| 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);
|
| }
|
|
|