mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-31 15:43:01 +00:00 
			
		
		
		
	Add option to marshal values without cycle detection.
This commit is contained in:
		| @@ -37,6 +37,7 @@ typedef struct { | |||||||
|     JanetFuncEnv **seen_envs; |     JanetFuncEnv **seen_envs; | ||||||
|     JanetFuncDef **seen_defs; |     JanetFuncDef **seen_defs; | ||||||
|     int32_t nextid; |     int32_t nextid; | ||||||
|  |     int maybe_cycles; | ||||||
| } MarshalState; | } MarshalState; | ||||||
|  |  | ||||||
| /* Lead bytes in marshaling protocol */ | /* Lead bytes in marshaling protocol */ | ||||||
| @@ -364,13 +365,15 @@ void janet_marshal_janet(JanetMarshalContext *ctx, Janet x) { | |||||||
|  |  | ||||||
| void janet_marshal_abstract(JanetMarshalContext *ctx, void *abstract) { | void janet_marshal_abstract(JanetMarshalContext *ctx, void *abstract) { | ||||||
|     MarshalState *st = (MarshalState *)(ctx->m_state); |     MarshalState *st = (MarshalState *)(ctx->m_state); | ||||||
|     janet_table_put(&st->seen, |     if (st->maybe_cycles) { | ||||||
|                     janet_wrap_abstract(abstract), |         janet_table_put(&st->seen, | ||||||
|                     janet_wrap_integer(st->nextid++)); |                         janet_wrap_abstract(abstract), | ||||||
|  |                         janet_wrap_integer(st->nextid++)); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| #define MARK_SEEN() \ | #define MARK_SEEN() \ | ||||||
|     janet_table_put(&st->seen, x, janet_wrap_integer(st->nextid++)) |     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) { | static void marshal_one_abstract(MarshalState *st, Janet x, int flags) { | ||||||
|     void *abstract = janet_unwrap_abstract(x); |     void *abstract = janet_unwrap_abstract(x); | ||||||
| @@ -428,11 +431,14 @@ static void marshal_one(MarshalState *st, Janet x, int flags) { | |||||||
|  |  | ||||||
|     /* Check reference and registry value */ |     /* Check reference and registry value */ | ||||||
|     { |     { | ||||||
|         Janet check = janet_table_get(&st->seen, x); |         Janet check; | ||||||
|         if (janet_checkint(check)) { |         if (st->maybe_cycles) { | ||||||
|             pushbyte(st, LB_REFERENCE); |             check = janet_table_get(&st->seen, x); | ||||||
|             pushint(st, janet_unwrap_integer(check)); |             if (janet_checkint(check)) { | ||||||
|             return; |                 pushbyte(st, LB_REFERENCE); | ||||||
|  |                 pushint(st, janet_unwrap_integer(check)); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|         if (st->rreg) { |         if (st->rreg) { | ||||||
|             check = janet_table_get(st->rreg, x); |             check = janet_table_get(st->rreg, x); | ||||||
| @@ -613,6 +619,7 @@ void janet_marshal( | |||||||
|     st.seen_defs = NULL; |     st.seen_defs = NULL; | ||||||
|     st.seen_envs = NULL; |     st.seen_envs = NULL; | ||||||
|     st.rreg = rreg; |     st.rreg = rreg; | ||||||
|  |     st.maybe_cycles = !(flags & JANET_MARSHAL_NO_CYCLES); | ||||||
|     janet_table_init(&st.seen, 0); |     janet_table_init(&st.seen, 0); | ||||||
|     marshal_one(&st, x, flags); |     marshal_one(&st, x, flags); | ||||||
|     janet_table_deinit(&st.seen); |     janet_table_deinit(&st.seen); | ||||||
| @@ -1471,16 +1478,17 @@ JANET_CORE_FN(cfun_env_lookup, | |||||||
| } | } | ||||||
|  |  | ||||||
| JANET_CORE_FN(cfun_marshal, | JANET_CORE_FN(cfun_marshal, | ||||||
|               "(marshal x &opt reverse-lookup buffer)", |               "(marshal x &opt reverse-lookup buffer no-cycles)", | ||||||
|               "Marshal a value into a buffer and return the buffer. The buffer " |               "Marshal a value into a buffer and return the buffer. The buffer " | ||||||
|               "can then later be unmarshalled to reconstruct the initial value. " |               "can then later be unmarshalled to reconstruct the initial value. " | ||||||
|               "Optionally, one can pass in a reverse lookup table to not marshal " |               "Optionally, one can pass in a reverse lookup table to not marshal " | ||||||
|               "aliased values that are found in the table. Then a forward " |               "aliased values that are found in the table. Then a forward " | ||||||
|               "lookup table can be used to recover the original value when " |               "lookup table can be used to recover the original value when " | ||||||
|               "unmarshalling.") { |               "unmarshalling.") { | ||||||
|     janet_arity(argc, 1, 3); |     janet_arity(argc, 1, 4); | ||||||
|     JanetBuffer *buffer; |     JanetBuffer *buffer; | ||||||
|     JanetTable *rreg = NULL; |     JanetTable *rreg = NULL; | ||||||
|  |     uint32_t flags = 0; | ||||||
|     if (argc > 1) { |     if (argc > 1) { | ||||||
|         rreg = janet_gettable(argv, 1); |         rreg = janet_gettable(argv, 1); | ||||||
|     } |     } | ||||||
| @@ -1489,7 +1497,10 @@ JANET_CORE_FN(cfun_marshal, | |||||||
|     } else { |     } else { | ||||||
|         buffer = janet_buffer(10); |         buffer = janet_buffer(10); | ||||||
|     } |     } | ||||||
|     janet_marshal(buffer, argv[0], rreg, 0); |     if (argc > 3 && janet_truthy(argv[3])) { | ||||||
|  |         flags |= JANET_MARSHAL_NO_CYCLES; | ||||||
|  |     } | ||||||
|  |     janet_marshal(buffer, argv[0], rreg, flags); | ||||||
|     return janet_wrap_buffer(buffer); |     return janet_wrap_buffer(buffer); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1671,6 +1671,7 @@ JANET_API JanetModule janet_native(const char *name, JanetString *error); | |||||||
|  |  | ||||||
| /* Marshaling */ | /* Marshaling */ | ||||||
| #define JANET_MARSHAL_UNSAFE 0x20000 | #define JANET_MARSHAL_UNSAFE 0x20000 | ||||||
|  | #define JANET_MARSHAL_NO_CYCLES 0x40000 | ||||||
|  |  | ||||||
| JANET_API void janet_marshal( | JANET_API void janet_marshal( | ||||||
|     JanetBuffer *buf, |     JanetBuffer *buf, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Calvin Rose
					Calvin Rose