diff --git a/src/tools/wasm-split/wasm-split.cpp b/src/tools/wasm-split/wasm-split.cpp index c520c04a1cf..669101fc4b5 100644 --- a/src/tools/wasm-split/wasm-split.cpp +++ b/src/tools/wasm-split/wasm-split.cpp @@ -390,14 +390,14 @@ void multiSplitModule(const WasmSplitOptions& options) { parseInput(wasm, options); // Map module names to the functions that should be in the modules. - std::map> moduleFuncs; + std::map> moduleFuncs; // The module for which we are currently parsing a set of functions. - std::string currModule; + Name currModule; // The set of functions we are currently inserting into. - std::unordered_set* currFuncs = nullptr; + std::unordered_set* currFuncs = nullptr; // Map functions to their modules to ensure no function is assigned to // multiple modules. - std::unordered_map funcModules; + std::unordered_map funcModules; std::string line; bool newSection = true; @@ -406,22 +406,23 @@ void multiSplitModule(const WasmSplitOptions& options) { newSection = true; continue; } + Name name = WasmBinaryReader::escape(line); if (newSection) { - currModule = line; - currFuncs = &moduleFuncs[line]; + currModule = name; + currFuncs = &moduleFuncs[name]; newSection = false; continue; } assert(currFuncs); - currFuncs->insert(line); - auto [it, inserted] = funcModules.insert({line, currModule}); + currFuncs->insert(name); + auto [it, inserted] = funcModules.insert({name, currModule}); if (!inserted && it->second != currModule) { - Fatal() << "Function " << line << "cannot be assigned to module " + Fatal() << "Function " << name << "cannot be assigned to module " << currModule << "; it is already assigned to module " << it->second << '\n'; } - if (inserted && !options.quiet && !wasm.getFunctionOrNull(line)) { - std::cerr << "warning: Function " << line << " does not exist\n"; + if (inserted && !options.quiet && !wasm.getFunctionOrNull(name)) { + std::cerr << "warning: Function " << name << " does not exist\n"; } } @@ -443,8 +444,8 @@ void multiSplitModule(const WasmSplitOptions& options) { } config.secondaryFuncs = std::set(funcs.begin(), funcs.end()); auto splitResults = ModuleSplitting::splitFunctions(wasm, config); - auto moduleName = - options.outPrefix + mod + (options.emitBinary ? ".wasm" : ".wast"); + auto moduleName = options.outPrefix + mod.toString() + + (options.emitBinary ? ".wasm" : ".wast"); if (options.symbolMap) { writeSymbolMap(*splitResults.secondary, moduleName + ".symbols"); } diff --git a/test/lit/wasm-split/multi-split-escape-names.wast b/test/lit/wasm-split/multi-split-escape-names.wast new file mode 100644 index 00000000000..561858e3e12 --- /dev/null +++ b/test/lit/wasm-split/multi-split-escape-names.wast @@ -0,0 +1,216 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-split -all -g --multi-split %s --manifest %s.manifest --out-prefix=%t -o %t.wasm +;; RUN: wasm-dis %t.wasm | filecheck %s --check-prefix=PRIMARY +;; RUN: wasm-dis %t1.wasm | filecheck %s --check-prefix=MOD1 +;; RUN: wasm-dis %t2.wasm | filecheck %s --check-prefix=MOD2 +;; RUN: wasm-dis %t3.wasm | filecheck %s --check-prefix=MOD3 + +(module + ;; PRIMARY: (type $ret-i32 (func (result i32))) + (type $ret-i32 (func (result i32))) + ;; PRIMARY: (type $ret-i64 (func (result i64))) + (type $ret-i64 (func (result i64))) + ;; PRIMARY: (type $ret-f32 (func (result f32))) + (type $ret-f32 (func (result f32))) + + ;; MOD1: (type $0 (func (result f32))) + + ;; MOD1: (type $1 (func (result i64))) + + ;; MOD1: (type $2 (func (result i32))) + + ;; MOD1: (import "" "table" (table $timport$0 1 funcref)) + + ;; MOD1: (import "" "std::operator<<\\28std::__2::basic_ostream>&\\2c\\20wasm::Module&\\29" (func $std::operator<<\28std::__2::basic_ostream>&\2c\20wasm::Module&\29 (result f32))) + + ;; MOD1: (import "" "wasm::Literal::Literal\\28std::__2::array\\20const&\\29" (func $wasm::Literal::Literal\28std::__2::array\20const&\29 (result i64))) + + ;; MOD1: (elem $0 (i32.const 0) $wasm::Type::getFeatures\28\29\20const) + + ;; MOD1: (func $wasm::Type::getFeatures\28\29\20const (result i32) + ;; MOD1-NEXT: (drop + ;; MOD1-NEXT: (call_ref $2 + ;; MOD1-NEXT: (ref.func $wasm::Type::getFeatures\28\29\20const) + ;; MOD1-NEXT: ) + ;; MOD1-NEXT: ) + ;; MOD1-NEXT: (drop + ;; MOD1-NEXT: (call_ref $1 + ;; MOD1-NEXT: (ref.func $wasm::Literal::Literal\28std::__2::array\20const&\29) + ;; MOD1-NEXT: ) + ;; MOD1-NEXT: ) + ;; MOD1-NEXT: (drop + ;; MOD1-NEXT: (call_ref $0 + ;; MOD1-NEXT: (ref.func $std::operator<<\28std::__2::basic_ostream>&\2c\20wasm::Module&\29) + ;; MOD1-NEXT: ) + ;; MOD1-NEXT: ) + ;; MOD1-NEXT: (i32.const 0) + ;; MOD1-NEXT: ) + (func $wasm::Type::getFeatures\28\29\20const (type $ret-i32) (result i32) + (drop + (call_ref $ret-i32 + (ref.func $wasm::Type::getFeatures\28\29\20const) + ) + ) + (drop + (call_ref $ret-i64 + (ref.func $wasm::Literal::Literal\28std::__2::array\20const&\29) + ) + ) + (drop + (call_ref $ret-f32 + (ref.func $std::operator<<\28std::__2::basic_ostream>&\2c\20wasm::Module&\29) + ) + ) + (i32.const 0) + ) + + ;; MOD2: (type $0 (func (result f32))) + + ;; MOD2: (type $1 (func (result i32))) + + ;; MOD2: (type $2 (func (result i64))) + + ;; MOD2: (import "" "table_4" (table $timport$0 1 funcref)) + + ;; MOD2: (import "" "std::operator<<\\28std::__2::basic_ostream>&\\2c\\20wasm::Module&\\29" (func $std::operator<<\28std::__2::basic_ostream>&\2c\20wasm::Module&\29 (result f32))) + + ;; MOD2: (import "" "trampoline_wasm::Type::getFeatures\\28\\29\\20const" (func $trampoline_wasm::Type::getFeatures\28\29\20const (result i32))) + + ;; MOD2: (elem $0 (i32.const 0) $wasm::Literal::Literal\28std::__2::array\20const&\29) + + ;; MOD2: (func $wasm::Literal::Literal\28std::__2::array\20const&\29 (result i64) + ;; MOD2-NEXT: (drop + ;; MOD2-NEXT: (call_ref $1 + ;; MOD2-NEXT: (ref.func $trampoline_wasm::Type::getFeatures\28\29\20const) + ;; MOD2-NEXT: ) + ;; MOD2-NEXT: ) + ;; MOD2-NEXT: (drop + ;; MOD2-NEXT: (call_ref $2 + ;; MOD2-NEXT: (ref.func $wasm::Literal::Literal\28std::__2::array\20const&\29) + ;; MOD2-NEXT: ) + ;; MOD2-NEXT: ) + ;; MOD2-NEXT: (drop + ;; MOD2-NEXT: (call_ref $0 + ;; MOD2-NEXT: (ref.func $std::operator<<\28std::__2::basic_ostream>&\2c\20wasm::Module&\29) + ;; MOD2-NEXT: ) + ;; MOD2-NEXT: ) + ;; MOD2-NEXT: (i64.const 0) + ;; MOD2-NEXT: ) + (func $wasm::Literal::Literal\28std::__2::array\20const&\29 (type $ret-i64) (result i64) + (drop + (call_ref $ret-i32 + (ref.func $wasm::Type::getFeatures\28\29\20const) + ) + ) + (drop + (call_ref $ret-i64 + (ref.func $wasm::Literal::Literal\28std::__2::array\20const&\29) + ) + ) + (drop + (call_ref $ret-f32 + (ref.func $std::operator<<\28std::__2::basic_ostream>&\2c\20wasm::Module&\29) + ) + ) + (i64.const 0) + ) + + ;; MOD3: (type $0 (func (result i64))) + + ;; MOD3: (type $1 (func (result i32))) + + ;; MOD3: (type $2 (func (result f32))) + + ;; MOD3: (import "" "table_5" (table $timport$0 1 funcref)) + + ;; MOD3: (import "" "wasm::Literal::Literal\\28std::__2::array\\20const&\\29" (func $trampoline_wasm::Literal::Literal\28std::__2::array\20const&\29 (result i64))) + + ;; MOD3: (import "" "trampoline_wasm::Type::getFeatures\\28\\29\\20const" (func $trampoline_wasm::Type::getFeatures\28\29\20const (result i32))) + + ;; MOD3: (elem $0 (i32.const 0) $std::operator<<\28std::__2::basic_ostream>&\2c\20wasm::Module&\29) + + ;; MOD3: (func $std::operator<<\28std::__2::basic_ostream>&\2c\20wasm::Module&\29 (result f32) + ;; MOD3-NEXT: (drop + ;; MOD3-NEXT: (call_ref $1 + ;; MOD3-NEXT: (ref.func $trampoline_wasm::Type::getFeatures\28\29\20const) + ;; MOD3-NEXT: ) + ;; MOD3-NEXT: ) + ;; MOD3-NEXT: (drop + ;; MOD3-NEXT: (call_ref $0 + ;; MOD3-NEXT: (ref.func $trampoline_wasm::Literal::Literal\28std::__2::array\20const&\29) + ;; MOD3-NEXT: ) + ;; MOD3-NEXT: ) + ;; MOD3-NEXT: (drop + ;; MOD3-NEXT: (call_ref $2 + ;; MOD3-NEXT: (ref.func $std::operator<<\28std::__2::basic_ostream>&\2c\20wasm::Module&\29) + ;; MOD3-NEXT: ) + ;; MOD3-NEXT: ) + ;; MOD3-NEXT: (f32.const 0) + ;; MOD3-NEXT: ) + (func $std::operator<<\28std::__2::basic_ostream>&\2c\20wasm::Module&\29 (type $ret-f32) (result f32) + (drop + (call_ref $ret-i32 + (ref.func $wasm::Type::getFeatures\28\29\20const) + ) + ) + (drop + (call_ref $ret-i64 + (ref.func $wasm::Literal::Literal\28std::__2::array\20const&\29) + ) + ) + (drop + (call_ref $ret-f32 + (ref.func $std::operator<<\28std::__2::basic_ostream>&\2c\20wasm::Module&\29) + ) + ) + (f32.const 0) + ) +) +;; PRIMARY: (import "placeholder" "0" (func $placeholder_0 (result i32))) + +;; PRIMARY: (import "placeholder" "0" (func $placeholder_0_4 (result i64))) + +;; PRIMARY: (import "placeholder" "0" (func $placeholder_0_5 (result f32))) + +;; PRIMARY: (table $0 1 funcref) + +;; PRIMARY: (table $1 1 funcref) + +;; PRIMARY: (table $2 1 funcref) + +;; PRIMARY: (elem $0 (table $0) (i32.const 0) func $placeholder_0) + +;; PRIMARY: (elem $1 (table $1) (i32.const 0) func $placeholder_0_4) + +;; PRIMARY: (elem $2 (table $2) (i32.const 0) func $placeholder_0_5) + +;; PRIMARY: (export "std::operator<<\\28std::__2::basic_ostream>&\\2c\\20wasm::Module&\\29" (func $trampoline_std::operator<<\28std::__2::basic_ostream>&\2c\20wasm::Module&\29)) + +;; PRIMARY: (export "wasm::Literal::Literal\\28std::__2::array\\20const&\\29" (func $trampoline_wasm::Literal::Literal\28std::__2::array\20const&\29)) + +;; PRIMARY: (export "table" (table $0)) + +;; PRIMARY: (export "trampoline_wasm::Type::getFeatures\\28\\29\\20const" (func $trampoline_wasm::Type::getFeatures\28\29\20const)) + +;; PRIMARY: (export "table_4" (table $1)) + +;; PRIMARY: (export "table_5" (table $2)) + +;; PRIMARY: (func $trampoline_wasm::Type::getFeatures\28\29\20const (result i32) +;; PRIMARY-NEXT: (call_indirect (type $ret-i32) +;; PRIMARY-NEXT: (i32.const 0) +;; PRIMARY-NEXT: ) +;; PRIMARY-NEXT: ) + +;; PRIMARY: (func $trampoline_wasm::Literal::Literal\28std::__2::array\20const&\29 (result i64) +;; PRIMARY-NEXT: (call_indirect $1 (type $ret-i64) +;; PRIMARY-NEXT: (i32.const 0) +;; PRIMARY-NEXT: ) +;; PRIMARY-NEXT: ) + +;; PRIMARY: (func $trampoline_std::operator<<\28std::__2::basic_ostream>&\2c\20wasm::Module&\29 (result f32) +;; PRIMARY-NEXT: (call_indirect $2 (type $ret-f32) +;; PRIMARY-NEXT: (i32.const 0) +;; PRIMARY-NEXT: ) +;; PRIMARY-NEXT: ) diff --git a/test/lit/wasm-split/multi-split-escape-names.wast.manifest b/test/lit/wasm-split/multi-split-escape-names.wast.manifest new file mode 100644 index 00000000000..23533e6dcf6 --- /dev/null +++ b/test/lit/wasm-split/multi-split-escape-names.wast.manifest @@ -0,0 +1,8 @@ +1 +wasm::Type::getFeatures() const + +2 +wasm::Literal::Literal(std::__2::array const&) + +3 +std::operator<<(std::__2::basic_ostream>&, wasm::Module&)