Bug 1133859: Allow shared array views as SIMD.load/store arguments; r=lth

--HG--
extra : rebase_source : 491c6d6fe54e7db8bd5460578fc1732fe7d2fdf2
This commit is contained in:
Benjamin Bouvier 2015-02-18 12:48:39 +01:00
Родитель dbf4bef164
Коммит 993adae83f
4 изменённых файлов: 106 добавлений и 11 удалений

Просмотреть файл

@ -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)
{