diff --git a/src/env.cc b/src/env.cc index 3deb4db09e6d92..e28866efd06894 100644 --- a/src/env.cc +++ b/src/env.cc @@ -10,6 +10,7 @@ using v8::Local; using v8::Message; using v8::StackFrame; using v8::StackTrace; +using v8::TryCatch; void Environment::PrintSyncTrace() const { if (!trace_sync_io_) @@ -55,4 +56,38 @@ void Environment::PrintSyncTrace() const { fflush(stderr); } + +bool Environment::KickNextTick() { + TickInfo* info = tick_info(); + + if (info->in_tick()) { + return true; + } + + if (info->length() == 0) { + isolate()->RunMicrotasks(); + } + + if (info->length() == 0) { + info->set_index(0); + return true; + } + + info->set_in_tick(true); + + // process nextTicks after call + TryCatch try_catch; + try_catch.SetVerbose(true); + tick_callback_function()->Call(process_object(), 0, nullptr); + + info->set_in_tick(false); + + if (try_catch.HasCaught()) { + info->set_last_threw(true); + return false; + } + + return true; +} + } // namespace node diff --git a/src/env.h b/src/env.h index 1801ffecd3ccea..5830b02b58e746 100644 --- a/src/env.h +++ b/src/env.h @@ -424,6 +424,8 @@ class Environment { void PrintSyncTrace() const; inline void set_trace_sync_io(bool value); + bool KickNextTick(); + inline uint32_t* heap_statistics_buffer() const; inline void set_heap_statistics_buffer(uint32_t* pointer); diff --git a/src/node.cc b/src/node.cc index a8723dc095f5c9..7ddae5205ee043 100644 --- a/src/node.cc +++ b/src/node.cc @@ -1026,7 +1026,6 @@ Handle MakeCallback(Environment* env, // If you hit this assertion, you forgot to enter the v8::Context first. CHECK_EQ(env->context(), env->isolate()->GetCurrentContext()); - Local process = env->process_object(); Local object, domain; bool has_async_queue = false; bool has_domain = false; @@ -1092,32 +1091,8 @@ Handle MakeCallback(Environment* env, return Undefined(env->isolate()); } - Environment::TickInfo* tick_info = env->tick_info(); - - if (tick_info->in_tick()) { - return ret; - } - - if (tick_info->length() == 0) { - env->isolate()->RunMicrotasks(); - } - - if (tick_info->length() == 0) { - tick_info->set_index(0); - return ret; - } - - tick_info->set_in_tick(true); - - // process nextTicks after call - env->tick_callback_function()->Call(process, 0, nullptr); - - tick_info->set_in_tick(false); - - if (try_catch.HasCaught()) { - tick_info->set_last_threw(true); + if (!env->KickNextTick()) return Undefined(env->isolate()); - } return ret; } diff --git a/src/node_internals.h b/src/node_internals.h index 8f35433b2f85c3..ffb5ec7ad96242 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -69,6 +69,8 @@ v8::Handle MakeCallback(Environment* env, int argc = 0, v8::Handle* argv = nullptr); +bool KickNextTick(); + // Convert a struct sockaddr to a { address: '1.2.3.4', port: 1234 } JS object. // Sets address and port properties on the info object and returns it. // If |info| is omitted, a new object is returned.