Skip to content

Commit

Permalink
Added a Boa runtime
Browse files Browse the repository at this point in the history
  • Loading branch information
Razican committed Apr 12, 2023
1 parent 6412b30 commit c2b1334
Show file tree
Hide file tree
Showing 24 changed files with 844 additions and 321 deletions.
240 changes: 135 additions & 105 deletions Cargo.lock

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ members = [
"boa_macros_tests",
"boa_parser",
"boa_profiler",
"boa_runtime",
"boa_tester",
"boa_testing",
"boa_unicode",
"boa_wasm",
]
Expand All @@ -35,6 +37,8 @@ boa_macros = { version = "0.16.0", path = "boa_macros" }
boa_ast = { version = "0.16.0", path = "boa_ast" }
boa_parser = { version = "0.16.0", path = "boa_parser" }
boa_icu_provider = { version = "0.16.0", path = "boa_icu_provider" }
boa_runtime = { version = "0.16.0", path = "boa_runtime" }
boa_testing = { version = "0.16.0", path = "boa_testing" }

[workspace.metadata.workspaces]
allow_branch = "main"
Expand Down
3 changes: 2 additions & 1 deletion boa_cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ repository.workspace = true
rust-version.workspace = true

[dependencies]
boa_engine = { workspace = true, features = ["deser", "console", "flowgraph", "trace", "annex-b"] }
boa_engine = { workspace = true, features = ["deser", "flowgraph", "trace", "annex-b"] }
boa_ast = { workspace = true, features = ["serde"] }
boa_parser.workspace = true
boa_gc.workspace = true
boa_interner.workspace = true
boa_runtime.workspace = true
rustyline = { version = "11.0.0", features = ["derive"]}
clap = { version = "4.2.1", features = ["derive"] }
serde_json = "1.0.95"
Expand Down
13 changes: 13 additions & 0 deletions boa_cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,11 @@ use boa_engine::{
context::ContextBuilder,
job::{FutureJob, JobQueue, NativeJob},
optimizer::OptimizerOptions,
property::Attribute,
vm::flowgraph::{Direction, Graph},
Context, JsResult, Source,
};
use boa_runtime::Console;
use clap::{Parser, ValueEnum, ValueHint};
use colored::{Color, Colorize};
use debug::init_boa_debug_object;
Expand Down Expand Up @@ -311,6 +313,9 @@ fn main() -> Result<(), io::Error> {
// Strict mode
context.strict(args.strict);

// Add `console`.
add_runtime(&mut context);

// Trace Output
context.set_trace(args.trace);

Expand Down Expand Up @@ -404,6 +409,14 @@ fn main() -> Result<(), io::Error> {
Ok(())
}

/// Adds the CLI runtime to the context.
fn add_runtime(context: &mut Context<'_>) {
let console = Console::init(context);
context
.register_global_property(Console::NAME, console, Attribute::all())
.expect("the console object shouldn't exist");
}

#[derive(Default)]
struct Jobs(RefCell<VecDeque<NativeJob>>);

Expand Down
3 changes: 0 additions & 3 deletions boa_engine/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ flowgraph = []
# Enable Boa's VM instruction tracing.
trace = []

# Enable Boa's WHATWG console object implementation.
console = []

# Enable Boa's additional ECMAScript features for web browsers.
annex-b = []

Expand Down
3 changes: 1 addition & 2 deletions boa_engine/src/builtins/function/tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use indoc::indoc;

use crate::{
builtins::error::ErrorKind,
error::JsNativeError,
Expand All @@ -9,6 +7,7 @@ use crate::{
property::{Attribute, PropertyDescriptor},
run_test_actions, JsValue, TestAction,
};
use indoc::indoc;

#[allow(clippy::float_cmp)]
#[test]
Expand Down
20 changes: 0 additions & 20 deletions boa_engine/src/builtins/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
//! Boa's ECMAScript built-in object implementations, e.g. Object, String, Math, Array, etc.
//!
//! This module also contains a JavaScript Console implementation.
pub mod array;
pub mod array_buffer;
Expand Down Expand Up @@ -105,9 +103,6 @@ use crate::{
Context, JsResult, JsString, JsValue,
};

#[cfg(feature = "console")]
use crate::console::Console;

/// A [Well-Known Intrinsic Object].
///
/// Well-known intrinsics are built-in objects that are explicitly referenced by the algorithms of
Expand Down Expand Up @@ -370,21 +365,6 @@ pub(crate) fn set_default_global_bindings(context: &mut Context<'_>) -> JsResult
#[cfg(feature = "intl")]
global_binding::<intl::Intl>(context)?;

#[cfg(feature = "console")]
{
let object = Console::init(context);
let global_object = context.global_object();
global_object.define_property_or_throw(
utf16!("console"),
PropertyDescriptor::builder()
.value(object)
.writable(true)
.enumerable(true)
.configurable(true),
context,
)?;
}

Ok(())
}

Expand Down
17 changes: 15 additions & 2 deletions boa_engine/src/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,8 @@ impl<'host> Context<'host> {

/// Register a global property.
///
/// It will return an error if the property is already defined.
///
/// # Example
/// ```
/// use boa_engine::{
Expand All @@ -310,13 +312,17 @@ impl<'host> Context<'host> {
///
/// let mut context = Context::default();
///
/// context.register_global_property("myPrimitiveProperty", 10, Attribute::all());
/// context
/// .register_global_property("myPrimitiveProperty", 10, Attribute::all())
/// .expect("property shouldn't exist");
///
/// let object = ObjectInitializer::new(&mut context)
/// .property("x", 0, Attribute::all())
/// .property("y", 1, Attribute::all())
/// .build();
/// context.register_global_property("myObjectProperty", object, Attribute::all());
/// context
/// .register_global_property("myObjectProperty", object, Attribute::all())
/// .expect("property shouldn't exist");
/// ```
pub fn register_global_property<K, V>(
&mut self,
Expand Down Expand Up @@ -411,6 +417,8 @@ impl<'host> Context<'host> {

/// Register a global class of type `T`, where `T` implements `Class`.
///
/// It will return an error if the global property is already defined.
///
/// # Example
/// ```ignore
/// #[derive(Debug, Trace, Finalize)]
Expand Down Expand Up @@ -515,6 +523,11 @@ impl<'host> Context<'host> {
self.kept_alive.clear();
}

/// Retrieves the current stack trace of the context.
pub fn stack_trace(&mut self) -> impl Iterator<Item = &CallFrame> {
self.vm.frames.iter().rev()
}

/// Replaces the currently active realm with `realm`, and returns the old realm.
pub fn enter_realm(&mut self, realm: Realm) -> Realm {
self.vm
Expand Down
45 changes: 16 additions & 29 deletions boa_engine/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
//! # Crate Features
//!
//! - **serde** - Enables serialization and deserialization of the AST (Abstract Syntax Tree).
//! - **console** - Enables `boa`'s [WHATWG `console`][whatwg] object implementation.
//! - **profiler** - Enables profiling with measureme (this is mostly internal).
//! - **intl** - Enables `boa`'s [ECMA-402 Internationalization API][ecma-402] (`Intl` object)
//!
Expand All @@ -56,7 +55,6 @@
//! - **`boa_unicode`** - Boa's Unicode identifier.
//! - **`boa_icu_provider`** - Boa's ICU4X data provider.
//!
//! [whatwg]: https://console.spec.whatwg.org
//! [ecma-402]: https://tc39.es/ecma402
//! [boa-conformance]: https://boajs.dev/boa/test262/
//! [boa-web]: https://boajs.dev/
Expand Down Expand Up @@ -151,21 +149,16 @@ pub mod error;
pub mod job;
pub mod native_function;
pub mod object;
pub mod optimizer;
pub mod property;
pub mod realm;
pub mod string;
pub mod symbol;
pub mod value;
pub mod vm;

pub mod optimizer;

#[cfg(feature = "console")]
pub mod console;

pub(crate) mod tagged;
mod tagged;
#[cfg(test)]
mod tests;
pub mod value;
pub mod vm;

/// A convenience module that re-exports the most commonly-used Boa APIs
pub mod prelude {
Expand Down Expand Up @@ -225,7 +218,7 @@ use std::borrow::Cow;
/// A test action executed in a test function.
#[cfg(test)]
#[derive(Clone)]
pub(crate) struct TestAction(Inner);
struct TestAction(Inner);

#[cfg(test)]
#[derive(Clone)]
Expand Down Expand Up @@ -265,12 +258,12 @@ enum Inner {
#[cfg(test)]
impl TestAction {
/// Evaluates some utility functions used in tests.
pub(crate) const fn run_harness() -> Self {
const fn run_harness() -> Self {
Self(Inner::RunHarness)
}

/// Runs `source`, panicking if the execution throws.
pub(crate) fn run(source: impl Into<Cow<'static, str>>) -> Self {
fn run(source: impl Into<Cow<'static, str>>) -> Self {
Self(Inner::Run {
source: source.into(),
})
Expand All @@ -279,22 +272,19 @@ impl TestAction {
/// Executes `op` with the currently active context.
///
/// Useful to make custom assertions that must be done from Rust code.
pub(crate) fn inspect_context(op: fn(&mut Context<'_>)) -> Self {
fn inspect_context(op: fn(&mut Context<'_>)) -> Self {
Self(Inner::InspectContext { op })
}

/// Asserts that evaluating `source` returns the `true` value.
pub(crate) fn assert(source: impl Into<Cow<'static, str>>) -> Self {
fn assert(source: impl Into<Cow<'static, str>>) -> Self {
Self(Inner::Assert {
source: source.into(),
})
}

/// Asserts that the script returns `expected` when evaluating `source`.
pub(crate) fn assert_eq(
source: impl Into<Cow<'static, str>>,
expected: impl Into<JsValue>,
) -> Self {
fn assert_eq(source: impl Into<Cow<'static, str>>, expected: impl Into<JsValue>) -> Self {
Self(Inner::AssertEq {
source: source.into(),
expected: expected.into(),
Expand All @@ -304,7 +294,7 @@ impl TestAction {
/// Asserts that calling `op` with the value obtained from evaluating `source` returns `true`.
///
/// Useful to check properties of the obtained value that cannot be checked from JS code.
pub(crate) fn assert_with_op(
fn assert_with_op(
source: impl Into<Cow<'static, str>>,
op: fn(JsValue, &mut Context<'_>) -> bool,
) -> Self {
Expand All @@ -315,7 +305,7 @@ impl TestAction {
}

/// Asserts that evaluating `source` throws the opaque error `value`.
pub(crate) fn assert_opaque_error(
fn assert_opaque_error(
source: impl Into<Cow<'static, str>>,
value: impl Into<JsValue>,
) -> Self {
Expand All @@ -326,7 +316,7 @@ impl TestAction {
}

/// Asserts that evaluating `source` throws a native error of `kind` and `message`.
pub(crate) fn assert_native_error(
fn assert_native_error(
source: impl Into<Cow<'static, str>>,
kind: builtins::error::ErrorKind,
message: &'static str,
Expand All @@ -339,26 +329,23 @@ impl TestAction {
}

/// Asserts that calling `op` with the currently executing context returns `true`.
pub(crate) fn assert_context(op: fn(&mut Context<'_>) -> bool) -> Self {
fn assert_context(op: fn(&mut Context<'_>) -> bool) -> Self {
Self(Inner::AssertContext { op })
}
}

/// Executes a list of test actions on a new, default context.
#[cfg(test)]
#[track_caller]
pub(crate) fn run_test_actions(actions: impl IntoIterator<Item = TestAction>) {
fn run_test_actions(actions: impl IntoIterator<Item = TestAction>) {
let context = &mut Context::default();
run_test_actions_with(actions, context);
}

/// Executes a list of test actions on the provided context.
#[cfg(test)]
#[track_caller]
pub(crate) fn run_test_actions_with(
actions: impl IntoIterator<Item = TestAction>,
context: &mut Context<'_>,
) {
fn run_test_actions_with(actions: impl IntoIterator<Item = TestAction>, context: &mut Context<'_>) {
#[track_caller]
fn forward_val(context: &mut Context<'_>, source: &str) -> JsResult<JsValue> {
context.eval_script(Source::from_bytes(source))
Expand Down
Loading

0 comments on commit c2b1334

Please sign in to comment.