예제 #1
0
    def action_add(self, id, stack_const, stack_exec, **kwargs):
        if id is None:
            id = uuid4().hex
            print(f'Generated ID {id}')

        def check_in_stack(k):
            if k in stack:
                raise KeyError(f'{k} defined twice')

        stack = {}

        for k, v in stack_const:
            check_in_stack(k)
            stack[k] = v

        for k, v in stack_exec:
            check_in_stack(k)

            try:
                v = eval(compile(v, filename='<string>', mode='eval'))
                stack[k] = v
            except:
                print(f'While evaluating {k}={v}')
                raise

        a, b = StackFrame.new(id, stack).create(self.db)

        return [a], [b]
예제 #2
0
    def initiate(cls, db: Etcd3Client, frz: FrozenThreadContext, r: 'Request', stack):
        # we need:
        # - create a new stack frame in the context of the http request

        sf = StackFrame.new(
            uuid4().hex,
            {
                **stack,
                'req_id': r.id
            }
        )

        a1, b1 = frz.call(db, sf)
        a2, b2 = sf.create(db)

        ok, _ = db.transaction(
            compare=[
                a1,
                a2
            ],
            success=[
                b1,
                b2,
            ], failure=[

            ]
        )

        return ok, r
    def test_ok(self):
        db, lease = self._db_lease()
        opcodes = load_opcodes(tfci_core.opcodes, tfci_std.opcodes)

        eng = ExecutionEngine(
            TEST_IDENT, lease, opcodes,
            TestProgramPages('dasm_ep_2_plus_2.txt', db, opcodes), db)

        sf1 = StackFrame.new('sf1', {'x': 1})

        t1 = ThreadContext.new('t1', 'ep_2_plus_2', [sf1.id])

        ok, _, _ = sf1.create().merge(t1.create()).exec(db)

        self.assertTrue(ok, "Transaction must execute successfully")

        ok, upd = eng.step(t1)

        self.assertTrue(ok, "Step must execute succ I")

        ok, upd = eng.step(t1)

        self.assertTrue(ok, "Step must execute succ II")

        ok, upd = eng.step(t1)

        self.assertTrue(ok, "Step must execute succ III")

        tx1 = StackFrame.load_exists('sf1')

        sf: StackFrame

        ok, (sf, ), _ = tx1.exec(db)

        self.assertTrue(ok, "StackFrame must exist")

        self.assertEqual(sf.vals['x'], 3, "Return value must be equal")

        tx2 = ThreadContext.load_exists('t1')

        ok, (tctx, ), _ = tx2.exec(db)

        self.assertFalse(ok, "ThreadContext must not exist")
예제 #4
0
    def fn(self, ctx: ExecutionContext) -> FollowUp:
        # how do we know which stacks have been changed ?

        csf = StackFrame.load_exists(ctx.singleton.db, ctx.resolve_arg(0))

        push_pop(csf, ctx, ctx.args[1:])

        return FollowUp.new(create_threads=[
            ctx.thread.update(ip=ctx.nip, sp=[csf.id] + ctx.thread.sp)
        ],
                            create_stacks=[csf])
예제 #5
0
    def fn(self, ctx: ExecutionContext) -> FollowUp:
        # how do we know which stacks have been changed ?

        csf = StackFrame.new(uuid4().hex)

        push_pop(csf, ctx)

        return FollowUp.new(create_threads=[
            ctx.thread.update(ip=ctx.nip, sp=[csf.id] + ctx.thread.sp)
        ],
                            create_stacks=[csf])
예제 #6
0
def push_pop(csf: StackFrame, ctx: ExecutionContext, args=None):
    if args is None:
        args = ctx.args

    for arg in args:
        if isinstance(arg, Identifier):
            csf.set(arg.name, ctx.stack_get(arg.name, arg.level))
        elif isinstance(arg, Constant):
            raise ExecutionError(
                f'(push) `{ctx.thread.id}:{ctx.thread.ip}` constant push requires an identifier'
            )
        elif isinstance(arg, Map):
            if isinstance(arg.to, Constant):
                val = arg.to.value
            elif isinstance(arg.to, Identifier):
                val = ctx.stack_get(arg.to.name, arg.to.level)
            else:
                raise NotImplementedError(f'{repr(arg)}')

            csf.set(arg.identifier.name, val)
        else:
            raise NotImplementedError(f'{repr(arg)}')
    def test_multi_proc(self):
        db, lease = self._db_lease()

        opcodes = load_opcodes(tfci_core.opcodes, tfci_std.opcodes)

        returns = []

        def callback(*args, **kwargs):
            returns.append((args, kwargs))

        cb_fix = callback_fixture('callback_fix', callback)

        opcodes[cb_fix.name] = cb_fix

        eng = ExecutionEngine(
            TEST_IDENT, lease, opcodes,
            TestProgramPages('dasm_multi_proc.txt', db, opcodes), db)

        PAYLOAD = list(range(5))

        sf1 = StackFrame.new('sf1', {
            'v': PAYLOAD,
            'x': 'callback_fn',
            '_ret': 'ret_fn',
        })

        t1 = ThreadContext.new('t1', 'fork_loop', [sf1.id])

        ok, _, _ = sf1.create().merge(t1.create()).exec(db)

        tcxs = [t1]

        while len(tcxs):
            for t in tcxs:
                ok, upd = eng.step(t)

                self.assertTrue(ok, 'Must be OK')
                tcxs = ThreadContext.load_all(db).values()

        self.assertEqual(sorted([y['v'] for _, y in returns]), PAYLOAD)
    def test_nonexistent_stack_arg(self):
        db, lease = self._db_lease()
        opcodes = load_opcodes(tfci_core.opcodes, tfci_std.opcodes)
        eng = ExecutionEngine(
            TEST_IDENT, lease, opcodes,
            TestProgramPages('dasm_ep_2_plus_2.txt', db, opcodes), db)

        sf1 = StackFrame.new('sf1')

        t1 = ThreadContext.new('t1', 'ep_2_plus_2', [sf1.id])

        tx = sf1.create().merge(t1.create())

        ok, _, _ = tx.exec(db)

        self.assertTrue(ok, "Transaction must execute successfully")

        ok, upd = eng.step(t1)

        self.assertTrue(ok, "Step must execute succ I")

        ok, upd = eng.step(t1)

        self.assertFalse(ok, "Step must execute succ II")
예제 #9
0
    def action_add(self, id, stacks, ep, **kwargs):
        a, b = self.model.new(id, ep, stacks).create(self.db)

        return [a] + [StackFrame.exists(self.db, s) for s in stacks], [b]