diff options
Diffstat (limited to 'ext/node/global.rs')
-rw-r--r-- | ext/node/global.rs | 95 |
1 files changed, 25 insertions, 70 deletions
diff --git a/ext/node/global.rs b/ext/node/global.rs index 618e68494..2434a64fd 100644 --- a/ext/node/global.rs +++ b/ext/node/global.rs @@ -1,13 +1,9 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -use std::mem::MaybeUninit; - use deno_core::v8; use deno_core::v8::GetPropertyNamesArgs; use deno_core::v8::MapFnTo; -use crate::NodeResolverRc; - // NOTE(bartlomieju): somehow calling `.map_fn_to()` multiple times on a function // returns two different pointers. That shouldn't be the case as `.map_fn_to()` // creates a thin wrapper that is a pure function. @piscisaureus suggests it @@ -17,8 +13,8 @@ use crate::NodeResolverRc; thread_local! { pub static GETTER_MAP_FN: v8::NamedPropertyGetterCallback<'static> = getter.map_fn_to(); pub static SETTER_MAP_FN: v8::NamedPropertySetterCallback<'static> = setter.map_fn_to(); - pub static QUERY_MAP_FN: v8::NamedPropertyGetterCallback<'static> = query.map_fn_to(); - pub static DELETER_MAP_FN: v8::NamedPropertyGetterCallback<'static> = deleter.map_fn_to(); + pub static QUERY_MAP_FN: v8::NamedPropertyQueryCallback<'static> = query.map_fn_to(); + pub static DELETER_MAP_FN: v8::NamedPropertyDeleterCallback<'static> = deleter.map_fn_to(); pub static ENUMERATOR_MAP_FN: v8::NamedPropertyEnumeratorCallback<'static> = enumerator.map_fn_to(); pub static DEFINER_MAP_FN: v8::NamedPropertyDefinerCallback<'static> = definer.map_fn_to(); pub static DESCRIPTOR_MAP_FN: v8::NamedPropertyGetterCallback<'static> = descriptor.map_fn_to(); @@ -93,8 +89,6 @@ enum Mode { } struct GlobalsStorage { - reflect_get: v8::Global<v8::Function>, - reflect_set: v8::Global<v8::Function>, deno_globals: v8::Global<v8::Object>, node_globals: v8::Global<v8::Object>, } @@ -154,27 +148,6 @@ pub fn global_object_middleware<'s>( .unwrap(); assert_ne!(global, object_prototype); - // Get the Reflect object - let reflect_key = - v8::String::new_external_onebyte_static(scope, b"Reflect").unwrap(); - let reflect = global - .get(scope, reflect_key.into()) - .unwrap() - .to_object(scope) - .unwrap(); - - // Get the Reflect.get function. - let get_key = v8::String::new_external_onebyte_static(scope, b"get").unwrap(); - let reflect_get = reflect.get(scope, get_key.into()).unwrap(); - let reflect_get_fn: v8::Local<v8::Function> = reflect_get.try_into().unwrap(); - let reflect_get = v8::Global::new(scope, reflect_get_fn); - - // Get the Reflect.set function. - let set_key = v8::String::new_external_onebyte_static(scope, b"set").unwrap(); - let reflect_set = reflect.get(scope, set_key.into()).unwrap(); - let reflect_set_fn: v8::Local<v8::Function> = reflect_set.try_into().unwrap(); - let reflect_set = v8::Global::new(scope, reflect_set_fn); - // globalThis.__bootstrap.ext_node_denoGlobals and // globalThis.__bootstrap.ext_node_nodeGlobals are the objects that contain // the Deno and Node specific globals respectively. If they do not yet exist @@ -231,8 +204,6 @@ pub fn global_object_middleware<'s>( // Create the storage struct and store it in a context slot. let storage = GlobalsStorage { - reflect_get, - reflect_set, deno_globals, node_globals, }; @@ -264,19 +235,19 @@ fn is_managed_key( } fn current_mode(scope: &mut v8::HandleScope) -> Mode { - let Some(v8_string) = - v8::StackTrace::current_script_name_or_source_url(scope) + let Some(host_defined_options) = scope.get_current_host_defined_options() else { return Mode::Deno; }; - let op_state = deno_core::JsRuntime::op_state_from(scope); - let op_state = op_state.borrow(); - let Some(node_resolver) = op_state.try_borrow::<NodeResolverRc>() else { - return Mode::Deno; + // SAFETY: host defined options must always be a PrimitiveArray in current V8. + let host_defined_options = unsafe { + v8::Local::<v8::PrimitiveArray>::cast_unchecked(host_defined_options) }; - let mut buffer = [MaybeUninit::uninit(); 2048]; - let str = v8_string.to_rust_cow_lossy(scope, &mut buffer); - if str.starts_with("node:") || node_resolver.in_npm_package_with_cache(str) { + if host_defined_options.length() < 1 { + return Mode::Deno; + } + let is_node = host_defined_options.get(scope, 0).is_true(); + if is_node { Mode::Node } else { Mode::Deno @@ -297,25 +268,17 @@ pub fn getter<'s>( let mode = current_mode(scope); let context = scope.get_current_context(); - let (reflect_get, inner) = { + let inner = { let storage = context.get_slot::<GlobalsStorage>(scope).unwrap(); - let reflect_get = storage.reflect_get.clone(); - let inner = storage.inner_for_mode(mode); - (reflect_get, inner) + storage.inner_for_mode(mode) }; - let reflect_get = v8::Local::new(scope, reflect_get); let inner = v8::Local::new(scope, inner); if !inner.has_own_property(scope, key).unwrap_or(false) { return v8::Intercepted::No; } - let undefined = v8::undefined(scope); - let Some(value) = reflect_get.call( - scope, - undefined.into(), - &[inner.into(), key.into(), this.into()], - ) else { + let Some(value) = inner.get_with_receiver(scope, key.into(), this) else { return v8::Intercepted::No; }; @@ -328,7 +291,7 @@ pub fn setter<'s>( key: v8::Local<'s, v8::Name>, value: v8::Local<'s, v8::Value>, args: v8::PropertyCallbackArguments<'s>, - mut rv: v8::ReturnValue, + mut rv: v8::ReturnValue<()>, ) -> v8::Intercepted { if !is_managed_key(scope, key) { return v8::Intercepted::No; @@ -338,26 +301,18 @@ pub fn setter<'s>( let mode = current_mode(scope); let context = scope.get_current_context(); - let (reflect_set, inner) = { + let inner = { let storage = context.get_slot::<GlobalsStorage>(scope).unwrap(); - let reflect_set = storage.reflect_set.clone(); - let inner = storage.inner_for_mode(mode); - (reflect_set, inner) + storage.inner_for_mode(mode) }; - let reflect_set = v8::Local::new(scope, reflect_set); let inner = v8::Local::new(scope, inner); - let undefined = v8::undefined(scope); - - let Some(success) = reflect_set.call( - scope, - undefined.into(), - &[inner.into(), key.into(), value, this.into()], - ) else { + let Some(success) = inner.set_with_receiver(scope, key.into(), value, this) + else { return v8::Intercepted::No; }; - rv.set(success); + rv.set_bool(success); v8::Intercepted::Yes } @@ -365,7 +320,7 @@ pub fn query<'s>( scope: &mut v8::HandleScope<'s>, key: v8::Local<'s, v8::Name>, _args: v8::PropertyCallbackArguments<'s>, - mut rv: v8::ReturnValue, + mut rv: v8::ReturnValue<v8::Integer>, ) -> v8::Intercepted { if !is_managed_key(scope, key) { return v8::Intercepted::No; @@ -396,7 +351,7 @@ pub fn deleter<'s>( scope: &mut v8::HandleScope<'s>, key: v8::Local<'s, v8::Name>, args: v8::PropertyCallbackArguments<'s>, - mut rv: v8::ReturnValue, + mut rv: v8::ReturnValue<v8::Boolean>, ) -> v8::Intercepted { if !is_managed_key(scope, key) { return v8::Intercepted::No; @@ -429,7 +384,7 @@ pub fn deleter<'s>( pub fn enumerator<'s>( scope: &mut v8::HandleScope<'s>, _args: v8::PropertyCallbackArguments<'s>, - mut rv: v8::ReturnValue, + mut rv: v8::ReturnValue<v8::Array>, ) { let mode = current_mode(scope); @@ -451,7 +406,7 @@ pub fn enumerator<'s>( return; }; - rv.set(array.into()); + rv.set(array); } pub fn definer<'s>( @@ -459,7 +414,7 @@ pub fn definer<'s>( key: v8::Local<'s, v8::Name>, descriptor: &v8::PropertyDescriptor, args: v8::PropertyCallbackArguments<'s>, - _rv: v8::ReturnValue, + _rv: v8::ReturnValue<()>, ) -> v8::Intercepted { if !is_managed_key(scope, key) { return v8::Intercepted::No; |