зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1133859: Allow shared array views as SIMD.load/store arguments; r=lth
--HG-- extra : rebase_source : 491c6d6fe54e7db8bd5460578fc1732fe7d2fdf2
This commit is contained in:
Родитель
dbf4bef164
Коммит
993adae83f
|
@ -1017,23 +1017,24 @@ Select(JSContext *cx, unsigned argc, Value *vp)
|
||||||
template<class VElem, unsigned NumElem>
|
template<class VElem, unsigned NumElem>
|
||||||
static bool
|
static bool
|
||||||
TypedArrayFromArgs(JSContext *cx, const CallArgs &args,
|
TypedArrayFromArgs(JSContext *cx, const CallArgs &args,
|
||||||
MutableHandle<TypedArrayObject*> typedArray, int32_t *byteStart)
|
MutableHandleObject typedArray, int32_t *byteStart)
|
||||||
{
|
{
|
||||||
if (!args[0].isObject())
|
if (!args[0].isObject())
|
||||||
return ErrorBadArgs(cx);
|
return ErrorBadArgs(cx);
|
||||||
|
|
||||||
JSObject &argobj = args[0].toObject();
|
JSObject &argobj = args[0].toObject();
|
||||||
if (!argobj.is<TypedArrayObject>())
|
if (!IsAnyTypedArray(&argobj))
|
||||||
return ErrorBadArgs(cx);
|
return ErrorBadArgs(cx);
|
||||||
|
|
||||||
typedArray.set(&argobj.as<TypedArrayObject>());
|
typedArray.set(&argobj);
|
||||||
|
|
||||||
int32_t index;
|
int32_t index;
|
||||||
if (!ToInt32(cx, args[1], &index))
|
if (!ToInt32(cx, args[1], &index))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
*byteStart = index * typedArray->bytesPerElement();
|
*byteStart = index * AnyTypedArrayBytesPerElement(typedArray);
|
||||||
if (*byteStart < 0 || (uint32_t(*byteStart) + NumElem * sizeof(VElem)) > typedArray->byteLength())
|
if (*byteStart < 0 ||
|
||||||
|
(uint32_t(*byteStart) + NumElem * sizeof(VElem)) > AnyTypedArrayByteLength(typedArray))
|
||||||
{
|
{
|
||||||
// Keep in sync with AsmJS OnOutOfBounds function.
|
// Keep in sync with AsmJS OnOutOfBounds function.
|
||||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_BAD_INDEX);
|
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_BAD_INDEX);
|
||||||
|
@ -1054,7 +1055,7 @@ Load(JSContext *cx, unsigned argc, Value *vp)
|
||||||
return ErrorBadArgs(cx);
|
return ErrorBadArgs(cx);
|
||||||
|
|
||||||
int32_t byteStart;
|
int32_t byteStart;
|
||||||
Rooted<TypedArrayObject*> typedArray(cx);
|
RootedObject typedArray(cx);
|
||||||
if (!TypedArrayFromArgs<Elem, NumElem>(cx, args, &typedArray, &byteStart))
|
if (!TypedArrayFromArgs<Elem, NumElem>(cx, args, &typedArray, &byteStart))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -1064,7 +1065,7 @@ Load(JSContext *cx, unsigned argc, Value *vp)
|
||||||
if (!result)
|
if (!result)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Elem *src = reinterpret_cast<Elem*>(static_cast<char*>(typedArray->viewData()) + byteStart);
|
Elem *src = reinterpret_cast<Elem*>(static_cast<char*>(AnyTypedArrayViewData(typedArray)) + byteStart);
|
||||||
Elem *dst = reinterpret_cast<Elem*>(result->typedMem());
|
Elem *dst = reinterpret_cast<Elem*>(result->typedMem());
|
||||||
memcpy(dst, src, sizeof(Elem) * NumElem);
|
memcpy(dst, src, sizeof(Elem) * NumElem);
|
||||||
|
|
||||||
|
@ -1083,7 +1084,7 @@ Store(JSContext *cx, unsigned argc, Value *vp)
|
||||||
return ErrorBadArgs(cx);
|
return ErrorBadArgs(cx);
|
||||||
|
|
||||||
int32_t byteStart;
|
int32_t byteStart;
|
||||||
Rooted<TypedArrayObject*> typedArray(cx);
|
RootedObject typedArray(cx);
|
||||||
if (!TypedArrayFromArgs<Elem, NumElem>(cx, args, &typedArray, &byteStart))
|
if (!TypedArrayFromArgs<Elem, NumElem>(cx, args, &typedArray, &byteStart))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -1091,7 +1092,7 @@ Store(JSContext *cx, unsigned argc, Value *vp)
|
||||||
return ErrorBadArgs(cx);
|
return ErrorBadArgs(cx);
|
||||||
|
|
||||||
Elem *src = TypedObjectMemory<Elem*>(args[2]);
|
Elem *src = TypedObjectMemory<Elem*>(args[2]);
|
||||||
Elem *dst = reinterpret_cast<Elem*>(static_cast<char*>(typedArray->viewData()) + byteStart);
|
Elem *dst = reinterpret_cast<Elem*>(static_cast<char*>(AnyTypedArrayViewData(typedArray)) + byteStart);
|
||||||
memcpy(dst, src, sizeof(Elem) * NumElem);
|
memcpy(dst, src, sizeof(Elem) * NumElem);
|
||||||
|
|
||||||
args.rval().setObject(args[2].toObject());
|
args.rval().setObject(args[2].toObject());
|
||||||
|
|
|
@ -11,9 +11,15 @@ const SIZE_64_ARRAY = 8;
|
||||||
|
|
||||||
const SIZE_BYTES = SIZE_32_ARRAY * 4;
|
const SIZE_BYTES = SIZE_32_ARRAY * 4;
|
||||||
|
|
||||||
function MakeComparator(kind, arr) {
|
function IsSharedTypedArray(arr) {
|
||||||
|
return arr && arr.buffer && arr.buffer instanceof SharedArrayBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
function MakeComparator(kind, arr, shared) {
|
||||||
var bpe = arr.BYTES_PER_ELEMENT;
|
var bpe = arr.BYTES_PER_ELEMENT;
|
||||||
var uint8 = (bpe != 1) ? new Uint8Array(arr.buffer) : arr;
|
var uint8 = (bpe != 1) ? (IsSharedTypedArray(arr) ? new SharedUint8Array(arr.buffer)
|
||||||
|
: new Uint8Array(arr.buffer))
|
||||||
|
: arr;
|
||||||
|
|
||||||
// Size in bytes of a single element in the SIMD vector.
|
// Size in bytes of a single element in the SIMD vector.
|
||||||
var sizeOfLaneElem;
|
var sizeOfLaneElem;
|
||||||
|
@ -163,9 +169,48 @@ function testLoad(kind, TA) {
|
||||||
assertThrowsInstanceOf(() => SIMD[kind].load(TA, obj), TypeError);
|
assertThrowsInstanceOf(() => SIMD[kind].load(TA, obj), TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testSharedArrayBufferCompat() {
|
||||||
|
if (!this.SharedArrayBuffer || !this.SharedFloat32Array || !this.Atomics)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var TA = new SharedFloat32Array(16);
|
||||||
|
for (var i = 0; i < 16; i++)
|
||||||
|
TA[i] = i + 1;
|
||||||
|
|
||||||
|
for (var ta of [
|
||||||
|
new SharedUint8Array(TA.buffer),
|
||||||
|
new SharedInt8Array(TA.buffer),
|
||||||
|
new SharedUint16Array(TA.buffer),
|
||||||
|
new SharedInt16Array(TA.buffer),
|
||||||
|
new SharedUint32Array(TA.buffer),
|
||||||
|
new SharedInt32Array(TA.buffer),
|
||||||
|
new SharedFloat32Array(TA.buffer),
|
||||||
|
new SharedFloat64Array(TA.buffer)
|
||||||
|
])
|
||||||
|
{
|
||||||
|
for (var kind of ['int32x4', 'float32x4', 'float64x2']) {
|
||||||
|
var comp = MakeComparator(kind, ta);
|
||||||
|
comp.load(0);
|
||||||
|
comp.loadX(0);
|
||||||
|
comp.loadXY(0);
|
||||||
|
comp.loadXYZ(0);
|
||||||
|
|
||||||
|
comp.load(3);
|
||||||
|
comp.loadX(3);
|
||||||
|
comp.loadXY(3);
|
||||||
|
comp.loadXYZ(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertThrowsInstanceOf(() => SIMD.int32x4.load(ta, 1024), RangeError);
|
||||||
|
assertThrowsInstanceOf(() => SIMD.float32x4.load(ta, 1024), RangeError);
|
||||||
|
assertThrowsInstanceOf(() => SIMD.float64x2.load(ta, 1024), RangeError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
testLoad('float32x4', new Float32Array(SIZE_32_ARRAY));
|
testLoad('float32x4', new Float32Array(SIZE_32_ARRAY));
|
||||||
testLoad('float64x2', new Float64Array(SIZE_64_ARRAY));
|
testLoad('float64x2', new Float64Array(SIZE_64_ARRAY));
|
||||||
testLoad('int32x4', new Int32Array(SIZE_32_ARRAY));
|
testLoad('int32x4', new Int32Array(SIZE_32_ARRAY));
|
||||||
|
testSharedArrayBufferCompat();
|
||||||
|
|
||||||
if (typeof reportCompare === "function")
|
if (typeof reportCompare === "function")
|
||||||
reportCompare(true, true);
|
reportCompare(true, true);
|
||||||
|
|
|
@ -103,9 +103,50 @@ function testStoreFloat64x2() {
|
||||||
assertThrowsInstanceOf(() => SIMD.float32x4.store(F64, 0, v), TypeError);
|
assertThrowsInstanceOf(() => SIMD.float32x4.store(F64, 0, v), TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testSharedArrayBufferCompat() {
|
||||||
|
if (!this.SharedArrayBuffer || !this.SharedFloat32Array || !this.Atomics)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var I32 = new SharedInt32Array(16);
|
||||||
|
var TA = I32;
|
||||||
|
|
||||||
|
var F32 = new SharedFloat32Array(TA.buffer);
|
||||||
|
var F64 = new SharedFloat64Array(TA.buffer);
|
||||||
|
|
||||||
|
var int32x4 = SIMD.int32x4(1, 2, 3, 4);
|
||||||
|
var float32x4 = SIMD.float32x4(1, 2, 3, 4);
|
||||||
|
var float64x2 = SIMD.float64x2(1, 2);
|
||||||
|
|
||||||
|
for (var ta of [
|
||||||
|
new SharedUint8Array(TA.buffer),
|
||||||
|
new SharedInt8Array(TA.buffer),
|
||||||
|
new SharedUint16Array(TA.buffer),
|
||||||
|
new SharedInt16Array(TA.buffer),
|
||||||
|
new SharedUint32Array(TA.buffer),
|
||||||
|
new SharedInt32Array(TA.buffer),
|
||||||
|
new SharedFloat32Array(TA.buffer),
|
||||||
|
new SharedFloat64Array(TA.buffer)
|
||||||
|
])
|
||||||
|
{
|
||||||
|
SIMD.int32x4.store(ta, 0, int32x4);
|
||||||
|
for (var i = 0; i < 4; i++) assertEq(I32[i], [1, 2, 3, 4][i]);
|
||||||
|
|
||||||
|
SIMD.float32x4.store(ta, 0, float32x4);
|
||||||
|
for (var i = 0; i < 4; i++) assertEq(F32[i], [1, 2, 3, 4][i]);
|
||||||
|
|
||||||
|
SIMD.float64x2.store(ta, 0, float64x2);
|
||||||
|
for (var i = 0; i < 2; i++) assertEq(F64[i], [1, 2][i]);
|
||||||
|
|
||||||
|
assertThrowsInstanceOf(() => SIMD.int32x4.store(ta, 1024, int32x4), RangeError);
|
||||||
|
assertThrowsInstanceOf(() => SIMD.float32x4.store(ta, 1024, float32x4), RangeError);
|
||||||
|
assertThrowsInstanceOf(() => SIMD.float64x2.store(ta, 1024, float64x2), RangeError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
testStoreInt32x4();
|
testStoreInt32x4();
|
||||||
testStoreFloat32x4();
|
testStoreFloat32x4();
|
||||||
testStoreFloat64x2();
|
testStoreFloat64x2();
|
||||||
|
testSharedArrayBufferCompat();
|
||||||
|
|
||||||
if (typeof reportCompare === "function")
|
if (typeof reportCompare === "function")
|
||||||
reportCompare(true, true);
|
reportCompare(true, true);
|
||||||
|
|
|
@ -113,6 +113,14 @@ AnyTypedArrayViewData(const JSObject *obj)
|
||||||
return obj->as<SharedTypedArrayObject>().viewData();
|
return obj->as<SharedTypedArrayObject>().viewData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline uint32_t
|
||||||
|
AnyTypedArrayBytesPerElement(const JSObject *obj)
|
||||||
|
{
|
||||||
|
if (obj->is<TypedArrayObject>())
|
||||||
|
return obj->as<TypedArrayObject>().bytesPerElement();
|
||||||
|
return obj->as<SharedTypedArrayObject>().bytesPerElement();
|
||||||
|
}
|
||||||
|
|
||||||
inline uint32_t
|
inline uint32_t
|
||||||
AnyTypedArrayByteLength(const JSObject *obj)
|
AnyTypedArrayByteLength(const JSObject *obj)
|
||||||
{
|
{
|
||||||
|
|
Загрузка…
Ссылка в новой задаче