Fix symbol conflicts defined in two crates (#496)

Not a lot of attention has been paid to dealing with conflicts of symbols
between crates and different `#[wasm_bindgen]` blocks. This commit starts to fix
this issue by unblocking #486 which first ran into this. Currently there's a bug
where if two independent crates bind the same JS API they'll generate the same
symbol which causes conflicts for things like LTO or linking in general.

This commit starts to add a "salt" to all symbols generated by `wasm-bindgen`
(these are all transparent to the user) to ensure that each crate's invocations
are kept apart from one another and using the correct bindings.
This commit is contained in:
Alex Crichton
2018-07-17 18:24:48 -05:00
committed by GitHub
parent 9218c40613
commit bf64f74cab
4 changed files with 167 additions and 32 deletions

View File

@ -1,6 +1,4 @@
use std::borrow::Cow;
use std::collections::HashSet;
use std::env;
use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
use ast;
@ -9,24 +7,7 @@ use quote::ToTokens;
use serde_json;
use shared;
use syn;
fn to_ident_name(s: &str) -> Cow<str> {
if s.chars().all(|c| match c {
'a'...'z' | 'A'...'Z' | '0'...'9' | '_' => true,
_ => false,
}) {
return Cow::from(s);
}
Cow::from(
s.chars()
.map(|c| match c {
'a'...'z' | 'A'...'Z' | '0'...'9' | '_' => c,
_ => '_',
})
.collect::<String>(),
)
}
use util::ShortHash;
impl ToTokens for ast::Program {
// Generate wrappers for all the items that we've found
@ -72,15 +53,9 @@ impl ToTokens for ast::Program {
static CNT: AtomicUsize = ATOMIC_USIZE_INIT;
let crate_name = env::var("CARGO_PKG_NAME").expect("should have CARGO_PKG_NAME env var");
let crate_vers =
env::var("CARGO_PKG_VERSION").expect("should have CARGO_PKG_VERSION env var");
let generated_static_name = format!(
"__WASM_BINDGEN_GENERATED_{}_{}_{}",
to_ident_name(&crate_name),
to_ident_name(&crate_vers),
CNT.fetch_add(1, Ordering::SeqCst)
"__WASM_BINDGEN_GENERATED_{}",
ShortHash(CNT.fetch_add(1, Ordering::SeqCst)),
);
let generated_static_name = Ident::new(&generated_static_name, Span::call_site());