mirror of
https://github.com/denoland/deno.git
synced 2024-12-23 15:49:44 -05:00
feat(core): codegen ops (#13861)
Co-authored-by: Aaron O'Mullan <aaron.omullan@gmail.com>
This commit is contained in:
parent
4e3ed37037
commit
b4e42953e1
78 changed files with 1754 additions and 1664 deletions
21
Cargo.lock
generated
21
Cargo.lock
generated
|
@ -856,6 +856,7 @@ version = "0.122.0"
|
|||
dependencies = [
|
||||
"anyhow",
|
||||
"deno_ast",
|
||||
"deno_ops",
|
||||
"futures",
|
||||
"indexmap",
|
||||
"libc",
|
||||
|
@ -1019,6 +1020,16 @@ dependencies = [
|
|||
"trust-dns-resolver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deno_ops"
|
||||
version = "0.1.1"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2 1.0.36",
|
||||
"quote 1.0.14",
|
||||
"syn 1.0.85",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deno_runtime"
|
||||
version = "0.48.0"
|
||||
|
@ -2925,6 +2936,16 @@ dependencies = [
|
|||
"output_vt100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-crate"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
|
|
|
@ -6,6 +6,7 @@ members = [
|
|||
"bench_util",
|
||||
"cli",
|
||||
"core",
|
||||
"ops",
|
||||
"runtime",
|
||||
"serde_v8",
|
||||
"test_ffi",
|
||||
|
|
|
@ -3,11 +3,9 @@ use deno_bench_util::bencher::{benchmark_group, Bencher};
|
|||
use deno_bench_util::{bench_js_async, bench_js_sync};
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op_async;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::serialize_op_result;
|
||||
use deno_core::op;
|
||||
|
||||
use deno_core::Extension;
|
||||
use deno_core::Op;
|
||||
use deno_core::OpState;
|
||||
|
||||
use std::cell::RefCell;
|
||||
|
@ -16,17 +14,25 @@ use std::rc::Rc;
|
|||
fn setup() -> Vec<Extension> {
|
||||
vec![Extension::builder()
|
||||
.ops(vec![
|
||||
("pi_json", op_sync(|_, _: (), _: ()| Ok(314159))),
|
||||
("pi_async", op_async(op_pi_async)),
|
||||
(
|
||||
"nop",
|
||||
Box::new(|state, _| Op::Sync(serialize_op_result(Ok(9), state))),
|
||||
),
|
||||
op_pi_json::decl(),
|
||||
op_pi_async::decl(),
|
||||
op_nop::decl(),
|
||||
])
|
||||
.build()]
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_nop(_: &mut OpState, _: (), _: ()) -> Result<(), AnyError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_pi_json(_: &mut OpState, _: (), _: ()) -> Result<i64, AnyError> {
|
||||
Ok(314159)
|
||||
}
|
||||
|
||||
// this is a function since async closures aren't stable
|
||||
#[op]
|
||||
async fn op_pi_async(
|
||||
_: Rc<RefCell<OpState>>,
|
||||
_: (),
|
||||
|
@ -36,15 +42,15 @@ async fn op_pi_async(
|
|||
}
|
||||
|
||||
fn bench_op_pi_json(b: &mut Bencher) {
|
||||
bench_js_sync(b, r#"Deno.core.opSync("pi_json", null);"#, setup);
|
||||
bench_js_sync(b, r#"Deno.core.opSync("op_pi_json", null);"#, setup);
|
||||
}
|
||||
|
||||
fn bench_op_nop(b: &mut Bencher) {
|
||||
bench_js_sync(b, r#"Deno.core.opSync("nop", null, null, null);"#, setup);
|
||||
bench_js_sync(b, r#"Deno.core.opSync("op_nop", null, null, null);"#, setup);
|
||||
}
|
||||
|
||||
fn bench_op_async(b: &mut Bencher) {
|
||||
bench_js_async(b, r#"Deno.core.opAsync("pi_async", null);"#, setup);
|
||||
bench_js_async(b, r#"Deno.core.opAsync("op_pi_async", null);"#, setup);
|
||||
}
|
||||
|
||||
fn bench_is_proxy(b: &mut Bencher) {
|
||||
|
@ -58,4 +64,5 @@ benchmark_group!(
|
|||
bench_op_async,
|
||||
bench_is_proxy
|
||||
);
|
||||
|
||||
bench_or_profile!(benches);
|
||||
|
|
156
cli/build.rs
156
cli/build.rs
|
@ -1,11 +1,14 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use deno_core::error::custom_error;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op;
|
||||
use deno_core::serde::Deserialize;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_core::serde_json::Value;
|
||||
use deno_core::Extension;
|
||||
use deno_core::JsRuntime;
|
||||
use deno_core::OpState;
|
||||
use deno_core::RuntimeOptions;
|
||||
use regex::Regex;
|
||||
use std::collections::HashMap;
|
||||
|
@ -185,79 +188,112 @@ fn create_compiler_snapshot(
|
|||
build_libs.push(op_lib.to_owned());
|
||||
}
|
||||
|
||||
let re_asset = Regex::new(r"asset:/{3}lib\.(\S+)\.d\.ts").expect("bad regex");
|
||||
let build_specifier = "asset:///bootstrap.ts";
|
||||
#[op]
|
||||
fn op_build_info(
|
||||
state: &mut OpState,
|
||||
_args: Value,
|
||||
_: (),
|
||||
) -> Result<Value, AnyError> {
|
||||
let build_specifier = "asset:///bootstrap.ts";
|
||||
let build_libs = state.borrow::<Vec<&str>>();
|
||||
Ok(json!({
|
||||
"buildSpecifier": build_specifier,
|
||||
"libs": build_libs,
|
||||
}))
|
||||
}
|
||||
|
||||
let mut js_runtime = JsRuntime::new(RuntimeOptions {
|
||||
will_snapshot: true,
|
||||
..Default::default()
|
||||
});
|
||||
js_runtime.register_op(
|
||||
"op_build_info",
|
||||
op_sync(move |_state, _args: Value, _: ()| {
|
||||
Ok(json!({
|
||||
"buildSpecifier": build_specifier,
|
||||
"libs": build_libs,
|
||||
}))
|
||||
}),
|
||||
);
|
||||
js_runtime.register_op(
|
||||
"op_cwd",
|
||||
op_sync(move |_state, _args: Value, _: ()| Ok(json!("cache:///"))),
|
||||
);
|
||||
// As of TypeScript 4.5, it tries to detect the existence of substitute lib
|
||||
// files, which we currently don't use, so we just return false.
|
||||
js_runtime.register_op(
|
||||
"op_exists",
|
||||
op_sync(move |_state, _args: LoadArgs, _: ()| Ok(json!(false))),
|
||||
);
|
||||
#[op]
|
||||
fn op_cwd(
|
||||
_state: &mut OpState,
|
||||
_args: Value,
|
||||
_: (),
|
||||
) -> Result<Value, AnyError> {
|
||||
Ok(json!("cache:///"))
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_exists(
|
||||
_state: &mut OpState,
|
||||
_args: Value,
|
||||
_: (),
|
||||
) -> Result<Value, AnyError> {
|
||||
Ok(json!(false))
|
||||
}
|
||||
|
||||
#[op]
|
||||
// using the same op that is used in `tsc.rs` for loading modules and reading
|
||||
// files, but a slightly different implementation at build time.
|
||||
js_runtime.register_op(
|
||||
"op_load",
|
||||
op_sync(move |_state, args: LoadArgs, _: ()| {
|
||||
// we need a basic file to send to tsc to warm it up.
|
||||
if args.specifier == build_specifier {
|
||||
fn op_load(
|
||||
state: &mut OpState,
|
||||
args: LoadArgs,
|
||||
_: (),
|
||||
) -> Result<Value, AnyError> {
|
||||
let op_crate_libs = state.borrow::<HashMap<&str, &str>>();
|
||||
let path_dts = state.borrow::<PathBuf>();
|
||||
let re_asset =
|
||||
Regex::new(r"asset:/{3}lib\.(\S+)\.d\.ts").expect("bad regex");
|
||||
let build_specifier = "asset:///bootstrap.ts";
|
||||
|
||||
// we need a basic file to send to tsc to warm it up.
|
||||
if args.specifier == build_specifier {
|
||||
Ok(json!({
|
||||
"data": r#"console.log("hello deno!");"#,
|
||||
"hash": "1",
|
||||
// this corresponds to `ts.ScriptKind.TypeScript`
|
||||
"scriptKind": 3
|
||||
}))
|
||||
// specifiers come across as `asset:///lib.{lib_name}.d.ts` and we need to
|
||||
// parse out just the name so we can lookup the asset.
|
||||
} else if let Some(caps) = re_asset.captures(&args.specifier) {
|
||||
if let Some(lib) = caps.get(1).map(|m| m.as_str()) {
|
||||
// if it comes from an op crate, we were supplied with the path to the
|
||||
// file.
|
||||
let path = if let Some(op_crate_lib) = op_crate_libs.get(lib) {
|
||||
PathBuf::from(op_crate_lib).canonicalize().unwrap()
|
||||
// otherwise we are will generate the path ourself
|
||||
} else {
|
||||
path_dts.join(format!("lib.{}.d.ts", lib))
|
||||
};
|
||||
let data = std::fs::read_to_string(path)?;
|
||||
Ok(json!({
|
||||
"data": r#"console.log("hello deno!");"#,
|
||||
"data": data,
|
||||
"hash": "1",
|
||||
// this corresponds to `ts.ScriptKind.TypeScript`
|
||||
"scriptKind": 3
|
||||
}))
|
||||
// specifiers come across as `asset:///lib.{lib_name}.d.ts` and we need to
|
||||
// parse out just the name so we can lookup the asset.
|
||||
} else if let Some(caps) = re_asset.captures(&args.specifier) {
|
||||
if let Some(lib) = caps.get(1).map(|m| m.as_str()) {
|
||||
// if it comes from an op crate, we were supplied with the path to the
|
||||
// file.
|
||||
let path = if let Some(op_crate_lib) = op_crate_libs.get(lib) {
|
||||
PathBuf::from(op_crate_lib).canonicalize().unwrap()
|
||||
// otherwise we are will generate the path ourself
|
||||
} else {
|
||||
path_dts.join(format!("lib.{}.d.ts", lib))
|
||||
};
|
||||
let data = std::fs::read_to_string(path)?;
|
||||
Ok(json!({
|
||||
"data": data,
|
||||
"hash": "1",
|
||||
// this corresponds to `ts.ScriptKind.TypeScript`
|
||||
"scriptKind": 3
|
||||
}))
|
||||
} else {
|
||||
Err(custom_error(
|
||||
"InvalidSpecifier",
|
||||
format!("An invalid specifier was requested: {}", args.specifier),
|
||||
))
|
||||
}
|
||||
} else {
|
||||
Err(custom_error(
|
||||
"InvalidSpecifier",
|
||||
format!("An invalid specifier was requested: {}", args.specifier),
|
||||
))
|
||||
}
|
||||
}),
|
||||
);
|
||||
js_runtime.sync_ops_cache();
|
||||
} else {
|
||||
Err(custom_error(
|
||||
"InvalidSpecifier",
|
||||
format!("An invalid specifier was requested: {}", args.specifier),
|
||||
))
|
||||
}
|
||||
}
|
||||
let js_runtime = JsRuntime::new(RuntimeOptions {
|
||||
will_snapshot: true,
|
||||
extensions: vec![Extension::builder()
|
||||
.ops(vec![
|
||||
op_build_info::decl(),
|
||||
op_cwd::decl(),
|
||||
op_exists::decl(),
|
||||
op_load::decl(),
|
||||
])
|
||||
.state(move |state| {
|
||||
state.put(op_crate_libs.clone());
|
||||
state.put(build_libs.clone());
|
||||
state.put(path_dts.clone());
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.build()],
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
create_snapshot(js_runtime, snapshot_path, files);
|
||||
}
|
||||
|
||||
|
|
115
cli/lsp/tsc.rs
115
cli/lsp/tsc.rs
|
@ -27,7 +27,7 @@ use deno_core::anyhow::anyhow;
|
|||
use deno_core::error::custom_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::located_script_name;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::op;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::resolve_url;
|
||||
use deno_core::serde::de;
|
||||
|
@ -40,7 +40,7 @@ use deno_core::url::Url;
|
|||
use deno_core::Extension;
|
||||
use deno_core::JsRuntime;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::OpFn;
|
||||
use deno_core::OpState;
|
||||
use deno_core::RuntimeOptions;
|
||||
use deno_runtime::tokio_util::create_basic_runtime;
|
||||
use log::error;
|
||||
|
@ -2502,19 +2502,6 @@ fn normalize_specifier<S: AsRef<str>>(
|
|||
.map_err(|err| err.into())
|
||||
}
|
||||
|
||||
// buffer-less json_sync ops
|
||||
fn op_lsp<F, V, R>(op_fn: F) -> Box<OpFn>
|
||||
where
|
||||
F: Fn(&mut State, V) -> Result<R, AnyError> + 'static,
|
||||
V: de::DeserializeOwned,
|
||||
R: Serialize + 'static,
|
||||
{
|
||||
op_sync(move |s, args, _: ()| {
|
||||
let state = s.borrow_mut::<State>();
|
||||
op_fn(state, args)
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct SourceSnapshotArgs {
|
||||
|
@ -2524,10 +2511,13 @@ struct SourceSnapshotArgs {
|
|||
|
||||
/// The language service is dropping a reference to a source file snapshot, and
|
||||
/// we can drop our version of that document.
|
||||
#[op]
|
||||
fn op_dispose(
|
||||
state: &mut State,
|
||||
state: &mut OpState,
|
||||
args: SourceSnapshotArgs,
|
||||
_: (),
|
||||
) -> Result<bool, AnyError> {
|
||||
let state = state.borrow_mut::<State>();
|
||||
let mark = state.performance.mark("op_dispose", Some(&args));
|
||||
let specifier = state.normalize_specifier(&args.specifier)?;
|
||||
state.snapshots.remove(&(specifier, args.version.into()));
|
||||
|
@ -2541,7 +2531,13 @@ struct SpecifierArgs {
|
|||
specifier: String,
|
||||
}
|
||||
|
||||
fn op_exists(state: &mut State, args: SpecifierArgs) -> Result<bool, AnyError> {
|
||||
#[op]
|
||||
fn op_exists(
|
||||
state: &mut OpState,
|
||||
args: SpecifierArgs,
|
||||
_: (),
|
||||
) -> Result<bool, AnyError> {
|
||||
let state = state.borrow_mut::<State>();
|
||||
// we don't measure the performance of op_exists anymore because as of TS 4.5
|
||||
// it is noisy with all the checking for custom libs, that we can't see the
|
||||
// forrest for the trees as well as it compounds any lsp performance
|
||||
|
@ -2569,10 +2565,13 @@ struct GetChangeRangeArgs {
|
|||
|
||||
/// The language service wants to compare an old snapshot with a new snapshot to
|
||||
/// determine what source has changed.
|
||||
#[op]
|
||||
fn op_get_change_range(
|
||||
state: &mut State,
|
||||
state: &mut OpState,
|
||||
args: GetChangeRangeArgs,
|
||||
_: (),
|
||||
) -> Result<Value, AnyError> {
|
||||
let state = state.borrow_mut::<State>();
|
||||
let mark = state.performance.mark("op_get_change_range", Some(&args));
|
||||
let specifier = state.normalize_specifier(&args.specifier)?;
|
||||
cache_snapshot(state, &specifier, args.version.clone())?;
|
||||
|
@ -2613,10 +2612,13 @@ fn op_get_change_range(
|
|||
r
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_get_length(
|
||||
state: &mut State,
|
||||
state: &mut OpState,
|
||||
args: SourceSnapshotArgs,
|
||||
_: (),
|
||||
) -> Result<usize, AnyError> {
|
||||
let state = state.borrow_mut::<State>();
|
||||
let mark = state.performance.mark("op_get_length", Some(&args));
|
||||
let specifier = state.normalize_specifier(args.specifier)?;
|
||||
let r = if let Some(Some(asset)) =
|
||||
|
@ -2644,10 +2646,13 @@ struct GetTextArgs {
|
|||
end: usize,
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_get_text(
|
||||
state: &mut State,
|
||||
state: &mut OpState,
|
||||
args: GetTextArgs,
|
||||
_: (),
|
||||
) -> Result<String, AnyError> {
|
||||
let state = state.borrow_mut::<State>();
|
||||
let mark = state.performance.mark("op_get_text", Some(&args));
|
||||
let specifier = state.normalize_specifier(args.specifier)?;
|
||||
let maybe_asset = state.state_snapshot.assets.get_cached(&specifier);
|
||||
|
@ -2664,14 +2669,23 @@ fn op_get_text(
|
|||
Ok(text::slice(content, args.start..args.end).to_string())
|
||||
}
|
||||
|
||||
fn op_is_cancelled(state: &mut State, _: ()) -> Result<bool, AnyError> {
|
||||
#[op]
|
||||
fn op_is_cancelled(
|
||||
state: &mut OpState,
|
||||
_: (),
|
||||
_: (),
|
||||
) -> Result<bool, AnyError> {
|
||||
let state = state.borrow_mut::<State>();
|
||||
Ok(state.token.is_cancelled())
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_load(
|
||||
state: &mut State,
|
||||
state: &mut OpState,
|
||||
args: SpecifierArgs,
|
||||
_: (),
|
||||
) -> Result<Option<String>, AnyError> {
|
||||
let state = state.borrow_mut::<State>();
|
||||
let mark = state.performance.mark("op_load", Some(&args));
|
||||
let specifier = state.normalize_specifier(args.specifier)?;
|
||||
let document = state.state_snapshot.documents.get(&specifier);
|
||||
|
@ -2679,10 +2693,13 @@ fn op_load(
|
|||
Ok(document.map(|d| d.content().to_string()))
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_resolve(
|
||||
state: &mut State,
|
||||
state: &mut OpState,
|
||||
args: ResolveArgs,
|
||||
_: (),
|
||||
) -> Result<Vec<Option<(String, String)>>, AnyError> {
|
||||
let state = state.borrow_mut::<State>();
|
||||
let mark = state.performance.mark("op_resolve", Some(&args));
|
||||
let referrer = state.normalize_specifier(&args.base)?;
|
||||
|
||||
|
@ -2713,15 +2730,24 @@ fn op_resolve(
|
|||
result
|
||||
}
|
||||
|
||||
fn op_respond(state: &mut State, args: Response) -> Result<bool, AnyError> {
|
||||
#[op]
|
||||
fn op_respond(
|
||||
state: &mut OpState,
|
||||
args: Response,
|
||||
_: (),
|
||||
) -> Result<bool, AnyError> {
|
||||
let state = state.borrow_mut::<State>();
|
||||
state.response = Some(args);
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_script_names(
|
||||
state: &mut State,
|
||||
state: &mut OpState,
|
||||
_args: Value,
|
||||
_: (),
|
||||
) -> Result<Vec<ModuleSpecifier>, AnyError> {
|
||||
let state = state.borrow_mut::<State>();
|
||||
Ok(
|
||||
state
|
||||
.state_snapshot
|
||||
|
@ -2739,10 +2765,13 @@ struct ScriptVersionArgs {
|
|||
specifier: String,
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_script_version(
|
||||
state: &mut State,
|
||||
state: &mut OpState,
|
||||
args: ScriptVersionArgs,
|
||||
_: (),
|
||||
) -> Result<Option<String>, AnyError> {
|
||||
let state = state.borrow_mut::<State>();
|
||||
// this op is very "noisy" and measuring its performance is not useful, so we
|
||||
// don't measure it uniquely anymore.
|
||||
let specifier = state.normalize_specifier(args.specifier)?;
|
||||
|
@ -2776,17 +2805,17 @@ fn js_runtime(performance: Arc<Performance>) -> JsRuntime {
|
|||
fn init_extension(performance: Arc<Performance>) -> Extension {
|
||||
Extension::builder()
|
||||
.ops(vec![
|
||||
("op_dispose", op_lsp(op_dispose)),
|
||||
("op_exists", op_lsp(op_exists)),
|
||||
("op_get_change_range", op_lsp(op_get_change_range)),
|
||||
("op_get_length", op_lsp(op_get_length)),
|
||||
("op_get_text", op_lsp(op_get_text)),
|
||||
("op_is_cancelled", op_lsp(op_is_cancelled)),
|
||||
("op_load", op_lsp(op_load)),
|
||||
("op_resolve", op_lsp(op_resolve)),
|
||||
("op_respond", op_lsp(op_respond)),
|
||||
("op_script_names", op_lsp(op_script_names)),
|
||||
("op_script_version", op_lsp(op_script_version)),
|
||||
op_dispose::decl(),
|
||||
op_exists::decl(),
|
||||
op_get_change_range::decl(),
|
||||
op_get_length::decl(),
|
||||
op_get_text::decl(),
|
||||
op_is_cancelled::decl(),
|
||||
op_load::decl(),
|
||||
op_resolve::decl(),
|
||||
op_respond::decl(),
|
||||
op_script_names::decl(),
|
||||
op_script_version::decl(),
|
||||
])
|
||||
.state(move |state| {
|
||||
state.put(State::new(
|
||||
|
@ -3832,7 +3861,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_op_exists() {
|
||||
let (_, state_snapshot, _) = setup(
|
||||
let (mut rt, state_snapshot, _) = setup(
|
||||
false,
|
||||
json!({
|
||||
"target": "esnext",
|
||||
|
@ -3843,12 +3872,16 @@ mod tests {
|
|||
&[],
|
||||
);
|
||||
let performance = Arc::new(Performance::default());
|
||||
let mut state = State::new(state_snapshot, performance);
|
||||
let actual = op_exists(
|
||||
&mut state,
|
||||
let state = State::new(state_snapshot, performance);
|
||||
let op_state = rt.op_state();
|
||||
let mut op_state = op_state.borrow_mut();
|
||||
op_state.put(state);
|
||||
let actual = op_exists::call(
|
||||
&mut op_state,
|
||||
SpecifierArgs {
|
||||
specifier: "/error/unknown:something/index.d.ts".to_string(),
|
||||
},
|
||||
(),
|
||||
);
|
||||
assert!(actual.is_ok());
|
||||
let actual = actual.unwrap();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::tools::bench::BenchEvent;
|
||||
use deno_core::error::generic_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::op;
|
||||
use deno_core::Extension;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::OpState;
|
||||
|
@ -15,17 +15,11 @@ use uuid::Uuid;
|
|||
pub fn init(sender: UnboundedSender<BenchEvent>) -> Extension {
|
||||
Extension::builder()
|
||||
.ops(vec![
|
||||
(
|
||||
"op_pledge_test_permissions",
|
||||
op_sync(op_pledge_test_permissions),
|
||||
),
|
||||
(
|
||||
"op_restore_test_permissions",
|
||||
op_sync(op_restore_test_permissions),
|
||||
),
|
||||
("op_get_bench_origin", op_sync(op_get_bench_origin)),
|
||||
("op_dispatch_bench_event", op_sync(op_dispatch_bench_event)),
|
||||
("op_bench_now", op_sync(op_bench_now)),
|
||||
op_pledge_test_permissions::decl(),
|
||||
op_restore_test_permissions::decl(),
|
||||
op_get_bench_origin::decl(),
|
||||
op_dispatch_bench_event::decl(),
|
||||
op_bench_now::decl(),
|
||||
])
|
||||
.state(move |state| {
|
||||
state.put(sender.clone());
|
||||
|
@ -37,6 +31,7 @@ pub fn init(sender: UnboundedSender<BenchEvent>) -> Extension {
|
|||
#[derive(Clone)]
|
||||
struct PermissionsHolder(Uuid, Permissions);
|
||||
|
||||
#[op]
|
||||
pub fn op_pledge_test_permissions(
|
||||
state: &mut OpState,
|
||||
args: ChildPermissionsArg,
|
||||
|
@ -55,6 +50,7 @@ pub fn op_pledge_test_permissions(
|
|||
Ok(token)
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_restore_test_permissions(
|
||||
state: &mut OpState,
|
||||
token: Uuid,
|
||||
|
@ -73,6 +69,7 @@ pub fn op_restore_test_permissions(
|
|||
}
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_get_bench_origin(
|
||||
state: &mut OpState,
|
||||
_: (),
|
||||
|
@ -81,6 +78,7 @@ fn op_get_bench_origin(
|
|||
Ok(state.borrow::<ModuleSpecifier>().to_string())
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_dispatch_bench_event(
|
||||
state: &mut OpState,
|
||||
event: BenchEvent,
|
||||
|
@ -92,6 +90,7 @@ fn op_dispatch_bench_event(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_bench_now(state: &mut OpState, _: (), _: ()) -> Result<u64, AnyError> {
|
||||
let ns = state.borrow::<time::Instant>().elapsed().as_nanos();
|
||||
let ns_u64 = u64::try_from(ns)?;
|
||||
|
|
|
@ -6,7 +6,7 @@ use crate::proc_state::ProcState;
|
|||
use crate::source_maps::get_orig_position;
|
||||
use crate::source_maps::CachedMaps;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::op;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_core::serde_json::Value;
|
||||
|
@ -19,9 +19,9 @@ use std::collections::HashMap;
|
|||
pub fn init() -> Extension {
|
||||
Extension::builder()
|
||||
.ops(vec![
|
||||
("op_apply_source_map", op_sync(op_apply_source_map)),
|
||||
("op_format_diagnostic", op_sync(op_format_diagnostic)),
|
||||
("op_format_file_name", op_sync(op_format_file_name)),
|
||||
op_apply_source_map::decl(),
|
||||
op_format_diagnostic::decl(),
|
||||
op_format_file_name::decl(),
|
||||
])
|
||||
.build()
|
||||
}
|
||||
|
@ -42,6 +42,7 @@ struct AppliedSourceMap {
|
|||
column_number: u32,
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_apply_source_map(
|
||||
state: &mut OpState,
|
||||
args: ApplySourceMap,
|
||||
|
@ -66,6 +67,7 @@ fn op_apply_source_map(
|
|||
})
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_format_diagnostic(
|
||||
_state: &mut OpState,
|
||||
args: Value,
|
||||
|
@ -75,6 +77,7 @@ fn op_format_diagnostic(
|
|||
Ok(json!(diagnostic.to_string()))
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_format_file_name(
|
||||
_state: &mut OpState,
|
||||
file_name: String,
|
||||
|
|
|
@ -16,7 +16,8 @@ use deno_core::anyhow::Context;
|
|||
use deno_core::error::custom_error;
|
||||
use deno_core::error::generic_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op_async;
|
||||
|
||||
use deno_core::op;
|
||||
use deno_core::parking_lot::RwLock;
|
||||
use deno_core::resolve_url_or_path;
|
||||
use deno_core::serde_json;
|
||||
|
@ -35,9 +36,7 @@ use std::rc::Rc;
|
|||
use std::sync::Arc;
|
||||
|
||||
pub fn init() -> Extension {
|
||||
Extension::builder()
|
||||
.ops(vec![("op_emit", op_async(op_emit))])
|
||||
.build()
|
||||
Extension::builder().ops(vec![op_emit::decl()]).build()
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
|
@ -141,6 +140,7 @@ fn to_maybe_jsx_import_source_module(
|
|||
}
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_emit(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: EmitArgs,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::tools::test::TestEvent;
|
||||
use deno_core::error::generic_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::op;
|
||||
use deno_core::Extension;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::OpState;
|
||||
|
@ -14,16 +14,10 @@ use uuid::Uuid;
|
|||
pub fn init(sender: UnboundedSender<TestEvent>) -> Extension {
|
||||
Extension::builder()
|
||||
.ops(vec![
|
||||
(
|
||||
"op_pledge_test_permissions",
|
||||
op_sync(op_pledge_test_permissions),
|
||||
),
|
||||
(
|
||||
"op_restore_test_permissions",
|
||||
op_sync(op_restore_test_permissions),
|
||||
),
|
||||
("op_get_test_origin", op_sync(op_get_test_origin)),
|
||||
("op_dispatch_test_event", op_sync(op_dispatch_test_event)),
|
||||
op_pledge_test_permissions::decl(),
|
||||
op_restore_test_permissions::decl(),
|
||||
op_get_test_origin::decl(),
|
||||
op_dispatch_test_event::decl(),
|
||||
])
|
||||
.state(move |state| {
|
||||
state.put(sender.clone());
|
||||
|
@ -35,6 +29,7 @@ pub fn init(sender: UnboundedSender<TestEvent>) -> Extension {
|
|||
#[derive(Clone)]
|
||||
struct PermissionsHolder(Uuid, Permissions);
|
||||
|
||||
#[op]
|
||||
pub fn op_pledge_test_permissions(
|
||||
state: &mut OpState,
|
||||
args: ChildPermissionsArg,
|
||||
|
@ -53,6 +48,7 @@ pub fn op_pledge_test_permissions(
|
|||
Ok(token)
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_restore_test_permissions(
|
||||
state: &mut OpState,
|
||||
token: Uuid,
|
||||
|
@ -71,6 +67,7 @@ pub fn op_restore_test_permissions(
|
|||
}
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_get_test_origin(
|
||||
state: &mut OpState,
|
||||
_: (),
|
||||
|
@ -79,6 +76,7 @@ fn op_get_test_origin(
|
|||
Ok(state.borrow::<ModuleSpecifier>().to_string())
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_dispatch_test_event(
|
||||
state: &mut OpState,
|
||||
event: TestEvent,
|
||||
|
|
183
cli/tsc.rs
183
cli/tsc.rs
|
@ -11,18 +11,18 @@ use deno_core::anyhow::anyhow;
|
|||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::located_script_name;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::op;
|
||||
use deno_core::parking_lot::RwLock;
|
||||
use deno_core::resolve_url_or_path;
|
||||
use deno_core::serde::de;
|
||||
use deno_core::serde::Deserialize;
|
||||
use deno_core::serde::Serialize;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_core::serde_json::Value;
|
||||
use deno_core::Extension;
|
||||
use deno_core::JsRuntime;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::OpFn;
|
||||
use deno_core::OpState;
|
||||
use deno_core::RuntimeOptions;
|
||||
use deno_core::Snapshot;
|
||||
use deno_graph::Resolved;
|
||||
|
@ -298,18 +298,6 @@ fn normalize_specifier(specifier: &str) -> Result<ModuleSpecifier, AnyError> {
|
|||
.map_err(|err| err.into())
|
||||
}
|
||||
|
||||
fn op<F, V, R>(op_fn: F) -> Box<OpFn>
|
||||
where
|
||||
F: Fn(&mut State, V) -> Result<R, AnyError> + 'static,
|
||||
V: de::DeserializeOwned,
|
||||
R: Serialize + 'static,
|
||||
{
|
||||
op_sync(move |s, args, _: ()| {
|
||||
let state = s.borrow_mut::<State>();
|
||||
op_fn(state, args)
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct CreateHashArgs {
|
||||
|
@ -318,7 +306,13 @@ struct CreateHashArgs {
|
|||
data: String,
|
||||
}
|
||||
|
||||
fn op_create_hash(state: &mut State, args: Value) -> Result<Value, AnyError> {
|
||||
#[op]
|
||||
fn op_create_hash(
|
||||
s: &mut OpState,
|
||||
args: Value,
|
||||
_: (),
|
||||
) -> Result<Value, AnyError> {
|
||||
let state = s.borrow_mut::<State>();
|
||||
let v: CreateHashArgs = serde_json::from_value(args)
|
||||
.context("Invalid request from JavaScript for \"op_create_hash\".")?;
|
||||
let mut data = vec![v.data.as_bytes().to_owned()];
|
||||
|
@ -327,7 +321,9 @@ fn op_create_hash(state: &mut State, args: Value) -> Result<Value, AnyError> {
|
|||
Ok(json!({ "hash": hash }))
|
||||
}
|
||||
|
||||
fn op_cwd(state: &mut State, _args: Value) -> Result<String, AnyError> {
|
||||
#[op]
|
||||
fn op_cwd(s: &mut OpState, _args: Value, _: ()) -> Result<String, AnyError> {
|
||||
let state = s.borrow_mut::<State>();
|
||||
if let Some(config_specifier) = &state.maybe_config_specifier {
|
||||
let cwd = config_specifier.join("./")?;
|
||||
Ok(cwd.to_string())
|
||||
|
@ -350,7 +346,13 @@ struct EmitArgs {
|
|||
maybe_specifiers: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
fn op_emit(state: &mut State, args: EmitArgs) -> Result<Value, AnyError> {
|
||||
#[op]
|
||||
fn op_emit(
|
||||
state: &mut OpState,
|
||||
args: EmitArgs,
|
||||
_: (),
|
||||
) -> Result<Value, AnyError> {
|
||||
let state = state.borrow_mut::<State>();
|
||||
match args.file_name.as_ref() {
|
||||
"deno:///.tsbuildinfo" => state.maybe_tsbuildinfo = Some(args.data),
|
||||
_ => {
|
||||
|
@ -403,7 +405,13 @@ struct ExistsArgs {
|
|||
specifier: String,
|
||||
}
|
||||
|
||||
fn op_exists(state: &mut State, args: ExistsArgs) -> Result<bool, AnyError> {
|
||||
#[op]
|
||||
fn op_exists(
|
||||
state: &mut OpState,
|
||||
args: ExistsArgs,
|
||||
_: (),
|
||||
) -> Result<bool, AnyError> {
|
||||
let state = state.borrow_mut::<State>();
|
||||
let graph_data = state.graph_data.read();
|
||||
if let Ok(specifier) = normalize_specifier(&args.specifier) {
|
||||
if specifier.scheme() == "asset" || specifier.scheme() == "data" {
|
||||
|
@ -443,7 +451,9 @@ fn as_ts_script_kind(media_type: &MediaType) -> i32 {
|
|||
}
|
||||
}
|
||||
|
||||
fn op_load(state: &mut State, args: Value) -> Result<Value, AnyError> {
|
||||
#[op]
|
||||
fn op_load(state: &mut OpState, args: Value, _: ()) -> Result<Value, AnyError> {
|
||||
let state = state.borrow_mut::<State>();
|
||||
let v: LoadArgs = serde_json::from_value(args)
|
||||
.context("Invalid request from JavaScript for \"op_load\".")?;
|
||||
let specifier = normalize_specifier(&v.specifier)
|
||||
|
@ -507,7 +517,13 @@ pub struct ResolveArgs {
|
|||
pub specifiers: Vec<String>,
|
||||
}
|
||||
|
||||
fn op_resolve(state: &mut State, args: ResolveArgs) -> Result<Value, AnyError> {
|
||||
#[op]
|
||||
fn op_resolve(
|
||||
state: &mut OpState,
|
||||
args: ResolveArgs,
|
||||
_: (),
|
||||
) -> Result<Value, AnyError> {
|
||||
let state = state.borrow_mut::<State>();
|
||||
let mut resolved: Vec<(String, String)> = Vec::new();
|
||||
let referrer = if let Some(remapped_specifier) =
|
||||
state.remapped_specifiers.get(&args.base)
|
||||
|
@ -612,7 +628,13 @@ struct RespondArgs {
|
|||
pub stats: emit::Stats,
|
||||
}
|
||||
|
||||
fn op_respond(state: &mut State, args: Value) -> Result<Value, AnyError> {
|
||||
#[op]
|
||||
fn op_respond(
|
||||
state: &mut OpState,
|
||||
args: Value,
|
||||
_: (),
|
||||
) -> Result<Value, AnyError> {
|
||||
let state = state.borrow_mut::<State>();
|
||||
let v: RespondArgs = serde_json::from_value(args)
|
||||
.context("Error converting the result for \"op_respond\".")?;
|
||||
state.maybe_response = Some(v);
|
||||
|
@ -623,10 +645,6 @@ fn op_respond(state: &mut State, args: Value) -> Result<Value, AnyError> {
|
|||
/// contains information, like any emitted files, diagnostics, statistics and
|
||||
/// optionally an updated TypeScript build info.
|
||||
pub(crate) fn exec(request: Request) -> Result<Response, AnyError> {
|
||||
let mut runtime = JsRuntime::new(RuntimeOptions {
|
||||
startup_snapshot: Some(compiler_snapshot()),
|
||||
..Default::default()
|
||||
});
|
||||
// tsc cannot handle root specifiers that don't have one of the "acceptable"
|
||||
// extensions. Therefore, we have to check the root modules against their
|
||||
// extensions and remap any that are unacceptable to tsc and add them to the
|
||||
|
@ -654,28 +672,32 @@ pub(crate) fn exec(request: Request) -> Result<Response, AnyError> {
|
|||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
{
|
||||
let op_state = runtime.op_state();
|
||||
let mut op_state = op_state.borrow_mut();
|
||||
op_state.put(State::new(
|
||||
request.graph_data,
|
||||
request.hash_data.clone(),
|
||||
request.maybe_config_specifier.clone(),
|
||||
request.maybe_tsbuildinfo.clone(),
|
||||
root_map,
|
||||
remapped_specifiers,
|
||||
));
|
||||
}
|
||||
|
||||
runtime.register_op("op_cwd", op(op_cwd));
|
||||
runtime.register_op("op_create_hash", op(op_create_hash));
|
||||
runtime.register_op("op_emit", op(op_emit));
|
||||
runtime.register_op("op_exists", op(op_exists));
|
||||
runtime.register_op("op_load", op(op_load));
|
||||
runtime.register_op("op_resolve", op(op_resolve));
|
||||
runtime.register_op("op_respond", op(op_respond));
|
||||
runtime.sync_ops_cache();
|
||||
let mut runtime = JsRuntime::new(RuntimeOptions {
|
||||
startup_snapshot: Some(compiler_snapshot()),
|
||||
extensions: vec![Extension::builder()
|
||||
.ops(vec![
|
||||
op_cwd::decl(),
|
||||
op_create_hash::decl(),
|
||||
op_emit::decl(),
|
||||
op_exists::decl(),
|
||||
op_load::decl(),
|
||||
op_resolve::decl(),
|
||||
op_respond::decl(),
|
||||
])
|
||||
.state(move |state| {
|
||||
state.put(State::new(
|
||||
request.graph_data.clone(),
|
||||
request.hash_data.clone(),
|
||||
request.maybe_config_specifier.clone(),
|
||||
request.maybe_tsbuildinfo.clone(),
|
||||
root_map.clone(),
|
||||
remapped_specifiers.clone(),
|
||||
));
|
||||
Ok(())
|
||||
})
|
||||
.build()],
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
let startup_source = "globalThis.startup({ legacyFlag: false })";
|
||||
let request_value = json!({
|
||||
|
@ -720,6 +742,7 @@ mod tests {
|
|||
use crate::diagnostics::DiagnosticCategory;
|
||||
use crate::emit::Stats;
|
||||
use deno_core::futures::future;
|
||||
use deno_core::OpState;
|
||||
use deno_graph::ModuleKind;
|
||||
use std::fs;
|
||||
|
||||
|
@ -757,7 +780,7 @@ mod tests {
|
|||
maybe_specifier: Option<ModuleSpecifier>,
|
||||
maybe_hash_data: Option<Vec<Vec<u8>>>,
|
||||
maybe_tsbuildinfo: Option<String>,
|
||||
) -> State {
|
||||
) -> OpState {
|
||||
let specifier = maybe_specifier
|
||||
.unwrap_or_else(|| resolve_url_or_path("file:///main.ts").unwrap());
|
||||
let hash_data = maybe_hash_data.unwrap_or_else(|| vec![b"".to_vec()]);
|
||||
|
@ -774,14 +797,17 @@ mod tests {
|
|||
None,
|
||||
)
|
||||
.await;
|
||||
State::new(
|
||||
let state = State::new(
|
||||
Arc::new(RwLock::new((&graph).into())),
|
||||
hash_data,
|
||||
None,
|
||||
maybe_tsbuildinfo,
|
||||
HashMap::new(),
|
||||
HashMap::new(),
|
||||
)
|
||||
);
|
||||
let mut op_state = OpState::new(1);
|
||||
op_state.put(state);
|
||||
op_state
|
||||
}
|
||||
|
||||
async fn test_exec(
|
||||
|
@ -852,9 +878,12 @@ mod tests {
|
|||
#[tokio::test]
|
||||
async fn test_create_hash() {
|
||||
let mut state = setup(None, Some(vec![b"something".to_vec()]), None).await;
|
||||
let actual =
|
||||
op_create_hash(&mut state, json!({ "data": "some sort of content" }))
|
||||
.expect("could not invoke op");
|
||||
let actual = op_create_hash::call(
|
||||
&mut state,
|
||||
json!({ "data": "some sort of content" }),
|
||||
(),
|
||||
)
|
||||
.expect("could not invoke op");
|
||||
assert_eq!(
|
||||
actual,
|
||||
json!({"hash": "ae92df8f104748768838916857a1623b6a3c593110131b0a00f81ad9dac16511"})
|
||||
|
@ -898,16 +927,18 @@ mod tests {
|
|||
#[tokio::test]
|
||||
async fn test_emit() {
|
||||
let mut state = setup(None, None, None).await;
|
||||
let actual = op_emit(
|
||||
let actual = op_emit::call(
|
||||
&mut state,
|
||||
EmitArgs {
|
||||
data: "some file content".to_string(),
|
||||
file_name: "cache:///some/file.js".to_string(),
|
||||
maybe_specifiers: Some(vec!["file:///some/file.ts".to_string()]),
|
||||
},
|
||||
(),
|
||||
)
|
||||
.expect("should have invoked op");
|
||||
assert_eq!(actual, json!(true));
|
||||
let state = state.borrow::<State>();
|
||||
assert_eq!(state.emitted_files.len(), 1);
|
||||
assert!(state.maybe_tsbuildinfo.is_none());
|
||||
assert_eq!(
|
||||
|
@ -926,7 +957,7 @@ mod tests {
|
|||
#[tokio::test]
|
||||
async fn test_emit_strange_specifier() {
|
||||
let mut state = setup(None, None, None).await;
|
||||
let actual = op_emit(
|
||||
let actual = op_emit::call(
|
||||
&mut state,
|
||||
EmitArgs {
|
||||
data: "some file content".to_string(),
|
||||
|
@ -935,9 +966,11 @@ mod tests {
|
|||
vec!["file:///some/file.ts?q=.json".to_string()],
|
||||
),
|
||||
},
|
||||
(),
|
||||
)
|
||||
.expect("should have invoked op");
|
||||
assert_eq!(actual, json!(true));
|
||||
let state = state.borrow::<State>();
|
||||
assert_eq!(state.emitted_files.len(), 1);
|
||||
assert!(state.maybe_tsbuildinfo.is_none());
|
||||
assert_eq!(
|
||||
|
@ -956,16 +989,18 @@ mod tests {
|
|||
#[tokio::test]
|
||||
async fn test_emit_tsbuildinfo() {
|
||||
let mut state = setup(None, None, None).await;
|
||||
let actual = op_emit(
|
||||
let actual = op_emit::call(
|
||||
&mut state,
|
||||
EmitArgs {
|
||||
data: "some file content".to_string(),
|
||||
file_name: "deno:///.tsbuildinfo".to_string(),
|
||||
maybe_specifiers: None,
|
||||
},
|
||||
(),
|
||||
)
|
||||
.expect("should have invoked op");
|
||||
assert_eq!(actual, json!(true));
|
||||
let state = state.borrow::<State>();
|
||||
assert_eq!(state.emitted_files.len(), 0);
|
||||
assert_eq!(
|
||||
state.maybe_tsbuildinfo,
|
||||
|
@ -981,9 +1016,10 @@ mod tests {
|
|||
Some("some content".to_string()),
|
||||
)
|
||||
.await;
|
||||
let actual = op_load(
|
||||
let actual = op_load::call(
|
||||
&mut state,
|
||||
json!({ "specifier": "https://deno.land/x/mod.ts"}),
|
||||
(),
|
||||
)
|
||||
.expect("should have invoked op");
|
||||
assert_eq!(
|
||||
|
@ -1012,9 +1048,12 @@ mod tests {
|
|||
Some("some content".to_string()),
|
||||
)
|
||||
.await;
|
||||
let value =
|
||||
op_load(&mut state, json!({ "specifier": "asset:///lib.dom.d.ts" }))
|
||||
.expect("should have invoked op");
|
||||
let value = op_load::call(
|
||||
&mut state,
|
||||
json!({ "specifier": "asset:///lib.dom.d.ts" }),
|
||||
(),
|
||||
)
|
||||
.expect("should have invoked op");
|
||||
let actual: LoadResponse =
|
||||
serde_json::from_value(value).expect("failed to deserialize");
|
||||
let expected = get_asset("lib.dom.d.ts").unwrap();
|
||||
|
@ -1031,9 +1070,12 @@ mod tests {
|
|||
Some("some content".to_string()),
|
||||
)
|
||||
.await;
|
||||
let actual =
|
||||
op_load(&mut state, json!({ "specifier": "deno:///.tsbuildinfo"}))
|
||||
.expect("should have invoked op");
|
||||
let actual = op_load::call(
|
||||
&mut state,
|
||||
json!({ "specifier": "deno:///.tsbuildinfo"}),
|
||||
(),
|
||||
)
|
||||
.expect("should have invoked op");
|
||||
assert_eq!(
|
||||
actual,
|
||||
json!({
|
||||
|
@ -1047,9 +1089,10 @@ mod tests {
|
|||
#[tokio::test]
|
||||
async fn test_load_missing_specifier() {
|
||||
let mut state = setup(None, None, None).await;
|
||||
let actual = op_load(
|
||||
let actual = op_load::call(
|
||||
&mut state,
|
||||
json!({ "specifier": "https://deno.land/x/mod.ts"}),
|
||||
(),
|
||||
)
|
||||
.expect("should have invoked op");
|
||||
assert_eq!(
|
||||
|
@ -1070,12 +1113,13 @@ mod tests {
|
|||
None,
|
||||
)
|
||||
.await;
|
||||
let actual = op_resolve(
|
||||
let actual = op_resolve::call(
|
||||
&mut state,
|
||||
ResolveArgs {
|
||||
base: "https://deno.land/x/a.ts".to_string(),
|
||||
specifiers: vec!["./b.ts".to_string()],
|
||||
},
|
||||
(),
|
||||
)
|
||||
.expect("should have invoked op");
|
||||
assert_eq!(actual, json!([["https://deno.land/x/b.ts", ".ts"]]));
|
||||
|
@ -1089,12 +1133,13 @@ mod tests {
|
|||
None,
|
||||
)
|
||||
.await;
|
||||
let actual = op_resolve(
|
||||
let actual = op_resolve::call(
|
||||
&mut state,
|
||||
ResolveArgs {
|
||||
base: "https://deno.land/x/a.ts".to_string(),
|
||||
specifiers: vec!["./bad.ts".to_string()],
|
||||
},
|
||||
(),
|
||||
)
|
||||
.expect("should have not errored");
|
||||
assert_eq!(
|
||||
|
@ -1106,7 +1151,7 @@ mod tests {
|
|||
#[tokio::test]
|
||||
async fn test_respond() {
|
||||
let mut state = setup(None, None, None).await;
|
||||
let actual = op_respond(
|
||||
let actual = op_respond::call(
|
||||
&mut state,
|
||||
json!({
|
||||
"diagnostics": [
|
||||
|
@ -1118,9 +1163,11 @@ mod tests {
|
|||
],
|
||||
"stats": [["a", 12]]
|
||||
}),
|
||||
(),
|
||||
)
|
||||
.expect("should have invoked op");
|
||||
assert_eq!(actual, json!(true));
|
||||
let state = state.borrow::<State>();
|
||||
assert_eq!(
|
||||
state.maybe_response,
|
||||
Some(RespondArgs {
|
||||
|
|
|
@ -921,6 +921,7 @@ delete Object.prototype.__proto__;
|
|||
// A build time only op that provides some setup information that is used to
|
||||
// ensure the snapshot is setup properly.
|
||||
/** @type {{ buildSpecifier: string; libs: string[] }} */
|
||||
|
||||
const { buildSpecifier, libs } = core.opSync("op_build_info", {});
|
||||
for (const lib of libs) {
|
||||
const specifier = `lib.${lib}.d.ts`;
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
ErrorCaptureStackTrace,
|
||||
Promise,
|
||||
ObjectEntries,
|
||||
ObjectFreeze,
|
||||
ObjectFromEntries,
|
||||
MapPrototypeGet,
|
||||
MapPrototypeDelete,
|
||||
|
@ -27,11 +26,12 @@
|
|||
ObjectAssign,
|
||||
SymbolFor,
|
||||
} = window.__bootstrap.primordials;
|
||||
const ops = window.Deno.core.ops;
|
||||
const opIds = Object.keys(ops).reduce((a, v, i) => ({ ...a, [v]: i }), {});
|
||||
|
||||
// Available on start due to bindings.
|
||||
const { opcallSync, opcallAsync, refOp_, unrefOp_ } = window.Deno.core;
|
||||
const { refOp_, unrefOp_ } = window.Deno.core;
|
||||
|
||||
let opsCache = {};
|
||||
const errorMap = {};
|
||||
// Builtin v8 / JS errors
|
||||
registerErrorClass("Error", Error);
|
||||
|
@ -110,15 +110,6 @@
|
|||
return promiseRing[idx] != NO_PROMISE;
|
||||
}
|
||||
|
||||
function ops() {
|
||||
return opsCache;
|
||||
}
|
||||
|
||||
function syncOpsCache() {
|
||||
// op id 0 is a special value to retrieve the map of registered ops.
|
||||
opsCache = ObjectFreeze(ObjectFromEntries(opcallSync(0)));
|
||||
}
|
||||
|
||||
function opresolve() {
|
||||
for (let i = 0; i < arguments.length; i += 2) {
|
||||
const promiseId = arguments[i];
|
||||
|
@ -160,7 +151,7 @@
|
|||
|
||||
function opAsync(opName, arg1 = null, arg2 = null) {
|
||||
const promiseId = nextPromiseId++;
|
||||
const maybeError = opcallAsync(opsCache[opName], promiseId, arg1, arg2);
|
||||
const maybeError = ops[opName](opIds[opName], promiseId, arg1, arg2);
|
||||
// Handle sync error (e.g: error parsing args)
|
||||
if (maybeError) return unwrapOpResult(maybeError);
|
||||
let p = PromisePrototypeThen(setPromise(promiseId), unwrapOpResult);
|
||||
|
@ -179,8 +170,8 @@
|
|||
return p;
|
||||
}
|
||||
|
||||
function opSync(opName, arg1 = null, arg2 = null) {
|
||||
return unwrapOpResult(opcallSync(opsCache[opName], arg1, arg2));
|
||||
function opSync(opName, arg1, arg2) {
|
||||
return unwrapOpResult(ops[opName](opIds[opName], arg1, arg2));
|
||||
}
|
||||
|
||||
function refOp(promiseId) {
|
||||
|
@ -228,7 +219,7 @@
|
|||
function metrics() {
|
||||
const [aggregate, perOps] = opSync("op_metrics");
|
||||
aggregate.ops = ObjectFromEntries(ArrayPrototypeMap(
|
||||
ObjectEntries(opsCache),
|
||||
ObjectEntries(opIds),
|
||||
([opName, opId]) => [opName, perOps[opId]],
|
||||
));
|
||||
return aggregate;
|
||||
|
@ -257,7 +248,6 @@
|
|||
const core = ObjectAssign(globalThis.Deno.core, {
|
||||
opAsync,
|
||||
opSync,
|
||||
ops,
|
||||
close,
|
||||
tryClose,
|
||||
read,
|
||||
|
@ -269,7 +259,6 @@
|
|||
registerErrorBuilder,
|
||||
registerErrorClass,
|
||||
opresolve,
|
||||
syncOpsCache,
|
||||
BadResource,
|
||||
BadResourcePrototype,
|
||||
Interrupted,
|
||||
|
|
|
@ -14,6 +14,7 @@ path = "lib.rs"
|
|||
|
||||
[dependencies]
|
||||
anyhow = "1.0.55"
|
||||
deno_ops = { path = "../ops", version = "0.1.0" }
|
||||
futures = "0.3.21"
|
||||
indexmap = "1.7.0"
|
||||
libc = "0.2.106"
|
||||
|
|
370
core/bindings.rs
370
core/bindings.rs
|
@ -1,6 +1,7 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use crate::error::is_instance_of_error;
|
||||
use crate::extensions::OpPair;
|
||||
use crate::modules::get_module_type_from_assertions;
|
||||
use crate::modules::parse_import_assertions;
|
||||
use crate::modules::validate_import_assertions;
|
||||
|
@ -8,21 +9,18 @@ use crate::modules::ImportAssertionsKind;
|
|||
use crate::modules::ModuleMap;
|
||||
use crate::resolve_url_or_path;
|
||||
use crate::JsRuntime;
|
||||
use crate::Op;
|
||||
use crate::OpId;
|
||||
use crate::OpPayload;
|
||||
use crate::OpResult;
|
||||
use crate::OpTable;
|
||||
use crate::OpState;
|
||||
use crate::PromiseId;
|
||||
use crate::ZeroCopyBuf;
|
||||
use anyhow::Error;
|
||||
use log::debug;
|
||||
use once_cell::sync::Lazy;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use serde_v8::to_v8;
|
||||
use std::cell::RefCell;
|
||||
use std::option::Option;
|
||||
use std::os::raw::c_void;
|
||||
use std::rc::Rc;
|
||||
use url::Url;
|
||||
use v8::HandleScope;
|
||||
use v8::Local;
|
||||
|
@ -31,88 +29,88 @@ use v8::SharedArrayBuffer;
|
|||
use v8::ValueDeserializerHelper;
|
||||
use v8::ValueSerializerHelper;
|
||||
|
||||
const UNDEFINED_OP_ID_MSG: &str =
|
||||
"invalid op id: received `undefined` instead of an integer.
|
||||
This error is often caused by a typo in an op name, or not calling
|
||||
JsRuntime::sync_ops_cache() after JsRuntime initialization.";
|
||||
|
||||
pub static EXTERNAL_REFERENCES: Lazy<v8::ExternalReferences> =
|
||||
Lazy::new(|| {
|
||||
v8::ExternalReferences::new(&[
|
||||
v8::ExternalReference {
|
||||
function: opcall_async.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: opcall_sync.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: ref_op.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: unref_op.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: set_macrotask_callback.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: set_nexttick_callback.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: set_promise_reject_callback.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: set_uncaught_exception_callback.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: run_microtasks.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: has_tick_scheduled.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: set_has_tick_scheduled.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: eval_context.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: queue_microtask.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: create_host_object.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: encode.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: decode.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: serialize.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: deserialize.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: get_promise_details.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: get_proxy_details.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: is_proxy.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: memory_usage.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: call_console.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: set_wasm_streaming_callback.map_fn_to(),
|
||||
},
|
||||
])
|
||||
pub fn external_references(
|
||||
ops: &[OpPair],
|
||||
op_state: Rc<RefCell<OpState>>,
|
||||
) -> v8::ExternalReferences {
|
||||
let mut refs = vec![
|
||||
v8::ExternalReference {
|
||||
function: ref_op.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: unref_op.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: set_macrotask_callback.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: set_nexttick_callback.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: set_promise_reject_callback.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: set_uncaught_exception_callback.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: run_microtasks.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: has_tick_scheduled.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: set_has_tick_scheduled.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: eval_context.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: queue_microtask.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: create_host_object.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: encode.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: decode.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: serialize.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: deserialize.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: get_promise_details.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: get_proxy_details.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: is_proxy.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: memory_usage.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: call_console.map_fn_to(),
|
||||
},
|
||||
v8::ExternalReference {
|
||||
function: set_wasm_streaming_callback.map_fn_to(),
|
||||
},
|
||||
];
|
||||
let op_refs = ops
|
||||
.iter()
|
||||
.map(|(_, opref)| v8::ExternalReference { function: *opref });
|
||||
refs.extend(op_refs);
|
||||
let raw_op_state = Rc::as_ptr(&op_state) as *mut c_void;
|
||||
refs.push(v8::ExternalReference {
|
||||
pointer: raw_op_state,
|
||||
});
|
||||
v8::ExternalReferences::new(&refs)
|
||||
}
|
||||
|
||||
pub fn script_origin<'a>(
|
||||
s: &mut v8::HandleScope<'a>,
|
||||
|
@ -154,6 +152,9 @@ pub fn module_origin<'a>(
|
|||
|
||||
pub fn initialize_context<'s>(
|
||||
scope: &mut v8::HandleScope<'s, ()>,
|
||||
ops: &[OpPair],
|
||||
snapshot_loaded: bool,
|
||||
op_state: Rc<RefCell<OpState>>,
|
||||
) -> v8::Local<'s, v8::Context> {
|
||||
let scope = &mut v8::EscapableHandleScope::new(scope);
|
||||
|
||||
|
@ -162,17 +163,43 @@ pub fn initialize_context<'s>(
|
|||
|
||||
let scope = &mut v8::ContextScope::new(scope, context);
|
||||
|
||||
// global.Deno = { core: {} };
|
||||
let deno_key = v8::String::new(scope, "Deno").unwrap();
|
||||
let core_key = v8::String::new(scope, "core").unwrap();
|
||||
let ops_key = v8::String::new(scope, "ops").unwrap();
|
||||
// Snapshot already registered `Deno.core.ops` but
|
||||
// extensions may provide ops that aren't part of the snapshot.
|
||||
//
|
||||
// TODO(@littledivy): This is extra complexity for
|
||||
// a really weird usecase. Remove this once all
|
||||
// tsc ops are static at snapshot time.
|
||||
if snapshot_loaded {
|
||||
// Grab Deno.core.ops object
|
||||
let deno_val = global.get(scope, deno_key.into()).unwrap();
|
||||
let deno_val = v8::Local::<v8::Object>::try_from(deno_val)
|
||||
.expect("`Deno` not in global scope.");
|
||||
let core_val = deno_val.get(scope, core_key.into()).unwrap();
|
||||
let core_val = v8::Local::<v8::Object>::try_from(core_val)
|
||||
.expect("`Deno.core` not in global scope");
|
||||
let ops_val = core_val.get(scope, ops_key.into()).unwrap();
|
||||
let ops_val = v8::Local::<v8::Object>::try_from(ops_val)
|
||||
.expect("`Deno.core.ops` not in global scope");
|
||||
|
||||
let raw_op_state = Rc::as_ptr(&op_state) as *const c_void;
|
||||
for (name, opfn) in ops {
|
||||
set_func_raw(scope, ops_val, name, *opfn, raw_op_state);
|
||||
}
|
||||
return scope.escape(context);
|
||||
}
|
||||
|
||||
// global.Deno = { core: { ops: {} } };
|
||||
let deno_val = v8::Object::new(scope);
|
||||
global.set(scope, deno_key.into(), deno_val.into());
|
||||
let core_key = v8::String::new(scope, "core").unwrap();
|
||||
let core_val = v8::Object::new(scope);
|
||||
deno_val.set(scope, core_key.into(), core_val.into());
|
||||
let ops_val = v8::Object::new(scope);
|
||||
core_val.set(scope, ops_key.into(), ops_val.into());
|
||||
|
||||
// Bind functions to Deno.core.*
|
||||
set_func(scope, core_val, "opcallSync", opcall_sync);
|
||||
set_func(scope, core_val, "opcallAsync", opcall_async);
|
||||
set_func(scope, core_val, "refOp_", ref_op);
|
||||
set_func(scope, core_val, "unrefOp_", unref_op);
|
||||
set_func(
|
||||
|
@ -227,10 +254,14 @@ pub fn initialize_context<'s>(
|
|||
// Direct bindings on `window`.
|
||||
set_func(scope, global, "queueMicrotask", queue_microtask);
|
||||
|
||||
// Bind functions to Deno.core.ops.*
|
||||
let raw_op_state = Rc::as_ptr(&op_state) as *const c_void;
|
||||
for (name, opfn) in ops {
|
||||
set_func_raw(scope, ops_val, name, *opfn, raw_op_state);
|
||||
}
|
||||
scope.escape(context)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn set_func(
|
||||
scope: &mut v8::HandleScope<'_>,
|
||||
obj: v8::Local<v8::Object>,
|
||||
|
@ -238,8 +269,26 @@ pub fn set_func(
|
|||
callback: impl v8::MapFnTo<v8::FunctionCallback>,
|
||||
) {
|
||||
let key = v8::String::new(scope, name).unwrap();
|
||||
let tmpl = v8::FunctionTemplate::new(scope, callback);
|
||||
let val = tmpl.get_function(scope).unwrap();
|
||||
let val = v8::Function::new(scope, callback).unwrap();
|
||||
val.set_name(key);
|
||||
obj.set(scope, key.into(), val.into());
|
||||
}
|
||||
|
||||
// Register a raw v8::FunctionCallback
|
||||
// with some external data.
|
||||
pub fn set_func_raw(
|
||||
scope: &mut v8::HandleScope<'_>,
|
||||
obj: v8::Local<v8::Object>,
|
||||
name: &'static str,
|
||||
callback: v8::FunctionCallback,
|
||||
external_data: *const c_void,
|
||||
) {
|
||||
let key = v8::String::new(scope, name).unwrap();
|
||||
let external = v8::External::new(scope, external_data as *mut c_void);
|
||||
let val = v8::Function::builder_raw(callback)
|
||||
.data(external.into())
|
||||
.build(scope)
|
||||
.unwrap();
|
||||
val.set_name(key);
|
||||
obj.set(scope, key.into(), val.into());
|
||||
}
|
||||
|
@ -460,137 +509,6 @@ pub extern "C" fn promise_reject_callback(message: v8::PromiseRejectMessage) {
|
|||
}
|
||||
}
|
||||
|
||||
fn opcall_sync<'s>(
|
||||
scope: &mut v8::HandleScope<'s>,
|
||||
args: v8::FunctionCallbackArguments,
|
||||
mut rv: v8::ReturnValue,
|
||||
) {
|
||||
let state_rc = JsRuntime::state(scope);
|
||||
let state = state_rc.borrow_mut();
|
||||
|
||||
let op_id = match v8::Local::<v8::Integer>::try_from(args.get(0))
|
||||
.map(|l| l.value() as OpId)
|
||||
.map_err(Error::from)
|
||||
{
|
||||
Ok(op_id) => op_id,
|
||||
Err(err) => {
|
||||
let msg = if args.get(0).is_undefined() {
|
||||
UNDEFINED_OP_ID_MSG.to_string()
|
||||
} else {
|
||||
format!("invalid op id: {}", err)
|
||||
};
|
||||
throw_type_error(scope, msg);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
// opcall(0) returns obj of all ops, handle as special case
|
||||
if op_id == 0 {
|
||||
// TODO: Serialize as HashMap when serde_v8 supports maps ...
|
||||
let ops = OpTable::op_entries(state.op_state.clone());
|
||||
rv.set(to_v8(scope, ops).unwrap());
|
||||
return;
|
||||
}
|
||||
|
||||
// Deserializable args (may be structured args or ZeroCopyBuf)
|
||||
let a = args.get(1);
|
||||
let b = args.get(2);
|
||||
|
||||
let payload = OpPayload {
|
||||
scope,
|
||||
a,
|
||||
b,
|
||||
op_id,
|
||||
promise_id: 0,
|
||||
};
|
||||
let op = OpTable::route_op(op_id, state.op_state.clone(), payload);
|
||||
match op {
|
||||
Op::Sync(result) => {
|
||||
state.op_state.borrow().tracker.track_sync(op_id);
|
||||
rv.set(result.to_v8(scope).unwrap());
|
||||
}
|
||||
Op::NotFound => {
|
||||
throw_type_error(scope, format!("Unknown op id: {}", op_id));
|
||||
}
|
||||
// Async ops (ref or unref)
|
||||
_ => {
|
||||
throw_type_error(
|
||||
scope,
|
||||
format!("Can not call an async op [{}] with opSync()", op_id),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn opcall_async<'s>(
|
||||
scope: &mut v8::HandleScope<'s>,
|
||||
args: v8::FunctionCallbackArguments,
|
||||
mut rv: v8::ReturnValue,
|
||||
) {
|
||||
let state_rc = JsRuntime::state(scope);
|
||||
let mut state = state_rc.borrow_mut();
|
||||
|
||||
let op_id = match v8::Local::<v8::Integer>::try_from(args.get(0))
|
||||
.map(|l| l.value() as OpId)
|
||||
.map_err(Error::from)
|
||||
{
|
||||
Ok(op_id) => op_id,
|
||||
Err(err) => {
|
||||
let msg = if args.get(0).is_undefined() {
|
||||
UNDEFINED_OP_ID_MSG.to_string()
|
||||
} else {
|
||||
format!("invalid op id: {}", err)
|
||||
};
|
||||
throw_type_error(scope, msg);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
// PromiseId
|
||||
let arg1 = args.get(1);
|
||||
let promise_id = v8::Local::<v8::Integer>::try_from(arg1)
|
||||
.map(|l| l.value() as PromiseId)
|
||||
.map_err(Error::from);
|
||||
// Fail if promise id invalid (not an int)
|
||||
let promise_id: PromiseId = match promise_id {
|
||||
Ok(promise_id) => promise_id,
|
||||
Err(err) => {
|
||||
throw_type_error(scope, format!("invalid promise id: {}", err));
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
// Deserializable args (may be structured args or ZeroCopyBuf)
|
||||
let a = args.get(2);
|
||||
let b = args.get(3);
|
||||
|
||||
let payload = OpPayload {
|
||||
scope,
|
||||
a,
|
||||
b,
|
||||
op_id,
|
||||
promise_id,
|
||||
};
|
||||
let op = OpTable::route_op(op_id, state.op_state.clone(), payload);
|
||||
match op {
|
||||
Op::Sync(result) => match result {
|
||||
OpResult::Ok(_) => throw_type_error(
|
||||
scope,
|
||||
format!("Can not call a sync op [{}] with opAsync()", op_id),
|
||||
),
|
||||
OpResult::Err(_) => rv.set(result.to_v8(scope).unwrap()),
|
||||
},
|
||||
Op::Async(fut) => {
|
||||
state.op_state.borrow().tracker.track_async(op_id);
|
||||
state.pending_ops.push(fut);
|
||||
state.have_unpolled_ops = true;
|
||||
}
|
||||
Op::NotFound => {
|
||||
throw_type_error(scope, format!("Unknown op id: {}", op_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn ref_op<'s>(
|
||||
scope: &mut v8::HandleScope<'s>,
|
||||
args: v8::FunctionCallbackArguments,
|
||||
|
@ -1471,7 +1389,7 @@ fn is_proxy(
|
|||
rv.set(v8::Boolean::new(scope, args.get(0).is_proxy()).into())
|
||||
}
|
||||
|
||||
fn throw_type_error(scope: &mut v8::HandleScope, message: impl AsRef<str>) {
|
||||
pub fn throw_type_error(scope: &mut v8::HandleScope, message: impl AsRef<str>) {
|
||||
let message = v8::String::new(scope, message.as_ref()).unwrap();
|
||||
let exception = v8::Exception::type_error(scope, message);
|
||||
scope.throw_exception(exception);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use anyhow::Error;
|
||||
|
||||
pub(crate) fn get_error_code(err: &Error) -> Option<&'static str> {
|
||||
pub fn get_error_code(err: &Error) -> Option<&'static str> {
|
||||
err
|
||||
.downcast_ref::<std::io::Error>()
|
||||
.map(|e| match e.raw_os_error() {
|
||||
|
|
|
@ -9,7 +9,7 @@ use deno_core::RuntimeOptions;
|
|||
fn main() {
|
||||
let my_ext = Extension::builder()
|
||||
.middleware(|name, opfn| match name {
|
||||
"op_print" => deno_core::void_op_sync(),
|
||||
"op_print" => deno_core::void_op_sync::v8_cb(),
|
||||
_ => opfn,
|
||||
})
|
||||
.build();
|
||||
|
|
|
@ -2,27 +2,37 @@
|
|||
//! This example shows you how to define ops in Rust and then call them from
|
||||
//! JavaScript.
|
||||
|
||||
use deno_core::op_sync;
|
||||
use deno_core::op;
|
||||
use deno_core::Extension;
|
||||
use deno_core::JsRuntime;
|
||||
use deno_core::OpState;
|
||||
use deno_core::RuntimeOptions;
|
||||
|
||||
// This is a hack to make the `#[op]` macro work with
|
||||
// deno_core examples.
|
||||
// You can remove this:
|
||||
use deno_core::*;
|
||||
|
||||
#[op]
|
||||
fn op_sum(
|
||||
_state: &mut OpState,
|
||||
nums: Vec<f64>,
|
||||
_: (),
|
||||
) -> Result<f64, deno_core::error::AnyError> {
|
||||
// Sum inputs
|
||||
let sum = nums.iter().fold(0.0, |a, v| a + v);
|
||||
// return as a Result<f64, AnyError>
|
||||
Ok(sum)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Build a deno_core::Extension providing custom ops
|
||||
let ext = Extension::builder()
|
||||
.ops(vec![
|
||||
// An op for summing an array of numbers
|
||||
(
|
||||
"op_sum",
|
||||
// The op-layer automatically deserializes inputs
|
||||
// and serializes the returned Result & value
|
||||
op_sync(|_state, nums: Vec<f64>, _: ()| {
|
||||
// Sum inputs
|
||||
let sum = nums.iter().fold(0.0, |a, v| a + v);
|
||||
// return as a Result<f64, AnyError>
|
||||
Ok(sum)
|
||||
}),
|
||||
),
|
||||
// The op-layer automatically deserializes inputs
|
||||
// and serializes the returned Result & value
|
||||
op_sum::decl(),
|
||||
])
|
||||
.build();
|
||||
|
||||
|
|
|
@ -11,12 +11,12 @@ const responseBuf = new Uint8Array(
|
|||
|
||||
/** Listens on 0.0.0.0:4500, returns rid. */
|
||||
function listen() {
|
||||
return Deno.core.opSync("listen");
|
||||
return Deno.core.opSync("op_listen");
|
||||
}
|
||||
|
||||
/** Accepts a connection, returns rid. */
|
||||
function accept(serverRid) {
|
||||
return Deno.core.opAsync("accept", serverRid);
|
||||
return Deno.core.opAsync("op_accept", serverRid);
|
||||
}
|
||||
|
||||
async function serve(rid) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
use deno_core::anyhow::Error;
|
||||
use deno_core::op;
|
||||
use deno_core::AsyncRefCell;
|
||||
use deno_core::AsyncResult;
|
||||
use deno_core::CancelHandle;
|
||||
|
@ -17,6 +18,11 @@ use std::rc::Rc;
|
|||
use tokio::io::AsyncReadExt;
|
||||
use tokio::io::AsyncWriteExt;
|
||||
|
||||
// This is a hack to make the `#[op]` macro work with
|
||||
// deno_core examples.
|
||||
// You can remove this:
|
||||
use deno_core::*;
|
||||
|
||||
struct Logger;
|
||||
|
||||
impl log::Log for Logger {
|
||||
|
@ -119,10 +125,7 @@ impl From<tokio::net::TcpStream> for TcpStream {
|
|||
|
||||
fn create_js_runtime() -> JsRuntime {
|
||||
let ext = deno_core::Extension::builder()
|
||||
.ops(vec![
|
||||
("listen", deno_core::op_sync(op_listen)),
|
||||
("accept", deno_core::op_async(op_accept)),
|
||||
])
|
||||
.ops(vec![op_listen::decl(), op_accept::decl()])
|
||||
.build();
|
||||
|
||||
JsRuntime::new(deno_core::RuntimeOptions {
|
||||
|
@ -131,6 +134,7 @@ fn create_js_runtime() -> JsRuntime {
|
|||
})
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_listen(state: &mut OpState, _: (), _: ()) -> Result<ResourceId, Error> {
|
||||
log::debug!("listen");
|
||||
let addr = "127.0.0.1:4544".parse::<SocketAddr>().unwrap();
|
||||
|
@ -141,6 +145,7 @@ fn op_listen(state: &mut OpState, _: (), _: ()) -> Result<ResourceId, Error> {
|
|||
Ok(rid)
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_accept(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
rid: ResourceId,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use deno_core::anyhow::Error;
|
||||
use deno_core::op;
|
||||
use deno_core::Extension;
|
||||
use deno_core::JsRuntime;
|
||||
use deno_core::OpState;
|
||||
|
@ -9,14 +10,16 @@ use futures::channel::mpsc;
|
|||
use futures::stream::StreamExt;
|
||||
use std::task::Poll;
|
||||
|
||||
// This is a hack to make the `#[op]` macro work with
|
||||
// deno_core examples.
|
||||
// You can remove this:
|
||||
use deno_core::*;
|
||||
|
||||
type Task = Box<dyn FnOnce()>;
|
||||
|
||||
fn main() {
|
||||
let my_ext = Extension::builder()
|
||||
.ops(vec![(
|
||||
"op_schedule_task",
|
||||
deno_core::op_sync(op_schedule_task),
|
||||
)])
|
||||
.ops(vec![op_schedule_task::decl()])
|
||||
.event_loop_middleware(|state, cx| {
|
||||
let recv = state.borrow_mut::<mpsc::UnboundedReceiver<Task>>();
|
||||
let mut ref_loop = false;
|
||||
|
@ -58,6 +61,7 @@ fn main() {
|
|||
runtime.block_on(future).unwrap();
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_schedule_task(state: &mut OpState, i: u8, _: ()) -> Result<(), Error> {
|
||||
let tx = state.borrow_mut::<mpsc::UnboundedSender<Task>>();
|
||||
tx.unbounded_send(Box::new(move || println!("Hello, world! x{}", i)))
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
use crate::OpFn;
|
||||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
use crate::OpState;
|
||||
use anyhow::Error;
|
||||
use std::task::Context;
|
||||
|
||||
pub type SourcePair = (&'static str, Box<SourceLoadFn>);
|
||||
pub type SourceLoadFn = dyn Fn() -> Result<String, Error>;
|
||||
pub type OpPair = (&'static str, Box<OpFn>);
|
||||
pub type OpMiddlewareFn = dyn Fn(&'static str, Box<OpFn>) -> Box<OpFn>;
|
||||
pub type OpFnRef = v8::FunctionCallback;
|
||||
pub type OpPair = (&'static str, OpFnRef);
|
||||
pub type OpMiddlewareFn = dyn Fn(&'static str, OpFnRef) -> OpFnRef;
|
||||
pub type OpStateFn = dyn Fn(&mut OpState) -> Result<(), Error>;
|
||||
pub type OpEventLoopFn = dyn Fn(&mut OpState, &mut Context) -> bool;
|
||||
|
||||
|
@ -108,7 +109,7 @@ impl ExtensionBuilder {
|
|||
|
||||
pub fn middleware<F>(&mut self, middleware_fn: F) -> &mut Self
|
||||
where
|
||||
F: Fn(&'static str, Box<OpFn>) -> Box<OpFn> + 'static,
|
||||
F: Fn(&'static str, OpFnRef) -> OpFnRef + 'static,
|
||||
{
|
||||
self.middleware = Some(Box::new(middleware_fn));
|
||||
self
|
||||
|
|
31
core/lib.rs
31
core/lib.rs
|
@ -13,7 +13,6 @@ mod modules;
|
|||
mod normalize_path;
|
||||
mod ops;
|
||||
mod ops_builtin;
|
||||
mod ops_json;
|
||||
mod ops_metrics;
|
||||
mod resources;
|
||||
mod runtime;
|
||||
|
@ -44,6 +43,10 @@ pub use crate::async_cell::AsyncRefCell;
|
|||
pub use crate::async_cell::AsyncRefFuture;
|
||||
pub use crate::async_cell::RcLike;
|
||||
pub use crate::async_cell::RcRef;
|
||||
pub use crate::extensions::Extension;
|
||||
pub use crate::extensions::ExtensionBuilder;
|
||||
pub use crate::extensions::OpMiddlewareFn;
|
||||
pub use crate::extensions::OpPair;
|
||||
pub use crate::flags::v8_set_flags;
|
||||
pub use crate::inspector::InspectorMsg;
|
||||
pub use crate::inspector::InspectorMsgKind;
|
||||
|
@ -65,24 +68,21 @@ pub use crate::modules::ModuleSourceFuture;
|
|||
pub use crate::modules::ModuleType;
|
||||
pub use crate::modules::NoopModuleLoader;
|
||||
pub use crate::normalize_path::normalize_path;
|
||||
pub use crate::ops::serialize_op_result;
|
||||
pub use crate::ops::Op;
|
||||
pub use crate::ops::OpAsyncFuture;
|
||||
pub use crate::ops::OpCall;
|
||||
pub use crate::ops::OpError;
|
||||
pub use crate::ops::OpFn;
|
||||
pub use crate::ops::OpId;
|
||||
pub use crate::ops::OpPayload;
|
||||
pub use crate::ops::OpResult;
|
||||
pub use crate::ops::OpState;
|
||||
pub use crate::ops::OpTable;
|
||||
pub use crate::ops::PromiseId;
|
||||
pub use crate::ops_builtin::op_close;
|
||||
pub use crate::ops_builtin::op_print;
|
||||
pub use crate::ops_builtin::op_resources;
|
||||
pub use crate::ops_json::op_async;
|
||||
pub use crate::ops_json::op_sync;
|
||||
pub use crate::ops_json::void_op_async;
|
||||
pub use crate::ops_json::void_op_sync;
|
||||
pub use crate::ops_builtin::void_op_async;
|
||||
pub use crate::ops_builtin::void_op_sync;
|
||||
pub use crate::ops_metrics::OpsTracker;
|
||||
pub use crate::resources::AsyncResult;
|
||||
pub use crate::resources::Resource;
|
||||
pub use crate::resources::ResourceId;
|
||||
|
@ -95,16 +95,21 @@ pub use crate::runtime::JsRuntime;
|
|||
pub use crate::runtime::RuntimeOptions;
|
||||
pub use crate::runtime::SharedArrayBufferStore;
|
||||
pub use crate::runtime::Snapshot;
|
||||
// pub use crate::runtime_modules::include_js_files!;
|
||||
pub use crate::extensions::Extension;
|
||||
pub use crate::extensions::ExtensionBuilder;
|
||||
pub use crate::extensions::OpMiddlewareFn;
|
||||
pub use crate::extensions::OpPair;
|
||||
pub use deno_ops::op;
|
||||
|
||||
pub fn v8_version() -> &'static str {
|
||||
v8::V8::get_version()
|
||||
}
|
||||
|
||||
/// An internal module re-exporting funcs used by the #[op] (`deno_ops`) macro
|
||||
#[doc(hidden)]
|
||||
pub mod _ops {
|
||||
pub use super::bindings::throw_type_error;
|
||||
pub use super::error_codes::get_error_code;
|
||||
pub use super::ops::to_op_result;
|
||||
pub use super::runtime::queue_async_op;
|
||||
}
|
||||
|
||||
/// A helper macro that will return a call site in Rust code. Should be
|
||||
/// used when executing internal one-line scripts for JsRuntime lifecycle.
|
||||
///
|
||||
|
|
|
@ -1073,13 +1073,11 @@ impl ModuleMap {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::ops::OpCall;
|
||||
use crate::serialize_op_result;
|
||||
use crate::error::AnyError;
|
||||
use crate::Extension;
|
||||
use crate::JsRuntime;
|
||||
use crate::Op;
|
||||
use crate::OpPayload;
|
||||
use crate::RuntimeOptions;
|
||||
use deno_ops::op;
|
||||
use futures::future::FutureExt;
|
||||
use parking_lot::Mutex;
|
||||
use std::fmt;
|
||||
|
@ -1088,6 +1086,10 @@ mod tests {
|
|||
use std::path::PathBuf;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::sync::Arc;
|
||||
// deno_ops macros generate code assuming deno_core in scope.
|
||||
mod deno_core {
|
||||
pub use crate::*;
|
||||
}
|
||||
|
||||
// TODO(ry) Sadly FuturesUnordered requires the current task to be set. So
|
||||
// even though we are only using poll() in these tests and not Tokio, we must
|
||||
|
@ -1401,20 +1403,16 @@ import "/a.js";
|
|||
let loader = Rc::new(ModsLoader::default());
|
||||
|
||||
let resolve_count = loader.count.clone();
|
||||
let dispatch_count = Arc::new(AtomicUsize::new(0));
|
||||
let dispatch_count_ = dispatch_count.clone();
|
||||
static DISPATCH_COUNT: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
let op_test = move |state, payload: OpPayload| -> Op {
|
||||
dispatch_count_.fetch_add(1, Ordering::Relaxed);
|
||||
let (control, _): (u8, ()) = payload.deserialize().unwrap();
|
||||
#[op]
|
||||
fn op_test(_: &mut OpState, control: u8, _: ()) -> Result<u8, AnyError> {
|
||||
DISPATCH_COUNT.fetch_add(1, Ordering::Relaxed);
|
||||
assert_eq!(control, 42);
|
||||
let resp = (0, 1, serialize_op_result(Ok(43), state));
|
||||
Op::Async(OpCall::ready(resp))
|
||||
};
|
||||
Ok(43)
|
||||
}
|
||||
|
||||
let ext = Extension::builder()
|
||||
.ops(vec![("op_test", Box::new(op_test))])
|
||||
.build();
|
||||
let ext = Extension::builder().ops(vec![op_test::decl()]).build();
|
||||
|
||||
let mut runtime = JsRuntime::new(RuntimeOptions {
|
||||
extensions: vec![ext],
|
||||
|
@ -1435,7 +1433,7 @@ import "/a.js";
|
|||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(dispatch_count.load(Ordering::Relaxed), 0);
|
||||
assert_eq!(DISPATCH_COUNT.load(Ordering::Relaxed), 0);
|
||||
|
||||
let module_map_rc = JsRuntime::module_map(runtime.v8_isolate());
|
||||
|
||||
|
@ -1452,12 +1450,12 @@ import "/a.js";
|
|||
import { b } from './b.js'
|
||||
if (b() != 'b') throw Error();
|
||||
let control = 42;
|
||||
Deno.core.opAsync("op_test", control);
|
||||
Deno.core.opSync("op_test", control);
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(dispatch_count.load(Ordering::Relaxed), 0);
|
||||
assert_eq!(DISPATCH_COUNT.load(Ordering::Relaxed), 0);
|
||||
let imports = module_map.get_requested_modules(mod_a);
|
||||
assert_eq!(
|
||||
imports,
|
||||
|
@ -1481,14 +1479,14 @@ import "/a.js";
|
|||
};
|
||||
|
||||
runtime.instantiate_module(mod_b).unwrap();
|
||||
assert_eq!(dispatch_count.load(Ordering::Relaxed), 0);
|
||||
assert_eq!(DISPATCH_COUNT.load(Ordering::Relaxed), 0);
|
||||
assert_eq!(resolve_count.load(Ordering::SeqCst), 1);
|
||||
|
||||
runtime.instantiate_module(mod_a).unwrap();
|
||||
assert_eq!(dispatch_count.load(Ordering::Relaxed), 0);
|
||||
assert_eq!(DISPATCH_COUNT.load(Ordering::Relaxed), 0);
|
||||
|
||||
let _ = runtime.mod_evaluate(mod_a);
|
||||
assert_eq!(dispatch_count.load(Ordering::Relaxed), 1);
|
||||
assert_eq!(DISPATCH_COUNT.load(Ordering::Relaxed), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1766,7 +1764,6 @@ import "/a.js";
|
|||
module_loader: Some(loader),
|
||||
..Default::default()
|
||||
});
|
||||
runtime.sync_ops_cache();
|
||||
runtime
|
||||
.execute_script(
|
||||
"file:///dyn_import3.js",
|
||||
|
|
149
core/ops.rs
149
core/ops.rs
|
@ -1,10 +1,9 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use crate::error::type_error;
|
||||
use crate::gotham_state::GothamState;
|
||||
use crate::ops_metrics::OpsTracker;
|
||||
use crate::resources::ResourceTable;
|
||||
use crate::runtime::GetErrorClassFn;
|
||||
use crate::OpsTracker;
|
||||
use anyhow::Error;
|
||||
use futures::future::maybe_done;
|
||||
use futures::future::FusedFuture;
|
||||
|
@ -12,23 +11,19 @@ use futures::future::MaybeDone;
|
|||
use futures::ready;
|
||||
use futures::task::noop_waker;
|
||||
use futures::Future;
|
||||
use indexmap::IndexMap;
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::Serialize;
|
||||
use std::cell::RefCell;
|
||||
use std::cell::UnsafeCell;
|
||||
use std::iter::once;
|
||||
use std::ops::Deref;
|
||||
use std::ops::DerefMut;
|
||||
use std::pin::Pin;
|
||||
use std::rc::Rc;
|
||||
use std::task::Context;
|
||||
use std::task::Poll;
|
||||
|
||||
/// Wrapper around a Future, which causes that Future to be polled immediately.
|
||||
/// (Background: ops are stored in a `FuturesUnordered` structure which polls
|
||||
///
|
||||
/// Background: ops are stored in a `FuturesUnordered` structure which polls
|
||||
/// them, but without the `OpCall` wrapper this doesn't happen until the next
|
||||
/// turn of the event loop, which is too late for certain ops.)
|
||||
/// turn of the event loop, which is too late for certain ops.
|
||||
pub struct OpCall<T>(MaybeDone<Pin<Box<dyn Future<Output = T>>>>);
|
||||
|
||||
impl<T> OpCall<T> {
|
||||
|
@ -83,32 +78,10 @@ where
|
|||
|
||||
pub type PromiseId = i32;
|
||||
pub type OpAsyncFuture = OpCall<(PromiseId, OpId, OpResult)>;
|
||||
pub type OpFn = dyn Fn(Rc<RefCell<OpState>>, OpPayload) -> Op + 'static;
|
||||
pub type OpFn =
|
||||
fn(&mut v8::HandleScope, v8::FunctionCallbackArguments, v8::ReturnValue);
|
||||
pub type OpId = usize;
|
||||
|
||||
pub struct OpPayload<'a, 'b, 'c> {
|
||||
pub(crate) scope: &'a mut v8::HandleScope<'b>,
|
||||
pub(crate) a: v8::Local<'c, v8::Value>,
|
||||
pub(crate) b: v8::Local<'c, v8::Value>,
|
||||
pub(crate) op_id: OpId,
|
||||
pub(crate) promise_id: PromiseId,
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'c> OpPayload<'a, 'b, 'c> {
|
||||
pub fn deserialize<T: DeserializeOwned, U: DeserializeOwned>(
|
||||
self,
|
||||
) -> Result<(T, U), Error> {
|
||||
let a: T = serde_v8::from_v8(self.scope, self.a)
|
||||
.map_err(Error::from)
|
||||
.map_err(|e| type_error(format!("Error parsing args: {}", e)))?;
|
||||
|
||||
let b: U = serde_v8::from_v8(self.scope, self.b)
|
||||
.map_err(Error::from)
|
||||
.map_err(|e| type_error(format!("Error parsing args: {}", e)))?;
|
||||
Ok((a, b))
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Op {
|
||||
Sync(OpResult),
|
||||
Async(OpAsyncFuture),
|
||||
|
@ -141,39 +114,43 @@ pub struct OpError {
|
|||
code: Option<&'static str>,
|
||||
}
|
||||
|
||||
pub fn serialize_op_result<R: Serialize + 'static>(
|
||||
impl OpError {
|
||||
pub fn new(get_class: GetErrorClassFn, err: Error) -> Self {
|
||||
Self {
|
||||
class_name: (get_class)(&err),
|
||||
message: err.to_string(),
|
||||
code: crate::error_codes::get_error_code(&err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_op_result<R: Serialize + 'static>(
|
||||
get_class: GetErrorClassFn,
|
||||
result: Result<R, Error>,
|
||||
state: Rc<RefCell<OpState>>,
|
||||
) -> OpResult {
|
||||
match result {
|
||||
Ok(v) => OpResult::Ok(v.into()),
|
||||
Err(err) => OpResult::Err(OpError {
|
||||
class_name: (state.borrow().get_error_class_fn)(&err),
|
||||
message: err.to_string(),
|
||||
code: crate::error_codes::get_error_code(&err),
|
||||
}),
|
||||
Err(err) => OpResult::Err(OpError::new(get_class, err)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Maintains the resources and ops inside a JS runtime.
|
||||
pub struct OpState {
|
||||
pub resource_table: ResourceTable,
|
||||
pub op_table: OpTable,
|
||||
pub get_error_class_fn: GetErrorClassFn,
|
||||
pub(crate) tracker: OpsTracker,
|
||||
pub tracker: OpsTracker,
|
||||
gotham_state: GothamState,
|
||||
}
|
||||
|
||||
impl OpState {
|
||||
pub(crate) fn new() -> OpState {
|
||||
pub fn new(ops_count: usize) -> OpState {
|
||||
OpState {
|
||||
resource_table: Default::default(),
|
||||
op_table: OpTable::default(),
|
||||
get_error_class_fn: &|_| "Error",
|
||||
tracker: OpsTracker {
|
||||
ops: UnsafeCell::new(Vec::with_capacity(256)),
|
||||
},
|
||||
gotham_state: Default::default(),
|
||||
tracker: OpsTracker {
|
||||
ops: UnsafeCell::new(vec![Default::default(); ops_count]),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -191,81 +168,3 @@ impl DerefMut for OpState {
|
|||
&mut self.gotham_state
|
||||
}
|
||||
}
|
||||
|
||||
/// Collection for storing registered ops. The special 'get_op_catalog'
|
||||
/// op with OpId `0` is automatically added when the OpTable is created.
|
||||
pub struct OpTable(IndexMap<String, Rc<OpFn>>);
|
||||
|
||||
impl OpTable {
|
||||
pub fn register_op<F>(&mut self, name: &str, op_fn: F) -> OpId
|
||||
where
|
||||
F: Fn(Rc<RefCell<OpState>>, OpPayload) -> Op + 'static,
|
||||
{
|
||||
let (op_id, prev) = self.0.insert_full(name.to_owned(), Rc::new(op_fn));
|
||||
assert!(prev.is_none());
|
||||
op_id
|
||||
}
|
||||
|
||||
pub fn op_entries(state: Rc<RefCell<OpState>>) -> Vec<(String, OpId)> {
|
||||
state.borrow().op_table.0.keys().cloned().zip(0..).collect()
|
||||
}
|
||||
|
||||
pub fn route_op(
|
||||
op_id: OpId,
|
||||
state: Rc<RefCell<OpState>>,
|
||||
payload: OpPayload,
|
||||
) -> Op {
|
||||
let op_fn = state
|
||||
.borrow()
|
||||
.op_table
|
||||
.0
|
||||
.get_index(op_id)
|
||||
.map(|(_, op_fn)| op_fn.clone());
|
||||
match op_fn {
|
||||
Some(f) => (f)(state, payload),
|
||||
None => Op::NotFound,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for OpTable {
|
||||
fn default() -> Self {
|
||||
fn dummy(_state: Rc<RefCell<OpState>>, _p: OpPayload) -> Op {
|
||||
unreachable!()
|
||||
}
|
||||
Self(once(("ops".to_owned(), Rc::new(dummy) as _)).collect())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn op_table() {
|
||||
let state = Rc::new(RefCell::new(OpState::new()));
|
||||
|
||||
let foo_id;
|
||||
let bar_id;
|
||||
{
|
||||
let op_table = &mut state.borrow_mut().op_table;
|
||||
foo_id =
|
||||
op_table.register_op("foo", |_, _| Op::Sync(OpResult::Ok(321.into())));
|
||||
assert_eq!(foo_id, 1);
|
||||
bar_id =
|
||||
op_table.register_op("bar", |_, _| Op::Sync(OpResult::Ok(123.into())));
|
||||
assert_eq!(bar_id, 2);
|
||||
}
|
||||
|
||||
let mut catalog_entries = OpTable::op_entries(state);
|
||||
catalog_entries.sort_by(|(_, id1), (_, id2)| id1.partial_cmp(id2).unwrap());
|
||||
assert_eq!(
|
||||
catalog_entries,
|
||||
vec![
|
||||
("ops".to_owned(), 0),
|
||||
("foo".to_owned(), 1),
|
||||
("bar".to_owned(), 2)
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
use crate::error::type_error;
|
||||
use crate::include_js_files;
|
||||
use crate::op_async;
|
||||
use crate::op_sync;
|
||||
use crate::ops_metrics::OpMetrics;
|
||||
use crate::resources::ResourceId;
|
||||
use crate::void_op_async;
|
||||
use crate::void_op_sync;
|
||||
use crate::Extension;
|
||||
use crate::OpState;
|
||||
use crate::Resource;
|
||||
use crate::ZeroCopyBuf;
|
||||
use anyhow::Error;
|
||||
use deno_ops::op;
|
||||
use std::cell::RefCell;
|
||||
use std::io::{stderr, stdout, Write};
|
||||
use std::rc::Rc;
|
||||
|
@ -24,29 +21,40 @@ pub(crate) fn init_builtins() -> Extension {
|
|||
"02_error.js",
|
||||
))
|
||||
.ops(vec![
|
||||
("op_close", op_sync(op_close)),
|
||||
("op_try_close", op_sync(op_try_close)),
|
||||
("op_print", op_sync(op_print)),
|
||||
("op_resources", op_sync(op_resources)),
|
||||
("op_wasm_streaming_feed", op_sync(op_wasm_streaming_feed)),
|
||||
("op_wasm_streaming_abort", op_sync(op_wasm_streaming_abort)),
|
||||
(
|
||||
"op_wasm_streaming_set_url",
|
||||
op_sync(op_wasm_streaming_set_url),
|
||||
),
|
||||
("op_metrics", op_sync(op_metrics)),
|
||||
("op_void_sync", void_op_sync()),
|
||||
("op_void_async", void_op_async()),
|
||||
// TODO(@AaronO): track IO metrics for builtin streams
|
||||
("op_read", op_async(op_read)),
|
||||
("op_write", op_async(op_write)),
|
||||
("op_shutdown", op_async(op_shutdown)),
|
||||
op_close::decl(),
|
||||
op_try_close::decl(),
|
||||
op_print::decl(),
|
||||
op_resources::decl(),
|
||||
op_wasm_streaming_feed::decl(),
|
||||
op_wasm_streaming_abort::decl(),
|
||||
op_wasm_streaming_set_url::decl(),
|
||||
op_void_sync::decl(),
|
||||
op_void_async::decl(),
|
||||
// // TODO(@AaronO): track IO metrics for builtin streams
|
||||
op_read::decl(),
|
||||
op_write::decl(),
|
||||
op_shutdown::decl(),
|
||||
op_metrics::decl(),
|
||||
])
|
||||
.build()
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn void_op_sync(_: &mut OpState, _: (), _: ()) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn void_op_async(
|
||||
_state: Rc<RefCell<OpState>>,
|
||||
_: (),
|
||||
_: (),
|
||||
) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Return map of resources with id as key
|
||||
/// and string representation as value.
|
||||
#[op]
|
||||
pub fn op_resources(
|
||||
state: &mut OpState,
|
||||
_: (),
|
||||
|
@ -60,7 +68,22 @@ pub fn op_resources(
|
|||
Ok(serialized_resources)
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_void_sync(_state: &mut OpState, _: (), _: ()) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub async fn op_void_async(
|
||||
_state: Rc<RefCell<OpState>>,
|
||||
_: (),
|
||||
_: (),
|
||||
) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Remove a resource from the resource table.
|
||||
#[op]
|
||||
pub fn op_close(
|
||||
state: &mut OpState,
|
||||
rid: Option<ResourceId>,
|
||||
|
@ -75,6 +98,7 @@ pub fn op_close(
|
|||
|
||||
/// Try to remove a resource from the resource table. If there is no resource
|
||||
/// with the specified `rid`, this is a no-op.
|
||||
#[op]
|
||||
pub fn op_try_close(
|
||||
state: &mut OpState,
|
||||
rid: Option<ResourceId>,
|
||||
|
@ -87,7 +111,19 @@ pub fn op_try_close(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_metrics(
|
||||
state: &mut OpState,
|
||||
_: (),
|
||||
_: (),
|
||||
) -> Result<(OpMetrics, Vec<OpMetrics>), Error> {
|
||||
let aggregate = state.tracker.aggregate();
|
||||
let per_op = state.tracker.per_op();
|
||||
Ok((aggregate, per_op))
|
||||
}
|
||||
|
||||
/// Builtin utility to print to stdout/stderr
|
||||
#[op]
|
||||
pub fn op_print(
|
||||
_state: &mut OpState,
|
||||
msg: String,
|
||||
|
@ -119,6 +155,7 @@ impl Resource for WasmStreamingResource {
|
|||
}
|
||||
|
||||
/// Feed bytes to WasmStreamingResource.
|
||||
#[op]
|
||||
pub fn op_wasm_streaming_feed(
|
||||
state: &mut OpState,
|
||||
rid: ResourceId,
|
||||
|
@ -133,6 +170,7 @@ pub fn op_wasm_streaming_feed(
|
|||
}
|
||||
|
||||
/// Abort a WasmStreamingResource.
|
||||
#[op]
|
||||
pub fn op_wasm_streaming_abort(
|
||||
state: &mut OpState,
|
||||
rid: ResourceId,
|
||||
|
@ -153,6 +191,7 @@ pub fn op_wasm_streaming_abort(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_wasm_streaming_set_url(
|
||||
state: &mut OpState,
|
||||
rid: ResourceId,
|
||||
|
@ -166,16 +205,7 @@ pub fn op_wasm_streaming_set_url(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn op_metrics(
|
||||
state: &mut OpState,
|
||||
_: (),
|
||||
_: (),
|
||||
) -> Result<(OpMetrics, Vec<OpMetrics>), Error> {
|
||||
let aggregate = state.tracker.aggregate();
|
||||
let per_op = state.tracker.per_op();
|
||||
Ok((aggregate, per_op))
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_read(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
rid: ResourceId,
|
||||
|
@ -185,6 +215,7 @@ async fn op_read(
|
|||
resource.read(buf).await.map(|n| n as u32)
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_write(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
rid: ResourceId,
|
||||
|
@ -194,6 +225,7 @@ async fn op_write(
|
|||
resource.write(buf).await.map(|n| n as u32)
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_shutdown(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
rid: ResourceId,
|
||||
|
|
166
core/ops_json.rs
166
core/ops_json.rs
|
@ -1,166 +0,0 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use crate::ops::OpCall;
|
||||
use crate::serialize_op_result;
|
||||
use crate::Op;
|
||||
use crate::OpFn;
|
||||
use crate::OpState;
|
||||
use anyhow::Error;
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::Serialize;
|
||||
use std::cell::RefCell;
|
||||
use std::future::Future;
|
||||
use std::rc::Rc;
|
||||
|
||||
/// A helper function that returns a sync NOP OpFn
|
||||
///
|
||||
/// It's mainly intended for embedders who want to disable ops, see ./examples/disable_ops.rs
|
||||
pub fn void_op_sync() -> Box<OpFn> {
|
||||
op_sync(|_, _: (), _: ()| Ok(()))
|
||||
}
|
||||
|
||||
/// A helper function that returns an async NOP OpFn
|
||||
///
|
||||
/// It's mainly intended for embedders who want to disable ops, see ./examples/disable_ops.rs
|
||||
pub fn void_op_async() -> Box<OpFn> {
|
||||
op_async(|_, _: (), _: ()| futures::future::ok(()))
|
||||
}
|
||||
|
||||
/// Creates an op that passes data synchronously using JSON.
|
||||
///
|
||||
/// The provided function `op_fn` has the following parameters:
|
||||
/// * `&mut OpState`: the op state, can be used to read/write resources in the runtime from an op.
|
||||
/// * `V`: the deserializable value that is passed to the Rust function.
|
||||
/// * `&mut [ZeroCopyBuf]`: raw bytes passed along, usually not needed if the JSON value is used.
|
||||
///
|
||||
/// `op_fn` returns a serializable value, which is directly returned to JavaScript.
|
||||
///
|
||||
/// When registering an op like this...
|
||||
/// ```ignore
|
||||
/// let mut runtime = JsRuntime::new(...);
|
||||
/// runtime.register_op("hello", deno_core::op_sync(Self::hello_op));
|
||||
/// runtime.sync_ops_cache();
|
||||
/// ```
|
||||
///
|
||||
/// ...it can be invoked from JS using the provided name, for example:
|
||||
/// ```js
|
||||
/// let result = Deno.core.opSync("hello", args);
|
||||
/// ```
|
||||
///
|
||||
/// `runtime.sync_ops_cache()` must be called after registering new ops
|
||||
/// A more complete example is available in the examples directory.
|
||||
pub fn op_sync<F, A, B, R>(op_fn: F) -> Box<OpFn>
|
||||
where
|
||||
F: Fn(&mut OpState, A, B) -> Result<R, Error> + 'static,
|
||||
A: DeserializeOwned,
|
||||
B: DeserializeOwned,
|
||||
R: Serialize + 'static,
|
||||
{
|
||||
Box::new(move |state, payload| -> Op {
|
||||
let result = payload
|
||||
.deserialize()
|
||||
.and_then(|(a, b)| op_fn(&mut state.borrow_mut(), a, b));
|
||||
Op::Sync(serialize_op_result(result, state))
|
||||
})
|
||||
}
|
||||
|
||||
/// Creates an op that passes data asynchronously using JSON.
|
||||
///
|
||||
/// When this op is dispatched, the runtime doesn't exit while processing it.
|
||||
///
|
||||
/// The provided function `op_fn` has the following parameters:
|
||||
/// * `Rc<RefCell<OpState>`: the op state, can be used to read/write resources in the runtime from an op.
|
||||
/// * `V`: the deserializable value that is passed to the Rust function.
|
||||
/// * `BufVec`: raw bytes passed along, usually not needed if the JSON value is used.
|
||||
///
|
||||
/// `op_fn` returns a future, whose output is a serializable value. This value will be asynchronously
|
||||
/// returned to JavaScript.
|
||||
///
|
||||
/// When registering an op like this...
|
||||
/// ```ignore
|
||||
/// let mut runtime = JsRuntime::new(...);
|
||||
/// runtime.register_op("hello", deno_core::op_async(Self::hello_op));
|
||||
/// runtime.sync_ops_cache();
|
||||
/// ```
|
||||
///
|
||||
/// ...it can be invoked from JS using the provided name, for example:
|
||||
/// ```js
|
||||
/// let future = Deno.core.opAsync("hello", args);
|
||||
/// ```
|
||||
///
|
||||
/// `runtime.sync_ops_cache()` must be called after registering new ops
|
||||
/// A more complete example is available in the examples directory.
|
||||
pub fn op_async<F, A, B, R, RV>(op_fn: F) -> Box<OpFn>
|
||||
where
|
||||
F: Fn(Rc<RefCell<OpState>>, A, B) -> R + 'static,
|
||||
A: DeserializeOwned,
|
||||
B: DeserializeOwned,
|
||||
R: Future<Output = Result<RV, Error>> + 'static,
|
||||
RV: Serialize + 'static,
|
||||
{
|
||||
Box::new(move |state, payload| -> Op {
|
||||
let op_id = payload.op_id;
|
||||
let pid = payload.promise_id;
|
||||
// Deserialize args, sync error on failure
|
||||
let args = match payload.deserialize() {
|
||||
Ok(args) => args,
|
||||
Err(err) => {
|
||||
return Op::Sync(serialize_op_result(Err::<(), Error>(err), state))
|
||||
}
|
||||
};
|
||||
let (a, b) = args;
|
||||
|
||||
use crate::futures::FutureExt;
|
||||
let fut = op_fn(state.clone(), a, b)
|
||||
.map(move |result| (pid, op_id, serialize_op_result(result, state)));
|
||||
Op::Async(OpCall::eager(fut))
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn op_async_stack_trace() {
|
||||
async fn op_throw(
|
||||
_state: Rc<RefCell<OpState>>,
|
||||
msg: Option<String>,
|
||||
_: (),
|
||||
) -> Result<(), Error> {
|
||||
assert_eq!(msg.unwrap(), "hello");
|
||||
Err(crate::error::generic_error("foo"))
|
||||
}
|
||||
|
||||
let ext = crate::Extension::builder()
|
||||
.ops(vec![("op_throw", op_async(op_throw))])
|
||||
.build();
|
||||
|
||||
let mut runtime = crate::JsRuntime::new(crate::RuntimeOptions {
|
||||
extensions: vec![ext],
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
runtime
|
||||
.execute_script(
|
||||
"<init>",
|
||||
r#"
|
||||
async function f1() {
|
||||
await Deno.core.opAsync('op_throw', 'hello');
|
||||
}
|
||||
|
||||
async function f2() {
|
||||
await f1();
|
||||
}
|
||||
|
||||
f2();
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
let e = runtime.run_event_loop(false).await.unwrap_err().to_string();
|
||||
println!("{}", e);
|
||||
assert!(e.contains("Error: foo"));
|
||||
assert!(e.contains("at async f1 (<init>:"));
|
||||
assert!(e.contains("at async f2 (<init>:"));
|
||||
}
|
||||
}
|
|
@ -59,20 +59,10 @@ impl OpsTracker {
|
|||
unsafe { &mut *self.ops.get() }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn ensure_capacity(ops: &mut Vec<OpMetrics>, op_id: OpId) {
|
||||
if op_id >= ops.len() {
|
||||
ops.resize(1 + op_id, OpMetrics::default())
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::mut_from_ref)]
|
||||
#[inline]
|
||||
fn metrics_mut(&self, id: OpId) -> &mut OpMetrics {
|
||||
let ops = self.ops_mut();
|
||||
// TODO(@AaronO): Pre-alloc capacity at runtime init once we forbid post-boot op registrations
|
||||
Self::ensure_capacity(ops, id);
|
||||
unsafe { ops.get_unchecked_mut(id) }
|
||||
unsafe { self.ops_mut().get_unchecked_mut(id) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
299
core/runtime.rs
299
core/runtime.rs
|
@ -6,6 +6,7 @@ use crate::error::generic_error;
|
|||
use crate::error::ErrWithV8Handle;
|
||||
use crate::error::JsError;
|
||||
use crate::extensions::OpEventLoopFn;
|
||||
use crate::extensions::OpPair;
|
||||
use crate::inspector::JsRuntimeInspector;
|
||||
use crate::module_specifier::ModuleSpecifier;
|
||||
use crate::modules::ModuleId;
|
||||
|
@ -16,13 +17,13 @@ use crate::modules::NoopModuleLoader;
|
|||
use crate::ops::*;
|
||||
use crate::Extension;
|
||||
use crate::OpMiddlewareFn;
|
||||
use crate::OpPayload;
|
||||
use crate::OpResult;
|
||||
use crate::OpState;
|
||||
use crate::PromiseId;
|
||||
use anyhow::Error;
|
||||
use futures::channel::oneshot;
|
||||
use futures::future::poll_fn;
|
||||
use futures::future::Future;
|
||||
use futures::future::FutureExt;
|
||||
use futures::stream::FuturesUnordered;
|
||||
use futures::stream::StreamExt;
|
||||
|
@ -143,7 +144,6 @@ pub type CompiledWasmModuleStore = CrossIsolateStore<v8::CompiledWasmModule>;
|
|||
pub(crate) struct JsRuntimeState {
|
||||
pub global_context: Option<v8::Global<v8::Context>>,
|
||||
pub(crate) js_recv_cb: Option<v8::Global<v8::Function>>,
|
||||
pub(crate) js_sync_cb: Option<v8::Global<v8::Function>>,
|
||||
pub(crate) js_macrotask_cbs: Vec<v8::Global<v8::Function>>,
|
||||
pub(crate) js_nexttick_cbs: Vec<v8::Global<v8::Function>>,
|
||||
pub(crate) js_promise_reject_cb: Option<v8::Global<v8::Function>>,
|
||||
|
@ -279,17 +279,37 @@ impl JsRuntime {
|
|||
|
||||
let has_startup_snapshot = options.startup_snapshot.is_some();
|
||||
|
||||
let js_error_create_fn = options
|
||||
.js_error_create_fn
|
||||
.unwrap_or_else(|| Rc::new(JsError::create));
|
||||
|
||||
// Add builtins extension
|
||||
options
|
||||
.extensions
|
||||
.insert(0, crate::ops_builtin::init_builtins());
|
||||
|
||||
let ops = Self::collect_ops(&mut options.extensions);
|
||||
let mut op_state = OpState::new(ops.len());
|
||||
|
||||
if let Some(get_error_class_fn) = options.get_error_class_fn {
|
||||
op_state.get_error_class_fn = get_error_class_fn;
|
||||
}
|
||||
|
||||
let op_state = Rc::new(RefCell::new(op_state));
|
||||
|
||||
let refs = bindings::external_references(&ops, op_state.clone());
|
||||
let refs: &'static v8::ExternalReferences = Box::leak(Box::new(refs));
|
||||
let global_context;
|
||||
let (mut isolate, maybe_snapshot_creator) = if options.will_snapshot {
|
||||
// TODO(ry) Support loading snapshots before snapshotting.
|
||||
assert!(options.startup_snapshot.is_none());
|
||||
let mut creator =
|
||||
v8::SnapshotCreator::new(Some(&bindings::EXTERNAL_REFERENCES));
|
||||
let mut creator = v8::SnapshotCreator::new(Some(refs));
|
||||
let isolate = unsafe { creator.get_owned_isolate() };
|
||||
let mut isolate = JsRuntime::setup_isolate(isolate);
|
||||
{
|
||||
let scope = &mut v8::HandleScope::new(&mut isolate);
|
||||
let context = bindings::initialize_context(scope);
|
||||
let context =
|
||||
bindings::initialize_context(scope, &ops, false, op_state.clone());
|
||||
global_context = v8::Global::new(scope, context);
|
||||
creator.set_default_context(context);
|
||||
}
|
||||
|
@ -299,7 +319,7 @@ impl JsRuntime {
|
|||
.create_params
|
||||
.take()
|
||||
.unwrap_or_else(v8::Isolate::create_params)
|
||||
.external_references(&**bindings::EXTERNAL_REFERENCES);
|
||||
.external_references(&**refs);
|
||||
let snapshot_loaded = if let Some(snapshot) = options.startup_snapshot {
|
||||
params = match snapshot {
|
||||
Snapshot::Static(data) => params.snapshot_blob(data),
|
||||
|
@ -315,13 +335,13 @@ impl JsRuntime {
|
|||
let mut isolate = JsRuntime::setup_isolate(isolate);
|
||||
{
|
||||
let scope = &mut v8::HandleScope::new(&mut isolate);
|
||||
let context = if snapshot_loaded {
|
||||
v8::Context::new(scope)
|
||||
} else {
|
||||
// If no snapshot is provided, we initialize the context with empty
|
||||
// main source code and source maps.
|
||||
bindings::initialize_context(scope)
|
||||
};
|
||||
let context = bindings::initialize_context(
|
||||
scope,
|
||||
&ops,
|
||||
snapshot_loaded,
|
||||
op_state.clone(),
|
||||
);
|
||||
|
||||
global_context = v8::Global::new(scope, context);
|
||||
}
|
||||
(isolate, None)
|
||||
|
@ -334,17 +354,6 @@ impl JsRuntime {
|
|||
.module_loader
|
||||
.unwrap_or_else(|| Rc::new(NoopModuleLoader));
|
||||
|
||||
let js_error_create_fn = options
|
||||
.js_error_create_fn
|
||||
.unwrap_or_else(|| Rc::new(JsError::create));
|
||||
let mut op_state = OpState::new();
|
||||
|
||||
if let Some(get_error_class_fn) = options.get_error_class_fn {
|
||||
op_state.get_error_class_fn = get_error_class_fn;
|
||||
}
|
||||
|
||||
let op_state = Rc::new(RefCell::new(op_state));
|
||||
|
||||
isolate.set_slot(Rc::new(RefCell::new(JsRuntimeState {
|
||||
global_context: Some(global_context),
|
||||
pending_promise_exceptions: HashMap::new(),
|
||||
|
@ -352,7 +361,6 @@ impl JsRuntime {
|
|||
pending_mod_evaluate: None,
|
||||
dyn_module_evaluate_idle_counter: 0,
|
||||
js_recv_cb: None,
|
||||
js_sync_cb: None,
|
||||
js_macrotask_cbs: vec![],
|
||||
js_nexttick_cbs: vec![],
|
||||
js_promise_reject_cb: None,
|
||||
|
@ -372,11 +380,6 @@ impl JsRuntime {
|
|||
let module_map = ModuleMap::new(loader, op_state);
|
||||
isolate.set_slot(Rc::new(RefCell::new(module_map)));
|
||||
|
||||
// Add builtins extension
|
||||
options
|
||||
.extensions
|
||||
.insert(0, crate::ops_builtin::init_builtins());
|
||||
|
||||
let mut js_runtime = Self {
|
||||
v8_isolate: Some(isolate),
|
||||
inspector: Some(inspector),
|
||||
|
@ -394,10 +397,8 @@ impl JsRuntime {
|
|||
}
|
||||
// Init extension ops
|
||||
js_runtime.init_extension_ops().unwrap();
|
||||
// Init callbacks (opresolve & syncOpsCache)
|
||||
// Init callbacks (opresolve)
|
||||
js_runtime.init_cbs();
|
||||
// Sync ops cache
|
||||
js_runtime.sync_ops_cache();
|
||||
|
||||
js_runtime
|
||||
}
|
||||
|
@ -461,34 +462,44 @@ impl JsRuntime {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Collects ops from extensions & applies middleware
|
||||
fn collect_ops(extensions: &mut [Extension]) -> Vec<OpPair> {
|
||||
// Middleware
|
||||
let middleware: Vec<Box<OpMiddlewareFn>> = extensions
|
||||
.iter_mut()
|
||||
.filter_map(|e| e.init_middleware())
|
||||
.collect();
|
||||
|
||||
// macroware wraps an opfn in all the middleware
|
||||
let macroware =
|
||||
move |name, opfn| middleware.iter().fold(opfn, |opfn, m| m(name, opfn));
|
||||
|
||||
// Flatten ops & apply middlware
|
||||
extensions
|
||||
.iter_mut()
|
||||
.filter_map(|e| e.init_ops())
|
||||
.flatten()
|
||||
.map(|(name, opfn)| (name, macroware(name, opfn)))
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Initializes ops of provided Extensions
|
||||
fn init_extension_ops(&mut self) -> Result<(), Error> {
|
||||
let op_state = self.op_state();
|
||||
// Take extensions to avoid double-borrow
|
||||
let mut extensions: Vec<Extension> = std::mem::take(&mut self.extensions);
|
||||
|
||||
// Middleware
|
||||
let middleware: Vec<Box<OpMiddlewareFn>> = extensions
|
||||
.iter_mut()
|
||||
.filter_map(|e| e.init_middleware())
|
||||
.collect();
|
||||
// macroware wraps an opfn in all the middleware
|
||||
let macroware =
|
||||
move |name, opfn| middleware.iter().fold(opfn, |opfn, m| m(name, opfn));
|
||||
|
||||
// Register ops
|
||||
// Setup state
|
||||
for e in extensions.iter_mut() {
|
||||
// ops are already registered during in bindings::initialize_context();
|
||||
e.init_state(&mut op_state.borrow_mut())?;
|
||||
// Register each op after middlewaring it
|
||||
let ops = e.init_ops().unwrap_or_default();
|
||||
for (name, opfn) in ops {
|
||||
self.register_op(name, macroware(name, opfn));
|
||||
}
|
||||
|
||||
// Setup event-loop middleware
|
||||
if let Some(middleware) = e.init_event_loop_middleware() {
|
||||
self.event_loop_middlewares.push(middleware);
|
||||
}
|
||||
}
|
||||
|
||||
// Restore extensions
|
||||
self.extensions = extensions;
|
||||
|
||||
|
@ -511,22 +522,10 @@ impl JsRuntime {
|
|||
fn init_cbs(&mut self) {
|
||||
let mut scope = self.handle_scope();
|
||||
let recv_cb = Self::grab_fn(&mut scope, "Deno.core.opresolve");
|
||||
let sync_cb = Self::grab_fn(&mut scope, "Deno.core.syncOpsCache");
|
||||
// Put global handles in state
|
||||
let state_rc = JsRuntime::state(&scope);
|
||||
let mut state = state_rc.borrow_mut();
|
||||
state.js_recv_cb.replace(recv_cb);
|
||||
state.js_sync_cb.replace(sync_cb);
|
||||
}
|
||||
|
||||
/// Ensures core.js has the latest op-name to op-id mappings
|
||||
pub fn sync_ops_cache(&mut self) {
|
||||
let scope = &mut self.handle_scope();
|
||||
let state_rc = JsRuntime::state(scope);
|
||||
let js_sync_cb_handle = state_rc.borrow().js_sync_cb.clone().unwrap();
|
||||
let js_sync_cb = js_sync_cb_handle.open(scope);
|
||||
let this = v8::undefined(scope).into();
|
||||
js_sync_cb.call(scope, this, &[]);
|
||||
}
|
||||
|
||||
/// Returns the runtime's op state, which can be used to maintain ops
|
||||
|
@ -612,7 +611,6 @@ impl JsRuntime {
|
|||
))));
|
||||
// Drop other v8::Global handles before snapshotting
|
||||
std::mem::take(&mut state.borrow_mut().js_recv_cb);
|
||||
std::mem::take(&mut state.borrow_mut().js_sync_cb);
|
||||
|
||||
let snapshot_creator = self.snapshot_creator.as_mut().unwrap();
|
||||
let snapshot = snapshot_creator
|
||||
|
@ -623,27 +621,6 @@ impl JsRuntime {
|
|||
snapshot
|
||||
}
|
||||
|
||||
/// Registers an op that can be called from JavaScript.
|
||||
///
|
||||
/// The _op_ mechanism allows to expose Rust functions to the JS runtime,
|
||||
/// which can be called using the provided `name`.
|
||||
///
|
||||
/// This function provides byte-level bindings. To pass data via JSON, the
|
||||
/// following functions can be passed as an argument for `op_fn`:
|
||||
/// * [op_sync()](fn.op_sync.html)
|
||||
/// * [op_async()](fn.op_async.html)
|
||||
pub fn register_op<F>(&mut self, name: &str, op_fn: F) -> OpId
|
||||
where
|
||||
F: Fn(Rc<RefCell<OpState>>, OpPayload) -> Op + 'static,
|
||||
{
|
||||
Self::state(self.v8_isolate())
|
||||
.borrow_mut()
|
||||
.op_state
|
||||
.borrow_mut()
|
||||
.op_table
|
||||
.register_op(name, op_fn)
|
||||
}
|
||||
|
||||
/// Registers a callback on the isolate when the memory limits are approached.
|
||||
/// Use this to prevent V8 from crashing the process when reaching the limit.
|
||||
///
|
||||
|
@ -1552,13 +1529,11 @@ impl JsRuntime {
|
|||
let mut state = state_rc.borrow_mut();
|
||||
state.have_unpolled_ops = false;
|
||||
|
||||
let op_state = state.op_state.clone();
|
||||
|
||||
while let Poll::Ready(Some(item)) = state.pending_ops.poll_next_unpin(cx)
|
||||
{
|
||||
let (promise_id, op_id, resp) = item;
|
||||
op_state.borrow().tracker.track_async_completed(op_id);
|
||||
state.unrefed_ops.remove(&promise_id);
|
||||
state.op_state.borrow().tracker.track_async_completed(op_id);
|
||||
args.push(v8::Integer::new(scope, promise_id as i32).into());
|
||||
args.push(resp.to_v8(scope).unwrap());
|
||||
}
|
||||
|
@ -1654,22 +1629,37 @@ impl JsRuntime {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn queue_async_op(
|
||||
scope: &v8::Isolate,
|
||||
op: impl Future<Output = (PromiseId, OpId, OpResult)> + 'static,
|
||||
) {
|
||||
let state_rc = JsRuntime::state(scope);
|
||||
let mut state = state_rc.borrow_mut();
|
||||
state.pending_ops.push(OpCall::eager(op));
|
||||
state.have_unpolled_ops = true;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod tests {
|
||||
use super::*;
|
||||
use crate::error::custom_error;
|
||||
use crate::error::AnyError;
|
||||
use crate::modules::ModuleSource;
|
||||
use crate::modules::ModuleSourceFuture;
|
||||
use crate::modules::ModuleType;
|
||||
use crate::op_async;
|
||||
use crate::op_sync;
|
||||
use crate::ZeroCopyBuf;
|
||||
use deno_ops::op;
|
||||
use futures::future::lazy;
|
||||
use std::ops::FnOnce;
|
||||
use std::pin::Pin;
|
||||
use std::rc::Rc;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::sync::Arc;
|
||||
// deno_ops macros generate code assuming deno_core in scope.
|
||||
mod deno_core {
|
||||
pub use crate::*;
|
||||
}
|
||||
|
||||
pub fn run_in_task<F>(f: F)
|
||||
where
|
||||
|
@ -1689,26 +1679,26 @@ pub mod tests {
|
|||
dispatch_count: Arc<AtomicUsize>,
|
||||
}
|
||||
|
||||
fn op_test(rc_op_state: Rc<RefCell<OpState>>, payload: OpPayload) -> Op {
|
||||
let rc_op_state2 = rc_op_state.clone();
|
||||
let op_state_ = rc_op_state2.borrow();
|
||||
#[op]
|
||||
async fn op_test(
|
||||
rc_op_state: Rc<RefCell<OpState>>,
|
||||
control: u8,
|
||||
buf: Option<ZeroCopyBuf>,
|
||||
) -> Result<u8, AnyError> {
|
||||
let op_state_ = rc_op_state.borrow();
|
||||
let test_state = op_state_.borrow::<TestState>();
|
||||
test_state.dispatch_count.fetch_add(1, Ordering::Relaxed);
|
||||
let (control, buf): (u8, Option<ZeroCopyBuf>) =
|
||||
payload.deserialize().unwrap();
|
||||
match test_state.mode {
|
||||
Mode::Async => {
|
||||
assert_eq!(control, 42);
|
||||
let resp = (0, 1, serialize_op_result(Ok(43), rc_op_state));
|
||||
Op::Async(OpCall::ready(resp))
|
||||
Ok(43)
|
||||
}
|
||||
Mode::AsyncZeroCopy(has_buffer) => {
|
||||
assert_eq!(buf.is_some(), has_buffer);
|
||||
if let Some(buf) = buf {
|
||||
assert_eq!(buf.len(), 1);
|
||||
}
|
||||
let resp = (0, 1, serialize_op_result(Ok(43), rc_op_state));
|
||||
Op::Async(OpCall::ready(resp))
|
||||
Ok(43)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1717,7 +1707,7 @@ pub mod tests {
|
|||
let dispatch_count = Arc::new(AtomicUsize::new(0));
|
||||
let dispatch_count2 = dispatch_count.clone();
|
||||
let ext = Extension::builder()
|
||||
.ops(vec![("op_test", Box::new(op_test))])
|
||||
.ops(vec![op_test::decl()])
|
||||
.state(move |state| {
|
||||
state.put(TestState {
|
||||
mode,
|
||||
|
@ -2027,30 +2017,6 @@ pub mod tests {
|
|||
v8_isolate_handle.terminate_execution();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pre_dispatch() {
|
||||
run_in_task(|cx| {
|
||||
let (mut runtime, _dispatch_count) = setup(Mode::Async);
|
||||
runtime
|
||||
.execute_script(
|
||||
"bad_op_id.js",
|
||||
r#"
|
||||
let thrown;
|
||||
try {
|
||||
Deno.core.opcallSync(100, null, null);
|
||||
} catch (e) {
|
||||
thrown = e;
|
||||
}
|
||||
assert(String(thrown) === "TypeError: Unknown op id: 100");
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
if let Poll::Ready(Err(_)) = runtime.poll_event_loop(cx, false) {
|
||||
unreachable!();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn syntax_error() {
|
||||
let mut runtime = JsRuntime::new(Default::default());
|
||||
|
@ -2095,6 +2061,7 @@ pub mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_error_builder() {
|
||||
#[op]
|
||||
fn op_err(_: &mut OpState, _: (), _: ()) -> Result<(), Error> {
|
||||
Err(custom_error("DOMExceptionOperationError", "abc"))
|
||||
}
|
||||
|
@ -2104,9 +2071,7 @@ pub mod tests {
|
|||
}
|
||||
|
||||
run_in_task(|cx| {
|
||||
let ext = Extension::builder()
|
||||
.ops(vec![("op_err", op_sync(op_err))])
|
||||
.build();
|
||||
let ext = Extension::builder().ops(vec![op_err::decl()]).build();
|
||||
let mut runtime = JsRuntime::new(RuntimeOptions {
|
||||
extensions: vec![ext],
|
||||
get_error_class_fn: Some(&get_error_class_name),
|
||||
|
@ -2177,7 +2142,7 @@ pub mod tests {
|
|||
});
|
||||
let cb_handle = runtime.v8_isolate().thread_safe_handle();
|
||||
|
||||
let callback_invoke_count = Rc::new(AtomicUsize::default());
|
||||
let callback_invoke_count = Rc::new(AtomicUsize::new(0));
|
||||
let inner_invoke_count = Rc::clone(&callback_invoke_count);
|
||||
|
||||
runtime.add_near_heap_limit_callback(
|
||||
|
@ -2221,7 +2186,7 @@ pub mod tests {
|
|||
});
|
||||
let cb_handle = runtime.v8_isolate().thread_safe_handle();
|
||||
|
||||
let callback_invoke_count_first = Rc::new(AtomicUsize::default());
|
||||
let callback_invoke_count_first = Rc::new(AtomicUsize::new(0));
|
||||
let inner_invoke_count_first = Rc::clone(&callback_invoke_count_first);
|
||||
runtime.add_near_heap_limit_callback(
|
||||
move |current_limit, _initial_limit| {
|
||||
|
@ -2230,7 +2195,7 @@ pub mod tests {
|
|||
},
|
||||
);
|
||||
|
||||
let callback_invoke_count_second = Rc::new(AtomicUsize::default());
|
||||
let callback_invoke_count_second = Rc::new(AtomicUsize::new(0));
|
||||
let inner_invoke_count_second = Rc::clone(&callback_invoke_count_second);
|
||||
runtime.add_near_heap_limit_callback(
|
||||
move |current_limit, _initial_limit| {
|
||||
|
@ -2500,6 +2465,7 @@ assertEquals(1, notify_return_value);
|
|||
async fn test_async_opstate_borrow() {
|
||||
struct InnerState(u64);
|
||||
|
||||
#[op]
|
||||
async fn op_async_borrow(
|
||||
op_state: Rc<RefCell<OpState>>,
|
||||
_: (),
|
||||
|
@ -2519,7 +2485,7 @@ assertEquals(1, notify_return_value);
|
|||
}
|
||||
|
||||
let extension = Extension::builder()
|
||||
.ops(vec![("op_async_borrow", op_async(op_async_borrow))])
|
||||
.ops(vec![op_async_borrow::decl()])
|
||||
.state(|state| {
|
||||
state.put(InnerState(42));
|
||||
Ok(())
|
||||
|
@ -2542,6 +2508,7 @@ assertEquals(1, notify_return_value);
|
|||
|
||||
#[tokio::test]
|
||||
async fn test_set_macrotask_callback_set_next_tick_callback() {
|
||||
#[op]
|
||||
async fn op_async_sleep(
|
||||
_op_state: Rc<RefCell<OpState>>,
|
||||
_: (),
|
||||
|
@ -2553,7 +2520,7 @@ assertEquals(1, notify_return_value);
|
|||
}
|
||||
|
||||
let extension = Extension::builder()
|
||||
.ops(vec![("op_async_sleep", op_async(op_async_sleep))])
|
||||
.ops(vec![op_async_sleep::decl()])
|
||||
.build();
|
||||
|
||||
let mut runtime = JsRuntime::new(RuntimeOptions {
|
||||
|
@ -2617,25 +2584,23 @@ assertEquals(1, notify_return_value);
|
|||
fn test_has_tick_scheduled() {
|
||||
use futures::task::ArcWake;
|
||||
|
||||
let macrotask = Arc::new(AtomicUsize::default());
|
||||
let macrotask_ = Arc::clone(¯otask);
|
||||
static MACROTASK: AtomicUsize = AtomicUsize::new(0);
|
||||
static NEXT_TICK: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
let next_tick = Arc::new(AtomicUsize::default());
|
||||
let next_tick_ = Arc::clone(&next_tick);
|
||||
|
||||
let op_macrotask = move |_: &mut OpState, _: (), _: ()| {
|
||||
macrotask_.fetch_add(1, Ordering::Relaxed);
|
||||
#[op]
|
||||
fn op_macrotask(_: &mut OpState, _: (), _: ()) -> Result<(), AnyError> {
|
||||
MACROTASK.fetch_add(1, Ordering::Relaxed);
|
||||
Ok(())
|
||||
};
|
||||
}
|
||||
|
||||
let op_next_tick = move |_: &mut OpState, _: (), _: ()| {
|
||||
next_tick_.fetch_add(1, Ordering::Relaxed);
|
||||
#[op]
|
||||
fn op_next_tick(_: &mut OpState, _: (), _: ()) -> Result<(), AnyError> {
|
||||
NEXT_TICK.fetch_add(1, Ordering::Relaxed);
|
||||
Ok(())
|
||||
};
|
||||
}
|
||||
|
||||
let extension = Extension::builder()
|
||||
.ops(vec![("op_macrotask", op_sync(op_macrotask))])
|
||||
.ops(vec![("op_next_tick", op_sync(op_next_tick))])
|
||||
.ops(vec![op_macrotask::decl(), op_next_tick::decl()])
|
||||
.build();
|
||||
|
||||
let mut runtime = JsRuntime::new(RuntimeOptions {
|
||||
|
@ -2670,8 +2635,8 @@ assertEquals(1, notify_return_value);
|
|||
let cx = &mut Context::from_waker(&waker);
|
||||
|
||||
assert!(matches!(runtime.poll_event_loop(cx, false), Poll::Pending));
|
||||
assert_eq!(1, macrotask.load(Ordering::Relaxed));
|
||||
assert_eq!(1, next_tick.load(Ordering::Relaxed));
|
||||
assert_eq!(1, MACROTASK.load(Ordering::Relaxed));
|
||||
assert_eq!(1, NEXT_TICK.load(Ordering::Relaxed));
|
||||
assert_eq!(awoken_times.swap(0, Ordering::Relaxed), 1);
|
||||
assert!(matches!(runtime.poll_event_loop(cx, false), Poll::Pending));
|
||||
assert_eq!(awoken_times.swap(0, Ordering::Relaxed), 1);
|
||||
|
@ -2756,28 +2721,34 @@ assertEquals(1, notify_return_value);
|
|||
|
||||
#[tokio::test]
|
||||
async fn test_set_promise_reject_callback() {
|
||||
let promise_reject = Arc::new(AtomicUsize::default());
|
||||
let promise_reject_ = Arc::clone(&promise_reject);
|
||||
static PROMISE_REJECT: AtomicUsize = AtomicUsize::new(0);
|
||||
static UNCAUGHT_EXCEPTION: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
let uncaught_exception = Arc::new(AtomicUsize::default());
|
||||
let uncaught_exception_ = Arc::clone(&uncaught_exception);
|
||||
|
||||
let op_promise_reject = move |_: &mut OpState, _: (), _: ()| {
|
||||
promise_reject_.fetch_add(1, Ordering::Relaxed);
|
||||
#[op]
|
||||
fn op_promise_reject(
|
||||
_: &mut OpState,
|
||||
_: (),
|
||||
_: (),
|
||||
) -> Result<(), AnyError> {
|
||||
PROMISE_REJECT.fetch_add(1, Ordering::Relaxed);
|
||||
Ok(())
|
||||
};
|
||||
}
|
||||
|
||||
let op_uncaught_exception = move |_: &mut OpState, _: (), _: ()| {
|
||||
uncaught_exception_.fetch_add(1, Ordering::Relaxed);
|
||||
#[op]
|
||||
fn op_uncaught_exception(
|
||||
_: &mut OpState,
|
||||
_: (),
|
||||
_: (),
|
||||
) -> Result<(), AnyError> {
|
||||
UNCAUGHT_EXCEPTION.fetch_add(1, Ordering::Relaxed);
|
||||
Ok(())
|
||||
};
|
||||
}
|
||||
|
||||
let extension = Extension::builder()
|
||||
.ops(vec![("op_promise_reject", op_sync(op_promise_reject))])
|
||||
.ops(vec![(
|
||||
"op_uncaught_exception",
|
||||
op_sync(op_uncaught_exception),
|
||||
)])
|
||||
.ops(vec![
|
||||
op_promise_reject::decl(),
|
||||
op_uncaught_exception::decl(),
|
||||
])
|
||||
.build();
|
||||
|
||||
let mut runtime = JsRuntime::new(RuntimeOptions {
|
||||
|
@ -2812,8 +2783,8 @@ assertEquals(1, notify_return_value);
|
|||
.unwrap();
|
||||
runtime.run_event_loop(false).await.unwrap();
|
||||
|
||||
assert_eq!(1, promise_reject.load(Ordering::Relaxed));
|
||||
assert_eq!(1, uncaught_exception.load(Ordering::Relaxed));
|
||||
assert_eq!(1, PROMISE_REJECT.load(Ordering::Relaxed));
|
||||
assert_eq!(1, UNCAUGHT_EXCEPTION.load(Ordering::Relaxed));
|
||||
|
||||
runtime
|
||||
.execute_script(
|
||||
|
@ -2840,7 +2811,7 @@ assertEquals(1, notify_return_value);
|
|||
// printed to stderr.
|
||||
runtime.run_event_loop(false).await.unwrap();
|
||||
|
||||
assert_eq!(2, promise_reject.load(Ordering::Relaxed));
|
||||
assert_eq!(2, uncaught_exception.load(Ordering::Relaxed));
|
||||
assert_eq!(2, PROMISE_REJECT.load(Ordering::Relaxed));
|
||||
assert_eq!(2, UNCAUGHT_EXCEPTION.load(Ordering::Relaxed));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,8 +8,7 @@ pub use in_memory_broadcast_channel::InMemoryBroadcastChannelResource;
|
|||
use async_trait::async_trait;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::include_js_files;
|
||||
use deno_core::op_async;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::op;
|
||||
use deno_core::Extension;
|
||||
use deno_core::OpState;
|
||||
use deno_core::Resource;
|
||||
|
@ -43,11 +42,15 @@ pub type Message = (String, Vec<u8>);
|
|||
|
||||
struct Unstable(bool); // --unstable
|
||||
|
||||
pub fn op_broadcast_subscribe<BC: BroadcastChannel + 'static>(
|
||||
#[op]
|
||||
pub fn op_broadcast_subscribe<BC>(
|
||||
state: &mut OpState,
|
||||
_: (),
|
||||
_: (),
|
||||
) -> Result<ResourceId, AnyError> {
|
||||
) -> Result<ResourceId, AnyError>
|
||||
where
|
||||
BC: BroadcastChannel + 'static,
|
||||
{
|
||||
let unstable = state.borrow::<Unstable>().0;
|
||||
|
||||
if !unstable {
|
||||
|
@ -62,31 +65,43 @@ pub fn op_broadcast_subscribe<BC: BroadcastChannel + 'static>(
|
|||
Ok(state.resource_table.add(resource))
|
||||
}
|
||||
|
||||
pub fn op_broadcast_unsubscribe<BC: BroadcastChannel + 'static>(
|
||||
#[op]
|
||||
pub fn op_broadcast_unsubscribe<BC>(
|
||||
state: &mut OpState,
|
||||
rid: ResourceId,
|
||||
_buf: (),
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), AnyError>
|
||||
where
|
||||
BC: BroadcastChannel + 'static,
|
||||
{
|
||||
let resource = state.resource_table.get::<BC::Resource>(rid)?;
|
||||
let bc = state.borrow::<BC>();
|
||||
bc.unsubscribe(&resource)
|
||||
}
|
||||
|
||||
pub async fn op_broadcast_send<BC: BroadcastChannel + 'static>(
|
||||
#[op]
|
||||
pub async fn op_broadcast_send<BC>(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
(rid, name): (ResourceId, String),
|
||||
buf: ZeroCopyBuf,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), AnyError>
|
||||
where
|
||||
BC: BroadcastChannel + 'static,
|
||||
{
|
||||
let resource = state.borrow().resource_table.get::<BC::Resource>(rid)?;
|
||||
let bc = state.borrow().borrow::<BC>().clone();
|
||||
bc.send(&resource, name, buf.to_vec()).await
|
||||
}
|
||||
|
||||
pub async fn op_broadcast_recv<BC: BroadcastChannel + 'static>(
|
||||
#[op]
|
||||
pub async fn op_broadcast_recv<BC>(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
rid: ResourceId,
|
||||
_: (),
|
||||
) -> Result<Option<Message>, AnyError> {
|
||||
) -> Result<Option<Message>, AnyError>
|
||||
where
|
||||
BC: BroadcastChannel + 'static,
|
||||
{
|
||||
let resource = state.borrow().resource_table.get::<BC::Resource>(rid)?;
|
||||
let bc = state.borrow().borrow::<BC>().clone();
|
||||
bc.recv(&resource).await
|
||||
|
@ -102,16 +117,10 @@ pub fn init<BC: BroadcastChannel + 'static>(
|
|||
"01_broadcast_channel.js",
|
||||
))
|
||||
.ops(vec![
|
||||
(
|
||||
"op_broadcast_subscribe",
|
||||
op_sync(op_broadcast_subscribe::<BC>),
|
||||
),
|
||||
(
|
||||
"op_broadcast_unsubscribe",
|
||||
op_sync(op_broadcast_unsubscribe::<BC>),
|
||||
),
|
||||
("op_broadcast_send", op_async(op_broadcast_send::<BC>)),
|
||||
("op_broadcast_recv", op_async(op_broadcast_recv::<BC>)),
|
||||
op_broadcast_subscribe::decl::<BC>(),
|
||||
op_broadcast_unsubscribe::decl::<BC>(),
|
||||
op_broadcast_send::decl::<BC>(),
|
||||
op_broadcast_recv::decl::<BC>(),
|
||||
])
|
||||
.state(move |state| {
|
||||
state.put(bc.clone());
|
||||
|
|
|
@ -24,6 +24,7 @@ use ctr::Ctr;
|
|||
use deno_core::error::custom_error;
|
||||
use deno_core::error::type_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op;
|
||||
use deno_core::OpState;
|
||||
use deno_core::ZeroCopyBuf;
|
||||
use rsa::pkcs1::FromRsaPrivateKey;
|
||||
|
@ -76,6 +77,7 @@ pub enum DecryptAlgorithm {
|
|||
},
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub async fn op_crypto_decrypt(
|
||||
_state: Rc<RefCell<OpState>>,
|
||||
opts: DecryptOptions,
|
||||
|
|
|
@ -16,6 +16,7 @@ use aes_gcm::AeadInPlace;
|
|||
use aes_gcm::NewAead;
|
||||
use aes_gcm::Nonce;
|
||||
use ctr::Ctr;
|
||||
use deno_core::op;
|
||||
|
||||
use block_modes::BlockMode;
|
||||
use ctr::cipher::StreamCipher;
|
||||
|
@ -79,6 +80,8 @@ pub enum EncryptAlgorithm {
|
|||
key_length: usize,
|
||||
},
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub async fn op_crypto_encrypt(
|
||||
_state: Rc<RefCell<OpState>>,
|
||||
opts: EncryptOptions,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use deno_core::error::custom_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op;
|
||||
use deno_core::OpState;
|
||||
use deno_core::ZeroCopyBuf;
|
||||
use rsa::pkcs1::UIntBytes;
|
||||
|
@ -84,6 +85,7 @@ pub enum ExportKeyResult {
|
|||
},
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_crypto_export_key(
|
||||
_state: &mut OpState,
|
||||
opts: ExportKeyOptions,
|
||||
|
|
|
@ -3,6 +3,7 @@ use std::rc::Rc;
|
|||
|
||||
use crate::shared::*;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op;
|
||||
use deno_core::OpState;
|
||||
use deno_core::ZeroCopyBuf;
|
||||
use elliptic_curve::rand_core::OsRng;
|
||||
|
@ -41,6 +42,7 @@ pub enum GenerateKeyOptions {
|
|||
},
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub async fn op_crypto_generate_key(
|
||||
_state: Rc<RefCell<OpState>>,
|
||||
opts: GenerateKeyOptions,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use deno_core::error::AnyError;
|
||||
use deno_core::op;
|
||||
use deno_core::OpState;
|
||||
use deno_core::ZeroCopyBuf;
|
||||
use elliptic_curve::pkcs8::der::Decodable as Pkcs8Decodable;
|
||||
|
@ -81,11 +82,13 @@ pub enum ImportKeyResult {
|
|||
#[serde(rename_all = "camelCase")]
|
||||
Ec { raw_data: RawKeyData },
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[allow(dead_code)]
|
||||
Aes { raw_data: RawKeyData },
|
||||
#[serde(rename_all = "camelCase")]
|
||||
Hmac { raw_data: RawKeyData },
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_crypto_import_key(
|
||||
_state: &mut OpState,
|
||||
opts: ImportKeyOptions,
|
||||
|
|
|
@ -9,8 +9,8 @@ use deno_core::error::not_supported;
|
|||
use deno_core::error::type_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::include_js_files;
|
||||
use deno_core::op_async;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::op;
|
||||
|
||||
use deno_core::Extension;
|
||||
use deno_core::OpState;
|
||||
use deno_core::ZeroCopyBuf;
|
||||
|
@ -88,22 +88,19 @@ pub fn init(maybe_seed: Option<u64>) -> Extension {
|
|||
"01_webidl.js",
|
||||
))
|
||||
.ops(vec![
|
||||
(
|
||||
"op_crypto_get_random_values",
|
||||
op_sync(op_crypto_get_random_values),
|
||||
),
|
||||
("op_crypto_generate_key", op_async(op_crypto_generate_key)),
|
||||
("op_crypto_sign_key", op_async(op_crypto_sign_key)),
|
||||
("op_crypto_verify_key", op_async(op_crypto_verify_key)),
|
||||
("op_crypto_derive_bits", op_async(op_crypto_derive_bits)),
|
||||
("op_crypto_import_key", op_sync(op_crypto_import_key)),
|
||||
("op_crypto_export_key", op_sync(op_crypto_export_key)),
|
||||
("op_crypto_encrypt", op_async(op_crypto_encrypt)),
|
||||
("op_crypto_decrypt", op_async(op_crypto_decrypt)),
|
||||
("op_crypto_subtle_digest", op_async(op_crypto_subtle_digest)),
|
||||
("op_crypto_random_uuid", op_sync(op_crypto_random_uuid)),
|
||||
("op_crypto_wrap_key", op_sync(op_crypto_wrap_key)),
|
||||
("op_crypto_unwrap_key", op_sync(op_crypto_unwrap_key)),
|
||||
op_crypto_get_random_values::decl(),
|
||||
op_crypto_generate_key::decl(),
|
||||
op_crypto_sign_key::decl(),
|
||||
op_crypto_verify_key::decl(),
|
||||
op_crypto_derive_bits::decl(),
|
||||
op_crypto_import_key::decl(),
|
||||
op_crypto_export_key::decl(),
|
||||
op_crypto_encrypt::decl(),
|
||||
op_crypto_decrypt::decl(),
|
||||
op_crypto_subtle_digest::decl(),
|
||||
op_crypto_random_uuid::decl(),
|
||||
op_crypto_wrap_key::decl(),
|
||||
op_crypto_unwrap_key::decl(),
|
||||
])
|
||||
.state(move |state| {
|
||||
if let Some(seed) = maybe_seed {
|
||||
|
@ -114,6 +111,7 @@ pub fn init(maybe_seed: Option<u64>) -> Extension {
|
|||
.build()
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_crypto_get_random_values(
|
||||
state: &mut OpState,
|
||||
mut zero_copy: ZeroCopyBuf,
|
||||
|
@ -170,6 +168,7 @@ pub struct SignArg {
|
|||
named_curve: Option<CryptoNamedCurve>,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub async fn op_crypto_sign_key(
|
||||
_state: Rc<RefCell<OpState>>,
|
||||
args: SignArg,
|
||||
|
@ -324,6 +323,7 @@ pub struct VerifyArg {
|
|||
named_curve: Option<CryptoNamedCurve>,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub async fn op_crypto_verify_key(
|
||||
_state: Rc<RefCell<OpState>>,
|
||||
args: VerifyArg,
|
||||
|
@ -484,6 +484,7 @@ pub struct DeriveKeyArg {
|
|||
info: Option<ZeroCopyBuf>,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub async fn op_crypto_derive_bits(
|
||||
_state: Rc<RefCell<OpState>>,
|
||||
args: DeriveKeyArg,
|
||||
|
@ -789,6 +790,7 @@ impl<'a> TryFrom<rsa::pkcs8::der::asn1::Any<'a>>
|
|||
}
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_crypto_random_uuid(
|
||||
state: &mut OpState,
|
||||
_: (),
|
||||
|
@ -808,6 +810,7 @@ pub fn op_crypto_random_uuid(
|
|||
Ok(uuid.to_string())
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub async fn op_crypto_subtle_digest(
|
||||
_state: Rc<RefCell<OpState>>,
|
||||
algorithm: CryptoHash,
|
||||
|
@ -831,6 +834,7 @@ pub struct WrapUnwrapKeyArg {
|
|||
algorithm: Algorithm,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_crypto_wrap_key(
|
||||
_state: &mut OpState,
|
||||
args: WrapUnwrapKeyArg,
|
||||
|
@ -860,6 +864,7 @@ pub fn op_crypto_wrap_key(
|
|||
}
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_crypto_unwrap_key(
|
||||
_state: &mut OpState,
|
||||
args: WrapUnwrapKeyArg,
|
||||
|
|
|
@ -9,8 +9,8 @@ use deno_core::futures::Future;
|
|||
use deno_core::futures::Stream;
|
||||
use deno_core::futures::StreamExt;
|
||||
use deno_core::include_js_files;
|
||||
use deno_core::op_async;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::op;
|
||||
|
||||
use deno_core::url::Url;
|
||||
use deno_core::AsyncRefCell;
|
||||
use deno_core::AsyncResult;
|
||||
|
@ -100,12 +100,9 @@ where
|
|||
"26_fetch.js",
|
||||
))
|
||||
.ops(vec![
|
||||
("op_fetch", op_sync(op_fetch::<FP>)),
|
||||
("op_fetch_send", op_async(op_fetch_send)),
|
||||
(
|
||||
"op_fetch_custom_client",
|
||||
op_sync(op_fetch_custom_client::<FP>),
|
||||
),
|
||||
op_fetch::decl::<FP>(),
|
||||
op_fetch_send::decl(),
|
||||
op_fetch_custom_client::decl::<FP>(),
|
||||
])
|
||||
.state(move |state| {
|
||||
state.put::<Options>(options.clone());
|
||||
|
@ -192,6 +189,7 @@ pub struct FetchReturn {
|
|||
cancel_handle_rid: Option<ResourceId>,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_fetch<FP>(
|
||||
state: &mut OpState,
|
||||
args: FetchArgs,
|
||||
|
@ -367,6 +365,7 @@ pub struct FetchResponse {
|
|||
response_rid: ResourceId,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub async fn op_fetch_send(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
rid: ResourceId,
|
||||
|
@ -525,6 +524,7 @@ pub struct CreateHttpClientOptions {
|
|||
private_key: Option<String>,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_fetch_custom_client<FP>(
|
||||
state: &mut OpState,
|
||||
args: CreateHttpClientOptions,
|
||||
|
|
|
@ -6,8 +6,8 @@ use deno_core::error::range_error;
|
|||
use deno_core::error::type_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::include_js_files;
|
||||
use deno_core::op_async;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::op;
|
||||
|
||||
use deno_core::serde_json;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_core::serde_json::Value;
|
||||
|
@ -140,27 +140,24 @@ pub fn init<P: FfiPermissions + 'static>(unstable: bool) -> Extension {
|
|||
"00_ffi.js",
|
||||
))
|
||||
.ops(vec![
|
||||
("op_ffi_load", op_sync(op_ffi_load::<P>)),
|
||||
("op_ffi_get_static", op_sync(op_ffi_get_static)),
|
||||
("op_ffi_call", op_sync(op_ffi_call)),
|
||||
("op_ffi_call_nonblocking", op_async(op_ffi_call_nonblocking)),
|
||||
("op_ffi_call_ptr", op_sync(op_ffi_call_ptr)),
|
||||
(
|
||||
"op_ffi_call_ptr_nonblocking",
|
||||
op_async(op_ffi_call_ptr_nonblocking),
|
||||
),
|
||||
("op_ffi_ptr_of", op_sync(op_ffi_ptr_of::<P>)),
|
||||
("op_ffi_buf_copy_into", op_sync(op_ffi_buf_copy_into::<P>)),
|
||||
("op_ffi_cstr_read", op_sync(op_ffi_cstr_read::<P>)),
|
||||
("op_ffi_read_u8", op_sync(op_ffi_read_u8::<P>)),
|
||||
("op_ffi_read_i8", op_sync(op_ffi_read_i8::<P>)),
|
||||
("op_ffi_read_u16", op_sync(op_ffi_read_u16::<P>)),
|
||||
("op_ffi_read_i16", op_sync(op_ffi_read_i16::<P>)),
|
||||
("op_ffi_read_u32", op_sync(op_ffi_read_u32::<P>)),
|
||||
("op_ffi_read_i32", op_sync(op_ffi_read_i32::<P>)),
|
||||
("op_ffi_read_u64", op_sync(op_ffi_read_u64::<P>)),
|
||||
("op_ffi_read_f32", op_sync(op_ffi_read_f32::<P>)),
|
||||
("op_ffi_read_f64", op_sync(op_ffi_read_f64::<P>)),
|
||||
op_ffi_load::decl::<P>(),
|
||||
op_ffi_get_static::decl(),
|
||||
op_ffi_call::decl(),
|
||||
op_ffi_call_nonblocking::decl(),
|
||||
op_ffi_call_ptr::decl(),
|
||||
op_ffi_call_ptr_nonblocking::decl(),
|
||||
op_ffi_ptr_of::decl::<P>(),
|
||||
op_ffi_buf_copy_into::decl::<P>(),
|
||||
op_ffi_cstr_read::decl::<P>(),
|
||||
op_ffi_read_u8::decl::<P>(),
|
||||
op_ffi_read_i8::decl::<P>(),
|
||||
op_ffi_read_u16::decl::<P>(),
|
||||
op_ffi_read_i16::decl::<P>(),
|
||||
op_ffi_read_u32::decl::<P>(),
|
||||
op_ffi_read_i32::decl::<P>(),
|
||||
op_ffi_read_u64::decl::<P>(),
|
||||
op_ffi_read_f32::decl::<P>(),
|
||||
op_ffi_read_f64::decl::<P>(),
|
||||
])
|
||||
.state(move |state| {
|
||||
// Stolen from deno_webgpu, is there a better option?
|
||||
|
@ -464,6 +461,7 @@ pub(crate) fn format_error(e: dlopen::Error, path: String) -> String {
|
|||
}
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_ffi_load<FP>(
|
||||
state: &mut deno_core::OpState,
|
||||
args: FfiLoadArgs,
|
||||
|
@ -650,6 +648,7 @@ fn ffi_call(args: FfiCallArgs, symbol: &Symbol) -> Result<Value, AnyError> {
|
|||
})
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_ffi_call_ptr(
|
||||
_state: &mut deno_core::OpState,
|
||||
args: FfiCallPtrArgs,
|
||||
|
@ -659,6 +658,7 @@ fn op_ffi_call_ptr(
|
|||
ffi_call(args.into(), &symbol)
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_ffi_call_ptr_nonblocking(
|
||||
_state: Rc<RefCell<deno_core::OpState>>,
|
||||
args: FfiCallPtrArgs,
|
||||
|
@ -678,6 +678,7 @@ struct FfiGetArgs {
|
|||
r#type: NativeType,
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_ffi_get_static(
|
||||
state: &mut deno_core::OpState,
|
||||
args: FfiGetArgs,
|
||||
|
@ -735,6 +736,7 @@ fn op_ffi_get_static(
|
|||
})
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_ffi_call(
|
||||
state: &mut deno_core::OpState,
|
||||
args: FfiCallArgs,
|
||||
|
@ -753,6 +755,7 @@ fn op_ffi_call(
|
|||
}
|
||||
|
||||
/// A non-blocking FFI call.
|
||||
#[op]
|
||||
async fn op_ffi_call_nonblocking(
|
||||
state: Rc<RefCell<deno_core::OpState>>,
|
||||
args: FfiCallArgs,
|
||||
|
@ -773,6 +776,7 @@ async fn op_ffi_call_nonblocking(
|
|||
.unwrap()
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_ffi_ptr_of<FP>(
|
||||
state: &mut deno_core::OpState,
|
||||
buf: ZeroCopyBuf,
|
||||
|
@ -787,6 +791,7 @@ where
|
|||
Ok(U32x2::from(buf.as_ptr() as u64))
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_ffi_buf_copy_into<FP>(
|
||||
state: &mut deno_core::OpState,
|
||||
(src, mut dst, len): (U32x2, ZeroCopyBuf, usize),
|
||||
|
@ -809,6 +814,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_ffi_cstr_read<FP>(
|
||||
state: &mut deno_core::OpState,
|
||||
ptr: U32x2,
|
||||
|
@ -824,6 +830,7 @@ where
|
|||
Ok(unsafe { CStr::from_ptr(ptr) }.to_str()?.to_string())
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_ffi_read_u8<FP>(
|
||||
state: &mut deno_core::OpState,
|
||||
ptr: U32x2,
|
||||
|
@ -838,6 +845,7 @@ where
|
|||
Ok(unsafe { ptr::read_unaligned(u64::from(ptr) as *const u8) })
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_ffi_read_i8<FP>(
|
||||
state: &mut deno_core::OpState,
|
||||
ptr: U32x2,
|
||||
|
@ -852,6 +860,7 @@ where
|
|||
Ok(unsafe { ptr::read_unaligned(u64::from(ptr) as *const i8) })
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_ffi_read_u16<FP>(
|
||||
state: &mut deno_core::OpState,
|
||||
ptr: U32x2,
|
||||
|
@ -866,6 +875,7 @@ where
|
|||
Ok(unsafe { ptr::read_unaligned(u64::from(ptr) as *const u16) })
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_ffi_read_i16<FP>(
|
||||
state: &mut deno_core::OpState,
|
||||
ptr: U32x2,
|
||||
|
@ -880,6 +890,7 @@ where
|
|||
Ok(unsafe { ptr::read_unaligned(u64::from(ptr) as *const i16) })
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_ffi_read_u32<FP>(
|
||||
state: &mut deno_core::OpState,
|
||||
ptr: U32x2,
|
||||
|
@ -894,6 +905,7 @@ where
|
|||
Ok(unsafe { ptr::read_unaligned(u64::from(ptr) as *const u32) })
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_ffi_read_i32<FP>(
|
||||
state: &mut deno_core::OpState,
|
||||
ptr: U32x2,
|
||||
|
@ -908,6 +920,7 @@ where
|
|||
Ok(unsafe { ptr::read_unaligned(u64::from(ptr) as *const i32) })
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_ffi_read_u64<FP>(
|
||||
state: &mut deno_core::OpState,
|
||||
ptr: U32x2,
|
||||
|
@ -924,6 +937,7 @@ where
|
|||
}))
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_ffi_read_f32<FP>(
|
||||
state: &mut deno_core::OpState,
|
||||
ptr: U32x2,
|
||||
|
@ -938,6 +952,7 @@ where
|
|||
Ok(unsafe { ptr::read_unaligned(u64::from(ptr) as *const f32) })
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_ffi_read_f64<FP>(
|
||||
state: &mut deno_core::OpState,
|
||||
ptr: U32x2,
|
||||
|
|
|
@ -20,8 +20,8 @@ use deno_core::futures::FutureExt;
|
|||
use deno_core::futures::StreamExt;
|
||||
use deno_core::futures::TryFutureExt;
|
||||
use deno_core::include_js_files;
|
||||
use deno_core::op_async;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::op;
|
||||
|
||||
use deno_core::AsyncRefCell;
|
||||
use deno_core::ByteString;
|
||||
use deno_core::CancelFuture;
|
||||
|
@ -72,19 +72,13 @@ pub fn init() -> Extension {
|
|||
"01_http.js",
|
||||
))
|
||||
.ops(vec![
|
||||
("op_http_accept", op_async(op_http_accept)),
|
||||
("op_http_read", op_async(op_http_read)),
|
||||
("op_http_write_headers", op_async(op_http_write_headers)),
|
||||
("op_http_write", op_async(op_http_write)),
|
||||
("op_http_shutdown", op_async(op_http_shutdown)),
|
||||
(
|
||||
"op_http_websocket_accept_header",
|
||||
op_sync(op_http_websocket_accept_header),
|
||||
),
|
||||
(
|
||||
"op_http_upgrade_websocket",
|
||||
op_async(op_http_upgrade_websocket),
|
||||
),
|
||||
op_http_accept::decl(),
|
||||
op_http_read::decl(),
|
||||
op_http_write_headers::decl(),
|
||||
op_http_write::decl(),
|
||||
op_http_shutdown::decl(),
|
||||
op_http_websocket_accept_header::decl(),
|
||||
op_http_upgrade_websocket::decl(),
|
||||
])
|
||||
.build()
|
||||
}
|
||||
|
@ -371,6 +365,7 @@ struct NextRequestResponse(
|
|||
String,
|
||||
);
|
||||
|
||||
#[op]
|
||||
async fn op_http_accept(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
rid: ResourceId,
|
||||
|
@ -501,6 +496,7 @@ struct RespondArgs(
|
|||
Vec<(ByteString, ByteString)>,
|
||||
);
|
||||
|
||||
#[op]
|
||||
async fn op_http_write_headers(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: RespondArgs,
|
||||
|
@ -697,6 +693,7 @@ async fn op_http_write_headers(
|
|||
}
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_http_write(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
rid: ResourceId,
|
||||
|
@ -737,6 +734,7 @@ async fn op_http_write(
|
|||
/// Gracefully closes the write half of the HTTP stream. Note that this does not
|
||||
/// remove the HTTP stream resource from the resource table; it still has to be
|
||||
/// closed with `Deno.core.close()`.
|
||||
#[op]
|
||||
async fn op_http_shutdown(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
rid: ResourceId,
|
||||
|
@ -751,6 +749,7 @@ async fn op_http_shutdown(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_http_read(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
rid: ResourceId,
|
||||
|
@ -799,6 +798,7 @@ async fn op_http_read(
|
|||
fut.try_or_cancel(cancel_handle).await
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_http_websocket_accept_header(
|
||||
_: &mut OpState,
|
||||
key: String,
|
||||
|
@ -811,6 +811,7 @@ fn op_http_websocket_accept_header(
|
|||
Ok(base64::encode(digest))
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_http_upgrade_websocket(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
rid: ResourceId,
|
||||
|
|
|
@ -76,9 +76,6 @@ pub fn init<P: NetPermissions + 'static>(
|
|||
unstable: bool,
|
||||
unsafely_ignore_certificate_errors: Option<Vec<String>>,
|
||||
) -> Extension {
|
||||
let mut ops_to_register = vec![];
|
||||
ops_to_register.extend(ops::init::<P>());
|
||||
ops_to_register.extend(ops_tls::init::<P>());
|
||||
Extension::builder()
|
||||
.js(include_js_files!(
|
||||
prefix "deno:ext/net",
|
||||
|
@ -86,7 +83,7 @@ pub fn init<P: NetPermissions + 'static>(
|
|||
"02_tls.js",
|
||||
"04_net_unstable.js",
|
||||
))
|
||||
.ops(ops_to_register)
|
||||
.ops([&ops::init::<P>()[..], &ops_tls::init::<P>()[..]].concat())
|
||||
.state(move |state| {
|
||||
state.put(DefaultTlsOptions {
|
||||
root_cert_store: root_cert_store.clone(),
|
||||
|
|
|
@ -9,8 +9,8 @@ use deno_core::error::custom_error;
|
|||
use deno_core::error::generic_error;
|
||||
use deno_core::error::type_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op_async;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::op;
|
||||
|
||||
use deno_core::AsyncRefCell;
|
||||
use deno_core::ByteString;
|
||||
use deno_core::CancelHandle;
|
||||
|
@ -52,14 +52,14 @@ use std::path::Path;
|
|||
|
||||
pub fn init<P: NetPermissions + 'static>() -> Vec<OpPair> {
|
||||
vec![
|
||||
("op_net_accept", op_async(op_net_accept)),
|
||||
("op_net_connect", op_async(op_net_connect::<P>)),
|
||||
("op_net_listen", op_sync(op_net_listen::<P>)),
|
||||
("op_dgram_recv", op_async(op_dgram_recv)),
|
||||
("op_dgram_send", op_async(op_dgram_send::<P>)),
|
||||
("op_dns_resolve", op_async(op_dns_resolve::<P>)),
|
||||
("op_set_nodelay", op_sync(op_set_nodelay::<P>)),
|
||||
("op_set_keepalive", op_sync(op_set_keepalive::<P>)),
|
||||
op_net_accept::decl(),
|
||||
op_net_connect::decl::<P>(),
|
||||
op_net_listen::decl::<P>(),
|
||||
op_dgram_recv::decl(),
|
||||
op_dgram_send::decl::<P>(),
|
||||
op_dns_resolve::decl::<P>(),
|
||||
op_set_nodelay::decl::<P>(),
|
||||
op_set_keepalive::decl::<P>(),
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -158,6 +158,7 @@ async fn accept_tcp(
|
|||
})
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_net_accept(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: AcceptArgs,
|
||||
|
@ -210,6 +211,7 @@ async fn receive_udp(
|
|||
})
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_dgram_recv(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: ReceiveArgs,
|
||||
|
@ -231,6 +233,7 @@ struct SendArgs {
|
|||
transport_args: ArgsEnum,
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_dgram_send<NP>(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: SendArgs,
|
||||
|
@ -299,6 +302,7 @@ pub struct ConnectArgs {
|
|||
transport_args: ArgsEnum,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub async fn op_net_connect<NP>(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: ConnectArgs,
|
||||
|
@ -474,6 +478,7 @@ fn listen_udp(
|
|||
Ok((rid, local_addr))
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_net_listen<NP>(
|
||||
state: &mut OpState,
|
||||
args: ListenArgs,
|
||||
|
@ -613,6 +618,7 @@ pub struct NameServer {
|
|||
port: u16,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub async fn op_dns_resolve<NP>(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: ResolveAddrArgs,
|
||||
|
@ -681,6 +687,7 @@ where
|
|||
Ok(results)
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_set_nodelay<NP>(
|
||||
state: &mut OpState,
|
||||
rid: ResourceId,
|
||||
|
@ -692,6 +699,7 @@ pub fn op_set_nodelay<NP>(
|
|||
resource.set_nodelay(nodelay)
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_set_keepalive<NP>(
|
||||
state: &mut OpState,
|
||||
rid: ResourceId,
|
||||
|
@ -877,7 +885,7 @@ mod tests {
|
|||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||
async fn tcp_set_no_delay() {
|
||||
let set_nodelay = Box::new(|state: &mut OpState, rid| {
|
||||
op_set_nodelay::<TestPermission>(state, rid, true).unwrap();
|
||||
op_set_nodelay::call::<TestPermission>(state, rid, true).unwrap();
|
||||
});
|
||||
let test_fn = Box::new(|socket: SockRef| {
|
||||
assert!(socket.nodelay().unwrap());
|
||||
|
@ -889,7 +897,7 @@ mod tests {
|
|||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||
async fn tcp_set_keepalive() {
|
||||
let set_keepalive = Box::new(|state: &mut OpState, rid| {
|
||||
op_set_keepalive::<TestPermission>(state, rid, true).unwrap();
|
||||
op_set_keepalive::call::<TestPermission>(state, rid, true).unwrap();
|
||||
});
|
||||
let test_fn = Box::new(|socket: SockRef| {
|
||||
assert!(!socket.nodelay().unwrap());
|
||||
|
@ -934,7 +942,7 @@ mod tests {
|
|||
};
|
||||
|
||||
let connect_fut =
|
||||
op_net_connect::<TestPermission>(conn_state, connect_args, ());
|
||||
op_net_connect::call::<TestPermission>(conn_state, connect_args, ());
|
||||
let conn = connect_fut.await.unwrap();
|
||||
|
||||
let rid = conn.rid;
|
||||
|
|
|
@ -25,8 +25,8 @@ use deno_core::futures::task::Poll;
|
|||
use deno_core::futures::task::RawWaker;
|
||||
use deno_core::futures::task::RawWakerVTable;
|
||||
use deno_core::futures::task::Waker;
|
||||
use deno_core::op_async;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::op;
|
||||
|
||||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::AsyncRefCell;
|
||||
use deno_core::AsyncResult;
|
||||
|
@ -644,11 +644,11 @@ impl Write for ImplementWriteTrait<'_, TcpStream> {
|
|||
|
||||
pub fn init<P: NetPermissions + 'static>() -> Vec<OpPair> {
|
||||
vec![
|
||||
("op_tls_start", op_async(op_tls_start::<P>)),
|
||||
("op_tls_connect", op_async(op_tls_connect::<P>)),
|
||||
("op_tls_listen", op_sync(op_tls_listen::<P>)),
|
||||
("op_tls_accept", op_async(op_tls_accept)),
|
||||
("op_tls_handshake", op_async(op_tls_handshake)),
|
||||
op_tls_start::decl::<P>(),
|
||||
op_tls_connect::decl::<P>(),
|
||||
op_tls_listen::decl::<P>(),
|
||||
op_tls_accept::decl(),
|
||||
op_tls_handshake::decl(),
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -765,6 +765,7 @@ pub struct StartTlsArgs {
|
|||
alpn_protocols: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub async fn op_tls_start<NP>(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: StartTlsArgs,
|
||||
|
@ -857,6 +858,7 @@ where
|
|||
})
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub async fn op_tls_connect<NP>(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: ConnectTlsArgs,
|
||||
|
@ -1016,6 +1018,7 @@ pub struct ListenTlsArgs {
|
|||
alpn_protocols: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_tls_listen<NP>(
|
||||
state: &mut OpState,
|
||||
args: ListenTlsArgs,
|
||||
|
@ -1112,6 +1115,7 @@ where
|
|||
})
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub async fn op_tls_accept(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
rid: ResourceId,
|
||||
|
@ -1163,6 +1167,7 @@ pub async fn op_tls_accept(
|
|||
})
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub async fn op_tls_handshake(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
rid: ResourceId,
|
||||
|
|
|
@ -7,7 +7,7 @@ use deno_core::error::type_error;
|
|||
use deno_core::error::uri_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::include_js_files;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::op;
|
||||
use deno_core::url::form_urlencoded;
|
||||
use deno_core::url::quirks;
|
||||
use deno_core::url::Url;
|
||||
|
@ -26,21 +26,12 @@ pub fn init() -> Extension {
|
|||
"01_urlpattern.js",
|
||||
))
|
||||
.ops(vec![
|
||||
("op_url_parse", op_sync(op_url_parse)),
|
||||
("op_url_reparse", op_sync(op_url_reparse)),
|
||||
(
|
||||
"op_url_parse_search_params",
|
||||
op_sync(op_url_parse_search_params),
|
||||
),
|
||||
(
|
||||
"op_url_stringify_search_params",
|
||||
op_sync(op_url_stringify_search_params),
|
||||
),
|
||||
("op_urlpattern_parse", op_sync(op_urlpattern_parse)),
|
||||
(
|
||||
"op_urlpattern_process_match_input",
|
||||
op_sync(op_urlpattern_process_match_input),
|
||||
),
|
||||
op_url_parse::decl(),
|
||||
op_url_reparse::decl(),
|
||||
op_url_parse_search_params::decl(),
|
||||
op_url_stringify_search_params::decl(),
|
||||
op_urlpattern_parse::decl(),
|
||||
op_urlpattern_process_match_input::decl(),
|
||||
])
|
||||
.build()
|
||||
}
|
||||
|
@ -65,6 +56,7 @@ type UrlParts = String;
|
|||
|
||||
/// Parse `UrlParseArgs::href` with an optional `UrlParseArgs::base_href`, or an
|
||||
/// optional part to "set" after parsing. Return `UrlParts`.
|
||||
#[op]
|
||||
pub fn op_url_parse(
|
||||
_state: &mut deno_core::OpState,
|
||||
href: String,
|
||||
|
@ -98,6 +90,7 @@ pub enum UrlSetter {
|
|||
Username = 9,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_url_reparse(
|
||||
_state: &mut deno_core::OpState,
|
||||
href: String,
|
||||
|
@ -167,6 +160,7 @@ fn url_result(
|
|||
)
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_url_parse_search_params(
|
||||
_state: &mut deno_core::OpState,
|
||||
args: Option<String>,
|
||||
|
@ -186,6 +180,7 @@ pub fn op_url_parse_search_params(
|
|||
Ok(params)
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_url_stringify_search_params(
|
||||
_state: &mut deno_core::OpState,
|
||||
args: Vec<(String, String)>,
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
use deno_core::error::type_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op;
|
||||
|
||||
use urlpattern::quirks;
|
||||
use urlpattern::quirks::MatchInput;
|
||||
use urlpattern::quirks::StringOrInit;
|
||||
use urlpattern::quirks::UrlPattern;
|
||||
|
||||
#[op]
|
||||
pub fn op_urlpattern_parse(
|
||||
_state: &mut deno_core::OpState,
|
||||
input: StringOrInit,
|
||||
|
@ -23,6 +25,7 @@ pub fn op_urlpattern_parse(
|
|||
Ok(pattern)
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_urlpattern_process_match_input(
|
||||
_state: &mut deno_core::OpState,
|
||||
input: StringOrInit,
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use async_trait::async_trait;
|
||||
use deno_core::error::type_error;
|
||||
use deno_core::op;
|
||||
|
||||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::url::Url;
|
||||
use deno_core::ZeroCopyBuf;
|
||||
|
@ -157,6 +159,7 @@ impl BlobPart for SlicedBlobPart {
|
|||
}
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_blob_create_part(
|
||||
state: &mut deno_core::OpState,
|
||||
data: ZeroCopyBuf,
|
||||
|
@ -175,6 +178,7 @@ pub struct SliceOptions {
|
|||
len: usize,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_blob_slice_part(
|
||||
state: &mut deno_core::OpState,
|
||||
id: Uuid,
|
||||
|
@ -200,6 +204,7 @@ pub fn op_blob_slice_part(
|
|||
Ok(id)
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub async fn op_blob_read_part(
|
||||
state: Rc<RefCell<deno_core::OpState>>,
|
||||
id: Uuid,
|
||||
|
@ -215,6 +220,7 @@ pub async fn op_blob_read_part(
|
|||
Ok(ZeroCopyBuf::from(buf.to_vec()))
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_blob_remove_part(
|
||||
state: &mut deno_core::OpState,
|
||||
id: Uuid,
|
||||
|
@ -225,6 +231,7 @@ pub fn op_blob_remove_part(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_blob_create_object_url(
|
||||
state: &mut deno_core::OpState,
|
||||
media_type: String,
|
||||
|
@ -250,6 +257,7 @@ pub fn op_blob_create_object_url(
|
|||
Ok(url.to_string())
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_blob_revoke_object_url(
|
||||
state: &mut deno_core::OpState,
|
||||
url: String,
|
||||
|
@ -273,6 +281,7 @@ pub struct ReturnBlobPart {
|
|||
pub size: usize,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_blob_from_object_url(
|
||||
state: &mut deno_core::OpState,
|
||||
url: String,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op;
|
||||
use deno_core::OpState;
|
||||
use deno_core::Resource;
|
||||
use deno_core::ResourceId;
|
||||
|
@ -32,6 +33,7 @@ impl Resource for CompressionResource {
|
|||
}
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_compression_new(
|
||||
state: &mut OpState,
|
||||
format: String,
|
||||
|
@ -53,6 +55,7 @@ pub fn op_compression_new(
|
|||
Ok(state.resource_table.add(resource))
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_compression_write(
|
||||
state: &mut OpState,
|
||||
rid: ResourceId,
|
||||
|
@ -86,6 +89,7 @@ pub fn op_compression_write(
|
|||
Ok(out.into())
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_compression_finish(
|
||||
state: &mut OpState,
|
||||
rid: ResourceId,
|
||||
|
|
|
@ -9,8 +9,7 @@ use deno_core::error::range_error;
|
|||
use deno_core::error::type_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::include_js_files;
|
||||
use deno_core::op_async;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::op;
|
||||
use deno_core::url::Url;
|
||||
use deno_core::ByteString;
|
||||
use deno_core::Extension;
|
||||
|
@ -83,58 +82,31 @@ pub fn init<P: TimersPermission + 'static>(
|
|||
"15_performance.js",
|
||||
))
|
||||
.ops(vec![
|
||||
("op_base64_decode", op_sync(op_base64_decode)),
|
||||
("op_base64_encode", op_sync(op_base64_encode)),
|
||||
("op_base64_atob", op_sync(op_base64_atob)),
|
||||
("op_base64_btoa", op_sync(op_base64_btoa)),
|
||||
(
|
||||
"op_encoding_normalize_label",
|
||||
op_sync(op_encoding_normalize_label),
|
||||
),
|
||||
("op_encoding_new_decoder", op_sync(op_encoding_new_decoder)),
|
||||
("op_encoding_decode", op_sync(op_encoding_decode)),
|
||||
("op_encoding_encode_into", op_sync(op_encoding_encode_into)),
|
||||
("op_blob_create_part", op_sync(op_blob_create_part)),
|
||||
("op_blob_slice_part", op_sync(op_blob_slice_part)),
|
||||
("op_blob_read_part", op_async(op_blob_read_part)),
|
||||
("op_blob_remove_part", op_sync(op_blob_remove_part)),
|
||||
(
|
||||
"op_blob_create_object_url",
|
||||
op_sync(op_blob_create_object_url),
|
||||
),
|
||||
(
|
||||
"op_blob_revoke_object_url",
|
||||
op_sync(op_blob_revoke_object_url),
|
||||
),
|
||||
("op_blob_from_object_url", op_sync(op_blob_from_object_url)),
|
||||
(
|
||||
"op_message_port_create_entangled",
|
||||
op_sync(op_message_port_create_entangled),
|
||||
),
|
||||
(
|
||||
"op_message_port_post_message",
|
||||
op_sync(op_message_port_post_message),
|
||||
),
|
||||
(
|
||||
"op_message_port_recv_message",
|
||||
op_async(op_message_port_recv_message),
|
||||
),
|
||||
(
|
||||
"op_compression_new",
|
||||
op_sync(compression::op_compression_new),
|
||||
),
|
||||
(
|
||||
"op_compression_write",
|
||||
op_sync(compression::op_compression_write),
|
||||
),
|
||||
(
|
||||
"op_compression_finish",
|
||||
op_sync(compression::op_compression_finish),
|
||||
),
|
||||
("op_now", op_sync(op_now::<P>)),
|
||||
("op_timer_handle", op_sync(op_timer_handle)),
|
||||
("op_sleep", op_async(op_sleep)),
|
||||
("op_sleep_sync", op_sync(op_sleep_sync::<P>)),
|
||||
op_base64_decode::decl(),
|
||||
op_base64_encode::decl(),
|
||||
op_base64_atob::decl(),
|
||||
op_base64_btoa::decl(),
|
||||
op_encoding_normalize_label::decl(),
|
||||
op_encoding_new_decoder::decl(),
|
||||
op_encoding_decode::decl(),
|
||||
op_encoding_encode_into::decl(),
|
||||
op_blob_create_part::decl(),
|
||||
op_blob_slice_part::decl(),
|
||||
op_blob_read_part::decl(),
|
||||
op_blob_remove_part::decl(),
|
||||
op_blob_create_object_url::decl(),
|
||||
op_blob_revoke_object_url::decl(),
|
||||
op_blob_from_object_url::decl(),
|
||||
op_message_port_create_entangled::decl(),
|
||||
op_message_port_post_message::decl(),
|
||||
op_message_port_recv_message::decl(),
|
||||
compression::op_compression_new::decl(),
|
||||
compression::op_compression_write::decl(),
|
||||
compression::op_compression_finish::decl(),
|
||||
op_now::decl::<P>(),
|
||||
op_timer_handle::decl(),
|
||||
op_sleep::decl(),
|
||||
op_sleep_sync::decl::<P>(),
|
||||
])
|
||||
.state(move |state| {
|
||||
state.put(blob_store.clone());
|
||||
|
@ -147,6 +119,7 @@ pub fn init<P: TimersPermission + 'static>(
|
|||
.build()
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_base64_decode(
|
||||
_: &mut OpState,
|
||||
input: String,
|
||||
|
@ -157,6 +130,7 @@ fn op_base64_decode(
|
|||
Ok(b64_decode(&input)?.into())
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_base64_atob(
|
||||
_: &mut OpState,
|
||||
s: ByteString,
|
||||
|
@ -210,6 +184,7 @@ fn b64_decode(input: &[u8]) -> Result<Vec<u8>, AnyError> {
|
|||
Ok(out)
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_base64_encode(
|
||||
_: &mut OpState,
|
||||
s: ZeroCopyBuf,
|
||||
|
@ -218,6 +193,7 @@ fn op_base64_encode(
|
|||
Ok(b64_encode(&s))
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_base64_btoa(
|
||||
_: &mut OpState,
|
||||
s: ByteString,
|
||||
|
@ -240,6 +216,7 @@ struct DecoderOptions {
|
|||
fatal: bool,
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_encoding_normalize_label(
|
||||
_state: &mut OpState,
|
||||
label: String,
|
||||
|
@ -255,6 +232,7 @@ fn op_encoding_normalize_label(
|
|||
Ok(encoding.name().to_lowercase())
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_encoding_new_decoder(
|
||||
state: &mut OpState,
|
||||
options: DecoderOptions,
|
||||
|
@ -294,6 +272,7 @@ struct DecodeOptions {
|
|||
stream: bool,
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_encoding_decode(
|
||||
state: &mut OpState,
|
||||
data: ZeroCopyBuf,
|
||||
|
@ -357,6 +336,7 @@ struct EncodeIntoResult {
|
|||
written: usize,
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_encoding_encode_into(
|
||||
_state: &mut OpState,
|
||||
input: String,
|
||||
|
|
|
@ -4,6 +4,8 @@ use std::rc::Rc;
|
|||
|
||||
use deno_core::error::type_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op;
|
||||
|
||||
use deno_core::ZeroCopyBuf;
|
||||
use deno_core::{CancelFuture, Resource};
|
||||
use deno_core::{CancelHandle, OpState};
|
||||
|
@ -104,6 +106,7 @@ impl Resource for MessagePortResource {
|
|||
}
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_message_port_create_entangled(
|
||||
state: &mut OpState,
|
||||
_: (),
|
||||
|
@ -185,6 +188,7 @@ pub struct JsMessageData {
|
|||
transferables: Vec<JsTransferable>,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_message_port_post_message(
|
||||
state: &mut OpState,
|
||||
rid: ResourceId,
|
||||
|
@ -203,6 +207,7 @@ pub fn op_message_port_post_message(
|
|||
resource.port.send(state, data)
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub async fn op_message_port_recv_message(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
rid: ResourceId,
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
//! This module helps deno implement timers and performance APIs.
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op;
|
||||
|
||||
use deno_core::CancelFuture;
|
||||
use deno_core::CancelHandle;
|
||||
use deno_core::OpState;
|
||||
|
@ -25,6 +27,7 @@ pub type StartTime = Instant;
|
|||
// since the start time of the deno runtime.
|
||||
// If the High precision flag is not set, the
|
||||
// nanoseconds are rounded on 2ms.
|
||||
#[op]
|
||||
pub fn op_now<TP>(
|
||||
state: &mut OpState,
|
||||
_argument: (),
|
||||
|
@ -64,6 +67,7 @@ impl Resource for TimerHandle {
|
|||
|
||||
/// Creates a [`TimerHandle`] resource that can be used to cancel invocations of
|
||||
/// [`op_sleep`].
|
||||
#[op]
|
||||
pub fn op_timer_handle(
|
||||
state: &mut OpState,
|
||||
_: (),
|
||||
|
@ -77,6 +81,7 @@ pub fn op_timer_handle(
|
|||
|
||||
/// Waits asynchronously until either `millis` milliseconds have passed or the
|
||||
/// [`TimerHandle`] resource given by `rid` has been canceled.
|
||||
#[op]
|
||||
pub async fn op_sleep(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
millis: u64,
|
||||
|
@ -89,6 +94,7 @@ pub async fn op_sleep(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_sleep_sync<TP>(
|
||||
state: &mut OpState,
|
||||
millis: u64,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op;
|
||||
use deno_core::ResourceId;
|
||||
use deno_core::{OpState, Resource};
|
||||
use serde::Deserialize;
|
||||
|
@ -177,6 +178,7 @@ pub struct CreateBindGroupLayoutArgs {
|
|||
entries: Vec<GpuBindGroupLayoutEntry>,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_create_bind_group_layout(
|
||||
state: &mut OpState,
|
||||
args: CreateBindGroupLayoutArgs,
|
||||
|
@ -220,6 +222,7 @@ pub struct CreatePipelineLayoutArgs {
|
|||
bind_group_layouts: Vec<u32>,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_create_pipeline_layout(
|
||||
state: &mut OpState,
|
||||
args: CreatePipelineLayoutArgs,
|
||||
|
@ -271,6 +274,7 @@ pub struct CreateBindGroupArgs {
|
|||
entries: Vec<GpuBindGroupEntry>,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_create_bind_group(
|
||||
state: &mut OpState,
|
||||
args: CreateBindGroupArgs,
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
use deno_core::error::type_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::futures::channel::oneshot;
|
||||
use deno_core::op;
|
||||
|
||||
use deno_core::OpState;
|
||||
use deno_core::Resource;
|
||||
use deno_core::ResourceId;
|
||||
|
@ -40,6 +42,7 @@ pub struct CreateBufferArgs {
|
|||
mapped_at_creation: bool,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_create_buffer(
|
||||
state: &mut OpState,
|
||||
args: CreateBufferArgs,
|
||||
|
@ -76,6 +79,7 @@ pub struct BufferGetMapAsyncArgs {
|
|||
size: u64,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub async fn op_webgpu_buffer_get_map_async(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: BufferGetMapAsyncArgs,
|
||||
|
@ -167,6 +171,7 @@ pub struct BufferGetMappedRangeArgs {
|
|||
size: Option<u64>,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_buffer_get_mapped_range(
|
||||
state: &mut OpState,
|
||||
args: BufferGetMappedRangeArgs,
|
||||
|
@ -204,6 +209,7 @@ pub struct BufferUnmapArgs {
|
|||
mapped_rid: ResourceId,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_buffer_unmap(
|
||||
state: &mut OpState,
|
||||
args: BufferUnmapArgs,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op;
|
||||
use deno_core::ResourceId;
|
||||
use deno_core::ZeroCopyBuf;
|
||||
use deno_core::{OpState, Resource};
|
||||
|
@ -39,6 +40,7 @@ pub struct CreateRenderBundleEncoderArgs {
|
|||
stencil_read_only: bool,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_create_render_bundle_encoder(
|
||||
state: &mut OpState,
|
||||
args: CreateRenderBundleEncoderArgs,
|
||||
|
@ -99,6 +101,7 @@ pub struct RenderBundleEncoderFinishArgs {
|
|||
label: Option<String>,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_bundle_encoder_finish(
|
||||
state: &mut OpState,
|
||||
args: RenderBundleEncoderFinishArgs,
|
||||
|
@ -135,6 +138,7 @@ pub struct RenderBundleEncoderSetBindGroupArgs {
|
|||
dynamic_offsets_data_length: usize,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_bundle_encoder_set_bind_group(
|
||||
state: &mut OpState,
|
||||
args: RenderBundleEncoderSetBindGroupArgs,
|
||||
|
@ -189,6 +193,7 @@ pub struct RenderBundleEncoderPushDebugGroupArgs {
|
|||
group_label: String,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_bundle_encoder_push_debug_group(
|
||||
state: &mut OpState,
|
||||
args: RenderBundleEncoderPushDebugGroupArgs,
|
||||
|
@ -218,6 +223,7 @@ pub struct RenderBundleEncoderPopDebugGroupArgs {
|
|||
render_bundle_encoder_rid: ResourceId,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_bundle_encoder_pop_debug_group(
|
||||
state: &mut OpState,
|
||||
args: RenderBundleEncoderPopDebugGroupArgs,
|
||||
|
@ -242,6 +248,7 @@ pub struct RenderBundleEncoderInsertDebugMarkerArgs {
|
|||
marker_label: String,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_bundle_encoder_insert_debug_marker(
|
||||
state: &mut OpState,
|
||||
args: RenderBundleEncoderInsertDebugMarkerArgs,
|
||||
|
@ -272,6 +279,7 @@ pub struct RenderBundleEncoderSetPipelineArgs {
|
|||
pipeline: ResourceId,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_bundle_encoder_set_pipeline(
|
||||
state: &mut OpState,
|
||||
args: RenderBundleEncoderSetPipelineArgs,
|
||||
|
@ -304,6 +312,7 @@ pub struct RenderBundleEncoderSetIndexBufferArgs {
|
|||
size: u64,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_bundle_encoder_set_index_buffer(
|
||||
state: &mut OpState,
|
||||
args: RenderBundleEncoderSetIndexBufferArgs,
|
||||
|
@ -340,6 +349,7 @@ pub struct RenderBundleEncoderSetVertexBufferArgs {
|
|||
size: u64,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_bundle_encoder_set_vertex_buffer(
|
||||
state: &mut OpState,
|
||||
args: RenderBundleEncoderSetVertexBufferArgs,
|
||||
|
@ -374,6 +384,7 @@ pub struct RenderBundleEncoderDrawArgs {
|
|||
first_instance: u32,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_bundle_encoder_draw(
|
||||
state: &mut OpState,
|
||||
args: RenderBundleEncoderDrawArgs,
|
||||
|
@ -406,6 +417,7 @@ pub struct RenderBundleEncoderDrawIndexedArgs {
|
|||
first_instance: u32,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_bundle_encoder_draw_indexed(
|
||||
state: &mut OpState,
|
||||
args: RenderBundleEncoderDrawIndexedArgs,
|
||||
|
@ -436,6 +448,7 @@ pub struct RenderBundleEncoderDrawIndirectArgs {
|
|||
indirect_offset: u64,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_bundle_encoder_draw_indirect(
|
||||
state: &mut OpState,
|
||||
args: RenderBundleEncoderDrawIndirectArgs,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op;
|
||||
use deno_core::ResourceId;
|
||||
use deno_core::{OpState, Resource};
|
||||
use serde::Deserialize;
|
||||
|
@ -36,6 +37,7 @@ pub struct CreateCommandEncoderArgs {
|
|||
_measure_execution_time: Option<bool>, // not yet implemented
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_create_command_encoder(
|
||||
state: &mut OpState,
|
||||
args: CreateCommandEncoderArgs,
|
||||
|
@ -96,6 +98,7 @@ pub struct CommandEncoderBeginRenderPassArgs {
|
|||
_occlusion_query_set: Option<u32>, // not yet implemented
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_command_encoder_begin_render_pass(
|
||||
state: &mut OpState,
|
||||
args: CommandEncoderBeginRenderPassArgs,
|
||||
|
@ -214,6 +217,7 @@ pub struct CommandEncoderBeginComputePassArgs {
|
|||
label: Option<String>,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_command_encoder_begin_compute_pass(
|
||||
state: &mut OpState,
|
||||
args: CommandEncoderBeginComputePassArgs,
|
||||
|
@ -252,6 +256,7 @@ pub struct CommandEncoderCopyBufferToBufferArgs {
|
|||
size: u64,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_command_encoder_copy_buffer_to_buffer(
|
||||
state: &mut OpState,
|
||||
args: CommandEncoderCopyBufferToBufferArgs,
|
||||
|
@ -310,6 +315,7 @@ pub struct CommandEncoderCopyBufferToTextureArgs {
|
|||
copy_size: wgpu_types::Extent3d,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_command_encoder_copy_buffer_to_texture(
|
||||
state: &mut OpState,
|
||||
args: CommandEncoderCopyBufferToTextureArgs,
|
||||
|
@ -360,6 +366,7 @@ pub struct CommandEncoderCopyTextureToBufferArgs {
|
|||
copy_size: wgpu_types::Extent3d,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_command_encoder_copy_texture_to_buffer(
|
||||
state: &mut OpState,
|
||||
args: CommandEncoderCopyTextureToBufferArgs,
|
||||
|
@ -414,6 +421,7 @@ pub struct CommandEncoderCopyTextureToTextureArgs {
|
|||
copy_size: wgpu_types::Extent3d,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_command_encoder_copy_texture_to_texture(
|
||||
state: &mut OpState,
|
||||
args: CommandEncoderCopyTextureToTextureArgs,
|
||||
|
@ -462,6 +470,7 @@ pub struct CommandEncoderClearBufferArgs {
|
|||
size: u64,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_command_encoder_clear_buffer(
|
||||
state: &mut OpState,
|
||||
args: CommandEncoderClearBufferArgs,
|
||||
|
@ -491,6 +500,7 @@ pub struct CommandEncoderPushDebugGroupArgs {
|
|||
group_label: String,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_command_encoder_push_debug_group(
|
||||
state: &mut OpState,
|
||||
args: CommandEncoderPushDebugGroupArgs,
|
||||
|
@ -512,6 +522,7 @@ pub struct CommandEncoderPopDebugGroupArgs {
|
|||
command_encoder_rid: ResourceId,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_command_encoder_pop_debug_group(
|
||||
state: &mut OpState,
|
||||
args: CommandEncoderPopDebugGroupArgs,
|
||||
|
@ -533,6 +544,7 @@ pub struct CommandEncoderInsertDebugMarkerArgs {
|
|||
marker_label: String,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_command_encoder_insert_debug_marker(
|
||||
state: &mut OpState,
|
||||
args: CommandEncoderInsertDebugMarkerArgs,
|
||||
|
@ -558,6 +570,7 @@ pub struct CommandEncoderWriteTimestampArgs {
|
|||
query_index: u32,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_command_encoder_write_timestamp(
|
||||
state: &mut OpState,
|
||||
args: CommandEncoderWriteTimestampArgs,
|
||||
|
@ -590,6 +603,7 @@ pub struct CommandEncoderResolveQuerySetArgs {
|
|||
destination_offset: u64,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_command_encoder_resolve_query_set(
|
||||
state: &mut OpState,
|
||||
args: CommandEncoderResolveQuerySetArgs,
|
||||
|
@ -624,6 +638,7 @@ pub struct CommandEncoderFinishArgs {
|
|||
label: Option<String>,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_command_encoder_finish(
|
||||
state: &mut OpState,
|
||||
args: CommandEncoderFinishArgs,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op;
|
||||
use deno_core::ResourceId;
|
||||
use deno_core::ZeroCopyBuf;
|
||||
use deno_core::{OpState, Resource};
|
||||
|
@ -26,6 +27,7 @@ pub struct ComputePassSetPipelineArgs {
|
|||
pipeline: ResourceId,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_compute_pass_set_pipeline(
|
||||
state: &mut OpState,
|
||||
args: ComputePassSetPipelineArgs,
|
||||
|
@ -56,6 +58,7 @@ pub struct ComputePassDispatchArgs {
|
|||
z: u32,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_compute_pass_dispatch(
|
||||
state: &mut OpState,
|
||||
args: ComputePassDispatchArgs,
|
||||
|
@ -83,6 +86,7 @@ pub struct ComputePassDispatchIndirectArgs {
|
|||
indirect_offset: u64,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_compute_pass_dispatch_indirect(
|
||||
state: &mut OpState,
|
||||
args: ComputePassDispatchIndirectArgs,
|
||||
|
@ -112,6 +116,7 @@ pub struct ComputePassBeginPipelineStatisticsQueryArgs {
|
|||
query_index: u32,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_compute_pass_begin_pipeline_statistics_query(
|
||||
state: &mut OpState,
|
||||
args: ComputePassBeginPipelineStatisticsQueryArgs,
|
||||
|
@ -139,6 +144,7 @@ pub struct ComputePassEndPipelineStatisticsQueryArgs {
|
|||
compute_pass_rid: ResourceId,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_compute_pass_end_pipeline_statistics_query(
|
||||
state: &mut OpState,
|
||||
args: ComputePassEndPipelineStatisticsQueryArgs,
|
||||
|
@ -163,6 +169,7 @@ pub struct ComputePassWriteTimestampArgs {
|
|||
query_index: u32,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_compute_pass_write_timestamp(
|
||||
state: &mut OpState,
|
||||
args: ComputePassWriteTimestampArgs,
|
||||
|
@ -191,6 +198,7 @@ pub struct ComputePassEndPassArgs {
|
|||
compute_pass_rid: ResourceId,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_compute_pass_end_pass(
|
||||
state: &mut OpState,
|
||||
args: ComputePassEndPassArgs,
|
||||
|
@ -225,6 +233,7 @@ pub struct ComputePassSetBindGroupArgs {
|
|||
dynamic_offsets_data_length: usize,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_compute_pass_set_bind_group(
|
||||
state: &mut OpState,
|
||||
args: ComputePassSetBindGroupArgs,
|
||||
|
@ -278,6 +287,7 @@ pub struct ComputePassPushDebugGroupArgs {
|
|||
group_label: String,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_compute_pass_push_debug_group(
|
||||
state: &mut OpState,
|
||||
args: ComputePassPushDebugGroupArgs,
|
||||
|
@ -307,6 +317,7 @@ pub struct ComputePassPopDebugGroupArgs {
|
|||
compute_pass_rid: ResourceId,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_compute_pass_pop_debug_group(
|
||||
state: &mut OpState,
|
||||
args: ComputePassPopDebugGroupArgs,
|
||||
|
@ -330,6 +341,7 @@ pub struct ComputePassInsertDebugMarkerArgs {
|
|||
marker_label: String,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_compute_pass_insert_debug_marker(
|
||||
state: &mut OpState,
|
||||
args: ComputePassInsertDebugMarkerArgs,
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::include_js_files;
|
||||
use deno_core::op_async;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::op;
|
||||
|
||||
use deno_core::Extension;
|
||||
use deno_core::OpFn;
|
||||
use deno_core::OpPair;
|
||||
use deno_core::OpState;
|
||||
use deno_core::Resource;
|
||||
use deno_core::ResourceId;
|
||||
|
@ -241,6 +241,7 @@ pub struct GpuAdapterDevice {
|
|||
is_software: bool,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub async fn op_webgpu_request_adapter(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: RequestAdapterArgs,
|
||||
|
@ -439,6 +440,7 @@ impl From<GpuRequiredFeatures> for wgpu_types::Features {
|
|||
}
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub async fn op_webgpu_request_device(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: RequestDeviceArgs,
|
||||
|
@ -539,6 +541,7 @@ impl From<GpuQueryType> for wgpu_types::QueryType {
|
|||
}
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_create_query_set(
|
||||
state: &mut OpState,
|
||||
args: CreateQuerySetArgs,
|
||||
|
@ -562,347 +565,102 @@ pub fn op_webgpu_create_query_set(
|
|||
) => state, WebGpuQuerySet)
|
||||
}
|
||||
|
||||
fn declare_webgpu_ops() -> Vec<(&'static str, Box<OpFn>)> {
|
||||
fn declare_webgpu_ops() -> Vec<OpPair> {
|
||||
vec![
|
||||
// Request device/adapter
|
||||
(
|
||||
"op_webgpu_request_adapter",
|
||||
op_async(op_webgpu_request_adapter),
|
||||
),
|
||||
(
|
||||
"op_webgpu_request_device",
|
||||
op_async(op_webgpu_request_device),
|
||||
),
|
||||
op_webgpu_request_adapter::decl(),
|
||||
op_webgpu_request_device::decl(),
|
||||
// Query Set
|
||||
(
|
||||
"op_webgpu_create_query_set",
|
||||
op_sync(op_webgpu_create_query_set),
|
||||
),
|
||||
op_webgpu_create_query_set::decl(),
|
||||
// buffer
|
||||
(
|
||||
"op_webgpu_create_buffer",
|
||||
op_sync(buffer::op_webgpu_create_buffer),
|
||||
),
|
||||
(
|
||||
"op_webgpu_buffer_get_mapped_range",
|
||||
op_sync(buffer::op_webgpu_buffer_get_mapped_range),
|
||||
),
|
||||
(
|
||||
"op_webgpu_buffer_unmap",
|
||||
op_sync(buffer::op_webgpu_buffer_unmap),
|
||||
),
|
||||
buffer::op_webgpu_create_buffer::decl(),
|
||||
buffer::op_webgpu_buffer_get_mapped_range::decl(),
|
||||
buffer::op_webgpu_buffer_unmap::decl(),
|
||||
// buffer async
|
||||
(
|
||||
"op_webgpu_buffer_get_map_async",
|
||||
op_async(buffer::op_webgpu_buffer_get_map_async),
|
||||
),
|
||||
buffer::op_webgpu_buffer_get_map_async::decl(),
|
||||
// remaining sync ops
|
||||
|
||||
// texture
|
||||
(
|
||||
"op_webgpu_create_texture",
|
||||
op_sync(texture::op_webgpu_create_texture),
|
||||
),
|
||||
(
|
||||
"op_webgpu_create_texture_view",
|
||||
op_sync(texture::op_webgpu_create_texture_view),
|
||||
),
|
||||
texture::op_webgpu_create_texture::decl(),
|
||||
texture::op_webgpu_create_texture_view::decl(),
|
||||
// sampler
|
||||
(
|
||||
"op_webgpu_create_sampler",
|
||||
op_sync(sampler::op_webgpu_create_sampler),
|
||||
),
|
||||
sampler::op_webgpu_create_sampler::decl(),
|
||||
// binding
|
||||
(
|
||||
"op_webgpu_create_bind_group_layout",
|
||||
op_sync(binding::op_webgpu_create_bind_group_layout),
|
||||
),
|
||||
(
|
||||
"op_webgpu_create_pipeline_layout",
|
||||
op_sync(binding::op_webgpu_create_pipeline_layout),
|
||||
),
|
||||
(
|
||||
"op_webgpu_create_bind_group",
|
||||
op_sync(binding::op_webgpu_create_bind_group),
|
||||
),
|
||||
binding::op_webgpu_create_bind_group_layout::decl(),
|
||||
binding::op_webgpu_create_pipeline_layout::decl(),
|
||||
binding::op_webgpu_create_bind_group::decl(),
|
||||
// pipeline
|
||||
(
|
||||
"op_webgpu_create_compute_pipeline",
|
||||
op_sync(pipeline::op_webgpu_create_compute_pipeline),
|
||||
),
|
||||
(
|
||||
"op_webgpu_compute_pipeline_get_bind_group_layout",
|
||||
op_sync(pipeline::op_webgpu_compute_pipeline_get_bind_group_layout),
|
||||
),
|
||||
(
|
||||
"op_webgpu_create_render_pipeline",
|
||||
op_sync(pipeline::op_webgpu_create_render_pipeline),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_pipeline_get_bind_group_layout",
|
||||
op_sync(pipeline::op_webgpu_render_pipeline_get_bind_group_layout),
|
||||
),
|
||||
pipeline::op_webgpu_create_compute_pipeline::decl(),
|
||||
pipeline::op_webgpu_compute_pipeline_get_bind_group_layout::decl(),
|
||||
pipeline::op_webgpu_create_render_pipeline::decl(),
|
||||
pipeline::op_webgpu_render_pipeline_get_bind_group_layout::decl(),
|
||||
// command_encoder
|
||||
(
|
||||
"op_webgpu_create_command_encoder",
|
||||
op_sync(command_encoder::op_webgpu_create_command_encoder),
|
||||
),
|
||||
(
|
||||
"op_webgpu_command_encoder_begin_render_pass",
|
||||
op_sync(command_encoder::op_webgpu_command_encoder_begin_render_pass),
|
||||
),
|
||||
(
|
||||
"op_webgpu_command_encoder_begin_compute_pass",
|
||||
op_sync(command_encoder::op_webgpu_command_encoder_begin_compute_pass),
|
||||
),
|
||||
(
|
||||
"op_webgpu_command_encoder_copy_buffer_to_buffer",
|
||||
op_sync(command_encoder::op_webgpu_command_encoder_copy_buffer_to_buffer),
|
||||
),
|
||||
(
|
||||
"op_webgpu_command_encoder_copy_buffer_to_texture",
|
||||
op_sync(
|
||||
command_encoder::op_webgpu_command_encoder_copy_buffer_to_texture,
|
||||
),
|
||||
),
|
||||
(
|
||||
"op_webgpu_command_encoder_copy_texture_to_buffer",
|
||||
op_sync(
|
||||
command_encoder::op_webgpu_command_encoder_copy_texture_to_buffer,
|
||||
),
|
||||
),
|
||||
(
|
||||
"op_webgpu_command_encoder_copy_texture_to_texture",
|
||||
op_sync(
|
||||
command_encoder::op_webgpu_command_encoder_copy_texture_to_texture,
|
||||
),
|
||||
),
|
||||
(
|
||||
"op_webgpu_command_encoder_clear_buffer",
|
||||
op_sync(command_encoder::op_webgpu_command_encoder_clear_buffer),
|
||||
),
|
||||
(
|
||||
"op_webgpu_command_encoder_push_debug_group",
|
||||
op_sync(command_encoder::op_webgpu_command_encoder_push_debug_group),
|
||||
),
|
||||
(
|
||||
"op_webgpu_command_encoder_pop_debug_group",
|
||||
op_sync(command_encoder::op_webgpu_command_encoder_pop_debug_group),
|
||||
),
|
||||
(
|
||||
"op_webgpu_command_encoder_insert_debug_marker",
|
||||
op_sync(command_encoder::op_webgpu_command_encoder_insert_debug_marker),
|
||||
),
|
||||
(
|
||||
"op_webgpu_command_encoder_write_timestamp",
|
||||
op_sync(command_encoder::op_webgpu_command_encoder_write_timestamp),
|
||||
),
|
||||
(
|
||||
"op_webgpu_command_encoder_resolve_query_set",
|
||||
op_sync(command_encoder::op_webgpu_command_encoder_resolve_query_set),
|
||||
),
|
||||
(
|
||||
"op_webgpu_command_encoder_finish",
|
||||
op_sync(command_encoder::op_webgpu_command_encoder_finish),
|
||||
),
|
||||
command_encoder::op_webgpu_create_command_encoder::decl(),
|
||||
command_encoder::op_webgpu_command_encoder_begin_render_pass::decl(),
|
||||
command_encoder::op_webgpu_command_encoder_begin_compute_pass::decl(),
|
||||
command_encoder::op_webgpu_command_encoder_copy_buffer_to_buffer::decl(),
|
||||
command_encoder::op_webgpu_command_encoder_copy_buffer_to_texture::decl(),
|
||||
command_encoder::op_webgpu_command_encoder_copy_texture_to_buffer::decl(),
|
||||
command_encoder::op_webgpu_command_encoder_copy_texture_to_texture::decl(),
|
||||
command_encoder::op_webgpu_command_encoder_clear_buffer::decl(),
|
||||
command_encoder::op_webgpu_command_encoder_push_debug_group::decl(),
|
||||
command_encoder::op_webgpu_command_encoder_pop_debug_group::decl(),
|
||||
command_encoder::op_webgpu_command_encoder_insert_debug_marker::decl(),
|
||||
command_encoder::op_webgpu_command_encoder_write_timestamp::decl(),
|
||||
command_encoder::op_webgpu_command_encoder_resolve_query_set::decl(),
|
||||
command_encoder::op_webgpu_command_encoder_finish::decl(),
|
||||
// render_pass
|
||||
(
|
||||
"op_webgpu_render_pass_set_viewport",
|
||||
op_sync(render_pass::op_webgpu_render_pass_set_viewport),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_pass_set_scissor_rect",
|
||||
op_sync(render_pass::op_webgpu_render_pass_set_scissor_rect),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_pass_set_blend_constant",
|
||||
op_sync(render_pass::op_webgpu_render_pass_set_blend_constant),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_pass_set_stencil_reference",
|
||||
op_sync(render_pass::op_webgpu_render_pass_set_stencil_reference),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_pass_begin_pipeline_statistics_query",
|
||||
op_sync(
|
||||
render_pass::op_webgpu_render_pass_begin_pipeline_statistics_query,
|
||||
),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_pass_end_pipeline_statistics_query",
|
||||
op_sync(render_pass::op_webgpu_render_pass_end_pipeline_statistics_query),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_pass_write_timestamp",
|
||||
op_sync(render_pass::op_webgpu_render_pass_write_timestamp),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_pass_execute_bundles",
|
||||
op_sync(render_pass::op_webgpu_render_pass_execute_bundles),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_pass_end_pass",
|
||||
op_sync(render_pass::op_webgpu_render_pass_end_pass),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_pass_set_bind_group",
|
||||
op_sync(render_pass::op_webgpu_render_pass_set_bind_group),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_pass_push_debug_group",
|
||||
op_sync(render_pass::op_webgpu_render_pass_push_debug_group),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_pass_pop_debug_group",
|
||||
op_sync(render_pass::op_webgpu_render_pass_pop_debug_group),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_pass_insert_debug_marker",
|
||||
op_sync(render_pass::op_webgpu_render_pass_insert_debug_marker),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_pass_set_pipeline",
|
||||
op_sync(render_pass::op_webgpu_render_pass_set_pipeline),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_pass_set_index_buffer",
|
||||
op_sync(render_pass::op_webgpu_render_pass_set_index_buffer),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_pass_set_vertex_buffer",
|
||||
op_sync(render_pass::op_webgpu_render_pass_set_vertex_buffer),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_pass_draw",
|
||||
op_sync(render_pass::op_webgpu_render_pass_draw),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_pass_draw_indexed",
|
||||
op_sync(render_pass::op_webgpu_render_pass_draw_indexed),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_pass_draw_indirect",
|
||||
op_sync(render_pass::op_webgpu_render_pass_draw_indirect),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_pass_draw_indexed_indirect",
|
||||
op_sync(render_pass::op_webgpu_render_pass_draw_indexed_indirect),
|
||||
),
|
||||
render_pass::op_webgpu_render_pass_set_viewport::decl(),
|
||||
render_pass::op_webgpu_render_pass_set_scissor_rect::decl(),
|
||||
render_pass::op_webgpu_render_pass_set_blend_constant::decl(),
|
||||
render_pass::op_webgpu_render_pass_set_stencil_reference::decl(),
|
||||
render_pass::op_webgpu_render_pass_begin_pipeline_statistics_query::decl(),
|
||||
render_pass::op_webgpu_render_pass_end_pipeline_statistics_query::decl(),
|
||||
render_pass::op_webgpu_render_pass_write_timestamp::decl(),
|
||||
render_pass::op_webgpu_render_pass_execute_bundles::decl(),
|
||||
render_pass::op_webgpu_render_pass_end_pass::decl(),
|
||||
render_pass::op_webgpu_render_pass_set_bind_group::decl(),
|
||||
render_pass::op_webgpu_render_pass_push_debug_group::decl(),
|
||||
render_pass::op_webgpu_render_pass_pop_debug_group::decl(),
|
||||
render_pass::op_webgpu_render_pass_insert_debug_marker::decl(),
|
||||
render_pass::op_webgpu_render_pass_set_pipeline::decl(),
|
||||
render_pass::op_webgpu_render_pass_set_index_buffer::decl(),
|
||||
render_pass::op_webgpu_render_pass_set_vertex_buffer::decl(),
|
||||
render_pass::op_webgpu_render_pass_draw::decl(),
|
||||
render_pass::op_webgpu_render_pass_draw_indexed::decl(),
|
||||
render_pass::op_webgpu_render_pass_draw_indirect::decl(),
|
||||
render_pass::op_webgpu_render_pass_draw_indexed_indirect::decl(),
|
||||
// compute_pass
|
||||
(
|
||||
"op_webgpu_compute_pass_set_pipeline",
|
||||
op_sync(compute_pass::op_webgpu_compute_pass_set_pipeline),
|
||||
),
|
||||
(
|
||||
"op_webgpu_compute_pass_dispatch",
|
||||
op_sync(compute_pass::op_webgpu_compute_pass_dispatch),
|
||||
),
|
||||
(
|
||||
"op_webgpu_compute_pass_dispatch_indirect",
|
||||
op_sync(compute_pass::op_webgpu_compute_pass_dispatch_indirect),
|
||||
),
|
||||
(
|
||||
"op_webgpu_compute_pass_begin_pipeline_statistics_query",
|
||||
op_sync(
|
||||
compute_pass::op_webgpu_compute_pass_begin_pipeline_statistics_query,
|
||||
),
|
||||
),
|
||||
(
|
||||
"op_webgpu_compute_pass_end_pipeline_statistics_query",
|
||||
op_sync(
|
||||
compute_pass::op_webgpu_compute_pass_end_pipeline_statistics_query,
|
||||
),
|
||||
),
|
||||
(
|
||||
"op_webgpu_compute_pass_write_timestamp",
|
||||
op_sync(compute_pass::op_webgpu_compute_pass_write_timestamp),
|
||||
),
|
||||
(
|
||||
"op_webgpu_compute_pass_end_pass",
|
||||
op_sync(compute_pass::op_webgpu_compute_pass_end_pass),
|
||||
),
|
||||
(
|
||||
"op_webgpu_compute_pass_set_bind_group",
|
||||
op_sync(compute_pass::op_webgpu_compute_pass_set_bind_group),
|
||||
),
|
||||
(
|
||||
"op_webgpu_compute_pass_push_debug_group",
|
||||
op_sync(compute_pass::op_webgpu_compute_pass_push_debug_group),
|
||||
),
|
||||
(
|
||||
"op_webgpu_compute_pass_pop_debug_group",
|
||||
op_sync(compute_pass::op_webgpu_compute_pass_pop_debug_group),
|
||||
),
|
||||
(
|
||||
"op_webgpu_compute_pass_insert_debug_marker",
|
||||
op_sync(compute_pass::op_webgpu_compute_pass_insert_debug_marker),
|
||||
compute_pass::op_webgpu_compute_pass_set_pipeline::decl(),
|
||||
compute_pass::op_webgpu_compute_pass_dispatch::decl(),
|
||||
compute_pass::op_webgpu_compute_pass_dispatch_indirect::decl(),
|
||||
compute_pass::op_webgpu_compute_pass_begin_pipeline_statistics_query::decl(
|
||||
),
|
||||
compute_pass::op_webgpu_compute_pass_end_pipeline_statistics_query::decl(),
|
||||
compute_pass::op_webgpu_compute_pass_write_timestamp::decl(),
|
||||
compute_pass::op_webgpu_compute_pass_end_pass::decl(),
|
||||
compute_pass::op_webgpu_compute_pass_set_bind_group::decl(),
|
||||
compute_pass::op_webgpu_compute_pass_push_debug_group::decl(),
|
||||
compute_pass::op_webgpu_compute_pass_pop_debug_group::decl(),
|
||||
compute_pass::op_webgpu_compute_pass_insert_debug_marker::decl(),
|
||||
// bundle
|
||||
(
|
||||
"op_webgpu_create_render_bundle_encoder",
|
||||
op_sync(bundle::op_webgpu_create_render_bundle_encoder),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_bundle_encoder_finish",
|
||||
op_sync(bundle::op_webgpu_render_bundle_encoder_finish),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_bundle_encoder_set_bind_group",
|
||||
op_sync(bundle::op_webgpu_render_bundle_encoder_set_bind_group),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_bundle_encoder_push_debug_group",
|
||||
op_sync(bundle::op_webgpu_render_bundle_encoder_push_debug_group),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_bundle_encoder_pop_debug_group",
|
||||
op_sync(bundle::op_webgpu_render_bundle_encoder_pop_debug_group),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_bundle_encoder_insert_debug_marker",
|
||||
op_sync(bundle::op_webgpu_render_bundle_encoder_insert_debug_marker),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_bundle_encoder_set_pipeline",
|
||||
op_sync(bundle::op_webgpu_render_bundle_encoder_set_pipeline),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_bundle_encoder_set_index_buffer",
|
||||
op_sync(bundle::op_webgpu_render_bundle_encoder_set_index_buffer),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_bundle_encoder_set_vertex_buffer",
|
||||
op_sync(bundle::op_webgpu_render_bundle_encoder_set_vertex_buffer),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_bundle_encoder_draw",
|
||||
op_sync(bundle::op_webgpu_render_bundle_encoder_draw),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_bundle_encoder_draw_indexed",
|
||||
op_sync(bundle::op_webgpu_render_bundle_encoder_draw_indexed),
|
||||
),
|
||||
(
|
||||
"op_webgpu_render_bundle_encoder_draw_indirect",
|
||||
op_sync(bundle::op_webgpu_render_bundle_encoder_draw_indirect),
|
||||
),
|
||||
bundle::op_webgpu_create_render_bundle_encoder::decl(),
|
||||
bundle::op_webgpu_render_bundle_encoder_finish::decl(),
|
||||
bundle::op_webgpu_render_bundle_encoder_set_bind_group::decl(),
|
||||
bundle::op_webgpu_render_bundle_encoder_push_debug_group::decl(),
|
||||
bundle::op_webgpu_render_bundle_encoder_pop_debug_group::decl(),
|
||||
bundle::op_webgpu_render_bundle_encoder_insert_debug_marker::decl(),
|
||||
bundle::op_webgpu_render_bundle_encoder_set_pipeline::decl(),
|
||||
bundle::op_webgpu_render_bundle_encoder_set_index_buffer::decl(),
|
||||
bundle::op_webgpu_render_bundle_encoder_set_vertex_buffer::decl(),
|
||||
bundle::op_webgpu_render_bundle_encoder_draw::decl(),
|
||||
bundle::op_webgpu_render_bundle_encoder_draw_indexed::decl(),
|
||||
bundle::op_webgpu_render_bundle_encoder_draw_indirect::decl(),
|
||||
// queue
|
||||
(
|
||||
"op_webgpu_queue_submit",
|
||||
op_sync(queue::op_webgpu_queue_submit),
|
||||
),
|
||||
(
|
||||
"op_webgpu_write_buffer",
|
||||
op_sync(queue::op_webgpu_write_buffer),
|
||||
),
|
||||
(
|
||||
"op_webgpu_write_texture",
|
||||
op_sync(queue::op_webgpu_write_texture),
|
||||
),
|
||||
queue::op_webgpu_queue_submit::decl(),
|
||||
queue::op_webgpu_write_buffer::decl(),
|
||||
queue::op_webgpu_write_texture::decl(),
|
||||
// shader
|
||||
(
|
||||
"op_webgpu_create_shader_module",
|
||||
op_sync(shader::op_webgpu_create_shader_module),
|
||||
),
|
||||
shader::op_webgpu_create_shader_module::decl(),
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op;
|
||||
use deno_core::ResourceId;
|
||||
use deno_core::{OpState, Resource};
|
||||
use serde::Deserialize;
|
||||
|
@ -57,6 +58,7 @@ pub struct CreateComputePipelineArgs {
|
|||
compute: GpuProgrammableStage,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_create_compute_pipeline(
|
||||
state: &mut OpState,
|
||||
args: CreateComputePipelineArgs,
|
||||
|
@ -126,6 +128,7 @@ pub struct PipelineLayout {
|
|||
err: Option<WebGpuError>,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_compute_pipeline_get_bind_group_layout(
|
||||
state: &mut OpState,
|
||||
args: ComputePipelineGetBindGroupLayoutArgs,
|
||||
|
@ -303,6 +306,7 @@ pub struct CreateRenderPipelineArgs {
|
|||
fragment: Option<GpuFragmentState>,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_create_render_pipeline(
|
||||
state: &mut OpState,
|
||||
args: CreateRenderPipelineArgs,
|
||||
|
@ -404,6 +408,7 @@ pub struct RenderPipelineGetBindGroupLayoutArgs {
|
|||
index: u32,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_pipeline_get_bind_group_layout(
|
||||
state: &mut OpState,
|
||||
args: RenderPipelineGetBindGroupLayoutArgs,
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
use std::num::NonZeroU32;
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op;
|
||||
use deno_core::OpState;
|
||||
use deno_core::ResourceId;
|
||||
use deno_core::ZeroCopyBuf;
|
||||
|
@ -19,6 +20,7 @@ pub struct QueueSubmitArgs {
|
|||
command_buffers: Vec<ResourceId>,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_queue_submit(
|
||||
state: &mut OpState,
|
||||
args: QueueSubmitArgs,
|
||||
|
@ -73,6 +75,7 @@ pub struct QueueWriteBufferArgs {
|
|||
size: Option<usize>,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_write_buffer(
|
||||
state: &mut OpState,
|
||||
args: QueueWriteBufferArgs,
|
||||
|
@ -111,6 +114,7 @@ pub struct QueueWriteTextureArgs {
|
|||
size: wgpu_types::Extent3d,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_write_texture(
|
||||
state: &mut OpState,
|
||||
args: QueueWriteTextureArgs,
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
use deno_core::error::type_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op;
|
||||
use deno_core::ResourceId;
|
||||
use deno_core::ZeroCopyBuf;
|
||||
use deno_core::{OpState, Resource};
|
||||
|
@ -32,6 +33,7 @@ pub struct RenderPassSetViewportArgs {
|
|||
max_depth: f32,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_pass_set_viewport(
|
||||
state: &mut OpState,
|
||||
args: RenderPassSetViewportArgs,
|
||||
|
@ -64,6 +66,7 @@ pub struct RenderPassSetScissorRectArgs {
|
|||
height: u32,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_pass_set_scissor_rect(
|
||||
state: &mut OpState,
|
||||
args: RenderPassSetScissorRectArgs,
|
||||
|
@ -91,6 +94,7 @@ pub struct RenderPassSetBlendConstantArgs {
|
|||
color: wgpu_types::Color,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_pass_set_blend_constant(
|
||||
state: &mut OpState,
|
||||
args: RenderPassSetBlendConstantArgs,
|
||||
|
@ -115,6 +119,7 @@ pub struct RenderPassSetStencilReferenceArgs {
|
|||
reference: u32,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_pass_set_stencil_reference(
|
||||
state: &mut OpState,
|
||||
args: RenderPassSetStencilReferenceArgs,
|
||||
|
@ -140,6 +145,7 @@ pub struct RenderPassBeginPipelineStatisticsQueryArgs {
|
|||
query_index: u32,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_pass_begin_pipeline_statistics_query(
|
||||
state: &mut OpState,
|
||||
args: RenderPassBeginPipelineStatisticsQueryArgs,
|
||||
|
@ -167,6 +173,7 @@ pub struct RenderPassEndPipelineStatisticsQueryArgs {
|
|||
render_pass_rid: ResourceId,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_pass_end_pipeline_statistics_query(
|
||||
state: &mut OpState,
|
||||
args: RenderPassEndPipelineStatisticsQueryArgs,
|
||||
|
@ -191,6 +198,7 @@ pub struct RenderPassWriteTimestampArgs {
|
|||
query_index: u32,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_pass_write_timestamp(
|
||||
state: &mut OpState,
|
||||
args: RenderPassWriteTimestampArgs,
|
||||
|
@ -219,6 +227,7 @@ pub struct RenderPassExecuteBundlesArgs {
|
|||
bundles: Vec<u32>,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_pass_execute_bundles(
|
||||
state: &mut OpState,
|
||||
args: RenderPassExecuteBundlesArgs,
|
||||
|
@ -258,6 +267,7 @@ pub struct RenderPassEndPassArgs {
|
|||
render_pass_rid: ResourceId,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_pass_end_pass(
|
||||
state: &mut OpState,
|
||||
args: RenderPassEndPassArgs,
|
||||
|
@ -289,6 +299,7 @@ pub struct RenderPassSetBindGroupArgs {
|
|||
dynamic_offsets_data_length: usize,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_pass_set_bind_group(
|
||||
state: &mut OpState,
|
||||
args: RenderPassSetBindGroupArgs,
|
||||
|
@ -342,6 +353,7 @@ pub struct RenderPassPushDebugGroupArgs {
|
|||
group_label: String,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_pass_push_debug_group(
|
||||
state: &mut OpState,
|
||||
args: RenderPassPushDebugGroupArgs,
|
||||
|
@ -371,6 +383,7 @@ pub struct RenderPassPopDebugGroupArgs {
|
|||
render_pass_rid: ResourceId,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_pass_pop_debug_group(
|
||||
state: &mut OpState,
|
||||
args: RenderPassPopDebugGroupArgs,
|
||||
|
@ -394,6 +407,7 @@ pub struct RenderPassInsertDebugMarkerArgs {
|
|||
marker_label: String,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_pass_insert_debug_marker(
|
||||
state: &mut OpState,
|
||||
args: RenderPassInsertDebugMarkerArgs,
|
||||
|
@ -424,6 +438,7 @@ pub struct RenderPassSetPipelineArgs {
|
|||
pipeline: u32,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_pass_set_pipeline(
|
||||
state: &mut OpState,
|
||||
args: RenderPassSetPipelineArgs,
|
||||
|
@ -455,6 +470,7 @@ pub struct RenderPassSetIndexBufferArgs {
|
|||
size: Option<u64>,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_pass_set_index_buffer(
|
||||
state: &mut OpState,
|
||||
args: RenderPassSetIndexBufferArgs,
|
||||
|
@ -496,6 +512,7 @@ pub struct RenderPassSetVertexBufferArgs {
|
|||
size: Option<u64>,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_pass_set_vertex_buffer(
|
||||
state: &mut OpState,
|
||||
args: RenderPassSetVertexBufferArgs,
|
||||
|
@ -538,6 +555,7 @@ pub struct RenderPassDrawArgs {
|
|||
first_instance: u32,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_pass_draw(
|
||||
state: &mut OpState,
|
||||
args: RenderPassDrawArgs,
|
||||
|
@ -569,6 +587,7 @@ pub struct RenderPassDrawIndexedArgs {
|
|||
first_instance: u32,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_pass_draw_indexed(
|
||||
state: &mut OpState,
|
||||
args: RenderPassDrawIndexedArgs,
|
||||
|
@ -598,6 +617,7 @@ pub struct RenderPassDrawIndirectArgs {
|
|||
indirect_offset: u64,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_pass_draw_indirect(
|
||||
state: &mut OpState,
|
||||
args: RenderPassDrawIndirectArgs,
|
||||
|
@ -627,6 +647,7 @@ pub struct RenderPassDrawIndexedIndirectArgs {
|
|||
indirect_offset: u64,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_render_pass_draw_indexed_indirect(
|
||||
state: &mut OpState,
|
||||
args: RenderPassDrawIndexedIndirectArgs,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op;
|
||||
use deno_core::ResourceId;
|
||||
use deno_core::{OpState, Resource};
|
||||
use serde::Deserialize;
|
||||
|
@ -32,6 +33,7 @@ pub struct CreateSamplerArgs {
|
|||
max_anisotropy: u8,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_create_sampler(
|
||||
state: &mut OpState,
|
||||
args: CreateSamplerArgs,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op;
|
||||
use deno_core::ResourceId;
|
||||
use deno_core::{OpState, Resource};
|
||||
use serde::Deserialize;
|
||||
|
@ -24,6 +25,7 @@ pub struct CreateShaderModuleArgs {
|
|||
_source_map: Option<()>, // not yet implemented
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_create_shader_module(
|
||||
state: &mut OpState,
|
||||
args: CreateShaderModuleArgs,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op;
|
||||
use deno_core::ResourceId;
|
||||
use deno_core::{OpState, Resource};
|
||||
use serde::Deserialize;
|
||||
|
@ -34,6 +35,7 @@ pub struct CreateTextureArgs {
|
|||
usage: u32,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_create_texture(
|
||||
state: &mut OpState,
|
||||
args: CreateTextureArgs,
|
||||
|
@ -76,6 +78,7 @@ pub struct CreateTextureViewArgs {
|
|||
array_layer_count: Option<u32>,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webgpu_create_texture_view(
|
||||
state: &mut OpState,
|
||||
args: CreateTextureViewArgs,
|
||||
|
|
|
@ -8,8 +8,8 @@ use deno_core::futures::stream::SplitStream;
|
|||
use deno_core::futures::SinkExt;
|
||||
use deno_core::futures::StreamExt;
|
||||
use deno_core::include_js_files;
|
||||
use deno_core::op_async;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::op;
|
||||
|
||||
use deno_core::url;
|
||||
use deno_core::AsyncRefCell;
|
||||
use deno_core::ByteString;
|
||||
|
@ -190,6 +190,7 @@ impl Resource for WsCancelResource {
|
|||
// This op is needed because creating a WS instance in JavaScript is a sync
|
||||
// operation and should throw error when permissions are not fulfilled,
|
||||
// but actual op that connects WS is async.
|
||||
#[op]
|
||||
pub fn op_ws_check_permission_and_cancel_handle<WP>(
|
||||
state: &mut OpState,
|
||||
url: String,
|
||||
|
@ -229,6 +230,7 @@ pub struct CreateResponse {
|
|||
extensions: String,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub async fn op_ws_create<WP>(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: CreateArgs,
|
||||
|
@ -378,6 +380,7 @@ pub enum SendValue {
|
|||
Ping,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub async fn op_ws_send(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
rid: ResourceId,
|
||||
|
@ -406,6 +409,7 @@ pub struct CloseArgs {
|
|||
reason: Option<String>,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub async fn op_ws_close(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: CloseArgs,
|
||||
|
@ -440,6 +444,7 @@ pub enum NextEventResponse {
|
|||
Closed,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub async fn op_ws_next_event(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
rid: ResourceId,
|
||||
|
@ -486,14 +491,11 @@ pub fn init<P: WebSocketPermissions + 'static>(
|
|||
"02_websocketstream.js",
|
||||
))
|
||||
.ops(vec![
|
||||
(
|
||||
"op_ws_check_permission_and_cancel_handle",
|
||||
op_sync(op_ws_check_permission_and_cancel_handle::<P>),
|
||||
),
|
||||
("op_ws_create", op_async(op_ws_create::<P>)),
|
||||
("op_ws_send", op_async(op_ws_send)),
|
||||
("op_ws_close", op_async(op_ws_close)),
|
||||
("op_ws_next_event", op_async(op_ws_next_event)),
|
||||
op_ws_check_permission_and_cancel_handle::decl::<P>(),
|
||||
op_ws_create::decl::<P>(),
|
||||
op_ws_send::decl(),
|
||||
op_ws_close::decl(),
|
||||
op_ws_next_event::decl(),
|
||||
])
|
||||
.state(move |state| {
|
||||
state.put::<WsUserAgent>(WsUserAgent(user_agent.clone()));
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::include_js_files;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::op;
|
||||
use deno_core::Extension;
|
||||
use deno_core::OpState;
|
||||
use rusqlite::params;
|
||||
|
@ -26,16 +26,13 @@ pub fn init(origin_storage_dir: Option<PathBuf>) -> Extension {
|
|||
"01_webstorage.js",
|
||||
))
|
||||
.ops(vec![
|
||||
("op_webstorage_length", op_sync(op_webstorage_length)),
|
||||
("op_webstorage_key", op_sync(op_webstorage_key)),
|
||||
("op_webstorage_set", op_sync(op_webstorage_set)),
|
||||
("op_webstorage_get", op_sync(op_webstorage_get)),
|
||||
("op_webstorage_remove", op_sync(op_webstorage_remove)),
|
||||
("op_webstorage_clear", op_sync(op_webstorage_clear)),
|
||||
(
|
||||
"op_webstorage_iterate_keys",
|
||||
op_sync(op_webstorage_iterate_keys),
|
||||
),
|
||||
op_webstorage_length::decl(),
|
||||
op_webstorage_key::decl(),
|
||||
op_webstorage_set::decl(),
|
||||
op_webstorage_get::decl(),
|
||||
op_webstorage_remove::decl(),
|
||||
op_webstorage_clear::decl(),
|
||||
op_webstorage_iterate_keys::decl(),
|
||||
])
|
||||
.state(move |state| {
|
||||
if let Some(origin_storage_dir) = &origin_storage_dir {
|
||||
|
@ -103,6 +100,7 @@ fn get_webstorage(
|
|||
Ok(conn)
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webstorage_length(
|
||||
state: &mut OpState,
|
||||
persistent: bool,
|
||||
|
@ -116,6 +114,7 @@ pub fn op_webstorage_length(
|
|||
Ok(length)
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webstorage_key(
|
||||
state: &mut OpState,
|
||||
index: u32,
|
||||
|
@ -140,6 +139,7 @@ pub struct SetArgs {
|
|||
key_value: String,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webstorage_set(
|
||||
state: &mut OpState,
|
||||
args: SetArgs,
|
||||
|
@ -167,6 +167,7 @@ pub fn op_webstorage_set(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webstorage_get(
|
||||
state: &mut OpState,
|
||||
key_name: String,
|
||||
|
@ -182,6 +183,7 @@ pub fn op_webstorage_get(
|
|||
Ok(val)
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webstorage_remove(
|
||||
state: &mut OpState,
|
||||
key_name: String,
|
||||
|
@ -195,6 +197,7 @@ pub fn op_webstorage_remove(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webstorage_clear(
|
||||
state: &mut OpState,
|
||||
persistent: bool,
|
||||
|
@ -208,6 +211,7 @@ pub fn op_webstorage_clear(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_webstorage_iterate_keys(
|
||||
state: &mut OpState,
|
||||
persistent: bool,
|
||||
|
|
17
ops/Cargo.toml
Normal file
17
ops/Cargo.toml
Normal file
|
@ -0,0 +1,17 @@
|
|||
[package]
|
||||
name = "deno_ops"
|
||||
version = "0.1.1"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
readme = "README.md"
|
||||
description = "Proc macro for writing Deno Ops"
|
||||
|
||||
[lib]
|
||||
path = "./lib.rs"
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
proc-macro-crate = "1.1.3"
|
||||
proc-macro2 = "1"
|
||||
quote = "1"
|
||||
syn = { version = "1", features = ["full", "extra-traits"] }
|
16
ops/README.md
Normal file
16
ops/README.md
Normal file
|
@ -0,0 +1,16 @@
|
|||
# deno_ops
|
||||
|
||||
`proc_macro` for generating highly optimized V8 functions from Deno ops.
|
||||
|
||||
```rust
|
||||
// Declare an op.
|
||||
#[op]
|
||||
pub fn op_add(_: &mut OpState, a: i32, b: i32) -> Result<i32, AnyError> {
|
||||
Ok(a + b)
|
||||
}
|
||||
|
||||
// Register with an extension.
|
||||
Extension::builder()
|
||||
.ops(vec![op_add::decl()])
|
||||
.build();
|
||||
```
|
264
ops/lib.rs
Normal file
264
ops/lib.rs
Normal file
|
@ -0,0 +1,264 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::Span;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use proc_macro_crate::crate_name;
|
||||
use proc_macro_crate::FoundCrate;
|
||||
use quote::quote;
|
||||
use syn::Ident;
|
||||
|
||||
// Identifer to the `deno_core` crate.
|
||||
//
|
||||
// If macro called in deno_core, `crate` is used.
|
||||
// If macro called outside deno_core, `deno_core` OR the renamed
|
||||
// version from Cargo.toml is used.
|
||||
fn core_import() -> TokenStream2 {
|
||||
let found_crate =
|
||||
crate_name("deno_core").expect("deno_core not present in `Cargo.toml`");
|
||||
|
||||
match found_crate {
|
||||
FoundCrate::Itself => {
|
||||
// TODO(@littledivy): This won't work for `deno_core` examples
|
||||
// since `crate` does not refer to `deno_core`.
|
||||
// examples must re-export deno_core to make this work
|
||||
// until Span inspection APIs are stabalized.
|
||||
//
|
||||
// https://github.com/rust-lang/rust/issues/54725
|
||||
quote!(crate)
|
||||
}
|
||||
FoundCrate::Name(name) => {
|
||||
let ident = Ident::new(&name, Span::call_site());
|
||||
quote!(#ident)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn op(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let func = syn::parse::<syn::ItemFn>(item).expect("expected a function");
|
||||
let name = &func.sig.ident;
|
||||
let generics = &func.sig.generics;
|
||||
let type_params = &func.sig.generics.params;
|
||||
let where_clause = &func.sig.generics.where_clause;
|
||||
|
||||
// Preserve the original func as op_foo::call()
|
||||
let original_func = {
|
||||
let mut func = func.clone();
|
||||
func.sig.ident = quote::format_ident!("call");
|
||||
func
|
||||
};
|
||||
|
||||
let core = core_import();
|
||||
|
||||
let v8_body = if func.sig.asyncness.is_some() {
|
||||
codegen_v8_async(&core, &func)
|
||||
} else {
|
||||
codegen_v8_sync(&core, &func)
|
||||
};
|
||||
|
||||
// Generate wrapper
|
||||
quote! {
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct #name;
|
||||
|
||||
impl #name {
|
||||
pub fn name() -> &'static str {
|
||||
stringify!(#name)
|
||||
}
|
||||
|
||||
pub fn v8_cb #generics () -> #core::v8::FunctionCallback #where_clause {
|
||||
use #core::v8::MapFnTo;
|
||||
Self::v8_func::<#type_params>.map_fn_to()
|
||||
}
|
||||
|
||||
pub fn decl #generics () -> (&'static str, #core::v8::FunctionCallback) #where_clause {
|
||||
(Self::name(), Self::v8_cb::<#type_params>())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#original_func
|
||||
|
||||
pub fn v8_func #generics (
|
||||
scope: &mut #core::v8::HandleScope,
|
||||
args: #core::v8::FunctionCallbackArguments,
|
||||
mut rv: #core::v8::ReturnValue,
|
||||
) #where_clause {
|
||||
#v8_body
|
||||
}
|
||||
}
|
||||
}.into()
|
||||
}
|
||||
|
||||
/// Generate the body of a v8 func for an async op
|
||||
fn codegen_v8_async(core: &TokenStream2, f: &syn::ItemFn) -> TokenStream2 {
|
||||
let a = codegen_arg(core, &f.sig.inputs[1], "a", 2);
|
||||
let b = codegen_arg(core, &f.sig.inputs[2], "b", 3);
|
||||
let type_params = &f.sig.generics.params;
|
||||
|
||||
quote! {
|
||||
use #core::futures::FutureExt;
|
||||
// SAFETY: Called from Deno.core.opAsync. Which retrieves the index using opId table.
|
||||
let op_id = unsafe {
|
||||
#core::v8::Local::<#core::v8::Integer>::cast(args.get(0))
|
||||
}.value() as usize;
|
||||
|
||||
let promise_id = args.get(1);
|
||||
let promise_id = #core::v8::Local::<#core::v8::Integer>::try_from(promise_id)
|
||||
.map(|l| l.value() as #core::PromiseId)
|
||||
.map_err(#core::anyhow::Error::from);
|
||||
// Fail if promise id invalid (not an int)
|
||||
let promise_id: #core::PromiseId = match promise_id {
|
||||
Ok(promise_id) => promise_id,
|
||||
Err(err) => {
|
||||
#core::_ops::throw_type_error(scope, format!("invalid promise id: {}", err));
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
#a
|
||||
#b
|
||||
|
||||
// SAFETY: Unchecked cast to external since #core guarantees args.data() is a v8 External.
|
||||
let state_refcell_raw = unsafe {
|
||||
#core::v8::Local::<#core::v8::External>::cast(args.data().unwrap_unchecked())
|
||||
}.value();
|
||||
|
||||
// SAFETY: The Rc<RefCell<OpState>> is functionally pinned and is tied to the isolate's lifetime
|
||||
let state = unsafe {
|
||||
let ptr = state_refcell_raw as *const std::cell::RefCell<#core::OpState>;
|
||||
// Increment so it will later be decremented/dropped by the underlaying func it is moved to
|
||||
std::rc::Rc::increment_strong_count(ptr);
|
||||
std::rc::Rc::from_raw(ptr)
|
||||
};
|
||||
// Track async call & get copy of get_error_class_fn
|
||||
let get_class = {
|
||||
let state = state.borrow();
|
||||
state.tracker.track_async(op_id);
|
||||
state.get_error_class_fn
|
||||
};
|
||||
|
||||
#core::_ops::queue_async_op(scope, async move {
|
||||
let result = Self::call::<#type_params>(state, a, b).await;
|
||||
(promise_id, op_id, #core::_ops::to_op_result(get_class, result))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate the body of a v8 func for a sync op
|
||||
fn codegen_v8_sync(core: &TokenStream2, f: &syn::ItemFn) -> TokenStream2 {
|
||||
let a = codegen_arg(core, &f.sig.inputs[1], "a", 1);
|
||||
let b = codegen_arg(core, &f.sig.inputs[2], "b", 2);
|
||||
let ret = codegen_sync_ret(core, &f.sig.output);
|
||||
let type_params = &f.sig.generics.params;
|
||||
|
||||
quote! {
|
||||
// SAFETY: Called from Deno.core.opSync. Which retrieves the index using opId table.
|
||||
let op_id = unsafe {
|
||||
#core::v8::Local::<#core::v8::Integer>::cast(args.get(0)).value()
|
||||
} as usize;
|
||||
|
||||
#a
|
||||
#b
|
||||
|
||||
// SAFETY: Unchecked cast to external since #core guarantees args.data() is a v8 External.
|
||||
let state_refcell_raw = unsafe {
|
||||
#core::v8::Local::<#core::v8::External>::cast(args.data().unwrap_unchecked())
|
||||
}.value();
|
||||
|
||||
// SAFETY: The Rc<RefCell<OpState>> is functionally pinned and is tied to the isolate's lifetime
|
||||
let state = unsafe { &*(state_refcell_raw as *const std::cell::RefCell<#core::OpState>) };
|
||||
|
||||
let op_state = &mut state.borrow_mut();
|
||||
let result = Self::call::<#type_params>(op_state, a, b);
|
||||
|
||||
op_state.tracker.track_sync(op_id);
|
||||
|
||||
#ret
|
||||
}
|
||||
}
|
||||
|
||||
fn codegen_arg(
|
||||
core: &TokenStream2,
|
||||
arg: &syn::FnArg,
|
||||
name: &str,
|
||||
idx: i32,
|
||||
) -> TokenStream2 {
|
||||
let ident = quote::format_ident!("{name}");
|
||||
let pat = match arg {
|
||||
syn::FnArg::Typed(pat) => &pat.pat,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
// Fast path if arg should be skipped
|
||||
if matches!(**pat, syn::Pat::Wild(_)) {
|
||||
return quote! { let #ident = (); };
|
||||
}
|
||||
// Otherwise deserialize it via serde_v8
|
||||
quote! {
|
||||
let #ident = args.get(#idx);
|
||||
let #ident = match #core::serde_v8::from_v8(scope, #ident) {
|
||||
Ok(v) => v,
|
||||
Err(err) => {
|
||||
let msg = format!("Error parsing args: {}", #core::anyhow::Error::from(err));
|
||||
return #core::_ops::throw_type_error(scope, msg);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn codegen_sync_ret(
|
||||
core: &TokenStream2,
|
||||
output: &syn::ReturnType,
|
||||
) -> TokenStream2 {
|
||||
let ret_type = match output {
|
||||
// Func with no return no-ops
|
||||
syn::ReturnType::Default => return quote! { let ret = (); },
|
||||
// Func with a return Result<T, E>
|
||||
syn::ReturnType::Type(_, ty) => ty,
|
||||
};
|
||||
|
||||
// Optimize Result<(), Err> to skip serde_v8 when Ok(...)
|
||||
let ok_block = if is_unit_result(&**ret_type) {
|
||||
quote! {}
|
||||
} else {
|
||||
quote! {
|
||||
let ret = #core::serde_v8::to_v8(scope, v).unwrap();
|
||||
rv.set(ret);
|
||||
}
|
||||
};
|
||||
|
||||
quote! {
|
||||
match result {
|
||||
Ok(v) => {
|
||||
#ok_block
|
||||
},
|
||||
Err(err) => {
|
||||
let err = #core::OpError::new(op_state.get_error_class_fn, err);
|
||||
rv.set(#core::serde_v8::to_v8(scope, err).unwrap());
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// Detects if a type is of the form Result<(), Err>
|
||||
fn is_unit_result(ty: &syn::Type) -> bool {
|
||||
let path = match ty {
|
||||
syn::Type::Path(ref path) => path,
|
||||
_ => return false,
|
||||
};
|
||||
|
||||
let maybe_result = path.path.segments.first().expect("Invalid return type.");
|
||||
if maybe_result.ident != "Result" {
|
||||
return false;
|
||||
}
|
||||
assert!(!maybe_result.arguments.is_empty());
|
||||
|
||||
let args = match &maybe_result.arguments {
|
||||
syn::PathArguments::AngleBracketed(args) => args,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
match args.args.first().unwrap() {
|
||||
syn::GenericArgument::Type(syn::Type::Tuple(ty)) => ty.elems.is_empty(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
|
@ -8,8 +8,8 @@ use deno_core::error::bad_resource_id;
|
|||
use deno_core::error::custom_error;
|
||||
use deno_core::error::type_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op_async;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::op;
|
||||
|
||||
use deno_core::Extension;
|
||||
use deno_core::OpState;
|
||||
use deno_core::RcRef;
|
||||
|
@ -38,59 +38,59 @@ use deno_core::error::not_supported;
|
|||
pub fn init() -> Extension {
|
||||
Extension::builder()
|
||||
.ops(vec![
|
||||
("op_open_sync", op_sync(op_open_sync)),
|
||||
("op_open_async", op_async(op_open_async)),
|
||||
("op_seek_sync", op_sync(op_seek_sync)),
|
||||
("op_seek_async", op_async(op_seek_async)),
|
||||
("op_fdatasync_sync", op_sync(op_fdatasync_sync)),
|
||||
("op_fdatasync_async", op_async(op_fdatasync_async)),
|
||||
("op_fsync_sync", op_sync(op_fsync_sync)),
|
||||
("op_fsync_async", op_async(op_fsync_async)),
|
||||
("op_fstat_sync", op_sync(op_fstat_sync)),
|
||||
("op_fstat_async", op_async(op_fstat_async)),
|
||||
("op_flock_sync", op_sync(op_flock_sync)),
|
||||
("op_flock_async", op_async(op_flock_async)),
|
||||
("op_funlock_sync", op_sync(op_funlock_sync)),
|
||||
("op_funlock_async", op_async(op_funlock_async)),
|
||||
("op_umask", op_sync(op_umask)),
|
||||
("op_chdir", op_sync(op_chdir)),
|
||||
("op_mkdir_sync", op_sync(op_mkdir_sync)),
|
||||
("op_mkdir_async", op_async(op_mkdir_async)),
|
||||
("op_chmod_sync", op_sync(op_chmod_sync)),
|
||||
("op_chmod_async", op_async(op_chmod_async)),
|
||||
("op_chown_sync", op_sync(op_chown_sync)),
|
||||
("op_chown_async", op_async(op_chown_async)),
|
||||
("op_remove_sync", op_sync(op_remove_sync)),
|
||||
("op_remove_async", op_async(op_remove_async)),
|
||||
("op_copy_file_sync", op_sync(op_copy_file_sync)),
|
||||
("op_copy_file_async", op_async(op_copy_file_async)),
|
||||
("op_stat_sync", op_sync(op_stat_sync)),
|
||||
("op_stat_async", op_async(op_stat_async)),
|
||||
("op_realpath_sync", op_sync(op_realpath_sync)),
|
||||
("op_realpath_async", op_async(op_realpath_async)),
|
||||
("op_read_dir_sync", op_sync(op_read_dir_sync)),
|
||||
("op_read_dir_async", op_async(op_read_dir_async)),
|
||||
("op_rename_sync", op_sync(op_rename_sync)),
|
||||
("op_rename_async", op_async(op_rename_async)),
|
||||
("op_link_sync", op_sync(op_link_sync)),
|
||||
("op_link_async", op_async(op_link_async)),
|
||||
("op_symlink_sync", op_sync(op_symlink_sync)),
|
||||
("op_symlink_async", op_async(op_symlink_async)),
|
||||
("op_read_link_sync", op_sync(op_read_link_sync)),
|
||||
("op_read_link_async", op_async(op_read_link_async)),
|
||||
("op_ftruncate_sync", op_sync(op_ftruncate_sync)),
|
||||
("op_ftruncate_async", op_async(op_ftruncate_async)),
|
||||
("op_truncate_sync", op_sync(op_truncate_sync)),
|
||||
("op_truncate_async", op_async(op_truncate_async)),
|
||||
("op_make_temp_dir_sync", op_sync(op_make_temp_dir_sync)),
|
||||
("op_make_temp_dir_async", op_async(op_make_temp_dir_async)),
|
||||
("op_make_temp_file_sync", op_sync(op_make_temp_file_sync)),
|
||||
("op_make_temp_file_async", op_async(op_make_temp_file_async)),
|
||||
("op_cwd", op_sync(op_cwd)),
|
||||
("op_futime_sync", op_sync(op_futime_sync)),
|
||||
("op_futime_async", op_async(op_futime_async)),
|
||||
("op_utime_sync", op_sync(op_utime_sync)),
|
||||
("op_utime_async", op_async(op_utime_async)),
|
||||
op_open_sync::decl(),
|
||||
op_open_async::decl(),
|
||||
op_seek_sync::decl(),
|
||||
op_seek_async::decl(),
|
||||
op_fdatasync_sync::decl(),
|
||||
op_fdatasync_async::decl(),
|
||||
op_fsync_sync::decl(),
|
||||
op_fsync_async::decl(),
|
||||
op_fstat_sync::decl(),
|
||||
op_fstat_async::decl(),
|
||||
op_flock_sync::decl(),
|
||||
op_flock_async::decl(),
|
||||
op_funlock_sync::decl(),
|
||||
op_funlock_async::decl(),
|
||||
op_umask::decl(),
|
||||
op_chdir::decl(),
|
||||
op_mkdir_sync::decl(),
|
||||
op_mkdir_async::decl(),
|
||||
op_chmod_sync::decl(),
|
||||
op_chmod_async::decl(),
|
||||
op_chown_sync::decl(),
|
||||
op_chown_async::decl(),
|
||||
op_remove_sync::decl(),
|
||||
op_remove_async::decl(),
|
||||
op_copy_file_sync::decl(),
|
||||
op_copy_file_async::decl(),
|
||||
op_stat_sync::decl(),
|
||||
op_stat_async::decl(),
|
||||
op_realpath_sync::decl(),
|
||||
op_realpath_async::decl(),
|
||||
op_read_dir_sync::decl(),
|
||||
op_read_dir_async::decl(),
|
||||
op_rename_sync::decl(),
|
||||
op_rename_async::decl(),
|
||||
op_link_sync::decl(),
|
||||
op_link_async::decl(),
|
||||
op_symlink_sync::decl(),
|
||||
op_symlink_async::decl(),
|
||||
op_read_link_sync::decl(),
|
||||
op_read_link_async::decl(),
|
||||
op_ftruncate_sync::decl(),
|
||||
op_ftruncate_async::decl(),
|
||||
op_truncate_sync::decl(),
|
||||
op_truncate_async::decl(),
|
||||
op_make_temp_dir_sync::decl(),
|
||||
op_make_temp_dir_async::decl(),
|
||||
op_make_temp_file_sync::decl(),
|
||||
op_make_temp_file_async::decl(),
|
||||
op_cwd::decl(),
|
||||
op_futime_sync::decl(),
|
||||
op_futime_async::decl(),
|
||||
op_utime_sync::decl(),
|
||||
op_utime_async::decl(),
|
||||
])
|
||||
.build()
|
||||
}
|
||||
|
@ -157,6 +157,7 @@ fn open_helper(
|
|||
Ok((path, open_options))
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_open_sync(
|
||||
state: &mut OpState,
|
||||
args: OpenArgs,
|
||||
|
@ -172,6 +173,7 @@ fn op_open_sync(
|
|||
Ok(rid)
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_open_async(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: OpenArgs,
|
||||
|
@ -214,6 +216,7 @@ fn seek_helper(args: SeekArgs) -> Result<(u32, SeekFrom), AnyError> {
|
|||
Ok((rid, seek_from))
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_seek_sync(
|
||||
state: &mut OpState,
|
||||
args: SeekArgs,
|
||||
|
@ -229,6 +232,7 @@ fn op_seek_sync(
|
|||
Ok(pos)
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_seek_async(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: SeekArgs,
|
||||
|
@ -253,6 +257,7 @@ async fn op_seek_async(
|
|||
Ok(pos)
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_fdatasync_sync(
|
||||
state: &mut OpState,
|
||||
rid: ResourceId,
|
||||
|
@ -265,6 +270,7 @@ fn op_fdatasync_sync(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_fdatasync_async(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
rid: ResourceId,
|
||||
|
@ -287,6 +293,7 @@ async fn op_fdatasync_async(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_fsync_sync(
|
||||
state: &mut OpState,
|
||||
rid: ResourceId,
|
||||
|
@ -299,6 +306,7 @@ fn op_fsync_sync(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_fsync_async(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
rid: ResourceId,
|
||||
|
@ -321,6 +329,7 @@ async fn op_fsync_async(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_fstat_sync(
|
||||
state: &mut OpState,
|
||||
rid: ResourceId,
|
||||
|
@ -333,6 +342,7 @@ fn op_fstat_sync(
|
|||
Ok(get_stat(metadata))
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_fstat_async(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
rid: ResourceId,
|
||||
|
@ -355,6 +365,7 @@ async fn op_fstat_async(
|
|||
Ok(get_stat(metadata))
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_flock_sync(
|
||||
state: &mut OpState,
|
||||
rid: ResourceId,
|
||||
|
@ -376,6 +387,7 @@ fn op_flock_sync(
|
|||
})
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_flock_async(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
rid: ResourceId,
|
||||
|
@ -416,6 +428,7 @@ async fn op_flock_async(
|
|||
.await?
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_funlock_sync(
|
||||
state: &mut OpState,
|
||||
rid: ResourceId,
|
||||
|
@ -433,6 +446,7 @@ fn op_funlock_sync(
|
|||
})
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_funlock_async(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
rid: ResourceId,
|
||||
|
@ -469,6 +483,7 @@ async fn op_funlock_async(
|
|||
.await?
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_umask(
|
||||
state: &mut OpState,
|
||||
mask: Option<u32>,
|
||||
|
@ -501,6 +516,7 @@ fn op_umask(
|
|||
}
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_chdir(
|
||||
state: &mut OpState,
|
||||
directory: String,
|
||||
|
@ -522,6 +538,7 @@ pub struct MkdirArgs {
|
|||
mode: Option<u32>,
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_mkdir_sync(
|
||||
state: &mut OpState,
|
||||
args: MkdirArgs,
|
||||
|
@ -544,6 +561,7 @@ fn op_mkdir_sync(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_mkdir_async(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: MkdirArgs,
|
||||
|
@ -582,6 +600,7 @@ pub struct ChmodArgs {
|
|||
mode: u32,
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_chmod_sync(
|
||||
state: &mut OpState,
|
||||
args: ChmodArgs,
|
||||
|
@ -611,6 +630,7 @@ fn op_chmod_sync(
|
|||
}
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_chmod_async(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: ChmodArgs,
|
||||
|
@ -656,6 +676,7 @@ pub struct ChownArgs {
|
|||
gid: Option<u32>,
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_chown_sync(
|
||||
state: &mut OpState,
|
||||
args: ChownArgs,
|
||||
|
@ -690,6 +711,7 @@ fn op_chown_sync(
|
|||
}
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_chown_async(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: ChownArgs,
|
||||
|
@ -738,6 +760,7 @@ pub struct RemoveArgs {
|
|||
recursive: bool,
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_remove_sync(
|
||||
state: &mut OpState,
|
||||
args: RemoveArgs,
|
||||
|
@ -783,6 +806,7 @@ fn op_remove_sync(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_remove_async(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: RemoveArgs,
|
||||
|
@ -841,6 +865,7 @@ pub struct CopyFileArgs {
|
|||
to: String,
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_copy_file_sync(
|
||||
state: &mut OpState,
|
||||
args: CopyFileArgs,
|
||||
|
@ -879,6 +904,7 @@ fn op_copy_file_sync(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_copy_file_async(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: CopyFileArgs,
|
||||
|
@ -1007,6 +1033,7 @@ pub struct StatArgs {
|
|||
lstat: bool,
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_stat_sync(
|
||||
state: &mut OpState,
|
||||
args: StatArgs,
|
||||
|
@ -1027,6 +1054,7 @@ fn op_stat_sync(
|
|||
Ok(get_stat(metadata))
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_stat_async(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: StatArgs,
|
||||
|
@ -1056,6 +1084,7 @@ async fn op_stat_async(
|
|||
.unwrap()
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_realpath_sync(
|
||||
state: &mut OpState,
|
||||
path: String,
|
||||
|
@ -1077,6 +1106,7 @@ fn op_realpath_sync(
|
|||
Ok(realpath_str)
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_realpath_async(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
path: String,
|
||||
|
@ -1114,6 +1144,7 @@ pub struct DirEntry {
|
|||
is_symlink: bool,
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_read_dir_sync(
|
||||
state: &mut OpState,
|
||||
path: String,
|
||||
|
@ -1154,6 +1185,7 @@ fn op_read_dir_sync(
|
|||
Ok(entries)
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_read_dir_async(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
path: String,
|
||||
|
@ -1206,6 +1238,7 @@ pub struct RenameArgs {
|
|||
newpath: String,
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_rename_sync(
|
||||
state: &mut OpState,
|
||||
args: RenameArgs,
|
||||
|
@ -1234,6 +1267,7 @@ fn op_rename_sync(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_rename_async(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: RenameArgs,
|
||||
|
@ -1279,6 +1313,7 @@ pub struct LinkArgs {
|
|||
newpath: String,
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_link_sync(
|
||||
state: &mut OpState,
|
||||
args: LinkArgs,
|
||||
|
@ -1309,6 +1344,7 @@ fn op_link_sync(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_link_async(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: LinkArgs,
|
||||
|
@ -1362,6 +1398,7 @@ pub struct SymlinkOptions {
|
|||
_type: String,
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_symlink_sync(
|
||||
state: &mut OpState,
|
||||
args: SymlinkArgs,
|
||||
|
@ -1423,6 +1460,7 @@ fn op_symlink_sync(
|
|||
}
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_symlink_async(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: SymlinkArgs,
|
||||
|
@ -1487,6 +1525,7 @@ async fn op_symlink_async(
|
|||
.unwrap()
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_read_link_sync(
|
||||
state: &mut OpState,
|
||||
path: String,
|
||||
|
@ -1510,6 +1549,7 @@ fn op_read_link_sync(
|
|||
Ok(targetstr)
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_read_link_async(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
path: String,
|
||||
|
@ -1545,6 +1585,7 @@ pub struct FtruncateArgs {
|
|||
len: i32,
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_ftruncate_sync(
|
||||
state: &mut OpState,
|
||||
args: FtruncateArgs,
|
||||
|
@ -1559,6 +1600,7 @@ fn op_ftruncate_sync(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_ftruncate_async(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: FtruncateArgs,
|
||||
|
@ -1591,6 +1633,7 @@ pub struct TruncateArgs {
|
|||
len: u64,
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_truncate_sync(
|
||||
state: &mut OpState,
|
||||
args: TruncateArgs,
|
||||
|
@ -1616,6 +1659,7 @@ fn op_truncate_sync(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_truncate_async(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: TruncateArgs,
|
||||
|
@ -1699,6 +1743,7 @@ pub struct MakeTempArgs {
|
|||
suffix: Option<String>,
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_make_temp_dir_sync(
|
||||
state: &mut OpState,
|
||||
args: MakeTempArgs,
|
||||
|
@ -1728,6 +1773,7 @@ fn op_make_temp_dir_sync(
|
|||
Ok(path_str)
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_make_temp_dir_async(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: MakeTempArgs,
|
||||
|
@ -1762,6 +1808,7 @@ async fn op_make_temp_dir_async(
|
|||
.unwrap()
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_make_temp_file_sync(
|
||||
state: &mut OpState,
|
||||
args: MakeTempArgs,
|
||||
|
@ -1791,6 +1838,7 @@ fn op_make_temp_file_sync(
|
|||
Ok(path_str)
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_make_temp_file_async(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: MakeTempArgs,
|
||||
|
@ -1833,6 +1881,7 @@ pub struct FutimeArgs {
|
|||
mtime: (i64, u32),
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_futime_sync(
|
||||
state: &mut OpState,
|
||||
args: FutimeArgs,
|
||||
|
@ -1856,6 +1905,7 @@ fn op_futime_sync(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_futime_async(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: FutimeArgs,
|
||||
|
@ -1904,6 +1954,7 @@ pub struct UtimeArgs {
|
|||
mtime: (i64, u32),
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_utime_sync(
|
||||
state: &mut OpState,
|
||||
args: UtimeArgs,
|
||||
|
@ -1922,6 +1973,7 @@ fn op_utime_sync(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_utime_async(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
args: UtimeArgs,
|
||||
|
@ -1949,6 +2001,7 @@ async fn op_utime_async(
|
|||
.unwrap()
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_cwd(state: &mut OpState, _: (), _: ()) -> Result<String, AnyError> {
|
||||
let path = current_dir()?;
|
||||
state
|
||||
|
|
|
@ -11,8 +11,8 @@ use deno_core::RcRef;
|
|||
use deno_core::Resource;
|
||||
use deno_core::ResourceId;
|
||||
|
||||
use deno_core::op_async;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::op;
|
||||
|
||||
use deno_core::Extension;
|
||||
use notify::event::Event as NotifyEvent;
|
||||
use notify::Error as NotifyError;
|
||||
|
@ -31,10 +31,7 @@ use tokio::sync::mpsc;
|
|||
|
||||
pub fn init() -> Extension {
|
||||
Extension::builder()
|
||||
.ops(vec![
|
||||
("op_fs_events_open", op_sync(op_fs_events_open)),
|
||||
("op_fs_events_poll", op_async(op_fs_events_poll)),
|
||||
])
|
||||
.ops(vec![op_fs_events_open::decl(), op_fs_events_poll::decl()])
|
||||
.build()
|
||||
}
|
||||
|
||||
|
@ -97,6 +94,7 @@ pub struct OpenArgs {
|
|||
paths: Vec<String>,
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_fs_events_open(
|
||||
state: &mut OpState,
|
||||
args: OpenArgs,
|
||||
|
@ -131,6 +129,7 @@ fn op_fs_events_open(
|
|||
Ok(rid)
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_fs_events_poll(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
rid: ResourceId,
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::rc::Rc;
|
|||
|
||||
use deno_core::error::bad_resource_id;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::op;
|
||||
use deno_core::Extension;
|
||||
use deno_core::OpState;
|
||||
use deno_core::ResourceId;
|
||||
|
@ -12,10 +12,11 @@ use deno_net::ops_tls::TlsStreamResource;
|
|||
|
||||
pub fn init() -> Extension {
|
||||
Extension::builder()
|
||||
.ops(vec![("op_http_start", op_sync(op_http_start))])
|
||||
.ops(vec![op_http_start::decl()])
|
||||
.build()
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_http_start(
|
||||
state: &mut OpState,
|
||||
tcp_stream_rid: ResourceId,
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
use deno_core::error::not_supported;
|
||||
use deno_core::error::resource_unavailable;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::op;
|
||||
use deno_core::AsyncMutFuture;
|
||||
use deno_core::AsyncRefCell;
|
||||
use deno_core::AsyncResult;
|
||||
|
@ -69,10 +69,7 @@ static STDERR_HANDLE: Lazy<StdFile> = Lazy::new(|| unsafe {
|
|||
|
||||
pub fn init() -> Extension {
|
||||
Extension::builder()
|
||||
.ops(vec![
|
||||
("op_read_sync", op_sync(op_read_sync)),
|
||||
("op_write_sync", op_sync(op_write_sync)),
|
||||
])
|
||||
.ops(vec![op_read_sync::decl(), op_write_sync::decl()])
|
||||
.build()
|
||||
}
|
||||
|
||||
|
@ -354,6 +351,7 @@ impl Resource for StdFileResource {
|
|||
}
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_read_sync(
|
||||
state: &mut OpState,
|
||||
rid: ResourceId,
|
||||
|
@ -368,6 +366,7 @@ fn op_read_sync(
|
|||
})
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_write_sync(
|
||||
state: &mut OpState,
|
||||
rid: ResourceId,
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
use super::utils::into_string;
|
||||
use crate::permissions::Permissions;
|
||||
use deno_core::error::{type_error, AnyError};
|
||||
use deno_core::op_sync;
|
||||
use deno_core::op;
|
||||
use deno_core::url::Url;
|
||||
use deno_core::Extension;
|
||||
use deno_core::OpState;
|
||||
|
@ -17,19 +17,19 @@ use std::sync::Arc;
|
|||
pub fn init(maybe_exit_code: Option<Arc<AtomicI32>>) -> Extension {
|
||||
Extension::builder()
|
||||
.ops(vec![
|
||||
("op_env", op_sync(op_env)),
|
||||
("op_exec_path", op_sync(op_exec_path)),
|
||||
("op_exit", op_sync(op_exit)),
|
||||
("op_delete_env", op_sync(op_delete_env)),
|
||||
("op_get_env", op_sync(op_get_env)),
|
||||
("op_getuid", op_sync(op_getuid)),
|
||||
("op_hostname", op_sync(op_hostname)),
|
||||
("op_loadavg", op_sync(op_loadavg)),
|
||||
("op_network_interfaces", op_sync(op_network_interfaces)),
|
||||
("op_os_release", op_sync(op_os_release)),
|
||||
("op_set_env", op_sync(op_set_env)),
|
||||
("op_set_exit_code", op_sync(op_set_exit_code)),
|
||||
("op_system_memory_info", op_sync(op_system_memory_info)),
|
||||
op_env::decl(),
|
||||
op_exec_path::decl(),
|
||||
op_exit::decl(),
|
||||
op_delete_env::decl(),
|
||||
op_get_env::decl(),
|
||||
op_getuid::decl(),
|
||||
op_hostname::decl(),
|
||||
op_loadavg::decl(),
|
||||
op_network_interfaces::decl(),
|
||||
op_os_release::decl(),
|
||||
op_set_env::decl(),
|
||||
op_set_exit_code::decl(),
|
||||
op_system_memory_info::decl(),
|
||||
])
|
||||
.state(move |state| {
|
||||
let exit_code = maybe_exit_code.clone().unwrap_or_default();
|
||||
|
@ -39,6 +39,7 @@ pub fn init(maybe_exit_code: Option<Arc<AtomicI32>>) -> Extension {
|
|||
.build()
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_exec_path(state: &mut OpState, _: (), _: ()) -> Result<String, AnyError> {
|
||||
let current_exe = env::current_exe().unwrap();
|
||||
state
|
||||
|
@ -53,6 +54,7 @@ fn op_exec_path(state: &mut OpState, _: (), _: ()) -> Result<String, AnyError> {
|
|||
into_string(path.into_os_string())
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_set_env(
|
||||
state: &mut OpState,
|
||||
key: String,
|
||||
|
@ -68,6 +70,7 @@ fn op_set_env(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_env(
|
||||
state: &mut OpState,
|
||||
_: (),
|
||||
|
@ -77,6 +80,7 @@ fn op_env(
|
|||
Ok(env::vars().collect())
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_get_env(
|
||||
state: &mut OpState,
|
||||
key: String,
|
||||
|
@ -93,6 +97,7 @@ fn op_get_env(
|
|||
Ok(r)
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_delete_env(
|
||||
state: &mut OpState,
|
||||
key: String,
|
||||
|
@ -106,6 +111,7 @@ fn op_delete_env(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_set_exit_code(
|
||||
state: &mut OpState,
|
||||
code: i32,
|
||||
|
@ -115,11 +121,13 @@ fn op_set_exit_code(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_exit(state: &mut OpState, _: (), _: ()) -> Result<(), AnyError> {
|
||||
let code = state.borrow::<Arc<AtomicI32>>().load(Relaxed);
|
||||
std::process::exit(code)
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_loadavg(
|
||||
state: &mut OpState,
|
||||
_: (),
|
||||
|
@ -133,6 +141,7 @@ fn op_loadavg(
|
|||
}
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_hostname(state: &mut OpState, _: (), _: ()) -> Result<String, AnyError> {
|
||||
super::check_unstable(state, "Deno.hostname");
|
||||
state.borrow_mut::<Permissions>().env.check_all()?;
|
||||
|
@ -140,6 +149,7 @@ fn op_hostname(state: &mut OpState, _: (), _: ()) -> Result<String, AnyError> {
|
|||
Ok(hostname)
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_os_release(
|
||||
state: &mut OpState,
|
||||
_: (),
|
||||
|
@ -151,6 +161,7 @@ fn op_os_release(
|
|||
Ok(release)
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_network_interfaces(
|
||||
state: &mut OpState,
|
||||
_: (),
|
||||
|
@ -218,6 +229,7 @@ struct MemInfo {
|
|||
pub swap_free: u64,
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_system_memory_info(
|
||||
state: &mut OpState,
|
||||
_: (),
|
||||
|
@ -240,6 +252,7 @@ fn op_system_memory_info(
|
|||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
#[op]
|
||||
fn op_getuid(
|
||||
state: &mut OpState,
|
||||
_: (),
|
||||
|
@ -251,6 +264,7 @@ fn op_getuid(
|
|||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
#[op]
|
||||
fn op_getuid(
|
||||
state: &mut OpState,
|
||||
_: (),
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::permissions::Permissions;
|
|||
use deno_core::error::custom_error;
|
||||
use deno_core::error::uri_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::op;
|
||||
use deno_core::url;
|
||||
use deno_core::Extension;
|
||||
use deno_core::OpState;
|
||||
|
@ -14,9 +14,9 @@ use std::path::Path;
|
|||
pub fn init() -> Extension {
|
||||
Extension::builder()
|
||||
.ops(vec![
|
||||
("op_query_permission", op_sync(op_query_permission)),
|
||||
("op_revoke_permission", op_sync(op_revoke_permission)),
|
||||
("op_request_permission", op_sync(op_request_permission)),
|
||||
op_query_permission::decl(),
|
||||
op_revoke_permission::decl(),
|
||||
op_request_permission::decl(),
|
||||
])
|
||||
.build()
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ pub struct PermissionArgs {
|
|||
command: Option<String>,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_query_permission(
|
||||
state: &mut OpState,
|
||||
args: PermissionArgs,
|
||||
|
@ -61,6 +62,7 @@ pub fn op_query_permission(
|
|||
Ok(perm.to_string())
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_revoke_permission(
|
||||
state: &mut OpState,
|
||||
args: PermissionArgs,
|
||||
|
@ -92,6 +94,7 @@ pub fn op_revoke_permission(
|
|||
Ok(perm.to_string())
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_request_permission(
|
||||
state: &mut OpState,
|
||||
args: PermissionArgs,
|
||||
|
|
|
@ -8,8 +8,8 @@ use crate::permissions::Permissions;
|
|||
use deno_core::error::bad_resource_id;
|
||||
use deno_core::error::type_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op_async;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::op;
|
||||
|
||||
use deno_core::AsyncMutFuture;
|
||||
use deno_core::AsyncRefCell;
|
||||
use deno_core::Extension;
|
||||
|
@ -29,11 +29,7 @@ use std::os::unix::process::ExitStatusExt;
|
|||
|
||||
pub fn init() -> Extension {
|
||||
Extension::builder()
|
||||
.ops(vec![
|
||||
("op_run", op_sync(op_run)),
|
||||
("op_run_status", op_async(op_run_status)),
|
||||
("op_kill", op_sync(op_kill)),
|
||||
])
|
||||
.ops(vec![op_run::decl(), op_run_status::decl(), op_kill::decl()])
|
||||
.build()
|
||||
}
|
||||
|
||||
|
@ -102,6 +98,7 @@ struct RunInfo {
|
|||
stderr_rid: Option<ResourceId>,
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_run(
|
||||
state: &mut OpState,
|
||||
run_args: RunArgs,
|
||||
|
@ -226,6 +223,7 @@ struct ProcessStatus {
|
|||
exit_signal: i32,
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_run_status(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
rid: ResourceId,
|
||||
|
@ -303,6 +301,7 @@ pub fn kill(pid: i32, signal: &str) -> Result<(), AnyError> {
|
|||
}
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_kill(
|
||||
state: &mut OpState,
|
||||
pid: i32,
|
||||
|
|
|
@ -3,14 +3,14 @@
|
|||
use crate::permissions::Permissions;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::op;
|
||||
use deno_core::Extension;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::OpState;
|
||||
|
||||
pub fn init(main_module: ModuleSpecifier) -> Extension {
|
||||
Extension::builder()
|
||||
.ops(vec![("op_main_module", op_sync(op_main_module))])
|
||||
.ops(vec![op_main_module::decl()])
|
||||
.state(move |state| {
|
||||
state.put::<ModuleSpecifier>(main_module.clone());
|
||||
Ok(())
|
||||
|
@ -18,6 +18,7 @@ pub fn init(main_module: ModuleSpecifier) -> Extension {
|
|||
.build()
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_main_module(
|
||||
state: &mut OpState,
|
||||
_: (),
|
||||
|
|
|
@ -4,8 +4,8 @@ use deno_core::error::generic_error;
|
|||
#[cfg(not(target_os = "windows"))]
|
||||
use deno_core::error::type_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op_async;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::op;
|
||||
|
||||
use deno_core::Extension;
|
||||
use deno_core::OpState;
|
||||
use std::cell::RefCell;
|
||||
|
@ -31,9 +31,9 @@ use tokio::signal::unix::{signal, Signal, SignalKind};
|
|||
pub fn init() -> Extension {
|
||||
Extension::builder()
|
||||
.ops(vec![
|
||||
("op_signal_bind", op_sync(op_signal_bind)),
|
||||
("op_signal_unbind", op_sync(op_signal_unbind)),
|
||||
("op_signal_poll", op_async(op_signal_poll)),
|
||||
op_signal_bind::decl(),
|
||||
op_signal_unbind::decl(),
|
||||
op_signal_poll::decl(),
|
||||
])
|
||||
.build()
|
||||
}
|
||||
|
@ -174,6 +174,7 @@ pub fn signal_str_to_int(s: &str) -> Result<libc::c_int, AnyError> {
|
|||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[op]
|
||||
fn op_signal_bind(
|
||||
state: &mut OpState,
|
||||
sig: String,
|
||||
|
@ -195,6 +196,7 @@ fn op_signal_bind(
|
|||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[op]
|
||||
async fn op_signal_poll(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
rid: ResourceId,
|
||||
|
@ -214,6 +216,7 @@ async fn op_signal_poll(
|
|||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[op]
|
||||
pub fn op_signal_unbind(
|
||||
state: &mut OpState,
|
||||
rid: ResourceId,
|
||||
|
@ -224,6 +227,7 @@ pub fn op_signal_unbind(
|
|||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
#[op]
|
||||
pub fn op_signal_bind(
|
||||
_state: &mut OpState,
|
||||
_: (),
|
||||
|
@ -233,6 +237,7 @@ pub fn op_signal_bind(
|
|||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
#[op]
|
||||
fn op_signal_unbind(
|
||||
_state: &mut OpState,
|
||||
_: (),
|
||||
|
@ -242,6 +247,7 @@ fn op_signal_unbind(
|
|||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
#[op]
|
||||
async fn op_signal_poll(
|
||||
_state: Rc<RefCell<OpState>>,
|
||||
_: (),
|
||||
|
|
|
@ -5,7 +5,7 @@ use deno_core::error::bad_resource_id;
|
|||
use deno_core::error::not_supported;
|
||||
use deno_core::error::resource_unavailable;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::op;
|
||||
use deno_core::Extension;
|
||||
use deno_core::OpState;
|
||||
use deno_core::RcRef;
|
||||
|
@ -47,9 +47,9 @@ fn get_windows_handle(
|
|||
pub fn init() -> Extension {
|
||||
Extension::builder()
|
||||
.ops(vec![
|
||||
("op_set_raw", op_sync(op_set_raw)),
|
||||
("op_isatty", op_sync(op_isatty)),
|
||||
("op_console_size", op_sync(op_console_size)),
|
||||
op_set_raw::decl(),
|
||||
op_isatty::decl(),
|
||||
op_console_size::decl(),
|
||||
])
|
||||
.build()
|
||||
}
|
||||
|
@ -67,6 +67,7 @@ pub struct SetRawArgs {
|
|||
options: SetRawOptions,
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_set_raw(
|
||||
state: &mut OpState,
|
||||
args: SetRawArgs,
|
||||
|
@ -211,6 +212,7 @@ fn op_set_raw(
|
|||
}
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_isatty(
|
||||
state: &mut OpState,
|
||||
rid: ResourceId,
|
||||
|
@ -245,6 +247,7 @@ struct ConsoleSize {
|
|||
rows: u32,
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_console_size(
|
||||
state: &mut OpState,
|
||||
rid: ResourceId,
|
||||
|
|
|
@ -5,8 +5,8 @@ mod sync_fetch;
|
|||
use crate::web_worker::WebWorkerInternalHandle;
|
||||
use crate::web_worker::WebWorkerType;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op_async;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::op;
|
||||
|
||||
use deno_core::CancelFuture;
|
||||
use deno_core::Extension;
|
||||
use deno_core::OpState;
|
||||
|
@ -19,16 +19,17 @@ use self::sync_fetch::op_worker_sync_fetch;
|
|||
pub fn init() -> Extension {
|
||||
Extension::builder()
|
||||
.ops(vec![
|
||||
("op_worker_post_message", op_sync(op_worker_post_message)),
|
||||
("op_worker_recv_message", op_async(op_worker_recv_message)),
|
||||
op_worker_post_message::decl(),
|
||||
op_worker_recv_message::decl(),
|
||||
// Notify host that guest worker closes.
|
||||
("op_worker_close", op_sync(op_worker_close)),
|
||||
("op_worker_get_type", op_sync(op_worker_get_type)),
|
||||
("op_worker_sync_fetch", op_sync(op_worker_sync_fetch)),
|
||||
op_worker_close::decl(),
|
||||
op_worker_get_type::decl(),
|
||||
op_worker_sync_fetch::decl(),
|
||||
])
|
||||
.build()
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_worker_post_message(
|
||||
state: &mut OpState,
|
||||
data: JsMessageData,
|
||||
|
@ -39,6 +40,7 @@ fn op_worker_post_message(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_worker_recv_message(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
_: (),
|
||||
|
@ -55,6 +57,7 @@ async fn op_worker_recv_message(
|
|||
.await?
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_worker_close(state: &mut OpState, _: (), _: ()) -> Result<(), AnyError> {
|
||||
// Notify parent that we're finished
|
||||
let mut handle = state.borrow_mut::<WebWorkerInternalHandle>().clone();
|
||||
|
@ -63,6 +66,7 @@ fn op_worker_close(state: &mut OpState, _: (), _: ()) -> Result<(), AnyError> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_worker_get_type(
|
||||
state: &mut OpState,
|
||||
_: (),
|
||||
|
|
|
@ -4,6 +4,7 @@ use crate::web_worker::WebWorkerInternalHandle;
|
|||
use crate::web_worker::WebWorkerType;
|
||||
use deno_core::error::type_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op;
|
||||
use deno_core::url::Url;
|
||||
use deno_core::OpState;
|
||||
use deno_fetch::data_url::DataUrl;
|
||||
|
@ -30,6 +31,7 @@ pub struct SyncFetchScript {
|
|||
script: String,
|
||||
}
|
||||
|
||||
#[op]
|
||||
pub fn op_worker_sync_fetch(
|
||||
state: &mut OpState,
|
||||
scripts: Vec<String>,
|
||||
|
|
|
@ -13,8 +13,8 @@ use crate::web_worker::WorkerControlEvent;
|
|||
use crate::web_worker::WorkerId;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::futures::future::LocalFutureObj;
|
||||
use deno_core::op_async;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::op;
|
||||
|
||||
use deno_core::serde::Deserialize;
|
||||
use deno_core::Extension;
|
||||
use deno_core::ModuleSpecifier;
|
||||
|
@ -122,14 +122,11 @@ pub fn init(
|
|||
Ok(())
|
||||
})
|
||||
.ops(vec![
|
||||
("op_create_worker", op_sync(op_create_worker)),
|
||||
(
|
||||
"op_host_terminate_worker",
|
||||
op_sync(op_host_terminate_worker),
|
||||
),
|
||||
("op_host_post_message", op_sync(op_host_post_message)),
|
||||
("op_host_recv_ctrl", op_async(op_host_recv_ctrl)),
|
||||
("op_host_recv_message", op_async(op_host_recv_message)),
|
||||
op_create_worker::decl(),
|
||||
op_host_terminate_worker::decl(),
|
||||
op_host_post_message::decl(),
|
||||
op_host_recv_ctrl::decl(),
|
||||
op_host_recv_message::decl(),
|
||||
])
|
||||
.build()
|
||||
}
|
||||
|
@ -147,6 +144,7 @@ pub struct CreateWorkerArgs {
|
|||
}
|
||||
|
||||
/// Create worker as the host
|
||||
#[op]
|
||||
fn op_create_worker(
|
||||
state: &mut OpState,
|
||||
args: CreateWorkerArgs,
|
||||
|
@ -263,6 +261,7 @@ fn op_create_worker(
|
|||
Ok(worker_id)
|
||||
}
|
||||
|
||||
#[op]
|
||||
fn op_host_terminate_worker(
|
||||
state: &mut OpState,
|
||||
id: WorkerId,
|
||||
|
@ -317,6 +316,7 @@ fn close_channel(
|
|||
}
|
||||
|
||||
/// Get control event from guest worker as host
|
||||
#[op]
|
||||
async fn op_host_recv_ctrl(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
id: WorkerId,
|
||||
|
@ -348,6 +348,7 @@ async fn op_host_recv_ctrl(
|
|||
Ok(WorkerControlEvent::Close)
|
||||
}
|
||||
|
||||
#[op]
|
||||
async fn op_host_recv_message(
|
||||
state: Rc<RefCell<OpState>>,
|
||||
id: WorkerId,
|
||||
|
@ -373,6 +374,7 @@ async fn op_host_recv_message(
|
|||
}
|
||||
|
||||
/// Post message to guest worker as host
|
||||
#[op]
|
||||
fn op_host_post_message(
|
||||
state: &mut OpState,
|
||||
id: WorkerId,
|
||||
|
|
Loading…
Reference in a new issue