1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-21 15:04:11 -05:00

refactor: unify JavaScript script execution method (#11043)

This commit renames "JsRuntime::execute" to "JsRuntime::execute_script". Additionally
same renames were applied to methods on "deno_runtime::Worker" and
"deno_runtime::WebWorker".

A new macro was added to "deno_core" called "located_script_name" which
returns the name of Rust file alongside line no and col no of that call site.
This macro is useful in combination with "JsRuntime::execute_script"
and allows to provide accurate place where "one-off" JavaScript scripts
are executed for internal runtime functions.

Co-authored-by: Nayeem Rahman <nayeemrmn99@gmail.com>
This commit is contained in:
Bartek Iwańczuk 2021-06-22 01:45:41 +02:00 committed by GitHub
parent a5eb2dfc93
commit 9105892ec8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 148 additions and 102 deletions

View file

@ -71,6 +71,6 @@ pub fn bench_js_async(
}
async fn inner_async(src: &str, runtime: &mut JsRuntime) {
runtime.execute("inner_loop", src).unwrap();
runtime.execute_script("inner_loop", src).unwrap();
runtime.run_event_loop(false).await.unwrap();
}

View file

@ -29,7 +29,7 @@ fn create_snapshot(
let display_path = file.strip_prefix(display_root).unwrap();
let display_path_str = display_path.display().to_string();
js_runtime
.execute(
.execute_script(
&("deno:".to_string() + &display_path_str.replace('\\', "/")),
&std::fs::read_to_string(&file).unwrap(),
)

View file

@ -20,6 +20,7 @@ use crate::tsc::ResolveArgs;
use deno_core::error::anyhow;
use deno_core::error::custom_error;
use deno_core::error::AnyError;
use deno_core::located_script_name;
use deno_core::op_sync;
use deno_core::resolve_url;
use deno_core::serde::de;
@ -2264,7 +2265,7 @@ fn start(
let init_config = json!({ "debug": debug, "rootUri": root_uri });
let init_src = format!("globalThis.serverInit({});", init_config);
runtime.execute("[native code]", &init_src)
runtime.execute_script(&located_script_name!(), &init_src)
}
#[derive(Debug, Serialize)]
@ -2649,7 +2650,7 @@ pub fn request(
};
let mark = performance.mark("request", Some(request_params.clone()));
let request_src = format!("globalThis.serverRequest({});", request_params);
runtime.execute("[native_code]", &request_src)?;
runtime.execute_script(&located_script_name!(), &request_src)?;
let op_state = runtime.op_state();
let mut op_state = op_state.borrow_mut();

View file

@ -55,6 +55,7 @@ use deno_core::error::generic_error;
use deno_core::error::AnyError;
use deno_core::futures::future::FutureExt;
use deno_core::futures::Future;
use deno_core::located_script_name;
use deno_core::resolve_url_or_path;
use deno_core::serde_json;
use deno_core::serde_json::json;
@ -554,9 +555,15 @@ async fn eval_command(
program_state.file_fetcher.insert_cached(file);
debug!("main_module {}", &main_module);
worker.execute_module(&main_module).await?;
worker.execute("window.dispatchEvent(new Event('load'))")?;
worker.execute_script(
&located_script_name!(),
"window.dispatchEvent(new Event('load'))",
)?;
worker.run_event_loop(false).await?;
worker.execute("window.dispatchEvent(new Event('unload'))")?;
worker.execute_script(
&located_script_name!(),
"window.dispatchEvent(new Event('unload'))",
)?;
Ok(())
}
@ -794,9 +801,15 @@ async fn run_from_stdin(flags: Flags) -> Result<(), AnyError> {
debug!("main_module {}", main_module);
worker.execute_module(&main_module).await?;
worker.execute("window.dispatchEvent(new Event('load'))")?;
worker.execute_script(
&located_script_name!(),
"window.dispatchEvent(new Event('load'))",
)?;
worker.run_event_loop(false).await?;
worker.execute("window.dispatchEvent(new Event('unload'))")?;
worker.execute_script(
&located_script_name!(),
"window.dispatchEvent(new Event('unload'))",
)?;
Ok(())
}
@ -866,9 +879,15 @@ async fn run_with_watch(flags: Flags, script: String) -> Result<(), AnyError> {
);
debug!("main_module {}", main_module);
worker.execute_module(&main_module).await?;
worker.execute("window.dispatchEvent(new Event('load'))")?;
worker.execute_script(
&located_script_name!(),
"window.dispatchEvent(new Event('load'))",
)?;
worker.run_event_loop(false).await?;
worker.execute("window.dispatchEvent(new Event('unload'))")?;
worker.execute_script(
&located_script_name!(),
"window.dispatchEvent(new Event('unload'))",
)?;
Ok(())
}
};
@ -909,11 +928,17 @@ async fn run_command(flags: Flags, script: String) -> Result<(), AnyError> {
debug!("main_module {}", main_module);
worker.execute_module(&main_module).await?;
worker.execute("window.dispatchEvent(new Event('load'))")?;
worker.execute_script(
&located_script_name!(),
"window.dispatchEvent(new Event('load'))",
)?;
worker
.run_event_loop(maybe_coverage_collector.is_none())
.await?;
worker.execute("window.dispatchEvent(new Event('unload'))")?;
worker.execute_script(
&located_script_name!(),
"window.dispatchEvent(new Event('unload'))",
)?;
if let Some(coverage_collector) = maybe_coverage_collector.as_mut() {
worker

View file

@ -13,6 +13,7 @@ use deno_core::error::uri_error;
use deno_core::error::AnyError;
use deno_core::error::Context;
use deno_core::futures::FutureExt;
use deno_core::located_script_name;
use deno_core::resolve_url;
use deno_core::serde::Deserialize;
use deno_core::serde::Serialize;
@ -262,9 +263,15 @@ pub async fn run(
}
worker.bootstrap(&options);
worker.execute_module(&main_module).await?;
worker.execute("window.dispatchEvent(new Event('load'))")?;
worker.execute_script(
&located_script_name!(),
"window.dispatchEvent(new Event('load'))",
)?;
worker.run_event_loop(true).await?;
worker.execute("window.dispatchEvent(new Event('unload'))")?;
worker.execute_script(
&located_script_name!(),
"window.dispatchEvent(new Event('unload'))",
)?;
std::process::exit(0);
}

View file

@ -1,3 +0,0 @@
const dir = Deno.makeTempDirSync();
Deno.chdir(dir);
Deno.removeSync(dir);

View file

@ -5635,25 +5635,6 @@ console.log("finish");
assert!(stderr.contains("BadResource"));
}
#[cfg(not(windows))]
#[test]
fn should_not_panic_on_not_found_cwd() {
let output = util::deno_cmd()
.current_dir(util::root_path())
.arg("run")
.arg("--allow-write")
.arg("--allow-read")
.arg("cli/tests/dont_panic_not_found_cwd.ts")
.stderr(std::process::Stdio::piped())
.spawn()
.unwrap()
.wait_with_output()
.unwrap();
assert!(!output.status.success());
let stderr = std::str::from_utf8(&output.stderr).unwrap().trim();
assert!(stderr.contains("Failed to get current working directory"));
}
#[cfg(windows)]
// Clippy suggests to remove the `NoStd` prefix from all variants. I disagree.
#[allow(clippy::enum_variant_names)]

View file

@ -16,6 +16,7 @@ use deno_core::futures::future;
use deno_core::futures::stream;
use deno_core::futures::FutureExt;
use deno_core::futures::StreamExt;
use deno_core::located_script_name;
use deno_core::serde_json::json;
use deno_core::url::Url;
use deno_core::ModuleSpecifier;
@ -302,7 +303,10 @@ pub async fn run_test_file(
let execute_result = worker.execute_module(&main_module).await;
execute_result?;
worker.execute("window.dispatchEvent(new Event('load'))")?;
worker.execute_script(
&located_script_name!(),
"window.dispatchEvent(new Event('load'))",
)?;
let execute_result = worker.execute_module(&test_module).await;
execute_result?;
@ -310,7 +314,10 @@ pub async fn run_test_file(
worker
.run_event_loop(maybe_coverage_collector.is_none())
.await?;
worker.execute("window.dispatchEvent(new Event('unload'))")?;
worker.execute_script(
&located_script_name!(),
"window.dispatchEvent(new Event('unload'))",
)?;
if let Some(coverage_collector) = maybe_coverage_collector.as_mut() {
worker

View file

@ -10,6 +10,7 @@ use deno_core::error::anyhow;
use deno_core::error::bail;
use deno_core::error::AnyError;
use deno_core::error::Context;
use deno_core::located_script_name;
use deno_core::op_sync;
use deno_core::resolve_url_or_path;
use deno_core::serde::de;
@ -556,9 +557,9 @@ pub fn exec(request: Request) -> Result<Response, AnyError> {
let exec_source = format!("globalThis.exec({})", request_str);
runtime
.execute("[native code]", startup_source)
.execute_script(&located_script_name!(), startup_source)
.context("Could not properly start the compiler runtime.")?;
runtime.execute("[native_code]", &exec_source)?;
runtime.execute_script(&located_script_name!(), &exec_source)?;
let op_state = runtime.op_state();
let mut op_state = op_state.borrow_mut();
@ -672,7 +673,7 @@ mod tests {
..Default::default()
});
js_runtime
.execute(
.execute_script(
"<anon>",
r#"
if (!(startup)) {

View file

@ -27,7 +27,7 @@ fn main() {
// contains a Deno.core object with several functions for interacting with it.
// You can find its definition in core.js.
runtime
.execute(
.execute_script(
"<usage>",
r#"
// Print helper function, calling Deno.core.print()

View file

@ -218,7 +218,7 @@ fn main() {
let future = async move {
js_runtime
.execute(
.execute_script(
"http_bench_json_ops.js",
include_str!("http_bench_json_ops.js"),
)

View file

@ -90,6 +90,22 @@ pub fn v8_version() -> &'static str {
v8::V8::get_version()
}
/// A helper macro that will return a call site in Rust code. Should be
/// used when executing internal one-line scripts for JsRuntime lifecycle.
///
/// Returns a string in form of: "[deno:<filename>:<line>:<column>]"
#[macro_export]
macro_rules! located_script_name {
() => {
format!(
"[deno:{}:{}:{}]",
std::file!(),
std::line!(),
std::column!()
);
};
}
#[cfg(test)]
mod tests {
use super::*;

View file

@ -1008,7 +1008,7 @@ mod tests {
runtime.sync_ops_cache();
runtime
.execute(
.execute_script(
"setup.js",
r#"
function assert(cond) {
@ -1116,7 +1116,7 @@ mod tests {
});
runtime
.execute(
.execute_script(
"file:///dyn_import2.js",
r#"
(async () => {
@ -1201,7 +1201,7 @@ mod tests {
// Dynamically import mod_b
runtime
.execute(
.execute_script(
"file:///dyn_import3.js",
r#"
(async () => {
@ -1251,7 +1251,7 @@ mod tests {
});
runtime.sync_ops_cache();
runtime
.execute(
.execute_script(
"file:///dyn_import3.js",
r#"
(async () => {

View file

@ -119,7 +119,7 @@ mod tests {
runtime.register_op("op_throw", op_async(op_throw));
runtime.sync_ops_cache();
runtime
.execute(
.execute_script(
"<init>",
r#"
async function f1() {

View file

@ -381,7 +381,7 @@ impl JsRuntime {
for (filename, source) in js_files {
let source = source()?;
// TODO(@AaronO): use JsRuntime::execute_static() here to move src off heap
self.execute(filename, &source)?;
self.execute_script(filename, &source)?;
}
}
// Restore extensions
@ -441,7 +441,9 @@ impl JsRuntime {
/// Ensures core.js has the latest op-name to op-id mappings
pub fn sync_ops_cache(&mut self) {
self.execute("<anon>", "Deno.core.syncOpsCache()").unwrap()
self
.execute_script("<anon>", "Deno.core.syncOpsCache()")
.unwrap()
}
/// Returns the runtime's op state, which can be used to maintain ops
@ -452,23 +454,31 @@ impl JsRuntime {
state.op_state.clone()
}
/// Executes traditional JavaScript code (traditional = not ES modules)
/// Executes traditional JavaScript code (traditional = not ES modules).
///
/// 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.
///
/// - "/some/file/path.js"
/// - "<anon>"
/// - "[native code]"
///
/// The same `name` value can be used for multiple executions.
///
/// `AnyError` can be downcast to a type that exposes additional information
/// about the V8 exception. By default this type is `JsError`, however it may
/// be a different type if `RuntimeOptions::js_error_create_fn` has been set.
pub fn execute(
pub fn execute_script(
&mut self,
js_filename: &str,
js_source: &str,
name: &str,
source_code: &str,
) -> Result<(), AnyError> {
let scope = &mut self.handle_scope();
let source = v8::String::new(scope, js_source).unwrap();
let name = v8::String::new(scope, js_filename).unwrap();
let source = v8::String::new(scope, source_code).unwrap();
let name = v8::String::new(scope, name).unwrap();
let origin = bindings::script_origin(scope, name);
let tc_scope = &mut v8::TryCatch::new(scope);
@ -1470,7 +1480,7 @@ pub mod tests {
runtime.sync_ops_cache();
runtime
.execute(
.execute_script(
"setup.js",
r#"
function assert(cond) {
@ -1489,7 +1499,7 @@ pub mod tests {
fn test_dispatch() {
let (mut runtime, dispatch_count) = setup(Mode::Async);
runtime
.execute(
.execute_script(
"filename.js",
r#"
let control = 42;
@ -1508,7 +1518,7 @@ pub mod tests {
fn test_dispatch_no_zero_copy_buf() {
let (mut runtime, dispatch_count) = setup(Mode::AsyncZeroCopy(false));
runtime
.execute(
.execute_script(
"filename.js",
r#"
Deno.core.opAsync("op_test");
@ -1522,7 +1532,7 @@ pub mod tests {
fn test_dispatch_stack_zero_copy_bufs() {
let (mut runtime, dispatch_count) = setup(Mode::AsyncZeroCopy(true));
runtime
.execute(
.execute_script(
"filename.js",
r#"
let zero_copy_a = new Uint8Array([0]);
@ -1550,7 +1560,7 @@ pub mod tests {
});
// Rn an infinite loop, which should be terminated.
match isolate.execute("infinite_loop.js", "for(;;) {}") {
match isolate.execute_script("infinite_loop.js", "for(;;) {}") {
Ok(_) => panic!("execution should be terminated"),
Err(e) => {
assert_eq!(e.to_string(), "Uncaught Error: execution terminated")
@ -1564,7 +1574,7 @@ pub mod tests {
// Verify that the isolate usable again.
isolate
.execute("simple.js", "1 + 1")
.execute_script("simple.js", "1 + 1")
.expect("execution should be possible again");
terminator_thread.join().unwrap();
@ -1589,7 +1599,7 @@ pub mod tests {
run_in_task(|mut cx| {
let (mut runtime, _dispatch_count) = setup(Mode::Async);
runtime
.execute(
.execute_script(
"bad_op_id.js",
r#"
let thrown;
@ -1612,7 +1622,7 @@ pub mod tests {
fn syntax_error() {
let mut runtime = JsRuntime::new(Default::default());
let src = "hocuspocus(";
let r = runtime.execute("i.js", src);
let r = runtime.execute_script("i.js", src);
let e = r.unwrap_err();
let js_error = e.downcast::<JsError>().unwrap();
assert_eq!(js_error.end_column, Some(11));
@ -1623,7 +1633,7 @@ pub mod tests {
run_in_task(|mut cx| {
let (mut runtime, _dispatch_count) = setup(Mode::Async);
runtime
.execute(
.execute_script(
"encode_decode_test.js",
include_str!("encode_decode_test.js"),
)
@ -1639,7 +1649,7 @@ pub mod tests {
run_in_task(|mut cx| {
let (mut runtime, _dispatch_count) = setup(Mode::Async);
runtime
.execute(
.execute_script(
"serialize_deserialize_test.js",
include_str!("serialize_deserialize_test.js"),
)
@ -1672,7 +1682,7 @@ pub mod tests {
runtime.register_op("op_err", op_sync(op_err));
runtime.sync_ops_cache();
runtime
.execute(
.execute_script(
"error_builder_test.js",
include_str!("error_builder_test.js"),
)
@ -1690,7 +1700,7 @@ pub mod tests {
will_snapshot: true,
..Default::default()
});
runtime.execute("a.js", "a = 1 + 2").unwrap();
runtime.execute_script("a.js", "a = 1 + 2").unwrap();
runtime.snapshot()
};
@ -1700,7 +1710,7 @@ pub mod tests {
..Default::default()
});
runtime2
.execute("check.js", "if (a != 3) throw Error('x')")
.execute_script("check.js", "if (a != 3) throw Error('x')")
.unwrap();
}
@ -1711,7 +1721,7 @@ pub mod tests {
will_snapshot: true,
..Default::default()
});
runtime.execute("a.js", "a = 1 + 2").unwrap();
runtime.execute_script("a.js", "a = 1 + 2").unwrap();
let snap: &[u8] = &*runtime.snapshot();
Vec::from(snap).into_boxed_slice()
};
@ -1722,7 +1732,7 @@ pub mod tests {
..Default::default()
});
runtime2
.execute("check.js", "if (a != 3) throw Error('x')")
.execute_script("check.js", "if (a != 3) throw Error('x')")
.unwrap();
}
@ -1746,7 +1756,7 @@ pub mod tests {
},
);
let err = runtime
.execute(
.execute_script(
"script name",
r#"let s = ""; while(true) { s += "Hello"; }"#,
)
@ -1798,7 +1808,7 @@ pub mod tests {
);
let err = runtime
.execute(
.execute_script(
"script name",
r#"let s = ""; while(true) { s += "Hello"; }"#,
)
@ -1866,7 +1876,7 @@ pub mod tests {
fn test_error_without_stack() {
let mut runtime = JsRuntime::new(RuntimeOptions::default());
// SyntaxError
let result = runtime.execute(
let result = runtime.execute_script(
"error_without_stack.js",
r#"
function main() {
@ -1884,7 +1894,7 @@ main();
#[test]
fn test_error_stack() {
let mut runtime = JsRuntime::new(RuntimeOptions::default());
let result = runtime.execute(
let result = runtime.execute_script(
"error_stack.js",
r#"
function assert(cond) {
@ -1912,7 +1922,7 @@ main();
run_in_task(|cx| {
let mut runtime = JsRuntime::new(RuntimeOptions::default());
runtime
.execute(
.execute_script(
"error_async_stack.js",
r#"
(async () => {
@ -1950,7 +1960,7 @@ main();
let mut runtime = JsRuntime::new(RuntimeOptions::default());
// Call non-existent op so we get error from `core.js`
let error = runtime
.execute(
.execute_script(
"core_js_stack_frame.js",
"Deno.core.opSync('non_existent');",
)
@ -1967,6 +1977,6 @@ main();
..Default::default()
};
let mut runtime = JsRuntime::new(options);
runtime.execute("<none>", "").unwrap();
runtime.execute_script("<none>", "").unwrap();
}
}

View file

@ -22,7 +22,7 @@ fn create_snapshot(
let display_path = file.strip_prefix(display_root).unwrap();
let display_path_str = display_path.display().to_string();
js_runtime
.execute(
.execute_script(
&("deno:".to_string() + &display_path_str.replace('\\', "/")),
&std::fs::read_to_string(&file).unwrap(),
)

View file

@ -22,7 +22,7 @@ mod tests {
..Default::default()
});
js_runtime
.execute(
.execute_script(
"<anon>",
r#"
if (!(bootstrap.mainRuntime && bootstrap.workerRuntime)) {

View file

@ -8,16 +8,15 @@ use crate::permissions::Permissions;
use crate::tokio_util::create_basic_runtime;
use deno_broadcast_channel::InMemoryBroadcastChannel;
use deno_core::error::AnyError;
use deno_core::error::Context as ErrorContext;
use deno_core::futures::channel::mpsc;
use deno_core::futures::future::poll_fn;
use deno_core::futures::future::FutureExt;
use deno_core::futures::stream::StreamExt;
use deno_core::located_script_name;
use deno_core::serde::Deserialize;
use deno_core::serde::Serialize;
use deno_core::serde_json;
use deno_core::serde_json::json;
use deno_core::url::Url;
use deno_core::v8;
use deno_core::Extension;
use deno_core::GetErrorClassFn;
@ -370,17 +369,17 @@ impl WebWorker {
runtime_options_str, self.name, options.use_deno_namespace, self.id
);
self
.execute(&script)
.execute_script(&located_script_name!(), &script)
.expect("Failed to execute worker bootstrap script");
}
/// Same as execute2() but the filename defaults to "$CWD/__anonymous__".
pub fn execute(&mut self, js_source: &str) -> Result<(), AnyError> {
let path = env::current_dir()
.context("Failed to get current working directory")?
.join("__anonymous__");
let url = Url::from_file_path(path).unwrap();
self.js_runtime.execute(url.as_str(), js_source)
/// See [JsRuntime::execute_script](deno_core::JsRuntime::execute_script)
pub fn execute_script(
&mut self,
name: &str,
source_code: &str,
) -> Result<(), AnyError> {
self.js_runtime.execute_script(name, source_code)
}
/// Loads and instantiates specified JavaScript module.
@ -493,7 +492,7 @@ pub fn run_web_worker(
// Execute provided source code immediately
let result = if let Some(source_code) = maybe_source_code {
worker.execute(&source_code)
worker.execute_script(&located_script_name!(), &source_code)
} else {
// TODO(bartlomieju): add "type": "classic", ie. ability to load
// script instead of module
@ -586,7 +585,7 @@ mod tests {
console.log("after postMessage");
}
"#;
worker.execute(source).unwrap();
worker.execute_script("a", source).unwrap();
let handle = worker.thread_safe_handle();
handle_sender.send(handle).unwrap();
let r = tokio_util::run_basic(worker.run_event_loop(false));
@ -633,7 +632,9 @@ mod tests {
let join_handle = std::thread::spawn(move || {
let mut worker = create_test_web_worker();
worker.execute("onmessage = () => { close(); }").unwrap();
worker
.execute_script("a", "onmessage = () => { close(); }")
.unwrap();
let handle = worker.thread_safe_handle();
handle_sender.send(handle).unwrap();
let r = tokio_util::run_basic(worker.run_event_loop(false));

View file

@ -7,10 +7,10 @@ use crate::ops;
use crate::permissions::Permissions;
use deno_broadcast_channel::InMemoryBroadcastChannel;
use deno_core::error::AnyError;
use deno_core::error::Context as ErrorContext;
use deno_core::futures::future::poll_fn;
use deno_core::futures::stream::StreamExt;
use deno_core::futures::Future;
use deno_core::located_script_name;
use deno_core::serde_json;
use deno_core::serde_json::json;
use deno_core::url::Url;
@ -177,17 +177,17 @@ impl MainWorker {
serde_json::to_string_pretty(&runtime_options).unwrap()
);
self
.execute(&script)
.execute_script(&located_script_name!(), &script)
.expect("Failed to execute bootstrap script");
}
/// Same as execute2() but the filename defaults to "$CWD/__anonymous__".
pub fn execute(&mut self, js_source: &str) -> Result<(), AnyError> {
let path = env::current_dir()
.context("Failed to get current working directory")?
.join("__anonymous__");
let url = Url::from_file_path(path).unwrap();
self.js_runtime.execute(url.as_str(), js_source)
/// See [JsRuntime::execute_script](deno_core::JsRuntime::execute_script)
pub fn execute_script(
&mut self,
name: &str,
source_code: &str,
) -> Result<(), AnyError> {
self.js_runtime.execute_script(name, source_code)
}
/// Loads and instantiates specified JavaScript module.