Skip to content

Commit c4cf44d

Browse files
committed
Rewrite Callback to add Callback::Reset
1 parent bd43cb9 commit c4cf44d

File tree

4 files changed

+50
-33
lines changed

4 files changed

+50
-33
lines changed

doc/callback.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ class Callback {
3535

3636
bool IsEmpty() const;
3737

38+
void Reset(const v8::Local<v8::Function> &fn);
39+
40+
void Reset();
41+
3842
v8::Local<v8::Value> Call(v8::Local<v8::Object> target,
3943
int argc,
4044
v8::Local<v8::Value> argv[]) const;

nan.h

Lines changed: 21 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1348,37 +1348,24 @@ typedef void NAN_INDEX_QUERY_RETURN_TYPE;
13481348

13491349
class Callback {
13501350
public:
1351-
Callback() {
1352-
HandleScope scope;
1353-
v8::Local<v8::Object> obj = New<v8::Object>();
1354-
handle.Reset(obj);
1355-
}
1351+
Callback() {}
13561352

1357-
explicit Callback(const v8::Local<v8::Function> &fn) {
1358-
HandleScope scope;
1359-
v8::Local<v8::Object> obj = New<v8::Object>();
1360-
handle.Reset(obj);
1361-
SetFunction(fn);
1362-
}
1353+
explicit Callback(const v8::Local<v8::Function> &fn) : handle_(fn) {}
13631354

13641355
~Callback() {
1365-
if (handle.IsEmpty()) return;
1366-
handle.Reset();
1356+
handle_.Reset();
13671357
}
13681358

13691359
bool operator==(const Callback &other) const {
1370-
HandleScope scope;
1371-
v8::Local<v8::Value> a = New(handle)->Get(kCallbackIndex);
1372-
v8::Local<v8::Value> b = New(other.handle)->Get(kCallbackIndex);
1373-
return a->StrictEquals(b);
1360+
return handle_ == other.handle_;
13741361
}
13751362

13761363
bool operator!=(const Callback &other) const {
1377-
return !this->operator==(other);
1364+
return !operator==(other);
13781365
}
13791366

13801367
inline
1381-
v8::Local<v8::Function> operator*() const { return this->GetFunction(); }
1368+
v8::Local<v8::Function> operator*() const { return GetFunction(); }
13821369

13831370
inline v8::Local<v8::Value> operator()(
13841371
v8::Local<v8::Object> target
@@ -1393,20 +1380,25 @@ class Callback {
13931380
return this->Call(argc, argv);
13941381
}
13951382

1383+
// TODO(kkoopa): remove
13961384
inline void SetFunction(const v8::Local<v8::Function> &fn) {
1397-
HandleScope scope;
1398-
Set(New(handle), kCallbackIndex, fn);
1385+
Reset(fn);
1386+
}
1387+
1388+
inline void Reset(const v8::Local<v8::Function> &fn) {
1389+
handle_.Reset(fn);
1390+
}
1391+
1392+
inline void Reset() {
1393+
handle_.Reset();
13991394
}
14001395

14011396
inline v8::Local<v8::Function> GetFunction() const {
1402-
EscapableHandleScope scope;
1403-
return scope.Escape(New(handle)->Get(kCallbackIndex)
1404-
.As<v8::Function>());
1397+
return New(handle_);
14051398
}
14061399

14071400
inline bool IsEmpty() const {
1408-
HandleScope scope;
1409-
return New(handle)->Get(kCallbackIndex)->IsUndefined();
1401+
return handle_.IsEmpty();
14101402
}
14111403

14121404
inline v8::Local<v8::Value>
@@ -1433,8 +1425,7 @@ class Callback {
14331425

14341426
private:
14351427
NAN_DISALLOW_ASSIGN_COPY_MOVE(Callback)
1436-
Persistent<v8::Object> handle;
1437-
static const uint32_t kCallbackIndex = 0;
1428+
Persistent<v8::Function> handle_;
14381429

14391430
#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
14401431
v8::Local<v8::Value> Call_(v8::Isolate *isolate
@@ -1443,8 +1434,7 @@ class Callback {
14431434
, v8::Local<v8::Value> argv[]) const {
14441435
EscapableHandleScope scope;
14451436

1446-
v8::Local<v8::Function> callback = New(handle)->
1447-
Get(kCallbackIndex).As<v8::Function>();
1437+
v8::Local<v8::Function> callback = New(handle_);
14481438
# if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
14491439
return scope.Escape(New(node::MakeCallback(
14501440
isolate
@@ -1469,8 +1459,7 @@ class Callback {
14691459
, v8::Local<v8::Value> argv[]) const {
14701460
EscapableHandleScope scope;
14711461

1472-
v8::Local<v8::Function> callback = New(handle)->
1473-
Get(kCallbackIndex).As<v8::Function>();
1462+
v8::Local<v8::Function> callback = New(handle_);
14741463
return scope.Escape(New(node::MakeCallback(
14751464
target
14761465
, callback

test/cpp/nancallback.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,18 @@ NAN_METHOD(CallAsFunction) {
4141
Callback(info[0].As<v8::Function>())();
4242
}
4343

44+
NAN_METHOD(ResetUnset) {
45+
Callback callback;
46+
callback.Reset();
47+
info.GetReturnValue().Set(callback.IsEmpty());
48+
}
49+
50+
NAN_METHOD(ResetSet) {
51+
Callback callback(info[0].As<v8::Function>());
52+
callback.Reset();
53+
info.GetReturnValue().Set(callback.IsEmpty());
54+
}
55+
4456
NAN_MODULE_INIT(Init) {
4557
Set(target
4658
, New<v8::String>("globalContext").ToLocalChecked()
@@ -66,6 +78,14 @@ NAN_MODULE_INIT(Init) {
6678
, New<v8::String>("callAsFunction").ToLocalChecked()
6779
, New<v8::FunctionTemplate>(CallAsFunction)->GetFunction()
6880
);
81+
Set(target
82+
, New<v8::String>("resetUnset").ToLocalChecked()
83+
, New<v8::FunctionTemplate>(ResetUnset)->GetFunction()
84+
);
85+
Set(target
86+
, New<v8::String>("resetSet").ToLocalChecked()
87+
, New<v8::FunctionTemplate>(ResetSet)->GetFunction()
88+
);
6989
}
7090

7191
NODE_MODULE(nancallback, Init)

test/js/nancallback-test.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const test = require('tap').test
1212
, round = Math.round;
1313

1414
test('nancallback', function (t) {
15-
t.plan(13)
15+
t.plan(17)
1616

1717
var persistent = bindings;
1818
t.type(persistent.globalContext, 'function');
@@ -21,11 +21,15 @@ test('nancallback', function (t) {
2121
t.type(persistent.compareCallbacks, 'function');
2222
t.type(persistent.callDirect, 'function');
2323
t.type(persistent.callAsFunction, 'function');
24+
t.type(persistent.resetUnset, 'function');
25+
t.type(persistent.resetSet, 'function');
2426
persistent.globalContext(function () { t.ok(true); });
2527
persistent.specificContext(function () { t.ok(true); });
2628
persistent.customReceiver(function () { t.equal(this, process); }, process);
2729
persistent.callDirect(function () { t.ok(true); });
2830
persistent.callAsFunction(function () { t.ok(true); });
31+
t.ok(persistent.resetUnset());
32+
t.ok(persistent.resetSet(function () {}));
2933

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

0 commit comments

Comments
 (0)