summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/01_core.js16
-rw-r--r--core/runtime.rs38
2 files changed, 25 insertions, 29 deletions
diff --git a/core/01_core.js b/core/01_core.js
index ab54316e5..4cefb52e9 100644
--- a/core/01_core.js
+++ b/core/01_core.js
@@ -194,8 +194,9 @@
function opAsync2(name, arg0, arg1) {
const id = nextPromiseId++;
let promise = PromisePrototypeThen(setPromise(id), unwrapOpResult);
+ let maybeResult;
try {
- ops[name](id, arg0, arg1);
+ maybeResult = ops[name](id, arg0, arg1);
} catch (err) {
// Cleanup the just-created promise
getPromise(id);
@@ -204,14 +205,20 @@
}
promise = handleOpCallTracing(name, id, promise);
promise[promiseIdSymbol] = id;
+ if (typeof maybeResult !== "undefined") {
+ const promise = getPromise(id);
+ promise.resolve(maybeResult);
+ }
+
return promise;
}
function opAsync(name, ...args) {
const id = nextPromiseId++;
let promise = PromisePrototypeThen(setPromise(id), unwrapOpResult);
+ let maybeResult;
try {
- ops[name](id, ...new SafeArrayIterator(args));
+ maybeResult = ops[name](id, ...new SafeArrayIterator(args));
} catch (err) {
// Cleanup the just-created promise
getPromise(id);
@@ -220,6 +227,11 @@
}
promise = handleOpCallTracing(name, id, promise);
promise[promiseIdSymbol] = id;
+ if (typeof maybeResult !== "undefined") {
+ const promise = getPromise(id);
+ promise.resolve(maybeResult);
+ }
+
return promise;
}
diff --git a/core/runtime.rs b/core/runtime.rs
index ef65d2192..b03f3f7d0 100644
--- a/core/runtime.rs
+++ b/core/runtime.rs
@@ -2437,12 +2437,12 @@ pub fn queue_fast_async_op(
}
#[inline]
-pub fn queue_async_op(
+pub fn queue_async_op<'s>(
ctx: &OpCtx,
- scope: &mut v8::HandleScope,
+ scope: &'s mut v8::HandleScope,
deferred: bool,
op: impl Future<Output = (RealmIdx, PromiseId, OpId, OpResult)> + 'static,
-) {
+) -> Option<v8::Local<'s, v8::Value>> {
let runtime_state = match ctx.runtime_state.upgrade() {
Some(rc_state) => rc_state,
// atleast 1 Rc is held by the JsRuntime.
@@ -2459,31 +2459,13 @@ pub fn queue_async_op(
);
match OpCall::eager(op) {
- // This calls promise.resolve() before the control goes back to userland JS. It works something
- // along the lines of:
- //
- // function opresolve(promiseId, ...) {
- // getPromise(promiseId).resolve(...);
- // }
- // const p = setPromise();
- // op.op_async(promiseId, ...); // Calls `opresolve`
- // return p;
- EagerPollResult::Ready((_, promise_id, op_id, mut resp)) if !deferred => {
- let context_state_rc = JsRealm::state_from_scope(scope);
- let context_state = context_state_rc.borrow();
-
- let args = &[
- v8::Integer::new(scope, promise_id).into(),
- resp.to_v8(scope).unwrap(),
- ];
-
+ // If the result is ready we'll just return it straight to the caller, so
+ // we don't have to invoke a JS callback to respond. // This works under the
+ // assumption that `()` return value is serialized as `null`.
+ EagerPollResult::Ready((_, _, op_id, mut resp)) if !deferred => {
+ let resp = resp.to_v8(scope).unwrap();
ctx.state.borrow_mut().tracker.track_async_completed(op_id);
-
- let tc_scope = &mut v8::TryCatch::new(scope);
- let js_recv_cb =
- context_state.js_recv_cb.as_ref().unwrap().open(tc_scope);
- let this = v8::undefined(tc_scope).into();
- js_recv_cb.call(tc_scope, this, args);
+ return Some(resp);
}
EagerPollResult::Ready(op) => {
let ready = OpCall::ready(op);
@@ -2497,6 +2479,8 @@ pub fn queue_async_op(
state.have_unpolled_ops = true;
}
}
+
+ None
}
#[cfg(test)]