зеркало из 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>
|
||||
static bool
|
||||
TypedArrayFromArgs(JSContext *cx, const CallArgs &args,
|
||||
MutableHandle<TypedArrayObject*> typedArray, int32_t *byteStart)
|
||||
MutableHandleObject typedArray, int32_t *byteStart)
|
||||
{
|
||||
if (!args[0].isObject())
|
||||
return ErrorBadArgs(cx);
|
||||
|
||||
JSObject &argobj = args[0].toObject();
|
||||
if (!argobj.is<TypedArrayObject>())
|
||||
if (!IsAnyTypedArray(&argobj))
|
||||
return ErrorBadArgs(cx);
|
||||
|
||||
typedArray.set(&argobj.as<TypedArrayObject>());
|
||||
typedArray.set(&argobj);
|
||||
|
||||
int32_t index;
|
||||
if (!ToInt32(cx, args[1], &index))
|
||||
return false;
|
||||
|
||||
*byteStart = index * typedArray->bytesPerElement();
|
||||
if (*byteStart < 0 || (uint32_t(*byteStart) + NumElem * sizeof(VElem)) > typedArray->byteLength())
|
||||
*byteStart = index * AnyTypedArrayBytesPerElement(typedArray);
|
||||
if (*byteStart < 0 ||
|
||||
(uint32_t(*byteStart) + NumElem * sizeof(VElem)) > AnyTypedArrayByteLength(typedArray))
|
||||
{
|
||||
// Keep in sync with AsmJS OnOutOfBounds function.
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_BAD_INDEX);
|
||||
|
@ -1054,7 +1055,7 @@ Load(JSContext *cx, unsigned argc, Value *vp)
|
|||
return ErrorBadArgs(cx);
|
||||
|
||||
int32_t byteStart;
|
||||
Rooted<TypedArrayObject*> typedArray(cx);
|
||||
RootedObject typedArray(cx);
|
||||
if (!TypedArrayFromArgs<Elem, NumElem>(cx, args, &typedArray, &byteStart))
|
||||
return false;
|
||||
|
||||
|
@ -1064,7 +1065,7 @@ Load(JSContext *cx, unsigned argc, Value *vp)
|
|||
if (!result)
|
||||
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());
|
||||
memcpy(dst, src, sizeof(Elem) * NumElem);
|
||||
|
||||
|
@ -1083,7 +1084,7 @@ Store(JSContext *cx, unsigned argc, Value *vp)
|
|||
return ErrorBadArgs(cx);
|
||||
|
||||
int32_t byteStart;
|
||||
Rooted<TypedArrayObject*> typedArray(cx);
|
||||
RootedObject typedArray(cx);
|
||||
if (!TypedArrayFromArgs<Elem, NumElem>(cx, args, &typedArray, &byteStart))
|
||||
return false;
|
||||
|
||||
|
@ -1091,7 +1092,7 @@ Store(JSContext *cx, unsigned argc, Value *vp)
|
|||
return ErrorBadArgs(cx);
|
||||
|
||||
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);
|
||||
|
||||
args.rval().setObject(args[2].toObject());
|
||||
|
|
|
@ -11,9 +11,15 @@ const SIZE_64_ARRAY = 8;
|
|||
|
||||
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 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.
|
||||
var sizeOfLaneElem;
|
||||
|
@ -163,9 +169,48 @@ function testLoad(kind, TA) {
|
|||
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('float64x2', new Float64Array(SIZE_64_ARRAY));
|
||||
testLoad('int32x4', new Int32Array(SIZE_32_ARRAY));
|
||||
testSharedArrayBufferCompat();
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
||||
|
|
|
@ -103,9 +103,50 @@ function testStoreFloat64x2() {
|
|||
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();
|
||||
testStoreFloat32x4();
|
||||
testStoreFloat64x2();
|
||||
testSharedArrayBufferCompat();
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
||||
|
|
|
@ -113,6 +113,14 @@ AnyTypedArrayViewData(const JSObject *obj)
|
|||
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
|
||||
AnyTypedArrayByteLength(const JSObject *obj)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче