From cdbed8d730d922131a32512f9456883f247a2a00 Mon Sep 17 00:00:00 2001 From: "Iban Eguia (Razican)" Date: Sun, 30 May 2021 22:57:08 +0200 Subject: [PATCH 1/4] Added the $262 object to Test262 test runner --- boa_tester/src/exec/js262.rs | 70 +++++++++++++++++++++++++ boa_tester/src/{exec.rs => exec/mod.rs} | 7 ++- 2 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 boa_tester/src/exec/js262.rs rename boa_tester/src/{exec.rs => exec/mod.rs} (99%) diff --git a/boa_tester/src/exec/js262.rs b/boa_tester/src/exec/js262.rs new file mode 100644 index 00000000000..9d2f9e71fa2 --- /dev/null +++ b/boa_tester/src/exec/js262.rs @@ -0,0 +1,70 @@ +use boa::{object::ObjectInitializer, property::Attribute, Context, Result, Value}; + +/// The `$262.createRealm()` function. +/// +/// Creates a new ECMAScript Realm, defines this API on the new realm's global object, and +/// returns the `$262` property of the new realm's global object. +#[allow(dead_code)] +fn create_realm(_this: &Value, _: &[Value], _context: &mut Context) -> Result { + todo!() +} + +/// The `$262.detachArrayBuffer()` function. +/// +/// Implements the `DetachArrayBuffer` abstract operation. +#[allow(dead_code)] +fn detach_array_buffer(_this: &Value, _: &[Value], _context: &mut Context) -> Result { + todo!() +} + +/// The `$262.evalScript()` function. +/// +/// Accepts a string value as its first argument and executes it as an ECMAScript script. +#[allow(dead_code)] +fn eval_script(_this: &Value, _: &[Value], _context: &mut Context) -> Result { + todo!() +} + +/// The `$262.gc()` function. +/// +/// Wraps the host's garbage collection invocation mechanism, if such a capability exists. +/// Must throw an exception if no capability exists. This is necessary for testing the +/// semantics of any feature that relies on garbage collection, e.g. the `WeakRef` API. +#[allow(dead_code)] +fn gc(_this: &Value, _: &[Value], _context: &mut Context) -> Result { + todo!() +} + +/// The `$262.global()` function. +/// +/// Returns a reference to the global object on which `$262` was initially defined. +fn global(_this: &Value, _: &[Value], context: &mut Context) -> Result { + Ok(Value::from(context.global_object())) +} + +/// Initializes the object in the context. +pub(super) fn init_262(context: &mut Context) { + let object = ObjectInitializer::new(context) + //.function(Self::create_realm, "createRealm", 0) + //.function(Self::detach_array_buffer, "detachArrayBuffer", 0) + //.function(Self::eval_script, "evalScript", 1) + //.function(Self::gc, "gc", 0) + .function(global, "global", 0) + // .property( + // "IsHTMLDDA", + // is_html_dda, + // Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::PERMANENT, + // ) + // .property( + // "agent", + // agent, + // Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::PERMANENT, + // ) + .build(); + + context.register_global_property( + "$262", + object, + Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::PERMANENT, + ); +} diff --git a/boa_tester/src/exec.rs b/boa_tester/src/exec/mod.rs similarity index 99% rename from boa_tester/src/exec.rs rename to boa_tester/src/exec/mod.rs index 311844e73b1..36a1559d235 100644 --- a/boa_tester/src/exec.rs +++ b/boa_tester/src/exec/mod.rs @@ -1,5 +1,8 @@ //! Execution module for the test runner. +mod js262; + +use self::js262::init_262; use super::{ Harness, Outcome, Phase, SuiteResult, Test, TestFlags, TestOutcomeResult, TestResult, TestSuite, IGNORED, @@ -272,7 +275,9 @@ impl Test { e.display() ) })?; - // TODO: add the $262 object. + + // add the $262 object. + init_262(&mut context); if strict { context From ea1a4d38b3237e956339000b0f3d085fa7eaf215 Mon Sep 17 00:00:00 2001 From: "Iban Eguia (Razican)" Date: Mon, 31 May 2021 22:27:57 +0200 Subject: [PATCH 2/4] Added some extra functionality, fixed the `global` attribute --- Cargo.lock | 1 + boa/src/object/internal_methods.rs | 4 +- boa_tester/Cargo.toml | 1 + boa_tester/src/exec/agent.rs | 43 ++++++++++++++++ boa_tester/src/exec/js262.rs | 83 ++++++++++++++++-------------- boa_tester/src/exec/mod.rs | 6 +-- 6 files changed, 93 insertions(+), 45 deletions(-) create mode 100644 boa_tester/src/exec/agent.rs diff --git a/Cargo.lock b/Cargo.lock index 1218255921d..9a74c4580c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -99,6 +99,7 @@ dependencies = [ "bitflags", "colored", "fxhash", + "gc", "git2", "hex", "num-format", diff --git a/boa/src/object/internal_methods.rs b/boa/src/object/internal_methods.rs index 0e522e3a5e0..f32220d8885 100644 --- a/boa/src/object/internal_methods.rs +++ b/boa/src/object/internal_methods.rs @@ -593,7 +593,7 @@ impl GcObject { /// If a field was already in the object with the same name that a `Some` is returned /// with that field, otherwise None is returned. #[inline] - pub(crate) fn insert_property( + pub fn insert_property( &mut self, key: K, value: V, @@ -711,7 +711,7 @@ impl Object { /// If a field was already in the object with the same name that a `Some` is returned /// with that field, otherwise None is retuned. #[inline] - pub(crate) fn insert_property( + pub fn insert_property( &mut self, key: K, value: V, diff --git a/boa_tester/Cargo.toml b/boa_tester/Cargo.toml index 60ebe06b6c1..ab15e6f309f 100644 --- a/boa_tester/Cargo.toml +++ b/boa_tester/Cargo.toml @@ -24,3 +24,4 @@ fxhash = "0.2.1" git2 = "0.13.20" hex = "0.4.3" num-format = "0.4.0" +gc = { version = "0.4.1", features = ["derive"] } diff --git a/boa_tester/src/exec/agent.rs b/boa_tester/src/exec/agent.rs new file mode 100644 index 00000000000..25a48734f9c --- /dev/null +++ b/boa_tester/src/exec/agent.rs @@ -0,0 +1,43 @@ +use boa::{ + object::{GcObject, ObjectInitializer}, + Context, Result, Value, +}; + +/// Creates the `agent` object. +pub(super) fn init(context: &mut Context) -> GcObject { + ObjectInitializer::new(context) + // .function(start, "start", 1) + // .function(broadcast, "broadcast", 2) + // .function(get_report, "getReport", 0) + .function(sleep, "sleep", 1) + // .function(monotonic_now, "monotonicNow", 1) + .build() +} + +/// Creates the "receiver" `agent` object. +#[allow(dead_code)] +pub(super) fn init_receiver(context: &mut Context) -> GcObject { + ObjectInitializer::new(context) + // .function(receive_broadcast, "receiveBroadcast", 1) + // .function(report, "report", 1) + .function(sleep, "sleep", 1) + // .function(leaving, "leaving", 0) + // .function(monotonic_now, "monotonicNow", 1) + .build() +} + +/// Takes a script source string and runs the script in a concurrent agent. Will block until that agent is running. +#[allow(dead_code)] +fn start(_this: &Value, _args: &[Value], _context: &mut Context) -> Result { + todo!() +} + +/// Takes a millisecond argument and sleeps the execution for approximately that duration. +fn sleep(_this: &Value, args: &[Value], context: &mut Context) -> Result { + use std::time::Duration; + + let milliseconds = args.get(0).cloned().unwrap_or_default().to_u32(context)?; + std::thread::sleep(Duration::from_millis(u64::from(milliseconds))); + + Ok(Value::default()) +} diff --git a/boa_tester/src/exec/js262.rs b/boa_tester/src/exec/js262.rs index 9d2f9e71fa2..cb805c0c3c8 100644 --- a/boa_tester/src/exec/js262.rs +++ b/boa_tester/src/exec/js262.rs @@ -1,12 +1,40 @@ -use boa::{object::ObjectInitializer, property::Attribute, Context, Result, Value}; +use boa::{ + exec::Executable, + object::{GcObject, ObjectInitializer}, + property::Attribute, + Context, Result, Value, +}; + +/// Initializes the object in the context. +pub(super) fn init(context: &mut Context, agent: GcObject) -> GcObject { + let global_obj = context.global_object(); + + let obj = ObjectInitializer::new(context) + .function(create_realm, "createRealm", 0) + .function(eval_script, "evalScript", 1) + .property("global", global_obj, Attribute::default()) + .property("agent", agent, Attribute::default()) + .build(); + + context.register_global_property("$262", obj.clone(), Attribute::default()); + + obj +} /// The `$262.createRealm()` function. /// /// Creates a new ECMAScript Realm, defines this API on the new realm's global object, and /// returns the `$262` property of the new realm's global object. -#[allow(dead_code)] fn create_realm(_this: &Value, _: &[Value], _context: &mut Context) -> Result { - todo!() + // eprintln!("called $262.createRealm()"); + + let mut context = Context::new(); + + // add the $262 object. + let agent = super::agent::init(&mut context); + let js_262 = init(&mut context, agent); + + Ok(Value::from(js_262)) } /// The `$262.detachArrayBuffer()` function. @@ -20,9 +48,18 @@ fn detach_array_buffer(_this: &Value, _: &[Value], _context: &mut Context) -> Re /// The `$262.evalScript()` function. /// /// Accepts a string value as its first argument and executes it as an ECMAScript script. -#[allow(dead_code)] -fn eval_script(_this: &Value, _: &[Value], _context: &mut Context) -> Result { - todo!() +fn eval_script(_this: &Value, args: &[Value], context: &mut Context) -> Result { + // eprintln!("called $262.evalScript()"); + + if let Some(source_text) = args.get(0).and_then(|val| val.as_string()) { + match boa::parse(source_text.as_str(), false) { + // TODO: check strict + Err(e) => context.throw_type_error(format!("Uncaught Syntax Error: {}", e)), + Ok(script) => script.run(context), + } + } else { + Ok(Value::undefined()) + } } /// The `$262.gc()` function. @@ -34,37 +71,3 @@ fn eval_script(_this: &Value, _: &[Value], _context: &mut Context) -> Result Result { todo!() } - -/// The `$262.global()` function. -/// -/// Returns a reference to the global object on which `$262` was initially defined. -fn global(_this: &Value, _: &[Value], context: &mut Context) -> Result { - Ok(Value::from(context.global_object())) -} - -/// Initializes the object in the context. -pub(super) fn init_262(context: &mut Context) { - let object = ObjectInitializer::new(context) - //.function(Self::create_realm, "createRealm", 0) - //.function(Self::detach_array_buffer, "detachArrayBuffer", 0) - //.function(Self::eval_script, "evalScript", 1) - //.function(Self::gc, "gc", 0) - .function(global, "global", 0) - // .property( - // "IsHTMLDDA", - // is_html_dda, - // Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::PERMANENT, - // ) - // .property( - // "agent", - // agent, - // Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::PERMANENT, - // ) - .build(); - - context.register_global_property( - "$262", - object, - Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::PERMANENT, - ); -} diff --git a/boa_tester/src/exec/mod.rs b/boa_tester/src/exec/mod.rs index 36a1559d235..93539d07fec 100644 --- a/boa_tester/src/exec/mod.rs +++ b/boa_tester/src/exec/mod.rs @@ -1,8 +1,8 @@ //! Execution module for the test runner. +mod agent; mod js262; -use self::js262::init_262; use super::{ Harness, Outcome, Phase, SuiteResult, Test, TestFlags, TestOutcomeResult, TestResult, TestSuite, IGNORED, @@ -263,7 +263,6 @@ impl Test { /// Sets the environment up to run the test. fn set_up_env(&self, harness: &Harness, strict: bool) -> Result { // Create new Realm - // TODO: in parallel. let mut context = Context::new(); // Register the print() function. @@ -277,7 +276,8 @@ impl Test { })?; // add the $262 object. - init_262(&mut context); + let agent = agent::init(&mut context); + let _ = js262::init(&mut context, agent); if strict { context From a80687f79a1d3a5def4eb9e544771d8787511bad Mon Sep 17 00:00:00 2001 From: "Iban Eguia (Razican)" Date: Mon, 31 May 2021 22:30:03 +0200 Subject: [PATCH 3/4] Updated dependencies --- Cargo.lock | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9a74c4580c4..72257b997db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -141,9 +141,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.6.1" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe" +checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" [[package]] name = "byteorder" @@ -162,9 +162,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.67" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" +checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787" dependencies = [ "jobserver", ] @@ -284,9 +284,9 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52fb27eab85b17fbb9f6fd667089e07d6a2eb8743d02639ee7f6a7a7729c9c94" +checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" dependencies = [ "cfg-if", "crossbeam-utils", @@ -297,11 +297,10 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4feb231f0d4d6af81aed15928e58ecf5816aa62a2393e2c82f46973e92a9a278" +checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" dependencies = [ - "autocfg", "cfg-if", "lazy_static", ] @@ -613,9 +612,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.94" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e" +checksum = "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36" [[package]] name = "libgit2-sys" @@ -709,18 +708,18 @@ checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" [[package]] name = "memmap2" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "397d1a6d6d0563c0f5462bbdae662cf6c784edf5e828e40c7257f85d82bf56dd" +checksum = "723e3ebdcdc5c023db1df315364573789f8857c11b631a2fdfad7c00f5c046b4" dependencies = [ "libc", ] [[package]] name = "memoffset" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83fb6581e8ed1f85fd45c116db8405483899489e38406156c25eb743554361d" +checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" dependencies = [ "autocfg", ] @@ -1374,9 +1373,9 @@ checksum = "07547e3ee45e28326cc23faac56d44f58f16ab23e413db526debce3b0bfd2742" [[package]] name = "unicode-normalization" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07fbfce1c8a97d547e8b5334978438d9d6ec8c20e38f56d4a4374d181493eaef" +checksum = "33717dca7ac877f497014e10d73f3acf948c342bee31b5ca7892faf94ccc6b49" dependencies = [ "tinyvec", ] From ea4975a1f6461b0eae6bb13732b69ebb8a5f6460 Mon Sep 17 00:00:00 2001 From: "Iban Eguia (Razican)" Date: Tue, 1 Jun 2021 16:09:44 +0200 Subject: [PATCH 4/4] Removed the `agent` --- boa_tester/src/exec/agent.rs | 43 ------------------------------------ boa_tester/src/exec/js262.rs | 7 +++--- boa_tester/src/exec/mod.rs | 4 +--- 3 files changed, 4 insertions(+), 50 deletions(-) delete mode 100644 boa_tester/src/exec/agent.rs diff --git a/boa_tester/src/exec/agent.rs b/boa_tester/src/exec/agent.rs deleted file mode 100644 index 25a48734f9c..00000000000 --- a/boa_tester/src/exec/agent.rs +++ /dev/null @@ -1,43 +0,0 @@ -use boa::{ - object::{GcObject, ObjectInitializer}, - Context, Result, Value, -}; - -/// Creates the `agent` object. -pub(super) fn init(context: &mut Context) -> GcObject { - ObjectInitializer::new(context) - // .function(start, "start", 1) - // .function(broadcast, "broadcast", 2) - // .function(get_report, "getReport", 0) - .function(sleep, "sleep", 1) - // .function(monotonic_now, "monotonicNow", 1) - .build() -} - -/// Creates the "receiver" `agent` object. -#[allow(dead_code)] -pub(super) fn init_receiver(context: &mut Context) -> GcObject { - ObjectInitializer::new(context) - // .function(receive_broadcast, "receiveBroadcast", 1) - // .function(report, "report", 1) - .function(sleep, "sleep", 1) - // .function(leaving, "leaving", 0) - // .function(monotonic_now, "monotonicNow", 1) - .build() -} - -/// Takes a script source string and runs the script in a concurrent agent. Will block until that agent is running. -#[allow(dead_code)] -fn start(_this: &Value, _args: &[Value], _context: &mut Context) -> Result { - todo!() -} - -/// Takes a millisecond argument and sleeps the execution for approximately that duration. -fn sleep(_this: &Value, args: &[Value], context: &mut Context) -> Result { - use std::time::Duration; - - let milliseconds = args.get(0).cloned().unwrap_or_default().to_u32(context)?; - std::thread::sleep(Duration::from_millis(u64::from(milliseconds))); - - Ok(Value::default()) -} diff --git a/boa_tester/src/exec/js262.rs b/boa_tester/src/exec/js262.rs index cb805c0c3c8..67168a311d2 100644 --- a/boa_tester/src/exec/js262.rs +++ b/boa_tester/src/exec/js262.rs @@ -6,14 +6,14 @@ use boa::{ }; /// Initializes the object in the context. -pub(super) fn init(context: &mut Context, agent: GcObject) -> GcObject { +pub(super) fn init(context: &mut Context) -> GcObject { let global_obj = context.global_object(); let obj = ObjectInitializer::new(context) .function(create_realm, "createRealm", 0) .function(eval_script, "evalScript", 1) .property("global", global_obj, Attribute::default()) - .property("agent", agent, Attribute::default()) + // .property("agent", agent, Attribute::default()) .build(); context.register_global_property("$262", obj.clone(), Attribute::default()); @@ -31,8 +31,7 @@ fn create_realm(_this: &Value, _: &[Value], _context: &mut Context) -> Result