Skip to content

Commit dfb69bd

Browse files
Merge pull request #22 from pufferfish101007/rewrite-2024 - mega rewrite
Mega rewrite. Notable changes: modularisation proper unit tests to ensure wasm (and imported js) is valid (resolves unit tests are not proper unit tests #18) simplifies adding new blocks boxed values use NaN boxing rather than tags ints are i32 rather than i64 casting should always pick the best type to cast to clones a bit less (resolves clone is potentially overused #20) add compiler settings (currently mostly unused) auto track implemented blocks (resolves Auto-track implemented blocks #15) converts nans to zeros (resolves NaNs should be treated as 0 in mathematical operations #17) makes output types more specific (e.g. +ve/-ve, nan-ness) - based off Update improved type analysis to develop TurboWarp/scratch-vm#216 adds own internal wasm! macro to generate code (with special pseudo-instructions for things like zeroing nans) github actions deploys each branch to its own gh pages subdirectory warped custom blocks with arguments supported turbo mode works properly now modules optimised using wasm-opt
2 parents 88da9ea + c52ee5d commit dfb69bd

File tree

125 files changed

+8217
-6147
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

125 files changed

+8217
-6147
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
on: [push, workflow_dispatch]
1+
on: [push, workflow_dispatch, pull_request]
22

3-
name: CI
3+
name: CI checks
44

55
jobs:
66
build:
@@ -16,18 +16,20 @@ jobs:
1616
profile: minimal
1717
toolchain: nightly
1818
override: true
19+
target: wasm32-unknown-unknown
1920

2021
- name: Run cargo check
2122
uses: actions-rs/cargo@v1
2223
with:
2324
command: check
25+
args: --target=wasm32-unknown-unknown
2426

2527
clippy:
2628
name: Lint (clippy)
2729
runs-on: ubuntu-latest
2830
steps:
2931
- name: Checkout sources
30-
uses: actions/checkout@v2
32+
uses: actions/checkout@v4
3133

3234
- name: Install nightly toolchain with clippy available
3335
uses: actions-rs/toolchain@v1
@@ -48,7 +50,7 @@ jobs:
4850
runs-on: ubuntu-latest
4951
steps:
5052
- name: Checkout sources
51-
uses: actions/checkout@v2
53+
uses: actions/checkout@v4
5254

5355
- name: Install nightly toolchain with rustfmt available
5456
uses: actions-rs/toolchain@v1
@@ -60,14 +62,12 @@ jobs:
6062

6163
- name: Run cargo fmt
6264
uses: actions-rs/cargo@v1
63-
continue-on-error: true # WARNING: only for this example, remove it!
6465
with:
6566
command: fmt
6667
args: --all -- --check
67-
68-
buildwasm:
69-
name: Build WASM & website
70-
if: github.ref_name == 'main'
68+
69+
test:
70+
name: Run unit tests
7171
runs-on: ubuntu-latest
7272
steps:
7373
- name: Checkout sources
@@ -79,34 +79,26 @@ jobs:
7979
profile: minimal
8080
toolchain: nightly
8181
override: true
82-
target: wasm32-unknown-unknown
83-
84-
- name: Install wasm-bindgen
82+
83+
- name: Run cargo test
8584
uses: actions-rs/cargo@v1
8685
with:
87-
command: install
88-
args: -f wasm-bindgen-cli
89-
90-
- name: Install binaryen
91-
run: sudo apt-get install binaryen
92-
93-
- name: Install node
94-
uses: actions/setup-node@v3
95-
with:
96-
node-version: "20.x"
97-
98-
- name: Run npm install
99-
run: npm install
100-
101-
- name: Build
102-
run: chmod +x build.sh && ./build.sh -pWV
103-
104-
- name: Move files for gh pages
105-
run: mv ./playground/dist docs && cp docs/index.html docs/404.html
106-
107-
- name: Commit changes
108-
uses: stefanzweifel/git-auto-commit-action@v4
109-
with:
110-
branch: gh-pages
111-
create_branch: true
112-
push_options: '--force'
86+
command: test
87+
args: >-
88+
--
89+
--skip cast::float::js_functions_match_declared_types
90+
--skip cast::int::js_functions_match_declared_types
91+
--skip cast::string::js_functions_match_declared_types
92+
--skip join::tests::js_functions_match_declared_types
93+
--skip lt::tests::js_functions_match_declared_types
94+
--skip gt::tests::js_functions_match_declared_types
95+
--skip equals::tests::js_functions_match_declared_types
96+
--skip length::tests::js_functions_match_declared_types
97+
--skip letter_of::tests::js_functions_match_declared_types
98+
--skip contains::tests::js_functions_match_declared_types
99+
--skip dayssince2000::tests::js_functions_match_declared_types
100+
--skip looks::say::tests_debug::js_functions_match_declared_types
101+
--skip looks::say::tests_non_debug::js_functions_match_declared_types
102+
--skip looks::think::tests_debug::js_functions_match_declared_types
103+
--skip looks::think::tests_non_debug::js_functions_match_declared_types
104+

.github/workflows/deploy.yml

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
on: [push, workflow_dispatch]
2+
3+
name: Deploy
4+
5+
jobs:
6+
deploy:
7+
name: Build WASM & website
8+
runs-on: ubuntu-latest
9+
env:
10+
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
11+
permissions:
12+
contents: write
13+
steps:
14+
- name: Checkout sources
15+
uses: actions/checkout@v4
16+
17+
- name: Install nightly toolchain
18+
uses: actions-rs/toolchain@v1
19+
with:
20+
profile: minimal
21+
toolchain: nightly
22+
override: true
23+
target: wasm32-unknown-unknown
24+
25+
- name: Install wasm-bindgen
26+
uses: actions-rs/cargo@v1
27+
with:
28+
command: install
29+
args: -f wasm-bindgen-cli
30+
31+
- name: Install cargo-outdir
32+
uses: actions-rs/cargo@v1
33+
with:
34+
command: install
35+
args: cargo-outdir
36+
37+
- name: Install binaryen
38+
run: sudo apt-get install binaryen
39+
40+
- name: Install node
41+
uses: actions/setup-node@v3
42+
with:
43+
node-version: "20.x"
44+
45+
- name: Run npm install
46+
run: |
47+
npm install
48+
npm i -g vite
49+
npm i -g binaryen@nightly
50+
51+
- name: Build
52+
env:
53+
VITE_HASH_HISTORY: true
54+
run: |
55+
chmod +x build.sh && ./build.sh -Wpz
56+
vite build --base=/hyperquark/$BRANCH_NAME/
57+
58+
- name: Move files to tmp
59+
run: mv ./playground/dist /tmp/hq-dist
60+
61+
- name: checkout gh-pages
62+
uses: actions/checkout@v4
63+
with:
64+
ref: gh-pages
65+
66+
- name: move file to gh-pages
67+
run: |
68+
rm -rf ./$BRANCH_NAME
69+
mv /tmp/hq-dist ./$BRANCH_NAME
70+
#mv ./main/* ./
71+
72+
- name: Commit changes
73+
uses: stefanzweifel/git-auto-commit-action@v5
74+
with:
75+
branch: gh-pages
76+
push_options: '--force-with-lease'

.gitignore

+6-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@
44
/bad.mjs
55
/bad.wat
66
/wabt*
7-
/js/
7+
/js/compiler
8+
/js/no-compiler
9+
/js/imports.ts
10+
/js/opcodes.js
811
/node_modules/
912
/package-lock.json
1013
/playground/dist/
11-
/.vite/
14+
/.vite/
15+
/.vscode/

Cargo.toml

+20-3
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,37 @@ publish = false
88
serde = { version = "1.0", default-features = false, features = ["derive", "alloc"] }
99
serde_json = { version = "1.0", default-features = false, features = ["alloc"] }
1010
enum-field-getter = { path = "enum-field-getter" }
11-
wasm-encoder = "0.214.0"
12-
wasm-bindgen = "0.2.92"
11+
wasm-encoder = "0.226.0"
1312
indexmap = { version = "2.0.0", default-features = false }
1413
hashers = "1.0.1"
1514
uuid = { version = "1.4.1", default-features = false, features = ["v4", "js"] }
1615
regex = "1.10.5"
1716
lazy-regex = "3.2.0"
17+
bitmask-enum = "2.2.5"
18+
itertools = { version = "0.13.0", default-features = false, features = ["use_alloc"] }
19+
split_exact = "1.1.0"
20+
wasm-bindgen = "0.2.92"
21+
serde-wasm-bindgen = "0.6.5"
22+
wasm-gen = { path = "wasm-gen" }
1823

19-
#[dev-dependencies]
24+
[dev-dependencies]
25+
wasmparser = "0.226.0"
26+
wasmprinter = "0.226.0"
2027
#reqwest = { version = "0.11", features = ["blocking"] }
2128

29+
[target.'cfg(not(target_family = "wasm"))'.dev-dependencies]
30+
ezno-checker = { git = "https://github.com/kaleidawave/ezno.git", rev = "96d5058bdbb0cde924be008ca1e5a67fe39f46b9" }
31+
2232
[lib]
2333
crate-type = ["cdylib", "rlib"]
2434

2535
[profile.release]
2636
lto = true
2737
opt-level = "z"
38+
39+
[build-dependencies]
40+
convert_case = "0.6.0"
41+
42+
[features]
43+
compiler = [] # if we only want to access flags, we don't want to additionally have all the compiler machinery
44+
default = ["compiler"]

README.md

+23-3
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,42 @@ Compile scratch projects to WASM
55

66
## Prerequisites
77

8-
- [Rust](https://rust-lang.org) (v1.65.0 or later)
8+
- [Rust](https://rust-lang.org) v1.65.0 or later
99
- the `wasm32-unknown-unknown` target (`rustup target add wasm32-unknown-unknown`)
1010
- wasm-bindgen-cli (`cargo install -f wasm-bindgen-cli`)
1111
- wasm-opt (install binaryen using whatever package manager you use)
12+
- `cargo-outdir` (`cargo install cargo-outdir`)
1213

1314
## Building
1415

1516
```bash
16-
./build.sh -pVW # use -dVW for a debug build without optimisation
17+
./build.sh -Wp # use -Wd for a debug build without optimisation
1718
```
1819

1920
You may need to run `chmod +x build.sh` if it says it doesn't have permission.
2021

2122
The build script has additonal configuration options; run `./build.sh -h` for info on these.
2223

23-
If you experience runtime stack overflow errors in debug mode, try using the `-O` option to enable wasm-opt.
24+
If you experience runtime stack overflow errors in debug mode, try using the `-s` or `-z` options to enable wasm-opt; weird wasm errors in production mode may conversely be solved by *disabling* wasm-opt using the `-o` flag.
25+
26+
## Adding a new block
27+
28+
To add a new block named `category_opcode`, if it cannot be reduced to simpler blocks:
29+
1. create `src/instructions/category/opcode.rs`. Make sure to `use super::super::prelude::*` and create the relevant `pub` items:
30+
- (optional) `pub struct Fields` (must be `Debug` and `Clone`)
31+
- `pub fn wasm(func: &StepFunc, inputs: Rc<[IrType]>, (fields: &Fields)?) -> HQResult<Vec<InternalInstruction>>;`
32+
- - wasm is generated using the `wasm_gen::wasm` macro. See [its README](./wasm-gen/README.md) for usage instructions, or e.g. [say.rs](./src/instructions/looks/say.rs) for an example.
33+
- `pub fn acceptable_inputs() -> Rc<[IrType]>;`
34+
- - these should really be base types (see BASE_TYPES in [types.rs](./src/ir/types.rs))
35+
- `pub fn output_type(inputs: Rc<[IrType]>, (fields: &Fields)?) -> HQResult<Option<IrType>>;`
36+
- - the output type should be as restrictive as possible; loose output types can cause us to lose out on some optimisations
37+
- ensure to add relevant `instructions_test!`s - see [instructions/tests.rs](./src/instructions/tests.rs) for usage
38+
2. add `pub mod opcode;` to `src/instructions/category.rs`, creating the file if needed
39+
- if you're creating the category file, add `mod category;` to `src/instructions.rs`
40+
3. add the block to `from_normal_block` in `src/ir/blocks.rs`; in most cases this should be a direct mapping of `BlockOpcode::category_opcode => IrOpcode::category_opcode`
41+
4. add the block's input names to `input_names` in `src/ir/blocks.rs`
42+
43+
If the block *can* be reduced to simpler steps, only carry out steps 3 and 4 above.
2444

2545
## generared WASM module memory layout
2646

0 commit comments

Comments
 (0)