I created a new empty Rust library. I set the crate-type
to cdylib
so that .wasm
files are generated. This is my lib.rs
:
#[no_mangle]
pub extern fn fibonacci(n: usize) -> usize {
if n < 2 {
return n;
}
return fibonacci(n - 1) + fibonacci(n - 2);
}
If I remove #[no_mangle]
, then Cargo produces a WASM binary that doesn't even contain any code:
$ wasm-objdump -h -x target/wasm32-unknown-unknown/release/fibonacci.wasm
fibonacci.wasm: file format wasm 0x1
Sections:
Table start=0x0000000a end=0x0000000f (size=0x00000005) count: 1
Memory start=0x00000011 end=0x00000014 (size=0x00000003) count: 1
Global start=0x00000016 end=0x0000002f (size=0x00000019) count: 3
Export start=0x00000031 end=0x00000056 (size=0x00000025) count: 3
Custom start=0x00000059 end=0x00000f5a (size=0x00000f01) ".debug_abbrev"
Custom start=0x00000f5e end=0x0005c6df (size=0x0005b781) ".debug_info"
Custom start=0x0005c6e3 end=0x00084461 (size=0x00027d7e) ".debug_ranges"
Custom start=0x00084465 end=0x00118f6a (size=0x00094b05) ".debug_str"
Custom start=0x00118f6e end=0x00152a48 (size=0x00039ada) ".debug_line"
Custom start=0x00152a4a end=0x00152a63 (size=0x00000019) "name"
Custom start=0x00152a65 end=0x00152ab2 (size=0x0000004d) "producers"
Custom start=0x00152ab4 end=0x00152ae0 (size=0x0000002c) "target_features"
Section Details:
Table[1]:
- table[0] type=funcref initial=1 max=1
Memory[1]:
- memory[0] pages: initial=16
Global[3]:
- global[0] i32 mutable=1 <__stack_pointer> - init i32=1048576
- global[1] i32 mutable=0 <__data_end> - init i32=1048576
- global[2] i32 mutable=0 <__heap_base> - init i32=1048576
Export[3]:
- memory[0] -> "memory"
- global[1] -> "__data_end"
- global[2] -> "__heap_base"
Custom:
- name: ".debug_abbrev"
Custom:
- name: ".debug_info"
Custom:
- name: ".debug_ranges"
Custom:
- name: ".debug_str"
Custom:
- name: ".debug_line"
Custom:
- name: "name"
- global[0] <__stack_pointer>
Custom:
- name: "producers"
Custom:
- name: "target_features"
- [+] mutable-globals
- [+] sign-ext
Is there any way to force the function to be included in the binary without using #[no_mangle]
? Using extern
by itself doesn't work.
The reference says about no_mangle
that it obviously disables name mangling, but moreover it is similar to the used
attribute.
However, used
only applies to static items, not functions, as visible in the example below.
Then, the only way to export your function implies disabling name mangling (which is reasonable in my opinion).
fn this_is_invisible(n: i32) -> i32 {
n * 2 + 1
}
pub fn this_is_also_invisible(n: i32) -> i32 {
n * 2 + 1
}
#[no_mangle]
fn this_is_accepted(n: i32) -> i32 {
n * 2 + 1
}
/*
// ERROR: attribute must be applied to a `static` variable
#[used]
fn this_is_rejected(n: i32) -> i32 {
n * 2 + 1
}
*/
$ nm target/debug/libmy_project.so | grep this_is
0000000000006e00 T this_is_accepted