1313 * limitations under the License.
1414 */
1515
16+ #include "ecma-arraybuffer-object.h"
1617#include "ecma-atomics-object.h"
18+ #include "ecma-bigint.h"
1719#include "ecma-builtins.h"
20+ #include "ecma-errors.h"
21+ #include "ecma-exceptions.h"
22+ #include "ecma-gc.h"
1823#include "ecma-globals.h"
1924#include "ecma-helpers.h"
25+ #include "ecma-shared-arraybuffer-object.h"
26+ #include "ecma-typedarray-object.h"
2027
2128#include "jrt.h"
2229
6673 * @{
6774 */
6875
76+ /**
77+ * Convert ecma_number to the appropriate type according to the element type of typedarray.
78+ */
79+ static ecma_value_t
80+ ecma_convert_number_to_typed_array_type (ecma_number_t num , /**< ecma_number argument */
81+ ecma_typedarray_type_t element_type ) /**< element type of typedarray */
82+ {
83+ uint32_t value = ecma_typedarray_setter_number_to_uint32 (num );
84+
85+ switch (element_type )
86+ {
87+ case ECMA_INT8_ARRAY :
88+ {
89+ return ecma_make_number_value ((int8_t ) value );
90+ }
91+ case ECMA_UINT8_ARRAY :
92+ {
93+ return ecma_make_number_value ((uint8_t ) value );
94+ }
95+ case ECMA_INT16_ARRAY :
96+ {
97+ return ecma_make_number_value ((int16_t ) value );
98+ }
99+ case ECMA_UINT16_ARRAY :
100+ {
101+ return ecma_make_number_value ((uint16_t ) value );
102+ }
103+ case ECMA_INT32_ARRAY :
104+ {
105+ return ecma_make_number_value ((int32_t ) value );
106+ }
107+ default :
108+ {
109+ JERRY_ASSERT (element_type == ECMA_UINT32_ARRAY );
110+
111+ return ecma_make_number_value (value );
112+ }
113+ }
114+ } /* ecma_convert_number_to_typed_array_type */
115+
69116/**
70117 * The Atomics object's 'compareExchange' routine
71118 *
72- * See also: ES11 24 .4.4
119+ * See also: ES12 25 .4.4
73120 *
74121 * @return ecma value
75122 * Returned value must be freed with ecma_free_value.
@@ -80,12 +127,122 @@ ecma_builtin_atomics_compare_exchange (ecma_value_t typedarray, /**< typedArray
80127 ecma_value_t expected_value , /**< expectedValue argument */
81128 ecma_value_t replacement_value ) /**< replacementValue argument*/
82129{
83- JERRY_UNUSED (typedarray );
84- JERRY_UNUSED (index );
85- JERRY_UNUSED (expected_value );
86- JERRY_UNUSED (replacement_value );
130+ ecma_value_t buffer = ecma_validate_integer_typedarray (typedarray , false);
87131
88- return ecma_make_uint32_value (0 );
132+ if (ECMA_IS_VALUE_ERROR (buffer ))
133+ {
134+ return buffer ;
135+ }
136+
137+ uint32_t idx = ecma_validate_atomic_access (typedarray , index );
138+
139+ if (idx == ECMA_STRING_NOT_ARRAY_INDEX )
140+ {
141+ return ECMA_VALUE_ERROR ;
142+ }
143+
144+ ecma_object_t * typedarray_p = ecma_get_object_from_value (typedarray );
145+ ecma_typedarray_info_t target_info = ecma_typedarray_get_info (typedarray_p );
146+
147+ if (ECMA_ARRAYBUFFER_LAZY_ALLOC (target_info .array_buffer_p ))
148+ {
149+ return ECMA_VALUE_ERROR ;
150+ }
151+
152+ ecma_typedarray_type_t element_type = target_info .id ;
153+ ecma_value_t expected ;
154+ ecma_value_t replacement ;
155+
156+ if (ECMA_TYPEDARRAY_IS_BIGINT_TYPE (element_type ))
157+ {
158+ expected = ecma_bigint_to_bigint (expected_value , false);
159+
160+ if (ECMA_IS_VALUE_ERROR (expected ))
161+ {
162+ return expected ;
163+ }
164+
165+ if (element_type == ECMA_BIGUINT64_ARRAY )
166+ {
167+ uint64_t num ;
168+ bool sign ;
169+
170+ ecma_bigint_get_digits_and_sign (expected , & num , 1 , & sign );
171+
172+ if (sign )
173+ {
174+ num = (uint64_t ) (- (int64_t ) num );
175+ }
176+
177+ if (expected != ECMA_BIGINT_ZERO )
178+ {
179+ ecma_deref_bigint (ecma_get_extended_primitive_from_value (expected ));
180+ }
181+
182+ expected = ecma_bigint_create_from_digits (& num , 1 , false);
183+ }
184+
185+ replacement = ecma_bigint_to_bigint (replacement_value , false);
186+
187+ if (ECMA_IS_VALUE_ERROR (replacement ))
188+ {
189+ ecma_free_value (expected );
190+ return replacement ;
191+ }
192+ }
193+ else
194+ {
195+ ecma_number_t tmp_exp ;
196+ ecma_number_t tmp_rep ;
197+
198+ expected = ecma_op_to_integer (expected_value , & tmp_exp );
199+
200+ if (ECMA_IS_VALUE_ERROR (expected ))
201+ {
202+ return expected ;
203+ }
204+
205+ expected = ecma_convert_number_to_typed_array_type (tmp_exp , element_type );
206+
207+ replacement = ecma_op_to_integer (replacement_value , & tmp_rep );
208+
209+ if (ECMA_IS_VALUE_ERROR (replacement ))
210+ {
211+ ecma_free_value (expected );
212+ return replacement ;
213+ }
214+
215+ replacement = ecma_make_number_value (tmp_rep );
216+ }
217+
218+ uint8_t element_size = target_info .element_size ;
219+ uint32_t offset = target_info .offset ;
220+ uint32_t indexed_position = idx * element_size + offset ;
221+
222+ if (ecma_arraybuffer_is_detached (ecma_get_object_from_value (buffer )))
223+ {
224+ ecma_free_value (expected );
225+ ecma_free_value (replacement );
226+ return ecma_raise_type_error (ECMA_ERR_ARRAYBUFFER_IS_DETACHED );
227+ }
228+
229+ ecma_typedarray_getter_fn_t typedarray_getter_cb = ecma_get_typedarray_getter_fn (element_type );
230+
231+ ecma_object_t * buffer_obj_p = ecma_get_object_from_value (buffer );
232+ lit_utf8_byte_t * pos = ecma_arraybuffer_get_buffer (buffer_obj_p ) + indexed_position ;
233+ ecma_value_t stored_value = typedarray_getter_cb (pos );
234+
235+ // TODO: Handle shared array buffers differently.
236+ if (ecma_op_same_value (stored_value , expected ))
237+ {
238+ ecma_typedarray_setter_fn_t typedarray_setter_cb = ecma_get_typedarray_setter_fn (element_type );
239+ typedarray_setter_cb (ecma_arraybuffer_get_buffer (buffer_obj_p ) + indexed_position , replacement );
240+ }
241+
242+ ecma_free_value (expected );
243+ ecma_free_value (replacement );
244+
245+ return stored_value ;
89246} /* ecma_builtin_atomics_compare_exchange */
90247
91248/**
@@ -117,11 +274,80 @@ ecma_builtin_atomics_store (ecma_value_t typedarray, /**< typedArray argument */
117274 ecma_value_t index , /**< index argument */
118275 ecma_value_t value ) /**< value argument */
119276{
120- JERRY_UNUSED (typedarray );
121- JERRY_UNUSED (index );
122- JERRY_UNUSED (value );
277+ /* 1. */
278+ ecma_value_t buffer = ecma_validate_integer_typedarray (typedarray , false);
123279
124- return ecma_make_uint32_value (0 );
280+ if (ECMA_IS_VALUE_ERROR (buffer ))
281+ {
282+ return buffer ;
283+ }
284+
285+ /* 2. */
286+ uint32_t idx = ecma_validate_atomic_access (typedarray , index );
287+
288+ if (idx == ECMA_STRING_NOT_ARRAY_INDEX )
289+ {
290+ return ECMA_VALUE_ERROR ;
291+ }
292+
293+ ecma_object_t * typedarray_p = ecma_get_object_from_value (typedarray );
294+ ecma_typedarray_info_t target_info = ecma_typedarray_get_info (typedarray_p );
295+
296+ if (ECMA_ARRAYBUFFER_LAZY_ALLOC (target_info .array_buffer_p ))
297+ {
298+ return ECMA_VALUE_ERROR ;
299+ }
300+
301+ uint8_t element_size = target_info .element_size ;
302+
303+ ecma_typedarray_type_t element_type = target_info .id ;
304+
305+ uint32_t offset = target_info .offset ;
306+
307+ uint32_t indexed_position = idx * element_size + offset ;
308+
309+ ecma_typedarray_setter_fn_t typedarray_setter_cb = ecma_get_typedarray_setter_fn (element_type );
310+ ecma_object_t * buffer_obj_p = ecma_get_object_from_value (buffer );
311+
312+ ecma_value_t value_to_store ;
313+ if (element_type == ECMA_BIGINT64_ARRAY || element_type == ECMA_BIGUINT64_ARRAY )
314+ {
315+ value_to_store = ecma_bigint_to_bigint (value , false);
316+
317+ if (ECMA_IS_VALUE_ERROR (value_to_store ))
318+ {
319+ return value_to_store ;
320+ }
321+ }
322+ else
323+ {
324+ ecma_number_t num_int ;
325+
326+ value_to_store = ecma_op_to_integer (value , & num_int );
327+
328+ if (ECMA_IS_VALUE_ERROR (value_to_store ))
329+ {
330+ return value_to_store ;
331+ }
332+
333+ if (ecma_number_is_zero (num_int ) && ecma_number_is_negative (num_int ))
334+ {
335+ num_int = (ecma_number_t ) 0 ;
336+ }
337+
338+ value_to_store = ecma_make_number_value (num_int );
339+ }
340+
341+ if (ecma_arraybuffer_is_detached (ecma_get_object_from_value (buffer )))
342+ {
343+ ecma_free_value (value_to_store );
344+ return ecma_raise_type_error (ECMA_ERR_ARRAYBUFFER_IS_DETACHED );
345+ }
346+
347+ // TODO: Handle shared array buffers differently.
348+ typedarray_setter_cb (ecma_arraybuffer_get_buffer (buffer_obj_p ) + indexed_position , value_to_store );
349+
350+ return value_to_store ;
125351} /* ecma_builtin_atomics_store */
126352
127353/**
0 commit comments