def visit_FunctionDef(self, node: ast.FunctionDef): # can't check just self.blocks, since we automatically # instantiate entry and exit name = node.name # Todo: warn about unsupported argument features params = [ir.NameRef(arg.arg) for arg in node.args.args] with self.flow_region(): for stmt in node.body: self.visit(stmt) func = ir.Function(name, params, self.body) return func
def externalizeMethod(info, method, dep): info.package.findOrAddName(method.name) id = ids.DefnId(ids.TARGET_PACKAGE_ID, ids.DefnId.FUNCTION, len(dep.externMethods)) externFlags = method.flags | frozenset([flags.EXTERN]) externMethod = ir.Function(method.name, id, astDefn=method.astDefn, typeParameters=method.typeParameters, returnType=method.returnType, parameterTypes=method.parameterTypes, flags=externFlags) dep.externMethods.append(externMethod) externalizeType(info, method.returnType) for p in method.typeParameters: externalizeTypeParameter(info, p) for t in method.parameterTypes: externalizeType(info, t) return externMethod
def buildFunction(functionData, namePrefix=None): nameComponents = [] if namePrefix is not None: nameComponents.append(namePrefix) sourceName = functionData.get("name", CONSTRUCTOR_SUFFIX) nameComponents.append(sourceName) name = Name(nameComponents) id = getattr(bytecode, functionData["id"]) flags = buildFlags(functionData["flags"]) function = ir.Function( name, id, sourceName=sourceName, returnType=buildType(functionData["returnType"]), typeParameters=[], parameterTypes=map(buildType, functionData["parameterTypes"]), flags=flags, insts=functionData.get("insts")) _builtinFunctionIdMap[id] = function return function
def testExternalizeTrait(self): trait = self.otherPackage.addTrait(Name(["Tr"]), typeParameters=[], supertypes=[self.rootClassType], methods=[], flags=frozenset([PUBLIC])) T = self.otherPackage.addTypeParameter( trait, Name(["Tr", "T"]), upperBound=ir_types.getRootClassType(), lowerBound=ir_types.getNothingClassType()) traitType = ir_types.ClassType.forReceiver(trait) method = self.otherPackage.addFunction(Name(["Tr", "f"]), returnType=ir_types.UnitType, typeParameters=[T], parameterTypes=[traitType], flags=frozenset( [PUBLIC, METHOD])) privateMethod = self.otherPackage.addFunction( Name(["Tr", "g"]), returnType=ir_types.UnitType, typeParameters=[T], parameterTypes=[traitType], flags=frozenset([PRIVATE, METHOD])) trait.methods = [method, privateMethod] externTrait = externalizeDefn(self.info, trait) expected = ir.Trait(Name(["Tr"]), trait.id, typeParameters=[T], supertypes=[self.rootClassType], flags=frozenset([PUBLIC, EXTERN])) expectedMethod = ir.Function(Name(["Tr", "f"]), method.id, returnType=ir_types.UnitType, typeParameters=[T], parameterTypes=[traitType], flags=frozenset([EXTERN, PUBLIC, METHOD])) expected.methods = [expectedMethod] self.assertEquals(expected, externTrait)
def testExternalizeFunction(self): function = self.otherPackage.addFunction(Name(["f"]), returnType=self.classTy, typeParameters=[], parameterTypes=[None], flags=frozenset([PUBLIC])) T = self.otherPackage.addTypeParameter( function, Name(["f.T"]), upperBound=ir_types.getRootClassType(), lowerBound=ir_types.getNothingClassType(), flags=frozenset([STATIC])) TTy = ir_types.VariableType(T) function.parameterTypes[0] = TTy externFunction = externalizeDefn(self.info, function) expected = ir.Function(Name(["f"]), function.id, returnType=self.classTy, typeParameters=[T], parameterTypes=[TTy], flags=frozenset([PUBLIC, EXTERN])) self.assertEquals(expected, externFunction)
def createEmptyFunctionList(self, count, packageId): fids = (ids.DefnId(packageId, ids.DefnId.FUNCTION, i) for i in xrange(count)) functions = list(ir.Function(None, id) for id in fids) return functions
def testExternalizeClass(self): clas = self.otherPackage.addClass(Name(["C"]), typeParameters=[], supertypes=[self.rootClassType], constructors=[], fields=[], methods=[], elementType=None, flags=frozenset( [ARRAY, FINAL, PUBLIC])) T = self.otherPackage.addTypeParameter( clas, Name(["C", "T"]), upperBound=ir_types.getRootClassType(), lowerBound=ir_types.getNothingClassType(), flags=frozenset([STATIC])) TTy = ir_types.VariableType(T) clas.elementType = TTy clasTy = ir_types.ClassType.forReceiver(clas) ctor = self.otherPackage.addFunction( Name(["C", CONSTRUCTOR_SUFFIX]), returnType=ir_types.UnitType, typeParameters=[T], parameterTypes=[clasTy], flags=frozenset([PUBLIC, METHOD, CONSTRUCTOR])) privateCtor = self.otherPackage.addFunction( Name(["C", CONSTRUCTOR_SUFFIX]), returnType=ir_types.UnitType, typeParameters=[T], parameterTypes=[clasTy], flags=frozenset([PRIVATE, METHOD, CONSTRUCTOR])) clas.constructors = [ctor, privateCtor] field = self.otherPackage.newField(Name(["C", "x"]), type=clasTy, flags=frozenset([PUBLIC])) privateField = self.otherPackage.newField(Name(["C", "y"]), type=clasTy, flags=frozenset([PRIVATE])) clas.fields = [field, privateField] method = self.otherPackage.addFunction(Name(["C", "f"]), returnType=ir_types.UnitType, typeParameters=[T], parameterTypes=[clasTy], flags=frozenset( [PUBLIC, METHOD])) privateMethod = self.otherPackage.addFunction( Name(["C", "g"]), returnType=ir_types.UnitType, typeParameters=[T], parameterTypes=[clasTy], flags=frozenset([PRIVATE, METHOD])) builtinMethod = \ builtins.getBuiltinFunctionById(bytecode.BUILTIN_ROOT_CLASS_TO_STRING_ID) clas.methods = [method, privateMethod, builtinMethod] externClass = externalizeDefn(self.info, clas) expected = ir.Class(Name(["C"]), clas.id, typeParameters=[T], supertypes=[self.rootClassType], elementType=TTy, flags=frozenset([ARRAY, FINAL, PUBLIC, EXTERN])) expectedCtor = ir.Function(Name(["C", CONSTRUCTOR_SUFFIX]), ctor.id, returnType=ir_types.UnitType, typeParameters=[T], parameterTypes=[clasTy], flags=frozenset( [PUBLIC, METHOD, CONSTRUCTOR, EXTERN])) expected.constructors = [expectedCtor] expectedField = ir.Field(Name(["C", "x"]), type=clasTy, flags=frozenset([PUBLIC])) expected.fields = [expectedField] expectedMethod = ir.Function(Name(["C", "f"]), method.id, returnType=ir_types.UnitType, typeParameters=[T], parameterTypes=[clasTy], flags=frozenset([PUBLIC, METHOD, EXTERN])) externBuiltinMethod = ir.Function( Name(["Object", "to-string"]), builtinMethod.id, returnType=ir_types.getStringType(), typeParameters=[], parameterTypes=[ir_types.getRootClassType()], flags=frozenset([EXTERN, PUBLIC, METHOD])) expected.methods = [expectedMethod, externBuiltinMethod] self.assertEquals(expected, externClass)
def p_DeclFunc(p): """DeclFunc : '(' ListaParametros ')' Bloco""" if p[2] == []: p[0] = IR.Function(None, p[4]) else: p[0] = IR.Function(p[2], p[4])
def p_DeclProg(p): """DeclProg : PROGRAMA Bloco""" p[0] = [Sym.SymbolFun("main", Sym.SymType.INT, IR.Function(None, p[2]))]
def _(self, node: ir.Function): body = self.visit(node.body) if body != node.body: return ir.Function(node.name, node.args, body) return node
def externalizeDefn(info, defn): if not defn.isForeign(): return defn assert flags.PUBLIC in defn.flags id = defn.id # Make sure we have a dependency on the package that contains this definition. info.package.ensureDependency( info.packageLoader.getPackageById(id.packageId)) # Find the list we're going to put our external description in. info.package.findOrAddName(defn.name) externFlags = defn.flags | frozenset([flags.EXTERN]) dep = info.package.dependencies[id.packageId.index] if isinstance(defn, ir.Global): externDefns = dep.externGlobals elif isinstance(defn, ir.Function): externDefns = dep.externFunctions elif isinstance(defn, ir.Class): externDefns = dep.externClasses elif isinstance(defn, ir.Trait): externDefns = dep.externTraits else: raise NotImplementedError() # Base case: we already externalized this definition, so re-use that. if id.externIndex is not None: return externDefns[id.externIndex] # Recursive case: add a placeholder definition so recursive calls can find it. # Externalize anything else the definition depends on. id.externIndex = len(externDefns) if isinstance(defn, ir.Global): externDefn = ir.Global(defn.name, id, astDefn=defn.astDefn, type=defn.type, flags=externFlags) externDefns.append(externDefn) externalizeType(info, defn.type) elif isinstance(defn, ir.Function): externDefn = ir.Function(defn.name, id, astDefn=defn.astDefn, typeParameters=defn.typeParameters, returnType=defn.returnType, parameterTypes=defn.parameterTypes, flags=externFlags) externDefns.append(externDefn) externalizeType(info, defn.returnType) for p in defn.typeParameters: externalizeTypeParameter(info, p) for t in defn.parameterTypes: externalizeType(info, t) elif isinstance(defn, ir.Class): externDefn = ir.Class(defn.name, id, astDefn=defn.astDefn, typeParameters=defn.typeParameters, supertypes=defn.supertypes, elementType=defn.elementType, flags=externFlags) externDefns.append(externDefn) for p in defn.typeParameters: externalizeTypeParameter(info, p) for t in defn.supertypes: externalizeType(info, t) externDefn.constructors = [ externalizeMethod(info, ctor, dep) for ctor in defn.constructors if flags.PUBLIC in ctor.flags ] externDefn.fields = [ f for f in defn.fields if flags.PUBLIC in f.flags or flags.ARRAY in f.flags ] each(info.package.findOrAddName, (f.name for f in externDefn.fields)) for f in externDefn.fields: externalizeType(info, f.type) externDefn.methods = [ externalizeMethod(info, m, dep) for m in defn.methods if flags.PUBLIC in m.flags ] if externDefn.elementType is not None: externalizeType(info, externDefn.elementType) elif isinstance(defn, ir.Trait): externDefn = ir.Trait(defn.name, id, astDefn=defn.astDefn, typeParameters=defn.typeParameters, supertypes=defn.supertypes, flags=externFlags) externDefns.append(externDefn) for p in defn.typeParameters: externalizeTypeParameter(info, p) for t in defn.supertypes: externalizeType(info, t) externDefn.methods = [ externalizeMethod(info, m, dep) for m in defn.methods if flags.PUBLIC in m.flags ] else: raise NotImplementedError return externDefn
def get_ir(cfg_func): """ Converts the given CFG function into IR entities """ ir_func = ir.Function() ir_var_list = [] cfg_var_list = [] ir_bb_label_list = [] for cfg_var in cfg_func.variable_list: ir_var = ir.Variable(cfg_var.name) ir_var_list.append(ir_var) cfg_var_list.append(cfg_var) label = 0 for cfg_bb in cfg_func.basic_block_list: ir_bb_label_list.append(label) for cfg_instr in cfg_bb.instruction_list: if isinstance(cfg_instr, cfg.ArithInstruction): ir_instr = ir.ArithInstruction(ir_func) ir_lhs = get_ir_numeric(cfg_instr.lhs, cfg_var_list, ir_var_list) ir_rhs_1 = get_ir_numeric(cfg_instr.rhs_1, cfg_var_list, ir_var_list) ir_rhs_2 = get_ir_numeric(cfg_instr.rhs_2, cfg_var_list, ir_var_list) ir_op = ir.Operation(cfg_instr.op.name) ir_instr.update(ir_lhs, ir_rhs_1, ir_rhs_2, ir_op) elif isinstance(cfg_instr, cfg.CmpInstruction): ir_instr = ir.CmpInstruction(ir_func) ir_lhs = get_ir_numeric(cfg_instr.lhs, cfg_var_list, ir_var_list) ir_rhs_1 = get_ir_numeric(cfg_instr.rhs_1, cfg_var_list, ir_var_list) ir_rhs_2 = get_ir_numeric(cfg_instr.rhs_2, cfg_var_list, ir_var_list) ir_op = ir.Operation(cfg_instr.op.name) ir_instr.update(ir_lhs, ir_rhs_1, ir_rhs_2, ir_op) elif isinstance(cfg_instr, cfg.EqInstruction): ir_instr = ir.EqInstruction(ir_func) ir_lhs = get_ir_numeric(cfg_instr.lhs, cfg_var_list, ir_var_list) ir_rhs = get_ir_numeric(cfg_instr.rhs, cfg_var_list, ir_var_list) ir_instr.update(ir_lhs, ir_rhs) ir_func.add_instruction_by_label(label, ir_instr) label += 1 #at end of BB, add branch statements if cfg_bb.number_of_children is 1: ir_instr = ir.UncondnJumpInstruction(ir_func) ir_func.add_instruction_by_label(label, ir_instr) elif cfg_bb.number_of_children is 2: if isinstance(cfg_bb.condition_instr, cfg.CmpInstruction): ir_instr = ir.CmpInstruction(ir_func) ir_lhs = get_ir_numeric(cfg_bb.condition_instr.lhs, cfg_var_list, ir_var_list) ir_rhs_1 = get_ir_numeric(cfg_bb.condition_instr.rhs_1, cfg_var_list, ir_var_list) ir_rhs_2 = get_ir_numeric(cfg_bb.condition_instr.rhs_2, cfg_var_list, ir_var_list) ir_op = ir.Operation(cfg_bb.condition_instr.op.name) ir_instr.update(ir_lhs, ir_rhs_1, ir_rhs_2, ir_op) ir_func.add_instruction_by_label(label, ir_instr) label += 1 ir_instr = ir.CondnJumpInstruction(ir_func) ir_condn_var = get_ir_numeric(cfg_bb.condition, cfg_var_list, ir_var_list) ir_instr.update(ir_condn_var, 0, 0) ir_func.add_instruction_by_label(label, ir_instr) else: ir_instr = ir.ReturnInstruction(ir_func) ir_func.add_instruction_by_label(label, ir_instr) label += 1 k = 0 for cfg_bb in cfg_func.basic_block_list: if cfg_bb.number_of_children is 1: this_label = ir_bb_label_list[k] + len(cfg_bb.instruction_list) assert (isinstance(ir_func.instr_list[this_label], ir.UncondnJumpInstruction)) next_label = ir_bb_label_list[cfg_bb.child.identity] ir_func.instr_list[this_label].next_instr_label = next_label elif cfg_bb.number_of_children is 2: this_label = ir_bb_label_list[k] + len(cfg_bb.instruction_list) if isinstance(cfg_bb.condition_instr, cfg.CmpInstruction): this_label += 1 assert (isinstance(ir_func.instr_list[this_label], ir.CondnJumpInstruction)) next_true_label = ir_bb_label_list[cfg_bb.child_true.identity] next_false_label = ir_bb_label_list[cfg_bb.child_false.identity] ir_func.instr_list[this_label].instr_true_label = next_true_label ir_func.instr_list[this_label].instr_false_label = next_false_label k += 1 ir_input_variables = [] for cfg_var in cfg_func.input_variable_list: ir_var = get_ir_numeric(cfg_var, cfg_var_list, ir_var_list) ir_input_variables.append(ir_var) ir_output_variables = [] for cfg_var in cfg_func.output_variable_list: ir_var = get_ir_numeric(cfg_var, cfg_var_list, ir_var_list) ir_output_variables.append(ir_var) ir_func.set_input_variables(ir_input_variables) ir_func.set_output_variables(ir_output_variables) ir_func.add_summary(cfg_func.summary) return ir_func