This commit is contained in:
Alex Crichton
2018-02-05 16:39:11 -08:00
parent 8f8da49dab
commit 0320bc0d7c
5 changed files with 163 additions and 19 deletions

View File

@ -26,6 +26,9 @@ impl<'a> Js<'a> {
for s in self.program.structs.iter() {
self.generate_struct(s);
}
for s in self.program.imported_structs.iter() {
self.generate_import_struct(s);
}
{
let mut bind = |name: &str, f: &Fn(&mut Self) -> String| {
@ -467,15 +470,56 @@ impl<'a> Js<'a> {
}
pub fn generate_import(&mut self, module: &str, import: &shared::Function) {
let mut dst = String::new();
let imported_name = format!("import{}", self.imports.len());
self.imports.push_str(&format!("
import {{ {} as {} }} from '{}';
", import.name, imported_name, module));
dst.push_str(&format!("function __wbg_import_{}(", import.name));
self.gen_import_shim(&import.mangled_import_name(None),
&imported_name,
import)
}
pub fn generate_import_struct(&mut self, import: &shared::ImportStruct) {
if let Some(ref module) = import.module {
self.imports.push_str(&format!("
import {{ {} }} from '{}';
", import.name, module));
}
for &(method, ref function) in import.functions.iter() {
self.generate_import_struct_function(&import.name,
method,
function);
}
}
fn generate_import_struct_function(
&mut self,
class: &str,
is_method: bool,
function: &shared::Function,
) {
let delegate = if is_method {
format!("{}.prototype.{}.call", class, function.name)
} else {
format!("{}.{}", class, function.name)
};
self.gen_import_shim(&function.mangled_import_name(Some(class)),
&delegate,
function)
}
fn gen_import_shim(
&mut self,
shim_name: &str,
shim_delegate: &str,
import: &shared::Function,
) {
let mut dst = String::new();
dst.push_str(&format!("function {}(", shim_name));
let mut invocation = String::new();
for (i, arg) in import.arguments.iter().enumerate() {
@ -518,7 +562,7 @@ impl<'a> Js<'a> {
}
}
dst.push_str(")");
let invoc = format!("{}({})", imported_name, invocation);
let invoc = format!("{}({})", shim_delegate, invocation);
let invoc = match import.ret {
Some(shared::Type::Number) => invoc,
Some(shared::Type::Boolean) => format!("{} ? 1 : 0", invoc),
@ -571,12 +615,16 @@ impl<'a> Js<'a> {
// fixed upstream.
let program_import = self.program.imports
.iter()
.find(|&&(_, ref f)| f.name == import.field());
if program_import.is_some() {
.any(|&(_, ref f)| f.mangled_import_name(None) == import.field());
let struct_import = self.program.imported_structs
.iter()
.flat_map(|s| s.functions.iter().map(move |f| (s, &f.1)))
.any(|(s, f)| f.mangled_import_name(Some(&s.name)) == import.field());
if program_import || struct_import {
import.module_mut().truncate(0);
import.module_mut().push_str("./");
import.module_mut().push_str(module_name);
import.field_mut().insert_str(0, "__wbg_import_");
continue
}
}
}

View File

@ -256,7 +256,7 @@ impl Function {
syn::Ident::from(generated_name)
}
fn shared(&self) -> shared::Function {
pub fn shared(&self) -> shared::Function {
shared::Function {
name: self.name.as_ref().to_string(),
arguments: self.arguments.iter().map(|t| t.shared()).collect(),

View File

@ -429,10 +429,9 @@ impl ToTokens for Receiver {
}
fn bindgen_import(import: &ast::Import, tokens: &mut Tokens) {
bindgen_import_function(&import.function,
&import.function.ident.to_string(),
Some(&import.module),
tokens);
let import_name = import.function.wasm_function.shared()
.mangled_import_name(None);
bindgen_import_function(&import.function, &import_name, tokens);
}
fn bindgen_imported_struct(import: &ast::ImportStruct, tokens: &mut Tokens) {
@ -446,12 +445,9 @@ fn bindgen_imported_struct(import: &ast::ImportStruct, tokens: &mut Tokens) {
let mut methods = Tokens::new();
for &(_is_method, ref f) in import.functions.iter() {
let import_name = format!("__wbg_{}_{}", name, f.ident);
bindgen_import_function(f,
&import_name,
import.module.as_ref().map(|s| &**s),
&mut methods);
let import_name = f.wasm_function.shared()
.mangled_import_name(Some(&import.name.to_string()));
bindgen_import_function(f, &import_name, &mut methods);
}
(my_quote! {
@ -463,7 +459,6 @@ fn bindgen_imported_struct(import: &ast::ImportStruct, tokens: &mut Tokens) {
fn bindgen_import_function(import: &ast::ImportFunction,
import_name: &str,
_import_module: Option<&str>,
tokens: &mut Tokens) {
let vis = &import.rust_vis;
let ret = &import.rust_decl.output;

View File

@ -61,6 +61,13 @@ impl Function {
name.push_str(&self.name);
return name
}
pub fn mangled_import_name(&self, struct_: Option<&str>) -> String {
match struct_ {
Some(s) => format!("__wbg_s_{}_{}", s, self.name),
None => format!("__wbg_f_{}", self.name),
}
}
}
#[derive(Serialize, Deserialize)]