mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-31 07:33:01 +00:00 
			
		
		
		
	More complete fix with some debugging tools.
This commit is contained in:
		| @@ -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) { | ||||
|   | ||||
| @@ -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++) { | ||||
|   | ||||
| @@ -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, "<incomplete function>"); | ||||
|                 break; | ||||
|             } | ||||
|             if (def->name) { | ||||
|                 const uint8_t *n = def->name; | ||||
|                 janet_buffer_push_cstring(buffer, "<function "); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Calvin Rose
					Calvin Rose