Skip to content

Commit 3510109

Browse files
committed
review: build function name index in load()
Signed-off-by: mathetake <takeshi@tetrate.io>
1 parent 50db266 commit 3510109

File tree

1 file changed

+44
-49
lines changed

1 file changed

+44
-49
lines changed

src/v8/v8.cc

Lines changed: 44 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ class V8 : public WasmVm {
8585
#undef _GET_MODULE_FUNCTION
8686

8787
private:
88-
std::string getFailMessage(std::string function_name, wasm::own<wasm::Trap> trap);
88+
std::string getFailMessage(std::string_view function_name, wasm::own<wasm::Trap> trap);
8989
wasm::vec<byte_t> getStrippedSource();
9090

9191
template <typename... Args>
@@ -115,7 +115,7 @@ class V8 : public WasmVm {
115115
absl::flat_hash_map<std::string, FuncDataPtr> host_functions_;
116116
absl::flat_hash_map<std::string, wasm::own<wasm::Func>> module_functions_;
117117

118-
std::string_view name_section_;
118+
absl::flat_hash_map<uint32_t, std::string> function_names_index_;
119119
};
120120

121121
// Helper functions.
@@ -267,7 +267,30 @@ bool V8::load(const std::string &code, bool allow_precompiled) {
267267
assert((shared_module_ != nullptr));
268268
}
269269

270-
name_section_ = getCustomSection("name");
270+
// build function index -> function name map for backtrace
271+
// https://webassembly.github.io/spec/core/appendix/custom.html#binary-namesubsection
272+
auto name_section = getCustomSection("name");
273+
const byte_t *pos = name_section.data();
274+
const byte_t *end = name_section.data() + name_section.size();
275+
276+
// module name subsection (id=0) is currently unimplemented in LLVM but we handle the
277+
// case just in case
278+
if (*pos == 0) {
279+
pos++;
280+
pos += parseVarint(pos, end);
281+
}
282+
283+
if (*pos == 1) {
284+
pos++;
285+
parseVarint(pos, end); // skip subsection size
286+
const uint32_t namemap_vector_size = parseVarint(pos, end);
287+
for (auto i = 0; i < namemap_vector_size; i++) {
288+
const uint32_t func_index = parseVarint(pos, end);
289+
const uint32_t func_name_size = parseVarint(pos, end);
290+
function_names_index_.insert({func_index, std::string(pos, func_name_size)});
291+
pos += func_name_size;
292+
}
293+
}
271294
return module_ != nullptr;
272295
}
273296

@@ -279,7 +302,7 @@ std::unique_ptr<WasmVm> V8::clone() {
279302
clone->store_ = wasm::Store::make(engine());
280303

281304
clone->module_ = wasm::Module::obtain(clone->store_.get(), shared_module_.get());
282-
clone->name_section_ = name_section;
305+
clone->function_names_index_ = function_names_index_;
283306
return clone;
284307
}
285308

@@ -491,6 +514,7 @@ bool V8::link(std::string_view debug_name) {
491514
} break;
492515
}
493516
}
517+
494518
return !isFailed();
495519
}
496520

@@ -642,58 +666,29 @@ void V8::getModuleFunctionImpl(std::string_view function_name,
642666
}
643667

644668
std::string V8::getFailMessage(std::string_view function_name, wasm::own<wasm::Trap> trap) {
645-
auto message = "Function: " + function_name + " failed:\n";
669+
auto message = "Function: " + std::string(function_name) + " failed:\n";
646670
message += "V8 message: " + std::string(trap->message().get(), trap->message().size()) + "\n";
647671

648672
auto trace = trap->trace();
649673

650-
if (!trace.size() || !name_section_.size()) {
651-
return message;
652-
}
674+
message += "wasm backtrace:\n";
675+
for (size_t i = 0; i < trace.size(); ++i) {
676+
auto frame = trace[i].get();
677+
message += " " + std::to_string(i) + ": ";
653678

654-
const byte_t *pos = name_section_.data();
655-
const byte_t *end = name_section_.data() + name_section_.size();
656-
// https://webassembly.github.io/spec/core/appendix/custom.html#binary-namesubsection
657-
658-
if (*pos == 0) { // module name section
659-
pos++;
660-
parseVarint(pos, end); // skip subsubsection size
661-
const uint32_t module_name_size = parseVarint(pos, end);
662-
message += "module name: " + std::string(pos, module_name_size) + "\n";
663-
pos += module_name_size;
664-
}
679+
std::stringstream address;
680+
address << std::hex << frame->module_offset();
681+
message += " 0x" + address.str() + " - ";
665682

666-
if (*pos == 1) { // function name section
667-
std::unordered_map<uint32_t, std::string> function_names{};
668-
pos++;
669-
parseVarint(pos, end); // skip subsection size
670-
const uint32_t namemap_vector_size = parseVarint(pos, end);
671-
for (auto i = 0; i < namemap_vector_size; i++) {
672-
const uint32_t func_index = parseVarint(pos, end);
673-
const uint32_t func_name_size = parseVarint(pos, end);
674-
function_names.insert({func_index, std::string(pos, func_name_size)});
675-
pos += func_name_size;
676-
}
677-
678-
message += "wasm backtrace:\n";
679-
for (size_t i = 0; i < trace.size(); ++i) {
680-
auto frame = trace[i].get();
681-
message += " " + std::to_string(i) + ": ";
682-
683-
std::stringstream address;
684-
address << std::hex << frame->module_offset();
685-
message += " 0x" + address.str() + " - ";
686-
687-
auto func_index = frame->func_index();
688-
auto it = function_names.find(func_index);
689-
std::string function_name;
690-
if (it != function_names.end()) {
691-
function_name = it->second;
692-
} else {
693-
function_name = "unknown(function index:" + std::to_string(func_index) + ")";
694-
}
695-
message += function_name + "\n";
683+
auto func_index = frame->func_index();
684+
auto it = function_names_index_.find(func_index);
685+
std::string function_name;
686+
if (it != function_names_index_.end()) {
687+
function_name = it->second;
688+
} else {
689+
function_name = "unknown(function index:" + std::to_string(func_index) + ")";
696690
}
691+
message += function_name + "\n";
697692
}
698693
return message;
699694
}

0 commit comments

Comments
 (0)