From 84a8a4df0421fc1c1d16605706b7be936cfef4b0 Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Mon, 7 Nov 2022 17:39:48 -0800 Subject: [PATCH] refactor: simplify deno_core's grab_global and ensure_objs (#16564) - refactor: remove JsRuntime::ensure_objs - refactor: Replace JsRuntime::grab_global with JsRuntime::eval --- core/bindings.rs | 17 ++++++++++---- core/runtime.rs | 56 +++++++++-------------------------------------- runtime/worker.rs | 2 +- 3 files changed, 24 insertions(+), 51 deletions(-) diff --git a/core/bindings.rs b/core/bindings.rs index d7df613c5a..82cce71025 100644 --- a/core/bindings.rs +++ b/core/bindings.rs @@ -110,7 +110,7 @@ pub fn initialize_context<'s>( // extensions may provide ops that aren't part of the snapshot. if snapshot_options.loaded() { // Grab the Deno.core.ops object & init it - let ops_obj = JsRuntime::grab_global::(scope, "Deno.core.ops") + let ops_obj = JsRuntime::eval::(scope, "Deno.core.ops") .expect("Deno.core.ops to exist"); initialize_ops(scope, ops_obj, op_ctxs, snapshot_options); if snapshot_options != SnapshotOptions::CreateFromExisting { @@ -120,13 +120,22 @@ pub fn initialize_context<'s>( } // global.Deno = { core: { } }; - let core_val = JsRuntime::ensure_objs(scope, global, "Deno.core").unwrap(); + let deno_obj = v8::Object::new(scope); + let deno_str = v8::String::new(scope, "Deno").unwrap(); + global.set(scope, deno_str.into(), deno_obj.into()); + + let core_obj = v8::Object::new(scope); + let core_str = v8::String::new(scope, "core").unwrap(); + deno_obj.set(scope, core_str.into(), core_obj.into()); // Bind functions to Deno.core.* - set_func(scope, core_val, "callConsole", call_console); + set_func(scope, core_obj, "callConsole", call_console); // Bind functions to Deno.core.ops.* - let ops_obj = JsRuntime::ensure_objs(scope, global, "Deno.core.ops").unwrap(); + let ops_obj = v8::Object::new(scope); + let ops_str = v8::String::new(scope, "ops").unwrap(); + core_obj.set(scope, ops_str.into(), ops_obj.into()); + if !snapshot_options.will_snapshot() { initialize_async_ops_info(scope, ops_obj, op_ctxs); } diff --git a/core/runtime.rs b/core/runtime.rs index f27b3b337d..b5e2141fb3 100644 --- a/core/runtime.rs +++ b/core/runtime.rs @@ -745,64 +745,28 @@ impl JsRuntime { Ok(()) } - /// Grab a Global handle to a v8 value returned by the expression - pub(crate) fn grab<'s, T>( + pub fn eval<'s, T>( scope: &mut v8::HandleScope<'s>, - root: v8::Local<'s, v8::Value>, - path: &str, + code: &str, ) -> Option> where v8::Local<'s, T>: TryFrom, Error = v8::DataError>, { - path - .split('.') - .fold(Some(root), |p, k| { - let p = v8::Local::::try_from(p?).ok()?; - let k = v8::String::new(scope, k)?; - p.get(scope, k.into()) - })? - .try_into() - .ok() - } - - pub fn grab_global<'s, T>( - scope: &mut v8::HandleScope<'s>, - path: &str, - ) -> Option> - where - v8::Local<'s, T>: TryFrom, Error = v8::DataError>, - { - let context = scope.get_current_context(); - let global = context.global(scope); - Self::grab(scope, global.into(), path) - } - - pub(crate) fn ensure_objs<'s>( - scope: &mut v8::HandleScope<'s>, - root: v8::Local<'s, v8::Object>, - path: &str, - ) -> Option> { - path.split('.').fold(Some(root), |p, k| { - let k = v8::String::new(scope, k)?.into(); - match p?.get(scope, k) { - Some(v) if !v.is_null_or_undefined() => v.try_into().ok(), - _ => { - let o = v8::Object::new(scope); - p?.set(scope, k, o.into()); - Some(o) - } - } - }) + let scope = &mut v8::EscapableHandleScope::new(scope); + let source = v8::String::new(scope, code).unwrap(); + let script = v8::Script::compile(scope, source, None).unwrap(); + let v = script.run(scope)?; + scope.escape(v).try_into().ok() } /// Grabs a reference to core.js' opresolve & syncOpsCache() fn init_cbs(&mut self) { let scope = &mut self.handle_scope(); let recv_cb = - Self::grab_global::(scope, "Deno.core.opresolve").unwrap(); + Self::eval::(scope, "Deno.core.opresolve").unwrap(); let recv_cb = v8::Global::new(scope, recv_cb); let build_custom_error_cb = - Self::grab_global::(scope, "Deno.core.buildCustomError") + Self::eval::(scope, "Deno.core.buildCustomError") .expect("Deno.core.buildCustomError is undefined in the realm"); let build_custom_error_cb = v8::Global::new(scope, build_custom_error_cb); // Put global handles in state @@ -854,7 +818,7 @@ impl JsRuntime { // TODO(@AaronO): make ops stable across snapshots { let scope = &mut self.handle_scope(); - let o = Self::grab_global::(scope, "Deno.core.ops").unwrap(); + let o = Self::eval::(scope, "Deno.core.ops").unwrap(); let names = o.get_own_property_names(scope, Default::default()).unwrap(); for i in 0..names.length() { let key = names.get_index(scope, i).unwrap(); diff --git a/runtime/worker.rs b/runtime/worker.rs index 98fec19af9..de15c9f6f0 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -101,7 +101,7 @@ fn grab_cb( scope: &mut v8::HandleScope, path: &str, ) -> v8::Global { - let cb = JsRuntime::grab_global::(scope, path) + let cb = JsRuntime::eval::(scope, path) .unwrap_or_else(|| panic!("{} must be defined", path)); v8::Global::new(scope, cb) }