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,124 @@ 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 JERRY_BUILTIN_BIGINT
157+ if (ECMA_TYPEDARRAY_IS_BIGINT_TYPE (element_type ))
158+ {
159+ expected = ecma_bigint_to_bigint (expected_value , false);
160+
161+ if (ECMA_IS_VALUE_ERROR (expected ))
162+ {
163+ return expected ;
164+ }
165+
166+ if (element_type == ECMA_BIGUINT64_ARRAY )
167+ {
168+ uint64_t num ;
169+ bool sign ;
170+
171+ ecma_bigint_get_digits_and_sign (expected , & num , 1 , & sign );
172+
173+ if (sign )
174+ {
175+ num = (uint64_t ) (- (int64_t ) num );
176+ }
177+
178+ if (expected != ECMA_BIGINT_ZERO )
179+ {
180+ ecma_deref_bigint (ecma_get_extended_primitive_from_value (expected ));
181+ }
182+
183+ expected = ecma_bigint_create_from_digits (& num , 1 , false);
184+ }
185+
186+ replacement = ecma_bigint_to_bigint (replacement_value , false);
187+
188+ if (ECMA_IS_VALUE_ERROR (replacement ))
189+ {
190+ ecma_free_value (expected );
191+ return replacement ;
192+ }
193+ }
194+ else
195+ #endif /* JERRY_BUILTIN_BIGINT */
196+ {
197+ ecma_number_t tmp_exp ;
198+ ecma_number_t tmp_rep ;
199+
200+ expected = ecma_op_to_integer (expected_value , & tmp_exp );
201+
202+ if (ECMA_IS_VALUE_ERROR (expected ))
203+ {
204+ return expected ;
205+ }
206+
207+ expected = ecma_convert_number_to_typed_array_type (tmp_exp , element_type );
208+
209+ replacement = ecma_op_to_integer (replacement_value , & tmp_rep );
210+
211+ if (ECMA_IS_VALUE_ERROR (replacement ))
212+ {
213+ ecma_free_value (expected );
214+ return replacement ;
215+ }
216+
217+ replacement = ecma_make_number_value (tmp_rep );
218+ }
219+
220+ uint8_t element_size = target_info .element_size ;
221+ uint32_t offset = target_info .offset ;
222+ uint32_t indexed_position = idx * element_size + offset ;
223+
224+ if (ecma_arraybuffer_is_detached (ecma_get_object_from_value (buffer )))
225+ {
226+ ecma_free_value (expected );
227+ ecma_free_value (replacement );
228+ return ecma_raise_type_error (ECMA_ERR_ARRAYBUFFER_IS_DETACHED );
229+ }
230+
231+ ecma_typedarray_getter_fn_t typedarray_getter_cb = ecma_get_typedarray_getter_fn (element_type );
232+
233+ ecma_object_t * buffer_obj_p = ecma_get_object_from_value (buffer );
234+ lit_utf8_byte_t * pos = ecma_arraybuffer_get_buffer (buffer_obj_p ) + indexed_position ;
235+ ecma_value_t stored_value = typedarray_getter_cb (pos );
236+
237+ // TODO: Handle shared array buffers differently.
238+ if (ecma_op_same_value (stored_value , expected ))
239+ {
240+ ecma_typedarray_setter_fn_t typedarray_setter_cb = ecma_get_typedarray_setter_fn (element_type );
241+ typedarray_setter_cb (ecma_arraybuffer_get_buffer (buffer_obj_p ) + indexed_position , replacement );
242+ }
243+
244+ ecma_free_value (expected );
245+ ecma_free_value (replacement );
246+
247+ return stored_value ;
89248} /* ecma_builtin_atomics_compare_exchange */
90249
91250/**
@@ -117,11 +276,83 @@ ecma_builtin_atomics_store (ecma_value_t typedarray, /**< typedArray argument */
117276 ecma_value_t index , /**< index argument */
118277 ecma_value_t value ) /**< value argument */
119278{
120- JERRY_UNUSED (typedarray );
121- JERRY_UNUSED (index );
122- JERRY_UNUSED (value );
279+ /* 1. */
280+ ecma_value_t buffer = ecma_validate_integer_typedarray (typedarray , false);
123281
124- return ecma_make_uint32_value (0 );
282+ if (ECMA_IS_VALUE_ERROR (buffer ))
283+ {
284+ return buffer ;
285+ }
286+
287+ /* 2. */
288+ uint32_t idx = ecma_validate_atomic_access (typedarray , index );
289+
290+ if (idx == ECMA_STRING_NOT_ARRAY_INDEX )
291+ {
292+ return ECMA_VALUE_ERROR ;
293+ }
294+
295+ ecma_object_t * typedarray_p = ecma_get_object_from_value (typedarray );
296+ ecma_typedarray_info_t target_info = ecma_typedarray_get_info (typedarray_p );
297+
298+ if (ECMA_ARRAYBUFFER_LAZY_ALLOC (target_info .array_buffer_p ))
299+ {
300+ return ECMA_VALUE_ERROR ;
301+ }
302+
303+ ecma_typedarray_type_t element_type = target_info .id ;
304+
305+ ecma_typedarray_setter_fn_t typedarray_setter_cb = ecma_get_typedarray_setter_fn (element_type );
306+
307+ ecma_value_t value_to_store ;
308+ #if JERRY_BUILTIN_BIGINT
309+ if (element_type == ECMA_BIGINT64_ARRAY || element_type == ECMA_BIGUINT64_ARRAY )
310+ {
311+ value_to_store = ecma_bigint_to_bigint (value , false);
312+
313+ if (ECMA_IS_VALUE_ERROR (value_to_store ))
314+ {
315+ return value_to_store ;
316+ }
317+ }
318+ else
319+ #endif /* JERRY_BUILTIN_BIGINT */
320+ {
321+ ecma_number_t num_int ;
322+
323+ value_to_store = ecma_op_to_integer (value , & num_int );
324+
325+ if (ECMA_IS_VALUE_ERROR (value_to_store ))
326+ {
327+ return value_to_store ;
328+ }
329+
330+ if (ecma_number_is_zero (num_int ) && ecma_number_is_negative (num_int ))
331+ {
332+ num_int = (ecma_number_t ) 0 ;
333+ }
334+
335+ value_to_store = ecma_make_number_value (num_int );
336+ }
337+
338+ ecma_object_t * buffer_obj_p = ecma_get_object_from_value (buffer );
339+
340+ if (ecma_arraybuffer_is_detached (buffer_obj_p ))
341+ {
342+ ecma_free_value (value_to_store );
343+ return ecma_raise_type_error (ECMA_ERR_ARRAYBUFFER_IS_DETACHED );
344+ }
345+
346+ uint8_t element_size = target_info .element_size ;
347+
348+ uint32_t offset = target_info .offset ;
349+
350+ uint32_t indexed_position = idx * element_size + offset ;
351+
352+ // TODO: Handle shared array buffers differently.
353+ typedarray_setter_cb (ecma_arraybuffer_get_buffer (buffer_obj_p ) + indexed_position , value_to_store );
354+
355+ return value_to_store ;
125356} /* ecma_builtin_atomics_store */
126357
127358/**
0 commit comments