Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Well-Known Symbols #587

Merged
merged 5 commits into from
Jul 29, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion boa/src/builtins/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1114,7 +1114,8 @@ impl Array {

/// Initialise the `Array` object on the global object.
#[inline]
pub(crate) fn init(global: &Value) -> (&str, Value) {
pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) {
let global = &interpreter.realm.global_obj;
joshwd36 marked this conversation as resolved.
Show resolved Hide resolved
let _timer = BoaProfiler::global().start_event(Self::NAME, "init");

// Create prototype
Expand Down
3 changes: 2 additions & 1 deletion boa/src/builtins/bigint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@ impl BigInt {

/// Initialise the `BigInt` object on the global object.
#[inline]
pub(crate) fn init(global: &Value) -> (&str, Value) {
pub fn init(interpreter: &mut Interpreter) -> (&'static str, Value) {
let global = &interpreter.realm.global_obj;
let _timer = BoaProfiler::global().start_event(Self::NAME, "init");

let prototype = Value::new_object(Some(global));
Expand Down
3 changes: 2 additions & 1 deletion boa/src/builtins/boolean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ impl Boolean {

/// Initialise the `Boolean` object on the global object.
#[inline]
pub(crate) fn init(global: &Value) -> (&str, Value) {
pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) {
let global = &interpreter.realm.global_obj;
let _timer = BoaProfiler::global().start_event(Self::NAME, "init");

// Create Prototype
Expand Down
3 changes: 2 additions & 1 deletion boa/src/builtins/console/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,8 @@ impl Console {

/// Initialise the `console` object on the global object.
#[inline]
pub(crate) fn init(global: &Value) -> (&str, Value) {
pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) {
let global = &interpreter.realm.global_obj;
let _timer = BoaProfiler::global().start_event(Self::NAME, "init");

let console = Value::new_object(Some(global));
Expand Down
3 changes: 2 additions & 1 deletion boa/src/builtins/error/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ impl Error {

/// Initialise the global object with the `Error` object.
#[inline]
pub(crate) fn init(global: &Value) -> (&str, Value) {
pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) {
let global = &interpreter.realm.global_obj;
let _timer = BoaProfiler::global().start_event(Self::NAME, "init");

let prototype = Value::new_object(Some(global));
Expand Down
3 changes: 2 additions & 1 deletion boa/src/builtins/error/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ impl RangeError {

/// Initialise the global object with the `RangeError` object.
#[inline]
pub(crate) fn init(global: &Value) -> (&str, Value) {
pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) {
let global = &interpreter.realm.global_obj;
let _timer = BoaProfiler::global().start_event(Self::NAME, "init");

let prototype = Value::new_object(Some(global));
Expand Down
3 changes: 2 additions & 1 deletion boa/src/builtins/error/reference.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ impl ReferenceError {
}

/// Initialise the global object with the `ReferenceError` object.
pub(crate) fn init(global: &Value) -> (&str, Value) {
pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) {
let global = &interpreter.realm.global_obj;
let _timer = BoaProfiler::global().start_event(Self::NAME, "init");

let prototype = Value::new_object(Some(global));
Expand Down
3 changes: 2 additions & 1 deletion boa/src/builtins/error/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ impl SyntaxError {

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

let prototype = Value::new_object(Some(global));
Expand Down
3 changes: 2 additions & 1 deletion boa/src/builtins/error/type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ impl TypeError {

/// Initialise the global object with the `RangeError` object.
#[inline]
pub(crate) fn init(global: &Value) -> (&str, Value) {
pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) {
let global = &interpreter.realm.global_obj;
let _timer = BoaProfiler::global().start_event(Self::NAME, "init");

let prototype = Value::new_object(Some(global));
Expand Down
3 changes: 2 additions & 1 deletion boa/src/builtins/function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,8 @@ where

/// Initialise the `Function` object on the global object.
#[inline]
pub fn init(global: &Value) -> (&str, Value) {
pub fn init(interpreter: &mut Interpreter) -> (&'static str, Value) {
let global = &interpreter.realm.global_obj;
let _timer = BoaProfiler::global().start_event("function", "init");
let prototype = Value::new_object(Some(global));

Expand Down
5 changes: 3 additions & 2 deletions boa/src/builtins/global_this/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
//! [spec]: https://tc39.es/ecma262/#sec-globalthis
//! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis

use crate::{builtins::value::Value, BoaProfiler};
use crate::{builtins::value::Value, BoaProfiler, Interpreter};

#[cfg(test)]
mod tests;
Expand All @@ -24,7 +24,8 @@ impl GlobalThis {

/// Initialize the `globalThis` property on the global object.
#[inline]
pub(crate) fn init(global: &Value) -> (&str, Value) {
pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) {
let global = &interpreter.realm.global_obj;
let _timer = BoaProfiler::global().start_event(Self::NAME, "init");

(Self::NAME, global.clone())
Expand Down
4 changes: 2 additions & 2 deletions boa/src/builtins/infinity/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#[cfg(test)]
mod tests;

use crate::{builtins::value::Value, BoaProfiler};
use crate::{builtins::value::Value, BoaProfiler, Interpreter};

/// JavaScript global `Infinity` property.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
Expand All @@ -24,7 +24,7 @@ impl Infinity {

/// Initialize the `Infinity` property on the global object.
#[inline]
pub(crate) fn init(_: &Value) -> (&str, Value) {
pub(crate) fn init(_interpreter: &mut Interpreter) -> (&'static str, Value) {
let _timer = BoaProfiler::global().start_event(Self::NAME, "init");

(Self::NAME, Value::from(f64::INFINITY))
Expand Down
3 changes: 2 additions & 1 deletion boa/src/builtins/json/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ impl Json {

/// Initialise the `JSON` object on the global object.
#[inline]
pub(crate) fn init(global: &Value) -> (&str, Value) {
pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) {
let global = &interpreter.realm.global_obj;
let _timer = BoaProfiler::global().start_event(Self::NAME, "init");
let json = Value::new_object(Some(global));

Expand Down
3 changes: 2 additions & 1 deletion boa/src/builtins/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,8 @@ impl Map {
}

/// Initialise the `Map` object on the global object.
pub(crate) fn init(global: &Value) -> (&str, Value) {
pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) {
let global = &interpreter.realm.global_obj;
let _timer = BoaProfiler::global().start_event(Self::NAME, "init");

// Create prototype
Expand Down
3 changes: 2 additions & 1 deletion boa/src/builtins/math/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,8 @@ impl Math {

/// Initialise the `Math` object on the global object.
#[inline]
pub(crate) fn init(global: &Value) -> (&str, Value) {
pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) {
let global = &interpreter.realm.global_obj;
let _timer = BoaProfiler::global().start_event(Self::NAME, "init");

(Self::NAME, Self::create(global))
Expand Down
14 changes: 8 additions & 6 deletions boa/src/builtins/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,11 @@ pub(crate) use self::{
undefined::Undefined,
value::{ResultValue, Value},
};
use crate::Interpreter;

/// Initializes builtin objects and functions
#[inline]
pub fn init(global: &Value) {
pub fn init(interpreter: &mut Interpreter) {
let globals = [
// The `Function` global must be initialized before other types.
function::init,
Expand Down Expand Up @@ -72,13 +73,14 @@ pub fn init(global: &Value) {
Undefined::init,
];

match global {
Value::Object(ref global_object) => {
for init in &globals {
let (name, value) = init(global);
for init in &globals {
let (name, value) = init(interpreter);
let global = &interpreter.realm.global_obj;
match global {
Value::Object(ref global_object) => {
global_object.borrow_mut().insert_field(name, value);
}
_ => unreachable!("expect global object"),
}
_ => unreachable!("expect global object"),
}
}
4 changes: 2 additions & 2 deletions boa/src/builtins/nan/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#[cfg(test)]
mod tests;

use crate::{builtins::value::Value, BoaProfiler};
use crate::{builtins::value::Value, BoaProfiler, Interpreter};

/// JavaScript global `NaN` property.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
Expand All @@ -25,7 +25,7 @@ impl NaN {

/// Initialize the `NaN` property on the global object.
#[inline]
pub(crate) fn init(_: &Value) -> (&str, Value) {
pub(crate) fn init(_interpreter: &mut Interpreter) -> (&'static str, Value) {
let _timer = BoaProfiler::global().start_event(Self::NAME, "init");

(Self::NAME, Value::from(f64::NAN))
Expand Down
3 changes: 2 additions & 1 deletion boa/src/builtins/number/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,8 @@ impl Number {

/// Initialise the `Number` object on the global object.
#[inline]
pub(crate) fn init(global: &Value) -> (&str, Value) {
pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) {
let global = &interpreter.realm.global_obj;
let _timer = BoaProfiler::global().start_event(Self::NAME, "init");

let prototype = Value::new_object(Some(global));
Expand Down
3 changes: 2 additions & 1 deletion boa/src/builtins/object/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,8 @@ pub fn property_is_enumerable(this: &Value, args: &[Value], ctx: &mut Interprete

/// Initialise the `Object` object on the global object.
#[inline]
pub fn init(global: &Value) -> (&str, Value) {
pub fn init(interpreter: &mut Interpreter) -> (&'static str, Value) {
let global = &interpreter.realm.global_obj;
let _timer = BoaProfiler::global().start_event("object", "init");

let prototype = Value::new_object(None);
Expand Down
3 changes: 2 additions & 1 deletion boa/src/builtins/regexp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,8 @@ impl RegExp {

/// Initialise the `RegExp` object on the global object.
#[inline]
pub(crate) fn init(global: &Value) -> (&str, Value) {
pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) {
let global = &interpreter.realm.global_obj;
let _timer = BoaProfiler::global().start_event(Self::NAME, "init");

(Self::NAME, Self::create(global))
Expand Down
3 changes: 2 additions & 1 deletion boa/src/builtins/string/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1023,7 +1023,8 @@ impl String {

/// Initialise the `String` object on the global object.
#[inline]
pub(crate) fn init(global: &Value) -> (&str, Value) {
pub(crate) fn init(interpreter: &mut Interpreter) -> (&'static str, Value) {
let global = &interpreter.realm.global_obj;
let _timer = BoaProfiler::global().start_event(Self::NAME, "init");

// Create `String` `prototype`
Expand Down
52 changes: 51 additions & 1 deletion boa/src/builtins/symbol/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,40 @@ impl Symbol {

/// Initialise the `Symbol` object on the global object.
#[inline]
pub fn init(global: &Value) -> (&str, Value) {
pub fn init(interpreter: &mut Interpreter) -> (&'static str, Value) {
let symbol_async_iterator = Symbol(
Some("Symbol.asyncIterator".into()),
interpreter.generate_hash(),
);
let symbol_has_instance = Symbol(
Some("Symbol.hasInstance".into()),
interpreter.generate_hash(),
);
let symbol_is_concat_spreadable = Symbol(
Some("Symbol.isConcatSpreadable".into()),
interpreter.generate_hash(),
);
let symbol_iterator = Symbol(Some("Symbol.iterator".into()), interpreter.generate_hash());
let symbol_match = Symbol(Some("Symbol.match".into()), interpreter.generate_hash());
let symbol_match_all = Symbol(Some("Symbol.matchAll".into()), interpreter.generate_hash());
joshwd36 marked this conversation as resolved.
Show resolved Hide resolved
let symbol_replace = Symbol(Some("Symbol.replace".into()), interpreter.generate_hash());
let symbol_search = Symbol(Some("Symbol.search".into()), interpreter.generate_hash());
let symbol_species = Symbol(Some("Symbol.species".into()), interpreter.generate_hash());
let symbol_split = Symbol(Some("Symbol.split".into()), interpreter.generate_hash());
let symbol_to_primitive = Symbol(
Some("Symbol.toPrimitive".into()),
interpreter.generate_hash(),
);
let symbol_to_string_tag = Symbol(
Some("Symbol.toStringTag".into()),
interpreter.generate_hash(),
);
let symbol_unscopables = Symbol(
Some("Symbol.unscopables".into()),
interpreter.generate_hash(),
);

let global = &interpreter.realm.global_obj;
let _timer = BoaProfiler::global().start_event(Self::NAME, "init");

// Create prototype object
Expand All @@ -118,6 +151,23 @@ impl Symbol {
true,
);

symbol_object.set_field("asyncIterator", Value::symbol(symbol_async_iterator));
symbol_object.set_field("hasInstance", Value::symbol(symbol_has_instance));
symbol_object.set_field(
"isConcatSpreadable",
Value::symbol(symbol_is_concat_spreadable),
);
symbol_object.set_field("iterator", Value::symbol(symbol_iterator));
symbol_object.set_field("match", Value::symbol(symbol_match));
symbol_object.set_field("matchAll", Value::symbol(symbol_match_all));
symbol_object.set_field("replace", Value::symbol(symbol_replace));
symbol_object.set_field("search", Value::symbol(symbol_search));
symbol_object.set_field("species", Value::symbol(symbol_species));
symbol_object.set_field("split", Value::symbol(symbol_split));
symbol_object.set_field("toPrimitive", Value::symbol(symbol_to_primitive));
symbol_object.set_field("toStringTag", Value::symbol(symbol_to_string_tag));
symbol_object.set_field("unscopables", Value::symbol(symbol_unscopables));

(Self::NAME, symbol_object)
}
}
4 changes: 2 additions & 2 deletions boa/src/builtins/undefined/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#[cfg(test)]
mod tests;

use crate::{builtins::value::Value, BoaProfiler};
use crate::{builtins::value::Value, BoaProfiler, Interpreter};

/// JavaScript global `undefined` property.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
Expand All @@ -24,7 +24,7 @@ impl Undefined {

/// Initialize the `undefined` property on the global object.
#[inline]
pub(crate) fn init(_: &Value) -> (&str, Value) {
pub(crate) fn init(_interpreter: &mut Interpreter) -> (&'static str, Value) {
let _timer = BoaProfiler::global().start_event(Self::NAME, "init");

(Self::NAME, Value::undefined())
Expand Down
18 changes: 16 additions & 2 deletions boa/src/exec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ mod throw;
mod try_node;

use crate::{
builtins,
builtins::{
function::{Function as FunctionObject, FunctionBody, ThisMode},
number::{f64_to_int32, f64_to_uint32},
Expand Down Expand Up @@ -79,12 +80,25 @@ pub struct Interpreter {
impl Interpreter {
/// Creates a new interpreter.
pub fn new(realm: Realm) -> Self {
Self {
let mut interpreter = Self {
state: InterpreterState::Executing,
realm,
symbol_count: 0,
console: Console::default(),
}
};

// Add new builtIns to Interpreter Realm
// At a later date this can be removed from here and called explicitly, but for now we almost always want these default builtins
interpreter.create_intrinsics();

interpreter
}

/// Sets up the default global objects within Global
fn create_intrinsics(&mut self) {
let _timer = BoaProfiler::global().start_event("create_intrinsics", "interpreter");
// Create intrinsics, add global objects here
builtins::init(self);
}

/// Retrieves the `Realm` of this executor.
Expand Down