1
0
mirror of https://github.com/janet-lang/janet synced 2024-12-26 00:10:27 +00:00

Working fiber marshaling.

This commit is contained in:
Calvin Rose 2018-08-24 11:35:08 -04:00
parent b8a6cd84c0
commit ecdef8de8b
3 changed files with 41 additions and 21 deletions

View File

@ -103,6 +103,9 @@ static void pushbytes(MarshalState *st, const uint8_t *bytes, int32_t len) {
/* Forward declaration to enable mutual recursion. */ /* Forward declaration to enable mutual recursion. */
static void marshal_one(MarshalState *st, Dst x, int flags); 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 */ /* Marshal a function env */
static void marshal_one_env(MarshalState *st, DstFuncEnv *env, int flags) { 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); pushint(st, env->length);
if (env->offset) { if (env->offset) {
/* On stack variant */ /* On stack variant */
marshal_one(st, dst_wrap_fiber(env->as.fiber), flags); marshal_one_fiber(st, env->as.fiber, flags + 1);
} else { } else {
/* Off stack variant */ /* Off stack variant */
for (int32_t i = 0; i < env->length; i++) 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; return ret;
} }
/* Forward declaration */ /* Forward declarations for mutual recursion */
static const uint8_t *unmarshal_one( static const uint8_t *unmarshal_one(
UnmarshalState *st, UnmarshalState *st,
const uint8_t *data, const uint8_t *data,
Dst *out, Dst *out,
int flags); 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 */ /* Unmarshal a funcenv */
static const uint8_t *unmarshal_one_env( static const uint8_t *unmarshal_one_env(
@ -515,10 +533,7 @@ static const uint8_t *unmarshal_one_env(
int32_t length = readint(st, &data); int32_t length = readint(st, &data);
if (offset) { if (offset) {
/* On stack variant */ /* On stack variant */
Dst fiberv; data = unmarshal_one_fiber(st, data, &(env->as.fiber), flags);
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);
/* Unmarshaling fiber may set values */ /* Unmarshaling fiber may set values */
if (env->offset != 0 && env->offset != offset) longjmp(st->err, UMR_UNKNOWN); if (env->offset != 0 && env->offset != offset) longjmp(st->err, UMR_UNKNOWN);
if (env->length != 0 && env->length != length) 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) { if (!env->as.values) {
DST_OUT_OF_MEMORY; 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); data = unmarshal_one(st, data, env->as.values + i, flags);
} }
env->offset = offset; env->offset = offset;
@ -707,17 +722,20 @@ static const uint8_t *unmarshal_one_fiber(
fiber->maxstack = readint(st, &data); fiber->maxstack = readint(st, &data);
/* Check for bad flags and ints */ /* 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->stackstart > fiber->stacktop ||
fiber->stacktop > fiber->capacity ||
fiber->stacktop > fiber->maxstack) { fiber->stacktop > fiber->maxstack) {
printf("bad flags and ints.\n");
goto error; goto error;
} }
/* Get root fuction */ /* Get root fuction */
Dst funcv; Dst funcv;
data = dst_unmarshal_one(st, data, &funcv, flags + 1); data = unmarshal_one(st, data, &funcv, flags + 1);
if (!dst_checktype(funcv, DST_FUNCTION)) goto error; if (!dst_checktype(funcv, DST_FUNCTION)) {
printf("bad root func.\n");
goto error;
}
fiber->root = dst_unwrap_function(funcv); fiber->root = dst_unwrap_function(funcv);
/* Allocate stack memory */ /* Allocate stack memory */
@ -745,8 +763,10 @@ static const uint8_t *unmarshal_one_fiber(
/* Get function */ /* Get function */
Dst funcv; Dst funcv;
data = unmarshal_one(st, data, &funcv, flags + 1); 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; goto error;
}
func = dst_unwrap_function(funcv); func = dst_unwrap_function(funcv);
def = func->def; def = func->def;
@ -763,15 +783,14 @@ static const uint8_t *unmarshal_one_fiber(
} }
/* Error checking */ /* 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 (expected_framesize != stacktop - stack) goto error;
if (pcdiff < 0 || pcdiff >= def->bytecode_length) 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 */ /* Get stack items */
for (int32_t i = stack; i < stacktop; i++) { for (int32_t i = stack; i < stacktop; i++)
data = dst_unmarshal_one(st, data, fiber->data + i, flags + 1); data = unmarshal_one(st, data, fiber->data + i, flags + 1);
}
/* Set frame */ /* Set frame */
framep->env = env; framep->env = env;
@ -787,14 +806,14 @@ static const uint8_t *unmarshal_one_fiber(
if (stack < 0) goto error; if (stack < 0) goto error;
/* Check for child fiber */ /* Check for child fiber */
if (fiber->flags & DST_FIBER_HAS_CHILD) { if (fiber->flags & DST_FIBER_FLAG_HASCHILD) {
fiber->flags &= ~DST_FIBER_FLAG_HASCHILD; fiber->flags &= ~DST_FIBER_FLAG_HASCHILD;
data = unmarshal_one_fiber(st, data, &(fiber->child), flags + 1); data = unmarshal_one_fiber(st, data, &(fiber->child), flags + 1);
} }
/* Return data */ /* Return data */
fiber->frame = frame; fiber->frame = frame;
*out = dst_wrap_fiber(fiber); *out = fiber;
return data; return data;
error: error:

View File

@ -577,7 +577,7 @@ struct DstStackFrame {
uint32_t *pc; uint32_t *pc;
DstFuncEnv *env; DstFuncEnv *env;
int32_t prevframe; int32_t prevframe;
uint32_t flags; int32_t flags;
}; };
/* Number of Dsts a frame takes up in the stack */ /* Number of Dsts a frame takes up in the stack */

View File

@ -166,6 +166,7 @@
(testmarsh (fn thing [x] (+ 11 x x 30)) "marshal function 3") (testmarsh (fn thing [x] (+ 11 x x 30)) "marshal function 3")
(testmarsh mapa "marshal function 4") (testmarsh mapa "marshal function 4")
(testmarsh reduce "marshal function 5") (testmarsh reduce "marshal function 5")
(testmarsh (fiber.new (fn @[] (yield 1) 2)) "marshal simple fiber")
# Large functions # Large functions
(def manydefs (fora [i :range [0 300]] (tuple 'def (gensym) (string "value_" i)))) (def manydefs (fora [i :range [0 300]] (tuple 'def (gensym) (string "value_" i))))