зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1252924 - SIMD.*.prototype.valueOf. r=waldo
When SIMD objects have proper value semantics, this method will just return |this| after a type check. Until then, do as the polyfill and override valueOf to throw a TypeError so that ToNumber() can't convert a SIMD value to a number. Fix wrong code in asm.js/testBug1099216.js. This code was using Float32x4(x) instead of Float32x4.check(x) as an argument coercion. MozReview-Commit-ID: H9zaEfoqs2J
This commit is contained in:
Родитель
a6cad32eee
Коммит
acc528baf8
|
@ -219,6 +219,7 @@ static const JSFunctionSpec TypeDescriptorMethods[] = {
|
||||||
// Shared TypedObject methods for all SIMD types.
|
// Shared TypedObject methods for all SIMD types.
|
||||||
static const JSFunctionSpec SimdTypedObjectMethods[] = {
|
static const JSFunctionSpec SimdTypedObjectMethods[] = {
|
||||||
JS_SELF_HOSTED_FN("toString", "SimdToString", 0, 0),
|
JS_SELF_HOSTED_FN("toString", "SimdToString", 0, 0),
|
||||||
|
JS_SELF_HOSTED_FN("valueOf", "SimdValueOf", 0, 0),
|
||||||
JS_SELF_HOSTED_FN("toSource", "SimdToSource", 0, 0),
|
JS_SELF_HOSTED_FN("toSource", "SimdToSource", 0, 0),
|
||||||
JS_FS_END
|
JS_FS_END
|
||||||
};
|
};
|
||||||
|
|
|
@ -690,6 +690,24 @@ function SimdTypeToLength(type) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This implements SIMD.*.prototype.valueOf().
|
||||||
|
// Once we have proper value semantics for SIMD types, this function should just
|
||||||
|
// perform a type check and return this.
|
||||||
|
// For now, throw a TypeError unconditionally since valueOf() was probably
|
||||||
|
// called from ToNumber() which is supposed to throw when attempting to convert
|
||||||
|
// a SIMD value to a number.
|
||||||
|
function SimdValueOf() {
|
||||||
|
if (!IsObject(this) || !ObjectIsTypedObject(this))
|
||||||
|
ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "SIMD", "valueOf", typeof this);
|
||||||
|
|
||||||
|
var descr = TypedObjectTypeDescr(this);
|
||||||
|
|
||||||
|
if (DESCR_KIND(descr) != JS_TYPEREPR_SIMD_KIND)
|
||||||
|
ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "SIMD", "valueOf", typeof this);
|
||||||
|
|
||||||
|
ThrowTypeError(JSMSG_SIMD_TO_NUMBER);
|
||||||
|
}
|
||||||
|
|
||||||
function SimdToSource() {
|
function SimdToSource() {
|
||||||
if (!IsObject(this) || !ObjectIsTypedObject(this))
|
if (!IsObject(this) || !ObjectIsTypedObject(this))
|
||||||
ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "SIMD.*", "toSource", typeof this);
|
ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "SIMD.*", "toSource", typeof this);
|
||||||
|
|
|
@ -7,9 +7,10 @@ if (typeof SIMD === 'undefined' || !isSimdAvailable()) {
|
||||||
"use asm";
|
"use asm";
|
||||||
var frd = global.Math.fround;
|
var frd = global.Math.fround;
|
||||||
var fx4 = global.SIMD.Float32x4;
|
var fx4 = global.SIMD.Float32x4;
|
||||||
|
var fc4 = fx4.check;
|
||||||
var fsp = fx4.splat;
|
var fsp = fx4.splat;
|
||||||
function s(){}
|
function s(){}
|
||||||
function d(x){x=fx4(x);}
|
function d(x){x=fc4(x);}
|
||||||
function e() {
|
function e() {
|
||||||
var x = frd(0);
|
var x = frd(0);
|
||||||
x = frd(x / x);
|
x = frd(x / x);
|
||||||
|
@ -23,11 +24,12 @@ if (typeof SIMD === 'undefined' || !isSimdAvailable()) {
|
||||||
"use asm"
|
"use asm"
|
||||||
var k = m.SIMD.Bool32x4
|
var k = m.SIMD.Bool32x4
|
||||||
var g = m.SIMD.Int32x4
|
var g = m.SIMD.Int32x4
|
||||||
|
var gc = g.check;
|
||||||
var h = g.select
|
var h = g.select
|
||||||
function f() {
|
function f() {
|
||||||
var x = k(0, 0, 0, 0)
|
var x = k(0, 0, 0, 0)
|
||||||
var y = g(1, 2, 3, 4)
|
var y = g(1, 2, 3, 4)
|
||||||
return g(h(x, y, y))
|
return gc(h(x, y, y))
|
||||||
}
|
}
|
||||||
return f;
|
return f;
|
||||||
})(this)();
|
})(this)();
|
||||||
|
@ -36,6 +38,7 @@ t = (function(global) {
|
||||||
"use asm"
|
"use asm"
|
||||||
var toF = global.Math.fround
|
var toF = global.Math.fround
|
||||||
var f4 = global.SIMD.Float32x4
|
var f4 = global.SIMD.Float32x4
|
||||||
|
var f4c = f4.check
|
||||||
function p(x, y, width, value, max_iterations) {
|
function p(x, y, width, value, max_iterations) {
|
||||||
x = x | 0
|
x = x | 0
|
||||||
y = y | 0
|
y = y | 0
|
||||||
|
@ -50,7 +53,7 @@ t = (function(global) {
|
||||||
max_iterations = max_iterations | 0
|
max_iterations = max_iterations | 0
|
||||||
var _ = f4(0, 0, 0, 0), c_im4 = f4(0, 0, 0, 0)
|
var _ = f4(0, 0, 0, 0), c_im4 = f4(0, 0, 0, 0)
|
||||||
c_im4 = f4(yf, yd, yd, yf)
|
c_im4 = f4(yf, yd, yd, yf)
|
||||||
return f4(c_im4);
|
return f4c(c_im4);
|
||||||
}
|
}
|
||||||
return {p:p,m:m};
|
return {p:p,m:m};
|
||||||
})(this)
|
})(this)
|
||||||
|
|
|
@ -471,6 +471,7 @@ MSG_DEF(JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED, 0, JSEXN_TYPEERR, "handle unattache
|
||||||
MSG_DEF(JSMSG_TYPEDOBJECT_STRUCTTYPE_BAD_ARGS, 0, JSEXN_RANGEERR, "invalid field descriptor")
|
MSG_DEF(JSMSG_TYPEDOBJECT_STRUCTTYPE_BAD_ARGS, 0, JSEXN_RANGEERR, "invalid field descriptor")
|
||||||
MSG_DEF(JSMSG_TYPEDOBJECT_TOO_BIG, 0, JSEXN_ERR, "Type is too large to allocate")
|
MSG_DEF(JSMSG_TYPEDOBJECT_TOO_BIG, 0, JSEXN_ERR, "Type is too large to allocate")
|
||||||
MSG_DEF(JSMSG_SIMD_FAILED_CONVERSION, 0, JSEXN_RANGEERR, "SIMD conversion loses precision")
|
MSG_DEF(JSMSG_SIMD_FAILED_CONVERSION, 0, JSEXN_RANGEERR, "SIMD conversion loses precision")
|
||||||
|
MSG_DEF(JSMSG_SIMD_TO_NUMBER, 0, JSEXN_TYPEERR, "can't convert SIMD value to number")
|
||||||
|
|
||||||
// Typed array
|
// Typed array
|
||||||
MSG_DEF(JSMSG_BAD_INDEX, 0, JSEXN_RANGEERR, "invalid or out-of-range index")
|
MSG_DEF(JSMSG_BAD_INDEX, 0, JSEXN_RANGEERR, "invalid or out-of-range index")
|
||||||
|
|
|
@ -13,49 +13,75 @@ function test() {
|
||||||
assertThrowsInstanceOf(() => ts.call(5), TypeError);
|
assertThrowsInstanceOf(() => ts.call(5), TypeError);
|
||||||
assertThrowsInstanceOf(() => ts.call({}), TypeError);
|
assertThrowsInstanceOf(() => ts.call({}), TypeError);
|
||||||
|
|
||||||
|
// Can't convert SIMD objects to numbers.
|
||||||
|
assertThrowsInstanceOf(() => +f, TypeError);
|
||||||
|
assertThrowsInstanceOf(() => f.valueOf(), TypeError);
|
||||||
|
|
||||||
var Float64x2 = SIMD.Float64x2;
|
var Float64x2 = SIMD.Float64x2;
|
||||||
var f = Float64x2(11, 22);
|
var f = Float64x2(11, 22);
|
||||||
assertEq(f.toString(), "SIMD.Float64x2(11, 22)");
|
assertEq(f.toString(), "SIMD.Float64x2(11, 22)");
|
||||||
|
assertThrowsInstanceOf(() => +f, TypeError);
|
||||||
|
assertThrowsInstanceOf(() => f.valueOf(), TypeError);
|
||||||
|
|
||||||
var Int8x16 = SIMD.Int8x16;
|
var Int8x16 = SIMD.Int8x16;
|
||||||
var f = Int8x16(11, 22, 33, 44, -11, -22, -33, -44, 1, 2, 3, 4, -1, -2, -3, -4);
|
var f = Int8x16(11, 22, 33, 44, -11, -22, -33, -44, 1, 2, 3, 4, -1, -2, -3, -4);
|
||||||
assertEq(f.toString(), "SIMD.Int8x16(11, 22, 33, 44, -11, -22, -33, -44, 1, 2, 3, 4, -1, -2, -3, -4)");
|
assertEq(f.toString(), "SIMD.Int8x16(11, 22, 33, 44, -11, -22, -33, -44, 1, 2, 3, 4, -1, -2, -3, -4)");
|
||||||
|
assertThrowsInstanceOf(() => +f, TypeError);
|
||||||
|
assertThrowsInstanceOf(() => f.valueOf(), TypeError);
|
||||||
|
|
||||||
var Int16x8 = SIMD.Int16x8;
|
var Int16x8 = SIMD.Int16x8;
|
||||||
var f = Int16x8(11, 22, 33, 44, -11, -22, -33, -44);
|
var f = Int16x8(11, 22, 33, 44, -11, -22, -33, -44);
|
||||||
assertEq(f.toString(), "SIMD.Int16x8(11, 22, 33, 44, -11, -22, -33, -44)");
|
assertEq(f.toString(), "SIMD.Int16x8(11, 22, 33, 44, -11, -22, -33, -44)");
|
||||||
|
assertThrowsInstanceOf(() => +f, TypeError);
|
||||||
|
assertThrowsInstanceOf(() => f.valueOf(), TypeError);
|
||||||
|
|
||||||
var Int32x4 = SIMD.Int32x4;
|
var Int32x4 = SIMD.Int32x4;
|
||||||
var f = Int32x4(11, 22, 33, 44);
|
var f = Int32x4(11, 22, 33, 44);
|
||||||
assertEq(f.toString(), "SIMD.Int32x4(11, 22, 33, 44)");
|
assertEq(f.toString(), "SIMD.Int32x4(11, 22, 33, 44)");
|
||||||
|
assertThrowsInstanceOf(() => +f, TypeError);
|
||||||
|
assertThrowsInstanceOf(() => f.valueOf(), TypeError);
|
||||||
|
|
||||||
var Uint8x16 = SIMD.Uint8x16;
|
var Uint8x16 = SIMD.Uint8x16;
|
||||||
var f = Uint8x16(11, 22, 33, 44, 245, 234, 223, 212, 1, 2, 3, 4, 255, 254, 0, 250);
|
var f = Uint8x16(11, 22, 33, 44, 245, 234, 223, 212, 1, 2, 3, 4, 255, 254, 0, 250);
|
||||||
assertEq(f.toString(), "SIMD.Uint8x16(11, 22, 33, 44, 245, 234, 223, 212, 1, 2, 3, 4, 255, 254, 0, 250)");
|
assertEq(f.toString(), "SIMD.Uint8x16(11, 22, 33, 44, 245, 234, 223, 212, 1, 2, 3, 4, 255, 254, 0, 250)");
|
||||||
|
assertThrowsInstanceOf(() => +f, TypeError);
|
||||||
|
assertThrowsInstanceOf(() => f.valueOf(), TypeError);
|
||||||
|
|
||||||
var Uint16x8 = SIMD.Uint16x8;
|
var Uint16x8 = SIMD.Uint16x8;
|
||||||
var f = Uint16x8(11, 22, 33, 44, 65535, 65534, 65533, 65532);
|
var f = Uint16x8(11, 22, 33, 44, 65535, 65534, 65533, 65532);
|
||||||
assertEq(f.toString(), "SIMD.Uint16x8(11, 22, 33, 44, 65535, 65534, 65533, 65532)");
|
assertEq(f.toString(), "SIMD.Uint16x8(11, 22, 33, 44, 65535, 65534, 65533, 65532)");
|
||||||
|
assertThrowsInstanceOf(() => +f, TypeError);
|
||||||
|
assertThrowsInstanceOf(() => f.valueOf(), TypeError);
|
||||||
|
|
||||||
var Uint32x4 = SIMD.Uint32x4;
|
var Uint32x4 = SIMD.Uint32x4;
|
||||||
var f = Uint32x4(11, 22, 4294967295, 4294967294);
|
var f = Uint32x4(11, 22, 4294967295, 4294967294);
|
||||||
assertEq(f.toString(), "SIMD.Uint32x4(11, 22, 4294967295, 4294967294)");
|
assertEq(f.toString(), "SIMD.Uint32x4(11, 22, 4294967295, 4294967294)");
|
||||||
|
assertThrowsInstanceOf(() => +f, TypeError);
|
||||||
|
assertThrowsInstanceOf(() => f.valueOf(), TypeError);
|
||||||
|
|
||||||
var Bool8x16 = SIMD.Bool8x16;
|
var Bool8x16 = SIMD.Bool8x16;
|
||||||
var f = Bool8x16(true, true, false, false, false, true, true, false, true, true, true, true, false, false, false, false);
|
var f = Bool8x16(true, true, false, false, false, true, true, false, true, true, true, true, false, false, false, false);
|
||||||
assertEq(f.toString(), "SIMD.Bool8x16(true, true, false, false, false, true, true, false, true, true, true, true, false, false, false, false)");
|
assertEq(f.toString(), "SIMD.Bool8x16(true, true, false, false, false, true, true, false, true, true, true, true, false, false, false, false)");
|
||||||
|
assertThrowsInstanceOf(() => +f, TypeError);
|
||||||
|
assertThrowsInstanceOf(() => f.valueOf(), TypeError);
|
||||||
|
|
||||||
var Bool16x8 = SIMD.Bool16x8;
|
var Bool16x8 = SIMD.Bool16x8;
|
||||||
var f = Bool16x8(true, true, false, false, true, false, false, true);
|
var f = Bool16x8(true, true, false, false, true, false, false, true);
|
||||||
assertEq(f.toString(), "SIMD.Bool16x8(true, true, false, false, true, false, false, true)");
|
assertEq(f.toString(), "SIMD.Bool16x8(true, true, false, false, true, false, false, true)");
|
||||||
|
assertThrowsInstanceOf(() => +f, TypeError);
|
||||||
|
assertThrowsInstanceOf(() => f.valueOf(), TypeError);
|
||||||
|
|
||||||
var Bool32x4 = SIMD.Bool32x4;
|
var Bool32x4 = SIMD.Bool32x4;
|
||||||
var f = Bool32x4(true, true, false, false);
|
var f = Bool32x4(true, true, false, false);
|
||||||
assertEq(f.toString(), "SIMD.Bool32x4(true, true, false, false)");
|
assertEq(f.toString(), "SIMD.Bool32x4(true, true, false, false)");
|
||||||
|
assertThrowsInstanceOf(() => +f, TypeError);
|
||||||
|
assertThrowsInstanceOf(() => f.valueOf(), TypeError);
|
||||||
|
|
||||||
var Bool64x2 = SIMD.Bool64x2;
|
var Bool64x2 = SIMD.Bool64x2;
|
||||||
var f = Bool64x2(true, false);
|
var f = Bool64x2(true, false);
|
||||||
assertEq(f.toString(), "SIMD.Bool64x2(true, false)");
|
assertEq(f.toString(), "SIMD.Bool64x2(true, false)");
|
||||||
|
assertThrowsInstanceOf(() => +f, TypeError);
|
||||||
|
assertThrowsInstanceOf(() => f.valueOf(), TypeError);
|
||||||
|
|
||||||
if (typeof reportCompare === "function")
|
if (typeof reportCompare === "function")
|
||||||
reportCompare(true, true);
|
reportCompare(true, true);
|
||||||
|
|
|
@ -31,11 +31,11 @@ namespace js {
|
||||||
*
|
*
|
||||||
* (If you're wondering, 0xb973c0de is used because it looks like "bytecode".)
|
* (If you're wondering, 0xb973c0de is used because it looks like "bytecode".)
|
||||||
*/
|
*/
|
||||||
static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 352;
|
static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 353;
|
||||||
static const uint32_t XDR_BYTECODE_VERSION =
|
static const uint32_t XDR_BYTECODE_VERSION =
|
||||||
uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND);
|
uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND);
|
||||||
|
|
||||||
static_assert(JSErr_Limit == 419,
|
static_assert(JSErr_Limit == 420,
|
||||||
"GREETINGS, POTENTIAL SUBTRAHEND INCREMENTER! If you added or "
|
"GREETINGS, POTENTIAL SUBTRAHEND INCREMENTER! If you added or "
|
||||||
"removed MSG_DEFs from js.msg, you should increment "
|
"removed MSG_DEFs from js.msg, you should increment "
|
||||||
"XDR_BYTECODE_VERSION_SUBTRAHEND and update this assertion's "
|
"XDR_BYTECODE_VERSION_SUBTRAHEND and update this assertion's "
|
||||||
|
|
Загрузка…
Ссылка в новой задаче