@@ -20,9 +20,9 @@ namespace v8 {
2020namespace internal {
2121
2222// See builtins-arraybuffer.cc for implementations of
23- // SharedArrayBuffer.prototye .byteLength and SharedArrayBuffer.prototype.slice
23+ // SharedArrayBuffer.prototype .byteLength and SharedArrayBuffer.prototype.slice
2424
25- // #sec-atomics.islockfree
25+ // https://tc39.es/ecma262/ #sec-atomics.islockfree
2626inline bool AtomicIsLockFree (double size) {
2727 // According to the standard, 1, 2, and 4 byte atomics are supposed to be
2828 // 'lock free' on every platform. 'Lock free' means that all possible uses of
@@ -39,7 +39,7 @@ inline bool AtomicIsLockFree(double size) {
3939 return size == 1 || size == 2 || size == 4 || size == 8 ;
4040}
4141
42- // ES #sec-atomics.islockfree
42+ // https://tc39.es/ecma262/ #sec-atomics.islockfree
4343BUILTIN (AtomicsIsLockFree) {
4444 HandleScope scope (isolate);
4545 Handle<Object> size = args.atOrUndefined (isolate, 1 );
@@ -48,37 +48,45 @@ BUILTIN(AtomicsIsLockFree) {
4848 return *isolate->factory ()->ToBoolean (AtomicIsLockFree (size->Number ()));
4949}
5050
51- // ES #sec-validatesharedintegertypedarray
52- V8_WARN_UNUSED_RESULT MaybeHandle<JSTypedArray> ValidateSharedIntegerTypedArray (
53- Isolate* isolate, Handle<Object> object,
51+ // https://tc39.es/ecma262/ #sec-validatesharedintegertypedarray
52+ V8_WARN_UNUSED_RESULT MaybeHandle<JSTypedArray> ValidateIntegerTypedArray (
53+ Isolate* isolate, Handle<Object> object, const char * method_name,
5454 bool only_int32_and_big_int64 = false ) {
5555 if (object->IsJSTypedArray ()) {
5656 Handle<JSTypedArray> typed_array = Handle<JSTypedArray>::cast (object);
57- if (typed_array->GetBuffer ()->is_shared ()) {
58- if (only_int32_and_big_int64) {
59- if (typed_array->type () == kExternalInt32Array ||
60- typed_array->type () == kExternalBigInt64Array ) {
61- return typed_array;
62- }
63- } else {
64- if (typed_array->type () != kExternalFloat32Array &&
65- typed_array->type () != kExternalFloat64Array &&
66- typed_array->type () != kExternalUint8ClampedArray )
67- return typed_array;
57+
58+ if (typed_array->WasDetached ()) {
59+ THROW_NEW_ERROR (
60+ isolate,
61+ NewTypeError (
62+ MessageTemplate::kDetachedOperation ,
63+ isolate->factory ()->NewStringFromAsciiChecked (method_name)),
64+ JSTypedArray);
65+ }
66+
67+ if (only_int32_and_big_int64) {
68+ if (typed_array->type () == kExternalInt32Array ||
69+ typed_array->type () == kExternalBigInt64Array ) {
70+ return typed_array;
6871 }
72+ } else {
73+ if (typed_array->type () != kExternalFloat32Array &&
74+ typed_array->type () != kExternalFloat64Array &&
75+ typed_array->type () != kExternalUint8ClampedArray )
76+ return typed_array;
6977 }
7078 }
7179
7280 THROW_NEW_ERROR (
7381 isolate,
7482 NewTypeError (only_int32_and_big_int64
75- ? MessageTemplate::kNotInt32OrBigInt64SharedTypedArray
76- : MessageTemplate::kNotIntegerSharedTypedArray ,
83+ ? MessageTemplate::kNotInt32OrBigInt64TypedArray
84+ : MessageTemplate::kNotIntegerTypedArray ,
7785 object),
7886 JSTypedArray);
7987}
8088
81- // ES #sec-validateatomicaccess
89+ // https://tc39.es/ecma262/ #sec-validateatomicaccess
8290// ValidateAtomicAccess( typedArray, requestIndex )
8391V8_WARN_UNUSED_RESULT Maybe<size_t > ValidateAtomicAccess (
8492 Isolate* isolate, Handle<JSTypedArray> typed_array,
@@ -91,8 +99,9 @@ V8_WARN_UNUSED_RESULT Maybe<size_t> ValidateAtomicAccess(
9199 Nothing<size_t >());
92100
93101 size_t access_index;
102+ size_t typed_array_length = typed_array->length ();
94103 if (!TryNumberToSize (*access_index_obj, &access_index) ||
95- typed_array-> WasDetached () || access_index >= typed_array-> length () ) {
104+ access_index >= typed_array_length ) {
96105 isolate->Throw (*isolate->factory ()->NewRangeError (
97106 MessageTemplate::kInvalidAtomicAccessIndex ));
98107 return Nothing<size_t >();
@@ -122,12 +131,18 @@ BUILTIN(AtomicsNotify) {
122131
123132 Handle<JSTypedArray> sta;
124133 ASSIGN_RETURN_FAILURE_ON_EXCEPTION (
125- isolate, sta, ValidateSharedIntegerTypedArray (isolate, array, true ));
134+ isolate, sta,
135+ ValidateIntegerTypedArray (isolate, array, " Atomics.notify" , true ));
126136
137+ // 2. Let i be ? ValidateAtomicAccess(typedArray, index).
127138 Maybe<size_t > maybe_index = ValidateAtomicAccess (isolate, sta, index);
128139 if (maybe_index.IsNothing ()) return ReadOnlyRoots (isolate).exception ();
129140 size_t i = maybe_index.FromJust ();
130141
142+ // 3. If count is undefined, let c be +∞.
143+ // 4. Else,
144+ // a. Let intCount be ? ToInteger(count).
145+ // b. Let c be max(intCount, 0).
131146 uint32_t c;
132147 if (count->IsUndefined (isolate)) {
133148 c = kMaxUInt32 ;
@@ -143,9 +158,17 @@ BUILTIN(AtomicsNotify) {
143158 c = static_cast <uint32_t >(count_double);
144159 }
145160
161+ // Steps 5-9 performed in FutexEmulation::Wake.
162+
163+ // 10. If IsSharedArrayBuffer(buffer) is false, return 0.
146164 Handle<JSArrayBuffer> array_buffer = sta->GetBuffer ();
147165 size_t wake_addr;
148166
167+ if (V8_UNLIKELY (!sta->GetBuffer ()->is_shared ())) {
168+ return Smi::FromInt (0 );
169+ }
170+
171+ // Steps 11-17 performed in FutexEmulation::Wake.
149172 if (sta->type () == kExternalBigInt64Array ) {
150173 wake_addr = GetAddress64 (i, sta->byte_offset ());
151174 } else {
@@ -158,19 +181,26 @@ BUILTIN(AtomicsNotify) {
158181Object DoWait (Isolate* isolate, FutexEmulation::WaitMode mode,
159182 Handle<Object> array, Handle<Object> index, Handle<Object> value,
160183 Handle<Object> timeout) {
161- // 1. Let buffer be ? ValidateSharedIntegerTypedArray (typedArray, true).
184+ // 1. Let buffer be ? ValidateIntegerTypedArray (typedArray, true).
162185 Handle<JSTypedArray> sta;
163186 ASSIGN_RETURN_FAILURE_ON_EXCEPTION (
164- isolate, sta, ValidateSharedIntegerTypedArray (isolate, array, true ));
187+ isolate, sta,
188+ ValidateIntegerTypedArray (isolate, array, " Atomics.wait" , true ));
165189
166- // 2. Let i be ? ValidateAtomicAccess(typedArray, index).
190+ // 2. If IsSharedArrayBuffer(buffer) is false, throw a TypeError exception.
191+ if (V8_UNLIKELY (!sta->GetBuffer ()->is_shared ())) {
192+ THROW_NEW_ERROR_RETURN_FAILURE (
193+ isolate, NewTypeError (MessageTemplate::kNotSharedTypedArray , array));
194+ }
195+
196+ // 3. Let i be ? ValidateAtomicAccess(typedArray, index).
167197 Maybe<size_t > maybe_index = ValidateAtomicAccess (isolate, sta, index);
168198 if (maybe_index.IsNothing ()) return ReadOnlyRoots (isolate).exception ();
169199 size_t i = maybe_index.FromJust ();
170200
171- // 3 . Let arrayTypeName be typedArray.[[TypedArrayName]].
172- // 4 . If arrayTypeName is "BigInt64Array", let v be ? ToBigInt64(value).
173- // 5 . Otherwise, let v be ? ToInt32(value).
201+ // 4 . Let arrayTypeName be typedArray.[[TypedArrayName]].
202+ // 5 . If arrayTypeName is "BigInt64Array", let v be ? ToBigInt64(value).
203+ // 6 . Otherwise, let v be ? ToInt32(value).
174204 if (sta->type () == kExternalBigInt64Array ) {
175205 ASSIGN_RETURN_FAILURE_ON_EXCEPTION (isolate, value,
176206 BigInt::FromObject (isolate, value));
@@ -180,8 +210,8 @@ Object DoWait(Isolate* isolate, FutexEmulation::WaitMode mode,
180210 Object::ToInt32 (isolate, value));
181211 }
182212
183- // 6 . Let q be ? ToNumber(timeout).
184- // 7 . If q is NaN, let t be +∞, else let t be max(q, 0).
213+ // 7 . Let q be ? ToNumber(timeout).
214+ // 8 . If q is NaN, let t be +∞, else let t be max(q, 0).
185215 double timeout_number;
186216 if (timeout->IsUndefined (isolate)) {
187217 timeout_number = ReadOnlyRoots (isolate).infinity_value ().Number ();
@@ -195,7 +225,7 @@ Object DoWait(Isolate* isolate, FutexEmulation::WaitMode mode,
195225 timeout_number = 0 ;
196226 }
197227
198- // 8 . If mode is sync, then
228+ // 9 . If mode is sync, then
199229 // a. Let B be AgentCanSuspend().
200230 // b. If B is false, throw a TypeError exception.
201231 if (mode == FutexEmulation::WaitMode::kSync &&
@@ -218,7 +248,7 @@ Object DoWait(Isolate* isolate, FutexEmulation::WaitMode mode,
218248 }
219249}
220250
221- // ES #sec-atomics.wait
251+ // https://tc39.es/ecma262/ #sec-atomics.wait
222252// Atomics.wait( typedArray, index, value, timeout )
223253BUILTIN (AtomicsWait) {
224254 HandleScope scope (isolate);
0 commit comments