Only export functions with default visibility As discussed in #585, this change makes s2wasm more aware of the symbol visibility output from LLVM, and only exports global functions with default visibility (instead of all globals as before).
diff --git a/src/s2wasm.h b/src/s2wasm.h index bf66f44..5eae659 100644 --- a/src/s2wasm.h +++ b/src/s2wasm.h
@@ -399,7 +399,10 @@ s++; if (match("text")) parseText(); else if (match("type")) parseType(); - else if (match("weak") || match("hidden") || match("protected") || match("internal")) getStr(); // contents are in the content that follows + else if (match("weak")) getStr(); // contents are in the content that follows + else if (match("hidden")) parseVisibility(LinkerObject::Visibility::kHidden); + else if (match("internal")) parseVisibility(LinkerObject::Visibility::kInternal); + else if (match("protected")) parseVisibility(LinkerObject::Visibility::kProtected); else if (match("imports")) skipImports(); else if (match("data")) {} else if (match("ident")) skipToEOL(); @@ -481,6 +484,10 @@ WASM_UNUSED(filename); // TODO: use the filename } + void parseVisibility(LinkerObject::Visibility vis) { + linkerObj->setVisibility(getStr(), vis); + skipWhitespace(); + } void parseGlobl() { linkerObj->addGlobal(getStr()); skipWhitespace();
diff --git a/src/wasm-linker.cpp b/src/wasm-linker.cpp index e6a0a05..fe95b97 100644 --- a/src/wasm-linker.cpp +++ b/src/wasm-linker.cpp
@@ -115,8 +115,17 @@ if (userMaxMemory) out.wasm.memory.max = userMaxMemory / Memory::kPageSize; out.wasm.memory.exportName = MEMORY; - // XXX For now, export all functions marked .globl. - for (Name name : out.globls) exportFunction(name, false); + // Export all globl functions with default visibility. Since .s files usually + // only output visibility information if it is not default, symbols are + // considered to have default visibility if they are not in the visibility table. + // Also export main for now because emscripten and the binaryen-shell tests use it. + for (Name name : out.globls) { + if (out.visibilities.count(name) == 0 || + out.visibilities.at(name) == LinkerObject::Visibility::kDefault || + name == "main") { + exportFunction(name, false); + } + } for (Name name : out.initializerFunctions) exportFunction(name, true); auto ensureFunctionIndex = [this](Name name) {
diff --git a/src/wasm-linker.h b/src/wasm-linker.h index 97e1c9c..808b892 100644 --- a/src/wasm-linker.h +++ b/src/wasm-linker.h
@@ -67,6 +67,7 @@ other.aliasedFunctions.end()); } }; + enum class Visibility { kDefault, kInternal, kHidden, kProtected }; LinkerObject() {} @@ -75,6 +76,9 @@ staticObjects.emplace_back(allocSize, alignment, name); } + void setVisibility(Name name, Visibility vis) { + visibilities[name] = vis; + } void addGlobal(Name name) { globls.push_back(name); } @@ -145,6 +149,7 @@ allocSize(allocSize), alignment(alignment), name(name) {} }; + std::unordered_map<cashew::IString, LinkerObject::Visibility> visibilities; std::vector<Name> globls; std::vector<StaticObject> staticObjects;
diff --git a/test/dot_s/alias.wast b/test/dot_s/alias.wast index d1e08e1..0bbd414 100644 --- a/test/dot_s/alias.wast +++ b/test/dot_s/alias.wast
@@ -2,8 +2,6 @@ (memory 1) (export "memory" memory) (type $FUNCSIG$v (func)) - (export "__exit" $__exit) - (export "__needs_exit" $__needs_exit) (export "dynCall_v" $dynCall_v) (table $__exit) (func $__exit (type $FUNCSIG$v)
diff --git a/test/dot_s/bcp-1.wast b/test/dot_s/bcp-1.wast index 0525be4..2e94f22 100644 --- a/test/dot_s/bcp-1.wast +++ b/test/dot_s/bcp-1.wast
@@ -15,23 +15,6 @@ (type $FUNCSIG$vi (func (param i32))) (import $abort "env" "abort") (import $exit "env" "exit" (param i32)) - (export "bad0" $bad0) - (export "bad1" $bad1) - (export "bad2" $bad2) - (export "bad3" $bad3) - (export "bad4" $bad4) - (export "bad5" $bad5) - (export "bad6" $bad6) - (export "bad7" $bad7) - (export "bad8" $bad8) - (export "bad9" $bad9) - (export "bad10" $bad10) - (export "good0" $good0) - (export "good1" $good1) - (export "good2" $good2) - (export "opt0" $opt0) - (export "opt1" $opt1) - (export "opt2" $opt2) (export "main" $main) (export "dynCall_i" $dynCall_i) (export "dynCall_ii" $dynCall_ii)
diff --git a/test/dot_s/debug.wast b/test/dot_s/debug.wast index 3a859fd..d17be66 100644 --- a/test/dot_s/debug.wast +++ b/test/dot_s/debug.wast
@@ -1,7 +1,6 @@ (module (memory 1) (export "memory" memory) - (export "fib" $fib) (func $fib (param $0 i32) (result i32) (local $1 i32) (local $2 i32)
diff --git a/test/dot_s/dyncall.wast b/test/dot_s/dyncall.wast index b0521de..9cb81ed 100644 --- a/test/dot_s/dyncall.wast +++ b/test/dot_s/dyncall.wast
@@ -5,11 +5,6 @@ (type $FUNCSIG$if (func (param f32) (result i32))) (type $FUNCSIG$vd (func (param f64))) (type $FUNCSIG$ffjjdi (func (param f32 i64 i64 f64 i32) (result f32))) - (export "i" $i) - (export "i_f" $i_f) - (export "vd" $vd) - (export "ffjjdi" $ffjjdi) - (export "vd2" $vd2) (export "main" $main) (export "dynCall_i" $dynCall_i) (export "dynCall_if" $dynCall_if)
diff --git a/test/dot_s/indirect-import.wast b/test/dot_s/indirect-import.wast index 21378ee..2eb506f 100644 --- a/test/dot_s/indirect-import.wast +++ b/test/dot_s/indirect-import.wast
@@ -12,8 +12,6 @@ (import $extern_fd "env" "extern_fd" (param f64) (result f32)) (import $extern_struct "env" "extern_struct" (param i32)) (import $extern_sret "env" "extern_sret" (param i32)) - (export "bar" $bar) - (export "baz" $baz) (export "dynCall_fd" $dynCall_fd) (export "dynCall_v" $dynCall_v) (export "dynCall_vi" $dynCall_vi)
diff --git a/test/dot_s/visibilities.wast b/test/dot_s/visibilities.wast index cfd5040..5879190 100644 --- a/test/dot_s/visibilities.wast +++ b/test/dot_s/visibilities.wast
@@ -1,9 +1,6 @@ (module (memory 1) (export "memory" memory) - (export "foo" $foo) - (export "bar" $bar) - (export "qux" $qux) (func $foo (return) )
diff --git a/test/llvm_autogenerated/reg-stackify.wast b/test/llvm_autogenerated/reg-stackify.wast index eea7e8b..652b078 100644 --- a/test/llvm_autogenerated/reg-stackify.wast +++ b/test/llvm_autogenerated/reg-stackify.wast
@@ -31,7 +31,6 @@ (export "no_sink_readonly_call" $no_sink_readonly_call) (export "stack_uses" $stack_uses) (export "multiple_uses" $multiple_uses) - (export "stackify_store_across_side_effects" $stackify_store_across_side_effects) (export "div_tree" $div_tree) (export "simple_multiple_use" $simple_multiple_use) (export "multiple_uses_in_same_insn" $multiple_uses_in_same_insn)
diff --git a/test/llvm_autogenerated/store-results.wast b/test/llvm_autogenerated/store-results.wast index dd974db..f67c4d8 100644 --- a/test/llvm_autogenerated/store-results.wast +++ b/test/llvm_autogenerated/store-results.wast
@@ -6,7 +6,6 @@ (export "single_block" $single_block) (export "foo" $foo) (export "bar" $bar) - (export "fi_ret" $fi_ret) (func $single_block (param $0 i32) (result i32) (return (i32.store