Description
Assume we have a crate named dependency
with the following content:
pub fn trigger() {
submodule::call();
}
pub mod submodule {
pub fn call() {
#[link_section = "some-custom-section"]
static SNIPPET: [u8; 3] = [b'X', b'Y', b'Z'];
extern "C" {
fn require_XYZ();
}
unsafe {
require_XYZ();
}
}
}
And we have another crate which uses the dependency
:
extern crate dependency;
#[no_mangle]
pub fn main() {
dependency::trigger();
}
If I compile this crate like this:
$ cargo build --target=wasm32-unknown-unknown --release
and dump it with wasm-objdump
then the "some-custom-section"
custom section will be missing. However, if I change the dependency
crate to look like this (I've moved the call
function from the submodule
to the crate root and even made it private):
pub fn trigger() {
call();
}
fn call() {
#[link_section = "some-custom-section"]
static SNIPPET: [u8; 3] = [b'X', b'Y', b'Z'];
extern "C" {
fn require_XYZ();
}
unsafe {
require_XYZ();
}
}
and build the main crate again then the custom section is generated. Calling dependency::submodule::call
directly instead of dependency::trigger
also results in the custom section being generated.
Based on my experiments the custom section generation currently works like this:
In which crate is the custom section defined? | Where is the function containing the section? | How is the function containing the custom section called? | Is it generated? |
---|---|---|---|
External crate | Submodule | Not called | No |
External crate | Submodule | Indirectly | No |
External crate | Submodule | Directly | Yes |
External crate | In root | Not called | No |
External crate | In root | Indirectly | Yes |
External crate | In root | Directly | Yes |
Main crate | Any | Any | Yes |
I have an example crate here which reproduces the issue:
$ git clone https://github.com/koute/rust-custom-section-issue
$ cd rust-custom-section-issue
# This will not generate a custom section:
$ cargo build --target=wasm32-unknown-unknown --release --features broken
$ wasm-objdump -s target/wasm32-unknown-unknown/release/rust_custom_section_issue.wasm
# This will:
$ cargo build --target=wasm32-unknown-unknown --release --features working
$ wasm-objdump -s target/wasm32-unknown-unknown/release/rust_custom_section_issue.wasm
I'm using the most recent nightly: rustc 1.32.0-nightly (4a45578bc 2018-12-07)
Could we make this somewhat consistent?
Some background: as a first step towards wasm-bindgen
compatibility I'm converting stdweb
's js!
macro to use custom sections, however to make it not break existing downstream users I need to have either a) every custom section in the whole crate graph be generated, or b) always generated if the custom section is defined inside of a potentially reachable (at runtime) function. Otherwise I end up generating an import for a snippet for which the corresponding custom section entry doesn't exist.