summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bench_util/js_runtime.rs5
-rw-r--r--cli/emit.rs7
-rw-r--r--cli/lsp/tsc.rs4
-rw-r--r--cli/module_loader.rs17
-rw-r--r--cli/standalone.rs10
-rw-r--r--cli/tools/coverage/mod.rs24
-rw-r--r--cli/tsc/mod.rs4
-rw-r--r--cli/util/text_encoding.rs36
-rw-r--r--cli/worker.rs36
-rw-r--r--core/examples/eval_js_value.rs2
-rw-r--r--core/examples/ts_module_loader.rs2
-rw-r--r--core/extensions.rs10
-rw-r--r--core/lib.rs3
-rw-r--r--core/modules.rs331
-rw-r--r--core/runtime.rs99
-rw-r--r--ext/node/lib.rs8
-rw-r--r--runtime/build.rs7
-rw-r--r--runtime/web_worker.rs15
-rw-r--r--runtime/worker.rs13
19 files changed, 457 insertions, 176 deletions
diff --git a/bench_util/js_runtime.rs b/bench_util/js_runtime.rs
index e381ba16b..4a5123a73 100644
--- a/bench_util/js_runtime.rs
+++ b/bench_util/js_runtime.rs
@@ -103,7 +103,8 @@ pub fn bench_js_async_with(
opts.benching_inner
};
let looped = loop_code(inner_iters, src);
- let src = looped.as_ref();
+ // Get a &'static str by leaking -- this is fine because it's benchmarking code
+ let src = Box::leak(looped.into_boxed_str());
if is_profiling() {
for _ in 0..opts.profiling_outer {
tokio_runtime.block_on(inner_async(src, &mut runtime));
@@ -115,7 +116,7 @@ pub fn bench_js_async_with(
}
}
-async fn inner_async(src: &str, runtime: &mut JsRuntime) {
+async fn inner_async(src: &'static str, runtime: &mut JsRuntime) {
runtime.execute_script("inner_loop", src).unwrap();
runtime.run_event_loop(false).await.unwrap();
}
diff --git a/cli/emit.rs b/cli/emit.rs
index d322fe38e..f69f70cc7 100644
--- a/cli/emit.rs
+++ b/cli/emit.rs
@@ -5,6 +5,7 @@ use crate::cache::FastInsecureHasher;
use crate::cache::ParsedSourceCache;
use deno_core::error::AnyError;
+use deno_core::ModuleCode;
use deno_core::ModuleSpecifier;
use deno_graph::MediaType;
use std::sync::Arc;
@@ -27,11 +28,11 @@ pub fn emit_parsed_source(
source: &Arc<str>,
emit_options: &deno_ast::EmitOptions,
emit_config_hash: u64,
-) -> Result<String, AnyError> {
+) -> Result<ModuleCode, AnyError> {
let source_hash = get_source_hash(source, emit_config_hash);
if let Some(emit_code) = emit_cache.get_emit_code(specifier, source_hash) {
- Ok(emit_code)
+ Ok(emit_code.into())
} else {
// this will use a cached version if it exists
let parsed_source = parsed_source_cache.get_or_parse_module(
@@ -42,6 +43,6 @@ pub fn emit_parsed_source(
let transpiled_source = parsed_source.transpile(emit_options)?;
debug_assert!(transpiled_source.source_map.is_none());
emit_cache.set_emit_code(specifier, source_hash, &transpiled_source.text);
- Ok(transpiled_source.text)
+ Ok(transpiled_source.text.into())
}
}
diff --git a/cli/lsp/tsc.rs b/cli/lsp/tsc.rs
index c8d8103b9..fedaae588 100644
--- a/cli/lsp/tsc.rs
+++ b/cli/lsp/tsc.rs
@@ -2854,7 +2854,7 @@ fn start(runtime: &mut JsRuntime, debug: bool) -> Result<(), AnyError> {
let init_config = json!({ "debug": debug });
let init_src = format!("globalThis.serverInit({init_config});");
- runtime.execute_script(&located_script_name!(), &init_src)?;
+ runtime.execute_script(located_script_name!(), init_src)?;
Ok(())
}
@@ -3442,7 +3442,7 @@ pub fn request(
};
let mark = performance.mark("request", Some(request_params.clone()));
let request_src = format!("globalThis.serverRequest({request_params});");
- runtime.execute_script(&located_script_name!(), &request_src)?;
+ runtime.execute_script(located_script_name!(), request_src)?;
let op_state = runtime.op_state();
let mut op_state = op_state.borrow_mut();
diff --git a/cli/module_loader.rs b/cli/module_loader.rs
index c5224a8b9..7f6101d80 100644
--- a/cli/module_loader.rs
+++ b/cli/module_loader.rs
@@ -14,6 +14,7 @@ use deno_core::error::AnyError;
use deno_core::futures::future::FutureExt;
use deno_core::futures::Future;
use deno_core::resolve_url;
+use deno_core::ModuleCode;
use deno_core::ModuleLoader;
use deno_core::ModuleSource;
use deno_core::ModuleSpecifier;
@@ -30,7 +31,7 @@ use std::rc::Rc;
use std::str;
struct ModuleCodeSource {
- pub code: String,
+ pub code: ModuleCode,
pub found_url: ModuleSpecifier,
pub media_type: MediaType,
}
@@ -91,7 +92,7 @@ impl CliModuleLoader {
specifier,
..
})) => Ok(ModuleCodeSource {
- code: source.to_string(),
+ code: source.into(),
found_url: specifier.clone(),
media_type: *media_type,
}),
@@ -101,13 +102,15 @@ impl CliModuleLoader {
specifier,
..
})) => {
- let code = match media_type {
+ let code: ModuleCode = match media_type {
MediaType::JavaScript
| MediaType::Unknown
| MediaType::Cjs
| MediaType::Mjs
- | MediaType::Json => source.to_string(),
- MediaType::Dts | MediaType::Dcts | MediaType::Dmts => "".to_string(),
+ | MediaType::Json => source.into(),
+ MediaType::Dts | MediaType::Dcts | MediaType::Dmts => {
+ Default::default()
+ }
MediaType::TypeScript
| MediaType::Mts
| MediaType::Cts
@@ -191,7 +194,7 @@ impl CliModuleLoader {
)?
};
ModuleCodeSource {
- code,
+ code: code.into(),
found_url: specifier.clone(),
media_type: MediaType::from_specifier(specifier),
}
@@ -208,7 +211,7 @@ impl CliModuleLoader {
code_without_source_map(code_source.code)
};
Ok(ModuleSource {
- code: code.into_bytes().into_boxed_slice(),
+ code,
module_url_specified: specifier.to_string(),
module_url_found: code_source.found_url.to_string(),
module_type: match code_source.media_type {
diff --git a/cli/standalone.rs b/cli/standalone.rs
index 8f74d50a8..254cb9de5 100644
--- a/cli/standalone.rs
+++ b/cli/standalone.rs
@@ -178,7 +178,7 @@ impl ModuleLoader for EmbeddedModuleLoader {
async move {
if let Some((source, _)) = is_data_uri {
return Ok(deno_core::ModuleSource {
- code: source.into_bytes().into_boxed_slice(),
+ code: source.into(),
module_type: deno_core::ModuleType::JavaScript,
module_url_specified: module_specifier.to_string(),
module_url_found: module_specifier.to_string(),
@@ -192,7 +192,7 @@ impl ModuleLoader for EmbeddedModuleLoader {
.to_owned();
Ok(deno_core::ModuleSource {
- code: code.into_bytes().into_boxed_slice(),
+ code: code.into(),
module_type: match module.kind {
eszip::ModuleKind::JavaScript => deno_core::ModuleType::JavaScript,
eszip::ModuleKind::Json => deno_core::ModuleType::Json,
@@ -384,16 +384,16 @@ pub async fn run(
options,
);
worker.execute_main_module(main_module).await?;
- worker.dispatch_load_event(&located_script_name!())?;
+ worker.dispatch_load_event(located_script_name!())?;
loop {
worker.run_event_loop(false).await?;
- if !worker.dispatch_beforeunload_event(&located_script_name!())? {
+ if !worker.dispatch_beforeunload_event(located_script_name!())? {
break;
}
}
- worker.dispatch_unload_event(&located_script_name!())?;
+ worker.dispatch_unload_event(located_script_name!())?;
std::process::exit(0);
}
diff --git a/cli/tools/coverage/mod.rs b/cli/tools/coverage/mod.rs
index eaa087171..9fead6e37 100644
--- a/cli/tools/coverage/mod.rs
+++ b/cli/tools/coverage/mod.rs
@@ -20,6 +20,7 @@ use deno_core::serde_json;
use deno_core::sourcemap::SourceMap;
use deno_core::url::Url;
use deno_core::LocalInspectorSession;
+use deno_core::ModuleCode;
use regex::Regex;
use std::fs;
use std::fs::File;
@@ -170,16 +171,16 @@ struct CoverageReport {
fn generate_coverage_report(
script_coverage: &ScriptCoverage,
- script_source: &str,
+ script_source: String,
maybe_source_map: &Option<Vec<u8>>,
output: &Option<PathBuf>,
) -> CoverageReport {
let maybe_source_map = maybe_source_map
.as_ref()
.map(|source_map| SourceMap::from_slice(source_map).unwrap());
- let text_lines = TextLines::new(script_source);
+ let text_lines = TextLines::new(&script_source);
- let comment_ranges = deno_ast::lex(script_source, MediaType::JavaScript)
+ let comment_ranges = deno_ast::lex(&script_source, MediaType::JavaScript)
.into_iter()
.filter(|item| {
matches!(item.inner, deno_ast::TokenOrComment::Comment { .. })
@@ -680,14 +681,14 @@ pub async fn cover_files(
})?;
// Check if file was transpiled
- let original_source = &file.source;
- let transpiled_code = match file.media_type {
+ let original_source = file.source.clone();
+ let transpiled_code: ModuleCode = match file.media_type {
MediaType::JavaScript
| MediaType::Unknown
| MediaType::Cjs
| MediaType::Mjs
- | MediaType::Json => file.source.as_ref().to_string(),
- MediaType::Dts | MediaType::Dmts | MediaType::Dcts => "".to_string(),
+ | MediaType::Json => file.source.into(),
+ MediaType::Dts | MediaType::Dmts | MediaType::Dcts => Default::default(),
MediaType::TypeScript
| MediaType::Jsx
| MediaType::Mts
@@ -695,7 +696,7 @@ pub async fn cover_files(
| MediaType::Tsx => {
let source_hash = get_source_hash(&file.source, ps.emit_options_hash);
match ps.emit_cache.get_emit_code(&file.specifier, source_hash) {
- Some(code) => code,
+ Some(code) => code.into(),
None => {
return Err(anyhow!(
"Missing transpiled source code for: \"{}\".
@@ -710,15 +711,16 @@ pub async fn cover_files(
}
};
+ let source_map = source_map_from_code(&transpiled_code);
let coverage_report = generate_coverage_report(
&script_coverage,
- &transpiled_code,
- &source_map_from_code(&transpiled_code),
+ transpiled_code.take_as_string(),
+ &source_map,
&out_mode,
);
if !coverage_report.found_lines.is_empty() {
- reporter.report(&coverage_report, original_source)?;
+ reporter.report(&coverage_report, &original_source)?;
}
}
diff --git a/cli/tsc/mod.rs b/cli/tsc/mod.rs
index 2f2015542..791aa6409 100644
--- a/cli/tsc/mod.rs
+++ b/cli/tsc/mod.rs
@@ -824,9 +824,9 @@ pub fn exec(request: Request) -> Result<Response, AnyError> {
});
runtime
- .execute_script(&located_script_name!(), startup_source)
+ .execute_script(located_script_name!(), startup_source)
.context("Could not properly start the compiler runtime.")?;
- runtime.execute_script(&located_script_name!(), &exec_source)?;
+ runtime.execute_script(located_script_name!(), exec_source)?;
let op_state = runtime.op_state();
let mut op_state = op_state.borrow_mut();
diff --git a/cli/util/text_encoding.rs b/cli/util/text_encoding.rs
index 87067e909..0111ec82f 100644
--- a/cli/util/text_encoding.rs
+++ b/cli/util/text_encoding.rs
@@ -1,5 +1,6 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+use deno_core::ModuleCode;
use encoding_rs::*;
use std::borrow::Cow;
use std::io::Error;
@@ -53,11 +54,12 @@ pub fn strip_bom(text: &str) -> &str {
}
}
-static SOURCE_MAP_PREFIX: &str =
- "//# sourceMappingURL=data:application/json;base64,";
+static SOURCE_MAP_PREFIX: &[u8] =
+ b"//# sourceMappingURL=data:application/json;base64,";
-pub fn source_map_from_code(code: &str) -> Option<Vec<u8>> {
- let last_line = code.rsplit(|u| u == '\n').next()?;
+pub fn source_map_from_code(code: &ModuleCode) -> Option<Vec<u8>> {
+ let bytes = code.as_bytes();
+ let last_line = bytes.rsplit(|u| *u == b'\n').next()?;
if last_line.starts_with(SOURCE_MAP_PREFIX) {
let input = last_line.split_at(SOURCE_MAP_PREFIX.len()).1;
let decoded_map = base64::decode(input)
@@ -68,17 +70,18 @@ pub fn source_map_from_code(code: &str) -> Option<Vec<u8>> {
}
}
-pub fn code_without_source_map(mut code: String) -> String {
- if let Some(last_line_index) = code.rfind('\n') {
- if code[last_line_index + 1..].starts_with(SOURCE_MAP_PREFIX) {
- code.truncate(last_line_index + 1);
- code
- } else {
- code
+/// Truncate the source code before the source map.
+pub fn code_without_source_map(mut code: ModuleCode) -> ModuleCode {
+ let bytes = code.as_bytes();
+ for i in (0..bytes.len()).rev() {
+ if bytes[i] == b'\n' {
+ if bytes[i + 1..].starts_with(SOURCE_MAP_PREFIX) {
+ code.truncate(i + 1);
+ }
+ return code;
}
- } else {
- code
}
+ code
}
#[cfg(test)]
@@ -155,8 +158,11 @@ mod tests {
"\n",
);
- fn run_test(input: &str, output: &str) {
- assert_eq!(code_without_source_map(input.to_string()), output);
+ fn run_test(input: &'static str, output: &'static str) {
+ assert_eq!(
+ code_without_source_map(input.into()).take_as_string(),
+ output
+ );
}
}
}
diff --git a/cli/worker.rs b/cli/worker.rs
index c505516a0..a0168a1f3 100644
--- a/cli/worker.rs
+++ b/cli/worker.rs
@@ -78,7 +78,7 @@ impl CliMainWorker {
self.execute_main_module_possibly_with_npm().await?;
}
- self.worker.dispatch_load_event(&located_script_name!())?;
+ self.worker.dispatch_load_event(located_script_name!())?;
loop {
self
@@ -87,13 +87,13 @@ impl CliMainWorker {
.await?;
if !self
.worker
- .dispatch_beforeunload_event(&located_script_name!())?
+ .dispatch_beforeunload_event(located_script_name!())?
{
break;
}
}
- self.worker.dispatch_unload_event(&located_script_name!())?;
+ self.worker.dispatch_unload_event(located_script_name!())?;
if let Some(coverage_collector) = maybe_coverage_collector.as_mut() {
self
@@ -129,7 +129,7 @@ impl CliMainWorker {
self
.inner
.worker
- .dispatch_load_event(&located_script_name!())?;
+ .dispatch_load_event(located_script_name!())?;
self.pending_unload = true;
let result = loop {
@@ -140,7 +140,7 @@ impl CliMainWorker {
match self
.inner
.worker
- .dispatch_beforeunload_event(&located_script_name!())
+ .dispatch_beforeunload_event(located_script_name!())
{
Ok(default_prevented) if default_prevented => {} // continue loop
Ok(_) => break Ok(()),
@@ -154,7 +154,7 @@ impl CliMainWorker {
self
.inner
.worker
- .dispatch_unload_event(&located_script_name!())?;
+ .dispatch_unload_event(located_script_name!())?;
Ok(())
}
@@ -166,7 +166,7 @@ impl CliMainWorker {
let _ = self
.inner
.worker
- .dispatch_unload_event(&located_script_name!());
+ .dispatch_unload_event(located_script_name!());
}
}
}
@@ -185,7 +185,7 @@ impl CliMainWorker {
// failures.
if self.ps.options.trace_ops() {
self.worker.js_runtime.execute_script(
- &located_script_name!(),
+ located_script_name!(),
"Deno[Deno.internal].core.enableOpCallTracing();",
)?;
}
@@ -200,19 +200,19 @@ impl CliMainWorker {
self.execute_side_module_possibly_with_npm().await?;
}
- self.worker.dispatch_load_event(&located_script_name!())?;
+ self.worker.dispatch_load_event(located_script_name!())?;
self.run_tests(&self.ps.options.shuffle_tests()).await?;
loop {
if !self
.worker
- .dispatch_beforeunload_event(&located_script_name!())?
+ .dispatch_beforeunload_event(located_script_name!())?
{
break;
}
self.worker.run_event_loop(false).await?;
}
- self.worker.dispatch_unload_event(&located_script_name!())?;
+ self.worker.dispatch_unload_event(located_script_name!())?;
if let Some(coverage_collector) = maybe_coverage_collector.as_mut() {
self
@@ -230,7 +230,7 @@ impl CliMainWorker {
self.enable_test();
self.worker.execute_script(
- &located_script_name!(),
+ located_script_name!(),
"Deno[Deno.internal].core.enableOpCallTracing();",
)?;
@@ -239,18 +239,18 @@ impl CliMainWorker {
self.execute_side_module_possibly_with_npm().await?;
}
- self.worker.dispatch_load_event(&located_script_name!())?;
+ self.worker.dispatch_load_event(located_script_name!())?;
self.run_tests(&None).await?;
loop {
if !self
.worker
- .dispatch_beforeunload_event(&located_script_name!())?
+ .dispatch_beforeunload_event(located_script_name!())?
{
break;
}
self.worker.run_event_loop(false).await?;
}
- self.worker.dispatch_unload_event(&located_script_name!())?;
+ self.worker.dispatch_unload_event(located_script_name!())?;
Ok(())
}
@@ -260,18 +260,18 @@ impl CliMainWorker {
// We execute the module module as a side module so that import.meta.main is not set.
self.execute_side_module_possibly_with_npm().await?;
- self.worker.dispatch_load_event(&located_script_name!())?;
+ self.worker.dispatch_load_event(located_script_name!())?;
self.run_benchmarks().await?;
loop {
if !self
.worker
- .dispatch_beforeunload_event(&located_script_name!())?
+ .dispatch_beforeunload_event(located_script_name!())?
{
break;
}
self.worker.run_event_loop(false).await?;
}
- self.worker.dispatch_unload_event(&located_script_name!())?;
+ self.worker.dispatch_unload_event(located_script_name!())?;
Ok(())
}
diff --git a/core/examples/eval_js_value.rs b/core/examples/eval_js_value.rs
index 6990abb85..e5b823a09 100644
--- a/core/examples/eval_js_value.rs
+++ b/core/examples/eval_js_value.rs
@@ -26,7 +26,7 @@ fn main() {
fn eval(
context: &mut JsRuntime,
- code: &str,
+ code: &'static str,
) -> Result<serde_json::Value, String> {
let res = context.execute_script("<anon>", code);
match res {
diff --git a/core/examples/ts_module_loader.rs b/core/examples/ts_module_loader.rs
index c7097fc91..4a38073ab 100644
--- a/core/examples/ts_module_loader.rs
+++ b/core/examples/ts_module_loader.rs
@@ -82,7 +82,7 @@ impl ModuleLoader for TypescriptModuleLoader {
code
};
let module = ModuleSource {
- code: code.into_bytes().into_boxed_slice(),
+ code: code.into(),
module_type,
module_url_specified: module_specifier.to_string(),
module_url_found: module_specifier.to_string(),
diff --git a/core/extensions.rs b/core/extensions.rs
index 2a578429b..94c4a2a79 100644
--- a/core/extensions.rs
+++ b/core/extensions.rs
@@ -1,4 +1,5 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+use crate::modules::ModuleCode;
use crate::OpState;
use anyhow::Context as _;
use anyhow::Error;
@@ -23,13 +24,12 @@ pub enum ExtensionFileSourceCode {
}
impl ExtensionFileSourceCode {
- pub fn load(&self) -> Result<String, Error> {
+ pub fn load(&self) -> Result<ModuleCode, Error> {
match self {
- ExtensionFileSourceCode::IncludedInBinary(code) => Ok(code.to_string()),
+ ExtensionFileSourceCode::IncludedInBinary(code) => Ok((*code).into()),
ExtensionFileSourceCode::LoadedFromFsDuringSnapshot(path) => {
- let msg = format!("Failed to read \"{}\"", path.display());
- let code = std::fs::read_to_string(path).context(msg)?;
- Ok(code)
+ let msg = || format!("Failed to read \"{}\"", path.display());
+ Ok(std::fs::read_to_string(path).with_context(msg)?.into())
}
}
}
diff --git a/core/lib.rs b/core/lib.rs
index 7751be6e8..ba0a026bc 100644
--- a/core/lib.rs
+++ b/core/lib.rs
@@ -77,6 +77,7 @@ pub use crate::module_specifier::ModuleSpecifier;
pub use crate::modules::ExtModuleLoader;
pub use crate::modules::ExtModuleLoaderCb;
pub use crate::modules::FsModuleLoader;
+pub use crate::modules::ModuleCode;
pub use crate::modules::ModuleId;
pub use crate::modules::ModuleLoader;
pub use crate::modules::ModuleSource;
@@ -144,7 +145,7 @@ pub mod _ops {
#[macro_export]
macro_rules! located_script_name {
() => {
- format!("[ext:{}:{}:{}]", std::file!(), std::line!(), std::column!());
+ concat!("[ext:{}:{}:{}]", std::file!(), std::line!(), std::column!());
};
}
diff --git a/core/modules.rs b/core/modules.rs
index 2d80071aa..78efdedfd 100644
--- a/core/modules.rs
+++ b/core/modules.rs
@@ -10,6 +10,7 @@ use crate::snapshot_util::SnapshottedData;
use crate::JsRuntime;
use crate::OpState;
use anyhow::Error;
+use core::panic;
use futures::future::FutureExt;
use futures::stream::FuturesUnordered;
use futures::stream::Stream;
@@ -18,6 +19,7 @@ use futures::stream::TryStreamExt;
use log::debug;
use serde::Deserialize;
use serde::Serialize;
+use std::borrow::Cow;
use std::cell::RefCell;
use std::collections::HashMap;
use std::collections::HashSet;
@@ -25,6 +27,7 @@ use std::collections::VecDeque;
use std::future::Future;
use std::pin::Pin;
use std::rc::Rc;
+use std::sync::Arc;
use std::task::Context;
use std::task::Poll;
@@ -192,14 +195,155 @@ impl std::fmt::Display for ModuleType {
// that happened; not only first and final target. It would simplify a lot
// of things throughout the codebase otherwise we may end up requesting
// intermediate redirects from file loader.
-#[derive(Debug, Clone, Eq, PartialEq)]
+// NOTE: This should _not_ be made #[derive(Clone)] unless we take some precautions to avoid excessive string copying.
+#[derive(Debug)]
pub struct ModuleSource {
- pub code: Box<[u8]>,
+ pub code: ModuleCode,
pub module_type: ModuleType,
pub module_url_specified: String,
pub module_url_found: String,
}
+/// Module 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 [`ModuleCode`] created from a `'static` byte array or string must contain ASCII characters.
+///
+/// Examples of ways to construct a [`ModuleCode`] object:
+///
+/// ```rust
+/// # use deno_core::ModuleCode;
+///
+/// let code: ModuleCode = "a string".into();
+/// let code: ModuleCode = b"a string".into();
+/// ```
+#[derive(Debug)]
+pub enum ModuleCode {
+ /// Created from static data -- must be 100% 7-bit ASCII!
+ Static(&'static [u8]),
+
+ /// An owned chunk of data.
+ Owned(Vec<u8>),
+
+ /// Scripts loaded from the `deno_graph` infrastructure.
+ Arc(Arc<str>),
+}
+
+impl ModuleCode {
+ #[inline(always)]
+ pub fn as_bytes(&self) -> &[u8] {
+ match self {
+ Self::Static(b) => b,
+ Self::Owned(b) => b,
+ Self::Arc(s) => s.as_bytes(),
+ }
+ }
+
+ pub fn try_static_ascii(&self) -> Option<&'static [u8]> {
+ match self {
+ Self::Static(b) => Some(b),
+ _ => None,
+ }
+ }
+
+ /// Takes a [`ModuleCode`] value as an owned [`String`]. May be slow.
+ pub fn take_as_string(self) -> String {
+ match self {
+ Self::Static(b) => String::from_utf8(b.to_vec()).unwrap(),
+ Self::Owned(b) => String::from_utf8(b).unwrap(),
+ Self::Arc(s) => (*s).to_owned(),
+ }
+ }
+
+ /// Truncates a `ModuleCode`] 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::Owned(b) => b.truncate(index),
+ // 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(),
+ }
+ }
+}
+
+impl Default for ModuleCode {
+ fn default() -> Self {
+ ModuleCode::Static(&[])
+ }
+}
+
+impl From<Arc<str>> for ModuleCode {
+ #[inline(always)]
+ fn from(value: Arc<str>) -> Self {
+ Self::Arc(value)
+ }
+}
+
+impl From<&Arc<str>> for ModuleCode {
+ #[inline(always)]
+ fn from(value: &Arc<str>) -> Self {
+ Self::Arc(value.clone())
+ }
+}
+
+impl From<Cow<'static, str>> for ModuleCode {
+ #[inline(always)]
+ fn from(value: Cow<'static, str>) -> Self {
+ match value {
+ Cow::Borrowed(b) => b.into(),
+ Cow::Owned(b) => b.into(),
+ }
+ }
+}
+
+impl From<Cow<'static, [u8]>> for ModuleCode {
+ #[inline(always)]
+ fn from(value: Cow<'static, [u8]>) -> Self {
+ match value {
+ Cow::Borrowed(b) => b.into(),
+ Cow::Owned(b) => b.into(),
+ }
+ }
+}
+
+impl From<&'static str> for ModuleCode {
+ #[inline(always)]
+ fn from(value: &'static str) -> Self {
+ assert!(value.is_ascii());
+ ModuleCode::Static(value.as_bytes())
+ }
+}
+
+impl From<String> for ModuleCode {
+ #[inline(always)]
+ fn from(value: String) -> Self {
+ value.into_bytes().into()
+ }
+}
+
+impl From<Vec<u8>> for ModuleCode {
+ #[inline(always)]
+ fn from(value: Vec<u8>) -> Self {
+ ModuleCode::Owned(value)
+ }
+}
+
+impl From<&'static [u8]> for ModuleCode {
+ #[inline(always)]
+ fn from(value: &'static [u8]) -> Self {
+ assert!(value.is_ascii());
+ ModuleCode::Static(value)
+ }
+}
+
+impl<const N: usize> From<&'static [u8; N]> for ModuleCode {
+ #[inline(always)]
+ fn from(value: &'static [u8; N]) -> Self {
+ assert!(value.is_ascii());
+ ModuleCode::Static(value)
+ }
+}
+
pub(crate) type PrepareLoadFuture =
dyn Future<Output = (ModuleLoadId, Result<RecursiveModuleLoad, Error>)>;
pub type ModuleSourceFuture = dyn Future<Output = Result<ModuleSource, Error>>;
@@ -323,7 +467,7 @@ pub(crate) fn resolve_helper(
/// Function that can be passed to the `ExtModuleLoader` that allows to
/// transpile sources before passing to V8.
pub type ExtModuleLoaderCb =
- Box<dyn Fn(&ExtensionFileSource) -> Result<String, Error>>;
+ Box<dyn Fn(&ExtensionFileSource) -> Result<ModuleCode, Error>>;
pub struct ExtModuleLoader {
module_loader: Rc<dyn ModuleLoader>,
@@ -448,7 +592,7 @@ impl ModuleLoader for ExtModuleLoader {
return async move {
let code = result?;
let source = ModuleSource {
- code: code.into_bytes().into_boxed_slice(),
+ code,
module_type: ModuleType::JavaScript,
module_url_specified: specifier.clone(),
module_url_found: specifier.clone(),
@@ -529,7 +673,7 @@ impl ModuleLoader for FsModuleLoader {
let code = std::fs::read(path)?;
let module = ModuleSource {
- code: code.into_boxed_slice(),
+ code: code.into(),
module_type,
module_url_specified: module_specifier.to_string(),
module_url_found: module_specifier.to_string(),
@@ -1002,6 +1146,32 @@ pub(crate) enum ModuleError {
Other(Error),
}
+pub enum ModuleName<'a> {
+ Static(&'static str),
+ NotStatic(&'a str),
+}
+
+impl<'a> ModuleName<'a> {
+ pub fn as_ref(&self) -> &'a str {
+ match self {
+ ModuleName::Static(s) => s,
+ ModuleName::NotStatic(s) => s,
+ }
+ }
+}
+
+impl<'a, S: AsRef<str>> From<&'a S> for ModuleName<'a> {
+ fn from(s: &'a S) -> Self {
+ Self::NotStatic(s.as_ref())
+ }
+}
+
+impl From<&'static str> for ModuleName<'static> {
+ fn from(value: &'static str) -> Self {
+ Self::Static(value)
+ }
+}
+
/// A collection of JS modules.
pub(crate) struct ModuleMap {
// Handling of specifiers and v8 objects
@@ -1326,16 +1496,54 @@ impl ModuleMap {
}
}
- fn new_json_module(
+ fn string_from_code<'a>(
+ scope: &mut v8::HandleScope<'a>,
+ code: &ModuleCode,
+ ) -> Option<v8::Local<'a, v8::String>> {
+ if let Some(code) = code.try_static_ascii() {
+ v8::String::new_external_onebyte_static(scope, code)
+ } else {
+ v8::String::new_from_utf8(
+ scope,
+ code.as_bytes(),
+ v8::NewStringType::Normal,
+ )
+ }
+ }
+
+ fn string_from_module_name<'a>(
+ scope: &mut v8::HandleScope<'a>,
+ name: &ModuleName,
+ ) -> Option<v8::Local<'a, v8::String>> {
+ match name {
+ ModuleName::Static(s) => {
+ assert!(s.is_ascii());
+ v8::String::new_external_onebyte_static(scope, s.as_bytes())
+ }
+ ModuleName::NotStatic(s) => v8::String::new(scope, s),
+ }
+ }
+
+ fn new_json_module<'a, N: Into<ModuleName<'a>>>(
&mut self,
scope: &mut v8::HandleScope,
- name: &str,
- source: &[u8],
+ name: N,
+ source: &ModuleCode,
) -> Result<ModuleId, ModuleError> {
- let name_str = v8::String::new(scope, name).unwrap();
+ // Manual monomorphization (TODO: replace w/momo)
+ self.new_json_module_inner(scope, name.into(), source)
+ }
+
+ fn new_json_module_inner(
+ &mut self,
+ scope: &mut v8::HandleScope,
+ name: ModuleName,
+ source: &ModuleCode,
+ ) -> Result<ModuleId, ModuleError> {
+ let name_str = Self::string_from_module_name(scope, &name).unwrap();
let source_str = v8::String::new_from_utf8(
scope,
- strip_bom(source),
+ strip_bom(source.as_bytes()),
v8::NewStringType::Normal,
)
.unwrap();
@@ -1364,25 +1572,47 @@ impl ModuleMap {
let value_handle = v8::Global::<v8::Value>::new(tc_scope, parsed_json);
self.json_value_store.insert(handle.clone(), value_handle);
- let id =
- self.create_module_info(name, ModuleType::Json, handle, false, vec![]);
+ let id = self.create_module_info(
+ name.as_ref(),
+ ModuleType::Json,
+ handle,
+ false,
+ vec![],
+ );
Ok(id)
}
- // Create and compile an ES module.
- pub(crate) fn new_es_module(
+ /// Create and compile an ES module. Generic interface that can receive either a `&'static str` or a string with a lifetime. Prefer
+ /// to pass `&'static str` as this allows us to use v8 external strings.
+ pub(crate) fn new_es_module<'a, N: Into<ModuleName<'a>>>(
&mut self,
scope: &mut v8::HandleScope,
main: bool,
- name: &str,
- source: &[u8],
+ name: N,
+ source: &ModuleCode,
is_dynamic_import: bool,
) -> Result<ModuleId, ModuleError> {
- let name_str = v8::String::new(scope, name).unwrap();
- let source_str =
- v8::String::new_from_utf8(scope, source, v8::NewStringType::Normal)
- .unwrap();
+ // Manual monomorphization (TODO: replace w/momo)
+ self.new_es_module_inner(
+ scope,
+ main,
+ name.into(),
+ source,
+ is_dynamic_import,
+ )
+ }
+
+ fn new_es_module_inner(
+ &mut self,
+ scope: &mut v8::HandleScope,
+ main: bool,
+ name: ModuleName,
+ source: &ModuleCode,
+ is_dynamic_import: bool,
+ ) -> Result<ModuleId, ModuleError> {
+ let name_str = Self::string_from_module_name(scope, &name).unwrap();
+ let source_str = Self::string_from_code(scope, source).unwrap();
let origin = bindings::module_origin(scope, name_str);
let source = v8::script_compiler::Source::new(source_str, Some(&origin));
@@ -1432,7 +1662,7 @@ impl ModuleMap {
self.snapshot_loaded_and_not_snapshotting,
self.loader.clone(),
&import_specifier,
- name,
+ name.as_ref(),
if is_dynamic_import {
ResolutionKind::DynamicImport
} else {
@@ -1456,7 +1686,7 @@ impl ModuleMap {
if let Some(main_module) = maybe_main_module {
return Err(ModuleError::Other(generic_error(
format!("Trying to create \"main\" module ({:?}), when one already exists ({:?})",
- name,
+ name.as_ref(),
main_module.name,
))));
}
@@ -1464,7 +1694,7 @@ impl ModuleMap {
let handle = v8::Global::<v8::Module>::new(tc_scope, module);
let id = self.create_module_info(
- name,
+ name.as_ref(),
ModuleType::JavaScript,
handle,
main,
@@ -1846,7 +2076,7 @@ import "/a.js";
}
match mock_source_code(&inner.url) {
Some(src) => Poll::Ready(Ok(ModuleSource {
- code: src.0.as_bytes().to_vec().into_boxed_slice(),
+ code: src.0.into(),
module_type: ModuleType::JavaScript,
module_url_specified: inner.url.clone(),
module_url_found: src.1.to_owned(),
@@ -2043,12 +2273,13 @@ import "/a.js";
scope,
true,
&specifier_a,
- br#"
+ &br#"
import { b } from './b.js'
if (b() != 'b') throw Error();
let control = 42;
Deno.core.ops.op_test(control);
- "#,
+ "#
+ .into(),
false,
)
.unwrap();
@@ -2068,7 +2299,7 @@ import "/a.js";
scope,
false,
"file:///b.js",
- b"export function b() { return 'b' }",
+ &b"export function b() { return 'b' }".into(),
false,
)
.unwrap();
@@ -2153,11 +2384,12 @@ import "/a.js";
scope,
true,
&specifier_a,
- br#"
+ &br#"
import jsonData from './b.json' assert {type: "json"};
assert(jsonData.a == "b");
assert(jsonData.c.d == 10);
- "#,
+ "#
+ .into(),
false,
)
.unwrap();
@@ -2175,7 +2407,7 @@ import "/a.js";
.new_json_module(
scope,
"file:///b.json",
- b"{\"a\": \"b\", \"c\": {\"d\": 10}}",
+ &b"{\"a\": \"b\", \"c\": {\"d\": 10}}".into(),
)
.unwrap();
let imports = module_map.get_requested_modules(mod_b).unwrap();
@@ -2285,9 +2517,7 @@ import "/a.js";
let info = ModuleSource {
module_url_specified: specifier.to_string(),
module_url_found: specifier.to_string(),
- code: b"export function b() { return 'b' }"
- .to_vec()
- .into_boxed_slice(),
+ code: b"export function b() { return 'b' }".into(),
module_type: ModuleType::JavaScript,
};
async move { Ok(info) }.boxed()
@@ -2427,7 +2657,7 @@ import "/a.js";
let info = ModuleSource {
module_url_specified: specifier.to_string(),
module_url_found: specifier.to_string(),
- code: code.as_bytes().to_vec().into_boxed_slice(),
+ code: code.into(),
module_type: ModuleType::JavaScript,
};
async move { Ok(info) }.boxed()
@@ -2703,7 +2933,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.to_owned()))
+ .load_main_module(&spec, Some(MAIN_WITH_CODE_SRC.into()))
.boxed_local();
let main_id = futures::executor::block_on(main_id_fut).unwrap();
@@ -2795,17 +3025,13 @@ if (import.meta.url != 'file:///main_with_code.js') throw Error();
"file:///main_module.js" => Ok(ModuleSource {
module_url_specified: "file:///main_module.js".to_string(),
module_url_found: "file:///main_module.js".to_string(),
- code: b"if (!import.meta.main) throw Error();"
- .to_vec()
- .into_boxed_slice(),
+ code: b"if (!import.meta.main) throw Error();".into(),
module_type: ModuleType::JavaScript,
}),
"file:///side_module.js" => Ok(ModuleSource {
module_url_specified: "file:///side_module.js".to_string(),
module_url_found: "file:///side_module.js".to_string(),
- code: b"if (import.meta.main) throw Error();"
- .to_vec()
- .into_boxed_slice(),
+ code: b"if (import.meta.main) throw Error();".into(),
module_type: ModuleType::JavaScript,
}),
_ => unreachable!(),
@@ -2866,7 +3092,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.to_owned()))
+ .load_main_module(&spec, Some(MAIN_WITH_CODE_SRC.into()))
.boxed_local();
let main_id = futures::executor::block_on(main_id_fut).unwrap();
@@ -2906,7 +3132,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.to_owned()))
+ .load_main_module(&spec, Some(MAIN_WITH_CODE_SRC.into()))
.boxed_local();
let main_id = futures::executor::block_on(main_id_fut).unwrap();
@@ -2976,4 +3202,23 @@ if (import.meta.url != 'file:///main_with_code.js') throw Error();
Some("Cannot load extension module from external code".to_string())
);
}
+
+ #[test]
+ fn code_truncate() {
+ let mut s = "123456".to_owned();
+ s.truncate(3);
+
+ let mut code: ModuleCode = "123456".into();
+ code.truncate(3);
+ assert_eq!(s, code.take_as_string());
+
+ let mut code: ModuleCode = "123456".to_owned().into();
+ code.truncate(3);
+ assert_eq!(s, code.take_as_string());
+
+ let arc_str: Arc<str> = "123456".into();
+ let mut code: ModuleCode = arc_str.into();
+ code.truncate(3);
+ assert_eq!(s, code.take_as_string());
+ }
}
diff --git a/core/runtime.rs b/core/runtime.rs
index 7b6dfba92..f9f2e5523 100644
--- a/core/runtime.rs
+++ b/core/runtime.rs
@@ -9,6 +9,7 @@ use crate::extensions::OpEventLoopFn;
use crate::inspector::JsRuntimeInspector;
use crate::module_specifier::ModuleSpecifier;
use crate::modules::ExtModuleLoaderCb;
+use crate::modules::ModuleCode;
use crate::modules::ModuleError;
use crate::modules::ModuleId;
use crate::modules::ModuleLoadId;
@@ -50,6 +51,8 @@ use std::sync::Mutex;
use std::sync::Once;
use std::task::Context;
use std::task::Poll;
+use v8::HandleScope;
+use v8::Local;
use v8::OwnedIsolate;
type PendingOpFuture = OpCall<(RealmIdx, PromiseId, OpId, OpResult)>;
@@ -748,7 +751,7 @@ impl JsRuntime {
realm.execute_script(
self.v8_isolate(),
file_source.specifier,
- &file_source.code.load()?,
+ file_source.code.load()?,
)?;
}
}
@@ -902,7 +905,7 @@ impl JsRuntime {
/// The execution takes place on the current global context, so it is possible
/// to maintain local JS state and invoke this method multiple times.
///
- /// `name` can be a filepath or any other string, eg.
+ /// `name` can be a filepath or any other string, but it is required to be 7-bit ASCII, eg.
///
/// - "/some/file/path.js"
/// - "<anon>"
@@ -911,10 +914,10 @@ impl JsRuntime {
/// The same `name` value can be used for multiple executions.
///
/// `Error` can usually be downcast to `JsError`.
- pub fn execute_script(
+ pub fn execute_script<S: Into<ModuleCode>>(
&mut self,
- name: &str,
- source_code: &str,
+ name: &'static str,
+ source_code: S,
) -> Result<v8::Global<v8::Value>, Error> {
self
.global_realm()
@@ -2056,21 +2059,15 @@ impl JsRuntime {
pub async fn load_main_module(
&mut self,
specifier: &ModuleSpecifier,
- code: Option<String>,
+ code: Option<ModuleCode>,
) -> Result<ModuleId, Error> {
let module_map_rc = Self::module_map(self.v8_isolate());
if let Some(code) = code {
let scope = &mut self.handle_scope();
+ // true for main module
module_map_rc
.borrow_mut()
- .new_es_module(
- scope,
- // main module
- true,
- specifier.as_str(),
- code.as_bytes(),
- false,
- )
+ .new_es_module(scope, true, specifier, &code, false)
.map_err(|e| match e {
ModuleError::Exception(exception) => {
let exception = v8::Local::new(scope, exception);
@@ -2116,21 +2113,15 @@ impl JsRuntime {
pub async fn load_side_module(
&mut self,
specifier: &ModuleSpecifier,
- code: Option<String>,
+ code: Option<ModuleCode>,
) -> Result<ModuleId, Error> {
let module_map_rc = Self::module_map(self.v8_isolate());
if let Some(code) = code {
let scope = &mut self.handle_scope();
+ // false for side module (not main module)
module_map_rc
.borrow_mut()
- .new_es_module(
- scope,
- // not main module
- false,
- specifier.as_str(),
- code.as_bytes(),
- false,
- )
+ .new_es_module(scope, false, specifier, &code, false)
.map_err(|e| match e {
ModuleError::Exception(exception) => {
let exception = v8::Local::new(scope, exception);
@@ -2476,6 +2467,21 @@ impl JsRealm {
self.0.open(scope).global(scope)
}
+ fn string_from_code<'a>(
+ scope: &mut HandleScope<'a>,
+ code: &ModuleCode,
+ ) -> Option<Local<'a, v8::String>> {
+ if let Some(code) = code.try_static_ascii() {
+ v8::String::new_external_onebyte_static(scope, code)
+ } else {
+ v8::String::new_from_utf8(
+ scope,
+ code.as_bytes(),
+ v8::NewStringType::Normal,
+ )
+ }
+ }
+
/// Executes traditional JavaScript code (traditional = not ES modules) in the
/// realm's context.
///
@@ -2488,16 +2494,28 @@ impl JsRealm {
/// The same `name` value can be used for multiple executions.
///
/// `Error` can usually be downcast to `JsError`.
- pub fn execute_script(
+ pub fn execute_script<S: Into<ModuleCode>>(
&self,
isolate: &mut v8::Isolate,
- name: &str,
- source_code: &str,
+ name: &'static str,
+ source_code: S,
+ ) -> Result<v8::Global<v8::Value>, Error> {
+ // Manual monomorphization (TODO: replace w/momo)
+ self.execute_script_inner(isolate, name, source_code.into())
+ }
+
+ fn execute_script_inner(
+ &self,
+ isolate: &mut v8::Isolate,
+ name: &'static str,
+ source_code: ModuleCode,
) -> Result<v8::Global<v8::Value>, Error> {
let scope = &mut self.handle_scope(isolate);
- let source = v8::String::new(scope, source_code).unwrap();
- let name = v8::String::new(scope, name).unwrap();
+ let source = Self::string_from_code(scope, &source_code).unwrap();
+ assert!(name.is_ascii());
+ let name =
+ v8::String::new_external_onebyte_static(scope, name.as_bytes()).unwrap();
let origin = bindings::script_origin(scope, name);
let tc_scope = &mut v8::TryCatch::new(scope);
@@ -3104,7 +3122,8 @@ pub mod tests {
runtime
.execute_script(
"encode_decode_test.js",
- include_str!("encode_decode_test.js"),
+ // Note: We make this to_owned because it contains non-ASCII chars
+ include_str!("encode_decode_test.js").to_owned(),
)
.unwrap();
if let Poll::Ready(Err(_)) = runtime.poll_event_loop(cx, false) {
@@ -3320,7 +3339,7 @@ pub mod tests {
export const a = "b";
export default 1 + 2;
"#
- .to_string();
+ .into();
let module_id = futures::executor::block_on(
runtime.load_main_module(&specifier, Some(source_code)),
@@ -3490,7 +3509,8 @@ pub mod tests {
import {{ f{prev} }} from "file:///{prev}.js";
export function f{i}() {{ return f{prev}() }}
"#
- );
+ )
+ .into();
let id = if main {
futures::executor::block_on(
@@ -3559,8 +3579,7 @@ pub mod tests {
});
let specifier = crate::resolve_url("file:///0.js").unwrap();
- let source_code =
- r#"export function f0() { return "hello world" }"#.to_string();
+ let source_code = r#"export function f0() { return "hello world" }"#.into();
let id = futures::executor::block_on(
runtime.load_side_module(&specifier, Some(source_code)),
)
@@ -3620,7 +3639,7 @@ pub mod tests {
return mod.f400() + " " + Deno.core.ops.op_test();
})();"#
.to_string();
- let val = runtime3.execute_script(".", &source_code).unwrap();
+ let val = runtime3.execute_script(".", source_code).unwrap();
let val = futures::executor::block_on(runtime3.resolve_value(val)).unwrap();
{
let scope = &mut runtime3.handle_scope();
@@ -4163,7 +4182,7 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", {
) -> Pin<Box<ModuleSourceFuture>> {
async move {
Ok(ModuleSource {
- code: b"console.log('hello world');".to_vec().into_boxed_slice(),
+ code: b"console.log('hello world');".into(),
module_url_specified: "file:///main.js".to_string(),
module_url_found: "file:///main.js".to_string(),
module_type: ModuleType::JavaScript,
@@ -4180,7 +4199,7 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", {
});
let specifier = crate::resolve_url("file:///main.js").unwrap();
- let source_code = "Deno.core.print('hello\\n')".to_string();
+ let source_code = "Deno.core.print('hello\\n')".into();
let module_id = futures::executor::block_on(
runtime.load_main_module(&specifier, Some(source_code)),
@@ -4273,7 +4292,7 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", {
.execute_script(
runtime.v8_isolate(),
"",
- &format!(
+ format!(
r#"
globalThis.rejectValue = undefined;
@@ -4282,7 +4301,7 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", {
}});
Deno.core.opAsync("op_void_async").then(() => Promise.reject({number}));
"#
- ),
+ )
)
.unwrap();
}
@@ -4344,7 +4363,7 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", {
async move {
Ok(ModuleSource {
- code: source.as_bytes().to_vec().into_boxed_slice(),
+ code: source.into(),
module_url_specified: "file:///main.js".to_string(),
module_url_found: "file:///main.js".to_string(),
module_type: ModuleType::JavaScript,
@@ -4858,7 +4877,7 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", {
async move {
Ok(ModuleSource {
- code: source.as_bytes().to_vec().into_boxed_slice(),
+ code: source.into(),
module_url_specified: "file:///main.js".to_string(),
module_url_found: "file:///main.js".to_string(),
module_type: ModuleType::JavaScript,
diff --git a/ext/node/lib.rs b/ext/node/lib.rs
index 5684bf172..bde3cfd86 100644
--- a/ext/node/lib.rs
+++ b/ext/node/lib.rs
@@ -390,7 +390,7 @@ pub fn initialize_runtime(
} else {
"undefined".to_string()
};
- let source_code = &format!(
+ let source_code = format!(
r#"(function loadBuiltinNodeModules(nodeGlobalThisName, usesLocalNodeModulesDir, argv0) {{
Deno[Deno.internal].node.initialize(
nodeGlobalThisName,
@@ -403,7 +403,7 @@ pub fn initialize_runtime(
argv0
);
- js_runtime.execute_script(&located_script_name!(), source_code)?;
+ js_runtime.execute_script(located_script_name!(), source_code)?;
Ok(())
}
@@ -417,7 +417,7 @@ pub fn load_cjs_module(
text.replace('\\', r"\\").replace('\'', r"\'")
}
- let source_code = &format!(
+ let source_code = format!(
r#"(function loadCjsModule(moduleName, isMain, inspectBrk) {{
Deno[Deno.internal].node.loadCjsModule(moduleName, isMain, inspectBrk);
}})('{module}', {main}, {inspect_brk});"#,
@@ -426,6 +426,6 @@ pub fn load_cjs_module(
inspect_brk = inspect_brk,
);
- js_runtime.execute_script(&located_script_name!(), source_code)?;
+ js_runtime.execute_script(located_script_name!(), source_code)?;
Ok(())
}
diff --git a/runtime/build.rs b/runtime/build.rs
index 016ece810..ec7c9642c 100644
--- a/runtime/build.rs
+++ b/runtime/build.rs
@@ -17,11 +17,12 @@ mod startup_snapshot {
use deno_core::snapshot_util::*;
use deno_core::Extension;
use deno_core::ExtensionFileSource;
+ use deno_core::ModuleCode;
use std::path::Path;
fn transpile_ts_for_snapshotting(
file_source: &ExtensionFileSource,
- ) -> Result<String, AnyError> {
+ ) -> Result<ModuleCode, AnyError> {
let media_type = MediaType::from_path(Path::new(&file_source.specifier));
let should_transpile = match media_type {
@@ -41,7 +42,7 @@ mod startup_snapshot {
let parsed = deno_ast::parse_module(ParseParams {
specifier: file_source.specifier.to_string(),
- text_info: SourceTextInfo::from_string(code),
+ text_info: SourceTextInfo::from_string(code.take_as_string()),
media_type,
capture_tokens: false,
scope_analysis: false,
@@ -53,7 +54,7 @@ mod startup_snapshot {
..Default::default()
})?;
- Ok(transpiled_source.text)
+ Ok(transpiled_source.text.into())
}
#[derive(Clone)]
diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs
index c6fbb8370..0aa142da8 100644
--- a/runtime/web_worker.rs
+++ b/runtime/web_worker.rs
@@ -25,6 +25,7 @@ use deno_core::CompiledWasmModuleStore;
use deno_core::Extension;
use deno_core::GetErrorClassFn;
use deno_core::JsRuntime;
+use deno_core::ModuleCode;
use deno_core::ModuleId;
use deno_core::ModuleLoader;
use deno_core::ModuleSpecifier;
@@ -575,16 +576,16 @@ impl WebWorker {
"#;
let poll_for_messages_fn = self
.js_runtime
- .execute_script(&located_script_name!(), script)
+ .execute_script(located_script_name!(), script)
.expect("Failed to execute worker bootstrap script");
self.poll_for_messages_fn = Some(poll_for_messages_fn);
}
/// See [JsRuntime::execute_script](deno_core::JsRuntime::execute_script)
- pub fn execute_script(
+ pub fn execute_script<S: Into<ModuleCode>>(
&mut self,
- name: &str,
- source_code: &str,
+ name: &'static str,
+ source_code: S,
) -> Result<(), AnyError> {
self.js_runtime.execute_script(name, source_code)?;
Ok(())
@@ -744,7 +745,7 @@ fn print_worker_error(
pub fn run_web_worker(
worker: WebWorker,
specifier: ModuleSpecifier,
- maybe_source_code: Option<String>,
+ mut maybe_source_code: Option<String>,
preload_module_cb: Arc<ops::worker_host::WorkerEventCb>,
pre_execute_module_cb: Arc<ops::worker_host::WorkerEventCb>,
format_js_error_fn: Option<Arc<FormatJsErrorFn>>,
@@ -772,8 +773,8 @@ pub fn run_web_worker(
};
// Execute provided source code immediately
- let result = if let Some(source_code) = maybe_source_code {
- let r = worker.execute_script(&located_script_name!(), &source_code);
+ let result = if let Some(source_code) = maybe_source_code.take() {
+ let r = worker.execute_script(located_script_name!(), source_code);
worker.start_polling_for_messages();
r
} else {
diff --git a/runtime/worker.rs b/runtime/worker.rs
index a995861c5..a24a22c96 100644
--- a/runtime/worker.rs
+++ b/runtime/worker.rs
@@ -21,6 +21,7 @@ use deno_core::FsModuleLoader;
use deno_core::GetErrorClassFn;
use deno_core::JsRuntime;
use deno_core::LocalInspectorSession;
+use deno_core::ModuleCode;
use deno_core::ModuleId;
use deno_core::ModuleLoader;
use deno_core::ModuleSpecifier;
@@ -364,10 +365,10 @@ impl MainWorker {
}
/// See [JsRuntime::execute_script](deno_core::JsRuntime::execute_script)
- pub fn execute_script(
+ pub fn execute_script<S: Into<ModuleCode>>(
&mut self,
- script_name: &str,
- source_code: &str,
+ script_name: &'static str,
+ source_code: S,
) -> Result<v8::Global<v8::Value>, AnyError> {
self.js_runtime.execute_script(script_name, source_code)
}
@@ -502,7 +503,7 @@ impl MainWorker {
/// Does not poll event loop, and thus not await any of the "load" event handlers.
pub fn dispatch_load_event(
&mut self,
- script_name: &str,
+ script_name: &'static str,
) -> Result<(), AnyError> {
self.execute_script(
script_name,
@@ -519,7 +520,7 @@ impl MainWorker {
/// Does not poll event loop, and thus not await any of the "unload" event handlers.
pub fn dispatch_unload_event(
&mut self,
- script_name: &str,
+ script_name: &'static str,
) -> Result<(), AnyError> {
self.execute_script(
script_name,
@@ -536,7 +537,7 @@ impl MainWorker {
/// running.
pub fn dispatch_beforeunload_event(
&mut self,
- script_name: &str,
+ script_name: &'static str,
) -> Result<bool, AnyError> {
let value = self.js_runtime.execute_script(
script_name,