diff --git a/src/libpanic_abort/lib.rs b/src/libpanic_abort/lib.rs index cf05e56e53c84..b86928534cb24 100644 --- a/src/libpanic_abort/lib.rs +++ b/src/libpanic_abort/lib.rs @@ -96,9 +96,14 @@ pub unsafe extern fn __rust_start_panic(_payload: usize) -> u32 { // runtime at all. pub mod personalities { #[no_mangle] - #[cfg(not(all(target_os = "windows", - target_env = "gnu", - target_arch = "x86_64")))] + #[cfg(not(any( + target_arch = "wasm32", + all( + target_os = "windows", + target_env = "gnu", + target_arch = "x86_64", + ), + )))] pub extern fn rust_eh_personality() {} // On x86_64-pc-windows-gnu we use our own personality function that needs diff --git a/src/librustc_codegen_llvm/back/linker.rs b/src/librustc_codegen_llvm/back/linker.rs index c03180c02fe63..e18c8b9dec463 100644 --- a/src/librustc_codegen_llvm/back/linker.rs +++ b/src/librustc_codegen_llvm/back/linker.rs @@ -89,6 +89,7 @@ impl LinkerInfo { Box::new(WasmLd { cmd, sess, + info: self }) as Box } } @@ -926,6 +927,7 @@ fn exported_symbols(tcx: TyCtxt, crate_type: CrateType) -> Vec { pub struct WasmLd<'a> { cmd: Command, sess: &'a Session, + info: &'a LinkerInfo, } impl<'a> Linker for WasmLd<'a> { @@ -1021,7 +1023,10 @@ impl<'a> Linker for WasmLd<'a> { fn build_dylib(&mut self, _out_filename: &Path) { } - fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType) { + fn export_symbols(&mut self, _tmpdir: &Path, crate_type: CrateType) { + for sym in self.info.exports[&crate_type].iter() { + self.cmd.arg("--export").arg(&sym); + } } fn subsystem(&mut self, _subsystem: &str) { diff --git a/src/test/run-make/wasm-export-all-symbols/Makefile b/src/test/run-make/wasm-export-all-symbols/Makefile new file mode 100644 index 0000000000000..07379b7624413 --- /dev/null +++ b/src/test/run-make/wasm-export-all-symbols/Makefile @@ -0,0 +1,16 @@ +-include ../../run-make-fulldeps/tools.mk + +ifeq ($(TARGET),wasm32-unknown-unknown) +all: + $(RUSTC) bar.rs --target wasm32-unknown-unknown + $(RUSTC) foo.rs --target wasm32-unknown-unknown + $(NODE) verify.js $(TMPDIR)/foo.wasm + $(RUSTC) bar.rs --target wasm32-unknown-unknown -O + $(RUSTC) foo.rs --target wasm32-unknown-unknown -O + $(NODE) verify.js $(TMPDIR)/foo.wasm + $(RUSTC) foo.rs --target wasm32-unknown-unknown -C lto + $(NODE) verify.js $(TMPDIR)/foo.wasm +else +all: +endif + diff --git a/src/test/run-make/wasm-export-all-symbols/bar.rs b/src/test/run-make/wasm-export-all-symbols/bar.rs new file mode 100644 index 0000000000000..5d4ce06a978fc --- /dev/null +++ b/src/test/run-make/wasm-export-all-symbols/bar.rs @@ -0,0 +1,14 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "rlib"] + +#[no_mangle] +pub extern fn foo() {} diff --git a/src/test/run-make/wasm-export-all-symbols/foo.rs b/src/test/run-make/wasm-export-all-symbols/foo.rs new file mode 100644 index 0000000000000..fc1ed31771a04 --- /dev/null +++ b/src/test/run-make/wasm-export-all-symbols/foo.rs @@ -0,0 +1,13 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "cdylib"] + +extern crate bar; diff --git a/src/test/run-make/wasm-export-all-symbols/verify.js b/src/test/run-make/wasm-export-all-symbols/verify.js new file mode 100644 index 0000000000000..5a505ea30c87d --- /dev/null +++ b/src/test/run-make/wasm-export-all-symbols/verify.js @@ -0,0 +1,32 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +const fs = require('fs'); +const process = require('process'); +const assert = require('assert'); +const buffer = fs.readFileSync(process.argv[2]); + +let m = new WebAssembly.Module(buffer); +let list = WebAssembly.Module.exports(m); +console.log('exports', list); + +const my_exports = {}; +let nexports = 0; +for (const entry of list) { + if (entry.kind !== 'function') + continue; + my_exports[entry.name] = true; + nexports += 1; +} + +if (nexports != 1) + throw new Error("should only have one function export"); +if (my_exports.foo === undefined) + throw new Error("`foo` wasn't defined");