diff --git a/nan.h b/nan.h index c24260a1..1544d83b 100644 --- a/nan.h +++ b/nan.h @@ -63,6 +63,14 @@ typedef v8::UnboundScript NanUnboundScript; typedef v8::Script NanBoundScript; #endif +#if (NODE_MODULE_VERSION < 42) +typedef v8::String::ExternalAsciiStringResource + NanExternalOneByteStringResource; +#else // io.js v1.0.0 +typedef v8::String::ExternalOneByteStringResource + NanExternalOneByteStringResource; +#endif + #include "nan_new.h" // NOLINT(build/include) // uv helpers @@ -1716,6 +1724,30 @@ template static size_t _nan_hex_decode( return i; } +namespace NanIntern { + +inline +NanExternalOneByteStringResource const* +GetExternalResource(v8::Local str) { +#if NODE_MODULE_VERSION < 42 + return str->GetExternalAsciiStringResource(); +#else // io.js v1.0.0 + return str->GetExternalOneByteStringResource(); +#endif +} + +inline +bool +IsExternal(v8::Local str) { +#if NODE_MODULE_VERSION < 42 + return str->IsExternalAscii(); +#else // io.js v1.0.0 + return str->IsExternalOneByte(); +#endif +} + +} // end of namespace NanIntern + static bool _NanGetExternalParts( v8::Handle val , const char** data @@ -1730,23 +1762,13 @@ static bool _NanGetExternalParts( assert(val->IsString()); v8::Local str = NanNew(val.As()); -#if NODE_MODULE_VERSION >= 42 // io.js v1.0.0 - if (str->IsExternalOneByte()) { - const v8::String::ExternalOneByteStringResource* ext; - ext = str->GetExternalOneByteStringResource(); + if (NanIntern::IsExternal(str)) { + const NanExternalOneByteStringResource* ext; + ext = NanIntern::GetExternalResource(str); *data = ext->data(); *len = ext->length(); return true; } -#else - if (str->IsExternalAscii()) { - const v8::String::ExternalAsciiStringResource* ext; - ext = str->GetExternalAsciiStringResource(); - *data = ext->data(); - *len = ext->length(); - return true; - } -#endif if (str->IsExternal()) { const v8::String::ExternalStringResource* ext; diff --git a/nan_implementation_12_inl.h b/nan_implementation_12_inl.h index 7f942fe4..5f0bff05 100644 --- a/nan_implementation_12_inl.h +++ b/nan_implementation_12_inl.h @@ -62,14 +62,26 @@ Factory::New(void * value) { return v8::External::New(v8::Isolate::GetCurrent(), value); } +//=== Function ================================================================= + +Factory::return_t +Factory::New( NanFunctionCallback callback + , v8::Handle data) { + return v8::Function::New( v8::Isolate::GetCurrent() + , callback + , data); +} + //=== Function Template ======================================================== Factory::return_t Factory::New( NanFunctionCallback callback , v8::Handle data , v8::Handle signature) { - return v8::FunctionTemplate::New(v8::Isolate::GetCurrent(), callback, data, - signature); + return v8::FunctionTemplate::New( v8::Isolate::GetCurrent() + , callback + , data + , signature); } //=== Number =================================================================== @@ -120,6 +132,13 @@ Factory::New() { return v8::Object::New(v8::Isolate::GetCurrent()); } +//=== Object Template ========================================================== + +Factory::return_t +Factory::New() { + return v8::ObjectTemplate::New(v8::Isolate::GetCurrent()); +} + //=== RegExp =================================================================== Factory::return_t @@ -191,11 +210,7 @@ Factory::New(v8::String::ExternalStringResource * value) { } Factory::return_t -#if NODE_MODULE_VERSION >= 42 // io.js v1.0.0 -Factory::New(v8::String::ExternalOneByteStringResource * value) { -#else -Factory::New(v8::String::ExternalAsciiStringResource * value) { -#endif +Factory::New(NanExternalOneByteStringResource * value) { return v8::String::NewExternal(v8::Isolate::GetCurrent(), value); } diff --git a/nan_implementation_pre_12_inl.h b/nan_implementation_pre_12_inl.h index a4dc3570..4c4ae116 100644 --- a/nan_implementation_pre_12_inl.h +++ b/nan_implementation_pre_12_inl.h @@ -67,13 +67,29 @@ Factory::New(void * value) { return v8::External::New(value); } +//=== Function ================================================================= + +Factory::return_t +Factory::New( NanFunctionCallback callback + , v8::Handle data) { + return Factory::New( callback + , data + , v8::Handle() + )->GetFunction(); +} + + //=== FunctionTemplate ========================================================= Factory::return_t Factory::New( NanFunctionCallback callback , v8::Handle data , v8::Handle signature) { - return v8::FunctionTemplate::New(callback, data, signature); + // Note(agnat): Emulate length argument here. Unfortunately, I couldn't find + // a way. Have at it though... + return v8::FunctionTemplate::New( callback + , data + , signature); } //=== Number =================================================================== @@ -122,6 +138,13 @@ Factory::New() { return v8::Object::New(); } +//=== Object Template ========================================================== + +Factory::return_t +Factory::New() { + return v8::ObjectTemplate::New(); +} + //=== RegExp =================================================================== Factory::return_t diff --git a/nan_new.h b/nan_new.h index 7b92b7a9..7058d123 100644 --- a/nan_new.h +++ b/nan_new.h @@ -67,6 +67,14 @@ struct Factory : FactoryBase { static inline return_t New(void *value); }; +template <> +struct Factory : FactoryBase { + static inline + return_t + New( NanFunctionCallback callback + , v8::Handle data = v8::Handle()); +}; + template <> struct Factory : FactoryBase { static inline @@ -110,6 +118,11 @@ struct Factory : FactoryBase { static inline return_t New(); }; +template <> +struct Factory : FactoryBase { + static inline return_t New(); +}; + template <> struct Factory : FactoryBase { static inline return_t New( @@ -139,11 +152,7 @@ struct Factory : FactoryBase { static inline return_t New(std::string const& value); static inline return_t New(v8::String::ExternalStringResource * value); -#if NODE_MODULE_VERSION >= 42 // io.js v1.0.0 - static inline return_t New(v8::String::ExternalOneByteStringResource * value); -#else - static inline return_t New(v8::String::ExternalAsciiStringResource * value); -#endif + static inline return_t New(NanExternalOneByteStringResource * value); // TODO(agnat): Deprecate. static inline return_t New(const uint8_t * value, int length = -1); @@ -209,12 +218,26 @@ NanNew(A0 arg0, A1 arg1, A2 arg2, A3 arg3) { return NanIntern::Factory::New(arg0, arg1, arg2, arg3); } +// Note(agnat): When passing overloaded function pointers to template functions +// as generic arguments the compiler needs help in picking the right overload. +// These two functions handle NanNew and NanNew with +// all argument variations. + +// v8::Function and v8::FunctionTemplate with one or two arguments template typename NanIntern::Factory::return_t +NanNew( NanFunctionCallback callback + , v8::Handle data = v8::Handle()) { + return NanIntern::Factory::New(callback, data); +} + +// v8::Function and v8::FunctionTemplate with three arguments +template +typename NanIntern::Factory::return_t NanNew( NanFunctionCallback callback , v8::Handle data = v8::Handle() - , v8::Handle signature = v8::Handle()) { - return NanIntern::Factory::New(callback, data, signature); + , A2 a2 = A2()) { + return NanIntern::Factory::New(callback, data, a2); } // Convenience @@ -284,11 +307,7 @@ NanNew(v8::String::ExternalStringResource * value) { inline NanIntern::Factory::return_t -#if NODE_MODULE_VERSION >= 42 // io.js v1.0.0 -NanNew(v8::String::ExternalOneByteStringResource * value) { -#else -NanNew(v8::String::ExternalAsciiStringResource * value) { -#endif +NanNew(NanExternalOneByteStringResource * value) { return NanNew(value); } diff --git a/test/cpp/nannew.cpp b/test/cpp/nannew.cpp index 4f990e3e..854e6bd5 100644 --- a/test/cpp/nannew.cpp +++ b/test/cpp/nannew.cpp @@ -124,6 +124,18 @@ NAN_METHOD(testExternal) { return_NanUndefined(); } +NAN_METHOD(testFunction) { + NanScope(); + NanTap t(args[0]); + t.plan(2); + + t.ok(_( assertType(NanNew(testFunction)))); + v8::Local data = NanNew("plonk"); + t.ok(_( assertType(NanNew(testFunction, data)))); + + return_NanUndefined(); +} + NAN_METHOD(testFunctionTemplate) { NanScope(); NanTap t(args[0]); @@ -192,6 +204,28 @@ NAN_METHOD(testNumberObject) { return_NanUndefined(); } +NAN_METHOD(testObject) { + NanScope(); + NanTap t(args[0]); + + t.plan(1); + + t.ok(_(assertType( NanNew()))); + + return_NanUndefined(); +} + +NAN_METHOD(testObjectTemplate) { + NanScope(); + NanTap t(args[0]); + + t.plan(1); + + t.ok(_(assertType( NanNew()))); + + return_NanUndefined(); +} + NAN_METHOD(testScript) { NanScope(); NanTap t(args[0]); @@ -355,9 +389,11 @@ NAN_METHOD(testRegression242) { NanScope(); NanTap t(args[0]); - // This line needs to *compile*. Not much to test at runtime. + // These lines must *compile*. Not much to test at runtime. Local ft = NanNew(overloaded); (void)ft; // not unused + Local f = NanNew(overloaded); + (void)f; // not unused t.plan(1); @@ -412,9 +448,12 @@ void Init(Handle exports) { NAN_EXPORT(exports, testBooleanObject); NAN_EXPORT(exports, testDate); NAN_EXPORT(exports, testExternal); + NAN_EXPORT(exports, testFunction); NAN_EXPORT(exports, testFunctionTemplate); NAN_EXPORT(exports, testNumber); NAN_EXPORT(exports, testNumberObject); + NAN_EXPORT(exports, testObject); + NAN_EXPORT(exports, testObjectTemplate); NAN_EXPORT(exports, testScript); NAN_EXPORT(exports, testSignature); NAN_EXPORT(exports, testString); diff --git a/test/js/nannew-test.js b/test/js/nannew-test.js index 34fca26b..2358a9e0 100644 --- a/test/js/nannew-test.js +++ b/test/js/nannew-test.js @@ -45,5 +45,7 @@ test('strings', function (t) { t.equals(bindings.newStringFromChars(), "hello?"); t.equals(bindings.newStringFromCharsWithLength(), "hell"); t.equals(bindings.newStringFromStdString(), "hello!"); + + t.end(); });