Skip to content

Commit

Permalink
Feature EvalError (#804)
Browse files Browse the repository at this point in the history
  • Loading branch information
HalidOdat authored Oct 6, 2020
1 parent 39b4ead commit 03f9632
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 3 deletions.
69 changes: 69 additions & 0 deletions boa/src/builtins/error/eval.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 2 additions & 2 deletions boa/src/builtins/error/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
25 changes: 25 additions & 0 deletions boa/src/builtins/error/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 2 additions & 1 deletion boa/src/builtins/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -82,6 +82,7 @@ pub fn init(context: &mut Context) {
ReferenceError::init,
TypeError::init,
SyntaxError::init,
EvalError::init,
#[cfg(feature = "console")]
console::Console::init,
];
Expand Down
27 changes: 27 additions & 0 deletions boa/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ pub struct StandardObjects {
referece_error: StandardConstructor,
range_error: StandardConstructor,
syntax_error: StandardConstructor,
eval_error: StandardConstructor,
}

impl StandardObjects {
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 03f9632

Please sign in to comment.