mirror of
https://github.com/denoland/deno.git
synced 2025-09-28 21:24:48 +00:00
refactor: Split isolate and state using safe get_slot() (#5929)
This commit is contained in:
parent
106b001738
commit
d4b05dd89e
30 changed files with 758 additions and 579 deletions
|
@ -375,14 +375,10 @@ impl DenoInspector {
|
||||||
isolate: &mut deno_core::CoreIsolate,
|
isolate: &mut deno_core::CoreIsolate,
|
||||||
host: SocketAddr,
|
host: SocketAddr,
|
||||||
) -> Box<Self> {
|
) -> Box<Self> {
|
||||||
let deno_core::CoreIsolate {
|
let core_state_rc = deno_core::CoreIsolate::state(isolate);
|
||||||
v8_isolate,
|
let core_state = core_state_rc.borrow();
|
||||||
global_context,
|
|
||||||
..
|
|
||||||
} = isolate;
|
|
||||||
|
|
||||||
let v8_isolate = v8_isolate.as_mut().unwrap();
|
let mut hs = v8::HandleScope::new(isolate);
|
||||||
let mut hs = v8::HandleScope::new(v8_isolate);
|
|
||||||
let scope = hs.enter();
|
let scope = hs.enter();
|
||||||
|
|
||||||
let (new_websocket_tx, new_websocket_rx) =
|
let (new_websocket_tx, new_websocket_rx) =
|
||||||
|
@ -420,7 +416,7 @@ impl DenoInspector {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Tell the inspector about the global context.
|
// Tell the inspector about the global context.
|
||||||
let context = global_context.get(scope).unwrap();
|
let context = core_state.global_context.get(scope).unwrap();
|
||||||
let context_name = v8::inspector::StringView::from(&b"global context"[..]);
|
let context_name = v8::inspector::StringView::from(&b"global context"[..]);
|
||||||
self_.context_created(context, Self::CONTEXT_GROUP_ID, context_name);
|
self_.context_created(context, Self::CONTEXT_GROUP_ID, context_name);
|
||||||
|
|
||||||
|
|
11
cli/main.rs
11
cli/main.rs
|
@ -80,7 +80,9 @@ use crate::state::State;
|
||||||
use crate::tsc::TargetLib;
|
use crate::tsc::TargetLib;
|
||||||
use crate::worker::MainWorker;
|
use crate::worker::MainWorker;
|
||||||
use deno_core::v8_set_flags;
|
use deno_core::v8_set_flags;
|
||||||
|
use deno_core::CoreIsolate;
|
||||||
use deno_core::ErrBox;
|
use deno_core::ErrBox;
|
||||||
|
use deno_core::EsIsolate;
|
||||||
use deno_core::ModuleSpecifier;
|
use deno_core::ModuleSpecifier;
|
||||||
use flags::DenoSubcommand;
|
use flags::DenoSubcommand;
|
||||||
use flags::Flags;
|
use flags::Flags;
|
||||||
|
@ -170,7 +172,9 @@ fn create_main_worker(
|
||||||
|
|
||||||
{
|
{
|
||||||
let (stdin, stdout, stderr) = get_stdio();
|
let (stdin, stdout, stderr) = get_stdio();
|
||||||
let mut t = worker.resource_table.borrow_mut();
|
let state_rc = CoreIsolate::state(&worker.isolate);
|
||||||
|
let state = state_rc.borrow();
|
||||||
|
let mut t = state.resource_table.borrow_mut();
|
||||||
t.add("stdin", Box::new(stdin));
|
t.add("stdin", Box::new(stdin));
|
||||||
t.add("stdout", Box::new(stdout));
|
t.add("stdout", Box::new(stdout));
|
||||||
t.add("stderr", Box::new(stderr));
|
t.add("stderr", Box::new(stderr));
|
||||||
|
@ -268,7 +272,10 @@ async fn print_file_info(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(deps) = worker.isolate.modules.deps(&module_specifier) {
|
let es_state_rc = EsIsolate::state(&worker.isolate);
|
||||||
|
let es_state = es_state_rc.borrow();
|
||||||
|
|
||||||
|
if let Some(deps) = es_state.modules.deps(&module_specifier) {
|
||||||
println!("{}{}", colors::bold("deps:\n".to_string()), deps.name);
|
println!("{}{}", colors::bold("deps:\n".to_string()), deps.name);
|
||||||
if let Some(ref depsdeps) = deps.deps {
|
if let Some(ref depsdeps) = deps.deps {
|
||||||
for d in depsdeps {
|
for d in depsdeps {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||||
use crate::op_error::OpError;
|
use crate::op_error::OpError;
|
||||||
use deno_core::Buf;
|
use deno_core::Buf;
|
||||||
use deno_core::CoreIsolate;
|
use deno_core::CoreIsolateState;
|
||||||
use deno_core::Op;
|
use deno_core::Op;
|
||||||
use deno_core::ZeroCopyBuf;
|
use deno_core::ZeroCopyBuf;
|
||||||
use futures::future::FutureExt;
|
use futures::future::FutureExt;
|
||||||
|
@ -46,12 +46,15 @@ struct AsyncArgs {
|
||||||
|
|
||||||
pub fn json_op<D>(
|
pub fn json_op<D>(
|
||||||
d: D,
|
d: D,
|
||||||
) -> impl Fn(&mut CoreIsolate, &[u8], Option<ZeroCopyBuf>) -> Op
|
) -> impl Fn(&mut CoreIsolateState, &[u8], Option<ZeroCopyBuf>) -> Op
|
||||||
where
|
where
|
||||||
D:
|
D: Fn(
|
||||||
Fn(&mut CoreIsolate, Value, Option<ZeroCopyBuf>) -> Result<JsonOp, OpError>,
|
&mut CoreIsolateState,
|
||||||
|
Value,
|
||||||
|
Option<ZeroCopyBuf>,
|
||||||
|
) -> Result<JsonOp, OpError>,
|
||||||
{
|
{
|
||||||
move |isolate: &mut CoreIsolate,
|
move |isolate_state: &mut CoreIsolateState,
|
||||||
control: &[u8],
|
control: &[u8],
|
||||||
zero_copy: Option<ZeroCopyBuf>| {
|
zero_copy: Option<ZeroCopyBuf>| {
|
||||||
let async_args: AsyncArgs = match serde_json::from_slice(control) {
|
let async_args: AsyncArgs = match serde_json::from_slice(control) {
|
||||||
|
@ -66,7 +69,7 @@ where
|
||||||
|
|
||||||
let result = serde_json::from_slice(control)
|
let result = serde_json::from_slice(control)
|
||||||
.map_err(OpError::from)
|
.map_err(OpError::from)
|
||||||
.and_then(|args| d(isolate, args, zero_copy));
|
.and_then(|args| d(isolate_state, args, zero_copy));
|
||||||
|
|
||||||
// Convert to Op
|
// Convert to Op
|
||||||
match result {
|
match result {
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
use crate::op_error::OpError;
|
use crate::op_error::OpError;
|
||||||
use byteorder::{LittleEndian, WriteBytesExt};
|
use byteorder::{LittleEndian, WriteBytesExt};
|
||||||
use deno_core::Buf;
|
use deno_core::Buf;
|
||||||
use deno_core::CoreIsolate;
|
use deno_core::CoreIsolateState;
|
||||||
use deno_core::Op;
|
use deno_core::Op;
|
||||||
use deno_core::ZeroCopyBuf;
|
use deno_core::ZeroCopyBuf;
|
||||||
use futures::future::FutureExt;
|
use futures::future::FutureExt;
|
||||||
|
@ -116,11 +116,11 @@ fn test_parse_min_record() {
|
||||||
|
|
||||||
pub fn minimal_op<D>(
|
pub fn minimal_op<D>(
|
||||||
d: D,
|
d: D,
|
||||||
) -> impl Fn(&mut CoreIsolate, &[u8], Option<ZeroCopyBuf>) -> Op
|
) -> impl Fn(&mut CoreIsolateState, &[u8], Option<ZeroCopyBuf>) -> Op
|
||||||
where
|
where
|
||||||
D: Fn(&mut CoreIsolate, bool, i32, Option<ZeroCopyBuf>) -> MinimalOp,
|
D: Fn(&mut CoreIsolateState, bool, i32, Option<ZeroCopyBuf>) -> MinimalOp,
|
||||||
{
|
{
|
||||||
move |isolate: &mut CoreIsolate,
|
move |isolate_state: &mut CoreIsolateState,
|
||||||
control: &[u8],
|
control: &[u8],
|
||||||
zero_copy: Option<ZeroCopyBuf>| {
|
zero_copy: Option<ZeroCopyBuf>| {
|
||||||
let mut record = match parse_min_record(control) {
|
let mut record = match parse_min_record(control) {
|
||||||
|
@ -138,7 +138,7 @@ where
|
||||||
};
|
};
|
||||||
let is_sync = record.promise_id == 0;
|
let is_sync = record.promise_id == 0;
|
||||||
let rid = record.arg;
|
let rid = record.arg;
|
||||||
let min_op = d(isolate, is_sync, rid, zero_copy);
|
let min_op = d(isolate_state, is_sync, rid, zero_copy);
|
||||||
|
|
||||||
match min_op {
|
match min_op {
|
||||||
MinimalOp::Sync(sync_result) => Op::Sync(match sync_result {
|
MinimalOp::Sync(sync_result) => Op::Sync(match sync_result {
|
||||||
|
|
|
@ -5,6 +5,7 @@ use crate::http_util::{create_http_client, HttpBody};
|
||||||
use crate::op_error::OpError;
|
use crate::op_error::OpError;
|
||||||
use crate::state::State;
|
use crate::state::State;
|
||||||
use deno_core::CoreIsolate;
|
use deno_core::CoreIsolate;
|
||||||
|
use deno_core::CoreIsolateState;
|
||||||
use deno_core::ZeroCopyBuf;
|
use deno_core::ZeroCopyBuf;
|
||||||
use futures::future::FutureExt;
|
use futures::future::FutureExt;
|
||||||
use http::header::HeaderName;
|
use http::header::HeaderName;
|
||||||
|
@ -24,7 +25,7 @@ struct FetchArgs {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn op_fetch(
|
pub fn op_fetch(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
state: &State,
|
state: &State,
|
||||||
args: Value,
|
args: Value,
|
||||||
data: Option<ZeroCopyBuf>,
|
data: Option<ZeroCopyBuf>,
|
||||||
|
@ -67,7 +68,7 @@ pub fn op_fetch(
|
||||||
}
|
}
|
||||||
debug!("Before fetch {}", url);
|
debug!("Before fetch {}", url);
|
||||||
|
|
||||||
let resource_table = isolate.resource_table.clone();
|
let resource_table = isolate_state.resource_table.clone();
|
||||||
let future = async move {
|
let future = async move {
|
||||||
let res = request.send().await?;
|
let res = request.send().await?;
|
||||||
debug!("Fetch response {}", url);
|
debug!("Fetch response {}", url);
|
||||||
|
|
|
@ -7,6 +7,7 @@ use crate::op_error::OpError;
|
||||||
use crate::ops::dispatch_json::JsonResult;
|
use crate::ops::dispatch_json::JsonResult;
|
||||||
use crate::state::State;
|
use crate::state::State;
|
||||||
use deno_core::CoreIsolate;
|
use deno_core::CoreIsolate;
|
||||||
|
use deno_core::CoreIsolateState;
|
||||||
use deno_core::ZeroCopyBuf;
|
use deno_core::ZeroCopyBuf;
|
||||||
use futures::future::FutureExt;
|
use futures::future::FutureExt;
|
||||||
use std::convert::From;
|
use std::convert::From;
|
||||||
|
@ -68,14 +69,14 @@ struct OpenOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_open(
|
fn op_open(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
state: &State,
|
state: &State,
|
||||||
args: Value,
|
args: Value,
|
||||||
_zero_copy: Option<ZeroCopyBuf>,
|
_zero_copy: Option<ZeroCopyBuf>,
|
||||||
) -> Result<JsonOp, OpError> {
|
) -> Result<JsonOp, OpError> {
|
||||||
let args: OpenArgs = serde_json::from_value(args)?;
|
let args: OpenArgs = serde_json::from_value(args)?;
|
||||||
let path = Path::new(&args.path).to_path_buf();
|
let path = Path::new(&args.path).to_path_buf();
|
||||||
let resource_table = isolate.resource_table.clone();
|
let resource_table = isolate_state.resource_table.clone();
|
||||||
|
|
||||||
let mut open_options = std::fs::OpenOptions::new();
|
let mut open_options = std::fs::OpenOptions::new();
|
||||||
|
|
||||||
|
@ -151,7 +152,7 @@ struct SeekArgs {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_seek(
|
fn op_seek(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
_state: &State,
|
_state: &State,
|
||||||
args: Value,
|
args: Value,
|
||||||
_zero_copy: Option<ZeroCopyBuf>,
|
_zero_copy: Option<ZeroCopyBuf>,
|
||||||
|
@ -174,7 +175,7 @@ fn op_seek(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let resource_table = isolate.resource_table.clone();
|
let resource_table = isolate_state.resource_table.clone();
|
||||||
let is_sync = args.promise_id.is_none();
|
let is_sync = args.promise_id.is_none();
|
||||||
|
|
||||||
if is_sync {
|
if is_sync {
|
||||||
|
|
|
@ -3,6 +3,7 @@ use super::dispatch_json::{Deserialize, JsonOp, Value};
|
||||||
use crate::op_error::OpError;
|
use crate::op_error::OpError;
|
||||||
use crate::state::State;
|
use crate::state::State;
|
||||||
use deno_core::CoreIsolate;
|
use deno_core::CoreIsolate;
|
||||||
|
use deno_core::CoreIsolateState;
|
||||||
use deno_core::ErrBox;
|
use deno_core::ErrBox;
|
||||||
use deno_core::ZeroCopyBuf;
|
use deno_core::ZeroCopyBuf;
|
||||||
use futures::future::poll_fn;
|
use futures::future::poll_fn;
|
||||||
|
@ -62,7 +63,7 @@ impl From<NotifyEvent> for FsEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn op_fs_events_open(
|
pub fn op_fs_events_open(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
state: &State,
|
state: &State,
|
||||||
args: Value,
|
args: Value,
|
||||||
_zero_copy: Option<ZeroCopyBuf>,
|
_zero_copy: Option<ZeroCopyBuf>,
|
||||||
|
@ -94,13 +95,13 @@ pub fn op_fs_events_open(
|
||||||
watcher.watch(path, recursive_mode).map_err(ErrBox::from)?;
|
watcher.watch(path, recursive_mode).map_err(ErrBox::from)?;
|
||||||
}
|
}
|
||||||
let resource = FsEventsResource { watcher, receiver };
|
let resource = FsEventsResource { watcher, receiver };
|
||||||
let mut resource_table = isolate.resource_table.borrow_mut();
|
let mut resource_table = isolate_state.resource_table.borrow_mut();
|
||||||
let rid = resource_table.add("fsEvents", Box::new(resource));
|
let rid = resource_table.add("fsEvents", Box::new(resource));
|
||||||
Ok(JsonOp::Sync(json!(rid)))
|
Ok(JsonOp::Sync(json!(rid)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn op_fs_events_poll(
|
pub fn op_fs_events_poll(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
_state: &State,
|
_state: &State,
|
||||||
args: Value,
|
args: Value,
|
||||||
_zero_copy: Option<ZeroCopyBuf>,
|
_zero_copy: Option<ZeroCopyBuf>,
|
||||||
|
@ -110,7 +111,7 @@ pub fn op_fs_events_poll(
|
||||||
rid: u32,
|
rid: u32,
|
||||||
}
|
}
|
||||||
let PollArgs { rid } = serde_json::from_value(args)?;
|
let PollArgs { rid } = serde_json::from_value(args)?;
|
||||||
let resource_table = isolate.resource_table.clone();
|
let resource_table = isolate_state.resource_table.clone();
|
||||||
let f = poll_fn(move |cx| {
|
let f = poll_fn(move |cx| {
|
||||||
let mut resource_table = resource_table.borrow_mut();
|
let mut resource_table = resource_table.borrow_mut();
|
||||||
let watcher = resource_table
|
let watcher = resource_table
|
||||||
|
|
|
@ -3,6 +3,7 @@ use crate::http_util::HttpBody;
|
||||||
use crate::op_error::OpError;
|
use crate::op_error::OpError;
|
||||||
use crate::state::State;
|
use crate::state::State;
|
||||||
use deno_core::CoreIsolate;
|
use deno_core::CoreIsolate;
|
||||||
|
use deno_core::CoreIsolateState;
|
||||||
use deno_core::ResourceTable;
|
use deno_core::ResourceTable;
|
||||||
use deno_core::ZeroCopyBuf;
|
use deno_core::ZeroCopyBuf;
|
||||||
use futures::future::poll_fn;
|
use futures::future::poll_fn;
|
||||||
|
@ -206,7 +207,7 @@ impl DenoAsyncRead for StreamResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn op_read(
|
pub fn op_read(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
_state: &State,
|
_state: &State,
|
||||||
is_sync: bool,
|
is_sync: bool,
|
||||||
rid: i32,
|
rid: i32,
|
||||||
|
@ -216,7 +217,7 @@ pub fn op_read(
|
||||||
if zero_copy.is_none() {
|
if zero_copy.is_none() {
|
||||||
return MinimalOp::Sync(Err(no_buffer_specified()));
|
return MinimalOp::Sync(Err(no_buffer_specified()));
|
||||||
}
|
}
|
||||||
let resource_table = isolate.resource_table.clone();
|
let resource_table = isolate_state.resource_table.clone();
|
||||||
|
|
||||||
let mut buf = zero_copy.unwrap();
|
let mut buf = zero_copy.unwrap();
|
||||||
|
|
||||||
|
@ -330,7 +331,7 @@ impl DenoAsyncWrite for StreamResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn op_write(
|
pub fn op_write(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
_state: &State,
|
_state: &State,
|
||||||
is_sync: bool,
|
is_sync: bool,
|
||||||
rid: i32,
|
rid: i32,
|
||||||
|
@ -346,7 +347,7 @@ pub fn op_write(
|
||||||
if is_sync {
|
if is_sync {
|
||||||
MinimalOp::Sync({
|
MinimalOp::Sync({
|
||||||
// First we look up the rid in the resource table.
|
// First we look up the rid in the resource table.
|
||||||
let mut resource_table = isolate.resource_table.borrow_mut();
|
let mut resource_table = isolate_state.resource_table.borrow_mut();
|
||||||
std_file_resource(&mut resource_table, rid as u32, move |r| match r {
|
std_file_resource(&mut resource_table, rid as u32, move |r| match r {
|
||||||
Ok(std_file) => {
|
Ok(std_file) => {
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
@ -361,7 +362,7 @@ pub fn op_write(
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
let resource_table = isolate.resource_table.clone();
|
let resource_table = isolate_state.resource_table.clone();
|
||||||
MinimalOp::Async(
|
MinimalOp::Async(
|
||||||
async move {
|
async move {
|
||||||
let nwritten = poll_fn(|cx| {
|
let nwritten = poll_fn(|cx| {
|
||||||
|
|
|
@ -5,6 +5,7 @@ use crate::op_error::OpError;
|
||||||
use crate::resolve_addr::resolve_addr;
|
use crate::resolve_addr::resolve_addr;
|
||||||
use crate::state::State;
|
use crate::state::State;
|
||||||
use deno_core::CoreIsolate;
|
use deno_core::CoreIsolate;
|
||||||
|
use deno_core::CoreIsolateState;
|
||||||
use deno_core::ResourceTable;
|
use deno_core::ResourceTable;
|
||||||
use deno_core::ZeroCopyBuf;
|
use deno_core::ZeroCopyBuf;
|
||||||
use futures::future::poll_fn;
|
use futures::future::poll_fn;
|
||||||
|
@ -37,12 +38,12 @@ struct AcceptArgs {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accept_tcp(
|
fn accept_tcp(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
args: AcceptArgs,
|
args: AcceptArgs,
|
||||||
_zero_copy: Option<ZeroCopyBuf>,
|
_zero_copy: Option<ZeroCopyBuf>,
|
||||||
) -> Result<JsonOp, OpError> {
|
) -> Result<JsonOp, OpError> {
|
||||||
let rid = args.rid as u32;
|
let rid = args.rid as u32;
|
||||||
let resource_table = isolate.resource_table.clone();
|
let resource_table = isolate_state.resource_table.clone();
|
||||||
|
|
||||||
let op = async move {
|
let op = async move {
|
||||||
let accept_fut = poll_fn(|cx| {
|
let accept_fut = poll_fn(|cx| {
|
||||||
|
@ -97,16 +98,16 @@ fn accept_tcp(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_accept(
|
fn op_accept(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
_state: &State,
|
_state: &State,
|
||||||
args: Value,
|
args: Value,
|
||||||
zero_copy: Option<ZeroCopyBuf>,
|
zero_copy: Option<ZeroCopyBuf>,
|
||||||
) -> Result<JsonOp, OpError> {
|
) -> Result<JsonOp, OpError> {
|
||||||
let args: AcceptArgs = serde_json::from_value(args)?;
|
let args: AcceptArgs = serde_json::from_value(args)?;
|
||||||
match args.transport.as_str() {
|
match args.transport.as_str() {
|
||||||
"tcp" => accept_tcp(isolate, args, zero_copy),
|
"tcp" => accept_tcp(isolate_state, args, zero_copy),
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
"unix" => net_unix::accept_unix(isolate, args.rid as u32, zero_copy),
|
"unix" => net_unix::accept_unix(isolate_state, args.rid as u32, zero_copy),
|
||||||
_ => Err(OpError::other(format!(
|
_ => Err(OpError::other(format!(
|
||||||
"Unsupported transport protocol {}",
|
"Unsupported transport protocol {}",
|
||||||
args.transport
|
args.transport
|
||||||
|
@ -121,7 +122,7 @@ struct ReceiveArgs {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn receive_udp(
|
fn receive_udp(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
_state: &State,
|
_state: &State,
|
||||||
args: ReceiveArgs,
|
args: ReceiveArgs,
|
||||||
zero_copy: Option<ZeroCopyBuf>,
|
zero_copy: Option<ZeroCopyBuf>,
|
||||||
|
@ -130,7 +131,7 @@ fn receive_udp(
|
||||||
|
|
||||||
let rid = args.rid as u32;
|
let rid = args.rid as u32;
|
||||||
|
|
||||||
let resource_table = isolate.resource_table.clone();
|
let resource_table = isolate_state.resource_table.clone();
|
||||||
|
|
||||||
let op = async move {
|
let op = async move {
|
||||||
let receive_fut = poll_fn(|cx| {
|
let receive_fut = poll_fn(|cx| {
|
||||||
|
@ -158,7 +159,7 @@ fn receive_udp(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_receive(
|
fn op_receive(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
state: &State,
|
state: &State,
|
||||||
args: Value,
|
args: Value,
|
||||||
zero_copy: Option<ZeroCopyBuf>,
|
zero_copy: Option<ZeroCopyBuf>,
|
||||||
|
@ -166,10 +167,10 @@ fn op_receive(
|
||||||
assert!(zero_copy.is_some());
|
assert!(zero_copy.is_some());
|
||||||
let args: ReceiveArgs = serde_json::from_value(args)?;
|
let args: ReceiveArgs = serde_json::from_value(args)?;
|
||||||
match args.transport.as_str() {
|
match args.transport.as_str() {
|
||||||
"udp" => receive_udp(isolate, state, args, zero_copy),
|
"udp" => receive_udp(isolate_state, state, args, zero_copy),
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
"unixpacket" => {
|
"unixpacket" => {
|
||||||
net_unix::receive_unix_packet(isolate, args.rid as u32, zero_copy)
|
net_unix::receive_unix_packet(isolate_state, args.rid as u32, zero_copy)
|
||||||
}
|
}
|
||||||
_ => Err(OpError::other(format!(
|
_ => Err(OpError::other(format!(
|
||||||
"Unsupported transport protocol {}",
|
"Unsupported transport protocol {}",
|
||||||
|
@ -187,14 +188,14 @@ struct SendArgs {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_send(
|
fn op_send(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
state: &State,
|
state: &State,
|
||||||
args: Value,
|
args: Value,
|
||||||
zero_copy: Option<ZeroCopyBuf>,
|
zero_copy: Option<ZeroCopyBuf>,
|
||||||
) -> Result<JsonOp, OpError> {
|
) -> Result<JsonOp, OpError> {
|
||||||
assert!(zero_copy.is_some());
|
assert!(zero_copy.is_some());
|
||||||
let buf = zero_copy.unwrap();
|
let buf = zero_copy.unwrap();
|
||||||
let resource_table = isolate.resource_table.clone();
|
let resource_table = isolate_state.resource_table.clone();
|
||||||
match serde_json::from_value(args)? {
|
match serde_json::from_value(args)? {
|
||||||
SendArgs {
|
SendArgs {
|
||||||
rid,
|
rid,
|
||||||
|
@ -256,12 +257,12 @@ struct ConnectArgs {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_connect(
|
fn op_connect(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
state: &State,
|
state: &State,
|
||||||
args: Value,
|
args: Value,
|
||||||
_zero_copy: Option<ZeroCopyBuf>,
|
_zero_copy: Option<ZeroCopyBuf>,
|
||||||
) -> Result<JsonOp, OpError> {
|
) -> Result<JsonOp, OpError> {
|
||||||
let resource_table = isolate.resource_table.clone();
|
let resource_table = isolate_state.resource_table.clone();
|
||||||
match serde_json::from_value(args)? {
|
match serde_json::from_value(args)? {
|
||||||
ConnectArgs {
|
ConnectArgs {
|
||||||
transport,
|
transport,
|
||||||
|
@ -342,7 +343,7 @@ struct ShutdownArgs {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_shutdown(
|
fn op_shutdown(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
state: &State,
|
state: &State,
|
||||||
args: Value,
|
args: Value,
|
||||||
_zero_copy: Option<ZeroCopyBuf>,
|
_zero_copy: Option<ZeroCopyBuf>,
|
||||||
|
@ -360,7 +361,7 @@ fn op_shutdown(
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut resource_table = isolate.resource_table.borrow_mut();
|
let mut resource_table = isolate_state.resource_table.borrow_mut();
|
||||||
let resource_holder = resource_table
|
let resource_holder = resource_table
|
||||||
.get_mut::<StreamResourceHolder>(rid)
|
.get_mut::<StreamResourceHolder>(rid)
|
||||||
.ok_or_else(OpError::bad_resource_id)?;
|
.ok_or_else(OpError::bad_resource_id)?;
|
||||||
|
@ -484,12 +485,12 @@ fn listen_udp(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_listen(
|
fn op_listen(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
state: &State,
|
state: &State,
|
||||||
args: Value,
|
args: Value,
|
||||||
_zero_copy: Option<ZeroCopyBuf>,
|
_zero_copy: Option<ZeroCopyBuf>,
|
||||||
) -> Result<JsonOp, OpError> {
|
) -> Result<JsonOp, OpError> {
|
||||||
let mut resource_table = isolate.resource_table.borrow_mut();
|
let mut resource_table = isolate_state.resource_table.borrow_mut();
|
||||||
match serde_json::from_value(args)? {
|
match serde_json::from_value(args)? {
|
||||||
ListenArgs {
|
ListenArgs {
|
||||||
transport,
|
transport,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use super::dispatch_json::{Deserialize, JsonOp};
|
use super::dispatch_json::{Deserialize, JsonOp};
|
||||||
use super::io::{StreamResource, StreamResourceHolder};
|
use super::io::{StreamResource, StreamResourceHolder};
|
||||||
use crate::op_error::OpError;
|
use crate::op_error::OpError;
|
||||||
use deno_core::CoreIsolate;
|
use deno_core::CoreIsolateState;
|
||||||
use deno_core::ResourceTable;
|
use deno_core::ResourceTable;
|
||||||
use deno_core::ZeroCopyBuf;
|
use deno_core::ZeroCopyBuf;
|
||||||
use futures::future::FutureExt;
|
use futures::future::FutureExt;
|
||||||
|
@ -27,11 +27,11 @@ pub struct UnixListenArgs {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn accept_unix(
|
pub fn accept_unix(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
rid: u32,
|
rid: u32,
|
||||||
_zero_copy: Option<ZeroCopyBuf>,
|
_zero_copy: Option<ZeroCopyBuf>,
|
||||||
) -> Result<JsonOp, OpError> {
|
) -> Result<JsonOp, OpError> {
|
||||||
let resource_table = isolate.resource_table.clone();
|
let resource_table = isolate_state.resource_table.clone();
|
||||||
{
|
{
|
||||||
let _ = resource_table
|
let _ = resource_table
|
||||||
.borrow()
|
.borrow()
|
||||||
|
@ -78,12 +78,12 @@ pub fn accept_unix(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn receive_unix_packet(
|
pub fn receive_unix_packet(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
rid: u32,
|
rid: u32,
|
||||||
zero_copy: Option<ZeroCopyBuf>,
|
zero_copy: Option<ZeroCopyBuf>,
|
||||||
) -> Result<JsonOp, OpError> {
|
) -> Result<JsonOp, OpError> {
|
||||||
let mut buf = zero_copy.unwrap();
|
let mut buf = zero_copy.unwrap();
|
||||||
let resource_table = isolate.resource_table.clone();
|
let resource_table = isolate_state.resource_table.clone();
|
||||||
|
|
||||||
let op = async move {
|
let op = async move {
|
||||||
let mut resource_table_ = resource_table.borrow_mut();
|
let mut resource_table_ = resource_table.borrow_mut();
|
||||||
|
|
|
@ -7,6 +7,7 @@ use crate::ops::json_op;
|
||||||
use crate::state::State;
|
use crate::state::State;
|
||||||
use deno_core::plugin_api;
|
use deno_core::plugin_api;
|
||||||
use deno_core::CoreIsolate;
|
use deno_core::CoreIsolate;
|
||||||
|
use deno_core::CoreIsolateState;
|
||||||
use deno_core::Op;
|
use deno_core::Op;
|
||||||
use deno_core::OpAsyncFuture;
|
use deno_core::OpAsyncFuture;
|
||||||
use deno_core::OpId;
|
use deno_core::OpId;
|
||||||
|
@ -33,7 +34,7 @@ struct OpenPluginArgs {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn op_open_plugin(
|
pub fn op_open_plugin(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
state: &State,
|
state: &State,
|
||||||
args: Value,
|
args: Value,
|
||||||
_zero_copy: Option<ZeroCopyBuf>,
|
_zero_copy: Option<ZeroCopyBuf>,
|
||||||
|
@ -50,7 +51,7 @@ pub fn op_open_plugin(
|
||||||
.map_err(OpError::from)?;
|
.map_err(OpError::from)?;
|
||||||
let plugin_resource = PluginResource::new(&plugin_lib);
|
let plugin_resource = PluginResource::new(&plugin_lib);
|
||||||
|
|
||||||
let mut resource_table = isolate.resource_table.borrow_mut();
|
let mut resource_table = isolate_state.resource_table.borrow_mut();
|
||||||
let rid = resource_table.add("plugin", Box::new(plugin_resource));
|
let rid = resource_table.add("plugin", Box::new(plugin_resource));
|
||||||
let plugin_resource = resource_table.get::<PluginResource>(rid).unwrap();
|
let plugin_resource = resource_table.get::<PluginResource>(rid).unwrap();
|
||||||
|
|
||||||
|
@ -62,7 +63,7 @@ pub fn op_open_plugin(
|
||||||
.unwrap();
|
.unwrap();
|
||||||
drop(resource_table);
|
drop(resource_table);
|
||||||
|
|
||||||
let mut interface = PluginInterface::new(isolate, &plugin_lib);
|
let mut interface = PluginInterface::new(isolate_state, &plugin_lib);
|
||||||
deno_plugin_init(&mut interface);
|
deno_plugin_init(&mut interface);
|
||||||
|
|
||||||
Ok(JsonOp::Sync(json!(rid)))
|
Ok(JsonOp::Sync(json!(rid)))
|
||||||
|
@ -79,14 +80,17 @@ impl PluginResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PluginInterface<'a> {
|
struct PluginInterface<'a> {
|
||||||
isolate: &'a mut CoreIsolate,
|
isolate_state: &'a mut CoreIsolateState,
|
||||||
plugin_lib: &'a Rc<Library>,
|
plugin_lib: &'a Rc<Library>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> PluginInterface<'a> {
|
impl<'a> PluginInterface<'a> {
|
||||||
fn new(isolate: &'a mut CoreIsolate, plugin_lib: &'a Rc<Library>) -> Self {
|
fn new(
|
||||||
|
isolate_state: &'a mut CoreIsolateState,
|
||||||
|
plugin_lib: &'a Rc<Library>,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
isolate,
|
isolate_state,
|
||||||
plugin_lib,
|
plugin_lib,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,10 +108,10 @@ impl<'a> plugin_api::Interface for PluginInterface<'a> {
|
||||||
dispatch_op_fn: plugin_api::DispatchOpFn,
|
dispatch_op_fn: plugin_api::DispatchOpFn,
|
||||||
) -> OpId {
|
) -> OpId {
|
||||||
let plugin_lib = self.plugin_lib.clone();
|
let plugin_lib = self.plugin_lib.clone();
|
||||||
self.isolate.op_registry.register(
|
self.isolate_state.op_registry.register(
|
||||||
name,
|
name,
|
||||||
move |isolate, control, zero_copy| {
|
move |isolate_state, control, zero_copy| {
|
||||||
let mut interface = PluginInterface::new(isolate, &plugin_lib);
|
let mut interface = PluginInterface::new(isolate_state, &plugin_lib);
|
||||||
let op = dispatch_op_fn(&mut interface, control, zero_copy);
|
let op = dispatch_op_fn(&mut interface, control, zero_copy);
|
||||||
match op {
|
match op {
|
||||||
sync_op @ Op::Sync(..) => sync_op,
|
sync_op @ Op::Sync(..) => sync_op,
|
||||||
|
|
|
@ -5,6 +5,7 @@ use crate::op_error::OpError;
|
||||||
use crate::signal::kill;
|
use crate::signal::kill;
|
||||||
use crate::state::State;
|
use crate::state::State;
|
||||||
use deno_core::CoreIsolate;
|
use deno_core::CoreIsolate;
|
||||||
|
use deno_core::CoreIsolateState;
|
||||||
use deno_core::ResourceTable;
|
use deno_core::ResourceTable;
|
||||||
use deno_core::ZeroCopyBuf;
|
use deno_core::ZeroCopyBuf;
|
||||||
use futures::future::poll_fn;
|
use futures::future::poll_fn;
|
||||||
|
@ -60,7 +61,7 @@ struct ChildResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_run(
|
fn op_run(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
state: &State,
|
state: &State,
|
||||||
args: Value,
|
args: Value,
|
||||||
_zero_copy: Option<ZeroCopyBuf>,
|
_zero_copy: Option<ZeroCopyBuf>,
|
||||||
|
@ -68,7 +69,7 @@ fn op_run(
|
||||||
let run_args: RunArgs = serde_json::from_value(args)?;
|
let run_args: RunArgs = serde_json::from_value(args)?;
|
||||||
|
|
||||||
state.check_run()?;
|
state.check_run()?;
|
||||||
let mut resource_table = isolate.resource_table.borrow_mut();
|
let mut resource_table = isolate_state.resource_table.borrow_mut();
|
||||||
|
|
||||||
let args = run_args.cmd;
|
let args = run_args.cmd;
|
||||||
let env = run_args.env;
|
let env = run_args.env;
|
||||||
|
@ -174,7 +175,7 @@ struct RunStatusArgs {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_run_status(
|
fn op_run_status(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
state: &State,
|
state: &State,
|
||||||
args: Value,
|
args: Value,
|
||||||
_zero_copy: Option<ZeroCopyBuf>,
|
_zero_copy: Option<ZeroCopyBuf>,
|
||||||
|
@ -183,7 +184,7 @@ fn op_run_status(
|
||||||
let rid = args.rid as u32;
|
let rid = args.rid as u32;
|
||||||
|
|
||||||
state.check_run()?;
|
state.check_run()?;
|
||||||
let resource_table = isolate.resource_table.clone();
|
let resource_table = isolate_state.resource_table.clone();
|
||||||
|
|
||||||
let future = async move {
|
let future = async move {
|
||||||
let run_status = poll_fn(|cx| {
|
let run_status = poll_fn(|cx| {
|
||||||
|
|
|
@ -5,6 +5,7 @@ use crate::repl;
|
||||||
use crate::repl::Repl;
|
use crate::repl::Repl;
|
||||||
use crate::state::State;
|
use crate::state::State;
|
||||||
use deno_core::CoreIsolate;
|
use deno_core::CoreIsolate;
|
||||||
|
use deno_core::CoreIsolateState;
|
||||||
use deno_core::ZeroCopyBuf;
|
use deno_core::ZeroCopyBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
@ -23,7 +24,7 @@ struct ReplStartArgs {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_repl_start(
|
fn op_repl_start(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
state: &State,
|
state: &State,
|
||||||
args: Value,
|
args: Value,
|
||||||
_zero_copy: Option<ZeroCopyBuf>,
|
_zero_copy: Option<ZeroCopyBuf>,
|
||||||
|
@ -34,7 +35,7 @@ fn op_repl_start(
|
||||||
repl::history_path(&state.borrow().global_state.dir, &args.history_file);
|
repl::history_path(&state.borrow().global_state.dir, &args.history_file);
|
||||||
let repl = repl::Repl::new(history_path);
|
let repl = repl::Repl::new(history_path);
|
||||||
let resource = ReplResource(Arc::new(Mutex::new(repl)));
|
let resource = ReplResource(Arc::new(Mutex::new(repl)));
|
||||||
let mut resource_table = isolate.resource_table.borrow_mut();
|
let mut resource_table = isolate_state.resource_table.borrow_mut();
|
||||||
let rid = resource_table.add("repl", Box::new(resource));
|
let rid = resource_table.add("repl", Box::new(resource));
|
||||||
Ok(JsonOp::Sync(json!(rid)))
|
Ok(JsonOp::Sync(json!(rid)))
|
||||||
}
|
}
|
||||||
|
@ -46,7 +47,7 @@ struct ReplReadlineArgs {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_repl_readline(
|
fn op_repl_readline(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
_state: &State,
|
_state: &State,
|
||||||
args: Value,
|
args: Value,
|
||||||
_zero_copy: Option<ZeroCopyBuf>,
|
_zero_copy: Option<ZeroCopyBuf>,
|
||||||
|
@ -55,7 +56,7 @@ fn op_repl_readline(
|
||||||
let rid = args.rid as u32;
|
let rid = args.rid as u32;
|
||||||
let prompt = args.prompt;
|
let prompt = args.prompt;
|
||||||
debug!("op_repl_readline {} {}", rid, prompt);
|
debug!("op_repl_readline {} {}", rid, prompt);
|
||||||
let resource_table = isolate.resource_table.borrow();
|
let resource_table = isolate_state.resource_table.borrow();
|
||||||
let resource = resource_table
|
let resource = resource_table
|
||||||
.get::<ReplResource>(rid)
|
.get::<ReplResource>(rid)
|
||||||
.ok_or_else(OpError::bad_resource_id)?;
|
.ok_or_else(OpError::bad_resource_id)?;
|
||||||
|
|
|
@ -3,6 +3,7 @@ use super::dispatch_json::{Deserialize, JsonOp, Value};
|
||||||
use crate::op_error::OpError;
|
use crate::op_error::OpError;
|
||||||
use crate::state::State;
|
use crate::state::State;
|
||||||
use deno_core::CoreIsolate;
|
use deno_core::CoreIsolate;
|
||||||
|
use deno_core::CoreIsolateState;
|
||||||
use deno_core::ZeroCopyBuf;
|
use deno_core::ZeroCopyBuf;
|
||||||
|
|
||||||
pub fn init(i: &mut CoreIsolate, s: &State) {
|
pub fn init(i: &mut CoreIsolate, s: &State) {
|
||||||
|
@ -11,18 +12,18 @@ pub fn init(i: &mut CoreIsolate, s: &State) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_resources(
|
fn op_resources(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
_state: &State,
|
_state: &State,
|
||||||
_args: Value,
|
_args: Value,
|
||||||
_zero_copy: Option<ZeroCopyBuf>,
|
_zero_copy: Option<ZeroCopyBuf>,
|
||||||
) -> Result<JsonOp, OpError> {
|
) -> Result<JsonOp, OpError> {
|
||||||
let serialized_resources = isolate.resource_table.borrow().entries();
|
let serialized_resources = isolate_state.resource_table.borrow().entries();
|
||||||
Ok(JsonOp::Sync(json!(serialized_resources)))
|
Ok(JsonOp::Sync(json!(serialized_resources)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// op_close removes a resource from the resource table.
|
/// op_close removes a resource from the resource table.
|
||||||
fn op_close(
|
fn op_close(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
_state: &State,
|
_state: &State,
|
||||||
args: Value,
|
args: Value,
|
||||||
_zero_copy: Option<ZeroCopyBuf>,
|
_zero_copy: Option<ZeroCopyBuf>,
|
||||||
|
@ -32,7 +33,7 @@ fn op_close(
|
||||||
rid: i32,
|
rid: i32,
|
||||||
}
|
}
|
||||||
let args: CloseArgs = serde_json::from_value(args)?;
|
let args: CloseArgs = serde_json::from_value(args)?;
|
||||||
let mut resource_table = isolate.resource_table.borrow_mut();
|
let mut resource_table = isolate_state.resource_table.borrow_mut();
|
||||||
resource_table
|
resource_table
|
||||||
.close(args.rid as u32)
|
.close(args.rid as u32)
|
||||||
.ok_or_else(OpError::bad_resource_id)?;
|
.ok_or_else(OpError::bad_resource_id)?;
|
||||||
|
|
|
@ -3,6 +3,7 @@ use super::dispatch_json::{JsonOp, Value};
|
||||||
use crate::op_error::OpError;
|
use crate::op_error::OpError;
|
||||||
use crate::state::State;
|
use crate::state::State;
|
||||||
use deno_core::CoreIsolate;
|
use deno_core::CoreIsolate;
|
||||||
|
use deno_core::CoreIsolateState;
|
||||||
use deno_core::ZeroCopyBuf;
|
use deno_core::ZeroCopyBuf;
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
|
@ -39,14 +40,14 @@ struct SignalArgs {
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
fn op_signal_bind(
|
fn op_signal_bind(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
state: &State,
|
state: &State,
|
||||||
args: Value,
|
args: Value,
|
||||||
_zero_copy: Option<ZeroCopyBuf>,
|
_zero_copy: Option<ZeroCopyBuf>,
|
||||||
) -> Result<JsonOp, OpError> {
|
) -> Result<JsonOp, OpError> {
|
||||||
state.check_unstable("Deno.signal");
|
state.check_unstable("Deno.signal");
|
||||||
let args: BindSignalArgs = serde_json::from_value(args)?;
|
let args: BindSignalArgs = serde_json::from_value(args)?;
|
||||||
let mut resource_table = isolate.resource_table.borrow_mut();
|
let mut resource_table = isolate_state.resource_table.borrow_mut();
|
||||||
let rid = resource_table.add(
|
let rid = resource_table.add(
|
||||||
"signal",
|
"signal",
|
||||||
Box::new(SignalStreamResource(
|
Box::new(SignalStreamResource(
|
||||||
|
@ -61,7 +62,7 @@ fn op_signal_bind(
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
fn op_signal_poll(
|
fn op_signal_poll(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
state: &State,
|
state: &State,
|
||||||
args: Value,
|
args: Value,
|
||||||
_zero_copy: Option<ZeroCopyBuf>,
|
_zero_copy: Option<ZeroCopyBuf>,
|
||||||
|
@ -69,7 +70,7 @@ fn op_signal_poll(
|
||||||
state.check_unstable("Deno.signal");
|
state.check_unstable("Deno.signal");
|
||||||
let args: SignalArgs = serde_json::from_value(args)?;
|
let args: SignalArgs = serde_json::from_value(args)?;
|
||||||
let rid = args.rid as u32;
|
let rid = args.rid as u32;
|
||||||
let resource_table = isolate.resource_table.clone();
|
let resource_table = isolate_state.resource_table.clone();
|
||||||
|
|
||||||
let future = poll_fn(move |cx| {
|
let future = poll_fn(move |cx| {
|
||||||
let mut resource_table = resource_table.borrow_mut();
|
let mut resource_table = resource_table.borrow_mut();
|
||||||
|
@ -88,7 +89,7 @@ fn op_signal_poll(
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
pub fn op_signal_unbind(
|
pub fn op_signal_unbind(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
state: &State,
|
state: &State,
|
||||||
args: Value,
|
args: Value,
|
||||||
_zero_copy: Option<ZeroCopyBuf>,
|
_zero_copy: Option<ZeroCopyBuf>,
|
||||||
|
@ -96,7 +97,7 @@ pub fn op_signal_unbind(
|
||||||
state.check_unstable("Deno.signal");
|
state.check_unstable("Deno.signal");
|
||||||
let args: SignalArgs = serde_json::from_value(args)?;
|
let args: SignalArgs = serde_json::from_value(args)?;
|
||||||
let rid = args.rid as u32;
|
let rid = args.rid as u32;
|
||||||
let mut resource_table = isolate.resource_table.borrow_mut();
|
let mut resource_table = isolate_state.resource_table.borrow_mut();
|
||||||
let resource = resource_table.get::<SignalStreamResource>(rid);
|
let resource = resource_table.get::<SignalStreamResource>(rid);
|
||||||
if let Some(signal) = resource {
|
if let Some(signal) = resource {
|
||||||
if let Some(waker) = &signal.1 {
|
if let Some(waker) = &signal.1 {
|
||||||
|
@ -113,7 +114,7 @@ pub fn op_signal_unbind(
|
||||||
|
|
||||||
#[cfg(not(unix))]
|
#[cfg(not(unix))]
|
||||||
pub fn op_signal_bind(
|
pub fn op_signal_bind(
|
||||||
_isolate: &mut CoreIsolate,
|
_isolate_state: &mut CoreIsolateState,
|
||||||
_state: &State,
|
_state: &State,
|
||||||
_args: Value,
|
_args: Value,
|
||||||
_zero_copy: Option<ZeroCopyBuf>,
|
_zero_copy: Option<ZeroCopyBuf>,
|
||||||
|
@ -123,7 +124,7 @@ pub fn op_signal_bind(
|
||||||
|
|
||||||
#[cfg(not(unix))]
|
#[cfg(not(unix))]
|
||||||
fn op_signal_unbind(
|
fn op_signal_unbind(
|
||||||
_isolate: &mut CoreIsolate,
|
_isolate_state: &mut CoreIsolateState,
|
||||||
_state: &State,
|
_state: &State,
|
||||||
_args: Value,
|
_args: Value,
|
||||||
_zero_copy: Option<ZeroCopyBuf>,
|
_zero_copy: Option<ZeroCopyBuf>,
|
||||||
|
@ -133,7 +134,7 @@ fn op_signal_unbind(
|
||||||
|
|
||||||
#[cfg(not(unix))]
|
#[cfg(not(unix))]
|
||||||
fn op_signal_poll(
|
fn op_signal_poll(
|
||||||
_isolate: &mut CoreIsolate,
|
_isolate_state: &mut CoreIsolateState,
|
||||||
_state: &State,
|
_state: &State,
|
||||||
_args: Value,
|
_args: Value,
|
||||||
_zero_copy: Option<ZeroCopyBuf>,
|
_zero_copy: Option<ZeroCopyBuf>,
|
||||||
|
|
|
@ -5,6 +5,7 @@ use crate::op_error::OpError;
|
||||||
use crate::resolve_addr::resolve_addr;
|
use crate::resolve_addr::resolve_addr;
|
||||||
use crate::state::State;
|
use crate::state::State;
|
||||||
use deno_core::CoreIsolate;
|
use deno_core::CoreIsolate;
|
||||||
|
use deno_core::CoreIsolateState;
|
||||||
use deno_core::ZeroCopyBuf;
|
use deno_core::ZeroCopyBuf;
|
||||||
use futures::future::poll_fn;
|
use futures::future::poll_fn;
|
||||||
use futures::future::FutureExt;
|
use futures::future::FutureExt;
|
||||||
|
@ -53,7 +54,7 @@ struct StartTLSArgs {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn op_start_tls(
|
pub fn op_start_tls(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
state: &State,
|
state: &State,
|
||||||
args: Value,
|
args: Value,
|
||||||
_zero_copy: Option<ZeroCopyBuf>,
|
_zero_copy: Option<ZeroCopyBuf>,
|
||||||
|
@ -62,7 +63,7 @@ pub fn op_start_tls(
|
||||||
let args: StartTLSArgs = serde_json::from_value(args)?;
|
let args: StartTLSArgs = serde_json::from_value(args)?;
|
||||||
let rid = args.rid as u32;
|
let rid = args.rid as u32;
|
||||||
let cert_file = args.cert_file.clone();
|
let cert_file = args.cert_file.clone();
|
||||||
let resource_table = isolate.resource_table.clone();
|
let resource_table = isolate_state.resource_table.clone();
|
||||||
|
|
||||||
let mut domain = args.hostname;
|
let mut domain = args.hostname;
|
||||||
if domain.is_empty() {
|
if domain.is_empty() {
|
||||||
|
@ -132,14 +133,14 @@ pub fn op_start_tls(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn op_connect_tls(
|
pub fn op_connect_tls(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
state: &State,
|
state: &State,
|
||||||
args: Value,
|
args: Value,
|
||||||
_zero_copy: Option<ZeroCopyBuf>,
|
_zero_copy: Option<ZeroCopyBuf>,
|
||||||
) -> Result<JsonOp, OpError> {
|
) -> Result<JsonOp, OpError> {
|
||||||
let args: ConnectTLSArgs = serde_json::from_value(args)?;
|
let args: ConnectTLSArgs = serde_json::from_value(args)?;
|
||||||
let cert_file = args.cert_file.clone();
|
let cert_file = args.cert_file.clone();
|
||||||
let resource_table = isolate.resource_table.clone();
|
let resource_table = isolate_state.resource_table.clone();
|
||||||
state.check_net(&args.hostname, args.port)?;
|
state.check_net(&args.hostname, args.port)?;
|
||||||
if let Some(path) = cert_file.clone() {
|
if let Some(path) = cert_file.clone() {
|
||||||
state.check_read(Path::new(&path))?;
|
state.check_read(Path::new(&path))?;
|
||||||
|
@ -306,7 +307,7 @@ struct ListenTlsArgs {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_listen_tls(
|
fn op_listen_tls(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
state: &State,
|
state: &State,
|
||||||
args: Value,
|
args: Value,
|
||||||
_zero_copy: Option<ZeroCopyBuf>,
|
_zero_copy: Option<ZeroCopyBuf>,
|
||||||
|
@ -337,7 +338,7 @@ fn op_listen_tls(
|
||||||
local_addr,
|
local_addr,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut resource_table = isolate.resource_table.borrow_mut();
|
let mut resource_table = isolate_state.resource_table.borrow_mut();
|
||||||
let rid = resource_table.add("tlsListener", Box::new(tls_listener_resource));
|
let rid = resource_table.add("tlsListener", Box::new(tls_listener_resource));
|
||||||
|
|
||||||
Ok(JsonOp::Sync(json!({
|
Ok(JsonOp::Sync(json!({
|
||||||
|
@ -356,14 +357,14 @@ struct AcceptTlsArgs {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_accept_tls(
|
fn op_accept_tls(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
_state: &State,
|
_state: &State,
|
||||||
args: Value,
|
args: Value,
|
||||||
_zero_copy: Option<ZeroCopyBuf>,
|
_zero_copy: Option<ZeroCopyBuf>,
|
||||||
) -> Result<JsonOp, OpError> {
|
) -> Result<JsonOp, OpError> {
|
||||||
let args: AcceptTlsArgs = serde_json::from_value(args)?;
|
let args: AcceptTlsArgs = serde_json::from_value(args)?;
|
||||||
let rid = args.rid as u32;
|
let rid = args.rid as u32;
|
||||||
let resource_table = isolate.resource_table.clone();
|
let resource_table = isolate_state.resource_table.clone();
|
||||||
let op = async move {
|
let op = async move {
|
||||||
let accept_fut = poll_fn(|cx| {
|
let accept_fut = poll_fn(|cx| {
|
||||||
let mut resource_table = resource_table.borrow_mut();
|
let mut resource_table = resource_table.borrow_mut();
|
||||||
|
|
|
@ -4,6 +4,7 @@ use super::io::{StreamResource, StreamResourceHolder};
|
||||||
use crate::op_error::OpError;
|
use crate::op_error::OpError;
|
||||||
use crate::state::State;
|
use crate::state::State;
|
||||||
use deno_core::CoreIsolate;
|
use deno_core::CoreIsolate;
|
||||||
|
use deno_core::CoreIsolateState;
|
||||||
use deno_core::ZeroCopyBuf;
|
use deno_core::ZeroCopyBuf;
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
use nix::sys::termios;
|
use nix::sys::termios;
|
||||||
|
@ -46,7 +47,7 @@ struct SetRawArgs {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn op_set_raw(
|
pub fn op_set_raw(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
state: &State,
|
state: &State,
|
||||||
args: Value,
|
args: Value,
|
||||||
_zero_copy: Option<ZeroCopyBuf>,
|
_zero_copy: Option<ZeroCopyBuf>,
|
||||||
|
@ -67,7 +68,7 @@ pub fn op_set_raw(
|
||||||
use winapi::shared::minwindef::FALSE;
|
use winapi::shared::minwindef::FALSE;
|
||||||
use winapi::um::{consoleapi, handleapi};
|
use winapi::um::{consoleapi, handleapi};
|
||||||
|
|
||||||
let mut resource_table = isolate.resource_table.borrow_mut();
|
let mut resource_table = isolate_state.resource_table.borrow_mut();
|
||||||
let resource_holder = resource_table.get_mut::<StreamResourceHolder>(rid);
|
let resource_holder = resource_table.get_mut::<StreamResourceHolder>(rid);
|
||||||
if resource_holder.is_none() {
|
if resource_holder.is_none() {
|
||||||
return Err(OpError::bad_resource_id());
|
return Err(OpError::bad_resource_id());
|
||||||
|
@ -133,7 +134,7 @@ pub fn op_set_raw(
|
||||||
{
|
{
|
||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::AsRawFd;
|
||||||
|
|
||||||
let mut resource_table = isolate.resource_table.borrow_mut();
|
let mut resource_table = isolate_state.resource_table.borrow_mut();
|
||||||
let resource_holder = resource_table.get_mut::<StreamResourceHolder>(rid);
|
let resource_holder = resource_table.get_mut::<StreamResourceHolder>(rid);
|
||||||
if resource_holder.is_none() {
|
if resource_holder.is_none() {
|
||||||
return Err(OpError::bad_resource_id());
|
return Err(OpError::bad_resource_id());
|
||||||
|
@ -215,7 +216,7 @@ struct IsattyArgs {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn op_isatty(
|
pub fn op_isatty(
|
||||||
isolate: &mut CoreIsolate,
|
isolate_state: &mut CoreIsolateState,
|
||||||
_state: &State,
|
_state: &State,
|
||||||
args: Value,
|
args: Value,
|
||||||
_zero_copy: Option<ZeroCopyBuf>,
|
_zero_copy: Option<ZeroCopyBuf>,
|
||||||
|
@ -223,7 +224,7 @@ pub fn op_isatty(
|
||||||
let args: IsattyArgs = serde_json::from_value(args)?;
|
let args: IsattyArgs = serde_json::from_value(args)?;
|
||||||
let rid = args.rid;
|
let rid = args.rid;
|
||||||
|
|
||||||
let mut resource_table = isolate.resource_table.borrow_mut();
|
let mut resource_table = isolate_state.resource_table.borrow_mut();
|
||||||
let isatty: bool =
|
let isatty: bool =
|
||||||
std_file_resource(&mut resource_table, rid as u32, move |r| match r {
|
std_file_resource(&mut resource_table, rid as u32, move |r| match r {
|
||||||
Ok(std_file) => {
|
Ok(std_file) => {
|
||||||
|
|
|
@ -6,6 +6,7 @@ use crate::state::State;
|
||||||
use crate::web_worker::WebWorkerHandle;
|
use crate::web_worker::WebWorkerHandle;
|
||||||
use crate::worker::WorkerEvent;
|
use crate::worker::WorkerEvent;
|
||||||
use deno_core::CoreIsolate;
|
use deno_core::CoreIsolate;
|
||||||
|
use deno_core::CoreIsolateState;
|
||||||
use deno_core::ZeroCopyBuf;
|
use deno_core::ZeroCopyBuf;
|
||||||
use futures::channel::mpsc;
|
use futures::channel::mpsc;
|
||||||
use std::convert::From;
|
use std::convert::From;
|
||||||
|
@ -13,7 +14,11 @@ use std::convert::From;
|
||||||
pub fn web_worker_op<D>(
|
pub fn web_worker_op<D>(
|
||||||
sender: mpsc::Sender<WorkerEvent>,
|
sender: mpsc::Sender<WorkerEvent>,
|
||||||
dispatcher: D,
|
dispatcher: D,
|
||||||
) -> impl Fn(&mut CoreIsolate, Value, Option<ZeroCopyBuf>) -> Result<JsonOp, OpError>
|
) -> impl Fn(
|
||||||
|
&mut CoreIsolateState,
|
||||||
|
Value,
|
||||||
|
Option<ZeroCopyBuf>,
|
||||||
|
) -> Result<JsonOp, OpError>
|
||||||
where
|
where
|
||||||
D: Fn(
|
D: Fn(
|
||||||
&mpsc::Sender<WorkerEvent>,
|
&mpsc::Sender<WorkerEvent>,
|
||||||
|
@ -21,7 +26,7 @@ where
|
||||||
Option<ZeroCopyBuf>,
|
Option<ZeroCopyBuf>,
|
||||||
) -> Result<JsonOp, OpError>,
|
) -> Result<JsonOp, OpError>,
|
||||||
{
|
{
|
||||||
move |_isolate: &mut CoreIsolate,
|
move |_isolate_state: &mut CoreIsolateState,
|
||||||
args: Value,
|
args: Value,
|
||||||
zero_copy: Option<ZeroCopyBuf>|
|
zero_copy: Option<ZeroCopyBuf>|
|
||||||
-> Result<JsonOp, OpError> { dispatcher(&sender, args, zero_copy) }
|
-> Result<JsonOp, OpError> { dispatcher(&sender, args, zero_copy) }
|
||||||
|
@ -31,7 +36,11 @@ pub fn web_worker_op2<D>(
|
||||||
handle: WebWorkerHandle,
|
handle: WebWorkerHandle,
|
||||||
sender: mpsc::Sender<WorkerEvent>,
|
sender: mpsc::Sender<WorkerEvent>,
|
||||||
dispatcher: D,
|
dispatcher: D,
|
||||||
) -> impl Fn(&mut CoreIsolate, Value, Option<ZeroCopyBuf>) -> Result<JsonOp, OpError>
|
) -> impl Fn(
|
||||||
|
&mut CoreIsolateState,
|
||||||
|
Value,
|
||||||
|
Option<ZeroCopyBuf>,
|
||||||
|
) -> Result<JsonOp, OpError>
|
||||||
where
|
where
|
||||||
D: Fn(
|
D: Fn(
|
||||||
WebWorkerHandle,
|
WebWorkerHandle,
|
||||||
|
@ -40,7 +49,7 @@ where
|
||||||
Option<ZeroCopyBuf>,
|
Option<ZeroCopyBuf>,
|
||||||
) -> Result<JsonOp, OpError>,
|
) -> Result<JsonOp, OpError>,
|
||||||
{
|
{
|
||||||
move |_isolate: &mut CoreIsolate,
|
move |_isolate_state: &mut CoreIsolateState,
|
||||||
args: Value,
|
args: Value,
|
||||||
zero_copy: Option<ZeroCopyBuf>|
|
zero_copy: Option<ZeroCopyBuf>|
|
||||||
-> Result<JsonOp, OpError> {
|
-> Result<JsonOp, OpError> {
|
||||||
|
|
|
@ -54,7 +54,9 @@ fn create_web_worker(
|
||||||
);
|
);
|
||||||
|
|
||||||
if has_deno_namespace {
|
if has_deno_namespace {
|
||||||
let mut resource_table = worker.resource_table.borrow_mut();
|
let state_rc = CoreIsolate::state(&worker.isolate);
|
||||||
|
let state = state_rc.borrow();
|
||||||
|
let mut resource_table = state.resource_table.borrow_mut();
|
||||||
let (stdin, stdout, stderr) = get_stdio();
|
let (stdin, stdout, stderr) = get_stdio();
|
||||||
resource_table.add("stdin", Box::new(stdin));
|
resource_table.add("stdin", Box::new(stdin));
|
||||||
resource_table.add("stdout", Box::new(stdout));
|
resource_table.add("stdout", Box::new(stdout));
|
||||||
|
|
34
cli/state.rs
34
cli/state.rs
|
@ -65,7 +65,7 @@ impl State {
|
||||||
pub fn stateful_json_op<D>(
|
pub fn stateful_json_op<D>(
|
||||||
&self,
|
&self,
|
||||||
dispatcher: D,
|
dispatcher: D,
|
||||||
) -> impl Fn(&mut deno_core::CoreIsolate, &[u8], Option<ZeroCopyBuf>) -> Op
|
) -> impl Fn(&mut deno_core::CoreIsolateState, &[u8], Option<ZeroCopyBuf>) -> Op
|
||||||
where
|
where
|
||||||
D: Fn(&State, Value, Option<ZeroCopyBuf>) -> Result<JsonOp, OpError>,
|
D: Fn(&State, Value, Option<ZeroCopyBuf>) -> Result<JsonOp, OpError>,
|
||||||
{
|
{
|
||||||
|
@ -76,10 +76,10 @@ impl State {
|
||||||
pub fn stateful_json_op2<D>(
|
pub fn stateful_json_op2<D>(
|
||||||
&self,
|
&self,
|
||||||
dispatcher: D,
|
dispatcher: D,
|
||||||
) -> impl Fn(&mut deno_core::CoreIsolate, &[u8], Option<ZeroCopyBuf>) -> Op
|
) -> impl Fn(&mut deno_core::CoreIsolateState, &[u8], Option<ZeroCopyBuf>) -> Op
|
||||||
where
|
where
|
||||||
D: Fn(
|
D: Fn(
|
||||||
&mut deno_core::CoreIsolate,
|
&mut deno_core::CoreIsolateState,
|
||||||
&State,
|
&State,
|
||||||
Value,
|
Value,
|
||||||
Option<ZeroCopyBuf>,
|
Option<ZeroCopyBuf>,
|
||||||
|
@ -95,13 +95,13 @@ impl State {
|
||||||
pub fn core_op<D>(
|
pub fn core_op<D>(
|
||||||
&self,
|
&self,
|
||||||
dispatcher: D,
|
dispatcher: D,
|
||||||
) -> impl Fn(&mut deno_core::CoreIsolate, &[u8], Option<ZeroCopyBuf>) -> Op
|
) -> impl Fn(&mut deno_core::CoreIsolateState, &[u8], Option<ZeroCopyBuf>) -> Op
|
||||||
where
|
where
|
||||||
D: Fn(&mut deno_core::CoreIsolate, &[u8], Option<ZeroCopyBuf>) -> Op,
|
D: Fn(&mut deno_core::CoreIsolateState, &[u8], Option<ZeroCopyBuf>) -> Op,
|
||||||
{
|
{
|
||||||
let state = self.clone();
|
let state = self.clone();
|
||||||
|
|
||||||
move |isolate: &mut deno_core::CoreIsolate,
|
move |isolate_state: &mut deno_core::CoreIsolateState,
|
||||||
control: &[u8],
|
control: &[u8],
|
||||||
zero_copy: Option<ZeroCopyBuf>|
|
zero_copy: Option<ZeroCopyBuf>|
|
||||||
-> Op {
|
-> Op {
|
||||||
|
@ -109,7 +109,7 @@ impl State {
|
||||||
let bytes_sent_zero_copy =
|
let bytes_sent_zero_copy =
|
||||||
zero_copy.as_ref().map(|b| b.len()).unwrap_or(0) as u64;
|
zero_copy.as_ref().map(|b| b.len()).unwrap_or(0) as u64;
|
||||||
|
|
||||||
let op = dispatcher(isolate, control, zero_copy);
|
let op = dispatcher(isolate_state, control, zero_copy);
|
||||||
|
|
||||||
match op {
|
match op {
|
||||||
Op::Sync(buf) => {
|
Op::Sync(buf) => {
|
||||||
|
@ -155,10 +155,10 @@ impl State {
|
||||||
pub fn stateful_minimal_op2<D>(
|
pub fn stateful_minimal_op2<D>(
|
||||||
&self,
|
&self,
|
||||||
dispatcher: D,
|
dispatcher: D,
|
||||||
) -> impl Fn(&mut deno_core::CoreIsolate, &[u8], Option<ZeroCopyBuf>) -> Op
|
) -> impl Fn(&mut deno_core::CoreIsolateState, &[u8], Option<ZeroCopyBuf>) -> Op
|
||||||
where
|
where
|
||||||
D: Fn(
|
D: Fn(
|
||||||
&mut deno_core::CoreIsolate,
|
&mut deno_core::CoreIsolateState,
|
||||||
&State,
|
&State,
|
||||||
bool,
|
bool,
|
||||||
i32,
|
i32,
|
||||||
|
@ -167,12 +167,12 @@ impl State {
|
||||||
{
|
{
|
||||||
let state = self.clone();
|
let state = self.clone();
|
||||||
self.core_op(crate::ops::minimal_op(
|
self.core_op(crate::ops::minimal_op(
|
||||||
move |isolate: &mut deno_core::CoreIsolate,
|
move |isolate_state: &mut deno_core::CoreIsolateState,
|
||||||
is_sync: bool,
|
is_sync: bool,
|
||||||
rid: i32,
|
rid: i32,
|
||||||
zero_copy: Option<ZeroCopyBuf>|
|
zero_copy: Option<ZeroCopyBuf>|
|
||||||
-> MinimalOp {
|
-> MinimalOp {
|
||||||
dispatcher(isolate, &state, is_sync, rid, zero_copy)
|
dispatcher(isolate_state, &state, is_sync, rid, zero_copy)
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -186,7 +186,7 @@ impl State {
|
||||||
&self,
|
&self,
|
||||||
dispatcher: D,
|
dispatcher: D,
|
||||||
) -> impl Fn(
|
) -> impl Fn(
|
||||||
&mut deno_core::CoreIsolate,
|
&mut deno_core::CoreIsolateState,
|
||||||
Value,
|
Value,
|
||||||
Option<ZeroCopyBuf>,
|
Option<ZeroCopyBuf>,
|
||||||
) -> Result<JsonOp, OpError>
|
) -> Result<JsonOp, OpError>
|
||||||
|
@ -194,7 +194,7 @@ impl State {
|
||||||
D: Fn(&State, Value, Option<ZeroCopyBuf>) -> Result<JsonOp, OpError>,
|
D: Fn(&State, Value, Option<ZeroCopyBuf>) -> Result<JsonOp, OpError>,
|
||||||
{
|
{
|
||||||
let state = self.clone();
|
let state = self.clone();
|
||||||
move |_isolate: &mut deno_core::CoreIsolate,
|
move |_isolate_state: &mut deno_core::CoreIsolateState,
|
||||||
args: Value,
|
args: Value,
|
||||||
zero_copy: Option<ZeroCopyBuf>|
|
zero_copy: Option<ZeroCopyBuf>|
|
||||||
-> Result<JsonOp, OpError> { dispatcher(&state, args, zero_copy) }
|
-> Result<JsonOp, OpError> { dispatcher(&state, args, zero_copy) }
|
||||||
|
@ -204,24 +204,24 @@ impl State {
|
||||||
&self,
|
&self,
|
||||||
dispatcher: D,
|
dispatcher: D,
|
||||||
) -> impl Fn(
|
) -> impl Fn(
|
||||||
&mut deno_core::CoreIsolate,
|
&mut deno_core::CoreIsolateState,
|
||||||
Value,
|
Value,
|
||||||
Option<ZeroCopyBuf>,
|
Option<ZeroCopyBuf>,
|
||||||
) -> Result<JsonOp, OpError>
|
) -> Result<JsonOp, OpError>
|
||||||
where
|
where
|
||||||
D: Fn(
|
D: Fn(
|
||||||
&mut deno_core::CoreIsolate,
|
&mut deno_core::CoreIsolateState,
|
||||||
&State,
|
&State,
|
||||||
Value,
|
Value,
|
||||||
Option<ZeroCopyBuf>,
|
Option<ZeroCopyBuf>,
|
||||||
) -> Result<JsonOp, OpError>,
|
) -> Result<JsonOp, OpError>,
|
||||||
{
|
{
|
||||||
let state = self.clone();
|
let state = self.clone();
|
||||||
move |isolate: &mut deno_core::CoreIsolate,
|
move |isolate_state: &mut deno_core::CoreIsolateState,
|
||||||
args: Value,
|
args: Value,
|
||||||
zero_copy: Option<ZeroCopyBuf>|
|
zero_copy: Option<ZeroCopyBuf>|
|
||||||
-> Result<JsonOp, OpError> {
|
-> Result<JsonOp, OpError> {
|
||||||
dispatcher(isolate, &state, args, zero_copy)
|
dispatcher(isolate_state, &state, args, zero_copy)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,12 +91,7 @@ impl WebWorker {
|
||||||
let mut worker = Worker::new(name, startup_data, state_);
|
let mut worker = Worker::new(name, startup_data, state_);
|
||||||
|
|
||||||
let terminated = Arc::new(AtomicBool::new(false));
|
let terminated = Arc::new(AtomicBool::new(false));
|
||||||
let isolate_handle = worker
|
let isolate_handle = worker.isolate.thread_safe_handle();
|
||||||
.isolate
|
|
||||||
.v8_isolate
|
|
||||||
.as_mut()
|
|
||||||
.unwrap()
|
|
||||||
.thread_safe_handle();
|
|
||||||
let (terminate_tx, terminate_rx) = mpsc::channel::<()>(1);
|
let (terminate_tx, terminate_rx) = mpsc::channel::<()>(1);
|
||||||
|
|
||||||
let handle = WebWorkerHandle {
|
let handle = WebWorkerHandle {
|
||||||
|
|
|
@ -4,6 +4,7 @@ use crate::inspector::DenoInspector;
|
||||||
use crate::ops;
|
use crate::ops;
|
||||||
use crate::state::State;
|
use crate::state::State;
|
||||||
use deno_core::Buf;
|
use deno_core::Buf;
|
||||||
|
use deno_core::CoreIsolate;
|
||||||
use deno_core::ErrBox;
|
use deno_core::ErrBox;
|
||||||
use deno_core::ModuleId;
|
use deno_core::ModuleId;
|
||||||
use deno_core::ModuleSpecifier;
|
use deno_core::ModuleSpecifier;
|
||||||
|
@ -86,7 +87,7 @@ fn create_channels() -> (WorkerChannelsInternal, WorkerHandle) {
|
||||||
/// - `WebWorker`
|
/// - `WebWorker`
|
||||||
pub struct Worker {
|
pub struct Worker {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub isolate: Box<deno_core::EsIsolate>,
|
pub isolate: deno_core::EsIsolate,
|
||||||
pub inspector: Option<Box<DenoInspector>>,
|
pub inspector: Option<Box<DenoInspector>>,
|
||||||
pub state: State,
|
pub state: State,
|
||||||
pub waker: AtomicWaker,
|
pub waker: AtomicWaker,
|
||||||
|
@ -101,7 +102,9 @@ impl Worker {
|
||||||
|
|
||||||
{
|
{
|
||||||
let global_state = state.borrow().global_state.clone();
|
let global_state = state.borrow().global_state.clone();
|
||||||
isolate.set_js_error_create_fn(move |core_js_error| {
|
let core_state_rc = CoreIsolate::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)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
103
core/bindings.rs
103
core/bindings.rs
|
@ -250,9 +250,6 @@ pub extern "C" fn host_import_module_dynamically_callback(
|
||||||
let mut cbs = v8::CallbackScope::new_escapable(context);
|
let mut cbs = v8::CallbackScope::new_escapable(context);
|
||||||
let mut hs = v8::EscapableHandleScope::new(cbs.enter());
|
let mut hs = v8::EscapableHandleScope::new(cbs.enter());
|
||||||
let scope = hs.enter();
|
let scope = hs.enter();
|
||||||
let isolate = scope.isolate();
|
|
||||||
let core_isolate: &mut EsIsolate =
|
|
||||||
unsafe { &mut *(isolate.get_data(1) as *mut EsIsolate) };
|
|
||||||
|
|
||||||
// NOTE(bartlomieju): will crash for non-UTF-8 specifier
|
// NOTE(bartlomieju): will crash for non-UTF-8 specifier
|
||||||
let specifier_str = specifier
|
let specifier_str = specifier
|
||||||
|
@ -277,11 +274,11 @@ pub extern "C" fn host_import_module_dynamically_callback(
|
||||||
let mut resolver_handle = v8::Global::new();
|
let mut resolver_handle = v8::Global::new();
|
||||||
resolver_handle.set(scope, resolver);
|
resolver_handle.set(scope, resolver);
|
||||||
|
|
||||||
core_isolate.dyn_import_cb(
|
{
|
||||||
resolver_handle,
|
let state_rc = EsIsolate::state(scope.isolate());
|
||||||
&specifier_str,
|
let mut state = state_rc.borrow_mut();
|
||||||
&referrer_name_str,
|
state.dyn_import_cb(resolver_handle, &specifier_str, &referrer_name_str);
|
||||||
);
|
}
|
||||||
|
|
||||||
&mut *scope.escape(promise)
|
&mut *scope.escape(promise)
|
||||||
}
|
}
|
||||||
|
@ -294,14 +291,13 @@ pub extern "C" fn host_initialize_import_meta_object_callback(
|
||||||
let mut cbs = v8::CallbackScope::new(context);
|
let mut cbs = v8::CallbackScope::new(context);
|
||||||
let mut hs = v8::HandleScope::new(cbs.enter());
|
let mut hs = v8::HandleScope::new(cbs.enter());
|
||||||
let scope = hs.enter();
|
let scope = hs.enter();
|
||||||
let isolate = scope.isolate();
|
let state_rc = EsIsolate::state(scope.isolate());
|
||||||
let core_isolate: &mut EsIsolate =
|
let state = state_rc.borrow();
|
||||||
unsafe { &mut *(isolate.get_data(1) as *mut EsIsolate) };
|
|
||||||
|
|
||||||
let id = module.get_identity_hash();
|
let id = module.get_identity_hash();
|
||||||
assert_ne!(id, 0);
|
assert_ne!(id, 0);
|
||||||
|
|
||||||
let info = core_isolate.modules.get_info(id).expect("Module not found");
|
let info = state.modules.get_info(id).expect("Module not found");
|
||||||
|
|
||||||
meta.create_data_property(
|
meta.create_data_property(
|
||||||
context,
|
context,
|
||||||
|
@ -320,10 +316,10 @@ pub extern "C" fn promise_reject_callback(message: v8::PromiseRejectMessage) {
|
||||||
let mut hs = v8::HandleScope::new(cbs.enter());
|
let mut hs = v8::HandleScope::new(cbs.enter());
|
||||||
let scope = hs.enter();
|
let scope = hs.enter();
|
||||||
|
|
||||||
let core_isolate: &mut CoreIsolate =
|
let state_rc = CoreIsolate::state(scope.isolate());
|
||||||
unsafe { &mut *(scope.isolate().get_data(0) as *mut CoreIsolate) };
|
let mut state = state_rc.borrow_mut();
|
||||||
|
|
||||||
let context = core_isolate.global_context.get(scope).unwrap();
|
let context = state.global_context.get(scope).unwrap();
|
||||||
let mut cs = v8::ContextScope::new(scope, context);
|
let mut cs = v8::ContextScope::new(scope, context);
|
||||||
let scope = cs.enter();
|
let scope = cs.enter();
|
||||||
|
|
||||||
|
@ -335,13 +331,13 @@ pub extern "C" fn promise_reject_callback(message: v8::PromiseRejectMessage) {
|
||||||
let error = message.get_value();
|
let error = message.get_value();
|
||||||
let mut error_global = v8::Global::<v8::Value>::new();
|
let mut error_global = v8::Global::<v8::Value>::new();
|
||||||
error_global.set(scope, error);
|
error_global.set(scope, error);
|
||||||
core_isolate
|
state
|
||||||
.pending_promise_exceptions
|
.pending_promise_exceptions
|
||||||
.insert(promise_id, error_global);
|
.insert(promise_id, error_global);
|
||||||
}
|
}
|
||||||
v8::PromiseRejectEvent::PromiseHandlerAddedAfterReject => {
|
v8::PromiseRejectEvent::PromiseHandlerAddedAfterReject => {
|
||||||
if let Some(mut handle) =
|
if let Some(mut handle) =
|
||||||
core_isolate.pending_promise_exceptions.remove(&promise_id)
|
state.pending_promise_exceptions.remove(&promise_id)
|
||||||
{
|
{
|
||||||
handle.reset(scope);
|
handle.reset(scope);
|
||||||
}
|
}
|
||||||
|
@ -415,17 +411,17 @@ fn recv(
|
||||||
args: v8::FunctionCallbackArguments,
|
args: v8::FunctionCallbackArguments,
|
||||||
_rv: v8::ReturnValue,
|
_rv: v8::ReturnValue,
|
||||||
) {
|
) {
|
||||||
let core_isolate: &mut CoreIsolate =
|
let state_rc = CoreIsolate::state(scope.isolate());
|
||||||
unsafe { &mut *(scope.isolate().get_data(0) as *mut CoreIsolate) };
|
let mut state = state_rc.borrow_mut();
|
||||||
|
|
||||||
if !core_isolate.js_recv_cb.is_empty() {
|
if !state.js_recv_cb.is_empty() {
|
||||||
let msg = v8::String::new(scope, "Deno.core.recv already called.").unwrap();
|
let msg = v8::String::new(scope, "Deno.core.recv already called.").unwrap();
|
||||||
scope.isolate().throw_exception(msg.into());
|
scope.isolate().throw_exception(msg.into());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let recv_fn = v8::Local::<v8::Function>::try_from(args.get(0)).unwrap();
|
let recv_fn = v8::Local::<v8::Function>::try_from(args.get(0)).unwrap();
|
||||||
core_isolate.js_recv_cb.set(scope, recv_fn);
|
state.js_recv_cb.set(scope, recv_fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send(
|
fn send(
|
||||||
|
@ -433,10 +429,6 @@ fn send(
|
||||||
args: v8::FunctionCallbackArguments,
|
args: v8::FunctionCallbackArguments,
|
||||||
mut rv: v8::ReturnValue,
|
mut rv: v8::ReturnValue,
|
||||||
) {
|
) {
|
||||||
let core_isolate: &mut CoreIsolate =
|
|
||||||
unsafe { &mut *(scope.isolate().get_data(0) as *mut CoreIsolate) };
|
|
||||||
assert!(!core_isolate.global_context.is_empty());
|
|
||||||
|
|
||||||
let op_id = match v8::Local::<v8::Uint32>::try_from(args.get(0)) {
|
let op_id = match v8::Local::<v8::Uint32>::try_from(args.get(0)) {
|
||||||
Ok(op_id) => op_id.value() as u32,
|
Ok(op_id) => op_id.value() as u32,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
@ -465,9 +457,12 @@ fn send(
|
||||||
.map(ZeroCopyBuf::new)
|
.map(ZeroCopyBuf::new)
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
|
let state_rc = CoreIsolate::state(scope.isolate());
|
||||||
|
let mut state = state_rc.borrow_mut();
|
||||||
|
assert!(!state.global_context.is_empty());
|
||||||
|
|
||||||
// If response is empty then it's either async op or exception was thrown
|
// If response is empty then it's either async op or exception was thrown
|
||||||
let maybe_response =
|
let maybe_response = state.dispatch_op(scope, op_id, control, zero_copy);
|
||||||
core_isolate.dispatch_op(scope, op_id, control, zero_copy);
|
|
||||||
|
|
||||||
if let Some(response) = maybe_response {
|
if let Some(response) = maybe_response {
|
||||||
// Synchronous response.
|
// Synchronous response.
|
||||||
|
@ -476,7 +471,7 @@ fn send(
|
||||||
|
|
||||||
if !buf.is_empty() {
|
if !buf.is_empty() {
|
||||||
let ui8 = boxed_slice_to_uint8array(scope, buf);
|
let ui8 = boxed_slice_to_uint8array(scope, buf);
|
||||||
rv.set(ui8.into())
|
rv.set(ui8.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -486,10 +481,10 @@ fn set_macrotask_callback(
|
||||||
args: v8::FunctionCallbackArguments,
|
args: v8::FunctionCallbackArguments,
|
||||||
_rv: v8::ReturnValue,
|
_rv: v8::ReturnValue,
|
||||||
) {
|
) {
|
||||||
let core_isolate: &mut CoreIsolate =
|
let state_rc = CoreIsolate::state(scope.isolate());
|
||||||
unsafe { &mut *(scope.isolate().get_data(0) as *mut CoreIsolate) };
|
let mut state = state_rc.borrow_mut();
|
||||||
|
|
||||||
if !core_isolate.js_macrotask_cb.is_empty() {
|
if !state.js_macrotask_cb.is_empty() {
|
||||||
let msg =
|
let msg =
|
||||||
v8::String::new(scope, "Deno.core.setMacrotaskCallback already called.")
|
v8::String::new(scope, "Deno.core.setMacrotaskCallback already called.")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -499,7 +494,7 @@ fn set_macrotask_callback(
|
||||||
|
|
||||||
let macrotask_cb_fn =
|
let macrotask_cb_fn =
|
||||||
v8::Local::<v8::Function>::try_from(args.get(0)).unwrap();
|
v8::Local::<v8::Function>::try_from(args.get(0)).unwrap();
|
||||||
core_isolate.js_macrotask_cb.set(scope, macrotask_cb_fn);
|
state.js_macrotask_cb.set(scope, macrotask_cb_fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_context(
|
fn eval_context(
|
||||||
|
@ -507,10 +502,10 @@ fn eval_context(
|
||||||
args: v8::FunctionCallbackArguments,
|
args: v8::FunctionCallbackArguments,
|
||||||
mut rv: v8::ReturnValue,
|
mut rv: v8::ReturnValue,
|
||||||
) {
|
) {
|
||||||
let core_isolate: &mut CoreIsolate =
|
let state_rc = CoreIsolate::state(scope.isolate());
|
||||||
unsafe { &mut *(scope.isolate().get_data(0) as *mut CoreIsolate) };
|
let state = state_rc.borrow();
|
||||||
assert!(!core_isolate.global_context.is_empty());
|
assert!(!state.global_context.is_empty());
|
||||||
let context = core_isolate.global_context.get(scope).unwrap();
|
let context = state.global_context.get(scope).unwrap();
|
||||||
|
|
||||||
let source = match v8::Local::<v8::String>::try_from(args.get(0)) {
|
let source = match v8::Local::<v8::String>::try_from(args.get(0)) {
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
|
@ -643,10 +638,10 @@ fn format_error(
|
||||||
args: v8::FunctionCallbackArguments,
|
args: v8::FunctionCallbackArguments,
|
||||||
mut rv: v8::ReturnValue,
|
mut rv: v8::ReturnValue,
|
||||||
) {
|
) {
|
||||||
let core_isolate: &mut CoreIsolate =
|
|
||||||
unsafe { &mut *(scope.isolate().get_data(0) as *mut CoreIsolate) };
|
|
||||||
let e = JSError::from_v8_exception(scope, args.get(0));
|
let e = JSError::from_v8_exception(scope, args.get(0));
|
||||||
let e = (core_isolate.js_error_create_fn)(e);
|
let state_rc = CoreIsolate::state(scope.isolate());
|
||||||
|
let state = state_rc.borrow();
|
||||||
|
let e = (state.js_error_create_fn)(e);
|
||||||
let e = e.to_string();
|
let e = e.to_string();
|
||||||
let e = v8::String::new(scope, &e).unwrap();
|
let e = v8::String::new(scope, &e).unwrap();
|
||||||
rv.set(e.into())
|
rv.set(e.into())
|
||||||
|
@ -734,19 +729,19 @@ fn shared_getter(
|
||||||
_args: v8::PropertyCallbackArguments,
|
_args: v8::PropertyCallbackArguments,
|
||||||
mut rv: v8::ReturnValue,
|
mut rv: v8::ReturnValue,
|
||||||
) {
|
) {
|
||||||
let core_isolate: &mut CoreIsolate =
|
let state_rc = CoreIsolate::state(scope.isolate());
|
||||||
unsafe { &mut *(scope.isolate().get_data(0) as *mut CoreIsolate) };
|
let mut state = state_rc.borrow_mut();
|
||||||
|
|
||||||
// Lazily initialize the persistent external ArrayBuffer.
|
// Lazily initialize the persistent external ArrayBuffer.
|
||||||
if core_isolate.shared_ab.is_empty() {
|
if state.shared_ab.is_empty() {
|
||||||
let ab = v8::SharedArrayBuffer::with_backing_store(
|
let ab = v8::SharedArrayBuffer::with_backing_store(
|
||||||
scope,
|
scope,
|
||||||
core_isolate.shared.get_backing_store(),
|
state.shared.get_backing_store(),
|
||||||
);
|
);
|
||||||
core_isolate.shared_ab.set(scope, ab);
|
state.shared_ab.set(scope, ab);
|
||||||
}
|
}
|
||||||
|
|
||||||
let shared_ab = core_isolate.shared_ab.get(scope).unwrap();
|
let shared_ab = state.shared_ab.get(scope).unwrap();
|
||||||
rv.set(shared_ab.into());
|
rv.set(shared_ab.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -759,11 +754,11 @@ pub fn module_resolve_callback<'s>(
|
||||||
let mut scope = v8::EscapableHandleScope::new(scope.enter());
|
let mut scope = v8::EscapableHandleScope::new(scope.enter());
|
||||||
let scope = scope.enter();
|
let scope = scope.enter();
|
||||||
|
|
||||||
let core_isolate: &mut EsIsolate =
|
let state_rc = EsIsolate::state(scope.isolate());
|
||||||
unsafe { &mut *(scope.isolate().get_data(1) as *mut EsIsolate) };
|
let mut state = state_rc.borrow_mut();
|
||||||
|
|
||||||
let referrer_id = referrer.get_identity_hash();
|
let referrer_id = referrer.get_identity_hash();
|
||||||
let referrer_name = core_isolate
|
let referrer_name = state
|
||||||
.modules
|
.modules
|
||||||
.get_info(referrer_id)
|
.get_info(referrer_id)
|
||||||
.expect("ModuleInfo not found")
|
.expect("ModuleInfo not found")
|
||||||
|
@ -778,8 +773,8 @@ pub fn module_resolve_callback<'s>(
|
||||||
let req_str = req.to_rust_string_lossy(scope);
|
let req_str = req.to_rust_string_lossy(scope);
|
||||||
|
|
||||||
if req_str == specifier_str {
|
if req_str == specifier_str {
|
||||||
let id = core_isolate.module_resolve_cb(&req_str, referrer_id);
|
let id = state.module_resolve_cb(&req_str, referrer_id);
|
||||||
let maybe_info = core_isolate.modules.get_info(id);
|
let maybe_info = state.modules.get_info(id);
|
||||||
|
|
||||||
if maybe_info.is_none() {
|
if maybe_info.is_none() {
|
||||||
let msg = format!(
|
let msg = format!(
|
||||||
|
@ -810,10 +805,10 @@ fn get_promise_details(
|
||||||
args: v8::FunctionCallbackArguments,
|
args: v8::FunctionCallbackArguments,
|
||||||
mut rv: v8::ReturnValue,
|
mut rv: v8::ReturnValue,
|
||||||
) {
|
) {
|
||||||
let core_isolate: &mut CoreIsolate =
|
let state_rc = CoreIsolate::state(scope.isolate());
|
||||||
unsafe { &mut *(scope.isolate().get_data(0) as *mut CoreIsolate) };
|
let state = state_rc.borrow();
|
||||||
assert!(!core_isolate.global_context.is_empty());
|
assert!(!state.global_context.is_empty());
|
||||||
let context = core_isolate.global_context.get(scope).unwrap();
|
let context = state.global_context.get(scope).unwrap();
|
||||||
|
|
||||||
let promise = match v8::Local::<v8::Promise>::try_from(args.get(0)) {
|
let promise = match v8::Local::<v8::Promise>::try_from(args.get(0)) {
|
||||||
Ok(val) => val,
|
Ok(val) => val,
|
||||||
|
|
|
@ -16,20 +16,20 @@ use crate::JSError;
|
||||||
use crate::ResourceTable;
|
use crate::ResourceTable;
|
||||||
use crate::ZeroCopyBuf;
|
use crate::ZeroCopyBuf;
|
||||||
use futures::future::FutureExt;
|
use futures::future::FutureExt;
|
||||||
use futures::stream::select;
|
|
||||||
use futures::stream::FuturesUnordered;
|
use futures::stream::FuturesUnordered;
|
||||||
use futures::stream::StreamExt;
|
use futures::stream::StreamExt;
|
||||||
use futures::task::AtomicWaker;
|
use futures::task::AtomicWaker;
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
use libc::c_void;
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::convert::From;
|
use std::convert::From;
|
||||||
use std::mem::forget;
|
use std::mem::forget;
|
||||||
|
use std::ops::Deref;
|
||||||
|
use std::ops::DerefMut;
|
||||||
use std::option::Option;
|
use std::option::Option;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::{Arc, Mutex, Once};
|
use std::sync::Once;
|
||||||
use std::task::Context;
|
use std::task::Context;
|
||||||
use std::task::Poll;
|
use std::task::Poll;
|
||||||
|
|
||||||
|
@ -72,7 +72,6 @@ pub enum StartupData<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
type JSErrorCreateFn = dyn Fn(JSError) -> ErrBox;
|
type JSErrorCreateFn = dyn Fn(JSError) -> ErrBox;
|
||||||
type IsolateErrorHandleFn = dyn FnMut(ErrBox) -> Result<(), ErrBox>;
|
|
||||||
|
|
||||||
/// A single execution context of JavaScript. Corresponds roughly to the "Web
|
/// 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
|
/// Worker" concept in the DOM. An CoreIsolate is a Future that can be used with
|
||||||
|
@ -82,28 +81,53 @@ type IsolateErrorHandleFn = dyn FnMut(ErrBox) -> Result<(), ErrBox>;
|
||||||
/// Ops are created in JavaScript by calling Deno.core.dispatch(), and in Rust
|
/// 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
|
/// 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.
|
/// as arguments. An async Op corresponds exactly to a Promise in JavaScript.
|
||||||
#[allow(unused)]
|
|
||||||
pub struct CoreIsolate {
|
pub struct CoreIsolate {
|
||||||
pub v8_isolate: Option<v8::OwnedIsolate>,
|
// This is an Option<OwnedIsolate> instead of just OwnedIsolate to workaround
|
||||||
|
// an safety issue with SnapshotCreator. See CoreIsolate::drop.
|
||||||
|
v8_isolate: Option<v8::OwnedIsolate>,
|
||||||
snapshot_creator: Option<v8::SnapshotCreator>,
|
snapshot_creator: Option<v8::SnapshotCreator>,
|
||||||
has_snapshotted: bool,
|
has_snapshotted: bool,
|
||||||
|
needs_init: bool,
|
||||||
|
startup_script: Option<OwnedScript>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Internal state for CoreIsolate which is stored in one of v8::Isolate's
|
||||||
|
/// embedder slots.
|
||||||
|
pub struct CoreIsolateState {
|
||||||
pub resource_table: Rc<RefCell<ResourceTable>>,
|
pub resource_table: Rc<RefCell<ResourceTable>>,
|
||||||
pub global_context: v8::Global<v8::Context>,
|
pub global_context: v8::Global<v8::Context>,
|
||||||
pub(crate) shared_ab: v8::Global<v8::SharedArrayBuffer>,
|
pub(crate) shared_ab: v8::Global<v8::SharedArrayBuffer>,
|
||||||
pub(crate) js_recv_cb: v8::Global<v8::Function>,
|
pub(crate) js_recv_cb: v8::Global<v8::Function>,
|
||||||
pub(crate) js_macrotask_cb: v8::Global<v8::Function>,
|
pub(crate) js_macrotask_cb: v8::Global<v8::Function>,
|
||||||
pub(crate) pending_promise_exceptions: HashMap<i32, v8::Global<v8::Value>>,
|
pub(crate) pending_promise_exceptions: HashMap<i32, v8::Global<v8::Value>>,
|
||||||
shared_isolate_handle: Arc<Mutex<Option<*mut v8::Isolate>>>,
|
|
||||||
pub(crate) js_error_create_fn: Box<JSErrorCreateFn>,
|
pub(crate) js_error_create_fn: Box<JSErrorCreateFn>,
|
||||||
needs_init: bool,
|
|
||||||
pub(crate) shared: SharedQueue,
|
pub(crate) shared: SharedQueue,
|
||||||
pending_ops: FuturesUnordered<PendingOpFuture>,
|
pending_ops: FuturesUnordered<PendingOpFuture>,
|
||||||
pending_unref_ops: FuturesUnordered<PendingOpFuture>,
|
pending_unref_ops: FuturesUnordered<PendingOpFuture>,
|
||||||
have_unpolled_ops: bool,
|
have_unpolled_ops: bool,
|
||||||
startup_script: Option<OwnedScript>,
|
|
||||||
pub op_registry: OpRegistry,
|
pub op_registry: OpRegistry,
|
||||||
waker: AtomicWaker,
|
waker: AtomicWaker,
|
||||||
error_handler: Option<Box<IsolateErrorHandleFn>>,
|
}
|
||||||
|
|
||||||
|
// TODO(ry) The trait v8::InIsolate is superfluous. HandleScope::new should just
|
||||||
|
// take &mut v8::Isolate.
|
||||||
|
impl v8::InIsolate for CoreIsolate {
|
||||||
|
fn isolate(&mut self) -> &mut v8::Isolate {
|
||||||
|
self.v8_isolate.as_mut().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for CoreIsolate {
|
||||||
|
type Target = v8::Isolate;
|
||||||
|
fn deref(&self) -> &v8::Isolate {
|
||||||
|
self.v8_isolate.as_ref().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DerefMut for CoreIsolate {
|
||||||
|
fn deref_mut(&mut self) -> &mut v8::Isolate {
|
||||||
|
self.v8_isolate.as_mut().unwrap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for CoreIsolate {
|
impl Drop for CoreIsolate {
|
||||||
|
@ -128,8 +152,6 @@ impl Drop for CoreIsolate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static DENO_INIT: Once = Once::new();
|
|
||||||
|
|
||||||
#[allow(clippy::missing_safety_doc)]
|
#[allow(clippy::missing_safety_doc)]
|
||||||
pub unsafe fn v8_init() {
|
pub unsafe fn v8_init() {
|
||||||
let platform = v8::new_default_platform().unwrap();
|
let platform = v8::new_default_platform().unwrap();
|
||||||
|
@ -150,7 +172,8 @@ pub unsafe fn v8_init() {
|
||||||
impl CoreIsolate {
|
impl CoreIsolate {
|
||||||
/// startup_data defines the snapshot or script used at startup to initialize
|
/// startup_data defines the snapshot or script used at startup to initialize
|
||||||
/// the isolate.
|
/// the isolate.
|
||||||
pub fn new(startup_data: StartupData, will_snapshot: bool) -> Box<Self> {
|
pub fn new(startup_data: StartupData, will_snapshot: bool) -> Self {
|
||||||
|
static DENO_INIT: Once = Once::new();
|
||||||
DENO_INIT.call_once(|| {
|
DENO_INIT.call_once(|| {
|
||||||
unsafe { v8_init() };
|
unsafe { v8_init() };
|
||||||
});
|
});
|
||||||
|
@ -210,44 +233,29 @@ impl CoreIsolate {
|
||||||
(isolate, None)
|
(isolate, None)
|
||||||
};
|
};
|
||||||
|
|
||||||
let shared = SharedQueue::new(RECOMMENDED_SIZE);
|
isolate.set_slot(Rc::new(RefCell::new(CoreIsolateState {
|
||||||
let needs_init = true;
|
|
||||||
|
|
||||||
let core_isolate = Self {
|
|
||||||
v8_isolate: None,
|
|
||||||
global_context,
|
global_context,
|
||||||
resource_table: Rc::new(RefCell::new(ResourceTable::default())),
|
resource_table: Rc::new(RefCell::new(ResourceTable::default())),
|
||||||
pending_promise_exceptions: HashMap::new(),
|
pending_promise_exceptions: HashMap::new(),
|
||||||
shared_ab: v8::Global::<v8::SharedArrayBuffer>::new(),
|
shared_ab: v8::Global::<v8::SharedArrayBuffer>::new(),
|
||||||
js_recv_cb: v8::Global::<v8::Function>::new(),
|
js_recv_cb: v8::Global::<v8::Function>::new(),
|
||||||
js_macrotask_cb: v8::Global::<v8::Function>::new(),
|
js_macrotask_cb: v8::Global::<v8::Function>::new(),
|
||||||
snapshot_creator: maybe_snapshot_creator,
|
|
||||||
has_snapshotted: false,
|
|
||||||
shared_isolate_handle: Arc::new(Mutex::new(None)),
|
|
||||||
js_error_create_fn: Box::new(JSError::create),
|
js_error_create_fn: Box::new(JSError::create),
|
||||||
shared,
|
shared: SharedQueue::new(RECOMMENDED_SIZE),
|
||||||
needs_init,
|
|
||||||
pending_ops: FuturesUnordered::new(),
|
pending_ops: FuturesUnordered::new(),
|
||||||
pending_unref_ops: FuturesUnordered::new(),
|
pending_unref_ops: FuturesUnordered::new(),
|
||||||
have_unpolled_ops: false,
|
have_unpolled_ops: false,
|
||||||
startup_script,
|
|
||||||
op_registry: OpRegistry::new(),
|
op_registry: OpRegistry::new(),
|
||||||
waker: AtomicWaker::new(),
|
waker: AtomicWaker::new(),
|
||||||
error_handler: None,
|
})));
|
||||||
};
|
|
||||||
|
|
||||||
let mut boxed_isolate = Box::new(core_isolate);
|
Self {
|
||||||
{
|
v8_isolate: Some(isolate),
|
||||||
let core_isolate_ptr: *mut Self = Box::into_raw(boxed_isolate);
|
snapshot_creator: maybe_snapshot_creator,
|
||||||
unsafe { isolate.set_data(0, core_isolate_ptr as *mut c_void) };
|
has_snapshotted: false,
|
||||||
boxed_isolate = unsafe { Box::from_raw(core_isolate_ptr) };
|
needs_init: true,
|
||||||
let shared_handle_ptr = &mut *isolate;
|
startup_script,
|
||||||
*boxed_isolate.shared_isolate_handle.lock().unwrap() =
|
|
||||||
Some(shared_handle_ptr);
|
|
||||||
boxed_isolate.v8_isolate = Some(isolate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boxed_isolate
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_isolate(mut isolate: v8::OwnedIsolate) -> v8::OwnedIsolate {
|
fn setup_isolate(mut isolate: v8::OwnedIsolate) -> v8::OwnedIsolate {
|
||||||
|
@ -256,6 +264,101 @@ impl CoreIsolate {
|
||||||
isolate
|
isolate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn state(isolate: &v8::Isolate) -> Rc<RefCell<CoreIsolateState>> {
|
||||||
|
let s = isolate.get_slot::<Rc<RefCell<CoreIsolateState>>>().unwrap();
|
||||||
|
s.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Executes a bit of built-in JavaScript to provide Deno.sharedQueue.
|
||||||
|
fn shared_init(&mut self) {
|
||||||
|
if self.needs_init {
|
||||||
|
self.needs_init = false;
|
||||||
|
js_check(self.execute("core.js", include_str!("core.js")));
|
||||||
|
// Maybe execute the startup script.
|
||||||
|
if let Some(s) = self.startup_script.take() {
|
||||||
|
self.execute(&s.filename, &s.source).unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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.
|
||||||
|
pub fn execute(
|
||||||
|
&mut self,
|
||||||
|
js_filename: &str,
|
||||||
|
js_source: &str,
|
||||||
|
) -> Result<(), ErrBox> {
|
||||||
|
self.shared_init();
|
||||||
|
|
||||||
|
let state_rc = Self::state(self);
|
||||||
|
let state = state_rc.borrow();
|
||||||
|
|
||||||
|
let mut hs = v8::HandleScope::new(self.v8_isolate.as_mut().unwrap());
|
||||||
|
let scope = hs.enter();
|
||||||
|
let context = state.global_context.get(scope).unwrap();
|
||||||
|
let mut cs = v8::ContextScope::new(scope, context);
|
||||||
|
let scope = cs.enter();
|
||||||
|
|
||||||
|
drop(state);
|
||||||
|
|
||||||
|
let source = v8::String::new(scope, js_source).unwrap();
|
||||||
|
let name = v8::String::new(scope, js_filename).unwrap();
|
||||||
|
let origin = bindings::script_origin(scope, name);
|
||||||
|
|
||||||
|
let mut try_catch = v8::TryCatch::new(scope);
|
||||||
|
let tc = try_catch.enter();
|
||||||
|
|
||||||
|
let mut script =
|
||||||
|
match v8::Script::compile(scope, context, source, Some(&origin)) {
|
||||||
|
Some(script) => script,
|
||||||
|
None => {
|
||||||
|
let exception = tc.exception().unwrap();
|
||||||
|
return exception_to_err_result(scope, exception);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match script.run(scope, context) {
|
||||||
|
Some(_) => Ok(()),
|
||||||
|
None => {
|
||||||
|
assert!(tc.has_caught());
|
||||||
|
let exception = tc.exception().unwrap();
|
||||||
|
exception_to_err_result(scope, exception)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Takes a snapshot. The isolate should have been created with will_snapshot
|
||||||
|
/// 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.
|
||||||
|
pub fn snapshot(&mut self) -> v8::StartupData {
|
||||||
|
assert!(self.snapshot_creator.is_some());
|
||||||
|
let state = Self::state(self);
|
||||||
|
|
||||||
|
// Note: create_blob() method must not be called from within a HandleScope.
|
||||||
|
// The HandleScope created here is exited at the end of the block.
|
||||||
|
// TODO(piscisaureus): The rusty_v8 type system should enforce this.
|
||||||
|
{
|
||||||
|
let v8_isolate = self.v8_isolate.as_mut().unwrap();
|
||||||
|
let mut hs = v8::HandleScope::new(v8_isolate);
|
||||||
|
let scope = hs.enter();
|
||||||
|
state.borrow_mut().global_context.reset(scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
let snapshot_creator = self.snapshot_creator.as_mut().unwrap();
|
||||||
|
let snapshot = snapshot_creator
|
||||||
|
.create_blob(v8::FunctionCodeHandling::Keep)
|
||||||
|
.unwrap();
|
||||||
|
self.has_snapshotted = true;
|
||||||
|
|
||||||
|
snapshot
|
||||||
|
}
|
||||||
|
|
||||||
/// Defines the how Deno.core.dispatch() acts.
|
/// Defines the how Deno.core.dispatch() acts.
|
||||||
/// Called whenever Deno.core.dispatch() is called in JavaScript. zero_copy_buf
|
/// Called whenever Deno.core.dispatch() is called in JavaScript. zero_copy_buf
|
||||||
/// corresponds to the second argument of Deno.core.dispatch().
|
/// corresponds to the second argument of Deno.core.dispatch().
|
||||||
|
@ -263,7 +366,125 @@ impl CoreIsolate {
|
||||||
/// Requires runtime to explicitly ask for op ids before using any of the ops.
|
/// Requires runtime to explicitly ask for op ids before using any of the ops.
|
||||||
pub fn register_op<F>(&mut self, name: &str, op: F) -> OpId
|
pub fn register_op<F>(&mut self, name: &str, op: F) -> OpId
|
||||||
where
|
where
|
||||||
F: Fn(&mut CoreIsolate, &[u8], Option<ZeroCopyBuf>) -> Op + 'static,
|
F: Fn(&mut CoreIsolateState, &[u8], Option<ZeroCopyBuf>) -> Op + 'static,
|
||||||
|
{
|
||||||
|
let state_rc = Self::state(self);
|
||||||
|
let mut state = state_rc.borrow_mut();
|
||||||
|
state.op_registry.register(name, op)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Future for CoreIsolate {
|
||||||
|
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 state_rc = Self::state(core_isolate);
|
||||||
|
{
|
||||||
|
let state = state_rc.borrow();
|
||||||
|
state.waker.register(cx.waker());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut hs = v8::HandleScope::new(core_isolate);
|
||||||
|
let scope = hs.enter();
|
||||||
|
let context = {
|
||||||
|
let state = state_rc.borrow();
|
||||||
|
state.global_context.get(scope).unwrap()
|
||||||
|
};
|
||||||
|
let mut cs = v8::ContextScope::new(scope, context);
|
||||||
|
let scope = cs.enter();
|
||||||
|
|
||||||
|
check_promise_exceptions(scope)?;
|
||||||
|
|
||||||
|
let mut overflow_response: Option<(OpId, Buf)> = None;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let mut state = state_rc.borrow_mut();
|
||||||
|
// Now handle actual ops.
|
||||||
|
state.have_unpolled_ops = false;
|
||||||
|
|
||||||
|
let pending_r = state.pending_ops.poll_next_unpin(cx);
|
||||||
|
match pending_r {
|
||||||
|
Poll::Ready(None) => break,
|
||||||
|
Poll::Pending => break,
|
||||||
|
Poll::Ready(Some((op_id, buf))) => {
|
||||||
|
let successful_push = state.shared.push(op_id, &buf);
|
||||||
|
if !successful_push {
|
||||||
|
// If we couldn't push the response to the shared queue, because
|
||||||
|
// there wasn't enough size, we will return the buffer via the
|
||||||
|
// legacy route, using the argument of deno_respond.
|
||||||
|
overflow_response = Some((op_id, buf));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let mut state = state_rc.borrow_mut();
|
||||||
|
let unref_r = state.pending_unref_ops.poll_next_unpin(cx);
|
||||||
|
#[allow(clippy::match_wild_err_arm)]
|
||||||
|
match unref_r {
|
||||||
|
Poll::Ready(None) => break,
|
||||||
|
Poll::Pending => break,
|
||||||
|
Poll::Ready(Some((op_id, buf))) => {
|
||||||
|
let successful_push = state.shared.push(op_id, &buf);
|
||||||
|
if !successful_push {
|
||||||
|
// If we couldn't push the response to the shared queue, because
|
||||||
|
// there wasn't enough size, we will return the buffer via the
|
||||||
|
// legacy route, using the argument of deno_respond.
|
||||||
|
overflow_response = Some((op_id, buf));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let state = state_rc.borrow();
|
||||||
|
if state.shared.size() > 0 {
|
||||||
|
drop(state);
|
||||||
|
async_op_response(scope, None)?;
|
||||||
|
// The other side should have shifted off all the messages.
|
||||||
|
let state = state_rc.borrow();
|
||||||
|
assert_eq!(state.shared.size(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
if let Some((op_id, buf)) = overflow_response.take() {
|
||||||
|
async_op_response(scope, Some((op_id, buf)))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
drain_macrotasks(scope)?;
|
||||||
|
|
||||||
|
check_promise_exceptions(scope)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let state = state_rc.borrow();
|
||||||
|
// We're idle if pending_ops is empty.
|
||||||
|
if state.pending_ops.is_empty() {
|
||||||
|
Poll::Ready(Ok(()))
|
||||||
|
} else {
|
||||||
|
if state.have_unpolled_ops {
|
||||||
|
state.waker.wake();
|
||||||
|
}
|
||||||
|
Poll::Pending
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CoreIsolateState {
|
||||||
|
/// Defines the how Deno.core.dispatch() acts.
|
||||||
|
/// Called whenever Deno.core.dispatch() is called in JavaScript. zero_copy_buf
|
||||||
|
/// corresponds to the second argument of Deno.core.dispatch().
|
||||||
|
///
|
||||||
|
/// Requires runtime to explicitly ask for op ids before using any of the ops.
|
||||||
|
pub fn register_op<F>(&mut self, name: &str, op: F) -> OpId
|
||||||
|
where
|
||||||
|
F: Fn(&mut CoreIsolateState, &[u8], Option<ZeroCopyBuf>) -> Op + 'static,
|
||||||
{
|
{
|
||||||
self.op_registry.register(name, op)
|
self.op_registry.register(name, op)
|
||||||
}
|
}
|
||||||
|
@ -278,18 +499,6 @@ impl CoreIsolate {
|
||||||
self.js_error_create_fn = Box::new(f);
|
self.js_error_create_fn = Box::new(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Executes a bit of built-in JavaScript to provide Deno.sharedQueue.
|
|
||||||
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")));
|
|
||||||
// Maybe execute the startup script.
|
|
||||||
if let Some(s) = self.startup_script.take() {
|
|
||||||
self.execute(&s.filename, &s.source).unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn dispatch_op<'s>(
|
pub fn dispatch_op<'s>(
|
||||||
&mut self,
|
&mut self,
|
||||||
scope: &mut impl v8::ToLocal<'s>,
|
scope: &mut impl v8::ToLocal<'s>,
|
||||||
|
@ -329,180 +538,23 @@ 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.
|
|
||||||
pub fn execute(
|
|
||||||
&mut self,
|
|
||||||
js_filename: &str,
|
|
||||||
js_source: &str,
|
|
||||||
) -> Result<(), ErrBox> {
|
|
||||||
self.shared_init();
|
|
||||||
|
|
||||||
let js_error_create_fn = &*self.js_error_create_fn;
|
|
||||||
let v8_isolate = self.v8_isolate.as_mut().unwrap();
|
|
||||||
|
|
||||||
let mut hs = v8::HandleScope::new(v8_isolate);
|
|
||||||
let scope = hs.enter();
|
|
||||||
assert!(!self.global_context.is_empty());
|
|
||||||
let context = self.global_context.get(scope).unwrap();
|
|
||||||
let mut cs = v8::ContextScope::new(scope, context);
|
|
||||||
let scope = cs.enter();
|
|
||||||
|
|
||||||
let source = v8::String::new(scope, js_source).unwrap();
|
|
||||||
let name = v8::String::new(scope, js_filename).unwrap();
|
|
||||||
let origin = bindings::script_origin(scope, name);
|
|
||||||
|
|
||||||
let mut try_catch = v8::TryCatch::new(scope);
|
|
||||||
let tc = try_catch.enter();
|
|
||||||
|
|
||||||
let mut script =
|
|
||||||
match v8::Script::compile(scope, context, source, Some(&origin)) {
|
|
||||||
Some(script) => script,
|
|
||||||
None => {
|
|
||||||
let exception = tc.exception().unwrap();
|
|
||||||
return exception_to_err_result(scope, exception, js_error_create_fn);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
match script.run(scope, context) {
|
|
||||||
Some(_) => Ok(()),
|
|
||||||
None => {
|
|
||||||
assert!(tc.has_caught());
|
|
||||||
let exception = tc.exception().unwrap();
|
|
||||||
exception_to_err_result(scope, exception, js_error_create_fn)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Takes a snapshot. The isolate should have been created with will_snapshot
|
|
||||||
/// 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.
|
|
||||||
pub fn snapshot(&mut self) -> v8::StartupData {
|
|
||||||
assert!(self.snapshot_creator.is_some());
|
|
||||||
|
|
||||||
// Note: create_blob() method must not be called from within a HandleScope.
|
|
||||||
// The HandleScope created here is exited at the end of the block.
|
|
||||||
// TODO(piscisaureus): The rusty_v8 type system should enforce this.
|
|
||||||
{
|
|
||||||
let v8_isolate = self.v8_isolate.as_mut().unwrap();
|
|
||||||
let mut hs = v8::HandleScope::new(v8_isolate);
|
|
||||||
let scope = hs.enter();
|
|
||||||
self.global_context.reset(scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
let snapshot_creator = self.snapshot_creator.as_mut().unwrap();
|
|
||||||
let snapshot = snapshot_creator
|
|
||||||
.create_blob(v8::FunctionCodeHandling::Keep)
|
|
||||||
.unwrap();
|
|
||||||
self.has_snapshotted = true;
|
|
||||||
|
|
||||||
snapshot
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Future for CoreIsolate {
|
|
||||||
type Output = Result<(), ErrBox>;
|
|
||||||
|
|
||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
|
||||||
let inner = self.get_mut();
|
|
||||||
inner.waker.register(cx.waker());
|
|
||||||
inner.shared_init();
|
|
||||||
|
|
||||||
let v8_isolate = inner.v8_isolate.as_mut().unwrap();
|
|
||||||
let js_error_create_fn = &*inner.js_error_create_fn;
|
|
||||||
let js_recv_cb = &inner.js_recv_cb;
|
|
||||||
let js_macrotask_cb = &inner.js_macrotask_cb;
|
|
||||||
let pending_promise_exceptions = &mut inner.pending_promise_exceptions;
|
|
||||||
|
|
||||||
let mut hs = v8::HandleScope::new(v8_isolate);
|
|
||||||
let scope = hs.enter();
|
|
||||||
let context = inner.global_context.get(scope).unwrap();
|
|
||||||
let mut cs = v8::ContextScope::new(scope, context);
|
|
||||||
let scope = cs.enter();
|
|
||||||
|
|
||||||
check_promise_exceptions(
|
|
||||||
scope,
|
|
||||||
pending_promise_exceptions,
|
|
||||||
js_error_create_fn,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let mut overflow_response: Option<(OpId, Buf)> = None;
|
|
||||||
|
|
||||||
loop {
|
|
||||||
// Now handle actual ops.
|
|
||||||
inner.have_unpolled_ops = false;
|
|
||||||
#[allow(clippy::match_wild_err_arm)]
|
|
||||||
match select(&mut inner.pending_ops, &mut inner.pending_unref_ops)
|
|
||||||
.poll_next_unpin(cx)
|
|
||||||
{
|
|
||||||
Poll::Ready(None) => break,
|
|
||||||
Poll::Pending => break,
|
|
||||||
Poll::Ready(Some((op_id, buf))) => {
|
|
||||||
let successful_push = inner.shared.push(op_id, &buf);
|
|
||||||
if !successful_push {
|
|
||||||
// If we couldn't push the response to the shared queue, because
|
|
||||||
// there wasn't enough size, we will return the buffer via the
|
|
||||||
// legacy route, using the argument of deno_respond.
|
|
||||||
overflow_response = Some((op_id, buf));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if inner.shared.size() > 0 {
|
|
||||||
async_op_response(scope, None, js_recv_cb, js_error_create_fn)?;
|
|
||||||
// The other side should have shifted off all the messages.
|
|
||||||
assert_eq!(inner.shared.size(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some((op_id, buf)) = overflow_response.take() {
|
|
||||||
async_op_response(
|
|
||||||
scope,
|
|
||||||
Some((op_id, buf)),
|
|
||||||
js_recv_cb,
|
|
||||||
js_error_create_fn,
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
drain_macrotasks(scope, js_macrotask_cb, js_error_create_fn)?;
|
|
||||||
|
|
||||||
check_promise_exceptions(
|
|
||||||
scope,
|
|
||||||
pending_promise_exceptions,
|
|
||||||
js_error_create_fn,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
// We're idle if pending_ops is empty.
|
|
||||||
if inner.pending_ops.is_empty() {
|
|
||||||
Poll::Ready(Ok(()))
|
|
||||||
} else {
|
|
||||||
if inner.have_unpolled_ops {
|
|
||||||
inner.waker.wake();
|
|
||||||
}
|
|
||||||
Poll::Pending
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn async_op_response<'s>(
|
fn async_op_response<'s>(
|
||||||
scope: &mut impl v8::ToLocal<'s>,
|
scope: &mut impl v8::ToLocal<'s>,
|
||||||
maybe_buf: Option<(OpId, Box<[u8]>)>,
|
maybe_buf: Option<(OpId, Box<[u8]>)>,
|
||||||
js_recv_cb: &v8::Global<v8::Function>,
|
|
||||||
js_error_create_fn: &JSErrorCreateFn,
|
|
||||||
) -> Result<(), ErrBox> {
|
) -> Result<(), ErrBox> {
|
||||||
let context = scope.get_current_context().unwrap();
|
let context = scope.get_current_context().unwrap();
|
||||||
let global: v8::Local<v8::Value> = context.global(scope).into();
|
let global: v8::Local<v8::Value> = context.global(scope).into();
|
||||||
let js_recv_cb = js_recv_cb
|
|
||||||
|
let state_rc = CoreIsolate::state(scope.isolate());
|
||||||
|
let state = state_rc.borrow_mut();
|
||||||
|
|
||||||
|
let js_recv_cb = state
|
||||||
|
.js_recv_cb
|
||||||
.get(scope)
|
.get(scope)
|
||||||
.expect("Deno.core.recv has not been called.");
|
.expect("Deno.core.recv has not been called.");
|
||||||
|
drop(state);
|
||||||
|
|
||||||
// TODO(piscisaureus): properly integrate TryCatch in the scope chain.
|
// TODO(piscisaureus): properly integrate TryCatch in the scope chain.
|
||||||
let mut try_catch = v8::TryCatch::new(scope);
|
let mut try_catch = v8::TryCatch::new(scope);
|
||||||
|
@ -521,20 +573,21 @@ fn async_op_response<'s>(
|
||||||
|
|
||||||
match tc.exception() {
|
match tc.exception() {
|
||||||
None => Ok(()),
|
None => Ok(()),
|
||||||
Some(exception) => {
|
Some(exception) => exception_to_err_result(scope, exception),
|
||||||
exception_to_err_result(scope, exception, js_error_create_fn)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn drain_macrotasks<'s>(
|
fn drain_macrotasks<'s>(
|
||||||
scope: &mut impl v8::ToLocal<'s>,
|
scope: &mut impl v8::ToLocal<'s>,
|
||||||
js_macrotask_cb: &v8::Global<v8::Function>,
|
|
||||||
js_error_create_fn: &JSErrorCreateFn,
|
|
||||||
) -> Result<(), ErrBox> {
|
) -> Result<(), ErrBox> {
|
||||||
let context = scope.get_current_context().unwrap();
|
let context = scope.get_current_context().unwrap();
|
||||||
let global: v8::Local<v8::Value> = context.global(scope).into();
|
let global: v8::Local<v8::Value> = context.global(scope).into();
|
||||||
let js_macrotask_cb = js_macrotask_cb.get(scope);
|
|
||||||
|
let js_macrotask_cb = {
|
||||||
|
let state_rc = CoreIsolate::state(scope.isolate());
|
||||||
|
let state = state_rc.borrow_mut();
|
||||||
|
state.js_macrotask_cb.get(scope)
|
||||||
|
};
|
||||||
if js_macrotask_cb.is_none() {
|
if js_macrotask_cb.is_none() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -550,7 +603,7 @@ fn drain_macrotasks<'s>(
|
||||||
let is_done = js_macrotask_cb.call(scope, context, global, &[]);
|
let is_done = js_macrotask_cb.call(scope, context, global, &[]);
|
||||||
|
|
||||||
if let Some(exception) = tc.exception() {
|
if let Some(exception) = tc.exception() {
|
||||||
return exception_to_err_result(scope, exception, js_error_create_fn);
|
return exception_to_err_result(scope, exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
let is_done = is_done.unwrap();
|
let is_done = is_done.unwrap();
|
||||||
|
@ -565,7 +618,6 @@ fn drain_macrotasks<'s>(
|
||||||
pub(crate) fn exception_to_err_result<'s, T>(
|
pub(crate) fn exception_to_err_result<'s, T>(
|
||||||
scope: &mut impl v8::ToLocal<'s>,
|
scope: &mut impl v8::ToLocal<'s>,
|
||||||
exception: v8::Local<v8::Value>,
|
exception: v8::Local<v8::Value>,
|
||||||
js_error_create_fn: &JSErrorCreateFn,
|
|
||||||
) -> Result<T, ErrBox> {
|
) -> Result<T, ErrBox> {
|
||||||
// TODO(piscisaureus): in rusty_v8, `is_execution_terminating()` should
|
// TODO(piscisaureus): in rusty_v8, `is_execution_terminating()` should
|
||||||
// also be implemented on `struct Isolate`.
|
// also be implemented on `struct Isolate`.
|
||||||
|
@ -593,7 +645,10 @@ 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 js_error = (js_error_create_fn)(js_error);
|
|
||||||
|
let state_rc = CoreIsolate::state(scope.isolate());
|
||||||
|
let state = state_rc.borrow();
|
||||||
|
let js_error = (state.js_error_create_fn)(js_error);
|
||||||
|
|
||||||
if is_terminating_exception {
|
if is_terminating_exception {
|
||||||
// Re-enable exception termination.
|
// Re-enable exception termination.
|
||||||
|
@ -607,13 +662,15 @@ pub(crate) fn exception_to_err_result<'s, T>(
|
||||||
|
|
||||||
fn check_promise_exceptions<'s>(
|
fn check_promise_exceptions<'s>(
|
||||||
scope: &mut impl v8::ToLocal<'s>,
|
scope: &mut impl v8::ToLocal<'s>,
|
||||||
pending_promise_exceptions: &mut HashMap<i32, v8::Global<v8::Value>>,
|
|
||||||
js_error_create_fn: &JSErrorCreateFn,
|
|
||||||
) -> Result<(), ErrBox> {
|
) -> Result<(), ErrBox> {
|
||||||
if let Some(&key) = pending_promise_exceptions.keys().next() {
|
let state_rc = CoreIsolate::state(scope.isolate());
|
||||||
let handle = pending_promise_exceptions.remove(&key).unwrap();
|
let mut state = state_rc.borrow_mut();
|
||||||
|
|
||||||
|
if let Some(&key) = state.pending_promise_exceptions.keys().next() {
|
||||||
|
let handle = state.pending_promise_exceptions.remove(&key).unwrap();
|
||||||
|
drop(state);
|
||||||
let exception = handle.get(scope).expect("empty error handle");
|
let exception = handle.get(scope).expect("empty error handle");
|
||||||
exception_to_err_result(scope, exception, js_error_create_fn)
|
exception_to_err_result(scope, exception)
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -632,6 +689,7 @@ pub mod tests {
|
||||||
use futures::future::lazy;
|
use futures::future::lazy;
|
||||||
use std::ops::FnOnce;
|
use std::ops::FnOnce;
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub fn run_in_task<F>(f: F)
|
pub fn run_in_task<F>(f: F)
|
||||||
where
|
where
|
||||||
|
@ -666,13 +724,13 @@ pub mod tests {
|
||||||
OverflowResAsync,
|
OverflowResAsync,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setup(mode: Mode) -> (Box<CoreIsolate>, Arc<AtomicUsize>) {
|
pub fn setup(mode: Mode) -> (CoreIsolate, Arc<AtomicUsize>) {
|
||||||
let dispatch_count = Arc::new(AtomicUsize::new(0));
|
let dispatch_count = Arc::new(AtomicUsize::new(0));
|
||||||
let dispatch_count_ = dispatch_count.clone();
|
let dispatch_count_ = dispatch_count.clone();
|
||||||
|
|
||||||
let mut isolate = CoreIsolate::new(StartupData::None, false);
|
let mut isolate = CoreIsolate::new(StartupData::None, false);
|
||||||
|
|
||||||
let dispatcher = move |_isolate: &mut CoreIsolate,
|
let dispatcher = move |_state: &mut CoreIsolateState,
|
||||||
control: &[u8],
|
control: &[u8],
|
||||||
_zero_copy: Option<ZeroCopyBuf>|
|
_zero_copy: Option<ZeroCopyBuf>|
|
||||||
-> Op {
|
-> Op {
|
||||||
|
|
|
@ -16,7 +16,7 @@ use futures::stream::StreamExt;
|
||||||
use futures::stream::StreamFuture;
|
use futures::stream::StreamFuture;
|
||||||
use futures::task::AtomicWaker;
|
use futures::task::AtomicWaker;
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
use libc::c_void;
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
|
@ -46,8 +46,9 @@ use crate::StartupData;
|
||||||
/// Creating `EsIsolate` requires to pass `loader` argument
|
/// Creating `EsIsolate` requires to pass `loader` argument
|
||||||
/// that implements `ModuleLoader` trait - that way actual resolution and
|
/// that implements `ModuleLoader` trait - that way actual resolution and
|
||||||
/// loading of modules can be customized by the implementor.
|
/// loading of modules can be customized by the implementor.
|
||||||
pub struct EsIsolate {
|
pub struct EsIsolate(CoreIsolate);
|
||||||
core_isolate: Box<CoreIsolate>,
|
|
||||||
|
pub struct EsIsolateState {
|
||||||
loader: Rc<dyn ModuleLoader>,
|
loader: Rc<dyn ModuleLoader>,
|
||||||
pub modules: Modules,
|
pub modules: Modules,
|
||||||
pub(crate) dyn_import_map:
|
pub(crate) dyn_import_map:
|
||||||
|
@ -62,13 +63,13 @@ impl Deref for EsIsolate {
|
||||||
type Target = CoreIsolate;
|
type Target = CoreIsolate;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
&self.core_isolate
|
&self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DerefMut for EsIsolate {
|
impl DerefMut for EsIsolate {
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
&mut self.core_isolate
|
&mut self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,38 +78,27 @@ impl EsIsolate {
|
||||||
loader: Rc<dyn ModuleLoader>,
|
loader: Rc<dyn ModuleLoader>,
|
||||||
startup_data: StartupData,
|
startup_data: StartupData,
|
||||||
will_snapshot: bool,
|
will_snapshot: bool,
|
||||||
) -> Box<Self> {
|
) -> Self {
|
||||||
let mut core_isolate = CoreIsolate::new(startup_data, will_snapshot);
|
let mut core_isolate = CoreIsolate::new(startup_data, will_snapshot);
|
||||||
{
|
{
|
||||||
let v8_isolate = core_isolate.v8_isolate.as_mut().unwrap();
|
core_isolate.set_host_initialize_import_meta_object_callback(
|
||||||
v8_isolate.set_host_initialize_import_meta_object_callback(
|
|
||||||
bindings::host_initialize_import_meta_object_callback,
|
bindings::host_initialize_import_meta_object_callback,
|
||||||
);
|
);
|
||||||
v8_isolate.set_host_import_module_dynamically_callback(
|
core_isolate.set_host_import_module_dynamically_callback(
|
||||||
bindings::host_import_module_dynamically_callback,
|
bindings::host_import_module_dynamically_callback,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let es_isolate = Self {
|
core_isolate.set_slot(Rc::new(RefCell::new(EsIsolateState {
|
||||||
modules: Modules::new(),
|
modules: Modules::new(),
|
||||||
loader,
|
loader,
|
||||||
core_isolate,
|
|
||||||
dyn_import_map: HashMap::new(),
|
dyn_import_map: HashMap::new(),
|
||||||
preparing_dyn_imports: FuturesUnordered::new(),
|
preparing_dyn_imports: FuturesUnordered::new(),
|
||||||
pending_dyn_imports: FuturesUnordered::new(),
|
pending_dyn_imports: FuturesUnordered::new(),
|
||||||
waker: AtomicWaker::new(),
|
waker: AtomicWaker::new(),
|
||||||
};
|
})));
|
||||||
|
|
||||||
let mut boxed_es_isolate = Box::new(es_isolate);
|
EsIsolate(core_isolate)
|
||||||
{
|
|
||||||
let es_isolate_ptr: *mut Self = Box::into_raw(boxed_es_isolate);
|
|
||||||
boxed_es_isolate = unsafe { Box::from_raw(es_isolate_ptr) };
|
|
||||||
unsafe {
|
|
||||||
let v8_isolate = boxed_es_isolate.v8_isolate.as_mut().unwrap();
|
|
||||||
v8_isolate.set_data(1, es_isolate_ptr as *mut c_void);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
boxed_es_isolate
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Low-level module creation.
|
/// Low-level module creation.
|
||||||
|
@ -120,14 +110,13 @@ impl EsIsolate {
|
||||||
name: &str,
|
name: &str,
|
||||||
source: &str,
|
source: &str,
|
||||||
) -> Result<ModuleId, ErrBox> {
|
) -> Result<ModuleId, ErrBox> {
|
||||||
let core_isolate = &mut self.core_isolate;
|
let state_rc = Self::state(self);
|
||||||
let v8_isolate = core_isolate.v8_isolate.as_mut().unwrap();
|
|
||||||
let js_error_create_fn = &*core_isolate.js_error_create_fn;
|
|
||||||
|
|
||||||
let mut hs = v8::HandleScope::new(v8_isolate);
|
let core_state_rc = CoreIsolate::state(self);
|
||||||
|
let core_state = core_state_rc.borrow();
|
||||||
|
let mut hs = v8::HandleScope::new(&mut self.0);
|
||||||
let scope = hs.enter();
|
let scope = hs.enter();
|
||||||
assert!(!core_isolate.global_context.is_empty());
|
let context = core_state.global_context.get(scope).unwrap();
|
||||||
let context = core_isolate.global_context.get(scope).unwrap();
|
|
||||||
let mut cs = v8::ContextScope::new(scope, context);
|
let mut cs = v8::ContextScope::new(scope, context);
|
||||||
let scope = cs.enter();
|
let scope = cs.enter();
|
||||||
|
|
||||||
|
@ -144,11 +133,7 @@ impl EsIsolate {
|
||||||
|
|
||||||
if tc.has_caught() {
|
if tc.has_caught() {
|
||||||
assert!(maybe_module.is_none());
|
assert!(maybe_module.is_none());
|
||||||
return exception_to_err_result(
|
return exception_to_err_result(scope, tc.exception().unwrap());
|
||||||
scope,
|
|
||||||
tc.exception().unwrap(),
|
|
||||||
js_error_create_fn,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let module = maybe_module.unwrap();
|
let module = maybe_module.unwrap();
|
||||||
|
@ -158,16 +143,21 @@ impl EsIsolate {
|
||||||
for i in 0..module.get_module_requests_length() {
|
for i in 0..module.get_module_requests_length() {
|
||||||
let import_specifier =
|
let import_specifier =
|
||||||
module.get_module_request(i).to_rust_string_lossy(scope);
|
module.get_module_request(i).to_rust_string_lossy(scope);
|
||||||
|
let state = state_rc.borrow();
|
||||||
let module_specifier =
|
let module_specifier =
|
||||||
self.loader.resolve(&import_specifier, name, false)?;
|
state.loader.resolve(&import_specifier, name, false)?;
|
||||||
import_specifiers.push(module_specifier);
|
import_specifiers.push(module_specifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut handle = v8::Global::<v8::Module>::new();
|
let mut handle = v8::Global::<v8::Module>::new();
|
||||||
handle.set(scope, module);
|
handle.set(scope, module);
|
||||||
self
|
|
||||||
.modules
|
{
|
||||||
.register(id, name, main, handle, import_specifiers);
|
let mut state = state_rc.borrow_mut();
|
||||||
|
state
|
||||||
|
.modules
|
||||||
|
.register(id, name, main, handle, import_specifiers);
|
||||||
|
}
|
||||||
Ok(id)
|
Ok(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,32 +167,30 @@ impl EsIsolate {
|
||||||
/// the V8 exception. By default this type is JSError, however it may be a
|
/// 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.
|
/// different type if CoreIsolate::set_js_error_create_fn() has been used.
|
||||||
fn mod_instantiate(&mut self, id: ModuleId) -> Result<(), ErrBox> {
|
fn mod_instantiate(&mut self, id: ModuleId) -> Result<(), ErrBox> {
|
||||||
let v8_isolate = self.core_isolate.v8_isolate.as_mut().unwrap();
|
let state_rc = Self::state(self);
|
||||||
let js_error_create_fn = &*self.core_isolate.js_error_create_fn;
|
let state = state_rc.borrow();
|
||||||
|
|
||||||
let mut hs = v8::HandleScope::new(v8_isolate);
|
let core_state_rc = CoreIsolate::state(self);
|
||||||
|
let core_state = core_state_rc.borrow();
|
||||||
|
let mut hs = v8::HandleScope::new(&mut self.0);
|
||||||
let scope = hs.enter();
|
let scope = hs.enter();
|
||||||
assert!(!self.core_isolate.global_context.is_empty());
|
let context = core_state.global_context.get(scope).unwrap();
|
||||||
let context = self.core_isolate.global_context.get(scope).unwrap();
|
|
||||||
let mut cs = v8::ContextScope::new(scope, context);
|
let mut cs = v8::ContextScope::new(scope, context);
|
||||||
let scope = cs.enter();
|
let scope = cs.enter();
|
||||||
|
|
||||||
let mut try_catch = v8::TryCatch::new(scope);
|
let mut try_catch = v8::TryCatch::new(scope);
|
||||||
let tc = try_catch.enter();
|
let tc = try_catch.enter();
|
||||||
|
|
||||||
let module_info = match self.modules.get_info(id) {
|
let module_info = match state.modules.get_info(id) {
|
||||||
Some(info) => info,
|
Some(info) => info,
|
||||||
None if id == 0 => return Ok(()),
|
None if id == 0 => return Ok(()),
|
||||||
_ => panic!("module id {} not found in module table", id),
|
_ => panic!("module id {} not found in module table", id),
|
||||||
};
|
};
|
||||||
let mut module = module_info.handle.get(scope).unwrap();
|
let mut module = module_info.handle.get(scope).unwrap();
|
||||||
|
drop(state);
|
||||||
|
|
||||||
if module.get_status() == v8::ModuleStatus::Errored {
|
if module.get_status() == v8::ModuleStatus::Errored {
|
||||||
exception_to_err_result(
|
exception_to_err_result(scope, module.get_exception())?
|
||||||
scope,
|
|
||||||
module.get_exception(),
|
|
||||||
js_error_create_fn,
|
|
||||||
)?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let result =
|
let result =
|
||||||
|
@ -211,7 +199,7 @@ impl EsIsolate {
|
||||||
Some(_) => Ok(()),
|
Some(_) => Ok(()),
|
||||||
None => {
|
None => {
|
||||||
let exception = tc.exception().unwrap();
|
let exception = tc.exception().unwrap();
|
||||||
exception_to_err_result(scope, exception, js_error_create_fn)
|
exception_to_err_result(scope, exception)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -222,20 +210,24 @@ impl EsIsolate {
|
||||||
/// the V8 exception. By default this type is JSError, however it may be a
|
/// 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.
|
/// different type if CoreIsolate::set_js_error_create_fn() has been used.
|
||||||
pub fn mod_evaluate(&mut self, id: ModuleId) -> Result<(), ErrBox> {
|
pub fn mod_evaluate(&mut self, id: ModuleId) -> Result<(), ErrBox> {
|
||||||
let core_isolate = &mut self.core_isolate;
|
let state_rc = Self::state(self);
|
||||||
let v8_isolate = core_isolate.v8_isolate.as_mut().unwrap();
|
let state = state_rc.borrow();
|
||||||
let js_error_create_fn = &*core_isolate.js_error_create_fn;
|
|
||||||
|
|
||||||
let mut hs = v8::HandleScope::new(v8_isolate);
|
let core_state_rc = CoreIsolate::state(self);
|
||||||
|
|
||||||
|
let mut hs = v8::HandleScope::new(&mut self.0);
|
||||||
let scope = hs.enter();
|
let scope = hs.enter();
|
||||||
assert!(!core_isolate.global_context.is_empty());
|
let context = {
|
||||||
let context = core_isolate.global_context.get(scope).unwrap();
|
let core_state = core_state_rc.borrow();
|
||||||
|
core_state.global_context.get(scope).unwrap()
|
||||||
|
};
|
||||||
let mut cs = v8::ContextScope::new(scope, context);
|
let mut cs = v8::ContextScope::new(scope, context);
|
||||||
let scope = cs.enter();
|
let scope = cs.enter();
|
||||||
|
|
||||||
let info = self.modules.get_info(id).expect("ModuleInfo not found");
|
let info = state.modules.get_info(id).expect("ModuleInfo not found");
|
||||||
let module = info.handle.get(scope).expect("Empty module handle");
|
let module = info.handle.get(scope).expect("Empty module handle");
|
||||||
let mut status = module.get_status();
|
let mut status = module.get_status();
|
||||||
|
drop(state);
|
||||||
if status == v8::ModuleStatus::Instantiated {
|
if status == v8::ModuleStatus::Instantiated {
|
||||||
// IMPORTANT: Top-level-await is enabled, which means that return value
|
// IMPORTANT: Top-level-await is enabled, which means that return value
|
||||||
// of module evaluation is a promise.
|
// of module evaluation is a promise.
|
||||||
|
@ -266,8 +258,9 @@ impl EsIsolate {
|
||||||
let promise = v8::Local::<v8::Promise>::try_from(value)
|
let promise = v8::Local::<v8::Promise>::try_from(value)
|
||||||
.expect("Expected to get promise as module evaluation result");
|
.expect("Expected to get promise as module evaluation result");
|
||||||
let promise_id = promise.get_identity_hash();
|
let promise_id = promise.get_identity_hash();
|
||||||
|
let mut core_state = core_state_rc.borrow_mut();
|
||||||
if let Some(mut handle) =
|
if let Some(mut handle) =
|
||||||
core_isolate.pending_promise_exceptions.remove(&promise_id)
|
core_state.pending_promise_exceptions.remove(&promise_id)
|
||||||
{
|
{
|
||||||
handle.reset(scope);
|
handle.reset(scope);
|
||||||
}
|
}
|
||||||
|
@ -280,68 +273,41 @@ impl EsIsolate {
|
||||||
v8::ModuleStatus::Evaluated => Ok(()),
|
v8::ModuleStatus::Evaluated => Ok(()),
|
||||||
v8::ModuleStatus::Errored => {
|
v8::ModuleStatus::Errored => {
|
||||||
let exception = module.get_exception();
|
let exception = module.get_exception();
|
||||||
exception_to_err_result(scope, exception, js_error_create_fn)
|
exception_to_err_result(scope, exception)
|
||||||
.map_err(|err| attach_handle_to_error(scope, err, exception))
|
.map_err(|err| attach_handle_to_error(scope, err, exception))
|
||||||
}
|
}
|
||||||
other => panic!("Unexpected module status {:?}", other),
|
other => panic!("Unexpected module status {:?}", other),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called by V8 during `Isolate::mod_instantiate`.
|
|
||||||
pub fn module_resolve_cb(
|
|
||||||
&mut self,
|
|
||||||
specifier: &str,
|
|
||||||
referrer_id: ModuleId,
|
|
||||||
) -> ModuleId {
|
|
||||||
let referrer = self.modules.get_name(referrer_id).unwrap();
|
|
||||||
let specifier = self
|
|
||||||
.loader
|
|
||||||
.resolve(specifier, referrer, false)
|
|
||||||
.expect("Module should have been already resolved");
|
|
||||||
self.modules.get_id(specifier.as_str()).unwrap_or(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called by V8 during `Isolate::mod_instantiate`.
|
|
||||||
pub fn dyn_import_cb(
|
|
||||||
&mut self,
|
|
||||||
resolver_handle: v8::Global<v8::PromiseResolver>,
|
|
||||||
specifier: &str,
|
|
||||||
referrer: &str,
|
|
||||||
) {
|
|
||||||
debug!("dyn_import specifier {} referrer {} ", specifier, referrer);
|
|
||||||
|
|
||||||
let load = RecursiveModuleLoad::dynamic_import(
|
|
||||||
specifier,
|
|
||||||
referrer,
|
|
||||||
self.loader.clone(),
|
|
||||||
);
|
|
||||||
self.dyn_import_map.insert(load.id, resolver_handle);
|
|
||||||
self.waker.wake();
|
|
||||||
let fut = load.prepare().boxed_local();
|
|
||||||
self.preparing_dyn_imports.push(fut);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn dyn_import_error(
|
fn dyn_import_error(
|
||||||
&mut self,
|
&mut self,
|
||||||
id: ModuleLoadId,
|
id: ModuleLoadId,
|
||||||
err: ErrBox,
|
err: ErrBox,
|
||||||
) -> Result<(), ErrBox> {
|
) -> Result<(), ErrBox> {
|
||||||
let core_isolate = &mut self.core_isolate;
|
let state_rc = Self::state(self);
|
||||||
let v8_isolate = core_isolate.v8_isolate.as_mut().unwrap();
|
let mut state = state_rc.borrow_mut();
|
||||||
|
|
||||||
let mut hs = v8::HandleScope::new(v8_isolate);
|
let core_state_rc = CoreIsolate::state(self);
|
||||||
|
let core_state = core_state_rc.borrow();
|
||||||
|
|
||||||
|
let mut hs = v8::HandleScope::new(&mut self.0);
|
||||||
let scope = hs.enter();
|
let scope = hs.enter();
|
||||||
let context = core_isolate.global_context.get(scope).unwrap();
|
let context = core_state.global_context.get(scope).unwrap();
|
||||||
let mut cs = v8::ContextScope::new(scope, context);
|
let mut cs = v8::ContextScope::new(scope, context);
|
||||||
let scope = cs.enter();
|
let scope = cs.enter();
|
||||||
|
|
||||||
let mut resolver_handle = self
|
drop(core_state);
|
||||||
|
|
||||||
|
let mut resolver_handle = state
|
||||||
.dyn_import_map
|
.dyn_import_map
|
||||||
.remove(&id)
|
.remove(&id)
|
||||||
.expect("Invalid dyn import id");
|
.expect("Invalid dyn import id");
|
||||||
let resolver = resolver_handle.get(scope).unwrap();
|
let resolver = resolver_handle.get(scope).unwrap();
|
||||||
resolver_handle.reset(scope);
|
resolver_handle.reset(scope);
|
||||||
|
|
||||||
|
drop(state);
|
||||||
|
|
||||||
let exception = err
|
let exception = err
|
||||||
.downcast_ref::<ErrWithV8Handle>()
|
.downcast_ref::<ErrWithV8Handle>()
|
||||||
.and_then(|err| err.get_handle().get(scope))
|
.and_then(|err| err.get_handle().get(scope))
|
||||||
|
@ -361,29 +327,40 @@ impl EsIsolate {
|
||||||
id: ModuleLoadId,
|
id: ModuleLoadId,
|
||||||
mod_id: ModuleId,
|
mod_id: ModuleId,
|
||||||
) -> Result<(), ErrBox> {
|
) -> Result<(), ErrBox> {
|
||||||
|
let state_rc = Self::state(self);
|
||||||
|
|
||||||
|
let core_state_rc = CoreIsolate::state(self);
|
||||||
|
let core_state = core_state_rc.borrow();
|
||||||
|
|
||||||
debug!("dyn_import_done {} {:?}", id, mod_id);
|
debug!("dyn_import_done {} {:?}", id, mod_id);
|
||||||
assert!(mod_id != 0);
|
assert!(mod_id != 0);
|
||||||
let v8_isolate = self.core_isolate.v8_isolate.as_mut().unwrap();
|
let mut hs = v8::HandleScope::new(&mut self.0);
|
||||||
let mut hs = v8::HandleScope::new(v8_isolate);
|
|
||||||
let scope = hs.enter();
|
let scope = hs.enter();
|
||||||
assert!(!self.core_isolate.global_context.is_empty());
|
let context = core_state.global_context.get(scope).unwrap();
|
||||||
let context = self.core_isolate.global_context.get(scope).unwrap();
|
|
||||||
let mut cs = v8::ContextScope::new(scope, context);
|
let mut cs = v8::ContextScope::new(scope, context);
|
||||||
let scope = cs.enter();
|
let scope = cs.enter();
|
||||||
|
|
||||||
let mut resolver_handle = self
|
let mut resolver_handle = {
|
||||||
.dyn_import_map
|
let mut state = state_rc.borrow_mut();
|
||||||
.remove(&id)
|
state
|
||||||
.expect("Invalid dyn import id");
|
.dyn_import_map
|
||||||
|
.remove(&id)
|
||||||
|
.expect("Invalid dyn import id")
|
||||||
|
};
|
||||||
let resolver = resolver_handle.get(scope).unwrap();
|
let resolver = resolver_handle.get(scope).unwrap();
|
||||||
resolver_handle.reset(scope);
|
resolver_handle.reset(scope);
|
||||||
let info = self
|
|
||||||
.modules
|
let mut module = {
|
||||||
.get_info(mod_id)
|
let state = state_rc.borrow();
|
||||||
.expect("Dyn import module info not found");
|
let info = state
|
||||||
// Resolution success
|
.modules
|
||||||
let mut module = info.handle.get(scope).unwrap();
|
.get_info(mod_id)
|
||||||
|
.expect("Dyn import module info not found");
|
||||||
|
// Resolution success
|
||||||
|
info.handle.get(scope).unwrap()
|
||||||
|
};
|
||||||
assert_eq!(module.get_status(), v8::ModuleStatus::Evaluated);
|
assert_eq!(module.get_status(), v8::ModuleStatus::Evaluated);
|
||||||
|
|
||||||
let module_namespace = module.get_module_namespace();
|
let module_namespace = module.get_module_namespace();
|
||||||
resolver.resolve(context, module_namespace).unwrap();
|
resolver.resolve(context, module_namespace).unwrap();
|
||||||
scope.isolate().run_microtasks();
|
scope.isolate().run_microtasks();
|
||||||
|
@ -394,8 +371,14 @@ impl EsIsolate {
|
||||||
&mut self,
|
&mut self,
|
||||||
cx: &mut Context,
|
cx: &mut Context,
|
||||||
) -> Poll<Result<(), ErrBox>> {
|
) -> Poll<Result<(), ErrBox>> {
|
||||||
|
let state_rc = Self::state(self);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match self.preparing_dyn_imports.poll_next_unpin(cx) {
|
let r = {
|
||||||
|
let mut state = state_rc.borrow_mut();
|
||||||
|
state.preparing_dyn_imports.poll_next_unpin(cx)
|
||||||
|
};
|
||||||
|
match r {
|
||||||
Poll::Pending | Poll::Ready(None) => {
|
Poll::Pending | Poll::Ready(None) => {
|
||||||
// There are no active dynamic import loaders, or none are ready.
|
// There are no active dynamic import loaders, or none are ready.
|
||||||
return Poll::Ready(Ok(()));
|
return Poll::Ready(Ok(()));
|
||||||
|
@ -406,7 +389,8 @@ impl EsIsolate {
|
||||||
|
|
||||||
match prepare_result {
|
match prepare_result {
|
||||||
Ok(load) => {
|
Ok(load) => {
|
||||||
self.pending_dyn_imports.push(load.into_future());
|
let state = state_rc.borrow_mut();
|
||||||
|
state.pending_dyn_imports.push(load.into_future());
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
self.dyn_import_error(dyn_import_id, err)?;
|
self.dyn_import_error(dyn_import_id, err)?;
|
||||||
|
@ -418,8 +402,14 @@ impl EsIsolate {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poll_dyn_imports(&mut self, cx: &mut Context) -> Poll<Result<(), ErrBox>> {
|
fn poll_dyn_imports(&mut self, cx: &mut Context) -> Poll<Result<(), ErrBox>> {
|
||||||
|
let state_rc = Self::state(self);
|
||||||
loop {
|
loop {
|
||||||
match self.pending_dyn_imports.poll_next_unpin(cx) {
|
let poll_result = {
|
||||||
|
let mut state = state_rc.borrow_mut();
|
||||||
|
state.pending_dyn_imports.poll_next_unpin(cx)
|
||||||
|
};
|
||||||
|
|
||||||
|
match poll_result {
|
||||||
Poll::Pending | Poll::Ready(None) => {
|
Poll::Pending | Poll::Ready(None) => {
|
||||||
// There are no active dynamic import loaders, or none are ready.
|
// There are no active dynamic import loaders, or none are ready.
|
||||||
return Poll::Ready(Ok(()));
|
return Poll::Ready(Ok(()));
|
||||||
|
@ -438,7 +428,8 @@ impl EsIsolate {
|
||||||
match self.register_during_load(info, &mut load) {
|
match self.register_during_load(info, &mut load) {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
// Keep importing until it's fully drained
|
// Keep importing until it's fully drained
|
||||||
self.pending_dyn_imports.push(load.into_future());
|
let state = state_rc.borrow_mut();
|
||||||
|
state.pending_dyn_imports.push(load.into_future());
|
||||||
}
|
}
|
||||||
Err(err) => self.dyn_import_error(dyn_import_id, err)?,
|
Err(err) => self.dyn_import_error(dyn_import_id, err)?,
|
||||||
}
|
}
|
||||||
|
@ -481,6 +472,7 @@ impl EsIsolate {
|
||||||
let referrer_specifier =
|
let referrer_specifier =
|
||||||
ModuleSpecifier::resolve_url(&module_url_found).unwrap();
|
ModuleSpecifier::resolve_url(&module_url_found).unwrap();
|
||||||
|
|
||||||
|
let state_rc = Self::state(self);
|
||||||
// #A There are 3 cases to handle at this moment:
|
// #A There are 3 cases to handle at this moment:
|
||||||
// 1. Source code resolved result have the same module name as requested
|
// 1. Source code resolved result have the same module name as requested
|
||||||
// and is not yet registered
|
// and is not yet registered
|
||||||
|
@ -493,10 +485,18 @@ impl EsIsolate {
|
||||||
|
|
||||||
// If necessary, register an alias.
|
// If necessary, register an alias.
|
||||||
if module_url_specified != module_url_found {
|
if module_url_specified != module_url_found {
|
||||||
self.modules.alias(&module_url_specified, &module_url_found);
|
let mut state = state_rc.borrow_mut();
|
||||||
|
state
|
||||||
|
.modules
|
||||||
|
.alias(&module_url_specified, &module_url_found);
|
||||||
}
|
}
|
||||||
|
|
||||||
let module_id = match self.modules.get_id(&module_url_found) {
|
let maybe_mod_id = {
|
||||||
|
let state = state_rc.borrow();
|
||||||
|
state.modules.get_id(&module_url_found)
|
||||||
|
};
|
||||||
|
|
||||||
|
let module_id = match maybe_mod_id {
|
||||||
Some(id) => {
|
Some(id) => {
|
||||||
// Module has already been registered.
|
// Module has already been registered.
|
||||||
debug!(
|
debug!(
|
||||||
|
@ -510,10 +510,19 @@ impl EsIsolate {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Now we must iterate over all imports of the module and load them.
|
// Now we must iterate over all imports of the module and load them.
|
||||||
let imports = self.modules.get_children(module_id).unwrap();
|
let imports = {
|
||||||
|
let state_rc = Self::state(self);
|
||||||
|
let state = state_rc.borrow();
|
||||||
|
state.modules.get_children(module_id).unwrap().clone()
|
||||||
|
};
|
||||||
|
|
||||||
for module_specifier in imports {
|
for module_specifier in imports {
|
||||||
if !self.modules.is_registered(module_specifier) {
|
let is_registered = {
|
||||||
|
let state_rc = Self::state(self);
|
||||||
|
let state = state_rc.borrow();
|
||||||
|
state.modules.is_registered(&module_specifier)
|
||||||
|
};
|
||||||
|
if !is_registered {
|
||||||
load
|
load
|
||||||
.add_import(module_specifier.to_owned(), referrer_specifier.clone());
|
.add_import(module_specifier.to_owned(), referrer_specifier.clone());
|
||||||
}
|
}
|
||||||
|
@ -541,11 +550,13 @@ impl EsIsolate {
|
||||||
specifier: &ModuleSpecifier,
|
specifier: &ModuleSpecifier,
|
||||||
code: Option<String>,
|
code: Option<String>,
|
||||||
) -> Result<ModuleId, ErrBox> {
|
) -> Result<ModuleId, ErrBox> {
|
||||||
let load = RecursiveModuleLoad::main(
|
let loader = {
|
||||||
&specifier.to_string(),
|
let state_rc = Self::state(self);
|
||||||
code,
|
let state = state_rc.borrow();
|
||||||
self.loader.clone(),
|
state.loader.clone()
|
||||||
);
|
};
|
||||||
|
|
||||||
|
let load = RecursiveModuleLoad::main(&specifier.to_string(), code, loader);
|
||||||
let (_load_id, prepare_result) = load.prepare().await;
|
let (_load_id, prepare_result) = load.prepare().await;
|
||||||
|
|
||||||
let mut load = prepare_result?;
|
let mut load = prepare_result?;
|
||||||
|
@ -558,30 +569,49 @@ impl EsIsolate {
|
||||||
let root_id = load.root_module_id.expect("Root module id empty");
|
let root_id = load.root_module_id.expect("Root module id empty");
|
||||||
self.mod_instantiate(root_id).map(|_| root_id)
|
self.mod_instantiate(root_id).map(|_| root_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn state(isolate: &v8::Isolate) -> Rc<RefCell<EsIsolateState>> {
|
||||||
|
let s = isolate.get_slot::<Rc<RefCell<EsIsolateState>>>().unwrap();
|
||||||
|
s.clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Future for EsIsolate {
|
impl Future for EsIsolate {
|
||||||
type Output = Result<(), ErrBox>;
|
type Output = Result<(), ErrBox>;
|
||||||
|
|
||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||||
let inner = self.get_mut();
|
let es_isolate = self.get_mut();
|
||||||
|
|
||||||
inner.waker.register(cx.waker());
|
let state_rc = Self::state(es_isolate);
|
||||||
|
|
||||||
if !inner.preparing_dyn_imports.is_empty() {
|
{
|
||||||
let poll_imports = inner.prepare_dyn_imports(cx)?;
|
let state = state_rc.borrow();
|
||||||
|
state.waker.register(cx.waker());
|
||||||
|
}
|
||||||
|
|
||||||
|
let has_preparing = {
|
||||||
|
let state = state_rc.borrow();
|
||||||
|
!state.preparing_dyn_imports.is_empty()
|
||||||
|
};
|
||||||
|
if has_preparing {
|
||||||
|
let poll_imports = es_isolate.prepare_dyn_imports(cx)?;
|
||||||
assert!(poll_imports.is_ready());
|
assert!(poll_imports.is_ready());
|
||||||
}
|
}
|
||||||
|
|
||||||
if !inner.pending_dyn_imports.is_empty() {
|
let has_pending = {
|
||||||
let poll_imports = inner.poll_dyn_imports(cx)?;
|
let state = state_rc.borrow();
|
||||||
|
!state.pending_dyn_imports.is_empty()
|
||||||
|
};
|
||||||
|
if has_pending {
|
||||||
|
let poll_imports = es_isolate.poll_dyn_imports(cx)?;
|
||||||
assert!(poll_imports.is_ready());
|
assert!(poll_imports.is_ready());
|
||||||
}
|
}
|
||||||
|
|
||||||
match ready!(inner.core_isolate.poll_unpin(cx)) {
|
match ready!(es_isolate.0.poll_unpin(cx)) {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
if inner.pending_dyn_imports.is_empty()
|
let state = state_rc.borrow();
|
||||||
&& inner.preparing_dyn_imports.is_empty()
|
if state.pending_dyn_imports.is_empty()
|
||||||
|
&& state.preparing_dyn_imports.is_empty()
|
||||||
{
|
{
|
||||||
Poll::Ready(Ok(()))
|
Poll::Ready(Ok(()))
|
||||||
} else {
|
} else {
|
||||||
|
@ -593,10 +623,47 @@ impl Future for EsIsolate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl EsIsolateState {
|
||||||
|
// Called by V8 during `Isolate::mod_instantiate`.
|
||||||
|
pub fn module_resolve_cb(
|
||||||
|
&mut self,
|
||||||
|
specifier: &str,
|
||||||
|
referrer_id: ModuleId,
|
||||||
|
) -> ModuleId {
|
||||||
|
let referrer = self.modules.get_name(referrer_id).unwrap();
|
||||||
|
let specifier = self
|
||||||
|
.loader
|
||||||
|
.resolve(specifier, referrer, false)
|
||||||
|
.expect("Module should have been already resolved");
|
||||||
|
self.modules.get_id(specifier.as_str()).unwrap_or(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called by V8 during `Isolate::mod_instantiate`.
|
||||||
|
pub fn dyn_import_cb(
|
||||||
|
&mut self,
|
||||||
|
resolver_handle: v8::Global<v8::PromiseResolver>,
|
||||||
|
specifier: &str,
|
||||||
|
referrer: &str,
|
||||||
|
) {
|
||||||
|
debug!("dyn_import specifier {} referrer {} ", specifier, referrer);
|
||||||
|
|
||||||
|
let load = RecursiveModuleLoad::dynamic_import(
|
||||||
|
specifier,
|
||||||
|
referrer,
|
||||||
|
self.loader.clone(),
|
||||||
|
);
|
||||||
|
self.dyn_import_map.insert(load.id, resolver_handle);
|
||||||
|
self.waker.wake();
|
||||||
|
let fut = load.prepare().boxed_local();
|
||||||
|
self.preparing_dyn_imports.push(fut);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub mod tests {
|
pub mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::core_isolate::tests::run_in_task;
|
use crate::core_isolate::tests::run_in_task;
|
||||||
|
use crate::core_isolate::CoreIsolateState;
|
||||||
use crate::js_check;
|
use crate::js_check;
|
||||||
use crate::modules::ModuleSourceFuture;
|
use crate::modules::ModuleSourceFuture;
|
||||||
use crate::ops::*;
|
use crate::ops::*;
|
||||||
|
@ -643,7 +710,7 @@ pub mod tests {
|
||||||
|
|
||||||
let mut isolate = EsIsolate::new(loader, StartupData::None, false);
|
let mut isolate = EsIsolate::new(loader, StartupData::None, false);
|
||||||
|
|
||||||
let dispatcher = move |_isolate: &mut CoreIsolate,
|
let dispatcher = move |_state: &mut CoreIsolateState,
|
||||||
control: &[u8],
|
control: &[u8],
|
||||||
_zero_copy: Option<ZeroCopyBuf>|
|
_zero_copy: Option<ZeroCopyBuf>|
|
||||||
-> Op {
|
-> Op {
|
||||||
|
@ -684,16 +751,23 @@ pub mod tests {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(dispatch_count.load(Ordering::Relaxed), 0);
|
assert_eq!(dispatch_count.load(Ordering::Relaxed), 0);
|
||||||
|
|
||||||
let imports = isolate.modules.get_children(mod_a);
|
let state_rc = EsIsolate::state(&isolate);
|
||||||
assert_eq!(
|
{
|
||||||
imports,
|
let state = state_rc.borrow();
|
||||||
Some(&vec![ModuleSpecifier::resolve_url("file:///b.js").unwrap()])
|
let imports = state.modules.get_children(mod_a);
|
||||||
);
|
assert_eq!(
|
||||||
|
imports,
|
||||||
|
Some(&vec![ModuleSpecifier::resolve_url("file:///b.js").unwrap()])
|
||||||
|
);
|
||||||
|
}
|
||||||
let mod_b = isolate
|
let mod_b = isolate
|
||||||
.mod_new(false, "file:///b.js", "export function b() { return 'b' }")
|
.mod_new(false, "file:///b.js", "export function b() { return 'b' }")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let imports = isolate.modules.get_children(mod_b).unwrap();
|
{
|
||||||
assert_eq!(imports.len(), 0);
|
let state = state_rc.borrow();
|
||||||
|
let imports = state.modules.get_children(mod_b).unwrap();
|
||||||
|
assert_eq!(imports.len(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
js_check(isolate.mod_instantiate(mod_b));
|
js_check(isolate.mod_instantiate(mod_b));
|
||||||
assert_eq!(dispatch_count.load(Ordering::Relaxed), 0);
|
assert_eq!(dispatch_count.load(Ordering::Relaxed), 0);
|
||||||
|
|
|
@ -4,6 +4,7 @@ extern crate derive_deref;
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
use deno_core::CoreIsolate;
|
use deno_core::CoreIsolate;
|
||||||
|
use deno_core::CoreIsolateState;
|
||||||
use deno_core::Op;
|
use deno_core::Op;
|
||||||
use deno_core::ResourceTable;
|
use deno_core::ResourceTable;
|
||||||
use deno_core::Script;
|
use deno_core::Script;
|
||||||
|
@ -77,7 +78,7 @@ impl From<Record> for RecordBuf {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Isolate {
|
struct Isolate {
|
||||||
core_isolate: Box<CoreIsolate>, // Unclear why CoreIsolate::new() returns a box.
|
core_isolate: CoreIsolate,
|
||||||
state: State,
|
state: State,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +116,7 @@ impl Isolate {
|
||||||
F: 'static + Fn(State, u32, Option<ZeroCopyBuf>) -> Result<u32, Error>,
|
F: 'static + Fn(State, u32, Option<ZeroCopyBuf>) -> Result<u32, Error>,
|
||||||
{
|
{
|
||||||
let state = self.state.clone();
|
let state = self.state.clone();
|
||||||
let core_handler = move |_isolate: &mut CoreIsolate,
|
let core_handler = move |_isolate_state: &mut CoreIsolateState,
|
||||||
control_buf: &[u8],
|
control_buf: &[u8],
|
||||||
zero_copy_buf: Option<ZeroCopyBuf>|
|
zero_copy_buf: Option<ZeroCopyBuf>|
|
||||||
-> Op {
|
-> Op {
|
||||||
|
@ -145,7 +146,7 @@ impl Isolate {
|
||||||
<F::Ok as TryInto<i32>>::Error: Debug,
|
<F::Ok as TryInto<i32>>::Error: Debug,
|
||||||
{
|
{
|
||||||
let state = self.state.clone();
|
let state = self.state.clone();
|
||||||
let core_handler = move |_isolate: &mut CoreIsolate,
|
let core_handler = move |_isolate_state: &mut CoreIsolateState,
|
||||||
control_buf: &[u8],
|
control_buf: &[u8],
|
||||||
zero_copy_buf: Option<ZeroCopyBuf>|
|
zero_copy_buf: Option<ZeroCopyBuf>|
|
||||||
-> Op {
|
-> Op {
|
||||||
|
|
|
@ -25,12 +25,14 @@ pub use rusty_v8 as v8;
|
||||||
|
|
||||||
pub use crate::core_isolate::js_check;
|
pub use crate::core_isolate::js_check;
|
||||||
pub use crate::core_isolate::CoreIsolate;
|
pub use crate::core_isolate::CoreIsolate;
|
||||||
|
pub use crate::core_isolate::CoreIsolateState;
|
||||||
pub use crate::core_isolate::Script;
|
pub use crate::core_isolate::Script;
|
||||||
pub use crate::core_isolate::Snapshot;
|
pub use crate::core_isolate::Snapshot;
|
||||||
pub use crate::core_isolate::StartupData;
|
pub use crate::core_isolate::StartupData;
|
||||||
pub use crate::errors::ErrBox;
|
pub use crate::errors::ErrBox;
|
||||||
pub use crate::errors::JSError;
|
pub use crate::errors::JSError;
|
||||||
pub use crate::es_isolate::EsIsolate;
|
pub use crate::es_isolate::EsIsolate;
|
||||||
|
pub use crate::es_isolate::EsIsolateState;
|
||||||
pub use crate::flags::v8_set_flags;
|
pub use crate::flags::v8_set_flags;
|
||||||
pub use crate::module_specifier::ModuleResolutionError;
|
pub use crate::module_specifier::ModuleResolutionError;
|
||||||
pub use crate::module_specifier::ModuleSpecifier;
|
pub use crate::module_specifier::ModuleSpecifier;
|
||||||
|
|
|
@ -745,7 +745,9 @@ mod tests {
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
let modules = &isolate.modules;
|
let state_rc = EsIsolate::state(&isolate);
|
||||||
|
let state = state_rc.borrow();
|
||||||
|
let modules = &state.modules;
|
||||||
assert_eq!(modules.get_id("file:///a.js"), Some(a_id));
|
assert_eq!(modules.get_id("file:///a.js"), Some(a_id));
|
||||||
let b_id = modules.get_id("file:///b.js").unwrap();
|
let b_id = modules.get_id("file:///b.js").unwrap();
|
||||||
let c_id = modules.get_id("file:///c.js").unwrap();
|
let c_id = modules.get_id("file:///c.js").unwrap();
|
||||||
|
@ -807,7 +809,9 @@ mod tests {
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
let modules = &isolate.modules;
|
let state_rc = EsIsolate::state(&isolate);
|
||||||
|
let state = state_rc.borrow();
|
||||||
|
let modules = &state.modules;
|
||||||
|
|
||||||
assert_eq!(modules.get_id("file:///circular1.js"), Some(circular1_id));
|
assert_eq!(modules.get_id("file:///circular1.js"), Some(circular1_id));
|
||||||
let circular2_id = modules.get_id("file:///circular2.js").unwrap();
|
let circular2_id = modules.get_id("file:///circular2.js").unwrap();
|
||||||
|
@ -878,7 +882,9 @@ mod tests {
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
let modules = &isolate.modules;
|
let state_rc = EsIsolate::state(&isolate);
|
||||||
|
let state = state_rc.borrow();
|
||||||
|
let modules = &state.modules;
|
||||||
|
|
||||||
assert_eq!(modules.get_id("file:///redirect1.js"), Some(redirect1_id));
|
assert_eq!(modules.get_id("file:///redirect1.js"), Some(redirect1_id));
|
||||||
|
|
||||||
|
@ -1016,7 +1022,9 @@ mod tests {
|
||||||
vec!["file:///b.js", "file:///c.js", "file:///d.js"]
|
vec!["file:///b.js", "file:///c.js", "file:///d.js"]
|
||||||
);
|
);
|
||||||
|
|
||||||
let modules = &isolate.modules;
|
let state_rc = EsIsolate::state(&isolate);
|
||||||
|
let state = state_rc.borrow();
|
||||||
|
let modules = &state.modules;
|
||||||
|
|
||||||
assert_eq!(modules.get_id("file:///main_with_code.js"), Some(main_id));
|
assert_eq!(modules.get_id("file:///main_with_code.js"), Some(main_id));
|
||||||
let b_id = modules.get_id("file:///b.js").unwrap();
|
let b_id = modules.get_id("file:///b.js").unwrap();
|
||||||
|
|
30
core/ops.rs
30
core/ops.rs
|
@ -1,5 +1,5 @@
|
||||||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||||
use crate::CoreIsolate;
|
use crate::core_isolate::CoreIsolateState;
|
||||||
use crate::ZeroCopyBuf;
|
use crate::ZeroCopyBuf;
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
@ -22,7 +22,7 @@ pub enum Op {
|
||||||
|
|
||||||
/// Main type describing op
|
/// Main type describing op
|
||||||
pub type OpDispatcher =
|
pub type OpDispatcher =
|
||||||
dyn Fn(&mut CoreIsolate, &[u8], Option<ZeroCopyBuf>) -> Op + 'static;
|
dyn Fn(&mut CoreIsolateState, &[u8], Option<ZeroCopyBuf>) -> Op + 'static;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct OpRegistry {
|
pub struct OpRegistry {
|
||||||
|
@ -33,8 +33,8 @@ pub struct OpRegistry {
|
||||||
impl OpRegistry {
|
impl OpRegistry {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let mut registry = Self::default();
|
let mut registry = Self::default();
|
||||||
let op_id = registry.register("ops", |isolate, _, _| {
|
let op_id = registry.register("ops", |state, _, _| {
|
||||||
let buf = isolate.op_registry.json_map();
|
let buf = state.op_registry.json_map();
|
||||||
Op::Sync(buf)
|
Op::Sync(buf)
|
||||||
});
|
});
|
||||||
assert_eq!(op_id, 0);
|
assert_eq!(op_id, 0);
|
||||||
|
@ -43,7 +43,7 @@ impl OpRegistry {
|
||||||
|
|
||||||
pub fn register<F>(&mut self, name: &str, op: F) -> OpId
|
pub fn register<F>(&mut self, name: &str, op: F) -> OpId
|
||||||
where
|
where
|
||||||
F: Fn(&mut CoreIsolate, &[u8], Option<ZeroCopyBuf>) -> Op + 'static,
|
F: Fn(&mut CoreIsolateState, &[u8], Option<ZeroCopyBuf>) -> Op + 'static,
|
||||||
{
|
{
|
||||||
let op_id = self.dispatchers.len() as u32;
|
let op_id = self.dispatchers.len() as u32;
|
||||||
|
|
||||||
|
@ -68,6 +68,7 @@ impl OpRegistry {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_op_registry() {
|
fn test_op_registry() {
|
||||||
|
use crate::CoreIsolate;
|
||||||
use std::sync::atomic;
|
use std::sync::atomic;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
let mut op_registry = OpRegistry::new();
|
let mut op_registry = OpRegistry::new();
|
||||||
|
@ -86,10 +87,12 @@ fn test_op_registry() {
|
||||||
expected.insert("test".to_string(), 1);
|
expected.insert("test".to_string(), 1);
|
||||||
assert_eq!(op_registry.name_to_id, expected);
|
assert_eq!(op_registry.name_to_id, expected);
|
||||||
|
|
||||||
let mut isolate = CoreIsolate::new(crate::StartupData::None, false);
|
let isolate = CoreIsolate::new(crate::StartupData::None, false);
|
||||||
|
|
||||||
let dispatch = op_registry.get(test_id).unwrap();
|
let dispatch = op_registry.get(test_id).unwrap();
|
||||||
let res = dispatch(&mut isolate, &[], None);
|
let state_rc = CoreIsolate::state(&isolate);
|
||||||
|
let mut state = state_rc.borrow_mut();
|
||||||
|
let res = dispatch(&mut state, &[], None);
|
||||||
if let Op::Sync(buf) = res {
|
if let Op::Sync(buf) = res {
|
||||||
assert_eq!(buf.len(), 0);
|
assert_eq!(buf.len(), 0);
|
||||||
} else {
|
} else {
|
||||||
|
@ -102,6 +105,7 @@ fn test_op_registry() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn register_op_during_call() {
|
fn register_op_during_call() {
|
||||||
|
use crate::CoreIsolate;
|
||||||
use std::sync::atomic;
|
use std::sync::atomic;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
@ -126,13 +130,17 @@ fn register_op_during_call() {
|
||||||
};
|
};
|
||||||
assert!(test_id != 0);
|
assert!(test_id != 0);
|
||||||
|
|
||||||
let mut isolate = CoreIsolate::new(crate::StartupData::None, false);
|
let isolate = CoreIsolate::new(crate::StartupData::None, false);
|
||||||
|
|
||||||
let dispatcher1 = {
|
let dispatcher1 = {
|
||||||
let g = op_registry.lock().unwrap();
|
let g = op_registry.lock().unwrap();
|
||||||
g.get(test_id).unwrap()
|
g.get(test_id).unwrap()
|
||||||
};
|
};
|
||||||
dispatcher1(&mut isolate, &[], None);
|
{
|
||||||
|
let state_rc = CoreIsolate::state(&isolate);
|
||||||
|
let mut state = state_rc.borrow_mut();
|
||||||
|
dispatcher1(&mut state, &[], None);
|
||||||
|
}
|
||||||
|
|
||||||
let mut expected = HashMap::new();
|
let mut expected = HashMap::new();
|
||||||
expected.insert("ops".to_string(), 0);
|
expected.insert("ops".to_string(), 0);
|
||||||
|
@ -147,7 +155,9 @@ fn register_op_during_call() {
|
||||||
let g = op_registry.lock().unwrap();
|
let g = op_registry.lock().unwrap();
|
||||||
g.get(2).unwrap()
|
g.get(2).unwrap()
|
||||||
};
|
};
|
||||||
let res = dispatcher2(&mut isolate, &[], None);
|
let state_rc = CoreIsolate::state(&isolate);
|
||||||
|
let mut state = state_rc.borrow_mut();
|
||||||
|
let res = dispatcher2(&mut state, &[], None);
|
||||||
if let Op::Sync(buf) = res {
|
if let Op::Sync(buf) = res {
|
||||||
assert_eq!(buf.len(), 0);
|
assert_eq!(buf.len(), 0);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -9,6 +9,7 @@ mod ops;
|
||||||
use deno_core::js_check;
|
use deno_core::js_check;
|
||||||
pub use deno_core::v8_set_flags;
|
pub use deno_core::v8_set_flags;
|
||||||
use deno_core::CoreIsolate;
|
use deno_core::CoreIsolate;
|
||||||
|
use deno_core::CoreIsolateState;
|
||||||
use deno_core::ErrBox;
|
use deno_core::ErrBox;
|
||||||
use deno_core::ModuleSpecifier;
|
use deno_core::ModuleSpecifier;
|
||||||
use deno_core::Op;
|
use deno_core::Op;
|
||||||
|
@ -49,11 +50,11 @@ pub struct TSState {
|
||||||
fn compiler_op<D>(
|
fn compiler_op<D>(
|
||||||
ts_state: Arc<Mutex<TSState>>,
|
ts_state: Arc<Mutex<TSState>>,
|
||||||
dispatcher: D,
|
dispatcher: D,
|
||||||
) -> impl Fn(&mut CoreIsolate, &[u8], Option<ZeroCopyBuf>) -> Op
|
) -> impl Fn(&mut CoreIsolateState, &[u8], Option<ZeroCopyBuf>) -> Op
|
||||||
where
|
where
|
||||||
D: Fn(&mut TSState, &[u8]) -> Op,
|
D: Fn(&mut TSState, &[u8]) -> Op,
|
||||||
{
|
{
|
||||||
move |_isolate: &mut CoreIsolate,
|
move |_state: &mut CoreIsolateState,
|
||||||
control: &[u8],
|
control: &[u8],
|
||||||
zero_copy_buf: Option<ZeroCopyBuf>|
|
zero_copy_buf: Option<ZeroCopyBuf>|
|
||||||
-> Op {
|
-> Op {
|
||||||
|
@ -64,7 +65,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TSIsolate {
|
pub struct TSIsolate {
|
||||||
isolate: Box<CoreIsolate>,
|
isolate: CoreIsolate,
|
||||||
state: Arc<Mutex<TSState>>,
|
state: Arc<Mutex<TSState>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,11 +332,11 @@ pub fn trace_serializer() {
|
||||||
/// CoreIsolate.
|
/// CoreIsolate.
|
||||||
pub fn op_fetch_asset<S: ::std::hash::BuildHasher>(
|
pub fn op_fetch_asset<S: ::std::hash::BuildHasher>(
|
||||||
custom_assets: HashMap<String, PathBuf, S>,
|
custom_assets: HashMap<String, PathBuf, S>,
|
||||||
) -> impl Fn(&mut CoreIsolate, &[u8], Option<ZeroCopyBuf>) -> Op {
|
) -> impl Fn(&mut CoreIsolateState, &[u8], Option<ZeroCopyBuf>) -> Op {
|
||||||
for (_, path) in custom_assets.iter() {
|
for (_, path) in custom_assets.iter() {
|
||||||
println!("cargo:rerun-if-changed={}", path.display());
|
println!("cargo:rerun-if-changed={}", path.display());
|
||||||
}
|
}
|
||||||
move |_isolate: &mut CoreIsolate,
|
move |_state: &mut CoreIsolateState,
|
||||||
control: &[u8],
|
control: &[u8],
|
||||||
zero_copy_buf: Option<ZeroCopyBuf>|
|
zero_copy_buf: Option<ZeroCopyBuf>|
|
||||||
-> Op {
|
-> Op {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue