Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Revert "src: move CallbackScope to separate cc/h"
This reverts commit fbd1c49.
  • Loading branch information
jasnell committed May 24, 2018
commit 435e6496dc82016cc4ae6b70bc7405a5e867b7c0
2 changes: 0 additions & 2 deletions node.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,6 @@

'sources': [
'src/async_wrap.cc',
'src/callback_scope.cc',
'src/cares_wrap.cc',
'src/connection_wrap.cc',
'src/connect_wrap.cc',
Expand Down Expand Up @@ -371,7 +370,6 @@
'src/async_wrap-inl.h',
'src/base_object.h',
'src/base_object-inl.h',
'src/callback_scope.h',
'src/connection_wrap.h',
'src/connect_wrap.h',
'src/env.h',
Expand Down
126 changes: 0 additions & 126 deletions src/callback_scope.cc

This file was deleted.

56 changes: 0 additions & 56 deletions src/callback_scope.h

This file was deleted.

111 changes: 111 additions & 0 deletions src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@ using v8::Undefined;
using v8::V8;
using v8::Value;

using AsyncHooks = Environment::AsyncHooks;

static Mutex process_mutex;
static Mutex environ_mutex;

Expand Down Expand Up @@ -922,6 +924,115 @@ void RemoveEnvironmentCleanupHook(v8::Isolate* isolate,
env->RemoveCleanupHook(fun, arg);
}


CallbackScope::CallbackScope(Isolate* isolate,
Local<Object> object,
async_context asyncContext)
: private_(new InternalCallbackScope(Environment::GetCurrent(isolate),
object,
asyncContext)),
try_catch_(isolate) {
try_catch_.SetVerbose(true);
}

CallbackScope::~CallbackScope() {
if (try_catch_.HasCaught())
private_->MarkAsFailed();
delete private_;
}

InternalCallbackScope::InternalCallbackScope(AsyncWrap* async_wrap)
: InternalCallbackScope(async_wrap->env(),
async_wrap->object(),
{ async_wrap->get_async_id(),
async_wrap->get_trigger_async_id() }) {}

InternalCallbackScope::InternalCallbackScope(Environment* env,
Local<Object> object,
const async_context& asyncContext,
ResourceExpectation expect)
: env_(env),
async_context_(asyncContext),
object_(object),
callback_scope_(env) {
if (expect == kRequireResource) {
CHECK(!object.IsEmpty());
}

if (!env->can_call_into_js()) {
failed_ = true;
return;
}

HandleScope handle_scope(env->isolate());
// If you hit this assertion, you forgot to enter the v8::Context first.
CHECK_EQ(Environment::GetCurrent(env->isolate()), env);

if (asyncContext.async_id != 0) {
// No need to check a return value because the application will exit if
// an exception occurs.
AsyncWrap::EmitBefore(env, asyncContext.async_id);
}

if (!IsInnerMakeCallback()) {
env->tick_info()->set_has_thrown(false);
}

env->async_hooks()->push_async_ids(async_context_.async_id,
async_context_.trigger_async_id);
pushed_ids_ = true;
}

InternalCallbackScope::~InternalCallbackScope() {
Close();
}

void InternalCallbackScope::Close() {
if (closed_) return;
closed_ = true;
HandleScope handle_scope(env_->isolate());

if (pushed_ids_)
env_->async_hooks()->pop_async_id(async_context_.async_id);

if (failed_) return;

if (async_context_.async_id != 0) {
AsyncWrap::EmitAfter(env_, async_context_.async_id);
}

if (IsInnerMakeCallback()) {
return;
}

Environment::TickInfo* tick_info = env_->tick_info();

if (!env_->can_call_into_js()) return;
if (!tick_info->has_scheduled()) {
env_->isolate()->RunMicrotasks();
}

// Make sure the stack unwound properly. If there are nested MakeCallback's
// then it should return early and not reach this code.
if (env_->async_hooks()->fields()[AsyncHooks::kTotals]) {
CHECK_EQ(env_->execution_async_id(), 0);
CHECK_EQ(env_->trigger_async_id(), 0);
}

if (!tick_info->has_scheduled() && !tick_info->has_promise_rejections()) {
return;
}

Local<Object> process = env_->process_object();

if (!env_->can_call_into_js()) return;

if (env_->tick_callback_function()->Call(process, 0, nullptr).IsEmpty()) {
env_->tick_info()->set_has_thrown(true);
failed_ = true;
}
}

MaybeLocal<Value> InternalMakeCallback(Environment* env,
Local<Object> recv,
const Local<Function> callback,
Expand Down
37 changes: 36 additions & 1 deletion src/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@
#include "v8.h" // NOLINT(build/include_order)
#include "v8-platform.h" // NOLINT(build/include_order)
#include "node_version.h" // NODE_MODULE_VERSION
#include "callback_scope.h"

#define NODE_MAKE_VERSION(major, minor, patch) \
((major) * 0x1000 + (minor) * 0x100 + (patch))
Expand Down Expand Up @@ -594,6 +593,12 @@ typedef void (*promise_hook_func) (v8::PromiseHookType type,
v8::Local<v8::Value> parent,
void* arg);

typedef double async_id;
struct async_context {
::node::async_id async_id;
::node::async_id trigger_async_id;
};

/* Registers an additional v8::PromiseHook wrapper. This API exists because V8
* itself supports only a single PromiseHook. */
NODE_EXTERN void AddPromiseHook(v8::Isolate* isolate,
Expand Down Expand Up @@ -642,6 +647,36 @@ NODE_EXTERN async_context EmitAsyncInit(v8::Isolate* isolate,
NODE_EXTERN void EmitAsyncDestroy(v8::Isolate* isolate,
async_context asyncContext);

class InternalCallbackScope;

/* This class works like `MakeCallback()` in that it sets up a specific
* asyncContext as the current one and informs the async_hooks and domains
* modules that this context is currently active.
*
* `MakeCallback()` is a wrapper around this class as well as
* `Function::Call()`. Either one of these mechanisms needs to be used for
* top-level calls into JavaScript (i.e. without any existing JS stack).
*
* This object should be stack-allocated to ensure that it is contained in a
* valid HandleScope.
*/
class NODE_EXTERN CallbackScope {
public:
CallbackScope(v8::Isolate* isolate,
v8::Local<v8::Object> resource,
async_context asyncContext);
~CallbackScope();

private:
InternalCallbackScope* private_;
v8::TryCatch try_catch_;

void operator=(const CallbackScope&) = delete;
void operator=(CallbackScope&&) = delete;
CallbackScope(const CallbackScope&) = delete;
CallbackScope(CallbackScope&&) = delete;
};

/* An API specific to emit before/after callbacks is unnecessary because
* MakeCallback will automatically call them for you.
*
Expand Down