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.

add typed array arena for efficient memory allocation

+73 -70
+3
include/ant.h
··· 108 108 jsval_t js_obj_to_func(jsval_t obj); 109 109 jsval_t js_mkpromise(struct js *js); 110 110 111 + jsval_t js_mktypedarray(void *data); 112 + void *js_gettypedarray(jsval_t val); 113 + 111 114 void js_resolve_promise(struct js *js, jsval_t promise, jsval_t value); 112 115 void js_reject_promise(struct js *js, jsval_t promise, jsval_t value); 113 116
+1 -1
meson.build
··· 74 74 build_date = run_command('date', '+%Y-%m-%d', check: true).stdout().strip() 75 75 76 76 version_conf = configuration_data() 77 - version_conf.set('ANT_VERSION', '0.2.1.14') 77 + version_conf.set('ANT_VERSION', '0.2.1.15') 78 78 version_conf.set('ANT_GIT_HASH', git_hash) 79 79 version_conf.set('ANT_BUILD_DATE', build_date) 80 80
+11 -2
src/ant.c
··· 424 424 enum { 425 425 T_OBJ, T_PROP, T_STR, T_UNDEF, T_NULL, T_NUM, 426 426 T_BOOL, T_FUNC, T_CODEREF, T_CFUNC, T_ERR, T_ARR, 427 - T_PROMISE, T_GENERATOR, T_BIGINT, T_PROPREF 427 + T_PROMISE, T_TYPEDARRAY, T_BIGINT, T_PROPREF 428 428 }; 429 429 430 430 static const char *typestr_raw(uint8_t t) { ··· 433 433 const char *names[] = { 434 434 "object", "prop", "string", "undefined", "null", "number", 435 435 "boolean", "function", "coderef", "cfunc", "err", "array", 436 - "promise", "generator", "bigint", "propref" 436 + "promise", "typedarray", "bigint", "propref" 437 437 }; 438 438 439 439 return (t < sizeof(names) / sizeof(names[0])) ? names[t] : "??"; ··· 478 478 479 479 jsval_t js_obj_to_func(jsval_t obj) { 480 480 return mkval(T_FUNC, vdata(obj)); 481 + } 482 + 483 + jsval_t js_mktypedarray(void *data) { 484 + return mkval(T_TYPEDARRAY, (uintptr_t)data); 485 + } 486 + 487 + void *js_gettypedarray(jsval_t val) { 488 + if (vtype(val) != T_TYPEDARRAY) return NULL; 489 + return (void *)vdata(val); 481 490 } 482 491 483 492 static jsval_t mkcoderef(jsval_t off, jsoff_t len) {
+1 -1
src/core/index.js
··· 21 21 T_ERR: 'err', 22 22 T_ARR: 'array', 23 23 T_PROMISE: 'promise', 24 - T_GENERATOR: 'generator', 24 + T_TYPEDARRAY: 'typedarray', 25 25 T_BIGINT: 'bigint', 26 26 T_PROPREF: 'propref' 27 27 };
+3 -9
src/modules/atomics.c
··· 81 81 } 82 82 83 83 static bool get_atomic_array_data(struct js *js, jsval_t this_val, TypedArrayData **out_data, uint8_t **out_ptr) { 84 - jsval_t ta_data_val = js_get(js, this_val, "_typedarray_data"); 85 - if (js_type(ta_data_val) != JS_NUM) { 86 - return false; 87 - } 88 - 89 - TypedArrayData *ta_data = (TypedArrayData *)(uintptr_t)js_getnum(ta_data_val); 90 - if (!ta_data || !ta_data->buffer) { 91 - return false; 92 - } 84 + jsval_t ta_data_val = js_get(js, this_val, "__ta"); 85 + TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_data_val); 86 + if (!ta_data || !ta_data->buffer) return false; 93 87 94 88 *out_data = ta_data; 95 89 *out_ptr = ta_data->buffer->data + ta_data->byte_offset;
+41 -30
src/modules/buffer.c
··· 2 2 #include <stdio.h> 3 3 #include <string.h> 4 4 #include <ctype.h> 5 + #include <sys/mman.h> 5 6 6 7 #include "runtime.h" 7 8 #include "modules/buffer.h" 8 9 #include "modules/symbol.h" 10 + 11 + #define TA_ARENA_SIZE (16 * 1024 * 1024) 12 + static uint8_t *ta_arena = NULL; 13 + static size_t ta_arena_offset = 0; 14 + 15 + static void *ta_arena_alloc(size_t size) { 16 + size = (size + 7) & ~7; 17 + 18 + if (!ta_arena) { 19 + void *hint = (void *)0x100000; 20 + ta_arena = mmap( 21 + hint, TA_ARENA_SIZE, PROT_READ | PROT_WRITE, 22 + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 23 + 24 + if (ta_arena == MAP_FAILED) { 25 + ta_arena = mmap( 26 + NULL, TA_ARENA_SIZE, PROT_READ | PROT_WRITE, 27 + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 28 + } 29 + if (ta_arena == MAP_FAILED) return NULL; 30 + } 31 + 32 + if (ta_arena_offset + size > TA_ARENA_SIZE) return NULL; 33 + void *ptr = ta_arena + ta_arena_offset; 34 + ta_arena_offset += size; 35 + 36 + return ptr; 37 + } 9 38 10 39 static jsval_t js_arraybuffer_slice(struct js *js, jsval_t *args, int nargs); 11 40 static jsval_t js_typedarray_slice(struct js *js, jsval_t *args, int nargs); ··· 201 230 long index = strtol(key, &endptr, 10); 202 231 if (endptr != key + key_len || index < 0) return js_mkundef(); 203 232 204 - jsval_t ta_data_val = js_get(js, obj, "_typedarray_data"); 205 - if (js_type(ta_data_val) != JS_NUM) return js_mkundef(); 206 - 207 - TypedArrayData *ta_data = (TypedArrayData *)(uintptr_t)js_getnum(ta_data_val); 233 + jsval_t ta_val = js_get(js, obj, "__ta"); 234 + TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_val); 208 235 if (!ta_data || (size_t)index >= ta_data->length) return js_mkundef(); 209 236 210 237 uint8_t *data = ta_data->buffer->data + ta_data->byte_offset; ··· 231 258 } 232 259 233 260 static jsval_t create_typed_array(struct js *js, TypedArrayType type, ArrayBufferData *buffer, size_t byte_offset, size_t length, const char *type_name) { 234 - TypedArrayData *ta_data = malloc(sizeof(TypedArrayData)); 261 + TypedArrayData *ta_data = ta_arena_alloc(sizeof(TypedArrayData)); 235 262 if (!ta_data) return js_mkerr(js, "Failed to allocate TypedArray"); 236 263 237 264 size_t element_size = get_element_size(type); ··· 246 273 jsval_t proto = js_get_ctor_proto(js, type_name, strlen(type_name)); 247 274 if (js_type(proto) == JS_OBJ) js_set_proto(js, obj, proto); 248 275 249 - js_set(js, obj, "_typedarray_data", js_mknum((double)(uintptr_t)ta_data)); 276 + js_set(js, obj, "__ta", js_mktypedarray(ta_data)); 250 277 js_set(js, obj, "length", js_mknum((double)length)); 251 278 js_set(js, obj, "byteLength", js_mknum((double)(length * element_size))); 252 279 js_set(js, obj, "byteOffset", js_mknum((double)byte_offset)); ··· 299 326 // TypedArray.prototype.slice(begin, end) 300 327 static jsval_t js_typedarray_slice(struct js *js, jsval_t *args, int nargs) { 301 328 jsval_t this_val = js_getthis(js); 302 - jsval_t ta_data_val = js_get(js, this_val, "_typedarray_data"); 329 + jsval_t ta_data_val = js_get(js, this_val, "__ta"); 303 330 304 - if (js_type(ta_data_val) != JS_NUM) { 305 - return js_mkerr(js, "Not a TypedArray"); 306 - } 307 - 308 - TypedArrayData *ta_data = (TypedArrayData *)(uintptr_t)js_getnum(ta_data_val); 331 + TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_data_val); 309 332 if (!ta_data) return js_mkerr(js, "Invalid TypedArray"); 310 333 311 334 int begin = 0, end = ta_data->length; ··· 337 360 // TypedArray.prototype.subarray(begin, end) 338 361 static jsval_t js_typedarray_subarray(struct js *js, jsval_t *args, int nargs) { 339 362 jsval_t this_val = js_getthis(js); 340 - jsval_t ta_data_val = js_get(js, this_val, "_typedarray_data"); 341 - 342 - if (js_type(ta_data_val) != JS_NUM) { 343 - return js_mkerr(js, "Not a TypedArray"); 344 - } 363 + jsval_t ta_data_val = js_get(js, this_val, "__ta"); 345 364 346 - TypedArrayData *ta_data = (TypedArrayData *)(uintptr_t)js_getnum(ta_data_val); 365 + TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_data_val); 347 366 if (!ta_data) return js_mkerr(js, "Invalid TypedArray"); 348 367 349 368 int begin = 0, end = ta_data->length; ··· 654 673 // Buffer.prototype.toString(encoding) 655 674 static jsval_t js_buffer_toString(struct js *js, jsval_t *args, int nargs) { 656 675 jsval_t this_val = js_getthis(js); 657 - jsval_t ta_data_val = js_get(js, this_val, "_typedarray_data"); 658 - 659 - if (js_type(ta_data_val) != JS_NUM) { 660 - return js_mkerr(js, "Not a Buffer"); 661 - } 676 + jsval_t ta_data_val = js_get(js, this_val, "__ta"); 662 677 663 - TypedArrayData *ta_data = (TypedArrayData *)(uintptr_t)js_getnum(ta_data_val); 678 + TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_data_val); 664 679 if (!ta_data) return js_mkerr(js, "Invalid Buffer"); 665 680 666 681 char *encoding = "utf8"; ··· 706 721 if (nargs < 1) return js_mkerr(js, "write requires a string"); 707 722 708 723 jsval_t this_val = js_getthis(js); 709 - jsval_t ta_data_val = js_get(js, this_val, "_typedarray_data"); 710 - 711 - if (js_type(ta_data_val) != JS_NUM) { 712 - return js_mkerr(js, "Not a Buffer"); 713 - } 724 + jsval_t ta_data_val = js_get(js, this_val, "__ta"); 714 725 715 - TypedArrayData *ta_data = (TypedArrayData *)(uintptr_t)js_getnum(ta_data_val); 726 + TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_data_val); 716 727 if (!ta_data) return js_mkerr(js, "Invalid Buffer"); 717 728 718 729 size_t str_len;
+3 -7
src/modules/crypto.c
··· 141 141 return js_mkerr(js, "libsodium initialization failed"); 142 142 } 143 143 144 - jsval_t ta_data_val = js_get(js, args[0], "_typedarray_data"); 145 - if (js_type(ta_data_val) != JS_NUM) { 146 - return js_mkerr(js, "argument must be a TypedArray"); 147 - } 148 - 149 - TypedArrayData *ta_data = (TypedArrayData *)(uintptr_t)js_getnum(ta_data_val); 144 + jsval_t ta_data_val = js_get(js, args[0], "__ta"); 145 + TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_data_val); 150 146 if (!ta_data || !ta_data->buffer) { 151 - return js_mkerr(js, "invalid TypedArray"); 147 + return js_mkerr(js, "argument must be a TypedArray"); 152 148 } 153 149 154 150 if (ta_data->byte_length > 65536) {
+10 -20
src/modules/textcodec.c
··· 29 29 if (js_type(arr) == JS_ERR) return arr; 30 30 31 31 if (str_len > 0) { 32 - jsval_t ta_data_val = js_get(js, arr, "_typedarray_data"); 33 - if (js_type(ta_data_val) == JS_NUM) { 34 - TypedArrayData *ta_data = (TypedArrayData *)(uintptr_t)js_getnum(ta_data_val); 35 - if (ta_data && ta_data->buffer && ta_data->buffer->data) memcpy(ta_data->buffer->data, str, str_len); 36 - } 32 + jsval_t ta_data_val = js_get(js, arr, "__ta"); 33 + TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_data_val); 34 + if (ta_data && ta_data->buffer && ta_data->buffer->data) memcpy(ta_data->buffer->data, str, str_len); 37 35 } 38 36 39 37 return arr; ··· 56 54 } 57 55 } 58 56 59 - jsval_t ta_data_val = js_get(js, args[1], "_typedarray_data"); 60 - if (js_type(ta_data_val) != JS_NUM) { 61 - return js_mkerr(js, "Second argument must be a Uint8Array"); 62 - } 63 - 64 - TypedArrayData *ta_data = (TypedArrayData *)(uintptr_t)js_getnum(ta_data_val); 65 - if (!ta_data) return js_mkerr(js, "Invalid Uint8Array"); 57 + jsval_t ta_data_val = js_get(js, args[1], "__ta"); 58 + TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_data_val); 59 + if (!ta_data) return js_mkerr(js, "Second argument must be a Uint8Array"); 66 60 67 61 size_t available = ta_data->byte_length; 68 62 size_t to_write = str_len < available ? str_len : available; ··· 97 91 return js_mkstr(js, "", 0); 98 92 } 99 93 100 - jsval_t ta_data_val = js_get(js, args[0], "_typedarray_data"); 101 - if (js_type(ta_data_val) == JS_NUM) { 102 - TypedArrayData *ta_data = (TypedArrayData *)(uintptr_t)js_getnum(ta_data_val); 103 - if (!ta_data || !ta_data->buffer) { 104 - return js_mkstr(js, "", 0); 105 - } 106 - 94 + jsval_t ta_data_val = js_get(js, args[0], "__ta"); 95 + TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_data_val); 96 + if (ta_data) { 97 + if (!ta_data->buffer) return js_mkstr(js, "", 0); 107 98 uint8_t *data = ta_data->buffer->data + ta_data->byte_offset; 108 99 size_t len = ta_data->byte_length; 109 - 110 100 return js_mkstr(js, (const char *)data, len); 111 101 } 112 102