mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-04-02 02:11:06 +00:00
Merge pull request #77 from dflemstr/wasm-construct-js-class
Add support for constructing JsValue instances generically
This commit is contained in:
commit
bb2e0c205f
@ -88,6 +88,7 @@ impl ToTokens for ast::Program {
|
|||||||
impl ToTokens for ast::Struct {
|
impl ToTokens for ast::Struct {
|
||||||
fn to_tokens(&self, tokens: &mut Tokens) {
|
fn to_tokens(&self, tokens: &mut Tokens) {
|
||||||
let name = &self.name;
|
let name = &self.name;
|
||||||
|
let new_fn = syn::Ident::from(shared::new_function(self.name.as_ref()));
|
||||||
let free_fn = syn::Ident::from(shared::free_function(self.name.as_ref()));
|
let free_fn = syn::Ident::from(shared::free_function(self.name.as_ref()));
|
||||||
let c = shared::name_to_descriptor(name.as_ref());
|
let c = shared::name_to_descriptor(name.as_ref());
|
||||||
let descriptor = Literal::byte_string(format!("{:4}", c).as_bytes());
|
let descriptor = Literal::byte_string(format!("{:4}", c).as_bytes());
|
||||||
@ -153,6 +154,28 @@ impl ToTokens for ast::Struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ::std::convert::From<#name> for ::wasm_bindgen::JsValue {
|
||||||
|
fn from(value: #name) -> Self {
|
||||||
|
let ptr = ::wasm_bindgen::convert::WasmBoundary::into_abi(
|
||||||
|
value,
|
||||||
|
unsafe { &mut ::wasm_bindgen::convert::GlobalStack::new() },
|
||||||
|
);
|
||||||
|
|
||||||
|
#[wasm_import_module = "__wbindgen_placeholder__"]
|
||||||
|
extern {
|
||||||
|
fn #new_fn(ptr: u32) -> u32;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
<::wasm_bindgen::JsValue as ::wasm_bindgen::convert::WasmBoundary>
|
||||||
|
::from_abi(
|
||||||
|
#new_fn(ptr),
|
||||||
|
unsafe { &mut ::wasm_bindgen::convert::GlobalStack::new() },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern fn #free_fn(ptr: u32) {
|
pub unsafe extern fn #free_fn(ptr: u32) {
|
||||||
<#name as ::wasm_bindgen::convert::WasmBoundary>::from_abi(
|
<#name as ::wasm_bindgen::convert::WasmBoundary>::from_abi(
|
||||||
|
@ -266,6 +266,15 @@ impl<'a> Context<'a> {
|
|||||||
}}
|
}}
|
||||||
"));
|
"));
|
||||||
ts_dst.push_str("constructor(ptr: number, sym: Symbol);\n");
|
ts_dst.push_str("constructor(ptr: number, sym: Symbol);\n");
|
||||||
|
|
||||||
|
let new_name = shared::new_function(&class);
|
||||||
|
if self.wasm_import_needed(&new_name) {
|
||||||
|
self.globals.push_str(&format!("
|
||||||
|
export function {new_name}(ptr) {{
|
||||||
|
return addHeapObject(new {class}(ptr, token));
|
||||||
|
}}
|
||||||
|
", new_name = new_name, class = class));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
dst.push_str(&format!("
|
dst.push_str(&format!("
|
||||||
constructor(ptr) {{
|
constructor(ptr) {{
|
||||||
@ -273,6 +282,15 @@ impl<'a> Context<'a> {
|
|||||||
}}
|
}}
|
||||||
"));
|
"));
|
||||||
ts_dst.push_str("constructor(ptr: number);\n");
|
ts_dst.push_str("constructor(ptr: number);\n");
|
||||||
|
|
||||||
|
let new_name = shared::new_function(&class);
|
||||||
|
if self.wasm_import_needed(&new_name) {
|
||||||
|
self.globals.push_str(&format!("
|
||||||
|
export function {new_name}(ptr) {{
|
||||||
|
return addHeapObject(new {class}(ptr));
|
||||||
|
}}
|
||||||
|
", new_name = new_name, class = class));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dst.push_str(&format!("
|
dst.push_str(&format!("
|
||||||
|
@ -88,6 +88,15 @@ pub struct CustomTypeName {
|
|||||||
pub name: String,
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_function(struct_name: &str) -> String {
|
||||||
|
let mut name = format!("__wbg_");
|
||||||
|
name.extend(struct_name
|
||||||
|
.chars()
|
||||||
|
.flat_map(|s| s.to_lowercase()));
|
||||||
|
name.push_str("_new");
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
|
||||||
pub fn free_function(struct_name: &str) -> String {
|
pub fn free_function(struct_name: &str) -> String {
|
||||||
let mut name = format!("__wbg_");
|
let mut name = format!("__wbg_");
|
||||||
name.extend(struct_name
|
name.extend(struct_name
|
||||||
|
@ -95,7 +95,7 @@ impl JsValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// #[doc(hidden)]
|
// #[doc(hidden)]
|
||||||
// pub fn __from_idx(idx: u32) -> JsValue {
|
// pub unsafe fn __from_idx(idx: u32) -> JsValue {
|
||||||
// JsValue { idx }
|
// JsValue { idx }
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
|
@ -4,7 +4,7 @@ extern crate test_support;
|
|||||||
fn simple() {
|
fn simple() {
|
||||||
test_support::project()
|
test_support::project()
|
||||||
.file("src/lib.rs", r#"
|
.file("src/lib.rs", r#"
|
||||||
#![feature(proc_macro, wasm_custom_section)]
|
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
|
||||||
|
|
||||||
extern crate wasm_bindgen;
|
extern crate wasm_bindgen;
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ fn simple() {
|
|||||||
fn strings() {
|
fn strings() {
|
||||||
test_support::project()
|
test_support::project()
|
||||||
.file("src/lib.rs", r#"
|
.file("src/lib.rs", r#"
|
||||||
#![feature(proc_macro, wasm_custom_section)]
|
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
|
||||||
|
|
||||||
extern crate wasm_bindgen;
|
extern crate wasm_bindgen;
|
||||||
|
|
||||||
@ -114,7 +114,7 @@ fn strings() {
|
|||||||
fn exceptions() {
|
fn exceptions() {
|
||||||
test_support::project()
|
test_support::project()
|
||||||
.file("src/lib.rs", r#"
|
.file("src/lib.rs", r#"
|
||||||
#![feature(proc_macro, wasm_custom_section)]
|
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
|
||||||
|
|
||||||
extern crate wasm_bindgen;
|
extern crate wasm_bindgen;
|
||||||
|
|
||||||
@ -179,7 +179,7 @@ fn exceptions() {
|
|||||||
fn pass_one_to_another() {
|
fn pass_one_to_another() {
|
||||||
test_support::project()
|
test_support::project()
|
||||||
.file("src/lib.rs", r#"
|
.file("src/lib.rs", r#"
|
||||||
#![feature(proc_macro, wasm_custom_section)]
|
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
|
||||||
|
|
||||||
extern crate wasm_bindgen;
|
extern crate wasm_bindgen;
|
||||||
|
|
||||||
@ -276,7 +276,7 @@ fn pass_into_js() {
|
|||||||
fn issue_27() {
|
fn issue_27() {
|
||||||
test_support::project()
|
test_support::project()
|
||||||
.file("src/lib.rs", r#"
|
.file("src/lib.rs", r#"
|
||||||
#![feature(proc_macro, wasm_custom_section)]
|
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
|
||||||
|
|
||||||
extern crate wasm_bindgen;
|
extern crate wasm_bindgen;
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
@ -314,3 +314,50 @@ fn issue_27() {
|
|||||||
"#)
|
"#)
|
||||||
.test();
|
.test();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pass_into_js_as_js_class() {
|
||||||
|
test_support::project()
|
||||||
|
.file("src/lib.rs", r#"
|
||||||
|
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
|
||||||
|
|
||||||
|
extern crate wasm_bindgen;
|
||||||
|
|
||||||
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub struct Foo(i32);
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
impl Foo {
|
||||||
|
pub fn inner(&self) -> i32 {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen(module = "./test")]
|
||||||
|
extern {
|
||||||
|
fn take_foo(foo: JsValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn run() {
|
||||||
|
take_foo(Foo(13).into());
|
||||||
|
}
|
||||||
|
"#)
|
||||||
|
.file("test.ts", r#"
|
||||||
|
import { run, Foo } from "./out";
|
||||||
|
import * as assert from "assert";
|
||||||
|
|
||||||
|
export function take_foo(foo: any) {
|
||||||
|
assert(foo instanceof Foo);
|
||||||
|
assert.strictEqual(foo.inner(), 13);
|
||||||
|
foo.free();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function test() {
|
||||||
|
run();
|
||||||
|
}
|
||||||
|
"#)
|
||||||
|
.test();
|
||||||
|
}
|
||||||
|
@ -6,7 +6,7 @@ fn dependencies_work() {
|
|||||||
.file(
|
.file(
|
||||||
"src/lib.rs",
|
"src/lib.rs",
|
||||||
r#"
|
r#"
|
||||||
#![feature(proc_macro, wasm_custom_section)]
|
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
|
||||||
extern crate wasm_bindgen;
|
extern crate wasm_bindgen;
|
||||||
extern crate dependency;
|
extern crate dependency;
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
@ -51,7 +51,7 @@ fn dependencies_work() {
|
|||||||
.file(
|
.file(
|
||||||
"vendor/dependency/src/lib.rs",
|
"vendor/dependency/src/lib.rs",
|
||||||
r#"
|
r#"
|
||||||
#![feature(proc_macro, wasm_custom_section)]
|
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
|
||||||
extern crate wasm_bindgen;
|
extern crate wasm_bindgen;
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ fn works() {
|
|||||||
test_support::project()
|
test_support::project()
|
||||||
.debug(false)
|
.debug(false)
|
||||||
.file("src/lib.rs", r#"
|
.file("src/lib.rs", r#"
|
||||||
#![feature(proc_macro, wasm_custom_section)]
|
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
|
||||||
|
|
||||||
extern crate wasm_bindgen;
|
extern crate wasm_bindgen;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user