diff --git a/Cargo.toml b/Cargo.toml index aaa8b69..3ff8cf8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,26 +10,21 @@ crate-type = ["cdylib", "rlib"] [features] # enable panic hook -default = ["console_error_panic_hook"] +dev = ["console_error_panic_hook"] [dependencies] wasm-bindgen = "0.2.84" - -# allows logging panics but increases code size - disable for deployment console_error_panic_hook = { version = "0.1.7", optional = true } -# allows logging from js -web-sys = { version = "0.3.77", features = ["console"] } +web-sys = { version = "0.3.77", features = ["console"] } # allows logging from rust [dev-dependencies] wasm-bindgen-test = "0.3.34" # include debug info (function names) in build if dev profile is used -# usage: wasm-pack build --dev [profile.dev] debug = true opt-level = "s" -## Enable DWARF output from wasm-bindgen -# usage: wasm-pack build --dev +## Enable DWARF output from wasm-bindgen if dev profile is used [package.metadata.wasm-pack.profile.dev.wasm-bindgen] dwarf-debug-info = true diff --git a/README.md b/README.md index 6b68408..515309e 100644 --- a/README.md +++ b/README.md @@ -1,84 +1,78 @@ -
- -

wasm-pack-template

- - A template for kick starting a Rust and WebAssembly project using wasm-pack. - -

- Build Status -

- -

- Tutorial - | - Chat -

- - Built with 🦀🕸 by The Rust and WebAssembly Working Group -
- -## About - -[**📚 Read this template tutorial! 📚**][template-docs] - -This template is designed for compiling Rust libraries into WebAssembly and -publishing the resulting package to NPM. - -Be sure to check out [other `wasm-pack` tutorials online][tutorials] for other -templates and usages of `wasm-pack`. - -[tutorials]: https://rustwasm.github.io/docs/wasm-pack/tutorials/index.html -[template-docs]: https://rustwasm.github.io/docs/wasm-pack/tutorials/npm-browser-packages/index.html - -## 🚴 Usage - -### 🐑 Use `cargo generate` to Clone this Template - -[Learn more about `cargo generate` here.](https://github.com/ashleygwilliams/cargo-generate) - +# Wasm Debugging Demo +- build with debugging features: +```bash +wasm-pack build --dev --features dev ``` -cargo generate --git https://github.com/rustwasm/wasm-pack-template.git --name my-project -cd my-project +- run the web application in `: +```bash +cd www && npm run start ``` - -### 🛠️ Build with `wasm-pack build` - +# Wasm Debugging Tools +### Enable debug info +- Include debug symbols (function names, variable names) in the compiled WASM so that stack traces and wasm are more readable +- Disable on release builds to reduce code size +```toml +# usage: wasm-pack build --dev +[profile.dev] +debug = true ``` -wasm-pack build +### [console_error_panic_hook](https://github.com/rustwasm/console_error_panic_hook) +- causes panics to log with `console.error ` +- Add the hook to `cargo.toml` but disable it for release builds because it increases code size +```toml +# usage: wasm-pack build --features dev +[features] +dev = ["console_error_panic_hook"] + +console_error_panic_hook = { version = "0.1.7", optional = true } ``` - -### 🔬 Test in Headless Browsers with `wasm-pack test` - +- enable it within a function at the start of the rust execution, any subsequent panics will be logged +```rust +#[cfg(feature = "console_error_panic_hook")] +console_error_panic_hook::set_once(); ``` -wasm-pack test --headless --firefox +### Enable DWARF Debugging +- Enable DWARF debug output in `dev` builds +- Sets `dwarf-debug-info` configuration for `wasm-bindgen` (not exposed by higher level `wasm-pack` crate) +- Dwarf enabled debuggers will be able to step through the rust sources +- Install an experimental DWARF debugger on chrome here: https://chromewebstore.google.com/detail/cc++-devtools-support-dwa/pdcpmagijalfljmkmjngeonclgbbannb + - If configured correctly, Rust code will show up under sources in the chrome debugger +```toml +# usage: wasm-pack build --dev +[package.metadata.wasm-pack.profile.dev.wasm-bindgen] +dwarf-debug-info = true ``` -### 🎁 Publish to NPM with `wasm-pack publish` - +# Inspecting Wasm Binaries +### wasm2wat/wat2wasm +- Converts `.wasm` binary into a human-readable WebAssembly Text Format (WAT) +- Edit the `.wat` file and then recompile to `.wasm` +```bash +wasm2wat pkg/project.wasm -o project.wat +wat2wasm project.wat -o new_project.wasm ``` -wasm-pack publish +# Logging in Wasm +### Logging via `web-sys` +- exposes bindings to all browser web APIs +- include` web-sys` in `cargo.toml` +```toml +web-sys = { version = "0.3.77", features = ["console"] } ``` - -## 🔋 Batteries Included - -* [`wasm-bindgen`](https://github.com/rustwasm/wasm-bindgen) for communicating - between WebAssembly and JavaScript. -* [`console_error_panic_hook`](https://github.com/rustwasm/console_error_panic_hook) - for logging panic messages to the developer console. -* `LICENSE-APACHE` and `LICENSE-MIT`: most Rust projects are licensed this way, so these are included for you - -## License - -Licensed under either of - -* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) -* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) - -at your option. - -### Contribution - -Unless you explicitly state otherwise, any contribution intentionally -submitted for inclusion in the work by you, as defined in the Apache-2.0 -license, shall be dual licensed as above, without any additional terms or -conditions. +- usage from Rust: +```rust +pub fn log(message: &str) { + web_sys::console::log_1(&message.into()); +} +``` +### Logging via wasm_bindgen +- Use `wasm_bindgen` to generate bindings to external functions yourself +```rust +#[wasm_bindgen] +extern "C" { + fn alert(s: &str); + + // binds external JS console.log function to rust function + #[wasm_bindgen(js_namespace = console)] + pub fn log(s: &str); +} +``` \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 8a37945..27ebc9c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,17 @@ mod util; use web_sys::console; // must import console here too because it's used in a macro use wasm_bindgen::prelude::*; +use std::alloc::{alloc, Layout}; +#[no_mangle] +pub static mut MEMORY: [u8; 128 * 1024] = [0; 128 * 1024]; // Fixed 128KB + +#[no_mangle] +pub extern "C" fn allocate_memory() { + let mut vec = Vec::new(); + loop { + vec.push(vec![0u8; 64 * 1024]); // Allocate 64KB chunks until OOM + } +} #[wasm_bindgen] #[repr(u8)] #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -33,11 +44,16 @@ pub struct Universe { impl Universe { pub fn new() -> Universe { util::log("Creating new universe"); + log_macro!("Enabling panic hook"); // enable the panic hook, any panics that occur after this will be logged with console.error #[cfg(feature = "console_error_panic_hook")] console_error_panic_hook::set_once(); + + panic!("testing the panic hook"); + util::web_sys_log("testing web_sys_log"); + let width = 264; let height = 264; let cells = (0..width * height) @@ -88,7 +104,7 @@ impl Universe { self.to_string() } pub fn tick(&mut self) { - let _timer = util::Timer::new("Universe::tick"); + // let _timer = util::Timer::new("Universe::tick"); let mut next = self.cells.clone(); for row in 0..self.height { diff --git a/src/util.rs b/src/util.rs index bea0012..2a166c9 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,5 +1,4 @@ use wasm_bindgen::prelude::wasm_bindgen; -use web_sys::console; // import browser console APIs from web_sys pub struct Timer<'a> { name: &'a str, @@ -9,7 +8,7 @@ impl<'a> Timer<'a> { // create new timer instance and begin timing // calls console.time("label") pub fn new(name: &'a str) -> Timer<'a> { - console::time_with_label(name); + web_sys::console::time_with_label(name); Timer { name } } } @@ -18,7 +17,7 @@ impl<'a> Timer<'a> { impl<'a> Drop for Timer<'a> { fn drop(&mut self) { // This calls `console.timeEnd("label")`, logging the elapsed time in the browser console. - console::time_end_with_label(self.name); + web_sys::console::time_end_with_label(self.name); } } @@ -28,10 +27,14 @@ impl<'a> Drop for Timer<'a> { macro_rules! log_macro { ( $( $t:tt )* ) => { // web_sys exposes JS APIs to Rust - console::log_1(&format!( $( $t )* ).into()); + web_sys::console::log_1(&format!( $( $t )* ).into()); } } +pub fn web_sys_log(message: &str) { + web_sys::console::log_1(&message.into()); +} + #[wasm_bindgen] extern "C" { fn alert(s: &str); diff --git a/www/index.js b/www/index.js index ac980a8..28980a7 100644 --- a/www/index.js +++ b/www/index.js @@ -165,3 +165,4 @@ const renderLoop = () => { animationId = requestAnimationFrame(renderLoop); }; play(); +console.log("Memory allocated:", memory.buffer.byteLength); // Should print 65536 (64KB)