Пример #1
0
 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
Пример #2
0
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
Пример #3
0
 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
Пример #4
0
 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)
Пример #5
0
 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)
Пример #6
0
 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
Пример #7
0
 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)
Пример #8
0
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])
Пример #9
0
def p_DeclProg(p):
    """DeclProg : PROGRAMA Bloco"""
    p[0] = [Sym.SymbolFun("main", Sym.SymType.INT, IR.Function(None, p[2]))]
Пример #10
0
 def _(self, node: ir.Function):
     body = self.visit(node.body)
     if body != node.body:
         return ir.Function(node.name, node.args, body)
     return node
Пример #11
0
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
Пример #12
0
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