diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-08-24 17:17:34 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-08-26 16:59:37 +0000 |
commit | 83ded6108a947453744114543146a7f691f6f1aa (patch) | |
tree | 499b8b296a6978f799f78ac58d4ab0f7b0ddd8a0 /src/qml/jsruntime/qv4atomics.cpp | |
parent | e4e220fb568e22a4da7e6bd3d28ac34038041759 (diff) |
Implement most remaining methods of Atomics
The only missing ones now are wait() and wake().
Change-Id: I2c0ee78cdd8a249e0e841861dd4b76c4665b0ae0
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4atomics.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4atomics.cpp | 83 |
1 files changed, 75 insertions, 8 deletions
diff --git a/src/qml/jsruntime/qv4atomics.cpp b/src/qml/jsruntime/qv4atomics.cpp index 21813c0667..b29e46db78 100644 --- a/src/qml/jsruntime/qv4atomics.cpp +++ b/src/qml/jsruntime/qv4atomics.cpp @@ -138,9 +138,31 @@ ReturnedValue Atomics::method_and(const FunctionObject *f, const Value *, const return atomicReadModifyWrite(f, argv, argc, AtomicAnd); } -ReturnedValue Atomics::method_compareExchange(const FunctionObject *f, const Value *, const Value *, int) +ReturnedValue Atomics::method_compareExchange(const FunctionObject *f, const Value *, const Value *argv, int argc) { - return f->engine()->throwTypeError(); + Scope scope(f); + if (!argc) + return scope.engine->throwTypeError(); + + SharedArrayBuffer *buffer = validateSharedIntegerTypedArray(scope, argv[0]); + if (!buffer) + return Encode::undefined(); + const TypedArray &a = static_cast<const TypedArray &>(argv[0]); + int index = validateAtomicAccess(scope, a, argc > 1 ? argv[1] : Primitive::undefinedValue()); + if (index < 0) + return Encode::undefined(); + + Value expected = Primitive::fromReturnedValue((argc > 2 ? argv[2] : Primitive::undefinedValue()).convertedToNumber()); + if (scope.hasException()) + return Encode::undefined(); + Value v = Primitive::fromReturnedValue((argc > 3 ? argv[3] : Primitive::undefinedValue()).convertedToNumber()); + if (scope.hasException()) + return Encode::undefined(); + + int bytesPerElement = a.d()->type->bytesPerElement; + int byteOffset = a.d()->byteOffset + index * bytesPerElement; + + return a.d()->type->atomicCompareExchange(buffer->data() + byteOffset, expected, v); } ReturnedValue Atomics::method_exchange(const FunctionObject *f, const Value *, const Value *argv, int argc) @@ -148,14 +170,40 @@ ReturnedValue Atomics::method_exchange(const FunctionObject *f, const Value *, c return atomicReadModifyWrite(f, argv, argc, AtomicExchange); } -ReturnedValue Atomics::method_isLockFree(const FunctionObject *f, const Value *, const Value *, int) +ReturnedValue Atomics::method_isLockFree(const FunctionObject *, const Value *, const Value *argv, int argc) { - return f->engine()->throwTypeError(); + if (!argc) + return Encode(false); + double n = argv[0].toInteger(); + if (n == 4.) + return Encode(true); + if (n == 2.) + return Encode(QAtomicOps<unsigned short>::isTestAndSetNative()); +#ifdef Q_ATOMIC_INT8_IS_SUPPORTED + if (n == 1.) + return Encode(QAtomicOps<unsigned char>::isTestAndSetNative()); +#endif + return Encode(false); } -ReturnedValue Atomics::method_load(const FunctionObject *f, const Value *, const Value *, int) +ReturnedValue Atomics::method_load(const FunctionObject *f, const Value *, const Value *argv, int argc) { - return f->engine()->throwTypeError(); + Scope scope(f); + if (!argc) + return scope.engine->throwTypeError(); + + SharedArrayBuffer *buffer = validateSharedIntegerTypedArray(scope, argv[0]); + if (!buffer) + return Encode::undefined(); + const TypedArray &a = static_cast<const TypedArray &>(argv[0]); + int index = validateAtomicAccess(scope, a, argc > 1 ? argv[1] : Primitive::undefinedValue()); + if (index < 0) + return Encode::undefined(); + + int bytesPerElement = a.d()->type->bytesPerElement; + int byteOffset = a.d()->byteOffset + index * bytesPerElement; + + return a.d()->type->atomicLoad(buffer->data() + byteOffset); } ReturnedValue Atomics::method_or(const FunctionObject *f, const Value *, const Value *argv, int argc) @@ -163,9 +211,28 @@ ReturnedValue Atomics::method_or(const FunctionObject *f, const Value *, const V return atomicReadModifyWrite(f, argv, argc, AtomicOr); } -ReturnedValue Atomics::method_store(const FunctionObject *f, const Value *, const Value *, int) +ReturnedValue Atomics::method_store(const FunctionObject *f, const Value *, const Value *argv, int argc) { - return f->engine()->throwTypeError(); + Scope scope(f); + if (!argc) + return scope.engine->throwTypeError(); + + SharedArrayBuffer *buffer = validateSharedIntegerTypedArray(scope, argv[0]); + if (!buffer) + return Encode::undefined(); + const TypedArray &a = static_cast<const TypedArray &>(argv[0]); + int index = validateAtomicAccess(scope, a, argc > 1 ? argv[1] : Primitive::undefinedValue()); + if (index < 0) + return Encode::undefined(); + + Value v = Primitive::fromReturnedValue((argc > 2 ? argv[2] : Primitive::undefinedValue()).convertedToNumber()); + if (scope.hasException()) + return Encode::undefined(); + + int bytesPerElement = a.d()->type->bytesPerElement; + int byteOffset = a.d()->byteOffset + index * bytesPerElement; + + return a.d()->type->atomicStore(buffer->data() + byteOffset, v); } ReturnedValue Atomics::method_sub(const FunctionObject *f, const Value *, const Value *argv, int argc) |