Skip to content

Commit

Permalink
Merge 6708820 into 8b40e9e
Browse files Browse the repository at this point in the history
  • Loading branch information
HalidOdat authored Jul 1, 2020
2 parents 8b40e9e + 6708820 commit 89fd802
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 47 deletions.
23 changes: 10 additions & 13 deletions boa/src/builtins/error/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,19 @@ use crate::{
profiler::BoaProfiler,
};

// mod eval;
pub(crate) mod range;
pub(crate) mod reference;
// mod syntax;
pub(crate) mod syntax;
pub(crate) mod r#type;
// mod uri;
// pub(crate) mod eval;
// pub(crate) mod uri;

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.
#[derive(Debug, Clone, Copy)]
Expand All @@ -43,17 +46,11 @@ impl Error {
pub(crate) const LENGTH: usize = 1;

/// Create a new error object.
pub(crate) fn make_error(this: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
if !args.is_empty() {
this.set_field(
"message",
Value::from(
args.get(0)
.expect("failed getting error message")
.to_string(),
),
);
pub(crate) fn make_error(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
if let Some(message) = args.get(0) {
this.set_field("message", ctx.to_string(message)?);
}

// 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);
Expand Down
17 changes: 6 additions & 11 deletions boa/src/builtins/error/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,11 @@ impl RangeError {
pub(crate) const LENGTH: usize = 1;

/// Create a new error object.
pub(crate) fn make_error(this: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
if !args.is_empty() {
this.set_field(
"message",
Value::from(
args.get(0)
.expect("failed getting error message")
.to_string(),
),
);
pub(crate) fn make_error(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
if let Some(message) = args.get(0) {
this.set_field("message", ctx.to_string(message)?);
}

// 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);
Expand All @@ -69,7 +63,8 @@ impl RangeError {
/// Create a new `RangeError` object.
pub(crate) fn create(global: &Value) -> Value {
let prototype = Value::new_object(Some(global));
prototype.set_field("message", Value::from(""));
prototype.set_field("name", Self::NAME);
prototype.set_field("message", "");

make_builtin_fn(Self::to_string, "toString", &prototype, 0);

Expand Down
17 changes: 6 additions & 11 deletions boa/src/builtins/error/reference.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,11 @@ impl ReferenceError {
pub(crate) const LENGTH: usize = 1;

/// Create a new error object.
pub(crate) fn make_error(this: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
if !args.is_empty() {
this.set_field(
"message",
Value::from(
args.get(0)
.expect("failed getting error message")
.to_string(),
),
);
pub(crate) fn make_error(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
if let Some(message) = args.get(0) {
this.set_field("message", ctx.to_string(message)?);
}

// 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);
Expand All @@ -68,7 +62,8 @@ impl ReferenceError {
/// Create a new `ReferenceError` object.
pub(crate) fn create(global: &Value) -> Value {
let prototype = Value::new_object(Some(global));
prototype.set_field("message", Value::from(""));
prototype.set_field("name", Self::NAME);
prototype.set_field("message", "");

make_builtin_fn(Self::to_string, "toString", &prototype, 0);

Expand Down
89 changes: 89 additions & 0 deletions boa/src/builtins/error/syntax.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
//! This module implements the global `SyntaxError` object.
//!
//! The SyntaxError object represents an error when trying to interpret syntactically invalid code.
//! It is thrown when the JavaScript engine encounters tokens or token order that does not conform
//! to the syntax of the language when parsing code.
//!
//! More information:
//! - [MDN documentation][mdn]
//! - [ECMAScript reference][spec]
//!
//! [spec]: https://tc39.es/ecma262/#sec-native-error-types-used-in-this-standard-syntaxerror
//! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError

use crate::{
builtins::{
function::make_builtin_fn,
function::make_constructor_fn,
object::ObjectData,
value::{ResultValue, Value},
},
exec::Interpreter,
profiler::BoaProfiler,
};
/// JavaScript `SyntaxError` impleentation.
#[derive(Debug, Clone, Copy)]
pub(crate) struct SyntaxError;

impl SyntaxError {
/// The name of the object.
pub(crate) const NAME: &'static str = "SyntaxError";

/// The amount of arguments this function object takes.
pub(crate) const LENGTH: usize = 1;

/// Create a new error object.
pub(crate) fn make_error(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
if let Some(message) = args.get(0) {
this.set_field("message", ctx.to_string(message)?);
}

// 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);
Err(this.clone())
}

/// `Error.prototype.toString()`
///
/// The toString() method returns a string representing the specified Error object.
///
/// More information:
/// - [MDN documentation][mdn]
/// - [ECMAScript reference][spec]
///
/// [spec]: https://tc39.es/ecma262/#sec-error.prototype.tostring
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/toString
#[allow(clippy::wrong_self_convention)]
pub(crate) fn to_string(this: &Value, _: &[Value], _: &mut Interpreter) -> ResultValue {
let name = this.get_field("name");
let message = this.get_field("message");
Ok(format!("{}: {}", name, message).into())
}

/// Create a new `SyntaxError` object.
pub(crate) fn create(global: &Value) -> Value {
let prototype = Value::new_object(Some(global));
prototype.set_field("name", Self::NAME);
prototype.set_field("message", "");

make_builtin_fn(Self::to_string, "toString", &prototype, 0);

make_constructor_fn(
Self::NAME,
Self::LENGTH,
Self::make_error,
global,
prototype,
true,
)
}

/// Initialise the global object with the `SyntaxError` object.
#[inline]
pub(crate) fn init(global: &Value) -> (&str, Value) {
let _timer = BoaProfiler::global().start_event(Self::NAME, "init");

(Self::NAME, Self::create(global))
}
}
16 changes: 5 additions & 11 deletions boa/src/builtins/error/type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,9 @@ impl TypeError {
pub(crate) const LENGTH: usize = 1;

/// Create a new error object.
pub(crate) fn make_error(this: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
if !args.is_empty() {
this.set_field(
"message",
Value::from(
args.get(0)
.expect("failed getting error message")
.to_string(),
),
);
pub(crate) fn make_error(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
if let Some(message) = args.get(0) {
this.set_field("message", ctx.to_string(message)?);
}

// This value is used by console.log and other routines to match Object type
Expand Down Expand Up @@ -76,7 +69,8 @@ impl TypeError {
/// Create a new `RangeError` object.
pub(crate) fn create(global: &Value) -> Value {
let prototype = Value::new_object(Some(global));
prototype.set_field("message", Value::from(""));
prototype.set_field("name", Self::NAME);
prototype.set_field("message", "");

make_builtin_fn(Self::to_string, "toString", &prototype, 0);

Expand Down
3 changes: 2 additions & 1 deletion boa/src/builtins/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub(crate) use self::{
array::Array,
bigint::BigInt,
boolean::Boolean,
error::{Error, RangeError, ReferenceError, TypeError},
error::{Error, RangeError, ReferenceError, SyntaxError, TypeError},
global_this::GlobalThis,
infinity::Infinity,
json::Json,
Expand Down Expand Up @@ -60,6 +60,7 @@ pub fn init(global: &Value) {
RangeError::init,
ReferenceError::init,
TypeError::init,
SyntaxError::init,
// Global properties.
NaN::init,
Infinity::init,
Expand Down
21 changes: 21 additions & 0 deletions boa/src/exec/exception.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,25 @@ impl Interpreter {
{
Err(self.construct_reference_error(message))
}

/// Constructs a `SyntaxError` with the specified message.
pub fn construct_syntax_error<M>(&mut self, message: M) -> Value
where
M: Into<String>,
{
New::from(Call::new(
Identifier::from("SyntaxError"),
vec![Const::from(message.into()).into()],
))
.run(self)
.expect_err("SyntaxError should always throw")
}

/// Throws a `SyntaxError` with the specified message.
pub fn throw_syntax_error<M>(&mut self, message: M) -> ResultValue
where
M: Into<String>,
{
Err(self.construct_syntax_error(message))
}
}

0 comments on commit 89fd802

Please sign in to comment.