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 TypedArray.prototype.toReversed(), toSorted(), and with() methods

+159
+159
src/modules/buffer.c
··· 53 53 static jsval_t js_typedarray_slice(struct js *js, jsval_t *args, int nargs); 54 54 static jsval_t js_typedarray_subarray(struct js *js, jsval_t *args, int nargs); 55 55 static jsval_t js_typedarray_fill(struct js *js, jsval_t *args, int nargs); 56 + static jsval_t js_typedarray_toReversed(struct js *js, jsval_t *args, int nargs); 57 + static jsval_t js_typedarray_toSorted(struct js *js, jsval_t *args, int nargs); 58 + static jsval_t js_typedarray_with(struct js *js, jsval_t *args, int nargs); 56 59 static jsval_t js_dataview_getUint8(struct js *js, jsval_t *args, int nargs); 57 60 static jsval_t js_dataview_setUint8(struct js *js, jsval_t *args, int nargs); 58 61 static jsval_t js_dataview_getInt16(struct js *js, jsval_t *args, int nargs); ··· 594 597 goto L_DONE; 595 598 L_DONE: 596 599 return this_val; 600 + } 601 + 602 + // TypedArray.prototype.toReversed() 603 + static jsval_t js_typedarray_toReversed(struct js *js, jsval_t *args, int nargs) { 604 + (void)args; (void)nargs; 605 + jsval_t this_val = js_getthis(js); 606 + jsval_t ta_data_val = js_get_slot(js, this_val, SLOT_BUFFER); 607 + 608 + TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_data_val); 609 + if (!ta_data) return js_mkerr(js, "Invalid TypedArray"); 610 + 611 + size_t length = ta_data->length; 612 + size_t element_size = get_element_size(ta_data->type); 613 + ArrayBufferData *new_buffer = create_array_buffer_data(length * element_size); 614 + if (!new_buffer) return js_mkerr(js, "Failed to allocate new buffer"); 615 + 616 + uint8_t *src = ta_data->buffer->data + ta_data->byte_offset; 617 + uint8_t *dst = new_buffer->data; 618 + 619 + for (size_t i = 0; i < length; i++) { 620 + memcpy(dst + i * element_size, src + (length - 1 - i) * element_size, element_size); 621 + } 622 + 623 + return create_typed_array(js, ta_data->type, new_buffer, 0, length, "TypedArray"); 624 + } 625 + 626 + // TypedArray.prototype.toSorted(comparefn) 627 + static jsval_t js_typedarray_toSorted(struct js *js, jsval_t *args, int nargs) { 628 + jsval_t this_val = js_getthis(js); 629 + jsval_t ta_data_val = js_get_slot(js, this_val, SLOT_BUFFER); 630 + 631 + TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_data_val); 632 + if (!ta_data) return js_mkerr(js, "Invalid TypedArray"); 633 + 634 + size_t length = ta_data->length; 635 + size_t element_size = get_element_size(ta_data->type); 636 + ArrayBufferData *new_buffer = create_array_buffer_data(length * element_size); 637 + if (!new_buffer) return js_mkerr(js, "Failed to allocate new buffer"); 638 + 639 + memcpy(new_buffer->data, ta_data->buffer->data + ta_data->byte_offset, length * element_size); 640 + 641 + jsval_t result = create_typed_array(js, ta_data->type, new_buffer, 0, length, "TypedArray"); 642 + jsval_t result_ta_val = js_get_slot(js, result, SLOT_BUFFER); 643 + TypedArrayData *result_ta = (TypedArrayData *)js_gettypedarray(result_ta_val); 644 + uint8_t *data = result_ta->buffer->data; 645 + 646 + jsval_t comparefn = (nargs > 0 && js_type(args[0]) == JS_FUNC) ? args[0] : js_mkundef(); 647 + bool has_comparefn = js_type(comparefn) == JS_FUNC; 648 + 649 + for (size_t i = 1; i < length; i++) { 650 + for (size_t j = i; j > 0; j--) { 651 + double a_val, b_val; 652 + int cmp; 653 + 654 + static const void *read_dispatch[] = { 655 + &&R_INT8, &&R_UINT8, &&R_UINT8, &&R_INT16, &&R_UINT16, 656 + &&R_INT32, &&R_UINT32, &&R_FLOAT32, &&R_FLOAT64, &&R_DONE, &&R_DONE 657 + }; 658 + 659 + if (ta_data->type > TYPED_ARRAY_BIGUINT64) goto R_DONE; 660 + goto *read_dispatch[ta_data->type]; 661 + 662 + R_INT8: a_val = (double)((int8_t*)data)[j-1]; b_val = (double)((int8_t*)data)[j]; goto R_COMPARE; 663 + R_UINT8: a_val = (double)data[j-1]; b_val = (double)data[j]; goto R_COMPARE; 664 + R_INT16: a_val = (double)((int16_t*)data)[j-1]; b_val = (double)((int16_t*)data)[j]; goto R_COMPARE; 665 + R_UINT16: a_val = (double)((uint16_t*)data)[j-1]; b_val = (double)((uint16_t*)data)[j]; goto R_COMPARE; 666 + R_INT32: a_val = (double)((int32_t*)data)[j-1]; b_val = (double)((int32_t*)data)[j]; goto R_COMPARE; 667 + R_UINT32: a_val = (double)((uint32_t*)data)[j-1]; b_val = (double)((uint32_t*)data)[j]; goto R_COMPARE; 668 + R_FLOAT32: a_val = (double)((float*)data)[j-1]; b_val = (double)((float*)data)[j]; goto R_COMPARE; 669 + R_FLOAT64: a_val = ((double*)data)[j-1]; b_val = ((double*)data)[j]; goto R_COMPARE; 670 + R_DONE: goto SORT_DONE; 671 + 672 + R_COMPARE: 673 + if (has_comparefn) { 674 + jsval_t cmp_args[2] = { js_mknum(a_val), js_mknum(b_val) }; 675 + jsval_t cmp_result = js_call(js, comparefn, cmp_args, 2); 676 + cmp = (int)js_getnum(cmp_result); 677 + } else { 678 + cmp = (a_val > b_val) ? 1 : ((a_val < b_val) ? -1 : 0); 679 + } 680 + 681 + if (cmp <= 0) break; 682 + 683 + static const void *swap_dispatch[] = { 684 + &&S_INT8, &&S_UINT8, &&S_UINT8, &&S_INT16, &&S_UINT16, 685 + &&S_INT32, &&S_UINT32, &&S_FLOAT32, &&S_FLOAT64, &&S_DONE, &&S_DONE 686 + }; 687 + 688 + if (ta_data->type > TYPED_ARRAY_BIGUINT64) goto S_DONE; 689 + goto *swap_dispatch[ta_data->type]; 690 + 691 + S_INT8: { int8_t tmp = ((int8_t*)data)[j-1]; ((int8_t*)data)[j-1] = ((int8_t*)data)[j]; ((int8_t*)data)[j] = tmp; goto S_DONE; } 692 + S_UINT8: { uint8_t tmp = data[j-1]; data[j-1] = data[j]; data[j] = tmp; goto S_DONE; } 693 + S_INT16: { int16_t tmp = ((int16_t*)data)[j-1]; ((int16_t*)data)[j-1] = ((int16_t*)data)[j]; ((int16_t*)data)[j] = tmp; goto S_DONE; } 694 + S_UINT16: { uint16_t tmp = ((uint16_t*)data)[j-1]; ((uint16_t*)data)[j-1] = ((uint16_t*)data)[j]; ((uint16_t*)data)[j] = tmp; goto S_DONE; } 695 + S_INT32: { int32_t tmp = ((int32_t*)data)[j-1]; ((int32_t*)data)[j-1] = ((int32_t*)data)[j]; ((int32_t*)data)[j] = tmp; goto S_DONE; } 696 + S_UINT32: { uint32_t tmp = ((uint32_t*)data)[j-1]; ((uint32_t*)data)[j-1] = ((uint32_t*)data)[j]; ((uint32_t*)data)[j] = tmp; goto S_DONE; } 697 + S_FLOAT32: { float tmp = ((float*)data)[j-1]; ((float*)data)[j-1] = ((float*)data)[j]; ((float*)data)[j] = tmp; goto S_DONE; } 698 + S_FLOAT64: { double tmp = ((double*)data)[j-1]; ((double*)data)[j-1] = ((double*)data)[j]; ((double*)data)[j] = tmp; goto S_DONE; } 699 + S_DONE:; 700 + } 701 + } 702 + 703 + SORT_DONE: 704 + return result; 705 + } 706 + 707 + // TypedArray.prototype.with(index, value) 708 + static jsval_t js_typedarray_with(struct js *js, jsval_t *args, int nargs) { 709 + if (nargs < 2) return js_mkerr(js, "with requires index and value"); 710 + 711 + jsval_t this_val = js_getthis(js); 712 + jsval_t ta_data_val = js_get_slot(js, this_val, SLOT_BUFFER); 713 + 714 + TypedArrayData *ta_data = (TypedArrayData *)js_gettypedarray(ta_data_val); 715 + if (!ta_data) return js_mkerr(js, "Invalid TypedArray"); 716 + 717 + int index = (int)js_getnum(args[0]); 718 + double value = js_getnum(args[1]); 719 + size_t length = ta_data->length; 720 + 721 + if (index < 0) index = length + index; 722 + if (index < 0 || (size_t)index >= length) { 723 + return js_mkerr(js, "Index out of bounds"); 724 + } 725 + 726 + size_t element_size = get_element_size(ta_data->type); 727 + ArrayBufferData *new_buffer = create_array_buffer_data(length * element_size); 728 + if (!new_buffer) return js_mkerr(js, "Failed to allocate new buffer"); 729 + 730 + memcpy(new_buffer->data, ta_data->buffer->data + ta_data->byte_offset, length * element_size); 731 + 732 + uint8_t *data = new_buffer->data; 733 + 734 + static const void *dispatch[] = { 735 + &&W_INT8, &&W_UINT8, &&W_UINT8, &&W_INT16, &&W_UINT16, 736 + &&W_INT32, &&W_UINT32, &&W_FLOAT32, &&W_FLOAT64, &&W_DONE, &&W_DONE 737 + }; 738 + 739 + if (ta_data->type > TYPED_ARRAY_BIGUINT64) goto W_DONE; 740 + goto *dispatch[ta_data->type]; 741 + 742 + W_INT8: ((int8_t*)data)[index] = (int8_t)value; goto W_DONE; 743 + W_UINT8: data[index] = (uint8_t)value; goto W_DONE; 744 + W_INT16: ((int16_t*)data)[index] = (int16_t)value; goto W_DONE; 745 + W_UINT16: ((uint16_t*)data)[index] = (uint16_t)value; goto W_DONE; 746 + W_INT32: ((int32_t*)data)[index] = (int32_t)value; goto W_DONE; 747 + W_UINT32: ((uint32_t*)data)[index] = (uint32_t)value; goto W_DONE; 748 + W_FLOAT32: ((float*)data)[index] = (float)value; goto W_DONE; 749 + W_FLOAT64: ((double*)data)[index] = value; goto W_DONE; 750 + W_DONE: 751 + 752 + return create_typed_array(js, ta_data->type, new_buffer, 0, length, "TypedArray"); 597 753 } 598 754 599 755 #define DEFINE_TYPEDARRAY_CONSTRUCTOR(name, type) \ ··· 1415 1571 js_set(js, typedarray_proto, "slice", js_mkfun(js_typedarray_slice)); 1416 1572 js_set(js, typedarray_proto, "subarray", js_mkfun(js_typedarray_subarray)); 1417 1573 js_set(js, typedarray_proto, "fill", js_mkfun(js_typedarray_fill)); 1574 + js_set(js, typedarray_proto, "toReversed", js_mkfun(js_typedarray_toReversed)); 1575 + js_set(js, typedarray_proto, "toSorted", js_mkfun(js_typedarray_toSorted)); 1576 + js_set(js, typedarray_proto, "with", js_mkfun(js_typedarray_with)); 1418 1577 js_set(js, typedarray_proto, get_toStringTag_sym_key(), js_mkstr(js, "TypedArray", 10)); 1419 1578 1420 1579 #define SETUP_TYPEDARRAY(name) \