Lets create wasm module with to_uppercase function.
Our goal is to send the string from JavaScript to Rust , process the string in Rust and send back to JavaScript .
<!DOCTYPE html>
<html lang= "en" >
<head>
<meta charset= "utf-8" >
<title> WebAssembly</title>
<script src= "bundle.js" ></script>
<script src= "script.js" ></script>
</head>
<body>
<input id= "a" >
<output id= "b" ></output>
</body>
</html>
window . onload = function () {
window . exports = {};
let a = document . querySelector ( ' #a ' ),
b = document . querySelector ( ' #b ' );
fetchAndInstantiate ( ' build/main.wasm ' )
. then ( mod => {
exports = mod . exports ;
let to_uppercase = s => {
let outptr = exports . to_uppercase ( newString ( exports , s ));
return copyCStr ( exports , outptr );
};
a . oninput = () =>
b . value = to_uppercase ( a . value );
});
};
use std :: mem ;
use std :: ffi :: CString ;
use std :: os :: raw ::{ c_char , c_void };
#[no_mangle]
pub extern "C" fn alloc ( size : usize ) -> * mut c_void {
let mut buf = Vec :: with_capacity ( size );
let ptr = buf .as_mut_ptr ();
mem :: forget ( buf );
return ptr as * mut c_void ;
}
#[no_mangle]
pub extern "C" fn dealloc_str ( ptr : * mut c_char ) {
unsafe {
let _ = CString :: from_raw ( ptr );
}
}
#[no_mangle]
pub fn to_uppercase ( ptr : * mut c_char ) -> * mut c_char {
let mut s : String ;
unsafe {
s = CString :: from_raw ( ptr ) .into_string () .unwrap ();
}
s = s .to_uppercase ();
let c_string = CString :: new ( s ) .unwrap ();
c_string .into_raw ()
}
Save
this file as
main.wasm in
build folder.
Or generate this file by
rustc +nightly --target wasm32-unknown-unknown -O --crate-type=cdylib src\main.rs -o build\main.big.wasm
We need to encode the string, allocate some space in the exported memory buffer and copy over the string for sending the string from JavaScript to Rust.
On return of the Rust function, we decode the new string from the memory buffer.
The helper functions are defined in
bundle.js .