Repository: denoland/deno_core
Pull request #600 (2024-02-23 23:04:35)

chore: checkin type-checks w/tsc
The lint step will actually type-check checkin and all of the extension code in checkin.


Patch:
diff --git a/.github/workflows/ci-job.yml b/.github/workflows/ci-job.yml
index 111b016..4753ec1 100644
--- a/.github/workflows/ci-job.yml
+++ b/.github/workflows/ci-job.yml
@@ -41,7 +41,8 @@ jobs:
 
       - name: Install ARM runner tools
         if: ${{ inputs.os == 'ubuntu-22.04-arm64' }}
-        run: sudo apt update && sudo apt-get install -y unzip clang
+        run: |
+          sudo apt update && sudo apt-get install -y unzip clang
 
       - name: Install Rust
         uses: dsherret/rust-toolchain-file@v1
diff --git a/.github/workflows/ci-lint/action.yml b/.github/workflows/ci-lint/action.yml
index f0b5d67..d3787e3 100644
--- a/.github/workflows/ci-lint/action.yml
+++ b/.github/workflows/ci-lint/action.yml
@@ -7,6 +7,10 @@ runs:
       run: |
         cargo fmt -- --check
         deno fmt --check ./core/ ./ops/ ./serde_v8/
+    - name: tsc
+      shell: bash
+      run: |
+        deno run --allow-read --allow-env npm:typescript@5.3.3/tsc --noEmit -p testing/tsconfig.json
     - name: Lint
       shell: bash
       run: |
diff --git a/core/01_core.js b/core/01_core.js
index 18980ec..6a1b8dd 100644
--- a/core/01_core.js
+++ b/core/01_core.js
@@ -378,7 +378,7 @@
     );
   }
 
-  function ensureFastOps(keep) {
+  function ensureFastOps(keep = false) {
     return new Proxy({}, {
       get(_target, opName) {
         const op = ops[opName];
diff --git a/core/benches/snapshot/snapshot.rs b/core/benches/snapshot/snapshot.rs
index ed45b2a..e2b01cc 100644
--- a/core/benches/snapshot/snapshot.rs
+++ b/core/benches/snapshot/snapshot.rs
@@ -128,7 +128,8 @@ fn bench_load_snapshot(c: &mut Criterion) {
       startup_snapshot: None,
       ..Default::default()
     });
-    let snapshot = runtime.snapshot().leak();
+    let snapshot = runtime.snapshot();
+    let snapshot = Box::leak(snapshot);
 
     b.iter_custom(|iters| {
       let mut total = 0;
diff --git a/core/internal.d.ts b/core/internal.d.ts
index b09d188..9986c63 100644
--- a/core/internal.d.ts
+++ b/core/internal.d.ts
@@ -46,7 +46,7 @@ declare namespace __bootstrap {
    * primordials.StringPrototypeStartsWith('thing', 'hello')
    * ```
    */
-  declare namespace primordials {
+  namespace primordials {
     type UncurryThis<T extends (this: unknown, ...args: unknown[]) => unknown> =
       (self: ThisParameterType<T>, ...args: Parameters<T>) => ReturnType<T>;
     type UncurryThisStaticApply<
diff --git a/core/lib.deno_core.d.ts b/core/lib.deno_core.d.ts
index 173e055..7252002 100644
--- a/core/lib.deno_core.d.ts
+++ b/core/lib.deno_core.d.ts
@@ -8,7 +8,7 @@
 declare namespace Deno {
   namespace core {
     /** Returns a proxy that generates the fast versions of sync and async ops. */
-    function ensureFastOps(): any;
+    function ensureFastOps(keep?: boolean): any;
 
     /** Mark following promise as "ref", ie. event loop won't exit
      * until all "ref" promises are resolved. All async ops are "ref" by default. */
diff --git a/core/lib.rs b/core/lib.rs
index f39cf0d..e19e55d 100644
--- a/core/lib.rs
+++ b/core/lib.rs
@@ -181,11 +181,6 @@ pub mod snapshot {
   pub use crate::runtime::CreateSnapshotOutput;
   pub use crate::runtime::FilterFn;
   pub use crate::runtime::Snapshot;
-  pub use crate::runtime::SnapshotBulkCompressingSerializer;
-  pub use crate::runtime::SnapshotData;
-  pub use crate::runtime::SnapshotFileSerializer;
-  pub use crate::runtime::SnapshotInMemorySerializer;
-  pub use crate::runtime::SnapshotSerializer;
 }
 
 /// A helper macro that will return a call site in Rust code. Should be
diff --git a/core/runtime/jsruntime.rs b/core/runtime/jsruntime.rs
index c976ad7..0001436 100644
--- a/core/runtime/jsruntime.rs
+++ b/core/runtime/jsruntime.rs
@@ -9,7 +9,6 @@ use super::op_driver::OpDriver;
 use super::setup;
 use super::snapshot;
 use super::stats::RuntimeActivityStatsFactory;
-use super::SnapshotData;
 use super::SnapshotStoreDataStore;
 use super::SnapshottedData;
 use crate::error::exception_to_err_result;
@@ -1875,7 +1874,7 @@ impl JsRuntimeForSnapshot {
   /// Takes a snapshot and consumes the runtime.
   ///
   /// `Error` can usually be downcast to `JsError`.
-  pub fn snapshot(mut self) -> SnapshotData {
+  pub fn snapshot(mut self) -> Box<[u8]> {
     // Ensure there are no live inspectors to prevent crashes.
     self.inner.prepare_for_cleanup();
 
@@ -1931,13 +1930,14 @@ impl JsRuntimeForSnapshot {
     };
     drop(realm);
 
-    let v8 = self
+    let v8_data = self
       .0
       .inner
       .prepare_for_snapshot()
       .create_blob(v8::FunctionCodeHandling::Keep)
       .unwrap();
-    SnapshotData { v8, sidecar_data }
+
+    snapshot::serialize(v8_data, sidecar_data)
   }
 }
 
diff --git a/core/runtime/mod.rs b/core/runtime/mod.rs
index 278c090..a4deb01 100644
--- a/core/runtime/mod.rs
+++ b/core/runtime/mod.rs
@@ -38,13 +38,8 @@ pub use snapshot::CreateSnapshotOptions;
 pub use snapshot::CreateSnapshotOutput;
 pub use snapshot::FilterFn;
 pub use snapshot::Snapshot;
-pub use snapshot::SnapshotBulkCompressingSerializer;
-pub use snapshot::SnapshotData;
 pub(crate) use snapshot::SnapshotDataId;
-pub use snapshot::SnapshotFileSerializer;
-pub use snapshot::SnapshotInMemorySerializer;
 pub(crate) use snapshot::SnapshotLoadDataStore;
-pub use snapshot::SnapshotSerializer;
 pub(crate) use snapshot::SnapshotStoreDataStore;
 pub(crate) use snapshot::SnapshottedData;
 
diff --git a/core/runtime/setup.rs b/core/runtime/setup.rs
index 1f0c3dc..76076bc 100644
--- a/core/runtime/setup.rs
+++ b/core/runtime/setup.rs
@@ -127,7 +127,6 @@ pub fn create_isolate(
     if let Some(snapshot) = maybe_startup_snapshot {
       params = match snapshot {
         V8StartupData::Static(data) => params.snapshot_blob(data),
-        V8StartupData::JustCreated(data) => params.snapshot_blob(data),
         V8StartupData::Boxed(data) => params.snapshot_blob(data),
       };
     }
diff --git a/core/runtime/snapshot.rs b/core/runtime/snapshot.rs
index 7799c55..3343b34 100644
--- a/core/runtime/snapshot.rs
+++ b/core/runtime/snapshot.rs
@@ -4,8 +4,6 @@ use anyhow::Error;
 use serde::Deserialize;
 use serde::Serialize;
 use std::collections::HashMap;
-use std::fmt::Debug;
-use std::io::Write;
 use std::path::Path;
 use std::path::PathBuf;
 use std::time::Instant;
@@ -26,8 +24,6 @@ const ULEN: usize = std::mem::size_of::<usize>();
 pub enum Snapshot {
   /// Embedded in static data.
   Static(&'static [u8]),
-  /// Freshly created, unserialized.
-  JustCreated(SnapshotData),
   /// Freshly created, serialized as a boxed slice.
   Boxed(Box<[u8]>),
 }
@@ -37,8 +33,6 @@ pub enum Snapshot {
 pub(crate) enum V8StartupData {
   /// Embedded in static data.
   Static(&'static [u8]),
-  /// Freshly created, unserialized.
-  JustCreated(v8::StartupData),
   /// Freshly created, serialized as a boxed slice.
   Boxed(Box<[u8]>),
 }
@@ -47,82 +41,44 @@ impl Snapshot {
   pub(crate) fn deconstruct(
     self,
   ) -> (V8StartupData, SerializableSnapshotSidecarData) {
-    if let Snapshot::JustCreated(snapshot) = self {
-      (
-        V8StartupData::JustCreated(snapshot.v8),
-        snapshot.sidecar_data,
-      )
-    } else {
-      match self {
-        Snapshot::Static(slice) => {
-          let len = usize::from_le_bytes(
-            slice[slice.len() - ULEN..].try_into().unwrap(),
-          );
-          let data = SerializableSnapshotSidecarData::from_slice(
-            &slice[len..slice.len() - ULEN],
-          );
-          (V8StartupData::Static(&slice[0..len]), data)
-        }
-        Snapshot::Boxed(slice) => {
-          let len = usize::from_le_bytes(
-            slice[slice.len() - ULEN..].try_into().unwrap(),
-          );
-          let data = SerializableSnapshotSidecarData::from_slice(
-            &slice[len..slice.len() - ULEN],
-          );
-          let mut v8 = Vec::from(slice);
-          v8.truncate(len);
-          let v8 = v8.into_boxed_slice();
-          (V8StartupData::Boxed(v8), data)
-        }
-        Snapshot::JustCreated(..) => unreachable!(),
+    match self {
+      Snapshot::Static(slice) => {
+        let len =
+          usize::from_le_bytes(slice[slice.len() - ULEN..].try_into().unwrap());
+        let data = SerializableSnapshotSidecarData::from_slice(
+          &slice[len..slice.len() - ULEN],
+        );
+        (V8StartupData::Static(&slice[0..len]), data)
+      }
+      Snapshot::Boxed(slice) => {
+        let len =
+          usize::from_le_bytes(slice[slice.len() - ULEN..].try_into().unwrap());
+        let data = SerializableSnapshotSidecarData::from_slice(
+          &slice[len..slice.len() - ULEN],
+        );
+        let mut v8 = Vec::from(slice);
+        v8.truncate(len);
+        let v8 = v8.into_boxed_slice();
+        (V8StartupData::Boxed(v8), data)
       }
     }
   }
 }
 
-/// An opaque blob of snapshot data that can be serialized to a [`SnapshotSerializer`].
-pub struct SnapshotData {
-  pub(crate) v8: v8::StartupData,
-  pub(crate) sidecar_data: SerializableSnapshotSidecarData,
-}
-
-impl SnapshotData {
-  /// Serialize this data into a [`SnapshotSerializer`].
-  pub fn serialize<T>(
-    self,
-    mut serializer: impl SnapshotSerializer<Output = T>,
-  ) -> std::io::Result<T> {
-    let sidecar_data = self.sidecar_data.into_bytes();
-    let len = ULEN + self.v8.len() + sidecar_data.len();
-    serializer.initialize(len)?;
-    let v8_size: usize = self.v8.len();
-    serializer.process_chunk(&self.v8)?;
-    serializer.process_chunk(&sidecar_data)?;
-    serializer.process_chunk(&v8_size.to_le_bytes())?;
-    serializer.finalize()
-  }
-
-  /// Create a static slice for a snapshot by leaking data.
-  pub fn leak(self) -> &'static [u8] {
-    let slice = Box::leak(
-      self
-        .serialize(SnapshotInMemorySerializer::default())
-        .unwrap(),
-    );
-    slice
-  }
+pub(crate) fn serialize(
+  v8_data: v8::StartupData,
+  sidecar_data: SerializableSnapshotSidecarData,
+) -> Box<[u8]> {
+  let v8_data_len = v8_data.len();
+  let sidecar_data = sidecar_data.into_bytes();
+  let mut data = Vec::with_capacity(v8_data_len + sidecar_data.len() + ULEN);
 
-  /// Create a boxed slice for a snapshot.
-  pub fn boxed(self) -> Box<[u8]> {
-    self
-      .serialize(SnapshotInMemorySerializer::default())
-      .unwrap()
-  }
+  // add ulen
+  data.extend_from_slice(&v8_data);
+  data.extend_from_slice(&sidecar_data);
+  data.extend_from_slice(&v8_data_len.to_le_bytes());
 
-  pub fn v8_len(&self) -> usize {
-    self.v8.len()
-  }
+  data.into_boxed_slice()
 }
 
 #[derive(Default)]
@@ -179,200 +135,28 @@ impl SnapshotStoreDataStore {
   }
 }
 
-/// Handles the serialization of the snapshot.
-pub trait SnapshotSerializer: Debug {
-  type Output;
-  fn initialize(&mut self, approximate_length: usize) -> std::io::Result<()>;
-  fn process_chunk(&mut self, chunk: &[u8]) -> std::io::Result<()>;
-  fn finalize(self) -> std::io::Result<Self::Output>;
-}
-
-mod sealed {
-  use super::SnapshotSerializer;
-  use std::any::Any;
-
-  /// Allows us to consume `self` in a boxed trait. This is required to allow
-  /// [`SnapshotSerializer`] to be boxed.
-  pub trait SnapshotSerializerSized: SnapshotSerializer + Unpin {
-    #[allow(clippy::type_complexity)]
-    fn get_finalizer(
-      &mut self,
-    ) -> fn(
-      Box<dyn SnapshotSerializerSized<Output = Self::Output> + 'static>,
-    ) -> std::io::Result<Self::Output>;
-  }
-
-  impl<T, S: SnapshotSerializer<Output = T> + Unpin + Any + 'static>
-    SnapshotSerializerSized for S
-  {
-    fn get_finalizer(
-      &mut self,
-    ) -> fn(
-      Box<dyn SnapshotSerializerSized<Output = Self::Output> + 'static>,
-    ) -> std::io::Result<Self::Output> {
-      |b| {
-        // SAFETY: We know that get_finalizer was called on a type of S through dynamic dispatch, so we can
-        // safely transmute this pointer from fat to thin and then finalize it.
-        let our_type = unsafe { Box::<S>::from_raw(Box::into_raw(b) as _) };
-        our_type.finalize()
-      }
-    }
-  }
-}
-
-impl<T> SnapshotSerializer
-  for Box<dyn sealed::SnapshotSerializerSized<Output = T> + 'static>
-{
-  type Output = T;
-  fn finalize(mut self) -> std::io::Result<Self::Output> {
-    (self.get_finalizer())(self)
-  }
-  fn initialize(&mut self, approximate_length: usize) -> std::io::Result<()> {
-    (**self).initialize(approximate_length)
-  }
-  fn process_chunk(&mut self, chunk: &[u8]) -> std::io::Result<()> {
-    (**self).process_chunk(chunk)
-  }
-}
-
-/// Serializes the snapshot to a file.
-#[derive(Debug)]
-pub struct SnapshotFileSerializer {
-  file: std::fs::File,
-}
-
-impl SnapshotFileSerializer {
-  pub fn new(file: std::fs::File) -> Self {
-    Self { file }
-  }
-}
-
-impl SnapshotSerializer for SnapshotFileSerializer {
-  type Output = std::fs::File;
-  fn initialize(&mut self, _approximate_length: usize) -> std::io::Result<()> {
-    Ok(())
-  }
-
-  fn process_chunk(&mut self, chunk: &[u8]) -> std::io::Result<()> {
-    self.file.write_all(chunk)
-  }
-
-  fn finalize(self) -> std::io::Result<Self::Output> {
-    Ok(self.file)
-  }
-}
-
-/// Serializes the snapshot to another serializer, with a bulk compression operation performed on top.
-pub struct SnapshotBulkCompressingSerializer<S: SnapshotSerializer> {
-  serializer: S,
-  compression: Box<dyn FnOnce(Vec<u8>) -> std::io::Result<Vec<u8>>>,
-  accumulator: Vec<u8>,
-}
-
-impl<S: SnapshotSerializer> Debug for SnapshotBulkCompressingSerializer<S> {
-  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-    f.write_fmt(format_args!(
-      "SnapshotBulkCompressingSerializer {{ {:?} }}",
-      self.serializer
-    ))
-  }
-}
-
-impl<S: SnapshotSerializer> SnapshotBulkCompressingSerializer<S> {
-  /// Create a new bulk-compressing serializer with a function that accepts
-  /// the uncompressed snapshot data and returns a new [`Vec<u8>`] containing
-  /// the compressed data. The compression function may choose to compress in-place.
-  pub fn new(
-    serializer: S,
-    compression: impl FnOnce(Vec<u8>) -> std::io::Result<Vec<u8>> + 'static,
-  ) -> Self {
-    Self {
-      serializer,
-      compression: Box::new(compression),
-      accumulator: Default::default(),
-    }
-  }
-}
-
-impl<S: SnapshotSerializer> SnapshotSerializer
-  for SnapshotBulkCompressingSerializer<S>
-{
-  type Output = S::Output;
-
-  fn initialize(&mut self, approximate_length: usize) -> std::io::Result<()> {
-    // Approximate 25% compression for a snapshot
-    self.accumulator.reserve_exact(approximate_length);
-    self.serializer.initialize(approximate_length * 3 / 4)
-  }
-
-  fn process_chunk(&mut self, chunk: &[u8]) -> std::io::Result<()> {
-    self.accumulator.extend(chunk);
-    Ok(())
-  }
-
-  fn finalize(mut self) -> std::io::Result<Self::Output> {
-    let output = (self.compression)(self.accumulator)?;
-    self.serializer.process_chunk(&output)?;
-    self.serializer.finalize()
-  }
-}
-
-/// Serialize a snapshot to memory.
-#[derive(Default)]
-pub struct SnapshotInMemorySerializer {
-  memory: Vec<u8>,
-}
-
-impl Debug for SnapshotInMemorySerializer {
-  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-    f.write_str("SnapshotInMemorySerializer")
-  }
-}
-
-impl SnapshotSerializer for SnapshotInMemorySerializer {
-  type Output = Box<[u8]>;
-
-  fn initialize(&mut self, length: usize) -> std::io::Result<()> {
-    self.memory.reserve_exact(length);
-    Ok(())
-  }
-
-  fn process_chunk(&mut self, chunk: &[u8]) -> std::io::Result<()> {
-    self.memory.extend(chunk);
-    Ok(())
-  }
-
-  fn finalize(self) -> std::io::Result<Self::Output> {
-    Ok(self.memory.into_boxed_slice())
-  }
-}
-
-pub struct CreateSnapshotOptions<T> {
+pub struct CreateSnapshotOptions {
   pub cargo_manifest_dir: &'static str,
   pub startup_snapshot: Option<Snapshot>,
   pub skip_op_registration: bool,
   pub extensions: Vec<Extension>,
-  pub serializer: Box<dyn sealed::SnapshotSerializerSized<Output = T>>,
   pub with_runtime_cb: Option<Box<WithRuntimeCb>>,
 }
 
-pub struct CreateSnapshotOutput<T> {
+pub struct CreateSnapshotOutput {
   /// Any files marked as LoadedFromFsDuringSnapshot are collected here and should be
   /// printed as 'cargo:rerun-if-changed' lines from your build script.
   pub files_loaded_during_snapshot: Vec<PathBuf>,
-  pub output: T,
+  pub output: Box<[u8]>,
 }
 
 #[must_use = "The files listed by create_snapshot should be printed as 'cargo:rerun-if-changed' lines"]
-pub fn create_snapshot<T>(
-  create_snapshot_options: CreateSnapshotOptions<T>,
+pub fn create_snapshot(
+  create_snapshot_options: CreateSnapshotOptions,
   warmup_script: Option<&'static str>,
-) -> Result<CreateSnapshotOutput<T>, Error> {
+) -> Result<CreateSnapshotOutput, Error> {
   let mut mark = Instant::now();
-  println!(
-    "Serializing snapshot to {:?}",
-    create_snapshot_options.serializer
-  );
+  println!("Creating a snapshot...",);
 
   // Get the extensions for a second pass if we want to warm up the snapshot.
   let warmup_exts = warmup_script.map(|_| {
@@ -413,7 +197,7 @@ pub fn create_snapshot<T>(
     // - Run warmup script in new context.
     // - Serialize the new context into a new snapshot blob.
     let mut js_runtime = JsRuntimeForSnapshot::new(RuntimeOptions {
-      startup_snapshot: Some(Snapshot::JustCreated(snapshot)),
+      startup_snapshot: Some(Snapshot::Boxed(snapshot)),
       extensions: warmup_exts,
       skip_op_registration: true,
       ..Default::default()
@@ -430,13 +214,11 @@ pub fn create_snapshot<T>(
 
   println!(
     "Snapshot size: {}, took {:#?}",
-    snapshot.v8_len(),
+    snapshot.len(),
     mark.elapsed(),
   );
   mark = Instant::now();
 
-  let output = snapshot.serialize(create_snapshot_options.serializer)?;
-
   println!(
     "Snapshot written, took: {:#?}",
     Instant::now().saturating_duration_since(mark),
@@ -444,7 +226,7 @@ pub fn create_snapshot<T>(
 
   Ok(CreateSnapshotOutput {
     files_loaded_during_snapshot,
-    output,
+    output: snapshot,
   })
 }
 
@@ -585,12 +367,6 @@ pub(crate) fn create_snapshot_creator(
           Some(external_refs),
         )
       }
-      V8StartupData::JustCreated(snapshot) => {
-        v8::Isolate::snapshot_creator_from_existing_snapshot(
-          snapshot,
-          Some(external_refs),
-        )
-      }
       V8StartupData::Static(snapshot) => {
         v8::Isolate::snapshot_creator_from_existing_snapshot(
           snapshot,


Test patch:
diff --git a/core/modules/tests.rs b/core/modules/tests.rs
index 9429afc..8a38491 100644
--- a/core/modules/tests.rs
+++ b/core/modules/tests.rs
@@ -1428,7 +1428,7 @@ fn dynamic_imports_snapshot() {
     runtime.snapshot()
   };
 
-  let snapshot = Snapshot::JustCreated(snapshot);
+  let snapshot = Snapshot::Boxed(snapshot);
   let mut runtime2 = JsRuntime::new(RuntimeOptions {
     startup_snapshot: Some(snapshot),
     ..Default::default()
@@ -1471,7 +1471,7 @@ fn import_meta_snapshot() {
     runtime.snapshot()
   };
 
-  let snapshot = Snapshot::JustCreated(snapshot);
+  let snapshot = Snapshot::Boxed(snapshot);
   let mut runtime2 = JsRuntime::new(RuntimeOptions {
     startup_snapshot: Some(snapshot),
     ..Default::default()
diff --git a/core/runtime/tests/jsrealm.rs b/core/runtime/tests/jsrealm.rs
index 7abefd2..37b094f 100644
--- a/core/runtime/tests/jsrealm.rs
+++ b/core/runtime/tests/jsrealm.rs
@@ -144,7 +144,7 @@ fn es_snapshot() {
   };
   let mut runtime = JsRuntime::new(RuntimeOptions {
     module_loader: None,
-    startup_snapshot: Some(Snapshot::JustCreated(startup_data)),
+    startup_snapshot: Some(Snapshot::Boxed(startup_data)),
     ..Default::default()
   });
 
diff --git a/core/runtime/tests/snapshot.rs b/core/runtime/tests/snapshot.rs
index ef3a56f..033d64d 100644
--- a/core/runtime/tests/snapshot.rs
+++ b/core/runtime/tests/snapshot.rs
@@ -11,7 +11,6 @@ use std::rc::Rc;
 
 use self::runtime::create_snapshot;
 use self::runtime::CreateSnapshotOptions;
-use self::runtime::SnapshotInMemorySerializer;
 
 #[test]
 fn will_snapshot() {
@@ -21,7 +20,7 @@ fn will_snapshot() {
     runtime.snapshot()
   };
 
-  let snapshot = Snapshot::JustCreated(snapshot);
+  let snapshot = Snapshot::Boxed(snapshot);
   let mut runtime2 = JsRuntime::new(RuntimeOptions {
     startup_snapshot: Some(snapshot),
     ..Default::default()
@@ -41,7 +40,7 @@ fn will_snapshot2() {
     runtime.snapshot()
   };
 
-  let snapshot = Snapshot::JustCreated(startup_data);
+  let snapshot = Snapshot::Boxed(startup_data);
   let mut runtime = JsRuntimeForSnapshot::new(RuntimeOptions {
     startup_snapshot: Some(snapshot),
     ..Default::default()
@@ -55,7 +54,7 @@ fn will_snapshot2() {
     runtime.snapshot()
   };
 
-  let snapshot = Snapshot::JustCreated(startup_data);
+  let snapshot = Snapshot::Boxed(startup_data);
   {
     let mut runtime = JsRuntime::new(RuntimeOptions {
       startup_snapshot: Some(snapshot),
@@ -94,7 +93,7 @@ fn test_snapshot_callbacks() {
     runtime.snapshot()
   };
 
-  let snapshot = Snapshot::JustCreated(snapshot);
+  let snapshot = Snapshot::Boxed(snapshot);
   let mut runtime2 = JsRuntime::new(RuntimeOptions {
     startup_snapshot: Some(snapshot),
     ..Default::default()
@@ -109,7 +108,7 @@ fn test_from_snapshot_boxed() {
   let snapshot = {
     let mut runtime = JsRuntimeForSnapshot::new(Default::default());
     runtime.execute_script_static("a.js", "a = 1 + 2").unwrap();
-    runtime.snapshot().boxed()
+    runtime.snapshot()
   };
 
   let snapshot = Snapshot::Boxed(snapshot);
@@ -127,7 +126,8 @@ fn test_from_snapshot_static() {
   let snapshot = {
     let mut runtime = JsRuntimeForSnapshot::new(Default::default());
     runtime.execute_script_static("a.js", "a = 1 + 2").unwrap();
-    runtime.snapshot().leak()
+    let data = runtime.snapshot();
+    Box::leak(data)
   };
 
   let snapshot = Snapshot::Static(snapshot);
@@ -152,7 +152,6 @@ fn test_snapshot_creator() {
       with_runtime_cb: Some(Box::new(|runtime| {
         runtime.execute_script_static("a.js", "a = 1 + 2").unwrap();
       })),
-      serializer: Box::<SnapshotInMemorySerializer>::default(),
     },
     None,
   )
@@ -185,7 +184,6 @@ fn test_snapshot_creator_warmup() {
 
         runtime.execute_script_static("a.js", "a = 1 + 2").unwrap();
       })),
-      serializer: Box::<SnapshotInMemorySerializer>::default(),
     },
     Some("const b = 'Hello'"),
   )
@@ -297,7 +295,7 @@ fn es_snapshot() {
   let snapshot = runtime.snapshot();
 
   let mut runtime2 = JsRuntimeForSnapshot::new(RuntimeOptions {
-    startup_snapshot: Some(Snapshot::JustCreated(snapshot)),
+    startup_snapshot: Some(Snapshot::Boxed(snapshot)),
     extensions: vec![Extension {
       name: "test_ext",
       ops: Cow::Borrowed(&[op_test::DECL]),
@@ -316,7 +314,7 @@ fn es_snapshot() {
   let snapshot2 = runtime2.snapshot();
 
   let mut runtime3 = JsRuntime::new(RuntimeOptions {
-    startup_snapshot: Some(Snapshot::JustCreated(snapshot2)),
+    startup_snapshot: Some(Snapshot::Boxed(snapshot2)),
     extensions: vec![Extension {
       name: "test_ext",
       ops: Cow::Borrowed(&[op_test::DECL]),
@@ -362,7 +360,7 @@ pub(crate) fn es_snapshot_without_runtime_module_loader() {
 
   let mut runtime = JsRuntime::new(RuntimeOptions {
     module_loader: None,
-    startup_snapshot: Some(Snapshot::JustCreated(startup_data)),
+    startup_snapshot: Some(Snapshot::Boxed(startup_data)),
     ..Default::default()
   });
   let realm = runtime.main_realm();
diff --git a/testing/checkin.d.ts b/testing/checkin.d.ts
index 56f3e21..ae215c2 100644
--- a/testing/checkin.d.ts
+++ b/testing/checkin.d.ts
@@ -1,13 +1,16 @@
 // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
 /// <reference path="../core/lib.deno_core.d.ts" />
+// TODO(mmastrac): make this typecheck
+// <reference path="../core/internal.d.ts" />
 /// <reference lib="dom" />
 
+// deno-lint-ignore-file no-explicit-any
+
 // Types and method unavailable in TypeScript by default.
 interface PromiseConstructor {
   withResolvers<T>(): {
     promise: Promise<T>;
     resolve: (value: T | PromiseLike<T>) => void;
-    // deno-lint-ignore no-explicit-any
     reject: (reason?: any) => void;
   };
 }
@@ -24,3 +27,28 @@ declare namespace Deno {
   export function refTimer(id);
   export function unrefTimer(id);
 }
+
+declare module 'ext:core/mod.js' {
+  const core: any;
+}
+
+declare module 'ext:core/ops' {
+  function op_log_debug(...any): any;
+  function op_log_info(...any): any;
+
+  function op_test_register(...any): any;
+
+  function op_async_throw_error_deferred(...any): any;
+  function op_async_throw_error_eager(...any): any;
+  function op_async_throw_error_lazy(...any): any;
+  function op_error_context_async(...any): any;
+  function op_error_context_sync(...any): any;
+  function op_error_custom_sync(...any): any;
+
+  function op_worker_await_close(...any): any;
+  function op_worker_parent(...any): any;
+  function op_worker_recv(...any): any;
+  function op_worker_send(...any): any;
+  function op_worker_spawn(...any): any;
+  function op_worker_terminate(...any): any;
+}
diff --git a/testing/checkin/runner/mod.rs b/testing/checkin/runner/mod.rs
index c8ebe21..e2da2bc 100644
--- a/testing/checkin/runner/mod.rs
+++ b/testing/checkin/runner/mod.rs
@@ -107,7 +107,7 @@ fn create_runtime(
     ..Default::default()
   });
 
-  let snapshot = runtime_for_snapshot.snapshot().boxed();
+  let snapshot = runtime_for_snapshot.snapshot();
 
   let extensions = vec![checkin_runtime::init_ops()];
   let mut runtime = JsRuntime::new(RuntimeOptions {
diff --git a/testing/checkin/runtime/__init.js b/testing/checkin/runtime/__init.js
index 98504bc..ec0888c 100644
--- a/testing/checkin/runtime/__init.js
+++ b/testing/checkin/runtime/__init.js
@@ -10,6 +10,7 @@ import * as throw_ from "checkin:throw";
 testing;
 async;
 error;
+throw_;
 
 globalThis.console = console.console;
 globalThis.setTimeout = timers.setTimeout;
@@ -17,7 +18,6 @@ globalThis.setInterval = timers.setInterval;
 globalThis.clearTimeout = timers.clearTimeout;
 globalThis.clearInterval = timers.clearInterval;
 globalThis.Worker = worker.Worker;
-globalThis.throwInExt = throw_.throwInExt;
 Reflect.defineProperty(globalThis, "onerror", {
   set: (cb) => {
     if (cb) {
diff --git a/testing/checkin/runtime/throw.ts b/testing/checkin/runtime/throw.ts
index 5e25594..2f44427 100644
--- a/testing/checkin/runtime/throw.ts
+++ b/testing/checkin/runtime/throw.ts
@@ -3,7 +3,7 @@
 /**
  * This is needed to test that stack traces in extensions are correct.
  */
-export function throwInExt() {
+export function throwExceptionFromExtension() {
   innerThrowInExt();
 }
 
diff --git a/testing/integration/error_ext_stack/error_ext_stack.out b/testing/integration/error_ext_stack/error_ext_stack.out
index 2c32eb3..b585138 100644
--- a/testing/integration/error_ext_stack/error_ext_stack.out
+++ b/testing/integration/error_ext_stack/error_ext_stack.out
@@ -1,4 +1,4 @@
 [ERR] Error: Failed
 [ERR]     at innerThrowInExt (checkin:throw:11:9)
-[ERR]     at throwInExt (checkin:throw:7:3)
-[ERR]     at test:///integration/error_ext_stack/error_ext_stack.ts:3:1
+[ERR]     at throwExceptionFromExtension (checkin:throw:7:3)
+[ERR]     at test:///integration/error_ext_stack/error_ext_stack.ts:4:1
diff --git a/testing/integration/error_ext_stack/error_ext_stack.ts b/testing/integration/error_ext_stack/error_ext_stack.ts
index cade9a2..1be2be5 100644
--- a/testing/integration/error_ext_stack/error_ext_stack.ts
+++ b/testing/integration/error_ext_stack/error_ext_stack.ts
@@ -1,4 +1,5 @@
 // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
 // FAIL
+import { throwExceptionFromExtension } from "checkin:throw";
 
-throwInExt();
+throwExceptionFromExtension();
diff --git a/testing/tsconfig.json b/testing/tsconfig.json
index b997ba5..3dbf5ff 100644
--- a/testing/tsconfig.json
+++ b/testing/tsconfig.json
@@ -7,6 +7,7 @@
       "checkin:console": ["checkin/runtime/console.ts"],
       "checkin:error": ["checkin/runtime/error.ts"],
       "checkin:testing": ["checkin/runtime/testing.ts"],
+      "checkin:throw": ["checkin/runtime/throw.ts"],
       "checkin:timers": ["checkin/runtime/timers.ts"],
       "checkin:worker": ["checkin/runtime/worker.ts"]
     },