Пример #1
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
Пример #2
0
 def annotate_walker_functions(self, getfn):
     self.incr_stack_ptr = getfn(self.root_walker.incr_stack,
                                 [annmodel.SomeInteger()],
                                 SomeAddress(),
                                 inline=True)
     self.decr_stack_ptr = getfn(self.root_walker.decr_stack,
                                 [annmodel.SomeInteger()],
                                 SomeAddress(),
                                 inline=True)
Пример #3
0
        class CTestFuncEntry(ExtFuncEntry):
            _about_ = c
            name = 'ccc'
            signature_args = [annmodel.SomeInteger()] * 2
            signature_result = annmodel.SomeInteger()

            def lltypeimpl(y, x):
                return y + x
            lltypeimpl = staticmethod(lltypeimpl)
Пример #4
0
 def test_cast_primitive(self):
     def llf(u):
         return cast_primitive(Signed, u)
     s = self.annotate(llf, [annmodel.SomeInteger(unsigned=True)])
     assert s.knowntype == int
     def llf(s):
         return cast_primitive(Unsigned, s)
     s = self.annotate(llf, [annmodel.SomeInteger()])
     assert s.unsigned == True
Пример #5
0
def test_return_any():
    @signature(types.int(), returns=types.any())
    def f(x):
        return x
    sig = getsig(f)
    assert sig == [model.SomeInteger(), model.SomeInteger()]

    @signature(types.str(), returns=types.any())
    def cannot_add_string(x):
        return f(3) + x
    exc = py.test.raises(model.AnnotatorError, annotate_at, cannot_add_string).value
    assert 'Blocked block' in str(exc)
    assert 'cannot_add_string' in str(exc)
Пример #6
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()
Пример #7
0
    def test_stress(self):
        from rpython.annotator.dictdef import DictKey, DictValue
        from rpython.annotator import model as annmodel
        from rpython.rtyper import rint
        from rpython.rtyper.test.test_rdict import not_really_random
        rodct = rordereddict
        dictrepr = rodct.OrderedDictRepr(
            None, rint.signed_repr, rint.signed_repr,
            DictKey(None, annmodel.SomeInteger()),
            DictValue(None, annmodel.SomeInteger()))
        dictrepr.setup()
        l_dict = rodct.ll_newdict(dictrepr.DICT)
        referencetable = [None] * 400
        referencelength = 0
        value = 0

        def complete_check():
            for n, refvalue in zip(range(len(referencetable)), referencetable):
                try:
                    gotvalue = rodct.ll_dict_getitem(l_dict, n)
                except KeyError:
                    assert refvalue is None
                else:
                    assert gotvalue == refvalue

        for x in not_really_random():
            n = int(x * 100.0)  # 0 <= x < 400
            op = repr(x)[-1]
            if op <= '2' and referencetable[n] is not None:
                rodct.ll_dict_delitem(l_dict, n)
                referencetable[n] = None
                referencelength -= 1
            elif op <= '6':
                rodct.ll_dict_setitem(l_dict, n, value)
                if referencetable[n] is None:
                    referencelength += 1
                referencetable[n] = value
                value += 1
            else:
                try:
                    gotvalue = rodct.ll_dict_getitem(l_dict, n)
                except KeyError:
                    assert referencetable[n] is None
                else:
                    assert gotvalue == referencetable[n]
            if 1.38 <= x <= 1.39:
                complete_check()
                print 'current dict length:', referencelength
            assert l_dict.num_live_items == referencelength
        complete_check()
Пример #8
0
def test_funny_links():
    from rpython.flowspace.model import Block, FunctionGraph, \
         Variable, Constant, Link
    from rpython.flowspace.operation import op
    for i in range(2):
        v_i = Variable("i")
        block = Block([v_i])
        g = FunctionGraph("is_one", block)
        op1 = op.eq(v_i, Constant(1))
        block.operations.append(op1)
        block.exitswitch = op1.result
        tlink = Link([Constant(1)], g.returnblock, True)
        flink = Link([Constant(0)], g.returnblock, False)
        links = [tlink, flink]
        if i:
            links.reverse()
        block.closeblock(*links)
        t = TranslationContext()
        a = t.buildannotator()
        a.build_graph_types(g, [annmodel.SomeInteger()])
        rtyper = t.buildrtyper()
        rtyper.specialize()
        interp = LLInterpreter(rtyper)
        assert interp.eval_graph(g, [1]) == 1
        assert interp.eval_graph(g, [0]) == 0
Пример #9
0
def test_any_as_argument():
    @signature(types.any(), types.int(), returns=types.float())
    def f(x, y):
        return x + y

    @signature(types.int(), returns=types.float())
    def g(x):
        return f(x, x)

    sig = getsig(g)
    assert sig == [model.SomeInteger(), model.SomeFloat()]

    @signature(types.float(), returns=types.float())
    def g(x):
        return f(x, 4)

    sig = getsig(g)
    assert sig == [model.SomeFloat(), model.SomeFloat()]

    @signature(types.str(), returns=types.int())
    def cannot_add_string(x):
        return f(x, 2)

    exc = py.test.raises(model.AnnotatorError, annotate_at,
                         cannot_add_string).value
    assert 'Blocked block' in str(exc)
Пример #10
0
    class Entry(ExtRegistryEntry):
        _about_ = dummy_func
        s_result_annotation = annmodel.SomeInteger()

        def specialize_call(self, hop):
            hop.exception_cannot_occur()
            return hop.inputconst(lltype.Signed, 42)
Пример #11
0
 def arguments_ALLOCATING(self):
     from rpython.annotator import model as annmodel
     from rpython.rtyper import llannotation
     return [
         annmodel.SomeInteger(knowntype=r_longlong),
         llannotation.lltype_to_annotation(llmemory.GCREF)
     ]
        def __init__(self, rtyper):
            super(RuleRepr, self).__init__()

            self.ll_rule_cache = {}

            self.match_init_repr = rtyper.getrepr(
                rtyper.annotator.bookkeeper.immutablevalue(Match.__init__)
            )
            self.match_context_init_repr = rtyper.getrepr(
                rtyper.annotator.bookkeeper.immutablevalue(
                    rsre_core.StrMatchContext.__init__
                )
            )
            self.match_context_repr = rtyper.getrepr(
                rtyper.annotator.bookkeeper.immutablevalue(
                    rsre_core.match_context
                )
            )

            list_repr = FixedSizeListRepr(
                rtyper, rtyper.getrepr(model.SomeInteger(nonneg=True))
            )
            list_repr._setup_repr()
            self.lowleveltype = lltype.Ptr(lltype.GcStruct(
                "RULE",
                ("name", lltype.Ptr(STR)),
                ("code", list_repr.lowleveltype),
                ("flags", lltype.Signed),
            ))
Пример #13
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
Пример #14
0
 def compute_result_annotation(self, s_l):
     from rpython.annotator import model as annmodel
     if annmodel.s_None.contains(s_l):
         pass  # first argument is only None so far, but we
         # expect a generalization later
     elif not isinstance(s_l, annmodel.SomeList):
         raise annmodel.AnnotatorError("First argument must be a list")
     return annmodel.SomeInteger(nonneg=True)
Пример #15
0
def test_dict():
    @signature(returns=types.dict(types.str(), types.int()))
    def f():
        return {'a': 1, 'b': 2}
    rettype = getsig(f)[0]
    assert isinstance(rettype, model.SomeDict)
    assert rettype.dictdef.dictkey.s_value   == model.SomeString()
    assert rettype.dictdef.dictvalue.s_value == model.SomeInteger()
Пример #16
0
        def method_matches(self, s_s, s_pos):
            assert model.SomeString().contains(s_s)
            assert model.SomeInteger(nonneg=True).contains(s_pos)

            bk = getbookkeeper()
            init_pbc = bk.immutablevalue(Match.__init__)
            bk.emulate_pbc_call((self, "match_init"), init_pbc, [
                model.SomeInstance(bk.getuniqueclassdef(Match)),
                model.SomeInteger(nonneg=True),
                model.SomeInteger(nonneg=True)
            ])
            init_pbc = bk.immutablevalue(rsre_core.StrMatchContext.__init__)
            bk.emulate_pbc_call((self, "str_match_context_init"), init_pbc, [
                model.SomeInstance(
                    bk.getuniqueclassdef(rsre_core.StrMatchContext)),
                bk.newlist(model.SomeInteger(nonneg=True)),
                model.SomeString(),
                model.SomeInteger(nonneg=True),
                model.SomeInteger(nonneg=True),
                model.SomeInteger(nonneg=True),
            ])
            match_context_pbc = bk.immutablevalue(rsre_core.match_context)
            bk.emulate_pbc_call((self, "match_context"), match_context_pbc, [
                model.SomeInstance(
                    bk.getuniqueclassdef(rsre_core.StrMatchContext)),
            ])

            return model.SomeInstance(getbookkeeper().getuniqueclassdef(Match),
                                      can_be_None=True)
Пример #17
0
    def build_increase_root_stack_depth_ptr(self, getfn):
        shadow_stack_pool = self.shadow_stack_pool

        def gc_increase_root_stack_depth(new_size):
            shadow_stack_pool.increase_root_stack_depth(new_size)

        self.gc_increase_root_stack_depth_ptr = getfn(
            gc_increase_root_stack_depth, [annmodel.SomeInteger()],
            annmodel.s_None)
Пример #18
0
def test_longlong():
    # get_loader for (r_longolong, nonneg=True) used to return
    # load_int_nonneg on 32-bit, instead of load_longlong.
    for nonneg in [True, False]:
        s_longlong = annmodel.SomeInteger(knowntype=r_longlong, nonneg=nonneg)
        load = get_loader(s_longlong)
        loader = Loader("I\x01\x23\x45\x67\x89\xab\xcd\x0e")
        res = load(loader)
        assert res == 0x0ecdab8967452301
Пример #19
0
 def compute_result_annotation(self, s_driver, s_name, s_value):
     from rpython.annotator import model as annmodel
     assert s_name.is_constant()
     if s_name.const == 'enable_opts':
         assert annmodel.SomeString(can_be_None=True).contains(s_value)
     else:
         assert (s_value == annmodel.s_None
                 or annmodel.SomeInteger().contains(s_value))
     return annmodel.s_None
Пример #20
0
def test_basic():
    @signature(types.int(), types.str(), returns=types.char())
    def f(a, b):
        return b[a]

    assert getsig(f) == [
        model.SomeInteger(),
        model.SomeString(),
        model.SomeChar()
    ]
Пример #21
0
def test_array():
    @signature(returns=types.array(types.int()))
    def f():
        return [1]
    rettype = getsig(f)[0]
    assert isinstance(rettype, model.SomeList)
    item = rettype.listdef.listitem
    assert item.s_value == model.SomeInteger()
    assert item.resized == False

    def try_append():
        l = f()
        l.append(2)
    check_annotator_fails(try_append)
Пример #22
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
Пример #23
0
 def test_oopspec(self):
     lst1 = [123, 456]     # non-mutated list
     def f(i):
         lst2 = [i]
         lst2.append(42)    # mutated list
         return lst1[i] + lst2[i]
     from rpython.annotator import model as annmodel
     _, _, graph = self.gengraph(f, [annmodel.SomeInteger(nonneg=True)])
     block = graph.startblock
     lst1_getitem_op = block.operations[-3]     # XXX graph fishing
     lst2_getitem_op = block.operations[-2]
     func1 = lst1_getitem_op.args[2].value
     func2 = lst2_getitem_op.args[2].value
     assert func1.oopspec == 'list.getitem_foldable(l, index)'
     assert not hasattr(func2, 'oopspec')
Пример #24
0
def test_list():
    @signature(types.list(types.int()), returns=types.int())
    def f(a):
        return len(a)

    argtype = getsig(f)[0]
    assert isinstance(argtype, model.SomeList)
    item = argtype.listdef.listitem
    assert item.s_value == model.SomeInteger()
    assert item.resized == True

    @check_annotator_fails
    def ok_for_body():
        f(['a'])

    @check_annotator_fails
    def bad_for_body():
        f('a')

    @signature(returns=types.list(types.char()))
    def ff():
        return ['a']

    @check_annotator_fails
    def mutate_broader():
        ff()[0] = 'abc'

    @check_annotator_fails
    def mutate_unrelated():
        ff()[0] = 1

    @check_annotator_fails
    @signature(types.list(types.char()), returns=types.int())
    def mutate_in_body(l):
        l[0] = 'abc'
        return len(l)

    def can_append():
        l = ff()
        l.append('b')

    getsig(can_append)
Пример #25
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._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)
     annhelper.finish()
Пример #26
0
    def test_mix_after_recursion(self):
        def prefn(n):
            if n:
                return 2 * prefn(n - 1)
            else:
                return 1

        t = TranslationContext()
        a = t.buildannotator()
        a.build_types(prefn, [int])
        typer = t.buildrtyper()
        typer.specialize()

        #t.view()

        def f():
            return 1

        from rpython.rtyper import annlowlevel
        annhelper = annlowlevel.MixLevelHelperAnnotator(typer)
        graph = annhelper.getgraph(f, [], annmodel.SomeInteger())
        annhelper.finish()
Пример #27
0
 def compute_result_annotation(self):
     from rpython.annotator import model as annmodel
     return annmodel.SomeInteger()
Пример #28
0
 def annotation(self):
     from rpython.annotator import model
     return model.SomeInteger()
Пример #29
0
    return lltype.nullptr(llmemory.GCREF.TO)


@register_helper(SomePtr(llmemory.GCREF))
def resop_new(no, llargs, llres):
    from rpython.jit.metainterp.history import ResOperation

    args = [_cast_to_box(llargs[i]) for i in range(len(llargs))]
    if llres:
        res = _cast_to_box(llres)
    else:
        res = None
    return _cast_to_gcref(ResOperation(no, args, res))


@register_helper(annmodel.SomeInteger())
def resop_getopnum(llop):
    return _cast_to_resop(llop).getopnum()


@register_helper(annmodel.SomeString(can_be_None=True))
def resop_getopname(llop):
    return llstr(_cast_to_resop(llop).getopname())


@register_helper(SomePtr(llmemory.GCREF))
def resop_getarg(llop, no):
    return _cast_to_gcref(_cast_to_resop(llop).getarg(no))


@register_helper(annmodel.s_None)
Пример #30
0
    def meta_interp(self,
                    function,
                    args,
                    repeat=1,
                    inline=False,
                    trace_limit=sys.maxint,
                    backendopt=None,
                    listcomp=False,
                    **kwds):  # XXX ignored
        from rpython.jit.metainterp.warmspot import WarmRunnerDesc
        from rpython.annotator.listdef import s_list_of_strings
        from rpython.annotator import model as annmodel

        for arg in args:
            assert is_valid_int(arg)

        self.pre_translation_hook()
        t = self._get_TranslationContext()
        if listcomp:
            t.config.translation.list_comprehension_operations = True

        arglist = ", ".join(
            ['int(argv[%d])' % (i + 1) for i in range(len(args))])
        if len(args) == 1:
            arglist += ','
        arglist = '(%s)' % arglist
        if repeat != 1:
            src = py.code.Source("""
            def entry_point(argv):
                args = %s
                res = function(*args)
                for k in range(%d - 1):
                    res = function(*args)
                print res
                return 0
            """ % (arglist, repeat))
        else:
            src = py.code.Source("""
            def entry_point(argv):
                args = %s
                res = function(*args)
                print res
                return 0
            """ % (arglist, ))
        exec src.compile() in locals()

        t.buildannotator().build_types(function, [int] * len(args),
                                       main_entry_point=True)
        t.buildrtyper().specialize()
        warmrunnerdesc = WarmRunnerDesc(t,
                                        translate_support_code=True,
                                        CPUClass=self.CPUClass,
                                        **kwds)
        for jd in warmrunnerdesc.jitdrivers_sd:
            jd.warmstate.set_param_threshold(3)  # for tests
            jd.warmstate.set_param_trace_eagerness(2)  # for tests
            jd.warmstate.set_param_trace_limit(trace_limit)
            jd.warmstate.set_param_inlining(inline)
            jd.warmstate.set_param_enable_opts(ALL_OPTS_NAMES)
        mixlevelann = warmrunnerdesc.annhelper
        entry_point_graph = mixlevelann.getgraph(entry_point,
                                                 [s_list_of_strings],
                                                 annmodel.SomeInteger())
        warmrunnerdesc.finish()
        self.post_translation_hook()
        return self._compile_and_run(t, entry_point, entry_point_graph, args)