summaryrefslogtreecommitdiff
path: root/core/runtime.rs
diff options
context:
space:
mode:
authorAaron O'Mullan <aaron.omullan@gmail.com>2022-03-15 22:50:17 +0100
committerGitHub <noreply@github.com>2022-03-15 22:50:17 +0100
commit07d8431f100e8df5f523adf542b47f8b91af3539 (patch)
tree97241da33c3f0e9f45617bdbd0a81d64c49b8e51 /core/runtime.rs
parent163e1d61920fbc6a0bdb18adc57b249b2d600472 (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.rs32
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.