Beispiel #1
0
 def visitSetSubscript(self, node):
     return ast.Discard(
         self.directCall(
             node, self.exports['interpreter_setitem'], None,
             [self(node.expr),
              self(node.subscript),
              self(node.value)]))
Beispiel #2
0
 def visitSetAttr(self, node):
     return ast.Discard(
         self.directCall(
             node, self.exports['interpreter_setattr'], None,
             [self(node.expr),
              self(node.name),
              self(node.value)]))
Beispiel #3
0
 def visitSetGlobal(self, node):
     p = self.code.codeparameters
     call = self.directCall(
         node, self.exports['interpreterStoreGlobal'], None,
         [self(p.selfparam),
          self(node.name),
          self(node.value)])
     return ast.Discard(call)
Beispiel #4
0
	def visitDiscard(self, node):
		expr = self(node.expr)
		if isinstance(expr, ast.Store): return expr

		if expr not in self.specialGlobals:
			if node.expr == expr:
				return node
			else:
				return ast.Discard(expr)
		else:
			return ()
Beispiel #5
0
    def methodCallToTypeSwitch(self, node, arg, pos, targets):
        # TODO if mutable types are allowed, we should be looking at the LowLevel type slot?
        # TODO localy rebuild read/modify/allocate information using filtered invokes.
        # TODO should the return value be SSAed?  This might interfere with nessled type switches.
        # If so, retarget the return value and fix up return types

        groups = self.groupTypes(node, arg, pos)
        if groups is None or len(groups) <= 1:
            return None  # Don't create trivial type switches

        cases = []
        for group in groups:
            # Create a filtered version of the argument.
            name = arg.name if isinstance(arg, ast.Local) else None
            expr = ast.Local(name)
            expr.annotation = self.filterReferenceAnnotationByType(
                arg.annotation, group)

            # Create the new op
            opannotation = node.annotation

            # Kill contexts where the filtered expression has no references.
            # (In these contexts, the new op will never be evaluated.)
            mask = self.makeRemapMask(expr.annotation)
            if -1 in mask: opannotation = opannotation.contextSubset(mask)

            # Filter out invocations that don't have the right type for the given parameter.
            opannotation = self.filterOpAnnotationByType(
                opannotation, group, pos)

            # Rewrite the op to use expr instead of the original arg.
            newop = rewrite.rewriteTerm(node, {arg: expr})
            assert newop is not node
            newop.annotation = opannotation

            # Try to reduce it to a direct call
            newop = self(newop)

            # Create the suite for this case
            stmts = []
            if targets is None:
                stmts.append(ast.Discard(newop))
            else:
                # HACK should SSA it?
                stmts.append(ast.Assign(newop, list(targets)))
            suite = ast.Suite(stmts)

            case = ast.TypeSwitchCase([self.existingFromObj(t) for t in group],
                                      expr, suite)
            cases.append(case)

        ts = ast.TypeSwitch(arg, cases)
        return ts
Beispiel #6
0
    def visitAssign(self, node):
        used = any(
            [self.flow.lookup(lcl) is not undefined for lcl in node.lcls])
        if used:
            for lcl in node.lcls:
                self.flow.undefine(lcl)
            self.marker(node.expr)
            return node

        elif self.hasNoSideEffects(node.expr):
            return []
        else:
            node = ast.Discard(node.expr)
            node = self(node)
            return node
Beispiel #7
0
	def visitAssign(self, node):
		assert self.locals

		if any([len(self.localuses[lcl]) > 0 for lcl in node.lcls]):
			expr = self(node.expr)

			assert self.locals, node.expr

			if isinstance(node.expr, ast.Local):
				# Assign local to local.  Nullop for SSA.
				assert len(node.lcls) == 1

				expr = self.reach(expr)
				self.locals.redefineLocal(node.lcls[0], expr)

				# Create a merge for exception handling.
				if self.hasExceptionHandling:
					el = self.exceptLocal(node.lcls[0])
					easgn = ast.Assign(expr, el)
					easgn.markMerge()
					return easgn
				else:
					return None


			else:
				renames = [self.locals.writeLocal(lcl) for lcl in node.lcls]
				for rename in renames:
					self.defns[rename] = expr

				asgn = ast.Assign(expr, renames)

				if self.hasExceptionHandling:
					# Create a merge for exception handling.
					output = [asgn]
					for lcl, rename in zip(node.lcls, renames):
						el = self.exceptLocal(lcl)
						easgn = ast.Assign(rename, el)
						easgn.markMerge()
						output.append(easgn)
					asgn = ast.Suite(output)

				return asgn

		elif not node.expr.isPure():
			return ast.Discard(self(node.expr))
		else:
			return None
Beispiel #8
0
from util.io import filesystem

from . import existingtransform

def existingSymbol(name):
	return ast.Existing(symbols.Extract(symbols.Symbol(name)))

def existingConstant(value):
	return ast.Existing(symbols.Extract(value))

uniformBindTemplate = ast.Discard(
	ast.Call(
		ast.GetAttr(
			symbols.Symbol('self'),
			existingSymbol('methodName')
		),
		[existingSymbol('name'), symbols.Symbol('value')],
		[], None, None
	)
)

def bindUniform(compiler, self, name, t, value):
	bind = symbols.SymbolRewriter(compiler.extractor, uniformBindTemplate)
	methodName = "bind_uniform_" + t.__name__
	return bind.rewrite(self=self, methodName=methodName, name=name, value=value)

typeCheckTemplate = ast.Call(
	ast.GetGlobal(existingConstant('isinstance')),
	[symbols.Symbol('root'), existingSymbol('type')],
	[], None, None
)