Compile scratch projects to WASM
- Rust v1.65.0 or later
- the
wasm32-unknown-unknowntarget (rustup target add wasm32-unknown-unknown) - wasm-bindgen-cli (
cargo install -f wasm-bindgen-cli) - wasm-opt (install binaryen using whatever package manager you use)
cargo-outdir(cargo install cargo-outdir)
./build.sh -Wp # use -Wd for a debug build without optimisationYou may need to run chmod +x build.sh if it says it doesn't have permission.
The build script has additonal configuration options; run ./build.sh -h for info on these.
If you experience runtime stack overflow errors in debug mode, try using the -s or -z options to enable wasm-opt, or build in production mode; weird wasm errors in production mode may conversely be solved by disabling wasm-opt using the -o flag.
If an error occurs during execution and you need a stack trace, run with the -D flag to enable panicking with DWARF debug symbols. You need to set up your browser to display a proper stack trace using these debug symbols. You'll need to disable wasm-opt using -o for this to work, as wasm-opt currently crashes when it encounters DWARF.
To preview the website (e.g. to run a project), use npm run watch. Do not just run vite as this will build in debug mode which doesn't work.
To add a new block named category_opcode, if it cannot be reduced to simpler blocks:
- create
src/instructions/category/opcode.rs. Make sure touse super::super::prelude::*and create the relevantpubitems:
- (optional)
pub struct Fields(must beDebugandClone) pub fn wasm(func: &StepFunc, inputs: Rc<[IrType]>, (fields: &Fields)?) -> HQResult<Vec<InternalInstruction>>;-
- wasm is generated using the
wasm_gen::wasmmacro. See its README for usage instructions, or e.g. say.rs for an example.
- wasm is generated using the
pub fn acceptable_inputs() -> HQResult<Rc<[IrType]>>;-
- these should really be base types (see BASE_TYPES in types.rs)
pub fn output_type(inputs: Rc<[IrType]>, (fields: &Fields)?) -> HQResult<ReturnType>;-
- the output type should be as restrictive as possible; loose output types can cause us to lose out on some optimisations
-
- Most output types should be either
ReturnType::NoneorSingleton(IrType)(included in the module prelude); blocks can return multiple values viaMultiValue(Rc<[IrType]>)but probably shouldn't.
- Most output types should be either
- ensure to add relevant
instructions_test!s - see instructions/tests.rs for usage
- add
pub mod opcode;tosrc/instructions/category.rs, creating the file if needed
- if you're creating the category file, add
mod category;tosrc/instructions.rs
- add the block to
from_normal_blockinsrc/ir/blocks.rs; in most cases this should be a direct mapping ofBlockOpcode::category_opcode => IrOpcode::category_opcode - add the block's input names to
input_namesinsrc/ir/blocks.rs
If the block can be reduced to simpler steps, only carry out steps 3 and 4 above.
| name | number of bytes | optional? | description |
|---|---|---|---|
| sprite_info | 80 * number of sprites (i.e. target num - 1) |
yes | see src/wasm/sprite.rs |
| threads | 4 * thread_num | present iff using the CallIndirect scheduler | indices of the next step funcs of currently running threads |
All values should be guaranteed to have the maximum possible alignment for that value type. Unused/padding bytes are not guaranteed to have any specific values and may be overwritten.
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
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.