Skip to content

Commit

Permalink
Implement [[HostDefined]] field on Realms
Browse files Browse the repository at this point in the history
  • Loading branch information
HalidOdat committed May 20, 2023
1 parent fdf9444 commit 9f1907b
Show file tree
Hide file tree
Showing 25 changed files with 339 additions and 110 deletions.
22 changes: 12 additions & 10 deletions boa_cli/src/debug/limits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,24 @@ fn set_recursion(_: &JsValue, args: &[JsValue], context: &mut Context<'_>) -> Js
}

pub(super) fn create_object(context: &mut Context<'_>) -> JsObject {
let get_loop = FunctionObjectBuilder::new(context, NativeFunction::from_fn_ptr(get_loop))
.name("get loop")
.length(0)
.build();
let set_loop = FunctionObjectBuilder::new(context, NativeFunction::from_fn_ptr(set_loop))
.name("set loop")
.length(1)
.build();
let get_loop =
FunctionObjectBuilder::new(context.realm(), NativeFunction::from_fn_ptr(get_loop))
.name("get loop")
.length(0)
.build();
let set_loop =
FunctionObjectBuilder::new(context.realm(), NativeFunction::from_fn_ptr(set_loop))
.name("set loop")
.length(1)
.build();

let get_recursion =
FunctionObjectBuilder::new(context, NativeFunction::from_fn_ptr(get_recursion))
FunctionObjectBuilder::new(context.realm(), NativeFunction::from_fn_ptr(get_recursion))
.name("get recursion")
.length(0)
.build();
let set_recursion =
FunctionObjectBuilder::new(context, NativeFunction::from_fn_ptr(set_recursion))
FunctionObjectBuilder::new(context.realm(), NativeFunction::from_fn_ptr(set_recursion))
.name("set recursion")
.length(1)
.build();
Expand Down
28 changes: 16 additions & 12 deletions boa_cli/src/debug/optimizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,24 +44,28 @@ fn set_statistics(_: &JsValue, args: &[JsValue], context: &mut Context<'_>) -> J
}

pub(super) fn create_object(context: &mut Context<'_>) -> JsObject {
let get_constant_folding =
FunctionObjectBuilder::new(context, NativeFunction::from_fn_ptr(get_constant_folding))
.name("get constantFolding")
.length(0)
.build();
let set_constant_folding =
FunctionObjectBuilder::new(context, NativeFunction::from_fn_ptr(set_constant_folding))
.name("set constantFolding")
.length(1)
.build();
let get_constant_folding = FunctionObjectBuilder::new(
context.realm(),
NativeFunction::from_fn_ptr(get_constant_folding),
)
.name("get constantFolding")
.length(0)
.build();
let set_constant_folding = FunctionObjectBuilder::new(
context.realm(),
NativeFunction::from_fn_ptr(set_constant_folding),
)
.name("set constantFolding")
.length(1)
.build();

let get_statistics =
FunctionObjectBuilder::new(context, NativeFunction::from_fn_ptr(get_statistics))
FunctionObjectBuilder::new(context.realm(), NativeFunction::from_fn_ptr(get_statistics))
.name("get statistics")
.length(0)
.build();
let set_statistics =
FunctionObjectBuilder::new(context, NativeFunction::from_fn_ptr(set_statistics))
FunctionObjectBuilder::new(context.realm(), NativeFunction::from_fn_ptr(set_statistics))
.name("set statistics")
.length(1)
.build();
Expand Down
4 changes: 2 additions & 2 deletions boa_engine/src/builtins/async_generator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ impl AsyncGenerator {
// 7. Let fulfilledClosure be a new Abstract Closure with parameters (value) that captures generator and performs the following steps when called:
// 8. Let onFulfilled be CreateBuiltinFunction(fulfilledClosure, 1, "", « »).
let on_fulfilled = FunctionObjectBuilder::new(
context,
context.realm(),
NativeFunction::from_copy_closure_with_captures(
|_this, args, generator, context| {
let next = {
Expand Down Expand Up @@ -608,7 +608,7 @@ impl AsyncGenerator {
// 9. Let rejectedClosure be a new Abstract Closure with parameters (reason) that captures generator and performs the following steps when called:
// 10. Let onRejected be CreateBuiltinFunction(rejectedClosure, 1, "", « »).
let on_rejected = FunctionObjectBuilder::new(
context,
context.realm(),
NativeFunction::from_copy_closure_with_captures(
|_this, args, generator, context| {
let mut generator_borrow_mut = generator.borrow_mut();
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/builtins/function/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ fn closure_capture_clone() {
.unwrap();

let func = FunctionObjectBuilder::new(
ctx,
ctx.realm(),
NativeFunction::from_copy_closure_with_captures(
|_, _, captures, context| {
let (string, object) = &captures;
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/builtins/intl/collator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,7 @@ impl Collator {
f
} else {
let bound_compare = FunctionObjectBuilder::new(
context,
context.realm(),
// 10.3.3.1. Collator Compare Functions
// https://tc39.es/ecma402/#sec-collator-compare-functions
NativeFunction::from_copy_closure_with_captures(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ impl AsyncFromSyncIterator {
// that captures done and performs the following steps when called:
// 9. Let onFulfilled be CreateBuiltinFunction(unwrap, 1, "", « »).
let on_fulfilled = FunctionObjectBuilder::new(
context,
context.realm(),
NativeFunction::from_copy_closure(move |_this, args, context| {
// a. Return CreateIterResultObject(value, done).
Ok(create_iter_result_object(
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/builtins/object/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1283,7 +1283,7 @@ impl Object {
// 4. Let closure be a new Abstract Closure with parameters (key, value) that captures
// obj and performs the following steps when called:
let closure = FunctionObjectBuilder::new(
context,
context.realm(),
NativeFunction::from_copy_closure_with_captures(
|_, args, obj, context| {
let key = args.get_or_undefined(0);
Expand Down
22 changes: 11 additions & 11 deletions boa_engine/src/builtins/promise/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ impl PromiseCapability {
// 4. Let executorClosure be a new Abstract Closure with parameters (resolve, reject) that captures promiseCapability and performs the following steps when called:
// 5. Let executor be CreateBuiltinFunction(executorClosure, 2, "", « »).
let executor = FunctionObjectBuilder::new(
context,
context.realm(),
NativeFunction::from_copy_closure_with_captures(
|_this, args: &[JsValue], captures, _| {
let mut promise_capability = captures.borrow_mut();
Expand Down Expand Up @@ -612,7 +612,7 @@ impl Promise {
// p. Set onFulfilled.[[Capability]] to resultCapability.
// q. Set onFulfilled.[[RemainingElements]] to remainingElementsCount.
let on_fulfilled = FunctionObjectBuilder::new(
context,
context.realm(),
NativeFunction::from_copy_closure_with_captures(
|_, args, captures, context| {
// https://tc39.es/ecma262/#sec-promise.all-resolve-element-functions
Expand Down Expand Up @@ -856,7 +856,7 @@ impl Promise {
// q. Set onFulfilled.[[Capability]] to resultCapability.
// r. Set onFulfilled.[[RemainingElements]] to remainingElementsCount.
let on_fulfilled = FunctionObjectBuilder::new(
context,
context.realm(),
NativeFunction::from_copy_closure_with_captures(
|_, args, captures, context| {
// https://tc39.es/ecma262/#sec-promise.allsettled-resolve-element-functions
Expand Down Expand Up @@ -942,7 +942,7 @@ impl Promise {
// y. Set onRejected.[[Capability]] to resultCapability.
// z. Set onRejected.[[RemainingElements]] to remainingElementsCount.
let on_rejected = FunctionObjectBuilder::new(
context,
context.realm(),
NativeFunction::from_copy_closure_with_captures(
|_, args, captures, context| {
// https://tc39.es/ecma262/#sec-promise.allsettled-reject-element-functions
Expand Down Expand Up @@ -1203,7 +1203,7 @@ impl Promise {
// p. Set onRejected.[[Capability]] to resultCapability.
// q. Set onRejected.[[RemainingElements]] to remainingElementsCount.
let on_rejected = FunctionObjectBuilder::new(
context,
context.realm(),
NativeFunction::from_copy_closure_with_captures(
|_, args, captures, context| {
// https://tc39.es/ecma262/#sec-promise.any-reject-element-functions
Expand Down Expand Up @@ -1631,7 +1631,7 @@ impl Promise {

// a. Let thenFinallyClosure be a new Abstract Closure with parameters (value) that captures onFinally and C and performs the following steps when called:
let then_finally_closure = FunctionObjectBuilder::new(
context,
context.realm(),
NativeFunction::from_copy_closure_with_captures(
|_this, args, captures, context| {
/// Capture object for the abstract `returnValue` closure.
Expand All @@ -1652,7 +1652,7 @@ impl Promise {

// iii. Let returnValue be a new Abstract Closure with no parameters that captures value and performs the following steps when called:
let return_value = FunctionObjectBuilder::new(
context,
context.realm(),
NativeFunction::from_copy_closure_with_captures(
|_this, _args, captures, _context| {
// 1. Return value.
Expand Down Expand Up @@ -1682,7 +1682,7 @@ impl Promise {

// c. Let catchFinallyClosure be a new Abstract Closure with parameters (reason) that captures onFinally and C and performs the following steps when called:
let catch_finally_closure = FunctionObjectBuilder::new(
context,
context.realm(),
NativeFunction::from_copy_closure_with_captures(
|_this, args, captures, context| {
/// Capture object for the abstract `throwReason` closure.
Expand All @@ -1703,7 +1703,7 @@ impl Promise {

// iii. Let throwReason be a new Abstract Closure with no parameters that captures reason and performs the following steps when called:
let throw_reason = FunctionObjectBuilder::new(
context,
context.realm(),
NativeFunction::from_copy_closure_with_captures(
|_this, _args, captures, _context| {
// 1. Return ThrowCompletion(reason).
Expand Down Expand Up @@ -2096,7 +2096,7 @@ impl Promise {
// 3. Let lengthResolve be the number of non-optional parameters of the function definition in Promise Resolve Functions.
// 4. Let resolve be CreateBuiltinFunction(stepsResolve, lengthResolve, "", « [[Promise]], [[AlreadyResolved]] »).
let resolve = FunctionObjectBuilder::new(
context,
context.realm(),
NativeFunction::from_copy_closure_with_captures(
|_this, args, captures, context| {
// https://tc39.es/ecma262/#sec-promise-resolve-functions
Expand Down Expand Up @@ -2202,7 +2202,7 @@ impl Promise {
// 8. Let lengthReject be the number of non-optional parameters of the function definition in Promise Reject Functions.
// 9. Let reject be CreateBuiltinFunction(stepsReject, lengthReject, "", « [[Promise]], [[AlreadyResolved]] »).
let reject = FunctionObjectBuilder::new(
context,
context.realm(),
NativeFunction::from_copy_closure_with_captures(
|_this, args, captures, context| {
// https://tc39.es/ecma262/#sec-promise-reject-functions
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/builtins/proxy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ impl Proxy {
// 3. Let revoker be ! CreateBuiltinFunction(revokerClosure, 0, "", « [[RevocableProxy]] »).
// 4. Set revoker.[[RevocableProxy]] to p.
FunctionObjectBuilder::new(
context,
context.realm(),
NativeFunction::from_copy_closure_with_captures(
|_, _, revocable_proxy, _| {
// a. Let F be the active function object.
Expand Down
18 changes: 17 additions & 1 deletion boa_engine/src/context/hooks.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
use crate::{
builtins::promise::OperationType,
job::JobCallback,
object::{JsFunction, JsObject},
object::{JsFunction, JsObject, NativeObject},
realm::Realm,
Context, JsResult, JsValue,
};
use boa_macros::{Finalize, Trace};
use chrono::{DateTime, FixedOffset, Local, LocalResult, NaiveDateTime, TimeZone, Utc};

use super::intrinsics::Intrinsics;

/// Default `[[HostDefined]]` type.
///
/// This is also used to indicate that the `host-defined` has **not** been set.
///
/// It's a zero-size type so `Box<DefaultHostDefined>` doesn't allocate!
#[derive(Default, Debug, Trace, Finalize)]
pub struct DefaultHostDefined {}

/// [`Host Hooks`] customizable by the host code or engine.
///
/// Every hook contains on its `Requirements` section the spec requirements
Expand Down Expand Up @@ -172,6 +181,13 @@ pub trait HostHooks {
None
}

/// Creates the new [`Realm`]'s `[[HostDefined]]` field.
///
/// By default it returns a [`DefaultHostDefined`] type.
fn create_host_defined_realm_field(&self, _intrinsics: &Intrinsics) -> Box<dyn NativeObject> {
Box::<DefaultHostDefined>::default()
}

/// Gets the current UTC time of the host.
///
/// Defaults to using [`Utc::now`] on all targets, which can cause panics if your platform
Expand Down
4 changes: 2 additions & 2 deletions boa_engine/src/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ impl<'host> Context<'host> {
length: usize,
body: NativeFunction,
) -> JsResult<()> {
let function = FunctionObjectBuilder::new(self, body)
let function = FunctionObjectBuilder::new(&self.realm, body)
.name(name)
.length(length)
.constructor(true)
Expand Down Expand Up @@ -348,7 +348,7 @@ impl<'host> Context<'host> {
length: usize,
body: NativeFunction,
) -> JsResult<()> {
let function = FunctionObjectBuilder::new(self, body)
let function = FunctionObjectBuilder::new(&self.realm, body)
.name(name)
.length(length)
.constructor(false)
Expand Down
20 changes: 12 additions & 8 deletions boa_engine/src/job.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
//! [Job]: https://tc39.es/ecma262/#sec-jobs
//! [JobCallback]: https://tc39.es/ecma262/#sec-jobcallback-records
use std::{any::Any, cell::RefCell, collections::VecDeque, fmt::Debug, future::Future, pin::Pin};
use std::{cell::RefCell, collections::VecDeque, fmt::Debug, future::Future, pin::Pin};

use crate::{
object::{JsFunction, NativeObject},
Expand Down Expand Up @@ -142,26 +142,30 @@ impl Debug for JobCallback {

impl JobCallback {
/// Creates a new `JobCallback`.
pub fn new<T: Any + Trace>(callback: JsFunction, host_defined: T) -> Self {
#[inline]
pub fn new<T: NativeObject>(callback: JsFunction, host_defined: T) -> Self {
Self {
callback,
host_defined: Box::new(host_defined),
}
}

/// Gets the inner callback of the job.
#[inline]
pub const fn callback(&self) -> &JsFunction {
&self.callback
}

/// Gets a reference to the host defined additional field as an `Any` trait object.
pub fn host_defined(&self) -> &dyn Any {
self.host_defined.as_any()
/// Gets a reference to the host defined additional field as an [`NativeObject`] trait object.
#[inline]
pub fn host_defined(&self) -> &dyn NativeObject {
&*self.host_defined
}

/// Gets a mutable reference to the host defined additional field as an `Any` trait object.
pub fn host_defined_mut(&mut self) -> &mut dyn Any {
self.host_defined.as_mut_any()
/// Gets a mutable reference to the host defined additional field as an [`NativeObject`] trait object.
#[inline]
pub fn host_defined_mut(&mut self) -> &mut dyn NativeObject {
&mut *self.host_defined
}
}

Expand Down
4 changes: 2 additions & 2 deletions boa_engine/src/module/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,7 @@ impl Module {
.then(
Some(
FunctionObjectBuilder::new(
context,
context.realm(),
NativeFunction::from_copy_closure_with_captures(
|_, _, module, context| {
module.link(context)?;
Expand All @@ -601,7 +601,7 @@ impl Module {
.then(
Some(
FunctionObjectBuilder::new(
context,
context.realm(),
NativeFunction::from_copy_closure_with_captures(
|_, _, module, context| Ok(module.evaluate(context).into()),
self.clone(),
Expand Down
4 changes: 2 additions & 2 deletions boa_engine/src/module/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1256,7 +1256,7 @@ impl SourceTextModule {
// 4. Let fulfilledClosure be a new Abstract Closure with no parameters that captures module and performs the following steps when called:
// 5. Let onFulfilled be CreateBuiltinFunction(fulfilledClosure, 0, "", « »).
let on_fulfilled = FunctionObjectBuilder::new(
context,
context.realm(),
NativeFunction::from_copy_closure_with_captures(
|_, _, module, context| {
// a. Perform AsyncModuleExecutionFulfilled(module).
Expand All @@ -1272,7 +1272,7 @@ impl SourceTextModule {
// 6. Let rejectedClosure be a new Abstract Closure with parameters (error) that captures module and performs the following steps when called:
// 7. Let onRejected be CreateBuiltinFunction(rejectedClosure, 0, "", « »).
let on_rejected = FunctionObjectBuilder::new(
context,
context.realm(),
NativeFunction::from_copy_closure_with_captures(
|_, args, module, context| {
let error = JsError::from_opaque(args.get_or_undefined(0).clone());
Expand Down
Loading

0 comments on commit 9f1907b

Please sign in to comment.