mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-03-16 02:00:51 +00:00
more-wip
This commit is contained in:
parent
8f8da49dab
commit
0320bc0d7c
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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(),
|
||||
|
@ -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;
|
||||
|
@ -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)]
|
||||
|
@ -13,18 +13,112 @@ fn simple() {
|
||||
wasm_bindgen! {
|
||||
extern struct Math {
|
||||
fn random() -> f64;
|
||||
fn log(a: f64) -> f64;
|
||||
}
|
||||
|
||||
pub fn get_random() -> f64 {
|
||||
Math::random()
|
||||
}
|
||||
|
||||
pub fn do_log(a: f64) -> f64 {
|
||||
Math::log(a)
|
||||
}
|
||||
}
|
||||
"#)
|
||||
.file("test.ts", r#"
|
||||
import * as wasm from "./out";
|
||||
import * as assert from "assert";
|
||||
|
||||
export function test() {
|
||||
wasm.get_random();
|
||||
assert.strictEqual(wasm.do_log(1.0), Math.log(1.0));
|
||||
}
|
||||
"#)
|
||||
.test();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn import_class() {
|
||||
test_support::project()
|
||||
.file("src/lib.rs", r#"
|
||||
#![feature(proc_macro)]
|
||||
|
||||
extern crate wasm_bindgen;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
wasm_bindgen! {
|
||||
#[wasm_module = "./test"]
|
||||
extern struct Foo {
|
||||
fn bar();
|
||||
}
|
||||
|
||||
pub fn bar() {
|
||||
Foo::bar();
|
||||
}
|
||||
}
|
||||
"#)
|
||||
.file("test.ts", r#"
|
||||
import * as wasm from "./out";
|
||||
import * as assert from "assert";
|
||||
|
||||
let called = false;
|
||||
|
||||
export class Foo {
|
||||
static bar() {
|
||||
called = true;
|
||||
}
|
||||
}
|
||||
|
||||
export function test() {
|
||||
wasm.bar();
|
||||
assert.strictEqual(called, true);
|
||||
}
|
||||
"#)
|
||||
.test();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn construct() {
|
||||
test_support::project()
|
||||
.file("src/lib.rs", r#"
|
||||
#![feature(proc_macro)]
|
||||
|
||||
extern crate wasm_bindgen;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
wasm_bindgen! {
|
||||
#[wasm_module = "./test"]
|
||||
extern struct Foo {
|
||||
fn create() -> Foo;
|
||||
fn doit(&self);
|
||||
}
|
||||
|
||||
pub fn bar() {
|
||||
let foo = Foo::bar();
|
||||
}
|
||||
}
|
||||
"#)
|
||||
.file("test.ts", r#"
|
||||
import * as wasm from "./out";
|
||||
import * as assert from "assert";
|
||||
|
||||
let called = false;
|
||||
|
||||
export class Foo {
|
||||
static create() {
|
||||
return new Foo();
|
||||
}
|
||||
|
||||
doit() {
|
||||
called = true;
|
||||
}
|
||||
}
|
||||
|
||||
export function test() {
|
||||
wasm.bar();
|
||||
assert.strictEqual(called, true);
|
||||
}
|
||||
"#)
|
||||
.test();
|
||||
|
Loading…
x
Reference in New Issue
Block a user