@@ -75,12 +75,12 @@ void PipeWrap::Initialize(Handle<Object> target,
Environment* env = Environment::GetCurrent(context);

Local<FunctionTemplate> t = FunctionTemplate::New(New);
t->SetClassName(FIXED_ONE_BYTE_STRING(node_isolate, "Pipe"));
t->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Pipe"));
t->InstanceTemplate()->SetInternalFieldCount(1);

enum PropertyAttribute attributes =
static_cast<PropertyAttribute>(v8::ReadOnly | v8::DontDelete);
t->InstanceTemplate()->SetAccessor(FIXED_ONE_BYTE_STRING(node_isolate, "fd"),
t->InstanceTemplate()->SetAccessor(env->fd_string(),
StreamWrap::GetFD,
NULL,
Handle<Value>(),
@@ -111,7 +111,7 @@ void PipeWrap::Initialize(Handle<Object> target,
NODE_SET_PROTOTYPE_METHOD(t, "setPendingInstances", SetPendingInstances);
#endif

target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "Pipe"), t->GetFunction());
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Pipe"), t->GetFunction());
env->set_pipe_constructor_template(t);
}

@@ -140,7 +140,8 @@ PipeWrap::PipeWrap(Environment* env, Handle<Object> object, bool ipc)


void PipeWrap::Bind(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

PipeWrap* wrap = Unwrap<PipeWrap>(args.This());

@@ -152,7 +153,8 @@ void PipeWrap::Bind(const FunctionCallbackInfo<Value>& args) {

#ifdef _WIN32
void PipeWrap::SetPendingInstances(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

PipeWrap* wrap = Unwrap<PipeWrap>(args.This());

@@ -164,7 +166,8 @@ void PipeWrap::SetPendingInstances(const FunctionCallbackInfo<Value>& args) {


void PipeWrap::Listen(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

PipeWrap* wrap = Unwrap<PipeWrap>(args.This());

@@ -190,7 +193,7 @@ void PipeWrap::OnConnection(uv_stream_t* handle, int status) {
assert(pipe_wrap->persistent().IsEmpty() == false);

Local<Value> argv[] = {
Integer::New(status, node_isolate),
Integer::New(status, env->isolate()),
Undefined()
};

@@ -239,7 +242,7 @@ void PipeWrap::AfterConnect(uv_connect_t* req, int status) {

Local<Object> req_wrap_obj = req_wrap->object();
Local<Value> argv[5] = {
Integer::New(status, node_isolate),
Integer::New(status, env->isolate()),
wrap->object(),
req_wrap_obj,
Boolean::New(readable),
@@ -253,7 +256,8 @@ void PipeWrap::AfterConnect(uv_connect_t* req, int status) {


void PipeWrap::Open(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

PipeWrap* wrap = Unwrap<PipeWrap>(args.This());

@@ -50,9 +50,10 @@ class ProcessWrap : public HandleWrap {
static void Initialize(Handle<Object> target,
Handle<Value> unused,
Handle<Context> context) {
Environment* env = Environment::GetCurrent(context);
Local<FunctionTemplate> constructor = FunctionTemplate::New(New);
constructor->InstanceTemplate()->SetInternalFieldCount(1);
constructor->SetClassName(FIXED_ONE_BYTE_STRING(node_isolate, "Process"));
constructor->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Process"));

NODE_SET_PROTOTYPE_METHOD(constructor, "close", HandleWrap::Close);

@@ -62,7 +63,7 @@ class ProcessWrap : public HandleWrap {
NODE_SET_PROTOTYPE_METHOD(constructor, "ref", HandleWrap::Ref);
NODE_SET_PROTOTYPE_METHOD(constructor, "unref", HandleWrap::Unref);

target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "Process"),
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Process"),
constructor->GetFunction());
}

@@ -90,8 +91,7 @@ class ProcessWrap : public HandleWrap {
static void ParseStdioOptions(Environment* env,
Local<Object> js_options,
uv_process_options_t* options) {
Local<String> stdio_key =
FIXED_ONE_BYTE_STRING(node_isolate, "stdio");
Local<String> stdio_key = env->stdio_string();
Local<Array> stdios = js_options->Get(stdio_key).As<Array>();

uint32_t len = stdios->Length();
@@ -100,31 +100,28 @@ class ProcessWrap : public HandleWrap {

for (uint32_t i = 0; i < len; i++) {
Local<Object> stdio = stdios->Get(i).As<Object>();
Local<Value> type =
stdio->Get(FIXED_ONE_BYTE_STRING(node_isolate, "type"));
Local<Value> type = stdio->Get(env->type_string());

if (type->Equals(FIXED_ONE_BYTE_STRING(node_isolate, "ignore"))) {
if (type->Equals(env->ignore_string())) {
options->stdio[i].flags = UV_IGNORE;
} else if (type->Equals(FIXED_ONE_BYTE_STRING(node_isolate, "pipe"))) {
} else if (type->Equals(env->pipe_string())) {
options->stdio[i].flags = static_cast<uv_stdio_flags>(
UV_CREATE_PIPE | UV_READABLE_PIPE | UV_WRITABLE_PIPE);
Local<String> handle_key =
FIXED_ONE_BYTE_STRING(node_isolate, "handle");
Local<String> handle_key = env->handle_string();
Local<Object> handle = stdio->Get(handle_key).As<Object>();
options->stdio[i].data.stream =
reinterpret_cast<uv_stream_t*>(
Unwrap<PipeWrap>(handle)->UVHandle());
} else if (type->Equals(FIXED_ONE_BYTE_STRING(node_isolate, "wrap"))) {
Local<String> handle_key =
FIXED_ONE_BYTE_STRING(node_isolate, "handle");
} else if (type->Equals(env->wrap_string())) {
Local<String> handle_key = env->handle_string();
Local<Object> handle = stdio->Get(handle_key).As<Object>();
uv_stream_t* stream = HandleToStream(env, handle);
assert(stream != NULL);

options->stdio[i].flags = UV_INHERIT_STREAM;
options->stdio[i].data.stream = stream;
} else {
Local<String> fd_key = FIXED_ONE_BYTE_STRING(node_isolate, "fd");
Local<String> fd_key = env->fd_string();
int fd = static_cast<int>(stdio->Get(fd_key)->IntegerValue());
options->stdio[i].flags = UV_INHERIT_FD;
options->stdio[i].data.fd = fd;
@@ -146,48 +143,44 @@ class ProcessWrap : public HandleWrap {
options.exit_cb = OnExit;

// options.uid
Local<Value> uid_v =
js_options->Get(FIXED_ONE_BYTE_STRING(node_isolate, "uid"));
Local<Value> uid_v = js_options->Get(env->uid_string());
if (uid_v->IsInt32()) {
int32_t uid = uid_v->Int32Value();
if (uid & ~((uv_uid_t) ~0)) {
return ThrowRangeError("options.uid is out of range");
return env->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 ThrowTypeError("options.uid should be a number");
return env->ThrowTypeError("options.uid should be a number");
}

// options.gid
Local<Value> gid_v =
js_options->Get(FIXED_ONE_BYTE_STRING(node_isolate, "gid"));
Local<Value> gid_v = js_options->Get(env->gid_string());
if (gid_v->IsInt32()) {
int32_t gid = gid_v->Int32Value();
if (gid & ~((uv_gid_t) ~0)) {
return ThrowRangeError("options.gid is out of range");
return env->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 ThrowTypeError("options.gid should be a number");
return env->ThrowTypeError("options.gid should be a number");
}

// TODO(bnoordhuis) is this possible to do without mallocing ?

// options.file
Local<Value> file_v =
js_options->Get(FIXED_ONE_BYTE_STRING(node_isolate, "file"));
Local<Value> file_v = js_options->Get(env->file_string());
String::Utf8Value file(file_v->IsString() ? file_v : Local<Value>());
if (file.length() > 0) {
options.file = *file;
} else {
return ThrowTypeError("Bad argument");
return env->ThrowTypeError("Bad argument");
}

// options.args
Local<Value> argv_v =
js_options->Get(FIXED_ONE_BYTE_STRING(node_isolate, "args"));
Local<Value> argv_v = js_options->Get(env->args_string());
if (!argv_v.IsEmpty() && argv_v->IsArray()) {
Local<Array> js_argv = Local<Array>::Cast(argv_v);
int argc = js_argv->Length();
@@ -201,16 +194,14 @@ class ProcessWrap : public HandleWrap {
}

// options.cwd
Local<Value> cwd_v =
js_options->Get(FIXED_ONE_BYTE_STRING(node_isolate, "cwd"));
Local<Value> cwd_v = js_options->Get(env->cwd_string());
String::Utf8Value cwd(cwd_v->IsString() ? cwd_v : Local<Value>());
if (cwd.length() > 0) {
options.cwd = *cwd;
}

// options.env
Local<Value> env_v =
js_options->Get(FIXED_ONE_BYTE_STRING(node_isolate, "envPairs"));
Local<Value> env_v = js_options->Get(env->env_pairs_string());
if (!env_v.IsEmpty() && env_v->IsArray()) {
Local<Array> env = Local<Array>::Cast(env_v);
int envc = env->Length();
@@ -227,14 +218,13 @@ class ProcessWrap : public HandleWrap {

// options.windows_verbatim_arguments
Local<String> windows_verbatim_arguments_key =
FIXED_ONE_BYTE_STRING(node_isolate, "windowsVerbatimArguments");
env->windows_verbatim_arguments_string();
if (js_options->Get(windows_verbatim_arguments_key)->IsTrue()) {
options.flags |= UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS;
}

// options.detached
Local<String> detached_key =
FIXED_ONE_BYTE_STRING(node_isolate, "detached");
Local<String> detached_key = env->detached_string();
if (js_options->Get(detached_key)->IsTrue()) {
options.flags |= UV_PROCESS_DETACHED;
}
@@ -243,8 +233,8 @@ class ProcessWrap : public HandleWrap {

if (err == 0) {
assert(wrap->process_.data == wrap);
wrap->object()->Set(FIXED_ONE_BYTE_STRING(node_isolate, "pid"),
Integer::New(wrap->process_.pid, node_isolate));
wrap->object()->Set(env->pid_string(),
Integer::New(wrap->process_.pid, env->isolate()));
}

if (options.args) {
@@ -263,7 +253,8 @@ class ProcessWrap : public HandleWrap {
}

static void Kill(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());
ProcessWrap* wrap = Unwrap<ProcessWrap>(args.This());

int signal = args[0]->Int32Value();
@@ -283,8 +274,8 @@ class ProcessWrap : public HandleWrap {
Context::Scope context_scope(env->context());

Local<Value> argv[] = {
Number::New(node_isolate, static_cast<double>(exit_status)),
OneByteString(node_isolate, signo_string(term_signal))
Number::New(env->isolate(), static_cast<double>(exit_status)),
OneByteString(env->isolate(), signo_string(term_signal))
};

wrap->MakeCallback(env->onexit_string(), ARRAY_SIZE(argv), argv);
@@ -46,17 +46,18 @@ class SignalWrap : public HandleWrap {
static void Initialize(Handle<Object> target,
Handle<Value> unused,
Handle<Context> context) {
Environment* env = Environment::GetCurrent(context);
Local<FunctionTemplate> constructor = FunctionTemplate::New(New);
constructor->InstanceTemplate()->SetInternalFieldCount(1);
constructor->SetClassName(FIXED_ONE_BYTE_STRING(node_isolate, "Signal"));
constructor->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Signal"));

NODE_SET_PROTOTYPE_METHOD(constructor, "close", HandleWrap::Close);
NODE_SET_PROTOTYPE_METHOD(constructor, "ref", HandleWrap::Ref);
NODE_SET_PROTOTYPE_METHOD(constructor, "unref", HandleWrap::Unref);
NODE_SET_PROTOTYPE_METHOD(constructor, "start", Start);
NODE_SET_PROTOTYPE_METHOD(constructor, "stop", Stop);

target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "Signal"),
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Signal"),
constructor->GetFunction());
}

@@ -84,7 +85,8 @@ class SignalWrap : public HandleWrap {
}

static void Start(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());
SignalWrap* wrap = Unwrap<SignalWrap>(args.This());

int signum = args[0]->Int32Value();
@@ -93,7 +95,8 @@ class SignalWrap : public HandleWrap {
}

static void Stop(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());
SignalWrap* wrap = Unwrap<SignalWrap>(args.This());

int err = uv_signal_stop(&wrap->handle_);
@@ -95,20 +95,21 @@ size_t ExternalArraySize(enum ExternalArrayType type) {

// copyOnto(source, source_start, dest, dest_start, copy_length)
void CopyOnto(const FunctionCallbackInfo<Value>& args) {
HandleScope handle_scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

if (!args[0]->IsObject())
return ThrowTypeError("source must be an object");
return env->ThrowTypeError("source must be an object");
if (!args[2]->IsObject())
return ThrowTypeError("dest must be an object");
return env->ThrowTypeError("dest must be an object");

Local<Object> source = args[0].As<Object>();
Local<Object> dest = args[2].As<Object>();

if (!source->HasIndexedPropertiesInExternalArrayData())
return ThrowError("source has no external array data");
return env->ThrowError("source has no external array data");
if (!dest->HasIndexedPropertiesInExternalArrayData())
return ThrowError("dest has no external array data");
return env->ThrowError("dest has no external array data");

size_t source_start = args[1]->Uint32Value();
size_t dest_start = args[3]->Uint32Value();
@@ -131,16 +132,16 @@ void CopyOnto(const FunctionCallbackInfo<Value>& args) {
// optimization for Uint8 arrays (i.e. Buffers)
if (source_size != 1 && dest_size != 1) {
if (source_size == 0)
return ThrowTypeError("unknown source external array type");
return env->ThrowTypeError("unknown source external array type");
if (dest_size == 0)
return ThrowTypeError("unknown dest external array type");
return env->ThrowTypeError("unknown dest external array type");

if (source_length * source_size < source_length)
return ThrowRangeError("source_length * source_size overflow");
return env->ThrowRangeError("source_length * source_size overflow");
if (copy_length * source_size < copy_length)
return ThrowRangeError("copy_length * source_size overflow");
return env->ThrowRangeError("copy_length * source_size overflow");
if (dest_length * dest_size < dest_length)
return ThrowRangeError("dest_length * dest_size overflow");
return env->ThrowRangeError("dest_length * dest_size overflow");

source_length *= source_size;
copy_length *= source_size;
@@ -149,19 +150,19 @@ void CopyOnto(const FunctionCallbackInfo<Value>& args) {

// necessary to check in case (source|dest)_start _and_ copy_length overflow
if (copy_length > source_length)
return ThrowRangeError("copy_length > source_length");
return env->ThrowRangeError("copy_length > source_length");
if (copy_length > dest_length)
return ThrowRangeError("copy_length > dest_length");
return env->ThrowRangeError("copy_length > dest_length");
if (source_start > source_length)
return ThrowRangeError("source_start > source_length");
return env->ThrowRangeError("source_start > source_length");
if (dest_start > dest_length)
return ThrowRangeError("dest_start > dest_length");
return env->ThrowRangeError("dest_start > dest_length");

// now we can guarantee these will catch oob access and *_start overflow
if (source_start + copy_length > source_length)
return ThrowRangeError("source_start + copy_length > source_length");
return env->ThrowRangeError("source_start + copy_length > source_length");
if (dest_start + copy_length > dest_length)
return ThrowRangeError("dest_start + copy_length > dest_length");
return env->ThrowRangeError("dest_start + copy_length > dest_length");

memmove(dest_data + dest_start, source_data + source_start, copy_length);
}
@@ -171,7 +172,8 @@ void CopyOnto(const FunctionCallbackInfo<Value>& args) {
// for internal use:
// dest._data = sliceOnto(source, dest, start, end);
void SliceOnto(const FunctionCallbackInfo<Value>& args) {
HandleScope handle_scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

Local<Object> source = args[0].As<Object>();
Local<Object> dest = args[1].As<Object>();
@@ -211,13 +213,14 @@ void SliceOnto(const FunctionCallbackInfo<Value>& args) {
// for internal use:
// alloc(obj, n[, type]);
void Alloc(const FunctionCallbackInfo<Value>& args) {
HandleScope handle_scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

Local<Object> obj = args[0].As<Object>();

// can't perform this check in JS
if (obj->HasIndexedPropertiesInExternalArrayData())
return ThrowTypeError("object already has external array data");
return env->ThrowTypeError("object already has external array data");

size_t length = args[1]->Uint32Value();
enum ExternalArrayType array_type;
@@ -232,37 +235,41 @@ void Alloc(const FunctionCallbackInfo<Value>& args) {
length *= type_length;
}

Alloc(obj, length, array_type);
Alloc(env, obj, length, array_type);
args.GetReturnValue().Set(obj);
}


void Alloc(Handle<Object> obj, size_t length, enum ExternalArrayType type) {
void Alloc(Environment* env,
Handle<Object> obj,
size_t length,
enum ExternalArrayType type) {
size_t type_size = ExternalArraySize(type);

assert(length <= kMaxLength);
assert(type_size > 0);

if (length == 0)
return Alloc(obj, NULL, length, type);
return Alloc(env, obj, NULL, length, type);

char* data = static_cast<char*>(malloc(length));
if (data == NULL) {
FatalError("node::smalloc::Alloc(v8::Handle<v8::Object>, size_t,"
" v8::ExternalArrayType)", "Out Of Memory");
}

Alloc(obj, data, length, type);
Alloc(env, obj, data, length, type);
}


void Alloc(Handle<Object> obj,
void Alloc(Environment* env,
Handle<Object> obj,
char* data,
size_t length,
enum ExternalArrayType type) {
assert(!obj->HasIndexedPropertiesInExternalArrayData());
Persistent<Object> p_obj(node_isolate, obj);
node_isolate->AdjustAmountOfExternalAllocatedMemory(length);
Persistent<Object> p_obj(env->isolate(), obj);
env->isolate()->AdjustAmountOfExternalAllocatedMemory(length);
p_obj.MakeWeak(data, TargetCallback);
p_obj.MarkIndependent();
p_obj.SetWrapperClassId(ALLOC_ID);
@@ -293,20 +300,20 @@ void TargetCallback(Isolate* isolate,

// for internal use: dispose(obj);
void AllocDispose(const FunctionCallbackInfo<Value>& args) {
AllocDispose(args[0].As<Object>());
Environment* env = Environment::GetCurrent(args.GetIsolate());
AllocDispose(env, args[0].As<Object>());
}


void AllocDispose(Handle<Object> obj) {
HandleScope handle_scope(node_isolate);
Environment* env = Environment::GetCurrent(node_isolate);
void AllocDispose(Environment* env, Handle<Object> obj) {
HandleScope handle_scope(env->isolate());

if (env->using_smalloc_alloc_cb()) {
Local<Value> ext_v = obj->GetHiddenValue(env->smalloc_p_string());
if (ext_v->IsExternal()) {
Local<External> ext = ext_v.As<External>();
CallbackInfo* cb_info = static_cast<CallbackInfo*>(ext->Value());
TargetFreeCallback(node_isolate, &cb_info->p_obj, cb_info);
TargetFreeCallback(env->isolate(), &cb_info->p_obj, cb_info);
return;
}
}
@@ -329,12 +336,13 @@ void AllocDispose(Handle<Object> obj) {
free(data);
}
if (length != 0) {
node_isolate->AdjustAmountOfExternalAllocatedMemory(-length);
env->isolate()->AdjustAmountOfExternalAllocatedMemory(-length);
}
}


void Alloc(Handle<Object> obj,
void Alloc(Environment* env,
Handle<Object> obj,
size_t length,
FreeCallback fn,
void* hint,
@@ -349,30 +357,30 @@ void Alloc(Handle<Object> obj,
length *= type_size;

char* data = new char[length];
Alloc(obj, data, length, fn, hint, type);
Alloc(env, obj, data, length, fn, hint, type);
}


void Alloc(Handle<Object> obj,
void Alloc(Environment* env,
Handle<Object> obj,
char* data,
size_t length,
FreeCallback fn,
void* hint,
enum ExternalArrayType type) {
assert(!obj->HasIndexedPropertiesInExternalArrayData());

HandleScope handle_scope(node_isolate);
Environment* env = Environment::GetCurrent(node_isolate);
HandleScope handle_scope(env->isolate());
env->set_using_smalloc_alloc_cb(true);

CallbackInfo* cb_info = new CallbackInfo;
cb_info->cb = fn;
cb_info->hint = hint;
cb_info->p_obj.Reset(node_isolate, obj);
cb_info->p_obj.Reset(env->isolate(), obj);
obj->SetHiddenValue(env->smalloc_p_string(), External::New(cb_info));

node_isolate->AdjustAmountOfExternalAllocatedMemory(length +
sizeof(*cb_info));
env->isolate()->AdjustAmountOfExternalAllocatedMemory(length +
sizeof(*cb_info));
cb_info->p_obj.MakeWeak(cb_info, TargetFreeCallback);
cb_info->p_obj.MarkIndependent();
cb_info->p_obj.SetWrapperClassId(ALLOC_ID);
@@ -404,12 +412,13 @@ void TargetFreeCallback(Isolate* isolate,


void HasExternalData(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args.GetIsolate());
args.GetReturnValue().Set(args[0]->IsObject() &&
HasExternalData(args[0].As<Object>()));
HasExternalData(env, args[0].As<Object>()));
}


bool HasExternalData(Local<Object> obj) {
bool HasExternalData(Environment* env, Local<Object> obj) {
return obj->HasIndexedPropertiesInExternalArrayData();
}

@@ -485,7 +494,7 @@ void Initialize(Handle<Object> exports,

NODE_SET_METHOD(exports, "hasExternalData", HasExternalData);

exports->Set(FIXED_ONE_BYTE_STRING(node_isolate, "kMaxLength"),
exports->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kMaxLength"),
Uint32::NewFromUnsigned(kMaxLength, env->isolate()));

HeapProfiler* heap_profiler = env->isolate()->GetHeapProfiler();
@@ -24,6 +24,7 @@

#include "node.h"
#include "v8.h"
#include "env.h"

namespace node {

@@ -72,22 +73,26 @@ NODE_EXTERN size_t ExternalArraySize(enum v8::ExternalArrayType type);
* v8::Integer::NewFromUnsigned(array_length));
* \code
*/
NODE_EXTERN void Alloc(v8::Handle<v8::Object> obj,
NODE_EXTERN void Alloc(Environment* env,
v8::Handle<v8::Object> obj,
size_t length,
enum v8::ExternalArrayType type =
v8::kExternalUnsignedByteArray);
NODE_EXTERN void Alloc(v8::Handle<v8::Object> obj,
NODE_EXTERN void Alloc(Environment* env,
v8::Handle<v8::Object> obj,
char* data,
size_t length,
enum v8::ExternalArrayType type =
v8::kExternalUnsignedByteArray);
NODE_EXTERN void Alloc(v8::Handle<v8::Object> obj,
NODE_EXTERN void Alloc(Environment* env,
v8::Handle<v8::Object> obj,
size_t length,
FreeCallback fn,
void* hint,
enum v8::ExternalArrayType type =
v8::kExternalUnsignedByteArray);
NODE_EXTERN void Alloc(v8::Handle<v8::Object> obj,
NODE_EXTERN void Alloc(Environment* env,
v8::Handle<v8::Object> obj,
char* data,
size_t length,
FreeCallback fn,
@@ -99,13 +104,13 @@ NODE_EXTERN void Alloc(v8::Handle<v8::Object> obj,
* Free memory associated with an externally allocated object. If no external
* memory is allocated to the object then nothing will happen.
*/
NODE_EXTERN void AllocDispose(v8::Handle<v8::Object> obj);
NODE_EXTERN void AllocDispose(Environment* env, v8::Handle<v8::Object> obj);


/**
* Check if the Object has externally allocated memory.
*/
NODE_EXTERN bool HasExternalData(v8::Local<v8::Object> obj);
NODE_EXTERN bool HasExternalData(Environment* env, v8::Local<v8::Object> obj);

} // namespace smalloc
} // namespace node
@@ -940,6 +940,7 @@ bool SyncProcessRunner::CheckRange(Local<Value> js_value) {

int SyncProcessRunner::CopyJsString(Local<Value> js_value,
const char** target) {
Isolate* isolate = env()->isolate();
Local<String> js_string;
size_t size, written;
char* buffer;
@@ -950,11 +951,11 @@ int SyncProcessRunner::CopyJsString(Local<Value> js_value,
js_string = js_value->ToString();

// Include space for null terminator byte.
size = StringBytes::StorageSize(js_string, UTF8) + 1;
size = StringBytes::StorageSize(isolate, js_string, UTF8) + 1;

buffer = new char[size];

written = StringBytes::Write(buffer, -1, js_string, UTF8);
written = StringBytes::Write(isolate, buffer, -1, js_string, UTF8);
buffer[written] = '\0';

*target = buffer;
@@ -964,6 +965,7 @@ int SyncProcessRunner::CopyJsString(Local<Value> js_value,

int SyncProcessRunner::CopyJsStringArray(Local<Value> js_value,
char** target) {
Isolate* isolate = env()->isolate();
Local<Array> js_array;
uint32_t length;
size_t list_size, data_size, data_offset;
@@ -991,7 +993,7 @@ int SyncProcessRunner::CopyJsStringArray(Local<Value> js_value,
// after every string. Align strings to cache lines.
data_size = 0;
for (uint32_t i = 0; i < length; i++) {
data_size += StringBytes::StorageSize(js_array->Get(i), UTF8) + 1;
data_size += StringBytes::StorageSize(isolate, js_array->Get(i), UTF8) + 1;
data_size = ROUND_UP(data_size, sizeof(void*)); // NOLINT(runtime/sizeof)
}

@@ -1002,7 +1004,8 @@ int SyncProcessRunner::CopyJsStringArray(Local<Value> js_value,

for (uint32_t i = 0; i < length; i++) {
list[i] = buffer + data_offset;
data_offset += StringBytes::Write(buffer + data_offset,
data_offset += StringBytes::Write(isolate,
buffer + data_offset,
-1,
js_array->Get(i),
UTF8);
@@ -196,8 +196,8 @@ class SyncProcessRunner {

static bool IsSet(Local<Value> value);
template <typename t> static bool CheckRange(Local<Value> js_value);
static int CopyJsString(Local<Value> js_value, const char** target);
static int CopyJsStringArray(Local<Value> js_value, char** target);
int CopyJsString(Local<Value> js_value, const char** target);
int CopyJsStringArray(Local<Value> js_value, char** target);

static void ExitCallback(uv_process_t* handle,
int64_t exit_status,
@@ -68,7 +68,8 @@ StreamWrap::StreamWrap(Environment* env,

void StreamWrap::GetFD(Local<String>, const PropertyCallbackInfo<Value>& args) {
#if !defined(_WIN32)
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());
StreamWrap* wrap = Unwrap<StreamWrap>(args.This());
int fd = -1;
if (wrap != NULL && wrap->stream() != NULL) {
@@ -80,15 +81,16 @@ void StreamWrap::GetFD(Local<String>, const PropertyCallbackInfo<Value>& args) {


void StreamWrap::UpdateWriteQueueSize() {
HandleScope scope(node_isolate);
HandleScope scope(env()->isolate());
Local<Integer> write_queue_size =
Integer::NewFromUnsigned(stream()->write_queue_size, node_isolate);
Integer::NewFromUnsigned(stream()->write_queue_size, env()->isolate());
object()->Set(env()->write_queue_size_string(), write_queue_size);
}


void StreamWrap::ReadStart(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

StreamWrap* wrap = Unwrap<StreamWrap>(args.This());

@@ -104,7 +106,8 @@ void StreamWrap::ReadStart(const FunctionCallbackInfo<Value>& args) {


void StreamWrap::ReadStop(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

StreamWrap* wrap = Unwrap<StreamWrap>(args.This());

@@ -124,7 +127,7 @@ void StreamWrap::OnAlloc(uv_handle_t* handle,

template <class WrapType, class UVType>
static Local<Object> AcceptHandle(Environment* env, uv_stream_t* pipe) {
HandleScope scope(node_isolate);
HandleScope scope(env->isolate());
Local<Object> wrap_obj;
UVType* handle;

@@ -227,7 +230,7 @@ void StreamWrap::WriteBuffer(const FunctionCallbackInfo<Value>& args) {
NULL,
StreamWrap::AfterWrite);
req_wrap->Dispatched();
req_wrap_obj->Set(env->async(), True(node_isolate));
req_wrap_obj->Set(env->async(), True(env->isolate()));

if (err) {
req_wrap->~WriteWrap();
@@ -239,7 +242,7 @@ void StreamWrap::WriteBuffer(const FunctionCallbackInfo<Value>& args) {
if (msg != NULL)
req_wrap_obj->Set(env->error_string(), OneByteString(env->isolate(), msg));
req_wrap_obj->Set(env->bytes_string(),
Integer::NewFromUnsigned(length, node_isolate));
Integer::NewFromUnsigned(length, env->isolate()));
args.GetReturnValue().Set(err);
}

@@ -263,9 +266,9 @@ void StreamWrap::WriteStringImpl(const FunctionCallbackInfo<Value>& args) {
// computing their actual size, rather than tripling the storage.
size_t storage_size;
if (encoding == UTF8 && string->Length() > 65535)
storage_size = StringBytes::Size(string, encoding);
storage_size = StringBytes::Size(env->isolate(), string, encoding);
else
storage_size = StringBytes::StorageSize(string, encoding);
storage_size = StringBytes::StorageSize(env->isolate(), string, encoding);

if (storage_size > INT_MAX) {
args.GetReturnValue().Set(UV_ENOBUFS);
@@ -283,7 +286,8 @@ void StreamWrap::WriteStringImpl(const FunctionCallbackInfo<Value>& args) {
bool try_write = storage_size + 15 <= sizeof(stack_storage) &&
(!wrap->is_named_pipe_ipc() || !args[2]->IsObject());
if (try_write) {
data_size = StringBytes::Write(stack_storage,
data_size = StringBytes::Write(env->isolate(),
stack_storage,
storage_size,
string,
encoding);
@@ -313,7 +317,11 @@ void StreamWrap::WriteStringImpl(const FunctionCallbackInfo<Value>& args) {
data_size = buf.len;
} else {
// Write it
data_size = StringBytes::Write(data, storage_size, string, encoding);
data_size = StringBytes::Write(env->isolate(),
data,
storage_size,
string,
encoding);
}

assert(data_size <= storage_size);
@@ -348,7 +356,7 @@ void StreamWrap::WriteStringImpl(const FunctionCallbackInfo<Value>& args) {
}

req_wrap->Dispatched();
req_wrap->object()->Set(env->async(), True(node_isolate));
req_wrap->object()->Set(env->async(), True(env->isolate()));

if (err) {
req_wrap->~WriteWrap();
@@ -360,7 +368,7 @@ void StreamWrap::WriteStringImpl(const FunctionCallbackInfo<Value>& args) {
if (msg != NULL)
req_wrap_obj->Set(env->error_string(), OneByteString(env->isolate(), msg));
req_wrap_obj->Set(env->bytes_string(),
Integer::NewFromUnsigned(data_size, node_isolate));
Integer::NewFromUnsigned(data_size, env->isolate()));
args.GetReturnValue().Set(err);
}

@@ -395,9 +403,9 @@ void StreamWrap::Writev(const FunctionCallbackInfo<Value>& args) {
enum encoding encoding = ParseEncoding(chunks->Get(i * 2 + 1));
size_t chunk_size;
if (encoding == UTF8 && string->Length() > 65535)
chunk_size = StringBytes::Size(string, encoding);
chunk_size = StringBytes::Size(env->isolate(), string, encoding);
else
chunk_size = StringBytes::StorageSize(string, encoding);
chunk_size = StringBytes::StorageSize(env->isolate(), string, encoding);

storage_size += chunk_size + 15;
}
@@ -436,7 +444,11 @@ void StreamWrap::Writev(const FunctionCallbackInfo<Value>& args) {

Handle<String> string = chunk->ToString();
enum encoding encoding = ParseEncoding(chunks->Get(i * 2 + 1));
str_size = StringBytes::Write(str_storage, str_size, string, encoding);
str_size = StringBytes::Write(env->isolate(),
str_storage,
str_size,
string,
encoding);
bufs[i].base = str_storage;
bufs[i].len = str_size;
offset += str_size;
@@ -454,9 +466,9 @@ void StreamWrap::Writev(const FunctionCallbackInfo<Value>& args) {
delete[] bufs;

req_wrap->Dispatched();
req_wrap->object()->Set(env->async(), True(node_isolate));
req_wrap->object()->Set(env->async(), True(env->isolate()));
req_wrap->object()->Set(env->bytes_string(),
Number::New(node_isolate, bytes));
Number::New(env->isolate(), bytes));
const char* msg = wrap->callbacks()->Error();
if (msg != NULL)
req_wrap_obj->Set(env->error_string(), OneByteString(env->isolate(), msg));
@@ -503,7 +515,7 @@ void StreamWrap::AfterWrite(uv_write_t* req, int status) {
wrap->callbacks()->AfterWrite(req_wrap);

Local<Value> argv[] = {
Integer::New(status, node_isolate),
Integer::New(status, env->isolate()),
wrap->object(),
req_wrap_obj,
Undefined()
@@ -554,7 +566,7 @@ void StreamWrap::AfterShutdown(uv_shutdown_t* req, int status) {

Local<Object> req_wrap_obj = req_wrap->object();
Local<Value> argv[3] = {
Integer::New(status, node_isolate),
Integer::New(status, env->isolate()),
wrap->object(),
req_wrap_obj
};
@@ -668,7 +680,7 @@ void StreamWrapCallbacks::DoRead(uv_stream_t* handle,
Context::Scope context_scope(env->context());

Local<Value> argv[] = {
Integer::New(nread, node_isolate),
Integer::New(nread, env->isolate()),
Undefined(),
Undefined()
};
@@ -38,6 +38,7 @@ namespace node {

using v8::Handle;
using v8::HandleScope;
using v8::Isolate;
using v8::Local;
using v8::String;
using v8::Value;
@@ -46,9 +47,12 @@ using v8::Value;
template <typename ResourceType, typename TypeName>
class ExternString: public ResourceType {
public:
explicit ExternString(Isolate* isolate) : isolate_(isolate) {
}

~ExternString() {
delete[] data_;
node_isolate->AdjustAmountOfExternalAllocatedMemory(-length_);
isolate()->AdjustAmountOfExternalAllocatedMemory(-length_);
}

const TypeName* data() const {
@@ -59,37 +63,46 @@ class ExternString: public ResourceType {
return length_;
}

static Local<String> NewFromCopy(const TypeName* data, size_t length) {
HandleScope scope(node_isolate);
static Local<String> NewFromCopy(Isolate* isolate,
const TypeName* data,
size_t length) {
HandleScope scope(isolate);

if (length == 0)
return scope.Close(String::Empty(node_isolate));
return scope.Close(String::Empty(isolate));

TypeName* new_data = new TypeName[length];
memcpy(new_data, data, length * sizeof(*new_data));

return scope.Close(ExternString<ResourceType, TypeName>::New(new_data,
return scope.Close(ExternString<ResourceType, TypeName>::New(isolate,
new_data,
length));
}

// uses "data" for external resource, and will be free'd on gc
static Local<String> New(const TypeName* data, size_t length) {
HandleScope scope(node_isolate);
static Local<String> New(Isolate* isolate,
const TypeName* data,
size_t length) {
HandleScope scope(isolate);

if (length == 0)
return scope.Close(String::Empty(node_isolate));
return scope.Close(String::Empty(isolate));

ExternString* h_str = new ExternString<ResourceType, TypeName>(data,
ExternString* h_str = new ExternString<ResourceType, TypeName>(isolate,
data,
length);
Local<String> str = String::NewExternal(h_str);
node_isolate->AdjustAmountOfExternalAllocatedMemory(length);
isolate->AdjustAmountOfExternalAllocatedMemory(length);

return scope.Close(str);
}

inline Isolate* isolate() const { return isolate_; }

private:
ExternString(const TypeName* data, size_t length)
: data_(data), length_(length) { }
ExternString(Isolate* isolate, const TypeName* data, size_t length)
: isolate_(isolate), data_(data), length_(length) { }
Isolate* isolate_;
const TypeName* data_;
size_t length_;
};
@@ -244,7 +257,8 @@ size_t hex_decode(char* buf,
}


bool StringBytes::GetExternalParts(Handle<Value> val,
bool StringBytes::GetExternalParts(Isolate* isolate,
Handle<Value> val,
const char** data,
size_t* len) {
if (Buffer::HasInstance(val)) {
@@ -277,15 +291,16 @@ bool StringBytes::GetExternalParts(Handle<Value> val,
}


size_t StringBytes::Write(char* buf,
size_t StringBytes::Write(Isolate* isolate,
char* buf,
size_t buflen,
Handle<Value> val,
enum encoding encoding,
int* chars_written) {
HandleScope scope(node_isolate);
HandleScope scope(isolate);
const char* data;
size_t len = 0;
bool is_extern = GetExternalParts(val, &data, &len);
bool is_extern = GetExternalParts(isolate, val, &data, &len);

Local<String> str = val.As<String>();
len = len < buflen ? len : buflen;
@@ -358,7 +373,9 @@ size_t StringBytes::Write(char* buf,
}


bool StringBytes::IsValidString(Handle<String> string, enum encoding enc) {
bool StringBytes::IsValidString(Isolate* isolate,
Handle<String> string,
enum encoding enc) {
if (enc == HEX && string->Length() % 2 != 0)
return false;
// TODO(bnoordhuis) Add BASE64 check?
@@ -369,8 +386,10 @@ bool StringBytes::IsValidString(Handle<String> string, enum encoding enc) {
// Quick and dirty size calculation
// Will always be at least big enough, but may have some extra
// UTF8 can be as much as 3x the size, Base64 can have 1-2 extra bytes
size_t StringBytes::StorageSize(Handle<Value> val, enum encoding encoding) {
HandleScope scope(node_isolate);
size_t StringBytes::StorageSize(Isolate* isolate,
Handle<Value> val,
enum encoding encoding) {
HandleScope scope(isolate);
size_t data_size = 0;
bool is_buffer = Buffer::HasInstance(val);

@@ -416,16 +435,18 @@ size_t StringBytes::StorageSize(Handle<Value> val, enum encoding encoding) {
}


size_t StringBytes::Size(Handle<Value> val, enum encoding encoding) {
HandleScope scope(node_isolate);
size_t StringBytes::Size(Isolate* isolate,
Handle<Value> val,
enum encoding encoding) {
HandleScope scope(isolate);
size_t data_size = 0;
bool is_buffer = Buffer::HasInstance(val);

if (is_buffer && (encoding == BUFFER || encoding == BINARY))
return Buffer::Length(val);

const char* data;
if (GetExternalParts(val, &data, &data_size))
if (GetExternalParts(isolate, val, &data, &data_size))
return data_size;

Local<String> str = val->ToString();
@@ -651,14 +672,15 @@ static size_t hex_encode(const char* src, size_t slen, char* dst, size_t dlen) {



Local<Value> StringBytes::Encode(const char* buf,
Local<Value> StringBytes::Encode(Isolate* isolate,
const char* buf,
size_t buflen,
enum encoding encoding) {
HandleScope scope(node_isolate);
HandleScope scope(isolate);

assert(buflen <= Buffer::kMaxLength);
if (!buflen && encoding != BUFFER)
return scope.Close(String::Empty(node_isolate));
return scope.Close(String::Empty(isolate));

Local<String> val;
switch (encoding) {
@@ -670,31 +692,31 @@ Local<Value> StringBytes::Encode(const char* buf,
char* out = new char[buflen];
force_ascii(buf, out, buflen);
if (buflen < EXTERN_APEX) {
val = OneByteString(node_isolate, out, buflen);
val = OneByteString(isolate, out, buflen);
delete[] out;
} else {
val = ExternOneByteString::New(out, buflen);
val = ExternOneByteString::New(isolate, out, buflen);
}
} else {
if (buflen < EXTERN_APEX)
val = OneByteString(node_isolate, buf, buflen);
val = OneByteString(isolate, buf, buflen);
else
val = ExternOneByteString::NewFromCopy(buf, buflen);
val = ExternOneByteString::NewFromCopy(isolate, buf, buflen);
}
break;

case UTF8:
val = String::NewFromUtf8(node_isolate,
val = String::NewFromUtf8(isolate,
buf,
String::kNormalString,
buflen);
break;

case BINARY:
if (buflen < EXTERN_APEX)
val = OneByteString(node_isolate, buf, buflen);
val = OneByteString(isolate, buf, buflen);
else
val = ExternOneByteString::NewFromCopy(buf, buflen);
val = ExternOneByteString::NewFromCopy(isolate, buf, buflen);
break;

case BASE64: {
@@ -705,23 +727,23 @@ Local<Value> StringBytes::Encode(const char* buf,
assert(written == dlen);

if (dlen < EXTERN_APEX) {
val = OneByteString(node_isolate, dst, dlen);
val = OneByteString(isolate, dst, dlen);
delete[] dst;
} else {
val = ExternOneByteString::New(dst, dlen);
val = ExternOneByteString::New(isolate, dst, dlen);
}
break;
}

case UCS2: {
const uint16_t* out = reinterpret_cast<const uint16_t*>(buf);
if (buflen < EXTERN_APEX)
val = String::NewFromTwoByte(node_isolate,
val = String::NewFromTwoByte(isolate,
out,
String::kNormalString,
buflen / 2);
else
val = ExternTwoByteString::NewFromCopy(out, buflen / 2);
val = ExternTwoByteString::NewFromCopy(isolate, out, buflen / 2);
break;
}

@@ -732,10 +754,10 @@ Local<Value> StringBytes::Encode(const char* buf,
assert(written == dlen);

if (dlen < EXTERN_APEX) {
val = OneByteString(node_isolate, dst, dlen);
val = OneByteString(isolate, dst, dlen);
delete[] dst;
} else {
val = ExternOneByteString::New(dst, dlen);
val = ExternOneByteString::New(isolate, dst, dlen);
}
break;
}
@@ -34,36 +34,91 @@ class StringBytes {
// Does the string match the encoding? Quick but non-exhaustive.
// Example: a HEX string must have a length that's a multiple of two.
// FIXME(bnoordhuis) IsMaybeValidString()? Naming things is hard...
static bool IsValidString(v8::Handle<v8::String> string, enum encoding enc);
static bool IsValidString(v8::Isolate* isolate,
v8::Handle<v8::String> string,
enum encoding enc);

// Fast, but can be 2 bytes oversized for Base64, and
// as much as triple UTF-8 strings <= 65536 chars in length
static size_t StorageSize(v8::Handle<v8::Value> val, enum encoding enc);
static size_t StorageSize(v8::Isolate* isolate,
v8::Handle<v8::Value> val,
enum encoding enc);

// Precise byte count, but slightly slower for Base64 and
// very much slower for UTF-8
static size_t Size(v8::Handle<v8::Value> val, enum encoding enc);
static size_t Size(v8::Isolate* isolate,
v8::Handle<v8::Value> val,
enum encoding enc);

// If the string is external then assign external properties to data and len,
// then return true. If not return false.
static bool GetExternalParts(v8::Handle<v8::Value> val,
static bool GetExternalParts(v8::Isolate* isolate,
v8::Handle<v8::Value> val,
const char** data,
size_t* len);

// Write the bytes from the string or buffer into the char*
// returns the number of bytes written, which will always be
// <= buflen. Use StorageSize/Size first to know how much
// memory to allocate.
static size_t Write(char* buf,
static size_t Write(v8::Isolate* isolate,
char* buf,
size_t buflen,
v8::Handle<v8::Value> val,
enum encoding enc,
int* chars_written = NULL);

// Take the bytes in the src, and turn it into a Buffer or String.
static v8::Local<v8::Value> Encode(const char* buf,
static v8::Local<v8::Value> Encode(v8::Isolate* isolate,
const char* buf,
size_t buflen,
enum encoding encoding);

// Deprecated legacy interface

NODE_DEPRECATED("Use IsValidString(isolate, ...)",
static inline bool IsValidString(
v8::Handle<v8::String> string,
enum encoding enc) {
return IsValidString(v8::Isolate::GetCurrent(), string, enc);
})

NODE_DEPRECATED("Use StorageSize(isolate, ...)",
static inline size_t StorageSize(v8::Handle<v8::Value> val,
enum encoding enc) {
return StorageSize(v8::Isolate::GetCurrent(), val, enc);
})

NODE_DEPRECATED("Use Size(isolate, ...)",
static inline size_t Size(v8::Handle<v8::Value> val,
enum encoding enc) {
return Size(v8::Isolate::GetCurrent(), val, enc);
})

NODE_DEPRECATED("Use GetExternalParts(isolate, ...)",
static inline bool GetExternalParts(v8::Handle<v8::Value> val,
const char** data,
size_t* len) {
return GetExternalParts(v8::Isolate::GetCurrent(), val, data, len);
})

NODE_DEPRECATED("Use Write(isolate, ...)",
static inline size_t Write(char* buf,
size_t buflen,
v8::Handle<v8::Value> val,
enum encoding enc,
int* chars_written = NULL) {
v8::Isolate* isolate = v8::Isolate::GetCurrent();
return Write(isolate, buf, buflen, val, enc, chars_written);
})

NODE_DEPRECATED("Use Encode(isolate, ...)",
static inline v8::Local<v8::Value> Encode(
const char* buf,
size_t buflen,
enum encoding encoding) {
return Encode(v8::Isolate::GetCurrent(), buf, buflen, encoding);
})
};

} // namespace node
@@ -70,12 +70,12 @@ void TCPWrap::Initialize(Handle<Object> target,
Environment* env = Environment::GetCurrent(context);

Local<FunctionTemplate> t = FunctionTemplate::New(New);
t->SetClassName(FIXED_ONE_BYTE_STRING(node_isolate, "TCP"));
t->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "TCP"));
t->InstanceTemplate()->SetInternalFieldCount(1);

enum PropertyAttribute attributes =
static_cast<PropertyAttribute>(v8::ReadOnly | v8::DontDelete);
t->InstanceTemplate()->SetAccessor(FIXED_ONE_BYTE_STRING(node_isolate, "fd"),
t->InstanceTemplate()->SetAccessor(env->fd_string(),
StreamWrap::GetFD,
NULL,
Handle<Value>(),
@@ -116,7 +116,7 @@ void TCPWrap::Initialize(Handle<Object> target,
SetSimultaneousAccepts);
#endif

target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "TCP"), t->GetFunction());
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "TCP"), t->GetFunction());
env->set_tcp_constructor_template(t);
}

@@ -202,7 +202,8 @@ void TCPWrap::GetPeerName(const FunctionCallbackInfo<Value>& args) {


void TCPWrap::SetNoDelay(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

TCPWrap* wrap = Unwrap<TCPWrap>(args.This());

@@ -213,7 +214,8 @@ void TCPWrap::SetNoDelay(const FunctionCallbackInfo<Value>& args) {


void TCPWrap::SetKeepAlive(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

TCPWrap* wrap = Unwrap<TCPWrap>(args.This());

@@ -227,7 +229,8 @@ void TCPWrap::SetKeepAlive(const FunctionCallbackInfo<Value>& args) {

#ifdef _WIN32
void TCPWrap::SetSimultaneousAccepts(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

TCPWrap* wrap = Unwrap<TCPWrap>(args.This());

@@ -239,15 +242,17 @@ void TCPWrap::SetSimultaneousAccepts(const FunctionCallbackInfo<Value>& args) {


void TCPWrap::Open(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());
TCPWrap* wrap = Unwrap<TCPWrap>(args.This());
int fd = args[0]->IntegerValue();
uv_tcp_open(&wrap->handle_, fd);
}


void TCPWrap::Bind(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

TCPWrap* wrap = Unwrap<TCPWrap>(args.This());

@@ -267,7 +272,8 @@ void TCPWrap::Bind(const FunctionCallbackInfo<Value>& args) {


void TCPWrap::Bind6(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

TCPWrap* wrap = Unwrap<TCPWrap>(args.This());

@@ -287,7 +293,8 @@ void TCPWrap::Bind6(const FunctionCallbackInfo<Value>& args) {


void TCPWrap::Listen(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

TCPWrap* wrap = Unwrap<TCPWrap>(args.This());

@@ -312,7 +319,7 @@ void TCPWrap::OnConnection(uv_stream_t* handle, int status) {
assert(tcp_wrap->persistent().IsEmpty() == false);

Local<Value> argv[2] = {
Integer::New(status, node_isolate),
Integer::New(status, env->isolate()),
Undefined()
};

@@ -349,11 +356,11 @@ void TCPWrap::AfterConnect(uv_connect_t* req, int status) {

Local<Object> req_wrap_obj = req_wrap->object();
Local<Value> argv[5] = {
Integer::New(status, node_isolate),
Integer::New(status, env->isolate()),
wrap->object(),
req_wrap_obj,
v8::True(node_isolate),
v8::True(node_isolate)
v8::True(env->isolate()),
v8::True(env->isolate())
};

req_wrap->MakeCallback(env->oncomplete_string(), ARRAY_SIZE(argv), argv);
@@ -434,7 +441,7 @@ void TCPWrap::Connect6(const FunctionCallbackInfo<Value>& args) {
Local<Object> AddressToJS(Environment* env,
const sockaddr* addr,
Local<Object> info) {
HandleScope scope(node_isolate);
HandleScope scope(env->isolate());
char ip[INET6_ADDRSTRLEN];
const sockaddr_in *a4;
const sockaddr_in6 *a6;
@@ -448,22 +455,22 @@ Local<Object> AddressToJS(Environment* env,
a6 = reinterpret_cast<const sockaddr_in6*>(addr);
uv_inet_ntop(AF_INET6, &a6->sin6_addr, ip, sizeof ip);
port = ntohs(a6->sin6_port);
info->Set(env->address_string(), OneByteString(node_isolate, ip));
info->Set(env->address_string(), OneByteString(env->isolate(), ip));
info->Set(env->family_string(), env->ipv6_string());
info->Set(env->port_string(), Integer::New(port, node_isolate));
info->Set(env->port_string(), Integer::New(port, env->isolate()));
break;

case AF_INET:
a4 = reinterpret_cast<const sockaddr_in*>(addr);
uv_inet_ntop(AF_INET, &a4->sin_addr, ip, sizeof ip);
port = ntohs(a4->sin_port);
info->Set(env->address_string(), OneByteString(node_isolate, ip));
info->Set(env->address_string(), OneByteString(env->isolate(), ip));
info->Set(env->family_string(), env->ipv4_string());
info->Set(env->port_string(), Integer::New(port, node_isolate));
info->Set(env->port_string(), Integer::New(port, env->isolate()));
break;

default:
info->Set(env->address_string(), String::Empty(node_isolate));
info->Set(env->address_string(), String::Empty(env->isolate()));
}

return scope.Close(info);
@@ -49,11 +49,12 @@ class TimerWrap : public HandleWrap {
static void Initialize(Handle<Object> target,
Handle<Value> unused,
Handle<Context> context) {
Environment* env = Environment::GetCurrent(context);
Local<FunctionTemplate> constructor = FunctionTemplate::New(New);
constructor->InstanceTemplate()->SetInternalFieldCount(1);
constructor->SetClassName(FIXED_ONE_BYTE_STRING(node_isolate, "Timer"));
constructor->Set(FIXED_ONE_BYTE_STRING(node_isolate, "kOnTimeout"),
Integer::New(kOnTimeout, node_isolate));
constructor->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Timer"));
constructor->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kOnTimeout"),
Integer::New(kOnTimeout, env->isolate()));

NODE_SET_METHOD(constructor, "now", Now);

@@ -67,7 +68,7 @@ class TimerWrap : public HandleWrap {
NODE_SET_PROTOTYPE_METHOD(constructor, "getRepeat", GetRepeat);
NODE_SET_PROTOTYPE_METHOD(constructor, "again", Again);

target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "Timer"),
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Timer"),
constructor->GetFunction());
}

@@ -95,7 +96,8 @@ class TimerWrap : public HandleWrap {
}

static void Start(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());
TimerWrap* wrap = Unwrap<TimerWrap>(args.This());

int64_t timeout = args[0]->IntegerValue();
@@ -105,23 +107,26 @@ class TimerWrap : public HandleWrap {
}

static void Stop(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());
TimerWrap* wrap = Unwrap<TimerWrap>(args.This());

int err = uv_timer_stop(&wrap->handle_);
args.GetReturnValue().Set(err);
}

static void Again(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());
TimerWrap* wrap = Unwrap<TimerWrap>(args.This());

int err = uv_timer_again(&wrap->handle_);
args.GetReturnValue().Set(err);
}

static void SetRepeat(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());
TimerWrap* wrap = Unwrap<TimerWrap>(args.This());

int64_t repeat = args[0]->IntegerValue();
@@ -130,7 +135,8 @@ class TimerWrap : public HandleWrap {
}

static void GetRepeat(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());
TimerWrap* wrap = Unwrap<TimerWrap>(args.This());

int64_t repeat = uv_timer_get_repeat(&wrap->handle_);
@@ -142,7 +148,7 @@ class TimerWrap : public HandleWrap {
Environment* env = wrap->env();
HandleScope handle_scope(env->isolate());
Context::Scope context_scope(env->context());
Local<Value> argv[1] = { Integer::New(status, node_isolate) };
Local<Value> argv[1] = { Integer::New(status, env->isolate()) };
wrap->MakeCallback(kOnTimeout, ARRAY_SIZE(argv), argv);
}

@@ -209,12 +209,16 @@ void TLSCallbacks::Wrap(const FunctionCallbackInfo<Value>& args) {
HandleScope handle_scope(args.GetIsolate());
Environment* env = Environment::GetCurrent(args.GetIsolate());

if (args.Length() < 1 || !args[0]->IsObject())
return ThrowTypeError("First argument should be a StreamWrap instance");
if (args.Length() < 2 || !args[1]->IsObject())
return ThrowTypeError("Second argument should be a SecureContext instance");
if (args.Length() < 1 || !args[0]->IsObject()) {
return env->ThrowTypeError(
"First argument should be a StreamWrap instance");
}
if (args.Length() < 2 || !args[1]->IsObject()) {
return env->ThrowTypeError(
"Second argument should be a SecureContext instance");
}
if (args.Length() < 3 || !args[2]->IsBoolean())
return ThrowTypeError("Third argument should be boolean");
return env->ThrowTypeError("Third argument should be boolean");

Local<Object> stream = args[0].As<Object>();
Local<Object> sc = args[1].As<Object>();
@@ -261,12 +265,13 @@ void TLSCallbacks::Receive(const FunctionCallbackInfo<Value>& args) {


void TLSCallbacks::Start(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

TLSCallbacks* wrap = Unwrap<TLSCallbacks>(args.This());

if (wrap->started_)
return ThrowError("Already started.");
return env->ThrowError("Already started.");
wrap->started_ = true;

// Send ClientHello handshake
@@ -403,7 +408,7 @@ const char* TLSCallbacks::PrintErrors() {


Local<Value> TLSCallbacks::GetSSLError(int status, int* err, const char** msg) {
HandleScope scope(node_isolate);
HandleScope scope(env()->isolate());

*err = SSL_get_error(ssl_, status);
switch (*err) {
@@ -412,7 +417,7 @@ Local<Value> TLSCallbacks::GetSSLError(int status, int* err, const char** msg) {
case SSL_ERROR_WANT_WRITE:
break;
case SSL_ERROR_ZERO_RETURN:
return scope.Close(FIXED_ONE_BYTE_STRING(node_isolate, "ZERO_RETURN"));
return scope.Close(env()->zero_return_string());
break;
default:
{
@@ -421,7 +426,7 @@ Local<Value> TLSCallbacks::GetSSLError(int status, int* err, const char** msg) {
const char* buf = PrintErrors();

Local<String> message =
OneByteString(node_isolate, buf, strlen(buf));
OneByteString(env()->isolate(), buf, strlen(buf));
Local<Value> exception = Exception::Error(message);

if (msg != NULL) {
@@ -452,7 +457,7 @@ void TLSCallbacks::ClearOut() {
read = SSL_read(ssl_, out, sizeof(out));
if (read > 0) {
Local<Value> argv[] = {
Integer::New(read, node_isolate),
Integer::New(read, env()->isolate()),
Buffer::New(env(), out, read)
};
wrap()->MakeCallback(env()->onread_string(), ARRAY_SIZE(argv), argv);
@@ -462,7 +467,7 @@ void TLSCallbacks::ClearOut() {
int flags = SSL_get_shutdown(ssl_);
if (!eof_ && flags & SSL_RECEIVED_SHUTDOWN) {
eof_ = true;
Local<Value> arg = Integer::New(UV_EOF, node_isolate);
Local<Value> arg = Integer::New(UV_EOF, env()->isolate());
wrap()->MakeCallback(env()->onread_string(), 1, &arg);
}

@@ -629,7 +634,7 @@ void TLSCallbacks::DoRead(uv_stream_t* handle,

HandleScope handle_scope(env()->isolate());
Context::Scope context_scope(env()->context());
Local<Value> arg = Integer::New(nread, node_isolate);
Local<Value> arg = Integer::New(nread, env()->isolate());
wrap()->MakeCallback(env()->onread_string(), 1, &arg);
return;
}
@@ -664,12 +669,13 @@ int TLSCallbacks::DoShutdown(ShutdownWrap* req_wrap, uv_shutdown_cb cb) {


void TLSCallbacks::SetVerifyMode(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

TLSCallbacks* wrap = Unwrap<TLSCallbacks>(args.This());

if (args.Length() < 2 || !args[0]->IsBoolean() || !args[1]->IsBoolean())
return ThrowTypeError("Bad arguments, expected two booleans");
return env->ThrowTypeError("Bad arguments, expected two booleans");

int verify_mode;
if (wrap->is_server()) {
@@ -695,7 +701,8 @@ void TLSCallbacks::SetVerifyMode(const FunctionCallbackInfo<Value>& args) {

void TLSCallbacks::EnableSessionCallbacks(
const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

TLSCallbacks* wrap = Unwrap<TLSCallbacks>(args.This());

@@ -705,7 +712,8 @@ void TLSCallbacks::EnableSessionCallbacks(


void TLSCallbacks::EnableHelloParser(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

TLSCallbacks* wrap = Unwrap<TLSCallbacks>(args.This());

@@ -723,30 +731,32 @@ void TLSCallbacks::OnClientHelloParseEnd(void* arg) {

#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
void TLSCallbacks::GetServername(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

TLSCallbacks* wrap = Unwrap<TLSCallbacks>(args.This());

const char* servername = SSL_get_servername(wrap->ssl_,
TLSEXT_NAMETYPE_host_name);
if (servername != NULL) {
args.GetReturnValue().Set(OneByteString(node_isolate, servername));
args.GetReturnValue().Set(OneByteString(env->isolate(), servername));
} else {
args.GetReturnValue().Set(false);
}
}


void TLSCallbacks::SetServername(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

TLSCallbacks* wrap = Unwrap<TLSCallbacks>(args.This());

if (args.Length() < 1 || !args[0]->IsString())
return ThrowTypeError("First argument should be a string");
return env->ThrowTypeError("First argument should be a string");

if (wrap->started_)
return ThrowError("Already started.");
return env->ThrowError("Already started.");

if (!wrap->is_client())
return;
@@ -785,7 +795,7 @@ int TLSCallbacks::SelectSNIContextCallback(SSL* s, int* ad, void* arg) {
}

p->sni_context_.Dispose();
p->sni_context_.Reset(node_isolate, ctx);
p->sni_context_.Reset(env->isolate(), ctx);

SecureContext* sc = Unwrap<SecureContext>(ctx.As<Object>());
InitNPN(sc, p);
@@ -804,7 +814,7 @@ void TLSCallbacks::Initialize(Handle<Object> target,

Local<FunctionTemplate> t = FunctionTemplate::New();
t->InstanceTemplate()->SetInternalFieldCount(1);
t->SetClassName(FIXED_ONE_BYTE_STRING(node_isolate, "TLSWrap"));
t->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "TLSWrap"));

NODE_SET_PROTOTYPE_METHOD(t, "receive", Receive);
NODE_SET_PROTOTYPE_METHOD(t, "start", Start);
@@ -816,7 +826,7 @@ void TLSCallbacks::Initialize(Handle<Object> target,
"enableHelloParser",
EnableHelloParser);

SSLWrap<TLSCallbacks>::AddMethods(t);
SSLWrap<TLSCallbacks>::AddMethods(env, t);

#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
NODE_SET_PROTOTYPE_METHOD(t, "getServername", GetServername);
@@ -54,12 +54,12 @@ void TTYWrap::Initialize(Handle<Object> target,
Environment* env = Environment::GetCurrent(context);

Local<FunctionTemplate> t = FunctionTemplate::New(New);
t->SetClassName(FIXED_ONE_BYTE_STRING(node_isolate, "TTY"));
t->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "TTY"));
t->InstanceTemplate()->SetInternalFieldCount(1);

enum PropertyAttribute attributes =
static_cast<PropertyAttribute>(v8::ReadOnly | v8::DontDelete);
t->InstanceTemplate()->SetAccessor(FIXED_ONE_BYTE_STRING(node_isolate, "fd"),
t->InstanceTemplate()->SetAccessor(env->fd_string(),
StreamWrap::GetFD,
NULL,
Handle<Value>(),
@@ -85,7 +85,7 @@ void TTYWrap::Initialize(Handle<Object> target,
NODE_SET_METHOD(target, "isTTY", IsTTY);
NODE_SET_METHOD(target, "guessHandleType", GuessHandleType);

target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "TTY"), t->GetFunction());
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "TTY"), t->GetFunction());
env->set_tty_constructor_template(t);
}

@@ -96,7 +96,8 @@ uv_tty_t* TTYWrap::UVHandle() {


void TTYWrap::GuessHandleType(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());
int fd = args[0]->Int32Value();
assert(fd >= 0);

@@ -114,12 +115,13 @@ void TTYWrap::GuessHandleType(const FunctionCallbackInfo<Value>& args) {
abort();
}

args.GetReturnValue().Set(OneByteString(node_isolate, type));
args.GetReturnValue().Set(OneByteString(env->isolate(), type));
}


void TTYWrap::IsTTY(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());
int fd = args[0]->Int32Value();
assert(fd >= 0);
bool rc = uv_guess_handle(fd) == UV_TTY;
@@ -128,7 +130,8 @@ void TTYWrap::IsTTY(const FunctionCallbackInfo<Value>& args) {


void TTYWrap::GetWindowSize(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

TTYWrap* wrap = Unwrap<TTYWrap>(args.This());
assert(args[0]->IsArray());
@@ -138,16 +141,17 @@ void TTYWrap::GetWindowSize(const FunctionCallbackInfo<Value>& args) {

if (err == 0) {
Local<v8::Array> a = args[0].As<Array>();
a->Set(0, Integer::New(width, node_isolate));
a->Set(1, Integer::New(height, node_isolate));
a->Set(0, Integer::New(width, env->isolate()));
a->Set(1, Integer::New(height, env->isolate()));
}

args.GetReturnValue().Set(err);
}


void TTYWrap::SetRawMode(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

TTYWrap* wrap = Unwrap<TTYWrap>(args.This());

@@ -93,11 +93,11 @@ void UDPWrap::Initialize(Handle<Object> target,

Local<FunctionTemplate> t = FunctionTemplate::New(New);
t->InstanceTemplate()->SetInternalFieldCount(1);
t->SetClassName(FIXED_ONE_BYTE_STRING(node_isolate, "UDP"));
t->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "UDP"));

enum PropertyAttribute attributes =
static_cast<PropertyAttribute>(v8::ReadOnly | v8::DontDelete);
t->InstanceTemplate()->SetAccessor(FIXED_ONE_BYTE_STRING(node_isolate, "fd"),
t->InstanceTemplate()->SetAccessor(env->fd_string(),
UDPWrap::GetFD,
NULL,
Handle<Value>(),
@@ -122,7 +122,7 @@ void UDPWrap::Initialize(Handle<Object> target,
NODE_SET_PROTOTYPE_METHOD(t, "ref", HandleWrap::Ref);
NODE_SET_PROTOTYPE_METHOD(t, "unref", HandleWrap::Unref);

target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "UDP"), t->GetFunction());
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "UDP"), t->GetFunction());
env->set_udp_constructor_function(t->GetFunction());
}

@@ -137,7 +137,8 @@ void UDPWrap::New(const FunctionCallbackInfo<Value>& args) {

void UDPWrap::GetFD(Local<String>, const PropertyCallbackInfo<Value>& args) {
#if !defined(_WIN32)
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());
UDPWrap* wrap = Unwrap<UDPWrap>(args.This());
int fd = (wrap == NULL) ? -1 : wrap->handle_.io_watcher.fd;
args.GetReturnValue().Set(fd);
@@ -146,7 +147,8 @@ void UDPWrap::GetFD(Local<String>, const PropertyCallbackInfo<Value>& args) {


void UDPWrap::DoBind(const FunctionCallbackInfo<Value>& args, int family) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());

UDPWrap* wrap = Unwrap<UDPWrap>(args.This());

@@ -193,7 +195,7 @@ void UDPWrap::Bind6(const FunctionCallbackInfo<Value>& args) {

#define X(name, fn) \
void UDPWrap::name(const FunctionCallbackInfo<Value>& args) { \
HandleScope scope(node_isolate); \
HandleScope scope(args.GetIsolate()); \
UDPWrap* wrap = Unwrap<UDPWrap>(args.This()); \
assert(args.Length() == 1); \
int flag = args[0]->Int32Value(); \
@@ -211,7 +213,8 @@ X(SetMulticastLoopback, uv_udp_set_multicast_loop)

void UDPWrap::SetMembership(const FunctionCallbackInfo<Value>& args,
uv_membership membership) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());
UDPWrap* wrap = Unwrap<UDPWrap>(args.This());

assert(args.Length() == 2);
@@ -315,7 +318,8 @@ void UDPWrap::Send6(const FunctionCallbackInfo<Value>& args) {


void UDPWrap::RecvStart(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());
UDPWrap* wrap = Unwrap<UDPWrap>(args.This());

int err = uv_udp_recv_start(&wrap->handle_, OnAlloc, OnRecv);
@@ -327,7 +331,8 @@ void UDPWrap::RecvStart(const FunctionCallbackInfo<Value>& args) {


void UDPWrap::RecvStop(const FunctionCallbackInfo<Value>& args) {
HandleScope scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());
UDPWrap* wrap = Unwrap<UDPWrap>(args.This());

int r = uv_udp_recv_stop(&wrap->handle_);
@@ -366,7 +371,7 @@ void UDPWrap::OnSend(uv_udp_send_t* req, int status) {
Environment* env = req_wrap->env();
HandleScope handle_scope(env->isolate());
Context::Scope context_scope(env->context());
Local<Value> arg = Integer::New(status, node_isolate);
Local<Value> arg = Integer::New(status, env->isolate());
req_wrap->MakeCallback(env->oncomplete_string(), 1, &arg);
}
delete req_wrap;
@@ -405,7 +410,7 @@ void UDPWrap::OnRecv(uv_udp_t* handle,

Local<Object> wrap_obj = wrap->object();
Local<Value> argv[] = {
Integer::New(nread, node_isolate),
Integer::New(nread, env->isolate()),
wrap_obj,
Undefined(env->isolate()),
Undefined(env->isolate())
@@ -21,6 +21,8 @@

#include "uv.h"
#include "node.h"
#include "env.h"
#include "env-inl.h"

namespace node {
namespace uv {
@@ -37,23 +39,25 @@ using v8::Value;


void ErrName(const FunctionCallbackInfo<Value>& args) {
v8::HandleScope handle_scope(node_isolate);
Environment* env = Environment::GetCurrent(args.GetIsolate());
HandleScope scope(env->isolate());
int err = args[0]->Int32Value();
if (err >= 0)
return ThrowError("err >= 0");
return env->ThrowError("err >= 0");
const char* name = uv_err_name(err);
args.GetReturnValue().Set(OneByteString(node_isolate, name));
args.GetReturnValue().Set(OneByteString(env->isolate(), name));
}


void Initialize(Handle<Object> target,
Handle<Value> unused,
Handle<Context> context) {
target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "errname"),
Environment* env = Environment::GetCurrent(context);
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "errname"),
FunctionTemplate::New(ErrName)->GetFunction());
#define V(name, _) \
target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "UV_" # name), \
Integer::New(UV_ ## name, node_isolate));
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "UV_" # name), \
Integer::New(UV_ ## name, env->isolate()));
UV_ERRNO_MAP(V)
#undef V
}