Bug 1248555: Addendum: support uncanonicalized NaNs in globals too; r=luke

MozReview-Commit-ID: JKIUhXBhJRe

--HG--
extra : rebase_source : bd5dc7a4c9ad4ac483fa48cf82c283d3a39fc8fe
This commit is contained in:
Benjamin Bouvier 2016-09-21 19:18:51 +02:00
parent 484b067500
commit b880d025fd
5 changed files with 64 additions and 10 deletions

View File

@ -505,8 +505,8 @@ Instance::memoryLength() const
}
template<typename T>
static JSObject*
CreateCustomNaNObject(JSContext* cx, T* addr)
JSObject*
js::wasm::CreateCustomNaNObject(JSContext* cx, T* addr)
{
MOZ_ASSERT(IsNaN(*addr));
@ -528,8 +528,11 @@ CreateCustomNaNObject(JSContext* cx, T* addr)
return obj;
}
static bool
ReadCustomFloat32NaNObject(JSContext* cx, HandleValue v, uint32_t* ret)
template JSObject* js::wasm::CreateCustomNaNObject(JSContext* cx, float* addr);
template JSObject* js::wasm::CreateCustomNaNObject(JSContext* cx, double* addr);
bool
js::wasm::ReadCustomFloat32NaNObject(JSContext* cx, HandleValue v, uint32_t* ret)
{
RootedObject obj(cx, &v.toObject());
RootedValue val(cx);
@ -544,8 +547,8 @@ ReadCustomFloat32NaNObject(JSContext* cx, HandleValue v, uint32_t* ret)
return true;
}
static bool
ReadCustomDoubleNaNObject(JSContext* cx, HandleValue v, uint64_t* ret)
bool
js::wasm::ReadCustomDoubleNaNObject(JSContext* cx, HandleValue v, uint64_t* ret)
{
RootedObject obj(cx, &v.toObject());
RootedValue val(cx);

View File

@ -139,6 +139,25 @@ class Instance
typedef UniquePtr<Instance> UniqueInstance;
// Converts a testing-only NaN JS object with a nan_low field to a float32 NaN
// with nan_low as the payload.
bool
ReadCustomFloat32NaNObject(JSContext* cx, HandleValue v, uint32_t* ret);
// Converts a testing-only NaN JS object with nan_{low,high} components to a
// double NaN with nan_low|(nan_high)>>32 as the payload.
bool
ReadCustomDoubleNaNObject(JSContext* cx, HandleValue v, uint64_t* ret);
// Creates a testing-only NaN JS object with fields as described above, for
// T=float or T=double.
template<typename T>
JSObject*
CreateCustomNaNObject(JSContext* cx, T* addr);
} // namespace wasm
} // namespace js

View File

@ -2027,10 +2027,10 @@ EmitGetGlobal(FunctionCompiler& f)
result = f.constant(int64_t(value.i64()));
break;
case ValType::F32:
result = f.constant(Float32Value(value.f32().fp()), mirType);
result = f.constant(value.f32());
break;
case ValType::F64:
result = f.constant(DoubleValue(value.f64().fp()), mirType);
result = f.constant(value.f64());
break;
case ValType::I8x16:
result = f.constant(SimdConstant::CreateX16(value.i8x16()), mirType);

View File

@ -161,6 +161,13 @@ GetImports(JSContext* cx,
break;
}
case ValType::F32: {
if (JitOptions.wasmTestMode && v.isObject()) {
uint32_t bits;
if (!ReadCustomFloat32NaNObject(cx, v, &bits))
return false;
val = Val(RawF32::fromBits(bits));
break;
}
double d;
if (!ToNumber(cx, v, &d))
return false;
@ -168,6 +175,13 @@ GetImports(JSContext* cx,
break;
}
case ValType::F64: {
if (JitOptions.wasmTestMode && v.isObject()) {
uint64_t bits;
if (!ReadCustomDoubleNaNObject(cx, v, &bits))
return false;
val = Val(RawF64::fromBits(bits));
break;
}
double d;
if (!ToNumber(cx, v, &d))
return false;

View File

@ -714,11 +714,29 @@ GetGlobalExport(JSContext* cx, const GlobalDescVector& globals, uint32_t globalI
return true;
}
case ValType::F32: {
jsval.set(DoubleValue(double(val.f32().fp())));
float f = val.f32().fp();
if (JitOptions.wasmTestMode && IsNaN(f)) {
uint32_t bits = val.f32().bits();
RootedObject obj(cx, CreateCustomNaNObject(cx, (float*)&bits));
if (!obj)
return false;
jsval.set(ObjectValue(*obj));
return true;
}
jsval.set(DoubleValue(double(f)));
return true;
}
case ValType::F64: {
jsval.set(DoubleValue(val.f64().fp()));
double d = val.f64().fp();
if (JitOptions.wasmTestMode && IsNaN(d)) {
uint64_t bits = val.f64().bits();
RootedObject obj(cx, CreateCustomNaNObject(cx, (double*)&bits));
if (!obj)
return false;
jsval.set(ObjectValue(*obj));
return true;
}
jsval.set(DoubleValue(d));
return true;
}
default: {