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
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
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)
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')
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')
def test_return(self) -> None: self.assert_emit(Return(self.m), "return cpy_r_m;")
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
def gen_return(self, builder: 'IRBuilder', value: Value, line: int) -> None: builder.add(Return(value))
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))