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
+ /**
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
+
69
116
/**
70
117
* The Atomics object's 'compareExchange' routine
71
118
*
72
- * See also: ES11 24 .4.4
119
+ * See also: ES12 25 .4.4
73
120
*
74
121
* @return ecma value
75
122
* Returned value must be freed with ecma_free_value.
@@ -80,12 +127,124 @@ ecma_builtin_atomics_compare_exchange (ecma_value_t typedarray, /**< typedArray
80
127
ecma_value_t expected_value , /**< expectedValue argument */
81
128
ecma_value_t replacement_value ) /**< replacementValue argument*/
82
129
{
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);
87
131
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 ;
89
248
} /* ecma_builtin_atomics_compare_exchange */
90
249
91
250
/**
@@ -117,11 +276,83 @@ ecma_builtin_atomics_store (ecma_value_t typedarray, /**< typedArray argument */
117
276
ecma_value_t index , /**< index argument */
118
277
ecma_value_t value ) /**< value argument */
119
278
{
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);
123
281
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 ;
125
356
} /* ecma_builtin_atomics_store */
126
357
127
358
/**
0 commit comments