1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-21 21:50:00 -05:00

chore(runtime): Make some ops in ext and runtime infallible. (#14589)

Co-authored-by: Aaron O'Mullan <aaron.omullan@gmail.com>
This commit is contained in:
Andreu Botella 2022-05-13 10:36:31 +02:00 committed by GitHub
parent 0ee76da07b
commit 3e7afb8918
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 83 additions and 133 deletions

View file

@ -2,14 +2,8 @@ use deno_bench_util::bench_or_profile;
use deno_bench_util::bencher::{benchmark_group, Bencher}; use deno_bench_util::bencher::{benchmark_group, Bencher};
use deno_bench_util::{bench_js_async, bench_js_sync}; use deno_bench_util::{bench_js_async, bench_js_sync};
use deno_core::error::AnyError;
use deno_core::op; use deno_core::op;
use deno_core::Extension; use deno_core::Extension;
use deno_core::OpState;
use std::cell::RefCell;
use std::rc::Rc;
fn setup() -> Vec<Extension> { fn setup() -> Vec<Extension> {
vec![Extension::builder() vec![Extension::builder()
@ -22,19 +16,17 @@ fn setup() -> Vec<Extension> {
} }
#[op] #[op]
fn op_nop() -> Result<(), AnyError> { fn op_nop() {}
Ok(())
}
#[op] #[op]
fn op_pi_json() -> Result<i64, AnyError> { fn op_pi_json() -> i64 {
Ok(314159) 314159
} }
// this is a function since async closures aren't stable // this is a function since async closures aren't stable
#[op] #[op]
async fn op_pi_async(_: Rc<RefCell<OpState>>) -> Result<i64, AnyError> { async fn op_pi_async() -> i64 {
Ok(314159) 314159
} }
fn bench_op_pi_json(b: &mut Bencher) { fn bench_op_pi_json(b: &mut Bencher) {

View file

@ -178,26 +178,23 @@ fn create_compiler_snapshot(
} }
#[op] #[op]
fn op_build_info( fn op_build_info(state: &mut OpState) -> Value {
state: &mut OpState,
_args: Value,
) -> Result<Value, AnyError> {
let build_specifier = "asset:///bootstrap.ts"; let build_specifier = "asset:///bootstrap.ts";
let build_libs = state.borrow::<Vec<&str>>(); let build_libs = state.borrow::<Vec<&str>>();
Ok(json!({ json!({
"buildSpecifier": build_specifier, "buildSpecifier": build_specifier,
"libs": build_libs, "libs": build_libs,
})) })
} }
#[op] #[op]
fn op_cwd(_args: Value) -> Result<Value, AnyError> { fn op_cwd() -> String {
Ok(json!("cache:///")) "cache:///".into()
} }
#[op] #[op]
fn op_exists(_args: Value) -> Result<Value, AnyError> { fn op_exists() -> bool {
Ok(json!(false)) false
} }
#[op] #[op]

View file

@ -2489,10 +2489,7 @@ struct SpecifierArgs {
} }
#[op] #[op]
fn op_exists( fn op_exists(state: &mut OpState, args: SpecifierArgs) -> bool {
state: &mut OpState,
args: SpecifierArgs,
) -> Result<bool, AnyError> {
let state = state.borrow_mut::<State>(); let state = state.borrow_mut::<State>();
// we don't measure the performance of op_exists anymore because as of TS 4.5 // 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 // it is noisy with all the checking for custom libs, that we can't see the
@ -2504,10 +2501,9 @@ fn op_exists(
// sometimes tsc tries to query invalid specifiers, especially when // sometimes tsc tries to query invalid specifiers, especially when
// something else isn't quite right, so instead of bubbling up the error // something else isn't quite right, so instead of bubbling up the error
// back to tsc, we simply swallow it and say the file doesn't exist // back to tsc, we simply swallow it and say the file doesn't exist
Err(_) => return Ok(false), Err(_) => return false,
}; };
let result = state.state_snapshot.documents.exists(&specifier); state.state_snapshot.documents.exists(&specifier)
Ok(result)
} }
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Deserialize, Serialize)]
@ -2621,9 +2617,9 @@ fn op_get_text(
} }
#[op] #[op]
fn op_is_cancelled(state: &mut OpState) -> Result<bool, AnyError> { fn op_is_cancelled(state: &mut OpState) -> bool {
let state = state.borrow_mut::<State>(); let state = state.borrow_mut::<State>();
Ok(state.token.is_cancelled()) state.token.is_cancelled()
} }
#[op] #[op]
@ -2676,27 +2672,22 @@ fn op_resolve(
} }
#[op] #[op]
fn op_respond(state: &mut OpState, args: Response) -> Result<bool, AnyError> { fn op_respond(state: &mut OpState, args: Response) -> bool {
let state = state.borrow_mut::<State>(); let state = state.borrow_mut::<State>();
state.response = Some(args); state.response = Some(args);
Ok(true) true
} }
#[op] #[op]
fn op_script_names( fn op_script_names(state: &mut OpState) -> Vec<ModuleSpecifier> {
state: &mut OpState,
_args: Value,
) -> Result<Vec<ModuleSpecifier>, AnyError> {
let state = state.borrow_mut::<State>(); let state = state.borrow_mut::<State>();
Ok( state
state .state_snapshot
.state_snapshot .documents
.documents .documents(true, true)
.documents(true, true) .into_iter()
.into_iter() .map(|d| d.specifier().clone())
.map(|d| d.specifier().clone()) .collect()
.collect(),
)
} }
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Deserialize, Serialize)]
@ -3844,8 +3835,6 @@ mod tests {
specifier: "/error/unknown:something/index.d.ts".to_string(), specifier: "/error/unknown:something/index.d.ts".to_string(),
}, },
); );
assert!(actual.is_ok());
let actual = actual.unwrap();
assert!(!actual); assert!(!actual);
} }

View file

@ -45,9 +45,8 @@ fn check_unstable(state: &OpState, api_name: &str) {
} }
#[op] #[op]
fn op_bench_check_unstable(state: &mut OpState) -> Result<(), AnyError> { fn op_bench_check_unstable(state: &mut OpState) {
check_unstable(state, "Deno.bench"); check_unstable(state, "Deno.bench");
Ok(())
} }
#[derive(Clone)] #[derive(Clone)]
@ -94,19 +93,14 @@ pub fn op_restore_test_permissions(
} }
#[op] #[op]
fn op_get_bench_origin(state: &mut OpState) -> Result<String, AnyError> { fn op_get_bench_origin(state: &mut OpState) -> String {
Ok(state.borrow::<ModuleSpecifier>().to_string()) state.borrow::<ModuleSpecifier>().to_string()
} }
#[op] #[op]
fn op_dispatch_bench_event( fn op_dispatch_bench_event(state: &mut OpState, event: BenchEvent) {
state: &mut OpState,
event: BenchEvent,
) -> Result<(), AnyError> {
let sender = state.borrow::<UnboundedSender<BenchEvent>>().clone(); let sender = state.borrow::<UnboundedSender<BenchEvent>>().clone();
sender.send(event).ok(); sender.send(event).ok();
Ok(())
} }
#[op] #[op]

View file

@ -344,7 +344,7 @@ struct EmitArgs {
} }
#[op] #[op]
fn op_emit(state: &mut OpState, args: EmitArgs) -> Result<Value, AnyError> { fn op_emit(state: &mut OpState, args: EmitArgs) -> bool {
let state = state.borrow_mut::<State>(); let state = state.borrow_mut::<State>();
match args.file_name.as_ref() { match args.file_name.as_ref() {
"deno:///.tsbuildinfo" => state.maybe_tsbuildinfo = Some(args.data), "deno:///.tsbuildinfo" => state.maybe_tsbuildinfo = Some(args.data),
@ -389,7 +389,7 @@ fn op_emit(state: &mut OpState, args: EmitArgs) -> Result<Value, AnyError> {
} }
} }
Ok(json!(true)) true
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
@ -399,20 +399,20 @@ struct ExistsArgs {
} }
#[op] #[op]
fn op_exists(state: &mut OpState, args: ExistsArgs) -> Result<bool, AnyError> { fn op_exists(state: &mut OpState, args: ExistsArgs) -> bool {
let state = state.borrow_mut::<State>(); let state = state.borrow_mut::<State>();
let graph_data = state.graph_data.read(); let graph_data = state.graph_data.read();
if let Ok(specifier) = normalize_specifier(&args.specifier) { if let Ok(specifier) = normalize_specifier(&args.specifier) {
if specifier.scheme() == "asset" || specifier.scheme() == "data" { if specifier.scheme() == "asset" || specifier.scheme() == "data" {
Ok(true) true
} else { } else {
Ok(matches!( matches!(
graph_data.get(&graph_data.follow_redirect(&specifier)), graph_data.get(&graph_data.follow_redirect(&specifier)),
Some(ModuleEntry::Module { .. }) Some(ModuleEntry::Module { .. })
)) )
} }
} else { } else {
Ok(false) false
} }
} }
@ -510,7 +510,7 @@ pub struct ResolveArgs {
fn op_resolve( fn op_resolve(
state: &mut OpState, state: &mut OpState,
args: ResolveArgs, args: ResolveArgs,
) -> Result<Value, AnyError> { ) -> Result<Vec<(String, String)>, AnyError> {
let state = state.borrow_mut::<State>(); let state = state.borrow_mut::<State>();
let mut resolved: Vec<(String, String)> = Vec::new(); let mut resolved: Vec<(String, String)> = Vec::new();
let referrer = if let Some(remapped_specifier) = let referrer = if let Some(remapped_specifier) =
@ -607,7 +607,7 @@ fn op_resolve(
} }
} }
Ok(json!(resolved)) Ok(resolved)
} }
#[derive(Debug, Deserialize, Eq, PartialEq)] #[derive(Debug, Deserialize, Eq, PartialEq)]
@ -917,9 +917,8 @@ mod tests {
file_name: "cache:///some/file.js".to_string(), file_name: "cache:///some/file.js".to_string(),
maybe_specifiers: Some(vec!["file:///some/file.ts".to_string()]), maybe_specifiers: Some(vec!["file:///some/file.ts".to_string()]),
}, },
) );
.expect("should have invoked op"); assert!(actual);
assert_eq!(actual, json!(true));
let state = state.borrow::<State>(); let state = state.borrow::<State>();
assert_eq!(state.emitted_files.len(), 1); assert_eq!(state.emitted_files.len(), 1);
assert!(state.maybe_tsbuildinfo.is_none()); assert!(state.maybe_tsbuildinfo.is_none());
@ -948,9 +947,8 @@ mod tests {
vec!["file:///some/file.ts?q=.json".to_string()], vec!["file:///some/file.ts?q=.json".to_string()],
), ),
}, },
) );
.expect("should have invoked op"); assert!(actual);
assert_eq!(actual, json!(true));
let state = state.borrow::<State>(); let state = state.borrow::<State>();
assert_eq!(state.emitted_files.len(), 1); assert_eq!(state.emitted_files.len(), 1);
assert!(state.maybe_tsbuildinfo.is_none()); assert!(state.maybe_tsbuildinfo.is_none());
@ -977,9 +975,8 @@ mod tests {
file_name: "deno:///.tsbuildinfo".to_string(), file_name: "deno:///.tsbuildinfo".to_string(),
maybe_specifiers: None, maybe_specifiers: None,
}, },
) );
.expect("should have invoked op"); assert!(actual);
assert_eq!(actual, json!(true));
let state = state.borrow::<State>(); let state = state.borrow::<State>();
assert_eq!(state.emitted_files.len(), 0); assert_eq!(state.emitted_files.len(), 0);
assert_eq!( assert_eq!(
@ -1095,7 +1092,10 @@ mod tests {
}, },
) )
.expect("should have invoked op"); .expect("should have invoked op");
assert_eq!(actual, json!([["https://deno.land/x/b.ts", ".ts"]])); assert_eq!(
actual,
vec![("https://deno.land/x/b.ts".into(), ".ts".into())]
);
} }
#[tokio::test] #[tokio::test]
@ -1116,7 +1116,7 @@ mod tests {
.expect("should have not errored"); .expect("should have not errored");
assert_eq!( assert_eq!(
actual, actual,
json!([["deno:///missing_dependency.d.ts", ".d.ts"]]) vec![("deno:///missing_dependency.d.ts".into(), ".d.ts".into())]
); );
} }

View file

@ -1141,7 +1141,6 @@ impl ModuleMap {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::error::AnyError;
use crate::Extension; use crate::Extension;
use crate::JsRuntime; use crate::JsRuntime;
use crate::RuntimeOptions; use crate::RuntimeOptions;
@ -1474,10 +1473,10 @@ import "/a.js";
static DISPATCH_COUNT: AtomicUsize = AtomicUsize::new(0); static DISPATCH_COUNT: AtomicUsize = AtomicUsize::new(0);
#[op] #[op]
fn op_test(_: &mut OpState, control: u8) -> Result<u8, AnyError> { fn op_test(control: u8) -> u8 {
DISPATCH_COUNT.fetch_add(1, Ordering::Relaxed); DISPATCH_COUNT.fetch_add(1, Ordering::Relaxed);
assert_eq!(control, 42); assert_eq!(control, 42);
Ok(43) 43
} }
let ext = Extension::builder().ops(vec![op_test::decl()]).build(); let ext = Extension::builder().ops(vec![op_test::decl()]).build();

View file

@ -160,13 +160,11 @@ pub fn op_url_parse_search_params(
} }
#[op] #[op]
pub fn op_url_stringify_search_params( pub fn op_url_stringify_search_params(args: Vec<(String, String)>) -> String {
args: Vec<(String, String)>,
) -> Result<String, AnyError> {
let search = form_urlencoded::Serializer::new(String::new()) let search = form_urlencoded::Serializer::new(String::new())
.extend_pairs(args) .extend_pairs(args)
.finish(); .finish();
Ok(search) search
} }
pub fn get_declaration() -> PathBuf { pub fn get_declaration() -> PathBuf {

View file

@ -163,11 +163,10 @@ impl BlobPart for SlicedBlobPart {
pub fn op_blob_create_part( pub fn op_blob_create_part(
state: &mut deno_core::OpState, state: &mut deno_core::OpState,
data: ZeroCopyBuf, data: ZeroCopyBuf,
) -> Result<Uuid, AnyError> { ) -> Uuid {
let blob_store = state.borrow::<BlobStore>(); let blob_store = state.borrow::<BlobStore>();
let part = InMemoryBlobPart(data.to_vec()); let part = InMemoryBlobPart(data.to_vec());
let id = blob_store.insert_part(Arc::new(part)); blob_store.insert_part(Arc::new(part))
Ok(id)
} }
#[derive(Deserialize)] #[derive(Deserialize)]
@ -219,13 +218,9 @@ pub async fn op_blob_read_part(
} }
#[op] #[op]
pub fn op_blob_remove_part( pub fn op_blob_remove_part(state: &mut deno_core::OpState, id: Uuid) {
state: &mut deno_core::OpState,
id: Uuid,
) -> Result<(), AnyError> {
let blob_store = state.borrow::<BlobStore>(); let blob_store = state.borrow::<BlobStore>();
blob_store.remove_part(&id); blob_store.remove_part(&id);
Ok(())
} }
#[op] #[op]

View file

@ -38,7 +38,7 @@ pub fn op_compression_new(
state: &mut OpState, state: &mut OpState,
format: String, format: String,
is_decoder: bool, is_decoder: bool,
) -> Result<ResourceId, AnyError> { ) -> ResourceId {
let w = Vec::new(); let w = Vec::new();
let inner = match (format.as_str(), is_decoder) { let inner = match (format.as_str(), is_decoder) {
("deflate", true) => Inner::DeflateDecoder(ZlibDecoder::new(w)), ("deflate", true) => Inner::DeflateDecoder(ZlibDecoder::new(w)),
@ -52,7 +52,7 @@ pub fn op_compression_new(
_ => unreachable!(), _ => unreachable!(),
}; };
let resource = CompressionResource(RefCell::new(inner)); let resource = CompressionResource(RefCell::new(inner));
Ok(state.resource_table.add(resource)) state.resource_table.add(resource)
} }
#[op] #[op]

View file

@ -180,13 +180,13 @@ fn b64_decode(input: &[u8]) -> Result<Vec<u8>, AnyError> {
} }
#[op] #[op]
fn op_base64_encode(s: ZeroCopyBuf) -> Result<String, AnyError> { fn op_base64_encode(s: ZeroCopyBuf) -> String {
Ok(b64_encode(&s)) b64_encode(&s)
} }
#[op] #[op]
fn op_base64_btoa(s: ByteString) -> Result<String, AnyError> { fn op_base64_btoa(s: ByteString) -> String {
Ok(b64_encode(s)) b64_encode(s)
} }
fn b64_encode(s: impl AsRef<[u8]>) -> String { fn b64_encode(s: impl AsRef<[u8]>) -> String {
@ -323,7 +323,7 @@ struct EncodeIntoResult {
fn op_encoding_encode_into( fn op_encoding_encode_into(
input: String, input: String,
mut buffer: ZeroCopyBuf, mut buffer: ZeroCopyBuf,
) -> Result<EncodeIntoResult, AnyError> { ) -> EncodeIntoResult {
// Since `input` is already UTF-8, we can simply find the last UTF-8 code // Since `input` is already UTF-8, we can simply find the last UTF-8 code
// point boundary from input that fits in `buffer`, and copy the bytes up to // point boundary from input that fits in `buffer`, and copy the bytes up to
// that point. // that point.
@ -347,18 +347,17 @@ fn op_encoding_encode_into(
buffer[..boundary].copy_from_slice(input[..boundary].as_bytes()); buffer[..boundary].copy_from_slice(input[..boundary].as_bytes());
Ok(EncodeIntoResult { EncodeIntoResult {
// The `read` output parameter is measured in UTF-16 code units. // The `read` output parameter is measured in UTF-16 code units.
read: input[..boundary].encode_utf16().count(), read: input[..boundary].encode_utf16().count(),
written: boundary, written: boundary,
}) }
} }
/// Creates a [`CancelHandle`] resource that can be used to cancel invocations of certain ops. /// Creates a [`CancelHandle`] resource that can be used to cancel invocations of certain ops.
#[op] #[op]
pub fn op_cancel_handle(state: &mut OpState) -> Result<ResourceId, AnyError> { pub fn op_cancel_handle(state: &mut OpState) -> ResourceId {
let rid = state.resource_table.add(CancelHandle::new()); state.resource_table.add(CancelHandle::new())
Ok(rid)
} }
pub fn get_declaration() -> PathBuf { pub fn get_declaration() -> PathBuf {

View file

@ -109,7 +109,7 @@ impl Resource for MessagePortResource {
#[op] #[op]
pub fn op_message_port_create_entangled( pub fn op_message_port_create_entangled(
state: &mut OpState, state: &mut OpState,
) -> Result<(ResourceId, ResourceId), AnyError> { ) -> (ResourceId, ResourceId) {
let (port1, port2) = create_entangled_message_port(); let (port1, port2) = create_entangled_message_port();
let port1_id = state.resource_table.add(MessagePortResource { let port1_id = state.resource_table.add(MessagePortResource {
@ -122,7 +122,7 @@ pub fn op_message_port_create_entangled(
cancel: CancelHandle::new(), cancel: CancelHandle::new(),
}); });
Ok((port1_id, port2_id)) (port1_id, port2_id)
} }
#[derive(Deserialize, Serialize)] #[derive(Deserialize, Serialize)]

View file

@ -28,7 +28,7 @@ pub type StartTime = Instant;
// If the High precision flag is not set, the // If the High precision flag is not set, the
// nanoseconds are rounded on 2ms. // nanoseconds are rounded on 2ms.
#[op] #[op]
pub fn op_now<TP>(state: &mut OpState, _argument: ()) -> Result<f64, AnyError> pub fn op_now<TP>(state: &mut OpState, _argument: ()) -> f64
where where
TP: TimersPermission + 'static, TP: TimersPermission + 'static,
{ {
@ -44,9 +44,7 @@ where
subsec_nanos -= subsec_nanos % reduced_time_precision; subsec_nanos -= subsec_nanos % reduced_time_precision;
} }
let result = (seconds * 1_000) as f64 + (subsec_nanos / 1_000_000.0); (seconds * 1_000) as f64 + (subsec_nanos / 1_000_000.0)
Ok(result)
} }
pub struct TimerHandle(Rc<CancelHandle>); pub struct TimerHandle(Rc<CancelHandle>);
@ -64,11 +62,10 @@ impl Resource for TimerHandle {
/// Creates a [`TimerHandle`] resource that can be used to cancel invocations of /// Creates a [`TimerHandle`] resource that can be used to cancel invocations of
/// [`op_sleep`]. /// [`op_sleep`].
#[op] #[op]
pub fn op_timer_handle(state: &mut OpState) -> Result<ResourceId, AnyError> { pub fn op_timer_handle(state: &mut OpState) -> ResourceId {
let rid = state state
.resource_table .resource_table
.add(TimerHandle(CancelHandle::new_rc())); .add(TimerHandle(CancelHandle::new_rc()))
Ok(rid)
} }
/// Waits asynchronously until either `millis` milliseconds have passed or the /// Waits asynchronously until either `millis` milliseconds have passed or the
@ -87,14 +84,10 @@ pub async fn op_sleep(
} }
#[op] #[op]
pub fn op_sleep_sync<TP>( pub fn op_sleep_sync<TP>(state: &mut OpState, millis: u64)
state: &mut OpState,
millis: u64,
) -> Result<(), AnyError>
where where
TP: TimersPermission + 'static, TP: TimersPermission + 'static,
{ {
state.borrow::<TP>().check_unstable(state, "Deno.sleepSync"); state.borrow::<TP>().check_unstable(state, "Deno.sleepSync");
std::thread::sleep(Duration::from_millis(millis)); std::thread::sleep(Duration::from_millis(millis));
Ok(())
} }

View file

@ -103,13 +103,12 @@ fn op_delete_env(state: &mut OpState, key: String) -> Result<(), AnyError> {
} }
#[op] #[op]
fn op_set_exit_code(state: &mut OpState, code: i32) -> Result<(), AnyError> { fn op_set_exit_code(state: &mut OpState, code: i32) {
state.borrow_mut::<Arc<AtomicI32>>().store(code, Relaxed); state.borrow_mut::<Arc<AtomicI32>>().store(code, Relaxed);
Ok(())
} }
#[op] #[op]
fn op_exit(state: &mut OpState) -> Result<(), AnyError> { fn op_exit(state: &mut OpState) {
let code = state.borrow::<Arc<AtomicI32>>().load(Relaxed); let code = state.borrow::<Arc<AtomicI32>>().load(Relaxed);
std::process::exit(code) std::process::exit(code)
} }

View file

@ -55,16 +55,15 @@ async fn op_worker_recv_message(
} }
#[op] #[op]
fn op_worker_close(state: &mut OpState) -> Result<(), AnyError> { fn op_worker_close(state: &mut OpState) {
// Notify parent that we're finished // Notify parent that we're finished
let mut handle = state.borrow_mut::<WebWorkerInternalHandle>().clone(); let mut handle = state.borrow_mut::<WebWorkerInternalHandle>().clone();
handle.terminate(); handle.terminate();
Ok(())
} }
#[op] #[op]
fn op_worker_get_type(state: &mut OpState) -> Result<WebWorkerType, AnyError> { fn op_worker_get_type(state: &mut OpState) -> WebWorkerType {
let handle = state.borrow::<WebWorkerInternalHandle>().clone(); let handle = state.borrow::<WebWorkerInternalHandle>().clone();
Ok(handle.worker_type) handle.worker_type
} }

View file

@ -258,16 +258,12 @@ fn op_create_worker(
} }
#[op] #[op]
fn op_host_terminate_worker( fn op_host_terminate_worker(state: &mut OpState, id: WorkerId) {
state: &mut OpState,
id: WorkerId,
) -> Result<(), AnyError> {
if let Some(worker_thread) = state.borrow_mut::<WorkersTable>().remove(&id) { if let Some(worker_thread) = state.borrow_mut::<WorkersTable>().remove(&id) {
worker_thread.terminate(); worker_thread.terminate();
} else { } else {
debug!("tried to terminate non-existent worker {}", id); debug!("tried to terminate non-existent worker {}", id);
} }
Ok(())
} }
enum WorkerChannel { enum WorkerChannel {