From a1d1b252a848b5f2b7a57e98a3822d8a3195731b Mon Sep 17 00:00:00 2001 From: Jeff Charles Date: Tue, 27 Aug 2024 16:19:15 -0400 Subject: [PATCH 1/3] Add JS runtime option infra and redirect-stdout-to-stderr option --- crates/cli/src/codegen/builder.rs | 22 ++--- crates/cli/src/codegen/dynamic.rs | 6 +- crates/cli/src/codegen/mod.rs | 11 --- crates/cli/src/codegen/static.rs | 18 ++-- crates/cli/src/commands.rs | 104 +++++++++++++++++++++-- crates/cli/src/main.rs | 20 +++-- crates/cli/tests/dynamic_linking_test.rs | 18 +++- crates/cli/tests/integration_test.rs | 69 +++++++++++---- crates/runner/src/lib.rs | 44 +++++++++- 9 files changed, 236 insertions(+), 76 deletions(-) diff --git a/crates/cli/src/codegen/builder.rs b/crates/cli/src/codegen/builder.rs index 868d1be5..5bdc68ca 100644 --- a/crates/cli/src/codegen/builder.rs +++ b/crates/cli/src/codegen/builder.rs @@ -1,5 +1,6 @@ -use crate::codegen::{CodeGen, CodeGenType, DynamicGenerator, StaticGenerator}; +use crate::codegen::{CodeGen, DynamicGenerator, StaticGenerator}; use anyhow::{bail, Result}; +use javy_config::Config; use std::path::PathBuf; /// Options for using WIT in the code generation process. @@ -78,19 +79,9 @@ impl CodeGenBuilder { self } - /// Build a [`CodeGenerator`]. - pub fn build(self) -> Result> - where - T: CodeGen, - { - match T::classify() { - CodeGenType::Static => self.build_static(), - CodeGenType::Dynamic => self.build_dynamic(), - } - } - - fn build_static(self) -> Result> { - let mut static_gen = Box::new(StaticGenerator::new()); + /// Build a static [`CodeGenerator`]. + pub fn build_static(self, js_runtime_config: Config) -> Result> { + let mut static_gen = Box::new(StaticGenerator::new(js_runtime_config)); static_gen.source_compression = self.source_compression; static_gen.wit_opts = self.wit_opts; @@ -98,7 +89,8 @@ impl CodeGenBuilder { Ok(static_gen) } - fn build_dynamic(self) -> Result> { + /// Build a dynamic [`CodeGenerator`]. + pub fn build_dynamic(self) -> Result> { let mut dynamic_gen = Box::new(DynamicGenerator::new()); if let Some(v) = self.provider_version { diff --git a/crates/cli/src/codegen/dynamic.rs b/crates/cli/src/codegen/dynamic.rs index c07b4fb6..df9fd859 100644 --- a/crates/cli/src/codegen/dynamic.rs +++ b/crates/cli/src/codegen/dynamic.rs @@ -1,6 +1,6 @@ use super::transform::{self, SourceCodeSection}; use crate::{ - codegen::{exports, CodeGen, CodeGenType, Exports, WitOptions}, + codegen::{exports, CodeGen, Exports, WitOptions}, js::JS, }; use anyhow::Result; @@ -285,10 +285,6 @@ impl CodeGen for DynamicGenerator { print_wat(&wasm)?; Ok(wasm) } - - fn classify() -> CodeGenType { - CodeGenType::Dynamic - } } #[cfg(feature = "dump_wat")] diff --git a/crates/cli/src/codegen/mod.rs b/crates/cli/src/codegen/mod.rs index 571f9e87..018c1fc6 100644 --- a/crates/cli/src/codegen/mod.rs +++ b/crates/cli/src/codegen/mod.rs @@ -49,20 +49,9 @@ pub(crate) use exports::*; use crate::JS; -pub(crate) enum CodeGenType { - /// Static code generation. - Static, - /// Dynamic code generation. - Dynamic, -} - /// Code generator trait to abstract the multiple JS to Wasm code generation /// paths. pub(crate) trait CodeGen { /// Generate Wasm from a given JS source. fn generate(&mut self, source: &JS) -> anyhow::Result>; - /// Classify the [`CodeGen`] type. - fn classify() -> CodeGenType - where - Self: Sized; } diff --git a/crates/cli/src/codegen/static.rs b/crates/cli/src/codegen/static.rs index 24560c31..64af9ba5 100644 --- a/crates/cli/src/codegen/static.rs +++ b/crates/cli/src/codegen/static.rs @@ -12,7 +12,7 @@ use crate::{ codegen::{ exports, transform::{self, SourceCodeSection}, - CodeGen, CodeGenType, Exports, WitOptions, + CodeGen, Exports, WitOptions, }, js::JS, }; @@ -26,17 +26,20 @@ pub(crate) struct StaticGenerator { function_exports: Exports, /// WIT options for code generation. pub wit_opts: WitOptions, + /// JS runtime options for code generation. + pub js_runtime_config: Config, } impl StaticGenerator { /// Creates a new [`StaticGenerator`]. - pub fn new() -> Self { + pub fn new(js_runtime_config: Config) -> Self { let engine = include_bytes!(concat!(env!("OUT_DIR"), "/engine.wasm")); Self { engine, source_compression: Default::default(), function_exports: Default::default(), wit_opts: Default::default(), + js_runtime_config, } } } @@ -71,9 +74,10 @@ impl CodeGen for StaticGenerator { .unwrap() .set_stdin(Box::new(ReadPipe::from(js.as_bytes()))); - WASI.get_mut() - .unwrap() - .push_env("JS_RUNTIME_CONFIG", &Config::all().bits().to_string())?; + WASI.get_mut().unwrap().push_env( + "JS_RUNTIME_CONFIG", + &self.js_runtime_config.bits().to_string(), + )?; }; let wasm = Wizer::new() @@ -143,10 +147,6 @@ impl CodeGen for StaticGenerator { transform::add_producers_section(&mut module.producers); Ok(module.emit_wasm()) } - - fn classify() -> CodeGenType { - CodeGenType::Static - } } fn export_exported_js_functions( diff --git a/crates/cli/src/commands.rs b/crates/cli/src/commands.rs index 045b4244..3c78ce50 100644 --- a/crates/cli/src/commands.rs +++ b/crates/cli/src/commands.rs @@ -1,5 +1,6 @@ use anyhow::{anyhow, bail}; use clap::{Parser, Subcommand}; +use javy_config::Config; use std::{path::PathBuf, str::FromStr}; use crate::codegen::WitOptions; @@ -91,6 +92,16 @@ pub struct BuildCommandOpts { )] /// Codegen options. pub codegen: Vec, + + #[arg( + short = 'J', + long = "js", + long_help = "Available JS runtime options: +-J redirect-stdout-to-stderr[=y|n] -- Redirects console.log to stderr. + " + )] + /// JS runtime options. + pub js_runtime: Vec, } #[derive(Debug, Parser)] @@ -110,6 +121,16 @@ pub struct CodegenOptionGroup { pub source_compression: bool, } +impl Default for CodegenOptionGroup { + fn default() -> Self { + Self { + dynamic: false, + wit: WitOptions::default(), + source_compression: true, + } + } +} + #[derive(Clone, Debug)] pub enum CodegenOption { /// Creates a smaller module that requires a dynamically linked QuickJS provider Wasm @@ -163,24 +184,89 @@ impl TryFrom> for CodegenOptionGroup { type Error = anyhow::Error; fn try_from(value: Vec) -> Result { - let mut dynamic = false; + let mut options = Self::default(); let mut wit = None; let mut wit_world = None; - let mut source_compression = true; for option in value { match option { - CodegenOption::Dynamic(enabled) => dynamic = enabled, + CodegenOption::Dynamic(enabled) => options.dynamic = enabled, CodegenOption::Wit(path) => wit = Some(path), CodegenOption::WitWorld(world) => wit_world = Some(world), - CodegenOption::SourceCompression(enabled) => source_compression = enabled, + CodegenOption::SourceCompression(enabled) => options.source_compression = enabled, } } - Ok(Self { - dynamic, - wit: WitOptions::from_tuple((wit, wit_world))?, - source_compression, - }) + options.wit = WitOptions::from_tuple((wit, wit_world))?; + Ok(options) + } +} + +#[derive(Debug, PartialEq)] +pub struct JsRuntimeOptionGroup { + /// Whether to redirect console.log to stderr. + pub redirect_stdout_to_stderr: bool, +} + +impl Default for JsRuntimeOptionGroup { + fn default() -> Self { + Self { + redirect_stdout_to_stderr: true, + } + } +} + +#[derive(Clone, Debug)] +pub enum JsRuntimeOption { + /// Whether to redirect console.log to stderr. + RedirectStdoutToStderr(bool), +} + +impl FromStr for JsRuntimeOption { + type Err = anyhow::Error; + + fn from_str(s: &str) -> std::result::Result { + let mut parts = s.splitn(2, '='); + let key = parts + .next() + .ok_or_else(|| anyhow!("Invalid JS runtime key"))?; + let value = parts.next(); + let option = match key { + "redirect-stdout-to-stderr" => Self::RedirectStdoutToStderr(match value { + None => true, + Some("y") => true, + Some("n") => false, + _ => bail!("Invalid value for redirect-stdout-to-stderr"), + }), + _ => bail!("Invalid JS runtime key"), + }; + Ok(option) + } +} + +impl From> for JsRuntimeOptionGroup { + fn from(value: Vec) -> Self { + let mut group = Self::default(); + + for option in value { + match option { + JsRuntimeOption::RedirectStdoutToStderr(enabled) => { + group.redirect_stdout_to_stderr = enabled; + } + } + } + + group + } +} + +impl From for Config { + fn from(value: JsRuntimeOptionGroup) -> Self { + let mut config = Self::all(); + config.set( + Config::REDIRECT_STDOUT_TO_STDERR, + value.redirect_stdout_to_stderr, + ); + config } } diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 1c2f1149..103011cf 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -4,12 +4,13 @@ mod commands; mod js; mod wit; -use crate::codegen::{DynamicGenerator, StaticGenerator, WitOptions}; +use crate::codegen::WitOptions; use crate::commands::{Cli, Command, EmitProviderCommandOpts}; -use anyhow::Result; +use anyhow::{bail, Result}; use clap::Parser; use codegen::CodeGenBuilder; -use commands::CodegenOptionGroup; +use commands::{CodegenOptionGroup, JsRuntimeOptionGroup}; +use javy_config::Config; use js::JS; use std::fs; use std::fs::File; @@ -44,9 +45,10 @@ fn main() -> Result<()> { .provider_version("2"); let mut gen = if opts.dynamic { - builder.build::()? + builder.build_dynamic()? } else { - builder.build::()? + let config = Config::all(); + builder.build_static(config)? }; let wasm = gen.generate(&js)?; @@ -63,10 +65,14 @@ fn main() -> Result<()> { .source_compression(codegen.source_compression) .provider_version("2"); + let js_runtime_options: JsRuntimeOptionGroup = opts.js_runtime.clone().into(); let mut gen = if codegen.dynamic { - builder.build::()? + if js_runtime_options != JsRuntimeOptionGroup::default() { + bail!("Cannot set JS runtime options when building a dynamic module"); + } + builder.build_dynamic()? } else { - builder.build::()? + builder.build_static(js_runtime_options.into())? }; let wasm = gen.generate(&js)?; diff --git a/crates/cli/tests/dynamic_linking_test.rs b/crates/cli/tests/dynamic_linking_test.rs index 09880c80..c73e727f 100644 --- a/crates/cli/tests/dynamic_linking_test.rs +++ b/crates/cli/tests/dynamic_linking_test.rs @@ -1,5 +1,5 @@ use anyhow::Result; -use javy_runner::Builder; +use javy_runner::{Builder, JavyCommand}; use std::path::{Path, PathBuf}; use std::str; @@ -152,6 +152,22 @@ fn test_producers_section_present() -> Result<()> { }) } +#[test] +fn test_using_runtime_flag_with_dynamic_triggers_error() -> Result<()> { + let build_result = Builder::default() + .root(root()) + .bin(BIN) + .input("console.js") + .preload("javy_quickjs_provider_v2".into(), provider_module_path()) + .command(JavyCommand::Build) + .redirect_stdout_to_stderr(false) + .build(); + assert!(build_result.is_err_and(|e| e + .to_string() + .contains("Error: Cannot set JS runtime options when building a dynamic module"))); + Ok(()) +} + #[test] // Temporarily ignore given that Javy.JSON is disabled by default. #[ignore] diff --git a/crates/cli/tests/integration_test.rs b/crates/cli/tests/integration_test.rs index 6a697963..1c350dd3 100644 --- a/crates/cli/tests/integration_test.rs +++ b/crates/cli/tests/integration_test.rs @@ -1,5 +1,5 @@ use anyhow::Result; -use javy_runner::{Runner, RunnerError}; +use javy_runner::{Builder, Runner, RunnerError}; use std::path::PathBuf; use std::str; @@ -95,22 +95,59 @@ fn test_encoding() -> Result<()> { } #[test] -fn test_logging() -> Result<()> { - run_with_compile_and_build(|builder| { - let mut runner = builder - .root(sample_scripts()) - .bin(BIN) - .input("logging.js") - .build()?; +fn test_logging_with_compile() -> Result<()> { + let mut runner = Builder::default() + .root(sample_scripts()) + .bin(BIN) + .input("logging.js") + .command(javy_runner::JavyCommand::Compile) + .build()?; + + let (output, logs, fuel_consumed) = run(&mut runner, &[]); + assert!(output.is_empty()); + assert_eq!( + "hello world from console.log\nhello world from console.error\n", + logs.as_str(), + ); + assert_fuel_consumed_within_threshold(34169, fuel_consumed); + Ok(()) +} - let (_output, logs, fuel_consumed) = run(&mut runner, &[]); - assert_eq!( - "hello world from console.log\nhello world from console.error\n", - logs.as_str(), - ); - assert_fuel_consumed_within_threshold(34169, fuel_consumed); - Ok(()) - }) +#[test] +fn test_logging_without_redirect() -> Result<()> { + let mut runner = Builder::default() + .root(sample_scripts()) + .bin(BIN) + .input("logging.js") + .command(javy_runner::JavyCommand::Build) + .redirect_stdout_to_stderr(false) + .build()?; + + let (output, logs, fuel_consumed) = run(&mut runner, &[]); + assert_eq!(b"hello world from console.log\n".to_vec(), output); + assert_eq!("hello world from console.error\n", logs.as_str()); + assert_fuel_consumed_within_threshold(34169, fuel_consumed); + Ok(()) +} + +#[test] +fn test_logging_with_redirect() -> Result<()> { + let mut runner = Builder::default() + .root(sample_scripts()) + .bin(BIN) + .input("logging.js") + .command(javy_runner::JavyCommand::Build) + .redirect_stdout_to_stderr(true) + .build()?; + + let (output, logs, fuel_consumed) = run(&mut runner, &[]); + assert!(output.is_empty()); + assert_eq!( + "hello world from console.log\nhello world from console.error\n", + logs.as_str(), + ); + assert_fuel_consumed_within_threshold(34169, fuel_consumed); + Ok(()) } #[test] diff --git a/crates/runner/src/lib.rs b/crates/runner/src/lib.rs index b6ac3fcc..a54fe505 100644 --- a/crates/runner/src/lib.rs +++ b/crates/runner/src/lib.rs @@ -31,6 +31,8 @@ pub struct Builder { wit: Option, /// The name of the wit world. world: Option, + /// Whether console.log should write to stderr. + redirect_stdout_to_stderr: Option, built: bool, /// Preload the module at path, using the given instance name. preload: Option<(String, PathBuf)>, @@ -49,6 +51,7 @@ impl Default for Builder { built: false, preload: None, command: JavyCommand::Build, + redirect_stdout_to_stderr: None, } } } @@ -84,6 +87,11 @@ impl Builder { self } + pub fn redirect_stdout_to_stderr(&mut self, enabled: bool) -> &mut Self { + self.redirect_stdout_to_stderr = Some(enabled); + self + } + pub fn command(&mut self, command: JavyCommand) -> &mut Self { self.command = command; self @@ -106,6 +114,7 @@ impl Builder { wit, world, root, + redirect_stdout_to_stderr, built: _, preload, command, @@ -121,7 +130,15 @@ impl Builder { Runner::compile_static(bin_path, root, input, wit, world) } } - JavyCommand::Build => Runner::build(bin_path, root, input, wit, world, preload), + JavyCommand::Build => Runner::build( + bin_path, + root, + input, + wit, + world, + redirect_stdout_to_stderr, + preload, + ), } } } @@ -183,6 +200,7 @@ impl Runner { source: impl AsRef, wit: Option, world: Option, + redirect_stdout_to_stderr: Option, preload: Option<(String, PathBuf)>, ) -> Result { // This directory is unique and will automatically get deleted @@ -192,7 +210,14 @@ impl Runner { let js_file = root.join(source); let wit_file = wit.map(|p| root.join(p)); - let args = Self::build_args(&js_file, &wasm_file, &wit_file, &world, preload.is_some()); + let args = Self::build_args( + &js_file, + &wasm_file, + &wit_file, + &world, + preload.is_some(), + &redirect_stdout_to_stderr, + ); Self::exec_command(bin, root, args)?; @@ -380,6 +405,7 @@ impl Runner { wit: &Option, world: &Option, dynamic: bool, + redirect_stdout_to_stderr: &Option, ) -> Vec { let mut args = vec![ "build".to_string(), @@ -400,6 +426,14 @@ impl Runner { args.push("dynamic".to_string()); } + if let Some(redirect_stdout_to_stderr) = *redirect_stdout_to_stderr { + args.push("-J".to_string()); + args.push(format!( + "redirect-stdout-to-stderr={}", + if redirect_stdout_to_stderr { "y" } else { "n" } + )); + } + args } @@ -433,7 +467,11 @@ impl Runner { io::stderr().write_all(&output.stderr)?; if !output.status.success() { - bail!("terminated with status = {}", output.status); + bail!( + "terminated with status = {}, stderr = {}", + output.status, + std::str::from_utf8(&output.stderr).unwrap(), + ); } Ok(()) From 11c3c2f2a6b48de82617a51f923afcf7b2af08ba Mon Sep 17 00:00:00 2001 From: Jeff Charles Date: Tue, 27 Aug 2024 17:35:03 -0400 Subject: [PATCH 2/3] Update fuel targets --- crates/cli/tests/integration_test.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/cli/tests/integration_test.rs b/crates/cli/tests/integration_test.rs index 1c350dd3..dd1f7001 100644 --- a/crates/cli/tests/integration_test.rs +++ b/crates/cli/tests/integration_test.rs @@ -109,7 +109,7 @@ fn test_logging_with_compile() -> Result<()> { "hello world from console.log\nhello world from console.error\n", logs.as_str(), ); - assert_fuel_consumed_within_threshold(34169, fuel_consumed); + assert_fuel_consumed_within_threshold(37309, fuel_consumed); Ok(()) } @@ -126,7 +126,7 @@ fn test_logging_without_redirect() -> Result<()> { let (output, logs, fuel_consumed) = run(&mut runner, &[]); assert_eq!(b"hello world from console.log\n".to_vec(), output); assert_eq!("hello world from console.error\n", logs.as_str()); - assert_fuel_consumed_within_threshold(34169, fuel_consumed); + assert_fuel_consumed_within_threshold(37485, fuel_consumed); Ok(()) } @@ -146,7 +146,7 @@ fn test_logging_with_redirect() -> Result<()> { "hello world from console.log\nhello world from console.error\n", logs.as_str(), ); - assert_fuel_consumed_within_threshold(34169, fuel_consumed); + assert_fuel_consumed_within_threshold(37309, fuel_consumed); Ok(()) } From 490b86b047becb60374a3e6078c756e03a1aebf6 Mon Sep 17 00:00:00 2001 From: Jeff Charles Date: Thu, 29 Aug 2024 11:55:16 -0400 Subject: [PATCH 3/3] Revert to old builder interface except for config --- crates/cli/src/codegen/builder.rs | 24 +++++++++++++++++++----- crates/cli/src/codegen/dynamic.rs | 6 +++++- crates/cli/src/codegen/mod.rs | 11 +++++++++++ crates/cli/src/codegen/static.rs | 6 +++++- crates/cli/src/main.rs | 17 +++++++---------- 5 files changed, 47 insertions(+), 17 deletions(-) diff --git a/crates/cli/src/codegen/builder.rs b/crates/cli/src/codegen/builder.rs index 5bdc68ca..a70f500d 100644 --- a/crates/cli/src/codegen/builder.rs +++ b/crates/cli/src/codegen/builder.rs @@ -1,4 +1,4 @@ -use crate::codegen::{CodeGen, DynamicGenerator, StaticGenerator}; +use crate::codegen::{CodeGen, CodeGenType, DynamicGenerator, StaticGenerator}; use anyhow::{bail, Result}; use javy_config::Config; use std::path::PathBuf; @@ -79,8 +79,23 @@ impl CodeGenBuilder { self } - /// Build a static [`CodeGenerator`]. - pub fn build_static(self, js_runtime_config: Config) -> Result> { + /// Build a [`CodeGenerator`]. + pub fn build(self, js_runtime_config: Config) -> Result> + where + T: CodeGen, + { + match T::classify() { + CodeGenType::Static => self.build_static(js_runtime_config), + CodeGenType::Dynamic => { + if js_runtime_config != Config::all() { + bail!("Cannot set JS runtime options when building a dynamic module") + } + self.build_dynamic() + } + } + } + + fn build_static(self, js_runtime_config: Config) -> Result> { let mut static_gen = Box::new(StaticGenerator::new(js_runtime_config)); static_gen.source_compression = self.source_compression; @@ -89,8 +104,7 @@ impl CodeGenBuilder { Ok(static_gen) } - /// Build a dynamic [`CodeGenerator`]. - pub fn build_dynamic(self) -> Result> { + fn build_dynamic(self) -> Result> { let mut dynamic_gen = Box::new(DynamicGenerator::new()); if let Some(v) = self.provider_version { diff --git a/crates/cli/src/codegen/dynamic.rs b/crates/cli/src/codegen/dynamic.rs index df9fd859..c07b4fb6 100644 --- a/crates/cli/src/codegen/dynamic.rs +++ b/crates/cli/src/codegen/dynamic.rs @@ -1,6 +1,6 @@ use super::transform::{self, SourceCodeSection}; use crate::{ - codegen::{exports, CodeGen, Exports, WitOptions}, + codegen::{exports, CodeGen, CodeGenType, Exports, WitOptions}, js::JS, }; use anyhow::Result; @@ -285,6 +285,10 @@ impl CodeGen for DynamicGenerator { print_wat(&wasm)?; Ok(wasm) } + + fn classify() -> CodeGenType { + CodeGenType::Dynamic + } } #[cfg(feature = "dump_wat")] diff --git a/crates/cli/src/codegen/mod.rs b/crates/cli/src/codegen/mod.rs index 018c1fc6..571f9e87 100644 --- a/crates/cli/src/codegen/mod.rs +++ b/crates/cli/src/codegen/mod.rs @@ -49,9 +49,20 @@ pub(crate) use exports::*; use crate::JS; +pub(crate) enum CodeGenType { + /// Static code generation. + Static, + /// Dynamic code generation. + Dynamic, +} + /// Code generator trait to abstract the multiple JS to Wasm code generation /// paths. pub(crate) trait CodeGen { /// Generate Wasm from a given JS source. fn generate(&mut self, source: &JS) -> anyhow::Result>; + /// Classify the [`CodeGen`] type. + fn classify() -> CodeGenType + where + Self: Sized; } diff --git a/crates/cli/src/codegen/static.rs b/crates/cli/src/codegen/static.rs index 64af9ba5..c43e51f8 100644 --- a/crates/cli/src/codegen/static.rs +++ b/crates/cli/src/codegen/static.rs @@ -12,7 +12,7 @@ use crate::{ codegen::{ exports, transform::{self, SourceCodeSection}, - CodeGen, Exports, WitOptions, + CodeGen, CodeGenType, Exports, WitOptions, }, js::JS, }; @@ -147,6 +147,10 @@ impl CodeGen for StaticGenerator { transform::add_producers_section(&mut module.producers); Ok(module.emit_wasm()) } + + fn classify() -> CodeGenType { + CodeGenType::Static + } } fn export_exported_js_functions( diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 103011cf..fc3ae783 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -6,9 +6,9 @@ mod wit; use crate::codegen::WitOptions; use crate::commands::{Cli, Command, EmitProviderCommandOpts}; -use anyhow::{bail, Result}; +use anyhow::Result; use clap::Parser; -use codegen::CodeGenBuilder; +use codegen::{CodeGenBuilder, DynamicGenerator, StaticGenerator}; use commands::{CodegenOptionGroup, JsRuntimeOptionGroup}; use javy_config::Config; use js::JS; @@ -44,11 +44,11 @@ fn main() -> Result<()> { .source_compression(!opts.no_source_compression) .provider_version("2"); + let config = Config::all(); let mut gen = if opts.dynamic { - builder.build_dynamic()? + builder.build::(config)? } else { - let config = Config::all(); - builder.build_static(config)? + builder.build::(config)? }; let wasm = gen.generate(&js)?; @@ -67,12 +67,9 @@ fn main() -> Result<()> { let js_runtime_options: JsRuntimeOptionGroup = opts.js_runtime.clone().into(); let mut gen = if codegen.dynamic { - if js_runtime_options != JsRuntimeOptionGroup::default() { - bail!("Cannot set JS runtime options when building a dynamic module"); - } - builder.build_dynamic()? + builder.build::(js_runtime_options.into())? } else { - builder.build_static(js_runtime_options.into())? + builder.build::(js_runtime_options.into())? }; let wasm = gen.generate(&js)?;