MIRROR: javascript for ๐Ÿœ's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

HOTFIX: promise object offset for multi-access

+31 -19
+1 -1
include/ant.h
··· 26 26 #define GC_FWD_ARGS jsval_t (*fwd_val)(void *ctx, jsval_t old), void *ctx 27 27 #define GC_UPDATE_ARGS struct js *js, jsoff_t (*fwd_off)(void *ctx, jsoff_t old), GC_FWD_ARGS 28 28 29 - enum { 29 + enum { 30 30 JS_UNDEF, JS_NULL, JS_TRUE, JS_FALSE, JS_STR, JS_NUM, 31 31 JS_ERR, JS_PRIV, JS_PROMISE, JS_OBJ, JS_FUNC, JS_SYMBOL 32 32 };
+25 -18
src/ant.c
··· 248 248 }; 249 249 250 250 typedef struct promise_data_entry { 251 + jsval_t value; 252 + UT_array *handlers; 251 253 uint32_t promise_id; 254 + jsoff_t obj_offset; 252 255 int state; 253 - jsval_t value; 254 - UT_array *handlers; 255 256 UT_hash_handle hh; 256 257 } promise_data_entry_t; 257 258 ··· 18406 18407 18407 18408 entry = (promise_data_entry_t *)malloc(sizeof(promise_data_entry_t)); 18408 18409 entry->promise_id = promise_id; 18410 + entry->obj_offset = 0; 18409 18411 entry->state = 0; 18410 18412 entry->value = js_mkundef(); 18411 18413 utarray_new(entry->handlers, &promise_handler_icd); ··· 18427 18429 18428 18430 uint32_t pid = next_promise_id++; 18429 18431 set_slot(js, obj, SLOT_PID, tov((double)pid)); 18430 - get_promise_data(pid, true); 18432 + promise_data_entry_t *pd = get_promise_data(pid, true); 18433 + if (pd) pd->obj_offset = (jsoff_t)vdata(obj); 18431 18434 18432 18435 return mkval(T_PROMISE, vdata(obj)); 18433 18436 } ··· 18479 18482 } 18480 18483 } 18481 18484 18482 - utarray_clear(pd->handlers); 18483 - 18484 - if (pd->state != 0) { 18485 - utarray_free(pd->handlers); 18486 - HASH_DEL(promise_registry, pd); 18487 - free(pd); 18488 - } 18489 - 18485 + utarray_clear(pd->handlers); 18490 18486 return js_mkundef(); 18491 18487 } 18492 18488 ··· 21607 21603 } 21608 21604 21609 21605 promise_data_entry_t *pd, *pd_tmp; 21610 - HASH_ITER(hh, promise_registry, pd, pd_tmp) { 21611 - FWD_VAL(pd->value); 21612 - UTARRAY_EACH(pd->handlers, promise_handler_t, h) { 21613 - FWD_VAL(h->onFulfilled); 21614 - FWD_VAL(h->onRejected); 21615 - FWD_VAL(h->nextPromise); 21606 + for (promise_data_entry_t *new_promise_registry = NULL, *_once = NULL; !_once; _once = (void*)1, promise_registry = new_promise_registry) 21607 + HASH_ITER(hh, promise_registry, pd, pd_tmp) { 21608 + HASH_DEL(promise_registry, pd); 21609 + jsoff_t new_off = fwd_off(ctx, pd->obj_offset); 21610 + if (new_off == pd->obj_offset && pd->obj_offset != 0) { 21611 + // Object not forwarded means it's dead - free the entry 21612 + utarray_free(pd->handlers); 21613 + free(pd); 21614 + continue; 21615 + } 21616 + pd->obj_offset = new_off; 21617 + FWD_VAL(pd->value); 21618 + UTARRAY_EACH(pd->handlers, promise_handler_t, h) { 21619 + FWD_VAL(h->onFulfilled); 21620 + FWD_VAL(h->onRejected); 21621 + FWD_VAL(h->nextPromise); 21622 + } 21623 + HASH_ADD(hh, new_promise_registry, promise_id, sizeof(uint32_t), pd); 21616 21624 } 21617 - } 21618 21625 21619 21626 if (rt && rt->js == js) FWD_VAL(rt->ant_obj); 21620 21627
+5
tests/test_double_resolve.cjs
··· 1 + (async () => { 2 + let p = Promise.resolve(1).then(x => x + 1); 3 + console.log(await p); 4 + console.log(await p); 5 + })();