Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(110)

Unified Diff: src/wasm/module-decoder.cc

Issue 1783593002: [wasm] Encode function signatures, bodies, and names as separate sections. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Added unittests Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/wasm/decoder.h ('k') | src/wasm/wasm-module.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/wasm/module-decoder.cc
diff --git a/src/wasm/module-decoder.cc b/src/wasm/module-decoder.cc
index 965a22dc19fafe6e434832766ae3892ff8792302..6d4b03666017261231039eee0c3b554a8d9843a6 100644
--- a/src/wasm/module-decoder.cc
+++ b/src/wasm/module-decoder.cc
@@ -117,6 +117,48 @@ class ModuleDecoder : public Decoder {
}
break;
}
+ case kDeclFunctionSignatures: {
+ // Functions require a signature table first.
+ CheckForPreviousSection(sections, kDeclSignatures, true);
+ int length;
+ uint32_t functions_count = consume_u32v(&length, "functions count");
+ module->functions.reserve(SafeReserve(functions_count));
+ for (uint32_t i = 0; i < functions_count; i++) {
+ module->functions.push_back(
+ {nullptr, i, 0, 0, 0, 0, 0, 0, false, false});
+ WasmFunction* function = &module->functions.back();
+ function->sig_index = consume_sig_index(module, &function->sig);
+ }
+ break;
+ }
+ case kDeclFunctionBodies: {
+ // Function bodies should follow signatures.
+ CheckForPreviousSection(sections, kDeclFunctionSignatures, true);
+ int length;
+ const byte* pos = pc_;
+ uint32_t functions_count = consume_u32v(&length, "functions count");
+ if (functions_count != module->functions.size()) {
+ error(pos, pos, "function body count %u mismatch (%u expected)",
+ functions_count,
+ static_cast<uint32_t>(module->functions.size()));
+ break;
+ }
+ for (uint32_t i = 0; i < functions_count; i++) {
+ WasmFunction* function = &module->functions[i];
+ int length;
+ uint32_t size = consume_u32v(&length, "body size");
+ function->code_start_offset = pc_offset();
+ function->code_end_offset = pc_offset() + size;
+
+ TRACE(" +%d %-20s: (%d bytes)\n", pc_offset(), "function body",
+ size);
+ pc_ += size;
+ if (pc_ > limit_) {
+ error(pc_, "function body extends beyond end of file");
+ }
+ }
+ break;
+ }
case kDeclFunctions: {
// Functions require a signature table first.
CheckForPreviousSection(sections, kDeclSignatures, true);
@@ -152,6 +194,35 @@ class ModuleDecoder : public Decoder {
}
break;
}
+ case kDeclNames: {
+ // Names correspond to functions.
+ CheckForPreviousSection(sections, kDeclFunctionSignatures, true);
+ int length;
+ const byte* pos = pc_;
+ uint32_t functions_count = consume_u32v(&length, "functions count");
+ if (functions_count != module->functions.size()) {
+ error(pos, pos, "function name count %u mismatch (%u expected)",
+ functions_count,
+ static_cast<uint32_t>(module->functions.size()));
+ break;
+ }
+
+ for (uint32_t i = 0; i < functions_count; i++) {
+ WasmFunction* function = &module->functions[i];
+ function->name_offset =
+ consume_string(&function->name_length, "function name");
+
+ uint32_t local_names_count =
+ consume_u32v(&length, "local names count");
+ for (uint32_t j = 0; j < local_names_count; j++) {
+ uint32_t unused = 0;
+ uint32_t offset = consume_string(&unused, "local name");
+ USE(unused);
+ USE(offset);
+ }
+ }
+ break;
+ }
case kDeclGlobals: {
int length;
uint32_t globals_count = consume_u32v(&length, "globals count");
@@ -185,7 +256,7 @@ class ModuleDecoder : public Decoder {
}
case kDeclFunctionTable: {
// An indirect function table requires functions first.
- CheckForPreviousSection(sections, kDeclFunctions, true);
+ CheckForFunctions(module, section);
int length;
uint32_t function_table_count =
consume_u32v(&length, "function table count");
@@ -206,23 +277,16 @@ class ModuleDecoder : public Decoder {
}
case kDeclStartFunction: {
// Declares a start function for a module.
- CheckForPreviousSection(sections, kDeclFunctions, true);
+ CheckForFunctions(module, section);
if (module->start_function_index >= 0) {
error("start function already declared");
break;
}
- int length;
- const byte* before = pc_;
- uint32_t index = consume_u32v(&length, "start function index");
- if (index >= module->functions.size()) {
- error(before, "invalid start function index");
- break;
- }
- module->start_function_index = static_cast<int>(index);
- FunctionSig* sig =
- module->signatures[module->functions[index].sig_index];
- if (sig->parameter_count() > 0) {
- error(before, "invalid start function: non-zero parameter count");
+ WasmFunction* func;
+ const byte* pos = pc_;
+ module->start_function_index = consume_func_index(module, &func);
+ if (func && func->sig->parameter_count() > 0) {
+ error(pos, "invalid start function: non-zero parameter count");
break;
}
break;
@@ -243,14 +307,7 @@ class ModuleDecoder : public Decoder {
module->import_table.push_back({nullptr, 0, 0});
WasmImport* import = &module->import_table.back();
- const byte* sigpos = pc_;
- import->sig_index = consume_u32v(&length, "signature index");
-
- if (import->sig_index >= module->signatures.size()) {
- error(sigpos, "invalid signature index");
- } else {
- import->sig = module->signatures[import->sig_index];
- }
+ import->sig_index = consume_sig_index(module, &import->sig);
const byte* pos = pc_;
import->module_name_offset = consume_string(
&import->module_name_length, "import module name");
@@ -264,7 +321,7 @@ class ModuleDecoder : public Decoder {
}
case kDeclExportTable: {
// Declares an export table.
- CheckForPreviousSection(sections, kDeclFunctions, true);
+ CheckForFunctions(module, section);
int length;
uint32_t export_table_count =
consume_u32v(&length, "export table count");
@@ -278,14 +335,8 @@ class ModuleDecoder : public Decoder {
module->export_table.push_back({0, 0});
WasmExport* exp = &module->export_table.back();
- const byte* sigpos = pc_;
- exp->func_index = consume_u32v(&length, "function index");
- if (exp->func_index >= module->functions.size()) {
- error(sigpos, sigpos,
- "function index %u out of bounds (%d functions)",
- exp->func_index,
- static_cast<int>(module->functions.size()));
- }
+ WasmFunction* func;
+ exp->func_index = consume_func_index(module, &func);
exp->name_offset = consume_string(&exp->name_length, "export name");
}
break;
@@ -304,34 +355,37 @@ class ModuleDecoder : public Decoder {
return count < kMaxReserve ? count : kMaxReserve;
}
- void CheckForPreviousSection(bool* sections, WasmSectionDeclCode section,
- bool present) {
- if (section >= kMaxModuleSectionCode) return;
- if (sections[section] == present) return;
- const char* name = "";
+ const char* SectionName(WasmSectionDeclCode section) {
switch (section) {
case kDeclMemory:
- name = "memory";
- break;
+ return "memory";
case kDeclSignatures:
- name = "signatures";
- break;
+ return "signatures";
case kDeclFunctions:
- name = "function declaration";
- break;
+ return "function declaration";
case kDeclGlobals:
- name = "global variable";
- break;
+ return "global variable";
case kDeclDataSegments:
- name = "data segment";
- break;
+ return "data segment";
case kDeclFunctionTable:
- name = "function table";
- break;
+ return "function table";
default:
- name = "";
- break;
+ return "";
}
+ }
+
+ void CheckForFunctions(WasmModule* module, WasmSectionDeclCode section) {
+ if (module->functions.size() == 0) {
+ error(pc_ - 1, nullptr, "functions must appear before section %s",
+ SectionName(section));
+ }
+ }
+
+ void CheckForPreviousSection(bool* sections, WasmSectionDeclCode section,
+ bool present) {
+ if (section >= kMaxModuleSectionCode) return;
+ if (sections[section] == present) return;
+ const char* name = SectionName(section);
if (present) {
error(pc_ - 1, nullptr, "required %s section missing", name);
} else {
@@ -382,6 +436,7 @@ class ModuleDecoder : public Decoder {
}
// Decodes a single function entry inside a module starting at {pc_}.
+ // TODO(titzer): legacy function body; remove
void DecodeFunctionInModule(WasmModule* module, WasmFunction* function,
bool verify_body = true) {
byte decl_bits = consume_u8("function decl");
@@ -517,11 +572,40 @@ class ModuleDecoder : public Decoder {
uint32_t consume_string(uint32_t* length, const char* name = nullptr) {
int varint_length;
*length = consume_u32v(&varint_length, "string length");
- uint32_t offset = static_cast<uint32_t>(pc_ - start_);
+ uint32_t offset = pc_offset();
+ TRACE(" +%u %-20s: (%u bytes)\n", offset, "string", *length);
consume_bytes(*length);
return offset;
}
+ uint32_t consume_sig_index(WasmModule* module, FunctionSig** sig) {
+ const byte* pos = pc_;
+ int length;
+ uint32_t sig_index = consume_u32v(&length, "signature index");
+ if (sig_index >= module->signatures.size()) {
+ error(pos, pos, "signature index %u out of bounds (%d signatures)",
+ sig_index, static_cast<int>(module->signatures.size()));
+ *sig = nullptr;
+ return 0;
+ }
+ *sig = module->signatures[sig_index];
+ return sig_index;
+ }
+
+ uint32_t consume_func_index(WasmModule* module, WasmFunction** func) {
+ const byte* pos = pc_;
+ int length;
+ uint32_t func_index = consume_u32v(&length, "function index");
+ if (func_index >= module->functions.size()) {
+ error(pos, pos, "function index %u out of bounds (%d functions)",
+ func_index, static_cast<int>(module->functions.size()));
+ *func = nullptr;
+ return 0;
+ }
+ *func = &module->functions[func_index];
+ return func_index;
+ }
+
// Reads a single 8-bit integer, interpreting it as a local type.
LocalType consume_local_type() {
byte val = consume_u8("local type");
« no previous file with comments | « src/wasm/decoder.h ('k') | src/wasm/wasm-module.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698