Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ Current Trunk
- The --mod-asyncify-never-unwind and --mod-asyncify-always-and-only-unwind
passed were deleted. They only existed to support the lazy code loading
support in emscripten that was removed. (#7893)
- The --print-symbol-map/--symbolmap flags we removed. They only existed to
support an emscripten feature which was re-implemented downstream. (#7862)

v124
----
Expand Down
1 change: 1 addition & 0 deletions src/passes/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ set(passes_SOURCES
Print.cpp
PrintCallGraph.cpp
PrintFeatures.cpp
PrintFunctionMap.cpp
RoundTrip.cpp
SetGlobals.cpp
SignaturePruning.cpp
Expand Down
54 changes: 54 additions & 0 deletions src/passes/PrintFunctionMap.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright 2019 WebAssembly Community Group participants
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

//
// Prints the a map of function indexes to function names. This can be
// useful for interpreting a stack trace from a production environment
// where names did not exist on the client. The map looks like this:
//
// 0:foo
// 1:bar
// 2:baz
//

#include "ir/module-utils.h"
#include "pass.h"
#include "support/file.h"
#include "wasm.h"

namespace wasm {

struct PrintFunctionMap : public Pass {
bool modifiesBinaryenIR() override { return false; }

void run(Module* module) override {
// If an argument is provided, write to that file; otherwise write to
// stdout.
auto outFile = getArgumentOrDefault("symbolmap", "");
Output output(outFile, Flags::Text);
auto& o = output.getStream();
Index i = 0;
auto write = [&](Function* func) {
o << i++ << ':' << func->name.str << '\n';
};
ModuleUtils::iterImportedFunctions(*module, write);
ModuleUtils::iterDefinedFunctions(*module, write);
}
};

Pass* createPrintFunctionMapPass() { return new PrintFunctionMap(); }

} // namespace wasm
11 changes: 11 additions & 0 deletions src/passes/pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,17 @@ void PassRegistry::registerPasses() {
registerPass(
"print-call-graph", "print call graph", createPrintCallGraphPass);

// Register PrintFunctionMap using its normal name.
registerPass("print-function-map",
"print a map of function indexes to names",
createPrintFunctionMapPass);
// Also register it as "symbolmap" so that wasm-opt --symbolmap=foo is the
// same as wasm-as --symbolmap=foo even though the latter is not a pass
// (wasm-as cannot run arbitrary passes).
// TODO: switch emscripten to this name, then remove the old one
registerPass(
"symbolmap", "(alias for print-function-map)", createPrintFunctionMapPass);

registerPass("propagate-globals-globally",
"propagate global values to other globals (useful for tests)",
createPropagateGlobalsGloballyPass);
Expand Down
1 change: 1 addition & 0 deletions src/passes/passes.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ Pass* createPrecomputePropagatePass();
Pass* createPrinterPass();
Pass* createPrintCallGraphPass();
Pass* createPrintFeaturesPass();
Pass* createPrintFunctionMapPass();
Pass* createPropagateGlobalsGloballyPass();
Pass* createRandomizeBranchHintsPass();
Pass* createRemoveNonJSOpsPass();
Expand Down
12 changes: 6 additions & 6 deletions src/tools/wasm-opt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -436,12 +436,12 @@ For more on how to optimize effectively, see

if (options.extra.count("output") == 0) {
if (!options.quiet) {
bool printsToStdout =
std::any_of(options.passes.begin(),
options.passes.end(),
[](const OptimizationOptions::PassInfo& info) {
return info.name == "print";
});
bool printsToStdout = std::any_of(
options.passes.begin(),
options.passes.end(),
[](const OptimizationOptions::PassInfo& info) {
return info.name == "print" || info.name == "print-function-map";
});
if (!printsToStdout) {
std::cerr << "warning: no output file specified, not emitting output\n";
}
Expand Down
5 changes: 5 additions & 0 deletions test/lit/help/wasm-metadce.test
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,9 @@
;; CHECK-NEXT: --print-full print in full s-expression
;; CHECK-NEXT: format
;; CHECK-NEXT:
;; CHECK-NEXT: --print-function-map print a map of function indexes
;; CHECK-NEXT: to names
;; CHECK-NEXT:
;; CHECK-NEXT: --print-minified print in minified s-expression
;; CHECK-NEXT: format
;; CHECK-NEXT:
Expand Down Expand Up @@ -519,6 +522,8 @@
;; CHECK-NEXT: --stub-unsupported-js stub out unsupported JS
;; CHECK-NEXT: operations
;; CHECK-NEXT:
;; CHECK-NEXT: --symbolmap (alias for print-function-map)
;; CHECK-NEXT:
;; CHECK-NEXT: --table64-lowering alias for memory64-lowering
;; CHECK-NEXT:
;; CHECK-NEXT: --trace-calls instrument the build with code
Expand Down
5 changes: 5 additions & 0 deletions test/lit/help/wasm-opt.test
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,9 @@
;; CHECK-NEXT: --print-full print in full s-expression
;; CHECK-NEXT: format
;; CHECK-NEXT:
;; CHECK-NEXT: --print-function-map print a map of function indexes
;; CHECK-NEXT: to names
;; CHECK-NEXT:
;; CHECK-NEXT: --print-minified print in minified s-expression
;; CHECK-NEXT: format
;; CHECK-NEXT:
Expand Down Expand Up @@ -543,6 +546,8 @@
;; CHECK-NEXT: --stub-unsupported-js stub out unsupported JS
;; CHECK-NEXT: operations
;; CHECK-NEXT:
;; CHECK-NEXT: --symbolmap (alias for print-function-map)
;; CHECK-NEXT:
;; CHECK-NEXT: --table64-lowering alias for memory64-lowering
;; CHECK-NEXT:
;; CHECK-NEXT: --trace-calls instrument the build with code
Expand Down
5 changes: 5 additions & 0 deletions test/lit/help/wasm2js.test
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,9 @@
;; CHECK-NEXT: --print-full print in full s-expression
;; CHECK-NEXT: format
;; CHECK-NEXT:
;; CHECK-NEXT: --print-function-map print a map of function indexes
;; CHECK-NEXT: to names
;; CHECK-NEXT:
;; CHECK-NEXT: --print-minified print in minified s-expression
;; CHECK-NEXT: format
;; CHECK-NEXT:
Expand Down Expand Up @@ -483,6 +486,8 @@
;; CHECK-NEXT: --stub-unsupported-js stub out unsupported JS
;; CHECK-NEXT: operations
;; CHECK-NEXT:
;; CHECK-NEXT: --symbolmap (alias for print-function-map)
;; CHECK-NEXT:
;; CHECK-NEXT: --table64-lowering alias for memory64-lowering
;; CHECK-NEXT:
;; CHECK-NEXT: --trace-calls instrument the build with code
Expand Down
87 changes: 87 additions & 0 deletions test/lit/wasm-split/symbolmap-multi-split.wast
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
;; RUN: wasm-split -all --multi-split %s --manifest %S/multi-split.wast.manifest --out-prefix=%t --symbolmap -o %t.wasm
;; RUN: filecheck %s --check-prefix PRIMARY-MAP < %t.wasm.symbols
;; RUN: filecheck %s --check-prefix MOD1-MAP < %t1.wasm.symbols
;; RUN: filecheck %s --check-prefix MOD2-MAP < %t2.wasm.symbols
;; RUN: filecheck %s --check-prefix MOD3-MAP < %t3.wasm.symbols

;; PRIMARY-MAP: 0:placeholder_0
;; PRIMARY-MAP: 1:placeholder_0_4
;; PRIMARY-MAP: 2:placeholder_0_5
;; PRIMARY-MAP: 3:trampoline_A
;; PRIMARY-MAP: 4:trampoline_B
;; PRIMARY-MAP: 5:trampoline_C

;; MOD1-MAP: 0:B
;; MOD1-MAP: 1:C
;; MOD1-MAP: 2:A

;; MOD2-MAP: 0:C
;; MOD2-MAP: 1:trampoline_A
;; MOD2-MAP: 2:B

;; MOD3-MAP: 0:trampoline_A
;; MOD3-MAP: 1:trampoline_B
;; MOD3-MAP: 2:C

(module
(type $ret-i32 (func (result i32)))
(type $ret-i64 (func (result i64)))
(type $ret-f32 (func (result f32)))

(func $A (type $ret-i32) (result i32)
(drop
(call_ref $ret-i32
(ref.func $A)
)
)
(drop
(call_ref $ret-i64
(ref.func $B)
)
)
(drop
(call_ref $ret-f32
(ref.func $C)
)
)
(i32.const 0)
)

(func $B (type $ret-i64) (result i64)
(drop
(call_ref $ret-i32
(ref.func $A)
)
)
(drop
(call_ref $ret-i64
(ref.func $B)
)
)
(drop
(call_ref $ret-f32
(ref.func $C)
)
)
(i64.const 0)
)

(func $C (type $ret-f32) (result f32)
(drop
(call_ref $ret-i32
(ref.func $A)
)
)
(drop
(call_ref $ret-i64
(ref.func $B)
)
)
(drop
(call_ref $ret-f32
(ref.func $C)
)
)
(f32.const 0)
)
)
28 changes: 28 additions & 0 deletions test/lit/wasm-split/symbolmap.wast
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
;; RUN: wasm-split %s --keep-funcs=bar -o1 %t.1.wasm -o2 %t.2.wasm --symbolmap
;; RUN: filecheck %s --check-prefix PRIMARY-MAP < %t.1.wasm.symbols
;; RUN: filecheck %s --check-prefix SECONDARY-MAP < %t.2.wasm.symbols
;; RUN: wasm-dis %t.1.wasm | filecheck %s --check-prefix PRIMARY

;; PRIMARY-MAP: 0:placeholder_0
;; PRIMARY-MAP: 1:placeholder_2
;; PRIMARY-MAP: 2:bar

;; SECONDARY-MAP: 0:baz
;; SECONDARY-MAP: 1:foo

;; Check that the names have been stripped.
;; PRIMARY: (func $0

(module
(table $table 3 3 funcref)
(elem $table (i32.const 0) $foo $bar $baz)
(func $foo
(nop)
)
(func $bar
(nop)
)
(func $baz
(nop)
)
)
11 changes: 11 additions & 0 deletions test/passes/print-function-map.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
0:Foo
1:bar
2:baz
(module
(type $0 (func))
(import "env" "foo" (func $Foo))
(func $bar
)
(func $baz
)
)
6 changes: 6 additions & 0 deletions test/passes/print-function-map.wast
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
(module
(import "env" "foo" (func $Foo))
(func $bar)
(func $baz)
)

20 changes: 20 additions & 0 deletions test/unit/test_symbolmap.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from scripts.test import shared
from . import utils


class SymbolMapTest(utils.BinaryenTestCase):
def test_symbolmap(self):
input_wasm = self.input_path('hello_world.wat')
# write the symbol map to a file
args = [input_wasm, '--symbolmap=out.symbols']
shared.run_process(shared.WASM_OPT + args)
with open('out.symbols') as f:
file_output = f.read()
# write the symbol map to stdout
args = [input_wasm, '--symbolmap']
stdout_output = shared.run_process(shared.WASM_OPT + args,
capture_output=True).stdout
# ignore whitespace in the comparison as on windows stdout gets an \r
self.assertEqual(file_output.strip(), stdout_output.strip())
# the wat contains a single function "add"
self.assertIn('0:add', file_output)
4 changes: 4 additions & 0 deletions test/unit/test_warnings.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ def test_quiet_suppresses_warnings(self):
def test_no_warn_on_print(self):
err = shared.run_process(shared.WASM_OPT + [self.input_path('asyncify-pure.wat'), '--print'], stderr=subprocess.PIPE).stderr
self.assertNotIn('warning: no output file specified, not emitting output', err)

def test_no_warn_on_print_function_map(self):
err = shared.run_process(shared.WASM_OPT + [self.input_path('asyncify-pure.wat'), '--print-function-map'], stderr=subprocess.PIPE).stderr
self.assertNotIn('warning: no output file specified, not emitting output', err)
Loading