Index: src/wasm/module-decoder.cc |
diff --git a/src/wasm/module-decoder.cc b/src/wasm/module-decoder.cc |
index 48f59cefa82bdf1d293da3eb529d4244e7dc2485..c753c63983267dff5182bd3306d43f47ebd4b84d 100644 |
--- a/src/wasm/module-decoder.cc |
+++ b/src/wasm/module-decoder.cc |
@@ -25,6 +25,8 @@ namespace wasm { |
#define TRACE(...) |
#endif |
+namespace { |
+ |
// The main logic for decoding the bytes of a module. |
class ModuleDecoder : public Decoder { |
public: |
@@ -719,6 +721,45 @@ class FunctionError : public FunctionResult { |
} |
}; |
+Vector<const byte> FindSection(const byte* module_start, const byte* module_end, |
+ WasmSection::Code code) { |
+ Decoder decoder(module_start, module_end); |
+ |
+ uint32_t magic_word = decoder.consume_u32("wasm magic"); |
+ if (magic_word != kWasmMagic) decoder.error("wrong magic word"); |
+ |
+ uint32_t magic_version = decoder.consume_u32("wasm version"); |
+ if (magic_version != kWasmVersion) decoder.error("wrong wasm version"); |
+ |
+ while (decoder.more() && decoder.ok()) { |
+ // Read the section name. |
+ int string_leb_length = 0; |
+ uint32_t string_length = |
+ decoder.consume_u32v(&string_leb_length, "section name length"); |
+ const byte* section_name_start = decoder.pc(); |
+ decoder.consume_bytes(string_length); |
+ if (decoder.failed()) break; |
+ |
+ WasmSection::Code section = |
+ WasmSection::lookup(section_name_start, string_length); |
+ |
+ // Read and check the section size. |
+ int section_leb_length = 0; |
+ uint32_t section_length = |
+ decoder.consume_u32v(§ion_leb_length, "section length"); |
+ |
+ const byte* section_start = decoder.pc(); |
+ decoder.consume_bytes(section_length); |
+ if (section == code && decoder.ok()) { |
+ return Vector<const uint8_t>(section_start, section_length); |
+ } |
+ } |
+ |
+ return Vector<const uint8_t>(); |
+} |
+ |
+} // namespace |
+ |
ModuleResult DecodeWasmModule(Isolate* isolate, Zone* zone, |
const byte* module_start, const byte* module_end, |
bool verify_functions, ModuleOrigin origin) { |
@@ -762,6 +803,34 @@ FunctionResult DecodeWasmFunction(Isolate* isolate, Zone* zone, |
ModuleDecoder decoder(zone, function_start, function_end, kWasmOrigin); |
return decoder.DecodeSingleFunction(module_env, function); |
} |
+ |
+FunctionOffsetsResult DecodeWasmFunctionOffsets(const byte* module_start, |
+ const byte* module_end) { |
+ Vector<const byte> code_section = |
+ FindSection(module_start, module_end, WasmSection::Code::FunctionBodies); |
+ Decoder decoder(code_section.start(), code_section.end()); |
+ if (!code_section.start()) decoder.error("no code section"); |
+ |
+ int length; |
+ uint32_t functions_count = decoder.consume_u32v(&length, "functions count"); |
+ FunctionOffsets table; |
+ // Take care of invalid input here. |
+ if (functions_count < static_cast<unsigned>(code_section.length()) / 2) |
+ table.reserve(functions_count); |
+ int section_offset = static_cast<int>(code_section.start() - module_start); |
+ DCHECK_LE(0, section_offset); |
+ for (uint32_t i = 0; i < functions_count && decoder.ok(); i++) { |
+ uint32_t size = decoder.consume_u32v(&length, "body size"); |
+ int offset = static_cast<int>(section_offset + decoder.pc_offset()); |
+ table.push_back(std::make_pair(offset, static_cast<int>(size))); |
+ DCHECK(table.back().first >= 0 && table.back().second >= 0); |
+ decoder.consume_bytes(size); |
+ } |
+ if (decoder.more()) decoder.error("unexpected additional bytes"); |
+ |
+ return decoder.toResult(std::move(table)); |
+} |
+ |
} // namespace wasm |
} // namespace internal |
} // namespace v8 |