@@ -85,7 +85,7 @@ class V8 : public WasmVm {
8585#undef _GET_MODULE_FUNCTION
8686
8787private:
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
644668std::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