mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-22 17:55:50 +00:00
Bug 1445272: Add (entry/exit) stubs support for anyref; r=luke
--HG-- extra : rebase_source : 1d4e3f43414a718d739efbe4907c1a1c85f261f8
This commit is contained in:
parent
8d30a725fa
commit
a45951f2cd
@ -95,6 +95,7 @@ class JSFunction : public js::NativeObject
|
|||||||
NATIVE_CLASS_CTOR = NATIVE_FUN | CONSTRUCTOR | CLASSCONSTRUCTOR_KIND,
|
NATIVE_CLASS_CTOR = NATIVE_FUN | CONSTRUCTOR | CLASSCONSTRUCTOR_KIND,
|
||||||
ASMJS_CTOR = ASMJS_KIND | NATIVE_CTOR,
|
ASMJS_CTOR = ASMJS_KIND | NATIVE_CTOR,
|
||||||
ASMJS_LAMBDA_CTOR = ASMJS_KIND | NATIVE_CTOR | LAMBDA,
|
ASMJS_LAMBDA_CTOR = ASMJS_KIND | NATIVE_CTOR | LAMBDA,
|
||||||
|
ASMJS_NATIVE = ASMJS_KIND | NATIVE_FUN,
|
||||||
WASM_FUN = NATIVE_FUN | WASM_OPTIMIZED,
|
WASM_FUN = NATIVE_FUN | WASM_OPTIMIZED,
|
||||||
INTERPRETED_METHOD = INTERPRETED | METHOD_KIND,
|
INTERPRETED_METHOD = INTERPRETED | METHOD_KIND,
|
||||||
INTERPRETED_METHOD_GENERATOR_OR_ASYNC = INTERPRETED | METHOD_KIND,
|
INTERPRETED_METHOD_GENERATOR_OR_ASYNC = INTERPRETED | METHOD_KIND,
|
||||||
|
@ -536,6 +536,9 @@ AddressOf(SymbolicAddress imm, ABIFunctionType* abiType)
|
|||||||
case SymbolicAddress::CallImport_F64:
|
case SymbolicAddress::CallImport_F64:
|
||||||
*abiType = Args_General4;
|
*abiType = Args_General4;
|
||||||
return FuncCast(Instance::callImport_f64, *abiType);
|
return FuncCast(Instance::callImport_f64, *abiType);
|
||||||
|
case SymbolicAddress::CallImport_Ref:
|
||||||
|
*abiType = Args_General4;
|
||||||
|
return FuncCast(Instance::callImport_ref, *abiType);
|
||||||
case SymbolicAddress::CoerceInPlace_ToInt32:
|
case SymbolicAddress::CoerceInPlace_ToInt32:
|
||||||
*abiType = Args_General1;
|
*abiType = Args_General1;
|
||||||
return FuncCast(CoerceInPlace_ToInt32, *abiType);
|
return FuncCast(CoerceInPlace_ToInt32, *abiType);
|
||||||
@ -690,6 +693,7 @@ wasm::NeedsBuiltinThunk(SymbolicAddress sym)
|
|||||||
case SymbolicAddress::CallImport_I32:
|
case SymbolicAddress::CallImport_I32:
|
||||||
case SymbolicAddress::CallImport_I64:
|
case SymbolicAddress::CallImport_I64:
|
||||||
case SymbolicAddress::CallImport_F64:
|
case SymbolicAddress::CallImport_F64:
|
||||||
|
case SymbolicAddress::CallImport_Ref:
|
||||||
case SymbolicAddress::CoerceInPlace_ToInt32: // GenerateImportJitExit
|
case SymbolicAddress::CoerceInPlace_ToInt32: // GenerateImportJitExit
|
||||||
case SymbolicAddress::CoerceInPlace_ToNumber:
|
case SymbolicAddress::CoerceInPlace_ToNumber:
|
||||||
#if defined(JS_CODEGEN_MIPS32)
|
#if defined(JS_CODEGEN_MIPS32)
|
||||||
|
@ -609,22 +609,25 @@ LazyStubSegment::addStubs(size_t codeLength, const Uint32Vector& funcExportIndic
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
for (DebugOnly<uint32_t> funcExportIndex : funcExportIndices) {
|
for (uint32_t funcExportIndex : funcExportIndices) {
|
||||||
const CodeRange& interpRange = codeRanges[i];
|
const CodeRange& interpRange = codeRanges[i];
|
||||||
MOZ_ASSERT(interpRange.isInterpEntry());
|
MOZ_ASSERT(interpRange.isInterpEntry());
|
||||||
MOZ_ASSERT(interpRange.funcIndex() == funcExports[funcExportIndex].funcIndex());
|
MOZ_ASSERT(interpRange.funcIndex() == funcExports[funcExportIndex].funcIndex());
|
||||||
|
|
||||||
codeRanges_.infallibleAppend(interpRange);
|
codeRanges_.infallibleAppend(interpRange);
|
||||||
codeRanges_.back().offsetBy(offsetInSegment);
|
codeRanges_.back().offsetBy(offsetInSegment);
|
||||||
|
i++;
|
||||||
|
|
||||||
const CodeRange& jitRange = codeRanges[i + 1];
|
if (funcExports[funcExportIndex].sig().temporarilyUnsupportedAnyRef())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const CodeRange& jitRange = codeRanges[i];
|
||||||
MOZ_ASSERT(jitRange.isJitEntry());
|
MOZ_ASSERT(jitRange.isJitEntry());
|
||||||
MOZ_ASSERT(jitRange.funcIndex() == interpRange.funcIndex());
|
MOZ_ASSERT(jitRange.funcIndex() == interpRange.funcIndex());
|
||||||
|
|
||||||
codeRanges_.infallibleAppend(jitRange);
|
codeRanges_.infallibleAppend(jitRange);
|
||||||
codeRanges_.back().offsetBy(offsetInSegment);
|
codeRanges_.back().offsetBy(offsetInSegment);
|
||||||
|
i++;
|
||||||
i += 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -673,8 +676,10 @@ LazyStubTier::createMany(const Uint32Vector& funcExportIndices, const CodeTier&
|
|||||||
uint8_t* moduleSegmentBase = codeTier.segment().base();
|
uint8_t* moduleSegmentBase = codeTier.segment().base();
|
||||||
|
|
||||||
CodeRangeVector codeRanges;
|
CodeRangeVector codeRanges;
|
||||||
|
DebugOnly<uint32_t> numExpectedRanges = 0;
|
||||||
for (uint32_t funcExportIndex : funcExportIndices) {
|
for (uint32_t funcExportIndex : funcExportIndices) {
|
||||||
const FuncExport& fe = funcExports[funcExportIndex];
|
const FuncExport& fe = funcExports[funcExportIndex];
|
||||||
|
numExpectedRanges += fe.sig().temporarilyUnsupportedAnyRef() ? 1 : 2;
|
||||||
void* calleePtr = moduleSegmentBase +
|
void* calleePtr = moduleSegmentBase +
|
||||||
moduleRanges[fe.interpCodeRangeIndex()].funcNormalEntry();
|
moduleRanges[fe.interpCodeRangeIndex()].funcNormalEntry();
|
||||||
Maybe<ImmPtr> callee;
|
Maybe<ImmPtr> callee;
|
||||||
@ -682,7 +687,7 @@ LazyStubTier::createMany(const Uint32Vector& funcExportIndices, const CodeTier&
|
|||||||
if (!GenerateEntryStubs(masm, funcExportIndex, fe, callee, /* asmjs*/ false, &codeRanges))
|
if (!GenerateEntryStubs(masm, funcExportIndex, fe, callee, /* asmjs*/ false, &codeRanges))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(codeRanges.length() == 2 * funcExportIndices.length(), "two entries per function");
|
MOZ_ASSERT(codeRanges.length() == numExpectedRanges, "incorrect number of entries per function");
|
||||||
|
|
||||||
masm.finish();
|
masm.finish();
|
||||||
|
|
||||||
@ -743,7 +748,9 @@ LazyStubTier::createMany(const Uint32Vector& funcExportIndices, const CodeTier&
|
|||||||
fe.funcIndex(), &exportIndex));
|
fe.funcIndex(), &exportIndex));
|
||||||
MOZ_ALWAYS_TRUE(exports_.insert(exports_.begin() + exportIndex, Move(lazyExport)));
|
MOZ_ALWAYS_TRUE(exports_.insert(exports_.begin() + exportIndex, Move(lazyExport)));
|
||||||
|
|
||||||
interpRangeIndex += 2;
|
// Functions with anyref in their sig have only one entry (interp).
|
||||||
|
// All other functions get an extra jit entry.
|
||||||
|
interpRangeIndex += fe.sig().temporarilyUnsupportedAnyRef() ? 1 : 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -763,6 +770,13 @@ LazyStubTier::createOne(uint32_t funcExportIndex, const CodeTier& codeTier)
|
|||||||
const UniqueLazyStubSegment& segment = stubSegments_[stubSegmentIndex];
|
const UniqueLazyStubSegment& segment = stubSegments_[stubSegmentIndex];
|
||||||
const CodeRangeVector& codeRanges = segment->codeRanges();
|
const CodeRangeVector& codeRanges = segment->codeRanges();
|
||||||
|
|
||||||
|
// Functions that have anyref in their sig don't get a jit entry.
|
||||||
|
if (codeTier.metadata().funcExports[funcExportIndex].sig().temporarilyUnsupportedAnyRef()) {
|
||||||
|
MOZ_ASSERT(codeRanges.length() >= 1);
|
||||||
|
MOZ_ASSERT(codeRanges.back().isInterpEntry());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(codeRanges.length() >= 2);
|
MOZ_ASSERT(codeRanges.length() >= 2);
|
||||||
MOZ_ASSERT(codeRanges[codeRanges.length() - 2].isInterpEntry());
|
MOZ_ASSERT(codeRanges[codeRanges.length() - 2].isInterpEntry());
|
||||||
|
|
||||||
|
@ -1139,6 +1139,7 @@ ThunkedNativeToDescription(SymbolicAddress func)
|
|||||||
case SymbolicAddress::CallImport_I32:
|
case SymbolicAddress::CallImport_I32:
|
||||||
case SymbolicAddress::CallImport_I64:
|
case SymbolicAddress::CallImport_I64:
|
||||||
case SymbolicAddress::CallImport_F64:
|
case SymbolicAddress::CallImport_F64:
|
||||||
|
case SymbolicAddress::CallImport_Ref:
|
||||||
case SymbolicAddress::CoerceInPlace_ToInt32:
|
case SymbolicAddress::CoerceInPlace_ToInt32:
|
||||||
case SymbolicAddress::CoerceInPlace_ToNumber:
|
case SymbolicAddress::CoerceInPlace_ToNumber:
|
||||||
MOZ_ASSERT(!NeedsBuiltinThunk(func), "not in sync with NeedsBuiltinThunk");
|
MOZ_ASSERT(!NeedsBuiltinThunk(func), "not in sync with NeedsBuiltinThunk");
|
||||||
|
@ -133,6 +133,10 @@ Instance::callImport(JSContext* cx, uint32_t funcImportIndex, unsigned argc, con
|
|||||||
case ValType::F64:
|
case ValType::F64:
|
||||||
args[i].set(JS::CanonicalizedDoubleValue(*(double*)&argv[i]));
|
args[i].set(JS::CanonicalizedDoubleValue(*(double*)&argv[i]));
|
||||||
break;
|
break;
|
||||||
|
case ValType::AnyRef: {
|
||||||
|
args[i].set(ObjectOrNullValue(*(JSObject**)&argv[i]));
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ValType::I64:
|
case ValType::I64:
|
||||||
case ValType::I8x16:
|
case ValType::I8x16:
|
||||||
case ValType::I16x8:
|
case ValType::I16x8:
|
||||||
@ -188,23 +192,28 @@ Instance::callImport(JSContext* cx, uint32_t funcImportIndex, unsigned argc, con
|
|||||||
if (!TypeScript::ThisTypes(script)->hasType(TypeSet::UndefinedType()))
|
if (!TypeScript::ThisTypes(script)->hasType(TypeSet::UndefinedType()))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
// Functions with anyref in signature don't have a jit exit at the moment.
|
||||||
|
if (fi.sig().temporarilyUnsupportedAnyRef())
|
||||||
|
return true;
|
||||||
|
|
||||||
const ValTypeVector& importArgs = fi.sig().args();
|
const ValTypeVector& importArgs = fi.sig().args();
|
||||||
|
|
||||||
size_t numKnownArgs = Min(importArgs.length(), importFun->nargs());
|
size_t numKnownArgs = Min(importArgs.length(), importFun->nargs());
|
||||||
for (uint32_t i = 0; i < numKnownArgs; i++) {
|
for (uint32_t i = 0; i < numKnownArgs; i++) {
|
||||||
TypeSet::Type type = TypeSet::UnknownType();
|
TypeSet::Type type = TypeSet::UnknownType();
|
||||||
switch (importArgs[i]) {
|
switch (importArgs[i]) {
|
||||||
case ValType::I32: type = TypeSet::Int32Type(); break;
|
case ValType::I32: type = TypeSet::Int32Type(); break;
|
||||||
case ValType::F32: type = TypeSet::DoubleType(); break;
|
case ValType::F32: type = TypeSet::DoubleType(); break;
|
||||||
case ValType::F64: type = TypeSet::DoubleType(); break;
|
case ValType::F64: type = TypeSet::DoubleType(); break;
|
||||||
case ValType::I64: MOZ_CRASH("NYI");
|
case ValType::AnyRef: MOZ_CRASH("case guarded above");
|
||||||
case ValType::I8x16: MOZ_CRASH("NYI");
|
case ValType::I64: MOZ_CRASH("NYI");
|
||||||
case ValType::I16x8: MOZ_CRASH("NYI");
|
case ValType::I8x16: MOZ_CRASH("NYI");
|
||||||
case ValType::I32x4: MOZ_CRASH("NYI");
|
case ValType::I16x8: MOZ_CRASH("NYI");
|
||||||
case ValType::F32x4: MOZ_CRASH("NYI");
|
case ValType::I32x4: MOZ_CRASH("NYI");
|
||||||
case ValType::B8x16: MOZ_CRASH("NYI");
|
case ValType::F32x4: MOZ_CRASH("NYI");
|
||||||
case ValType::B16x8: MOZ_CRASH("NYI");
|
case ValType::B8x16: MOZ_CRASH("NYI");
|
||||||
case ValType::B32x4: MOZ_CRASH("NYI");
|
case ValType::B16x8: MOZ_CRASH("NYI");
|
||||||
|
case ValType::B32x4: MOZ_CRASH("NYI");
|
||||||
}
|
}
|
||||||
if (!TypeScript::ArgTypes(script, i)->hasType(type))
|
if (!TypeScript::ArgTypes(script, i)->hasType(type))
|
||||||
return true;
|
return true;
|
||||||
@ -265,6 +274,31 @@ Instance::callImport_f64(Instance* instance, int32_t funcImportIndex, int32_t ar
|
|||||||
return ToNumber(cx, rval, (double*)argv);
|
return ToNumber(cx, rval, (double*)argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
ToRef(JSContext* cx, HandleValue val, void* addr)
|
||||||
|
{
|
||||||
|
if (val.isNull()) {
|
||||||
|
*(JSObject**)addr = nullptr;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSObject* obj = ToObject(cx, val);
|
||||||
|
if (!obj)
|
||||||
|
return false;
|
||||||
|
*(JSObject**)addr = obj;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ int32_t
|
||||||
|
Instance::callImport_ref(Instance* instance, int32_t funcImportIndex, int32_t argc, uint64_t* argv)
|
||||||
|
{
|
||||||
|
JSContext* cx = TlsContext.get();
|
||||||
|
RootedValue rval(cx);
|
||||||
|
if (!instance->callImport(cx, funcImportIndex, argc, argv, &rval))
|
||||||
|
return false;
|
||||||
|
return ToRef(cx, rval, argv);
|
||||||
|
}
|
||||||
|
|
||||||
/* static */ uint32_t
|
/* static */ uint32_t
|
||||||
Instance::growMemory_i32(Instance* instance, uint32_t delta)
|
Instance::growMemory_i32(Instance* instance, uint32_t delta)
|
||||||
{
|
{
|
||||||
@ -672,6 +706,11 @@ Instance::callExport(JSContext* cx, uint32_t funcIndex, CallArgs args)
|
|||||||
if (!ToNumber(cx, v, (double*)&exportArgs[i]))
|
if (!ToNumber(cx, v, (double*)&exportArgs[i]))
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
|
case ValType::AnyRef: {
|
||||||
|
if (!ToRef(cx, v, &exportArgs[i]))
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ValType::I8x16: {
|
case ValType::I8x16: {
|
||||||
SimdConstant simd;
|
SimdConstant simd;
|
||||||
if (!ToSimdConstant<Int8x16>(cx, v, &simd))
|
if (!ToSimdConstant<Int8x16>(cx, v, &simd))
|
||||||
@ -755,6 +794,8 @@ Instance::callExport(JSContext* cx, uint32_t funcIndex, CallArgs args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void* retAddr = &exportArgs[0];
|
void* retAddr = &exportArgs[0];
|
||||||
|
|
||||||
|
bool expectsObject = false;
|
||||||
JSObject* retObj = nullptr;
|
JSObject* retObj = nullptr;
|
||||||
switch (func.sig().ret()) {
|
switch (func.sig().ret()) {
|
||||||
case ExprType::Void:
|
case ExprType::Void:
|
||||||
@ -771,6 +812,10 @@ Instance::callExport(JSContext* cx, uint32_t funcIndex, CallArgs args)
|
|||||||
case ExprType::F64:
|
case ExprType::F64:
|
||||||
args.rval().set(NumberValue(*(double*)retAddr));
|
args.rval().set(NumberValue(*(double*)retAddr));
|
||||||
break;
|
break;
|
||||||
|
case ExprType::AnyRef:
|
||||||
|
retObj = *(JSObject**)retAddr;
|
||||||
|
expectsObject = true;
|
||||||
|
break;
|
||||||
case ExprType::I8x16:
|
case ExprType::I8x16:
|
||||||
retObj = CreateSimd<Int8x16>(cx, (int8_t*)retAddr);
|
retObj = CreateSimd<Int8x16>(cx, (int8_t*)retAddr);
|
||||||
if (!retObj)
|
if (!retObj)
|
||||||
@ -810,7 +855,9 @@ Instance::callExport(JSContext* cx, uint32_t funcIndex, CallArgs args)
|
|||||||
MOZ_CRASH("Limit");
|
MOZ_CRASH("Limit");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (retObj)
|
if (expectsObject)
|
||||||
|
args.rval().set(ObjectOrNullValue(retObj));
|
||||||
|
else if (retObj)
|
||||||
args.rval().set(ObjectValue(*retObj));
|
args.rval().set(ObjectValue(*retObj));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -164,6 +164,7 @@ class Instance
|
|||||||
static int32_t callImport_i32(Instance*, int32_t, int32_t, uint64_t*);
|
static int32_t callImport_i32(Instance*, int32_t, int32_t, uint64_t*);
|
||||||
static int32_t callImport_i64(Instance*, int32_t, int32_t, uint64_t*);
|
static int32_t callImport_i64(Instance*, int32_t, int32_t, uint64_t*);
|
||||||
static int32_t callImport_f64(Instance*, int32_t, int32_t, uint64_t*);
|
static int32_t callImport_f64(Instance*, int32_t, int32_t, uint64_t*);
|
||||||
|
static int32_t callImport_ref(Instance*, int32_t, int32_t, uint64_t*);
|
||||||
static uint32_t growMemory_i32(Instance* instance, uint32_t delta);
|
static uint32_t growMemory_i32(Instance* instance, uint32_t delta);
|
||||||
static uint32_t currentMemory_i32(Instance* instance);
|
static uint32_t currentMemory_i32(Instance* instance);
|
||||||
static int32_t wait_i32(Instance* instance, uint32_t byteOffset, int32_t value, int64_t timeout);
|
static int32_t wait_i32(Instance* instance, uint32_t byteOffset, int32_t value, int64_t timeout);
|
||||||
|
@ -1291,11 +1291,23 @@ WasmInstanceObject::getExportedFunction(JSContext* cx, HandleWasmInstanceObject
|
|||||||
RootedAtom name(cx, NumberToAtom(cx, funcIndex));
|
RootedAtom name(cx, NumberToAtom(cx, funcIndex));
|
||||||
if (!name)
|
if (!name)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Functions with anyref don't have jit entries yet, so they should
|
||||||
|
// mostly behave like asm.js functions. Pretend it's the case, until
|
||||||
|
// jit entries are implemented.
|
||||||
|
JSFunction::Flags flags = sig.temporarilyUnsupportedAnyRef()
|
||||||
|
? JSFunction::ASMJS_NATIVE
|
||||||
|
: JSFunction::WASM_FUN;
|
||||||
|
|
||||||
fun.set(NewNativeFunction(cx, WasmCall, numArgs, name, gc::AllocKind::FUNCTION_EXTENDED,
|
fun.set(NewNativeFunction(cx, WasmCall, numArgs, name, gc::AllocKind::FUNCTION_EXTENDED,
|
||||||
SingletonObject, JSFunction::WASM_FUN));
|
SingletonObject, flags));
|
||||||
if (!fun)
|
if (!fun)
|
||||||
return false;
|
return false;
|
||||||
fun->setWasmJitEntry(instance.code().getAddressOfJitEntry(funcIndex));
|
|
||||||
|
if (sig.temporarilyUnsupportedAnyRef())
|
||||||
|
fun->setAsmJSIndex(funcIndex);
|
||||||
|
else
|
||||||
|
fun->setWasmJitEntry(instance.code().getAddressOfJitEntry(funcIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
fun->setExtendedSlot(FunctionExtended::WASM_INSTANCE_SLOT, ObjectValue(*instanceObj));
|
fun->setExtendedSlot(FunctionExtended::WASM_INSTANCE_SLOT, ObjectValue(*instanceObj));
|
||||||
|
@ -92,6 +92,10 @@ SetupABIArguments(MacroAssembler& masm, const FuncExport& fe, Register argv, Reg
|
|||||||
masm.load32(src, iter->gpr());
|
masm.load32(src, iter->gpr());
|
||||||
else if (type == MIRType::Int64)
|
else if (type == MIRType::Int64)
|
||||||
masm.load64(src, iter->gpr64());
|
masm.load64(src, iter->gpr64());
|
||||||
|
else if (type == MIRType::Pointer)
|
||||||
|
masm.loadPtr(src, iter->gpr());
|
||||||
|
else
|
||||||
|
MOZ_CRASH("unknown GPR type");
|
||||||
break;
|
break;
|
||||||
#ifdef JS_CODEGEN_REGISTER_PAIR
|
#ifdef JS_CODEGEN_REGISTER_PAIR
|
||||||
case ABIArg::GPR_PAIR:
|
case ABIArg::GPR_PAIR:
|
||||||
@ -148,6 +152,10 @@ SetupABIArguments(MacroAssembler& masm, const FuncExport& fe, Register argv, Reg
|
|||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case MIRType::Pointer:
|
||||||
|
masm.loadPtr(src, scratch);
|
||||||
|
masm.storePtr(scratch, Address(masm.getStackPointer(), iter->offsetFromArgBase()));
|
||||||
|
break;
|
||||||
case MIRType::Double:
|
case MIRType::Double:
|
||||||
masm.loadDouble(src, ScratchDoubleReg);
|
masm.loadDouble(src, ScratchDoubleReg);
|
||||||
masm.storeDouble(ScratchDoubleReg,
|
masm.storeDouble(ScratchDoubleReg,
|
||||||
@ -204,6 +212,9 @@ StoreABIReturn(MacroAssembler& masm, const FuncExport& fe, Register argv)
|
|||||||
masm.canonicalizeDouble(ReturnDoubleReg);
|
masm.canonicalizeDouble(ReturnDoubleReg);
|
||||||
masm.storeDouble(ReturnDoubleReg, Address(argv, 0));
|
masm.storeDouble(ReturnDoubleReg, Address(argv, 0));
|
||||||
break;
|
break;
|
||||||
|
case ExprType::AnyRef:
|
||||||
|
masm.storePtr(ReturnReg, Address(argv, 0));
|
||||||
|
break;
|
||||||
case ExprType::I8x16:
|
case ExprType::I8x16:
|
||||||
case ExprType::I16x8:
|
case ExprType::I16x8:
|
||||||
case ExprType::I32x4:
|
case ExprType::I32x4:
|
||||||
@ -758,6 +769,9 @@ GenerateJitEntry(MacroAssembler& masm, size_t funcExportIndex, const FuncExport&
|
|||||||
masm.canonicalizeDouble(ReturnDoubleReg);
|
masm.canonicalizeDouble(ReturnDoubleReg);
|
||||||
masm.boxDouble(ReturnDoubleReg, JSReturnOperand, ScratchDoubleReg);
|
masm.boxDouble(ReturnDoubleReg, JSReturnOperand, ScratchDoubleReg);
|
||||||
break;
|
break;
|
||||||
|
case ExprType::AnyRef:
|
||||||
|
MOZ_CRASH("return anyref in jitentry NYI");
|
||||||
|
break;
|
||||||
case ExprType::I64:
|
case ExprType::I64:
|
||||||
case ExprType::I8x16:
|
case ExprType::I8x16:
|
||||||
case ExprType::I16x8:
|
case ExprType::I16x8:
|
||||||
@ -845,6 +859,9 @@ StackCopy(MacroAssembler& masm, MIRType type, Register scratch, Address src, Add
|
|||||||
masm.load64(src, scratch64);
|
masm.load64(src, scratch64);
|
||||||
masm.store64(scratch64, dst);
|
masm.store64(scratch64, dst);
|
||||||
#endif
|
#endif
|
||||||
|
} else if (type == MIRType::Pointer) {
|
||||||
|
masm.loadPtr(src, scratch);
|
||||||
|
masm.storePtr(scratch, dst);
|
||||||
} else if (type == MIRType::Float32) {
|
} else if (type == MIRType::Float32) {
|
||||||
masm.loadFloat32(src, ScratchFloat32Reg);
|
masm.loadFloat32(src, ScratchFloat32Reg);
|
||||||
masm.storeFloat32(ScratchFloat32Reg, dst);
|
masm.storeFloat32(ScratchFloat32Reg, dst);
|
||||||
@ -878,8 +895,10 @@ FillArgumentArray(MacroAssembler& masm, const ValTypeVector& args, unsigned argO
|
|||||||
masm.breakpoint();
|
masm.breakpoint();
|
||||||
else
|
else
|
||||||
masm.store64(i->gpr64(), dst);
|
masm.store64(i->gpr64(), dst);
|
||||||
} else {
|
} else if (type == MIRType::Pointer) {
|
||||||
MOZ_CRASH("unexpected input type?");
|
if (toValue)
|
||||||
|
MOZ_CRASH("generating a jit exit for anyref NYI");
|
||||||
|
masm.storePtr(i->gpr(), dst);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#ifdef JS_CODEGEN_REGISTER_PAIR
|
#ifdef JS_CODEGEN_REGISTER_PAIR
|
||||||
@ -926,6 +945,8 @@ FillArgumentArray(MacroAssembler& masm, const ValTypeVector& args, unsigned argO
|
|||||||
} else if (type == MIRType::Int64) {
|
} else if (type == MIRType::Int64) {
|
||||||
// We can't box int64 into Values (yet).
|
// We can't box int64 into Values (yet).
|
||||||
masm.breakpoint();
|
masm.breakpoint();
|
||||||
|
} else if (type == MIRType::Pointer) {
|
||||||
|
MOZ_CRASH("generating a jit exit for anyref NYI");
|
||||||
} else {
|
} else {
|
||||||
MOZ_ASSERT(IsFloatingPointType(type));
|
MOZ_ASSERT(IsFloatingPointType(type));
|
||||||
if (type == MIRType::Float32) {
|
if (type == MIRType::Float32) {
|
||||||
@ -1122,6 +1143,11 @@ GenerateImportInterpExit(MacroAssembler& masm, const FuncImport& fi, uint32_t fu
|
|||||||
masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel);
|
masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel);
|
||||||
masm.loadDouble(argv, ReturnDoubleReg);
|
masm.loadDouble(argv, ReturnDoubleReg);
|
||||||
break;
|
break;
|
||||||
|
case ExprType::AnyRef:
|
||||||
|
masm.call(SymbolicAddress::CallImport_Ref);
|
||||||
|
masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel);
|
||||||
|
masm.loadPtr(argv, ReturnReg);
|
||||||
|
break;
|
||||||
case ExprType::I8x16:
|
case ExprType::I8x16:
|
||||||
case ExprType::I16x8:
|
case ExprType::I16x8:
|
||||||
case ExprType::I32x4:
|
case ExprType::I32x4:
|
||||||
@ -1297,6 +1323,9 @@ GenerateImportJitExit(MacroAssembler& masm, const FuncImport& fi, Label* throwLa
|
|||||||
case ExprType::F64:
|
case ExprType::F64:
|
||||||
masm.convertValueToDouble(JSReturnOperand, ReturnDoubleReg, &oolConvert);
|
masm.convertValueToDouble(JSReturnOperand, ReturnDoubleReg, &oolConvert);
|
||||||
break;
|
break;
|
||||||
|
case ExprType::AnyRef:
|
||||||
|
MOZ_CRASH("anyref returned by import (jit exit) NYI");
|
||||||
|
break;
|
||||||
case ExprType::I8x16:
|
case ExprType::I8x16:
|
||||||
case ExprType::I16x8:
|
case ExprType::I16x8:
|
||||||
case ExprType::I32x4:
|
case ExprType::I32x4:
|
||||||
@ -1712,7 +1741,7 @@ wasm::GenerateEntryStubs(MacroAssembler& masm, size_t funcExportIndex, const Fun
|
|||||||
if (!codeRanges->emplaceBack(CodeRange::InterpEntry, fe.funcIndex(), offsets))
|
if (!codeRanges->emplaceBack(CodeRange::InterpEntry, fe.funcIndex(), offsets))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (isAsmJS)
|
if (isAsmJS || fe.sig().temporarilyUnsupportedAnyRef())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (!GenerateJitEntry(masm, funcExportIndex, fe, callee, &offsets))
|
if (!GenerateJitEntry(masm, funcExportIndex, fe, callee, &offsets))
|
||||||
@ -1748,6 +1777,9 @@ wasm::GenerateStubs(const ModuleEnvironment& env, const FuncImportVector& import
|
|||||||
if (!code->codeRanges.emplaceBack(CodeRange::ImportInterpExit, funcIndex, interpOffsets))
|
if (!code->codeRanges.emplaceBack(CodeRange::ImportInterpExit, funcIndex, interpOffsets))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (fi.sig().temporarilyUnsupportedAnyRef())
|
||||||
|
continue;
|
||||||
|
|
||||||
JitExitOffsets jitOffsets;
|
JitExitOffsets jitOffsets;
|
||||||
if (!GenerateImportJitExit(masm, fi, &throwLabel, &jitOffsets))
|
if (!GenerateImportJitExit(masm, fi, &throwLabel, &jitOffsets))
|
||||||
return false;
|
return false;
|
||||||
|
@ -591,8 +591,17 @@ class Sig
|
|||||||
bool hasI64ArgOrRet() const {
|
bool hasI64ArgOrRet() const {
|
||||||
if (ret() == ExprType::I64)
|
if (ret() == ExprType::I64)
|
||||||
return true;
|
return true;
|
||||||
for (ValType a : args()) {
|
for (ValType arg : args()) {
|
||||||
if (a == ValType::I64)
|
if (arg == ValType::I64)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool temporarilyUnsupportedAnyRef() const {
|
||||||
|
if (ret() == ExprType::AnyRef)
|
||||||
|
return true;
|
||||||
|
for (ValType arg : args()) {
|
||||||
|
if (arg == ValType::AnyRef)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -1459,6 +1468,7 @@ enum class SymbolicAddress
|
|||||||
CallImport_I32,
|
CallImport_I32,
|
||||||
CallImport_I64,
|
CallImport_I64,
|
||||||
CallImport_F64,
|
CallImport_F64,
|
||||||
|
CallImport_Ref,
|
||||||
CoerceInPlace_ToInt32,
|
CoerceInPlace_ToInt32,
|
||||||
CoerceInPlace_ToNumber,
|
CoerceInPlace_ToNumber,
|
||||||
CoerceInPlace_JitEntry,
|
CoerceInPlace_JitEntry,
|
||||||
|
Loading…
Reference in New Issue
Block a user