简体   繁体   中英

Will private functions be included when I compile a rust project to WASM?

If I have a lib.rs file and I'm using a function from a module in the mod.rs file, and that function uses another function within the mod.rs file but isn't made public to lib.rs. Thus is inaccessible to the lib.rs.

What happens if I publish my project to the web? Which files are made public? I'm assuming the whole mod.rs is still accessible since the website still needs to use function from the mod.rs, or will it only load in the public functions from mod.rs?

Note: I am not at all familiar with releasing projects to the actual web. So it also plays a big role in not seeing how it all works. I'm using WASM (with JS) to compile certain functions.

It's not exactly clear what you mean, as there are two aspects here:

  1. Yes, if you access a private function from a public function (including via indirections, nested calls, modules, etc.), the code of the private function will be included in the final executable. This is obviously true, as the public function simply would not work without the code from the private function...

  2. No, if a symbol is not explicitly marked pub (or #[used] ) and reachable from the crate's top level the compiler and linker are free to remove the symbol if they so choose. This means a private function is most likely not included in your final wasm module as a visible symbol, and you should not assume that they are. The private function's code might be included due to the above, but it is not possible to call the private function directly from the outside.

It is not trivial to tell in advance if the compiler and/or linker will not include a function as a visible symbol. The symbol might be included if you are compiling in debug -mode, simply because the compiler and/or linker do not do the necessary work to prove that the symbol does not need to be included. Also, using link-time-optimization might be required to do that, which you may simply not use. Yet in any case, unless the symbol is explicitly marked pub (or #[used ; and even then the linker might decide to work against you), you can't assume the symbol to be publicly visible.

For example:

mod r#mod {
    #[inline(never)]
    fn private(i: i32) -> i32 {
        i + 1
    }

    #[inline(never)]
    pub fn public(i: i32) -> i32 {
        private(i) + 1
    }
}

pub fn public(i: i32) -> i32 {
    r#mod::public(i) + 1
}

Here, the IR generates three symbols:

; playground::mod::private
define internal fastcc i32 @_ZN10playground3mod7private17h0fb30f481d7b59dcE(i32 %i) unnamed_addr #0 {
start:
  %0 = add i32 %i, 1
  ret i32 %0
}

; playground::mod::public
define internal fastcc i32 @_ZN10playground3mod6public17h771c0f8fe9a648a0E(i32 %i) unnamed_addr #0 {
start:
; call playground::mod::private
  %_2 = tail call fastcc i32 @_ZN10playground3mod7private17h0fb30f481d7b59dcE(i32 %i)
  %0 = add i32 %_2, 1
  ret i32 %0
}

; playground::public
define i32 @_ZN10playground6public17h7abee63a81dd5c88E(i32 %i) unnamed_addr #1 {
start:
; call playground::mod::public
  %_2 = tail call fastcc i32 @_ZN10playground3mod6public17h771c0f8fe9a648a0E(i32 %i)
  %0 = add i32 %_2, 1
  ret i32 %0
}

As you can see, the IR will produce two symbols that are explicitly marked internal - mod::private and mod::public , even though mod::public is pub , but it is inside a private module! - and only public is not internal and will become publicly visible in the final executable.

Yes, The code will be available.

Just make sure to use these access specifiers used correctly or it will get hard to call a private function even if it is loaded in the WASM.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM