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

Object specialization #419

Merged
merged 9 commits into from
Jun 15, 2020
Prev Previous commit
Next Next commit
Changed init functions to return a (&str, Value)
  • Loading branch information
HalidOdat committed Jun 15, 2020
commit 5eb1a39fd464e3523d3f7887c3274f8c20038ce1
5 changes: 2 additions & 3 deletions boa/src/builtins/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1041,10 +1041,9 @@ impl Array {

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

let array = Self::create(global);
global.as_object_mut().unwrap().insert_field("Array", array);
("Array", Self::create(global))
}
}
8 changes: 2 additions & 6 deletions boa/src/builtins/bigint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,14 +223,10 @@ impl BigInt {

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

let bigint = Self::create(global);
global
.as_object_mut()
.unwrap()
.insert_field("BigInt", bigint);
("BigInt", Self::create(global))
}
}

Expand Down
8 changes: 2 additions & 6 deletions boa/src/builtins/boolean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,9 @@ impl Boolean {

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

let boolean = Self::create(global);
global
.as_object_mut()
.unwrap()
.insert_field("Boolean", boolean);
("Boolean", Self::create(global))
}
}
8 changes: 2 additions & 6 deletions boa/src/builtins/console/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -554,12 +554,8 @@ pub fn create(global: &Value) -> Value {

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

let console = create(global);
global
.as_object_mut()
.unwrap()
.insert_field("console", console);
("console", create(global))
}
5 changes: 2 additions & 3 deletions boa/src/builtins/error/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,9 @@ impl Error {
}

/// Initialise the global object with the `Error` object.
pub(crate) fn init(global: &Value) {
pub(crate) fn init(global: &Value) -> (&str, Value) {
let _timer = BoaProfiler::global().start_event("error", "init");

let error = Self::create(global);
global.as_object_mut().unwrap().insert_field("Error", error);
("Error", Self::create(global))
}
}
8 changes: 2 additions & 6 deletions boa/src/builtins/error/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,9 @@ impl RangeError {
}

/// Initialise the global object with the `RangeError` object.
pub(crate) fn init(global: &Value) {
pub(crate) fn init(global: &Value) -> (&str, Value) {
let _timer = BoaProfiler::global().start_event("rangeerror", "init");

let range_error = Self::create(global);
global
.as_object_mut()
.unwrap()
.insert_field("RangeError", range_error);
("RangeError", Self::create(global))
}
}
4 changes: 2 additions & 2 deletions boa/src/builtins/error/type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ impl TypeError {
}

/// Initialise the global object with the `RangeError` object.
pub(crate) fn init(global: &Value) {
pub(crate) fn init(global: &Value) -> (&str, Value) {
HalidOdat marked this conversation as resolved.
Show resolved Hide resolved
let _timer = BoaProfiler::global().start_event("typeerror", "init");

global.set_field("TypeError", Self::create(global));
("TypeError", Self::create(global))
}
}
8 changes: 2 additions & 6 deletions boa/src/builtins/function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -491,12 +491,8 @@ where

/// Initialise the `Function` object on the global object.
#[inline]
pub fn init(global: &Value) {
pub fn init(global: &Value) -> (&str, Value) {
let _timer = BoaProfiler::global().start_event("function", "init");

let function = create(global);
global
.as_object_mut()
.unwrap()
.insert_field("Function", function);
("Function", create(global))
}
32 changes: 26 additions & 6 deletions boa/src/builtins/global_this/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,31 @@
//! This module implements the global `globalThis` property.
//!
//! The global globalThis property contains the global this value,
//! which is akin to the global object.
//!
//! More information:
//! - [MDN documentation][mdn]
//! - [ECMAScript reference][spec]
//!
//! [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};

#[cfg(test)]
mod tests;

use crate::{builtins::value::Value, BoaProfiler};
/// The JavaScript `globalThis`.
pub(crate) struct GlobalThis;

impl GlobalThis {
pub(crate) const NAME: &'static str = "globalThis";

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

/// Initialize the `globalThis` property on the global object.
#[inline]
pub fn init(global: &Value) {
let _timer = BoaProfiler::global().start_event("globalThis", "init");
global.set_field("globalThis", global.clone());
(Self::NAME, global.clone())
}
}
5 changes: 2 additions & 3 deletions boa/src/builtins/json/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,8 @@ pub fn create(global: &Value) -> Value {

/// Initialise the `JSON` object on the global object.
#[inline]
pub fn init(global: &Value) {
pub fn init(global: &Value) -> (&str, Value) {
let _timer = BoaProfiler::global().start_event("json", "init");

let json = create(global);
global.as_object_mut().unwrap().insert_field("JSON", json);
("JSON", create(global))
}
5 changes: 3 additions & 2 deletions boa/src/builtins/math/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,8 @@ pub fn create(global: &Value) -> Value {

/// Initialise the `Math` object on the global object.
#[inline]
pub fn init(global: &Value) {
pub fn init(global: &Value) -> (&str, Value) {
let _timer = BoaProfiler::global().start_event("math", "init");
global.set_field("Math", create(global));

("Math", create(global))
}
42 changes: 25 additions & 17 deletions boa/src/builtins/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ pub(crate) use self::{
bigint::BigInt,
boolean::Boolean,
error::{Error, RangeError, TypeError},
global_this::GlobalThis,
nan::NaN,
number::Number,
regexp::RegExp,
string::String,
Expand All @@ -33,22 +35,28 @@ pub(crate) use self::{
/// Initializes builtin objects and functions
#[inline]
pub fn init(global: &Value) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be mostly easy to implement:

Suggested change
pub fn init(global: &Value) {
pub fn init(global: &mut Object) {

We would need to use Object::default() in the Realm constructor here. And then implement From<Object> for Value.

Finally, I would change the new_object() function here to not accept an Option, but to require always a global object.

This would allow implementing initialization with a very fast implementation, even doing it multi-threaded at some point.

Then, I think that we should create a trait or a type with a function that receives a &mut Object as a parameter and returns a (&'static str, Value), this would help with creating an external API.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes. this would make somethings easier but what if we wanted an object to reference the global object (for example globalThis), this would make it really hard, right?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes. this would make somethings easier but what if we wanted an object to reference the global object (for example globalThis), this would make it really hard, right?

Hmmm yes, this would be more difficult, like if we want to have top/window/globalThis, all pointing to the global object.

I think we can merge it as it is now, and maybe think on a design in the future :)

function::init(global);
Array::init(global);
BigInt::init(global);
Boolean::init(global);
global_this::init(global);
json::init(global);
math::init(global);
nan::init(global);
Number::init(global);
object::init(global);
RegExp::init(global);
String::init(global);
Symbol::init(global);
console::init(global);
let globals = vec![
HalidOdat marked this conversation as resolved.
Show resolved Hide resolved
function::init(global),
Array::init(global),
BigInt::init(global),
Boolean::init(global),
json::init(global),
math::init(global),
Number::init(global),
NaN::init(global),
GlobalThis::init(global),
object::init(global),
RegExp::init(global),
String::init(global),
Symbol::init(global),
console::init(global),
Error::init(global),
RangeError::init(global),
TypeError::init(global),
];

HalidOdat marked this conversation as resolved.
Show resolved Hide resolved
Error::init(global);
RangeError::init(global);
TypeError::init(global);
let mut global_object = global.as_object_mut().expect("global object");
HalidOdat marked this conversation as resolved.
Show resolved Hide resolved
for (name, value) in globals {
global_object.insert_field(name, value);
}
}
29 changes: 24 additions & 5 deletions boa/src/builtins/nan/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,30 @@
//! This module implements the global `NaN` property.
//!
//! The global `NaN` is a property of the global object. In other words,
//! it is a variable in global scope.
//!
//! More information:
//! - [MDN documentation][mdn]
//! - [ECMAScript reference][spec]
//!
//! [spec]: https://tc39.es/ecma262/#sec-value-properties-of-the-global-object-nan
//! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN

#[cfg(test)]
mod tests;

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

/// Initialize the `NaN` property on the global object.
#[inline]
pub fn init(global: &Value) {
let _timer = BoaProfiler::global().start_event("NaN", "init");
global.set_field("NaN", Value::from(f64::NAN));
/// JavaScript global `NaN` property.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub(crate) struct NaN;

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

("NaN", Value::from(f64::NAN))
}
}
8 changes: 2 additions & 6 deletions boa/src/builtins/number/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -571,14 +571,10 @@ impl Number {

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

let number = Self::create(global);
global
.as_object_mut()
.unwrap()
.insert_field("Number", number);
("Number", Self::create(global))
}

/// The abstract operation Number::equal takes arguments
Expand Down
8 changes: 2 additions & 6 deletions boa/src/builtins/object/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -488,12 +488,8 @@ pub fn create(global: &Value) -> Value {

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

let object = create(global);
global
.as_object_mut()
.unwrap()
.insert_field("Object", object);
("Object", create(global))
}
9 changes: 3 additions & 6 deletions boa/src/builtins/regexp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,12 +492,9 @@ impl RegExp {

/// Initialise the `RegExp` object on the global object.
#[inline]
pub(crate) fn init(global: &Value) {
pub(crate) fn init(global: &Value) -> (&str, Value) {
let _timer = BoaProfiler::global().start_event("regexp", "init");
let regexp = Self::create(global);
global
.as_object_mut()
.unwrap()
.insert_field("RegExp", regexp);

("RegExp", Self::create(global))
}
}
9 changes: 3 additions & 6 deletions boa/src/builtins/string/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1085,12 +1085,9 @@ impl String {

/// Initialise the `String` object on the global object.
#[inline]
pub(crate) fn init(global: &Value) {
pub(crate) fn init(global: &Value) -> (&str, Value) {
let _timer = BoaProfiler::global().start_event("string", "init");
let string = Self::create(global);
global
.as_object_mut()
.unwrap()
.insert_field("String", string);

("String", Self::create(global))
}
}
9 changes: 3 additions & 6 deletions boa/src/builtins/symbol/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,9 @@ impl Symbol {

/// Initialise the `Symbol` object on the global object.
#[inline]
pub fn init(global: &Value) {
pub fn init(global: &Value) -> (&str, Value) {
let _timer = BoaProfiler::global().start_event("symbol", "init");
let symbol = Self::create(global);
global
.as_object_mut()
.unwrap()
.insert_field("Symbol", symbol);

("Symbol", Self::create(global))
}
}