Description
I've ran into an issue with one of my libraries that was preventing it from compiling with wasm-pack
. It would otherwise compile just fine with rustc
to other targets (no compiler errors) but when I would attempt to compile with wasm-pack
I would get this cryptic error:
LLVM ERROR: Function addresses with offsets not supported
error: could not compile `hello-wasm`.
No line numbers, no error trace, just that.
After spending quite a while to find the offending block of code, I've discovered that the issue was caused by misusing the type system a bit.
Here's the offending code:
use wasm_bindgen::prelude::*;
use std::vec::Vec;
#[wasm_bindgen]
pub fn err() -> i32 {
let vector: Vec<u8> = Vec::new();
// In my library, I meant to use `core::u16::MAX` and did this instead
let my_size = (u16::max as usize) - 1; // <- casting function as usize
// `u16::max` is actually a function to compare two numbers and get the maximum between them
if my_size > vector.len() {
20
} else {
50
}
}
I expected to see this happen: I think this is actually a type error. u16::max
is a function and I'm casting it to a usize
. I would hope the Rust compiler would yell at me for that or at least require me to write unsafe
before I can cast a function to a usize
.
Instead, this happened: The program compiles and runs just fine unless you attempt to compile it to wasm with wasm-pack build
. If you run the function in a test, it spits out 20
.
rustc --version --verbose
:
rustc 1.47.0 (18bf6b4f0 2020-10-07)
binary: rustc
commit-hash: 18bf6b4f01a6feaf7259ba7cdae58031af1b7b39
commit-date: 2020-10-07
host: x86_64-apple-darwin
release: 1.47.0
LLVM version: 11.0
wasm-pack -V
:
wasm-pack 0.9.1
Hoping to save someone else a few days of hair pulling!
Edit: A little bit more testing, it looks like the program compiles just fine if you change the line to this:
// let my_size = (u16::max as usize) - 1;
let my_size = (u16::max as usize)
So it seems like combining the cast with an operation causes the issue. Interestingly, not all operations cause the error.
// Doesn't compile with `wasm-pack`
let my_size = (u16::max as usize) + 1;
let my_size = (u16::max as usize) - 1;
let my_size = (u16::max as usize) + 2;
let my_size = (u16::max as usize) - 2;
// Compiles Fine with `wasm-pack`:
let my_size = (u16::max as usize) * 1;
let my_size = (u16::max as usize) / 1;
let my_size = (u16::max as usize) * 2;
let my_size = (u16::max as usize) / 2;