Merge branch 'bench_endoders'
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user