├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── README.md ├── run.js └── src └── main.rs /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | /target/ 3 | **/*.rs.bk 4 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "dtoa" 3 | version = "0.4.2" 4 | source = "registry+https://github.com/rust-lang/crates.io-index" 5 | 6 | [[package]] 7 | name = "itoa" 8 | version = "0.3.4" 9 | source = "registry+https://github.com/rust-lang/crates.io-index" 10 | 11 | [[package]] 12 | name = "num-traits" 13 | version = "0.1.40" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | 16 | [[package]] 17 | name = "quote" 18 | version = "0.3.15" 19 | source = "registry+https://github.com/rust-lang/crates.io-index" 20 | 21 | [[package]] 22 | name = "rust-wasm" 23 | version = "0.1.0" 24 | dependencies = [ 25 | "serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", 26 | "serde_derive 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", 27 | "serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 28 | ] 29 | 30 | [[package]] 31 | name = "serde" 32 | version = "1.0.21" 33 | source = "registry+https://github.com/rust-lang/crates.io-index" 34 | 35 | [[package]] 36 | name = "serde_derive" 37 | version = "1.0.21" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | dependencies = [ 40 | "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 41 | "serde_derive_internals 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", 42 | "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", 43 | ] 44 | 45 | [[package]] 46 | name = "serde_derive_internals" 47 | version = "0.17.0" 48 | source = "registry+https://github.com/rust-lang/crates.io-index" 49 | dependencies = [ 50 | "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", 51 | "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", 52 | ] 53 | 54 | [[package]] 55 | name = "serde_json" 56 | version = "1.0.6" 57 | source = "registry+https://github.com/rust-lang/crates.io-index" 58 | dependencies = [ 59 | "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 60 | "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 61 | "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", 62 | "serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", 63 | ] 64 | 65 | [[package]] 66 | name = "syn" 67 | version = "0.11.11" 68 | source = "registry+https://github.com/rust-lang/crates.io-index" 69 | dependencies = [ 70 | "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 71 | "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", 72 | "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 73 | ] 74 | 75 | [[package]] 76 | name = "synom" 77 | version = "0.11.3" 78 | source = "registry+https://github.com/rust-lang/crates.io-index" 79 | dependencies = [ 80 | "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 81 | ] 82 | 83 | [[package]] 84 | name = "unicode-xid" 85 | version = "0.0.4" 86 | source = "registry+https://github.com/rust-lang/crates.io-index" 87 | 88 | [metadata] 89 | "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" 90 | "checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" 91 | "checksum num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "99843c856d68d8b4313b03a17e33c4bb42ae8f6610ea81b28abe076ac721b9b0" 92 | "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" 93 | "checksum serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6eda663e865517ee783b0891a3f6eb3a253e0b0dabb46418969ee9635beadd9e" 94 | "checksum serde_derive 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)" = "652bc323d694dc925829725ec6c890156d8e70ae5202919869cb00fe2eff3788" 95 | "checksum serde_derive_internals 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "32f1926285523b2db55df263d2aa4eb69ddcfa7a7eade6430323637866b513ab" 96 | "checksum serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e4586746d1974a030c48919731ecffd0ed28d0c40749d0d18d43b3a7d6c9b20e" 97 | "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" 98 | "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" 99 | "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" 100 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust-wasm" 3 | version = "0.1.0" 4 | authors = ["Hidekazu Kobayashi "] 5 | 6 | [dependencies] 7 | serde_derive = "^1.0.21" 8 | serde = "^1.0.21" 9 | serde_json = "^1.0.6" 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rust-wasm 2 | 3 | Use rustc >= 1.23.0-nightly(2017-11-25). 4 | 5 | ``` 6 | cargo build --release --target wasm32-unknown-unknown 7 | node --expose-wasm run.js 8 | ``` 9 | -------------------------------------------------------------------------------- /run.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | 3 | const wasm = fs.readFileSync('./target/wasm32-unknown-unknown/release/rust-wasm.wasm'); 4 | const mod = new WebAssembly.Instance(new WebAssembly.Module(wasm)); 5 | const heap = new Uint8Array(mod.exports.memory.buffer); 6 | 7 | function allocStr(mem, str) { 8 | const buf = Buffer.from(str); 9 | const ptr = mod.exports.alloc(buf.length + 1); 10 | heap.set(buf, ptr); 11 | heap[buf.length] = 0; // write null byte 12 | return ptr; 13 | } 14 | 15 | function copyCStr(mem, ptr) { 16 | let end = ptr; 17 | while (mem[end] !== 0) { 18 | end++; 19 | } 20 | 21 | return Buffer.from(mem.buffer, ptr, end-ptr).toString(); 22 | } 23 | 24 | const person = { 25 | firstName: 'foo', 26 | lastName: 'bar', 27 | }; 28 | const personJson = JSON.stringify(person); 29 | const personPtr = allocStr(heap, personJson); 30 | const greetingPtr = mod.exports.hello(personPtr); 31 | mod.exports.dealloc(personPtr); 32 | const greetingJson = copyCStr(heap, greetingPtr); 33 | mod.exports.dealloc(greetingPtr); 34 | const { message } = JSON.parse(greetingJson); 35 | console.log(message); 36 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use std::mem; 2 | use std::ffi::{CString, CStr}; 3 | use std::os::raw::{c_char, c_void}; 4 | 5 | #[macro_use] 6 | extern crate serde_derive; 7 | extern crate serde; 8 | extern crate serde_json; 9 | 10 | fn main() {} 11 | 12 | #[no_mangle] 13 | pub fn alloc(size: usize) -> *mut c_void { 14 | let mut buf = Vec::with_capacity(size); 15 | let ptr = buf.as_mut_ptr(); 16 | mem::forget(buf); 17 | return ptr as *mut c_void; 18 | } 19 | 20 | #[no_mangle] 21 | pub fn dealloc(ptr: *mut c_void, cap: usize) { 22 | unsafe { 23 | let _buf = Vec::from_raw_parts(ptr, 0, cap); 24 | } 25 | } 26 | 27 | #[derive(Deserialize)] 28 | #[serde(rename_all = "camelCase")] 29 | struct Person { 30 | first_name: String, 31 | last_name: String, 32 | } 33 | 34 | #[derive(Serialize)] 35 | #[serde(rename_all = "camelCase")] 36 | struct Greeting { 37 | message: String, 38 | } 39 | 40 | #[no_mangle] 41 | pub fn hello(input_ptr: *mut c_char) -> *mut c_char { 42 | let input = unsafe { 43 | CStr::from_ptr(input_ptr) 44 | }.to_str().unwrap(); 45 | let person: Person = serde_json::from_str(input).unwrap(); 46 | let message = format!( 47 | "Hello, {} {}! Welcome to Rust World!!", 48 | person.first_name, 49 | person.last_name 50 | ); 51 | let greeting = Greeting { message }; 52 | let res = serde_json::to_string(&greeting).unwrap(); 53 | let c_str = CString::new(res).unwrap(); 54 | c_str.into_raw() 55 | } 56 | --------------------------------------------------------------------------------