Esempio n. 1
0
def call_final_function(translator, final_func, annhelper=None):
    """When the program finishes normally, call 'final_func()'."""
    from pypy.annotation import model as annmodel
    from pypy.rpython.lltypesystem import lltype
    from pypy.rpython.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 = copyvar(translator.annotator, entry_point.getreturnvar())
    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)
Esempio 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
Esempio n. 3
0
 def make_driverhook_graphs(self):
     from pypy.rlib.jit import BaseJitCell
     bk = self.rtyper.annotator.bookkeeper
     classdef = bk.getuniqueclassdef(BaseJitCell)
     s_BaseJitCell_or_None = annmodel.SomeInstance(classdef,
                                                   can_be_None=True)
     s_BaseJitCell_not_None = annmodel.SomeInstance(classdef)
     s_Str = annmodel.SomeString()
     #
     annhelper = MixLevelHelperAnnotator(self.translator.rtyper)
     for jd in self.jitdrivers_sd:
         jd._set_jitcell_at_ptr = self._make_hook_graph(jd,
             annhelper, jd.jitdriver.set_jitcell_at, annmodel.s_None,
             s_BaseJitCell_not_None)
         jd._get_jitcell_at_ptr = self._make_hook_graph(jd,
             annhelper, jd.jitdriver.get_jitcell_at, s_BaseJitCell_or_None)
         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()
Esempio 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
Esempio n. 5
0
def builtin_func_for_spec(rtyper, oopspec_name, ll_args, ll_res):
    key = (oopspec_name, tuple(ll_args), ll_res)
    try:
        return rtyper._builtin_func_for_spec_cache[key]
    except (KeyError, AttributeError):
        pass
    args_s = [annmodel.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 = annmodel.lltype_to_annotation(ll_res)
    impl = setup_extra_builtin(rtyper, oopspec_name, len(args_s))
    if getattr(impl, 'need_result_type', False):
        bk = rtyper.annotator.bookkeeper
        args_s.insert(0, annmodel.SomePBC([bk.getdesc(deref(ll_res))]))
    #
    mixlevelann = MixLevelHelperAnnotator(rtyper)
    c_func = mixlevelann.constfunc(impl, args_s, s_result)
    mixlevelann.finish()
    #
    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
Esempio n. 6
0
 def build_meta_interp(self,
                       CPUClass,
                       translate_support_code=False,
                       view="auto",
                       no_stats=False,
                       ProfilerClass=EmptyProfiler,
                       **kwds):
     assert CPUClass is not None
     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)
         annhelper = self.annhelper
     else:
         annhelper = None
     cpu = CPUClass(self.translator.rtyper,
                    self.stats,
                    translate_support_code,
                    gcdescr=self.gcdescr)
     self.cpu = cpu
     self.metainterp_sd = MetaInterpStaticData(
         self.portal_graph,  # xxx
         cpu,
         self.stats,
         opt,
         ProfilerClass=ProfilerClass,
         warmrunnerdesc=self)
Esempio n. 7
0
 def make_leave_jit_graph(self):
     self.leave_graph = None
     if self.jitdriver.leave:
         args_s = self.portal_args_s
         from pypy.annotation import model as annmodel
         annhelper = MixLevelHelperAnnotator(self.translator.rtyper)
         s_result = annmodel.s_None
         self.leave_graph = annhelper.getgraph(self.jitdriver.leave,
                                               args_s, s_result)
         annhelper.finish()
Esempio n. 8
0
def test_enforced_args():
    from pypy.annotation.model import s_None
    from pypy.rpython.annlowlevel import MixLevelHelperAnnotator
    from pypy.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()
Esempio n. 9
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(type_system='lltype').specialize()
        exctransformer = t.getexceptiontransformer()
        exctransformer.create_exception_handling(graphof(t, common))
        from pypy.annotation import model as annmodel
        from pypy.rpython.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 conftest.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 pypy.rpython.llinterp import LLInterpreter
        llinterp = LLInterpreter(t.rtyper)
        res = llinterp.eval_graph(later_graph, [10])
        assert res == 1
Esempio n. 10
0
 def __init__(self, translator, inline=False):
     self.translator = translator
     self.seen_graphs = {}
     self.prepared = False
     self.minimal_transform = {}
     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.graphs_to_inline = {}
     self.graph_dependencies = {}
     self.ll_finalizers_ptrs = []
     if self.MinimalGCTransformer:
         self.minimalgctransformer = self.MinimalGCTransformer(self)
     else:
         self.minimalgctransformer = None
Esempio n. 11
0
 def make_driverhook_graphs(self):
     from pypy.rlib.jit import BaseJitCell
     bk = self.rtyper.annotator.bookkeeper
     classdef = bk.getuniqueclassdef(BaseJitCell)
     s_BaseJitCell_or_None = annmodel.SomeInstance(classdef,
                                                   can_be_None=True)
     s_BaseJitCell_not_None = annmodel.SomeInstance(classdef)
     s_Str = annmodel.SomeString()
     #
     annhelper = MixLevelHelperAnnotator(self.translator.rtyper)
     self.set_jitcell_at_ptr = self._make_hook_graph(
         annhelper, self.jitdriver.set_jitcell_at, annmodel.s_None,
         s_BaseJitCell_not_None)
     self.get_jitcell_at_ptr = self._make_hook_graph(
         annhelper, self.jitdriver.get_jitcell_at, s_BaseJitCell_or_None)
     self.can_inline_ptr = self._make_hook_graph(annhelper,
                                                 self.jitdriver.can_inline,
                                                 annmodel.s_Bool)
     self.get_printable_location_ptr = self._make_hook_graph(
         annhelper, self.jitdriver.get_printable_location, s_Str)
     annhelper.finish()
Esempio n. 12
0
def call_initial_function(translator, initial_func, annhelper=None):
    """Before the program starts, call 'initial_func()'."""
    from pypy.annotation import model as annmodel
    from pypy.rpython.lltypesystem import lltype
    from pypy.rpython.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 = [copyvar(translator.annotator, v) 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)
Esempio n. 13
0
    def replace_promote_virtualizable(self, rtyper, graphs):
        from pypy.annotation import model as annmodel
        from pypy.rpython.annlowlevel import MixLevelHelperAnnotator
        graph = graphs[0]

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

        def mycall(vinst_ll):
            pass

        annhelper = MixLevelHelperAnnotator(rtyper)
        if self.type_system == 'lltype':
            s_vinst = annmodel.SomePtr(v_inst_ll_type)
        else:
            s_vinst = annmodel.SomeOOInstance(v_inst_ll_type)
        funcptr = annhelper.delayedfunction(mycall, [s_vinst], annmodel.s_None)
        annhelper.finish()
        replace_promote_virtualizable_with_call(graphs, v_inst_ll_type,
                                                funcptr)
        return funcptr
Esempio n. 14
0
 def getannmixlevel(self):
     if self.annmixlevel is not None:
         return self.annmixlevel
     from pypy.rpython.annlowlevel import MixLevelHelperAnnotator
     self.annmixlevel = MixLevelHelperAnnotator(self)
     return self.annmixlevel
Esempio n. 15
0
        argc = get_argc()
        argv = get_argv()
        args = [rffi.charp2str(argv[i]) for i in range(argc)]

        result = 1
        try:
            result = entrypoint(args)
        except Exception, exc:
            os.write(
                2, 'DEBUG: An uncaught exception was raised in entrypoint: ' +
                str(exc) + '\n')

        return result

    entrypoint._annenforceargs_ = [s_list_of_strings]
    mixlevelannotator = MixLevelHelperAnnotator(translator.rtyper)
    res = annmodel.lltype_to_annotation(lltype.Signed)
    graph = mixlevelannotator.getgraph(new_entrypoint, [], res)
    mixlevelannotator.finish()
    mixlevelannotator.backend_optimize()

    return new_entrypoint


class GenLLVM(object):
    # see create_codewriter() below
    function_count = {}

    def __init__(self, translator, standalone):

        # reset counters
Esempio n. 16
0
    def __init__(self, translator):
        self.translator = translator
        self.raise_analyzer = canraise.RaiseAnalyzer(translator)
        edata = translator.rtyper.getexceptiondata()
        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()

        rclass = translator.rtyper.type_system.rclass
        (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 = rclass.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(
        )
Esempio n. 17
0
    def __init__(self, translator):
        self.translator = translator
        self.raise_analyzer = canraise.RaiseAnalyzer(translator)
        edata = translator.rtyper.getexceptiondata()
        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()

        rclass = translator.rtyper.type_system.rclass
        (runtime_error_ll_exc_type,
         runtime_error_ll_exc) = self.get_builtin_exception(RuntimeError)
        (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)

        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):
            # assert(!RPyExceptionOccurred());
            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

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

        def rpyexc_restore_exception(evalue):
            if evalue:
                rpyexc_raise(rclass.ll_inst_type(evalue), evalue)

        def rpyexc_raise_runtime_error():
            rpyexc_raise(runtime_error_ll_exc_type, runtime_error_ll_exc)

        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",
            rpyexc_raise,
            [self.lltype_of_exception_type, self.lltype_of_exception_value],
            lltype.Void,
            jitcallkind='rpyexc_raise')  # for the JIT

        self.rpyexc_raise_runtime_error_ptr = self.build_func(
            "RPyRaiseRuntimeError", rpyexc_raise_runtime_error, [],
            lltype.Void)

        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", 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(
        )
Esempio n. 18
0
        dump_arguments = rmarshal.get_marshaller(tuple(args_s))
        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