1
0
mirror of https://github.com/janet-lang/janet synced 2025-05-01 15:04:15 +00:00

Add option to marshal values without cycle detection.

This commit is contained in:
Calvin Rose 2022-08-26 11:20:02 -05:00
parent 0817e627ee
commit a575f5df36
2 changed files with 24 additions and 12 deletions

View File

@ -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);
if (st->maybe_cycles) {
janet_table_put(&st->seen, janet_table_put(&st->seen,
janet_wrap_abstract(abstract), janet_wrap_abstract(abstract),
janet_wrap_integer(st->nextid++)); 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,12 +431,15 @@ 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 (st->maybe_cycles) {
check = janet_table_get(&st->seen, x);
if (janet_checkint(check)) { if (janet_checkint(check)) {
pushbyte(st, LB_REFERENCE); pushbyte(st, LB_REFERENCE);
pushint(st, janet_unwrap_integer(check)); pushint(st, janet_unwrap_integer(check));
return; return;
} }
}
if (st->rreg) { if (st->rreg) {
check = janet_table_get(st->rreg, x); check = janet_table_get(st->rreg, x);
if (janet_checktype(check, JANET_SYMBOL)) { if (janet_checktype(check, JANET_SYMBOL)) {
@ -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);
} }

View File

@ -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,