diff --git a/src/SUMMARY.md b/src/SUMMARY.md index c7320a57..47f49cb5 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -307,6 +307,7 @@ - [Import user-defined Javascript types](webassembly/import-js-type.md) - [Limitations](webassembly/limitations.md) - [Borrow Checker](webassembly/limitations/borrow-checker.md) + - [Closures](webassembly/limitations/closures.md) - [Async](webassembly/async.md) diff --git a/src/webassembly/limitations.md b/src/webassembly/limitations.md new file mode 100644 index 00000000..e54a0ad1 --- /dev/null +++ b/src/webassembly/limitations.md @@ -0,0 +1,29 @@ +# Limitations and Workarounds + +Because it runs in a Virtual Machine with its own set of restrictions, +some common native operations are not available in WebAssembly. For instance, +there is no file system in WASM, therefore file operations are handled +through Web APIs. + +Other methods from the standard library that rely on system calls cannot be +used as well. They can however either be replaced by a dependency or be enabled +by setting a feature flag. For instance, + +- Many methods from `std::time` rely on system calls, so they will panic when called +in WASM. [Drop in replacements](https://docs.rs/web-time/latest/web_time/) exist that +use the brower's `Date` and `performance` methods +- `rand` which usually relies on thread local storage, can be made to use +`Math.random()` by setting the dependency feature `getrandom = { ..., features = ["js"] }` +- Statically linking against another language and bundling as one binary is mostly not supported +because the standard WASM ABI is not based on C's like in most environments. Instead, you +should dynamically link with `#[wasm_bindgen] extern "C"`. This means that some crates +which bundle C or C++ binaries will not be portable to WASM. + +Furthermore, interoperability with Javascript, a language that knows nothing about +the borrow-checker but uses Garbage Collection to manage memory forces us to +alter how we use both Rust and Javascript with WebAssembly. + +This chapter covers a few caveats of WASM programming: + +- [Borrow Checker](limitations/borrow-checker.md) +- [Closures](limitations/closures.md) diff --git a/src/webassembly/limitations/borrow-checker.md b/src/webassembly/limitations/borrow-checker.md index b79a932e..b8503706 100644 --- a/src/webassembly/limitations/borrow-checker.md +++ b/src/webassembly/limitations/borrow-checker.md @@ -1,6 +1,7 @@ # Borrow Checker -Types annotated with `wasm_bindgen` can reference each other. +When we export a Rust type to Javascript and the pass an instance of this type to a method that takes ownership of it, the javascript variable will be cleared and dereferencing it will throw a runtime error. +This essentially implements the borrow checker at Runtime in Javascript. ```rust #[wasm_bindgen] @@ -28,8 +29,6 @@ impl MultiCounter { } ``` -But what happens when you call `add_counter` from Javascript ? - ```javascript import init, {set_panic_hook, Counter, MultiCounter} from '/wasm/project.js'; diff --git a/src/webassembly/limitations/closures.md b/src/webassembly/limitations/closures.md new file mode 100644 index 00000000..1d358843 --- /dev/null +++ b/src/webassembly/limitations/closures.md @@ -0,0 +1,2 @@ +# Closures +