Skip to content

Commit bf5df68

Browse files
authored
Migrated code generation logic to it's own crate (#890)
* Migrated code generation logic to it's own crate * Skip javy-codegen during CI test command. * Skip javy-codegen during CI lint command. * Correct various typo's and updated CI flows and Makefiles * Added integration testing for codegen and cleaned up documentation. * Corrected minor formatting issue in README.md * Updated feature documentation to no longer include javy_unstable * Added missing newline in documentation. * Updated integration tests to use the default plugin. * Updated test comment * Support using Cow instead of Vec<u8> for Plugins * Upgrade codegen to vet approved version of convert_case * Updated cargo lock and vetting information * Revert "Updated cargo lock and vetting information" This reverts commit fc91898. * Fixed up vetting information.
1 parent 815e3b9 commit bf5df68

21 files changed

+281
-77
lines changed

.github/workflows/ci.yml

+13-2
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ jobs:
5757
- name: Test
5858
env:
5959
CARGO_TARGET_WASM32_WASIP1_RUNNER: wasmtime --dir=.
60-
run: cargo hack test --target=wasm32-wasip1 --workspace --exclude=javy-cli --exclude=javy-runner --exclude=javy-test-plugin --each-feature -- --nocapture
60+
run: cargo hack test --target=wasm32-wasip1 --workspace --exclude=javy-cli --exclude=javy-codegen --exclude=javy-runner --exclude=javy-test-plugin --each-feature -- --nocapture
6161

6262
- name: Test Runner
6363
run: cargo test --package=javy-runner
@@ -66,6 +66,7 @@ jobs:
6666
run: |
6767
cargo clippy --workspace \
6868
--exclude=javy-cli \
69+
--exclude=javy-codegen \
6970
--exclude=javy-runner \
7071
--exclude=javy-fuzz \
7172
--target=wasm32-wasip1 --all-targets -- -D warnings
@@ -84,14 +85,24 @@ jobs:
8485
- name: Test CLI
8586
run: CARGO_PROFILE_RELEASE_LTO=off cargo test --package=javy-cli --release -- --nocapture
8687

88+
- name: Test CodeGen
89+
run: |
90+
target/release/javy emit-plugin -o crates/codegen/default_plugin.wasm
91+
CARGO_PROFILE_RELEASE_LTO=off cargo hack test --package=javy-codegen --release --each-feature -- --nocapture
92+
8793
- name: Check benchmarks
8894
run: CARGO_PROFILE_RELEASE_LTO=off cargo check --package=javy-cli --release --benches
8995

90-
- name: Lint
96+
- name: Lint CLI
9197
run: |
9298
cargo fmt -- --check
9399
CARGO_PROFILE_RELEASE_LTO=off cargo clippy --package=javy-cli --release --all-targets -- -D warnings
94100
101+
- name: Lint CodeGen
102+
run: |
103+
cargo fmt -- --check
104+
CARGO_PROFILE_RELEASE_LTO=off cargo hack clippy --package=javy-codegen --release --all-targets --each-feature -- -D warnings
105+
95106
- name: WPT
96107
run: |
97108
npm install --prefix wpt

Cargo.lock

+32-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
[workspace]
22
members = [
33
"crates/cli",
4+
"crates/codegen",
45
"crates/javy",
56
"crates/plugin",
67
"crates/plugin-api",

Makefile

+11-3
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ test-plugin-api:
3434
test-plugin:
3535
CARGO_TARGET_WASM32_WASIP1_RUNNER="wasmtime" cargo test --package=javy-plugin --target=wasm32-wasip1 -- --nocapture
3636

37+
test-codegen: cli
38+
target/release/javy emit-plugin -o crates/codegen/default_plugin.wasm
39+
CARGO_PROFILE_RELEASE_LTO=off cargo hack test --package=javy-codegen --release --each-feature -- --nocapture
40+
3741
# Test in release mode to skip some debug assertions
3842
# Note: to make this faster, the engine should be optimized beforehand (wasm-strip + wasm-opt).
3943
# Disabling LTO substantially improves compile time
@@ -45,11 +49,11 @@ test-runner:
4549

4650
test-wpt: cli
4751
npm install --prefix wpt
48-
npm test --prefix wpt
52+
npm test --prefix wpt
4953

50-
tests: test-javy test-plugin-api test-plugin test-runner test-cli test-wpt
54+
tests: test-javy test-plugin-api test-plugin test-runner test-codegen test-cli test-wpt
5155

52-
fmt: fmt-javy fmt-plugin-api fmt-plugin fmt-cli
56+
fmt: fmt-javy fmt-plugin-api fmt-plugin fmt-cli fmt-codegen
5357

5458
fmt-javy:
5559
cargo fmt --package=javy -- --check
@@ -68,3 +72,7 @@ fmt-plugin:
6872
fmt-cli:
6973
cargo fmt --package=javy-cli -- --check
7074
CARGO_PROFILE_RELEASE_LTO=off cargo clippy --package=javy-cli --release --all-targets -- -D warnings
75+
76+
fmt-codegen:
77+
cargo fmt --package=javy-codegen -- --check
78+
cargo clippy --package=javy-codegen --release --all-targets -- -D warnings

crates/cli/Cargo.toml

+3-15
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,18 @@ build = "build.rs"
1010
name = "javy"
1111
path = "src/main.rs"
1212

13-
[features]
14-
dump_wat = ["dep:wasmprinter"]
15-
1613
[dependencies]
14+
wasi-common = { workspace = true }
1715
wizer = { workspace = true }
1816
anyhow = { workspace = true }
19-
brotli = "7.0.0"
20-
wasmprinter = { version = "0.226.0", optional = true }
2117
wasmtime = { workspace = true }
22-
wasmtime-wasi = { workspace = true }
23-
wasi-common = { workspace = true }
2418
walrus = "0.23.3"
25-
swc_core = { version = "10.7.0", features = [
26-
"common_sourcemap",
27-
"ecma_ast",
28-
"ecma_parser",
29-
] }
30-
wit-parser = "0.212.0"
31-
convert_case = "0.8.0"
32-
wasm-opt = { workspace = true }
19+
wasm-opt = "0.116.1"
3320
tempfile = { workspace = true }
3421
clap = { version = "4.5.31", features = ["derive"] }
3522
serde = { workspace = true, default-features = false }
3623
serde_json = { workspace = true }
24+
javy-codegen = { path = "../codegen/", features = ["plugin_internal"] }
3725

3826
[dev-dependencies]
3927
criterion = "0.5"

crates/cli/src/main.rs

+21-17
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
mod codegen;
21
mod commands;
32
mod js_config;
43
mod option;
@@ -7,9 +6,9 @@ mod plugin;
76
use crate::commands::{Cli, Command, EmitPluginCommandOpts};
87
use anyhow::Result;
98
use clap::Parser;
10-
use codegen::js::JS;
11-
use codegen::{plugin::Plugin, wit::WitOptions, Generator, LinkingKind};
9+
1210
use commands::CodegenOptionGroup;
11+
use javy_codegen::{Generator, LinkingKind, Plugin, WitOptions, JS};
1312
use js_config::JsConfig;
1413
use plugin::{
1514
CliPlugin, PluginKind, UninitializedPlugin, PLUGIN_MODULE, QUICKJS_PROVIDER_V2_MODULE,
@@ -30,33 +29,38 @@ fn main() -> Result<()> {
3029
3130
Refer to https://github.com/bytecodealliance/javy/issues/702 for
3231
details.
33-
32+
3433
Use the `build` command instead.
3534
"#
3635
);
3736

3837
let js = JS::from_file(&opts.input)?;
3938

40-
let mut generator = Generator::new();
41-
generator
42-
.wit_opts(WitOptions::from_tuple((
43-
opts.wit.clone(),
44-
opts.wit_world.clone(),
45-
))?)
46-
.source_compression(!opts.no_source_compression)
47-
.js_runtime_config(JsConfig::default().to_json()?);
39+
let plugin_bytes = if opts.dynamic {
40+
QUICKJS_PROVIDER_V2_MODULE
41+
} else {
42+
PLUGIN_MODULE
43+
};
44+
45+
let mut generator = Generator::new(Plugin::new(plugin_bytes.into()));
4846

4947
if opts.dynamic {
5048
generator
51-
.plugin(Plugin::new(QUICKJS_PROVIDER_V2_MODULE.into()))
5249
.linking(LinkingKind::Dynamic)
5350
.linking_v2_plugin(true);
5451
} else {
5552
generator
56-
.plugin(Plugin::new(PLUGIN_MODULE.into()))
5753
.linking(LinkingKind::Static)
5854
.linking_default_plugin(true);
59-
};
55+
}
56+
57+
generator
58+
.wit_opts(WitOptions::from_tuple((
59+
opts.wit.clone(),
60+
opts.wit_world.clone(),
61+
))?)
62+
.source_compression(!opts.no_source_compression)
63+
.js_runtime_config(JsConfig::default().to_json()?);
6064

6165
let wasm = generator.generate(&js)?;
6266

@@ -66,7 +70,6 @@ fn main() -> Result<()> {
6670
Command::Build(opts) => {
6771
let js = JS::from_file(&opts.input)?;
6872
let codegen_opts: CodegenOptionGroup = opts.codegen.clone().try_into()?;
69-
let mut generator = Generator::new();
7073

7174
// Always assume the default plugin if no plugin is provided.
7275
let cli_plugin = match &codegen_opts.plugin {
@@ -76,14 +79,15 @@ fn main() -> Result<()> {
7679

7780
let js_opts = JsConfig::from_group_values(&cli_plugin, opts.js.clone())?;
7881

82+
let mut generator = Generator::new(cli_plugin.into_plugin());
83+
7984
// Always link to the default plugin if no plugin is provided.
8085
if codegen_opts.plugin.is_none() {
8186
generator.linking_default_plugin(true);
8287
}
8388

8489
// Configure the generator with the provided options.
8590
generator
86-
.plugin(cli_plugin.into_plugin())
8791
.wit_opts(codegen_opts.wit)
8892
.source_compression(!codegen_opts.source_compression)
8993
.js_runtime_config(js_opts.to_json()?);

crates/cli/src/plugin.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use crate::codegen::plugin::Plugin;
21
use anyhow::{bail, Result};
2+
use javy_codegen::Plugin;
33
use std::{fs, str};
44
use walrus::{ExportItem, ValType};
55
use wizer::Wizer;

crates/codegen/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
default_plugin.wasm

crates/codegen/CHANGELOG.md

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6+
and this project adheres to [Semantic
7+
Versioning](https://semver.org/spec/v2.0.0.html).
8+
9+
## [1.0.0] - 2025-2-15
10+
11+
Initial release

crates/codegen/Cargo.toml

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
[package]
2+
name = "javy-codegen"
3+
version = "1.0.0-alpha.1"
4+
authors.workspace = true
5+
edition.workspace = true
6+
license.workspace = true
7+
description = "Wasm generation library for use with Javy"
8+
homepage = "https://github.com/bytecodealliance/javy/tree/main/crates/codegen"
9+
repository = "https://github.com/bytecodealliance/javy/tree/main/crates/codegen"
10+
categories = ["wasm"]
11+
12+
[features]
13+
plugin_internal = []
14+
dump_wat = ["dep:wasmprinter"]
15+
16+
[dependencies]
17+
wizer = { workspace = true }
18+
anyhow = { workspace = true }
19+
brotli = "7.0.0"
20+
wasmprinter = { version = "0.224.0", optional = true }
21+
wasmtime = { workspace = true }
22+
wasmtime-wasi = { workspace = true }
23+
wasi-common = { workspace = true }
24+
walrus = "0.23.3"
25+
swc_core = { version = "10.7.0", features = [
26+
"common_sourcemap",
27+
"ecma_ast",
28+
"ecma_parser",
29+
] }
30+
wit-parser = "0.212.0"
31+
convert_case = "0.8.0"
32+
wasm-opt = "0.116.1"
33+
tempfile = { workspace = true }

crates/codegen/README.md

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<div align="center">
2+
<h1><code>javy-codegen</code></h1>
3+
<p>
4+
<strong>A crate for generating Wasm modules using Javy</strong>
5+
</p>
6+
<p>
7+
<a href="https://docs.rs/javy-codegen"><img src="https://docs.rs/javy-codegen/badge.svg" alt="Documentation Status" /></a>
8+
<a href="https://crates.io/crates/javy-codegen"><img src="https://img.shields.io/crates/v/javy-codegen" alt="crates.io status" /></a>
9+
</p>
10+
</div>
11+
12+
Refer to the [crate level documentation](https://docs.rs/javy-codegen) to learn more.
13+
14+
Example usage:
15+
16+
```rust
17+
use std::path::Path;
18+
use javy_codegen::{Generator, LinkingKind, Plugin, JS};
19+
20+
fn main() {
21+
// Load your target Javascript.
22+
let js = JS::from_file(Path::new("example.js"));
23+
24+
// Load existing pre-initialized Javy plugin.
25+
let plugin = Plugin::new_from_path(Path::new("example-plugin.wasm"));
26+
27+
// Configure code generator.
28+
let mut generator = Generator::new();
29+
generator.plugin(plugin);
30+
generator.linking(LinkingKind::Static);
31+
32+
// Generate your Wasm module.
33+
let wasm = generator.generate(&js)?;
34+
}
35+
```
File renamed without changes.

crates/cli/src/codegen/exports.rs crates/codegen/src/exports.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ use anyhow::{anyhow, Result};
22
use convert_case::{Case, Casing};
33
use std::{env, path::Path};
44

5-
use crate::{codegen::js::JS, codegen::wit};
5+
use crate::js::JS;
6+
use crate::wit;
67

78
pub(crate) type Exports = Vec<Export>;
89

0 commit comments

Comments
 (0)