Skip to content

Commit

Permalink
Add dereference and function call operators to NanCallback
Browse files Browse the repository at this point in the history
  • Loading branch information
kkoopa committed May 30, 2015
1 parent 0f3af8a commit 79b9779
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 9 deletions.
32 changes: 24 additions & 8 deletions nan.h
Original file line number Diff line number Diff line change
Expand Up @@ -1601,6 +1601,22 @@ class NanCallback {
return !this->operator==(other);
}

NAN_INLINE
v8::Local<v8::Function> operator*() const { return this->GetFunction(); }

NAN_INLINE v8::Local<v8::Value> operator()(
v8::Handle<v8::Object> target
, int argc = 0
, v8::Handle<v8::Value> argv[] = 0) const {
return this->Call(target, argc, argv);
}

NAN_INLINE v8::Local<v8::Value> operator()(
int argc = 0
, v8::Handle<v8::Value> argv[] = 0) const {
return this->Call(argc, argv);
}

NAN_INLINE void SetFunction(const v8::Handle<v8::Function> &fn) {
NanScope();
NanNew(handle)->Set(kCallbackIndex, fn);
Expand All @@ -1617,7 +1633,7 @@ class NanCallback {
return NanNew(handle)->Get(kCallbackIndex)->IsUndefined();
}

NAN_INLINE v8::Handle<v8::Value>
NAN_INLINE v8::Local<v8::Value>
Call(v8::Handle<v8::Object> target
, int argc
, v8::Handle<v8::Value> argv[]) const {
Expand All @@ -1629,7 +1645,7 @@ class NanCallback {
#endif
}

NAN_INLINE v8::Handle<v8::Value>
NAN_INLINE v8::Local<v8::Value>
Call(int argc, v8::Handle<v8::Value> argv[]) const {
#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
v8::Isolate *isolate = v8::Isolate::GetCurrent();
Expand All @@ -1645,37 +1661,37 @@ class NanCallback {
static const uint32_t kCallbackIndex = 0;

#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
v8::Handle<v8::Value> Call_(v8::Isolate *isolate
v8::Local<v8::Value> Call_(v8::Isolate *isolate
, v8::Handle<v8::Object> target
, int argc
, v8::Handle<v8::Value> argv[]) const {
NanEscapableScope();

v8::Local<v8::Function> callback = NanNew(handle)->
Get(kCallbackIndex).As<v8::Function>();
return NanEscapeScope(node::MakeCallback(
return NanEscapeScope(NanNew(node::MakeCallback(
isolate
, target
, callback
, argc
, argv
));
)));
}
#else
v8::Handle<v8::Value> Call_(v8::Handle<v8::Object> target
v8::Local<v8::Value> Call_(v8::Handle<v8::Object> target
, int argc
, v8::Handle<v8::Value> argv[]) const {
NanEscapableScope();

#if NODE_VERSION_AT_LEAST(0, 8, 0)
v8::Local<v8::Function> callback = handle->
Get(kCallbackIndex).As<v8::Function>();
return NanEscapeScope(node::MakeCallback(
return NanEscapeScope(NanNew(node::MakeCallback(
target
, callback
, argc
, argv
));
)));
#else
v8::Local<v8::Function> callback = handle->
Get(kCallbackIndex).As<v8::Function>();
Expand Down
20 changes: 20 additions & 0 deletions test/cpp/nancallback.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,18 @@ NAN_METHOD(CompareCallbacks) {
NanReturnValue(NanNew<v8::Boolean>(cb1 == cb2 && cb1 != cb3));
}

NAN_METHOD(CallDirect) {
NanScope();

NanCallback cb(args[0].As<v8::Function>());
(*cb)->Call(NanGetCurrentContext()->Global(), 0, NULL);
NanReturnUndefined();
}

NAN_METHOD(CallAsFunction) {
NanCallback(args[0].As<v8::Function>())();
}

void Init (v8::Handle<v8::Object> target) {
target->Set(
NanNew<v8::String>("globalContext")
Expand All @@ -59,6 +71,14 @@ void Init (v8::Handle<v8::Object> target) {
NanNew<v8::String>("compareCallbacks")
, NanNew<v8::FunctionTemplate>(CompareCallbacks)->GetFunction()
);
target->Set(
NanNew<v8::String>("callDirect")
, NanNew<v8::FunctionTemplate>(CallDirect)->GetFunction()
);
target->Set(
NanNew<v8::String>("callAsFunction")
, NanNew<v8::FunctionTemplate>(CallAsFunction)->GetFunction()
);
}

NODE_MODULE(nancallback, Init)
6 changes: 5 additions & 1 deletion test/js/nancallback-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,20 @@ const test = require('tap').test
, round = Math.round;

test('nancallback', function (t) {
t.plan(9)
t.plan(13)

var persistent = bindings;
t.type(persistent.globalContext, 'function');
t.type(persistent.specificContext, 'function');
t.type(persistent.customReceiver, 'function');
t.type(persistent.compareCallbacks, 'function');
t.type(persistent.callDirect, 'function');
t.type(persistent.callAsFunction, 'function');
persistent.globalContext(function () { t.ok(true); });
persistent.specificContext(function () { t.ok(true); });
persistent.customReceiver(function () { t.equal(this, process); }, process);
persistent.callDirect(function () { t.ok(true); });
persistent.callAsFunction(function () { t.ok(true); });

var round2 = Math.round
, x = function(param) { return param + 1; }
Expand Down

0 comments on commit 79b9779

Please sign in to comment.