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.

remove dependence on ANT_PTR, use object.native.ptr instead

+516 -387
+3 -1
include/ant.h
··· 25 25 }}) 26 26 27 27 #define ANT_STRING(s) js_mkstr(js, s, sizeof(s) - 1) 28 - #define ANT_PTR(ptr) js_mknum((double)(uintptr_t)(ptr)) 29 28 #define ANT_COPY(buf, len, s) cpy(buf, len, s, sizeof(s) - 1) 30 29 #define REMAIN(n, len) ((n) >= (len) ? 0 : (len) - (n)) 31 30 ··· 116 115 ant_value_t js_mkfun_dyn(ant_cfunc_t fn); 117 116 118 117 ant_value_t js_heavy_mkfun(ant_t *js, ant_value_t (*fn)(ant_t *, ant_value_t *, int), ant_value_t data); 118 + ant_value_t js_heavy_mkfun_native(ant_t *js, ant_value_t (*fn)(ant_t *, ant_value_t *, int), void *ptr, uint32_t tag); 119 119 ant_value_t js_mkprop_fast(ant_t *js, ant_value_t obj, const char *key, size_t len, ant_value_t v); 120 + 121 + // TODO: deprecate 120 122 ant_offset_t js_mkprop_fast_off(ant_t *js, ant_value_t obj, const char *key, size_t len, ant_value_t v); 121 123 122 124 #define js_mkfun(fn) ({ \
+14
include/modules/collections.h
··· 51 51 iter_type_t type; 52 52 } set_iterator_state_t; 53 53 54 + enum { 55 + MAP_NATIVE_TAG = 0x4d415050u, // MAPP 56 + SET_NATIVE_TAG = 0x53455450u, // SETP 57 + 58 + WEAKMAP_NATIVE_TAG = 0x574d4150u, // WMAP 59 + WEAKSET_NATIVE_TAG = 0x57534554u, // WSET 60 + 61 + MAP_ITER_NATIVE_TAG = 0x4d495452u, // MITR 62 + SET_ITER_NATIVE_TAG = 0x53495452u // SITR 63 + }; 64 + 54 65 void init_collections_module(void); 55 66 56 67 map_entry_t **get_map_from_obj(ant_value_t obj); 57 68 set_entry_t **get_set_from_obj(ant_value_t obj); 69 + 70 + map_iterator_state_t *get_map_iter_state(ant_value_t obj); 71 + set_iterator_state_t *get_set_iter_state(ant_value_t obj); 58 72 59 73 extern ant_value_t g_map_iter_proto; 60 74 extern ant_value_t g_set_iter_proto;
+12 -2
include/modules/formdata.h
··· 25 25 bool formdata_is_formdata(ant_t *js, ant_value_t obj); 26 26 27 27 ant_value_t formdata_create_empty(ant_t *js); 28 - ant_value_t formdata_append_string(ant_t *js, ant_value_t fd, ant_value_t name_v, ant_value_t value_v); 29 - ant_value_t formdata_append_file(ant_t *js, ant_value_t fd, ant_value_t name_v, ant_value_t blob_v, ant_value_t filename_v); 28 + fd_data_t *formdata_get_data(ant_value_t fd); 29 + 30 + ant_value_t formdata_append_string( 31 + ant_t *js, ant_value_t fd, 32 + ant_value_t name_v, ant_value_t value_v 33 + ); 34 + 35 + ant_value_t formdata_append_file( 36 + ant_t *js, ant_value_t fd, 37 + ant_value_t name_v, ant_value_t blob_v, 38 + ant_value_t filename_v 39 + ); 30 40 31 41 #endif
+6 -4
include/object.h
··· 27 27 typedef struct { 28 28 ant_value_t value; 29 29 ant_value_t trigger_parent; 30 + 31 + struct ant_object *gc_pending_next; 30 32 promise_handler_t inline_handler; 33 + 31 34 UT_array *handlers; 32 35 uint32_t promise_id; 33 36 uint16_t handler_count; 34 37 uint8_t state; 38 + 35 39 bool trigger_queued; 36 40 bool has_rejection_handler; 37 41 bool processing; 38 42 bool unhandled_reported; 43 + bool gc_pending_rooted; 39 44 } ant_promise_state_t; 40 45 41 46 typedef struct { ··· 94 99 ant_promise_state_t *promise_state; 95 100 ant_extra_slot_t *extra_slots; 96 101 97 - struct ant_object *gc_pending_next; 98 102 void (*finalizer)(ant_t *, struct ant_object *); 99 103 ant_value_t inobj[ANT_INOBJ_MAX_SLOTS]; 100 104 ··· 116 120 uint8_t type_tag; 117 121 uint8_t inobj_limit; 118 122 uint8_t extra_count; 123 + uint8_t overflow_cap; 119 124 120 125 uint8_t extensible: 1; 121 126 uint8_t frozen: 1; ··· 128 133 uint8_t gc_permanent: 1; 129 134 uint8_t generation: 1; 130 135 uint8_t in_remember_set: 1; 131 - 132 - bool gc_pending_rooted; 133 - uint8_t overflow_cap; 134 136 } ant_object_t; 135 137 136 138 static inline bool ant_object_has_sidecar(const ant_object_t *obj) {
+14 -3
include/ptr.h
··· 1 - #ifndef ANT_PTR_H 2 - #define ANT_PTR_H 1 + #ifndef ANT_NATIVE_PTR_H 2 + #define ANT_NATIVE_PTR_H 3 3 4 4 #include "types.h" 5 5 #include "internal.h" // IWYU pragma: keep ··· 21 21 o->native.tag = tag; 22 22 } 23 23 24 + static inline void js_set_native(ant_value_t obj, void *ptr, uint32_t tag) { 25 + ant_object_t *o = js_obj_ptr(obj); 26 + if (!o) return; 27 + o->native.ptr = ptr; 28 + o->native.tag = tag; 29 + } 30 + 31 + static inline void js_clear_native(ant_value_t obj) { 32 + js_set_native(obj, NULL, 0); 33 + } 34 + 24 35 static inline uint32_t js_get_native_tag(ant_value_t obj) { 25 36 ant_object_t *o = js_obj_ptr(obj); 26 37 return o ? o->native.tag : 0; ··· 31 42 return js_get_native_tag(obj) == tag; 32 43 } 33 44 34 - #endif 45 + #endif
+5
include/streams/readable.h
··· 31 31 bool disturbed; 32 32 } rs_stream_t; 33 33 34 + enum { 35 + RS_STREAM_NATIVE_TAG = 0x52535452u, // RSTR 36 + RS_CONTROLLER_NATIVE_TAG = 0x52534354u // RSCT 37 + }; 38 + 34 39 extern ant_value_t g_rs_proto; 35 40 extern ant_value_t g_reader_proto; 36 41 extern ant_value_t g_controller_proto;
+5
include/streams/writable.h
··· 29 29 bool pending_abort_was_already_erroring; 30 30 } ws_stream_t; 31 31 32 + enum { 33 + WS_STREAM_NATIVE_TAG = 0x57535452u, // WSTR 34 + WS_CONTROLLER_NATIVE_TAG = 0x57534354u // WSCT 35 + }; 36 + 32 37 extern ant_value_t g_ws_proto; 33 38 extern ant_value_t g_ws_writer_proto; 34 39 extern ant_value_t g_ws_controller_proto;
+11 -4
src/ant.c
··· 431 431 obj->extra_count = 0; 432 432 433 433 obj->finalizer = NULL; 434 - obj->gc_pending_next = NULL; 435 - obj->gc_pending_rooted = false; 436 - 437 434 obj->native.ptr = NULL; 438 435 obj->native.tag = 0; 439 436 ··· 15231 15228 return promoted; 15232 15229 } 15233 15230 15234 - ant_value_t js_heavy_mkfun(ant_t *js, ant_value_t (*fn)(ant_t *, ant_value_t *, int), ant_value_t data) { 15231 + ant_value_t js_heavy_mkfun(ant_t *js, ant_value_t (*fn)(ant_params_t), ant_value_t data) { 15235 15232 ant_value_t cfunc = js_mkfun_dyn(fn); 15236 15233 ant_value_t fn_obj = mkobj(js, 0); 15237 15234 15238 15235 set_slot(fn_obj, SLOT_CFUNC, cfunc); 15239 15236 set_slot(fn_obj, SLOT_DATA, data); 15237 + 15238 + return js_obj_to_func(fn_obj); 15239 + } 15240 + 15241 + ant_value_t js_heavy_mkfun_native(ant_t *js, ant_value_t (*fn)(ant_params_t), void *ptr, uint32_t tag) { 15242 + ant_value_t cfunc = js_mkfun_dyn(fn); 15243 + ant_value_t fn_obj = mkobj(js, 0); 15244 + 15245 + set_slot(fn_obj, SLOT_CFUNC, cfunc); 15246 + js_set_native(fn_obj, ptr, tag); 15240 15247 15241 15248 return js_obj_to_func(fn_obj); 15242 15249 }
+37 -22
src/gc/objects.c
··· 94 94 } 95 95 96 96 void gc_root_pending_promise(ant_object_t *obj) { 97 - if (!obj || obj->gc_pending_rooted) return; 98 - obj->gc_pending_rooted = true; 99 - obj->gc_pending_next = g_pending_promises; 97 + ant_promise_state_t *pd = obj ? obj->promise_state : NULL; 98 + if (!pd || pd->gc_pending_rooted) return; 99 + 100 + pd->gc_pending_rooted = true; 101 + pd->gc_pending_next = g_pending_promises; 100 102 g_pending_promises = obj; 101 103 } 102 104 103 105 void gc_unroot_pending_promise(ant_object_t *obj) { 104 - if (!obj || !obj->gc_pending_rooted) return; 105 - obj->gc_pending_rooted = false; 106 + ant_promise_state_t *pd = obj ? obj->promise_state : NULL; 107 + if (!pd || !pd->gc_pending_rooted) return; 108 + 109 + pd->gc_pending_rooted = false; 106 110 ant_object_t **pp = &g_pending_promises; 107 111 while (*pp) { 108 - if (*pp == obj) { *pp = obj->gc_pending_next; break; } 109 - pp = &(*pp)->gc_pending_next; 112 + ant_promise_state_t *current = (*pp)->promise_state; 113 + if (*pp == obj) { *pp = pd->gc_pending_next; break; } 114 + if (!current) { *pp = NULL; break; } 115 + pp = &current->gc_pending_next; 110 116 } 111 - obj->gc_pending_next = NULL; 117 + pd->gc_pending_next = NULL; 112 118 } 113 119 114 120 void gc_remember_add(ant_t *js, ant_object_t *obj) { ··· 239 245 } 240 246 241 247 if (obj->type_tag == T_MAP) { 242 - map_entry_t **head = (map_entry_t **)(uintptr_t)js_getnum(obj->u.data.value); 248 + map_entry_t **head = obj->native.tag == MAP_NATIVE_TAG 249 + ? (map_entry_t **)obj->native.ptr : NULL; 243 250 if (head) { 244 251 map_entry_t *e, *tmp; 245 252 HASH_ITER(hh, *head, e, tmp) { 246 253 gc_mark_value(js, e->key_val); 247 254 gc_mark_value(js, e->value); 248 255 }} 249 - } else if (obj->type_tag == T_WEAKMAP) { 250 - weakmap_entry_t **head = (weakmap_entry_t **)(uintptr_t)js_getnum(obj->u.data.value); 256 + } 257 + 258 + else if (obj->type_tag == T_WEAKMAP) { 259 + weakmap_entry_t **head = obj->native.tag == WEAKMAP_NATIVE_TAG 260 + ? (weakmap_entry_t **)obj->native.ptr : NULL; 251 261 if (head) { 252 262 weakmap_entry_t *e, *tmp; 253 263 HASH_ITER(hh, *head, e, tmp) { 254 264 gc_mark_value(js, e->key_obj); 255 265 gc_mark_value(js, e->value); 256 266 }} 257 - } else if (obj->type_tag == T_SET) { 258 - set_entry_t **head = (set_entry_t **)(uintptr_t)js_getnum(obj->u.data.value); 267 + } 268 + 269 + else if (obj->type_tag == T_SET) { 270 + set_entry_t **head = obj->native.tag == SET_NATIVE_TAG 271 + ? (set_entry_t **)obj->native.ptr : NULL; 259 272 if (head) { 260 273 set_entry_t *e, *tmp; 261 274 HASH_ITER(hh, *head, e, tmp) { gc_mark_value(js, e->value); } ··· 527 540 gc_mark_wasm(js, gc_mark_value); 528 541 gc_mark_napi(js, gc_mark_value); 529 542 530 - for ( 531 - ant_object_t *obj = g_pending_promises; 532 - obj; obj = obj->gc_pending_next 533 - ) gc_grey_obj(js, obj); 543 + for (ant_object_t *obj = g_pending_promises; obj;) { 544 + ant_promise_state_t *pd = obj->promise_state; 545 + ant_object_t *next = pd ? pd->gc_pending_next : NULL; 546 + gc_grey_obj(js, obj); 547 + obj = next; 548 + } 534 549 535 550 gc_scan_current_stack(js); 536 551 gc_scan_other_stacks(js); ··· 567 582 obj->extra_slots = NULL; 568 583 } 569 584 570 - if (obj->gc_pending_rooted) 585 + if (obj->promise_state && obj->promise_state->gc_pending_rooted) 571 586 gc_unroot_pending_promise(obj); 572 587 573 588 if (obj->promise_state) { ··· 584 599 585 600 switch (obj->type_tag) { 586 601 case T_MAP: { 587 - map_entry_t **head = (map_entry_t **)(uintptr_t)js_getnum(obj->u.data.value); 602 + map_entry_t **head = obj->native.tag == MAP_NATIVE_TAG ? (map_entry_t **)obj->native.ptr : NULL; 588 603 if (head) { 589 604 map_entry_t *e, *tmp; 590 605 HASH_ITER(hh, *head, e, tmp) { HASH_DEL(*head, e); free(e->key); free(e); } ··· 593 608 break; 594 609 } 595 610 case T_SET: { 596 - set_entry_t **head = (set_entry_t **)(uintptr_t)js_getnum(obj->u.data.value); 611 + set_entry_t **head = obj->native.tag == SET_NATIVE_TAG ? (set_entry_t **)obj->native.ptr : NULL; 597 612 if (head) { 598 613 set_entry_t *e, *tmp; 599 614 HASH_ITER(hh, *head, e, tmp) { HASH_DEL(*head, e); free(e->key); free(e); } ··· 602 617 break; 603 618 } 604 619 case T_WEAKMAP: { 605 - weakmap_entry_t **head = (weakmap_entry_t **)(uintptr_t)js_getnum(obj->u.data.value); 620 + weakmap_entry_t **head = obj->native.tag == WEAKMAP_NATIVE_TAG ? (weakmap_entry_t **)obj->native.ptr : NULL; 606 621 if (head) { 607 622 weakmap_entry_t *e, *tmp; 608 623 HASH_ITER(hh, *head, e, tmp) { HASH_DEL(*head, e); free(e); } ··· 611 626 break; 612 627 } 613 628 case T_WEAKSET: { 614 - weakset_entry_t **head = (weakset_entry_t **)(uintptr_t)js_getnum(obj->u.data.value); 629 + weakset_entry_t **head = obj->native.tag == WEAKSET_NATIVE_TAG ? (weakset_entry_t **)obj->native.ptr : NULL; 615 630 if (head) { 616 631 weakset_entry_t *e, *tmp; 617 632 HASH_ITER(hh, *head, e, tmp) { HASH_DEL(*head, e); free(e); }
+6 -4
src/modules/abort.c
··· 4 4 #include <uv.h> 5 5 6 6 #include "ant.h" 7 + #include "ptr.h" 7 8 #include "errors.h" 8 9 #include "internal.h" 9 10 #include "runtime.h" ··· 44 45 static ant_value_t g_signal_proto = 0; 45 46 static bool g_initialized = false; 46 47 48 + enum { ABORT_SIGNAL_NATIVE_TAG = 0x41534947u }; // ASIG 49 + 47 50 static inline unsigned int abort_array_len(UT_array *arr) { 48 51 return arr ? utarray_len(arr) : 0; 49 52 } 50 53 51 54 static abort_signal_data_t *get_signal_data(ant_value_t obj) { 52 - ant_value_t slot = js_get_slot(obj, SLOT_DATA); 53 - if (vtype(slot) != T_NUM) return NULL; 54 - return (abort_signal_data_t *)(uintptr_t)js_getnum(slot); 55 + if (!js_check_native_tag(obj, ABORT_SIGNAL_NATIVE_TAG)) return NULL; 56 + return (abort_signal_data_t *)js_get_native_ptr(obj); 55 57 } 56 58 57 59 static abort_signal_data_t *get_signal_data_if_signal_object(ant_value_t obj) { ··· 186 188 } 187 189 188 190 ant_value_t obj = js_mkobj(js); 189 - js_set_slot(obj, SLOT_DATA, ANT_PTR(data)); 191 + js_set_native(obj, data, ABORT_SIGNAL_NATIVE_TAG); 190 192 js_set_slot(obj, SLOT_BRAND, js_mknum(BRAND_ABORT_SIGNAL)); 191 193 if (g_initialized) js_set_slot_wb(js, obj, SLOT_PROTO, g_signal_proto); 192 194
+12 -9
src/modules/blob.c
··· 7 7 #include <stdio.h> 8 8 9 9 #include "ant.h" 10 + #include "ptr.h" 10 11 #include "errors.h" 11 12 #include "runtime.h" 12 13 #include "internal.h" ··· 20 21 ant_value_t g_blob_proto = 0; 21 22 ant_value_t g_file_proto = 0; 22 23 24 + enum { BLOB_NATIVE_TAG = 0x424c4f42u }; // BLOB 25 + 23 26 bool blob_is_blob(ant_t *js, ant_value_t obj) { 24 27 int id = js_brand_id(obj); 25 28 return id == BRAND_BLOB || id == BRAND_FILE; 26 29 } 27 30 28 31 blob_data_t *blob_get_data(ant_value_t obj) { 29 - ant_value_t slot = js_get_slot(obj, SLOT_DATA); 30 - if (vtype(slot) != T_NUM) return NULL; 31 - return (blob_data_t *)(uintptr_t)(size_t)js_getnum(slot); 32 + if (!js_check_native_tag(obj, BLOB_NATIVE_TAG)) return NULL; 33 + return (blob_data_t *)js_get_native_ptr(obj); 32 34 } 33 35 34 36 static blob_data_t *blob_data_new(const uint8_t *data, size_t size, const char *type) { ··· 150 152 } 151 153 152 154 static void blob_finalize(ant_t *js, ant_object_t *obj) { 153 - ant_extra_slot_t *slot = ant_object_extra_slot(obj, SLOT_DATA); 154 - if (!slot || vtype(slot->value) != T_NUM) return; 155 - blob_data_t *bd = (blob_data_t *)(uintptr_t)(size_t)js_getnum(slot->value); 155 + if (!obj || obj->native.tag != BLOB_NATIVE_TAG) return; 156 + blob_data_t *bd = (blob_data_t *)obj->native.ptr; 156 157 if (bd) { free(bd->data); free(bd->type); free(bd->name); free(bd); } 158 + obj->native.ptr = NULL; 159 + obj->native.tag = 0; 157 160 } 158 161 159 162 ant_value_t blob_create(ant_t *js, const uint8_t *data, size_t size, const char *type) { ··· 163 166 164 167 js_set_proto_init(obj, g_blob_proto); 165 168 js_set_slot(obj, SLOT_BRAND, js_mknum(BRAND_BLOB)); 166 - js_set_slot(obj, SLOT_DATA, ANT_PTR(bd)); 169 + js_set_native(obj, bd, BLOB_NATIVE_TAG); 167 170 js_set_finalizer(obj, blob_finalize); 168 171 169 172 return obj; ··· 344 347 if (is_object_type(proto)) js_set_proto_init(obj, proto); 345 348 346 349 js_set_slot(obj, SLOT_BRAND, js_mknum(BRAND_BLOB)); 347 - js_set_slot(obj, SLOT_DATA, ANT_PTR(bd)); 350 + js_set_native(obj, bd, BLOB_NATIVE_TAG); 348 351 js_set_finalizer(obj, blob_finalize); 349 352 350 353 return obj; ··· 415 418 if (is_object_type(proto)) js_set_proto_init(obj, proto); 416 419 417 420 js_set_slot(obj, SLOT_BRAND, js_mknum(BRAND_FILE)); 418 - js_set_slot(obj, SLOT_DATA, ANT_PTR(bd)); 421 + js_set_native(obj, bd, BLOB_NATIVE_TAG); 419 422 js_set_finalizer(obj, blob_finalize); 420 423 421 424 return obj;
+37 -52
src/modules/child_process.c
··· 24 24 #endif 25 25 26 26 #include "ant.h" 27 + #include "ptr.h" 27 28 #include "errors.h" 28 29 #include "internal.h" 29 30 #include "silver/engine.h" ··· 108 109 }; 109 110 110 111 static child_process_t *pending_children_head = NULL; 112 + 113 + enum { 114 + CHILD_PROCESS_NATIVE_TAG = 0x43505243u, // CPRC 115 + CHILD_STREAM_NATIVE_TAG = 0x4353544du // CSTM 116 + }; 117 + 118 + static child_process_t *get_child_process(ant_value_t obj) { 119 + if (!js_check_native_tag(obj, CHILD_PROCESS_NATIVE_TAG)) return NULL; 120 + return (child_process_t *)js_get_native_ptr(obj); 121 + } 122 + 123 + static child_stream_ctx_t *get_child_stream_ctx(ant_value_t obj) { 124 + if (!js_check_native_tag(obj, CHILD_STREAM_NATIVE_TAG)) return NULL; 125 + return (child_stream_ctx_t *)js_get_native_ptr(obj); 126 + } 111 127 static child_process_t *pending_children_tail = NULL; 112 128 113 129 static ant_value_t g_child_process_proto = 0; ··· 503 519 if (vtype(args[0]) != T_STR) return js_mkerr(js, "Event name must be a string"); 504 520 if (vtype(args[1]) != T_FUNC) return js_mkerr(js, "Callback must be a function"); 505 521 506 - ant_value_t cp_ptr = js_get_slot(this_obj, SLOT_DATA); 507 - if (vtype(cp_ptr) == T_UNDEF) return js_mkerr(js, "Invalid child process object"); 508 - child_process_t *cp = (child_process_t *)(uintptr_t)js_getnum(cp_ptr); 522 + child_process_t *cp = get_child_process(this_obj); 523 + if (!cp) return js_mkerr(js, "Invalid child process object"); 509 524 510 525 size_t name_len; 511 526 char *name = js_getstr(js, args[0], &name_len); ··· 531 546 if (vtype(args[0]) != T_STR) return js_mkerr(js, "Event name must be a string"); 532 547 if (vtype(args[1]) != T_FUNC) return js_mkerr(js, "Callback must be a function"); 533 548 534 - ant_value_t cp_ptr = js_get_slot(this_obj, SLOT_DATA); 535 - if (vtype(cp_ptr) == T_UNDEF) return js_mkerr(js, "Invalid child process object"); 536 - 537 - child_process_t *cp = (child_process_t *)(uintptr_t)js_getnum(cp_ptr); 549 + child_process_t *cp = get_child_process(this_obj); 550 + if (!cp) return js_mkerr(js, "Invalid child process object"); 538 551 539 552 size_t name_len; 540 553 char *name = js_getstr(js, args[0], &name_len); ··· 557 570 static ant_value_t child_kill(ant_t *js, ant_value_t *args, int nargs) { 558 571 ant_value_t this_obj = js_getthis(js); 559 572 560 - ant_value_t cp_ptr = js_get_slot(this_obj, SLOT_DATA); 561 - if (vtype(cp_ptr) == T_UNDEF) return js_false; 562 - 563 - child_process_t *cp = (child_process_t *)(uintptr_t)js_getnum(cp_ptr); 573 + child_process_t *cp = get_child_process(this_obj); 574 + if (!cp) return js_false; 564 575 if (cp->exited) return js_false; 565 576 566 577 int sig = SIGTERM; ··· 627 638 ant_value_t this_obj = js_getthis(js); 628 639 if (nargs < 1) return js_mkerr(js, "write() requires data argument"); 629 640 630 - ant_value_t cp_ptr = js_get_slot(this_obj, SLOT_DATA); 631 - if (vtype(cp_ptr) == T_UNDEF) return js_mkerr(js, "Invalid child process object"); 632 - 633 - child_process_t *cp = (child_process_t *)(uintptr_t)js_getnum(cp_ptr); 641 + child_process_t *cp = get_child_process(this_obj); 642 + if (!cp) return js_mkerr(js, "Invalid child process object"); 634 643 return child_write_impl(js, cp, args[0]); 635 644 } 636 645 637 646 static ant_value_t child_ref(ant_t *js, ant_value_t *args, int nargs) { 638 647 ant_value_t this_obj = js_getthis(js); 639 - ant_value_t cp_ptr = js_get_slot(this_obj, SLOT_DATA); 640 - 641 - if (vtype(cp_ptr) == T_UNDEF) return this_obj; 642 - child_process_t *cp = (child_process_t *)(uintptr_t)js_getnum(cp_ptr); 648 + child_process_t *cp = get_child_process(this_obj); 643 649 644 650 if (!cp) return this_obj; 645 651 cp->keep_alive = true; ··· 655 661 656 662 static ant_value_t child_unref(ant_t *js, ant_value_t *args, int nargs) { 657 663 ant_value_t this_obj = js_getthis(js); 658 - ant_value_t cp_ptr = js_get_slot(this_obj, SLOT_DATA); 659 - 660 - if (vtype(cp_ptr) == T_UNDEF) return this_obj; 661 - child_process_t *cp = (child_process_t *)(uintptr_t)js_getnum(cp_ptr); 664 + child_process_t *cp = get_child_process(this_obj); 662 665 663 666 if (!cp) return this_obj; 664 667 cp->keep_alive = false; ··· 675 678 static ant_value_t child_end(ant_t *js, ant_value_t *args, int nargs) { 676 679 ant_value_t this_obj = js_getthis(js); 677 680 678 - ant_value_t cp_ptr = js_get_slot(this_obj, SLOT_DATA); 679 - if (vtype(cp_ptr) == T_UNDEF) return js_mkundef(); 680 - 681 - child_process_t *cp = (child_process_t *)(uintptr_t)js_getnum(cp_ptr); 681 + child_process_t *cp = get_child_process(this_obj); 682 + if (!cp) return js_mkundef(); 682 683 return child_end_impl(cp); 683 684 } 684 685 ··· 727 728 static ant_value_t child_stream_write(ant_t *js, ant_value_t *args, int nargs) { 728 729 ant_value_t this_obj = js_getthis(js); 729 730 if (nargs < 1) return js_mkerr(js, "write() requires data argument"); 730 - ant_value_t ctx_ptr = js_get_slot(this_obj, SLOT_DATA); 731 - if (vtype(ctx_ptr) == T_UNDEF) return js_mkerr(js, "Invalid stream object"); 732 - child_stream_ctx_t *ctx = (child_stream_ctx_t *)(uintptr_t)js_getnum(ctx_ptr); 731 + child_stream_ctx_t *ctx = get_child_stream_ctx(this_obj); 733 732 if (!ctx || !ctx->cp) return js_mkerr(js, "Invalid stream context"); 734 733 return child_write_impl(js, ctx->cp, args[0]); 735 734 } ··· 737 736 static ant_value_t child_stream_end(ant_t *js, ant_value_t *args, int nargs) { 738 737 (void)args; (void)nargs; 739 738 ant_value_t this_obj = js_getthis(js); 740 - ant_value_t ctx_ptr = js_get_slot(this_obj, SLOT_DATA); 741 - if (vtype(ctx_ptr) == T_UNDEF) return js_mkundef(); 742 - child_stream_ctx_t *ctx = (child_stream_ctx_t *)(uintptr_t)js_getnum(ctx_ptr); 739 + child_stream_ctx_t *ctx = get_child_stream_ctx(this_obj); 743 740 if (!ctx || !ctx->cp) return js_mkundef(); 744 741 return child_end_impl(ctx->cp); 745 742 } ··· 747 744 static ant_value_t child_stream_ref(ant_t *js, ant_value_t *args, int nargs) { 748 745 (void)args; (void)nargs; 749 746 ant_value_t this_obj = js_getthis(js); 750 - ant_value_t ctx_ptr = js_get_slot(this_obj, SLOT_DATA); 751 - if (vtype(ctx_ptr) == T_UNDEF) return this_obj; 752 - child_stream_ctx_t *ctx = (child_stream_ctx_t *)(uintptr_t)js_getnum(ctx_ptr); 747 + child_stream_ctx_t *ctx = get_child_stream_ctx(this_obj); 753 748 if (!ctx || !ctx->cp) return this_obj; 754 749 755 750 uv_handle_t *h = child_stream_handle(ctx->cp, ctx->kind); ··· 760 755 static ant_value_t child_stream_unref(ant_t *js, ant_value_t *args, int nargs) { 761 756 (void)args; (void)nargs; 762 757 ant_value_t this_obj = js_getthis(js); 763 - ant_value_t ctx_ptr = js_get_slot(this_obj, SLOT_DATA); 764 - if (vtype(ctx_ptr) == T_UNDEF) return this_obj; 765 - child_stream_ctx_t *ctx = (child_stream_ctx_t *)(uintptr_t)js_getnum(ctx_ptr); 758 + child_stream_ctx_t *ctx = get_child_stream_ctx(this_obj); 766 759 if (!ctx || !ctx->cp) return this_obj; 767 760 768 761 uv_handle_t *h = child_stream_handle(ctx->cp, ctx->kind); ··· 773 766 static ant_value_t child_stream_destroy(ant_t *js, ant_value_t *args, int nargs) { 774 767 (void)args; (void)nargs; 775 768 ant_value_t this_obj = js_getthis(js); 776 - ant_value_t ctx_ptr = js_get_slot(this_obj, SLOT_DATA); 777 - if (vtype(ctx_ptr) == T_UNDEF) return this_obj; 778 - child_stream_ctx_t *ctx = (child_stream_ctx_t *)(uintptr_t)js_getnum(ctx_ptr); 769 + child_stream_ctx_t *ctx = get_child_stream_ctx(this_obj); 779 770 if (!ctx || !ctx->cp) return this_obj; 780 771 781 772 child_process_t *cp = ctx->cp; ··· 800 791 if (vtype(args[0]) != T_STR) return js_mkerr(js, "Event name must be a string"); 801 792 if (vtype(args[1]) != T_FUNC) return js_mkerr(js, "Callback must be a function"); 802 793 803 - ant_value_t ctx_ptr = js_get_slot(this_obj, SLOT_DATA); 804 - if (vtype(ctx_ptr) == T_UNDEF) return js_mkerr(js, "Invalid stream object"); 805 - 806 - child_stream_ctx_t *ctx = (child_stream_ctx_t *)(uintptr_t)js_getnum(ctx_ptr); 794 + child_stream_ctx_t *ctx = get_child_stream_ctx(this_obj); 807 795 if (!ctx || !ctx->cp) return js_mkerr(js, "Invalid stream context"); 808 796 809 797 child_process_t *cp = ctx->cp; ··· 837 825 if (vtype(args[0]) != T_STR) return js_mkerr(js, "Event name must be a string"); 838 826 if (vtype(args[1]) != T_FUNC) return js_mkerr(js, "Callback must be a function"); 839 827 840 - ant_value_t ctx_ptr = js_get_slot(this_obj, SLOT_DATA); 841 - if (vtype(ctx_ptr) == T_UNDEF) return js_mkerr(js, "Invalid stream object"); 842 - 843 - child_stream_ctx_t *ctx = (child_stream_ctx_t *)(uintptr_t)js_getnum(ctx_ptr); 828 + child_stream_ctx_t *ctx = get_child_stream_ctx(this_obj); 844 829 if (!ctx || !ctx->cp) return js_mkerr(js, "Invalid stream context"); 845 830 846 831 child_process_t *cp = ctx->cp; ··· 880 865 else if (kind == CHILD_STREAM_STDOUT) cp->stdout_ctx = ctx; 881 866 else cp->stderr_ctx = ctx; 882 867 883 - js_set_slot(obj, SLOT_DATA, ANT_PTR(ctx)); 868 + js_set_native(obj, ctx, CHILD_STREAM_NATIVE_TAG); 884 869 js_set(js, obj, "on", js_mkfun(child_stream_on)); 885 870 js_set(js, obj, "once", js_mkfun(child_stream_once)); 886 871 js_set(js, obj, "ref", js_mkfun(child_stream_ref)); ··· 900 885 ant_value_t obj = js_mkobj(js); 901 886 if (is_object_type(g_child_process_proto)) js_set_proto_init(obj, g_child_process_proto); 902 887 903 - js_set_slot(obj, SLOT_DATA, ANT_PTR(cp)); 888 + js_set_native(obj, cp, CHILD_PROCESS_NATIVE_TAG); 904 889 js_set(js, obj, "pid", js_mknum((double)cp->process.pid)); 905 890 js_set(js, obj, "exitCode", js_mknull()); 906 891 js_set(js, obj, "signalCode", js_mknull());
+23 -20
src/modules/collections.c
··· 4 4 #include <math.h> 5 5 6 6 #include "ant.h" 7 + #include "ptr.h" 7 8 #include "gc.h" 8 9 #include "errors.h" 9 10 #include "runtime.h" ··· 308 309 map_entry_t **get_map_from_obj(ant_value_t obj) { 309 310 ant_object_t *ptr = js_obj_ptr(obj); 310 311 if (!ptr || ptr->type_tag != T_MAP) return NULL; 311 - return (map_entry_t **)(uintptr_t)js_getnum(ptr->u.data.value); 312 + if (!js_check_native_tag(obj, MAP_NATIVE_TAG)) return NULL; 313 + return (map_entry_t **)js_get_native_ptr(obj); 312 314 } 313 315 314 316 set_entry_t **get_set_from_obj(ant_value_t obj) { 315 317 ant_object_t *ptr = js_obj_ptr(obj); 316 318 if (!ptr || ptr->type_tag != T_SET) return NULL; 317 - return (set_entry_t **)(uintptr_t)js_getnum(ptr->u.data.value); 319 + if (!js_check_native_tag(obj, SET_NATIVE_TAG)) return NULL; 320 + return (set_entry_t **)js_get_native_ptr(obj); 318 321 } 319 322 320 323 static weakmap_entry_t **get_weakmap_from_obj(ant_value_t obj) { 321 324 ant_object_t *ptr = js_obj_ptr(obj); 322 325 if (!ptr || ptr->type_tag != T_WEAKMAP) return NULL; 323 - return (weakmap_entry_t **)(uintptr_t)js_getnum(ptr->u.data.value); 326 + if (!js_check_native_tag(obj, WEAKMAP_NATIVE_TAG)) return NULL; 327 + return (weakmap_entry_t **)js_get_native_ptr(obj); 324 328 } 325 329 326 330 static weakset_entry_t **get_weakset_from_obj(ant_value_t obj) { 327 331 ant_object_t *ptr = js_obj_ptr(obj); 328 332 if (!ptr || ptr->type_tag != T_WEAKSET) return NULL; 329 - return (weakset_entry_t **)(uintptr_t)js_getnum(ptr->u.data.value); 333 + if (!js_check_native_tag(obj, WEAKSET_NATIVE_TAG)) return NULL; 334 + return (weakset_entry_t **)js_get_native_ptr(obj); 330 335 } 331 336 332 - static map_iterator_state_t *get_map_iter_state(ant_value_t obj) { 333 - ant_value_t state_val = js_get_slot(obj, SLOT_ITER_STATE); 334 - if (vtype(state_val) == T_UNDEF) return NULL; 335 - return (map_iterator_state_t *)(uintptr_t)js_getnum(state_val); 337 + map_iterator_state_t *get_map_iter_state(ant_value_t obj) { 338 + if (!js_check_native_tag(obj, MAP_ITER_NATIVE_TAG)) return NULL; 339 + return (map_iterator_state_t *)js_get_native_ptr(obj); 336 340 } 337 341 338 - static set_iterator_state_t *get_set_iter_state(ant_value_t obj) { 339 - ant_value_t state_val = js_get_slot(obj, SLOT_ITER_STATE); 340 - if (vtype(state_val) == T_UNDEF) return NULL; 341 - return (set_iterator_state_t *)(uintptr_t)js_getnum(state_val); 342 + set_iterator_state_t *get_set_iter_state(ant_value_t obj) { 343 + if (!js_check_native_tag(obj, SET_ITER_NATIVE_TAG)) return NULL; 344 + return (set_iterator_state_t *)js_get_native_ptr(obj); 342 345 } 343 346 344 347 static ant_value_t map_set(ant_t *js, ant_value_t *args, int nargs) { ··· 529 532 530 533 ant_value_t iter = js_mkobj(js); 531 534 js_set_proto_init(iter, g_map_iter_proto); 532 - js_set_slot(iter, SLOT_ITER_STATE, ANT_PTR(state)); 535 + js_set_native(iter, state, MAP_ITER_NATIVE_TAG); 533 536 534 537 return iter; 535 538 } ··· 583 586 584 587 ant_value_t iter = js_mkobj(js); 585 588 js_set_proto_init(iter, g_set_iter_proto); 586 - js_set_slot(iter, SLOT_ITER_STATE, ANT_PTR(state)); 589 + js_set_native(iter, state, SET_ITER_NATIVE_TAG); 587 590 588 591 return iter; 589 592 } ··· 701 704 if (!set_head) return js_mkerr(js, "out of memory"); 702 705 *set_head = NULL; 703 706 704 - js_set_slot(set_obj, SLOT_DATA, ANT_PTR(set_head)); 707 + js_set_native(set_obj, set_head, SET_NATIVE_TAG); 705 708 if (out_set) *out_set = set_head; 706 709 707 710 return set_obj; ··· 1400 1403 map_entry_t **map_head = ant_calloc(sizeof(map_entry_t *)); 1401 1404 if (!map_head) return js_mkerr(js, "out of memory"); 1402 1405 *map_head = NULL; 1403 - js_set_slot(map_obj, SLOT_DATA, ANT_PTR(map_head)); 1406 + js_set_native(map_obj, map_head, MAP_NATIVE_TAG); 1404 1407 1405 1408 ant_offset_t len = js_arr_len(js, items); 1406 1409 for (ant_offset_t i = 0; i < len; i++) { ··· 1448 1451 1449 1452 if (vtype(js->new_target) == T_FUNC || vtype(js->new_target) == T_CFUNC) 1450 1453 js_set_slot(map_obj, SLOT_CTOR, js->new_target); 1451 - js_set_slot(map_obj, SLOT_DATA, ANT_PTR(map_head)); 1454 + js_set_native(map_obj, map_head, MAP_NATIVE_TAG); 1452 1455 1453 1456 if (nargs == 0 || vtype(args[0]) == T_UNDEF || vtype(args[0]) == T_NULL) return map_obj; 1454 1457 ant_value_t init_result = map_init_from_iterable(js, map_head, args[0]); ··· 1478 1481 1479 1482 if (vtype(js->new_target) == T_FUNC || vtype(js->new_target) == T_CFUNC) 1480 1483 js_set_slot(set_obj, SLOT_CTOR, js->new_target); 1481 - js_set_slot(set_obj, SLOT_DATA, ANT_PTR(set_head)); 1484 + js_set_native(set_obj, set_head, SET_NATIVE_TAG); 1482 1485 1483 1486 if (nargs == 0 || vtype(args[0]) == T_UNDEF || vtype(args[0]) == T_NULL) return set_obj; 1484 1487 ant_value_t init_result = set_init_from_iterable(js, set_head, args[0]); ··· 1508 1511 1509 1512 if (vtype(js->new_target) == T_FUNC || vtype(js->new_target) == T_CFUNC) 1510 1513 js_set_slot(wm_obj, SLOT_CTOR, js->new_target); 1511 - js_set_slot(wm_obj, SLOT_DATA, ANT_PTR(wm_head)); 1514 + js_set_native(wm_obj, wm_head, WEAKMAP_NATIVE_TAG); 1512 1515 1513 1516 if (nargs == 0 || vtype(args[0]) == T_UNDEF || vtype(args[0]) == T_NULL) return wm_obj; 1514 1517 ant_value_t init_result = weakmap_init_from_iterable(js, wm_head, args[0]); ··· 1538 1541 1539 1542 if (vtype(js->new_target) == T_FUNC || vtype(js->new_target) == T_CFUNC) 1540 1543 js_set_slot(ws_obj, SLOT_CTOR, js->new_target); 1541 - js_set_slot(ws_obj, SLOT_DATA, ANT_PTR(ws_head)); 1544 + js_set_native(ws_obj, ws_head, WEAKSET_NATIVE_TAG); 1542 1545 1543 1546 if (nargs == 0 || vtype(args[0]) == T_UNDEF || vtype(args[0]) == T_NULL) return ws_obj; 1544 1547 ant_value_t init_result = weakset_init_from_iterable(js, ws_head, args[0]);
+6 -5
src/modules/crypto.c
··· 12 12 #pragma GCC diagnostic pop 13 13 14 14 #include "ant.h" 15 + #include "ptr.h" 15 16 #include "base64.h" 16 17 #include "errors.h" 17 18 #include "runtime.h" ··· 33 34 unsigned int digest_len; 34 35 bool finalized; 35 36 } ant_hash_state_t; 37 + 38 + enum { CRYPTO_HASH_NATIVE_TAG = 0x48415348u }; // HASH 36 39 37 40 int crypto_fill_random(void *buf, size_t len) { 38 41 if (len == 0) return 0; ··· 219 222 } 220 223 221 224 static ant_hash_state_t *crypto_get_hash_state(ant_value_t value) { 222 - ant_value_t slot = js_get_slot(value, SLOT_DATA); 223 - if (vtype(slot) != T_NUM) return NULL; 224 - 225 - ant_hash_state_t *state = (ant_hash_state_t *)(uintptr_t)js_getnum(slot); 225 + if (!js_check_native_tag(value, CRYPTO_HASH_NATIVE_TAG)) return NULL; 226 + ant_hash_state_t *state = (ant_hash_state_t *)js_get_native_ptr(value); 226 227 return (state && state->ctx) ? state : NULL; 227 228 } 228 229 ··· 568 569 js_set(js, obj, "update", js_mkfun(js_hash_update)); 569 570 js_set(js, obj, "digest", js_mkfun(js_hash_digest)); 570 571 571 - js_set_slot(obj, SLOT_DATA, ANT_PTR(state)); 572 + js_set_native(obj, state, CRYPTO_HASH_NATIVE_TAG); 572 573 js_set_sym(js, obj, get_toStringTag_sym(), js_mkstr(js, "Hash", 4)); 573 574 574 575 return obj;
+12 -8
src/modules/events.c
··· 7 7 #include <utarray.h> 8 8 9 9 #include "ant.h" 10 + #include "ptr.h" 10 11 #include "errors.h" 11 12 #include "runtime.h" 12 13 #include "internal.h" ··· 34 35 static ant_value_t g_errorevent_proto = 0; 35 36 static ant_value_t g_promiserejectionevent_proto = 0; 36 37 38 + enum { 39 + EVENT_NATIVE_TAG = 0x45564e54u, // EVNT 40 + EVENT_EMITTER_NATIVE_TAG = 0x45454d54u // EEMT 41 + }; 42 + 37 43 static event_data_t *get_event_data(ant_value_t obj) { 38 - ant_value_t slot = js_get_slot(obj, SLOT_DATA); 39 - if (vtype(slot) != T_NUM) return NULL; 40 - return (event_data_t *)(uintptr_t)js_getnum(slot); 44 + if (!js_check_native_tag(obj, EVENT_NATIVE_TAG)) return NULL; 45 + return (event_data_t *)js_get_native_ptr(obj); 41 46 } 42 47 43 48 static double get_timestamp_ms(void) { ··· 150 155 } 151 156 152 157 static EventType **get_or_create_emitter_events(ant_t *js, ant_value_t this_obj) { 153 - ant_value_t slot = js_get_slot(this_obj, SLOT_DATA); 154 - if (vtype(slot) == T_UNDEF) { 158 + if (!js_check_native_tag(this_obj, EVENT_EMITTER_NATIVE_TAG)) { 155 159 EventType **events = ant_calloc(sizeof(EventType *)); 156 160 if (!events) return NULL; 157 161 *events = NULL; ··· 162 166 reg->next = emitter_registry; 163 167 emitter_registry = reg; 164 168 165 - js_set_slot(this_obj, SLOT_DATA, ANT_PTR(events)); 169 + js_set_native(this_obj, events, EVENT_EMITTER_NATIVE_TAG); 166 170 return events; 167 171 } 168 - return (EventType **)(uintptr_t)js_getnum(slot); 172 + return (EventType **)js_get_native_ptr(this_obj); 169 173 } 170 174 171 175 static EventType *find_or_create_global_event_type(ant_t *js, ant_value_t js_key) { ··· 290 294 js_set_accessor_desc(js, obj, "isTrusted", 9, g_isTrusted_getter, js_mkundef(), 0); 291 295 292 296 event_data_t *data = ant_calloc(sizeof(event_data_t)); 293 - if (data) js_set_slot(obj, SLOT_DATA, ANT_PTR(data)); 297 + if (data) js_set_native(obj, data, EVENT_NATIVE_TAG); 294 298 } 295 299 296 300 static ant_value_t js_event_ctor(ant_t *js, ant_value_t *args, int nargs) {
+15 -6
src/modules/fetch.c
··· 9 9 #include <utarray.h> 10 10 11 11 #include "ant.h" 12 + #include "ptr.h" 12 13 #include "common.h" 13 14 #include "errors.h" 14 15 #include "internal.h" ··· 44 45 bool restart_pending; 45 46 bool response_started; 46 47 } fetch_request_t; 48 + 49 + enum { FETCH_REQUEST_NATIVE_TAG = 0x46524551u }; // FREQ 47 50 48 51 static UT_array *pending_requests = NULL; 49 52 static const int k_fetch_max_redirects = 20; ··· 654 657 } 655 658 656 659 static ant_value_t fetch_upload_on_reject(ant_t *js, ant_value_t *args, int nargs) { 657 - fetch_request_t *req = (fetch_request_t *)(uintptr_t)(size_t)js_getnum(js_get_slot(js->current_func, SLOT_DATA)); 660 + fetch_request_t *req = js_check_native_tag(js->current_func, FETCH_REQUEST_NATIVE_TAG) 661 + ? (fetch_request_t *)js_get_native_ptr(js->current_func) 662 + : NULL; 658 663 ant_value_t reason = (nargs > 0) ? args[0] : js_mkundef(); 659 664 660 665 if (!req) return js_mkundef(); ··· 672 677 673 678 static void fetch_upload_schedule_next_read(fetch_request_t *req); 674 679 static ant_value_t fetch_upload_on_read(ant_t *js, ant_value_t *args, int nargs) { 675 - fetch_request_t *req = (fetch_request_t *)(uintptr_t)(size_t)js_getnum(js_get_slot(js->current_func, SLOT_DATA)); 680 + fetch_request_t *req = js_check_native_tag(js->current_func, FETCH_REQUEST_NATIVE_TAG) 681 + ? (fetch_request_t *)js_get_native_ptr(js->current_func) 682 + : NULL; 676 683 677 684 ant_value_t result = (nargs > 0) ? args[0] : js_mkundef(); 678 685 ant_value_t done = 0; ··· 732 739 next_p = rs_default_reader_read(js, req->upload_reader); 733 740 req->upload_read_promise = next_p; 734 741 735 - fulfill = js_heavy_mkfun(js, fetch_upload_on_read, ANT_PTR(req)); 736 - reject = js_heavy_mkfun(js, fetch_upload_on_reject, ANT_PTR(req)); 742 + fulfill = js_heavy_mkfun_native(js, fetch_upload_on_read, req, FETCH_REQUEST_NATIVE_TAG); 743 + reject = js_heavy_mkfun_native(js, fetch_upload_on_reject, req, FETCH_REQUEST_NATIVE_TAG); 737 744 738 745 fetch_request_retain(req); 739 746 then_result = js_promise_then(js, next_p, fulfill, reject); ··· 831 838 } 832 839 833 840 static ant_value_t fetch_abort_listener(ant_t *js, ant_value_t *args, int nargs) { 834 - fetch_request_t *req = (fetch_request_t *)(uintptr_t)(size_t)js_getnum(js_get_slot(js->current_func, SLOT_DATA)); 841 + fetch_request_t *req = js_check_native_tag(js->current_func, FETCH_REQUEST_NATIVE_TAG) 842 + ? (fetch_request_t *)js_get_native_ptr(js->current_func) 843 + : NULL; 835 844 ant_value_t signal = 0; 836 845 ant_value_t reason = 0; 837 846 ··· 894 903 return promise; 895 904 } 896 905 897 - req->abort_listener = js_heavy_mkfun(js, fetch_abort_listener, ANT_PTR(req)); 906 + req->abort_listener = js_heavy_mkfun_native(js, fetch_abort_listener, req, FETCH_REQUEST_NATIVE_TAG); 898 907 abort_signal_add_listener(js, signal, req->abort_listener); 899 908 } 900 909
+27 -16
src/modules/formdata.c
··· 5 5 #include <time.h> 6 6 7 7 #include "ant.h" 8 + #include "ptr.h" 8 9 #include "errors.h" 9 10 #include "runtime.h" 10 11 #include "internal.h" ··· 29 30 static ant_value_t g_formdata_proto = 0; 30 31 static ant_value_t g_formdata_iter_proto = 0; 31 32 static fd_data_t *get_fd_data(ant_value_t obj); 33 + 34 + enum { 35 + FORMDATA_NATIVE_TAG = 0x46444154u, // FDAT 36 + FORMDATA_ITER_NATIVE_TAG = 0x46444954u // FDIT 37 + }; 32 38 33 39 bool formdata_is_formdata(ant_t *js, ant_value_t obj) { 34 40 return js_check_brand(obj, BRAND_FORMDATA); ··· 64 70 } 65 71 66 72 static fd_data_t *get_fd_data(ant_value_t obj) { 67 - ant_value_t slot = js_get_slot(obj, SLOT_DATA); 68 - if (vtype(slot) != T_NUM) return NULL; 69 - return (fd_data_t *)(uintptr_t)(size_t)js_getnum(slot); 73 + if (!js_check_native_tag(obj, FORMDATA_NATIVE_TAG)) return NULL; 74 + return (fd_data_t *)js_get_native_ptr(obj); 75 + } 76 + 77 + // TODO: compact 78 + fd_data_t *formdata_get_data(ant_value_t fd) { 79 + return get_fd_data(fd); 70 80 } 71 81 72 82 static ant_value_t get_fd_values(ant_value_t obj) { ··· 74 84 } 75 85 76 86 static void formdata_finalize(ant_t *js, ant_object_t *obj) { 77 - ant_extra_slot_t *slot = ant_object_extra_slot(obj, SLOT_DATA); 78 - if (!slot || vtype(slot->value) != T_NUM) return; 79 - fd_data_t *d = (fd_data_t *)(uintptr_t)(size_t)js_getnum(slot->value); 87 + if (!obj || obj->native.tag != FORMDATA_NATIVE_TAG) return; 88 + fd_data_t *d = (fd_data_t *)obj->native.ptr; 80 89 fd_data_free(d); 90 + obj->native.ptr = NULL; 91 + obj->native.tag = 0; 81 92 } 82 93 83 94 static bool fd_append_str(fd_data_t *d, const char *name, const char *value) { ··· 134 145 ant_value_t obj = js_mkobj(js); 135 146 js_set_proto_init(obj, g_formdata_proto); 136 147 js_set_slot(obj, SLOT_BRAND, js_mknum(BRAND_FORMDATA)); 137 - js_set_slot(obj, SLOT_DATA, ANT_PTR(d)); 148 + js_set_native(obj, d, FORMDATA_NATIVE_TAG); 138 149 139 150 ant_value_t vals = js_mkarr(js); 140 151 js_set_slot_wb(js, obj, SLOT_ENTRIES, vals); ··· 369 380 } 370 381 371 382 static ant_value_t formdata_iter_next(ant_t *js, ant_value_t *args, int nargs) { 372 - ant_value_t state_v = js_get_slot(js->this_val, SLOT_ITER_STATE); 373 - if (vtype(state_v) != T_NUM) return js_iter_result(js, false, js_mkundef()); 383 + if (!js_check_native_tag(js->this_val, FORMDATA_ITER_NATIVE_TAG)) 384 + return js_iter_result(js, false, js_mkundef()); 374 385 375 - fd_iter_t *st = (fd_iter_t *)(uintptr_t)(size_t)js_getnum(state_v); 386 + fd_iter_t *st = (fd_iter_t *)js_get_native_ptr(js->this_val); 376 387 ant_value_t fd_obj = js_get_slot(js->this_val, SLOT_DATA); 377 388 fd_data_t *d = get_fd_data(fd_obj); 378 389 if (!d) return js_iter_result(js, false, js_mkundef()); ··· 407 418 } 408 419 409 420 static void formdata_iter_finalize(ant_t *js, ant_object_t *obj) { 410 - ant_extra_slot_t *slot = ant_object_extra_slot(obj, SLOT_ITER_STATE); 411 - if (!slot || vtype(slot->value) != T_NUM) return; 412 - fd_iter_t *st = (fd_iter_t *)(uintptr_t)(size_t)js_getnum(slot->value); 413 - free(st); 421 + if (!obj || obj->native.tag != FORMDATA_ITER_NATIVE_TAG) return; 422 + free(obj->native.ptr); 423 + obj->native.ptr = NULL; 424 + obj->native.tag = 0; 414 425 } 415 426 416 427 static ant_value_t make_formdata_iter(ant_t *js, ant_value_t fd_obj, int kind) { ··· 420 431 421 432 ant_value_t iter = js_mkobj(js); 422 433 js_set_proto_init(iter, g_formdata_iter_proto); 423 - js_set_slot(iter, SLOT_ITER_STATE, ANT_PTR(st)); 434 + js_set_native(iter, st, FORMDATA_ITER_NATIVE_TAG); 424 435 js_set_slot_wb(js, iter, SLOT_DATA, fd_obj); 425 436 js_set_finalizer(iter, formdata_iter_finalize); 426 437 return iter; ··· 452 463 453 464 if (is_object_type(proto)) js_set_proto_init(obj, proto); 454 465 js_set_slot(obj, SLOT_BRAND, js_mknum(BRAND_FORMDATA)); 455 - js_set_slot(obj, SLOT_DATA, ANT_PTR(d)); 466 + js_set_native(obj, d, FORMDATA_NATIVE_TAG); 456 467 457 468 ant_value_t vals = js_mkarr(js); 458 469 js_set_slot_wb(js, obj, SLOT_ENTRIES, vals);
+13 -9
src/modules/headers.c
··· 4 4 #include <stdio.h> 5 5 6 6 #include "ant.h" 7 + #include "ptr.h" 7 8 #include "errors.h" 8 9 #include "runtime.h" 9 10 #include "internal.h" ··· 45 46 ant_value_t g_headers_proto = 0; 46 47 ant_value_t g_headers_iter_proto = 0; 47 48 49 + enum { 50 + HEADERS_NATIVE_TAG = 0x48445253u, // HDRS 51 + HEADERS_ITER_NATIVE_TAG = 0x48444954u // HDIT 52 + }; 53 + 48 54 static hdr_list_t *list_new(void) { 49 55 hdr_list_t *l = ant_calloc(sizeof(hdr_list_t)); 50 56 if (!l) return NULL; ··· 64 70 } 65 71 66 72 static hdr_list_t *get_list(ant_value_t obj) { 67 - ant_value_t slot = js_get_slot(obj, SLOT_DATA); 68 - if (vtype(slot) != T_NUM) return NULL; 69 - return (hdr_list_t *)(uintptr_t)(size_t)js_getnum(slot); 73 + if (!js_check_native_tag(obj, HEADERS_NATIVE_TAG)) return NULL; 74 + return (hdr_list_t *)js_get_native_ptr(obj); 70 75 } 71 76 72 77 static headers_guard_t get_guard(ant_value_t obj) { ··· 474 479 } 475 480 476 481 bool advance_headers(ant_t *js, js_iter_t *it, ant_value_t *out) { 477 - ant_value_t state_val = js_get_slot(it->iterator, SLOT_ITER_STATE); 478 - if (vtype(state_val) == T_UNDEF) return false; 479 - hdr_iter_t *st = (hdr_iter_t *)(uintptr_t)(size_t)js_getnum(state_val); 482 + if (!js_check_native_tag(it->iterator, HEADERS_ITER_NATIVE_TAG)) return false; 483 + hdr_iter_t *st = (hdr_iter_t *)js_get_native_ptr(it->iterator); 480 484 481 485 size_t count = 0; 482 486 sorted_pair_t *view = build_sorted_view(st->list, &count); ··· 522 526 523 527 ant_value_t iter = js_mkobj(js); 524 528 js_set_proto_init(iter, g_headers_iter_proto); 525 - js_set_slot(iter, SLOT_ITER_STATE, ANT_PTR(st)); 529 + js_set_native(iter, st, HEADERS_ITER_NATIVE_TAG); 526 530 return iter; 527 531 } 528 532 ··· 812 816 if (is_object_type(proto)) js_set_proto_init(obj, proto); 813 817 814 818 js_set_slot(obj, SLOT_BRAND, js_mknum(BRAND_HEADERS)); 815 - js_set_slot(obj, SLOT_DATA, ANT_PTR(l)); 819 + js_set_native(obj, l, HEADERS_NATIVE_TAG); 816 820 js_set_slot(obj, SLOT_HEADERS_GUARD, js_mknum(HEADERS_GUARD_NONE)); 817 821 818 822 return obj; ··· 825 829 ant_value_t obj = js_mkobj(js); 826 830 js_set_proto_init(obj, g_headers_proto); 827 831 js_set_slot(obj, SLOT_BRAND, js_mknum(BRAND_HEADERS)); 828 - js_set_slot(obj, SLOT_DATA, ANT_PTR(l)); 832 + js_set_native(obj, l, HEADERS_NATIVE_TAG); 829 833 js_set_slot(obj, SLOT_HEADERS_GUARD, js_mknum(HEADERS_GUARD_NONE)); 830 834 831 835 return obj;
+10 -3
src/modules/lmdb.c
··· 1 1 #include <compat.h> // IWYU pragma: keep 2 2 3 3 #include "ant.h" 4 + #include "ptr.h" 4 5 #include "errors.h" 5 6 #include "internal.h" 6 7 #include "modules/lmdb.h" ··· 68 69 static lmdb_env_ref_t *env_refs = NULL; 69 70 static lmdb_db_ref_t *db_refs = NULL; 70 71 static lmdb_txn_ref_t *txn_refs = NULL; 72 + 73 + enum { 74 + LMDB_ENV_NATIVE_TAG = 0x4c454e56u, // LENV 75 + LMDB_DB_NATIVE_TAG = 0x4c444242u, // LDBB 76 + LMDB_TXN_NATIVE_TAG = 0x4c54584eu // LTXN 77 + }; 71 78 72 79 static ant_value_t make_env_obj(ant_t *js, lmdb_env_handle_t *env); 73 80 static ant_value_t make_db_obj(ant_t *js, lmdb_db_handle_t *db); ··· 1033 1040 static ant_value_t make_env_obj(ant_t *js, lmdb_env_handle_t *env) { 1034 1041 ensure_lmdb_prototypes(js); 1035 1042 ant_value_t obj = js_mkobj(js); 1036 - js_set_slot(obj, SLOT_DATA, ANT_PTR(env)); 1043 + js_set_native(obj, env, LMDB_ENV_NATIVE_TAG); 1037 1044 register_env_ref(obj, env); 1038 1045 if (is_special_object(lmdb_types.env_proto)) js_set_proto_init(obj, lmdb_types.env_proto); 1039 1046 return obj; ··· 1042 1049 static ant_value_t make_db_obj(ant_t *js, lmdb_db_handle_t *db) { 1043 1050 ensure_lmdb_prototypes(js); 1044 1051 ant_value_t obj = js_mkobj(js); 1045 - js_set_slot(obj, SLOT_DATA, ANT_PTR(db)); 1052 + js_set_native(obj, db, LMDB_DB_NATIVE_TAG); 1046 1053 register_db_ref(obj, db); 1047 1054 if (is_special_object(lmdb_types.db_proto)) js_set_proto_init(obj, lmdb_types.db_proto); 1048 1055 return obj; ··· 1051 1058 static ant_value_t make_txn_obj(ant_t *js, lmdb_txn_handle_t *txn) { 1052 1059 ensure_lmdb_prototypes(js); 1053 1060 ant_value_t obj = js_mkobj(js); 1054 - js_set_slot(obj, SLOT_DATA, ANT_PTR(txn)); 1061 + js_set_native(obj, txn, LMDB_TXN_NATIVE_TAG); 1055 1062 register_txn_ref(obj, txn); 1056 1063 if (is_special_object(lmdb_types.txn_proto)) js_set_proto_init(obj, lmdb_types.txn_proto); 1057 1064 return obj;
+1 -5
src/modules/multipart.c
··· 530 530 ant_t *js, ant_value_t fd, size_t *out_size, char **out_boundary 531 531 ) { 532 532 ant_value_t values_arr = js_get_slot(fd, SLOT_ENTRIES); 533 - ant_value_t data_slot = js_get_slot(fd, SLOT_DATA); 534 533 char boundary[49]; 535 534 536 535 mp_buf_t b = {NULL, 0, 0}; 537 - fd_data_t *d = NULL; 538 - 539 - if (vtype(data_slot) != T_NUM) return NULL; 540 - d = (fd_data_t *)(uintptr_t)(size_t)js_getnum(data_slot); 536 + fd_data_t *d = formdata_get_data(fd); 541 537 if (!d) return NULL; 542 538 543 539 snprintf(
+10 -6
src/modules/napi.c
··· 39 39 #endif 40 40 41 41 #include "ant.h" 42 + #include "ptr.h" 42 43 #include "descriptors.h" 43 44 #include "errors.h" 44 45 #include "internal.h" ··· 221 222 uint32_t limbs[]; 222 223 } napi_bigint_payload_t; 223 224 225 + enum { NAPI_CALLBACK_NATIVE_TAG = 0x4e43424bu }; // NCBK 226 + 224 227 static ant_napi_env_t *g_napi_env = NULL; 225 228 static napi_external_entry_t *g_napi_externals = NULL; 226 229 static napi_wrap_entry_t *g_napi_wraps = NULL; 230 + 227 231 static uint64_t g_napi_external_next_id = 1; 228 232 static uint64_t g_napi_wrap_next_id = 1; 233 + static int64_t g_napi_external_memory = 0; 234 + 229 235 static napi_native_lib_t *g_napi_native_libs = NULL; 230 236 static napi_module *g_pending_napi_module = NULL; 231 - static int64_t g_napi_external_memory = 0; 232 237 233 238 static const napi_node_version g_napi_node_version = { 234 239 .major = 25, 235 - .minor = 0, 240 + .minor = 9, 236 241 .patch = 0, 237 242 .release = "ant", 238 243 }; ··· 476 481 477 482 static ant_value_t napi_callback_trampoline(ant_t *js, ant_value_t *args, int nargs) { 478 483 ant_value_t current = js_getcurrentfunc(js); 479 - ant_value_t data_slot = js_get_slot(current, SLOT_DATA); 480 - if (vtype(data_slot) != T_NUM) return js_mkundef(); 484 + if (!js_check_native_tag(current, NAPI_CALLBACK_NATIVE_TAG)) return js_mkundef(); 481 485 482 - napi_callback_binding_t *binding = (napi_callback_binding_t *)(uintptr_t)js_getnum(data_slot); 486 + napi_callback_binding_t *binding = (napi_callback_binding_t *)js_get_native_ptr(current); 483 487 if (!binding || !binding->cb) return js_mkundef(); 484 488 485 489 ant_napi_env_t *nenv = binding->env ? binding->env : napi_get_or_create_env(js); ··· 530 534 binding->cb = cb; 531 535 binding->data = data; 532 536 533 - ant_value_t fn = js_heavy_mkfun(nenv->js, napi_callback_trampoline, ANT_PTR(binding)); 537 + ant_value_t fn = js_heavy_mkfun_native(nenv->js, napi_callback_trampoline, binding, NAPI_CALLBACK_NATIVE_TAG); 534 538 js_mark_constructor(fn, true); 535 539 if (utf8name && utf8name[0]) { 536 540 size_t nlen = (length == NAPI_AUTO_LENGTH) ? strlen(utf8name) : length;
+9 -7
src/modules/request.c
··· 5 5 #include <stdio.h> 6 6 7 7 #include "ant.h" 8 + #include "ptr.h" 8 9 #include "errors.h" 9 10 #include "runtime.h" 10 11 #include "internal.h" ··· 27 28 28 29 ant_value_t g_request_proto = 0; 29 30 31 + enum { REQUEST_NATIVE_TAG = 0x52455153u }; // REQS 32 + 30 33 static request_data_t *get_data(ant_value_t obj) { 31 - ant_value_t slot = js_get_slot(obj, SLOT_DATA); 32 - if (vtype(slot) != T_NUM) return NULL; 33 - return (request_data_t *)(uintptr_t)(size_t)js_getnum(slot); 34 + if (!js_check_native_tag(obj, REQUEST_NATIVE_TAG)) return NULL; 35 + return (request_data_t *)js_get_native_ptr(obj); 34 36 } 35 37 36 38 request_data_t *request_get_data(ant_value_t obj) { ··· 109 111 110 112 js_set_proto_init(obj, g_request_proto); 111 113 js_set_slot(obj, SLOT_BRAND, js_mknum(BRAND_REQUEST)); 112 - js_set_slot(obj, SLOT_DATA, ANT_PTR(req)); 114 + js_set_native(obj, req, REQUEST_NATIVE_TAG); 113 115 114 116 headers_set_guard(hdrs, 115 117 strcmp(req->mode, "no-cors") == 0 ··· 938 940 ant_value_t obj = js_mkobj(js); 939 941 js_set_proto_init(obj, g_request_proto); 940 942 js_set_slot(obj, SLOT_BRAND, js_mknum(BRAND_REQUEST)); 941 - js_set_slot(obj, SLOT_DATA, ANT_PTR(nd)); 943 + js_set_native(obj, nd, REQUEST_NATIVE_TAG); 942 944 943 945 js_set_slot_wb(js, obj, SLOT_REQUEST_HEADERS, new_headers); 944 946 js_set_slot(obj, SLOT_REQUEST_ABORT_REASON, js_mkundef()); ··· 1297 1299 else js_set_proto_init(obj, g_request_proto); 1298 1300 1299 1301 js_set_slot(obj, SLOT_BRAND, js_mknum(BRAND_REQUEST)); 1300 - js_set_slot(obj, SLOT_DATA, ANT_PTR(req)); 1302 + js_set_native(obj, req, REQUEST_NATIVE_TAG); 1301 1303 js_set_slot(obj, SLOT_REQUEST_ABORT_REASON, js_mkundef()); 1302 1304 1303 1305 signal = abort_signal_create_dependent(js, input_signal); ··· 1375 1377 obj = js_mkobj(js); 1376 1378 js_set_proto_init(obj, g_request_proto); 1377 1379 js_set_slot(obj, SLOT_BRAND, js_mknum(BRAND_REQUEST)); 1378 - js_set_slot(obj, SLOT_DATA, ANT_PTR(req)); 1380 + js_set_native(obj, req, REQUEST_NATIVE_TAG); 1379 1381 js_set_slot(obj, SLOT_REQUEST_ABORT_REASON, js_mkundef()); 1380 1382 1381 1383 signal = abort_signal_create_dependent(js, input_signal);
+7 -5
src/modules/response.c
··· 5 5 #include <stdio.h> 6 6 7 7 #include "ant.h" 8 + #include "ptr.h" 8 9 #include "errors.h" 9 10 #include "runtime.h" 10 11 #include "internal.h" ··· 27 28 28 29 ant_value_t g_response_proto = 0; 29 30 31 + enum { RESPONSE_NATIVE_TAG = 0x52455350u }; // RESP 32 + 30 33 static response_data_t *get_data(ant_value_t obj) { 31 - ant_value_t slot = js_get_slot(obj, SLOT_DATA); 32 - if (vtype(slot) != T_NUM) return NULL; 33 - return (response_data_t *)(uintptr_t)(size_t)js_getnum(slot); 34 + if (!js_check_native_tag(obj, RESPONSE_NATIVE_TAG)) return NULL; 35 + return (response_data_t *)js_get_native_ptr(obj); 34 36 } 35 37 36 38 response_data_t *response_get_data(ant_value_t obj) { ··· 725 727 obj = js_mkobj(js); 726 728 js_set_proto_init(obj, g_response_proto); 727 729 js_set_slot(obj, SLOT_BRAND, js_mknum(BRAND_RESPONSE)); 728 - js_set_slot(obj, SLOT_DATA, ANT_PTR(resp)); 730 + js_set_native(obj, resp, RESPONSE_NATIVE_TAG); 729 731 730 732 headers = headers_create_empty(js); 731 733 if (is_err(headers)) { ··· 1053 1055 obj = js_mkobj(js); 1054 1056 js_set_proto_init(obj, g_response_proto); 1055 1057 js_set_slot(obj, SLOT_BRAND, js_mknum(BRAND_RESPONSE)); 1056 - js_set_slot(obj, SLOT_DATA, ANT_PTR(nd)); 1058 + js_set_native(obj, nd, RESPONSE_NATIVE_TAG); 1057 1059 js_set_slot_wb(js, obj, SLOT_RESPONSE_HEADERS, new_headers); 1058 1060 js_set_slot_wb(js, obj, SLOT_RESPONSE_BODY_STREAM, js_mkundef()); 1059 1061
+10 -7
src/modules/string_decoder.c
··· 4 4 #include <stdbool.h> 5 5 6 6 #include "ant.h" 7 + #include "ptr.h" 7 8 #include "base64.h" 8 9 #include "errors.h" 9 10 #include "internal.h" ··· 30 31 31 32 static ant_value_t g_string_decoder_proto = 0; 32 33 34 + enum { STRING_DECODER_NATIVE_TAG = 0x53444543u }; // SDEC 35 + 33 36 static sd_state_t *sd_get_state(ant_value_t obj) { 34 - ant_value_t s = js_get_slot(obj, SLOT_DATA); 35 - if (vtype(s) != T_NUM) return NULL; 36 - return (sd_state_t *)(uintptr_t)(size_t)js_getnum(s); 37 + if (!js_check_native_tag(obj, STRING_DECODER_NATIVE_TAG)) return NULL; 38 + return (sd_state_t *)js_get_native_ptr(obj); 37 39 } 38 40 39 41 static void sd_finalize(ant_t *js, ant_object_t *obj) { 40 - ant_extra_slot_t *slot = ant_object_extra_slot(obj, SLOT_DATA); 41 - if (!slot || vtype(slot->value) != T_NUM) return; 42 - sd_state_t *st = (sd_state_t *)(uintptr_t)(size_t)js_getnum(slot->value); 42 + if (!obj || obj->native.tag != STRING_DECODER_NATIVE_TAG) return; 43 + sd_state_t *st = (sd_state_t *)obj->native.ptr; 43 44 if (st) { free(st->td); free(st); } 45 + obj->native.ptr = NULL; 46 + obj->native.tag = 0; 44 47 } 45 48 46 49 static int sd_parse_encoding(const char *s, size_t len) { ··· 225 228 ant_value_t proto = js_instance_proto_from_new_target(js, g_string_decoder_proto); 226 229 227 230 if (is_object_type(proto)) js_set_proto_init(obj, proto); 228 - js_set_slot(obj, SLOT_DATA, ANT_PTR(st)); 231 + js_set_native(obj, st, STRING_DECODER_NATIVE_TAG); 229 232 js_set_finalizer(obj, sd_finalize); 230 233 231 234 return obj;
+3 -2
src/modules/structured-clone.c
··· 4 4 #include <uthash.h> 5 5 6 6 #include "ant.h" 7 + #include "ptr.h" 7 8 #include "errors.h" 8 9 #include "runtime.h" 9 10 #include "internal.h" ··· 190 191 if (!new_head) return js_mkerr(js, "out of memory"); 191 192 192 193 *new_head = NULL; 193 - js_set_slot(clone, SLOT_DATA, ANT_PTR(new_head)); 194 + js_set_native(clone, new_head, MAP_NATIVE_TAG); 194 195 sc_add(seen, val, clone); 195 196 196 197 map_entry_t **src_head = get_map_from_obj(val); ··· 226 227 set_entry_t **new_head = ant_calloc(sizeof(set_entry_t *)); 227 228 if (!new_head) return js_mkerr(js, "out of memory"); 228 229 *new_head = NULL; 229 - js_set_slot(clone, SLOT_DATA, ANT_PTR(new_head)); 230 + js_set_native(clone, new_head, SET_NATIVE_TAG); 230 231 sc_add(seen, val, clone); 231 232 232 233 set_entry_t **src_head = get_set_from_obj(val);
+10 -7
src/modules/textcodec.c
··· 3 3 #include <stdint.h> 4 4 5 5 #include "ant.h" 6 + #include "ptr.h" 6 7 #include "errors.h" 7 8 #include "runtime.h" 8 9 #include "internal.h" ··· 16 17 static ant_value_t g_textencoder_proto = 0; 17 18 static ant_value_t g_textdecoder_proto = 0; 18 19 20 + enum { TEXT_DECODER_NATIVE_TAG = 0x54444543u }; // TDEC 21 + 19 22 td_state_t *td_state_new(td_encoding_t enc, bool fatal, bool ignore_bom) { 20 23 td_state_t *st = calloc(1, sizeof(td_state_t)); 21 24 if (!st) return NULL; ··· 26 29 } 27 30 28 31 static td_state_t *td_get_state(ant_value_t obj) { 29 - ant_value_t s = js_get_slot(obj, SLOT_DATA); 30 - if (vtype(s) != T_NUM) return NULL; 31 - return (td_state_t *)(uintptr_t)(size_t)js_getnum(s); 32 + if (!js_check_native_tag(obj, TEXT_DECODER_NATIVE_TAG)) return NULL; 33 + return (td_state_t *)js_get_native_ptr(obj); 32 34 } 33 35 34 36 static void td_finalize(ant_t *js, ant_object_t *obj) { 35 - ant_extra_slot_t *slot = ant_object_extra_slot(obj, SLOT_DATA); 36 - if (!slot || vtype(slot->value) != T_NUM) return; 37 - free((td_state_t *)(uintptr_t)(size_t)js_getnum(slot->value)); 37 + if (!obj || obj->native.tag != TEXT_DECODER_NATIVE_TAG) return; 38 + free(obj->native.ptr); 39 + obj->native.ptr = NULL; 40 + obj->native.tag = 0; 38 41 } 39 42 40 43 static int resolve_encoding(const char *s, size_t len) { ··· 426 429 ant_value_t proto = js_instance_proto_from_new_target(js, g_textdecoder_proto); 427 430 428 431 if (is_object_type(proto)) js_set_proto_init(obj, proto); 429 - js_set_slot(obj, SLOT_DATA, ANT_PTR(st)); 432 + js_set_native(obj, st, TEXT_DECODER_NATIVE_TAG); 430 433 js_set_finalizer(obj, td_finalize); 431 434 432 435 return obj;
+11 -8
src/modules/url.c
··· 7 7 #include <uriparser/Uri.h> 8 8 9 9 #include "ant.h" 10 + #include "ptr.h" 10 11 #include "errors.h" 11 12 #include "internal.h" 12 13 #include "runtime.h" ··· 20 21 static ant_value_t g_usp_proto = 0; 21 22 static ant_value_t g_usp_iter_proto = 0; 22 23 24 + enum { URL_NATIVE_TAG = 0x55524c53u }; // URLS 25 + 23 26 enum { 24 27 USP_ITER_ENTRIES = 0, 25 28 USP_ITER_KEYS = 1, ··· 27 30 }; 28 31 29 32 url_state_t *url_get_state(ant_value_t obj) { 30 - ant_value_t slot = js_get_slot(obj, SLOT_DATA); 31 - if (vtype(slot) != T_NUM) return NULL; 32 - return (url_state_t *)(uintptr_t)(size_t)js_getnum(slot); 33 + if (!js_check_native_tag(obj, URL_NATIVE_TAG)) return NULL; 34 + return (url_state_t *)js_get_native_ptr(obj); 33 35 } 34 36 35 37 bool usp_is_urlsearchparams(ant_t *js, ant_value_t obj) { ··· 49 51 } 50 52 51 53 static void url_finalize(ant_t *js, ant_object_t *obj) { 52 - ant_extra_slot_t *slot = ant_object_extra_slot(obj, SLOT_DATA); 53 - if (!slot || vtype(slot->value) != T_NUM) return; 54 - url_free_state((url_state_t *)(uintptr_t)(size_t)js_getnum(slot->value)); 54 + if (!obj || obj->native.tag != URL_NATIVE_TAG) return; 55 + url_free_state((url_state_t *)obj->native.ptr); 56 + obj->native.ptr = NULL; 57 + obj->native.tag = 0; 55 58 } 56 59 57 60 static int default_port_for(const char *proto) { ··· 979 982 980 983 ant_value_t obj = js_mkobj(js); 981 984 js_set_proto_init(obj, g_url_proto); 982 - js_set_slot(obj, SLOT_DATA, ANT_PTR(s)); 985 + js_set_native(obj, s, URL_NATIVE_TAG); 983 986 js_set_finalizer(obj, url_finalize); 984 987 985 988 const char *query = (s->search && s->search[0] == '?') ? s->search + 1 : ""; ··· 992 995 ant_value_t make_url_obj(ant_t *js, url_state_t *s) { 993 996 ant_value_t obj = js_mkobj(js); 994 997 js_set_proto_init(obj, g_url_proto); 995 - js_set_slot(obj, SLOT_DATA, ANT_PTR(s)); 998 + js_set_native(obj, s, URL_NATIVE_TAG); 996 999 js_set_finalizer(obj, url_finalize); 997 1000 const char *query = (s->search && s->search[0] == '?') ? s->search + 1 : ""; 998 1001 ant_value_t usp = make_usp_for_url(js, obj, query);
+27 -30
src/modules/wasm.c
··· 68 68 bool own_func; 69 69 } wasm_func_handle_t; 70 70 71 - enum { WASM_FUNC_STATE_TAG = 0x57465354u }; // WFST 71 + enum { 72 + WASM_FUNC_STATE_TAG = 0x57465354u, // WFST 73 + WASM_MODULE_NATIVE_TAG = 0x574d4f44u, // WMOD 74 + WASM_INSTANCE_NATIVE_TAG = 0x57494e53u, // WINS 75 + WASM_EXTERN_NATIVE_TAG = 0x57455854u // WEXT 76 + }; 72 77 73 78 static size_t g_wasm_import_env_count = 0; 74 79 static size_t g_wasm_import_env_cap = 0; ··· 173 178 174 179 static wasm_module_handle_t *wasm_module_handle(ant_value_t value) { 175 180 if (!js_check_brand(value, BRAND_WASM_MODULE)) return NULL; 176 - ant_value_t slot = js_get_slot(value, SLOT_DATA); 177 - if (vtype(slot) != T_NUM) return NULL; 178 - return (wasm_module_handle_t *)(uintptr_t)(size_t)js_getnum(slot); 181 + if (!js_check_native_tag(value, WASM_MODULE_NATIVE_TAG)) return NULL; 182 + return (wasm_module_handle_t *)js_get_native_ptr(value); 179 183 } 180 184 181 185 static wasm_instance_handle_t *wasm_instance_handle(ant_value_t value) { 182 186 if (!js_check_brand(value, BRAND_WASM_INSTANCE)) return NULL; 183 - ant_value_t slot = js_get_slot(value, SLOT_DATA); 184 - if (vtype(slot) != T_NUM) return NULL; 185 - return (wasm_instance_handle_t *)(uintptr_t)(size_t)js_getnum(slot); 187 + if (!js_check_native_tag(value, WASM_INSTANCE_NATIVE_TAG)) return NULL; 188 + return (wasm_instance_handle_t *)js_get_native_ptr(value); 186 189 } 187 190 188 191 static wasm_extern_handle_t *wasm_extern_handle(ant_value_t value, wasm_extern_wrap_kind_t kind) { ··· 192 195 return NULL; 193 196 } 194 197 195 - ant_value_t slot = js_get_slot(value, SLOT_DATA); 196 - if (vtype(slot) != T_NUM) return NULL; 197 - wasm_extern_handle_t *handle = (wasm_extern_handle_t *)(uintptr_t)(size_t)js_getnum(slot); 198 + if (!js_check_native_tag(value, WASM_EXTERN_NATIVE_TAG)) return NULL; 199 + wasm_extern_handle_t *handle = (wasm_extern_handle_t *)js_get_native_ptr(value); 198 200 return handle && handle->kind == kind ? handle : NULL; 199 201 } 200 202 ··· 368 370 ant_value_t obj = js_mkobj(js); 369 371 js_set_proto_init(obj, g_wasm_module_proto); 370 372 js_set_slot(obj, SLOT_BRAND, js_mknum(BRAND_WASM_MODULE)); 371 - js_set_slot(obj, SLOT_DATA, ANT_PTR(handle)); 373 + js_set_native(obj, handle, WASM_MODULE_NATIVE_TAG); 372 374 return obj; 373 375 } 374 376 375 377 static void wasm_module_finalize(ant_t *js, ant_object_t *obj) { 376 - ant_extra_slot_t *slot = ant_object_extra_slot(obj, SLOT_DATA); 377 - if (!slot || vtype(slot->value) != T_NUM) return; 378 - 379 - wasm_module_handle_t *handle = 380 - (wasm_module_handle_t *)(uintptr_t)(size_t)js_getnum(slot->value); 381 - 378 + if (!obj || obj->native.tag != WASM_MODULE_NATIVE_TAG) return; 379 + wasm_module_handle_t *handle = (wasm_module_handle_t *)obj->native.ptr; 382 380 if (!handle) return; 383 381 if (handle->module) wasm_module_delete(handle->module); 384 382 if (handle->store) wasm_store_delete(handle->store); 385 383 386 384 free(handle); 385 + obj->native.ptr = NULL; 386 + obj->native.tag = 0; 387 387 } 388 388 389 389 static ant_value_t wasm_wrap_instance(ant_t *js, wasm_instance_handle_t *handle, ant_value_t module_ref) { 390 390 ant_value_t obj = js_mkobj(js); 391 391 js_set_proto_init(obj, g_wasm_instance_proto); 392 392 js_set_slot(obj, SLOT_BRAND, js_mknum(BRAND_WASM_INSTANCE)); 393 - js_set_slot(obj, SLOT_DATA, ANT_PTR(handle)); 393 + js_set_native(obj, handle, WASM_INSTANCE_NATIVE_TAG); 394 394 js_set_slot_wb(js, obj, SLOT_CTOR, module_ref); 395 395 return obj; 396 396 } 397 397 398 398 static void wasm_instance_finalize(ant_t *js, ant_object_t *obj) { 399 - ant_extra_slot_t *slot = ant_object_extra_slot(obj, SLOT_DATA); 400 - if (!slot || vtype(slot->value) != T_NUM) return; 401 - 402 - wasm_instance_handle_t *handle = 403 - (wasm_instance_handle_t *)(uintptr_t)(size_t)js_getnum(slot->value); 404 - 399 + if (!obj || obj->native.tag != WASM_INSTANCE_NATIVE_TAG) return; 400 + wasm_instance_handle_t *handle = (wasm_instance_handle_t *)obj->native.ptr; 405 401 if (!handle) return; 406 402 for (size_t j = 0; j < handle->host_func_count; j++) 407 403 if (handle->host_funcs[j]) wasm_func_delete(handle->host_funcs[j]); ··· 409 405 free(handle->host_funcs); 410 406 wasm_extern_vec_delete(&handle->exports); 411 407 free(handle); 408 + obj->native.ptr = NULL; 409 + obj->native.tag = 0; 412 410 } 413 411 414 412 static ant_value_t wasm_wrap_extern_object(ant_t *js, wasm_extern_wrap_kind_t kind, ant_value_t proto, int brand, wasm_store_t *store, bool own_handle, void *ptr, ant_value_t owner) { ··· 429 427 ant_value_t obj = js_mkobj(js); 430 428 js_set_proto_init(obj, proto); 431 429 js_set_slot(obj, SLOT_BRAND, js_mknum(brand)); 432 - js_set_slot(obj, SLOT_DATA, ANT_PTR(handle)); 430 + js_set_native(obj, handle, WASM_EXTERN_NATIVE_TAG); 433 431 if (is_object_type(owner)) js_set_slot_wb(js, obj, SLOT_ENTRIES, owner); 434 432 return obj; 435 433 } 436 434 437 435 static void wasm_extern_finalize(ant_t *js, ant_object_t *obj) { 438 - ant_extra_slot_t *slot = ant_object_extra_slot(obj, SLOT_DATA); 439 - if (!slot || vtype(slot->value) != T_NUM) return; 440 - 441 - wasm_extern_handle_t *handle = 442 - (wasm_extern_handle_t *)(uintptr_t)(size_t)js_getnum(slot->value); 436 + if (!obj || obj->native.tag != WASM_EXTERN_NATIVE_TAG) return; 437 + wasm_extern_handle_t *handle = (wasm_extern_handle_t *)obj->native.ptr; 443 438 if (!handle) return; 444 439 445 440 if (handle->own_handle) { ··· 458 453 } 459 454 460 455 free(handle); 456 + obj->native.ptr = NULL; 457 + obj->native.tag = 0; 461 458 } 462 459 463 460 static ant_value_t js_wasm_exported_func_call(ant_t *js, ant_value_t *args, int nargs) {
+6 -4
src/modules/worker_threads.c
··· 23 23 #endif 24 24 25 25 #include "ant.h" 26 + #include "ptr.h" 26 27 #include "internal.h" 27 28 #include "runtime.h" 28 29 #include "descriptors.h" ··· 61 62 62 63 static ant_worker_thread_t *active_workers_head = NULL; 63 64 65 + enum { WORKER_NATIVE_TAG = 0x57524b52u }; // WRKR 66 + 64 67 static bool wt_is_worker_mode(void) { 65 68 const char *mode = getenv(WT_ENV_MODE); 66 69 return mode && strcmp(mode, "1") == 0; ··· 90 93 91 94 static ant_worker_thread_t *wt_get_worker(ant_t *js, ant_value_t this_obj) { 92 95 if (!is_object_type(this_obj)) return NULL; 93 - ant_value_t data = js_get_slot(this_obj, SLOT_DATA); 94 - if (vtype(data) != T_NUM) return NULL; 95 - return (ant_worker_thread_t *)(uintptr_t)js_getnum(data); 96 + if (!js_check_native_tag(this_obj, WORKER_NATIVE_TAG)) return NULL; 97 + return (ant_worker_thread_t *)js_get_native_ptr(this_obj); 96 98 } 97 99 98 100 static bool wt_is_message_port(ant_t *js, ant_value_t obj) { ··· 836 838 837 839 wt->js = js; 838 840 wt->self_val = this_obj; 839 - js_set_slot(this_obj, SLOT_DATA, ANT_PTR(wt)); 841 + js_set_native(this_obj, wt, WORKER_NATIVE_TAG); 840 842 841 843 wt->prev = NULL; 842 844 wt->next = active_workers_head;
+6 -4
src/silver/glue.c
··· 258 258 } 259 259 260 260 case SV_ITER_MAP: { 261 - map_iterator_state_t *st = (map_iterator_state_t *)(uintptr_t)js_getnum(iter_buf[0]); 261 + map_iterator_state_t *st = get_map_iter_state(iter_buf[0]); 262 + if (!st) return js_mkerr(js, "Invalid Map iterator"); 262 263 if (!st->current) { 263 264 *out_value = js_mkundef(); 264 265 *out_done = true; ··· 291 292 } 292 293 293 294 case SV_ITER_SET: { 294 - set_iterator_state_t *st = (set_iterator_state_t *)(uintptr_t)js_getnum(iter_buf[0]); 295 + set_iterator_state_t *st = get_set_iter_state(iter_buf[0]); 296 + if (!st) return js_mkerr(js, "Invalid Set iterator"); 295 297 if (!st->current) { 296 298 *out_value = js_mkundef(); 297 299 *out_done = true; ··· 441 443 map_iterator_state_t *map_st; 442 444 iter_type_t map_type; 443 445 if (sv_is_map_iter(js, iterator, &map_st, &map_type)) { 444 - iter_buf[0] = ANT_PTR(map_st); 446 + iter_buf[0] = iterator; 445 447 iter_buf[1] = tov((double)map_type); 446 448 iter_buf[2] = tov(SV_ITER_MAP); 447 449 GC_ROOT_RESTORE(js, root_mark); ··· 451 453 set_iterator_state_t *set_st; 452 454 iter_type_t set_type; 453 455 if (sv_is_set_iter(js, iterator, &set_st, &set_type)) { 454 - iter_buf[0] = ANT_PTR(set_st); 456 + iter_buf[0] = iterator; 455 457 iter_buf[1] = tov((double)set_type); 456 458 iter_buf[2] = tov(SV_ITER_SET); 457 459 GC_ROOT_RESTORE(js, root_mark);
+8 -14
src/silver/ops/iteration.h
··· 31 31 if (vtype(obj) != T_OBJ) return false; 32 32 if (!g_map_iter_proto || js_get_proto(js, obj) != g_map_iter_proto) return false; 33 33 34 - ant_value_t state_val = js_get_slot(obj, SLOT_ITER_STATE); 35 - if (vtype(state_val) == T_UNDEF) return false; 36 - 37 - map_iterator_state_t *st = (map_iterator_state_t *)(uintptr_t)js_getnum(state_val); 34 + map_iterator_state_t *st = get_map_iter_state(obj); 38 35 if (!st) return false; 39 36 40 37 *out_state = st; ··· 51 48 if (vtype(obj) != T_OBJ) return false; 52 49 if (!g_set_iter_proto || js_get_proto(js, obj) != g_set_iter_proto) return false; 53 50 54 - ant_value_t state_val = js_get_slot(obj, SLOT_ITER_STATE); 55 - if (vtype(state_val) == T_UNDEF) return false; 56 - 57 - set_iterator_state_t *st = (set_iterator_state_t *)(uintptr_t)js_getnum(state_val); 51 + set_iterator_state_t *st = get_set_iter_state(obj); 58 52 if (!st) return false; 59 53 60 54 *out_state = st; ··· 93 87 map_iterator_state_t *map_st; 94 88 iter_type_t map_type; 95 89 if (sv_is_map_iter(js, iterator, &map_st, &map_type)) { 96 - vm->stack[vm->sp++] = ANT_PTR(map_st); 90 + vm->stack[vm->sp++] = iterator; 97 91 vm->stack[vm->sp++] = tov((double)map_type); 98 92 vm->stack[vm->sp++] = tov(SV_ITER_MAP); 99 93 return tov(0); ··· 102 96 set_iterator_state_t *set_st; 103 97 iter_type_t set_type; 104 98 if (sv_is_set_iter(js, iterator, &set_st, &set_type)) { 105 - vm->stack[vm->sp++] = ANT_PTR(set_st); 99 + vm->stack[vm->sp++] = iterator; 106 100 vm->stack[vm->sp++] = tov((double)set_type); 107 101 vm->stack[vm->sp++] = tov(SV_ITER_SET); 108 102 return tov(0); ··· 180 174 } 181 175 182 176 case SV_ITER_MAP: { 183 - map_iterator_state_t *st = 184 - (map_iterator_state_t *)(uintptr_t)js_getnum(vm->stack[vm->sp - 3]); 177 + map_iterator_state_t *st = get_map_iter_state(vm->stack[vm->sp - 3]); 178 + if (!st) return js_mkerr(js, "Invalid Map iterator"); 185 179 if (!st->current) { 186 180 *out_value = js_mkundef(); 187 181 *out_done = true; ··· 213 207 } 214 208 215 209 case SV_ITER_SET: { 216 - set_iterator_state_t *st = 217 - (set_iterator_state_t *)(uintptr_t)js_getnum(vm->stack[vm->sp - 3]); 210 + set_iterator_state_t *st = get_set_iter_state(vm->stack[vm->sp - 3]); 211 + if (!st) return js_mkerr(js, "Invalid Set iterator"); 218 212 if (!st->current) { 219 213 *out_value = js_mkundef(); 220 214 *out_done = true;
+27 -26
src/streams/codec.c
··· 2 2 #include <string.h> 3 3 4 4 #include "ant.h" 5 + #include "ptr.h" 5 6 #include "errors.h" 6 7 #include "runtime.h" 7 8 #include "internal.h" ··· 16 17 ant_value_t g_tes_proto; 17 18 ant_value_t g_tds_proto; 18 19 20 + enum { 21 + TES_NATIVE_TAG = 0x54455354u, // TEST 22 + TDS_NATIVE_TAG = 0x54445354u // TDST 23 + }; 24 + 19 25 typedef struct { 20 26 uint8_t pending[3]; 21 27 uint8_t pending_len; ··· 31 37 32 38 bool tes_is_stream(ant_value_t obj) { 33 39 return is_object_type(obj) 34 - && vtype(js_get_slot(obj, SLOT_DATA)) == T_NUM 40 + && js_check_native_tag(obj, TES_NATIVE_TAG) 35 41 && ts_is_stream(tes_get_ts(obj)); 36 42 } 37 43 38 44 bool tds_is_stream(ant_value_t obj) { 39 45 return is_object_type(obj) 40 - && vtype(js_get_slot(obj, SLOT_DATA)) == T_NUM 46 + && js_check_native_tag(obj, TDS_NATIVE_TAG) 41 47 && ts_is_stream(tds_get_ts(obj)); 42 48 } 43 49 ··· 58 64 } 59 65 60 66 static void tes_state_finalize(ant_t *js, ant_object_t *obj) { 61 - ant_extra_slot_t *slot = ant_object_extra_slot(obj, SLOT_DATA); 62 - if (!slot || vtype(slot->value) != T_NUM) return; 63 - free((tes_state_t *)(uintptr_t)(size_t)js_getnum(slot->value)); 67 + if (!obj || obj->native.tag != TES_NATIVE_TAG) return; 68 + free(obj->native.ptr); 69 + obj->native.ptr = NULL; 70 + obj->native.tag = 0; 64 71 } 65 72 66 73 static void tds_state_finalize(ant_t *js, ant_object_t *obj) { 67 - ant_extra_slot_t *slot = ant_object_extra_slot(obj, SLOT_DATA); 68 - if (!slot || vtype(slot->value) != T_NUM) return; 69 - free((td_state_t *)(uintptr_t)(size_t)js_getnum(slot->value)); 74 + if (!obj || obj->native.tag != TDS_NATIVE_TAG) return; 75 + free(obj->native.ptr); 76 + obj->native.ptr = NULL; 77 + obj->native.tag = 0; 70 78 } 71 79 72 80 static ant_value_t codec_transform_controller(ant_value_t *args, int nargs) { ··· 79 87 80 88 static ant_value_t tes_transform(ant_t *js, ant_value_t *args, int nargs) { 81 89 ant_value_t wrapper = js_get_slot(js->current_func, SLOT_DATA); 82 - ant_value_t state_val = js_get_slot(wrapper, SLOT_DATA); 83 90 84 - tes_state_t *st = (tes_state_t *)(uintptr_t)(size_t)js_getnum(state_val); 91 + tes_state_t *st = (tes_state_t *)js_get_native_ptr(wrapper); 85 92 ant_value_t ctrl_obj = codec_transform_controller(args, nargs); 86 93 ant_value_t chunk = (nargs > 0) ? args[0] : js_mkundef(); 87 94 ··· 165 172 166 173 static ant_value_t tes_flush(ant_t *js, ant_value_t *args, int nargs) { 167 174 ant_value_t wrapper = js_get_slot(js->current_func, SLOT_DATA); 168 - ant_value_t state_val = js_get_slot(wrapper, SLOT_DATA); 169 - tes_state_t *st = (tes_state_t *)(uintptr_t)(size_t)js_getnum(state_val); 175 + tes_state_t *st = (tes_state_t *)js_get_native_ptr(wrapper); 170 176 ant_value_t ctrl_obj = codec_flush_controller(args, nargs); 171 177 172 178 if (st->pending_len > 0) { ··· 211 217 ant_value_t obj = js_mkobj(js); 212 218 ant_value_t proto = js_instance_proto_from_new_target(js, g_tes_proto); 213 219 if (is_object_type(proto)) js_set_proto_init(obj, proto); 214 - js_set_slot(obj, SLOT_DATA, ANT_PTR(st)); 220 + js_set_native(obj, st, TES_NATIVE_TAG); 215 221 js_set_finalizer(obj, tes_state_finalize); 216 222 217 223 ant_value_t wrapper = js_mkobj(js); 218 - js_set_slot(wrapper, SLOT_DATA, ANT_PTR(st)); 224 + js_set_native(wrapper, st, TES_NATIVE_TAG); 219 225 220 226 ant_value_t transformer = js_mkobj(js); 221 227 ant_value_t transform_fn = js_heavy_mkfun(js, tes_transform, wrapper); ··· 241 247 242 248 static ant_value_t tds_transform(ant_t *js, ant_value_t *args, int nargs) { 243 249 ant_value_t wrapper = js_get_slot(js->current_func, SLOT_DATA); 244 - ant_value_t state_val = js_get_slot(wrapper, SLOT_DATA); 245 - td_state_t *st = (td_state_t *)(uintptr_t)(size_t)js_getnum(state_val); 250 + td_state_t *st = (td_state_t *)js_get_native_ptr(wrapper); 246 251 ant_value_t ctrl_obj = codec_transform_controller(args, nargs); 247 252 248 253 ant_value_t chunk = (nargs > 0) ? args[0] : js_mkundef(); ··· 268 273 269 274 static ant_value_t tds_flush(ant_t *js, ant_value_t *args, int nargs) { 270 275 ant_value_t wrapper = js_get_slot(js->current_func, SLOT_DATA); 271 - ant_value_t state_val = js_get_slot(wrapper, SLOT_DATA); 272 - td_state_t *st = (td_state_t *)(uintptr_t)(size_t)js_getnum(state_val); 276 + td_state_t *st = (td_state_t *)js_get_native_ptr(wrapper); 273 277 ant_value_t ctrl_obj = codec_flush_controller(args, nargs); 274 278 275 279 ant_value_t result = td_decode(js, st, NULL, 0, false); ··· 287 291 } 288 292 289 293 static ant_value_t js_tds_get_encoding(ant_t *js, ant_value_t *args, int nargs) { 290 - ant_value_t state_val = js_get_slot(js->this_val, SLOT_DATA); 291 - td_state_t *st = (td_state_t *)(uintptr_t)(size_t)js_getnum(state_val); 294 + td_state_t *st = (td_state_t *)js_get_native_ptr(js->this_val); 292 295 if (!st) return js_mkstr(js, "utf-8", 5); 293 296 switch (st->encoding) { 294 297 case TD_ENC_UTF16LE: return js_mkstr(js, "utf-16le", 8); ··· 300 303 } 301 304 302 305 static ant_value_t js_tds_get_fatal(ant_t *js, ant_value_t *args, int nargs) { 303 - ant_value_t state_val = js_get_slot(js->this_val, SLOT_DATA); 304 - td_state_t *st = (td_state_t *)(uintptr_t)(size_t)js_getnum(state_val); 306 + td_state_t *st = (td_state_t *)js_get_native_ptr(js->this_val); 305 307 return (st && st->fatal) ? js_true : js_false; 306 308 } 307 309 308 310 static ant_value_t js_tds_get_ignore_bom(ant_t *js, ant_value_t *args, int nargs) { 309 - ant_value_t state_val = js_get_slot(js->this_val, SLOT_DATA); 310 - td_state_t *st = (td_state_t *)(uintptr_t)(size_t)js_getnum(state_val); 311 + td_state_t *st = (td_state_t *)js_get_native_ptr(js->this_val); 311 312 return (st && st->ignore_bom) ? js_true : js_false; 312 313 } 313 314 ··· 390 391 ant_value_t obj = js_mkobj(js); 391 392 ant_value_t proto = js_instance_proto_from_new_target(js, g_tds_proto); 392 393 if (is_object_type(proto)) js_set_proto_init(obj, proto); 393 - js_set_slot(obj, SLOT_DATA, ANT_PTR(st)); 394 + js_set_native(obj, st, TDS_NATIVE_TAG); 394 395 js_set_finalizer(obj, tds_state_finalize); 395 396 396 397 ant_value_t wrapper = js_mkobj(js); 397 - js_set_slot(wrapper, SLOT_DATA, ANT_PTR(st)); 398 + js_set_native(wrapper, st, TDS_NATIVE_TAG); 398 399 399 400 ant_value_t transformer = js_mkobj(js); 400 401 ant_value_t transform_fn = js_heavy_mkfun(js, tds_transform, wrapper);
+37 -31
src/streams/compression.c
··· 3 3 #include <zlib.h> 4 4 5 5 #include "ant.h" 6 + #include "ptr.h" 6 7 #include "errors.h" 7 8 #include "runtime.h" 8 9 #include "internal.h" ··· 16 17 17 18 ant_value_t g_cs_proto; 18 19 ant_value_t g_ds_proto; 20 + 21 + enum { 22 + CS_Z_NATIVE_TAG = 0x43535a53u, // CSZS 23 + DS_Z_NATIVE_TAG = 0x44535a53u, // DSZS 24 + 25 + CS_BROTLI_NATIVE_TAG = 0x43534252u, // CSBR 26 + DS_BROTLI_NATIVE_TAG = 0x44534252u // DSBR 27 + }; 19 28 20 29 typedef struct { 21 30 z_stream strm; ··· 56 65 57 66 bool cs_is_stream(ant_value_t obj) { 58 67 return is_object_type(obj) 59 - && vtype(js_get_slot(obj, SLOT_DATA)) == T_NUM 68 + && (js_check_native_tag(obj, CS_Z_NATIVE_TAG) || js_check_native_tag(obj, CS_BROTLI_NATIVE_TAG)) 60 69 && ts_is_stream(get_ts(obj)); 61 70 } 62 71 63 72 bool ds_is_stream(ant_value_t obj) { 64 73 return is_object_type(obj) 65 - && vtype(js_get_slot(obj, SLOT_DATA)) == T_NUM 74 + && (js_check_native_tag(obj, DS_Z_NATIVE_TAG) || js_check_native_tag(obj, DS_BROTLI_NATIVE_TAG)) 66 75 && ts_is_stream(get_ts(obj)); 67 76 } 68 77 ··· 83 92 } 84 93 85 94 static void zstate_finalize(ant_t *js, ant_object_t *obj) { 86 - ant_extra_slot_t *slot = ant_object_extra_slot(obj, SLOT_DATA); 87 - if (!slot || vtype(slot->value) != T_NUM) return; 88 - zstate_t *st = (zstate_t *)(uintptr_t)(size_t)js_getnum(slot->value); 95 + if (!obj || obj->native.tag != CS_Z_NATIVE_TAG) return; 96 + zstate_t *st = (zstate_t *)obj->native.ptr; 97 + if (!st) return; 89 98 if (st->initialized) deflateEnd(&st->strm); 90 99 free(st); 100 + obj->native.ptr = NULL; 101 + obj->native.tag = 0; 91 102 } 92 103 93 104 static void zstate_inflate_finalize(ant_t *js, ant_object_t *obj) { 94 - ant_extra_slot_t *slot = ant_object_extra_slot(obj, SLOT_DATA); 95 - if (!slot || vtype(slot->value) != T_NUM) return; 96 - zstate_t *st = (zstate_t *)(uintptr_t)(size_t)js_getnum(slot->value); 105 + if (!obj || obj->native.tag != DS_Z_NATIVE_TAG) return; 106 + zstate_t *st = (zstate_t *)obj->native.ptr; 107 + if (!st) return; 97 108 if (st->initialized) inflateEnd(&st->strm); 98 109 free(st); 110 + obj->native.ptr = NULL; 111 + obj->native.tag = 0; 99 112 } 100 113 101 114 static void brotli_state_finalize(ant_t *js, ant_object_t *obj) { 102 - ant_extra_slot_t *slot = ant_object_extra_slot(obj, SLOT_DATA); 103 - if (!slot || vtype(slot->value) != T_NUM) return; 104 - brotli_stream_state_t *st = 105 - (brotli_stream_state_t *)(uintptr_t)(size_t)js_getnum(slot->value); 115 + if (!obj || (obj->native.tag != CS_BROTLI_NATIVE_TAG && obj->native.tag != DS_BROTLI_NATIVE_TAG)) return; 116 + brotli_stream_state_t *st = (brotli_stream_state_t *)obj->native.ptr; 106 117 brotli_stream_state_destroy(st); 118 + obj->native.ptr = NULL; 119 + obj->native.tag = 0; 107 120 } 108 121 109 122 static ant_value_t enqueue_buffer(ant_t *js, ant_value_t ctrl_obj, const uint8_t *data, size_t len) { ··· 120 133 121 134 static ant_value_t cs_transform(ant_t *js, ant_value_t *args, int nargs) { 122 135 ant_value_t wrapper = js_get_slot(js->current_func, SLOT_DATA); 123 - ant_value_t state_val = js_get_slot(wrapper, SLOT_DATA); 124 136 125 - zstate_t *st = (zstate_t *)(uintptr_t)(size_t)js_getnum(state_val); 137 + zstate_t *st = (zstate_t *)js_get_native_ptr(wrapper); 126 138 ant_value_t ctrl_obj = (nargs > 1) ? args[1] : js_mkundef(); 127 139 ant_value_t chunk = (nargs > 0) ? args[0] : js_mkundef(); 128 140 ··· 135 147 if (!input || input_len == 0) return js_mkundef(); 136 148 137 149 if (get_wrapper_format(wrapper) == ZFMT_BROTLI) { 138 - brotli_stream_state_t *brotli_st = 139 - (brotli_stream_state_t *)(uintptr_t)(size_t)js_getnum(state_val); 150 + brotli_stream_state_t *brotli_st = (brotli_stream_state_t *)js_get_native_ptr(wrapper); 140 151 return brotli_stream_transform(js, brotli_st, ctrl_obj, input, input_len); 141 152 } 142 153 ··· 162 173 163 174 static ant_value_t cs_flush(ant_t *js, ant_value_t *args, int nargs) { 164 175 ant_value_t wrapper = js_get_slot(js->current_func, SLOT_DATA); 165 - ant_value_t state_val = js_get_slot(wrapper, SLOT_DATA); 166 176 ant_value_t ctrl_obj = (nargs > 0) ? args[0] : js_mkundef(); 167 177 168 178 if (get_wrapper_format(wrapper) == ZFMT_BROTLI) { 169 - brotli_stream_state_t *brotli_st = 170 - (brotli_stream_state_t *)(uintptr_t)(size_t)js_getnum(state_val); 179 + brotli_stream_state_t *brotli_st = (brotli_stream_state_t *)js_get_native_ptr(wrapper); 171 180 return brotli_stream_flush(js, brotli_st, ctrl_obj); 172 - } zstate_t *st = (zstate_t *)(uintptr_t)(size_t)js_getnum(state_val); 181 + } 182 + zstate_t *st = (zstate_t *)js_get_native_ptr(wrapper); 173 183 174 184 st->strm.next_in = NULL; 175 185 st->strm.avail_in = 0; ··· 230 240 ant_value_t obj = js_mkobj(js); 231 241 ant_value_t proto = js_instance_proto_from_new_target(js, g_cs_proto); 232 242 if (is_object_type(proto)) js_set_proto_init(obj, proto); 233 - js_set_slot(obj, SLOT_DATA, fmt == ZFMT_BROTLI ? ANT_PTR(brotli) : ANT_PTR(st)); 243 + js_set_native(obj, fmt == ZFMT_BROTLI ? (void *)brotli : (void *)st, fmt == ZFMT_BROTLI ? CS_BROTLI_NATIVE_TAG : CS_Z_NATIVE_TAG); 234 244 js_set_finalizer(obj, fmt == ZFMT_BROTLI ? brotli_state_finalize : zstate_finalize); 235 245 236 246 ant_value_t wrapper = js_mkobj(js); 237 - js_set_slot(wrapper, SLOT_DATA, fmt == ZFMT_BROTLI ? ANT_PTR(brotli) : ANT_PTR(st)); 247 + js_set_native(wrapper, fmt == ZFMT_BROTLI ? (void *)brotli : (void *)st, fmt == ZFMT_BROTLI ? CS_BROTLI_NATIVE_TAG : CS_Z_NATIVE_TAG); 238 248 js_set_slot(wrapper, SLOT_CTOR, js_mknum((double)fmt)); 239 249 240 250 ant_value_t transformer = js_mkobj(js); ··· 265 275 266 276 static ant_value_t ds_transform(ant_t *js, ant_value_t *args, int nargs) { 267 277 ant_value_t wrapper = js_get_slot(js->current_func, SLOT_DATA); 268 - ant_value_t state_val = js_get_slot(wrapper, SLOT_DATA); 269 - zstate_t *st = (zstate_t *)(uintptr_t)(size_t)js_getnum(state_val); 278 + zstate_t *st = (zstate_t *)js_get_native_ptr(wrapper); 270 279 ant_value_t ctrl_obj = (nargs > 1) ? args[1] : js_mkundef(); 271 280 272 281 ant_value_t chunk = (nargs > 0) ? args[0] : js_mkundef(); ··· 278 287 279 288 if (!input || input_len == 0) return js_mkundef(); 280 289 if (get_wrapper_format(wrapper) == ZFMT_BROTLI) { 281 - brotli_stream_state_t *brotli_st = 282 - (brotli_stream_state_t *)(uintptr_t)(size_t)js_getnum(state_val); 290 + brotli_stream_state_t *brotli_st = (brotli_stream_state_t *)js_get_native_ptr(wrapper); 283 291 return brotli_stream_transform(js, brotli_st, ctrl_obj, input, input_len); 284 292 } 285 293 ··· 306 314 307 315 static ant_value_t ds_flush(ant_t *js, ant_value_t *args, int nargs) { 308 316 ant_value_t wrapper = js_get_slot(js->current_func, SLOT_DATA); 309 - ant_value_t state_val = js_get_slot(wrapper, SLOT_DATA); 310 317 ant_value_t ctrl_obj = (nargs > 0) ? args[0] : js_mkundef(); 311 318 if (get_wrapper_format(wrapper) == ZFMT_BROTLI) { 312 - brotli_stream_state_t *st = 313 - (brotli_stream_state_t *)(uintptr_t)(size_t)js_getnum(state_val); 319 + brotli_stream_state_t *st = (brotli_stream_state_t *)js_get_native_ptr(wrapper); 314 320 return brotli_stream_flush(js, st, ctrl_obj); 315 321 } 316 322 return js_mkundef(); ··· 355 361 ant_value_t obj = js_mkobj(js); 356 362 ant_value_t proto = js_instance_proto_from_new_target(js, g_ds_proto); 357 363 if (is_object_type(proto)) js_set_proto_init(obj, proto); 358 - js_set_slot(obj, SLOT_DATA, fmt == ZFMT_BROTLI ? ANT_PTR(brotli) : ANT_PTR(st)); 364 + js_set_native(obj, fmt == ZFMT_BROTLI ? (void *)brotli : (void *)st, fmt == ZFMT_BROTLI ? DS_BROTLI_NATIVE_TAG : DS_Z_NATIVE_TAG); 359 365 js_set_finalizer(obj, fmt == ZFMT_BROTLI ? brotli_state_finalize : zstate_inflate_finalize); 360 366 361 367 ant_value_t wrapper = js_mkobj(js); 362 - js_set_slot(wrapper, SLOT_DATA, fmt == ZFMT_BROTLI ? ANT_PTR(brotli) : ANT_PTR(st)); 368 + js_set_native(wrapper, fmt == ZFMT_BROTLI ? (void *)brotli : (void *)st, fmt == ZFMT_BROTLI ? DS_BROTLI_NATIVE_TAG : DS_Z_NATIVE_TAG); 363 369 js_set_slot(wrapper, SLOT_CTOR, js_mknum((double)fmt)); 364 370 365 371 ant_value_t transformer = js_mkobj(js);
+20 -14
src/streams/pipes.c
··· 1 1 #include <string.h> 2 2 3 3 #include "ant.h" 4 + #include "ptr.h" 4 5 #include "errors.h" 5 6 #include "internal.h" 6 7 #include "descriptors.h" ··· 22 23 bool prevent_cancel; 23 24 } pipe_state_t; 24 25 26 + enum { 27 + PIPE_STATE_NATIVE_TAG = 0x50495045u, // PIPE 28 + TEE_STATE_NATIVE_TAG = 0x54454553u // TEES 29 + }; 30 + 25 31 static void pipes_chain_promise( 26 32 ant_t *js, ant_value_t value, 27 33 ant_value_t on_resolve, ant_value_t on_reject ··· 46 52 } 47 53 48 54 static void pipe_state_finalize(ant_t *js, ant_object_t *obj) { 49 - ant_extra_slot_t *slot = ant_object_extra_slot(obj, SLOT_DATA); 50 - if (!slot || vtype(slot->value) != T_NUM) return; 51 - free((pipe_state_t *)(uintptr_t)(size_t)js_getnum(slot->value)); 55 + if (!obj || obj->native.tag != PIPE_STATE_NATIVE_TAG) return; 56 + free(obj->native.ptr); 57 + obj->native.ptr = NULL; 58 + obj->native.tag = 0; 52 59 } 53 60 54 61 static pipe_state_t *pipe_get_state(ant_value_t state) { 55 - ant_value_t s = js_get_slot(state, SLOT_DATA); 56 - if (vtype(s) != T_NUM) return NULL; 57 - return (pipe_state_t *)(uintptr_t)(size_t)js_getnum(s); 62 + if (!js_check_native_tag(state, PIPE_STATE_NATIVE_TAG)) return NULL; 63 + return (pipe_state_t *)js_get_native_ptr(state); 58 64 } 59 65 60 66 static ant_value_t pipe_state_source(ant_value_t state) { ··· 390 396 391 397 ant_value_t promise = js_mkpromise(js); 392 398 ant_value_t state = js_mkobj(js); 393 - js_set_slot(state, SLOT_DATA, ANT_PTR(pst)); 399 + js_set_native(state, pst, PIPE_STATE_NATIVE_TAG); 394 400 js_set_slot(state, SLOT_ENTRIES, source); 395 401 js_set_slot(state, SLOT_CTOR, dest); 396 402 js_set_slot(state, SLOT_AUX, reader); ··· 483 489 } tee_state_t; 484 490 485 491 static void tee_state_finalize(ant_t *js, ant_object_t *obj) { 486 - ant_extra_slot_t *slot = ant_object_extra_slot(obj, SLOT_DATA); 487 - if (!slot || vtype(slot->value) != T_NUM) return; 488 - free((tee_state_t *)(uintptr_t)(size_t)js_getnum(slot->value)); 492 + if (!obj || obj->native.tag != TEE_STATE_NATIVE_TAG) return; 493 + free(obj->native.ptr); 494 + obj->native.ptr = NULL; 495 + obj->native.tag = 0; 489 496 } 490 497 491 498 static tee_state_t *tee_get_state(ant_value_t state) { 492 - ant_value_t s = js_get_slot(state, SLOT_DATA); 493 - if (vtype(s) != T_NUM) return NULL; 494 - return (tee_state_t *)(uintptr_t)(size_t)js_getnum(s); 499 + if (!js_check_native_tag(state, TEE_STATE_NATIVE_TAG)) return NULL; 500 + return (tee_state_t *)js_get_native_ptr(state); 495 501 } 496 502 497 503 static ant_value_t tee_state_reader(ant_value_t state) { ··· 740 746 if (!st) return js_mkerr(js, "out of memory"); 741 747 742 748 ant_value_t state = js_mkobj(js); 743 - js_set_slot(state, SLOT_DATA, ANT_PTR(st)); 749 + js_set_native(state, st, TEE_STATE_NATIVE_TAG); 744 750 js_set_slot(state, SLOT_ENTRIES, js->this_val); 745 751 js_set_slot(state, SLOT_AUX, reader); 746 752 js_set_slot(state, SLOT_RS_PULL, js_mkundef());
+17 -16
src/streams/readable.c
··· 2 2 #include <string.h> 3 3 4 4 #include "ant.h" 5 + #include "ptr.h" 5 6 #include "errors.h" 6 7 #include "runtime.h" 7 8 #include "internal.h" ··· 49 50 } 50 51 51 52 rs_stream_t *rs_get_stream(ant_value_t obj) { 52 - ant_value_t s = js_get_slot(obj, SLOT_DATA); 53 - if (vtype(s) != T_NUM) return NULL; 54 - return (rs_stream_t *)(uintptr_t)(size_t)js_getnum(s); 53 + if (!js_check_native_tag(obj, RS_STREAM_NATIVE_TAG)) return NULL; 54 + return (rs_stream_t *)js_get_native_ptr(obj); 55 55 } 56 56 57 57 rs_controller_t *rs_get_controller(ant_value_t obj) { 58 - ant_value_t s = js_get_slot(obj, SLOT_DATA); 59 - if (vtype(s) != T_NUM) return NULL; 60 - return (rs_controller_t *)(uintptr_t)(size_t)js_getnum(s); 58 + if (!js_check_native_tag(obj, RS_CONTROLLER_NATIVE_TAG)) return NULL; 59 + return (rs_controller_t *)js_get_native_ptr(obj); 61 60 } 62 61 63 62 static void rs_stream_finalize(ant_t *js, ant_object_t *obj) { 64 - ant_extra_slot_t *slot = ant_object_extra_slot(obj, SLOT_DATA); 65 - if (!slot || vtype(slot->value) != T_NUM) return; 66 - free((rs_stream_t *)(uintptr_t)(size_t)js_getnum(slot->value)); 63 + if (!obj || obj->native.tag != RS_STREAM_NATIVE_TAG) return; 64 + free(obj->native.ptr); 65 + obj->native.ptr = NULL; 66 + obj->native.tag = 0; 67 67 } 68 68 69 69 static void rs_controller_finalize(ant_t *js, ant_object_t *obj) { 70 - ant_extra_slot_t *slot = ant_object_extra_slot(obj, SLOT_DATA); 71 - if (!slot || vtype(slot->value) != T_NUM) return; 72 - rs_controller_t *ctrl = 73 - (rs_controller_t *)(uintptr_t)(size_t)js_getnum(slot->value); 70 + if (!obj || obj->native.tag != RS_CONTROLLER_NATIVE_TAG) return; 71 + rs_controller_t *ctrl = (rs_controller_t *)obj->native.ptr; 72 + if (!ctrl) return; 74 73 free(ctrl->queue_sizes); 75 74 free(ctrl); 75 + obj->native.ptr = NULL; 76 + obj->native.tag = 0; 76 77 } 77 78 78 79 ant_value_t rs_stream_controller(ant_t *js, ant_value_t stream_obj) { ··· 805 806 ant_value_t ctrl_obj = js_mkobj(js); 806 807 js_set_proto_init(ctrl_obj, g_controller_proto); 807 808 js_set_slot(ctrl_obj, SLOT_BRAND, js_mknum(BRAND_READABLE_STREAM_CONTROLLER)); 808 - js_set_slot(ctrl_obj, SLOT_DATA, ANT_PTR(ctrl)); 809 + js_set_native(ctrl_obj, ctrl, RS_CONTROLLER_NATIVE_TAG); 809 810 js_set_slot(ctrl_obj, SLOT_ENTRIES, stream_obj); 810 811 js_set_slot(ctrl_obj, SLOT_RS_PULL, pull_fn); 811 812 js_set_slot(ctrl_obj, SLOT_RS_CANCEL, cancel_fn); ··· 879 880 880 881 if (is_object_type(proto)) js_set_proto_init(obj, proto); 881 882 js_set_slot(obj, SLOT_BRAND, js_mknum(BRAND_READABLE_STREAM)); 882 - js_set_slot(obj, SLOT_DATA, ANT_PTR(st)); 883 + js_set_native(obj, st, RS_STREAM_NATIVE_TAG); 883 884 js_set_finalizer(obj, rs_stream_finalize); 884 885 885 886 if (is_bytes_source) ··· 950 951 ant_value_t obj = js_mkobj(js); 951 952 js_set_proto_init(obj, g_rs_proto); 952 953 js_set_slot(obj, SLOT_BRAND, js_mknum(BRAND_READABLE_STREAM)); 953 - js_set_slot(obj, SLOT_DATA, ANT_PTR(st)); 954 + js_set_native(obj, st, RS_STREAM_NATIVE_TAG); 954 955 js_set_finalizer(obj, rs_stream_finalize); 955 956 956 957 ant_value_t ctrl_obj = setup_default_controller(js, obj, pull_fn, cancel_fn, js_mkundef(), hwm);
+23 -18
src/streams/transform.c
··· 2 2 #include <string.h> 3 3 4 4 #include "ant.h" 5 + #include "ptr.h" 5 6 #include "errors.h" 6 7 #include "runtime.h" 7 8 #include "internal.h" ··· 54 55 } 55 56 56 57 static void ts_ws_finalize(ant_t *js, ant_object_t *obj) { 57 - ant_extra_slot_t *slot = ant_object_extra_slot(obj, SLOT_DATA); 58 - if (!slot || vtype(slot->value) != T_NUM) return; 59 - free((ws_stream_t *)(uintptr_t)(size_t)js_getnum(slot->value)); 58 + if (!obj || obj->native.tag != WS_STREAM_NATIVE_TAG) return; 59 + free(obj->native.ptr); 60 + obj->native.ptr = NULL; 61 + obj->native.tag = 0; 60 62 } 61 63 62 64 static void ts_ws_ctrl_finalize(ant_t *js, ant_object_t *obj) { 63 - ant_extra_slot_t *slot = ant_object_extra_slot(obj, SLOT_DATA); 64 - if (!slot || vtype(slot->value) != T_NUM) return; 65 - ws_controller_t *ctrl = 66 - (ws_controller_t *)(uintptr_t)(size_t)js_getnum(slot->value); 65 + if (!obj || obj->native.tag != WS_CONTROLLER_NATIVE_TAG) return; 66 + ws_controller_t *ctrl = (ws_controller_t *)obj->native.ptr; 67 + if (!ctrl) return; 67 68 free(ctrl->queue_sizes); 68 69 free(ctrl); 70 + obj->native.ptr = NULL; 71 + obj->native.tag = 0; 69 72 } 70 73 71 74 static void ts_rs_finalize(ant_t *js, ant_object_t *obj) { 72 - ant_extra_slot_t *slot = ant_object_extra_slot(obj, SLOT_DATA); 73 - if (!slot || vtype(slot->value) != T_NUM) return; 74 - free((rs_stream_t *)(uintptr_t)(size_t)js_getnum(slot->value)); 75 + if (!obj || obj->native.tag != RS_STREAM_NATIVE_TAG) return; 76 + free(obj->native.ptr); 77 + obj->native.ptr = NULL; 78 + obj->native.tag = 0; 75 79 } 76 80 77 81 static void ts_rs_ctrl_finalize(ant_t *js, ant_object_t *obj) { 78 - ant_extra_slot_t *slot = ant_object_extra_slot(obj, SLOT_DATA); 79 - if (!slot || vtype(slot->value) != T_NUM) return; 80 - rs_controller_t *ctrl = 81 - (rs_controller_t *)(uintptr_t)(size_t)js_getnum(slot->value); 82 + if (!obj || obj->native.tag != RS_CONTROLLER_NATIVE_TAG) return; 83 + rs_controller_t *ctrl = (rs_controller_t *)obj->native.ptr; 84 + if (!ctrl) return; 82 85 free(ctrl->queue_sizes); 83 86 free(ctrl); 87 + obj->native.ptr = NULL; 88 + obj->native.tag = 0; 84 89 } 85 90 86 91 static inline bool ts_get_backpressure(ant_value_t ts_obj) { ··· 956 961 ant_value_t rs_obj = js_mkobj(js); 957 962 js_set_proto_init(rs_obj, g_rs_proto); 958 963 js_set_slot(rs_obj, SLOT_BRAND, js_mknum(BRAND_READABLE_STREAM)); 959 - js_set_slot(rs_obj, SLOT_DATA, ANT_PTR(rst)); 964 + js_set_native(rs_obj, rst, RS_STREAM_NATIVE_TAG); 960 965 js_set_finalizer(rs_obj, ts_rs_finalize); 961 966 962 967 rs_controller_t *rcc = calloc(1, sizeof(rs_controller_t)); ··· 966 971 ant_value_t rs_ctrl_obj = js_mkobj(js); 967 972 js_set_proto_init(rs_ctrl_obj, g_controller_proto); 968 973 js_set_slot(rs_ctrl_obj, SLOT_BRAND, js_mknum(BRAND_READABLE_STREAM_CONTROLLER)); 969 - js_set_slot(rs_ctrl_obj, SLOT_DATA, ANT_PTR(rcc)); 974 + js_set_native(rs_ctrl_obj, rcc, RS_CONTROLLER_NATIVE_TAG); 970 975 js_set_slot(rs_ctrl_obj, SLOT_ENTRIES, rs_obj); 971 976 js_set_slot(rs_ctrl_obj, SLOT_RS_PULL, source_pull); 972 977 js_set_slot(rs_ctrl_obj, SLOT_RS_CANCEL, source_cancel); ··· 984 989 ant_value_t ws_obj = js_mkobj(js); 985 990 js_set_proto_init(ws_obj, g_ws_proto); 986 991 js_set_slot(ws_obj, SLOT_BRAND, js_mknum(BRAND_WRITABLE_STREAM)); 987 - js_set_slot(ws_obj, SLOT_DATA, ANT_PTR(wst)); 992 + js_set_native(ws_obj, wst, WS_STREAM_NATIVE_TAG); 988 993 js_set_slot(ws_obj, SLOT_SETTLED, js_mkarr(js)); 989 994 js_set_finalizer(ws_obj, ts_ws_finalize); 990 995 ··· 1002 1007 ant_value_t ws_ctrl_obj = js_mkobj(js); 1003 1008 js_set_proto_init(ws_ctrl_obj, g_ws_controller_proto); 1004 1009 js_set_slot(ws_ctrl_obj, SLOT_BRAND, js_mknum(BRAND_WRITABLE_STREAM_CONTROLLER)); 1005 - js_set_slot(ws_ctrl_obj, SLOT_DATA, ANT_PTR(wc)); 1010 + js_set_native(ws_ctrl_obj, wc, WS_CONTROLLER_NATIVE_TAG); 1006 1011 js_set_slot(ws_ctrl_obj, SLOT_ENTRIES, ws_obj); 1007 1012 js_set_slot(ws_ctrl_obj, SLOT_WS_WRITE, sink_write); 1008 1013 js_set_slot(ws_ctrl_obj, SLOT_WS_CLOSE, sink_close);
+16 -15
src/streams/writable.c
··· 2 2 #include <string.h> 3 3 4 4 #include "ant.h" 5 + #include "ptr.h" 5 6 #include "errors.h" 6 7 #include "runtime.h" 7 8 #include "internal.h" ··· 37 38 } 38 39 39 40 ws_stream_t *ws_get_stream(ant_value_t obj) { 40 - ant_value_t s = js_get_slot(obj, SLOT_DATA); 41 - if (vtype(s) != T_NUM) return NULL; 42 - return (ws_stream_t *)(uintptr_t)(size_t)js_getnum(s); 41 + if (!js_check_native_tag(obj, WS_STREAM_NATIVE_TAG)) return NULL; 42 + return (ws_stream_t *)js_get_native_ptr(obj); 43 43 } 44 44 45 45 ws_controller_t *ws_get_controller(ant_value_t obj) { 46 - ant_value_t s = js_get_slot(obj, SLOT_DATA); 47 - if (vtype(s) != T_NUM) return NULL; 48 - return (ws_controller_t *)(uintptr_t)(size_t)js_getnum(s); 46 + if (!js_check_native_tag(obj, WS_CONTROLLER_NATIVE_TAG)) return NULL; 47 + return (ws_controller_t *)js_get_native_ptr(obj); 49 48 } 50 49 51 50 static void ws_stream_finalize(ant_t *js, ant_object_t *obj) { 52 - ant_extra_slot_t *slot = ant_object_extra_slot(obj, SLOT_DATA); 53 - if (!slot || vtype(slot->value) != T_NUM) return; 54 - free((ws_stream_t *)(uintptr_t)(size_t)js_getnum(slot->value)); 51 + if (!obj || obj->native.tag != WS_STREAM_NATIVE_TAG) return; 52 + free(obj->native.ptr); 53 + obj->native.ptr = NULL; 54 + obj->native.tag = 0; 55 55 } 56 56 57 57 static void ws_controller_finalize(ant_t *js, ant_object_t *obj) { 58 - ant_extra_slot_t *slot = ant_object_extra_slot(obj, SLOT_DATA); 59 - if (!slot || vtype(slot->value) != T_NUM) return; 60 - ws_controller_t *ctrl = 61 - (ws_controller_t *)(uintptr_t)(size_t)js_getnum(slot->value); 58 + if (!obj || obj->native.tag != WS_CONTROLLER_NATIVE_TAG) return; 59 + ws_controller_t *ctrl = (ws_controller_t *)obj->native.ptr; 60 + if (!ctrl) return; 62 61 free(ctrl->queue_sizes); 63 62 free(ctrl); 63 + obj->native.ptr = NULL; 64 + obj->native.tag = 0; 64 65 } 65 66 66 67 ant_value_t ws_stream_controller(ant_value_t stream_obj) { ··· 1075 1076 ant_value_t ctrl_obj = js_mkobj(js); 1076 1077 js_set_proto_init(ctrl_obj, g_ws_controller_proto); 1077 1078 js_set_slot(ctrl_obj, SLOT_BRAND, js_mknum(BRAND_WRITABLE_STREAM_CONTROLLER)); 1078 - js_set_slot(ctrl_obj, SLOT_DATA, ANT_PTR(ctrl)); 1079 + js_set_native(ctrl_obj, ctrl, WS_CONTROLLER_NATIVE_TAG); 1079 1080 js_set_slot(ctrl_obj, SLOT_ENTRIES, stream_obj); 1080 1081 js_set_slot(ctrl_obj, SLOT_WS_WRITE, write_fn); 1081 1082 js_set_slot(ctrl_obj, SLOT_WS_CLOSE, close_fn); ··· 1157 1158 1158 1159 if (is_object_type(proto)) js_set_proto_init(obj, proto); 1159 1160 js_set_slot(obj, SLOT_BRAND, js_mknum(BRAND_WRITABLE_STREAM)); 1160 - js_set_slot(obj, SLOT_DATA, ANT_PTR(st)); 1161 + js_set_native(obj, st, WS_STREAM_NATIVE_TAG); 1161 1162 js_set_slot(obj, SLOT_SETTLED, js_mkarr(js)); 1162 1163 js_set_finalizer(obj, ws_stream_finalize); 1163 1164