mirror of
https://github.com/denoland/deno.git
synced 2024-12-22 07:14:47 -05:00
refactor(core): support error stack, remove js_check (#7629)
This commit adds support for stack traces in "deno_core". Implementation of "Display" trait for "JsError" has been updated and in consequence "deno_core::js_check" became obsolete and removed.
This commit is contained in:
parent
cf0c49191e
commit
68fd7a927b
10 changed files with 309 additions and 167 deletions
11
cli/build.rs
11
cli/build.rs
|
@ -2,7 +2,6 @@
|
|||
|
||||
mod op_fetch_asset;
|
||||
|
||||
use deno_core::js_check;
|
||||
use deno_core::JsRuntime;
|
||||
use deno_core::RuntimeOptions;
|
||||
use std::collections::HashMap;
|
||||
|
@ -24,10 +23,12 @@ fn create_snapshot(
|
|||
println!("cargo:rerun-if-changed={}", file.display());
|
||||
let display_path = file.strip_prefix(display_root).unwrap();
|
||||
let display_path_str = display_path.display().to_string();
|
||||
js_check(isolate.execute(
|
||||
&("deno:".to_string() + &display_path_str.replace('\\', "/")),
|
||||
&std::fs::read_to_string(&file).unwrap(),
|
||||
));
|
||||
isolate
|
||||
.execute(
|
||||
&("deno:".to_string() + &display_path_str.replace('\\', "/")),
|
||||
&std::fs::read_to_string(&file).unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let snapshot = isolate.snapshot();
|
||||
|
|
20
cli/js.rs
20
cli/js.rs
|
@ -34,15 +34,17 @@ fn cli_snapshot() {
|
|||
startup_snapshot: Some(deno_isolate_init()),
|
||||
..Default::default()
|
||||
});
|
||||
deno_core::js_check(isolate.execute(
|
||||
"<anon>",
|
||||
r#"
|
||||
isolate
|
||||
.execute(
|
||||
"<anon>",
|
||||
r#"
|
||||
if (!(bootstrap.mainRuntime && bootstrap.workerRuntime)) {
|
||||
throw Error("bad");
|
||||
}
|
||||
console.log("we have console.log!!!");
|
||||
"#,
|
||||
));
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -51,13 +53,15 @@ fn compiler_snapshot() {
|
|||
startup_snapshot: Some(compiler_isolate_init()),
|
||||
..Default::default()
|
||||
});
|
||||
deno_core::js_check(isolate.execute(
|
||||
"<anon>",
|
||||
r#"
|
||||
isolate
|
||||
.execute(
|
||||
"<anon>",
|
||||
r#"
|
||||
if (!(bootstrapCompilerRuntime)) {
|
||||
throw Error("bad");
|
||||
}
|
||||
console.log(`ts version: ${ts.version}`);
|
||||
"#,
|
||||
));
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
|
|
@ -78,6 +78,7 @@ pub fn apply_source_map<G: SourceMapGetter>(
|
|||
start_column,
|
||||
end_column,
|
||||
frames: js_error.frames.clone(),
|
||||
stack: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -204,6 +205,7 @@ mod tests {
|
|||
start_column: Some(16),
|
||||
end_column: None,
|
||||
frames: vec![],
|
||||
stack: None,
|
||||
};
|
||||
let getter = MockSourceMapGetter {};
|
||||
let actual = apply_source_map(&e, &getter);
|
||||
|
|
|
@ -97,6 +97,7 @@ pub struct JsError {
|
|||
pub start_column: Option<i64>, // 0-based
|
||||
pub end_column: Option<i64>, // 0-based
|
||||
pub frames: Vec<JsStackFrame>,
|
||||
pub stack: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
|
@ -166,7 +167,7 @@ impl JsError {
|
|||
|
||||
let msg = v8::Exception::create_message(scope, exception);
|
||||
|
||||
let (message, frames) = if exception.is_native_error() {
|
||||
let (message, frames, stack) = if exception.is_native_error() {
|
||||
// The exception is a JS Error object.
|
||||
let exception: v8::Local<v8::Object> =
|
||||
exception.clone().try_into().unwrap();
|
||||
|
@ -184,7 +185,14 @@ impl JsError {
|
|||
|
||||
// Access error.stack to ensure that prepareStackTrace() has been called.
|
||||
// This should populate error.__callSiteEvals.
|
||||
let _ = get_property(scope, exception, "stack");
|
||||
let stack: Option<v8::Local<v8::String>> =
|
||||
get_property(scope, exception, "stack")
|
||||
.unwrap()
|
||||
.try_into()
|
||||
.ok();
|
||||
let stack = stack.map(|s| s.to_rust_string_lossy(scope));
|
||||
|
||||
// FIXME(bartlmieju): the rest of this function is CLI only
|
||||
|
||||
// Read an array of structured frames from error.__callSiteEvals.
|
||||
let frames_v8 = get_property(scope, exception, "__callSiteEvals");
|
||||
|
@ -300,12 +308,12 @@ impl JsError {
|
|||
});
|
||||
}
|
||||
}
|
||||
(message, frames)
|
||||
(message, frames, stack)
|
||||
} else {
|
||||
// The exception is not a JS Error object.
|
||||
// Get the message given by V8::Exception::create_message(), and provide
|
||||
// empty frames.
|
||||
(msg.get(scope).to_rust_string_lossy(scope), vec![])
|
||||
(msg.get(scope).to_rust_string_lossy(scope), vec![], None)
|
||||
};
|
||||
|
||||
Self {
|
||||
|
@ -321,6 +329,7 @@ impl JsError {
|
|||
start_column: msg.get_start_column().try_into().ok(),
|
||||
end_column: msg.get_end_column().try_into().ok(),
|
||||
frames,
|
||||
stack,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -339,35 +348,24 @@ fn format_source_loc(
|
|||
|
||||
impl Display for JsError {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
if let Some(stack) = &self.stack {
|
||||
let stack_lines = stack.lines();
|
||||
if stack_lines.count() > 1 {
|
||||
return writeln!(f, "{}", stack);
|
||||
}
|
||||
}
|
||||
|
||||
writeln!(f, "{}", self.message)?;
|
||||
if let Some(script_resource_name) = &self.script_resource_name {
|
||||
if self.line_number.is_some() && self.start_column.is_some() {
|
||||
assert!(self.line_number.is_some());
|
||||
assert!(self.start_column.is_some());
|
||||
let source_loc = format_source_loc(
|
||||
script_resource_name,
|
||||
self.line_number.unwrap(),
|
||||
self.start_column.unwrap(),
|
||||
);
|
||||
write!(f, "{}", source_loc)?;
|
||||
}
|
||||
if self.source_line.is_some() {
|
||||
let source_line = self.source_line.as_ref().unwrap();
|
||||
write!(f, "\n{}\n", source_line)?;
|
||||
let mut s = String::new();
|
||||
for i in 0..self.end_column.unwrap() {
|
||||
if i >= self.start_column.unwrap() {
|
||||
s.push('^');
|
||||
} else if source_line.chars().nth(i as usize).unwrap() == '\t' {
|
||||
s.push('\t');
|
||||
} else {
|
||||
s.push(' ');
|
||||
}
|
||||
}
|
||||
writeln!(f, "{}", s)?;
|
||||
writeln!(f, " at {}", source_loc)?;
|
||||
}
|
||||
}
|
||||
|
||||
write!(f, "{}", self.message)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
use deno_core::js_check;
|
||||
use deno_core::BufVec;
|
||||
use deno_core::JsRuntime;
|
||||
use deno_core::Op;
|
||||
|
@ -263,7 +262,7 @@ fn main() {
|
|||
.unwrap();
|
||||
isolate.await
|
||||
};
|
||||
js_check(runtime.block_on(future));
|
||||
runtime.block_on(future).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -5,7 +5,6 @@ extern crate log;
|
|||
|
||||
use deno_core::error::bad_resource_id;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::js_check;
|
||||
use deno_core::BufVec;
|
||||
use deno_core::JsRuntime;
|
||||
use deno_core::OpState;
|
||||
|
@ -196,5 +195,5 @@ fn main() {
|
|||
.unwrap();
|
||||
isolate.await
|
||||
};
|
||||
js_check(runtime.block_on(future));
|
||||
runtime.block_on(future).unwrap();
|
||||
}
|
||||
|
|
|
@ -466,7 +466,6 @@ impl Modules {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::js_check;
|
||||
use crate::JsRuntime;
|
||||
use crate::RuntimeOptions;
|
||||
use futures::future::FutureExt;
|
||||
|
@ -654,7 +653,7 @@ mod tests {
|
|||
let a_id_fut = runtime.load_module(&spec, None);
|
||||
let a_id = futures::executor::block_on(a_id_fut).expect("Failed to load");
|
||||
|
||||
js_check(runtime.mod_evaluate(a_id));
|
||||
runtime.mod_evaluate(a_id).unwrap();
|
||||
let l = loads.lock().unwrap();
|
||||
assert_eq!(
|
||||
l.to_vec(),
|
||||
|
@ -721,7 +720,7 @@ mod tests {
|
|||
let result = runtime.load_module(&spec, None).await;
|
||||
assert!(result.is_ok());
|
||||
let circular1_id = result.unwrap();
|
||||
js_check(runtime.mod_evaluate(circular1_id));
|
||||
runtime.mod_evaluate(circular1_id).unwrap();
|
||||
|
||||
let l = loads.lock().unwrap();
|
||||
assert_eq!(
|
||||
|
@ -798,7 +797,7 @@ mod tests {
|
|||
println!(">> result {:?}", result);
|
||||
assert!(result.is_ok());
|
||||
let redirect1_id = result.unwrap();
|
||||
js_check(runtime.mod_evaluate(redirect1_id));
|
||||
runtime.mod_evaluate(redirect1_id).unwrap();
|
||||
let l = loads.lock().unwrap();
|
||||
assert_eq!(
|
||||
l.to_vec(),
|
||||
|
@ -948,7 +947,7 @@ mod tests {
|
|||
let main_id =
|
||||
futures::executor::block_on(main_id_fut).expect("Failed to load");
|
||||
|
||||
js_check(runtime.mod_evaluate(main_id));
|
||||
runtime.mod_evaluate(main_id).unwrap();
|
||||
|
||||
let l = loads.lock().unwrap();
|
||||
assert_eq!(
|
||||
|
|
322
core/runtime.rs
322
core/runtime.rs
|
@ -332,7 +332,7 @@ impl JsRuntime {
|
|||
pub(crate) fn shared_init(&mut self) {
|
||||
if self.needs_init {
|
||||
self.needs_init = false;
|
||||
js_check(self.execute("core.js", include_str!("core.js")));
|
||||
self.execute("core.js", include_str!("core.js")).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1359,16 +1359,18 @@ pub mod tests {
|
|||
|
||||
runtime.register_op("test", dispatch);
|
||||
|
||||
js_check(runtime.execute(
|
||||
"setup.js",
|
||||
r#"
|
||||
runtime
|
||||
.execute(
|
||||
"setup.js",
|
||||
r#"
|
||||
function assert(cond) {
|
||||
if (!cond) {
|
||||
throw Error("assert");
|
||||
}
|
||||
}
|
||||
"#,
|
||||
));
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(dispatch_count.load(Ordering::Relaxed), 0);
|
||||
(runtime, dispatch_count)
|
||||
}
|
||||
|
@ -1376,9 +1378,10 @@ pub mod tests {
|
|||
#[test]
|
||||
fn test_dispatch() {
|
||||
let (mut runtime, dispatch_count) = setup(Mode::Async);
|
||||
js_check(runtime.execute(
|
||||
"filename.js",
|
||||
r#"
|
||||
runtime
|
||||
.execute(
|
||||
"filename.js",
|
||||
r#"
|
||||
let control = new Uint8Array([42]);
|
||||
Deno.core.send(1, control);
|
||||
async function main() {
|
||||
|
@ -1386,40 +1389,45 @@ pub mod tests {
|
|||
}
|
||||
main();
|
||||
"#,
|
||||
));
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(dispatch_count.load(Ordering::Relaxed), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dispatch_no_zero_copy_buf() {
|
||||
let (mut runtime, dispatch_count) = setup(Mode::AsyncZeroCopy(0));
|
||||
js_check(runtime.execute(
|
||||
"filename.js",
|
||||
r#"
|
||||
runtime
|
||||
.execute(
|
||||
"filename.js",
|
||||
r#"
|
||||
Deno.core.send(1);
|
||||
"#,
|
||||
));
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(dispatch_count.load(Ordering::Relaxed), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dispatch_stack_zero_copy_bufs() {
|
||||
let (mut runtime, dispatch_count) = setup(Mode::AsyncZeroCopy(2));
|
||||
js_check(runtime.execute(
|
||||
"filename.js",
|
||||
r#"
|
||||
runtime
|
||||
.execute(
|
||||
"filename.js",
|
||||
r#"
|
||||
let zero_copy_a = new Uint8Array([0]);
|
||||
let zero_copy_b = new Uint8Array([1]);
|
||||
Deno.core.send(1, zero_copy_a, zero_copy_b);
|
||||
"#,
|
||||
));
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(dispatch_count.load(Ordering::Relaxed), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dispatch_heap_zero_copy_bufs() {
|
||||
let (mut runtime, dispatch_count) = setup(Mode::AsyncZeroCopy(5));
|
||||
js_check(runtime.execute(
|
||||
runtime.execute(
|
||||
"filename.js",
|
||||
r#"
|
||||
let zero_copy_a = new Uint8Array([0]);
|
||||
|
@ -1429,7 +1437,7 @@ pub mod tests {
|
|||
let zero_copy_e = new Uint8Array([4]);
|
||||
Deno.core.send(1, zero_copy_a, zero_copy_b, zero_copy_c, zero_copy_d, zero_copy_e);
|
||||
"#,
|
||||
));
|
||||
).unwrap();
|
||||
assert_eq!(dispatch_count.load(Ordering::Relaxed), 1);
|
||||
}
|
||||
|
||||
|
@ -1438,39 +1446,45 @@ pub mod tests {
|
|||
run_in_task(|cx| {
|
||||
let (mut runtime, dispatch_count) = setup(Mode::Async);
|
||||
|
||||
js_check(runtime.execute(
|
||||
"setup2.js",
|
||||
r#"
|
||||
runtime
|
||||
.execute(
|
||||
"setup2.js",
|
||||
r#"
|
||||
let nrecv = 0;
|
||||
Deno.core.setAsyncHandler(1, (buf) => {
|
||||
nrecv++;
|
||||
});
|
||||
"#,
|
||||
));
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(dispatch_count.load(Ordering::Relaxed), 0);
|
||||
js_check(runtime.execute(
|
||||
"check1.js",
|
||||
r#"
|
||||
runtime
|
||||
.execute(
|
||||
"check1.js",
|
||||
r#"
|
||||
assert(nrecv == 0);
|
||||
let control = new Uint8Array([42]);
|
||||
Deno.core.send(1, control);
|
||||
assert(nrecv == 0);
|
||||
"#,
|
||||
));
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(dispatch_count.load(Ordering::Relaxed), 1);
|
||||
assert!(matches!(runtime.poll_unpin(cx), Poll::Ready(Ok(_))));
|
||||
assert_eq!(dispatch_count.load(Ordering::Relaxed), 1);
|
||||
js_check(runtime.execute(
|
||||
"check2.js",
|
||||
r#"
|
||||
runtime
|
||||
.execute(
|
||||
"check2.js",
|
||||
r#"
|
||||
assert(nrecv == 1);
|
||||
Deno.core.send(1, control);
|
||||
assert(nrecv == 1);
|
||||
"#,
|
||||
));
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(dispatch_count.load(Ordering::Relaxed), 2);
|
||||
assert!(matches!(runtime.poll_unpin(cx), Poll::Ready(Ok(_))));
|
||||
js_check(runtime.execute("check3.js", "assert(nrecv == 2)"));
|
||||
runtime.execute("check3.js", "assert(nrecv == 2)").unwrap();
|
||||
assert_eq!(dispatch_count.load(Ordering::Relaxed), 2);
|
||||
// We are idle, so the next poll should be the last.
|
||||
assert!(matches!(runtime.poll_unpin(cx), Poll::Ready(Ok(_))));
|
||||
|
@ -1481,9 +1495,10 @@ pub mod tests {
|
|||
fn test_poll_async_optional_ops() {
|
||||
run_in_task(|cx| {
|
||||
let (mut runtime, dispatch_count) = setup(Mode::AsyncUnref);
|
||||
js_check(runtime.execute(
|
||||
"check1.js",
|
||||
r#"
|
||||
runtime
|
||||
.execute(
|
||||
"check1.js",
|
||||
r#"
|
||||
Deno.core.setAsyncHandler(1, (buf) => {
|
||||
// This handler will never be called
|
||||
assert(false);
|
||||
|
@ -1491,7 +1506,8 @@ pub mod tests {
|
|||
let control = new Uint8Array([42]);
|
||||
Deno.core.send(1, control);
|
||||
"#,
|
||||
));
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(dispatch_count.load(Ordering::Relaxed), 1);
|
||||
// The above op never finish, but runtime can finish
|
||||
// because the op is an unreffed async op.
|
||||
|
@ -1520,7 +1536,7 @@ pub mod tests {
|
|||
match isolate.execute("infinite_loop.js", "for(;;) {}") {
|
||||
Ok(_) => panic!("execution should be terminated"),
|
||||
Err(e) => {
|
||||
assert_eq!(e.to_string(), "Uncaught Error: execution terminated")
|
||||
assert_eq!(e.to_string(), "Uncaught Error: execution terminated\n")
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1561,9 +1577,10 @@ pub mod tests {
|
|||
#[test]
|
||||
fn overflow_req_sync() {
|
||||
let (mut runtime, dispatch_count) = setup(Mode::OverflowReqSync);
|
||||
js_check(runtime.execute(
|
||||
"overflow_req_sync.js",
|
||||
r#"
|
||||
runtime
|
||||
.execute(
|
||||
"overflow_req_sync.js",
|
||||
r#"
|
||||
let asyncRecv = 0;
|
||||
Deno.core.setAsyncHandler(1, (buf) => { asyncRecv++ });
|
||||
// Large message that will overflow the shared space.
|
||||
|
@ -1574,7 +1591,8 @@ pub mod tests {
|
|||
assert(response[0] == 43);
|
||||
assert(asyncRecv == 0);
|
||||
"#,
|
||||
));
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(dispatch_count.load(Ordering::Relaxed), 1);
|
||||
}
|
||||
|
||||
|
@ -1583,9 +1601,10 @@ pub mod tests {
|
|||
// TODO(ry) This test is quite slow due to memcpy-ing 100MB into JS. We
|
||||
// should optimize this.
|
||||
let (mut runtime, dispatch_count) = setup(Mode::OverflowResSync);
|
||||
js_check(runtime.execute(
|
||||
"overflow_res_sync.js",
|
||||
r#"
|
||||
runtime
|
||||
.execute(
|
||||
"overflow_res_sync.js",
|
||||
r#"
|
||||
let asyncRecv = 0;
|
||||
Deno.core.setAsyncHandler(1, (buf) => { asyncRecv++ });
|
||||
// Large message that will overflow the shared space.
|
||||
|
@ -1596,7 +1615,8 @@ pub mod tests {
|
|||
assert(response[0] == 99);
|
||||
assert(asyncRecv == 0);
|
||||
"#,
|
||||
));
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(dispatch_count.load(Ordering::Relaxed), 1);
|
||||
}
|
||||
|
||||
|
@ -1604,9 +1624,10 @@ pub mod tests {
|
|||
fn overflow_req_async() {
|
||||
run_in_task(|cx| {
|
||||
let (mut runtime, dispatch_count) = setup(Mode::OverflowReqAsync);
|
||||
js_check(runtime.execute(
|
||||
"overflow_req_async.js",
|
||||
r#"
|
||||
runtime
|
||||
.execute(
|
||||
"overflow_req_async.js",
|
||||
r#"
|
||||
let asyncRecv = 0;
|
||||
Deno.core.setAsyncHandler(1, (buf) => {
|
||||
assert(buf.byteLength === 1);
|
||||
|
@ -1620,10 +1641,13 @@ pub mod tests {
|
|||
assert(response == null);
|
||||
assert(asyncRecv == 0);
|
||||
"#,
|
||||
));
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(dispatch_count.load(Ordering::Relaxed), 1);
|
||||
assert!(matches!(runtime.poll_unpin(cx), Poll::Ready(Ok(_))));
|
||||
js_check(runtime.execute("check.js", "assert(asyncRecv == 1);"));
|
||||
runtime
|
||||
.execute("check.js", "assert(asyncRecv == 1);")
|
||||
.unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1633,9 +1657,10 @@ pub mod tests {
|
|||
// TODO(ry) This test is quite slow due to memcpy-ing 100MB into JS. We
|
||||
// should optimize this.
|
||||
let (mut runtime, dispatch_count) = setup(Mode::OverflowResAsync);
|
||||
js_check(runtime.execute(
|
||||
"overflow_res_async.js",
|
||||
r#"
|
||||
runtime
|
||||
.execute(
|
||||
"overflow_res_async.js",
|
||||
r#"
|
||||
let asyncRecv = 0;
|
||||
Deno.core.setAsyncHandler(1, (buf) => {
|
||||
assert(buf.byteLength === 100 * 1024 * 1024);
|
||||
|
@ -1648,10 +1673,13 @@ pub mod tests {
|
|||
assert(response == null);
|
||||
assert(asyncRecv == 0);
|
||||
"#,
|
||||
));
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(dispatch_count.load(Ordering::Relaxed), 1);
|
||||
poll_until_ready(&mut runtime, 3).unwrap();
|
||||
js_check(runtime.execute("check.js", "assert(asyncRecv == 1);"));
|
||||
runtime
|
||||
.execute("check.js", "assert(asyncRecv == 1);")
|
||||
.unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1661,9 +1689,10 @@ pub mod tests {
|
|||
// should optimize this.
|
||||
run_in_task(|_cx| {
|
||||
let (mut runtime, dispatch_count) = setup(Mode::OverflowResAsync);
|
||||
js_check(runtime.execute(
|
||||
"overflow_res_multiple_dispatch_async.js",
|
||||
r#"
|
||||
runtime
|
||||
.execute(
|
||||
"overflow_res_multiple_dispatch_async.js",
|
||||
r#"
|
||||
let asyncRecv = 0;
|
||||
Deno.core.setAsyncHandler(1, (buf) => {
|
||||
assert(buf.byteLength === 100 * 1024 * 1024);
|
||||
|
@ -1679,10 +1708,13 @@ pub mod tests {
|
|||
// are done even if shared space overflows
|
||||
Deno.core.dispatch(1, control);
|
||||
"#,
|
||||
));
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(dispatch_count.load(Ordering::Relaxed), 2);
|
||||
poll_until_ready(&mut runtime, 3).unwrap();
|
||||
js_check(runtime.execute("check.js", "assert(asyncRecv == 2);"));
|
||||
runtime
|
||||
.execute("check.js", "assert(asyncRecv == 2);")
|
||||
.unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1690,9 +1722,10 @@ pub mod tests {
|
|||
fn test_pre_dispatch() {
|
||||
run_in_task(|mut cx| {
|
||||
let (mut runtime, _dispatch_count) = setup(Mode::OverflowResAsync);
|
||||
js_check(runtime.execute(
|
||||
"bad_op_id.js",
|
||||
r#"
|
||||
runtime
|
||||
.execute(
|
||||
"bad_op_id.js",
|
||||
r#"
|
||||
let thrown;
|
||||
try {
|
||||
Deno.core.dispatch(100);
|
||||
|
@ -1701,7 +1734,8 @@ pub mod tests {
|
|||
}
|
||||
assert(String(thrown) === "TypeError: Unknown op id: 100");
|
||||
"#,
|
||||
));
|
||||
)
|
||||
.unwrap();
|
||||
if let Poll::Ready(Err(_)) = runtime.poll_unpin(&mut cx) {
|
||||
unreachable!();
|
||||
}
|
||||
|
@ -1712,7 +1746,9 @@ pub mod tests {
|
|||
fn core_test_js() {
|
||||
run_in_task(|mut cx| {
|
||||
let (mut runtime, _dispatch_count) = setup(Mode::Async);
|
||||
js_check(runtime.execute("core_test.js", include_str!("core_test.js")));
|
||||
runtime
|
||||
.execute("core_test.js", include_str!("core_test.js"))
|
||||
.unwrap();
|
||||
if let Poll::Ready(Err(_)) = runtime.poll_unpin(&mut cx) {
|
||||
unreachable!();
|
||||
}
|
||||
|
@ -1733,10 +1769,12 @@ pub mod tests {
|
|||
fn test_encode_decode() {
|
||||
run_in_task(|mut cx| {
|
||||
let (mut runtime, _dispatch_count) = setup(Mode::Async);
|
||||
js_check(runtime.execute(
|
||||
"encode_decode_test.js",
|
||||
include_str!("encode_decode_test.js"),
|
||||
));
|
||||
runtime
|
||||
.execute(
|
||||
"encode_decode_test.js",
|
||||
include_str!("encode_decode_test.js"),
|
||||
)
|
||||
.unwrap();
|
||||
if let Poll::Ready(Err(_)) = runtime.poll_unpin(&mut cx) {
|
||||
unreachable!();
|
||||
}
|
||||
|
@ -1750,7 +1788,7 @@ pub mod tests {
|
|||
will_snapshot: true,
|
||||
..Default::default()
|
||||
});
|
||||
js_check(runtime.execute("a.js", "a = 1 + 2"));
|
||||
runtime.execute("a.js", "a = 1 + 2").unwrap();
|
||||
runtime.snapshot()
|
||||
};
|
||||
|
||||
|
@ -1759,7 +1797,9 @@ pub mod tests {
|
|||
startup_snapshot: Some(snapshot),
|
||||
..Default::default()
|
||||
});
|
||||
js_check(runtime2.execute("check.js", "if (a != 3) throw Error('x')"));
|
||||
runtime2
|
||||
.execute("check.js", "if (a != 3) throw Error('x')")
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1769,7 +1809,7 @@ pub mod tests {
|
|||
will_snapshot: true,
|
||||
..Default::default()
|
||||
});
|
||||
js_check(runtime.execute("a.js", "a = 1 + 2"));
|
||||
runtime.execute("a.js", "a = 1 + 2").unwrap();
|
||||
let snap: &[u8] = &*runtime.snapshot();
|
||||
Vec::from(snap).into_boxed_slice()
|
||||
};
|
||||
|
@ -1779,7 +1819,9 @@ pub mod tests {
|
|||
startup_snapshot: Some(snapshot),
|
||||
..Default::default()
|
||||
});
|
||||
js_check(runtime2.execute("check.js", "if (a != 3) throw Error('x')"));
|
||||
runtime2
|
||||
.execute("check.js", "if (a != 3) throw Error('x')")
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1926,16 +1968,18 @@ pub mod tests {
|
|||
});
|
||||
runtime.register_op("test", dispatcher);
|
||||
|
||||
js_check(runtime.execute(
|
||||
"setup.js",
|
||||
r#"
|
||||
runtime
|
||||
.execute(
|
||||
"setup.js",
|
||||
r#"
|
||||
function assert(cond) {
|
||||
if (!cond) {
|
||||
throw Error("assert");
|
||||
}
|
||||
}
|
||||
"#,
|
||||
));
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(dispatch_count.load(Ordering::Relaxed), 0);
|
||||
|
||||
|
@ -1972,14 +2016,14 @@ pub mod tests {
|
|||
assert_eq!(imports.len(), 0);
|
||||
}
|
||||
|
||||
js_check(runtime.mod_instantiate(mod_b));
|
||||
runtime.mod_instantiate(mod_b).unwrap();
|
||||
assert_eq!(dispatch_count.load(Ordering::Relaxed), 0);
|
||||
assert_eq!(resolve_count.load(Ordering::SeqCst), 1);
|
||||
|
||||
js_check(runtime.mod_instantiate(mod_a));
|
||||
runtime.mod_instantiate(mod_a).unwrap();
|
||||
assert_eq!(dispatch_count.load(Ordering::Relaxed), 0);
|
||||
|
||||
js_check(runtime.mod_evaluate(mod_a));
|
||||
runtime.mod_evaluate(mod_a).unwrap();
|
||||
assert_eq!(dispatch_count.load(Ordering::Relaxed), 1);
|
||||
}
|
||||
|
||||
|
@ -2024,14 +2068,16 @@ pub mod tests {
|
|||
..Default::default()
|
||||
});
|
||||
|
||||
js_check(runtime.execute(
|
||||
"file:///dyn_import2.js",
|
||||
r#"
|
||||
runtime
|
||||
.execute(
|
||||
"file:///dyn_import2.js",
|
||||
r#"
|
||||
(async () => {
|
||||
await import("/foo.js");
|
||||
})();
|
||||
"#,
|
||||
));
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(count.load(Ordering::Relaxed), 0);
|
||||
// We should get an error here.
|
||||
|
@ -2107,9 +2153,10 @@ pub mod tests {
|
|||
});
|
||||
|
||||
// Dynamically import mod_b
|
||||
js_check(runtime.execute(
|
||||
"file:///dyn_import3.js",
|
||||
r#"
|
||||
runtime
|
||||
.execute(
|
||||
"file:///dyn_import3.js",
|
||||
r#"
|
||||
(async () => {
|
||||
let mod = await import("./b.js");
|
||||
if (mod.b() !== 'b') {
|
||||
|
@ -2122,7 +2169,8 @@ pub mod tests {
|
|||
}
|
||||
})();
|
||||
"#,
|
||||
));
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// First poll runs `prepare_load` hook.
|
||||
assert!(matches!(runtime.poll_unpin(cx), Poll::Pending));
|
||||
|
@ -2148,9 +2196,10 @@ pub mod tests {
|
|||
module_loader: Some(loader),
|
||||
..Default::default()
|
||||
});
|
||||
js_check(runtime.execute(
|
||||
"file:///dyn_import3.js",
|
||||
r#"
|
||||
runtime
|
||||
.execute(
|
||||
"file:///dyn_import3.js",
|
||||
r#"
|
||||
(async () => {
|
||||
let mod = await import("./b.js");
|
||||
if (mod.b() !== 'b') {
|
||||
|
@ -2160,7 +2209,8 @@ pub mod tests {
|
|||
Deno.core.ops();
|
||||
})();
|
||||
"#,
|
||||
));
|
||||
)
|
||||
.unwrap();
|
||||
// First poll runs `prepare_load` hook.
|
||||
let _ = runtime.poll_unpin(cx);
|
||||
assert_eq!(prepare_load_count.load(Ordering::Relaxed), 1);
|
||||
|
@ -2213,8 +2263,94 @@ pub mod tests {
|
|||
)
|
||||
.unwrap();
|
||||
|
||||
js_check(runtime.mod_evaluate(module_id));
|
||||
runtime.mod_evaluate(module_id).unwrap();
|
||||
|
||||
let _snapshot = runtime.snapshot();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_error_without_stack() {
|
||||
let mut runtime = JsRuntime::new(RuntimeOptions::default());
|
||||
// SyntaxError
|
||||
let result = runtime.execute(
|
||||
"error_without_stack.js",
|
||||
r#"
|
||||
function main() {
|
||||
console.log("asdf);
|
||||
}
|
||||
|
||||
main();
|
||||
"#,
|
||||
);
|
||||
let expected_error = r#"Uncaught SyntaxError: Invalid or unexpected token
|
||||
at error_without_stack.js:3:14
|
||||
"#;
|
||||
assert_eq!(result.unwrap_err().to_string(), expected_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_error_stack() {
|
||||
let mut runtime = JsRuntime::new(RuntimeOptions::default());
|
||||
let result = runtime.execute(
|
||||
"error_stack.js",
|
||||
r#"
|
||||
function assert(cond) {
|
||||
if (!cond) {
|
||||
throw Error("assert");
|
||||
}
|
||||
}
|
||||
|
||||
function main() {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
main();
|
||||
"#,
|
||||
);
|
||||
let expected_error = r#"Error: assert
|
||||
at assert (error_stack.js:4:11)
|
||||
at main (error_stack.js:9:3)
|
||||
at error_stack.js:12:1
|
||||
"#;
|
||||
assert_eq!(result.unwrap_err().to_string(), expected_error);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_error_async_stack() {
|
||||
run_in_task(|cx| {
|
||||
let mut runtime = JsRuntime::new(RuntimeOptions::default());
|
||||
runtime
|
||||
.execute(
|
||||
"error_async_stack.js",
|
||||
r#"
|
||||
(async () => {
|
||||
const p = (async () => {
|
||||
await Promise.resolve().then(() => {
|
||||
throw new Error("async");
|
||||
});
|
||||
})();
|
||||
|
||||
try {
|
||||
await p;
|
||||
} catch (error) {
|
||||
console.log(error.stack);
|
||||
throw error;
|
||||
}
|
||||
})();"#,
|
||||
)
|
||||
.unwrap();
|
||||
let expected_error = r#"Error: async
|
||||
at error_async_stack.js:5:13
|
||||
at async error_async_stack.js:4:5
|
||||
at async error_async_stack.js:10:5
|
||||
"#;
|
||||
|
||||
match runtime.poll_unpin(cx) {
|
||||
Poll::Ready(Err(e)) => {
|
||||
assert_eq!(e.to_string(), expected_error);
|
||||
}
|
||||
_ => panic!(),
|
||||
};
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ use deno_core::error::bad_resource_id;
|
|||
use deno_core::error::type_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::futures;
|
||||
use deno_core::js_check;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_core::serde_json::Value;
|
||||
|
@ -50,10 +49,12 @@ pub fn init(isolate: &mut JsRuntime) {
|
|||
println!("cargo:rerun-if-changed={}", file.display());
|
||||
let display_path = file.strip_prefix(display_root).unwrap();
|
||||
let display_path_str = display_path.display().to_string();
|
||||
js_check(isolate.execute(
|
||||
&("deno:".to_string() + &display_path_str.replace('\\', "/")),
|
||||
&std::fs::read_to_string(&file).unwrap(),
|
||||
));
|
||||
isolate
|
||||
.execute(
|
||||
&("deno:".to_string() + &display_path_str.replace('\\', "/")),
|
||||
&std::fs::read_to_string(&file).unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
use deno_core::error::uri_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::js_check;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_core::serde_json::Value;
|
||||
|
@ -55,10 +54,12 @@ pub fn init(isolate: &mut JsRuntime) {
|
|||
println!("cargo:rerun-if-changed={}", file.display());
|
||||
let display_path = file.strip_prefix(display_root).unwrap();
|
||||
let display_path_str = display_path.display().to_string();
|
||||
js_check(isolate.execute(
|
||||
&("deno:".to_string() + &display_path_str.replace('\\', "/")),
|
||||
&std::fs::read_to_string(&file).unwrap(),
|
||||
));
|
||||
isolate
|
||||
.execute(
|
||||
&("deno:".to_string() + &display_path_str.replace('\\', "/")),
|
||||
&std::fs::read_to_string(&file).unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,7 +69,6 @@ pub fn get_declaration() -> PathBuf {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use deno_core::js_check;
|
||||
use deno_core::JsRuntime;
|
||||
use futures::future::lazy;
|
||||
use futures::future::FutureExt;
|
||||
|
@ -92,10 +92,12 @@ mod tests {
|
|||
fn test_abort_controller() {
|
||||
run_in_task(|mut cx| {
|
||||
let mut isolate = setup();
|
||||
js_check(isolate.execute(
|
||||
"abort_controller_test.js",
|
||||
include_str!("abort_controller_test.js"),
|
||||
));
|
||||
isolate
|
||||
.execute(
|
||||
"abort_controller_test.js",
|
||||
include_str!("abort_controller_test.js"),
|
||||
)
|
||||
.unwrap();
|
||||
if let Poll::Ready(Err(_)) = isolate.poll_unpin(&mut cx) {
|
||||
unreachable!();
|
||||
}
|
||||
|
@ -106,7 +108,9 @@ mod tests {
|
|||
fn test_event() {
|
||||
run_in_task(|mut cx| {
|
||||
let mut isolate = setup();
|
||||
js_check(isolate.execute("event_test.js", include_str!("event_test.js")));
|
||||
isolate
|
||||
.execute("event_test.js", include_str!("event_test.js"))
|
||||
.unwrap();
|
||||
if let Poll::Ready(Err(_)) = isolate.poll_unpin(&mut cx) {
|
||||
unreachable!();
|
||||
}
|
||||
|
@ -121,8 +125,8 @@ mod tests {
|
|||
if let Err(error) = result {
|
||||
let error_string = error.to_string();
|
||||
// Test that the script specifier is a URL: `deno:<repo-relative path>`.
|
||||
assert!(error_string.starts_with("deno:op_crates/web/01_event.js"));
|
||||
assert!(error_string.contains("Uncaught TypeError"));
|
||||
assert!(error_string.contains("deno:op_crates/web/01_event.js"));
|
||||
assert!(error_string.contains("TypeError"));
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
|
@ -136,12 +140,9 @@ mod tests {
|
|||
fn test_event_target() {
|
||||
run_in_task(|mut cx| {
|
||||
let mut isolate = setup();
|
||||
js_check(
|
||||
isolate.execute(
|
||||
"event_target_test.js",
|
||||
include_str!("event_target_test.js"),
|
||||
),
|
||||
);
|
||||
isolate
|
||||
.execute("event_target_test.js", include_str!("event_target_test.js"))
|
||||
.unwrap();
|
||||
if let Poll::Ready(Err(_)) = isolate.poll_unpin(&mut cx) {
|
||||
unreachable!();
|
||||
}
|
||||
|
@ -152,10 +153,12 @@ mod tests {
|
|||
fn test_text_encoding() {
|
||||
run_in_task(|mut cx| {
|
||||
let mut isolate = setup();
|
||||
js_check(isolate.execute(
|
||||
"text_encoding_test.js",
|
||||
include_str!("text_encoding_test.js"),
|
||||
));
|
||||
isolate
|
||||
.execute(
|
||||
"text_encoding_test.js",
|
||||
include_str!("text_encoding_test.js"),
|
||||
)
|
||||
.unwrap();
|
||||
if let Poll::Ready(Err(_)) = isolate.poll_unpin(&mut cx) {
|
||||
unreachable!();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue