Index: src/wasm/encoder.cc |
diff --git a/src/wasm/encoder.cc b/src/wasm/encoder.cc |
index 6f91793f21bd633b60b7485458db3c4a7b60564b..a9b6c89792ceb5e9ff590587dc1e9d5559a41bb8 100644 |
--- a/src/wasm/encoder.cc |
+++ b/src/wasm/encoder.cc |
@@ -30,11 +30,15 @@ |
namespace internal { |
namespace wasm { |
-// Emit a section code and the size as a padded varint that can be patched |
+// Emit a section name and the size as a padded varint that can be patched |
// later. |
-size_t EmitSection(WasmSectionCode code, ZoneBuffer& buffer) { |
- // Emit the section code. |
- buffer.write_u8(code); |
+size_t EmitSection(WasmSection::Code code, ZoneBuffer& buffer) { |
+ // Emit the section name. |
+ const char* name = WasmSection::getName(code); |
+ TRACE("emit section: %s\n", name); |
+ size_t length = WasmSection::getNameLength(code); |
+ buffer.write_size(length); // Section name string size. |
+ buffer.write(reinterpret_cast<const byte*>(name), length); |
// Emit a placeholder for the length. |
return buffer.reserve_u32v(); |
@@ -51,8 +55,6 @@ |
locals_(builder->zone()), |
signature_index_(0), |
exported_(0), |
- func_index_(static_cast<uint32_t>(builder->imports_.size() + |
- builder->functions_.size())), |
body_(builder->zone()), |
name_(builder->zone()), |
i32_temps_(builder->zone()), |
@@ -86,10 +88,6 @@ |
void WasmFunctionBuilder::EmitSetLocal(uint32_t local_index) { |
EmitWithVarInt(kExprSetLocal, local_index); |
-} |
- |
-void WasmFunctionBuilder::EmitTeeLocal(uint32_t local_index) { |
- EmitWithVarInt(kExprTeeLocal, local_index); |
} |
void WasmFunctionBuilder::EmitCode(const byte* code, uint32_t code_size) { |
@@ -145,14 +143,14 @@ |
buffer.write_u32v(signature_index_); |
} |
-void WasmFunctionBuilder::WriteExport(ZoneBuffer& buffer) const { |
+void WasmFunctionBuilder::WriteExport(ZoneBuffer& buffer, |
+ uint32_t func_index) const { |
if (exported_) { |
+ buffer.write_u32v(func_index); |
buffer.write_size(name_.size()); |
if (name_.size() > 0) { |
buffer.write(reinterpret_cast<const byte*>(&name_[0]), name_.size()); |
} |
- buffer.write_u8(kExternalFunction); |
- buffer.write_u32v(func_index_); |
} |
} |
@@ -177,10 +175,7 @@ |
} |
void WasmDataSegmentEncoder::Write(ZoneBuffer& buffer) const { |
- buffer.write_u8(0); // linear memory zero |
- buffer.write_u8(kExprI32Const); |
buffer.write_u32v(dest_); |
- buffer.write_u8(kExprEnd); |
buffer.write_u32v(static_cast<uint32_t>(data_.size())); |
buffer.write(&data_[0], data_.size()); |
} |
@@ -196,11 +191,17 @@ |
signature_map_(zone), |
start_function_index_(-1) {} |
-WasmFunctionBuilder* WasmModuleBuilder::AddFunction(FunctionSig* sig) { |
+uint32_t WasmModuleBuilder::AddFunction() { |
functions_.push_back(new (zone_) WasmFunctionBuilder(this)); |
- // Add the signature if one was provided here. |
- if (sig) functions_.back()->SetSignature(sig); |
- return functions_.back(); |
+ return static_cast<uint32_t>(functions_.size() - 1); |
+} |
+ |
+WasmFunctionBuilder* WasmModuleBuilder::FunctionAt(size_t index) { |
+ if (functions_.size() > index) { |
+ return functions_.at(index); |
+ } else { |
+ return nullptr; |
+ } |
} |
void WasmModuleBuilder::AddDataSegment(WasmDataSegmentEncoder* data) { |
@@ -242,18 +243,16 @@ |
uint32_t WasmModuleBuilder::AddImport(const char* name, int name_length, |
FunctionSig* sig) { |
- DCHECK_EQ(0, functions_.size()); // imports must be added before functions! |
imports_.push_back({AddSignature(sig), name, name_length}); |
return static_cast<uint32_t>(imports_.size() - 1); |
} |
-void WasmModuleBuilder::MarkStartFunction(WasmFunctionBuilder* function) { |
- start_function_index_ = function->func_index(); |
-} |
- |
-uint32_t WasmModuleBuilder::AddGlobal(LocalType type, bool exported, |
- bool mutability) { |
- globals_.push_back(std::make_tuple(type, exported, mutability)); |
+void WasmModuleBuilder::MarkStartFunction(uint32_t index) { |
+ start_function_index_ = index; |
+} |
+ |
+uint32_t WasmModuleBuilder::AddGlobal(LocalType type, bool exported) { |
+ globals_.push_back(std::make_pair(type, exported)); |
return static_cast<uint32_t>(globals_.size() - 1); |
} |
@@ -267,7 +266,7 @@ |
// == Emit signatures ======================================================== |
if (signatures_.size() > 0) { |
- size_t start = EmitSection(kTypeSectionCode, buffer); |
+ size_t start = EmitSection(WasmSection::Code::Signatures, buffer); |
buffer.write_size(signatures_.size()); |
for (FunctionSig* sig : signatures_) { |
@@ -284,130 +283,86 @@ |
FixupSection(buffer, start); |
} |
+ // == Emit globals =========================================================== |
+ if (globals_.size() > 0) { |
+ size_t start = EmitSection(WasmSection::Code::Globals, buffer); |
+ buffer.write_size(globals_.size()); |
+ |
+ for (auto global : globals_) { |
+ buffer.write_u32v(0); // Length of the global name. |
+ buffer.write_u8(WasmOpcodes::LocalTypeCodeFor(global.first)); |
+ buffer.write_u8(global.second); |
+ } |
+ FixupSection(buffer, start); |
+ } |
+ |
// == Emit imports =========================================================== |
if (imports_.size() > 0) { |
- size_t start = EmitSection(kImportSectionCode, buffer); |
+ size_t start = EmitSection(WasmSection::Code::ImportTable, buffer); |
buffer.write_size(imports_.size()); |
for (auto import : imports_) { |
- buffer.write_u32v(import.name_length); // module name length |
- buffer.write(reinterpret_cast<const byte*>(import.name), // module name |
+ buffer.write_u32v(import.sig_index); |
+ buffer.write_u32v(import.name_length); |
+ buffer.write(reinterpret_cast<const byte*>(import.name), |
import.name_length); |
- buffer.write_u32v(0); // field name length |
- buffer.write_u8(kExternalFunction); |
- buffer.write_u32v(import.sig_index); |
+ buffer.write_u32v(0); |
} |
FixupSection(buffer, start); |
} |
// == Emit function signatures =============================================== |
- bool has_names = false; |
if (functions_.size() > 0) { |
- size_t start = EmitSection(kFunctionSectionCode, buffer); |
+ size_t start = EmitSection(WasmSection::Code::FunctionSignatures, buffer); |
buffer.write_size(functions_.size()); |
for (auto function : functions_) { |
function->WriteSignature(buffer); |
if (function->exported()) exports++; |
- if (function->name_.size() > 0) has_names = true; |
} |
FixupSection(buffer, start); |
} |
// == emit function table ==================================================== |
if (indirect_functions_.size() > 0) { |
- size_t start = EmitSection(kTableSectionCode, buffer); |
- buffer.write_u8(1); // table count |
- buffer.write_u8(kWasmAnyFunctionTypeForm); |
- buffer.write_u8(kResizableMaximumFlag); |
+ size_t start = EmitSection(WasmSection::Code::FunctionTable, buffer); |
buffer.write_size(indirect_functions_.size()); |
- buffer.write_size(indirect_functions_.size()); |
+ |
+ for (auto index : indirect_functions_) { |
+ buffer.write_u32v(index); |
+ } |
FixupSection(buffer, start); |
} |
// == emit memory declaration ================================================ |
{ |
- size_t start = EmitSection(kMemorySectionCode, buffer); |
- buffer.write_u8(1); // memory count |
- buffer.write_u32v(kResizableMaximumFlag); |
+ size_t start = EmitSection(WasmSection::Code::Memory, buffer); |
buffer.write_u32v(16); // min memory size |
buffer.write_u32v(16); // max memory size |
- FixupSection(buffer, start); |
- } |
- |
- // == Emit globals =========================================================== |
- if (globals_.size() > 0) { |
- size_t start = EmitSection(kGlobalSectionCode, buffer); |
- buffer.write_size(globals_.size()); |
- |
- for (auto global : globals_) { |
- static const int kLocalTypeIndex = 0; |
- static const int kMutabilityIndex = 2; |
- buffer.write_u8( |
- WasmOpcodes::LocalTypeCodeFor(std::get<kLocalTypeIndex>(global))); |
- buffer.write_u8(std::get<kMutabilityIndex>(global)); |
- switch (std::get<kLocalTypeIndex>(global)) { |
- case kAstI32: { |
- static const byte code[] = {WASM_I32V_1(0)}; |
- buffer.write(code, sizeof(code)); |
- break; |
- } |
- case kAstF32: { |
- static const byte code[] = {WASM_F32(0)}; |
- buffer.write(code, sizeof(code)); |
- break; |
- } |
- case kAstI64: { |
- static const byte code[] = {WASM_I64V_1(0)}; |
- buffer.write(code, sizeof(code)); |
- break; |
- } |
- case kAstF64: { |
- static const byte code[] = {WASM_F64(0.0)}; |
- buffer.write(code, sizeof(code)); |
- break; |
- } |
- default: |
- UNREACHABLE(); |
- } |
- buffer.write_u8(kExprEnd); |
- } |
+ buffer.write_u8(0); // memory export |
+ static_assert(kDeclMemorySize == 3, "memory size must match emit above"); |
FixupSection(buffer, start); |
} |
// == emit exports =========================================================== |
if (exports > 0) { |
- size_t start = EmitSection(kExportSectionCode, buffer); |
+ size_t start = EmitSection(WasmSection::Code::ExportTable, buffer); |
buffer.write_u32v(exports); |
- for (auto function : functions_) function->WriteExport(buffer); |
+ uint32_t index = 0; |
+ for (auto function : functions_) { |
+ function->WriteExport(buffer, index++); |
+ } |
FixupSection(buffer, start); |
} |
// == emit start function index ============================================== |
if (start_function_index_ >= 0) { |
- size_t start = EmitSection(kStartSectionCode, buffer); |
+ size_t start = EmitSection(WasmSection::Code::StartFunction, buffer); |
buffer.write_u32v(start_function_index_); |
- FixupSection(buffer, start); |
- } |
- |
- // == emit function table elements =========================================== |
- if (indirect_functions_.size() > 0) { |
- size_t start = EmitSection(kElementSectionCode, buffer); |
- buffer.write_u8(1); // count of entries |
- buffer.write_u8(0); // table index |
- buffer.write_u8(kExprI32Const); // offset |
- buffer.write_u32v(0); |
- buffer.write_u8(kExprEnd); |
- buffer.write_size(indirect_functions_.size()); // element count |
- |
- for (auto index : indirect_functions_) { |
- buffer.write_u32v(index); |
- } |
- |
FixupSection(buffer, start); |
} |
// == emit code ============================================================== |
if (functions_.size() > 0) { |
- size_t start = EmitSection(kCodeSectionCode, buffer); |
+ size_t start = EmitSection(WasmSection::Code::FunctionBodies, buffer); |
buffer.write_size(functions_.size()); |
for (auto function : functions_) { |
function->WriteBody(buffer); |
@@ -417,33 +372,11 @@ |
// == emit data segments ===================================================== |
if (data_segments_.size() > 0) { |
- size_t start = EmitSection(kDataSectionCode, buffer); |
+ size_t start = EmitSection(WasmSection::Code::DataSegments, buffer); |
buffer.write_size(data_segments_.size()); |
for (auto segment : data_segments_) { |
segment->Write(buffer); |
- } |
- FixupSection(buffer, start); |
- } |
- |
- // == Emit names ============================================================= |
- if (has_names) { |
- // Emit the section code. |
- buffer.write_u8(kUnknownSectionCode); |
- // Emit a placeholder for the length. |
- size_t start = buffer.reserve_u32v(); |
- // Emit the section string. |
- buffer.write_size(4); |
- buffer.write(reinterpret_cast<const byte*>("name"), 4); |
- // Emit the names. |
- buffer.write_size(functions_.size()); |
- for (auto function : functions_) { |
- buffer.write_size(function->name_.size()); |
- if (function->name_.size() > 0) { |
- buffer.write(reinterpret_cast<const byte*>(&function->name_[0]), |
- function->name_.size()); |
- } |
- buffer.write_u8(0); |
} |
FixupSection(buffer, start); |
} |