void EventHook::onFunctionReturn(ActRec* ar, TypedValue retval) { // The locals are already gone. Null out everything. ar->setThisOrClassAllowNull(nullptr); ar->setLocalsDecRefd(); ar->setVarEnv(nullptr); try { auto const flags = check_request_surprise(); onFunctionExit(ar, &retval, false, nullptr, flags); // Async profiler if ((flags & AsyncEventHookFlag) && ar->func()->isAsyncFunction() && ar->resumed()) { auto session = AsioSession::Get(); // Return @ resumed execution => AsyncFunctionWaitHandle succeeded. if (session->hasOnResumableSuccess()) { auto afwh = frame_afwh(ar); session->onResumableSuccess(afwh, cellAsCVarRef(retval)); } } } catch (...) { /* * We're responsible for freeing the return value if we exit with an * exception. See irgen-ret. */ tvRefcountedDecRef(retval); throw; } }
void AsioSession::updateEventHookState() { if (hasOnResumableCreate() || hasOnResumableAwait() || hasOnResumableSuccess()) { EventHook::EnableAsync(); } else { EventHook::DisableAsync(); } }