Changeset 272341 in webkit
- Timestamp:
- Feb 3, 2021 3:07:41 PM (18 months ago)
- Location:
- trunk
- Files:
-
- 5 added
- 8 edited
-
JSTests/ChangeLog (modified) (1 diff)
-
JSTests/stress/atomic-increment-bigint64.js (added)
-
JSTests/stress/bigint-atomics-fail.js (added)
-
JSTests/stress/bigint64-atomics.js (added)
-
JSTests/stress/biguint64-atomics.js (added)
-
JSTests/stress/isLockFree.js (modified) (3 diffs)
-
JSTests/stress/shared-array-buffer-bigint.js (added)
-
JSTests/test262/config.yaml (modified) (1 diff)
-
Source/JavaScriptCore/ChangeLog (modified) (1 diff)
-
Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (modified) (1 diff)
-
Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/AtomicsObject.cpp (modified) (31 diffs)
-
Source/JavaScriptCore/runtime/ToNativeFromValue.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r272243 r272341 1 2021-02-01 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] Atomics should support BigInt64Array / BigUint64Array 4 https://bugs.webkit.org/show_bug.cgi?id=221245 5 6 Reviewed by Keith Miller. 7 8 * stress/atomic-increment-bigint64.js: Added. 9 (shouldBe): 10 (i.agent.start.262.agent.receiveBroadcast): 11 * stress/bigint-atomics-fail.js: Added. 12 (shouldThrow): 13 * stress/bigint64-atomics.js: Added. 14 (shouldBe): 15 (test): 16 * stress/biguint64-atomics.js: Added. 17 (shouldBe): 18 (test): 19 * stress/isLockFree.js: 20 (foo6): 21 (foo7): 22 (foo8): 23 (foo9): 24 * stress/shared-array-buffer-bigint.js: Added. 25 (shouldFail): 26 (shouldSucceed): 27 (runAtomic): 28 * test262/config.yaml: 29 1 30 2021-02-02 Ross Kirsling <ross.kirsling@sony.com> 2 31 -
trunk/JSTests/stress/isLockFree.js
r227104 r272341 36 36 noInline(foo5); 37 37 38 function foo6(bytes) { 39 return Atomics.isLockFree(6); 40 } 41 noInline(foo6); 42 43 function foo7(bytes) { 44 return Atomics.isLockFree(7); 45 } 46 noInline(foo7); 47 48 function foo8(bytes) { 49 return Atomics.isLockFree(8); 50 } 51 noInline(foo8); 52 53 function foo9(bytes) { 54 return Atomics.isLockFree(9); 55 } 56 noInline(foo9); 57 38 58 for (var i = 0; i < 10000; ++i) { 39 59 var result = foo(0); … … 53 73 throw new Error("Bad result: " + result); 54 74 var result = foo(5); 75 if (result !== false) 76 throw new Error("Bad result: " + result); 77 var result = foo(6); 78 if (result !== false) 79 throw new Error("Bad result: " + result); 80 var result = foo(7); 81 if (result !== false) 82 throw new Error("Bad result: " + result); 83 var result = foo(8); 84 if (result !== true) 85 throw new Error("Bad result: " + result); 86 var result = foo(9); 55 87 if (result !== false) 56 88 throw new Error("Bad result: " + result); … … 73 105 if (result !== false) 74 106 throw new Error("Bad result: " + result); 107 var result = foo6(); 108 if (result !== false) 109 throw new Error("Bad result: " + result); 110 var result = foo7(); 111 if (result !== false) 112 throw new Error("Bad result: " + result); 113 var result = foo8(); 114 if (result !== true) 115 throw new Error("Bad result: " + result); 116 var result = foo9(); 117 if (result !== false) 118 throw new Error("Bad result: " + result); 75 119 } -
trunk/JSTests/test262/config.yaml
r272170 r272341 29 29 - Intl.ListFormat 30 30 paths: 31 - test/built-ins/Atomics/add/bigint32 - test/built-ins/Atomics/and/bigint33 - test/built-ins/Atomics/compareExchange/bigint34 - test/built-ins/Atomics/exchange/bigint35 - test/built-ins/Atomics/isLockFree/bigint36 - test/built-ins/Atomics/load/bigint37 - test/built-ins/Atomics/notify/bigint38 - test/built-ins/Atomics/or/bigint39 - test/built-ins/Atomics/store/bigint40 - test/built-ins/Atomics/sub/bigint41 - test/built-ins/Atomics/wait/bigint42 - test/built-ins/Atomics/xor/bigint43 44 31 # test262 bot is using Catalina's ICU 64, upgrading to Big Sur is required 45 32 # https://bugs.webkit.org/show_bug.cgi?id=218844 -
trunk/Source/JavaScriptCore/ChangeLog
r272330 r272341 1 2021-02-01 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] Atomics should support BigInt64Array / BigUint64Array 4 https://bugs.webkit.org/show_bug.cgi?id=221245 5 6 Reviewed by Keith Miller. 7 8 This patch adds BigInt64Array / BigUint64Array support for Atomics. 9 10 1. Atomics.store should be rewritten since it returns non-type-coerced result, so we cannot use atomicReadModifyWrite. 11 The spec also describes Atomics.store without using AtomicReadModifyWrite[1]. 12 2. Extend Atomics.isLockFree to also accept a size of 8. 13 3. Currently, DFG / FTL handle Atomics + BigInt64Array/BigUint64Array as Array::Generic. 14 15 [1]: https://tc39.es/ecma262/#sec-atomics.store 16 17 * dfg/DFGSpeculativeJIT64.cpp: 18 (JSC::DFG::SpeculativeJIT::compile): 19 * ftl/FTLLowerDFGToB3.cpp: 20 (JSC::FTL::DFG::LowerDFGToB3::compileAtomicsIsLockFree): 21 * runtime/AtomicsObject.cpp: 22 (JSC::JSC_DEFINE_HOST_FUNCTION): 23 (JSC::atomicsWaitImpl): 24 (JSC::JSC_DEFINE_JIT_OPERATION): 25 * runtime/ToNativeFromValue.h: 26 (JSC::toNativeFromValue): 27 1 28 2021-02-03 Yusuke Suzuki <ysuzuki@apple.com> 2 29 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r272170 r272341 3456 3456 m_jit.move(TrustedImm32(JSValue::ValueTrue), resultGPR); 3457 3457 JITCompiler::JumpList done; 3458 done.append(m_jit.branch32(JITCompiler::Equal, operandGPR, TrustedImm32(8))); 3458 3459 done.append(m_jit.branch32(JITCompiler::Equal, operandGPR, TrustedImm32(4))); 3459 3460 done.append(m_jit.branch32(JITCompiler::Equal, operandGPR, TrustedImm32(1))); -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
r272170 r272341 4296 4296 LBasicBlock lastNext = m_out.insertNewBlocksBefore(trueCase); 4297 4297 4298 Vector<SwitchCase > cases;4298 Vector<SwitchCase, 4> cases; 4299 4299 cases.append(SwitchCase(m_out.constInt32(1), trueCase, Weight())); 4300 4300 cases.append(SwitchCase(m_out.constInt32(2), trueCase, Weight())); 4301 4301 cases.append(SwitchCase(m_out.constInt32(4), trueCase, Weight())); 4302 cases.append(SwitchCase(m_out.constInt32(8), trueCase, Weight())); 4302 4303 m_out.switchInstruction(bytes, cases, falseCase, Weight()); 4303 4304 -
trunk/Source/JavaScriptCore/runtime/AtomicsObject.cpp
r272170 r272341 91 91 92 92 template<typename Adaptor, typename Func> 93 EncodedJSValue atomicReadModifyWriteCase(JSGlobalObject* globalObject, const JSValue* args, ThrowScope& scope, JSArrayBufferView* typedArrayView, unsigned accessIndex, const Func& func) 94 { 93 EncodedJSValue atomicReadModifyWriteCase(JSGlobalObject* globalObject, VM& vm, const JSValue* args, JSArrayBufferView* typedArrayView, unsigned accessIndex, const Func& func) 94 { 95 auto scope = DECLARE_THROW_SCOPE(vm); 96 95 97 JSGenericTypedArrayView<Adaptor>* typedArray = jsCast<JSGenericTypedArrayView<Adaptor>*>(typedArrayView); 96 98 97 double extraArgs[Func::numExtraArgs + 1]; // Add 1 to avoid 0 size array error in VS.99 typename Adaptor::Type extraArgs[Func::numExtraArgs + 1]; // Add 1 to avoid 0 size array error in VS. 98 100 for (unsigned i = 0; i < Func::numExtraArgs; ++i) { 99 double value = args[2 + i].toIntegerOrInfinity(globalObject);100 RETURN_IF_EXCEPTION(scope, JSValue::encode(jsUndefined()));101 auto value = toNativeFromValue<Adaptor>(globalObject, args[2 + i]); 102 RETURN_IF_EXCEPTION(scope, { }); 101 103 extraArgs[i] = value; 102 104 } … … 105 107 return throwVMTypeError(globalObject, scope, typedArrayBufferHasBeenDetachedErrorMessage); 106 108 107 return JSValue::encode(func(typedArray->typedVector() + accessIndex, extraArgs)); 108 } 109 110 static unsigned validateAtomicAccess(VM& vm, JSGlobalObject* globalObject, JSArrayBufferView* typedArrayView, JSValue accessIndexValue) 109 auto result = func(typedArray->typedVector() + accessIndex, extraArgs); 110 RELEASE_AND_RETURN(scope, JSValue::encode(Adaptor::toJSValue(globalObject, result))); 111 } 112 113 static unsigned validateAtomicAccess(JSGlobalObject* globalObject, VM& vm, JSArrayBufferView* typedArrayView, JSValue accessIndexValue) 111 114 { 112 115 auto scope = DECLARE_THROW_SCOPE(vm); … … 128 131 } 129 132 130 enum class TypedArrayOperationMode { Read , Write};133 enum class TypedArrayOperationMode { ReadWrite, Wait }; 131 134 template<TypedArrayOperationMode mode> 132 135 inline JSArrayBufferView* validateIntegerTypedArray(JSGlobalObject* globalObject, JSValue typedArrayValue) … … 138 141 RETURN_IF_EXCEPTION(scope, { }); 139 142 140 if constexpr (mode == TypedArrayOperationMode::W rite) {143 if constexpr (mode == TypedArrayOperationMode::Wait) { 141 144 switch (typedArray->type()) { 142 145 case Int32ArrayType: 146 case BigInt64ArrayType: 143 147 break; 144 148 default: 145 throwTypeError(globalObject, scope, "Typed array argument must be an Int32Array ."_s);149 throwTypeError(globalObject, scope, "Typed array argument must be an Int32Array or BigInt64Array."_s); 146 150 return { }; 147 151 } … … 154 158 case Uint16ArrayType: 155 159 case Uint32ArrayType: 160 case BigInt64ArrayType: 161 case BigUint64ArrayType: 156 162 break; 157 163 default: 158 throwTypeError(globalObject, scope, "Typed array argument must be an Int8Array, Int16Array, Int32Array, Uint8Array, Uint16Array, or Uint32Array."_s);164 throwTypeError(globalObject, scope, "Typed array argument must be an Int8Array, Int16Array, Int32Array, Uint8Array, Uint16Array, Uint32Array, BigInt64Array, or BigUint64Array."_s); 159 165 return { }; 160 166 } … … 164 170 165 171 template<typename Func> 166 EncodedJSValue atomicReadModifyWrite(VM& vm, JSGlobalObject* globalObject, const JSValue* args, const Func& func) 167 { 168 auto scope = DECLARE_THROW_SCOPE(vm); 169 170 JSArrayBufferView* typedArrayView = validateIntegerTypedArray<TypedArrayOperationMode::Read>(globalObject, args[0]); 171 RETURN_IF_EXCEPTION(scope, { }); 172 173 unsigned accessIndex = validateAtomicAccess(vm, globalObject, typedArrayView, args[1]); 174 RETURN_IF_EXCEPTION(scope, { }); 175 172 EncodedJSValue atomicReadModifyWrite(JSGlobalObject* globalObject, VM& vm, const JSValue* args, const Func& func) 173 { 174 auto scope = DECLARE_THROW_SCOPE(vm); 175 176 JSArrayBufferView* typedArrayView = validateIntegerTypedArray<TypedArrayOperationMode::ReadWrite>(globalObject, args[0]); 177 RETURN_IF_EXCEPTION(scope, { }); 178 179 unsigned accessIndex = validateAtomicAccess(globalObject, vm, typedArrayView, args[1]); 180 RETURN_IF_EXCEPTION(scope, { }); 181 182 scope.release(); 176 183 switch (typedArrayView->type()) { 177 184 case Int8ArrayType: 178 return atomicReadModifyWriteCase<Int8Adaptor>(globalObject, args, scope, typedArrayView, accessIndex, func);185 return atomicReadModifyWriteCase<Int8Adaptor>(globalObject, vm, args, typedArrayView, accessIndex, func); 179 186 case Int16ArrayType: 180 return atomicReadModifyWriteCase<Int16Adaptor>(globalObject, args, scope, typedArrayView, accessIndex, func);187 return atomicReadModifyWriteCase<Int16Adaptor>(globalObject, vm, args, typedArrayView, accessIndex, func); 181 188 case Int32ArrayType: 182 return atomicReadModifyWriteCase<Int32Adaptor>(globalObject, args, scope, typedArrayView, accessIndex, func);189 return atomicReadModifyWriteCase<Int32Adaptor>(globalObject, vm, args, typedArrayView, accessIndex, func); 183 190 case Uint8ArrayType: 184 return atomicReadModifyWriteCase<Uint8Adaptor>(globalObject, args, scope, typedArrayView, accessIndex, func);191 return atomicReadModifyWriteCase<Uint8Adaptor>(globalObject, vm, args, typedArrayView, accessIndex, func); 185 192 case Uint16ArrayType: 186 return atomicReadModifyWriteCase<Uint16Adaptor>(globalObject, args, scope, typedArrayView, accessIndex, func);193 return atomicReadModifyWriteCase<Uint16Adaptor>(globalObject, vm, args, typedArrayView, accessIndex, func); 187 194 case Uint32ArrayType: 188 return atomicReadModifyWriteCase<Uint32Adaptor>(globalObject, args, scope, typedArrayView, accessIndex, func); 195 return atomicReadModifyWriteCase<Uint32Adaptor>(globalObject, vm, args, typedArrayView, accessIndex, func); 196 case BigInt64ArrayType: 197 return atomicReadModifyWriteCase<BigInt64Adaptor>(globalObject, vm, args, typedArrayView, accessIndex, func); 198 case BigUint64ArrayType: 199 return atomicReadModifyWriteCase<BigUint64Adaptor>(globalObject, vm, args, typedArrayView, accessIndex, func); 189 200 default: 190 201 RELEASE_ASSERT_NOT_REACHED(); … … 199 210 for (unsigned i = 2 + Func::numExtraArgs; i--;) 200 211 args[i] = callFrame->argument(i); 201 return atomicReadModifyWrite(globalObject ->vm(), globalObject, args, func);212 return atomicReadModifyWrite(globalObject, globalObject->vm(), args, func); 202 213 } 203 214 … … 206 217 207 218 template<typename T> 208 JSValue operator()(T* ptr, const double* args) const209 { 210 return jsNumber(WTF::atomicExchangeAdd(ptr, toInt32(args[0])));219 T operator()(T* ptr, const T* args) const 220 { 221 return WTF::atomicExchangeAdd(ptr, args[0]); 211 222 } 212 223 }; … … 216 227 217 228 template<typename T> 218 JSValue operator()(T* ptr, const double* args) const219 { 220 return jsNumber(WTF::atomicExchangeAnd(ptr, toInt32(args[0])));229 T operator()(T* ptr, const T* args) const 230 { 231 return WTF::atomicExchangeAnd(ptr, args[0]); 221 232 } 222 233 }; … … 226 237 227 238 template<typename T> 228 JSValue operator()(T* ptr, const double* args) const229 { 230 T expected = static_cast<T>(toInt32(args[0]));231 T newValue = static_cast<T>(toInt32(args[1]));232 return jsNumber(WTF::atomicCompareExchangeStrong(ptr, expected, newValue));239 T operator()(T* ptr, const T* args) const 240 { 241 T expected = args[0]; 242 T newValue = args[1]; 243 return WTF::atomicCompareExchangeStrong(ptr, expected, newValue); 233 244 } 234 245 }; … … 238 249 239 250 template<typename T> 240 JSValue operator()(T* ptr, const double* args) const241 { 242 return jsNumber(WTF::atomicExchange(ptr, static_cast<T>(toInt32(args[0]))));251 T operator()(T* ptr, const T* args) const 252 { 253 return WTF::atomicExchange(ptr, args[0]); 243 254 } 244 255 }; … … 248 259 249 260 template<typename T> 250 JSValue operator()(T* ptr, const double*) const251 { 252 return jsNumber(WTF::atomicLoadFullyFenced(ptr));261 T operator()(T* ptr, const T*) const 262 { 263 return WTF::atomicLoadFullyFenced(ptr); 253 264 } 254 265 }; … … 258 269 259 270 template<typename T> 260 JSValue operator()(T* ptr, const double* args) const 261 { 262 return jsNumber(WTF::atomicExchangeOr(ptr, toInt32(args[0]))); 263 } 264 }; 265 266 struct StoreFunc { 267 static constexpr unsigned numExtraArgs = 1; 268 269 template<typename T> 270 JSValue operator()(T* ptr, const double* args) const 271 { 272 double valueAsInt = args[0]; 273 T valueAsT = static_cast<T>(toInt32(valueAsInt)); 274 WTF::atomicStoreFullyFenced(ptr, valueAsT); 275 return jsNumber(valueAsInt); 271 T operator()(T* ptr, const T* args) const 272 { 273 return WTF::atomicExchangeOr(ptr, args[0]); 276 274 } 277 275 }; … … 281 279 282 280 template<typename T> 283 JSValue operator()(T* ptr, const double* args) const284 { 285 return jsNumber(WTF::atomicExchangeSub(ptr, toInt32(args[0])));281 T operator()(T* ptr, const T* args) const 282 { 283 return WTF::atomicExchangeSub(ptr, args[0]); 286 284 } 287 285 }; … … 291 289 292 290 template<typename T> 293 JSValue operator()(T* ptr, const double* args) const294 { 295 return jsNumber(WTF::atomicExchangeXor(ptr, toInt32(args[0])));291 T operator()(T* ptr, const T* args) const 292 { 293 return WTF::atomicExchangeXor(ptr, args[0]); 296 294 } 297 295 }; … … 310 308 case 2: 311 309 case 4: 310 case 8: 312 311 result = true; 313 312 break; … … 319 318 } 320 319 320 template<typename Adaptor> 321 EncodedJSValue atomicStoreCase(JSGlobalObject* globalObject, VM& vm, JSValue operand, JSArrayBufferView* typedArrayView, unsigned accessIndex) 322 { 323 auto scope = DECLARE_THROW_SCOPE(vm); 324 325 JSGenericTypedArrayView<Adaptor>* typedArray = jsCast<JSGenericTypedArrayView<Adaptor>*>(typedArrayView); 326 327 typename Adaptor::Type extraArg; 328 JSValue value; 329 if constexpr (std::is_same_v<Adaptor, BigInt64Adaptor> || std::is_same_v<Adaptor, BigUint64Adaptor>) { 330 value = operand.toBigInt(globalObject); 331 RETURN_IF_EXCEPTION(scope, { }); 332 extraArg = toNativeFromValue<Adaptor>(globalObject, value); 333 RETURN_IF_EXCEPTION(scope, { }); 334 } else { 335 value = jsNumber(operand.toIntegerOrInfinity(globalObject)); 336 RETURN_IF_EXCEPTION(scope, { }); 337 extraArg = toNativeFromValue<Adaptor>(globalObject, value); 338 RETURN_IF_EXCEPTION(scope, { }); 339 } 340 341 if (typedArray->isDetached()) 342 return throwVMTypeError(globalObject, scope, typedArrayBufferHasBeenDetachedErrorMessage); 343 344 WTF::atomicStoreFullyFenced(typedArray->typedVector() + accessIndex, extraArg); 345 RELEASE_AND_RETURN(scope, JSValue::encode(value)); 346 } 347 348 EncodedJSValue atomicStore(JSGlobalObject* globalObject, VM& vm, JSValue base, JSValue index, JSValue operand) 349 { 350 // https://tc39.es/ecma262/#sec-atomics.store 351 352 auto scope = DECLARE_THROW_SCOPE(vm); 353 354 JSArrayBufferView* typedArrayView = validateIntegerTypedArray<TypedArrayOperationMode::ReadWrite>(globalObject, base); 355 RETURN_IF_EXCEPTION(scope, { }); 356 357 unsigned accessIndex = validateAtomicAccess(globalObject, vm, typedArrayView, index); 358 RETURN_IF_EXCEPTION(scope, { }); 359 360 scope.release(); 361 switch (typedArrayView->type()) { 362 case Int8ArrayType: 363 return atomicStoreCase<Int8Adaptor>(globalObject, vm, operand, typedArrayView, accessIndex); 364 case Int16ArrayType: 365 return atomicStoreCase<Int16Adaptor>(globalObject, vm, operand, typedArrayView, accessIndex); 366 case Int32ArrayType: 367 return atomicStoreCase<Int32Adaptor>(globalObject, vm, operand, typedArrayView, accessIndex); 368 case Uint8ArrayType: 369 return atomicStoreCase<Uint8Adaptor>(globalObject, vm, operand, typedArrayView, accessIndex); 370 case Uint16ArrayType: 371 return atomicStoreCase<Uint16Adaptor>(globalObject, vm, operand, typedArrayView, accessIndex); 372 case Uint32ArrayType: 373 return atomicStoreCase<Uint32Adaptor>(globalObject, vm, operand, typedArrayView, accessIndex); 374 case BigInt64ArrayType: 375 return atomicStoreCase<BigInt64Adaptor>(globalObject, vm, operand, typedArrayView, accessIndex); 376 case BigUint64ArrayType: 377 return atomicStoreCase<BigUint64Adaptor>(globalObject, vm, operand, typedArrayView, accessIndex); 378 default: 379 RELEASE_ASSERT_NOT_REACHED(); 380 return { }; 381 } 382 } 383 321 384 } // anonymous namespace 322 385 … … 358 421 JSC_DEFINE_HOST_FUNCTION(atomicsFuncStore, (JSGlobalObject* globalObject, CallFrame* callFrame)) 359 422 { 360 return atomic ReadModifyWrite(globalObject, callFrame, StoreFunc());423 return atomicStore(globalObject, globalObject->vm(), callFrame->argument(0), callFrame->argument(1), callFrame->argument(2)); 361 424 } 362 425 … … 366 429 } 367 430 368 JSC_DEFINE_HOST_FUNCTION(atomicsFuncWait, (JSGlobalObject* globalObject, CallFrame* callFrame)) 369 { 370 VM& vm = globalObject->vm(); 371 auto scope = DECLARE_THROW_SCOPE(vm); 372 373 auto* typedArrayBuffer = validateIntegerTypedArray<TypedArrayOperationMode::Write>(globalObject, callFrame->argument(0)); 374 RETURN_IF_EXCEPTION(scope, { }); 375 auto* typedArray = jsCast<JSInt32Array*>(typedArrayBuffer); 376 377 if (!typedArray->isShared()) { 378 throwTypeError(globalObject, scope, "Typed array for wait/notify must wrap a SharedArrayBuffer."_s); 379 return JSValue::encode(jsUndefined()); 380 } 381 382 unsigned accessIndex = validateAtomicAccess(vm, globalObject, typedArray, callFrame->argument(1)); 383 RETURN_IF_EXCEPTION(scope, { }); 384 385 int32_t* ptr = typedArray->typedVector() + accessIndex; 386 387 int32_t expectedValue = callFrame->argument(2).toInt32(globalObject); 388 RETURN_IF_EXCEPTION(scope, JSValue::encode(jsUndefined())); 389 390 double timeoutInMilliseconds = callFrame->argument(3).toNumber(globalObject); 391 RETURN_IF_EXCEPTION(scope, JSValue::encode(jsUndefined())); 431 template<typename ValueType, typename JSArrayType> 432 JSValue atomicsWaitImpl(JSGlobalObject* globalObject, JSArrayType* typedArray, unsigned accessIndex, ValueType expectedValue, JSValue timeoutValue) 433 { 434 VM& vm = globalObject->vm(); 435 auto scope = DECLARE_THROW_SCOPE(vm); 436 437 ValueType* ptr = typedArray->typedVector() + accessIndex; 438 439 double timeoutInMilliseconds = timeoutValue.toNumber(globalObject); 440 RETURN_IF_EXCEPTION(scope, { }); 392 441 Seconds timeout = Seconds::infinity(); 393 442 if (!std::isnan(timeoutInMilliseconds)) … … 396 445 if (!vm.m_typedArrayController->isAtomicsWaitAllowedOnCurrentThread()) { 397 446 throwTypeError(globalObject, scope, "Atomics.wait cannot be called from the current thread."_s); 398 return JSValue::encode(jsUndefined());447 return { }; 399 448 } 400 449 … … 413 462 } 414 463 if (!didPassValidation) 415 return JSValue::encode(vm.smallStrings.notEqualString());464 return vm.smallStrings.notEqualString(); 416 465 if (!result.wasUnparked) 417 return JSValue::encode(vm.smallStrings.timedOutString()); 418 return JSValue::encode(vm.smallStrings.okString()); 466 return vm.smallStrings.timedOutString(); 467 return vm.smallStrings.okString(); 468 } 469 470 JSC_DEFINE_HOST_FUNCTION(atomicsFuncWait, (JSGlobalObject* globalObject, CallFrame* callFrame)) 471 { 472 VM& vm = globalObject->vm(); 473 auto scope = DECLARE_THROW_SCOPE(vm); 474 475 auto* typedArrayView = validateIntegerTypedArray<TypedArrayOperationMode::Wait>(globalObject, callFrame->argument(0)); 476 RETURN_IF_EXCEPTION(scope, { }); 477 478 if (!typedArrayView->isShared()) 479 return throwVMTypeError(globalObject, scope, "Typed array for wait/notify must wrap a SharedArrayBuffer."_s); 480 481 unsigned accessIndex = validateAtomicAccess(globalObject, vm, typedArrayView, callFrame->argument(1)); 482 RETURN_IF_EXCEPTION(scope, { }); 483 484 switch (typedArrayView->type()) { 485 case Int32ArrayType: { 486 int32_t expectedValue = callFrame->argument(2).toInt32(globalObject); 487 RETURN_IF_EXCEPTION(scope, { }); 488 RELEASE_AND_RETURN(scope, JSValue::encode(atomicsWaitImpl<int32_t>(globalObject, jsCast<JSInt32Array*>(typedArrayView), accessIndex, expectedValue, callFrame->argument(3)))); 489 } 490 case BigInt64ArrayType: { 491 int64_t expectedValue = callFrame->argument(2).toBigInt64(globalObject); 492 RETURN_IF_EXCEPTION(scope, { }); 493 RELEASE_AND_RETURN(scope, JSValue::encode(atomicsWaitImpl<int64_t>(globalObject, jsCast<JSBigInt64Array*>(typedArrayView), accessIndex, expectedValue, callFrame->argument(3)))); 494 } 495 default: 496 RELEASE_ASSERT_NOT_REACHED(); 497 break; 498 } 499 return { }; 419 500 } 420 501 … … 424 505 auto scope = DECLARE_THROW_SCOPE(vm); 425 506 426 auto* typedArrayBuffer = validateIntegerTypedArray<TypedArrayOperationMode::Write>(globalObject, callFrame->argument(0)); 427 RETURN_IF_EXCEPTION(scope, { }); 428 auto* typedArray = jsCast<JSInt32Array*>(typedArrayBuffer); 429 430 unsigned accessIndex = validateAtomicAccess(vm, globalObject, typedArray, callFrame->argument(1)); 507 auto* typedArrayView = validateIntegerTypedArray<TypedArrayOperationMode::Wait>(globalObject, callFrame->argument(0)); 508 RETURN_IF_EXCEPTION(scope, { }); 509 510 unsigned accessIndex = validateAtomicAccess(globalObject, vm, typedArrayView, callFrame->argument(1)); 431 511 RETURN_IF_EXCEPTION(scope, { }); 432 512 … … 441 521 } 442 522 443 if (!typedArray ->isShared())523 if (!typedArrayView->isShared()) 444 524 return JSValue::encode(jsNumber(0)); 445 525 446 int32_t* ptr = typedArray->typedVector() + accessIndex; 447 return JSValue::encode(jsNumber(ParkingLot::unparkCount(ptr, count))); 526 switch (typedArrayView->type()) { 527 case Int32ArrayType: { 528 int32_t* ptr = jsCast<JSInt32Array*>(typedArrayView)->typedVector() + accessIndex; 529 return JSValue::encode(jsNumber(ParkingLot::unparkCount(ptr, count))); 530 } 531 case BigInt64ArrayType: { 532 int64_t* ptr = jsCast<JSBigInt64Array*>(typedArrayView)->typedVector() + accessIndex; 533 return JSValue::encode(jsNumber(ParkingLot::unparkCount(ptr, count))); 534 } 535 default: 536 RELEASE_ASSERT_NOT_REACHED(); 537 break; 538 } 539 return { }; 448 540 } 449 541 … … 461 553 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 462 554 JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(operand)}; 463 return atomicReadModifyWrite( vm, globalObject, args, AddFunc());555 return atomicReadModifyWrite(globalObject, vm, args, AddFunc()); 464 556 } 465 557 … … 470 562 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 471 563 JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(operand)}; 472 return atomicReadModifyWrite( vm, globalObject, args, AndFunc());564 return atomicReadModifyWrite(globalObject, vm, args, AndFunc()); 473 565 } 474 566 … … 479 571 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 480 572 JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(expected), JSValue::decode(newValue)}; 481 return atomicReadModifyWrite( vm, globalObject, args, CompareExchangeFunc());573 return atomicReadModifyWrite(globalObject, vm, args, CompareExchangeFunc()); 482 574 } 483 575 … … 488 580 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 489 581 JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(operand)}; 490 return atomicReadModifyWrite( vm, globalObject, args, ExchangeFunc());582 return atomicReadModifyWrite(globalObject, vm, args, ExchangeFunc()); 491 583 } 492 584 … … 505 597 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 506 598 JSValue args[] = {JSValue::decode(base), JSValue::decode(index)}; 507 return atomicReadModifyWrite( vm, globalObject, args, LoadFunc());599 return atomicReadModifyWrite(globalObject, vm, args, LoadFunc()); 508 600 } 509 601 … … 514 606 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 515 607 JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(operand)}; 516 return atomicReadModifyWrite( vm, globalObject, args, OrFunc());608 return atomicReadModifyWrite(globalObject, vm, args, OrFunc()); 517 609 } 518 610 … … 522 614 CallFrame* callFrame = DECLARE_CALL_FRAME(vm); 523 615 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 616 return atomicStore(globalObject, vm, JSValue::decode(base), JSValue::decode(index), JSValue::decode(operand)); 617 } 618 619 JSC_DEFINE_JIT_OPERATION(operationAtomicsSub, EncodedJSValue, (JSGlobalObject* globalObject, EncodedJSValue base, EncodedJSValue index, EncodedJSValue operand)) 620 { 621 VM& vm = globalObject->vm(); 622 CallFrame* callFrame = DECLARE_CALL_FRAME(vm); 623 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 524 624 JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(operand)}; 525 return atomicReadModifyWrite( vm, globalObject, args, StoreFunc());526 } 527 528 JSC_DEFINE_JIT_OPERATION(operationAtomics Sub, EncodedJSValue, (JSGlobalObject* globalObject, EncodedJSValue base, EncodedJSValue index, EncodedJSValue operand))625 return atomicReadModifyWrite(globalObject, vm, args, SubFunc()); 626 } 627 628 JSC_DEFINE_JIT_OPERATION(operationAtomicsXor, EncodedJSValue, (JSGlobalObject* globalObject, EncodedJSValue base, EncodedJSValue index, EncodedJSValue operand)) 529 629 { 530 630 VM& vm = globalObject->vm(); … … 532 632 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 533 633 JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(operand)}; 534 return atomicReadModifyWrite(vm, globalObject, args, SubFunc()); 535 } 536 537 JSC_DEFINE_JIT_OPERATION(operationAtomicsXor, EncodedJSValue, (JSGlobalObject* globalObject, EncodedJSValue base, EncodedJSValue index, EncodedJSValue operand)) 538 { 539 VM& vm = globalObject->vm(); 540 CallFrame* callFrame = DECLARE_CALL_FRAME(vm); 541 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 542 JSValue args[] = {JSValue::decode(base), JSValue::decode(index), JSValue::decode(operand)}; 543 return atomicReadModifyWrite(vm, globalObject, args, XorFunc()); 634 return atomicReadModifyWrite(globalObject, vm, args, XorFunc()); 544 635 } 545 636 -
trunk/Source/JavaScriptCore/runtime/ToNativeFromValue.h
r272170 r272341 34 34 typename Adaptor::Type toNativeFromValue(JSValue value) 35 35 { 36 // FIXME: BigInt36 ASSERT(!value.isBigInt()); 37 37 if (value.isInt32()) 38 38 return Adaptor::toNativeFromInt32(value.asInt32());
Note: See TracChangeset
for help on using the changeset viewer.