diff --git a/src/core/ev.c b/src/core/ev.c index 01080d02..abe3940b 100644 --- a/src/core/ev.c +++ b/src/core/ev.c @@ -405,7 +405,7 @@ static void janet_stream_marshal(void *p, JanetMarshalContext *ctx) { #ifdef JANET_WINDOWS /* TODO - ref counting to avoid situation where a handle is closed or GCed * while in transit, and it's value gets reused. DuplicateHandle does not work - * for network sockets, and in general for winsock it is better to nipt duplicate + * for network sockets, and in general for winsock it is better to not duplicate * unless there is a need to. */ HANDLE duph = INVALID_HANDLE_VALUE; if (s->flags & JANET_STREAM_SOCKET) { diff --git a/src/core/marsh.c b/src/core/marsh.c index 2d58844a..f81e91c0 100644 --- a/src/core/marsh.c +++ b/src/core/marsh.c @@ -246,6 +246,7 @@ static void marshal_one_def(MarshalState *st, JanetFuncDef *def, int flags) { } /* Add to lookup */ janet_v_push(st->seen_defs, def); + pushint(st, def->flags); pushint(st, def->slotcount); pushint(st, def->arity); @@ -266,14 +267,14 @@ static void marshal_one_def(MarshalState *st, JanetFuncDef *def, int flags) { /* marshal constants */ for (int32_t i = 0; i < def->constants_length; i++) - marshal_one(st, def->constants[i], flags); + marshal_one(st, def->constants[i], flags + 1); /* Marshal symbol map, if needed */ for (int32_t i = 0; i < def->symbolmap_length; i++) { pushint(st, (int32_t) def->symbolmap[i].birth_pc); pushint(st, (int32_t) def->symbolmap[i].death_pc); pushint(st, (int32_t) def->symbolmap[i].slot_index); - marshal_one(st, janet_wrap_symbol(def->symbolmap[i].symbol), flags); + marshal_one(st, janet_wrap_symbol(def->symbolmap[i].symbol), flags + 1); } /* marshal the bytecode */ @@ -387,18 +388,27 @@ void janet_marshal_janet(JanetMarshalContext *ctx, Janet x) { marshal_one(st, x, ctx->flags + 1); } +#ifdef JANET_MARSHAL_DEBUG +#define MARK_SEEN() \ + do { if (st->maybe_cycles) { \ + Janet _check = janet_table_get(&st->seen, x); \ + if (!janet_checktype(_check, JANET_NIL)) janet_eprintf("double MARK_SEEN on %v\n", x); \ + janet_eprintf("made reference %d (%t) to %v\n", st->nextid, x, x); \ + janet_table_put(&st->seen, x, janet_wrap_integer(st->nextid++)); \ + } } while (0) +#else +#define MARK_SEEN() \ + do { if (st->maybe_cycles) { \ + janet_table_put(&st->seen, x, janet_wrap_integer(st->nextid++)); \ + } } while (0) +#endif + void janet_marshal_abstract(JanetMarshalContext *ctx, void *abstract) { MarshalState *st = (MarshalState *)(ctx->m_state); - if (st->maybe_cycles) { - janet_table_put(&st->seen, - janet_wrap_abstract(abstract), - janet_wrap_integer(st->nextid++)); - } + Janet x = janet_wrap_abstract(abstract); + MARK_SEEN(); } -#define MARK_SEEN() \ - do { if (st->maybe_cycles) janet_table_put(&st->seen, x, janet_wrap_integer(st->nextid++)); } while (0) - static void marshal_one_abstract(MarshalState *st, Janet x, int flags) { void *abstract = janet_unwrap_abstract(x); #ifdef JANET_EV @@ -420,9 +430,8 @@ static void marshal_one_abstract(MarshalState *st, Janet x, int flags) { if (at->marshal) { pushbyte(st, LB_ABSTRACT); marshal_one(st, janet_csymbolv(at->name), flags + 1); - JanetMarshalContext context = {st, NULL, flags, NULL, at}; + JanetMarshalContext context = {st, NULL, flags + 1, NULL, at}; at->marshal(abstract, &context); - MARK_SEEN(); } else { janet_panicf("cannot marshal %p", x); } @@ -738,9 +747,22 @@ static uint64_t read64(UnmarshalState *st, const uint8_t **atdata) { return ret; } +#ifdef JANET_MARSHAL_DEBUG +static void dump_reference_table(UnmarshalState *st) { + for (int32_t i = 0; i < janet_v_count(st->lookup); i++) { + janet_eprintf(" reference %d (%t) = %v\n", i, st->lookup[i], st->lookup[i]); + } +} +#endif + /* Assert a janet type */ -static void janet_asserttype(Janet x, JanetType t) { +static void janet_asserttype(Janet x, JanetType t, UnmarshalState *st) { if (!janet_checktype(x, t)) { +#ifdef JANET_MARSHAL_DEBUG + dump_reference_table(st); +#else + (void) st; +#endif janet_panicf("expected type %T, got %v", 1 << t, x); } } @@ -792,7 +814,7 @@ static const uint8_t *unmarshal_one_env( Janet fiberv; /* On stack variant */ data = unmarshal_one(st, data, &fiberv, flags); - janet_asserttype(fiberv, JANET_FIBER); + janet_asserttype(fiberv, JANET_FIBER, st); env->as.fiber = janet_unwrap_fiber(fiberv); /* Negative offset indicates untrusted input */ env->offset = -offset; @@ -890,13 +912,13 @@ static const uint8_t *unmarshal_one_def( if (def->flags & JANET_FUNCDEF_FLAG_HASNAME) { Janet x; data = unmarshal_one(st, data, &x, flags + 1); - janet_asserttype(x, JANET_STRING); + janet_asserttype(x, JANET_STRING, st); def->name = janet_unwrap_string(x); } if (def->flags & JANET_FUNCDEF_FLAG_HASSOURCE) { Janet x; data = unmarshal_one(st, data, &x, flags + 1); - janet_asserttype(x, JANET_STRING); + janet_asserttype(x, JANET_STRING, st); def->source = janet_unwrap_string(x); } @@ -926,8 +948,9 @@ static const uint8_t *unmarshal_one_def( def->symbolmap[i].slot_index = (uint32_t) readint(st, &data); Janet value; data = unmarshal_one(st, data, &value, flags + 1); - if (!janet_checktype(value, JANET_SYMBOL)) - janet_panicf("expected symbol in unmarshal, got %v", value); + if (!janet_checktype(value, JANET_SYMBOL)) { + janet_panicf("corrupted symbolmap when unmarshalling debug info, got %v", value); + } def->symbolmap[i].symbol = janet_unwrap_symbol(value); } def->symbolmap_length = (uint32_t) symbolmap_length; @@ -1076,7 +1099,7 @@ static const uint8_t *unmarshal_one_fiber( /* Get function */ Janet funcv; data = unmarshal_one(st, data, &funcv, flags + 1); - janet_asserttype(funcv, JANET_FUNCTION); + janet_asserttype(funcv, JANET_FUNCTION, st); func = janet_unwrap_function(funcv); def = func->def; @@ -1122,7 +1145,7 @@ static const uint8_t *unmarshal_one_fiber( Janet envv; fiber_flags &= ~JANET_FIBER_FLAG_HASENV; data = unmarshal_one(st, data, &envv, flags + 1); - janet_asserttype(envv, JANET_TABLE); + janet_asserttype(envv, JANET_TABLE, st); fiber_env = janet_unwrap_table(envv); } @@ -1131,7 +1154,7 @@ static const uint8_t *unmarshal_one_fiber( Janet fiberv; fiber_flags &= ~JANET_FIBER_FLAG_HASCHILD; data = unmarshal_one(st, data, &fiberv, flags + 1); - janet_asserttype(fiberv, JANET_FIBER); + janet_asserttype(fiberv, JANET_FIBER, st); fiber->child = janet_unwrap_fiber(fiberv); } @@ -1229,11 +1252,12 @@ static const uint8_t *unmarshal_one_abstract(UnmarshalState *st, const uint8_t * if (at == NULL) janet_panic("unknown abstract type"); if (at->unmarshal) { JanetMarshalContext context = {NULL, st, flags, data, at}; - *out = janet_wrap_abstract(at->unmarshal(&context)); + void *abst = at->unmarshal(&context); + janet_assert(abst != NULL, "null pointer abstract"); + *out = janet_wrap_abstract(abst); if (context.at != NULL) { janet_panic("janet_unmarshal_abstract not called"); } - janet_v_push(st->lookup, *out); return context.data; } janet_panic("invalid abstract type - no unmarshal function pointer"); @@ -1331,7 +1355,7 @@ static const uint8_t *unmarshal_one( } case LB_FIBER: { JanetFiber *fiber; - data = unmarshal_one_fiber(st, data + 1, &fiber, flags); + data = unmarshal_one_fiber(st, data + 1, &fiber, flags + 1); *out = janet_wrap_fiber(fiber); return data; } @@ -1346,6 +1370,9 @@ static const uint8_t *unmarshal_one( func = janet_gcalloc(JANET_MEMORY_FUNCTION, sizeof(JanetFunction) + len * sizeof(JanetFuncEnv)); func->def = NULL; + for (int32_t i = 0; i < len; i++) { + func->envs[i] = NULL; + } *out = janet_wrap_function(func); janet_v_push(st->lookup, *out); data = unmarshal_one_def(st, data, &def, flags + 1); @@ -1399,7 +1426,7 @@ static const uint8_t *unmarshal_one( if (lead == LB_STRUCT_PROTO) { Janet proto; data = unmarshal_one(st, data, &proto, flags + 1); - janet_asserttype(proto, JANET_STRUCT); + janet_asserttype(proto, JANET_STRUCT, st); janet_struct_proto(struct_) = janet_unwrap_struct(proto); } for (int32_t i = 0; i < len; i++) { @@ -1422,7 +1449,7 @@ static const uint8_t *unmarshal_one( if (lead == LB_TABLE_PROTO) { Janet proto; data = unmarshal_one(st, data, &proto, flags + 1); - janet_asserttype(proto, JANET_TABLE); + janet_asserttype(proto, JANET_TABLE, st); t->proto = janet_unwrap_table(proto); } for (int32_t i = 0; i < len; i++) { diff --git a/src/core/pp.c b/src/core/pp.c index 9c897a0b..d8409c2c 100644 --- a/src/core/pp.c +++ b/src/core/pp.c @@ -250,6 +250,10 @@ void janet_to_string_b(JanetBuffer *buffer, Janet x) { case JANET_FUNCTION: { JanetFunction *fun = janet_unwrap_function(x); JanetFuncDef *def = fun->def; + if (def == NULL) { + janet_buffer_push_cstring(buffer, ""); + break; + } if (def->name) { const uint8_t *n = def->name; janet_buffer_push_cstring(buffer, "