--- a/js/src/wasm/WasmBinaryFormat.cpp
+++ b/js/src/wasm/WasmBinaryFormat.cpp
@@ -126,16 +126,178 @@ wasm::DecodeTypeSection(Decoder& d, SigW
}
if (!d.finishSection(sectionStart, sectionSize, "type"))
return false;
return true;
}
+UniqueChars
+wasm::DecodeName(Decoder& d)
+{
+ uint32_t numBytes;
+ if (!d.readVarU32(&numBytes))
+ return nullptr;
+
+ const uint8_t* bytes;
+ if (!d.readBytes(numBytes, &bytes))
+ return nullptr;
+
+ UniqueChars name(js_pod_malloc<char>(numBytes + 1));
+ if (!name)
+ return nullptr;
+
+ memcpy(name.get(), bytes, numBytes);
+ name[numBytes] = '\0';
+
+ return name;
+}
+
+bool
+wasm::DecodeSignatureIndex(Decoder& d, const SigWithIdVector& sigs, uint32_t* sigIndex)
+{
+ if (!d.readVarU32(sigIndex))
+ return d.fail("expected signature index");
+
+ if (*sigIndex >= sigs.length())
+ return d.fail("signature index out of range");
+
+ return true;
+}
+
+bool
+wasm::DecodeTableLimits(Decoder& d, TableDescVector* tables)
+{
+ uint32_t elementType;
+ if (!d.readVarU32(&elementType))
+ return d.fail("expected table element type");
+
+ if (elementType != uint32_t(TypeCode::AnyFunc))
+ return d.fail("expected 'anyfunc' element type");
+
+ Limits limits;
+ if (!DecodeLimits(d, &limits))
+ return false;
+
+ if (tables->length())
+ return d.fail("already have default table");
+
+ return tables->emplaceBack(TableKind::AnyFunction, limits);
+}
+
+bool
+wasm::GlobalIsJSCompatible(Decoder& d, ValType type, bool isMutable)
+{
+ switch (type) {
+ case ValType::I32:
+ case ValType::F32:
+ case ValType::F64:
+ break;
+ case ValType::I64:
+ if (!JitOptions.wasmTestMode)
+ return d.fail("can't import/export an Int64 global to JS");
+ break;
+ default:
+ return d.fail("unexpected variable type in global import/export");
+ }
+
+ if (isMutable)
+ return d.fail("can't import/export mutable globals in the MVP");
+
+ return true;
+}
+
+static bool
+DecodeImport(Decoder& d, const SigWithIdVector& sigs, Uint32Vector* funcSigIndices,
+ GlobalDescVector* globals, TableDescVector* tables, Maybe<Limits>* memory,
+ ImportVector* imports)
+{
+ UniqueChars moduleName = DecodeName(d);
+ if (!moduleName)
+ return d.fail("expected valid import module name");
+
+ UniqueChars funcName = DecodeName(d);
+ if (!funcName)
+ return d.fail("expected valid import func name");
+
+ uint32_t rawImportKind;
+ if (!d.readVarU32(&rawImportKind))
+ return d.fail("failed to read import kind");
+
+ DefinitionKind importKind = DefinitionKind(rawImportKind);
+
+ switch (importKind) {
+ case DefinitionKind::Function: {
+ uint32_t sigIndex;
+ if (!DecodeSignatureIndex(d, sigs, &sigIndex))
+ return false;
+ if (!funcSigIndices->append(sigIndex))
+ return false;
+ break;
+ }
+ case DefinitionKind::Table: {
+ if (!DecodeTableLimits(d, tables))
+ return false;
+ break;
+ }
+ case DefinitionKind::Memory: {
+ Limits limits;
+ if (!DecodeMemoryLimits(d, !!*memory, &limits))
+ return false;
+ memory->emplace(limits);
+ break;
+ }
+ case DefinitionKind::Global: {
+ ValType type;
+ bool isMutable;
+ if (!DecodeGlobalType(d, &type, &isMutable))
+ return false;
+ if (!GlobalIsJSCompatible(d, type, isMutable))
+ return false;
+ if (!globals->append(GlobalDesc(type, isMutable, globals->length())))
+ return false;
+ break;
+ }
+ default:
+ return d.fail("unsupported import kind");
+ }
+
+ return imports->emplaceBack(Move(moduleName), Move(funcName), importKind);
+}
+
+bool
+wasm::DecodeImportSection(Decoder& d, const SigWithIdVector& sigs, Uint32Vector* funcSigIndices,
+ GlobalDescVector* globals, TableDescVector* tables, Maybe<Limits>* memory,
+ ImportVector* imports)
+{
+ uint32_t sectionStart, sectionSize;
+ if (!d.startSection(SectionId::Import, §ionStart, §ionSize, "import"))
+ return false;
+ if (sectionStart == Decoder::NotStarted)
+ return true;
+
+ uint32_t numImports;
+ if (!d.readVarU32(&numImports))
+ return d.fail("failed to read number of imports");
+
+ if (numImports > MaxImports)
+ return d.fail("too many imports");
+
+ for (uint32_t i = 0; i < numImports; i++) {
+ if (!DecodeImport(d, sigs, funcSigIndices, globals, tables, memory, imports))
+ return false;
+ }
+
+ if (!d.finishSection(sectionStart, sectionSize, "import"))
+ return false;
+
+ return true;
+}
+
bool
wasm::EncodeLocalEntries(Encoder& e, const ValTypeVector& locals)
{
uint32_t numLocalEntries = 0;
ValType prev = ValType(TypeCode::Limit);
for (ValType t : locals) {
if (t != prev) {
numLocalEntries++;
--- a/js/src/wasm/WasmBinaryFormat.h
+++ b/js/src/wasm/WasmBinaryFormat.h
@@ -33,16 +33,33 @@ MOZ_MUST_USE bool
DecodePreamble(Decoder& d);
MOZ_MUST_USE bool
CheckValType(Decoder& d, ValType type);
MOZ_MUST_USE bool
DecodeTypeSection(Decoder& d, SigWithIdVector* sigs);
+UniqueChars
+DecodeName(Decoder& d);
+
+MOZ_MUST_USE bool
+DecodeSignatureIndex(Decoder& d, const SigWithIdVector& sigs, uint32_t* sigIndex);
+
+MOZ_MUST_USE bool
+DecodeTableLimits(Decoder& d, TableDescVector* tables);
+
+MOZ_MUST_USE bool
+GlobalIsJSCompatible(Decoder& d, ValType type, bool isMutable);
+
+MOZ_MUST_USE bool
+DecodeImportSection(Decoder& d, const SigWithIdVector& sigs, Uint32Vector* funcSigIndices,
+ GlobalDescVector* globals, TableDescVector* tables, Maybe<Limits>* memory,
+ ImportVector* imports);
+
MOZ_MUST_USE bool
EncodeLocalEntries(Encoder& d, const ValTypeVector& locals);
MOZ_MUST_USE bool
DecodeLocalEntries(Decoder& d, ValTypeVector* locals);
MOZ_MUST_USE bool
DecodeGlobalType(Decoder& d, ValType* type, bool* isMutable);
--- a/js/src/wasm/WasmBinaryToAST.cpp
+++ b/js/src/wasm/WasmBinaryToAST.cpp
@@ -1427,24 +1427,23 @@ AstDecodeExpr(AstDecodeContext& c)
lastExpr->setOffset(exprOffset);
return true;
}
/*****************************************************************************/
// wasm decoding and generation
static bool
-AstDecodeTypeSection(AstDecodeContext& c)
+AstDecodeTypeSection(AstDecodeContext& c, SigWithIdVector* sigs)
{
- SigWithIdVector sigs;
- if (!DecodeTypeSection(c.d, &sigs))
+ if (!DecodeTypeSection(c.d, sigs))
return false;
- for (size_t sigIndex = 0; sigIndex < sigs.length(); sigIndex++) {
- const Sig& sig = sigs[sigIndex];
+ for (size_t sigIndex = 0; sigIndex < sigs->length(); sigIndex++) {
+ const Sig& sig = (*sigs)[sigIndex];
AstValTypeVector args(c.lifo);
if (!args.appendAll(sig.args()))
return false;
AstSig sigNoName(Move(args), sig.ret());
AstName sigName;
if (!AstDecodeGenerateName(c, AstName(u"type"), sigIndex, &sigName))
@@ -1453,16 +1452,113 @@ AstDecodeTypeSection(AstDecodeContext& c
AstSig* astSig = new(c.lifo) AstSig(sigName, Move(sigNoName));
if (!astSig || !c.module().append(astSig))
return false;
}
return true;
}
+static AstName
+ToAstName(AstDecodeContext& c, const UniqueChars& name)
+{
+ size_t len = strlen(name.get());
+ char16_t* buffer = static_cast<char16_t *>(c.lifo.alloc(len * sizeof(char16_t)));
+ if (!buffer)
+ return AstName();
+
+ for (size_t i = 0; i < len; i++)
+ buffer[i] = name.get()[i];
+
+ return AstName(buffer, len);
+}
+
+static bool
+AstDecodeImportSection(AstDecodeContext& c, const SigWithIdVector& sigs)
+{
+ Uint32Vector funcSigIndices;
+ GlobalDescVector globals;
+ TableDescVector tables;
+ Maybe<Limits> memory;
+ ImportVector imports;
+ if (!DecodeImportSection(c.d, sigs, &funcSigIndices, &globals, &tables, &memory, &imports))
+ return false;
+
+ size_t lastFunc = 0;
+ size_t lastGlobal = 0;
+ size_t lastTable = 0;
+ size_t lastMemory = 0;
+
+ for (size_t importIndex = 0; importIndex < imports.length(); importIndex++) {
+ const Import& import = imports[importIndex];
+
+ AstName moduleName = ToAstName(c, import.module);
+ AstName fieldName = ToAstName(c, import.field);
+
+ AstImport* ast = nullptr;
+ switch (import.kind) {
+ case DefinitionKind::Function: {
+ AstName importName;
+ if (!AstDecodeGenerateName(c, AstName(u"import"), lastFunc, &importName))
+ return false;
+
+ AstRef sigRef;
+ if (!AstDecodeGenerateRef(c, AstName(u"type"), funcSigIndices[lastFunc], &sigRef))
+ return false;
+
+ ast = new(c.lifo) AstImport(importName, moduleName, fieldName, sigRef);
+ lastFunc++;
+ break;
+ }
+ case DefinitionKind::Global: {
+ AstName importName;
+ if (!AstDecodeGenerateName(c, AstName(u"global"), lastGlobal, &importName))
+ return false;
+
+ const GlobalDesc& global = globals[lastGlobal];
+ ValType type = global.type();
+ bool isMutable = global.isMutable();
+
+ if (!c.addGlobalDesc(type, isMutable, /* import */ true))
+ return false;
+
+ ast = new(c.lifo) AstImport(importName, moduleName, fieldName,
+ AstGlobal(importName, type, isMutable));
+ lastGlobal++;
+ break;
+ }
+ case DefinitionKind::Table: {
+ AstName importName;
+ if (!AstDecodeGenerateName(c, AstName(u"table"), lastTable, &importName))
+ return false;
+
+ ast = new(c.lifo) AstImport(importName, moduleName, fieldName, DefinitionKind::Table,
+ tables[lastTable].limits);
+ lastTable++;
+ break;
+ }
+ case DefinitionKind::Memory: {
+ AstName importName;
+ if (!AstDecodeGenerateName(c, AstName(u"memory"), lastMemory, &importName))
+ return false;
+
+ ast = new(c.lifo) AstImport(importName, moduleName, fieldName, DefinitionKind::Memory,
+ *memory);
+ lastMemory++;
+ break;
+ }
+ }
+
+ if (!ast || !c.module().append(ast))
+ return false;
+ }
+
+ return true;
+}
+
static bool
AstDecodeSignatureIndex(AstDecodeContext& c, uint32_t* sigIndex)
{
if (!c.d.readVarU32(sigIndex))
return c.d.fail("expected signature index");
if (*sigIndex >= c.module().sigs().length())
return c.d.fail("signature index out of range");
@@ -1561,153 +1657,16 @@ AstDecodeName(AstDecodeContext& c, AstNa
for (size_t i = 0; i < length; i++)
buffer[i] = bytes[i];
*name = AstName(buffer, length);
return true;
}
static bool
-AstDecodeLimitsTable(AstDecodeContext& c, Limits* limits)
-{
- uint32_t kind;
- if (!c.d.readVarU32(&kind))
- return false;
-
- if (kind != uint32_t(TypeCode::AnyFunc))
- return c.d.fail("unknown type constructor kind");
-
- if (!DecodeLimits(c.d, limits))
- return false;
-
- return true;
-}
-
-static bool
-AstDecodeImport(AstDecodeContext& c, uint32_t importIndex, AstImport** import)
-{
- AstName moduleName;
- if (!AstDecodeName(c, &moduleName))
- return c.d.fail("expected import module name");
-
- if (moduleName.empty())
- return c.d.fail("module name cannot be empty");
-
- AstName fieldName;
- if (!AstDecodeName(c, &fieldName))
- return c.d.fail("expected import field name");
-
- uint32_t kind;
- if (!c.d.readVarU32(&kind))
- return c.d.fail("expected import kind");
-
- switch (kind) {
- case uint32_t(DefinitionKind::Function): {
- AstName importName;
- if (!AstDecodeGenerateName(c, AstName(u"import"), importIndex, &importName))
- return false;
-
- uint32_t sigIndex = AstNoIndex;
- if (!AstDecodeSignatureIndex(c, &sigIndex))
- return false;
-
- AstRef sigRef;
- if (!AstDecodeGenerateRef(c, AstName(u"type"), sigIndex, &sigRef))
- return false;
-
- *import = new(c.lifo) AstImport(importName, moduleName, fieldName, sigRef);
- break;
- }
- case uint32_t(DefinitionKind::Global): {
- AstName importName;
- if (!AstDecodeGenerateName(c, AstName(u"global"), importIndex, &importName))
- return false;
-
- ValType type;
- bool isMutable;
- if (!DecodeGlobalType(c.d, &type, &isMutable))
- return false;
-
- if (!c.addGlobalDesc(type, isMutable, /* import */ true))
- return false;
-
- *import = new(c.lifo) AstImport(importName, moduleName, fieldName,
- AstGlobal(importName, type, isMutable));
- break;
- }
- case uint32_t(DefinitionKind::Table): {
- if (c.module().hasTable())
- return c.d.fail("already have default table");
-
- AstName importName;
- if (!AstDecodeGenerateName(c, AstName(u"table"), importIndex, &importName))
- return false;
-
- Limits table;
- if (!AstDecodeLimitsTable(c, &table))
- return false;
-
- *import = new(c.lifo) AstImport(importName, moduleName, fieldName,
- DefinitionKind::Table, table);
- break;
- }
- case uint32_t(DefinitionKind::Memory): {
- AstName importName;
- if (!AstDecodeGenerateName(c, AstName(u"memory"), importIndex, &importName))
- return false;
-
- Limits memory;
- if (!DecodeMemoryLimits(c.d, c.module().hasMemory(), &memory))
- return false;
-
- *import = new(c.lifo) AstImport(importName, moduleName, fieldName,
- DefinitionKind::Memory, memory);
- break;
- }
- default:
- return c.d.fail("unknown import kind");
- }
-
- if (!*import)
- return false;
-
- return true;
-}
-
-static bool
-AstDecodeImportSection(AstDecodeContext& c)
-{
- uint32_t sectionStart, sectionSize;
- if (!c.d.startSection(SectionId::Import, §ionStart, §ionSize, "import"))
- return false;
- if (sectionStart == Decoder::NotStarted)
- return true;
-
- uint32_t numImports;
- if (!c.d.readVarU32(&numImports))
- return c.d.fail("failed to read number of imports");
-
- if (numImports > MaxImports)
- return c.d.fail( "too many imports");
-
- for (uint32_t i = 0; i < numImports; i++) {
- AstImport* import = nullptr;
- if (!AstDecodeImport(c, i, &import))
- return false;
- if (!c.module().append(import))
- return false;
- }
-
- if (!c.d.finishSection(sectionStart, sectionSize, "import"))
- return false;
-
- return true;
-}
-
-static bool
AstDecodeMemorySection(AstDecodeContext& c)
{
bool present;
Limits memory;
if (!DecodeMemorySection(c.d, c.module().hasMemory(), &memory, &present))
return false;
if (present) {
@@ -2108,19 +2067,20 @@ wasm::BinaryToAst(JSContext* cx, const u
AstModule* result = new(lifo) AstModule(lifo);
if (!result->init())
return false;
UniqueChars error;
Decoder d(bytes, bytes + length, &error);
AstDecodeContext c(cx, lifo, d, *result, true);
+ SigWithIdVector sigs;
if (!DecodePreamble(d) ||
- !AstDecodeTypeSection(c) ||
- !AstDecodeImportSection(c) ||
+ !AstDecodeTypeSection(c, &sigs) ||
+ !AstDecodeImportSection(c, sigs) ||
!AstDecodeFunctionSection(c) ||
!AstDecodeTableSection(c) ||
!AstDecodeMemorySection(c) ||
!AstDecodeGlobalSection(c) ||
!AstDecodeExportSection(c) ||
!AstDecodeStartSection(c) ||
!AstDecodeElemSection(c) ||
!AstDecodeCodeSection(c) ||
--- a/js/src/wasm/WasmCode.h
+++ b/js/src/wasm/WasmCode.h
@@ -368,28 +368,16 @@ struct CallThunk
} u;
CallThunk(uint32_t offset, uint32_t funcIndex) : offset(offset) { u.funcIndex = funcIndex; }
CallThunk() = default;
};
WASM_DECLARE_POD_VECTOR(CallThunk, CallThunkVector)
-// CacheableChars is used to cacheably store UniqueChars.
-
-struct CacheableChars : UniqueChars
-{
- CacheableChars() = default;
- explicit CacheableChars(char* ptr) : UniqueChars(ptr) {}
- MOZ_IMPLICIT CacheableChars(UniqueChars&& rhs) : UniqueChars(Move(rhs)) {}
- WASM_DECLARE_SERIALIZABLE(CacheableChars)
-};
-
-typedef Vector<CacheableChars, 0, SystemAllocPolicy> CacheableCharsVector;
-
// A wasm module can either use no memory, a unshared memory (ArrayBuffer) or
// shared memory (SharedArrayBuffer).
enum class MemoryUsage
{
None = false,
Unshared = 1,
Shared = 2
--- a/js/src/wasm/WasmCompile.cpp
+++ b/js/src/wasm/WasmCompile.cpp
@@ -406,26 +406,39 @@ DecodeFunctionBodyExprs(FunctionDecoder&
}
MOZ_CRASH("unreachable");
#undef CHECK
}
static bool
-DecodeSignatureIndex(Decoder& d, const ModuleGeneratorData& init, const SigWithId** sig)
+DecodeImportSection(Decoder& d, ModuleGeneratorData* init, ImportVector* imports)
{
- uint32_t sigIndex;
- if (!d.readVarU32(&sigIndex))
- return d.fail("expected signature index");
+ Maybe<Limits> memory;
+ Uint32Vector funcSigIndices;
+ if (!DecodeImportSection(d, init->sigs, &funcSigIndices, &init->globals, &init->tables, &memory,
+ imports))
+ return false;
+
+ for (uint32_t sigIndex : funcSigIndices) {
+ if (!init->funcSigs.append(&init->sigs[sigIndex]))
+ return false;
+ }
- if (sigIndex >= init.sigs.length())
- return d.fail("signature index out of range");
+ // The global data offsets will be filled in by ModuleGenerator::init.
+ if (!init->funcImportGlobalDataOffsets.resize(init->funcSigs.length()))
+ return false;
- *sig = &init.sigs[sigIndex];
+ if (memory) {
+ init->memoryUsage = MemoryUsage::Unshared;
+ init->minMemoryLength = memory->initial;
+ init->maxMemoryLength = memory->maximum;
+ }
+
return true;
}
static bool
DecodeFunctionSection(Decoder& d, ModuleGeneratorData* init)
{
uint32_t sectionStart, sectionSize;
if (!d.startSection(SectionId::Function, §ionStart, §ionSize, "function"))
@@ -440,205 +453,47 @@ DecodeFunctionSection(Decoder& d, Module
uint32_t numFuncs = init->funcSigs.length() + numDefs;
if (numFuncs > MaxFuncs)
return d.fail("too many functions");
if (!init->funcSigs.reserve(numFuncs))
return false;
for (uint32_t i = 0; i < numDefs; i++) {
- const SigWithId* sig;
- if (!DecodeSignatureIndex(d, *init, &sig))
+ uint32_t sigIndex;
+ if (!DecodeSignatureIndex(d, init->sigs, &sigIndex))
return false;
+ const SigWithId* sig = &init->sigs[sigIndex];
init->funcSigs.infallibleAppend(sig);
}
if (!d.finishSection(sectionStart, sectionSize, "function"))
return false;
return true;
}
-static UniqueChars
-DecodeName(Decoder& d)
-{
- uint32_t numBytes;
- if (!d.readVarU32(&numBytes))
- return nullptr;
-
- const uint8_t* bytes;
- if (!d.readBytes(numBytes, &bytes))
- return nullptr;
-
- UniqueChars name(js_pod_malloc<char>(numBytes + 1));
- if (!name)
- return nullptr;
-
- memcpy(name.get(), bytes, numBytes);
- name[numBytes] = '\0';
-
- return name;
-}
-
-static bool
-DecodeMemoryLimits(Decoder& d, ModuleGeneratorData* init)
-{
- Limits memory;
- if (!DecodeMemoryLimits(d, UsesMemory(init->memoryUsage), &memory))
- return false;
-
- init->memoryUsage = MemoryUsage::Unshared;
- init->minMemoryLength = memory.initial;
- init->maxMemoryLength = memory.maximum;
- return true;
-}
-
-static bool
-DecodeResizableTable(Decoder& d, ModuleGeneratorData* init)
-{
- uint32_t elementType;
- if (!d.readVarU32(&elementType))
- return d.fail("expected table element type");
-
- if (elementType != uint32_t(TypeCode::AnyFunc))
- return d.fail("expected 'anyfunc' element type");
-
- Limits limits;
- if (!DecodeLimits(d, &limits))
- return false;
-
- if (!init->tables.empty())
- return d.fail("already have default table");
-
- return init->tables.emplaceBack(TableKind::AnyFunction, limits);
-}
-
-static bool
-GlobalIsJSCompatible(Decoder& d, ValType type, bool isMutable)
-{
- switch (type) {
- case ValType::I32:
- case ValType::F32:
- case ValType::F64:
- break;
- case ValType::I64:
- if (!JitOptions.wasmTestMode)
- return d.fail("can't import/export an Int64 global to JS");
- break;
- default:
- return d.fail("unexpected variable type in global import/export");
- }
-
- if (isMutable)
- return d.fail("can't import/export mutable globals in the MVP");
-
- return true;
-}
-
-static bool
-DecodeImport(Decoder& d, ModuleGeneratorData* init, ImportVector* imports)
-{
- UniqueChars moduleName = DecodeName(d);
- if (!moduleName)
- return d.fail("expected valid import module name");
-
- UniqueChars funcName = DecodeName(d);
- if (!funcName)
- return d.fail("expected valid import func name");
-
- uint32_t importKind;
- if (!d.readVarU32(&importKind))
- return d.fail("failed to read import kind");
-
- switch (DefinitionKind(importKind)) {
- case DefinitionKind::Function: {
- const SigWithId* sig = nullptr;
- if (!DecodeSignatureIndex(d, *init, &sig))
- return false;
- if (!init->funcSigs.emplaceBack(sig))
- return false;
- break;
- }
- case DefinitionKind::Table: {
- if (!DecodeResizableTable(d, init))
- return false;
- break;
- }
- case DefinitionKind::Memory: {
- if (!DecodeMemoryLimits(d, init))
- return false;
- break;
- }
- case DefinitionKind::Global: {
- ValType type;
- bool isMutable;
- if (!DecodeGlobalType(d, &type, &isMutable))
- return false;
- if (!GlobalIsJSCompatible(d, type, isMutable))
- return false;
- if (!init->globals.append(GlobalDesc(type, isMutable, init->globals.length())))
- return false;
- break;
- }
- default:
- return d.fail("unsupported import kind");
- }
-
- return imports->emplaceBack(Move(moduleName), Move(funcName), DefinitionKind(importKind));
-}
-
-static bool
-DecodeImportSection(Decoder& d, ModuleGeneratorData* init, ImportVector* imports)
-{
- uint32_t sectionStart, sectionSize;
- if (!d.startSection(SectionId::Import, §ionStart, §ionSize, "import"))
- return false;
- if (sectionStart == Decoder::NotStarted)
- return true;
-
- uint32_t numImports;
- if (!d.readVarU32(&numImports))
- return d.fail("failed to read number of imports");
-
- if (numImports > MaxImports)
- return d.fail("too many imports");
-
- for (uint32_t i = 0; i < numImports; i++) {
- if (!DecodeImport(d, init, imports))
- return false;
- }
-
- // The global data offsets will be filled in by ModuleGenerator::init.
- if (!init->funcImportGlobalDataOffsets.resize(init->funcSigs.length()))
- return false;
-
- if (!d.finishSection(sectionStart, sectionSize, "import"))
- return false;
-
- return true;
-}
-
static bool
DecodeTableSection(Decoder& d, ModuleGeneratorData* init, Uint32Vector* oldElems)
{
uint32_t sectionStart, sectionSize;
if (!d.startSection(SectionId::Table, §ionStart, §ionSize, "table"))
return false;
if (sectionStart == Decoder::NotStarted)
return true;
uint32_t numTables;
if (!d.readVarU32(&numTables))
return d.fail("failed to read number of tables");
if (numTables != 1)
return d.fail("the number of tables must be exactly one");
- if (!DecodeResizableTable(d, init))
+ if (!DecodeTableLimits(d, &init->tables))
return false;
if (!d.finishSection(sectionStart, sectionSize, "table"))
return false;
return true;
}
@@ -1080,17 +935,17 @@ wasm::Compile(const ShareableBytes& byte
if (!DecodePreamble(d))
return nullptr;
if (!DecodeTypeSection(d, &init->sigs))
return nullptr;
ImportVector imports;
- if (!DecodeImportSection(d, init.get(), &imports))
+ if (!::DecodeImportSection(d, init.get(), &imports))
return nullptr;
if (!DecodeFunctionSection(d, init.get()))
return nullptr;
Uint32Vector oldElems;
if (!DecodeTableSection(d, init.get(), &oldElems))
return nullptr;
--- a/js/src/wasm/WasmModule.h
+++ b/js/src/wasm/WasmModule.h
@@ -72,38 +72,16 @@ struct LinkData : LinkDataCacheablePod
SymbolicLinkArray symbolicLinks;
WASM_DECLARE_SERIALIZABLE(LinkData)
};
typedef UniquePtr<LinkData> UniqueLinkData;
typedef UniquePtr<const LinkData> UniqueConstLinkData;
-// Import describes a single wasm import. An ImportVector describes all
-// of a single module's imports.
-//
-// ImportVector is built incrementally by ModuleGenerator and then stored
-// immutably by Module.
-
-struct Import
-{
- CacheableChars module;
- CacheableChars field;
- DefinitionKind kind;
-
- Import() = default;
- Import(UniqueChars&& module, UniqueChars&& field, DefinitionKind kind)
- : module(Move(module)), field(Move(field)), kind(kind)
- {}
-
- WASM_DECLARE_SERIALIZABLE(Import)
-};
-
-typedef Vector<Import, 0, SystemAllocPolicy> ImportVector;
-
// Export describes the export of a definition in a Module to a field in the
// export object. For functions, Export stores an index into the
// FuncExportVector in Metadata. For memory and table exports, there is
// at most one (default) memory/table so no index is needed. Note: a single
// definition can be exported by multiple Exports in the ExportVector.
//
// ExportVector is built incrementally by ModuleGenerator and then stored
// immutably by Module.
--- a/js/src/wasm/WasmTypes.h
+++ b/js/src/wasm/WasmTypes.h
@@ -480,16 +480,50 @@ class InitExpr
switch (kind()) {
case Kind::Constant: return u.val_.type();
case Kind::GetGlobal: return u.global.type_;
}
MOZ_CRASH("unexpected initExpr type");
}
};
+// CacheableChars is used to cacheably store UniqueChars.
+
+struct CacheableChars : UniqueChars
+{
+ CacheableChars() = default;
+ explicit CacheableChars(char* ptr) : UniqueChars(ptr) {}
+ MOZ_IMPLICIT CacheableChars(UniqueChars&& rhs) : UniqueChars(Move(rhs)) {}
+ WASM_DECLARE_SERIALIZABLE(CacheableChars)
+};
+
+typedef Vector<CacheableChars, 0, SystemAllocPolicy> CacheableCharsVector;
+
+// Import describes a single wasm import. An ImportVector describes all
+// of a single module's imports.
+//
+// ImportVector is built incrementally by ModuleGenerator and then stored
+// immutably by Module.
+
+struct Import
+{
+ CacheableChars module;
+ CacheableChars field;
+ DefinitionKind kind;
+
+ Import() = default;
+ Import(UniqueChars&& module, UniqueChars&& field, DefinitionKind kind)
+ : module(Move(module)), field(Move(field)), kind(kind)
+ {}
+
+ WASM_DECLARE_SERIALIZABLE(Import)
+};
+
+typedef Vector<Import, 0, SystemAllocPolicy> ImportVector;
+
// A GlobalDesc describes a single global variable. Currently, asm.js and wasm
// exposes mutable and immutable private globals, but can't import nor export
// mutable globals.
enum class GlobalKind
{
Import,
Constant,