Merge branch 'bench_endoders'

This commit is contained in:
2026-02-17 12:36:15 -06:00
4 changed files with 520 additions and 59 deletions

View File

@@ -11308,38 +11308,41 @@ static int nota_get_arr_len (JSContext *ctx, JSValue arr) {
return (int)len;
}
typedef struct NotaVisitedNode {
JSGCRef ref;
struct NotaVisitedNode *next;
} NotaVisitedNode;
typedef struct NotaEncodeContext {
JSContext *ctx;
JSGCRef *visitedStack_ref; /* pointer to GC-rooted ref */
NotaVisitedNode *visited_list;
NotaBuffer nb;
int cycle;
JSGCRef *replacer_ref; /* pointer to GC-rooted ref */
} NotaEncodeContext;
static void nota_stack_push (NotaEncodeContext *enc, JSValueConst val) {
JSContext *ctx = enc->ctx;
int len = nota_get_arr_len (ctx, enc->visitedStack_ref->val);
JS_SetPropertyNumber (ctx, enc->visitedStack_ref->val, len, JS_DupValue (ctx, val));
NotaVisitedNode *node = (NotaVisitedNode *)sys_malloc (sizeof (NotaVisitedNode));
JS_PushGCRef (enc->ctx, &node->ref);
node->ref.val = JS_DupValue (enc->ctx, val);
node->next = enc->visited_list;
enc->visited_list = node;
}
static void nota_stack_pop (NotaEncodeContext *enc) {
JSContext *ctx = enc->ctx;
int len = nota_get_arr_len (ctx, enc->visitedStack_ref->val);
JS_SetPropertyStr (ctx, enc->visitedStack_ref->val, "length", JS_NewUint32 (ctx, len - 1));
NotaVisitedNode *node = enc->visited_list;
enc->visited_list = node->next;
JS_FreeValue (enc->ctx, node->ref.val);
JS_PopGCRef (enc->ctx, &node->ref);
sys_free (node);
}
static int nota_stack_has (NotaEncodeContext *enc, JSValueConst val) {
JSContext *ctx = enc->ctx;
int len = nota_get_arr_len (ctx, enc->visitedStack_ref->val);
for (int i = 0; i < len; i++) {
JSValue elem = JS_GetPropertyNumber (ctx, enc->visitedStack_ref->val, i);
if (mist_is_gc_object (elem) && mist_is_gc_object (val)) {
if (JS_StrictEq (ctx, elem, val)) {
JS_FreeValue (ctx, elem);
return 1;
}
}
JS_FreeValue (ctx, elem);
NotaVisitedNode *node = enc->visited_list;
while (node) {
if (JS_StrictEq (enc->ctx, node->ref.val, val))
return 1;
node = node->next;
}
return 0;
}
@@ -11481,6 +11484,13 @@ static void nota_encode_value (NotaEncodeContext *enc, JSValueConst val, JSValue
nota_write_sym (&enc->nb, NOTA_NULL);
break;
case JS_TAG_PTR: {
if (JS_IsText (replaced_ref.val)) {
const char *str = JS_ToCString (ctx, replaced_ref.val);
nota_write_text (&enc->nb, str);
JS_FreeCString (ctx, str);
break;
}
if (js_is_blob (ctx, replaced_ref.val)) {
size_t buf_len;
void *buf_data = js_get_blob_data (ctx, &buf_len, replaced_ref.val);
@@ -11592,16 +11602,14 @@ static void nota_encode_value (NotaEncodeContext *enc, JSValueConst val, JSValue
}
void *value2nota (JSContext *ctx, JSValue v) {
JSGCRef val_ref, stack_ref, key_ref;
JSGCRef val_ref, key_ref;
JS_PushGCRef (ctx, &val_ref);
JS_PushGCRef (ctx, &stack_ref);
JS_PushGCRef (ctx, &key_ref);
val_ref.val = v;
NotaEncodeContext enc_s, *enc = &enc_s;
enc->ctx = ctx;
stack_ref.val = JS_NewArray (ctx);
enc->visitedStack_ref = &stack_ref;
enc->visited_list = NULL;
enc->cycle = 0;
enc->replacer_ref = NULL;
@@ -11611,14 +11619,12 @@ void *value2nota (JSContext *ctx, JSValue v) {
if (enc->cycle) {
JS_PopGCRef (ctx, &key_ref);
JS_PopGCRef (ctx, &stack_ref);
JS_PopGCRef (ctx, &val_ref);
nota_buffer_free (&enc->nb);
return NULL;
}
JS_PopGCRef (ctx, &key_ref);
JS_PopGCRef (ctx, &stack_ref);
JS_PopGCRef (ctx, &val_ref);
void *data_ptr = enc->nb.data;
enc->nb.data = NULL;
@@ -11646,18 +11652,16 @@ JSValue nota2value (JSContext *js, void *nota) {
static JSValue js_nota_encode (JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
if (argc < 1) return JS_ThrowTypeError (ctx, "nota.encode requires at least 1 argument");
JSGCRef val_ref, stack_ref, replacer_ref, key_ref;
JSGCRef val_ref, replacer_ref, key_ref;
JS_PushGCRef (ctx, &val_ref);
JS_PushGCRef (ctx, &stack_ref);
JS_PushGCRef (ctx, &replacer_ref);
JS_PushGCRef (ctx, &key_ref);
val_ref.val = argv[0];
stack_ref.val = JS_NewArray (ctx);
replacer_ref.val = (argc > 1 && JS_IsFunction (argv[1])) ? argv[1] : JS_NULL;
NotaEncodeContext enc_s, *enc = &enc_s;
enc->ctx = ctx;
enc->visitedStack_ref = &stack_ref;
enc->visited_list = NULL;
enc->cycle = 0;
enc->replacer_ref = &replacer_ref;
@@ -11678,7 +11682,6 @@ static JSValue js_nota_encode (JSContext *ctx, JSValueConst this_val, int argc,
JS_PopGCRef (ctx, &key_ref);
JS_PopGCRef (ctx, &replacer_ref);
JS_PopGCRef (ctx, &stack_ref);
JS_PopGCRef (ctx, &val_ref);
return ret;
}