summaryrefslogtreecommitdiff
path: root/src/node.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/node.cc')
-rw-r--r--src/node.cc502
1 files changed, 235 insertions, 267 deletions
diff --git a/src/node.cc b/src/node.cc
index a9c11e0bd1..82be2f9b2b 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()!