diff --git a/src/wasm/module-decoder.cc b/src/wasm/module-decoder.cc index 5605e495cf..5f9d710bf8 100644 --- a/src/wasm/module-decoder.cc +++ b/src/wasm/module-decoder.cc @@ -30,7 +30,7 @@ namespace wasm { #define TRACE(...) #endif -const char* SectionName(WasmSectionCode code) { +const char* SectionName(SectionCode code) { switch (code) { case kUnknownSectionCode: return "Unknown"; @@ -106,7 +106,7 @@ class WasmSectionIterator { return section_code_ != kUnknownSectionCode && decoder_.more(); } - inline WasmSectionCode section_code() const { return section_code_; } + inline SectionCode section_code() const { return section_code_; } inline const byte* section_start() const { return section_start_; } @@ -138,7 +138,7 @@ class WasmSectionIterator { private: Decoder& decoder_; - WasmSectionCode section_code_; + SectionCode section_code_; const byte* section_start_; const byte* payload_start_; const byte* section_end_; @@ -184,15 +184,13 @@ class WasmSectionIterator { strncmp(reinterpret_cast(section_name_start), kNameString, kNameStringLength) == 0) { section_code = kNameSectionCode; - } else { - section_code = kUnknownSectionCode; } } else if (!IsValidSectionCode(section_code)) { decoder_.errorf(decoder_.pc(), "unknown section code #0x%02x", section_code); section_code = kUnknownSectionCode; } - section_code_ = static_cast(section_code); + section_code_ = static_cast(section_code); TRACE("Section: %s\n", SectionName(section_code_)); if (section_code_ == kUnknownSectionCode && @@ -651,22 +649,36 @@ class ModuleDecoder : public Decoder { // TODO(titzer): find a way to report name errors as warnings. // Use an inner decoder so that errors don't fail the outer decoder. Decoder inner(start_, pc_, end_); - uint32_t functions_count = inner.consume_u32v("functions count"); + // Decode all name subsections. + // Be lenient with their order. + while (inner.ok() && inner.more()) { + uint8_t name_type = inner.consume_u8("name type"); + if (name_type & 0x80) inner.error("name type if not varuint7"); - for (uint32_t i = 0; inner.ok() && i < functions_count; ++i) { - uint32_t function_name_length = 0; - uint32_t name_offset = - consume_string(inner, &function_name_length, false); - uint32_t func_index = i; - if (inner.ok() && func_index < module->functions.size()) { - module->functions[func_index].name_offset = name_offset; - module->functions[func_index].name_length = function_name_length; - } + uint32_t name_payload_len = inner.consume_u32v("name payload length"); + if (!inner.checkAvailable(name_payload_len)) break; - uint32_t local_names_count = inner.consume_u32v("local names count"); - for (uint32_t j = 0; inner.ok() && j < local_names_count; j++) { - uint32_t length = inner.consume_u32v("string length"); - inner.consume_bytes(length, "string"); + // Decode function names, ignore the rest. + // Local names will be decoded when needed. + if (name_type == NameSectionType::kFunction) { + uint32_t functions_count = inner.consume_u32v("functions count"); + + for (; inner.ok() && functions_count > 0; --functions_count) { + uint32_t function_index = inner.consume_u32v("function index"); + uint32_t name_length = 0; + uint32_t name_offset = consume_string(inner, &name_length, false); + // Be lenient with errors in the name section: Ignore illegal + // or out-of-order indexes and non-UTF8 names. You can even assign + // to the same function multiple times (last valid one wins). + if (inner.ok() && function_index < module->functions.size() && + unibrow::Utf8::Validate(inner.start() + name_offset, + name_length)) { + module->functions[function_index].name_offset = name_offset; + module->functions[function_index].name_length = name_length; + } + } + } else { + inner.consume_bytes(name_payload_len, "name subsection payload"); } } // Skip the whole names section in the outer decoder. diff --git a/src/wasm/module-decoder.h b/src/wasm/module-decoder.h index da88b10e86..b29dfb196b 100644 --- a/src/wasm/module-decoder.h +++ b/src/wasm/module-decoder.h @@ -20,7 +20,7 @@ const uint8_t kWasmFunctionTypeForm = 0x60; const uint8_t kWasmAnyFunctionTypeForm = 0x70; const uint8_t kResizableMaximumFlag = 1; -enum WasmSectionCode { +enum SectionCode { kUnknownSectionCode = 0, // code for unknown sections kTypeSectionCode = 1, // Function signature declarations kImportSectionCode = 2, // Import declarations @@ -36,11 +36,13 @@ enum WasmSectionCode { kNameSectionCode = 12, // Name section (encoded as a string) }; +enum NameSectionType : uint8_t { kFunction = 1, kLocal = 2 }; + inline bool IsValidSectionCode(uint8_t byte) { return kTypeSectionCode <= byte && byte <= kDataSectionCode; } -const char* SectionName(WasmSectionCode code); +const char* SectionName(SectionCode code); typedef Result ModuleResult; typedef Result FunctionResult; diff --git a/src/wasm/wasm-module-builder.cc b/src/wasm/wasm-module-builder.cc index 73f68e891f..a3d52eba79 100644 --- a/src/wasm/wasm-module-builder.cc +++ b/src/wasm/wasm-module-builder.cc @@ -34,7 +34,7 @@ namespace wasm { // Emit a section code and the size as a padded varint that can be patched // later. -size_t EmitSection(WasmSectionCode code, ZoneBuffer& buffer) { +size_t EmitSection(SectionCode code, ZoneBuffer& buffer) { // Emit the section code. buffer.write_u8(code); @@ -206,8 +206,7 @@ void WasmFunctionBuilder::WriteExports(ZoneBuffer& buffer) const { buffer.write_size(name.size()); buffer.write(reinterpret_cast(name.data()), name.size()); buffer.write_u8(kExternalFunction); - buffer.write_u32v(func_index_ + static_cast( - builder_->function_imports_.size())); + buffer.write_size(func_index_ + builder_->function_imports_.size()); } } @@ -391,14 +390,14 @@ void WasmModuleBuilder::WriteTo(ZoneBuffer& buffer) const { } // == Emit function signatures =============================================== - bool has_names = false; + uint32_t num_function_names = 0; if (functions_.size() > 0) { size_t start = EmitSection(kFunctionSectionCode, buffer); buffer.write_size(functions_.size()); for (auto function : functions_) { function->WriteSignature(buffer); exports += static_cast(function->exported_names_.size()); - if (function->name_.size() > 0) has_names = true; + if (!function->name_.empty()) ++num_function_names; } FixupSection(buffer, start); } @@ -507,8 +506,7 @@ void WasmModuleBuilder::WriteTo(ZoneBuffer& buffer) const { // == emit start function index ============================================== if (start_function_index_ >= 0) { size_t start = EmitSection(kStartSectionCode, buffer); - buffer.write_u32v(start_function_index_ + - static_cast(function_imports_.size())); + buffer.write_size(start_function_index_ + function_imports_.size()); FixupSection(buffer, start); } @@ -523,8 +521,7 @@ void WasmModuleBuilder::WriteTo(ZoneBuffer& buffer) const { buffer.write_size(indirect_functions_.size()); // element count for (auto index : indirect_functions_) { - buffer.write_u32v(index + - static_cast(function_imports_.size())); + buffer.write_size(index + function_imports_.size()); } FixupSection(buffer, start); @@ -557,7 +554,7 @@ void WasmModuleBuilder::WriteTo(ZoneBuffer& buffer) const { } // == Emit names ============================================================= - if (has_names) { + if (num_function_names > 0 || !function_imports_.empty()) { // Emit the section code. buffer.write_u8(kUnknownSectionCode); // Emit a placeholder for the length. @@ -565,19 +562,37 @@ void WasmModuleBuilder::WriteTo(ZoneBuffer& buffer) const { // Emit the section string. buffer.write_size(4); buffer.write(reinterpret_cast("name"), 4); - // Emit the names. - size_t count = functions_.size() + function_imports_.size(); - buffer.write_size(count); - for (size_t i = 0; i < function_imports_.size(); i++) { - buffer.write_u8(0); // empty name for import - buffer.write_u8(0); // no local variables + // Emit a subsection for the function names. + buffer.write_u8(NameSectionType::kFunction); + // Emit a placeholder for the subsection length. + size_t functions_start = buffer.reserve_u32v(); + // Emit the function names. + // Imports are always named. + uint32_t num_imports = static_cast(function_imports_.size()); + buffer.write_size(num_imports + num_function_names); + uint32_t function_index = 0; + for (; function_index < num_imports; ++function_index) { + const WasmFunctionImport* import = &function_imports_[function_index]; + DCHECK_NOT_NULL(import->name); + buffer.write_u32v(function_index); + uint32_t name_len = static_cast(import->name_length); + buffer.write_u32v(name_len); + buffer.write(reinterpret_cast(import->name), name_len); } - for (auto function : functions_) { - buffer.write_size(function->name_.size()); - buffer.write(reinterpret_cast(function->name_.data()), - function->name_.size()); - buffer.write_u8(0); + if (num_function_names > 0) { + for (auto function : functions_) { + DCHECK_EQ(function_index, + function->func_index() + function_imports_.size()); + if (!function->name_.empty()) { + buffer.write_u32v(function_index); + buffer.write_size(function->name_.size()); + buffer.write(reinterpret_cast(function->name_.data()), + function->name_.size()); + } + ++function_index; + } } + FixupSection(buffer, functions_start); FixupSection(buffer, start); } } diff --git a/src/wasm/wasm-objects.cc b/src/wasm/wasm-objects.cc index 6655a29e65..cbab5e7dcd 100644 --- a/src/wasm/wasm-objects.cc +++ b/src/wasm/wasm-objects.cc @@ -1132,9 +1132,10 @@ MaybeHandle WasmCompiledModule::ExtractUtf8StringFromModuleBytes( isolate); DCHECK_GE(module_bytes->length(), offset); DCHECK_GE(module_bytes->length() - offset, size); - Address raw = module_bytes->GetCharsAddress() + offset; - if (!unibrow::Utf8::Validate(reinterpret_cast(raw), size)) - return {}; // UTF8 decoding error for name. + // UTF8 validation happens at decode time. + DCHECK(unibrow::Utf8::Validate( + reinterpret_cast(module_bytes->GetCharsAddress() + offset), + size)); DCHECK_GE(kMaxInt, offset); DCHECK_GE(kMaxInt, size); return isolate->factory()->NewStringFromUtf8SubString( @@ -1219,6 +1220,8 @@ MaybeHandle WasmCompiledModule::GetFunctionNameOrNull( uint32_t func_index) { DCHECK_LT(func_index, compiled_module->module()->functions.size()); WasmFunction& function = compiled_module->module()->functions[func_index]; + DCHECK_IMPLIES(function.name_offset == 0, function.name_length == 0); + if (!function.name_offset) return {}; return WasmCompiledModule::ExtractUtf8StringFromModuleBytes( isolate, compiled_module, function.name_offset, function.name_length); } diff --git a/test/cctest/wasm/wasm-run-utils.h b/test/cctest/wasm/wasm-run-utils.h index 21050f2531..157b318013 100644 --- a/test/cctest/wasm/wasm-run-utils.h +++ b/test/cctest/wasm/wasm-run-utils.h @@ -308,14 +308,17 @@ class TestingModule : public ModuleEnv { Handle old_bytes( instance_object_->compiled_module()->module_bytes(), isolate_); uint32_t old_size = static_cast(old_bytes->length()); - ScopedVector new_bytes(old_size + bytes.length()); + // Avoid placing strings at offset 0, this might be interpreted as "not + // set", e.g. for function names. + uint32_t bytes_offset = old_size ? old_size : 1; + ScopedVector new_bytes(bytes_offset + bytes.length()); memcpy(new_bytes.start(), old_bytes->GetChars(), old_size); - memcpy(new_bytes.start() + old_size, bytes.start(), bytes.length()); + memcpy(new_bytes.start() + bytes_offset, bytes.start(), bytes.length()); Handle new_bytes_str = Handle::cast( isolate_->factory()->NewStringFromOneByte(new_bytes).ToHandleChecked()); instance_object_->compiled_module()->shared()->set_module_bytes( *new_bytes_str); - return old_size; + return bytes_offset; } WasmFunction* GetFunctionAt(int index) { return &module_.functions[index]; } diff --git a/test/fuzzer/wasm-section-fuzzers.cc b/test/fuzzer/wasm-section-fuzzers.cc index e98c510b77..d883c26ec9 100644 --- a/test/fuzzer/wasm-section-fuzzers.cc +++ b/test/fuzzer/wasm-section-fuzzers.cc @@ -19,8 +19,7 @@ using namespace v8::internal::wasm; static const char* kNameString = "name"; static const size_t kNameStringLength = 4; -int fuzz_wasm_section(WasmSectionCode section, const uint8_t* data, - size_t size) { +int fuzz_wasm_section(SectionCode section, const uint8_t* data, size_t size) { v8_fuzzer::FuzzerSupport* support = v8_fuzzer::FuzzerSupport::Get(); v8::Isolate* isolate = support->GetIsolate(); v8::internal::Isolate* i_isolate = diff --git a/test/fuzzer/wasm-section-fuzzers.h b/test/fuzzer/wasm-section-fuzzers.h index 41ff6af687..5d38981cf4 100644 --- a/test/fuzzer/wasm-section-fuzzers.h +++ b/test/fuzzer/wasm-section-fuzzers.h @@ -10,7 +10,7 @@ #include "src/wasm/module-decoder.h" -int fuzz_wasm_section(v8::internal::wasm::WasmSectionCode section, +int fuzz_wasm_section(v8::internal::wasm::SectionCode section, const uint8_t* data, size_t size); #endif // WASM_SECTION_FUZZERS_H_ diff --git a/test/inspector/debugger/wasm-get-breakable-locations-expected.txt b/test/inspector/debugger/wasm-get-breakable-locations-expected.txt index 736117bf97..7f869bf040 100644 --- a/test/inspector/debugger/wasm-get-breakable-locations-expected.txt +++ b/test/inspector/debugger/wasm-get-breakable-locations-expected.txt @@ -1,9 +1,9 @@ Running testFunction... Script nr 0 parsed. URL: v8://test/setup Script nr 1 parsed. URL: v8://test/runTestFunction -Script nr 2 parsed. URL: wasm://wasm/wasm-eb3c2032/wasm-eb3c2032-0 +Script nr 2 parsed. URL: wasm://wasm/wasm-354ada0e/wasm-354ada0e-0 This is a wasm script (nr 0). -Script nr 3 parsed. URL: wasm://wasm/wasm-eb3c2032/wasm-eb3c2032-1 +Script nr 3 parsed. URL: wasm://wasm/wasm-354ada0e/wasm-354ada0e-1 This is a wasm script (nr 1). Querying breakable locations for all wasm scripts now... Requesting all breakable locations in wasm script 0 @@ -37,51 +37,51 @@ Requesting breakable locations in lines [4,6) [0] 4:6 || >call 0 [1] 5:4 || >end Setting a breakpoint on each breakable location... -Setting at wasm://wasm/wasm-eb3c2032/wasm-eb3c2032-0:2:2 +Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:2:2 Success! -Setting at wasm://wasm/wasm-eb3c2032/wasm-eb3c2032-0:3:2 +Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:3:2 Success! -Setting at wasm://wasm/wasm-eb3c2032/wasm-eb3c2032-0:4:2 +Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:4:2 Success! -Setting at wasm://wasm/wasm-eb3c2032/wasm-eb3c2032-0:5:0 +Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:5:0 Success! -Setting at wasm://wasm/wasm-eb3c2032/wasm-eb3c2032-1:1:2 +Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:1:2 Success! -Setting at wasm://wasm/wasm-eb3c2032/wasm-eb3c2032-1:2:2 +Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:2:2 Success! -Setting at wasm://wasm/wasm-eb3c2032/wasm-eb3c2032-1:3:4 +Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:3:4 Success! -Setting at wasm://wasm/wasm-eb3c2032/wasm-eb3c2032-1:4:6 +Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:4:6 Success! -Setting at wasm://wasm/wasm-eb3c2032/wasm-eb3c2032-1:5:4 +Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:5:4 Success! -Setting at wasm://wasm/wasm-eb3c2032/wasm-eb3c2032-1:6:2 +Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:6:2 Success! -Setting at wasm://wasm/wasm-eb3c2032/wasm-eb3c2032-1:7:0 +Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:7:0 Success! Running wasm code... Missing breakpoints: 11 Script nr 4 parsed. URL: v8://test/runWasm -Stopped at wasm://wasm/wasm-eb3c2032/wasm-eb3c2032-1:1:2 +Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:1:2 Missing breakpoints: 10 -Stopped at wasm://wasm/wasm-eb3c2032/wasm-eb3c2032-1:2:2 +Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:2:2 Missing breakpoints: 9 -Stopped at wasm://wasm/wasm-eb3c2032/wasm-eb3c2032-1:3:4 +Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:3:4 Missing breakpoints: 8 -Stopped at wasm://wasm/wasm-eb3c2032/wasm-eb3c2032-1:4:6 +Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:4:6 Missing breakpoints: 7 -Stopped at wasm://wasm/wasm-eb3c2032/wasm-eb3c2032-0:2:2 +Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:2:2 Missing breakpoints: 6 -Stopped at wasm://wasm/wasm-eb3c2032/wasm-eb3c2032-0:3:2 +Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:3:2 Missing breakpoints: 5 -Stopped at wasm://wasm/wasm-eb3c2032/wasm-eb3c2032-0:4:2 +Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:4:2 Missing breakpoints: 4 -Stopped at wasm://wasm/wasm-eb3c2032/wasm-eb3c2032-0:5:0 +Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:5:0 Missing breakpoints: 3 -Stopped at wasm://wasm/wasm-eb3c2032/wasm-eb3c2032-1:5:4 +Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:5:4 Missing breakpoints: 2 -Stopped at wasm://wasm/wasm-eb3c2032/wasm-eb3c2032-1:6:2 +Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:6:2 Missing breakpoints: 1 -Stopped at wasm://wasm/wasm-eb3c2032/wasm-eb3c2032-1:7:0 +Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:7:0 Missing breakpoints: 0 Finished! diff --git a/test/inspector/debugger/wasm-scripts-expected.txt b/test/inspector/debugger/wasm-scripts-expected.txt index 040d125ec7..41d2c0b380 100644 --- a/test/inspector/debugger/wasm-scripts-expected.txt +++ b/test/inspector/debugger/wasm-scripts-expected.txt @@ -1,14 +1,14 @@ Check that inspector gets two wasm scripts at module creation time. Script #0 parsed. URL: v8://test/testFunction Script #1 parsed. URL: v8://test/runTestRunction -Script #2 parsed. URL: wasm://wasm/wasm-4205e2ce/wasm-4205e2ce-0 -Script #3 parsed. URL: wasm://wasm/wasm-4205e2ce/wasm-4205e2ce-1 -Source for wasm://wasm/wasm-4205e2ce/wasm-4205e2ce-0: +Script #2 parsed. URL: wasm://wasm/wasm-7b04570e/wasm-7b04570e-0 +Script #3 parsed. URL: wasm://wasm/wasm-7b04570e/wasm-7b04570e-1 +Source for wasm://wasm/wasm-7b04570e/wasm-7b04570e-0: func $nopFunction nop end -Source for wasm://wasm/wasm-4205e2ce/wasm-4205e2ce-1: +Source for wasm://wasm/wasm-7b04570e/wasm-7b04570e-1: func $main block i32.const 2 diff --git a/test/inspector/debugger/wasm-stepping-expected.txt b/test/inspector/debugger/wasm-stepping-expected.txt index 922d51aa49..a2df3e47b9 100644 --- a/test/inspector/debugger/wasm-stepping-expected.txt +++ b/test/inspector/debugger/wasm-stepping-expected.txt @@ -2,10 +2,10 @@ Installing code an global variable. Calling instantiate function. Waiting for two wasm scripts to be parsed. Ignoring script with url v8://test/callInstantiate -Got wasm script: wasm://wasm/wasm-0e9ccf72/wasm-0e9ccf72-0 -Requesting source for wasm://wasm/wasm-0e9ccf72/wasm-0e9ccf72-0... -Got wasm script: wasm://wasm/wasm-0e9ccf72/wasm-0e9ccf72-1 -Requesting source for wasm://wasm/wasm-0e9ccf72/wasm-0e9ccf72-1... +Got wasm script: wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0 +Requesting source for wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0... +Got wasm script: wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1 +Requesting source for wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1... func $wasm_A nop nop @@ -25,59 +25,59 @@ func $wasm_B (param i32) end end -Setting breakpoint on line 7 (on the setlocal before the call), url wasm://wasm/wasm-0e9ccf72/wasm-0e9ccf72-1 +Setting breakpoint on line 7 (on the setlocal before the call), url wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1 { columnNumber : 6 lineNumber : 7 scriptId : } -Paused at wasm://wasm/wasm-0e9ccf72/wasm-0e9ccf72-1:7:6: >set_local 0 +Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:7:6: >set_local 0 Step action: stepInto -Paused at wasm://wasm/wasm-0e9ccf72/wasm-0e9ccf72-1:8:6: >call 0 +Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:8:6: >call 0 Step action: stepInto -Paused at wasm://wasm/wasm-0e9ccf72/wasm-0e9ccf72-0:1:2: >nop +Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0:1:2: >nop Step action: stepOver -Paused at wasm://wasm/wasm-0e9ccf72/wasm-0e9ccf72-0:2:2: >nop +Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0:2:2: >nop Step action: stepOut -Paused at wasm://wasm/wasm-0e9ccf72/wasm-0e9ccf72-1:9:6: >br 1 +Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:9:6: >br 1 Step action: stepOut -Paused at wasm://wasm/wasm-0e9ccf72/wasm-0e9ccf72-1:7:6: >set_local 0 +Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:7:6: >set_local 0 Step action: stepOver -Paused at wasm://wasm/wasm-0e9ccf72/wasm-0e9ccf72-1:8:6: >call 0 +Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:8:6: >call 0 Step action: stepOver -Paused at wasm://wasm/wasm-0e9ccf72/wasm-0e9ccf72-1:9:6: >br 1 +Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:9:6: >br 1 Step action: resume -Paused at wasm://wasm/wasm-0e9ccf72/wasm-0e9ccf72-1:7:6: >set_local 0 +Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:7:6: >set_local 0 Step action: stepInto -Paused at wasm://wasm/wasm-0e9ccf72/wasm-0e9ccf72-1:8:6: >call 0 +Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:8:6: >call 0 Step action: stepInto -Paused at wasm://wasm/wasm-0e9ccf72/wasm-0e9ccf72-0:1:2: >nop +Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0:1:2: >nop Step action: stepOut -Paused at wasm://wasm/wasm-0e9ccf72/wasm-0e9ccf72-1:9:6: >br 1 +Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:9:6: >br 1 Step action: stepInto -Paused at wasm://wasm/wasm-0e9ccf72/wasm-0e9ccf72-1:1:2: >loop +Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:1:2: >loop Step action: stepInto -Paused at wasm://wasm/wasm-0e9ccf72/wasm-0e9ccf72-1:2:4: >get_local 0 +Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:2:4: >get_local 0 Step action: stepInto -Paused at wasm://wasm/wasm-0e9ccf72/wasm-0e9ccf72-1:3:4: >if +Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:3:4: >if Step action: stepInto -Paused at wasm://wasm/wasm-0e9ccf72/wasm-0e9ccf72-1:4:6: >get_local 0 +Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:4:6: >get_local 0 Step action: stepInto -Paused at wasm://wasm/wasm-0e9ccf72/wasm-0e9ccf72-1:5:6: >i32.const 1 +Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:5:6: >i32.const 1 Step action: stepInto -Paused at wasm://wasm/wasm-0e9ccf72/wasm-0e9ccf72-1:6:6: >i32.sub +Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:6:6: >i32.sub Step action: stepInto -Paused at wasm://wasm/wasm-0e9ccf72/wasm-0e9ccf72-1:7:6: >set_local 0 +Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:7:6: >set_local 0 Step action: stepInto -Paused at wasm://wasm/wasm-0e9ccf72/wasm-0e9ccf72-1:8:6: >call 0 +Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:8:6: >call 0 Step action: stepInto -Paused at wasm://wasm/wasm-0e9ccf72/wasm-0e9ccf72-0:1:2: >nop +Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0:1:2: >nop Step action: stepInto -Paused at wasm://wasm/wasm-0e9ccf72/wasm-0e9ccf72-0:2:2: >nop +Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0:2:2: >nop Step action: stepInto -Paused at wasm://wasm/wasm-0e9ccf72/wasm-0e9ccf72-0:3:0: >end +Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0:3:0: >end Step action: stepInto -Paused at wasm://wasm/wasm-0e9ccf72/wasm-0e9ccf72-1:9:6: >br 1 +Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:9:6: >br 1 Step action: resume exports.main returned! Finished! diff --git a/test/mjsunit/regress/wasm/regression-684858.js b/test/mjsunit/regress/wasm/regression-684858.js index e11d909c86..bfef7fcc8e 100644 --- a/test/mjsunit/regress/wasm/regression-684858.js +++ b/test/mjsunit/regress/wasm/regression-684858.js @@ -10,7 +10,7 @@ var name = 'regression_684858'; function patchNameLength(buffer) { var count = 0; var view = new Uint8Array(buffer); - for (var i = 0, e = view.length - name.length; i < e; ++i) { + for (var i = 0, e = view.length - name.length; i <= e; ++i) { var subs = String.fromCharCode.apply(null, view.slice(i, i + name.length)); if (subs != name) continue; ++count; diff --git a/test/mjsunit/wasm/function-names.js b/test/mjsunit/wasm/function-names.js index beb7e07b34..9320c50789 100644 --- a/test/mjsunit/wasm/function-names.js +++ b/test/mjsunit/wasm/function-names.js @@ -54,16 +54,16 @@ Error.prepareStackTrace = function(error, frames) { return frames; }; - (function testFunctionNamesAsCallSites() { - var names = expected_names.concat(["testFunctionNamesAsCallSites", null]); + var names = expected_names.concat(['testFunctionNamesAsCallSites', null]); try { module.exports.main(); - assertFalse("should throw"); + assertFalse('should throw'); } catch (e) { - assertEquals(names.length, e.stack.length); + assertEquals(names.length, e.stack.length, 'stack length'); for (var i = 0; i < names.length; ++i) { - assertEquals(names[i], e.stack[i].getFunctionName()); + assertEquals( + names[i], e.stack[i].getFunctionName(), 'function name at ' + i); } } })(); diff --git a/test/mjsunit/wasm/stack.js b/test/mjsunit/wasm/stack.js index 79ab28e367..ba2818925d 100644 --- a/test/mjsunit/wasm/stack.js +++ b/test/mjsunit/wasm/stack.js @@ -25,7 +25,8 @@ function verifyStack(frames, expected) { assertContains(exp[4], frames[i].getFileName(), "["+i+"].getFileName()"); var toString; if (exp[0]) { - toString = exp[1] + " ([" + exp[2] + "]+" + exp[3] + ")"; + var fun_str = exp[1] !== null ? exp[1] : ""; + toString = fun_str + " ([" + exp[2] + "]+" + exp[3] + ")"; } else { toString = exp[4] + ":" + exp[2] + ":"; } @@ -70,10 +71,10 @@ var module = builder.instantiate({mod: {func: STACK}}); (function testSimpleStack() { var expected_string = "Error\n" + // The line numbers below will change as this test gains / loses lines.. - " at STACK (stack.js:39:11)\n" + // -- + " at STACK (stack.js:40:11)\n" + // -- " at main ([1]+1)\n" + // -- - " at testSimpleStack (stack.js:78:18)\n" + // -- - " at stack.js:80:3"; // -- + " at testSimpleStack (stack.js:79:18)\n" + // -- + " at stack.js:81:3"; // -- module.exports.main(); assertEquals(expected_string, stripPath(stack)); @@ -90,10 +91,10 @@ Error.prepareStackTrace = function(error, frames) { verifyStack(stack, [ // isWasm function line pos file - [ false, "STACK", 39, 0, "stack.js"], + [ false, "STACK", 40, 0, "stack.js"], [ true, "main", 1, 1, null], - [ false, "testStackFrames", 89, 0, "stack.js"], - [ false, null, 98, 0, "stack.js"] + [ false, "testStackFrames", 90, 0, "stack.js"], + [ false, null, 99, 0, "stack.js"] ]); })(); @@ -106,8 +107,8 @@ Error.prepareStackTrace = function(error, frames) { verifyStack(e.stack, [ // isWasm function line pos file [ true, "exec_unreachable", 2, 1, null], - [ false, "testWasmUnreachable", 102, 0, "stack.js"], - [ false, null, 113, 0, "stack.js"] + [ false, "testWasmUnreachable", 103, 0, "stack.js"], + [ false, null, 114, 0, "stack.js"] ]); } })(); @@ -120,10 +121,10 @@ Error.prepareStackTrace = function(error, frames) { assertContains("out of bounds", e.message); verifyStack(e.stack, [ // isWasm function line pos file - [ true, "", 3, 3, null], + [ true, null, 3, 3, null], [ true, "call_mem_out_of_bounds", 4, 1, null], - [ false, "testWasmMemOutOfBounds", 117, 0, "stack.js"], - [ false, null, 129, 0, "stack.js"] + [ false, "testWasmMemOutOfBounds", 118, 0, "stack.js"], + [ false, null, 130, 0, "stack.js"] ]); } })(); diff --git a/test/mjsunit/wasm/wasm-constants.js b/test/mjsunit/wasm/wasm-constants.js index e224c8562b..7c0904a80a 100644 --- a/test/mjsunit/wasm/wasm-constants.js +++ b/test/mjsunit/wasm/wasm-constants.js @@ -65,6 +65,10 @@ let kCodeSectionCode = 10; // Function code let kDataSectionCode = 11; // Data segments let kNameSectionCode = 12; // Name section (encoded as string) +// Name section types +let kFunctionNamesCode = 1; +let kLocalNamesCode = 2; + let kWasmFunctionTypeForm = 0x60; let kWasmAnyFunctionTypeForm = 0x70; diff --git a/test/mjsunit/wasm/wasm-module-builder.js b/test/mjsunit/wasm/wasm-module-builder.js index 2940057838..79a3e8da89 100644 --- a/test/mjsunit/wasm/wasm-module-builder.js +++ b/test/mjsunit/wasm/wasm-module-builder.js @@ -336,15 +336,16 @@ class WasmModuleBuilder { } // Add functions declarations - let has_names = false; + let num_function_names = 0; let names = false; if (wasm.functions.length > 0) { if (debug) print("emitting function decls @ " + binary.length); binary.emit_section(kFunctionSectionCode, section => { section.emit_u32v(wasm.functions.length); for (let func of wasm.functions) { - has_names = has_names || (func.name != undefined && - func.name.length > 0); + if (func.name !== undefined) { + ++num_function_names; + } section.emit_u32v(func.type_index); } }); @@ -363,7 +364,7 @@ class WasmModuleBuilder { } // Add memory section - if (wasm.memory != undefined) { + if (wasm.memory !== undefined) { if (debug) print("emitting memory @ " + binary.length); binary.emit_section(kMemorySectionCode, section => { section.emit_u8(1); // one memory entry @@ -424,7 +425,7 @@ class WasmModuleBuilder { } // Add export table. - var mem_export = (wasm.memory != undefined && wasm.memory.exp); + var mem_export = (wasm.memory !== undefined && wasm.memory.exp); var exports_count = wasm.exports.length + (mem_export ? 1 : 0); if (exports_count > 0) { if (debug) print("emitting exports @ " + binary.length); @@ -444,7 +445,7 @@ class WasmModuleBuilder { } // Add start function section. - if (wasm.start_index != undefined) { + if (wasm.start_index !== undefined) { if (debug) print("emitting start function @ " + binary.length); binary.emit_section(kStartSectionCode, section => { section.emit_u32v(wasm.start_index); @@ -485,7 +486,7 @@ class WasmModuleBuilder { // Function body length will be patched later. let local_decls = []; let l = func.locals; - if (l != undefined) { + if (l !== undefined) { let local_decls_count = 0; if (l.i32_count > 0) { local_decls.push({count: l.i32_count, type: kWasmI32}); @@ -545,21 +546,18 @@ class WasmModuleBuilder { } // Add function names. - if (has_names) { - if (debug) print("emitting names @ " + binary.length); + if (num_function_names > 0) { + if (debug) print('emitting names @ ' + binary.length); binary.emit_section(kUnknownSectionCode, section => { - section.emit_string("name"); - var count = wasm.functions.length + wasm.num_imported_funcs; - section.emit_u32v(count); - for (var i = 0; i < wasm.num_imported_funcs; i++) { - section.emit_u8(0); // empty string - section.emit_u8(0); // local names count == 0 - } - for (let func of wasm.functions) { - var name = func.name == undefined ? "" : func.name; - section.emit_string(name); - section.emit_u8(0); // local names count == 0 - } + section.emit_string('name'); + section.emit_section(kFunctionNamesCode, name_section => { + name_section.emit_u32v(num_function_names); + for (let func of wasm.functions) { + if (func.name === undefined) continue; + name_section.emit_u32v(func.index); + name_section.emit_string(func.name); + } + }); }); }