Ejemplo n.º 1
0
def gen_func_ir(builder: IRBuilder,
                blocks: List[BasicBlock],
                sig: FuncSignature,
                env: Environment,
                fn_info: FuncInfo,
                cdef: Optional[ClassDef]) -> Tuple[FuncIR, Optional[Value]]:
    """Generate the FuncIR for a function.

    This takes the basic blocks, environment, and function info of a
    particular function and returns the IR. If the function is nested,
    also returns the register containing the instance of the
    corresponding callable class.
    """
    func_reg = None  # type: Optional[Value]
    if fn_info.is_nested or fn_info.in_non_ext:
        func_ir = add_call_to_callable_class(builder, blocks, sig, env, fn_info)
        add_get_to_callable_class(builder, fn_info)
        func_reg = instantiate_callable_class(builder, fn_info)
    else:
        assert isinstance(fn_info.fitem, FuncDef)
        func_decl = builder.mapper.func_to_decl[fn_info.fitem]
        if fn_info.is_decorated:
            class_name = None if cdef is None else cdef.name
            func_decl = FuncDecl(fn_info.name, class_name, builder.module_name, sig,
                                 func_decl.kind,
                                 func_decl.is_prop_getter, func_decl.is_prop_setter)
            func_ir = FuncIR(func_decl, blocks, env, fn_info.fitem.line,
                             traceback_name=fn_info.fitem.name)
        else:
            func_ir = FuncIR(func_decl, blocks, env,
                             fn_info.fitem.line, traceback_name=fn_info.fitem.name)
    return (func_ir, func_reg)
Ejemplo n.º 2
0
def gen_dispatch_func_ir(
    builder: IRBuilder,
    fitem: FuncDef,
    main_func_name: str,
    dispatch_name: str,
    sig: FuncSignature,
) -> Tuple[FuncIR, Value]:
    """Create a dispatch function (a function that checks the first argument type and dispatches
    to the correct implementation)
    """
    builder.enter(FuncInfo(fitem, dispatch_name))
    setup_callable_class(builder)
    builder.fn_info.callable_class.ir.attributes['registry'] = dict_rprimitive
    builder.fn_info.callable_class.ir.attributes[
        'dispatch_cache'] = dict_rprimitive
    builder.fn_info.callable_class.ir.has_dict = True
    builder.fn_info.callable_class.ir.needs_getseters = True
    generate_singledispatch_callable_class_ctor(builder)

    generate_singledispatch_dispatch_function(builder, main_func_name, fitem)
    args, _, blocks, _, fn_info = builder.leave()
    dispatch_callable_class = add_call_to_callable_class(
        builder, args, blocks, sig, fn_info)
    builder.functions.append(dispatch_callable_class)
    add_get_to_callable_class(builder, fn_info)
    add_register_method_to_callable_class(builder, fn_info)
    func_reg = instantiate_callable_class(builder, fn_info)
    dispatch_func_ir = generate_dispatch_glue_native_function(
        builder, fitem, dispatch_callable_class.decl, dispatch_name)

    return dispatch_func_ir, func_reg