Exemplo n.º 1
0
    def _setup_frame_realloc(self, translate_support_code):
        FUNC_TP = lltype.Ptr(
            lltype.FuncType([llmemory.GCREF, lltype.Signed], llmemory.GCREF))
        base_ofs = self.get_baseofs_of_frame_field()

        def realloc_frame(frame, size):
            try:
                if not we_are_translated():
                    assert not self._exception_emulator[0]
                frame = lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, frame)
                if size > frame.jf_frame_info.jfi_frame_depth:
                    # update the frame_info size, which is for whatever reason
                    # not up to date
                    frame.jf_frame_info.update_frame_depth(base_ofs, size)
                new_frame = jitframe.JITFRAME.allocate(frame.jf_frame_info)
                frame.jf_forward = new_frame
                i = 0
                while i < len(frame.jf_frame):
                    new_frame.jf_frame[i] = frame.jf_frame[i]
                    frame.jf_frame[i] = 0
                    i += 1
                new_frame.jf_savedata = frame.jf_savedata
                new_frame.jf_guard_exc = frame.jf_guard_exc
                # all other fields are empty
                llop.gc_writebarrier(lltype.Void, new_frame)
                return lltype.cast_opaque_ptr(llmemory.GCREF, new_frame)
            except Exception as e:
                print "Unhandled exception", e, "in realloc_frame"
                return lltype.nullptr(llmemory.GCREF.TO)

        def realloc_frame_crash(frame, size):
            print "frame", frame, "size", size
            return lltype.nullptr(llmemory.GCREF.TO)

        if not translate_support_code:
            fptr = llhelper(FUNC_TP, realloc_frame)
        else:
            FUNC = FUNC_TP.TO
            args_s = [lltype_to_annotation(ARG) for ARG in FUNC.ARGS]
            s_result = lltype_to_annotation(FUNC.RESULT)
            mixlevelann = MixLevelHelperAnnotator(self.rtyper)
            graph = mixlevelann.getgraph(realloc_frame, args_s, s_result)
            fptr = mixlevelann.graph2delayed(graph, FUNC)
            mixlevelann.finish()
        self.realloc_frame = heaptracker.adr2int(
            llmemory.cast_ptr_to_adr(fptr))

        if not translate_support_code:
            fptr = llhelper(FUNC_TP, realloc_frame_crash)
        else:
            FUNC = FUNC_TP.TO
            args_s = [lltype_to_annotation(ARG) for ARG in FUNC.ARGS]
            s_result = lltype_to_annotation(FUNC.RESULT)
            mixlevelann = MixLevelHelperAnnotator(self.rtyper)
            graph = mixlevelann.getgraph(realloc_frame_crash, args_s, s_result)
            fptr = mixlevelann.graph2delayed(graph, FUNC)
            mixlevelann.finish()
        self.realloc_frame_crash = heaptracker.adr2int(
            llmemory.cast_ptr_to_adr(fptr))
Exemplo n.º 2
0
 def build_cpu(self,
               CPUClass,
               translate_support_code=False,
               no_stats=False,
               supports_floats=True,
               supports_longlong=True,
               supports_singlefloats=True,
               **kwds):
     assert CPUClass is not None
     self.opt = history.Options(**kwds)
     if no_stats:
         stats = history.NoStats()
     else:
         stats = history.Stats()
     self.stats = stats
     if translate_support_code:
         self.annhelper = MixLevelHelperAnnotator(self.translator.rtyper)
     cpu = CPUClass(self.translator.rtyper,
                    self.stats,
                    self.opt,
                    translate_support_code,
                    gcdescr=self.gcdescr)
     if not supports_floats:
         cpu.supports_floats = False
     if not supports_longlong:
         cpu.supports_longlong = False
     if not supports_singlefloats:
         cpu.supports_singlefloats = False
     self.cpu = cpu
Exemplo n.º 3
0
def call_final_function(translator, final_func, annhelper=None):
    """When the program finishes normally, call 'final_func()'."""
    from rpython.annotator import model as annmodel
    from rpython.rtyper.lltypesystem import lltype
    from rpython.rtyper.annlowlevel import MixLevelHelperAnnotator

    own_annhelper = (annhelper is None)
    if own_annhelper:
        annhelper = MixLevelHelperAnnotator(translator.rtyper)
    c_final_func = annhelper.constfunc(final_func, [], annmodel.s_None)
    if own_annhelper:
        annhelper.finish()

    entry_point = translator.entry_point_graph
    v = entry_point.getreturnvar().copy()
    extrablock = Block([v])
    v_none = varoftype(lltype.Void)
    newop = SpaceOperation('direct_call', [c_final_func], v_none)
    extrablock.operations = [newop]
    extrablock.closeblock(Link([v], entry_point.returnblock))
    for block in entry_point.iterblocks():
        if block is not extrablock:
            for link in block.exits:
                if link.target is entry_point.returnblock:
                    link.target = extrablock
    checkgraph(entry_point)
Exemplo n.º 4
0
def test_pseudohighlevelcallable():
    t = TranslationContext()
    t.buildannotator()
    rtyper = t.buildrtyper()
    rtyper.specialize()
    a = MixLevelHelperAnnotator(rtyper)

    class A:
        value = 5

        def double(self):
            return self.value * 2

    def fn1(a):
        a2 = A()
        a2.value = a.double()
        return a2

    s_A, r_A = a.s_r_instanceof(A)
    fn1ptr = a.delayedfunction(fn1, [s_A], s_A)
    pseudo = PseudoHighLevelCallable(fn1ptr, [s_A], s_A)

    def fn2(n):
        a = A()
        a.value = n
        a2 = pseudo(a)
        return a2.value

    graph = a.getgraph(fn2, [annmodel.SomeInteger()], annmodel.SomeInteger())
    a.finish()

    llinterp = LLInterpreter(rtyper)
    res = llinterp.eval_graph(graph, [21])
    assert res == 42
Exemplo n.º 5
0
def complete_destrptr(gctransformer):
    translator = gctransformer.translator
    mixlevelannotator = MixLevelHelperAnnotator(translator.rtyper)
    args_s = [lltype_to_annotation(STACKLET_PTR)]
    s_result = annmodel.s_None
    destrptr = mixlevelannotator.delayedfunction(stacklet_destructor, args_s,
                                                 s_result)
    mixlevelannotator.finish()
    lltype.attachRuntimeTypeInfo(STACKLET, destrptr=destrptr)
Exemplo n.º 6
0
def test_enforced_args():
    from rpython.annotator.model import s_None
    from rpython.rtyper.annlowlevel import MixLevelHelperAnnotator
    from rpython.translator.interactive import Translation
    def f1():
        str2charp("hello")
    def f2():
        str2charp("world")
    t = Translation(f1, [])
    t.rtype()
    mixann = MixLevelHelperAnnotator(t.context.rtyper)
    mixann.getgraph(f2, [], s_None)
    mixann.finish()
Exemplo n.º 7
0
 def test_conditional_call(self):
     def g():
         pass
     def f(n):
         conditional_call(n >= 0, g)
     def later(m):
         conditional_call(m, g)
     t = TranslationContext()
     t.buildannotator().build_types(f, [int])
     t.buildrtyper().specialize()
     mix = MixLevelHelperAnnotator(t.rtyper)
     mix.getgraph(later, [annmodel.s_Bool], annmodel.s_None)
     mix.finish()
Exemplo n.º 8
0
    def make_driverhook_graphs(self):
        #
        annhelper = MixLevelHelperAnnotator(self.translator.rtyper)
        for jd in self.jitdrivers_sd:
            jd._get_printable_location_ptr = self._make_hook_graph(
                jd, annhelper, jd.jitdriver.get_printable_location,
                annmodel.SomeString())
            jd._get_unique_id_ptr = self._make_hook_graph(
                jd, annhelper, jd.jitdriver.get_unique_id,
                annmodel.SomeInteger())
            jd._confirm_enter_jit_ptr = self._make_hook_graph(
                jd,
                annhelper,
                jd.jitdriver.confirm_enter_jit,
                annmodel.s_Bool,
                onlygreens=False)
            jd._can_never_inline_ptr = self._make_hook_graph(
                jd, annhelper, jd.jitdriver.can_never_inline, annmodel.s_Bool)
            jd._should_unroll_one_iteration_ptr = self._make_hook_graph(
                jd, annhelper, jd.jitdriver.should_unroll_one_iteration,
                annmodel.s_Bool)
            #
            items = []
            types = ()
            pos = ()
            if jd.jitdriver.get_location:
                assert hasattr(jd.jitdriver.get_location, '_loc_types'), """
                You must decorate your get_location function:

                from rpython.rlib.rjitlog import rjitlog as jl
                @jl.returns(jl.MP_FILENAME, jl.MP_XXX, ...)
                def get_loc(your, green, keys):
                    name = "x.txt" # extract it from your green keys
                    return (name, ...)
                """
                types = jd.jitdriver.get_location._loc_types
                del jd.jitdriver.get_location._loc_types
                #
                for _, type in types:
                    if type == 's':
                        items.append(annmodel.SomeString())
                    elif type == 'i':
                        items.append(annmodel.SomeInteger())
                    else:
                        raise NotImplementedError
            s_Tuple = annmodel.SomeTuple(items)
            jd._get_location_ptr = self._make_hook_graph(
                jd, annhelper, jd.jitdriver.get_location, s_Tuple)
            jd._get_loc_types = types
        annhelper.finish()
Exemplo n.º 9
0
def builtin_func_for_spec(rtyper,
                          oopspec_name,
                          ll_args,
                          ll_res,
                          extra=None,
                          extrakey=None):
    assert (extra is None) == (extrakey is None)
    key = (oopspec_name, tuple(ll_args), ll_res, extrakey)
    try:
        return rtyper._builtin_func_for_spec_cache[key]
    except (KeyError, AttributeError):
        pass
    args_s = [lltype_to_annotation(v) for v in ll_args]
    if '.' not in oopspec_name:  # 'newxxx' operations
        LIST_OR_DICT = ll_res
    else:
        LIST_OR_DICT = ll_args[0]
    s_result = lltype_to_annotation(ll_res)
    impl = setup_extra_builtin(rtyper, oopspec_name, len(args_s), extra)
    if getattr(impl, 'need_result_type', False):
        if hasattr(rtyper, 'annotator'):
            bk = rtyper.annotator.bookkeeper
            ll_restype = ll_res
            if impl.need_result_type != 'exact':
                ll_restype = ll_restype.TO
            desc = bk.getdesc(ll_restype)
        else:

            class TestingDesc(object):
                knowntype = int
                pyobj = None

            desc = TestingDesc()
        args_s.insert(0, annmodel.SomePBC([desc]))
    #
    if hasattr(rtyper, 'annotator'):  # regular case
        mixlevelann = MixLevelHelperAnnotator(rtyper)
        c_func = mixlevelann.constfunc(impl, args_s, s_result)
        mixlevelann.finish()
    else:
        # for testing only
        c_func = Constant(oopspec_name,
                          lltype.Ptr(lltype.FuncType(ll_args, ll_res)))
    #
    if not hasattr(rtyper, '_builtin_func_for_spec_cache'):
        rtyper._builtin_func_for_spec_cache = {}
    rtyper._builtin_func_for_spec_cache[key] = (c_func, LIST_OR_DICT)
    #
    return c_func, LIST_OR_DICT
Exemplo n.º 10
0
def test_delayed_fnptr():
    from rpython.flowspace.model import SpaceOperation
    from rpython.rtyper.annlowlevel import MixLevelHelperAnnotator
    from rpython.translator.translator import TranslationContext
    t = TranslationContext()
    t.buildannotator()
    t.buildrtyper()
    annhelper = MixLevelHelperAnnotator(t.rtyper)

    def f():
        pass

    c_f = annhelper.constfunc(f, [], None)
    op = SpaceOperation('direct_call', [c_f], None)
    analyzer = BoolGraphAnalyzer(t)
    assert analyzer.analyze(op)
Exemplo n.º 11
0
 def make_driverhook_graphs(self):
     s_Str = annmodel.SomeString()
     #
     annhelper = MixLevelHelperAnnotator(self.translator.rtyper)
     for jd in self.jitdrivers_sd:
         jd._get_printable_location_ptr = self._make_hook_graph(jd,
             annhelper, jd.jitdriver.get_printable_location, s_Str)
         jd._confirm_enter_jit_ptr = self._make_hook_graph(jd,
             annhelper, jd.jitdriver.confirm_enter_jit, annmodel.s_Bool,
             onlygreens=False)
         jd._can_never_inline_ptr = self._make_hook_graph(jd,
             annhelper, jd.jitdriver.can_never_inline, annmodel.s_Bool)
         jd._should_unroll_one_iteration_ptr = self._make_hook_graph(jd,
             annhelper, jd.jitdriver.should_unroll_one_iteration,
             annmodel.s_Bool)
     annhelper.finish()
Exemplo n.º 12
0
    def test_secondary_backendopt(self):
        # checks an issue with a newly added graph that calls an
        # already-exception-transformed graph.  This can occur e.g.
        # from a late-seen destructor added by the GC transformer
        # which ends up calling existing code.
        def common(n):
            if n > 5:
                raise ValueError

        def main(n):
            common(n)

        def later(n):
            try:
                common(n)
                return 0
            except ValueError:
                return 1

        t = TranslationContext()
        t.buildannotator().build_types(main, [int])
        t.buildrtyper().specialize()
        exctransformer = t.getexceptiontransformer()
        exctransformer.create_exception_handling(graphof(t, common))
        from rpython.annotator import model as annmodel
        from rpython.rtyper.annlowlevel import MixLevelHelperAnnotator
        annhelper = MixLevelHelperAnnotator(t.rtyper)
        later_graph = annhelper.getgraph(later, [annmodel.SomeInteger()],
                                         annmodel.SomeInteger())
        annhelper.finish()
        annhelper.backend_optimize()
        # ^^^ as the inliner can't handle exception-transformed graphs,
        # this should *not* inline common() into later().
        if option.view:
            later_graph.show()
        common_graph = graphof(t, common)
        found = False
        for block in later_graph.iterblocks():
            for op in block.operations:
                if (op.opname == 'direct_call'
                        and op.args[0].value._obj.graph is common_graph):
                    found = True
        assert found, "cannot find the call (buggily inlined?)"
        from rpython.rtyper.llinterp import LLInterpreter
        llinterp = LLInterpreter(t.rtyper)
        res = llinterp.eval_graph(later_graph, [10])
        assert res == 1
Exemplo n.º 13
0
    def replace_force_virtualizable(self, rtyper, graphs):
        from rpython.annotator import model as annmodel
        from rpython.rtyper.annlowlevel import MixLevelHelperAnnotator
        graph = graphs[0]

        for block, op in graph.iterblockops():
            if op.opname == 'jit_force_virtualizable':
                v_inst_ll_type = op.args[0].concretetype
                break

        def mycall(vinst_ll):
            if vinst_ll.vable_token:
                raise ValueError

        annhelper = MixLevelHelperAnnotator(rtyper)
        s_vinst = SomePtr(v_inst_ll_type)
        funcptr = annhelper.delayedfunction(mycall, [s_vinst], annmodel.s_None)
        annhelper.finish()
        replace_force_virtualizable_with_call(graphs, v_inst_ll_type, funcptr)
        return funcptr
Exemplo n.º 14
0
 def __init__(self, translator, inline=False):
     self.translator = translator
     self.seen_graphs = set()
     self.prepared = False
     self.minimal_transform = set()
     if translator:
         self.mixlevelannotator = MixLevelHelperAnnotator(translator.rtyper)
     else:
         self.mixlevelannotator = None
     self.inline = inline
     if translator and inline:
         self.lltype_to_classdef = translator.rtyper.lltype_to_classdef_mapping()
         self.raise_analyzer = RaiseAnalyzer(translator)
     self.graphs_to_inline = {}
     self.graph_dependencies = {}
     self.ll_finalizers_ptrs = []
     if self.MinimalGCTransformer:
         self.minimalgctransformer = self.MinimalGCTransformer(self)
     else:
         self.minimalgctransformer = None
Exemplo n.º 15
0
def call_initial_function(translator, initial_func, annhelper=None):
    """Before the program starts, call 'initial_func()'."""
    from rpython.annotator import model as annmodel
    from rpython.rtyper.lltypesystem import lltype
    from rpython.rtyper.annlowlevel import MixLevelHelperAnnotator

    own_annhelper = (annhelper is None)
    if own_annhelper:
        annhelper = MixLevelHelperAnnotator(translator.rtyper)
    c_initial_func = annhelper.constfunc(initial_func, [], annmodel.s_None)
    if own_annhelper:
        annhelper.finish()

    entry_point = translator.entry_point_graph
    args = [v.copy() for v in entry_point.getargs()]
    extrablock = Block(args)
    v_none = varoftype(lltype.Void)
    newop = SpaceOperation('direct_call', [c_initial_func], v_none)
    extrablock.operations = [newop]
    extrablock.closeblock(Link(args, entry_point.startblock))
    entry_point.startblock = extrablock
    checkgraph(entry_point)
Exemplo n.º 16
0
    def getentrypointptr(self):
        # XXX check that the entrypoint has the correct
        # signature:  list-of-strings -> int
        if not self.make_entrypoint_wrapper:
            bk = self.translator.annotator.bookkeeper
            return getfunctionptr(bk.getdesc(self.entrypoint).getuniquegraph())
        if self._entrypoint_wrapper is not None:
            return self._entrypoint_wrapper
        #
        from rpython.annotator import model as annmodel
        from rpython.rtyper.lltypesystem import rffi
        from rpython.rtyper.annlowlevel import MixLevelHelperAnnotator
        from rpython.rtyper.llannotation import lltype_to_annotation
        entrypoint = self.entrypoint

        #
        def entrypoint_wrapper(argc, argv):
            """This is a wrapper that takes "Signed argc" and "char **argv"
            like the C main function, and puts them inside an RPython list
            of strings before invoking the real entrypoint() function.
            """
            list = [""] * argc
            i = 0
            while i < argc:
                list[i] = rffi.charp2str(argv[i])
                i += 1
            return entrypoint(list)

        #
        mix = MixLevelHelperAnnotator(self.translator.rtyper)
        args_s = [annmodel.SomeInteger(), lltype_to_annotation(rffi.CCHARPP)]
        s_result = annmodel.SomeInteger()
        graph = mix.getgraph(entrypoint_wrapper, args_s, s_result)
        mix.finish()
        res = getfunctionptr(graph)
        self._entrypoint_wrapper = res
        return res
Exemplo n.º 17
0
    def __init__(self, translator):
        self.translator = translator
        self.raise_analyzer = canraise.RaiseAnalyzer(translator)
        edata = translator.rtyper.exceptiondata
        self.lltype_of_exception_value = edata.lltype_of_exception_value
        self.lltype_of_exception_type = edata.lltype_of_exception_type
        self.mixlevelannotator = MixLevelHelperAnnotator(translator.rtyper)
        exc_data, null_type, null_value = self.setup_excdata()

        (assertion_error_ll_exc_type,
         assertion_error_ll_exc) = self.get_builtin_exception(AssertionError)
        (n_i_error_ll_exc_type,
         n_i_error_ll_exc) = self.get_builtin_exception(NotImplementedError)

        self.c_assertion_error_ll_exc_type = constant_value(
            assertion_error_ll_exc_type)
        self.c_n_i_error_ll_exc_type = constant_value(n_i_error_ll_exc_type)

        def rpyexc_occured():
            exc_type = exc_data.exc_type
            return bool(exc_type)

        def rpyexc_fetch_type():
            return exc_data.exc_type

        def rpyexc_fetch_value():
            return exc_data.exc_value

        def rpyexc_clear():
            exc_data.exc_type = null_type
            exc_data.exc_value = null_value

        def rpyexc_raise(etype, evalue):
            # When compiling in debug mode, the following ll_asserts will
            # crash the program as soon as it raises AssertionError or
            # NotImplementedError.  Useful when you are in a debugger.
            # When compiling in release mode, AssertionErrors and
            # NotImplementedErrors are raised normally, and only later
            # caught by debug_catch_exception and printed, which allows
            # us to see at least part of the traceback for them.
            ll_assert(etype != assertion_error_ll_exc_type, "AssertionError")
            ll_assert(etype != n_i_error_ll_exc_type, "NotImplementedError")
            exc_data.exc_type = etype
            exc_data.exc_value = evalue
            lloperation.llop.debug_start_traceback(lltype.Void, etype)

        def rpyexc_reraise(etype, evalue):
            exc_data.exc_type = etype
            exc_data.exc_value = evalue
            lloperation.llop.debug_reraise_traceback(lltype.Void, etype)

        def rpyexc_fetch_exception():
            evalue = rpyexc_fetch_value()
            rpyexc_clear()
            return evalue

        def rpyexc_restore_exception(evalue):
            if evalue:
                exc_data.exc_type = ll_inst_type(evalue)
                exc_data.exc_value = evalue

        self.rpyexc_occured_ptr = self.build_func("RPyExceptionOccurred",
                                                  rpyexc_occured, [],
                                                  lltype.Bool)

        self.rpyexc_fetch_type_ptr = self.build_func(
            "RPyFetchExceptionType", rpyexc_fetch_type, [],
            self.lltype_of_exception_type)

        self.rpyexc_fetch_value_ptr = self.build_func(
            "RPyFetchExceptionValue", rpyexc_fetch_value, [],
            self.lltype_of_exception_value)

        self.rpyexc_clear_ptr = self.build_func("RPyClearException",
                                                rpyexc_clear, [], lltype.Void)

        self.rpyexc_raise_ptr = self.build_func(
            "RPyRaiseException",
            self.noinline(rpyexc_raise),
            [self.lltype_of_exception_type, self.lltype_of_exception_value],
            lltype.Void,
            jitcallkind='rpyexc_raise')  # for the JIT

        self.rpyexc_reraise_ptr = self.build_func(
            "RPyReRaiseException",
            rpyexc_reraise,
            [self.lltype_of_exception_type, self.lltype_of_exception_value],
            lltype.Void,
            jitcallkind='rpyexc_raise')  # for the JIT

        self.rpyexc_fetch_exception_ptr = self.build_func(
            "RPyFetchException", rpyexc_fetch_exception, [],
            self.lltype_of_exception_value)

        self.rpyexc_restore_exception_ptr = self.build_func(
            "RPyRestoreException", self.noinline(rpyexc_restore_exception),
            [self.lltype_of_exception_value], lltype.Void)

        self.build_extra_funcs()

        self.mixlevelannotator.finish()
        self.lltype_to_classdef = translator.rtyper.lltype_to_classdef_mapping(
        )
Exemplo n.º 18
0
 def getannmixlevel(self):
     if self.annmixlevel is not None:
         return self.annmixlevel
     from rpython.rtyper.annlowlevel import MixLevelHelperAnnotator
     self.annmixlevel = MixLevelHelperAnnotator(self)
     return self.annmixlevel
Exemplo n.º 19
0
        load_result = rmarshal.get_loader(s_result)

    except (NotImplementedError, rmarshal.CannotMarshal,
            rmarshal.CannotUnmarshall), e:
        msg = 'Not Implemented: %s' % (e, )
        log.WARNING(msg)

        def execute(*args):
            not_implemented_stub(msg)

    else:

        def execute(*args):
            # marshal the function name and input arguments
            buf = []
            dump_string(buf, fnname)
            dump_arguments(buf, args)
            # send the buffer and wait for the answer
            loader = sandboxed_io(buf)
            # decode the answer
            result = load_result(loader)
            loader.check_finished()
            return result

    execute = func_with_new_name(execute, 'sandboxed_' + fnname)

    ann = MixLevelHelperAnnotator(db.translator.rtyper)
    graph = ann.getgraph(execute, args_s, s_result)
    ann.finish()
    return graph
Exemplo n.º 20
0
def _annotate(rtyper, f, args_s, s_result):
    ann = MixLevelHelperAnnotator(rtyper)
    graph = ann.getgraph(f, args_s, s_result)
    ann.finish()
    return graph