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
6976/**
7077 * The Atomics object's 'compareExchange' routine
7178 *
72- * See also: ES11 24 .4.4
79+ * See also: ES12 25 .4.4
7380 *
7481 * @return ecma value
7582 * Returned value must be freed with ecma_free_value.
@@ -80,12 +87,90 @@ ecma_builtin_atomics_compare_exchange (ecma_value_t typedarray, /**< typedArray
8087 ecma_value_t expected_value , /**< expectedValue argument */
8188 ecma_value_t replacement_value ) /**< replacementValue argument*/
8289{
83- JERRY_UNUSED (typedarray );
84- JERRY_UNUSED (index );
85- JERRY_UNUSED (expected_value );
86- JERRY_UNUSED (replacement_value );
90+ ecma_value_t buffer = ecma_validate_integer_typedarray (typedarray , false);
8791
88- return ecma_make_uint32_value (0 );
92+ if (ECMA_IS_VALUE_ERROR (buffer ))
93+ {
94+ return buffer ;
95+ }
96+
97+ uint32_t idx = ecma_validate_atomic_access (typedarray , index );
98+
99+ if (idx == ECMA_STRING_NOT_ARRAY_INDEX )
100+ {
101+ return ECMA_VALUE_ERROR ;
102+ }
103+
104+ ecma_object_t * typedarray_p = ecma_get_object_from_value (typedarray );
105+ ecma_typedarray_info_t target_info = ecma_typedarray_get_info (typedarray_p );
106+
107+ if (ECMA_ARRAYBUFFER_LAZY_ALLOC (target_info .array_buffer_p ))
108+ {
109+ return ECMA_VALUE_ERROR ;
110+ }
111+
112+ ecma_typedarray_type_t element_type = target_info .id ;
113+ ecma_value_t expected ;
114+ ecma_value_t replacement ;
115+ ecma_number_t tmp_exp ;
116+ ecma_number_t tmp_rep ;
117+
118+ if (ECMA_TYPEDARRAY_IS_BIGINT_TYPE (element_type ))
119+ {
120+ expected = ecma_bigint_to_bigint (expected_value , false);
121+
122+ if (ECMA_IS_VALUE_ERROR (expected ))
123+ {
124+ return expected ;
125+ }
126+
127+ replacement = ecma_bigint_to_bigint (replacement_value , false);
128+
129+ if (ECMA_IS_VALUE_ERROR (replacement ))
130+ {
131+ ecma_free_value (expected );
132+ return replacement ;
133+ }
134+ }
135+ else if (!ECMA_IS_VALUE_ERROR (ecma_op_to_integer (expected_value , & tmp_exp ))
136+ && !ECMA_IS_VALUE_ERROR (ecma_op_to_integer (replacement_value , & tmp_rep )))
137+ {
138+ expected = ecma_make_number_value (tmp_exp );
139+ replacement = ecma_make_number_value (tmp_rep );
140+ }
141+ else
142+ {
143+ return ECMA_VALUE_ERROR ;
144+ }
145+
146+ uint8_t element_size = target_info .element_size ;
147+ uint32_t offset = target_info .offset ;
148+ uint32_t indexed_position = idx * element_size + offset ;
149+
150+ if (ecma_arraybuffer_is_detached (ecma_get_object_from_value (buffer )))
151+ {
152+ ecma_free_value (expected );
153+ ecma_free_value (replacement );
154+ return ecma_raise_type_error (ECMA_ERR_ARRAYBUFFER_IS_DETACHED );
155+ }
156+
157+ ecma_typedarray_getter_fn_t typedarray_getter_cb = ecma_get_typedarray_getter_fn (element_type );
158+
159+ ecma_object_t * buffer_obj_p = ecma_get_object_from_value (buffer );
160+ lit_utf8_byte_t * pos = ecma_arraybuffer_get_buffer (buffer_obj_p ) + indexed_position ;
161+ ecma_value_t stored_value = typedarray_getter_cb (pos );
162+
163+ // TODO: Handle shared array buffers differently.
164+ if (ecma_op_same_value (stored_value , expected ))
165+ {
166+ ecma_typedarray_setter_fn_t typedarray_setter_cb = ecma_get_typedarray_setter_fn (element_type );
167+ typedarray_setter_cb (ecma_arraybuffer_get_buffer (buffer_obj_p ) + indexed_position , replacement );
168+ }
169+
170+ ecma_free_value (expected );
171+ ecma_free_value (replacement );
172+
173+ return stored_value ;
89174} /* ecma_builtin_atomics_compare_exchange */
90175
91176/**
@@ -117,11 +202,83 @@ ecma_builtin_atomics_store (ecma_value_t typedarray, /**< typedArray argument */
117202 ecma_value_t index , /**< index argument */
118203 ecma_value_t value ) /**< value argument */
119204{
120- JERRY_UNUSED (typedarray );
121- JERRY_UNUSED (index );
122- JERRY_UNUSED (value );
205+ /* 1. */
206+ ecma_value_t buffer = ecma_validate_integer_typedarray (typedarray , false);
123207
124- return ecma_make_uint32_value (0 );
208+ if (ECMA_IS_VALUE_ERROR (buffer ))
209+ {
210+ return buffer ;
211+ }
212+
213+ /* 2. */
214+ uint32_t idx = ecma_validate_atomic_access (typedarray , index );
215+
216+ if (idx == ECMA_STRING_NOT_ARRAY_INDEX )
217+ {
218+ return ECMA_VALUE_ERROR ;
219+ }
220+
221+ ecma_object_t * typedarray_p = ecma_get_object_from_value (typedarray );
222+ ecma_typedarray_info_t target_info = ecma_typedarray_get_info (typedarray_p );
223+
224+ if (ECMA_ARRAYBUFFER_LAZY_ALLOC (target_info .array_buffer_p ))
225+ {
226+ return ECMA_VALUE_ERROR ;
227+ }
228+
229+ uint8_t element_size = target_info .element_size ;
230+
231+ ecma_typedarray_type_t element_type = target_info .id ;
232+
233+ uint32_t offset = target_info .offset ;
234+
235+ uint32_t indexed_position = idx * element_size + offset ;
236+
237+ ecma_typedarray_setter_fn_t typedarray_setter_cb = ecma_get_typedarray_setter_fn (element_type );
238+ ecma_object_t * buffer_obj_p = ecma_get_object_from_value (buffer );
239+
240+ ecma_value_t v ;
241+ if (element_type == ECMA_BIGINT64_ARRAY || element_type == ECMA_BIGUINT64_ARRAY )
242+ {
243+ v = ecma_bigint_to_bigint (value , false);
244+ }
245+ else
246+ {
247+ ecma_number_t num_int ;
248+
249+ v = ecma_op_to_integer (value , & num_int );
250+
251+ if (ECMA_IS_VALUE_ERROR (v ))
252+ {
253+ return v ;
254+ }
255+
256+ if (ecma_number_is_zero (num_int ) && ecma_number_is_negative (num_int ))
257+ {
258+ num_int = (ecma_number_t ) 0 ;
259+ value = ecma_make_number_value ((ecma_number_t ) 0 );
260+ }
261+
262+ v = ecma_make_number_value (num_int );
263+ }
264+
265+ if (ECMA_IS_VALUE_ERROR (v ))
266+ {
267+ return v ;
268+ }
269+
270+ if (ecma_arraybuffer_is_detached (ecma_get_object_from_value (buffer )))
271+ {
272+ ecma_free_value (v );
273+ return ecma_raise_type_error (ECMA_ERR_ARRAYBUFFER_IS_DETACHED );
274+ }
275+
276+ // TODO: Handle shared array buffers differently.
277+ typedarray_setter_cb (ecma_arraybuffer_get_buffer (buffer_obj_p ) + indexed_position , v );
278+
279+ ecma_free_value (v );
280+
281+ return ecma_copy_value (value );
125282} /* ecma_builtin_atomics_store */
126283
127284/**
0 commit comments