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.

improve ArrayBuffer and TypedArray support

+158 -15
+1 -1
examples/spec/modules.js
··· 22 22 test('console toStringTag', Object.prototype.toString.call(console), '[object console]'); 23 23 test('JSON toStringTag', Object.prototype.toString.call(JSON), '[object JSON]'); 24 24 test('process toStringTag', Object.prototype.toString.call(process), '[object process]'); 25 - test('Buffer toStringTag', Object.prototype.toString.call(Buffer), '[object Buffer]'); 25 + test('Buffer toStringTag', Object.prototype.toString.call(Buffer.alloc(0)), '[object Buffer]'); 26 26 test('crypto toStringTag', Object.prototype.toString.call(crypto), '[object Crypto]'); 27 27 28 28 test('path toStringTag', Object.prototype.toString.call(path), '[object path]');
+1 -1
meson.build
··· 168 168 timestamp = timestamp_opt 169 169 endif 170 170 171 - version_conf.set('ANT_VERSION', '0.3.11.' + timestamp + '-g' + git_hash) 171 + version_conf.set('ANT_VERSION', '0.3.12.' + timestamp + '-g' + git_hash) 172 172 version_conf.set('ANT_BUILD_TIMESTAMP', timestamp) 173 173 174 174 cmd_cc = meson.get_compiler('c')
+116
src/ant.c
··· 206 206 } ant_library_t; 207 207 208 208 static const char *INTERN_LENGTH = NULL; 209 + static const char *INTERN_BUFFER = NULL; 209 210 static const char *INTERN_PROTOTYPE = NULL; 210 211 static const char *INTERN_CONSTRUCTOR = NULL; 211 212 static const char *INTERN_NAME = NULL; ··· 1687 1688 return count <= 4 && !has_nested; 1688 1689 } 1689 1690 1691 + // todo: split into smaller functions 1690 1692 static size_t strobj(struct js *js, jsval_t obj, char *buf, size_t len) { 1691 1693 jsoff_t time_off = lkp(js, obj, "__time", 6); 1692 1694 if (time_off != 0) return strdate(js, obj, buf, len); ··· 1721 1723 is_set = (tlen == 3 && memcmp(tag_str, "Set", 3) == 0); 1722 1724 is_arraybuffer = (tlen >= 11 && memcmp(tag_str + tlen - 11, "ArrayBuffer", 11) == 0); 1723 1725 1726 + jsval_t ta_slot = js_get_slot(js, obj, SLOT_BUFFER); 1727 + if (vtype(ta_slot) == T_TYPEDARRAY) { 1728 + TypedArrayData *ta = (TypedArrayData *)vdata(ta_slot); 1729 + if (ta && ta->buffer) { 1730 + static const char *ta_type_names[] = { 1731 + "Int8Array", "Uint8Array", "Uint8ClampedArray", 1732 + "Int16Array", "Uint16Array", "Int32Array", "Uint32Array", 1733 + "Float32Array", "Float64Array", "BigInt64Array", "BigUint64Array" 1734 + }; 1735 + 1736 + const char *type_name = NULL; 1737 + size_t type_len = 0; 1738 + 1739 + jsval_t proto = js_get_proto(js, obj); 1740 + jsval_t buffer_proto = get_ctor_proto(js, "Buffer", 6); 1741 + if (vtype(proto) == T_OBJ && vtype(buffer_proto) == T_OBJ && vdata(proto) == vdata(buffer_proto)) { 1742 + type_name = "Buffer"; 1743 + type_len = 6; 1744 + } else if (ta->type <= TYPED_ARRAY_BIGUINT64) { 1745 + type_name = ta_type_names[ta->type]; 1746 + type_len = strlen(type_name); 1747 + } else { 1748 + type_name = "TypedArray"; 1749 + type_len = 10; 1750 + } 1751 + 1752 + n += cpy(buf + n, len - n, type_name, type_len); 1753 + n += (size_t) snprintf(buf + n, len - n, "(%zu) ", ta->length); 1754 + n += cpy(buf + n, len - n, "[ ", 2); 1755 + 1756 + uint8_t *data = ta->buffer->data + ta->byte_offset; 1757 + 1758 + for (size_t i = 0; i < ta->length && i < 100; i++) { 1759 + if (i > 0) n += cpy(buf + n, len - n, ", ", 2); 1760 + 1761 + switch (ta->type) { 1762 + case TYPED_ARRAY_INT8: 1763 + n += (size_t) snprintf(buf + n, len - n, "%d", (int)((int8_t*)data)[i]); 1764 + break; 1765 + case TYPED_ARRAY_UINT8: 1766 + case TYPED_ARRAY_UINT8_CLAMPED: 1767 + n += (size_t) snprintf(buf + n, len - n, "%u", (unsigned)data[i]); 1768 + break; 1769 + case TYPED_ARRAY_INT16: 1770 + n += (size_t) snprintf(buf + n, len - n, "%d", (int)((int16_t*)data)[i]); 1771 + break; 1772 + case TYPED_ARRAY_UINT16: 1773 + n += (size_t) snprintf(buf + n, len - n, "%u", (unsigned)((uint16_t*)data)[i]); 1774 + break; 1775 + case TYPED_ARRAY_INT32: 1776 + n += (size_t) snprintf(buf + n, len - n, "%d", ((int32_t*)data)[i]); 1777 + break; 1778 + case TYPED_ARRAY_UINT32: 1779 + n += (size_t) snprintf(buf + n, len - n, "%u", ((uint32_t*)data)[i]); 1780 + break; 1781 + case TYPED_ARRAY_FLOAT32: 1782 + n += (size_t) snprintf(buf + n, len - n, "%g", (double)((float*)data)[i]); 1783 + break; 1784 + case TYPED_ARRAY_FLOAT64: 1785 + n += (size_t) snprintf(buf + n, len - n, "%g", ((double*)data)[i]); 1786 + break; 1787 + case TYPED_ARRAY_BIGINT64: 1788 + n += (size_t) snprintf(buf + n, len - n, "%lldn", (long long)((int64_t*)data)[i]); 1789 + break; 1790 + case TYPED_ARRAY_BIGUINT64: 1791 + n += (size_t) snprintf(buf + n, len - n, "%llun", (unsigned long long)((uint64_t*)data)[i]); 1792 + break; 1793 + default: 1794 + n += (size_t) snprintf(buf + n, len - n, "%u", (unsigned)data[i]); 1795 + break; 1796 + } 1797 + } 1798 + 1799 + if (ta->length > 100) n += cpy(buf + n, len - n, ", ...", 5); 1800 + n += cpy(buf + n, len - n, " ]", 2); 1801 + pop_stringify(); 1802 + return n; 1803 + } 1804 + } 1805 + 1724 1806 if (is_arraybuffer) { 1725 1807 jsval_t buf_val = js_get_slot(js, obj, SLOT_BUFFER); 1726 1808 if (vtype(buf_val) == T_NUM) { ··· 1744 1826 n += cpy(buf + n, len - n, "\n}", 2); 1745 1827 pop_stringify(); 1746 1828 return n; 1829 + } 1830 + } 1831 + 1832 + bool is_dataview = (tlen == 8 && memcmp(tag_str, "DataView", 8) == 0); 1833 + if (is_dataview) { 1834 + jsval_t dv_data_val = js_get_slot(js, obj, SLOT_DATA); 1835 + if (js_type(dv_data_val) == JS_NUM) { 1836 + DataViewData *dv = (DataViewData *)(uintptr_t)tod(dv_data_val); 1837 + if (dv && dv->buffer) { 1838 + n += cpy(buf + n, len - n, "DataView {\n", 11); 1839 + n += cpy(buf + n, len - n, " [byteLength]: ", 16); 1840 + n += (size_t) snprintf(buf + n, len - n, "%zu", dv->byte_length); 1841 + n += cpy(buf + n, len - n, ",\n", 2); 1842 + n += cpy(buf + n, len - n, " [byteOffset]: ", 16); 1843 + n += (size_t) snprintf(buf + n, len - n, "%zu", dv->byte_offset); 1844 + n += cpy(buf + n, len - n, ",\n", 2); 1845 + n += cpy(buf + n, len - n, " [buffer]: ArrayBuffer {\n", 26); 1846 + n += cpy(buf + n, len - n, " [Uint8Contents]: <", 22); 1847 + 1848 + if (dv->buffer->data && dv->buffer->length > 0) { 1849 + for (size_t i = 0; i < dv->buffer->length; i++) { 1850 + if (i > 0) n += cpy(buf + n, len - n, " ", 1); 1851 + n += (size_t) snprintf(buf + n, len - n, "%02x", dv->buffer->data[i]); 1852 + } 1853 + } 1854 + 1855 + n += cpy(buf + n, len - n, ">,\n", 3); 1856 + n += cpy(buf + n, len - n, " [byteLength]: ", 18); 1857 + n += (size_t) snprintf(buf + n, len - n, "%zu", dv->buffer->length); 1858 + n += cpy(buf + n, len - n, "\n }\n}", 6); 1859 + pop_stringify(); 1860 + return n; 1861 + } 1747 1862 } 1748 1863 } 1749 1864 ··· 3085 3200 static void intern_init(void) { 3086 3201 if (INTERN_LENGTH) return; 3087 3202 INTERN_LENGTH = intern_string("length", 6); 3203 + INTERN_BUFFER = intern_string("buffer", 6); 3088 3204 INTERN_PROTOTYPE = intern_string("prototype", 9); 3089 3205 INTERN_CONSTRUCTOR = intern_string("constructor", 11); 3090 3206 INTERN_NAME = intern_string("name", 4);
+33 -6
src/modules/buffer.c
··· 307 307 S_DONE: return true; 308 308 } 309 309 310 - static jsval_t create_typed_array(struct js *js, TypedArrayType type, ArrayBufferData *buffer, size_t byte_offset, size_t length, const char *type_name) { 310 + static jsval_t create_arraybuffer_obj(struct js *js, ArrayBufferData *buffer) { 311 + jsval_t ab_obj = js_mkobj(js); 312 + jsval_t ab_proto = js_get_ctor_proto(js, "ArrayBuffer", 11); 313 + if (js_type(ab_proto) == JS_OBJ) js_set_proto(js, ab_obj, ab_proto); 314 + 315 + js_set_slot(js, ab_obj, SLOT_BUFFER, js_mknum((double)(uintptr_t)buffer)); 316 + js_set(js, ab_obj, "byteLength", js_mknum((double)buffer->length)); 317 + buffer->ref_count++; 318 + 319 + return ab_obj; 320 + } 321 + 322 + static jsval_t create_typed_array_with_buffer( 323 + struct js *js, TypedArrayType type, ArrayBufferData *buffer, 324 + size_t byte_offset, size_t length, const char *type_name, jsval_t arraybuffer_obj 325 + ) { 311 326 TypedArrayData *ta_data = ta_arena_alloc(sizeof(TypedArrayData)); 312 327 if (!ta_data) return js_mkerr(js, "Failed to allocate TypedArray"); 313 328 ··· 328 343 js_set(js, obj, "byteLength", js_mknum((double)(length * element_size))); 329 344 js_set(js, obj, "byteOffset", js_mknum((double)byte_offset)); 330 345 js_set(js, obj, "BYTES_PER_ELEMENT", js_mknum((double)element_size)); 346 + js_set(js, obj, "buffer", arraybuffer_obj); 331 347 332 348 js_set_getter(js, obj, typedarray_index_getter); 333 349 js_set_setter(js, obj, typedarray_index_setter); ··· 335 351 return obj; 336 352 } 337 353 354 + static jsval_t create_typed_array( 355 + struct js *js, TypedArrayType type, ArrayBufferData *buffer, 356 + size_t byte_offset, size_t length, const char *type_name 357 + ) { 358 + jsval_t ab_obj = create_arraybuffer_obj(js, buffer); 359 + return create_typed_array_with_buffer(js, type, buffer, byte_offset, length, type_name, ab_obj); 360 + } 361 + 338 362 static jsval_t js_typedarray_constructor(struct js *js, jsval_t *args, int nargs, TypedArrayType type, const char *type_name) { 339 363 if (nargs == 0) { 340 364 ArrayBufferData *buffer = create_array_buffer_data(0); ··· 366 390 length = (buffer->length - byte_offset) / element_size; 367 391 } 368 392 369 - return create_typed_array(js, type, buffer, byte_offset, length, type_name); 393 + return create_typed_array_with_buffer(js, type, buffer, byte_offset, length, type_name, args[0]); 370 394 } 371 395 372 396 int arg_type = js_type(args[0]); ··· 588 612 jsval_t proto = js_get_ctor_proto(js, "DataView", 8); 589 613 if (js_type(proto) == JS_OBJ) js_set_proto(js, obj, proto); 590 614 591 - js_set_slot(js, obj, SLOT_DATA, js_mknum((double)(uintptr_t)dv_data)); 615 + js_set_slot(js, obj, SLOT_DATA, ANT_PTR(dv_data)); 616 + js_mkprop_fast(js, obj, "buffer", 6, args[0]); 617 + js_set_descriptor(js, obj, "buffer", 6, 0); 618 + 592 619 js_set(js, obj, "byteLength", js_mknum((double)byte_length)); 593 - js_set(js, obj, "byteOffset", js_mknum((double)byte_offset)); 620 + js_set(js, obj, "byteOffset", js_mknum((double)byte_offset)); 594 621 595 622 return obj; 596 623 } ··· 930 957 if (len % 2 != 0) return NULL; 931 958 932 959 size_t decoded_len = len / 2; 933 - uint8_t *decoded = ANT_GC_MALLOC(decoded_len); 960 + uint8_t *decoded = malloc(decoded_len); 934 961 if (!decoded) return NULL; 935 962 936 963 for (size_t i = 0; i < decoded_len; i++) { 937 964 unsigned int byte; 938 965 if (sscanf(data + i * 2, "%2x", &byte) != 1) { 939 - ANT_GC_FREE(decoded); return NULL; 966 + free(decoded); return NULL; 940 967 } 941 968 decoded[i] = (uint8_t)byte; 942 969 }
+6 -6
src/modules/child_process.c
··· 318 318 if (js_type(args[0]) != JS_STR) return js_mkerr(js, "Event name must be a string"); 319 319 if (js_type(args[1]) != JS_FUNC) return js_mkerr(js, "Callback must be a function"); 320 320 321 - jsval_t cp_ptr = js_get(js, this_obj, "_cp_ptr"); 321 + jsval_t cp_ptr = js_get_slot(js, this_obj, SLOT_DATA); 322 322 if (js_type(cp_ptr) == JS_UNDEF) return js_mkerr(js, "Invalid child process object"); 323 323 324 324 child_process_t *cp = (child_process_t *)(uintptr_t)js_getnum(cp_ptr); ··· 347 347 if (js_type(args[0]) != JS_STR) return js_mkerr(js, "Event name must be a string"); 348 348 if (js_type(args[1]) != JS_FUNC) return js_mkerr(js, "Callback must be a function"); 349 349 350 - jsval_t cp_ptr = js_get(js, this_obj, "_cp_ptr"); 350 + jsval_t cp_ptr = js_get_slot(js, this_obj, SLOT_DATA); 351 351 if (js_type(cp_ptr) == JS_UNDEF) return js_mkerr(js, "Invalid child process object"); 352 352 353 353 child_process_t *cp = (child_process_t *)(uintptr_t)js_getnum(cp_ptr); ··· 373 373 static jsval_t child_kill(struct js *js, jsval_t *args, int nargs) { 374 374 jsval_t this_obj = js_getthis(js); 375 375 376 - jsval_t cp_ptr = js_get(js, this_obj, "_cp_ptr"); 376 + jsval_t cp_ptr = js_get_slot(js, this_obj, SLOT_DATA); 377 377 if (js_type(cp_ptr) == JS_UNDEF) return js_mkfalse(); 378 378 379 379 child_process_t *cp = (child_process_t *)(uintptr_t)js_getnum(cp_ptr); ··· 402 402 jsval_t this_obj = js_getthis(js); 403 403 if (nargs < 1) return js_mkerr(js, "write() requires data argument"); 404 404 405 - jsval_t cp_ptr = js_get(js, this_obj, "_cp_ptr"); 405 + jsval_t cp_ptr = js_get_slot(js, this_obj, SLOT_DATA); 406 406 if (js_type(cp_ptr) == JS_UNDEF) return js_mkerr(js, "Invalid child process object"); 407 407 408 408 child_process_t *cp = (child_process_t *)(uintptr_t)js_getnum(cp_ptr); ··· 433 433 (void)args; (void)nargs; 434 434 jsval_t this_obj = js_getthis(js); 435 435 436 - jsval_t cp_ptr = js_get(js, this_obj, "_cp_ptr"); 436 + jsval_t cp_ptr = js_get_slot(js, this_obj, SLOT_DATA); 437 437 if (js_type(cp_ptr) == JS_UNDEF) return js_mkundef(); 438 438 439 439 child_process_t *cp = (child_process_t *)(uintptr_t)js_getnum(cp_ptr); ··· 448 448 static jsval_t create_child_object(struct js *js, child_process_t *cp) { 449 449 jsval_t obj = js_mkobj(js); 450 450 451 - js_set(js, obj, "_cp_ptr", js_mknum((double)(uintptr_t)cp)); 451 + js_set_slot(js, obj, SLOT_DATA, ANT_PTR(cp)); 452 452 js_set(js, obj, "pid", js_mknum((double)cp->process.pid)); 453 453 js_set(js, obj, "exitCode", js_mknull()); 454 454 js_set(js, obj, "signalCode", js_mknull());
+1 -1
src/modules/io.c
··· 168 168 lbrack: 169 169 switch (p[1]) { 170 170 case 'A': if (memcmp(p + 2, "syncFunction", 7) == 0) { EMIT_UNTIL(']', JSON_FUNC) } break; 171 - case 'b': if (memcmp(p + 2, "yteLength]", 10) == 0) { EMIT_UNTIL(']', JSON_STRING) } break; 171 + case 'b': if (memcmp(p + 2, "yte", 3) == 0 || memcmp(p + 2, "uffer]", 6) == 0) { EMIT_UNTIL(']', JSON_STRING) } break; 172 172 case 'F': if (memcmp(p + 2, "unction", 7) == 0) { EMIT_UNTIL(']', JSON_FUNC) } break; 173 173 case 'n': if (memcmp(p + 2, "ative code]", 11) == 0) { EMIT_UNTIL(']', JSON_FUNC) } break; 174 174 case 'C': if (memcmp(p + 2, "ircular", 7) == 0) { EMIT_UNTIL(']', JSON_REF) } break;