mirror of
https://github.com/janet-lang/janet
synced 2025-07-05 11:32:54 +00:00
More work on serilaization
This commit is contained in:
parent
6220b70105
commit
58edb63607
@ -481,8 +481,6 @@ static Slot compile_symbol(GstCompiler *c, FormOptions opts, GstValue sym) {
|
|||||||
/* We have a named literal */
|
/* We have a named literal */
|
||||||
return compile_literal(c, opts, lit);
|
return compile_literal(c, opts, lit);
|
||||||
} else if (level > 0) {
|
} else if (level > 0) {
|
||||||
/* We have an upvalue */
|
|
||||||
if (level > 1) {
|
|
||||||
/* We have an upvalue from a parent function. Make
|
/* We have an upvalue from a parent function. Make
|
||||||
* sure that the chain of functions up to the upvalue keep
|
* sure that the chain of functions up to the upvalue keep
|
||||||
* their parent references */
|
* their parent references */
|
||||||
@ -493,7 +491,6 @@ static Slot compile_symbol(GstCompiler *c, FormOptions opts, GstValue sym) {
|
|||||||
scope = scope->parent;
|
scope = scope->parent;
|
||||||
}
|
}
|
||||||
scope->touchEnv = 1;
|
scope->touchEnv = 1;
|
||||||
}
|
|
||||||
ret = compiler_get_target(c, opts);
|
ret = compiler_get_target(c, opts);
|
||||||
gst_buffer_push_u16(c->vm, buffer, GST_OP_UPV);
|
gst_buffer_push_u16(c->vm, buffer, GST_OP_UPV);
|
||||||
gst_buffer_push_u16(c->vm, buffer, ret.index);
|
gst_buffer_push_u16(c->vm, buffer, ret.index);
|
||||||
|
@ -240,7 +240,8 @@ static const char *gst_deserialize_impl(
|
|||||||
uint16_t prevsize = 0;
|
uint16_t prevsize = 0;
|
||||||
uint8_t statusbyte;
|
uint8_t statusbyte;
|
||||||
t = gst_thread(vm, gst_wrap_nil(), 64);
|
t = gst_thread(vm, gst_wrap_nil(), 64);
|
||||||
gst_array_push(vm, visited, gst_wrap_thread(t));
|
ret = gst_wrap_thread(t);
|
||||||
|
gst_array_push(vm, visited, ret);
|
||||||
err = gst_deserialize_impl(vm, data, end, &data, visited, &ret);
|
err = gst_deserialize_impl(vm, data, end, &data, visited, &ret);
|
||||||
if (err != NULL) return err;
|
if (err != NULL) return err;
|
||||||
if (ret.type == GST_NIL) {
|
if (ret.type == GST_NIL) {
|
||||||
@ -250,30 +251,26 @@ static const char *gst_deserialize_impl(
|
|||||||
} else {
|
} else {
|
||||||
return "expected thread parent to thread";
|
return "expected thread parent to thread";
|
||||||
}
|
}
|
||||||
ret = gst_wrap_thread(t);
|
|
||||||
deser_assert(data < end, UEB);
|
deser_assert(data < end, UEB);
|
||||||
statusbyte = *data++;
|
statusbyte = *data++;
|
||||||
read_u32(length);
|
read_u32(length);
|
||||||
/* Check for empty thread - TODO check for valid state */
|
|
||||||
if (length == 0)
|
|
||||||
break;
|
|
||||||
/* Set status */
|
/* Set status */
|
||||||
if (statusbyte == 0) t->status = GST_THREAD_PENDING;
|
t->status = statusbyte % 4;
|
||||||
else if (statusbyte == 1) t->status = GST_THREAD_ALIVE;
|
|
||||||
else t->status = GST_THREAD_DEAD;
|
|
||||||
/* Add frames */
|
/* Add frames */
|
||||||
for (i = 0; i < length; ++i) {
|
for (i = 0; i < length; ++i) {
|
||||||
GstValue callee, env;
|
GstValue callee, env;
|
||||||
uint32_t pcoffset;
|
uint32_t pcoffset;
|
||||||
uint16_t ret, args, size, j;
|
uint16_t ret, args, size, j;
|
||||||
/* Create a new frame */
|
|
||||||
if (i > 0)
|
|
||||||
gst_thread_beginframe(vm, t, gst_wrap_nil(), 0);
|
|
||||||
/* Read the stack */
|
/* Read the stack */
|
||||||
err = gst_deserialize_impl(vm, data, end, &data, visited, &callee);
|
err = gst_deserialize_impl(vm, data, end, &data, visited, &callee);
|
||||||
if (err != NULL) return err;
|
if (err != NULL) return err;
|
||||||
err = gst_deserialize_impl(vm, data, end, &data, visited, &env);
|
err = gst_deserialize_impl(vm, data, end, &data, visited, &env);
|
||||||
if (err != NULL) return err;
|
if (err != NULL) return err;
|
||||||
|
if (env.type != GST_FUNCENV && env.type != GST_NIL)
|
||||||
|
return "expected funcenv in stackframe";
|
||||||
|
/* Create a new frame */
|
||||||
|
if (i > 0)
|
||||||
|
gst_thread_beginframe(vm, t, gst_wrap_nil(), 0);
|
||||||
read_u32(pcoffset);
|
read_u32(pcoffset);
|
||||||
read_u32(ret);
|
read_u32(ret);
|
||||||
read_u32(args);
|
read_u32(args);
|
||||||
@ -282,15 +279,16 @@ static const char *gst_deserialize_impl(
|
|||||||
stack = gst_thread_stack(t);
|
stack = gst_thread_stack(t);
|
||||||
if (callee.type == GST_FUNCTION) {
|
if (callee.type == GST_FUNCTION) {
|
||||||
gst_frame_pc(stack) = callee.data.function->def->byteCode + pcoffset;
|
gst_frame_pc(stack) = callee.data.function->def->byteCode + pcoffset;
|
||||||
if (env.type == GST_FUNCENV)
|
|
||||||
gst_frame_env(stack) = env.data.env;
|
|
||||||
else
|
|
||||||
gst_frame_env(stack) = NULL;
|
|
||||||
}
|
}
|
||||||
gst_frame_ret(stack) = ret;
|
gst_frame_ret(stack) = ret;
|
||||||
gst_frame_args(stack) = args;
|
gst_frame_args(stack) = args;
|
||||||
gst_frame_size(stack) = size;
|
gst_frame_size(stack) = size;
|
||||||
gst_frame_prevsize(stack) = prevsize;
|
gst_frame_prevsize(stack) = prevsize;
|
||||||
|
gst_frame_callee(stack) = callee;
|
||||||
|
if (env.type == GST_NIL)
|
||||||
|
gst_frame_env(stack) = NULL;
|
||||||
|
else
|
||||||
|
gst_frame_env(stack) = env.data.env;
|
||||||
prevsize = size;
|
prevsize = size;
|
||||||
/* Push stack args */
|
/* Push stack args */
|
||||||
for (j = 0; j < size; ++j) {
|
for (j = 0; j < size; ++j) {
|
||||||
@ -333,6 +331,8 @@ static const char *gst_deserialize_impl(
|
|||||||
def->literalsLen = literalsLen;
|
def->literalsLen = literalsLen;
|
||||||
if (literalsLen > 0) {
|
if (literalsLen > 0) {
|
||||||
def->literals = gst_alloc(vm, literalsLen * sizeof(GstValue));
|
def->literals = gst_alloc(vm, literalsLen * sizeof(GstValue));
|
||||||
|
} else {
|
||||||
|
def->literals = NULL;
|
||||||
}
|
}
|
||||||
for (i = 0; i < literalsLen; ++i) {
|
for (i = 0; i < literalsLen; ++i) {
|
||||||
err = gst_deserialize_impl(vm, data, end, &data, visited, def->literals + i);
|
err = gst_deserialize_impl(vm, data, end, &data, visited, def->literals + i);
|
||||||
@ -385,6 +385,9 @@ static const char *gst_deserialize_impl(
|
|||||||
if (err != NULL) return err;
|
if (err != NULL) return err;
|
||||||
err = gst_deserialize_impl(vm, data, end, &data, visited, &env);
|
err = gst_deserialize_impl(vm, data, end, &data, visited, &env);
|
||||||
if (err != NULL) return err;
|
if (err != NULL) return err;
|
||||||
|
printf("parent: %s\n", (const char *)gst_to_string(vm, parent));
|
||||||
|
printf("def: %s\n", (const char *)gst_to_string(vm, def));
|
||||||
|
printf("env: %s\n", (const char *)gst_to_string(vm, env));
|
||||||
if (parent.type == GST_NIL) {
|
if (parent.type == GST_NIL) {
|
||||||
ret.data.function->parent = NULL;
|
ret.data.function->parent = NULL;
|
||||||
} else if (parent.type == GST_FUNCTION) {
|
} else if (parent.type == GST_FUNCTION) {
|
||||||
@ -472,6 +475,7 @@ const char *gst_serialize_impl(
|
|||||||
#define write_u16(b) gst_buffer_push_u16(vm, buffer, (b))
|
#define write_u16(b) gst_buffer_push_u16(vm, buffer, (b))
|
||||||
#define write_dbl(b) gst_buffer_push_real(vm, buffer, (b))
|
#define write_dbl(b) gst_buffer_push_real(vm, buffer, (b))
|
||||||
#define write_int(b) gst_buffer_push_integer(vm, buffer, (b))
|
#define write_int(b) gst_buffer_push_integer(vm, buffer, (b))
|
||||||
|
/*printf("Type: %d\n", x.type);*/
|
||||||
|
|
||||||
/* Check non reference types - if successful, return NULL */
|
/* Check non reference types - if successful, return NULL */
|
||||||
switch (x.type) {
|
switch (x.type) {
|
||||||
@ -613,9 +617,7 @@ const char *gst_serialize_impl(
|
|||||||
err = gst_serialize_impl(vm, buffer, visited, nextId, gst_wrap_nil());
|
err = gst_serialize_impl(vm, buffer, visited, nextId, gst_wrap_nil());
|
||||||
if (err != NULL) return err;
|
if (err != NULL) return err;
|
||||||
/* Write the status byte */
|
/* Write the status byte */
|
||||||
if (t->status == GST_THREAD_PENDING) write_byte(0);
|
write_byte(t->status);
|
||||||
else if (t->status == GST_THREAD_ALIVE) write_byte(1);
|
|
||||||
else write_byte(2);
|
|
||||||
/* Write number of stack frames */
|
/* Write number of stack frames */
|
||||||
write_u32(framecount);
|
write_u32(framecount);
|
||||||
/* Write stack frames */
|
/* Write stack frames */
|
||||||
@ -689,19 +691,17 @@ const char *gst_serialize_impl(
|
|||||||
|
|
||||||
case GST_FUNCTION: /* Function */
|
case GST_FUNCTION: /* Function */
|
||||||
{
|
{
|
||||||
|
GstValue pv, ev, dv;
|
||||||
GstFunction *fn = x.data.function;
|
GstFunction *fn = x.data.function;
|
||||||
write_byte(214);
|
write_byte(214);
|
||||||
if (fn->parent)
|
pv = fn->parent ? gst_wrap_function(fn->parent) : gst_wrap_nil();
|
||||||
err = gst_serialize_impl(vm, buffer, visited, nextId, gst_wrap_function(fn->parent));
|
dv = gst_wrap_funcdef(fn->def);
|
||||||
else
|
ev = fn->env ? gst_wrap_funcenv(fn->env) : gst_wrap_nil();
|
||||||
err = gst_serialize_impl(vm, buffer, visited, nextId, gst_wrap_nil());
|
err = gst_serialize_impl(vm, buffer, visited, nextId, pv);
|
||||||
if (err != NULL) return err;
|
if (err != NULL) return err;
|
||||||
err = gst_serialize_impl(vm, buffer, visited, nextId, gst_wrap_funcdef(fn->def));
|
err = gst_serialize_impl(vm, buffer, visited, nextId, dv);
|
||||||
if (err != NULL) return err;
|
if (err != NULL) return err;
|
||||||
if (fn->env == NULL)
|
err = gst_serialize_impl(vm, buffer, visited, nextId, ev);
|
||||||
err = gst_serialize_impl(vm, buffer, visited, nextId, gst_wrap_nil());
|
|
||||||
else
|
|
||||||
err = gst_serialize_impl(vm, buffer, visited, nextId, gst_wrap_funcenv(fn->env));
|
|
||||||
if (err != NULL) return err;
|
if (err != NULL) return err;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -648,7 +648,10 @@ int gst_stl_funcenv(Gst *vm) {
|
|||||||
GstFunction *fn;
|
GstFunction *fn;
|
||||||
if (!gst_check_function(vm, 0, &fn))
|
if (!gst_check_function(vm, 0, &fn))
|
||||||
gst_c_throwc(vm, "expected function");
|
gst_c_throwc(vm, "expected function");
|
||||||
|
if (fn->env)
|
||||||
gst_c_return(vm, gst_wrap_funcenv(fn->env));
|
gst_c_return(vm, gst_wrap_funcenv(fn->env));
|
||||||
|
else
|
||||||
|
return GST_RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int gst_stl_funcdef(Gst *vm) {
|
int gst_stl_funcdef(Gst *vm) {
|
||||||
|
25
core/vm.c
25
core/vm.c
@ -161,16 +161,6 @@ int gst_continue(Gst *vm) {
|
|||||||
{
|
{
|
||||||
GstFunction *fn;
|
GstFunction *fn;
|
||||||
v1 = gst_frame_callee(stack);
|
v1 = gst_frame_callee(stack);
|
||||||
if (v1.type != GST_FUNCTION)
|
|
||||||
gst_error(vm, GST_EXPECTED_FUNCTION);
|
|
||||||
if (gst_frame_env(stack) == NULL) {
|
|
||||||
gst_frame_env(stack) = gst_alloc(vm, sizeof(GstFuncEnv));
|
|
||||||
gst_frame_env(stack)->thread = vm->thread;
|
|
||||||
gst_frame_env(stack)->stackOffset = vm->thread->count;
|
|
||||||
gst_frame_env(stack)->values = NULL;
|
|
||||||
}
|
|
||||||
if (pc[2] > v1.data.function->def->literalsLen)
|
|
||||||
gst_error(vm, GST_NO_UPVALUE);
|
|
||||||
temp = v1.data.function->def->literals[pc[2]];
|
temp = v1.data.function->def->literals[pc[2]];
|
||||||
if (temp.type != GST_FUNCDEF)
|
if (temp.type != GST_FUNCDEF)
|
||||||
gst_error(vm, "cannot create closure from non-funcdef");
|
gst_error(vm, "cannot create closure from non-funcdef");
|
||||||
@ -180,7 +170,20 @@ int gst_continue(Gst *vm) {
|
|||||||
fn->parent = v1.data.function;
|
fn->parent = v1.data.function;
|
||||||
else
|
else
|
||||||
fn->parent = NULL;
|
fn->parent = NULL;
|
||||||
|
if (v1.type != GST_FUNCTION)
|
||||||
|
gst_error(vm, GST_EXPECTED_FUNCTION);
|
||||||
|
if (gst_frame_env(stack) == NULL && (fn->def->flags & GST_FUNCDEF_FLAG_NEEDSENV)) {
|
||||||
|
gst_frame_env(stack) = gst_alloc(vm, sizeof(GstFuncEnv));
|
||||||
|
gst_frame_env(stack)->thread = vm->thread;
|
||||||
|
gst_frame_env(stack)->stackOffset = vm->thread->count;
|
||||||
|
gst_frame_env(stack)->values = NULL;
|
||||||
|
}
|
||||||
|
if (pc[2] > v1.data.function->def->literalsLen)
|
||||||
|
gst_error(vm, GST_NO_UPVALUE);
|
||||||
|
if (fn->def->flags & GST_FUNCDEF_FLAG_NEEDSENV)
|
||||||
fn->env = gst_frame_env(stack);
|
fn->env = gst_frame_env(stack);
|
||||||
|
else
|
||||||
|
fn->env = NULL;
|
||||||
temp.type = GST_FUNCTION;
|
temp.type = GST_FUNCTION;
|
||||||
temp.data.function = fn;
|
temp.data.function = fn;
|
||||||
stack[pc[1]] = temp;
|
stack[pc[1]] = temp;
|
||||||
@ -365,6 +368,8 @@ int gst_continue(Gst *vm) {
|
|||||||
temp.data.thread->status = GST_THREAD_ALIVE;
|
temp.data.thread->status = GST_THREAD_ALIVE;
|
||||||
vm->thread = temp.data.thread;
|
vm->thread = temp.data.thread;
|
||||||
stack = gst_thread_stack(temp.data.thread);
|
stack = gst_thread_stack(temp.data.thread);
|
||||||
|
if (gst_frame_callee(stack).type != GST_FUNCTION)
|
||||||
|
goto vm_return;
|
||||||
stack[gst_frame_ret(stack)] = v1;
|
stack[gst_frame_ret(stack)] = v1;
|
||||||
pc = gst_frame_pc(stack);
|
pc = gst_frame_pc(stack);
|
||||||
continue;
|
continue;
|
||||||
|
18
libs/serialize.gst
Normal file
18
libs/serialize.gst
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
(export! "scheck" (fn [x]
|
||||||
|
(: dat (serialize x))
|
||||||
|
(: deser (deserialize dat))
|
||||||
|
(print (debugp deser))
|
||||||
|
deser
|
||||||
|
))
|
||||||
|
|
||||||
|
(scheck 1)
|
||||||
|
(scheck true)
|
||||||
|
(scheck nil)
|
||||||
|
(scheck "asdasdasd")
|
||||||
|
(scheck (struct 1 2 3 4))
|
||||||
|
(scheck (tuple 1 2 3))
|
||||||
|
(scheck 123412.12)
|
||||||
|
(scheck (funcdef (fn [] 1)))
|
||||||
|
(scheck (funcenv (fn [] 1)))
|
||||||
|
(scheck (funcenv ((fn [a] (fn [] a)) 1)))
|
||||||
|
(scheck (fn [] 1))
|
Loading…
x
Reference in New Issue
Block a user