@@ -646,32 +646,148 @@ ecma_builtin_typedarray_prototype_reverse (ecma_value_t this_arg) /**< this argu
646646 return ecma_copy_value (this_arg );
647647} /* ecma_builtin_typedarray_prototype_reverse */
648648
649+ /**
650+ * The %TypedArray%.prototype object's 'set' routine for a typedArray source
651+ *
652+ * See also:
653+ * ES2015, 22.2.3.22, 22.2.3.22.2
654+ *
655+ * @return ecma value of undefined if success, error otherwise.
656+ * Returned value must be freed with ecma_free_value.
657+ */
658+ static ecma_value_t
659+ ecma_op_typedarray_set_with_typedarray (ecma_value_t this_arg , /**< this argument */
660+ ecma_value_t arr_val , /**< typedarray object */
661+ ecma_value_t offset_val ) /**< offset value */
662+ {
663+ /* 6.~ 8. targetOffset */
664+ ecma_number_t target_offset_num ;
665+ if (!ecma_is_value_empty (ecma_get_number (offset_val , & target_offset_num )))
666+ {
667+ return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid offset" ));
668+ }
669+
670+ if (ecma_number_is_nan (target_offset_num ))
671+ {
672+ target_offset_num = 0 ;
673+ }
674+
675+ if (target_offset_num <= -1.0 || target_offset_num >= (ecma_number_t ) UINT32_MAX + 0.5 )
676+ {
677+ return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid offset" ));
678+ }
679+
680+ ecma_object_t * target_typedarray_p = ecma_get_object_from_value (this_arg );
681+ ecma_object_t * src_typedarray_p = ecma_get_object_from_value (arr_val );
682+
683+ /* 9. targetBuffer */
684+ ecma_object_t * target_arraybuffer_p = ecma_typedarray_get_arraybuffer (target_typedarray_p );
685+ lit_utf8_byte_t * target_buffer_p = ecma_typedarray_get_buffer (target_typedarray_p );
686+
687+ /* 11. targetLength */
688+ ecma_length_t target_length = ecma_typedarray_get_length (target_typedarray_p );
689+
690+ /* 12. srcBuffer */
691+ ecma_object_t * src_arraybuffer_p = ecma_typedarray_get_arraybuffer (src_typedarray_p );
692+ lit_utf8_byte_t * src_buffer_p = ecma_typedarray_get_buffer (src_typedarray_p );
693+
694+ /* 15. targetType */
695+ lit_magic_string_id_t target_class_id = ecma_object_get_class_name (target_typedarray_p );
696+
697+ /* 16. targetElementSize */
698+ uint8_t target_shift = ecma_typedarray_get_element_size_shift (target_typedarray_p );
699+ uint8_t target_element_size = (uint8_t ) (1 << target_shift );
700+
701+ /* 17. targetByteOffset */
702+ ecma_length_t target_byte_offset = ecma_typedarray_get_offset (target_typedarray_p );
703+
704+ /* 19. srcType */
705+ lit_magic_string_id_t src_class_id = ecma_object_get_class_name (src_typedarray_p );
706+
707+ /* 20. srcElementSize */
708+ uint8_t src_shift = ecma_typedarray_get_element_size_shift (src_typedarray_p );
709+ uint8_t src_element_size = (uint8_t ) (1 << src_shift );
710+
711+ /* 21. srcLength */
712+ ecma_length_t src_length = ecma_typedarray_get_length (src_typedarray_p );
713+ uint32_t src_length_uint32 = ecma_number_to_uint32 (src_length );
714+
715+ if ((ecma_number_t ) src_length_uint32 != src_length )
716+ {
717+ return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid source length" ));
718+ }
719+
720+ /* 22. srcByteOffset */
721+ ecma_length_t src_byte_offset = ecma_typedarray_get_offset (src_typedarray_p );
722+
723+ /* 23. */
724+ uint32_t target_offset_uint32 = ecma_number_to_uint32 (target_offset_num );
725+
726+ if ((int64_t ) src_length_uint32 + target_offset_uint32 > target_length )
727+ {
728+ return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid range of index" ));
729+ }
730+
731+ /* 24.d, 25. srcByteIndex */
732+ ecma_length_t src_byte_index = 0 ;
733+
734+ if (src_arraybuffer_p != target_arraybuffer_p )
735+ {
736+ src_byte_index = src_byte_offset ;
737+ }
738+
739+ /* 26. targetByteIndex */
740+ uint32_t target_byte_index = target_offset_uint32 * target_element_size + target_byte_offset ;
741+
742+ /* 27. limit */
743+ uint32_t limit = target_byte_index + target_element_size * src_length_uint32 ;
744+
745+ if (src_class_id == target_class_id )
746+ {
747+ memmove (target_buffer_p + target_byte_index , src_buffer_p + src_byte_index ,
748+ target_element_size * src_length_uint32 );
749+ }
750+ else
751+ {
752+ while (target_byte_index < limit )
753+ {
754+ ecma_number_t elem_num = ecma_get_typedarray_element (src_buffer_p + src_byte_index , src_class_id );
755+ ecma_set_typedarray_element (target_buffer_p + target_byte_index , elem_num , target_class_id );
756+ src_byte_index += src_element_size ;
757+ target_byte_index += target_element_size ;
758+ }
759+ }
760+
761+ return ECMA_VALUE_UNDEFINED ;
762+ } /* ecma_op_typedarray_set_with_typedarray */
763+
649764/**
650765 * The %TypedArray%.prototype object's 'set' routine
651766 *
652767 * See also:
653768 * ES2015, 22.2.3.22, 22.2.3.22.1
654769 *
655- * @return ecma value of undefined.
770+ * @return ecma value of undefined if success, error otherwise.
771+ * Returned value must be freed with ecma_free_value.
656772 */
657773ecma_value_t
658774ecma_builtin_typedarray_prototype_set (ecma_value_t this_arg , /**< this argument */
659775 ecma_value_t arr_val , /**< array object */
660776 ecma_value_t offset_val ) /**< offset value */
661777{
662- /* 1. */
663- if (ecma_is_typedarray (arr_val ))
664- {
665- /* 22.2.3.22.2 %TypedArray%.prototype(typedArray [, offset ]) is not supported */
666- return ecma_raise_type_error (ECMA_ERR_MSG ("TypedArray.set(typedArray [,offset]) is not supported." ));
667- }
668-
669778 /* 2.~ 4. */
670779 if (!ecma_is_typedarray (this_arg ))
671780 {
672781 return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not a TypedArray." ));
673782 }
674783
784+ /* 1. */
785+ if (ecma_is_typedarray (arr_val ))
786+ {
787+ /* 22.2.3.22.2 */
788+ return ecma_op_typedarray_set_with_typedarray (this_arg , arr_val , offset_val );
789+ }
790+
675791 /* 6.~ 8. targetOffset */
676792 ecma_value_t ret_val = ECMA_VALUE_EMPTY ;
677793 ECMA_OP_TO_NUMBER_TRY_CATCH (target_offset_num , offset_val , ret_val );
0 commit comments