зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1732782 - Fix Wasm exceptions JS API for layout changes. r=rhunt
Fixes how exception payloads are written to and read from exception objects using the JS API, which was broken when the Wasm instructions transitioned to using an alignment-aware tag type to find the offsets into the payload. Differential Revision: https://phabricator.services.mozilla.com/D126853
This commit is contained in:
Родитель
8e59b5f49b
Коммит
b0627b0ec2
|
@ -96,7 +96,7 @@ assertErrorMessage(
|
|||
/first argument must be a WebAssembly.Tag/
|
||||
);
|
||||
|
||||
const { tag1, tag2, tag3, tag4, tag5, tag6, tag7 } = wasmEvalText(
|
||||
const { tag1, tag2, tag3, tag4, tag5, tag6, tag7, tag8, tag9 } = wasmEvalText(
|
||||
`(module
|
||||
(tag (export "tag1") (param))
|
||||
(tag (export "tag2") (param i32))
|
||||
|
@ -104,7 +104,9 @@ const { tag1, tag2, tag3, tag4, tag5, tag6, tag7 } = wasmEvalText(
|
|||
(tag (export "tag4") (param i32 externref i32))
|
||||
(tag (export "tag5") (param i32 externref i32 externref))
|
||||
(tag (export "tag6") (param funcref))
|
||||
(tag (export "tag7") (param i64)))`
|
||||
(tag (export "tag7") (param i64))
|
||||
(tag (export "tag8") (param i32 f64))
|
||||
(tag (export "tag9") (param externref funcref)))`
|
||||
).exports;
|
||||
|
||||
new WebAssembly.Exception(tag1, []);
|
||||
|
@ -168,25 +170,23 @@ assertErrorMessage(
|
|||
const exn2 = new WebAssembly.Exception(tag2, [3]);
|
||||
assertEq(exn2.getArg(tag2, 0), 3);
|
||||
|
||||
assertEq(
|
||||
new WebAssembly.Exception(tag2, [undefined]).getArg(tag2, 0),
|
||||
0
|
||||
);
|
||||
assertEq(new WebAssembly.Exception(tag2, [undefined]).getArg(tag2, 0), 0);
|
||||
|
||||
const exn4 = new WebAssembly.Exception(tag4, [3, "foo", 4]);
|
||||
assertEq(exn4.getArg(tag4, 0), 3);
|
||||
assertEq(exn4.getArg(tag4, 1), "foo");
|
||||
assertEq(exn4.getArg(tag4, 2), 4);
|
||||
|
||||
const exn5 = new WebAssembly.Exception(
|
||||
tag5,
|
||||
[3,
|
||||
"foo",
|
||||
4,
|
||||
"bar"]
|
||||
);
|
||||
const exn5 = new WebAssembly.Exception(tag5, [3, "foo", 4, "bar"]);
|
||||
assertEq(exn5.getArg(tag5, 3), "bar");
|
||||
|
||||
const { funcref } = wasmEvalText(
|
||||
`(module (func (export "funcref")))`
|
||||
).exports;
|
||||
const exn9 = new WebAssembly.Exception(tag9, ["foo", funcref]);
|
||||
assertEq(exn9.getArg(tag9, 0), "foo");
|
||||
assertEq(exn9.getArg(tag9, 1), funcref);
|
||||
|
||||
assertErrorMessage(
|
||||
() => exn2.getArg(),
|
||||
TypeError,
|
||||
|
@ -257,6 +257,30 @@ assertEqArray(
|
|||
[42, 5.5]
|
||||
);
|
||||
|
||||
assertEqArray(
|
||||
wasmEvalText(
|
||||
`(module
|
||||
(import "m" "exn" (tag $exn (param i32 f64)))
|
||||
(import "m" "f" (func $f))
|
||||
(func (export "f") (result i32 f64)
|
||||
try (result i32 f64)
|
||||
call $f
|
||||
(i32.const 0)
|
||||
(f64.const 0)
|
||||
catch $exn
|
||||
end))`,
|
||||
{
|
||||
m: {
|
||||
exn: tag8,
|
||||
f: () => {
|
||||
throw new WebAssembly.Exception(tag8, [9999, 9999]);
|
||||
},
|
||||
},
|
||||
}
|
||||
).exports.f(),
|
||||
[9999, 9999]
|
||||
);
|
||||
|
||||
assertEqArray(
|
||||
wasmEvalText(
|
||||
`(module
|
||||
|
@ -282,6 +306,61 @@ assertEqArray(
|
|||
[42, "foo", 42]
|
||||
);
|
||||
|
||||
assertEqArray(
|
||||
wasmEvalText(
|
||||
`(module
|
||||
(import "m" "exn" (tag $exn (param i32 externref i32 externref)))
|
||||
(import "m" "f" (func $f))
|
||||
(func (export "f") (result i32 externref i32 externref)
|
||||
try (result i32 externref i32 externref)
|
||||
call $f
|
||||
(i32.const 0)
|
||||
(ref.null extern)
|
||||
(i32.const 0)
|
||||
(ref.null extern)
|
||||
catch $exn
|
||||
end))`,
|
||||
{
|
||||
m: {
|
||||
exn: tag5,
|
||||
f: () => {
|
||||
throw new WebAssembly.Exception(tag5, [42, "foo", 42, "bar"]);
|
||||
},
|
||||
},
|
||||
}
|
||||
).exports.f(),
|
||||
[42, "foo", 42, "bar"]
|
||||
);
|
||||
|
||||
{
|
||||
const { funcref } = wasmEvalText(
|
||||
`(module (func (export "funcref")))`
|
||||
).exports;
|
||||
assertEqArray(
|
||||
wasmEvalText(
|
||||
`(module
|
||||
(import "m" "exn" (tag $exn (param externref funcref)))
|
||||
(import "m" "f" (func $f))
|
||||
(func (export "f") (result externref funcref)
|
||||
try (result externref funcref)
|
||||
call $f
|
||||
(ref.null extern)
|
||||
(ref.null func)
|
||||
catch $exn
|
||||
end))`,
|
||||
{
|
||||
m: {
|
||||
exn: tag9,
|
||||
f: () => {
|
||||
throw new WebAssembly.Exception(tag9, ["foo", funcref]);
|
||||
},
|
||||
},
|
||||
}
|
||||
).exports.f(),
|
||||
["foo", funcref]
|
||||
);
|
||||
}
|
||||
|
||||
assertEq(
|
||||
wasmEvalText(
|
||||
`(module
|
||||
|
@ -323,7 +402,7 @@ assertEq(
|
|||
end))`,
|
||||
{
|
||||
m: {
|
||||
exn: exn,
|
||||
exn,
|
||||
f: () => {
|
||||
throw new WebAssembly.Exception(exn, [42]);
|
||||
},
|
||||
|
@ -362,3 +441,49 @@ assertEq(
|
|||
1
|
||||
);
|
||||
}
|
||||
|
||||
// Test `getArg` on a Wasm-thrown exception.
|
||||
assertEq(
|
||||
(() => {
|
||||
try {
|
||||
wasmEvalText(
|
||||
`(module
|
||||
(import "m" "exn" (tag $exn (param i32 f64)))
|
||||
(func (export "f")
|
||||
(i32.const 9999)
|
||||
(f64.const 9999)
|
||||
throw $exn))`,
|
||||
{ m: { exn: tag8 } }
|
||||
).exports.f();
|
||||
} catch (exn) {
|
||||
return exn.getArg(tag8, 1);
|
||||
}
|
||||
})(),
|
||||
9999
|
||||
);
|
||||
|
||||
assertEqArray(
|
||||
(() => {
|
||||
try {
|
||||
wasmEvalText(
|
||||
`(module
|
||||
(import "m" "exn" (tag $exn (param i32 externref i32 externref)))
|
||||
(func (export "f") (param externref externref)
|
||||
(i32.const 1)
|
||||
(local.get 0)
|
||||
(i32.const 2)
|
||||
(local.get 1)
|
||||
throw $exn))`,
|
||||
{ m: { exn: tag5 } }
|
||||
).exports.f("foo", "bar");
|
||||
} catch (exn) {
|
||||
return [
|
||||
exn.getArg(tag5, 0),
|
||||
exn.getArg(tag5, 1),
|
||||
exn.getArg(tag5, 2),
|
||||
exn.getArg(tag5, 3),
|
||||
];
|
||||
}
|
||||
})(),
|
||||
[1, "foo", 2, "bar"]
|
||||
);
|
||||
|
|
|
@ -3574,9 +3574,9 @@ bool BaseCompiler::emitCatch() {
|
|||
masm.bind(&tryCatch.catchInfos.back().label);
|
||||
|
||||
// Extract the arguments in the exception package and push them.
|
||||
const TagDesc& tagDesc = moduleEnv_.tags[tagIndex];
|
||||
const ValTypeVector& params = tagDesc.argTypes;
|
||||
const TagOffsetVector& offsets = tagDesc.argOffsets;
|
||||
const TagType& tagType = moduleEnv_.tags[tagIndex].type;
|
||||
const ValTypeVector& params = tagType.argTypes;
|
||||
const TagOffsetVector& offsets = tagType.argOffsets;
|
||||
|
||||
const uint32_t dataOffset =
|
||||
NativeObject::getFixedSlotOffset(ArrayBufferObject::DATA_SLOT);
|
||||
|
@ -3601,7 +3601,7 @@ bool BaseCompiler::emitCatch() {
|
|||
masm.load32(Address(refs, NativeObject::offsetOfFixedElements() +
|
||||
ObjectElements::offsetOfLength()),
|
||||
scratch);
|
||||
masm.branch32(Assembler::Equal, scratch, Imm32(tagDesc.refCount), &ok);
|
||||
masm.branch32(Assembler::Equal, scratch, Imm32(tagType.refCount), &ok);
|
||||
masm.assumeUnreachable("Array length should be equal to exn ref count.");
|
||||
masm.bind(&ok);
|
||||
freeI32(scratch);
|
||||
|
@ -3955,11 +3955,11 @@ bool BaseCompiler::emitThrow() {
|
|||
|
||||
const TagDesc& tagDesc = moduleEnv_.tags[exnIndex];
|
||||
const ResultType& params = tagDesc.resultType();
|
||||
const TagOffsetVector& offsets = tagDesc.argOffsets;
|
||||
const TagOffsetVector& offsets = tagDesc.type.argOffsets;
|
||||
|
||||
// Create the new exception object that we will throw.
|
||||
pushI32(exnIndex);
|
||||
pushI32(tagDesc.bufferSize);
|
||||
pushI32(tagDesc.type.bufferSize);
|
||||
if (!emitInstanceCall(lineOrBytecode, SASigExceptionNew)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1463,7 +1463,7 @@ bool WasmModuleObject::imports(JSContext* cx, unsigned argc, Value* vp) {
|
|||
case DefinitionKind::Tag: {
|
||||
size_t tagIndex = numTagImport++;
|
||||
const TagDesc& tag = metadata.tags[tagIndex];
|
||||
typeObj = TagTypeToObject(cx, tag.argTypes);
|
||||
typeObj = TagTypeToObject(cx, tag.type.argTypes);
|
||||
break;
|
||||
}
|
||||
# endif // ENABLE_WASM_EXCEPTIONS
|
||||
|
@ -1568,7 +1568,7 @@ bool WasmModuleObject::exports(JSContext* cx, unsigned argc, Value* vp) {
|
|||
# ifdef ENABLE_WASM_EXCEPTIONS
|
||||
case DefinitionKind::Tag: {
|
||||
const TagDesc& tag = metadata.tags[exp.tagIndex()];
|
||||
typeObj = TagTypeToObject(cx, tag.argTypes);
|
||||
typeObj = TagTypeToObject(cx, tag.type.argTypes);
|
||||
break;
|
||||
}
|
||||
# endif // ENABLE_WASM_EXCEPTIONS
|
||||
|
@ -3710,7 +3710,7 @@ void WasmTagObject::finalize(JSFreeOp* fop, JSObject* obj) {
|
|||
WasmTagObject& exnObj = obj->as<WasmTagObject>();
|
||||
if (!exnObj.isNewborn()) {
|
||||
fop->release(obj, &exnObj.tag(), MemoryUse::WasmTagTag);
|
||||
fop->delete_(obj, &exnObj.valueTypes(), MemoryUse::WasmTagType);
|
||||
fop->delete_(obj, &exnObj.tagType(), MemoryUse::WasmTagType);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3745,6 +3745,15 @@ bool WasmTagObject::construct(JSContext* cx, unsigned argc, Value* vp) {
|
|||
if (!ParseValTypes(cx, paramsVal, params)) {
|
||||
return false;
|
||||
}
|
||||
TagOffsetVector offsets;
|
||||
if (!offsets.resize(params.length())) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
TagType tagType = TagType(std::move(params), std::move(offsets));
|
||||
if (!tagType.computeLayout()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RootedObject proto(cx);
|
||||
if (!GetPrototypeFromBuiltinConstructor(cx, args, JSProto_WasmTag, &proto)) {
|
||||
|
@ -3754,7 +3763,7 @@ bool WasmTagObject::construct(JSContext* cx, unsigned argc, Value* vp) {
|
|||
proto = GlobalObject::getOrCreatePrototype(cx, JSProto_WasmTag);
|
||||
}
|
||||
|
||||
RootedWasmTagObject tagObj(cx, WasmTagObject::create(cx, params, proto));
|
||||
RootedWasmTagObject tagObj(cx, WasmTagObject::create(cx, tagType, proto));
|
||||
if (!tagObj) {
|
||||
return false;
|
||||
}
|
||||
|
@ -3764,7 +3773,8 @@ bool WasmTagObject::construct(JSContext* cx, unsigned argc, Value* vp) {
|
|||
}
|
||||
|
||||
/* static */
|
||||
WasmTagObject* WasmTagObject::create(JSContext* cx, const ValTypeVector& type,
|
||||
WasmTagObject* WasmTagObject::create(JSContext* cx,
|
||||
const wasm::TagType& tagType,
|
||||
HandleObject proto) {
|
||||
AutoSetNewObjectMetadata metadata(cx);
|
||||
RootedWasmTagObject obj(cx,
|
||||
|
@ -3783,13 +3793,12 @@ WasmTagObject* WasmTagObject::create(JSContext* cx, const ValTypeVector& type,
|
|||
|
||||
InitReservedSlot(obj, TAG_SLOT, tag.forget().take(), MemoryUse::WasmTagTag);
|
||||
|
||||
wasm::ValTypeVector* newValueTypes = js_new<ValTypeVector>();
|
||||
for (auto t : type) {
|
||||
if (!newValueTypes->append(t)) {
|
||||
return nullptr;
|
||||
}
|
||||
TagType* newType = js_new<TagType>();
|
||||
if (!newType || !newType->clone(tagType)) {
|
||||
ReportOutOfMemory(cx);
|
||||
return nullptr;
|
||||
}
|
||||
InitReservedSlot(obj, TYPE_SLOT, newValueTypes, MemoryUse::WasmTagType);
|
||||
InitReservedSlot(obj, TYPE_SLOT, newType, MemoryUse::WasmTagType);
|
||||
|
||||
MOZ_ASSERT(!obj->isNewborn());
|
||||
|
||||
|
@ -3832,8 +3841,12 @@ const JSFunctionSpec WasmTagObject::methods[] = {
|
|||
|
||||
const JSFunctionSpec WasmTagObject::static_methods[] = {JS_FS_END};
|
||||
|
||||
TagType& WasmTagObject::tagType() const {
|
||||
return *(TagType*)getFixedSlot(TYPE_SLOT).toPrivate();
|
||||
};
|
||||
|
||||
wasm::ValTypeVector& WasmTagObject::valueTypes() const {
|
||||
return *(ValTypeVector*)getFixedSlot(TYPE_SLOT).toPrivate();
|
||||
return tagType().argTypes;
|
||||
};
|
||||
|
||||
wasm::ResultType WasmTagObject::resultType() const {
|
||||
|
@ -3923,25 +3936,24 @@ bool WasmExceptionObject::construct(JSContext* cx, unsigned argc, Value* vp) {
|
|||
return false;
|
||||
}
|
||||
|
||||
wasm::ValTypeVector& params = exnTag->valueTypes();
|
||||
const wasm::TagType& tagType = exnTag->tagType();
|
||||
const wasm::ValTypeVector& params = tagType.argTypes;
|
||||
const wasm::TagOffsetVector& offsets = tagType.argOffsets;
|
||||
|
||||
// This is pre-sizing the data buffer for the exception object.
|
||||
size_t nbytes = 0;
|
||||
for (const ValType param : params) {
|
||||
if (!param.isReference()) {
|
||||
nbytes += SizeOf(param);
|
||||
}
|
||||
}
|
||||
|
||||
RootedArrayBufferObject buf(cx, ArrayBufferObject::createZeroed(cx, nbytes));
|
||||
RootedArrayBufferObject buf(
|
||||
cx, ArrayBufferObject::createZeroed(cx, tagType.bufferSize));
|
||||
if (!buf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RootedArrayObject refs(cx, NewDenseEmptyArray(cx));
|
||||
RootedArrayObject refs(cx, NewDenseFullyAllocatedArray(cx, tagType.refCount));
|
||||
if (!refs) {
|
||||
return false;
|
||||
}
|
||||
refs->setDenseInitializedLength(tagType.refCount);
|
||||
for (int i = 0; i < tagType.refCount; i++) {
|
||||
refs->initDenseElement(i, UndefinedValue());
|
||||
}
|
||||
|
||||
uint8_t* bufPtr = buf->dataPointer();
|
||||
RootedValue nextArg(cx);
|
||||
|
@ -3961,18 +3973,19 @@ bool WasmExceptionObject::construct(JSContext* cx, unsigned argc, Value* vp) {
|
|||
}
|
||||
|
||||
if (params[i].isReference()) {
|
||||
RootedObject objPtr(cx);
|
||||
if (!ToWebAssemblyValue(cx, nextArg, params[i], objPtr.address(), true)) {
|
||||
return false;
|
||||
}
|
||||
if (!NewbornArrayPush(cx, refs, ObjectValue(*objPtr))) {
|
||||
ASSERT_ANYREF_IS_JSOBJECT;
|
||||
RootedAnyRef anyref(cx, AnyRef::null());
|
||||
if (!ToWebAssemblyValue(cx, nextArg, params[i],
|
||||
anyref.get().asJSObjectAddress(), true)) {
|
||||
return false;
|
||||
}
|
||||
refs->setDenseElement(offsets[i] / sizeof(Value),
|
||||
ObjectValue(*anyref.get().asJSObject()));
|
||||
} else {
|
||||
if (!ToWebAssemblyValue(cx, nextArg, params[i], bufPtr, true)) {
|
||||
if (!ToWebAssemblyValue(cx, nextArg, params[i], bufPtr + offsets[i],
|
||||
true)) {
|
||||
return false;
|
||||
}
|
||||
bufPtr += SizeOf(params[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4080,25 +4093,17 @@ bool WasmExceptionObject::getArgImpl(JSContext* cx, const CallArgs& args) {
|
|||
return false;
|
||||
}
|
||||
|
||||
uint32_t offset = exnTag->tagType().argOffsets[index];
|
||||
RootedValue result(cx);
|
||||
if (params[index].isReference()) {
|
||||
uint32_t refIndex = 0;
|
||||
for (size_t i = 0; i < index; i++) {
|
||||
if (params[i].isReference()) {
|
||||
refIndex++;
|
||||
}
|
||||
}
|
||||
JSObject* ref = &exnObj->refs().getDenseElement(refIndex).toObject();
|
||||
if (!ToJSValue(cx, &ref, params[index], &result)) {
|
||||
ASSERT_ANYREF_IS_JSOBJECT;
|
||||
RootedValue val(cx, exnObj->refs().getDenseElement(offset / sizeof(Value)));
|
||||
RootedAnyRef anyref(cx, AnyRef::fromJSObject(val.toObjectOrNull()));
|
||||
if (!ToJSValue(cx, anyref.get().asJSObjectAddress(), params[index],
|
||||
&result)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
uint32_t offset = 0;
|
||||
for (size_t i = 0; i < index; i++) {
|
||||
if (!params[i].isReference()) {
|
||||
offset += SizeOf(params[i]);
|
||||
}
|
||||
}
|
||||
if (!ToJSValue(cx, exnObj->values().dataPointer() + offset, params[index],
|
||||
&result)) {
|
||||
return false;
|
||||
|
|
|
@ -506,10 +506,11 @@ class WasmTagObject : public NativeObject {
|
|||
static const JSFunctionSpec static_methods[];
|
||||
static bool construct(JSContext*, unsigned, Value*);
|
||||
|
||||
static WasmTagObject* create(JSContext* cx, const wasm::ValTypeVector& type,
|
||||
static WasmTagObject* create(JSContext* cx, const wasm::TagType& tagType,
|
||||
HandleObject proto);
|
||||
bool isNewborn() const;
|
||||
|
||||
wasm::TagType& tagType() const;
|
||||
wasm::ValTypeVector& valueTypes() const;
|
||||
wasm::ResultType resultType() const;
|
||||
wasm::ExceptionTag& tag() const;
|
||||
|
|
|
@ -840,8 +840,7 @@ bool Module::instantiateLocalTag(JSContext* cx, const TagDesc& ed,
|
|||
// If the tag description is exported, create an export tag
|
||||
// object for it.
|
||||
RootedObject proto(cx, &cx->global()->getPrototype(JSProto_WasmTag));
|
||||
RootedWasmTagObject tagObj(cx,
|
||||
WasmTagObject::create(cx, ed.argTypes, proto));
|
||||
RootedWasmTagObject tagObj(cx, WasmTagObject::create(cx, ed.type, proto));
|
||||
if (!tagObj) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -181,7 +181,7 @@ size_t GlobalDesc::sizeOfExcludingThis(MallocSizeOf mallocSizeOf) const {
|
|||
}
|
||||
|
||||
#ifdef ENABLE_WASM_EXCEPTIONS
|
||||
bool TagDesc::computeLayout() {
|
||||
bool TagType::computeLayout() {
|
||||
StructLayout layout;
|
||||
int32_t refCount = 0;
|
||||
for (const ValType argType : argTypes) {
|
||||
|
|
|
@ -286,25 +286,43 @@ using GlobalDescVector = Vector<GlobalDesc, 0, SystemAllocPolicy>;
|
|||
// offset in the elements of the exception's ArrayObject.
|
||||
using TagOffsetVector = Vector<int32_t, 0, SystemAllocPolicy>;
|
||||
|
||||
struct TagDesc {
|
||||
TagKind kind;
|
||||
struct TagType {
|
||||
ValTypeVector argTypes;
|
||||
TagOffsetVector argOffsets;
|
||||
int32_t bufferSize;
|
||||
int32_t refCount;
|
||||
bool isExport;
|
||||
|
||||
TagDesc(TagKind kind, ValTypeVector&& argTypes, TagOffsetVector&& argOffsets,
|
||||
bool isExport = false)
|
||||
: kind(kind),
|
||||
argTypes(std::move(argTypes)),
|
||||
TagType() : argTypes(), argOffsets(), bufferSize(0), refCount(0) {}
|
||||
TagType(ValTypeVector&& argTypes, TagOffsetVector&& argOffsets)
|
||||
: argTypes(std::move(argTypes)),
|
||||
argOffsets(std::move(argOffsets)),
|
||||
bufferSize(0),
|
||||
refCount(0),
|
||||
isExport(isExport) {}
|
||||
refCount(0) {}
|
||||
|
||||
[[nodiscard]] bool computeLayout();
|
||||
ResultType resultType() const { return ResultType::Vector(argTypes); }
|
||||
|
||||
[[nodiscard]] bool clone(const TagType& src) {
|
||||
MOZ_ASSERT(argTypes.empty());
|
||||
MOZ_ASSERT(argOffsets.empty());
|
||||
if (!argTypes.appendAll(src.argTypes) ||
|
||||
!argOffsets.appendAll(src.argOffsets)) {
|
||||
return false;
|
||||
}
|
||||
bufferSize = src.bufferSize;
|
||||
refCount = src.refCount;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct TagDesc {
|
||||
TagKind kind;
|
||||
TagType type;
|
||||
bool isExport;
|
||||
|
||||
TagDesc(TagKind kind, TagType&& type, bool isExport = false)
|
||||
: kind(kind), type(std::move(type)), isExport(isExport) {}
|
||||
|
||||
ResultType resultType() const { return ResultType::Vector(type.argTypes); }
|
||||
};
|
||||
|
||||
using TagDescVector = Vector<TagDesc, 0, SystemAllocPolicy>;
|
||||
|
|
|
@ -2055,14 +2055,14 @@ static bool DecodeImport(Decoder& d, ModuleEnvironment* env) {
|
|||
if (!offsets.resize(tagArgs.length())) {
|
||||
return false;
|
||||
}
|
||||
if (!env->tags.emplaceBack(tagKind, std::move(tagArgs),
|
||||
std::move(offsets))) {
|
||||
TagType type = TagType(std::move(tagArgs), std::move(offsets));
|
||||
if (!env->tags.emplaceBack(tagKind, std::move(type))) {
|
||||
return false;
|
||||
}
|
||||
if (env->tags.length() > MaxTags) {
|
||||
return d.fail("too many tags");
|
||||
}
|
||||
if (!env->tags.back().computeLayout()) {
|
||||
if (!env->tags.back().type.computeLayout()) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
@ -2286,9 +2286,9 @@ static bool DecodeTagSection(Decoder& d, ModuleEnvironment* env) {
|
|||
if (!offsets.resize(tagArgs.length())) {
|
||||
return false;
|
||||
}
|
||||
env->tags.infallibleEmplaceBack(tagKind, std::move(tagArgs),
|
||||
std::move(offsets));
|
||||
if (!env->tags.back().computeLayout()) {
|
||||
TagType type = TagType(std::move(tagArgs), std::move(offsets));
|
||||
env->tags.infallibleEmplaceBack(tagKind, std::move(type));
|
||||
if (!env->tags.back().type.computeLayout()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -2409,7 +2409,7 @@ static bool DecodeExport(Decoder& d, ModuleEnvironment* env,
|
|||
}
|
||||
|
||||
# ifdef WASM_PRIVATE_REFTYPES
|
||||
if (!TagIsJSCompatible(d, env->tags[tagIndex].argTypes)) {
|
||||
if (!TagIsJSCompatible(d, env->tags[tagIndex].type.argTypes)) {
|
||||
return false;
|
||||
}
|
||||
# endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче