Skip to content

Commit

Permalink
Merge pull request #1 from MarkMcCaskey/master
Browse files Browse the repository at this point in the history
Add Rust-focused updates and clean up
  • Loading branch information
torch2424 authored Oct 29, 2019
2 parents 9f54155 + 09fb485 commit 877497f
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 43 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
# Generated by Cargo
# will have compiled files and executables
**/target/
**/**/target/

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

// Import the standard string library
use std::str;

Expand All @@ -13,7 +12,8 @@ static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;

// Create a static mutable byte buffer.
// We will use for passing memory between our host and wasm.
// NOTE: global `static mut` means we will have "unsafe" code
// NOTE: global `static mut` means we have to access it with unsafe
// and manually ensure that only one mutable reference exists to it at a time
// but for passing memory between a host and wasm should be fine.
const WASM_MEMORY_BUFFER_SIZE: usize = 1024;
static mut WASM_MEMORY_BUFFER: [u8; WASM_MEMORY_BUFFER_SIZE] = [0; WASM_MEMORY_BUFFER_SIZE];
Expand All @@ -22,35 +22,24 @@ static mut WASM_MEMORY_BUFFER: [u8; WASM_MEMORY_BUFFER_SIZE] = [0; WASM_MEMORY_B
// in wasm memory
#[wasm_bindgen]
pub fn get_wasm_memory_buffer_pointer() -> *const u8 {
let pointer: *const u8;
unsafe {
pointer = WASM_MEMORY_BUFFER.as_ptr();
}

return pointer;
unsafe { WASM_MEMORY_BUFFER.as_ptr() }
}

// Function to get the string from the buffer and add the text to it
#[wasm_bindgen]
pub fn add_wasm_is_cool(passed_string_length: usize) -> usize {

// Let's get the passed string from our passed bytes
let mut passed_string = "";
unsafe {
passed_string = str::from_utf8(&WASM_MEMORY_BUFFER[0..passed_string_length]).unwrap();
}
let passed_string =
unsafe { str::from_utf8(&WASM_MEMORY_BUFFER[..passed_string_length]).unwrap() };

// Let's add our phrase to the passed string
let new_string = format!("{} Wasm is cool!", passed_string);

// Let's write the new string back to our buffer
let new_string_bytes = new_string.as_bytes();
for i in 0..new_string_bytes.len() {
unsafe {
WASM_MEMORY_BUFFER[i] = new_string_bytes[i];
}
unsafe {
WASM_MEMORY_BUFFER[..new_string.len()].copy_from_slice(new_string.as_bytes());
}

// Return the length of the new string for the host to fetch it out of memory
return new_string.len();
// Return the length of the new string for the host to fetch it out of memory
new_string.len()
}
56 changes: 33 additions & 23 deletions passing-data/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,39 +1,40 @@
// Import the Filesystem so we can read our .wasm file
use std::io::prelude::*;
use std::fs::File;
use std::io::prelude::*;

// Import the wasmer runtime so we can use it
use wasmer_runtime::{
instantiate,
imports,
error,
Func
};
use wasmer_runtime::{error, imports, instantiate, Func};

// Import some helpers for handling Pointers into Wasm Memory
use wasmer_runtime_core::memory::ptr::{WasmPtr, Array};
use wasmer_runtime_core::memory::ptr::{Array, WasmPtr};

// Create an absolute path to the Wasm file
const WASM_FILE_LOCATION: &str = concat!(
env!("CARGO_MANIFEST_DIR"),
"/example-rust-wasm-crate/strings-wasm-is-cool/pkg/strings_wasm_is_cool_bg.wasm"
);

// Our entry point to our application
fn main() -> error::Result<()> {

// Let's read in our .wasm file as bytes

// Let's open the file.
// The file path may be different depending where you run `cargo run`, and where you place the file.
let mut file = File::open("./example-rust-wasm-crate/strings-wasm-is-cool/pkg/strings_wasm_is_cool_bg.wasm").expect("Incorrect file path to wasm module.");
let mut file = File::open(WASM_FILE_LOCATION).expect("Incorrect file path to wasm module.");

// Let's read the file into a Vec
let mut wasm_vec = Vec::new();
file.read_to_end(&mut wasm_vec).expect("Error reading the wasm file");
file.read_to_end(&mut wasm_vec)
.expect("Error reading the wasm file");

// Let's get our byte slice ( [u8] ) from our wasm_vec.
// Let's get our byte slice ( &[u8] ) from our wasm_vec.
let wasm_bytes = wasm_vec.as_slice();

// Now that we have the wasm file as bytes, let's run it with the wasmer runtime

// Our import object, that allows exposing functions to our wasm module.
// We're not importing anything, so make an empty import object.
let import_object = imports!{};
let import_object = imports! {};

// Let's create an instance of wasm module running in the wasmer-runtime
let instance = instantiate(wasm_bytes, &import_object)?;
Expand All @@ -42,34 +43,43 @@ fn main() -> error::Result<()> {
let wasm_instance_context = instance.context();
let wasm_instance_memory = wasm_instance_context.memory(0);

// Let's get the pointer to the buffer defined by the wasm module in the wasm memory
let get_wasm_memory_buffer_pointer: Func<(), i32> =
instance
// Let's get the pointer to the buffer defined by the wasm module in the wasm memory.
// We use the type system and the power of generics to get a function we can call
// directly with a type signature of no arguments and returning 1 u32
let get_wasm_memory_buffer_pointer: Func<(), u32> = instance
.func("get_wasm_memory_buffer_pointer")
.expect("get_wasm_memory_buffer_pointer");
let response = get_wasm_memory_buffer_pointer.call().unwrap() as u32;
let response = get_wasm_memory_buffer_pointer.call().unwrap();
// Let's create a WasmPtr which is a thin wrapper around u32 to ergonomically access memory
let wasm_buffer_pointer: WasmPtr<u8, Array> = WasmPtr::new(response);

// Let's write a string to the wasm memory
let original_string = "Did you know";
println!("The original string is: {}", original_string);
let memory_writer = wasm_buffer_pointer.deref(wasm_instance_memory, 0, original_string.len() as u32).unwrap();
// We deref our WasmPtr to get a &[Cell<u8>]
let memory_writer = wasm_buffer_pointer
.deref(wasm_instance_memory, 0, original_string.len() as u32)
.unwrap();
for (i, b) in original_string.bytes().enumerate() {
memory_writer[i].set(b);
}

// Let's call the exported function that concatenates a phrase to our string.
let add_wasm_is_cool: Func<u32, i32> = instance.func("add_wasm_is_cool").expect("Wasm is cool export");
let add_wasm_is_cool: Func<u32, u32> = instance
.func("add_wasm_is_cool")
.expect("Wasm is cool export");
let new_string_length = add_wasm_is_cool.call(original_string.len() as u32).unwrap();

// Get our pointer again, since memory may have shifted around
let new_pointer_response = get_wasm_memory_buffer_pointer.call().unwrap() as u32;
// Get our pointer again, since memory may have shifted around
let new_pointer_response = get_wasm_memory_buffer_pointer.call().unwrap();
let new_wasm_buffer_pointer: WasmPtr<u8, Array> = WasmPtr::new(new_pointer_response);

// Read the string from that new pointer.
let new_string = new_wasm_buffer_pointer.get_utf8_string(wasm_instance_memory, new_string_length as u32).unwrap();
let new_string = new_wasm_buffer_pointer
.get_utf8_string(wasm_instance_memory, new_string_length)
.unwrap();
println!("The new string is: {}", new_string);

// Asserting that the returned value from the function is our expected value.
assert_eq!(new_string, "Did you know Wasm is cool!");

Expand Down

0 comments on commit 877497f

Please sign in to comment.