refactor(core): rename CoreIsolate to JsRuntime (#7373)

deno_core/
- rename core_isolate.rs to runtime.rs
- rename CoreIsolate to JsRuntime
- rename JSError to JsError
- rename JSStackFrame to JsStackFrame

cli/
- update references from deno_core::CoreIsolate to deno_core::JsRuntime
- rename deno_core::JSError to deno_core::JsError
- rename fmt_errors::JSError to fmt_errors::JsError
This commit is contained in:
Bartek Iwańczuk 2020-09-06 21:44:29 +02:00 committed by GitHub
parent 16a9c92aba
commit f57a2c1e85
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 274 additions and 278 deletions

View file

@ -4,7 +4,7 @@ mod op_fetch_asset;
use deno_core::js_check;
use deno_core::BasicState;
use deno_core::CoreIsolate;
use deno_core::JsRuntime;
use deno_core::OpRegistry;
use deno_core::StartupData;
use std::collections::HashMap;
@ -13,7 +13,7 @@ use std::path::Path;
use std::path::PathBuf;
fn create_snapshot(
mut isolate: CoreIsolate,
mut isolate: JsRuntime,
snapshot_path: &Path,
files: Vec<String>,
) {
@ -32,7 +32,7 @@ fn create_snapshot(
fn create_runtime_snapshot(snapshot_path: &Path, files: Vec<String>) {
let state = BasicState::new();
let isolate = CoreIsolate::new(state, StartupData::None, true);
let isolate = JsRuntime::new(state, StartupData::None, true);
create_snapshot(isolate, snapshot_path, files);
}
@ -71,7 +71,7 @@ fn create_compiler_snapshot(
op_fetch_asset::op_fetch_asset(custom_libs),
);
let isolate = CoreIsolate::new(state, StartupData::None, true);
let isolate = JsRuntime::new(state, StartupData::None, true);
create_snapshot(isolate, snapshot_path, files);
}

View file

@ -3,11 +3,11 @@
//! There are many types of errors in Deno:
//! - ErrBox: a generic boxed object. This is the super type of all
//! errors handled in Rust.
//! - JSError: a container for the error message and stack trace for exceptions
//! - JsError: a container for the error message and stack trace for exceptions
//! thrown in JavaScript code. We use this to pretty-print stack traces.
//! - Diagnostic: these are errors that originate in TypeScript's compiler.
//! They're similar to JSError, in that they have line numbers.
//! But Diagnostics are compile-time type errors, whereas JSErrors are runtime
//! They're similar to JsError, in that they have line numbers.
//! But Diagnostics are compile-time type errors, whereas JsErrors are runtime
//! exceptions.
use crate::import_map::ImportMapError;

View file

@ -103,13 +103,13 @@ fn format_maybe_source_line(
format!("\n{}{}\n{}{}", indent, source_line, indent, color_underline)
}
/// Wrapper around deno_core::JSError which provides color to_string.
/// Wrapper around deno_core::JsError which provides color to_string.
#[derive(Debug)]
pub struct JSError(deno_core::JSError);
pub struct JsError(deno_core::JsError);
impl JSError {
impl JsError {
pub fn create(
core_js_error: deno_core::JSError,
core_js_error: deno_core::JsError,
source_map_getter: &impl SourceMapGetter,
) -> ErrBox {
let core_js_error = apply_source_map(&core_js_error, source_map_getter);
@ -118,14 +118,14 @@ impl JSError {
}
}
impl Deref for JSError {
type Target = deno_core::JSError;
impl Deref for JsError {
type Target = deno_core::JsError;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl fmt::Display for JSError {
impl fmt::Display for JsError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut formatted_frames = self.0.formatted_frames.clone();
@ -170,7 +170,7 @@ impl fmt::Display for JSError {
}
}
impl Error for JSError {}
impl Error for JsError {}
#[cfg(test)]
mod tests {

View file

@ -96,7 +96,7 @@ impl GlobalState {
}
/// This function is called when new module load is
/// initialized by the CoreIsolate. Its resposibility is to collect
/// initialized by the JsRuntime. Its resposibility is to collect
/// all dependencies and if it is required then also perform TS typecheck
/// and traspilation.
pub async fn prepare_module_load(
@ -180,7 +180,7 @@ impl GlobalState {
}
// TODO(bartlomieju): this method doesn't need to be async anymore
/// This method is used after `prepare_module_load` finishes and CoreIsolate
/// This method is used after `prepare_module_load` finishes and JsRuntime
/// starts loading source and executing source code. This method shouldn't
/// perform any IO (besides $DENO_DIR) and only operate on sources collected
/// during `prepare_module_load`.

View file

@ -373,10 +373,10 @@ impl DenoInspector {
const CONTEXT_GROUP_ID: i32 = 1;
pub fn new(
isolate: &mut deno_core::CoreIsolate,
isolate: &mut deno_core::JsRuntime,
host: SocketAddr,
) -> Box<Self> {
let core_state_rc = deno_core::CoreIsolate::state(isolate);
let core_state_rc = deno_core::JsRuntime::state(isolate);
let core_state = core_state_rc.borrow();
let scope = &mut v8::HandleScope::new(&mut **isolate);

View file

@ -13,7 +13,7 @@ pub static UNSTABLE_NS_LIB: &str = include_str!("dts/lib.deno.unstable.d.ts");
#[test]
fn cli_snapshot() {
let mut isolate = deno_core::CoreIsolate::new(
let mut isolate = deno_core::JsRuntime::new(
deno_core::BasicState::new(),
deno_core::StartupData::Snapshot(deno_core::Snapshot::Static(CLI_SNAPSHOT)),
false,
@ -31,7 +31,7 @@ fn cli_snapshot() {
#[test]
fn compiler_snapshot() {
let mut isolate = deno_core::CoreIsolate::new(
let mut isolate = deno_core::JsRuntime::new(
deno_core::BasicState::new(),
deno_core::StartupData::Snapshot(deno_core::Snapshot::Static(
COMPILER_SNAPSHOT,

View file

@ -79,9 +79,9 @@ use crate::permissions::Permissions;
use crate::tsc::TargetLib;
use crate::worker::MainWorker;
use deno_core::v8_set_flags;
use deno_core::CoreIsolate;
use deno_core::Deps;
use deno_core::ErrBox;
use deno_core::JsRuntime;
use deno_core::ModuleSpecifier;
use deno_doc as doc;
use deno_doc::parser::DocFileLoader;
@ -217,7 +217,7 @@ async fn print_file_info(
{
output.map = source_map.filename.to_str().map(|s| s.to_owned());
}
let es_state_rc = CoreIsolate::state(&worker.isolate);
let es_state_rc = JsRuntime::state(&worker.isolate);
let es_state = es_state_rc.borrow();
if let Some(deps) = es_state.modules.deps(&module_specifier) {

View file

@ -81,7 +81,7 @@ fn get_asset(name: &str) -> Option<&'static str> {
}
/// Warning: Returns a non-JSON op dispatcher. Must be manually attached to
/// CoreIsolate.
/// JsRuntime.
pub fn op_fetch_asset<H: std::hash::BuildHasher, S>(
custom_assets: HashMap<String, PathBuf, H>,
) -> impl Fn(Rc<S>, BufVec) -> Op {

View file

@ -1,6 +1,6 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use crate::fmt_errors::JSError;
use crate::fmt_errors::JsError;
use crate::global_state::GlobalState;
use crate::ops::io::get_stdio;
use crate::permissions::Permissions;
@ -249,7 +249,7 @@ fn serialize_worker_event(event: WorkerEvent) -> Value {
}
});
if let Ok(js_error) = error.downcast::<JSError>() {
if let Ok(js_error) = error.downcast::<JsError>() {
serialized_error = json!({
"type": "terminalError",
"error": {
@ -271,7 +271,7 @@ fn serialize_worker_event(event: WorkerEvent) -> Value {
}
});
if let Ok(js_error) = error.downcast::<JSError>() {
if let Ok(js_error) = error.downcast::<JsError>() {
serialized_error = json!({
"type": "error",
"error": {

View file

@ -1,5 +1,5 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
//! This mod provides functions to remap a deno_core::deno_core::JSError based on a source map
//! This mod provides functions to remap a deno_core::deno_core::JsError based on a source map
use sourcemap::SourceMap;
use std::collections::HashMap;
use std::str;
@ -18,13 +18,13 @@ pub trait SourceMapGetter {
/// find a SourceMap.
pub type CachedMaps = HashMap<String, Option<SourceMap>>;
/// Apply a source map to a deno_core::JSError, returning a JSError where file
/// Apply a source map to a deno_core::JsError, returning a JsError where file
/// names and line/column numbers point to the location in the original source,
/// rather than the transpiled source code.
pub fn apply_source_map<G: SourceMapGetter>(
js_error: &deno_core::JSError,
js_error: &deno_core::JsError,
getter: &G,
) -> deno_core::JSError {
) -> deno_core::JsError {
// Note that js_error.frames has already been source mapped in
// prepareStackTrace().
let mut mappings_map: CachedMaps = HashMap::new();
@ -67,7 +67,7 @@ pub fn apply_source_map<G: SourceMapGetter>(
_ => js_error.source_line.clone(),
};
deno_core::JSError {
deno_core::JsError {
message: js_error.message.clone(),
source_line,
script_resource_name,
@ -194,7 +194,7 @@ mod tests {
#[test]
fn apply_source_map_line() {
let e = deno_core::JSError {
let e = deno_core::JsError {
message: "TypeError: baz".to_string(),
source_line: Some("foo".to_string()),
script_resource_name: Some("foo_bar.ts".to_string()),

View file

@ -7,7 +7,7 @@ use crate::disk_cache::DiskCache;
use crate::file_fetcher::SourceFile;
use crate::file_fetcher::SourceFileFetcher;
use crate::flags::Flags;
use crate::fmt_errors::JSError;
use crate::fmt_errors::JsError;
use crate::global_state::GlobalState;
use crate::module_graph::ModuleGraph;
use crate::module_graph::ModuleGraphLoader;
@ -1191,9 +1191,9 @@ async fn create_runtime_module_graph(
}
/// Because TS compiler can raise runtime error, we need to
/// manually convert formatted JSError into and ErrBox.
/// manually convert formatted JsError into and ErrBox.
fn js_error_to_errbox(error: ErrBox) -> ErrBox {
match error.downcast::<JSError>() {
match error.downcast::<JsError>() {
Ok(js_error) => {
let msg = format!("Error in TS compiler:\n{}", js_error);
ErrBox::error(msg)

View file

@ -1,14 +1,14 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use crate::fmt_errors::JSError;
use crate::fmt_errors::JsError;
use crate::global_state::GlobalState;
use crate::inspector::DenoInspector;
use crate::ops;
use crate::ops::io::get_stdio;
use crate::startup_data;
use crate::state::State;
use deno_core::CoreIsolate;
use deno_core::ErrBox;
use deno_core::JsRuntime;
use deno_core::ModuleId;
use deno_core::ModuleSpecifier;
use deno_core::StartupData;
@ -91,7 +91,7 @@ fn create_channels() -> (WorkerChannelsInternal, WorkerHandle) {
/// - `WebWorker`
pub struct Worker {
pub name: String,
pub isolate: deno_core::CoreIsolate,
pub isolate: deno_core::JsRuntime,
pub inspector: Option<Box<DenoInspector>>,
pub state: Rc<State>,
pub waker: AtomicWaker,
@ -105,7 +105,7 @@ impl Worker {
startup_data: StartupData,
state: &Rc<State>,
) -> Self {
let mut isolate = deno_core::CoreIsolate::new_with_loader(
let mut isolate = deno_core::JsRuntime::new_with_loader(
state.clone(),
state.clone(),
startup_data,
@ -114,10 +114,10 @@ impl Worker {
{
let global_state = state.global_state.clone();
let core_state_rc = CoreIsolate::state(&isolate);
let core_state_rc = JsRuntime::state(&isolate);
let mut core_state = core_state_rc.borrow_mut();
core_state.set_js_error_create_fn(move |core_js_error| {
JSError::create(core_js_error, &global_state.ts_compiler)
JsError::create(core_js_error, &global_state.ts_compiler)
});
}
@ -235,7 +235,7 @@ impl Future for Worker {
}
impl Deref for Worker {
type Target = deno_core::CoreIsolate;
type Target = deno_core::JsRuntime;
fn deref(&self) -> &Self::Target {
&self.isolate
}

View file

@ -8,9 +8,9 @@ The main dependency of this crate is
bindings.
This Rust crate contains the essential V8 bindings for Deno's command-line
interface (Deno CLI). The main abstraction here is the Isolate which provides a
way to execute JavaScript. The Isolate is modeled as a
`Future<Item=(), Error=JSError>` which completes once all of its ops have
interface (Deno CLI). The main abstraction here is the JsRuntime which provides
a way to execute JavaScript. The JsRuntime is modeled as a
`Future<Item=(), Error=JsError>` which completes once all of its ops have
completed.
In order to bind Rust functions into JavaScript, use the `Deno.core.dispatch()`

View file

@ -1,9 +1,9 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use crate::CoreIsolate;
use crate::CoreIsolateState;
use crate::ErrBox;
use crate::JSError;
use crate::JsError;
use crate::JsRuntime;
use crate::JsRuntimeState;
use crate::Op;
use crate::OpId;
use crate::ZeroCopyBuf;
@ -239,7 +239,7 @@ pub extern "C" fn host_import_module_dynamically_callback(
let resolver_handle = v8::Global::new(scope, resolver);
{
let state_rc = CoreIsolate::state(scope);
let state_rc = JsRuntime::state(scope);
let mut state = state_rc.borrow_mut();
state.dyn_import_cb(resolver_handle, &specifier_str, &referrer_name_str);
}
@ -253,7 +253,7 @@ pub extern "C" fn host_initialize_import_meta_object_callback(
meta: v8::Local<v8::Object>,
) {
let scope = &mut unsafe { v8::CallbackScope::new(context) };
let state_rc = CoreIsolate::state(scope);
let state_rc = JsRuntime::state(scope);
let state = state_rc.borrow();
let id = module.get_identity_hash();
@ -273,7 +273,7 @@ pub extern "C" fn host_initialize_import_meta_object_callback(
pub extern "C" fn promise_reject_callback(message: v8::PromiseRejectMessage) {
let scope = &mut unsafe { v8::CallbackScope::new(&message) };
let state_rc = CoreIsolate::state(scope);
let state_rc = JsRuntime::state(scope);
let mut state = state_rc.borrow_mut();
let promise = message.get_promise();
@ -355,7 +355,7 @@ fn recv(
args: v8::FunctionCallbackArguments,
_rv: v8::ReturnValue,
) {
let state_rc = CoreIsolate::state(scope);
let state_rc = JsRuntime::state(scope);
let mut state = state_rc.borrow_mut();
let cb = match v8::Local::<v8::Function>::try_from(args.get(0)) {
@ -376,7 +376,7 @@ fn send<'s>(
args: v8::FunctionCallbackArguments,
mut rv: v8::ReturnValue,
) {
let state_rc = CoreIsolate::state(scope);
let state_rc = JsRuntime::state(scope);
let state = state_rc.borrow_mut();
let op_id = match v8::Local::<v8::Integer>::try_from(args.get(0))
@ -443,7 +443,7 @@ fn set_macrotask_callback(
args: v8::FunctionCallbackArguments,
_rv: v8::ReturnValue,
) {
let state_rc = CoreIsolate::state(scope);
let state_rc = JsRuntime::state(scope);
let mut state = state_rc.borrow_mut();
let cb = match v8::Local::<v8::Function>::try_from(args.get(0)) {
@ -592,8 +592,8 @@ fn format_error(
args: v8::FunctionCallbackArguments,
mut rv: v8::ReturnValue,
) {
let e = JSError::from_v8_exception(scope, args.get(0));
let state_rc = CoreIsolate::state(scope);
let e = JsError::from_v8_exception(scope, args.get(0));
let state_rc = JsRuntime::state(scope);
let state = state_rc.borrow();
let e = (state.js_error_create_fn)(e);
let e = e.to_string();
@ -684,9 +684,9 @@ fn shared_getter(
_args: v8::PropertyCallbackArguments,
mut rv: v8::ReturnValue,
) {
let state_rc = CoreIsolate::state(scope);
let state_rc = JsRuntime::state(scope);
let mut state = state_rc.borrow_mut();
let CoreIsolateState {
let JsRuntimeState {
shared_ab, shared, ..
} = &mut *state;
@ -712,7 +712,7 @@ pub fn module_resolve_callback<'s>(
) -> Option<v8::Local<'s, v8::Module>> {
let scope = &mut unsafe { v8::CallbackScope::new(context) };
let state_rc = CoreIsolate::state(scope);
let state_rc = JsRuntime::state(scope);
let mut state = state_rc.borrow_mut();
let referrer_id = referrer.get_identity_hash();

View file

@ -170,7 +170,7 @@ SharedQueue Binary Layout
function handleAsyncMsgFromRust(opId, buf) {
if (buf) {
// This is the overflow_response case of deno::Isolate::poll().
// This is the overflow_response case of deno::JsRuntime::poll().
asyncHandlers[opId](buf);
} else {
while (true) {

View file

@ -110,23 +110,23 @@ impl From<Box<dyn AnyError>> for ErrBox {
}
}
/// A `JSError` represents an exception coming from V8, with stack frames and
/// line numbers. The deno_cli crate defines another `JSError` type, which wraps
/// A `JsError` represents an exception coming from V8, with stack frames and
/// line numbers. The deno_cli crate defines another `JsError` type, which wraps
/// the one defined here, that adds source map support and colorful formatting.
#[derive(Debug, PartialEq, Clone)]
pub struct JSError {
pub struct JsError {
pub message: String,
pub source_line: Option<String>,
pub script_resource_name: Option<String>,
pub line_number: Option<i64>,
pub start_column: Option<i64>, // 0-based
pub end_column: Option<i64>, // 0-based
pub frames: Vec<JSStackFrame>,
pub frames: Vec<JsStackFrame>,
pub formatted_frames: Vec<String>,
}
#[derive(Debug, PartialEq, Clone)]
pub struct JSStackFrame {
pub struct JsStackFrame {
pub type_name: Option<String>,
pub function_name: Option<String>,
pub method_name: Option<String>,
@ -152,7 +152,7 @@ fn get_property<'a>(
object.get(scope, key.into())
}
impl JSError {
impl JsError {
pub(crate) fn create(js_error: Self) -> ErrBox {
js_error.into()
}
@ -199,7 +199,7 @@ impl JSError {
formatted_frames_v8.and_then(|a| a.try_into().ok());
// Convert them into Vec<JSStack> and Vec<String> respectively.
let mut frames: Vec<JSStackFrame> = vec![];
let mut frames: Vec<JsStackFrame> = vec![];
let mut formatted_frames: Vec<String> = vec![];
if let (Some(frames_v8), Some(formatted_frames_v8)) =
(frames_v8, formatted_frames_v8)
@ -292,7 +292,7 @@ impl JSError {
.try_into()
.ok();
let promise_index = promise_index.map(|n| n.value());
frames.push(JSStackFrame {
frames.push(JsStackFrame {
type_name,
function_name,
method_name,
@ -343,7 +343,7 @@ impl JSError {
}
}
impl Error for JSError {}
impl Error for JsError {}
fn format_source_loc(
file_name: &str,
@ -355,7 +355,7 @@ fn format_source_loc(
format!("{}:{}:{}", file_name, line_number, column_number)
}
impl fmt::Display for JSError {
impl fmt::Display for JsError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(script_resource_name) = &self.script_resource_name {
if self.line_number.is_some() && self.start_column.is_some() {

View file

@ -4,7 +4,7 @@ extern crate log;
use deno_core::js_check;
use deno_core::BasicState;
use deno_core::BufVec;
use deno_core::CoreIsolate;
use deno_core::JsRuntime;
use deno_core::Op;
use deno_core::OpRegistry;
use deno_core::Script;
@ -77,7 +77,7 @@ impl From<Record> for RecordBuf {
}
}
fn create_isolate() -> CoreIsolate {
fn create_isolate() -> JsRuntime {
let state = BasicState::new();
register_op_bin_sync(&state, "listen", op_listen);
register_op_bin_sync(&state, "close", op_close);
@ -90,7 +90,7 @@ fn create_isolate() -> CoreIsolate {
filename: "http_bench_bin_ops.js",
});
CoreIsolate::new(state, startup_data, false)
JsRuntime::new(state, startup_data, false)
}
fn op_listen(

View file

@ -4,8 +4,8 @@ extern crate log;
use deno_core::js_check;
use deno_core::BasicState;
use deno_core::BufVec;
use deno_core::CoreIsolate;
use deno_core::ErrBox;
use deno_core::JsRuntime;
use deno_core::OpRegistry;
use deno_core::Script;
use deno_core::StartupData;
@ -41,7 +41,7 @@ impl log::Log for Logger {
fn flush(&self) {}
}
fn create_isolate() -> CoreIsolate {
fn create_isolate() -> JsRuntime {
let state = BasicState::new();
state.register_op_json_sync("listen", op_listen);
state.register_op_json_sync("close", op_close);
@ -54,7 +54,7 @@ fn create_isolate() -> CoreIsolate {
filename: "http_bench_json_ops.js",
});
CoreIsolate::new(state, startup_data, false)
JsRuntime::new(state, startup_data, false)
}
fn op_listen(

View file

@ -10,7 +10,6 @@ extern crate log;
mod basic_state;
mod bindings;
mod core_isolate;
mod errors;
mod flags;
mod module_specifier;
@ -19,23 +18,16 @@ mod normalize_path;
mod ops;
pub mod plugin_api;
mod resources;
mod runtime;
mod shared_queue;
mod zero_copy_buf;
pub use rusty_v8 as v8;
pub use crate::basic_state::BasicState;
pub use crate::core_isolate::js_check;
pub use crate::core_isolate::CoreIsolate;
pub use crate::core_isolate::CoreIsolateState;
pub use crate::core_isolate::GetErrorClassFn;
pub use crate::core_isolate::HeapLimits;
pub use crate::core_isolate::Script;
pub use crate::core_isolate::Snapshot;
pub use crate::core_isolate::StartupData;
pub use crate::errors::AnyError;
pub use crate::errors::ErrBox;
pub use crate::errors::JSError;
pub use crate::errors::JsError;
pub use crate::flags::v8_set_flags;
pub use crate::module_specifier::ModuleResolutionError;
pub use crate::module_specifier::ModuleSpecifier;
@ -55,6 +47,14 @@ pub use crate::ops::OpRegistry;
pub use crate::ops::OpRouter;
pub use crate::ops::OpTable;
pub use crate::resources::ResourceTable;
pub use crate::runtime::js_check;
pub use crate::runtime::GetErrorClassFn;
pub use crate::runtime::HeapLimits;
pub use crate::runtime::JsRuntime;
pub use crate::runtime::JsRuntimeState;
pub use crate::runtime::Script;
pub use crate::runtime::Snapshot;
pub use crate::runtime::StartupData;
pub use crate::zero_copy_buf::BufVec;
pub use crate::zero_copy_buf::ZeroCopyBuf;
pub use serde_json;

View file

@ -84,7 +84,7 @@ pub trait ModuleLoader {
///
/// For example implementor might download multiple modules in
/// parallel and transpile them to final JS sources before
/// yielding control back to Isolate.
/// yielding control back to the runtime.
///
/// It's not required to implement this method.
fn prepare_load(
@ -99,7 +99,7 @@ pub trait ModuleLoader {
}
/// Placeholder structure used when creating
/// isolate that doesn't support module loading.
/// a runtime that doesn't support module loading.
pub(crate) struct NoopModuleLoader;
impl ModuleLoader for NoopModuleLoader {
@ -138,8 +138,7 @@ pub enum LoadState {
Done,
}
/// This future is used to implement parallel async module loading without
/// that is consumed by the isolate.
/// This future is used to implement parallel async module loading.
pub struct RecursiveModuleLoad {
kind: Kind,
// TODO(bartlomieju): in future this value should
@ -547,7 +546,7 @@ mod tests {
use super::*;
use crate::js_check;
use crate::BasicState;
use crate::CoreIsolate;
use crate::JsRuntime;
use crate::StartupData;
use futures::future::FutureExt;
use std::error::Error;
@ -560,7 +559,7 @@ mod tests {
// even though we are only using poll() in these tests and not Tokio, we must
// nevertheless run it in the tokio executor. Ideally run_in_task can be
// removed in the future.
use crate::core_isolate::tests::run_in_task;
use crate::runtime::tests::run_in_task;
#[derive(Default)]
struct MockLoader {
@ -725,17 +724,17 @@ mod tests {
fn test_recursive_load() {
let loader = MockLoader::new();
let loads = loader.loads.clone();
let mut isolate = CoreIsolate::new_with_loader(
let mut runtime = JsRuntime::new_with_loader(
loader,
BasicState::new(),
StartupData::None,
false,
);
let spec = ModuleSpecifier::resolve_url("file:///a.js").unwrap();
let a_id_fut = isolate.load_module(&spec, None);
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(isolate.mod_evaluate(a_id));
js_check(runtime.mod_evaluate(a_id));
let l = loads.lock().unwrap();
assert_eq!(
l.to_vec(),
@ -747,7 +746,7 @@ mod tests {
]
);
let state_rc = CoreIsolate::state(&isolate);
let state_rc = JsRuntime::state(&runtime);
let state = state_rc.borrow();
let modules = &state.modules;
assert_eq!(modules.get_id("file:///a.js"), Some(a_id));
@ -792,7 +791,7 @@ mod tests {
fn test_circular_load() {
let loader = MockLoader::new();
let loads = loader.loads.clone();
let mut isolate = CoreIsolate::new_with_loader(
let mut runtime = JsRuntime::new_with_loader(
loader,
BasicState::new(),
StartupData::None,
@ -801,10 +800,10 @@ mod tests {
let fut = async move {
let spec = ModuleSpecifier::resolve_url("file:///circular1.js").unwrap();
let result = isolate.load_module(&spec, None).await;
let result = runtime.load_module(&spec, None).await;
assert!(result.is_ok());
let circular1_id = result.unwrap();
js_check(isolate.mod_evaluate(circular1_id));
js_check(runtime.mod_evaluate(circular1_id));
let l = loads.lock().unwrap();
assert_eq!(
@ -816,7 +815,7 @@ mod tests {
]
);
let state_rc = CoreIsolate::state(&isolate);
let state_rc = JsRuntime::state(&runtime);
let state = state_rc.borrow();
let modules = &state.modules;
@ -870,7 +869,7 @@ mod tests {
fn test_redirect_load() {
let loader = MockLoader::new();
let loads = loader.loads.clone();
let mut isolate = CoreIsolate::new_with_loader(
let mut runtime = JsRuntime::new_with_loader(
loader,
BasicState::new(),
StartupData::None,
@ -879,11 +878,11 @@ mod tests {
let fut = async move {
let spec = ModuleSpecifier::resolve_url("file:///redirect1.js").unwrap();
let result = isolate.load_module(&spec, None).await;
let result = runtime.load_module(&spec, None).await;
println!(">> result {:?}", result);
assert!(result.is_ok());
let redirect1_id = result.unwrap();
js_check(isolate.mod_evaluate(redirect1_id));
js_check(runtime.mod_evaluate(redirect1_id));
let l = loads.lock().unwrap();
assert_eq!(
l.to_vec(),
@ -894,7 +893,7 @@ mod tests {
]
);
let state_rc = CoreIsolate::state(&isolate);
let state_rc = JsRuntime::state(&runtime);
let state = state_rc.borrow();
let modules = &state.modules;
@ -939,14 +938,14 @@ mod tests {
run_in_task(|mut cx| {
let loader = MockLoader::new();
let loads = loader.loads.clone();
let mut isolate = CoreIsolate::new_with_loader(
let mut runtime = JsRuntime::new_with_loader(
loader,
BasicState::new(),
StartupData::None,
false,
);
let spec = ModuleSpecifier::resolve_url("file:///main.js").unwrap();
let mut recursive_load = isolate.load_module(&spec, None).boxed_local();
let mut recursive_load = runtime.load_module(&spec, None).boxed_local();
let result = recursive_load.poll_unpin(&mut cx);
assert!(result.is_pending());
@ -989,14 +988,14 @@ mod tests {
fn loader_disappears_after_error() {
run_in_task(|mut cx| {
let loader = MockLoader::new();
let mut isolate = CoreIsolate::new_with_loader(
let mut runtime = JsRuntime::new_with_loader(
loader,
BasicState::new(),
StartupData::None,
false,
);
let spec = ModuleSpecifier::resolve_url("file:///bad_import.js").unwrap();
let mut load_fut = isolate.load_module(&spec, None).boxed_local();
let mut load_fut = runtime.load_module(&spec, None).boxed_local();
let result = load_fut.poll_unpin(&mut cx);
if let Poll::Ready(Err(err)) = result {
assert_eq!(
@ -1022,7 +1021,7 @@ mod tests {
fn recursive_load_main_with_code() {
let loader = MockLoader::new();
let loads = loader.loads.clone();
let mut isolate = CoreIsolate::new_with_loader(
let mut runtime = JsRuntime::new_with_loader(
loader,
BasicState::new(),
StartupData::None,
@ -1033,13 +1032,13 @@ mod tests {
// The behavior should be very similar to /a.js.
let spec =
ModuleSpecifier::resolve_url("file:///main_with_code.js").unwrap();
let main_id_fut = isolate
let main_id_fut = runtime
.load_module(&spec, Some(MAIN_WITH_CODE_SRC.to_owned()))
.boxed_local();
let main_id =
futures::executor::block_on(main_id_fut).expect("Failed to load");
js_check(isolate.mod_evaluate(main_id));
js_check(runtime.mod_evaluate(main_id));
let l = loads.lock().unwrap();
assert_eq!(
@ -1047,7 +1046,7 @@ mod tests {
vec!["file:///b.js", "file:///c.js", "file:///d.js"]
);
let state_rc = CoreIsolate::state(&isolate);
let state_rc = JsRuntime::state(&runtime);
let state = state_rc.borrow();
let modules = &state.modules;

View file

@ -1,10 +1,5 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
// Do not add any dependency to modules.rs!
// modules.rs is complex and should remain decoupled from isolate.rs to keep the
// Isolate struct from becoming too bloating for users who do not need
// asynchronous module loading.
use rusty_v8 as v8;
use crate::bindings;
@ -25,7 +20,7 @@ use crate::ops::*;
use crate::shared_queue::SharedQueue;
use crate::shared_queue::RECOMMENDED_SIZE;
use crate::ErrBox;
use crate::JSError;
use crate::JsError;
use crate::OpRouter;
use futures::stream::FuturesUnordered;
use futures::stream::StreamExt;
@ -97,7 +92,7 @@ impl StartupData<'_> {
}
}
type JSErrorCreateFn = dyn Fn(JSError) -> ErrBox;
type JsErrorCreateFn = dyn Fn(JsError) -> ErrBox;
pub type GetErrorClassFn = dyn for<'e> Fn(&'e ErrBox) -> &'static str;
@ -109,16 +104,18 @@ struct IsolateAllocations {
}
/// A single execution context of JavaScript. Corresponds roughly to the "Web
/// Worker" concept in the DOM. An CoreIsolate is a Future that can be used with
/// Tokio. The CoreIsolate future completes when there is an error or when all
/// Worker" concept in the DOM. A JsRuntime is a Future that can be used with
/// an event loop (Tokio, async_std).
////
/// The JsRuntime future completes when there is an error or when all
/// pending ops have completed.
///
/// Ops are created in JavaScript by calling Deno.core.dispatch(), and in Rust
/// by implementing dispatcher function that takes control buffer and optional zero copy buffer
/// as arguments. An async Op corresponds exactly to a Promise in JavaScript.
pub struct CoreIsolate {
pub struct JsRuntime {
// This is an Option<OwnedIsolate> instead of just OwnedIsolate to workaround
// an safety issue with SnapshotCreator. See CoreIsolate::drop.
// an safety issue with SnapshotCreator. See JsRuntime::drop.
v8_isolate: Option<v8::OwnedIsolate>,
snapshot_creator: Option<v8::SnapshotCreator>,
has_snapshotted: bool,
@ -127,15 +124,15 @@ pub struct CoreIsolate {
allocations: IsolateAllocations,
}
/// Internal state for CoreIsolate which is stored in one of v8::Isolate's
/// Internal state for JsRuntime which is stored in one of v8::Isolate's
/// embedder slots.
pub struct CoreIsolateState {
pub struct JsRuntimeState {
pub global_context: Option<v8::Global<v8::Context>>,
pub(crate) shared_ab: Option<v8::Global<v8::SharedArrayBuffer>>,
pub(crate) js_recv_cb: Option<v8::Global<v8::Function>>,
pub(crate) js_macrotask_cb: Option<v8::Global<v8::Function>>,
pub(crate) pending_promise_exceptions: HashMap<i32, v8::Global<v8::Value>>,
pub(crate) js_error_create_fn: Box<JSErrorCreateFn>,
pub(crate) js_error_create_fn: Box<JsErrorCreateFn>,
pub(crate) shared: SharedQueue,
pub(crate) pending_ops: FuturesUnordered<PendingOpFuture>,
pub(crate) pending_unref_ops: FuturesUnordered<PendingOpFuture>,
@ -150,20 +147,20 @@ pub struct CoreIsolateState {
waker: AtomicWaker,
}
impl Deref for CoreIsolate {
impl Deref for JsRuntime {
type Target = v8::Isolate;
fn deref(&self) -> &v8::Isolate {
self.v8_isolate.as_ref().unwrap()
}
}
impl DerefMut for CoreIsolate {
impl DerefMut for JsRuntime {
fn deref_mut(&mut self) -> &mut v8::Isolate {
self.v8_isolate.as_mut().unwrap()
}
}
impl Drop for CoreIsolate {
impl Drop for JsRuntime {
fn drop(&mut self) {
if let Some(creator) = self.snapshot_creator.take() {
// TODO(ry): in rusty_v8, `SnapShotCreator::get_owned_isolate()` returns
@ -229,7 +226,7 @@ pub(crate) struct IsolateOptions {
heap_limits: Option<HeapLimits>,
}
impl CoreIsolate {
impl JsRuntime {
/// startup_data defines the snapshot or script used at startup to initialize
/// the isolate.
pub fn new(
@ -308,7 +305,7 @@ impl CoreIsolate {
let mut creator =
v8::SnapshotCreator::new(Some(&bindings::EXTERNAL_REFERENCES));
let isolate = unsafe { creator.get_owned_isolate() };
let mut isolate = CoreIsolate::setup_isolate(isolate);
let mut isolate = JsRuntime::setup_isolate(isolate);
{
let scope = &mut v8::HandleScope::new(&mut isolate);
let context = bindings::initialize_context(scope);
@ -335,7 +332,7 @@ impl CoreIsolate {
}
let isolate = v8::Isolate::new(params);
let mut isolate = CoreIsolate::setup_isolate(isolate);
let mut isolate = JsRuntime::setup_isolate(isolate);
{
let scope = &mut v8::HandleScope::new(&mut isolate);
let context = if snapshot_loaded {
@ -350,13 +347,13 @@ impl CoreIsolate {
(isolate, None)
};
isolate.set_slot(Rc::new(RefCell::new(CoreIsolateState {
isolate.set_slot(Rc::new(RefCell::new(JsRuntimeState {
global_context: Some(global_context),
pending_promise_exceptions: HashMap::new(),
shared_ab: None,
js_recv_cb: None,
js_macrotask_cb: None,
js_error_create_fn: Box::new(JSError::create),
js_error_create_fn: Box::new(JsError::create),
shared: SharedQueue::new(RECOMMENDED_SIZE),
pending_ops: FuturesUnordered::new(),
pending_unref_ops: FuturesUnordered::new(),
@ -392,8 +389,8 @@ impl CoreIsolate {
isolate
}
pub fn state(isolate: &v8::Isolate) -> Rc<RefCell<CoreIsolateState>> {
let s = isolate.get_slot::<Rc<RefCell<CoreIsolateState>>>().unwrap();
pub fn state(isolate: &v8::Isolate) -> Rc<RefCell<JsRuntimeState>> {
let s = isolate.get_slot::<Rc<RefCell<JsRuntimeState>>>().unwrap();
s.clone()
}
@ -412,8 +409,8 @@ impl CoreIsolate {
/// Executes traditional JavaScript code (traditional = not ES modules)
///
/// ErrBox 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 CoreIsolate::set_js_error_create_fn() has been used.
/// the V8 exception. By default this type is JsError, however it may be a
/// different type if JsRuntime::set_js_error_create_fn() has been used.
pub fn execute(
&mut self,
js_filename: &str,
@ -459,8 +456,8 @@ impl CoreIsolate {
/// set to true.
///
/// ErrBox 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 CoreIsolate::set_js_error_create_fn() has been used.
/// the V8 exception. By default this type is JsError, however it may be a
/// different type if JsRuntime::set_js_error_create_fn() has been used.
pub fn snapshot(&mut self) -> v8::StartupData {
assert!(self.snapshot_creator.is_some());
let state = Self::state(self);
@ -535,14 +532,14 @@ where
callback(current_heap_limit, initial_heap_limit)
}
impl Future for CoreIsolate {
impl Future for JsRuntime {
type Output = Result<(), ErrBox>;
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
let core_isolate = self.get_mut();
core_isolate.shared_init();
let runtime = self.get_mut();
runtime.shared_init();
let state_rc = Self::state(core_isolate);
let state_rc = Self::state(runtime);
{
let state = state_rc.borrow();
state.waker.register(cx.waker());
@ -553,7 +550,7 @@ impl Future for CoreIsolate {
!state.preparing_dyn_imports.is_empty()
};
if has_preparing {
let poll_imports = core_isolate.prepare_dyn_imports(cx)?;
let poll_imports = runtime.prepare_dyn_imports(cx)?;
assert!(poll_imports.is_ready());
}
@ -562,12 +559,12 @@ impl Future for CoreIsolate {
!state.pending_dyn_imports.is_empty()
};
if has_pending {
let poll_imports = core_isolate.poll_dyn_imports(cx)?;
let poll_imports = runtime.poll_dyn_imports(cx)?;
assert!(poll_imports.is_ready());
}
let scope = &mut v8::HandleScope::with_context(
&mut **core_isolate,
&mut **runtime,
state_rc.borrow().global_context.as_ref().unwrap(),
);
@ -654,13 +651,13 @@ impl Future for CoreIsolate {
}
}
impl CoreIsolateState {
impl JsRuntimeState {
/// Allows a callback to be set whenever a V8 exception is made. This allows
/// the caller to wrap the JSError into an error. By default this callback
/// is set to JSError::create.
/// the caller to wrap the JsError into an error. By default this callback
/// is set to JsError::create.
pub fn set_js_error_create_fn(
&mut self,
f: impl Fn(JSError) -> ErrBox + 'static,
f: impl Fn(JsError) -> ErrBox + 'static,
) {
self.js_error_create_fn = Box::new(f);
}
@ -706,7 +703,7 @@ fn async_op_response<'s>(
) -> Result<(), ErrBox> {
let context = scope.get_current_context();
let global: v8::Local<v8::Value> = context.global(scope).into();
let js_recv_cb = CoreIsolate::state(scope)
let js_recv_cb = JsRuntime::state(scope)
.borrow()
.js_recv_cb
.as_ref()
@ -736,7 +733,7 @@ fn drain_macrotasks<'s>(scope: &mut v8::HandleScope<'s>) -> Result<(), ErrBox> {
let context = scope.get_current_context();
let global: v8::Local<v8::Value> = context.global(scope).into();
let js_macrotask_cb = match CoreIsolate::state(scope)
let js_macrotask_cb = match JsRuntime::state(scope)
.borrow_mut()
.js_macrotask_cb
.as_ref()
@ -790,9 +787,9 @@ pub(crate) fn exception_to_err_result<'s, T>(
}
}
let js_error = JSError::from_v8_exception(scope, exception);
let js_error = JsError::from_v8_exception(scope, exception);
let state_rc = CoreIsolate::state(scope);
let state_rc = JsRuntime::state(scope);
let state = state_rc.borrow();
let js_error = (state.js_error_create_fn)(js_error);
@ -809,7 +806,7 @@ pub(crate) fn exception_to_err_result<'s, T>(
fn check_promise_exceptions<'s>(
scope: &mut v8::HandleScope<'s>,
) -> Result<(), ErrBox> {
let state_rc = CoreIsolate::state(scope);
let state_rc = JsRuntime::state(scope);
let mut state = state_rc.borrow_mut();
if let Some(&key) = state.pending_promise_exceptions.keys().next() {
@ -843,7 +840,7 @@ fn boxed_slice_to_uint8array<'sc>(
}
// Related to module loading
impl CoreIsolate {
impl JsRuntime {
/// Low-level module creation.
///
/// Called during module loading or dynamic import loading.
@ -902,8 +899,8 @@ impl CoreIsolate {
/// Instantiates a ES module
///
/// ErrBox 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 CoreIsolate::set_js_error_create_fn() has been used.
/// the V8 exception. By default this type is JsError, however it may be a
/// different type if JsRuntime::set_js_error_create_fn() has been used.
fn mod_instantiate(&mut self, id: ModuleId) -> Result<(), ErrBox> {
let state_rc = Self::state(self);
let state = state_rc.borrow();
@ -938,8 +935,8 @@ impl CoreIsolate {
/// Evaluates an already instantiated ES module.
///
/// ErrBox 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 CoreIsolate::set_js_error_create_fn() has been used.
/// the V8 exception. By default this type is JsError, however it may be a
/// different type if JsRuntime::set_js_error_create_fn() has been used.
pub fn mod_evaluate(&mut self, id: ModuleId) -> Result<(), ErrBox> {
self.shared_init();
@ -965,7 +962,7 @@ impl CoreIsolate {
// Because that promise is created internally by V8, when error occurs during
// module evaluation the promise is rejected, and since the promise has no rejection
// handler it will result in call to `bindings::promise_reject_callback` adding
// the promise to pending promise rejection table - meaning Isolate will return
// the promise to pending promise rejection table - meaning JsRuntime will return
// error on next poll().
//
// This situation is not desirable as we want to manually return error at the
@ -1253,7 +1250,7 @@ impl CoreIsolate {
/// Asynchronously load specified module and all of it's dependencies
///
/// User must call `Isolate::mod_evaluate` with returned `ModuleId`
/// User must call `JsRuntime::mod_evaluate` with returned `ModuleId`
/// manually after load is finished.
pub async fn load_module(
&mut self,
@ -1316,7 +1313,7 @@ pub mod tests {
}
}
panic!(
"CoreIsolate still not ready after polling {} times.",
"JsRuntime still not ready after polling {} times.",
max_poll_count
)
}
@ -1407,15 +1404,15 @@ pub mod tests {
}
}
fn setup(mode: Mode) -> (CoreIsolate, Arc<AtomicUsize>) {
fn setup(mode: Mode) -> (JsRuntime, Arc<AtomicUsize>) {
let dispatch_count = Arc::new(AtomicUsize::new(0));
let test_state = Rc::new(TestOpRouter {
mode,
dispatch_count: dispatch_count.clone(),
});
let mut isolate = CoreIsolate::new(test_state, StartupData::None, false);
let mut runtime = JsRuntime::new(test_state, StartupData::None, false);
js_check(isolate.execute(
js_check(runtime.execute(
"setup.js",
r#"
function assert(cond) {
@ -1426,13 +1423,13 @@ pub mod tests {
"#,
));
assert_eq!(dispatch_count.load(Ordering::Relaxed), 0);
(isolate, dispatch_count)
(runtime, dispatch_count)
}
#[test]
fn test_dispatch() {
let (mut isolate, dispatch_count) = setup(Mode::Async);
js_check(isolate.execute(
let (mut runtime, dispatch_count) = setup(Mode::Async);
js_check(runtime.execute(
"filename.js",
r#"
let control = new Uint8Array([42]);
@ -1448,8 +1445,8 @@ pub mod tests {
#[test]
fn test_dispatch_no_zero_copy_buf() {
let (mut isolate, dispatch_count) = setup(Mode::AsyncZeroCopy(0));
js_check(isolate.execute(
let (mut runtime, dispatch_count) = setup(Mode::AsyncZeroCopy(0));
js_check(runtime.execute(
"filename.js",
r#"
Deno.core.send(1);
@ -1460,8 +1457,8 @@ pub mod tests {
#[test]
fn test_dispatch_stack_zero_copy_bufs() {
let (mut isolate, dispatch_count) = setup(Mode::AsyncZeroCopy(2));
js_check(isolate.execute(
let (mut runtime, dispatch_count) = setup(Mode::AsyncZeroCopy(2));
js_check(runtime.execute(
"filename.js",
r#"
let zero_copy_a = new Uint8Array([0]);
@ -1474,8 +1471,8 @@ pub mod tests {
#[test]
fn test_dispatch_heap_zero_copy_bufs() {
let (mut isolate, dispatch_count) = setup(Mode::AsyncZeroCopy(5));
js_check(isolate.execute(
let (mut runtime, dispatch_count) = setup(Mode::AsyncZeroCopy(5));
js_check(runtime.execute(
"filename.js",
r#"
let zero_copy_a = new Uint8Array([0]);
@ -1492,9 +1489,9 @@ pub mod tests {
#[test]
fn test_poll_async_delayed_ops() {
run_in_task(|cx| {
let (mut isolate, dispatch_count) = setup(Mode::Async);
let (mut runtime, dispatch_count) = setup(Mode::Async);
js_check(isolate.execute(
js_check(runtime.execute(
"setup2.js",
r#"
let nrecv = 0;
@ -1504,7 +1501,7 @@ pub mod tests {
"#,
));
assert_eq!(dispatch_count.load(Ordering::Relaxed), 0);
js_check(isolate.execute(
js_check(runtime.execute(
"check1.js",
r#"
assert(nrecv == 0);
@ -1514,9 +1511,9 @@ pub mod tests {
"#,
));
assert_eq!(dispatch_count.load(Ordering::Relaxed), 1);
assert!(matches!(isolate.poll_unpin(cx), Poll::Ready(Ok(_))));
assert!(matches!(runtime.poll_unpin(cx), Poll::Ready(Ok(_))));
assert_eq!(dispatch_count.load(Ordering::Relaxed), 1);
js_check(isolate.execute(
js_check(runtime.execute(
"check2.js",
r#"
assert(nrecv == 1);
@ -1525,19 +1522,19 @@ pub mod tests {
"#,
));
assert_eq!(dispatch_count.load(Ordering::Relaxed), 2);
assert!(matches!(isolate.poll_unpin(cx), Poll::Ready(Ok(_))));
js_check(isolate.execute("check3.js", "assert(nrecv == 2)"));
assert!(matches!(runtime.poll_unpin(cx), Poll::Ready(Ok(_))));
js_check(runtime.execute("check3.js", "assert(nrecv == 2)"));
assert_eq!(dispatch_count.load(Ordering::Relaxed), 2);
// We are idle, so the next poll should be the last.
assert!(matches!(isolate.poll_unpin(cx), Poll::Ready(Ok(_))));
assert!(matches!(runtime.poll_unpin(cx), Poll::Ready(Ok(_))));
});
}
#[test]
fn test_poll_async_optional_ops() {
run_in_task(|cx| {
let (mut isolate, dispatch_count) = setup(Mode::AsyncUnref);
js_check(isolate.execute(
let (mut runtime, dispatch_count) = setup(Mode::AsyncUnref);
js_check(runtime.execute(
"check1.js",
r#"
Deno.core.setAsyncHandler(1, (buf) => {
@ -1549,9 +1546,9 @@ pub mod tests {
"#,
));
assert_eq!(dispatch_count.load(Ordering::Relaxed), 1);
// The above op never finish, but isolate can finish
// The above op never finish, but runtime can finish
// because the op is an unreffed async op.
assert!(matches!(isolate.poll_unpin(cx), Poll::Ready(Ok(_))));
assert!(matches!(runtime.poll_unpin(cx), Poll::Ready(Ok(_))));
})
}
@ -1604,10 +1601,10 @@ pub mod tests {
fn dangling_shared_isolate() {
let v8_isolate_handle = {
// isolate is dropped at the end of this block
let (mut isolate, _dispatch_count) = setup(Mode::Async);
let (mut runtime, _dispatch_count) = setup(Mode::Async);
// TODO(piscisaureus): in rusty_v8, the `thread_safe_handle()` method
// should not require a mutable reference to `struct rusty_v8::Isolate`.
isolate.v8_isolate.as_mut().unwrap().thread_safe_handle()
runtime.v8_isolate.as_mut().unwrap().thread_safe_handle()
};
// this should not SEGFAULT
@ -1616,8 +1613,8 @@ pub mod tests {
#[test]
fn overflow_req_sync() {
let (mut isolate, dispatch_count) = setup(Mode::OverflowReqSync);
js_check(isolate.execute(
let (mut runtime, dispatch_count) = setup(Mode::OverflowReqSync);
js_check(runtime.execute(
"overflow_req_sync.js",
r#"
let asyncRecv = 0;
@ -1638,8 +1635,8 @@ pub mod tests {
fn overflow_res_sync() {
// TODO(ry) This test is quite slow due to memcpy-ing 100MB into JS. We
// should optimize this.
let (mut isolate, dispatch_count) = setup(Mode::OverflowResSync);
js_check(isolate.execute(
let (mut runtime, dispatch_count) = setup(Mode::OverflowResSync);
js_check(runtime.execute(
"overflow_res_sync.js",
r#"
let asyncRecv = 0;
@ -1659,8 +1656,8 @@ pub mod tests {
#[test]
fn overflow_req_async() {
run_in_task(|cx| {
let (mut isolate, dispatch_count) = setup(Mode::OverflowReqAsync);
js_check(isolate.execute(
let (mut runtime, dispatch_count) = setup(Mode::OverflowReqAsync);
js_check(runtime.execute(
"overflow_req_async.js",
r#"
let asyncRecv = 0;
@ -1678,8 +1675,8 @@ pub mod tests {
"#,
));
assert_eq!(dispatch_count.load(Ordering::Relaxed), 1);
assert!(matches!(isolate.poll_unpin(cx), Poll::Ready(Ok(_))));
js_check(isolate.execute("check.js", "assert(asyncRecv == 1);"));
assert!(matches!(runtime.poll_unpin(cx), Poll::Ready(Ok(_))));
js_check(runtime.execute("check.js", "assert(asyncRecv == 1);"));
});
}
@ -1688,8 +1685,8 @@ pub mod tests {
run_in_task(|_cx| {
// TODO(ry) This test is quite slow due to memcpy-ing 100MB into JS. We
// should optimize this.
let (mut isolate, dispatch_count) = setup(Mode::OverflowResAsync);
js_check(isolate.execute(
let (mut runtime, dispatch_count) = setup(Mode::OverflowResAsync);
js_check(runtime.execute(
"overflow_res_async.js",
r#"
let asyncRecv = 0;
@ -1706,8 +1703,8 @@ pub mod tests {
"#,
));
assert_eq!(dispatch_count.load(Ordering::Relaxed), 1);
poll_until_ready(&mut isolate, 3).unwrap();
js_check(isolate.execute("check.js", "assert(asyncRecv == 1);"));
poll_until_ready(&mut runtime, 3).unwrap();
js_check(runtime.execute("check.js", "assert(asyncRecv == 1);"));
});
}
@ -1716,8 +1713,8 @@ pub mod tests {
// TODO(ry) This test is quite slow due to memcpy-ing 100MB into JS. We
// should optimize this.
run_in_task(|_cx| {
let (mut isolate, dispatch_count) = setup(Mode::OverflowResAsync);
js_check(isolate.execute(
let (mut runtime, dispatch_count) = setup(Mode::OverflowResAsync);
js_check(runtime.execute(
"overflow_res_multiple_dispatch_async.js",
r#"
let asyncRecv = 0;
@ -1737,16 +1734,16 @@ pub mod tests {
"#,
));
assert_eq!(dispatch_count.load(Ordering::Relaxed), 2);
poll_until_ready(&mut isolate, 3).unwrap();
js_check(isolate.execute("check.js", "assert(asyncRecv == 2);"));
poll_until_ready(&mut runtime, 3).unwrap();
js_check(runtime.execute("check.js", "assert(asyncRecv == 2);"));
});
}
#[test]
fn test_pre_dispatch() {
run_in_task(|mut cx| {
let (mut isolate, _dispatch_count) = setup(Mode::OverflowResAsync);
js_check(isolate.execute(
let (mut runtime, _dispatch_count) = setup(Mode::OverflowResAsync);
js_check(runtime.execute(
"bad_op_id.js",
r#"
let thrown;
@ -1758,7 +1755,7 @@ pub mod tests {
assert(String(thrown) === "TypeError: Unknown op id: 100");
"#,
));
if let Poll::Ready(Err(_)) = isolate.poll_unpin(&mut cx) {
if let Poll::Ready(Err(_)) = runtime.poll_unpin(&mut cx) {
unreachable!();
}
});
@ -1767,9 +1764,9 @@ pub mod tests {
#[test]
fn core_test_js() {
run_in_task(|mut cx| {
let (mut isolate, _dispatch_count) = setup(Mode::Async);
js_check(isolate.execute("core_test.js", include_str!("core_test.js")));
if let Poll::Ready(Err(_)) = isolate.poll_unpin(&mut cx) {
let (mut runtime, _dispatch_count) = setup(Mode::Async);
js_check(runtime.execute("core_test.js", include_str!("core_test.js")));
if let Poll::Ready(Err(_)) = runtime.poll_unpin(&mut cx) {
unreachable!();
}
});
@ -1777,24 +1774,24 @@ pub mod tests {
#[test]
fn syntax_error() {
let mut isolate =
CoreIsolate::new(BasicState::new(), StartupData::None, false);
let mut runtime =
JsRuntime::new(BasicState::new(), StartupData::None, false);
let src = "hocuspocus(";
let r = isolate.execute("i.js", src);
let r = runtime.execute("i.js", src);
let e = r.unwrap_err();
let js_error = e.downcast::<JSError>().unwrap();
let js_error = e.downcast::<JsError>().unwrap();
assert_eq!(js_error.end_column, Some(11));
}
#[test]
fn test_encode_decode() {
run_in_task(|mut cx| {
let (mut isolate, _dispatch_count) = setup(Mode::Async);
js_check(isolate.execute(
let (mut runtime, _dispatch_count) = setup(Mode::Async);
js_check(runtime.execute(
"encode_decode_test.js",
include_str!("encode_decode_test.js"),
));
if let Poll::Ready(Err(_)) = isolate.poll_unpin(&mut cx) {
if let Poll::Ready(Err(_)) = runtime.poll_unpin(&mut cx) {
unreachable!();
}
});
@ -1803,30 +1800,30 @@ pub mod tests {
#[test]
fn will_snapshot() {
let snapshot = {
let mut isolate =
CoreIsolate::new(BasicState::new(), StartupData::None, true);
js_check(isolate.execute("a.js", "a = 1 + 2"));
isolate.snapshot()
let mut runtime =
JsRuntime::new(BasicState::new(), StartupData::None, true);
js_check(runtime.execute("a.js", "a = 1 + 2"));
runtime.snapshot()
};
let startup_data = StartupData::Snapshot(Snapshot::JustCreated(snapshot));
let mut isolate2 = CoreIsolate::new(BasicState::new(), startup_data, false);
js_check(isolate2.execute("check.js", "if (a != 3) throw Error('x')"));
let mut runtime2 = JsRuntime::new(BasicState::new(), startup_data, false);
js_check(runtime2.execute("check.js", "if (a != 3) throw Error('x')"));
}
#[test]
fn test_from_boxed_snapshot() {
let snapshot = {
let mut isolate =
CoreIsolate::new(BasicState::new(), StartupData::None, true);
js_check(isolate.execute("a.js", "a = 1 + 2"));
let snap: &[u8] = &*isolate.snapshot();
let mut runtime =
JsRuntime::new(BasicState::new(), StartupData::None, true);
js_check(runtime.execute("a.js", "a = 1 + 2"));
let snap: &[u8] = &*runtime.snapshot();
Vec::from(snap).into_boxed_slice()
};
let startup_data = StartupData::Snapshot(Snapshot::Boxed(snapshot));
let mut isolate2 = CoreIsolate::new(BasicState::new(), startup_data, false);
js_check(isolate2.execute("check.js", "if (a != 3) throw Error('x')"));
let mut runtime2 = JsRuntime::new(BasicState::new(), startup_data, false);
js_check(runtime2.execute("check.js", "if (a != 3) throw Error('x')"));
}
#[test]
@ -1835,24 +1832,24 @@ pub mod tests {
initial: 0,
max: 20 * 1024, // 20 kB
};
let mut isolate = CoreIsolate::with_heap_limits(
let mut runtime = JsRuntime::with_heap_limits(
BasicState::new(),
StartupData::None,
heap_limits,
);
let cb_handle = isolate.thread_safe_handle();
let cb_handle = runtime.thread_safe_handle();
let callback_invoke_count = Rc::new(AtomicUsize::default());
let inner_invoke_count = Rc::clone(&callback_invoke_count);
isolate.add_near_heap_limit_callback(
runtime.add_near_heap_limit_callback(
move |current_limit, _initial_limit| {
inner_invoke_count.fetch_add(1, Ordering::SeqCst);
cb_handle.terminate_execution();
current_limit * 2
},
);
let err = isolate
let err = runtime
.execute(
"script name",
r#"let s = ""; while(true) { s += "Hello"; }"#,
@ -1860,21 +1857,21 @@ pub mod tests {
.expect_err("script should fail");
assert_eq!(
"Uncaught Error: execution terminated",
err.downcast::<JSError>().unwrap().message
err.downcast::<JsError>().unwrap().message
);
assert!(callback_invoke_count.load(Ordering::SeqCst) > 0)
}
#[test]
fn test_heap_limit_cb_remove() {
let mut isolate =
CoreIsolate::new(BasicState::new(), StartupData::None, false);
let mut runtime =
JsRuntime::new(BasicState::new(), StartupData::None, false);
isolate.add_near_heap_limit_callback(|current_limit, _initial_limit| {
runtime.add_near_heap_limit_callback(|current_limit, _initial_limit| {
current_limit * 2
});
isolate.remove_near_heap_limit_callback(20 * 1024);
assert!(isolate.allocations.near_heap_limit_callback_data.is_none());
runtime.remove_near_heap_limit_callback(20 * 1024);
assert!(runtime.allocations.near_heap_limit_callback_data.is_none());
}
#[test]
@ -1883,16 +1880,16 @@ pub mod tests {
initial: 0,
max: 20 * 1024, // 20 kB
};
let mut isolate = CoreIsolate::with_heap_limits(
let mut runtime = JsRuntime::with_heap_limits(
BasicState::new(),
StartupData::None,
heap_limits,
);
let cb_handle = isolate.thread_safe_handle();
let cb_handle = runtime.thread_safe_handle();
let callback_invoke_count_first = Rc::new(AtomicUsize::default());
let inner_invoke_count_first = Rc::clone(&callback_invoke_count_first);
isolate.add_near_heap_limit_callback(
runtime.add_near_heap_limit_callback(
move |current_limit, _initial_limit| {
inner_invoke_count_first.fetch_add(1, Ordering::SeqCst);
current_limit * 2
@ -1901,7 +1898,7 @@ pub mod tests {
let callback_invoke_count_second = Rc::new(AtomicUsize::default());
let inner_invoke_count_second = Rc::clone(&callback_invoke_count_second);
isolate.add_near_heap_limit_callback(
runtime.add_near_heap_limit_callback(
move |current_limit, _initial_limit| {
inner_invoke_count_second.fetch_add(1, Ordering::SeqCst);
cb_handle.terminate_execution();
@ -1909,7 +1906,7 @@ pub mod tests {
},
);
let err = isolate
let err = runtime
.execute(
"script name",
r#"let s = ""; while(true) { s += "Hello"; }"#,
@ -1917,7 +1914,7 @@ pub mod tests {
.expect_err("script should fail");
assert_eq!(
"Uncaught Error: execution terminated",
err.downcast::<JSError>().unwrap().message
err.downcast::<JsError>().unwrap().message
);
assert_eq!(0, callback_invoke_count_first.load(Ordering::SeqCst));
assert!(callback_invoke_count_second.load(Ordering::SeqCst) > 0);
@ -1971,10 +1968,10 @@ pub mod tests {
};
state.register_op("test", dispatcher);
let mut isolate =
CoreIsolate::new_with_loader(loader, state, StartupData::None, false);
let mut runtime =
JsRuntime::new_with_loader(loader, state, StartupData::None, false);
js_check(isolate.execute(
js_check(runtime.execute(
"setup.js",
r#"
function assert(cond) {
@ -1988,7 +1985,7 @@ pub mod tests {
assert_eq!(dispatch_count.load(Ordering::Relaxed), 0);
let specifier_a = "file:///a.js".to_string();
let mod_a = isolate
let mod_a = runtime
.mod_new(
true,
&specifier_a,
@ -2002,7 +1999,7 @@ pub mod tests {
.unwrap();
assert_eq!(dispatch_count.load(Ordering::Relaxed), 0);
let state_rc = CoreIsolate::state(&isolate);
let state_rc = JsRuntime::state(&runtime);
{
let state = state_rc.borrow();
let imports = state.modules.get_children(mod_a);
@ -2011,7 +2008,7 @@ pub mod tests {
Some(&vec![ModuleSpecifier::resolve_url("file:///b.js").unwrap()])
);
}
let mod_b = isolate
let mod_b = runtime
.mod_new(false, "file:///b.js", "export function b() { return 'b' }")
.unwrap();
{
@ -2020,14 +2017,14 @@ pub mod tests {
assert_eq!(imports.len(), 0);
}
js_check(isolate.mod_instantiate(mod_b));
js_check(runtime.mod_instantiate(mod_b));
assert_eq!(dispatch_count.load(Ordering::Relaxed), 0);
assert_eq!(resolve_count.load(Ordering::SeqCst), 1);
js_check(isolate.mod_instantiate(mod_a));
js_check(runtime.mod_instantiate(mod_a));
assert_eq!(dispatch_count.load(Ordering::Relaxed), 0);
js_check(isolate.mod_evaluate(mod_a));
js_check(runtime.mod_evaluate(mod_a));
assert_eq!(dispatch_count.load(Ordering::Relaxed), 1);
}
@ -2066,14 +2063,14 @@ pub mod tests {
run_in_task(|cx| {
let loader = Rc::new(DynImportErrLoader::default());
let count = loader.count.clone();
let mut isolate = CoreIsolate::new_with_loader(
let mut runtime = JsRuntime::new_with_loader(
loader,
BasicState::new(),
StartupData::None,
false,
);
js_check(isolate.execute(
js_check(runtime.execute(
"file:///dyn_import2.js",
r#"
(async () => {
@ -2084,7 +2081,7 @@ pub mod tests {
assert_eq!(count.load(Ordering::Relaxed), 0);
// We should get an error here.
let result = isolate.poll_unpin(cx);
let result = runtime.poll_unpin(cx);
if let Poll::Ready(Ok(_)) = result {
unreachable!();
}
@ -2148,7 +2145,7 @@ pub mod tests {
let prepare_load_count = loader.prepare_load_count.clone();
let resolve_count = loader.resolve_count.clone();
let load_count = loader.load_count.clone();
let mut isolate = CoreIsolate::new_with_loader(
let mut runtime = JsRuntime::new_with_loader(
loader,
BasicState::new(),
StartupData::None,
@ -2156,7 +2153,7 @@ pub mod tests {
);
// Dynamically import mod_b
js_check(isolate.execute(
js_check(runtime.execute(
"file:///dyn_import3.js",
r#"
(async () => {
@ -2174,14 +2171,14 @@ pub mod tests {
));
// First poll runs `prepare_load` hook.
assert!(matches!(isolate.poll_unpin(cx), Poll::Pending));
assert!(matches!(runtime.poll_unpin(cx), Poll::Pending));
assert_eq!(prepare_load_count.load(Ordering::Relaxed), 1);
// Second poll actually loads modules into the isolate.
assert!(matches!(isolate.poll_unpin(cx), Poll::Ready(Ok(_))));
assert!(matches!(runtime.poll_unpin(cx), Poll::Ready(Ok(_))));
assert_eq!(resolve_count.load(Ordering::Relaxed), 4);
assert_eq!(load_count.load(Ordering::Relaxed), 2);
assert!(matches!(isolate.poll_unpin(cx), Poll::Ready(Ok(_))));
assert!(matches!(runtime.poll_unpin(cx), Poll::Ready(Ok(_))));
assert_eq!(resolve_count.load(Ordering::Relaxed), 4);
assert_eq!(load_count.load(Ordering::Relaxed), 2);
})
@ -2193,13 +2190,13 @@ pub mod tests {
run_in_task(|cx| {
let loader = Rc::new(DynImportOkLoader::default());
let prepare_load_count = loader.prepare_load_count.clone();
let mut isolate = CoreIsolate::new_with_loader(
let mut runtime = JsRuntime::new_with_loader(
loader,
BasicState::new(),
StartupData::None,
false,
);
js_check(isolate.execute(
js_check(runtime.execute(
"file:///dyn_import3.js",
r#"
(async () => {
@ -2213,10 +2210,10 @@ pub mod tests {
"#,
));
// First poll runs `prepare_load` hook.
let _ = isolate.poll_unpin(cx);
let _ = runtime.poll_unpin(cx);
assert_eq!(prepare_load_count.load(Ordering::Relaxed), 1);
// Second poll triggers error
let _ = isolate.poll_unpin(cx);
let _ = runtime.poll_unpin(cx);
})
}
@ -2249,7 +2246,7 @@ pub mod tests {
}
let loader = std::rc::Rc::new(ModsLoader::default());
let mut runtime_isolate = CoreIsolate::new_with_loader(
let mut runtime = JsRuntime::new_with_loader(
loader,
BasicState::new(),
StartupData::None,
@ -2260,12 +2257,12 @@ pub mod tests {
let source_code = "Deno.core.print('hello\\n')".to_string();
let module_id = futures::executor::block_on(
runtime_isolate.load_module(&specifier, Some(source_code)),
runtime.load_module(&specifier, Some(source_code)),
)
.unwrap();
js_check(runtime_isolate.mod_evaluate(module_id));
js_check(runtime.mod_evaluate(module_id));
let _snapshot = runtime_isolate.snapshot();
let _snapshot = runtime.snapshot();
}
}

View file

@ -1,10 +1,10 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use deno_core::js_check;
use deno_core::CoreIsolate;
use deno_core::JsRuntime;
use std::path::PathBuf;
pub fn init(isolate: &mut CoreIsolate) {
pub fn init(isolate: &mut JsRuntime) {
let files = vec![
get_path("00_dom_exception.js"),
get_path("01_event.js"),
@ -32,7 +32,7 @@ fn get_path(file_name: &str) -> PathBuf {
mod tests {
use deno_core::js_check;
use deno_core::BasicState;
use deno_core::CoreIsolate;
use deno_core::JsRuntime;
use deno_core::StartupData;
use futures::future::lazy;
use futures::future::FutureExt;
@ -46,9 +46,9 @@ mod tests {
futures::executor::block_on(lazy(move |cx| f(cx)));
}
fn setup() -> CoreIsolate {
fn setup() -> JsRuntime {
let mut isolate =
CoreIsolate::new(BasicState::new(), StartupData::None, false);
JsRuntime::new(BasicState::new(), StartupData::None, false);
crate::init(&mut isolate);
isolate
}