Skip to content

Commit

Permalink
construct_type_error and construct_range_error
Browse files Browse the repository at this point in the history
  • Loading branch information
HalidOdat committed Jun 15, 2020
1 parent c144cbd commit 25572f5
Show file tree
Hide file tree
Showing 11 changed files with 65 additions and 50 deletions.
3 changes: 1 addition & 2 deletions boa/src/builtins/bigint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,7 @@ impl BigInt {
}

// 3. Throw a TypeError exception.
ctx.throw_type_error("'this' is not a BigInt")?;
unreachable!();
Err(ctx.construct_type_error("'this' is not a BigInt"))
}

/// `BigInt()`
Expand Down
4 changes: 1 addition & 3 deletions boa/src/builtins/boolean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,7 @@ impl Boolean {
_ => {}
}

Err(ctx
.throw_type_error("'this' is not a boolean")
.expect_err("throw_type_error() did not return an error"))
Err(ctx.construct_type_error("'this' is not a boolean"))
}

/// `[[Construct]]` Create a new boolean object
Expand Down
5 changes: 4 additions & 1 deletion boa/src/builtins/function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,9 @@ pub fn make_constructor_fn(
prototype: Value,
constructable: bool,
) -> Value {
let _timer =
BoaProfiler::global().start_event(&format!("make_constructor_fn: {}", name), "init");

// Create the native function
let mut function = Function::builtin(Vec::new(), body);
function.constructable = constructable;
Expand Down Expand Up @@ -478,7 +481,7 @@ where
N: Into<String>,
{
let name = name.into();
let _timer = BoaProfiler::global().start_event(&name, "make_builtin_fn");
let _timer = BoaProfiler::global().start_event(&format!("make_builtin_fn: {}", &name), "init");

let mut function = Object::function(Function::builtin(Vec::new(), function));
function.insert_field("length", Value::from(length));
Expand Down
1 change: 1 addition & 0 deletions boa/src/builtins/global_this/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ mod tests;
pub(crate) struct GlobalThis;

impl GlobalThis {
/// The binding name of the property.
pub(crate) const NAME: &'static str = "globalThis";

/// Initialize the `globalThis` property on the global object.
Expand Down
2 changes: 1 addition & 1 deletion boa/src/builtins/nan/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use crate::{builtins::value::Value, BoaProfiler};
pub(crate) struct NaN;

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

/// Initialize the `NaN` property on the global object.
Expand Down
4 changes: 1 addition & 3 deletions boa/src/builtins/number/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,7 @@ impl Number {
_ => {}
}

Err(ctx
.throw_type_error("'this' is not a number")
.expect_err("throw_type_error() did not return an error"))
Err(ctx.construct_type_error("'this' is not a number"))
}

/// Helper function that formats a float as a ES6-style exponential number string.
Expand Down
4 changes: 1 addition & 3 deletions boa/src/builtins/string/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,7 @@ impl String {
_ => {}
}

Err(ctx
.throw_type_error("'this' is not a string")
.expect_err("throw_type_error() did not return an error"))
Err(ctx.construct_type_error("'this' is not a string"))
}

/// [[Construct]] - Creates a new instance `this`
Expand Down
3 changes: 1 addition & 2 deletions boa/src/builtins/symbol/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,7 @@ impl Symbol {
_ => {}
}

ctx.throw_type_error("'this' is not a Symbol")?;
unreachable!();
Err(ctx.construct_type_error("'this' is not a Symbol"))
}

/// The `Symbol()` constructor returns a value of type symbol.
Expand Down
6 changes: 3 additions & 3 deletions boa/src/builtins/value/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,9 +257,9 @@ impl Value {
.map(JSONValue::Number)
.unwrap_or(JSONValue::Null)),
ValueData::Integer(val) => Ok(JSONValue::Number(JSONNumber::from(val))),
ValueData::BigInt(_) => Err(interpreter
.throw_type_error("BigInt value can't be serialized in JSON")
.expect_err("throw_type_error should always return an error")),
ValueData::BigInt(_) => {
Err(interpreter.construct_type_error("BigInt value can't be serialized in JSON"))
}
ValueData::Symbol(_) | ValueData::Undefined => {
unreachable!("Symbols and Undefined JSON Values depend on parent type");
}
Expand Down
42 changes: 38 additions & 4 deletions boa/src/exec/exception.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use crate::{
};

impl Interpreter {
/// Throws a `RangeError` with the specified message.
pub fn throw_range_error<M>(&mut self, message: M) -> ResultValue
/// Constructs a `RangeError` with the specified message.
pub fn construct_range_error<M>(&mut self, message: M) -> Value
where
M: Into<String>,
{
Expand All @@ -19,10 +19,19 @@ impl Interpreter {
vec![Const::from(message.into()).into()],
))
.run(self)
.expect_err("RangeError should always throw")
}

/// Throws a `TypeError` with the specified message.
pub fn throw_type_error<M>(&mut self, message: M) -> ResultValue
/// Throws a `RangeError` with the specified message.
pub fn throw_range_error<M>(&mut self, message: M) -> ResultValue
where
M: Into<String>,
{
Err(self.construct_range_error(message))
}

/// Constructs a `TypeError` with the specified message.
pub fn construct_type_error<M>(&mut self, message: M) -> Value
where
M: Into<String>,
{
Expand All @@ -32,5 +41,30 @@ impl Interpreter {
vec![Const::from(message.into()).into()],
))
.run(self)
.expect_err("TypeError should always throw")
}

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

/// Constructs a `ReferenceError` with the specified message.
pub fn construct_reference_error<M>(&mut self, _message: M) -> Value
where
M: Into<String>,
{
unimplemented!("ReferenceError: is not implemented");
}

/// Throws a `ReferenceError` with the specified message.
pub fn throw_reference_error<M>(&mut self, message: M) -> ResultValue
where
M: Into<String>,
{
Err(self.construct_reference_error(message))
}
}
41 changes: 13 additions & 28 deletions boa/src/exec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,7 @@ impl Interpreter {
ValueData::Integer(integer) => Ok(integer.to_string()),
ValueData::String(string) => Ok(string.clone()),
ValueData::Symbol(_) => {
self.throw_type_error("can't convert symbol to string")?;
unreachable!();
Err(self.construct_type_error("can't convert symbol to string"))
}
ValueData::BigInt(ref bigint) => Ok(bigint.to_string()),
ValueData::Object(_) => {
Expand All @@ -196,13 +195,9 @@ impl Interpreter {
#[allow(clippy::wrong_self_convention)]
pub fn to_bigint(&mut self, value: &Value) -> Result<BigInt, Value> {
match value.data() {
ValueData::Null => {
self.throw_type_error("cannot convert null to a BigInt")?;
unreachable!();
}
ValueData::Null => Err(self.construct_type_error("cannot convert null to a BigInt")),
ValueData::Undefined => {
self.throw_type_error("cannot convert undefined to a BigInt")?;
unreachable!();
Err(self.construct_type_error("cannot convert undefined to a BigInt"))
}
ValueData::String(ref string) => Ok(BigInt::from_string(string, self)?),
ValueData::Boolean(true) => Ok(BigInt::from(1)),
Expand All @@ -212,20 +207,18 @@ impl Interpreter {
if let Ok(bigint) = BigInt::try_from(*num) {
return Ok(bigint);
}
self.throw_type_error(format!(
Err(self.construct_type_error(format!(
"The number {} cannot be converted to a BigInt because it is not an integer",
num
))?;
unreachable!();
)))
}
ValueData::BigInt(b) => Ok(b.clone()),
ValueData::Object(_) => {
let primitive = self.to_primitive(&mut value.clone(), PreferredType::Number);
self.to_bigint(&primitive)
}
ValueData::Symbol(_) => {
self.throw_type_error("cannot convert Symbol to a BigInt")?;
unreachable!();
Err(self.construct_type_error("cannot convert Symbol to a BigInt"))
}
}
}
Expand All @@ -242,13 +235,11 @@ impl Interpreter {
let integer_index = self.to_integer(value)?;

if integer_index < 0 {
self.throw_range_error("Integer index must be >= 0")?;
unreachable!();
return Err(self.construct_range_error("Integer index must be >= 0"));
}

if integer_index > 2i64.pow(53) - 1 {
self.throw_range_error("Integer index must be less than 2**(53) - 1")?;
unreachable!()
return Err(self.construct_range_error("Integer index must be less than 2**(53) - 1"));
}

Ok(integer_index as usize)
Expand Down Expand Up @@ -281,14 +272,8 @@ impl Interpreter {
ValueData::String(ref string) => Ok(string.parse().unwrap_or(f64::NAN)),
ValueData::Rational(number) => Ok(number),
ValueData::Integer(integer) => Ok(f64::from(integer)),
ValueData::Symbol(_) => {
self.throw_type_error("argument must not be a symbol")?;
unreachable!()
}
ValueData::BigInt(_) => {
self.throw_type_error("argument must not be a bigint")?;
unreachable!()
}
ValueData::Symbol(_) => Err(self.construct_type_error("argument must not be a symbol")),
ValueData::BigInt(_) => Err(self.construct_type_error("argument must not be a bigint")),
ValueData::Object(_) => {
let prim_value = self.to_primitive(&mut (value.clone()), PreferredType::Number);
self.to_number(&prim_value)
Expand Down Expand Up @@ -575,10 +560,10 @@ impl Interpreter {
#[inline]
pub fn require_object_coercible<'a>(&mut self, value: &'a Value) -> Result<&'a Value, Value> {
if value.is_null_or_undefined() {
self.throw_type_error("cannot convert null or undefined to Object")?;
unreachable!();
Err(self.construct_type_error("cannot convert null or undefined to Object"))
} else {
Ok(value)
}
Ok(value)
}
}

Expand Down

0 comments on commit 25572f5

Please sign in to comment.