Browse Source

Feature `EvalError` (#804)

pull/806/head
Halid Odat 4 years ago committed by GitHub
parent
commit
03f96327db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 69
      boa/src/builtins/error/eval.rs
  2. 4
      boa/src/builtins/error/mod.rs
  3. 25
      boa/src/builtins/error/tests.rs
  4. 3
      boa/src/builtins/mod.rs
  5. 27
      boa/src/context.rs

69
boa/src/builtins/error/eval.rs

@ -0,0 +1,69 @@
//! This module implements the global `EvalError` object.
//!
//! Indicates an error regarding the global `eval()` function.
//! This exception is not thrown by JavaScript anymore, however
//! the `EvalError` object remains for compatibility.
//!
//! More information:
//! - [MDN documentation][mdn]
//! - [ECMAScript reference][spec]
//!
//! [spec]: https://tc39.es/ecma262/#sec-native-error-types-used-in-this-standard-evalerror
//! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/EvalError
use crate::{
builtins::BuiltIn,
object::{ConstructorBuilder, ObjectData},
profiler::BoaProfiler,
property::Attribute,
Context, Result, Value,
};
/// JavaScript `EvalError` impleentation.
#[derive(Debug, Clone, Copy)]
pub(crate) struct EvalError;
impl BuiltIn for EvalError {
const NAME: &'static str = "EvalError";
fn attribute() -> Attribute {
Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE
}
fn init(context: &mut Context) -> (&'static str, Value, Attribute) {
let _timer = BoaProfiler::global().start_event(Self::NAME, "init");
let error_prototype = context.standard_objects().error_object().prototype();
let attribute = Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE;
let eval_error_object = ConstructorBuilder::with_standard_object(
context,
Self::constructor,
context.standard_objects().eval_error_object().clone(),
)
.name(Self::NAME)
.length(Self::LENGTH)
.inherit(error_prototype.into())
.property("name", Self::NAME, attribute)
.property("message", "", attribute)
.build();
(Self::NAME, eval_error_object.into(), Self::attribute())
}
}
impl EvalError {
/// The amount of arguments this function object takes.
pub(crate) const LENGTH: usize = 1;
/// Create a new error object.
pub(crate) fn constructor(this: &Value, args: &[Value], ctx: &mut Context) -> Result<Value> {
if let Some(message) = args.get(0) {
this.set_field("message", message.to_string(ctx)?);
}
// This value is used by console.log and other routines to match Object type
// to its Javascript Identifier (global constructor method name)
this.set_data(ObjectData::Error);
Ok(this.clone())
}
}

4
boa/src/builtins/error/mod.rs

@ -18,21 +18,21 @@ use crate::{
Context, Result, Value,
};
pub(crate) mod eval;
pub(crate) mod range;
pub(crate) mod reference;
pub(crate) mod syntax;
pub(crate) mod r#type;
// pub(crate) mod eval;
// pub(crate) mod uri;
#[cfg(test)]
mod tests;
pub(crate) use self::eval::EvalError;
pub(crate) use self::r#type::TypeError;
pub(crate) use self::range::RangeError;
pub(crate) use self::reference::ReferenceError;
pub(crate) use self::syntax::SyntaxError;
// pub(crate) use self::eval::EvalError;
// pub(crate) use self::uri::UriError;
/// Built-in `Error` object.

25
boa/src/builtins/error/tests.rs

@ -28,3 +28,28 @@ fn error_to_string() {
);
assert_eq!(forward(&mut ctx, "type_e.toString()"), "\"TypeError: 5\"");
}
#[test]
fn eval_error_name() {
let mut ctx = Context::new();
assert_eq!(forward(&mut ctx, "EvalError.name"), "\"EvalError\"");
}
#[test]
fn eval_error_length() {
let mut ctx = Context::new();
assert_eq!(forward(&mut ctx, "EvalError.length"), "1");
}
#[test]
fn eval_error_to_string() {
let mut ctx = Context::new();
assert_eq!(
forward(&mut ctx, "new EvalError('hello').toString()"),
"\"EvalError: hello\""
);
assert_eq!(
forward(&mut ctx, "new EvalError().toString()"),
"\"EvalError\""
);
}

3
boa/src/builtins/mod.rs

@ -27,7 +27,7 @@ pub(crate) use self::{
bigint::BigInt,
boolean::Boolean,
date::Date,
error::{Error, RangeError, ReferenceError, SyntaxError, TypeError},
error::{Error, EvalError, RangeError, ReferenceError, SyntaxError, TypeError},
function::BuiltInFunctionObject,
global_this::GlobalThis,
infinity::Infinity,
@ -82,6 +82,7 @@ pub fn init(context: &mut Context) {
ReferenceError::init,
TypeError::init,
SyntaxError::init,
EvalError::init,
#[cfg(feature = "console")]
console::Console::init,
];

27
boa/src/context.rs

@ -81,6 +81,7 @@ pub struct StandardObjects {
referece_error: StandardConstructor,
range_error: StandardConstructor,
syntax_error: StandardConstructor,
eval_error: StandardConstructor,
}
impl StandardObjects {
@ -153,6 +154,11 @@ impl StandardObjects {
pub fn syntax_error_object(&self) -> &StandardConstructor {
&self.syntax_error
}
#[inline]
pub fn eval_error_object(&self) -> &StandardConstructor {
&self.eval_error
}
}
/// Javascript context. It is the primary way to interact with the runtime.
@ -374,6 +380,27 @@ impl Context {
Err(self.construct_syntax_error(message))
}
/// Constructs a `EvalError` with the specified message.
pub fn construct_eval_error<M>(&mut self, message: M) -> Value
where
M: Into<String>,
{
New::from(Call::new(
Identifier::from("EvalError"),
vec![Const::from(message.into()).into()],
))
.run(self)
.expect("Into<String> used as message")
}
/// Throws a `EvalError` with the specified message.
pub fn throw_eval_error<M>(&mut self, message: M) -> Result<Value>
where
M: Into<String>,
{
Err(self.construct_eval_error(message))
}
/// Utility to create a function Value for Function Declarations, Arrow Functions or Function Expressions
pub(crate) fn create_function<P, B>(
&mut self,

Loading…
Cancel
Save