зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1531647 - Implement atomic operations on BigInt TypedArrays r=lth
Differential Revision: https://phabricator.services.mozilla.com/D21648 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
fa340ddad3
Коммит
fe9c5481dd
|
@ -151,6 +151,68 @@ JS::Result<> ArrayOps<uint32_t>::storeResult(JSContext* cx, uint32_t v,
|
|||
return Ok();
|
||||
}
|
||||
|
||||
template <>
|
||||
struct ArrayOps<int64_t> {
|
||||
static JS::Result<int64_t> convertValue(JSContext* cx, HandleValue v) {
|
||||
BigInt* bi = ToBigInt(cx, v);
|
||||
if (!bi) {
|
||||
return cx->alreadyReportedError();
|
||||
}
|
||||
return BigInt::toInt64(bi);
|
||||
}
|
||||
|
||||
static JS::Result<int64_t> convertValue(JSContext* cx, HandleValue v,
|
||||
MutableHandleValue result) {
|
||||
BigInt* bi = ToBigInt(cx, v);
|
||||
if (!bi) {
|
||||
return cx->alreadyReportedError();
|
||||
}
|
||||
result.setBigInt(bi);
|
||||
return BigInt::toInt64(bi);
|
||||
}
|
||||
|
||||
static JS::Result<> storeResult(JSContext* cx, int64_t v,
|
||||
MutableHandleValue result) {
|
||||
BigInt* bi = BigInt::createFromInt64(cx, v);
|
||||
if (!bi) {
|
||||
return cx->alreadyReportedError();
|
||||
}
|
||||
result.setBigInt(bi);
|
||||
return Ok();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ArrayOps<uint64_t> {
|
||||
static JS::Result<uint64_t> convertValue(JSContext* cx, HandleValue v) {
|
||||
BigInt* bi = ToBigInt(cx, v);
|
||||
if (!bi) {
|
||||
return cx->alreadyReportedError();
|
||||
}
|
||||
return BigInt::toUint64(bi);
|
||||
}
|
||||
|
||||
static JS::Result<uint64_t> convertValue(JSContext* cx, HandleValue v,
|
||||
MutableHandleValue result) {
|
||||
BigInt* bi = ToBigInt(cx, v);
|
||||
if (!bi) {
|
||||
return cx->alreadyReportedError();
|
||||
}
|
||||
result.setBigInt(bi);
|
||||
return BigInt::toUint64(bi);
|
||||
}
|
||||
|
||||
static JS::Result<> storeResult(JSContext* cx, uint64_t v,
|
||||
MutableHandleValue result) {
|
||||
BigInt* bi = BigInt::createFromUint64(cx, v);
|
||||
if (!bi) {
|
||||
return cx->alreadyReportedError();
|
||||
}
|
||||
result.setBigInt(bi);
|
||||
return Ok();
|
||||
}
|
||||
};
|
||||
|
||||
template <template <typename> class F, typename... Args>
|
||||
bool perform(JSContext* cx, HandleValue objv, HandleValue idxv, Args... args) {
|
||||
Rooted<TypedArrayObject*> view(cx, nullptr);
|
||||
|
@ -178,9 +240,11 @@ bool perform(JSContext* cx, HandleValue objv, HandleValue idxv, Args... args) {
|
|||
case Scalar::Float32:
|
||||
case Scalar::Float64:
|
||||
case Scalar::Uint8Clamped:
|
||||
case Scalar::BigInt64:
|
||||
case Scalar::BigUint64:
|
||||
return ReportBadArrayType(cx);
|
||||
case Scalar::BigInt64:
|
||||
return F<int64_t>::run(cx, viewData.cast<int64_t*>() + offset, args...);
|
||||
case Scalar::BigUint64:
|
||||
return F<uint64_t>::run(cx, viewData.cast<uint64_t*>() + offset, args...);
|
||||
case Scalar::MaxTypedArrayViewType:
|
||||
case Scalar::Int64:
|
||||
break;
|
||||
|
@ -305,12 +369,17 @@ static bool AtomicsBinop(JSContext* cx, HandleValue objv, HandleValue idxv,
|
|||
} \
|
||||
static uint32_t operate(SharedMem<uint32_t*> addr, uint32_t v) { \
|
||||
return NAME(addr, v); \
|
||||
} \
|
||||
static int64_t operate(SharedMem<int64_t*> addr, int64_t v) { \
|
||||
return NAME(addr, v); \
|
||||
} \
|
||||
static uint64_t operate(SharedMem<uint64_t*> addr, uint64_t v) { \
|
||||
return NAME(addr, v); \
|
||||
}
|
||||
|
||||
class PerformAdd {
|
||||
public:
|
||||
INTEGRAL_TYPES_FOR_EACH(jit::AtomicOperations::fetchAddSeqCst)
|
||||
static int32_t perform(int32_t x, int32_t y) { return x + y; }
|
||||
};
|
||||
|
||||
bool js::atomics_add(JSContext* cx, unsigned argc, Value* vp) {
|
||||
|
@ -322,7 +391,6 @@ bool js::atomics_add(JSContext* cx, unsigned argc, Value* vp) {
|
|||
class PerformSub {
|
||||
public:
|
||||
INTEGRAL_TYPES_FOR_EACH(jit::AtomicOperations::fetchSubSeqCst)
|
||||
static int32_t perform(int32_t x, int32_t y) { return x - y; }
|
||||
};
|
||||
|
||||
bool js::atomics_sub(JSContext* cx, unsigned argc, Value* vp) {
|
||||
|
@ -334,7 +402,6 @@ bool js::atomics_sub(JSContext* cx, unsigned argc, Value* vp) {
|
|||
class PerformAnd {
|
||||
public:
|
||||
INTEGRAL_TYPES_FOR_EACH(jit::AtomicOperations::fetchAndSeqCst)
|
||||
static int32_t perform(int32_t x, int32_t y) { return x & y; }
|
||||
};
|
||||
|
||||
bool js::atomics_and(JSContext* cx, unsigned argc, Value* vp) {
|
||||
|
@ -346,7 +413,6 @@ bool js::atomics_and(JSContext* cx, unsigned argc, Value* vp) {
|
|||
class PerformOr {
|
||||
public:
|
||||
INTEGRAL_TYPES_FOR_EACH(jit::AtomicOperations::fetchOrSeqCst)
|
||||
static int32_t perform(int32_t x, int32_t y) { return x | y; }
|
||||
};
|
||||
|
||||
bool js::atomics_or(JSContext* cx, unsigned argc, Value* vp) {
|
||||
|
@ -358,7 +424,6 @@ bool js::atomics_or(JSContext* cx, unsigned argc, Value* vp) {
|
|||
class PerformXor {
|
||||
public:
|
||||
INTEGRAL_TYPES_FOR_EACH(jit::AtomicOperations::fetchXorSeqCst)
|
||||
static int32_t perform(int32_t x, int32_t y) { return x ^ y; }
|
||||
};
|
||||
|
||||
bool js::atomics_xor(JSContext* cx, unsigned argc, Value* vp) {
|
||||
|
@ -494,29 +559,10 @@ FutexThread::WaitResult js::atomics_wait_impl(
|
|||
return AtomicsWait(cx, sarb, byteOffset, value, timeout);
|
||||
}
|
||||
|
||||
bool js::atomics_wait(JSContext* cx, unsigned argc, Value* vp) {
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
HandleValue objv = args.get(0);
|
||||
HandleValue idxv = args.get(1);
|
||||
HandleValue valv = args.get(2);
|
||||
HandleValue timeoutv = args.get(3);
|
||||
MutableHandleValue r = args.rval();
|
||||
|
||||
Rooted<TypedArrayObject*> view(cx, nullptr);
|
||||
if (!GetSharedTypedArray(cx, objv, &view)) {
|
||||
return false;
|
||||
}
|
||||
if (view->type() != Scalar::Int32) {
|
||||
return ReportBadArrayType(cx);
|
||||
}
|
||||
uint32_t offset;
|
||||
if (!GetTypedArrayIndex(cx, idxv, view, &offset)) {
|
||||
return false;
|
||||
}
|
||||
int32_t value;
|
||||
if (!ToInt32(cx, valv, &value)) {
|
||||
return false;
|
||||
}
|
||||
template <typename T>
|
||||
static bool DoAtomicsWait(JSContext* cx, Handle<TypedArrayObject*> view,
|
||||
uint32_t offset, T value, HandleValue timeoutv,
|
||||
MutableHandleValue r) {
|
||||
mozilla::Maybe<mozilla::TimeDuration> timeout;
|
||||
if (!timeoutv.isUndefined()) {
|
||||
double timeout_ms;
|
||||
|
@ -537,7 +583,7 @@ bool js::atomics_wait(JSContext* cx, unsigned argc, Value* vp) {
|
|||
// The computation will not overflow because range checks have been
|
||||
// performed.
|
||||
uint32_t byteOffset =
|
||||
offset * sizeof(int32_t) +
|
||||
offset * sizeof(T) +
|
||||
(view->dataPointerShared().cast<uint8_t*>().unwrap(/* arithmetic */) -
|
||||
sab->dataPointerShared().unwrap(/* arithmetic */));
|
||||
|
||||
|
@ -559,6 +605,44 @@ bool js::atomics_wait(JSContext* cx, unsigned argc, Value* vp) {
|
|||
}
|
||||
}
|
||||
|
||||
bool js::atomics_wait(JSContext* cx, unsigned argc, Value* vp) {
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
HandleValue objv = args.get(0);
|
||||
HandleValue idxv = args.get(1);
|
||||
HandleValue valv = args.get(2);
|
||||
HandleValue timeoutv = args.get(3);
|
||||
MutableHandleValue r = args.rval();
|
||||
|
||||
Rooted<TypedArrayObject*> view(cx, nullptr);
|
||||
if (!GetSharedTypedArray(cx, objv, &view)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (view->type() != Scalar::Int32 && view->type() != Scalar::BigInt64) {
|
||||
return ReportBadArrayType(cx);
|
||||
}
|
||||
|
||||
uint32_t offset;
|
||||
if (!GetTypedArrayIndex(cx, idxv, view, &offset)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (view->type() == Scalar::Int32) {
|
||||
int32_t value;
|
||||
if (!ToInt32(cx, valv, &value)) {
|
||||
return false;
|
||||
}
|
||||
return DoAtomicsWait(cx, view, offset, value, timeoutv, r);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(view->type() == Scalar::BigInt64);
|
||||
RootedBigInt valbi(cx, ToBigInt(cx, valv));
|
||||
if (!valbi) {
|
||||
return false;
|
||||
}
|
||||
return DoAtomicsWait(cx, view, offset, BigInt::toInt64(valbi), timeoutv, r);
|
||||
}
|
||||
|
||||
int64_t js::atomics_notify_impl(SharedArrayRawBuffer* sarb, uint32_t byteOffset,
|
||||
int64_t count) {
|
||||
// Validation should ensure this does not happen.
|
||||
|
@ -605,9 +689,11 @@ bool js::atomics_notify(JSContext* cx, unsigned argc, Value* vp) {
|
|||
if (!GetSharedTypedArray(cx, objv, &view)) {
|
||||
return false;
|
||||
}
|
||||
if (view->type() != Scalar::Int32) {
|
||||
if (view->type() != Scalar::Int32 && view->type() != Scalar::BigInt64) {
|
||||
return ReportBadArrayType(cx);
|
||||
}
|
||||
uint32_t elementSize =
|
||||
view->type() == Scalar::Int32 ? sizeof(int32_t) : sizeof(int64_t);
|
||||
uint32_t offset;
|
||||
if (!GetTypedArrayIndex(cx, idxv, view, &offset)) {
|
||||
return false;
|
||||
|
@ -630,7 +716,7 @@ bool js::atomics_notify(JSContext* cx, unsigned argc, Value* vp) {
|
|||
// The computation will not overflow because range checks have been
|
||||
// performed.
|
||||
uint32_t byteOffset =
|
||||
offset * sizeof(int32_t) +
|
||||
offset * elementSize +
|
||||
(view->dataPointerShared().cast<uint8_t*>().unwrap(/* arithmetic */) -
|
||||
sab->dataPointerShared().unwrap(/* arithmetic */));
|
||||
|
||||
|
|
|
@ -239,65 +239,6 @@ skip script test262/built-ins/TypedArrayConstructors/internals/Set/key-is-not-ca
|
|||
skip script test262/built-ins/TypedArrayConstructors/internals/Set/key-is-not-integer.js
|
||||
skip script test262/built-ins/TypedArrayConstructors/internals/Set/tonumber-value-throws.js
|
||||
|
||||
# https://bugzilla.mozilla.org/show_bug.cgi?id=1531647
|
||||
skip script test262/built-ins/Atomics/store/bigint/bad-range.js
|
||||
skip script test262/built-ins/Atomics/store/bigint/nonshared-int-views.js
|
||||
skip script test262/built-ins/Atomics/store/bigint/good-views.js
|
||||
skip script test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-add.js
|
||||
skip script test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-or.js
|
||||
skip script test262/built-ins/Atomics/wait/bigint/bad-range.js
|
||||
skip script test262/built-ins/Atomics/wait/bigint/non-shared-bufferdata-throws.js
|
||||
skip script test262/built-ins/Atomics/wait/bigint/nan-for-timeout.js
|
||||
skip script test262/built-ins/Atomics/wait/bigint/waiterlist-block-indexedposition-wake.js
|
||||
skip script test262/built-ins/Atomics/wait/bigint/negative-index-throws.js
|
||||
skip script test262/built-ins/Atomics/wait/bigint/value-not-equal.js
|
||||
skip script test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-and.js
|
||||
skip script test262/built-ins/Atomics/wait/bigint/negative-timeout.js
|
||||
skip script test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-sub.js
|
||||
skip script test262/built-ins/Atomics/wait/bigint/negative-timeout-agent.js
|
||||
skip script test262/built-ins/Atomics/wait/bigint/waiterlist-order-of-operations-is-fifo.js
|
||||
skip script test262/built-ins/Atomics/wait/bigint/null-bufferdata-throws.js
|
||||
skip script test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-exchange.js
|
||||
skip script test262/built-ins/Atomics/wait/bigint/out-of-range-index-throws.js
|
||||
skip script test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-store.js
|
||||
skip script test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-compareExchange.js
|
||||
skip script test262/built-ins/Atomics/wait/bigint/false-for-timeout.js
|
||||
skip script test262/built-ins/Atomics/wait/bigint/false-for-timeout-agent.js
|
||||
skip script test262/built-ins/Atomics/wait/bigint/was-woken-before-timeout.js
|
||||
skip script test262/built-ins/Atomics/wait/bigint/non-bigint64-typedarray-throws.js
|
||||
skip script test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-no-operation.js
|
||||
skip script test262/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-xor.js
|
||||
skip script test262/built-ins/Atomics/add/bigint/bad-range.js
|
||||
skip script test262/built-ins/Atomics/add/bigint/nonshared-int-views.js
|
||||
skip script test262/built-ins/Atomics/add/bigint/good-views.js
|
||||
skip script test262/built-ins/Atomics/xor/bigint/bad-range.js
|
||||
skip script test262/built-ins/Atomics/xor/bigint/nonshared-int-views.js
|
||||
skip script test262/built-ins/Atomics/xor/bigint/good-views.js
|
||||
skip script test262/built-ins/Atomics/notify/bigint/bad-range.js
|
||||
skip script test262/built-ins/Atomics/notify/bigint/non-shared-bufferdata-throws.js
|
||||
skip script test262/built-ins/Atomics/notify/bigint/notify-all-on-loc.js
|
||||
skip script test262/built-ins/Atomics/notify/bigint/null-bufferdata-throws.js
|
||||
skip script test262/built-ins/Atomics/notify/bigint/non-bigint64-typedarray-throws.js
|
||||
skip script test262/built-ins/Atomics/load/bigint/bad-range.js
|
||||
skip script test262/built-ins/Atomics/load/bigint/nonshared-int-views.js
|
||||
skip script test262/built-ins/Atomics/load/bigint/good-views.js
|
||||
skip script test262/built-ins/Atomics/isLockFree/bigint/expected-return-value.js
|
||||
skip script test262/built-ins/Atomics/and/bigint/bad-range.js
|
||||
skip script test262/built-ins/Atomics/and/bigint/nonshared-int-views.js
|
||||
skip script test262/built-ins/Atomics/and/bigint/good-views.js
|
||||
skip script test262/built-ins/Atomics/or/bigint/bad-range.js
|
||||
skip script test262/built-ins/Atomics/or/bigint/good-views.js
|
||||
skip script test262/built-ins/Atomics/or/bigint/nonshared-int-views.js
|
||||
skip script test262/built-ins/Atomics/compareExchange/bigint/bad-range.js
|
||||
skip script test262/built-ins/Atomics/compareExchange/bigint/nonshared-int-views.js
|
||||
skip script test262/built-ins/Atomics/compareExchange/bigint/good-views.js
|
||||
skip script test262/built-ins/Atomics/exchange/bigint/bad-range.js
|
||||
skip script test262/built-ins/Atomics/exchange/bigint/nonshared-int-views.js
|
||||
skip script test262/built-ins/Atomics/exchange/bigint/good-views.js
|
||||
skip script test262/built-ins/Atomics/sub/bigint/bad-range.js
|
||||
skip script test262/built-ins/Atomics/sub/bigint/nonshared-int-views.js
|
||||
skip script test262/built-ins/Atomics/sub/bigint/good-views.js
|
||||
|
||||
# https://bugzilla.mozilla.org/show_bug.cgi?id=1317405
|
||||
skip script test262/language/computed-property-names/class/static/method-number.js
|
||||
skip script test262/language/computed-property-names/class/static/method-string.js
|
||||
|
|
Загрузка…
Ссылка в новой задаче