summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDivy Srivastava <dj.srivastava23@gmail.com>2022-10-27 07:58:27 -0700
committerGitHub <noreply@github.com>2022-10-27 16:58:27 +0200
commit115cc1e6ae00cfd9283c1549060892e0c00dcbc4 (patch)
tree695d3d5715439796c48780df49039f1803d6aae3
parent02187966c108fd50354c8de57bab443a5b262373 (diff)
Revert "perf(core): generate inlined wrappers for async ops (#16428)" (#16443)
-rw-r--r--bench_util/js_runtime.rs5
-rw-r--r--cli/bench/async_ops.js5
-rw-r--r--cli/tests/unit/metrics_test.ts2
-rw-r--r--core/01_core.js88
-rw-r--r--core/bindings.rs92
-rw-r--r--core/examples/http_bench_json_ops.js4
-rw-r--r--core/extensions.rs3
-rw-r--r--core/runtime.rs56
-rw-r--r--ops/lib.rs122
-rw-r--r--runtime/js/99_main.js2
10 files changed, 113 insertions, 266 deletions
diff --git a/bench_util/js_runtime.rs b/bench_util/js_runtime.rs
index f87fa3b03..06dd79fae 100644
--- a/bench_util/js_runtime.rs
+++ b/bench_util/js_runtime.rs
@@ -63,6 +63,7 @@ pub fn bench_js_sync_with(
let code = v8::String::new(scope, looped_src.as_ref()).unwrap();
let script = v8::Script::compile(scope, code, None).unwrap();
+
// Run once if profiling, otherwise regular bench loop
if is_profiling() {
script.run(scope).unwrap();
@@ -101,9 +102,7 @@ pub fn bench_js_async_with(
};
let looped = loop_code(inner_iters, src);
let src = looped.as_ref();
- runtime
- .execute_script("init", "Deno.core.initializeAsyncOps();")
- .unwrap();
+
if is_profiling() {
for _ in 0..opts.profiling_outer {
tokio_runtime.block_on(inner_async(src, &mut runtime));
diff --git a/cli/bench/async_ops.js b/cli/bench/async_ops.js
index 2647accbd..ac4eb6858 100644
--- a/cli/bench/async_ops.js
+++ b/cli/bench/async_ops.js
@@ -5,7 +5,7 @@ let [total, count] = typeof Deno !== "undefined"
: [process.argv[2], process.argv[3]];
total = total ? parseInt(total, 0) : 50;
-count = count ? parseInt(count, 10) : 1000000;
+count = count ? parseInt(count, 10) : 100000;
async function bench(fun) {
const start = Date.now();
@@ -16,5 +16,4 @@ async function bench(fun) {
if (--total) queueMicrotask(() => bench(fun));
}
-const { ops } = Deno.core;
-bench(() => ops.op_void_async());
+bench(() => Deno.core.opAsync("op_void_async"));
diff --git a/cli/tests/unit/metrics_test.ts b/cli/tests/unit/metrics_test.ts
index 7f78d4578..82ff7ddd0 100644
--- a/cli/tests/unit/metrics_test.ts
+++ b/cli/tests/unit/metrics_test.ts
@@ -84,6 +84,6 @@ Deno.test(function opNamesMatch() {
// @ts-ignore: Deno.core allowed
Deno.core.opNames().sort(),
// @ts-ignore: Deno.core allowed
- Object.keys(Deno.core.ops).sort().filter((name) => name !== "asyncOpsInfo"),
+ Object.keys(Deno.core.ops).sort(),
);
});
diff --git a/core/01_core.js b/core/01_core.js
index 5df11c382..7bee019d9 100644
--- a/core/01_core.js
+++ b/core/01_core.js
@@ -28,7 +28,7 @@
SymbolFor,
setQueueMicrotask,
} = window.__bootstrap.primordials;
- const { ops } = window.Deno.core;
+ const ops = window.Deno.core.ops;
const errorMap = {};
// Builtin v8 / JS errors
@@ -159,63 +159,21 @@
return res;
}
- function rollPromiseId() {
- return nextPromiseId++;
- }
-
- // Generate async op wrappers. See core/bindings.rs
- function initializeAsyncOps() {
- function genAsyncOp(op, name, args) {
- return new Function(
- "setPromise",
- "getPromise",
- "promiseIdSymbol",
- "rollPromiseId",
- "handleOpCallTracing",
- "op",
- "unwrapOpResult",
- "PromisePrototypeThen",
- `
- return function ${name}(${args}) {
- const id = rollPromiseId();
- let promise = PromisePrototypeThen(setPromise(id), unwrapOpResult);
- try {
- op(id, ${args});
- } catch (err) {
- // Cleanup the just-created promise
- getPromise(id);
- // Rethrow the error
- throw err;
- }
- handleOpCallTracing("${name}", id, promise);
- promise[promiseIdSymbol] = id;
- return promise;
- }
- `,
- )(
- setPromise,
- getPromise,
- promiseIdSymbol,
- rollPromiseId,
- handleOpCallTracing,
- op,
- unwrapOpResult,
- PromisePrototypeThen,
- );
- }
-
- // { <name>: <argc>, ... }
- for (const ele of Object.entries(ops.asyncOpsInfo())) {
- if (!ele) continue;
- const [name, argc] = ele;
- const op = ops[name];
- const args = Array.from({ length: argc }, (_, i) => `arg${i}`).join(", ");
- ops[name] = genAsyncOp(op, name, args);
+ function opAsync(opName, ...args) {
+ const promiseId = nextPromiseId++;
+ let p = setPromise(promiseId);
+ try {
+ ops[opName](promiseId, ...args);
+ } catch (err) {
+ // Cleanup the just-created promise
+ getPromise(promiseId);
+ // Rethrow the error
+ throw err;
}
- }
-
- function handleOpCallTracing(opName, promiseId, p) {
+ p = PromisePrototypeThen(p, unwrapOpResult);
if (opCallTracingEnabled) {
+ // Capture a stack trace by creating a new `Error` object. We remove the
+ // first 6 characters (the `Error\n` prefix) to get just the stack trace.
const stack = StringPrototypeSlice(new Error().stack, 6);
MapPrototypeSet(opCallTraces, promiseId, { opName, stack });
p = PromisePrototypeFinally(
@@ -223,10 +181,9 @@
() => MapPrototypeDelete(opCallTraces, promiseId),
);
}
- }
-
- function opAsync(opName, ...args) {
- return ops[opName](...args);
+ // Save the id on the promise so it can later be ref'ed or unref'ed
+ p[promiseIdSymbol] = promiseId;
+ return p;
}
function refOp(promiseId) {
@@ -346,7 +303,6 @@
// Extra Deno.core.* exports
const core = ObjectAssign(globalThis.Deno.core, {
opAsync,
- initializeAsyncOps,
resources,
metrics,
registerErrorBuilder,
@@ -366,11 +322,11 @@
setPromiseHooks,
close: (rid) => ops.op_close(rid),
tryClose: (rid) => ops.op_try_close(rid),
- read: (rid, buffer) => ops.op_read(rid, buffer),
- readAll: (rid) => ops.op_read_all(rid),
- write: (rid, buffer) => ops.op_write(rid, buffer),
- writeAll: (rid, buffer) => ops.op_write_all(rid, buffer),
- shutdown: (rid) => ops.op_shutdown(rid),
+ read: opAsync.bind(null, "op_read"),
+ readAll: opAsync.bind(null, "op_read_all"),
+ write: opAsync.bind(null, "op_write"),
+ writeAll: opAsync.bind(null, "op_write_all"),
+ shutdown: opAsync.bind(null, "op_shutdown"),
print: (msg, isErr) => ops.op_print(msg, isErr),
setMacrotaskCallback: (fn) => ops.op_set_macrotask_callback(fn),
setNextTickCallback: (fn) => ops.op_set_next_tick_callback(fn),
diff --git a/core/bindings.rs b/core/bindings.rs
index 60d15f745..741ab6336 100644
--- a/core/bindings.rs
+++ b/core/bindings.rs
@@ -97,7 +97,6 @@ pub fn initialize_context<'s>(
scope: &mut v8::HandleScope<'s, ()>,
op_ctxs: &[OpCtx],
snapshot_loaded: bool,
- will_snapshot: bool,
) -> v8::Local<'s, v8::Context> {
let scope = &mut v8::EscapableHandleScope::new(scope);
@@ -117,9 +116,7 @@ pub fn initialize_context<'s>(
let ops_obj = JsRuntime::grab_global::<v8::Object>(scope, "Deno.core.ops")
.expect("Deno.core.ops to exist");
initialize_ops(scope, ops_obj, op_ctxs, snapshot_loaded);
- if !will_snapshot {
- initialize_async_ops_info(scope, ops_obj, op_ctxs);
- }
+
return scope.escape(context);
}
@@ -131,10 +128,8 @@ pub fn initialize_context<'s>(
// Bind functions to Deno.core.ops.*
let ops_obj = JsRuntime::ensure_objs(scope, global, "Deno.core.ops").unwrap();
- if !will_snapshot {
- initialize_async_ops_info(scope, ops_obj, op_ctxs);
- }
- initialize_ops(scope, ops_obj, op_ctxs, !will_snapshot);
+
+ initialize_ops(scope, ops_obj, op_ctxs, snapshot_loaded);
scope.escape(context)
}
@@ -595,84 +590,3 @@ pub fn throw_type_error(scope: &mut v8::HandleScope, message: impl AsRef<str>) {
let exception = v8::Exception::type_error(scope, message);
scope.throw_exception(exception);
}
-
-struct AsyncOpsInfo {
- ptr: *const OpCtx,
- len: usize,
-}
-
-impl<'s> IntoIterator for &'s AsyncOpsInfo {
- type Item = &'s OpCtx;
- type IntoIter = AsyncOpsInfoIterator<'s>;
-
- fn into_iter(self) -> Self::IntoIter {
- AsyncOpsInfoIterator {
- // SAFETY: OpCtx slice is valid for the lifetime of the Isolate
- info: unsafe { std::slice::from_raw_parts(self.ptr, self.len) },
- index: 0,
- }
- }
-}
-
-struct AsyncOpsInfoIterator<'s> {
- info: &'s [OpCtx],
- index: usize,
-}
-
-impl<'s> Iterator for AsyncOpsInfoIterator<'s> {
- type Item = &'s OpCtx;
-
- fn next(&mut self) -> Option<Self::Item> {
- loop {
- match self.info.get(self.index) {
- Some(ctx) if ctx.decl.is_async => {
- self.index += 1;
- return Some(ctx);
- }
- Some(_) => {
- self.index += 1;
- }
- None => return None,
- }
- }
- }
-}
-
-fn async_ops_info(
- scope: &mut v8::HandleScope,
- args: v8::FunctionCallbackArguments,
- mut rv: v8::ReturnValue,
-) {
- let async_op_names = v8::Object::new(scope);
- let external: v8::Local<v8::External> = args.data().try_into().unwrap();
- let info: &AsyncOpsInfo =
- // SAFETY: external is guaranteed to be a valid pointer to AsyncOpsInfo
- unsafe { &*(external.value() as *const AsyncOpsInfo) };
- for ctx in info {
- let name = v8::String::new(scope, ctx.decl.name).unwrap();
- let argc = v8::Integer::new(scope, ctx.decl.argc as i32);
- async_op_names.set(scope, name.into(), argc.into());
- }
- rv.set(async_op_names.into());
-}
-
-fn initialize_async_ops_info(
- scope: &mut v8::HandleScope,
- ops_obj: v8::Local<v8::Object>,
- op_ctxs: &[OpCtx],
-) {
- let key = v8::String::new(scope, "asyncOpsInfo").unwrap();
- let external = v8::External::new(
- scope,
- Box::into_raw(Box::new(AsyncOpsInfo {
- ptr: op_ctxs as *const [OpCtx] as _,
- len: op_ctxs.len(),
- })) as *mut c_void,
- );
- let val = v8::Function::builder(async_ops_info)
- .data(external.into())
- .build(scope)
- .unwrap();
- val.set_name(key);
- ops_obj.set(scope, key.into(), val.into());
-}
diff --git a/core/examples/http_bench_json_ops.js b/core/examples/http_bench_json_ops.js
index 261d91559..883ef1752 100644
--- a/core/examples/http_bench_json_ops.js
+++ b/core/examples/http_bench_json_ops.js
@@ -2,8 +2,6 @@
// This is not a real HTTP server. We read blindly one time into 'requestBuf',
// then write this fixed 'responseBuf'. The point of this benchmark is to
// exercise the event loop in a simple yet semi-realistic way.
-Deno.core.initializeAsyncOps();
-
const requestBuf = new Uint8Array(64 * 1024);
const responseBuf = new Uint8Array(
"HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nHello World\n"
@@ -18,7 +16,7 @@ function listen() {
/** Accepts a connection, returns rid. */
function accept(serverRid) {
- return Deno.core.ops.op_accept(serverRid);
+ return Deno.core.opAsync("op_accept", serverRid);
}
async function serve(rid) {
diff --git a/core/extensions.rs b/core/extensions.rs
index 7b9ab5908..846770d1f 100644
--- a/core/extensions.rs
+++ b/core/extensions.rs
@@ -16,9 +16,6 @@ pub struct OpDecl {
pub enabled: bool,
pub is_async: bool,
pub is_unstable: bool,
- /// V8 argument count. Used as an optimization
- /// hint by `core.initalizeAsyncOps`.
- pub argc: usize,
pub is_v8: bool,
pub fast_fn: Option<Box<dyn FastFunction>>,
}
diff --git a/core/runtime.rs b/core/runtime.rs
index 294982b7c..e574bf9d3 100644
--- a/core/runtime.rs
+++ b/core/runtime.rs
@@ -384,8 +384,7 @@ impl JsRuntime {
isolate_ptr.read()
};
let scope = &mut v8::HandleScope::new(&mut isolate);
- let context =
- bindings::initialize_context(scope, &op_ctxs, false, true);
+ let context = bindings::initialize_context(scope, &op_ctxs, false);
global_context = v8::Global::new(scope, context);
scope.set_default_context(context);
}
@@ -423,7 +422,7 @@ impl JsRuntime {
};
let scope = &mut v8::HandleScope::new(&mut isolate);
let context =
- bindings::initialize_context(scope, &op_ctxs, snapshot_loaded, false);
+ bindings::initialize_context(scope, &op_ctxs, snapshot_loaded);
global_context = v8::Global::new(scope, context);
}
@@ -551,7 +550,6 @@ impl JsRuntime {
scope,
&self.state.borrow().op_ctxs,
self.built_from_snapshot,
- false,
);
JsRealm::new(v8::Global::new(scope, context))
};
@@ -2245,7 +2243,6 @@ pub mod tests {
#[derive(Copy, Clone)]
enum Mode {
Async,
- AsyncDeferred,
AsyncZeroCopy(bool),
}
@@ -2254,28 +2251,20 @@ pub mod tests {
dispatch_count: Arc<AtomicUsize>,
}
- #[op]
+ #[op(deferred)]
async fn op_test(
rc_op_state: Rc<RefCell<OpState>>,
control: u8,
buf: Option<ZeroCopyBuf>,
) -> Result<u8, AnyError> {
- #![allow(clippy::await_holding_refcell_ref)] // False positive.
let op_state_ = rc_op_state.borrow();
let test_state = op_state_.borrow::<TestState>();
test_state.dispatch_count.fetch_add(1, Ordering::Relaxed);
- let mode = test_state.mode;
- drop(op_state_);
- match mode {
+ match test_state.mode {
Mode::Async => {
assert_eq!(control, 42);
Ok(43)
}
- Mode::AsyncDeferred => {
- tokio::task::yield_now().await;
- assert_eq!(control, 42);
- Ok(43)
- }
Mode::AsyncZeroCopy(has_buffer) => {
assert_eq!(buf.is_some(), has_buffer);
if let Some(buf) = buf {
@@ -2325,15 +2314,14 @@ pub mod tests {
#[test]
fn test_ref_unref_ops() {
- let (mut runtime, _dispatch_count) = setup(Mode::AsyncDeferred);
+ let (mut runtime, _dispatch_count) = setup(Mode::Async);
runtime
.execute_script(
"filename.js",
r#"
- Deno.core.initializeAsyncOps();
var promiseIdSymbol = Symbol.for("Deno.core.internalPromiseId");
- var p1 = Deno.core.ops.op_test(42);
- var p2 = Deno.core.ops.op_test(42);
+ var p1 = Deno.core.opAsync("op_test", 42);
+ var p2 = Deno.core.opAsync("op_test", 42);
"#,
)
.unwrap();
@@ -2386,7 +2374,6 @@ pub mod tests {
"filename.js",
r#"
let control = 42;
- Deno.core.initializeAsyncOps();
Deno.core.opAsync("op_test", control);
async function main() {
Deno.core.opAsync("op_test", control);
@@ -2405,7 +2392,6 @@ pub mod tests {
.execute_script(
"filename.js",
r#"
- Deno.core.initializeAsyncOps();
const p = Deno.core.opAsync("op_test", 42);
if (p[Symbol.for("Deno.core.internalPromiseId")] == undefined) {
throw new Error("missing id on returned promise");
@@ -2422,7 +2408,6 @@ pub mod tests {
.execute_script(
"filename.js",
r#"
- Deno.core.initializeAsyncOps();
Deno.core.opAsync("op_test");
"#,
)
@@ -2437,7 +2422,6 @@ pub mod tests {
.execute_script(
"filename.js",
r#"
- Deno.core.initializeAsyncOps();
let zero_copy_a = new Uint8Array([0]);
Deno.core.opAsync("op_test", null, zero_copy_a);
"#,
@@ -3037,6 +3021,7 @@ pub mod tests {
function main() {
console.log("asdf);
}
+
main();
"#,
);
@@ -3056,16 +3041,18 @@ function assert(cond) {
throw Error("assert");
}
}
+
function main() {
assert(false);
}
+
main();
"#,
);
let expected_error = r#"Error: assert
at assert (error_stack.js:4:11)
- at main (error_stack.js:8:3)
- at error_stack.js:10:1"#;
+ at main (error_stack.js:9:3)
+ at error_stack.js:12:1"#;
assert_eq!(result.unwrap_err().to_string(), expected_error);
}
@@ -3083,6 +3070,7 @@ main();
throw new Error("async");
});
})();
+
try {
await p;
} catch (error) {
@@ -3095,7 +3083,7 @@ main();
let expected_error = r#"Error: async
at error_async_stack.js:5:13
at async error_async_stack.js:4:5
- at async error_async_stack.js:9:5"#;
+ at async error_async_stack.js:10:5"#;
match runtime.poll_event_loop(cx, false) {
Poll::Ready(Err(e)) => {
@@ -3188,6 +3176,7 @@ function assertEquals(a, b) {
const sab = new SharedArrayBuffer(16);
const i32a = new Int32Array(sab);
globalThis.resolved = false;
+
(function() {
const result = Atomics.waitAsync(i32a, 0, 0);
result.value.then(
@@ -3195,6 +3184,7 @@ globalThis.resolved = false;
() => { assertUnreachable();
});
})();
+
const notify_return_value = Atomics.notify(i32a, 0, 1);
assertEquals(1, notify_return_value);
"#,
@@ -3304,7 +3294,7 @@ assertEquals(1, notify_return_value);
runtime
.execute_script(
"op_async_borrow.js",
- "Deno.core.initializeAsyncOps(); Deno.core.ops.op_async_borrow()",
+ "Deno.core.opAsync('op_async_borrow')",
)
.unwrap();
runtime.run_event_loop(false).await.unwrap();
@@ -3378,8 +3368,7 @@ Deno.core.ops.op_sync_serialize_object_with_numbers_as_keys({
.execute_script(
"op_async_serialize_object_with_numbers_as_keys.js",
r#"
-Deno.core.initializeAsyncOps();
-Deno.core.ops.op_async_serialize_object_with_numbers_as_keys({
+Deno.core.opAsync('op_async_serialize_object_with_numbers_as_keys', {
lines: {
100: {
unit: "m"
@@ -3417,7 +3406,6 @@ Deno.core.ops.op_async_serialize_object_with_numbers_as_keys({
.execute_script(
"macrotasks_and_nextticks.js",
r#"
- Deno.core.initializeAsyncOps();
(async function () {
const results = [];
Deno.core.ops.op_set_macrotask_callback(() => {
@@ -3428,6 +3416,7 @@ Deno.core.ops.op_async_serialize_object_with_numbers_as_keys({
results.push("nextTick");
Deno.core.ops.op_set_has_tick_scheduled(false);
});
+
Deno.core.ops.op_set_has_tick_scheduled(true);
await Deno.core.opAsync('op_async_sleep');
if (results[0] != "nextTick") {
@@ -3638,6 +3627,7 @@ Deno.core.ops.op_async_serialize_object_with_numbers_as_keys({
Deno.core.ops.op_store_pending_promise_exception(promise);
Deno.core.ops.op_promise_reject();
});
+
new Promise((_, reject) => reject(Error("reject")));
"#,
)
@@ -3655,6 +3645,7 @@ Deno.core.ops.op_async_serialize_object_with_numbers_as_keys({
prev(...args);
});
}
+
new Promise((_, reject) => reject(Error("reject")));
"#,
)
@@ -3704,6 +3695,7 @@ Deno.core.ops.op_async_serialize_object_with_numbers_as_keys({
Deno.core.ops.op_set_promise_reject_callback((type, promise, reason) => {
Deno.core.ops.op_promise_reject();
});
+
throw new Error('top level throw');
"#;
@@ -3834,6 +3826,8 @@ Deno.core.ops.op_async_serialize_object_with_numbers_as_keys({
const a1b = a1.subarray(0, 3);
const a2 = new Uint8Array([5,10,15]);
const a2b = a2.subarray(0, 3);
+
+
if (!(a1.length > 0 && a1b.length > 0)) {
throw new Error("a1 & a1b should have a length");
}
@@ -3844,6 +3838,7 @@ Deno.core.ops.op_async_serialize_object_with_numbers_as_keys({
if (a1.length > 0 || a1b.length > 0) {
throw new Error("expecting a1 & a1b to be detached");
}
+
const a3 = Deno.core.ops.op_boomerang(a2b);
if (a3.byteLength != 3) {
throw new Error(`Expected a3.byteLength === 3, got ${a3.byteLength}`);
@@ -3854,6 +3849,7 @@ Deno.core.ops.op_async_serialize_object_with_numbers_as_keys({
if (a2.byteLength > 0 || a2b.byteLength > 0) {
throw new Error("expecting a2 & a2b to be detached, a3 re-attached");
}
+
const wmem = new WebAssembly.Memory({ initial: 1, maximum: 2 });
const w32 = new Uint32Array(wmem.buffer);
w32[0] = 1; w32[1] = 2; w32[2] = 3;
diff --git a/ops/lib.rs b/ops/lib.rs
index 44f783280..8cd85f4f3 100644
--- a/ops/lib.rs
+++ b/ops/lib.rs
@@ -118,7 +118,7 @@ pub fn op(attr: TokenStream, item: TokenStream) -> TokenStream {
let (has_fallible_fast_call, fast_impl, fast_field) =
codegen_fast_impl(&core, &func, name, is_async, must_be_fast);
- let (v8_body, argc) = if is_async {
+ let v8_body = if is_async {
codegen_v8_async(&core, &func, margs, asyncness, deferred)
} else {
codegen_v8_sync(&core, &func, margs, has_fallible_fast_call)
@@ -154,7 +154,6 @@ pub fn op(attr: TokenStream, item: TokenStream) -> TokenStream {
is_async: #is_async,
is_unstable: #is_unstable,
is_v8: #is_v8,
- argc: #argc,
}
}
@@ -182,7 +181,7 @@ fn codegen_v8_async(
margs: MacroArgs,
asyncness: bool,
deferred: bool,
-) -> (TokenStream2, usize) {
+) -> TokenStream2 {
let MacroArgs { is_v8, .. } = margs;
let special_args = f
.sig
@@ -195,7 +194,7 @@ fn codegen_v8_async(
let rust_i0 = special_args.len();
let args_head = special_args.into_iter().collect::<TokenStream2>();
- let (arg_decls, args_tail, argc) = codegen_args(core, f, rust_i0, 1);
+ let (arg_decls, args_tail) = codegen_args(core, f, rust_i0, 1);
let type_params = exclude_lifetime_params(&f.sig.generics.params);
let (pre_result, mut result_fut) = match asyncness {
@@ -226,47 +225,44 @@ fn codegen_v8_async(
false => quote! { let result = Ok(result); },
};
- (
- quote! {
- use #core::futures::FutureExt;
- // SAFETY: #core guarantees args.data() is a v8 External pointing to an OpCtx for the isolates lifetime
- let ctx = unsafe {
- &*(#core::v8::Local::<#core::v8::External>::cast(args.data()).value()
- as *const #core::_ops::OpCtx)
- };
- let op_id = ctx.id;
-
- let promise_id = args.get(0);
- let promise_id = #core::v8::Local::<#core::v8::Integer>::try_from(promise_id)
- .map(|l| l.value() as #core::PromiseId)
- .map_err(#core::anyhow::Error::from);
- // Fail if promise id invalid (not an int)
- let promise_id: #core::PromiseId = match promise_id {
- Ok(promise_id) => promise_id,
- Err(err) => {
- #core::_ops::throw_type_error(scope, format!("invalid promise id: {}", err));
- return;
- }
- };
+ quote! {
+ use #core::futures::FutureExt;
+ // SAFETY: #core guarantees args.data() is a v8 External pointing to an OpCtx for the isolates lifetime
+ let ctx = unsafe {
+ &*(#core::v8::Local::<#core::v8::External>::cast(args.data()).value()
+ as *const #core::_ops::OpCtx)
+ };
+ let op_id = ctx.id;
+
+ let promise_id = args.get(0);
+ let promise_id = #core::v8::Local::<#core::v8::Integer>::try_from(promise_id)
+ .map(|l| l.value() as #core::PromiseId)
+ .map_err(#core::anyhow::Error::from);
+ // Fail if promise id invalid (not an int)
+ let promise_id: #core::PromiseId = match promise_id {
+ Ok(promise_id) => promise_id,
+ Err(err) => {
+ #core::_ops::throw_type_error(scope, format!("invalid promise id: {}", err));
+ return;
+ }
+ };
- #arg_decls
+ #arg_decls
- // Track async call & get copy of get_error_class_fn
- let get_class = {
- let state = ::std::cell::RefCell::borrow(&ctx.state);
- state.tracker.track_async(op_id);
- state.get_error_class_fn
- };
+ // Track async call & get copy of get_error_class_fn
+ let get_class = {
+ let state = ::std::cell::RefCell::borrow(&ctx.state);
+ state.tracker.track_async(op_id);
+ state.get_error_class_fn
+ };
- #pre_result
- #core::_ops::queue_async_op(ctx, scope, #deferred, async move {
- let result = #result_fut
- #result_wrapper
- (promise_id, op_id, #core::_ops::to_op_result(get_class, result))
- });
- },
- argc,
- )
+ #pre_result
+ #core::_ops::queue_async_op(ctx, scope, #deferred, async move {
+ let result = #result_fut
+ #result_wrapper
+ (promise_id, op_id, #core::_ops::to_op_result(get_class, result))
+ });
+ }
}
fn scope_arg(arg: &FnArg) -> Option<TokenStream2> {
@@ -520,7 +516,7 @@ fn codegen_v8_sync(
f: &syn::ItemFn,
margs: MacroArgs,
has_fallible_fast_call: bool,
-) -> (TokenStream2, usize) {
+) -> TokenStream2 {
let MacroArgs { is_v8, .. } = margs;
let special_args = f
.sig
@@ -532,7 +528,7 @@ fn codegen_v8_sync(
.collect::<Vec<_>>();
let rust_i0 = special_args.len();
let args_head = special_args.into_iter().collect::<TokenStream2>();
- let (arg_decls, args_tail, argc) = codegen_args(core, f, rust_i0, 0);
+ let (arg_decls, args_tail) = codegen_args(core, f, rust_i0, 0);
let ret = codegen_sync_ret(core, &f.sig.output);
let type_params = exclude_lifetime_params(&f.sig.generics.params);
@@ -551,27 +547,24 @@ fn codegen_v8_sync(
quote! {}
};
- (
- quote! {
- // SAFETY: #core guarantees args.data() is a v8 External pointing to an OpCtx for the isolates lifetime
- let ctx = unsafe {
- &*(#core::v8::Local::<#core::v8::External>::cast(args.data()).value()
- as *const #core::_ops::OpCtx)
- };
+ quote! {
+ // SAFETY: #core guarantees args.data() is a v8 External pointing to an OpCtx for the isolates lifetime
+ let ctx = unsafe {
+ &*(#core::v8::Local::<#core::v8::External>::cast(args.data()).value()
+ as *const #core::_ops::OpCtx)
+ };
- #fast_error_handler
- #arg_decls
+ #fast_error_handler
+ #arg_decls
- let result = Self::call::<#type_params>(#args_head #args_tail);
+ let result = Self::call::<#type_params>(#args_head #args_tail);
- // use RefCell::borrow instead of state.borrow to avoid clash with std::borrow::Borrow
- let op_state = ::std::cell::RefCell::borrow(&*ctx.state);
- op_state.tracker.track_sync(ctx.id);
+ // use RefCell::borrow instead of state.borrow to avoid clash with std::borrow::Borrow
+ let op_state = ::std::cell::RefCell::borrow(&*ctx.state);
+ op_state.tracker.track_sync(ctx.id);
- #ret
- },
- argc,
- )
+ #ret
+ }
}
struct FastApiSyn {
@@ -810,15 +803,12 @@ fn is_fast_scalar(
}
}
-/// (full declarations, idents, v8 argument count)
-type ArgumentDecl = (TokenStream2, TokenStream2, usize);
-
fn codegen_args(
core: &TokenStream2,
f: &syn::ItemFn,
rust_i0: usize, // Index of first generic arg in rust
v8_i0: usize, // Index of first generic arg in v8/js
-) -> ArgumentDecl {
+) -> (TokenStream2, TokenStream2) {
let inputs = &f.sig.inputs.iter().skip(rust_i0).enumerate();
let ident_seq: TokenStream2 = inputs
.clone()
@@ -833,7 +823,7 @@ fn codegen_args(
codegen_arg(core, arg, format!("arg_{i}").as_ref(), v8_i0 + i)
})
.collect();
- (decls, ident_seq, inputs.len())
+ (decls, ident_seq)
}
fn codegen_arg(
diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js
index ef99969b2..afacd9b34 100644
--- a/runtime/js/99_main.js
+++ b/runtime/js/99_main.js
@@ -692,7 +692,6 @@ delete Intl.v8BreakIterator;
throw new Error("Worker runtime already bootstrapped");
}
- core.initializeAsyncOps();
performance.setTimeOrigin(DateNow());
net.setup(runtimeOptions.unstableFlag);
@@ -792,7 +791,6 @@ delete Intl.v8BreakIterator;
throw new Error("Worker runtime already bootstrapped");
}
- core.initializeAsyncOps();
performance.setTimeOrigin(DateNow());
net.setup(runtimeOptions.unstableFlag);