From 6b192f718528bb5a7899244c62cf87c0699649cd Mon Sep 17 00:00:00 2001 From: theMackabu Date: Sun, 5 Apr 2026 21:21:29 -0700 Subject: [PATCH] migrate buffers to finalizer system --- include/common.h | 2 +- include/modules/buffer.h | 9 +- src/ant.c | 216 ++++++----- src/modules/atomics.c | 4 +- src/modules/blob.c | 24 +- src/modules/buffer.c | 442 +++++++++-------------- src/modules/child_process.c | 3 +- src/modules/crypto.c | 16 +- src/modules/fetch.c | 3 +- src/modules/fs.c | 24 +- src/modules/io.c | 2 +- src/modules/lmdb.c | 16 +- src/modules/napi.c | 26 +- src/modules/net.c | 7 +- src/modules/response.c | 3 +- src/modules/server.c | 3 +- src/modules/structured-clone.c | 15 +- src/modules/textcodec.c | 2 +- src/modules/util.c | 52 +-- src/modules/v8.c | 3 +- src/streams/pipes.c | 12 +- src/streams/readable.c | 14 +- src/streams/transform.c | 26 +- src/streams/writable.c | 10 +- tests/repro_typedarray_metadata_leak.cjs | 17 + 25 files changed, 404 insertions(+), 547 deletions(-) create mode 100644 tests/repro_typedarray_metadata_leak.cjs diff --git a/include/common.h b/include/common.h index 163c551..cb89457 100644 --- a/include/common.h +++ b/include/common.h @@ -22,7 +22,7 @@ typedef enum { SLOT_PROTO, SLOT_FUNC_PROTO, SLOT_ASYNC_PROTO, - SLOT_BUFFER, + SLOT_AUX, SLOT_TARGET_FUNC, SLOT_NAME, SLOT_MODULE_CTX, diff --git a/include/modules/buffer.h b/include/modules/buffer.h index 2e51207..86a1736 100644 --- a/include/modules/buffer.h +++ b/include/modules/buffer.h @@ -49,10 +49,16 @@ void init_buffer_module(void); void cleanup_buffer_module(void); void free_array_buffer_data(ArrayBufferData *data); -ArrayBufferData *create_array_buffer_data(size_t length); +size_t buffer_get_external_memory(void); + ant_value_t create_arraybuffer_obj(ant_t *js, ArrayBufferData *buffer); const char *buffer_typedarray_type_name(TypedArrayType type); +ArrayBufferData *create_array_buffer_data(size_t length); +ArrayBufferData *buffer_get_arraybuffer_data(ant_value_t value); +TypedArrayData *buffer_get_typedarray_data(ant_value_t value); +DataViewData *buffer_get_dataview_data(ant_value_t value); + ant_value_t create_typed_array( ant_t *js, TypedArrayType type, ArrayBufferData *buffer, size_t byte_offset, size_t length, const char *type_name @@ -70,7 +76,6 @@ ant_value_t create_dataview_with_buffer( ant_value_t arraybuffer_obj ); -size_t buffer_get_external_memory(void); bool buffer_is_dataview(ant_value_t obj); bool buffer_is_binary_source(ant_value_t value); bool buffer_source_get_bytes(ant_t *js, ant_value_t value, const uint8_t **out, size_t *len); diff --git a/src/ant.c b/src/ant.c index fad8090..4dd44df 100644 --- a/src/ant.c +++ b/src/ant.c @@ -1166,89 +1166,85 @@ static size_t strobj(ant_t *js, ant_value_t obj, char *buf, size_t len) { is_set = (tlen == 3 && memcmp(tag_str, "Set", 3) == 0); is_arraybuffer = (tlen >= 11 && memcmp(tag_str + tlen - 11, "ArrayBuffer", 11) == 0); - ant_value_t ta_slot = js_get_slot(obj, SLOT_BUFFER); - if (vtype(ta_slot) == T_TYPEDARRAY) { - TypedArrayData *ta = (TypedArrayData *)vdata(ta_slot); - if (ta && ta->buffer) { - const char *type_name = NULL; - size_t type_len = 0; - - ant_value_t proto = js_get_proto(js, obj); - ant_value_t buffer_proto = get_ctor_proto(js, "Buffer", 6); - if (vtype(proto) == T_OBJ && vtype(buffer_proto) == T_OBJ && vdata(proto) == vdata(buffer_proto)) { - type_name = "Buffer"; - type_len = 6; - } else if (ta->type <= TYPED_ARRAY_BIGUINT64) { - type_name = buffer_typedarray_type_name(ta->type); - type_len = strlen(type_name); - } else { - type_name = "TypedArray"; - type_len = 10; - } - - n += cpy(buf + n, REMAIN(n, len), type_name, type_len); - n += (size_t) snprintf(buf + n, REMAIN(n, len), "(%zu) ", ta->length); - n += cpy(buf + n, REMAIN(n, len), "[ ", 2); - - uint8_t *data = ta->buffer->data + ta->byte_offset; + TypedArrayData *ta = buffer_get_typedarray_data(obj); + if (ta && ta->buffer) { + const char *type_name = NULL; + size_t type_len = 0; + + ant_value_t proto = js_get_proto(js, obj); + ant_value_t buffer_proto = get_ctor_proto(js, "Buffer", 6); + if (vtype(proto) == T_OBJ && vtype(buffer_proto) == T_OBJ && vdata(proto) == vdata(buffer_proto)) { + type_name = "Buffer"; + type_len = 6; + } else if (ta->type <= TYPED_ARRAY_BIGUINT64) { + type_name = buffer_typedarray_type_name(ta->type); + type_len = strlen(type_name); + } else { + type_name = "TypedArray"; + type_len = 10; + } + + n += cpy(buf + n, REMAIN(n, len), type_name, type_len); + n += (size_t) snprintf(buf + n, REMAIN(n, len), "(%zu) ", ta->length); + n += cpy(buf + n, REMAIN(n, len), "[ ", 2); + + uint8_t *data = ta->buffer->data + ta->byte_offset; + + for (size_t i = 0; i < ta->length && i < 100; i++) { + if (i > 0) n += cpy(buf + n, REMAIN(n, len), ", ", 2); - for (size_t i = 0; i < ta->length && i < 100; i++) { - if (i > 0) n += cpy(buf + n, REMAIN(n, len), ", ", 2); - - switch (ta->type) { - case TYPED_ARRAY_INT8: - n += (size_t) snprintf(buf + n, REMAIN(n, len), "%d", (int)((int8_t*)data)[i]); - break; - case TYPED_ARRAY_UINT8: - case TYPED_ARRAY_UINT8_CLAMPED: - n += (size_t) snprintf(buf + n, REMAIN(n, len), "%u", (unsigned)data[i]); - break; - case TYPED_ARRAY_INT16: - n += (size_t) snprintf(buf + n, REMAIN(n, len), "%d", (int)((int16_t*)data)[i]); - break; - case TYPED_ARRAY_UINT16: - n += (size_t) snprintf(buf + n, REMAIN(n, len), "%u", (unsigned)((uint16_t*)data)[i]); - break; - case TYPED_ARRAY_INT32: - n += (size_t) snprintf(buf + n, REMAIN(n, len), "%d", ((int32_t*)data)[i]); - break; - case TYPED_ARRAY_UINT32: - n += (size_t) snprintf(buf + n, REMAIN(n, len), "%u", ((uint32_t*)data)[i]); - break; - case TYPED_ARRAY_FLOAT16: - n += (size_t) snprintf( - buf + n, REMAIN(n, len), "%g", half_to_double(((uint16_t*)data)[i]) - ); - break; - case TYPED_ARRAY_FLOAT32: - n += (size_t) snprintf(buf + n, REMAIN(n, len), "%g", (double)((float*)data)[i]); - break; - case TYPED_ARRAY_FLOAT64: - n += (size_t) snprintf(buf + n, REMAIN(n, len), "%g", ((double*)data)[i]); - break; - case TYPED_ARRAY_BIGINT64: - n += (size_t) snprintf(buf + n, REMAIN(n, len), "%lldn", (long long)((int64_t*)data)[i]); - break; - case TYPED_ARRAY_BIGUINT64: - n += (size_t) snprintf(buf + n, REMAIN(n, len), "%llun", (unsigned long long)((uint64_t*)data)[i]); - break; - default: - n += (size_t) snprintf(buf + n, REMAIN(n, len), "%u", (unsigned)data[i]); - break; - } + switch (ta->type) { + case TYPED_ARRAY_INT8: + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%d", (int)((int8_t*)data)[i]); + break; + case TYPED_ARRAY_UINT8: + case TYPED_ARRAY_UINT8_CLAMPED: + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%u", (unsigned)data[i]); + break; + case TYPED_ARRAY_INT16: + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%d", (int)((int16_t*)data)[i]); + break; + case TYPED_ARRAY_UINT16: + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%u", (unsigned)((uint16_t*)data)[i]); + break; + case TYPED_ARRAY_INT32: + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%d", ((int32_t*)data)[i]); + break; + case TYPED_ARRAY_UINT32: + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%u", ((uint32_t*)data)[i]); + break; + case TYPED_ARRAY_FLOAT16: + n += (size_t) snprintf( + buf + n, REMAIN(n, len), "%g", half_to_double(((uint16_t*)data)[i]) + ); + break; + case TYPED_ARRAY_FLOAT32: + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%g", (double)((float*)data)[i]); + break; + case TYPED_ARRAY_FLOAT64: + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%g", ((double*)data)[i]); + break; + case TYPED_ARRAY_BIGINT64: + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%lldn", (long long)((int64_t*)data)[i]); + break; + case TYPED_ARRAY_BIGUINT64: + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%llun", (unsigned long long)((uint64_t*)data)[i]); + break; + default: + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%u", (unsigned)data[i]); + break; } - - if (ta->length > 100) n += cpy(buf + n, REMAIN(n, len), ", ...", 5); - n += cpy(buf + n, REMAIN(n, len), " ]", 2); - pop_stringify(); - return n; } + + if (ta->length > 100) n += cpy(buf + n, REMAIN(n, len), ", ...", 5); + n += cpy(buf + n, REMAIN(n, len), " ]", 2); + pop_stringify(); + return n; } if (is_arraybuffer) { - ant_value_t buf_val = js_get_slot(obj, SLOT_BUFFER); - if (vtype(buf_val) == T_NUM) { - ArrayBufferData *ab_data = (ArrayBufferData *)(uintptr_t)tod(buf_val); + ArrayBufferData *ab_data = buffer_get_arraybuffer_data(obj); + if (ab_data) { size_t bytelen = ab_data ? ab_data->length : 0; n += cpy(buf + n, REMAIN(n, len), tag_str, tlen); @@ -1273,34 +1269,31 @@ static size_t strobj(ant_t *js, ant_value_t obj, char *buf, size_t len) { bool is_dataview = (tlen == 8 && memcmp(tag_str, "DataView", 8) == 0); if (is_dataview) { - ant_value_t dv_data_val = js_get_slot(obj, SLOT_DATA); - if (vtype(dv_data_val) == T_NUM) { - DataViewData *dv = (DataViewData *)(uintptr_t)tod(dv_data_val); - if (dv && dv->buffer) { - n += cpy(buf + n, REMAIN(n, len), "DataView {\n", 11); - n += cpy(buf + n, REMAIN(n, len), " [byteLength]: ", 16); - n += (size_t) snprintf(buf + n, REMAIN(n, len), "%zu", dv->byte_length); - n += cpy(buf + n, REMAIN(n, len), ",\n", 2); - n += cpy(buf + n, REMAIN(n, len), " [byteOffset]: ", 16); - n += (size_t) snprintf(buf + n, REMAIN(n, len), "%zu", dv->byte_offset); - n += cpy(buf + n, REMAIN(n, len), ",\n", 2); - n += cpy(buf + n, REMAIN(n, len), " [buffer]: ArrayBuffer {\n", 26); - n += cpy(buf + n, REMAIN(n, len), " [Uint8Contents]: <", 22); - - if (dv->buffer->data && dv->buffer->length > 0) { - for (size_t i = 0; i < dv->buffer->length; i++) { - if (i > 0) n += cpy(buf + n, REMAIN(n, len), " ", 1); - n += (size_t) snprintf(buf + n, REMAIN(n, len), "%02x", dv->buffer->data[i]); - } + DataViewData *dv = buffer_get_dataview_data(obj); + if (dv && dv->buffer) { + n += cpy(buf + n, REMAIN(n, len), "DataView {\n", 11); + n += cpy(buf + n, REMAIN(n, len), " [byteLength]: ", 16); + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%zu", dv->byte_length); + n += cpy(buf + n, REMAIN(n, len), ",\n", 2); + n += cpy(buf + n, REMAIN(n, len), " [byteOffset]: ", 16); + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%zu", dv->byte_offset); + n += cpy(buf + n, REMAIN(n, len), ",\n", 2); + n += cpy(buf + n, REMAIN(n, len), " [buffer]: ArrayBuffer {\n", 26); + n += cpy(buf + n, REMAIN(n, len), " [Uint8Contents]: <", 22); + + if (dv->buffer->data && dv->buffer->length > 0) { + for (size_t i = 0; i < dv->buffer->length; i++) { + if (i > 0) n += cpy(buf + n, REMAIN(n, len), " ", 1); + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%02x", dv->buffer->data[i]); } - - n += cpy(buf + n, REMAIN(n, len), ">,\n", 3); - n += cpy(buf + n, REMAIN(n, len), " [byteLength]: ", 18); - n += (size_t) snprintf(buf + n, REMAIN(n, len), "%zu", dv->buffer->length); - n += cpy(buf + n, REMAIN(n, len), "\n }\n}", 6); - pop_stringify(); - return n; } + + n += cpy(buf + n, REMAIN(n, len), ">,\n", 3); + n += cpy(buf + n, REMAIN(n, len), " [byteLength]: ", 18); + n += (size_t) snprintf(buf + n, REMAIN(n, len), "%zu", dv->buffer->length); + n += cpy(buf + n, REMAIN(n, len), "\n }\n}", 6); + pop_stringify(); + return n; } } @@ -12865,20 +12858,20 @@ void js_destroy(ant_t *js) { js_esm_cleanup_module_cache(); code_arena_reset(); - cleanup_buffer_module(); cleanup_lmdb_module(); ant_object_t *lists[] = { js->objects, js->objects_old, js->permanent_objects }; - for (int i = 0; i < 3; i++) - for (ant_object_t *obj = lists[i]; obj;) { - ant_object_t *next = obj->next; - gc_object_free(js, obj); - obj = next; - } + for (int i = 0; i < 3; i++) for (ant_object_t *obj = lists[i]; obj;) { + ant_object_t *next = obj->next; + gc_object_free(js, obj); + obj = next; + } js->objects = NULL; js->objects_old = NULL; js->permanent_objects = NULL; + + cleanup_buffer_module(); fixed_arena_destroy(&js->obj_arena); fixed_arena_destroy(&js->closure_arena); fixed_arena_destroy(&js->upvalue_arena); @@ -12886,9 +12879,11 @@ void js_destroy(ant_t *js) { free(js->prop_refs); js->prop_refs = NULL; js->prop_refs_len = js->prop_refs_cap = 0; + free(js->c_roots); js->c_roots = NULL; js->c_root_count = js->c_root_cap = 0; + free(js->pending_rejections.items); js->pending_rejections.items = NULL; js->pending_rejections.len = js->pending_rejections.cap = 0; @@ -12896,6 +12891,7 @@ void js_destroy(ant_t *js) { js_pool_destroy(&js->pool.rope); js_pool_destroy(&js->pool.symbol); js_pool_destroy(&js->pool.permanent); + js_class_pool_destroy(&js->pool.bigint); js_class_pool_destroy(&js->pool.string); diff --git a/src/modules/atomics.c b/src/modules/atomics.c index 3b38084..b34ae03 100644 --- a/src/modules/atomics.c +++ b/src/modules/atomics.c @@ -83,12 +83,12 @@ int wait_queue_notify(WaitQueue *queue, int32_t *address, int count) { } static bool get_atomic_array_data(ant_t *js, ant_value_t this_val, TypedArrayData **out_data, uint8_t **out_ptr) { - ant_value_t ta_data_val = js_get_slot(this_val, SLOT_BUFFER); - TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_data_val); + TypedArrayData *ta_data = buffer_get_typedarray_data(this_val); if (!ta_data || !ta_data->buffer) return false; *out_data = ta_data; *out_ptr = ta_data->buffer->data + ta_data->byte_offset; + return true; } diff --git a/src/modules/blob.c b/src/modules/blob.c index 577539f..4e1d457 100644 --- a/src/modules/blob.c +++ b/src/modules/blob.c @@ -99,27 +99,19 @@ static ant_value_t process_blob_part(ant_t *js, byte_buf_t *buf, ant_value_t par } if (t == T_OBJ) { - ant_value_t buf_slot = js_get_slot(part, SLOT_BUFFER); - if (vtype(buf_slot) == T_TYPEDARRAY) { - TypedArrayData *ta = (TypedArrayData *)js_gettypedarray(buf_slot); - if (ta && ta->buffer && !ta->buffer->is_detached) { - if (!byte_buf_append(buf, ta->buffer->data + ta->byte_offset, ta->byte_length)) - return js_mkerr(js, "out of memory"); - } + TypedArrayData *ta = buffer_get_typedarray_data(part); + if (ta && ta->buffer && !ta->buffer->is_detached) { + if (!byte_buf_append(buf, ta->buffer->data + ta->byte_offset, ta->byte_length)) return js_mkerr(js, "out of memory"); return js_mkundef(); } - if (vtype(buf_slot) == T_NUM) { - ArrayBufferData *abd = (ArrayBufferData *)(uintptr_t)(size_t)js_getnum(buf_slot); - if (abd && !abd->is_detached) { - if (!byte_buf_append(buf, abd->data, abd->length)) - return js_mkerr(js, "out of memory"); - return js_mkundef(); - } + ArrayBufferData *abd = buffer_get_arraybuffer_data(part); + if (abd && !abd->is_detached) { + if (!byte_buf_append(buf, abd->data, abd->length)) return js_mkerr(js, "out of memory"); + return js_mkundef(); } blob_data_t *bd = blob_get_data(part); if (bd && bd->size > 0) { - if (!byte_buf_append(buf, bd->data, bd->size)) - return js_mkerr(js, "out of memory"); + if (!byte_buf_append(buf, bd->data, bd->size)) return js_mkerr(js, "out of memory"); return js_mkundef(); } } diff --git a/src/modules/buffer.c b/src/modules/buffer.c index 8af5920..5835d41 100644 --- a/src/modules/buffer.c +++ b/src/modules/buffer.c @@ -3,13 +3,6 @@ #include #include -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#else -#include -#endif - #include "ant.h" #include "utf8.h" #include "utils.h" @@ -18,36 +11,106 @@ #include "internal.h" #include "runtime.h" #include "descriptors.h" +#include "ptr.h" #include "silver/engine.h" #include "modules/buffer.h" #include "modules/symbol.h" -#define TA_ARENA_SIZE (16 * 1024 * 1024) #define BUFFER_REGISTRY_INITIAL_CAP 64 -static uint8_t *ta_arena = NULL; -static size_t ta_arena_offset = 0; - +static size_t ta_metadata_bytes = 0; static size_t buffer_registry_count = 0; static size_t buffer_registry_cap = 0; static ArrayBufferData **buffer_registry = NULL; static ant_value_t g_typedarray_iter_proto = 0; +enum { + BUFFER_ARRAYBUFFER_NATIVE_TAG = 0x41425546u, // ABUF + BUFFER_TYPEDARRAY_NATIVE_TAG = 0x54594152u, // TYAR + BUFFER_DATAVIEW_NATIVE_TAG = 0x44564957u, // DVIW +}; + +static void *ta_meta_alloc(size_t size) { + void *ptr = ant_calloc(size); + if (!ptr) return NULL; + ta_metadata_bytes += size; + return ptr; +} + +static void ta_meta_free(void *ptr, size_t size) { + if (!ptr) return; + if (ta_metadata_bytes >= size) ta_metadata_bytes -= size; + else ta_metadata_bytes = 0; + free(ptr); +} + +ArrayBufferData *buffer_get_arraybuffer_data(ant_value_t value) { + if (!is_object_type(value) || buffer_is_dataview(value)) return NULL; + if (js_check_native_tag(value, BUFFER_ARRAYBUFFER_NATIVE_TAG)) + return (ArrayBufferData *)js_get_native_ptr(value); + return NULL; +} + +TypedArrayData *buffer_get_typedarray_data(ant_value_t value) { + if (vtype(value) == T_TYPEDARRAY) + return (TypedArrayData *)js_gettypedarray(value); + if (!is_object_type(value)) return NULL; + if (js_check_native_tag(value, BUFFER_TYPEDARRAY_NATIVE_TAG)) + return (TypedArrayData *)js_get_native_ptr(value); + return NULL; +} + +DataViewData *buffer_get_dataview_data(ant_value_t value) { + if (!is_object_type(value)) return NULL; + if (js_check_native_tag(value, BUFFER_DATAVIEW_NATIVE_TAG)) + return (DataViewData *)js_get_native_ptr(value); + return NULL; +} + +static void arraybuffer_finalize(ant_t *js, ant_object_t *obj) { + ant_value_t value = js_obj_from_ptr(obj); + if (!js_check_native_tag(value, BUFFER_ARRAYBUFFER_NATIVE_TAG)) return; + ArrayBufferData *data = (ArrayBufferData *)js_get_native_ptr(value); + js_set_native_ptr(value, NULL); + js_set_native_tag(value, 0); + if (data) free_array_buffer_data(data); +} + +static void typedarray_finalize(ant_t *js, ant_object_t *obj) { + ant_value_t value = js_obj_from_ptr(obj); + if (!js_check_native_tag(value, BUFFER_TYPEDARRAY_NATIVE_TAG)) return; + TypedArrayData *ta_data = (TypedArrayData *)js_get_native_ptr(value); + js_set_native_ptr(value, NULL); + js_set_native_tag(value, 0); + if (!ta_data) return; + + if (ta_data->buffer) free_array_buffer_data(ta_data->buffer); + ta_meta_free(ta_data, sizeof(*ta_data)); +} + +static void dataview_finalize(ant_t *js, ant_object_t *obj) { + ant_value_t value = js_obj_from_ptr(obj); + if (!js_check_native_tag(value, BUFFER_DATAVIEW_NATIVE_TAG)) return; + DataViewData *dv_data = (DataViewData *)js_get_native_ptr(value); + js_set_native_ptr(value, NULL); + js_set_native_tag(value, 0); + if (!dv_data) return; + + if (dv_data->buffer) free_array_buffer_data(dv_data->buffer); + ta_meta_free(dv_data, sizeof(*dv_data)); +} + bool buffer_is_dataview(ant_value_t obj) { return js_check_brand(obj, BRAND_DATAVIEW); } bool buffer_is_binary_source(ant_value_t value) { - ant_value_t slot = 0; - if (vtype(value) == T_TYPEDARRAY) return true; if (!is_object_type(value)) return false; if (buffer_is_dataview(value)) return true; - - slot = js_get_slot(value, SLOT_BUFFER); - return vtype(slot) == T_TYPEDARRAY || vtype(slot) == T_NUM; + return buffer_get_typedarray_data(value) != NULL || buffer_get_arraybuffer_data(value) != NULL; } bool buffer_source_get_bytes(ant_t *js, ant_value_t value, const uint8_t **out, size_t *len) { @@ -55,8 +118,7 @@ bool buffer_source_get_bytes(ant_t *js, ant_value_t value, const uint8_t **out, if (len) *len = 0; if (!buffer_is_binary_source(value)) return false; - ant_value_t slot = js_get_slot(value, SLOT_BUFFER); - TypedArrayData *ta = (TypedArrayData *)js_gettypedarray(slot); + TypedArrayData *ta = buffer_get_typedarray_data(value); if (ta) { if (!ta->buffer || ta->buffer->is_detached) { *out = NULL; *len = 0; return true; } @@ -65,18 +127,16 @@ bool buffer_source_get_bytes(ant_t *js, ant_value_t value, const uint8_t **out, return true; } - if (vtype(slot) == T_NUM) { - ArrayBufferData *ab = (ArrayBufferData *)(uintptr_t)(size_t)js_getnum(slot); - if (!ab || ab->is_detached) { *out = NULL; *len = 0; return true; } + ArrayBufferData *ab = buffer_get_arraybuffer_data(value); + if (ab) { + if (ab->is_detached) { *out = NULL; *len = 0; return true; } *out = ab->data; *len = ab->length; return true; } if (buffer_is_dataview(value)) { - ant_value_t dv_data_val = js_get_slot(value, SLOT_DATA); - if (vtype(dv_data_val) != T_NUM) return false; - DataViewData *dv = (DataViewData *)(uintptr_t)js_getnum(dv_data_val); + DataViewData *dv = buffer_get_dataview_data(value); if (!dv || !dv->buffer || dv->buffer->is_detached) { *out = NULL; *len = 0; return true; } *out = dv->buffer->data + dv->byte_offset; *len = dv->byte_length; @@ -95,8 +155,7 @@ static bool advance_typedarray(ant_t *js, js_iter_t *it, ant_value_t *out) { uint32_t kind = ITER_STATE_KIND(state); uint32_t idx = ITER_STATE_INDEX(state); - ant_value_t ta_val = js_get_slot(ta_obj, SLOT_BUFFER); - TypedArrayData *ta = (TypedArrayData *)js_gettypedarray(ta_val); + TypedArrayData *ta = buffer_get_typedarray_data(ta_obj); if (!ta || !ta->buffer || ta->buffer->is_detached || idx >= (uint32_t)ta->length) return false; @@ -190,11 +249,10 @@ static void unregister_buffer(ArrayBufferData *data) { if (!data || !buffer_registry) return; for (size_t i = 0; i < buffer_registry_count; i++) { - if (buffer_registry[i] == data) { - buffer_registry[i] = buffer_registry[--buffer_registry_count]; - return; - } - } + if (buffer_registry[i] == data) { + buffer_registry[i] = buffer_registry[--buffer_registry_count]; + return; + }} } static inline ssize_t normalize_index(ssize_t idx, ssize_t len) { @@ -204,35 +262,6 @@ static inline ssize_t normalize_index(ssize_t idx, ssize_t len) { return idx; } -static void *ta_arena_alloc(size_t size) { - size = (size + 7) & ~7; - - if (!ta_arena) { -#ifdef _WIN32 - ta_arena = VirtualAlloc(NULL, TA_ARENA_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); - if (!ta_arena) return NULL; -#else - void *hint = (void *)0x100000; - ta_arena = mmap( - hint, TA_ARENA_SIZE, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - - if (ta_arena == MAP_FAILED) { - ta_arena = mmap( - NULL, TA_ARENA_SIZE, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - } - if (ta_arena == MAP_FAILED) return NULL; -#endif - } - - if (ta_arena_offset + size > TA_ARENA_SIZE) return NULL; - void *ptr = ta_arena + ta_arena_offset; - ta_arena_offset += size; - - return ptr; -} - ArrayBufferData *create_array_buffer_data(size_t length) { ArrayBufferData *data = ant_calloc(sizeof(ArrayBufferData) + length); if (!data) return NULL; @@ -340,8 +369,10 @@ static ant_value_t js_arraybuffer_constructor(ant_t *js, ant_value_t *args, int ant_value_t proto = js_get_ctor_proto(js, "ArrayBuffer", 11); if (is_special_object(proto)) js_set_proto_init(obj, proto); - js_set_slot(obj, SLOT_BUFFER, ANT_PTR(data)); + js_set_native_ptr(obj, data); + js_set_native_tag(obj, BUFFER_ARRAYBUFFER_NATIVE_TAG); js_set(js, obj, "byteLength", js_mknum((double)length)); + js_set_finalizer(obj, arraybuffer_finalize); return obj; } @@ -349,13 +380,7 @@ static ant_value_t js_arraybuffer_constructor(ant_t *js, ant_value_t *args, int // ArrayBuffer.prototype.slice(begin, end) static ant_value_t js_arraybuffer_slice(ant_t *js, ant_value_t *args, int nargs) { ant_value_t this_val = js_getthis(js); - ant_value_t data_val = js_get_slot(this_val, SLOT_BUFFER); - - if (vtype(data_val) != T_NUM) { - return js_mkerr(js, "Not an ArrayBuffer"); - } - - ArrayBufferData *data = (ArrayBufferData *)(uintptr_t)js_getnum(data_val); + ArrayBufferData *data = buffer_get_arraybuffer_data(this_val); if (!data) return js_mkerr(js, "Invalid ArrayBuffer"); if (data->is_detached) return js_mkerr(js, "Cannot slice a detached ArrayBuffer"); @@ -378,8 +403,10 @@ static ant_value_t js_arraybuffer_slice(ant_t *js, ant_value_t *args, int nargs) ant_value_t proto = js_get_ctor_proto(js, "ArrayBuffer", 11); if (is_special_object(proto)) js_set_proto_init(new_obj, proto); - js_set_slot(new_obj, SLOT_BUFFER, ANT_PTR(new_data)); + js_set_native_ptr(new_obj, new_data); + js_set_native_tag(new_obj, BUFFER_ARRAYBUFFER_NATIVE_TAG); js_set(js, new_obj, "byteLength", js_mknum((double)new_length)); + js_set_finalizer(new_obj, arraybuffer_finalize); return new_obj; } @@ -387,13 +414,7 @@ static ant_value_t js_arraybuffer_slice(ant_t *js, ant_value_t *args, int nargs) // ArrayBuffer.prototype.transfer(newLength) static ant_value_t js_arraybuffer_transfer(ant_t *js, ant_value_t *args, int nargs) { ant_value_t this_val = js_getthis(js); - ant_value_t data_val = js_get_slot(this_val, SLOT_BUFFER); - - if (vtype(data_val) != T_NUM) { - return js_mkerr(js, "Not an ArrayBuffer"); - } - - ArrayBufferData *data = (ArrayBufferData *)(uintptr_t)js_getnum(data_val); + ArrayBufferData *data = buffer_get_arraybuffer_data(this_val); if (!data) return js_mkerr(js, "Invalid ArrayBuffer"); if (data->is_detached) { @@ -423,8 +444,10 @@ static ant_value_t js_arraybuffer_transfer(ant_t *js, ant_value_t *args, int nar ant_value_t proto = js_get_ctor_proto(js, "ArrayBuffer", 11); if (is_special_object(proto)) js_set_proto_init(new_obj, proto); - js_set_slot(new_obj, SLOT_BUFFER, ANT_PTR(new_data)); + js_set_native_ptr(new_obj, new_data); + js_set_native_tag(new_obj, BUFFER_ARRAYBUFFER_NATIVE_TAG); js_set(js, new_obj, "byteLength", js_mknum((double)new_length)); + js_set_finalizer(new_obj, arraybuffer_finalize); return new_obj; } @@ -437,11 +460,8 @@ static ant_value_t js_arraybuffer_transferToFixedLength(ant_t *js, ant_value_t * // ArrayBuffer.prototype.detached getter static ant_value_t js_arraybuffer_detached_getter(ant_t *js, ant_value_t *args, int nargs) { ant_value_t this_val = js_getthis(js); - ant_value_t data_val = js_get_slot(this_val, SLOT_BUFFER); - if (vtype(data_val) != T_NUM) return js_false; - - ArrayBufferData *data = (ArrayBufferData *)(uintptr_t)js_getnum(data_val); - if (!data) return js_true; + ArrayBufferData *data = buffer_get_arraybuffer_data(this_val); + if (!data) return js_false; return js_bool(data->is_detached); } @@ -456,8 +476,7 @@ static ant_value_t typedarray_index_getter(ant_t *js, ant_value_t obj, const cha index = index * 10 + (c - '0'); } - ant_value_t ta_val = js_get_slot(obj, SLOT_BUFFER); - TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_val); + TypedArrayData *ta_data = buffer_get_typedarray_data(obj); if (!ta_data || index >= ta_data->length) return js_mkundef(); if (!ta_data->buffer || ta_data->buffer->is_detached) return js_mkundef(); @@ -495,8 +514,7 @@ static bool typedarray_index_setter(ant_t *js, ant_value_t obj, const char *key, index = index * 10 + (c - '0'); } - ant_value_t ta_val = js_get_slot(obj, SLOT_BUFFER); - TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_val); + TypedArrayData *ta_data = buffer_get_typedarray_data(obj); if (!ta_data || index >= ta_data->length) return true; if (!ta_data->buffer || ta_data->buffer->is_detached) return true; @@ -577,8 +595,10 @@ ant_value_t create_arraybuffer_obj(ant_t *js, ArrayBufferData *buffer) { ant_value_t ab_proto = js_get_ctor_proto(js, "ArrayBuffer", 11); if (is_special_object(ab_proto)) js_set_proto_init(ab_obj, ab_proto); - js_set_slot(ab_obj, SLOT_BUFFER, js_mknum((double)(uintptr_t)buffer)); + js_set_native_ptr(ab_obj, buffer); + js_set_native_tag(ab_obj, BUFFER_ARRAYBUFFER_NATIVE_TAG); js_set(js, ab_obj, "byteLength", js_mknum((double)buffer->length)); + js_set_finalizer(ab_obj, arraybuffer_finalize); buffer->ref_count++; return ab_obj; @@ -588,7 +608,7 @@ ant_value_t create_typed_array_with_buffer( ant_t *js, TypedArrayType type, ArrayBufferData *buffer, size_t byte_offset, size_t length, const char *type_name, ant_value_t arraybuffer_obj ) { - TypedArrayData *ta_data = ta_arena_alloc(sizeof(TypedArrayData)); + TypedArrayData *ta_data = ta_meta_alloc(sizeof(TypedArrayData)); if (!ta_data) return js_mkerr(js, "Failed to allocate TypedArray"); size_t element_size = get_element_size(type); @@ -603,7 +623,8 @@ ant_value_t create_typed_array_with_buffer( ant_value_t proto = js_get_ctor_proto(js, type_name, strlen(type_name)); if (is_special_object(proto)) js_set_proto_init(obj, proto); - js_set_slot(obj, SLOT_BUFFER, js_mktypedarray(ta_data)); + js_set_native_ptr(obj, ta_data); + js_set_native_tag(obj, BUFFER_TYPEDARRAY_NATIVE_TAG); js_set(js, obj, "length", js_mknum((double)length)); js_set(js, obj, "byteLength", js_mknum((double)(length * element_size))); js_set(js, obj, "byteOffset", js_mknum((double)byte_offset)); @@ -612,6 +633,7 @@ ant_value_t create_typed_array_with_buffer( js_set_getter(obj, typedarray_index_getter); js_set_setter(obj, typedarray_index_setter); + js_set_finalizer(obj, typedarray_finalize); return obj; } @@ -630,7 +652,7 @@ ant_value_t create_dataview_with_buffer( size_t byte_offset, size_t byte_length, ant_value_t arraybuffer_obj ) { - DataViewData *dv_data = ta_arena_alloc(sizeof(DataViewData)); + DataViewData *dv_data = ta_meta_alloc(sizeof(DataViewData)); if (!dv_data) return js_mkerr(js, "Failed to allocate DataView"); dv_data->buffer = buffer; @@ -642,12 +664,14 @@ ant_value_t create_dataview_with_buffer( ant_value_t proto = js_get_ctor_proto(js, "DataView", 8); if (is_special_object(proto)) js_set_proto_init(obj, proto); + js_set_native_ptr(obj, dv_data); + js_set_native_tag(obj, BUFFER_DATAVIEW_NATIVE_TAG); js_set_slot(obj, SLOT_BRAND, js_mknum(BRAND_DATAVIEW)); - js_set_slot(obj, SLOT_DATA, ANT_PTR(dv_data)); js_mkprop_fast(js, obj, "buffer", 6, arraybuffer_obj); js_set_descriptor(js, obj, "buffer", 6, 0); js_set(js, obj, "byteLength", js_mknum((double)byte_length)); js_set(js, obj, "byteOffset", js_mknum((double)byte_offset)); + js_set_finalizer(obj, dataview_finalize); return obj; } @@ -685,9 +709,9 @@ static ant_value_t js_typedarray_constructor(ant_t *js, ant_value_t *args, int n return create_typed_array(js, type, buffer, 0, length, type_name); } - ant_value_t buffer_data_val = js_get_slot(args[0], SLOT_BUFFER); - if (vtype(buffer_data_val) == T_NUM) { - ArrayBufferData *buffer = (ArrayBufferData *)(uintptr_t)js_getnum(buffer_data_val); + ArrayBufferData *arraybuffer = buffer_get_arraybuffer_data(args[0]); + if (arraybuffer) { + ArrayBufferData *buffer = arraybuffer; size_t byte_offset = 0; size_t length = buffer->length; @@ -781,9 +805,7 @@ static ant_value_t js_typedarray_constructor(ant_t *js, ant_value_t *args, int n // TypedArray.prototype.at(index) static ant_value_t js_typedarray_at(ant_t *js, ant_value_t *args, int nargs) { ant_value_t this_val = js_getthis(js); - ant_value_t ta_data_val = js_get_slot(this_val, SLOT_BUFFER); - - TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_data_val); + TypedArrayData *ta_data = buffer_get_typedarray_data(this_val); if (!ta_data) return js_mkerr(js, "Invalid TypedArray"); if (nargs == 0 || vtype(args[0]) != T_NUM) return js_mkundef(); @@ -816,9 +838,7 @@ static ant_value_t js_typedarray_at(ant_t *js, ant_value_t *args, int nargs) { static ant_value_t js_typedarray_slice(ant_t *js, ant_value_t *args, int nargs) { ant_value_t this_val = js_getthis(js); - ant_value_t ta_data_val = js_get_slot(this_val, SLOT_BUFFER); - - TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_data_val); + TypedArrayData *ta_data = buffer_get_typedarray_data(this_val); if (!ta_data) return js_mkerr(js, "Invalid TypedArray"); ssize_t len = (ssize_t)ta_data->length; @@ -853,9 +873,7 @@ static ant_value_t js_typedarray_slice(ant_t *js, ant_value_t *args, int nargs) // TypedArray.prototype.subarray(begin, end) static ant_value_t js_typedarray_subarray(ant_t *js, ant_value_t *args, int nargs) { ant_value_t this_val = js_getthis(js); - ant_value_t ta_data_val = js_get_slot(this_val, SLOT_BUFFER); - - TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_data_val); + TypedArrayData *ta_data = buffer_get_typedarray_data(this_val); if (!ta_data) return js_mkerr(js, "Invalid TypedArray"); ssize_t len = (ssize_t)ta_data->length; @@ -881,9 +899,7 @@ static ant_value_t js_typedarray_subarray(ant_t *js, ant_value_t *args, int narg // TypedArray.prototype.fill(value, start, end) static ant_value_t js_typedarray_fill(ant_t *js, ant_value_t *args, int nargs) { ant_value_t this_val = js_getthis(js); - ant_value_t ta_data_val = js_get_slot(this_val, SLOT_BUFFER); - - TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_data_val); + TypedArrayData *ta_data = buffer_get_typedarray_data(this_val); if (!ta_data) return js_mkerr(js, "Invalid TypedArray"); double value = 0; @@ -945,8 +961,7 @@ static ant_value_t js_typedarray_set(ant_t *js, ant_value_t *args, int nargs) { if (nargs < 1) return js_mkerr(js, "set requires source argument"); ant_value_t this_val = js_getthis(js); - ant_value_t dst_ta_val = js_get_slot(this_val, SLOT_BUFFER); - TypedArrayData *dst = (TypedArrayData *)js_gettypedarray(dst_ta_val); + TypedArrayData *dst = buffer_get_typedarray_data(this_val); if (!dst) return js_mkerr(js, "Invalid TypedArray"); if (!dst->buffer || dst->buffer->is_detached) return js_mkerr(js, "Cannot operate on a detached TypedArray"); @@ -957,8 +972,7 @@ static ant_value_t js_typedarray_set(ant_t *js, ant_value_t *args, int nargs) { if (offset > dst->length) return js_mkerr(js, "Offset out of bounds"); ant_value_t src_val = args[0]; - ant_value_t src_ta_val = js_get_slot(src_val, SLOT_BUFFER); - TypedArrayData *src_ta = (TypedArrayData *)js_gettypedarray(src_ta_val); + TypedArrayData *src_ta = buffer_get_typedarray_data(src_val); if (src_ta && src_ta->buffer && !src_ta->buffer->is_detached) { size_t src_len = src_ta->length; @@ -1017,8 +1031,7 @@ static ant_value_t js_typedarray_set(ant_t *js, ant_value_t *args, int nargs) { // TypedArray.prototype.copyWithin(target, start, end) static ant_value_t js_typedarray_copyWithin(ant_t *js, ant_value_t *args, int nargs) { ant_value_t this_val = js_getthis(js); - ant_value_t ta_data_val = js_get_slot(this_val, SLOT_BUFFER); - TypedArrayData *ta = (TypedArrayData *)js_gettypedarray(ta_data_val); + TypedArrayData *ta = buffer_get_typedarray_data(this_val); if (!ta) return js_mkerr(js, "Invalid TypedArray"); if (!ta->buffer || ta->buffer->is_detached) return js_mkerr(js, "Cannot operate on a detached TypedArray"); @@ -1051,9 +1064,7 @@ static ant_value_t js_typedarray_copyWithin(ant_t *js, ant_value_t *args, int na static ant_value_t js_typedarray_toReversed(ant_t *js, ant_value_t *args, int nargs) { (void)args; (void)nargs; ant_value_t this_val = js_getthis(js); - ant_value_t ta_data_val = js_get_slot(this_val, SLOT_BUFFER); - - TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_data_val); + TypedArrayData *ta_data = buffer_get_typedarray_data(this_val); if (!ta_data) return js_mkerr(js, "Invalid TypedArray"); size_t length = ta_data->length; @@ -1079,9 +1090,7 @@ static ant_value_t js_typedarray_toReversed(ant_t *js, ant_value_t *args, int na // TypedArray.prototype.toSorted(comparefn) static ant_value_t js_typedarray_toSorted(ant_t *js, ant_value_t *args, int nargs) { ant_value_t this_val = js_getthis(js); - ant_value_t ta_data_val = js_get_slot(this_val, SLOT_BUFFER); - - TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_data_val); + TypedArrayData *ta_data = buffer_get_typedarray_data(this_val); if (!ta_data) return js_mkerr(js, "Invalid TypedArray"); size_t length = ta_data->length; @@ -1095,8 +1104,7 @@ static ant_value_t js_typedarray_toSorted(ant_t *js, ant_value_t *args, int narg free_array_buffer_data(new_buffer); if (is_err(result)) return result; - ant_value_t result_ta_val = js_get_slot(result, SLOT_BUFFER); - TypedArrayData *result_ta = (TypedArrayData *)js_gettypedarray(result_ta_val); + TypedArrayData *result_ta = buffer_get_typedarray_data(result); uint8_t *data = result_ta->buffer->data; ant_value_t comparefn = (nargs > 0 && vtype(args[0]) == T_FUNC) ? args[0] : js_mkundef(); @@ -1167,9 +1175,7 @@ static ant_value_t js_typedarray_with(ant_t *js, ant_value_t *args, int nargs) { if (nargs < 2) return js_mkerr(js, "with requires index and value"); ant_value_t this_val = js_getthis(js); - ant_value_t ta_data_val = js_get_slot(this_val, SLOT_BUFFER); - - TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_data_val); + TypedArrayData *ta_data = buffer_get_typedarray_data(this_val); if (!ta_data) return js_mkerr(js, "Invalid TypedArray"); ssize_t index = (ssize_t)js_getnum(args[0]); @@ -1347,12 +1353,10 @@ static ant_value_t js_dataview_constructor(ant_t *js, ant_value_t *args, int nar return js_mkerr(js, "DataView requires an ArrayBuffer"); } - ant_value_t buffer_data_val = js_get_slot(args[0], SLOT_BUFFER); - if (vtype(buffer_data_val) != T_NUM) { + ArrayBufferData *buffer = buffer_get_arraybuffer_data(args[0]); + if (!buffer) { return js_mkerr(js, "First argument must be an ArrayBuffer"); } - - ArrayBufferData *buffer = (ArrayBufferData *)(uintptr_t)js_getnum(buffer_data_val); size_t byte_offset = 0; size_t byte_length = buffer->length; @@ -1371,7 +1375,7 @@ static ant_value_t js_dataview_constructor(ant_t *js, ant_value_t *args, int nar } } else byte_length = buffer->length - byte_offset; - DataViewData *dv_data = ta_arena_alloc(sizeof(DataViewData)); + DataViewData *dv_data = ta_meta_alloc(sizeof(DataViewData)); if (!dv_data) return js_mkerr(js, "Failed to allocate DataView"); dv_data->buffer = buffer; @@ -1383,13 +1387,15 @@ static ant_value_t js_dataview_constructor(ant_t *js, ant_value_t *args, int nar ant_value_t proto = js_get_ctor_proto(js, "DataView", 8); if (is_special_object(proto)) js_set_proto_init(obj, proto); + js_set_native_ptr(obj, dv_data); + js_set_native_tag(obj, BUFFER_DATAVIEW_NATIVE_TAG); js_set_slot(obj, SLOT_BRAND, js_mknum(BRAND_DATAVIEW)); - js_set_slot(obj, SLOT_DATA, ANT_PTR(dv_data)); js_mkprop_fast(js, obj, "buffer", 6, args[0]); js_set_descriptor(js, obj, "buffer", 6, 0); js_set(js, obj, "byteLength", js_mknum((double)byte_length)); js_set(js, obj, "byteOffset", js_mknum((double)byte_offset)); + js_set_finalizer(obj, dataview_finalize); return obj; } @@ -1399,13 +1405,8 @@ static ant_value_t js_dataview_getInt8(ant_t *js, ant_value_t *args, int nargs) if (nargs < 1) return js_mkerr(js, "getInt8 requires byteOffset"); ant_value_t this_val = js_getthis(js); - ant_value_t dv_data_val = js_get_slot(this_val, SLOT_DATA); - - if (vtype(dv_data_val) != T_NUM) { - return js_mkerr(js, "Not a DataView"); - } - - DataViewData *dv = (DataViewData *)(uintptr_t)js_getnum(dv_data_val); + DataViewData *dv = buffer_get_dataview_data(this_val); + if (!dv) return js_mkerr(js, "Not a DataView"); size_t offset = (size_t)js_getnum(args[0]); if (offset >= dv->byte_length) { @@ -1421,13 +1422,8 @@ static ant_value_t js_dataview_setInt8(ant_t *js, ant_value_t *args, int nargs) if (nargs < 2) return js_mkerr(js, "setInt8 requires byteOffset and value"); ant_value_t this_val = js_getthis(js); - ant_value_t dv_data_val = js_get_slot(this_val, SLOT_DATA); - - if (vtype(dv_data_val) != T_NUM) { - return js_mkerr(js, "Not a DataView"); - } - - DataViewData *dv = (DataViewData *)(uintptr_t)js_getnum(dv_data_val); + DataViewData *dv = buffer_get_dataview_data(this_val); + if (!dv) return js_mkerr(js, "Not a DataView"); size_t offset = (size_t)js_getnum(args[0]); int8_t value = (int8_t)js_to_int32(js_getnum(args[1])); @@ -1444,13 +1440,8 @@ static ant_value_t js_dataview_getUint8(ant_t *js, ant_value_t *args, int nargs) if (nargs < 1) return js_mkerr(js, "getUint8 requires byteOffset"); ant_value_t this_val = js_getthis(js); - ant_value_t dv_data_val = js_get_slot(this_val, SLOT_DATA); - - if (vtype(dv_data_val) != T_NUM) { - return js_mkerr(js, "Not a DataView"); - } - - DataViewData *dv = (DataViewData *)(uintptr_t)js_getnum(dv_data_val); + DataViewData *dv = buffer_get_dataview_data(this_val); + if (!dv) return js_mkerr(js, "Not a DataView"); size_t offset = (size_t)js_getnum(args[0]); if (offset >= dv->byte_length) { @@ -1466,13 +1457,8 @@ static ant_value_t js_dataview_setUint8(ant_t *js, ant_value_t *args, int nargs) if (nargs < 2) return js_mkerr(js, "setUint8 requires byteOffset and value"); ant_value_t this_val = js_getthis(js); - ant_value_t dv_data_val = js_get_slot(this_val, SLOT_DATA); - - if (vtype(dv_data_val) != T_NUM) { - return js_mkerr(js, "Not a DataView"); - } - - DataViewData *dv = (DataViewData *)(uintptr_t)js_getnum(dv_data_val); + DataViewData *dv = buffer_get_dataview_data(this_val); + if (!dv) return js_mkerr(js, "Not a DataView"); size_t offset = (size_t)js_getnum(args[0]); uint8_t value = (uint8_t)js_to_uint32(js_getnum(args[1])); @@ -1489,13 +1475,8 @@ static ant_value_t js_dataview_getInt16(ant_t *js, ant_value_t *args, int nargs) if (nargs < 1) return js_mkerr(js, "getInt16 requires byteOffset"); ant_value_t this_val = js_getthis(js); - ant_value_t dv_data_val = js_get_slot(this_val, SLOT_DATA); - - if (vtype(dv_data_val) != T_NUM) { - return js_mkerr(js, "Not a DataView"); - } - - DataViewData *dv = (DataViewData *)(uintptr_t)js_getnum(dv_data_val); + DataViewData *dv = buffer_get_dataview_data(this_val); + if (!dv) return js_mkerr(js, "Not a DataView"); size_t offset = (size_t)js_getnum(args[0]); bool little_endian = (nargs > 1 && js_truthy(js, args[1])); @@ -1520,13 +1501,8 @@ static ant_value_t js_dataview_getUint16(ant_t *js, ant_value_t *args, int nargs if (nargs < 1) return js_mkerr(js, "getUint16 requires byteOffset"); ant_value_t this_val = js_getthis(js); - ant_value_t dv_data_val = js_get_slot(this_val, SLOT_DATA); - - if (vtype(dv_data_val) != T_NUM) { - return js_mkerr(js, "Not a DataView"); - } - - DataViewData *dv = (DataViewData *)(uintptr_t)js_getnum(dv_data_val); + DataViewData *dv = buffer_get_dataview_data(this_val); + if (!dv) return js_mkerr(js, "Not a DataView"); size_t offset = (size_t)js_getnum(args[0]); bool little_endian = (nargs > 1 && js_truthy(js, args[1])); @@ -1548,13 +1524,8 @@ static ant_value_t js_dataview_setUint16(ant_t *js, ant_value_t *args, int nargs if (nargs < 2) return js_mkerr(js, "setUint16 requires byteOffset and value"); ant_value_t this_val = js_getthis(js); - ant_value_t dv_data_val = js_get_slot(this_val, SLOT_DATA); - - if (vtype(dv_data_val) != T_NUM) { - return js_mkerr(js, "Not a DataView"); - } - - DataViewData *dv = (DataViewData *)(uintptr_t)js_getnum(dv_data_val); + DataViewData *dv = buffer_get_dataview_data(this_val); + if (!dv) return js_mkerr(js, "Not a DataView"); size_t offset = (size_t)js_getnum(args[0]); uint16_t value = (uint16_t)js_to_uint32(js_getnum(args[1])); bool little_endian = (nargs > 2 && js_truthy(js, args[2])); @@ -1581,13 +1552,8 @@ static ant_value_t js_dataview_getInt32(ant_t *js, ant_value_t *args, int nargs) if (nargs < 1) return js_mkerr(js, "getInt32 requires byteOffset"); ant_value_t this_val = js_getthis(js); - ant_value_t dv_data_val = js_get_slot(this_val, SLOT_DATA); - - if (vtype(dv_data_val) != T_NUM) { - return js_mkerr(js, "Not a DataView"); - } - - DataViewData *dv = (DataViewData *)(uintptr_t)js_getnum(dv_data_val); + DataViewData *dv = buffer_get_dataview_data(this_val); + if (!dv) return js_mkerr(js, "Not a DataView"); size_t offset = (size_t)js_getnum(args[0]); bool little_endian = (nargs > 1 && js_truthy(js, args[1])); @@ -1612,13 +1578,8 @@ static ant_value_t js_dataview_getFloat32(ant_t *js, ant_value_t *args, int narg if (nargs < 1) return js_mkerr(js, "getFloat32 requires byteOffset"); ant_value_t this_val = js_getthis(js); - ant_value_t dv_data_val = js_get_slot(this_val, SLOT_DATA); - - if (vtype(dv_data_val) != T_NUM) { - return js_mkerr(js, "Not a DataView"); - } - - DataViewData *dv = (DataViewData *)(uintptr_t)js_getnum(dv_data_val); + DataViewData *dv = buffer_get_dataview_data(this_val); + if (!dv) return js_mkerr(js, "Not a DataView"); size_t offset = (size_t)js_getnum(args[0]); bool little_endian = (nargs > 1 && js_truthy(js, args[1])); @@ -1645,13 +1606,8 @@ static ant_value_t js_dataview_setInt16(ant_t *js, ant_value_t *args, int nargs) if (nargs < 2) return js_mkerr(js, "setInt16 requires byteOffset and value"); ant_value_t this_val = js_getthis(js); - ant_value_t dv_data_val = js_get_slot(this_val, SLOT_DATA); - - if (vtype(dv_data_val) != T_NUM) { - return js_mkerr(js, "Not a DataView"); - } - - DataViewData *dv = (DataViewData *)(uintptr_t)js_getnum(dv_data_val); + DataViewData *dv = buffer_get_dataview_data(this_val); + if (!dv) return js_mkerr(js, "Not a DataView"); size_t offset = (size_t)js_getnum(args[0]); int16_t value = (int16_t)js_to_int32(js_getnum(args[1])); bool little_endian = (nargs > 2 && js_truthy(js, args[2])); @@ -1678,13 +1634,8 @@ static ant_value_t js_dataview_setInt32(ant_t *js, ant_value_t *args, int nargs) if (nargs < 2) return js_mkerr(js, "setInt32 requires byteOffset and value"); ant_value_t this_val = js_getthis(js); - ant_value_t dv_data_val = js_get_slot(this_val, SLOT_DATA); - - if (vtype(dv_data_val) != T_NUM) { - return js_mkerr(js, "Not a DataView"); - } - - DataViewData *dv = (DataViewData *)(uintptr_t)js_getnum(dv_data_val); + DataViewData *dv = buffer_get_dataview_data(this_val); + if (!dv) return js_mkerr(js, "Not a DataView"); size_t offset = (size_t)js_getnum(args[0]); int32_t value = js_to_int32(js_getnum(args[1])); bool little_endian = (nargs > 2 && js_truthy(js, args[2])); @@ -1715,13 +1666,8 @@ static ant_value_t js_dataview_getUint32(ant_t *js, ant_value_t *args, int nargs if (nargs < 1) return js_mkerr(js, "getUint32 requires byteOffset"); ant_value_t this_val = js_getthis(js); - ant_value_t dv_data_val = js_get_slot(this_val, SLOT_DATA); - - if (vtype(dv_data_val) != T_NUM) { - return js_mkerr(js, "Not a DataView"); - } - - DataViewData *dv = (DataViewData *)(uintptr_t)js_getnum(dv_data_val); + DataViewData *dv = buffer_get_dataview_data(this_val); + if (!dv) return js_mkerr(js, "Not a DataView"); size_t offset = (size_t)js_getnum(args[0]); bool little_endian = (nargs > 1 && js_truthy(js, args[1])); @@ -1743,13 +1689,8 @@ static ant_value_t js_dataview_setUint32(ant_t *js, ant_value_t *args, int nargs if (nargs < 2) return js_mkerr(js, "setUint32 requires byteOffset and value"); ant_value_t this_val = js_getthis(js); - ant_value_t dv_data_val = js_get_slot(this_val, SLOT_DATA); - - if (vtype(dv_data_val) != T_NUM) { - return js_mkerr(js, "Not a DataView"); - } - - DataViewData *dv = (DataViewData *)(uintptr_t)js_getnum(dv_data_val); + DataViewData *dv = buffer_get_dataview_data(this_val); + if (!dv) return js_mkerr(js, "Not a DataView"); size_t offset = (size_t)js_getnum(args[0]); uint32_t value = js_to_uint32(js_getnum(args[1])); @@ -1778,13 +1719,8 @@ static ant_value_t js_dataview_setFloat32(ant_t *js, ant_value_t *args, int narg if (nargs < 2) return js_mkerr(js, "setFloat32 requires byteOffset and value"); ant_value_t this_val = js_getthis(js); - ant_value_t dv_data_val = js_get_slot(this_val, SLOT_DATA); - - if (vtype(dv_data_val) != T_NUM) { - return js_mkerr(js, "Not a DataView"); - } - - DataViewData *dv = (DataViewData *)(uintptr_t)js_getnum(dv_data_val); + DataViewData *dv = buffer_get_dataview_data(this_val); + if (!dv) return js_mkerr(js, "Not a DataView"); size_t offset = (size_t)js_getnum(args[0]); float value = (float)js_getnum(args[1]); bool little_endian = (nargs > 2 && js_truthy(js, args[2])); @@ -1817,13 +1753,8 @@ static ant_value_t js_dataview_getFloat64(ant_t *js, ant_value_t *args, int narg if (nargs < 1) return js_mkerr(js, "getFloat64 requires byteOffset"); ant_value_t this_val = js_getthis(js); - ant_value_t dv_data_val = js_get_slot(this_val, SLOT_DATA); - - if (vtype(dv_data_val) != T_NUM) { - return js_mkerr(js, "Not a DataView"); - } - - DataViewData *dv = (DataViewData *)(uintptr_t)js_getnum(dv_data_val); + DataViewData *dv = buffer_get_dataview_data(this_val); + if (!dv) return js_mkerr(js, "Not a DataView"); size_t offset = (size_t)js_getnum(args[0]); bool little_endian = (nargs > 1 && js_truthy(js, args[1])); @@ -1852,13 +1783,8 @@ static ant_value_t js_dataview_setFloat64(ant_t *js, ant_value_t *args, int narg if (nargs < 2) return js_mkerr(js, "setFloat64 requires byteOffset and value"); ant_value_t this_val = js_getthis(js); - ant_value_t dv_data_val = js_get_slot(this_val, SLOT_DATA); - - if (vtype(dv_data_val) != T_NUM) { - return js_mkerr(js, "Not a DataView"); - } - - DataViewData *dv = (DataViewData *)(uintptr_t)js_getnum(dv_data_val); + DataViewData *dv = buffer_get_dataview_data(this_val); + if (!dv) return js_mkerr(js, "Not a DataView"); size_t offset = (size_t)js_getnum(args[0]); double value = js_getnum(args[1]); bool little_endian = (nargs > 2 && js_truthy(js, args[2])); @@ -2045,9 +1971,7 @@ static ant_value_t js_buffer_allocUnsafe(ant_t *js, ant_value_t *args, int nargs } static ant_value_t typedarray_join_with(ant_t *js, ant_value_t this_val, const char *sep, size_t sep_len) { - ant_value_t ta_data_val = js_get_slot(this_val, SLOT_BUFFER); - - TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_data_val); + TypedArrayData *ta_data = buffer_get_typedarray_data(this_val); if (!ta_data) return js_mkstr(js, "", 0); if (!ta_data->buffer || ta_data->buffer->is_detached || ta_data->length == 0) return js_mkstr(js, "", 0); @@ -2119,9 +2043,7 @@ static ant_value_t js_typedarray_join(ant_t *js, ant_value_t *args, int nargs) { static ant_value_t js_typedarray_indexOf(ant_t *js, ant_value_t *args, int nargs) { ant_value_t this_val = js_getthis(js); - ant_value_t ta_data_val = js_get_slot(this_val, SLOT_BUFFER); - - TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_data_val); + TypedArrayData *ta_data = buffer_get_typedarray_data(this_val); if (!ta_data || !ta_data->buffer || ta_data->buffer->is_detached) return js_mknum(-1); size_t len = ta_data->length; @@ -2170,9 +2092,7 @@ static ant_value_t js_buffer_slice(ant_t *js, ant_value_t *args, int nargs) { // Buffer.prototype.toString(encoding) static ant_value_t js_buffer_toString(ant_t *js, ant_value_t *args, int nargs) { ant_value_t this_val = js_getthis(js); - ant_value_t ta_data_val = js_get_slot(this_val, SLOT_BUFFER); - - TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_data_val); + TypedArrayData *ta_data = buffer_get_typedarray_data(this_val); if (!ta_data) return js_mkerr(js, "Invalid Buffer"); BufferEncoding encoding = ENC_UTF8; @@ -2253,9 +2173,7 @@ static ant_value_t js_buffer_write(ant_t *js, ant_value_t *args, int nargs) { if (nargs < 1) return js_mkerr(js, "write requires a string"); ant_value_t this_val = js_getthis(js); - ant_value_t ta_data_val = js_get_slot(this_val, SLOT_BUFFER); - - TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_data_val); + TypedArrayData *ta_data = buffer_get_typedarray_data(this_val); if (!ta_data) return js_mkerr(js, "Invalid Buffer"); size_t str_len; @@ -2377,8 +2295,7 @@ static ant_value_t js_buffer_concat(ant_t *js, ant_value_t *args, int nargs) { snprintf(idx, sizeof(idx), "%zu", i); ant_value_t buf = js_get(js, list, idx); - ant_value_t ta_data_val = js_get_slot(buf, SLOT_BUFFER); - TypedArrayData *ta = js_gettypedarray(ta_data_val); + TypedArrayData *ta = buffer_get_typedarray_data(buf); if (!ta || !ta->buffer) continue; size_t copy_len = ta->byte_length; @@ -2397,11 +2314,8 @@ static ant_value_t js_buffer_concat(ant_t *js, ant_value_t *args, int nargs) { static ant_value_t js_buffer_compare(ant_t *js, ant_value_t *args, int nargs) { if (nargs < 2) return js_mkerr(js, "Buffer.compare requires two arguments"); - ant_value_t ta1_val = js_get_slot(args[0], SLOT_BUFFER); - ant_value_t ta2_val = js_get_slot(args[1], SLOT_BUFFER); - - TypedArrayData *ta1 = js_gettypedarray(ta1_val); - TypedArrayData *ta2 = js_gettypedarray(ta2_val); + TypedArrayData *ta1 = buffer_get_typedarray_data(args[0]); + TypedArrayData *ta2 = buffer_get_typedarray_data(args[1]); if (!ta1 || !ta2) { return js_mkerr(js, "Arguments must be Buffers"); @@ -2440,8 +2354,10 @@ static ant_value_t js_sharedarraybuffer_constructor(ant_t *js, ant_value_t *args ant_value_t proto = js_get_ctor_proto(js, "SharedArrayBuffer", 17); if (is_special_object(proto)) js_set_proto_init(obj, proto); - js_set_slot(obj, SLOT_BUFFER, ANT_PTR(data)); + js_set_native_ptr(obj, data); + js_set_native_tag(obj, BUFFER_ARRAYBUFFER_NATIVE_TAG); js_set(js, obj, "byteLength", js_mknum((double)length)); + js_set_finalizer(obj, arraybuffer_finalize); return obj; } @@ -2642,11 +2558,11 @@ void cleanup_buffer_module(void) { buffer_registry_cap = 0; } - ta_arena_offset = 0; + ta_metadata_bytes = 0; } size_t buffer_get_external_memory(void) { - size_t total = ta_arena ? ta_arena_offset : 0; + size_t total = ta_metadata_bytes; for (size_t i = 0; i < buffer_registry_count; i++) { if (buffer_registry[i]) diff --git a/src/modules/child_process.c b/src/modules/child_process.c index 7079c8a..d4d1f2c 100644 --- a/src/modules/child_process.c +++ b/src/modules/child_process.c @@ -585,8 +585,7 @@ static ant_value_t child_write_impl(ant_t *js, child_process_t *cp, ant_value_t data = js_getstr(js, data_arg, &data_len); if (!data) return js_mkerr(js, "Data must be a string or Buffer"); } else { - ant_value_t ta_data_val = js_get_slot(data_arg, SLOT_BUFFER); - TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_data_val); + TypedArrayData *ta_data = buffer_get_typedarray_data(data_arg); if (!ta_data || !ta_data->buffer || !ta_data->buffer->data) { return js_mkerr(js, "Data must be a string or Buffer"); } diff --git a/src/modules/crypto.c b/src/modules/crypto.c index 1b845ee..3426559 100644 --- a/src/modules/crypto.c +++ b/src/modules/crypto.c @@ -45,18 +45,17 @@ static ant_value_t crypto_make_buffer(ant_t *js, const uint8_t *data, size_t len } static bool crypto_get_mutable_bytes(ant_value_t value, uint8_t **out, size_t *len) { - ant_value_t slot = js_get_slot(value, SLOT_BUFFER); - if (vtype(slot) == T_TYPEDARRAY) { - TypedArrayData *ta = (TypedArrayData *)js_gettypedarray(slot); - if (!ta || !ta->buffer || ta->buffer->is_detached) return false; + TypedArrayData *ta = buffer_get_typedarray_data(value); + if (ta) { + if (!ta->buffer || ta->buffer->is_detached) return false; *out = ta->buffer->data + ta->byte_offset; *len = ta->byte_length; return true; } - if (vtype(slot) == T_NUM) { - ArrayBufferData *ab = (ArrayBufferData *)(uintptr_t)(size_t)js_getnum(slot); - if (!ab || ab->is_detached) return false; + ArrayBufferData *ab = buffer_get_arraybuffer_data(value); + if (ab) { + if (ab->is_detached) return false; *out = ab->data; *len = ab->length; return true; @@ -354,8 +353,7 @@ static ant_value_t js_crypto_get_random_values(ant_t *js, ant_value_t *args, int return js_mkerr(js, "libsodium initialization failed"); } - ant_value_t ta_data_val = js_get_slot(args[0], SLOT_BUFFER); - TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_data_val); + TypedArrayData *ta_data = buffer_get_typedarray_data(args[0]); if (!ta_data || !ta_data->buffer) { return js_mkerr(js, "argument must be a TypedArray"); } diff --git a/src/modules/fetch.c b/src/modules/fetch.c index 1f6577f..555ad08 100644 --- a/src/modules/fetch.c +++ b/src/modules/fetch.c @@ -265,8 +265,7 @@ static ant_value_t fetch_create_chunk(ant_t *js, const uint8_t *data, size_t len } static bool fetch_get_upload_chunk(ant_value_t value, const uint8_t **out, size_t *len) { - ant_value_t slot = js_get_slot(value, SLOT_BUFFER); - TypedArrayData *ta = (TypedArrayData *)js_gettypedarray(slot); + TypedArrayData *ta = buffer_get_typedarray_data(value); if (!ta || ta->type != TYPED_ARRAY_UINT8) return false; if (!ta->buffer || ta->buffer->is_detached) { diff --git a/src/modules/fs.c b/src/modules/fs.c index d88f294..6b504ba 100644 --- a/src/modules/fs.c +++ b/src/modules/fs.c @@ -2868,8 +2868,7 @@ static void on_read_fd_complete(uv_fs_t *uv_req) { ssize_t bytes_read = uv_req->result; if (req->data && bytes_read > 0) { - ant_value_t ta_val = js_get_slot(req->target_buffer, SLOT_BUFFER); - TypedArrayData *ta = (TypedArrayData *)js_gettypedarray(ta_val); + TypedArrayData *ta = buffer_get_typedarray_data(req->target_buffer); if (ta && ta->buffer && ta->buffer->data) { uint8_t *dest = ta->buffer->data + ta->byte_offset + req->buf_offset; memcpy(dest, req->data, (size_t)bytes_read); @@ -2897,8 +2896,7 @@ static ant_value_t builtin_fs_read_fd(ant_t *js, ant_value_t *args, int nargs) { int fd = (int)js_getnum(args[0]); ant_value_t buf_arg = args[1]; - ant_value_t ta_data_val = js_get_slot(buf_arg, SLOT_BUFFER); - TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_data_val); + TypedArrayData *ta_data = buffer_get_typedarray_data(buf_arg); if (!ta_data || !ta_data->buffer || !ta_data->buffer->data) return js_mkerr(js, "read() buffer argument must be a Buffer or TypedArray"); @@ -2959,8 +2957,7 @@ static ant_value_t builtin_fs_readSync(ant_t *js, ant_value_t *args, int nargs) int fd = (int)js_getnum(args[0]); - ant_value_t ta_data_val = js_get_slot(args[1], SLOT_BUFFER); - TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_data_val); + TypedArrayData *ta_data = buffer_get_typedarray_data(args[1]); if (!ta_data || !ta_data->buffer || !ta_data->buffer->data) return js_mkerr(js, "readSync() second argument must be a Buffer, TypedArray, or DataView"); @@ -3022,8 +3019,7 @@ static ant_value_t builtin_fs_writeSync(ant_t *js, ant_value_t *args, int nargs) return js_mknum((double)result); } - ant_value_t ta_data_val = js_get_slot(args[1], SLOT_BUFFER); - TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_data_val); + TypedArrayData *ta_data = buffer_get_typedarray_data(args[1]); if (!ta_data || !ta_data->buffer || !ta_data->buffer->data) return js_mkerr(js, "writeSync() second argument must be a Buffer, TypedArray, DataView, or string"); @@ -3082,8 +3078,7 @@ static ant_value_t builtin_fs_write_fd(ant_t *js, ant_value_t *args, int nargs) write_data = str; write_len = str_len; } else { - ant_value_t ta_data_val = js_get_slot(args[1], SLOT_BUFFER); - TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_data_val); + TypedArrayData *ta_data = buffer_get_typedarray_data(args[1]); if (!ta_data || !ta_data->buffer || !ta_data->buffer->data) return js_mkerr(js, "write() second argument must be a Buffer, TypedArray, DataView, or string"); @@ -3162,8 +3157,7 @@ static ant_value_t builtin_fs_writevSync(ant_t *js, ant_value_t *args, int nargs for (ant_offset_t i = 0; i < arr_len; i++) { ant_value_t item = js_arr_get(js, args[1], i); - ant_value_t ta_val = js_get_slot(item, SLOT_BUFFER); - TypedArrayData *ta = (TypedArrayData *)js_gettypedarray(ta_val); + TypedArrayData *ta = buffer_get_typedarray_data(item); if (!ta || !ta->buffer || !ta->buffer->data) { free(bufs); return js_mkerr(js, "writevSync() buffers must contain ArrayBufferViews"); @@ -3200,8 +3194,7 @@ static ant_value_t builtin_fs_writev_fd(ant_t *js, ant_value_t *args, int nargs) size_t total_len = 0; for (ant_offset_t i = 0; i < arr_len; i++) { ant_value_t item = js_arr_get(js, args[1], i); - ant_value_t ta_val = js_get_slot(item, SLOT_BUFFER); - TypedArrayData *ta = (TypedArrayData *)js_gettypedarray(ta_val); + TypedArrayData *ta = buffer_get_typedarray_data(item); if (!ta || !ta->buffer || !ta->buffer->data) return js_mkerr(js, "writev() buffers must contain ArrayBufferViews"); total_len += ta->byte_length; @@ -3219,8 +3212,7 @@ static ant_value_t builtin_fs_writev_fd(ant_t *js, ant_value_t *args, int nargs) size_t off = 0; for (ant_offset_t i = 0; i < arr_len; i++) { ant_value_t item = js_arr_get(js, args[1], i); - ant_value_t ta_val = js_get_slot(item, SLOT_BUFFER); - TypedArrayData *ta = (TypedArrayData *)js_gettypedarray(ta_val); + TypedArrayData *ta = buffer_get_typedarray_data(item); memcpy(req->data + off, ta->buffer->data + ta->byte_offset, ta->byte_length); off += ta->byte_length; } diff --git a/src/modules/io.c b/src/modules/io.c index c9e17ee..5934f50 100644 --- a/src/modules/io.c +++ b/src/modules/io.c @@ -587,7 +587,7 @@ static const char *get_slot_name(internal_slot_t slot) { [SLOT_PROTO] = "PROTO", [SLOT_FUNC_PROTO] = "FUNC_PROTO", [SLOT_ASYNC_PROTO] = "ASYNC_PROTO", - [SLOT_BUFFER] = "BUFFER", + [SLOT_AUX] = "AUX", [SLOT_TARGET_FUNC] = "TARGET_FUNC", [SLOT_NAME] = "NAME", [SLOT_MODULE_CTX] = "MODULE_CTX", diff --git a/src/modules/lmdb.c b/src/modules/lmdb.c index a5cf3e0..693116c 100644 --- a/src/modules/lmdb.c +++ b/src/modules/lmdb.c @@ -298,19 +298,17 @@ static bool js_to_mdb_val(ant_t *js, ant_value_t input, MDB_val *out) { } if (vtype(input) == T_OBJ) { - ant_value_t slot = js_get_slot(input, SLOT_BUFFER); - - if (vtype(slot) == T_TYPEDARRAY) { - TypedArrayData *ta = (TypedArrayData *)js_gettypedarray(slot); - if (!ta || !ta->buffer || !ta->buffer->data) return false; + TypedArrayData *ta = buffer_get_typedarray_data(input); + if (ta) { + if (!ta->buffer || !ta->buffer->data) return false; out->mv_data = (void *)(ta->buffer->data + ta->byte_offset); out->mv_size = ta->byte_length; return true; } - - if (vtype(slot) == T_NUM) { - ArrayBufferData *ab = (ArrayBufferData *)(uintptr_t)js_getnum(slot); - if (!ab || !ab->data) return false; + + ArrayBufferData *ab = buffer_get_arraybuffer_data(input); + if (ab) { + if (!ab->data) return false; out->mv_data = (void *)ab->data; out->mv_size = ab->length; return true; diff --git a/src/modules/napi.c b/src/modules/napi.c index 9ced3bf..904840c 100644 --- a/src/modules/napi.c +++ b/src/modules/napi.c @@ -345,9 +345,7 @@ static bool napi_get_typedarray_data( napi_value value, TypedArrayData **out ) { - ant_value_t slot = js_get_slot((ant_value_t)value, SLOT_BUFFER); - if (vtype(slot) != T_TYPEDARRAY) return false; - TypedArrayData *ta = (TypedArrayData *)js_gettypedarray(slot); + TypedArrayData *ta = buffer_get_typedarray_data((ant_value_t)value); if (!ta || !ta->buffer || ta->buffer->is_detached) return false; *out = ta; return true; @@ -1081,10 +1079,7 @@ NAPI_EXTERN napi_status NAPI_CDECL napi_create_typedarray( return napi_set_last(env, napi_invalid_arg, "invalid argument"); } - ant_value_t slot = js_get_slot((ant_value_t)arraybuffer, SLOT_BUFFER); - if (vtype(slot) != T_NUM) return napi_set_last(env, napi_arraybuffer_expected, "arraybuffer expected"); - - ArrayBufferData *ab = (ArrayBufferData *)(uintptr_t)js_getnum(slot); + ArrayBufferData *ab = buffer_get_arraybuffer_data((ant_value_t)arraybuffer); if (!ab || ab->is_detached) return napi_set_last(env, napi_arraybuffer_expected, "invalid arraybuffer"); TypedArrayType ta_type; @@ -1416,10 +1411,7 @@ NAPI_EXTERN napi_status NAPI_CDECL napi_get_arraybuffer_info( if (!nenv || !nenv->js) return napi_set_last(env, napi_invalid_arg, "invalid env"); if (!is_object_type((ant_value_t)arraybuffer)) return napi_set_last(env, napi_arraybuffer_expected, "arraybuffer expected"); - ant_value_t slot = js_get_slot((ant_value_t)arraybuffer, SLOT_BUFFER); - if (vtype(slot) != T_NUM) return napi_set_last(env, napi_arraybuffer_expected, "arraybuffer expected"); - - ArrayBufferData *ab = (ArrayBufferData *)(uintptr_t)js_getnum(slot); + ArrayBufferData *ab = buffer_get_arraybuffer_data((ant_value_t)arraybuffer); if (!ab || ab->is_detached) return napi_set_last(env, napi_arraybuffer_expected, "arraybuffer expected"); if (data) *data = ab->data; @@ -1926,13 +1918,7 @@ NAPI_EXTERN napi_status NAPI_CDECL napi_is_arraybuffer( if (!nenv || !nenv->js || !result) return napi_set_last(env, napi_invalid_arg, "invalid argument"); if (!is_object_type((ant_value_t)value)) { *result = false; return napi_set_last(env, napi_ok, NULL); } - ant_value_t slot = js_get_slot((ant_value_t)value, SLOT_BUFFER); - if (vtype(slot) != T_NUM) { - *result = false; - } else { - ant_value_t buf_prop = js_get(nenv->js, (ant_value_t)value, "buffer"); - *result = vtype(buf_prop) == T_UNDEF; - } + *result = buffer_get_arraybuffer_data((ant_value_t)value) != NULL; return napi_set_last(env, napi_ok, NULL); } @@ -1978,9 +1964,7 @@ NAPI_EXTERN napi_status NAPI_CDECL napi_is_dataview( if (!is_object_type((ant_value_t)value)) { *result = false; } else { - ant_value_t slot = js_get_slot((ant_value_t)value, SLOT_DATA); - ant_value_t byte_len = js_get(nenv->js, (ant_value_t)value, "byteLength"); - *result = vtype(slot) == T_NUM && vtype(byte_len) == T_NUM; + *result = buffer_get_dataview_data((ant_value_t)value) != NULL; } return napi_set_last(env, napi_ok, NULL); } diff --git a/src/modules/net.c b/src/modules/net.c index 250bad0..81603d4 100644 --- a/src/modules/net.c +++ b/src/modules/net.c @@ -705,12 +705,9 @@ static ant_value_t js_net_socket_write(ant_t *js, ant_value_t *args, int nargs) copy = malloc(parsed.len); if (!copy) return js_mkerr_typed(js, JS_ERR_TYPE, "Out of memory"); + memcpy(copy, parsed.bytes, parsed.len); - - if (ant_conn_write(socket->conn, copy, parsed.len, NULL, NULL) != 0) { - free(copy); - return js_false; - } + if (ant_conn_write(socket->conn, copy, parsed.len, NULL, NULL) != 0) return js_false; GC_ROOT_SAVE(root_mark, js); GC_ROOT_PIN(js, parsed.callback); diff --git a/src/modules/response.c b/src/modules/response.c index bfd6e23..c282785 100644 --- a/src/modules/response.c +++ b/src/modules/response.c @@ -395,8 +395,7 @@ static void resolve_body_promise( static bool response_chunk_is_uint8_array(ant_value_t chunk, TypedArrayData **out_ta) { if (!is_object_type(chunk)) return false; - ant_value_t slot = js_get_slot(chunk, SLOT_BUFFER); - TypedArrayData *ta = (TypedArrayData *)js_gettypedarray(slot); + TypedArrayData *ta = buffer_get_typedarray_data(chunk); if (!ta || !ta->buffer || ta->buffer->is_detached) return false; if (ta->type != TYPED_ARRAY_UINT8) return false; *out_ta = ta; diff --git a/src/modules/server.c b/src/modules/server.c index 295fb78..2ab30e8 100644 --- a/src/modules/server.c +++ b/src/modules/server.c @@ -343,8 +343,7 @@ static void server_abort_request(server_request_t *req, const char *message) { } static bool server_response_chunk(server_request_t *req, ant_value_t value, const uint8_t **out, size_t *len) { - ant_value_t slot = js_get_slot(value, SLOT_BUFFER); - TypedArrayData *ta = (TypedArrayData *)js_gettypedarray(slot); + TypedArrayData *ta = buffer_get_typedarray_data(value); if (!ta || ta->type != TYPED_ARRAY_UINT8) return false; if (!ta->buffer || ta->buffer->is_detached) { diff --git a/src/modules/structured-clone.c b/src/modules/structured-clone.c index b1bd9e1..f6ef583 100644 --- a/src/modules/structured-clone.c +++ b/src/modules/structured-clone.c @@ -77,15 +77,13 @@ static ant_value_t sc_clone_typed_array( static ant_value_t sc_clone_rec(ant_t *js, ant_value_t val, sc_entry_t **seen, sc_entry_t **transfer) { uint8_t t = vtype(val); - ant_value_t slot = js_mkundef(); TypedArrayData *ta_data = NULL; if (t == T_UNDEF || t == T_NULL || t == T_BOOL || t == T_NUM || t == T_BIGINT || t == T_STR) return val; if (t == T_SYMBOL) return js_throw(js, make_dom_exception(js, "Symbol cannot be serialized", "DataCloneError")); if (is_object_type(val)) { - slot = js_get_slot(val, SLOT_BUFFER); - ta_data = (TypedArrayData *)js_gettypedarray(slot); + ta_data = buffer_get_typedarray_data(val); } if (ta_data) { @@ -106,9 +104,8 @@ static ant_value_t sc_clone_rec(ant_t *js, ant_value_t val, sc_entry_t **seen, s ant_value_t existing = sc_lookup(seen, val); if (vtype(existing) != T_UNDEF) return existing; - ant_value_t buf_slot_v = js_get_slot(val, SLOT_BUFFER); - if (vtype(buf_slot_v) == T_NUM) { - ArrayBufferData *abd = (ArrayBufferData *)(uintptr_t)(size_t)js_getnum(buf_slot_v); + ArrayBufferData *abd = buffer_get_arraybuffer_data(val); + if (abd) { if (abd && !abd->is_detached) { if (transfer && sc_has(transfer, val)) { ArrayBufferData *new_abd = calloc(1, sizeof(ArrayBufferData)); @@ -135,11 +132,7 @@ static ant_value_t sc_clone_rec(ant_t *js, ant_value_t val, sc_entry_t **seen, s }} if (buffer_is_dataview(val)) { - ant_value_t dv_data_val = js_get_slot(val, SLOT_DATA); - if (vtype(dv_data_val) != T_NUM) - return js_throw(js, make_dom_exception(js, "DataView could not be cloned", "DataCloneError")); - - DataViewData *dv = (DataViewData *)(uintptr_t)js_getnum(dv_data_val); + DataViewData *dv = buffer_get_dataview_data(val); if (!dv || !dv->buffer) return js_throw(js, make_dom_exception(js, "DataView could not be cloned", "DataCloneError")); diff --git a/src/modules/textcodec.c b/src/modules/textcodec.c index ad79333..b231cf3 100644 --- a/src/modules/textcodec.c +++ b/src/modules/textcodec.c @@ -132,7 +132,7 @@ static ant_value_t js_textencoder_encode_into(ant_t *js, ant_value_t *args, int if (!str) { str = ""; str_len = 0; } } - TypedArrayData *ta = (TypedArrayData *)js_gettypedarray(js_get_slot(args[1], SLOT_BUFFER)); + TypedArrayData *ta = buffer_get_typedarray_data(args[1]); if (!ta) return js_mkerr_typed(js, JS_ERR_TYPE, "Second argument must be a Uint8Array"); uint8_t *dest = (ta->buffer && !ta->buffer->is_detached) diff --git a/src/modules/util.c b/src/modules/util.c index f06c71a..8e27184 100644 --- a/src/modules/util.c +++ b/src/modules/util.c @@ -228,32 +228,6 @@ static bool util_has_proto_in_chain(ant_t *js, ant_value_t value, ant_value_t pr return false; } -static bool util_is_typed_array_value(ant_value_t value, TypedArrayData **out) { - ant_value_t slot; - - if (vtype(value) == T_TYPEDARRAY) { - if (out) *out = (TypedArrayData *)js_gettypedarray(value); - return true; - } - - if (!is_object_type(value)) return false; - slot = js_get_slot(value, SLOT_BUFFER); - if (vtype(slot) != T_TYPEDARRAY) return false; - - if (out) *out = (TypedArrayData *)js_gettypedarray(slot); - return true; -} - -static ArrayBufferData *util_get_arraybuffer_data(ant_value_t value) { - ant_value_t slot; - - if (!is_object_type(value) || buffer_is_dataview(value)) return NULL; - slot = js_get_slot(value, SLOT_BUFFER); - if (vtype(slot) != T_NUM) return NULL; - - return (ArrayBufferData *)(uintptr_t)(size_t)js_getnum(slot); -} - static bool util_is_boxed_primitive(ant_value_t value, uint8_t *type_out) { ant_value_t primitive; @@ -290,23 +264,23 @@ static bool util_is_arguments_object_value(ant_t *js, ant_value_t value) { } static ant_value_t util_types_is_any_array_buffer(ant_t *js, ant_value_t *args, int nargs) { - ArrayBufferData *buffer = (nargs > 0) ? util_get_arraybuffer_data(args[0]) : NULL; + ArrayBufferData *buffer = (nargs > 0) ? buffer_get_arraybuffer_data(args[0]) : NULL; return js_bool(buffer != NULL); } static ant_value_t util_types_is_array_buffer(ant_t *js, ant_value_t *args, int nargs) { - ArrayBufferData *buffer = (nargs > 0) ? util_get_arraybuffer_data(args[0]) : NULL; + ArrayBufferData *buffer = (nargs > 0) ? buffer_get_arraybuffer_data(args[0]) : NULL; return js_bool(buffer != NULL && !buffer->is_shared); } static ant_value_t util_types_is_shared_array_buffer(ant_t *js, ant_value_t *args, int nargs) { - ArrayBufferData *buffer = (nargs > 0) ? util_get_arraybuffer_data(args[0]) : NULL; + ArrayBufferData *buffer = (nargs > 0) ? buffer_get_arraybuffer_data(args[0]) : NULL; return js_bool(buffer != NULL && buffer->is_shared); } static ant_value_t util_types_is_array_buffer_view(ant_t *js, ant_value_t *args, int nargs) { if (nargs < 1) return js_false; - return js_bool(buffer_is_dataview(args[0]) || util_is_typed_array_value(args[0], NULL)); + return js_bool(buffer_is_dataview(args[0]) || buffer_get_typedarray_data(args[0]) != NULL); } static ant_value_t util_types_is_data_view(ant_t *js, ant_value_t *args, int nargs) { @@ -316,25 +290,24 @@ static ant_value_t util_types_is_data_view(ant_t *js, ant_value_t *args, int nar static ant_value_t util_types_is_typed_array(ant_t *js, ant_value_t *args, int nargs) { if (nargs < 1) return js_false; - return js_bool(util_is_typed_array_value(args[0], NULL)); + return js_bool(buffer_get_typedarray_data(args[0]) != NULL); } static ant_value_t util_types_is_float16_array(ant_t *js, ant_value_t *args, int nargs) { - TypedArrayData *typed_array = NULL; - if (nargs < 1 || !util_is_typed_array_value(args[0], &typed_array)) return js_false; + TypedArrayData *typed_array = (nargs > 0) ? buffer_get_typedarray_data(args[0]) : NULL; + if (!typed_array) return js_false; return js_bool(typed_array != NULL && typed_array->type == TYPED_ARRAY_FLOAT16); } -#define DEFINE_TYPED_ARRAY_CHECK(fn_name, typed_array_kind) \ - static ant_value_t fn_name(ant_t *js, ant_value_t *args, int nargs) { \ - TypedArrayData *typed_array = NULL; \ - if (nargs < 1 || !util_is_typed_array_value(args[0], &typed_array)) return js_false; \ - return js_bool(typed_array != NULL && typed_array->type == typed_array_kind); \ +#define DEFINE_TYPED_ARRAY_CHECK(fn_name, typed_array_kind) \ + static ant_value_t fn_name(ant_t *js, ant_value_t *args, int nargs) { \ + TypedArrayData *typed_array = (nargs > 0) ? buffer_get_typedarray_data(args[0]) : NULL; \ + if (!typed_array) return js_false; \ + return js_bool(typed_array != NULL && typed_array->type == typed_array_kind); \ } DEFINE_TYPED_ARRAY_CHECK(util_types_is_int8_array, TYPED_ARRAY_INT8) DEFINE_TYPED_ARRAY_CHECK(util_types_is_uint8_array, TYPED_ARRAY_UINT8) -DEFINE_TYPED_ARRAY_CHECK(util_types_is_uint8_clamped_array, TYPED_ARRAY_UINT8_CLAMPED) DEFINE_TYPED_ARRAY_CHECK(util_types_is_int16_array, TYPED_ARRAY_INT16) DEFINE_TYPED_ARRAY_CHECK(util_types_is_uint16_array, TYPED_ARRAY_UINT16) DEFINE_TYPED_ARRAY_CHECK(util_types_is_int32_array, TYPED_ARRAY_INT32) @@ -343,6 +316,7 @@ DEFINE_TYPED_ARRAY_CHECK(util_types_is_float32_array, TYPED_ARRAY_FLOAT32) DEFINE_TYPED_ARRAY_CHECK(util_types_is_float64_array, TYPED_ARRAY_FLOAT64) DEFINE_TYPED_ARRAY_CHECK(util_types_is_bigint64_array, TYPED_ARRAY_BIGINT64) DEFINE_TYPED_ARRAY_CHECK(util_types_is_biguint64_array, TYPED_ARRAY_BIGUINT64) +DEFINE_TYPED_ARRAY_CHECK(util_types_is_uint8_clamped_array, TYPED_ARRAY_UINT8_CLAMPED) static ant_value_t util_types_is_promise(ant_t *js, ant_value_t *args, int nargs) { if (nargs < 1) return js_false; diff --git a/src/modules/v8.c b/src/modules/v8.c index f491dc8..0841533 100644 --- a/src/modules/v8.c +++ b/src/modules/v8.c @@ -233,8 +233,7 @@ static ant_value_t des_val(ant_t *js, dec_t *d, int depth) { static ant_value_t v8_deserialize(ant_t *js, ant_value_t *args, int nargs) { if (nargs < 1) return js_mkerr(js, "deserialize: Buffer required"); - ant_value_t buf_slot = js_get_slot(args[0], SLOT_BUFFER); - TypedArrayData *ta = (TypedArrayData *)js_gettypedarray(buf_slot); + TypedArrayData *ta = buffer_get_typedarray_data(args[0]); if (!ta || !ta->buffer) return js_mkerr(js, "deserialize: expected a Buffer"); const uint8_t *data = ta->buffer->data + ta->byte_offset; diff --git a/src/streams/pipes.c b/src/streams/pipes.c index 5be45a0..17cc47b 100644 --- a/src/streams/pipes.c +++ b/src/streams/pipes.c @@ -60,7 +60,7 @@ static ant_value_t pipe_state_dest(ant_value_t state) { } static ant_value_t pipe_state_reader(ant_value_t state) { - return js_get_slot(state, SLOT_BUFFER); + return js_get_slot(state, SLOT_AUX); } static ant_value_t pipe_state_writer(ant_value_t state) { @@ -121,7 +121,7 @@ static void pipes_release_locks(ant_t *js, ant_value_t state) { ant_value_t reader = pipe_state_reader(state); if (rs_is_reader(reader)) { pipes_release_reader(js, reader); - js_set_slot(state, SLOT_BUFFER, js_mkundef()); + js_set_slot(state, SLOT_AUX, js_mkundef()); } ant_value_t writer = pipe_state_writer(state); @@ -387,7 +387,7 @@ ant_value_t readable_stream_pipe_to( js_set_slot(state, SLOT_DATA, ANT_PTR(pst)); js_set_slot(state, SLOT_ENTRIES, source); js_set_slot(state, SLOT_CTOR, dest); - js_set_slot(state, SLOT_BUFFER, reader); + js_set_slot(state, SLOT_AUX, reader); js_set_slot(state, SLOT_DEFAULT, writer); js_set_slot(state, SLOT_RS_PULL, promise); js_set_finalizer(state, pipe_state_finalize); @@ -493,14 +493,14 @@ static tee_state_t *tee_get_state(ant_value_t state) { } static ant_value_t tee_state_reader(ant_value_t state) { - return js_get_slot(state, SLOT_BUFFER); + return js_get_slot(state, SLOT_AUX); } static void tee_release_reader(ant_t *js, ant_value_t state) { ant_value_t reader = tee_state_reader(state); if (!rs_is_reader(reader)) return; pipes_release_reader(js, reader); - js_set_slot(state, SLOT_BUFFER, js_mkundef()); + js_set_slot(state, SLOT_AUX, js_mkundef()); } static void tee_resolve_cancel_promises(ant_t *js, ant_value_t state) { @@ -750,7 +750,7 @@ static ant_value_t js_rs_tee(ant_t *js, ant_value_t *args, int nargs) { ant_value_t state = js_mkobj(js); js_set_slot(state, SLOT_DATA, ANT_PTR(st)); js_set_slot(state, SLOT_ENTRIES, js->this_val); - js_set_slot(state, SLOT_BUFFER, reader); + js_set_slot(state, SLOT_AUX, reader); js_set_slot(state, SLOT_RS_PULL, js_mkundef()); js_set_slot(state, SLOT_RS_CANCEL, js_mkundef()); js_set_slot(state, SLOT_RS_CLOSED, js_mkundef()); diff --git a/src/streams/readable.c b/src/streams/readable.c index 8313023..b8099fc 100644 --- a/src/streams/readable.c +++ b/src/streams/readable.c @@ -26,7 +26,7 @@ bool rs_is_stream(ant_value_t obj) { bool rs_is_reader(ant_value_t obj) { return js_check_brand(obj, BRAND_READABLE_STREAM_READER) && vtype(js_get_slot(obj, SLOT_RS_CLOSED)) == T_PROMISE - && vtype(js_get_slot(obj, SLOT_BUFFER)) == T_ARR; + && vtype(js_get_slot(obj, SLOT_AUX)) == T_ARR; } bool rs_is_controller(ant_value_t obj) { @@ -91,7 +91,7 @@ ant_value_t rs_stream_reader(ant_value_t stream_obj) { } ant_value_t rs_stream_error(ant_value_t stream_obj) { - return js_get_slot(stream_obj, SLOT_BUFFER); + return js_get_slot(stream_obj, SLOT_AUX); } static inline ant_value_t rs_ctrl_stream(ant_value_t ctrl_obj) { @@ -111,7 +111,7 @@ ant_value_t rs_ctrl_size(ant_value_t ctrl_obj) { } static inline ant_value_t rs_ctrl_queue(ant_t *js, ant_value_t ctrl_obj) { - return js_get_slot(ctrl_obj, SLOT_BUFFER); + return js_get_slot(ctrl_obj, SLOT_AUX); } ant_value_t rs_reader_stream(ant_value_t reader_obj) { @@ -123,7 +123,7 @@ ant_value_t rs_reader_closed(ant_value_t reader_obj) { } ant_value_t rs_reader_reqs(ant_value_t reader_obj) { - return js_get_slot(reader_obj, SLOT_BUFFER); + return js_get_slot(reader_obj, SLOT_AUX); } bool rs_reader_has_reqs(ant_t *js, ant_value_t reader_obj) { @@ -252,7 +252,7 @@ void readable_stream_error(ant_t *js, ant_value_t stream_obj, ant_value_t e) { rs_stream_t *stream = rs_get_stream(stream_obj); if (!stream || stream->state != RS_STATE_READABLE) return; stream->state = RS_STATE_ERRORED; - js_set_slot(stream_obj, SLOT_BUFFER, e); + js_set_slot(stream_obj, SLOT_AUX, e); ant_value_t reader_obj = rs_stream_reader(stream_obj); if (rs_is_reader(reader_obj)) { @@ -673,7 +673,7 @@ ant_value_t js_rs_reader_ctor(ant_t *js, ant_value_t *args, int nargs) { js_set_slot(obj, SLOT_BRAND, js_mknum(BRAND_READABLE_STREAM_READER)); js_set_slot(obj, SLOT_ENTRIES, stream_obj); js_set_slot(obj, SLOT_RS_CLOSED, closed); - js_set_slot(obj, SLOT_BUFFER, js_mkarr(js)); + js_set_slot(obj, SLOT_AUX, js_mkarr(js)); js_set_slot(stream_obj, SLOT_CTOR, obj); if (stream->state == RS_STATE_CLOSED) @@ -817,7 +817,7 @@ static ant_value_t setup_default_controller( js_set_slot(ctrl_obj, SLOT_RS_PULL, pull_fn); js_set_slot(ctrl_obj, SLOT_RS_CANCEL, cancel_fn); js_set_slot(ctrl_obj, SLOT_RS_SIZE, size_fn); - js_set_slot(ctrl_obj, SLOT_BUFFER, js_mkarr(js)); + js_set_slot(ctrl_obj, SLOT_AUX, js_mkarr(js)); js_set_finalizer(ctrl_obj, rs_controller_finalize); js_set_slot(stream_obj, SLOT_ENTRIES, ctrl_obj); diff --git a/src/streams/transform.c b/src/streams/transform.c index 7d41219..0950f00 100644 --- a/src/streams/transform.c +++ b/src/streams/transform.c @@ -113,7 +113,7 @@ static inline ant_value_t ts_writable(ant_value_t ts_obj) { } static inline ant_value_t ts_bp_promise(ant_value_t ts_obj) { - return js_get_slot(ts_obj, SLOT_BUFFER); + return js_get_slot(ts_obj, SLOT_AUX); } ant_value_t ts_stream_controller(ant_value_t ts_obj) { @@ -133,7 +133,7 @@ static inline ant_value_t ts_ctrl_flush_fn(ant_value_t ctrl_obj) { } static inline ant_value_t ts_ctrl_cancel_fn(ant_value_t ctrl_obj) { - return js_get_slot(ctrl_obj, SLOT_BUFFER); + return js_get_slot(ctrl_obj, SLOT_AUX); } static inline ant_value_t ts_ctrl_transformer(ant_value_t ctrl_obj) { @@ -149,7 +149,7 @@ static inline ant_value_t ts_ctrl_finish_promise(ant_value_t ctrl_obj) { } static inline ant_value_t ts_writable_stored_error(ant_value_t ts_obj) { - return js_get_slot(ts_writable(ts_obj), SLOT_BUFFER); + return js_get_slot(ts_writable(ts_obj), SLOT_AUX); } static inline ant_value_t ts_cancel_promise(ant_value_t ts_obj) { @@ -198,7 +198,7 @@ if (ts_cancel_promise(ts_obj) == promise) { static void ts_ctrl_clear_algorithms(ant_value_t ctrl_obj) { js_set_slot(ctrl_obj, SLOT_ENTRIES, js_mkundef()); js_set_slot(ctrl_obj, SLOT_CTOR, js_mkundef()); - js_set_slot(ctrl_obj, SLOT_BUFFER, js_mkundef()); + js_set_slot(ctrl_obj, SLOT_AUX, js_mkundef()); } static ant_value_t ts_take_thrown_or(ant_t *js, ant_value_t fallback) { @@ -261,7 +261,7 @@ static void ts_set_backpressure(ant_t *js, ant_value_t ts_obj, bool backpressure if (vtype(bp) == T_PROMISE) js_resolve_promise(js, bp, js_mkundef()); } ant_value_t new_bp = js_mkpromise(js); - js_set_slot(ts_obj, SLOT_BUFFER, new_bp); + js_set_slot(ts_obj, SLOT_AUX, new_bp); ts_set_bp_flag(ts_obj, backpressure); } @@ -420,7 +420,7 @@ static ant_value_t ts_source_cancel_resolve(ant_t *js, ant_value_t *args, int na ant_value_t wrapper = js_get_slot(js->current_func, SLOT_DATA); ant_value_t p = js_get_slot(wrapper, SLOT_DATA); ant_value_t ts_obj = js_get_slot(wrapper, SLOT_ENTRIES); - ant_value_t reason = js_get_slot(wrapper, SLOT_BUFFER); + ant_value_t reason = js_get_slot(wrapper, SLOT_AUX); ant_value_t readable = ts_readable(ts_obj); rs_stream_t *rs = rs_get_stream(readable); @@ -457,7 +457,7 @@ static ant_value_t ts_abort_cancel_resolve(ant_t *js, ant_value_t *args, int nar ant_value_t wrapper = js_get_slot(js->current_func, SLOT_DATA); ant_value_t p = js_get_slot(wrapper, SLOT_DATA); ant_value_t ts_obj = js_get_slot(wrapper, SLOT_ENTRIES); - ant_value_t reason = js_get_slot(wrapper, SLOT_BUFFER); + ant_value_t reason = js_get_slot(wrapper, SLOT_AUX); ant_value_t readable = ts_readable(ts_obj); rs_stream_t *rs = rs_get_stream(readable); @@ -591,7 +591,7 @@ static ant_value_t ts_sink_abort(ant_t *js, ant_value_t *args, int nargs) { ant_value_t wrapper = js_mkobj(js); js_set_slot(wrapper, SLOT_DATA, p); js_set_slot(wrapper, SLOT_ENTRIES, ts_obj); - js_set_slot(wrapper, SLOT_BUFFER, reason); + js_set_slot(wrapper, SLOT_AUX, reason); js_set_slot(wrapper, SLOT_CTOR, ts_cancel_started_by_abort(ts_obj) ? js_true : js_false); ant_value_t res_fn = js_heavy_mkfun(js, ts_abort_cancel_resolve, wrapper); @@ -732,7 +732,7 @@ static ant_value_t ts_source_cancel(ant_t *js, ant_value_t *args, int nargs) { ant_value_t wrapper = js_mkobj(js); js_set_slot(wrapper, SLOT_DATA, p); js_set_slot(wrapper, SLOT_ENTRIES, ts_obj); - js_set_slot(wrapper, SLOT_BUFFER, reason); + js_set_slot(wrapper, SLOT_AUX, reason); js_set_slot(wrapper, SLOT_CTOR, ts_cancel_started_by_abort(ts_obj) ? js_true : js_false); ant_value_t res_fn = js_heavy_mkfun(js, ts_source_cancel_resolve, wrapper); ant_value_t rej_fn = js_heavy_mkfun(js, ts_source_cancel_reject, wrapper); @@ -935,7 +935,7 @@ ant_value_t js_ts_ctor(ant_t *js, ant_value_t *args, int nargs) { js_set_slot(ctrl_obj, SLOT_DATA, ts_obj); js_set_slot(ctrl_obj, SLOT_ENTRIES, transform_fn); js_set_slot(ctrl_obj, SLOT_CTOR, flush_fn); - js_set_slot(ctrl_obj, SLOT_BUFFER, cancel_fn); + js_set_slot(ctrl_obj, SLOT_AUX, cancel_fn); js_set_slot(ctrl_obj, SLOT_SETTLED, transformer); js_set_slot(ctrl_obj, SLOT_RS_PULL, js_mkundef()); js_set_slot(ts_obj, SLOT_DEFAULT, ctrl_obj); @@ -975,7 +975,7 @@ ant_value_t js_ts_ctor(ant_t *js, ant_value_t *args, int nargs) { js_set_slot(rs_ctrl_obj, SLOT_RS_PULL, source_pull); js_set_slot(rs_ctrl_obj, SLOT_RS_CANCEL, source_cancel); js_set_slot(rs_ctrl_obj, SLOT_RS_SIZE, readable_size_fn); - js_set_slot(rs_ctrl_obj, SLOT_BUFFER, js_mkarr(js)); + js_set_slot(rs_ctrl_obj, SLOT_AUX, js_mkarr(js)); js_set_finalizer(rs_ctrl_obj, ts_rs_ctrl_finalize); js_set_slot(rs_obj, SLOT_ENTRIES, rs_ctrl_obj); @@ -995,7 +995,7 @@ ant_value_t js_ts_ctor(ant_t *js, ant_value_t *args, int nargs) { js_set_slot(ts_obj, SLOT_CTOR, ws_obj); ant_value_t bp_promise = js_mkpromise(js); - js_set_slot(ts_obj, SLOT_BUFFER, bp_promise); + js_set_slot(ts_obj, SLOT_AUX, bp_promise); ts_set_backpressure(js, ts_obj, true); @@ -1013,7 +1013,7 @@ ant_value_t js_ts_ctor(ant_t *js, ant_value_t *args, int nargs) { js_set_slot(ws_ctrl_obj, SLOT_WS_ABORT, sink_abort); js_set_slot(ws_ctrl_obj, SLOT_RS_SIZE, writable_size_fn); js_set_slot(ws_ctrl_obj, SLOT_CTOR, js_mkundef()); - js_set_slot(ws_ctrl_obj, SLOT_BUFFER, js_mkarr(js)); + js_set_slot(ws_ctrl_obj, SLOT_AUX, js_mkarr(js)); js_set_finalizer(ws_ctrl_obj, ts_ws_ctrl_finalize); js_set_slot(ws_obj, SLOT_ENTRIES, ws_ctrl_obj); diff --git a/src/streams/writable.c b/src/streams/writable.c index 8eec972..7ead6bc 100644 --- a/src/streams/writable.c +++ b/src/streams/writable.c @@ -78,7 +78,7 @@ ant_value_t ws_stream_writer(ant_value_t stream_obj) { } static inline ant_value_t ws_stream_stored_error(ant_value_t stream_obj) { - return js_get_slot(stream_obj, SLOT_BUFFER); + return js_get_slot(stream_obj, SLOT_AUX); } static inline ant_value_t ws_stream_write_requests(ant_t *js, ant_value_t stream_obj) { @@ -126,7 +126,7 @@ static inline ant_value_t ws_ctrl_sink(ant_value_t ctrl_obj) { } static inline ant_value_t ws_ctrl_queue(ant_value_t ctrl_obj) { - return js_get_slot(ctrl_obj, SLOT_BUFFER); + return js_get_slot(ctrl_obj, SLOT_AUX); } static inline ant_value_t ws_ctrl_signal(ant_value_t ctrl_obj) { @@ -266,7 +266,7 @@ static void writable_stream_start_erroring(ant_t *js, ant_value_t stream_obj, an ws_controller_t *ctrl = ws_get_controller(ctrl_obj); stream->state = WS_STATE_ERRORING; - js_set_slot(stream_obj, SLOT_BUFFER, reason); + js_set_slot(stream_obj, SLOT_AUX, reason); ant_value_t signal_ac = ws_ctrl_signal(ctrl_obj); if (is_object_type(signal_ac)) { @@ -427,7 +427,7 @@ static void writable_stream_finish_in_flight_close(ant_t *js, ant_value_t stream if (!stream) return; if (stream->state == WS_STATE_ERRORING) { - js_set_slot(stream_obj, SLOT_BUFFER, js_mkundef()); + js_set_slot(stream_obj, SLOT_AUX, js_mkundef()); if (stream->has_pending_abort) { ant_value_t ap = ws_stream_pending_abort_promise(stream_obj); js_resolve_promise(js, ap, js_mkundef()); @@ -1079,7 +1079,7 @@ static ant_value_t setup_ws_default_controller( js_set_slot(ctrl_obj, SLOT_WS_ABORT, abort_fn); js_set_slot(ctrl_obj, SLOT_RS_SIZE, size_fn); js_set_slot(ctrl_obj, SLOT_CTOR, underlying_sink); - js_set_slot(ctrl_obj, SLOT_BUFFER, js_mkarr(js)); + js_set_slot(ctrl_obj, SLOT_AUX, js_mkarr(js)); js_set_finalizer(ctrl_obj, ws_controller_finalize); ant_value_t ac_ctor = js_get(js, js_glob(js), "AbortController"); diff --git a/tests/repro_typedarray_metadata_leak.cjs b/tests/repro_typedarray_metadata_leak.cjs new file mode 100644 index 0000000..39e7da6 --- /dev/null +++ b/tests/repro_typedarray_metadata_leak.cjs @@ -0,0 +1,17 @@ +'use strict'; + +const total = 600000; +const step = 100000; +let checksum = 0; + +for (let i = 0; i < total; i++) { + const buf = Buffer.alloc(32); + buf[0] = i & 255; + checksum ^= buf[0]; + + if ((i + 1) % step === 0) { + console.log(`allocated ${i + 1}`); + } +} + +console.log(`OK: allocated ${total} buffers checksum=${checksum}`); -- 2.51.2