Skip to content

Commit

Permalink
Add a ContextData struct to inject host defined types from the context (
Browse files Browse the repository at this point in the history
#3802)

* Add more utility traits and funtions to boa_interop

* cargo clippy

* Readd the safe version for Fn which also implements Copy

* Use a new trait for converting a Rust type to a JsResult<JsValue>

* cargo clippy

* Add a test for returning result and Fn()

* Seal both IntoJsFunction and IntoJsFunctionUnsafe

* Try Borrowing and return a nice error instead of panicking

* Address comments

* Rename into_js_function to into_js_function_copied

* Move TryIntoJsResult to boa_engine

* Move JsRest to be at the end only of arguments and add JsAll

* use from_copy_closure and remove unsafe

* Add a HostDefined struct to grab host defined in the argument list

* cargo fmt and clippy

* Explain why we need Clone

* Remove the vector from JsRest<> and use a reference

* Add HostDefined to context as Data, and rename the injector in boa_interop

* Use TypeError instead if the type was not found in context

* Update core/interop/src/lib.rs

Co-authored-by: José Julián Espina <[email protected]>

* cargo fmt

* cargo fmt

---------

Co-authored-by: José Julián Espina <[email protected]>
  • Loading branch information
hansl and jedel1043 authored Apr 18, 2024
1 parent 261e264 commit f955248
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 61 deletions.
31 changes: 30 additions & 1 deletion core/engine/src/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use crate::{
realm::Realm,
script::Script,
vm::{ActiveRunnable, CallFrame, Vm},
JsNativeError, JsResult, JsString, JsValue, Source,
HostDefined, JsNativeError, JsResult, JsString, JsValue, NativeObject, Source,
};

use self::intrinsics::StandardConstructor;
Expand Down Expand Up @@ -115,6 +115,8 @@ pub struct Context {

/// Unique identifier for each parser instance used during the context lifetime.
parser_identifier: u32,

data: HostDefined,
}

impl std::fmt::Debug for Context {
Expand Down Expand Up @@ -585,6 +587,32 @@ impl Context {
pub fn can_block(&self) -> bool {
self.can_block
}

/// Insert a type into the context-specific [`HostDefined`] field.
#[inline]
pub fn insert_data<T: NativeObject>(&mut self, value: T) -> Option<Box<T>> {
self.data.insert(value)
}

/// Check if the context-specific [`HostDefined`] has type T.
#[inline]
#[must_use]
pub fn has_data<T: NativeObject>(&self) -> bool {
self.data.has::<T>()
}

/// Remove type T from the context-specific [`HostDefined`], if it exists.
#[inline]
pub fn remove_data<T: NativeObject>(&mut self) -> Option<Box<T>> {
self.data.remove::<T>()
}

/// Get type T from the context-specific [`HostDefined`], if it exists.
#[inline]
#[must_use]
pub fn get_data<T: NativeObject>(&self) -> Option<&T> {
self.data.get::<T>()
}
}

// ==== Private API ====
Expand Down Expand Up @@ -1070,6 +1098,7 @@ impl ContextBuilder {
root_shape,
parser_identifier: 0,
can_block: self.can_block,
data: HostDefined::default(),
};

builtins::set_default_global_bindings(&mut context)?;
Expand Down
48 changes: 24 additions & 24 deletions core/interop/src/into_js_function_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,35 +16,35 @@ macro_rules! impl_into_js_function {
($($id: ident: $t: ident),*) => {
impl<$($t,)* R, T> IntoJsFunctionSealed<($($t,)*), R> for T
where
$($t: TryFromJsArgument + 'static,)*
$($t: for<'a> TryFromJsArgument<'a> + 'static,)*
R: TryIntoJsResult,
T: FnMut($($t,)*) -> R + 'static
{}

impl<$($t,)* R, T> IntoJsFunctionSealed<($($t,)* ContextArgToken,), R> for T
where
$($t: TryFromJsArgument + 'static,)*
$($t: for<'a> TryFromJsArgument<'a> + 'static,)*
R: TryIntoJsResult,
T: FnMut($($t,)* &mut Context) -> R + 'static
{}

impl<$($t,)* R, T> IntoJsFunctionSealed<($($t,)* JsRest,), R> for T
impl<$($t,)* R, T> IntoJsFunctionSealed<($($t,)* JsRest<'_>,), R> for T
where
$($t: TryFromJsArgument + 'static,)*
$($t: for<'a> TryFromJsArgument<'a> + 'static,)*
R: TryIntoJsResult,
T: FnMut($($t,)* JsRest) -> R + 'static
T: FnMut($($t,)* JsRest<'_>) -> R + 'static
{}

impl<$($t,)* R, T> IntoJsFunctionSealed<($($t,)* JsRest, ContextArgToken), R> for T
impl<$($t,)* R, T> IntoJsFunctionSealed<($($t,)* JsRest<'_>, ContextArgToken), R> for T
where
$($t: TryFromJsArgument + 'static,)*
$($t: for<'a> TryFromJsArgument<'a> + 'static,)*
R: TryIntoJsResult,
T: FnMut($($t,)* JsRest, &mut Context) -> R + 'static
T: FnMut($($t,)* JsRest<'_>, &mut Context) -> R + 'static
{}

impl<$($t,)* R, T> UnsafeIntoJsFunction<($($t,)*), R> for T
where
$($t: TryFromJsArgument + 'static,)*
$($t: for<'a> TryFromJsArgument<'a> + 'static,)*
R: TryIntoJsResult,
T: FnMut($($t,)*) -> R + 'static,
{
Expand All @@ -68,11 +68,11 @@ macro_rules! impl_into_js_function {
}
}

impl<$($t,)* R, T> UnsafeIntoJsFunction<($($t,)* JsRest,), R> for T
impl<$($t,)* R, T> UnsafeIntoJsFunction<($($t,)* JsRest<'_>,), R> for T
where
$($t: TryFromJsArgument + 'static,)*
$($t: for<'a> TryFromJsArgument<'a> + 'static,)*
R: TryIntoJsResult,
T: FnMut($($t,)* JsRest) -> R + 'static,
T: FnMut($($t,)* JsRest<'_>) -> R + 'static,
{
#[allow(unused_variables)]
unsafe fn into_js_function_unsafe(self, _context: &mut Context) -> NativeFunction {
Expand All @@ -96,7 +96,7 @@ macro_rules! impl_into_js_function {

impl<$($t,)* R, T> UnsafeIntoJsFunction<($($t,)* ContextArgToken,), R> for T
where
$($t: TryFromJsArgument + 'static,)*
$($t: for<'a> TryFromJsArgument<'a> + 'static,)*
R: TryIntoJsResult,
T: FnMut($($t,)* &mut Context) -> R + 'static,
{
Expand All @@ -116,11 +116,11 @@ macro_rules! impl_into_js_function {
}
}

impl<$($t,)* R, T> UnsafeIntoJsFunction<($($t,)* JsRest, ContextArgToken), R> for T
impl<$($t,)* R, T> UnsafeIntoJsFunction<($($t,)* JsRest<'_>, ContextArgToken), R> for T
where
$($t: TryFromJsArgument + 'static,)*
$($t: for<'a> TryFromJsArgument<'a> + 'static,)*
R: TryIntoJsResult,
T: FnMut($($t,)* JsRest, &mut Context) -> R + 'static,
T: FnMut($($t,)* JsRest<'_>, &mut Context) -> R + 'static,
{
#[allow(unused_variables)]
unsafe fn into_js_function_unsafe(self, _context: &mut Context) -> NativeFunction {
Expand All @@ -141,7 +141,7 @@ macro_rules! impl_into_js_function {
// Safe versions for `Fn(..) -> ...`.
impl<$($t,)* R, T> IntoJsFunctionCopied<($($t,)*), R> for T
where
$($t: TryFromJsArgument + 'static,)*
$($t: for<'a> TryFromJsArgument<'a> + 'static,)*
R: TryIntoJsResult,
T: Fn($($t,)*) -> R + 'static + Copy,
{
Expand All @@ -159,11 +159,11 @@ macro_rules! impl_into_js_function {
}
}

impl<$($t,)* R, T> IntoJsFunctionCopied<($($t,)* JsRest,), R> for T
impl<$($t,)* R, T> IntoJsFunctionCopied<($($t,)* JsRest<'_>,), R> for T
where
$($t: TryFromJsArgument + 'static,)*
$($t: for<'a> TryFromJsArgument<'a> + 'static,)*
R: TryIntoJsResult,
T: Fn($($t,)* JsRest) -> R + 'static + Copy,
T: Fn($($t,)* JsRest<'_>) -> R + 'static + Copy,
{
#[allow(unused_variables)]
fn into_js_function_copied(self, _context: &mut Context) -> NativeFunction {
Expand All @@ -181,7 +181,7 @@ macro_rules! impl_into_js_function {

impl<$($t,)* R, T> IntoJsFunctionCopied<($($t,)* ContextArgToken,), R> for T
where
$($t: TryFromJsArgument + 'static,)*
$($t: for<'a> TryFromJsArgument<'a> + 'static,)*
R: TryIntoJsResult,
T: Fn($($t,)* &mut Context) -> R + 'static + Copy,
{
Expand All @@ -199,11 +199,11 @@ macro_rules! impl_into_js_function {
}
}

impl<$($t,)* R, T> IntoJsFunctionCopied<($($t,)* JsRest, ContextArgToken), R> for T
impl<$($t,)* R, T> IntoJsFunctionCopied<($($t,)* JsRest<'_>, ContextArgToken), R> for T
where
$($t: TryFromJsArgument + 'static,)*
$($t: for<'a> TryFromJsArgument<'a> + 'static,)*
R: TryIntoJsResult,
T: Fn($($t,)* JsRest, &mut Context) -> R + 'static + Copy,
T: Fn($($t,)* JsRest<'_>, &mut Context) -> R + 'static + Copy,
{
#[allow(unused_variables)]
fn into_js_function_copied(self, _context: &mut Context) -> NativeFunction {
Expand Down
Loading

0 comments on commit f955248

Please sign in to comment.