diff options
author | Aaron O'Mullan <aaron.omullan@gmail.com> | 2022-03-15 22:50:17 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-15 22:50:17 +0100 |
commit | 07d8431f100e8df5f523adf542b47f8b91af3539 (patch) | |
tree | 97241da33c3f0e9f45617bdbd0a81d64c49b8e51 /core/runtime.rs | |
parent | 163e1d61920fbc6a0bdb18adc57b249b2d600472 (diff) |
fix(core): nuke Deno.core.ops pre-snapshot (#13970)
To avoid OOB & other ExternalReference snapshot serialization issues
Co-authored-by: Bert Belder <bertbelder@gmail.com>
Diffstat (limited to 'core/runtime.rs')
-rw-r--r-- | core/runtime.rs | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/core/runtime.rs b/core/runtime.rs index 019065526..c95ef6a20 100644 --- a/core/runtime.rs +++ b/core/runtime.rs @@ -297,13 +297,12 @@ impl JsRuntime { let op_state = Rc::new(RefCell::new(op_state)); - let refs = bindings::external_references(&ops, op_state.clone()); - let refs: &'static v8::ExternalReferences = Box::leak(Box::new(refs)); let global_context; let (mut isolate, maybe_snapshot_creator) = if options.will_snapshot { // TODO(ry) Support loading snapshots before snapshotting. assert!(options.startup_snapshot.is_none()); - let mut creator = v8::SnapshotCreator::new(Some(refs)); + let mut creator = + v8::SnapshotCreator::new(Some(&bindings::EXTERNAL_REFERENCES)); let isolate = unsafe { creator.get_owned_isolate() }; let mut isolate = JsRuntime::setup_isolate(isolate); { @@ -319,7 +318,7 @@ impl JsRuntime { .create_params .take() .unwrap_or_else(v8::Isolate::create_params) - .external_references(&**refs); + .external_references(&**bindings::EXTERNAL_REFERENCES); let snapshot_loaded = if let Some(snapshot) = options.startup_snapshot { params = match snapshot { Snapshot::Static(data) => params.snapshot_blob(data), @@ -518,6 +517,18 @@ impl JsRuntime { v8::Global::new(scope, cb) } + fn grab_obj<'s>( + 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) + } + /// Grabs a reference to core.js' opresolve & syncOpsCache() fn init_cbs(&mut self) { let mut scope = self.handle_scope(); @@ -594,6 +605,19 @@ impl JsRuntime { /// be a different type if `RuntimeOptions::js_error_create_fn` has been set. pub fn snapshot(&mut self) -> v8::StartupData { assert!(self.snapshot_creator.is_some()); + + // Nuke Deno.core.ops.* to avoid ExternalReference snapshotting issues + // 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(); + for i in 0..names.length() { + let key = names.get_index(scope, i).unwrap(); + obj.delete(scope, key); + } + } + let state = Self::state(self.v8_isolate()); // Note: create_blob() method must not be called from within a HandleScope. |