diff --git a/nan.h b/nan.h index ad5af847..328e9b1f 100644 --- a/nan.h +++ b/nan.h @@ -1852,75 +1852,47 @@ NAN_INLINE void SetInstanceTemplate( SetTemplate(templ->InstanceTemplate(), name, value, attributes); } -#if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION -NAN_INLINE void SetMethod( - v8::Handle recv - , const char *name - , FunctionCallback callback) { - HandleScope scope; - v8::Local fn = GetFunction(New( - callback)).ToLocalChecked(); - v8::Local fn_name = New(name).ToLocalChecked(); - fn->SetName(fn_name); - recv->Set(fn_name, fn); -} +namespace imp { -NAN_INLINE void SetMethod( - v8::Handle templ - , const char *name - , FunctionCallback callback) { - HandleScope scope; - v8::Local t = New(callback); - v8::Local fn_name = New(name).ToLocalChecked(); - t->SetClassName(fn_name); - templ->Set(fn_name, t); +// Note(@agnat): Helper to distinguish different receiver types. The first +// version deals with receivers derived from v8::Template. The second version +// handles everything else. The final argument only serves as discriminator and +// is unused. +template +NAN_INLINE +void +SetMethodAux(T recv, + v8::Local name, + v8::Local tpl, + v8::Template *) { + recv->Set(name, tpl); } -NAN_INLINE void SetMethod( - v8::Handle templ - , const char *name - , FunctionCallback callback) { - HandleScope scope; - v8::Local t = New(callback); - v8::Local fn_name = New(name).ToLocalChecked(); - t->SetClassName(fn_name); - templ->Set(fn_name, t); -} -#else -NAN_INLINE void SetMethod( - v8::Local recv - , const char *name - , FunctionCallback callback) { - HandleScope scope; - v8::Local fn = GetFunction(New( - callback)).ToLocalChecked(); - v8::Local fn_name = New(name).ToLocalChecked(); - fn->SetName(fn_name); - recv->Set(fn_name, fn); +template +NAN_INLINE +void +SetMethodAux(T recv, + v8::Local name, + v8::Local tpl, + ...) { + recv->Set(name, GetFunction(tpl).ToLocalChecked()); } -NAN_INLINE void SetMethod( - v8::Local templ - , const char *name - , FunctionCallback callback) { - HandleScope scope; - v8::Local t = New(callback); - v8::Local fn_name = New(name).ToLocalChecked(); - t->SetClassName(fn_name); - templ->Set(fn_name, t); -} +} // end of namespace imp +template class HandleType> NAN_INLINE void SetMethod( - v8::Local templ + HandleType recv , const char *name , FunctionCallback callback) { HandleScope scope; v8::Local t = New(callback); v8::Local fn_name = New(name).ToLocalChecked(); t->SetClassName(fn_name); - templ->Set(fn_name, t); + // Note(@agnat): Pass an empty T* as discriminator. See note on + // SetMethodAux(...) above + imp::SetMethodAux(recv, fn_name, t, static_cast(0)); } -#endif NAN_INLINE void SetPrototypeMethod( v8::Local recv diff --git a/package.json b/package.json index 61abba42..f7e3ecd8 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "url": "git://github.com/nodejs/nan.git" }, "scripts": { - "test": "tap --gc test/js/*-test.js", + "test": "tap --gc --stderr test/js/*-test.js", "rebuild-tests": "node-gyp rebuild --msvs_version=2013 --directory test", "docs": "doc/.build.sh" }, diff --git a/test/cpp/settemplate.cpp b/test/cpp/settemplate.cpp index a1d49e98..6ca4813b 100644 --- a/test/cpp/settemplate.cpp +++ b/test/cpp/settemplate.cpp @@ -30,6 +30,8 @@ MyObject::MyObject() { MyObject::~MyObject() { } +void Foo(FunctionCallbackInfo const&) {} + NAN_MODULE_INIT(MyObject::Init) { // Prepare constructor template v8::Local tpl = Nan::New(New); @@ -74,6 +76,19 @@ NAN_MODULE_INIT(MyObject::Init) { Set(target , Nan::New("MyObject").ToLocalChecked() , tpl->GetFunction()); + + + //=== SetMethod ============================================================== + + v8::Local obj = Nan::New(); + SetMethod(obj, "foo", Foo); + + // https://github.com/nodejs/nan/issues/564 + v8::Local func = Nan::New(Foo); + SetMethod(func, "foo", Foo); + + v8::Local t = Nan::New(Foo); + SetMethod(t, "foo", Foo); } NAN_METHOD(MyObject::New) {