Esempio n. 1
0
def test_cancollect_external():
    fext1 = rffi.llexternal('fext1', [], lltype.Void, threadsafe=False)
    def g():
        fext1()
    t = rtype(g, [])
    gg = graphof(t, g)
    assert not CollectAnalyzer(t).analyze_direct_call(gg)

    fext2 = rffi.llexternal('fext2', [], lltype.Void, threadsafe=True)
    def g():
        fext2()
    t = rtype(g, [])
    gg = graphof(t, g)
    assert CollectAnalyzer(t).analyze_direct_call(gg)

    S = lltype.GcStruct('S', ('x', lltype.Signed))
    FUNC = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void))
    fext3 = rffi.llexternal('fext3', [FUNC], lltype.Void, threadsafe=False)
    def h(x):
        lltype.malloc(S, zero=True)
    def g():
        fext3(h)
    t = rtype(g, [])
    gg = graphof(t, g)
    assert CollectAnalyzer(t).analyze_direct_call(gg)
Esempio n. 2
0
def test_multiple_calls():
    class A:
        pass
    class B(A):
        pass
    def g2(b, i): 
        b.i = h(i)
    def g1(a, b, i):
        a.b = b
        g2(b, h(i))
        return a.b.i
    def h(x):
        return x + 42
    def fn(i):
        a = A()
        b = B()
        x = h(i)
        return g1(a, b, x)
    t, graph = rtype(fn, [int])
    callgraph, caller_candidates = check_inlining(t, graph, [0], 3 * 42)
    print callgraph
    assert caller_candidates == {graph: True}
    assert len(callgraph) == 1
    g1graph = graphof(t, g1)
    g2graph = graphof(t, g2)
    assert callgraph == {graph: {g1graph: True}}
    callgraph, caller_candidates = check_inlining(t, graph, [0], 3 * 42)
    assert callgraph == {graph: {g2graph: True}}
Esempio n. 3
0
    def test_normalize_abstract_method(self):
        class Base:
            def fn(self):
                raise NotImplementedError
        class Sub1(Base):
            def fn(self):
                return 1
        class Sub2(Base):
            def fn(self):
                return -2
        def dummyfn(n):
            if n == 1:
                x = Sub1()
            else:
                x = Sub2()
            return x.fn()

        translator = self.rtype(dummyfn, [int], int)
        base_graph = graphof(translator, Base.fn.im_func)
        sub1_graph = graphof(translator, Sub1.fn.im_func)
        sub2_graph = graphof(translator, Sub2.fn.im_func)
        assert base_graph.getreturnvar().concretetype == lltype.Signed
        assert sub1_graph.getreturnvar().concretetype == lltype.Signed
        assert sub2_graph.getreturnvar().concretetype == lltype.Signed

        llinterp = LLInterpreter(translator.rtyper)
        res = llinterp.eval_graph(graphof(translator, dummyfn), [1])
        assert res == 1
        res = llinterp.eval_graph(graphof(translator, dummyfn), [2])
        assert res == -2
Esempio n. 4
0
 def check_inline(self, func, in_func, sig, entry=None,
                  inline_guarded_calls=False,
                  graph=False):
     if entry is None:
         entry = in_func
     t = self.translate(entry, sig)
     # inline!
     sanity_check(t)    # also check before inlining (so we don't blame it)
     if option.view:
         t.view()
     raise_analyzer = canraise.RaiseAnalyzer(t)
     inliner = Inliner(t, graphof(t, in_func), func,
                       t.rtyper.lltype_to_classdef_mapping(),
                       inline_guarded_calls,
                       raise_analyzer=raise_analyzer)
     inliner.inline_all()
     if option.view:
         t.view()
     sanity_check(t)
     interp = LLInterpreter(t.rtyper)
     def eval_func(args):
         return interp.eval_graph(graphof(t, entry), args)
     if graph:
         return eval_func, graphof(t, func)
     return eval_func
Esempio n. 5
0
    def rtype(self, fn, argtypes, resulttype, checkfunction=None):
        t = TranslationContext()
        a = t.buildannotator()
        a.build_types(prefn, [int])
        typer = t.buildrtyper()
        typer.specialize()
        #t.view()

        s_result = a.typeannotation(resulttype)

        from pypy.rpython import annlowlevel
        # annotate, normalize and rtype fn after the fact
        annhelper = annlowlevel.MixLevelHelperAnnotator(typer)               
        graph = annhelper.getgraph(fn, [a.typeannotation(argtype) for argtype in argtypes],
                                   s_result)
        annhelper.finish()
        t.checkgraphs()

        if checkfunction is not None:
            checkfunction(t)

        # sanity check prefn
        llinterp = LLInterpreter(typer)
        res = llinterp.eval_graph(graphof(t, prefn), [1])
        assert res == 100
        res = llinterp.eval_graph(graphof(t, prefn), [2])
        assert res == 201
        
        return t
Esempio n. 6
0
    def test_add_more_subclasses(self):
        from pypy.rpython import rclass
        from pypy.rpython.lltypesystem.rclass import ll_issubclass
        from pypy.rpython.lltypesystem.rclass import CLASSTYPE
        class Sub3(PBase):
            def newmethod(self):
                return 3
        def dummyfn(n):
            x = Sub3()
            return x.newmethod()

        def checkfunction(translator):
            # make sure that there is a sensible comparison defined on the
            # symbolics
            bk = translator.annotator.bookkeeper
            rtyper = translator.rtyper
            base_classdef = bk.getuniqueclassdef(PBase)
            base_vtable = rclass.getclassrepr(rtyper, base_classdef).getruntime(CLASSTYPE)
            sub3_classdef = bk.getuniqueclassdef(Sub3)
            sub3_vtable = rclass.getclassrepr(rtyper, sub3_classdef).getruntime(CLASSTYPE)
            assert ll_issubclass(sub3_vtable, base_vtable)
            assert not ll_issubclass(base_vtable, sub3_vtable)

        translator = self.rtype(dummyfn, [int], int, checkfunction)
        base_graph    = graphof(translator, PBase.fn.im_func)
        sub1_graph    = graphof(translator, PSub1.fn.im_func)
        sub2_graph    = graphof(translator, PSub2.fn.im_func)
        sub3_graph    = graphof(translator, Sub3.fn.im_func)
        dummyfn_graph = graphof(translator, dummyfn)
        assert base_graph.getreturnvar().concretetype == lltype.Signed
        assert sub1_graph.getreturnvar().concretetype == lltype.Signed
        assert sub2_graph.getreturnvar().concretetype == lltype.Signed
        assert sub3_graph.getreturnvar().concretetype == lltype.Signed
        assert dummyfn_graph.getreturnvar().concretetype == lltype.Signed
Esempio n. 7
0
    def test_normalize_f2_as_taking_string_argument(self):
        def f1(l1):
            pass
        def f2(l2):
            pass
        def g(n):
            if n > 0:
                f1("123")
                f = f1
            else:
                f2("b")
                f = f2
            f("a")

        # The call table looks like:
        #
        #                 FuncDesc(f1)  FuncDesc(f2)
        #   --------------------------------------------
        #   line g+2:       graph1
        #   line g+5:                      graph2
        #   line g+7:       graph1         graph2
        #
        # But all lines get compressed to a single line.

        translator = self.rtype(g, [int], annmodel.s_None)
        f1graph = graphof(translator, f1)
        f2graph = graphof(translator, f2)
        s_l1 = translator.annotator.binding(f1graph.getargs()[0])
        s_l2 = translator.annotator.binding(f2graph.getargs()[0])
        assert s_l1.__class__ == annmodel.SomeString   # and not SomeChar
        assert s_l2.__class__ == annmodel.SomeString   # and not SomeChar
Esempio n. 8
0
    def test_llexternal(self):
        from pypy.rpython.lltypesystem.rffi import llexternal
        from pypy.rpython.lltypesystem import lltype
        z = llexternal('z', [lltype.Signed], lltype.Signed)
        def f(x):
            return z(x)
        t, ra = self.translate(f, [int])
        fgraph = graphof(t, f)
        backend_optimizations(t)
        assert fgraph.startblock.operations[0].opname == 'direct_call'

        result = ra.can_raise(fgraph.startblock.operations[0])
        assert not result

        z = lltype.functionptr(lltype.FuncType([lltype.Signed], lltype.Signed),
                               'foobar')
        def g(x):
            return z(x)
        t, ra = self.translate(g, [int])
        ggraph = graphof(t, g)

        assert ggraph.startblock.operations[0].opname == 'direct_call'

        result = ra.can_raise(ggraph.startblock.operations[0])
        assert result
Esempio n. 9
0
def test_half_exceptiontransformed_graphs():
    from pypy.translator import exceptiontransform

    def f1(x):
        if x < 0:
            raise ValueError
        return 754

    def g1(x):
        try:
            return f1(x)
        except ValueError:
            return 5

    def f2(x):
        if x < 0:
            raise ValueError
        return 21

    def g2(x):
        try:
            return f2(x)
        except ValueError:
            return 6

    f3 = lltype.functionptr(lltype.FuncType([lltype.Signed], lltype.Signed), "f3", _callable=f1)

    def g3(x):
        try:
            return f3(x)
        except ValueError:
            return 7

    def f(flag, x):
        if flag == 1:
            return g1(x)
        elif flag == 2:
            return g2(x)
        else:
            return g3(x)

    t = TranslationContext()
    t.buildannotator().build_types(f, [int, int])
    t.buildrtyper().specialize()
    etrafo = exceptiontransform.ExceptionTransformer(t)
    etrafo.create_exception_handling(graphof(t, f1))
    etrafo.create_exception_handling(graphof(t, g2))
    etrafo.create_exception_handling(graphof(t, g3))
    graph = graphof(t, f)
    interp = LLInterpreter(t.rtyper)
    res = interp.eval_graph(graph, [1, -64])
    assert res == 5
    res = interp.eval_graph(graph, [2, -897])
    assert res == 6
    res = interp.eval_graph(graph, [3, -9831])
    assert res == 7
Esempio n. 10
0
def test_annotate_r_dict():
    t = TranslationContext()
    a = t.buildannotator()
    a.build_types(test_r_dict, [])
    #t.view()
    graph = graphof(t, strange_key_eq)
    assert a.binding(graph.getargs()[0]).knowntype == str
    assert a.binding(graph.getargs()[1]).knowntype == str
    graph = graphof(t, strange_key_hash)
    assert a.binding(graph.getargs()[0]).knowntype == str
def test_cancollect():
    S = lltype.GcStruct('S', ('x', lltype.Signed))
    def g():
        lltype.malloc(S, zero=True)
    t = rtype(g, [])
    gg = graphof(t, g)
    assert CollectAnalyzer(t).analyze_direct_call(gg)

    def g(x):
        return -x
    t = rtype(g, [int])
    gg = graphof(t, g)
    assert not CollectAnalyzer(t).analyze_direct_call(gg)    
Esempio n. 12
0
def get_graph(arg, translator):
    from pypy.translator.translator import graphof

    if isinstance(arg, Variable):
        return None
    f = arg.value
    from pypy.rpython.lltypesystem import lltype
    from pypy.rpython.ootypesystem import ootype

    if not isinstance(f, lltype._ptr) and not isinstance(f, ootype._callable):
        return None
    funcobj = get_funcobj(f)
    try:
        callable = funcobj._callable
    except (AttributeError, KeyError, AssertionError):
        return None
    try:
        return funcobj.graph
    except AttributeError:
        return None
    try:
        callable = funcobj._callable
        return graphof(translator, callable)
    except (AttributeError, KeyError, AssertionError):
        return None
Esempio n. 13
0
def translate(func, argtypes, backend_optimize=True):
    t = TranslationContext()
    t.buildannotator().build_types(func, argtypes)
    t.buildrtyper().specialize()
    if backend_optimize:
        backend_optimizations(t)
    return graphof(t, func), t
Esempio n. 14
0
def test_tuple():
    def f(x, y):
        return h(x + 1, x * y)
    def h(x, y):
        return x, y

    def g(x):
        a, b = f(x, x*5)
        return a + b
    t, graph = rtype(g, [int])
    callgraph, caller_candidates = check_inlining(t, graph, [2], 23)
    assert caller_candidates == {graph: True}
    assert len(callgraph) == 2
    fgraph = graphof(t, f)
    hgraph = graphof(t, h)
    assert callgraph == {graph: {fgraph: True}, fgraph: {hgraph:  True}}
Esempio n. 15
0
def test_substruct():
    class A(object):
        pass
    class B(object):
        pass
    def g(a, b):
        a.b = b
        a.b.x = 1
        return a.b
    def f():
        a0 = A()
        b0 = B()
        return g(a0, b0).x
    t, adi, graph = build_adi(f, [])
    g_graph = graphof(t, g)
    a0var = graph.startblock.operations[0].result
    b0var = graph.startblock.operations[3].result 
    a0state = adi.getstate(a0var)
    b0state = adi.getstate(b0var)
    assert len(a0state.creation_points) == 1
    a0crep = a0state.creation_points.keys()[0]
    assert not a0crep.escapes
    assert a0crep.changes
    assert len(b0state.creation_points) == 1
    b0crep = b0state.creation_points.keys()[0]
    assert b0crep.escapes
    assert b0crep.changes
Esempio n. 16
0
    def test_dont_remove_with__del__(self):
        import os
        delcalls = [0]
        class A(object):
            nextid = 0
            def __init__(self):
                self.id = self.nextid
                self.nextid += 1

            def __del__(self):
                delcalls[0] += 1
                os.write(1, "__del__\n")

        def f(x=int):
            a = A()
            i = 0
            while i < x:
                a = A()
                os.write(1, str(delcalls[0]) + "\n")
                i += 1
            return 1
        t = TranslationContext()
        t.buildannotator().build_types(f, [int])
        t.buildrtyper().specialize()
        graph = graphof(t, f)
        backend_optimizations(t)
        op = graph.startblock.exits[0].target.exits[1].target.operations[0]
        assert op.opname == "malloc"
Esempio n. 17
0
 def check(self, fn, signature, args, expected_result, must_be_removed=True,
           inline=None):
     remover = self.MallocRemover()
     t = TranslationContext()
     t.buildannotator().build_types(fn, signature)
     t.buildrtyper(type_system=self.type_system).specialize()
     graph = graphof(t, fn)
     if inline is not None:
         from pypy.translator.backendopt.inline import auto_inline_graphs
         auto_inline_graphs(t, t.graphs, inline)
     if option.view:
         t.view()
     # to detect missing keepalives and broken intermediate graphs,
     # we do the loop ourselves instead of calling remove_simple_mallocs()
     while True:
         progress = remover.remove_mallocs_once(graph)
         simplify.transform_dead_op_vars_in_blocks(list(graph.iterblocks()))
         if progress and option.view:
             t.view()
         if expected_result is not Ellipsis:
             interp = LLInterpreter(t.rtyper)
             res = interp.eval_graph(graph, args)
             assert res == expected_result
         if not progress:
             break
     if must_be_removed:
         self.check_malloc_removed(graph)
     return graph
Esempio n. 18
0
def enum_direct_calls(translator, func):
    blocks = []
    graph = graphof(translator, func)
    for block in graph.iterblocks():
        for op in block.operations:
            if op.opname == 'direct_call':
                yield op
Esempio n. 19
0
def hannotate(func, argtypes, policy=P_DEFAULT, annotator=False, inline=None,
              backendoptimize=False):
    # build the normal ll graphs for ll_function
    t = TranslationContext()
    a = t.buildannotator()
    a.build_types(func, argtypes)
    rtyper = t.buildrtyper()
    rtyper.specialize()
    if inline:
        auto_inlining(t, threshold=inline)
    if backendoptimize:
        from pypy.translator.backendopt.all import backend_optimizations
        backend_optimizations(t)
    graph1 = graphof(t, func)

    # build hint annotator types
    hannotator = HintAnnotator(base_translator=t, policy=policy)
    hs = hannotator.build_types(graph1, [SomeLLAbstractConstant(v.concretetype,
                                                                {OriginFlags(): True})
                                         for v in graph1.getargs()])
    hannotator.simplify()
    t = hannotator.translator
    if conftest.option.view:
        t.view()
    if annotator:
        return hs, hannotator
    else:
        return hs
Esempio n. 20
0
def test_specialize_deepfreeze_calls():

    l1 = [1,2,3,4,5]
    l2 = [6,7,8,9,10]
    
    def getlist(n):
        if n:
            return l1
        else:
            return l2

    def ll_get(l, i):
        return l[i]

    def ll_function(n, i):
        l = getlist(n)

        l2 = ll_get(l, 0)

        l = hint(l, deepfreeze=True)
        res = ll_get(l, i)
        return res

    hs, ha = hannotate(ll_function, [int, int], annotator=True, policy=P_NOVIRTUAL)
    assert hs.deepfrozen
    assert hs.concretetype == lltype.Signed
    ll_get_graph = graphof(ha.base_translator, ll_get)
    gdesc = ha.bookkeeper.getdesc(ll_get_graph)    
    assert len(gdesc._cache) == 2
    assert 'xDxx' in gdesc._cache
    v1, v2 = gdesc._cache['xDxx'].getargs()

    assert isinstance(ha.binding(v1), SomeLLAbstractConstant)
    assert isinstance(ha.binding(v2), SomeLLAbstractConstant)
    assert ha.binding(v1).deepfrozen
def test_remove_same_as():
    def nothing(x):
        return x
    def f():
        nothing(False)
        if nothing(True):
            return 42
        else:
            return 666
    t = TranslationContext()
    t.buildannotator().build_types(f, [])
    t.buildrtyper().specialize()
    # now we make the 'if True' appear
    f_graph = graphof(t, f)
    simple_inline_function(t, nothing, f_graph)
    # here, the graph looks like  v21=same_as(True);  exitswitch: v21
    remove_same_as(f_graph)
    t.checkgraphs()
    # only one path should be left
    for block in f_graph.iterblocks():
        assert len(block.exits) <= 1

    interp = LLInterpreter(t.rtyper)
    result = interp.eval_graph(f_graph, [])
    assert result == 42
Esempio n. 22
0
def test_lookup_graphs_abstract():
    from pypy.translator.translator import TranslationContext, graphof
    class A:
        pass
    class B(A):
        def foo(self):
            pass
    class C(A):
        def foo(self):
            pass

    def fn(flag):
        obj = flag and B() or C()
        obj.foo()
        return obj

    t = TranslationContext()
    t.buildannotator().build_types(fn, [int])
    t.buildrtyper(type_system='ootype').specialize()
    graph = graphof(t, fn)
    TYPE_A = graph.getreturnvar().concretetype
    TYPE_B = TYPE_A._subclasses[0]
    TYPE_C = TYPE_A._subclasses[1]
    assert len(TYPE_A._lookup_graphs('ofoo')) == 2
    assert len(TYPE_B._lookup_graphs('ofoo')) == 1
    assert len(TYPE_C._lookup_graphs('ofoo')) == 1
Esempio n. 23
0
    def test_premature_death(self):
        import os
        from pypy.annotation.listdef import s_list_of_strings

        inputtypes = [s_list_of_strings]

        def debug(msg):
            os.write(2, "debug: " + msg + '\n')

        def entry_point(argv):
            #debug("entry point starting")
            for arg in argv:
                #debug(" argv -> " + arg)
                r = arg.replace('_', '-')
                #debug(' replaced -> ' + r)
                a = r.lower()
                #debug(" lowered -> " + a)
            return 0

        t  = self.translateopt(entry_point, inputtypes, mallocs=True)

        entry_point_graph = graphof(t, entry_point)

        argv = t.rtyper.getrepr(inputtypes[0]).convert_const(['./pypy-c'])

        interp = LLInterpreter(t.rtyper)
        interp.eval_graph(entry_point_graph, [argv])
Esempio n. 24
0
    def test_instantiate(self):
        # instantiate is interesting, because it leads to one of the few cases of
        # an indirect call without a list of graphs
        from pypy.rlib.objectmodel import instantiate

        class A:
            pass

        class B(A):
            pass

        def g(x):
            if x:
                C = A
            else:
                C = B
            a = instantiate(C)

        def f(x):
            return g(x)

        t, ra = self.translate(f, [int])
        fgraph = graphof(t, f)
        result = ra.can_raise(fgraph.startblock.operations[0])
        assert result
Esempio n. 25
0
 def check(self, fn, signature, args, expected_result,
           expected_mallocs=0, expected_calls=0):
     t = TranslationContext()
     self.translator = t
     t.buildannotator().build_types(fn, signature)
     t.buildrtyper(type_system=self.type_system).specialize()
     graph = graphof(t, fn)
     if option.view:
         t.view()
     self.original_graph_count = len(t.graphs)
     # to detect broken intermediate graphs,
     # we do the loop ourselves instead of calling remove_simple_mallocs()
     maxiter = 100
     mallocv = MallocVirtualizer(t.graphs, t.rtyper, verbose=True)
     while True:
         progress = mallocv.remove_mallocs_once()
         #simplify.transform_dead_op_vars_in_blocks(list(graph.iterblocks()))
         if progress and option.view:
             t.view()
         t.checkgraphs()
         if expected_result is not DONT_CHECK_RESULT:
             interp = LLInterpreter(t.rtyper)
             if not isinstance(expected_result, CHECK_RAISES):
                 res = interp.eval_graph(graph, args)
                 assert res == expected_result
             else:
                 excinfo = py.test.raises(LLException,
                                          interp.eval_graph, graph, args)
                 assert expected_result.excname in str(excinfo.value)
         if not progress:
             break
         maxiter -= 1
         assert maxiter > 0, "infinite loop?"
     self.check_malloc_removed(graph, expected_mallocs, expected_calls)
     return graph
Esempio n. 26
0
    def test_auto_inlining_small_call_big_call_count(self):
        def leaf(n):
            total = 0
            i = 0
            while i < n:
                total += i
                if total > 100:
                    raise OverflowError
                i += 1
            return total
        def g(n):
            return leaf(n)
        def f(n):
            try:
                return g(n)
            except OverflowError:
                return -1
        eval_func, t = self.check_auto_inlining(f, [int], multiplier=10,
                                           call_count_check=True)
        f_graph = graphof(t, f)
        assert len(collect_called_graphs(f_graph, t)) == 0

        result = eval_func([10])
        assert result == 45
        result = eval_func([15])
        assert result == -1
Esempio n. 27
0
    def test_read_really(self):
        class A(object):
            def __init__(self, y):
                self.y = y
            def f(self):
                self.x = 1
                return self.y
        def h(flag):
            obj = A(flag)
            return obj.f()
        
        t, wa = self.translate(h, [int])
        hgraph = graphof(t, h)
        op_call_f = hgraph.startblock.operations[-1]

        # check that we fished the expected ops
        assert op_call_f.opname == "direct_call"
        assert get_funcobj(op_call_f.args[0].value)._name == 'A.f'

        result = wa.analyze(op_call_f)
        assert len(result) == 2
        result = list(result)
        result.sort()
        [(struct1, T1, name1), (struct2, T2, name2)] = result
        assert struct1 == "readstruct"
        assert name1.endswith("y")
        assert struct2 == "struct"
        assert name2.endswith("x")
        assert T1 == T2
Esempio n. 28
0
    def test_llexternal_with_callback(self):
        from pypy.rpython.lltypesystem.rffi import llexternal
        from pypy.rpython.lltypesystem import lltype

        class Abc:
            pass
        abc = Abc()

        FUNC = lltype.FuncType([lltype.Signed], lltype.Signed)
        z = llexternal('z', [lltype.Ptr(FUNC)], lltype.Signed)
        def g(n):
            abc.foobar = n
            return n + 1
        def f(x):
            return z(g)
        t, wa = self.translate(f, [int])
        fgraph = graphof(t, f)
        backend_optimizations(t)
        assert fgraph.startblock.operations[0].opname == 'direct_call'

        result = wa.analyze(fgraph.startblock.operations[0])
        assert len(result) == 1
        (struct, T, name), = result
        assert struct == "struct"
        assert name.endswith("foobar")
Esempio n. 29
0
    def test_list(self):
        def g(x, y, z):
            return f(x, y, z)
        def f(x, y, z):
            l = [0] * x
            l.append(y)
            return len(l) + z


        t, wa = self.translate(g, [int, int, int])
        ggraph = graphof(t, g)
        assert ggraph.startblock.operations[0].opname == 'direct_call'

        result = sorted(wa.analyze(ggraph.startblock.operations[0]))
        array, A = result[0]
        assert array == "array"
        assert A.TO.OF == lltype.Signed

        struct, S1, name = result[1]
        assert struct == "struct"
        assert S1.TO.items == A
        assert S1.TO.length == lltype.Signed
        assert name == "items"

        struct, S2, name = result[2]
        assert struct == "struct"
        assert name == "length"
        assert S1 is S2
Esempio n. 30
0
def test_indirect_sometimes_residual_pure_but_fixed_red_call():
    def h1(x):
        return x-2
    def h2(x):
        return x*4
    l = [h1, h2]
    def f(n, x):
        frozenl = hint(l, deepfreeze=True)
        h = frozenl[n&1]
        z = h(x)
        hint(z, concrete=True)
        return z

    P = StopAtXPolicy(h1)
    P.oopspec = True
    P.entrypoint_returns_red = False
    hs, hannotator = hannotate(f, [int, int], policy=P, annotator=True)
    assert hs.is_green()

    #tsgraph = graphof(hannotator.translator, h2)
    #hs = hannotator.binding(tsgraph.getargs()[0])
    #assert hs.is_green()

    tsgraph = graphof(hannotator.translator, f)
    hs = hannotator.binding(tsgraph.getargs()[0])
    assert hs.is_green()
    hs = hannotator.binding(tsgraph.getargs()[1])
    assert hs.is_green()
Esempio n. 31
0
 def fix_graph_of_g(translator):
     from pypy.translator.translator import graphof
     from pypy.objspace.flow.model import Constant
     from pypy.rpython.lltypesystem import rffi
     layoutbuilder = cls.ensure_layoutbuilder(translator)
     type_id = layoutbuilder.get_type_id(P)
     #
     # now fix the do_malloc_fixedsize_clear in the graph of g
     graph = graphof(translator, g)
     for op in graph.startblock.operations:
         if op.opname == 'do_malloc_fixedsize_clear':
             op.args = [
                 Constant(type_id, llgroup.HALFWORD),
                 Constant(llmemory.sizeof(P), lltype.Signed),
                 Constant(False, lltype.Bool),  # has_finalizer
                 Constant(False, lltype.Bool),  # is_finalizer_light
                 Constant(False, lltype.Bool)
             ]  # contains_weakptr
             break
     else:
         assert 0, "oups, not found"
Esempio n. 32
0
def test_simple_barrier():
    S = lltype.GcStruct("S", ('x', lltype.Signed))
    T = lltype.GcStruct("T", ('s', lltype.Ptr(S)))

    def f():
        s1 = lltype.malloc(S)
        s1.x = 1
        s2 = lltype.malloc(S)
        s2.x = 2
        t = lltype.malloc(T)
        t.s = s1
        t.s = s2
        return t

    t, transformer = rtype_and_transform(f, [],
                                         RefcountingGCTransformer,
                                         check=False)
    graph = graphof(t, f)
    ops = getops(graph)
    assert len(ops['getfield']) == 2
    assert len(ops['bare_setfield']) == 4
Esempio n. 33
0
    def test__del__(self):
        class A(object):
            def __init__(self):
                self.a = 2

            def __del__(self):
                self.a = 3

        def f():
            a = A()
            return a.a

        t = TranslationContext()
        t.buildannotator().build_types(f, [])
        t.buildrtyper().specialize()
        graph = graphof(t, f)
        TYPE = graph.startblock.operations[0].args[0].value
        RTTI = getRuntimeTypeInfo(TYPE)
        queryptr = RTTI._obj.query_funcptr  # should not raise
        destrptr = RTTI._obj.destructor_funcptr
        assert destrptr is not None
Esempio n. 34
0
def test_arraybarrier():
    S = lltype.GcStruct("S", ('x', lltype.Signed))
    A = lltype.GcArray(lltype.Ptr(S))

    def f():
        s1 = lltype.malloc(S)
        s1.x = 1
        s2 = lltype.malloc(S)
        s2.x = 2
        a = lltype.malloc(A, 1)
        a[0] = s1
        a[0] = s2

    t, transformer = rtype_and_transform(f, [],
                                         RefcountingGCTransformer,
                                         check=False)
    graph = graphof(t, f)
    ops = getops(graph)
    assert len(ops['getarrayitem']) == 2
    assert len(ops['bare_setarrayitem']) == 2
    assert len(ops['bare_setfield']) == 2
Esempio n. 35
0
    def test_indirect_sometimes_residual_pure_red_call(self, setup=setup_for_indirect_call):
        def h1(x):
            return x-2
        def h2(x):
            return x*4
        call, lst = setup(h1, h2)
        def f(n, x):
            frozenl = hint(lst, deepfreeze=True)
            h = frozenl[n&1]
            return call(h, x)

        P = StopAtXPolicy(h1)
        P.oopspec = True
        P.entrypoint_returns_red = False
        hs, hannotator = self.hannotate(f, [int, int], policy=P, annotator=True)
        assert not hs.is_green()
        assert isinstance(hs, SomeLLAbstractConstant)

        tsgraph = graphof(hannotator.translator, h2)
        hs = hannotator.binding(tsgraph.getargs()[0])
        assert not hs.is_green()
Esempio n. 36
0
 def check(self,
           fn,
           signature,
           args,
           expected_result,
           expected_mallocs=0,
           expected_calls=0):
     t = TranslationContext()
     self.translator = t
     t.buildannotator().build_types(fn, signature)
     t.buildrtyper(type_system=self.type_system).specialize()
     graph = graphof(t, fn)
     if option.view:
         t.view()
     self.original_graph_count = len(t.graphs)
     # to detect broken intermediate graphs,
     # we do the loop ourselves instead of calling remove_simple_mallocs()
     maxiter = 100
     mallocv = MallocVirtualizer(t.graphs, t.rtyper, verbose=True)
     while True:
         progress = mallocv.remove_mallocs_once()
         #simplify.transform_dead_op_vars_in_blocks(list(graph.iterblocks()))
         if progress and option.view:
             t.view()
         t.checkgraphs()
         if expected_result is not DONT_CHECK_RESULT:
             interp = LLInterpreter(t.rtyper)
             if not isinstance(expected_result, CHECK_RAISES):
                 res = interp.eval_graph(graph, args)
                 assert res == expected_result
             else:
                 excinfo = py.test.raises(LLException, interp.eval_graph,
                                          graph, args)
                 assert expected_result.excname in str(excinfo.value)
         if not progress:
             break
         maxiter -= 1
         assert maxiter > 0, "infinite loop?"
     self.check_malloc_removed(graph, expected_mallocs, expected_calls)
     return graph
Esempio n. 37
0
    def test_method(self):
        class A(object):
            def f(self):
                return 1
            def m(self):
                raise ValueError
        class B(A):
            def f(self):
                return 2
            def m(self):
                return 3
        def f(a):
            return a.f()
        def m(a):
            return a.m()
        def h(flag):
            if flag:
                obj = A()
            else:
                obj = B()
            f(obj)
            m(obj)
        
        t, ra = self.translate(h, [int])
        hgraph = graphof(t, h)
        # fiiiish :-(
        block = hgraph.startblock.exits[0].target.exits[0].target
        op_call_f = block.operations[0]
        op_call_m = block.operations[1]

        # check that we fished the expected ops
        def check_call(op, fname):
            assert op.opname == "direct_call"
            assert get_funcobj(op.args[0].value)._name == fname
        check_call(op_call_f, "f")
        check_call(op_call_m, "m")

        assert not ra.can_raise(op_call_f)
        assert ra.can_raise(op_call_m)
Esempio n. 38
0
    def test_method_recursive(self):
        class A:
            def m(self, x):
                if x > 0:
                    return self.m(x - 1)
                else:
                    return 42

        def m(a):
            return a.m(2)

        def h():
            obj = A()
            m(obj)

        t, ra = self.translate(h, [])
        hgraph = graphof(t, h)
        # fiiiish :-(
        block = hgraph.startblock
        op_call_m = block.operations[-1]
        assert op_call_m.opname == "direct_call"
        assert not ra.can_raise(op_call_m)
Esempio n. 39
0
def test_untagged_subclasses():
    def g(x):
        return x.attrvalue  # should not produce a call to ll_unboxed_getclass

    def fn(n):
        y = C(12)
        if n > 0:
            x = B(5)
        else:
            x = D(5)
        return g(x)

    interp, graph = get_interpreter(fn, [-1000])

    t = interp.typer.annotator.translator
    ggraph = graphof(t, g)
    assert summary(ggraph) == {'cast_pointer': 2, 'getfield': 2}

    res = interp.eval_graph(graph, [-1000])
    assert res == 68
    res = interp.eval_graph(graph, [3])
    assert res == 66
Esempio n. 40
0
def make_deallocator(TYPE,
                     attr="static_deallocation_funcptr_for_type",
                     cls=RefcountingGCTransformer):
    if TYPE._is_varsize():
        def f():
            return lltype.malloc(TYPE, 1)
    else:
        def f():
            return lltype.malloc(TYPE)
    t = TranslationContext()
    t.buildannotator().build_types(f, [])
    t.buildrtyper().specialize()
    transformer = cls(t)
    fptr = getattr(transformer, attr)(TYPE)
    transformer.transform_graph(graphof(t, f))
    transformer.finish(backendopt=False)
    if conftest.option.view:
        t.view()
    if fptr:
        return fptr._obj.graph, t
    else:
        return None, t
Esempio n. 41
0
def llinterp_stackless_function(fn,
                                returntranslator=False,
                                assert_unwind=True):
    def wrapper(argv):
        return fn()

    t = rtype_stackless_function(wrapper)
    st = StacklessTransformer(t, wrapper, assert_unwind=assert_unwind)
    st.transform_all()
    if conftest.option.view:
        t.view()

    graph = graphof(t, st.slp_entry_point)
    r_list_of_strings = t.rtyper.getrepr(
        t.annotator.binding(graph.startblock.inputargs[0]))
    ll_list = r_list_of_strings.convert_const([''])
    interp = llinterp.LLInterpreter(t.rtyper)
    res = interp.eval_graph(graph, [ll_list])
    if returntranslator:
        return res, t
    else:
        return res
Esempio n. 42
0
def test_find_loop_blocks3():
    import os
    def ps(loops):
        return 42.0, 42.1
    def f(loops):
        benchtime, stones = ps(abs(loops))
        s = '' # annotator happiness
        if loops >= 0:
            s = ("RPystone(%s) time for %d passes = %f" %
                 (23, loops, benchtime) + '\n' + (
                 "This machine benchmarks at %f pystones/second" % stones))
        os.write(1, s)
        if loops == 12345:
            f(loops-1)
    t = TranslationContext()
    t.buildannotator().build_types(f, [int])
    t.buildrtyper().specialize()
    graph = graphof(t, f)
    backedges = find_backedges(graph)
    assert backedges == []
    loop_blocks = find_loop_blocks(graph)
    assert len(loop_blocks) == 0
Esempio n. 43
0
def test_call():
    class A(object):
        pass

    def g(b):
        return b.i + 2

    def f():
        a = A()
        a.i = 2
        return g(a)

    t, adi, graph = build_adi(f, [])
    g_graph = graphof(t, g)
    bvar = g_graph.startblock.inputargs[0]
    bstate = adi.getstate(bvar)
    bcrep, = bstate.creation_points
    assert not bcrep.escapes
    avar = graph.startblock.operations[0].result
    astate = adi.getstate(avar)
    acrep, = astate.creation_points
    assert not acrep.escapes
Esempio n. 44
0
    def test_specialize_calls(self):
        def ll_add(x, y):
            return x+y
        def ll_function(x,y):
            z0 = ll_add(y, 2)
            z1 = ll_add(x, y)
            x1 = hint(x, concrete=True)
            z2 = ll_add(x1, y)
            return z2
        hs, ha  = self.hannotate(ll_function, [int, int], annotator=True)
        assert hs.eager_concrete
        assert hs.concretetype == lltype.Signed
        ll_add_graph = graphof(ha.base_translator, ll_add)
        gdesc = ha.bookkeeper.getdesc(ll_add_graph)    
        assert len(gdesc._cache) == 2
        assert 'Exxx' in gdesc._cache
        v1, v2 = gdesc._cache['Exxx'].getargs()

        assert isinstance(ha.binding(v1), SomeLLAbstractConstant)
        assert isinstance(ha.binding(v2), SomeLLAbstractConstant)
        assert ha.binding(v1).eager_concrete
        assert not ha.binding(v2).is_fixed()
Esempio n. 45
0
    def test_adt_method(self):
        def ll_callme(n):
            return n
        ll_callme = lltype.staticAdtMethod(ll_callme)
        S = lltype.GcStruct('S', ('x', lltype.Signed),
                            adtmeths = {'yep': True,
                                        'callme': ll_callme})
        def g(p, x, y, z):
            p.x = x
            if p.yep:
                z *= p.callme(y)
            return z
        def f(x, y, z):
            p = lltype.malloc(S)
            return g(p, x, y, z)

        t, wa = self.translate(f, [int, int, int])
        fgraph = graphof(t, f)
        assert fgraph.startblock.operations[-1].opname == 'direct_call'

        result = wa.analyze(fgraph.startblock.operations[-1])
        assert list(result) == [("struct", lltype.Ptr(S), "x")]
Esempio n. 46
0
    def test_implicit_cast(self):
        z = llexternal('z', [USHORT, ULONG, USHORT, DOUBLE],
                       USHORT,
                       sandboxsafe=True)  # to allow the wrapper to be inlined

        def f(x, y, xx, yy):
            return z(x, y, xx, yy)

        a = RPythonAnnotator()
        r = a.build_types(f, [int, int, int, int])
        rtyper = RPythonTyper(a)
        rtyper.specialize()
        a.translator.rtyper = rtyper
        backend_optimizations(a.translator)
        if option.view:
            a.translator.view()
        graph = graphof(a.translator, f)
        s = summary(graph)
        # there should be not too many operations here by now
        expected = {'force_cast': 3, 'cast_int_to_float': 1, 'direct_call': 1}
        for k, v in expected.items():
            assert s[k] == v
Esempio n. 47
0
def get_graph(arg, translator):
    from pypy.translator.translator import graphof
    if isinstance(arg, Variable):
        return None
    f = arg.value
    from pypy.rpython.lltypesystem import lltype
    from pypy.rpython.ootypesystem import ootype
    if not isinstance(f, lltype._ptr) and not isinstance(f, ootype._callable):
        return None
    funcobj = get_funcobj(f)
    try:
        callable = funcobj._callable
    except (AttributeError, KeyError, AssertionError):
        return None
    try:
        return funcobj.graph
    except AttributeError:
        return None
    try:
        callable = funcobj._callable
        return graphof(translator, callable)
    except (AttributeError, KeyError, AssertionError):
        return None
Esempio n. 48
0
    def task_hintannotate_lltype(self):
        from pypy.jit.hintannotator.annotator import HintAnnotator
        from pypy.jit.hintannotator.model import OriginFlags
        from pypy.jit.hintannotator.model import SomeLLAbstractConstant

        get_portal = self.extra['portal']
        PORTAL, POLICY = get_portal(self)
        t = self.translator
        self.portal_graph = graphof(t, PORTAL)

        hannotator = HintAnnotator(base_translator=t, policy=POLICY)
        self.hint_translator = hannotator.translator
        hs = hannotator.build_types(self.portal_graph, [
            SomeLLAbstractConstant(v.concretetype, {OriginFlags(): True})
            for v in self.portal_graph.getargs()
        ])
        count = hannotator.bookkeeper.nonstuboriggraphcount
        stubcount = hannotator.bookkeeper.stuboriggraphcount
        self.log.info("The hint-annotator saw %d graphs"
                      " (and made stubs for %d graphs)." % (count, stubcount))
        n = len(list(hannotator.translator.graphs[0].iterblocks()))
        self.log.info("portal has %d blocks" % n)
        self.hannotator = hannotator
Esempio n. 49
0
 def test_instantiate(self):
     # instantiate is interesting, because it leads to one of the few cases of
     # an indirect call without a list of graphs
     from pypy.rlib.objectmodel import instantiate
     class A:
         pass 
     class B(A):
         pass
     def g(x):
         if x:
             C = A
         else:
             C = B
         a = instantiate(C)
     def f(x):
         return g(x)
     t, wa = self.translate(f, [int])
     fgraph = graphof(t, f)
     result = wa.analyze(fgraph.startblock.operations[0])
     if self.type_system == 'lltype':
         assert result is top_set
     else:
         assert not result # ootype is more precise in this case
Esempio n. 50
0
def test_dynamic_deallocator():
    class A(object):
        pass
    class B(A):
        pass
    def f(x):
        a = A()
        a.x = 1
        b = B()
        b.x = 2
        b.y = 3
        if x:
            c = a
        else:
            c = b
        return c.x
    t, transformer = rtype_and_transform(
        f, [int], RefcountingGCTransformer, check=False)
    fgraph = graphof(t, f)
    s_instance = t.annotator.bookkeeper.valueoftype(A)
    TYPE = t.rtyper.getrepr(s_instance).lowleveltype.TO
    p = transformer.dynamic_deallocation_funcptr_for_type(TYPE)
    t.rtyper.specialize_more_blocks()
Esempio n. 51
0
def test_dont_transform_too_much():
    def check(x):
        if x:
            rstack.stack_unwind()

    def f(x):
        return x + 2

    def g(x):
        check(x)
        return f(x) + x + 1

    def example():
        return g(one()) + 1

    res, t = llinterp_stackless_function(example, returntranslator=True)
    assert res == 6

    ggraph = graphof(t, g)
    for block, op in ggraph.iterblockops():
        if op.opname == 'direct_call':
            if op.args[0].value._obj._callable is f:
                assert op != block.operations[-1]
Esempio n. 52
0
def test_getfield_pyobj():
    class S:
        pass

    def f(thing):
        s = S()
        s.x = thing
        return s.x

    t, transformer = rtype_and_transform(f, [object], _TestGCTransformer)
    fgraph = graphof(t, f)
    pyobj_getfields = 0
    pyobj_setfields = 0
    for b in fgraph.iterblocks():
        for op in b.operations:
            if op.opname == 'getfield' and var_ispyobj(op.result):
                pyobj_getfields += 1
            elif op.opname == 'bare_setfield' and var_ispyobj(op.args[2]):
                pyobj_setfields += 1
    # although there's only one explicit getfield in the code, a
    # setfield on a pyobj must get the old value out and decref it
    assert pyobj_getfields >= 2
    assert pyobj_setfields >= 1
Esempio n. 53
0
 def graphof(self, func):
     rtyper = self.metainterp_sd.cpu.rtyper
     return graphof(rtyper.annotator.translator, func)
Esempio n. 54
0
def translate(func, argtypes):
    t = TranslationContext()
    t.buildannotator().build_types(func, argtypes)
    t.buildrtyper().specialize()
    return graphof(t, func), t
Esempio n. 55
0
def translate(func, argtypes, type_system="lltype"):
    t = TranslationContext()
    t.buildannotator().build_types(func, argtypes)
    t.entry_point_graph = graphof(t, func)
    t.buildrtyper(type_system=type_system).specialize()
    return graphof(t, func), t
Esempio n. 56
0
 def eval_func(args):
     return interp.eval_graph(graphof(t, entry), args)