summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/net/ops.rs12
-rw-r--r--ops/fast_call.rs41
-rw-r--r--ops/lib.rs5
-rw-r--r--ops/optimizer.rs37
-rw-r--r--ops/optimizer_tests/async_nop.expected1
-rw-r--r--ops/optimizer_tests/async_result.expected3
-rw-r--r--ops/optimizer_tests/callback_options.expected3
-rw-r--r--ops/optimizer_tests/callback_options.out7
-rw-r--r--ops/optimizer_tests/op_blob_revoke_object_url.expected1
-rw-r--r--ops/optimizer_tests/op_blob_revoke_object_url.out71
-rw-r--r--ops/optimizer_tests/op_blob_revoke_object_url.rs9
-rw-r--r--ops/optimizer_tests/op_state.expected1
-rw-r--r--ops/optimizer_tests/op_state_basic1.expected1
-rw-r--r--ops/optimizer_tests/op_state_generics.expected1
-rw-r--r--ops/optimizer_tests/op_state_result.expected1
-rw-r--r--ops/optimizer_tests/op_state_warning.expected1
-rw-r--r--ops/optimizer_tests/op_state_with_transforms.expected3
-rw-r--r--ops/optimizer_tests/opstate_with_arity.expected1
-rw-r--r--ops/optimizer_tests/option_arg.expected1
-rw-r--r--ops/optimizer_tests/option_arg.out66
-rw-r--r--ops/optimizer_tests/option_arg.rs6
-rw-r--r--ops/optimizer_tests/raw_ptr.expected3
-rw-r--r--ops/optimizer_tests/serde_v8_value.expected1
-rw-r--r--ops/optimizer_tests/uint8array.expected11
-rw-r--r--ops/optimizer_tests/uint8array.out191
-rw-r--r--ops/optimizer_tests/uint8array.rs3
-rw-r--r--ops/optimizer_tests/unit_result.expected11
-rw-r--r--ops/optimizer_tests/unit_result.out113
-rw-r--r--ops/optimizer_tests/unit_result.rs3
-rw-r--r--ops/optimizer_tests/unit_result2.expected11
-rw-r--r--ops/optimizer_tests/unit_result2.out149
-rw-r--r--ops/optimizer_tests/unit_result2.rs10
-rw-r--r--ops/optimizer_tests/unit_ret.expected11
-rw-r--r--ops/optimizer_tests/unit_ret.out84
-rw-r--r--ops/optimizer_tests/unit_ret.rs3
35 files changed, 844 insertions, 32 deletions
diff --git a/ext/net/ops.rs b/ext/net/ops.rs
index 96de8cff1..e567c3188 100644
--- a/ext/net/ops.rs
+++ b/ext/net/ops.rs
@@ -67,8 +67,8 @@ pub fn init<P: NetPermissions + 'static>() -> Vec<OpDecl> {
#[cfg(unix)]
crate::ops_unix::op_net_send_unixpacket::decl::<P>(),
op_dns_resolve::decl::<P>(),
- op_set_nodelay::decl::<P>(),
- op_set_keepalive::decl::<P>(),
+ op_set_nodelay::decl(),
+ op_set_keepalive::decl(),
]
}
@@ -509,7 +509,7 @@ where
}
#[op]
-pub fn op_set_nodelay<NP>(
+pub fn op_set_nodelay(
state: &mut OpState,
rid: ResourceId,
nodelay: bool,
@@ -521,7 +521,7 @@ pub fn op_set_nodelay<NP>(
}
#[op]
-pub fn op_set_keepalive<NP>(
+pub fn op_set_keepalive(
state: &mut OpState,
rid: ResourceId,
keepalive: bool,
@@ -836,7 +836,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::call::<TestPermission>(state, rid, true).unwrap();
+ op_set_nodelay::call(state, rid, true).unwrap();
});
let test_fn = Box::new(|socket: SockRef| {
assert!(socket.nodelay().unwrap());
@@ -848,7 +848,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::call::<TestPermission>(state, rid, true).unwrap();
+ op_set_keepalive::call(state, rid, true).unwrap();
});
let test_fn = Box::new(|socket: SockRef| {
assert!(!socket.nodelay().unwrap());
diff --git a/ops/fast_call.rs b/ops/fast_call.rs
index 8f6348ec4..07bf87026 100644
--- a/ops/fast_call.rs
+++ b/ops/fast_call.rs
@@ -141,10 +141,19 @@ pub(crate) fn generate(
if optimizer.has_fast_callback_option
|| optimizer.needs_opstate()
|| optimizer.is_async
+ || optimizer.needs_fast_callback_option
{
- fast_fn_inputs.push(parse_quote! {
+ let decl = parse_quote! {
fast_api_callback_options: *mut #core::v8::fast_api::FastApiCallbackOptions
- });
+ };
+
+ if optimizer.has_fast_callback_option {
+ // Replace last parameter.
+ assert!(fast_fn_inputs.pop().is_some());
+ fast_fn_inputs.push(decl);
+ } else {
+ fast_fn_inputs.push(decl);
+ }
input_variants.push(q!({ CallbackOptions }));
}
@@ -162,14 +171,10 @@ pub(crate) fn generate(
let mut output_transforms = q!({});
- if optimizer.needs_opstate() || optimizer.is_async {
- // Grab the op_state identifier, the first one. ¯\_(ツ)_/¯
- let op_state = match idents.first() {
- Some(ident) if optimizer.has_opstate_in_parameters() => ident.clone(),
- // fn op_foo() -> Result<...>
- _ => Ident::new("op_state", Span::call_site()),
- };
-
+ if optimizer.needs_opstate()
+ || optimizer.is_async
+ || optimizer.has_fast_callback_option
+ {
// Dark arts 🪄 ✨
//
// - V8 calling convention guarantees that the callback options pointer is non-null.
@@ -179,13 +184,27 @@ pub(crate) fn generate(
let prelude = q!({
let __opts: &mut v8::fast_api::FastApiCallbackOptions =
unsafe { &mut *fast_api_callback_options };
+ });
+
+ pre_transforms.push_tokens(&prelude);
+ }
+
+ if optimizer.needs_opstate() || optimizer.is_async {
+ // Grab the op_state identifier, the first one. ¯\_(ツ)_/¯
+ let op_state = match idents.first() {
+ Some(ident) if optimizer.has_opstate_in_parameters() => ident.clone(),
+ // fn op_foo() -> Result<...>
+ _ => Ident::new("op_state", Span::call_site()),
+ };
+
+ let ctx = q!({
let __ctx = unsafe {
&*(v8::Local::<v8::External>::cast(unsafe { __opts.data.data }).value()
as *const _ops::OpCtx)
};
});
- pre_transforms.push_tokens(&prelude);
+ pre_transforms.push_tokens(&ctx);
pre_transforms.push_tokens(&match optimizer.is_async {
false => q!(
Vars {
diff --git a/ops/lib.rs b/ops/lib.rs
index a5c196c04..971b0dfa0 100644
--- a/ops/lib.rs
+++ b/ops/lib.rs
@@ -76,10 +76,11 @@ impl Op {
fn gen(mut self) -> TokenStream2 {
let mut optimizer = Optimizer::new();
match optimizer.analyze(&mut self) {
- Ok(_) | Err(BailoutReason::MustBeSingleSegment) => {}
- Err(BailoutReason::FastUnsupportedParamType) => {
+ Err(BailoutReason::MustBeSingleSegment)
+ | Err(BailoutReason::FastUnsupportedParamType) => {
optimizer.fast_compatible = false;
}
+ _ => {}
};
let Self {
diff --git a/ops/optimizer.rs b/ops/optimizer.rs
index cf2c71ae4..8fa2ab1f5 100644
--- a/ops/optimizer.rs
+++ b/ops/optimizer.rs
@@ -9,7 +9,7 @@ use syn::{
parse_quote, punctuated::Punctuated, token::Colon2,
AngleBracketedGenericArguments, FnArg, GenericArgument, PatType, Path,
PathArguments, PathSegment, ReturnType, Signature, Type, TypePath, TypePtr,
- TypeReference, TypeSlice,
+ TypeReference, TypeSlice, TypeTuple,
};
#[derive(Debug)]
@@ -196,7 +196,10 @@ pub(crate) struct Optimizer {
pub(crate) has_rc_opstate: bool,
+ // Do we need an explict FastApiCallbackOptions argument?
pub(crate) has_fast_callback_option: bool,
+ // Do we depend on FastApiCallbackOptions?
+ pub(crate) needs_fast_callback_option: bool,
pub(crate) fast_result: Option<FastValue>,
pub(crate) fast_parameters: Vec<FastValue>,
@@ -218,6 +221,11 @@ impl Debug for Optimizer {
"has_fast_callback_option: {}",
self.has_fast_callback_option
)?;
+ writeln!(
+ f,
+ "needs_fast_callback_option: {}",
+ self.needs_fast_callback_option
+ )?;
writeln!(f, "fast_result: {:?}", self.fast_result)?;
writeln!(f, "fast_parameters: {:?}", self.fast_parameters)?;
writeln!(f, "transforms: {:?}", self.transforms)?;
@@ -298,6 +306,9 @@ impl Optimizer {
fn analyze_return_type(&mut self, ty: &Type) -> Result<(), BailoutReason> {
match ty {
+ Type::Tuple(TypeTuple { elems, .. }) if elems.is_empty() => {
+ self.fast_result = Some(FastValue::Void);
+ }
Type::Path(TypePath {
path: Path { segments, .. },
..
@@ -333,6 +344,14 @@ impl Optimizer {
self.fast_compatible = false;
return Err(BailoutReason::FastUnsupportedParamType);
}
+ Some(GenericArgument::Type(Type::Tuple(TypeTuple {
+ elems,
+ ..
+ })))
+ if elems.is_empty() =>
+ {
+ self.fast_result = Some(FastValue::Void);
+ }
_ => return Err(BailoutReason::FastUnsupportedParamType),
}
}
@@ -407,15 +426,19 @@ impl Optimizer {
{
let segment = single_segment(segments)?;
match segment {
- // Is `T` a FastApiCallbackOption?
+ // Is `T` a FastApiCallbackOptions?
PathSegment { ident, .. }
- if ident == "FastApiCallbackOption" =>
+ if ident == "FastApiCallbackOptions" =>
{
self.has_fast_callback_option = true;
}
- _ => {}
+ _ => return Err(BailoutReason::FastUnsupportedParamType),
}
+ } else {
+ return Err(BailoutReason::FastUnsupportedParamType);
}
+ } else {
+ return Err(BailoutReason::FastUnsupportedParamType);
}
}
}
@@ -517,7 +540,7 @@ impl Optimizer {
match segment {
// Is `T` a u8?
PathSegment { ident, .. } if ident == "u8" => {
- self.has_fast_callback_option = true;
+ self.needs_fast_callback_option = true;
self.fast_parameters.push(FastValue::Uint8Array);
assert!(self
.transforms
@@ -526,7 +549,7 @@ impl Optimizer {
}
// Is `T` a u32?
PathSegment { ident, .. } if ident == "u32" => {
- self.has_fast_callback_option = true;
+ self.needs_fast_callback_option = true;
self.fast_parameters.push(FastValue::Uint32Array);
assert!(self
.transforms
@@ -554,7 +577,7 @@ impl Optimizer {
match segment {
// Is `T` a u8?
PathSegment { ident, .. } if ident == "u8" => {
- self.has_fast_callback_option = true;
+ self.needs_fast_callback_option = true;
self.fast_parameters.push(FastValue::Uint8Array);
assert!(self
.transforms
diff --git a/ops/optimizer_tests/async_nop.expected b/ops/optimizer_tests/async_nop.expected
index 78c161e8c..42a1180bd 100644
--- a/ops/optimizer_tests/async_nop.expected
+++ b/ops/optimizer_tests/async_nop.expected
@@ -3,6 +3,7 @@ returns_result: false
has_ref_opstate: false
has_rc_opstate: false
has_fast_callback_option: false
+needs_fast_callback_option: false
fast_result: Some(Void)
fast_parameters: [V8Value, I32]
transforms: {}
diff --git a/ops/optimizer_tests/async_result.expected b/ops/optimizer_tests/async_result.expected
index dcd9cd1e3..be2e79ac0 100644
--- a/ops/optimizer_tests/async_result.expected
+++ b/ops/optimizer_tests/async_result.expected
@@ -2,7 +2,8 @@
returns_result: true
has_ref_opstate: false
has_rc_opstate: true
-has_fast_callback_option: true
+has_fast_callback_option: false
+needs_fast_callback_option: true
fast_result: None
fast_parameters: [V8Value, I32, U32, Uint8Array]
transforms: {2: Transform { kind: SliceU8(true), index: 2 }}
diff --git a/ops/optimizer_tests/callback_options.expected b/ops/optimizer_tests/callback_options.expected
index b309ab987..245fdfd55 100644
--- a/ops/optimizer_tests/callback_options.expected
+++ b/ops/optimizer_tests/callback_options.expected
@@ -2,7 +2,8 @@
returns_result: false
has_ref_opstate: false
has_rc_opstate: false
-has_fast_callback_option: false
+has_fast_callback_option: true
+needs_fast_callback_option: false
fast_result: Some(Void)
fast_parameters: [V8Value]
transforms: {}
diff --git a/ops/optimizer_tests/callback_options.out b/ops/optimizer_tests/callback_options.out
index 020cc4a3e..81745375d 100644
--- a/ops/optimizer_tests/callback_options.out
+++ b/ops/optimizer_tests/callback_options.out
@@ -61,7 +61,7 @@ impl<'scope> deno_core::v8::fast_api::FastFunction for op_fallback_fast {
fn args(&self) -> &'static [deno_core::v8::fast_api::Type] {
use deno_core::v8::fast_api::Type::*;
use deno_core::v8::fast_api::CType;
- &[V8Value]
+ &[V8Value, CallbackOptions]
}
fn return_type(&self) -> deno_core::v8::fast_api::CType {
deno_core::v8::fast_api::CType::Void
@@ -69,10 +69,13 @@ impl<'scope> deno_core::v8::fast_api::FastFunction for op_fallback_fast {
}
fn op_fallback_fast_fn<'scope>(
_: deno_core::v8::Local<deno_core::v8::Object>,
- options: Option<&mut FastApiCallbackOptions>,
+ fast_api_callback_options: *mut deno_core::v8::fast_api::FastApiCallbackOptions,
) -> () {
use deno_core::v8;
use deno_core::_ops;
+ let __opts: &mut v8::fast_api::FastApiCallbackOptions = unsafe {
+ &mut *fast_api_callback_options
+ };
let result = op_fallback::call(options);
result
}
diff --git a/ops/optimizer_tests/op_blob_revoke_object_url.expected b/ops/optimizer_tests/op_blob_revoke_object_url.expected
new file mode 100644
index 000000000..0fae25e86
--- /dev/null
+++ b/ops/optimizer_tests/op_blob_revoke_object_url.expected
@@ -0,0 +1 @@
+MustBeSingleSegment \ No newline at end of file
diff --git a/ops/optimizer_tests/op_blob_revoke_object_url.out b/ops/optimizer_tests/op_blob_revoke_object_url.out
new file mode 100644
index 000000000..72bc75e05
--- /dev/null
+++ b/ops/optimizer_tests/op_blob_revoke_object_url.out
@@ -0,0 +1,71 @@
+#[allow(non_camel_case_types)]
+///Auto-generated by `deno_ops`, i.e: `#[op]`
+///
+///Use `op_blob_revoke_object_url::decl()` to get an op-declaration
+///you can include in a `deno_core::Extension`.
+pub struct op_blob_revoke_object_url;
+#[doc(hidden)]
+impl op_blob_revoke_object_url {
+ pub fn name() -> &'static str {
+ stringify!(op_blob_revoke_object_url)
+ }
+ pub fn v8_fn_ptr<'scope>() -> deno_core::v8::FunctionCallback {
+ use deno_core::v8::MapFnTo;
+ Self::v8_func.map_fn_to()
+ }
+ pub fn decl<'scope>() -> deno_core::OpDecl {
+ deno_core::OpDecl {
+ name: Self::name(),
+ v8_fn_ptr: Self::v8_fn_ptr(),
+ enabled: true,
+ fast_fn: None,
+ is_async: false,
+ is_unstable: false,
+ is_v8: false,
+ argc: 1usize,
+ }
+ }
+ #[inline]
+ #[allow(clippy::too_many_arguments)]
+ pub fn call(state: &mut deno_core::OpState, url: String) -> Result<(), AnyError> {
+ let url = Url::parse(&url)?;
+ let blob_store = state.borrow::<BlobStore>();
+ blob_store.remove_object_url(&url);
+ Ok(())
+ }
+ pub fn v8_func<'scope>(
+ scope: &mut deno_core::v8::HandleScope<'scope>,
+ args: deno_core::v8::FunctionCallbackArguments,
+ mut rv: deno_core::v8::ReturnValue,
+ ) {
+ let ctx = unsafe {
+ &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value()
+ as *const deno_core::_ops::OpCtx)
+ };
+ let arg_0 = match deno_core::v8::Local::<
+ deno_core::v8::String,
+ >::try_from(args.get(0usize as i32)) {
+ Ok(v8_string) => deno_core::serde_v8::to_utf8(v8_string, scope),
+ Err(_) => {
+ return deno_core::_ops::throw_type_error(
+ scope,
+ format!("Expected string at position {}", 0usize),
+ );
+ }
+ };
+ let result = Self::call(&mut std::cell::RefCell::borrow_mut(&ctx.state), arg_0);
+ let op_state = ::std::cell::RefCell::borrow(&*ctx.state);
+ op_state.tracker.track_sync(ctx.id);
+ match result {
+ Ok(result) => {}
+ Err(err) => {
+ let exception = deno_core::error::to_v8_error(
+ scope,
+ op_state.get_error_class_fn,
+ &err,
+ );
+ scope.throw_exception(exception);
+ }
+ };
+ }
+}
diff --git a/ops/optimizer_tests/op_blob_revoke_object_url.rs b/ops/optimizer_tests/op_blob_revoke_object_url.rs
new file mode 100644
index 000000000..8e139da06
--- /dev/null
+++ b/ops/optimizer_tests/op_blob_revoke_object_url.rs
@@ -0,0 +1,9 @@
+pub fn op_blob_revoke_object_url(
+ state: &mut deno_core::OpState,
+ url: String,
+) -> Result<(), AnyError> {
+ let url = Url::parse(&url)?;
+ let blob_store = state.borrow::<BlobStore>();
+ blob_store.remove_object_url(&url);
+ Ok(())
+}
diff --git a/ops/optimizer_tests/op_state.expected b/ops/optimizer_tests/op_state.expected
index d8d680455..241ea7693 100644
--- a/ops/optimizer_tests/op_state.expected
+++ b/ops/optimizer_tests/op_state.expected
@@ -3,6 +3,7 @@ returns_result: false
has_ref_opstate: true
has_rc_opstate: false
has_fast_callback_option: false
+needs_fast_callback_option: false
fast_result: Some(Void)
fast_parameters: [V8Value, I32]
transforms: {}
diff --git a/ops/optimizer_tests/op_state_basic1.expected b/ops/optimizer_tests/op_state_basic1.expected
index 6e7b15493..e325dd2f7 100644
--- a/ops/optimizer_tests/op_state_basic1.expected
+++ b/ops/optimizer_tests/op_state_basic1.expected
@@ -3,6 +3,7 @@ returns_result: false
has_ref_opstate: true
has_rc_opstate: false
has_fast_callback_option: false
+needs_fast_callback_option: false
fast_result: Some(U32)
fast_parameters: [V8Value, U32, U32]
transforms: {}
diff --git a/ops/optimizer_tests/op_state_generics.expected b/ops/optimizer_tests/op_state_generics.expected
index b78c81c5f..c29258d75 100644
--- a/ops/optimizer_tests/op_state_generics.expected
+++ b/ops/optimizer_tests/op_state_generics.expected
@@ -3,6 +3,7 @@ returns_result: false
has_ref_opstate: true
has_rc_opstate: false
has_fast_callback_option: false
+needs_fast_callback_option: false
fast_result: Some(Void)
fast_parameters: [V8Value]
transforms: {}
diff --git a/ops/optimizer_tests/op_state_result.expected b/ops/optimizer_tests/op_state_result.expected
index e13390052..15ac033f3 100644
--- a/ops/optimizer_tests/op_state_result.expected
+++ b/ops/optimizer_tests/op_state_result.expected
@@ -3,6 +3,7 @@ returns_result: true
has_ref_opstate: true
has_rc_opstate: false
has_fast_callback_option: false
+needs_fast_callback_option: false
fast_result: Some(U32)
fast_parameters: [V8Value, U32, U32]
transforms: {}
diff --git a/ops/optimizer_tests/op_state_warning.expected b/ops/optimizer_tests/op_state_warning.expected
index 94580fd6d..7b33ad1ef 100644
--- a/ops/optimizer_tests/op_state_warning.expected
+++ b/ops/optimizer_tests/op_state_warning.expected
@@ -3,6 +3,7 @@ returns_result: true
has_ref_opstate: true
has_rc_opstate: false
has_fast_callback_option: false
+needs_fast_callback_option: false
fast_result: Some(U32)
fast_parameters: [V8Value]
transforms: {}
diff --git a/ops/optimizer_tests/op_state_with_transforms.expected b/ops/optimizer_tests/op_state_with_transforms.expected
index 0fc9c9949..d6757801e 100644
--- a/ops/optimizer_tests/op_state_with_transforms.expected
+++ b/ops/optimizer_tests/op_state_with_transforms.expected
@@ -2,7 +2,8 @@
returns_result: false
has_ref_opstate: true
has_rc_opstate: false
-has_fast_callback_option: true
+has_fast_callback_option: false
+needs_fast_callback_option: true
fast_result: Some(Void)
fast_parameters: [V8Value, Uint8Array]
transforms: {1: Transform { kind: SliceU8(true), index: 1 }}
diff --git a/ops/optimizer_tests/opstate_with_arity.expected b/ops/optimizer_tests/opstate_with_arity.expected
index 4be888c33..b38455d0d 100644
--- a/ops/optimizer_tests/opstate_with_arity.expected
+++ b/ops/optimizer_tests/opstate_with_arity.expected
@@ -3,6 +3,7 @@ returns_result: true
has_ref_opstate: false
has_rc_opstate: false
has_fast_callback_option: false
+needs_fast_callback_option: false
fast_result: Some(U32)
fast_parameters: [V8Value, U32, U32, U32, U32]
transforms: {}
diff --git a/ops/optimizer_tests/option_arg.expected b/ops/optimizer_tests/option_arg.expected
new file mode 100644
index 000000000..250ff1022
--- /dev/null
+++ b/ops/optimizer_tests/option_arg.expected
@@ -0,0 +1 @@
+FastUnsupportedParamType \ No newline at end of file
diff --git a/ops/optimizer_tests/option_arg.out b/ops/optimizer_tests/option_arg.out
new file mode 100644
index 000000000..9f647765f
--- /dev/null
+++ b/ops/optimizer_tests/option_arg.out
@@ -0,0 +1,66 @@
+#[allow(non_camel_case_types)]
+///Auto-generated by `deno_ops`, i.e: `#[op]`
+///
+///Use `op_try_close::decl()` to get an op-declaration
+///you can include in a `deno_core::Extension`.
+pub struct op_try_close;
+#[doc(hidden)]
+impl op_try_close {
+ pub fn name() -> &'static str {
+ stringify!(op_try_close)
+ }
+ pub fn v8_fn_ptr<'scope>() -> deno_core::v8::FunctionCallback {
+ use deno_core::v8::MapFnTo;
+ Self::v8_func.map_fn_to()
+ }
+ pub fn decl<'scope>() -> deno_core::OpDecl {
+ deno_core::OpDecl {
+ name: Self::name(),
+ v8_fn_ptr: Self::v8_fn_ptr(),
+ enabled: true,
+ fast_fn: None,
+ is_async: false,
+ is_unstable: false,
+ is_v8: false,
+ argc: 1usize,
+ }
+ }
+ #[inline]
+ #[allow(clippy::too_many_arguments)]
+ pub fn call(state: &mut OpState, rid: Option<ResourceId>) -> Result<(), Error> {}
+ pub fn v8_func<'scope>(
+ scope: &mut deno_core::v8::HandleScope<'scope>,
+ args: deno_core::v8::FunctionCallbackArguments,
+ mut rv: deno_core::v8::ReturnValue,
+ ) {
+ let ctx = unsafe {
+ &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value()
+ as *const deno_core::_ops::OpCtx)
+ };
+ let arg_0 = args.get(0usize as i32);
+ let arg_0 = match deno_core::serde_v8::from_v8(scope, arg_0) {
+ Ok(v) => v,
+ Err(err) => {
+ let msg = format!(
+ "Error parsing args at position {}: {}", 0usize,
+ deno_core::anyhow::Error::from(err)
+ );
+ return deno_core::_ops::throw_type_error(scope, msg);
+ }
+ };
+ let result = Self::call(&mut std::cell::RefCell::borrow_mut(&ctx.state), arg_0);
+ let op_state = ::std::cell::RefCell::borrow(&*ctx.state);
+ op_state.tracker.track_sync(ctx.id);
+ match result {
+ Ok(result) => {}
+ Err(err) => {
+ let exception = deno_core::error::to_v8_error(
+ scope,
+ op_state.get_error_class_fn,
+ &err,
+ );
+ scope.throw_exception(exception);
+ }
+ };
+ }
+}
diff --git a/ops/optimizer_tests/option_arg.rs b/ops/optimizer_tests/option_arg.rs
new file mode 100644
index 000000000..47a02974d
--- /dev/null
+++ b/ops/optimizer_tests/option_arg.rs
@@ -0,0 +1,6 @@
+pub fn op_try_close(
+ state: &mut OpState,
+ rid: Option<ResourceId>,
+) -> Result<(), Error> {
+ // ...
+}
diff --git a/ops/optimizer_tests/raw_ptr.expected b/ops/optimizer_tests/raw_ptr.expected
index 12577eb77..badd6e3f4 100644
--- a/ops/optimizer_tests/raw_ptr.expected
+++ b/ops/optimizer_tests/raw_ptr.expected
@@ -2,7 +2,8 @@
returns_result: false
has_ref_opstate: true
has_rc_opstate: false
-has_fast_callback_option: true
+has_fast_callback_option: false
+needs_fast_callback_option: true
fast_result: Some(Void)
fast_parameters: [V8Value, Uint8Array, Uint32Array]
transforms: {1: Transform { kind: PtrU8, index: 1 }, 2: Transform { kind: SliceU32(true), index: 2 }}
diff --git a/ops/optimizer_tests/serde_v8_value.expected b/ops/optimizer_tests/serde_v8_value.expected
index 058b17b1c..411fbec0b 100644
--- a/ops/optimizer_tests/serde_v8_value.expected
+++ b/ops/optimizer_tests/serde_v8_value.expected
@@ -3,6 +3,7 @@ returns_result: false
has_ref_opstate: false
has_rc_opstate: false
has_fast_callback_option: false
+needs_fast_callback_option: false
fast_result: Some(Bool)
fast_parameters: [V8Value, V8Value]
transforms: {0: Transform { kind: V8Value, index: 0 }}
diff --git a/ops/optimizer_tests/uint8array.expected b/ops/optimizer_tests/uint8array.expected
new file mode 100644
index 000000000..0e5667a63
--- /dev/null
+++ b/ops/optimizer_tests/uint8array.expected
@@ -0,0 +1,11 @@
+=== Optimizer Dump ===
+returns_result: false
+has_ref_opstate: false
+has_rc_opstate: false
+has_fast_callback_option: false
+needs_fast_callback_option: true
+fast_result: Some(Bool)
+fast_parameters: [V8Value, Uint8Array, Uint8Array]
+transforms: {0: Transform { kind: SliceU8(false), index: 0 }, 1: Transform { kind: SliceU8(true), index: 1 }}
+is_async: false
+fast_compatible: true
diff --git a/ops/optimizer_tests/uint8array.out b/ops/optimizer_tests/uint8array.out
new file mode 100644
index 000000000..90d420fa0
--- /dev/null
+++ b/ops/optimizer_tests/uint8array.out
@@ -0,0 +1,191 @@
+#[allow(non_camel_case_types)]
+///Auto-generated by `deno_ops`, i.e: `#[op]`
+///
+///Use `op_import_spki_x25519::decl()` to get an op-declaration
+///you can include in a `deno_core::Extension`.
+pub struct op_import_spki_x25519;
+#[doc(hidden)]
+impl op_import_spki_x25519 {
+ pub fn name() -> &'static str {
+ stringify!(op_import_spki_x25519)
+ }
+ pub fn v8_fn_ptr<'scope>() -> deno_core::v8::FunctionCallback {
+ use deno_core::v8::MapFnTo;
+ Self::v8_func.map_fn_to()
+ }
+ pub fn decl<'scope>() -> deno_core::OpDecl {
+ deno_core::OpDecl {
+ name: Self::name(),
+ v8_fn_ptr: Self::v8_fn_ptr(),
+ enabled: true,
+ fast_fn: Some(
+ Box::new(op_import_spki_x25519_fast {
+ _phantom: ::std::marker::PhantomData,
+ }),
+ ),
+ is_async: false,
+ is_unstable: false,
+ is_v8: false,
+ argc: 2usize,
+ }
+ }
+ #[inline]
+ #[allow(clippy::too_many_arguments)]
+ pub fn call(key_data: &[u8], out: &mut [u8]) -> bool {}
+ pub fn v8_func<'scope>(
+ scope: &mut deno_core::v8::HandleScope<'scope>,
+ args: deno_core::v8::FunctionCallbackArguments,
+ mut rv: deno_core::v8::ReturnValue,
+ ) {
+ let ctx = unsafe {
+ &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value()
+ as *const deno_core::_ops::OpCtx)
+ };
+ let arg_0 = {
+ let value = args.get(0usize as i32);
+ match deno_core::v8::Local::<deno_core::v8::ArrayBuffer>::try_from(value) {
+ Ok(b) => {
+ let byte_length = b.byte_length();
+ if let Some(data) = b.data() {
+ let store = data.cast::<u8>().as_ptr();
+ unsafe { ::std::slice::from_raw_parts_mut(store, byte_length) }
+ } else {
+ &mut []
+ }
+ }
+ Err(_) => {
+ if let Ok(view)
+ = deno_core::v8::Local::<
+ deno_core::v8::ArrayBufferView,
+ >::try_from(value) {
+ let len = view.byte_length();
+ let offset = view.byte_offset();
+ let buffer = match view.buffer(scope) {
+ Some(v) => v,
+ None => {
+ return deno_core::_ops::throw_type_error(
+ scope,
+ format!("Expected ArrayBufferView at position {}", 0usize),
+ );
+ }
+ };
+ if let Some(data) = buffer.data() {
+ let store = data.cast::<u8>().as_ptr();
+ unsafe {
+ ::std::slice::from_raw_parts_mut(store.add(offset), len)
+ }
+ } else {
+ &mut []
+ }
+ } else {
+ return deno_core::_ops::throw_type_error(
+ scope,
+ format!("Expected ArrayBufferView at position {}", 0usize),
+ );
+ }
+ }
+ }
+ };
+ let arg_1 = {
+ let value = args.get(1usize as i32);
+ match deno_core::v8::Local::<deno_core::v8::ArrayBuffer>::try_from(value) {
+ Ok(b) => {
+ let byte_length = b.byte_length();
+ if let Some(data) = b.data() {
+ let store = data.cast::<u8>().as_ptr();
+ unsafe { ::std::slice::from_raw_parts_mut(store, byte_length) }
+ } else {
+ &mut []
+ }
+ }
+ Err(_) => {
+ if let Ok(view)
+ = deno_core::v8::Local::<
+ deno_core::v8::ArrayBufferView,
+ >::try_from(value) {
+ let len = view.byte_length();
+ let offset = view.byte_offset();
+ let buffer = match view.buffer(scope) {
+ Some(v) => v,
+ None => {
+ return deno_core::_ops::throw_type_error(
+ scope,
+ format!("Expected ArrayBufferView at position {}", 1usize),
+ );
+ }
+ };
+ if let Some(data) = buffer.data() {
+ let store = data.cast::<u8>().as_ptr();
+ unsafe {
+ ::std::slice::from_raw_parts_mut(store.add(offset), len)
+ }
+ } else {
+ &mut []
+ }
+ } else {
+ return deno_core::_ops::throw_type_error(
+ scope,
+ format!("Expected ArrayBufferView at position {}", 1usize),
+ );
+ }
+ }
+ }
+ };
+ let result = Self::call(arg_0, arg_1);
+ let op_state = ::std::cell::RefCell::borrow(&*ctx.state);
+ op_state.tracker.track_sync(ctx.id);
+ match deno_core::serde_v8::to_v8(scope, result) {
+ Ok(ret) => rv.set(ret),
+ Err(err) => {
+ deno_core::_ops::throw_type_error(
+ scope,
+ format!(
+ "Error serializing return: {}",
+ deno_core::anyhow::Error::from(err)
+ ),
+ )
+ }
+ };
+ }
+}
+struct op_import_spki_x25519_fast {
+ _phantom: ::std::marker::PhantomData<()>,
+}
+impl<'scope> deno_core::v8::fast_api::FastFunction for op_import_spki_x25519_fast {
+ fn function(&self) -> *const ::std::ffi::c_void {
+ op_import_spki_x25519_fast_fn as *const ::std::ffi::c_void
+ }
+ fn args(&self) -> &'static [deno_core::v8::fast_api::Type] {
+ use deno_core::v8::fast_api::Type::*;
+ use deno_core::v8::fast_api::CType;
+ &[V8Value, TypedArray(CType::Uint8), TypedArray(CType::Uint8), CallbackOptions]
+ }
+ fn return_type(&self) -> deno_core::v8::fast_api::CType {
+ deno_core::v8::fast_api::CType::Bool
+ }
+}
+fn op_import_spki_x25519_fast_fn<'scope>(
+ _: deno_core::v8::Local<deno_core::v8::Object>,
+ key_data: *const deno_core::v8::fast_api::FastApiTypedArray<u8>,
+ out: *const deno_core::v8::fast_api::FastApiTypedArray<u8>,
+ fast_api_callback_options: *mut deno_core::v8::fast_api::FastApiCallbackOptions,
+) -> bool {
+ use deno_core::v8;
+ use deno_core::_ops;
+ let key_data = match unsafe { &*key_data }.get_storage_if_aligned() {
+ Some(v) => v,
+ None => {
+ unsafe { &mut *fast_api_callback_options }.fallback = true;
+ return Default::default();
+ }
+ };
+ let out = match unsafe { &*out }.get_storage_if_aligned() {
+ Some(v) => v,
+ None => {
+ unsafe { &mut *fast_api_callback_options }.fallback = true;
+ return Default::default();
+ }
+ };
+ let result = op_import_spki_x25519::call(key_data, out);
+ result
+}
diff --git a/ops/optimizer_tests/uint8array.rs b/ops/optimizer_tests/uint8array.rs
new file mode 100644
index 000000000..f4507b21f
--- /dev/null
+++ b/ops/optimizer_tests/uint8array.rs
@@ -0,0 +1,3 @@
+pub fn op_import_spki_x25519(key_data: &[u8], out: &mut [u8]) -> bool {
+ // ...
+}
diff --git a/ops/optimizer_tests/unit_result.expected b/ops/optimizer_tests/unit_result.expected
new file mode 100644
index 000000000..693a771e9
--- /dev/null
+++ b/ops/optimizer_tests/unit_result.expected
@@ -0,0 +1,11 @@
+=== Optimizer Dump ===
+returns_result: true
+has_ref_opstate: false
+has_rc_opstate: false
+has_fast_callback_option: false
+needs_fast_callback_option: false
+fast_result: Some(Void)
+fast_parameters: [V8Value]
+transforms: {}
+is_async: false
+fast_compatible: true
diff --git a/ops/optimizer_tests/unit_result.out b/ops/optimizer_tests/unit_result.out
new file mode 100644
index 000000000..f9d1e0c34
--- /dev/null
+++ b/ops/optimizer_tests/unit_result.out
@@ -0,0 +1,113 @@
+#[allow(non_camel_case_types)]
+///Auto-generated by `deno_ops`, i.e: `#[op]`
+///
+///Use `op_unit_result::decl()` to get an op-declaration
+///you can include in a `deno_core::Extension`.
+pub struct op_unit_result;
+#[doc(hidden)]
+impl op_unit_result {
+ pub fn name() -> &'static str {
+ stringify!(op_unit_result)
+ }
+ pub fn v8_fn_ptr<'scope>() -> deno_core::v8::FunctionCallback {
+ use deno_core::v8::MapFnTo;
+ Self::v8_func.map_fn_to()
+ }
+ pub fn decl<'scope>() -> deno_core::OpDecl {
+ deno_core::OpDecl {
+ name: Self::name(),
+ v8_fn_ptr: Self::v8_fn_ptr(),
+ enabled: true,
+ fast_fn: Some(
+ Box::new(op_unit_result_fast {
+ _phantom: ::std::marker::PhantomData,
+ }),
+ ),
+ is_async: false,
+ is_unstable: false,
+ is_v8: false,
+ argc: 0usize,
+ }
+ }
+ #[inline]
+ #[allow(clippy::too_many_arguments)]
+ fn call() -> Result<(), AnyError> {
+ Ok(())
+ }
+ pub fn v8_func<'scope>(
+ scope: &mut deno_core::v8::HandleScope<'scope>,
+ args: deno_core::v8::FunctionCallbackArguments,
+ mut rv: deno_core::v8::ReturnValue,
+ ) {
+ let ctx = unsafe {
+ &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value()
+ as *const deno_core::_ops::OpCtx)
+ };
+ {
+ let op_state = &mut std::cell::RefCell::borrow_mut(&ctx.state);
+ if let Some(err) = op_state.last_fast_op_error.take() {
+ let exception = deno_core::error::to_v8_error(
+ scope,
+ op_state.get_error_class_fn,
+ &err,
+ );
+ scope.throw_exception(exception);
+ return;
+ }
+ }
+ let result = Self::call();
+ let op_state = ::std::cell::RefCell::borrow(&*ctx.state);
+ op_state.tracker.track_sync(ctx.id);
+ match result {
+ Ok(result) => {}
+ Err(err) => {
+ let exception = deno_core::error::to_v8_error(
+ scope,
+ op_state.get_error_class_fn,
+ &err,
+ );
+ scope.throw_exception(exception);
+ }
+ };
+ }
+}
+struct op_unit_result_fast {
+ _phantom: ::std::marker::PhantomData<()>,
+}
+impl<'scope> deno_core::v8::fast_api::FastFunction for op_unit_result_fast {
+ fn function(&self) -> *const ::std::ffi::c_void {
+ op_unit_result_fast_fn as *const ::std::ffi::c_void
+ }
+ fn args(&self) -> &'static [deno_core::v8::fast_api::Type] {
+ use deno_core::v8::fast_api::Type::*;
+ use deno_core::v8::fast_api::CType;
+ &[V8Value, CallbackOptions]
+ }
+ fn return_type(&self) -> deno_core::v8::fast_api::CType {
+ deno_core::v8::fast_api::CType::Void
+ }
+}
+fn op_unit_result_fast_fn<'scope>(
+ _: deno_core::v8::Local<deno_core::v8::Object>,
+ fast_api_callback_options: *mut deno_core::v8::fast_api::FastApiCallbackOptions,
+) -> () {
+ use deno_core::v8;
+ use deno_core::_ops;
+ let __opts: &mut v8::fast_api::FastApiCallbackOptions = unsafe {
+ &mut *fast_api_callback_options
+ };
+ let __ctx = unsafe {
+ &*(v8::Local::<v8::External>::cast(unsafe { __opts.data.data }).value()
+ as *const _ops::OpCtx)
+ };
+ let op_state = &mut ::std::cell::RefCell::borrow_mut(&__ctx.state);
+ let result = op_unit_result::call();
+ match result {
+ Ok(result) => result,
+ Err(err) => {
+ op_state.last_fast_op_error.replace(err);
+ __opts.fallback = true;
+ Default::default()
+ }
+ }
+}
diff --git a/ops/optimizer_tests/unit_result.rs b/ops/optimizer_tests/unit_result.rs
new file mode 100644
index 000000000..207896929
--- /dev/null
+++ b/ops/optimizer_tests/unit_result.rs
@@ -0,0 +1,3 @@
+fn op_unit_result() -> Result<(), AnyError> {
+ Ok(())
+}
diff --git a/ops/optimizer_tests/unit_result2.expected b/ops/optimizer_tests/unit_result2.expected
new file mode 100644
index 000000000..d799a77b2
--- /dev/null
+++ b/ops/optimizer_tests/unit_result2.expected
@@ -0,0 +1,11 @@
+=== Optimizer Dump ===
+returns_result: true
+has_ref_opstate: true
+has_rc_opstate: false
+has_fast_callback_option: false
+needs_fast_callback_option: false
+fast_result: Some(Void)
+fast_parameters: [V8Value, U32, Bool]
+transforms: {}
+is_async: false
+fast_compatible: true
diff --git a/ops/optimizer_tests/unit_result2.out b/ops/optimizer_tests/unit_result2.out
new file mode 100644
index 000000000..87e0ee0b5
--- /dev/null
+++ b/ops/optimizer_tests/unit_result2.out
@@ -0,0 +1,149 @@
+#[allow(non_camel_case_types)]
+///Auto-generated by `deno_ops`, i.e: `#[op]`
+///
+///Use `op_set_nodelay::decl()` to get an op-declaration
+///you can include in a `deno_core::Extension`.
+pub struct op_set_nodelay;
+#[doc(hidden)]
+impl op_set_nodelay {
+ pub fn name() -> &'static str {
+ stringify!(op_set_nodelay)
+ }
+ pub fn v8_fn_ptr<'scope>() -> deno_core::v8::FunctionCallback {
+ use deno_core::v8::MapFnTo;
+ Self::v8_func.map_fn_to()
+ }
+ pub fn decl<'scope>() -> deno_core::OpDecl {
+ deno_core::OpDecl {
+ name: Self::name(),
+ v8_fn_ptr: Self::v8_fn_ptr(),
+ enabled: true,
+ fast_fn: Some(
+ Box::new(op_set_nodelay_fast {
+ _phantom: ::std::marker::PhantomData,
+ }),
+ ),
+ is_async: false,
+ is_unstable: false,
+ is_v8: false,
+ argc: 2usize,
+ }
+ }
+ #[inline]
+ #[allow(clippy::too_many_arguments)]
+ pub fn call(
+ state: &mut OpState,
+ rid: ResourceId,
+ nodelay: bool,
+ ) -> Result<(), AnyError> {
+ super::check_unstable(state, "Deno.Conn#setNoDelay");
+ let resource: Rc<TcpStreamResource> = state
+ .resource_table
+ .get::<TcpStreamResource>(rid)?;
+ resource.set_nodelay(nodelay)
+ }
+ pub fn v8_func<'scope>(
+ scope: &mut deno_core::v8::HandleScope<'scope>,
+ args: deno_core::v8::FunctionCallbackArguments,
+ mut rv: deno_core::v8::ReturnValue,
+ ) {
+ let ctx = unsafe {
+ &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value()
+ as *const deno_core::_ops::OpCtx)
+ };
+ {
+ let op_state = &mut std::cell::RefCell::borrow_mut(&ctx.state);
+ if let Some(err) = op_state.last_fast_op_error.take() {
+ let exception = deno_core::error::to_v8_error(
+ scope,
+ op_state.get_error_class_fn,
+ &err,
+ );
+ scope.throw_exception(exception);
+ return;
+ }
+ }
+ let arg_0 = args.get(0usize as i32);
+ let arg_0 = match deno_core::serde_v8::from_v8(scope, arg_0) {
+ Ok(v) => v,
+ Err(err) => {
+ let msg = format!(
+ "Error parsing args at position {}: {}", 0usize,
+ deno_core::anyhow::Error::from(err)
+ );
+ return deno_core::_ops::throw_type_error(scope, msg);
+ }
+ };
+ let arg_1 = args.get(1usize as i32);
+ let arg_1 = match deno_core::serde_v8::from_v8(scope, arg_1) {
+ Ok(v) => v,
+ Err(err) => {
+ let msg = format!(
+ "Error parsing args at position {}: {}", 1usize,
+ deno_core::anyhow::Error::from(err)
+ );
+ return deno_core::_ops::throw_type_error(scope, msg);
+ }
+ };
+ let result = Self::call(
+ &mut std::cell::RefCell::borrow_mut(&ctx.state),
+ arg_0,
+ arg_1,
+ );
+ let op_state = ::std::cell::RefCell::borrow(&*ctx.state);
+ op_state.tracker.track_sync(ctx.id);
+ match result {
+ Ok(result) => {}
+ Err(err) => {
+ let exception = deno_core::error::to_v8_error(
+ scope,
+ op_state.get_error_class_fn,
+ &err,
+ );
+ scope.throw_exception(exception);
+ }
+ };
+ }
+}
+struct op_set_nodelay_fast {
+ _phantom: ::std::marker::PhantomData<()>,
+}
+impl<'scope> deno_core::v8::fast_api::FastFunction for op_set_nodelay_fast {
+ fn function(&self) -> *const ::std::ffi::c_void {
+ op_set_nodelay_fast_fn as *const ::std::ffi::c_void
+ }
+ fn args(&self) -> &'static [deno_core::v8::fast_api::Type] {
+ use deno_core::v8::fast_api::Type::*;
+ use deno_core::v8::fast_api::CType;
+ &[V8Value, Uint32, Bool, CallbackOptions]
+ }
+ fn return_type(&self) -> deno_core::v8::fast_api::CType {
+ deno_core::v8::fast_api::CType::Void
+ }
+}
+fn op_set_nodelay_fast_fn<'scope>(
+ _: deno_core::v8::Local<deno_core::v8::Object>,
+ rid: ResourceId,
+ nodelay: bool,
+ fast_api_callback_options: *mut deno_core::v8::fast_api::FastApiCallbackOptions,
+) -> () {
+ use deno_core::v8;
+ use deno_core::_ops;
+ let __opts: &mut v8::fast_api::FastApiCallbackOptions = unsafe {
+ &mut *fast_api_callback_options
+ };
+ let __ctx = unsafe {
+ &*(v8::Local::<v8::External>::cast(unsafe { __opts.data.data }).value()
+ as *const _ops::OpCtx)
+ };
+ let state = &mut ::std::cell::RefCell::borrow_mut(&__ctx.state);
+ let result = op_set_nodelay::call(state, rid, nodelay);
+ match result {
+ Ok(result) => result,
+ Err(err) => {
+ state.last_fast_op_error.replace(err);
+ __opts.fallback = true;
+ Default::default()
+ }
+ }
+}
diff --git a/ops/optimizer_tests/unit_result2.rs b/ops/optimizer_tests/unit_result2.rs
new file mode 100644
index 000000000..d3e8ced6a
--- /dev/null
+++ b/ops/optimizer_tests/unit_result2.rs
@@ -0,0 +1,10 @@
+pub fn op_set_nodelay(
+ state: &mut OpState,
+ rid: ResourceId,
+ nodelay: bool,
+) -> Result<(), AnyError> {
+ super::check_unstable(state, "Deno.Conn#setNoDelay");
+ let resource: Rc<TcpStreamResource> =
+ state.resource_table.get::<TcpStreamResource>(rid)?;
+ resource.set_nodelay(nodelay)
+}
diff --git a/ops/optimizer_tests/unit_ret.expected b/ops/optimizer_tests/unit_ret.expected
new file mode 100644
index 000000000..5d414e1e3
--- /dev/null
+++ b/ops/optimizer_tests/unit_ret.expected
@@ -0,0 +1,11 @@
+=== Optimizer Dump ===
+returns_result: false
+has_ref_opstate: false
+has_rc_opstate: false
+has_fast_callback_option: false
+needs_fast_callback_option: false
+fast_result: Some(Void)
+fast_parameters: [V8Value]
+transforms: {}
+is_async: false
+fast_compatible: true
diff --git a/ops/optimizer_tests/unit_ret.out b/ops/optimizer_tests/unit_ret.out
new file mode 100644
index 000000000..c18fa1915
--- /dev/null
+++ b/ops/optimizer_tests/unit_ret.out
@@ -0,0 +1,84 @@
+#[allow(non_camel_case_types)]
+///Auto-generated by `deno_ops`, i.e: `#[op]`
+///
+///Use `op_unit::decl()` to get an op-declaration
+///you can include in a `deno_core::Extension`.
+pub struct op_unit;
+#[doc(hidden)]
+impl op_unit {
+ pub fn name() -> &'static str {
+ stringify!(op_unit)
+ }
+ pub fn v8_fn_ptr<'scope>() -> deno_core::v8::FunctionCallback {
+ use deno_core::v8::MapFnTo;
+ Self::v8_func.map_fn_to()
+ }
+ pub fn decl<'scope>() -> deno_core::OpDecl {
+ deno_core::OpDecl {
+ name: Self::name(),
+ v8_fn_ptr: Self::v8_fn_ptr(),
+ enabled: true,
+ fast_fn: Some(
+ Box::new(op_unit_fast {
+ _phantom: ::std::marker::PhantomData,
+ }),
+ ),
+ is_async: false,
+ is_unstable: false,
+ is_v8: false,
+ argc: 0usize,
+ }
+ }
+ #[inline]
+ #[allow(clippy::too_many_arguments)]
+ fn call() -> () {
+ ()
+ }
+ pub fn v8_func<'scope>(
+ scope: &mut deno_core::v8::HandleScope<'scope>,
+ args: deno_core::v8::FunctionCallbackArguments,
+ mut rv: deno_core::v8::ReturnValue,
+ ) {
+ let ctx = unsafe {
+ &*(deno_core::v8::Local::<deno_core::v8::External>::cast(args.data()).value()
+ as *const deno_core::_ops::OpCtx)
+ };
+ let result = Self::call();
+ let op_state = ::std::cell::RefCell::borrow(&*ctx.state);
+ op_state.tracker.track_sync(ctx.id);
+ match deno_core::serde_v8::to_v8(scope, result) {
+ Ok(ret) => rv.set(ret),
+ Err(err) => {
+ deno_core::_ops::throw_type_error(
+ scope,
+ format!(
+ "Error serializing return: {}",
+ deno_core::anyhow::Error::from(err)
+ ),
+ )
+ }
+ };
+ }
+}
+struct op_unit_fast {
+ _phantom: ::std::marker::PhantomData<()>,
+}
+impl<'scope> deno_core::v8::fast_api::FastFunction for op_unit_fast {
+ fn function(&self) -> *const ::std::ffi::c_void {
+ op_unit_fast_fn as *const ::std::ffi::c_void
+ }
+ fn args(&self) -> &'static [deno_core::v8::fast_api::Type] {
+ use deno_core::v8::fast_api::Type::*;
+ use deno_core::v8::fast_api::CType;
+ &[V8Value]
+ }
+ fn return_type(&self) -> deno_core::v8::fast_api::CType {
+ deno_core::v8::fast_api::CType::Void
+ }
+}
+fn op_unit_fast_fn<'scope>(_: deno_core::v8::Local<deno_core::v8::Object>) -> () {
+ use deno_core::v8;
+ use deno_core::_ops;
+ let result = op_unit::call();
+ result
+}
diff --git a/ops/optimizer_tests/unit_ret.rs b/ops/optimizer_tests/unit_ret.rs
new file mode 100644
index 000000000..4cf3651db
--- /dev/null
+++ b/ops/optimizer_tests/unit_ret.rs
@@ -0,0 +1,3 @@
+fn op_unit() -> () {
+ ()
+}