зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1253137 - Baldr: update section header structure to match BinaryEncoding.md, part 1 (r=sunfish)
MozReview-Commit-ID: 41Yhj7esXsj
This commit is contained in:
Родитель
cdd46d9e49
Коммит
e87faa365d
|
@ -624,40 +624,6 @@ DecodeExpr(FunctionDecoder& f, ExprType expected)
|
|||
return f.fail("bad expression code");
|
||||
}
|
||||
|
||||
static bool
|
||||
DecodeFuncBody(JSContext* cx, Decoder& d, ModuleGenerator& mg, FunctionGenerator& fg,
|
||||
uint32_t funcIndex)
|
||||
{
|
||||
const uint8_t* bodyBegin = d.currentPosition();
|
||||
|
||||
FunctionDecoder f(cx, d, mg, fg, funcIndex);
|
||||
|
||||
uint32_t numExprs;
|
||||
if (!d.readVarU32(&numExprs))
|
||||
return Fail(cx, d, "expected number of function body expressions");
|
||||
|
||||
if (numExprs) {
|
||||
for (size_t i = 0; i < numExprs - 1; i++) {
|
||||
if (!DecodeExpr(f, ExprType::Void))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!DecodeExpr(f, f.ret()))
|
||||
return false;
|
||||
} else {
|
||||
if (!CheckType(f, ExprType::Void, f.ret()))
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint8_t* bodyEnd = d.currentPosition();
|
||||
uintptr_t bodyLength = bodyEnd - bodyBegin;
|
||||
if (!fg.bytecode().resize(bodyLength))
|
||||
return false;
|
||||
|
||||
memcpy(fg.bytecode().begin(), bodyBegin, bodyLength);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
// dynamic link data
|
||||
|
||||
|
@ -684,12 +650,11 @@ typedef HashSet<const DeclaredSig*, SigHashPolicy> SigSet;
|
|||
static bool
|
||||
DecodeSignatureSection(JSContext* cx, Decoder& d, ModuleGeneratorData* init)
|
||||
{
|
||||
if (!d.readCStringIf(SigLabel))
|
||||
return true;
|
||||
|
||||
uint32_t sectionStart;
|
||||
if (!d.startSection(§ionStart))
|
||||
return Fail(cx, d, "expected signature section byte size");
|
||||
if (!d.startSection(SigLabel, §ionStart))
|
||||
return Fail(cx, d, "failed to start section");
|
||||
if (sectionStart == Decoder::NotStarted)
|
||||
return true;
|
||||
|
||||
uint32_t numSigs;
|
||||
if (!d.readVarU32(&numSigs))
|
||||
|
@ -762,12 +727,11 @@ DecodeSignatureIndex(JSContext* cx, Decoder& d, const ModuleGeneratorData& init,
|
|||
static bool
|
||||
DecodeDeclarationSection(JSContext* cx, Decoder& d, ModuleGeneratorData* init)
|
||||
{
|
||||
if (!d.readCStringIf(DeclLabel))
|
||||
return true;
|
||||
|
||||
uint32_t sectionStart;
|
||||
if (!d.startSection(§ionStart))
|
||||
return Fail(cx, d, "expected decl section byte size");
|
||||
if (!d.startSection(DeclLabel, §ionStart))
|
||||
return Fail(cx, d, "failed to start section");
|
||||
if (sectionStart == Decoder::NotStarted)
|
||||
return true;
|
||||
|
||||
uint32_t numDecls;
|
||||
if (!d.readVarU32(&numDecls))
|
||||
|
@ -793,12 +757,11 @@ DecodeDeclarationSection(JSContext* cx, Decoder& d, ModuleGeneratorData* init)
|
|||
static bool
|
||||
DecodeTableSection(JSContext* cx, Decoder& d, ModuleGeneratorData* init)
|
||||
{
|
||||
if (!d.readCStringIf(TableLabel))
|
||||
return true;
|
||||
|
||||
uint32_t sectionStart;
|
||||
if (!d.startSection(§ionStart))
|
||||
return Fail(cx, d, "expected table section byte size");
|
||||
if (!d.startSection(TableLabel, §ionStart))
|
||||
return Fail(cx, d, "failed to start section");
|
||||
if (sectionStart == Decoder::NotStarted)
|
||||
return true;
|
||||
|
||||
if (!d.readVarU32(&init->numTableElems))
|
||||
return Fail(cx, d, "expected number of table elems");
|
||||
|
@ -894,12 +857,11 @@ DecodeImport(JSContext* cx, Decoder& d, ModuleGeneratorData* init, ImportNameVec
|
|||
static bool
|
||||
DecodeImportSection(JSContext* cx, Decoder& d, ModuleGeneratorData* init, ImportNameVector* importNames)
|
||||
{
|
||||
if (!d.readCStringIf(ImportLabel))
|
||||
return true;
|
||||
|
||||
uint32_t sectionStart;
|
||||
if (!d.startSection(§ionStart))
|
||||
return Fail(cx, d, "expected import section byte size");
|
||||
if (!d.startSection(ImportLabel, §ionStart))
|
||||
return Fail(cx, d, "failed to start section");
|
||||
if (sectionStart == Decoder::NotStarted)
|
||||
return true;
|
||||
|
||||
for (uint32_t i = 0; !d.readCStringIf(EndLabel); i++) {
|
||||
if (i >= MaxImports)
|
||||
|
@ -922,12 +884,12 @@ static bool
|
|||
DecodeMemorySection(JSContext* cx, Decoder& d, ModuleGenerator& mg,
|
||||
MutableHandle<ArrayBufferObject*> heap)
|
||||
{
|
||||
if (!d.readCStringIf(MemoryLabel))
|
||||
uint32_t sectionStart;
|
||||
if (!d.startSection(MemoryLabel, §ionStart))
|
||||
return Fail(cx, d, "failed to start section");
|
||||
if (sectionStart == Decoder::NotStarted)
|
||||
return true;
|
||||
|
||||
uint32_t sectionStart;
|
||||
if (!d.startSection(§ionStart))
|
||||
return Fail(cx, d, "expected memory section byte size");
|
||||
|
||||
if (!d.readCStringIf(InitialLabel))
|
||||
return Fail(cx, d, "expected memory section initial field");
|
||||
|
@ -1016,12 +978,11 @@ DecodeMemoryExport(JSContext* cx, Decoder& d, ModuleGenerator& mg, CStringSet* d
|
|||
static bool
|
||||
DecodeExportsSection(JSContext* cx, Decoder& d, ModuleGenerator& mg)
|
||||
{
|
||||
if (!d.readCStringIf(ExportLabel))
|
||||
return true;
|
||||
|
||||
uint32_t sectionStart;
|
||||
if (!d.startSection(§ionStart))
|
||||
return Fail(cx, d, "expected export section byte size");
|
||||
if (!d.startSection(ExportLabel, §ionStart))
|
||||
return Fail(cx, d, "failed to start section");
|
||||
if (sectionStart == Decoder::NotStarted)
|
||||
return true;
|
||||
|
||||
CStringSet dupSet(cx);
|
||||
if (!dupSet.init())
|
||||
|
@ -1049,7 +1010,7 @@ DecodeExportsSection(JSContext* cx, Decoder& d, ModuleGenerator& mg)
|
|||
}
|
||||
|
||||
static bool
|
||||
DecodeFunctionSection(JSContext* cx, Decoder& d, ModuleGenerator& mg, uint32_t funcIndex)
|
||||
DecodeFunctionBody(JSContext* cx, Decoder& d, ModuleGenerator& mg, uint32_t funcIndex)
|
||||
{
|
||||
int64_t before = PRMJ_Now();
|
||||
|
||||
|
@ -1057,10 +1018,6 @@ DecodeFunctionSection(JSContext* cx, Decoder& d, ModuleGenerator& mg, uint32_t f
|
|||
if (!mg.startFuncDef(d.currentOffset(), &fg))
|
||||
return false;
|
||||
|
||||
uint32_t sectionStart;
|
||||
if (!d.startSection(§ionStart))
|
||||
return Fail(cx, d, "expected func section byte size");
|
||||
|
||||
const DeclaredSig& sig = mg.funcSig(funcIndex);
|
||||
for (ValType type : sig.args()) {
|
||||
if (!fg.addLocal(type))
|
||||
|
@ -1079,11 +1036,33 @@ DecodeFunctionSection(JSContext* cx, Decoder& d, ModuleGenerator& mg, uint32_t f
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!DecodeFuncBody(cx, d, mg, fg, funcIndex))
|
||||
const uint8_t* bodyBegin = d.currentPosition();
|
||||
|
||||
FunctionDecoder f(cx, d, mg, fg, funcIndex);
|
||||
|
||||
uint32_t numExprs;
|
||||
if (!d.readVarU32(&numExprs))
|
||||
return Fail(cx, d, "expected number of function body expressions");
|
||||
|
||||
if (numExprs) {
|
||||
for (size_t i = 0; i < numExprs - 1; i++) {
|
||||
if (!DecodeExpr(f, ExprType::Void))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!DecodeExpr(f, f.ret()))
|
||||
return false;
|
||||
} else {
|
||||
if (!CheckType(f, ExprType::Void, f.ret()))
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint8_t* bodyEnd = d.currentPosition();
|
||||
uintptr_t bodyLength = bodyEnd - bodyBegin;
|
||||
if (!fg.bytecode().resize(bodyLength))
|
||||
return false;
|
||||
|
||||
if (!d.finishSection(sectionStart))
|
||||
return Fail(cx, d, "func section byte size mismatch");
|
||||
memcpy(fg.bytecode().begin(), bodyBegin, bodyLength);
|
||||
|
||||
int64_t after = PRMJ_Now();
|
||||
unsigned generateTime = (after - before) / PRMJ_USEC_PER_MSEC;
|
||||
|
@ -1092,43 +1071,45 @@ DecodeFunctionSection(JSContext* cx, Decoder& d, ModuleGenerator& mg, uint32_t f
|
|||
}
|
||||
|
||||
static bool
|
||||
DecodeFunctionSections(JSContext* cx, Decoder& d, ModuleGenerator& mg)
|
||||
DecodeFunctionBodiesSection(JSContext* cx, Decoder& d, ModuleGenerator& mg)
|
||||
{
|
||||
if (!mg.startFuncDefs())
|
||||
return false;
|
||||
|
||||
uint32_t funcIndex = 0;
|
||||
uint32_t sectionStart;
|
||||
if (!d.startSection(FuncLabel, §ionStart))
|
||||
return Fail(cx, d, "failed to start section");
|
||||
|
||||
for (; d.readCStringIf(FuncLabel); funcIndex++) {
|
||||
if (funcIndex >= mg.numFuncSigs())
|
||||
return Fail(cx, d, "more function definitions than declarations");
|
||||
if (sectionStart == Decoder::NotStarted) {
|
||||
if (mg.numFuncSigs() != 0)
|
||||
return Fail(cx, d, "expected function bodies");
|
||||
|
||||
if (!DecodeFunctionSection(cx, d, mg, funcIndex))
|
||||
return mg.finishFuncDefs();
|
||||
}
|
||||
|
||||
for (uint32_t funcIndex = 0; funcIndex < mg.numFuncSigs(); funcIndex++) {
|
||||
if (!DecodeFunctionBody(cx, d, mg, funcIndex))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (funcIndex < mg.numFuncSigs())
|
||||
return Fail(cx, d, "fewer function definitions than declarations");
|
||||
if (!d.finishSection(sectionStart))
|
||||
return Fail(cx, d, "function section byte size mismatch");
|
||||
|
||||
if (!mg.finishFuncDefs())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return mg.finishFuncDefs();
|
||||
}
|
||||
|
||||
static bool
|
||||
DecodeDataSection(JSContext* cx, Decoder& d, Handle<ArrayBufferObject*> heap)
|
||||
{
|
||||
if (!d.readCStringIf(DataLabel))
|
||||
uint32_t sectionStart;
|
||||
if (!d.startSection(DataLabel, §ionStart))
|
||||
return Fail(cx, d, "failed to start section");
|
||||
if (sectionStart == Decoder::NotStarted)
|
||||
return true;
|
||||
|
||||
if (!heap)
|
||||
return Fail(cx, d, "data section requires a memory section");
|
||||
|
||||
uint32_t sectionStart;
|
||||
if (!d.startSection(§ionStart))
|
||||
return Fail(cx, d, "expected data section byte size");
|
||||
|
||||
uint8_t* const heapBase = heap->dataPointer();
|
||||
uint32_t const heapLength = heap->byteLength();
|
||||
uint32_t prevEnd = 0;
|
||||
|
@ -1165,31 +1146,6 @@ DecodeDataSection(JSContext* cx, Decoder& d, Handle<ArrayBufferObject*> heap)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
DecodeUnknownSection(JSContext* cx, Decoder& d)
|
||||
{
|
||||
UniqueChars sectionName = d.readCString();
|
||||
if (!sectionName)
|
||||
return Fail(cx, d, "failed to read section name");
|
||||
|
||||
if (!strcmp(sectionName.get(), SigLabel) ||
|
||||
!strcmp(sectionName.get(), ImportLabel) ||
|
||||
!strcmp(sectionName.get(), DeclLabel) ||
|
||||
!strcmp(sectionName.get(), TableLabel) ||
|
||||
!strcmp(sectionName.get(), MemoryLabel) ||
|
||||
!strcmp(sectionName.get(), ExportLabel) ||
|
||||
!strcmp(sectionName.get(), FuncLabel) ||
|
||||
!strcmp(sectionName.get(), DataLabel))
|
||||
{
|
||||
return Fail(cx, d, "known section out of order");
|
||||
}
|
||||
|
||||
if (!d.skipSection())
|
||||
return Fail(cx, d, "unable to skip unknown section");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
DecodeModule(JSContext* cx, UniqueChars file, const uint8_t* bytes, uint32_t length,
|
||||
ImportNameVector* importNames, UniqueExportMap* exportMap,
|
||||
|
@ -1230,7 +1186,7 @@ DecodeModule(JSContext* cx, UniqueChars file, const uint8_t* bytes, uint32_t len
|
|||
if (!DecodeExportsSection(cx, d, mg))
|
||||
return false;
|
||||
|
||||
if (!DecodeFunctionSections(cx, d, mg))
|
||||
if (!DecodeFunctionBodiesSection(cx, d, mg))
|
||||
return false;
|
||||
|
||||
if (!DecodeDataSection(cx, d, heap))
|
||||
|
@ -1239,8 +1195,8 @@ DecodeModule(JSContext* cx, UniqueChars file, const uint8_t* bytes, uint32_t len
|
|||
CacheableCharsVector funcNames;
|
||||
|
||||
while (!d.readCStringIf(EndLabel)) {
|
||||
if (!DecodeUnknownSection(cx, d))
|
||||
return false;
|
||||
if (!d.skipSection())
|
||||
return Fail(cx, d, "unable to skip unknown section");
|
||||
}
|
||||
|
||||
if (!d.done())
|
||||
|
|
|
@ -459,8 +459,9 @@ class Encoder
|
|||
// require backpatching since the size of the section is only known at the
|
||||
// end while the size's uint32 must be stored at the beginning.
|
||||
|
||||
MOZ_WARN_UNUSED_RESULT bool startSection(size_t* offset) {
|
||||
return writePatchableVarU32(offset);
|
||||
MOZ_WARN_UNUSED_RESULT bool startSection(const char* name, size_t* offset) {
|
||||
return writePatchableVarU32(offset) &&
|
||||
writeCString(name);
|
||||
}
|
||||
void finishSection(size_t offset) {
|
||||
return patchVarU32(offset, bytecode_.length() - offset - varU32ByteLength(offset));
|
||||
|
@ -684,10 +685,20 @@ class Decoder
|
|||
|
||||
// See "section" description in Encoder.
|
||||
|
||||
MOZ_WARN_UNUSED_RESULT bool startSection(uint32_t* startOffset) {
|
||||
*startOffset = currentOffset();
|
||||
uint32_t unused;
|
||||
return readVarU32(&unused);
|
||||
static const uint32_t NotStarted = UINT32_MAX;
|
||||
|
||||
MOZ_WARN_UNUSED_RESULT bool startSection(const char* name, uint32_t* startOffset) {
|
||||
const uint8_t* before = cur_;
|
||||
uint32_t numBytes;
|
||||
if (!readVarU32(&numBytes) || bytesRemain() < numBytes)
|
||||
return false;
|
||||
if (!readCStringIf(name)) {
|
||||
cur_ = before;
|
||||
*startOffset = NotStarted;
|
||||
return true;
|
||||
}
|
||||
*startOffset = before - beg_;
|
||||
return true;
|
||||
}
|
||||
MOZ_WARN_UNUSED_RESULT bool finishSection(uint32_t startOffset) {
|
||||
uint32_t currentOffset = cur_ - beg_;
|
||||
|
|
|
@ -3709,11 +3709,8 @@ EncodeSignatureSection(Encoder& e, WasmAstModule& module)
|
|||
if (module.sigs().empty())
|
||||
return true;
|
||||
|
||||
if (!e.writeCString(SigLabel))
|
||||
return false;
|
||||
|
||||
size_t offset;
|
||||
if (!e.startSection(&offset))
|
||||
if (!e.startSection(SigLabel, &offset))
|
||||
return false;
|
||||
|
||||
if (!e.writeVarU32(module.sigs().length()))
|
||||
|
@ -3742,11 +3739,8 @@ EncodeDeclarationSection(Encoder& e, WasmAstModule& module)
|
|||
if (module.funcs().empty())
|
||||
return true;
|
||||
|
||||
if (!e.writeCString(DeclLabel))
|
||||
return false;
|
||||
|
||||
size_t offset;
|
||||
if (!e.startSection(&offset))
|
||||
if (!e.startSection(DeclLabel, &offset))
|
||||
return false;
|
||||
|
||||
if (!e.writeVarU32(module.funcs().length()))
|
||||
|
@ -3790,11 +3784,8 @@ EncodeImportSection(Encoder& e, WasmAstModule& module)
|
|||
if (module.imports().empty())
|
||||
return true;
|
||||
|
||||
if (!e.writeCString(ImportLabel))
|
||||
return false;
|
||||
|
||||
size_t offset;
|
||||
if (!e.startSection(&offset))
|
||||
if (!e.startSection(ImportLabel, &offset))
|
||||
return false;
|
||||
|
||||
for (WasmAstImport* imp : module.imports()) {
|
||||
|
@ -3817,11 +3808,8 @@ EncodeMemorySection(Encoder& e, WasmAstModule& module)
|
|||
if (!module.maybeMemory())
|
||||
return true;
|
||||
|
||||
if (!e.writeCString(MemoryLabel))
|
||||
return false;
|
||||
|
||||
size_t offset;
|
||||
if (!e.startSection(&offset))
|
||||
if (!e.startSection(MemoryLabel, &offset))
|
||||
return false;
|
||||
|
||||
WasmAstMemory& memory = *module.maybeMemory();
|
||||
|
@ -3866,11 +3854,8 @@ EncodeExportSection(Encoder& e, WasmAstModule& module)
|
|||
if (module.exports().empty())
|
||||
return true;
|
||||
|
||||
if (!e.writeCString(ExportLabel))
|
||||
return false;
|
||||
|
||||
size_t offset;
|
||||
if (!e.startSection(&offset))
|
||||
if (!e.startSection(ExportLabel, &offset))
|
||||
return false;
|
||||
|
||||
for (WasmAstExport* exp : module.exports()) {
|
||||
|
@ -3903,11 +3888,8 @@ EncodeTableSection(Encoder& e, WasmAstModule& module)
|
|||
if (!module.maybeTable())
|
||||
return true;
|
||||
|
||||
if (!e.writeCString(TableLabel))
|
||||
return false;
|
||||
|
||||
size_t offset;
|
||||
if (!e.startSection(&offset))
|
||||
if (!e.startSection(TableLabel, &offset))
|
||||
return false;
|
||||
|
||||
if (!e.writeVarU32(module.maybeTable()->elems().length()))
|
||||
|
@ -3923,15 +3905,8 @@ EncodeTableSection(Encoder& e, WasmAstModule& module)
|
|||
}
|
||||
|
||||
static bool
|
||||
EncodeFunctionSection(Encoder& e, WasmAstFunc& func)
|
||||
EncodeFunctionBody(Encoder& e, WasmAstFunc& func)
|
||||
{
|
||||
if (!e.writeCString(FuncLabel))
|
||||
return false;
|
||||
|
||||
size_t offset;
|
||||
if (!e.startSection(&offset))
|
||||
return false;
|
||||
|
||||
if (!e.writeVarU32(func.vars().length()))
|
||||
return false;
|
||||
|
||||
|
@ -3948,8 +3923,25 @@ EncodeFunctionSection(Encoder& e, WasmAstFunc& func)
|
|||
return false;
|
||||
}
|
||||
|
||||
e.finishSection(offset);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
EncodeFunctionBodiesSection(Encoder& e, WasmAstModule& module)
|
||||
{
|
||||
if (module.funcs().empty())
|
||||
return true;
|
||||
|
||||
size_t offset;
|
||||
if (!e.startSection(FuncLabel, &offset))
|
||||
return false;
|
||||
|
||||
for (WasmAstFunc* func : module.funcs()) {
|
||||
if (!EncodeFunctionBody(e, *func))
|
||||
return false;
|
||||
}
|
||||
|
||||
e.finishSection(offset);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3990,11 +3982,8 @@ EncodeDataSection(Encoder& e, WasmAstModule& module)
|
|||
|
||||
const WasmAstSegmentVector& segments = module.maybeMemory()->segments();
|
||||
|
||||
if (!e.writeCString(DataLabel))
|
||||
return false;
|
||||
|
||||
size_t offset;
|
||||
if (!e.startSection(&offset))
|
||||
if (!e.startSection(DataLabel, &offset))
|
||||
return false;
|
||||
|
||||
for (WasmAstSegment* segment : segments) {
|
||||
|
@ -4044,10 +4033,8 @@ EncodeModule(WasmAstModule& module)
|
|||
if (!EncodeExportSection(e, module))
|
||||
return nullptr;
|
||||
|
||||
for (WasmAstFunc* func : module.funcs()) {
|
||||
if (!EncodeFunctionSection(e, *func))
|
||||
return nullptr;
|
||||
}
|
||||
if (!EncodeFunctionBodiesSection(e, module))
|
||||
return nullptr;
|
||||
|
||||
if (!EncodeDataSection(e, module))
|
||||
return nullptr;
|
||||
|
|
|
@ -24,7 +24,7 @@ const dataLabel = "data";
|
|||
const magicError = /failed to match magic number/;
|
||||
const versionError = /failed to match binary version/;
|
||||
const extraError = /failed to consume all bytes of module/;
|
||||
const sectionError = /failed to read section name/;
|
||||
const sectionError = /failed to start section/;
|
||||
|
||||
const I32Code = 0;
|
||||
const I64Code = 1;
|
||||
|
@ -75,8 +75,8 @@ function cstring(name) {
|
|||
function moduleWithSections(sectionArray) {
|
||||
var bytes = moduleHeaderThen();
|
||||
for (let section of sectionArray) {
|
||||
bytes.push(...varU32(section.name.length + 1 + section.body.length));
|
||||
bytes.push(...cstring(section.name));
|
||||
bytes.push(...varU32(section.body.length));
|
||||
bytes.push(...section.body);
|
||||
}
|
||||
bytes.push(0);
|
||||
|
@ -103,12 +103,16 @@ function declSection(decls) {
|
|||
return { name: declLabel, body };
|
||||
}
|
||||
|
||||
function funcSection(func) {
|
||||
var body = [];
|
||||
var locals = varU32(func.locals.length);
|
||||
function funcBody(func) {
|
||||
var body = varU32(func.locals.length);
|
||||
for (let local of func.locals)
|
||||
locals.push(...varU32(local));
|
||||
body = body.concat(locals, func.body);
|
||||
body.push(...varU32(local));
|
||||
body.push(...varU32(func.body.length));
|
||||
return body.concat(...func.body);
|
||||
}
|
||||
|
||||
function bodySection(bodies) {
|
||||
var body = [].concat(...bodies);
|
||||
return { name: funcLabel, body };
|
||||
}
|
||||
|
||||
|
@ -134,7 +138,7 @@ function tableSection(elems) {
|
|||
|
||||
const v2vSig = {args:[], ret:VoidCode};
|
||||
const i2vSig = {args:[I32Code], ret:VoidCode};
|
||||
const v2vFunc = funcSection({locals:[], body:[0]});
|
||||
const v2vBody = funcBody({locals:[], body:[]});
|
||||
|
||||
assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([ {name: sigLabel, body: U32MAX_LEB, } ]))), TypeError, /too many signatures/);
|
||||
assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([ {name: sigLabel, body: [1, ...U32MAX_LEB], } ]))), TypeError, /too many arguments in signature/);
|
||||
|
@ -153,8 +157,8 @@ assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([sigSection([{args:[1
|
|||
|
||||
assertThrowsInstanceOf(() => wasmEval(toBuf(moduleWithSections([sigSection([]), declSection([0])]))), TypeError, /signature index out of range/);
|
||||
assertThrowsInstanceOf(() => wasmEval(toBuf(moduleWithSections([sigSection([v2vSig]), declSection([1])]))), TypeError, /signature index out of range/);
|
||||
assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([sigSection([v2vSig]), declSection([0])]))), TypeError, /fewer function definitions than declarations/);
|
||||
wasmEval(toBuf(moduleWithSections([sigSection([v2vSig]), declSection([0]), v2vFunc])));
|
||||
assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([sigSection([v2vSig]), declSection([0])]))), TypeError, /expected function bodies/);
|
||||
wasmEval(toBuf(moduleWithSections([sigSection([v2vSig]), declSection([0]), bodySection([v2vBody])])));
|
||||
|
||||
assertThrowsInstanceOf(() => wasmEval(toBuf(moduleWithSections([sigSection([v2vSig]), {name: importLabel, body:[]}]))), TypeError);
|
||||
assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([importSection([{sigIndex:0, module:"a", func:"b"}])]))), TypeError, /signature index out of range/);
|
||||
|
@ -166,14 +170,14 @@ wasmEval(toBuf(moduleWithSections([
|
|||
sigSection([v2vSig]),
|
||||
importSection([{sigIndex:0, module:"a", func:""}]),
|
||||
declSection([0]),
|
||||
v2vFunc])), {a:()=>{}});
|
||||
bodySection([v2vBody])])), {a:()=>{}});
|
||||
|
||||
assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([ {name: dataLabel, body: [], } ]))), TypeError, /data section requires a memory section/);
|
||||
|
||||
wasmEval(toBuf(moduleWithSections([tableSection([])])));
|
||||
assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([tableSection([0])]))), TypeError, /table element out of range/);
|
||||
wasmEval(toBuf(moduleWithSections([sigSection([v2vSig]), declSection([0]), tableSection([0]), v2vFunc])));
|
||||
wasmEval(toBuf(moduleWithSections([sigSection([v2vSig]), declSection([0]), tableSection([0,0]), v2vFunc])));
|
||||
assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([sigSection([v2vSig]), declSection([0]), tableSection([0,1]), v2vFunc]))), TypeError, /table element out of range/);
|
||||
wasmEval(toBuf(moduleWithSections([sigSection([v2vSig]), declSection([0,0,0]), tableSection([0,1,0,2]), v2vFunc, v2vFunc, v2vFunc])));
|
||||
wasmEval(toBuf(moduleWithSections([sigSection([v2vSig,i2vSig]), declSection([0,0,1]), tableSection([0,1,2]), v2vFunc, v2vFunc, v2vFunc])));
|
||||
wasmEval(toBuf(moduleWithSections([sigSection([v2vSig]), declSection([0]), tableSection([0]), bodySection([v2vBody])])));
|
||||
wasmEval(toBuf(moduleWithSections([sigSection([v2vSig]), declSection([0]), tableSection([0,0]), bodySection([v2vBody])])));
|
||||
assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([sigSection([v2vSig]), declSection([0]), tableSection([0,1]), bodySection([v2vBody])]))), TypeError, /table element out of range/);
|
||||
wasmEval(toBuf(moduleWithSections([sigSection([v2vSig]), declSection([0,0,0]), tableSection([0,1,0,2]), bodySection([v2vBody, v2vBody, v2vBody])])));
|
||||
wasmEval(toBuf(moduleWithSections([sigSection([v2vSig,i2vSig]), declSection([0,0,1]), tableSection([0,1,2]), bodySection([v2vBody, v2vBody, v2vBody])])));
|
||||
|
|
Загрузка…
Ссылка в новой задаче