Repository: denoland/deno_core
Pull request #971 (2024-11-19 20:05:22)

Revert "refactor: rename op2 to op"
Reverts denoland/deno_core#967
To reland at another time


Patch:
diff --git a/core/benches/ops/async.rs b/core/benches/ops/async.rs
index 83a7b39..a72da53 100644
--- a/core/benches/ops/async.rs
+++ b/core/benches/ops/async.rs
@@ -26,13 +26,13 @@ deno_core::extension!(
   ],
 );
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_call_promise_resolver(scope: &mut v8::HandleScope, f: &v8::Function) {
   let recv = v8::undefined(scope).into();
   f.call(scope, recv, &[]);
 }
 
-#[op]
+#[op2]
 pub fn op_resolve_promise<'s>(
   scope: &'s mut v8::HandleScope,
 ) -> v8::Local<'s, v8::Promise> {
@@ -42,57 +42,57 @@ pub fn op_resolve_promise<'s>(
   resolver.get_promise(scope)
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_void() {}
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_make_external() -> *const c_void {
   std::ptr::null()
 }
 
-#[op(async)]
+#[op2(async)]
 pub async fn op_async_void() {}
 
-#[op(async)]
+#[op2(async)]
 pub async fn op_async_yield() {
   tokio::task::yield_now().await
 }
 
-#[op(async(lazy), fast)]
+#[op2(async(lazy), fast)]
 pub async fn op_async_yield_lazy() {
   tokio::task::yield_now().await
 }
 
-#[op(async(lazy), nofast)]
+#[op2(async(lazy), nofast)]
 pub async fn op_async_yield_lazy_nofast() {
   tokio::task::yield_now().await
 }
 
-#[op(async(deferred), fast)]
+#[op2(async(deferred), fast)]
 pub async fn op_async_yield_deferred() {
   tokio::task::yield_now().await
 }
 
-#[op(async(deferred), nofast)]
+#[op2(async(deferred), nofast)]
 pub async fn op_async_yield_deferred_nofast() {
   tokio::task::yield_now().await
 }
 
-#[op(async(lazy), fast)]
+#[op2(async(lazy), fast)]
 pub async fn op_async_void_lazy() {}
 
-#[op(async(lazy), nofast)]
+#[op2(async(lazy), nofast)]
 pub async fn op_async_void_lazy_nofast() {}
 
-#[op(async(deferred), fast)]
+#[op2(async(deferred), fast)]
 pub async fn op_async_void_deferred_return() -> u32 {
   1
 }
 
-#[op(async(deferred), fast)]
+#[op2(async(deferred), fast)]
 pub async fn op_async_void_deferred() {}
 
-#[op(async(deferred), nofast)]
+#[op2(async(deferred), nofast)]
 pub async fn op_async_void_deferred_nofast() {}
 
 fn bench_op(
diff --git a/core/benches/ops/sync.rs b/core/benches/ops/sync.rs
index f0177ef..1c64051 100644
--- a/core/benches/ops/sync.rs
+++ b/core/benches/ops/sync.rs
@@ -45,115 +45,115 @@ deno_core::extension!(
   }
 );
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_void() {}
 
-#[op(fast, no_side_effects)]
+#[op2(fast, no_side_effects)]
 pub fn op_void_no_side_effects() {}
 
-#[op(nofast)]
+#[op2(nofast)]
 pub fn op_void_nofast() {}
 
-#[op(no_side_effects, nofast)]
+#[op2(no_side_effects, nofast)]
 pub fn op_void_nofast_no_side_effects() {}
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_void_metrics() {}
 
-#[op(nofast)]
+#[op2(nofast)]
 pub fn op_void_nofast_metrics() {}
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_u32() -> u32 {
   1
 }
 
-#[op]
+#[op2]
 pub fn op_option_u32() -> Option<u32> {
   Some(1)
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_string(#[string] s: &str) -> u32 {
   s.len() as _
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_string_onebyte(#[string(onebyte)] s: Cow<[u8]>) -> u32 {
   s.len() as _
 }
 
-#[op]
+#[op2]
 pub fn op_string_bytestring(#[serde] s: ByteString) -> u32 {
   s.len() as _
 }
 
-#[op(no_side_effects)]
+#[op2(no_side_effects)]
 pub fn op_string_bytestring_no_side_effects(#[serde] s: ByteString) -> u32 {
   s.len() as _
 }
 
-#[op]
+#[op2]
 pub fn op_string_option_u32(#[string] s: &str) -> Option<u32> {
   Some(s.len() as _)
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_local(_s: v8::Local<v8::String>) {}
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_local_scope(_scope: &mut v8::HandleScope, _s: v8::Local<v8::String>) {
 }
 
-#[op(nofast)]
+#[op2(nofast)]
 pub fn op_local_nofast(_s: v8::Local<v8::String>) {}
 
-#[op]
+#[op2]
 pub fn op_global(#[global] _s: v8::Global<v8::String>) {}
 
-#[op]
+#[op2]
 pub fn op_global_scope(
   _scope: &mut v8::HandleScope,
   #[global] _s: v8::Global<v8::String>,
 ) {
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_scope(_scope: &mut v8::HandleScope) {}
 
-#[op(nofast)]
+#[op2(nofast)]
 pub fn op_isolate_nofast(_isolate: *mut v8::Isolate) {}
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_make_external() -> *const c_void {
   std::ptr::null()
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_bigint(#[bigint] _input: u64) {}
 
-#[op(fast)]
+#[op2(fast)]
 #[bigint]
 pub fn op_bigint_return() -> u64 {
   0
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_external(_input: *const c_void) {}
 
-#[op(nofast)]
+#[op2(nofast)]
 pub fn op_external_nofast(_input: *const c_void) {}
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_buffer(#[buffer] _buffer: &[u8]) {}
 
-#[op]
+#[op2]
 pub fn op_buffer_jsbuffer(#[buffer] _buffer: JsBuffer) {}
 
-#[op(nofast)]
+#[op2(nofast)]
 pub fn op_buffer_nofast(#[buffer] _buffer: &[u8]) {}
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_arraybuffer(#[arraybuffer] _buffer: &[u8]) {}
 
 fn bench_op(
diff --git a/core/benches/snapshot/snapshot.rs b/core/benches/snapshot/snapshot.rs
index fb75374..7e0b019 100644
--- a/core/benches/snapshot/snapshot.rs
+++ b/core/benches/snapshot/snapshot.rs
@@ -29,7 +29,7 @@ macro_rules! fake_extensions {
           );
 
           mod ops {
-            #[deno_core::op(fast)]
+            #[deno_core::op2(fast)]
             pub fn $name() {
             }
           }
diff --git a/core/convert.rs b/core/convert.rs
index 694fcc8..067d2c4 100644
--- a/core/convert.rs
+++ b/core/convert.rs
@@ -9,11 +9,11 @@ use std::convert::Infallible;
 /// When passing data from Rust into JS, either
 /// via an op or by calling a JS function directly,
 /// you need to serialize the data into a native
-/// V8 value. When using the [`op`][deno_core::op] macro, the return
+/// V8 value. When using the [`op2`][deno_core::op2] macro, the return
 /// value is converted to a `v8::Local<Value>` automatically,
 /// and the strategy for conversion is controlled by attributes
 /// like `#[smi]`, `#[number]`, `#[string]`. For types with support
-/// built-in to the op macro, like primitives, strings, and buffers,
+/// built-in to the op2 macro, like primitives, strings, and buffers,
 /// these attributes are sufficient and you don't need to worry about this trait.
 ///
 /// If, however, you want to return a custom type from an op, or
@@ -21,14 +21,14 @@ use std::convert::Infallible;
 /// you can implement the `ToV8` trait. This allows you the
 /// choose the best serialization strategy for your specific use case.
 /// You can then use the `#[to_v8]` attribute to indicate
-/// that the `#[op]` macro should call your implementation for the conversion.
+/// that the `#[op2]` macro should call your implementation for the conversion.
 ///
 /// # Example
 ///
 /// ```ignore
 /// use deno_core::ToV8;
 /// use deno_core::convert::Smi;
-/// use deno_core::op;
+/// use deno_core::op2;
 ///
 /// struct Foo(i32);
 ///
@@ -44,8 +44,8 @@ use std::convert::Infallible;
 ///   }
 /// }
 ///
-/// // using the `#[to_v8]` attribute tells the `op` macro to call this implementation.
-/// #[op]
+/// // using the `#[to_v8]` attribute tells the `op2` macro to call this implementation.
+/// #[op2]
 /// #[to_v8]
 /// fn op_foo() -> Foo {
 ///   Foo(42)
@@ -80,7 +80,7 @@ pub trait ToV8<'a> {
 /// To convert these values into custom Rust types, you can implement the [`FromV8`] trait.
 ///
 /// Once you've implemented this trait, you can use the `#[from_v8]` attribute
-/// to tell the [`op`][deno_core::op] macro to use your implementation to convert the argument
+/// to tell the [`op2`][deno_core::op2] macro to use your implementation to convert the argument
 /// to the desired type.
 ///
 /// # Example
@@ -88,7 +88,7 @@ pub trait ToV8<'a> {
 /// ```ignore
 /// use deno_core::FromV8;
 /// use deno_core::convert::Smi;
-/// use deno_core::op;
+/// use deno_core::op2;
 ///
 /// struct Foo(i32);
 ///
@@ -103,8 +103,8 @@ pub trait ToV8<'a> {
 ///   }
 /// }
 ///
-/// // using the `#[from_v8]` attribute tells the `op` macro to call this implementation.
-/// #[op]
+/// // using the `#[from_v8]` attribute tells the `op2` macro to call this implementation.
+/// #[op2]
 /// fn op_foo(#[from_v8] foo: Foo) {
 ///   let Foo(_) = foo;
 /// }
@@ -122,7 +122,7 @@ pub trait FromV8<'a>: Sized {
 // impls
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
-/// Marks a numeric type as being serialized as a v8 `smi` in a `v8::Integer`.
+/// Marks a numeric type as being serialized as a v8 `smi` in a `v8::Integer`.  
 #[repr(transparent)]
 pub struct Smi<T: SmallInt>(pub T);
 
@@ -185,7 +185,7 @@ impl<'a, T: SmallInt> FromV8<'a> for Smi<T> {
 }
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
-/// Marks a numeric type as being serialized as a v8 `number` in a `v8::Number`.
+/// Marks a numeric type as being serialized as a v8 `number` in a `v8::Number`.  
 #[repr(transparent)]
 pub struct Number<T: Numeric>(pub T);
 
diff --git a/core/examples/hello_world.rs b/core/examples/hello_world.rs
index 44c8b70..6e99349 100644
--- a/core/examples/hello_world.rs
+++ b/core/examples/hello_world.rs
@@ -6,7 +6,7 @@ use deno_core::*;
 
 /// An op for summing an array of numbers. The op-layer automatically
 /// deserializes inputs and serializes the returned Result & value.
-#[op]
+#[op2]
 fn op_sum(#[serde] nums: Vec<f64>) -> Result<f64, deno_core::error::AnyError> {
   // Sum inputs
   let sum = nums.iter().fold(0.0, |a, v| a + v);
diff --git a/core/examples/op.js b/core/examples/op2.js
similarity index 83%
rename from core/examples/op.js
rename to core/examples/op2.js
index 74a7ef0..b59734a 100644
--- a/core/examples/op.js
+++ b/core/examples/op2.js
@@ -1,4 +1,4 @@
 // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
-globalThis.op_sample = {
+globalThis.op2_sample = {
   "use_state": (f) => Deno.core.ops.op_use_state(f),
 };
diff --git a/core/examples/op.rs b/core/examples/op2.rs
similarity index 81%
rename from core/examples/op.rs
rename to core/examples/op2.rs
index 725062d..d91d0a2 100644
--- a/core/examples/op.rs
+++ b/core/examples/op2.rs
@@ -4,7 +4,7 @@ use deno_core::anyhow::Error;
 use deno_core::*;
 use std::rc::Rc;
 
-#[op]
+#[op2]
 fn op_use_state(
   state: &mut OpState,
   #[global] callback: v8::Global<v8::Function>,
@@ -14,17 +14,17 @@ fn op_use_state(
 }
 
 extension!(
-  op_sample,
+  op2_sample,
   ops = [op_use_state],
-  esm_entry_point = "ext:op_sample/op.js",
-  esm = [ dir "examples", "op.js" ],
-  docs = "A small example demonstrating op usage.", "Contains one op."
+  esm_entry_point = "ext:op2_sample/op2.js",
+  esm = [ dir "examples", "op2.js" ],
+  docs = "A small example demonstrating op2 usage.", "Contains one op."
 );
 
 fn main() -> Result<(), Error> {
   let module_name = "test.js";
   let module_code = "
-      op_sample.use_state(() => {
+      op2_sample.use_state(() => {
           console.log('Hello World');
       });
   "
@@ -32,7 +32,7 @@ fn main() -> Result<(), Error> {
 
   let mut js_runtime = JsRuntime::new(deno_core::RuntimeOptions {
     module_loader: Some(Rc::new(FsModuleLoader)),
-    extensions: vec![op_sample::init_ops_and_esm()],
+    extensions: vec![op2_sample::init_ops_and_esm()],
     ..Default::default()
   });
 
diff --git a/core/examples/snapshot/README.md b/core/examples/snapshot/README.md
index 7d752e8..af76532 100644
--- a/core/examples/snapshot/README.md
+++ b/core/examples/snapshot/README.md
@@ -19,7 +19,7 @@ Differences from those blog posts:
 
 - The `create_snapshot()` API has changed in various ways.
 - New API features for extensions:
-  - `#[op]` ([read more][op])
+  - `#[op2]` ([read more][op2])
   - `extension!(...)` macro replaces `Extension::builder()`
   - ESM-based extensions.
 
@@ -28,5 +28,5 @@ Missing features vs. those blog posts:
 - Does not implement [TsModuleLoader], to keep this example more concise.
 
 [blog]: https://deno.com/blog/roll-your-own-javascript-runtime-pt3#creating-a-snapshot-in-buildrs
-[op]: https://github.com/denoland/deno_core/tree/main/ops/op#readme
+[op2]: https://github.com/denoland/deno_core/tree/main/ops/op2#readme
 [TsModuleLoader]: https://deno.com/blog/roll-your-own-javascript-runtime-pt2#supporting-typescript
diff --git a/core/examples/snapshot/src/main.rs b/core/examples/snapshot/src/main.rs
index ddf566b..83f865d 100644
--- a/core/examples/snapshot/src/main.rs
+++ b/core/examples/snapshot/src/main.rs
@@ -2,7 +2,7 @@
 use std::{env::current_dir, rc::Rc};
 
 use deno_core::{
-  error::AnyError, extension, op, FsModuleLoader, JsRuntime,
+  error::AnyError, extension, op2, FsModuleLoader, JsRuntime,
   PollEventLoopOptions, RuntimeOptions,
 };
 
@@ -16,7 +16,7 @@ fn main() {
   }
 }
 
-#[op(fast)]
+#[op2(fast)]
 fn op_call_rust(#[string] value: String) {
   println!("Received this value from JS: {value}");
 }
diff --git a/core/extensions.rs b/core/extensions.rs
index b6e4f5a..11bc573 100644
--- a/core/extensions.rs
+++ b/core/extensions.rs
@@ -220,7 +220,7 @@ impl OpDecl {
   /// For use by internal op implementation only.
   #[doc(hidden)]
   #[allow(clippy::too_many_arguments)]
-  pub const fn new_internal_op(
+  pub const fn new_internal_op2(
     name: (&'static str, FastStaticString),
     is_async: bool,
     is_reentrant: bool,
diff --git a/core/lib.rs b/core/lib.rs
index 986f209..4e01455 100644
--- a/core/lib.rs
+++ b/core/lib.rs
@@ -51,7 +51,7 @@ pub use sourcemap;
 pub use url;
 pub use v8;
 
-pub use deno_ops::op;
+pub use deno_ops::op2;
 
 pub use crate::async_cancel::CancelFuture;
 pub use crate::async_cancel::CancelHandle;
@@ -166,7 +166,7 @@ pub use crate::source_map::SourceMapData;
 pub use crate::tasks::V8CrossThreadTaskSpawner;
 pub use crate::tasks::V8TaskSpawner;
 
-// Ensure we can use op in deno_core without any hackery.
+// Ensure we can use op2 in deno_core without any hackery.
 extern crate self as deno_core;
 
 /// An internal module re-exporting functions used by the #[op] (`deno_ops`) macro
diff --git a/core/ops.rs b/core/ops.rs
index 45d0cbf..20c5bbd 100644
--- a/core/ops.rs
+++ b/core/ops.rs
@@ -48,7 +48,7 @@ pub fn reentrancy_check(decl: &'static OpDecl) -> Option<ReentrancyGuard> {
 
   let current = CURRENT_OP.with(|f| f.get());
   if let Some(current) = current {
-    panic!("op {} was not marked as #[op(reentrant)], but re-entrantly invoked op {}", current.name, decl.name);
+    panic!("op {} was not marked as #[op2(reentrant)], but re-entrantly invoked op {}", current.name, decl.name);
   }
   CURRENT_OP.with(|f| f.set(Some(decl)));
   Some(ReentrancyGuard {})
diff --git a/core/ops_builtin.rs b/core/ops_builtin.rs
index df40121..df598c9 100644
--- a/core/ops_builtin.rs
+++ b/core/ops_builtin.rs
@@ -8,7 +8,7 @@ use crate::io::BufMutView;
 use crate::io::BufView;
 use crate::io::ResourceId;
 use crate::modules::ModuleMap;
-use crate::op;
+use crate::op2;
 use crate::ops_builtin_types;
 use crate::ops_builtin_v8;
 use crate::runtime::v8_static_strings;
@@ -135,7 +135,7 @@ builtin_ops! {
   ops_builtin_v8::op_leak_tracing_get
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_panic(#[string] message: String) {
   #[allow(clippy::print_stderr)]
   {
@@ -146,7 +146,7 @@ pub fn op_panic(#[string] message: String) {
 
 /// Return map of resources with id as key
 /// and string representation as value.
-#[op]
+#[op2]
 #[serde]
 pub fn op_resources(state: &mut OpState) -> Vec<(ResourceId, String)> {
   state
@@ -156,42 +156,42 @@ pub fn op_resources(state: &mut OpState) -> Vec<(ResourceId, String)> {
     .collect()
 }
 
-#[op(fast)]
+#[op2(fast)]
 fn op_add(a: i32, b: i32) -> i32 {
   a + b
 }
 
 #[allow(clippy::unused_async)]
-#[op(async)]
+#[op2(async)]
 pub async fn op_add_async(a: i32, b: i32) -> i32 {
   a + b
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_void_sync() {}
 
 #[allow(clippy::unused_async)]
-#[op(async)]
+#[op2(async)]
 pub async fn op_void_async() {}
 
 #[allow(clippy::unused_async)]
-#[op(async)]
+#[op2(async)]
 pub async fn op_error_async() -> Result<(), Error> {
   Err(Error::msg("error"))
 }
 
 #[allow(clippy::unused_async)]
-#[op(async(deferred), fast)]
+#[op2(async(deferred), fast)]
 pub async fn op_error_async_deferred() -> Result<(), Error> {
   Err(Error::msg("error"))
 }
 
 #[allow(clippy::unused_async)]
-#[op(async(deferred), fast)]
+#[op2(async(deferred), fast)]
 pub async fn op_void_async_deferred() {}
 
 /// Remove a resource from the resource table.
-#[op(fast)]
+#[op2(fast)]
 pub fn op_close(
   state: Rc<RefCell<OpState>>,
   #[smi] rid: ResourceId,
@@ -203,7 +203,7 @@ pub fn op_close(
 
 /// Try to remove a resource from the resource table. If there is no resource
 /// with the specified `rid`, this is a no-op.
-#[op(fast)]
+#[op2(fast)]
 pub fn op_try_close(state: Rc<RefCell<OpState>>, #[smi] rid: ResourceId) {
   if let Ok(resource) = state.borrow_mut().resource_table.take_any(rid) {
     resource.close();
@@ -211,7 +211,7 @@ pub fn op_try_close(state: Rc<RefCell<OpState>>, #[smi] rid: ResourceId) {
 }
 
 /// Builtin utility to print to stdout/stderr
-#[op(fast)]
+#[op2(fast)]
 pub fn op_print(#[string] msg: &str, is_err: bool) -> Result<(), Error> {
   if is_err {
     stderr().write_all(msg.as_bytes())?;
@@ -239,7 +239,7 @@ impl Resource for WasmStreamingResource {
 }
 
 /// Feed bytes to WasmStreamingResource.
-#[op(fast)]
+#[op2(fast)]
 pub fn op_wasm_streaming_feed(
   state: Rc<RefCell<OpState>>,
   #[smi] rid: ResourceId,
@@ -255,7 +255,7 @@ pub fn op_wasm_streaming_feed(
   Ok(())
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_wasm_streaming_set_url(
   state: &mut OpState,
   #[smi] rid: ResourceId,
@@ -269,7 +269,7 @@ pub fn op_wasm_streaming_set_url(
   Ok(())
 }
 
-#[op(async)]
+#[op2(async)]
 async fn op_read(
   state: Rc<RefCell<OpState>>,
   #[smi] rid: ResourceId,
@@ -280,7 +280,7 @@ async fn op_read(
   resource.read_byob(view).await.map(|(n, _)| n as u32)
 }
 
-#[op(async)]
+#[op2(async)]
 #[buffer]
 async fn op_read_all(
   state: Rc<RefCell<OpState>>,
@@ -315,7 +315,7 @@ async fn op_read_all(
   Ok(buf.maybe_unwrap_bytes().unwrap())
 }
 
-#[op(async)]
+#[op2(async)]
 async fn op_write(
   state: Rc<RefCell<OpState>>,
   #[smi] rid: ResourceId,
@@ -327,7 +327,7 @@ async fn op_write(
   Ok(resp.nwritten() as u32)
 }
 
-#[op(fast)]
+#[op2(fast)]
 fn op_read_sync(
   state: Rc<RefCell<OpState>>,
   #[smi] rid: ResourceId,
@@ -337,7 +337,7 @@ fn op_read_sync(
   resource.read_byob_sync(data).map(|n| n as u32)
 }
 
-#[op(fast)]
+#[op2(fast)]
 fn op_write_sync(
   state: Rc<RefCell<OpState>>,
   #[smi] rid: ResourceId,
@@ -348,7 +348,7 @@ fn op_write_sync(
   Ok(nwritten as u32)
 }
 
-#[op(async)]
+#[op2(async)]
 async fn op_write_all(
   state: Rc<RefCell<OpState>>,
   #[smi] rid: ResourceId,
@@ -360,7 +360,7 @@ async fn op_write_all(
   Ok(())
 }
 
-#[op(async)]
+#[op2(async)]
 async fn op_write_type_error(
   state: Rc<RefCell<OpState>>,
   #[smi] rid: ResourceId,
@@ -371,7 +371,7 @@ async fn op_write_type_error(
   Ok(())
 }
 
-#[op(async)]
+#[op2(async)]
 async fn op_shutdown(
   state: Rc<RefCell<OpState>>,
   #[smi] rid: ResourceId,
@@ -380,13 +380,13 @@ async fn op_shutdown(
   resource.shutdown().await
 }
 
-#[op]
+#[op2]
 #[string]
 fn op_format_file_name(#[string] file_name: &str) -> String {
   format_file_name(file_name)
 }
 
-#[op(fast)]
+#[op2(fast)]
 fn op_str_byte_length(
   scope: &mut v8::HandleScope,
   value: v8::Local<v8::Value>,
@@ -399,19 +399,19 @@ fn op_str_byte_length(
 }
 
 /// Creates a [`CancelHandle`] resource that can be used to cancel invocations of certain ops.
-#[op(fast)]
+#[op2(fast)]
 #[smi]
 pub fn op_cancel_handle(state: &mut OpState) -> u32 {
   state.resource_table.add(CancelHandle::new())
 }
 
-#[op]
+#[op2]
 #[serde]
 fn op_encode_binary_string(#[buffer] s: &[u8]) -> ByteString {
   ByteString::from(s)
 }
 
-#[op(fast)]
+#[op2(fast)]
 fn op_is_terminal(
   state: &mut OpState,
   #[smi] rid: ResourceId,
@@ -533,7 +533,7 @@ fn wrap_module<'s>(
   Some(wrapper_module)
 }
 
-#[op(reentrant)]
+#[op2(reentrant)]
 fn op_import_sync<'s>(
   scope: &mut v8::HandleScope<'s>,
   #[string] specifier: &str,
diff --git a/core/ops_builtin_types.rs b/core/ops_builtin_types.rs
index 3a9e998..85d02ba 100644
--- a/core/ops_builtin_types.rs
+++ b/core/ops_builtin_types.rs
@@ -1,42 +1,42 @@
 // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
-use crate::op;
+use crate::op2;
 
-#[op(fast, no_side_effects)]
+#[op2(fast, no_side_effects)]
 pub fn op_is_any_array_buffer(value: &v8::Value) -> bool {
   value.is_array_buffer() || value.is_shared_array_buffer()
 }
 
-#[op(fast, no_side_effects)]
+#[op2(fast, no_side_effects)]
 pub fn op_is_arguments_object(value: &v8::Value) -> bool {
   value.is_arguments_object()
 }
 
-#[op(fast, no_side_effects)]
+#[op2(fast, no_side_effects)]
 pub fn op_is_array_buffer(value: &v8::Value) -> bool {
   value.is_array_buffer()
 }
 
-#[op(fast, no_side_effects)]
+#[op2(fast, no_side_effects)]
 pub fn op_is_array_buffer_view(value: &v8::Value) -> bool {
   value.is_array_buffer_view()
 }
 
-#[op(fast, no_side_effects)]
+#[op2(fast, no_side_effects)]
 pub fn op_is_async_function(value: &v8::Value) -> bool {
   value.is_async_function()
 }
 
-#[op(fast, no_side_effects)]
+#[op2(fast, no_side_effects)]
 pub fn op_is_big_int_object(value: &v8::Value) -> bool {
   value.is_big_int_object()
 }
 
-#[op(fast, no_side_effects)]
+#[op2(fast, no_side_effects)]
 pub fn op_is_boolean_object(value: &v8::Value) -> bool {
   value.is_boolean_object()
 }
 
-#[op(fast, no_side_effects)]
+#[op2(fast, no_side_effects)]
 pub fn op_is_boxed_primitive(value: &v8::Value) -> bool {
   value.is_boolean_object()
     || value.is_string_object()
@@ -45,102 +45,102 @@ pub fn op_is_boxed_primitive(value: &v8::Value) -> bool {
     || value.is_big_int_object()
 }
 
-#[op(fast, no_side_effects)]
+#[op2(fast, no_side_effects)]
 pub fn op_is_data_view(value: &v8::Value) -> bool {
   value.is_data_view()
 }
 
-#[op(fast, no_side_effects)]
+#[op2(fast, no_side_effects)]
 pub fn op_is_date(value: &v8::Value) -> bool {
   value.is_date()
 }
 
-#[op(fast, no_side_effects)]
+#[op2(fast, no_side_effects)]
 pub fn op_is_generator_function(value: &v8::Value) -> bool {
   value.is_generator_function()
 }
 
-#[op(fast, no_side_effects)]
+#[op2(fast, no_side_effects)]
 pub fn op_is_generator_object(value: &v8::Value) -> bool {
   value.is_generator_object()
 }
 
-#[op(fast, no_side_effects)]
+#[op2(fast, no_side_effects)]
 pub fn op_is_map(value: &v8::Value) -> bool {
   value.is_map()
 }
 
-#[op(fast, no_side_effects)]
+#[op2(fast, no_side_effects)]
 pub fn op_is_map_iterator(value: &v8::Value) -> bool {
   value.is_map_iterator()
 }
 
-#[op(fast, no_side_effects)]
+#[op2(fast, no_side_effects)]
 pub fn op_is_module_namespace_object(value: &v8::Value) -> bool {
   value.is_module_namespace_object()
 }
 
-#[op(fast, reentrant)] // may be invoked by `format_exception_cb`
+#[op2(fast, reentrant)] // may be invoked by `format_exception_cb`
 pub fn op_is_native_error(value: &v8::Value) -> bool {
   value.is_native_error()
 }
 
-#[op(fast, no_side_effects)]
+#[op2(fast, no_side_effects)]
 pub fn op_is_number_object(value: &v8::Value) -> bool {
   value.is_number_object()
 }
 
-#[op(fast, no_side_effects)]
+#[op2(fast, no_side_effects)]
 pub fn op_is_promise(value: &v8::Value) -> bool {
   value.is_promise()
 }
 
-#[op(fast, no_side_effects)]
+#[op2(fast, no_side_effects)]
 pub fn op_is_proxy(value: &v8::Value) -> bool {
   value.is_proxy()
 }
 
-#[op(fast, no_side_effects)]
+#[op2(fast, no_side_effects)]
 pub fn op_is_reg_exp(value: &v8::Value) -> bool {
   value.is_reg_exp()
 }
 
-#[op(fast, no_side_effects)]
+#[op2(fast, no_side_effects)]
 pub fn op_is_set(value: &v8::Value) -> bool {
   value.is_set()
 }
 
-#[op(fast, no_side_effects)]
+#[op2(fast, no_side_effects)]
 pub fn op_is_set_iterator(value: &v8::Value) -> bool {
   value.is_set_iterator()
 }
 
-#[op(fast, no_side_effects)]
+#[op2(fast, no_side_effects)]
 pub fn op_is_shared_array_buffer(value: &v8::Value) -> bool {
   value.is_shared_array_buffer()
 }
 
-#[op(fast, no_side_effects)]
+#[op2(fast, no_side_effects)]
 pub fn op_is_string_object(value: &v8::Value) -> bool {
   value.is_string_object()
 }
 
-#[op(fast, no_side_effects)]
+#[op2(fast, no_side_effects)]
 pub fn op_is_symbol_object(value: &v8::Value) -> bool {
   value.is_symbol_object()
 }
 
-#[op(fast, no_side_effects)]
+#[op2(fast, no_side_effects)]
 pub fn op_is_typed_array(value: &v8::Value) -> bool {
   value.is_typed_array()
 }
 
-#[op(fast, no_side_effects)]
+#[op2(fast, no_side_effects)]
 pub fn op_is_weak_map(value: &v8::Value) -> bool {
   value.is_weak_map()
 }
 
-#[op(fast, no_side_effects)]
+#[op2(fast, no_side_effects)]
 pub fn op_is_weak_set(value: &v8::Value) -> bool {
   value.is_weak_set()
 }
diff --git a/core/ops_builtin_v8.rs b/core/ops_builtin_v8.rs
index 5f3e365..88cc73b 100644
--- a/core/ops_builtin_v8.rs
+++ b/core/ops_builtin_v8.rs
@@ -5,7 +5,7 @@ use crate::error::range_error;
 use crate::error::type_error;
 use crate::error::JsError;
 use crate::modules::script_origin;
-use crate::op;
+use crate::op2;
 use crate::ops_builtin::WasmStreamingResource;
 use crate::resolve_url;
 use crate::runtime::JsRealm;
@@ -23,7 +23,7 @@ use std::rc::Rc;
 use v8::ValueDeserializerHelper;
 use v8::ValueSerializerHelper;
 
-#[op]
+#[op2]
 pub fn op_add_main_module_handler(
   scope: &mut v8::HandleScope,
   #[global] f: v8::Global<v8::Function>,
@@ -35,7 +35,7 @@ pub fn op_add_main_module_handler(
     .push(f);
 }
 
-#[op]
+#[op2]
 pub fn op_set_handled_promise_rejection_handler(
   scope: &mut v8::HandleScope,
   #[global] f: Option<v8::Global<v8::Function>>,
@@ -44,25 +44,25 @@ pub fn op_set_handled_promise_rejection_handler(
   *exception_state.js_handled_promise_rejection_cb.borrow_mut() = f;
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_ref_op(scope: &mut v8::HandleScope, promise_id: i32) {
   let context_state = JsRealm::state_from_scope(scope);
   context_state.unrefed_ops.borrow_mut().remove(&promise_id);
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_unref_op(scope: &mut v8::HandleScope, promise_id: i32) {
   let context_state = JsRealm::state_from_scope(scope);
   context_state.unrefed_ops.borrow_mut().insert(promise_id);
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_leak_tracing_enable(scope: &mut v8::HandleScope, enabled: bool) {
   let context_state = JsRealm::state_from_scope(scope);
   context_state.activity_traces.set_enabled(enabled);
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_leak_tracing_submit(
   scope: &mut v8::HandleScope,
   #[smi] kind: u8,
@@ -77,7 +77,7 @@ pub fn op_leak_tracing_submit(
   );
 }
 
-#[op]
+#[op2]
 pub fn op_leak_tracing_get_all<'s>(
   scope: &mut v8::HandleScope<'s>,
 ) -> v8::Local<'s, v8::Value> {
@@ -96,7 +96,7 @@ pub fn op_leak_tracing_get_all<'s>(
   out.into()
 }
 
-#[op]
+#[op2]
 pub fn op_leak_tracing_get<'s>(
   scope: &mut v8::HandleScope<'s>,
   #[smi] kind: u8,
@@ -120,7 +120,7 @@ pub fn op_leak_tracing_get<'s>(
 /// Queue a timer. We return a "large integer" timer ID in an f64 which allows for up
 /// to `MAX_SAFE_INTEGER` (2^53) timers to exist, versus 2^32 timers if we used
 /// `u32`.
-#[op]
+#[op2]
 pub fn op_timer_queue(
   scope: &mut v8::HandleScope,
   depth: u32,
@@ -143,7 +143,7 @@ pub fn op_timer_queue(
 /// Queue a timer. We return a "large integer" timer ID in an f64 which allows for up
 /// to `MAX_SAFE_INTEGER` (2^53) timers to exist, versus 2^32 timers if we used
 /// `u32`.
-#[op]
+#[op2]
 pub fn op_timer_queue_system(
   scope: &mut v8::HandleScope,
   repeat: bool,
@@ -159,7 +159,7 @@ pub fn op_timer_queue_system(
 /// Queue a timer. We return a "large integer" timer ID in an f64 which allows for up
 /// to `MAX_SAFE_INTEGER` (2^53) timers to exist, versus 2^32 timers if we used
 /// `u32`.
-#[op]
+#[op2]
 pub fn op_timer_queue_immediate(
   scope: &mut v8::HandleScope,
   #[global] task: v8::Global<v8::Function>,
@@ -168,7 +168,7 @@ pub fn op_timer_queue_immediate(
   context_state.timers.queue_timer(0, (task, 0)) as _
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_timer_cancel(scope: &mut v8::HandleScope, id: f64) {
   let context_state = JsRealm::state_from_scope(scope);
   context_state.timers.cancel_timer(id as _);
@@ -177,19 +177,19 @@ pub fn op_timer_cancel(scope: &mut v8::HandleScope, id: f64) {
     .complete(RuntimeActivityType::Timer, id as _);
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_timer_ref(scope: &mut v8::HandleScope, id: f64) {
   let context_state = JsRealm::state_from_scope(scope);
   context_state.timers.ref_timer(id as _);
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_timer_unref(scope: &mut v8::HandleScope, id: f64) {
   let context_state = JsRealm::state_from_scope(scope);
   context_state.timers.unref_timer(id as _);
 }
 
-#[op(reentrant)]
+#[op2(reentrant)]
 #[global]
 pub fn op_lazy_load_esm(
   scope: &mut v8::HandleScope,
@@ -201,7 +201,7 @@ pub fn op_lazy_load_esm(
 
 // We run in a `nofast` op here so we don't get put into a `DisallowJavascriptExecutionScope` and we're
 // allowed to touch JS heap.
-#[op(nofast)]
+#[op2(nofast)]
 pub fn op_queue_microtask(
   isolate: *mut v8::Isolate,
   cb: v8::Local<v8::Function>,
@@ -214,7 +214,7 @@ pub fn op_queue_microtask(
 
 // We run in a `nofast` op here so we don't get put into a `DisallowJavascriptExecutionScope` and we're
 // allowed to touch JS heap.
-#[op(nofast, reentrant)]
+#[op2(nofast, reentrant)]
 pub fn op_run_microtasks(isolate: *mut v8::Isolate) {
   // SAFETY: we know v8 provides us with a valid, non-null isolate
   unsafe {
@@ -225,14 +225,14 @@ pub fn op_run_microtasks(isolate: *mut v8::Isolate) {
   };
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_has_tick_scheduled(scope: &mut v8::HandleScope) -> bool {
   JsRealm::state_from_scope(scope)
     .has_next_tick_scheduled
     .get()
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_set_has_tick_scheduled(scope: &mut v8::HandleScope, v: bool) {
   JsRealm::state_from_scope(scope)
     .has_next_tick_scheduled
@@ -257,7 +257,7 @@ impl<'s> EvalContextError<'s> {
   }
 }
 
-#[op(reentrant)]
+#[op2(reentrant)]
 pub fn op_eval_context<'a>(
   scope: &mut v8::HandleScope<'a>,
   source: v8::Local<'a, v8::Value>,
@@ -372,7 +372,7 @@ pub fn op_eval_context<'a>(
   }
 }
 
-#[op]
+#[op2]
 pub fn op_encode<'a>(
   scope: &mut v8::HandleScope<'a>,
   text: v8::Local<'a, v8::Value>,
@@ -389,7 +389,7 @@ pub fn op_encode<'a>(
   Ok(u8array)
 }
 
-#[op]
+#[op2]
 pub fn op_decode<'a>(
   scope: &mut v8::HandleScope<'a>,
   #[buffer] zero_copy: &[u8],
@@ -585,7 +585,7 @@ impl<'a> v8::ValueDeserializerImpl for SerializeDeserialize<'a> {
 }
 
 // May be reentrant in the case of errors.
-#[op(reentrant)]
+#[op2(reentrant)]
 #[buffer]
 pub fn op_serialize(
   scope: &mut v8::HandleScope,
@@ -677,7 +677,7 @@ pub fn op_serialize(
   }
 }
 
-#[op]
+#[op2]
 pub fn op_deserialize<'a>(
   scope: &mut v8::HandleScope<'a>,
   #[buffer] zero_copy: JsBuffer,
@@ -750,7 +750,7 @@ pub fn op_deserialize<'a>(
   }
 }
 
-#[op]
+#[op2]
 pub fn op_get_promise_details<'a>(
   scope: &mut v8::HandleScope<'a>,
   promise: v8::Local<'a, v8::Promise>,
@@ -775,7 +775,7 @@ pub fn op_get_promise_details<'a>(
   out.into()
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_set_promise_hooks(
   scope: &mut v8::HandleScope,
   init_hook: v8::Local<v8::Value>,
@@ -826,7 +826,7 @@ pub fn op_set_promise_hooks(
 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 // USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-#[op]
+#[op2]
 pub fn op_get_proxy_details<'a>(
   scope: &mut v8::HandleScope<'a>,
   proxy: v8::Local<'a, v8::Value>,
@@ -842,7 +842,7 @@ pub fn op_get_proxy_details<'a>(
   out_array.into()
 }
 
-#[op]
+#[op2]
 pub fn op_get_non_index_property_names<'a>(
   scope: &mut v8::HandleScope<'a>,
   obj: v8::Local<'a, v8::Value>,
@@ -883,7 +883,7 @@ pub fn op_get_non_index_property_names<'a>(
   maybe_names.map(|names| names.into())
 }
 
-#[op]
+#[op2]
 #[string]
 pub fn op_get_constructor_name(
   scope: &mut v8::HandleScope,
@@ -911,7 +911,7 @@ pub struct MemoryUsage {
   // array_buffers: usize,
 }
 
-#[op]
+#[op2]
 #[serde]
 pub fn op_memory_usage(scope: &mut v8::HandleScope) -> MemoryUsage {
   let mut s = v8::HeapStatistics::default();
@@ -924,7 +924,7 @@ pub fn op_memory_usage(scope: &mut v8::HandleScope) -> MemoryUsage {
   }
 }
 
-#[op]
+#[op2]
 pub fn op_set_wasm_streaming_callback(
   scope: &mut v8::HandleScope,
   #[global] cb: v8::Global<v8::Function>,
@@ -968,7 +968,7 @@ pub fn op_set_wasm_streaming_callback(
 // This op is re-entrant as it makes a v8 call. It also cannot be fast because
 // we require a JS execution scope.
 #[allow(clippy::let_and_return)]
-#[op(nofast, reentrant)]
+#[op2(nofast, reentrant)]
 pub fn op_abort_wasm_streaming(
   state: Rc<RefCell<OpState>>,
   rid: u32,
@@ -992,7 +992,7 @@ pub fn op_abort_wasm_streaming(
 }
 
 // This op calls `op_apply_source_map` re-entrantly.
-#[op(reentrant)]
+#[op2(reentrant)]
 #[serde]
 pub fn op_destructure_error(
   scope: &mut v8::HandleScope,
@@ -1004,7 +1004,7 @@ pub fn op_destructure_error(
 /// Effectively throw an uncatchable error. This will terminate runtime
 /// execution before any more JS code can run, except in the REPL where it
 /// should just output the error to the console.
-#[op(fast, reentrant)]
+#[op2(fast, reentrant)]
 pub fn op_dispatch_exception(
   scope: &mut v8::HandleScope,
   exception: v8::Local<v8::Value>,
@@ -1024,7 +1024,7 @@ pub fn op_dispatch_exception(
   scope.terminate_execution();
 }
 
-#[op]
+#[op2]
 #[serde]
 pub fn op_op_names(scope: &mut v8::HandleScope) -> Vec<String> {
   let state = JsRealm::state_from_scope(scope);
@@ -1052,7 +1052,7 @@ fn write_line_and_col_to_ret_buf(
   ret_buf[4..8].copy_from_slice(&column_number.to_le_bytes());
 }
 
-#[op]
+#[op2]
 #[string]
 pub fn op_current_user_call_site(
   scope: &mut v8::HandleScope,
@@ -1113,7 +1113,7 @@ pub fn op_current_user_call_site(
 /// `JsError::exception_message`. The callback is passed the error value and
 /// should return a string or `null`. If no callback is set or the callback
 /// returns `null`, the built-in default formatting will be used.
-#[op]
+#[op2]
 pub fn op_set_format_exception_callback<'a>(
   scope: &mut v8::HandleScope<'a>,
   #[global] cb: v8::Global<v8::Function>,
@@ -1128,12 +1128,12 @@ pub fn op_set_format_exception_callback<'a>(
   old.map(|func| func.into())
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_event_loop_has_more_work(scope: &mut v8::HandleScope) -> bool {
   JsRuntime::has_more_work(scope)
 }
 
-#[op]
+#[op2]
 pub fn op_get_extras_binding_object<'a>(
   scope: &mut v8::HandleScope<'a>,
 ) -> v8::Local<'a, v8::Value> {
diff --git a/core/runtime/ops.rs b/core/runtime/ops.rs
index 02e7082..b5ad0f9 100644
--- a/core/runtime/ops.rs
+++ b/core/runtime/ops.rs
@@ -523,7 +523,7 @@ mod tests {
   use crate::error::StdAnyError;
   use crate::external;
   use crate::external::ExternalPointer;
-  use crate::op;
+  use crate::op2;
   use crate::runtime::JsRuntimeState;
   use crate::FromV8;
   use crate::GarbageCollected;
@@ -655,12 +655,12 @@ mod tests {
     static FAIL: Cell<bool> = const { Cell::new(false) }
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_test_fail() {
     FAIL.with(|b| b.set(true))
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_test_print_debug(#[string] s: &str) {
     println!("{s}")
   }
@@ -772,7 +772,7 @@ mod tests {
     assert!(run_test2(1, "", "assert(false)").is_err());
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_test_add(a: u32, b: i32) -> u32 {
     (a as i32 + b) as u32
   }
@@ -815,7 +815,7 @@ mod tests {
 
   // Note: #[smi] parameters are signed in JS regardless of the sign in Rust. Overflow and underflow
   // of valid ranges result in automatic wrapping.
-  #[op(fast)]
+  #[op2(fast)]
   #[smi]
   pub fn op_test_add_smi_unsigned(#[smi] a: u32, #[smi] b: u16) -> u32 {
     a + b as u32
@@ -837,7 +837,7 @@ mod tests {
     Ok(())
   }
 
-  #[op]
+  #[op2]
   pub fn op_test_add_option(a: u32, b: Option<u32>) -> u32 {
     a + b.unwrap_or(100)
   }
@@ -862,7 +862,7 @@ mod tests {
     static RETURN_COUNT: Cell<usize> = const { Cell::new(0) };
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_test_result_void_switch() -> Result<(), AnyError> {
     let count = RETURN_COUNT.with(|count| {
       let new = count.get() + 1;
@@ -876,12 +876,12 @@ mod tests {
     }
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_test_result_void_err() -> Result<(), AnyError> {
     Err(generic_error("failed!!!"))
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_test_result_void_ok() -> Result<(), AnyError> {
     Ok(())
   }
@@ -918,12 +918,12 @@ mod tests {
     Ok(())
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_test_result_primitive_err() -> Result<u32, AnyError> {
     Err(generic_error("failed!!!"))
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_test_result_primitive_ok() -> Result<u32, AnyError> {
     Ok(123)
   }
@@ -944,12 +944,12 @@ mod tests {
     Ok(())
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_test_bool(b: bool) -> bool {
     b
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_test_bool_result(b: bool) -> Result<bool, AnyError> {
     if b {
       Ok(true)
@@ -978,12 +978,12 @@ mod tests {
     Ok(())
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_test_float(a: f32, b: f64) -> f32 {
     a + b as f32
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_test_float_result(a: f32, b: f64) -> Result<f64, AnyError> {
     let a = a as f64;
     if a + b >= 0. {
@@ -1013,19 +1013,19 @@ mod tests {
     Ok(())
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   #[bigint]
   pub fn op_test_bigint_u64(#[bigint] input: u64) -> u64 {
     input
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   #[bigint]
   pub fn op_test_bigint_i64(#[bigint] input: i64) -> i64 {
     input
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   #[number]
   pub fn op_test_bigint_i64_as_number(#[number] input: i64) -> i64 {
     input
@@ -1061,27 +1061,27 @@ mod tests {
     Ok(())
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_test_string_owned(#[string] s: String) -> u32 {
     s.len() as _
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_test_string_ref(#[string] s: &str) -> u32 {
     s.len() as _
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_test_string_cow(#[string] s: Cow<str>) -> u32 {
     s.len() as _
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_test_string_roundtrip_char(#[string] s: Cow<str>) -> u32 {
     s.chars().next().unwrap() as u32
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_test_string_roundtrip_char_onebyte(
     #[string(onebyte)] s: Cow<[u8]>,
   ) -> u32 {
@@ -1159,7 +1159,7 @@ mod tests {
     Ok(())
   }
 
-  #[op]
+  #[op2]
   #[string]
   pub fn op_test_string_return(
     #[string] a: Cow<str>,
@@ -1168,7 +1168,7 @@ mod tests {
     (a + b).to_string()
   }
 
-  #[op]
+  #[op2]
   #[string]
   pub fn op_test_string_option_return(
     #[string] a: Cow<str>,
@@ -1180,13 +1180,13 @@ mod tests {
     Some((a + b).to_string())
   }
 
-  #[op]
+  #[op2]
   #[string]
   pub fn op_test_string_roundtrip(#[string] s: String) -> String {
     s
   }
 
-  #[op]
+  #[op2]
   #[string(onebyte)]
   pub fn op_test_string_roundtrip_onebyte(
     #[string(onebyte)] s: Cow<[u8]>,
@@ -1226,12 +1226,12 @@ mod tests {
   }
 
   // We don't actually test this one -- we just want it to compile
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_test_generics<T: Clone>() {}
 
   /// Tests v8 types without a handle scope
   #[allow(clippy::needless_lifetimes)]
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_test_v8_types<'s>(
     s: &v8::String,
     s2: v8::Local<v8::String>,
@@ -1246,7 +1246,7 @@ mod tests {
     }
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_test_v8_option_string(s: Option<&v8::String>) -> i32 {
     if let Some(s) = s {
       s.length() as i32
@@ -1256,7 +1256,7 @@ mod tests {
   }
 
   /// Tests v8 types without a handle scope
-  #[op]
+  #[op2]
   #[allow(clippy::needless_lifetimes)]
   pub fn op_test_v8_type_return<'s>(
     s: v8::Local<'s, v8::String>,
@@ -1265,7 +1265,7 @@ mod tests {
   }
 
   /// Tests v8 types without a handle scope
-  #[op]
+  #[op2]
   #[allow(clippy::needless_lifetimes)]
   pub fn op_test_v8_type_return_option<'s>(
     s: Option<v8::Local<'s, v8::String>>,
@@ -1273,7 +1273,7 @@ mod tests {
     s
   }
 
-  #[op]
+  #[op2]
   pub fn op_test_v8_type_handle_scope<'s>(
     scope: &mut v8::HandleScope<'s>,
     s: &v8::String,
@@ -1283,7 +1283,7 @@ mod tests {
   }
 
   /// Extract whatever lives in "key" from the object.
-  #[op]
+  #[op2]
   pub fn op_test_v8_type_handle_scope_obj<'s>(
     scope: &mut v8::HandleScope<'s>,
     o: &v8::Object,
@@ -1293,7 +1293,7 @@ mod tests {
   }
 
   /// Extract whatever lives in "key" from the object.
-  #[op]
+  #[op2]
   pub fn op_test_v8_type_handle_scope_result<'s>(
     scope: &mut v8::HandleScope<'s>,
     o: &v8::Object,
@@ -1351,7 +1351,7 @@ mod tests {
     Ok(())
   }
 
-  #[op]
+  #[op2]
   pub fn op_test_v8_global(
     scope: &mut v8::HandleScope,
     #[global] s: v8::Global<v8::String>,
@@ -1375,7 +1375,7 @@ mod tests {
     pub s: String,
   }
 
-  #[op]
+  #[op2]
   #[serde]
   pub fn op_test_serde_v8(#[serde] mut serde: Serde) -> Serde {
     serde.s += "!";
@@ -1397,7 +1397,7 @@ mod tests {
     Ok(())
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_jsruntimestate(_state: &JsRuntimeState) {}
 
   #[tokio::test]
@@ -1406,32 +1406,32 @@ mod tests {
     Ok(())
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_state_rc(state: Rc<RefCell<OpState>>, value: u32) -> u32 {
     let old_value: u32 = state.borrow_mut().take();
     state.borrow_mut().put(value);
     old_value
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_state_ref(state: &OpState) -> u32 {
     let old_value: &u32 = state.borrow();
     *old_value
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_state_mut(state: &mut OpState, value: u32) {
     *state.borrow_mut() = value;
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_state_mut_attr(#[state] value: &mut u32, new_value: u32) -> u32 {
     let old_value = *value;
     *value = new_value;
     old_value
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_state_multi_attr(
     #[state] value32: &u32,
     #[state] value16: &u16,
@@ -1467,7 +1467,7 @@ mod tests {
     Ok(())
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_buffer_slice(
     #[buffer] input: &[u8],
     #[number] inlen: usize,
@@ -1481,7 +1481,7 @@ mod tests {
     }
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_buffer_ptr(
     #[buffer] input: *const u8,
     #[number] inlen: usize,
@@ -1494,7 +1494,7 @@ mod tests {
     }
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_buffer_slice_32(
     #[buffer] input: &[u32],
     #[number] inlen: usize,
@@ -1508,7 +1508,7 @@ mod tests {
     }
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_buffer_ptr_32(
     #[buffer] input: *const u32,
     #[number] inlen: usize,
@@ -1521,7 +1521,7 @@ mod tests {
     }
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_buffer_slice_f64(
     #[buffer] input: &[f64],
     #[number] inlen: usize,
@@ -1535,7 +1535,7 @@ mod tests {
     }
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_buffer_ptr_f64(
     #[buffer] input: *const f64,
     #[number] inlen: usize,
@@ -1641,7 +1641,7 @@ mod tests {
     Ok(())
   }
 
-  #[op]
+  #[op2]
   pub fn op_buffer_jsbuffer(
     #[buffer] input: JsBuffer,
     #[number] inlen: usize,
@@ -1672,7 +1672,7 @@ mod tests {
     Ok(())
   }
 
-  #[op]
+  #[op2]
   pub fn op_buffer_any(#[anybuffer] buffer: &[u8]) -> u32 {
     let mut sum: u32 = 0;
     for i in buffer {
@@ -1726,7 +1726,7 @@ mod tests {
     Ok(())
   }
 
-  #[op]
+  #[op2]
   pub fn op_buffer_any_length(#[anybuffer] buffer: &[u8]) -> u32 {
     buffer.len() as _
   }
@@ -1777,7 +1777,7 @@ mod tests {
     Ok(())
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_arraybuffer_slice(
     #[arraybuffer] input: &[u8],
     #[number] inlen: usize,
@@ -1813,7 +1813,7 @@ mod tests {
   }
 
   // TODO(mmastrac): This is a dangerous op that we'll use to test resizable buffers in a later pass.
-  #[op(fast)]
+  #[op2(fast)]
   pub fn op_buffer_slice_unsafe_callback(
     scope: &mut v8::HandleScope,
     buffer: v8::Local<v8::ArrayBuffer>,
@@ -1843,7 +1843,7 @@ mod tests {
 
   /// Ensures that three copies are independent. Note that we cannot mutate the
   /// `bytes::Bytes`.
-  #[op(fast)]
+  #[op2(fast)]
   #[allow(clippy::boxed_local)] // Clippy bug? It warns about input2
   pub fn op_buffer_copy(
     #[buffer(copy)] mut input1: Vec<u8>,
@@ -1874,7 +1874,7 @@ mod tests {
     Ok(())
   }
 
-  #[op]
+  #[op2]
   #[buffer]
   pub fn op_buffer_bytesmut() -> BytesMut {
     let mut buffer = BytesMut::new();
@@ -1901,13 +1901,13 @@ mod tests {
 
   impl GarbageCollected for TestResource {}
 
-  #[op]
+  #[op2]
   #[cppgc]
   pub fn op_test_make_cppgc_resource() -> TestResource {
     TestResource { value: 42 }
   }
 
-  #[op]
+  #[op2]
   #[cppgc]
   pub fn op_test_make_cppgc_resource_option(
     create: bool,
@@ -1919,7 +1919,7 @@ mod tests {
     }
   }
 
-  #[op(async)]
+  #[op2(async)]
   #[smi]
   pub async fn op_test_get_cppgc_resource(
     #[cppgc] resource: &TestResource,
@@ -1928,7 +1928,7 @@ mod tests {
     resource.value
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   #[smi]
   pub fn op_test_get_cppgc_resource_option(
     #[cppgc] resource: Option<&TestResource>,
@@ -1961,12 +1961,12 @@ mod tests {
 
   static STRING: &str = "hello world";
 
-  #[op(fast)]
+  #[op2(fast)]
   fn op_external_make() -> *const std::ffi::c_void {
     STRING.as_ptr() as _
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   fn op_external_process(
     input: *const std::ffi::c_void,
   ) -> *const std::ffi::c_void {
@@ -1984,12 +1984,12 @@ mod tests {
     Ok(())
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   fn op_external_make_ptr(#[bigint] value: u64) -> *const std::ffi::c_void {
     value as _
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   fn op_external_process_ptr(
     input: *const std::ffi::c_void,
     #[number] offset: isize,
@@ -2017,19 +2017,19 @@ mod tests {
 
   external!(ExternalObject, "test external object");
 
-  #[op(fast)]
+  #[op2(fast)]
   fn op_typed_external() -> *const std::ffi::c_void {
     // This operation is safe because we know
     ExternalPointer::new(ExternalObject(RefCell::new(42))).into_raw()
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   fn op_typed_external_process(ptr: *const std::ffi::c_void) {
     let ptr = ExternalPointer::<ExternalObject>::from_raw(ptr);
     *(unsafe { ptr.unsafely_deref() }.0.borrow_mut()) += 1;
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   fn op_typed_external_take(ptr: *const std::ffi::c_void) -> u32 {
     let ptr = ExternalPointer::<ExternalObject>::from_raw(ptr);
     *unsafe { ptr.unsafely_take() }.0.borrow()
@@ -2045,13 +2045,13 @@ mod tests {
     Ok(())
   }
 
-  #[op(nofast)]
+  #[op2(nofast)]
   fn op_isolate_run_microtasks(isolate: *mut v8::Isolate) {
     // SAFETY: testing
     unsafe { isolate.as_mut().unwrap().perform_microtask_checkpoint() };
   }
 
-  #[op(nofast)]
+  #[op2(nofast)]
   fn op_isolate_queue_microtask(
     isolate: *mut v8::Isolate,
     cb: v8::Local<v8::Function>,
@@ -2070,7 +2070,7 @@ mod tests {
     Ok(())
   }
 
-  #[op(async)]
+  #[op2(async)]
   async fn op_async_void() {}
 
   #[tokio::test]
@@ -2080,19 +2080,19 @@ mod tests {
     Ok(())
   }
 
-  #[op(async)]
+  #[op2(async)]
   async fn op_async_number(x: u32) -> u32 {
     x
   }
 
-  #[op(async)]
+  #[op2(async)]
   async fn op_async_add(x: u32, y: u32) -> u32 {
     x.wrapping_add(y)
   }
 
   // Note: #[smi] parameters are signed in JS regardless of the sign in Rust. Overflow and underflow
   // of valid ranges result in automatic wrapping.
-  #[op(async)]
+  #[op2(async)]
   #[smi]
   async fn op_async_add_smi(#[smi] x: u32, #[smi] y: u32) -> u32 {
     tokio::time::sleep(Duration::from_millis(10)).await;
@@ -2129,12 +2129,12 @@ mod tests {
     Ok(())
   }
 
-  #[op(async)]
+  #[op2(async)]
   async fn op_async_sleep() {
     tokio::time::sleep(Duration::from_millis(500)).await
   }
 
-  #[op(async)]
+  #[op2(async)]
   fn op_async_sleep_impl() -> impl Future<Output = ()> {
     tokio::time::sleep(Duration::from_millis(500))
   }
@@ -2147,7 +2147,7 @@ mod tests {
     Ok(())
   }
 
-  #[op(async)]
+  #[op2(async)]
   pub async fn op_async_sleep_error() -> Result<(), Error> {
     tokio::time::sleep(Duration::from_millis(500)).await;
     bail!("whoops")
@@ -2165,12 +2165,12 @@ mod tests {
     Ok(())
   }
 
-  #[op(async(deferred), fast)]
+  #[op2(async(deferred), fast)]
   pub async fn op_async_deferred_success() -> Result<u32, Error> {
     Ok(42)
   }
 
-  #[op(async(deferred), fast)]
+  #[op2(async(deferred), fast)]
   pub async fn op_async_deferred_error() -> Result<(), Error> {
     bail!("whoops")
   }
@@ -2193,12 +2193,12 @@ mod tests {
     Ok(())
   }
 
-  #[op(async(lazy), fast)]
+  #[op2(async(lazy), fast)]
   pub async fn op_async_lazy_success() -> Result<u32, Error> {
     Ok(42)
   }
 
-  #[op(async(lazy), fast)]
+  #[op2(async(lazy), fast)]
   pub async fn op_async_lazy_error() -> Result<(), Error> {
     bail!("whoops")
   }
@@ -2222,7 +2222,7 @@ mod tests {
 
   /// Test exits from the three possible routes -- before future, future immediate,
   /// future polled failed, future polled success.
-  #[op(async)]
+  #[op2(async)]
   pub fn op_async_result_impl(
     mode: u8,
   ) -> Result<impl Future<Output = Result<(), Error>>, Error> {
@@ -2261,7 +2261,7 @@ mod tests {
     Ok(())
   }
 
-  #[op(async)]
+  #[op2(async)]
   pub async fn op_async_state_rc(
     state: Rc<RefCell<OpState>>,
     value: u32,
@@ -2281,13 +2281,13 @@ mod tests {
     Ok(())
   }
 
-  #[op(async)]
+  #[op2(async)]
   #[buffer]
   async fn op_async_buffer(#[buffer] input: JsBuffer) -> JsBuffer {
     input
   }
 
-  #[op(async)]
+  #[op2(async)]
   #[buffer]
   async fn op_async_buffer_vec(#[buffer] input: JsBuffer) -> Vec<u8> {
     let mut output = input.to_vec();
@@ -2295,7 +2295,7 @@ mod tests {
     output
   }
 
-  #[op(async)]
+  #[op2(async)]
   fn op_async_buffer_impl(#[buffer] input: &[u8]) -> impl Future<Output = u32> {
     let l = input.len();
     async move { l as _ }
@@ -2325,7 +2325,7 @@ mod tests {
     Ok(())
   }
 
-  #[op(async)]
+  #[op2(async)]
   async fn op_async_external(
     input: *const std::ffi::c_void,
   ) -> *const std::ffi::c_void {
@@ -2345,7 +2345,7 @@ mod tests {
     Ok(())
   }
 
-  #[op(async)]
+  #[op2(async)]
   #[serde]
   pub async fn op_async_serde_option_v8(
     #[serde] mut serde: Serde,
@@ -2366,7 +2366,7 @@ mod tests {
     Ok(())
   }
 
-  #[op]
+  #[op2]
   #[to_v8]
   pub fn op_smi_to_from_v8(#[from_v8] value: Smi<i32>) -> Smi<i32> {
     value
@@ -2386,7 +2386,7 @@ mod tests {
     Ok(())
   }
 
-  #[op]
+  #[op2]
   #[to_v8]
   pub fn op_number_to_from_v8(#[from_v8] value: Number<f64>) -> Number<f64> {
     value
@@ -2445,7 +2445,7 @@ mod tests {
     }
   }
 
-  #[op]
+  #[op2]
   #[to_v8]
   fn op_bool_to_from_v8(#[from_v8] value: Bool) -> Bool {
     value
diff --git a/core/runtime/ops_rust_to_v8.rs b/core/runtime/ops_rust_to_v8.rs
index f2c0c9c..51cc18a 100644
--- a/core/runtime/ops_rust_to_v8.rs
+++ b/core/runtime/ops_rust_to_v8.rs
@@ -17,10 +17,10 @@
 //! the `set(v8::Local<v8::Value>)` function) is not possible. Moreover, converting a Rust string to a `v8::String`
 //! might fail, particularly if its size surpasses v8's limitations.
 //!
-//! The `#[op]` proc macro maps the distinct calling patterns to the appropriate trait interfaces.
+//! The `#[op2]` proc macro maps the distinct calling patterns to the appropriate trait interfaces.
 //! This mapping accounts for conversion nature and potential error occurrences. When a conversion is inherently
-//! expected to succeed, `#[op]` negates the necessity for explicit error checks, potentially boosting execution
-//! efficiency. Furthermore, `#[op]` strives to leverage `v8::ReturnValue` setters when possible, eliminating
+//! expected to succeed, `#[op2]` negates the necessity for explicit error checks, potentially boosting execution
+//! efficiency. Furthermore, `#[op2]` strives to leverage `v8::ReturnValue` setters when possible, eliminating
 //! the need for explicit object handle allocation. This optimization can favorably impact performance and
 //! memory management.
 
diff --git a/ops/README.md b/ops/README.md
index 14bd5b3..7f71fb9 100644
--- a/ops/README.md
+++ b/ops/README.md
@@ -3,10 +3,10 @@
 `proc_macro` for generating highly optimized V8 functions from Rust functions.
 
 ```rust,ignore
-use deno_core::{op, extension};
+use deno_core::{op2, extension};
 
 // Declare an op.
-#[op(fast)]
+#[op2(fast)]
 pub fn op_add(a: i32, b: i32) -> i32 {
   a + b
 }
diff --git a/ops/lib.rs b/ops/lib.rs
index 8838643..2b7d4c9 100644
--- a/ops/lib.rs
+++ b/ops/lib.rs
@@ -4,21 +4,21 @@
 use proc_macro::TokenStream;
 use std::error::Error;
 
-mod op;
+mod op2;
 
 /// A macro designed to provide an extremely fast V8->Rust interface layer.
-#[doc = include_str!("op/README.md")]
+#[doc = include_str!("op2/README.md")]
 #[proc_macro_attribute]
-pub fn op(attr: TokenStream, item: TokenStream) -> TokenStream {
-  op_macro(attr, item)
+pub fn op2(attr: TokenStream, item: TokenStream) -> TokenStream {
+  op2_macro(attr, item)
 }
 
-fn op_macro(attr: TokenStream, item: TokenStream) -> TokenStream {
-  match crate::op::op(attr.into(), item.into()) {
+fn op2_macro(attr: TokenStream, item: TokenStream) -> TokenStream {
+  match crate::op2::op2(attr.into(), item.into()) {
     Ok(output) => output.into(),
     Err(err) => {
       let mut err: &dyn Error = &err;
-      let mut output = "Failed to parse #[op]:\n".to_owned();
+      let mut output = "Failed to parse #[op2]:\n".to_owned();
       loop {
         output += &format!(" - {err}\n");
         if let Some(source) = err.source() {
diff --git a/ops/op/README.md b/ops/op2/README.md
similarity index 98%
rename from ops/op/README.md
rename to ops/op2/README.md
index 90caef3..77b4025 100644
--- a/ops/op/README.md
+++ b/ops/op2/README.md
@@ -1,4 +1,6 @@
-# op
+# op2
+
+`#[op2]` is the in-progress replacement for `#[op]`.
 
 ## Strings
 
@@ -77,13 +79,13 @@ still happen on a slow path.
 
 ## fastcalls
 
-`op` requires fastcall-compatible ops to be annotated with `fast`. If you wish
+`op2` requires fastcall-compatible ops to be annotated with `fast`. If you wish
 to avoid fastcalls for some reason (this is unlikely), you can specify `nofast`
 instead.
 
 You may also choose an alternate op function to use as the fastcall equivalent
 to a slow function. In this case, you can specify `fast(op_XYZ)`. The other op
-must be decorated with `#[op(fast)]`, and does not need to be registered. When
+must be decorated with `#[op2(fast)]`, and does not need to be registered. When
 v8 optimized the slow function to a fastcall, it will switch the implementation
 over if the parameters are compatible. This is useful for a function that takes
 any buffer type in the slow path and wishes to use the very fast typed `u8`
diff --git a/ops/op/config.rs b/ops/op2/config.rs
similarity index 84%
rename from ops/op/config.rs
rename to ops/op2/config.rs
index b935f89..1b822d2 100644
--- a/ops/op/config.rs
+++ b/ops/op2/config.rs
@@ -4,7 +4,7 @@ use proc_macro2::TokenTree;
 use proc_macro_rules::rules;
 use quote::ToTokens;
 
-use crate::op::OpError;
+use crate::op2::Op2Error;
 
 #[derive(Debug, Default, Eq, PartialEq)]
 pub(crate) struct MacroConfig {
@@ -42,7 +42,7 @@ impl MacroConfig {
   fn from_token_trees(
     flags: Vec<TokenTree>,
     args: Vec<Option<Vec<impl ToTokens>>>,
-  ) -> Result<Self, OpError> {
+  ) -> Result<Self, Op2Error> {
     let flags = flags.into_iter().zip(args).map(|(flag, args)| {
       if let Some(args) = args {
         let args = args
@@ -61,7 +61,7 @@ impl MacroConfig {
   /// Parses a list of string flags.
   pub fn from_flags(
     flags: impl IntoIterator<Item = String>,
-  ) -> Result<Self, OpError> {
+  ) -> Result<Self, Op2Error> {
     let mut config: MacroConfig = Self::default();
     let flags = flags.into_iter().collect::<Vec<_>>();
 
@@ -69,7 +69,7 @@ impl MacroConfig {
     let mut flags_sorted = flags.clone();
     flags_sorted.sort();
     if flags != flags_sorted {
-      return Err(OpError::ImproperlySortedAttribute(flags_sorted.join(", ")));
+      return Err(Op2Error::ImproperlySortedAttribute(flags_sorted.join(", ")));
     }
 
     for flag in flags {
@@ -97,7 +97,7 @@ impl MacroConfig {
             }
           })
         })
-        .map_err(|_| OpError::PatternMatchFailed("attribute", flag))?
+        .map_err(|_| Op2Error::PatternMatchFailed("attribute", flag))?
         .collect::<Vec<_>>();
       } else if flag == "nofast" {
         config.nofast = true;
@@ -125,42 +125,42 @@ impl MacroConfig {
             }
           })
         })
-        .map_err(|_| OpError::PatternMatchFailed("attribute", flag))?;
+        .map_err(|_| Op2Error::PatternMatchFailed("attribute", flag))?;
       } else {
-        return Err(OpError::InvalidAttribute(flag));
+        return Err(Op2Error::InvalidAttribute(flag));
       }
     }
 
     // Test for invalid attribute combinations
     if config.fast && config.nofast {
-      return Err(OpError::InvalidAttributeCombination("fast", "nofast"));
+      return Err(Op2Error::InvalidAttributeCombination("fast", "nofast"));
     }
     if config.fast && !config.fast_alternatives.is_empty() {
-      return Err(OpError::InvalidAttributeCombination("fast", "fast(...)"));
+      return Err(Op2Error::InvalidAttributeCombination("fast", "fast(...)"));
     }
     if config.fast_alternatives.len() > 1 {
-      return Err(OpError::TooManyFastAlternatives);
+      return Err(Op2Error::TooManyFastAlternatives);
     }
     if config.fast
       && (config.r#async && !config.async_lazy && !config.async_deferred)
     {
-      return Err(OpError::InvalidAttributeCombination("fast", "async"));
+      return Err(Op2Error::InvalidAttributeCombination("fast", "async"));
     }
     if config.nofast
       && (config.r#async && !config.async_lazy && !config.async_deferred)
     {
-      return Err(OpError::InvalidAttributeCombination("nofast", "async"));
+      return Err(Op2Error::InvalidAttributeCombination("nofast", "async"));
     }
     if config.no_side_effects
       && (config.r#async && !config.async_lazy && !config.async_deferred)
     {
-      return Err(OpError::InvalidAttributeCombination(
+      return Err(Op2Error::InvalidAttributeCombination(
         "no_side_effects",
         "async",
       ));
     }
     if config.no_side_effects && config.reentrant {
-      return Err(OpError::InvalidAttributeCombination(
+      return Err(Op2Error::InvalidAttributeCombination(
         "no_side_effects",
         "reentrant",
       ));
@@ -169,9 +169,9 @@ impl MacroConfig {
     Ok(config)
   }
 
-  /// Parses the attribute parameters that `proc_macro` passes to the macro. For `#[op(arg1, arg2)]`, the
+  /// Parses the attribute parameters that `proc_macro` passes to the macro. For `#[op2(arg1, arg2)]`, the
   /// tokens will be `arg1, arg2`.
-  pub fn from_tokens(tokens: TokenStream) -> Result<Self, OpError> {
+  pub fn from_tokens(tokens: TokenStream) -> Result<Self, Op2Error> {
     let attr_string = tokens.to_string();
 
     let config = std::panic::catch_unwind(|| {
@@ -187,12 +187,12 @@ impl MacroConfig {
         }
       })
     })
-    .map_err(|_| OpError::PatternMatchFailed("attribute", attr_string))??;
+    .map_err(|_| Op2Error::PatternMatchFailed("attribute", attr_string))??;
     Ok(config)
   }
 
   #[cfg(test)]
-  fn from_token_tree(tokens: TokenTree) -> Result<Self, OpError> {
+  fn from_token_tree(tokens: TokenTree) -> Result<Self, Op2Error> {
     let attr_string = tokens.to_string();
 
     let config = std::panic::catch_unwind(|| {
@@ -202,20 +202,20 @@ impl MacroConfig {
         }
       })
     })
-    .map_err(|_| OpError::PatternMatchFailed("attribute", attr_string))??;
+    .map_err(|_| Op2Error::PatternMatchFailed("attribute", attr_string))??;
     Ok(config)
   }
 
-  /// If the attribute matches #[op(...)] or #[op], returns `Some(MacroConfig)`, otherwise returns `None`.
+  /// If the attribute matches #[op2(...)] or #[op2], returns `Some(MacroConfig)`, otherwise returns `None`.
   #[cfg(test)]
   pub fn from_maybe_attribute_tokens(
     tokens: TokenStream,
-  ) -> Result<Option<Self>, OpError> {
+  ) -> Result<Option<Self>, Op2Error> {
     rules!(tokens => {
-      (#[op]) => {
+      (#[op2]) => {
         Ok(Some(MacroConfig::default()))
       }
-      (#[op $flags:tt ]) => {
+      (#[op2 $flags:tt ]) => {
         Ok(Some(MacroConfig::from_token_tree(flags)?))
       }
       (#[$_attr:meta]) => {
@@ -232,7 +232,7 @@ mod tests {
   use syn::Meta;
 
   fn test_parse(s: &str, expected: MacroConfig) {
-    let item_fn = syn::parse_str::<ItemFn>(&format!("#[op{s}] fn x() {{ }}"))
+    let item_fn = syn::parse_str::<ItemFn>(&format!("#[op2{s}] fn x() {{ }}"))
       .expect("Failed to parse function");
     let attr = item_fn.attrs.first().unwrap();
     let config =
diff --git a/ops/op/dispatch_async.rs b/ops/op2/dispatch_async.rs
similarity index 100%
rename from ops/op/dispatch_async.rs
rename to ops/op2/dispatch_async.rs
diff --git a/ops/op/dispatch_fast.rs b/ops/op2/dispatch_fast.rs
similarity index 99%
rename from ops/op/dispatch_fast.rs
rename to ops/op2/dispatch_fast.rs
index ccc29a0..19fb568 100644
--- a/ops/op/dispatch_fast.rs
+++ b/ops/op2/dispatch_fast.rs
@@ -18,7 +18,7 @@ use super::signature::Special;
 use super::signature::Strings;
 use super::V8MappingError;
 use super::V8SignatureMappingError;
-use crate::op::dispatch_async::map_async_return_type;
+use crate::op2::dispatch_async::map_async_return_type;
 use proc_macro2::Ident;
 use proc_macro2::TokenStream;
 use quote::format_ident;
diff --git a/ops/op/dispatch_shared.rs b/ops/op2/dispatch_shared.rs
similarity index 100%
rename from ops/op/dispatch_shared.rs
rename to ops/op2/dispatch_shared.rs
diff --git a/ops/op/dispatch_slow.rs b/ops/op2/dispatch_slow.rs
similarity index 100%
rename from ops/op/dispatch_slow.rs
rename to ops/op2/dispatch_slow.rs
diff --git a/ops/op/generator_state.rs b/ops/op2/generator_state.rs
similarity index 100%
rename from ops/op/generator_state.rs
rename to ops/op2/generator_state.rs
diff --git a/ops/op/mod.rs b/ops/op2/mod.rs
similarity index 94%
rename from ops/op/mod.rs
rename to ops/op2/mod.rs
index 3b9dd0d..0826442 100644
--- a/ops/op/mod.rs
+++ b/ops/op2/mod.rs
@@ -37,7 +37,7 @@ pub mod signature;
 pub mod signature_retval;
 
 #[derive(Debug, Error)]
-pub enum OpError {
+pub enum Op2Error {
   #[error("Failed to match a pattern for '{0}': (input was '{1}')")]
   PatternMatchFailed(&'static str, String),
   #[error("Invalid attribute: '{0}'")]
@@ -79,23 +79,24 @@ pub enum V8SignatureMappingError {
 
 pub type V8MappingError = &'static str;
 
-/// Generate the op macro expansion.
-pub(crate) fn op(
+/// Generate the op2 macro expansion.
+pub(crate) fn op2(
   attr: TokenStream,
   item: TokenStream,
-) -> Result<TokenStream, OpError> {
+) -> Result<TokenStream, Op2Error> {
   let Ok(func) = parse2::<ItemFn>(item.clone()) else {
     let impl_block = parse2::<syn::ItemImpl>(item)?;
     return object_wrap::generate_impl_ops(impl_block);
   };
+
   let config = MacroConfig::from_tokens(attr)?;
-  generate_op(config, func)
+  generate_op2(config, func)
 }
 
-pub(crate) fn generate_op(
+pub(crate) fn generate_op2(
   config: MacroConfig,
   mut func: ItemFn,
-) -> Result<TokenStream, OpError> {
+) -> Result<TokenStream, Op2Error> {
   // Create a copy of the original function, named "call"
   let call = Ident::new("call", Span::call_site());
   let mut op_fn = func.clone();
@@ -213,8 +214,8 @@ pub(crate) fn generate_op(
   let no_side_effect = config.no_side_effects;
 
   match (is_async, config.r#async) {
-    (true, false) => return Err(OpError::ShouldBeAsync),
-    (false, true) => return Err(OpError::ShouldNotBeAsync),
+    (true, false) => return Err(Op2Error::ShouldBeAsync),
+    (false, true) => return Err(Op2Error::ShouldNotBeAsync),
     _ => {}
   }
 
@@ -233,7 +234,7 @@ pub(crate) fn generate_op(
           && !config.getter
           && !config.setter
         {
-          return Err(OpError::ShouldBeFast);
+          return Err(Op2Error::ShouldBeFast);
         }
         // nofast requires the function to be valid for fast
         if config.nofast || config.getter || config.setter {
@@ -248,10 +249,10 @@ pub(crate) fn generate_op(
       }
       None => {
         if config.fast || config.getter || config.setter {
-          return Err(OpError::ShouldNotBeFast("fast"));
+          return Err(Op2Error::ShouldNotBeFast("fast"));
         }
         if config.nofast {
-          return Err(OpError::ShouldNotBeFast("nofast"));
+          return Err(Op2Error::ShouldNotBeFast("nofast"));
         }
         (quote!(None), quote!(None), quote!())
       }
@@ -315,7 +316,7 @@ pub(crate) fn generate_op(
 
       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_op(
+        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,
@@ -358,12 +359,12 @@ mod tests {
   use syn::File;
   use syn::Item;
 
-  #[testing_macros::fixture("op/test_cases/sync/*.rs")]
+  #[testing_macros::fixture("op2/test_cases/sync/*.rs")]
   fn test_proc_macro_sync(input: PathBuf) {
     test_proc_macro_output(input)
   }
 
-  #[testing_macros::fixture("op/test_cases/async/*.rs")]
+  #[testing_macros::fixture("op2/test_cases/async/*.rs")]
   fn test_proc_macro_async(input: PathBuf) {
     test_proc_macro_output(input)
   }
@@ -403,7 +404,7 @@ deno_ops_compile_test_runner::prelude!();";
           }
         });
         let tokens =
-          generate_op(config.unwrap(), func).expect("Failed to generate op");
+          generate_op2(config.unwrap(), func).expect("Failed to generate op");
         println!("======== Raw tokens ========:\n{}", tokens.clone());
         let tree = syn::parse2(tokens).unwrap();
         let actual = prettyplease::unparse(&tree);
@@ -472,7 +473,7 @@ deno_ops_compile_test_runner::prelude!();";
     let md = include_str!("valid_args.md");
     let separator = "\n<!-- START ARGS -->\n";
     let end_separator = "\n<!-- END ARGS -->\n";
-    let readme = std::fs::read_to_string("op/README.md").unwrap();
+    let readme = std::fs::read_to_string("op2/README.md").unwrap();
     let (header, remainder) = split_readme(&readme, separator, end_separator);
 
     let mut actual = format!("{header}{separator}<table><tr><th>Rust</th><th>Fastcall</th><th>v8</th></tr>\n");
@@ -497,7 +498,7 @@ deno_ops_compile_test_runner::prelude!();";
         let sig = parse_signature(vec![], function.sig.clone())
           .expect("Failed to parse signature");
         println!("Parsed signature: {sig:?}");
-        generate_op(
+        generate_op2(
           MacroConfig {
             fast,
             ..Default::default()
@@ -513,7 +514,7 @@ deno_ops_compile_test_runner::prelude!();";
     actual += remainder;
 
     if update_expected {
-      std::fs::write("op/README.md", actual)
+      std::fs::write("op2/README.md", actual)
         .expect("Failed to write expectation file");
     } else {
       assert_eq!(
@@ -530,7 +531,7 @@ deno_ops_compile_test_runner::prelude!();";
     let md = include_str!("valid_retvals.md");
     let separator = "\n<!-- START RV -->\n";
     let end_separator = "\n<!-- END RV -->\n";
-    let readme = std::fs::read_to_string("op/README.md").unwrap();
+    let readme = std::fs::read_to_string("op2/README.md").unwrap();
     let (header, remainder) = split_readme(&readme, separator, end_separator);
     let mut actual = format!("{header}{separator}<table><tr><th>Rust</th><th>Fastcall</th><th>Async</th><th>v8</th></tr>\n");
 
@@ -555,7 +556,7 @@ deno_ops_compile_test_runner::prelude!();";
         let sig = parse_signature(function.attrs.clone(), function.sig.clone())
           .expect("Failed to parse signature");
         println!("Parsed signature: {sig:?}");
-        generate_op(
+        generate_op2(
           MacroConfig {
             fast,
             ..Default::default()
@@ -572,7 +573,7 @@ deno_ops_compile_test_runner::prelude!();";
             parse_signature(function.attrs.clone(), function.sig.clone())
               .expect("Failed to parse signature");
           println!("Parsed signature: {sig:?}");
-          generate_op(
+          generate_op2(
             MacroConfig {
               r#async: true,
               ..Default::default()
@@ -590,7 +591,7 @@ deno_ops_compile_test_runner::prelude!();";
     actual += remainder;
 
     if update_expected {
-      std::fs::write("op/README.md", actual)
+      std::fs::write("op2/README.md", actual)
         .expect("Failed to write expectation file");
     } else {
       assert_eq!(
diff --git a/ops/op/object_wrap.rs b/ops/op2/object_wrap.rs
similarity index 91%
rename from ops/op/object_wrap.rs
rename to ops/op2/object_wrap.rs
index 0989a39..fc16f49 100644
--- a/ops/op/object_wrap.rs
+++ b/ops/op2/object_wrap.rs
@@ -8,21 +8,21 @@ use syn::ImplItem;
 use syn::ItemFn;
 use syn::ItemImpl;
 
-use crate::op::generate_op;
-use crate::op::MacroConfig;
-use crate::op::OpError;
+use crate::op2::generate_op2;
+use crate::op2::MacroConfig;
+use crate::op2::Op2Error;
 
 // Object wrap for Cppgc-backed objects
 //
 // This module generates the glue code declarations
 // for `impl` blocks to create JS objects in Rust
-// using the op infra.
+// using the op2 infra.
 //
 // ```rust
 // #[op]
 // impl MyObject {
 //    #[constructor] // <-- first attribute defines binding type
-//    #[cppgc]       // <-- attributes for op
+//    #[cppgc]       // <-- attributes for op2
 //    fn new() -> MyObject {
 //      MyObject::new()
 //    }
@@ -69,7 +69,7 @@ use crate::op::OpError;
 //
 pub(crate) fn generate_impl_ops(
   item: ItemImpl,
-) -> Result<TokenStream, OpError> {
+) -> Result<TokenStream, Op2Error> {
   let mut tokens = TokenStream::new();
 
   let self_ty = &item.self_ty;
@@ -104,7 +104,7 @@ pub(crate) fn generate_impl_ops(
       })?;
       if config.constructor {
         if constructor.is_some() {
-          return Err(OpError::MultipleConstructors);
+          return Err(Op2Error::MultipleConstructors);
         }
 
         constructor = Some(ident);
@@ -120,7 +120,7 @@ pub(crate) fn generate_impl_ops(
         config.method = Some(self_ty_ident.clone());
       }
 
-      let op = generate_op(config, func)?;
+      let op = generate_op2(config, func)?;
       tokens.extend(op);
     }
   }
diff --git a/ops/op/signature.rs b/ops/op2/signature.rs
similarity index 100%
rename from ops/op/signature.rs
rename to ops/op2/signature.rs
diff --git a/ops/op/signature_retval.rs b/ops/op2/signature_retval.rs
similarity index 99%
rename from ops/op/signature_retval.rs
rename to ops/op2/signature_retval.rs
index e6b7c34..da85638 100644
--- a/ops/op/signature_retval.rs
+++ b/ops/op2/signature_retval.rs
@@ -1,5 +1,5 @@
 // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
-use crate::op::signature::*;
+use crate::op2::signature::*;
 use proc_macro_rules::rules;
 
 use quote::ToTokens;


Test patch:
diff --git a/.github/workflows/ci-test/action.yml b/.github/workflows/ci-test/action.yml
index bc00322..e446585 100644
--- a/.github/workflows/ci-test/action.yml
+++ b/.github/workflows/ci-test/action.yml
@@ -13,5 +13,5 @@ runs:
       # Only regression tests here for now.
       # Regression test for https://github.com/denoland/deno/pull/19615.
       run: |-
-        cargo run -p deno_core --example op
-        cargo run -p deno_core --example op --features include_js_files_for_snapshotting
+        cargo run -p deno_core --example op2
+        cargo run -p deno_core --example op2 --features include_js_files_for_snapshotting
diff --git a/core/modules/tests.rs b/core/modules/tests.rs
index 81df988..c7186f7 100644
--- a/core/modules/tests.rs
+++ b/core/modules/tests.rs
@@ -30,7 +30,7 @@ use crate::ResolutionKind;
 use crate::RuntimeOptions;
 use anyhow::bail;
 use anyhow::Error;
-use deno_ops::op;
+use deno_ops::op2;
 use futures::future::poll_fn;
 use futures::future::FutureExt;
 use parking_lot::Mutex;
@@ -388,7 +388,7 @@ fn test_mods() {
   let loader = Rc::new(TestingModuleLoader::new(NoopModuleLoader));
   static DISPATCH_COUNT: AtomicUsize = AtomicUsize::new(0);
 
-  #[op(fast)]
+  #[op2(fast)]
   fn op_test(control: u8) -> u8 {
     DISPATCH_COUNT.fetch_add(1, Ordering::Relaxed);
     assert_eq!(control, 42);
diff --git a/core/runtime/tests/error.rs b/core/runtime/tests/error.rs
index 54ba566..82ae74f 100644
--- a/core/runtime/tests/error.rs
+++ b/core/runtime/tests/error.rs
@@ -1,7 +1,7 @@
 // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
 use crate::error::custom_error;
 use crate::error::JsError;
-use crate::op;
+use crate::op2;
 use crate::JsRuntime;
 use crate::RuntimeOptions;
 use anyhow::Error;
@@ -10,7 +10,7 @@ use std::task::Poll;
 
 #[tokio::test]
 async fn test_error_builder() {
-  #[op(fast)]
+  #[op2(fast)]
   fn op_err() -> Result<(), Error> {
     Err(custom_error("DOMExceptionOperationError", "abc"))
   }
diff --git a/core/runtime/tests/jsrealm.rs b/core/runtime/tests/jsrealm.rs
index 879157c..366bb16 100644
--- a/core/runtime/tests/jsrealm.rs
+++ b/core/runtime/tests/jsrealm.rs
@@ -1,7 +1,7 @@
 // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
 use crate::error;
 use crate::modules::StaticModuleLoader;
-use crate::op;
+use crate::op2;
 use crate::JsRuntime;
 use crate::JsRuntimeForSnapshot;
 use crate::RuntimeOptions;
@@ -76,7 +76,7 @@ fn test_set_format_exception_callback_realms() {
 #[tokio::test]
 async fn js_realm_ref_unref_ops() {
   // Never resolves.
-  #[op(async)]
+  #[op2(async)]
   async fn op_pending() {
     futures::future::pending().await
   }
diff --git a/core/runtime/tests/misc.rs b/core/runtime/tests/misc.rs
index c799e40..f92e2cb 100644
--- a/core/runtime/tests/misc.rs
+++ b/core/runtime/tests/misc.rs
@@ -85,7 +85,7 @@ impl WakeRef for LoggingWaker {
 async fn test_wakers_for_async_ops() {
   static STATE: AtomicI8 = AtomicI8::new(0);
 
-  #[op(async)]
+  #[op2(async)]
   async fn op_async_sleep() -> Result<(), Error> {
     STATE.store(1, Ordering::SeqCst);
     tokio::time::sleep(std::time::Duration::from_millis(1)).await;
@@ -643,7 +643,7 @@ fn test_is_proxy() {
 
 #[tokio::test]
 async fn test_set_macrotask_callback_set_next_tick_callback() {
-  #[op(async)]
+  #[op2(async)]
   async fn op_async_sleep() -> Result<(), Error> {
     // Future must be Poll::Pending on first call
     tokio::time::sleep(std::time::Duration::from_millis(1)).await;
@@ -693,13 +693,13 @@ fn test_has_tick_scheduled() {
   static MACROTASK: AtomicUsize = AtomicUsize::new(0);
   static NEXT_TICK: AtomicUsize = AtomicUsize::new(0);
 
-  #[op(fast)]
+  #[op2(fast)]
   fn op_macrotask() -> Result<(), AnyError> {
     MACROTASK.fetch_add(1, Ordering::Relaxed);
     Ok(())
   }
 
-  #[op(fast)]
+  #[op2(fast)]
   fn op_next_tick() -> Result<(), AnyError> {
     NEXT_TICK.fetch_add(1, Ordering::Relaxed);
     Ok(())
@@ -804,7 +804,7 @@ async fn test_promise_rejection_handler_generic(
   case: &'static str,
   error: Option<&'static str>,
 ) {
-  #[op(fast)]
+  #[op2(fast)]
   fn op_breakpoint() {}
 
   deno_core::extension!(test_ext, ops = [op_breakpoint]);
@@ -961,7 +961,7 @@ async fn test_stalled_tla() {
 // Regression test for https://github.com/denoland/deno/issues/20034.
 #[tokio::test]
 async fn test_dynamic_import_module_error_stack() {
-  #[op(async)]
+  #[op2(async)]
   async fn op_async_error() -> Result<(), Error> {
     tokio::time::sleep(std::time::Duration::from_millis(1)).await;
     Err(crate::error::type_error("foo"))
@@ -1007,7 +1007,7 @@ async fn test_dynamic_import_module_error_stack() {
   expected = "Failed to initialize a JsRuntime: Top-level await is not allowed in synchronous evaluation"
 )]
 async fn tla_in_esm_extensions_panics() {
-  #[op(async)]
+  #[op2(async)]
   async fn op_wait(#[number] ms: usize) {
     tokio::time::sleep(Duration::from_millis(ms as u64)).await
   }
@@ -1045,7 +1045,7 @@ async fn tla_in_esm_extensions_panics() {
     at mod:error:3:9"#
 )]
 async fn esm_extensions_throws() {
-  #[op(async)]
+  #[op2(async)]
   async fn op_wait(#[number] ms: usize) {
     tokio::time::sleep(Duration::from_millis(ms as u64)).await
   }
@@ -1183,7 +1183,7 @@ async fn task_spawner_cross_thread_blocking() {
 
 #[tokio::test]
 async fn terminate_execution_run_event_loop_js() {
-  #[op(async)]
+  #[op2(async)]
   async fn op_async_sleep() -> Result<(), Error> {
     tokio::time::sleep(std::time::Duration::from_millis(100)).await;
     Ok(())
diff --git a/core/runtime/tests/mod.rs b/core/runtime/tests/mod.rs
index ffac98c..1d31036 100644
--- a/core/runtime/tests/mod.rs
+++ b/core/runtime/tests/mod.rs
@@ -1,6 +1,6 @@
 // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
 use crate::error::AnyError;
-use crate::op;
+use crate::op2;
 use crate::CrossIsolateStore;
 use crate::JsRuntime;
 use crate::OpState;
@@ -31,7 +31,7 @@ struct TestState {
 }
 
 #[allow(clippy::await_holding_refcell_ref)] // False positive.
-#[op(async)]
+#[op2(async)]
 async fn op_test(
   rc_op_state: Rc<RefCell<OpState>>,
   control: u8,
diff --git a/core/runtime/tests/ops.rs b/core/runtime/tests/ops.rs
index e13532f..f0c9be7 100644
--- a/core/runtime/tests/ops.rs
+++ b/core/runtime/tests/ops.rs
@@ -22,7 +22,7 @@ use url::Url;
 async fn test_async_opstate_borrow() {
   struct InnerState(u64);
 
-  #[op(async)]
+  #[op2(async)]
   async fn op_async_borrow(
     op_state: Rc<RefCell<OpState>>,
   ) -> Result<(), Error> {
@@ -60,7 +60,7 @@ async fn test_async_opstate_borrow() {
 
 #[tokio::test]
 async fn test_sync_op_serialize_object_with_numbers_as_keys() {
-  #[op]
+  #[op2]
   fn op_sync_serialize_object_with_numbers_as_keys(
     #[serde] value: serde_json::Value,
   ) -> Result<(), Error> {
@@ -102,7 +102,7 @@ lines: {
 
 #[tokio::test]
 async fn test_async_op_serialize_object_with_numbers_as_keys() {
-  #[op(async)]
+  #[op2(async)]
   async fn op_async_serialize_object_with_numbers_as_keys(
     #[serde] value: serde_json::Value,
   ) -> Result<(), Error> {
@@ -145,7 +145,7 @@ async fn test_async_op_serialize_object_with_numbers_as_keys() {
 
 #[test]
 fn test_op_return_serde_v8_error() {
-  #[op]
+  #[op2]
   #[serde]
   fn op_err() -> Result<std::collections::BTreeMap<u64, u64>, anyhow::Error> {
     Ok([(1, 2), (3, 4)].into_iter().collect()) // Maps can't have non-string keys in serde_v8
@@ -166,7 +166,7 @@ fn test_op_return_serde_v8_error() {
 
 #[test]
 fn test_op_high_arity() {
-  #[op(fast)]
+  #[op2(fast)]
   #[number]
   fn op_add_4(
     #[number] x1: i64,
@@ -191,7 +191,7 @@ fn test_op_high_arity() {
 
 #[test]
 fn test_op_disabled() {
-  #[op(fast)]
+  #[op2(fast)]
   #[number]
   fn op_foo() -> Result<i64, anyhow::Error> {
     Ok(42)
@@ -215,12 +215,12 @@ fn test_op_disabled() {
 
 #[test]
 fn test_op_detached_buffer() {
-  #[op]
+  #[op2]
   fn op_sum_take(#[buffer(detach)] b: JsBuffer) -> Result<u32, anyhow::Error> {
     Ok(b.as_ref().iter().clone().map(|x| *x as u32).sum())
   }
 
-  #[op]
+  #[op2]
   #[buffer]
   fn op_boomerang(
     #[buffer(detach)] b: JsBuffer,
@@ -296,14 +296,14 @@ fn duplicate_op_names() {
   mod a {
     use super::*;
 
-    #[op]
+    #[op2]
     #[string]
     pub fn op_test() -> Result<String, Error> {
       Ok(String::from("Test"))
     }
   }
 
-  #[op]
+  #[op2]
   #[string]
   pub fn op_test() -> Result<String, Error> {
     Ok(String::from("Test"))
@@ -318,13 +318,13 @@ fn duplicate_op_names() {
 
 #[test]
 fn ops_in_js_have_proper_names() {
-  #[op]
+  #[op2]
   #[string]
   fn op_test_sync() -> Result<String, Error> {
     Ok(String::from("Test"))
   }
 
-  #[op(async)]
+  #[op2(async)]
   #[string]
   async fn op_test_async() -> Result<String, Error> {
     Ok(String::from("Test"))
@@ -473,7 +473,7 @@ fn test_call_site() {
 // https://github.com/denoland/deno/issues/19455
 #[tokio::test]
 pub async fn test_top_level_await() {
-  #[op(async)]
+  #[op2(async)]
   async fn op_sleep_forever() {
     tokio::time::sleep(Duration::MAX).await
   }
@@ -528,12 +528,12 @@ await op_void_async_deferred();
   .expect("Failed to get module result");
 }
 
-#[op(async)]
+#[op2(async)]
 pub async fn op_async() {
   println!("op_async!");
 }
 
-#[op(async)]
+#[op2(async)]
 #[allow(unreachable_code)]
 pub fn op_async_impl_future_error() -> Result<impl Future<Output = ()>, AnyError>
 {
@@ -541,51 +541,51 @@ pub fn op_async_impl_future_error() -> Result<impl Future<Output = ()>, AnyError
   Ok(async {})
 }
 
-#[op(async)]
+#[op2(async)]
 pub async fn op_async_yield() {
   tokio::task::yield_now().await;
   println!("op_async_yield!");
 }
 
-#[op(async)]
+#[op2(async)]
 pub async fn op_async_yield_error() -> Result<(), AnyError> {
   tokio::task::yield_now().await;
   println!("op_async_yield_error!");
   bail!("dead");
 }
 
-#[op(async)]
+#[op2(async)]
 pub async fn op_async_error() -> Result<(), AnyError> {
   println!("op_async_error!");
   bail!("dead");
 }
 
-#[op(async(deferred), fast)]
+#[op2(async(deferred), fast)]
 pub async fn op_async_deferred() {
   println!("op_async_deferred!");
 }
 
-#[op(async(lazy), fast)]
+#[op2(async(lazy), fast)]
 pub async fn op_async_lazy() {
   println!("op_async_lazy!");
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_sync() {
   println!("op_sync!");
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_sync_error() -> Result<(), AnyError> {
   bail!("Always fails");
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_sync_arg_error(_: u32) {
   panic!("Should never be called")
 }
 
-#[op(async)]
+#[op2(async)]
 pub async fn op_async_arg_error(_: u32) {
   panic!("Should never be called")
 }
diff --git a/core/runtime/tests/snapshot.rs b/core/runtime/tests/snapshot.rs
index b609434..a7f0ce4 100644
--- a/core/runtime/tests/snapshot.rs
+++ b/core/runtime/tests/snapshot.rs
@@ -231,7 +231,7 @@ fn es_snapshot() {
     }
   }
 
-  #[op]
+  #[op2]
   #[string]
   fn op_test() -> Result<String, Error> {
     Ok(String::from("test"))
@@ -395,13 +395,13 @@ pub(crate) fn es_snapshot_without_runtime_module_loader() {
 
 #[test]
 pub fn snapshot_with_additional_extensions() {
-  #[op]
+  #[op2]
   #[string]
   fn op_before() -> String {
     "before".to_owned()
   }
 
-  #[op]
+  #[op2]
   #[string]
   fn op_after() -> String {
     "after".to_owned()
diff --git a/ops/compile_test_runner/src/lib.rs b/ops/compile_test_runner/src/lib.rs
index 6cf04e2..ed6e361 100644
--- a/ops/compile_test_runner/src/lib.rs
+++ b/ops/compile_test_runner/src/lib.rs
@@ -2,7 +2,7 @@
 #[macro_export]
 macro_rules! prelude {
   () => {
-    use deno_ops::op;
+    use deno_ops::op2;
 
     pub fn main() {}
   };
@@ -13,7 +13,7 @@ mod tests {
   use std::path::PathBuf;
 
   // TODO(mmastrac): It's faster to do things with testing_macros::fixture?
-  #[testing_macros::fixture("../op/test_cases/compiler_pass/*.rs")]
+  #[testing_macros::fixture("../op2/test_cases/compiler_pass/*.rs")]
   fn compile_test(input: PathBuf) {
     let t = trybuild::TestCases::new();
     t.pass(input);
@@ -25,8 +25,8 @@ mod tests {
     // Run all the tests on a nightly build (which should take advantage of cargo's --keep-going to
     // run in parallel: https://github.com/dtolnay/trybuild/pull/168)
     let t = trybuild::TestCases::new();
-    t.pass("../op/test_cases/**/*.rs");
-    t.compile_fail("../op/test_cases_fail/**/*.rs");
+    t.pass("../op2/test_cases/**/*.rs");
+    t.compile_fail("../op2/test_cases_fail/**/*.rs");
   }
 
   #[rustversion::not(nightly)]
@@ -35,8 +35,8 @@ mod tests {
     // Run all the tests if we're in the CI
     if let Ok(true) = std::env::var("CI").map(|s| s == "true") {
       let t = trybuild::TestCases::new();
-      t.compile_fail("../op/test_cases_fail/**/*.rs");
-      t.pass("../op/test_cases/**/*.rs");
+      t.compile_fail("../op2/test_cases_fail/**/*.rs");
+      t.pass("../op2/test_cases/**/*.rs");
     }
   }
 }
diff --git a/ops/op/test_cases/async/async_arg_return.out b/ops/op2/test_cases/async/async_arg_return.out
similarity index 99%
rename from ops/op/test_cases/async/async_arg_return.out
rename to ops/op2/test_cases/async/async_arg_return.out
index e631918..5790f7d 100644
--- a/ops/op/test_cases/async/async_arg_return.out
+++ b/ops/op2/test_cases/async/async_arg_return.out
@@ -6,7 +6,7 @@ pub const fn op_async() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_async {
         const NAME: &'static str = stringify!(op_async);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_async),
             true,
             false,
diff --git a/ops/op/test_cases/async/async_arg_return.rs b/ops/op2/test_cases/async/async_arg_return.rs
similarity index 92%
rename from ops/op/test_cases/async/async_arg_return.rs
rename to ops/op2/test_cases/async/async_arg_return.rs
index 7aa8c67..61c7564 100644
--- a/ops/op/test_cases/async/async_arg_return.rs
+++ b/ops/op2/test_cases/async/async_arg_return.rs
@@ -2,7 +2,7 @@
 #![deny(warnings)]
 deno_ops_compile_test_runner::prelude!();
 
-#[op(async)]
+#[op2(async)]
 pub async fn op_async(x: i32) -> i32 {
   x
 }
diff --git a/ops/op/test_cases/async/async_arg_return_result.out b/ops/op2/test_cases/async/async_arg_return_result.out
similarity index 99%
rename from ops/op/test_cases/async/async_arg_return_result.out
rename to ops/op2/test_cases/async/async_arg_return_result.out
index 05099d5..c26b338 100644
--- a/ops/op/test_cases/async/async_arg_return_result.out
+++ b/ops/op2/test_cases/async/async_arg_return_result.out
@@ -6,7 +6,7 @@ pub const fn op_async() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_async {
         const NAME: &'static str = stringify!(op_async);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_async),
             true,
             false,
diff --git a/ops/op/test_cases/async/async_arg_return_result.rs b/ops/op2/test_cases/async/async_arg_return_result.rs
similarity index 93%
rename from ops/op/test_cases/async/async_arg_return_result.rs
rename to ops/op2/test_cases/async/async_arg_return_result.rs
index 2103763..09ffc64 100644
--- a/ops/op/test_cases/async/async_arg_return_result.rs
+++ b/ops/op2/test_cases/async/async_arg_return_result.rs
@@ -2,7 +2,7 @@
 #![deny(warnings)]
 deno_ops_compile_test_runner::prelude!();
 
-#[op(async)]
+#[op2(async)]
 pub async fn op_async(x: i32) -> std::io::Result<i32> {
   Ok(x)
 }
diff --git a/ops/op/test_cases/async/async_cppgc.out b/ops/op2/test_cases/async/async_cppgc.out
similarity index 99%
rename from ops/op/test_cases/async/async_cppgc.out
rename to ops/op2/test_cases/async/async_cppgc.out
index 75d1b53..c9ccea8 100644
--- a/ops/op/test_cases/async/async_cppgc.out
+++ b/ops/op2/test_cases/async/async_cppgc.out
@@ -6,7 +6,7 @@ const fn op_make_cppgc_object() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_make_cppgc_object {
         const NAME: &'static str = stringify!(op_make_cppgc_object);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_make_cppgc_object),
             true,
             false,
@@ -131,7 +131,7 @@ const fn op_use_cppgc_object() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_use_cppgc_object {
         const NAME: &'static str = stringify!(op_use_cppgc_object);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_use_cppgc_object),
             true,
             false,
@@ -256,7 +256,7 @@ const fn op_use_optional_cppgc_object() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_use_optional_cppgc_object {
         const NAME: &'static str = stringify!(op_use_optional_cppgc_object);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_use_optional_cppgc_object),
             true,
             false,
diff --git a/ops/op/test_cases/async/async_cppgc.rs b/ops/op2/test_cases/async/async_cppgc.rs
similarity index 90%
rename from ops/op/test_cases/async/async_cppgc.rs
rename to ops/op2/test_cases/async/async_cppgc.rs
index 28d9556..c729669 100644
--- a/ops/op/test_cases/async/async_cppgc.rs
+++ b/ops/op2/test_cases/async/async_cppgc.rs
@@ -7,14 +7,14 @@ struct Wrap;
 
 impl GarbageCollected for Wrap {}
 
-#[op(async)]
+#[op2(async)]
 #[cppgc]
 async fn op_make_cppgc_object() -> Wrap {
   Wrap
 }
 
-#[op(async)]
+#[op2(async)]
 async fn op_use_cppgc_object(#[cppgc] _wrap: &Wrap) {}
 
-#[op(async)]
+#[op2(async)]
 async fn op_use_optional_cppgc_object(#[cppgc] _wrap: Option<&Wrap>) {}
diff --git a/ops/op/test_cases/async/async_deferred.out b/ops/op2/test_cases/async/async_deferred.out
similarity index 99%
rename from ops/op/test_cases/async/async_deferred.out
rename to ops/op2/test_cases/async/async_deferred.out
index 8c3065f..7d39aff 100644
--- a/ops/op/test_cases/async/async_deferred.out
+++ b/ops/op2/test_cases/async/async_deferred.out
@@ -6,7 +6,7 @@ pub const fn op_async_deferred() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_async_deferred {
         const NAME: &'static str = stringify!(op_async_deferred);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_async_deferred),
             true,
             false,
diff --git a/ops/op/test_cases/async/async_deferred.rs b/ops/op2/test_cases/async/async_deferred.rs
similarity index 87%
rename from ops/op/test_cases/async/async_deferred.rs
rename to ops/op2/test_cases/async/async_deferred.rs
index ad9fe14..f920f56 100644
--- a/ops/op/test_cases/async/async_deferred.rs
+++ b/ops/op2/test_cases/async/async_deferred.rs
@@ -2,7 +2,7 @@
 #![deny(warnings)]
 deno_ops_compile_test_runner::prelude!();
 
-#[op(async(deferred), fast)]
+#[op2(async(deferred), fast)]
 pub async fn op_async_deferred() -> std::io::Result<i32> {
   Ok(0)
 }
diff --git a/ops/op/test_cases/async/async_jsbuffer.out b/ops/op2/test_cases/async/async_jsbuffer.out
similarity index 99%
rename from ops/op/test_cases/async/async_jsbuffer.out
rename to ops/op2/test_cases/async/async_jsbuffer.out
index cf6c1c0..52b36a0 100644
--- a/ops/op/test_cases/async/async_jsbuffer.out
+++ b/ops/op2/test_cases/async/async_jsbuffer.out
@@ -6,7 +6,7 @@ pub const fn op_async_v8_buffer() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_async_v8_buffer {
         const NAME: &'static str = stringify!(op_async_v8_buffer);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_async_v8_buffer),
             true,
             false,
diff --git a/ops/op/test_cases/async/async_jsbuffer.rs b/ops/op2/test_cases/async/async_jsbuffer.rs
similarity index 94%
rename from ops/op/test_cases/async/async_jsbuffer.rs
rename to ops/op2/test_cases/async/async_jsbuffer.rs
index cd77851..077478c 100644
--- a/ops/op/test_cases/async/async_jsbuffer.rs
+++ b/ops/op2/test_cases/async/async_jsbuffer.rs
@@ -4,7 +4,7 @@ deno_ops_compile_test_runner::prelude!();
 
 use deno_core::JsBuffer;
 
-#[op(async)]
+#[op2(async)]
 #[buffer]
 pub async fn op_async_v8_buffer(#[buffer] buf: JsBuffer) -> JsBuffer {
   buf
diff --git a/ops/op/test_cases/async/async_lazy.out b/ops/op2/test_cases/async/async_lazy.out
similarity index 99%
rename from ops/op/test_cases/async/async_lazy.out
rename to ops/op2/test_cases/async/async_lazy.out
index 07a562b..d6b1f53 100644
--- a/ops/op/test_cases/async/async_lazy.out
+++ b/ops/op2/test_cases/async/async_lazy.out
@@ -6,7 +6,7 @@ pub const fn op_async_lazy() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_async_lazy {
         const NAME: &'static str = stringify!(op_async_lazy);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_async_lazy),
             true,
             false,
diff --git a/ops/op/test_cases/async/async_lazy.rs b/ops/op2/test_cases/async/async_lazy.rs
similarity index 88%
rename from ops/op/test_cases/async/async_lazy.rs
rename to ops/op2/test_cases/async/async_lazy.rs
index c747716..60b78ad 100644
--- a/ops/op/test_cases/async/async_lazy.rs
+++ b/ops/op2/test_cases/async/async_lazy.rs
@@ -2,7 +2,7 @@
 #![deny(warnings)]
 deno_ops_compile_test_runner::prelude!();
 
-#[op(async(lazy), fast)]
+#[op2(async(lazy), fast)]
 pub async fn op_async_lazy() -> std::io::Result<i32> {
   Ok(0)
 }
diff --git a/ops/op/test_cases/async/async_op_metadata.out b/ops/op2/test_cases/async/async_op_metadata.out
similarity index 99%
rename from ops/op/test_cases/async/async_op_metadata.out
rename to ops/op2/test_cases/async/async_op_metadata.out
index 39a2412..bbbb515 100644
--- a/ops/op/test_cases/async/async_op_metadata.out
+++ b/ops/op2/test_cases/async/async_op_metadata.out
@@ -6,7 +6,7 @@ const fn op_blob_read_part() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_blob_read_part {
         const NAME: &'static str = stringify!(op_blob_read_part);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_blob_read_part),
             true,
             false,
@@ -114,7 +114,7 @@ const fn op_broadcast_recv() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_broadcast_recv {
         const NAME: &'static str = stringify!(op_broadcast_recv);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_broadcast_recv),
             true,
             false,
diff --git a/ops/op/test_cases/async/async_op_metadata.rs b/ops/op2/test_cases/async/async_op_metadata.rs
similarity index 94%
rename from ops/op/test_cases/async/async_op_metadata.rs
rename to ops/op2/test_cases/async/async_op_metadata.rs
index 35ce1c3..3f41d58 100644
--- a/ops/op/test_cases/async/async_op_metadata.rs
+++ b/ops/op2/test_cases/async/async_op_metadata.rs
@@ -2,14 +2,14 @@
 #![deny(warnings)]
 deno_ops_compile_test_runner::prelude!();
 
-#[op(async)]
+#[op2(async)]
 #[meta(sanitizer_details = "read from a Blob or File")]
 #[meta(sanitizer_fix = "awaiting the result of a Blob or File read")]
 async fn op_blob_read_part() {
   return;
 }
 
-#[op(async)]
+#[op2(async)]
 #[meta(
   sanitizer_details = "receive a message from a BroadcastChannel",
   sanitizer_fix = "closing the BroadcastChannel"
diff --git a/ops/op/test_cases/async/async_opstate.out b/ops/op2/test_cases/async/async_opstate.out
similarity index 99%
rename from ops/op/test_cases/async/async_opstate.out
rename to ops/op2/test_cases/async/async_opstate.out
index e33c7a1..fe4af77 100644
--- a/ops/op/test_cases/async/async_opstate.out
+++ b/ops/op2/test_cases/async/async_opstate.out
@@ -6,7 +6,7 @@ pub const fn op_async_opstate() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_async_opstate {
         const NAME: &'static str = stringify!(op_async_opstate);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_async_opstate),
             true,
             false,
diff --git a/ops/op/test_cases/async/async_opstate.rs b/ops/op2/test_cases/async/async_opstate.rs
similarity index 95%
rename from ops/op/test_cases/async/async_opstate.rs
rename to ops/op2/test_cases/async/async_opstate.rs
index d60ac21..d94a795 100644
--- a/ops/op/test_cases/async/async_opstate.rs
+++ b/ops/op2/test_cases/async/async_opstate.rs
@@ -6,7 +6,7 @@ use deno_core::OpState;
 use std::cell::RefCell;
 use std::rc::Rc;
 
-#[op(async)]
+#[op2(async)]
 pub async fn op_async_opstate(
   state: Rc<RefCell<OpState>>,
 ) -> std::io::Result<i32> {
diff --git a/ops/op/test_cases/async/async_result.out b/ops/op2/test_cases/async/async_result.out
similarity index 99%
rename from ops/op/test_cases/async/async_result.out
rename to ops/op2/test_cases/async/async_result.out
index ed4e97d..9c26401 100644
--- a/ops/op/test_cases/async/async_result.out
+++ b/ops/op2/test_cases/async/async_result.out
@@ -6,7 +6,7 @@ pub const fn op_async() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_async {
         const NAME: &'static str = stringify!(op_async);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_async),
             true,
             false,
diff --git a/ops/op/test_cases/async/async_result.rs b/ops/op2/test_cases/async/async_result.rs
similarity index 93%
rename from ops/op/test_cases/async/async_result.rs
rename to ops/op2/test_cases/async/async_result.rs
index 6a9a3a6..d2981f9 100644
--- a/ops/op/test_cases/async/async_result.rs
+++ b/ops/op2/test_cases/async/async_result.rs
@@ -2,7 +2,7 @@
 #![deny(warnings)]
 deno_ops_compile_test_runner::prelude!();
 
-#[op(async)]
+#[op2(async)]
 pub async fn op_async() -> std::io::Result<i32> {
   Ok(0)
 }
diff --git a/ops/op/test_cases/async/async_result_impl.out b/ops/op2/test_cases/async/async_result_impl.out
similarity index 99%
rename from ops/op/test_cases/async/async_result_impl.out
rename to ops/op2/test_cases/async/async_result_impl.out
index 8e6b1ad..3b8405d 100644
--- a/ops/op/test_cases/async/async_result_impl.out
+++ b/ops/op2/test_cases/async/async_result_impl.out
@@ -6,7 +6,7 @@ pub const fn op_async_result_impl() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_async_result_impl {
         const NAME: &'static str = stringify!(op_async_result_impl);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_async_result_impl),
             true,
             false,
diff --git a/ops/op/test_cases/async/async_result_impl.rs b/ops/op2/test_cases/async/async_result_impl.rs
similarity index 95%
rename from ops/op/test_cases/async/async_result_impl.rs
rename to ops/op2/test_cases/async/async_result_impl.rs
index 50d9f6e..f07f1be 100644
--- a/ops/op/test_cases/async/async_result_impl.rs
+++ b/ops/op2/test_cases/async/async_result_impl.rs
@@ -5,7 +5,7 @@ deno_ops_compile_test_runner::prelude!();
 use deno_core::error::AnyError;
 use std::future::Future;
 
-#[op(async)]
+#[op2(async)]
 pub fn op_async_result_impl(
   x: i32,
 ) -> Result<impl Future<Output = std::io::Result<i32>>, AnyError> {
diff --git a/ops/op/test_cases/async/async_result_smi.out b/ops/op2/test_cases/async/async_result_smi.out
similarity index 99%
rename from ops/op/test_cases/async/async_result_smi.out
rename to ops/op2/test_cases/async/async_result_smi.out
index ab9f216..046a02f 100644
--- a/ops/op/test_cases/async/async_result_smi.out
+++ b/ops/op2/test_cases/async/async_result_smi.out
@@ -6,7 +6,7 @@ pub const fn op_async() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_async {
         const NAME: &'static str = stringify!(op_async);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_async),
             true,
             false,
diff --git a/ops/op/test_cases/async/async_result_smi.rs b/ops/op2/test_cases/async/async_result_smi.rs
similarity index 95%
rename from ops/op/test_cases/async/async_result_smi.rs
rename to ops/op2/test_cases/async/async_result_smi.rs
index f76fff8..5144b7c 100644
--- a/ops/op/test_cases/async/async_result_smi.rs
+++ b/ops/op2/test_cases/async/async_result_smi.rs
@@ -4,7 +4,7 @@ deno_ops_compile_test_runner::prelude!();
 
 pub type ResourceId = i16;
 
-#[op(async)]
+#[op2(async)]
 #[smi]
 pub async fn op_async(#[smi] rid: ResourceId) -> std::io::Result<ResourceId> {
   Ok(rid as _)
diff --git a/ops/op/test_cases/async/async_stack_trace.out b/ops/op2/test_cases/async/async_stack_trace.out
similarity index 99%
rename from ops/op/test_cases/async/async_stack_trace.out
rename to ops/op2/test_cases/async/async_stack_trace.out
index 969a2a1..91a2c3d 100644
--- a/ops/op/test_cases/async/async_stack_trace.out
+++ b/ops/op2/test_cases/async/async_stack_trace.out
@@ -6,7 +6,7 @@ pub const fn op_async_stack_trace() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_async_stack_trace {
         const NAME: &'static str = stringify!(op_async_stack_trace);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_async_stack_trace),
             true,
             false,
diff --git a/ops/op/test_cases/async/async_stack_trace.rs b/ops/op2/test_cases/async/async_stack_trace.rs
similarity index 86%
rename from ops/op/test_cases/async/async_stack_trace.rs
rename to ops/op2/test_cases/async/async_stack_trace.rs
index ed6e539..5aaaa97 100644
--- a/ops/op/test_cases/async/async_stack_trace.rs
+++ b/ops/op2/test_cases/async/async_stack_trace.rs
@@ -2,5 +2,5 @@
 #![deny(warnings)]
 deno_ops_compile_test_runner::prelude!();
 
-#[op(async, stack_trace)]
+#[op2(async, stack_trace)]
 pub async fn op_async_stack_trace() {}
diff --git a/ops/op/test_cases/async/async_v8_global.out b/ops/op2/test_cases/async/async_v8_global.out
similarity index 99%
rename from ops/op/test_cases/async/async_v8_global.out
rename to ops/op2/test_cases/async/async_v8_global.out
index 0d3c2e1..9ba3b09 100644
--- a/ops/op/test_cases/async/async_v8_global.out
+++ b/ops/op2/test_cases/async/async_v8_global.out
@@ -6,7 +6,7 @@ pub const fn op_async_v8_global() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_async_v8_global {
         const NAME: &'static str = stringify!(op_async_v8_global);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_async_v8_global),
             true,
             false,
diff --git a/ops/op/test_cases/async/async_v8_global.rs b/ops/op2/test_cases/async/async_v8_global.rs
similarity index 94%
rename from ops/op/test_cases/async/async_v8_global.rs
rename to ops/op2/test_cases/async/async_v8_global.rs
index b218263..865e34f 100644
--- a/ops/op/test_cases/async/async_v8_global.rs
+++ b/ops/op2/test_cases/async/async_v8_global.rs
@@ -4,5 +4,5 @@ deno_ops_compile_test_runner::prelude!();
 
 use deno_core::v8;
 
-#[op(async)]
+#[op2(async)]
 pub async fn op_async_v8_global(#[global] _s: v8::Global<v8::String>) {}
diff --git a/ops/op/test_cases/async/async_void.out b/ops/op2/test_cases/async/async_void.out
similarity index 99%
rename from ops/op/test_cases/async/async_void.out
rename to ops/op2/test_cases/async/async_void.out
index 8bc480f..79082d4 100644
--- a/ops/op/test_cases/async/async_void.out
+++ b/ops/op2/test_cases/async/async_void.out
@@ -6,7 +6,7 @@ pub const fn op_async() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_async {
         const NAME: &'static str = stringify!(op_async);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_async),
             true,
             false,
diff --git a/ops/op/test_cases/async/async_void.rs b/ops/op2/test_cases/async/async_void.rs
similarity index 92%
rename from ops/op/test_cases/async/async_void.rs
rename to ops/op2/test_cases/async/async_void.rs
index 33f7830..2c825e8 100644
--- a/ops/op/test_cases/async/async_void.rs
+++ b/ops/op2/test_cases/async/async_void.rs
@@ -2,5 +2,5 @@
 #![deny(warnings)]
 deno_ops_compile_test_runner::prelude!();
 
-#[op(async)]
+#[op2(async)]
 pub async fn op_async() {}
diff --git a/ops/op/test_cases/compiler_pass/async.rs b/ops/op2/test_cases/compiler_pass/async.rs
similarity index 89%
rename from ops/op/test_cases/compiler_pass/async.rs
rename to ops/op2/test_cases/compiler_pass/async.rs
index 0573ebf..9918fe2 100644
--- a/ops/op/test_cases/compiler_pass/async.rs
+++ b/ops/op2/test_cases/compiler_pass/async.rs
@@ -11,50 +11,50 @@ use std::rc::Rc;
 
 // Collect a few examples that we'll smoke test when not running on the CI.
 
-#[op(async)]
+#[op2(async)]
 pub async fn op_async1() {}
 
-#[op(async)]
+#[op2(async)]
 pub async fn op_async2(x: i32) -> i32 {
   x
 }
 
-#[op(async)]
+#[op2(async)]
 pub async fn op_async3(x: i32) -> std::io::Result<i32> {
   Ok(x)
 }
 
-#[op(async)]
+#[op2(async)]
 pub fn op_async4(x: i32) -> Result<impl Future<Output = i32>, AnyError> {
   Ok(async move { x })
 }
 
-#[op(async)]
+#[op2(async)]
 pub fn op_async5(
   x: i32,
 ) -> Result<impl Future<Output = std::io::Result<i32>>, AnyError> {
   Ok(async move { Ok(x) })
 }
 
-#[op(async)]
+#[op2(async)]
 pub async fn op_async6(x: f32) -> f32 {
   x
 }
 
-#[op(async)]
+#[op2(async)]
 pub async fn op_async_opstate(
   state: Rc<RefCell<OpState>>,
 ) -> std::io::Result<i32> {
   Ok(*state.borrow().borrow::<i32>())
 }
 
-#[op(async)]
+#[op2(async)]
 #[buffer]
 pub async fn op_async_buffer(#[buffer] buf: JsBuffer) -> JsBuffer {
   buf
 }
 
-#[op(async)]
+#[op2(async)]
 #[string]
 pub async fn op_async_string(#[string] s: String) -> String {
   s
diff --git a/ops/op/test_cases/compiler_pass/sync.rs b/ops/op2/test_cases/compiler_pass/sync.rs
similarity index 89%
rename from ops/op/test_cases/compiler_pass/sync.rs
rename to ops/op2/test_cases/compiler_pass/sync.rs
index ac93324..62b24cf 100644
--- a/ops/op/test_cases/compiler_pass/sync.rs
+++ b/ops/op2/test_cases/compiler_pass/sync.rs
@@ -6,30 +6,30 @@ use deno_core::v8;
 
 // Collect a few examples that we'll smoke test when not running on the CI.
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_fast(x: u32) -> u32 {
   x
 }
 
-#[op(fast)]
+#[op2(fast)]
 fn op_buffers(#[buffer] _a: &[u8], #[buffer(copy)] _b: Vec<u8>) {}
 
 struct Something {}
 
-#[op(fast)]
+#[op2(fast)]
 fn op_state_rc(
   #[state] _arg: &Something,
   #[state] _arg_opt: Option<&Something>,
 ) {
 }
 
-#[op(fast)]
+#[op2(fast)]
 fn op_v8_1(_s: v8::Local<v8::String>) {}
 
-#[op(fast)]
+#[op2(fast)]
 fn op_v8_2(_s: &v8::String) {}
 
-#[op]
+#[op2]
 fn op_v8_3(#[global] _s: v8::Global<v8::String>) {}
 
 pub type Int16 = i16;
@@ -37,7 +37,7 @@ pub type Int32 = i32;
 pub type Uint16 = u16;
 pub type Uint32 = u32;
 
-#[op(fast)]
+#[op2(fast)]
 #[smi]
 fn op_smi_unsigned_return(
   #[smi] a: Int16,
@@ -48,7 +48,7 @@ fn op_smi_unsigned_return(
   a as Uint32 + b as Uint32 + c as Uint32 + d as Uint32
 }
 
-#[op(fast)]
+#[op2(fast)]
 #[smi]
 fn op_smi_signed_return(
   #[smi] a: Int16,
@@ -59,5 +59,5 @@ fn op_smi_signed_return(
   a as Int32 + b as Int32 + c as Int32 + d as Int32
 }
 
-#[op(fast, stack_trace)]
+#[op2(fast, stack_trace)]
 fn op_stack_trace(#[string] _: String) {}
diff --git a/ops/op/test_cases/sync/add.out b/ops/op2/test_cases/sync/add.out
similarity index 99%
rename from ops/op/test_cases/sync/add.out
rename to ops/op2/test_cases/sync/add.out
index bfc523f..62459d7 100644
--- a/ops/op/test_cases/sync/add.out
+++ b/ops/op2/test_cases/sync/add.out
@@ -6,7 +6,7 @@ const fn op_add() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_add {
         const NAME: &'static str = stringify!(op_add);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_add),
             false,
             false,
diff --git a/ops/op/test_cases/sync/add.rs b/ops/op2/test_cases/sync/add.rs
similarity index 93%
rename from ops/op/test_cases/sync/add.rs
rename to ops/op2/test_cases/sync/add.rs
index 44fb81f..4b03f81 100644
--- a/ops/op/test_cases/sync/add.rs
+++ b/ops/op2/test_cases/sync/add.rs
@@ -2,7 +2,7 @@
 #![deny(warnings)]
 deno_ops_compile_test_runner::prelude!();
 
-#[op(fast)]
+#[op2(fast)]
 fn op_add(a: u32, b: u32) -> u32 {
   a + b
 }
diff --git a/ops/op/test_cases/sync/add_options.out b/ops/op2/test_cases/sync/add_options.out
similarity index 99%
rename from ops/op/test_cases/sync/add_options.out
rename to ops/op2/test_cases/sync/add_options.out
index 7162be0..53f11d3 100644
--- a/ops/op/test_cases/sync/add_options.out
+++ b/ops/op2/test_cases/sync/add_options.out
@@ -6,7 +6,7 @@ pub const fn op_test_add_option() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_test_add_option {
         const NAME: &'static str = stringify!(op_test_add_option);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_test_add_option),
             false,
             false,
diff --git a/ops/op/test_cases/sync/add_options.rs b/ops/op2/test_cases/sync/add_options.rs
similarity index 96%
rename from ops/op/test_cases/sync/add_options.rs
rename to ops/op2/test_cases/sync/add_options.rs
index f518579..b24bd03 100644
--- a/ops/op/test_cases/sync/add_options.rs
+++ b/ops/op2/test_cases/sync/add_options.rs
@@ -2,7 +2,7 @@
 #![deny(warnings)]
 deno_ops_compile_test_runner::prelude!();
 
-#[op]
+#[op2]
 pub fn op_test_add_option(a: u32, b: Option<u32>) -> u32 {
   a + b.unwrap_or(100)
 }
diff --git a/ops/op/test_cases/sync/bigint.out b/ops/op2/test_cases/sync/bigint.out
similarity index 99%
rename from ops/op/test_cases/sync/bigint.out
rename to ops/op2/test_cases/sync/bigint.out
index 82117b2..9e6040e 100644
--- a/ops/op/test_cases/sync/bigint.out
+++ b/ops/op2/test_cases/sync/bigint.out
@@ -6,7 +6,7 @@ pub const fn op_bigint() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_bigint {
         const NAME: &'static str = stringify!(op_bigint);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_bigint),
             false,
             false,
diff --git a/ops/op/test_cases/sync/bigint.rs b/ops/op2/test_cases/sync/bigint.rs
similarity index 93%
rename from ops/op/test_cases/sync/bigint.rs
rename to ops/op2/test_cases/sync/bigint.rs
index c1340b0..3c057de 100644
--- a/ops/op/test_cases/sync/bigint.rs
+++ b/ops/op2/test_cases/sync/bigint.rs
@@ -2,7 +2,7 @@
 #![deny(warnings)]
 deno_ops_compile_test_runner::prelude!();
 
-#[op(fast)]
+#[op2(fast)]
 #[bigint]
 pub fn op_bigint() -> u64 {
   0
diff --git a/ops/op/test_cases/sync/bool.out b/ops/op2/test_cases/sync/bool.out
similarity index 99%
rename from ops/op/test_cases/sync/bool.out
rename to ops/op2/test_cases/sync/bool.out
index b01f6d5..7085734 100644
--- a/ops/op/test_cases/sync/bool.out
+++ b/ops/op2/test_cases/sync/bool.out
@@ -6,7 +6,7 @@ pub const fn op_bool() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_bool {
         const NAME: &'static str = stringify!(op_bool);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_bool),
             false,
             false,
diff --git a/ops/op/test_cases/sync/bool.rs b/ops/op2/test_cases/sync/bool.rs
similarity index 93%
rename from ops/op/test_cases/sync/bool.rs
rename to ops/op2/test_cases/sync/bool.rs
index 6c2d8a0..0091c4a 100644
--- a/ops/op/test_cases/sync/bool.rs
+++ b/ops/op2/test_cases/sync/bool.rs
@@ -2,7 +2,7 @@
 #![deny(warnings)]
 deno_ops_compile_test_runner::prelude!();
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_bool(arg: bool) -> bool {
   arg
 }
diff --git a/ops/op/test_cases/sync/bool_result.out b/ops/op2/test_cases/sync/bool_result.out
similarity index 99%
rename from ops/op/test_cases/sync/bool_result.out
rename to ops/op2/test_cases/sync/bool_result.out
index b0f30de..23d369c 100644
--- a/ops/op/test_cases/sync/bool_result.out
+++ b/ops/op2/test_cases/sync/bool_result.out
@@ -6,7 +6,7 @@ pub const fn op_bool() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_bool {
         const NAME: &'static str = stringify!(op_bool);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_bool),
             false,
             false,
diff --git a/ops/op/test_cases/sync/bool_result.rs b/ops/op2/test_cases/sync/bool_result.rs
similarity index 94%
rename from ops/op/test_cases/sync/bool_result.rs
rename to ops/op2/test_cases/sync/bool_result.rs
index 33c5b15..97c76b6 100644
--- a/ops/op/test_cases/sync/bool_result.rs
+++ b/ops/op2/test_cases/sync/bool_result.rs
@@ -4,7 +4,7 @@ deno_ops_compile_test_runner::prelude!();
 
 use deno_core::error::AnyError;
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_bool(arg: bool) -> Result<bool, AnyError> {
   Ok(arg)
 }
diff --git a/ops/op/test_cases/sync/buffers.out b/ops/op2/test_cases/sync/buffers.out
similarity index 99%
rename from ops/op/test_cases/sync/buffers.out
rename to ops/op2/test_cases/sync/buffers.out
index 95960fc..e09241e 100644
--- a/ops/op/test_cases/sync/buffers.out
+++ b/ops/op2/test_cases/sync/buffers.out
@@ -6,7 +6,7 @@ const fn op_buffers() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_buffers {
         const NAME: &'static str = stringify!(op_buffers);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_buffers),
             false,
             false,
@@ -289,7 +289,7 @@ const fn op_buffers_32() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_buffers_32 {
         const NAME: &'static str = stringify!(op_buffers_32);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_buffers_32),
             false,
             false,
@@ -572,7 +572,7 @@ const fn op_buffers_option() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_buffers_option {
         const NAME: &'static str = stringify!(op_buffers_option);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_buffers_option),
             false,
             false,
diff --git a/ops/op/test_cases/sync/buffers.rs b/ops/op2/test_cases/sync/buffers.rs
similarity index 93%
rename from ops/op/test_cases/sync/buffers.rs
rename to ops/op2/test_cases/sync/buffers.rs
index 4d06531..b9c846b 100644
--- a/ops/op/test_cases/sync/buffers.rs
+++ b/ops/op2/test_cases/sync/buffers.rs
@@ -4,7 +4,7 @@ deno_ops_compile_test_runner::prelude!();
 
 use deno_core::JsBuffer;
 
-#[op(fast)]
+#[op2(fast)]
 fn op_buffers(
   #[buffer] _a: &[u8],
   #[buffer] _b: &mut [u8],
@@ -13,7 +13,7 @@ fn op_buffers(
 ) {
 }
 
-#[op(fast)]
+#[op2(fast)]
 fn op_buffers_32(
   #[buffer] _a: &[u32],
   #[buffer] _b: &mut [u32],
@@ -22,7 +22,7 @@ fn op_buffers_32(
 ) {
 }
 
-#[op]
+#[op2]
 fn op_buffers_option(
   #[buffer] _a: Option<&[u8]>,
   #[buffer] _b: Option<JsBuffer>,
diff --git a/ops/op/test_cases/sync/buffers_copy.out b/ops/op2/test_cases/sync/buffers_copy.out
similarity index 99%
rename from ops/op/test_cases/sync/buffers_copy.out
rename to ops/op2/test_cases/sync/buffers_copy.out
index 282c5f8..d61d82b 100644
--- a/ops/op/test_cases/sync/buffers_copy.out
+++ b/ops/op2/test_cases/sync/buffers_copy.out
@@ -6,7 +6,7 @@ const fn op_buffers() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_buffers {
         const NAME: &'static str = stringify!(op_buffers);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_buffers),
             false,
             false,
@@ -245,7 +245,7 @@ const fn op_buffers_32() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_buffers_32 {
         const NAME: &'static str = stringify!(op_buffers_32);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_buffers_32),
             false,
             false,
diff --git a/ops/op/test_cases/sync/buffers_copy.rs b/ops/op2/test_cases/sync/buffers_copy.rs
similarity index 92%
rename from ops/op/test_cases/sync/buffers_copy.rs
rename to ops/op2/test_cases/sync/buffers_copy.rs
index 0647b45..9cb5ce0 100644
--- a/ops/op/test_cases/sync/buffers_copy.rs
+++ b/ops/op2/test_cases/sync/buffers_copy.rs
@@ -2,7 +2,7 @@
 #![deny(warnings)]
 deno_ops_compile_test_runner::prelude!();
 
-#[op(fast)]
+#[op2(fast)]
 fn op_buffers(
   #[buffer(copy)] _a: Vec<u8>,
   #[buffer(copy)] _b: Box<[u8]>,
@@ -10,6 +10,6 @@ fn op_buffers(
 ) {
 }
 
-#[op(fast)]
+#[op2(fast)]
 fn op_buffers_32(#[buffer(copy)] _a: Vec<u32>, #[buffer(copy)] _b: Box<[u32]>) {
 }
diff --git a/ops/op/test_cases/sync/buffers_out.out b/ops/op2/test_cases/sync/buffers_out.out
similarity index 99%
rename from ops/op/test_cases/sync/buffers_out.out
rename to ops/op2/test_cases/sync/buffers_out.out
index 4196a45..8040575 100644
--- a/ops/op/test_cases/sync/buffers_out.out
+++ b/ops/op2/test_cases/sync/buffers_out.out
@@ -6,7 +6,7 @@ const fn op_buffers() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_buffers {
         const NAME: &'static str = stringify!(op_buffers);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_buffers),
             false,
             false,
@@ -129,7 +129,7 @@ const fn op_buffers_option() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_buffers_option {
         const NAME: &'static str = stringify!(op_buffers_option);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_buffers_option),
             false,
             false,
@@ -262,7 +262,7 @@ const fn op_arraybuffers() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_arraybuffers {
         const NAME: &'static str = stringify!(op_arraybuffers);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_arraybuffers),
             false,
             false,
diff --git a/ops/op/test_cases/sync/buffers_out.rs b/ops/op2/test_cases/sync/buffers_out.rs
similarity index 95%
rename from ops/op/test_cases/sync/buffers_out.rs
rename to ops/op2/test_cases/sync/buffers_out.rs
index e4773c5..2a205a3 100644
--- a/ops/op/test_cases/sync/buffers_out.rs
+++ b/ops/op2/test_cases/sync/buffers_out.rs
@@ -4,19 +4,19 @@ deno_ops_compile_test_runner::prelude!();
 
 use deno_core::JsBuffer;
 
-#[op]
+#[op2]
 #[buffer]
 fn op_buffers(#[buffer] buffer: JsBuffer) -> JsBuffer {
   buffer
 }
 
-#[op]
+#[op2]
 #[buffer]
 fn op_buffers_option(#[buffer] buffer: Option<JsBuffer>) -> Option<JsBuffer> {
   buffer
 }
 
-#[op]
+#[op2]
 #[arraybuffer]
 fn op_arraybuffers(#[arraybuffer] buffer: JsBuffer) -> JsBuffer {
   buffer
@@ -24,7 +24,7 @@ fn op_arraybuffers(#[arraybuffer] buffer: JsBuffer) -> JsBuffer {
 
 // TODO(mmastrac): Option + Marker doesn't work yet
 
-// #[op]
+// #[op2]
 // #[arraybuffer]
 // fn op_arraybuffers_option(#[arraybuffer] buffer: Option<JsBuffer>) -> Option<JsBuffer> {
 //   buffer
diff --git a/ops/op/test_cases/sync/cfg.out b/ops/op2/test_cases/sync/cfg.out
similarity index 99%
rename from ops/op/test_cases/sync/cfg.out
rename to ops/op2/test_cases/sync/cfg.out
index 56136ff..016ccda 100644
--- a/ops/op/test_cases/sync/cfg.out
+++ b/ops/op2/test_cases/sync/cfg.out
@@ -8,7 +8,7 @@ pub const fn op_maybe_windows() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_maybe_windows {
         const NAME: &'static str = stringify!(op_maybe_windows);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_maybe_windows),
             false,
             false,
@@ -155,7 +155,7 @@ pub const fn op_maybe_windows() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_maybe_windows {
         const NAME: &'static str = stringify!(op_maybe_windows);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_maybe_windows),
             false,
             false,
diff --git a/ops/op/test_cases/sync/cfg.rs b/ops/op2/test_cases/sync/cfg.rs
similarity index 92%
rename from ops/op/test_cases/sync/cfg.rs
rename to ops/op2/test_cases/sync/cfg.rs
index cf79c26..18764aa 100644
--- a/ops/op/test_cases/sync/cfg.rs
+++ b/ops/op2/test_cases/sync/cfg.rs
@@ -3,11 +3,11 @@
 deno_ops_compile_test_runner::prelude!();
 
 /// This is a doc comment.
-#[op(fast)]
+#[op2(fast)]
 #[cfg(windows)]
 pub fn op_maybe_windows() -> () {}
 
 /// This is a doc comment.
-#[op(fast)]
+#[op2(fast)]
 #[cfg(not(windows))]
 pub fn op_maybe_windows() -> () {}
diff --git a/ops/op/test_cases/sync/clippy_allow.out b/ops/op2/test_cases/sync/clippy_allow.out
similarity index 99%
rename from ops/op/test_cases/sync/clippy_allow.out
rename to ops/op2/test_cases/sync/clippy_allow.out
index 5e6132d..ea8fea9 100644
--- a/ops/op/test_cases/sync/clippy_allow.out
+++ b/ops/op2/test_cases/sync/clippy_allow.out
@@ -8,7 +8,7 @@ pub const fn op_extra_annotation() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_extra_annotation {
         const NAME: &'static str = stringify!(op_extra_annotation);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_extra_annotation),
             false,
             false,
@@ -153,7 +153,7 @@ pub const fn op_clippy_internal() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_clippy_internal {
         const NAME: &'static str = stringify!(op_clippy_internal);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_clippy_internal),
             false,
             false,
diff --git a/ops/op/test_cases/sync/clippy_allow.rs b/ops/op2/test_cases/sync/clippy_allow.rs
similarity index 92%
rename from ops/op/test_cases/sync/clippy_allow.rs
rename to ops/op2/test_cases/sync/clippy_allow.rs
index 546497a..3a10ba2 100644
--- a/ops/op/test_cases/sync/clippy_allow.rs
+++ b/ops/op2/test_cases/sync/clippy_allow.rs
@@ -3,11 +3,11 @@
 deno_ops_compile_test_runner::prelude!();
 
 /// This is a doc comment.
-#[op(fast)]
+#[op2(fast)]
 #[allow(clippy::some_annotation)]
 pub fn op_extra_annotation() -> () {}
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_clippy_internal() -> () {
   {
     #![allow(clippy::await_holding_refcell_ref)]
diff --git a/ops/op/test_cases/sync/cppgc_resource.out b/ops/op2/test_cases/sync/cppgc_resource.out
similarity index 99%
rename from ops/op/test_cases/sync/cppgc_resource.out
rename to ops/op2/test_cases/sync/cppgc_resource.out
index 0a951a9..393d4b7 100644
--- a/ops/op/test_cases/sync/cppgc_resource.out
+++ b/ops/op2/test_cases/sync/cppgc_resource.out
@@ -6,7 +6,7 @@ const fn op_cppgc_object() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_cppgc_object {
         const NAME: &'static str = stringify!(op_cppgc_object);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_cppgc_object),
             false,
             false,
@@ -211,7 +211,7 @@ const fn op_option_cppgc_object() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_option_cppgc_object {
         const NAME: &'static str = stringify!(op_option_cppgc_object);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_option_cppgc_object),
             false,
             false,
@@ -424,7 +424,7 @@ const fn op_make_cppgc_object() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_make_cppgc_object {
         const NAME: &'static str = stringify!(op_make_cppgc_object);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_make_cppgc_object),
             false,
             false,
@@ -518,7 +518,7 @@ const fn op_use_cppgc_object() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_use_cppgc_object {
         const NAME: &'static str = stringify!(op_use_cppgc_object);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_use_cppgc_object),
             false,
             false,
@@ -723,7 +723,7 @@ const fn op_make_cppgc_object_option() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_make_cppgc_object_option {
         const NAME: &'static str = stringify!(op_make_cppgc_object_option);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_make_cppgc_object_option),
             false,
             false,
@@ -820,7 +820,7 @@ const fn op_use_cppgc_object_option() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_use_cppgc_object_option {
         const NAME: &'static str = stringify!(op_use_cppgc_object_option);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_use_cppgc_object_option),
             false,
             false,
diff --git a/ops/op/test_cases/sync/cppgc_resource.rs b/ops/op2/test_cases/sync/cppgc_resource.rs
similarity index 78%
rename from ops/op/test_cases/sync/cppgc_resource.rs
rename to ops/op2/test_cases/sync/cppgc_resource.rs
index 8bddc5e..1fad292 100644
--- a/ops/op/test_cases/sync/cppgc_resource.rs
+++ b/ops/op2/test_cases/sync/cppgc_resource.rs
@@ -7,26 +7,26 @@ struct Wrap;
 
 impl GarbageCollected for Wrap {}
 
-#[op(fast)]
+#[op2(fast)]
 fn op_cppgc_object(#[cppgc] _resource: &Wrap) {}
 
-#[op(fast)]
+#[op2(fast)]
 fn op_option_cppgc_object(#[cppgc] _resource: Option<&Wrap>) {}
 
-#[op]
+#[op2]
 #[cppgc]
 fn op_make_cppgc_object() -> Wrap {
   Wrap
 }
 
-#[op(fast)]
+#[op2(fast)]
 fn op_use_cppgc_object(#[cppgc] _wrap: &Wrap) {}
 
-#[op]
+#[op2]
 #[cppgc]
 fn op_make_cppgc_object_option() -> Option<Wrap> {
-  Some(Wrap)
+    Some(Wrap)
 }
 
-#[op(fast)]
-fn op_use_cppgc_object_option(#[cppgc] _wrap: &Wrap) {}
+#[op2(fast)]
+fn op_use_cppgc_object_option(#[cppgc] _wrap: &Wrap)  {}
diff --git a/ops/op/test_cases/sync/doc_comment.out b/ops/op2/test_cases/sync/doc_comment.out
similarity index 99%
rename from ops/op/test_cases/sync/doc_comment.out
rename to ops/op2/test_cases/sync/doc_comment.out
index 0d26624..0a1452f 100644
--- a/ops/op/test_cases/sync/doc_comment.out
+++ b/ops/op2/test_cases/sync/doc_comment.out
@@ -7,7 +7,7 @@ pub const fn op_has_doc_comment() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_has_doc_comment {
         const NAME: &'static str = stringify!(op_has_doc_comment);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_has_doc_comment),
             false,
             false,
diff --git a/ops/op/test_cases/sync/doc_comment.rs b/ops/op2/test_cases/sync/doc_comment.rs
similarity index 93%
rename from ops/op/test_cases/sync/doc_comment.rs
rename to ops/op2/test_cases/sync/doc_comment.rs
index 5f8ef4c..84e5bb4 100644
--- a/ops/op/test_cases/sync/doc_comment.rs
+++ b/ops/op2/test_cases/sync/doc_comment.rs
@@ -3,5 +3,5 @@
 deno_ops_compile_test_runner::prelude!();
 
 /// This is a doc comment.
-#[op(fast)]
+#[op2(fast)]
 pub fn op_has_doc_comment() -> () {}
diff --git a/ops/op/test_cases/sync/fast_alternative.out b/ops/op2/test_cases/sync/fast_alternative.out
similarity index 99%
rename from ops/op/test_cases/sync/fast_alternative.out
rename to ops/op2/test_cases/sync/fast_alternative.out
index a36867e..770c06b 100644
--- a/ops/op/test_cases/sync/fast_alternative.out
+++ b/ops/op2/test_cases/sync/fast_alternative.out
@@ -6,7 +6,7 @@ const fn op_slow() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_slow {
         const NAME: &'static str = stringify!(op_slow);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_slow),
             false,
             false,
@@ -124,7 +124,7 @@ const fn op_fast() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_fast {
         const NAME: &'static str = stringify!(op_fast);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_fast),
             false,
             false,
@@ -343,7 +343,7 @@ const fn op_slow_generic<T: Trait>() -> ::deno_core::_ops::OpDecl {
     }
     impl<T: Trait> ::deno_core::_ops::Op for op_slow_generic<T> {
         const NAME: &'static str = stringify!(op_slow_generic);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_slow_generic),
             false,
             false,
@@ -461,7 +461,7 @@ const fn op_fast_generic<T: Trait>() -> ::deno_core::_ops::OpDecl {
     }
     impl<T: Trait> ::deno_core::_ops::Op for op_fast_generic<T> {
         const NAME: &'static str = stringify!(op_fast_generic);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_fast_generic),
             false,
             false,
diff --git a/ops/op/test_cases/sync/fast_alternative.rs b/ops/op2/test_cases/sync/fast_alternative.rs
similarity index 87%
rename from ops/op/test_cases/sync/fast_alternative.rs
rename to ops/op2/test_cases/sync/fast_alternative.rs
index 942677e..663c96d 100644
--- a/ops/op/test_cases/sync/fast_alternative.rs
+++ b/ops/op2/test_cases/sync/fast_alternative.rs
@@ -5,12 +5,12 @@ deno_ops_compile_test_runner::prelude!();
 use deno_core::v8;
 
 // Unused scope would normally make this a slow-only op
-#[op(fast(op_fast))]
+#[op2(fast(op_fast))]
 fn op_slow(_scope: &v8::HandleScope, a: u32, b: u32) -> u32 {
   a + b
 }
 
-#[op(fast)]
+#[op2(fast)]
 fn op_fast(a: u32, b: u32) -> u32 {
   a + b
 }
@@ -18,12 +18,12 @@ fn op_fast(a: u32, b: u32) -> u32 {
 pub trait Trait {}
 
 // Unused scope would normally make this a slow-only op
-#[op(fast(op_fast_generic::<T>))]
+#[op2(fast(op_fast_generic::<T>))]
 fn op_slow_generic<T: Trait>(_scope: &v8::HandleScope, a: u32, b: u32) -> u32 {
   a + b
 }
 
-#[op(fast)]
+#[op2(fast)]
 fn op_fast_generic<T: Trait>(a: u32, b: u32) -> u32 {
   a + b
 }
diff --git a/ops/op/test_cases/sync/from_v8.out b/ops/op2/test_cases/sync/from_v8.out
similarity index 99%
rename from ops/op/test_cases/sync/from_v8.out
rename to ops/op2/test_cases/sync/from_v8.out
index 0793c08..80ba5b9 100644
--- a/ops/op/test_cases/sync/from_v8.out
+++ b/ops/op2/test_cases/sync/from_v8.out
@@ -6,7 +6,7 @@ pub const fn op_from_v8_arg() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_from_v8_arg {
         const NAME: &'static str = stringify!(op_from_v8_arg);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_from_v8_arg),
             false,
             false,
diff --git a/ops/op/test_cases/sync/from_v8.rs b/ops/op2/test_cases/sync/from_v8.rs
similarity index 98%
rename from ops/op/test_cases/sync/from_v8.rs
rename to ops/op2/test_cases/sync/from_v8.rs
index aaa1ae0..2649c51 100644
--- a/ops/op/test_cases/sync/from_v8.rs
+++ b/ops/op2/test_cases/sync/from_v8.rs
@@ -16,7 +16,7 @@ impl<'a> FromV8<'a> for Foo {
   }
 }
 
-#[op]
+#[op2]
 #[from_v8]
 pub fn op_from_v8_arg(#[from_v8] foo: Foo) {
   let _ = foo;
diff --git a/ops/op/test_cases/sync/generics.out b/ops/op2/test_cases/sync/generics.out
similarity index 99%
rename from ops/op/test_cases/sync/generics.out
rename to ops/op2/test_cases/sync/generics.out
index 6e4d5bd..1be6185 100644
--- a/ops/op/test_cases/sync/generics.out
+++ b/ops/op2/test_cases/sync/generics.out
@@ -6,7 +6,7 @@ pub const fn op_generics<T: Trait>() -> ::deno_core::_ops::OpDecl {
     }
     impl<T: Trait> ::deno_core::_ops::Op for op_generics<T> {
         const NAME: &'static str = stringify!(op_generics);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_generics),
             false,
             false,
@@ -149,7 +149,7 @@ pub const fn op_generics_static<T: Trait + 'static>() -> ::deno_core::_ops::OpDe
     }
     impl<T: Trait + 'static> ::deno_core::_ops::Op for op_generics_static<T> {
         const NAME: &'static str = stringify!(op_generics_static);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_generics_static),
             false,
             false,
@@ -292,7 +292,7 @@ pub const fn op_generics_static_where<T: Trait + 'static>() -> ::deno_core::_ops
     }
     impl<T: Trait + 'static> ::deno_core::_ops::Op for op_generics_static_where<T> {
         const NAME: &'static str = stringify!(op_generics_static_where);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_generics_static_where),
             false,
             false,
diff --git a/ops/op/test_cases/sync/generics.rs b/ops/op2/test_cases/sync/generics.rs
similarity index 88%
rename from ops/op/test_cases/sync/generics.rs
rename to ops/op2/test_cases/sync/generics.rs
index 85f95de..7465aef 100644
--- a/ops/op/test_cases/sync/generics.rs
+++ b/ops/op2/test_cases/sync/generics.rs
@@ -4,13 +4,13 @@ deno_ops_compile_test_runner::prelude!();
 
 pub trait Trait {}
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_generics<T: Trait>() {}
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_generics_static<T: Trait + 'static>() {}
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_generics_static_where<T>()
 where
   T: Trait + 'static,
diff --git a/ops/op/test_cases/sync/nofast.out b/ops/op2/test_cases/sync/nofast.out
similarity index 99%
rename from ops/op/test_cases/sync/nofast.out
rename to ops/op2/test_cases/sync/nofast.out
index dee8e0c..820bfc1 100644
--- a/ops/op/test_cases/sync/nofast.out
+++ b/ops/op2/test_cases/sync/nofast.out
@@ -6,7 +6,7 @@ const fn op_nofast() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_nofast {
         const NAME: &'static str = stringify!(op_nofast);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_nofast),
             false,
             false,
diff --git a/ops/op/test_cases/sync/nofast.rs b/ops/op2/test_cases/sync/nofast.rs
similarity index 92%
rename from ops/op/test_cases/sync/nofast.rs
rename to ops/op2/test_cases/sync/nofast.rs
index 1c1fcc7..6046fb0 100644
--- a/ops/op/test_cases/sync/nofast.rs
+++ b/ops/op2/test_cases/sync/nofast.rs
@@ -2,7 +2,7 @@
 #![deny(warnings)]
 deno_ops_compile_test_runner::prelude!();
 
-#[op(nofast)]
+#[op2(nofast)]
 fn op_nofast(a: u32, b: u32) -> u32 {
   a + b
 }
diff --git a/ops/op/test_cases/sync/op_state_attr.out b/ops/op2/test_cases/sync/op_state_attr.out
similarity index 99%
rename from ops/op/test_cases/sync/op_state_attr.out
rename to ops/op2/test_cases/sync/op_state_attr.out
index c2e5b37..cfae9d1 100644
--- a/ops/op/test_cases/sync/op_state_attr.out
+++ b/ops/op2/test_cases/sync/op_state_attr.out
@@ -6,7 +6,7 @@ const fn op_state_rc() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_state_rc {
         const NAME: &'static str = stringify!(op_state_rc);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_state_rc),
             false,
             false,
diff --git a/ops/op/test_cases/sync/op_state_attr.rs b/ops/op2/test_cases/sync/op_state_attr.rs
similarity index 96%
rename from ops/op/test_cases/sync/op_state_attr.rs
rename to ops/op2/test_cases/sync/op_state_attr.rs
index 05867e3..c7e5352 100644
--- a/ops/op/test_cases/sync/op_state_attr.rs
+++ b/ops/op2/test_cases/sync/op_state_attr.rs
@@ -10,7 +10,7 @@ use std::borrow::BorrowMut;
 
 struct Something {}
 
-#[op(fast)]
+#[op2(fast)]
 fn op_state_rc(
   #[state] _arg: &Something,
   #[state] _arg_opt: Option<&Something>,
diff --git a/ops/op/test_cases/sync/op_state_rc.out b/ops/op2/test_cases/sync/op_state_rc.out
similarity index 99%
rename from ops/op/test_cases/sync/op_state_rc.out
rename to ops/op2/test_cases/sync/op_state_rc.out
index 49f7f41..917a3b1 100644
--- a/ops/op/test_cases/sync/op_state_rc.out
+++ b/ops/op2/test_cases/sync/op_state_rc.out
@@ -6,7 +6,7 @@ const fn op_state_rc() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_state_rc {
         const NAME: &'static str = stringify!(op_state_rc);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_state_rc),
             false,
             false,
diff --git a/ops/op/test_cases/sync/op_state_rc.rs b/ops/op2/test_cases/sync/op_state_rc.rs
similarity index 95%
rename from ops/op/test_cases/sync/op_state_rc.rs
rename to ops/op2/test_cases/sync/op_state_rc.rs
index 620c842..56687fe 100644
--- a/ops/op/test_cases/sync/op_state_rc.rs
+++ b/ops/op2/test_cases/sync/op_state_rc.rs
@@ -6,5 +6,5 @@ use deno_core::OpState;
 use std::cell::RefCell;
 use std::rc::Rc;
 
-#[op(fast)]
+#[op2(fast)]
 fn op_state_rc(_state: Rc<RefCell<OpState>>) {}
diff --git a/ops/op/test_cases/sync/op_state_ref.out b/ops/op2/test_cases/sync/op_state_ref.out
similarity index 99%
rename from ops/op/test_cases/sync/op_state_ref.out
rename to ops/op2/test_cases/sync/op_state_ref.out
index 2967c08..589e4ac 100644
--- a/ops/op/test_cases/sync/op_state_ref.out
+++ b/ops/op2/test_cases/sync/op_state_ref.out
@@ -6,7 +6,7 @@ const fn op_state_ref() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_state_ref {
         const NAME: &'static str = stringify!(op_state_ref);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_state_ref),
             false,
             false,
@@ -177,7 +177,7 @@ const fn op_state_mut() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_state_mut {
         const NAME: &'static str = stringify!(op_state_mut);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_state_mut),
             false,
             false,
@@ -348,7 +348,7 @@ const fn op_state_and_v8() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_state_and_v8 {
         const NAME: &'static str = stringify!(op_state_and_v8);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_state_and_v8),
             false,
             false,
@@ -461,7 +461,7 @@ const fn op_state_and_v8_local() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_state_and_v8_local {
         const NAME: &'static str = stringify!(op_state_and_v8_local);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_state_and_v8_local),
             false,
             false,
diff --git a/ops/op/test_cases/sync/op_state_ref.rs b/ops/op2/test_cases/sync/op_state_ref.rs
similarity index 92%
rename from ops/op/test_cases/sync/op_state_ref.rs
rename to ops/op2/test_cases/sync/op_state_ref.rs
index d1742c3..8f2d67d 100644
--- a/ops/op/test_cases/sync/op_state_ref.rs
+++ b/ops/op2/test_cases/sync/op_state_ref.rs
@@ -11,20 +11,20 @@ use std::borrow::Borrow;
 #[allow(unused)]
 use std::borrow::BorrowMut;
 
-#[op(fast)]
+#[op2(fast)]
 fn op_state_ref(_state: &OpState) {}
 
-#[op(fast)]
+#[op2(fast)]
 fn op_state_mut(_state: &mut OpState) {}
 
-#[op]
+#[op2]
 fn op_state_and_v8(
   _state: &mut OpState,
   #[global] _callback: v8::Global<v8::Function>,
 ) {
 }
 
-#[op(fast)]
+#[op2(fast)]
 fn op_state_and_v8_local(
   _state: &mut OpState,
   _callback: v8::Local<v8::Function>,
diff --git a/ops/op/test_cases/sync/result_external.out b/ops/op2/test_cases/sync/result_external.out
similarity index 99%
rename from ops/op/test_cases/sync/result_external.out
rename to ops/op2/test_cases/sync/result_external.out
index fe440db..3555150 100644
--- a/ops/op/test_cases/sync/result_external.out
+++ b/ops/op2/test_cases/sync/result_external.out
@@ -6,7 +6,7 @@ pub const fn op_external_with_result() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_external_with_result {
         const NAME: &'static str = stringify!(op_external_with_result);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_external_with_result),
             false,
             false,
diff --git a/ops/op/test_cases/sync/result_external.rs b/ops/op2/test_cases/sync/result_external.rs
similarity index 95%
rename from ops/op/test_cases/sync/result_external.rs
rename to ops/op2/test_cases/sync/result_external.rs
index 2e8e3f3..6566136 100644
--- a/ops/op/test_cases/sync/result_external.rs
+++ b/ops/op2/test_cases/sync/result_external.rs
@@ -4,7 +4,7 @@ deno_ops_compile_test_runner::prelude!();
 
 use deno_core::error::AnyError;
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_external_with_result() -> Result<*mut std::ffi::c_void, AnyError> {
   Ok(0 as _)
 }
diff --git a/ops/op/test_cases/sync/result_primitive.out b/ops/op2/test_cases/sync/result_primitive.out
similarity index 99%
rename from ops/op/test_cases/sync/result_primitive.out
rename to ops/op2/test_cases/sync/result_primitive.out
index fae229d..6a79984 100644
--- a/ops/op/test_cases/sync/result_primitive.out
+++ b/ops/op2/test_cases/sync/result_primitive.out
@@ -6,7 +6,7 @@ pub const fn op_u32_with_result() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_u32_with_result {
         const NAME: &'static str = stringify!(op_u32_with_result);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_u32_with_result),
             false,
             false,
diff --git a/ops/op/test_cases/sync/result_primitive.rs b/ops/op2/test_cases/sync/result_primitive.rs
similarity index 94%
rename from ops/op/test_cases/sync/result_primitive.rs
rename to ops/op2/test_cases/sync/result_primitive.rs
index 40943f8..5aaeb97 100644
--- a/ops/op/test_cases/sync/result_primitive.rs
+++ b/ops/op2/test_cases/sync/result_primitive.rs
@@ -4,7 +4,7 @@ deno_ops_compile_test_runner::prelude!();
 
 use deno_core::error::AnyError;
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_u32_with_result() -> Result<u32, AnyError> {
   Ok(0)
 }
diff --git a/ops/op/test_cases/sync/result_scope.out b/ops/op2/test_cases/sync/result_scope.out
similarity index 99%
rename from ops/op/test_cases/sync/result_scope.out
rename to ops/op2/test_cases/sync/result_scope.out
index 2d3cffd..4af4bd4 100644
--- a/ops/op/test_cases/sync/result_scope.out
+++ b/ops/op2/test_cases/sync/result_scope.out
@@ -6,7 +6,7 @@ pub const fn op_void_with_result() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_void_with_result {
         const NAME: &'static str = stringify!(op_void_with_result);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_void_with_result),
             false,
             false,
diff --git a/ops/op/test_cases/sync/result_scope.rs b/ops/op2/test_cases/sync/result_scope.rs
similarity index 95%
rename from ops/op/test_cases/sync/result_scope.rs
rename to ops/op2/test_cases/sync/result_scope.rs
index 616b500..70c1ce7 100644
--- a/ops/op/test_cases/sync/result_scope.rs
+++ b/ops/op2/test_cases/sync/result_scope.rs
@@ -5,7 +5,7 @@ deno_ops_compile_test_runner::prelude!();
 use deno_core::error::AnyError;
 use deno_core::v8;
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_void_with_result(
   _scope: &mut v8::HandleScope,
 ) -> Result<(), AnyError> {
diff --git a/ops/op/test_cases/sync/result_void.out b/ops/op2/test_cases/sync/result_void.out
similarity index 99%
rename from ops/op/test_cases/sync/result_void.out
rename to ops/op2/test_cases/sync/result_void.out
index d192c29..23f9850 100644
--- a/ops/op/test_cases/sync/result_void.out
+++ b/ops/op2/test_cases/sync/result_void.out
@@ -6,7 +6,7 @@ pub const fn op_void_with_result() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_void_with_result {
         const NAME: &'static str = stringify!(op_void_with_result);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_void_with_result),
             false,
             false,
diff --git a/ops/op/test_cases/sync/result_void.rs b/ops/op2/test_cases/sync/result_void.rs
similarity index 93%
rename from ops/op/test_cases/sync/result_void.rs
rename to ops/op2/test_cases/sync/result_void.rs
index 4eb7fd9..0014c07 100644
--- a/ops/op/test_cases/sync/result_void.rs
+++ b/ops/op2/test_cases/sync/result_void.rs
@@ -2,7 +2,7 @@
 #![deny(warnings)]
 deno_ops_compile_test_runner::prelude!();
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_void_with_result() -> std::io::Result<()> {
   Ok(())
 }
diff --git a/ops/op/test_cases/sync/serde_v8.out b/ops/op2/test_cases/sync/serde_v8.out
similarity index 99%
rename from ops/op/test_cases/sync/serde_v8.out
rename to ops/op2/test_cases/sync/serde_v8.out
index 77faea4..ca0094d 100644
--- a/ops/op/test_cases/sync/serde_v8.out
+++ b/ops/op2/test_cases/sync/serde_v8.out
@@ -6,7 +6,7 @@ pub const fn op_serde_v8() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_serde_v8 {
         const NAME: &'static str = stringify!(op_serde_v8);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_serde_v8),
             false,
             false,
diff --git a/ops/op/test_cases/sync/serde_v8.rs b/ops/op2/test_cases/sync/serde_v8.rs
similarity index 98%
rename from ops/op/test_cases/sync/serde_v8.rs
rename to ops/op2/test_cases/sync/serde_v8.rs
index 5f8bf5b..8066750 100644
--- a/ops/op/test_cases/sync/serde_v8.rs
+++ b/ops/op2/test_cases/sync/serde_v8.rs
@@ -10,7 +10,7 @@ pub struct Input {}
 #[derive(Serialize, Deserialize)]
 pub struct Output {}
 
-#[op]
+#[op2]
 #[serde]
 pub fn op_serde_v8(#[serde] _input: Input) -> Output {
   Output {}
diff --git a/ops/op/test_cases/sync/smi.out b/ops/op2/test_cases/sync/smi.out
similarity index 99%
rename from ops/op/test_cases/sync/smi.out
rename to ops/op2/test_cases/sync/smi.out
index 2c07be0..dc08d78 100644
--- a/ops/op/test_cases/sync/smi.out
+++ b/ops/op2/test_cases/sync/smi.out
@@ -6,7 +6,7 @@ const fn op_smi_unsigned_return() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_smi_unsigned_return {
         const NAME: &'static str = stringify!(op_smi_unsigned_return);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_smi_unsigned_return),
             false,
             false,
@@ -285,7 +285,7 @@ const fn op_smi_signed_return() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_smi_signed_return {
         const NAME: &'static str = stringify!(op_smi_signed_return);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_smi_signed_return),
             false,
             false,
@@ -564,7 +564,7 @@ const fn op_smi_option() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_smi_option {
         const NAME: &'static str = stringify!(op_smi_option);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_smi_option),
             false,
             false,
diff --git a/ops/op/test_cases/sync/smi.rs b/ops/op2/test_cases/sync/smi.rs
similarity index 95%
rename from ops/op/test_cases/sync/smi.rs
rename to ops/op2/test_cases/sync/smi.rs
index bd3e094..4f3b434 100644
--- a/ops/op/test_cases/sync/smi.rs
+++ b/ops/op2/test_cases/sync/smi.rs
@@ -7,7 +7,7 @@ pub type Int32 = i32;
 pub type Uint16 = u16;
 pub type Uint32 = u32;
 
-#[op(fast)]
+#[op2(fast)]
 #[smi]
 fn op_smi_unsigned_return(
   #[smi] a: Int16,
@@ -18,7 +18,7 @@ fn op_smi_unsigned_return(
   a as Uint32 + b as Uint32 + c as Uint32 + d as Uint32
 }
 
-#[op(fast)]
+#[op2(fast)]
 #[smi]
 fn op_smi_signed_return(
   #[smi] a: Int16,
@@ -29,7 +29,7 @@ fn op_smi_signed_return(
   a as Int32 + b as Int32 + c as Int32 + d as Int32
 }
 
-#[op]
+#[op2]
 #[smi]
 fn op_smi_option(#[smi] a: Option<Uint32>) -> Option<Uint32> {
   a
diff --git a/ops/op/test_cases/sync/stack_trace.out b/ops/op2/test_cases/sync/stack_trace.out
similarity index 99%
rename from ops/op/test_cases/sync/stack_trace.out
rename to ops/op2/test_cases/sync/stack_trace.out
index 278d425..06e4b64 100644
--- a/ops/op/test_cases/sync/stack_trace.out
+++ b/ops/op2/test_cases/sync/stack_trace.out
@@ -6,7 +6,7 @@ const fn op_stack_trace() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_stack_trace {
         const NAME: &'static str = stringify!(op_stack_trace);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_stack_trace),
             false,
             false,
diff --git a/ops/op/test_cases/sync/stack_trace.rs b/ops/op2/test_cases/sync/stack_trace.rs
similarity index 86%
rename from ops/op/test_cases/sync/stack_trace.rs
rename to ops/op2/test_cases/sync/stack_trace.rs
index d43deff..6f817b1 100644
--- a/ops/op/test_cases/sync/stack_trace.rs
+++ b/ops/op2/test_cases/sync/stack_trace.rs
@@ -2,5 +2,5 @@
 #![deny(warnings)]
 deno_ops_compile_test_runner::prelude!();
 
-#[op(fast, stack_trace)]
+#[op2(fast, stack_trace)]
 fn op_stack_trace() {}
diff --git a/ops/op/test_cases/sync/stack_trace_scope.out b/ops/op2/test_cases/sync/stack_trace_scope.out
similarity index 99%
rename from ops/op/test_cases/sync/stack_trace_scope.out
rename to ops/op2/test_cases/sync/stack_trace_scope.out
index 399a860..c69e515 100644
--- a/ops/op/test_cases/sync/stack_trace_scope.out
+++ b/ops/op2/test_cases/sync/stack_trace_scope.out
@@ -6,7 +6,7 @@ const fn op_stack_trace() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_stack_trace {
         const NAME: &'static str = stringify!(op_stack_trace);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_stack_trace),
             false,
             false,
diff --git a/ops/op/test_cases/sync/stack_trace_scope.rs b/ops/op2/test_cases/sync/stack_trace_scope.rs
similarity index 66%
rename from ops/op/test_cases/sync/stack_trace_scope.rs
rename to ops/op2/test_cases/sync/stack_trace_scope.rs
index 11c375a..0d48528 100644
--- a/ops/op/test_cases/sync/stack_trace_scope.rs
+++ b/ops/op2/test_cases/sync/stack_trace_scope.rs
@@ -2,6 +2,5 @@
 #![deny(warnings)]
 deno_ops_compile_test_runner::prelude!();
 
-#[op(fast, stack_trace)]
-fn op_stack_trace(#[string] _: String) {
-}
+#[op2(fast, stack_trace)]
+fn op_stack_trace(#[string] _: String) {}
diff --git a/ops/op/test_cases/sync/string_cow.out b/ops/op2/test_cases/sync/string_cow.out
similarity index 99%
rename from ops/op/test_cases/sync/string_cow.out
rename to ops/op2/test_cases/sync/string_cow.out
index 1d747f0..4bb0fd9 100644
--- a/ops/op/test_cases/sync/string_cow.out
+++ b/ops/op2/test_cases/sync/string_cow.out
@@ -6,7 +6,7 @@ const fn op_string_cow() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_string_cow {
         const NAME: &'static str = stringify!(op_string_cow);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_string_cow),
             false,
             false,
diff --git a/ops/op/test_cases/sync/string_cow.rs b/ops/op2/test_cases/sync/string_cow.rs
similarity index 94%
rename from ops/op/test_cases/sync/string_cow.rs
rename to ops/op2/test_cases/sync/string_cow.rs
index 500b19d..365cf58 100644
--- a/ops/op/test_cases/sync/string_cow.rs
+++ b/ops/op2/test_cases/sync/string_cow.rs
@@ -4,7 +4,7 @@ deno_ops_compile_test_runner::prelude!();
 
 use std::borrow::Cow;
 
-#[op(fast)]
+#[op2(fast)]
 fn op_string_cow(#[string] s: Cow<str>) -> u32 {
   s.len() as _
 }
diff --git a/ops/op/test_cases/sync/string_onebyte.out b/ops/op2/test_cases/sync/string_onebyte.out
similarity index 99%
rename from ops/op/test_cases/sync/string_onebyte.out
rename to ops/op2/test_cases/sync/string_onebyte.out
index bd5db62..5349dfc 100644
--- a/ops/op/test_cases/sync/string_onebyte.out
+++ b/ops/op2/test_cases/sync/string_onebyte.out
@@ -6,7 +6,7 @@ const fn op_string_onebyte() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_string_onebyte {
         const NAME: &'static str = stringify!(op_string_onebyte);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_string_onebyte),
             false,
             false,
diff --git a/ops/op/test_cases/sync/string_onebyte.rs b/ops/op2/test_cases/sync/string_onebyte.rs
similarity index 94%
rename from ops/op/test_cases/sync/string_onebyte.rs
rename to ops/op2/test_cases/sync/string_onebyte.rs
index 5606cd0..460730c 100644
--- a/ops/op/test_cases/sync/string_onebyte.rs
+++ b/ops/op2/test_cases/sync/string_onebyte.rs
@@ -4,7 +4,7 @@ deno_ops_compile_test_runner::prelude!();
 
 use std::borrow::Cow;
 
-#[op(fast)]
+#[op2(fast)]
 fn op_string_onebyte(#[string(onebyte)] s: Cow<[u8]>) -> u32 {
   s.len() as _
 }
diff --git a/ops/op/test_cases/sync/string_option_return.out b/ops/op2/test_cases/sync/string_option_return.out
similarity index 99%
rename from ops/op/test_cases/sync/string_option_return.out
rename to ops/op2/test_cases/sync/string_option_return.out
index 2a595b9..9af4668 100644
--- a/ops/op/test_cases/sync/string_option_return.out
+++ b/ops/op2/test_cases/sync/string_option_return.out
@@ -6,7 +6,7 @@ pub const fn op_string_return() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_string_return {
         const NAME: &'static str = stringify!(op_string_return);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_string_return),
             false,
             false,
diff --git a/ops/op/test_cases/sync/string_option_return.rs b/ops/op2/test_cases/sync/string_option_return.rs
similarity index 96%
rename from ops/op/test_cases/sync/string_option_return.rs
rename to ops/op2/test_cases/sync/string_option_return.rs
index 9181c98..9618b1e 100644
--- a/ops/op/test_cases/sync/string_option_return.rs
+++ b/ops/op2/test_cases/sync/string_option_return.rs
@@ -2,7 +2,7 @@
 #![deny(warnings)]
 deno_ops_compile_test_runner::prelude!();
 
-#[op]
+#[op2]
 #[string]
 pub fn op_string_return(#[string] s: Option<String>) -> Option<String> {
   s
diff --git a/ops/op/test_cases/sync/string_owned.out b/ops/op2/test_cases/sync/string_owned.out
similarity index 99%
rename from ops/op/test_cases/sync/string_owned.out
rename to ops/op2/test_cases/sync/string_owned.out
index 18fe144..b932c75 100644
--- a/ops/op/test_cases/sync/string_owned.out
+++ b/ops/op2/test_cases/sync/string_owned.out
@@ -6,7 +6,7 @@ const fn op_string_owned() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_string_owned {
         const NAME: &'static str = stringify!(op_string_owned);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_string_owned),
             false,
             false,
diff --git a/ops/op/test_cases/sync/string_owned.rs b/ops/op2/test_cases/sync/string_owned.rs
similarity index 93%
rename from ops/op/test_cases/sync/string_owned.rs
rename to ops/op2/test_cases/sync/string_owned.rs
index 84725b4..ab4ac40 100644
--- a/ops/op/test_cases/sync/string_owned.rs
+++ b/ops/op2/test_cases/sync/string_owned.rs
@@ -2,7 +2,7 @@
 #![deny(warnings)]
 deno_ops_compile_test_runner::prelude!();
 
-#[op(fast)]
+#[op2(fast)]
 fn op_string_owned(#[string] s: String) -> u32 {
   s.len() as _
 }
diff --git a/ops/op/test_cases/sync/string_ref.out b/ops/op2/test_cases/sync/string_ref.out
similarity index 99%
rename from ops/op/test_cases/sync/string_ref.out
rename to ops/op2/test_cases/sync/string_ref.out
index 32c37bc..73e4eb0 100644
--- a/ops/op/test_cases/sync/string_ref.out
+++ b/ops/op2/test_cases/sync/string_ref.out
@@ -6,7 +6,7 @@ const fn op_string_owned() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_string_owned {
         const NAME: &'static str = stringify!(op_string_owned);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_string_owned),
             false,
             false,
diff --git a/ops/op/test_cases/sync/string_ref.rs b/ops/op2/test_cases/sync/string_ref.rs
similarity index 93%
rename from ops/op/test_cases/sync/string_ref.rs
rename to ops/op2/test_cases/sync/string_ref.rs
index bc05d09..87d03da 100644
--- a/ops/op/test_cases/sync/string_ref.rs
+++ b/ops/op2/test_cases/sync/string_ref.rs
@@ -2,7 +2,7 @@
 #![deny(warnings)]
 deno_ops_compile_test_runner::prelude!();
 
-#[op(fast)]
+#[op2(fast)]
 fn op_string_owned(#[string] s: &str) -> u32 {
   s.len() as _
 }
diff --git a/ops/op/test_cases/sync/string_return.out b/ops/op2/test_cases/sync/string_return.out
similarity index 99%
rename from ops/op/test_cases/sync/string_return.out
rename to ops/op2/test_cases/sync/string_return.out
index 3827889..fd394f4 100644
--- a/ops/op/test_cases/sync/string_return.out
+++ b/ops/op2/test_cases/sync/string_return.out
@@ -6,7 +6,7 @@ pub const fn op_string_return() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_string_return {
         const NAME: &'static str = stringify!(op_string_return);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_string_return),
             false,
             false,
@@ -104,7 +104,7 @@ pub const fn op_string_return_ref() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_string_return_ref {
         const NAME: &'static str = stringify!(op_string_return_ref);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_string_return_ref),
             false,
             false,
@@ -202,7 +202,7 @@ pub const fn op_string_return_cow() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_string_return_cow {
         const NAME: &'static str = stringify!(op_string_return_cow);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_string_return_cow),
             false,
             false,
diff --git a/ops/op/test_cases/sync/string_return.rs b/ops/op2/test_cases/sync/string_return.rs
similarity index 94%
rename from ops/op/test_cases/sync/string_return.rs
rename to ops/op2/test_cases/sync/string_return.rs
index 5b66390..00c60f8 100644
--- a/ops/op/test_cases/sync/string_return.rs
+++ b/ops/op2/test_cases/sync/string_return.rs
@@ -3,19 +3,19 @@
 deno_ops_compile_test_runner::prelude!();
 use std::borrow::Cow;
 
-#[op]
+#[op2]
 #[string]
 pub fn op_string_return() -> String {
   "".into()
 }
 
-#[op]
+#[op2]
 #[string]
 pub fn op_string_return_ref() -> &'static str {
   ""
 }
 
-#[op]
+#[op2]
 #[string]
 pub fn op_string_return_cow<'a>() -> Cow<'a, str> {
   "".into()
diff --git a/ops/op/test_cases/sync/to_v8.out b/ops/op2/test_cases/sync/to_v8.out
similarity index 99%
rename from ops/op/test_cases/sync/to_v8.out
rename to ops/op2/test_cases/sync/to_v8.out
index 8a11580..8185830 100644
--- a/ops/op/test_cases/sync/to_v8.out
+++ b/ops/op2/test_cases/sync/to_v8.out
@@ -6,7 +6,7 @@ pub const fn op_to_v8_return() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_to_v8_return {
         const NAME: &'static str = stringify!(op_to_v8_return);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_to_v8_return),
             false,
             false,
diff --git a/ops/op/test_cases/sync/to_v8.rs b/ops/op2/test_cases/sync/to_v8.rs
similarity index 98%
rename from ops/op/test_cases/sync/to_v8.rs
rename to ops/op2/test_cases/sync/to_v8.rs
index 6e0d5aa..3a26df9 100644
--- a/ops/op/test_cases/sync/to_v8.rs
+++ b/ops/op2/test_cases/sync/to_v8.rs
@@ -16,7 +16,7 @@ impl<'a> ToV8<'a> for Foo {
   }
 }
 
-#[op]
+#[op2]
 #[to_v8]
 pub fn op_to_v8_return() -> Foo {
   Foo
diff --git a/ops/op/test_cases/sync/v8_global.out b/ops/op2/test_cases/sync/v8_global.out
similarity index 99%
rename from ops/op/test_cases/sync/v8_global.out
rename to ops/op2/test_cases/sync/v8_global.out
index a106aaa..467ba14 100644
--- a/ops/op/test_cases/sync/v8_global.out
+++ b/ops/op2/test_cases/sync/v8_global.out
@@ -6,7 +6,7 @@ pub const fn op_global() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_global {
         const NAME: &'static str = stringify!(op_global);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_global),
             false,
             false,
diff --git a/ops/op/test_cases/sync/v8_global.rs b/ops/op2/test_cases/sync/v8_global.rs
similarity index 97%
rename from ops/op/test_cases/sync/v8_global.rs
rename to ops/op2/test_cases/sync/v8_global.rs
index 16ee72d..9c9b91d 100644
--- a/ops/op/test_cases/sync/v8_global.rs
+++ b/ops/op2/test_cases/sync/v8_global.rs
@@ -4,7 +4,7 @@ deno_ops_compile_test_runner::prelude!();
 
 use deno_core::v8;
 
-#[op]
+#[op2]
 #[global]
 pub fn op_global(
   #[global] g: v8::Global<v8::String>,
diff --git a/ops/op/test_cases/sync/v8_handlescope.out b/ops/op2/test_cases/sync/v8_handlescope.out
similarity index 99%
rename from ops/op/test_cases/sync/v8_handlescope.out
rename to ops/op2/test_cases/sync/v8_handlescope.out
index e9069a2..43a57a3 100644
--- a/ops/op/test_cases/sync/v8_handlescope.out
+++ b/ops/op2/test_cases/sync/v8_handlescope.out
@@ -6,7 +6,7 @@ const fn op_handlescope() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_handlescope {
         const NAME: &'static str = stringify!(op_handlescope);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_handlescope),
             false,
             false,
diff --git a/ops/op/test_cases/sync/v8_handlescope.rs b/ops/op2/test_cases/sync/v8_handlescope.rs
similarity index 97%
rename from ops/op/test_cases/sync/v8_handlescope.rs
rename to ops/op2/test_cases/sync/v8_handlescope.rs
index bb192fa..549a4c3 100644
--- a/ops/op/test_cases/sync/v8_handlescope.rs
+++ b/ops/op2/test_cases/sync/v8_handlescope.rs
@@ -4,7 +4,7 @@ deno_ops_compile_test_runner::prelude!();
 
 use deno_core::v8;
 
-#[op]
+#[op2]
 fn op_handlescope<'a>(
   _scope: &v8::HandleScope<'a>,
   _str2: v8::Local<v8::String>,
diff --git a/ops/op/test_cases/sync/v8_lifetime.out b/ops/op2/test_cases/sync/v8_lifetime.out
similarity index 99%
rename from ops/op/test_cases/sync/v8_lifetime.out
rename to ops/op2/test_cases/sync/v8_lifetime.out
index 59f912d..2980096 100644
--- a/ops/op/test_cases/sync/v8_lifetime.out
+++ b/ops/op2/test_cases/sync/v8_lifetime.out
@@ -6,7 +6,7 @@ pub const fn op_v8_lifetime() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_v8_lifetime {
         const NAME: &'static str = stringify!(op_v8_lifetime);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_v8_lifetime),
             false,
             false,
diff --git a/ops/op/test_cases/sync/v8_lifetime.rs b/ops/op2/test_cases/sync/v8_lifetime.rs
similarity index 97%
rename from ops/op/test_cases/sync/v8_lifetime.rs
rename to ops/op2/test_cases/sync/v8_lifetime.rs
index 0b68b1d..e66ad32 100644
--- a/ops/op/test_cases/sync/v8_lifetime.rs
+++ b/ops/op2/test_cases/sync/v8_lifetime.rs
@@ -4,7 +4,7 @@ deno_ops_compile_test_runner::prelude!();
 
 use deno_core::v8;
 
-#[op]
+#[op2]
 pub fn op_v8_lifetime<'s>(
   _s: v8::Local<'s, v8::String>,
 ) -> v8::Local<'s, v8::String> {
diff --git a/ops/op/test_cases/sync/v8_ref_option.out b/ops/op2/test_cases/sync/v8_ref_option.out
similarity index 99%
rename from ops/op/test_cases/sync/v8_ref_option.out
rename to ops/op2/test_cases/sync/v8_ref_option.out
index 8f4bac7..2cdcabd 100644
--- a/ops/op/test_cases/sync/v8_ref_option.out
+++ b/ops/op2/test_cases/sync/v8_ref_option.out
@@ -6,7 +6,7 @@ pub const fn op_v8_lifetime() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_v8_lifetime {
         const NAME: &'static str = stringify!(op_v8_lifetime);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_v8_lifetime),
             false,
             false,
diff --git a/ops/op/test_cases/sync/v8_ref_option.rs b/ops/op2/test_cases/sync/v8_ref_option.rs
similarity index 94%
rename from ops/op/test_cases/sync/v8_ref_option.rs
rename to ops/op2/test_cases/sync/v8_ref_option.rs
index 6dfd73c..1e655d9 100644
--- a/ops/op/test_cases/sync/v8_ref_option.rs
+++ b/ops/op2/test_cases/sync/v8_ref_option.rs
@@ -4,5 +4,5 @@ deno_ops_compile_test_runner::prelude!();
 
 use deno_core::v8;
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_v8_lifetime<'s>(_s: Option<&v8::String>, _s2: Option<&v8::String>) {}
diff --git a/ops/op/test_cases/sync/v8_string.out b/ops/op2/test_cases/sync/v8_string.out
similarity index 99%
rename from ops/op/test_cases/sync/v8_string.out
rename to ops/op2/test_cases/sync/v8_string.out
index 31d1eff..e0b4b3e 100644
--- a/ops/op/test_cases/sync/v8_string.out
+++ b/ops/op2/test_cases/sync/v8_string.out
@@ -6,7 +6,7 @@ const fn op_v8_string() -> ::deno_core::_ops::OpDecl {
     }
     impl ::deno_core::_ops::Op for op_v8_string {
         const NAME: &'static str = stringify!(op_v8_string);
-        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op(
+        const DECL: ::deno_core::_ops::OpDecl = ::deno_core::_ops::OpDecl::new_internal_op2(
             ::deno_core::__op_name_fast!(op_v8_string),
             false,
             false,
diff --git a/ops/op/test_cases/sync/v8_string.rs b/ops/op2/test_cases/sync/v8_string.rs
similarity index 97%
rename from ops/op/test_cases/sync/v8_string.rs
rename to ops/op2/test_cases/sync/v8_string.rs
index 265b440..0935dc8 100644
--- a/ops/op/test_cases/sync/v8_string.rs
+++ b/ops/op2/test_cases/sync/v8_string.rs
@@ -4,7 +4,7 @@ deno_ops_compile_test_runner::prelude!();
 
 use deno_core::v8;
 
-#[op]
+#[op2]
 fn op_v8_string<'a>(
   _str1: &v8::String,
   _str2: v8::Local<v8::String>,
diff --git a/ops/op/test_cases_fail/lifetimes.rs b/ops/op2/test_cases_fail/lifetimes.rs
similarity index 93%
rename from ops/op/test_cases_fail/lifetimes.rs
rename to ops/op2/test_cases_fail/lifetimes.rs
index d928eb2..adb4863 100644
--- a/ops/op/test_cases_fail/lifetimes.rs
+++ b/ops/op2/test_cases_fail/lifetimes.rs
@@ -9,8 +9,8 @@ struct Wrap;
 
 impl GarbageCollected for Wrap {}
 
-#[op(fast)]
+#[op2(fast)]
 fn op_use_cppgc_object(#[cppgc] _wrap: &'static Wrap) {}
 
-#[op(fast)]
+#[op2(fast)]
 fn op_use_buffer(#[buffer] _buffer: &'static [u8]) {}
diff --git a/ops/op/test_cases_fail/lifetimes.stderr b/ops/op2/test_cases_fail/lifetimes.stderr
similarity index 50%
rename from ops/op/test_cases_fail/lifetimes.stderr
rename to ops/op2/test_cases_fail/lifetimes.stderr
index 60ad948..70f3e67 100644
--- a/ops/op/test_cases_fail/lifetimes.stderr
+++ b/ops/op2/test_cases_fail/lifetimes.stderr
@@ -1,42 +1,42 @@
 error: unused import: `deno_core::error::AnyError`
- --> ../op/test_cases_fail/lifetimes.rs:4:5
+ --> ../op2/test_cases_fail/lifetimes.rs:4:5
   |
 4 | use deno_core::error::AnyError;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
 note: the lint level is defined here
- --> ../op/test_cases_fail/lifetimes.rs:2:9
+ --> ../op2/test_cases_fail/lifetimes.rs:2:9
   |
 2 | #![deny(warnings)]
   |         ^^^^^^^^
   = note: `#[deny(unused_imports)]` implied by `#[deny(warnings)]`
 
 error: unused import: `std::future::Future`
- --> ../op/test_cases_fail/lifetimes.rs:6:5
+ --> ../op2/test_cases_fail/lifetimes.rs:6:5
   |
 6 | use std::future::Future;
   |     ^^^^^^^^^^^^^^^^^^^
 
 error[E0597]: `arg0` does not live long enough
-  --> ../op/test_cases_fail/lifetimes.rs:12:1
+  --> ../op2/test_cases_fail/lifetimes.rs:12:1
    |
-12 | #[op(fast)]
-   | ^^^^^^^^^^-
-   | |         |
-   | |         `arg0` dropped here while still borrowed
+12 | #[op2(fast)]
+   | ^^^^^^^^^^^-
+   | |          |
+   | |          `arg0` dropped here while still borrowed
    | borrowed value does not live long enough
    | argument requires that `arg0` is borrowed for `'static`
    |
-   = note: this error originates in the attribute macro `op` (in Nightly builds, run with -Z macro-backtrace for more info)
+   = note: this error originates in the attribute macro `op2` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0597]: `arg0_temp` does not live long enough
-  --> ../op/test_cases_fail/lifetimes.rs:15:1
+  --> ../op2/test_cases_fail/lifetimes.rs:15:1
    |
-15 | #[op(fast)]
-   | ^^^^^^^^^^-
-   | |         |
-   | |         `arg0_temp` dropped here while still borrowed
+15 | #[op2(fast)]
+   | ^^^^^^^^^^^-
+   | |          |
+   | |          `arg0_temp` dropped here while still borrowed
    | borrowed value does not live long enough
    | argument requires that `arg0_temp` is borrowed for `'static`
    |
-   = note: this error originates in the attribute macro `op` (in Nightly builds, run with -Z macro-backtrace for more info)
+   = note: this error originates in the attribute macro `op2` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/ops/op/valid_args.md b/ops/op2/valid_args.md
similarity index 100%
rename from ops/op/valid_args.md
rename to ops/op2/valid_args.md
diff --git a/ops/op/valid_retvals.md b/ops/op2/valid_retvals.md
similarity index 100%
rename from ops/op/valid_retvals.md
rename to ops/op2/valid_retvals.md
diff --git a/testing/checkin/runner/ops.rs b/testing/checkin/runner/ops.rs
index d97c775..8ac41b1 100644
--- a/testing/checkin/runner/ops.rs
+++ b/testing/checkin/runner/ops.rs
@@ -3,7 +3,7 @@ use std::cell::RefCell;
 use std::rc::Rc;
 
 use deno_core::error::AnyError;
-use deno_core::op;
+use deno_core::op2;
 use deno_core::stats::RuntimeActivityDiff;
 use deno_core::stats::RuntimeActivitySnapshot;
 use deno_core::stats::RuntimeActivityStats;
@@ -17,18 +17,18 @@ use super::extensions::SomeType;
 use super::Output;
 use super::TestData;
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_log_debug(#[string] s: &str) {
   println!("{s}");
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_log_info(#[state] output: &mut Output, #[string] s: String) {
   println!("{s}");
   output.line(s);
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_stats_capture(#[string] name: String, state: Rc<RefCell<OpState>>) {
   let stats = state
     .borrow()
@@ -40,7 +40,7 @@ pub fn op_stats_capture(#[string] name: String, state: Rc<RefCell<OpState>>) {
   test_data.insert(name, data);
 }
 
-#[op]
+#[op2]
 #[serde]
 pub fn op_stats_dump(
   #[string] name: String,
@@ -50,7 +50,7 @@ pub fn op_stats_dump(
   stats.dump()
 }
 
-#[op]
+#[op2]
 #[serde]
 pub fn op_stats_diff(
   #[string] before: String,
@@ -62,7 +62,7 @@ pub fn op_stats_diff(
   RuntimeActivityStats::diff(before, after)
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_stats_delete(
   #[string] name: String,
   #[state] test_data: &mut TestData,
@@ -79,7 +79,7 @@ pub struct DOMPoint {
 
 impl GarbageCollected for DOMPoint {}
 
-#[op]
+#[op2]
 impl DOMPoint {
   #[constructor]
   #[cppgc]
@@ -144,7 +144,7 @@ impl DOMPoint {
   }
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_nop_generic<T: SomeType + 'static>(state: &mut OpState) {
   state.take::<T>();
 }
diff --git a/testing/checkin/runner/ops_async.rs b/testing/checkin/runner/ops_async.rs
index 178b3c4..672ed74 100644
--- a/testing/checkin/runner/ops_async.rs
+++ b/testing/checkin/runner/ops_async.rs
@@ -1,5 +1,5 @@
 // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
-use deno_core::op;
+use deno_core::op2;
 use deno_core::v8;
 use deno_core::GarbageCollected;
 use deno_core::OpState;
@@ -12,7 +12,7 @@ use std::rc::Rc;
 use super::Output;
 use super::TestData;
 
-#[op]
+#[op2]
 pub fn op_task_submit(
   state: &mut OpState,
   #[global] f: v8::Global<v8::Function>,
@@ -24,12 +24,12 @@ pub fn op_task_submit(
   });
 }
 
-#[op(async)]
+#[op2(async)]
 pub async fn op_async_yield() {
   tokio::task::yield_now().await
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_async_barrier_create(
   #[state] test_data: &mut TestData,
   #[string] name: String,
@@ -39,7 +39,7 @@ pub fn op_async_barrier_create(
   test_data.insert(name, barrier);
 }
 
-#[op(async)]
+#[op2(async)]
 pub fn op_async_barrier_await(
   #[state] test_data: &TestData,
   #[string] name: String,
@@ -51,7 +51,7 @@ pub fn op_async_barrier_await(
   }
 }
 
-#[op(async)]
+#[op2(async)]
 pub async fn op_async_spin_on_state(state: Rc<RefCell<OpState>>) {
   poll_fn(|cx| {
     // Ensure that we never get polled when the state has been emptied
@@ -68,13 +68,13 @@ pub struct TestResource {
 
 impl GarbageCollected for TestResource {}
 
-#[op(async)]
+#[op2(async)]
 #[cppgc]
 pub async fn op_async_make_cppgc_resource() -> TestResource {
   TestResource { value: 42 }
 }
 
-#[op(async)]
+#[op2(async)]
 #[smi]
 pub async fn op_async_get_cppgc_resource(
   #[cppgc] resource: &TestResource,
@@ -82,7 +82,7 @@ pub async fn op_async_get_cppgc_resource(
   resource.value
 }
 
-#[op(async)]
+#[op2(async)]
 pub fn op_async_never_resolves() -> impl Future<Output = ()> {
   futures::future::pending::<()>()
 }
diff --git a/testing/checkin/runner/ops_buffer.rs b/testing/checkin/runner/ops_buffer.rs
index d95f19d..70bdc18 100644
--- a/testing/checkin/runner/ops_buffer.rs
+++ b/testing/checkin/runner/ops_buffer.rs
@@ -1,10 +1,10 @@
 // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
-use deno_core::op;
+use deno_core::op2;
 use deno_core::JsBuffer;
 
 use super::TestData;
 
-#[op]
+#[op2]
 pub fn op_v8slice_store(
   #[state] test_data: &mut TestData,
   #[string] name: String,
@@ -13,7 +13,7 @@ pub fn op_v8slice_store(
   test_data.insert(name, data);
 }
 
-#[op]
+#[op2]
 #[buffer]
 pub fn op_v8slice_clone(
   #[state] test_data: &mut TestData,
diff --git a/testing/checkin/runner/ops_error.rs b/testing/checkin/runner/ops_error.rs
index b8e47a0..f0c8c7d 100644
--- a/testing/checkin/runner/ops_error.rs
+++ b/testing/checkin/runner/ops_error.rs
@@ -3,29 +3,29 @@ use anyhow::anyhow;
 use anyhow::Error;
 use deno_core::error::custom_error;
 use deno_core::error::type_error;
-use deno_core::op;
+use deno_core::op2;
 
-#[op(async)]
+#[op2(async)]
 pub async fn op_async_throw_error_eager() -> Result<(), Error> {
   Err(type_error("Error"))
 }
 
-#[op(async(deferred), fast)]
+#[op2(async(deferred), fast)]
 pub async fn op_async_throw_error_deferred() -> Result<(), Error> {
   Err(type_error("Error"))
 }
 
-#[op(async(lazy), fast)]
+#[op2(async(lazy), fast)]
 pub async fn op_async_throw_error_lazy() -> Result<(), Error> {
   Err(type_error("Error"))
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_error_custom_sync(#[string] message: String) -> Result<(), Error> {
   Err(custom_error("BadResource", message))
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_error_context_sync(
   #[string] message: String,
   #[string] context: String,
@@ -33,7 +33,7 @@ pub fn op_error_context_sync(
   Err(anyhow!(message).context(context))
 }
 
-#[op(async)]
+#[op2(async)]
 pub async fn op_error_context_async(
   #[string] message: String,
   #[string] context: String,
diff --git a/testing/checkin/runner/ops_io.rs b/testing/checkin/runner/ops_io.rs
index 84c7643..f591980 100644
--- a/testing/checkin/runner/ops_io.rs
+++ b/testing/checkin/runner/ops_io.rs
@@ -1,6 +1,6 @@
 // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
 use anyhow::Error;
-use deno_core::op;
+use deno_core::op2;
 use deno_core::AsyncRefCell;
 use deno_core::BufView;
 use deno_core::OpState;
@@ -53,7 +53,7 @@ impl Resource for PipeResource {
   }
 }
 
-#[op]
+#[op2]
 #[serde]
 pub fn op_pipe_create(op_state: &mut OpState) -> (ResourceId, ResourceId) {
   let (s1, s2) = tokio::io::duplex(1024);
@@ -87,7 +87,7 @@ impl Resource for FileResource {
   }
 }
 
-#[op(async)]
+#[op2(async)]
 #[serde]
 pub async fn op_file_open(
   #[string] path: String,
@@ -106,7 +106,7 @@ pub async fn op_file_open(
   Ok(rid)
 }
 
-#[op]
+#[op2]
 #[string]
 pub fn op_path_to_url(#[string] path: &str) -> Result<String, Error> {
   let path = std::path::absolute(path)?;
diff --git a/testing/checkin/runner/ops_worker.rs b/testing/checkin/runner/ops_worker.rs
index f677511..3aa0715 100644
--- a/testing/checkin/runner/ops_worker.rs
+++ b/testing/checkin/runner/ops_worker.rs
@@ -2,7 +2,7 @@
 use anyhow::anyhow;
 use anyhow::bail;
 use anyhow::Error;
-use deno_core::op;
+use deno_core::op2;
 use deno_core::url::Url;
 use deno_core::v8::IsolateHandle;
 use deno_core::GarbageCollected;
@@ -88,7 +88,7 @@ pub fn worker_create(
   (worker, worker_host_side)
 }
 
-#[op]
+#[op2]
 #[cppgc]
 pub fn op_worker_spawn(
   #[state] this_worker: &Worker,
@@ -154,7 +154,7 @@ async fn run_worker_task(
   Ok(())
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_worker_send(
   #[cppgc] worker: &WorkerControl,
   #[string] message: String,
@@ -163,13 +163,13 @@ pub fn op_worker_send(
   Ok(())
 }
 
-#[op(async)]
+#[op2(async)]
 #[string]
 pub async fn op_worker_recv(#[cppgc] worker: &WorkerControl) -> Option<String> {
   worker.worker_channel.rx.lock().await.recv().await
 }
 
-#[op]
+#[op2]
 #[cppgc]
 pub fn op_worker_parent(
   state: Rc<RefCell<OpState>>,
@@ -190,7 +190,7 @@ pub fn op_worker_parent(
   })
 }
 
-#[op(async)]
+#[op2(async)]
 pub async fn op_worker_await_close(#[cppgc] worker: &WorkerControl) {
   loop {
     if worker
@@ -207,7 +207,7 @@ pub async fn op_worker_await_close(#[cppgc] worker: &WorkerControl) {
   }
 }
 
-#[op(fast)]
+#[op2(fast)]
 pub fn op_worker_terminate(
   #[cppgc] worker: &WorkerControl,
   state: Rc<RefCell<OpState>>,
diff --git a/testing/checkin/runner/testing.rs b/testing/checkin/runner/testing.rs
index 58b3753..6665744 100644
--- a/testing/checkin/runner/testing.rs
+++ b/testing/checkin/runner/testing.rs
@@ -1,7 +1,7 @@
 // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
 use anyhow::bail;
 use anyhow::Error;
-use deno_core::op;
+use deno_core::op2;
 use deno_core::url::Url;
 use deno_core::v8;
 use deno_core::JsRuntime;
@@ -37,7 +37,7 @@ pub struct TestFunctions {
   pub functions: Vec<(String, v8::Global<v8::Function>)>,
 }
 
-#[op]
+#[op2]
 pub fn op_test_register(
   #[state] tests: &mut TestFunctions,
   #[string] name: String,