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
66
73
* @{
67
74
*/
68
75
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
+
69
112
/**
70
113
* The Atomics object's 'compareExchange' routine
71
114
*
72
- * See also: ES11 24 .4.4
115
+ * See also: ES12 25 .4.4
73
116
*
74
117
* @return ecma value
75
118
* Returned value must be freed with ecma_free_value.
@@ -80,12 +123,122 @@ ecma_builtin_atomics_compare_exchange (ecma_value_t typedarray, /**< typedArray
80
123
ecma_value_t expected_value , /**< expectedValue argument */
81
124
ecma_value_t replacement_value ) /**< replacementValue argument*/
82
125
{
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);
87
127
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 ;
89
242
} /* ecma_builtin_atomics_compare_exchange */
90
243
91
244
/**
@@ -117,11 +270,80 @@ ecma_builtin_atomics_store (ecma_value_t typedarray, /**< typedArray argument */
117
270
ecma_value_t index , /**< index argument */
118
271
ecma_value_t value ) /**< value argument */
119
272
{
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);
123
275
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 ;
125
347
} /* ecma_builtin_atomics_store */
126
348
127
349
/**
0 commit comments