From 110a9cd8db515c4d1a9ac5cd8837291da7c6c5ea Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Wed, 3 Jul 2013 04:23:44 +0200 Subject: lib, src: upgrade after v8 api change This is a big commit that touches just about every file in the src/ directory. The V8 API has changed in significant ways. The most important changes are: * Binding functions take a const v8::FunctionCallbackInfo& argument rather than a const v8::Arguments& argument. * Binding functions return void rather than v8::Handle. The return value is returned with the args.GetReturnValue().Set() family of functions. * v8::Persistent no longer derives from v8::Handle and no longer allows you to directly dereference the object that the persistent handle points to. This means that the common pattern of caching oft-used JS values in a persistent handle no longer quite works, you first need to reconstruct a v8::Local from the persistent handle with the Local::New(isolate, persistent) factory method. A handful of (internal) convenience classes and functions have been added to make dealing with the new API a little easier. The most visible one is node::Cached, which wraps a v8::Persistent with some template sugar. It can hold arbitrary types but so far it's exclusively used for v8::Strings (which was by far the most commonly cached handle type.) --- src/node_internals.h | 206 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 197 insertions(+), 9 deletions(-) (limited to 'src/node_internals.h') diff --git a/src/node_internals.h b/src/node_internals.h index 9e5e0bf92d..29c38adb0a 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -22,6 +22,7 @@ #ifndef SRC_NODE_INTERNALS_H_ #define SRC_NODE_INTERNALS_H_ +#include #include #include "v8.h" @@ -32,7 +33,67 @@ namespace node { extern v8::Isolate* node_isolate; // Defined in node.cc at startup. -extern v8::Persistent process; +extern v8::Persistent process_p; + +template +class CachedBase { +public: + CachedBase(); + operator v8::Handle() const; + void operator=(v8::Handle that); // Can only assign once. + bool IsEmpty() const; +private: + CachedBase(const CachedBase&); + void operator=(const CachedBase&); + v8::Persistent handle_; +}; + +template +class Cached : public CachedBase { +public: + operator v8::Handle() const; + void operator=(v8::Handle that); +}; + +template <> +class Cached : public CachedBase { +public: + operator v8::Handle() const; + void operator=(v8::Handle that); +}; + +template +v8::Handle MakeCallback( + const v8::Persistent& recv, + const TypeName method, + int argc, + v8::Handle* argv); + +template +v8::Handle MakeCallback( + const v8::Persistent& recv, + const Cached& method, + int argc, + v8::Handle* argv); + +inline bool HasInstance(v8::Persistent& function_template, + v8::Handle value); + +inline v8::Local NewInstance(v8::Persistent& ctor, + int argc = 0, + v8::Handle* argv = NULL); + +// TODO(bnoordhuis) Move to src/node_buffer.h once it's been established +// that the current approach to dealing with Persistent is working out. +namespace Buffer { + +template +inline char* Data(v8::Persistent& val); + +template +inline size_t Length(v8::Persistent& val); + +} // namespace Buffer #ifdef _WIN32 // emulate snprintf() on windows, _snprintf() doesn't zero-terminate the buffer @@ -87,22 +148,44 @@ inline static int snprintf(char* buf, unsigned int len, const char* fmt, ...) { #define THROW_ERROR(fun) \ do { \ v8::HandleScope scope(node_isolate); \ - return v8::ThrowException(fun(v8::String::New(errmsg))); \ + v8::ThrowException(fun(v8::String::New(errmsg))); \ } \ while (0) -inline static v8::Handle ThrowError(const char* errmsg) { +inline static void ThrowError(const char* errmsg) { THROW_ERROR(v8::Exception::Error); } -inline static v8::Handle ThrowTypeError(const char* errmsg) { +inline static void ThrowTypeError(const char* errmsg) { THROW_ERROR(v8::Exception::TypeError); } -inline static v8::Handle ThrowRangeError(const char* errmsg) { +inline static void ThrowRangeError(const char* errmsg) { THROW_ERROR(v8::Exception::RangeError); } +inline static void ThrowErrnoException(int errorno, + const char* syscall = NULL, + const char* message = NULL, + const char* path = NULL) { + NODE_EXTERN v8::Local ErrnoException(int errorno, + const char* syscall = NULL, + const char* message = NULL, + const char* path = NULL); + v8::ThrowException(ErrnoException(errorno, syscall, message, path)); +} + +inline static void ThrowUVException(int errorno, + const char* syscall = NULL, + const char* message = NULL, + const char* path = NULL) { + NODE_EXTERN v8::Local UVException(int errorno, + const char* syscall = NULL, + const char* message = NULL, + const char* path = NULL); + v8::ThrowException(UVException(errorno, syscall, message, path)); +} + NO_RETURN void FatalError(const char* location, const char* message); #define UNWRAP(type) \ @@ -116,10 +199,6 @@ NO_RETURN void FatalError(const char* location, const char* message); abort(); \ } -v8::Handle FromConstructorTemplate( - v8::Persistent t, - const v8::Arguments& args); - // allow for quick domain check extern bool using_domains; @@ -165,6 +244,115 @@ inline MUST_USE_RESULT bool ParseArrayIndex(v8::Handle arg, return true; } +template +CachedBase::CachedBase() { +} + +template +CachedBase::operator v8::Handle() const { + return v8::Local::New(node_isolate, handle_); +} + +template +void CachedBase::operator=(v8::Handle that) { + assert(handle_.IsEmpty() == true); // Can only assign once. + handle_.Reset(node_isolate, that); +} + +template +bool CachedBase::IsEmpty() const { + return handle_.IsEmpty(); +} + +template +Cached::operator v8::Handle() const { + return CachedBase::operator v8::Handle(); +} + +template +void Cached::operator=(v8::Handle that) { + CachedBase::operator=(that); +} + +inline Cached::operator v8::Handle() const { + return CachedBase::operator v8::Handle(); +} + +inline void Cached::operator=(v8::Handle that) { + CachedBase::operator=(that); +} + +// Forward declarations, see node.h +NODE_EXTERN v8::Handle MakeCallback( + const v8::Handle recv, + const char* method, + int argc, + v8::Handle* argv); +NODE_EXTERN v8::Handle MakeCallback( + const v8::Handle object, + const v8::Handle symbol, + int argc, + v8::Handle* argv); +NODE_EXTERN v8::Handle MakeCallback( + const v8::Handle object, + const v8::Handle callback, + int argc, + v8::Handle* argv); + +template +v8::Handle MakeCallback( + const v8::Persistent& recv, + const TypeName method, + int argc, + v8::Handle* argv) { + v8::Local recv_obj = + v8::Local::New(node_isolate, recv); + return MakeCallback(recv_obj, method, argc, argv); +} + +template +v8::Handle MakeCallback( + const v8::Persistent& recv, + const Cached& method, + int argc, + v8::Handle* argv) { + const v8::Handle handle = method; + return MakeCallback(recv, handle, argc, argv); +} + +inline bool HasInstance(v8::Persistent& function_template, + v8::Handle value) { + v8::Local function_template_handle = + v8::Local::New(node_isolate, function_template); + return function_template_handle->HasInstance(value); +} + +inline v8::Local NewInstance(v8::Persistent& ctor, + int argc, + v8::Handle* argv) { + v8::Local constructor_handle = + v8::Local::New(node_isolate, ctor); + return constructor_handle->NewInstance(argc, argv); +} + +namespace Buffer { + +template +inline char* Data(v8::Persistent& val) { + NODE_EXTERN char* Data(v8::Handle); + NODE_EXTERN char* Data(v8::Handle); + return Data(v8::Local::New(node_isolate, val)); +} + +template +inline size_t Length(v8::Persistent& val) { + NODE_EXTERN size_t Length(v8::Handle); + NODE_EXTERN size_t Length(v8::Handle); + return Length(v8::Local::New(node_isolate, val)); +} + +} // namespace Buffer + } // namespace node #endif // SRC_NODE_INTERNALS_H_ -- cgit v1.2.1