コード例 #1
0
def test_SSA_to_SSI():
    c = Variable('c')
    x = Variable('x')
    y = Variable('y')
    b1 = Block([c])
    b2 = Block([x])
    b3 = Block([])

    graph = FunctionGraph('x', b1)
    b2.operations.append(SpaceOperation('add', [x, c], y))
    b2.exitswitch = y

    b1.closeblock(Link([Constant(0)], b2))
    b2.closeblock(Link([y], b2), Link([], b3))
    b3.closeblock(Link([y, c], graph.exceptblock))
    SSA_to_SSI(graph)

    assert len(b1.inputargs) == 1
    assert len(b2.inputargs) == 2
    assert len(b3.inputargs) == 2

    assert b2.inputargs == b2.operations[0].args
    assert len(b1.exits[0].args) == 2
    assert b1.exits[0].args[1] is c
    assert len(b2.exits[0].args) == 2
    assert b2.exits[0].args == [y, b2.inputargs[1]]
    assert len(b2.exits[1].args) == 2
    assert len(b3.exits[0].args) == 2

    index = b3.inputargs.index(b3.exits[0].args[0])
    assert b2.exits[1].args[index] is b2.operations[0].result

    index = b3.inputargs.index(b3.exits[0].args[1])
    assert b2.exits[1].args[index] is b2.inputargs[1]
コード例 #2
0
ファイル: test_regalloc.py プロジェクト: sota/pypy-old
 def test_regalloc_exitswitch_2(self):
     v1 = Variable(); v1.concretetype = rclass.CLASSTYPE
     v2 = Variable(); v2.concretetype = rclass.CLASSTYPE
     v3 = Variable(); v3.concretetype = rclass.CLASSTYPE
     v4 = Variable(); v4.concretetype = rclass.CLASSTYPE
     block = Block([])
     block.operations = [
         SpaceOperation('res_call', [], v1),
         SpaceOperation('-live-', [], None),
         ]
     graph = FunctionGraph('f', block, v4)
     exclink = Link([v2], graph.returnblock)
     exclink.llexitcase = 123     # normally an exception class
     exclink.last_exception = v2
     exclink.last_exc_value = "unused"
     block.exitswitch = c_last_exception
     block.closeblock(Link([v1], graph.returnblock),
                      exclink)
     #
     self.check_assembler(graph, """
         res_call -> %i0
         -live-
         catch_exception L1
         int_return %i0
         ---
         L1:
         goto_if_exception_mismatch $123, L2
         last_exception -> %i0
         int_return %i0
         ---
         L2:
         reraise
     """)
コード例 #3
0
 def test_regalloc_lists(self):
     v1 = Variable()
     v1.concretetype = lltype.Signed
     v2 = Variable()
     v2.concretetype = lltype.Signed
     v3 = Variable()
     v3.concretetype = lltype.Signed
     v4 = Variable()
     v4.concretetype = lltype.Signed
     v5 = Variable()
     v5.concretetype = lltype.Signed
     block = Block([v1])
     block.operations = [
         SpaceOperation('int_add', [v1, Constant(1, lltype.Signed)], v2),
         SpaceOperation('rescall', [ListOfKind('int', [v1, v2])], v5),
         SpaceOperation('rescall', [ListOfKind('int', [v1, v2])], v3),
     ]
     graph = FunctionGraph('f', block, v4)
     block.closeblock(Link([v3], graph.returnblock))
     #
     self.check_assembler(
         graph, """
         int_add %i0, $1 -> %i1
         rescall I[%i0, %i1] -> %i2
         rescall I[%i0, %i1] -> %i0
         int_return %i0
     """)
コード例 #4
0
def test_decode_builtin_call_method():
    A = lltype.GcArray(lltype.Signed)

    def myfoobar(a, i, marker, c):
        assert marker == 'mymarker'
        return a[i] * ord(c)

    myfoobar.oopspec = 'spam.foobar(a, 2, c, i)'
    TYPE = lltype.FuncType(
        [lltype.Ptr(A), lltype.Signed, lltype.Void, lltype.Char],
        lltype.Signed)
    fnobj = lltype.functionptr(TYPE, 'foobar', _callable=myfoobar)
    vi = Variable('i')
    vi.concretetype = lltype.Signed
    vc = Variable('c')
    vc.concretetype = lltype.Char
    v_result = Variable('result')
    v_result.concretetype = lltype.Signed
    myarray = lltype.malloc(A, 10)
    myarray[5] = 42
    op = SpaceOperation(
        'direct_call',
        [newconst(fnobj),
         newconst(myarray), vi,
         voidconst('mymarker'), vc], v_result)
    oopspec, opargs = decode_builtin_call(op)
    assert oopspec == 'spam.foobar'
    assert opargs == [newconst(myarray), newconst(2), vc, vi]
コード例 #5
0
def test_func_simple():
    # -------------------- flowgraph building --------------------
    #     def f(x):
    #         return x+1
    x = Variable("x")
    x.concretetype = Signed
    result = Variable("result")
    result.concretetype = Signed
    one = Constant(1)
    one.concretetype = Signed
    op = SpaceOperation("int_add", [x, one], result)
    block = Block([x])
    graph = FunctionGraph("f", block)
    block.operations.append(op)
    block.closeblock(Link([result], graph.returnblock))
    graph.getreturnvar().concretetype = Signed
    # --------------------         end        --------------------

    F = FuncType([Signed], Signed)
    f = functionptr(F, "f", graph=graph)
    db = LowLevelDatabase()
    db.get(f)
    db.complete()
    dump_on_stdout(db)

    S = GcStruct('testing', ('fptr', Ptr(F)))
    s = malloc(S)
    s.fptr = f
    db = LowLevelDatabase()
    db.get(s)
    db.complete()
    dump_on_stdout(db)
コード例 #6
0
 def builder(translator, func):
     # build a hacked graph that doesn't take a *arg any more, but
     # individual extra arguments
     graph = translator.buildflowgraph(func)
     argnames, vararg, kwarg = graph.signature
     assert vararg, "graph should have a *arg at this point"
     assert not kwarg, "where does this **arg come from??"
     argscopy = [Variable(v) for v in graph.getargs()]
     starargs = [
         Variable('stararg%d' % i) for i in range(nb_extra_args)
     ]
     newstartblock = Block(argscopy[:-1] + starargs)
     newtup = op.newtuple(*starargs)
     newtup.result = argscopy[-1]
     newstartblock.operations.append(newtup)
     newstartblock.closeblock(Link(argscopy, graph.startblock))
     graph.startblock = newstartblock
     argnames = argnames + ['.star%d' % i for i in range(nb_extra_args)]
     graph.signature = Signature(argnames)
     # note that we can mostly ignore defaults: if nb_extra_args > 0,
     # then defaults aren't applied.  if nb_extra_args == 0, then this
     # just removes the *arg and the defaults keep their meaning.
     if nb_extra_args > 0:
         graph.defaults = None  # shouldn't be used in this case
     checkgraph(graph)
     return graph
コード例 #7
0
ファイル: test_model.py プロジェクト: sczfaker/pypy
def test_generalize_string_concat(annotator):
    hlop = op.add(Variable(), Variable())
    s_str = SomeString(can_be_None=True)
    s_value, s_exc = annotate_op(annotator, hlop, [s_None, s_str])
    s_value2, s_exc2 = annotate_op(annotator, hlop, [s_str, s_str])
    assert contains_s(s_value2, s_value)
    assert contains_s(s_exc2, s_exc)
コード例 #8
0
ファイル: test_model.py プロジェクト: sczfaker/pypy
def test_generalize_getitem_string(annotator):
    hlop = op.getitem(Variable(), Variable())
    s_int = SomeInteger()
    s_str = SomeString(can_be_None=True)
    s_value, s_exc = annotate_op(annotator, hlop, [s_None, s_int])
    s_value2, s_exc2 = annotate_op(annotator, hlop, [s_str, s_int])
    assert contains_s(s_value2, s_value)
    assert contains_s(s_exc2, s_exc)
コード例 #9
0
ファイル: test_model.py プロジェクト: sczfaker/pypy
def test_getitem_dict(annotator):
    bk = annotator.bookkeeper
    hlop = op.getitem(Variable(), Variable())
    with bk.at_position(None):
        s_dict = bk.newdict()
    s_dict.dictdef.generalize_key(SomeString())
    s_dict.dictdef.generalize_value(SomeInteger())
    s_result, _ = annotate_op(annotator, hlop, [s_dict, SomeString()])
    assert s_result == SomeInteger()
コード例 #10
0
ファイル: test_model.py プロジェクト: sczfaker/pypy
def test_generalize_getitem_list(annotator):
    bk = annotator.bookkeeper
    hlop = op.getitem(Variable(), Variable())
    s_int = SomeInteger()
    with bk.at_position(None):
        s_empty_list = bk.newlist()
    s_value, s_exc = annotate_op(annotator, hlop, [s_None, s_int])
    s_value2, s_exc2 = annotate_op(annotator, hlop, [s_empty_list, s_int])
    assert contains_s(s_value2, s_value)
    assert contains_s(s_exc2, s_exc)
コード例 #11
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
コード例 #12
0
ファイル: simplify.py プロジェクト: Mu-L/pypy
def simplify_exceptions(graph):
    """The exception handling caused by non-implicit exceptions
    starts with an exitswitch on Exception, followed by a lengthy
    chain of is_/issubtype tests. We collapse them all into
    the block's single list of exits.
    """
    renaming = {}
    for block in graph.iterblocks():
        if not (block.canraise and block.exits[-1].exitcase is Exception):
            continue
        covered = [link.exitcase for link in block.exits[1:-1]]
        seen = []
        preserve = list(block.exits[:-1])
        exc = block.exits[-1]
        last_exception = exc.last_exception
        last_exc_value = exc.last_exc_value
        query = exc.target
        switches = []
        # collect the targets
        while len(query.exits) == 2:
            newrenaming = {}
            for lprev, ltarg in zip(exc.args, query.inputargs):
                newrenaming[ltarg] = lprev.replace(renaming)
            op = query.operations[0]
            if not (op.opname in ("is_", "issubtype")
                    and op.args[0].replace(newrenaming) == last_exception):
                break
            renaming.update(newrenaming)
            case = query.operations[0].args[-1].value
            assert issubclass(case, py.builtin.BaseException)
            lno, lyes = query.exits
            assert lno.exitcase == False and lyes.exitcase == True
            if case not in seen:
                is_covered = False
                for cov in covered:
                    if issubclass(case, cov):
                        is_covered = True
                        break
                if not is_covered:
                    switches.append((case, lyes))
                seen.append(case)
            exc = lno
            query = exc.target
        if Exception not in seen:
            switches.append((Exception, exc))
        # construct the block's new exits
        exits = []
        for case, oldlink in switches:
            link = oldlink.replace(renaming)
            assert case is not None
            link.last_exception = last_exception
            link.last_exc_value = last_exc_value
            # make the above two variables unique
            renaming2 = {}
            for v in link.getextravars():
                renaming2[v] = Variable(v)
            link = link.replace(renaming2)
            link.exitcase = case
            exits.append(link)
        block.recloseblock(*(preserve + exits))
コード例 #13
0
    def rewrite_can_enter_jit(self, jd, can_enter_jits):
        FUNCPTR = jd._PTR_JIT_ENTER_FUNCTYPE
        jit_enter_fnptr = self.helper_func(FUNCPTR, jd._maybe_enter_jit_fn)

        if len(can_enter_jits) == 0:
            # see test_warmspot.test_no_loop_at_all
            operations = jd.portal_graph.startblock.operations
            op1 = operations[0]
            assert (op1.opname == 'jit_marker'
                    and op1.args[0].value == 'jit_merge_point')
            op0 = SpaceOperation('jit_marker',
                                 [Constant('can_enter_jit', lltype.Void)] +
                                 op1.args[1:], None)
            operations.insert(0, op0)
            can_enter_jits = [(jd.portal_graph, jd.portal_graph.startblock, 0)]

        for graph, block, index in can_enter_jits:
            if graph is jd._jit_merge_point_in:
                continue

            op = block.operations[index]
            greens_v, reds_v = support.decode_hp_hint_args(op)
            args_v = greens_v + reds_v

            vlist = [Constant(jit_enter_fnptr, FUNCPTR)] + args_v

            v_result = Variable()
            v_result.concretetype = lltype.Void
            newop = SpaceOperation('direct_call', vlist, v_result)
            block.operations[index] = newop
コード例 #14
0
ファイル: inline.py プロジェクト: Mu-L/pypy
def instrument_inline_candidates(graphs, threshold):
    cache = {None: False}
    def candidate(graph):
        try:
            return cache[graph]
        except KeyError:
            res = static_instruction_count(graph) <= threshold
            cache[graph] = res
            return res
    n = 0
    for parentgraph in graphs:
        for block in parentgraph.iterblocks():
            ops = block.operations
            i = len(ops) - 1
            while i >= 0:
                op = ops[i]
                i -= 1
                if op.opname == "direct_call":
                    funcobj = op.args[0].value._obj
                    graph = getattr(funcobj, 'graph', None)
                    if graph is not None:
                        if getattr(getattr(funcobj, '_callable', None),
                                   '_dont_inline_', False):
                            continue
                    if candidate(graph):
                        tag = Constant('inline', Void)
                        label = Constant(n, Signed)
                        dummy = Variable()
                        dummy.concretetype = Void
                        count = SpaceOperation('instrument_count',
                                               [tag, label], dummy)
                        ops.insert(i + 1, count)
                        n += 1
    log.inlining("%d call sites instrumented" % n)
コード例 #15
0
ファイル: partial_escape.py プロジェクト: papanikge/thesis
def materialize_object(obj_key, state, ops):
    """ Accepts a VirtualState object and creates the required operations, for
    its materialization/initialization. XXX: Edits ops in-place
    """

    if obj_key not in state:
        return False

    # We're gonna delete the object from the state dict first (since it has
    # escaped) for correct recursion reasons in case of cyclic dependency.
    # this needs to be done with all the aliases of the object!
    vo = state[obj_key] # Thus, we'll make a copy first.
    assert obj_key in vo.aliases
    for key in vo.aliases:
        del state[key]

    # Starting assembling the operations. Creation and required castings:
    newvar = Variable()
    newvar.concretetype = vo.concretetype
    ops.append(SpaceOperation('malloc', vo.malloc_args, newvar))

    # recreate the aliases
    for var in vo.aliases:
        if var.concretetype != vo.concretetype:
            ops.append(SpaceOperation('cast_pointer', [newvar], var))
        else:
            ops.append(SpaceOperation('same_as', [newvar], var))

    # Initialization
    for (key, concretetype), value in vo.vars.items():
        if concretetype != vo.concretetype:
            # we need a cast_pointer
            v = Variable()
            v.concretetype = concretetype
            op = SpaceOperation('cast_pointer', [newvar], v)
            ops.append(op)
            target = v
        else:
            target = newvar
        # What if the assigned is a virtual object? Recursion:
        materialize_object(value, state, ops)
        m = Variable()
        m.concretetype = lltype.Void
        ops.append(SpaceOperation('setfield', [target,
                                               Constant(key, lltype.Void),
                                               value], m))
    return True
コード例 #16
0
 def copy(self):
     "Make a copy of this state in which all Variables are fresh."
     newstate = []
     for w in self.mergeable:
         if isinstance(w, Variable):
             w = Variable(w)
         newstate.append(w)
     return FrameState(newstate, self.blocklist, self.next_offset)
コード例 #17
0
ファイル: generator.py プロジェクト: sota/pypy-old
def _insert_reads(block, varnames):
    assert len(varnames) == len(block.inputargs)
    v_entry1 = Variable('entry')
    for i, name in enumerate(varnames):
        hlop = op.getattr(v_entry1, const(name))
        hlop.result = block.inputargs[i]
        block.operations.insert(i, hlop)
    block.inputargs = [v_entry1]
コード例 #18
0
def test_SSA_to_SSI_2():
    x = Variable('x')
    y = Variable('y')
    z = Variable('z')
    b1 = Block([x])
    b2 = Block([y])
    b3 = Block([])

    b3.operations.append(SpaceOperation('hello', [y], z))
    b1.closeblock(Link([x], b2), Link([], b3))
    graph = FunctionGraph('x', b1)
    SSA_to_SSI(graph)

    assert b1.inputargs == [x]
    assert b2.inputargs == [y]
    assert b3.inputargs == [b3.operations[0].args[0]]
    assert b1.exits[0].args == [x]
    assert b1.exits[1].args == [x]
コード例 #19
0
def _copy(v):
    from rpython.flowspace.flowcontext import FlowSignal
    if isinstance(v, Variable):
        return Variable(v)
    elif isinstance(v, FlowSignal):
        vars = [_copy(var) for var in v.args]
        return v.rebuild(*vars)
    else:
        return v
コード例 #20
0
 def __init__(self, func, code):
     from rpython.flowspace.flowcontext import SpamBlock
     locals = [None] * code.co_nlocals
     for i in range(code.formalargcount):
         locals[i] = Variable(code.co_varnames[i])
     state = FrameState(locals, [], None, [], 0)
     initialblock = SpamBlock(state)
     super(PyGraph, self).__init__(self._sanitize_funcname(func), initialblock)
     self.func = func
     self.signature = code.signature
     self.defaults = func.__defaults__ or ()
コード例 #21
0
ファイル: transform.py プロジェクト: hmrg-grmh/pypy
    def transform_graph(self, graph):
        if graph in self.minimal_transform:
            if self.minimalgctransformer:
                self.minimalgctransformer.transform_graph(graph)
            self.minimal_transform.remove(graph)
            return
        if graph in self.seen_graphs:
            return
        self.seen_graphs.add(graph)

        self.links_to_split = {} # link -> vars to pop_alive across the link

        # for sanity, we need an empty block at the start of the graph
        inserted_empty_startblock = False
        if not starts_with_empty_block(graph):
            insert_empty_startblock(graph)
            inserted_empty_startblock = True
        is_borrowed = self.compute_borrowed_vars(graph)

        try:
            for block in graph.iterblocks():
                self.transform_block(block, is_borrowed)
        except GCTransformError as e:
            e.args = ('[function %s]: %s' % (graph.name, e.message),)
            raise

        for link, livecounts in self.links_to_split.iteritems():
            llops = LowLevelOpList()
            for var, livecount in livecounts.iteritems():
                for i in range(livecount):
                    self.pop_alive(var, llops)
                for i in range(-livecount):
                    self.push_alive(var, llops)
            if llops:
                if link.prevblock.exitswitch is None:
                    link.prevblock.operations.extend(llops)
                else:
                    insert_empty_block(link, llops)

        # remove the empty block at the start of the graph, which should
        # still be empty (but let's check)
        if starts_with_empty_block(graph) and inserted_empty_startblock:
            old_startblock = graph.startblock
            graph.startblock = graph.startblock.exits[0].target

        checkgraph(graph)

        self.links_to_split = None
        v = Variable('vanishing_exc_value')
        v.concretetype = self.get_lltype_of_exception_value()
        llops = LowLevelOpList()
        self.pop_alive(v, llops)
        graph.exc_cleanup = (v, list(llops))
        return is_borrowed    # xxx for tests only
コード例 #22
0
ファイル: flowcontext.py プロジェクト: zielmicha/pypy
 def guessexception(self, ctx, *cases):
     block = self.crnt_block
     links = []
     for case in [None] + list(cases):
         if case is not None:
             if case is Exception:
                 last_exc = Variable('last_exception')
             else:
                 last_exc = Constant(case)
             last_exc_value = Variable('last_exc_value')
             vars = [last_exc, last_exc_value]
             vars2 = [Variable(), Variable()]
         else:
             vars = []
             vars2 = []
         egg = EggBlock(vars2, block, case)
         ctx.pendingblocks.append(egg)
         link = Link(vars, egg, case)
         if case is not None:
             link.extravars(last_exception=last_exc, last_exc_value=last_exc_value)
             egg.extravars(last_exception=last_exc)
コード例 #23
0
def test_decode_builtin_call_nomethod():
    def myfoobar(i, marker, c):
        assert marker == 'mymarker'
        return i * ord(c)

    myfoobar.oopspec = 'foobar(2, c, i)'
    TYPE = lltype.FuncType([lltype.Signed, lltype.Void, lltype.Char],
                           lltype.Signed)
    fnobj = lltype.functionptr(TYPE, 'foobar', _callable=myfoobar)
    vi = Variable('i')
    vi.concretetype = lltype.Signed
    vc = Variable('c')
    vc.concretetype = lltype.Char
    v_result = Variable('result')
    v_result.concretetype = lltype.Signed
    op = SpaceOperation(
        'direct_call',
        [newconst(fnobj), vi, voidconst('mymarker'), vc], v_result)
    oopspec, opargs = decode_builtin_call(op)
    assert oopspec == 'foobar'
    assert opargs == [newconst(2), vc, vi]
コード例 #24
0
ファイル: storesink.py プロジェクト: sbw111/lab4
 def _translate_arg(arg):
     if isinstance(arg, Variable):
         res = local_versions.get(arg, None)
         if res is None:
             res = Variable(arg)
             res.concretetype = arg.concretetype
             link.args.append(arg)
             block.inputargs.append(res)
             local_versions[arg] = res
         return res
     else:
         return arg
コード例 #25
0
ファイル: malloc.py プロジェクト: sbw111/lab4
    def flowin(self, block, count, vars, newvarsmap):
        # in this 'block', follow where the 'var' goes to and replace
        # it by a flattened-out family of variables.  This family is given
        # by newvarsmap, whose keys are the 'flatnames'.

        def list_newvars():
            return [newvarsmap[key] for key in self.flatnames]

        assert block.operations != ()
        self.newops = []
        for op in block.operations:
            for arg in op.args[1:]:   # should be the first arg only
                assert arg not in vars
            if op.args and op.args[0] in vars:
                self.flowin_op(op, vars, newvarsmap)
            elif op.result in vars:
                assert op.opname == self.MALLOC_OP
                progress = True
                # drop the "malloc" operation
                newvarsmap = self.flatconstants.copy()   # zero initial values
                # if there are substructures, they are now individually
                # malloc'ed in an exploded way.  (They will typically be
                # removed again by the next malloc removal pass.)
                for key in self.needsubmallocs:
                    v = Variable()
                    v.concretetype = self.newvarstype[key]
                    c = Constant(v.concretetype.TO, lltype.Void)
                    if c.value == op.args[0].value:
                        progress = False   # replacing a malloc with
                                           # the same malloc!
                    newop = self.recreate_malloc(c, v)
                    self.newops.append(newop)
                    newvarsmap[key] = v
                count[0] += progress
            else:
                self.newops.append(op)

        assert block.exitswitch not in vars

        for link in block.exits:
            appended = False
            newargs = []
            for arg in link.args:
                if arg in vars:
                    if not appended:
                        newargs += list_newvars()
                        appended = True
                else:
                    newargs.append(arg)
            link.args[:] = newargs

        block.operations[:] = self.newops
コード例 #26
0
    def create_proxy_graph(self, op):
        """ creates a graph which calls the original function, checks for
        raised exceptions, fetches and then raises them again. If this graph is
        inlined, the correct exception matching blocks are produced."""
        # XXX slightly annoying: construct a graph by hand
        # but better than the alternative
        result = op.result.copy()
        opargs = []
        inputargs = []
        callargs = []
        ARGTYPES = []
        for var in op.args:
            if isinstance(var, Variable):
                v = Variable()
                v.concretetype = var.concretetype
                inputargs.append(v)
                opargs.append(v)
                callargs.append(var)
                ARGTYPES.append(var.concretetype)
            else:
                opargs.append(var)
        newop = SpaceOperation(op.opname, opargs, result)
        startblock = Block(inputargs)
        startblock.operations.append(newop)
        newgraph = FunctionGraph("dummy_exc1", startblock)
        startblock.closeblock(Link([result], newgraph.returnblock))
        newgraph.returnblock.inputargs[0].concretetype = op.result.concretetype
        self.gen_exc_check(startblock, newgraph.returnblock)
        excblock = Block([])

        llops = rtyper.LowLevelOpList(None)
        var_value = self.gen_getfield('exc_value', llops)
        var_type = self.gen_getfield('exc_type', llops)
        #
        c_check1 = self.c_assertion_error_ll_exc_type
        c_check2 = self.c_n_i_error_ll_exc_type
        llops.genop('debug_catch_exception', [var_type, c_check1, c_check2])
        #
        self.gen_setfield('exc_value', self.c_null_evalue, llops)
        self.gen_setfield('exc_type', self.c_null_etype, llops)
        excblock.operations[:] = llops
        newgraph.exceptblock.inputargs[
            0].concretetype = self.lltype_of_exception_type
        newgraph.exceptblock.inputargs[
            1].concretetype = self.lltype_of_exception_value
        excblock.closeblock(Link([var_type, var_value], newgraph.exceptblock))
        startblock.exits[True].target = excblock
        startblock.exits[True].args = []
        fptr = self.constant_func("dummy_exc1", ARGTYPES,
                                  op.result.concretetype, newgraph)
        return newgraph, SpaceOperation("direct_call", [fptr] + callargs,
                                        op.result)
コード例 #27
0
def union(w1, w2):
    "Union of two variables or constants."
    if w1 == w2:
        return w1
    if w1 is None or w2 is None:
        return None  # if w1 or w2 is an undefined local, we "kill" the value
        # coming from the other path and return an undefined local
    if isinstance(w1, Variable) or isinstance(w2, Variable):
        return Variable()  # new fresh Variable
    if isinstance(w1, Constant) and isinstance(w2, Constant):
        # FlowSignal represent stack unrollers in the stack.
        # They should not be merged because they will be unwrapped.
        # This is needed for try:except: and try:finally:, though
        # it makes the control flow a bit larger by duplicating the
        # handlers.
        dont_merge_w1 = w1 in UNPICKLE_TAGS or isinstance(w1.value, SpecTag)
        dont_merge_w2 = w2 in UNPICKLE_TAGS or isinstance(w2.value, SpecTag)
        if dont_merge_w1 or dont_merge_w2:
            raise UnionError
        else:
            return Variable()  # generalize different constants
    raise TypeError('union of %r and %r' %
                    (w1.__class__.__name__, w2.__class__.__name__))
コード例 #28
0
ファイル: pygraph.py プロジェクト: tools-env/mesapy
 def __init__(self, func, code):
     from rpython.flowspace.flowcontext import SpamBlock
     locals = [None] * code.co_nlocals
     for i in range(code.formalargcount):
         locals[i] = Variable(code.co_varnames[i])
     state = FrameState(locals, [], None, [], 0)
     initialblock = SpamBlock(state)
     unsafe = False
     if func.func_doc and func.func_doc.lstrip().startswith('UNSAFE'):
         unsafe = True
     super(PyGraph, self).__init__(self._sanitize_funcname(func), initialblock, unsafe=unsafe)
     self.func = func
     self.signature = code.signature
     self.defaults = func.func_defaults or ()
コード例 #29
0
ファイル: normalizecalls.py プロジェクト: sota/pypy-old
def normalize_calltable_row_annotation(annotator, graphs):
    if len(graphs) <= 1:
        return False  # nothing to do
    graph_bindings = {}
    for graph in graphs:
        graph_bindings[graph] = [annotator.binding(v) for v in graph.getargs()]
    iterbindings = graph_bindings.itervalues()
    nbargs = len(iterbindings.next())
    for binding in iterbindings:
        assert len(binding) == nbargs

    generalizedargs = []
    for i in range(nbargs):
        args_s = []
        for graph, bindings in graph_bindings.items():
            args_s.append(bindings[i])
        s_value = annmodel.unionof(*args_s)
        generalizedargs.append(s_value)
    result_s = [
        annotator.binding(graph.getreturnvar()) for graph in graph_bindings
    ]
    generalizedresult = annmodel.unionof(*result_s)

    conversion = False
    for graph in graphs:
        bindings = graph_bindings[graph]
        need_conversion = (generalizedargs != bindings)
        if need_conversion:
            conversion = True
            oldblock = graph.startblock
            inlist = []
            for j, s_value in enumerate(generalizedargs):
                v = Variable(graph.getargs()[j])
                annotator.setbinding(v, s_value)
                inlist.append(v)
            newblock = Block(inlist)
            # prepare the output args of newblock and link
            outlist = inlist[:]
            newblock.closeblock(Link(outlist, oldblock))
            graph.startblock = newblock
            # finished
            checkgraph(graph)
            annotator.annotated[newblock] = annotator.annotated[oldblock]
        # convert the return value too
        if annotator.binding(graph.getreturnvar()) != generalizedresult:
            conversion = True
            annotator.setbinding(graph.getreturnvar(), generalizedresult)

    return conversion
コード例 #30
0
def union(w1, w2):
    "Union of two variables or constants."
    from rpython.flowspace.flowcontext import FlowSignal
    if w1 == w2:
        return w1
    if w1 is None or w2 is None:
        return None  # if w1 or w2 is an undefined local, we "kill" the value
        # coming from the other path and return an undefined local
    if isinstance(w1, Variable) or isinstance(w2, Variable):
        return Variable()  # new fresh Variable
    if isinstance(w1, Constant) and isinstance(w2, Constant):
        if isinstance(w1.value, SpecTag) or isinstance(w2.value, SpecTag):
            raise UnionError
        else:
            return Variable()  # generalize different constants
    if isinstance(w1, FlowSignal) and isinstance(w2, FlowSignal):
        if type(w1) is not type(w2):
            raise UnionError
        vars = [union(v1, v2) for v1, v2 in zip(w1.args, w2.args)]
        return w1.rebuild(*vars)
    if isinstance(w1, FlowSignal) or isinstance(w2, FlowSignal):
        raise UnionError
    raise TypeError('union of %r and %r' %
                    (w1.__class__.__name__, w2.__class__.__name__))