Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch to rquickjs #618

Merged
merged 23 commits into from
May 2, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
7b08602
chore: Initial migration to rquickjs
saulecabrera Mar 6, 2024
300c3ca
More progress on migration:
saulecabrera Mar 19, 2024
878ddd5
Migrate all of the APIs to use rquickjs
saulecabrera Apr 5, 2024
2c4b52b
Finalize migration of the toolchain as a whole
saulecabrera Apr 11, 2024
b0d8285
Rebase
saulecabrera Apr 11, 2024
a126ede
Uncomment integration tests
saulecabrera Apr 11, 2024
85abf57
Throw `TypeError` when `fatal` decoding is specified.
saulecabrera Apr 11, 2024
2bea077
Fix clippy errors
saulecabrera Apr 11, 2024
d599ed4
Update documentation where applicable and remove reference to older c…
saulecabrera Apr 11, 2024
b255b55
Handle converting from JS strings to Rust strings for text encoding
saulecabrera Apr 12, 2024
c039625
Migrate serializers and deserializers to use rquickjs and move them u…
saulecabrera Apr 16, 2024
7e4ec6f
Move quickcheck to the top level Cargo.toml
saulecabrera Apr 16, 2024
9af48b0
Update versions and CHANGELOGs
saulecabrera Apr 16, 2024
cdcac4d
Audit dependencies
saulecabrera Apr 16, 2024
9eec07b
Improve safety comment
saulecabrera Apr 16, 2024
055de24
Port previous implementation of read sync
saulecabrera Apr 16, 2024
2aa4f6f
Review comments
saulecabrera Apr 16, 2024
29361f3
Improve comment for why `ManuallyDrop`
saulecabrera Apr 16, 2024
5fbcf8a
Use `ManuallyDrop` for Context
saulecabrera Apr 23, 2024
6d7fec5
Format comments where applicable
saulecabrera Apr 23, 2024
5b2f0ad
Use rquickjs 0.6.0 through a fork
saulecabrera May 1, 2024
3b0d041
Cargo vet config
saulecabrera May 1, 2024
d51ae19
Remove comment, cargo vet doesn't like them
saulecabrera May 1, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 74 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 2 additions & 4 deletions crates/apis/src/random/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,8 @@ mod tests {
let runtime = Runtime::default();
Random.register(&runtime, &APIConfig::default())?;
runtime.context().with(|this| {
let eval_opts = EvalOptions {
strict: false,
..Default::default()
};
let mut eval_opts = EvalOptions::default();
eval_opts.strict = false;
this.eval_with_options("result = Math.random()", eval_opts)?;
let result: f64 = this
.globals()
Expand Down
6 changes: 2 additions & 4 deletions crates/apis/src/text_encoding/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,8 @@ impl JSApiSet for TextEncoding {
encode(hold!(cx.clone(), args)).map_err(|e| to_js_error(cx, e))
}),
)?;
let opts = EvalOptions {
strict: false,
..Default::default()
};
let mut opts = EvalOptions::default();
opts.strict = false;
this.eval_with_options(include_str!("./text-encoding.js"), opts)?;

Ok::<_, Error>(())
Expand Down
14 changes: 7 additions & 7 deletions crates/cli/tests/integration_test.rs
saulecabrera marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ fn test_identity() {

let (output, _, fuel_consumed) = run_with_u8s(&mut runner, 42);
assert_eq!(42, output);
assert_fuel_consumed_within_threshold(37907, fuel_consumed);
assert_fuel_consumed_within_threshold(43239, fuel_consumed);
}

#[test]
Expand Down Expand Up @@ -46,7 +46,7 @@ fn test_encoding() {

let (output, _, fuel_consumed) = run(&mut runner, "hello".as_bytes());
assert_eq!("el".as_bytes(), output);
assert_fuel_consumed_within_threshold(258_852, fuel_consumed);
assert_fuel_consumed_within_threshold(218_527, fuel_consumed);

let (output, _, _) = run(&mut runner, "invalid".as_bytes());
assert_eq!("true".as_bytes(), output);
Expand All @@ -67,7 +67,7 @@ fn test_logging() {
"hello world from console.log\nhello world from console.error\n",
logs.as_str(),
);
assert_fuel_consumed_within_threshold(22_296, fuel_consumed);
assert_fuel_consumed_within_threshold(34169, fuel_consumed);
}

#[test]
Expand All @@ -76,7 +76,7 @@ fn test_readme_script() {

let (output, _, fuel_consumed) = run(&mut runner, r#"{ "n": 2, "bar": "baz" }"#.as_bytes());
assert_eq!(r#"{"foo":3,"newBar":"baz!"}"#.as_bytes(), output);
assert_fuel_consumed_within_threshold(284_736, fuel_consumed);
assert_fuel_consumed_within_threshold(235_476, fuel_consumed);
}

#[cfg(feature = "experimental_event_loop")]
Expand Down Expand Up @@ -106,7 +106,7 @@ fn test_exported_functions() {
let mut runner = Runner::new_with_exports("exported-fn.js", "exported-fn.wit", "exported-fn");
let (_, logs, fuel_consumed) = run_fn(&mut runner, "foo", &[]);
assert_eq!("Hello from top-level\nHello from foo\n", logs);
assert_fuel_consumed_within_threshold(54610, fuel_consumed);
assert_fuel_consumed_within_threshold(72552, fuel_consumed);
let (_, logs, _) = run_fn(&mut runner, "foo-bar", &[]);
assert_eq!("Hello from top-level\nHello from fooBar\n", logs);
}
Expand Down Expand Up @@ -180,7 +180,7 @@ fn test_exported_default_arrow_fn() {
);
let (_, logs, fuel_consumed) = run_fn(&mut runner, "default", &[]);
assert_eq!(logs, "42\n");
assert_fuel_consumed_within_threshold(48_628, fuel_consumed);
assert_fuel_consumed_within_threshold(67547, fuel_consumed);
}

#[test]
Expand All @@ -192,7 +192,7 @@ fn test_exported_default_fn() {
);
let (_, logs, fuel_consumed) = run_fn(&mut runner, "default", &[]);
assert_eq!(logs, "42\n");
assert_fuel_consumed_within_threshold(49_748, fuel_consumed);
assert_fuel_consumed_within_threshold(67792, fuel_consumed);
}

fn run_with_u8s(r: &mut Runner, stdin: u8) -> (u8, String, u64) {
Expand Down
44 changes: 27 additions & 17 deletions crates/core/src/execution.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,40 @@
use std::process;

use anyhow::{bail, Error, Result};
use anyhow::{anyhow, bail, Error, Result};
use javy::{
from_js_error,
quickjs::{context::EvalOptions, Module, Value},
Runtime,
to_js_error, Runtime,
};

static EVENT_LOOP_ERR: &str = r#"
Pending jobs in the event queue.
Scheduling events is not supported when the
experimental_event_loop cargo feature is disabled.
"#;

/// Evaluate the given bytecode.
///
/// Evaluating also prepares (or "instantiates") the state of the JavaScript
/// engine given all the information encoded in the bytecode.
pub fn run_bytecode(runtime: &Runtime, bytecode: &[u8]) {
runtime
.context()
.with(|this| Module::instantiate_read_object(this, bytecode).map(|_| ()))
.with(|this| {
let module = unsafe { Module::load(this.clone(), bytecode)? };
let (_, promise) = module.eval()?;

if cfg!(feature = "experimental_event_loop") {
// If the experimental event loop is enabled, trigger it.
promise.finish::<Value>().map(|_| ())
saulecabrera marked this conversation as resolved.
Show resolved Hide resolved
} else {
// Else we simply expect the promise to resolve immediately.
match promise.result() {
None => Err(to_js_error(this, anyhow!(EVENT_LOOP_ERR))),
Some(r) => r,
}
}
})
.map_err(|e| runtime.context().with(|cx| from_js_error(cx.clone(), e)))
// Prefer calling `process_event_loop` *outside* of the `with` callback,
// to avoid errors regarding multiple mutable borrows.
Expand All @@ -38,13 +58,9 @@ pub fn invoke_function(runtime: &Runtime, fn_module: &str, fn_name: &str) {
runtime
.context()
.with(|this| {
let opts = EvalOptions {
strict: false,
// We're assuming imports and exports, therefore we want to evaluate
// as a module.
global: false,
..Default::default()
};
let mut opts = EvalOptions::default();
opts.strict = false;
opts.global = false;
this.eval_with_options::<Value<'_>, _>(js, opts)
.map_err(|e| from_js_error(this.clone(), e))
.map(|_| ())
Expand All @@ -57,13 +73,7 @@ fn process_event_loop(rt: &Runtime) -> Result<()> {
if cfg!(feature = "experimental_event_loop") {
rt.resolve_pending_jobs()?
} else if rt.has_pending_jobs() {
bail!(
r#"
Pending jobs in the event queue.
Scheduling events is not supported when the
experimental_event_loop cargo feature is disabled.
"#
);
bail!(EVENT_LOOP_ERR);
}

Ok(())
Expand Down
2 changes: 1 addition & 1 deletion crates/javy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ categories = ["wasm"]

[dependencies]
anyhow = { workspace = true }
rquickjs = { version = "0.5.1", features = ["array-buffer"] }
rquickjs = { git = "https://github.com/Shopify/rquickjs", branch = "improved-wasm-support", features = ["array-buffer", "bindgen", "no-free"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1.0", optional = true }
serde-transcode = { version = "1.1", optional = true }
Expand Down
4 changes: 1 addition & 3 deletions crates/javy/src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,7 @@ impl Runtime {
/// Compiles the given module to bytecode.
pub fn compile_to_bytecode(&self, name: &str, contents: &str) -> Result<Vec<u8>> {
self.context()
.with(|this| {
unsafe { Module::unsafe_declare(this.clone(), name, contents) }?.write_object_le()
})
.with(|this| Module::declare(this.clone(), name, contents)?.write_le())
.map_err(|e| self.context().with(|cx| from_js_error(cx.clone(), e)))
}
}
Expand Down
Loading