-
Notifications
You must be signed in to change notification settings - Fork 14k
Description
When trying to compile a code that uses foreign global variables under wasm32-unknown-unknown it appears that wrong code is generated. My use case is that I want to export a variable foo from the host, so Rust program compiled into wasm can use value of this variable.
I tried this code:
extern "C" {
#[no_mangle]
static foo: i32;
}
#[no_mangle]
pub extern "C" fn bar() -> i32 {
unsafe { foo }
}Compiled with:
rustc --target wasm32-unknown-unknown -O --crate-type=cdylib src/main.rs -o wasm_test.wasmProduces following WASM code:
(module
(type (;0;) (func))
(type (;1;) (func (result i32)))
(func $__wasm_call_ctors (type 0))
(func $bar (type 1) (result i32)
i32.const 0
i32.load)
(table (;0;) 1 1 anyfunc)
(memory (;0;) 16)
(global (;0;) (mut i32) (i32.const 1048576))
(global (;1;) i32 (i32.const 1048576))
(global (;2;) i32 (i32.const 1048576))
(export "memory" (memory 0))
(export "__heap_base" (global 1))
(export "__data_end" (global 2))
(export "bar" (func $bar)))Rust appears to treat variable extern "C" static foo: i32; as variable with local linkage without emitting "import global" opcodes.
This should be the direct translation into C++ code. This also declares a variable with external linkage:
extern int foo;
int bar() { return foo; }Compiled into WASM:
(module
(import "env" "foo" (global $foo i32))
(table 0 anyfunc)
(memory $0 1)
(export "memory" (memory $0))
(export "_Z3barv" (func $_Z3barv))
(func $_Z3barv (; 0 ;) (result i32)
(i32.load
(get_global $foo)
)
)
)Note the (import "env" "foo" (global $foo i32)): This is what C++ compiler emits when it encounters a variable declared with an external linkage. Source
I believe current behaviour of Rust compiler is incorrect and wrong WASM code is generated for variables with external C linkage. Perhaps there is a special syntax for emitting (import "env" "foo" (global $foo i32))? Right now the only workaround seems to be using functions instead of variables to communicate between host and the wasm program which works perfectly fine. Please let me know if I missed something and there is an easy way to achieve this.
Meta
rustc --version --verbose:
rustc 1.36.0-nightly (a9ec99f 2019-05-13)
I've also tried on stable, and other versions of rust nightly.