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 BigInt64Array

+328 -168
+4 -4
examples/results.txt
··· 1315 1315 compat-table/es2019/misc.optional-catch-binding.await.js: OK 1316 1316 compat-table/es2019/misc.optional-catch-binding.js: OK 1317 1317 compat-table/es2019/misc.optional-catch-binding.yield.js: OK 1318 - compat-table/es2020/BigInt64Array.js: failed 1318 + compat-table/es2020/BigInt64Array.js: OK 1319 1319 compat-table/es2020/BigInt.asIntN.js: OK 1320 1320 compat-table/es2020/BigInt.asUintN.js: OK 1321 1321 compat-table/es2020/BigInt.constructor.js: OK 1322 1322 compat-table/es2020/BigInt.js: OK 1323 - compat-table/es2020/BigUint64Array.js: failed 1324 - compat-table/es2020/DataView.prototype.getBigInt64.js: TypeError: undefined is not a function 1325 - compat-table/es2020/DataView.prototype.getBigUint64.js: TypeError: undefined is not a function 1323 + compat-table/es2020/BigUint64Array.js: OK 1324 + compat-table/es2020/DataView.prototype.getBigInt64.js: OK 1325 + compat-table/es2020/DataView.prototype.getBigUint64.js: OK 1326 1326 compat-table/es2020/Promise.allSettled.js: OK 1327 1327 compat-table/es2020/String.prototype.matchAll.js: OK 1328 1328 compat-table/es2020/String.prototype.matchAll.throws-non-global.js: OK
+5
include/modules/bigint.h
··· 21 21 ant_value_t bigint_bitxor(ant_t *js, ant_value_t a, ant_value_t b); 22 22 ant_value_t bigint_bitnot(ant_t *js, ant_value_t value); 23 23 ant_value_t bigint_asint_bits(ant_t *js, ant_value_t arg, uint64_t *bits_out); 24 + ant_value_t bigint_from_int64(ant_t *js, int64_t value); 25 + ant_value_t bigint_from_uint64(ant_t *js, uint64_t value); 26 + 27 + bool bigint_to_int64_wrapping(ant_t *js, ant_value_t value, int64_t *out); 28 + bool bigint_to_uint64_wrapping(ant_t *js, ant_value_t value, uint64_t *out); 24 29 25 30 bool bigint_is_negative(ant_t *js, ant_value_t v); 26 31 bool bigint_is_zero(ant_t *js, ant_value_t v);
+38 -1
src/modules/bigint.c
··· 143 143 return mkval(T_BIGINT, (uintptr_t)payload); 144 144 } 145 145 146 - static ant_value_t bigint_from_u64(ant_t *js, uint64_t value) { 146 + ant_value_t bigint_from_uint64(ant_t *js, uint64_t value) { 147 147 uint32_t limbs[2] = { 148 148 (uint32_t)(value & 0xffffffffu), 149 149 (uint32_t)(value >> 32) ··· 151 151 152 152 size_t count = limbs[1] == 0 ? 1 : 2; 153 153 return js_mkbigint_limbs(js, limbs, count, false); 154 + } 155 + 156 + ant_value_t bigint_from_int64(ant_t *js, int64_t value) { 157 + uint64_t magnitude = value < 0 158 + ? (uint64_t)(-(value + 1)) + 1 159 + : (uint64_t)value; 160 + 161 + uint32_t limbs[2] = { 162 + (uint32_t)(magnitude & 0xffffffffu), 163 + (uint32_t)(magnitude >> 32) 164 + }; 165 + 166 + size_t count = limbs[1] == 0 ? 1 : 2; 167 + return js_mkbigint_limbs(js, limbs, count, value < 0); 168 + } 169 + 170 + static uint64_t bigint_low_u64(ant_t *js, ant_value_t value) { 171 + size_t count = 0; 172 + const uint32_t *limbs = bigint_limbs(js, value, &count); 173 + uint64_t out = count > 0 ? (uint64_t)limbs[0] : 0; 174 + if (count > 1) out |= ((uint64_t)limbs[1] << 32); 175 + return out; 176 + } 177 + 178 + bool bigint_to_uint64_wrapping(ant_t *js, ant_value_t value, uint64_t *out) { 179 + if (!out || vtype(value) != T_BIGINT) return false; 180 + uint64_t low = bigint_low_u64(js, value); 181 + *out = bigint_is_negative(js, value) ? (uint64_t)(0 - low) : low; 182 + return true; 183 + } 184 + 185 + bool bigint_to_int64_wrapping(ant_t *js, ant_value_t value, int64_t *out) { 186 + if (!out) return false; 187 + uint64_t bits = 0; 188 + if (!bigint_to_uint64_wrapping(js, value, &bits)) return false; 189 + *out = (int64_t)bits; 190 + return true; 154 191 } 155 192 156 193 static bool bigint_parse_abs_u64(ant_t *js, ant_value_t value, uint64_t *out) {
+271 -163
src/modules/buffer.c
··· 15 15 #include "descriptors.h" 16 16 17 17 #include "silver/engine.h" 18 + #include "modules/bigint.h" 18 19 #include "modules/buffer.h" 19 20 #include "modules/symbol.h" 20 21 ··· 153 154 return false; 154 155 } 155 156 157 + static bool typedarray_read_value(ant_t *js, const TypedArrayData *ta_data, size_t index, ant_value_t *out) { 158 + if (!out || !ta_data || !ta_data->buffer || ta_data->buffer->is_detached || index >= ta_data->length) { 159 + return false; 160 + } 161 + 162 + uint8_t *data = ta_data->buffer->data + ta_data->byte_offset; 163 + switch (ta_data->type) { 164 + case TYPED_ARRAY_INT8: *out = js_mknum((double)((int8_t *)data)[index]); return true; 165 + case TYPED_ARRAY_UINT8: 166 + case TYPED_ARRAY_UINT8_CLAMPED: *out = js_mknum((double)data[index]); return true; 167 + case TYPED_ARRAY_INT16: *out = js_mknum((double)((int16_t *)data)[index]); return true; 168 + case TYPED_ARRAY_UINT16: *out = js_mknum((double)((uint16_t *)data)[index]); return true; 169 + case TYPED_ARRAY_INT32: *out = js_mknum((double)((int32_t *)data)[index]); return true; 170 + case TYPED_ARRAY_UINT32: *out = js_mknum((double)((uint32_t *)data)[index]); return true; 171 + case TYPED_ARRAY_FLOAT16: *out = js_mknum(half_to_double(((uint16_t *)data)[index])); return true; 172 + case TYPED_ARRAY_FLOAT32: *out = js_mknum((double)((float *)data)[index]); return true; 173 + case TYPED_ARRAY_FLOAT64: *out = js_mknum(((double *)data)[index]); return true; 174 + case TYPED_ARRAY_BIGINT64: *out = bigint_from_int64(js, ((int64_t *)data)[index]); return !is_err(*out); 175 + case TYPED_ARRAY_BIGUINT64: *out = bigint_from_uint64(js, ((uint64_t *)data)[index]); return !is_err(*out); 176 + default: return false; 177 + } 178 + } 179 + 156 180 static bool advance_typedarray(ant_t *js, js_iter_t *it, ant_value_t *out) { 157 181 ant_value_t iter = it->iterator; 158 182 ant_value_t ta_obj = js_get_slot(iter, SLOT_DATA); ··· 163 187 uint32_t idx = ITER_STATE_INDEX(state); 164 188 165 189 TypedArrayData *ta = buffer_get_typedarray_data(ta_obj); 166 - if (!ta || !ta->buffer || ta->buffer->is_detached || idx >= (uint32_t)ta->length) 167 - return false; 168 - 169 - uint8_t *data = ta->buffer->data + ta->byte_offset; 170 - double value; 171 - switch (ta->type) { 172 - case TYPED_ARRAY_INT8: value = (double)((int8_t *)data)[idx]; break; 173 - case TYPED_ARRAY_UINT8: 174 - case TYPED_ARRAY_UINT8_CLAMPED: value = (double)data[idx]; break; 175 - case TYPED_ARRAY_INT16: value = (double)((int16_t *)data)[idx]; break; 176 - case TYPED_ARRAY_UINT16: value = (double)((uint16_t *)data)[idx]; break; 177 - case TYPED_ARRAY_INT32: value = (double)((int32_t *)data)[idx]; break; 178 - case TYPED_ARRAY_UINT32: value = (double)((uint32_t *)data)[idx]; break; 179 - case TYPED_ARRAY_FLOAT16: value = half_to_double(((uint16_t *)data)[idx]); break; 180 - case TYPED_ARRAY_FLOAT32: value = (double)((float *)data)[idx]; break; 181 - case TYPED_ARRAY_FLOAT64: value = ((double *)data)[idx]; break; 182 - default: return false; 183 - } 190 + if (!ta || !ta->buffer || ta->buffer->is_detached || idx >= (uint32_t)ta->length) return false; 191 + 192 + ant_value_t value; 193 + if (!typedarray_read_value(js, ta, idx, &value)) return false; 184 194 185 195 switch (kind) { 186 196 case ARR_ITER_KEYS: ··· 189 199 case ARR_ITER_ENTRIES: { 190 200 ant_value_t pair = js_mkarr(js); 191 201 js_arr_push(js, pair, js_mknum((double)idx)); 192 - js_arr_push(js, pair, js_mknum(value)); 202 + js_arr_push(js, pair, value); 193 203 *out = pair; 194 204 break; 195 205 } 196 206 default: 197 - *out = js_mknum(value); 207 + *out = value; 198 208 break; 199 209 } 200 210 ··· 479 489 return js_bool(buffer_is_dataview(args[0]) || buffer_get_typedarray_data(args[0]) != NULL); 480 490 } 481 491 492 + static ant_value_t buffer_require_bigint_value(ant_t *js, ant_value_t value) { 493 + if (vtype(value) == T_BIGINT) return value; 494 + if (is_object_type(value)) { 495 + ant_value_t primitive = js_get_slot(value, SLOT_PRIMITIVE); 496 + if (vtype(primitive) == T_BIGINT) return primitive; 497 + } 498 + return js_mkerr_typed(js, JS_ERR_TYPE, "Cannot convert to BigInt"); 499 + } 500 + 501 + static ant_value_t typedarray_write_value(ant_t *js, TypedArrayData *ta_data, size_t index, ant_value_t value) { 502 + if (!ta_data || !ta_data->buffer || ta_data->buffer->is_detached || index >= ta_data->length) { 503 + return js_mkundef(); 504 + } 505 + 506 + uint8_t *data = ta_data->buffer->data + ta_data->byte_offset; 507 + switch (ta_data->type) { 508 + case TYPED_ARRAY_INT8: ((int8_t *)data)[index] = (int8_t)js_to_number(js, value); return js_mkundef(); 509 + case TYPED_ARRAY_UINT8: data[index] = (uint8_t)js_to_number(js, value); return js_mkundef(); 510 + case TYPED_ARRAY_UINT8_CLAMPED: data[index] = (uint8_t)js_to_number(js, value); return js_mkundef(); 511 + case TYPED_ARRAY_INT16: ((int16_t *)data)[index] = (int16_t)js_to_number(js, value); return js_mkundef(); 512 + case TYPED_ARRAY_UINT16: ((uint16_t *)data)[index] = (uint16_t)js_to_number(js, value); return js_mkundef(); 513 + case TYPED_ARRAY_INT32: ((int32_t *)data)[index] = (int32_t)js_to_number(js, value); return js_mkundef(); 514 + case TYPED_ARRAY_UINT32: ((uint32_t *)data)[index] = (uint32_t)js_to_number(js, value); return js_mkundef(); 515 + case TYPED_ARRAY_FLOAT16: ((uint16_t *)data)[index] = double_to_half(js_to_number(js, value)); return js_mkundef(); 516 + case TYPED_ARRAY_FLOAT32: ((float *)data)[index] = (float)js_to_number(js, value); return js_mkundef(); 517 + case TYPED_ARRAY_FLOAT64: ((double *)data)[index] = js_to_number(js, value); return js_mkundef(); 518 + case TYPED_ARRAY_BIGINT64: { 519 + ant_value_t bigint = buffer_require_bigint_value(js, value); 520 + int64_t wrapped = 0; 521 + if (is_err(bigint)) return bigint; 522 + if (!bigint_to_int64_wrapping(js, bigint, &wrapped)) { 523 + return js_mkerr_typed(js, JS_ERR_TYPE, "Cannot convert to BigInt"); 524 + } 525 + ((int64_t *)data)[index] = wrapped; 526 + return js_mkundef(); 527 + } 528 + case TYPED_ARRAY_BIGUINT64: { 529 + ant_value_t bigint = buffer_require_bigint_value(js, value); 530 + uint64_t wrapped = 0; 531 + if (is_err(bigint)) return bigint; 532 + if (!bigint_to_uint64_wrapping(js, bigint, &wrapped)) { 533 + return js_mkerr_typed(js, JS_ERR_TYPE, "Cannot convert to BigInt"); 534 + } 535 + ((uint64_t *)data)[index] = wrapped; 536 + return js_mkundef(); 537 + } 538 + default: 539 + return js_mkundef(); 540 + } 541 + } 542 + 482 543 static ant_value_t typedarray_index_getter(ant_t *js, ant_value_t obj, const char *key, size_t key_len) { 483 544 if (key_len == 0 || key_len > 10) return js_mkundef(); 484 545 ··· 492 553 TypedArrayData *ta_data = buffer_get_typedarray_data(obj); 493 554 if (!ta_data || index >= ta_data->length) return js_mkundef(); 494 555 if (!ta_data->buffer || ta_data->buffer->is_detached) return js_mkundef(); 495 - 496 - uint8_t *data = ta_data->buffer->data + ta_data->byte_offset; 497 - double value; 498 - 499 - static const void *dispatch[] = { 500 - &&L_INT8, &&L_UINT8, &&L_UINT8, &&L_INT16, &&L_UINT16, 501 - &&L_INT32, &&L_UINT32, &&L_FLOAT16, &&L_FLOAT32, &&L_FLOAT64, &&L_UNDEF, &&L_UNDEF 502 - }; 503 - 504 - if (ta_data->type > TYPED_ARRAY_BIGUINT64) goto L_UNDEF; 505 - goto *dispatch[ta_data->type]; 506 - 507 - L_INT8: value = (double)((int8_t*)data)[index]; goto L_DONE; 508 - L_UINT8: value = (double)data[index]; goto L_DONE; 509 - L_INT16: value = (double)((int16_t*)data)[index]; goto L_DONE; 510 - L_UINT16: value = (double)((uint16_t*)data)[index]; goto L_DONE; 511 - L_INT32: value = (double)((int32_t*)data)[index]; goto L_DONE; 512 - L_UINT32: value = (double)((uint32_t*)data)[index]; goto L_DONE; 513 - L_FLOAT16: value = half_to_double(((uint16_t*)data)[index]); goto L_DONE; 514 - L_FLOAT32: value = (double)((float*)data)[index]; goto L_DONE; 515 - L_FLOAT64: value = ((double*)data)[index]; goto L_DONE; 516 - L_UNDEF: return js_mkundef(); 517 - L_DONE: return js_mknum(value); 556 + 557 + ant_value_t value; 558 + if (!typedarray_read_value(js, ta_data, index, &value)) return js_mkundef(); 559 + return value; 518 560 } 519 561 520 562 static bool typedarray_index_setter(ant_t *js, ant_value_t obj, const char *key, size_t key_len, ant_value_t value) { ··· 530 572 TypedArrayData *ta_data = buffer_get_typedarray_data(obj); 531 573 if (!ta_data || index >= ta_data->length) return true; 532 574 if (!ta_data->buffer || ta_data->buffer->is_detached) return true; 533 - 534 - double num_val = vtype(value) == T_NUM ? js_getnum(value) : 0; 535 - uint8_t *data = ta_data->buffer->data + ta_data->byte_offset; 536 - 537 - static const void *dispatch[] = { 538 - &&S_INT8, &&S_UINT8, &&S_UINT8, &&S_INT16, &&S_UINT16, 539 - &&S_INT32, &&S_UINT32, &&S_FLOAT16, &&S_FLOAT32, &&S_FLOAT64, &&S_FAIL, &&S_FAIL 540 - }; 541 - 542 - if (ta_data->type > TYPED_ARRAY_BIGUINT64) goto S_FAIL; 543 - goto *dispatch[ta_data->type]; 544 - 545 - S_INT8: ((int8_t*)data)[index] = (int8_t)num_val; goto S_DONE; 546 - S_UINT8: data[index] = (uint8_t)num_val; goto S_DONE; 547 - S_INT16: ((int16_t*)data)[index] = (int16_t)num_val; goto S_DONE; 548 - S_UINT16: ((uint16_t*)data)[index] = (uint16_t)num_val; goto S_DONE; 549 - S_INT32: ((int32_t*)data)[index] = (int32_t)num_val; goto S_DONE; 550 - S_UINT32: ((uint32_t*)data)[index] = (uint32_t)num_val; goto S_DONE; 551 - S_FLOAT16: ((uint16_t*)data)[index] = double_to_half(num_val); goto S_DONE; 552 - S_FLOAT32: ((float*)data)[index] = (float)num_val; goto S_DONE; 553 - S_FLOAT64: ((double*)data)[index] = num_val; goto S_DONE; 554 - S_FAIL: return false; 555 - S_DONE: return true; 575 + 576 + return !is_err(typedarray_write_value(js, ta_data, index, value)); 556 577 } 557 578 558 579 static bool typedarray_read_number(const TypedArrayData *ta_data, size_t index, double *out) { ··· 772 793 if (!buffer) { if (values) free(values); return js_mkerr(js, "Failed to allocate buffer"); } 773 794 774 795 ant_value_t result = create_typed_array(js, type, buffer, 0, length, type_name); 775 - uint8_t *data = buffer->data; 776 - 777 - static const void *write_dispatch[] = { 778 - &&W_INT8, &&W_UINT8, &&W_UINT8, &&W_INT16, &&W_UINT16, 779 - &&W_INT32, &&W_UINT32, &&W_FLOAT16, &&W_FLOAT32, &&W_FLOAT64, &&W_DONE, &&W_DONE 780 - }; 796 + if (is_err(result)) { if (values) free(values); return result; } 797 + TypedArrayData *result_ta = buffer_get_typedarray_data(result); 781 798 782 799 for (size_t i = 0; i < length; i++) { 783 800 ant_value_t elem; ··· 786 803 snprintf(idx_str, sizeof(idx_str), "%zu", i); 787 804 elem = js_get(js, args[0], idx_str); 788 805 } 789 - 790 - double val = vtype(elem) == T_NUM 791 - ? js_getnum(elem) 792 - : js_to_number(js, elem); 793 - 794 - if (type > TYPED_ARRAY_BIGUINT64) goto W_DONE; 795 - goto *write_dispatch[type]; 796 - 797 - W_INT8: ((int8_t*)data)[i] = (int8_t)val; goto W_NEXT; 798 - W_UINT8: data[i] = (uint8_t)val; goto W_NEXT; 799 - W_INT16: ((int16_t*)data)[i] = (int16_t)val; goto W_NEXT; 800 - W_UINT16: ((uint16_t*)data)[i] = (uint16_t)val; goto W_NEXT; 801 - W_INT32: ((int32_t*)data)[i] = (int32_t)val; goto W_NEXT; 802 - W_UINT32: ((uint32_t*)data)[i] = (uint32_t)val; goto W_NEXT; 803 - W_FLOAT16: ((uint16_t*)data)[i] = double_to_half(val); goto W_NEXT; 804 - W_FLOAT32: ((float*)data)[i] = (float)val; goto W_NEXT; 805 - W_FLOAT64: ((double*)data)[i] = val; goto W_NEXT; 806 - W_NEXT:; 806 + ant_value_t write_result = typedarray_write_value(js, result_ta, i, elem); 807 + if (is_err(write_result)) { 808 + if (values) free(values); 809 + return write_result; 810 + } 807 811 } 808 - W_DONE: 809 812 if (values) free(values); 810 813 return result; 811 814 } ··· 829 832 if (idx < 0 || idx >= len) return js_mkundef(); 830 833 if (!ta_data->buffer || ta_data->buffer->is_detached) return js_mkundef(); 831 834 832 - size_t index = (size_t)idx; 833 - uint8_t *data = ta_data->buffer->data + ta_data->byte_offset; 834 - double value; 835 - 836 - switch (ta_data->type) { 837 - case TYPED_ARRAY_INT8: value = (double)((int8_t*)data)[index]; break; 838 - case TYPED_ARRAY_UINT8: 839 - case TYPED_ARRAY_UINT8_CLAMPED: value = (double)data[index]; break; 840 - case TYPED_ARRAY_INT16: value = (double)((int16_t*)data)[index]; break; 841 - case TYPED_ARRAY_UINT16: value = (double)((uint16_t*)data)[index]; break; 842 - case TYPED_ARRAY_INT32: value = (double)((int32_t*)data)[index]; break; 843 - case TYPED_ARRAY_UINT32: value = (double)((uint32_t*)data)[index]; break; 844 - case TYPED_ARRAY_FLOAT16: value = half_to_double(((uint16_t*)data)[index]); break; 845 - case TYPED_ARRAY_FLOAT32: value = (double)((float*)data)[index]; break; 846 - case TYPED_ARRAY_FLOAT64: value = ((double*)data)[index]; break; 847 - default: return js_mkundef(); 848 - } 849 - return js_mknum(value); 835 + ant_value_t value; 836 + if (!typedarray_read_value(js, ta_data, (size_t)idx, &value)) return js_mkundef(); 837 + return value; 850 838 } 851 839 852 840 static ant_value_t js_typedarray_slice(ant_t *js, ant_value_t *args, int nargs) { ··· 915 903 TypedArrayData *ta_data = buffer_get_typedarray_data(this_val); 916 904 if (!ta_data) return js_mkerr(js, "Invalid TypedArray"); 917 905 918 - double value = 0; 919 - if (nargs > 0 && vtype(args[0]) == T_NUM) value = js_getnum(args[0]); 906 + ant_value_t value = nargs > 0 ? args[0] : js_mknum(0); 920 907 921 908 ssize_t len = (ssize_t)ta_data->length; 922 909 ssize_t start = 0, end = len; ··· 927 914 start = normalize_index(start, len); 928 915 end = normalize_index(end, len); 929 916 if (end < start) end = start; 917 + 918 + if (ta_data->type == TYPED_ARRAY_BIGINT64 || ta_data->type == TYPED_ARRAY_BIGUINT64) { 919 + for (ssize_t i = start; i < end; i++) { 920 + ant_value_t write_result = typedarray_write_value(js, ta_data, (size_t)i, value); 921 + if (is_err(write_result)) return write_result; 922 + } 923 + return this_val; 924 + } 930 925 931 926 uint8_t *data = ta_data->buffer->data + ta_data->byte_offset; 932 927 ··· 939 934 goto *dispatch[ta_data->type]; 940 935 941 936 L_INT8: 942 - for (ssize_t i = start; i < end; i++) ((int8_t*)data)[i] = (int8_t)value; 937 + for (ssize_t i = start; i < end; i++) ((int8_t*)data)[i] = (int8_t)js_to_number(js, value); 943 938 goto L_DONE; 944 939 L_UINT8: 945 - for (ssize_t i = start; i < end; i++) data[i] = (uint8_t)value; 940 + for (ssize_t i = start; i < end; i++) data[i] = (uint8_t)js_to_number(js, value); 946 941 goto L_DONE; 947 942 L_INT16: 948 - for (ssize_t i = start; i < end; i++) ((int16_t*)data)[i] = (int16_t)value; 943 + for (ssize_t i = start; i < end; i++) ((int16_t*)data)[i] = (int16_t)js_to_number(js, value); 949 944 goto L_DONE; 950 945 L_UINT16: 951 - for (ssize_t i = start; i < end; i++) ((uint16_t*)data)[i] = (uint16_t)value; 946 + for (ssize_t i = start; i < end; i++) ((uint16_t*)data)[i] = (uint16_t)js_to_number(js, value); 952 947 goto L_DONE; 953 948 L_INT32: 954 - for (ssize_t i = start; i < end; i++) ((int32_t*)data)[i] = (int32_t)value; 949 + for (ssize_t i = start; i < end; i++) ((int32_t*)data)[i] = (int32_t)js_to_number(js, value); 955 950 goto L_DONE; 956 951 L_UINT32: 957 - for (ssize_t i = start; i < end; i++) ((uint32_t*)data)[i] = (uint32_t)value; 952 + for (ssize_t i = start; i < end; i++) ((uint32_t*)data)[i] = (uint32_t)js_to_number(js, value); 958 953 goto L_DONE; 959 954 L_FLOAT16: 960 - for (ssize_t i = start; i < end; i++) ((uint16_t*)data)[i] = double_to_half(value); 955 + for (ssize_t i = start; i < end; i++) ((uint16_t*)data)[i] = double_to_half(js_to_number(js, value)); 961 956 goto L_DONE; 962 957 L_FLOAT32: 963 - for (ssize_t i = start; i < end; i++) ((float*)data)[i] = (float)value; 958 + for (ssize_t i = start; i < end; i++) ((float*)data)[i] = (float)js_to_number(js, value); 964 959 goto L_DONE; 965 960 L_FLOAT64: 966 - for (ssize_t i = start; i < end; i++) ((double*)data)[i] = value; 961 + for (ssize_t i = start; i < end; i++) ((double*)data)[i] = js_to_number(js, value); 967 962 goto L_DONE; 968 963 L_DONE: 969 964 return this_val; ··· 1000 995 } 1001 996 1002 997 for (size_t i = 0; i < src_len; i++) { 1003 - double value = 0; 1004 - if (!typedarray_read_number(src_ta, i, &value)) value = 0; 1005 - (void)typedarray_write_number(dst, offset + i, value); 998 + ant_value_t value = js_mkundef(); 999 + if (!typedarray_read_value(js, src_ta, i, &value)) value = js_mknum(0); 1000 + ant_value_t write_result = typedarray_write_value(js, dst, offset + i, value); 1001 + if (is_err(write_result)) return write_result; 1006 1002 } 1007 1003 return js_mkundef(); 1008 1004 } ··· 1022 1018 if (offset + src_len > dst->length) return js_mkerr(js, "Source is too large"); 1023 1019 1024 1020 for (size_t i = 0; i < src_len; i++) { 1025 - double value = 0; 1026 1021 if (vtype(src_val) == T_STR) { 1027 1022 ant_offset_t slen = 0; 1028 1023 ant_offset_t soff = vstr(js, src_val, &slen); 1029 1024 const unsigned char *sptr = (const unsigned char *)(uintptr_t)soff; 1025 + double value = 0; 1030 1026 if (i < (size_t)slen) value = sptr[i]; 1027 + ant_value_t write_result = typedarray_write_value(js, dst, offset + i, js_mknum(value)); 1028 + if (is_err(write_result)) return write_result; 1031 1029 } else { 1032 1030 char idx[24]; 1033 1031 size_t idx_len = uint_to_str(idx, sizeof(idx), (uint64_t)i); 1034 1032 idx[idx_len] = '\0'; 1035 1033 ant_value_t elem = js_get(js, src_val, idx); 1036 - value = vtype(elem) == T_NUM ? js_getnum(elem) : 0; 1034 + ant_value_t write_result = typedarray_write_value(js, dst, offset + i, elem); 1035 + if (is_err(write_result)) return write_result; 1037 1036 } 1038 - (void)typedarray_write_number(dst, offset + i, value); 1039 1037 } 1040 1038 1041 1039 return js_mkundef(); ··· 1192 1190 if (!ta_data) return js_mkerr(js, "Invalid TypedArray"); 1193 1191 1194 1192 ssize_t index = (ssize_t)js_getnum(args[0]); 1195 - double value = js_getnum(args[1]); 1196 1193 size_t length = ta_data->length; 1197 1194 1198 1195 if (index < 0) index = (ssize_t)length + index; ··· 1206 1203 1207 1204 memcpy(new_buffer->data, ta_data->buffer->data + ta_data->byte_offset, length * element_size); 1208 1205 1209 - uint8_t *data = new_buffer->data; 1210 - 1211 - static const void *dispatch[] = { 1212 - &&W_INT8, &&W_UINT8, &&W_UINT8, &&W_INT16, &&W_UINT16, 1213 - &&W_INT32, &&W_UINT32, &&W_FLOAT16, &&W_FLOAT32, &&W_FLOAT64, &&W_DONE, &&W_DONE 1214 - }; 1215 - 1216 - if (ta_data->type > TYPED_ARRAY_BIGUINT64) goto W_DONE; 1217 - goto *dispatch[ta_data->type]; 1218 - 1219 - W_INT8: ((int8_t*)data)[index] = (int8_t)value; goto W_DONE; 1220 - W_UINT8: data[index] = (uint8_t)value; goto W_DONE; 1221 - W_INT16: ((int16_t*)data)[index] = (int16_t)value; goto W_DONE; 1222 - W_UINT16: ((uint16_t*)data)[index] = (uint16_t)value; goto W_DONE; 1223 - W_INT32: ((int32_t*)data)[index] = (int32_t)value; goto W_DONE; 1224 - W_UINT32: ((uint32_t*)data)[index] = (uint32_t)value; goto W_DONE; 1225 - W_FLOAT16: ((uint16_t*)data)[index] = double_to_half(value); goto W_DONE; 1226 - W_FLOAT32: ((float*)data)[index] = (float)value; goto W_DONE; 1227 - W_FLOAT64: ((double*)data)[index] = value; goto W_DONE; 1228 - W_DONE: 1229 - 1230 1206 ant_value_t out = create_typed_array_like( 1231 1207 js, this_val, ta_data->type, 1232 1208 new_buffer, 0, length 1233 1209 ); free_array_buffer_data(new_buffer); 1210 + if (is_err(out)) return out; 1211 + 1212 + TypedArrayData *out_ta = buffer_get_typedarray_data(out); 1213 + ant_value_t write_result = typedarray_write_value(js, out_ta, (size_t)index, args[1]); 1214 + if (is_err(write_result)) return write_result; 1234 1215 1235 1216 return out; 1236 1217 } ··· 1341 1322 result = create_typed_array(js, type, buffer, 0, count, type_name); 1342 1323 if (is_err(result)) goto done; 1343 1324 if (!gc_temp_root_handle_valid(gc_temp_root_add(&temp_roots, result))) goto oom; 1344 - uint8_t *data = buffer->data; 1325 + TypedArrayData *result_ta = buffer_get_typedarray_data(result); 1345 1326 1346 1327 for (size_t i = 0; i < count; i++) { 1347 - double val = vtype(collected[i]) == T_NUM ? js_getnum(collected[i]) : js_to_number(js, collected[i]); 1348 - switch (type) { 1349 - case TYPED_ARRAY_INT8: ((int8_t *)data)[i] = (int8_t)val; break; 1350 - case TYPED_ARRAY_UINT8: 1351 - case TYPED_ARRAY_UINT8_CLAMPED: data[i] = (uint8_t)val; break; 1352 - case TYPED_ARRAY_INT16: ((int16_t *)data)[i] = (int16_t)val; break; 1353 - case TYPED_ARRAY_UINT16: ((uint16_t *)data)[i] = (uint16_t)val; break; 1354 - case TYPED_ARRAY_INT32: ((int32_t *)data)[i] = (int32_t)val; break; 1355 - case TYPED_ARRAY_UINT32: ((uint32_t *)data)[i] = (uint32_t)val; break; 1356 - case TYPED_ARRAY_FLOAT16: ((uint16_t *)data)[i] = double_to_half(val); break; 1357 - case TYPED_ARRAY_FLOAT32: ((float *)data)[i] = (float)val; break; 1358 - case TYPED_ARRAY_FLOAT64: ((double *)data)[i] = val; break; 1359 - default: break; 1360 - }} 1328 + ant_value_t write_result = typedarray_write_value(js, result_ta, i, collected[i]); 1329 + if (is_err(write_result)) { 1330 + result = write_result; 1331 + goto done; 1332 + } 1333 + } 1361 1334 1362 1335 done: 1363 1336 if (temp_roots_active) gc_temp_root_scope_end(&temp_roots); ··· 1862 1835 return js_mkundef(); 1863 1836 } 1864 1837 1838 + static ant_value_t js_dataview_getBigInt64(ant_t *js, ant_value_t *args, int nargs) { 1839 + if (nargs < 1) return js_mkerr(js, "getBigInt64 requires byteOffset"); 1840 + 1841 + ant_value_t this_val = js_getthis(js); 1842 + DataViewData *dv = buffer_get_dataview_data(this_val); 1843 + if (!dv) return js_mkerr(js, "Not a DataView"); 1844 + size_t offset = (size_t)js_getnum(args[0]); 1845 + bool little_endian = (nargs > 1 && js_truthy(js, args[1])); 1846 + 1847 + if (offset + 8 > dv->byte_length) return js_mkerr(js, "Offset out of bounds"); 1848 + 1849 + uint8_t *ptr = dv->buffer->data + dv->byte_offset + offset; 1850 + uint64_t bits; 1851 + if (little_endian) { 1852 + bits = (uint64_t)ptr[0] | ((uint64_t)ptr[1] << 8) | ((uint64_t)ptr[2] << 16) | ((uint64_t)ptr[3] << 24) | 1853 + ((uint64_t)ptr[4] << 32) | ((uint64_t)ptr[5] << 40) | ((uint64_t)ptr[6] << 48) | ((uint64_t)ptr[7] << 56); 1854 + } else { 1855 + bits = ((uint64_t)ptr[0] << 56) | ((uint64_t)ptr[1] << 48) | ((uint64_t)ptr[2] << 40) | ((uint64_t)ptr[3] << 32) | 1856 + ((uint64_t)ptr[4] << 24) | ((uint64_t)ptr[5] << 16) | ((uint64_t)ptr[6] << 8) | (uint64_t)ptr[7]; 1857 + } 1858 + 1859 + return bigint_from_int64(js, (int64_t)bits); 1860 + } 1861 + 1862 + static ant_value_t js_dataview_setBigInt64(ant_t *js, ant_value_t *args, int nargs) { 1863 + if (nargs < 2) return js_mkerr(js, "setBigInt64 requires byteOffset and value"); 1864 + 1865 + ant_value_t this_val = js_getthis(js); 1866 + DataViewData *dv = buffer_get_dataview_data(this_val); 1867 + if (!dv) return js_mkerr(js, "Not a DataView"); 1868 + size_t offset = (size_t)js_getnum(args[0]); 1869 + ant_value_t bigint = buffer_require_bigint_value(js, args[1]); 1870 + bool little_endian = (nargs > 2 && js_truthy(js, args[2])); 1871 + int64_t wrapped = 0; 1872 + 1873 + if (is_err(bigint)) return bigint; 1874 + if (offset + 8 > dv->byte_length) return js_mkerr(js, "Offset out of bounds"); 1875 + if (!bigint_to_int64_wrapping(js, bigint, &wrapped)) { 1876 + return js_mkerr_typed(js, JS_ERR_TYPE, "Cannot convert to BigInt"); 1877 + } 1878 + 1879 + uint8_t *ptr = dv->buffer->data + dv->byte_offset + offset; 1880 + uint64_t bits = (uint64_t)wrapped; 1881 + if (little_endian) { 1882 + ptr[0] = (uint8_t)(bits & 0xFF); 1883 + ptr[1] = (uint8_t)((bits >> 8) & 0xFF); 1884 + ptr[2] = (uint8_t)((bits >> 16) & 0xFF); 1885 + ptr[3] = (uint8_t)((bits >> 24) & 0xFF); 1886 + ptr[4] = (uint8_t)((bits >> 32) & 0xFF); 1887 + ptr[5] = (uint8_t)((bits >> 40) & 0xFF); 1888 + ptr[6] = (uint8_t)((bits >> 48) & 0xFF); 1889 + ptr[7] = (uint8_t)((bits >> 56) & 0xFF); 1890 + } else { 1891 + ptr[0] = (uint8_t)((bits >> 56) & 0xFF); 1892 + ptr[1] = (uint8_t)((bits >> 48) & 0xFF); 1893 + ptr[2] = (uint8_t)((bits >> 40) & 0xFF); 1894 + ptr[3] = (uint8_t)((bits >> 32) & 0xFF); 1895 + ptr[4] = (uint8_t)((bits >> 24) & 0xFF); 1896 + ptr[5] = (uint8_t)((bits >> 16) & 0xFF); 1897 + ptr[6] = (uint8_t)((bits >> 8) & 0xFF); 1898 + ptr[7] = (uint8_t)(bits & 0xFF); 1899 + } 1900 + 1901 + return js_mkundef(); 1902 + } 1903 + 1904 + static ant_value_t js_dataview_getBigUint64(ant_t *js, ant_value_t *args, int nargs) { 1905 + if (nargs < 1) return js_mkerr(js, "getBigUint64 requires byteOffset"); 1906 + 1907 + ant_value_t this_val = js_getthis(js); 1908 + DataViewData *dv = buffer_get_dataview_data(this_val); 1909 + if (!dv) return js_mkerr(js, "Not a DataView"); 1910 + size_t offset = (size_t)js_getnum(args[0]); 1911 + bool little_endian = (nargs > 1 && js_truthy(js, args[1])); 1912 + 1913 + if (offset + 8 > dv->byte_length) return js_mkerr(js, "Offset out of bounds"); 1914 + 1915 + uint8_t *ptr = dv->buffer->data + dv->byte_offset + offset; 1916 + uint64_t bits; 1917 + if (little_endian) { 1918 + bits = (uint64_t)ptr[0] | ((uint64_t)ptr[1] << 8) | ((uint64_t)ptr[2] << 16) | ((uint64_t)ptr[3] << 24) | 1919 + ((uint64_t)ptr[4] << 32) | ((uint64_t)ptr[5] << 40) | ((uint64_t)ptr[6] << 48) | ((uint64_t)ptr[7] << 56); 1920 + } else { 1921 + bits = ((uint64_t)ptr[0] << 56) | ((uint64_t)ptr[1] << 48) | ((uint64_t)ptr[2] << 40) | ((uint64_t)ptr[3] << 32) | 1922 + ((uint64_t)ptr[4] << 24) | ((uint64_t)ptr[5] << 16) | ((uint64_t)ptr[6] << 8) | (uint64_t)ptr[7]; 1923 + } 1924 + 1925 + return bigint_from_uint64(js, bits); 1926 + } 1927 + 1928 + static ant_value_t js_dataview_setBigUint64(ant_t *js, ant_value_t *args, int nargs) { 1929 + if (nargs < 2) return js_mkerr(js, "setBigUint64 requires byteOffset and value"); 1930 + 1931 + ant_value_t this_val = js_getthis(js); 1932 + DataViewData *dv = buffer_get_dataview_data(this_val); 1933 + if (!dv) return js_mkerr(js, "Not a DataView"); 1934 + size_t offset = (size_t)js_getnum(args[0]); 1935 + ant_value_t bigint = buffer_require_bigint_value(js, args[1]); 1936 + bool little_endian = (nargs > 2 && js_truthy(js, args[2])); 1937 + uint64_t wrapped = 0; 1938 + 1939 + if (is_err(bigint)) return bigint; 1940 + if (offset + 8 > dv->byte_length) return js_mkerr(js, "Offset out of bounds"); 1941 + if (!bigint_to_uint64_wrapping(js, bigint, &wrapped)) { 1942 + return js_mkerr_typed(js, JS_ERR_TYPE, "Cannot convert to BigInt"); 1943 + } 1944 + 1945 + uint8_t *ptr = dv->buffer->data + dv->byte_offset + offset; 1946 + if (little_endian) { 1947 + ptr[0] = (uint8_t)(wrapped & 0xFF); 1948 + ptr[1] = (uint8_t)((wrapped >> 8) & 0xFF); 1949 + ptr[2] = (uint8_t)((wrapped >> 16) & 0xFF); 1950 + ptr[3] = (uint8_t)((wrapped >> 24) & 0xFF); 1951 + ptr[4] = (uint8_t)((wrapped >> 32) & 0xFF); 1952 + ptr[5] = (uint8_t)((wrapped >> 40) & 0xFF); 1953 + ptr[6] = (uint8_t)((wrapped >> 48) & 0xFF); 1954 + ptr[7] = (uint8_t)((wrapped >> 56) & 0xFF); 1955 + } else { 1956 + ptr[0] = (uint8_t)((wrapped >> 56) & 0xFF); 1957 + ptr[1] = (uint8_t)((wrapped >> 48) & 0xFF); 1958 + ptr[2] = (uint8_t)((wrapped >> 40) & 0xFF); 1959 + ptr[3] = (uint8_t)((wrapped >> 32) & 0xFF); 1960 + ptr[4] = (uint8_t)((wrapped >> 24) & 0xFF); 1961 + ptr[5] = (uint8_t)((wrapped >> 16) & 0xFF); 1962 + ptr[6] = (uint8_t)((wrapped >> 8) & 0xFF); 1963 + ptr[7] = (uint8_t)(wrapped & 0xFF); 1964 + } 1965 + 1966 + return js_mkundef(); 1967 + } 1968 + 1865 1969 static uint8_t *hex_decode(const char *data, size_t len, size_t *out_len) { 1866 1970 if (len % 2 != 0) return NULL; 1867 1971 ··· 2657 2761 js_set(js, dataview_proto, "setFloat32", js_mkfun(js_dataview_setFloat32)); 2658 2762 js_set(js, dataview_proto, "getFloat64", js_mkfun(js_dataview_getFloat64)); 2659 2763 js_set(js, dataview_proto, "setFloat64", js_mkfun(js_dataview_setFloat64)); 2764 + js_set(js, dataview_proto, "getBigInt64", js_mkfun(js_dataview_getBigInt64)); 2765 + js_set(js, dataview_proto, "setBigInt64", js_mkfun(js_dataview_setBigInt64)); 2766 + js_set(js, dataview_proto, "getBigUint64", js_mkfun(js_dataview_getBigUint64)); 2767 + js_set(js, dataview_proto, "setBigUint64", js_mkfun(js_dataview_setBigUint64)); 2660 2768 js_set_sym(js, dataview_proto, get_toStringTag_sym(), js_mkstr(js, "DataView", 8)); 2661 2769 2662 2770 js_set_slot(dataview_ctor_obj, SLOT_CFUNC, js_mkfun(js_dataview_constructor));
+10
tests/test_buffer.cjs
··· 66 66 const bi64 = new BigInt64Array(2); 67 67 console.log('BigInt64Array length:', bi64.length); 68 68 console.log('BigInt64Array BYTES_PER_ELEMENT:', bi64.BYTES_PER_ELEMENT); 69 + bi64[0] = 0x8000000000000000n; 70 + console.log('BigInt64Array wraps signed 64-bit:', bi64[0] === -0x8000000000000000n); 69 71 70 72 // Test BigUint64Array 71 73 const bu64 = new BigUint64Array(2); 72 74 console.log('BigUint64Array length:', bu64.length); 73 75 console.log('BigUint64Array BYTES_PER_ELEMENT:', bu64.BYTES_PER_ELEMENT); 76 + bu64[0] = 0x10000000000000000n; 77 + console.log('BigUint64Array wraps unsigned 64-bit:', bu64[0] === 0n); 74 78 75 79 console.log('\n=== TypedArray from ArrayBuffer ==='); 76 80 ··· 142 146 dv.setUint8(3, 0x00); 143 147 const float32 = dv.getFloat32(0, false); // 1.0 in IEEE 754 144 148 console.log('Float32:', float32); 149 + 150 + // Test BigInt64 / BigUint64 DataView operations 151 + dv.setBigInt64(0, 1n); 152 + console.log('DataView getBigInt64:', dv.getBigInt64(0) === 1n); 153 + dv.setBigUint64(0, 1n); 154 + console.log('DataView getBigUint64:', dv.getBigUint64(0) === 1n); 145 155 146 156 console.log('\n=== Buffer Tests (Node.js-style) ==='); 147 157