Bug 1253137 - Baldr: make all the section-ids match and remove c-string labels not in BinaryEncoding.md (r=sunfish)
authorLuke Wagner <luke@mozilla.com>
Fri, 04 Mar 2016 11:03:21 -0600
changeset 325040 e3d938a82d2c670e286b55645ce03a7d04a4c096
parent 325039 6bd419f5a9d04670b250e69e96049e38e7e181f1
child 325041 54e28eab483302f0c9d9ff890506db0c47d2f027
push id1128
push userjlund@mozilla.com
push dateWed, 01 Jun 2016 01:31:59 +0000
treeherdermozilla-release@fe0d30de989d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssunfish
bugs1253137
milestone47.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1253137 - Baldr: make all the section-ids match and remove c-string labels not in BinaryEncoding.md (r=sunfish) MozReview-Commit-ID: HlKooMckgX3
js/src/asmjs/Wasm.cpp
js/src/asmjs/WasmBinary.h
js/src/asmjs/WasmGenerator.h
js/src/asmjs/WasmText.cpp
js/src/jit-test/tests/wasm/binary.js
--- a/js/src/asmjs/Wasm.cpp
+++ b/js/src/asmjs/Wasm.cpp
@@ -699,20 +699,20 @@ struct ImportName
 typedef Vector<ImportName, 0, SystemAllocPolicy> ImportNameVector;
 
 /*****************************************************************************/
 // wasm decoding and generation
 
 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;
 
     uint32_t numSigs;
     if (!d.readVarU32(&numSigs))
         return Fail(cx, d, "expected number of signatures");
 
@@ -776,20 +776,20 @@ DecodeSignatureIndex(JSContext* cx, Deco
     if (sigIndex >= init.sigs.length())
         return Fail(cx, d, "signature index out of range");
 
     *sig = &init.sigs[sigIndex];
     return true;
 }
 
 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;
 
     uint32_t numDecls;
     if (!d.readVarU32(&numDecls))
         return Fail(cx, d, "expected number of declarations");
 
@@ -806,20 +806,20 @@ DecodeDeclarationSection(JSContext* cx, 
 
     if (!d.finishSection(sectionStart))
         return Fail(cx, d, "decls section byte size mismatch");
 
     return true;
 }
 
 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;
 
     if (!d.readVarU32(&init->numTableElems))
         return Fail(cx, d, "expected number of table elems");
 
     if (init->numTableElems > MaxTableElems)
@@ -906,47 +906,47 @@ DecodeImport(JSContext* cx, Decoder& d, 
     UniqueChars funcName = d.readCString();
     if (!funcName)
         return Fail(cx, d, "expected import func name");
 
     return importNames->emplaceBack(Move(moduleName), Move(funcName));
 }
 
 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;
     }
 
     if (!d.finishSection(sectionStart))
         return Fail(cx, d, "import section byte size mismatch");
 
     return true;
 }
 
 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;
 
     uint32_t initialSizePages;
     if (!d.readVarU32(&initialSizePages))
         return Fail(cx, d, "expected initial memory size");
 
@@ -1025,31 +1025,31 @@ DecodeFunctionExport(JSContext* cx, Deco
     UniqueChars fieldName = DecodeFieldName(cx, d, dupSet);
     if (!fieldName)
         return false;
 
     return mg.declareExport(Move(fieldName), funcIndex);
 }
 
 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;
 
     CStringSet dupSet(cx);
     if (!dupSet.init())
         return false;
 
     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");
 
     for (uint32_t i = 0; i < numExports; i++) {
         if (!DecodeFunctionExport(cx, d, mg, &dupSet))
             return false;
     }
@@ -1119,23 +1119,23 @@ DecodeFunctionBody(JSContext* cx, Decode
 
     int64_t after = PRMJ_Now();
     unsigned generateTime = (after - before) / PRMJ_USEC_PER_MSEC;
 
     return mg.finishFuncDef(funcIndex, generateTime, &fg);
 }
 
 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) {
         if (mg.numFuncSigs() != 0)
             return Fail(cx, d, "expected function bodies");
 
         return mg.finishFuncDefs();
     }
@@ -1147,35 +1147,36 @@ DecodeFunctionBodiesSection(JSContext* c
 
     if (!d.finishSection(sectionStart))
         return Fail(cx, d, "function section byte size mismatch");
 
     return mg.finishFuncDefs();
 }
 
 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;
 
     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");
 
         if (dstOffset < prevEnd)
             return Fail(cx, d, "data segments must be disjoint and ordered");
 
         uint32_t numBytes;
@@ -1212,42 +1213,42 @@ DecodeModule(JSContext* cx, UniqueChars 
 
     if (!d.readFixedU32(&u32) || u32 != EncodingVersion)
         return Fail(cx, d, "failed to match binary version");
 
     UniqueModuleGeneratorData init = js::MakeUnique<ModuleGeneratorData>(cx);
     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;
 
     while (!d.done()) {
         if (!d.skipSection())
             return Fail(cx, d, "failed to skip unknown section at end");
     }
--- a/js/src/asmjs/WasmBinary.h
+++ b/js/src/asmjs/WasmBinary.h
@@ -25,41 +25,31 @@
 #include "builtin/SIMD.h"
 
 namespace js {
 
 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
 
-// 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
-
-// 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
 {
     // Control opcodes
     Nop,
     Block,
     Loop,
     If,
@@ -648,27 +638,16 @@ class Decoder
         for (; cur_ != end_; cur_++) {
             if (!*cur_) {
                 cur_++;
                 return UniqueChars(DuplicateString(begin));
             }
         }
         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_;
         if (bytesRemain() < numBytes)
             return false;
         cur_ += numBytes;
         return true;
     }
--- a/js/src/asmjs/WasmGenerator.h
+++ b/js/src/asmjs/WasmGenerator.h
@@ -24,16 +24,25 @@
 #include "asmjs/WasmModule.h"
 #include "jit/MacroAssembler.h"
 
 namespace js {
 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.
 
 struct SlowFunction
 {
     SlowFunction(uint32_t index, unsigned ms, unsigned lineOrBytecode)
      : index(index), ms(ms), lineOrBytecode(lineOrBytecode)
     {}
--- a/js/src/asmjs/WasmText.cpp
+++ b/js/src/asmjs/WasmText.cpp
@@ -3714,23 +3714,23 @@ EncodeExpr(Encoder& e, WasmAstExpr& expr
     }
     MOZ_CRASH("Bad expr kind");
 }
 
 /*****************************************************************************/
 // 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()))
         return false;
 
     for (WasmAstSig* sig : module.sigs()) {
         if (!e.writeVarU32(sig->args().length()))
             return false;
@@ -3744,23 +3744,23 @@ EncodeSignatureSection(Encoder& e, WasmA
         }
     }
 
     e.finishSection(offset);
     return true;
 }
 
 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()))
         return false;
 
     for (WasmAstFunc* func : module.funcs()) {
         if (!e.writeVarU32(func->sig().index()))
             return false;
@@ -3789,47 +3789,45 @@ EncodeImport(Encoder& e, WasmAstImport& 
 
     if (!EncodeCString(e, imp.func()))
         return false;
 
     return true;
 }
 
 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();
 
     if (!e.writeVarU32(memory.initialSize()))
         return false;
 
     uint32_t maxSize = memory.maxSize() ? *memory.maxSize() : memory.initialSize();
@@ -3859,29 +3857,29 @@ EncodeFunctionExport(Encoder& e, WasmAst
 
     if (!EncodeCString(e, exp.name()))
         return false;
 
     return true;
 }
 
 static bool
-EncodeExportSection(Encoder& e, WasmAstModule& module)
+EncodeExportTable(Encoder& e, WasmAstModule& module)
 {
     uint32_t numFuncExports = 0;
     for (WasmAstExport* exp : module.exports()) {
         if (exp->kind() == WasmAstExportKind::Func)
             numFuncExports++;
     }
 
     if (!numFuncExports)
         return true;
 
     size_t offset;
-    if (!e.startSection(ExportLabel, &offset))
+    if (!e.startSection(ExportTableId, &offset))
         return false;
 
     if (!e.writeVarU32(numFuncExports))
         return false;
 
     for (WasmAstExport* exp : module.exports()) {
         switch (exp->kind()) {
           case WasmAstExportKind::Func:
@@ -3893,23 +3891,23 @@ EncodeExportSection(Encoder& e, WasmAstM
         }
     }
 
     e.finishSection(offset);
     return true;
 }
 
 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()))
         return false;
 
     for (WasmRef& ref : module.maybeTable()->elems()) {
         if (!e.writeVarU32(ref.index()))
             return false;
@@ -3937,23 +3935,23 @@ EncodeFunctionBody(Encoder& e, WasmAstFu
         if (!EncodeExpr(e, *expr))
             return false;
     }
 
     return true;
 }
 
 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()) {
         if (!EncodeFunctionBody(e, *func))
             return false;
     }
 
     e.finishSection(offset);
@@ -3985,37 +3983,35 @@ EncodeDataSegment(Encoder& e, WasmAstSeg
 
     if (!e.writeRawData(bytes.begin(), bytes.length()))
         return false;
 
     return true;
 }
 
 static bool
-EncodeDataSection(Encoder& e, WasmAstModule& module)
+EncodeDataSegments(Encoder& e, WasmAstModule& module)
 {
     if (!module.maybeMemory() || module.maybeMemory()->segments().empty())
         return true;
 
     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;
 }
 
 static UniqueBytecode
 EncodeModule(WasmAstModule& module)
 {
     UniqueBytecode bytecode = MakeUnique<Bytecode>();
@@ -4025,38 +4021,38 @@ EncodeModule(WasmAstModule& module)
     Encoder e(*bytecode);
 
     if (!e.writeFixedU32(MagicNumber))
         return nullptr;
 
     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);
 }
 
 /*****************************************************************************/
 
 UniqueBytecode
--- a/js/src/jit-test/tests/wasm/binary.js
+++ b/js/src/jit-test/tests/wasm/binary.js
@@ -8,23 +8,23 @@ const magic3 = 0x6d;  // 'm'
 
 // EncodingVersion = 10 (to be changed to 1 at some point in the future)
 const ver0 = 0x0a;
 const ver1 = 0x00;
 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/;
 const unknownSectionError = /failed to skip unknown section at end/;
 const sectionError = /failed to start section/;
 
 const I32Code = 0;
 const I64Code = 1;
@@ -101,97 +101,96 @@ function sigSection(sigs) {
     var body = [];
     body.push(...varU32(sigs.length));
     for (let sig of sigs) {
         body.push(...varU32(sig.args.length));
         body.push(...varU32(sig.ret));
         for (let arg of sig.args)
             body.push(...varU32(arg));
     }
-    return { name: sigLabel, body };
+    return { name: sigId, body };
 }
 
 function declSection(decls) {
     var body = [];
     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) {
     var body = varU32(func.locals.length);
     for (let local of func.locals)
         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 };
+    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) {
     var body = [];
     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])])));
 wasmEval(toBuf(moduleWithSections([sigSection([i2vSig])])));
 wasmEval(toBuf(moduleWithSections([sigSection([v2vSig, i2vSig])])));
 
 assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([sigSection([{args:[], ret:100}])]))), TypeError, /bad expression type/);
 assertErrorMessage(() => wasmEval(toBuf(moduleWithSections([sigSection([{args:[100], ret:VoidCode}])]))), TypeError, /bad value type/);
 
 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, /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([])])));
 wasmEval(toBuf(moduleWithSections([sigSection([v2vSig]), importSection([{sigIndex:0, module:"a", func:""}])])), {a:()=>{}});
 
 wasmEval(toBuf(moduleWithSections([
     sigSection([v2vSig]),
     importSection([{sigIndex:0, module:"a", func:""}]),
     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/);
 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])])));