summaryrefslogtreecommitdiff
path: root/core/runtime.rs
diff options
context:
space:
mode:
Diffstat (limited to 'core/runtime.rs')
-rw-r--r--core/runtime.rs82
1 files changed, 55 insertions, 27 deletions
diff --git a/core/runtime.rs b/core/runtime.rs
index 8ec3dfb08..6ca586997 100644
--- a/core/runtime.rs
+++ b/core/runtime.rs
@@ -507,36 +507,64 @@ impl JsRuntime {
Ok(())
}
- /// Grab a Global handle to a function returned by the given expression
- fn grab_fn(
- scope: &mut v8::HandleScope,
- code: &str,
- ) -> v8::Global<v8::Function> {
- let code = v8::String::new(scope, code).unwrap();
- let script = v8::Script::compile(scope, code, None).unwrap();
- let v8_value = script.run(scope).unwrap();
- let cb = v8::Local::<v8::Function>::try_from(v8_value).unwrap();
- v8::Global::new(scope, cb)
- }
-
- fn grab_obj<'s>(
+ /// Grab a Global handle to a v8 value returned by the expression
+ pub(crate) fn grab<'s, T>(
scope: &mut v8::HandleScope<'s>,
- code: &str,
- ) -> v8::Local<'s, v8::Object> {
- let scope = &mut v8::EscapableHandleScope::new(scope);
- let code = v8::String::new(scope, code).unwrap();
- let script = v8::Script::compile(scope, code, None).unwrap();
- let v8_value = script.run(scope).unwrap();
- let obj = v8::Local::<v8::Object>::try_from(v8_value).unwrap();
- scope.escape(obj)
+ root: v8::Local<'s, v8::Value>,
+ path: &str,
+ ) -> Option<v8::Local<'s, T>>
+ where
+ v8::Local<'s, T>: TryFrom<v8::Local<'s, v8::Value>, Error = v8::DataError>,
+ {
+ path
+ .split('.')
+ .fold(Some(root), |p, k| {
+ let p = v8::Local::<v8::Object>::try_from(p?).ok()?;
+ let k = v8::String::new(scope, k)?;
+ p.get(scope, k.into())
+ })?
+ .try_into()
+ .ok()
+ }
+
+ pub(crate) fn grab_global<'s, T>(
+ scope: &mut v8::HandleScope<'s>,
+ path: &str,
+ ) -> Option<v8::Local<'s, T>>
+ where
+ v8::Local<'s, T>: TryFrom<v8::Local<'s, v8::Value>, 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<v8::Local<'s, v8::Object>> {
+ 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)
+ }
+ }
+ })
}
/// Grabs a reference to core.js' opresolve & syncOpsCache()
fn init_cbs(&mut self) {
- let mut scope = self.handle_scope();
- let recv_cb = Self::grab_fn(&mut scope, "Deno.core.opresolve");
+ let scope = &mut self.handle_scope();
+ let recv_cb =
+ Self::grab_global::<v8::Function>(scope, "Deno.core.opresolve").unwrap();
+ let recv_cb = v8::Global::new(scope, recv_cb);
// Put global handles in state
- let state_rc = JsRuntime::state(&scope);
+ let state_rc = JsRuntime::state(scope);
let mut state = state_rc.borrow_mut();
state.js_recv_cb.replace(recv_cb);
}
@@ -612,11 +640,11 @@ impl JsRuntime {
// TODO(@AaronO): make ops stable across snapshots
{
let scope = &mut self.handle_scope();
- let obj = Self::grab_obj(scope, "Deno.core.ops");
- let names = obj.get_own_property_names(scope).unwrap();
+ let o = Self::grab_global::<v8::Object>(scope, "Deno.core.ops").unwrap();
+ let names = o.get_own_property_names(scope).unwrap();
for i in 0..names.length() {
let key = names.get_index(scope, i).unwrap();
- obj.delete(scope, key);
+ o.delete(scope, key);
}
}