From ecdef8de8b569e3075baa80c8b04526110d07763 Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Fri, 24 Aug 2018 11:35:08 -0400 Subject: [PATCH] Working fiber marshaling. --- src/core/marsh.c | 59 ++++++++++++++++++++++++++++--------------- src/include/dst/dst.h | 2 +- test/suite1.dst | 1 + 3 files changed, 41 insertions(+), 21 deletions(-) diff --git a/src/core/marsh.c b/src/core/marsh.c index 9a3fcac5..91448bb8 100644 --- a/src/core/marsh.c +++ b/src/core/marsh.c @@ -103,6 +103,9 @@ static void pushbytes(MarshalState *st, const uint8_t *bytes, int32_t len) { /* Forward declaration to enable mutual recursion. */ static void marshal_one(MarshalState *st, Dst x, int flags); +static void marshal_one_fiber(MarshalState *st, DstFiber *fiber, int flags); +static void marshal_one_def(MarshalState *st, DstFuncDef *def, int flags); +static void marshal_one_env(MarshalState *st, DstFuncEnv *env, int flags); /* Marshal a function env */ static void marshal_one_env(MarshalState *st, DstFuncEnv *env, int flags) { @@ -120,11 +123,11 @@ static void marshal_one_env(MarshalState *st, DstFuncEnv *env, int flags) { pushint(st, env->length); if (env->offset) { /* On stack variant */ - marshal_one(st, dst_wrap_fiber(env->as.fiber), flags); + marshal_one_fiber(st, env->as.fiber, flags + 1); } else { /* Off stack variant */ for (int32_t i = 0; i < env->length; i++) - marshal_one(st, env->as.values[i], flags); + marshal_one(st, env->as.values[i], flags + 1); } } @@ -485,12 +488,27 @@ static int32_t readint(UnmarshalState *st, const uint8_t **atdata) { return ret; } -/* Forward declaration */ +/* Forward declarations for mutual recursion */ static const uint8_t *unmarshal_one( UnmarshalState *st, const uint8_t *data, Dst *out, int flags); +static const uint8_t *unmarshal_one_env( + UnmarshalState *st, + const uint8_t *data, + DstFuncEnv **out, + int flags); +static const uint8_t *unmarshal_one_def( + UnmarshalState *st, + const uint8_t *data, + DstFuncDef **out, + int flags); +static const uint8_t *unmarshal_one_fiber( + UnmarshalState *st, + const uint8_t *data, + DstFiber **out, + int flags); /* Unmarshal a funcenv */ static const uint8_t *unmarshal_one_env( @@ -515,10 +533,7 @@ static const uint8_t *unmarshal_one_env( int32_t length = readint(st, &data); if (offset) { /* On stack variant */ - Dst fiberv; - data = unmarshal_one(st, data, &fiberv, flags); - if (!dst_checktype(fiberv, DST_FIBER)) longjmp(st->err, UMR_EXPECTED_FIBER); - env->as.fiber = dst_unwrap_fiber(fiberv); + data = unmarshal_one_fiber(st, data, &(env->as.fiber), flags); /* Unmarshaling fiber may set values */ if (env->offset != 0 && env->offset != offset) longjmp(st->err, UMR_UNKNOWN); if (env->length != 0 && env->length != length) longjmp(st->err, UMR_UNKNOWN); @@ -528,7 +543,7 @@ static const uint8_t *unmarshal_one_env( if (!env->as.values) { DST_OUT_OF_MEMORY; } - for (int32_t i = 0; i < env->length; i++) + for (int32_t i = 0; i < length; i++) data = unmarshal_one(st, data, env->as.values + i, flags); } env->offset = offset; @@ -707,17 +722,20 @@ static const uint8_t *unmarshal_one_fiber( fiber->maxstack = readint(st, &data); /* Check for bad flags and ints */ - if (frame + DST_FRAME_SIZE > fiber->stackstart || + if ((int32_t)(frame + DST_FRAME_SIZE) > fiber->stackstart || fiber->stackstart > fiber->stacktop || - fiber->stacktop > fiber->capacity || fiber->stacktop > fiber->maxstack) { + printf("bad flags and ints.\n"); goto error; } /* Get root fuction */ Dst funcv; - data = dst_unmarshal_one(st, data, &funcv, flags + 1); - if (!dst_checktype(funcv, DST_FUNCTION)) goto error; + data = unmarshal_one(st, data, &funcv, flags + 1); + if (!dst_checktype(funcv, DST_FUNCTION)) { + printf("bad root func.\n"); + goto error; + } fiber->root = dst_unwrap_function(funcv); /* Allocate stack memory */ @@ -745,8 +763,10 @@ static const uint8_t *unmarshal_one_fiber( /* Get function */ Dst funcv; data = unmarshal_one(st, data, &funcv, flags + 1); - if (!dst_checktype(framefunc, DST_FUNCTION)) + if (!dst_checktype(funcv, DST_FUNCTION)) { + printf("bad root func.\n"); goto error; + } func = dst_unwrap_function(funcv); def = func->def; @@ -763,15 +783,14 @@ static const uint8_t *unmarshal_one_fiber( } /* Error checking */ - int32_t expected_framesize = def->arity + !!(def->flags & DST_FUNCDEF_FLAG_VARARG); + int32_t expected_framesize = def->slotcount; if (expected_framesize != stacktop - stack) goto error; if (pcdiff < 0 || pcdiff >= def->bytecode_length) goto error; - if (prevframe + DST_FRAME_SIZE > stack) goto error; + if ((int32_t)(prevframe + DST_FRAME_SIZE) > stack) goto error; /* Get stack items */ - for (int32_t i = stack; i < stacktop; i++) { - data = dst_unmarshal_one(st, data, fiber->data + i, flags + 1); - } + for (int32_t i = stack; i < stacktop; i++) + data = unmarshal_one(st, data, fiber->data + i, flags + 1); /* Set frame */ framep->env = env; @@ -787,14 +806,14 @@ static const uint8_t *unmarshal_one_fiber( if (stack < 0) goto error; /* Check for child fiber */ - if (fiber->flags & DST_FIBER_HAS_CHILD) { + if (fiber->flags & DST_FIBER_FLAG_HASCHILD) { fiber->flags &= ~DST_FIBER_FLAG_HASCHILD; data = unmarshal_one_fiber(st, data, &(fiber->child), flags + 1); } /* Return data */ fiber->frame = frame; - *out = dst_wrap_fiber(fiber); + *out = fiber; return data; error: diff --git a/src/include/dst/dst.h b/src/include/dst/dst.h index fbf21589..a06bcede 100644 --- a/src/include/dst/dst.h +++ b/src/include/dst/dst.h @@ -577,7 +577,7 @@ struct DstStackFrame { uint32_t *pc; DstFuncEnv *env; int32_t prevframe; - uint32_t flags; + int32_t flags; }; /* Number of Dsts a frame takes up in the stack */ diff --git a/test/suite1.dst b/test/suite1.dst index 3b40d9df..7210b245 100644 --- a/test/suite1.dst +++ b/test/suite1.dst @@ -166,6 +166,7 @@ (testmarsh (fn thing [x] (+ 11 x x 30)) "marshal function 3") (testmarsh mapa "marshal function 4") (testmarsh reduce "marshal function 5") +(testmarsh (fiber.new (fn @[] (yield 1) 2)) "marshal simple fiber") # Large functions (def manydefs (fora [i :range [0 300]] (tuple 'def (gensym) (string "value_" i))))