Bug 1253137 - Baldr: make all the section-ids match and remove c-string labels not in BinaryEncoding.md (r=sunfish)

MozReview-Commit-ID: HlKooMckgX3
This commit is contained in:
Luke Wagner 2016-03-04 11:03:21 -06:00
Родитель ddad2020aa
Коммит 12ecf44921
5 изменённых файлов: 107 добавлений и 123 удалений

Просмотреть файл

@ -704,10 +704,10 @@ typedef Vector<ImportName, 0, SystemAllocPolicy> ImportNameVector;
typedef HashSet<const DeclaredSig*, SigHashPolicy> SigSet;
static bool
DecodeSignatureSection(JSContext* cx, Decoder& d, ModuleGeneratorData* init)
DecodeSignatures(JSContext* cx, Decoder& d, ModuleGeneratorData* init)
{
uint32_t sectionStart;
if (!d.startSection(SigLabel, &sectionStart))
if (!d.startSection(SignaturesId, &sectionStart))
return Fail(cx, d, "failed to start section");
if (sectionStart == Decoder::NotStarted)
return true;
@ -781,10 +781,10 @@ DecodeSignatureIndex(JSContext* cx, Decoder& d, const ModuleGeneratorData& init,
}
static bool
DecodeDeclarationSection(JSContext* cx, Decoder& d, ModuleGeneratorData* init)
DecodeFunctionSignatures(JSContext* cx, Decoder& d, ModuleGeneratorData* init)
{
uint32_t sectionStart;
if (!d.startSection(DeclLabel, &sectionStart))
if (!d.startSection(FunctionSignaturesId, &sectionStart))
return Fail(cx, d, "failed to start section");
if (sectionStart == Decoder::NotStarted)
return true;
@ -811,10 +811,10 @@ DecodeDeclarationSection(JSContext* cx, Decoder& d, ModuleGeneratorData* init)
}
static bool
DecodeTableSection(JSContext* cx, Decoder& d, ModuleGeneratorData* init)
DecodeFunctionTable(JSContext* cx, Decoder& d, ModuleGeneratorData* init)
{
uint32_t sectionStart;
if (!d.startSection(TableLabel, &sectionStart))
if (!d.startSection(FunctionTableId, &sectionStart))
return Fail(cx, d, "failed to start section");
if (sectionStart == Decoder::NotStarted)
return true;
@ -911,21 +911,22 @@ DecodeImport(JSContext* cx, Decoder& d, ModuleGeneratorData* init, ImportNameVec
}
static bool
DecodeImportSection(JSContext* cx, Decoder& d, ModuleGeneratorData* init, ImportNameVector* importNames)
DecodeImportTable(JSContext* cx, Decoder& d, ModuleGeneratorData* init, ImportNameVector* importNames)
{
uint32_t sectionStart;
if (!d.startSection(ImportLabel, &sectionStart))
if (!d.startSection(ImportTableId, &sectionStart))
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)
return Fail(cx, d, "too many imports");
uint32_t numImports;
if (!d.readVarU32(&numImports))
return Fail(cx, d, "failed to read number of imports");
if (!d.readCStringIf(FuncLabel))
return Fail(cx, d, "expected 'func' import subsection");
if (numImports > MaxImports)
return Fail(cx, d, "too many imports");
for (uint32_t i = 0; i < numImports; i++) {
if (!DecodeImport(cx, d, init, importNames))
return false;
}
@ -937,11 +938,10 @@ DecodeImportSection(JSContext* cx, Decoder& d, ModuleGeneratorData* init, Import
}
static bool
DecodeMemorySection(JSContext* cx, Decoder& d, ModuleGenerator& mg,
MutableHandle<ArrayBufferObject*> heap)
DecodeMemory(JSContext* cx, Decoder& d, ModuleGenerator& mg, MutableHandle<ArrayBufferObject*> heap)
{
uint32_t sectionStart;
if (!d.startSection(MemoryLabel, &sectionStart))
if (!d.startSection(MemoryId, &sectionStart))
return Fail(cx, d, "failed to start section");
if (sectionStart == Decoder::NotStarted)
return true;
@ -1030,10 +1030,10 @@ DecodeFunctionExport(JSContext* cx, Decoder& d, ModuleGenerator& mg, CStringSet*
}
static bool
DecodeExportsSection(JSContext* cx, Decoder& d, ModuleGenerator& mg)
DecodeExportTable(JSContext* cx, Decoder& d, ModuleGenerator& mg)
{
uint32_t sectionStart;
if (!d.startSection(ExportLabel, &sectionStart))
if (!d.startSection(ExportTableId, &sectionStart))
return Fail(cx, d, "failed to start section");
if (sectionStart == Decoder::NotStarted)
return true;
@ -1044,7 +1044,7 @@ DecodeExportsSection(JSContext* cx, Decoder& d, ModuleGenerator& mg)
uint32_t numExports;
if (!d.readVarU32(&numExports))
return false;
return Fail(cx, d, "failed to read number of exports");
if (numExports > MaxExports)
return Fail(cx, d, "too many exports");
@ -1124,13 +1124,13 @@ DecodeFunctionBody(JSContext* cx, Decoder& d, ModuleGenerator& mg, uint32_t func
}
static bool
DecodeFunctionBodiesSection(JSContext* cx, Decoder& d, ModuleGenerator& mg)
DecodeFunctionBodies(JSContext* cx, Decoder& d, ModuleGenerator& mg)
{
if (!mg.startFuncDefs())
return false;
uint32_t sectionStart;
if (!d.startSection(FuncLabel, &sectionStart))
if (!d.startSection(FunctionBodiesId, &sectionStart))
return Fail(cx, d, "failed to start section");
if (sectionStart == Decoder::NotStarted) {
@ -1152,10 +1152,10 @@ DecodeFunctionBodiesSection(JSContext* cx, Decoder& d, ModuleGenerator& mg)
}
static bool
DecodeDataSection(JSContext* cx, Decoder& d, Handle<ArrayBufferObject*> heap)
DecodeDataSegments(JSContext* cx, Decoder& d, Handle<ArrayBufferObject*> heap)
{
uint32_t sectionStart;
if (!d.startSection(DataLabel, &sectionStart))
if (!d.startSection(DataSegmentsId, &sectionStart))
return Fail(cx, d, "failed to start section");
if (sectionStart == Decoder::NotStarted)
return true;
@ -1163,14 +1163,15 @@ DecodeDataSection(JSContext* cx, Decoder& d, Handle<ArrayBufferObject*> heap)
if (!heap)
return Fail(cx, d, "data section requires a memory section");
uint32_t numSegments;
if (!d.readVarU32(&numSegments))
return Fail(cx, d, "failed to read number of data segments");
uint8_t* const heapBase = heap->dataPointer();
uint32_t const heapLength = heap->byteLength();
uint32_t prevEnd = 0;
for (uint32_t i = 0; !d.readCStringIf(EndLabel); i++) {
if (!d.readCStringIf(SegmentLabel))
return Fail(cx, d, "expected segment tag");
for (uint32_t i = 0; i < numSegments; i++) {
uint32_t dstOffset;
if (!d.readVarU32(&dstOffset))
return Fail(cx, d, "expected segment destination offset");
@ -1217,32 +1218,32 @@ DecodeModule(JSContext* cx, UniqueChars file, const uint8_t* bytes, uint32_t len
if (!init)
return false;
if (!DecodeSignatureSection(cx, d, init.get()))
if (!DecodeSignatures(cx, d, init.get()))
return false;
if (!DecodeImportSection(cx, d, init.get(), importNames))
if (!DecodeImportTable(cx, d, init.get(), importNames))
return false;
if (!DecodeDeclarationSection(cx, d, init.get()))
if (!DecodeFunctionSignatures(cx, d, init.get()))
return false;
if (!DecodeTableSection(cx, d, init.get()))
if (!DecodeFunctionTable(cx, d, init.get()))
return false;
ModuleGenerator mg(cx);
if (!mg.init(Move(init), Move(file)))
return false;
if (!DecodeMemorySection(cx, d, mg, heap))
if (!DecodeMemory(cx, d, mg, heap))
return false;
if (!DecodeExportsSection(cx, d, mg))
if (!DecodeExportTable(cx, d, mg))
return false;
if (!DecodeFunctionBodiesSection(cx, d, mg))
if (!DecodeFunctionBodies(cx, d, mg))
return false;
if (!DecodeDataSection(cx, d, heap))
if (!DecodeDataSegments(cx, d, heap))
return false;
CacheableCharsVector funcNames;

Просмотреть файл

@ -30,31 +30,21 @@ class PropertyName;
namespace wasm {
// Module generator limits
static const unsigned MaxSigs = 4 * 1024;
static const unsigned MaxFuncs = 512 * 1024;
static const unsigned MaxImports = 4 * 1024;
static const unsigned MaxExports = 4 * 1024;
static const unsigned MaxTableElems = 128 * 1024;
static const unsigned MaxArgsPerFunc = 4 * 1024;
// Module header constants
static const uint32_t MagicNumber = 0x6d736100; // "\0asm"
static const uint32_t EncodingVersion = 0xa; // will change while iterating toward release,
// change to 1 at release, and hopefully never
// change after that
static const uint32_t MagicNumber = 0x6d736100; // "\0asm"
static const uint32_t EncodingVersion = 0xa; // will change while iterating toward release,
// change to 1 at release, and hopefully never
// change after that
// Names:
static const char SigLabel[] = "sig";
static const char ImportLabel[] = "import";
static const char DeclLabel[] = "decl";
static const char TableLabel[] = "table";
static const char MemoryLabel[] = "memory";
static const char ExportLabel[] = "export";
static const char FuncLabel[] = "func";
static const char DataLabel[] = "data";
static const char SegmentLabel[] = "segment";
static const char EndLabel[] = "";
// Section ids:
static const char SignaturesId[] = "signatures";
static const char ImportTableId[] = "import_table";
static const char FunctionSignaturesId[] = "function_signatures";
static const char FunctionTableId[] = "function_table";
static const char MemoryId[] = "memory";
static const char ExportTableId[] = "export_table";
static const char FunctionBodiesId[] = "function_bodies";
static const char DataSegmentsId[] = "data_segments";
enum class Expr : uint16_t
{
@ -653,17 +643,6 @@ class Decoder
}
return nullptr;
}
MOZ_WARN_UNUSED_RESULT bool readCStringIf(const char* tag) {
for (const uint8_t* p = cur_; p != end_; p++, tag++) {
if (*p != *tag)
return false;
if (!*p) {
cur_ = p + 1;
return true;
}
}
return false;
}
MOZ_WARN_UNUSED_RESULT bool readRawData(uint32_t numBytes, const uint8_t** bytes = nullptr) {
if (bytes)
*bytes = cur_;

Просмотреть файл

@ -29,6 +29,15 @@ namespace wasm {
class FunctionGenerator;
// Module generator limits
static const unsigned MaxSigs = 4 * 1024;
static const unsigned MaxFuncs = 512 * 1024;
static const unsigned MaxImports = 4 * 1024;
static const unsigned MaxExports = 4 * 1024;
static const unsigned MaxTableElems = 128 * 1024;
static const unsigned MaxArgsPerFunc = 4 * 1024;
// A slow function describes a function that took longer than msThreshold to
// validate and compile.

Просмотреть файл

@ -3719,13 +3719,13 @@ EncodeExpr(Encoder& e, WasmAstExpr& expr)
// wasm AST binary serialization
static bool
EncodeSignatureSection(Encoder& e, WasmAstModule& module)
EncodeSignatures(Encoder& e, WasmAstModule& module)
{
if (module.sigs().empty())
return true;
size_t offset;
if (!e.startSection(SigLabel, &offset))
if (!e.startSection(SignaturesId, &offset))
return false;
if (!e.writeVarU32(module.sigs().length()))
@ -3749,13 +3749,13 @@ EncodeSignatureSection(Encoder& e, WasmAstModule& module)
}
static bool
EncodeDeclarationSection(Encoder& e, WasmAstModule& module)
EncodeFunctionSignatures(Encoder& e, WasmAstModule& module)
{
if (module.funcs().empty())
return true;
size_t offset;
if (!e.startSection(DeclLabel, &offset))
if (!e.startSection(FunctionSignaturesId, &offset))
return false;
if (!e.writeVarU32(module.funcs().length()))
@ -3794,37 +3794,35 @@ EncodeImport(Encoder& e, WasmAstImport& imp)
}
static bool
EncodeImportSection(Encoder& e, WasmAstModule& module)
EncodeImportTable(Encoder& e, WasmAstModule& module)
{
if (module.imports().empty())
return true;
size_t offset;
if (!e.startSection(ImportLabel, &offset))
if (!e.startSection(ImportTableId, &offset))
return false;
if (!e.writeVarU32(module.imports().length()))
return false;
for (WasmAstImport* imp : module.imports()) {
if (!e.writeCString(FuncLabel))
return false;
if (!EncodeImport(e, *imp))
return false;
}
if (!e.writeCString(EndLabel))
return false;
e.finishSection(offset);
return true;
}
static bool
EncodeMemorySection(Encoder& e, WasmAstModule& module)
EncodeMemory(Encoder& e, WasmAstModule& module)
{
if (!module.maybeMemory())
return true;
size_t offset;
if (!e.startSection(MemoryLabel, &offset))
if (!e.startSection(MemoryId, &offset))
return false;
WasmAstMemory& memory = *module.maybeMemory();
@ -3864,7 +3862,7 @@ EncodeFunctionExport(Encoder& e, WasmAstExport& exp)
}
static bool
EncodeExportSection(Encoder& e, WasmAstModule& module)
EncodeExportTable(Encoder& e, WasmAstModule& module)
{
uint32_t numFuncExports = 0;
for (WasmAstExport* exp : module.exports()) {
@ -3876,7 +3874,7 @@ EncodeExportSection(Encoder& e, WasmAstModule& module)
return true;
size_t offset;
if (!e.startSection(ExportLabel, &offset))
if (!e.startSection(ExportTableId, &offset))
return false;
if (!e.writeVarU32(numFuncExports))
@ -3898,13 +3896,13 @@ EncodeExportSection(Encoder& e, WasmAstModule& module)
}
static bool
EncodeTableSection(Encoder& e, WasmAstModule& module)
EncodeFunctionTable(Encoder& e, WasmAstModule& module)
{
if (!module.maybeTable())
return true;
size_t offset;
if (!e.startSection(TableLabel, &offset))
if (!e.startSection(FunctionTableId, &offset))
return false;
if (!e.writeVarU32(module.maybeTable()->elems().length()))
@ -3942,13 +3940,13 @@ EncodeFunctionBody(Encoder& e, WasmAstFunc& func)
}
static bool
EncodeFunctionBodiesSection(Encoder& e, WasmAstModule& module)
EncodeFunctionBodies(Encoder& e, WasmAstModule& module)
{
if (module.funcs().empty())
return true;
size_t offset;
if (!e.startSection(FuncLabel, &offset))
if (!e.startSection(FunctionBodiesId, &offset))
return false;
for (WasmAstFunc* func : module.funcs()) {
@ -3990,7 +3988,7 @@ EncodeDataSegment(Encoder& e, WasmAstSegment& segment)
}
static bool
EncodeDataSection(Encoder& e, WasmAstModule& module)
EncodeDataSegments(Encoder& e, WasmAstModule& module)
{
if (!module.maybeMemory() || module.maybeMemory()->segments().empty())
return true;
@ -3998,19 +3996,17 @@ EncodeDataSection(Encoder& e, WasmAstModule& module)
const WasmAstSegmentVector& segments = module.maybeMemory()->segments();
size_t offset;
if (!e.startSection(DataLabel, &offset))
if (!e.startSection(DataSegmentsId, &offset))
return false;
if (!e.writeVarU32(segments.length()))
return false;
for (WasmAstSegment* segment : segments) {
if (!e.writeCString(SegmentLabel))
return false;
if (!EncodeDataSegment(e, *segment))
return false;
}
if (!e.writeCString(EndLabel))
return false;
e.finishSection(offset);
return true;
}
@ -4030,28 +4026,28 @@ EncodeModule(WasmAstModule& module)
if (!e.writeFixedU32(EncodingVersion))
return nullptr;
if (!EncodeSignatureSection(e, module))
if (!EncodeSignatures(e, module))
return nullptr;
if (!EncodeImportSection(e, module))
if (!EncodeImportTable(e, module))
return nullptr;
if (!EncodeDeclarationSection(e, module))
if (!EncodeFunctionSignatures(e, module))
return nullptr;
if (!EncodeTableSection(e, module))
if (!EncodeFunctionTable(e, module))
return nullptr;
if (!EncodeMemorySection(e, module))
if (!EncodeMemory(e, module))
return nullptr;
if (!EncodeExportSection(e, module))
if (!EncodeExportTable(e, module))
return nullptr;
if (!EncodeFunctionBodiesSection(e, module))
if (!EncodeFunctionBodies(e, module))
return nullptr;
if (!EncodeDataSection(e, module))
if (!EncodeDataSegments(e, module))
return nullptr;
return Move(bytecode);

Просмотреть файл

@ -13,13 +13,13 @@ const ver2 = 0x00;
const ver3 = 0x00;
// Section names
const sigLabel = "sig";
const declLabel = "decl";
const tableLabel = "table";
const importLabel = "import";
const exportLabel = "export";
const funcLabel = "func";
const dataLabel = "data";
const sigId = "signatures";
const importId = "import_table";
const functionSignaturesId = "function_signatures";
const functionTableId = "function_table";
const exportTableId = "export_table";
const functionBodiesId = "function_bodies";
const dataSegmentsId = "data_segments";
const magicError = /failed to match magic number/;
const versionError = /failed to match binary version/;
@ -106,7 +106,7 @@ function sigSection(sigs) {
for (let arg of sig.args)
body.push(...varU32(arg));
}
return { name: sigLabel, body };
return { name: sigId, body };
}
function declSection(decls) {
@ -114,7 +114,7 @@ function declSection(decls) {
body.push(...varU32(decls.length));
for (let decl of decls)
body.push(...varU32(decl));
return { name: declLabel, body };
return { name: functionSignaturesId, body };
}
function funcBody(func) {
@ -127,19 +127,18 @@ function funcBody(func) {
function bodySection(bodies) {
var body = [].concat(...bodies);
return { name: funcLabel, body };
return { name: functionBodiesId, body };
}
function importSection(imports) {
var body = [];
body.push(...varU32(imports.length));
for (let imp of imports) {
body.push(...cstring(funcLabel));
body.push(...varU32(imp.sigIndex));
body.push(...cstring(imp.module));
body.push(...cstring(imp.func));
}
body.push(0);
return { name: importLabel, body };
return { name: importId, body };
}
function tableSection(elems) {
@ -147,19 +146,19 @@ function tableSection(elems) {
body.push(...varU32(elems.length));
for (let i of elems)
body.push(...varU32(i));
return { name: tableLabel, body };
return { name: functionTableId, body };
}
const v2vSig = {args:[], ret:VoidCode};
const i2vSig = {args:[I32Code], ret:VoidCode};
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/);
assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([ {name: sigId, body: U32MAX_LEB, } ]))), TypeError, /too many signatures/);
assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([ {name: sigId, body: [1, ...U32MAX_LEB], } ]))), TypeError, /too many arguments in signature/);
assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([sigSection([{args:[], ret:VoidCode}, {args:[], ret:VoidCode}])]))), TypeError, /duplicate signature/);
assertThrowsInstanceOf(() => wasmEval(toBuf(moduleWithSections([{name: sigLabel, body: [1]}]))), TypeError);
assertThrowsInstanceOf(() => wasmEval(toBuf(moduleWithSections([{name: sigLabel, body: [1, 1, 0]}]))), TypeError);
assertThrowsInstanceOf(() => wasmEval(toBuf(moduleWithSections([{name: sigId, body: [1]}]))), TypeError);
assertThrowsInstanceOf(() => wasmEval(toBuf(moduleWithSections([{name: sigId, body: [1, 1, 0]}]))), TypeError);
wasmEval(toBuf(moduleWithSections([sigSection([])])));
wasmEval(toBuf(moduleWithSections([sigSection([v2vSig])])));
@ -174,7 +173,7 @@ assertThrowsInstanceOf(() => wasmEval(toBuf(moduleWithSections([sigSection([v2vS
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);
assertThrowsInstanceOf(() => wasmEval(toBuf(moduleWithSections([sigSection([v2vSig]), {name: importId, body:[]}]))), TypeError);
assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([importSection([{sigIndex:0, module:"a", func:"b"}])]))), TypeError, /signature index out of range/);
assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([sigSection([v2vSig]), importSection([{sigIndex:1, module:"a", func:"b"}])]))), TypeError, /signature index out of range/);
wasmEval(toBuf(moduleWithSections([sigSection([v2vSig]), importSection([])])));
@ -186,7 +185,7 @@ wasmEval(toBuf(moduleWithSections([
declSection([0]),
bodySection([v2vBody])])), {a:()=>{}});
assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([ {name: dataLabel, body: [], } ]))), TypeError, /data section requires a memory section/);
assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([ {name: dataSegmentsId, body: [], } ]))), TypeError, /data section requires a memory section/);
wasmEval(toBuf(moduleWithSections([tableSection([])])));
assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([tableSection([0])]))), TypeError, /table element out of range/);