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 try_finally_entry_blocks(builder: IRBuilder,
                             err_handler: BasicBlock,
                             return_entry: BasicBlock,
                             main_entry: BasicBlock,
                             finally_block: BasicBlock,
                             ret_reg: Optional[Register]) -> Value:
    old_exc = builder.alloc_temp(exc_rtuple)

    # Entry block for non-exceptional flow
    builder.activate_block(main_entry)
    if ret_reg:
        builder.add(
            Assign(
                ret_reg,
                builder.add(LoadErrorValue(builder.ret_types[-1]))
            )
        )
    builder.goto(return_entry)

    builder.activate_block(return_entry)
    builder.add(Assign(old_exc, builder.add(LoadErrorValue(exc_rtuple))))
    builder.goto(finally_block)

    # Entry block for errors
    builder.activate_block(err_handler)
    if ret_reg:
        builder.add(
            Assign(
                ret_reg,
                builder.add(LoadErrorValue(builder.ret_types[-1]))
            )
        )
    builder.add(Assign(old_exc, builder.primitive_op(error_catch_op, [], -1)))
    builder.goto(finally_block)

    return old_exc
Example #3
0
    def native_args_to_positional(self, args: Sequence[Value],
                                  arg_kinds: List[int],
                                  arg_names: Sequence[Optional[str]],
                                  sig: FuncSignature,
                                  line: int) -> List[Value]:
        """Prepare arguments for a native call.

        Given args/kinds/names and a target signature for a native call, map
        keyword arguments to their appropriate place in the argument list,
        fill in error values for unspecified default arguments,
        package arguments that will go into *args/**kwargs into a tuple/dict,
        and coerce arguments to the appropriate type.
        """

        sig_arg_kinds = [arg.kind for arg in sig.args]
        sig_arg_names = [arg.name for arg in sig.args]
        formal_to_actual = map_actuals_to_formals(
            arg_kinds, arg_names, sig_arg_kinds, sig_arg_names,
            lambda n: AnyType(TypeOfAny.special_form))

        # Flatten out the arguments, loading error values for default
        # arguments, constructing tuples/dicts for star args, and
        # coercing everything to the expected type.
        output_args = []
        for lst, arg in zip(formal_to_actual, sig.args):
            output_arg = None
            if arg.kind == ARG_STAR:
                output_arg = self.primitive_op(new_tuple_op,
                                               [args[i] for i in lst], line)
            elif arg.kind == ARG_STAR2:
                dict_entries = [
                    (self.load_static_unicode(cast(str,
                                                   arg_names[i])), args[i])
                    for i in lst
                ]
                output_arg = self.make_dict(dict_entries, line)
            elif not lst:
                output_arg = self.add(
                    LoadErrorValue(arg.type, is_borrowed=True))
            else:
                output_arg = args[lst[0]]
            output_args.append(self.coerce(output_arg, arg.type, line))

        return output_args
Example #4
0
    def allocate_class(self, cdef: ClassDef) -> Value:
        # OK AND NOW THE FUN PART
        base_exprs = cdef.base_type_exprs + cdef.removed_base_type_exprs
        if base_exprs:
            bases = [self.accept(x) for x in base_exprs]
            tp_bases = self.primitive_op(new_tuple_op, bases, cdef.line)
        else:
            tp_bases = self.add(
                LoadErrorValue(object_rprimitive, is_borrowed=True))
        modname = self.load_static_unicode(self.module_name)
        template = self.add(
            LoadStatic(object_rprimitive, cdef.name + "_template",
                       self.module_name, NAMESPACE_TYPE))
        # Create the class
        tp = self.primitive_op(pytype_from_template_op,
                               [template, tp_bases, modname], cdef.line)
        # Immediately fix up the trait vtables, before doing anything with the class.
        ir = self.mapper.type_to_ir[cdef.info]
        if not ir.is_trait and not ir.builtin_base:
            self.add(
                Call(
                    FuncDecl(cdef.name + '_trait_vtable_setup', None,
                             self.module_name,
                             FuncSignature([], bool_rprimitive)), [], -1))
        # Populate a '__mypyc_attrs__' field containing the list of attrs
        self.primitive_op(py_setattr_op, [
            tp,
            self.load_static_unicode('__mypyc_attrs__'),
            self.create_mypyc_attrs_tuple(self.mapper.type_to_ir[cdef.info],
                                          cdef.line)
        ], cdef.line)

        # Save the class
        self.add(InitStatic(tp, cdef.name, self.module_name, NAMESPACE_TYPE))

        # Add it to the dict
        self.primitive_op(dict_set_item_op, [
            self.builder.load_globals_dict(),
            self.load_static_unicode(cdef.name),
            tp,
        ], cdef.line)

        return tp
Example #5
0
def transform_del_item(builder: IRBuilder, target: AssignmentTarget, line: int) -> None:
    if isinstance(target, AssignmentTargetIndex):
        builder.gen_method_call(
            target.base,
            '__delitem__',
            [target.index],
            result_type=None,
            line=line
        )
    elif isinstance(target, AssignmentTargetAttr):
        key = builder.load_static_unicode(target.attr)
        builder.add(PrimitiveOp([target.obj, key], py_delattr_op, line))
    elif isinstance(target, AssignmentTargetRegister):
        # Delete a local by assigning an error value to it, which will
        # prompt the insertion of uninit checks.
        builder.add(Assign(target.register,
                           builder.add(LoadErrorValue(target.type, undefines=True))))
    elif isinstance(target, AssignmentTargetTuple):
        for subtarget in target.items:
            transform_del_item(builder, subtarget, line)