Example #1
0
def add_handler_block(ir: FuncIR) -> BasicBlock:
    block = BasicBlock()
    ir.blocks.append(block)
    op = LoadErrorValue(ir.ret_type)
    block.ops.append(op)
    ir.env.add_op(op)
    block.ops.append(Return(op))
    return block
Example #2
0
 def visit_return_stmt(self, stmt: ReturnStmt) -> Register:
     if stmt.expr:
         retval = self.accept(stmt.expr)
     else:
         retval = self.environment.add_temp(NoneRType())
         self.add(PrimitiveOp(retval, PrimitiveOp.NONE))
     self.add(Return(retval))
     return INVALID_REGISTER
Example #3
0
    def gen_glue_ne_method(self, cls: ClassIR, line: int) -> FuncIR:
        """Generate a __ne__ method from a __eq__ method. """
        self.builder.enter()

        rt_args = (RuntimeArg("self", RInstance(cls)), RuntimeArg("rhs", object_rprimitive))

        # The environment operates on Vars, so we make some up
        fake_vars = [(Var(arg.name), arg.type) for arg in rt_args]
        args = [
            self.builder.read(
                self.builder.environment.add_local_reg(
                    var, type, is_arg=True
                ),
                line
            )
            for var, type in fake_vars
        ]  # type: List[Value]
        self.builder.ret_types[-1] = object_rprimitive

        # If __eq__ returns NotImplemented, then __ne__ should also
        not_implemented_block, regular_block = BasicBlock(), BasicBlock()
        eqval = self.add(MethodCall(args[0], '__eq__', [args[1]], line))
        not_implemented = self.primitive_op(not_implemented_op, [], line)
        self.add(Branch(
            self.builder.binary_op(eqval, not_implemented, 'is', line),
            not_implemented_block,
            regular_block,
            Branch.BOOL_EXPR))

        self.builder.activate_block(regular_block)
        retval = self.builder.coerce(
            self.builder.unary_op(eqval, 'not', line), object_rprimitive, line
        )
        self.add(Return(retval))

        self.builder.activate_block(not_implemented_block)
        self.add(Return(not_implemented))

        blocks, env, ret_type, _ = self.builder.leave()
        return FuncIR(
            FuncDecl('__ne__', cls.name, self.module_name,
                     FuncSignature(rt_args, ret_type)),
            blocks, env)
Example #4
0
 def test_simple(self) -> None:
     self.block.ops.append(Return(self.reg))
     fn = FuncIR('myfunc', [self.arg], IntRType(), [self.block], self.env)
     emitter = Emitter(EmitterContext())
     generate_native_function(fn, emitter)
     result = emitter.fragments
     assert_string_arrays_equal([
         'static CPyTagged CPyDef_myfunc(CPyTagged cpy_r_arg) {\n',
         'CPyL0: ;\n',
         '    return cpy_r_arg;\n',
         '}\n',
     ],
                                result,
                                msg='Generated code invalid')
Example #5
0
 def test_simple(self) -> None:
     self.block.ops.append(Return(self.reg))
     fn = FuncIR('myfunc', None, 'mod', FuncSignature([self.arg], int_rprimitive),
                 [self.block], self.env)
     emitter = Emitter(EmitterContext(['mod']))
     generate_native_function(fn, emitter, 'prog.py', 'prog')
     result = emitter.fragments
     assert_string_arrays_equal(
         [
             'static CPyTagged CPyDef_myfunc(CPyTagged cpy_r_arg) {\n',
             'CPyL0: ;\n',
             '    return cpy_r_arg;\n',
             '}\n',
         ],
         result, msg='Generated code invalid')
Example #6
0
 def test_return(self) -> None:
     self.assert_emit(Return(self.m), "return cpy_r_m;")
Example #7
0
    def generate_attr_defaults(self, cdef: ClassDef) -> None:
        """Generate an initialization method for default attr values (from class vars)"""
        cls = self.mapper.type_to_ir[cdef.info]
        if cls.builtin_base:
            return

        # Pull out all assignments in classes in the mro so we can initialize them
        # TODO: Support nested statements
        default_assignments = []
        for info in reversed(cdef.info.mro):
            if info not in self.mapper.type_to_ir:
                continue
            for stmt in info.defn.defs.body:
                if (isinstance(stmt, AssignmentStmt)
                        and isinstance(stmt.lvalues[0], NameExpr)
                        and not is_class_var(stmt.lvalues[0])
                        and not isinstance(stmt.rvalue, TempNode)):
                    if stmt.lvalues[0].name == '__slots__':
                        continue

                    # Skip type annotated assignments in dataclasses
                    if is_dataclass(cdef) and stmt.type:
                        continue

                    default_assignments.append(stmt)

        if not default_assignments:
            return

        self.builder.enter()
        self.builder.ret_types[-1] = bool_rprimitive

        rt_args = (RuntimeArg(SELF_NAME, RInstance(cls)),)
        self_var = self.builder.read(add_self_to_env(self.builder.environment, cls), -1)

        for stmt in default_assignments:
            lvalue = stmt.lvalues[0]
            assert isinstance(lvalue, NameExpr)
            if not stmt.is_final_def and not is_constant(stmt.rvalue):
                self.builder.warning('Unsupported default attribute value', stmt.rvalue.line)

            # If the attribute is initialized to None and type isn't optional,
            # don't initialize it to anything.
            attr_type = cls.attr_type(lvalue.name)
            if isinstance(stmt.rvalue, RefExpr) and stmt.rvalue.fullname == 'builtins.None':
                if (not is_optional_type(attr_type) and not is_object_rprimitive(attr_type)
                        and not is_none_rprimitive(attr_type)):
                    continue
            val = self.builder.coerce(self.accept(stmt.rvalue), attr_type, stmt.line)
            self.add(SetAttr(self_var, lvalue.name, val, -1))

        self.add(Return(self.primitive_op(true_op, [], -1)))

        blocks, env, ret_type, _ = self.builder.leave()
        ir = FuncIR(
            FuncDecl('__mypyc_defaults_setup',
                     cls.name, self.module_name,
                     FuncSignature(rt_args, ret_type)),
            blocks, env)
        self.builder.functions.append(ir)
        cls.methods[ir.name] = ir
Example #8
0
 def gen_return(self, builder: 'IRBuilder', value: Value,
                line: int) -> None:
     builder.add(Return(value))
Example #9
0
 def add_implicit_return(self) -> None:
     block = self.blocks[-1][-1]
     if not block.ops or not isinstance(block.ops[-1], Return):
         retval = self.environment.add_temp(NoneRType())
         self.add(PrimitiveOp(retval, PrimitiveOp.NONE))
         self.add(Return(retval))