This commit is contained in:
2026-01-30 17:02:50 -06:00
parent 24ecff3f1c
commit a49b94e0a1
4 changed files with 1059 additions and 1418 deletions

View File

@@ -59,10 +59,10 @@ static void wota_stack_free(WotaEncodeContext *enc)
}
}
static JSValue apply_replacer(WotaEncodeContext *enc, JSValueConst holder, JSAtom key, JSValueConst val)
static JSValue apply_replacer(WotaEncodeContext *enc, JSValueConst holder, JSValue key, JSValueConst val)
{
if (JS_IsNull(enc->replacer)) return JS_DupValue(enc->ctx, val);
JSValue key_val = (key == JS_ATOM_NULL) ? JS_NULL : JS_AtomToValue(enc->ctx, key);
JSValue key_val = JS_IsNull(key) ? JS_NULL : JS_DupValue(enc->ctx, key);
JSValue args[2] = { key_val, JS_DupValue(enc->ctx, val) };
JSValue result = JS_Call(enc->ctx, enc->replacer, holder, 2, args);
JS_FreeValue(enc->ctx, args[0]);
@@ -71,51 +71,51 @@ static JSValue apply_replacer(WotaEncodeContext *enc, JSValueConst holder, JSAto
return result;
}
static void wota_encode_value(WotaEncodeContext *enc, JSValueConst val, JSValueConst holder, JSAtom key);
static void wota_encode_value(WotaEncodeContext *enc, JSValueConst val, JSValueConst holder, JSValue key);
static void encode_object_properties(WotaEncodeContext *enc, JSValueConst val, JSValueConst holder)
{
JSContext *ctx = enc->ctx;
JSPropertyEnum *ptab;
JSValue *keys;
uint32_t plen;
if (JS_GetOwnPropertyNames(ctx, &ptab, &plen, val, JS_GPN_ENUM_ONLY | JS_GPN_STRING_MASK) < 0) {
if (JS_GetOwnPropertyNames(ctx, &keys, &plen, val) < 0) {
wota_write_sym(&enc->wb, WOTA_NULL);
return;
}
uint32_t non_function_count = 0;
JSValue props[plen];
JSAtom atoms[plen];
JSValue kept_keys[plen];
for (uint32_t i = 0; i < plen; i++) {
JSValue prop_val = JS_GetProperty(ctx, val, ptab[i].atom);
JSValue prop_val = JS_GetProperty(ctx, val, keys[i]);
if (!JS_IsFunction(prop_val)) {
atoms[non_function_count] = ptab[i].atom;
kept_keys[non_function_count] = keys[i];
props[non_function_count++] = prop_val;
} else
} else {
JS_FreeValue(ctx, prop_val);
JS_FreeValue(ctx, keys[i]);
}
}
wota_write_record(&enc->wb, non_function_count);
for (uint32_t i = 0; i < non_function_count; i++) {
size_t plen;
const char *prop_name = JS_AtomToCStringLen(ctx, &plen, atoms[i]);
size_t klen;
const char *prop_name = JS_ToCStringLen(ctx, &klen, kept_keys[i]);
JSValue prop_val = props[i];
wota_write_text_len(&enc->wb, prop_name, plen);
wota_encode_value(enc, prop_val, val, atoms[i]);
wota_write_text_len(&enc->wb, prop_name ? prop_name : "", prop_name ? klen : 0);
wota_encode_value(enc, prop_val, val, kept_keys[i]);
JS_FreeCString(ctx, prop_name);
JS_FreeValue(ctx, prop_val);
JS_FreeValue(ctx, kept_keys[i]);
}
for (int i = 0; i < plen; i++)
JS_FreeAtom(ctx, ptab[i].atom);
js_free(ctx, ptab);
js_free(ctx, keys);
}
static void wota_encode_value(WotaEncodeContext *enc, JSValueConst val, JSValueConst holder, JSAtom key)
static void wota_encode_value(WotaEncodeContext *enc, JSValueConst val, JSValueConst holder, JSValue key)
{
JSContext *ctx = enc->ctx;
JSValue replaced;
if (!JS_IsNull(enc->replacer) && key != JS_ATOM_NULL)
if (!JS_IsNull(enc->replacer) && !JS_IsNull(key))
replaced = apply_replacer(enc, holder, key, val);
else
replaced = JS_DupValue(enc->ctx, val);
@@ -176,9 +176,8 @@ static void wota_encode_value(WotaEncodeContext *enc, JSValueConst val, JSValueC
wota_write_array(&enc->wb, arr_len);
for (int64_t i = 0; i < arr_len; i++) {
JSValue elem_val = JS_GetPropertyUint32(ctx, replaced, i);
JSAtom idx_atom = JS_NewAtomUInt32(ctx, (uint32_t)i);
wota_encode_value(enc, elem_val, replaced, idx_atom);
JS_FreeAtom(ctx, idx_atom);
/* Use int index as key placeholder */
wota_encode_value(enc, elem_val, replaced, JS_NewInt32(ctx, (int32_t)i));
JS_FreeValue(ctx, elem_val);
}
wota_stack_pop(enc);
@@ -189,7 +188,7 @@ static void wota_encode_value(WotaEncodeContext *enc, JSValueConst val, JSValueC
JSValue adata = JS_NULL;
if (!JS_IsNull(adata)) {
wota_write_sym(&enc->wb, WOTA_PRIVATE);
wota_encode_value(enc, adata, replaced, JS_ATOM_NULL);
wota_encode_value(enc, adata, replaced, JS_NULL);
JS_FreeValue(ctx, adata);
break;
}
@@ -223,7 +222,7 @@ static void wota_encode_value(WotaEncodeContext *enc, JSValueConst val, JSValueC
JS_FreeValue(ctx, replaced);
}
static char *decode_wota_value(JSContext *ctx, char *data_ptr, JSValue *out_val, JSValue holder, JSAtom key, JSValue reviver)
static char *decode_wota_value(JSContext *ctx, char *data_ptr, JSValue *out_val, JSValue holder, JSValue key, JSValue reviver)
{
uint64_t first_word = *(uint64_t *)data_ptr;
int type = (int)(first_word & 0xffU);
@@ -245,7 +244,7 @@ static char *decode_wota_value(JSContext *ctx, char *data_ptr, JSValue *out_val,
data_ptr = wota_read_sym(&scode, data_ptr);
if (scode == WOTA_PRIVATE) {
JSValue inner = JS_NULL;
data_ptr = decode_wota_value(ctx, data_ptr, &inner, holder, JS_ATOM_NULL, reviver);
data_ptr = decode_wota_value(ctx, data_ptr, &inner, holder, JS_NULL, reviver);
JSValue obj = JS_NewObject(ctx);
cell_rt *crt = JS_GetContextOpaque(ctx);
// JS_SetProperty(ctx, obj, crt->actor_sym, inner);
@@ -277,10 +276,9 @@ static char *decode_wota_value(JSContext *ctx, char *data_ptr, JSValue *out_val,
JSValue arr = JS_NewArrayLen(ctx, c);
for (long long i = 0; i < c; i++) {
JSValue elem_val = JS_NULL;
JSAtom idx_atom = JS_NewAtomUInt32(ctx, (uint32_t)i);
data_ptr = decode_wota_value(ctx, data_ptr, &elem_val, arr, idx_atom, reviver);
JSValue idx_key = JS_NewInt32(ctx, (int32_t)i);
data_ptr = decode_wota_value(ctx, data_ptr, &elem_val, arr, idx_key, reviver);
JS_SetPropertyUint32(ctx, arr, i, elem_val);
JS_FreeAtom(ctx, idx_atom);
}
*out_val = arr;
break;
@@ -294,11 +292,11 @@ static char *decode_wota_value(JSContext *ctx, char *data_ptr, JSValue *out_val,
size_t key_len;
data_ptr = wota_read_text_len(&key_len, &tkey, data_ptr);
if (!tkey) continue; // invalid key
JSAtom prop_key = JS_NewAtomLen(ctx, tkey, key_len);
JSValue prop_key = JS_NewStringLen(ctx, tkey, key_len);
JSValue sub_val = JS_NULL;
data_ptr = decode_wota_value(ctx, data_ptr, &sub_val, obj, prop_key, reviver);
JS_SetProperty(ctx, obj, prop_key, sub_val);
JS_FreeAtom(ctx, prop_key);
JS_FreeValue(ctx, prop_key);
free(tkey);
}
*out_val = obj;
@@ -310,7 +308,7 @@ static char *decode_wota_value(JSContext *ctx, char *data_ptr, JSValue *out_val,
break;
}
if (!JS_IsNull(reviver)) {
JSValue key_val = (key == JS_ATOM_NULL) ? JS_NULL : JS_AtomToValue(ctx, key);
JSValue key_val = JS_IsNull(key) ? JS_NULL : JS_DupValue(ctx, key);
JSValue args[2] = { key_val, JS_DupValue(ctx, *out_val) };
JSValue revived = JS_Call(ctx, reviver, holder, 2, args);
JS_FreeValue(ctx, args[0]);
@@ -333,7 +331,7 @@ void *value2wota(JSContext *ctx, JSValue v, JSValue replacer, size_t *bytes)
enc->cycle = 0;
enc->replacer = replacer;
wota_buffer_init(&enc->wb, 16);
wota_encode_value(enc, v, JS_NULL, JS_ATOM_NULL);
wota_encode_value(enc, v, JS_NULL, JS_NULL);
if (enc->cycle) {
wota_stack_free(enc);
wota_buffer_free(&enc->wb);
@@ -350,7 +348,7 @@ JSValue wota2value(JSContext *ctx, void *wota)
{
JSValue result = JS_NULL;
JSValue holder = JS_NewObject(ctx);
decode_wota_value(ctx, wota, &result, holder, JS_ATOM_NULL, JS_NULL);
decode_wota_value(ctx, wota, &result, holder, JS_NULL, JS_NULL);
JS_FreeValue(ctx, holder);
return result;
}
@@ -376,9 +374,9 @@ static JSValue js_wota_decode(JSContext *ctx, JSValueConst this_val, int argc, J
char *data_ptr = (char *)buf;
JSValue result = JS_NULL;
JSValue holder = JS_NewObject(ctx);
JSAtom empty_atom = JS_NewAtom(ctx, "");
decode_wota_value(ctx, data_ptr, &result, holder, empty_atom, reviver);
JS_FreeAtom(ctx, empty_atom);
JSValue empty_key = JS_NewString(ctx, "");
decode_wota_value(ctx, data_ptr, &result, holder, empty_key, reviver);
JS_FreeValue(ctx, empty_key);
JS_FreeValue(ctx, holder);
return result;
}

View File

@@ -69,7 +69,6 @@ DEF(invalid, 1, 0, 0, none) /* never emitted */
DEF( push_i32, 5, 0, 1, i32)
DEF( push_const, 5, 0, 1, const)
DEF( fclosure, 5, 0, 1, const) /* must follow push_const */
DEF(push_atom_value, 5, 0, 1, atom)
DEF( null, 1, 0, 1, none)
DEF( push_this, 1, 0, 1, none) /* only used at the start of a function */
DEF( push_false, 1, 0, 1, none)

File diff suppressed because it is too large Load Diff