mirror of
https://github.com/denoland/deno.git
synced 2024-11-24 15:19:26 -05:00
perf(ops): Reenable fast unit result optimization (#16827)
The optimization was missed in the optimizer rewrite https://github.com/denoland/deno/pull/16514
This commit is contained in:
parent
0012484f4f
commit
9ffc6acdbb
35 changed files with 844 additions and 32 deletions
|
@ -67,8 +67,8 @@ pub fn init<P: NetPermissions + 'static>() -> Vec<OpDecl> {
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
crate::ops_unix::op_net_send_unixpacket::decl::<P>(),
|
crate::ops_unix::op_net_send_unixpacket::decl::<P>(),
|
||||||
op_dns_resolve::decl::<P>(),
|
op_dns_resolve::decl::<P>(),
|
||||||
op_set_nodelay::decl::<P>(),
|
op_set_nodelay::decl(),
|
||||||
op_set_keepalive::decl::<P>(),
|
op_set_keepalive::decl(),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -509,7 +509,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op]
|
#[op]
|
||||||
pub fn op_set_nodelay<NP>(
|
pub fn op_set_nodelay(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
rid: ResourceId,
|
rid: ResourceId,
|
||||||
nodelay: bool,
|
nodelay: bool,
|
||||||
|
@ -521,7 +521,7 @@ pub fn op_set_nodelay<NP>(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op]
|
#[op]
|
||||||
pub fn op_set_keepalive<NP>(
|
pub fn op_set_keepalive(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
rid: ResourceId,
|
rid: ResourceId,
|
||||||
keepalive: bool,
|
keepalive: bool,
|
||||||
|
@ -836,7 +836,7 @@ mod tests {
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
async fn tcp_set_no_delay() {
|
async fn tcp_set_no_delay() {
|
||||||
let set_nodelay = Box::new(|state: &mut OpState, rid| {
|
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| {
|
let test_fn = Box::new(|socket: SockRef| {
|
||||||
assert!(socket.nodelay().unwrap());
|
assert!(socket.nodelay().unwrap());
|
||||||
|
@ -848,7 +848,7 @@ mod tests {
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||||
async fn tcp_set_keepalive() {
|
async fn tcp_set_keepalive() {
|
||||||
let set_keepalive = Box::new(|state: &mut OpState, rid| {
|
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| {
|
let test_fn = Box::new(|socket: SockRef| {
|
||||||
assert!(!socket.nodelay().unwrap());
|
assert!(!socket.nodelay().unwrap());
|
||||||
|
|
|
@ -141,10 +141,19 @@ pub(crate) fn generate(
|
||||||
if optimizer.has_fast_callback_option
|
if optimizer.has_fast_callback_option
|
||||||
|| optimizer.needs_opstate()
|
|| optimizer.needs_opstate()
|
||||||
|| optimizer.is_async
|
|| 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
|
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 }));
|
input_variants.push(q!({ CallbackOptions }));
|
||||||
}
|
}
|
||||||
|
@ -162,14 +171,10 @@ pub(crate) fn generate(
|
||||||
|
|
||||||
let mut output_transforms = q!({});
|
let mut output_transforms = q!({});
|
||||||
|
|
||||||
if optimizer.needs_opstate() || optimizer.is_async {
|
if optimizer.needs_opstate()
|
||||||
// Grab the op_state identifier, the first one. ¯\_(ツ)_/¯
|
|| optimizer.is_async
|
||||||
let op_state = match idents.first() {
|
|| optimizer.has_fast_callback_option
|
||||||
Some(ident) if optimizer.has_opstate_in_parameters() => ident.clone(),
|
{
|
||||||
// fn op_foo() -> Result<...>
|
|
||||||
_ => Ident::new("op_state", Span::call_site()),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Dark arts 🪄 ✨
|
// Dark arts 🪄 ✨
|
||||||
//
|
//
|
||||||
// - V8 calling convention guarantees that the callback options pointer is non-null.
|
// - V8 calling convention guarantees that the callback options pointer is non-null.
|
||||||
|
@ -179,13 +184,27 @@ pub(crate) fn generate(
|
||||||
let prelude = q!({
|
let prelude = q!({
|
||||||
let __opts: &mut v8::fast_api::FastApiCallbackOptions =
|
let __opts: &mut v8::fast_api::FastApiCallbackOptions =
|
||||||
unsafe { &mut *fast_api_callback_options };
|
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 {
|
let __ctx = unsafe {
|
||||||
&*(v8::Local::<v8::External>::cast(unsafe { __opts.data.data }).value()
|
&*(v8::Local::<v8::External>::cast(unsafe { __opts.data.data }).value()
|
||||||
as *const _ops::OpCtx)
|
as *const _ops::OpCtx)
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
pre_transforms.push_tokens(&prelude);
|
pre_transforms.push_tokens(&ctx);
|
||||||
pre_transforms.push_tokens(&match optimizer.is_async {
|
pre_transforms.push_tokens(&match optimizer.is_async {
|
||||||
false => q!(
|
false => q!(
|
||||||
Vars {
|
Vars {
|
||||||
|
|
|
@ -76,10 +76,11 @@ impl Op {
|
||||||
fn gen(mut self) -> TokenStream2 {
|
fn gen(mut self) -> TokenStream2 {
|
||||||
let mut optimizer = Optimizer::new();
|
let mut optimizer = Optimizer::new();
|
||||||
match optimizer.analyze(&mut self) {
|
match optimizer.analyze(&mut self) {
|
||||||
Ok(_) | Err(BailoutReason::MustBeSingleSegment) => {}
|
Err(BailoutReason::MustBeSingleSegment)
|
||||||
Err(BailoutReason::FastUnsupportedParamType) => {
|
| Err(BailoutReason::FastUnsupportedParamType) => {
|
||||||
optimizer.fast_compatible = false;
|
optimizer.fast_compatible = false;
|
||||||
}
|
}
|
||||||
|
_ => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
let Self {
|
let Self {
|
||||||
|
|
|
@ -9,7 +9,7 @@ use syn::{
|
||||||
parse_quote, punctuated::Punctuated, token::Colon2,
|
parse_quote, punctuated::Punctuated, token::Colon2,
|
||||||
AngleBracketedGenericArguments, FnArg, GenericArgument, PatType, Path,
|
AngleBracketedGenericArguments, FnArg, GenericArgument, PatType, Path,
|
||||||
PathArguments, PathSegment, ReturnType, Signature, Type, TypePath, TypePtr,
|
PathArguments, PathSegment, ReturnType, Signature, Type, TypePath, TypePtr,
|
||||||
TypeReference, TypeSlice,
|
TypeReference, TypeSlice, TypeTuple,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -196,7 +196,10 @@ pub(crate) struct Optimizer {
|
||||||
|
|
||||||
pub(crate) has_rc_opstate: bool,
|
pub(crate) has_rc_opstate: bool,
|
||||||
|
|
||||||
|
// Do we need an explict FastApiCallbackOptions argument?
|
||||||
pub(crate) has_fast_callback_option: bool,
|
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_result: Option<FastValue>,
|
||||||
pub(crate) fast_parameters: Vec<FastValue>,
|
pub(crate) fast_parameters: Vec<FastValue>,
|
||||||
|
@ -218,6 +221,11 @@ impl Debug for Optimizer {
|
||||||
"has_fast_callback_option: {}",
|
"has_fast_callback_option: {}",
|
||||||
self.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_result: {:?}", self.fast_result)?;
|
||||||
writeln!(f, "fast_parameters: {:?}", self.fast_parameters)?;
|
writeln!(f, "fast_parameters: {:?}", self.fast_parameters)?;
|
||||||
writeln!(f, "transforms: {:?}", self.transforms)?;
|
writeln!(f, "transforms: {:?}", self.transforms)?;
|
||||||
|
@ -298,6 +306,9 @@ impl Optimizer {
|
||||||
|
|
||||||
fn analyze_return_type(&mut self, ty: &Type) -> Result<(), BailoutReason> {
|
fn analyze_return_type(&mut self, ty: &Type) -> Result<(), BailoutReason> {
|
||||||
match ty {
|
match ty {
|
||||||
|
Type::Tuple(TypeTuple { elems, .. }) if elems.is_empty() => {
|
||||||
|
self.fast_result = Some(FastValue::Void);
|
||||||
|
}
|
||||||
Type::Path(TypePath {
|
Type::Path(TypePath {
|
||||||
path: Path { segments, .. },
|
path: Path { segments, .. },
|
||||||
..
|
..
|
||||||
|
@ -333,6 +344,14 @@ impl Optimizer {
|
||||||
self.fast_compatible = false;
|
self.fast_compatible = false;
|
||||||
return Err(BailoutReason::FastUnsupportedParamType);
|
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),
|
_ => return Err(BailoutReason::FastUnsupportedParamType),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -407,15 +426,19 @@ impl Optimizer {
|
||||||
{
|
{
|
||||||
let segment = single_segment(segments)?;
|
let segment = single_segment(segments)?;
|
||||||
match segment {
|
match segment {
|
||||||
// Is `T` a FastApiCallbackOption?
|
// Is `T` a FastApiCallbackOptions?
|
||||||
PathSegment { ident, .. }
|
PathSegment { ident, .. }
|
||||||
if ident == "FastApiCallbackOption" =>
|
if ident == "FastApiCallbackOptions" =>
|
||||||
{
|
{
|
||||||
self.has_fast_callback_option = true;
|
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 {
|
match segment {
|
||||||
// Is `T` a u8?
|
// Is `T` a u8?
|
||||||
PathSegment { ident, .. } if ident == "u8" => {
|
PathSegment { ident, .. } if ident == "u8" => {
|
||||||
self.has_fast_callback_option = true;
|
self.needs_fast_callback_option = true;
|
||||||
self.fast_parameters.push(FastValue::Uint8Array);
|
self.fast_parameters.push(FastValue::Uint8Array);
|
||||||
assert!(self
|
assert!(self
|
||||||
.transforms
|
.transforms
|
||||||
|
@ -526,7 +549,7 @@ impl Optimizer {
|
||||||
}
|
}
|
||||||
// Is `T` a u32?
|
// Is `T` a u32?
|
||||||
PathSegment { ident, .. } if ident == "u32" => {
|
PathSegment { ident, .. } if ident == "u32" => {
|
||||||
self.has_fast_callback_option = true;
|
self.needs_fast_callback_option = true;
|
||||||
self.fast_parameters.push(FastValue::Uint32Array);
|
self.fast_parameters.push(FastValue::Uint32Array);
|
||||||
assert!(self
|
assert!(self
|
||||||
.transforms
|
.transforms
|
||||||
|
@ -554,7 +577,7 @@ impl Optimizer {
|
||||||
match segment {
|
match segment {
|
||||||
// Is `T` a u8?
|
// Is `T` a u8?
|
||||||
PathSegment { ident, .. } if ident == "u8" => {
|
PathSegment { ident, .. } if ident == "u8" => {
|
||||||
self.has_fast_callback_option = true;
|
self.needs_fast_callback_option = true;
|
||||||
self.fast_parameters.push(FastValue::Uint8Array);
|
self.fast_parameters.push(FastValue::Uint8Array);
|
||||||
assert!(self
|
assert!(self
|
||||||
.transforms
|
.transforms
|
||||||
|
|
|
@ -3,6 +3,7 @@ returns_result: false
|
||||||
has_ref_opstate: false
|
has_ref_opstate: false
|
||||||
has_rc_opstate: false
|
has_rc_opstate: false
|
||||||
has_fast_callback_option: false
|
has_fast_callback_option: false
|
||||||
|
needs_fast_callback_option: false
|
||||||
fast_result: Some(Void)
|
fast_result: Some(Void)
|
||||||
fast_parameters: [V8Value, I32]
|
fast_parameters: [V8Value, I32]
|
||||||
transforms: {}
|
transforms: {}
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
returns_result: true
|
returns_result: true
|
||||||
has_ref_opstate: false
|
has_ref_opstate: false
|
||||||
has_rc_opstate: true
|
has_rc_opstate: true
|
||||||
has_fast_callback_option: true
|
has_fast_callback_option: false
|
||||||
|
needs_fast_callback_option: true
|
||||||
fast_result: None
|
fast_result: None
|
||||||
fast_parameters: [V8Value, I32, U32, Uint8Array]
|
fast_parameters: [V8Value, I32, U32, Uint8Array]
|
||||||
transforms: {2: Transform { kind: SliceU8(true), index: 2 }}
|
transforms: {2: Transform { kind: SliceU8(true), index: 2 }}
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
returns_result: false
|
returns_result: false
|
||||||
has_ref_opstate: false
|
has_ref_opstate: false
|
||||||
has_rc_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_result: Some(Void)
|
||||||
fast_parameters: [V8Value]
|
fast_parameters: [V8Value]
|
||||||
transforms: {}
|
transforms: {}
|
||||||
|
|
|
@ -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] {
|
fn args(&self) -> &'static [deno_core::v8::fast_api::Type] {
|
||||||
use deno_core::v8::fast_api::Type::*;
|
use deno_core::v8::fast_api::Type::*;
|
||||||
use deno_core::v8::fast_api::CType;
|
use deno_core::v8::fast_api::CType;
|
||||||
&[V8Value]
|
&[V8Value, CallbackOptions]
|
||||||
}
|
}
|
||||||
fn return_type(&self) -> deno_core::v8::fast_api::CType {
|
fn return_type(&self) -> deno_core::v8::fast_api::CType {
|
||||||
deno_core::v8::fast_api::CType::Void
|
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>(
|
fn op_fallback_fast_fn<'scope>(
|
||||||
_: deno_core::v8::Local<deno_core::v8::Object>,
|
_: 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::v8;
|
||||||
use deno_core::_ops;
|
use deno_core::_ops;
|
||||||
|
let __opts: &mut v8::fast_api::FastApiCallbackOptions = unsafe {
|
||||||
|
&mut *fast_api_callback_options
|
||||||
|
};
|
||||||
let result = op_fallback::call(options);
|
let result = op_fallback::call(options);
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
1
ops/optimizer_tests/op_blob_revoke_object_url.expected
Normal file
1
ops/optimizer_tests/op_blob_revoke_object_url.expected
Normal file
|
@ -0,0 +1 @@
|
||||||
|
MustBeSingleSegment
|
71
ops/optimizer_tests/op_blob_revoke_object_url.out
Normal file
71
ops/optimizer_tests/op_blob_revoke_object_url.out
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
9
ops/optimizer_tests/op_blob_revoke_object_url.rs
Normal file
9
ops/optimizer_tests/op_blob_revoke_object_url.rs
Normal file
|
@ -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(())
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ returns_result: false
|
||||||
has_ref_opstate: true
|
has_ref_opstate: true
|
||||||
has_rc_opstate: false
|
has_rc_opstate: false
|
||||||
has_fast_callback_option: false
|
has_fast_callback_option: false
|
||||||
|
needs_fast_callback_option: false
|
||||||
fast_result: Some(Void)
|
fast_result: Some(Void)
|
||||||
fast_parameters: [V8Value, I32]
|
fast_parameters: [V8Value, I32]
|
||||||
transforms: {}
|
transforms: {}
|
||||||
|
|
|
@ -3,6 +3,7 @@ returns_result: false
|
||||||
has_ref_opstate: true
|
has_ref_opstate: true
|
||||||
has_rc_opstate: false
|
has_rc_opstate: false
|
||||||
has_fast_callback_option: false
|
has_fast_callback_option: false
|
||||||
|
needs_fast_callback_option: false
|
||||||
fast_result: Some(U32)
|
fast_result: Some(U32)
|
||||||
fast_parameters: [V8Value, U32, U32]
|
fast_parameters: [V8Value, U32, U32]
|
||||||
transforms: {}
|
transforms: {}
|
||||||
|
|
|
@ -3,6 +3,7 @@ returns_result: false
|
||||||
has_ref_opstate: true
|
has_ref_opstate: true
|
||||||
has_rc_opstate: false
|
has_rc_opstate: false
|
||||||
has_fast_callback_option: false
|
has_fast_callback_option: false
|
||||||
|
needs_fast_callback_option: false
|
||||||
fast_result: Some(Void)
|
fast_result: Some(Void)
|
||||||
fast_parameters: [V8Value]
|
fast_parameters: [V8Value]
|
||||||
transforms: {}
|
transforms: {}
|
||||||
|
|
|
@ -3,6 +3,7 @@ returns_result: true
|
||||||
has_ref_opstate: true
|
has_ref_opstate: true
|
||||||
has_rc_opstate: false
|
has_rc_opstate: false
|
||||||
has_fast_callback_option: false
|
has_fast_callback_option: false
|
||||||
|
needs_fast_callback_option: false
|
||||||
fast_result: Some(U32)
|
fast_result: Some(U32)
|
||||||
fast_parameters: [V8Value, U32, U32]
|
fast_parameters: [V8Value, U32, U32]
|
||||||
transforms: {}
|
transforms: {}
|
||||||
|
|
|
@ -3,6 +3,7 @@ returns_result: true
|
||||||
has_ref_opstate: true
|
has_ref_opstate: true
|
||||||
has_rc_opstate: false
|
has_rc_opstate: false
|
||||||
has_fast_callback_option: false
|
has_fast_callback_option: false
|
||||||
|
needs_fast_callback_option: false
|
||||||
fast_result: Some(U32)
|
fast_result: Some(U32)
|
||||||
fast_parameters: [V8Value]
|
fast_parameters: [V8Value]
|
||||||
transforms: {}
|
transforms: {}
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
returns_result: false
|
returns_result: false
|
||||||
has_ref_opstate: true
|
has_ref_opstate: true
|
||||||
has_rc_opstate: false
|
has_rc_opstate: false
|
||||||
has_fast_callback_option: true
|
has_fast_callback_option: false
|
||||||
|
needs_fast_callback_option: true
|
||||||
fast_result: Some(Void)
|
fast_result: Some(Void)
|
||||||
fast_parameters: [V8Value, Uint8Array]
|
fast_parameters: [V8Value, Uint8Array]
|
||||||
transforms: {1: Transform { kind: SliceU8(true), index: 1 }}
|
transforms: {1: Transform { kind: SliceU8(true), index: 1 }}
|
||||||
|
|
|
@ -3,6 +3,7 @@ returns_result: true
|
||||||
has_ref_opstate: false
|
has_ref_opstate: false
|
||||||
has_rc_opstate: false
|
has_rc_opstate: false
|
||||||
has_fast_callback_option: false
|
has_fast_callback_option: false
|
||||||
|
needs_fast_callback_option: false
|
||||||
fast_result: Some(U32)
|
fast_result: Some(U32)
|
||||||
fast_parameters: [V8Value, U32, U32, U32, U32]
|
fast_parameters: [V8Value, U32, U32, U32, U32]
|
||||||
transforms: {}
|
transforms: {}
|
||||||
|
|
1
ops/optimizer_tests/option_arg.expected
Normal file
1
ops/optimizer_tests/option_arg.expected
Normal file
|
@ -0,0 +1 @@
|
||||||
|
FastUnsupportedParamType
|
66
ops/optimizer_tests/option_arg.out
Normal file
66
ops/optimizer_tests/option_arg.out
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
6
ops/optimizer_tests/option_arg.rs
Normal file
6
ops/optimizer_tests/option_arg.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
pub fn op_try_close(
|
||||||
|
state: &mut OpState,
|
||||||
|
rid: Option<ResourceId>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
// ...
|
||||||
|
}
|
|
@ -2,7 +2,8 @@
|
||||||
returns_result: false
|
returns_result: false
|
||||||
has_ref_opstate: true
|
has_ref_opstate: true
|
||||||
has_rc_opstate: false
|
has_rc_opstate: false
|
||||||
has_fast_callback_option: true
|
has_fast_callback_option: false
|
||||||
|
needs_fast_callback_option: true
|
||||||
fast_result: Some(Void)
|
fast_result: Some(Void)
|
||||||
fast_parameters: [V8Value, Uint8Array, Uint32Array]
|
fast_parameters: [V8Value, Uint8Array, Uint32Array]
|
||||||
transforms: {1: Transform { kind: PtrU8, index: 1 }, 2: Transform { kind: SliceU32(true), index: 2 }}
|
transforms: {1: Transform { kind: PtrU8, index: 1 }, 2: Transform { kind: SliceU32(true), index: 2 }}
|
||||||
|
|
|
@ -3,6 +3,7 @@ returns_result: false
|
||||||
has_ref_opstate: false
|
has_ref_opstate: false
|
||||||
has_rc_opstate: false
|
has_rc_opstate: false
|
||||||
has_fast_callback_option: false
|
has_fast_callback_option: false
|
||||||
|
needs_fast_callback_option: false
|
||||||
fast_result: Some(Bool)
|
fast_result: Some(Bool)
|
||||||
fast_parameters: [V8Value, V8Value]
|
fast_parameters: [V8Value, V8Value]
|
||||||
transforms: {0: Transform { kind: V8Value, index: 0 }}
|
transforms: {0: Transform { kind: V8Value, index: 0 }}
|
||||||
|
|
11
ops/optimizer_tests/uint8array.expected
Normal file
11
ops/optimizer_tests/uint8array.expected
Normal file
|
@ -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
|
191
ops/optimizer_tests/uint8array.out
Normal file
191
ops/optimizer_tests/uint8array.out
Normal file
|
@ -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
|
||||||
|
}
|
3
ops/optimizer_tests/uint8array.rs
Normal file
3
ops/optimizer_tests/uint8array.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
pub fn op_import_spki_x25519(key_data: &[u8], out: &mut [u8]) -> bool {
|
||||||
|
// ...
|
||||||
|
}
|
11
ops/optimizer_tests/unit_result.expected
Normal file
11
ops/optimizer_tests/unit_result.expected
Normal file
|
@ -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
|
113
ops/optimizer_tests/unit_result.out
Normal file
113
ops/optimizer_tests/unit_result.out
Normal file
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
ops/optimizer_tests/unit_result.rs
Normal file
3
ops/optimizer_tests/unit_result.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fn op_unit_result() -> Result<(), AnyError> {
|
||||||
|
Ok(())
|
||||||
|
}
|
11
ops/optimizer_tests/unit_result2.expected
Normal file
11
ops/optimizer_tests/unit_result2.expected
Normal file
|
@ -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
|
149
ops/optimizer_tests/unit_result2.out
Normal file
149
ops/optimizer_tests/unit_result2.out
Normal file
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10
ops/optimizer_tests/unit_result2.rs
Normal file
10
ops/optimizer_tests/unit_result2.rs
Normal file
|
@ -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)
|
||||||
|
}
|
11
ops/optimizer_tests/unit_ret.expected
Normal file
11
ops/optimizer_tests/unit_ret.expected
Normal file
|
@ -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
|
84
ops/optimizer_tests/unit_ret.out
Normal file
84
ops/optimizer_tests/unit_ret.out
Normal file
|
@ -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
|
||||||
|
}
|
3
ops/optimizer_tests/unit_ret.rs
Normal file
3
ops/optimizer_tests/unit_ret.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fn op_unit() -> () {
|
||||||
|
()
|
||||||
|
}
|
Loading…
Reference in a new issue