diff --git a/boa_engine/src/builtins/array/tests.rs b/boa_engine/src/builtins/array/tests.rs index 42d0e492188..71b7b39f3ec 100644 --- a/boa_engine/src/builtins/array/tests.rs +++ b/boa_engine/src/builtins/array/tests.rs @@ -1,8 +1,5 @@ use super::Array; -use crate::{ - builtins::{error::ErrorKind, Number}, - run_test_actions, Context, JsValue, TestAction, -}; +use crate::{builtins::Number, run_test_actions, Context, JsNativeErrorKind, JsValue, TestAction}; use indoc::indoc; #[test] @@ -191,7 +188,7 @@ fn flat_map_not_callable() { var array = [1,2,3]; array.flatMap("not a function"); "#}, - ErrorKind::Type, + JsNativeErrorKind::Type, "flatMap mapper function is not callable", )]); } @@ -639,7 +636,7 @@ fn reduce() { // Empty array TestAction::assert_native_error( "[].reduce((acc, x) => acc + x);", - ErrorKind::Type, + JsNativeErrorKind::Type, "Array.prototype.reduce: called on an empty array and with no initial value", ), // Array with no defined elements @@ -650,7 +647,7 @@ fn reduce() { delete deleteArr[1]; deleteArr.reduce((acc, x) => acc + x); "#}, - ErrorKind::Type, + JsNativeErrorKind::Type, "Array.prototype.reduce: called on an empty array and with no initial value", ), // No callback @@ -659,7 +656,7 @@ fn reduce() { var someArr = [0, 1]; someArr.reduce(''); "#}, - ErrorKind::Type, + JsNativeErrorKind::Type, "Array.prototype.reduce: callback function is not callable", ), ]); @@ -720,7 +717,7 @@ fn reduce_right() { // Empty array TestAction::assert_native_error( "[].reduceRight((acc, x) => acc + x);", - ErrorKind::Type, + JsNativeErrorKind::Type, "Array.prototype.reduceRight: called on an empty array and with no initial value", ), // Array with no defined elements @@ -731,7 +728,7 @@ fn reduce_right() { delete deleteArr[1]; deleteArr.reduceRight((acc, x) => acc + x); "#}, - ErrorKind::Type, + JsNativeErrorKind::Type, "Array.prototype.reduceRight: called on an empty array and with no initial value", ), // No callback @@ -740,7 +737,7 @@ fn reduce_right() { var otherArr = [0, 1]; otherArr.reduceRight(""); "#}, - ErrorKind::Type, + JsNativeErrorKind::Type, "Array.prototype.reduceRight: callback function is not callable", ), ]); @@ -865,7 +862,7 @@ fn array_spread_arrays() { fn array_spread_non_iterable() { run_test_actions([TestAction::assert_native_error( "const array2 = [...5];", - ErrorKind::Type, + JsNativeErrorKind::Type, "value with type `number` is not iterable", )]); } diff --git a/boa_engine/src/builtins/bigint/tests.rs b/boa_engine/src/builtins/bigint/tests.rs index f62b95625d1..5c0f1894fe6 100644 --- a/boa_engine/src/builtins/bigint/tests.rs +++ b/boa_engine/src/builtins/bigint/tests.rs @@ -1,4 +1,4 @@ -use crate::{builtins::error::ErrorKind, run_test_actions, JsBigInt, TestAction}; +use crate::{run_test_actions, JsBigInt, JsNativeErrorKind, TestAction}; #[test] fn equality() { @@ -62,17 +62,17 @@ fn bigint_function_throws() { run_test_actions([ TestAction::assert_native_error( "BigInt(0.1)", - ErrorKind::Range, + JsNativeErrorKind::Range, "cannot convert 0.1 to a BigInt", ), TestAction::assert_native_error( "BigInt(null)", - ErrorKind::Type, + JsNativeErrorKind::Type, "cannot convert null to a BigInt", ), TestAction::assert_native_error( "BigInt(undefined)", - ErrorKind::Type, + JsNativeErrorKind::Type, "cannot convert undefined to a BigInt", ), ]); @@ -108,29 +108,37 @@ fn operations() { ), TestAction::assert_eq("15000n / 50n", JsBigInt::from(300)), TestAction::assert_eq("15001n / 50n", JsBigInt::from(300)), - TestAction::assert_native_error("1n/0n", ErrorKind::Range, "BigInt division by zero"), + TestAction::assert_native_error( + "1n/0n", + JsNativeErrorKind::Range, + "BigInt division by zero", + ), TestAction::assert_eq("15007n % 10n", JsBigInt::from(7)), - TestAction::assert_native_error("1n % 0n", ErrorKind::Range, "BigInt division by zero"), + TestAction::assert_native_error( + "1n % 0n", + JsNativeErrorKind::Range, + "BigInt division by zero", + ), TestAction::assert_eq( "100n ** 10n", JsBigInt::from_string("100000000000000000000").unwrap(), ), TestAction::assert_native_error( "10n ** (-10n)", - ErrorKind::Range, + JsNativeErrorKind::Range, "BigInt negative exponent", ), TestAction::assert_eq("8n << 2n", JsBigInt::from(32)), TestAction::assert_native_error( "1000n << 1000000000000000n", - ErrorKind::Range, + JsNativeErrorKind::Range, "Maximum BigInt size exceeded", ), TestAction::assert_eq("8n >> 2n", JsBigInt::from(2)), // TODO: this should return 0n instead of throwing TestAction::assert_native_error( "1000n >> 1000000000000000n", - ErrorKind::Range, + JsNativeErrorKind::Range, "Maximum BigInt size exceeded", ), ]); @@ -151,17 +159,17 @@ fn to_string_invalid_radix() { run_test_actions([ TestAction::assert_native_error( "10n.toString(null)", - ErrorKind::Range, + JsNativeErrorKind::Range, "radix must be an integer at least 2 and no greater than 36", ), TestAction::assert_native_error( "10n.toString(-1)", - ErrorKind::Range, + JsNativeErrorKind::Range, "radix must be an integer at least 2 and no greater than 36", ), TestAction::assert_native_error( "10n.toString(37)", - ErrorKind::Range, + JsNativeErrorKind::Range, "radix must be an integer at least 2 and no greater than 36", ), ]); @@ -219,22 +227,22 @@ fn as_int_n_errors() { run_test_actions([ TestAction::assert_native_error( "BigInt.asIntN(-1, 0n)", - ErrorKind::Range, + JsNativeErrorKind::Range, "Index must be between 0 and 2^53 - 1", ), TestAction::assert_native_error( "BigInt.asIntN(-2.5, 0n)", - ErrorKind::Range, + JsNativeErrorKind::Range, "Index must be between 0 and 2^53 - 1", ), TestAction::assert_native_error( "BigInt.asIntN(9007199254740992, 0n)", - ErrorKind::Range, + JsNativeErrorKind::Range, "Index must be between 0 and 2^53 - 1", ), TestAction::assert_native_error( "BigInt.asIntN(0n, 0n)", - ErrorKind::Type, + JsNativeErrorKind::Type, "argument must not be a bigint", ), ]); @@ -292,22 +300,22 @@ fn as_uint_n_errors() { run_test_actions([ TestAction::assert_native_error( "BigInt.asUintN(-1, 0n)", - ErrorKind::Range, + JsNativeErrorKind::Range, "Index must be between 0 and 2^53 - 1", ), TestAction::assert_native_error( "BigInt.asUintN(-2.5, 0n)", - ErrorKind::Range, + JsNativeErrorKind::Range, "Index must be between 0 and 2^53 - 1", ), TestAction::assert_native_error( "BigInt.asUintN(9007199254740992, 0n)", - ErrorKind::Range, + JsNativeErrorKind::Range, "Index must be between 0 and 2^53 - 1", ), TestAction::assert_native_error( "BigInt.asUintN(0n, 0n)", - ErrorKind::Type, + JsNativeErrorKind::Type, "argument must not be a bigint", ), ]); diff --git a/boa_engine/src/builtins/date/tests.rs b/boa_engine/src/builtins/date/tests.rs index 3650caf0dcd..54c7305d7dd 100644 --- a/boa_engine/src/builtins/date/tests.rs +++ b/boa_engine/src/builtins/date/tests.rs @@ -1,4 +1,4 @@ -use crate::{builtins::error::ErrorKind, run_test_actions, TestAction}; +use crate::{run_test_actions, JsNativeErrorKind, TestAction}; use chrono::{Local, NaiveDate, NaiveDateTime, NaiveTime, TimeZone}; use indoc::indoc; @@ -47,7 +47,7 @@ fn timestamp_from_utc( fn date_this_time_value() { run_test_actions([TestAction::assert_native_error( "({toString: Date.prototype.toString}).toString()", - ErrorKind::Type, + JsNativeErrorKind::Type, "'this' is not a Date", )]); } diff --git a/boa_engine/src/builtins/function/tests.rs b/boa_engine/src/builtins/function/tests.rs index ef77c4bb91b..d5d87131fbd 100644 --- a/boa_engine/src/builtins/function/tests.rs +++ b/boa_engine/src/builtins/function/tests.rs @@ -1,11 +1,10 @@ use crate::{ - builtins::error::ErrorKind, error::JsNativeError, js_string, native_function::NativeFunction, object::{FunctionObjectBuilder, JsObject}, property::{Attribute, PropertyDescriptor}, - run_test_actions, JsValue, TestAction, + run_test_actions, JsNativeErrorKind, JsValue, TestAction, }; use indoc::indoc; @@ -60,7 +59,7 @@ fn function_prototype() { ), TestAction::assert_native_error( "new Function.prototype()", - ErrorKind::Type, + JsNativeErrorKind::Type, "not a constructor", ), ]); @@ -81,7 +80,7 @@ fn function_prototype_call_throw() { let call = Function.prototype.call; call(call) "#}, - ErrorKind::Type, + JsNativeErrorKind::Type, "undefined is not a function", )]); } @@ -181,12 +180,12 @@ fn function_constructor_early_errors_super() { run_test_actions([ TestAction::assert_native_error( "Function('super()')()", - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "invalid `super` call", ), TestAction::assert_native_error( "Function('super.a')()", - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "invalid `super` reference", ), ]); diff --git a/boa_engine/src/builtins/json/tests.rs b/boa_engine/src/builtins/json/tests.rs index b65b04253a9..72151acf97a 100644 --- a/boa_engine/src/builtins/json/tests.rs +++ b/boa_engine/src/builtins/json/tests.rs @@ -1,6 +1,6 @@ use indoc::indoc; -use crate::{builtins::error::ErrorKind, run_test_actions, JsValue, TestAction}; +use crate::{run_test_actions, JsNativeErrorKind, JsValue, TestAction}; #[test] fn json_sanity() { @@ -307,7 +307,7 @@ fn json_fields_should_be_enumerable() { fn json_parse_with_no_args_throws_syntax_error() { run_test_actions([TestAction::assert_native_error( "JSON.parse();", - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "expected value at line 1 column 1", )]); } diff --git a/boa_engine/src/builtins/map/tests.rs b/boa_engine/src/builtins/map/tests.rs index ca4f5d0904d..75aa377b515 100644 --- a/boa_engine/src/builtins/map/tests.rs +++ b/boa_engine/src/builtins/map/tests.rs @@ -1,4 +1,4 @@ -use crate::{builtins::error::ErrorKind, run_test_actions, JsValue, TestAction}; +use crate::{run_test_actions, JsNativeErrorKind, JsValue, TestAction}; use indoc::indoc; #[test] @@ -242,7 +242,7 @@ fn recursive_display() { fn not_a_function() { run_test_actions([TestAction::assert_native_error( "let map = Map()", - ErrorKind::Type, + JsNativeErrorKind::Type, "calling a builtin Map constructor without new is forbidden", )]); } diff --git a/boa_engine/src/builtins/number/tests.rs b/boa_engine/src/builtins/number/tests.rs index d56db30e981..8e38fe3e78a 100644 --- a/boa_engine/src/builtins/number/tests.rs +++ b/boa_engine/src/builtins/number/tests.rs @@ -1,10 +1,7 @@ #![allow(clippy::float_cmp)] use crate::{ - builtins::{error::ErrorKind, Number}, - run_test_actions, - value::AbstractRelation, - TestAction, + builtins::Number, run_test_actions, value::AbstractRelation, JsNativeErrorKind, TestAction, }; #[test] @@ -81,10 +78,10 @@ fn to_precision() { "(1/3).toPrecision(60)", "0.333333333333333314829616256247390992939472198486328125000000", ), - TestAction::assert_native_error("(1).toPrecision(101)", ErrorKind::Range, ERROR), - TestAction::assert_native_error("(1).toPrecision(0)", ErrorKind::Range, ERROR), - TestAction::assert_native_error("(1).toPrecision(-2000)", ErrorKind::Range, ERROR), - TestAction::assert_native_error("(1).toPrecision('%')", ErrorKind::Range, ERROR), + TestAction::assert_native_error("(1).toPrecision(101)", JsNativeErrorKind::Range, ERROR), + TestAction::assert_native_error("(1).toPrecision(0)", JsNativeErrorKind::Range, ERROR), + TestAction::assert_native_error("(1).toPrecision(-2000)", JsNativeErrorKind::Range, ERROR), + TestAction::assert_native_error("(1).toPrecision('%')", JsNativeErrorKind::Range, ERROR), ]); } diff --git a/boa_engine/src/builtins/object/tests.rs b/boa_engine/src/builtins/object/tests.rs index d9901dbc378..b02d9d97bb2 100644 --- a/boa_engine/src/builtins/object/tests.rs +++ b/boa_engine/src/builtins/object/tests.rs @@ -1,4 +1,4 @@ -use crate::{builtins::error::ErrorKind, run_test_actions, JsValue, TestAction}; +use crate::{run_test_actions, JsNativeErrorKind, JsValue, TestAction}; use indoc::indoc; #[test] @@ -15,7 +15,7 @@ fn object_create_with_regular_object() { fn object_create_with_undefined() { run_test_actions([TestAction::assert_native_error( "Object.create()", - ErrorKind::Type, + JsNativeErrorKind::Type, "Object prototype may only be an Object or null: undefined", )]); } @@ -24,7 +24,7 @@ fn object_create_with_undefined() { fn object_create_with_number() { run_test_actions([TestAction::assert_native_error( "Object.create(5)", - ErrorKind::Type, + JsNativeErrorKind::Type, "Object prototype may only be an Object or null: 5", )]); } @@ -238,11 +238,19 @@ fn object_get_own_property_names_invalid_args() { const ERROR: &str = "cannot convert 'null' or 'undefined' to object"; run_test_actions([ - TestAction::assert_native_error("Object.getOwnPropertyNames()", ErrorKind::Type, ERROR), - TestAction::assert_native_error("Object.getOwnPropertyNames(null)", ErrorKind::Type, ERROR), + TestAction::assert_native_error( + "Object.getOwnPropertyNames()", + JsNativeErrorKind::Type, + ERROR, + ), + TestAction::assert_native_error( + "Object.getOwnPropertyNames(null)", + JsNativeErrorKind::Type, + ERROR, + ), TestAction::assert_native_error( "Object.getOwnPropertyNames(undefined)", - ErrorKind::Type, + JsNativeErrorKind::Type, ERROR, ), ]); @@ -307,15 +315,19 @@ fn object_get_own_property_symbols_invalid_args() { const ERROR: &str = "cannot convert 'null' or 'undefined' to object"; run_test_actions([ - TestAction::assert_native_error("Object.getOwnPropertySymbols()", ErrorKind::Type, ERROR), + TestAction::assert_native_error( + "Object.getOwnPropertySymbols()", + JsNativeErrorKind::Type, + ERROR, + ), TestAction::assert_native_error( "Object.getOwnPropertySymbols(null)", - ErrorKind::Type, + JsNativeErrorKind::Type, ERROR, ), TestAction::assert_native_error( "Object.getOwnPropertySymbols(undefined)", - ErrorKind::Type, + JsNativeErrorKind::Type, ERROR, ), ]); @@ -382,9 +394,13 @@ fn object_from_entries_invalid_args() { const ERROR: &str = "cannot convert null or undefined to Object"; run_test_actions([ - TestAction::assert_native_error("Object.fromEntries()", ErrorKind::Type, ERROR), - TestAction::assert_native_error("Object.fromEntries(null)", ErrorKind::Type, ERROR), - TestAction::assert_native_error("Object.fromEntries(undefined)", ErrorKind::Type, ERROR), + TestAction::assert_native_error("Object.fromEntries()", JsNativeErrorKind::Type, ERROR), + TestAction::assert_native_error("Object.fromEntries(null)", JsNativeErrorKind::Type, ERROR), + TestAction::assert_native_error( + "Object.fromEntries(undefined)", + JsNativeErrorKind::Type, + ERROR, + ), ]); } diff --git a/boa_engine/src/builtins/regexp/tests.rs b/boa_engine/src/builtins/regexp/tests.rs index 4aab948a055..ff972d08d02 100644 --- a/boa_engine/src/builtins/regexp/tests.rs +++ b/boa_engine/src/builtins/regexp/tests.rs @@ -1,4 +1,4 @@ -use crate::{builtins::error::ErrorKind, object::JsObject, run_test_actions, JsValue, TestAction}; +use crate::{object::JsObject, run_test_actions, JsNativeErrorKind, JsValue, TestAction}; use indoc::indoc; #[test] @@ -120,12 +120,12 @@ fn no_panic_on_parse_fail() { run_test_actions([ TestAction::assert_native_error( r"var re = /]/u;", - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "Invalid regular expression literal: Unbalanced bracket at position: 1:10", ), TestAction::assert_native_error( r"var re = /a{/u;", - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "Invalid regular expression literal: Invalid quantifier at position: 1:10", ), ]); @@ -182,13 +182,25 @@ fn search() { 4, ), // this-val-non-obj - TestAction::assert_native_error("search.value.call()", ErrorKind::Type, ERROR), - TestAction::assert_native_error("search.value.call(undefined)", ErrorKind::Type, ERROR), - TestAction::assert_native_error("search.value.call(null)", ErrorKind::Type, ERROR), - TestAction::assert_native_error("search.value.call(true)", ErrorKind::Type, ERROR), - TestAction::assert_native_error("search.value.call('string')", ErrorKind::Type, ERROR), - TestAction::assert_native_error("search.value.call(Symbol.search)", ErrorKind::Type, ERROR), - TestAction::assert_native_error("search.value.call(86)", ErrorKind::Type, ERROR), + TestAction::assert_native_error("search.value.call()", JsNativeErrorKind::Type, ERROR), + TestAction::assert_native_error( + "search.value.call(undefined)", + JsNativeErrorKind::Type, + ERROR, + ), + TestAction::assert_native_error("search.value.call(null)", JsNativeErrorKind::Type, ERROR), + TestAction::assert_native_error("search.value.call(true)", JsNativeErrorKind::Type, ERROR), + TestAction::assert_native_error( + "search.value.call('string')", + JsNativeErrorKind::Type, + ERROR, + ), + TestAction::assert_native_error( + "search.value.call(Symbol.search)", + JsNativeErrorKind::Type, + ERROR, + ), + TestAction::assert_native_error("search.value.call(86)", JsNativeErrorKind::Type, ERROR), // u-lastindex-advance TestAction::assert_eq(r"/\udf06/u[Symbol.search]('\ud834\udf06')", -1), TestAction::assert_eq("/a/[Symbol.search](\"a\")", 0), diff --git a/boa_engine/src/builtins/set/tests.rs b/boa_engine/src/builtins/set/tests.rs index 6616a45b057..50f5289ab2f 100644 --- a/boa_engine/src/builtins/set/tests.rs +++ b/boa_engine/src/builtins/set/tests.rs @@ -1,4 +1,4 @@ -use crate::{builtins::error::ErrorKind, run_test_actions, TestAction}; +use crate::{run_test_actions, JsNativeErrorKind, TestAction}; use indoc::indoc; #[test] @@ -170,7 +170,7 @@ fn recursive_display() { fn not_a_function() { run_test_actions([TestAction::assert_native_error( "Set()", - ErrorKind::Type, + JsNativeErrorKind::Type, "calling a builtin Set constructor without new is forbidden", )]); } diff --git a/boa_engine/src/builtins/string/tests.rs b/boa_engine/src/builtins/string/tests.rs index 45bca332c49..b5418286a10 100644 --- a/boa_engine/src/builtins/string/tests.rs +++ b/boa_engine/src/builtins/string/tests.rs @@ -1,6 +1,6 @@ use indoc::indoc; -use crate::{builtins::error::ErrorKind, js_string, run_test_actions, JsValue, TestAction}; +use crate::{js_string, run_test_actions, JsNativeErrorKind, JsValue, TestAction}; #[test] fn length() { @@ -104,7 +104,7 @@ fn repeat() { fn repeat_throws_when_count_is_negative() { run_test_actions([TestAction::assert_native_error( "'x'.repeat(-1)", - ErrorKind::Range, + JsNativeErrorKind::Range, "repeat count must be a positive finite number \ that doesn't overflow the maximum string length (2^32 - 1)", )]); @@ -114,7 +114,7 @@ fn repeat_throws_when_count_is_negative() { fn repeat_throws_when_count_is_infinity() { run_test_actions([TestAction::assert_native_error( "'x'.repeat(Infinity)", - ErrorKind::Range, + JsNativeErrorKind::Range, "repeat count must be a positive finite number \ that doesn't overflow the maximum string length (2^32 - 1)", )]); @@ -124,7 +124,7 @@ fn repeat_throws_when_count_is_infinity() { fn repeat_throws_when_count_overflows_max_length() { run_test_actions([TestAction::assert_native_error( "'x'.repeat(2 ** 64)", - ErrorKind::Range, + JsNativeErrorKind::Range, "repeat count must be a positive finite number \ that doesn't overflow the maximum string length (2^32 - 1)", )]); @@ -247,7 +247,7 @@ fn starts_with() { fn starts_with_with_regex_arg() { run_test_actions([TestAction::assert_native_error( "'Saturday night'.startsWith(/Saturday/)", - ErrorKind::Type, + JsNativeErrorKind::Type, "First argument to String.prototype.startsWith must not be a regular expression", )]); } @@ -273,7 +273,7 @@ fn ends_with() { fn ends_with_with_regex_arg() { run_test_actions([TestAction::assert_native_error( "'Saturday night'.endsWith(/night/)", - ErrorKind::Type, + JsNativeErrorKind::Type, "First argument to String.prototype.endsWith must not be a regular expression", )]); } @@ -299,7 +299,7 @@ fn includes() { fn includes_with_regex_arg() { run_test_actions([TestAction::assert_native_error( "'Saturday night'.includes(/day/)", - ErrorKind::Type, + JsNativeErrorKind::Type, "First argument to String.prototype.includes must not be a regular expression", )]); } @@ -589,7 +589,7 @@ fn split_with_symbol_split_method() { sep[Symbol.split] = 10; 'hello'.split(sep, 10); "#}, - ErrorKind::Type, + JsNativeErrorKind::Type, "value returned for property of object is not a function", ), ]); @@ -880,32 +880,32 @@ fn from_code_point() { TestAction::assert_eq("String.fromCodePoint(9731, 9733, 9842, 0x4F60)", "☃★♲你"), TestAction::assert_native_error( "String.fromCodePoint('_')", - ErrorKind::Range, + JsNativeErrorKind::Range, "codepoint `NaN` is not an integer", ), TestAction::assert_native_error( "String.fromCodePoint(Infinity)", - ErrorKind::Range, + JsNativeErrorKind::Range, "codepoint `inf` is not an integer", ), TestAction::assert_native_error( "String.fromCodePoint(-1)", - ErrorKind::Range, + JsNativeErrorKind::Range, "codepoint `-1` outside of Unicode range", ), TestAction::assert_native_error( "String.fromCodePoint(3.14)", - ErrorKind::Range, + JsNativeErrorKind::Range, "codepoint `3.14` is not an integer", ), TestAction::assert_native_error( "String.fromCodePoint(3e-2)", - ErrorKind::Range, + JsNativeErrorKind::Range, "codepoint `0.03` is not an integer", ), TestAction::assert_native_error( "String.fromCodePoint(NaN)", - ErrorKind::Range, + JsNativeErrorKind::Range, "codepoint `NaN` is not an integer", ), ]); diff --git a/boa_engine/src/context/mod.rs b/boa_engine/src/context/mod.rs index 1f7eb74750c..17630607a76 100644 --- a/boa_engine/src/context/mod.rs +++ b/boa_engine/src/context/mod.rs @@ -484,30 +484,36 @@ impl<'host> Context<'host> { /// Set the value of trace on the context #[cfg(feature = "trace")] + #[inline] pub fn set_trace(&mut self, trace: bool) { self.vm.trace = trace; } /// Get optimizer options. + #[inline] pub const fn optimizer_options(&self) -> OptimizerOptions { self.optimizer_options } /// Enable or disable optimizations + #[inline] pub fn set_optimizer_options(&mut self, optimizer_options: OptimizerOptions) { self.optimizer_options = optimizer_options; } /// Changes the strictness mode of the context. + #[inline] pub fn strict(&mut self, strict: bool) { self.strict = strict; } /// Enqueues a [`NativeJob`] on the [`JobQueue`]. + #[inline] pub fn enqueue_job(&mut self, job: NativeJob) { self.job_queue().enqueue_promise_job(job, self); } /// Runs all the jobs in the job queue. + #[inline] pub fn run_jobs(&mut self) { self.job_queue().run_jobs(self); self.clear_kept_objects(); @@ -521,16 +527,19 @@ impl<'host> Context<'host> { /// [clear]: https://tc39.es/ecma262/multipage/executable-code-and-execution-contexts.html#sec-clear-kept-objects /// [add]: https://tc39.es/ecma262/multipage/executable-code-and-execution-contexts.html#sec-addtokeptobjects /// [weak]: https://tc39.es/ecma262/multipage/managing-memory.html#sec-weak-ref-objects + #[inline] pub fn clear_kept_objects(&mut self) { self.kept_alive.clear(); } /// Retrieves the current stack trace of the context. + #[inline] pub fn stack_trace(&mut self) -> impl Iterator { self.vm.frames.iter().rev() } /// Replaces the currently active realm with `realm`, and returns the old realm. + #[inline] pub fn enter_realm(&mut self, realm: Realm) -> Realm { self.vm .environments @@ -543,26 +552,31 @@ impl<'host> Context<'host> { } /// Gets the host hooks. + #[inline] pub fn host_hooks(&self) -> MaybeShared<'host, dyn HostHooks> { self.host_hooks.clone() } /// Gets the job queue. + #[inline] pub fn job_queue(&self) -> MaybeShared<'host, dyn JobQueue> { self.job_queue.clone() } /// Get the [`RuntimeLimits`]. - pub fn runtime_limits(&mut self) -> RuntimeLimits { + #[inline] + pub const fn runtime_limits(&self) -> RuntimeLimits { self.vm.runtime_limits } /// Set the [`RuntimeLimits`]. + #[inline] pub fn set_runtime_limits(&mut self, runtime_limits: RuntimeLimits) { self.vm.runtime_limits = runtime_limits; } /// Get a mutable reference to the [`RuntimeLimits`]. + #[inline] pub fn runtime_limits_mut(&mut self) -> &mut RuntimeLimits { &mut self.vm.runtime_limits } diff --git a/boa_engine/src/environments/tests.rs b/boa_engine/src/environments/tests.rs index 5baee075ab9..e900eb4b475 100644 --- a/boa_engine/src/environments/tests.rs +++ b/boa_engine/src/environments/tests.rs @@ -1,4 +1,4 @@ -use crate::{builtins::error::ErrorKind, run_test_actions, TestAction}; +use crate::{run_test_actions, JsNativeErrorKind, TestAction}; use indoc::indoc; #[test] @@ -10,7 +10,7 @@ fn let_is_block_scoped() { } bar; "#}, - ErrorKind::Reference, + JsNativeErrorKind::Reference, "bar is not defined", )]); } @@ -24,7 +24,7 @@ fn const_is_block_scoped() { } bar; "#}, - ErrorKind::Reference, + JsNativeErrorKind::Reference, "bar is not defined", )]); } @@ -51,7 +51,7 @@ fn functions_use_declaration_scope() { foo(); } "#}, - ErrorKind::Reference, + JsNativeErrorKind::Reference, "bar is not defined", )]); } diff --git a/boa_engine/src/error.rs b/boa_engine/src/error.rs index 5e966f197f5..ce5899166df 100644 --- a/boa_engine/src/error.rs +++ b/boa_engine/src/error.rs @@ -44,7 +44,7 @@ use thiserror::Error; /// let kind = &native_error.as_native().unwrap().kind; /// assert!(matches!(kind, JsNativeErrorKind::Type)); /// ``` -#[derive(Debug, Clone, Trace, Finalize)] +#[derive(Debug, Clone, Trace, Finalize, PartialEq, Eq)] pub struct JsError { inner: Repr, } @@ -59,7 +59,7 @@ pub struct JsError { /// This should never be used outside of this module. If that's not the case, /// you should add methods to either `JsError` or `JsNativeError` to /// represent that special use case. -#[derive(Debug, Clone, Trace, Finalize)] +#[derive(Debug, Clone, Trace, Finalize, PartialEq, Eq)] enum Repr { Native(JsNativeError), Opaque(JsValue), @@ -417,7 +417,7 @@ impl std::fmt::Display for JsError { /// /// assert_eq!(native_error.message(), "cannot decode uri"); /// ``` -#[derive(Clone, Trace, Finalize, Error)] +#[derive(Clone, Trace, Finalize, Error, PartialEq, Eq)] #[error("{kind}: {message}")] pub struct JsNativeError { /// The kind of native error (e.g. `TypeError`, `SyntaxError`, etc.) @@ -766,7 +766,7 @@ impl JsNativeError { /// /// # Panics /// - /// If the converting a [`JsNativeErrorKind::RuntimeLimit`] to an opaque object. + /// If converting a [`JsNativeErrorKind::RuntimeLimit`] to an opaque object. #[inline] pub fn to_opaque(&self, context: &mut Context<'_>) -> JsObject { let Self { @@ -864,7 +864,7 @@ impl From for JsNativeError { /// /// [spec]: https://tc39.es/ecma262/#sec-error-objects /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error -#[derive(Debug, Clone, Trace, Finalize)] +#[derive(Debug, Clone, Trace, Finalize, PartialEq, Eq)] #[non_exhaustive] pub enum JsNativeErrorKind { /// A collection of errors wrapped in a single error. diff --git a/boa_engine/src/lib.rs b/boa_engine/src/lib.rs index 5ba437c63be..d333c807cd8 100644 --- a/boa_engine/src/lib.rs +++ b/boa_engine/src/lib.rs @@ -248,7 +248,7 @@ enum Inner { }, AssertNativeError { source: Cow<'static, str>, - kind: builtins::error::ErrorKind, + kind: JsNativeErrorKind, message: &'static str, }, AssertContext { @@ -319,7 +319,7 @@ impl TestAction { /// Asserts that evaluating `source` throws a native error of `kind` and `message`. fn assert_native_error( source: impl Into>, - kind: builtins::error::ErrorKind, + kind: JsNativeErrorKind, message: &'static str, ) -> Self { Self(Inner::AssertNativeError { diff --git a/boa_engine/src/object/tests.rs b/boa_engine/src/object/tests.rs index 5b590926528..9113845f235 100644 --- a/boa_engine/src/object/tests.rs +++ b/boa_engine/src/object/tests.rs @@ -1,4 +1,4 @@ -use crate::{builtins::error::ErrorKind, run_test_actions, TestAction}; +use crate::{run_test_actions, JsNativeErrorKind, TestAction}; use indoc::indoc; #[test] @@ -9,7 +9,7 @@ fn ordinary_has_instance_nonobject_prototype() { C.prototype = 1 String instanceof C "#}, - ErrorKind::Type, + JsNativeErrorKind::Type, "function has non-object prototype in instanceof check", )]); } diff --git a/boa_engine/src/realm.rs b/boa_engine/src/realm.rs index 22b4d5c4d6d..3967f32d38e 100644 --- a/boa_engine/src/realm.rs +++ b/boa_engine/src/realm.rs @@ -24,6 +24,14 @@ pub struct Realm { inner: Gc, } +impl Eq for Realm {} + +impl PartialEq for Realm { + fn eq(&self, other: &Self) -> bool { + Gc::ptr_eq(&self.inner, &other.inner) + } +} + impl fmt::Debug for Realm { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Realm") @@ -35,12 +43,6 @@ impl fmt::Debug for Realm { } } -impl PartialEq for Realm { - fn eq(&self, other: &Self) -> bool { - std::ptr::eq(&*self.inner, &*other.inner) - } -} - #[derive(Trace, Finalize)] struct Inner { intrinsics: Intrinsics, diff --git a/boa_engine/src/tests/control_flow/loops.rs b/boa_engine/src/tests/control_flow/loops.rs index 61ee02b6c3c..dd26eebfe81 100644 --- a/boa_engine/src/tests/control_flow/loops.rs +++ b/boa_engine/src/tests/control_flow/loops.rs @@ -1,4 +1,4 @@ -use crate::{builtins::error::ErrorKind, run_test_actions, TestAction}; +use crate::{run_test_actions, JsNativeErrorKind, TestAction}; use indoc::indoc; #[test] @@ -125,7 +125,7 @@ fn for_loop_iteration_variable_does_not_leak() { for (let i = 0;false;) {} i "#}, - ErrorKind::Reference, + JsNativeErrorKind::Reference, "i is not defined", )]); } @@ -138,7 +138,7 @@ fn test_invalid_break_target() { break nonexistent; } "#}, - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "undefined break target: nonexistent at position: 1:1", )]); } @@ -625,7 +625,7 @@ fn for_of_loop_let() { } "#}), TestAction::assert_eq("result", 3), - TestAction::assert_native_error("i", ErrorKind::Reference, "i is not defined"), + TestAction::assert_native_error("i", JsNativeErrorKind::Reference, "i is not defined"), ]); } @@ -639,7 +639,7 @@ fn for_of_loop_const() { } "#}), TestAction::assert_eq("result", 3), - TestAction::assert_native_error("i", ErrorKind::Reference, "i is not defined"), + TestAction::assert_native_error("i", JsNativeErrorKind::Reference, "i is not defined"), ]); } diff --git a/boa_engine/src/tests/control_flow/mod.rs b/boa_engine/src/tests/control_flow/mod.rs index 70ea43e7f98..3283e56e3f6 100644 --- a/boa_engine/src/tests/control_flow/mod.rs +++ b/boa_engine/src/tests/control_flow/mod.rs @@ -1,13 +1,13 @@ use indoc::indoc; mod loops; -use crate::{builtins::error::ErrorKind, run_test_actions, TestAction}; +use crate::{run_test_actions, JsNativeErrorKind, TestAction}; #[test] fn test_invalid_break() { run_test_actions([TestAction::assert_native_error( "break;", - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "illegal break statement at position: 1:1", )]); } @@ -20,7 +20,7 @@ fn test_invalid_continue_target() { continue nonexistent; } "#}, - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "undefined continue target: nonexistent at position: 1:1", )]); } @@ -29,7 +29,7 @@ fn test_invalid_continue_target() { fn test_invalid_continue() { run_test_actions([TestAction::assert_native_error( "continue;", - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "illegal continue statement at position: 1:1", )]); } diff --git a/boa_engine/src/tests/function.rs b/boa_engine/src/tests/function.rs index 8e4e7ce8438..615ef837071 100644 --- a/boa_engine/src/tests/function.rs +++ b/boa_engine/src/tests/function.rs @@ -1,4 +1,4 @@ -use crate::{builtins::error::ErrorKind, run_test_actions, JsValue, TestAction}; +use crate::{run_test_actions, JsNativeErrorKind, JsValue, TestAction}; use indoc::indoc; #[test] @@ -87,7 +87,7 @@ fn should_set_this_value() { fn should_type_error_when_new_is_not_constructor() { run_test_actions([TestAction::assert_native_error( "new ''()", - ErrorKind::Type, + JsNativeErrorKind::Type, "not a constructor", )]); } @@ -125,9 +125,13 @@ fn not_a_function() { let a = {}; let b = true; "#}), - TestAction::assert_native_error("a()", ErrorKind::Type, "not a callable function"), - TestAction::assert_native_error("a.a()", ErrorKind::Type, "not a callable function"), - TestAction::assert_native_error("b()", ErrorKind::Type, "not a callable function"), + TestAction::assert_native_error("a()", JsNativeErrorKind::Type, "not a callable function"), + TestAction::assert_native_error( + "a.a()", + JsNativeErrorKind::Type, + "not a callable function", + ), + TestAction::assert_native_error("b()", JsNativeErrorKind::Type, "not a callable function"), ]); } @@ -140,7 +144,7 @@ fn strict_mode_dup_func_parameters() { 'use strict'; function f(a, b, b) {} "#}, - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "Duplicate parameter name not allowed in this context at position: 2:12", )]); } diff --git a/boa_engine/src/tests/mod.rs b/boa_engine/src/tests/mod.rs index 34930868bb4..a6c848abfdb 100644 --- a/boa_engine/src/tests/mod.rs +++ b/boa_engine/src/tests/mod.rs @@ -7,7 +7,7 @@ mod operators; mod promise; mod spread; -use crate::{builtins::error::ErrorKind, run_test_actions, JsValue, TestAction}; +use crate::{run_test_actions, JsNativeErrorKind, JsValue, TestAction}; #[test] fn length_correct_value_on_string_literal() { @@ -40,7 +40,7 @@ fn empty_var_decl_undefined() { fn identifier_on_global_object_undefined() { run_test_actions([TestAction::assert_native_error( "bar;", - ErrorKind::Reference, + JsNativeErrorKind::Reference, "bar is not defined", )]); } @@ -372,7 +372,7 @@ fn undefined_constant() { fn identifier_op() { run_test_actions([TestAction::assert_native_error( "break = 1", - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, r#"expected token 'identifier', got '=' in identifier parsing at line 1, col 7"#, )]); } @@ -386,7 +386,7 @@ fn strict_mode_octal() { 'use strict'; var n = 023; "#}, - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "implicit octal literals are not allowed in strict mode at position: 2:9", )]); } @@ -404,7 +404,7 @@ fn strict_mode_with() { } } "#}, - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "with statement not allowed in strict mode at line 3, col 5", )]); } @@ -429,7 +429,11 @@ fn strict_mode_reserved_name() { ]; run_test_actions(cases.into_iter().map(|(case, msg)| { - TestAction::assert_native_error(format!("'use strict'; {case}"), ErrorKind::Syntax, msg) + TestAction::assert_native_error( + format!("'use strict'; {case}"), + JsNativeErrorKind::Syntax, + msg, + ) })); } diff --git a/boa_engine/src/tests/operators.rs b/boa_engine/src/tests/operators.rs index 0ed66599788..4a261da2e62 100644 --- a/boa_engine/src/tests/operators.rs +++ b/boa_engine/src/tests/operators.rs @@ -1,4 +1,4 @@ -use crate::{builtins::error::ErrorKind, run_test_actions, JsValue, TestAction}; +use crate::{run_test_actions, JsNativeErrorKind, JsValue, TestAction}; use indoc::indoc; #[test] @@ -143,22 +143,22 @@ fn invalid_unary_access() { run_test_actions([ TestAction::assert_native_error( "++[]", - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "Invalid left-hand side in assignment at position: 1:1", ), TestAction::assert_native_error( "[]++", - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "Invalid left-hand side in assignment at position: 1:3", ), TestAction::assert_native_error( "--[]", - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "Invalid left-hand side in assignment at position: 1:1", ), TestAction::assert_native_error( "[]--", - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "Invalid left-hand side in assignment at position: 1:3", ), ]); @@ -170,22 +170,22 @@ fn unary_operations_on_this() { run_test_actions([ TestAction::assert_native_error( "++this", - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "Invalid left-hand side in assignment at position: 1:1", ), TestAction::assert_native_error( "--this", - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "Invalid left-hand side in assignment at position: 1:1", ), TestAction::assert_native_error( "this++", - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "Invalid left-hand side in assignment at position: 1:5", ), TestAction::assert_native_error( "this--", - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "Invalid left-hand side in assignment at position: 1:5", ), ]); @@ -305,7 +305,7 @@ fn assignment_to_non_assignable() { .map(|src| { TestAction::assert_native_error( src, - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "Invalid left-hand side in assignment at position: 1:3", ) }), @@ -330,7 +330,7 @@ fn assignment_to_non_assignable_ctd() { .map(|src| { TestAction::assert_native_error( src, - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "Invalid left-hand side in assignment at position: 1:13", ) }), @@ -344,7 +344,7 @@ fn multicharacter_assignment_to_non_assignable() { run_test_actions(["3 **= 5", "3 <<= 5", "3 >>= 5"].into_iter().map(|src| { TestAction::assert_native_error( src, - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "Invalid left-hand side in assignment at position: 1:3", ) })); @@ -358,7 +358,7 @@ fn multicharacter_assignment_to_non_assignable_ctd() { .map(|src| { TestAction::assert_native_error( src, - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "Invalid left-hand side in assignment at position: 1:13", ) }), @@ -373,7 +373,7 @@ fn multicharacter_bitwise_assignment_to_non_assignable() { .map(|src| { TestAction::assert_native_error( src, - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "Invalid left-hand side in assignment at position: 1:3", ) }), @@ -393,7 +393,7 @@ fn multicharacter_bitwise_assignment_to_non_assignable_ctd() { .map(|src| { TestAction::assert_native_error( src, - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "Invalid left-hand side in assignment at position: 1:13", ) }), @@ -405,22 +405,22 @@ fn assign_to_array_decl() { run_test_actions([ TestAction::assert_native_error( "[1] = [2]", - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "Invalid left-hand side in assignment at position: 1:5", ), TestAction::assert_native_error( "[3, 5] = [7, 8]", - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "Invalid left-hand side in assignment at position: 1:8", ), TestAction::assert_native_error( "[6, 8] = [2]", - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "Invalid left-hand side in assignment at position: 1:8", ), TestAction::assert_native_error( "[6] = [2, 9]", - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "Invalid left-hand side in assignment at position: 1:5", ), ]); @@ -430,7 +430,7 @@ fn assign_to_array_decl() { fn assign_to_object_decl() { run_test_actions([TestAction::assert_native_error( "{a: 3} = {a: 5};", - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "unexpected token '=', primary expression at line 1, col 8", )]); } @@ -439,7 +439,7 @@ fn assign_to_object_decl() { fn assignmentoperator_lhs_not_defined() { run_test_actions([TestAction::assert_native_error( "a += 5", - ErrorKind::Reference, + JsNativeErrorKind::Reference, "a is not defined", )]); } @@ -448,7 +448,7 @@ fn assignmentoperator_lhs_not_defined() { fn assignmentoperator_rhs_throws_error() { run_test_actions([TestAction::assert_native_error( "let a; a += b", - ErrorKind::Reference, + JsNativeErrorKind::Reference, "b is not defined", )]); } @@ -457,7 +457,7 @@ fn assignmentoperator_rhs_throws_error() { fn instanceofoperator_rhs_not_object() { run_test_actions([TestAction::assert_native_error( "let s = new String(); s instanceof 1", - ErrorKind::Type, + JsNativeErrorKind::Type, "right-hand side of 'instanceof' should be an object, got `number`", )]); } @@ -466,7 +466,7 @@ fn instanceofoperator_rhs_not_object() { fn instanceofoperator_rhs_not_callable() { run_test_actions([TestAction::assert_native_error( "let s = new String(); s instanceof {}", - ErrorKind::Type, + JsNativeErrorKind::Type, "right-hand side of 'instanceof' is not callable", )]); } @@ -504,7 +504,7 @@ fn delete_variable_in_strict() { let x = 10; delete x; "#}, - ErrorKind::Syntax, + JsNativeErrorKind::Syntax, "cannot delete variables in strict mode at position: 3:1", )]); } @@ -513,7 +513,7 @@ fn delete_variable_in_strict() { fn delete_non_configurable() { run_test_actions([TestAction::assert_native_error( "'use strict'; delete Boolean.prototype", - ErrorKind::Type, + JsNativeErrorKind::Type, "Cannot delete property", )]); } @@ -528,7 +528,7 @@ fn delete_non_configurable_in_function() { } t() "#}, - ErrorKind::Type, + JsNativeErrorKind::Type, "Cannot delete property", )]); } @@ -557,7 +557,7 @@ fn delete_in_function_global_strict() { } a(); "#}, - ErrorKind::Type, + JsNativeErrorKind::Type, "Cannot delete property", )]); } @@ -591,7 +591,7 @@ fn delete_in_strict_function_returned() { } a()(); "#}, - ErrorKind::Type, + JsNativeErrorKind::Type, "Cannot delete property", )]); } @@ -633,7 +633,7 @@ mod in_operator { fn should_type_error_when_rhs_not_object() { run_test_actions([TestAction::assert_native_error( "'fail' in undefined", - ErrorKind::Type, + JsNativeErrorKind::Type, "right-hand side of 'in' should be an object, got `undefined`", )]); } diff --git a/boa_engine/src/tests/spread.rs b/boa_engine/src/tests/spread.rs index e5f01edb863..05ad16fc954 100644 --- a/boa_engine/src/tests/spread.rs +++ b/boa_engine/src/tests/spread.rs @@ -1,4 +1,4 @@ -use crate::{builtins::error::ErrorKind, run_test_actions, JsValue, TestAction}; +use crate::{run_test_actions, JsNativeErrorKind, JsValue, TestAction}; use indoc::indoc; #[test] @@ -97,7 +97,7 @@ fn spread_getters_in_object() { var a = { x: 42 }; var aWithXGetter = { ...a, ... { get x() { throw new Error('not thrown yet') } } }; "#}, - ErrorKind::Error, + JsNativeErrorKind::Error, "not thrown yet", )]); } diff --git a/boa_engine/src/value/tests.rs b/boa_engine/src/value/tests.rs index 21d7637eb3b..d0d558e4a08 100644 --- a/boa_engine/src/value/tests.rs +++ b/boa_engine/src/value/tests.rs @@ -700,7 +700,7 @@ fn to_bigint() { /// Relevant mitigation for these are in `JsObject::ordinary_to_primitive` and /// `JsObject::to_json` mod cyclic_conversions { - use crate::builtins::error::ErrorKind; + use crate::JsNativeErrorKind; use super::*; @@ -712,7 +712,7 @@ mod cyclic_conversions { a[0] = a; JSON.stringify(a) "#}, - ErrorKind::Type, + JsNativeErrorKind::Type, "cyclic object value", )]); } diff --git a/boa_engine/src/vm/opcode/iteration/loop_ops.rs b/boa_engine/src/vm/opcode/iteration/loop_ops.rs index 3a0b15f8990..3b586aeb249 100644 --- a/boa_engine/src/vm/opcode/iteration/loop_ops.rs +++ b/boa_engine/src/vm/opcode/iteration/loop_ops.rs @@ -26,6 +26,8 @@ impl Operation for LoopStart { } } +/// This is a helper function used to clean the loop environment created by the +/// [`LoopStart`] and [`LoopContinue`] opcodes. fn cleanup_loop_environment(context: &mut Context<'_>) { let mut envs_to_pop = 0_usize; while let Some(env_entry) = context.vm.frame_mut().env_stack.pop() { diff --git a/boa_engine/src/vm/tests.rs b/boa_engine/src/vm/tests.rs index 929e3d9a826..9460ae2dce1 100644 --- a/boa_engine/src/vm/tests.rs +++ b/boa_engine/src/vm/tests.rs @@ -1,4 +1,4 @@ -use crate::{builtins::error::ErrorKind, run_test_actions, JsValue, TestAction}; +use crate::{run_test_actions, JsNativeErrorKind, JsValue, TestAction}; use indoc::indoc; #[test] @@ -190,7 +190,7 @@ fn super_call_constructor_null() { } new A(); "#}, - ErrorKind::Type, + JsNativeErrorKind::Type, "super constructor object must be constructor", )]); } @@ -237,3 +237,38 @@ fn order_of_execution_in_assigment_with_comma_expressions() { "1234", )]); } + +#[test] +fn loop_runtime_limit() { + run_test_actions([ + TestAction::assert_eq( + indoc! {r#" + for (let i = 0; i < 20; ++i) { } + "#}, + JsValue::undefined(), + ), + TestAction::inspect_context(|context| { + context.runtime_limits_mut().set_loop_iteration_limit(10); + }), + TestAction::assert_native_error( + indoc! {r#" + for (let i = 0; i < 20; ++i) { } + "#}, + JsNativeErrorKind::RuntimeLimit, + "max loop iteration limit 10 exceeded", + ), + TestAction::assert_eq( + indoc! {r#" + for (let i = 0; i < 10; ++i) { } + "#}, + JsValue::undefined(), + ), + TestAction::assert_native_error( + indoc! {r#" + while (1) { } + "#}, + JsNativeErrorKind::RuntimeLimit, + "max loop iteration limit 10 exceeded", + ), + ]); +}