Repository: denoland/deno_core
Pull request #620 (2024-02-29 21:38:37)

refactor(core): fast string overhaul


With this change, `FastString`s created from `ascii_str!` are one-byte const capable.

Because `FastString` may hold a non-static value like a `Box` or `Arc<str>`, we introduce `FastStaticString` as a way to guarantee that a string is compatible with v8 `OneByteConst`s.

To simplify use of the API, the embedder-facing script load/execute functions now take an `impl IntoModuleSourceCode`, allowing us to remove the static string overloads. 

codecov-commenter: ## [Codecov](https://app.codecov.io/gh/denoland/deno_core/pull/620?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=denoland) Report
Attention: Patch coverage is `77.11111%` with `103 lines` in your changes are missing coverage. Please review.
> Project coverage is 81.83%. Comparing base [(`e42470d`)](https://app.codecov.io/gh/denoland/deno_core/commit/e42470db922eabd75984d82f413c0f043e396dd7?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=denoland) to head [(`490c29a`)](https://app.codecov.io/gh/denoland/deno_core/pull/620?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=denoland).

| [Files](https://app.codecov.io/gh/denoland/deno_core/pull/620?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=denoland) | Patch % | Lines |
|---|---|---|
| [core/fast\_string.rs](https://app.codecov.io/gh/denoland/deno_core/pull/620?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=denoland#diff-Y29yZS9mYXN0X3N0cmluZy5ycw==) | 59.52% | [68 Missing :warning: ](https://app.codecov.io/gh/denoland/deno_core/pull/620?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=denoland) |
| [core/extensions.rs](https://app.codecov.io/gh/denoland/deno_core/pull/620?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=denoland#diff-Y29yZS9leHRlbnNpb25zLnJz) | 14.28% | [12 Missing :warning: ](https://app.codecov.io/gh/denoland/deno_core/pull/620?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=denoland) |
| [core/runtime/jsruntime.rs](https://app.codecov.io/gh/denoland/deno_core/pull/620?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=denoland#diff-Y29yZS9ydW50aW1lL2pzcnVudGltZS5ycw==) | 75.00% | [9 Missing :warning: ](https://app.codecov.io/gh/denoland/deno_core/pull/620?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=denoland) |
| [core/modules/mod.rs](https://app.codecov.io/gh/denoland/deno_core/pull/620?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=denoland#diff-Y29yZS9tb2R1bGVzL21vZC5ycw==) | 78.12% | [7 Missing :warning: ](https://app.codecov.io/gh/denoland/deno_core/pull/620?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=denoland) |
| [core/runtime/jsrealm.rs](https://app.codecov.io/gh/denoland/deno_core/pull/620?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=denoland#diff-Y29yZS9ydW50aW1lL2pzcmVhbG0ucnM=) | 40.00% | [6 Missing :warning: ](https://app.codecov.io/gh/denoland/deno_core/pull/620?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=denoland) |
| [core/main.rs](https://app.codecov.io/gh/denoland/deno_core/pull/620?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=denoland#diff-Y29yZS9tYWluLnJz) | 0.00% | [1 Missing :warning: ](https://app.codecov.io/gh/denoland/deno_core/pull/620?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=denoland) |

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main     #620      +/-   ##
==========================================
- Coverage   82.03%   81.83%   -0.20%     
==========================================
  Files          96       96              
  Lines       23281    23408     +127     
==========================================
+ Hits        19098    19157      +59     
- Misses       4183     4251      +68     
```



</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/denoland/deno_core/pull/620?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=denoland).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=denoland).


Patch:
diff --git a/core/examples/op2.rs b/core/examples/op2.rs
index 6e08eb7..d91d0a2 100644
--- a/core/examples/op2.rs
+++ b/core/examples/op2.rs
@@ -44,10 +44,7 @@ fn main() -> Result<(), Error> {
 
   let future = async move {
     let mod_id = js_runtime
-      .load_main_module(
-        &main_module,
-        Some(deno_core::FastString::from(module_code)),
-      )
+      .load_main_es_module_from_code(&main_module, module_code)
       .await?;
 
     let result = js_runtime.mod_evaluate(mod_id);
diff --git a/core/examples/ts_module_loader.rs b/core/examples/ts_module_loader.rs
index 9b657c9..44d63dd 100644
--- a/core/examples/ts_module_loader.rs
+++ b/core/examples/ts_module_loader.rs
@@ -155,7 +155,7 @@ fn main() -> Result<(), Error> {
   )?;
 
   let future = async move {
-    let mod_id = js_runtime.load_main_module(&main_module, None).await?;
+    let mod_id = js_runtime.load_main_es_module(&main_module).await?;
     let result = js_runtime.mod_evaluate(mod_id);
     js_runtime.run_event_loop(Default::default()).await?;
     result.await
diff --git a/core/examples/wasm.rs b/core/examples/wasm.rs
index 1b6b6a7..8ebf2af 100644
--- a/core/examples/wasm.rs
+++ b/core/examples/wasm.rs
@@ -72,6 +72,6 @@ fn main() {
   });
 
   runtime
-    .execute_script("<usage>", include_ascii_string!("wasm.js"))
+    .execute_script("<usage>", ascii_str_include!("wasm.js"))
     .unwrap();
 }
diff --git a/core/extension_set.rs b/core/extension_set.rs
index 309daad..757778e 100644
--- a/core/extension_set.rs
+++ b/core/extension_set.rs
@@ -92,10 +92,7 @@ fn check_no_duplicate_op_names(ops: &[OpDecl]) {
   let mut count_by_name = HashMap::new();
 
   for op in ops.iter() {
-    count_by_name
-      .entry(&op.name)
-      .or_insert(vec![])
-      .push(op.name.to_string());
+    count_by_name.entry(op.name).or_insert(vec![]).push(op.name);
   }
 
   let mut duplicate_ops = vec![];
diff --git a/core/extensions.rs b/core/extensions.rs
index 155abc7..644f0ad 100644
--- a/core/extensions.rs
+++ b/core/extensions.rs
@@ -1,6 +1,8 @@
 // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+use crate::modules::IntoModuleCodeString;
 use crate::modules::ModuleCodeString;
 use crate::runtime::bindings;
+use crate::FastStaticString;
 use crate::OpState;
 use anyhow::Context as _;
 use anyhow::Error;
@@ -17,7 +19,7 @@ pub enum ExtensionFileSourceCode {
   /// will result in two copies of the source code being included - one in the
   /// snapshot, the other the static string in the `Extension`.
   #[deprecated = "Use ExtensionFileSource::new"]
-  IncludedInBinary(&'static str),
+  IncludedInBinary(FastStaticString),
 
   // Source code is loaded from a file on disk. It's meant to be used if the
   // embedder is creating snapshots. Files will be loaded from the filesystem
@@ -27,7 +29,7 @@ pub enum ExtensionFileSourceCode {
   // Source code was loaded from memory. It's meant to be used if the
   // embedder is creating snapshots. Files will be loaded from memory
   // during the build time and they will only be present in the V8 snapshot.
-  LoadedFromMemoryDuringSnapshot(&'static str),
+  LoadedFromMemoryDuringSnapshot(FastStaticString),
 
   /// Source code may be computed at runtime.
   Computed(Arc<str>),
@@ -58,7 +60,7 @@ pub struct ExtensionFileSource {
 }
 
 impl ExtensionFileSource {
-  pub const fn new(specifier: &'static str, code: &'static str) -> Self {
+  pub const fn new(specifier: &'static str, code: FastStaticString) -> Self {
     #[allow(deprecated)]
     Self {
       specifier,
@@ -93,7 +95,7 @@ impl ExtensionFileSource {
 
   pub const fn loaded_from_memory_during_snapshot(
     specifier: &'static str,
-    code: &'static str,
+    code: FastStaticString,
   ) -> Self {
     #[allow(deprecated)]
     Self {
@@ -119,7 +121,7 @@ impl ExtensionFileSource {
           self.specifier,
           Self::find_non_ascii(code)
         );
-        Ok(ModuleCodeString::from_static(code))
+        Ok(IntoModuleCodeString::into_module_code(*code))
       }
       ExtensionFileSourceCode::LoadedFromFsDuringSnapshot(path) => {
         let msg = || format!("Failed to read \"{}\"", path);
@@ -139,7 +141,7 @@ impl ExtensionFileSource {
           self.specifier,
           Self::find_non_ascii(code)
         );
-        Ok(ModuleCodeString::Arc(code.clone()))
+        Ok(ModuleCodeString::from(code.clone()))
       }
     }
   }
@@ -163,9 +165,10 @@ pub type GlobalObjectMiddlewareFn =
 
 extern "C" fn noop() {}
 
-#[derive(Copy, Clone)]
+#[derive(Clone, Copy)]
 pub struct OpDecl {
   pub name: &'static str,
+  pub(crate) name_fast: FastStaticString,
   pub is_async: bool,
   pub is_reentrant: bool,
   pub arg_count: u8,
@@ -184,7 +187,7 @@ impl OpDecl {
   #[doc(hidden)]
   #[allow(clippy::too_many_arguments)]
   pub const fn new_internal_op2(
-    name: &'static str,
+    name: (&'static str, FastStaticString),
     is_async: bool,
     is_reentrant: bool,
     arg_count: u8,
@@ -195,7 +198,8 @@ impl OpDecl {
   ) -> Self {
     #[allow(deprecated)]
     Self {
-      name,
+      name: name.0,
+      name_fast: name.1,
       is_async,
       is_reentrant,
       arg_count,
@@ -899,7 +903,7 @@ macro_rules! __extension_include_js_files_inner {
 
   // loaded, source
   (@item mode=loaded, specifier=$specifier:expr, source=$source:expr) => {
-    $crate::ExtensionFileSource::loaded_from_memory_during_snapshot($specifier, $source)
+    $crate::ExtensionFileSource::loaded_from_memory_during_snapshot($specifier, $crate::ascii_str!($source))
   };
   // loaded, file
   (@item mode=loaded, dir=$dir:expr, specifier=$specifier:expr, file=$file:literal) => {
@@ -907,11 +911,11 @@ macro_rules! __extension_include_js_files_inner {
   };
   // included, source
   (@item mode=included, specifier=$specifier:expr, source=$source:expr) => {
-    $crate::ExtensionFileSource::new($specifier, $source)
+    $crate::ExtensionFileSource::new($specifier, $crate::ascii_str!($source))
   };
   // included, file
   (@item mode=included, dir=$dir:expr, specifier=$specifier:expr, file=$file:literal) => {
-    $crate::ExtensionFileSource::new($specifier, include_str!(concat!($dir, "/", $file)))
+    $crate::ExtensionFileSource::new($specifier, $crate::ascii_str_include!(concat!($dir, "/", $file)))
   };
 }
 
diff --git a/core/fast_string.rs b/core/fast_string.rs
index aea5807..6e685fa 100644
--- a/core/fast_string.rs
+++ b/core/fast_string.rs
@@ -4,31 +4,159 @@ use serde::Deserializer;
 use serde::Serializer;
 use std::borrow::Borrow;
 use std::fmt::Debug;
+use std::fmt::Display;
+use std::fmt::Formatter;
 use std::hash::Hash;
+use std::ops::Deref;
 use std::sync::Arc;
 use url::Url;
 use v8::NewStringType;
 
+static EMPTY_STRING: v8::OneByteConst =
+  v8::String::create_external_onebyte_const("".as_bytes());
+
+/// A static string that is compile-time checked to be ASCII and is stored in the
+/// most efficient possible way to create V8 strings.
+#[derive(Clone, Copy)]
+#[repr(transparent)]
+pub struct FastStaticString {
+  s: &'static v8::OneByteConst,
+}
+
+impl FastStaticString {
+  pub const fn new(s: &'static v8::OneByteConst) -> Self {
+    FastStaticString { s }
+  }
+
+  pub const fn as_str(&self) -> &'static str {
+    // SAFETY: We know this was constructed from a valid one-byte string.
+    unsafe { std::str::from_utf8_unchecked(self.as_bytes()) }
+  }
+
+  pub const fn as_bytes(&self) -> &'static [u8] {
+    unsafe {
+      let ptrs: [usize; 3] = std::ptr::read(self.s as *const _ as *const _);
+      std::slice::from_raw_parts(ptrs[1] as *const u8, ptrs[2])
+    }
+  }
+
+  // TODO(mmastrac): This is a workaround for a compiler error for large scripts that take too
+  // long to call is_ascii on.
+  #[doc(hidden)]
+  pub const fn create_external_onebyte_const(
+    s: &'static [u8],
+  ) -> v8::OneByteConst {
+    #[repr(C)]
+    struct OneByteConst {
+      _vtable: *const (),
+      cached_data: *const char,
+      length: usize,
+    }
+    // SAFETY: Workaround compiler error in create_external_onebyte_const for long ascii strings
+    unsafe {
+      assert!(s.is_ascii());
+      let c = v8::String::create_external_onebyte_const(&[]);
+      let mut ptrs: OneByteConst = std::mem::transmute(c);
+      ptrs.cached_data = std::mem::transmute(s.as_ptr());
+      ptrs.length = s.len();
+      std::mem::transmute(ptrs)
+    }
+  }
+
+  pub fn v8_string<'s>(
+    &self,
+    scope: &mut v8::HandleScope<'s>,
+  ) -> v8::Local<'s, v8::String> {
+    FastString::from(*self).v8_string(scope)
+  }
+}
+
+impl From<&'static v8::OneByteConst> for FastStaticString {
+  fn from(s: &'static v8::OneByteConst) -> Self {
+    Self::new(s)
+  }
+}
+
+impl Hash for FastStaticString {
+  fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+    self.as_str().hash(state)
+  }
+}
+
+impl AsRef<str> for FastStaticString {
+  fn as_ref(&self) -> &str {
+    self.as_str()
+  }
+}
+
+impl Deref for FastStaticString {
+  type Target = str;
+  fn deref(&self) -> &Self::Target {
+    self.as_str()
+  }
+}
+
+impl Borrow<str> for FastStaticString {
+  fn borrow(&self) -> &str {
+    self.as_str()
+  }
+}
+
+impl Debug for FastStaticString {
+  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+    Debug::fmt(self.as_str(), f)
+  }
+}
+
+impl Default for FastStaticString {
+  fn default() -> Self {
+    FastStaticString { s: &EMPTY_STRING }
+  }
+}
+
+impl PartialEq for FastStaticString {
+  fn eq(&self, other: &Self) -> bool {
+    self.as_bytes() == other.as_bytes()
+  }
+}
+
+impl Eq for FastStaticString {}
+
+impl Display for FastStaticString {
+  fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+    f.write_str(self.as_str())
+  }
+}
+
 /// Module names and code can be sourced from strings or bytes that are either owned or borrowed. This enumeration allows us
 /// to perform a minimal amount of cloning and format-shifting of the underlying data.
 ///
-/// Note that any [`FastString`] created from a `'static` byte array or string must contain ASCII characters.
+/// Note that any [`FastString`] created using [`ascii_str!`] must contain only ASCII characters. Other [`FastString`] types
+/// may be UTF-8, though this will incur a small performance penalty. It is recommended that large, static strings always
+/// use [`ascii_str!`].
 ///
 /// Examples of ways to construct a [`FastString`]:
 ///
 /// ```rust
 /// # use deno_core::{ascii_str, FastString};
 ///
-/// let code: FastString = ascii_str!("a string");
+/// let code: FastString = ascii_str!("a string").into();
 /// let code: FastString = format!("a string").into();
 /// ```
-pub enum FastString {
+pub struct FastString {
+  inner: FastStringInner,
+}
+
+enum FastStringInner {
   /// Created from static data.
   Static(&'static str),
 
-  /// Created from static data, known to contain only ASCII chars.
+  /// Created from static ascii, known to contain only ASCII chars.
   StaticAscii(&'static str),
 
+  /// Created from static data, known to contain only ASCII chars.
+  StaticConst(FastStaticString),
+
   /// An owned chunk of data. Note that we use `Box` rather than `Vec` to avoid the
   /// storage overhead.
   Owned(Box<str>),
@@ -38,87 +166,82 @@ pub enum FastString {
 }
 
 impl FastString {
-  /// Compile-time function to determine if a string is ASCII. Note that UTF-8 chars
-  /// longer than one byte have the high-bit set and thus, are not ASCII.
-  const fn is_ascii(s: &'static [u8]) -> bool {
-    let mut i = 0;
-    while i < s.len() {
-      if !s[i].is_ascii() {
-        return false;
-      }
-      i += 1;
-    }
-    true
-  }
-
   /// Create a [`FastString`] from a static string. The string may contain non-ASCII characters, and if
   /// so, will take the slower path when used in v8.
   pub const fn from_static(s: &'static str) -> Self {
-    if Self::is_ascii(s.as_bytes()) {
-      Self::StaticAscii(s)
+    if s.is_ascii() {
+      Self {
+        inner: FastStringInner::StaticAscii(s),
+      }
     } else {
-      Self::Static(s)
+      Self {
+        inner: FastStringInner::Static(s),
+      }
     }
   }
 
-  /// Create a [`FastString`] from a static string. If the string contains non-ASCII characters, the compiler
-  /// will abort.
-  pub const fn ensure_static_ascii(s: &'static str) -> Self {
-    if Self::is_ascii(s.as_bytes()) {
-      Self::StaticAscii(s)
-    } else {
-      panic!("This string contained non-ASCII characters and cannot be created with ensure_static_ascii")
+  /// Returns a static string from this `FastString`, if available.
+  pub fn as_static_str(&self) -> Option<&'static str> {
+    match self.inner {
+      FastStringInner::Static(s) => Some(s),
+      FastStringInner::StaticAscii(s) => Some(s),
+      FastStringInner::StaticConst(s) => Some(s.as_str()),
+      _ => None,
     }
   }
 
   /// Creates a cheap copy of this [`FastString`], potentially transmuting it to a faster form. Note that this
   /// is not a clone operation as it consumes the old [`FastString`].
   pub fn into_cheap_copy(self) -> (Self, Self) {
-    match self {
-      Self::Static(s) => (Self::Static(s), Self::Static(s)),
-      Self::StaticAscii(s) => (Self::StaticAscii(s), Self::StaticAscii(s)),
-      Self::Arc(s) => (Self::Arc(s.clone()), Self::Arc(s)),
-      Self::Owned(s) => {
+    match self.inner {
+      FastStringInner::Owned(s) => {
         let s: Arc<str> = s.into();
-        (Self::Arc(s.clone()), Self::Arc(s))
+        (
+          Self {
+            inner: FastStringInner::Arc(s.clone()),
+          },
+          Self {
+            inner: FastStringInner::Arc(s),
+          },
+        )
       }
+      _ => (self.try_clone().unwrap(), self),
     }
   }
 
   /// If this [`FastString`] is cheaply cloneable, returns a clone.
   pub fn try_clone(&self) -> Option<Self> {
-    match self {
-      Self::Static(s) => Some(Self::Static(s)),
-      Self::StaticAscii(s) => Some(Self::StaticAscii(s)),
-      Self::Arc(s) => Some(Self::Arc(s.clone())),
-      Self::Owned(_s) => None,
-    }
-  }
-
-  pub const fn try_static_ascii(&self) -> Option<&'static [u8]> {
-    match self {
-      Self::StaticAscii(s) => Some(s.as_bytes()),
-      _ => None,
+    match &self.inner {
+      FastStringInner::Static(s) => Some(Self {
+        inner: FastStringInner::Static(s),
+      }),
+      FastStringInner::StaticAscii(s) => Some(Self {
+        inner: FastStringInner::StaticAscii(s),
+      }),
+      FastStringInner::StaticConst(s) => Some(Self {
+        inner: FastStringInner::StaticConst(*s),
+      }),
+      FastStringInner::Arc(s) => Some(Self {
+        inner: FastStringInner::Arc(s.clone()),
+      }),
+      FastStringInner::Owned(_s) => None,
     }
   }
 
+  #[inline(always)]
   pub fn as_bytes(&self) -> &[u8] {
-    // TODO(mmastrac): This can be const eventually (waiting for Arc const deref)
-    match self {
-      Self::Arc(s) => s.as_bytes(),
-      Self::Owned(s) => s.as_bytes(),
-      Self::Static(s) => s.as_bytes(),
-      Self::StaticAscii(s) => s.as_bytes(),
-    }
+    self.as_str().as_bytes()
   }
 
+  #[inline(always)]
   pub fn as_str(&self) -> &str {
-    // TODO(mmastrac): This can be const eventually (waiting for Arc const deref)
-    match self {
-      Self::Arc(s) => s,
-      Self::Owned(s) => s,
-      Self::Static(s) => s,
-      Self::StaticAscii(s) => s,
+    match &self.inner {
+      // TODO(mmastrac): When we get a const deref, as_str can be const
+      FastStringInner::Arc(s) => s,
+      FastStringInner::Owned(s) => s,
+      FastStringInner::Static(s) => s,
+      FastStringInner::StaticAscii(s) => s,
+      FastStringInner::StaticConst(s) => s.as_str(),
     }
   }
 
@@ -128,9 +251,14 @@ impl FastString {
     &self,
     scope: &mut v8::HandleScope<'a>,
   ) -> v8::Local<'a, v8::String> {
-    match self.try_static_ascii() {
-      Some(s) => v8::String::new_external_onebyte_static(scope, s).unwrap(),
-      None => {
+    match self.inner {
+      FastStringInner::StaticAscii(s) => {
+        v8::String::new_external_onebyte_static(scope, s.as_bytes()).unwrap()
+      }
+      FastStringInner::StaticConst(s) => {
+        v8::String::new_from_onebyte_const(scope, s.s).unwrap()
+      }
+      _ => {
         v8::String::new_from_utf8(scope, self.as_bytes(), NewStringType::Normal)
           .unwrap()
       }
@@ -139,12 +267,24 @@ impl FastString {
 
   /// Truncates a [`FastString`] value, possibly re-allocating or memcpy'ing. May be slow.
   pub fn truncate(&mut self, index: usize) {
-    match self {
-      Self::Static(b) => *self = Self::Static(&b[..index]),
-      Self::StaticAscii(b) => *self = Self::StaticAscii(&b[..index]),
-      Self::Owned(b) => *self = Self::Owned(b[..index].to_owned().into()),
+    match &mut self.inner {
+      FastStringInner::Static(b) => {
+        self.inner = FastStringInner::Static(&b[..index])
+      }
+      FastStringInner::StaticAscii(b) => {
+        self.inner = FastStringInner::StaticAscii(&b[..index])
+      }
+      FastStringInner::StaticConst(b) => {
+        self.inner = FastStringInner::StaticAscii(&b.as_str()[..index])
+      }
+      // TODO(mmastrac): this could be more efficient
+      FastStringInner::Owned(b) => {
+        self.inner = FastStringInner::Owned(b[..index].to_owned().into())
+      }
       // We can't do much if we have an Arc<str>, so we'll just take ownership of the truncated version
-      Self::Arc(s) => *self = s[..index].to_owned().into(),
+      FastStringInner::Arc(s) => {
+        self.inner = FastStringInner::Arc(s[..index].to_owned().into())
+      }
     }
   }
 }
@@ -161,6 +301,13 @@ impl AsRef<str> for FastString {
   }
 }
 
+impl Deref for FastString {
+  type Target = str;
+  fn deref(&self) -> &Self::Target {
+    self.as_str()
+  }
+}
+
 impl Borrow<str> for FastString {
   fn borrow(&self) -> &str {
     self.as_str()
@@ -175,7 +322,9 @@ impl Debug for FastString {
 
 impl Default for FastString {
   fn default() -> Self {
-    Self::StaticAscii("")
+    Self {
+      inner: FastStringInner::StaticConst(FastStaticString::default()),
+    }
   }
 }
 
@@ -187,11 +336,19 @@ impl PartialEq for FastString {
 
 impl Eq for FastString {}
 
-/// [`FastString`] can be made cheaply from `&'static str` as we know it's owned and don't need to do an
+impl Display for FastString {
+  fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+    f.write_str(self.as_str())
+  }
+}
+
+/// [`FastString`] can be made cheaply from [`Url`] as we know it's owned and don't need to do an
 /// ASCII check.
-impl From<&'static str> for FastString {
-  fn from(value: &'static str) -> Self {
-    FastString::from_static(value)
+impl From<FastStaticString> for FastString {
+  fn from(value: FastStaticString) -> Self {
+    Self {
+      inner: FastStringInner::StaticConst(value),
+    }
   }
 }
 
@@ -208,7 +365,9 @@ impl From<Url> for FastString {
 /// ASCII check.
 impl From<String> for FastString {
   fn from(value: String) -> Self {
-    FastString::Owned(value.into_boxed_str())
+    Self {
+      inner: FastStringInner::Owned(value.into_boxed_str()),
+    }
   }
 }
 
@@ -216,7 +375,9 @@ impl From<String> for FastString {
 /// ASCII check.
 impl From<Arc<str>> for FastString {
   fn from(value: Arc<str>) -> Self {
-    FastString::Arc(value)
+    Self {
+      inner: FastStringInner::Arc(value),
+    }
   }
 }
 
@@ -243,39 +404,77 @@ impl<'de> serde::Deserialize<'de> for FastString {
 
 /// Include a fast string in the binary. This string is asserted at compile-time to be 7-bit ASCII for optimal
 /// v8 performance.
+///
+/// This macro creates a [`FastStaticString`] that may be converted to a [`FastString`] via [`Into::into`].
 #[macro_export]
-macro_rules! include_ascii_string {
-  ($file:literal) => {
-    $crate::FastString::ensure_static_ascii(::std::include_str!($file))
-  };
+macro_rules! ascii_str_include {
+  ($file:expr) => {{
+    const STR: $crate::v8::OneByteConst =
+      $crate::FastStaticString::create_external_onebyte_const(
+        ::std::include_str!($file).as_bytes(),
+      );
+    let s: &'static $crate::v8::OneByteConst = &STR;
+    $crate::FastStaticString::new(s)
+  }};
 }
 
 /// Include a fast string in the binary from a string literal. This string is asserted at compile-time to be
 /// 7-bit ASCII for optimal v8 performance.
+///
+/// This macro creates a [`FastStaticString`] that may be converted to a [`FastString`] via [`Into::into`].
 #[macro_export]
 macro_rules! ascii_str {
-  ($str:expr) => {
-    $crate::FastString::ensure_static_ascii($str)
-  };
+  ($str:literal) => {{
+    const C: $crate::v8::OneByteConst =
+      $crate::FastStaticString::create_external_onebyte_const($str.as_bytes());
+    unsafe { std::mem::transmute::<_, $crate::FastStaticString>(&C) }
+  }};
 }
 
+/// Used to generate the fast, const versions of op names. Internal only.
 #[macro_export]
+#[doc(hidden)]
 macro_rules! __op_name_fast {
-  ($op:ident) => {
-    stringify!($op)
-  };
+  ($op:ident) => {{
+    const LITERAL: &'static [u8] = stringify!($op).as_bytes();
+    const STR: $crate::v8::OneByteConst =
+      $crate::FastStaticString::create_external_onebyte_const(LITERAL);
+    let s: &'static $crate::v8::OneByteConst = &STR;
+    (stringify!($op), $crate::FastStaticString::new(s))
+  }};
 }
 
 #[cfg(test)]
 mod tests {
   use super::*;
 
+  // TODO(mmastrac): we need to upstream as_str() on OneByteConst to rusty_v8 to get
+  // rid of the hacks that break miri.
+  #[cfg(not(miri))]
+  #[test]
+  fn string_eq() {
+    let s: FastString = ascii_str!("Testing").into();
+    assert_eq!("Testing", s.as_str());
+    let s2 = FastString::from_static("Testing");
+    assert_eq!(s, s2);
+    let (s1, s2) = s.into_cheap_copy();
+    assert_eq!("Testing", s1.as_str());
+    assert_eq!("Testing", s2.as_str());
+
+    let s = FastString::from("Testing".to_owned());
+    assert_eq!("Testing", s.as_str());
+    let (s1, s2) = s.into_cheap_copy();
+    assert_eq!("Testing", s1.as_str());
+    assert_eq!("Testing", s2.as_str());
+  }
+
+  #[cfg(not(miri))]
   #[test]
   fn truncate() {
     let mut s = "123456".to_owned();
     s.truncate(3);
 
-    let mut code: FastString = FastString::from_static("123456");
+    let mut code: FastString = ascii_str!("123456").into();
     code.truncate(3);
     assert_eq!(s, code.as_ref());
 
@@ -288,4 +487,19 @@ mod tests {
     code.truncate(3);
     assert_eq!(s, code.as_ref());
   }
+
+  #[test]
+  fn test_large_include() {
+    // This test would require an excessively large file in the repo, so we just run this manually
+    // ascii_str_include!("runtime/tests/large_string.txt");
+    // ascii_str_include!(concat!("runtime", "/tests/", "large_string.txt"));
+  }
+
+  /// Ensure that all of our macros compile properly in a static context.
+  #[test]
+  fn test_const() {
+    const _: (&str, FastStaticString) = __op_name_fast!(op_name);
+    const _: FastStaticString = ascii_str!("hmm");
+    const _: FastStaticString = ascii_str_include!("Cargo.toml");
+  }
 }
diff --git a/core/lib.rs b/core/lib.rs
index b4753b3..43a4931 100644
--- a/core/lib.rs
+++ b/core/lib.rs
@@ -72,6 +72,7 @@ pub use crate::extensions::OpMiddlewareFn;
 pub use crate::external::ExternalDefinition;
 pub use crate::external::ExternalPointer;
 pub use crate::external::Externalizable;
+pub use crate::fast_string::FastStaticString;
 pub use crate::fast_string::FastString;
 pub use crate::feature_checker::FeatureChecker;
 pub use crate::flags::v8_set_flags;
diff --git a/core/main.rs b/core/main.rs
index 718bebc..a2b9cc8 100644
--- a/core/main.rs
+++ b/core/main.rs
@@ -119,7 +119,7 @@ fn main() -> Result<(), Error> {
   )?;
 
   let future = async move {
-    let mod_id = js_runtime.load_main_module(&main_module, None).await?;
+    let mod_id = js_runtime.load_main_es_module(&main_module).await?;
     let result = js_runtime.mod_evaluate(mod_id);
     js_runtime.run_event_loop(Default::default()).await?;
     result.await
diff --git a/core/modules/loaders.rs b/core/modules/loaders.rs
index 228d03b..0be6ee1 100644
--- a/core/modules/loaders.rs
+++ b/core/modules/loaders.rs
@@ -2,6 +2,7 @@
 use crate::error::generic_error;
 use crate::extensions::ExtensionFileSource;
 use crate::module_specifier::ModuleSpecifier;
+use crate::modules::IntoModuleCodeString;
 use crate::modules::ModuleCodeString;
 use crate::modules::ModuleSource;
 use crate::modules::ModuleSourceFuture;
@@ -338,19 +339,22 @@ pub struct StaticModuleLoader {
 impl StaticModuleLoader {
   /// Create a new [`StaticModuleLoader`] from an `Iterator` of specifiers and code.
   pub fn new(
-    from: impl IntoIterator<Item = (ModuleSpecifier, ModuleCodeString)>,
+    from: impl IntoIterator<Item = (ModuleSpecifier, impl IntoModuleCodeString)>,
   ) -> Self {
     Self {
       map: HashMap::from_iter(
-        from
-          .into_iter()
-          .map(|(url, code)| (url, code.into_cheap_copy().0)),
+        from.into_iter().map(|(url, code)| {
+          (url, code.into_module_code().into_cheap_copy().0)
+        }),
       ),
     }
   }
 
   /// Create a new [`StaticModuleLoader`] from a single code item.
-  pub fn with(specifier: ModuleSpecifier, code: ModuleCodeString) -> Self {
+  pub fn with(
+    specifier: ModuleSpecifier,
+    code: impl IntoModuleCodeString,
+  ) -> Self {
     Self::new([(specifier, code)])
   }
 }
diff --git a/core/modules/map.rs b/core/modules/map.rs
index e9cf1fc..7bd9ef1 100644
--- a/core/modules/map.rs
+++ b/core/modules/map.rs
@@ -1,5 +1,8 @@
 // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
 use super::module_map_data::ModuleMapSnapshotData;
+use super::IntoModuleCodeString;
+use super::IntoModuleName;
+use crate::ascii_str;
 use crate::error::exception_to_err_result;
 use crate::error::generic_error;
 use crate::error::throw_type_error;
@@ -24,7 +27,7 @@ use crate::runtime::JsRealm;
 use crate::runtime::SnapshotLoadDataStore;
 use crate::runtime::SnapshotStoreDataStore;
 use crate::ExtensionFileSource;
-use crate::FastString;
+use crate::FastStaticString;
 use crate::JsRuntime;
 use crate::ModuleLoadResponse;
 use crate::ModuleSource;
@@ -195,7 +198,7 @@ impl ModuleMap {
   /// that had been redirected.
   pub(crate) fn get_id(
     &self,
-    name: impl AsRef<str>,
+    name: &str,
     requested_module_type: impl AsRef<RequestedModuleType>,
   ) -> Option<ModuleId> {
     self.data.borrow().get_id(name, requested_module_type)
@@ -357,7 +360,7 @@ impl ModuleMap {
           // synthetic module.
           CustomModuleEvaluationKind::Synthetic(value_global) => {
             let value = v8::Local::new(scope, value_global);
-            let exports = vec![(FastString::StaticAscii("default"), value)];
+            let exports = vec![(ascii_str!("default"), value)];
             self.new_synthetic_module(
               scope,
               module_url_found,
@@ -375,7 +378,7 @@ impl ModuleMap {
           ) => {
             let (url1, url2) = module_url_found.into_cheap_copy();
             let value = v8::Local::new(scope, synthetic_value);
-            let exports = vec![(FastString::StaticAscii("default"), value)];
+            let exports = vec![(ascii_str!("default"), value)];
             let _synthetic_mod_id = self.new_synthetic_module(
               scope,
               url1,
@@ -403,21 +406,16 @@ impl ModuleMap {
   pub fn new_synthetic_module(
     &self,
     scope: &mut v8::HandleScope,
-    name: ModuleName,
+    name: impl IntoModuleName,
     module_type: ModuleType,
-    exports: Vec<(FastString, v8::Local<v8::Value>)>,
+    exports: Vec<(FastStaticString, v8::Local<v8::Value>)>,
   ) -> Result<ModuleId, ModuleError> {
+    let name = name.into_module_name();
     let name_str = name.v8_string(scope);
 
     let export_names = exports
       .iter()
-      .map(|(name, _)| {
-        if let Some(buffer) = name.try_static_ascii() {
-          v8::String::new_external_onebyte_static(scope, buffer).unwrap()
-        } else {
-          v8::String::new(scope, name.as_str()).unwrap()
-        }
-      })
+      .map(|(name, _)| name.v8_string(scope))
       .collect::<Vec<_>>();
     let module = v8::Module::create_synthetic_module(
       scope,
@@ -464,16 +462,17 @@ impl ModuleMap {
     &self,
     scope: &mut v8::HandleScope,
     main: bool,
-    name: ModuleName,
-    source: ModuleCodeString,
+    name: impl IntoModuleName,
+    source: impl IntoModuleCodeString,
     is_dynamic_import: bool,
   ) -> Result<ModuleId, ModuleError> {
+    let name = name.into_module_name();
     self.new_module_from_js_source(
       scope,
       main,
       ModuleType::JavaScript,
-      name,
-      source,
+      name.into_module_name(),
+      source.into_module_code(),
       is_dynamic_import,
     )
   }
@@ -605,9 +604,11 @@ impl ModuleMap {
   pub(crate) fn new_json_module(
     &self,
     scope: &mut v8::HandleScope,
-    name: ModuleName,
-    code: ModuleCodeString,
+    name: impl IntoModuleName,
+    code: impl IntoModuleCodeString,
   ) -> Result<ModuleId, ModuleError> {
+    let name = name.into_module_name();
+    let code = code.into_module_code();
     let source_str = v8::String::new_from_utf8(
       scope,
       strip_bom(code.as_bytes()),
@@ -625,7 +626,7 @@ impl ModuleMap {
         return Err(ModuleError::Exception(exception));
       }
     };
-    let exports = vec![(FastString::StaticAscii("default"), parsed_json)];
+    let exports = vec![(ascii_str!("default"), parsed_json)];
     self.new_synthetic_module(tc_scope, name, ModuleType::Json, exports)
   }
 
@@ -816,7 +817,7 @@ impl ModuleMap {
         if self
           .data
           .borrow()
-          .is_registered(module_specifier, requested_module_type)
+          .is_registered(module_specifier.as_str(), requested_module_type)
         {
           async move { (load.id, Ok(load)) }.boxed_local()
         } else {
@@ -1465,7 +1466,7 @@ impl ModuleMap {
   ///
   /// It is caller's responsibility to ensure that not duplicate specifiers are
   /// passed to this method.
-  pub(crate) fn lazy_load_es_module_from_code(
+  pub(crate) fn lazy_load_es_module_with_code(
     &self,
     scope: &mut v8::HandleScope,
     module_specifier: &str,
@@ -1473,7 +1474,7 @@ impl ModuleMap {
   ) -> Result<v8::Global<v8::Value>, Error> {
     let specifier = ModuleSpecifier::parse(module_specifier)?;
     let mod_id = self
-      .new_es_module(scope, false, specifier.into(), source_code, false)
+      .new_es_module(scope, false, specifier, source_code, false)
       .map_err(|e| e.into_any_error(scope, false, true))?;
 
     self.instantiate_module(scope, mod_id).map_err(|e| {
@@ -1556,7 +1557,7 @@ impl ModuleMap {
       ModuleLoadResponse::Async(fut) => futures::executor::block_on(fut),
     }?;
 
-    self.lazy_load_es_module_from_code(
+    self.lazy_load_es_module_with_code(
       scope,
       module_specifier,
       ModuleSource::get_string_source(specifier.as_str(), source.code)?,
diff --git a/core/modules/mod.rs b/core/modules/mod.rs
index 03e0afa..be6163d 100644
--- a/core/modules/mod.rs
+++ b/core/modules/mod.rs
@@ -3,6 +3,7 @@ use crate::error::exception_to_err_result;
 use crate::error::AnyError;
 use crate::fast_string::FastString;
 use crate::module_specifier::ModuleSpecifier;
+use crate::FastStaticString;
 use anyhow::bail;
 use anyhow::Context;
 use anyhow::Error;
@@ -12,6 +13,7 @@ use std::borrow::Cow;
 use std::collections::HashMap;
 use std::future::Future;
 use std::sync::Arc;
+use url::Url;
 
 mod loaders;
 mod map;
@@ -48,6 +50,76 @@ pub enum ModuleSourceCode {
 pub type ModuleCodeString = FastString;
 pub type ModuleName = FastString;
 
+/// Converts various string-like things into `ModuleName`.
+pub trait IntoModuleName {
+  fn into_module_name(self) -> ModuleName;
+}
+
+impl IntoModuleName for ModuleName {
+  fn into_module_name(self) -> ModuleName {
+    self
+  }
+}
+
+impl IntoModuleName for &'static str {
+  fn into_module_name(self) -> ModuleName {
+    ModuleName::from_static(self)
+  }
+}
+
+impl IntoModuleName for String {
+  fn into_module_name(self) -> ModuleName {
+    ModuleName::from(self)
+  }
+}
+
+impl IntoModuleName for Url {
+  fn into_module_name(self) -> ModuleName {
+    ModuleName::from(self)
+  }
+}
+
+impl IntoModuleName for FastStaticString {
+  fn into_module_name(self) -> ModuleName {
+    ModuleName::from(self)
+  }
+}
+
+/// Converts various string-like things into `ModuleCodeString`.
+pub trait IntoModuleCodeString {
+  fn into_module_code(self) -> ModuleCodeString;
+}
+
+impl IntoModuleCodeString for ModuleCodeString {
+  fn into_module_code(self) -> ModuleCodeString {
+    self
+  }
+}
+
+impl IntoModuleCodeString for &'static str {
+  fn into_module_code(self) -> ModuleCodeString {
+    ModuleCodeString::from_static(self)
+  }
+}
+
+impl IntoModuleCodeString for String {
+  fn into_module_code(self) -> ModuleCodeString {
+    ModuleCodeString::from(self)
+  }
+}
+
+impl IntoModuleCodeString for FastStaticString {
+  fn into_module_code(self) -> ModuleCodeString {
+    ModuleCodeString::from(self)
+  }
+}
+
+impl IntoModuleCodeString for Arc<str> {
+  fn into_module_code(self) -> ModuleCodeString {
+    ModuleCodeString::from(self)
+  }
+}
+
 #[derive(Debug)]
 pub enum ModuleCodeBytes {
   /// Created from static data.
@@ -327,7 +399,7 @@ impl ModuleSource {
   #[cfg(test)]
   pub fn for_test(code: &'static str, file: impl AsRef<str>) -> Self {
     Self {
-      code: ModuleSourceCode::String(FastString::from_static(code)),
+      code: ModuleSourceCode::String(code.into_module_code()),
       module_type: ModuleType::JavaScript,
       module_url_specified: file.as_ref().to_owned().into(),
       module_url_found: None,
@@ -349,7 +421,7 @@ impl ModuleSource {
       Some(found.into())
     };
     Self {
-      code: ModuleSourceCode::String(FastString::from_static(code)),
+      code: ModuleSourceCode::String(code.into_module_code()),
       module_type: ModuleType::JavaScript,
       module_url_specified: specified.into(),
       module_url_found: found,
diff --git a/core/modules/module_map_data.rs b/core/modules/module_map_data.rs
index 7e06f4b..6e2c0cf 100644
--- a/core/modules/module_map_data.rs
+++ b/core/modules/module_map_data.rs
@@ -57,7 +57,7 @@ impl<T> ModuleNameTypeMap<T> {
   pub fn get<Q>(&self, ty: &RequestedModuleType, name: &Q) -> Option<&T>
   where
     ModuleName: std::borrow::Borrow<Q>,
-    Q: std::cmp::Eq + std::hash::Hash + ?Sized,
+    Q: std::cmp::Eq + std::hash::Hash + std::fmt::Debug + ?Sized,
   {
     let index = self.map_index(ty)?;
     let map = self.submaps.get(index)?;
@@ -192,12 +192,12 @@ impl ModuleMapData {
   /// that had been redirected.
   pub fn get_id(
     &self,
-    name: impl AsRef<str>,
+    name: &str,
     requested_module_type: impl AsRef<RequestedModuleType>,
   ) -> Option<ModuleId> {
     let map = &self.by_name;
     let first_symbolic_module =
-      map.get(requested_module_type.as_ref(), name.as_ref())?;
+      map.get(requested_module_type.as_ref(), name)?;
     let mut mod_name = match first_symbolic_module {
       SymbolicModule::Mod(mod_id) => return Some(*mod_id),
       SymbolicModule::Alias(target) => target,
@@ -217,11 +217,11 @@ impl ModuleMapData {
 
   pub fn is_registered(
     &self,
-    specifier: impl AsRef<str>,
+    specifier: &str,
     requested_module_type: impl AsRef<RequestedModuleType>,
   ) -> bool {
     self
-      .get_id(specifier.as_ref(), requested_module_type.as_ref())
+      .get_id(specifier, requested_module_type.as_ref())
       .is_some()
   }
 
@@ -365,3 +365,28 @@ impl ModuleMapData {
     }
   }
 }
+
+#[cfg(test)]
+mod tests {
+  use super::*;
+  use crate::ascii_str;
+  use url::Url;
+
+  #[cfg(not(miri))]
+  #[test]
+  fn module_name_map_test() {
+    let mut data: ModuleNameTypeMap<usize> = ModuleNameTypeMap::default();
+    data.insert(
+      &RequestedModuleType::Json,
+      ascii_str!("http://example.com/").into(),
+      1,
+    );
+    assert_eq!(
+      Some(&1),
+      data.get(
+        &RequestedModuleType::Json,
+        Url::parse("http://example.com/").unwrap().as_str()
+      )
+    );
+  }
+}
diff --git a/core/modules/recursive_load.rs b/core/modules/recursive_load.rs
index 68fa57f..42961cf 100644
--- a/core/modules/recursive_load.rs
+++ b/core/modules/recursive_load.rs
@@ -117,7 +117,7 @@ impl RecursiveModuleLoad {
     // Ignore the error here, let it be hit in `Stream::poll_next()`.
     if let Ok(root_specifier) = load.resolve_root() {
       if let Some(module_id) =
-        module_map_rc.get_id(root_specifier, requested_module_type)
+        module_map_rc.get_id(root_specifier.as_str(), requested_module_type)
       {
         load.root_module_id = Some(module_id);
       }
diff --git a/core/runtime/bindings.rs b/core/runtime/bindings.rs
index 841d676..30497bb 100644
--- a/core/runtime/bindings.rs
+++ b/core/runtime/bindings.rs
@@ -21,7 +21,7 @@ use crate::modules::ModuleMap;
 use crate::ops::OpCtx;
 use crate::runtime::InitMode;
 use crate::runtime::JsRealm;
-use crate::FastString;
+use crate::FastStaticString;
 use crate::JsRuntime;
 use crate::ModuleType;
 
@@ -801,7 +801,7 @@ pub fn create_exports_for_ops_virtual_module<'s>(
   op_ctxs: &[OpCtx],
   scope: &mut v8::HandleScope<'s>,
   global: v8::Local<v8::Object>,
-) -> Vec<(FastString, v8::Local<'s, v8::Value>)> {
+) -> Vec<(FastStaticString, v8::Local<'s, v8::Value>)> {
   let mut exports = Vec::with_capacity(op_ctxs.len());
 
   let deno_obj = get(scope, global, &v8_static_strings::DENO, "Deno");
@@ -832,8 +832,7 @@ pub fn create_exports_for_ops_virtual_module<'s>(
         .unwrap();
       op_fn = result.try_into().unwrap()
     }
-
-    exports.push((FastString::StaticAscii(op_ctx.decl.name), op_fn.into()));
+    exports.push((op_ctx.decl.name_fast, op_fn.into()));
   }
 
   exports
diff --git a/core/runtime/jsrealm.rs b/core/runtime/jsrealm.rs
index 7ffb766..e68f472 100644
--- a/core/runtime/jsrealm.rs
+++ b/core/runtime/jsrealm.rs
@@ -5,9 +5,11 @@ use super::exception_state::ExceptionState;
 use super::op_driver::OpDriver;
 use crate::error::exception_to_err_result;
 use crate::module_specifier::ModuleSpecifier;
+use crate::modules::IntoModuleCodeString;
 use crate::modules::ModuleCodeString;
 use crate::modules::ModuleId;
 use crate::modules::ModuleMap;
+use crate::modules::ModuleName;
 use crate::ops::OpCtx;
 use crate::stats::RuntimeActivityTraces;
 use crate::tasks::V8TaskSpawnerFactory;
@@ -265,12 +267,11 @@ impl JsRealm {
     &self,
     isolate: &mut v8::Isolate,
     name: &'static str,
-    source_code: impl Into<ModuleCodeString>,
+    source_code: impl IntoModuleCodeString,
   ) -> Result<v8::Global<v8::Value>, Error> {
-    let source_code = source_code.into();
     let scope = &mut self.0.handle_scope(isolate);
 
-    let source = source_code.v8_string(scope);
+    let source = source_code.into_module_code().v8_string(scope);
     debug_assert!(name.is_ascii());
     let name =
       v8::String::new_external_onebyte_static(scope, name.as_bytes()).unwrap();
@@ -338,7 +339,7 @@ impl JsRealm {
   ///
   /// User must call [`ModuleMap::mod_evaluate`] with returned `ModuleId`
   /// manually after load is finished.
-  pub(crate) async fn load_main_module(
+  pub(crate) async fn load_main_es_module_from_code(
     &self,
     isolate: &mut v8::Isolate,
     specifier: &ModuleSpecifier,
@@ -346,11 +347,10 @@ impl JsRealm {
   ) -> Result<ModuleId, Error> {
     let module_map_rc = self.0.module_map();
     if let Some(code) = code {
-      let specifier = specifier.as_str().to_owned().into();
       let scope = &mut self.handle_scope(isolate);
       // true for main module
       module_map_rc
-        .new_es_module(scope, true, specifier, code, false)
+        .new_es_module(scope, true, specifier.to_owned(), code, false)
         .map_err(|e| e.into_any_error(scope, false, false))?;
     }
 
@@ -384,7 +384,7 @@ impl JsRealm {
   // TODO(bartlomieju): create a separate method to execute code synchronously
   // from a loader? Would simplify JsRuntime code and not require running in
   // a `block_on`.
-  pub(crate) async fn load_side_module(
+  pub(crate) async fn load_side_es_module_from_code(
     &self,
     isolate: &mut v8::Isolate,
     specifier: &ModuleSpecifier,
@@ -392,7 +392,7 @@ impl JsRealm {
   ) -> Result<ModuleId, Error> {
     let module_map_rc = self.0.module_map();
     if let Some(code) = code {
-      let specifier = specifier.as_str().to_owned().into();
+      let specifier = specifier.to_owned();
       let scope = &mut self.handle_scope(isolate);
       // false for side module (not main module)
       module_map_rc
@@ -427,14 +427,18 @@ impl JsRealm {
   ///
   /// It is caller's responsibility to ensure that not duplicate specifiers are
   /// passed to this method.
-  pub(crate) fn lazy_load_es_module_from_code(
+  pub(crate) fn lazy_load_es_module_with_code(
     &self,
     isolate: &mut v8::Isolate,
-    module_specifier: &str,
+    module_specifier: ModuleName,
     code: ModuleCodeString,
   ) -> Result<v8::Global<v8::Value>, Error> {
     let module_map_rc = self.0.module_map();
     let scope = &mut self.handle_scope(isolate);
-    module_map_rc.lazy_load_es_module_from_code(scope, module_specifier, code)
+    module_map_rc.lazy_load_es_module_with_code(
+      scope,
+      module_specifier.as_str(),
+      code,
+    )
   }
 }
diff --git a/core/runtime/jsruntime.rs b/core/runtime/jsruntime.rs
index f1908d9..dbf04ac 100644
--- a/core/runtime/jsruntime.rs
+++ b/core/runtime/jsruntime.rs
@@ -11,6 +11,7 @@ use super::snapshot;
 use super::stats::RuntimeActivityStatsFactory;
 use super::SnapshotStoreDataStore;
 use super::SnapshottedData;
+use crate::ascii_str;
 use crate::error::exception_to_err_result;
 use crate::error::AnyError;
 use crate::error::GetErrorClassFn;
@@ -25,7 +26,8 @@ use crate::modules::default_import_meta_resolve_cb;
 use crate::modules::CustomModuleEvaluationCb;
 use crate::modules::ExtModuleLoader;
 use crate::modules::ImportMetaResolveCallback;
-use crate::modules::ModuleCodeString;
+use crate::modules::IntoModuleCodeString;
+use crate::modules::IntoModuleName;
 use crate::modules::ModuleId;
 use crate::modules::ModuleLoader;
 use crate::modules::ModuleMap;
@@ -42,7 +44,7 @@ use crate::stats::RuntimeActivityType;
 use crate::Extension;
 use crate::ExtensionFileSource;
 use crate::ExtensionFileSourceCode;
-use crate::FastString;
+use crate::FastStaticString;
 use crate::FeatureChecker;
 use crate::NoopModuleLoader;
 use crate::OpMetricsEvent;
@@ -258,7 +260,7 @@ impl Future for RcPromiseFuture {
   }
 }
 
-const VIRTUAL_OPS_MODULE_NAME: &str = "ext:core/ops";
+static VIRTUAL_OPS_MODULE_NAME: FastStaticString = ascii_str!("ext:core/ops");
 
 pub(crate) struct InternalSourceFile {
   pub specifier: &'static str,
@@ -1006,7 +1008,7 @@ impl JsRuntime {
     let mod_id = module_map
       .new_synthetic_module(
         scope,
-        FastString::StaticAscii(VIRTUAL_OPS_MODULE_NAME),
+        VIRTUAL_OPS_MODULE_NAME,
         crate::ModuleType::JavaScript,
         synthetic_module_exports,
       )
@@ -1052,7 +1054,7 @@ impl JsRuntime {
 
     for file_source in &BUILTIN_ES_MODULES {
       mark_as_loaded_from_fs_during_snapshot(files_loaded, &file_source.code);
-      module_map.lazy_load_es_module_from_code(
+      module_map.lazy_load_es_module_with_code(
         scope,
         file_source.specifier,
         file_source.load()?,
@@ -1091,7 +1093,7 @@ impl JsRuntime {
       for file_source in extension.get_esm_sources() {
         mark_as_loaded_from_fs_during_snapshot(files_loaded, &file_source.code);
         realm
-          .load_side_module(
+          .load_side_es_module_from_code(
             self.v8_isolate(),
             &ModuleSpecifier::parse(file_source.specifier)?,
             None,
@@ -1265,10 +1267,9 @@ impl JsRuntime {
     state.op_ctxs.iter().map(|o| o.decl.name).collect()
   }
 
-  /// Executes traditional JavaScript code (traditional = not ES modules).
-  ///
-  /// The execution takes place on the current main realm, so it is possible
-  /// to maintain local JS state and invoke this method multiple times.
+  /// Executes traditional, non-ECMAScript-module JavaScript code, This code executes in
+  /// the global scope by default, and it is possible to maintain local JS state and invoke
+  /// this method multiple times.
   ///
   /// `name` can be a filepath or any other string, but it is required to be 7-bit ASCII, eg.
   ///
@@ -1278,17 +1279,23 @@ impl JsRuntime {
   ///
   /// The same `name` value can be used for multiple executions.
   ///
+  /// The source may be any type that implements the internal [`IntoModuleCodeString`] trait, but
+  /// it is highly recommended that embedders use the [`ascii_str!`] to generate the fastest version
+  /// of strings for v8 to handle. If the strings are not static, you may also pass a [`String`]
+  /// generated by the [`format!`] macro.
+  ///
   /// `Error` can usually be downcast to `JsError`.
   pub fn execute_script(
     &mut self,
     name: &'static str,
-    source_code: impl Into<ModuleCodeString>,
+    source_code: impl IntoModuleCodeString,
   ) -> Result<v8::Global<v8::Value>, Error> {
     let isolate = &mut self.inner.v8_isolate;
-    self
-      .inner
-      .main_realm
-      .execute_script(isolate, name, source_code)
+    self.inner.main_realm.execute_script(
+      isolate,
+      name,
+      source_code.into_module_code(),
+    )
   }
 
   /// Call a function and return a future resolving with the return value of the
@@ -2073,38 +2080,97 @@ impl JsRuntime {
   /// The module will be marked as "main", and because of that
   /// "import.meta.main" will return true when checked inside that module.
   ///
+  /// The source may be any type that implements the internal [`IntoModuleCodeString`] trait, but
+  /// it is highly recommended that embedders use the [`ascii_str!`] to generate the fastest version
+  /// of strings for v8 to handle. If the strings are not static, you may also pass a [`String`]
+  /// generated by the [`format!`] macro.
+  ///
+  /// User must call [`JsRuntime::mod_evaluate`] with returned `ModuleId`
+  /// manually after load is finished.
+  pub async fn load_main_es_module_from_code(
+    &mut self,
+    specifier: &ModuleSpecifier,
+    code: impl IntoModuleCodeString,
+  ) -> Result<ModuleId, Error> {
+    let isolate = &mut self.inner.v8_isolate;
+    self
+      .inner
+      .main_realm
+      .load_main_es_module_from_code(
+        isolate,
+        specifier,
+        Some(code.into_module_code()),
+      )
+      .await
+  }
+
+  /// Asynchronously load specified module and all of its dependencies, retrieving
+  /// the module from the supplied [`ModuleLoader`].
+  ///
+  /// The module will be marked as "main", and because of that
+  /// "import.meta.main" will return true when checked inside that module.
+  ///
+  /// User must call [`JsRuntime::mod_evaluate`] with returned `ModuleId`
+  /// manually after load is finished.
+  pub async fn load_main_es_module(
+    &mut self,
+    specifier: &ModuleSpecifier,
+  ) -> Result<ModuleId, Error> {
+    let isolate = &mut self.inner.v8_isolate;
+    self
+      .inner
+      .main_realm
+      .load_main_es_module_from_code(isolate, specifier, None)
+      .await
+  }
+
+  /// Asynchronously load specified ES module and all of its dependencies from the
+  /// provided source.
+  ///
+  /// This method is meant to be used when loading some utility code that
+  /// might be later imported by the main module (ie. an entry point module).
+  ///
+  /// The source may be any type that implements the internal [`IntoModuleCodeString`] trait, but
+  /// it is highly recommended that embedders use the [`ascii_str!`] to generate the fastest version
+  /// of strings for v8 to handle. If the strings are not static, you may also pass a [`String`]
+  /// generated by the [`format!`] macro.
+  ///
   /// User must call [`JsRuntime::mod_evaluate`] with returned `ModuleId`
   /// manually after load is finished.
-  pub async fn load_main_module(
+  pub async fn load_side_es_module_from_code(
     &mut self,
     specifier: &ModuleSpecifier,
-    code: Option<ModuleCodeString>,
+    code: impl IntoModuleCodeString,
   ) -> Result<ModuleId, Error> {
     let isolate = &mut self.inner.v8_isolate;
     self
       .inner
       .main_realm
-      .load_main_module(isolate, specifier, code)
+      .load_side_es_module_from_code(
+        isolate,
+        specifier,
+        Some(code.into_module_code()),
+      )
       .await
   }
 
-  /// Asynchronously load specified ES module and all of its dependencies.
+  /// Asynchronously load specified ES module and all of its dependencies, retrieving
+  /// the module from the supplied [`ModuleLoader`].
   ///
   /// This method is meant to be used when loading some utility code that
   /// might be later imported by the main module (ie. an entry point module).
   ///
   /// User must call [`JsRuntime::mod_evaluate`] with returned `ModuleId`
   /// manually after load is finished.
-  pub async fn load_side_module(
+  pub async fn load_side_es_module(
     &mut self,
     specifier: &ModuleSpecifier,
-    code: Option<ModuleCodeString>,
   ) -> Result<ModuleId, Error> {
     let isolate = &mut self.inner.v8_isolate;
     self
       .inner
       .main_realm
-      .load_side_module(isolate, specifier, code)
+      .load_side_es_module_from_code(isolate, specifier, None)
       .await
   }
 
@@ -2115,16 +2181,17 @@ impl JsRuntime {
   ///
   /// It is caller's responsibility to ensure that not duplicate specifiers are
   /// passed to this method.
-  pub fn lazy_load_es_module_from_code(
+  pub fn lazy_load_es_module_with_code(
     &mut self,
-    specifier: &str,
-    code: ModuleCodeString,
+    specifier: impl IntoModuleName,
+    code: impl IntoModuleCodeString,
   ) -> Result<v8::Global<v8::Value>, Error> {
     let isolate = &mut self.inner.v8_isolate;
-    self
-      .inner
-      .main_realm
-      .lazy_load_es_module_from_code(isolate, specifier, code)
+    self.inner.main_realm.lazy_load_es_module_with_code(
+      isolate,
+      specifier.into_module_name(),
+      code.into_module_code(),
+    )
   }
 
   fn do_js_event_loop_tick_realm(


Test patch:
diff --git a/core/modules/tests.rs b/core/modules/tests.rs
index e78d4bd..c99c984 100644
--- a/core/modules/tests.rs
+++ b/core/modules/tests.rs
@@ -6,6 +6,7 @@ use crate::modules::loaders::ModuleLoadEventCounts;
 use crate::modules::loaders::TestingModuleLoader;
 use crate::modules::loaders::*;
 use crate::modules::CustomModuleEvaluationKind;
+use crate::modules::IntoModuleName;
 use crate::modules::ModuleCodeBytes;
 use crate::modules::ModuleError;
 use crate::modules::ModuleInfo;
@@ -259,7 +260,7 @@ fn test_recursive_load() {
     ..Default::default()
   });
   let spec = resolve_url("file:///a.js").unwrap();
-  let a_id_fut = runtime.load_main_module(&spec, None);
+  let a_id_fut = runtime.load_main_es_module(&spec);
   let a_id = futures::executor::block_on(a_id_fut).unwrap();
 
   #[allow(clippy::let_underscore_future)]
@@ -362,20 +363,17 @@ fn test_mods() {
 
   let (mod_a, mod_b) = {
     let scope = &mut runtime.handle_scope();
-    let specifier_a = ascii_str!("file:///a.js");
     let mod_a = module_map
       .new_es_module(
         scope,
         true,
-        specifier_a,
-        ascii_str!(
-          r#"
-        import { b } from './b.js'
-        if (b() != 'b') throw Error();
-        let control = 42;
-        Deno.core.ops.op_test(control);
-      "#
-        ),
+        "file:///a.js",
+        r#"
+          import { b } from './b.js'
+          if (b() != 'b') throw Error();
+          let control = 42;
+          Deno.core.ops.op_test(control);
+        "#,
         false,
       )
       .unwrap();
@@ -722,7 +720,7 @@ fn test_custom_module_type_default() {
 
   let err = {
     let scope = &mut runtime.handle_scope();
-    let specifier_a = ascii_str!("file:///a.png");
+    let specifier_a = ascii_str!("file:///a.png").into();
     module_map
       .new_module(
         scope,
@@ -789,7 +787,7 @@ fn test_custom_module_type_callback_synthetic() {
 
   let err = {
     let scope = &mut runtime.handle_scope();
-    let specifier_a = ascii_str!("file:///a.png");
+    let specifier_a = ascii_str!("file:///a.png").into();
     module_map
       .new_module(
         scope,
@@ -814,7 +812,7 @@ fn test_custom_module_type_callback_synthetic() {
 
   {
     let scope = &mut runtime.handle_scope();
-    let specifier_a = ascii_str!("file:///b.png");
+    let specifier_a = ascii_str!("file:///b.png").into();
     module_map
       .new_module(
         scope,
@@ -884,7 +882,7 @@ export const foo = bytes;
 
   let mod_id = {
     let scope = &mut runtime.handle_scope();
-    let specifier_a = ascii_str!("file:///b.png");
+    let specifier_a = ascii_str!("file:///b.png").into();
     module_map
       .new_module(
         scope,
@@ -908,7 +906,7 @@ export const foo = bytes;
     &ModuleInfo {
       id: mod_id,
       main: true,
-      name: ascii_str!("file:///b.png"),
+      name: "file:///b.png".into_module_name(),
       requests: vec![ModuleRequest {
         specifier: "file:///b.png".to_string(),
         requested_module_type: RequestedModuleType::Other(
@@ -924,7 +922,7 @@ export const foo = bytes;
     &ModuleInfo {
       id: mod_id - 1,
       main: false,
-      name: ascii_str!("file:///b.png"),
+      name: "file:///b.png".into_module_name(),
       requests: vec![],
       module_type: ModuleType::Other("foobar-synth".into()),
     }
@@ -1059,7 +1057,7 @@ fn test_circular_load() {
 
   let fut = async move {
     let spec = resolve_url("file:///circular1.js").unwrap();
-    let result = runtime.load_main_module(&spec, None).await;
+    let result = runtime.load_main_es_module(&spec).await;
     assert!(result.is_ok());
     let circular1_id = result.unwrap();
     #[allow(clippy::let_underscore_future)]
@@ -1140,7 +1138,7 @@ fn test_redirect_load() {
   let fut =
     async move {
       let spec = resolve_url("file:///redirect1.js").unwrap();
-      let result = runtime.load_main_module(&spec, None).await;
+      let result = runtime.load_main_es_module(&spec).await;
       assert!(result.is_ok());
       let redirect1_id = result.unwrap();
       #[allow(clippy::let_underscore_future)]
@@ -1207,8 +1205,7 @@ async fn slow_never_ready_modules() {
 
   poll_fn(move |cx| {
     let spec = resolve_url("file:///main.js").unwrap();
-    let mut recursive_load =
-      runtime.load_main_module(&spec, None).boxed_local();
+    let mut recursive_load = runtime.load_main_es_module(&spec).boxed_local();
 
     let result = recursive_load.poll_unpin(cx);
     assert!(result.is_pending());
@@ -1252,7 +1249,7 @@ async fn loader_disappears_after_error() {
   });
 
   let spec = resolve_url("file:///bad_import.js").unwrap();
-  let result = runtime.load_main_module(&spec, None).await;
+  let result = runtime.load_main_es_module(&spec).await;
   let err = result.unwrap_err();
   assert_eq!(
     err.downcast_ref::<MockError>().unwrap(),
@@ -1262,16 +1259,14 @@ async fn loader_disappears_after_error() {
 
 #[test]
 fn recursive_load_main_with_code() {
-  const MAIN_WITH_CODE_SRC: FastString = ascii_str!(
-    r#"
-import { b } from "/b.js";
-import { c } from "/c.js";
-if (b() != 'b') throw Error();
-if (c() != 'c') throw Error();
-if (!import.meta.main) throw Error();
-if (import.meta.url != 'file:///main_with_code.js') throw Error();
-"#
-  );
+  const MAIN_WITH_CODE_SRC: &str = r#"
+    import { b } from "/b.js";
+    import { c } from "/c.js";
+    if (b() != 'b') throw Error();
+    if (c() != 'c') throw Error();
+    if (!import.meta.main) throw Error();
+    if (import.meta.url != 'file:///main_with_code.js') throw Error();
+  "#;
 
   let loader = MockLoader::new();
   let loads = loader.loads.clone();
@@ -1284,7 +1279,7 @@ if (import.meta.url != 'file:///main_with_code.js') throw Error();
   // The behavior should be very similar to /a.js.
   let spec = resolve_url("file:///main_with_code.js").unwrap();
   let main_id_fut = runtime
-    .load_main_module(&spec, Some(MAIN_WITH_CODE_SRC))
+    .load_main_es_module_from_code(&spec, MAIN_WITH_CODE_SRC)
     .boxed_local();
   let main_id = futures::executor::block_on(main_id_fut).unwrap();
 
@@ -1367,9 +1362,7 @@ fn main_and_side_module() {
     ..Default::default()
   });
 
-  let main_id_fut = runtime
-    .load_main_module(&main_specifier, None)
-    .boxed_local();
+  let main_id_fut = runtime.load_main_es_module(&main_specifier).boxed_local();
   let main_id = futures::executor::block_on(main_id_fut).unwrap();
 
   #[allow(clippy::let_underscore_future)]
@@ -1378,15 +1371,11 @@ fn main_and_side_module() {
     .unwrap();
 
   // Try to add another main module - it should error.
-  let side_id_fut = runtime
-    .load_main_module(&side_specifier, None)
-    .boxed_local();
+  let side_id_fut = runtime.load_main_es_module(&side_specifier).boxed_local();
   futures::executor::block_on(side_id_fut).unwrap_err();
 
   // And now try to load it as a side module
-  let side_id_fut = runtime
-    .load_side_module(&side_specifier, None)
-    .boxed_local();
+  let side_id_fut = runtime.load_side_es_module(&side_specifier).boxed_local();
   let side_id = futures::executor::block_on(side_id_fut).unwrap();
 
   #[allow(clippy::let_underscore_future)]
@@ -1400,11 +1389,9 @@ fn dynamic_imports_snapshot() {
   //TODO: Once the issue with the ModuleNamespaceEntryGetter is fixed, we can maintain a reference to the module
   // and use it when loading the snapshot
   let snapshot = {
-    const MAIN_WITH_CODE_SRC: FastString = ascii_str!(
-      r#"
-    await import("./b.js");
-  "#
-    );
+    const MAIN_WITH_CODE_SRC: &str = r#"
+      await import("./b.js");
+    "#;
 
     let loader = MockLoader::new();
     let mut runtime = JsRuntimeForSnapshot::new(RuntimeOptions {
@@ -1416,7 +1403,7 @@ fn dynamic_imports_snapshot() {
     // The behavior should be very similar to /a.js.
     let spec = resolve_url("file:///main_with_code.js").unwrap();
     let main_id_fut = runtime
-      .load_main_module(&spec, Some(MAIN_WITH_CODE_SRC))
+      .load_main_es_module_from_code(&spec, MAIN_WITH_CODE_SRC)
       .boxed_local();
     let main_id = futures::executor::block_on(main_id_fut).unwrap();
 
@@ -1440,13 +1427,11 @@ fn dynamic_imports_snapshot() {
 #[test]
 fn import_meta_snapshot() {
   let snapshot = {
-    const MAIN_WITH_CODE_SRC: ModuleCodeString = ascii_str!(
-      r#"
-  if (import.meta.url != 'file:///main_with_code.js') throw Error();
-  globalThis.meta = import.meta;
-  globalThis.url = import.meta.url;
-  "#
-    );
+    const MAIN_WITH_CODE_SRC: &str = r#"
+      if (import.meta.url != 'file:///main_with_code.js') throw Error();
+      globalThis.meta = import.meta;
+      globalThis.url = import.meta.url;
+    "#;
 
     let loader = MockLoader::new();
     let mut runtime = JsRuntimeForSnapshot::new(RuntimeOptions {
@@ -1458,7 +1443,7 @@ fn import_meta_snapshot() {
     // The behavior should be very similar to /a.js.
     let spec = resolve_url("file:///main_with_code.js").unwrap();
     let main_id_fut = runtime
-      .load_main_module(&spec, Some(MAIN_WITH_CODE_SRC))
+      .load_main_es_module_from_code(&spec, MAIN_WITH_CODE_SRC)
       .boxed_local();
     let main_id = futures::executor::block_on(main_id_fut).unwrap();
 
@@ -1585,7 +1570,7 @@ async fn no_duplicate_loads() {
   });
 
   let spec = resolve_url("file:///main.js").unwrap();
-  let a_id = runtime.load_main_module(&spec, None).await.unwrap();
+  let a_id = runtime.load_main_es_module(&spec).await.unwrap();
   #[allow(clippy::let_underscore_future)]
   let _ = runtime.mod_evaluate(a_id);
   runtime.run_event_loop(Default::default()).await.unwrap();
@@ -1616,21 +1601,20 @@ async fn import_meta_resolve_cb() {
 
   let spec = ModuleSpecifier::parse("file:///test.js").unwrap();
   let source = r#"
-  if (import.meta.resolve("foo") !== "foo:bar") throw new Error("a");
-  if (import.meta.resolve("./mod.js") !== "file:///mod.js") throw new Error("b");
-  let caught = false;
-  try {
-    import.meta.resolve("boom!");
-  } catch (e) {
-    if (!(e instanceof TypeError)) throw new Error("c");
-    caught = true;
-  }
-  if (!caught) throw new Error("d");
-  "#
-  .to_string();
+    if (import.meta.resolve("foo") !== "foo:bar") throw new Error("a");
+    if (import.meta.resolve("./mod.js") !== "file:///mod.js") throw new Error("b");
+    let caught = false;
+    try {
+      import.meta.resolve("boom!");
+    } catch (e) {
+      if (!(e instanceof TypeError)) throw new Error("c");
+      caught = true;
+    }
+    if (!caught) throw new Error("d");
+  "#;
 
   let a_id = runtime
-    .load_main_module(&spec, Some(source.into()))
+    .load_main_es_module_from_code(&spec, source)
     .await
     .unwrap();
   let local = LocalSet::new();
@@ -1648,24 +1632,20 @@ async fn import_meta_resolve_cb() {
 fn builtin_core_module() {
   let main_specifier = resolve_url("ext:///main_module.js").unwrap();
 
-  let source_code =
-    r#"import { core, primordials, internals } from "ext:core/mod.js";
-if (typeof core === "undefined") throw new Error("core missing");
-if (typeof primordials === "undefined") throw new Error("core missing");
-if (typeof internals === "undefined") throw new Error("core missing");
-"#
-    .to_string();
-  let loader =
-    StaticModuleLoader::new([(main_specifier.clone(), source_code.into())]);
+  let source_code = r#"
+    import { core, primordials, internals } from "ext:core/mod.js";
+    if (typeof core === "undefined") throw new Error("core missing");
+    if (typeof primordials === "undefined") throw new Error("core missing");
+    if (typeof internals === "undefined") throw new Error("core missing");
+  "#;
+  let loader = StaticModuleLoader::new([(main_specifier.clone(), source_code)]);
 
   let mut runtime = JsRuntime::new(RuntimeOptions {
     module_loader: Some(Rc::new(loader)),
     ..Default::default()
   });
 
-  let main_id_fut = runtime
-    .load_main_module(&main_specifier, None)
-    .boxed_local();
+  let main_id_fut = runtime.load_main_es_module(&main_specifier).boxed_local();
   let main_id = futures::executor::block_on(main_id_fut).unwrap();
 
   #[allow(clippy::let_underscore_future)]
@@ -1679,18 +1659,16 @@ fn import_meta_filename_dirname() {
   #[cfg(not(target_os = "windows"))]
   let main_specifier = resolve_url("file:///main_module.js").unwrap();
   #[cfg(not(target_os = "windows"))]
-  let code = ascii_str!(
-    r#"if (import.meta.filename != '/main_module.js') throw Error();
-    if (import.meta.dirname != '/') throw Error();"#
-  );
+  let code = r#"if (import.meta.filename != '/main_module.js') throw Error();
+    if (import.meta.dirname != '/') throw Error();
+  "#;
 
   #[cfg(target_os = "windows")]
   let main_specifier = resolve_url("file:///C:/main_module.js").unwrap();
   #[cfg(target_os = "windows")]
-  let code = ascii_str!(
-    r#"if (import.meta.filename != 'C:\\main_module.js') throw Error();
-    if (import.meta.dirname != 'C:\\') throw Error();"#
-  );
+  let code = r#"if (import.meta.filename != 'C:\\main_module.js') throw Error();
+    if (import.meta.dirname != 'C:\\') throw Error();
+  "#;
 
   let loader = StaticModuleLoader::new([(main_specifier.clone(), code)]);
 
@@ -1699,9 +1677,7 @@ fn import_meta_filename_dirname() {
     ..Default::default()
   });
 
-  let main_id_fut = runtime
-    .load_main_module(&main_specifier, None)
-    .boxed_local();
+  let main_id_fut = runtime.load_main_es_module(&main_specifier).boxed_local();
   let main_id = futures::executor::block_on(main_id_fut).unwrap();
 
   #[allow(clippy::let_underscore_future)]
diff --git a/core/runtime/tests/jsrealm.rs b/core/runtime/tests/jsrealm.rs
index e34dc13..e40c6ea 100644
--- a/core/runtime/tests/jsrealm.rs
+++ b/core/runtime/tests/jsrealm.rs
@@ -24,10 +24,10 @@ fn test_set_format_exception_callback_realms() {
         "",
         format!(
           r#"
-            Deno.core.ops.op_set_format_exception_callback((error) => {{
-              return `{realm_name} / ${{error}}`;
-            }});
-          "#
+          Deno.core.ops.op_set_format_exception_callback((error) => {{
+            return `{realm_name} / ${{error}}`;
+          }});
+        "#
         ),
       )
       .unwrap();
diff --git a/core/runtime/tests/misc.rs b/core/runtime/tests/misc.rs
index 8cb1cf9..41665a8 100644
--- a/core/runtime/tests/misc.rs
+++ b/core/runtime/tests/misc.rs
@@ -116,8 +116,8 @@ async fn test_wakers_for_async_ops() {
   runtime
     .execute_script(
       "",
-      FastString::from_static(
-        "const { op_async_sleep } = Deno.core.ensureFastOps(); (async () => { await op_async_sleep(); })()",
+      ascii_str!(
+        "const { op_async_sleep } = Deno.core.ensureFastOps(); (async () => { await op_async_sleep(); })()"
       ),
     )
     .unwrap();
@@ -429,15 +429,13 @@ fn test_get_module_namespace() {
   });
 
   let specifier = crate::resolve_url("file:///main.js").unwrap();
-  let source_code = ascii_str!(
-    r#"
+  let source_code = r#"
     export const a = "b";
     export default 1 + 2;
-    "#
-  );
+  "#;
 
   let module_id = futures::executor::block_on(
-    runtime.load_main_module(&specifier, Some(source_code)),
+    runtime.load_main_es_module_from_code(&specifier, source_code),
   )
   .unwrap();
 
@@ -783,10 +781,10 @@ fn terminate_during_module_eval() {
   });
 
   let specifier = crate::resolve_url("file:///main.js").unwrap();
-  let source_code = ascii_str!("Deno.core.print('hello\\n')");
 
   let module_id = futures::executor::block_on(
-    runtime.load_main_module(&specifier, Some(source_code)),
+    runtime
+      .load_main_es_module_from_code(&specifier, "Deno.core.print('hello\\n')"),
   )
   .unwrap();
 
@@ -853,9 +851,9 @@ async fn test_promise_rejection_handler_generic(
 
   let future = if module {
     let id = runtime
-      .load_main_module(
+      .load_main_es_module_from_code(
         &Url::parse("file:///test.js").unwrap(),
-        Some(script.into()),
+        script,
       )
       .await
       .unwrap();
@@ -925,14 +923,14 @@ async fn test_promise_rejection_handler(
 async fn test_stalled_tla() {
   let loader = StaticModuleLoader::with(
     Url::parse("file:///test.js").unwrap(),
-    ascii_str!("await new Promise(() => {});"),
+    "await new Promise(() => {});",
   );
   let mut runtime = JsRuntime::new(RuntimeOptions {
     module_loader: Some(Rc::new(loader)),
     ..Default::default()
   });
   let module_id = runtime
-    .load_main_module(&crate::resolve_url("file:///test.js").unwrap(), None)
+    .load_main_es_module(&crate::resolve_url("file:///test.js").unwrap())
     .await
     .unwrap();
   #[allow(clippy::let_underscore_future)]
@@ -968,15 +966,11 @@ async fn test_dynamic_import_module_error_stack() {
   let loader = StaticModuleLoader::new([
     (
       Url::parse("file:///main.js").unwrap(),
-      ascii_str!(
-        "
-        await import(\"file:///import.js\");
-        "
-      ),
+      "await import(\"file:///import.js\");"
     ),
     (
       Url::parse("file:///import.js").unwrap(),
-      ascii_str!("const { op_async_error } = Deno.core.ensureFastOps(); await op_async_error();"),
+      "const { op_async_error } = Deno.core.ensureFastOps(); await op_async_error();",
     ),
   ]);
   let mut runtime = JsRuntime::new(RuntimeOptions {
@@ -986,7 +980,7 @@ async fn test_dynamic_import_module_error_stack() {
   });
 
   let module_id = runtime
-    .load_main_module(&crate::resolve_url("file:///main.js").unwrap(), None)
+    .load_main_es_module(&crate::resolve_url("file:///main.js").unwrap())
     .await
     .unwrap();
   #[allow(clippy::let_underscore_future)]
diff --git a/core/runtime/tests/ops.rs b/core/runtime/tests/ops.rs
index ad63985..4235aa6 100644
--- a/core/runtime/tests/ops.rs
+++ b/core/runtime/tests/ops.rs
@@ -482,22 +482,18 @@ pub async fn test_top_level_await() {
   let loader = StaticModuleLoader::new([
     (
       Url::parse("http://x/main.js").unwrap(),
-      ascii_str!(
-        r#"
+      r#"
 const { op_sleep_forever } = Deno.core.ensureFastOps();
 (async () => await op_sleep_forever())();
 await import('./mod.js');
-    "#
-      ),
+    "#,
     ),
     (
       Url::parse("http://x/mod.js").unwrap(),
-      ascii_str!(
-        r#"
+      r#"
 const { op_void_async_deferred } = Deno.core.ensureFastOps();
 await op_void_async_deferred();
-    "#
-      ),
+    "#,
     ),
   ]);
 
@@ -508,7 +504,7 @@ await op_void_async_deferred();
   });
 
   let id = runtime
-    .load_main_module(&Url::parse("http://x/main.js").unwrap(), None)
+    .load_main_es_module(&Url::parse("http://x/main.js").unwrap())
     .await
     .unwrap();
   let mut rx = runtime.mod_evaluate(id);
diff --git a/core/runtime/tests/snapshot.rs b/core/runtime/tests/snapshot.rs
index efeb765..fda36a8 100644
--- a/core/runtime/tests/snapshot.rs
+++ b/core/runtime/tests/snapshot.rs
@@ -197,17 +197,16 @@ fn es_snapshot() {
       import {{ f{prev} }} from "file:///{prev}.js";
       export function f{i}() {{ return f{prev}() }}
       "#
-    )
-    .into();
+    );
 
     let id = if main {
       futures::executor::block_on(
-        runtime.load_main_module(&specifier, Some(source_code)),
+        runtime.load_main_es_module_from_code(&specifier, source_code),
       )
       .unwrap()
     } else {
       futures::executor::block_on(
-        runtime.load_side_module(&specifier, Some(source_code)),
+        runtime.load_side_es_module_from_code(&specifier, source_code),
       )
       .unwrap()
     };
@@ -246,11 +245,10 @@ fn es_snapshot() {
   });
 
   let specifier = crate::resolve_url("file:///0.js").unwrap();
-  let source_code =
-    ascii_str!(r#"export function f0() { return "hello world" }"#);
-  let id = futures::executor::block_on(
-    runtime.load_side_module(&specifier, Some(source_code)),
-  )
+  let id = futures::executor::block_on(runtime.load_side_es_module_from_code(
+    &specifier,
+    r#"export function f0() { return "hello world" }"#,
+  ))
   .unwrap();
 
   #[allow(clippy::let_underscore_future)]
diff --git a/testing/checkin/runner/mod.rs b/testing/checkin/runner/mod.rs
index d8f08aa..4072eb1 100644
--- a/testing/checkin/runner/mod.rs
+++ b/testing/checkin/runner/mod.rs
@@ -169,7 +169,7 @@ async fn run_integration_test_task(
 ) -> Result<(), Error> {
   let test_dir = get_test_dir(&["integration", &test]);
   let url = get_test_url(&test_dir, &test)?;
-  let module = runtime.load_main_module(&url, None).await?;
+  let module = runtime.load_main_es_module(&url).await?;
   let f = runtime.mod_evaluate(module);
   let mut actual_output = String::new();
   if let Err(e) = runtime
@@ -209,7 +209,7 @@ async fn run_unit_test_task(
 ) -> Result<(), Error> {
   let test_dir = get_test_dir(&["unit"]);
   let url = get_test_url(&test_dir, &test)?;
-  let module = runtime.load_main_module(&url, None).await?;
+  let module = runtime.load_main_es_module(&url).await?;
   let f = runtime.mod_evaluate(module);
   runtime
     .run_event_loop(PollEventLoopOptions::default())
diff --git a/testing/checkin/runner/ops_worker.rs b/testing/checkin/runner/ops_worker.rs
index 7900e02..0fd0ccd 100644
--- a/testing/checkin/runner/ops_worker.rs
+++ b/testing/checkin/runner/ops_worker.rs
@@ -126,7 +126,7 @@ async fn run_worker_task(
   mut shutdown_rx: UnboundedReceiver<()>,
 ) -> Result<(), Error> {
   let url = Url::try_from(base_url.as_str())?.join(&main_script)?;
-  let module = runtime.load_main_module(&url, None).await?;
+  let module = runtime.load_main_es_module(&url).await?;
   let f = runtime.mod_evaluate(module);
   // We need this structure for the shutdown code to ensure that the output is
   // consistent whether the v8 termination signal is sent, or the shutdown_rx is