13
13
* limitations under the License.
14
14
*/
15
15
16
+ #include "ecma-arraybuffer-object.h"
16
17
#include "ecma-atomics-object.h"
18
+ #include "ecma-bigint.h"
17
19
#include "ecma-builtins.h"
20
+ #include "ecma-errors.h"
21
+ #include "ecma-exceptions.h"
22
+ #include "ecma-gc.h"
18
23
#include "ecma-globals.h"
19
24
#include "ecma-helpers.h"
25
+ #include "ecma-shared-arraybuffer-object.h"
26
+ #include "ecma-typedarray-object.h"
20
27
21
28
#include "jrt.h"
22
29
69
76
/**
70
77
* The Atomics object's 'compareExchange' routine
71
78
*
72
- * See also: ES11 24 .4.4
79
+ * See also: ES12 25 .4.4
73
80
*
74
81
* @return ecma value
75
82
* Returned value must be freed with ecma_free_value.
@@ -80,12 +87,90 @@ ecma_builtin_atomics_compare_exchange (ecma_value_t typedarray, /**< typedArray
80
87
ecma_value_t expected_value , /**< expectedValue argument */
81
88
ecma_value_t replacement_value ) /**< replacementValue argument*/
82
89
{
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);
87
91
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 ;
89
174
} /* ecma_builtin_atomics_compare_exchange */
90
175
91
176
/**
@@ -117,11 +202,83 @@ ecma_builtin_atomics_store (ecma_value_t typedarray, /**< typedArray argument */
117
202
ecma_value_t index , /**< index argument */
118
203
ecma_value_t value ) /**< value argument */
119
204
{
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);
123
207
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 );
125
282
} /* ecma_builtin_atomics_store */
126
283
127
284
/**
0 commit comments