- 
                Notifications
    You must be signed in to change notification settings 
- Fork 13.9k
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.