Skip to content

Commit

Permalink
Use const fn for op declaration (#685)
Browse files Browse the repository at this point in the history
Switch op declaration from a `impl #name` to a `const fn #name`. 
This form for declaration can be used inside `impl` blocks.

```rust
struct Foo {}

impl Foo {
    #[op2(fast)]
    pub fn bar(#[state] state: &mut OpState) {}
}

// const DECL: OpDecl = Foo::bar();
```

Based on Matt's suggestion in
#682

[Playground
link](https://play.rust-lang.org/?version=stable&mode=release&edition=2021&gist=2d7152d548b4a466779c401551b21b05)

This patch wraps `const` around the existing
`impl` codegen to unblock work on op2++
  • Loading branch information
littledivy committed Apr 6, 2024
1 parent 742afe5 commit 5245f5d
Show file tree
Hide file tree
Showing 54 changed files with 8,757 additions and 8,374 deletions.
3 changes: 2 additions & 1 deletion core/examples/hello_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ fn op_sum(#[serde] nums: Vec<f64>) -> Result<f64, deno_core::error::AnyError> {

fn main() {
// Build a deno_core::Extension providing custom ops
const DECL: OpDecl = op_sum();
let ext = Extension {
name: "my_ext",
ops: std::borrow::Cow::Borrowed(&[op_sum::DECL]),
ops: std::borrow::Cow::Borrowed(&[DECL]),
..Default::default()
};

Expand Down
11 changes: 6 additions & 5 deletions core/extensions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ macro_rules! ops {
vec![
$(
$( #[ $m ] )*
$( $op )::+ :: decl $( :: <$op_param> )? () ,
$( $op )+ $( :: <$op_param> )? () ,
)+
]
}
Expand All @@ -331,7 +331,7 @@ macro_rules! ops {
pub(crate) fn $name() -> ::std::Vec<$crate::OpDecl> {
use $crate::Op;
vec![
$( $( #[ $m ] )* $( $op )::+ :: DECL, )+
$( $( #[ $m ] )* $( $op )+() , )+
]
}
}
Expand Down Expand Up @@ -450,10 +450,11 @@ macro_rules! extension {
const V: ::std::option::Option<&'static ::std::primitive::str> = $crate::or!($(::std::option::Option::Some($esm_entry_point))?, ::std::option::Option::None);
V
},
ops: ::std::borrow::Cow::Borrowed(&[$($(
ops: ::std::borrow::Cow::Borrowed(&[$($({
$( #[ $m ] )*
$( $op )::+ $( :: < $($op_param),* > )? :: DECL
),+)?]),
const DECL: $crate::OpDecl = $( $op )::+ $( :: < $($op_param),* > )? ();
DECL
}),+)?]),
external_references: ::std::borrow::Cow::Borrowed(&[ $( $external_reference ),* ]),
global_template_middleware: ::std::option::Option::None,
global_object_middleware: ::std::option::Option::None,
Expand Down
3 changes: 1 addition & 2 deletions core/ops_builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use crate::ops_builtin_types;
use crate::ops_builtin_v8;
use crate::CancelHandle;
use crate::JsBuffer;
use crate::Op;
use crate::OpDecl;
use crate::OpState;
use crate::Resource;
Expand All @@ -26,7 +25,7 @@ use std::rc::Rc;
macro_rules! builtin_ops {
( $($op:ident $(:: $sub:ident)*),* ) => {
pub const BUILTIN_OPS: &'static [OpDecl] = &[
$( $op $(:: $sub)*::DECL, )*
$( $op $(:: $sub) * () ),*
];
}
}
Expand Down
3 changes: 1 addition & 2 deletions core/runtime/tests/ops.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use crate::error::AnyError;
use crate::extensions::Op;
use crate::extensions::OpDecl;
use crate::modules::StaticModuleLoader;
use crate::runtime::tests::setup;
Expand Down Expand Up @@ -196,7 +195,7 @@ fn test_op_disabled() {
}

fn ops() -> Vec<OpDecl> {
vec![op_foo::DECL.disable()]
vec![op_foo().disable()]
}

deno_core::extension!(test_ext, ops_fn = ops);
Expand Down
9 changes: 4 additions & 5 deletions core/runtime/tests/snapshot.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use crate::extensions::Op;
use crate::modules::ModuleInfo;
use crate::modules::RequestedModuleType;
use crate::runtime::NO_OF_BUILTIN_MODULES;
Expand Down Expand Up @@ -236,11 +235,10 @@ fn es_snapshot() {
fn op_test() -> Result<String, Error> {
Ok(String::from("test"))
}

let mut runtime = JsRuntimeForSnapshot::new(RuntimeOptions {
extensions: vec![Extension {
name: "test_ext",
ops: Cow::Borrowed(&[op_test::DECL]),
ops: Cow::Borrowed(&[DECL]),
..Default::default()
}],
..Default::default()
Expand Down Expand Up @@ -278,7 +276,7 @@ fn es_snapshot() {
startup_snapshot: Some(snapshot),
extensions: vec![Extension {
name: "test_ext",
ops: Cow::Borrowed(&[op_test::DECL]),
ops: Cow::Borrowed(&[DECL]),
..Default::default()
}],
..Default::default()
Expand All @@ -294,11 +292,12 @@ fn es_snapshot() {
let snapshot2 = runtime2.snapshot();
let snapshot2 = Box::leak(snapshot2);

const DECL: OpDecl = op_test();
let mut runtime3 = JsRuntime::new(RuntimeOptions {
startup_snapshot: Some(snapshot2),
extensions: vec![Extension {
name: "test_ext",
ops: Cow::Borrowed(&[op_test::DECL]),
ops: Cow::Borrowed(&[DECL]),
..Default::default()
}],
..Default::default()
Expand Down
4 changes: 2 additions & 2 deletions ops/op2/dispatch_fast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -375,8 +375,8 @@ pub(crate) fn generate_dispatch_fast(
let alternative =
syn::parse_str::<Type>(alternative).expect("Failed to reparse type");
return Ok(Some((
quote!(#alternative::DECL.fast_fn()),
quote!(#alternative::DECL.fast_fn_with_metrics()),
quote!(#alternative().fast_fn()),
quote!(#alternative().fast_fn_with_metrics()),
quote!(),
)));
}
Expand Down
70 changes: 35 additions & 35 deletions ops/op2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,46 +244,46 @@ fn generate_op2(

Ok(quote! {
#[allow(non_camel_case_types)]
#(#attrs)*
#vis struct #name <#(#generic),*> {
// We need to mark these type parameters as used, so we use a PhantomData
_unconstructable: ::std::marker::PhantomData<(#(#generic),*)>
}

impl <#(#generic : #bound),*> ::deno_core::_ops::Op for #name <#(#generic),*> {
const NAME: &'static str = stringify!(#name);
const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
/*name*/ ::deno_core::__op_name_fast!(#name),
/*is_async*/ #is_async,
/*is_reentrant*/ #is_reentrant,
/*arg_count*/ #arg_count as u8,
/*slow_fn*/ Self::#slow_function as _,
/*slow_fn_metrics*/ Self::#slow_function_metrics as _,
/*fast_fn*/ #fast_definition,
/*fast_fn_metrics*/ #fast_definition_metrics,
/*metadata*/ ::deno_core::OpMetadata {
#(#meta_key: Some(#meta_value),)*
..::deno_core::OpMetadata::default()
},
);
}

impl <#(#generic : #bound),*> #name <#(#generic),*> {
pub const fn name() -> &'static str {
stringify!(#name)
#vis const fn #name <#(#generic : #bound),*> () -> ::deno_core::_ops::OpDecl {
#[allow(non_camel_case_types)]
#(#attrs)*
#vis struct #name <#(#generic),*> {
// We need to mark these type parameters as used, so we use a PhantomData
_unconstructable: ::std::marker::PhantomData<(#(#generic),*)>
}

#[deprecated(note = "Use the const op::DECL instead")]
pub const fn decl() -> deno_core::_ops::OpDecl {
<Self as deno_core::_ops::Op>::DECL
impl <#(#generic : #bound),*> ::deno_core::_ops::Op for #name <#(#generic),*> {
const NAME: &'static str = stringify!(#name);
const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
/*name*/ ::deno_core::__op_name_fast!(#name),
/*is_async*/ #is_async,
/*is_reentrant*/ #is_reentrant,
/*arg_count*/ #arg_count as u8,
/*slow_fn*/ Self::#slow_function as _,
/*slow_fn_metrics*/ Self::#slow_function_metrics as _,
/*fast_fn*/ #fast_definition,
/*fast_fn_metrics*/ #fast_definition_metrics,
/*metadata*/ ::deno_core::OpMetadata {
#(#meta_key: Some(#meta_value),)*
..::deno_core::OpMetadata::default()
},
);
}

#fast_fn
#slow_fn
impl <#(#generic : #bound),*> #name <#(#generic),*> {
pub const fn name() -> &'static str {
stringify!(#name)
}

#[inline(always)]
#(#attrs)*
#op_fn
#fast_fn
#slow_fn

#[inline(always)]
#(#attrs)*
#op_fn
}

<#name <#(#generic),*> as ::deno_core::_ops::Op>::DECL
}
})
}
Expand Down

0 comments on commit 5245f5d

Please sign in to comment.