-
Notifications
You must be signed in to change notification settings - Fork 207
Description
In this repo, I've shown two scenarios where code that is functionally identical produces very different WASM binaries.
Setup
The two scenarios I'm testing are for a rust cdylib
whose code looks like this:
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
#[export_name = "fallible_func"]
pub extern "C" fn fallible_func(val: i32) -> i32 {
unsafe { Fallible_func(val) }
}
#[cfg(feature = "print")]
#[export_name = "print"]
pub extern "C" fn print(str: *const i8) {
unsafe {
// Call the FFI Print function with the a pointer to the C string `cstr`.
Print(str as *mut i8);
};
}
Importantly, the print
function is guarded by the print
feature that is off by default.
The c code we're binding looks like this:
#include <stdio.h>
#include <assert.h>
int Fallible_func(int value)
{
assert(value > 0);
return value;
}
void Print(char *str)
{
printf("%s\n", str);
}
If we run the cargo build
with NO_PRINTF=1
, then the c code instead looks like this:
#include <stdio.h>
#include <assert.h>
int Fallible_func(int value)
{
assert(value > 0);
return value;
}
void Print(char *str)
{
// printf("%s\n", str);
}
Scenario 1:
Note: This is all imports and exports.
(import "wasi_snapshot_preview1" "fd_close" (func $__imported_wasi_snapshot_preview1_fd_close (;0;) (type 2)))
(import "wasi_snapshot_preview1" "fd_fdstat_get" (func $__imported_wasi_snapshot_preview1_fd_fdstat_get (;1;) (type 3)))
(import "wasi_snapshot_preview1" "fd_seek" (func $__imported_wasi_snapshot_preview1_fd_seek (;2;) (type 4)))
(import "wasi_snapshot_preview1" "fd_write" (func $__imported_wasi_snapshot_preview1_fd_write (;3;) (type 5)))
(export "memory" (memory 0))
(export "fallible_func" (func $fallible_func.command_export))
WASM binary size: 2.4K
Scenario 2: NO_PRINTF=1
Note: This is all imports and exports. No imports at all here.
(export "memory" (memory 0))
(export "fallible_func" (func $fallible_func.command_export))
WASM binary size: 459B
Conclusion
This might be totally expected given the rust compilation pipeline and the way wasi-libc
is authored and structured, but is quite surprising to me.
I was expecting that link-time optimizations would be 'smart' enough to notice that printf
was not referenced by any exported functions in the rust library and recursively pruned. I've put together the minimal repro in hopes that it helps illustrate the observations in a reproducible way and could be helpful if this behaviour is not as intended.