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+ static ecma_value_t
77+ ecma_convert_number_to_typed_array_type (ecma_number_t num , ecma_typedarray_type_t element_type )
78+ {
79+ uint32_t value = ecma_typedarray_setter_number_to_uint32 (num );
80+
81+ switch (element_type )
82+ {
83+ case ECMA_INT8_ARRAY :
84+ {
85+ return ecma_make_number_value ((int8_t ) value );
86+ }
87+ case ECMA_UINT8_ARRAY :
88+ {
89+ return ecma_make_number_value ((uint8_t ) value );
90+ }
91+ case ECMA_INT16_ARRAY :
92+ {
93+ return ecma_make_number_value ((int16_t ) value );
94+ }
95+ case ECMA_UINT16_ARRAY :
96+ {
97+ return ecma_make_number_value ((uint16_t ) value );
98+ }
99+ case ECMA_INT32_ARRAY :
100+ {
101+ return ecma_make_number_value ((int32_t ) value );
102+ }
103+ default :
104+ {
105+ JERRY_ASSERT (element_type == ECMA_UINT32_ARRAY );
106+
107+ return ecma_make_number_value (value );
108+ }
109+ }
110+ }
111+
69112/**
70113 * The Atomics object's 'compareExchange' routine
71114 *
72- * See also: ES11 24 .4.4
115+ * See also: ES12 25 .4.4
73116 *
74117 * @return ecma value
75118 * Returned value must be freed with ecma_free_value.
@@ -80,12 +123,122 @@ ecma_builtin_atomics_compare_exchange (ecma_value_t typedarray, /**< typedArray
80123 ecma_value_t expected_value , /**< expectedValue argument */
81124 ecma_value_t replacement_value ) /**< replacementValue argument*/
82125{
83- JERRY_UNUSED (typedarray );
84- JERRY_UNUSED (index );
85- JERRY_UNUSED (expected_value );
86- JERRY_UNUSED (replacement_value );
126+ ecma_value_t buffer = ecma_validate_integer_typedarray (typedarray , false);
87127
88- return ecma_make_uint32_value (0 );
128+ if (ECMA_IS_VALUE_ERROR (buffer ))
129+ {
130+ return buffer ;
131+ }
132+
133+ uint32_t idx = ecma_validate_atomic_access (typedarray , index );
134+
135+ if (idx == ECMA_STRING_NOT_ARRAY_INDEX )
136+ {
137+ return ECMA_VALUE_ERROR ;
138+ }
139+
140+ ecma_object_t * typedarray_p = ecma_get_object_from_value (typedarray );
141+ ecma_typedarray_info_t target_info = ecma_typedarray_get_info (typedarray_p );
142+
143+ if (ECMA_ARRAYBUFFER_LAZY_ALLOC (target_info .array_buffer_p ))
144+ {
145+ return ECMA_VALUE_ERROR ;
146+ }
147+
148+ ecma_typedarray_type_t element_type = target_info .id ;
149+ ecma_value_t expected ;
150+ ecma_value_t replacement ;
151+
152+ if (ECMA_TYPEDARRAY_IS_BIGINT_TYPE (element_type ))
153+ {
154+ expected = ecma_bigint_to_bigint (expected_value , false);
155+
156+ if (ECMA_IS_VALUE_ERROR (expected ))
157+ {
158+ return expected ;
159+ }
160+
161+ if (element_type == ECMA_BIGUINT64_ARRAY )
162+ {
163+ uint64_t num ;
164+ bool sign ;
165+
166+ ecma_bigint_get_digits_and_sign (expected , & num , 1 , & sign );
167+
168+ if (sign )
169+ {
170+ num = (uint64_t ) (- (int64_t ) num );
171+ }
172+
173+ if (expected != ECMA_BIGINT_ZERO )
174+ {
175+ ecma_deref_bigint (ecma_get_extended_primitive_from_value (expected ));
176+ }
177+
178+ expected = ecma_bigint_create_from_digits (& num , 1 , false);
179+ }
180+
181+ replacement = ecma_bigint_to_bigint (replacement_value , false);
182+
183+ if (ECMA_IS_VALUE_ERROR (replacement ))
184+ {
185+ ecma_free_value (expected );
186+ return replacement ;
187+ }
188+ }
189+ else
190+ {
191+ ecma_number_t tmp_exp ;
192+ ecma_number_t tmp_rep ;
193+
194+ expected = ecma_op_to_integer (expected_value , & tmp_exp );
195+
196+ if (ECMA_IS_VALUE_ERROR (expected ))
197+ {
198+ return expected ;
199+ }
200+
201+ expected = ecma_convert_number_to_typed_array_type (tmp_exp , element_type );
202+
203+ replacement = ecma_op_to_integer (replacement_value , & tmp_rep );
204+
205+ if (ECMA_IS_VALUE_ERROR (replacement ))
206+ {
207+ ecma_free_value (expected );
208+ return replacement ;
209+ }
210+
211+ replacement = ecma_make_number_value (tmp_rep );
212+ }
213+
214+ uint8_t element_size = target_info .element_size ;
215+ uint32_t offset = target_info .offset ;
216+ uint32_t indexed_position = idx * element_size + offset ;
217+
218+ if (ecma_arraybuffer_is_detached (ecma_get_object_from_value (buffer )))
219+ {
220+ ecma_free_value (expected );
221+ ecma_free_value (replacement );
222+ return ecma_raise_type_error (ECMA_ERR_ARRAYBUFFER_IS_DETACHED );
223+ }
224+
225+ ecma_typedarray_getter_fn_t typedarray_getter_cb = ecma_get_typedarray_getter_fn (element_type );
226+
227+ ecma_object_t * buffer_obj_p = ecma_get_object_from_value (buffer );
228+ lit_utf8_byte_t * pos = ecma_arraybuffer_get_buffer (buffer_obj_p ) + indexed_position ;
229+ ecma_value_t stored_value = typedarray_getter_cb (pos );
230+
231+ // TODO: Handle shared array buffers differently.
232+ if (ecma_op_same_value (stored_value , expected ))
233+ {
234+ ecma_typedarray_setter_fn_t typedarray_setter_cb = ecma_get_typedarray_setter_fn (element_type );
235+ typedarray_setter_cb (ecma_arraybuffer_get_buffer (buffer_obj_p ) + indexed_position , replacement );
236+ }
237+
238+ ecma_free_value (expected );
239+ ecma_free_value (replacement );
240+
241+ return stored_value ;
89242} /* ecma_builtin_atomics_compare_exchange */
90243
91244/**
@@ -117,11 +270,80 @@ ecma_builtin_atomics_store (ecma_value_t typedarray, /**< typedArray argument */
117270 ecma_value_t index , /**< index argument */
118271 ecma_value_t value ) /**< value argument */
119272{
120- JERRY_UNUSED (typedarray );
121- JERRY_UNUSED (index );
122- JERRY_UNUSED (value );
273+ /* 1. */
274+ ecma_value_t buffer = ecma_validate_integer_typedarray (typedarray , false);
123275
124- return ecma_make_uint32_value (0 );
276+ if (ECMA_IS_VALUE_ERROR (buffer ))
277+ {
278+ return buffer ;
279+ }
280+
281+ /* 2. */
282+ uint32_t idx = ecma_validate_atomic_access (typedarray , index );
283+
284+ if (idx == ECMA_STRING_NOT_ARRAY_INDEX )
285+ {
286+ return ECMA_VALUE_ERROR ;
287+ }
288+
289+ ecma_object_t * typedarray_p = ecma_get_object_from_value (typedarray );
290+ ecma_typedarray_info_t target_info = ecma_typedarray_get_info (typedarray_p );
291+
292+ if (ECMA_ARRAYBUFFER_LAZY_ALLOC (target_info .array_buffer_p ))
293+ {
294+ return ECMA_VALUE_ERROR ;
295+ }
296+
297+ uint8_t element_size = target_info .element_size ;
298+
299+ ecma_typedarray_type_t element_type = target_info .id ;
300+
301+ uint32_t offset = target_info .offset ;
302+
303+ uint32_t indexed_position = idx * element_size + offset ;
304+
305+ ecma_typedarray_setter_fn_t typedarray_setter_cb = ecma_get_typedarray_setter_fn (element_type );
306+ ecma_object_t * buffer_obj_p = ecma_get_object_from_value (buffer );
307+
308+ ecma_value_t v ;
309+ if (element_type == ECMA_BIGINT64_ARRAY || element_type == ECMA_BIGUINT64_ARRAY )
310+ {
311+ v = ecma_bigint_to_bigint (value , false);
312+ }
313+ else
314+ {
315+ ecma_number_t num_int ;
316+
317+ v = ecma_op_to_integer (value , & num_int );
318+
319+ if (ECMA_IS_VALUE_ERROR (v ))
320+ {
321+ return v ;
322+ }
323+
324+ if (ecma_number_is_zero (num_int ) && ecma_number_is_negative (num_int ))
325+ {
326+ num_int = (ecma_number_t ) 0 ;
327+ }
328+
329+ v = ecma_make_number_value (num_int );
330+ }
331+
332+ if (ECMA_IS_VALUE_ERROR (v ))
333+ {
334+ return v ;
335+ }
336+
337+ if (ecma_arraybuffer_is_detached (ecma_get_object_from_value (buffer )))
338+ {
339+ ecma_free_value (v );
340+ return ecma_raise_type_error (ECMA_ERR_ARRAYBUFFER_IS_DETACHED );
341+ }
342+
343+ // TODO: Handle shared array buffers differently.
344+ typedarray_setter_cb (ecma_arraybuffer_get_buffer (buffer_obj_p ) + indexed_position , v );
345+
346+ return v ;
125347} /* ecma_builtin_atomics_store */
126348
127349/**
0 commit comments