diff options
author | Ben Noordhuis <info@bnoordhuis.nl> | 2013-07-03 04:23:44 +0200 |
---|---|---|
committer | Ben Noordhuis <info@bnoordhuis.nl> | 2013-07-06 17:44:44 +0200 |
commit | 110a9cd8db515c4d1a9ac5cd8837291da7c6c5ea (patch) | |
tree | 71e5a14a98131d89d670f842eb36bfcccab00b7b | |
parent | 9b3de60d3537df657e75887436a5b1df5ed80c2d (diff) | |
download | nodejs-110a9cd8db515c4d1a9ac5cd8837291da7c6c5ea.tar.gz nodejs-110a9cd8db515c4d1a9ac5cd8837291da7c6c5ea.tar.bz2 nodejs-110a9cd8db515c4d1a9ac5cd8837291da7c6c5ea.zip |
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<T>& argument
rather than a const v8::Arguments& argument.
* Binding functions return void rather than v8::Handle<v8::Value>. The
return value is returned with the args.GetReturnValue().Set() family
of functions.
* v8::Persistent<T> no longer derives from v8::Handle<T> 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<T> from the persistent
handle with the Local<T>::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<T>, which wraps a v8::Persistent<T>
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.)
43 files changed, 2241 insertions, 3609 deletions
diff --git a/lib/net.js b/lib/net.js index 726424a15..0d5b556d0 100644 --- a/lib/net.js +++ b/lib/net.js @@ -556,8 +556,7 @@ Socket.prototype._getpeername = function() { } if (!this._peername) { this._peername = this._handle.getpeername(); - // getpeername() returns null on error - if (this._peername === null) { + if (!this._peername) { return {}; } } @@ -581,7 +580,7 @@ Socket.prototype._getsockname = function() { } if (!this._sockname) { this._sockname = this._handle.getsockname(); - if (this._sockname === null) { + if (!this._sockname) { return {}; } } @@ -648,7 +647,7 @@ Socket.prototype._writeGeneric = function(writev, data, encoding, cb) { var writeReq = createWriteReq(this._handle, data, enc); } - if (!writeReq || typeof writeReq !== 'object') + if (!writeReq) return this._destroy(errnoException(process._errno, 'write'), cb); writeReq.oncomplete = afterWrite; @@ -112,7 +112,6 @@ 'src/timer_wrap.cc', 'src/tty_wrap.cc', 'src/process_wrap.cc', - 'src/v8_typed_array.cc', 'src/udp_wrap.cc', # headers to make for a more pleasant IDE experience 'src/handle_wrap.h', @@ -142,7 +141,6 @@ 'src/string_bytes.h', 'src/stream_wrap.h', 'src/tree.h', - 'src/v8_typed_array.h', 'deps/http_parser/http_parser.h', '<(SHARED_INTERMEDIATE_DIR)/node_natives.h', # javascript files to make for an even more pleasant IDE experience diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index 0b12bce4a..14adf5452 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -45,9 +45,9 @@ namespace node { namespace cares_wrap { -using v8::Arguments; using v8::Array; using v8::Function; +using v8::FunctionCallbackInfo; using v8::Handle; using v8::HandleScope; using v8::Integer; @@ -69,7 +69,7 @@ struct ares_task_t { }; -static Persistent<String> oncomplete_sym; +static Cached<String> oncomplete_sym; static ares_channel ares_channel; static uv_timer_t ares_timer; static RB_HEAD(ares_task_list, ares_task_t) ares_tasks; @@ -268,7 +268,8 @@ static void SetAresErrno(int errorno) { HandleScope scope(node_isolate); Local<Value> key = String::NewSymbol("_errno"); Local<Value> value = String::NewSymbol(AresErrnoString(errorno)); - node::process->Set(key, value); + Local<Object> process = Local<Object>::New(node_isolate, process_p); + process->Set(key, value); } @@ -276,26 +277,18 @@ class QueryWrap { public: QueryWrap() { HandleScope scope(node_isolate); - - object_ = Persistent<Object>::New(node_isolate, Object::New()); + persistent().Reset(node_isolate, Object::New()); } virtual ~QueryWrap() { - assert(!object_.IsEmpty()); - - object_->Delete(oncomplete_sym); - - object_.Dispose(node_isolate); - object_.Clear(); - } - - Handle<Object> GetObject() { - return object_; + assert(!persistent().IsEmpty()); + object()->Delete(oncomplete_sym); + persistent().Dispose(); } void SetOnComplete(Handle<Value> oncomplete) { assert(oncomplete->IsFunction()); - object_->Set(oncomplete_sym, oncomplete); + object()->Set(oncomplete_sym, oncomplete); } // Subclasses should implement the appropriate Send method. @@ -309,6 +302,14 @@ class QueryWrap { return 0; } + inline Persistent<Object>& persistent() { + return object_; + } + + inline Local<Object> object() { + return Local<Object>::New(node_isolate, persistent()); + } + protected: void* GetQueryArg() { return static_cast<void*>(this); @@ -343,13 +344,13 @@ class QueryWrap { void CallOnComplete(Local<Value> answer) { HandleScope scope(node_isolate); Local<Value> argv[2] = { Integer::New(0, node_isolate), answer }; - MakeCallback(object_, oncomplete_sym, ARRAY_SIZE(argv), argv); + MakeCallback(object(), oncomplete_sym, ARRAY_SIZE(argv), argv); } void CallOnComplete(Local<Value> answer, Local<Value> family) { HandleScope scope(node_isolate); Local<Value> argv[3] = { Integer::New(0, node_isolate), answer, family }; - MakeCallback(object_, oncomplete_sym, ARRAY_SIZE(argv), argv); + MakeCallback(object(), oncomplete_sym, ARRAY_SIZE(argv), argv); } void ParseError(int status) { @@ -358,7 +359,7 @@ class QueryWrap { HandleScope scope(node_isolate); Local<Value> argv[1] = { Integer::New(-1, node_isolate) }; - MakeCallback(object_, oncomplete_sym, ARRAY_SIZE(argv), argv); + MakeCallback(object(), oncomplete_sym, ARRAY_SIZE(argv), argv); } // Subclasses should implement the appropriate Parse method. @@ -730,7 +731,7 @@ class GetHostByNameWrap: public QueryWrap { template <class Wrap> -static Handle<Value> Query(const Arguments& args) { +static void Query(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); assert(!args.IsConstructCall()); @@ -742,8 +743,8 @@ static Handle<Value> Query(const Arguments& args) { // We must cache the wrap's js object here, because cares might make the // callback from the wrap->Send stack. This will destroy the wrap's internal - // object reference, causing wrap->GetObject() to return undefined. - Local<Object> object = Local<Object>::New(node_isolate, wrap->GetObject()); + // object reference, causing wrap->object() to return an empty handle. + Local<Object> object = wrap->object(); String::Utf8Value name(args[0]); @@ -751,15 +752,14 @@ static Handle<Value> Query(const Arguments& args) { if (r) { SetAresErrno(r); delete wrap; - return scope.Close(v8::Null(node_isolate)); } else { - return scope.Close(object); + args.GetReturnValue().Set(object); } } template <class Wrap> -static Handle<Value> QueryWithFamily(const Arguments& args) { +static void QueryWithFamily(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); assert(!args.IsConstructCall()); @@ -771,8 +771,8 @@ static Handle<Value> QueryWithFamily(const Arguments& args) { // We must cache the wrap's js object here, because cares might make the // callback from the wrap->Send stack. This will destroy the wrap's internal - // object reference, causing wrap->GetObject() to return undefined. - Local<Object> object = Local<Object>::New(node_isolate, wrap->GetObject()); + // object reference, causing wrap->object() to return an empty handle. + Local<Object> object = wrap->object(); String::Utf8Value name(args[0]); int family = args[1]->Int32Value(); @@ -781,9 +781,8 @@ static Handle<Value> QueryWithFamily(const Arguments& args) { if (r) { SetAresErrno(r); delete wrap; - return scope.Close(v8::Null(node_isolate)); } else { - return scope.Close(object); + args.GetReturnValue().Set(object); } } @@ -877,31 +876,29 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) { uv_freeaddrinfo(res); // Make the callback into JavaScript - MakeCallback(req_wrap->object_, oncomplete_sym, ARRAY_SIZE(argv), argv); + MakeCallback(req_wrap->object(), oncomplete_sym, ARRAY_SIZE(argv), argv); delete req_wrap; } -static Handle<Value> IsIP(const Arguments& args) { +static void IsIP(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); String::AsciiValue ip(args[0]); char address_buffer[sizeof(struct in6_addr)]; - if (uv_inet_pton(AF_INET, *ip, &address_buffer).code == UV_OK) { - return scope.Close(v8::Integer::New(4, node_isolate)); - } - - if (uv_inet_pton(AF_INET6, *ip, &address_buffer).code == UV_OK) { - return scope.Close(v8::Integer::New(6, node_isolate)); - } + int rc = 0; + if (uv_inet_pton(AF_INET, *ip, &address_buffer).code == UV_OK) + rc = 4; + else if (uv_inet_pton(AF_INET6, *ip, &address_buffer).code == UV_OK) + rc = 6; - return scope.Close(v8::Integer::New(0, node_isolate)); + args.GetReturnValue().Set(rc); } -static Handle<Value> GetAddrInfo(const Arguments& args) { +static void GetAddrInfo(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); String::Utf8Value hostname(args[0]); @@ -937,14 +934,13 @@ static Handle<Value> GetAddrInfo(const Arguments& args) { if (r) { SetErrno(uv_last_error(uv_default_loop())); delete req_wrap; - return scope.Close(v8::Null(node_isolate)); } else { - return scope.Close(req_wrap->object_); + args.GetReturnValue().Set(req_wrap->persistent()); } } -static Handle<Value> GetServers(const Arguments& args) { +static void GetServers(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Local<Array> server_array = Array::New(); @@ -969,11 +965,11 @@ static Handle<Value> GetServers(const Arguments& args) { ares_free_data(servers); - return scope.Close(server_array); + args.GetReturnValue().Set(server_array); } -static Handle<Value> SetServers(const Arguments& args) { +static void SetServers(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); assert(args[0]->IsArray()); @@ -984,7 +980,7 @@ static Handle<Value> SetServers(const Arguments& args) { if (len == 0) { int rv = ares_set_servers(ares_channel, NULL); - return scope.Close(Integer::New(rv)); + return args.GetReturnValue().Set(rv); } ares_addr_node* servers = new ares_addr_node[len]; @@ -1039,16 +1035,14 @@ static Handle<Value> SetServers(const Arguments& args) { delete[] servers; - return scope.Close(Integer::New(r)); + args.GetReturnValue().Set(r); } -static Handle<Value> StrError(const Arguments& args) { - HandleScope scope; - - int r = args[0]->Int32Value(); - - return scope.Close(String::New(ares_strerror(r))); +static void StrError(const FunctionCallbackInfo<Value>& args) { + HandleScope scope(node_isolate); + const char* errmsg = ares_strerror(args[0]->Int32Value()); + args.GetReturnValue().Set(String::New(errmsg)); } @@ -1100,7 +1094,7 @@ static void Initialize(Handle<Object> target) { target->Set(String::NewSymbol("AF_UNSPEC"), Integer::New(AF_UNSPEC, node_isolate)); - oncomplete_sym = NODE_PSYMBOL("oncomplete"); + oncomplete_sym = String::New("oncomplete"); } diff --git a/src/fs_event_wrap.cc b/src/fs_event_wrap.cc index f767db037..bcac8dbab 100644 --- a/src/fs_event_wrap.cc +++ b/src/fs_event_wrap.cc @@ -24,20 +24,28 @@ #include <stdlib.h> -using namespace v8; - namespace node { -static Persistent<String> change_sym; -static Persistent<String> onchange_sym; -static Persistent<String> rename_sym; +using v8::FunctionCallbackInfo; +using v8::FunctionTemplate; +using v8::Handle; +using v8::HandleScope; +using v8::Integer; +using v8::Local; +using v8::Object; +using v8::String; +using v8::Value; + +static Cached<String> change_sym; +static Cached<String> onchange_sym; +static Cached<String> rename_sym; class FSEventWrap: public HandleWrap { public: static void Initialize(Handle<Object> target); - static Handle<Value> New(const Arguments& args); - static Handle<Value> Start(const Arguments& args); - static Handle<Value> Close(const Arguments& args); + static void New(const FunctionCallbackInfo<Value>& args); + static void Start(const FunctionCallbackInfo<Value>& args); + static void Close(const FunctionCallbackInfo<Value>& args); private: FSEventWrap(Handle<Object> object); @@ -74,33 +82,28 @@ void FSEventWrap::Initialize(Handle<Object> target) { NODE_SET_PROTOTYPE_METHOD(t, "start", Start); NODE_SET_PROTOTYPE_METHOD(t, "close", Close); - target->Set(String::NewSymbol("FSEvent"), - Persistent<FunctionTemplate>::New(node_isolate, - t)->GetFunction()); + target->Set(String::New("FSEvent"), t->GetFunction()); - change_sym = NODE_PSYMBOL("change"); - onchange_sym = NODE_PSYMBOL("onchange"); - rename_sym = NODE_PSYMBOL("rename"); + change_sym = String::New("change"); + onchange_sym = String::New("onchange"); + rename_sym = String::New("rename"); } -Handle<Value> FSEventWrap::New(const Arguments& args) { +void FSEventWrap::New(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); - assert(args.IsConstructCall()); new FSEventWrap(args.This()); - - return scope.Close(args.This()); } -Handle<Value> FSEventWrap::Start(const Arguments& args) { +void FSEventWrap::Start(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(FSEventWrap) if (args.Length() < 1 || !args[0]->IsString()) { - return ThrowException(Exception::TypeError(String::New("Bad arguments"))); + return ThrowTypeError("Bad arguments"); } String::Utf8Value path(args[0]); @@ -116,7 +119,7 @@ Handle<Value> FSEventWrap::Start(const Arguments& args) { SetErrno(uv_last_error(uv_default_loop())); } - return scope.Close(Integer::New(r, node_isolate)); + args.GetReturnValue().Set(r); } @@ -127,7 +130,7 @@ void FSEventWrap::OnEvent(uv_fs_event_t* handle, const char* filename, FSEventWrap* wrap = static_cast<FSEventWrap*>(handle->data); - assert(wrap->object_.IsEmpty() == false); + assert(wrap->persistent().IsEmpty() == false); // We're in a bind here. libuv can set both UV_RENAME and UV_CHANGE but // the Node API only lets us pass a single event to JS land. @@ -158,14 +161,18 @@ void FSEventWrap::OnEvent(uv_fs_event_t* handle, const char* filename, Handle<Value> argv[3] = { Integer::New(status, node_isolate), eventStr, - filename ? String::New(filename) : v8::Null(node_isolate) + Null(node_isolate) }; - MakeCallback(wrap->object_, onchange_sym, ARRAY_SIZE(argv), argv); + if (filename != NULL) { + argv[2] = String::New(filename); + } + + MakeCallback(wrap->object(), onchange_sym, ARRAY_SIZE(argv), argv); } -Handle<Value> FSEventWrap::Close(const Arguments& args) { +void FSEventWrap::Close(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); // Unwrap manually here. The UNWRAP() macro asserts that wrap != NULL. @@ -176,12 +183,10 @@ Handle<Value> FSEventWrap::Close(const Arguments& args) { void* ptr = args.This()->GetAlignedPointerFromInternalField(0); FSEventWrap* wrap = static_cast<FSEventWrap*>(ptr); - if (wrap == NULL || wrap->initialized_ == false) { - return Undefined(node_isolate); - } + if (wrap == NULL || wrap->initialized_ == false) return; wrap->initialized_ = false; - return HandleWrap::Close(args); + HandleWrap::Close(args); } diff --git a/src/handle_wrap.cc b/src/handle_wrap.cc index cf3768ace..6860231ca 100644 --- a/src/handle_wrap.cc +++ b/src/handle_wrap.cc @@ -25,20 +25,17 @@ namespace node { -using v8::Arguments; -using v8::Function; +using v8::FunctionCallbackInfo; using v8::Handle; using v8::HandleScope; +using v8::Local; using v8::Object; -using v8::Persistent; using v8::String; -using v8::Undefined; using v8::Value; - // defined in node.cc extern QUEUE handle_wrap_queue; -static Persistent<String> close_sym; +static Cached<String> close_sym; void HandleWrap::Initialize(Handle<Object> target) { @@ -46,7 +43,7 @@ void HandleWrap::Initialize(Handle<Object> target) { } -Handle<Value> HandleWrap::Ref(const Arguments& args) { +void HandleWrap::Ref(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP_NO_ABORT(HandleWrap) @@ -55,12 +52,10 @@ Handle<Value> HandleWrap::Ref(const Arguments& args) { uv_ref(wrap->handle__); wrap->flags_ &= ~kUnref; } - - return v8::Undefined(node_isolate); } -Handle<Value> HandleWrap::Unref(const Arguments& args) { +void HandleWrap::Unref(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP_NO_ABORT(HandleWrap) @@ -69,33 +64,27 @@ Handle<Value> HandleWrap::Unref(const Arguments& args) { uv_unref(wrap->handle__); wrap->flags_ |= kUnref; } - - return v8::Undefined(node_isolate); } -Handle<Value> HandleWrap::Close(const Arguments& args) { +void HandleWrap::Close(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); HandleWrap *wrap = static_cast<HandleWrap*>( args.This()->GetAlignedPointerFromInternalField(0)); // guard against uninitialized handle or double close - if (wrap == NULL || wrap->handle__ == NULL) { - return Undefined(node_isolate); - } + if (wrap == NULL || wrap->handle__ == NULL) return; - assert(!wrap->object_.IsEmpty()); + assert(!wrap->persistent().IsEmpty()); uv_close(wrap->handle__, OnClose); wrap->handle__ = NULL; if (args[0]->IsFunction()) { - if (close_sym.IsEmpty() == true) close_sym = NODE_PSYMBOL("close"); - wrap->object_->Set(close_sym, args[0]); + if (close_sym.IsEmpty() == true) close_sym = String::New("close"); + wrap->object()->Set(close_sym, args[0]); wrap->flags_ |= kCloseCallback; } - - return Undefined(node_isolate); } @@ -105,16 +94,16 @@ HandleWrap::HandleWrap(Handle<Object> object, uv_handle_t* h) { handle__->data = this; HandleScope scope(node_isolate); - assert(object_.IsEmpty()); + assert(persistent().IsEmpty()); assert(object->InternalFieldCount() > 0); - object_ = v8::Persistent<v8::Object>::New(node_isolate, object); - object_->SetAlignedPointerInInternalField(0, this); + persistent().Reset(node_isolate, object); + object->SetAlignedPointerInInternalField(0, this); QUEUE_INSERT_TAIL(&handle_wrap_queue, &handle_wrap_queue_); } HandleWrap::~HandleWrap() { - assert(object_.IsEmpty()); + assert(persistent().IsEmpty()); QUEUE_REMOVE(&handle_wrap_queue_); } @@ -123,20 +112,21 @@ void HandleWrap::OnClose(uv_handle_t* handle) { HandleWrap* wrap = static_cast<HandleWrap*>(handle->data); // The wrap object should still be there. - assert(wrap->object_.IsEmpty() == false); + assert(wrap->persistent().IsEmpty() == false); // But the handle pointer should be gone. assert(wrap->handle__ == NULL); + HandleScope scope(node_isolate); + Local<Object> object = wrap->object(); + if (wrap->flags_ & kCloseCallback) { assert(close_sym.IsEmpty() == false); - MakeCallback(wrap->object_, close_sym, 0, NULL); + MakeCallback(object, close_sym, 0, NULL); } - wrap->object_->SetAlignedPointerInInternalField(0, NULL); - wrap->object_.Dispose(node_isolate); - wrap->object_.Clear(); - + object->SetAlignedPointerInInternalField(0, NULL); + wrap->persistent().Dispose(); delete wrap; } diff --git a/src/handle_wrap.h b/src/handle_wrap.h index 3a42148a6..d8194b97b 100644 --- a/src/handle_wrap.h +++ b/src/handle_wrap.h @@ -53,31 +53,38 @@ namespace node { args.This()->GetAlignedPointerFromInternalField(0)); class HandleWrap { - public: - static void Initialize(v8::Handle<v8::Object> target); - static v8::Handle<v8::Value> Close(const v8::Arguments& args); - static v8::Handle<v8::Value> Ref(const v8::Arguments& args); - static v8::Handle<v8::Value> Unref(const v8::Arguments& args); - - inline uv_handle_t* GetHandle() { return handle__; }; - - protected: - HandleWrap(v8::Handle<v8::Object> object, uv_handle_t* handle); - virtual ~HandleWrap(); - - v8::Persistent<v8::Object> object_; - - private: - friend v8::Handle<v8::Value> GetActiveHandles(const v8::Arguments&); - static void OnClose(uv_handle_t* handle); - QUEUE handle_wrap_queue_; - // Using double underscore due to handle_ member in tcp_wrap. Probably - // tcp_wrap should rename it's member to 'handle'. - uv_handle_t* handle__; - unsigned int flags_; - - static const unsigned int kUnref = 1; - static const unsigned int kCloseCallback = 2; +public: + static void Initialize(v8::Handle<v8::Object> target); + static void Close(const v8::FunctionCallbackInfo<v8::Value>& args); + static void Ref(const v8::FunctionCallbackInfo<v8::Value>& args); + static void Unref(const v8::FunctionCallbackInfo<v8::Value>& args); + + inline uv_handle_t* GetHandle() { return handle__; }; + +protected: + HandleWrap(v8::Handle<v8::Object> object, uv_handle_t* handle); + virtual ~HandleWrap(); + + inline v8::Local<v8::Object> object() { + return v8::Local<v8::Object>::New(node_isolate, persistent()); + } + + inline v8::Persistent<v8::Object>& persistent() { + return object_; + } + +private: + friend void GetActiveHandles(const v8::FunctionCallbackInfo<v8::Value>&); + static void OnClose(uv_handle_t* handle); + v8::Persistent<v8::Object> object_; + QUEUE handle_wrap_queue_; + // Using double underscore due to handle_ member in tcp_wrap. Probably + // tcp_wrap should rename it's member to 'handle'. + uv_handle_t* handle__; + unsigned int flags_; + + static const unsigned int kUnref = 1; + static const unsigned int kCloseCallback = 2; }; diff --git a/src/node.cc b/src/node.cc index a9c11e0bd..82be2f9b2 100644 --- a/src/node.cc +++ b/src/node.cc @@ -80,9 +80,6 @@ typedef int mode_t; #include "node_provider.h" #endif #include "node_script.h" -#include "v8_typed_array.h" - -using namespace v8; # ifdef __APPLE__ # include <crt_externs.h> @@ -93,41 +90,68 @@ extern char **environ; namespace node { +using v8::Array; +using v8::Boolean; +using v8::Context; +using v8::Exception; +using v8::Function; +using v8::FunctionCallbackInfo; +using v8::FunctionTemplate; +using v8::HandleScope; +using v8::HeapStatistics; +using v8::Integer; +using v8::Isolate; +using v8::Locker; +using v8::Message; +using v8::Number; +using v8::Object; +using v8::ObjectTemplate; +using v8::Persistent; +using v8::PropertyCallbackInfo; +using v8::ResourceConstraints; +using v8::SetResourceConstraints; +using v8::ThrowException; +using v8::TryCatch; +using v8::Uint32; +using v8::V8; +using v8::Value; +using v8::kExternalUnsignedIntArray; + QUEUE handle_wrap_queue = { &handle_wrap_queue, &handle_wrap_queue }; QUEUE req_wrap_queue = { &req_wrap_queue, &req_wrap_queue }; // declared in req_wrap.h -Persistent<String> process_symbol; -Persistent<String> domain_symbol; +Cached<String> process_symbol; +Cached<String> domain_symbol; // declared in node_internals.h -Persistent<Object> process; +Persistent<Object> process_p; -static Persistent<Function> process_tickFromSpinner; static Persistent<Function> process_tickCallback; +static Persistent<Object> binding_cache; +static Persistent<Array> module_load_list; -static Persistent<String> exports_symbol; +static Cached<String> exports_symbol; -static Persistent<String> errno_symbol; -static Persistent<String> syscall_symbol; -static Persistent<String> errpath_symbol; -static Persistent<String> code_symbol; +static Cached<String> errno_symbol; +static Cached<String> syscall_symbol; +static Cached<String> errpath_symbol; +static Cached<String> code_symbol; -static Persistent<String> rss_symbol; -static Persistent<String> heap_total_symbol; -static Persistent<String> heap_used_symbol; +static Cached<String> rss_symbol; +static Cached<String> heap_total_symbol; +static Cached<String> heap_used_symbol; -static Persistent<String> fatal_exception_symbol; +static Cached<String> fatal_exception_symbol; -static Persistent<String> enter_symbol; -static Persistent<String> exit_symbol; -static Persistent<String> disposed_symbol; +static Cached<String> enter_symbol; +static Cached<String> exit_symbol; +static Cached<String> disposed_symbol; // Essential for node_wrap.h Persistent<FunctionTemplate> pipeConstructorTmpl; -Persistent<FunctionTemplate> ttyConstructorTmpl; Persistent<FunctionTemplate> tcpConstructorTmpl; -Persistent<FunctionTemplate> udpConstructorTmpl; +Persistent<FunctionTemplate> ttyConstructorTmpl; static bool print_eval = false; static bool force_repl = false; @@ -149,7 +173,7 @@ static uv_idle_t tick_spinner; static uv_check_t check_immediate_watcher; static uv_idle_t idle_immediate_dummy; static bool need_immediate_cb; -static Persistent<String> immediate_callback_sym; +static Cached<String> immediate_callback_sym; // for quick ref to tickCallback values static struct { @@ -187,10 +211,10 @@ static void CheckImmediate(uv_check_t* handle, int status) { HandleScope scope(node_isolate); if (immediate_callback_sym.IsEmpty()) { - immediate_callback_sym = NODE_PSYMBOL("_immediateCallback"); + immediate_callback_sym = String::New("_immediateCallback"); } - MakeCallback(process, immediate_callback_sym, 0, NULL); + MakeCallback(process_p, immediate_callback_sym, 0, NULL); } @@ -695,10 +719,10 @@ Local<Value> ErrnoException(int errorno, Local<String> cons2 = String::Concat(cons1, message); if (syscall_symbol.IsEmpty()) { - syscall_symbol = NODE_PSYMBOL("syscall"); - errno_symbol = NODE_PSYMBOL("errno"); - errpath_symbol = NODE_PSYMBOL("path"); - code_symbol = NODE_PSYMBOL("code"); + syscall_symbol = String::New("syscall"); + errno_symbol = String::New("errno"); + errpath_symbol = String::New("path"); + code_symbol = String::New("code"); } if (path) { @@ -742,10 +766,10 @@ Local<Value> UVException(int errorno, const char *msg, const char *path) { if (syscall_symbol.IsEmpty()) { - syscall_symbol = NODE_PSYMBOL("syscall"); - errno_symbol = NODE_PSYMBOL("errno"); - errpath_symbol = NODE_PSYMBOL("path"); - code_symbol = NODE_PSYMBOL("code"); + syscall_symbol = String::New("syscall"); + errno_symbol = String::New("errno"); + errpath_symbol = String::New("path"); + code_symbol = String::New("code"); } if (!msg || !msg[0]) @@ -828,10 +852,10 @@ Local<Value> WinapiErrnoException(int errorno, Local<String> message = String::NewSymbol(msg); if (syscall_symbol.IsEmpty()) { - syscall_symbol = NODE_PSYMBOL("syscall"); - errno_symbol = NODE_PSYMBOL("errno"); - errpath_symbol = NODE_PSYMBOL("path"); - code_symbol = NODE_PSYMBOL("code"); + syscall_symbol = String::New("syscall"); + errno_symbol = String::New("errno"); + errpath_symbol = String::New("path"); + code_symbol = String::New("code"); } if (path) { @@ -853,22 +877,11 @@ Local<Value> WinapiErrnoException(int errorno, #endif -Handle<Value> FromConstructorTemplate(Persistent<FunctionTemplate> t, - const Arguments& args) { - HandleScope scope(node_isolate); - Local<Value> argv[32]; - unsigned argc = args.Length(); - if (argc > ARRAY_SIZE(argv)) argc = ARRAY_SIZE(argv); - for (unsigned i = 0; i < argc; ++i) argv[i] = args[i]; - return scope.Close(t->GetFunction()->NewInstance(argc, argv)); -} - - -Handle<Value> SetupDomainUse(const Arguments& args) { +void SetupDomainUse(const FunctionCallbackInfo<Value>& args) { + if (using_domains) return; HandleScope scope(node_isolate); - if (using_domains) - return Undefined(node_isolate); using_domains = true; + Local<Object> process = Local<Object>::New(node_isolate, process_p); Local<Value> tdc_v = process->Get(String::New("_tickDomainCallback")); Local<Value> ndt_v = process->Get(String::New("_nextDomainTick")); if (!tdc_v->IsFunction()) { @@ -883,9 +896,7 @@ Handle<Value> SetupDomainUse(const Arguments& args) { Local<Function> ndt = ndt_v.As<Function>(); process->Set(String::New("_tickCallback"), tdc); process->Set(String::New("nextTick"), ndt); - process_tickCallback.Dispose(node_isolate); // May be set by MakeCallback(). - process_tickCallback = Persistent<Function>::New(node_isolate, tdc); - return Undefined(node_isolate); + process_tickCallback.Reset(node_isolate, tdc); } @@ -898,9 +909,9 @@ MakeDomainCallback(const Handle<Object> object, // lazy load domain specific symbols if (enter_symbol.IsEmpty()) { - enter_symbol = NODE_PSYMBOL("enter"); - exit_symbol = NODE_PSYMBOL("exit"); - disposed_symbol = NODE_PSYMBOL("_disposed"); + enter_symbol = String::New("enter"); + exit_symbol = String::New("exit"); + disposed_symbol = String::New("_disposed"); } Local<Value> domain_v = object->Get(domain_symbol); @@ -950,7 +961,9 @@ MakeDomainCallback(const Handle<Object> object, } // process nextTicks after call - process_tickCallback->Call(process, 0, NULL); + Local<Object> process = Local<Object>::New(node_isolate, process_p); + Local<Function> fn = Local<Function>::New(node_isolate, process_tickCallback); + fn->Call(process, 0, NULL); if (try_catch.HasCaught()) { return Undefined(node_isolate); @@ -966,6 +979,7 @@ MakeCallback(const Handle<Object> object, int argc, Handle<Value> argv[]) { // TODO Hook for long stack traces to be made here. + Local<Object> process = Local<Object>::New(node_isolate, process_p); // lazy load no domain next tick callbacks if (process_tickCallback.IsEmpty()) { @@ -974,8 +988,7 @@ MakeCallback(const Handle<Object> object, fprintf(stderr, "process._tickCallback assigned to non-function\n"); abort(); } - Local<Function> cb = cb_v.As<Function>(); - process_tickCallback = Persistent<Function>::New(node_isolate, cb); + process_tickCallback.Reset(node_isolate, cb_v.As<Function>()); } TryCatch try_catch; @@ -993,7 +1006,8 @@ MakeCallback(const Handle<Object> object, } // process nextTicks after call - process_tickCallback->Call(process, 0, NULL); + Local<Function> fn = Local<Function>::New(node_isolate, process_tickCallback); + fn->Call(process, 0, NULL); if (try_catch.HasCaught()) { return Undefined(node_isolate); @@ -1034,10 +1048,11 @@ MakeCallback(const Handle<Object> object, void SetErrno(uv_err_t err) { HandleScope scope(node_isolate); + Local<Object> process = Local<Object>::New(node_isolate, process_p); - static Persistent<String> errno_symbol; + static Cached<String> errno_symbol; if (errno_symbol.IsEmpty()) { - errno_symbol = NODE_PSYMBOL("_errno"); + errno_symbol = String::New("_errno"); } if (err.code == UV_UNKNOWN) { @@ -1253,7 +1268,7 @@ Local<Value> ExecuteString(Handle<String> source, Handle<Value> filename) { } -static Handle<Value> GetActiveRequests(const Arguments& args) { +static void GetActiveRequests(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Local<Array> ary = Array::New(); @@ -1262,17 +1277,17 @@ static Handle<Value> GetActiveRequests(const Arguments& args) { QUEUE_FOREACH(q, &req_wrap_queue) { ReqWrap<uv_req_t>* w = container_of(q, ReqWrap<uv_req_t>, req_wrap_queue_); - if (w->object_.IsEmpty()) continue; - ary->Set(i++, w->object_); + if (w->persistent().IsEmpty()) continue; + ary->Set(i++, w->object()); } - return scope.Close(ary); + args.GetReturnValue().Set(ary); } // Non-static, friend of HandleWrap. Could have been a HandleWrap method but // implemented here for consistency with GetActiveRequests(). -Handle<Value> GetActiveHandles(const Arguments& args) { +void GetActiveHandles(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Local<Array> ary = Array::New(); @@ -1283,27 +1298,27 @@ Handle<Value> GetActiveHandles(const Arguments& args) { QUEUE_FOREACH(q, &handle_wrap_queue) { HandleWrap* w = container_of(q, HandleWrap, handle_wrap_queue_); - if (w->object_.IsEmpty() || (w->flags_ & HandleWrap::kUnref)) continue; - Local<Value> obj = w->object_->Get(owner_sym); - if (obj->IsUndefined()) obj = *w->object_; - ary->Set(i++, obj); + if (w->persistent().IsEmpty() || (w->flags_ & HandleWrap::kUnref)) continue; + Local<Object> object = w->object(); + Local<Value> owner = object->Get(owner_sym); + if (owner->IsUndefined()) owner = object; + ary->Set(i++, owner); } - return scope.Close(ary); + args.GetReturnValue().Set(ary); } -static Handle<Value> Abort(const Arguments& args) { +static void Abort(const FunctionCallbackInfo<Value>& args) { abort(); - return Undefined(node_isolate); } -static Handle<Value> Chdir(const Arguments& args) { +static void Chdir(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); if (args.Length() != 1 || !args[0]->IsString()) { - return ThrowException(Exception::Error(String::New("Bad argument."))); + return ThrowError("Bad argument."); // FIXME(bnoordhuis) ThrowTypeError? } String::Utf8Value path(args[0]); @@ -1311,14 +1326,12 @@ static Handle<Value> Chdir(const Arguments& args) { uv_err_t r = uv_chdir(*path); if (r.code != UV_OK) { - return ThrowException(UVException(r.code, "uv_chdir")); + return ThrowUVException(r.code, "uv_chdir"); } - - return Undefined(node_isolate); } -static Handle<Value> Cwd(const Arguments& args) { +static void Cwd(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); #ifdef _WIN32 /* MAX_PATH is in characters, not bytes. Make sure we have enough headroom. */ @@ -1329,27 +1342,26 @@ static Handle<Value> Cwd(const Arguments& args) { uv_err_t r = uv_cwd(buf, ARRAY_SIZE(buf) - 1); if (r.code != UV_OK) { - return ThrowException(UVException(r.code, "uv_cwd")); + return ThrowUVException(r.code, "uv_cwd"); } buf[ARRAY_SIZE(buf) - 1] = '\0'; Local<String> cwd = String::New(buf); - return scope.Close(cwd); + args.GetReturnValue().Set(cwd); } -static Handle<Value> Umask(const Arguments& args) { +static void Umask(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); - unsigned int old; + uint32_t old; if (args.Length() < 1 || args[0]->IsUndefined()) { old = umask(0); - umask((mode_t)old); + umask(static_cast<mode_t>(old)); } else if(!args[0]->IsInt32() && !args[0]->IsString()) { - return ThrowException(Exception::TypeError( - String::New("argument must be an integer or octal string."))); + return ThrowTypeError("argument must be an integer or octal string."); } else { int oct; @@ -1363,8 +1375,7 @@ static Handle<Value> Umask(const Arguments& args) { for (int i = 0; i < str.length(); i++) { char c = (*str)[i]; if (c > '7' || c < '0') { - return ThrowException(Exception::TypeError( - String::New("invalid octal string"))); + return ThrowTypeError("invalid octal string"); } oct *= 8; oct += c - '0'; @@ -1373,7 +1384,7 @@ static Handle<Value> Umask(const Arguments& args) { old = umask(static_cast<mode_t>(oct)); } - return scope.Close(Uint32::New(old, node_isolate)); + args.GetReturnValue().Set(old); } @@ -1479,21 +1490,17 @@ static gid_t gid_by_name(Handle<Value> value) { } -static Handle<Value> GetUid(const Arguments& args) { - HandleScope scope(node_isolate); - int uid = getuid(); - return scope.Close(Integer::New(uid, node_isolate)); +static void GetUid(const FunctionCallbackInfo<Value>& args) { + args.GetReturnValue().Set(getuid()); } -static Handle<Value> GetGid(const Arguments& args) { - HandleScope scope(node_isolate); - int gid = getgid(); - return scope.Close(Integer::New(gid, node_isolate)); +static void GetGid(const FunctionCallbackInfo<Value>& args) { + args.GetReturnValue().Set(getgid()); } -static Handle<Value> SetGid(const Arguments& args) { +static void SetGid(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); if (!args[0]->IsUint32() && !args[0]->IsString()) { @@ -1507,14 +1514,12 @@ static Handle<Value> SetGid(const Arguments& args) { } if (setgid(gid)) { - return ThrowException(ErrnoException(errno, "setgid")); + return ThrowErrnoException(errno, "setgid"); } - - return Undefined(node_isolate); } -static Handle<Value> SetUid(const Arguments& args) { +static void SetUid(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); if (!args[0]->IsUint32() && !args[0]->IsString()) { @@ -1528,20 +1533,18 @@ static Handle<Value> SetUid(const Arguments& args) { } if (setuid(uid)) { - return ThrowException(ErrnoException(errno, "setuid")); + return ThrowErrnoException(errno, "setuid"); } - - return Undefined(node_isolate); } -static Handle<Value> GetGroups(const Arguments& args) { +static void GetGroups(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); int ngroups = getgroups(0, NULL); if (ngroups == -1) { - return ThrowException(ErrnoException(errno, "getgroups")); + return ThrowErrnoException(errno, "getgroups"); } gid_t* groups = new gid_t[ngroups]; @@ -1550,7 +1553,7 @@ static Handle<Value> GetGroups(const Arguments& args) { if (ngroups == -1) { delete[] groups; - return ThrowException(ErrnoException(errno, "getgroups")); + return ThrowErrnoException(errno, "getgroups"); } Local<Array> groups_list = Array::New(ngroups); @@ -1568,11 +1571,11 @@ static Handle<Value> GetGroups(const Arguments& args) { groups_list->Set(ngroups, Integer::New(egid, node_isolate)); } - return scope.Close(groups_list); + args.GetReturnValue().Set(groups_list); } -static Handle<Value> SetGroups(const Arguments& args) { +static void SetGroups(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); if (!args[0]->IsArray()) { @@ -1598,14 +1601,12 @@ static Handle<Value> SetGroups(const Arguments& args) { delete[] groups; if (rc == -1) { - return ThrowException(ErrnoException(errno, "setgroups")); + return ThrowErrnoException(errno, "setgroups"); } - - return Undefined(node_isolate); } -static Handle<Value> InitGroups(const Arguments& args) { +static void InitGroups(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); if (!args[0]->IsUint32() && !args[0]->IsString()) { @@ -1647,37 +1648,28 @@ static Handle<Value> InitGroups(const Arguments& args) { } if (rc) { - return ThrowException(ErrnoException(errno, "initgroups")); + return ThrowErrnoException(errno, "initgroups"); } - - return Undefined(node_isolate); } #endif // __POSIX__ && !defined(__ANDROID__) -v8::Handle<v8::Value> Exit(const v8::Arguments& args) { +void Exit(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); exit(args[0]->IntegerValue()); - return Undefined(node_isolate); } -static Handle<Value> Uptime(const Arguments& args) { +static void Uptime(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); double uptime; - - uv_err_t err = uv_uptime(&uptime); - - if (err.code != UV_OK) { - return Undefined(node_isolate); - } - - return scope.Close(Number::New(uptime - prog_start_time)); + if (uv_uptime(&uptime).code != UV_OK) return; + args.GetReturnValue().Set(uptime - prog_start_time); } -v8::Handle<v8::Value> MemoryUsage(const v8::Arguments& args) { +void MemoryUsage(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); size_t rss; @@ -1685,15 +1677,15 @@ v8::Handle<v8::Value> MemoryUsage(const v8::Arguments& args) { uv_err_t err = uv_resident_set_memory(&rss); if (err.code != UV_OK) { - return ThrowException(UVException(err.code, "uv_resident_set_memory")); + return ThrowUVException(err.code, "uv_resident_set_memory"); } Local<Object> info = Object::New(); if (rss_symbol.IsEmpty()) { - rss_symbol = NODE_PSYMBOL("rss"); - heap_total_symbol = NODE_PSYMBOL("heapTotal"); - heap_used_symbol = NODE_PSYMBOL("heapUsed"); + rss_symbol = String::New("rss"); + heap_total_symbol = String::New("heapTotal"); + heap_used_symbol = String::New("heapUsed"); } info->Set(rss_symbol, Number::New(rss)); @@ -1708,15 +1700,15 @@ v8::Handle<v8::Value> MemoryUsage(const v8::Arguments& args) { Integer::NewFromUnsigned(v8_heap_stats.used_heap_size(), node_isolate)); - return scope.Close(info); + args.GetReturnValue().Set(info); } -Handle<Value> Kill(const Arguments& args) { +void Kill(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); if (args.Length() != 2) { - return ThrowException(Exception::Error(String::New("Bad argument."))); + return ThrowError("Bad argument."); } int pid = args[0]->IntegerValue(); @@ -1725,10 +1717,8 @@ Handle<Value> Kill(const Arguments& args) { if (err.code != UV_OK) { SetErrno(err); - return scope.Close(Integer::New(-1, node_isolate)); + args.GetReturnValue().Set(-1); } - - return Undefined(node_isolate); } // used in Hrtime() below @@ -1739,7 +1729,7 @@ Handle<Value> Kill(const Arguments& args) { // so this function instead returns an Array with 2 entries representing seconds // and nanoseconds, to avoid any integer overflow possibility. // Pass in an Array from a previous hrtime() call to instead get a time diff. -Handle<Value> Hrtime(const v8::Arguments& args) { +void Hrtime(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); uint64_t t = uv_hrtime(); @@ -1747,9 +1737,7 @@ Handle<Value> Hrtime(const v8::Arguments& args) { if (args.Length() > 0) { // return a time diff tuple if (!args[0]->IsArray()) { - Local<Value> exception = Exception::TypeError( - String::New("process.hrtime() only accepts an Array tuple.")); - return ThrowException(exception); + return ThrowTypeError("process.hrtime() only accepts an Array tuple."); } Local<Array> inArray = Local<Array>::Cast(args[0]); uint64_t seconds = inArray->Get(0)->Uint32Value(); @@ -1760,8 +1748,7 @@ Handle<Value> Hrtime(const v8::Arguments& args) { Local<Array> tuple = Array::New(2); tuple->Set(0, Integer::NewFromUnsigned(t / NANOS_PER_SEC, node_isolate)); tuple->Set(1, Integer::NewFromUnsigned(t % NANOS_PER_SEC, node_isolate)); - - return scope.Close(tuple); + args.GetReturnValue().Set(tuple); } @@ -1769,23 +1756,21 @@ typedef void (UV_DYNAMIC* extInit)(Handle<Object> exports); // DLOpen is process.dlopen(module, filename). // Used to load 'module.node' dynamically shared objects. -Handle<Value> DLOpen(const v8::Arguments& args) { +void DLOpen(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); char symbol[1024], *base, *pos; uv_lib_t lib; int r; if (args.Length() < 2) { - Local<Value> exception = Exception::Error( - String::New("process.dlopen takes exactly 2 arguments.")); - return ThrowException(exception); + return ThrowError("process.dlopen takes exactly 2 arguments."); } Local<Object> module = args[0]->ToObject(); // Cast String::Utf8Value filename(args[1]); // Cast if (exports_symbol.IsEmpty()) { - exports_symbol = NODE_PSYMBOL("exports"); + exports_symbol = String::New("exports"); } Local<Object> exports = module->Get(exports_symbol)->ToObject(); @@ -1795,7 +1780,8 @@ Handle<Value> DLOpen(const v8::Arguments& args) { // Windows needs to add the filename into the error message errmsg = String::Concat(errmsg, args[1]->ToString()); #endif - return ThrowException(Exception::Error(errmsg)); + ThrowException(Exception::Error(errmsg)); + return; } String::Utf8Value path(args[1]); @@ -1826,9 +1812,7 @@ Handle<Value> DLOpen(const v8::Arguments& args) { /* Add the `_module` suffix to the extension name. */ r = snprintf(symbol, sizeof symbol, "%s_module", base); if (r <= 0 || static_cast<size_t>(r) >= sizeof symbol) { - Local<Value> exception = - Exception::Error(String::New("Out of memory.")); - return ThrowException(exception); + return ThrowError("Out of memory."); } /* Replace dashes with underscores. When loading foo-bar.node, @@ -1859,7 +1843,6 @@ Handle<Value> DLOpen(const v8::Arguments& args) { // Tell coverity that 'handle' should not be freed when we return. // coverity[leaked_storage] - return Undefined(node_isolate); } @@ -1884,8 +1867,9 @@ void FatalException(Handle<Value> error, Handle<Message> message) { HandleScope scope(node_isolate); if (fatal_exception_symbol.IsEmpty()) - fatal_exception_symbol = NODE_PSYMBOL("_fatalException"); + fatal_exception_symbol = String::New("_fatalException"); + Local<Object> process = Local<Object>::New(node_isolate, process_p); Local<Value> fatal_v = process->Get(fatal_exception_symbol); if (!fatal_v->IsFunction()) { @@ -1933,71 +1917,68 @@ void OnMessage(Handle<Message> message, Handle<Value> error) { } -Persistent<Object> binding_cache; -Persistent<Array> module_load_list; - -static Handle<Value> Binding(const Arguments& args) { +static void Binding(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Local<String> module = args[0]->ToString(); String::Utf8Value module_v(module); node_module_struct* modp; - if (binding_cache.IsEmpty()) { - binding_cache = Persistent<Object>::New(node_isolate, Object::New()); - } - + Local<Object> cache = Local<Object>::New(node_isolate, binding_cache); Local<Object> exports; - if (binding_cache->Has(module)) { - exports = binding_cache->Get(module)->ToObject(); - return scope.Close(exports); + if (cache->Has(module)) { + exports = cache->Get(module)->ToObject(); + args.GetReturnValue().Set(exports); + return; } // Append a string to process.moduleLoadList char buf[1024]; snprintf(buf, 1024, "Binding %s", *module_v); - uint32_t l = module_load_list->Length(); - module_load_list->Set(l, String::New(buf)); + + Local<Array> modules = Local<Array>::New(node_isolate, module_load_list); + uint32_t l = modules->Length(); + modules->Set(l, String::New(buf)); if ((modp = get_builtin_module(*module_v)) != NULL) { exports = Object::New(); // Internal bindings don't have a "module" object, // only exports. modp->register_func(exports, Undefined(node_isolate)); - binding_cache->Set(module, exports); + cache->Set(module, exports); } else if (!strcmp(*module_v, "constants")) { exports = Object::New(); DefineConstants(exports); - binding_cache->Set(module, exports); + cache->Set(module, exports); } else if (!strcmp(*module_v, "natives")) { exports = Object::New(); DefineJavaScript(exports); - binding_cache->Set(module, exports); + cache->Set(module, exports); } else { - return ThrowException(Exception::Error(String::New("No such module"))); + return ThrowError("No such module"); } - return scope.Close(exports); + args.GetReturnValue().Set(exports); } -static Handle<Value> ProcessTitleGetter(Local<String> property, - const AccessorInfo& info) { +static void ProcessTitleGetter(Local<String> property, + const PropertyCallbackInfo<Value>& info) { HandleScope scope(node_isolate); char buffer[512]; uv_get_process_title(buffer, sizeof(buffer)); - return scope.Close(String::New(buffer)); + info.GetReturnValue().Set(String::New(buffer)); } static void ProcessTitleSetter(Local<String> property, Local<Value> value, - const AccessorInfo& info) { + const PropertyCallbackInfo<void>& info) { HandleScope scope(node_isolate); String::Utf8Value title(value); // TODO: protect with a lock @@ -2005,14 +1986,14 @@ static void ProcessTitleSetter(Local<String> property, } -static Handle<Value> EnvGetter(Local<String> property, - const AccessorInfo& info) { +static void EnvGetter(Local<String> property, + const PropertyCallbackInfo<Value>& info) { HandleScope scope(node_isolate); #ifdef __POSIX__ String::Utf8Value key(property); const char* val = getenv(*key); if (val) { - return scope.Close(String::New(val)); + return info.GetReturnValue().Set(String::New(val)); } #else // _WIN32 String::Value key(property); @@ -2025,17 +2006,19 @@ static Handle<Value> EnvGetter(Local<String> property, // not found. if ((result > 0 || GetLastError() == ERROR_SUCCESS) && result < ARRAY_SIZE(buffer)) { - return scope.Close(String::New(reinterpret_cast<uint16_t*>(buffer), result)); + return info.GetReturnValue().Set( + String::New(reinterpret_cast<uint16_t*>(buffer), result)); } #endif // Not found. Fetch from prototype. - return scope.Close(info.Data().As<Object>()->Get(property)); + info.GetReturnValue().Set( + info.Data().As<Object>()->Get(property)); } -static Handle<Value> EnvSetter(Local<String> property, - Local<Value> value, - const AccessorInfo& info) { +static void EnvSetter(Local<String> property, + Local<Value> value, + const PropertyCallbackInfo<Value>& info) { HandleScope scope(node_isolate); #ifdef __POSIX__ String::Utf8Value key(property); @@ -2051,63 +2034,58 @@ static Handle<Value> EnvSetter(Local<String> property, } #endif // Whether it worked or not, always return rval. - return scope.Close(value); + info.GetReturnValue().Set(value); } -static Handle<Integer> EnvQuery(Local<String> property, - const AccessorInfo& info) { +static void EnvQuery(Local<String> property, + const PropertyCallbackInfo<Integer>& info) { HandleScope scope(node_isolate); + int32_t rc = -1; // Not found unless proven otherwise. #ifdef __POSIX__ String::Utf8Value key(property); - if (getenv(*key)) { - return scope.Close(Integer::New(0, node_isolate)); - } + if (getenv(*key)) rc = 0; #else // _WIN32 String::Value key(property); WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key); if (GetEnvironmentVariableW(key_ptr, NULL, 0) > 0 || GetLastError() == ERROR_SUCCESS) { + rc = 0; if (key_ptr[0] == L'=') { // Environment variables that start with '=' are hidden and read-only. - return scope.Close(Integer::New(v8::ReadOnly || - v8::DontDelete || - v8::DontEnum, - node_isolate)); - } else { - return scope.Close(Integer::New(0, node_isolate)); + rc = static_cast<int32_t>(v8::ReadOnly) | + static_cast<int32_t>(v8::DontDelete) | + static_cast<int32_t>(v8::DontEnum); } } #endif - // Not found - return scope.Close(Handle<Integer>()); + if (rc != -1) info.GetReturnValue().Set(rc); } -static Handle<Boolean> EnvDeleter(Local<String> property, - const AccessorInfo& info) { +static void EnvDeleter(Local<String> property, + const PropertyCallbackInfo<Boolean>& info) { HandleScope scope(node_isolate); + bool rc = true; #ifdef __POSIX__ String::Utf8Value key(property); - if (!getenv(*key)) return False(node_isolate); - unsetenv(*key); // can't check return value, it's void on some platforms - return True(node_isolate); + rc = getenv(*key) != NULL; + if (rc) unsetenv(*key); #else String::Value key(property); WCHAR* key_ptr = reinterpret_cast<WCHAR*>(*key); if (key_ptr[0] == L'=' || !SetEnvironmentVariableW(key_ptr, NULL)) { // Deletion failed. Return true if the key wasn't there in the first place, // false if it is still there. - bool rv = GetEnvironmentVariableW(key_ptr, NULL, NULL) == 0 && - GetLastError() != ERROR_SUCCESS; - return scope.Close(Boolean::New(rv)); + rc = GetEnvironmentVariableW(key_ptr, NULL, NULL) == 0 && + GetLastError() != ERROR_SUCCESS; } - return True(node_isolate); #endif + info.GetReturnValue().Set(rc); } -static Handle<Array> EnvEnumerator(const AccessorInfo& info) { +static void EnvEnumerator(const PropertyCallbackInfo<Array>& info) { HandleScope scope(node_isolate); #ifdef __POSIX__ int size = 0; @@ -2123,10 +2101,7 @@ static Handle<Array> EnvEnumerator(const AccessorInfo& info) { } #else // _WIN32 WCHAR* environment = GetEnvironmentStringsW(); - if (environment == NULL) { - // This should not happen. - return scope.Close(Handle<Array>()); - } + if (environment == NULL) return; // This should not happen. Local<Array> env = Array::New(); WCHAR* p = environment; int i = 0; @@ -2147,7 +2122,8 @@ static Handle<Array> EnvEnumerator(const AccessorInfo& info) { } FreeEnvironmentStringsW(environment); #endif - return scope.Close(env); + + info.GetReturnValue().Set(env); } @@ -2174,35 +2150,35 @@ static Handle<Object> GetFeatures() { } -static Handle<Value> DebugPortGetter(Local<String> property, - const AccessorInfo& info) { +static void DebugPortGetter(Local<String> property, + const PropertyCallbackInfo<Value>& info) { HandleScope scope(node_isolate); - return scope.Close(Integer::NewFromUnsigned(debug_port, node_isolate)); + info.GetReturnValue().Set(debug_port); } static void DebugPortSetter(Local<String> property, Local<Value> value, - const AccessorInfo& info) { + const PropertyCallbackInfo<void>& info) { HandleScope scope(node_isolate); debug_port = value->NumberValue(); } -static Handle<Value> DebugProcess(const Arguments& args); -static Handle<Value> DebugPause(const Arguments& args); -static Handle<Value> DebugEnd(const Arguments& args); +static void DebugProcess(const FunctionCallbackInfo<Value>& args); +static void DebugPause(const FunctionCallbackInfo<Value>& args); +static void DebugEnd(const FunctionCallbackInfo<Value>& args); -Handle<Value> NeedImmediateCallbackGetter(Local<String> property, - const AccessorInfo& info) { - return Boolean::New(need_immediate_cb); +void NeedImmediateCallbackGetter(Local<String> property, + const PropertyCallbackInfo<Value>& info) { + info.GetReturnValue().Set(need_immediate_cb); } static void NeedImmediateCallbackSetter(Local<String> property, Local<Value> value, - const AccessorInfo& info) { + const PropertyCallbackInfo<void>&) { HandleScope scope(node_isolate); bool bool_value = value->BooleanValue(); @@ -2228,11 +2204,13 @@ Handle<Object> SetupProcessObject(int argc, char *argv[]) { int i, j; Local<FunctionTemplate> process_template = FunctionTemplate::New(); + process_template->SetClassName(String::New("process")); - process_template->SetClassName(String::NewSymbol("process")); + Local<Object> process = process_template->GetFunction()->NewInstance(); + assert(process.IsEmpty() == false); + assert(process->IsObject() == true); - process = Persistent<Object>::New(node_isolate, - process_template->GetFunction()->NewInstance()); + process_p.Reset(node_isolate, process); process->SetAccessor(String::New("title"), ProcessTitleGetter, @@ -2242,8 +2220,9 @@ Handle<Object> SetupProcessObject(int argc, char *argv[]) { process->Set(String::NewSymbol("version"), String::New(NODE_VERSION)); // process.moduleLoadList - module_load_list = Persistent<Array>::New(node_isolate, Array::New()); - process->Set(String::NewSymbol("moduleLoadList"), module_load_list); + Local<Array> modules = Array::New(); + module_load_list.Reset(node_isolate, modules); + process->Set(String::NewSymbol("moduleLoadList"), modules); // process.versions Local<Object> versions = Object::New(); @@ -2414,7 +2393,7 @@ Handle<Object> SetupProcessObject(int argc, char *argv[]) { // pre-set _events object for faster emit checks process->Set(String::NewSymbol("_events"), Object::New()); - return process; + return scope.Close(process); } @@ -2430,8 +2409,8 @@ static void SignalExit(int signal) { void Load(Handle<Object> process_l) { - process_symbol = NODE_PSYMBOL("process"); - domain_symbol = NODE_PSYMBOL("domain"); + process_symbol = String::New("process"); + domain_symbol = String::New("domain"); // Compile, execute the src/node.js file. (Which was included as static C // string in node_natives.h. 'natve_node' is the string containing that @@ -2466,7 +2445,6 @@ void Load(Handle<Object> process_l) { // Add a reference to the global object Local<Object> global = v8::Context::GetCurrent()->Global(); - Local<Value> args[1] = { Local<Value>::New(node_isolate, process_l) }; #if defined HAVE_DTRACE || defined HAVE_ETW || defined HAVE_SYSTEMTAP InitDTrace(global); @@ -2484,7 +2462,8 @@ void Load(Handle<Object> process_l) { // thrown during process startup. try_catch.SetVerbose(true); - f->Call(global, 1, args); + Local<Value> arg = process_l; + f->Call(global, 1, &arg); } static void PrintHelp(); @@ -2643,7 +2622,7 @@ static void EmitDebugEnabledAsyncCallback(uv_async_t* handle, int status) { Local<Object> obj = Object::New(); obj->Set(String::New("cmd"), String::New("NODE_DEBUG_ENABLED")); Local<Value> args[] = { String::New("internalMessage"), obj }; - MakeCallback(process, "emit", ARRAY_SIZE(args), args); + MakeCallback(process_p, "emit", ARRAY_SIZE(args), args); } @@ -2677,7 +2656,7 @@ static void EnableDebug(bool wait_connect) { // Do not emit NODE_DEBUG_ENABLED when debugger is enabled before starting // the main process (i.e. when called via `node --debug`) - if (!process.IsEmpty()) + if (!process_p.IsEmpty()) EmitDebugEnabled(); node_isolate->Exit(); @@ -2706,12 +2685,11 @@ static void RegisterSignalHandler(int signal, void (*handler)(int)) { } -Handle<Value> DebugProcess(const Arguments& args) { +void DebugProcess(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); if (args.Length() != 1) { - return ThrowException(Exception::Error( - String::New("Invalid number of arguments."))); + return ThrowError("Invalid number of arguments."); } pid_t pid; @@ -2720,10 +2698,8 @@ Handle<Value> DebugProcess(const Arguments& args) { pid = args[0]->IntegerValue(); r = kill(pid, SIGUSR1); if (r != 0) { - return ThrowException(ErrnoException(errno, "kill")); + return ThrowErrnoException(errno, "kill"); } - - return Undefined(node_isolate); } #endif // __POSIX__ @@ -2794,9 +2770,8 @@ static int RegisterDebugSignalHandler() { } -static Handle<Value> DebugProcess(const Arguments& args) { +static void DebugProcess(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); - Handle<Value> rv = Undefined(node_isolate); DWORD pid; HANDLE process = NULL; HANDLE thread = NULL; @@ -2805,7 +2780,7 @@ static Handle<Value> DebugProcess(const Arguments& args) { LPTHREAD_START_ROUTINE* handler = NULL; if (args.Length() != 1) { - rv = ThrowException(Exception::Error(String::New("Invalid number of arguments."))); + ThrowError("Invalid number of arguments."); goto out; } @@ -2817,21 +2792,20 @@ static Handle<Value> DebugProcess(const Arguments& args) { FALSE, pid); if (process == NULL) { - rv = ThrowException(WinapiErrnoException(GetLastError(), "OpenProcess")); + ThrowException(WinapiErrnoException(GetLastError(), "OpenProcess")); goto out; } if (GetDebugSignalHandlerMappingName(pid, mapping_name, ARRAY_SIZE(mapping_name)) < 0) { - rv = ThrowException(ErrnoException(errno, "sprintf")); + ThrowErrnoException(errno, "sprintf"); goto out; } mapping = OpenFileMappingW(FILE_MAP_READ, FALSE, mapping_name); if (mapping == NULL) { - rv = ThrowException(WinapiErrnoException(GetLastError(), - "OpenFileMappingW")); + ThrowException(WinapiErrnoException(GetLastError(), "OpenFileMappingW")); goto out; } @@ -2842,7 +2816,7 @@ static Handle<Value> DebugProcess(const Arguments& args) { 0, sizeof *handler)); if (handler == NULL || *handler == NULL) { - rv = ThrowException(WinapiErrnoException(GetLastError(), "MapViewOfFile")); + ThrowException(WinapiErrnoException(GetLastError(), "MapViewOfFile")); goto out; } @@ -2854,15 +2828,13 @@ static Handle<Value> DebugProcess(const Arguments& args) { 0, NULL); if (thread == NULL) { - rv = ThrowException(WinapiErrnoException(GetLastError(), - "CreateRemoteThread")); + ThrowException(WinapiErrnoException(GetLastError(), "CreateRemoteThread")); goto out; } // Wait for the thread to terminate if (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0) { - rv = ThrowException(WinapiErrnoException(GetLastError(), - "WaitForSingleObject")); + ThrowException(WinapiErrnoException(GetLastError(), "WaitForSingleObject")); goto out; } @@ -2879,25 +2851,20 @@ static Handle<Value> DebugProcess(const Arguments& args) { if (mapping != NULL) { CloseHandle(mapping); } - - return Undefined(node_isolate); } #endif // _WIN32 -static Handle<Value> DebugPause(const Arguments& args) { +static void DebugPause(const FunctionCallbackInfo<Value>& args) { v8::Debug::DebugBreak(node_isolate); - return Undefined(node_isolate); } -static Handle<Value> DebugEnd(const Arguments& args) { +static void DebugEnd(const FunctionCallbackInfo<Value>& args) { if (debugger_running) { v8::Debug::DisableAgent(); debugger_running = false; } - - return Undefined(node_isolate); } @@ -3026,7 +2993,7 @@ void EmitExit(v8::Handle<v8::Object> process_l) { // process.emit('exit') process_l->Set(String::NewSymbol("_exiting"), True(node_isolate)); Local<Value> args[] = { String::New("exit"), Integer::New(0, node_isolate) }; - MakeCallback(process, "emit", ARRAY_SIZE(args), args); + MakeCallback(process_l, "emit", ARRAY_SIZE(args), args); } static char **copy_argv(int argc, char **argv) { @@ -3081,9 +3048,10 @@ int Start(int argc, char *argv[]) { Local<Context> context = Context::New(node_isolate); Context::Scope context_scope(context); + binding_cache.Reset(node_isolate, Object::New()); + // Use original argv, as we're just copying values out of it. - Handle<Object> process_l = SetupProcessObject(argc, argv); - v8_typed_array::AttachBindings(context->Global()); + Local<Object> process_l = SetupProcessObject(argc, argv); // Create all the objects, load modules, do everything. // so your next reading stop should be node::Load()! diff --git a/src/node.h b/src/node.h index 59d03a355..16bfec56d 100644 --- a/src/node.h +++ b/src/node.h @@ -95,10 +95,6 @@ v8::Handle<v8::Object> SetupProcessObject(int argc, char *argv[]); void Load(v8::Handle<v8::Object> process); void EmitExit(v8::Handle<v8::Object> process); -#define NODE_PSYMBOL(s) \ - v8::Persistent<v8::String>::New(v8::Isolate::GetCurrent(), \ - v8::String::NewSymbol(s)) - /* Converts a unixtime to V8 Date */ #define NODE_UNIXTIME_V8(t) v8::Date::New(1000*static_cast<double>(t)) #define NODE_V8_UNIXTIME(v) (static_cast<double>((v)->NumberValue())/1000.0); @@ -109,25 +105,25 @@ void EmitExit(v8::Handle<v8::Object> process); static_cast<v8::PropertyAttribute>( \ v8::ReadOnly|v8::DontDelete)) -template <typename target_t> -void SetMethod(target_t obj, const char* name, - v8::InvocationCallback callback) -{ - obj->Set(v8::String::NewSymbol(name), - v8::FunctionTemplate::New(callback)->GetFunction()); +// Used to be a macro, hence the uppercase name. +template <typename TypeName> +inline void NODE_SET_METHOD(TypeName& recv, + const char* name, + v8::FunctionCallback callback) { + v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(callback); + recv->Set(v8::String::New(name), t->GetFunction()); } - -template <typename target_t> -void SetPrototypeMethod(target_t target, - const char* name, v8::InvocationCallback callback) -{ - v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(callback); - target->PrototypeTemplate()->Set(v8::String::NewSymbol(name), templ); +#define NODE_SET_METHOD node::NODE_SET_METHOD + +// Used to be a macro, hence the uppercase name. +// Not a template because it only makes sense for FunctionTemplates. +inline void NODE_SET_PROTOTYPE_METHOD(v8::Handle<v8::FunctionTemplate> recv, + const char* name, + v8::FunctionCallback callback) { + v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(callback); + recv->PrototypeTemplate()->Set(v8::String::New(name), t->GetFunction()); } - -// for backwards compatibility -#define NODE_SET_METHOD node::SetMethod -#define NODE_SET_PROTOTYPE_METHOD node::SetPrototypeMethod +#define NODE_SET_PROTOTYPE_METHOD node::NODE_SET_PROTOTYPE_METHOD enum encoding {ASCII, UTF8, BASE64, UCS2, BINARY, HEX, BUFFER}; enum encoding ParseEncoding(v8::Handle<v8::Value> encoding_v, @@ -151,25 +147,6 @@ NODE_EXTERN ssize_t DecodeWrite(char *buf, v8::Local<v8::Object> BuildStatsObject(const uv_stat_t* s); -static inline v8::Persistent<v8::Function>* cb_persist(v8::Local<v8::Value> v) { - v8::Persistent<v8::Function>* fn = new v8::Persistent<v8::Function>(); - *fn = v8::Persistent<v8::Function>::New(v8::Isolate::GetCurrent(), - v.As<v8::Function>()); - return fn; -} - -static inline v8::Persistent<v8::Function>* cb_unwrap(void *data) { - v8::Persistent<v8::Function> *cb = - reinterpret_cast<v8::Persistent<v8::Function>*>(data); - assert((*cb)->IsFunction()); - return cb; -} - -static inline void cb_destroy(v8::Persistent<v8::Function> * cb) { - cb->Dispose(v8::Isolate::GetCurrent()); - delete cb; -} - NODE_EXTERN v8::Local<v8::Value> ErrnoException(int errorno, const char *syscall = NULL, const char *msg = "", diff --git a/src/node_buffer.cc b/src/node_buffer.cc index 95cfa3e92..9ed92b09e 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -57,9 +57,8 @@ namespace node { namespace Buffer { - -using v8::Arguments; using v8::Function; +using v8::FunctionCallbackInfo; using v8::FunctionTemplate; using v8::Handle; using v8::HandleScope; @@ -72,8 +71,7 @@ using v8::Uint32; using v8::Undefined; using v8::Value; - -Persistent<Function> p_buffer_fn; +static Persistent<Function> p_buffer_fn; bool HasInstance(Handle<Value> val) { @@ -140,7 +138,7 @@ Local<Object> New(size_t length) { // of GC reclaiming the values prematurely. argv[0] = Undefined(node_isolate); argv[1] = Uint32::New(length, node_isolate); - Local<Object> obj = p_buffer_fn->NewInstance(2, argv); + Local<Object> obj = NewInstance(p_buffer_fn, ARRAY_SIZE(argv), argv); // TODO(trevnorris): done like this to handle HasInstance since only checks // if external array data has been set, but would like to use a better @@ -172,7 +170,7 @@ Local<Object> New(const char* data, size_t length) { // of GC reclaiming the values prematurely. argv[0] = Undefined(node_isolate); argv[1] = Uint32::New(length, node_isolate); - Local<Object> obj = p_buffer_fn->NewInstance(2, argv); + Local<Object> obj = NewInstance(p_buffer_fn, ARRAY_SIZE(argv), argv); // TODO(trevnorris): done like this to handle HasInstance since only checks // if external array data has been set, but would like to use a better @@ -206,7 +204,7 @@ Local<Object> New(char* data, // of GC reclaiming the values prematurely. argv[0] = Undefined(node_isolate); argv[1] = Uint32::New(length, node_isolate); - Local<Object> obj = p_buffer_fn->NewInstance(2, argv); + Local<Object> obj = NewInstance(p_buffer_fn, ARRAY_SIZE(argv), argv); smalloc::Alloc(obj, data, length, callback, hint); @@ -224,7 +222,7 @@ Local<Object> Use(char* data, uint32_t length) { // of GC reclaiming the values prematurely. argv[0] = Undefined(node_isolate); argv[1] = Uint32::New(length, node_isolate); - Local<Object> obj = p_buffer_fn->NewInstance(2, argv); + Local<Object> obj = NewInstance(p_buffer_fn, ARRAY_SIZE(argv), argv); smalloc::Alloc(obj, data, length); @@ -233,49 +231,49 @@ Local<Object> Use(char* data, uint32_t length) { template <encoding encoding> -Handle<Value> StringSlice(const Arguments& args) { +void StringSlice(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); ARGS_THIS(args.This()) SLICE_START_END(args[0], args[1], obj_length) - return scope.Close(StringBytes::Encode(obj_data + start, length, encoding)); + args.GetReturnValue().Set( + StringBytes::Encode(obj_data + start, length, encoding)); } -Handle<Value> BinarySlice(const Arguments& args) { - return StringSlice<BINARY>(args); +void BinarySlice(const FunctionCallbackInfo<Value>& args) { + StringSlice<BINARY>(args); } -Handle<Value> AsciiSlice(const Arguments& args) { - return StringSlice<ASCII>(args); +void AsciiSlice(const FunctionCallbackInfo<Value>& args) { + StringSlice<ASCII>(args); } -Handle<Value> Utf8Slice(const Arguments& args) { - return StringSlice<UTF8>(args); +void Utf8Slice(const FunctionCallbackInfo<Value>& args) { + StringSlice<UTF8>(args); } -Handle<Value> Ucs2Slice(const Arguments& args) { - return StringSlice<UCS2>(args); +void Ucs2Slice(const FunctionCallbackInfo<Value>& args) { + StringSlice<UCS2>(args); } - -Handle<Value> HexSlice(const Arguments& args) { - return StringSlice<HEX>(args); +void HexSlice(const FunctionCallbackInfo<Value>& args) { + StringSlice<HEX>(args); } -Handle<Value> Base64Slice(const Arguments& args) { - return StringSlice<BASE64>(args); +void Base64Slice(const FunctionCallbackInfo<Value>& args) { + StringSlice<BASE64>(args); } // bytesCopied = buffer.copy(target[, targetStart][, sourceStart][, sourceEnd]); -Handle<Value> Copy(const Arguments &args) { +void Copy(const FunctionCallbackInfo<Value> &args) { HandleScope scope(node_isolate); Local<Object> target = args[0]->ToObject(); @@ -297,7 +295,7 @@ Handle<Value> Copy(const Arguments &args) { // Copy 0 bytes; we're done if (target_start >= target_length || source_start >= source_end) - return scope.Close(Uint32::New(0, node_isolate)); + return args.GetReturnValue().Set(0); if (source_start > obj_length) return ThrowRangeError("out of range index"); @@ -305,27 +303,27 @@ Handle<Value> Copy(const Arguments &args) { if (source_end - source_start > target_length - target_start) source_end = source_start + target_length - target_start; - size_t to_copy = MIN(MIN(source_end - source_start, - target_length - target_start), - obj_length - source_start); + uint32_t to_copy = MIN(MIN(source_end - source_start, + target_length - target_start), + obj_length - source_start); memmove(target_data + target_start, obj_data + source_start, to_copy); - - return scope.Close(Uint32::New(to_copy, node_isolate)); + args.GetReturnValue().Set(to_copy); } // buffer.fill(value[, start][, end]); -Handle<Value> Fill(const Arguments &args) { +void Fill(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); ARGS_THIS(args.This()) SLICE_START_END(args[1], args[2], obj_length) + args.GetReturnValue().Set(args.This()); if (args[0]->IsNumber()) { int value = args[0]->Uint32Value() & 255; memset(obj_data + start, value, length); - return args.This(); + return; } String::Utf8Value at(args[0]); @@ -335,7 +333,7 @@ Handle<Value> Fill(const Arguments &args) { if (at_length == 1) { int value = static_cast<int>((*at)[0]); memset(obj_data + start, value, length); - return args.This(); + return; } size_t in_there = at_length; @@ -344,7 +342,7 @@ Handle<Value> Fill(const Arguments &args) { memcpy(obj_data + start, *at, MIN(at_length, length)); if (at_length >= length) - return args.This(); + return; while (in_there < length - in_there) { memcpy(ptr, obj_data + start, in_there); @@ -356,13 +354,11 @@ Handle<Value> Fill(const Arguments &args) { memcpy(ptr, obj_data + start, length - in_there); in_there = length; } - - return args.This(); } template <encoding encoding> -Handle<Value> StringWrite(const Arguments& args) { +void StringWrite(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); ARGS_THIS(args.This()) @@ -384,7 +380,7 @@ Handle<Value> StringWrite(const Arguments& args) { max_length = MIN(obj_length - offset, max_length); if (max_length == 0) - return scope.Close(Uint32::New(0, node_isolate)); + return args.GetReturnValue().Set(0); if (encoding == UCS2) max_length = max_length / 2; @@ -392,43 +388,42 @@ Handle<Value> StringWrite(const Arguments& args) { if (offset >= obj_length) return ThrowRangeError("Offset is out of bounds"); - size_t written = StringBytes::Write(obj_data + offset, - max_length, - str, - encoding, - NULL); - - return scope.Close(Uint32::New(written, node_isolate)); + uint32_t written = StringBytes::Write(obj_data + offset, + max_length, + str, + encoding, + NULL); + args.GetReturnValue().Set(written); } -Handle<Value> Base64Write(const Arguments& args) { - return StringWrite<BASE64>(args); +void Base64Write(const FunctionCallbackInfo<Value>& args) { + StringWrite<BASE64>(args); } -Handle<Value> BinaryWrite(const Arguments& args) { - return StringWrite<BINARY>(args); +void BinaryWrite(const FunctionCallbackInfo<Value>& args) { + StringWrite<BINARY>(args); } -Handle<Value> Utf8Write(const Arguments& args) { - return StringWrite<UTF8>(args); +void Utf8Write(const FunctionCallbackInfo<Value>& args) { + StringWrite<UTF8>(args); } -Handle<Value> Ucs2Write(const Arguments& args) { - return StringWrite<UCS2>(args); +void Ucs2Write(const FunctionCallbackInfo<Value>& args) { + StringWrite<UCS2>(args); } -Handle<Value> HexWrite(const Arguments& args) { - return StringWrite<HEX>(args); +void HexWrite(const FunctionCallbackInfo<Value>& args) { + StringWrite<HEX>(args); } -Handle<Value> AsciiWrite(const Arguments& args) { - return StringWrite<ASCII>(args); +void AsciiWrite(const FunctionCallbackInfo<Value>& args) { + StringWrite<ASCII>(args); } @@ -443,7 +438,7 @@ static inline void Swizzle(char* start, unsigned int len) { template <typename T, enum Endianness endianness> -Handle<Value> ReadFloatGeneric(const Arguments& args) { +void ReadFloatGeneric(const FunctionCallbackInfo<Value>& args) { bool doAssert = !args[1]->BooleanValue(); size_t offset; @@ -466,32 +461,32 @@ Handle<Value> ReadFloatGeneric(const Arguments& args) { memcpy(na.bytes, ptr, sizeof(na.bytes)); if (endianness != GetEndianness()) Swizzle(na.bytes, sizeof(na.bytes)); - return Number::New(na.val); + args.GetReturnValue().Set(na.val); } -Handle<Value> ReadFloatLE(const Arguments& args) { - return ReadFloatGeneric<float, kLittleEndian>(args); +void ReadFloatLE(const FunctionCallbackInfo<Value>& args) { + ReadFloatGeneric<float, kLittleEndian>(args); } -Handle<Value> ReadFloatBE(const Arguments& args) { - return ReadFloatGeneric<float, kBigEndian>(args); +void ReadFloatBE(const FunctionCallbackInfo<Value>& args) { + ReadFloatGeneric<float, kBigEndian>(args); } -Handle<Value> ReadDoubleLE(const Arguments& args) { - return ReadFloatGeneric<double, kLittleEndian>(args); +void ReadDoubleLE(const FunctionCallbackInfo<Value>& args) { + ReadFloatGeneric<double, kLittleEndian>(args); } -Handle<Value> ReadDoubleBE(const Arguments& args) { - return ReadFloatGeneric<double, kBigEndian>(args); +void ReadDoubleBE(const FunctionCallbackInfo<Value>& args) { + ReadFloatGeneric<double, kBigEndian>(args); } template <typename T, enum Endianness endianness> -Handle<Value> WriteFloatGeneric(const Arguments& args) { +void WriteFloatGeneric(const FunctionCallbackInfo<Value>& args) { bool doAssert = !args[2]->BooleanValue(); T val = static_cast<T>(args[0]->NumberValue()); @@ -515,32 +510,30 @@ Handle<Value> WriteFloatGeneric(const Arguments& args) { char* ptr = static_cast<char*>(data) + offset; if (endianness != GetEndianness()) Swizzle(na.bytes, sizeof(na.bytes)); memcpy(ptr, na.bytes, sizeof(na.bytes)); - - return Undefined(node_isolate); } -Handle<Value> WriteFloatLE(const Arguments& args) { - return WriteFloatGeneric<float, kLittleEndian>(args); +void WriteFloatLE(const FunctionCallbackInfo<Value>& args) { + WriteFloatGeneric<float, kLittleEndian>(args); } -Handle<Value> WriteFloatBE(const Arguments& args) { - return WriteFloatGeneric<float, kBigEndian>(args); +void WriteFloatBE(const FunctionCallbackInfo<Value>& args) { + WriteFloatGeneric<float, kBigEndian>(args); } -Handle<Value> WriteDoubleLE(const Arguments& args) { - return WriteFloatGeneric<double, kLittleEndian>(args); +void WriteDoubleLE(const FunctionCallbackInfo<Value>& args) { + WriteFloatGeneric<double, kLittleEndian>(args); } -Handle<Value> WriteDoubleBE(const Arguments& args) { - return WriteFloatGeneric<double, kBigEndian>(args); +void WriteDoubleBE(const FunctionCallbackInfo<Value>& args) { + WriteFloatGeneric<double, kBigEndian>(args); } -Handle<Value> ByteLength(const Arguments &args) { +void ByteLength(const FunctionCallbackInfo<Value> &args) { HandleScope scope(node_isolate); if (!args[0]->IsString()) @@ -549,18 +542,19 @@ Handle<Value> ByteLength(const Arguments &args) { Local<String> s = args[0]->ToString(); enum encoding e = ParseEncoding(args[1], UTF8); - return scope.Close(Uint32::New(StringBytes::Size(s, e), node_isolate)); + uint32_t size = StringBytes::Size(s, e); + args.GetReturnValue().Set(size); } // pass Buffer object to load prototype methods -Handle<Value> SetupBufferJS(const Arguments& args) { +void SetupBufferJS(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); assert(args[0]->IsFunction()); Local<Function> bv = args[0].As<Function>(); - p_buffer_fn = Persistent<Function>::New(node_isolate, bv); + p_buffer_fn.Reset(node_isolate, bv); Local<Value> proto_v = bv->Get(String::New("prototype")); assert(proto_v->IsObject()); @@ -599,8 +593,6 @@ Handle<Value> SetupBufferJS(const Arguments& args) { // for backwards compatibility proto->Set(String::New("offset"), Uint32::New(0, node_isolate), v8::ReadOnly); - - return Undefined(node_isolate); } diff --git a/src/node_counters.cc b/src/node_counters.cc index 289be6018..8f6d136f4 100644 --- a/src/node_counters.cc +++ b/src/node_counters.cc @@ -20,7 +20,6 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. #include "node_counters.h" - #include "uv.h" #include <string.h> @@ -28,60 +27,55 @@ namespace node { -using namespace v8; - +using v8::FunctionCallbackInfo; +using v8::FunctionTemplate; +using v8::GCCallbackFlags; +using v8::GCEpilogueCallback; +using v8::GCPrologueCallback; +using v8::GCType; +using v8::Handle; +using v8::HandleScope; +using v8::Local; +using v8::Object; +using v8::String; +using v8::Value; static uint64_t counter_gc_start_time; static uint64_t counter_gc_end_time; -#define SLURP_OBJECT(obj, member, valp) \ - if (!(obj)->IsObject()) { \ - return (ThrowException(Exception::Error(String::New("expected " \ - "object for " #obj " to contain object member " #member)))); \ - } \ - *valp = Local<Object>::Cast(obj->Get(String::New(#member))); - -Handle<Value> COUNTER_NET_SERVER_CONNECTION(const Arguments& args) { +void COUNTER_NET_SERVER_CONNECTION(const FunctionCallbackInfo<Value>&) { NODE_COUNT_SERVER_CONN_OPEN(); - return Undefined(node_isolate); } -Handle<Value> COUNTER_NET_SERVER_CONNECTION_CLOSE(const Arguments& args) { +void COUNTER_NET_SERVER_CONNECTION_CLOSE(const FunctionCallbackInfo<Value>&) { NODE_COUNT_SERVER_CONN_CLOSE(); - return Undefined(node_isolate); } -Handle<Value> COUNTER_HTTP_SERVER_REQUEST(const Arguments& args) { +void COUNTER_HTTP_SERVER_REQUEST(const FunctionCallbackInfo<Value>&) { NODE_COUNT_HTTP_SERVER_REQUEST(); - return Undefined(node_isolate); } -Handle<Value> COUNTER_HTTP_SERVER_RESPONSE(const Arguments& args) { +void COUNTER_HTTP_SERVER_RESPONSE(const FunctionCallbackInfo<Value>&) { NODE_COUNT_HTTP_SERVER_RESPONSE(); - return Undefined(node_isolate); } -Handle<Value> COUNTER_HTTP_CLIENT_REQUEST(const Arguments& args) { +void COUNTER_HTTP_CLIENT_REQUEST(const FunctionCallbackInfo<Value>&) { NODE_COUNT_HTTP_CLIENT_REQUEST(); - return Undefined(node_isolate); } -Handle<Value> COUNTER_HTTP_CLIENT_RESPONSE(const Arguments& args) { +void COUNTER_HTTP_CLIENT_RESPONSE(const FunctionCallbackInfo<Value>&) { NODE_COUNT_HTTP_CLIENT_RESPONSE(); - return Undefined(node_isolate); } static void counter_gc_start(GCType type, GCCallbackFlags flags) { counter_gc_start_time = NODE_COUNT_GET_GC_RAWTIME(); - - return; } @@ -98,33 +92,30 @@ static void counter_gc_done(GCType type, GCCallbackFlags flags) { counter_gc_end_time = endgc; } } - - return; } -#define NODE_PROBE(name) #name, name - void InitPerfCounters(Handle<Object> target) { HandleScope scope(node_isolate); static struct { const char* name; - Handle<Value> (*func)(const Arguments&); - Persistent<FunctionTemplate> templ; + void (*func)(const FunctionCallbackInfo<Value>&); } tab[] = { +#define NODE_PROBE(name) #name, name { NODE_PROBE(COUNTER_NET_SERVER_CONNECTION) }, { NODE_PROBE(COUNTER_NET_SERVER_CONNECTION_CLOSE) }, { NODE_PROBE(COUNTER_HTTP_SERVER_REQUEST) }, { NODE_PROBE(COUNTER_HTTP_SERVER_RESPONSE) }, { NODE_PROBE(COUNTER_HTTP_CLIENT_REQUEST) }, { NODE_PROBE(COUNTER_HTTP_CLIENT_RESPONSE) } +#undef NODE_PROBE }; for (int i = 0; i < ARRAY_SIZE(tab); i++) { - tab[i].templ = Persistent<FunctionTemplate>::New(node_isolate, - FunctionTemplate::New(tab[i].func)); - target->Set(String::NewSymbol(tab[i].name), tab[i].templ->GetFunction()); + Local<String> key = String::New(tab[i].name); + Local<Value> val = FunctionTemplate::New(tab[i].func)->GetFunction(); + target->Set(key, val); } // Only Windows performance counters supported diff --git a/src/node_crypto.cc b/src/node_crypto.cc index c902bcb7a..fc826c154 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -45,15 +45,13 @@ #define ASSERT_IS_STRING_OR_BUFFER(val) do { \ if (!Buffer::HasInstance(val) && !val->IsString()) { \ - return ThrowException(Exception::TypeError(String::New( \ - "Not a string or buffer"))); \ + return ThrowTypeError("Not a string or buffer"); \ } \ } while (0) #define ASSERT_IS_BUFFER(val) do { \ if (!Buffer::HasInstance(val)) { \ - return ThrowException(Exception::TypeError(String::New( \ - "Not a buffer"))); \ + return ThrowTypeError("Not a buffer"); \ } \ } while (0) @@ -69,7 +67,20 @@ static const int X509_NAME_FLAGS = ASN1_STRFLGS_ESC_CTRL namespace node { namespace crypto { -using namespace v8; +using v8::Array; +using v8::Exception; +using v8::False; +using v8::FunctionCallbackInfo; +using v8::FunctionTemplate; +using v8::HandleScope; +using v8::Integer; +using v8::Local; +using v8::Null; +using v8::Object; +using v8::Persistent; +using v8::String; +using v8::ThrowException; + // Forcibly clear OpenSSL's error stack on return. This stops stale errors // from popping up later in the lifecycle of crypto operations where they @@ -79,24 +90,24 @@ struct ClearErrorOnReturn { ~ClearErrorOnReturn() { ERR_clear_error(); } }; -static Persistent<String> errno_symbol; -static Persistent<String> syscall_symbol; -static Persistent<String> subject_symbol; -static Persistent<String> subjectaltname_symbol; -static Persistent<String> modulus_symbol; -static Persistent<String> exponent_symbol; -static Persistent<String> issuer_symbol; -static Persistent<String> valid_from_symbol; -static Persistent<String> valid_to_symbol; -static Persistent<String> fingerprint_symbol; -static Persistent<String> name_symbol; -static Persistent<String> version_symbol; -static Persistent<String> ext_key_usage_symbol; -static Persistent<String> onhandshakestart_sym; -static Persistent<String> onhandshakedone_sym; -static Persistent<String> onclienthello_sym; -static Persistent<String> onnewsession_sym; -static Persistent<String> sessionid_sym; +static Cached<String> errno_symbol; +static Cached<String> syscall_symbol; +static Cached<String> subject_symbol; +static Cached<String> subjectaltname_symbol; +static Cached<String> modulus_symbol; +static Cached<String> exponent_symbol; +static Cached<String> issuer_symbol; +static Cached<String> valid_from_symbol; +static Cached<String> valid_to_symbol; +static Cached<String> fingerprint_symbol; +static Cached<String> name_symbol; +static Cached<String> version_symbol; +static Cached<String> ext_key_usage_symbol; +static Cached<String> onhandshakestart_sym; +static Cached<String> onhandshakedone_sym; +static Cached<String> onclienthello_sym; +static Cached<String> onnewsession_sym; +static Cached<String> sessionid_sym; static Persistent<FunctionTemplate> secure_context_constructor; @@ -138,21 +149,24 @@ static void crypto_lock_cb(int mode, int n, const char* file, int line) { } -Handle<Value> ThrowCryptoErrorHelper(unsigned long err, bool is_type_error) { +void ThrowCryptoErrorHelper(unsigned long err, bool is_type_error) { HandleScope scope(node_isolate); char errmsg[128]; ERR_error_string_n(err, errmsg, sizeof(errmsg)); - return is_type_error ? ThrowTypeError(errmsg) : ThrowError(errmsg); + if (is_type_error) + ThrowTypeError(errmsg); + else + ThrowError(errmsg); } -Handle<Value> ThrowCryptoError(unsigned long err) { - return ThrowCryptoErrorHelper(err, false); +void ThrowCryptoError(unsigned long err) { + ThrowCryptoErrorHelper(err, false); } -Handle<Value> ThrowCryptoTypeError(unsigned long err) { - return ThrowCryptoErrorHelper(err, true); +void ThrowCryptoTypeError(unsigned long err) { + ThrowCryptoErrorHelper(err, true); } @@ -160,8 +174,7 @@ void SecureContext::Initialize(Handle<Object> target) { HandleScope scope(node_isolate); Local<FunctionTemplate> t = FunctionTemplate::New(SecureContext::New); - secure_context_constructor = Persistent<FunctionTemplate>::New(node_isolate, - t); + secure_context_constructor.Reset(node_isolate, t); t->InstanceTemplate()->SetInternalFieldCount(1); t->SetClassName(String::NewSymbol("SecureContext")); @@ -185,15 +198,14 @@ void SecureContext::Initialize(Handle<Object> target) { } -Handle<Value> SecureContext::New(const Arguments& args) { +void SecureContext::New(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); SecureContext *p = new SecureContext(); p->Wrap(args.This()); - return args.This(); } -Handle<Value> SecureContext::Init(const Arguments& args) { +void SecureContext::Init(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.This()); @@ -207,19 +219,19 @@ Handle<Value> SecureContext::Init(const Arguments& args) { #ifndef OPENSSL_NO_SSL2 method = SSLv2_method(); #else - return ThrowException(Exception::Error(String::New("SSLv2 methods disabled"))); + return ThrowError("SSLv2 methods disabled"); #endif } else if (strcmp(*sslmethod, "SSLv2_server_method") == 0) { #ifndef OPENSSL_NO_SSL2 method = SSLv2_server_method(); #else - return ThrowException(Exception::Error(String::New("SSLv2 methods disabled"))); + return ThrowError("SSLv2 methods disabled"); #endif } else if (strcmp(*sslmethod, "SSLv2_client_method") == 0) { #ifndef OPENSSL_NO_SSL2 method = SSLv2_client_method(); #else - return ThrowException(Exception::Error(String::New("SSLv2 methods disabled"))); + return ThrowError("SSLv2 methods disabled"); #endif } else if (strcmp(*sslmethod, "SSLv3_method") == 0) { method = SSLv3_method(); @@ -240,7 +252,7 @@ Handle<Value> SecureContext::Init(const Arguments& args) { } else if (strcmp(*sslmethod, "TLSv1_client_method") == 0) { method = TLSv1_client_method(); } else { - return ThrowException(Exception::Error(String::New("Unknown method"))); + return ThrowError("Unknown method"); } } @@ -255,7 +267,6 @@ Handle<Value> SecureContext::Init(const Arguments& args) { SSL_CTX_sess_set_new_cb(sc->ctx_, NewSessionCallback); sc->ca_store_ = NULL; - return True(node_isolate); } @@ -297,9 +308,13 @@ int SecureContext::NewSessionCallback(SSL* s, SSL_SESSION* sess) { }; if (onnewsession_sym.IsEmpty()) { - onnewsession_sym = NODE_PSYMBOL("onnewsession"); + onnewsession_sym = String::New("onnewsession"); } - MakeCallback(p->handle_, onnewsession_sym, ARRAY_SIZE(argv), argv); + + MakeCallback(p->handle(node_isolate), + onnewsession_sym, + ARRAY_SIZE(argv), + argv); return 0; } @@ -352,21 +367,21 @@ static X509* LoadX509 (Handle<Value> v) { } -Handle<Value> SecureContext::SetKey(const Arguments& args) { +void SecureContext::SetKey(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.This()); unsigned int len = args.Length(); if (len != 1 && len != 2) { - return ThrowException(Exception::TypeError(String::New("Bad parameter"))); + return ThrowTypeError("Bad parameter"); } if (len == 2 && !args[1]->IsString()) { - return ThrowException(Exception::TypeError(String::New("Bad parameter"))); + return ThrowTypeError("Bad parameter"); } BIO *bio = LoadBIO(args[0]); - if (!bio) return False(node_isolate); + if (!bio) return; String::Utf8Value passphrase(args[1]); @@ -377,8 +392,7 @@ Handle<Value> SecureContext::SetKey(const Arguments& args) { BIO_free_all(bio); unsigned long err = ERR_get_error(); if (!err) { - return ThrowException(Exception::Error( - String::New("PEM_read_bio_PrivateKey"))); + return ThrowError("PEM_read_bio_PrivateKey"); } return ThrowCryptoError(err); } @@ -386,8 +400,6 @@ Handle<Value> SecureContext::SetKey(const Arguments& args) { SSL_CTX_use_PrivateKey(sc->ctx_, key); EVP_PKEY_free(key); BIO_free_all(bio); - - return True(node_isolate); } @@ -457,18 +469,17 @@ end: } -Handle<Value> SecureContext::SetCert(const Arguments& args) { +void SecureContext::SetCert(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.This()); if (args.Length() != 1) { - return ThrowException(Exception::TypeError( - String::New("Bad parameter"))); + return ThrowTypeError("Bad parameter"); } BIO* bio = LoadBIO(args[0]); - if (!bio) return False(node_isolate); + if (!bio) return; int rv = SSL_CTX_use_certificate_chain(sc->ctx_, bio); @@ -477,24 +488,21 @@ Handle<Value> SecureContext::SetCert(const Arguments& args) { if (!rv) { unsigned long err = ERR_get_error(); if (!err) { - return ThrowException(Exception::Error( - String::New("SSL_CTX_use_certificate_chain"))); + return ThrowError("SSL_CTX_use_certificate_chain"); } return ThrowCryptoError(err); } - - return True(node_isolate); } -Handle<Value> SecureContext::AddCACert(const Arguments& args) { +void SecureContext::AddCACert(const FunctionCallbackInfo<Value>& args) { bool newCAStore = false; HandleScope scope(node_isolate); SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.This()); if (args.Length() != 1) { - return ThrowException(Exception::TypeError(String::New("Bad parameter"))); + return ThrowTypeError("Bad parameter"); } if (!sc->ca_store_) { @@ -503,7 +511,7 @@ Handle<Value> SecureContext::AddCACert(const Arguments& args) { } X509* x509 = LoadX509(args[0]); - if (!x509) return False(node_isolate); + if (!x509) return; X509_STORE_add_cert(sc->ca_store_, x509); SSL_CTX_add_client_CA(sc->ctx_, x509); @@ -513,47 +521,41 @@ Handle<Value> SecureContext::AddCACert(const Arguments& args) { if (newCAStore) { SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_); } - - return True(node_isolate); } -Handle<Value> SecureContext::AddCRL(const Arguments& args) { +void SecureContext::AddCRL(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.This()); if (args.Length() != 1) { - return ThrowException(Exception::TypeError(String::New("Bad parameter"))); + return ThrowTypeError("Bad parameter"); } ClearErrorOnReturn clear_error_on_return; (void) &clear_error_on_return; // Silence compiler warning. BIO *bio = LoadBIO(args[0]); - if (!bio) return False(node_isolate); + if (!bio) return; X509_CRL *x509 = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL); if (x509 == NULL) { BIO_free_all(bio); - return False(node_isolate); + return; } X509_STORE_add_crl(sc->ca_store_, x509); - X509_STORE_set_flags(sc->ca_store_, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); - BIO_free_all(bio); X509_CRL_free(x509); - - return True(node_isolate); } -Handle<Value> SecureContext::AddRootCerts(const Arguments& args) { +void SecureContext::AddRootCerts(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.This()); @@ -568,14 +570,14 @@ Handle<Value> SecureContext::AddRootCerts(const Arguments& args) { if (!BIO_write(bp, root_certs[i], strlen(root_certs[i]))) { BIO_free_all(bp); - return False(node_isolate); + return; } X509 *x509 = PEM_read_bio_X509(bp, NULL, NULL, NULL); if (x509 == NULL) { BIO_free_all(bp); - return False(node_isolate); + return; } X509_STORE_add_cert(root_cert_store, x509); @@ -587,47 +589,44 @@ Handle<Value> SecureContext::AddRootCerts(const Arguments& args) { sc->ca_store_ = root_cert_store; SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_); - - return True(node_isolate); } -Handle<Value> SecureContext::SetCiphers(const Arguments& args) { +void SecureContext::SetCiphers(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.This()); if (args.Length() != 1 || !args[0]->IsString()) { - return ThrowException(Exception::TypeError(String::New("Bad parameter"))); + return ThrowTypeError("Bad parameter"); } String::Utf8Value ciphers(args[0]); SSL_CTX_set_cipher_list(sc->ctx_, *ciphers); - - return True(node_isolate); } -Handle<Value> SecureContext::SetOptions(const Arguments& args) { + +void SecureContext::SetOptions(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.This()); if (args.Length() != 1 || !args[0]->IntegerValue()) { - return ThrowException(Exception::TypeError(String::New("Bad parameter"))); + return ThrowTypeError("Bad parameter"); } SSL_CTX_set_options(sc->ctx_, args[0]->IntegerValue()); - - return True(node_isolate); } -Handle<Value> SecureContext::SetSessionIdContext(const Arguments& args) { + +void SecureContext::SetSessionIdContext( + const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.This()); if (args.Length() != 1 || !args[0]->IsString()) { - return ThrowException(Exception::TypeError(String::New("Bad parameter"))); + return ThrowTypeError("Bad parameter"); } String::Utf8Value sessionIdContext(args[0]); @@ -635,25 +634,28 @@ Handle<Value> SecureContext::SetSessionIdContext(const Arguments& args) { unsigned int sid_ctx_len = sessionIdContext.length(); int r = SSL_CTX_set_session_id_context(sc->ctx_, sid_ctx, sid_ctx_len); - if (r != 1) { - Local<String> message; - BIO* bio; - BUF_MEM* mem; - if ((bio = BIO_new(BIO_s_mem()))) { - ERR_print_errors(bio); - BIO_get_mem_ptr(bio, &mem); - message = String::New(mem->data, mem->length); - BIO_free_all(bio); - } else { - message = String::New("SSL_CTX_set_session_id_context error"); - } - return ThrowException(Exception::TypeError(message)); + if (r == 1) return; + + BIO* bio; + BUF_MEM* mem; + Local<String> message; + + bio = BIO_new(BIO_s_mem()); + if (bio == NULL) { + message = String::New("SSL_CTX_set_session_id_context error"); + } + else { + ERR_print_errors(bio); + BIO_get_mem_ptr(bio, &mem); + message = String::New(mem->data, mem->length); + BIO_free_all(bio); } - return True(node_isolate); + ThrowException(Exception::TypeError(message)); } -Handle<Value> SecureContext::SetSessionTimeout(const Arguments& args) { + +void SecureContext::SetSessionTimeout(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.This()); @@ -664,19 +666,18 @@ Handle<Value> SecureContext::SetSessionTimeout(const Arguments& args) { int32_t sessionTimeout = args[0]->Int32Value(); SSL_CTX_set_timeout(sc->ctx_, sessionTimeout); - - return True(node_isolate); } -Handle<Value> SecureContext::Close(const Arguments& args) { + +void SecureContext::Close(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.This()); sc->FreeCTXMem(); - return False(node_isolate); } + //Takes .pfx or .p12 and password in string or buffer format -Handle<Value> SecureContext::LoadPKCS12(const Arguments& args) { +void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); BIO* in = NULL; @@ -690,14 +691,12 @@ Handle<Value> SecureContext::LoadPKCS12(const Arguments& args) { SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.This()); if (args.Length() < 1) { - return ThrowException(Exception::TypeError( - String::New("Bad parameter"))); + return ThrowTypeError("Bad parameter"); } in = LoadBIO(args[0]); if (in == NULL) { - return ThrowException(Exception::Error( - String::New("Unable to load BIO"))); + return ThrowError("Unable to load BIO"); } if (args.Length() >= 2) { @@ -706,8 +705,7 @@ Handle<Value> SecureContext::LoadPKCS12(const Arguments& args) { int passlen = Buffer::Length(args[1]); if (passlen < 0) { BIO_free_all(in); - return ThrowException(Exception::TypeError( - String::New("Bad password"))); + return ThrowTypeError("Bad password"); } pass = new char[passlen + 1]; int pass_written = DecodeWrite(pass, passlen, args[1], BINARY); @@ -747,10 +745,8 @@ Handle<Value> SecureContext::LoadPKCS12(const Arguments& args) { if (!ret) { unsigned long err = ERR_get_error(); const char* str = ERR_reason_error_string(err); - return ThrowException(Exception::Error(String::New(str))); + return ThrowError(str); } - - return True(node_isolate); } @@ -863,10 +859,10 @@ size_t ClientHelloParser::Write(const uint8_t* data, size_t len) { // Parse frame, call javascript handler and // move parser into the paused state if (onclienthello_sym.IsEmpty()) { - onclienthello_sym = NODE_PSYMBOL("onclienthello"); + onclienthello_sym = String::New("onclienthello"); } if (sessionid_sym.IsEmpty()) { - sessionid_sym = NODE_PSYMBOL("sessionId"); + sessionid_sym = String::New("sessionId"); } state_ = kPaused; @@ -876,7 +872,10 @@ size_t ClientHelloParser::Write(const uint8_t* data, size_t len) { session_size)); argv[0] = hello; - MakeCallback(conn_->handle_, onclienthello_sym, 1, argv); + MakeCallback(conn_->handle(node_isolate), + onclienthello_sym, + ARRAY_SIZE(argv), + argv); break; case kEnded: default: @@ -920,12 +919,12 @@ int Connection::HandleBIOError(BIO *bio, const char* func, int rv) { return 0; } else { - static char ssl_error_buf[512]; + static char ssl_error_buf[512]; ERR_error_string_n(rv, ssl_error_buf, sizeof(ssl_error_buf)); HandleScope scope(node_isolate); Local<Value> e = Exception::Error(String::New(ssl_error_buf)); - handle_->Set(String::New("error"), e); + handle(node_isolate)->Set(String::New("error"), e); DEBUG_PRINT("[%p] BIO: %s failed: (%d) %s\n", ssl_, func, rv, ssl_error_buf); @@ -960,8 +959,8 @@ int Connection::HandleSSLError(const char* func, return 0; } else if (err == SSL_ERROR_ZERO_RETURN) { - handle_->Set(String::New("error"), - Exception::Error(String::New("ZERO_RETURN"))); + handle(node_isolate)->Set(String::New("error"), + Exception::Error(String::New("ZERO_RETURN"))); return rv; } else if ((err == SSL_ERROR_SYSCALL) && (ss == kIgnoreSyscall)) { @@ -983,7 +982,7 @@ int Connection::HandleSSLError(const char* func, ERR_print_errors(bio); BIO_get_mem_ptr(bio, &mem); Local<Value> e = Exception::Error(String::New(mem->data, mem->length)); - handle_->Set(String::New("error"), e); + handle(node_isolate)->Set(String::New("error"), e); BIO_free_all(bio); } @@ -999,7 +998,8 @@ void Connection::ClearError() { HandleScope scope(node_isolate); // We should clear the error in JS-land - assert(handle_->Get(String::New("error"))->BooleanValue() == false); + assert( + handle(node_isolate)->Get(String::New("error"))->BooleanValue() == false); #endif // NDEBUG } @@ -1010,11 +1010,12 @@ void Connection::SetShutdownFlags() { int flags = SSL_get_shutdown(ssl_); if (flags & SSL_SENT_SHUTDOWN) { - handle_->Set(String::New("sentShutdown"), True(node_isolate)); + handle(node_isolate)->Set(String::New("sentShutdown"), True(node_isolate)); } if (flags & SSL_RECEIVED_SHUTDOWN) { - handle_->Set(String::New("receivedShutdown"), True(node_isolate)); + handle(node_isolate)->Set(String::New("receivedShutdown"), + True(node_isolate)); } } @@ -1133,9 +1134,7 @@ int Connection::SelectNextProtoCallback_(SSL *s, Connection *p = static_cast<Connection*> SSL_get_app_data(s); // Release old protocol handler if present - if (!p->selectedNPNProto_.IsEmpty()) { - p->selectedNPNProto_.Dispose(node_isolate); - } + p->selectedNPNProto_.Dispose(); if (p->npnProtos_.IsEmpty()) { // We should at least select one protocol @@ -1144,8 +1143,7 @@ int Connection::SelectNextProtoCallback_(SSL *s, *outlen = 8; // set status unsupported - p->selectedNPNProto_ = Persistent<Value>::New(node_isolate, - False(node_isolate)); + p->selectedNPNProto_.Reset(node_isolate, False(node_isolate)); return SSL_TLSEXT_ERR_OK; } @@ -1158,17 +1156,15 @@ int Connection::SelectNextProtoCallback_(SSL *s, switch (status) { case OPENSSL_NPN_UNSUPPORTED: - p->selectedNPNProto_ = Persistent<Value>::New(node_isolate, - Null(node_isolate)); + p->selectedNPNProto_.Reset(node_isolate, Null(node_isolate)); break; case OPENSSL_NPN_NEGOTIATED: - p->selectedNPNProto_ = Persistent<Value>::New(node_isolate, String::New( - reinterpret_cast<const char*>(*out), *outlen - )); + p->selectedNPNProto_.Reset( + node_isolate, + String::New(reinterpret_cast<const char*>(*out), *outlen)); break; case OPENSSL_NPN_NO_OVERLAP: - p->selectedNPNProto_ = Persistent<Value>::New(node_isolate, - False(node_isolate)); + p->selectedNPNProto_.Reset(node_isolate, False(node_isolate)); break; default: break; @@ -1187,33 +1183,20 @@ int Connection::SelectSNIContextCallback_(SSL *s, int *ad, void* arg) { const char* servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name); if (servername) { - if (!p->servername_.IsEmpty()) { - p->servername_.Dispose(node_isolate); - } - p->servername_ = Persistent<String>::New(node_isolate, - String::New(servername)); + p->servername_.Reset(node_isolate, String::New(servername)); // Call the SNI callback and use its return value as context if (!p->sniObject_.IsEmpty()) { - if (!p->sniContext_.IsEmpty()) { - p->sniContext_.Dispose(node_isolate); - } - - // Get callback init args - Local<Value> argv[1] = {*p->servername_}; + p->sniContext_.Dispose(); - // Call it - Local<Value> ret = Local<Value>::New(node_isolate, - MakeCallback(p->sniObject_, - "onselect", - ARRAY_SIZE(argv), - argv)); + Local<Value> arg = Local<String>::New(node_isolate, p->servername_); + Local<Value> ret = Local<Value>::New( + node_isolate, MakeCallback(p->sniObject_, "onselect", 1, &arg)); // If ret is SecureContext - if (secure_context_constructor->HasInstance(ret)) { - p->sniContext_ = Persistent<Value>::New(node_isolate, ret); - SecureContext *sc = ObjectWrap::Unwrap<SecureContext>( - Local<Object>::Cast(ret)); + if (HasInstance(secure_context_constructor, ret)) { + p->sniContext_.Reset(node_isolate, ret); + SecureContext* sc = ObjectWrap::Unwrap<SecureContext>(ret.As<Object>()); SSL_set_SSL_CTX(s, sc->ctx_); } else { return SSL_TLSEXT_ERR_NOACK; @@ -1225,15 +1208,14 @@ int Connection::SelectSNIContextCallback_(SSL *s, int *ad, void* arg) { } #endif -Handle<Value> Connection::New(const Arguments& args) { +void Connection::New(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Connection *p = new Connection(); p->Wrap(args.This()); if (args.Length() < 1 || !args[0]->IsObject()) { - return ThrowException(Exception::Error(String::New( - "First argument must be a crypto module Credentials"))); + return ThrowError("First argument must be a crypto module Credentials"); } SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args[0]->ToObject()); @@ -1305,8 +1287,6 @@ Handle<Value> Connection::New(const Arguments& args) { } else { SSL_set_connect_state(p->ssl_); } - - return args.This(); } @@ -1318,34 +1298,32 @@ void Connection::SSLInfoCallback(const SSL *ssl_, int where, int ret) { HandleScope scope(node_isolate); Connection* c = static_cast<Connection*>(SSL_get_app_data(ssl)); if (onhandshakestart_sym.IsEmpty()) { - onhandshakestart_sym = NODE_PSYMBOL("onhandshakestart"); + onhandshakestart_sym = String::New("onhandshakestart"); } - MakeCallback(c->handle_, onhandshakestart_sym, 0, NULL); + MakeCallback(c->handle(node_isolate), onhandshakestart_sym, 0, NULL); } if (where & SSL_CB_HANDSHAKE_DONE) { HandleScope scope(node_isolate); Connection* c = static_cast<Connection*>(SSL_get_app_data(ssl)); if (onhandshakedone_sym.IsEmpty()) { - onhandshakedone_sym = NODE_PSYMBOL("onhandshakedone"); + onhandshakedone_sym = String::New("onhandshakedone"); } - MakeCallback(c->handle_, onhandshakedone_sym, 0, NULL); + MakeCallback(c->handle(node_isolate), onhandshakedone_sym, 0, NULL); } } -Handle<Value> Connection::EncIn(const Arguments& args) { +void Connection::EncIn(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Connection *ss = Connection::Unwrap(args); if (args.Length() < 3) { - return ThrowException(Exception::TypeError( - String::New("Takes 3 parameters"))); + return ThrowTypeError("Takes 3 parameters"); } if (!Buffer::HasInstance(args[0])) { - return ThrowException(Exception::TypeError( - String::New("Second argument should be a buffer"))); + return ThrowTypeError("Second argument should be a buffer"); } char* buffer_data = Buffer::Data(args[0]); @@ -1354,8 +1332,7 @@ Handle<Value> Connection::EncIn(const Arguments& args) { size_t off = args[1]->Int32Value(); size_t len = args[2]->Int32Value(); if (off + len > buffer_length) { - return ThrowException(Exception::Error( - String::New("off + len > buffer.length"))); + return ThrowError("off + len > buffer.length"); } int bytes_written; @@ -1370,23 +1347,21 @@ Handle<Value> Connection::EncIn(const Arguments& args) { ss->SetShutdownFlags(); } - return scope.Close(Integer::New(bytes_written, node_isolate)); + args.GetReturnValue().Set(bytes_written); } -Handle<Value> Connection::ClearOut(const Arguments& args) { +void Connection::ClearOut(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Connection *ss = Connection::Unwrap(args); if (args.Length() < 3) { - return ThrowException(Exception::TypeError( - String::New("Takes 3 parameters"))); + return ThrowTypeError("Takes 3 parameters"); } if (!Buffer::HasInstance(args[0])) { - return ThrowException(Exception::TypeError( - String::New("Second argument should be a buffer"))); + return ThrowTypeError("Second argument should be a buffer"); } char* buffer_data = Buffer::Data(args[0]); @@ -1395,8 +1370,7 @@ Handle<Value> Connection::ClearOut(const Arguments& args) { size_t off = args[1]->Int32Value(); size_t len = args[2]->Int32Value(); if (off + len > buffer_length) { - return ThrowException(Exception::Error( - String::New("off + len > buffer.length"))); + return ThrowError("off + len > buffer.length"); } if (!SSL_is_init_finished(ss->ssl_)) { @@ -1416,7 +1390,9 @@ Handle<Value> Connection::ClearOut(const Arguments& args) { kSyscallError); } - if (rv < 0) return scope.Close(Integer::New(rv, node_isolate)); + if (rv < 0) { + return args.GetReturnValue().Set(rv); + } } int bytes_read = SSL_read(ss->ssl_, buffer_data + off, len); @@ -1426,43 +1402,37 @@ Handle<Value> Connection::ClearOut(const Arguments& args) { kSyscallError); ss->SetShutdownFlags(); - return scope.Close(Integer::New(bytes_read, node_isolate)); + args.GetReturnValue().Set(bytes_read); } -Handle<Value> Connection::ClearPending(const Arguments& args) { +void Connection::ClearPending(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); - Connection *ss = Connection::Unwrap(args); - int bytes_pending = BIO_pending(ss->bio_read_); - return scope.Close(Integer::New(bytes_pending, node_isolate)); + args.GetReturnValue().Set(bytes_pending); } -Handle<Value> Connection::EncPending(const Arguments& args) { +void Connection::EncPending(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); - Connection *ss = Connection::Unwrap(args); - int bytes_pending = BIO_pending(ss->bio_write_); - return scope.Close(Integer::New(bytes_pending, node_isolate)); + args.GetReturnValue().Set(bytes_pending); } -Handle<Value> Connection::EncOut(const Arguments& args) { +void Connection::EncOut(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Connection *ss = Connection::Unwrap(args); if (args.Length() < 3) { - return ThrowException(Exception::TypeError( - String::New("Takes 3 parameters"))); + return ThrowTypeError("Takes 3 parameters"); } if (!Buffer::HasInstance(args[0])) { - return ThrowException(Exception::TypeError( - String::New("Second argument should be a buffer"))); + return ThrowTypeError("Second argument should be a buffer"); } char* buffer_data = Buffer::Data(args[0]); @@ -1471,8 +1441,7 @@ Handle<Value> Connection::EncOut(const Arguments& args) { size_t off = args[1]->Int32Value(); size_t len = args[2]->Int32Value(); if (off + len > buffer_length) { - return ThrowException(Exception::Error( - String::New("off + len > buffer.length"))); + return ThrowError("off + len > buffer.length"); } int bytes_read = BIO_read(ss->bio_write_, buffer_data + off, len); @@ -1480,23 +1449,21 @@ Handle<Value> Connection::EncOut(const Arguments& args) { ss->HandleBIOError(ss->bio_write_, "BIO_read:EncOut", bytes_read); ss->SetShutdownFlags(); - return scope.Close(Integer::New(bytes_read, node_isolate)); + args.GetReturnValue().Set(bytes_read); } -Handle<Value> Connection::ClearIn(const Arguments& args) { +void Connection::ClearIn(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Connection *ss = Connection::Unwrap(args); if (args.Length() < 3) { - return ThrowException(Exception::TypeError( - String::New("Takes 3 parameters"))); + return ThrowTypeError("Takes 3 parameters"); } if (!Buffer::HasInstance(args[0])) { - return ThrowException(Exception::TypeError( - String::New("Second argument should be a buffer"))); + return ThrowTypeError("Second argument should be a buffer"); } char* buffer_data = Buffer::Data(args[0]); @@ -1505,8 +1472,7 @@ Handle<Value> Connection::ClearIn(const Arguments& args) { size_t off = args[1]->Int32Value(); size_t len = args[2]->Int32Value(); if (off + len > buffer_length) { - return ThrowException(Exception::Error( - String::New("off + len > buffer.length"))); + return ThrowError("off + len > buffer.length"); } if (!SSL_is_init_finished(ss->ssl_)) { @@ -1525,7 +1491,9 @@ Handle<Value> Connection::ClearIn(const Arguments& args) { kSyscallError); } - if (rv < 0) return scope.Close(Integer::New(rv, node_isolate)); + if (rv < 0) { + return args.GetReturnValue().Set(rv); + } } int bytes_written = SSL_write(ss->ssl_, buffer_data + off, len); @@ -1536,16 +1504,16 @@ Handle<Value> Connection::ClearIn(const Arguments& args) { kSyscallError); ss->SetShutdownFlags(); - return scope.Close(Integer::New(bytes_written, node_isolate)); + args.GetReturnValue().Set(bytes_written); } -Handle<Value> Connection::GetPeerCertificate(const Arguments& args) { +void Connection::GetPeerCertificate(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Connection *ss = Connection::Unwrap(args); - if (ss->ssl_ == NULL) return Undefined(node_isolate); + if (ss->ssl_ == NULL) return; Local<Object> info = Object::New(); X509* peer_cert = SSL_get_peer_certificate(ss->ssl_); if (peer_cert != NULL) { @@ -1656,51 +1624,47 @@ Handle<Value> Connection::GetPeerCertificate(const Arguments& args) { X509_free(peer_cert); } - return scope.Close(info); + + args.GetReturnValue().Set(info); } -Handle<Value> Connection::GetSession(const Arguments& args) { + +void Connection::GetSession(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Connection *ss = Connection::Unwrap(args); - if (ss->ssl_ == NULL) return Undefined(node_isolate); + if (ss->ssl_ == NULL) return; SSL_SESSION* sess = SSL_get_session(ss->ssl_); - if (!sess) return Undefined(node_isolate); + if (!sess) return; int slen = i2d_SSL_SESSION(sess, NULL); assert(slen > 0); - if (slen > 0) { - unsigned char* sbuf = new unsigned char[slen]; - unsigned char* p = sbuf; - i2d_SSL_SESSION(sess, &p); - Local<Value> s = Encode(sbuf, slen, BINARY); - delete[] sbuf; - return scope.Close(s); - } - - return Null(node_isolate); + unsigned char* sbuf = new unsigned char[slen]; + unsigned char* p = sbuf; + i2d_SSL_SESSION(sess, &p); + args.GetReturnValue().Set(Encode(sbuf, slen, BINARY)); + delete[] sbuf; } -Handle<Value> Connection::SetSession(const Arguments& args) { + +void Connection::SetSession(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Connection *ss = Connection::Unwrap(args); if (args.Length() < 1 || (!args[0]->IsString() && !Buffer::HasInstance(args[0]))) { - Local<Value> exception = Exception::TypeError(String::New("Bad argument")); - return ThrowException(exception); + return ThrowTypeError("Bad argument"); } ASSERT_IS_BUFFER(args[0]); ssize_t slen = Buffer::Length(args[0]); if (slen < 0) { - Local<Value> exception = Exception::TypeError(String::New("Bad argument")); - return ThrowException(exception); + return ThrowTypeError("Bad argument"); } char* sbuf = new char[slen]; @@ -1713,21 +1677,18 @@ Handle<Value> Connection::SetSession(const Arguments& args) { delete [] sbuf; - if (!sess) - return Undefined(node_isolate); + if (!sess) return; int r = SSL_set_session(ss->ssl_, sess); SSL_SESSION_free(sess); if (!r) { - Local<String> eStr = String::New("SSL_set_session error"); - return ThrowException(Exception::Error(eStr)); + return ThrowError("SSL_set_session error"); } - - return True(node_isolate); } -Handle<Value> Connection::LoadSession(const Arguments& args) { + +void Connection::LoadSession(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Connection *ss = Connection::Unwrap(args); @@ -1747,30 +1708,24 @@ Handle<Value> Connection::LoadSession(const Arguments& args) { } ss->hello_parser_.Finish(); - - return True(node_isolate); } -Handle<Value> Connection::IsSessionReused(const Arguments& args) { - HandleScope scope(node_isolate); +void Connection::IsSessionReused(const FunctionCallbackInfo<Value>& args) { + HandleScope scope(node_isolate); Connection *ss = Connection::Unwrap(args); - - if (ss->ssl_ == NULL || SSL_session_reused(ss->ssl_) == false) { - return False(node_isolate); - } - - return True(node_isolate); + bool yes = ss->ssl_ && SSL_session_reused(ss->ssl_); + args.GetReturnValue().Set(yes); } -Handle<Value> Connection::Start(const Arguments& args) { +void Connection::Start(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Connection *ss = Connection::Unwrap(args); + int rv = 0; if (!SSL_is_init_finished(ss->ssl_)) { - int rv; if (ss->is_server_) { rv = SSL_accept(ss->ssl_); ss->HandleSSLError("SSL_accept:Start", rv, kZeroIsAnError, kSyscallError); @@ -1781,62 +1736,51 @@ Handle<Value> Connection::Start(const Arguments& args) { kZeroIsAnError, kSyscallError); } - - return scope.Close(Integer::New(rv, node_isolate)); } - - return scope.Close(Integer::New(0, node_isolate)); + args.GetReturnValue().Set(rv); } -Handle<Value> Connection::Shutdown(const Arguments& args) { +void Connection::Shutdown(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Connection *ss = Connection::Unwrap(args); - if (ss->ssl_ == NULL) return False(node_isolate); + if (ss->ssl_ == NULL) { + return args.GetReturnValue().Set(false); + } + int rv = SSL_shutdown(ss->ssl_); ss->HandleSSLError("SSL_shutdown", rv, kZeroIsNotAnError, kIgnoreSyscall); ss->SetShutdownFlags(); - - return scope.Close(Integer::New(rv, node_isolate)); + args.GetReturnValue().Set(rv); } -Handle<Value> Connection::ReceivedShutdown(const Arguments& args) { +void Connection::ReceivedShutdown(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); - Connection *ss = Connection::Unwrap(args); - - if (ss->ssl_ == NULL) return False(node_isolate); - int r = SSL_get_shutdown(ss->ssl_); - - if (r & SSL_RECEIVED_SHUTDOWN) return True(node_isolate); - - return False(node_isolate); + bool yes = ss->ssl_ && SSL_get_shutdown(ss->ssl_) == SSL_RECEIVED_SHUTDOWN; + args.GetReturnValue().Set(yes); } -Handle<Value> Connection::IsInitFinished(const Arguments& args) { +void Connection::IsInitFinished(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); - Connection *ss = Connection::Unwrap(args); - - if (ss->ssl_ == NULL || SSL_is_init_finished(ss->ssl_) == false) { - return False(node_isolate); - } - - return True(node_isolate); + bool yes = ss->ssl_ && SSL_is_init_finished(ss->ssl_); + args.GetReturnValue().Set(yes); } -Handle<Value> Connection::VerifyError(const Arguments& args) { +void Connection::VerifyError(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Connection *ss = Connection::Unwrap(args); - if (ss->ssl_ == NULL) return Null(node_isolate); - + if (ss->ssl_ == NULL) { + return args.GetReturnValue().SetNull(); + } // XXX Do this check in JS land? X509* peer_cert = SSL_get_peer_certificate(ss->ssl_); @@ -1844,8 +1788,8 @@ Handle<Value> Connection::VerifyError(const Arguments& args) { // We requested a certificate and they did not send us one. // Definitely an error. // XXX is this the right error message? - return scope.Close(Exception::Error( - String::New("UNABLE_TO_GET_ISSUER_CERT"))); + return args.GetReturnValue().Set( + Exception::Error(String::New("UNABLE_TO_GET_ISSUER_CERT"))); } X509_free(peer_cert); @@ -1856,7 +1800,7 @@ Handle<Value> Connection::VerifyError(const Arguments& args) { switch (x509_verify_error) { case X509_V_OK: - return Null(node_isolate); + break; case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: s = String::New("UNABLE_TO_GET_ISSUER_CERT"); @@ -1971,29 +1915,33 @@ Handle<Value> Connection::VerifyError(const Arguments& args) { break; } - return scope.Close(Exception::Error(s)); + if (s.IsEmpty()) + args.GetReturnValue().SetNull(); + else + args.GetReturnValue().Set(Exception::Error(s)); } -Handle<Value> Connection::GetCurrentCipher(const Arguments& args) { +void Connection::GetCurrentCipher(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Connection *ss = Connection::Unwrap(args); OPENSSL_CONST SSL_CIPHER *c; - if ( ss->ssl_ == NULL ) return Undefined(node_isolate); + if (ss->ssl_ == NULL) return; c = SSL_get_current_cipher(ss->ssl_); - if ( c == NULL ) return Undefined(node_isolate); + if (c == NULL) return; Local<Object> info = Object::New(); const char* cipher_name = SSL_CIPHER_get_name(c); info->Set(name_symbol, String::New(cipher_name)); const char* cipher_version = SSL_CIPHER_get_version(c); info->Set(version_symbol, String::New(cipher_version)); - return scope.Close(info); + args.GetReturnValue().Set(info); } -Handle<Value> Connection::Close(const Arguments& args) { + +void Connection::Close(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Connection *ss = Connection::Unwrap(args); @@ -2002,11 +1950,11 @@ Handle<Value> Connection::Close(const Arguments& args) { SSL_free(ss->ssl_); ss->ssl_ = NULL; } - return True(node_isolate); } + #ifdef OPENSSL_NPN_NEGOTIATED -Handle<Value> Connection::GetNegotiatedProto(const Arguments& args) { +void Connection::GetNegotiatedProto(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Connection *ss = Connection::Unwrap(args); @@ -2018,67 +1966,57 @@ Handle<Value> Connection::GetNegotiatedProto(const Arguments& args) { SSL_get0_next_proto_negotiated(ss->ssl_, &npn_proto, &npn_proto_len); if (!npn_proto) { - return False(node_isolate); + return args.GetReturnValue().Set(false); } - return scope.Close(String::New(reinterpret_cast<const char*>(npn_proto), - npn_proto_len)); + args.GetReturnValue().Set( + String::New(reinterpret_cast<const char*>(npn_proto), npn_proto_len)); } else { - return ss->selectedNPNProto_; + args.GetReturnValue().Set(ss->selectedNPNProto_); } } -Handle<Value> Connection::SetNPNProtocols(const Arguments& args) { + +void Connection::SetNPNProtocols(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Connection *ss = Connection::Unwrap(args); if (args.Length() < 1 || !Buffer::HasInstance(args[0])) { - return ThrowException(Exception::Error(String::New( - "Must give a Buffer as first argument"))); + return ThrowError("Must give a Buffer as first argument"); } - // Release old handle - if (!ss->npnProtos_.IsEmpty()) { - ss->npnProtos_.Dispose(node_isolate); - } - ss->npnProtos_ = Persistent<Object>::New(node_isolate, args[0]->ToObject()); - - return True(node_isolate); -}; + ss->npnProtos_.Reset(node_isolate, args[0].As<Object>()); +} #endif + #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB -Handle<Value> Connection::GetServername(const Arguments& args) { +void Connection::GetServername(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Connection *ss = Connection::Unwrap(args); if (ss->is_server_ && !ss->servername_.IsEmpty()) { - return ss->servername_; + args.GetReturnValue().Set(ss->servername_); } else { - return False(node_isolate); + args.GetReturnValue().Set(false); } } -Handle<Value> Connection::SetSNICallback(const Arguments& args) { + +void Connection::SetSNICallback(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Connection *ss = Connection::Unwrap(args); if (args.Length() < 1 || !args[0]->IsFunction()) { - return ThrowException(Exception::Error(String::New( - "Must give a Function as first argument"))); + return ThrowError("Must give a Function as first argument"); } - // Release old handle - if (!ss->sniObject_.IsEmpty()) { - ss->sniObject_.Dispose(node_isolate); - } - ss->sniObject_ = Persistent<Object>::New(node_isolate, Object::New()); - ss->sniObject_->Set(String::New("onselect"), args[0]); - - return True(node_isolate); + Local<Object> obj = Object::New(); + obj->Set(String::New("onselect"), args[0]); + ss->sniObject_.Reset(node_isolate, obj); } #endif @@ -2100,17 +2038,15 @@ void CipherBase::Initialize(Handle<Object> target) { } -Handle<Value> CipherBase::New(const Arguments& args) { +void CipherBase::New(const FunctionCallbackInfo<Value>& args) { + assert(args.IsConstructCall() == true); HandleScope scope(node_isolate); - CipherBase* cipher = new CipherBase(args[0]->IsTrue() ? kCipher : kDecipher); cipher->Wrap(args.This()); - return args.This(); } -Handle<Value> CipherBase::Init(char* cipher_type, - char* key_buf, - int key_buf_len) { + +void CipherBase::Init(char* cipher_type, char* key_buf, int key_buf_len) { HandleScope scope(node_isolate); assert(cipher_ == NULL); @@ -2145,11 +2081,10 @@ Handle<Value> CipherBase::Init(char* cipher_type, reinterpret_cast<unsigned char*>(iv), kind_ == kCipher); initialised_ = true; - return Null(node_isolate); } -Handle<Value> CipherBase::Init(const Arguments& args) { +void CipherBase::Init(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); CipherBase* cipher = ObjectWrap::Unwrap<CipherBase>(args.This()); @@ -2162,23 +2097,15 @@ Handle<Value> CipherBase::Init(const Arguments& args) { String::Utf8Value cipher_type(args[0]); char* key_buf = Buffer::Data(args[1]); ssize_t key_buf_len = Buffer::Length(args[1]); - - Handle<Value> ret = cipher->Init(*cipher_type, key_buf, key_buf_len); - - if (ret->IsNull()) { - return args.This(); - } else { - // Exception - return scope.Close(ret); - } + cipher->Init(*cipher_type, key_buf, key_buf_len); } -Handle<Value> CipherBase::InitIv(char* cipher_type, - char* key, - int key_len, - char* iv, - int iv_len) { +void CipherBase::InitIv(char* cipher_type, + char* key, + int key_len, + char* iv, + int iv_len) { HandleScope scope(node_isolate); cipher_ = EVP_get_cipherbyname(cipher_type); @@ -2206,11 +2133,10 @@ Handle<Value> CipherBase::InitIv(char* cipher_type, reinterpret_cast<unsigned char*>(iv), kind_ == kCipher); initialised_ = true; - return Null(node_isolate); } -Handle<Value> CipherBase::InitIv(const Arguments& args) { +void CipherBase::InitIv(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); CipherBase* cipher = ObjectWrap::Unwrap<CipherBase>(args.This()); @@ -2227,19 +2153,7 @@ Handle<Value> CipherBase::InitIv(const Arguments& args) { char* key_buf = Buffer::Data(args[1]); ssize_t iv_len = Buffer::Length(args[2]); char* iv_buf = Buffer::Data(args[2]); - - Handle<Value> ret = cipher->InitIv(*cipher_type, - key_buf, - key_len, - iv_buf, - iv_len); - - if (ret->IsNull()) { - return args.This(); - } else { - // Exception - return scope.Close(ret); - } + cipher->InitIv(*cipher_type, key_buf, key_len, iv_buf, iv_len); } @@ -2258,7 +2172,7 @@ bool CipherBase::Update(char* data, } -Handle<Value> CipherBase::Update(const Arguments& args) { +void CipherBase::Update(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); CipherBase* cipher = ObjectWrap::Unwrap<CipherBase>(args.This()); @@ -2289,10 +2203,9 @@ Handle<Value> CipherBase::Update(const Arguments& args) { } Local<Object> buf = Buffer::New(reinterpret_cast<char*>(out), out_len); - if (out) delete[] out; - return scope.Close(buf); + args.GetReturnValue().Set(buf); } @@ -2302,14 +2215,10 @@ bool CipherBase::SetAutoPadding(bool auto_padding) { } -Handle<Value> CipherBase::SetAutoPadding(const Arguments& args) { +void CipherBase::SetAutoPadding(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); - CipherBase* cipher = ObjectWrap::Unwrap<CipherBase>(args.This()); - cipher->SetAutoPadding(args.Length() < 1 || args[0]->BooleanValue()); - - return Undefined(node_isolate); } @@ -2325,7 +2234,7 @@ bool CipherBase::Final(unsigned char** out, int *out_len) { } -Handle<Value> CipherBase::Final(const Arguments& args) { +void CipherBase::Final(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); CipherBase* cipher = ObjectWrap::Unwrap<CipherBase>(args.This()); @@ -2343,7 +2252,8 @@ Handle<Value> CipherBase::Final(const Arguments& args) { if (!r) return ThrowCryptoTypeError(ERR_get_error()); } - return scope.Close(Buffer::New(reinterpret_cast<char*>(out_value), out_len)); + args.GetReturnValue().Set( + Buffer::New(reinterpret_cast<char*>(out_value), out_len)); } @@ -2362,16 +2272,14 @@ void Hmac::Initialize(v8::Handle<v8::Object> target) { } -Handle<Value> Hmac::New(const Arguments& args) { +void Hmac::New(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); - Hmac* hmac = new Hmac(); hmac->Wrap(args.This()); - return args.This(); } -Handle<Value> Hmac::HmacInit(char* hashType, char* key, int key_len) { +void Hmac::HmacInit(char* hashType, char* key, int key_len) { HandleScope scope(node_isolate); assert(md_ == NULL); @@ -2386,12 +2294,10 @@ Handle<Value> Hmac::HmacInit(char* hashType, char* key, int key_len) { HMAC_Init(&ctx_, key, key_len, md_); } initialised_ = true; - - return Null(node_isolate); } -Handle<Value> Hmac::HmacInit(const Arguments& args) { +void Hmac::HmacInit(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Hmac* hmac = ObjectWrap::Unwrap<Hmac>(args.This()); @@ -2400,22 +2306,13 @@ Handle<Value> Hmac::HmacInit(const Arguments& args) { return ThrowError("Must give hashtype string, key as arguments"); } - ASSERT_IS_BUFFER(args[1]); String::Utf8Value hashType(args[0]); char* buffer_data = Buffer::Data(args[1]); size_t buffer_length = Buffer::Length(args[1]); - - Handle<Value> ret = hmac->HmacInit(*hashType, buffer_data, buffer_length); - - if (ret->IsNull()) { - return args.This(); - } else { - // Exception - return ret; - } + hmac->HmacInit(*hashType, buffer_data, buffer_length); } @@ -2426,7 +2323,7 @@ bool Hmac::HmacUpdate(char* data, int len) { } -Handle<Value> Hmac::HmacUpdate(const Arguments& args) { +void Hmac::HmacUpdate(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Hmac* hmac = ObjectWrap::Unwrap<Hmac>(args.This()); @@ -2451,8 +2348,6 @@ Handle<Value> Hmac::HmacUpdate(const Arguments& args) { if (!r) { return ThrowTypeError("HmacUpdate fail"); } - - return args.This(); } @@ -2466,7 +2361,7 @@ bool Hmac::HmacDigest(unsigned char** md_value, unsigned int* md_len) { } -Handle<Value> Hmac::HmacDigest(const Arguments& args) { +void Hmac::HmacDigest(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Hmac* hmac = ObjectWrap::Unwrap<Hmac>(args.This()); @@ -2478,7 +2373,6 @@ Handle<Value> Hmac::HmacDigest(const Arguments& args) { unsigned char* md_value = NULL; unsigned int md_len = 0; - Local<Value> outString; bool r = hmac->HmacDigest(&md_value, &md_len); if (!r) { @@ -2486,11 +2380,10 @@ Handle<Value> Hmac::HmacDigest(const Arguments& args) { md_len = 0; } - outString = StringBytes::Encode( + Local<Value> rc = StringBytes::Encode( reinterpret_cast<const char*>(md_value), md_len, encoding); - delete[] md_value; - return scope.Close(outString); + args.GetReturnValue().Set(rc); } @@ -2508,7 +2401,7 @@ void Hash::Initialize(v8::Handle<v8::Object> target) { } -Handle<Value> Hash::New(const Arguments& args) { +void Hash::New(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); if (args.Length() == 0 || !args[0]->IsString()) { @@ -2524,7 +2417,6 @@ Handle<Value> Hash::New(const Arguments& args) { } hash->Wrap(args.This()); - return args.This(); } @@ -2546,7 +2438,7 @@ bool Hash::HashUpdate(char* data, int len) { } -Handle<Value> Hash::HashUpdate(const Arguments& args) { +void Hash::HashUpdate(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Hash* hash = ObjectWrap::Unwrap<Hash>(args.This()); @@ -2571,12 +2463,10 @@ Handle<Value> Hash::HashUpdate(const Arguments& args) { if (!r) { return ThrowTypeError("HashUpdate fail"); } - - return args.This(); } -Handle<Value> Hash::HashDigest(const Arguments& args) { +void Hash::HashDigest(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Hash* hash = ObjectWrap::Unwrap<Hash>(args.This()); @@ -2597,8 +2487,9 @@ Handle<Value> Hash::HashDigest(const Arguments& args) { EVP_MD_CTX_cleanup(&hash->mdctx_); hash->initialised_ = false; - return scope.Close(StringBytes::Encode( - reinterpret_cast<const char*>(md_value), md_len, encoding)); + Local<Value> rc = StringBytes::Encode( + reinterpret_cast<const char*>(md_value), md_len, encoding); + args.GetReturnValue().Set(rc); } @@ -2617,16 +2508,14 @@ void Sign::Initialize(v8::Handle<v8::Object> target) { } -Handle<Value> Sign::New(const Arguments& args) { +void Sign::New(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); - Sign* sign = new Sign(); sign->Wrap(args.This()); - - return args.This(); } -Handle<Value> Sign::SignInit(const char* sign_type) { + +void Sign::SignInit(const char* sign_type) { HandleScope scope(node_isolate); assert(md_ == NULL); @@ -2637,11 +2526,10 @@ Handle<Value> Sign::SignInit(const char* sign_type) { EVP_MD_CTX_init(&mdctx_); EVP_SignInit_ex(&mdctx_, md_, NULL); initialised_ = true; - return Null(node_isolate); } -Handle<Value> Sign::SignInit(const Arguments& args) { +void Sign::SignInit(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Sign* sign = ObjectWrap::Unwrap<Sign>(args.This()); @@ -2651,15 +2539,7 @@ Handle<Value> Sign::SignInit(const Arguments& args) { } String::Utf8Value sign_type(args[0]); - - Handle<Value> ret = sign->SignInit(*sign_type); - - if (ret->IsNull()) { - return args.This(); - } else { - // Exception - return scope.Close(ret); - } + sign->SignInit(*sign_type); } @@ -2670,7 +2550,7 @@ bool Sign::SignUpdate(char* data, int len) { } -Handle<Value> Sign::SignUpdate(const Arguments& args) { +void Sign::SignUpdate(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Sign* sign = ObjectWrap::Unwrap<Sign>(args.This()); @@ -2695,8 +2575,6 @@ Handle<Value> Sign::SignUpdate(const Arguments& args) { if (!r) { return ThrowTypeError("SignUpdate fail"); } - - return args.This(); } @@ -2723,14 +2601,13 @@ bool Sign::SignFinal(unsigned char** md_value, } -Handle<Value> Sign::SignFinal(const Arguments& args) { +void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Sign* sign = ObjectWrap::Unwrap<Sign>(args.This()); unsigned char* md_value; unsigned int md_len; - Local<Value> outString; enum encoding encoding = BUFFER; if (args.Length() >= 2) { @@ -2751,11 +2628,10 @@ Handle<Value> Sign::SignFinal(const Arguments& args) { md_len = 0; } - outString = StringBytes::Encode( + Local<Value> rc = StringBytes::Encode( reinterpret_cast<const char*>(md_value), md_len, encoding); - delete[] md_value; - return scope.Close(outString); + args.GetReturnValue().Set(rc); } @@ -2774,17 +2650,14 @@ void Verify::Initialize(v8::Handle<v8::Object> target) { } -Handle<Value> Verify::New(const Arguments& args) { +void Verify::New(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); - Verify* verify = new Verify(); verify->Wrap(args.This()); - - return args.This(); } -Handle<Value> Verify::VerifyInit(const char* verify_type) { +void Verify::VerifyInit(const char* verify_type) { HandleScope scope(node_isolate); assert(md_ == NULL); @@ -2796,12 +2669,10 @@ Handle<Value> Verify::VerifyInit(const char* verify_type) { EVP_MD_CTX_init(&mdctx_); EVP_VerifyInit_ex(&mdctx_, md_, NULL); initialised_ = true; - - return Null(node_isolate); } -Handle<Value> Verify::VerifyInit(const Arguments& args) { +void Verify::VerifyInit(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Verify* verify = ObjectWrap::Unwrap<Verify>(args.This()); @@ -2811,15 +2682,7 @@ Handle<Value> Verify::VerifyInit(const Arguments& args) { } String::Utf8Value verify_type(args[0]); - - Handle<Value> ret = verify->VerifyInit(*verify_type); - - if (ret->IsNull()) { - return args.This(); - } else { - // Exception - return scope.Close(ret); - } + verify->VerifyInit(*verify_type); } @@ -2830,7 +2693,7 @@ bool Verify::VerifyUpdate(char* data, int len) { } -Handle<Value> Verify::VerifyUpdate(const Arguments& args) { +void Verify::VerifyUpdate(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Verify* verify = ObjectWrap::Unwrap<Verify>(args.This()); @@ -2855,26 +2718,25 @@ Handle<Value> Verify::VerifyUpdate(const Arguments& args) { if (!r) { return ThrowTypeError("VerifyUpdate fail"); } - - return args.This(); } -Handle<Value> Verify::VerifyFinal(char* key_pem, - int key_pem_len, - unsigned char* sig, - int siglen) { +bool Verify::VerifyFinal(char* key_pem, + int key_pem_len, + unsigned char* sig, + int siglen) { HandleScope scope(node_isolate); if (!initialised_) { - return ThrowError("Verify not initalised"); + ThrowError("Verify not initalised"); + return false; } EVP_PKEY* pkey = NULL; BIO* bp = NULL; X509* x509 = NULL; bool fatal = true; - int r; + int r = 0; bp = BIO_new(BIO_s_mem()); if (bp == NULL) @@ -2926,14 +2788,15 @@ exit: if (fatal) { unsigned long err = ERR_get_error(); - return ThrowCryptoError(err); + ThrowCryptoError(err); + return false; } - return scope.Close(r ? True(node_isolate) : False(node_isolate)); + return r == 1; } -Handle<Value> Verify::VerifyFinal(const Arguments& args) { +void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Verify* verify = ObjectWrap::Unwrap<Verify>(args.This()); @@ -2951,7 +2814,6 @@ Handle<Value> Verify::VerifyFinal(const Arguments& args) { ssize_t hlen = StringBytes::Size(args[1], encoding); - // only copy if we need to, because it's a string. unsigned char* hbuf; if (args[1]->IsString()) { @@ -2963,11 +2825,11 @@ Handle<Value> Verify::VerifyFinal(const Arguments& args) { hbuf = reinterpret_cast<unsigned char*>(Buffer::Data(args[1])); } - Local<Value> retval = Local<Value>::New(verify->VerifyFinal(kbuf, klen, hbuf, hlen)); + bool rc = verify->VerifyFinal(kbuf, klen, hbuf, hlen); if (args[1]->IsString()) { delete[] hbuf; } - return scope.Close(retval); + args.GetReturnValue().Set(rc); } @@ -3037,7 +2899,8 @@ bool DiffieHellman::Init(unsigned char* p, } -Handle<Value> DiffieHellman::DiffieHellmanGroup(const Arguments& args) { +void DiffieHellman::DiffieHellmanGroup( + const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); DiffieHellman* diffieHellman = new DiffieHellman(); @@ -3066,12 +2929,10 @@ Handle<Value> DiffieHellman::DiffieHellmanGroup(const Arguments& args) { } diffieHellman->Wrap(args.This()); - - return args.This(); } -Handle<Value> DiffieHellman::New(const Arguments& args) { +void DiffieHellman::New(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); DiffieHellman* diffieHellman = new DiffieHellman(); @@ -3092,12 +2953,10 @@ Handle<Value> DiffieHellman::New(const Arguments& args) { } diffieHellman->Wrap(args.This()); - - return args.This(); } -Handle<Value> DiffieHellman::GenerateKeys(const Arguments& args) { +void DiffieHellman::GenerateKeys(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); DiffieHellman* diffieHellman = @@ -3111,21 +2970,17 @@ Handle<Value> DiffieHellman::GenerateKeys(const Arguments& args) { return ThrowError("Key generation failed"); } - Local<Value> outString; - int dataSize = BN_num_bytes(diffieHellman->dh->pub_key); char* data = new char[dataSize]; BN_bn2bin(diffieHellman->dh->pub_key, reinterpret_cast<unsigned char*>(data)); - outString = Encode(data, dataSize, BUFFER); + args.GetReturnValue().Set(Encode(data, dataSize, BUFFER)); delete[] data; - - return scope.Close(outString); } -Handle<Value> DiffieHellman::GetPrime(const Arguments& args) { +void DiffieHellman::GetPrime(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); DiffieHellman* diffieHellman = @@ -3139,17 +2994,12 @@ Handle<Value> DiffieHellman::GetPrime(const Arguments& args) { char* data = new char[dataSize]; BN_bn2bin(diffieHellman->dh->p, reinterpret_cast<unsigned char*>(data)); - Local<Value> outString; - - outString = Encode(data, dataSize, BUFFER); - + args.GetReturnValue().Set(Encode(data, dataSize, BUFFER)); delete[] data; - - return scope.Close(outString); } -Handle<Value> DiffieHellman::GetGenerator(const Arguments& args) { +void DiffieHellman::GetGenerator(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); DiffieHellman* diffieHellman = @@ -3163,17 +3013,12 @@ Handle<Value> DiffieHellman::GetGenerator(const Arguments& args) { char* data = new char[dataSize]; BN_bn2bin(diffieHellman->dh->g, reinterpret_cast<unsigned char*>(data)); - Local<Value> outString; - - outString = Encode(data, dataSize, BUFFER); - + args.GetReturnValue().Set(Encode(data, dataSize, BUFFER)); delete[] data; - - return scope.Close(outString); } -Handle<Value> DiffieHellman::GetPublicKey(const Arguments& args) { +void DiffieHellman::GetPublicKey(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); DiffieHellman* diffieHellman = @@ -3192,17 +3037,12 @@ Handle<Value> DiffieHellman::GetPublicKey(const Arguments& args) { BN_bn2bin(diffieHellman->dh->pub_key, reinterpret_cast<unsigned char*>(data)); - Local<Value> outString; - - outString = Encode(data, dataSize, BUFFER); - + args.GetReturnValue().Set(Encode(data, dataSize, BUFFER)); delete[] data; - - return scope.Close(outString); } -Handle<Value> DiffieHellman::GetPrivateKey(const Arguments& args) { +void DiffieHellman::GetPrivateKey(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); DiffieHellman* diffieHellman = @@ -3221,17 +3061,12 @@ Handle<Value> DiffieHellman::GetPrivateKey(const Arguments& args) { BN_bn2bin(diffieHellman->dh->priv_key, reinterpret_cast<unsigned char*>(data)); - Local<Value> outString; - - outString = Encode(data, dataSize, BUFFER); - + args.GetReturnValue().Set(Encode(data, dataSize, BUFFER)); delete[] data; - - return scope.Close(outString); } -Handle<Value> DiffieHellman::ComputeSecret(const Arguments& args) { +void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); DiffieHellman* diffieHellman = @@ -3298,16 +3133,12 @@ Handle<Value> DiffieHellman::ComputeSecret(const Arguments& args) { memset(data, 0, dataSize - size); } - Local<Value> outString; - - outString = Encode(data, dataSize, BUFFER); - + args.GetReturnValue().Set(Encode(data, dataSize, BUFFER)); delete[] data; - return scope.Close(outString); } -Handle<Value> DiffieHellman::SetPublicKey(const Arguments& args) { +void DiffieHellman::SetPublicKey(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); DiffieHellman* diffieHellman = @@ -3325,12 +3156,10 @@ Handle<Value> DiffieHellman::SetPublicKey(const Arguments& args) { reinterpret_cast<unsigned char*>(Buffer::Data(args[0])), Buffer::Length(args[0]), 0); } - - return args.This(); } -Handle<Value> DiffieHellman::SetPrivateKey(const Arguments& args) { +void DiffieHellman::SetPrivateKey(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); DiffieHellman* diffieHellman = @@ -3349,8 +3178,6 @@ Handle<Value> DiffieHellman::SetPrivateKey(const Arguments& args) { Buffer::Length(args[0]), 0); } - - return args.This(); } @@ -3420,15 +3247,15 @@ void EIO_PBKDF2After(uv_work_t* work_req, int status) { assert(status == 0); pbkdf2_req* req = container_of(work_req, pbkdf2_req, work_req); HandleScope scope(node_isolate); + Local<Object> obj = Local<Object>::New(node_isolate, req->obj); + req->obj.Dispose(); Local<Value> argv[2]; - Persistent<Object> obj = req->obj; EIO_PBKDF2After(req, argv); MakeCallback(obj, "ondone", ARRAY_SIZE(argv), argv); - obj.Dispose(node_isolate); } -Handle<Value> PBKDF2(const Arguments& args) { +void PBKDF2(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); const char* type_error = NULL; @@ -3502,25 +3329,28 @@ Handle<Value> PBKDF2(const Arguments& args) { req->keylen = keylen; if (args[4]->IsFunction()) { - req->obj = Persistent<Object>::New(node_isolate, Object::New()); - req->obj->Set(String::New("ondone"), args[4]); + Local<Object> obj = Object::New(); + obj->Set(String::New("ondone"), args[4]); + req->obj.Reset(node_isolate, obj); uv_queue_work(uv_default_loop(), &req->work_req, EIO_PBKDF2, EIO_PBKDF2After); - return Undefined(node_isolate); } else { Local<Value> argv[2]; EIO_PBKDF2(req); EIO_PBKDF2After(req, argv); - if (argv[0]->IsObject()) return ThrowException(argv[0]); - return scope.Close(argv[1]); + if (argv[0]->IsObject()) + ThrowException(argv[0]); + else + args.GetReturnValue().Set(argv[1]); } + return; err: delete[] salt; delete[] pass; - return ThrowException(Exception::TypeError(String::New(type_error))); + return ThrowTypeError(type_error); } @@ -3535,9 +3365,7 @@ struct RandomBytesRequest { RandomBytesRequest::~RandomBytesRequest() { - if (obj_.IsEmpty()) return; - obj_.Dispose(node_isolate); - obj_.Clear(); + obj_.Dispose(); } @@ -3597,7 +3425,7 @@ void RandomBytesAfter(uv_work_t* work_req, int status) { template <bool pseudoRandom> -Handle<Value> RandomBytes(const Arguments& args) { +void RandomBytes(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); // maybe allow a buffer to write to? cuts down on object creation @@ -3617,15 +3445,15 @@ Handle<Value> RandomBytes(const Arguments& args) { req->size_ = size; if (args[1]->IsFunction()) { - req->obj_ = Persistent<Object>::New(node_isolate, Object::New()); - req->obj_->Set(String::New("ondone"), args[1]); + Local<Object> obj = Object::New(); + obj->Set(String::New("ondone"), args[1]); + req->obj_.Reset(node_isolate, obj); uv_queue_work(uv_default_loop(), &req->work_req_, RandomBytesWork<pseudoRandom>, RandomBytesAfter); - - return req->obj_; + args.GetReturnValue().Set(obj); } else { Local<Value> argv[2]; @@ -3634,14 +3462,14 @@ Handle<Value> RandomBytes(const Arguments& args) { delete req; if (!argv[0]->IsNull()) - return ThrowException(argv[0]); + ThrowException(argv[0]); else - return argv[1]; + args.GetReturnValue().Set(argv[1]); } } -Handle<Value> GetSSLCiphers(const Arguments& args) { +void GetSSLCiphers(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); SSL_CTX* ctx = SSL_CTX_new(TLSv1_server_method()); @@ -3666,7 +3494,7 @@ Handle<Value> GetSSLCiphers(const Arguments& args) { SSL_free(ssl); SSL_CTX_free(ctx); - return scope.Close(arr); + args.GetReturnValue().Set(arr); } @@ -3680,19 +3508,19 @@ static void array_push_back(const TypeName* md, } -Handle<Value> GetCiphers(const Arguments& args) { +void GetCiphers(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Local<Array> arr = Array::New(); EVP_CIPHER_do_all_sorted(array_push_back<EVP_CIPHER>, &arr); - return scope.Close(arr); + args.GetReturnValue().Set(arr); } -Handle<Value> GetHashes(const Arguments& args) { +void GetHashes(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Local<Array> arr = Array::New(); EVP_MD_do_all_sorted(array_push_back<EVP_MD>, &arr); - return scope.Close(arr); + args.GetReturnValue().Set(arr); } @@ -3738,17 +3566,17 @@ void InitCrypto(Handle<Object> target) { NODE_SET_METHOD(target, "getCiphers", GetCiphers); NODE_SET_METHOD(target, "getHashes", GetHashes); - subject_symbol = NODE_PSYMBOL("subject"); - issuer_symbol = NODE_PSYMBOL("issuer"); - valid_from_symbol = NODE_PSYMBOL("valid_from"); - valid_to_symbol = NODE_PSYMBOL("valid_to"); - subjectaltname_symbol = NODE_PSYMBOL("subjectaltname"); - modulus_symbol = NODE_PSYMBOL("modulus"); - exponent_symbol = NODE_PSYMBOL("exponent"); - fingerprint_symbol = NODE_PSYMBOL("fingerprint"); - name_symbol = NODE_PSYMBOL("name"); - version_symbol = NODE_PSYMBOL("version"); - ext_key_usage_symbol = NODE_PSYMBOL("ext_key_usage"); + subject_symbol = String::New("subject"); + issuer_symbol = String::New("issuer"); + valid_from_symbol = String::New("valid_from"); + valid_to_symbol = String::New("valid_to"); + subjectaltname_symbol = String::New("subjectaltname"); + modulus_symbol = String::New("modulus"); + exponent_symbol = String::New("exponent"); + fingerprint_symbol = String::New("fingerprint"); + name_symbol = String::New("name"); + version_symbol = String::New("version"); + ext_key_usage_symbol = String::New("ext_key_usage"); } } // namespace crypto diff --git a/src/node_crypto.h b/src/node_crypto.h index c3c4a89a8..727b7868c 100644 --- a/src/node_crypto.h +++ b/src/node_crypto.h @@ -64,19 +64,21 @@ class SecureContext : ObjectWrap { protected: - static v8::Handle<v8::Value> New(const v8::Arguments& args); - static v8::Handle<v8::Value> Init(const v8::Arguments& args); - static v8::Handle<v8::Value> SetKey(const v8::Arguments& args); - static v8::Handle<v8::Value> SetCert(const v8::Arguments& args); - static v8::Handle<v8::Value> AddCACert(const v8::Arguments& args); - static v8::Handle<v8::Value> AddCRL(const v8::Arguments& args); - static v8::Handle<v8::Value> AddRootCerts(const v8::Arguments& args); - static v8::Handle<v8::Value> SetCiphers(const v8::Arguments& args); - static v8::Handle<v8::Value> SetOptions(const v8::Arguments& args); - static v8::Handle<v8::Value> SetSessionIdContext(const v8::Arguments& args); - static v8::Handle<v8::Value> SetSessionTimeout(const v8::Arguments& args); - static v8::Handle<v8::Value> Close(const v8::Arguments& args); - static v8::Handle<v8::Value> LoadPKCS12(const v8::Arguments& args); + static void New(const v8::FunctionCallbackInfo<v8::Value>& args); + static void Init(const v8::FunctionCallbackInfo<v8::Value>& args); + static void SetKey(const v8::FunctionCallbackInfo<v8::Value>& args); + static void SetCert(const v8::FunctionCallbackInfo<v8::Value>& args); + static void AddCACert(const v8::FunctionCallbackInfo<v8::Value>& args); + static void AddCRL(const v8::FunctionCallbackInfo<v8::Value>& args); + static void AddRootCerts(const v8::FunctionCallbackInfo<v8::Value>& args); + static void SetCiphers(const v8::FunctionCallbackInfo<v8::Value>& args); + static void SetOptions(const v8::FunctionCallbackInfo<v8::Value>& args); + static void SetSessionIdContext( + const v8::FunctionCallbackInfo<v8::Value>& args); + static void SetSessionTimeout( + const v8::FunctionCallbackInfo<v8::Value>& args); + static void Close(const v8::FunctionCallbackInfo<v8::Value>& args); + static void LoadPKCS12(const v8::FunctionCallbackInfo<v8::Value>& args); static SSL_SESSION* GetSessionCallback(SSL* s, unsigned char* key, @@ -172,48 +174,52 @@ class Connection : ObjectWrap { #endif protected: - static v8::Handle<v8::Value> New(const v8::Arguments& args); - static v8::Handle<v8::Value> EncIn(const v8::Arguments& args); - static v8::Handle<v8::Value> ClearOut(const v8::Arguments& args); - static v8::Handle<v8::Value> ClearPending(const v8::Arguments& args); - static v8::Handle<v8::Value> EncPending(const v8::Arguments& args); - static v8::Handle<v8::Value> EncOut(const v8::Arguments& args); - static v8::Handle<v8::Value> ClearIn(const v8::Arguments& args); - static v8::Handle<v8::Value> GetPeerCertificate(const v8::Arguments& args); - static v8::Handle<v8::Value> GetSession(const v8::Arguments& args); - static v8::Handle<v8::Value> SetSession(const v8::Arguments& args); - static v8::Handle<v8::Value> LoadSession(const v8::Arguments& args); - static v8::Handle<v8::Value> IsSessionReused(const v8::Arguments& args); - static v8::Handle<v8::Value> IsInitFinished(const v8::Arguments& args); - static v8::Handle<v8::Value> VerifyError(const v8::Arguments& args); - static v8::Handle<v8::Value> GetCurrentCipher(const v8::Arguments& args); - static v8::Handle<v8::Value> Shutdown(const v8::Arguments& args); - static v8::Handle<v8::Value> ReceivedShutdown(const v8::Arguments& args); - static v8::Handle<v8::Value> Start(const v8::Arguments& args); - static v8::Handle<v8::Value> Close(const v8::Arguments& args); + static void New(const v8::FunctionCallbackInfo<v8::Value>& args); + static void EncIn(const v8::FunctionCallbackInfo<v8::Value>& args); + static void ClearOut(const v8::FunctionCallbackInfo<v8::Value>& args); + static void ClearPending(const v8::FunctionCallbackInfo<v8::Value>& args); + static void EncPending(const v8::FunctionCallbackInfo<v8::Value>& args); + static void EncOut(const v8::FunctionCallbackInfo<v8::Value>& args); + static void ClearIn(const v8::FunctionCallbackInfo<v8::Value>& args); + static void GetPeerCertificate( + const v8::FunctionCallbackInfo<v8::Value>& args); + static void GetSession(const v8::FunctionCallbackInfo<v8::Value>& args); + static void SetSession(const v8::FunctionCallbackInfo<v8::Value>& args); + static void LoadSession(const v8::FunctionCallbackInfo<v8::Value>& args); + static void IsSessionReused(const v8::FunctionCallbackInfo<v8::Value>& args); + static void IsInitFinished(const v8::FunctionCallbackInfo<v8::Value>& args); + static void VerifyError(const v8::FunctionCallbackInfo<v8::Value>& args); + static void GetCurrentCipher(const v8::FunctionCallbackInfo<v8::Value>& args); + static void Shutdown(const v8::FunctionCallbackInfo<v8::Value>& args); + static void ReceivedShutdown(const v8::FunctionCallbackInfo<v8::Value>& args); + static void Start(const v8::FunctionCallbackInfo<v8::Value>& args); + static void Close(const v8::FunctionCallbackInfo<v8::Value>& args); #ifdef OPENSSL_NPN_NEGOTIATED // NPN - static v8::Handle<v8::Value> GetNegotiatedProto(const v8::Arguments& args); - static v8::Handle<v8::Value> SetNPNProtocols(const v8::Arguments& args); - static int AdvertiseNextProtoCallback_(SSL *s, - const unsigned char **data, - unsigned int *len, - void *arg); - static int SelectNextProtoCallback_(SSL *s, - unsigned char **out, unsigned char *outlen, + static void GetNegotiatedProto( + const v8::FunctionCallbackInfo<v8::Value>& args); + static void SetNPNProtocols(const v8::FunctionCallbackInfo<v8::Value>& args); + static int AdvertiseNextProtoCallback_(SSL* s, + const unsigned char** data, + unsigned int* len, + void* arg); + static int SelectNextProtoCallback_(SSL* s, + unsigned char** out, + unsigned char* outlen, const unsigned char* in, - unsigned int inlen, void *arg); + unsigned int inlen, + void* arg); #endif #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB // SNI - static v8::Handle<v8::Value> GetServername(const v8::Arguments& args); - static v8::Handle<v8::Value> SetSNICallback(const v8::Arguments& args); - static int SelectSNIContextCallback_(SSL *s, int *ad, void* arg); + static void GetServername(const v8::FunctionCallbackInfo<v8::Value>& args); + static void SetSNICallback(const v8::FunctionCallbackInfo<v8::Value>& args); + static int SelectSNIContextCallback_(SSL* s, int* ad, void* arg); #endif - int HandleBIOError(BIO *bio, const char* func, int rv); + int HandleBIOError(BIO* bio, const char* func, int rv); enum ZeroStatus { kZeroIsNotAnError, @@ -230,7 +236,7 @@ class Connection : ObjectWrap { void ClearError(); void SetShutdownFlags(); - static Connection* Unwrap(const v8::Arguments& args) { + static Connection* Unwrap(const v8::FunctionCallbackInfo<v8::Value>& args) { Connection* ss = ObjectWrap::Unwrap<Connection>(args.This()); ss->ClearError(); return ss; @@ -254,14 +260,14 @@ class Connection : ObjectWrap { } #ifdef OPENSSL_NPN_NEGOTIATED - if (!npnProtos_.IsEmpty()) npnProtos_.Dispose(node_isolate); - if (!selectedNPNProto_.IsEmpty()) selectedNPNProto_.Dispose(node_isolate); + npnProtos_.Dispose(); + selectedNPNProto_.Dispose(); #endif #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB - if (!sniObject_.IsEmpty()) sniObject_.Dispose(node_isolate); - if (!sniContext_.IsEmpty()) sniContext_.Dispose(node_isolate); - if (!servername_.IsEmpty()) servername_.Dispose(node_isolate); + sniObject_.Dispose(); + sniContext_.Dispose(); + servername_.Dispose(); #endif } @@ -291,22 +297,18 @@ class CipherBase : public ObjectWrap { kDecipher }; - v8::Handle<v8::Value> Init(char* cipher_type, char* key_buf, int key_buf_len); - v8::Handle<v8::Value> InitIv(char* cipher_type, - char* key, - int key_len, - char* iv, - int iv_len); + void Init(char* cipher_type, char* key_buf, int key_buf_len); + void InitIv(char* cipher_type, char* key, int key_len, char* iv, int iv_len); bool Update(char* data, int len, unsigned char** out, int* out_len); bool Final(unsigned char** out, int *out_len); bool SetAutoPadding(bool auto_padding); - static v8::Handle<v8::Value> New(const v8::Arguments& args); - static v8::Handle<v8::Value> Init(const v8::Arguments& args); - static v8::Handle<v8::Value> InitIv(const v8::Arguments& args); - static v8::Handle<v8::Value> Update(const v8::Arguments& args); - static v8::Handle<v8::Value> Final(const v8::Arguments& args); - static v8::Handle<v8::Value> SetAutoPadding(const v8::Arguments& args); + static void New(const v8::FunctionCallbackInfo<v8::Value>& args); + static void Init(const v8::FunctionCallbackInfo<v8::Value>& args); + static void InitIv(const v8::FunctionCallbackInfo<v8::Value>& args); + static void Update(const v8::FunctionCallbackInfo<v8::Value>& args); + static void Final(const v8::FunctionCallbackInfo<v8::Value>& args); + static void SetAutoPadding(const v8::FunctionCallbackInfo<v8::Value>& args); CipherBase(CipherKind kind) : cipher_(NULL), initialised_(false), @@ -330,14 +332,14 @@ class Hmac : public ObjectWrap { static void Initialize (v8::Handle<v8::Object> target); protected: - v8::Handle<v8::Value> HmacInit(char* hashType, char* key, int key_len); + void HmacInit(char* hashType, char* key, int key_len); bool HmacUpdate(char* data, int len); bool HmacDigest(unsigned char** md_value, unsigned int* md_len); - static v8::Handle<v8::Value> New(const v8::Arguments& args); - static v8::Handle<v8::Value> HmacInit(const v8::Arguments& args); - static v8::Handle<v8::Value> HmacUpdate(const v8::Arguments& args); - static v8::Handle<v8::Value> HmacDigest(const v8::Arguments& args); + static void New(const v8::FunctionCallbackInfo<v8::Value>& args); + static void HmacInit(const v8::FunctionCallbackInfo<v8::Value>& args); + static void HmacUpdate(const v8::FunctionCallbackInfo<v8::Value>& args); + static void HmacDigest(const v8::FunctionCallbackInfo<v8::Value>& args); Hmac() : md_(NULL), initialised_(false) { } @@ -361,9 +363,9 @@ class Hash : public ObjectWrap { bool HashUpdate(char* data, int len); protected: - static v8::Handle<v8::Value> New(const v8::Arguments& args); - static v8::Handle<v8::Value> HashUpdate(const v8::Arguments& args); - static v8::Handle<v8::Value> HashDigest(const v8::Arguments& args); + static void New(const v8::FunctionCallbackInfo<v8::Value>& args); + static void HashUpdate(const v8::FunctionCallbackInfo<v8::Value>& args); + static void HashDigest(const v8::FunctionCallbackInfo<v8::Value>& args); Hash() : md_(NULL), initialised_(false) { } @@ -383,7 +385,7 @@ class Sign : public ObjectWrap { public: static void Initialize(v8::Handle<v8::Object> target); - v8::Handle<v8::Value> SignInit(const char* sign_type); + void SignInit(const char* sign_type); bool SignUpdate(char* data, int len); bool SignFinal(unsigned char** md_value, unsigned int *md_len, @@ -391,10 +393,10 @@ class Sign : public ObjectWrap { int key_pem_len); protected: - static v8::Handle<v8::Value> New(const v8::Arguments& args); - static v8::Handle<v8::Value> SignInit(const v8::Arguments& args); - static v8::Handle<v8::Value> SignUpdate(const v8::Arguments& args); - static v8::Handle<v8::Value> SignFinal(const v8::Arguments& args); + static void New(const v8::FunctionCallbackInfo<v8::Value>& args); + static void SignInit(const v8::FunctionCallbackInfo<v8::Value>& args); + static void SignUpdate(const v8::FunctionCallbackInfo<v8::Value>& args); + static void SignFinal(const v8::FunctionCallbackInfo<v8::Value>& args); Sign() : md_(NULL), initialised_(false) { } @@ -414,18 +416,18 @@ class Verify : public ObjectWrap { public: static void Initialize (v8::Handle<v8::Object> target); - v8::Handle<v8::Value> VerifyInit(const char* verify_type); + void VerifyInit(const char* verify_type); bool VerifyUpdate(char* data, int len); - v8::Handle<v8::Value> VerifyFinal(char* key_pem, - int key_pem_len, - unsigned char* sig, - int siglen); + bool VerifyFinal(char* key_pem, + int key_pem_len, + unsigned char* sig, + int siglen); protected: - static v8::Handle<v8::Value> New (const v8::Arguments& args); - static v8::Handle<v8::Value> VerifyInit(const v8::Arguments& args); - static v8::Handle<v8::Value> VerifyUpdate(const v8::Arguments& args); - static v8::Handle<v8::Value> VerifyFinal(const v8::Arguments& args); + static void New (const v8::FunctionCallbackInfo<v8::Value>& args); + static void VerifyInit(const v8::FunctionCallbackInfo<v8::Value>& args); + static void VerifyUpdate(const v8::FunctionCallbackInfo<v8::Value>& args); + static void VerifyFinal(const v8::FunctionCallbackInfo<v8::Value>& args); Verify() : md_(NULL), initialised_(false) { } @@ -451,16 +453,17 @@ class DiffieHellman : public ObjectWrap { bool Init(unsigned char* p, int p_len, unsigned char* g, int g_len); protected: - static v8::Handle<v8::Value> DiffieHellmanGroup(const v8::Arguments& args); - static v8::Handle<v8::Value> New(const v8::Arguments& args); - static v8::Handle<v8::Value> GenerateKeys(const v8::Arguments& args); - static v8::Handle<v8::Value> GetPrime(const v8::Arguments& args); - static v8::Handle<v8::Value> GetGenerator(const v8::Arguments& args); - static v8::Handle<v8::Value> GetPublicKey(const v8::Arguments& args); - static v8::Handle<v8::Value> GetPrivateKey(const v8::Arguments& args); - static v8::Handle<v8::Value> ComputeSecret(const v8::Arguments& args); - static v8::Handle<v8::Value> SetPublicKey(const v8::Arguments& args); - static v8::Handle<v8::Value> SetPrivateKey(const v8::Arguments& args); + static void DiffieHellmanGroup( + const v8::FunctionCallbackInfo<v8::Value>& args); + static void New(const v8::FunctionCallbackInfo<v8::Value>& args); + static void GenerateKeys(const v8::FunctionCallbackInfo<v8::Value>& args); + static void GetPrime(const v8::FunctionCallbackInfo<v8::Value>& args); + static void GetGenerator(const v8::FunctionCallbackInfo<v8::Value>& args); + static void GetPublicKey(const v8::FunctionCallbackInfo<v8::Value>& args); + static void GetPrivateKey(const v8::FunctionCallbackInfo<v8::Value>& args); + static void ComputeSecret(const v8::FunctionCallbackInfo<v8::Value>& args); + static void SetPublicKey(const v8::FunctionCallbackInfo<v8::Value>& args); + static void SetPrivateKey(const v8::FunctionCallbackInfo<v8::Value>& args); DiffieHellman() : ObjectWrap(), initialised_(false), dh(NULL) { } diff --git a/src/node_dtrace.cc b/src/node_dtrace.cc index 4fb4fcd44..b7b0822c3 100644 --- a/src/node_dtrace.cc +++ b/src/node_dtrace.cc @@ -59,12 +59,23 @@ namespace node { -using namespace v8; +using v8::FunctionCallbackInfo; +using v8::FunctionTemplate; +using v8::GCCallbackFlags; +using v8::GCEpilogueCallback; +using v8::GCPrologueCallback; +using v8::GCType; +using v8::Handle; +using v8::HandleScope; +using v8::Local; +using v8::Object; +using v8::String; +using v8::Value; #define SLURP_STRING(obj, member, valp) \ if (!(obj)->IsObject()) { \ - return (ThrowException(Exception::Error(String::New("expected " \ - "object for " #obj " to contain string member " #member)))); \ + return ThrowError( \ + "expected object for " #obj " to contain string member " #member); \ } \ String::Utf8Value _##member(obj->Get(String::New(#member))); \ if ((*(const char **)valp = *_##member) == NULL) \ @@ -72,22 +83,22 @@ using namespace v8; #define SLURP_INT(obj, member, valp) \ if (!(obj)->IsObject()) { \ - return (ThrowException(Exception::Error(String::New("expected " \ - "object for " #obj " to contain integer member " #member)))); \ + return ThrowError( \ + "expected object for " #obj " to contain integer member " #member); \ } \ *valp = obj->Get(String::New(#member))->ToInteger()->Value(); #define SLURP_OBJECT(obj, member, valp) \ if (!(obj)->IsObject()) { \ - return (ThrowException(Exception::Error(String::New("expected " \ - "object for " #obj " to contain object member " #member)))); \ + return ThrowError( \ + "expected object for " #obj " to contain object member " #member); \ } \ *valp = Local<Object>::Cast(obj->Get(String::New(#member))); #define SLURP_CONNECTION(arg, conn) \ if (!(arg)->IsObject()) { \ - return (ThrowException(Exception::Error(String::New("expected " \ - "argument " #arg " to be a connection object")))); \ + return ThrowError( \ + "expected argument " #arg " to be a connection object"); \ } \ node_dtrace_connection_t conn; \ Local<Object> _##conn = Local<Object>::Cast(arg); \ @@ -103,8 +114,8 @@ using namespace v8; #define SLURP_CONNECTION_HTTP_CLIENT(arg, conn) \ if (!(arg)->IsObject()) { \ - return (ThrowException(Exception::Error(String::New("expected " \ - "argument " #arg " to be a connection object")))); \ + return ThrowError( \ + "expected argument " #arg " to be a connection object"); \ } \ node_dtrace_connection_t conn; \ Local<Object> _##conn = Local<Object>::Cast(arg); \ @@ -115,12 +126,12 @@ using namespace v8; #define SLURP_CONNECTION_HTTP_CLIENT_RESPONSE(arg0, arg1, conn) \ if (!(arg0)->IsObject()) { \ - return (ThrowException(Exception::Error(String::New("expected " \ - "argument " #arg0 " to be a connection object")))); \ + return ThrowError( \ + "expected argument " #arg0 " to be a connection object"); \ } \ if (!(arg1)->IsObject()) { \ - return (ThrowException(Exception::Error(String::New("expected " \ - "argument " #arg1 " to be a connection object")))); \ + return ThrowError( \ + "expected argument " #arg1 " to be a connection object"); \ } \ node_dtrace_connection_t conn; \ Local<Object> _##conn = Local<Object>::Cast(arg0); \ @@ -131,86 +142,71 @@ using namespace v8; SLURP_INT(_##conn, port, &conn.port); -Handle<Value> DTRACE_NET_SERVER_CONNECTION(const Arguments& args) { +void DTRACE_NET_SERVER_CONNECTION(const FunctionCallbackInfo<Value>& args) { #ifndef HAVE_SYSTEMTAP if (!NODE_NET_SERVER_CONNECTION_ENABLED()) - return Undefined(node_isolate); + return; #endif - HandleScope scope(node_isolate); - SLURP_CONNECTION(args[0], conn); - NODE_NET_SERVER_CONNECTION(&conn, conn.remote, conn.port, conn.fd); - - return Undefined(node_isolate); } -Handle<Value> DTRACE_NET_STREAM_END(const Arguments& args) { + +void DTRACE_NET_STREAM_END(const FunctionCallbackInfo<Value>& args) { #ifndef HAVE_SYSTEMTAP if (!NODE_NET_STREAM_END_ENABLED()) - return Undefined(node_isolate); + return; #endif - HandleScope scope(node_isolate); - SLURP_CONNECTION(args[0], conn); - NODE_NET_STREAM_END(&conn, conn.remote, conn.port, conn.fd); - - return Undefined(node_isolate); } -Handle<Value> DTRACE_NET_SOCKET_READ(const Arguments& args) { + +void DTRACE_NET_SOCKET_READ(const FunctionCallbackInfo<Value>& args) { #ifndef HAVE_SYSTEMTAP if (!NODE_NET_SOCKET_READ_ENABLED()) - return Undefined(node_isolate); + return; #endif - HandleScope scope(node_isolate); - SLURP_CONNECTION(args[0], conn); if (!args[1]->IsNumber()) { - return (ThrowException(Exception::Error(String::New("expected " - "argument 1 to be number of bytes")))); + return ThrowError("expected argument 1 to be number of bytes"); } + int nbytes = args[1]->Int32Value(); NODE_NET_SOCKET_READ(&conn, nbytes, conn.remote, conn.port, conn.fd); - - return Undefined(node_isolate); } -Handle<Value> DTRACE_NET_SOCKET_WRITE(const Arguments& args) { + +void DTRACE_NET_SOCKET_WRITE(const FunctionCallbackInfo<Value>& args) { #ifndef HAVE_SYSTEMTAP if (!NODE_NET_SOCKET_WRITE_ENABLED()) - return Undefined(node_isolate); + return; #endif - HandleScope scope(node_isolate); - SLURP_CONNECTION(args[0], conn); if (!args[1]->IsNumber()) { - return (ThrowException(Exception::Error(String::New("expected " - "argument 1 to be number of bytes")))); + return ThrowError("expected argument 1 to be number of bytes"); } + int nbytes = args[1]->Int32Value(); NODE_NET_SOCKET_WRITE(&conn, nbytes, conn.remote, conn.port, conn.fd); - - return Undefined(node_isolate); } -Handle<Value> DTRACE_HTTP_SERVER_REQUEST(const Arguments& args) { + +void DTRACE_HTTP_SERVER_REQUEST(const FunctionCallbackInfo<Value>& args) { node_dtrace_http_server_request_t req; #ifndef HAVE_SYSTEMTAP if (!NODE_HTTP_SERVER_REQUEST_ENABLED()) - return Undefined(node_isolate); + return; #endif HandleScope scope(node_isolate); - Local<Object> arg0 = Local<Object>::Cast(args[0]); Local<Object> headers; @@ -218,12 +214,12 @@ Handle<Value> DTRACE_HTTP_SERVER_REQUEST(const Arguments& args) { req._un.version = 1; SLURP_STRING(arg0, url, &req.url); SLURP_STRING(arg0, method, &req.method); - SLURP_OBJECT(arg0, headers, &headers); - if (!(headers)->IsObject()) - return (ThrowException(Exception::Error(String::New("expected " - "object for request to contain string member headers")))); + if (!(headers)->IsObject()) { + return ThrowError( + "expected object for request to contain string member headers"); + } Local<Value> strfwdfor = headers->Get(String::New("x-forwarded-for")); String::Utf8Value fwdfor(strfwdfor); @@ -232,35 +228,29 @@ Handle<Value> DTRACE_HTTP_SERVER_REQUEST(const Arguments& args) { req.forwardedFor = const_cast<char*>(""); SLURP_CONNECTION(args[1], conn); - NODE_HTTP_SERVER_REQUEST(&req, &conn, conn.remote, conn.port, req.method, \ req.url, conn.fd); - - return Undefined(node_isolate); } -Handle<Value> DTRACE_HTTP_SERVER_RESPONSE(const Arguments& args) { + +void DTRACE_HTTP_SERVER_RESPONSE(const FunctionCallbackInfo<Value>& args) { #ifndef HAVE_SYSTEMTAP if (!NODE_HTTP_SERVER_RESPONSE_ENABLED()) - return Undefined(node_isolate); + return; #endif - HandleScope scope(node_isolate); - SLURP_CONNECTION(args[0], conn); - NODE_HTTP_SERVER_RESPONSE(&conn, conn.remote, conn.port, conn.fd); - - return Undefined(node_isolate); } -Handle<Value> DTRACE_HTTP_CLIENT_REQUEST(const Arguments& args) { + +void DTRACE_HTTP_CLIENT_REQUEST(const FunctionCallbackInfo<Value>& args) { node_dtrace_http_client_request_t req; char *header; #ifndef HAVE_SYSTEMTAP if (!NODE_HTTP_CLIENT_REQUEST_ENABLED()) - return Undefined(node_isolate); + return; #endif HandleScope scope(node_isolate); @@ -290,28 +280,21 @@ Handle<Value> DTRACE_HTTP_CLIENT_REQUEST(const Arguments& args) { *header = '\0'; SLURP_CONNECTION_HTTP_CLIENT(args[1], conn); - NODE_HTTP_CLIENT_REQUEST(&req, &conn, conn.remote, conn.port, req.method, \ req.url, conn.fd); - - return Undefined(node_isolate); } -Handle<Value> DTRACE_HTTP_CLIENT_RESPONSE(const Arguments& args) { + +void DTRACE_HTTP_CLIENT_RESPONSE(const FunctionCallbackInfo<Value>& args) { #ifndef HAVE_SYSTEMTAP if (!NODE_HTTP_CLIENT_RESPONSE_ENABLED()) - return Undefined(node_isolate); + return; #endif HandleScope scope(node_isolate); - SLURP_CONNECTION_HTTP_CLIENT_RESPONSE(args[0], args[1], conn); - NODE_HTTP_CLIENT_RESPONSE(&conn, conn.remote, conn.port, conn.fd); - - return Undefined(node_isolate); } -#define NODE_PROBE(name) #name, name, Persistent<FunctionTemplate>() static int dtrace_gc_start(GCType type, GCCallbackFlags flags) { NODE_GC_START(type, flags); @@ -322,17 +305,21 @@ static int dtrace_gc_start(GCType type, GCCallbackFlags flags) { return 0; } + static int dtrace_gc_done(GCType type, GCCallbackFlags flags) { NODE_GC_DONE(type, flags); return 0; } + void InitDTrace(Handle<Object> target) { + HandleScope scope(node_isolate); + static struct { const char *name; - Handle<Value> (*func)(const Arguments&); - Persistent<FunctionTemplate> templ; + void (*func)(const FunctionCallbackInfo<Value>&); } tab[] = { +#define NODE_PROBE(name) #name, name { NODE_PROBE(DTRACE_NET_SERVER_CONNECTION) }, { NODE_PROBE(DTRACE_NET_STREAM_END) }, { NODE_PROBE(DTRACE_NET_SOCKET_READ) }, @@ -341,12 +328,13 @@ void InitDTrace(Handle<Object> target) { { NODE_PROBE(DTRACE_HTTP_SERVER_RESPONSE) }, { NODE_PROBE(DTRACE_HTTP_CLIENT_REQUEST) }, { NODE_PROBE(DTRACE_HTTP_CLIENT_RESPONSE) } +#undef NODE_PROBE }; for (unsigned int i = 0; i < ARRAY_SIZE(tab); i++) { - tab[i].templ = Persistent<FunctionTemplate>::New(node_isolate, - FunctionTemplate::New(tab[i].func)); - target->Set(String::NewSymbol(tab[i].name), tab[i].templ->GetFunction()); + Local<String> key = String::New(tab[i].name); + Local<Value> val = FunctionTemplate::New(tab[i].func)->GetFunction(); + target->Set(key, val); } #ifdef HAVE_ETW diff --git a/src/node_file.cc b/src/node_file.cc index 69b76736c..68eb668d8 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -39,12 +39,23 @@ namespace node { -using namespace v8; +using v8::Array; +using v8::Function; +using v8::FunctionCallbackInfo; +using v8::FunctionTemplate; +using v8::Handle; +using v8::HandleScope; +using v8::Integer; +using v8::Local; +using v8::Number; +using v8::Object; +using v8::Persistent; +using v8::String; +using v8::Value; #define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define TYPE_ERROR(msg) \ - ThrowException(Exception::TypeError(String::New(msg))); +#define TYPE_ERROR(msg) ThrowTypeError(msg) #define THROW_BAD_ARGS TYPE_ERROR("Bad argument") @@ -61,16 +72,16 @@ class FSReqWrap: public ReqWrap<uv_fs_t> { }; -static Persistent<String> oncomplete_sym; +static Cached<String> oncomplete_sym; #define ASSERT_OFFSET(a) \ if (!(a)->IsUndefined() && !(a)->IsNull() && !IsInt64((a)->NumberValue())) { \ - return ThrowException(Exception::TypeError(String::New("Not an integer"))); \ + return ThrowTypeError("Not an integer"); \ } #define ASSERT_TRUNCATE_LENGTH(a) \ if (!(a)->IsUndefined() && !(a)->IsNull() && !IsInt64((a)->NumberValue())) { \ - return ThrowException(Exception::TypeError(String::New("Not an integer"))); \ + return ThrowTypeError("Not an integer"); \ } #define GET_OFFSET(a) ((a)->IsNumber() ? (a)->IntegerValue() : -1) #define GET_TRUNCATE_LENGTH(a) ((a)->IntegerValue()) @@ -192,9 +203,9 @@ static void After(uv_fs_t *req) { } if (oncomplete_sym.IsEmpty()) { - oncomplete_sym = NODE_PSYMBOL("oncomplete"); + oncomplete_sym = String::New("oncomplete"); } - MakeCallback(req_wrap->object_, oncomplete_sym, argc, argv); + MakeCallback(req_wrap->object(), oncomplete_sym, argc, argv); uv_fs_req_cleanup(&req_wrap->req_); delete req_wrap; @@ -216,7 +227,7 @@ struct fs_req_wrap { FSReqWrap* req_wrap = new FSReqWrap(#func); \ int r = uv_fs_##func(uv_default_loop(), &req_wrap->req_, \ __VA_ARGS__, After); \ - req_wrap->object_->Set(oncomplete_sym, callback); \ + req_wrap->object()->Set(oncomplete_sym, callback); \ req_wrap->Dispatched(); \ if (r < 0) { \ uv_fs_t* req = &req_wrap->req_; \ @@ -225,14 +236,14 @@ struct fs_req_wrap { req->errorno = uv_last_error(uv_default_loop()).code; \ After(req); \ } \ - return scope.Close(req_wrap->object_); + args.GetReturnValue().Set(req_wrap->persistent()); #define SYNC_CALL(func, path, ...) \ fs_req_wrap req_wrap; \ int result = uv_fs_##func(uv_default_loop(), &req_wrap.req, __VA_ARGS__, NULL); \ if (result < 0) { \ int code = uv_last_error(uv_default_loop()).code; \ - return ThrowException(UVException(code, #func, "", path)); \ + return ThrowUVException(code, #func, "", path); \ } #define SYNC_REQ req_wrap.req @@ -240,7 +251,7 @@ struct fs_req_wrap { #define SYNC_RESULT result -static Handle<Value> Close(const Arguments& args) { +static void Close(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); if (args.Length() < 1 || !args[0]->IsInt32()) { @@ -253,49 +264,49 @@ static Handle<Value> Close(const Arguments& args) { ASYNC_CALL(close, args[1], fd) } else { SYNC_CALL(close, 0, fd) - return Undefined(node_isolate); } } -static Persistent<FunctionTemplate> stats_constructor_template; +static Persistent<Function> stats_constructor; -static Persistent<String> dev_symbol; -static Persistent<String> ino_symbol; -static Persistent<String> mode_symbol; -static Persistent<String> nlink_symbol; -static Persistent<String> uid_symbol; -static Persistent<String> gid_symbol; -static Persistent<String> rdev_symbol; -static Persistent<String> size_symbol; -static Persistent<String> blksize_symbol; -static Persistent<String> blocks_symbol; -static Persistent<String> atime_symbol; -static Persistent<String> mtime_symbol; -static Persistent<String> ctime_symbol; +static Cached<String> dev_symbol; +static Cached<String> ino_symbol; +static Cached<String> mode_symbol; +static Cached<String> nlink_symbol; +static Cached<String> uid_symbol; +static Cached<String> gid_symbol; +static Cached<String> rdev_symbol; +static Cached<String> size_symbol; +static Cached<String> blksize_symbol; +static Cached<String> blocks_symbol; +static Cached<String> atime_symbol; +static Cached<String> mtime_symbol; +static Cached<String> ctime_symbol; Local<Object> BuildStatsObject(const uv_stat_t* s) { HandleScope scope(node_isolate); if (dev_symbol.IsEmpty()) { - dev_symbol = NODE_PSYMBOL("dev"); - ino_symbol = NODE_PSYMBOL("ino"); - mode_symbol = NODE_PSYMBOL("mode"); - nlink_symbol = NODE_PSYMBOL("nlink"); - uid_symbol = NODE_PSYMBOL("uid"); - gid_symbol = NODE_PSYMBOL("gid"); - rdev_symbol = NODE_PSYMBOL("rdev"); - size_symbol = NODE_PSYMBOL("size"); - blksize_symbol = NODE_PSYMBOL("blksize"); - blocks_symbol = NODE_PSYMBOL("blocks"); - atime_symbol = NODE_PSYMBOL("atime"); - mtime_symbol = NODE_PSYMBOL("mtime"); - ctime_symbol = NODE_PSYMBOL("ctime"); - } - - Local<Object> stats = - stats_constructor_template->GetFunction()->NewInstance(); - + dev_symbol = String::New("dev"); + ino_symbol = String::New("ino"); + mode_symbol = String::New("mode"); + nlink_symbol = String::New("nlink"); + uid_symbol = String::New("uid"); + gid_symbol = String::New("gid"); + rdev_symbol = String::New("rdev"); + size_symbol = String::New("size"); + blksize_symbol = String::New("blksize"); + blocks_symbol = String::New("blocks"); + atime_symbol = String::New("atime"); + mtime_symbol = String::New("mtime"); + ctime_symbol = String::New("ctime"); + } + + Local<Function> constructor = + Local<Function>::New(node_isolate, stats_constructor); + + Local<Object> stats = constructor->NewInstance(); if (stats.IsEmpty()) return Local<Object>(); // The code below is very nasty-looking but it prevents a segmentation fault @@ -355,7 +366,7 @@ Local<Object> BuildStatsObject(const uv_stat_t* s) { return scope.Close(stats); } -static Handle<Value> Stat(const Arguments& args) { +static void Stat(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); if (args.Length() < 1) return TYPE_ERROR("path required"); @@ -367,12 +378,12 @@ static Handle<Value> Stat(const Arguments& args) { ASYNC_CALL(stat, args[1], *path) } else { SYNC_CALL(stat, *path, *path) - return scope.Close( + args.GetReturnValue().Set( BuildStatsObject(static_cast<const uv_stat_t*>(SYNC_REQ.ptr))); } } -static Handle<Value> LStat(const Arguments& args) { +static void LStat(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); if (args.Length() < 1) return TYPE_ERROR("path required"); @@ -384,12 +395,12 @@ static Handle<Value> LStat(const Arguments& args) { ASYNC_CALL(lstat, args[1], *path) } else { SYNC_CALL(lstat, *path, *path) - return scope.Close( + args.GetReturnValue().Set( BuildStatsObject(static_cast<const uv_stat_t*>(SYNC_REQ.ptr))); } } -static Handle<Value> FStat(const Arguments& args) { +static void FStat(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); if (args.Length() < 1 || !args[0]->IsInt32()) { @@ -402,12 +413,12 @@ static Handle<Value> FStat(const Arguments& args) { ASYNC_CALL(fstat, args[1], fd) } else { SYNC_CALL(fstat, 0, fd) - return scope.Close( + args.GetReturnValue().Set( BuildStatsObject(static_cast<const uv_stat_t*>(SYNC_REQ.ptr))); } } -static Handle<Value> Symlink(const Arguments& args) { +static void Symlink(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); int len = args.Length(); @@ -427,8 +438,7 @@ static Handle<Value> Symlink(const Arguments& args) { } else if (strcmp(*mode, "junction") == 0) { flags |= UV_FS_SYMLINK_JUNCTION; } else if (strcmp(*mode, "file") != 0) { - return ThrowException(Exception::Error( - String::New("Unknown symlink type"))); + return ThrowError("Unknown symlink type"); } } @@ -436,11 +446,10 @@ static Handle<Value> Symlink(const Arguments& args) { ASYNC_CALL(symlink, args[3], *dest, *path, flags) } else { SYNC_CALL(symlink, *path, *dest, *path, flags) - return Undefined(node_isolate); } } -static Handle<Value> Link(const Arguments& args) { +static void Link(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); int len = args.Length(); @@ -456,11 +465,10 @@ static Handle<Value> Link(const Arguments& args) { ASYNC_CALL(link, args[2], *orig_path, *new_path) } else { SYNC_CALL(link, *orig_path, *orig_path, *new_path) - return Undefined(node_isolate); } } -static Handle<Value> ReadLink(const Arguments& args) { +static void ReadLink(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); if (args.Length() < 1) return TYPE_ERROR("path required"); @@ -472,11 +480,12 @@ static Handle<Value> ReadLink(const Arguments& args) { ASYNC_CALL(readlink, args[1], *path) } else { SYNC_CALL(readlink, *path, *path) - return scope.Close(String::New((char*)SYNC_REQ.ptr)); + args.GetReturnValue().Set( + String::New(static_cast<const char*>(SYNC_REQ.ptr))); } } -static Handle<Value> Rename(const Arguments& args) { +static void Rename(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); int len = args.Length(); @@ -492,11 +501,10 @@ static Handle<Value> Rename(const Arguments& args) { ASYNC_CALL(rename, args[2], *old_path, *new_path) } else { SYNC_CALL(rename, *old_path, *old_path, *new_path) - return Undefined(node_isolate); } } -static Handle<Value> FTruncate(const Arguments& args) { +static void FTruncate(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); if (args.Length() < 2 || !args[0]->IsInt32()) { @@ -512,11 +520,10 @@ static Handle<Value> FTruncate(const Arguments& args) { ASYNC_CALL(ftruncate, args[2], fd, len) } else { SYNC_CALL(ftruncate, 0, fd, len) - return Undefined(node_isolate); } } -static Handle<Value> Fdatasync(const Arguments& args) { +static void Fdatasync(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); if (args.Length() < 1 || !args[0]->IsInt32()) { @@ -529,11 +536,10 @@ static Handle<Value> Fdatasync(const Arguments& args) { ASYNC_CALL(fdatasync, args[1], fd) } else { SYNC_CALL(fdatasync, 0, fd) - return Undefined(node_isolate); } } -static Handle<Value> Fsync(const Arguments& args) { +static void Fsync(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); if (args.Length() < 1 || !args[0]->IsInt32()) { @@ -546,11 +552,10 @@ static Handle<Value> Fsync(const Arguments& args) { ASYNC_CALL(fsync, args[1], fd) } else { SYNC_CALL(fsync, 0, fd) - return Undefined(node_isolate); } } -static Handle<Value> Unlink(const Arguments& args) { +static void Unlink(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); if (args.Length() < 1) return TYPE_ERROR("path required"); @@ -562,11 +567,10 @@ static Handle<Value> Unlink(const Arguments& args) { ASYNC_CALL(unlink, args[1], *path) } else { SYNC_CALL(unlink, *path, *path) - return Undefined(node_isolate); } } -static Handle<Value> RMDir(const Arguments& args) { +static void RMDir(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); if (args.Length() < 1) return TYPE_ERROR("path required"); @@ -578,11 +582,10 @@ static Handle<Value> RMDir(const Arguments& args) { ASYNC_CALL(rmdir, args[1], *path) } else { SYNC_CALL(rmdir, *path, *path) - return Undefined(node_isolate); } } -static Handle<Value> MKDir(const Arguments& args) { +static void MKDir(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); if (args.Length() < 2 || !args[0]->IsString() || !args[1]->IsInt32()) { @@ -596,11 +599,10 @@ static Handle<Value> MKDir(const Arguments& args) { ASYNC_CALL(mkdir, args[2], *path, mode) } else { SYNC_CALL(mkdir, *path, *path, mode) - return Undefined(node_isolate); } } -static Handle<Value> ReadDir(const Arguments& args) { +static void ReadDir(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); if (args.Length() < 1) return TYPE_ERROR("path required"); @@ -629,11 +631,11 @@ static Handle<Value> ReadDir(const Arguments& args) { #endif } - return scope.Close(names); + args.GetReturnValue().Set(names); } } -static Handle<Value> Open(const Arguments& args) { +static void Open(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); int len = args.Length(); @@ -652,8 +654,7 @@ static Handle<Value> Open(const Arguments& args) { ASYNC_CALL(open, args[3], *path, flags, mode) } else { SYNC_CALL(open, *path, *path, flags, mode) - int fd = SYNC_RESULT; - return scope.Close(Integer::New(fd, node_isolate)); + args.GetReturnValue().Set(SYNC_RESULT); } } @@ -666,7 +667,7 @@ static Handle<Value> Open(const Arguments& args) { // 3 length how much to write // 4 position if integer, position to write at in the file. // if null, write from the current position -static Handle<Value> Write(const Arguments& args) { +static void Write(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); if (!args[0]->IsInt32()) { @@ -676,8 +677,7 @@ static Handle<Value> Write(const Arguments& args) { int fd = args[0]->Int32Value(); if (!Buffer::HasInstance(args[1])) { - return ThrowException(Exception::Error( - String::New("Second argument needs to be a buffer"))); + return ThrowError("Second argument needs to be a buffer"); } Local<Object> buffer_obj = args[1]->ToObject(); @@ -686,14 +686,12 @@ static Handle<Value> Write(const Arguments& args) { size_t off = args[2]->Int32Value(); if (off >= buffer_length) { - return ThrowException(Exception::Error( - String::New("Offset is out of bounds"))); + return ThrowError("Offset is out of bounds"); } ssize_t len = args[3]->Int32Value(); if (off + len > buffer_length) { - return ThrowException(Exception::Error( - String::New("off + len > buffer.length"))); + return ThrowError("off + len > buffer.length"); } ASSERT_OFFSET(args[4]); @@ -706,7 +704,7 @@ static Handle<Value> Write(const Arguments& args) { ASYNC_CALL(write, cb, fd, buf, len, pos) } else { SYNC_CALL(write, 0, fd, buf, len, pos) - return scope.Close(Integer::New(SYNC_RESULT, node_isolate)); + args.GetReturnValue().Set(SYNC_RESULT); } } @@ -722,7 +720,7 @@ static Handle<Value> Write(const Arguments& args) { * 4 position file position - null for current position * */ -static Handle<Value> Read(const Arguments& args) { +static void Read(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); if (args.Length() < 2 || !args[0]->IsInt32()) { @@ -739,8 +737,7 @@ static Handle<Value> Read(const Arguments& args) { char * buf = NULL; if (!Buffer::HasInstance(args[1])) { - return ThrowException(Exception::Error( - String::New("Second argument needs to be a buffer"))); + return ThrowError("Second argument needs to be a buffer"); } Local<Object> buffer_obj = args[1]->ToObject(); @@ -749,14 +746,12 @@ static Handle<Value> Read(const Arguments& args) { size_t off = args[2]->Int32Value(); if (off >= buffer_length) { - return ThrowException(Exception::Error( - String::New("Offset is out of bounds"))); + return ThrowError("Offset is out of bounds"); } len = args[3]->Int32Value(); if (off + len > buffer_length) { - return ThrowException(Exception::Error( - String::New("Length extends beyond buffer"))); + return ThrowError("Length extends beyond buffer"); } pos = GET_OFFSET(args[4]); @@ -769,8 +764,7 @@ static Handle<Value> Read(const Arguments& args) { ASYNC_CALL(read, cb, fd, buf, len, pos); } else { SYNC_CALL(read, 0, fd, buf, len, pos) - Local<Integer> bytesRead = Integer::New(SYNC_RESULT, node_isolate); - return scope.Close(bytesRead); + args.GetReturnValue().Set(SYNC_RESULT); } } @@ -778,7 +772,7 @@ static Handle<Value> Read(const Arguments& args) { /* fs.chmod(path, mode); * Wrapper for chmod(1) / EIO_CHMOD */ -static Handle<Value> Chmod(const Arguments& args) { +static void Chmod(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); if(args.Length() < 2 || !args[0]->IsString() || !args[1]->IsInt32()) { @@ -791,7 +785,6 @@ static Handle<Value> Chmod(const Arguments& args) { ASYNC_CALL(chmod, args[2], *path, mode); } else { SYNC_CALL(chmod, *path, *path, mode); - return Undefined(node_isolate); } } @@ -799,7 +792,7 @@ static Handle<Value> Chmod(const Arguments& args) { /* fs.fchmod(fd, mode); * Wrapper for fchmod(1) / EIO_FCHMOD */ -static Handle<Value> FChmod(const Arguments& args) { +static void FChmod(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); if(args.Length() < 2 || !args[0]->IsInt32() || !args[1]->IsInt32()) { @@ -812,7 +805,6 @@ static Handle<Value> FChmod(const Arguments& args) { ASYNC_CALL(fchmod, args[2], fd, mode); } else { SYNC_CALL(fchmod, 0, fd, mode); - return Undefined(node_isolate); } } @@ -820,7 +812,7 @@ static Handle<Value> FChmod(const Arguments& args) { /* fs.chown(path, uid, gid); * Wrapper for chown(1) / EIO_CHOWN */ -static Handle<Value> Chown(const Arguments& args) { +static void Chown(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); int len = args.Length(); @@ -839,7 +831,6 @@ static Handle<Value> Chown(const Arguments& args) { ASYNC_CALL(chown, args[3], *path, uid, gid); } else { SYNC_CALL(chown, *path, *path, uid, gid); - return Undefined(node_isolate); } } @@ -847,7 +838,7 @@ static Handle<Value> Chown(const Arguments& args) { /* fs.fchown(fd, uid, gid); * Wrapper for fchown(1) / EIO_FCHOWN */ -static Handle<Value> FChown(const Arguments& args) { +static void FChown(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); int len = args.Length(); @@ -866,12 +857,11 @@ static Handle<Value> FChown(const Arguments& args) { ASYNC_CALL(fchown, args[3], fd, uid, gid); } else { SYNC_CALL(fchown, 0, fd, uid, gid); - return Undefined(node_isolate); } } -static Handle<Value> UTimes(const Arguments& args) { +static void UTimes(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); int len = args.Length(); @@ -890,11 +880,10 @@ static Handle<Value> UTimes(const Arguments& args) { ASYNC_CALL(utime, args[3], *path, atime, mtime); } else { SYNC_CALL(utime, *path, *path, atime, mtime); - return Undefined(node_isolate); } } -static Handle<Value> FUTimes(const Arguments& args) { +static void FUTimes(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); int len = args.Length(); @@ -913,7 +902,6 @@ static Handle<Value> FUTimes(const Arguments& args) { ASYNC_CALL(futime, args[3], fd, atime, mtime); } else { SYNC_CALL(futime, 0, fd, atime, mtime); - return Undefined(node_isolate); } } @@ -954,15 +942,15 @@ void File::Initialize(Handle<Object> target) { void InitFs(Handle<Object> target) { HandleScope scope(node_isolate); + // Initialize the stats object - Local<FunctionTemplate> stat_templ = FunctionTemplate::New(); - stats_constructor_template = Persistent<FunctionTemplate>::New(node_isolate, - stat_templ); - target->Set(String::NewSymbol("Stats"), - stats_constructor_template->GetFunction()); + Local<Function> constructor = FunctionTemplate::New()->GetFunction(); + target->Set(String::NewSymbol("Stats"), constructor); + stats_constructor.Reset(node_isolate, constructor); + File::Initialize(target); - oncomplete_sym = NODE_PSYMBOL("oncomplete"); + oncomplete_sym = String::New("oncomplete"); StatWatcher::Initialize(target); } diff --git a/src/node_http_parser.cc b/src/node_http_parser.cc index c9391b57c..de89b4e74 100644 --- a/src/node_http_parser.cc +++ b/src/node_http_parser.cc @@ -47,26 +47,37 @@ namespace node { -using namespace v8; - -static Persistent<String> on_headers_sym; -static Persistent<String> on_headers_complete_sym; -static Persistent<String> on_body_sym; -static Persistent<String> on_message_complete_sym; - -static Persistent<String> method_sym; -static Persistent<String> status_code_sym; -static Persistent<String> http_version_sym; -static Persistent<String> version_major_sym; -static Persistent<String> version_minor_sym; -static Persistent<String> should_keep_alive_sym; -static Persistent<String> upgrade_sym; -static Persistent<String> headers_sym; -static Persistent<String> url_sym; - -static Persistent<String> unknown_method_sym; - -#define X(num, name, string) static Persistent<String> name##_sym; +using v8::Array; +using v8::Exception; +using v8::Function; +using v8::FunctionCallbackInfo; +using v8::FunctionTemplate; +using v8::Handle; +using v8::HandleScope; +using v8::Integer; +using v8::Local; +using v8::Object; +using v8::String; +using v8::Value; + +static Cached<String> on_headers_sym; +static Cached<String> on_headers_complete_sym; +static Cached<String> on_body_sym; +static Cached<String> on_message_complete_sym; + +static Cached<String> method_sym; +static Cached<String> status_code_sym; +static Cached<String> http_version_sym; +static Cached<String> version_major_sym; +static Cached<String> version_minor_sym; +static Cached<String> should_keep_alive_sym; +static Cached<String> upgrade_sym; +static Cached<String> headers_sym; +static Cached<String> url_sym; + +static Cached<String> unknown_method_sym; + +#define X(num, name, string) static Cached<String> name##_sym; HTTP_METHOD_MAP(X) #undef X @@ -97,7 +108,7 @@ static size_t current_buffer_len; int name##_(const char* at, size_t length) -static inline Persistent<String> +static inline Handle<String> method_to_str(unsigned short m) { switch (m) { #define X(num, name, string) case HTTP_##name: return name##_sym; @@ -243,7 +254,8 @@ public: HTTP_CB(on_headers_complete) { - Local<Value> cb = handle_->Get(on_headers_complete_sym); + Local<Object> obj = handle(node_isolate); + Local<Value> cb = obj->Get(on_headers_complete_sym); if (!cb->IsFunction()) return 0; @@ -288,9 +300,8 @@ public: : False(node_isolate)); Local<Value> argv[1] = { message_info }; - Local<Value> head_response = - Local<Function>::Cast(cb)->Call(handle_, 1, argv); + cb.As<Function>()->Call(obj, ARRAY_SIZE(argv), argv); if (head_response.IsEmpty()) { got_exception_ = true; @@ -304,7 +315,9 @@ public: HTTP_DATA_CB(on_body) { HandleScope scope(node_isolate); - Local<Value> cb = handle_->Get(on_body_sym); + Local<Object> obj = handle(node_isolate); + Local<Value> cb = obj->Get(on_body_sym); + if (!cb->IsFunction()) return 0; @@ -314,7 +327,7 @@ public: Integer::New(length, node_isolate) }; - Local<Value> r = Local<Function>::Cast(cb)->Call(handle_, 3, argv); + Local<Value> r = cb.As<Function>()->Call(obj, ARRAY_SIZE(argv), argv); if (r.IsEmpty()) { got_exception_ = true; @@ -331,12 +344,13 @@ public: if (num_fields_) Flush(); // Flush trailing HTTP headers. - Local<Value> cb = handle_->Get(on_message_complete_sym); + Local<Object> obj = handle(node_isolate); + Local<Value> cb = obj->Get(on_message_complete_sym); if (!cb->IsFunction()) return 0; - Local<Value> r = Local<Function>::Cast(cb)->Call(handle_, 0, NULL); + Local<Value> r = cb.As<Function>()->Call(obj, 0, NULL); if (r.IsEmpty()) { got_exception_ = true; @@ -347,21 +361,15 @@ public: } - static Handle<Value> New(const Arguments& args) { + static void New(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); http_parser_type type = static_cast<http_parser_type>(args[0]->Int32Value()); - if (type != HTTP_REQUEST && type != HTTP_RESPONSE) { - return ThrowException(Exception::Error(String::New( - "Argument must be HTTPParser.REQUEST or HTTPParser.RESPONSE"))); - } - + assert(type == HTTP_REQUEST || type == HTTP_RESPONSE); Parser* parser = new Parser(type); parser->Wrap(args.This()); - - return args.This(); } @@ -379,7 +387,7 @@ public: // var bytesParsed = parser->execute(buffer); - static Handle<Value> Execute(const Arguments& args) { + static void Execute(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Parser* parser = ObjectWrap::Unwrap<Parser>(args.This()); @@ -388,15 +396,13 @@ public: assert(!current_buffer_data); if (current_buffer) { - return ThrowException(Exception::TypeError( - String::New("Already parsing a buffer"))); + return ThrowTypeError("Already parsing a buffer"); } Local<Value> buffer_v = args[0]; if (!Buffer::HasInstance(buffer_v)) { - return ThrowException(Exception::TypeError( - String::New("Argument should be a buffer"))); + return ThrowTypeError("Argument should be a buffer"); } Local<Object> buffer_obj = buffer_v->ToObject(); @@ -420,7 +426,7 @@ public: current_buffer_data = NULL; // If there was an exception in one of the callbacks - if (parser->got_exception_) return Local<Value>(); + if (parser->got_exception_) return; Local<Integer> nparsed_obj = Integer::New(nparsed, node_isolate); // If there was a parse error in one of the callbacks @@ -432,14 +438,14 @@ public: Local<Object> obj = e->ToObject(); obj->Set(String::NewSymbol("bytesParsed"), nparsed_obj); obj->Set(String::NewSymbol("code"), String::New(http_errno_name(err))); - return scope.Close(e); + args.GetReturnValue().Set(e); } else { - return scope.Close(nparsed_obj); + args.GetReturnValue().Set(nparsed_obj); } } - static Handle<Value> Finish(const Arguments& args) { + static void Finish(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Parser* parser = ObjectWrap::Unwrap<Parser>(args.This()); @@ -449,7 +455,7 @@ public: int rv = http_parser_execute(&(parser->parser_), &settings, NULL, 0); - if (parser->got_exception_) return Local<Value>(); + if (parser->got_exception_) return; if (rv != 0) { enum http_errno err = HTTP_PARSER_ERRNO(&parser->parser_); @@ -458,28 +464,20 @@ public: Local<Object> obj = e->ToObject(); obj->Set(String::NewSymbol("bytesParsed"), Integer::New(0, node_isolate)); obj->Set(String::NewSymbol("code"), String::New(http_errno_name(err))); - return scope.Close(e); + args.GetReturnValue().Set(e); } - - return Undefined(node_isolate); } - static Handle<Value> Reinitialize(const Arguments& args) { + static void Reinitialize(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); http_parser_type type = static_cast<http_parser_type>(args[0]->Int32Value()); - if (type != HTTP_REQUEST && type != HTTP_RESPONSE) { - return ThrowException(Exception::Error(String::New( - "Argument must be HTTPParser.REQUEST or HTTPParser.RESPONSE"))); - } - + assert(type == HTTP_REQUEST || type == HTTP_RESPONSE); Parser* parser = ObjectWrap::Unwrap<Parser>(args.This()); parser->Init(type); - - return Undefined(node_isolate); } @@ -503,7 +501,8 @@ private: void Flush() { HandleScope scope(node_isolate); - Local<Value> cb = handle_->Get(on_headers_sym); + Local<Object> obj = handle(node_isolate); + Local<Value> cb = obj->Get(on_headers_sym); if (!cb->IsFunction()) return; @@ -513,7 +512,7 @@ private: url_.ToString() }; - Local<Value> r = Local<Function>::Cast(cb)->Call(handle_, 2, argv); + Local<Value> r = cb.As<Function>()->Call(obj, ARRAY_SIZE(argv), argv); if (r.IsEmpty()) got_exception_ = true; @@ -551,13 +550,10 @@ void InitHttpParser(Handle<Object> target) { t->InstanceTemplate()->SetInternalFieldCount(1); t->SetClassName(String::NewSymbol("HTTPParser")); - PropertyAttribute attrib = (PropertyAttribute) (ReadOnly | DontDelete); t->Set(String::NewSymbol("REQUEST"), - Integer::New(HTTP_REQUEST, node_isolate), - attrib); + Integer::New(HTTP_REQUEST, node_isolate)); t->Set(String::NewSymbol("RESPONSE"), - Integer::New(HTTP_RESPONSE, node_isolate), - attrib); + Integer::New(HTTP_RESPONSE, node_isolate)); NODE_SET_PROTOTYPE_METHOD(t, "execute", Parser::Execute); NODE_SET_PROTOTYPE_METHOD(t, "finish", Parser::Finish); @@ -565,25 +561,25 @@ void InitHttpParser(Handle<Object> target) { target->Set(String::NewSymbol("HTTPParser"), t->GetFunction()); - on_headers_sym = NODE_PSYMBOL("onHeaders"); - on_headers_complete_sym = NODE_PSYMBOL("onHeadersComplete"); - on_body_sym = NODE_PSYMBOL("onBody"); - on_message_complete_sym = NODE_PSYMBOL("onMessageComplete"); + on_headers_sym = String::New("onHeaders"); + on_headers_complete_sym = String::New("onHeadersComplete"); + on_body_sym = String::New("onBody"); + on_message_complete_sym = String::New("onMessageComplete"); -#define X(num, name, string) name##_sym = NODE_PSYMBOL(#string); +#define X(num, name, string) name##_sym = String::New(#string); HTTP_METHOD_MAP(X) #undef X - unknown_method_sym = NODE_PSYMBOL("UNKNOWN_METHOD"); - - method_sym = NODE_PSYMBOL("method"); - status_code_sym = NODE_PSYMBOL("statusCode"); - http_version_sym = NODE_PSYMBOL("httpVersion"); - version_major_sym = NODE_PSYMBOL("versionMajor"); - version_minor_sym = NODE_PSYMBOL("versionMinor"); - should_keep_alive_sym = NODE_PSYMBOL("shouldKeepAlive"); - upgrade_sym = NODE_PSYMBOL("upgrade"); - headers_sym = NODE_PSYMBOL("headers"); - url_sym = NODE_PSYMBOL("url"); + unknown_method_sym = String::New("UNKNOWN_METHOD"); + + method_sym = String::New("method"); + status_code_sym = String::New("statusCode"); + http_version_sym = String::New("httpVersion"); + version_major_sym = String::New("versionMajor"); + version_minor_sym = String::New("versionMinor"); + should_keep_alive_sym = String::New("shouldKeepAlive"); + upgrade_sym = String::New("upgrade"); + headers_sym = String::New("headers"); + url_sym = String::New("url"); settings.on_message_begin = Parser::on_message_begin; settings.on_url = Parser::on_url; diff --git a/src/node_internals.h b/src/node_internals.h index 9e5e0bf92..29c38adb0 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 <assert.h> #include <stdlib.h> #include "v8.h" @@ -32,7 +33,67 @@ namespace node { extern v8::Isolate* node_isolate; // Defined in node.cc at startup. -extern v8::Persistent<v8::Object> process; +extern v8::Persistent<v8::Object> process_p; + +template <typename TypeName> +class CachedBase { +public: + CachedBase(); + operator v8::Handle<TypeName>() const; + void operator=(v8::Handle<TypeName> that); // Can only assign once. + bool IsEmpty() const; +private: + CachedBase(const CachedBase&); + void operator=(const CachedBase&); + v8::Persistent<TypeName> handle_; +}; + +template <typename TypeName> +class Cached : public CachedBase<TypeName> { +public: + operator v8::Handle<v8::Value>() const; + void operator=(v8::Handle<TypeName> that); +}; + +template <> +class Cached<v8::Value> : public CachedBase<v8::Value> { +public: + operator v8::Handle<v8::Value>() const; + void operator=(v8::Handle<v8::Value> that); +}; + +template <typename TypeName> +v8::Handle<v8::Value> MakeCallback( + const v8::Persistent<v8::Object>& recv, + const TypeName method, + int argc, + v8::Handle<v8::Value>* argv); + +template <typename TypeName> +v8::Handle<v8::Value> MakeCallback( + const v8::Persistent<v8::Object>& recv, + const Cached<TypeName>& method, + int argc, + v8::Handle<v8::Value>* argv); + +inline bool HasInstance(v8::Persistent<v8::FunctionTemplate>& function_template, + v8::Handle<v8::Value> value); + +inline v8::Local<v8::Object> NewInstance(v8::Persistent<v8::Function>& ctor, + int argc = 0, + v8::Handle<v8::Value>* 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 <typename TypeName> +inline char* Data(v8::Persistent<TypeName>& val); + +template <typename TypeName> +inline size_t Length(v8::Persistent<TypeName>& 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<v8::Value> ThrowError(const char* errmsg) { +inline static void ThrowError(const char* errmsg) { THROW_ERROR(v8::Exception::Error); } -inline static v8::Handle<v8::Value> ThrowTypeError(const char* errmsg) { +inline static void ThrowTypeError(const char* errmsg) { THROW_ERROR(v8::Exception::TypeError); } -inline static v8::Handle<v8::Value> 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<v8::Value> 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<v8::Value> 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<v8::Value> FromConstructorTemplate( - v8::Persistent<v8::FunctionTemplate> 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<v8::Value> arg, return true; } +template <typename TypeName> +CachedBase<TypeName>::CachedBase() { +} + +template <typename TypeName> +CachedBase<TypeName>::operator v8::Handle<TypeName>() const { + return v8::Local<TypeName>::New(node_isolate, handle_); +} + +template <typename TypeName> +void CachedBase<TypeName>::operator=(v8::Handle<TypeName> that) { + assert(handle_.IsEmpty() == true); // Can only assign once. + handle_.Reset(node_isolate, that); +} + +template <typename TypeName> +bool CachedBase<TypeName>::IsEmpty() const { + return handle_.IsEmpty(); +} + +template <typename TypeName> +Cached<TypeName>::operator v8::Handle<v8::Value>() const { + return CachedBase<TypeName>::operator v8::Handle<TypeName>(); +} + +template <typename TypeName> +void Cached<TypeName>::operator=(v8::Handle<TypeName> that) { + CachedBase<TypeName>::operator=(that); +} + +inline Cached<v8::Value>::operator v8::Handle<v8::Value>() const { + return CachedBase<v8::Value>::operator v8::Handle<v8::Value>(); +} + +inline void Cached<v8::Value>::operator=(v8::Handle<v8::Value> that) { + CachedBase<v8::Value>::operator=(that); +} + +// Forward declarations, see node.h +NODE_EXTERN v8::Handle<v8::Value> MakeCallback( + const v8::Handle<v8::Object> recv, + const char* method, + int argc, + v8::Handle<v8::Value>* argv); +NODE_EXTERN v8::Handle<v8::Value> MakeCallback( + const v8::Handle<v8::Object> object, + const v8::Handle<v8::String> symbol, + int argc, + v8::Handle<v8::Value>* argv); +NODE_EXTERN v8::Handle<v8::Value> MakeCallback( + const v8::Handle<v8::Object> object, + const v8::Handle<v8::Function> callback, + int argc, + v8::Handle<v8::Value>* argv); + +template <typename TypeName> +v8::Handle<v8::Value> MakeCallback( + const v8::Persistent<v8::Object>& recv, + const TypeName method, + int argc, + v8::Handle<v8::Value>* argv) { + v8::Local<v8::Object> recv_obj = + v8::Local<v8::Object>::New(node_isolate, recv); + return MakeCallback(recv_obj, method, argc, argv); +} + +template <typename TypeName> +v8::Handle<v8::Value> MakeCallback( + const v8::Persistent<v8::Object>& recv, + const Cached<TypeName>& method, + int argc, + v8::Handle<v8::Value>* argv) { + const v8::Handle<TypeName> handle = method; + return MakeCallback(recv, handle, argc, argv); +} + +inline bool HasInstance(v8::Persistent<v8::FunctionTemplate>& function_template, + v8::Handle<v8::Value> value) { + v8::Local<v8::FunctionTemplate> function_template_handle = + v8::Local<v8::FunctionTemplate>::New(node_isolate, function_template); + return function_template_handle->HasInstance(value); +} + +inline v8::Local<v8::Object> NewInstance(v8::Persistent<v8::Function>& ctor, + int argc, + v8::Handle<v8::Value>* argv) { + v8::Local<v8::Function> constructor_handle = + v8::Local<v8::Function>::New(node_isolate, ctor); + return constructor_handle->NewInstance(argc, argv); +} + +namespace Buffer { + +template <typename TypeName> +inline char* Data(v8::Persistent<TypeName>& val) { + NODE_EXTERN char* Data(v8::Handle<v8::Value>); + NODE_EXTERN char* Data(v8::Handle<v8::Object>); + return Data(v8::Local<TypeName>::New(node_isolate, val)); +} + +template <typename TypeName> +inline size_t Length(v8::Persistent<TypeName>& val) { + NODE_EXTERN size_t Length(v8::Handle<v8::Value>); + NODE_EXTERN size_t Length(v8::Handle<v8::Object>); + return Length(v8::Local<TypeName>::New(node_isolate, val)); +} + +} // namespace Buffer + } // namespace node #endif // SRC_NODE_INTERNALS_H_ diff --git a/src/node_object_wrap.h b/src/node_object_wrap.h index 19f536dfe..990c82b1d 100644 --- a/src/node_object_wrap.h +++ b/src/node_object_wrap.h @@ -38,49 +38,56 @@ namespace node { class NODE_EXTERN ObjectWrap { - public: - ObjectWrap ( ) { +public: + ObjectWrap() { refs_ = 0; } - virtual ~ObjectWrap ( ) { - if (!handle_.IsEmpty()) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); - assert(handle_.IsNearDeath(isolate)); - handle_.ClearWeak(isolate); - handle_->SetAlignedPointerInInternalField(0, 0); - handle_.Dispose(isolate); - handle_.Clear(); - } + virtual ~ObjectWrap() { + if (persistent().IsEmpty()) return; + assert(persistent().IsNearDeath()); + persistent().ClearWeak(); + persistent().Dispose(); } template <class T> - static inline T* Unwrap (v8::Handle<v8::Object> handle) { + static inline T* Unwrap(v8::Handle<v8::Object> handle) { assert(!handle.IsEmpty()); assert(handle->InternalFieldCount() > 0); return static_cast<T*>(handle->GetAlignedPointerFromInternalField(0)); } - v8::Persistent<v8::Object> handle_; // ro + inline v8::Local<v8::Object> handle() { + return handle(v8::Isolate::GetCurrent()); + } + + + inline v8::Local<v8::Object> handle(v8::Isolate* isolate) { + return v8::Local<v8::Object>::New(isolate, persistent()); + } + - protected: - inline void Wrap (v8::Handle<v8::Object> handle) { - assert(handle_.IsEmpty()); + inline v8::Persistent<v8::Object>& persistent() { + return handle_; + } + + +protected: + inline void Wrap(v8::Handle<v8::Object> handle) { + assert(persistent().IsEmpty()); assert(handle->InternalFieldCount() > 0); - v8::Isolate* isolate = v8::Isolate::GetCurrent(); - handle_ = v8::Persistent<v8::Object>::New(isolate, handle); - handle_->SetAlignedPointerInInternalField(0, this); + handle->SetAlignedPointerInInternalField(0, this); + persistent().Reset(v8::Isolate::GetCurrent(), handle); MakeWeak(); } - inline void MakeWeak (void) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); - handle_.MakeWeak(isolate, this, WeakCallback); - handle_.MarkIndependent(isolate); + inline void MakeWeak(void) { + persistent().MakeWeak(this, WeakCallback); + persistent().MarkIndependent(); } /* Ref() marks the object as being attached to an event loop. @@ -88,9 +95,9 @@ class NODE_EXTERN ObjectWrap { * all references are lost. */ virtual void Ref() { - assert(!handle_.IsEmpty()); + assert(!persistent().IsEmpty()); + persistent().ClearWeak(); refs_++; - handle_.ClearWeak(v8::Isolate::GetCurrent()); } /* Unref() marks an object as detached from the event loop. This is its @@ -103,26 +110,26 @@ class NODE_EXTERN ObjectWrap { * DO NOT CALL THIS FROM DESTRUCTOR */ virtual void Unref() { - assert(!handle_.IsEmpty()); - assert(!handle_.IsWeak(v8::Isolate::GetCurrent())); + assert(!persistent().IsEmpty()); + assert(!persistent().IsWeak()); assert(refs_ > 0); - if (--refs_ == 0) { MakeWeak(); } + if (--refs_ == 0) MakeWeak(); } + int refs_; // ro - int refs_; // ro - - - private: +private: static void WeakCallback(v8::Isolate* isolate, v8::Persistent<v8::Object>* pobj, ObjectWrap* wrap) { v8::HandleScope scope(isolate); assert(wrap->refs_ == 0); - assert(*pobj == wrap->handle_); - assert((*pobj).IsNearDeath(isolate)); + assert(*pobj == wrap->persistent()); + assert((*pobj).IsNearDeath()); delete wrap; } + + v8::Persistent<v8::Object> handle_; }; } // namespace node diff --git a/src/node_os.cc b/src/node_os.cc index 9bff7e6b0..6e11002be 100644 --- a/src/node_os.cc +++ b/src/node_os.cc @@ -46,81 +46,95 @@ namespace node { -using namespace v8; - -static Handle<Value> GetEndianness(const Arguments& args) { +using v8::Array; +using v8::FunctionCallbackInfo; +using v8::HandleScope; +using v8::Integer; +using v8::Local; +using v8::Number; +using v8::Object; +using v8::String; +using v8::Value; + + +static void GetEndianness(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); - return scope.Close(String::New(IsBigEndian() ? "BE" : "LE")); + const char* rval = IsBigEndian() ? "BE" : "LE"; + args.GetReturnValue().Set(String::New(rval)); } -static Handle<Value> GetHostname(const Arguments& args) { + +static void GetHostname(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); char buf[MAXHOSTNAMELEN + 1]; if (gethostname(buf, sizeof(buf))) { #ifdef __POSIX__ - return ThrowException(ErrnoException(errno, "gethostname")); + int errorno = errno; #else // __MINGW32__ - return ThrowException(ErrnoException(WSAGetLastError(), "gethostname")); + int errorno = WSAGetLastError(); #endif // __MINGW32__ + return ThrowErrnoException(errorno, "gethostname"); } buf[sizeof(buf) - 1] = '\0'; - return scope.Close(String::New(buf)); + args.GetReturnValue().Set(String::New(buf)); } -static Handle<Value> GetOSType(const Arguments& args) { + +static void GetOSType(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); + const char* rval; #ifdef __POSIX__ struct utsname info; if (uname(&info) < 0) { - return ThrowException(ErrnoException(errno, "uname")); + return ThrowErrnoException(errno, "uname"); } - return scope.Close(String::New(info.sysname)); + rval = info.sysname; #else // __MINGW32__ - return scope.Close(String::New("Windows_NT")); + rval ="Windows_NT"; #endif + + args.GetReturnValue().Set(String::New(rval)); } -static Handle<Value> GetOSRelease(const Arguments& args) { + +static void GetOSRelease(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); + const char* rval; #ifdef __POSIX__ struct utsname info; if (uname(&info) < 0) { - return ThrowException(ErrnoException(errno, "uname")); + return ThrowErrnoException(errno, "uname"); } - return scope.Close(String::New(info.release)); + rval = info.release; #else // __MINGW32__ char release[256]; OSVERSIONINFO info; - info.dwOSVersionInfoSize = sizeof(info); - if (GetVersionEx(&info) == 0) { - return Undefined(node_isolate); - } + info.dwOSVersionInfoSize = sizeof(info); + if (GetVersionEx(&info) == 0) return; sprintf(release, "%d.%d.%d", static_cast<int>(info.dwMajorVersion), static_cast<int>(info.dwMinorVersion), static_cast<int>(info.dwBuildNumber)); - return scope.Close(String::New(release)); + rval = release; #endif + args.GetReturnValue().Set(String::New(rval)); } -static Handle<Value> GetCPUInfo(const Arguments& args) { + +static void GetCPUInfo(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); uv_cpu_info_t* cpu_infos; int count, i; uv_err_t err = uv_cpu_info(&cpu_infos, &count); - - if (err.code != UV_OK) { - return Undefined(node_isolate); - } + if (err.code != UV_OK) return; Local<Array> cpus = Array::New(); - for (i = 0; i < count; i++) { Local<Object> times_info = Object::New(); times_info->Set(String::New("user"), @@ -143,60 +157,48 @@ static Handle<Value> GetCPUInfo(const Arguments& args) { } uv_free_cpu_info(cpu_infos, count); - - return scope.Close(cpus); + args.GetReturnValue().Set(cpus); } -static Handle<Value> GetFreeMemory(const Arguments& args) { + +static void GetFreeMemory(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); double amount = uv_get_free_memory(); - - if (amount < 0) { - return Undefined(node_isolate); - } - - return scope.Close(Number::New(amount)); + if (amount < 0) return; + args.GetReturnValue().Set(amount); } -static Handle<Value> GetTotalMemory(const Arguments& args) { + +static void GetTotalMemory(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); double amount = uv_get_total_memory(); - - if (amount < 0) { - return Undefined(node_isolate); - } - - return scope.Close(Number::New(amount)); + if (amount < 0) return; + args.GetReturnValue().Set(amount); } -static Handle<Value> GetUptime(const Arguments& args) { + +static void GetUptime(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); double uptime; - uv_err_t err = uv_uptime(&uptime); - - if (err.code != UV_OK) { - return Undefined(node_isolate); - } - - return scope.Close(Number::New(uptime)); + if (err.code != UV_OK) return; + args.GetReturnValue().Set(uptime); } -static Handle<Value> GetLoadAvg(const Arguments& args) { + +static void GetLoadAvg(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); double loadavg[3]; uv_loadavg(loadavg); - Local<Array> loads = Array::New(3); loads->Set(0, Number::New(loadavg[0])); loads->Set(1, Number::New(loadavg[1])); loads->Set(2, Number::New(loadavg[2])); - - return scope.Close(loads); + args.GetReturnValue().Set(loads); } -static Handle<Value> GetInterfaceAddresses(const Arguments& args) { +static void GetInterfaceAddresses(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); uv_interface_address_t* interfaces; int count, i; @@ -207,9 +209,9 @@ static Handle<Value> GetInterfaceAddresses(const Arguments& args) { Local<Array> ifarr; uv_err_t err = uv_interface_addresses(&interfaces, &count); - - if (err.code != UV_OK) - return ThrowException(UVException(err.code, "uv_interface_addresses")); + if (err.code != UV_OK) { + return ThrowUVException(err.code, "uv_interface_addresses"); + } ret = Object::New(); @@ -248,8 +250,7 @@ static Handle<Value> GetInterfaceAddresses(const Arguments& args) { } uv_free_interface_addresses(interfaces, count); - - return scope.Close(ret); + args.GetReturnValue().Set(ret); } diff --git a/src/node_script.cc b/src/node_script.cc index 4766cd05a..0e98f0676 100644 --- a/src/node_script.cc +++ b/src/node_script.cc @@ -26,11 +26,11 @@ namespace node { -using v8::Arguments; using v8::Array; using v8::Context; using v8::Exception; using v8::Function; +using v8::FunctionCallbackInfo; using v8::FunctionTemplate; using v8::Handle; using v8::HandleScope; @@ -39,7 +39,6 @@ using v8::Object; using v8::Persistent; using v8::Script; using v8::String; -using v8::ThrowException; using v8::TryCatch; using v8::V8; using v8::Value; @@ -48,9 +47,9 @@ using v8::Value; class WrappedContext : ObjectWrap { public: static void Initialize(Handle<Object> target); - static Handle<Value> New(const Arguments& args); + static void New(const FunctionCallbackInfo<Value>& args); - Persistent<Context> GetV8Context(); + Local<Context> GetV8Context(); static Local<Object> NewInstance(); static bool InstanceOf(Handle<Value> value); @@ -81,57 +80,55 @@ class WrappedScript : ObjectWrap { EvalContextFlags context_flag, EvalOutputFlags output_flag, EvalTimeoutFlags timeout_flag> - static Handle<Value> EvalMachine(const Arguments& args); + static void EvalMachine(const FunctionCallbackInfo<Value>& args); protected: - static Persistent<FunctionTemplate> constructor_template; - WrappedScript() : ObjectWrap() {} ~WrappedScript(); - static Handle<Value> New(const Arguments& args); - static Handle<Value> CreateContext(const Arguments& arg); - static Handle<Value> RunInContext(const Arguments& args); - static Handle<Value> RunInThisContext(const Arguments& args); - static Handle<Value> RunInNewContext(const Arguments& args); - static Handle<Value> CompileRunInContext(const Arguments& args); - static Handle<Value> CompileRunInThisContext(const Arguments& args); - static Handle<Value> CompileRunInNewContext(const Arguments& args); + static void New(const FunctionCallbackInfo<Value>& args); + static void CreateContext(const FunctionCallbackInfo<Value>& args); + static void RunInContext(const FunctionCallbackInfo<Value>& args); + static void RunInThisContext(const FunctionCallbackInfo<Value>& args); + static void RunInNewContext(const FunctionCallbackInfo<Value>& args); + static void CompileRunInContext(const FunctionCallbackInfo<Value>& args); + static void CompileRunInThisContext(const FunctionCallbackInfo<Value>& args); + static void CompileRunInNewContext(const FunctionCallbackInfo<Value>& args); Persistent<Script> script_; }; -Persistent<Function> cloneObjectMethod; - void CloneObject(Handle<Object> recv, - Handle<Value> source, Handle<Value> target) { + Handle<Value> source, + Handle<Value> target) { HandleScope scope(node_isolate); - Handle<Value> args[] = {source, target}; - - // Init - if (cloneObjectMethod.IsEmpty()) { - Local<Function> cloneObjectMethod_ = Local<Function>::Cast( - Script::Compile(String::New( - "(function(source, target) {\n\ - Object.getOwnPropertyNames(source).forEach(function(key) {\n\ - try {\n\ - var desc = Object.getOwnPropertyDescriptor(source, key);\n\ - if (desc.value === source) desc.value = target;\n\ - Object.defineProperty(target, key, desc);\n\ - } catch (e) {\n\ - // Catch sealed properties errors\n\ - }\n\ - });\n\ - })" - ), String::New("binding:script"))->Run() - ); - cloneObjectMethod = Persistent<Function>::New(node_isolate, - cloneObjectMethod_); - } - - cloneObjectMethod->Call(recv, 2, args); + const char raw_script_source[] = + "(function(source, target) { \n" + " Object.getOwnPropertyNames(source).forEach(function(key) { \n" + " try { \n" + " var desc = Object.getOwnPropertyDescriptor(source, key); \n" + " if (desc.value === source) desc.value = target; \n" + " Object.defineProperty(target, key, desc); \n" + " } catch (e) { \n" + " // Catch sealed properties errors \n" + " } \n" + " }); \n" + "}); \n"; + + Local<String> script_source = + String::New(raw_script_source, sizeof(raw_script_source) - 1); + Local<Script> script = + Script::Compile(script_source, String::New("binding:script")); + + Local<Function> fun = script->Run().As<Function>(); + assert(fun.IsEmpty() == false); + assert(fun->IsFunction() == true); + + Handle<Value> argv[] = { source, target }; + Handle<Value> rc = fun->Call(recv, ARRAY_SIZE(argv), argv); + assert(rc.IsEmpty() == false); } @@ -139,124 +136,110 @@ void WrappedContext::Initialize(Handle<Object> target) { HandleScope scope(node_isolate); Local<FunctionTemplate> t = FunctionTemplate::New(WrappedContext::New); - constructor_template = Persistent<FunctionTemplate>::New(node_isolate, t); - constructor_template->InstanceTemplate()->SetInternalFieldCount(1); - constructor_template->SetClassName(String::NewSymbol("Context")); + t->InstanceTemplate()->SetInternalFieldCount(1); + t->SetClassName(String::NewSymbol("Context")); - target->Set(String::NewSymbol("Context"), - constructor_template->GetFunction()); + target->Set(String::NewSymbol("Context"), t->GetFunction()); + constructor_template.Reset(node_isolate, t); } bool WrappedContext::InstanceOf(Handle<Value> value) { - return !value.IsEmpty() && constructor_template->HasInstance(value); + return !value.IsEmpty() && HasInstance(constructor_template, value); } -Handle<Value> WrappedContext::New(const Arguments& args) { +void WrappedContext::New(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); - WrappedContext *t = new WrappedContext(); t->Wrap(args.This()); - - return args.This(); } WrappedContext::WrappedContext() : ObjectWrap() { - context_ = Persistent<Context>::New(node_isolate, Context::New(node_isolate)); + context_.Reset(node_isolate, Context::New(node_isolate)); } WrappedContext::~WrappedContext() { - context_.Dispose(node_isolate); + context_.Dispose(); } Local<Object> WrappedContext::NewInstance() { - Local<Object> context = constructor_template->GetFunction()->NewInstance(); - return context; + Local<FunctionTemplate> constructor_template_handle = + Local<FunctionTemplate>::New(node_isolate, constructor_template); + return constructor_template_handle->GetFunction()->NewInstance(); } -Persistent<Context> WrappedContext::GetV8Context() { - return context_; +Local<Context> WrappedContext::GetV8Context() { + return Local<Context>::New(node_isolate, context_); } -Persistent<FunctionTemplate> WrappedScript::constructor_template; - - void WrappedScript::Initialize(Handle<Object> target) { HandleScope scope(node_isolate); Local<FunctionTemplate> t = FunctionTemplate::New(WrappedScript::New); - constructor_template = Persistent<FunctionTemplate>::New(node_isolate, t); - constructor_template->InstanceTemplate()->SetInternalFieldCount(1); + t->InstanceTemplate()->SetInternalFieldCount(1); // Note: We use 'NodeScript' instead of 'Script' so that we do not // conflict with V8's Script class defined in v8/src/messages.js // See GH-203 https://github.com/joyent/node/issues/203 - constructor_template->SetClassName(String::NewSymbol("NodeScript")); + t->SetClassName(String::NewSymbol("NodeScript")); - NODE_SET_PROTOTYPE_METHOD(constructor_template, + NODE_SET_PROTOTYPE_METHOD(t, "createContext", WrappedScript::CreateContext); - NODE_SET_PROTOTYPE_METHOD(constructor_template, + NODE_SET_PROTOTYPE_METHOD(t, "runInContext", WrappedScript::RunInContext); - NODE_SET_PROTOTYPE_METHOD(constructor_template, + NODE_SET_PROTOTYPE_METHOD(t, "runInThisContext", WrappedScript::RunInThisContext); - NODE_SET_PROTOTYPE_METHOD(constructor_template, + NODE_SET_PROTOTYPE_METHOD(t, "runInNewContext", WrappedScript::RunInNewContext); - NODE_SET_METHOD(constructor_template, + NODE_SET_METHOD(t, "createContext", WrappedScript::CreateContext); - NODE_SET_METHOD(constructor_template, + NODE_SET_METHOD(t, "runInContext", WrappedScript::CompileRunInContext); - NODE_SET_METHOD(constructor_template, + NODE_SET_METHOD(t, "runInThisContext", WrappedScript::CompileRunInThisContext); - NODE_SET_METHOD(constructor_template, + NODE_SET_METHOD(t, "runInNewContext", WrappedScript::CompileRunInNewContext); - target->Set(String::NewSymbol("NodeScript"), - constructor_template->GetFunction()); + target->Set(String::NewSymbol("NodeScript"), t->GetFunction()); } -Handle<Value> WrappedScript::New(const Arguments& args) { - if (!args.IsConstructCall()) { - return FromConstructorTemplate(constructor_template, args); - } - +void WrappedScript::New(const FunctionCallbackInfo<Value>& args) { + assert(args.IsConstructCall() == true); HandleScope scope(node_isolate); - WrappedScript *t = new WrappedScript(); t->Wrap(args.This()); - - return - WrappedScript::EvalMachine< + WrappedScript::EvalMachine< compileCode, thisContext, wrapExternal, noTimeout>(args); } WrappedScript::~WrappedScript() { - script_.Dispose(node_isolate); + script_.Dispose(); } -Handle<Value> WrappedScript::CreateContext(const Arguments& args) { +void WrappedScript::CreateContext(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Local<Object> context = WrappedContext::NewInstance(); @@ -267,54 +250,50 @@ Handle<Value> WrappedScript::CreateContext(const Arguments& args) { CloneObject(args.This(), sandbox, context); } else { - return ThrowException(Exception::TypeError(String::New( - "createContext() accept only object as first argument."))); + return ThrowTypeError( + "createContext() accept only object as first argument."); } } - - return scope.Close(context); + args.GetReturnValue().Set(context); } -Handle<Value> WrappedScript::RunInContext(const Arguments& args) { - return - WrappedScript::EvalMachine< +void WrappedScript::RunInContext(const FunctionCallbackInfo<Value>& args) { + WrappedScript::EvalMachine< unwrapExternal, userContext, returnResult, useTimeout>(args); } -Handle<Value> WrappedScript::RunInThisContext(const Arguments& args) { - return - WrappedScript::EvalMachine< +void WrappedScript::RunInThisContext(const FunctionCallbackInfo<Value>& args) { + WrappedScript::EvalMachine< unwrapExternal, thisContext, returnResult, useTimeout>(args); } -Handle<Value> WrappedScript::RunInNewContext(const Arguments& args) { - return - WrappedScript::EvalMachine< +void WrappedScript::RunInNewContext(const FunctionCallbackInfo<Value>& args) { + WrappedScript::EvalMachine< unwrapExternal, newContext, returnResult, useTimeout>(args); } -Handle<Value> WrappedScript::CompileRunInContext(const Arguments& args) { - return - WrappedScript::EvalMachine< +void WrappedScript::CompileRunInContext( + const FunctionCallbackInfo<Value>& args) { + WrappedScript::EvalMachine< compileCode, userContext, returnResult, useTimeout>(args); } -Handle<Value> WrappedScript::CompileRunInThisContext(const Arguments& args) { - return - WrappedScript::EvalMachine< +void WrappedScript::CompileRunInThisContext( + const FunctionCallbackInfo<Value>& args) { + WrappedScript::EvalMachine< compileCode, thisContext, returnResult, useTimeout>(args); } -Handle<Value> WrappedScript::CompileRunInNewContext(const Arguments& args) { - return - WrappedScript::EvalMachine< +void WrappedScript::CompileRunInNewContext( + const FunctionCallbackInfo<Value>& args) { + WrappedScript::EvalMachine< compileCode, newContext, returnResult, useTimeout>(args); } @@ -323,23 +302,20 @@ template <WrappedScript::EvalInputFlags input_flag, WrappedScript::EvalContextFlags context_flag, WrappedScript::EvalOutputFlags output_flag, WrappedScript::EvalTimeoutFlags timeout_flag> -Handle<Value> WrappedScript::EvalMachine(const Arguments& args) { +void WrappedScript::EvalMachine(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); if (input_flag == compileCode && args.Length() < 1) { - return ThrowException(Exception::TypeError( - String::New("needs at least 'code' argument."))); + return ThrowTypeError("needs at least 'code' argument."); } const int sandbox_index = input_flag == compileCode ? 1 : 0; if (context_flag == userContext && !WrappedContext::InstanceOf(args[sandbox_index])) { - return ThrowException(Exception::TypeError( - String::New("needs a 'context' argument."))); + return ThrowTypeError("needs a 'context' argument."); } - Local<String> code; if (input_flag == compileCode) code = args[0]->ToString(); @@ -361,8 +337,7 @@ Handle<Value> WrappedScript::EvalMachine(const Arguments& args) { const int timeout_index = filename_index + 1; if (timeout_flag == useTimeout && args.Length() > timeout_index) { if (!args[timeout_index]->IsUint32()) { - return ThrowException(Exception::TypeError( - String::New("needs an unsigned integer 'ms' argument."))); + return ThrowTypeError("needs an unsigned integer 'ms' argument."); } timeout = args[timeout_index]->Uint32Value(); } @@ -376,7 +351,7 @@ Handle<Value> WrappedScript::EvalMachine(const Arguments& args) { display_error = true; } - Handle<Context> context = Context::GetCurrent(); + Local<Context> context = Context::GetCurrent(); Local<Array> keys; if (context_flag == newContext) { @@ -406,7 +381,7 @@ Handle<Value> WrappedScript::EvalMachine(const Arguments& args) { try_catch.SetVerbose(false); Handle<Value> result; - Handle<Script> script; + Local<Script> script; if (input_flag == compileCode) { // well, here WrappedScript::New would suffice in all cases, but maybe @@ -418,23 +393,21 @@ Handle<Value> WrappedScript::EvalMachine(const Arguments& args) { if (display_error) DisplayExceptionLine(try_catch.Message()); // Hack because I can't get a proper stacktrace on SyntaxError - return try_catch.ReThrow(); + try_catch.ReThrow(); + return; } } else { WrappedScript *n_script = ObjectWrap::Unwrap<WrappedScript>(args.This()); if (!n_script) { - return ThrowException(Exception::Error( - String::New("Must be called as a method of Script."))); + return ThrowError("Must be called as a method of Script."); } else if (n_script->script_.IsEmpty()) { - return ThrowException(Exception::Error( - String::New("'this' must be a result of previous " - "new Script(code) call."))); + return ThrowError( + "'this' must be a result of previous new Script(code) call."); } - script = n_script->script_; + script = Local<Script>::New(node_isolate, n_script->script_); } - if (output_flag == returnResult) { if (timeout) { Watchdog wd(timeout); @@ -444,20 +417,19 @@ Handle<Value> WrappedScript::EvalMachine(const Arguments& args) { } if (try_catch.HasCaught() && try_catch.HasTerminated()) { V8::CancelTerminateExecution(args.GetIsolate()); - return ThrowException(Exception::Error( - String::New("Script execution timed out."))); + return ThrowError("Script execution timed out."); } if (result.IsEmpty()) { if (display_error) DisplayExceptionLine(try_catch.Message()); - return try_catch.ReThrow(); + try_catch.ReThrow(); + return; } } else { WrappedScript *n_script = ObjectWrap::Unwrap<WrappedScript>(args.This()); if (!n_script) { - return ThrowException(Exception::Error( - String::New("Must be called as a method of Script."))); + return ThrowError("Must be called as a method of Script."); } - n_script->script_ = Persistent<Script>::New(node_isolate, script); + n_script->script_.Reset(node_isolate, script); result = args.This(); } @@ -466,13 +438,12 @@ Handle<Value> WrappedScript::EvalMachine(const Arguments& args) { CloneObject(args.This(), context->Global()->GetPrototype(), sandbox); } - return result == args.This() ? result : scope.Close(result); + args.GetReturnValue().Set(result); } void InitEvals(Handle<Object> target) { HandleScope scope(node_isolate); - WrappedContext::Initialize(target); WrappedScript::Initialize(target); } @@ -480,6 +451,4 @@ void InitEvals(Handle<Object> target) { } // namespace node - NODE_MODULE(node_evals, node::InitEvals) - diff --git a/src/node_stat_watcher.cc b/src/node_stat_watcher.cc index aa6ccf952..07ba5efce 100644 --- a/src/node_stat_watcher.cc +++ b/src/node_stat_watcher.cc @@ -27,25 +27,31 @@ namespace node { -using namespace v8; +using v8::FunctionCallbackInfo; +using v8::FunctionTemplate; +using v8::Handle; +using v8::HandleScope; +using v8::Integer; +using v8::Local; +using v8::Object; +using v8::String; +using v8::Value; -Persistent<FunctionTemplate> StatWatcher::constructor_template; -static Persistent<String> onchange_sym; -static Persistent<String> onstop_sym; +static Cached<String> onchange_sym; +static Cached<String> onstop_sym; void StatWatcher::Initialize(Handle<Object> target) { HandleScope scope(node_isolate); Local<FunctionTemplate> t = FunctionTemplate::New(StatWatcher::New); - constructor_template = Persistent<FunctionTemplate>::New(node_isolate, t); - constructor_template->InstanceTemplate()->SetInternalFieldCount(1); - constructor_template->SetClassName(String::NewSymbol("StatWatcher")); + t->InstanceTemplate()->SetInternalFieldCount(1); + t->SetClassName(String::NewSymbol("StatWatcher")); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "start", StatWatcher::Start); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "stop", StatWatcher::Stop); + NODE_SET_PROTOTYPE_METHOD(t, "start", StatWatcher::Start); + NODE_SET_PROTOTYPE_METHOD(t, "stop", StatWatcher::Stop); - target->Set(String::NewSymbol("StatWatcher"), constructor_template->GetFunction()); + target->Set(String::NewSymbol("StatWatcher"), t->GetFunction()); } @@ -84,22 +90,24 @@ void StatWatcher::Callback(uv_fs_poll_t* handle, SetErrno(uv_last_error(wrap->watcher_->loop)); } if (onchange_sym.IsEmpty()) { - onchange_sym = NODE_PSYMBOL("onchange"); + onchange_sym = String::New("onchange"); } - MakeCallback(wrap->handle_, onchange_sym, ARRAY_SIZE(argv), argv); + MakeCallback(wrap->handle(node_isolate), + onchange_sym, + ARRAY_SIZE(argv), + argv); } -Handle<Value> StatWatcher::New(const Arguments& args) { +void StatWatcher::New(const FunctionCallbackInfo<Value>& args) { assert(args.IsConstructCall()); HandleScope scope(node_isolate); StatWatcher* s = new StatWatcher(); s->Wrap(args.This()); - return args.This(); } -Handle<Value> StatWatcher::Start(const Arguments& args) { +void StatWatcher::Start(const FunctionCallbackInfo<Value>& args) { assert(args.Length() == 3); HandleScope scope(node_isolate); @@ -111,20 +119,17 @@ Handle<Value> StatWatcher::Start(const Arguments& args) { if (!persistent) uv_unref(reinterpret_cast<uv_handle_t*>(wrap->watcher_)); uv_fs_poll_start(wrap->watcher_, Callback, *path, interval); wrap->Ref(); - - return Undefined(node_isolate); } -Handle<Value> StatWatcher::Stop(const Arguments& args) { +void StatWatcher::Stop(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); StatWatcher* wrap = ObjectWrap::Unwrap<StatWatcher>(args.This()); if (onstop_sym.IsEmpty()) { - onstop_sym = NODE_PSYMBOL("onstop"); + onstop_sym = String::New("onstop"); } - MakeCallback(wrap->handle_, onstop_sym, 0, NULL); + MakeCallback(wrap->handle(node_isolate), onstop_sym, 0, NULL); wrap->Stop(); - return Undefined(node_isolate); } diff --git a/src/node_stat_watcher.h b/src/node_stat_watcher.h index 94ed10a0e..9fd582061 100644 --- a/src/node_stat_watcher.h +++ b/src/node_stat_watcher.h @@ -37,9 +37,9 @@ class StatWatcher : ObjectWrap { StatWatcher(); virtual ~StatWatcher(); - static v8::Handle<v8::Value> New(const v8::Arguments& args); - static v8::Handle<v8::Value> Start(const v8::Arguments& args); - static v8::Handle<v8::Value> Stop(const v8::Arguments& args); + static void New(const v8::FunctionCallbackInfo<v8::Value>& args); + static void Start(const v8::FunctionCallbackInfo<v8::Value>& args); + static void Stop(const v8::FunctionCallbackInfo<v8::Value>& args); private: static void Callback(uv_fs_poll_t* handle, diff --git a/src/node_wrap.h b/src/node_wrap.h index 1b7b45162..ff7179fdb 100644 --- a/src/node_wrap.h +++ b/src/node_wrap.h @@ -39,15 +39,15 @@ extern v8::Persistent<v8::FunctionTemplate> tcpConstructorTmpl; #define WITH_GENERIC_STREAM(obj, BODY) \ do { \ if (!tcpConstructorTmpl.IsEmpty() && \ - tcpConstructorTmpl->HasInstance(obj)) { \ + HasInstance(tcpConstructorTmpl, obj)) { \ PipeWrap* wrap = PipeWrap::Unwrap(obj); \ BODY \ } else if (!ttyConstructorTmpl.IsEmpty() && \ - ttyConstructorTmpl->HasInstance(obj)) { \ + HasInstance(ttyConstructorTmpl, obj)) { \ TTYWrap* wrap = TTYWrap::Unwrap(obj); \ BODY \ } else if (!pipeConstructorTmpl.IsEmpty() && \ - pipeConstructorTmpl->HasInstance(obj)) { \ + HasInstance(pipeConstructorTmpl, obj)) { \ TCPWrap* wrap = TCPWrap::Unwrap(obj); \ BODY \ } \ diff --git a/src/node_zlib.cc b/src/node_zlib.cc index 9bfc33e58..07f44d126 100644 --- a/src/node_zlib.cc +++ b/src/node_zlib.cc @@ -32,11 +32,20 @@ namespace node { -using namespace v8; +using v8::FunctionCallbackInfo; +using v8::FunctionTemplate; +using v8::Handle; +using v8::HandleScope; +using v8::Integer; +using v8::Local; +using v8::Number; +using v8::Object; +using v8::String; +using v8::Value; -static Persistent<String> callback_sym; -static Persistent<String> onerror_sym; +static Cached<String> callback_sym; +static Cached<String> onerror_sym; enum node_zlib_mode { NONE, @@ -104,16 +113,15 @@ class ZCtx : public ObjectWrap { } - static Handle<Value> Close(const Arguments& args) { + static void Close(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); ZCtx *ctx = ObjectWrap::Unwrap<ZCtx>(args.This()); ctx->Close(); - return scope.Close(Undefined(node_isolate)); } // write(flush, in, in_off, in_len, out, out_off, out_len) - static Handle<Value> Write(const Arguments& args) { + static void Write(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); assert(args.Length() == 7); @@ -183,7 +191,7 @@ class ZCtx : public ObjectWrap { ZCtx::Process, ZCtx::After); - return ctx->handle_; + args.GetReturnValue().Set(ctx->persistent()); } @@ -273,10 +281,10 @@ class ZCtx : public ObjectWrap { ctx->write_in_progress_ = false; // call the write() cb - assert(ctx->handle_->Get(callback_sym)->IsFunction() && - "Invalid callback"); + Local<Object> handle = ctx->handle(node_isolate); + assert(handle->Get(callback_sym)->IsFunction() && "Invalid callback"); Local<Value> args[2] = { avail_in, avail_out }; - MakeCallback(ctx->handle_, callback_sym, ARRAY_SIZE(args), args); + MakeCallback(handle, callback_sym, ARRAY_SIZE(args), args); ctx->Unref(); } @@ -289,37 +297,37 @@ class ZCtx : public ObjectWrap { msg = msg_; } - assert(ctx->handle_->Get(onerror_sym)->IsFunction() && - "Invalid error handler"); + Local<Object> handle = ctx->handle(node_isolate); + assert(handle->Get(onerror_sym)->IsFunction() && "Invalid error handler"); HandleScope scope(node_isolate); - Local<Value> args[2] = { String::New(msg), - Local<Value>::New(node_isolate, - Number::New(ctx->err_)) }; - MakeCallback(ctx->handle_, onerror_sym, ARRAY_SIZE(args), args); + Local<Value> args[2] = { + String::New(msg), + Number::New(ctx->err_) + }; + MakeCallback(handle, onerror_sym, ARRAY_SIZE(args), args); // no hope of rescue. ctx->write_in_progress_ = false; ctx->Unref(); } - static Handle<Value> New(const Arguments& args) { + static void New(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); if (args.Length() < 1 || !args[0]->IsInt32()) { - return ThrowException(Exception::TypeError(String::New("Bad argument"))); + return ThrowTypeError("Bad argument"); } node_zlib_mode mode = (node_zlib_mode) args[0]->Int32Value(); if (mode < DEFLATE || mode > UNZIP) { - return ThrowException(Exception::TypeError(String::New("Bad argument"))); + return ThrowTypeError("Bad argument"); } ZCtx *ctx = new ZCtx(mode); ctx->Wrap(args.This()); - return args.This(); } // just pull the ints out of the args and call the other Init - static Handle<Value> Init(const Arguments& args) { + static void Init(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); assert((args.Length() == 4 || args.Length() == 5) && @@ -357,10 +365,9 @@ class ZCtx : public ObjectWrap { Init(ctx, level, windowBits, memLevel, strategy, dictionary, dictionary_len); SetDictionary(ctx); - return Undefined(node_isolate); } - static Handle<Value> Params(const Arguments& args) { + static void Params(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); assert(args.Length() == 2 && "params(level, strategy)"); @@ -368,18 +375,15 @@ class ZCtx : public ObjectWrap { ZCtx* ctx = ObjectWrap::Unwrap<ZCtx>(args.This()); Params(ctx, args[0]->Int32Value(), args[1]->Int32Value()); - - return Undefined(node_isolate); } - static Handle<Value> Reset(const Arguments &args) { + static void Reset(const FunctionCallbackInfo<Value> &args) { HandleScope scope(node_isolate); ZCtx *ctx = ObjectWrap::Unwrap<ZCtx>(args.This()); Reset(ctx); SetDictionary(ctx); - return Undefined(node_isolate); } static void Init(ZCtx *ctx, int level, int windowBits, int memLevel, @@ -549,8 +553,8 @@ void InitZlib(Handle<Object> target) { z->SetClassName(String::NewSymbol("Zlib")); target->Set(String::NewSymbol("Zlib"), z->GetFunction()); - callback_sym = NODE_PSYMBOL("callback"); - onerror_sym = NODE_PSYMBOL("onerror"); + callback_sym = String::New("callback"); + onerror_sym = String::New("onerror"); // valid flush values. NODE_DEFINE_CONSTANT(target, Z_NO_FLUSH); diff --git a/src/pipe_wrap.cc b/src/pipe_wrap.cc index 1e3e5b0a2..614191b7b 100644 --- a/src/pipe_wrap.cc +++ b/src/pipe_wrap.cc @@ -29,9 +29,9 @@ namespace node { -using v8::Arguments; using v8::Boolean; using v8::Function; +using v8::FunctionCallbackInfo; using v8::FunctionTemplate; using v8::Handle; using v8::HandleScope; @@ -43,11 +43,9 @@ using v8::PropertyAttribute; using v8::String; using v8::Value; -extern Persistent<FunctionTemplate> pipeConstructorTmpl; static Persistent<Function> pipeConstructor; - -static Persistent<String> onconnection_sym; -static Persistent<String> oncomplete_sym; +static Cached<String> onconnection_sym; +static Cached<String> oncomplete_sym; // TODO share with TCPWrap? @@ -62,7 +60,7 @@ uv_pipe_t* PipeWrap::UVHandle() { Local<Object> PipeWrap::Instantiate() { HandleScope scope(node_isolate); assert(!pipeConstructor.IsEmpty()); - return scope.Close(pipeConstructor->NewInstance()); + return scope.Close(NewInstance(pipeConstructor)); } @@ -114,14 +112,13 @@ void PipeWrap::Initialize(Handle<Object> target) { NODE_SET_PROTOTYPE_METHOD(t, "setPendingInstances", SetPendingInstances); #endif - pipeConstructorTmpl = Persistent<FunctionTemplate>::New(node_isolate, t); - pipeConstructor = Persistent<Function>::New(node_isolate, t->GetFunction()); - - target->Set(String::NewSymbol("Pipe"), pipeConstructor); + pipeConstructorTmpl.Reset(node_isolate, t); + pipeConstructor.Reset(node_isolate, t->GetFunction()); + target->Set(String::NewSymbol("Pipe"), t->GetFunction()); } -Handle<Value> PipeWrap::New(const Arguments& args) { +void PipeWrap::New(const FunctionCallbackInfo<Value>& args) { // This constructor should not be exposed to public javascript. // Therefore we assert that we are not trying to call this as a // normal function. @@ -130,8 +127,6 @@ Handle<Value> PipeWrap::New(const Arguments& args) { HandleScope scope(node_isolate); PipeWrap* wrap = new PipeWrap(args.This(), args[0]->IsTrue()); assert(wrap); - - return scope.Close(args.This()); } @@ -144,7 +139,7 @@ PipeWrap::PipeWrap(Handle<Object> object, bool ipc) } -Handle<Value> PipeWrap::Bind(const Arguments& args) { +void PipeWrap::Bind(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(PipeWrap) @@ -156,12 +151,12 @@ Handle<Value> PipeWrap::Bind(const Arguments& args) { // Error starting the pipe. if (r) SetErrno(uv_last_error(uv_default_loop())); - return scope.Close(Integer::New(r, node_isolate)); + args.GetReturnValue().Set(r); } #ifdef _WIN32 -Handle<Value> PipeWrap::SetPendingInstances(const Arguments& args) { +void PipeWrap::SetPendingInstances(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(PipeWrap) @@ -169,13 +164,11 @@ Handle<Value> PipeWrap::SetPendingInstances(const Arguments& args) { int instances = args[0]->Int32Value(); uv_pipe_pending_instances(&wrap->handle_, instances); - - return v8::Null(node_isolate); } #endif -Handle<Value> PipeWrap::Listen(const Arguments& args) { +void PipeWrap::Listen(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(PipeWrap) @@ -189,7 +182,7 @@ Handle<Value> PipeWrap::Listen(const Arguments& args) { // Error starting the pipe. if (r) SetErrno(uv_last_error(uv_default_loop())); - return scope.Close(Integer::New(r, node_isolate)); + args.GetReturnValue().Set(r); } @@ -202,16 +195,16 @@ void PipeWrap::OnConnection(uv_stream_t* handle, int status) { // We should not be getting this callback if someone as already called // uv_close() on the handle. - assert(wrap->object_.IsEmpty() == false); + assert(wrap->persistent().IsEmpty() == false); if (status != 0) { SetErrno(uv_last_error(uv_default_loop())); - MakeCallback(wrap->object_, "onconnection", 0, NULL); + MakeCallback(wrap->object(), "onconnection", 0, NULL); return; } // Instanciate the client javascript object and handle. - Local<Object> client_obj = pipeConstructor->NewInstance(); + Local<Object> client_obj = NewInstance(pipeConstructor); // Unwrap the client javascript object. assert(client_obj->InternalFieldCount() > 0); @@ -224,9 +217,9 @@ void PipeWrap::OnConnection(uv_stream_t* handle, int status) { // Successful accept. Call the onconnection callback in JavaScript land. Local<Value> argv[1] = { client_obj }; if (onconnection_sym.IsEmpty()) { - onconnection_sym = NODE_PSYMBOL("onconnection"); + onconnection_sym = String::New("onconnection"); } - MakeCallback(wrap->object_, onconnection_sym, ARRAY_SIZE(argv), argv); + MakeCallback(wrap->object(), onconnection_sym, ARRAY_SIZE(argv), argv); } // TODO Maybe share this with TCPWrap? @@ -237,8 +230,8 @@ void PipeWrap::AfterConnect(uv_connect_t* req, int status) { HandleScope scope(node_isolate); // The wrap and request objects should still be there. - assert(req_wrap->object_.IsEmpty() == false); - assert(wrap->object_.IsEmpty() == false); + assert(req_wrap->persistent().IsEmpty() == false); + assert(wrap->persistent().IsEmpty() == false); bool readable, writable; @@ -250,24 +243,25 @@ void PipeWrap::AfterConnect(uv_connect_t* req, int status) { writable = uv_is_writable(req->handle) != 0; } + Local<Object> req_wrap_obj = req_wrap->object(); Local<Value> argv[5] = { Integer::New(status, node_isolate), - Local<Value>::New(node_isolate, wrap->object_), - Local<Value>::New(node_isolate, req_wrap->object_), + wrap->object(), + req_wrap_obj, Local<Value>::New(node_isolate, Boolean::New(readable)), Local<Value>::New(node_isolate, Boolean::New(writable)) }; if (oncomplete_sym.IsEmpty()) { - oncomplete_sym = NODE_PSYMBOL("oncomplete"); + oncomplete_sym = String::New("oncomplete"); } - MakeCallback(req_wrap->object_, oncomplete_sym, ARRAY_SIZE(argv), argv); + MakeCallback(req_wrap_obj, oncomplete_sym, ARRAY_SIZE(argv), argv); delete req_wrap; } -Handle<Value> PipeWrap::Open(const Arguments& args) { +void PipeWrap::Open(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(PipeWrap) @@ -275,12 +269,10 @@ Handle<Value> PipeWrap::Open(const Arguments& args) { int fd = args[0]->IntegerValue(); uv_pipe_open(&wrap->handle_, fd); - - return scope.Close(v8::Null(node_isolate)); } -Handle<Value> PipeWrap::Connect(const Arguments& args) { +void PipeWrap::Connect(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(PipeWrap) @@ -296,7 +288,7 @@ Handle<Value> PipeWrap::Connect(const Arguments& args) { req_wrap->Dispatched(); - return scope.Close(req_wrap->object_); + args.GetReturnValue().Set(req_wrap->persistent()); } diff --git a/src/pipe_wrap.h b/src/pipe_wrap.h index f1e12eb75..ec6be3173 100644 --- a/src/pipe_wrap.h +++ b/src/pipe_wrap.h @@ -36,14 +36,15 @@ class PipeWrap : public StreamWrap { private: PipeWrap(v8::Handle<v8::Object> object, bool ipc); - static v8::Handle<v8::Value> New(const v8::Arguments& args); - static v8::Handle<v8::Value> Bind(const v8::Arguments& args); - static v8::Handle<v8::Value> Listen(const v8::Arguments& args); - static v8::Handle<v8::Value> Connect(const v8::Arguments& args); - static v8::Handle<v8::Value> Open(const v8::Arguments& args); + static void New(const v8::FunctionCallbackInfo<v8::Value>& args); + static void Bind(const v8::FunctionCallbackInfo<v8::Value>& args); + static void Listen(const v8::FunctionCallbackInfo<v8::Value>& args); + static void Connect(const v8::FunctionCallbackInfo<v8::Value>& args); + static void Open(const v8::FunctionCallbackInfo<v8::Value>& args); #ifdef _WIN32 - static v8::Handle<v8::Value> SetPendingInstances(const v8::Arguments& args); + static void SetPendingInstances( + const v8::FunctionCallbackInfo<v8::Value>& args); #endif static void OnConnection(uv_stream_t* handle, int status); diff --git a/src/process_wrap.cc b/src/process_wrap.cc index f8974dde8..dac6f2955 100644 --- a/src/process_wrap.cc +++ b/src/process_wrap.cc @@ -28,10 +28,9 @@ namespace node { -using v8::Arguments; using v8::Array; -using v8::Exception; using v8::Function; +using v8::FunctionCallbackInfo; using v8::FunctionTemplate; using v8::Handle; using v8::HandleScope; @@ -39,12 +38,10 @@ using v8::Integer; using v8::Local; using v8::Number; using v8::Object; -using v8::Persistent; using v8::String; -using v8::ThrowException; using v8::Value; -static Persistent<String> onexit_sym; +static Cached<String> onexit_sym; class ProcessWrap : public HandleWrap { public: @@ -69,17 +66,13 @@ class ProcessWrap : public HandleWrap { } private: - static Handle<Value> New(const Arguments& args) { + static void New(const FunctionCallbackInfo<Value>& args) { // This constructor should not be exposed to public javascript. // Therefore we assert that we are not trying to call this as a // normal function. assert(args.IsConstructCall()); - HandleScope scope(node_isolate); - ProcessWrap *wrap = new ProcessWrap(args.This()); - assert(wrap); - - return scope.Close(args.This()); + new ProcessWrap(args.This()); } ProcessWrap(Handle<Object> object) @@ -127,7 +120,7 @@ class ProcessWrap : public HandleWrap { } } - static Handle<Value> Spawn(const Arguments& args) { + static void Spawn(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(ProcessWrap) @@ -144,14 +137,12 @@ class ProcessWrap : public HandleWrap { if (uid_v->IsInt32()) { int32_t uid = uid_v->Int32Value(); if (uid & ~((uv_uid_t) ~0)) { - return ThrowException(Exception::RangeError( - String::New("options.uid is out of range"))); + return ThrowRangeError("options.uid is out of range"); } options.flags |= UV_PROCESS_SETUID; options.uid = (uv_uid_t) uid; } else if (!uid_v->IsUndefined() && !uid_v->IsNull()) { - return ThrowException(Exception::TypeError( - String::New("options.uid should be a number"))); + return ThrowTypeError("options.uid should be a number"); } // options.gid @@ -159,14 +150,12 @@ class ProcessWrap : public HandleWrap { if (gid_v->IsInt32()) { int32_t gid = gid_v->Int32Value(); if (gid & ~((uv_gid_t) ~0)) { - return ThrowException(Exception::RangeError( - String::New("options.gid is out of range"))); + return ThrowRangeError("options.gid is out of range"); } options.flags |= UV_PROCESS_SETGID; options.gid = (uv_gid_t) gid; } else if (!gid_v->IsUndefined() && !gid_v->IsNull()) { - return ThrowException(Exception::TypeError( - String::New("options.gid should be a number"))); + return ThrowTypeError("options.gid should be a number"); } // TODO is this possible to do without mallocing ? @@ -177,7 +166,7 @@ class ProcessWrap : public HandleWrap { if (file.length() > 0) { options.file = *file; } else { - return ThrowException(Exception::TypeError(String::New("Bad argument"))); + return ThrowTypeError("Bad argument"); } // options.args @@ -235,8 +224,8 @@ class ProcessWrap : public HandleWrap { } else { assert(wrap->process_.data == wrap); - wrap->object_->Set(String::New("pid"), - Integer::New(wrap->process_.pid, node_isolate)); + wrap->object()->Set(String::New("pid"), + Integer::New(wrap->process_.pid, node_isolate)); } if (options.args) { @@ -251,21 +240,17 @@ class ProcessWrap : public HandleWrap { delete[] options.stdio; - return scope.Close(Integer::New(r, node_isolate)); + args.GetReturnValue().Set(r); } - static Handle<Value> Kill(const Arguments& args) { + static void Kill(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); - UNWRAP(ProcessWrap) int signal = args[0]->Int32Value(); - int r = uv_process_kill(&wrap->process_, signal); - if (r) SetErrno(uv_last_error(uv_default_loop())); - - return scope.Close(Integer::New(r, node_isolate)); + args.GetReturnValue().Set(r); } static void OnExit(uv_process_t* handle, int exit_status, int term_signal) { @@ -285,10 +270,10 @@ class ProcessWrap : public HandleWrap { } if (onexit_sym.IsEmpty()) { - onexit_sym = NODE_PSYMBOL("onexit"); + onexit_sym = String::New("onexit"); } - MakeCallback(wrap->object_, onexit_sym, ARRAY_SIZE(argv), argv); + MakeCallback(wrap->object(), onexit_sym, ARRAY_SIZE(argv), argv); } uv_process_t process_; diff --git a/src/req_wrap.h b/src/req_wrap.h index 60e4184d5..3d0844414 100644 --- a/src/req_wrap.h +++ b/src/req_wrap.h @@ -28,16 +28,17 @@ namespace node { // defined in node.cc -extern v8::Persistent<v8::String> process_symbol; -extern v8::Persistent<v8::String> domain_symbol; +extern Cached<v8::String> process_symbol; +extern Cached<v8::String> domain_symbol; extern QUEUE req_wrap_queue; template <typename T> class ReqWrap { - public: +public: ReqWrap() { v8::HandleScope scope(node_isolate); - object_ = v8::Persistent<v8::Object>::New(node_isolate, v8::Object::New()); + v8::Local<v8::Object> object = v8::Object::New(); + persistent().Reset(node_isolate, object); if (using_domains) { v8::Local<v8::Value> domain = v8::Context::GetCurrent() @@ -47,7 +48,7 @@ class ReqWrap { ->Get(domain_symbol); if (!domain->IsUndefined()) { - object_->Set(domain_symbol, domain); + object->Set(domain_symbol, domain); } } @@ -59,9 +60,8 @@ class ReqWrap { QUEUE_REMOVE(&req_wrap_queue_); // Assert that someone has called Dispatched() assert(req_.data == this); - assert(!object_.IsEmpty()); - object_.Dispose(node_isolate); - object_.Clear(); + assert(!persistent().IsEmpty()); + persistent().Dispose(); } // Call this after the req has been dispatched. @@ -69,6 +69,14 @@ class ReqWrap { req_.data = this; } + inline v8::Local<v8::Object> object() { + return v8::Local<v8::Object>::New(node_isolate, persistent()); + } + + inline v8::Persistent<v8::Object>& persistent() { + return object_; + } + v8::Persistent<v8::Object> object_; QUEUE req_wrap_queue_; void* data_; diff --git a/src/signal_wrap.cc b/src/signal_wrap.cc index 7f84553de..201e03359 100644 --- a/src/signal_wrap.cc +++ b/src/signal_wrap.cc @@ -25,19 +25,18 @@ namespace node { -using v8::Arguments; using v8::Function; +using v8::FunctionCallbackInfo; using v8::FunctionTemplate; using v8::Handle; using v8::HandleScope; using v8::Integer; using v8::Local; using v8::Object; -using v8::Persistent; using v8::String; using v8::Value; -static Persistent<String> onsignal_sym; +static Cached<String> onsignal_sym; class SignalWrap : public HandleWrap { @@ -57,13 +56,13 @@ class SignalWrap : public HandleWrap { NODE_SET_PROTOTYPE_METHOD(constructor, "start", Start); NODE_SET_PROTOTYPE_METHOD(constructor, "stop", Stop); - onsignal_sym = NODE_PSYMBOL("onsignal"); + onsignal_sym = String::New("onsignal"); target->Set(String::NewSymbol("Signal"), constructor->GetFunction()); } private: - static Handle<Value> New(const Arguments& args) { + static void New(const FunctionCallbackInfo<Value>& args) { // This constructor should not be exposed to public javascript. // Therefore we assert that we are not trying to call this as a // normal function. @@ -71,8 +70,6 @@ class SignalWrap : public HandleWrap { HandleScope scope(node_isolate); new SignalWrap(args.This()); - - return scope.Close(args.This()); } SignalWrap(Handle<Object> object) @@ -84,30 +81,23 @@ class SignalWrap : public HandleWrap { ~SignalWrap() { } - static Handle<Value> Start(const Arguments& args) { + static void Start(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); - UNWRAP(SignalWrap) int signum = args[0]->Int32Value(); - int r = uv_signal_start(&wrap->handle_, OnSignal, signum); - if (r) SetErrno(uv_last_error(uv_default_loop())); - - return scope.Close(Integer::New(r, node_isolate)); + args.GetReturnValue().Set(r); } - static Handle<Value> Stop(const Arguments& args) { + static void Stop(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); - UNWRAP(SignalWrap) int r = uv_signal_stop(&wrap->handle_); - if (r) SetErrno(uv_last_error(uv_default_loop())); - - return scope.Close(Integer::New(r, node_isolate)); + args.GetReturnValue().Set(r); } static void OnSignal(uv_signal_t* handle, int signum) { @@ -117,7 +107,7 @@ class SignalWrap : public HandleWrap { assert(wrap); Local<Value> argv[1] = { Integer::New(signum, node_isolate) }; - MakeCallback(wrap->object_, onsignal_sym, ARRAY_SIZE(argv), argv); + MakeCallback(wrap->object(), onsignal_sym, ARRAY_SIZE(argv), argv); } uv_signal_t handle_; diff --git a/src/smalloc.cc b/src/smalloc.cc index ca5e88dcc..dcd814156 100644 --- a/src/smalloc.cc +++ b/src/smalloc.cc @@ -34,8 +34,7 @@ namespace node { namespace smalloc { -using v8::Arguments; -using v8::FunctionTemplate; +using v8::FunctionCallbackInfo; using v8::Handle; using v8::HandleScope; using v8::HeapProfiler; @@ -58,17 +57,16 @@ struct CallbackInfo { typedef v8::WeakReferenceCallbacks<Object, char>::Revivable Callback; typedef v8::WeakReferenceCallbacks<Object, void>::Revivable CallbackFree; -Callback target_cb; -CallbackFree target_free_cb; - -void TargetCallback(Isolate* isolate, Persistent<Object>* target, char* arg); +void TargetCallback(Isolate* isolate, + Persistent<Object>* target, + char* arg); void TargetFreeCallback(Isolate* isolate, Persistent<Object>* target, void* arg); // for internal use: copyOnto(source, source_start, dest, dest_start, length) -Handle<Value> CopyOnto(const Arguments& args) { +void CopyOnto(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Local<Object> source = args[0]->ToObject(); @@ -95,13 +93,11 @@ Handle<Value> CopyOnto(const Arguments& args) { assert(dest_start + length <= dest_length); memmove(dest_data + dest_start, source_data + source_start, length); - - return Undefined(node_isolate); } // for internal use: dest._data = sliceOnto(source, dest, start, end); -Handle<Value> SliceOnto(const Arguments& args) { +void SliceOnto(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Local<Object> source = args[0]->ToObject(); @@ -120,21 +116,19 @@ Handle<Value> SliceOnto(const Arguments& args) { dest->SetIndexedPropertiesToExternalArrayData(source_data + start, kExternalUnsignedByteArray, end - start); - - return scope.Close(source); + args.GetReturnValue().Set(source); } // for internal use: alloc(obj, n); -Handle<Value> Alloc(const Arguments& args) { +void Alloc(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); Local<Object> obj = args[0]->ToObject(); size_t length = args[1]->Uint32Value(); Alloc(obj, length); - - return scope.Close(obj); + args.GetReturnValue().Set(obj); } @@ -153,31 +147,32 @@ void Alloc(Handle<Object> obj, size_t length) { void Alloc(Handle<Object> obj, char* data, size_t length) { Persistent<Object> p_obj(node_isolate, obj); - node_isolate->AdjustAmountOfExternalAllocatedMemory(length); - p_obj.MakeWeak(node_isolate, data, target_cb); - p_obj.MarkIndependent(node_isolate); - p_obj.SetWrapperClassId(node_isolate, ALLOC_ID); - p_obj->SetIndexedPropertiesToExternalArrayData(data, - kExternalUnsignedByteArray, - length); + p_obj.MakeWeak(data, TargetCallback); + p_obj.MarkIndependent(); + p_obj.SetWrapperClassId(ALLOC_ID); + obj->SetIndexedPropertiesToExternalArrayData(data, + kExternalUnsignedByteArray, + length); } -void TargetCallback(Isolate* isolate, Persistent<Object>* target, char* data) { - int len = (*target)->GetIndexedPropertiesExternalArrayDataLength(); +void TargetCallback(Isolate* isolate, + Persistent<Object>* target, + char* data) { + HandleScope handle_scope(node_isolate); + Local<Object> obj = Local<Object>::New(isolate, *target); + int len = obj->GetIndexedPropertiesExternalArrayDataLength(); if (data != NULL && len > 0) { isolate->AdjustAmountOfExternalAllocatedMemory(-len); free(data); } (*target).Dispose(); - (*target).Clear(); } -Handle<Value> AllocDispose(const Arguments& args) { +void AllocDispose(const FunctionCallbackInfo<Value>& args) { AllocDispose(args[0]->ToObject()); - return Undefined(node_isolate); } @@ -218,12 +213,12 @@ void Alloc(Handle<Object> obj, node_isolate->AdjustAmountOfExternalAllocatedMemory(length + sizeof(*cb_info)); - p_obj.MakeWeak(node_isolate, static_cast<void*>(cb_info), target_free_cb); - p_obj.MarkIndependent(node_isolate); - p_obj.SetWrapperClassId(node_isolate, ALLOC_ID); - p_obj->SetIndexedPropertiesToExternalArrayData(data, - kExternalUnsignedByteArray, - length); + p_obj.MakeWeak(static_cast<void*>(cb_info), TargetFreeCallback); + p_obj.MarkIndependent(); + p_obj.SetWrapperClassId(ALLOC_ID); + obj->SetIndexedPropertiesToExternalArrayData(data, + kExternalUnsignedByteArray, + length); } @@ -232,13 +227,13 @@ void Alloc(Handle<Object> obj, void TargetFreeCallback(Isolate* isolate, Persistent<Object>* target, void* arg) { - Local<Object> obj = **target; + HandleScope handle_scope(node_isolate); + Local<Object> obj = Local<Object>::New(isolate, *target); int len = obj->GetIndexedPropertiesExternalArrayDataLength(); char* data = static_cast<char*>(obj->GetIndexedPropertiesExternalArrayData()); CallbackInfo* cb_info = static_cast<CallbackInfo*>(arg); isolate->AdjustAmountOfExternalAllocatedMemory(-(len + sizeof(*cb_info))); (*target).Dispose(); - (*target).Clear(); cb_info->cb(data, cb_info->hint); delete cb_info; } @@ -312,9 +307,6 @@ void Initialize(Handle<Object> exports) { exports->Set(String::New("kMaxLength"), Uint32::New(kMaxLength, node_isolate)); - target_cb = TargetCallback; - target_free_cb = TargetFreeCallback; - HeapProfiler* heap_profiler = node_isolate->GetHeapProfiler(); heap_profiler->SetWrapperClassInfoProvider(ALLOC_ID, WrapperInfo); } diff --git a/src/stream_wrap.cc b/src/stream_wrap.cc index ffa139e1d..73d0a5949 100644 --- a/src/stream_wrap.cc +++ b/src/stream_wrap.cc @@ -35,27 +35,25 @@ namespace node { -using v8::AccessorInfo; -using v8::Arguments; using v8::Array; +using v8::FunctionCallbackInfo; using v8::Handle; using v8::HandleScope; using v8::Integer; using v8::Local; using v8::Number; using v8::Object; -using v8::Persistent; +using v8::PropertyCallbackInfo; using v8::String; -using v8::Uint32; using v8::Value; -static Persistent<String> buffer_sym; -static Persistent<String> bytes_sym; -static Persistent<String> write_queue_size_sym; -static Persistent<String> onread_sym; -static Persistent<String> oncomplete_sym; -static Persistent<String> handle_sym; +static Cached<String> buffer_sym; +static Cached<String> bytes_sym; +static Cached<String> write_queue_size_sym; +static Cached<String> onread_sym; +static Cached<String> oncomplete_sym; +static Cached<String> handle_sym; static bool initialized; @@ -67,11 +65,11 @@ void StreamWrap::Initialize(Handle<Object> target) { HandleWrap::Initialize(target); - buffer_sym = NODE_PSYMBOL("buffer"); - bytes_sym = NODE_PSYMBOL("bytes"); - write_queue_size_sym = NODE_PSYMBOL("writeQueueSize"); - onread_sym = NODE_PSYMBOL("onread"); - oncomplete_sym = NODE_PSYMBOL("oncomplete"); + buffer_sym = String::New("buffer"); + bytes_sym = String::New("bytes"); + write_queue_size_sym = String::New("writeQueueSize"); + onread_sym = String::New("onread"); + oncomplete_sym = String::New("oncomplete"); } @@ -83,27 +81,25 @@ StreamWrap::StreamWrap(Handle<Object> object, uv_stream_t* stream) } -Handle<Value> StreamWrap::GetFD(Local<String>, const AccessorInfo& args) { -#if defined(_WIN32) - return v8::Null(node_isolate); -#else +void StreamWrap::GetFD(Local<String>, const PropertyCallbackInfo<Value>& args) { +#if !defined(_WIN32) HandleScope scope(node_isolate); UNWRAP_NO_ABORT(StreamWrap) int fd = -1; if (wrap != NULL && wrap->stream_ != NULL) fd = wrap->stream_->io_watcher.fd; - return scope.Close(Integer::New(fd, node_isolate)); + args.GetReturnValue().Set(fd); #endif } void StreamWrap::UpdateWriteQueueSize() { HandleScope scope(node_isolate); - object_->Set(write_queue_size_sym, - Integer::New(stream_->write_queue_size, node_isolate)); + object()->Set(write_queue_size_sym, + Integer::New(stream_->write_queue_size, node_isolate)); } -Handle<Value> StreamWrap::ReadStart(const Arguments& args) { +void StreamWrap::ReadStart(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(StreamWrap) @@ -120,11 +116,11 @@ Handle<Value> StreamWrap::ReadStart(const Arguments& args) { // Error starting the tcp. if (r) SetErrno(uv_last_error(uv_default_loop())); - return scope.Close(Integer::New(r, node_isolate)); + args.GetReturnValue().Set(r); } -Handle<Value> StreamWrap::ReadStop(const Arguments& args) { +void StreamWrap::ReadStop(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(StreamWrap) @@ -134,7 +130,7 @@ Handle<Value> StreamWrap::ReadStop(const Arguments& args) { // Error starting the tcp. if (r) SetErrno(uv_last_error(uv_default_loop())); - return scope.Close(Integer::New(r, node_isolate)); + args.GetReturnValue().Set(r); } @@ -178,7 +174,7 @@ void StreamWrap::OnReadCommon(uv_stream_t* handle, // We should not be getting this callback if someone as already called // uv_close() on the handle. - assert(wrap->object_.IsEmpty() == false); + assert(wrap->persistent().IsEmpty() == false); if (nread > 0) { if (wrap->stream_->type == UV_TCP) { @@ -214,7 +210,7 @@ size_t StreamWrap::WriteBuffer(Handle<Value> val, uv_buf_t* buf) { } -Handle<Value> StreamWrap::WriteBuffer(const Arguments& args) { +void StreamWrap::WriteBuffer(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(StreamWrap) @@ -225,7 +221,8 @@ Handle<Value> StreamWrap::WriteBuffer(const Arguments& args) { char* storage = new char[sizeof(WriteWrap)]; WriteWrap* req_wrap = new (storage) WriteWrap(wrap); - req_wrap->object_->SetHiddenValue(buffer_sym, args[0]); + Local<Object> req_wrap_obj = req_wrap->object(); + req_wrap_obj->SetHiddenValue(buffer_sym, args[0]); uv_buf_t buf; WriteBuffer(args[0], &buf); @@ -237,22 +234,20 @@ Handle<Value> StreamWrap::WriteBuffer(const Arguments& args) { StreamWrap::AfterWrite); req_wrap->Dispatched(); - req_wrap->object_->Set(bytes_sym, - Integer::NewFromUnsigned(length, node_isolate)); + req_wrap_obj->Set(bytes_sym, Integer::NewFromUnsigned(length, node_isolate)); if (r) { SetErrno(uv_last_error(uv_default_loop())); req_wrap->~WriteWrap(); delete[] storage; - return scope.Close(v8::Null(node_isolate)); } else { - return scope.Close(req_wrap->object_); + args.GetReturnValue().Set(req_wrap->persistent()); } } template <enum encoding encoding> -Handle<Value> StreamWrap::WriteStringImpl(const Arguments& args) { +void StreamWrap::WriteStringImpl(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); int r; @@ -276,7 +271,7 @@ Handle<Value> StreamWrap::WriteStringImpl(const Arguments& args) { uv_err_t err; err.code = UV_ENOBUFS; SetErrno(err); - return scope.Close(v8::Null(node_isolate)); + return; } char* storage = new char[sizeof(WriteWrap) + storage_size + 15]; @@ -317,10 +312,10 @@ Handle<Value> StreamWrap::WriteStringImpl(const Arguments& args) { // Reference StreamWrap instance to prevent it from being garbage // collected before `AfterWrite` is called. if (handle_sym.IsEmpty()) { - handle_sym = NODE_PSYMBOL("handle"); + handle_sym = String::New("handle"); } - assert(!req_wrap->object_.IsEmpty()); - req_wrap->object_->Set(handle_sym, send_handle_obj); + assert(!req_wrap->persistent().IsEmpty()); + req_wrap->object()->Set(handle_sym, send_handle_obj); } r = wrap->callbacks_->DoWrite(req_wrap, @@ -331,20 +326,19 @@ Handle<Value> StreamWrap::WriteStringImpl(const Arguments& args) { } req_wrap->Dispatched(); - req_wrap->object_->Set(bytes_sym, Number::New((uint32_t) data_size)); + req_wrap->object()->Set(bytes_sym, Number::New(node_isolate, data_size)); if (r) { SetErrno(uv_last_error(uv_default_loop())); req_wrap->~WriteWrap(); delete[] storage; - return scope.Close(v8::Null(node_isolate)); } else { - return scope.Close(req_wrap->object_); + args.GetReturnValue().Set(req_wrap->persistent()); } } -Handle<Value> StreamWrap::Writev(const Arguments& args) { +void StreamWrap::Writev(const FunctionCallbackInfo<Value>& args) { HandleScope scope; UNWRAP(StreamWrap) @@ -386,7 +380,7 @@ Handle<Value> StreamWrap::Writev(const Arguments& args) { uv_err_t err; err.code = UV_ENOBUFS; SetErrno(err); - return scope.Close(v8::Null(node_isolate)); + return; } if (ARRAY_SIZE(bufs_) < count) @@ -435,31 +429,30 @@ Handle<Value> StreamWrap::Writev(const Arguments& args) { delete[] bufs; req_wrap->Dispatched(); - req_wrap->object_->Set(bytes_sym, Number::New(bytes)); + req_wrap->object()->Set(bytes_sym, Number::New(node_isolate, bytes)); if (r) { SetErrno(uv_last_error(uv_default_loop())); req_wrap->~WriteWrap(); delete[] storage; - return scope.Close(v8::Null(node_isolate)); } else { - return scope.Close(req_wrap->object_); + args.GetReturnValue().Set(req_wrap->persistent()); } } -Handle<Value> StreamWrap::WriteAsciiString(const Arguments& args) { - return WriteStringImpl<ASCII>(args); +void StreamWrap::WriteAsciiString(const FunctionCallbackInfo<Value>& args) { + WriteStringImpl<ASCII>(args); } -Handle<Value> StreamWrap::WriteUtf8String(const Arguments& args) { - return WriteStringImpl<UTF8>(args); +void StreamWrap::WriteUtf8String(const FunctionCallbackInfo<Value>& args) { + WriteStringImpl<UTF8>(args); } -Handle<Value> StreamWrap::WriteUcs2String(const Arguments& args) { - return WriteStringImpl<UCS2>(args); +void StreamWrap::WriteUcs2String(const FunctionCallbackInfo<Value>& args) { + WriteStringImpl<UCS2>(args); } @@ -470,12 +463,13 @@ void StreamWrap::AfterWrite(uv_write_t* req, int status) { HandleScope scope(node_isolate); // The wrap and request objects should still be there. - assert(req_wrap->object_.IsEmpty() == false); - assert(wrap->object_.IsEmpty() == false); + assert(req_wrap->persistent().IsEmpty() == false); + assert(wrap->persistent().IsEmpty() == false); // Unref handle property + Local<Object> req_wrap_obj = req_wrap->object(); if (!handle_sym.IsEmpty()) { - req_wrap->object_->Delete(handle_sym); + req_wrap_obj->Delete(handle_sym); } if (status) { @@ -486,18 +480,18 @@ void StreamWrap::AfterWrite(uv_write_t* req, int status) { Local<Value> argv[] = { Integer::New(status, node_isolate), - Local<Value>::New(node_isolate, wrap->object_), - Local<Value>::New(node_isolate, req_wrap->object_) + wrap->object(), + req_wrap_obj }; - MakeCallback(req_wrap->object_, oncomplete_sym, ARRAY_SIZE(argv), argv); + MakeCallback(req_wrap_obj, oncomplete_sym, ARRAY_SIZE(argv), argv); req_wrap->~WriteWrap(); delete[] reinterpret_cast<char*>(req_wrap); } -Handle<Value> StreamWrap::Shutdown(const Arguments& args) { +void StreamWrap::Shutdown(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(StreamWrap) @@ -511,9 +505,8 @@ Handle<Value> StreamWrap::Shutdown(const Arguments& args) { if (r) { SetErrno(uv_last_error(uv_default_loop())); delete req_wrap; - return scope.Close(v8::Null(node_isolate)); } else { - return scope.Close(req_wrap->object_); + args.GetReturnValue().Set(req_wrap->persistent()); } } @@ -523,8 +516,8 @@ void StreamWrap::AfterShutdown(uv_shutdown_t* req, int status) { StreamWrap* wrap = (StreamWrap*) req->handle->data; // The wrap and request objects should still be there. - assert(req_wrap->object_.IsEmpty() == false); - assert(wrap->object_.IsEmpty() == false); + assert(req_wrap->persistent().IsEmpty() == false); + assert(wrap->persistent().IsEmpty() == false); HandleScope scope(node_isolate); @@ -532,13 +525,14 @@ void StreamWrap::AfterShutdown(uv_shutdown_t* req, int status) { SetErrno(uv_last_error(uv_default_loop())); } + Local<Object> req_wrap_obj = req_wrap->object(); Local<Value> argv[3] = { Integer::New(status, node_isolate), - Local<Value>::New(node_isolate, wrap->object_), - Local<Value>::New(node_isolate, req_wrap->object_) + wrap->object(), + req_wrap_obj }; - MakeCallback(req_wrap->object_, oncomplete_sym, ARRAY_SIZE(argv), argv); + MakeCallback(req_wrap_obj, oncomplete_sym, ARRAY_SIZE(argv), argv); delete req_wrap; } @@ -634,7 +628,7 @@ void StreamWrapCallbacks::DoRead(uv_stream_t* handle, argc++; } - MakeCallback(wrap_->object_, onread_sym, argc, argv); + MakeCallback(wrap_->object(), onread_sym, argc, argv); } @@ -644,7 +638,7 @@ int StreamWrapCallbacks::DoShutdown(ShutdownWrap* req_wrap, uv_shutdown_cb cb) { Handle<Object> StreamWrapCallbacks::Self() { - return wrap_->object_; + return wrap_->object(); } } diff --git a/src/stream_wrap.h b/src/stream_wrap.h index 5ac725b4c..6ef20d364 100644 --- a/src/stream_wrap.h +++ b/src/stream_wrap.h @@ -104,19 +104,19 @@ class StreamWrap : public HandleWrap { static void Initialize(v8::Handle<v8::Object> target); - static v8::Handle<v8::Value> GetFD(v8::Local<v8::String>, - const v8::AccessorInfo&); + static void GetFD(v8::Local<v8::String>, + const v8::PropertyCallbackInfo<v8::Value>&); // JavaScript functions - static v8::Handle<v8::Value> ReadStart(const v8::Arguments& args); - static v8::Handle<v8::Value> ReadStop(const v8::Arguments& args); - static v8::Handle<v8::Value> Shutdown(const v8::Arguments& args); + static void ReadStart(const v8::FunctionCallbackInfo<v8::Value>& args); + static void ReadStop(const v8::FunctionCallbackInfo<v8::Value>& args); + static void Shutdown(const v8::FunctionCallbackInfo<v8::Value>& args); - static v8::Handle<v8::Value> Writev(const v8::Arguments& args); - static v8::Handle<v8::Value> WriteBuffer(const v8::Arguments& args); - static v8::Handle<v8::Value> WriteAsciiString(const v8::Arguments& args); - static v8::Handle<v8::Value> WriteUtf8String(const v8::Arguments& args); - static v8::Handle<v8::Value> WriteUcs2String(const v8::Arguments& args); + static void Writev(const v8::FunctionCallbackInfo<v8::Value>& args); + static void WriteBuffer(const v8::FunctionCallbackInfo<v8::Value>& args); + static void WriteAsciiString(const v8::FunctionCallbackInfo<v8::Value>& args); + static void WriteUtf8String(const v8::FunctionCallbackInfo<v8::Value>& args); + static void WriteUcs2String(const v8::FunctionCallbackInfo<v8::Value>& args); // Overridable callbacks StreamWrapCallbacks* callbacks_; @@ -147,7 +147,7 @@ class StreamWrap : public HandleWrap { uv_buf_t buf, uv_handle_type pending); template <enum encoding encoding> - static v8::Handle<v8::Value> WriteStringImpl(const v8::Arguments& args); + static void WriteStringImpl(const v8::FunctionCallbackInfo<v8::Value>& args); uv_stream_t* stream_; diff --git a/src/tcp_wrap.cc b/src/tcp_wrap.cc index 990134709..b73600902 100644 --- a/src/tcp_wrap.cc +++ b/src/tcp_wrap.cc @@ -32,8 +32,8 @@ namespace node { -using v8::Arguments; using v8::Function; +using v8::FunctionCallbackInfo; using v8::FunctionTemplate; using v8::Handle; using v8::HandleScope; @@ -44,12 +44,11 @@ using v8::Object; using v8::Persistent; using v8::PropertyAttribute; using v8::String; -using v8::Undefined; using v8::Value; static Persistent<Function> tcpConstructor; -static Persistent<String> oncomplete_sym; -static Persistent<String> onconnection_sym; +static Cached<String> oncomplete_sym; +static Cached<String> onconnection_sym; typedef class ReqWrap<uv_connect_t> ConnectWrap; @@ -63,7 +62,7 @@ Local<Object> TCPWrap::Instantiate() { assert(tcpConstructor.IsEmpty() == false); HandleScope scope(node_isolate); - Local<Object> obj = tcpConstructor->NewInstance(); + Local<Object> obj = NewInstance(tcpConstructor); return scope.Close(obj); } @@ -119,13 +118,12 @@ void TCPWrap::Initialize(Handle<Object> target) { NODE_SET_PROTOTYPE_METHOD(t, "setSimultaneousAccepts", SetSimultaneousAccepts); #endif - tcpConstructorTmpl = Persistent<FunctionTemplate>::New(node_isolate, t); - tcpConstructor = Persistent<Function>::New(node_isolate, t->GetFunction()); + onconnection_sym = String::New("onconnection"); + oncomplete_sym = String::New("oncomplete"); - onconnection_sym = NODE_PSYMBOL("onconnection"); - oncomplete_sym = NODE_PSYMBOL("oncomplete"); - - target->Set(String::NewSymbol("TCP"), tcpConstructor); + tcpConstructorTmpl.Reset(node_isolate, t); + tcpConstructor.Reset(node_isolate, t->GetFunction()); + target->Set(String::NewSymbol("TCP"), t->GetFunction()); } @@ -141,17 +139,14 @@ uv_tcp_t* TCPWrap::UVHandle() { } -Handle<Value> TCPWrap::New(const Arguments& args) { +void TCPWrap::New(const FunctionCallbackInfo<Value>& args) { // This constructor should not be exposed to public javascript. // Therefore we assert that we are not trying to call this as a // normal function. assert(args.IsConstructCall()); - HandleScope scope(node_isolate); TCPWrap* wrap = new TCPWrap(args.This()); assert(wrap); - - return scope.Close(args.This()); } @@ -165,11 +160,11 @@ TCPWrap::TCPWrap(Handle<Object> object) TCPWrap::~TCPWrap() { - assert(object_.IsEmpty()); + assert(persistent().IsEmpty()); } -Handle<Value> TCPWrap::GetSockName(const Arguments& args) { +void TCPWrap::GetSockName(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); struct sockaddr_storage address; @@ -179,18 +174,14 @@ Handle<Value> TCPWrap::GetSockName(const Arguments& args) { int r = uv_tcp_getsockname(&wrap->handle_, reinterpret_cast<sockaddr*>(&address), &addrlen); - - if (r) { - SetErrno(uv_last_error(uv_default_loop())); - return Null(node_isolate); - } + if (r) return SetErrno(uv_last_error(uv_default_loop())); const sockaddr* addr = reinterpret_cast<const sockaddr*>(&address); - return scope.Close(AddressToJS(addr)); + args.GetReturnValue().Set(AddressToJS(addr)); } -Handle<Value> TCPWrap::GetPeerName(const Arguments& args) { +void TCPWrap::GetPeerName(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); struct sockaddr_storage address; @@ -200,32 +191,25 @@ Handle<Value> TCPWrap::GetPeerName(const Arguments& args) { int r = uv_tcp_getpeername(&wrap->handle_, reinterpret_cast<sockaddr*>(&address), &addrlen); - - if (r) { - SetErrno(uv_last_error(uv_default_loop())); - return Null(node_isolate); - } + if (r) return SetErrno(uv_last_error(uv_default_loop())); const sockaddr* addr = reinterpret_cast<const sockaddr*>(&address); - return scope.Close(AddressToJS(addr)); + args.GetReturnValue().Set(AddressToJS(addr)); } -Handle<Value> TCPWrap::SetNoDelay(const Arguments& args) { +void TCPWrap::SetNoDelay(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(TCPWrap) int enable = static_cast<int>(args[0]->BooleanValue()); int r = uv_tcp_nodelay(&wrap->handle_, enable); - if (r) - SetErrno(uv_last_error(uv_default_loop())); - - return Undefined(node_isolate); + if (r) SetErrno(uv_last_error(uv_default_loop())); } -Handle<Value> TCPWrap::SetKeepAlive(const Arguments& args) { +void TCPWrap::SetKeepAlive(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(TCPWrap) @@ -234,40 +218,32 @@ Handle<Value> TCPWrap::SetKeepAlive(const Arguments& args) { unsigned int delay = args[1]->Uint32Value(); int r = uv_tcp_keepalive(&wrap->handle_, enable, delay); - if (r) - SetErrno(uv_last_error(uv_default_loop())); - - return Undefined(node_isolate); + if (r) SetErrno(uv_last_error(uv_default_loop())); } #ifdef _WIN32 -Handle<Value> TCPWrap::SetSimultaneousAccepts(const Arguments& args) { +void TCPWrap::SetSimultaneousAccepts(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(TCPWrap) bool enable = args[0]->BooleanValue(); - int r = uv_tcp_simultaneous_accepts(&wrap->handle_, enable ? 1 : 0); - if (r) - SetErrno(uv_last_error(uv_default_loop())); - - return Undefined(node_isolate); + if (r) SetErrno(uv_last_error(uv_default_loop())); } #endif -Handle<Value> TCPWrap::Open(const Arguments& args) { +void TCPWrap::Open(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(TCPWrap) int fd = args[0]->IntegerValue(); uv_tcp_open(&wrap->handle_, fd); - return Null(node_isolate); } -Handle<Value> TCPWrap::Bind(const Arguments& args) { +void TCPWrap::Bind(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(TCPWrap) @@ -281,11 +257,11 @@ Handle<Value> TCPWrap::Bind(const Arguments& args) { // Error starting the tcp. if (r) SetErrno(uv_last_error(uv_default_loop())); - return scope.Close(Integer::New(r, node_isolate)); + args.GetReturnValue().Set(r); } -Handle<Value> TCPWrap::Bind6(const Arguments& args) { +void TCPWrap::Bind6(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(TCPWrap) @@ -299,11 +275,11 @@ Handle<Value> TCPWrap::Bind6(const Arguments& args) { // Error starting the tcp. if (r) SetErrno(uv_last_error(uv_default_loop())); - return scope.Close(Integer::New(r, node_isolate)); + args.GetReturnValue().Set(r); } -Handle<Value> TCPWrap::Listen(const Arguments& args) { +void TCPWrap::Listen(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(TCPWrap) @@ -317,7 +293,7 @@ Handle<Value> TCPWrap::Listen(const Arguments& args) { // Error starting the tcp. if (r) SetErrno(uv_last_error(uv_default_loop())); - return scope.Close(Integer::New(r, node_isolate)); + args.GetReturnValue().Set(r); } @@ -329,7 +305,7 @@ void TCPWrap::OnConnection(uv_stream_t* handle, int status) { // We should not be getting this callback if someone as already called // uv_close() on the handle. - assert(wrap->object_.IsEmpty() == false); + assert(wrap->persistent().IsEmpty() == false); Local<Value> argv[1]; @@ -353,7 +329,7 @@ void TCPWrap::OnConnection(uv_stream_t* handle, int status) { argv[0] = Local<Value>::New(node_isolate, Null(node_isolate)); } - MakeCallback(wrap->object_, onconnection_sym, ARRAY_SIZE(argv), argv); + MakeCallback(wrap->object(), onconnection_sym, ARRAY_SIZE(argv), argv); } @@ -364,28 +340,28 @@ void TCPWrap::AfterConnect(uv_connect_t* req, int status) { HandleScope scope(node_isolate); // The wrap and request objects should still be there. - assert(req_wrap->object_.IsEmpty() == false); - assert(wrap->object_.IsEmpty() == false); + assert(req_wrap->persistent().IsEmpty() == false); + assert(wrap->persistent().IsEmpty() == false); if (status) { SetErrno(uv_last_error(uv_default_loop())); } + Local<Object> req_wrap_obj = req_wrap->object(); Local<Value> argv[5] = { Integer::New(status, node_isolate), - Local<Value>::New(node_isolate, wrap->object_), - Local<Value>::New(node_isolate, req_wrap->object_), + wrap->object(), + req_wrap_obj, Local<Value>::New(node_isolate, v8::True(node_isolate)), Local<Value>::New(node_isolate, v8::True(node_isolate)) }; - - MakeCallback(req_wrap->object_, oncomplete_sym, ARRAY_SIZE(argv), argv); + MakeCallback(req_wrap_obj, oncomplete_sym, ARRAY_SIZE(argv), argv); delete req_wrap; } -Handle<Value> TCPWrap::Connect(const Arguments& args) { +void TCPWrap::Connect(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(TCPWrap) @@ -408,14 +384,13 @@ Handle<Value> TCPWrap::Connect(const Arguments& args) { if (r) { SetErrno(uv_last_error(uv_default_loop())); delete req_wrap; - return scope.Close(v8::Null(node_isolate)); } else { - return scope.Close(req_wrap->object_); + args.GetReturnValue().Set(req_wrap->persistent()); } } -Handle<Value> TCPWrap::Connect6(const Arguments& args) { +void TCPWrap::Connect6(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(TCPWrap) @@ -435,20 +410,19 @@ Handle<Value> TCPWrap::Connect6(const Arguments& args) { if (r) { SetErrno(uv_last_error(uv_default_loop())); delete req_wrap; - return scope.Close(v8::Null(node_isolate)); } else { - return scope.Close(req_wrap->object_); + args.GetReturnValue().Set(req_wrap->persistent()); } } // also used by udp_wrap.cc Local<Object> AddressToJS(const sockaddr* addr) { - static Persistent<String> address_sym; - static Persistent<String> family_sym; - static Persistent<String> port_sym; - static Persistent<String> ipv4_sym; - static Persistent<String> ipv6_sym; + static Cached<String> address_sym; + static Cached<String> family_sym; + static Cached<String> port_sym; + static Cached<String> ipv4_sym; + static Cached<String> ipv6_sym; HandleScope scope(node_isolate); char ip[INET6_ADDRSTRLEN]; @@ -457,11 +431,11 @@ Local<Object> AddressToJS(const sockaddr* addr) { int port; if (address_sym.IsEmpty()) { - address_sym = NODE_PSYMBOL("address"); - family_sym = NODE_PSYMBOL("family"); - port_sym = NODE_PSYMBOL("port"); - ipv4_sym = NODE_PSYMBOL("IPv4"); - ipv6_sym = NODE_PSYMBOL("IPv6"); + address_sym = String::New("address"); + family_sym = String::New("family"); + port_sym = String::New("port"); + ipv4_sym = String::New("IPv4"); + ipv6_sym = String::New("IPv6"); } Local<Object> info = Object::New(); diff --git a/src/tcp_wrap.h b/src/tcp_wrap.h index 9b8cd2914..317557d4a 100644 --- a/src/tcp_wrap.h +++ b/src/tcp_wrap.h @@ -37,20 +37,21 @@ class TCPWrap : public StreamWrap { TCPWrap(v8::Handle<v8::Object> object); ~TCPWrap(); - static v8::Handle<v8::Value> New(const v8::Arguments& args); - static v8::Handle<v8::Value> GetSockName(const v8::Arguments& args); - static v8::Handle<v8::Value> GetPeerName(const v8::Arguments& args); - static v8::Handle<v8::Value> SetNoDelay(const v8::Arguments& args); - static v8::Handle<v8::Value> SetKeepAlive(const v8::Arguments& args); - static v8::Handle<v8::Value> Bind(const v8::Arguments& args); - static v8::Handle<v8::Value> Bind6(const v8::Arguments& args); - static v8::Handle<v8::Value> Listen(const v8::Arguments& args); - static v8::Handle<v8::Value> Connect(const v8::Arguments& args); - static v8::Handle<v8::Value> Connect6(const v8::Arguments& args); - static v8::Handle<v8::Value> Open(const v8::Arguments& args); + static void New(const v8::FunctionCallbackInfo<v8::Value>& args); + static void GetSockName(const v8::FunctionCallbackInfo<v8::Value>& args); + static void GetPeerName(const v8::FunctionCallbackInfo<v8::Value>& args); + static void SetNoDelay(const v8::FunctionCallbackInfo<v8::Value>& args); + static void SetKeepAlive(const v8::FunctionCallbackInfo<v8::Value>& args); + static void Bind(const v8::FunctionCallbackInfo<v8::Value>& args); + static void Bind6(const v8::FunctionCallbackInfo<v8::Value>& args); + static void Listen(const v8::FunctionCallbackInfo<v8::Value>& args); + static void Connect(const v8::FunctionCallbackInfo<v8::Value>& args); + static void Connect6(const v8::FunctionCallbackInfo<v8::Value>& args); + static void Open(const v8::FunctionCallbackInfo<v8::Value>& args); #ifdef _WIN32 - static v8::Handle<v8::Value> SetSimultaneousAccepts(const v8::Arguments& args); + static void SetSimultaneousAccepts( + const v8::FunctionCallbackInfo<v8::Value>& args); #endif static void OnConnection(uv_stream_t* handle, int status); diff --git a/src/timer_wrap.cc b/src/timer_wrap.cc index 23abc5c41..40bc3edd4 100644 --- a/src/timer_wrap.cc +++ b/src/timer_wrap.cc @@ -24,19 +24,18 @@ namespace node { -using v8::Arguments; using v8::Function; +using v8::FunctionCallbackInfo; using v8::FunctionTemplate; using v8::Handle; using v8::HandleScope; using v8::Integer; using v8::Local; using v8::Object; -using v8::Persistent; using v8::String; using v8::Value; -static Persistent<String> ontimeout_sym; +static Cached<String> ontimeout_sym; class TimerWrap : public HandleWrap { public: @@ -61,23 +60,19 @@ class TimerWrap : public HandleWrap { NODE_SET_PROTOTYPE_METHOD(constructor, "getRepeat", GetRepeat); NODE_SET_PROTOTYPE_METHOD(constructor, "again", Again); - ontimeout_sym = NODE_PSYMBOL("ontimeout"); + ontimeout_sym = String::New("ontimeout"); target->Set(String::NewSymbol("Timer"), constructor->GetFunction()); } private: - static Handle<Value> New(const Arguments& args) { + static void New(const FunctionCallbackInfo<Value>& args) { // This constructor should not be exposed to public javascript. // Therefore we assert that we are not trying to call this as a // normal function. assert(args.IsConstructCall()); - HandleScope scope(node_isolate); - TimerWrap *wrap = new TimerWrap(args.This()); - assert(wrap); - - return scope.Close(args.This()); + new TimerWrap(args.This()); } TimerWrap(Handle<Object> object) @@ -89,67 +84,51 @@ class TimerWrap : public HandleWrap { ~TimerWrap() { } - static Handle<Value> Start(const Arguments& args) { + static void Start(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); - UNWRAP(TimerWrap) int64_t timeout = args[0]->IntegerValue(); int64_t repeat = args[1]->IntegerValue(); - int r = uv_timer_start(&wrap->handle_, OnTimeout, timeout, repeat); - if (r) SetErrno(uv_last_error(uv_default_loop())); - - return scope.Close(Integer::New(r, node_isolate)); + args.GetReturnValue().Set(r); } - static Handle<Value> Stop(const Arguments& args) { + static void Stop(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); - UNWRAP(TimerWrap) int r = uv_timer_stop(&wrap->handle_); - if (r) SetErrno(uv_last_error(uv_default_loop())); - - return scope.Close(Integer::New(r, node_isolate)); + args.GetReturnValue().Set(r); } - static Handle<Value> Again(const Arguments& args) { + static void Again(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); - UNWRAP(TimerWrap) int r = uv_timer_again(&wrap->handle_); - if (r) SetErrno(uv_last_error(uv_default_loop())); - - return scope.Close(Integer::New(r, node_isolate)); + args.GetReturnValue().Set(r); } - static Handle<Value> SetRepeat(const Arguments& args) { + static void SetRepeat(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); - UNWRAP(TimerWrap) int64_t repeat = args[0]->IntegerValue(); - uv_timer_set_repeat(&wrap->handle_, repeat); - - return scope.Close(Integer::New(0, node_isolate)); + args.GetReturnValue().Set(0); } - static Handle<Value> GetRepeat(const Arguments& args) { + static void GetRepeat(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); - UNWRAP(TimerWrap) int64_t repeat = uv_timer_get_repeat(&wrap->handle_); - if (repeat < 0) SetErrno(uv_last_error(uv_default_loop())); - - return scope.Close(Integer::New(repeat, node_isolate)); + args.GetReturnValue().Set(static_cast<double>(repeat)); } static void OnTimeout(uv_timer_t* handle, int status) { @@ -159,14 +138,13 @@ class TimerWrap : public HandleWrap { assert(wrap); Local<Value> argv[1] = { Integer::New(status, node_isolate) }; - MakeCallback(wrap->object_, ontimeout_sym, ARRAY_SIZE(argv), argv); + MakeCallback(wrap->object(), ontimeout_sym, ARRAY_SIZE(argv), argv); } - static Handle<Value> Now(const Arguments& args) { + static void Now(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); - double now = static_cast<double>(uv_now(uv_default_loop())); - return scope.Close(v8::Number::New(now)); + args.GetReturnValue().Set(now); } uv_timer_t handle_; diff --git a/src/tls_wrap.cc b/src/tls_wrap.cc index e220b0b38..28ca5732c 100644 --- a/src/tls_wrap.cc +++ b/src/tls_wrap.cc @@ -28,28 +28,39 @@ namespace node { -using namespace v8; using crypto::SecureContext; - -static Persistent<String> onread_sym; -static Persistent<String> onerror_sym; -static Persistent<String> onsniselect_sym; -static Persistent<String> onhandshakestart_sym; -static Persistent<String> onhandshakedone_sym; -static Persistent<String> onclienthello_sym; -static Persistent<String> onnewsession_sym; -static Persistent<String> subject_sym; -static Persistent<String> subjectaltname_sym; -static Persistent<String> modulus_sym; -static Persistent<String> exponent_sym; -static Persistent<String> issuer_sym; -static Persistent<String> valid_from_sym; -static Persistent<String> valid_to_sym; -static Persistent<String> fingerprint_sym; -static Persistent<String> name_sym; -static Persistent<String> version_sym; -static Persistent<String> ext_key_usage_sym; -static Persistent<String> sessionid_sym; +using v8::Array; +using v8::Exception; +using v8::Function; +using v8::FunctionCallbackInfo; +using v8::FunctionTemplate; +using v8::HandleScope; +using v8::Integer; +using v8::Null; +using v8::Object; +using v8::Persistent; +using v8::String; +using v8::Value; + +static Cached<String> onread_sym; +static Cached<String> onerror_sym; +static Cached<String> onsniselect_sym; +static Cached<String> onhandshakestart_sym; +static Cached<String> onhandshakedone_sym; +static Cached<String> onclienthello_sym; +static Cached<String> onnewsession_sym; +static Cached<String> subject_sym; +static Cached<String> subjectaltname_sym; +static Cached<String> modulus_sym; +static Cached<String> exponent_sym; +static Cached<String> issuer_sym; +static Cached<String> valid_from_sym; +static Cached<String> valid_to_sym; +static Cached<String> fingerprint_sym; +static Cached<String> name_sym; +static Cached<String> version_sym; +static Cached<String> ext_key_usage_sym; +static Cached<String> sessionid_sym; static Persistent<Function> tlsWrap; @@ -78,10 +89,11 @@ TLSCallbacks::TLSCallbacks(Kind kind, // Persist SecureContext sc_ = ObjectWrap::Unwrap<SecureContext>(sc); - sc_handle_ = Persistent<Object>::New(node_isolate, sc); + sc_handle_.Reset(node_isolate, sc); - handle_ = Persistent<Object>::New(node_isolate, tlsWrap->NewInstance()); - handle_->SetAlignedPointerInInternalField(0, this); + Local<Object> object = NewInstance(tlsWrap); + object->SetAlignedPointerInInternalField(0, this); + persistent().Reset(node_isolate, object); // Initialize queue for clearIn writes QUEUE_INIT(&write_item_queue_); @@ -137,8 +149,7 @@ int TLSCallbacks::NewSessionCallback(SSL* s, SSL_SESSION* sess) { Local<Object> session = Buffer::New(reinterpret_cast<char*>(sess->session_id), sess->session_id_length); Handle<Value> argv[2] = { session, buff }; - - MakeCallback(c->handle_, onnewsession_sym, ARRAY_SIZE(argv), argv); + MakeCallback(c->object(), onnewsession_sym, ARRAY_SIZE(argv), argv); return 0; } @@ -153,24 +164,17 @@ TLSCallbacks::~TLSCallbacks() { clear_in_ = NULL; sc_ = NULL; - sc_handle_.Dispose(node_isolate); - sc_handle_.Clear(); - - handle_.Dispose(node_isolate); - handle_.Clear(); + sc_handle_.Dispose(); + persistent().Dispose(); #ifdef OPENSSL_NPN_NEGOTIATED - npn_protos_.Dispose(node_isolate); - npn_protos_.Clear(); - selected_npn_proto_.Dispose(node_isolate); - selected_npn_proto_.Clear(); + npn_protos_.Dispose(); + selected_npn_proto_.Dispose(); #endif // OPENSSL_NPN_NEGOTIATED #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB - servername_.Dispose(node_isolate); - servername_.Clear(); - sni_context_.Dispose(node_isolate); - sni_context_.Clear(); + servername_.Dispose(); + sni_context_.Dispose(); #endif // SSL_CTRL_SET_TLSEXT_SERVERNAME_CB } @@ -295,7 +299,7 @@ void TLSCallbacks::InitSSL() { } -Handle<Value> TLSCallbacks::Wrap(const Arguments& args) { +void TLSCallbacks::Wrap(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); if (args.Length() < 1 || !args[0]->IsObject()) @@ -315,14 +319,15 @@ Handle<Value> TLSCallbacks::Wrap(const Arguments& args) { wrap->OverrideCallbacks(callbacks); }); - if (callbacks == NULL) - return Null(node_isolate); + if (callbacks == NULL) { + return args.GetReturnValue().SetNull(); + } - return scope.Close(callbacks->handle_); + args.GetReturnValue().Set(callbacks->persistent()); } -Handle<Value> TLSCallbacks::Start(const Arguments& args) { +void TLSCallbacks::Start(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(TLSCallbacks); @@ -335,8 +340,6 @@ Handle<Value> TLSCallbacks::Start(const Arguments& args) { assert(wrap->kind_ == kTLSClient); wrap->ClearOut(); wrap->EncOut(); - - return Null(node_isolate); } @@ -347,15 +350,17 @@ void TLSCallbacks::SSLInfoCallback(const SSL* ssl_, int where, int ret) { if (where & SSL_CB_HANDSHAKE_START) { HandleScope scope(node_isolate); TLSCallbacks* c = static_cast<TLSCallbacks*>(SSL_get_app_data(ssl)); - if (c->handle_->Has(onhandshakestart_sym)) - MakeCallback(c->handle_, onhandshakestart_sym, 0, NULL); + Local<Object> object = c->object(); + if (object->Has(onhandshakestart_sym)) + MakeCallback(object, onhandshakestart_sym, 0, NULL); } if (where & SSL_CB_HANDSHAKE_DONE) { HandleScope scope(node_isolate); TLSCallbacks* c = static_cast<TLSCallbacks*>(SSL_get_app_data(ssl)); c->established_ = true; - if (c->handle_->Has(onhandshakedone_sym)) - MakeCallback(c->handle_, onhandshakedone_sym, 0, NULL); + Local<Object> object = c->object(); + if (object->Has(onhandshakedone_sym)) + MakeCallback(object, onhandshakedone_sym, 0, NULL); } } @@ -417,7 +422,7 @@ void TLSCallbacks::EncOutCb(uv_write_t* req, int status) { Local<Value> arg = String::Concat( String::New("write cb error, status: "), Integer::New(status, node_isolate)->ToString()); - MakeCallback(callbacks->handle_, onerror_sym, 1, &arg); + MakeCallback(callbacks->object(), onerror_sym, 1, &arg); callbacks->InvokeQueued(status); return; } @@ -488,7 +493,7 @@ void TLSCallbacks::ClearOut() { Handle<Value> argv = GetSSLError(read, &err); if (!argv.IsEmpty()) - MakeCallback(handle_, onerror_sym, 1, &argv); + MakeCallback(object(), onerror_sym, 1, &argv); } } @@ -521,7 +526,7 @@ bool TLSCallbacks::ClearIn() { int err; Handle<Value> argv = GetSSLError(written, &err); if (!argv.IsEmpty()) - MakeCallback(handle_, onerror_sym, 1, &argv); + MakeCallback(object(), onerror_sym, 1, &argv); return false; } @@ -583,7 +588,7 @@ int TLSCallbacks::DoWrite(WriteWrap* w, int err; Handle<Value> argv = GetSSLError(written, &err); if (!argv.IsEmpty()) { - MakeCallback(handle_, onerror_sym, 1, &argv); + MakeCallback(object(), onerror_sym, 1, &argv); return -1; } @@ -772,7 +777,7 @@ void TLSCallbacks::ParseClientHello() { session_size)); argv[0] = hello_obj; - MakeCallback(handle_, onclienthello_sym, 1, argv); + MakeCallback(object(), onclienthello_sym, 1, argv); break; case kParseEnded: default: @@ -782,7 +787,7 @@ void TLSCallbacks::ParseClientHello() { #define CASE_X509_ERR(CODE) case X509_V_ERR_##CODE: reason = #CODE; break; -Handle<Value> TLSCallbacks::VerifyError(const Arguments& args) { +void TLSCallbacks::VerifyError(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(TLSCallbacks); @@ -793,8 +798,7 @@ Handle<Value> TLSCallbacks::VerifyError(const Arguments& args) { // We requested a certificate and they did not send us one. // Definitely an error. // XXX is this the right error message? - return scope.Close(Exception::Error( - String::New("UNABLE_TO_GET_ISSUER_CERT"))); + return ThrowError("UNABLE_TO_GET_ISSUER_CERT"); } X509_free(peer_cert); @@ -803,36 +807,36 @@ Handle<Value> TLSCallbacks::VerifyError(const Arguments& args) { const char* reason = NULL; Local<String> s; switch (x509_verify_error) { - case X509_V_OK: - return Null(node_isolate); - CASE_X509_ERR(UNABLE_TO_GET_ISSUER_CERT) - CASE_X509_ERR(UNABLE_TO_GET_CRL) - CASE_X509_ERR(UNABLE_TO_DECRYPT_CERT_SIGNATURE) - CASE_X509_ERR(UNABLE_TO_DECRYPT_CRL_SIGNATURE) - CASE_X509_ERR(UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY) - CASE_X509_ERR(CERT_SIGNATURE_FAILURE) - CASE_X509_ERR(CRL_SIGNATURE_FAILURE) - CASE_X509_ERR(CERT_NOT_YET_VALID) - CASE_X509_ERR(CERT_HAS_EXPIRED) - CASE_X509_ERR(CRL_NOT_YET_VALID) - CASE_X509_ERR(CRL_HAS_EXPIRED) - CASE_X509_ERR(ERROR_IN_CERT_NOT_BEFORE_FIELD) - CASE_X509_ERR(ERROR_IN_CERT_NOT_AFTER_FIELD) - CASE_X509_ERR(ERROR_IN_CRL_LAST_UPDATE_FIELD) - CASE_X509_ERR(ERROR_IN_CRL_NEXT_UPDATE_FIELD) - CASE_X509_ERR(OUT_OF_MEM) - CASE_X509_ERR(DEPTH_ZERO_SELF_SIGNED_CERT) - CASE_X509_ERR(SELF_SIGNED_CERT_IN_CHAIN) - CASE_X509_ERR(UNABLE_TO_GET_ISSUER_CERT_LOCALLY) - CASE_X509_ERR(UNABLE_TO_VERIFY_LEAF_SIGNATURE) - CASE_X509_ERR(CERT_CHAIN_TOO_LONG) - CASE_X509_ERR(CERT_REVOKED) - CASE_X509_ERR(INVALID_CA) - CASE_X509_ERR(PATH_LENGTH_EXCEEDED) - CASE_X509_ERR(INVALID_PURPOSE) - CASE_X509_ERR(CERT_UNTRUSTED) - CASE_X509_ERR(CERT_REJECTED) - default: + case X509_V_OK: + return args.GetReturnValue().SetNull(); + CASE_X509_ERR(UNABLE_TO_GET_ISSUER_CERT) + CASE_X509_ERR(UNABLE_TO_GET_CRL) + CASE_X509_ERR(UNABLE_TO_DECRYPT_CERT_SIGNATURE) + CASE_X509_ERR(UNABLE_TO_DECRYPT_CRL_SIGNATURE) + CASE_X509_ERR(UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY) + CASE_X509_ERR(CERT_SIGNATURE_FAILURE) + CASE_X509_ERR(CRL_SIGNATURE_FAILURE) + CASE_X509_ERR(CERT_NOT_YET_VALID) + CASE_X509_ERR(CERT_HAS_EXPIRED) + CASE_X509_ERR(CRL_NOT_YET_VALID) + CASE_X509_ERR(CRL_HAS_EXPIRED) + CASE_X509_ERR(ERROR_IN_CERT_NOT_BEFORE_FIELD) + CASE_X509_ERR(ERROR_IN_CERT_NOT_AFTER_FIELD) + CASE_X509_ERR(ERROR_IN_CRL_LAST_UPDATE_FIELD) + CASE_X509_ERR(ERROR_IN_CRL_NEXT_UPDATE_FIELD) + CASE_X509_ERR(OUT_OF_MEM) + CASE_X509_ERR(DEPTH_ZERO_SELF_SIGNED_CERT) + CASE_X509_ERR(SELF_SIGNED_CERT_IN_CHAIN) + CASE_X509_ERR(UNABLE_TO_GET_ISSUER_CERT_LOCALLY) + CASE_X509_ERR(UNABLE_TO_VERIFY_LEAF_SIGNATURE) + CASE_X509_ERR(CERT_CHAIN_TOO_LONG) + CASE_X509_ERR(CERT_REVOKED) + CASE_X509_ERR(INVALID_CA) + CASE_X509_ERR(PATH_LENGTH_EXCEEDED) + CASE_X509_ERR(INVALID_PURPOSE) + CASE_X509_ERR(CERT_UNTRUSTED) + CASE_X509_ERR(CERT_REJECTED) + default: s = String::New(X509_verify_cert_error_string(x509_verify_error)); break; } @@ -841,12 +845,12 @@ Handle<Value> TLSCallbacks::VerifyError(const Arguments& args) { s = String::New(reason); } - return scope.Close(Exception::Error(s)); + args.GetReturnValue().Set(Exception::Error(s)); } #undef CASE_X509_ERR -Handle<Value> TLSCallbacks::SetVerifyMode(const Arguments& args) { +void TLSCallbacks::SetVerifyMode(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(TLSCallbacks); @@ -872,21 +876,19 @@ Handle<Value> TLSCallbacks::SetVerifyMode(const Arguments& args) { // Always allow a connection. We'll reject in javascript. SSL_set_verify(wrap->ssl_, verify_mode, VerifyCallback); - - return True(node_isolate); } -Handle<Value> TLSCallbacks::IsSessionReused(const Arguments& args) { +void TLSCallbacks::IsSessionReused(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); - UNWRAP(TLSCallbacks); - - return scope.Close(Boolean::New(SSL_session_reused(wrap->ssl_))); + bool yes = SSL_session_reused(wrap->ssl_); + args.GetReturnValue().Set(yes); } -Handle<Value> TLSCallbacks::EnableSessionCallbacks(const Arguments& args) { +void TLSCallbacks::EnableSessionCallbacks( + const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(TLSCallbacks); @@ -895,12 +897,10 @@ Handle<Value> TLSCallbacks::EnableSessionCallbacks(const Arguments& args) { wrap->hello_.state = kParseWaiting; wrap->hello_.frame_len = 0; wrap->hello_.body_offset = 0; - - return scope.Close(Null(node_isolate)); } -Handle<Value> TLSCallbacks::GetPeerCertificate(const Arguments& args) { +void TLSCallbacks::GetPeerCertificate(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(TLSCallbacks); @@ -1021,18 +1021,17 @@ Handle<Value> TLSCallbacks::GetPeerCertificate(const Arguments& args) { X509_free(peer_cert); } - return scope.Close(info); + args.GetReturnValue().Set(info); } -Handle<Value> TLSCallbacks::GetSession(const Arguments& args) { +void TLSCallbacks::GetSession(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(TLSCallbacks); SSL_SESSION* sess = SSL_get_session(wrap->ssl_); - if (!sess) - return Undefined(node_isolate); + if (!sess) return; int slen = i2d_SSL_SESSION(sess, NULL); assert(slen > 0); @@ -1042,15 +1041,16 @@ Handle<Value> TLSCallbacks::GetSession(const Arguments& args) { unsigned char* p = sbuf; i2d_SSL_SESSION(sess, &p); Local<Value> s = Encode(sbuf, slen, BINARY); + args.GetReturnValue().Set(s); delete[] sbuf; - return scope.Close(s); + return; } - return Null(node_isolate); + args.GetReturnValue().SetNull(); } -Handle<Value> TLSCallbacks::SetSession(const Arguments& args) { +void TLSCallbacks::SetSession(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(TLSCallbacks); @@ -1074,22 +1074,18 @@ Handle<Value> TLSCallbacks::SetSession(const Arguments& args) { delete[] sbuf; - if (!sess) - return Undefined(node_isolate); + if (!sess) return; int r = SSL_set_session(wrap->ssl_, sess); SSL_SESSION_free(sess); if (!r) { - Local<String> eStr = String::New("SSL_set_session error"); - return ThrowException(Exception::Error(eStr)); + return ThrowError("SSL_set_session error"); } - - return True(node_isolate); } -Handle<Value> TLSCallbacks::LoadSession(const Arguments& args) { +void TLSCallbacks::LoadSession(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(TLSCallbacks); @@ -1108,12 +1104,10 @@ Handle<Value> TLSCallbacks::LoadSession(const Arguments& args) { } wrap->ParseFinish(); - - return True(node_isolate); } -Handle<Value> TLSCallbacks::GetCurrentCipher(const Arguments& args) { +void TLSCallbacks::GetCurrentCipher(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(TLSCallbacks); @@ -1122,7 +1116,7 @@ Handle<Value> TLSCallbacks::GetCurrentCipher(const Arguments& args) { c = SSL_get_current_cipher(wrap->ssl_); if (c == NULL) - return Undefined(node_isolate); + return; const char* cipher_name = SSL_CIPHER_get_name(c); const char* cipher_version = SSL_CIPHER_get_version(c); @@ -1130,7 +1124,7 @@ Handle<Value> TLSCallbacks::GetCurrentCipher(const Arguments& args) { Local<Object> info = Object::New(); info->Set(name_sym, String::New(cipher_name)); info->Set(version_sym, String::New(cipher_version)); - return scope.Close(info); + args.GetReturnValue().Set(info); } @@ -1164,9 +1158,7 @@ int TLSCallbacks::SelectNextProtoCallback(SSL* s, TLSCallbacks* p = static_cast<TLSCallbacks*>(arg); // Release old protocol handler if present - if (!p->selected_npn_proto_.IsEmpty()) { - p->selected_npn_proto_.Dispose(node_isolate); - } + p->selected_npn_proto_.Dispose(); if (p->npn_protos_.IsEmpty()) { // We should at least select one protocol @@ -1175,8 +1167,7 @@ int TLSCallbacks::SelectNextProtoCallback(SSL* s, *outlen = 8; // set status: unsupported - p->selected_npn_proto_ = Persistent<Value>::New(node_isolate, - False(node_isolate)); + p->selected_npn_proto_.Reset(node_isolate, False(node_isolate)); return SSL_TLSEXT_ERR_OK; } @@ -1202,22 +1193,22 @@ int TLSCallbacks::SelectNextProtoCallback(SSL* s, } if (!result.IsEmpty()) - p->selected_npn_proto_ = Persistent<Value>::New(node_isolate, result); + p->selected_npn_proto_.Reset(node_isolate, result); return SSL_TLSEXT_ERR_OK; } -Handle<Value> TLSCallbacks::GetNegotiatedProto(const Arguments& args) { +void TLSCallbacks::GetNegotiatedProto(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(TLSCallbacks); if (wrap->kind_ == kTLSClient) { - if (wrap->selected_npn_proto_.IsEmpty()) - return Undefined(node_isolate); - else - return wrap->selected_npn_proto_; + if (wrap->selected_npn_proto_.IsEmpty() == false) { + args.GetReturnValue().Set(wrap->selected_npn_proto_); + } + return; } const unsigned char* npn_proto; @@ -1225,15 +1216,16 @@ Handle<Value> TLSCallbacks::GetNegotiatedProto(const Arguments& args) { SSL_get0_next_proto_negotiated(wrap->ssl_, &npn_proto, &npn_proto_len); - if (!npn_proto) - return False(node_isolate); + if (!npn_proto) { + return args.GetReturnValue().Set(false); + } - return scope.Close(String::New(reinterpret_cast<const char*>(npn_proto), - npn_proto_len)); + args.GetReturnValue().Set( + String::New(reinterpret_cast<const char*>(npn_proto), npn_proto_len)); } -Handle<Value> TLSCallbacks::SetNPNProtocols(const Arguments& args) { +void TLSCallbacks::SetNPNProtocols(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(TLSCallbacks); @@ -1241,33 +1233,26 @@ Handle<Value> TLSCallbacks::SetNPNProtocols(const Arguments& args) { if (args.Length() < 1 || !Buffer::HasInstance(args[0])) return ThrowTypeError("Must give a Buffer as first argument"); - // Release old handle - if (!wrap->npn_protos_.IsEmpty()) - wrap->npn_protos_.Dispose(node_isolate); - - wrap->npn_protos_ = - Persistent<Object>::New(node_isolate, args[0]->ToObject()); - - return True(node_isolate); + wrap->npn_protos_.Reset(node_isolate, args[0].As<Object>()); } #endif // OPENSSL_NPN_NEGOTIATED #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB -Handle<Value> TLSCallbacks::GetServername(const Arguments& args) { +void TLSCallbacks::GetServername(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(TLSCallbacks); if (wrap->kind_ == kTLSServer && !wrap->servername_.IsEmpty()) { - return wrap->servername_; + args.GetReturnValue().Set(wrap->servername_); } else { - return False(node_isolate); + args.GetReturnValue().Set(false); } } -Handle<Value> TLSCallbacks::SetServername(const Arguments& args) { +void TLSCallbacks::SetServername(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(TLSCallbacks); @@ -1276,17 +1261,15 @@ Handle<Value> TLSCallbacks::SetServername(const Arguments& args) { return ThrowTypeError("First argument should be a string"); if (wrap->started_) - return ThrowException(Exception::Error(String::New("Already started."))); + return ThrowError("Already started."); if (wrap->kind_ != kTLSClient) - return False(node_isolate); + return; #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB String::Utf8Value servername(args[0].As<String>()); SSL_set_tlsext_host_name(wrap->ssl_, *servername); #endif // SSL_CTRL_SET_TLSEXT_SERVERNAME_CB - - return Null(node_isolate); } @@ -1298,31 +1281,21 @@ int TLSCallbacks::SelectSNIContextCallback(SSL* s, int* ad, void* arg) { const char* servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name); if (servername) { - if (!p->servername_.IsEmpty()) - p->servername_.Dispose(node_isolate); - p->servername_ = Persistent<String>::New(node_isolate, - String::New(servername)); + p->servername_.Reset(node_isolate, String::New(servername)); // Call the SNI callback and use its return value as context - if (p->handle_->Has(onsniselect_sym)) { - if (!p->sni_context_.IsEmpty()) - p->sni_context_.Dispose(node_isolate); - - // Get callback init args - Local<Value> argv[1] = {*p->servername_}; + Local<Object> object = p->object(); + if (object->Has(onsniselect_sym)) { + p->sni_context_.Dispose(); - // Call it - Local<Value> ret = Local<Value>::New(node_isolate, - MakeCallback(p->handle_, - onsniselect_sym, - ARRAY_SIZE(argv), - argv)); + Local<Value> arg = Local<String>::New(node_isolate, p->servername_); + Handle<Value> ret = MakeCallback(object, onsniselect_sym, 1, &arg); // If ret is SecureContext if (ret->IsUndefined()) return SSL_TLSEXT_ERR_NOACK; - p->sni_context_ = Persistent<Value>::New(node_isolate, ret); + p->sni_context_.Reset(node_isolate, ret); SecureContext* sc = ObjectWrap::Unwrap<SecureContext>(ret.As<Object>()); SSL_set_SSL_CTX(s, sc->ctx_); } @@ -1365,28 +1338,28 @@ void TLSCallbacks::Initialize(Handle<Object> target) { NODE_SET_PROTOTYPE_METHOD(t, "setServername", SetServername); #endif // SSL_CRT_SET_TLSEXT_SERVERNAME_CB - tlsWrap = Persistent<Function>::New(node_isolate, t->GetFunction()); - - onread_sym = NODE_PSYMBOL("onread"); - onsniselect_sym = NODE_PSYMBOL("onsniselect"); - onerror_sym = NODE_PSYMBOL("onerror"); - onhandshakestart_sym = NODE_PSYMBOL("onhandshakestart"); - onhandshakedone_sym = NODE_PSYMBOL("onhandshakedone"); - onclienthello_sym = NODE_PSYMBOL("onclienthello"); - onnewsession_sym = NODE_PSYMBOL("onnewsession"); - - subject_sym = NODE_PSYMBOL("subject"); - issuer_sym = NODE_PSYMBOL("issuer"); - valid_from_sym = NODE_PSYMBOL("valid_from"); - valid_to_sym = NODE_PSYMBOL("valid_to"); - subjectaltname_sym = NODE_PSYMBOL("subjectaltname"); - modulus_sym = NODE_PSYMBOL("modulus"); - exponent_sym = NODE_PSYMBOL("exponent"); - fingerprint_sym = NODE_PSYMBOL("fingerprint"); - name_sym = NODE_PSYMBOL("name"); - version_sym = NODE_PSYMBOL("version"); - ext_key_usage_sym = NODE_PSYMBOL("ext_key_usage"); - sessionid_sym = NODE_PSYMBOL("sessionId"); + tlsWrap.Reset(node_isolate, t->GetFunction()); + + onread_sym = String::New("onread"); + onsniselect_sym = String::New("onsniselect"); + onerror_sym = String::New("onerror"); + onhandshakestart_sym = String::New("onhandshakestart"); + onhandshakedone_sym = String::New("onhandshakedone"); + onclienthello_sym = String::New("onclienthello"); + onnewsession_sym = String::New("onnewsession"); + + subject_sym = String::New("subject"); + issuer_sym = String::New("issuer"); + valid_from_sym = String::New("valid_from"); + valid_to_sym = String::New("valid_to"); + subjectaltname_sym = String::New("subjectaltname"); + modulus_sym = String::New("modulus"); + exponent_sym = String::New("exponent"); + fingerprint_sym = String::New("fingerprint"); + name_sym = String::New("name"); + version_sym = String::New("version"); + ext_key_usage_sym = String::New("ext_key_usage"); + sessionid_sym = String::New("sessionId"); } } // namespace node diff --git a/src/tls_wrap.h b/src/tls_wrap.h index be97fe3ef..3e5692632 100644 --- a/src/tls_wrap.h +++ b/src/tls_wrap.h @@ -118,17 +118,19 @@ class TLSCallbacks : public StreamWrapCallbacks { v8::Handle<v8::Value> GetSSLError(int status, int* err); - static v8::Handle<v8::Value> Wrap(const v8::Arguments& args); - static v8::Handle<v8::Value> Start(const v8::Arguments& args); - static v8::Handle<v8::Value> GetPeerCertificate(const v8::Arguments& args); - static v8::Handle<v8::Value> GetSession(const v8::Arguments& args); - static v8::Handle<v8::Value> SetSession(const v8::Arguments& args); - static v8::Handle<v8::Value> LoadSession(const v8::Arguments& args); - static v8::Handle<v8::Value> GetCurrentCipher(const v8::Arguments& args); - static v8::Handle<v8::Value> VerifyError(const v8::Arguments& args); - static v8::Handle<v8::Value> SetVerifyMode(const v8::Arguments& args); - static v8::Handle<v8::Value> IsSessionReused(const v8::Arguments& args); - static v8::Handle<v8::Value> EnableSessionCallbacks(const v8::Arguments& args); + static void Wrap(const v8::FunctionCallbackInfo<v8::Value>& args); + static void Start(const v8::FunctionCallbackInfo<v8::Value>& args); + static void GetPeerCertificate( + const v8::FunctionCallbackInfo<v8::Value>& args); + static void GetSession(const v8::FunctionCallbackInfo<v8::Value>& args); + static void SetSession(const v8::FunctionCallbackInfo<v8::Value>& args); + static void LoadSession(const v8::FunctionCallbackInfo<v8::Value>& args); + static void GetCurrentCipher(const v8::FunctionCallbackInfo<v8::Value>& args); + static void VerifyError(const v8::FunctionCallbackInfo<v8::Value>& args); + static void SetVerifyMode(const v8::FunctionCallbackInfo<v8::Value>& args); + static void IsSessionReused(const v8::FunctionCallbackInfo<v8::Value>& args); + static void EnableSessionCallbacks( + const v8::FunctionCallbackInfo<v8::Value>& args); // TLS Session API static SSL_SESSION* GetSessionCallback(SSL* s, @@ -138,8 +140,9 @@ class TLSCallbacks : public StreamWrapCallbacks { static int NewSessionCallback(SSL* s, SSL_SESSION* sess); #ifdef OPENSSL_NPN_NEGOTIATED - static v8::Handle<v8::Value> GetNegotiatedProto(const v8::Arguments& args); - static v8::Handle<v8::Value> SetNPNProtocols(const v8::Arguments& args); + static void GetNegotiatedProto( + const v8::FunctionCallbackInfo<v8::Value>& args); + static void SetNPNProtocols(const v8::FunctionCallbackInfo<v8::Value>& args); static int AdvertiseNextProtoCallback(SSL* s, const unsigned char** data, unsigned int* len, @@ -153,15 +156,23 @@ class TLSCallbacks : public StreamWrapCallbacks { #endif // OPENSSL_NPN_NEGOTIATED #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB - static v8::Handle<v8::Value> GetServername(const v8::Arguments& args); - static v8::Handle<v8::Value> SetServername(const v8::Arguments& args); + static void GetServername(const v8::FunctionCallbackInfo<v8::Value>& args); + static void SetServername(const v8::FunctionCallbackInfo<v8::Value>& args); static int SelectSNIContextCallback(SSL* s, int* ad, void* arg); #endif // SSL_CTRL_SET_TLSEXT_SERVERNAME_CB + inline v8::Local<v8::Object> object() { + return v8::Local<v8::Object>::New(node_isolate, persistent()); + } + + inline v8::Persistent<v8::Object>& persistent() { + return object_; + } + Kind kind_; crypto::SecureContext* sc_; v8::Persistent<v8::Object> sc_handle_; - v8::Persistent<v8::Object> handle_; + v8::Persistent<v8::Object> object_; SSL* ssl_; BIO* enc_in_; BIO* enc_out_; diff --git a/src/tty_wrap.cc b/src/tty_wrap.cc index 182a26028..457a3e878 100644 --- a/src/tty_wrap.cc +++ b/src/tty_wrap.cc @@ -29,18 +29,16 @@ namespace node { -using v8::Arguments; using v8::Function; +using v8::FunctionCallbackInfo; using v8::FunctionTemplate; using v8::Handle; using v8::HandleScope; using v8::Integer; using v8::Local; using v8::Object; -using v8::Persistent; using v8::PropertyAttribute; using v8::String; -using v8::Undefined; using v8::Value; @@ -80,8 +78,7 @@ void TTYWrap::Initialize(Handle<Object> target) { NODE_SET_METHOD(target, "isTTY", IsTTY); NODE_SET_METHOD(target, "guessHandleType", GuessHandleType); - ttyConstructorTmpl = Persistent<FunctionTemplate>::New(node_isolate, t); - + ttyConstructorTmpl.Reset(node_isolate, t); target->Set(String::NewSymbol("TTY"), t->GetFunction()); } @@ -98,89 +95,66 @@ uv_tty_t* TTYWrap::UVHandle() { } -Handle<Value> TTYWrap::GuessHandleType(const Arguments& args) { +void TTYWrap::GuessHandleType(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); int fd = args[0]->Int32Value(); assert(fd >= 0); uv_handle_type t = uv_guess_handle(fd); + const char* type = NULL; switch (t) { - case UV_TCP: - return scope.Close(String::New("TCP")); - - case UV_TTY: - return scope.Close(String::New("TTY")); - - case UV_UDP: - return scope.Close(String::New("UDP")); - - case UV_NAMED_PIPE: - return scope.Close(String::New("PIPE")); - - case UV_FILE: - return scope.Close(String::New("FILE")); - - case UV_UNKNOWN_HANDLE: - return scope.Close(String::New("UNKNOWN")); - - default: - assert(0); - return v8::Undefined(node_isolate); + case UV_TCP: type = "TCP"; break; + case UV_TTY: type = "TTY"; break; + case UV_UDP: type = "UDP"; break; + case UV_FILE: type = "FILE"; break; + case UV_NAMED_PIPE: type = "PIPE"; break; + case UV_UNKNOWN_HANDLE: type = "UNKNOWN"; break; + default: + abort(); } + + args.GetReturnValue().Set(String::New(type)); } -Handle<Value> TTYWrap::IsTTY(const Arguments& args) { +void TTYWrap::IsTTY(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); int fd = args[0]->Int32Value(); assert(fd >= 0); - - if (uv_guess_handle(fd) == UV_TTY) { - return v8::True(node_isolate); - } - - return v8::False(node_isolate); + bool rc = uv_guess_handle(fd) == UV_TTY; + args.GetReturnValue().Set(rc); } -Handle<Value> TTYWrap::GetWindowSize(const Arguments& args) { +void TTYWrap::GetWindowSize(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(TTYWrap) int width, height; int r = uv_tty_get_winsize(&wrap->handle_, &width, &height); - - if (r) { - SetErrno(uv_last_error(uv_default_loop())); - return v8::Undefined(node_isolate); - } + if (r) return SetErrno(uv_last_error(uv_default_loop())); Local<v8::Array> a = v8::Array::New(2); a->Set(0, Integer::New(width, node_isolate)); a->Set(1, Integer::New(height, node_isolate)); - - return scope.Close(a); + args.GetReturnValue().Set(a); } -Handle<Value> TTYWrap::SetRawMode(const Arguments& args) { +void TTYWrap::SetRawMode(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); UNWRAP(TTYWrap) int r = uv_tty_set_mode(&wrap->handle_, args[0]->IsTrue()); - - if (r) { - SetErrno(uv_last_error(uv_default_loop())); - } - - return scope.Close(Integer::New(r, node_isolate)); + if (r) SetErrno(uv_last_error(uv_default_loop())); + args.GetReturnValue().Set(r); } -Handle<Value> TTYWrap::New(const Arguments& args) { +void TTYWrap::New(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); // This constructor should not be exposed to public javascript. @@ -192,10 +166,7 @@ Handle<Value> TTYWrap::New(const Arguments& args) { assert(fd >= 0); TTYWrap* wrap = new TTYWrap(args.This(), fd, args[1]->IsTrue()); - assert(wrap); wrap->UpdateWriteQueueSize(); - - return scope.Close(args.This()); } diff --git a/src/tty_wrap.h b/src/tty_wrap.h index f20fea6ad..898bd1157 100644 --- a/src/tty_wrap.h +++ b/src/tty_wrap.h @@ -27,28 +27,21 @@ namespace node { -using v8::Object; -using v8::Handle; -using v8::Local; -using v8::Value; -using v8::Arguments; - - class TTYWrap : public StreamWrap { public: - static void Initialize(Handle<Object> target); - static TTYWrap* Unwrap(Local<Object> obj); + static void Initialize(v8::Handle<v8::Object> target); + static TTYWrap* Unwrap(v8::Local<v8::Object> obj); uv_tty_t* UVHandle(); private: - TTYWrap(Handle<Object> object, int fd, bool readable); + TTYWrap(v8::Handle<v8::Object> object, int fd, bool readable); - static Handle<Value> GuessHandleType(const Arguments& args); - static Handle<Value> IsTTY(const Arguments& args); - static Handle<Value> GetWindowSize(const Arguments& args); - static Handle<Value> SetRawMode(const Arguments& args); - static Handle<Value> New(const Arguments& args); + static void GuessHandleType(const v8::FunctionCallbackInfo<v8::Value>& args); + static void IsTTY(const v8::FunctionCallbackInfo<v8::Value>& args); + static void GetWindowSize(const v8::FunctionCallbackInfo<v8::Value>& args); + static void SetRawMode(const v8::FunctionCallbackInfo<v8::Value>& args); + static void New(const v8::FunctionCallbackInfo<v8::Value>& args); uv_tty_t handle_; }; diff --git a/src/udp_wrap.cc b/src/udp_wrap.cc index a6e18449c..01ce1c275 100644 --- a/src/udp_wrap.cc +++ b/src/udp_wrap.cc @@ -30,9 +30,8 @@ namespace node { -using v8::AccessorInfo; -using v8::Arguments; using v8::Function; +using v8::FunctionCallbackInfo; using v8::FunctionTemplate; using v8::Handle; using v8::HandleScope; @@ -41,6 +40,7 @@ using v8::Local; using v8::Object; using v8::Persistent; using v8::PropertyAttribute; +using v8::PropertyCallbackInfo; using v8::String; using v8::Uint32; using v8::Value; @@ -51,9 +51,9 @@ typedef ReqWrap<uv_udp_send_t> SendWrap; Local<Object> AddressToJS(const sockaddr* addr); static Persistent<Function> constructor; -static Persistent<String> buffer_sym; -static Persistent<String> oncomplete_sym; -static Persistent<String> onmessage_sym; +static Cached<String> buffer_sym; +static Cached<String> oncomplete_sym; +static Cached<String> onmessage_sym; UDPWrap::UDPWrap(Handle<Object> object) @@ -72,9 +72,9 @@ void UDPWrap::Initialize(Handle<Object> target) { HandleScope scope(node_isolate); - buffer_sym = NODE_PSYMBOL("buffer"); - oncomplete_sym = NODE_PSYMBOL("oncomplete"); - onmessage_sym = NODE_PSYMBOL("onmessage"); + buffer_sym = String::New("buffer"); + oncomplete_sym = String::New("oncomplete"); + onmessage_sym = String::New("onmessage"); Local<FunctionTemplate> t = FunctionTemplate::New(New); t->InstanceTemplate()->SetInternalFieldCount(1); @@ -107,35 +107,29 @@ void UDPWrap::Initialize(Handle<Object> target) { NODE_SET_PROTOTYPE_METHOD(t, "ref", HandleWrap::Ref); NODE_SET_PROTOTYPE_METHOD(t, "unref", HandleWrap::Unref); - constructor = Persistent<Function>::New(node_isolate, - Persistent<FunctionTemplate>::New(node_isolate, t)->GetFunction()); - target->Set(String::NewSymbol("UDP"), constructor); + constructor.Reset(node_isolate, t->GetFunction()); + target->Set(String::NewSymbol("UDP"), t->GetFunction()); } -Handle<Value> UDPWrap::New(const Arguments& args) { +void UDPWrap::New(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); - assert(args.IsConstructCall()); new UDPWrap(args.This()); - - return scope.Close(args.This()); } -Handle<Value> UDPWrap::GetFD(Local<String>, const AccessorInfo& args) { -#if defined(_WIN32) - return v8::Null(node_isolate); -#else +void UDPWrap::GetFD(Local<String>, const PropertyCallbackInfo<Value>& args) { +#if !defined(_WIN32) HandleScope scope(node_isolate); UNWRAP(UDPWrap) int fd = (wrap == NULL) ? -1 : wrap->handle_.io_watcher.fd; - return scope.Close(Integer::New(fd, node_isolate)); + args.GetReturnValue().Set(fd); #endif } -Handle<Value> UDPWrap::DoBind(const Arguments& args, int family) { +void UDPWrap::DoBind(const FunctionCallbackInfo<Value>& args, int family) { HandleScope scope(node_isolate); int r; @@ -160,32 +154,30 @@ Handle<Value> UDPWrap::DoBind(const Arguments& args, int family) { abort(); } - if (r) - SetErrno(uv_last_error(uv_default_loop())); - - return scope.Close(Integer::New(r, node_isolate)); + if (r) SetErrno(uv_last_error(uv_default_loop())); + args.GetReturnValue().Set(r); } -Handle<Value> UDPWrap::Bind(const Arguments& args) { - return DoBind(args, AF_INET); +void UDPWrap::Bind(const FunctionCallbackInfo<Value>& args) { + DoBind(args, AF_INET); } -Handle<Value> UDPWrap::Bind6(const Arguments& args) { - return DoBind(args, AF_INET6); +void UDPWrap::Bind6(const FunctionCallbackInfo<Value>& args) { + DoBind(args, AF_INET6); } #define X(name, fn) \ - Handle<Value> UDPWrap::name(const Arguments& args) { \ + void UDPWrap::name(const FunctionCallbackInfo<Value>& args) { \ HandleScope scope(node_isolate); \ UNWRAP(UDPWrap) \ assert(args.Length() == 1); \ int flag = args[0]->Int32Value(); \ int r = fn(&wrap->handle_, flag); \ if (r) SetErrno(uv_last_error(uv_default_loop())); \ - return scope.Close(Integer::New(r, node_isolate)); \ + args.GetReturnValue().Set(r); \ } X(SetTTL, uv_udp_set_ttl) @@ -196,8 +188,8 @@ X(SetMulticastLoopback, uv_udp_set_multicast_loop) #undef X -Handle<Value> UDPWrap::SetMembership(const Arguments& args, - uv_membership membership) { +void UDPWrap::SetMembership(const FunctionCallbackInfo<Value>& args, + uv_membership membership) { HandleScope scope(node_isolate); UNWRAP(UDPWrap) @@ -211,27 +203,26 @@ Handle<Value> UDPWrap::SetMembership(const Arguments& args, iface_cstr = NULL; } - int r = uv_udp_set_membership(&wrap->handle_, *address, iface_cstr, + int r = uv_udp_set_membership(&wrap->handle_, + *address, + iface_cstr, membership); - - if (r) - SetErrno(uv_last_error(uv_default_loop())); - - return scope.Close(Integer::New(r, node_isolate)); + if (r) SetErrno(uv_last_error(uv_default_loop())); + args.GetReturnValue().Set(r); } -Handle<Value> UDPWrap::AddMembership(const Arguments& args) { - return SetMembership(args, UV_JOIN_GROUP); +void UDPWrap::AddMembership(const FunctionCallbackInfo<Value>& args) { + SetMembership(args, UV_JOIN_GROUP); } -Handle<Value> UDPWrap::DropMembership(const Arguments& args) { - return SetMembership(args, UV_LEAVE_GROUP); +void UDPWrap::DropMembership(const FunctionCallbackInfo<Value>& args) { + SetMembership(args, UV_LEAVE_GROUP); } -Handle<Value> UDPWrap::DoSend(const Arguments& args, int family) { +void UDPWrap::DoSend(const FunctionCallbackInfo<Value>& args, int family) { HandleScope scope(node_isolate); int r; @@ -249,7 +240,7 @@ Handle<Value> UDPWrap::DoSend(const Arguments& args, int family) { assert(length <= Buffer::Length(buffer_obj) - offset); SendWrap* req_wrap = new SendWrap(); - req_wrap->object_->SetHiddenValue(buffer_sym, buffer_obj); + req_wrap->object()->SetHiddenValue(buffer_sym, buffer_obj); uv_buf_t buf = uv_buf_init(Buffer::Data(buffer_obj) + offset, length); @@ -276,69 +267,57 @@ Handle<Value> UDPWrap::DoSend(const Arguments& args, int family) { if (r) { SetErrno(uv_last_error(uv_default_loop())); delete req_wrap; - return Null(node_isolate); } else { - return scope.Close(req_wrap->object_); + args.GetReturnValue().Set(req_wrap->persistent()); } } -Handle<Value> UDPWrap::Send(const Arguments& args) { - return DoSend(args, AF_INET); +void UDPWrap::Send(const FunctionCallbackInfo<Value>& args) { + DoSend(args, AF_INET); } -Handle<Value> UDPWrap::Send6(const Arguments& args) { - return DoSend(args, AF_INET6); +void UDPWrap::Send6(const FunctionCallbackInfo<Value>& args) { + DoSend(args, AF_INET6); } -Handle<Value> UDPWrap::RecvStart(const Arguments& args) { +void UDPWrap::RecvStart(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); - UNWRAP(UDPWrap) // UV_EALREADY means that the socket is already bound but that's okay int r = uv_udp_recv_start(&wrap->handle_, OnAlloc, OnRecv); - if (r && uv_last_error(uv_default_loop()).code != UV_EALREADY) { - SetErrno(uv_last_error(uv_default_loop())); - return False(node_isolate); - } - - return True(node_isolate); + bool ok = r == 0 || uv_last_error(uv_default_loop()).code == UV_EALREADY; + if (ok == false) SetErrno(uv_last_error(uv_default_loop())); + args.GetReturnValue().Set(ok); } -Handle<Value> UDPWrap::RecvStop(const Arguments& args) { +void UDPWrap::RecvStop(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); - UNWRAP(UDPWrap) int r = uv_udp_recv_stop(&wrap->handle_); - - return scope.Close(Integer::New(r, node_isolate)); + args.GetReturnValue().Set(r); } -Handle<Value> UDPWrap::GetSockName(const Arguments& args) { +void UDPWrap::GetSockName(const FunctionCallbackInfo<Value>& args) { HandleScope scope(node_isolate); struct sockaddr_storage address; - UNWRAP(UDPWrap) int addrlen = sizeof(address); int r = uv_udp_getsockname(&wrap->handle_, reinterpret_cast<sockaddr*>(&address), &addrlen); - - if (r) { - SetErrno(uv_last_error(uv_default_loop())); - return Null(node_isolate); - } + if (r) return SetErrno(uv_last_error(uv_default_loop())); const sockaddr* addr = reinterpret_cast<const sockaddr*>(&address); - return scope.Close(AddressToJS(addr)); + args.GetReturnValue().Set(AddressToJS(addr)); } @@ -351,21 +330,22 @@ void UDPWrap::OnSend(uv_udp_send_t* req, int status) { SendWrap* req_wrap = reinterpret_cast<SendWrap*>(req->data); UDPWrap* wrap = reinterpret_cast<UDPWrap*>(req->handle->data); - assert(req_wrap->object_.IsEmpty() == false); - assert(wrap->object_.IsEmpty() == false); + assert(req_wrap->persistent().IsEmpty() == false); + assert(wrap->persistent().IsEmpty() == false); if (status) { SetErrno(uv_last_error(uv_default_loop())); } + Local<Object> req_wrap_obj = req_wrap->object(); Local<Value> argv[4] = { Integer::New(status, node_isolate), - Local<Value>::New(node_isolate, wrap->object_), - Local<Value>::New(node_isolate, req_wrap->object_), - req_wrap->object_->GetHiddenValue(buffer_sym), + wrap->object(), + req_wrap_obj, + req_wrap_obj->GetHiddenValue(buffer_sym), }; - MakeCallback(req_wrap->object_, oncomplete_sym, ARRAY_SIZE(argv), argv); + MakeCallback(req_wrap_obj, oncomplete_sym, ARRAY_SIZE(argv), argv); delete req_wrap; } @@ -392,9 +372,10 @@ void UDPWrap::OnRecv(uv_udp_t* handle, if (nread < 0) { if (buf.base != NULL) free(buf.base); - Local<Value> argv[] = { Local<Object>::New(node_isolate, wrap->object_) }; + Local<Object> wrap_obj = wrap->object(); + Local<Value> argv[] = { wrap_obj }; SetErrno(uv_last_error(uv_default_loop())); - MakeCallback(wrap->object_, onmessage_sym, ARRAY_SIZE(argv), argv); + MakeCallback(wrap_obj, onmessage_sym, ARRAY_SIZE(argv), argv); return; } @@ -406,12 +387,13 @@ void UDPWrap::OnRecv(uv_udp_t* handle, buf.base = static_cast<char*>(realloc(buf.base, nread)); + Local<Object> wrap_obj = wrap->object(); Local<Value> argv[] = { - Local<Object>::New(node_isolate, wrap->object_), + wrap_obj, Buffer::Use(buf.base, nread), AddressToJS(addr) }; - MakeCallback(wrap->object_, onmessage_sym, ARRAY_SIZE(argv), argv); + MakeCallback(wrap_obj, onmessage_sym, ARRAY_SIZE(argv), argv); } @@ -425,11 +407,7 @@ UDPWrap* UDPWrap::Unwrap(Local<Object> obj) { Local<Object> UDPWrap::Instantiate() { // If this assert fires then Initialize hasn't been called yet. assert(constructor.IsEmpty() == false); - - HandleScope scope(node_isolate); - Local<Object> obj = constructor->NewInstance(); - - return scope.Close(obj); + return NewInstance(constructor); } diff --git a/src/udp_wrap.h b/src/udp_wrap.h index dc4ddfb8e..878ca2046 100644 --- a/src/udp_wrap.h +++ b/src/udp_wrap.h @@ -10,22 +10,23 @@ namespace node { class UDPWrap: public HandleWrap { public: static void Initialize(v8::Handle<v8::Object> target); - static v8::Handle<v8::Value> GetFD(v8::Local<v8::String>, - const v8::AccessorInfo&); - static v8::Handle<v8::Value> New(const v8::Arguments& args); - static v8::Handle<v8::Value> Bind(const v8::Arguments& args); - static v8::Handle<v8::Value> Send(const v8::Arguments& args); - static v8::Handle<v8::Value> Bind6(const v8::Arguments& args); - static v8::Handle<v8::Value> Send6(const v8::Arguments& args); - static v8::Handle<v8::Value> RecvStart(const v8::Arguments& args); - static v8::Handle<v8::Value> RecvStop(const v8::Arguments& args); - static v8::Handle<v8::Value> GetSockName(const v8::Arguments& args); - static v8::Handle<v8::Value> AddMembership(const v8::Arguments& args); - static v8::Handle<v8::Value> DropMembership(const v8::Arguments& args); - static v8::Handle<v8::Value> SetMulticastTTL(const v8::Arguments& args); - static v8::Handle<v8::Value> SetMulticastLoopback(const v8::Arguments& args); - static v8::Handle<v8::Value> SetBroadcast(const v8::Arguments& args); - static v8::Handle<v8::Value> SetTTL(const v8::Arguments& args); + static void GetFD(v8::Local<v8::String>, + const v8::PropertyCallbackInfo<v8::Value>&); + static void New(const v8::FunctionCallbackInfo<v8::Value>& args); + static void Bind(const v8::FunctionCallbackInfo<v8::Value>& args); + static void Send(const v8::FunctionCallbackInfo<v8::Value>& args); + static void Bind6(const v8::FunctionCallbackInfo<v8::Value>& args); + static void Send6(const v8::FunctionCallbackInfo<v8::Value>& args); + static void RecvStart(const v8::FunctionCallbackInfo<v8::Value>& args); + static void RecvStop(const v8::FunctionCallbackInfo<v8::Value>& args); + static void GetSockName(const v8::FunctionCallbackInfo<v8::Value>& args); + static void AddMembership(const v8::FunctionCallbackInfo<v8::Value>& args); + static void DropMembership(const v8::FunctionCallbackInfo<v8::Value>& args); + static void SetMulticastTTL(const v8::FunctionCallbackInfo<v8::Value>& args); + static void SetMulticastLoopback( + const v8::FunctionCallbackInfo<v8::Value>& args); + static void SetBroadcast(const v8::FunctionCallbackInfo<v8::Value>& args); + static void SetTTL(const v8::FunctionCallbackInfo<v8::Value>& args); static UDPWrap* Unwrap(v8::Local<v8::Object> obj); static v8::Local<v8::Object> Instantiate(); @@ -35,10 +36,12 @@ class UDPWrap: public HandleWrap { UDPWrap(v8::Handle<v8::Object> object); virtual ~UDPWrap(); - static v8::Handle<v8::Value> DoBind(const v8::Arguments& args, int family); - static v8::Handle<v8::Value> DoSend(const v8::Arguments& args, int family); - static v8::Handle<v8::Value> SetMembership(const v8::Arguments& args, - uv_membership membership); + static void DoBind(const v8::FunctionCallbackInfo<v8::Value>& args, + int family); + static void DoSend(const v8::FunctionCallbackInfo<v8::Value>& args, + int family); + static void SetMembership(const v8::FunctionCallbackInfo<v8::Value>& args, + uv_membership membership); static uv_buf_t OnAlloc(uv_handle_t* handle, size_t suggested_size); static void OnSend(uv_udp_send_t* req, int status); diff --git a/src/v8_typed_array.cc b/src/v8_typed_array.cc deleted file mode 100644 index 404011057..000000000 --- a/src/v8_typed_array.cc +++ /dev/null @@ -1,874 +0,0 @@ -// V8 Typed Array implementation. -// (c) Dean McNamee <dean@gmail.com>, 2011. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. - -#include <stdlib.h> // calloc, etc -#include <string.h> // memmove -#include <stdint.h> - -#include "v8_typed_array.h" -#include "v8_typed_array_bswap.h" -#include "node_buffer.h" -#include "node.h" -#include "v8.h" - -namespace { - -using node::ThrowError; -using node::ThrowRangeError; -using node::ThrowTypeError; - -struct BatchedMethods { - const char* name; - v8::Handle<v8::Value> (*func)(const v8::Arguments& args); -}; - -class ArrayBuffer { - public: - static v8::Persistent<v8::FunctionTemplate> GetTemplate() { - static v8::Persistent<v8::FunctionTemplate> ft_cache; - if (!ft_cache.IsEmpty()) - return ft_cache; - - v8::HandleScope scope(node::node_isolate); - ft_cache = v8::Persistent<v8::FunctionTemplate>::New(node::node_isolate, - v8::FunctionTemplate::New(&ArrayBuffer::V8New)); - ft_cache->SetClassName(v8::String::New("ArrayBuffer")); - v8::Local<v8::ObjectTemplate> instance = ft_cache->InstanceTemplate(); - instance->SetInternalFieldCount(1); // Buffer. - - v8::Local<v8::Signature> default_signature = v8::Signature::New(ft_cache); - - instance->Set(v8::String::New("slice"), - v8::FunctionTemplate::New(&ArrayBuffer::slice, - v8::Handle<v8::Value>(), - default_signature)); - - return ft_cache; - } - - static bool HasInstance(v8::Handle<v8::Value> value) { - return GetTemplate()->HasInstance(value); - } - - private: - static void WeakCallback(v8::Isolate* isolate, - v8::Persistent<v8::Object>* pobj, - void* data) { - v8::HandleScope handle_scope(isolate); - v8::Local<v8::Object> obj = v8::Local<v8::Object>::New(*pobj); - - void* ptr = obj->GetIndexedPropertiesExternalArrayData(); - int element_size = v8_typed_array::SizeOfArrayElementForType( - obj->GetIndexedPropertiesExternalArrayDataType()); - int size = - obj->GetIndexedPropertiesExternalArrayDataLength() * element_size; - - node::node_isolate->AdjustAmountOfExternalAllocatedMemory(-size); - - (*pobj).ClearWeak(isolate); - (*pobj).Dispose(isolate); - - free(ptr); - } - - static v8::Handle<v8::Value> V8New(const v8::Arguments& args) { - if (!args.IsConstructCall()) - return node::FromConstructorTemplate(GetTemplate(), args); - - // To match Chrome, we allow "new ArrayBuffer()". - // if (args.Length() != 1) - // return ThrowError("Wrong number of arguments."); - - if (args[0]->Int32Value() < 0) { - return ThrowRangeError("ArrayBufferView size is not a small enough " - "positive integer."); - } - - size_t num_bytes = args[0]->Uint32Value(); - if (num_bytes > node::Buffer::kMaxLength) { - return ThrowRangeError("length > kMaxLength"); - } - - void* buf = calloc(num_bytes, 1); - if (!buf) - return ThrowError("Unable to allocate ArrayBuffer."); - - args.This()->SetAlignedPointerInInternalField(0, buf); - - args.This()->Set(v8::String::New("byteLength"), - v8::Integer::NewFromUnsigned(num_bytes, - node::node_isolate), - (v8::PropertyAttribute)(v8::ReadOnly|v8::DontDelete)); - - // NOTE(deanm): This is not in the spec, you shouldn't be able to index - // the ArrayBuffer. However, it currently simplifies some handling in our - // implementation, so we make ArrayView operator[] act like an Uint8Array. - // , This allows DataView to work with both ArrayBuffers and TypedArrays. - args.This()->SetIndexedPropertiesToExternalArrayData( - buf, v8::kExternalUnsignedByteArray, num_bytes); - - node::node_isolate->AdjustAmountOfExternalAllocatedMemory(num_bytes); - - v8::Persistent<v8::Object> persistent = - v8::Persistent<v8::Object>::New(node::node_isolate, args.This()); - persistent.MakeWeak(node::node_isolate, - static_cast<void*>(NULL), - &ArrayBuffer::WeakCallback); - - return args.This(); - } - - static v8::Handle<v8::Value> slice(const v8::Arguments& args) { - if (args.Length() < 1) - return ThrowError("Wrong number of arguments."); - - unsigned int length = - args.This()->Get(v8::String::New("byteLength"))->Uint32Value(); - int begin = args[0]->Int32Value(); - int end = length; - if (args.Length() > 1) - end = args[1]->Int32Value(); - - if (begin < 0) begin = length + begin; - if (begin < 0) begin = 0; - if (static_cast<unsigned>(begin) > length) begin = length; - - if (end < 0) end = length + end; - if (end < 0) end = 0; - if (static_cast<unsigned>(end) > length) end = length; - - if (begin > end) begin = end; - - unsigned int slice_length = end - begin; - v8::Local<v8::Value> argv[] = { - v8::Integer::New(slice_length, node::node_isolate)}; - v8::Local<v8::Object> buffer = ArrayBuffer::GetTemplate()-> - GetFunction()->NewInstance(1, argv); - - // constructor failed - if (buffer.IsEmpty()) return v8::Undefined(node::node_isolate); - - void* src = args.This()->GetAlignedPointerFromInternalField(0); - void* dest = buffer->GetAlignedPointerFromInternalField(0); - memcpy(dest, static_cast<char*>(src) + begin, slice_length); - - return buffer; - } -}; - -static bool checkAlignment(size_t val, unsigned int bytes) { - return (val & (bytes - 1)) == 0; // Handles bytes == 0. -} - -template <v8::ExternalArrayType TEAType> -struct TEANameTrait { - static const char* const name; -}; - -template <> const char* const - TEANameTrait<v8::kExternalByteArray>::name = "Int8Array"; -template <> const char* const - TEANameTrait<v8::kExternalUnsignedByteArray>::name = "Uint8Array"; -template <> const char* const - TEANameTrait<v8::kExternalPixelArray>::name = "Uint8ClampedArray"; -template <> const char* const - TEANameTrait<v8::kExternalShortArray>::name = "Int16Array"; -template <> const char* const - TEANameTrait<v8::kExternalUnsignedShortArray>::name = "Uint16Array"; -template <> const char* const - TEANameTrait<v8::kExternalIntArray>::name = "Int32Array"; -template <> const char* const - TEANameTrait<v8::kExternalUnsignedIntArray>::name = "Uint32Array"; -template <> const char* const - TEANameTrait<v8::kExternalFloatArray>::name = "Float32Array"; -template <> const char* const - TEANameTrait<v8::kExternalDoubleArray>::name = "Float64Array"; - -template <unsigned int TBytes, v8::ExternalArrayType TEAType> -class TypedArray { - public: - static v8::Persistent<v8::FunctionTemplate> GetTemplate() { - static v8::Persistent<v8::FunctionTemplate> ft_cache; - if (!ft_cache.IsEmpty()) - return ft_cache; - - v8::HandleScope scope(node::node_isolate); - ft_cache = v8::Persistent<v8::FunctionTemplate>::New(node::node_isolate, - v8::FunctionTemplate::New(&TypedArray<TBytes, TEAType>::V8New)); - ft_cache->SetClassName(v8::String::New(TEANameTrait<TEAType>::name)); - v8::Local<v8::ObjectTemplate> instance = ft_cache->InstanceTemplate(); - instance->SetInternalFieldCount(0); - - ft_cache->Set(v8::String::New("BYTES_PER_ELEMENT"), - v8::Uint32::New(TBytes, node::node_isolate), v8::ReadOnly); - instance->Set(v8::String::New("BYTES_PER_ELEMENT"), - v8::Uint32::New(TBytes, node::node_isolate), v8::ReadOnly); - - v8::Local<v8::Signature> default_signature = v8::Signature::New(ft_cache); - - static BatchedMethods methods[] = { - { "get", &TypedArray<TBytes, TEAType>::get }, - { "set", &TypedArray<TBytes, TEAType>::set }, - { "slice", &TypedArray<TBytes, TEAType>::subarray }, - { "subarray", &TypedArray<TBytes, TEAType>::subarray }, - }; - - for (size_t i = 0; i < sizeof(methods) / sizeof(*methods); ++i) { - instance->Set(v8::String::New(methods[i].name), - v8::FunctionTemplate::New(methods[i].func, - v8::Handle<v8::Value>(), - default_signature)); - } - - return ft_cache; - } - - static bool HasInstance(v8::Handle<v8::Value> value) { - return GetTemplate()->HasInstance(value); - } - - private: - static v8::Handle<v8::Value> V8New(const v8::Arguments& args) { - if (!args.IsConstructCall()) - return node::FromConstructorTemplate(GetTemplate(), args); - - // To match Chrome, we allow "new Float32Array()". - // if (args.Length() != 1) - // return ThrowError("Wrong number of arguments."); - - v8::Local<v8::Object> buffer; - unsigned int length = 0; - unsigned int byte_offset = 0; - - if (ArrayBuffer::HasInstance(args[0])) { // ArrayBuffer constructor. - buffer = v8::Local<v8::Object>::Cast(args[0]); - size_t buflen = - buffer->GetIndexedPropertiesExternalArrayDataLength(); - - if (!args[1]->IsUndefined() && args[1]->Int32Value() < 0) - return ThrowRangeError("Byte offset out of range."); - byte_offset = args[1]->Uint32Value(); - - if (args.Length() > 2) { - if (args[2]->Int32Value() < 0) - return ThrowRangeError("Length out of range."); - length = args[2]->Uint32Value(); - } else { - if (buflen < byte_offset || - !checkAlignment(buflen - byte_offset, TBytes)) { - return ThrowRangeError("Byte offset / length is not aligned."); - } - length = (buflen - byte_offset) / TBytes; - } - - // NOTE(deanm): Sloppy integer overflow checks. - if (byte_offset > buflen || byte_offset + length > buflen || - byte_offset + length * TBytes > buflen) { - return ThrowRangeError("Length is out of range."); - } - - void* buf = buffer->GetIndexedPropertiesExternalArrayData(); - char* begin = reinterpret_cast<char*>(buf) + byte_offset; - - if (!checkAlignment(reinterpret_cast<uintptr_t>(begin), TBytes)) - return ThrowRangeError("Byte offset is not aligned."); - - args.This()->SetIndexedPropertiesToExternalArrayData( - begin, TEAType, length); - } - else if (args[0]->IsObject()) { // TypedArray / type[] constructor. - v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(args[0]); - length = obj->Get(v8::String::New("length"))->Uint32Value(); - - // TODO(deanm): Handle integer overflow. - v8::Local<v8::Value> argv[1] = { - v8::Integer::NewFromUnsigned(length * TBytes, node::node_isolate)}; - buffer = ArrayBuffer::GetTemplate()-> - GetFunction()->NewInstance(1, argv); - // constructor failed - if (buffer.IsEmpty()) return v8::Undefined(node::node_isolate); - - void* buf = buffer->GetAlignedPointerFromInternalField(0); - args.This()->SetIndexedPropertiesToExternalArrayData( - buf, TEAType, length); - // TODO(deanm): check for failure. - for (uint32_t i = 0; i < length; ++i) { - // Use the v8 setter to deal with typing. Maybe slow? - args.This()->Set(i, obj->Get(i)); - } - } else { // length constructor. - // Try to match Chrome, Float32Array(""), Float32Array(true/false) is - // okay, but Float32Array(null) throws a TypeError and - // Float32Array(undefined) throw a RangeError. - if (args.Length() > 0 && (args[0]->IsUndefined() || args[0]->IsNull())) - return ThrowTypeError("Type error"); - - if (args[0]->Int32Value() < 0) { - return ThrowRangeError("ArrayBufferView size is not a small enough " - "positive integer."); - } - - length = args[0]->Uint32Value(); - // TODO(deanm): Handle integer overflow. - v8::Local<v8::Value> argv[1] = { - v8::Integer::NewFromUnsigned(length * TBytes, node::node_isolate)}; - - buffer = ArrayBuffer::GetTemplate()-> - GetFunction()->NewInstance(1, argv); - // constructor failed - if (buffer.IsEmpty()) return v8::Undefined(node::node_isolate); - - void* buf = buffer->GetAlignedPointerFromInternalField(0); - args.This()->SetIndexedPropertiesToExternalArrayData( - buf, TEAType, length); - // TODO(deanm): check for failure. - } - - args.This()->Set(v8::String::New("buffer"), - buffer, - (v8::PropertyAttribute)(v8::ReadOnly|v8::DontDelete)); - args.This()->Set(v8::String::New("length"), - v8::Integer::NewFromUnsigned(length, node::node_isolate), - (v8::PropertyAttribute)(v8::ReadOnly|v8::DontDelete)); - args.This()->Set(v8::String::New("byteOffset"), - v8::Integer::NewFromUnsigned(byte_offset, - node::node_isolate), - (v8::PropertyAttribute)(v8::ReadOnly|v8::DontDelete)); - args.This()->Set(v8::String::New("byteLength"), - v8::Integer::NewFromUnsigned(length * TBytes, - node::node_isolate), - (v8::PropertyAttribute)(v8::ReadOnly|v8::DontDelete)); - - return args.This(); - } - - static v8::Handle<v8::Value> get(const v8::Arguments& args) { - if (args.Length() < 1) - return ThrowError("Wrong number of arguments."); - - if (args[0]->IsNumber()) - return args.This()->Get(args[0]->Uint32Value()); - - return v8::Undefined(node::node_isolate); - } - - static v8::Handle<v8::Value> set(const v8::Arguments& args) { - if (args.Length() < 1) - return ThrowError("Wrong number of arguments."); - - //if (!args[0]->IsObject()) - // return ThrowTypeError("Type error."); - - if (args[0]->IsNumber()) { // index, <type> value - args.This()->Set(args[0]->Uint32Value(), args[1]); - } else if (args[0]->IsObject()) { - v8::Handle<v8::Object> obj = v8::Handle<v8::Object>::Cast(args[0]); - - if (TypedArray<TBytes, TEAType>::HasInstance(obj)) { // ArrayBufferView. - if (args[1]->Int32Value() < 0) - return ThrowRangeError("Offset may not be negative."); - - unsigned int offset = args[1]->Uint32Value(); - unsigned int src_length = - obj->Get(v8::String::New("length"))->Uint32Value(); - unsigned int dst_length = - args.This()->Get(v8::String::New("length"))->Uint32Value(); - if (offset > dst_length) - return ThrowRangeError("Offset out of range."); - - if (src_length > dst_length - offset) - return ThrowRangeError("Offset/length out of range."); - - // We don't want to get the buffer pointer, because that means we'll have - // to just do the calculations for byteOffset / byteLength again. - // Instead just use the pointer on the external array data. - void* src_ptr = obj->GetIndexedPropertiesExternalArrayData(); - void* dst_ptr = args.This()->GetIndexedPropertiesExternalArrayData(); - - // From the spec: - // If the input array is a TypedArray, the two arrays may use the same - // underlying ArrayBuffer. In this situation, setting the values takes - // place as if all the data is first copied into a temporary buffer that - // does not overlap either of the arrays, and then the data from the - // temporary buffer is copied into the current array. - memmove(reinterpret_cast<char*>(dst_ptr) + offset * TBytes, src_ptr, - src_length * TBytes); - } else { // type[] - if (args[1]->Int32Value() < 0) - return ThrowRangeError("Offset may not be negative."); - - unsigned int src_length = - obj->Get(v8::String::New("length"))->Uint32Value(); - unsigned int dst_length = - args.This()->Get(v8::String::New("length"))->Uint32Value(); - unsigned int offset = args[1]->Uint32Value(); - - if (offset > dst_length) - return ThrowRangeError("Offset out of range."); - - if (src_length > dst_length - offset) - return ThrowRangeError("Offset/length out of range."); - - for (uint32_t i = 0; i < src_length; ++i) { - // Use the v8 setter to deal with typing. Maybe slow? - args.This()->Set(i + offset, obj->Get(i)); - } - } - } - - return v8::Undefined(node::node_isolate); - } - - static v8::Handle<v8::Value> subarray(const v8::Arguments& args) { - // TODO(deanm): The unsigned / signed type mixing makes me super nervous. - - unsigned int length = - args.This()->Get(v8::String::New("length"))->Uint32Value(); - int begin = args[0]->Int32Value(); - int end = length; - if (args.Length() > 1) - end = args[1]->Int32Value(); - - if (begin < 0) begin = length + begin; - if (begin < 0) begin = 0; - if ((unsigned)begin > length) begin = length; - - if (end < 0) end = length + end; - if (end < 0) end = 0; - if ((unsigned)end > length) end = length; - - if (begin > end) begin = end; - - int byte_offset = begin * TBytes + - args.This()->Get(v8::String::New("byteOffset"))->Uint32Value(); - - // Call through to the ArrayBuffer, byteOffset, length constructor. - v8::Local<v8::Value> argv[] = { - args.This()->Get(v8::String::New("buffer")), - v8::Integer::New(byte_offset, node::node_isolate), - v8::Integer::New(end - begin, node::node_isolate)}; - return TypedArray<TBytes, TEAType>::GetTemplate()-> - GetFunction()->NewInstance(3, argv); - } -}; - -class Int8Array : public TypedArray<1, v8::kExternalByteArray> { }; -class Uint8Array : public TypedArray<1, v8::kExternalUnsignedByteArray> { }; -class Uint8ClampedArray : public TypedArray<1, v8::kExternalPixelArray> { }; -class Int16Array : public TypedArray<2, v8::kExternalShortArray> { }; -class Uint16Array : public TypedArray<2, v8::kExternalUnsignedShortArray> { }; -class Int32Array : public TypedArray<4, v8::kExternalIntArray> { }; -class Uint32Array : public TypedArray<4, v8::kExternalUnsignedIntArray> { }; -class Float32Array : public TypedArray<4, v8::kExternalFloatArray> { }; -class Float64Array : public TypedArray<8, v8::kExternalDoubleArray> { }; - -template <typename T> -v8::Handle<v8::Value> cTypeToValue(T) { - return v8::Undefined(node::node_isolate); -} - -template <> -v8::Handle<v8::Value> cTypeToValue(unsigned char val) { - return v8::Integer::NewFromUnsigned(val, node::node_isolate); -} - -template <> -v8::Handle<v8::Value> cTypeToValue(signed char val) { - return v8::Integer::New(val, node::node_isolate); -} - -template <> -v8::Handle<v8::Value> cTypeToValue(unsigned short val) { - return v8::Integer::NewFromUnsigned(val, node::node_isolate); -} - -template <> -v8::Handle<v8::Value> cTypeToValue(short val) { - return v8::Integer::New(val, node::node_isolate); -} - -template <> -v8::Handle<v8::Value> cTypeToValue(unsigned int val) { - return v8::Integer::NewFromUnsigned(val, node::node_isolate); -} - -template <> -v8::Handle<v8::Value> cTypeToValue(int val) { - return v8::Integer::New(val, node::node_isolate); -} - -template <> -v8::Handle<v8::Value> cTypeToValue(float val) { - return v8::Number::New(val); -} - -template <> -v8::Handle<v8::Value> cTypeToValue(double val) { - return v8::Number::New(val); -} - - -template <typename T> -T valueToCType(v8::Handle<v8::Value> value) { - return 0; -} - -template <> -unsigned char valueToCType(v8::Handle<v8::Value> value) { - return value->Uint32Value(); -} - -template <> -signed char valueToCType(v8::Handle<v8::Value> value) { - return value->Int32Value(); -} - -template <> -unsigned short valueToCType(v8::Handle<v8::Value> value) { - return value->Uint32Value(); -} - -template <> -short valueToCType(v8::Handle<v8::Value> value) { - return value->Int32Value(); -} - -template <> -unsigned int valueToCType(v8::Handle<v8::Value> value) { - return value->Uint32Value(); -} - -template <> -int valueToCType(v8::Handle<v8::Value> value) { - return value->Int32Value(); -} - -template <> -float valueToCType(v8::Handle<v8::Value> value) { - return static_cast<float>(value->NumberValue()); -} - -template <> -double valueToCType(v8::Handle<v8::Value> value) { - return value->NumberValue(); -} - - -class DataView { - public: - static v8::Persistent<v8::FunctionTemplate> GetTemplate() { - static v8::Persistent<v8::FunctionTemplate> ft_cache; - if (!ft_cache.IsEmpty()) - return ft_cache; - - v8::HandleScope scope(node::node_isolate); - ft_cache = v8::Persistent<v8::FunctionTemplate>::New(node::node_isolate, - v8::FunctionTemplate::New(&DataView::V8New)); - ft_cache->SetClassName(v8::String::New("DataView")); - v8::Local<v8::ObjectTemplate> instance = ft_cache->InstanceTemplate(); - instance->SetInternalFieldCount(0); - - v8::Local<v8::Signature> default_signature = v8::Signature::New(ft_cache); - - static BatchedMethods methods[] = { - { "getUint8", &DataView::getUint8 }, - { "getInt8", &DataView::getInt8 }, - { "getUint16", &DataView::getUint16 }, - { "getInt16", &DataView::getInt16 }, - { "getUint32", &DataView::getUint32 }, - { "getInt32", &DataView::getInt32 }, - { "getFloat32", &DataView::getFloat32 }, - { "getFloat64", &DataView::getFloat64 }, - { "setUint8", &DataView::setUint8 }, - { "setInt8", &DataView::setInt8 }, - { "setUint16", &DataView::setUint16 }, - { "setInt16", &DataView::setInt16 }, - { "setUint32", &DataView::setUint32 }, - { "setInt32", &DataView::setInt32 }, - { "setFloat32", &DataView::setFloat32 }, - { "setFloat64", &DataView::setFloat64 }, - }; - - for (size_t i = 0; i < sizeof(methods) / sizeof(*methods); ++i) { - instance->Set(v8::String::New(methods[i].name), - v8::FunctionTemplate::New(methods[i].func, - v8::Handle<v8::Value>(), - default_signature)); - } - - return ft_cache; - } - - static bool HasInstance(v8::Handle<v8::Value> value) { - return GetTemplate()->HasInstance(value); - } - - private: - static v8::Handle<v8::Value> V8New(const v8::Arguments& args) { - if (!args.IsConstructCall()) - return node::FromConstructorTemplate(GetTemplate(), args); - - if (args.Length() < 1) - return ThrowError("Wrong number of arguments."); - - if (!args[0]->IsObject()) - return ThrowError("Object must be an ArrayBuffer."); - - v8::Handle<v8::Object> buffer = v8::Handle<v8::Object>::Cast(args[0]); - if (!ArrayBuffer::HasInstance(buffer)) - return ThrowError("Object must be an ArrayBuffer."); - - unsigned int byte_length = - buffer->GetIndexedPropertiesExternalArrayDataLength(); - unsigned int byte_offset = args[1]->Uint32Value(); - - if (args[1]->Int32Value() < 0 || byte_offset >= byte_length) - return ThrowRangeError("byteOffset out of range."); - - if (!args[2]->IsUndefined()) { - if (args[2]->Int32Value() < 0) - return ThrowRangeError("byteLength out of range."); - unsigned int new_byte_length = args[2]->Uint32Value(); - if (new_byte_length > byte_length) - return ThrowRangeError("byteLength out of range."); - if (byte_offset + new_byte_length > byte_length) - return ThrowRangeError("byteOffset/byteLength out of range."); - byte_length = new_byte_length; - } else { - // Adjust the original byte_length from total length to length to end. - byte_length -= byte_offset; - } - - void* buf = buffer->GetIndexedPropertiesExternalArrayData(); - - // Like ArrayBuffer, we violate the spec and add an operator[]. - args.This()->SetIndexedPropertiesToExternalArrayData( - reinterpret_cast<char*>(buf) + byte_offset, - v8::kExternalUnsignedByteArray, byte_length); - - args.This()->Set(v8::String::New("buffer"), - buffer, - (v8::PropertyAttribute)(v8::ReadOnly|v8::DontDelete)); - args.This()->Set(v8::String::New("byteOffset"), - v8::Integer::NewFromUnsigned(byte_offset, - node::node_isolate), - (v8::PropertyAttribute)(v8::ReadOnly|v8::DontDelete)); - args.This()->Set(v8::String::New("byteLength"), - v8::Integer::NewFromUnsigned(byte_length, - node::node_isolate), - (v8::PropertyAttribute)(v8::ReadOnly|v8::DontDelete)); - return args.This(); - } - - template <typename T> - static v8::Handle<v8::Value> getGeneric(const v8::Arguments& args) { - if (args.Length() < 1) - return ThrowError("Wrong number of arguments."); - - unsigned int index = args[0]->Uint32Value(); - // NOTE(deanm): args[1]->BooleanValue when the argument was not passed in - // gives us the right answer, but seems to be very slow. This seems to be - // the cost of calling BooleanValue() on undefined. - bool little_endian = args.Length() > 1 ? args[1]->BooleanValue() : false; - // TODO(deanm): All of these things should be cacheable. - int element_size = v8_typed_array::SizeOfArrayElementForType( - args.This()->GetIndexedPropertiesExternalArrayDataType()); - assert(element_size > 0); - int size = args.This()->GetIndexedPropertiesExternalArrayDataLength(); - assert(size >= 0); - - if (static_cast<uint64_t>(index) + sizeof(T) > - static_cast<uint64_t>(size) * element_size) { - return ThrowError("Index out of range."); - } - - void* ptr = reinterpret_cast<char*>( - args.This()->GetIndexedPropertiesExternalArrayData()) + index; - - T val; -#if V8_TYPED_ARRAY_LITTLE_ENDIAN - if (!little_endian) { -#else - if (little_endian) { -#endif - val = v8_typed_array::LoadAndSwapBytes<T>(ptr); - } else { - memcpy(&val, ptr, sizeof(T)); - } - return cTypeToValue<T>(val); - } - - template <typename T> - static v8::Handle<v8::Value> setGeneric(const v8::Arguments& args) { - if (args.Length() < 2) - return ThrowError("Wrong number of arguments."); - - unsigned int index = args[0]->Int32Value(); - // NOTE(deanm): args[1]->BooleanValue when the argument was not passed in - // gives us the right answer, but seems to be very slow. This seems to be - // the cost of calling BooleanValue() on undefined. - bool little_endian = args.Length() > 2 ? args[2]->BooleanValue() : false; - // TODO(deanm): All of these things should be cacheable. - int element_size = v8_typed_array::SizeOfArrayElementForType( - args.This()->GetIndexedPropertiesExternalArrayDataType()); - assert(element_size > 0); - int size = args.This()->GetIndexedPropertiesExternalArrayDataLength(); - assert(size >= 0); - - if (static_cast<uint64_t>(index) + sizeof(T) > - static_cast<uint64_t>(size) * element_size) { - return ThrowError("Index out of range."); - } - - void* ptr = reinterpret_cast<char*>( - args.This()->GetIndexedPropertiesExternalArrayData()) + index; - - T val = valueToCType<T>(args[1]); -#if V8_TYPED_ARRAY_LITTLE_ENDIAN - if (!little_endian) { -#else - if (little_endian) { -#endif - v8_typed_array::SwapBytesAndStore<T>(ptr, val); - } else { - memcpy(ptr, &val, sizeof(T)); - } - return v8::Undefined(node::node_isolate); - } - - static v8::Handle<v8::Value> getUint8(const v8::Arguments& args) { - return getGeneric<unsigned char>(args); - } - - static v8::Handle<v8::Value> getInt8(const v8::Arguments& args) { - return getGeneric<signed char>(args); - } - - static v8::Handle<v8::Value> getUint16(const v8::Arguments& args) { - return getGeneric<unsigned short>(args); - } - - static v8::Handle<v8::Value> getInt16(const v8::Arguments& args) { - return getGeneric<short>(args); - } - - static v8::Handle<v8::Value> getUint32(const v8::Arguments& args) { - return getGeneric<unsigned int>(args); - } - - static v8::Handle<v8::Value> getInt32(const v8::Arguments& args) { - return getGeneric<int>(args); - } - - static v8::Handle<v8::Value> getFloat32(const v8::Arguments& args) { - return getGeneric<float>(args); - } - - static v8::Handle<v8::Value> getFloat64(const v8::Arguments& args) { - return getGeneric<double>(args); - } - - static v8::Handle<v8::Value> setUint8(const v8::Arguments& args) { - return setGeneric<unsigned char>(args); - } - - static v8::Handle<v8::Value> setInt8(const v8::Arguments& args) { - return setGeneric<signed char>(args); - } - - static v8::Handle<v8::Value> setUint16(const v8::Arguments& args) { - return setGeneric<unsigned short>(args); - } - - static v8::Handle<v8::Value> setInt16(const v8::Arguments& args) { - return setGeneric<short>(args); - } - - static v8::Handle<v8::Value> setUint32(const v8::Arguments& args) { - return setGeneric<unsigned int>(args); - } - - static v8::Handle<v8::Value> setInt32(const v8::Arguments& args) { - return setGeneric<int>(args); - } - - static v8::Handle<v8::Value> setFloat32(const v8::Arguments& args) { - return setGeneric<float>(args); - } - - static v8::Handle<v8::Value> setFloat64(const v8::Arguments& args) { - return setGeneric<double>(args); - } -}; - - -} // namespace - -namespace v8_typed_array { - -void AttachBindings(v8::Handle<v8::Object> obj) { - v8::HandleScope scope(node::node_isolate); - - obj->Set(v8::String::New("ArrayBuffer"), - ArrayBuffer::GetTemplate()->GetFunction()); - obj->Set(v8::String::New("Int8Array"), - Int8Array::GetTemplate()->GetFunction()); - obj->Set(v8::String::New("Uint8Array"), - Uint8Array::GetTemplate()->GetFunction()); - obj->Set(v8::String::New("Uint8ClampedArray"), - Uint8ClampedArray::GetTemplate()->GetFunction()); - obj->Set(v8::String::New("Int16Array"), - Int16Array::GetTemplate()->GetFunction()); - obj->Set(v8::String::New("Uint16Array"), - Uint16Array::GetTemplate()->GetFunction()); - obj->Set(v8::String::New("Int32Array"), - Int32Array::GetTemplate()->GetFunction()); - obj->Set(v8::String::New("Uint32Array"), - Uint32Array::GetTemplate()->GetFunction()); - obj->Set(v8::String::New("Float32Array"), - Float32Array::GetTemplate()->GetFunction()); - obj->Set(v8::String::New("Float64Array"), - Float64Array::GetTemplate()->GetFunction()); - obj->Set(v8::String::New("DataView"), - DataView::GetTemplate()->GetFunction()); -} - -int SizeOfArrayElementForType(v8::ExternalArrayType type) { - switch (type) { - case v8::kExternalByteArray: - case v8::kExternalUnsignedByteArray: - case v8::kExternalPixelArray: - return 1; - case v8::kExternalShortArray: - case v8::kExternalUnsignedShortArray: - return 2; - case v8::kExternalIntArray: - case v8::kExternalUnsignedIntArray: - case v8::kExternalFloatArray: - return 4; - case v8::kExternalDoubleArray: - return 8; - default: - return 0; - } -} - -} // namespace v8_typed_array diff --git a/src/v8_typed_array.h b/src/v8_typed_array.h deleted file mode 100644 index dc518ccdd..000000000 --- a/src/v8_typed_array.h +++ /dev/null @@ -1,35 +0,0 @@ -// V8 Typed Array implementation. -// (c) Dean McNamee <dean@gmail.com>, 2011. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. - -#ifndef V8_TYPED_ARRAY_H_ -#define V8_TYPED_ARRAY_H_ - -#include "v8.h" - -namespace v8_typed_array { - -void AttachBindings(v8::Handle<v8::Object> obj); - -int SizeOfArrayElementForType(v8::ExternalArrayType type); - -} // namespace v8_typed_array - -#endif // V8_TYPED_ARRAY_H_ diff --git a/src/v8_typed_array_bswap.h b/src/v8_typed_array_bswap.h deleted file mode 100644 index 87939bbd5..000000000 --- a/src/v8_typed_array_bswap.h +++ /dev/null @@ -1,201 +0,0 @@ -// V8 Typed Array implementation. -// (c) Dean McNamee <dean@gmail.com>, 2012. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. - -#ifndef V8_TYPED_ARRAY_BSWAP_H_ -#define V8_TYPED_ARRAY_BSWAP_H_ - -// Windows will always be little endian (including ARM), so we just need to -// worry about gcc. -#if defined (__ppc__) || defined (__ppc64__) || defined(__ARMEB__) -#define V8_TYPED_ARRAY_BIG_ENDIAN 1 -#else -#define V8_TYPED_ARRAY_LITTLE_ENDIAN 1 -#endif - -#if defined (_MSC_VER) && (_MSC_VER < 1600) - typedef unsigned char uint8_t; - typedef signed char int8_t; - typedef unsigned __int16 uint16_t; - typedef signed __int16 int16_t; - typedef unsigned __int32 uint32_t; - typedef signed __int32 int32_t; - typedef unsigned __int64 uint64_t; - typedef signed __int64 int64_t; - // Definitions to avoid ICU redefinition issue - #define U_HAVE_INT8_T 1 - #define U_HAVE_UINT8_T 1 - #define U_HAVE_INT16_T 1 - #define U_HAVE_UINT16_T 1 - #define U_HAVE_INT32_T 1 - #define U_HAVE_UINT32_T 1 - #define U_HAVE_INT64_T 1 - #define U_HAVE_UINT64_T 1 -#else - #include <stdint.h> -#endif - -#if defined (_MSC_VER) -#define V8_TYPED_ARRAY_BSWAP16 _byteswap_ushort -#define V8_TYPED_ARRAY_BSWAP32 _byteswap_ulong -#define V8_TYPED_ARRAY_BSWAP64 _byteswap_uint64 -#else -// On LLVM based compilers we can feature test, but for GCC we unfortunately -// have to rely on the version. Additionally __builtin_bswap32/64 were added -// in GCC 4.3, but __builtin_bswap16 was not added until GCC 4.8. -// We should be able to assume GCC/LLVM here (and can use ULL constants, etc). -// Fallback swap macros taken from QEMU bswap.h -#ifdef __has_builtin -#define V8_TYPED_ARRAY_BSWAP_HAS_BUILTIN(x) __has_builtin(x) -#define V8_TYPED_ARRAY_BSWAP_HAS_BUILTIN16(x) __has_builtin(x) -#else -#define V8_TYPED_ARRAY_BSWAP_HAS_BUILTIN(x) (defined(__GNUC__) && \ - (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) -#define V8_TYPED_ARRAY_BSWAP_HAS_BUILTIN16(x) (defined(__GNUC__) && \ - (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) -#endif - -#if V8_TYPED_ARRAY_BSWAP_HAS_BUILTIN(__builtin_bswap64) -#define V8_TYPED_ARRAY_BSWAP64 __builtin_bswap64 -#else -#define V8_TYPED_ARRAY_BSWAP64(x) \ -({ \ - uint64_t __x = (x); \ - ((uint64_t)( \ - (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000000000ffULL) << 56) | \ - (uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000000000ff00ULL) << 40) | \ - (uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \ - (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000ff000000ULL) << 8) | \ - (uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \ - (uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \ - (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \ - (uint64_t)(((uint64_t)(__x) & (uint64_t)0xff00000000000000ULL) >> 56) )); \ -}) -#endif - -#if V8_TYPED_ARRAY_BSWAP_HAS_BUILTIN(__builtin_bswap32) -#define V8_TYPED_ARRAY_BSWAP32 __builtin_bswap32 -#else -#define V8_TYPED_ARRAY_BSWAP32(x) \ -({ \ - uint32_t __x = (x); \ - ((uint32_t)( \ - (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \ - (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) << 8) | \ - (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >> 8) | \ - (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) )); \ -}) -#endif - -#if V8_TYPED_ARRAY_BSWAP_HAS_BUILTIN16(__builtin_bswap16) -#define V8_TYPED_ARRAY_BSWAP16 __builtin_bswap16 -#else -#define V8_TYPED_ARRAY_BSWAP16(x) \ -({ \ - uint16_t __x = (x); \ - ((uint16_t)( \ - (((uint16_t)(__x) & (uint16_t)0x00ffU) << 8) | \ - (((uint16_t)(__x) & (uint16_t)0xff00U) >> 8) )); \ -}) -#endif -#endif - - -namespace v8_typed_array { - -template <typename T> -inline T SwapBytes(T x) { - typedef char NoSwapBytesForType[sizeof(T) == 0 ? 1 : -1]; - return 0; -} - -template <> -inline signed char SwapBytes(signed char x) { return x; } -template <> -inline unsigned char SwapBytes(unsigned char x) { return x; } -template <> -inline uint16_t SwapBytes(uint16_t x) { return V8_TYPED_ARRAY_BSWAP16(x); } -template <> -inline int16_t SwapBytes(int16_t x) { return V8_TYPED_ARRAY_BSWAP16(x); } -template <> -inline uint32_t SwapBytes(uint32_t x) { return V8_TYPED_ARRAY_BSWAP32(x); } -template <> -inline int32_t SwapBytes(int32_t x) { return V8_TYPED_ARRAY_BSWAP32(x); } -template <> -inline uint64_t SwapBytes(uint64_t x) { return V8_TYPED_ARRAY_BSWAP64(x); } -template <> -inline int64_t SwapBytes(int64_t x) { return V8_TYPED_ARRAY_BSWAP64(x); } - -template <typename T> // General implementation for all non-FP types. -inline T LoadAndSwapBytes(void* ptr) { - T val; - memcpy(&val, ptr, sizeof(T)); - return SwapBytes(val); -} - -template <> -inline float LoadAndSwapBytes<float>(void* ptr) { - typedef char VerifySizesAreEqual[sizeof(uint32_t) == sizeof(float) ? 1 : -1]; - uint32_t swappable; - float val; - memcpy(&swappable, ptr, sizeof(swappable)); - swappable = SwapBytes(swappable); - memcpy(&val, &swappable, sizeof(swappable)); - return val; -} - -template <> -inline double LoadAndSwapBytes<double>(void* ptr) { - typedef char VerifySizesAreEqual[sizeof(uint64_t) == sizeof(double) ? 1 : -1]; - uint64_t swappable; - double val; - memcpy(&swappable, ptr, sizeof(swappable)); - swappable = SwapBytes(swappable); - memcpy(&val, &swappable, sizeof(swappable)); - return val; -} - -template <typename T> // General implementation for all non-FP types. -inline void SwapBytesAndStore(void* ptr, T val) { - val = SwapBytes(val); - memcpy(ptr, &val, sizeof(T)); -} - -template <> -inline void SwapBytesAndStore(void* ptr, float val) { - typedef char VerifySizesAreEqual[sizeof(uint32_t) == sizeof(float) ? 1 : -1]; - uint32_t swappable; - memcpy(&swappable, &val, sizeof(swappable)); - swappable = SwapBytes(swappable); - memcpy(ptr, &swappable, sizeof(swappable)); -} - -template <> -inline void SwapBytesAndStore(void* ptr, double val) { - typedef char VerifySizesAreEqual[sizeof(uint64_t) == sizeof(double) ? 1 : -1]; - uint64_t swappable; - memcpy(&swappable, &val, sizeof(swappable)); - swappable = SwapBytes(swappable); - memcpy(ptr, &swappable, sizeof(swappable)); -} - -} // namespace v8_typed_array - -#endif // V8_TYPED_ARRAY_BSWAP_H_ |