Skip to content

Commit

Permalink
Adding native error types, starting with RangeError
Browse files Browse the repository at this point in the history
  • Loading branch information
Razican committed May 22, 2020
1 parent ffabf6a commit 6e8e0d9
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 9 deletions.
9 changes: 8 additions & 1 deletion boa/src/builtins/error.rs → boa/src/builtins/error/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,22 @@
//! [spec]: https://tc39.es/ecma262/#sec-error-objects
//! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
use super::function::make_constructor_fn;
use crate::{
builtins::{
function::make_constructor_fn,
object::ObjectKind,
value::{ResultValue, Value},
},
exec::Interpreter,
};

// mod eval;
pub mod range;
// mod reference;
// mod syntax;
// mod type_err;
// mod uri;

/// Create a new error object.
pub fn make_error(this: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
if !args.is_empty() {
Expand Down
67 changes: 67 additions & 0 deletions boa/src/builtins/error/range.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
//! This module implements the global `RangeError` object.
//!
//! Indicates a value that is not in the set or range of allowable values.
//!
//! More information:
//! - [MDN documentation][mdn]
//! - [ECMAScript reference][spec]
//!
//! [spec]: https://tc39.es/ecma262/#sec-native-error-types-used-in-this-standard-rangeerror
//! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RangeError
use crate::{
builtins::{
function::make_constructor_fn,
object::ObjectKind,
value::{ResultValue, Value},
},
exec::Interpreter,
};

/// Create a new error object.
pub fn make_error(this: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
if !args.is_empty() {
this.set_field_slice(
"message",
Value::from(
args.get(0)
.expect("failed getting error message")
.to_string(),
),
);
}
// This value is used by console.log and other routines to match Object type
// to its Javascript Identifier (global constructor method name)
this.set_kind(ObjectKind::Error);
Ok(Value::undefined())
}

/// `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
pub fn to_string(this: &mut Value, _: &[Value], _: &mut Interpreter) -> ResultValue {
let name = this.get_field_slice("name");
let message = this.get_field_slice("message");
Ok(Value::from(format!("{}: {}", name, message)))
}

/// Create a new `RangeError` object.
pub fn create(global: &Value) -> Value {
let prototype = Value::new_object(Some(global));
prototype.set_field_slice("message", Value::from(""));
prototype.set_field_slice("name", Value::from("RangeError"));
make_builtin_fn!(to_string, named "toString", of prototype);
make_constructor_fn(make_error, global, prototype)
}

/// Initialise the global object with the `RangeError` object.
pub fn init(global: &Value) {
global.set_field_slice("RangeError", create(global));
}
2 changes: 1 addition & 1 deletion boa/src/builtins/number/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ pub fn to_string(this: &mut Value, args: &[Value], _ctx: &mut Interpreter) -> Re

// 4. If radixNumber < 2 or radixNumber > 36, throw a RangeError exception.
if radix_number < 2 || radix_number > 36 {
panic!("Radix must be between 2 and 36");
panic!("RangeError: radix must be an integer at least 2 and no greater than 36");
}

// 5. If radixNumber = 10, return ! ToString(x).
Expand Down
13 changes: 6 additions & 7 deletions boa/src/exec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,12 @@ impl Interpreter {
this: &mut Value,
arguments_list: &[Value],
) -> ResultValue {
// All functions should be objects, and eventually will be.
// During this transition call will support both native functions and function objects
match (*f).deref() {
ValueData::Object(ref obj) => match (*obj).deref().borrow().func {
Some(ref func) => func.call(&mut f.clone(), arguments_list, self, this),
None => panic!("Expected function"),
},
match *f.data() {
ValueData::Object(ref obj) => {
let obj = (**obj).borrow();
let func = obj.func.as_ref().expect("Expected function");
func.call(&mut f.clone(), arguments_list, self, this)
}
_ => Err(Value::undefined()),
}
}
Expand Down

0 comments on commit 6e8e0d9

Please sign in to comment.