Ejemplo n.º 1
0
    def test_direct_assembler_call_translates(self):
        """Test CALL_ASSEMBLER and the recursion limit"""
        # - also tests threadlocalref_get
        from rpython.rlib.rstackovf import StackOverflow

        class Thing(object):
            def __init__(self, val):
                self.val = val

        class Frame(object):
            _virtualizable_ = ['thing']

        driver = JitDriver(greens=['codeno'],
                           reds=['i', 'frame'],
                           virtualizables=['frame'],
                           get_printable_location=lambda codeno: str(codeno))

        class SomewhereElse(object):
            pass

        somewhere_else = SomewhereElse()

        class Foo(object):
            pass

        t = ThreadLocalReference(Foo, loop_invariant=True)
        tf = ThreadLocalField(lltype.Char, "test_call_assembler_")

        def change(newthing):
            somewhere_else.frame.thing = newthing

        def main(codeno):
            frame = Frame()
            somewhere_else.frame = frame
            frame.thing = Thing(0)
            portal(codeno, frame)
            return frame.thing.val

        def portal(codeno, frame):
            i = 0
            while i < 10:
                driver.can_enter_jit(frame=frame, codeno=codeno, i=i)
                driver.jit_merge_point(frame=frame, codeno=codeno, i=i)
                nextval = frame.thing.val
                if codeno == 0:
                    subframe = Frame()
                    subframe.thing = Thing(nextval)
                    nextval = portal(1, subframe)
                elif frame.thing.val > 40:
                    change(Thing(13))
                    nextval = 13
                frame.thing = Thing(nextval + 1)
                i += 1
                if t.get().nine != 9: raise ValueError
                if ord(tf.getraw()) != 0x92: raise ValueError
            return frame.thing.val

        driver2 = JitDriver(greens=[], reds=['n'])

        def main2(bound):
            try:
                while portal2(bound) == -bound + 1:
                    bound *= 2
            except StackOverflow:
                pass
            return bound

        def portal2(n):
            while True:
                driver2.jit_merge_point(n=n)
                n -= 1
                if n <= 0:
                    return n
                n = portal2(n)

        assert portal2(10) == -9

        def setup(value):
            foo = Foo()
            foo.nine = value
            t.set(foo)
            tf.setraw("\x92")
            return foo

        def mainall(codeno, bound):
            foo = setup(bound + 8)
            result = main(codeno) + main2(bound)
            keepalive_until_here(foo)
            return result

        tmp_obj = setup(9)
        expected_1 = main(0)
        res = self.meta_interp(mainall, [0, 1],
                               inline=True,
                               policy=StopAtXPolicy(change))
        print hex(res)
        assert res & 255 == expected_1
        bound = res & ~255
        assert 1024 <= bound <= 131072
        assert bound & (bound - 1) == 0  # a power of two
Ejemplo n.º 2
0
            if resolver is not None:
                resolver.smash(
                    sealException(
                        userError(u"Ejector tried to escape from vat")))

    def takeSomeTurns(self):
        # Limit the number of continuous turns to keep network latency low.
        # It's possible that more turns will be queued while we're taking
        # these turns, after all.
        count = len(self._pending)
        # print "Taking", count, "turn(s) on", self.repr()
        for _ in range(count):
            self.takeTurn()


currentVat = ThreadLocalReference(Vat)


def testingVat():
    return Vat(None, None, name="testing", checkpoints=1000)


class scopedVat(object):
    def __init__(self, vat):
        self.vat = vat

    def __enter__(self):
        oldVat = currentVat.get()
        if oldVat is not None:
            raise RuntimeError("Implementation error: Attempted to nest vat")
        currentVat.set(self.vat)