aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4atomics.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-08-24 17:17:34 +0200
committerLars Knoll <lars.knoll@qt.io>2018-08-26 16:59:37 +0000
commit83ded6108a947453744114543146a7f691f6f1aa (patch)
tree499b8b296a6978f799f78ac58d4ab0f7b0ddd8a0 /src/qml/jsruntime/qv4atomics.cpp
parente4e220fb568e22a4da7e6bd3d28ac34038041759 (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.cpp83
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)