зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1292724 - Baldr: don't fail to validate i64 imports and exports; throw runtime errors (r=sunfish)
MozReview-Commit-ID: 8KDCNutTjnB --HG-- extra : rebase_source : 7175217d7ad93d6c2a26b022052961c4aa48170b
This commit is contained in:
Родитель
3bef492837
Коммит
f7ea839a1d
|
@ -587,24 +587,6 @@ DecodeFunctionSection(Decoder& d, ModuleGeneratorData* init)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
CheckTypeForJS(Decoder& d, const Sig& sig)
|
||||
{
|
||||
for (ValType argType : sig.args()) {
|
||||
if (argType == ValType::I64 && !JitOptions.wasmTestMode)
|
||||
return Fail(d, "cannot import/export i64 argument");
|
||||
if (IsSimdType(argType))
|
||||
return Fail(d, "cannot import/export SIMD argument");
|
||||
}
|
||||
|
||||
if (sig.ret() == ExprType::I64 && !JitOptions.wasmTestMode)
|
||||
return Fail(d, "cannot import/export i64 return type");
|
||||
if (IsSimdType(sig.ret()))
|
||||
return Fail(d, "cannot import/export SIMD return type");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static UniqueChars
|
||||
MaybeDecodeName(Decoder& d)
|
||||
{
|
||||
|
@ -766,9 +748,6 @@ DecodeImport(Decoder& d, bool newFormat, ModuleGeneratorData* init, ImportVector
|
|||
if (!DecodeSignatureIndex(d, *init, &sig))
|
||||
return false;
|
||||
|
||||
if (!CheckTypeForJS(d, *sig))
|
||||
return false;
|
||||
|
||||
if (!init->funcImports.emplaceBack(sig))
|
||||
return false;
|
||||
|
||||
|
@ -806,8 +785,6 @@ DecodeImport(Decoder& d, bool newFormat, ModuleGeneratorData* init, ImportVector
|
|||
const SigWithId* sig = nullptr;
|
||||
if (!DecodeSignatureIndex(d, *init, &sig))
|
||||
return false;
|
||||
if (!CheckTypeForJS(d, *sig))
|
||||
return false;
|
||||
if (!init->funcImports.emplaceBack(sig))
|
||||
return false;
|
||||
break;
|
||||
|
@ -1103,9 +1080,6 @@ DecodeExport(Decoder& d, bool newFormat, ModuleGenerator& mg, CStringSet* dupSet
|
|||
if (funcIndex >= mg.numFuncSigs())
|
||||
return Fail(d, "exported function index out of bounds");
|
||||
|
||||
if (!CheckTypeForJS(d, mg.funcSig(funcIndex)))
|
||||
return false;
|
||||
|
||||
UniqueChars fieldName = DecodeExportName(d, dupSet);
|
||||
if (!fieldName)
|
||||
return false;
|
||||
|
@ -1130,9 +1104,6 @@ DecodeExport(Decoder& d, bool newFormat, ModuleGenerator& mg, CStringSet* dupSet
|
|||
if (funcIndex >= mg.numFuncSigs())
|
||||
return Fail(d, "exported function index out of bounds");
|
||||
|
||||
if (!CheckTypeForJS(d, mg.funcSig(funcIndex)))
|
||||
return false;
|
||||
|
||||
return mg.addFuncExport(Move(fieldName), funcIndex);
|
||||
}
|
||||
case DefinitionKind::Table: {
|
||||
|
|
|
@ -133,7 +133,10 @@ Instance::callImport(JSContext* cx, uint32_t funcImportIndex, unsigned argc, con
|
|||
args[i].set(JS::CanonicalizedDoubleValue(*(double*)&argv[i]));
|
||||
break;
|
||||
case ValType::I64: {
|
||||
MOZ_ASSERT(JitOptions.wasmTestMode, "no int64 in asm.js/wasm");
|
||||
if (!JitOptions.wasmTestMode) {
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_I64);
|
||||
return false;
|
||||
}
|
||||
RootedObject obj(cx, CreateI64Object(cx, *(int64_t*)&argv[i]));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
@ -160,6 +163,12 @@ Instance::callImport(JSContext* cx, uint32_t funcImportIndex, unsigned argc, con
|
|||
if (!Call(cx, fval, thisv, args, rval))
|
||||
return false;
|
||||
|
||||
// Throw an error if returning i64 and not in test mode.
|
||||
if (!JitOptions.wasmTestMode && fi.sig().ret() == ExprType::I64) {
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_I64);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't try to optimize if the function has at least one i64 arg or if
|
||||
// it returns an int64. GenerateJitExit relies on this, as does the
|
||||
// type inference code below in this function.
|
||||
|
@ -539,7 +548,10 @@ Instance::callExport(JSContext* cx, uint32_t funcIndex, CallArgs args)
|
|||
return false;
|
||||
break;
|
||||
case ValType::I64:
|
||||
MOZ_ASSERT(JitOptions.wasmTestMode, "no int64 in asm.js/wasm");
|
||||
if (!JitOptions.wasmTestMode) {
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_I64);
|
||||
return false;
|
||||
}
|
||||
if (!ReadI64Object(cx, v, (int64_t*)&exportArgs[i]))
|
||||
return false;
|
||||
break;
|
||||
|
@ -655,7 +667,10 @@ Instance::callExport(JSContext* cx, uint32_t funcIndex, CallArgs args)
|
|||
args.rval().set(Int32Value(*(int32_t*)retAddr));
|
||||
break;
|
||||
case ExprType::I64:
|
||||
MOZ_ASSERT(JitOptions.wasmTestMode, "no int64 in asm.js/wasm");
|
||||
if (!JitOptions.wasmTestMode) {
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_I64);
|
||||
return false;
|
||||
}
|
||||
retObj = CreateI64Object(cx, *(int64_t*)retAddr);
|
||||
if (!retObj)
|
||||
return false;
|
||||
|
|
|
@ -168,7 +168,6 @@ wasm::GenerateEntry(MacroAssembler& masm, const FuncExport& fe)
|
|||
unsigned argOffset = iter.index() * sizeof(ExportArg);
|
||||
Address src(argv, argOffset);
|
||||
MIRType type = iter.mirType();
|
||||
MOZ_ASSERT_IF(type == MIRType::Int64, JitOptions.wasmTestMode);
|
||||
switch (iter->kind()) {
|
||||
case ABIArg::GPR:
|
||||
if (type == MIRType::Int32)
|
||||
|
@ -283,7 +282,6 @@ wasm::GenerateEntry(MacroAssembler& masm, const FuncExport& fe)
|
|||
masm.store32(ReturnReg, Address(argv, 0));
|
||||
break;
|
||||
case ExprType::I64:
|
||||
MOZ_ASSERT(JitOptions.wasmTestMode, "no int64 in asm.js/wasm");
|
||||
masm.store64(ReturnReg64, Address(argv, 0));
|
||||
break;
|
||||
case ExprType::F32:
|
||||
|
@ -334,8 +332,6 @@ FillArgumentArray(MacroAssembler& masm, const ValTypeVector& args, unsigned argO
|
|||
Address dstAddr(masm.getStackPointer(), argOffset + i.index() * sizeof(Value));
|
||||
|
||||
MIRType type = i.mirType();
|
||||
MOZ_ASSERT_IF(type == MIRType::Int64, JitOptions.wasmTestMode);
|
||||
|
||||
switch (i->kind()) {
|
||||
case ABIArg::GPR:
|
||||
if (type == MIRType::Int32) {
|
||||
|
@ -520,7 +516,6 @@ wasm::GenerateInterpExit(MacroAssembler& masm, const FuncImport& fi, uint32_t fu
|
|||
masm.load32(argv, ReturnReg);
|
||||
break;
|
||||
case ExprType::I64:
|
||||
MOZ_ASSERT(JitOptions.wasmTestMode);
|
||||
masm.call(SymbolicAddress::CallImport_I64);
|
||||
masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, JumpTarget::Throw);
|
||||
masm.load64(argv, ReturnReg64);
|
||||
|
@ -716,7 +711,6 @@ wasm::GenerateJitExit(MacroAssembler& masm, const FuncImport& fi)
|
|||
/* -0 check */ false);
|
||||
break;
|
||||
case ExprType::I64:
|
||||
MOZ_ASSERT(JitOptions.wasmTestMode, "no int64 in asm.js/wasm");
|
||||
// We don't expect int64 to be returned from Ion yet, because of a
|
||||
// guard in callImport.
|
||||
masm.breakpoint();
|
||||
|
|
|
@ -28,8 +28,6 @@ testConst('i32', '-0x80000000', -2147483648);
|
|||
testConst('i32', '0xffffffff', -1);
|
||||
|
||||
{
|
||||
assertErrorMessage(() => wasmEvalText('(module (func (result i64) (i64.const 0)) (export "" 0))'), TypeError, /cannot .* i64/);
|
||||
|
||||
setJitCompilerOption('wasm.test-mode', 1);
|
||||
|
||||
testConst('i64', '0', 0);
|
||||
|
@ -74,8 +72,6 @@ testConst('i32', '0xffffffff', -1);
|
|||
testConstError('i64', 'not an i64');
|
||||
|
||||
setJitCompilerOption('wasm.test-mode', 0);
|
||||
|
||||
assertErrorMessage(() => wasmEvalText('(module (func (result i64) (i64.const 0)) (export "" 0))'), TypeError, /cannot .* i64/);
|
||||
}
|
||||
|
||||
testConst('f32', '0.0', 0.0);
|
||||
|
|
|
@ -67,8 +67,15 @@ wasmEvalText('(module (func (result i32) (param i32) (i32.const 42)))');
|
|||
wasmEvalText('(module (func (param f32)))');
|
||||
wasmEvalText('(module (func (param f64)))');
|
||||
|
||||
assertErrorMessage(() => wasmEvalText('(module (func (param i64) (result i32) (i32.const 123)) (export "" 0))'), TypeError, /i64 argument/);
|
||||
assertErrorMessage(() => wasmEvalText('(module (func (param i32) (result i64) (i64.const 123)) (export "" 0))'), TypeError, /i64 return type/);
|
||||
var f = wasmEvalText('(module (func (param i64) (result i32) (i32.const 123)) (export "" 0))');
|
||||
assertErrorMessage(() => f(), TypeError, /i64/);
|
||||
var f = wasmEvalText('(module (func (param i32) (result i64) (i64.const 123)) (export "" 0))');
|
||||
assertErrorMessage(() => f(), TypeError, /i64/);
|
||||
|
||||
var f = wasmEvalText('(module (import $imp "a" "b" (param i64) (result i32)) (func $f (call_import $imp (i64.const 0))) (export "" $f))', {a:{b:()=>{}}});
|
||||
assertErrorMessage(() => f(), TypeError, /i64/);
|
||||
var f = wasmEvalText('(module (import $imp "a" "b" (result i64)) (func $f (call_import $imp)) (export "" $f))', {a:{b:()=>{}}});
|
||||
assertErrorMessage(() => f(), TypeError, /i64/);
|
||||
|
||||
setJitCompilerOption('wasm.test-mode', 1);
|
||||
assertEqI64(wasmEvalText('(module (func (result i64) (i64.const 123)) (export "" 0))')(), {low: 123, high: 0});
|
||||
|
@ -327,9 +334,6 @@ if (typeof evaluate === 'function')
|
|||
evaluate(`Wasm.instantiateModule(wasmTextToBinary('(module)')) `, { fileName: null });
|
||||
|
||||
{
|
||||
assertErrorMessage(() => wasmEvalText('(module (import "a" "" (param i64) (result i32)))'), TypeError, /i64 argument/);
|
||||
assertErrorMessage(() => wasmEvalText('(module (import "a" "" (result i64)))'), TypeError, /i64 return type/);
|
||||
|
||||
setJitCompilerOption('wasm.test-mode', 1);
|
||||
|
||||
let imp = {
|
||||
|
|
|
@ -287,6 +287,14 @@ assertEq(e1.foo, tbl.get(1));
|
|||
assertEq(tbl.get(0) === e1.foo, false);
|
||||
assertEq(e1.foo === e2.foo, false);
|
||||
|
||||
// i64 is fully allowed for imported wasm functions
|
||||
|
||||
var code1 = textToBinary('(module (func $exp (param i64) (result i64) (i64.add (get_local 0) (i64.const 10))) (export "exp" $exp))');
|
||||
var e1 = new Instance(new Module(code1)).exports;
|
||||
var code2 = textToBinary('(module (import $i "a" "b" (param i64) (result i64)) (func $f (result i32) (i32.wrap/i64 (call_import $i (i64.const 42)))) (export "f" $f))');
|
||||
var e2 = new Instance(new Module(code2), {a:{b:e1.exp}}).exports;
|
||||
assertEq(e2.f(), 52);
|
||||
|
||||
// Non-existent export errors
|
||||
|
||||
assertErrorMessage(() => new Module(textToBinary('(module (export "a" 0))')), TypeError, /exported function index out of bounds/);
|
||||
|
|
|
@ -356,6 +356,7 @@ MSG_DEF(JSMSG_WASM_BAD_IMPORT_ARG, 0, JSEXN_TYPEERR, "second argument, i
|
|||
MSG_DEF(JSMSG_WASM_BAD_IMPORT_FIELD, 1, JSEXN_TYPEERR, "import object field is not {0}")
|
||||
MSG_DEF(JSMSG_WASM_BAD_IMPORT_SIG, 0, JSEXN_TYPEERR, "imported function signature mismatch")
|
||||
MSG_DEF(JSMSG_WASM_BAD_SET_VALUE, 0, JSEXN_TYPEERR, "second argument must be null or an exported WebAssembly Function object")
|
||||
MSG_DEF(JSMSG_WASM_BAD_I64, 0, JSEXN_TYPEERR, "cannot pass i64 to or from JS")
|
||||
MSG_DEF(JSMSG_WASM_UNREACHABLE, 0, JSEXN_ERR, "unreachable executed")
|
||||
MSG_DEF(JSMSG_WASM_INTEGER_OVERFLOW, 0, JSEXN_ERR, "integer overflow")
|
||||
MSG_DEF(JSMSG_WASM_INVALID_CONVERSION, 0, JSEXN_ERR, "invalid conversion to integer")
|
||||
|
|
Загрузка…
Ссылка в новой задаче