src: remove `node_isolate` from source
authorFedor Indutny <fedor.indutny@gmail.com>
Fri, 21 Feb 2014 13:02:42 +0000 (17:02 +0400)
committerFedor Indutny <fedor.indutny@gmail.com>
Fri, 21 Feb 2014 23:20:56 +0000 (03:20 +0400)
fix #6899

42 files changed:
src/cares_wrap.cc
src/env-inl.h
src/env.h
src/fs_event_wrap.cc
src/handle_wrap.cc
src/node.cc
src/node.h
src/node_buffer.cc
src/node_buffer.h
src/node_contextify.cc
src/node_counters.cc
src/node_counters.h
src/node_crypto.cc
src/node_crypto.h
src/node_dtrace.cc
src/node_dtrace.h
src/node_file.cc
src/node_http_parser.cc
src/node_internals.h
src/node_javascript.cc
src/node_javascript.h
src/node_os.cc
src/node_stat_watcher.cc
src/node_stat_watcher.h
src/node_wrap.h
src/node_zlib.cc
src/pipe_wrap.cc
src/process_wrap.cc
src/signal_wrap.cc
src/smalloc.cc
src/smalloc.h
src/spawn_sync.cc
src/spawn_sync.h
src/stream_wrap.cc
src/string_bytes.cc
src/string_bytes.h
src/tcp_wrap.cc
src/timer_wrap.cc
src/tls_wrap.cc
src/tty_wrap.cc
src/udp_wrap.cc
src/uv.cc

index 558d6d5..567b159 100644 (file)
@@ -193,14 +193,14 @@ static void ares_sockstate_cb(void* data,
 }
 
 
-static Local<Array> HostentToAddresses(struct hostent* host) {
-  HandleScope scope(node_isolate);
+static Local<Array> HostentToAddresses(Environment* env, struct hostent* host) {
+  HandleScope scope(env->isolate());
   Local<Array> addresses = Array::New();
 
   char ip[INET6_ADDRSTRLEN];
   for (uint32_t i = 0; host->h_addr_list[i] != NULL; ++i) {
     uv_inet_ntop(host->h_addrtype, host->h_addr_list[i], ip, sizeof(ip));
-    Local<String> address = OneByteString(node_isolate, ip);
+    Local<String> address = OneByteString(env->isolate(), ip);
     addresses->Set(i, address);
   }
 
@@ -208,12 +208,12 @@ static Local<Array> HostentToAddresses(struct hostent* host) {
 }
 
 
-static Local<Array> HostentToNames(struct hostent* host) {
-  HandleScope scope(node_isolate);
+static Local<Array> HostentToNames(Environment* env, struct hostent* host) {
+  HandleScope scope(env->isolate());
   Local<Array> names = Array::New();
 
   for (uint32_t i = 0; host->h_aliases[i] != NULL; ++i) {
-    Local<String> address = OneByteString(node_isolate, host->h_aliases[i]);
+    Local<String> address = OneByteString(env->isolate(), host->h_aliases[i]);
     names->Set(i, address);
   }
 
@@ -377,7 +377,7 @@ class QueryAWrap: public QueryWrap {
       return;
     }
 
-    Local<Array> addresses = HostentToAddresses(host);
+    Local<Array> addresses = HostentToAddresses(env(), host);
     ares_free_hostent(host);
 
     this->CallOnComplete(addresses);
@@ -414,7 +414,7 @@ class QueryAaaaWrap: public QueryWrap {
       return;
     }
 
-    Local<Array> addresses = HostentToAddresses(host);
+    Local<Array> addresses = HostentToAddresses(env(), host);
     ares_free_hostent(host);
 
     this->CallOnComplete(addresses);
@@ -453,7 +453,7 @@ class QueryCnameWrap: public QueryWrap {
     // A cname lookup always returns a single record but we follow the
     // common API here.
     Local<Array> result = Array::New(1);
-    result->Set(0, OneByteString(node_isolate, host->h_name));
+    result->Set(0, OneByteString(env()->isolate(), host->h_name));
     ares_free_hostent(host);
 
     this->CallOnComplete(result);
@@ -490,18 +490,16 @@ class QueryMxWrap: public QueryWrap {
     }
 
     Local<Array> mx_records = Array::New();
-    Local<String> exchange_symbol =
-        FIXED_ONE_BYTE_STRING(node_isolate, "exchange");
-    Local<String> priority_symbol =
-        FIXED_ONE_BYTE_STRING(node_isolate, "priority");
+    Local<String> exchange_symbol = env()->exchange_string();
+    Local<String> priority_symbol = env()->priority_string();
 
     ares_mx_reply* current = mx_start;
     for (uint32_t i = 0; current != NULL; ++i, current = current->next) {
       Local<Object> mx_record = Object::New();
       mx_record->Set(exchange_symbol,
-                     OneByteString(node_isolate, current->host));
+                     OneByteString(env()->isolate(), current->host));
       mx_record->Set(priority_symbol,
-                     Integer::New(current->priority, node_isolate));
+                     Integer::New(current->priority, env()->isolate()));
       mx_records->Set(i, mx_record);
     }
 
@@ -540,7 +538,7 @@ class QueryNsWrap: public QueryWrap {
       return;
     }
 
-    Local<Array> names = HostentToNames(host);
+    Local<Array> names = HostentToNames(env(), host);
     ares_free_hostent(host);
 
     this->CallOnComplete(names);
@@ -580,7 +578,7 @@ class QueryTxtWrap: public QueryWrap {
 
     ares_txt_reply* current = txt_out;
     for (uint32_t i = 0; current != NULL; ++i, current = current->next) {
-      Local<String> txt = OneByteString(node_isolate, current->txt);
+      Local<String> txt = OneByteString(env()->isolate(), current->txt);
       txt_records->Set(i, txt);
     }
 
@@ -620,26 +618,22 @@ class QuerySrvWrap: public QueryWrap {
     }
 
     Local<Array> srv_records = Array::New();
-    Local<String> name_symbol =
-        FIXED_ONE_BYTE_STRING(node_isolate, "name");
-    Local<String> port_symbol =
-        FIXED_ONE_BYTE_STRING(node_isolate, "port");
-    Local<String> priority_symbol =
-        FIXED_ONE_BYTE_STRING(node_isolate, "priority");
-    Local<String> weight_symbol =
-        FIXED_ONE_BYTE_STRING(node_isolate, "weight");
+    Local<String> name_symbol = env()->name_string();
+    Local<String> port_symbol = env()->port_string();
+    Local<String> priority_symbol = env()->priority_string();
+    Local<String> weight_symbol = env()->weight_string();
 
     ares_srv_reply* current = srv_start;
     for (uint32_t i = 0; current != NULL; ++i, current = current->next) {
       Local<Object> srv_record = Object::New();
       srv_record->Set(name_symbol,
-                      OneByteString(node_isolate, current->host));
+                      OneByteString(env()->isolate(), current->host));
       srv_record->Set(port_symbol,
-                      Integer::New(current->port, node_isolate));
+                      Integer::New(current->port, env()->isolate()));
       srv_record->Set(priority_symbol,
-                      Integer::New(current->priority, node_isolate));
+                      Integer::New(current->priority, env()->isolate()));
       srv_record->Set(weight_symbol,
-                      Integer::New(current->weight, node_isolate));
+                      Integer::New(current->weight, env()->isolate()));
       srv_records->Set(i, srv_record);
     }
 
@@ -679,34 +673,28 @@ class QueryNaptrWrap: public QueryWrap {
     }
 
     Local<Array> naptr_records = Array::New();
-    Local<String> flags_symbol =
-        FIXED_ONE_BYTE_STRING(node_isolate, "flags");
-    Local<String> service_symbol =
-        FIXED_ONE_BYTE_STRING(node_isolate, "service");
-    Local<String> regexp_symbol =
-        FIXED_ONE_BYTE_STRING(node_isolate, "regexp");
-    Local<String> replacement_symbol =
-        FIXED_ONE_BYTE_STRING(node_isolate, "replacement");
-    Local<String> order_symbol =
-        FIXED_ONE_BYTE_STRING(node_isolate, "order");
-    Local<String> preference_symbol =
-        FIXED_ONE_BYTE_STRING(node_isolate, "preference");
+    Local<String> flags_symbol = env()->flags_string();
+    Local<String> service_symbol = env()->service_string();
+    Local<String> regexp_symbol = env()->regexp_string();
+    Local<String> replacement_symbol = env()->replacement_string();
+    Local<String> order_symbol = env()->order_string();
+    Local<String> preference_symbol = env()->preference_string();
 
     ares_naptr_reply* current = naptr_start;
     for (uint32_t i = 0; current != NULL; ++i, current = current->next) {
       Local<Object> naptr_record = Object::New();
       naptr_record->Set(flags_symbol,
-                        OneByteString(node_isolate, current->flags));
+                        OneByteString(env()->isolate(), current->flags));
       naptr_record->Set(service_symbol,
-                        OneByteString(node_isolate, current->service));
+                        OneByteString(env()->isolate(), current->service));
       naptr_record->Set(regexp_symbol,
-                        OneByteString(node_isolate, current->regexp));
+                        OneByteString(env()->isolate(), current->regexp));
       naptr_record->Set(replacement_symbol,
-                        OneByteString(node_isolate, current->replacement));
+                        OneByteString(env()->isolate(), current->replacement));
       naptr_record->Set(order_symbol,
-                        Integer::New(current->order, node_isolate));
+                        Integer::New(current->order, env()->isolate()));
       naptr_record->Set(preference_symbol,
-                        Integer::New(current->preference, node_isolate));
+                        Integer::New(current->preference, env()->isolate()));
       naptr_records->Set(i, naptr_record);
     }
 
@@ -748,20 +736,20 @@ class QuerySoaWrap: public QueryWrap {
 
     Local<Object> soa_record = Object::New();
 
-    soa_record->Set(FIXED_ONE_BYTE_STRING(node_isolate, "nsname"),
-                    OneByteString(node_isolate, soa_out->nsname));
-    soa_record->Set(FIXED_ONE_BYTE_STRING(node_isolate, "hostmaster"),
-                    OneByteString(node_isolate, soa_out->hostmaster));
-    soa_record->Set(FIXED_ONE_BYTE_STRING(node_isolate, "serial"),
-                    Integer::New(soa_out->serial, node_isolate));
-    soa_record->Set(FIXED_ONE_BYTE_STRING(node_isolate, "refresh"),
-                    Integer::New(soa_out->refresh, node_isolate));
-    soa_record->Set(FIXED_ONE_BYTE_STRING(node_isolate, "retry"),
-                    Integer::New(soa_out->retry, node_isolate));
-    soa_record->Set(FIXED_ONE_BYTE_STRING(node_isolate, "expire"),
-                    Integer::New(soa_out->expire, node_isolate));
-    soa_record->Set(FIXED_ONE_BYTE_STRING(node_isolate, "minttl"),
-                    Integer::New(soa_out->minttl, node_isolate));
+    soa_record->Set(env()->nsname_string(),
+                    OneByteString(env()->isolate(), soa_out->nsname));
+    soa_record->Set(env()->hostmaster_string(),
+                    OneByteString(env()->isolate(), soa_out->hostmaster));
+    soa_record->Set(env()->serial_string(),
+                    Integer::New(soa_out->serial, env()->isolate()));
+    soa_record->Set(env()->refresh_string(),
+                    Integer::New(soa_out->refresh, env()->isolate()));
+    soa_record->Set(env()->retry_string(),
+                    Integer::New(soa_out->retry, env()->isolate()));
+    soa_record->Set(env()->expire_string(),
+                    Integer::New(soa_out->expire, env()->isolate()));
+    soa_record->Set(env()->minttl_string(),
+                    Integer::New(soa_out->minttl, env()->isolate()));
 
     ares_free_data(soa_out);
 
@@ -803,7 +791,7 @@ class GetHostByAddrWrap: public QueryWrap {
   void Parse(struct hostent* host) {
     HandleScope handle_scope(env()->isolate());
     Context::Scope context_scope(env()->context());
-    this->CallOnComplete(HostentToNames(host));
+    this->CallOnComplete(HostentToNames(env(), host));
   }
 };
 
@@ -825,10 +813,10 @@ class GetHostByNameWrap: public QueryWrap {
 
  protected:
   void Parse(struct hostent* host) {
-    HandleScope scope(node_isolate);
+    HandleScope scope(env()->isolate());
 
-    Local<Array> addresses = HostentToAddresses(host);
-    Local<Integer> family = Integer::New(host->h_addrtype, node_isolate);
+    Local<Array> addresses = HostentToAddresses(env(), host);
+    Local<Integer> family = Integer::New(host->h_addrtype, env()->isolate());
 
     this->CallOnComplete(addresses, family);
   }
@@ -865,8 +853,8 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
   Context::Scope context_scope(env->context());
 
   Local<Value> argv[] = {
-    Integer::New(status, node_isolate),
-    Null(node_isolate)
+    Integer::New(status, env->isolate()),
+    Null(env->isolate())
   };
 
   if (status == 0) {
@@ -906,7 +894,7 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
           continue;
 
         // Create JavaScript string
-        Local<String> s = OneByteString(node_isolate, ip);
+        Local<String> s = OneByteString(env->isolate(), ip);
         results->Set(n, s);
         n++;
       }
@@ -933,7 +921,7 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
           continue;
 
         // Create JavaScript string
-        Local<String> s = OneByteString(node_isolate, ip);
+        Local<String> s = OneByteString(env->isolate(), ip);
         results->Set(n, s);
         n++;
       }
@@ -956,7 +944,8 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
 
 
 static void IsIP(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   String::AsciiValue ip(args[0]);
   char address_buffer[sizeof(struct in6_addr)];
@@ -1041,7 +1030,7 @@ static void GetServers(const FunctionCallbackInfo<Value>& args) {
     int err = uv_inet_ntop(cur->family, caddr, ip, sizeof(ip));
     assert(err == 0);
 
-    Local<String> addr = OneByteString(node_isolate, ip);
+    Local<String> addr = OneByteString(env->isolate(), ip);
     server_array->Set(i, addr);
   }
 
@@ -1121,9 +1110,10 @@ static void SetServers(const FunctionCallbackInfo<Value>& args) {
 
 
 static void StrError(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
   const char* errmsg = ares_strerror(args[0]->Int32Value());
-  args.GetReturnValue().Set(OneByteString(node_isolate, errmsg));
+  args.GetReturnValue().Set(OneByteString(env->isolate(), errmsg));
 }
 
 
@@ -1169,12 +1159,12 @@ static void Initialize(Handle<Object> target,
   NODE_SET_METHOD(target, "getServers", GetServers);
   NODE_SET_METHOD(target, "setServers", SetServers);
 
-  target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "AF_INET"),
-              Integer::New(AF_INET, node_isolate));
-  target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "AF_INET6"),
-              Integer::New(AF_INET6, node_isolate));
-  target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "AF_UNSPEC"),
-              Integer::New(AF_UNSPEC, node_isolate));
+  target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "AF_INET"),
+              Integer::New(AF_INET, env->isolate()));
+  target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "AF_INET6"),
+              Integer::New(AF_INET6, env->isolate()));
+  target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "AF_UNSPEC"),
+              Integer::New(AF_UNSPEC, env->isolate()));
 }
 
 }  // namespace cares_wrap
index 7d0a9dd..bcc7995 100644 (file)
@@ -23,6 +23,7 @@
 #define SRC_ENV_INL_H_
 
 #include "env.h"
+#include "node.h"
 #include "util.h"
 #include "util-inl.h"
 #include "uv.h"
@@ -364,6 +365,57 @@ inline Environment::IsolateData* Environment::isolate_data() const {
   return isolate_data_;
 }
 
+// this would have been a template function were it not for the fact that g++
+// sometimes fails to resolve it...
+#define THROW_ERROR(fun)                                                      \
+  do {                                                                        \
+    v8::HandleScope scope(isolate);                                           \
+    v8::ThrowException(fun(OneByteString(isolate, errmsg)));                 \
+  }                                                                           \
+  while (0)
+
+inline void Environment::ThrowError(v8::Isolate* isolate, const char* errmsg) {
+  THROW_ERROR(v8::Exception::Error);
+}
+
+inline void Environment::ThrowTypeError(v8::Isolate* isolate,
+                                        const char* errmsg) {
+  THROW_ERROR(v8::Exception::TypeError);
+}
+
+inline void Environment::ThrowRangeError(v8::Isolate* isolate,
+                                         const char* errmsg) {
+  THROW_ERROR(v8::Exception::RangeError);
+}
+
+inline void Environment::ThrowError(const char* errmsg) {
+  ThrowError(isolate(), errmsg);
+}
+
+inline void Environment::ThrowTypeError(const char* errmsg) {
+  ThrowTypeError(isolate(), errmsg);
+}
+
+inline void Environment::ThrowRangeError(const char* errmsg) {
+  ThrowRangeError(isolate(), errmsg);
+}
+
+inline void Environment::ThrowErrnoException(int errorno,
+                                             const char* syscall,
+                                             const char* message,
+                                             const char* path) {
+  v8::ThrowException(
+      ErrnoException(isolate(), errorno, syscall, message, path));
+}
+
+inline void Environment::ThrowUVException(int errorno,
+                                          const char* syscall,
+                                          const char* message,
+                                          const char* path) {
+  v8::ThrowException(
+      UVException(isolate(), errorno, syscall, message, path));
+}
+
 #define V(PropertyName, StringValue)                                          \
   inline                                                                      \
   v8::Local<v8::String> Environment::IsolateData::PropertyName() const {      \
index f04403d..73a810d 100644 (file)
--- a/src/env.h
+++ b/src/env.h
@@ -54,6 +54,7 @@ namespace node {
 #define PER_ISOLATE_STRING_PROPERTIES(V)                                      \
   V(address_string, "address")                                                \
   V(args_string, "args")                                                      \
+  V(argv_string, "argv")                                                      \
   V(async_queue_string, "_asyncQueue")                                        \
   V(async, "async")                                                           \
   V(atime_string, "atime")                                                    \
@@ -62,21 +63,35 @@ namespace node {
   V(blocks_string, "blocks")                                                  \
   V(buffer_string, "buffer")                                                  \
   V(bytes_string, "bytes")                                                    \
+  V(bytes_parsed_string, "bytesParsed")                                       \
+  V(byte_length_string, "byteLength")                                         \
   V(callback_string, "callback")                                              \
   V(change_string, "change")                                                  \
   V(close_string, "close")                                                    \
   V(code_string, "code")                                                      \
   V(ctime_string, "ctime")                                                    \
   V(cwd_string, "cwd")                                                        \
+  V(debug_port_string, "debugPort")                                           \
+  V(debug_string, "debug")                                                    \
   V(detached_string, "detached")                                              \
   V(dev_string, "dev")                                                        \
   V(disposed_string, "_disposed")                                             \
   V(domain_string, "domain")                                                  \
+  V(exchange_string, "exchange")                                              \
+  V(idle_string, "idle")                                                      \
+  V(irq_string, "irq")                                                        \
   V(enter_string, "enter")                                                    \
   V(env_pairs_string, "envPairs")                                             \
+  V(env_string, "env")                                                        \
   V(errno_string, "errno")                                                    \
   V(error_string, "error")                                                    \
+  V(events_string, "_events")                                                 \
+  V(exec_argv_string, "execArgv")                                             \
+  V(exec_path_string, "execPath")                                             \
+  V(exiting_string, "_exiting")                                               \
+  V(exit_code_string, "exitCode")                                             \
   V(exit_string, "exit")                                                      \
+  V(expire_string, "expire")                                                  \
   V(exponent_string, "exponent")                                              \
   V(exports_string, "exports")                                                \
   V(ext_key_usage_string, "ext_key_usage")                                    \
@@ -86,30 +101,42 @@ namespace node {
   V(file_string, "file")                                                      \
   V(fingerprint_string, "fingerprint")                                        \
   V(flags_string, "flags")                                                    \
+  V(fsevent_string, "FSEvent")                                                \
   V(gid_string, "gid")                                                        \
   V(handle_string, "handle")                                                  \
   V(headers_string, "headers")                                                \
   V(heap_size_limit_string, "heap_size_limit")                                \
   V(heap_total_string, "heapTotal")                                           \
   V(heap_used_string, "heapUsed")                                             \
+  V(hostmaster_string, "hostmaster")                                          \
   V(ignore_string, "ignore")                                                  \
   V(immediate_callback_string, "_immediateCallback")                          \
   V(inherit_string, "inherit")                                                \
   V(ino_string, "ino")                                                        \
   V(input_string, "input")                                                    \
+  V(internal_string, "internal")                                              \
   V(ipv4_string, "IPv4")                                                      \
+  V(ipv6_lc_string, "ipv6")                                                   \
   V(ipv6_string, "IPv6")                                                      \
   V(issuer_string, "issuer")                                                  \
   V(kill_signal_string, "killSignal")                                         \
+  V(mac_string, "mac")                                                        \
   V(mark_sweep_compact_string, "mark-sweep-compact")                          \
   V(max_buffer_string, "maxBuffer")                                           \
   V(message_string, "message")                                                \
   V(method_string, "method")                                                  \
+  V(minttl_string, "minttl")                                                  \
   V(mode_string, "mode")                                                      \
+  V(model_string, "model")                                                    \
   V(modulus_string, "modulus")                                                \
   V(mtime_string, "mtime")                                                    \
   V(name_string, "name")                                                      \
+  V(need_imm_cb_string, "_needImmediateCallback")                             \
+  V(netmask_string, "netmask")                                                \
+  V(nice_string, "nice")                                                      \
   V(nlink_string, "nlink")                                                    \
+  V(nsname_string, "nsname")                                                  \
+  V(offset_string, "offset")                                                  \
   V(onchange_string, "onchange")                                              \
   V(onclienthello_string, "onclienthello")                                    \
   V(oncomplete_string, "oncomplete")                                          \
@@ -127,17 +154,33 @@ namespace node {
   V(onsignal_string, "onsignal")                                              \
   V(onstop_string, "onstop")                                                  \
   V(output_string, "output")                                                  \
+  V(order_string, "order")                                                    \
+  V(owner_string, "owner")                                                    \
+  V(parse_error_string, "Parse Error")                                        \
   V(path_string, "path")                                                      \
+  V(pbkdf2_error_string, "PBKDF2 Error")                                      \
   V(pid_string, "pid")                                                        \
   V(pipe_string, "pipe")                                                      \
   V(port_string, "port")                                                      \
+  V(preference_string, "preference")                                          \
+  V(priority_string, "priority")                                              \
   V(processed_string, "processed")                                            \
+  V(prototype_string, "prototype")                                            \
   V(rdev_string, "rdev")                                                      \
   V(readable_string, "readable")                                              \
+  V(received_shutdown_string, "receivedShutdown")                             \
+  V(refresh_string, "refresh")                                                \
+  V(regexp_string, "regexp")                                                  \
   V(rename_string, "rename")                                                  \
+  V(replacement_string, "replacement")                                        \
+  V(retry_string, "retry")                                                    \
   V(rss_string, "rss")                                                        \
+  V(serial_string, "serial")                                                  \
   V(scavenge_string, "scavenge")                                              \
+  V(scopeid_string, "scopeid")                                                \
+  V(sent_shutdown_string, "sentShutdown")                                     \
   V(serial_number_string, "serialNumber")                                     \
+  V(service_string, "service")                                                \
   V(servername_string, "servername")                                          \
   V(session_id_string, "sessionId")                                           \
   V(should_keep_alive_string, "shouldKeepAlive")                              \
@@ -146,6 +189,7 @@ namespace node {
   V(smalloc_p_string, "_smalloc_p")                                           \
   V(sni_context_err_string, "Invalid SNI context")                            \
   V(sni_context_string, "sni_context")                                        \
+  V(speed_string, "speed")                                                    \
   V(stack_string, "stack")                                                    \
   V(status_code_string, "statusCode")                                         \
   V(status_message_string, "statusMessage")                                   \
@@ -153,27 +197,43 @@ namespace node {
   V(stdio_string, "stdio")                                                    \
   V(subject_string, "subject")                                                \
   V(subjectaltname_string, "subjectaltname")                                  \
+  V(sys_string, "sys")                                                        \
   V(syscall_string, "syscall")                                                \
+  V(tick_callback_string, "_tickCallback")                                    \
+  V(tick_domain_cb_string, "_tickDomainCallback")                             \
+  V(tick_info_string, "_tickInfo")                                            \
   V(timeout_string, "timeout")                                                \
+  V(times_string, "times")                                                    \
   V(timestamp_string, "timestamp")                                            \
+  V(title_string, "title")                                                    \
+  V(tls_npn_string, "tls_npn")                                                \
+  V(tls_sni_string, "tls_sni")                                                \
+  V(tls_string, "tls")                                                        \
   V(tls_ticket_string, "tlsTicket")                                           \
   V(total_heap_size_executable_string, "total_heap_size_executable")          \
   V(total_heap_size_string, "total_heap_size")                                \
   V(total_physical_size_string, "total_physical_size")                        \
   V(type_string, "type")                                                      \
   V(uid_string, "uid")                                                        \
+  V(unknown_string, "<unknown>")                                              \
   V(upgrade_string, "upgrade")                                                \
   V(url_string, "url")                                                        \
   V(used_heap_size_string, "used_heap_size")                                  \
+  V(user_string, "user")                                                      \
+  V(uv_string, "uv")                                                          \
   V(valid_from_string, "valid_from")                                          \
   V(valid_to_string, "valid_to")                                              \
   V(verify_error_string, "verifyError")                                       \
   V(version_major_string, "versionMajor")                                     \
   V(version_minor_string, "versionMinor")                                     \
   V(version_string, "version")                                                \
+  V(weight_string, "weight")                                                  \
   V(windows_verbatim_arguments_string, "windowsVerbatimArguments")            \
+  V(wrap_string, "wrap")                                                      \
   V(writable_string, "writable")                                              \
   V(write_queue_size_string, "writeQueueSize")                                \
+  V(x_forwarded_string, "x-forwarded-for")                                    \
+  V(zero_return_string, "ZERO_RETURN")                                        \
 
 #define ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V)                           \
   V(async_listener_run_function, v8::Function)                                \
@@ -331,6 +391,23 @@ class Environment {
   inline bool printed_error() const;
   inline void set_printed_error(bool value);
 
+  inline void ThrowError(const char* errmsg);
+  inline void ThrowTypeError(const char* errmsg);
+  inline void ThrowRangeError(const char* errmsg);
+  inline void ThrowErrnoException(int errorno,
+                                  const char* syscall = NULL,
+                                  const char* message = NULL,
+                                  const char* path = NULL);
+  inline void ThrowUVException(int errorno,
+                               const char* syscall = NULL,
+                               const char* message = NULL,
+                               const char* path = NULL);
+
+  // Convenience methods for contextify
+  inline static void ThrowError(v8::Isolate* isolate, const char* errmsg);
+  inline static void ThrowTypeError(v8::Isolate* isolate, const char* errmsg);
+  inline static void ThrowRangeError(v8::Isolate* isolate, const char* errmsg);
+
   // Strings are shared across shared contexts. The getters simply proxy to
   // the per-isolate primitive.
 #define V(PropertyName, StringValue)                                          \
index 28b20ac..ee28c44 100644 (file)
@@ -81,14 +81,16 @@ FSEventWrap::~FSEventWrap() {
 void FSEventWrap::Initialize(Handle<Object> target,
                              Handle<Value> unused,
                              Handle<Context> context) {
+  Environment* env = Environment::GetCurrent(context);
+
   Local<FunctionTemplate> t = FunctionTemplate::New(New);
   t->InstanceTemplate()->SetInternalFieldCount(1);
-  t->SetClassName(FIXED_ONE_BYTE_STRING(node_isolate, "FSEvent"));
+  t->SetClassName(env->fsevent_string());
 
   NODE_SET_PROTOTYPE_METHOD(t, "start", Start);
   NODE_SET_PROTOTYPE_METHOD(t, "close", Close);
 
-  target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "FSEvent"), t->GetFunction());
+  target->Set(env->fsevent_string(), t->GetFunction());
 }
 
 
@@ -101,12 +103,13 @@ void FSEventWrap::New(const FunctionCallbackInfo<Value>& args) {
 
 
 void FSEventWrap::Start(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   FSEventWrap* wrap = Unwrap<FSEventWrap>(args.This());
 
   if (args.Length() < 1 || !args[0]->IsString()) {
-    return ThrowTypeError("Bad arguments");
+    return env->ThrowTypeError("Bad arguments");
   }
 
   String::Utf8Value path(args[0]);
@@ -158,7 +161,7 @@ void FSEventWrap::OnEvent(uv_fs_event_t* handle, const char* filename,
   // unreasonable, right? Still, we should revisit this before v1.0.
   Local<String> event_string;
   if (status) {
-    event_string = String::Empty(node_isolate);
+    event_string = String::Empty(env->isolate());
   } else if (events & UV_RENAME) {
     event_string = env->rename_string();
   } else if (events & UV_CHANGE) {
@@ -169,13 +172,13 @@ void FSEventWrap::OnEvent(uv_fs_event_t* handle, const char* filename,
   }
 
   Local<Value> argv[] = {
-    Integer::New(status, node_isolate),
+    Integer::New(status, env->isolate()),
     event_string,
-    Null(node_isolate)
+    Null(env->isolate())
   };
 
   if (filename != NULL) {
-    argv[2] = OneByteString(node_isolate, filename);
+    argv[2] = OneByteString(env->isolate(), filename);
   }
 
   wrap->MakeCallback(env->onchange_string(), ARRAY_SIZE(argv), argv);
@@ -183,7 +186,8 @@ void FSEventWrap::OnEvent(uv_fs_event_t* handle, const char* filename,
 
 
 void FSEventWrap::Close(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   FSEventWrap* wrap = Unwrap<FSEventWrap>(args.This());
 
index b7ee48d..3df1e49 100644 (file)
@@ -44,7 +44,8 @@ extern QUEUE handle_wrap_queue;
 
 
 void HandleWrap::Ref(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   HandleWrap* wrap = Unwrap<HandleWrap>(args.This());
 
@@ -56,7 +57,8 @@ void HandleWrap::Ref(const FunctionCallbackInfo<Value>& args) {
 
 
 void HandleWrap::Unref(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   HandleWrap* wrap = Unwrap<HandleWrap>(args.This());
 
@@ -68,7 +70,8 @@ void HandleWrap::Unref(const FunctionCallbackInfo<Value>& args) {
 
 
 void HandleWrap::Close(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   HandleWrap* wrap = Unwrap<HandleWrap>(args.This());
 
@@ -76,7 +79,6 @@ void HandleWrap::Close(const FunctionCallbackInfo<Value>& args) {
   if (wrap == NULL || wrap->handle__ == NULL)
     return;
 
-  Environment* env = wrap->env();
   assert(!wrap->persistent().IsEmpty());
   uv_close(wrap->handle__, OnClose);
   wrap->handle__ = NULL;
@@ -96,7 +98,7 @@ HandleWrap::HandleWrap(Environment* env,
       flags_(0),
       handle__(handle) {
   handle__->data = this;
-  HandleScope scope(node_isolate);
+  HandleScope scope(env->isolate());
   Wrap<HandleWrap>(object, this);
   QUEUE_INSERT_TAIL(&handle_wrap_queue, &handle_wrap_queue_);
 }
@@ -109,10 +111,9 @@ HandleWrap::~HandleWrap() {
 
 
 void HandleWrap::OnClose(uv_handle_t* handle) {
-  HandleScope scope(node_isolate);
-
   HandleWrap* wrap = static_cast<HandleWrap*>(handle->data);
   Environment* env = wrap->env();
+  HandleScope scope(env->isolate());
 
   // The wrap object should still be there.
   assert(wrap->persistent().IsEmpty() == false);
index 434682f..7c0bb33 100644 (file)
@@ -142,8 +142,7 @@ static double prog_start_time;
 static bool debugger_running;
 static uv_async_t dispatch_debug_messages_async;
 
-// Declared in node_internals.h
-Isolate* node_isolate = NULL;
+static Isolate* node_isolate = NULL;
 
 
 class ArrayBufferAllocator : public ArrayBuffer::Allocator {
@@ -187,8 +186,8 @@ void ArrayBufferAllocator::Free(void* data, size_t length) {
 
 
 static void CheckImmediate(uv_check_t* handle, int status) {
-  HandleScope scope(node_isolate);
   Environment* env = Environment::from_immediate_check_handle(handle);
+  HandleScope scope(env->isolate());
   Context::Scope context_scope(env->context());
   MakeCallback(env, env->process_object(), env->immediate_callback_string());
 }
@@ -677,45 +676,46 @@ const char *signo_string(int signo) {
 }
 
 
-Local<Value> ErrnoException(int errorno,
+Local<Value> ErrnoException(Isolate* isolate,
+                            int errorno,
                             const char *syscall,
                             const char *msg,
                             const char *path) {
-  Environment* env = Environment::GetCurrent(node_isolate);
+  Environment* env = Environment::GetCurrent(isolate);
 
   Local<Value> e;
-  Local<String> estring = OneByteString(node_isolate, errno_string(errorno));
+  Local<String> estring = OneByteString(env->isolate(), errno_string(errorno));
   if (msg == NULL || msg[0] == '\0') {
     msg = strerror(errorno);
   }
-  Local<String> message = OneByteString(node_isolate, msg);
+  Local<String> message = OneByteString(env->isolate(), msg);
 
   Local<String> cons1 =
-      String::Concat(estring, FIXED_ONE_BYTE_STRING(node_isolate, ", "));
+      String::Concat(estring, FIXED_ONE_BYTE_STRING(env->isolate(), ", "));
   Local<String> cons2 = String::Concat(cons1, message);
 
   if (path) {
     Local<String> cons3 =
-        String::Concat(cons2, FIXED_ONE_BYTE_STRING(node_isolate, " '"));
+        String::Concat(cons2, FIXED_ONE_BYTE_STRING(env->isolate(), " '"));
     Local<String> cons4 =
-        String::Concat(cons3, String::NewFromUtf8(node_isolate, path));
+        String::Concat(cons3, String::NewFromUtf8(env->isolate(), path));
     Local<String> cons5 =
-        String::Concat(cons4, FIXED_ONE_BYTE_STRING(node_isolate, "'"));
+        String::Concat(cons4, FIXED_ONE_BYTE_STRING(env->isolate(), "'"));
     e = Exception::Error(cons5);
   } else {
     e = Exception::Error(cons2);
   }
 
   Local<Object> obj = e->ToObject();
-  obj->Set(env->errno_string(), Integer::New(errorno, node_isolate));
+  obj->Set(env->errno_string(), Integer::New(errorno, env->isolate()));
   obj->Set(env->code_string(), estring);
 
   if (path != NULL) {
-    obj->Set(env->path_string(), String::NewFromUtf8(node_isolate, path));
+    obj->Set(env->path_string(), String::NewFromUtf8(env->isolate(), path));
   }
 
   if (syscall != NULL) {
-    obj->Set(env->syscall_string(), OneByteString(node_isolate, syscall));
+    obj->Set(env->syscall_string(), OneByteString(env->isolate(), syscall));
   }
 
   return e;
@@ -723,19 +723,20 @@ Local<Value> ErrnoException(int errorno,
 
 
 // hack alert! copy of ErrnoException, tuned for uv errors
-Local<Value> UVException(int errorno,
+Local<Value> UVException(Isolate* isolate,
+                         int errorno,
                          const char *syscall,
                          const char *msg,
                          const char *path) {
-  Environment* env = Environment::GetCurrent(node_isolate);
+  Environment* env = Environment::GetCurrent(isolate);
 
   if (!msg || !msg[0])
     msg = uv_strerror(errorno);
 
-  Local<String> estring = OneByteString(node_isolate, uv_err_name(errorno));
-  Local<String> message = OneByteString(node_isolate, msg);
+  Local<String> estring = OneByteString(env->isolate(), uv_err_name(errorno));
+  Local<String> message = OneByteString(env->isolate(), msg);
   Local<String> cons1 =
-      String::Concat(estring, FIXED_ONE_BYTE_STRING(node_isolate, ", "));
+      String::Concat(estring, FIXED_ONE_BYTE_STRING(env->isolate(), ", "));
   Local<String> cons2 = String::Concat(cons1, message);
 
   Local<Value> e;
@@ -745,23 +746,23 @@ Local<Value> UVException(int errorno,
   if (path) {
 #ifdef _WIN32
     if (strncmp(path, "\\\\?\\UNC\\", 8) == 0) {
-      path_str = String::Concat(FIXED_ONE_BYTE_STRING(node_isolate, "\\\\"),
-                                String::NewFromUtf8(node_isolate, path + 8));
+      path_str = String::Concat(FIXED_ONE_BYTE_STRING(env->isolate(), "\\\\"),
+                                String::NewFromUtf8(env->isolate(), path + 8));
     } else if (strncmp(path, "\\\\?\\", 4) == 0) {
-      path_str = String::NewFromUtf8(node_isolate, path + 4);
+      path_str = String::NewFromUtf8(env->isolate(), path + 4);
     } else {
-      path_str = String::NewFromUtf8(node_isolate, path);
+      path_str = String::NewFromUtf8(env->isolate(), path);
     }
 #else
-    path_str = String::NewFromUtf8(node_isolate, path);
+    path_str = String::NewFromUtf8(env->isolate(), path);
 #endif
 
     Local<String> cons3 =
-        String::Concat(cons2, FIXED_ONE_BYTE_STRING(node_isolate, " '"));
+        String::Concat(cons2, FIXED_ONE_BYTE_STRING(env->isolate(), " '"));
     Local<String> cons4 =
         String::Concat(cons3, path_str);
     Local<String> cons5 =
-        String::Concat(cons4, FIXED_ONE_BYTE_STRING(node_isolate, "'"));
+        String::Concat(cons4, FIXED_ONE_BYTE_STRING(env->isolate(), "'"));
     e = Exception::Error(cons5);
   } else {
     e = Exception::Error(cons2);
@@ -769,7 +770,7 @@ Local<Value> UVException(int errorno,
 
   Local<Object> obj = e->ToObject();
   // TODO(piscisaureus) errno should probably go
-  obj->Set(env->errno_string(), Integer::New(errorno, node_isolate));
+  obj->Set(env->errno_string(), Integer::New(errorno, env->isolate()));
   obj->Set(env->code_string(), estring);
 
   if (path != NULL) {
@@ -777,7 +778,7 @@ Local<Value> UVException(int errorno,
   }
 
   if (syscall != NULL) {
-    obj->Set(env->syscall_string(), OneByteString(node_isolate, syscall));
+    obj->Set(env->syscall_string(), OneByteString(env->isolate(), syscall));
   }
 
   return e;
@@ -809,43 +810,51 @@ static const char *winapi_strerror(const int errorno) {
 }
 
 
-Local<Value> WinapiErrnoException(int errorno,
+Local<Value> WinapiErrnoException(Environment* env,
+                                  int errorno,
                                   const char* syscall,
                                   const char* msg,
                                   const char* path) {
-  Environment* env = Environment::GetCurrent(node_isolate);
-
   Local<Value> e;
   if (!msg || !msg[0]) {
     msg = winapi_strerror(errorno);
   }
-  Local<String> message = OneByteString(node_isolate, msg);
+  Local<String> message = OneByteString(env->isolate(), msg);
 
   if (path) {
     Local<String> cons1 =
-        String::Concat(message, FIXED_ONE_BYTE_STRING(node_isolate, " '"));
+        String::Concat(message, FIXED_ONE_BYTE_STRING(env->isolate(), " '"));
     Local<String> cons2 =
-        String::Concat(cons1, String::NewFromUtf8(node_isolate, path));
+        String::Concat(cons1, String::NewFromUtf8(env->isolate(), path));
     Local<String> cons3 =
-        String::Concat(cons2, FIXED_ONE_BYTE_STRING(node_isolate, "'"));
+        String::Concat(cons2, FIXED_ONE_BYTE_STRING(env->isolate(), "'"));
     e = Exception::Error(cons3);
   } else {
     e = Exception::Error(message);
   }
 
   Local<Object> obj = e->ToObject();
-  obj->Set(env->errno_string(), Integer::New(errorno, node_isolate));
+  obj->Set(env->errno_string(), Integer::New(errorno, env->isolate()));
 
   if (path != NULL) {
-    obj->Set(env->path_string(), String::NewFromUtf8(node_isolate, path));
+    obj->Set(env->path_string(), String::NewFromUtf8(env->isolate(), path));
   }
 
   if (syscall != NULL) {
-    obj->Set(env->syscall_string(), OneByteString(node_isolate, syscall));
+    obj->Set(env->syscall_string(), OneByteString(env->isolate(), syscall));
   }
 
   return e;
 }
+
+
+Local<Value> WinapiErrnoException(int errorno,
+                                  const char* syscall,
+                                  const char* msg,
+                                  const char* path) {
+  Environment* env = Environment::GetCurrent(Isolate::GetCurrent());
+  return WinapiErrnoException(env, errorno, syscall, msg, path);
+}
 #endif
 
 
@@ -882,11 +891,10 @@ void SetupDomainUse(const FunctionCallbackInfo<Value>& args) {
     return;
   env->set_using_domains(true);
 
-  HandleScope scope(node_isolate);
+  HandleScope scope(env->isolate());
   Local<Object> process_object = env->process_object();
 
-  Local<String> tick_callback_function_key =
-      FIXED_ONE_BYTE_STRING(node_isolate, "_tickDomainCallback");
+  Local<String> tick_callback_function_key = env->tick_domain_cb_string();
   Local<Function> tick_callback_function =
       process_object->Get(tick_callback_function_key).As<Function>();
 
@@ -895,8 +903,7 @@ void SetupDomainUse(const FunctionCallbackInfo<Value>& args) {
     abort();
   }
 
-  process_object->Set(FIXED_ONE_BYTE_STRING(node_isolate, "_tickCallback"),
-                      tick_callback_function);
+  process_object->Set(env->tick_callback_string(), tick_callback_function);
   env->set_tick_callback_function(tick_callback_function);
 
   assert(args[0]->IsArray());
@@ -964,7 +971,7 @@ Handle<Value> MakeDomainCallback(Environment* env,
       env->async_listener_load_function()->Call(process, 1, &recv);
 
       if (try_catch.HasCaught())
-        return Undefined(node_isolate);
+        return Undefined(env->isolate());
     }
   }
 
@@ -978,7 +985,7 @@ Handle<Value> MakeDomainCallback(Environment* env,
 
       if (domain->Get(env->disposed_string())->IsTrue()) {
         // domain has been disposed of.
-        return Undefined(node_isolate);
+        return Undefined(env->isolate());
       }
 
       Local<Function> enter =
@@ -987,7 +994,7 @@ Handle<Value> MakeDomainCallback(Environment* env,
       enter->Call(domain, 0, NULL);
 
       if (try_catch.HasCaught()) {
-        return Undefined(node_isolate);
+        return Undefined(env->isolate());
       }
     }
   }
@@ -995,7 +1002,7 @@ Handle<Value> MakeDomainCallback(Environment* env,
   Local<Value> ret = callback->Call(recv, argc, argv);
 
   if (try_catch.HasCaught()) {
-    return Undefined(node_isolate);
+    return Undefined(env->isolate());
   }
 
   if (has_domain) {
@@ -1005,7 +1012,7 @@ Handle<Value> MakeDomainCallback(Environment* env,
     exit->Call(domain, 0, NULL);
 
     if (try_catch.HasCaught()) {
-      return Undefined(node_isolate);
+      return Undefined(env->isolate());
     }
   }
 
@@ -1013,7 +1020,7 @@ Handle<Value> MakeDomainCallback(Environment* env,
     env->async_listener_unload_function()->Call(process, 1, &recv);
 
     if (try_catch.HasCaught())
-      return Undefined(node_isolate);
+      return Undefined(env->isolate());
   }
 
   Environment::TickInfo* tick_info = env->tick_info();
@@ -1040,7 +1047,7 @@ Handle<Value> MakeDomainCallback(Environment* env,
 
   if (try_catch.HasCaught()) {
     tick_info->set_last_threw(true);
-    return Undefined(node_isolate);
+    return Undefined(env->isolate());
   }
 
   return ret;
@@ -1069,20 +1076,20 @@ Handle<Value> MakeCallback(Environment* env,
   if (has_async_queue) {
     env->async_listener_load_function()->Call(process, 1, &recv);
     if (try_catch.HasCaught())
-      return Undefined(node_isolate);
+      return Undefined(env->isolate());
   }
 
   Local<Value> ret = callback->Call(recv, argc, argv);
 
   if (try_catch.HasCaught()) {
-    return Undefined(node_isolate);
+    return Undefined(env->isolate());
   }
 
   if (has_async_queue) {
     env->async_listener_unload_function()->Call(process, 1, &recv);
 
     if (try_catch.HasCaught())
-      return Undefined(node_isolate);
+      return Undefined(env->isolate());
   }
 
   Environment::TickInfo* tick_info = env->tick_info();
@@ -1105,7 +1112,7 @@ Handle<Value> MakeCallback(Environment* env,
 
   if (try_catch.HasCaught()) {
     tick_info->set_last_threw(true);
-    return Undefined(node_isolate);
+    return Undefined(env->isolate());
   }
 
   return ret;
@@ -1141,16 +1148,17 @@ Handle<Value> MakeCallback(Environment* env,
                            const char* method,
                            int argc,
                            Handle<Value> argv[]) {
-  Local<String> method_string = OneByteString(node_isolate, method);
+  Local<String> method_string = OneByteString(env->isolate(), method);
   return MakeCallback(env, recv, method_string, argc, argv);
 }
 
 
-Handle<Value> MakeCallback(Handle<Object> recv,
+Handle<Value> MakeCallback(Isolate* isolate,
+                           Handle<Object> recv,
                            const char* method,
                            int argc,
                            Handle<Value> argv[]) {
-  HandleScope handle_scope(node_isolate);  // FIXME(bnoordhuis) Isolate-ify.
+  HandleScope handle_scope(isolate);
   Local<Context> context = recv->CreationContext();
   Environment* env = Environment::GetCurrent(context);
   Context::Scope context_scope(context);
@@ -1158,11 +1166,12 @@ Handle<Value> MakeCallback(Handle<Object> recv,
 }
 
 
-Handle<Value> MakeCallback(Handle<Object> recv,
+Handle<Value> MakeCallback(Isolate* isolate,
+                           Handle<Object> recv,
                            Handle<String> symbol,
                            int argc,
                            Handle<Value> argv[]) {
-  HandleScope handle_scope(node_isolate);  // FIXME(bnoordhuis) Isolate-ify.
+  HandleScope handle_scope(isolate);
   Local<Context> context = recv->CreationContext();
   Environment* env = Environment::GetCurrent(context);
   Context::Scope context_scope(context);
@@ -1170,11 +1179,12 @@ Handle<Value> MakeCallback(Handle<Object> recv,
 }
 
 
-Handle<Value> MakeCallback(Handle<Object> recv,
+Handle<Value> MakeCallback(Isolate* isolate,
+                           Handle<Object> recv,
                            Handle<Function> callback,
                            int argc,
                            Handle<Value> argv[]) {
-  HandleScope handle_scope(node_isolate);  // FIXME(bnoordhuis) Isolate-ify.
+  HandleScope handle_scope(isolate);
   Local<Context> context = recv->CreationContext();
   Environment* env = Environment::GetCurrent(context);
   Context::Scope context_scope(context);
@@ -1196,8 +1206,10 @@ Handle<Value> MakeDomainCallback(Handle<Object> recv,
 }
 
 
-enum encoding ParseEncoding(Handle<Value> encoding_v, enum encoding _default) {
-  HandleScope scope(node_isolate);
+enum encoding ParseEncoding(Isolate* isolate,
+                            Handle<Value> encoding_v,
+                            enum encoding _default) {
+  HandleScope scope(isolate);
 
   if (!encoding_v->IsString())
     return _default;
@@ -1243,15 +1255,21 @@ enum encoding ParseEncoding(Handle<Value> encoding_v, enum encoding _default) {
   }
 }
 
-Local<Value> Encode(const void *buf, size_t len, enum encoding encoding) {
-  return StringBytes::Encode(static_cast<const char*>(buf),
+Local<Value> Encode(Isolate* isolate,
+                    const void* buf,
+                    size_t len,
+                    enum encoding encoding) {
+  return StringBytes::Encode(isolate,
+                             static_cast<const char*>(buf),
                              len,
                              encoding);
 }
 
 // Returns -1 if the handle was not valid for decoding
-ssize_t DecodeBytes(v8::Handle<v8::Value> val, enum encoding encoding) {
-  HandleScope scope(node_isolate);
+ssize_t DecodeBytes(Isolate* isolate,
+                    Handle<Value> val,
+                    enum encoding encoding) {
+  HandleScope scope(isolate);
 
   if (val->IsArray()) {
     fprintf(stderr, "'raw' encoding (array of integers) has been removed. "
@@ -1260,7 +1278,7 @@ ssize_t DecodeBytes(v8::Handle<v8::Value> val, enum encoding encoding) {
     return -1;
   }
 
-  return StringBytes::Size(val, encoding);
+  return StringBytes::Size(isolate, val, encoding);
 }
 
 #ifndef MIN
@@ -1268,11 +1286,12 @@ ssize_t DecodeBytes(v8::Handle<v8::Value> val, enum encoding encoding) {
 #endif
 
 // Returns number of bytes written.
-ssize_t DecodeWrite(char *buf,
+ssize_t DecodeWrite(Isolate* isolate,
+                    char* buf,
                     size_t buflen,
-                    v8::Handle<v8::Value> val,
+                    Handle<Value> val,
                     enum encoding encoding) {
-  return StringBytes::Write(buf, buflen, val, encoding, NULL);
+  return StringBytes::Write(isolate, buf, buflen, val, encoding, NULL);
 }
 
 void AppendExceptionLine(Environment* env,
@@ -1459,7 +1478,7 @@ static Local<Value> ExecuteString(Environment* env,
 
 
 static void GetActiveRequests(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  HandleScope scope(args.GetIsolate());
 
   Local<Array> ary = Array::New();
   QUEUE* q = NULL;
@@ -1479,13 +1498,14 @@ static void GetActiveRequests(const FunctionCallbackInfo<Value>& args) {
 // Non-static, friend of HandleWrap. Could have been a HandleWrap method but
 // implemented here for consistency with GetActiveRequests().
 void GetActiveHandles(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   Local<Array> ary = Array::New();
   QUEUE* q = NULL;
   int i = 0;
 
-  Local<String> owner_sym = FIXED_ONE_BYTE_STRING(node_isolate, "owner");
+  Local<String> owner_sym = env->owner_string();
 
   QUEUE_FOREACH(q, &handle_wrap_queue) {
     HandleWrap* w = CONTAINER_OF(q, HandleWrap, handle_wrap_queue_);
@@ -1508,22 +1528,25 @@ static void Abort(const FunctionCallbackInfo<Value>& args) {
 
 
 static void Chdir(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   if (args.Length() != 1 || !args[0]->IsString()) {
-    return ThrowError("Bad argument.");  // FIXME(bnoordhuis) ThrowTypeError?
+    // FIXME(bnoordhuis) ThrowTypeError?
+    return env->ThrowError("Bad argument.");
   }
 
   String::Utf8Value path(args[0]);
   int err = uv_chdir(*path);
   if (err) {
-    return ThrowUVException(err, "uv_chdir");
+    return env->ThrowUVException(err, "uv_chdir");
   }
 }
 
 
 static void Cwd(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 #ifdef _WIN32
   /* MAX_PATH is in characters, not bytes. Make sure we have enough headroom. */
   char buf[MAX_PATH * 4 + 1];
@@ -1533,25 +1556,26 @@ static void Cwd(const FunctionCallbackInfo<Value>& args) {
 
   int err = uv_cwd(buf, ARRAY_SIZE(buf) - 1);
   if (err) {
-    return ThrowUVException(err, "uv_cwd");
+    return env->ThrowUVException(err, "uv_cwd");
   }
 
   buf[ARRAY_SIZE(buf) - 1] = '\0';
-  Local<String> cwd = String::NewFromUtf8(node_isolate, buf);
+  Local<String> cwd = String::NewFromUtf8(env->isolate(), buf);
 
   args.GetReturnValue().Set(cwd);
 }
 
 
 static void Umask(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
   uint32_t old;
 
   if (args.Length() < 1 || args[0]->IsUndefined()) {
     old = umask(0);
     umask(static_cast<mode_t>(old));
   } else if (!args[0]->IsInt32() && !args[0]->IsString()) {
-    return ThrowTypeError("argument must be an integer or octal string.");
+    return env->ThrowTypeError("argument must be an integer or octal string.");
   } else {
     int oct;
     if (args[0]->IsInt32()) {
@@ -1564,7 +1588,7 @@ static void Umask(const FunctionCallbackInfo<Value>& args) {
       for (int i = 0; i < str.length(); i++) {
         char c = (*str)[i];
         if (c > '7' || c < '0') {
-          return ThrowTypeError("invalid octal string");
+          return env->ThrowTypeError("invalid octal string");
         }
         oct *= 8;
         oct += c - '0';
@@ -1692,50 +1716,53 @@ static void GetGid(const FunctionCallbackInfo<Value>& args) {
 
 
 static void SetGid(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   if (!args[0]->IsUint32() && !args[0]->IsString()) {
-    return ThrowTypeError("setgid argument must be a number or a string");
+    return env->ThrowTypeError("setgid argument must be a number or a string");
   }
 
   gid_t gid = gid_by_name(args[0]);
 
   if (gid == gid_not_found) {
-    return ThrowError("setgid group id does not exist");
+    return env->ThrowError("setgid group id does not exist");
   }
 
   if (setgid(gid)) {
-    return ThrowErrnoException(errno, "setgid");
+    return env->ThrowErrnoException(errno, "setgid");
   }
 }
 
 
 static void SetUid(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   if (!args[0]->IsUint32() && !args[0]->IsString()) {
-    return ThrowTypeError("setuid argument must be a number or a string");
+    return env->ThrowTypeError("setuid argument must be a number or a string");
   }
 
   uid_t uid = uid_by_name(args[0]);
 
   if (uid == uid_not_found) {
-    return ThrowError("setuid user id does not exist");
+    return env->ThrowError("setuid user id does not exist");
   }
 
   if (setuid(uid)) {
-    return ThrowErrnoException(errno, "setuid");
+    return env->ThrowErrnoException(errno, "setuid");
   }
 }
 
 
 static void GetGroups(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   int ngroups = getgroups(0, NULL);
 
   if (ngroups == -1) {
-    return ThrowErrnoException(errno, "getgroups");
+    return env->ThrowErrnoException(errno, "getgroups");
   }
 
   gid_t* groups = new gid_t[ngroups];
@@ -1744,7 +1771,7 @@ static void GetGroups(const FunctionCallbackInfo<Value>& args) {
 
   if (ngroups == -1) {
     delete[] groups;
-    return ThrowErrnoException(errno, "getgroups");
+    return env->ThrowErrnoException(errno, "getgroups");
   }
 
   Local<Array> groups_list = Array::New(ngroups);
@@ -1752,7 +1779,7 @@ static void GetGroups(const FunctionCallbackInfo<Value>& args) {
   gid_t egid = getegid();
 
   for (int i = 0; i < ngroups; i++) {
-    groups_list->Set(i, Integer::New(groups[i], node_isolate));
+    groups_list->Set(i, Integer::New(groups[i], env->isolate()));
     if (groups[i] == egid)
       seen_egid = true;
   }
@@ -1760,7 +1787,7 @@ static void GetGroups(const FunctionCallbackInfo<Value>& args) {
   delete[] groups;
 
   if (seen_egid == false) {
-    groups_list->Set(ngroups, Integer::New(egid, node_isolate));
+    groups_list->Set(ngroups, Integer::New(egid, env->isolate()));
   }
 
   args.GetReturnValue().Set(groups_list);
@@ -1768,10 +1795,11 @@ static void GetGroups(const FunctionCallbackInfo<Value>& args) {
 
 
 static void SetGroups(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   if (!args[0]->IsArray()) {
-    return ThrowTypeError("argument 1 must be an array");
+    return env->ThrowTypeError("argument 1 must be an array");
   }
 
   Local<Array> groups_list = args[0].As<Array>();
@@ -1783,7 +1811,7 @@ static void SetGroups(const FunctionCallbackInfo<Value>& args) {
 
     if (gid == gid_not_found) {
       delete[] groups;
-      return ThrowError("group name not found");
+      return env->ThrowError("group name not found");
     }
 
     groups[i] = gid;
@@ -1793,20 +1821,21 @@ static void SetGroups(const FunctionCallbackInfo<Value>& args) {
   delete[] groups;
 
   if (rc == -1) {
-    return ThrowErrnoException(errno, "setgroups");
+    return env->ThrowErrnoException(errno, "setgroups");
   }
 }
 
 
 static void InitGroups(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   if (!args[0]->IsUint32() && !args[0]->IsString()) {
-    return ThrowTypeError("argument 1 must be a number or a string");
+    return env->ThrowTypeError("argument 1 must be a number or a string");
   }
 
   if (!args[1]->IsUint32() && !args[1]->IsString()) {
-    return ThrowTypeError("argument 2 must be a number or a string");
+    return env->ThrowTypeError("argument 2 must be a number or a string");
   }
 
   String::Utf8Value arg0(args[0]);
@@ -1823,7 +1852,7 @@ static void InitGroups(const FunctionCallbackInfo<Value>& args) {
   }
 
   if (user == NULL) {
-    return ThrowError("initgroups user not found");
+    return env->ThrowError("initgroups user not found");
   }
 
   extra_group = gid_by_name(args[1]);
@@ -1831,7 +1860,7 @@ static void InitGroups(const FunctionCallbackInfo<Value>& args) {
   if (extra_group == gid_not_found) {
     if (must_free)
       free(user);
-    return ThrowError("initgroups extra group not found");
+    return env->ThrowError("initgroups extra group not found");
   }
 
   int rc = initgroups(user, extra_group);
@@ -1841,7 +1870,7 @@ static void InitGroups(const FunctionCallbackInfo<Value>& args) {
   }
 
   if (rc) {
-    return ThrowErrnoException(errno, "initgroups");
+    return env->ThrowErrnoException(errno, "initgroups");
   }
 }
 
@@ -1849,13 +1878,15 @@ static void InitGroups(const FunctionCallbackInfo<Value>& args) {
 
 
 void Exit(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
   exit(args[0]->IntegerValue());
 }
 
 
 static void Uptime(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
   double uptime;
   if (uv_uptime(&uptime))
     return;
@@ -1864,26 +1895,26 @@ static void Uptime(const FunctionCallbackInfo<Value>& args) {
 
 
 void MemoryUsage(const FunctionCallbackInfo<Value>& args) {
-  HandleScope handle_scope(args.GetIsolate());
   Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   size_t rss;
   int err = uv_resident_set_memory(&rss);
   if (err) {
-    return ThrowUVException(err, "uv_resident_set_memory");
+    return env->ThrowUVException(err, "uv_resident_set_memory");
   }
 
   // V8 memory usage
   HeapStatistics v8_heap_stats;
-  node_isolate->GetHeapStatistics(&v8_heap_stats);
+  env->isolate()->GetHeapStatistics(&v8_heap_stats);
 
   Local<Integer> heap_total =
-      Integer::NewFromUnsigned(v8_heap_stats.total_heap_size(), node_isolate);
+      Integer::NewFromUnsigned(v8_heap_stats.total_heap_size(), env->isolate());
   Local<Integer> heap_used =
-      Integer::NewFromUnsigned(v8_heap_stats.used_heap_size(), node_isolate);
+      Integer::NewFromUnsigned(v8_heap_stats.used_heap_size(), env->isolate());
 
   Local<Object> info = Object::New();
-  info->Set(env->rss_string(), Number::New(node_isolate, rss));
+  info->Set(env->rss_string(), Number::New(env->isolate(), rss));
   info->Set(env->heap_total_string(), heap_total);
   info->Set(env->heap_used_string(), heap_used);
 
@@ -1892,10 +1923,11 @@ void MemoryUsage(const FunctionCallbackInfo<Value>& args) {
 
 
 void Kill(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   if (args.Length() != 2) {
-    return ThrowError("Bad argument.");
+    return env->ThrowError("Bad argument.");
   }
 
   int pid = args[0]->IntegerValue();
@@ -1913,14 +1945,16 @@ void Kill(const FunctionCallbackInfo<Value>& args) {
 // and nanoseconds, to avoid any integer overflow possibility.
 // Pass in an Array from a previous hrtime() call to instead get a time diff.
 void Hrtime(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   uint64_t t = uv_hrtime();
 
   if (args.Length() > 0) {
     // return a time diff tuple
     if (!args[0]->IsArray()) {
-      return ThrowTypeError("process.hrtime() only accepts an Array tuple.");
+      return env->ThrowTypeError(
+          "process.hrtime() only accepts an Array tuple.");
     }
     Local<Array> inArray = Local<Array>::Cast(args[0]);
     uint64_t seconds = inArray->Get(0)->Uint32Value();
@@ -1929,8 +1963,8 @@ void Hrtime(const FunctionCallbackInfo<Value>& 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));
+  tuple->Set(0, Integer::NewFromUnsigned(t / NANOS_PER_SEC, env->isolate()));
+  tuple->Set(1, Integer::NewFromUnsigned(t % NANOS_PER_SEC, env->isolate()));
   args.GetReturnValue().Set(tuple);
 }
 
@@ -1973,7 +2007,7 @@ void DLOpen(const FunctionCallbackInfo<Value>& args) {
   uv_lib_t lib;
 
   if (args.Length() < 2) {
-    ThrowError("process.dlopen takes exactly 2 arguments.");
+    env->ThrowError("process.dlopen takes exactly 2 arguments.");
     return;
   }
 
@@ -1989,7 +2023,7 @@ void DLOpen(const FunctionCallbackInfo<Value>& args) {
     // Windows needs to add the filename into the error message
     errmsg = String::Concat(errmsg, args[1]->ToString());
 #endif  // _WIN32
-    ThrowException(Exception::Error(errmsg));
+    env->isolate()->ThrowException(Exception::Error(errmsg));
     return;
   }
 
@@ -2002,7 +2036,7 @@ void DLOpen(const FunctionCallbackInfo<Value>& args) {
   modpending = NULL;
 
   if (mp == NULL) {
-    ThrowError("Module did not self-register.");
+    env->ThrowError("Module did not self-register.");
     return;
   }
   if (mp->nm_version != NODE_MODULE_VERSION) {
@@ -2011,11 +2045,11 @@ void DLOpen(const FunctionCallbackInfo<Value>& args) {
              sizeof(errmsg),
              "Module version mismatch. Expected %d, got %d.",
              NODE_MODULE_VERSION, mp->nm_version);
-    ThrowError(errmsg);
+    env->ThrowError(errmsg);
     return;
   }
   if (mp->nm_flags & NM_F_BUILTIN) {
-    ThrowError("Built-in module self-registered.");
+    env->ThrowError("Built-in module self-registered.");
     return;
   }
 
@@ -2028,7 +2062,7 @@ void DLOpen(const FunctionCallbackInfo<Value>& args) {
   } else if (mp->nm_register_func != NULL) {
     mp->nm_register_func(exports, module, mp->nm_priv);
   } else {
-    ThrowError("Module has no declared entry point.");
+    env->ThrowError("Module has no declared entry point.");
     return;
   }
 
@@ -2055,10 +2089,12 @@ NO_RETURN void FatalError(const char* location, const char* message) {
 }
 
 
-void FatalException(Handle<Value> error, Handle<Message> message) {
-  HandleScope scope(node_isolate);
+void FatalException(Isolate* isolate,
+                    Handle<Value> error,
+                    Handle<Message> message) {
+  HandleScope scope(isolate);
 
-  Environment* env = Environment::GetCurrent(node_isolate);
+  Environment* env = Environment::GetCurrent(isolate);
   Local<Object> process_object = env->process_object();
   Local<String> fatal_exception_string = env->fatal_exception_string();
   Local<Function> fatal_exception_function =
@@ -2093,18 +2129,18 @@ void FatalException(Handle<Value> error, Handle<Message> message) {
 }
 
 
-void FatalException(const TryCatch& try_catch) {
-  HandleScope scope(node_isolate);
+void FatalException(Isolate* isolate, const TryCatch& try_catch) {
+  HandleScope scope(isolate);
   // TODO(bajtos) do not call FatalException if try_catch is verbose
   // (requires V8 API to expose getter for try_catch.is_verbose_)
-  FatalException(try_catch.Exception(), try_catch.Message());
+  FatalException(isolate, try_catch.Exception(), try_catch.Message());
 }
 
 
 void OnMessage(Handle<Message> message, Handle<Value> error) {
   // The current version of V8 sends messages for errors only
   // (thus `error` is always set).
-  FatalException(error, message);
+  FatalException(Isolate::GetCurrent(), error, message);
 }
 
 
@@ -2130,7 +2166,7 @@ static void Binding(const FunctionCallbackInfo<Value>& args) {
 
   Local<Array> modules = env->module_load_list_array();
   uint32_t l = modules->Length();
-  modules->Set(l, OneByteString(node_isolate, buf));
+  modules->Set(l, OneByteString(env->isolate(), buf));
 
   node_module* mod = get_builtin_module(*module_v);
   if (mod != NULL) {
@@ -2148,10 +2184,10 @@ static void Binding(const FunctionCallbackInfo<Value>& args) {
     cache->Set(module, exports);
   } else if (!strcmp(*module_v, "natives")) {
     exports = Object::New();
-    DefineJavaScript(exports);
+    DefineJavaScript(env, exports);
     cache->Set(module, exports);
   } else {
-    return ThrowError("No such module");
+    return env->ThrowError("No such module");
   }
 
   args.GetReturnValue().Set(exports);
@@ -2160,17 +2196,19 @@ static void Binding(const FunctionCallbackInfo<Value>& args) {
 
 static void ProcessTitleGetter(Local<String> property,
                                const PropertyCallbackInfo<Value>& info) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(info.GetIsolate());
+  HandleScope scope(env->isolate());
   char buffer[512];
   uv_get_process_title(buffer, sizeof(buffer));
-  info.GetReturnValue().Set(String::NewFromUtf8(node_isolate, buffer));
+  info.GetReturnValue().Set(String::NewFromUtf8(env->isolate(), buffer));
 }
 
 
 static void ProcessTitleSetter(Local<String> property,
                                Local<Value> value,
                                const PropertyCallbackInfo<void>& info) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(info.GetIsolate());
+  HandleScope scope(env->isolate());
   String::Utf8Value title(value);
   // TODO(piscisaureus): protect with a lock
   uv_set_process_title(*title);
@@ -2179,12 +2217,13 @@ static void ProcessTitleSetter(Local<String> property,
 
 static void EnvGetter(Local<String> property,
                       const PropertyCallbackInfo<Value>& info) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(info.GetIsolate());
+  HandleScope scope(env->isolate());
 #ifdef __POSIX__
   String::Utf8Value key(property);
   const char* val = getenv(*key);
   if (val) {
-    return info.GetReturnValue().Set(String::NewFromUtf8(node_isolate, val));
+    return info.GetReturnValue().Set(String::NewFromUtf8(env->isolate(), val));
   }
 #else  // _WIN32
   String::Value key(property);
@@ -2198,7 +2237,7 @@ static void EnvGetter(Local<String> property,
   if ((result > 0 || GetLastError() == ERROR_SUCCESS) &&
       result < ARRAY_SIZE(buffer)) {
     const uint16_t* two_byte_buffer = reinterpret_cast<const uint16_t*>(buffer);
-    Local<String> rc = String::NewFromTwoByte(node_isolate, two_byte_buffer);
+    Local<String> rc = String::NewFromTwoByte(env->isolate(), two_byte_buffer);
     return info.GetReturnValue().Set(rc);
   }
 #endif
@@ -2211,7 +2250,8 @@ static void EnvGetter(Local<String> property,
 static void EnvSetter(Local<String> property,
                       Local<Value> value,
                       const PropertyCallbackInfo<Value>& info) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(info.GetIsolate());
+  HandleScope scope(env->isolate());
 #ifdef __POSIX__
   String::Utf8Value key(property);
   String::Utf8Value val(value);
@@ -2232,7 +2272,8 @@ static void EnvSetter(Local<String> property,
 
 static void EnvQuery(Local<String> property,
                      const PropertyCallbackInfo<Integer>& info) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(info.GetIsolate());
+  HandleScope scope(env->isolate());
   int32_t rc = -1;  // Not found unless proven otherwise.
 #ifdef __POSIX__
   String::Utf8Value key(property);
@@ -2259,7 +2300,8 @@ static void EnvQuery(Local<String> property,
 
 static void EnvDeleter(Local<String> property,
                        const PropertyCallbackInfo<Boolean>& info) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(info.GetIsolate());
+  HandleScope scope(env->isolate());
   bool rc = true;
 #ifdef __POSIX__
   String::Utf8Value key(property);
@@ -2281,29 +2323,30 @@ static void EnvDeleter(Local<String> property,
 
 
 static void EnvEnumerator(const PropertyCallbackInfo<Array>& info) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(info.GetIsolate());
+  HandleScope scope(env->isolate());
 #ifdef __POSIX__
   int size = 0;
   while (environ[size])
     size++;
 
-  Local<Array> env = Array::New(size);
+  Local<Array> envarr = Array::New(size);
 
   for (int i = 0; i < size; ++i) {
     const char* var = environ[i];
     const char* s = strchr(var, '=');
     const int length = s ? s - var : strlen(var);
-    Local<String> name = String::NewFromUtf8(node_isolate,
+    Local<String> name = String::NewFromUtf8(env->isolate(),
                                              var,
                                              String::kNormalString,
                                              length);
-    env->Set(i, name);
+    envarr->Set(i, name);
   }
 #else  // _WIN32
   WCHAR* environment = GetEnvironmentStringsW();
   if (environment == NULL)
     return;  // This should not happen.
-  Local<Array> env = Array::New();
+  Local<Array> envarr = Array::New();
   WCHAR* p = environment;
   int i = 0;
   while (*p != NULL) {
@@ -2320,51 +2363,51 @@ static void EnvEnumerator(const PropertyCallbackInfo<Array>& info) {
     }
     const uint16_t* two_byte_buffer = reinterpret_cast<const uint16_t*>(p);
     const size_t two_byte_buffer_len = s - p;
-    Local<String> value = String::NewFromTwoByte(node_isolate,
+    Local<String> value = String::NewFromTwoByte(env->isolate(),
                                                  two_byte_buffer,
                                                  String::kNormalString,
                                                  two_byte_buffer_len);
-    env->Set(i++, value);
+    envarr->Set(i++, value);
     p = s + wcslen(s) + 1;
   }
   FreeEnvironmentStringsW(environment);
 #endif
 
-  info.GetReturnValue().Set(env);
+  info.GetReturnValue().Set(envarr);
 }
 
 
-static Handle<Object> GetFeatures() {
-  HandleScope scope(node_isolate);
+static Handle<Object> GetFeatures(Environment* env) {
+  HandleScope scope(env->isolate());
 
   Local<Object> obj = Object::New();
 #if defined(DEBUG) && DEBUG
-  Local<Value> debug = True(node_isolate);
+  Local<Value> debug = True(env->isolate());
 #else
-  Local<Value> debug = False(node_isolate);
+  Local<Value> debug = False(env->isolate());
 #endif  // defined(DEBUG) && DEBUG
 
-  obj->Set(FIXED_ONE_BYTE_STRING(node_isolate, "debug"), debug);
+  obj->Set(env->debug_string(), debug);
 
-  obj->Set(FIXED_ONE_BYTE_STRING(node_isolate, "uv"), True(node_isolate));
+  obj->Set(env->uv_string(), True(env->isolate()));
   // TODO(bnoordhuis) ping libuv
-  obj->Set(FIXED_ONE_BYTE_STRING(node_isolate, "ipv6"), True(node_isolate));
+  obj->Set(env->ipv6_lc_string(), True(env->isolate()));
 
 #ifdef OPENSSL_NPN_NEGOTIATED
-  Local<Boolean> tls_npn = True(node_isolate);
+  Local<Boolean> tls_npn = True(env->isolate());
 #else
-  Local<Boolean> tls_npn = False(node_isolate);
+  Local<Boolean> tls_npn = False(env->isolate());
 #endif
-  obj->Set(FIXED_ONE_BYTE_STRING(node_isolate, "tls_npn"), tls_npn);
+  obj->Set(env->tls_npn_string(), tls_npn);
 
 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
-  Local<Boolean> tls_sni = True(node_isolate);
+  Local<Boolean> tls_sni = True(env->isolate());
 #else
-  Local<Boolean> tls_sni = False(node_isolate);
+  Local<Boolean> tls_sni = False(env->isolate());
 #endif
-  obj->Set(FIXED_ONE_BYTE_STRING(node_isolate, "tls_sni"), tls_sni);
+  obj->Set(env->tls_sni_string(), tls_sni);
 
-  obj->Set(FIXED_ONE_BYTE_STRING(node_isolate, "tls"),
+  obj->Set(env->tls_string(),
            Boolean::New(get_builtin_module("crypto") != NULL));
 
   return scope.Close(obj);
@@ -2373,7 +2416,8 @@ static Handle<Object> GetFeatures() {
 
 static void DebugPortGetter(Local<String> property,
                             const PropertyCallbackInfo<Value>& info) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(info.GetIsolate());
+  HandleScope scope(env->isolate());
   info.GetReturnValue().Set(debug_port);
 }
 
@@ -2381,7 +2425,8 @@ static void DebugPortGetter(Local<String> property,
 static void DebugPortSetter(Local<String> property,
                             Local<Value> value,
                             const PropertyCallbackInfo<void>& info) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(info.GetIsolate());
+  HandleScope scope(env->isolate());
   debug_port = value->NumberValue();
 }
 
@@ -2469,7 +2514,7 @@ void StopProfilerIdleNotifier(const FunctionCallbackInfo<Value>& args) {
 
 #define READONLY_PROPERTY(obj, str, var)                                      \
   do {                                                                        \
-    obj->Set(OneByteString(node_isolate, str), var, v8::ReadOnly);            \
+    obj->Set(OneByteString(env->isolate(), str), var, v8::ReadOnly);          \
   } while (0)
 
 
@@ -2478,18 +2523,18 @@ void SetupProcessObject(Environment* env,
                         const char* const* argv,
                         int exec_argc,
                         const char* const* exec_argv) {
-  HandleScope scope(node_isolate);
+  HandleScope scope(env->isolate());
 
   Local<Object> process = env->process_object();
 
-  process->SetAccessor(FIXED_ONE_BYTE_STRING(node_isolate, "title"),
+  process->SetAccessor(env->title_string(),
                        ProcessTitleGetter,
                        ProcessTitleSetter);
 
   // process.version
   READONLY_PROPERTY(process,
                     "version",
-                    FIXED_ONE_BYTE_STRING(node_isolate, NODE_VERSION));
+                    FIXED_ONE_BYTE_STRING(env->isolate(), NODE_VERSION));
 
   // process.moduleLoadList
   READONLY_PROPERTY(process,
@@ -2505,26 +2550,27 @@ void SetupProcessObject(Environment* env,
                                      NODE_STRINGIFY(HTTP_PARSER_VERSION_MINOR);
   READONLY_PROPERTY(versions,
                     "http_parser",
-                    FIXED_ONE_BYTE_STRING(node_isolate, http_parser_version));
+                    FIXED_ONE_BYTE_STRING(env->isolate(), http_parser_version));
 
   // +1 to get rid of the leading 'v'
   READONLY_PROPERTY(versions,
                     "node",
-                    OneByteString(node_isolate, NODE_VERSION + 1));
+                    OneByteString(env->isolate(), NODE_VERSION + 1));
   READONLY_PROPERTY(versions,
                     "v8",
-                    OneByteString(node_isolate, V8::GetVersion()));
+                    OneByteString(env->isolate(), V8::GetVersion()));
   READONLY_PROPERTY(versions,
                     "uv",
-                    OneByteString(node_isolate, uv_version_string()));
+                    OneByteString(env->isolate(), uv_version_string()));
   READONLY_PROPERTY(versions,
                     "zlib",
-                    FIXED_ONE_BYTE_STRING(node_isolate, ZLIB_VERSION));
+                    FIXED_ONE_BYTE_STRING(env->isolate(), ZLIB_VERSION));
 
   const char node_modules_version[] = NODE_STRINGIFY(NODE_MODULE_VERSION);
-  READONLY_PROPERTY(versions,
-                    "modules",
-                    FIXED_ONE_BYTE_STRING(node_isolate, node_modules_version));
+  READONLY_PROPERTY(
+      versions,
+      "modules",
+      FIXED_ONE_BYTE_STRING(env->isolate(), node_modules_version));
 
 #if HAVE_OPENSSL
   // Stupid code to slice out the version string.
@@ -2545,31 +2591,31 @@ void SetupProcessObject(Environment* env,
     READONLY_PROPERTY(
         versions,
         "openssl",
-        OneByteString(node_isolate, &OPENSSL_VERSION_TEXT[i], j - i));
+        OneByteString(env->isolate(), &OPENSSL_VERSION_TEXT[i], j - i));
   }
 #endif
 
   // process.arch
-  READONLY_PROPERTY(process, "arch", OneByteString(node_isolate, ARCH));
+  READONLY_PROPERTY(process, "arch", OneByteString(env->isolate(), ARCH));
 
   // process.platform
   READONLY_PROPERTY(process,
                     "platform",
-                    OneByteString(node_isolate, PLATFORM));
+                    OneByteString(env->isolate(), PLATFORM));
 
   // process.argv
   Local<Array> arguments = Array::New(argc);
   for (int i = 0; i < argc; ++i) {
-    arguments->Set(i, String::NewFromUtf8(node_isolate, argv[i]));
+    arguments->Set(i, String::NewFromUtf8(env->isolate(), argv[i]));
   }
-  process->Set(FIXED_ONE_BYTE_STRING(node_isolate, "argv"), arguments);
+  process->Set(env->argv_string(), arguments);
 
   // process.execArgv
   Local<Array> exec_arguments = Array::New(exec_argc);
   for (int i = 0; i < exec_argc; ++i) {
-    exec_arguments->Set(i, String::NewFromUtf8(node_isolate, exec_argv[i]));
+    exec_arguments->Set(i, String::NewFromUtf8(env->isolate(), exec_argv[i]));
   }
-  process->Set(FIXED_ONE_BYTE_STRING(node_isolate, "execArgv"), exec_arguments);
+  process->Set(env->exec_argv_string(), exec_arguments);
 
   // create process.env
   Local<ObjectTemplate> process_env_template = ObjectTemplate::New();
@@ -2580,12 +2626,11 @@ void SetupProcessObject(Environment* env,
                                                 EnvEnumerator,
                                                 Object::New());
   Local<Object> process_env = process_env_template->NewInstance();
-  process->Set(FIXED_ONE_BYTE_STRING(node_isolate, "env"), process_env);
+  process->Set(env->env_string(), process_env);
 
-  READONLY_PROPERTY(process, "pid", Integer::New(getpid(), node_isolate));
-  READONLY_PROPERTY(process, "features", GetFeatures());
-  process->SetAccessor(
-      FIXED_ONE_BYTE_STRING(node_isolate, "_needImmediateCallback"),
+  READONLY_PROPERTY(process, "pid", Integer::New(getpid(), env->isolate()));
+  READONLY_PROPERTY(process, "features", GetFeatures(env));
+  process->SetAccessor(env->need_imm_cb_string(),
       NeedImmediateCallbackGetter,
       NeedImmediateCallbackSetter);
 
@@ -2593,50 +2638,49 @@ void SetupProcessObject(Environment* env,
   if (eval_string) {
     READONLY_PROPERTY(process,
                       "_eval",
-                      String::NewFromUtf8(node_isolate, eval_string));
+                      String::NewFromUtf8(env->isolate(), eval_string));
   }
 
   // -p, --print
   if (print_eval) {
-    READONLY_PROPERTY(process, "_print_eval", True(node_isolate));
+    READONLY_PROPERTY(process, "_print_eval", True(env->isolate()));
   }
 
   // -i, --interactive
   if (force_repl) {
-    READONLY_PROPERTY(process, "_forceRepl", True(node_isolate));
+    READONLY_PROPERTY(process, "_forceRepl", True(env->isolate()));
   }
 
   // --no-deprecation
   if (no_deprecation) {
-    READONLY_PROPERTY(process, "noDeprecation", True(node_isolate));
+    READONLY_PROPERTY(process, "noDeprecation", True(env->isolate()));
   }
 
   // --throw-deprecation
   if (throw_deprecation) {
-    READONLY_PROPERTY(process, "throwDeprecation", True(node_isolate));
+    READONLY_PROPERTY(process, "throwDeprecation", True(env->isolate()));
   }
 
   // --trace-deprecation
   if (trace_deprecation) {
-    READONLY_PROPERTY(process, "traceDeprecation", True(node_isolate));
+    READONLY_PROPERTY(process, "traceDeprecation", True(env->isolate()));
   }
 
   size_t exec_path_len = 2 * PATH_MAX;
   char* exec_path = new char[exec_path_len];
   Local<String> exec_path_value;
   if (uv_exepath(exec_path, &exec_path_len) == 0) {
-    exec_path_value = String::NewFromUtf8(node_isolate,
+    exec_path_value = String::NewFromUtf8(env->isolate(),
                                           exec_path,
                                           String::kNormalString,
                                           exec_path_len);
   } else {
-    exec_path_value = String::NewFromUtf8(node_isolate, argv[0]);
+    exec_path_value = String::NewFromUtf8(env->isolate(), argv[0]);
   }
-  process->Set(FIXED_ONE_BYTE_STRING(node_isolate, "execPath"),
-               exec_path_value);
+  process->Set(env->exec_path_string(), exec_path_value);
   delete[] exec_path;
 
-  process->SetAccessor(FIXED_ONE_BYTE_STRING(node_isolate, "debugPort"),
+  process->SetAccessor(env->debug_port_string(),
                        DebugPortGetter,
                        DebugPortSetter);
 
@@ -2693,10 +2737,10 @@ void SetupProcessObject(Environment* env,
       env->tick_info()->fields(),
       kExternalUnsignedIntArray,
       env->tick_info()->fields_count());
-  process->Set(FIXED_ONE_BYTE_STRING(node_isolate, "_tickInfo"), tick_info_obj);
+  process->Set(env->tick_info_string(), tick_info_obj);
 
   // pre-set _events object for faster emit checks
-  process->Set(FIXED_ONE_BYTE_STRING(node_isolate, "_events"), Object::New());
+  process->Set(env->events_string(), Object::New());
 }
 
 
@@ -2719,7 +2763,8 @@ static void SignalExit(int signal) {
 // when debugging the stream.Writable class or the process.nextTick
 // function, it is useful to bypass JavaScript entirely.
 static void RawDebug(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   assert(args.Length() == 1 && args[0]->IsString() &&
          "must be called with a single string");
@@ -2731,7 +2776,7 @@ static void RawDebug(const FunctionCallbackInfo<Value>& args) {
 
 
 void Load(Environment* env) {
-  HandleScope handle_scope(node_isolate);
+  HandleScope handle_scope(env->isolate());
 
   // 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
@@ -2748,7 +2793,7 @@ void Load(Environment* env) {
   try_catch.SetVerbose(false);
 
   Local<String> script_name = FIXED_ONE_BYTE_STRING(env->isolate(), "node.js");
-  Local<Value> f_value = ExecuteString(env, MainSource(), script_name);
+  Local<Value> f_value = ExecuteString(env, MainSource(env), script_name);
   if (try_catch.HasCaught())  {
     ReportException(env, try_catch);
     exit(10);
@@ -2768,11 +2813,11 @@ void Load(Environment* env) {
   Local<Object> global = env->context()->Global();
 
 #if defined HAVE_DTRACE || defined HAVE_ETW
-  InitDTrace(global);
+  InitDTrace(env, global);
 #endif
 
 #if defined HAVE_PERFCTR
-  InitPerfCounters(global);
+  InitPerfCounters(env, global);
 #endif
 
   // Enable handling of uncaught exceptions
@@ -2977,9 +3022,8 @@ static void DispatchMessagesDebugAgentCallback() {
 
 
 // Called from the main thread.
-static void EnableDebug(bool wait_connect) {
+static void EnableDebug(Isolate* isolate, bool wait_connect) {
   assert(debugger_running == false);
-  Isolate* isolate = node_isolate;  // TODO(bnoordhuis) Multi-isolate support.
   Isolate::Scope isolate_scope(isolate);
   HandleScope handle_scope(isolate);
   v8::Debug::SetDebugMessageDispatchHandler(DispatchMessagesDebugAgentCallback,
@@ -3015,7 +3059,7 @@ static void EnableDebug(bool wait_connect) {
 static void DispatchDebugMessagesAsyncCallback(uv_async_t* handle, int status) {
   if (debugger_running == false) {
     fprintf(stderr, "Starting debugger agent.\n");
-    EnableDebug(false);
+    EnableDebug(node_isolate, false);
   }
   Isolate::Scope isolate_scope(node_isolate);
   v8::Debug::ProcessDebugMessages();
@@ -3056,10 +3100,11 @@ static void RegisterSignalHandler(int signal, void (*handler)(int signal)) {
 
 
 void DebugProcess(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   if (args.Length() != 1) {
-    return ThrowError("Invalid number of arguments.");
+    return env->ThrowError("Invalid number of arguments.");
   }
 
   pid_t pid;
@@ -3068,7 +3113,7 @@ void DebugProcess(const FunctionCallbackInfo<Value>& args) {
   pid = args[0]->IntegerValue();
   r = kill(pid, SIGUSR1);
   if (r != 0) {
-    return ThrowErrnoException(errno, "kill");
+    return env->ThrowErrnoException(errno, "kill");
   }
 }
 
@@ -3143,7 +3188,8 @@ static int RegisterDebugSignalHandler() {
 
 
 static void DebugProcess(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
   DWORD pid;
   HANDLE process = NULL;
   HANDLE thread = NULL;
@@ -3152,7 +3198,7 @@ static void DebugProcess(const FunctionCallbackInfo<Value>& args) {
   LPTHREAD_START_ROUTINE* handler = NULL;
 
   if (args.Length() != 1) {
-    ThrowError("Invalid number of arguments.");
+    env->ThrowError("Invalid number of arguments.");
     goto out;
   }
 
@@ -3164,20 +3210,23 @@ static void DebugProcess(const FunctionCallbackInfo<Value>& args) {
                         FALSE,
                         pid);
   if (process == NULL) {
-    ThrowException(WinapiErrnoException(GetLastError(), "OpenProcess"));
+    env->ThrowException(
+        WinapiErrnoException(env, GetLastError(), "OpenProcess"));
     goto out;
   }
 
   if (GetDebugSignalHandlerMappingName(pid,
                                        mapping_name,
                                        ARRAY_SIZE(mapping_name)) < 0) {
-    ThrowErrnoException(errno, "sprintf");
+    env->ThrowErrnoException(errno, "sprintf");
     goto out;
   }
 
   mapping = OpenFileMappingW(FILE_MAP_READ, FALSE, mapping_name);
   if (mapping == NULL) {
-    ThrowException(WinapiErrnoException(GetLastError(), "OpenFileMappingW"));
+    env->ThrowException(WinapiErrnoException(env,
+                                             GetLastError(),
+                                             "OpenFileMappingW"));
     goto out;
   }
 
@@ -3188,7 +3237,8 @@ static void DebugProcess(const FunctionCallbackInfo<Value>& args) {
                     0,
                     sizeof *handler));
   if (handler == NULL || *handler == NULL) {
-    ThrowException(WinapiErrnoException(GetLastError(), "MapViewOfFile"));
+    env->ThrowException(
+        WinapiErrnoException(env, GetLastError(), "MapViewOfFile"));
     goto out;
   }
 
@@ -3200,13 +3250,17 @@ static void DebugProcess(const FunctionCallbackInfo<Value>& args) {
                               0,
                               NULL);
   if (thread == NULL) {
-    ThrowException(WinapiErrnoException(GetLastError(), "CreateRemoteThread"));
+    env->ThrowException(WinapiErrnoException(env,
+                                             GetLastError(),
+                                             "CreateRemoteThread"));
     goto out;
   }
 
   // Wait for the thread to terminate
   if (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0) {
-    ThrowException(WinapiErrnoException(GetLastError(), "WaitForSingleObject"));
+    env->ThrowException(WinapiErrnoException(env,
+                                             GetLastError(),
+                                             "WaitForSingleObject"));
     goto out;
   }
 
@@ -3224,7 +3278,7 @@ static void DebugProcess(const FunctionCallbackInfo<Value>& args) {
 
 
 static void DebugPause(const FunctionCallbackInfo<Value>& args) {
-  v8::Debug::DebugBreak(node_isolate);
+  v8::Debug::DebugBreak(args.GetIsolate());
 }
 
 
@@ -3329,7 +3383,7 @@ void Init(int* argc,
 
   // If the --debug flag was specified then initialize the debug thread.
   if (use_debug_agent) {
-    EnableDebug(debug_wait_connect);
+    EnableDebug(node_isolate, debug_wait_connect);
   } else {
     RegisterDebugSignalHandler();
   }
@@ -3373,15 +3427,14 @@ int EmitExit(Environment* env) {
   HandleScope handle_scope(env->isolate());
   Context::Scope context_scope(env->context());
   Local<Object> process_object = env->process_object();
-  process_object->Set(FIXED_ONE_BYTE_STRING(node_isolate, "_exiting"),
-                      True(node_isolate));
+  process_object->Set(env->exiting_string(), True(env->isolate()));
 
-  Handle<String> exitCode = FIXED_ONE_BYTE_STRING(node_isolate, "exitCode");
+  Handle<String> exitCode = env->exit_code_string();
   int code = process_object->Get(exitCode)->IntegerValue();
 
   Local<Value> args[] = {
-    FIXED_ONE_BYTE_STRING(node_isolate, "exit"),
-    Integer::New(code, node_isolate)
+    env->exit_string(),
+    Integer::New(code, env->isolate())
   };
 
   MakeCallback(env, process_object, "emit", ARRAY_SIZE(args), args);
index c07b3ae..3c48c79 100644 (file)
 #include "v8.h"  // NOLINT(build/include_order)
 #include "node_version.h"  // NODE_MODULE_VERSION
 
+#define NODE_DEPRECATED(msg, fn) V8_DEPRECATED(msg, fn)
+
 // Forward-declare these functions now to stop MSVS from becoming
 // terminally confused when it's done in node_internals.h
 namespace node {
 
-NODE_EXTERN v8::Local<v8::Value> ErrnoException(int errorno,
+NODE_EXTERN v8::Local<v8::Value> ErrnoException(v8::Isolate* isolate,
+                                                int errorno,
                                                 const char* syscall = NULL,
                                                 const char* message = NULL,
                                                 const char* path = NULL);
-NODE_EXTERN v8::Local<v8::Value> UVException(int errorno,
+NODE_EXTERN v8::Local<v8::Value> UVException(v8::Isolate* isolate,
+                                             int errorno,
                                              const char* syscall = NULL,
                                              const char* message = NULL,
                                              const char* path = NULL);
 
+NODE_DEPRECATED("Use UVException(isolate, ...)",
+                inline v8::Local<v8::Value> ErrnoException(
+      int errorno,
+      const char* syscall = NULL,
+      const char* message = NULL,
+      const char* path = NULL) {
+  return ErrnoException(v8::Isolate::GetCurrent(),
+                        errorno,
+                        syscall,
+                        message,
+                        path);
+})
+
+inline v8::Local<v8::Value> UVException(int errorno,
+                                        const char* syscall = NULL,
+                                        const char* message = NULL,
+                                        const char* path = NULL) {
+  return UVException(v8::Isolate::GetCurrent(),
+                     errorno,
+                     syscall,
+                     message,
+                     path);
+}
+
 /*
  * MakeCallback doesn't have a HandleScope. That means the callers scope
  * will retain ownership of created handles from MakeCallback and related.
@@ -187,27 +215,79 @@ inline void NODE_SET_PROTOTYPE_METHOD(v8::Handle<v8::FunctionTemplate> recv,
 #define NODE_SET_PROTOTYPE_METHOD node::NODE_SET_PROTOTYPE_METHOD
 
 enum encoding {ASCII, UTF8, BASE64, UCS2, BINARY, HEX, BUFFER};
-enum encoding ParseEncoding(v8::Handle<v8::Value> encoding_v,
+enum encoding ParseEncoding(v8::Isolate* isolate,
+                            v8::Handle<v8::Value> encoding_v,
                             enum encoding _default = BINARY);
-NODE_EXTERN void FatalException(const v8::TryCatch& try_catch);
-
-NODE_EXTERN v8::Local<v8::Value> Encode(const void *buf, size_t len,
+NODE_DEPRECATED("Use ParseEncoding(isolate, ...)",
+                inline enum encoding ParseEncoding(
+      v8::Handle<v8::Value> encoding_v,
+      enum encoding _default = BINARY) {
+  return ParseEncoding(v8::Isolate::GetCurrent(), encoding_v, _default);
+})
+
+NODE_EXTERN void FatalException(v8::Isolate* isolate,
+                                const v8::TryCatch& try_catch);
+
+NODE_DEPRECATED("Use FatalException(isolate, ...)",
+                inline void FatalException(const v8::TryCatch& try_catch) {
+  return FatalException(v8::Isolate::GetCurrent(), try_catch);
+})
+
+NODE_EXTERN v8::Local<v8::Value> Encode(v8::Isolate* isolate,
+                                        const void* buf,
+                                        size_t len,
                                         enum encoding encoding = BINARY);
+NODE_DEPRECATED("Use Encode(isolate, ...)",
+                inline v8::Local<v8::Value> Encode(
+    const void* buf,
+    size_t len,
+    enum encoding encoding = BINARY) {
+  return Encode(v8::Isolate::GetCurrent(), buf, len, encoding);
+})
 
 // Returns -1 if the handle was not valid for decoding
-NODE_EXTERN ssize_t DecodeBytes(v8::Handle<v8::Value>,
+NODE_EXTERN ssize_t DecodeBytes(v8::Isolate* isolate,
+                                v8::Handle<v8::Value>,
                                 enum encoding encoding = BINARY);
+NODE_DEPRECATED("Use DecodeBytes(isolate, ...)",
+                inline ssize_t DecodeBytes(
+    v8::Handle<v8::Value> val,
+    enum encoding encoding = BINARY) {
+  return DecodeBytes(v8::Isolate::GetCurrent(), val, encoding);
+})
 
 // returns bytes written.
-NODE_EXTERN ssize_t DecodeWrite(char *buf,
+NODE_EXTERN ssize_t DecodeWrite(v8::Isolate* isolate,
+                                char* buf,
                                 size_t buflen,
                                 v8::Handle<v8::Value>,
                                 enum encoding encoding = BINARY);
+NODE_DEPRECATED("Use DecodeWrite(isolate, ...)",
+                inline ssize_t DecodeWrite(char* buf,
+                                           size_t buflen,
+                                           v8::Handle<v8::Value> val,
+                                           enum encoding encoding = BINARY) {
+  return DecodeWrite(v8::Isolate::GetCurrent(), buf, buflen, val, encoding);
+})
 
 #ifdef _WIN32
-NODE_EXTERN v8::Local<v8::Value> WinapiErrnoException(int errorno,
-    const char *syscall = NULL,  const char *msg = "",
+NODE_EXTERN v8::Local<v8::Value> WinapiErrnoException(
+    v8::Isolate* isolate,
+    int errorno,
+    const char *syscall = NULL,
+    const char *msg = "",
     const char *path = NULL);
+
+NODE_DEPRECATED("Use WinapiErrnoException(isolate, ...)",
+                inline v8::Local<v8::Value> WinapiErrnoException(int errorno,
+    const char *syscall = NULL,  const char *msg = "",
+    const char *path = NULL) {
+  return WinapiErrnoException(v8::Isolate::GetCurrent(),
+                              errorno,
+                              syscall,
+                              msg,
+                              path);
+})
 #endif
 
 const char *signo_string(int errorno);
index 5a3803e..8304c4f 100644 (file)
@@ -37,7 +37,9 @@
 #define MIN(a, b) ((a) < (b) ? (a) : (b))
 
 #define CHECK_NOT_OOB(r)                                                    \
-  do { if (!(r)) return ThrowRangeError("out of range index"); } while (0)
+  do {                                                                      \
+    if (!(r)) return env->ThrowRangeError("out of range index");            \
+  } while (0)
 
 #define ARGS_THIS(argT)                                                     \
   Local<Object> obj = argT;                                                 \
@@ -66,6 +68,7 @@ using v8::FunctionCallbackInfo;
 using v8::FunctionTemplate;
 using v8::Handle;
 using v8::HandleScope;
+using v8::Isolate;
 using v8::Local;
 using v8::Number;
 using v8::Object;
@@ -113,23 +116,22 @@ size_t Length(Handle<Object> obj) {
 }
 
 
-Local<Object> New(Handle<String> string, enum encoding enc) {
-  HandleScope scope(node_isolate);
+Local<Object> New(Isolate* isolate, Handle<String> string, enum encoding enc) {
+  HandleScope scope(isolate);
 
-  size_t length = StringBytes::Size(string, enc);
+  size_t length = StringBytes::Size(isolate, string, enc);
 
   Local<Object> buf = New(length);
   char* data = Buffer::Data(buf);
-  StringBytes::Write(data, length, string, enc);
+  StringBytes::Write(isolate, data, length, string, enc);
 
   return scope.Close(buf);
 }
 
 
-Local<Object> New(size_t length) {
-  HandleScope handle_scope(node_isolate);
-  Environment* env = Environment::GetCurrent(node_isolate);
-  Local<Object> obj = Buffer::New(env, length);
+Local<Object> New(Isolate* isolate, size_t length) {
+  HandleScope handle_scope(isolate);
+  Local<Object> obj = Buffer::New(Environment::GetCurrent(isolate), length);
   return handle_scope.Close(obj);
 }
 
@@ -137,11 +139,11 @@ Local<Object> New(size_t length) {
 // TODO(trevnorris): these have a flaw by needing to call the Buffer inst then
 // Alloc. continue to look for a better architecture.
 Local<Object> New(Environment* env, size_t length) {
-  HandleScope scope(node_isolate);
+  HandleScope scope(env->isolate());
 
   assert(length <= kMaxLength);
 
-  Local<Value> arg = Uint32::NewFromUnsigned(length, node_isolate);
+  Local<Value> arg = Uint32::NewFromUnsigned(length, env->isolate());
   Local<Object> obj = env->buffer_constructor_function()->NewInstance(1, &arg);
 
   // TODO(trevnorris): done like this to handle HasInstance since only checks
@@ -155,15 +157,15 @@ Local<Object> New(Environment* env, size_t length) {
   } else {
     data = NULL;
   }
-  smalloc::Alloc(obj, data, length);
+  smalloc::Alloc(env, obj, data, length);
 
   return scope.Close(obj);
 }
 
 
-Local<Object> New(const char* data, size_t length) {
-  HandleScope handle_scope(node_isolate);
-  Environment* env = Environment::GetCurrent(node_isolate);
+Local<Object> New(Isolate* isolate, const char* data, size_t length) {
+  Environment* env = Environment::GetCurrent(isolate);
+  HandleScope handle_scope(env->isolate());
   Local<Object> obj = Buffer::New(env, data, length);
   return handle_scope.Close(obj);
 }
@@ -173,11 +175,11 @@ Local<Object> New(const char* data, size_t length) {
 // but for consistency w/ the other should use data. And a copy version renamed
 // to something else.
 Local<Object> New(Environment* env, const char* data, size_t length) {
-  HandleScope scope(node_isolate);
+  HandleScope scope(env->isolate());
 
   assert(length <= kMaxLength);
 
-  Local<Value> arg = Uint32::NewFromUnsigned(length, node_isolate);
+  Local<Value> arg = Uint32::NewFromUnsigned(length, env->isolate());
   Local<Object> obj = env->buffer_constructor_function()->NewInstance(1, &arg);
 
   // TODO(trevnorris): done like this to handle HasInstance since only checks
@@ -193,18 +195,19 @@ Local<Object> New(Environment* env, const char* data, size_t length) {
     new_data = NULL;
   }
 
-  smalloc::Alloc(obj, new_data, length);
+  smalloc::Alloc(env, obj, new_data, length);
 
   return scope.Close(obj);
 }
 
 
-Local<Object> New(char* data,
+Local<Object> New(Isolate* isolate,
+                  char* data,
                   size_t length,
                   smalloc::FreeCallback callback,
                   void* hint) {
-  HandleScope handle_scope(node_isolate);
-  Environment* env = Environment::GetCurrent(node_isolate);
+  Environment* env = Environment::GetCurrent(isolate);
+  HandleScope handle_scope(env->isolate());
   Local<Object> obj = Buffer::New(env, data, length, callback, hint);
   return handle_scope.Close(obj);
 }
@@ -215,36 +218,36 @@ Local<Object> New(Environment* env,
                   size_t length,
                   smalloc::FreeCallback callback,
                   void* hint) {
-  HandleScope scope(node_isolate);
+  HandleScope scope(env->isolate());
 
   assert(length <= kMaxLength);
 
-  Local<Value> arg = Uint32::NewFromUnsigned(length, node_isolate);
+  Local<Value> arg = Uint32::NewFromUnsigned(length, env->isolate());
   Local<Object> obj = env->buffer_constructor_function()->NewInstance(1, &arg);
 
-  smalloc::Alloc(obj, data, length, callback, hint);
+  smalloc::Alloc(env, obj, data, length, callback, hint);
 
   return scope.Close(obj);
 }
 
 
-Local<Object> Use(char* data, uint32_t length) {
-  HandleScope handle_scope(node_isolate);
-  Environment* env = Environment::GetCurrent(node_isolate);
+Local<Object> Use(Isolate* isolate, char* data, uint32_t length) {
+  Environment* env = Environment::GetCurrent(isolate);
+  HandleScope handle_scope(env->isolate());
   Local<Object> obj = Buffer::Use(env, data, length);
   return handle_scope.Close(obj);
 }
 
 
 Local<Object> Use(Environment* env, char* data, uint32_t length) {
-  HandleScope scope(node_isolate);
+  HandleScope scope(env->isolate());
 
   assert(length <= kMaxLength);
 
-  Local<Value> arg = Uint32::NewFromUnsigned(length, node_isolate);
+  Local<Value> arg = Uint32::NewFromUnsigned(length, env->isolate());
   Local<Object> obj = env->buffer_constructor_function()->NewInstance(1, &arg);
 
-  smalloc::Alloc(obj, data, length);
+  smalloc::Alloc(env, obj, data, length);
 
   return scope.Close(obj);
 }
@@ -252,13 +255,14 @@ Local<Object> Use(Environment* env, char* data, uint32_t length) {
 
 template <encoding encoding>
 void StringSlice(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   ARGS_THIS(args.This())
   SLICE_START_END(args[0], args[1], obj_length)
 
   args.GetReturnValue().Set(
-      StringBytes::Encode(obj_data + start, length, encoding));
+      StringBytes::Encode(env->isolate(), obj_data + start, length, encoding));
 }
 
 
@@ -294,12 +298,13 @@ void Base64Slice(const FunctionCallbackInfo<Value>& args) {
 
 // bytesCopied = buffer.copy(target[, targetStart][, sourceStart][, sourceEnd]);
 void Copy(const FunctionCallbackInfo<Value> &args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   Local<Object> target = args[0]->ToObject();
 
   if (!HasInstance(target))
-    return ThrowTypeError("first arg should be a Buffer");
+    return env->ThrowTypeError("first arg should be a Buffer");
 
   ARGS_THIS(args.This())
   size_t target_length = target->GetIndexedPropertiesExternalArrayDataLength();
@@ -318,7 +323,7 @@ void Copy(const FunctionCallbackInfo<Value> &args) {
     return args.GetReturnValue().Set(0);
 
   if (source_start > obj_length)
-    return ThrowRangeError("out of range index");
+    return env->ThrowRangeError("out of range index");
 
   if (source_end - source_start > target_length - target_start)
     source_end = source_start + target_length - target_start;
@@ -334,7 +339,8 @@ void Copy(const FunctionCallbackInfo<Value> &args) {
 
 // buffer.fill(value[, start][, end]);
 void Fill(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   ARGS_THIS(args.This())
   SLICE_START_END(args[1], args[2], obj_length)
@@ -379,17 +385,18 @@ void Fill(const FunctionCallbackInfo<Value>& args) {
 
 template <encoding encoding>
 void StringWrite(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   ARGS_THIS(args.This())
 
   if (!args[0]->IsString())
-    return ThrowTypeError("Argument must be a string");
+    return env->ThrowTypeError("Argument must be a string");
 
   Local<String> str = args[0]->ToString();
 
   if (encoding == HEX && str->Length() % 2 != 0)
-    return ThrowTypeError("Invalid hex string");
+    return env->ThrowTypeError("Invalid hex string");
 
   size_t offset;
   size_t max_length;
@@ -406,9 +413,10 @@ void StringWrite(const FunctionCallbackInfo<Value>& args) {
     max_length = max_length / 2;
 
   if (offset >= obj_length)
-    return ThrowRangeError("Offset is out of bounds");
+    return env->ThrowRangeError("Offset is out of bounds");
 
-  uint32_t written = StringBytes::Write(obj_data + offset,
+  uint32_t written = StringBytes::Write(env->isolate(),
+                                        obj_data + offset,
                                         max_length,
                                         str,
                                         encoding,
@@ -459,6 +467,7 @@ static inline void Swizzle(char* start, unsigned int len) {
 
 template <typename T, enum Endianness endianness>
 void ReadFloatGeneric(const FunctionCallbackInfo<Value>& args) {
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
   bool doAssert = !args[1]->BooleanValue();
   size_t offset;
 
@@ -467,7 +476,7 @@ void ReadFloatGeneric(const FunctionCallbackInfo<Value>& args) {
   if (doAssert) {
     size_t len = Length(args.This());
     if (offset + sizeof(T) > len || offset + sizeof(T) < offset)
-      return ThrowRangeError("Trying to read beyond buffer length");
+      return env->ThrowRangeError("Trying to read beyond buffer length");
   }
 
   union NoAlias {
@@ -508,20 +517,21 @@ void ReadDoubleBE(const FunctionCallbackInfo<Value>& args) {
 
 template <typename T, enum Endianness endianness>
 uint32_t WriteFloatGeneric(const FunctionCallbackInfo<Value>& args) {
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
   bool doAssert = !args[2]->BooleanValue();
 
   T val = static_cast<T>(args[0]->NumberValue());
   size_t offset;
 
   if (!ParseArrayIndex(args[1], 0, &offset)) {
-    ThrowRangeError("out of range index");
+    env->ThrowRangeError("out of range index");
     return 0;
   }
 
   if (doAssert) {
     size_t len = Length(args.This());
     if (offset + sizeof(T) > len || offset + sizeof(T) < offset) {
-      ThrowRangeError("Trying to write beyond buffer length");
+      env->ThrowRangeError("Trying to write beyond buffer length");
       return 0;
     }
   }
@@ -562,7 +572,8 @@ void WriteDoubleBE(const FunctionCallbackInfo<Value>& args) {
 
 
 void ToArrayBuffer(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   ARGS_THIS(args.This());
   void* adata = malloc(obj_length);
@@ -581,30 +592,30 @@ void ToArrayBuffer(const FunctionCallbackInfo<Value>& args) {
 
 
 void ByteLength(const FunctionCallbackInfo<Value> &args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   if (!args[0]->IsString())
-    return ThrowTypeError("Argument must be a string");
+    return env->ThrowTypeError("Argument must be a string");
 
   Local<String> s = args[0]->ToString();
-  enum encoding e = ParseEncoding(args[1], UTF8);
+  enum encoding e = ParseEncoding(env->isolate(), args[1], UTF8);
 
-  uint32_t size = StringBytes::Size(s, e);
+  uint32_t size = StringBytes::Size(env->isolate(), s, e);
   args.GetReturnValue().Set(size);
 }
 
 
 // pass Buffer object to load prototype methods
 void SetupBufferJS(const FunctionCallbackInfo<Value>& args) {
-  HandleScope handle_scope(args.GetIsolate());
   Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   assert(args[0]->IsFunction());
 
   Local<Function> bv = args[0].As<Function>();
   env->set_buffer_constructor_function(bv);
-  Local<Value> proto_v =
-      bv->Get(FIXED_ONE_BYTE_STRING(node_isolate, "prototype"));
+  Local<Value> proto_v = bv->Get(env->prototype_string());
 
   assert(proto_v->IsObject());
 
@@ -640,15 +651,15 @@ void SetupBufferJS(const FunctionCallbackInfo<Value>& args) {
   NODE_SET_METHOD(proto, "fill", Fill);
 
   // for backwards compatibility
-  proto->Set(FIXED_ONE_BYTE_STRING(node_isolate, "offset"),
-             Uint32::New(0, node_isolate),
+  proto->Set(env->offset_string(),
+             Uint32::New(0, env->isolate()),
              v8::ReadOnly);
 
   assert(args[1]->IsObject());
 
   Local<Object> internal = args[1].As<Object>();
 
-  internal->Set(FIXED_ONE_BYTE_STRING(node_isolate, "byteLength"),
+  internal->Set(env->byte_length_string(),
                 FunctionTemplate::New(ByteLength)->GetFunction());
 }
 
index 9b004bd..1d58c30 100644 (file)
@@ -43,22 +43,52 @@ NODE_EXTERN size_t Length(v8::Handle<v8::Value> val);
 NODE_EXTERN size_t Length(v8::Handle<v8::Object> val);
 
 // public constructor
-NODE_EXTERN v8::Local<v8::Object> New(size_t length);
+NODE_EXTERN v8::Local<v8::Object> New(v8::Isolate* isolate, size_t length);
+NODE_DEPRECATED("Use New(isolate, ...)",
+                inline v8::Local<v8::Object> New(size_t length) {
+  return New(v8::Isolate::GetCurrent(), length);
+})
 // public constructor from string
-NODE_EXTERN v8::Local<v8::Object> New(v8::Handle<v8::String> string,
+NODE_EXTERN v8::Local<v8::Object> New(v8::Isolate* isolate,
+                                      v8::Handle<v8::String> string,
                                       enum encoding enc = UTF8);
+NODE_DEPRECATED("Use New(isolate, ...)",
+                inline v8::Local<v8::Object> New(v8::Handle<v8::String> string,
+                                                 enum encoding enc = UTF8) {
+  return New(v8::Isolate::GetCurrent(), string, enc);
+})
 // public constructor - data is copied
 // TODO(trevnorris): should be something like Copy()
-NODE_EXTERN v8::Local<v8::Object> New(const char* data, size_t len);
+NODE_EXTERN v8::Local<v8::Object> New(v8::Isolate* isolate,
+                                      const char* data,
+                                      size_t len);
+NODE_DEPRECATED("Use New(isolate, ...)",
+                inline v8::Local<v8::Object> New(const char* data, size_t len) {
+  return New(v8::Isolate::GetCurrent(), data, len);
+})
 // public constructor - data is used, callback is passed data on object gc
-NODE_EXTERN v8::Local<v8::Object> New(char* data,
+NODE_EXTERN v8::Local<v8::Object> New(v8::Isolate* isolate,
+                                      char* data,
                                       size_t length,
                                       smalloc::FreeCallback callback,
                                       void* hint);
+NODE_DEPRECATED("Use New(isolate, ...)",
+                inline v8::Local<v8::Object> New(char* data,
+                                                 size_t length,
+                                                 smalloc::FreeCallback callback,
+                                                 void* hint) {
+  return New(v8::Isolate::GetCurrent(), data, length, callback, hint);
+})
 
 // public constructor - data is used.
 // TODO(trevnorris): should be New() for consistency
-NODE_EXTERN v8::Local<v8::Object> Use(char* data, uint32_t len);
+NODE_EXTERN v8::Local<v8::Object> Use(v8::Isolate* isolate,
+                                      char* data,
+                                      uint32_t len);
+NODE_DEPRECATED("Use Use(isolate, ...)",
+                inline v8::Local<v8::Object> Use(char* data, uint32_t len) {
+  return Use(v8::Isolate::GetCurrent(), data, len);
+})
 
 // This is verbose to be explicit with inline commenting
 static inline bool IsWithinBounds(size_t off, size_t len, size_t max) {
index 4ef6126..05d2b11 100644 (file)
@@ -128,7 +128,7 @@ class ContextifyContext {
   // should be fixed properly in V8, and this copy function should be
   // removed once there is a better way.
   void CopyProperties() {
-    HandleScope scope(node_isolate);
+    HandleScope scope(env()->isolate());
 
     Local<Context> context = PersistentToLocal(env()->isolate(), context_);
     Local<Object> global = context->Global()->GetPrototype()->ToObject();
@@ -155,7 +155,7 @@ class ContextifyContext {
         // which doesn't faithfully capture the full range of configurations
         // that can be done using Object.defineProperty.
         if (clone_property_method.IsEmpty()) {
-          Local<String> code = FIXED_ONE_BYTE_STRING(node_isolate,
+          Local<String> code = FIXED_ONE_BYTE_STRING(env()->isolate(),
               "(function cloneProperty(source, key, target) {\n"
               "  if (key === 'Proxy') return;\n"
               "  try {\n"
@@ -167,7 +167,7 @@ class ContextifyContext {
               "  }\n"
               "})");
 
-          Local<String> fname = FIXED_ONE_BYTE_STRING(node_isolate,
+          Local<String> fname = FIXED_ONE_BYTE_STRING(env()->isolate(),
               "binding:script");
           Local<Script> script = Script::Compile(code, fname);
           clone_property_method = Local<Function>::Cast(script->Run());
@@ -186,7 +186,7 @@ class ContextifyContext {
   // NamedPropertyHandler will store a reference to it forever and keep it
   // from getting gc'd.
   Local<Value> CreateDataWrapper(Environment* env) {
-    HandleScope scope(node_isolate);
+    HandleScope scope(env->isolate());
     Local<Object> wrapper =
         env->script_data_constructor_function()->NewInstance();
     if (wrapper.IsEmpty())
@@ -198,11 +198,11 @@ class ContextifyContext {
 
 
   Local<Context> CreateV8Context(Environment* env) {
-    HandleScope scope(node_isolate);
+    HandleScope scope(env->isolate());
     Local<FunctionTemplate> function_template = FunctionTemplate::New();
     function_template->SetHiddenPrototype(true);
 
-    Local<Object> sandbox = PersistentToLocal(node_isolate, sandbox_);
+    Local<Object> sandbox = PersistentToLocal(env->isolate(), sandbox_);
     function_template->SetClassName(sandbox->GetConstructorName());
 
     Local<ObjectTemplate> object_template =
@@ -215,7 +215,7 @@ class ContextifyContext {
                                              CreateDataWrapper(env));
     object_template->SetAccessCheckCallbacks(GlobalPropertyNamedAccessCheck,
                                              GlobalPropertyIndexedAccessCheck);
-    return scope.Close(Context::New(node_isolate, NULL, object_template));
+    return scope.Close(Context::New(env->isolate(), NULL, object_template));
   }
 
 
@@ -230,16 +230,16 @@ class ContextifyContext {
 
 
   static void MakeContext(const FunctionCallbackInfo<Value>& args) {
-    HandleScope handle_scope(args.GetIsolate());
     Environment* env = Environment::GetCurrent(args.GetIsolate());
+    HandleScope scope(env->isolate());
 
     if (!args[0]->IsObject()) {
-      return ThrowTypeError("sandbox argument must be an object.");
+      return env->ThrowTypeError("sandbox argument must be an object.");
     }
     Local<Object> sandbox = args[0].As<Object>();
 
     Local<String> hidden_name =
-        FIXED_ONE_BYTE_STRING(node_isolate, "_contextifyHidden");
+        FIXED_ONE_BYTE_STRING(env->isolate(), "_contextifyHidden");
 
     // Don't allow contextifying a sandbox multiple times.
     assert(sandbox->GetHiddenValue(hidden_name).IsEmpty());
@@ -261,16 +261,17 @@ class ContextifyContext {
 
 
   static void IsContext(const FunctionCallbackInfo<Value>& args) {
-    HandleScope scope(node_isolate);
+    Environment* env = Environment::GetCurrent(args.GetIsolate());
+    HandleScope scope(env->isolate());
 
     if (!args[0]->IsObject()) {
-      ThrowTypeError("sandbox must be an object");
+      env->ThrowTypeError("sandbox must be an object");
       return;
     }
     Local<Object> sandbox = args[0].As<Object>();
 
     Local<String> hidden_name =
-        FIXED_ONE_BYTE_STRING(node_isolate, "_contextifyHidden");
+        FIXED_ONE_BYTE_STRING(env->isolate(), "_contextifyHidden");
 
     args.GetReturnValue().Set(!sandbox->GetHiddenValue(hidden_name).IsEmpty());
   }
@@ -287,9 +288,10 @@ class ContextifyContext {
 
 
   static ContextifyContext* ContextFromContextifiedSandbox(
+      Isolate* isolate,
       const Local<Object>& sandbox) {
     Local<String> hidden_name =
-        FIXED_ONE_BYTE_STRING(node_isolate, "_contextifyHidden");
+        FIXED_ONE_BYTE_STRING(isolate, "_contextifyHidden");
     Local<Value> context_external_v = sandbox->GetHiddenValue(hidden_name);
     if (context_external_v.IsEmpty() || !context_external_v->IsExternal()) {
       return NULL;
@@ -319,20 +321,21 @@ class ContextifyContext {
   static void GlobalPropertyGetterCallback(
       Local<String> property,
       const PropertyCallbackInfo<Value>& args) {
-    HandleScope scope(node_isolate);
+    Isolate* isolate = args.GetIsolate();
+    HandleScope scope(isolate);
 
     ContextifyContext* ctx =
         Unwrap<ContextifyContext>(args.Data().As<Object>());
 
-    Local<Object> sandbox = PersistentToLocal(node_isolate, ctx->sandbox_);
+    Local<Object> sandbox = PersistentToLocal(isolate, ctx->sandbox_);
     Local<Value> rv = sandbox->GetRealNamedProperty(property);
     if (rv.IsEmpty()) {
-      Local<Object> proxy_global = PersistentToLocal(node_isolate,
+      Local<Object> proxy_global = PersistentToLocal(isolate,
                                                      ctx->proxy_global_);
       rv = proxy_global->GetRealNamedProperty(property);
     }
     if (!rv.IsEmpty() && rv == ctx->sandbox_) {
-      rv = PersistentToLocal(node_isolate, ctx->proxy_global_);
+      rv = PersistentToLocal(isolate, ctx->proxy_global_);
     }
 
     args.GetReturnValue().Set(rv);
@@ -343,25 +346,27 @@ class ContextifyContext {
       Local<String> property,
       Local<Value> value,
       const PropertyCallbackInfo<Value>& args) {
-    HandleScope scope(node_isolate);
+    Isolate* isolate = args.GetIsolate();
+    HandleScope scope(isolate);
 
     ContextifyContext* ctx =
         Unwrap<ContextifyContext>(args.Data().As<Object>());
 
-    PersistentToLocal(node_isolate, ctx->sandbox_)->Set(property, value);
+    PersistentToLocal(isolate, ctx->sandbox_)->Set(property, value);
   }
 
 
   static void GlobalPropertyQueryCallback(
       Local<String> property,
       const PropertyCallbackInfo<Integer>& args) {
-    HandleScope scope(node_isolate);
+    Isolate* isolate = args.GetIsolate();
+    HandleScope scope(isolate);
 
     ContextifyContext* ctx =
         Unwrap<ContextifyContext>(args.Data().As<Object>());
 
-    Local<Object> sandbox = PersistentToLocal(node_isolate, ctx->sandbox_);
-    Local<Object> proxy_global = PersistentToLocal(node_isolate,
+    Local<Object> sandbox = PersistentToLocal(isolate, ctx->sandbox_);
+    Local<Object> proxy_global = PersistentToLocal(isolate,
                                                    ctx->proxy_global_);
 
     bool in_sandbox = sandbox->GetRealNamedProperty(property).IsEmpty();
@@ -376,15 +381,16 @@ class ContextifyContext {
   static void GlobalPropertyDeleterCallback(
       Local<String> property,
       const PropertyCallbackInfo<Boolean>& args) {
-    HandleScope scope(node_isolate);
+    Isolate* isolate = args.GetIsolate();
+    HandleScope scope(isolate);
 
     ContextifyContext* ctx =
         Unwrap<ContextifyContext>(args.Data().As<Object>());
 
-    bool success = PersistentToLocal(node_isolate,
+    bool success = PersistentToLocal(isolate,
                                      ctx->sandbox_)->Delete(property);
     if (!success) {
-      success = PersistentToLocal(node_isolate,
+      success = PersistentToLocal(isolate,
                                   ctx->proxy_global_)->Delete(property);
     }
     args.GetReturnValue().Set(success);
@@ -393,12 +399,12 @@ class ContextifyContext {
 
   static void GlobalPropertyEnumeratorCallback(
       const PropertyCallbackInfo<Array>& args) {
-    HandleScope scope(node_isolate);
+    HandleScope scope(args.GetIsolate());
 
     ContextifyContext* ctx =
         Unwrap<ContextifyContext>(args.Data().As<Object>());
 
-    Local<Object> sandbox = PersistentToLocal(node_isolate, ctx->sandbox_);
+    Local<Object> sandbox = PersistentToLocal(args.GetIsolate(), ctx->sandbox_);
     args.GetReturnValue().Set(sandbox->GetPropertyNames());
   }
 };
@@ -409,9 +415,9 @@ class ContextifyScript : public BaseObject {
 
  public:
   static void Init(Environment* env, Local<Object> target) {
-    HandleScope scope(node_isolate);
+    HandleScope scope(env->isolate());
     Local<String> class_name =
-        FIXED_ONE_BYTE_STRING(node_isolate, "ContextifyScript");
+        FIXED_ONE_BYTE_STRING(env->isolate(), "ContextifyScript");
 
     Local<FunctionTemplate> script_tmpl = FunctionTemplate::New(New);
     script_tmpl->InstanceTemplate()->SetInternalFieldCount(1);
@@ -428,13 +434,13 @@ class ContextifyScript : public BaseObject {
 
   // args: code, [options]
   static void New(const FunctionCallbackInfo<Value>& args) {
-    HandleScope scope(node_isolate);
+    Environment* env = Environment::GetCurrent(args.GetIsolate());
+    HandleScope scope(env->isolate());
 
     if (!args.IsConstructCall()) {
-      return ThrowError("Must call vm.Script as a constructor.");
+      return env->ThrowError("Must call vm.Script as a constructor.");
     }
 
-    Environment* env = Environment::GetCurrent(args.GetIsolate());
     ContextifyScript* contextify_script =
         new ContextifyScript(env, args.This());
 
@@ -459,7 +465,7 @@ class ContextifyScript : public BaseObject {
       try_catch.ReThrow();
       return;
     }
-    contextify_script->script_.Reset(node_isolate, v8_script);
+    contextify_script->script_.Reset(env->isolate(), v8_script);
   }
 
 
@@ -471,8 +477,8 @@ class ContextifyScript : public BaseObject {
 
   // args: [options]
   static void RunInThisContext(const FunctionCallbackInfo<Value>& args) {
-    HandleScope handle_scope(args.GetIsolate());
-    Environment* env = Environment::GetCurrent(args.GetIsolate());
+    Isolate* isolate = args.GetIsolate();
+    HandleScope handle_scope(isolate);
 
     // Assemble arguments
     TryCatch try_catch;
@@ -484,17 +490,20 @@ class ContextifyScript : public BaseObject {
     }
 
     // Do the eval within this context
+    Environment* env = Environment::GetCurrent(isolate);
     EvalMachine(env, timeout, display_errors, args, try_catch);
   }
 
   // args: sandbox, [options]
   static void RunInContext(const FunctionCallbackInfo<Value>& args) {
-    HandleScope scope(node_isolate);
+    Environment* env = Environment::GetCurrent(args.GetIsolate());
+    HandleScope scope(env->isolate());
 
     // Assemble arguments
     TryCatch try_catch;
     if (!args[0]->IsObject()) {
-      return ThrowTypeError("contextifiedSandbox argument must be an object.");
+      return env->ThrowTypeError(
+          "contextifiedSandbox argument must be an object.");
     }
     Local<Object> sandbox = args[0].As<Object>();
     int64_t timeout = GetTimeoutArg(args, 1);
@@ -506,9 +515,10 @@ class ContextifyScript : public BaseObject {
 
     // Get the context from the sandbox
     ContextifyContext* contextify_context =
-        ContextifyContext::ContextFromContextifiedSandbox(sandbox);
+        ContextifyContext::ContextFromContextifiedSandbox(env->isolate(),
+                                                          sandbox);
     if (contextify_context == NULL) {
-      return ThrowTypeError(
+      return env->ThrowTypeError(
           "sandbox argument must have been converted to a context.");
     }
 
@@ -532,11 +542,12 @@ class ContextifyScript : public BaseObject {
       return -1;
     }
     if (!args[i]->IsObject()) {
-      ThrowTypeError("options must be an object");
+      Environment::ThrowTypeError(args.GetIsolate(),
+                                  "options must be an object");
       return -1;
     }
 
-    Local<String> key = FIXED_ONE_BYTE_STRING(node_isolate, "timeout");
+    Local<String> key = FIXED_ONE_BYTE_STRING(args.GetIsolate(), "timeout");
     Local<Value> value = args[i].As<Object>()->Get(key);
     if (value->IsUndefined()) {
       return -1;
@@ -544,7 +555,8 @@ class ContextifyScript : public BaseObject {
     int64_t timeout = value->IntegerValue();
 
     if (timeout <= 0) {
-      ThrowRangeError("timeout must be a positive number");
+      Environment::ThrowRangeError(args.GetIsolate(),
+                                   "timeout must be a positive number");
       return -1;
     }
     return timeout;
@@ -557,11 +569,13 @@ class ContextifyScript : public BaseObject {
       return true;
     }
     if (!args[i]->IsObject()) {
-      ThrowTypeError("options must be an object");
+      Environment::ThrowTypeError(args.GetIsolate(),
+                                  "options must be an object");
       return false;
     }
 
-    Local<String> key = FIXED_ONE_BYTE_STRING(node_isolate, "displayErrors");
+    Local<String> key = FIXED_ONE_BYTE_STRING(args.GetIsolate(),
+                                              "displayErrors");
     Local<Value> value = args[i].As<Object>()->Get(key);
 
     return value->IsUndefined() ? true : value->BooleanValue();
@@ -571,7 +585,7 @@ class ContextifyScript : public BaseObject {
   static Local<String> GetFilenameArg(const FunctionCallbackInfo<Value>& args,
                                       const int i) {
     Local<String> defaultFilename =
-        FIXED_ONE_BYTE_STRING(node_isolate, "evalmachine.<anonymous>");
+        FIXED_ONE_BYTE_STRING(args.GetIsolate(), "evalmachine.<anonymous>");
 
     if (args[i]->IsUndefined()) {
       return defaultFilename;
@@ -580,11 +594,12 @@ class ContextifyScript : public BaseObject {
       return args[i].As<String>();
     }
     if (!args[i]->IsObject()) {
-      ThrowTypeError("options must be an object");
+      Environment::ThrowTypeError(args.GetIsolate(),
+                                  "options must be an object");
       return Local<String>();
     }
 
-    Local<String> key = FIXED_ONE_BYTE_STRING(node_isolate, "filename");
+    Local<String> key = FIXED_ONE_BYTE_STRING(args.GetIsolate(), "filename");
     Local<Value> value = args[i].As<Object>()->Get(key);
 
     return value->IsUndefined() ? defaultFilename : value->ToString();
@@ -597,13 +612,14 @@ class ContextifyScript : public BaseObject {
                           const FunctionCallbackInfo<Value>& args,
                           TryCatch& try_catch) {
     if (!ContextifyScript::InstanceOf(env, args.This())) {
-      ThrowTypeError("Script methods can only be called on script instances.");
+      env->ThrowTypeError(
+          "Script methods can only be called on script instances.");
       return false;
     }
 
     ContextifyScript* wrapped_script =
         Unwrap<ContextifyScript>(args.This());
-    Local<Script> script = PersistentToLocal(node_isolate,
+    Local<Script> script = PersistentToLocal(env->isolate(),
                                              wrapped_script->script_);
 
     Local<Value> result;
@@ -616,7 +632,7 @@ class ContextifyScript : public BaseObject {
 
     if (try_catch.HasCaught() && try_catch.HasTerminated()) {
       V8::CancelTerminateExecution(args.GetIsolate());
-      ThrowError("Script execution timed out.");
+      env->ThrowError("Script execution timed out.");
       return false;
     }
 
index 1350a08..9e351ac 100644 (file)
@@ -21,6 +21,8 @@
 
 #include "node_counters.h"
 #include "uv.h"
+#include "env.h"
+#include "env-inl.h"
 
 #include <string.h>
 
@@ -96,8 +98,8 @@ static void counter_gc_done(GCType type, GCCallbackFlags flags) {
 }
 
 
-void InitPerfCounters(Handle<Object> target) {
-  HandleScope scope(node_isolate);
+void InitPerfCounters(Environment* env, Handle<Object> target) {
+  HandleScope scope(env->isolate());
 
   static struct {
     const char* name;
@@ -114,7 +116,7 @@ void InitPerfCounters(Handle<Object> target) {
   };
 
   for (int i = 0; i < ARRAY_SIZE(tab); i++) {
-    Local<String> key = OneByteString(node_isolate, tab[i].name);
+    Local<String> key = OneByteString(env->isolate(), tab[i].name);
     Local<Value> val = FunctionTemplate::New(tab[i].func)->GetFunction();
     target->Set(key, val);
   }
index 670f38e..8340ffc 100644 (file)
 #endif
 
 #include "v8.h"
+#include "env.h"
 
 namespace node {
 
-void InitPerfCounters(v8::Handle<v8::Object> target);
+void InitPerfCounters(Environment* env, v8::Handle<v8::Object> target);
 void TermPerfCounters(v8::Handle<v8::Object> target);
 
 }  // namespace node
index fe7e0b3..0991f54 100644 (file)
 
 #define ASSERT_IS_STRING_OR_BUFFER(val) do {                  \
     if (!Buffer::HasInstance(val) && !val->IsString()) {      \
-      return ThrowTypeError("Not a string or buffer");        \
+      return env->ThrowTypeError("Not a string or buffer");   \
     }                                                         \
   } while (0)
 
 #define ASSERT_IS_BUFFER(val) do {                            \
     if (!Buffer::HasInstance(val)) {                          \
-      return ThrowTypeError("Not a buffer");                  \
+      return env->ThrowTypeError("Not a buffer");             \
     }                                                         \
   } while (0)
 
@@ -115,7 +115,8 @@ X509_STORE* root_cert_store;
 
 // Just to generate static methods
 template class SSLWrap<TLSCallbacks>;
-template void SSLWrap<TLSCallbacks>::AddMethods(Handle<FunctionTemplate> t);
+template void SSLWrap<TLSCallbacks>::AddMethods(Environment* env,
+                                                Handle<FunctionTemplate> t);
 template void SSLWrap<TLSCallbacks>::InitNPN(SecureContext* sc,
                                              TLSCallbacks* base);
 template SSL_SESSION* SSLWrap<TLSCallbacks>::GetSessionCallback(
@@ -193,24 +194,26 @@ static int CryptoPemCallback(char *buf, int size, int rwflag, void *u) {
 }
 
 
-void ThrowCryptoErrorHelper(unsigned long err, bool is_type_error) {
-  HandleScope scope(node_isolate);
+void ThrowCryptoErrorHelper(Environment* env,
+                            unsigned long err,
+                            bool is_type_error) {
+  HandleScope scope(env->isolate());
   char errmsg[128];
   ERR_error_string_n(err, errmsg, sizeof(errmsg));
   if (is_type_error)
-    ThrowTypeError(errmsg);
+    env->ThrowTypeError(errmsg);
   else
-    ThrowError(errmsg);
+    env->ThrowError(errmsg);
 }
 
 
-void ThrowCryptoError(unsigned long err) {
-  ThrowCryptoErrorHelper(err, false);
+void ThrowCryptoError(Environment* env, unsigned long err) {
+  ThrowCryptoErrorHelper(env, err, false);
 }
 
 
-void ThrowCryptoTypeError(unsigned long err) {
-  ThrowCryptoErrorHelper(err, true);
+void ThrowCryptoTypeError(Environment* env, unsigned long err) {
+  ThrowCryptoErrorHelper(env, err, true);
 }
 
 
@@ -262,6 +265,7 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
   HandleScope scope(args.GetIsolate());
 
   SecureContext* sc = Unwrap<SecureContext>(args.This());
+  Environment* env = sc->env();
 
   OPENSSL_CONST SSL_METHOD *method = SSLv23_method();
 
@@ -272,19 +276,19 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
 #ifndef OPENSSL_NO_SSL2
       method = SSLv2_method();
 #else
-      return ThrowError("SSLv2 methods disabled");
+      return env->ThrowError("SSLv2 methods disabled");
 #endif
     } else if (strcmp(*sslmethod, "SSLv2_server_method") == 0) {
 #ifndef OPENSSL_NO_SSL2
       method = SSLv2_server_method();
 #else
-      return ThrowError("SSLv2 methods disabled");
+      return env->ThrowError("SSLv2 methods disabled");
 #endif
     } else if (strcmp(*sslmethod, "SSLv2_client_method") == 0) {
 #ifndef OPENSSL_NO_SSL2
       method = SSLv2_client_method();
 #else
-      return ThrowError("SSLv2 methods disabled");
+      return env->ThrowError("SSLv2 methods disabled");
 #endif
     } else if (strcmp(*sslmethod, "SSLv3_method") == 0) {
       method = SSLv3_method();
@@ -317,7 +321,7 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
     } else if (strcmp(*sslmethod, "TLSv1_2_client_method") == 0) {
       method = TLSv1_2_client_method();
     } else {
-      return ThrowError("Unknown method");
+      return env->ThrowError("Unknown method");
     }
   }
 
@@ -337,12 +341,12 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
 
 // Takes a string or buffer and loads it into a BIO.
 // Caller responsible for BIO_free_all-ing the returned object.
-static BIO* LoadBIO(Handle<Value> v) {
+static BIO* LoadBIO(Environment* env, Handle<Value> v) {
   BIO* bio = NodeBIO::New();
   if (!bio)
     return NULL;
 
-  HandleScope scope(node_isolate);
+  HandleScope scope(env->isolate());
 
   int r = -1;
 
@@ -366,10 +370,10 @@ static BIO* LoadBIO(Handle<Value> v) {
 
 // Takes a string or buffer and loads it into an X509
 // Caller responsible for X509_free-ing the returned object.
-static X509* LoadX509(Handle<Value> v) {
-  HandleScope scope(node_isolate);
+static X509* LoadX509(Environment* env, Handle<Value> v) {
+  HandleScope scope(env->isolate());
 
-  BIO *bio = LoadBIO(v);
+  BIO *bio = LoadBIO(env, v);
   if (!bio)
     return NULL;
 
@@ -385,19 +389,20 @@ static X509* LoadX509(Handle<Value> v) {
 
 
 void SecureContext::SetKey(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(args.GetIsolate());
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   SecureContext* sc = Unwrap<SecureContext>(args.This());
 
   unsigned int len = args.Length();
   if (len != 1 && len != 2) {
-    return ThrowTypeError("Bad parameter");
+    return env->ThrowTypeError("Bad parameter");
   }
   if (len == 2 && !args[1]->IsString()) {
-    return ThrowTypeError("Bad parameter");
+    return env->ThrowTypeError("Bad parameter");
   }
 
-  BIO *bio = LoadBIO(args[0]);
+  BIO *bio = LoadBIO(env, args[0]);
   if (!bio)
     return;
 
@@ -412,9 +417,9 @@ void SecureContext::SetKey(const FunctionCallbackInfo<Value>& args) {
     BIO_free_all(bio);
     unsigned long err = ERR_get_error();
     if (!err) {
-      return ThrowError("PEM_read_bio_PrivateKey");
+      return env->ThrowError("PEM_read_bio_PrivateKey");
     }
-    return ThrowCryptoError(err);
+    return ThrowCryptoError(env, err);
   }
 
   SSL_CTX_use_PrivateKey(sc->ctx_, key);
@@ -491,15 +496,16 @@ int SSL_CTX_use_certificate_chain(SSL_CTX *ctx, BIO *in) {
 
 
 void SecureContext::SetCert(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(args.GetIsolate());
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   SecureContext* sc = Unwrap<SecureContext>(args.This());
 
   if (args.Length() != 1) {
-    return ThrowTypeError("Bad parameter");
+    return env->ThrowTypeError("Bad parameter");
   }
 
-  BIO* bio = LoadBIO(args[0]);
+  BIO* bio = LoadBIO(env, args[0]);
   if (!bio)
     return;
 
@@ -510,21 +516,22 @@ void SecureContext::SetCert(const FunctionCallbackInfo<Value>& args) {
   if (!rv) {
     unsigned long err = ERR_get_error();
     if (!err) {
-      return ThrowError("SSL_CTX_use_certificate_chain");
+      return env->ThrowError("SSL_CTX_use_certificate_chain");
     }
-    return ThrowCryptoError(err);
+    return ThrowCryptoError(env, err);
   }
 }
 
 
 void SecureContext::AddCACert(const FunctionCallbackInfo<Value>& args) {
   bool newCAStore = false;
-  HandleScope scope(args.GetIsolate());
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   SecureContext* sc = Unwrap<SecureContext>(args.This());
 
   if (args.Length() != 1) {
-    return ThrowTypeError("Bad parameter");
+    return env->ThrowTypeError("Bad parameter");
   }
 
   if (!sc->ca_store_) {
@@ -532,7 +539,7 @@ void SecureContext::AddCACert(const FunctionCallbackInfo<Value>& args) {
     newCAStore = true;
   }
 
-  X509* x509 = LoadX509(args[0]);
+  X509* x509 = LoadX509(env, args[0]);
   if (!x509)
     return;
 
@@ -548,18 +555,19 @@ void SecureContext::AddCACert(const FunctionCallbackInfo<Value>& args) {
 
 
 void SecureContext::AddCRL(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(args.GetIsolate());
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   SecureContext* sc = Unwrap<SecureContext>(args.This());
 
   if (args.Length() != 1) {
-    return ThrowTypeError("Bad parameter");
+    return env->ThrowTypeError("Bad parameter");
   }
 
   ClearErrorOnReturn clear_error_on_return;
   (void) &clear_error_on_return;  // Silence compiler warning.
 
-  BIO *bio = LoadBIO(args[0]);
+  BIO *bio = LoadBIO(env, args[0]);
   if (!bio)
     return;
 
@@ -622,7 +630,7 @@ void SecureContext::SetCiphers(const FunctionCallbackInfo<Value>& args) {
   SecureContext* sc = Unwrap<SecureContext>(args.This());
 
   if (args.Length() != 1 || !args[0]->IsString()) {
-    return ThrowTypeError("Bad parameter");
+    return sc->env()->ThrowTypeError("Bad parameter");
   }
 
   const String::Utf8Value ciphers(args[0]);
@@ -634,21 +642,22 @@ void SecureContext::SetECDHCurve(const FunctionCallbackInfo<Value>& args) {
   HandleScope scope(args.GetIsolate());
 
   SecureContext* sc = Unwrap<SecureContext>(args.This());
+  Environment* env = sc->env();
 
   if (args.Length() != 1 || !args[0]->IsString())
-    return ThrowTypeError("First argument should be a string");
+    return env->ThrowTypeError("First argument should be a string");
 
   String::Utf8Value curve(args[0]);
 
   int nid = OBJ_sn2nid(*curve);
 
   if (nid == NID_undef)
-    return ThrowTypeError("First argument should be a valid curve name");
+    return env->ThrowTypeError("First argument should be a valid curve name");
 
   EC_KEY* ecdh = EC_KEY_new_by_curve_name(nid);
 
   if (ecdh == NULL)
-    return ThrowTypeError("First argument should be a valid curve name");
+    return env->ThrowTypeError("First argument should be a valid curve name");
 
   SSL_CTX_set_options(sc->ctx_, SSL_OP_SINGLE_ECDH_USE);
   SSL_CTX_set_tmp_ecdh(sc->ctx_, ecdh);
@@ -663,7 +672,7 @@ void SecureContext::SetOptions(const FunctionCallbackInfo<Value>& args) {
   SecureContext* sc = Unwrap<SecureContext>(args.This());
 
   if (args.Length() != 1 || !args[0]->IntegerValue()) {
-    return ThrowTypeError("Bad parameter");
+    return sc->env()->ThrowTypeError("Bad parameter");
   }
 
   SSL_CTX_set_options(sc->ctx_, args[0]->IntegerValue());
@@ -677,7 +686,7 @@ void SecureContext::SetSessionIdContext(
   SecureContext* sc = Unwrap<SecureContext>(args.This());
 
   if (args.Length() != 1 || !args[0]->IsString()) {
-    return ThrowTypeError("Bad parameter");
+    return sc->env()->ThrowTypeError("Bad parameter");
   }
 
   const String::Utf8Value sessionIdContext(args[0]);
@@ -714,7 +723,7 @@ void SecureContext::SetSessionTimeout(const FunctionCallbackInfo<Value>& args) {
   SecureContext* sc = Unwrap<SecureContext>(args.This());
 
   if (args.Length() != 1 || !args[0]->IsInt32()) {
-    return ThrowTypeError("Bad parameter");
+    return sc->env()->ThrowTypeError("Bad parameter");
   }
 
   int32_t sessionTimeout = args[0]->Int32Value();
@@ -731,7 +740,8 @@ void SecureContext::Close(const FunctionCallbackInfo<Value>& args) {
 
 // Takes .pfx or .p12 and password in string or buffer format
 void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(args.GetIsolate());
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   BIO* in = NULL;
   PKCS12* p12 = NULL;
@@ -744,12 +754,12 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
   SecureContext* sc = Unwrap<SecureContext>(args.This());
 
   if (args.Length() < 1) {
-    return ThrowTypeError("Bad parameter");
+    return env->ThrowTypeError("Bad parameter");
   }
 
-  in = LoadBIO(args[0]);
+  in = LoadBIO(env, args[0]);
   if (in == NULL) {
-    return ThrowError("Unable to load BIO");
+    return env->ThrowError("Unable to load BIO");
   }
 
   if (args.Length() >= 2) {
@@ -758,10 +768,14 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
     int passlen = Buffer::Length(args[1]);
     if (passlen < 0) {
       BIO_free_all(in);
-      return ThrowTypeError("Bad password");
+      return env->ThrowTypeError("Bad password");
     }
     pass = new char[passlen + 1];
-    int pass_written = DecodeWrite(pass, passlen, args[1], BINARY);
+    int pass_written = DecodeWrite(env->isolate(),
+                                   pass,
+                                   passlen,
+                                   args[1],
+                                   BINARY);
 
     assert(pass_written == passlen);
     pass[passlen] = '\0';
@@ -797,7 +811,7 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
   if (!ret) {
     unsigned long err = ERR_get_error();
     const char* str = ERR_reason_error_string(err);
-    return ThrowError(str);
+    return env->ThrowError(str);
   }
 }
 
@@ -812,7 +826,7 @@ void SecureContext::GetTicketKeys(const FunctionCallbackInfo<Value>& args) {
   if (SSL_CTX_get_tlsext_ticket_keys(wrap->ctx_,
                                      Buffer::Data(buff),
                                      Buffer::Length(buff)) != 1) {
-    return ThrowError("Failed to fetch tls ticket keys");
+    return wrap->env()->ThrowError("Failed to fetch tls ticket keys");
   }
 
   args.GetReturnValue().Set(buff);
@@ -823,19 +837,18 @@ void SecureContext::GetTicketKeys(const FunctionCallbackInfo<Value>& args) {
 void SecureContext::SetTicketKeys(const FunctionCallbackInfo<Value>& args) {
 #if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_CTX_get_tlsext_ticket_keys)
   HandleScope scope(args.GetIsolate());
+  SecureContext* wrap = Unwrap<SecureContext>(args.This());
 
   if (args.Length() < 1 ||
       !Buffer::HasInstance(args[0]) ||
       Buffer::Length(args[0]) != 48) {
-    return ThrowTypeError("Bad argument");
+    return wrap->env()->ThrowTypeError("Bad argument");
   }
 
-  SecureContext* wrap = Unwrap<SecureContext>(args.This());
-
   if (SSL_CTX_set_tlsext_ticket_keys(wrap->ctx_,
                                      Buffer::Data(args[0]),
                                      Buffer::Length(args[0])) != 1) {
-    return ThrowError("Failed to fetch tls ticket keys");
+    return wrap->env()->ThrowError("Failed to fetch tls ticket keys");
   }
 
   args.GetReturnValue().Set(true);
@@ -844,8 +857,8 @@ void SecureContext::SetTicketKeys(const FunctionCallbackInfo<Value>& args) {
 
 
 template <class Base>
-void SSLWrap<Base>::AddMethods(Handle<FunctionTemplate> t) {
-  HandleScope scope(node_isolate);
+void SSLWrap<Base>::AddMethods(Environment* env, Handle<FunctionTemplate> t) {
+  HandleScope scope(env->isolate());
 
   NODE_SET_PROTOTYPE_METHOD(t, "getPeerCertificate", GetPeerCertificate);
   NODE_SET_PROTOTYPE_METHOD(t, "getSession", GetSession);
@@ -954,9 +967,9 @@ void SSLWrap<Base>::OnClientHello(void* arg,
       hello.session_size());
   hello_obj->Set(env->session_id_string(), buff);
   if (hello.servername() == NULL) {
-    hello_obj->Set(env->servername_string(), String::Empty(node_isolate));
+    hello_obj->Set(env->servername_string(), String::Empty(env->isolate()));
   } else {
-    Local<String> servername = OneByteString(node_isolate,
+    Local<String> servername = OneByteString(env->isolate(),
                                              hello.servername(),
                                              hello.servername_size());
     hello_obj->Set(env->servername_string(), servername);
@@ -1120,7 +1133,8 @@ void SSLWrap<Base>::GetPeerCertificate(
 
 template <class Base>
 void SSLWrap<Base>::GetSession(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(args.GetIsolate());
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   Base* w = Unwrap<Base>(args.This());
 
@@ -1134,31 +1148,32 @@ void SSLWrap<Base>::GetSession(const FunctionCallbackInfo<Value>& args) {
   unsigned char* sbuf = new unsigned char[slen];
   unsigned char* p = sbuf;
   i2d_SSL_SESSION(sess, &p);
-  args.GetReturnValue().Set(Encode(sbuf, slen, BUFFER));
+  args.GetReturnValue().Set(Encode(env->isolate(), sbuf, slen, BUFFER));
   delete[] sbuf;
 }
 
 
 template <class Base>
 void SSLWrap<Base>::SetSession(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(args.GetIsolate());
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   Base* w = Unwrap<Base>(args.This());
 
   if (args.Length() < 1 ||
       (!args[0]->IsString() && !Buffer::HasInstance(args[0]))) {
-    return ThrowTypeError("Bad argument");
+    return env->ThrowTypeError("Bad argument");
   }
 
   ASSERT_IS_BUFFER(args[0]);
   ssize_t slen = Buffer::Length(args[0]);
 
   if (slen < 0)
-    return ThrowTypeError("Bad argument");
+    return env->ThrowTypeError("Bad argument");
 
   char* sbuf = new char[slen];
 
-  ssize_t wlen = DecodeWrite(sbuf, slen, args[0], BINARY);
+  ssize_t wlen = DecodeWrite(env->isolate(), sbuf, slen, args[0], BINARY);
   assert(wlen == slen);
 
   const unsigned char* p = reinterpret_cast<const unsigned char*>(sbuf);
@@ -1173,7 +1188,7 @@ void SSLWrap<Base>::SetSession(const FunctionCallbackInfo<Value>& args) {
   SSL_SESSION_free(sess);
 
   if (!r)
-    return ThrowError("SSL_set_session error");
+    return env->ThrowError("SSL_set_session error");
 }
 
 
@@ -1285,7 +1300,7 @@ void SSLWrap<Base>::NewSessionDone(const FunctionCallbackInfo<Value>& args) {
 template <class Base>
 void SSLWrap<Base>::SetMaxSendFragment(
     const v8::FunctionCallbackInfo<v8::Value>& args) {
-  HandleScope scope(node_isolate);
+  HandleScope scope(args.GetIsolate());
   CHECK(args.Length() >= 1 && args[0]->IsNumber());
 
   Base* w = Unwrap<Base>(args.This());
@@ -1505,7 +1520,7 @@ void SSLWrap<Base>::SetNPNProtocols(const FunctionCallbackInfo<Value>& args) {
   Base* w = Unwrap<Base>(args.This());
 
   if (args.Length() < 1 || !Buffer::HasInstance(args[0]))
-    return ThrowTypeError("Must give a Buffer as first argument");
+    return w->env()->ThrowTypeError("Must give a Buffer as first argument");
 
   w->npn_protos_.Reset(args.GetIsolate(), args[0].As<Object>());
 }
@@ -1553,10 +1568,10 @@ int Connection::HandleBIOError(BIO *bio, const char* func, int rv) {
     char ssl_error_buf[512];
     ERR_error_string_n(rv, ssl_error_buf, sizeof(ssl_error_buf));
 
-    HandleScope scope(node_isolate);
+    HandleScope scope(ssl_env()->isolate());
     Local<Value> exception =
-        Exception::Error(OneByteString(node_isolate, ssl_error_buf));
-    object()->Set(FIXED_ONE_BYTE_STRING(node_isolate, "error"), exception);
+        Exception::Error(OneByteString(ssl_env()->isolate(), ssl_error_buf));
+    object()->Set(ssl_env()->error_string(), exception);
 
     DEBUG_PRINT("[%p] BIO: %s failed: (%d) %s\n",
                 ssl_,
@@ -1597,16 +1612,18 @@ int Connection::HandleSSLError(const char* func,
     return 0;
 
   } else if (err == SSL_ERROR_ZERO_RETURN) {
+    HandleScope scope(ssl_env()->isolate());
+
     Local<Value> exception =
-        Exception::Error(FIXED_ONE_BYTE_STRING(node_isolate, "ZERO_RETURN"));
-    object()->Set(FIXED_ONE_BYTE_STRING(node_isolate, "error"), exception);
+        Exception::Error(ssl_env()->zero_return_string());
+    object()->Set(ssl_env()->error_string(), exception);
     return rv;
 
   } else if (err == SSL_ERROR_SYSCALL && ss == kIgnoreSyscall) {
     return 0;
 
   } else {
-    HandleScope scope(node_isolate);
+    HandleScope scope(ssl_env()->isolate());
     BUF_MEM* mem;
     BIO *bio;
 
@@ -1621,9 +1638,11 @@ int Connection::HandleSSLError(const char* func,
     if (bio != NULL) {
       ERR_print_errors(bio);
       BIO_get_mem_ptr(bio, &mem);
-      Local<Value> exception =
-          Exception::Error(OneByteString(node_isolate, mem->data, mem->length));
-      object()->Set(FIXED_ONE_BYTE_STRING(node_isolate, "error"), exception);
+      Local<Value> exception = Exception::Error(
+          OneByteString(ssl_env()->isolate(),
+            mem->data,
+            mem->length));
+      object()->Set(ssl_env()->error_string(), exception);
       BIO_free_all(bio);
     }
 
@@ -1636,10 +1655,10 @@ int Connection::HandleSSLError(const char* func,
 
 void Connection::ClearError() {
 #ifndef NDEBUG
-  HandleScope scope(node_isolate);
+  HandleScope scope(ssl_env()->isolate());
 
   // We should clear the error in JS-land
-  Local<String> error_key = FIXED_ONE_BYTE_STRING(node_isolate, "error");
+  Local<String> error_key = ssl_env()->error_string();
   Local<Value> error = object()->Get(error_key);
   assert(error->BooleanValue() == false);
 #endif  // NDEBUG
@@ -1647,20 +1666,18 @@ void Connection::ClearError() {
 
 
 void Connection::SetShutdownFlags() {
-  HandleScope scope(node_isolate);
+  HandleScope scope(ssl_env()->isolate());
 
   int flags = SSL_get_shutdown(ssl_);
 
   if (flags & SSL_SENT_SHUTDOWN) {
-    Local<String> sent_shutdown_key =
-        FIXED_ONE_BYTE_STRING(node_isolate, "sentShutdown");
-    object()->Set(sent_shutdown_key, True(node_isolate));
+    Local<String> sent_shutdown_key = ssl_env()->sent_shutdown_string();
+    object()->Set(sent_shutdown_key, True(ssl_env()->isolate()));
   }
 
   if (flags & SSL_RECEIVED_SHUTDOWN) {
-    Local<String> received_shutdown_key =
-        FIXED_ONE_BYTE_STRING(node_isolate, "receivedShutdown");
-    object()->Set(received_shutdown_key, True(node_isolate));
+    Local<String> received_shutdown_key = ssl_env()->received_shutdown_string();
+    object()->Set(received_shutdown_key, True(ssl_env()->isolate()));
   }
 }
 
@@ -1686,7 +1703,7 @@ void Connection::Initialize(Environment* env, Handle<Object> target) {
   NODE_SET_PROTOTYPE_METHOD(t, "start", Connection::Start);
   NODE_SET_PROTOTYPE_METHOD(t, "close", Connection::Close);
 
-  SSLWrap<Connection>::AddMethods(t);
+  SSLWrap<Connection>::AddMethods(env, t);
 
 #ifdef OPENSSL_NPN_NEGOTIATED
   NODE_SET_PROTOTYPE_METHOD(t,
@@ -1792,14 +1809,15 @@ int Connection::SelectSNIContextCallback_(SSL *s, int *ad, void* arg) {
 #endif
 
 void Connection::New(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(args.GetIsolate());
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   if (args.Length() < 1 || !args[0]->IsObject()) {
-    return ThrowError("First argument must be a crypto module Credentials");
+    env->ThrowError("First argument must be a crypto module Credentials");
+    return;
   }
 
   SecureContext* sc = Unwrap<SecureContext>(args[0]->ToObject());
-  Environment* env = sc->env();
 
   bool is_server = args[1]->BooleanValue();
 
@@ -1889,13 +1907,14 @@ void Connection::EncIn(const FunctionCallbackInfo<Value>& args) {
   HandleScope scope(args.GetIsolate());
 
   Connection* conn = Unwrap<Connection>(args.This());
+  Environment* env = conn->env();
 
   if (args.Length() < 3) {
-    return ThrowTypeError("Takes 3 parameters");
+    return env->ThrowTypeError("Takes 3 parameters");
   }
 
   if (!Buffer::HasInstance(args[0])) {
-    return ThrowTypeError("Second argument should be a buffer");
+    return env->ThrowTypeError("Second argument should be a buffer");
   }
 
   char* buffer_data = Buffer::Data(args[0]);
@@ -1905,7 +1924,7 @@ void Connection::EncIn(const FunctionCallbackInfo<Value>& args) {
   size_t len = args[2]->Int32Value();
 
   if (!Buffer::IsWithinBounds(off, len, buffer_length))
-    return ThrowError("off + len > buffer.length");
+    return env->ThrowError("off + len > buffer.length");
 
   int bytes_written;
   char* data = buffer_data + off;
@@ -1939,13 +1958,14 @@ void Connection::ClearOut(const FunctionCallbackInfo<Value>& args) {
   HandleScope scope(args.GetIsolate());
 
   Connection* conn = Unwrap<Connection>(args.This());
+  Environment* env = conn->env();
 
   if (args.Length() < 3) {
-    return ThrowTypeError("Takes 3 parameters");
+    return env->ThrowTypeError("Takes 3 parameters");
   }
 
   if (!Buffer::HasInstance(args[0])) {
-    return ThrowTypeError("Second argument should be a buffer");
+    return env->ThrowTypeError("Second argument should be a buffer");
   }
 
   char* buffer_data = Buffer::Data(args[0]);
@@ -1955,7 +1975,7 @@ void Connection::ClearOut(const FunctionCallbackInfo<Value>& args) {
   size_t len = args[2]->Int32Value();
 
   if (!Buffer::IsWithinBounds(off, len, buffer_length))
-    return ThrowError("off + len > buffer.length");
+    return env->ThrowError("off + len > buffer.length");
 
   if (!SSL_is_init_finished(conn->ssl_)) {
     int rv;
@@ -2010,13 +2030,14 @@ void Connection::EncOut(const FunctionCallbackInfo<Value>& args) {
   HandleScope scope(args.GetIsolate());
 
   Connection* conn = Unwrap<Connection>(args.This());
+  Environment* env = conn->env();
 
   if (args.Length() < 3) {
-    return ThrowTypeError("Takes 3 parameters");
+    return env->ThrowTypeError("Takes 3 parameters");
   }
 
   if (!Buffer::HasInstance(args[0])) {
-    return ThrowTypeError("Second argument should be a buffer");
+    return env->ThrowTypeError("Second argument should be a buffer");
   }
 
   char* buffer_data = Buffer::Data(args[0]);
@@ -2026,7 +2047,7 @@ void Connection::EncOut(const FunctionCallbackInfo<Value>& args) {
   size_t len = args[2]->Int32Value();
 
   if (!Buffer::IsWithinBounds(off, len, buffer_length))
-    return ThrowError("off + len > buffer.length");
+    return env->ThrowError("off + len > buffer.length");
 
   int bytes_read = BIO_read(conn->bio_write_, buffer_data + off, len);
 
@@ -2041,13 +2062,14 @@ void Connection::ClearIn(const FunctionCallbackInfo<Value>& args) {
   HandleScope scope(args.GetIsolate());
 
   Connection* conn = Unwrap<Connection>(args.This());
+  Environment* env = conn->env();
 
   if (args.Length() < 3) {
-    return ThrowTypeError("Takes 3 parameters");
+    return env->ThrowTypeError("Takes 3 parameters");
   }
 
   if (!Buffer::HasInstance(args[0])) {
-    return ThrowTypeError("Second argument should be a buffer");
+    return env->ThrowTypeError("Second argument should be a buffer");
   }
 
   char* buffer_data = Buffer::Data(args[0]);
@@ -2057,7 +2079,7 @@ void Connection::ClearIn(const FunctionCallbackInfo<Value>& args) {
   size_t len = args[2]->Int32Value();
 
   if (!Buffer::IsWithinBounds(off, len, buffer_length))
-    return ThrowError("off + len > buffer.length");
+    return env->ThrowError("off + len > buffer.length");
 
   if (!SSL_is_init_finished(conn->ssl_)) {
     int rv;
@@ -2147,9 +2169,10 @@ void Connection::SetSNICallback(const FunctionCallbackInfo<Value>& args) {
   HandleScope scope(args.GetIsolate());
 
   Connection* conn = Unwrap<Connection>(args.This());
+  Environment* env = conn->env();
 
   if (args.Length() < 1 || !args[0]->IsFunction()) {
-    return ThrowError("Must give a Function as first argument");
+    return env->ThrowError("Must give a Function as first argument");
   }
 
   Local<Object> obj = Object::New();
@@ -2189,12 +2212,12 @@ void CipherBase::New(const FunctionCallbackInfo<Value>& args) {
 void CipherBase::Init(const char* cipher_type,
                       const char* key_buf,
                       int key_buf_len) {
-  HandleScope scope(node_isolate);
+  HandleScope scope(env()->isolate());
 
   assert(cipher_ == NULL);
   cipher_ = EVP_get_cipherbyname(cipher_type);
   if (cipher_ == NULL) {
-    return ThrowError("Unknown cipher");
+    return env()->ThrowError("Unknown cipher");
   }
 
   unsigned char key[EVP_MAX_KEY_LENGTH];
@@ -2213,7 +2236,7 @@ void CipherBase::Init(const char* cipher_type,
   EVP_CipherInit_ex(&ctx_, cipher_, NULL, NULL, NULL, kind_ == kCipher);
   if (!EVP_CIPHER_CTX_set_key_length(&ctx_, key_len)) {
     EVP_CIPHER_CTX_cleanup(&ctx_);
-    return ThrowError("Invalid key length");
+    return env()->ThrowError("Invalid key length");
   }
 
   EVP_CipherInit_ex(&ctx_,
@@ -2233,7 +2256,7 @@ void CipherBase::Init(const FunctionCallbackInfo<Value>& args) {
 
   if (args.Length() < 2 ||
       !(args[0]->IsString() && Buffer::HasInstance(args[1]))) {
-    return ThrowError("Must give cipher-type, key");
+    return cipher->env()->ThrowError("Must give cipher-type, key");
   }
 
   const String::Utf8Value cipher_type(args[0]);
@@ -2248,24 +2271,24 @@ void CipherBase::InitIv(const char* cipher_type,
                         int key_len,
                         const char* iv,
                         int iv_len) {
-  HandleScope scope(node_isolate);
+  HandleScope scope(env()->isolate());
 
   cipher_ = EVP_get_cipherbyname(cipher_type);
   if (cipher_ == NULL) {
-    return ThrowError("Unknown cipher");
+    return env()->ThrowError("Unknown cipher");
   }
 
   /* OpenSSL versions up to 0.9.8l failed to return the correct
      iv_length (0) for ECB ciphers */
   if (EVP_CIPHER_iv_length(cipher_) != iv_len &&
       !(EVP_CIPHER_mode(cipher_) == EVP_CIPH_ECB_MODE && iv_len == 0)) {
-    return ThrowError("Invalid IV length");
+    return env()->ThrowError("Invalid IV length");
   }
   EVP_CIPHER_CTX_init(&ctx_);
   EVP_CipherInit_ex(&ctx_, cipher_, NULL, NULL, NULL, kind_ == kCipher);
   if (!EVP_CIPHER_CTX_set_key_length(&ctx_, key_len)) {
     EVP_CIPHER_CTX_cleanup(&ctx_);
-    return ThrowError("Invalid key length");
+    return env()->ThrowError("Invalid key length");
   }
 
   EVP_CipherInit_ex(&ctx_,
@@ -2282,9 +2305,10 @@ void CipherBase::InitIv(const FunctionCallbackInfo<Value>& args) {
   HandleScope scope(args.GetIsolate());
 
   CipherBase* cipher = Unwrap<CipherBase>(args.This());
+  Environment* env = cipher->env();
 
   if (args.Length() < 3 || !args[0]->IsString()) {
-    return ThrowError("Must give cipher-type, key, and iv as argument");
+    return env->ThrowError("Must give cipher-type, key, and iv as argument");
   }
 
   ASSERT_IS_BUFFER(args[1]);
@@ -2331,7 +2355,7 @@ void CipherBase::GetAuthTag(const FunctionCallbackInfo<Value>& args) {
     Local<Object> buf = Buffer::Use(env, out, out_len);
     args.GetReturnValue().Set(buf);
   } else {
-    ThrowError("Attempting to get auth tag in unsupported state");
+    env->ThrowError("Attempting to get auth tag in unsupported state");
   }
 }
 
@@ -2349,15 +2373,16 @@ bool CipherBase::SetAuthTag(const char* data, unsigned int len) {
 
 void CipherBase::SetAuthTag(const FunctionCallbackInfo<Value>& args) {
   HandleScope handle_scope(args.GetIsolate());
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
 
   Local<Object> buf = args[0].As<Object>();
   if (!buf->IsObject() || !Buffer::HasInstance(buf))
-    return ThrowTypeError("Argument must be a Buffer");
+    return env->ThrowTypeError("Argument must be a Buffer");
 
   CipherBase* cipher = Unwrap<CipherBase>(args.This());
 
   if (!cipher->SetAuthTag(Buffer::Data(buf), Buffer::Length(buf)))
-    ThrowError("Attempting to set auth tag in unsupported state");
+    env->ThrowError("Attempting to set auth tag in unsupported state");
 }
 
 
@@ -2403,12 +2428,16 @@ void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
   // Only copy the data if we have to, because it's a string
   if (args[0]->IsString()) {
     Local<String> string = args[0].As<String>();
-    enum encoding encoding = ParseEncoding(args[1], BINARY);
-    if (!StringBytes::IsValidString(string, encoding))
-      return ThrowTypeError("Bad input string");
-    size_t buflen = StringBytes::StorageSize(string, encoding);
+    enum encoding encoding = ParseEncoding(env->isolate(), args[1], BINARY);
+    if (!StringBytes::IsValidString(env->isolate(), string, encoding))
+      return env->ThrowTypeError("Bad input string");
+    size_t buflen = StringBytes::StorageSize(env->isolate(), string, encoding);
     char* buf = new char[buflen];
-    size_t written = StringBytes::Write(buf, buflen, string, encoding);
+    size_t written = StringBytes::Write(env->isolate(),
+                                        buf,
+                                        buflen,
+                                        string,
+                                        encoding);
     r = cipher->Update(buf, written, &out, &out_len);
     delete[] buf;
   } else {
@@ -2419,7 +2448,7 @@ void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
 
   if (!r) {
     delete[] out;
-    return ThrowCryptoTypeError(ERR_get_error());
+    return ThrowCryptoTypeError(env, ERR_get_error());
   }
 
   Local<Object> buf = Buffer::New(env, reinterpret_cast<char*>(out), out_len);
@@ -2489,7 +2518,7 @@ void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
     out_value = NULL;
     out_len = 0;
     if (!r)
-      return ThrowCryptoTypeError(ERR_get_error());
+      return ThrowCryptoTypeError(env, ERR_get_error());
   }
 
   args.GetReturnValue().Set(
@@ -2518,12 +2547,12 @@ void Hmac::New(const FunctionCallbackInfo<Value>& args) {
 
 
 void Hmac::HmacInit(const char* hash_type, const char* key, int key_len) {
-  HandleScope scope(node_isolate);
+  HandleScope scope(env()->isolate());
 
   assert(md_ == NULL);
   md_ = EVP_get_digestbyname(hash_type);
   if (md_ == NULL) {
-    return ThrowError("Unknown message digest");
+    return env()->ThrowError("Unknown message digest");
   }
   HMAC_CTX_init(&ctx_);
   if (key_len == 0) {
@@ -2539,9 +2568,10 @@ void Hmac::HmacInit(const FunctionCallbackInfo<Value>& args) {
   HandleScope scope(args.GetIsolate());
 
   Hmac* hmac = Unwrap<Hmac>(args.This());
+  Environment* env = hmac->env();
 
   if (args.Length() < 2 || !args[0]->IsString()) {
-    return ThrowError("Must give hashtype string, key as arguments");
+    return env->ThrowError("Must give hashtype string, key as arguments");
   }
 
   ASSERT_IS_BUFFER(args[1]);
@@ -2562,7 +2592,8 @@ bool Hmac::HmacUpdate(const char* data, int len) {
 
 
 void Hmac::HmacUpdate(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(args.GetIsolate());
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   Hmac* hmac = Unwrap<Hmac>(args.This());
 
@@ -2572,12 +2603,16 @@ void Hmac::HmacUpdate(const FunctionCallbackInfo<Value>& args) {
   bool r;
   if (args[0]->IsString()) {
     Local<String> string = args[0].As<String>();
-    enum encoding encoding = ParseEncoding(args[1], BINARY);
-    if (!StringBytes::IsValidString(string, encoding))
-      return ThrowTypeError("Bad input string");
-    size_t buflen = StringBytes::StorageSize(string, encoding);
+    enum encoding encoding = ParseEncoding(env->isolate(), args[1], BINARY);
+    if (!StringBytes::IsValidString(env->isolate(), string, encoding))
+      return env->ThrowTypeError("Bad input string");
+    size_t buflen = StringBytes::StorageSize(env->isolate(), string, encoding);
     char* buf = new char[buflen];
-    size_t written = StringBytes::Write(buf, buflen, string, encoding);
+    size_t written = StringBytes::Write(env->isolate(),
+                                        buf,
+                                        buflen,
+                                        string,
+                                        encoding);
     r = hmac->HmacUpdate(buf, written);
     delete[] buf;
   } else {
@@ -2587,7 +2622,7 @@ void Hmac::HmacUpdate(const FunctionCallbackInfo<Value>& args) {
   }
 
   if (!r) {
-    return ThrowTypeError("HmacUpdate fail");
+    return env->ThrowTypeError("HmacUpdate fail");
   }
 }
 
@@ -2604,13 +2639,14 @@ bool Hmac::HmacDigest(unsigned char** md_value, unsigned int* md_len) {
 
 
 void Hmac::HmacDigest(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(args.GetIsolate());
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   Hmac* hmac = Unwrap<Hmac>(args.This());
 
   enum encoding encoding = BUFFER;
   if (args.Length() >= 1) {
-    encoding = ParseEncoding(args[0]->ToString(), BUFFER);
+    encoding = ParseEncoding(env->isolate(), args[0]->ToString(), BUFFER);
   }
 
   unsigned char* md_value = NULL;
@@ -2622,8 +2658,10 @@ void Hmac::HmacDigest(const FunctionCallbackInfo<Value>& args) {
     md_len = 0;
   }
 
-  Local<Value> rc = StringBytes::Encode(
-        reinterpret_cast<const char*>(md_value), md_len, encoding);
+  Local<Value> rc = StringBytes::Encode(env->isolate(),
+                                        reinterpret_cast<const char*>(md_value),
+                                        md_len,
+                                        encoding);
   delete[] md_value;
   args.GetReturnValue().Set(rc);
 }
@@ -2642,18 +2680,18 @@ void Hash::Initialize(Environment* env, v8::Handle<v8::Object> target) {
 
 
 void Hash::New(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(args.GetIsolate());
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   if (args.Length() == 0 || !args[0]->IsString()) {
-    return ThrowError("Must give hashtype string as argument");
+    return env->ThrowError("Must give hashtype string as argument");
   }
 
   const String::Utf8Value hash_type(args[0]);
 
-  Environment* env = Environment::GetCurrent(args.GetIsolate());
   Hash* hash = new Hash(env, args.This());
   if (!hash->HashInit(*hash_type)) {
-    return ThrowError("Digest method not supported");
+    return env->ThrowError("Digest method not supported");
   }
 }
 
@@ -2679,7 +2717,8 @@ bool Hash::HashUpdate(const char* data, int len) {
 
 
 void Hash::HashUpdate(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(args.GetIsolate());
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   Hash* hash = Unwrap<Hash>(args.This());
 
@@ -2689,12 +2728,16 @@ void Hash::HashUpdate(const FunctionCallbackInfo<Value>& args) {
   bool r;
   if (args[0]->IsString()) {
     Local<String> string = args[0].As<String>();
-    enum encoding encoding = ParseEncoding(args[1], BINARY);
-    if (!StringBytes::IsValidString(string, encoding))
-      return ThrowTypeError("Bad input string");
-    size_t buflen = StringBytes::StorageSize(string, encoding);
+    enum encoding encoding = ParseEncoding(env->isolate(), args[1], BINARY);
+    if (!StringBytes::IsValidString(env->isolate(), string, encoding))
+      return env->ThrowTypeError("Bad input string");
+    size_t buflen = StringBytes::StorageSize(env->isolate(), string, encoding);
     char* buf = new char[buflen];
-    size_t written = StringBytes::Write(buf, buflen, string, encoding);
+    size_t written = StringBytes::Write(env->isolate(),
+                                        buf,
+                                        buflen,
+                                        string,
+                                        encoding);
     r = hash->HashUpdate(buf, written);
     delete[] buf;
   } else {
@@ -2704,23 +2747,24 @@ void Hash::HashUpdate(const FunctionCallbackInfo<Value>& args) {
   }
 
   if (!r) {
-    return ThrowTypeError("HashUpdate fail");
+    return env->ThrowTypeError("HashUpdate fail");
   }
 }
 
 
 void Hash::HashDigest(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(args.GetIsolate());
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   Hash* hash = Unwrap<Hash>(args.This());
 
   if (!hash->initialised_) {
-    return ThrowError("Not initialized");
+    return env->ThrowError("Not initialized");
   }
 
   enum encoding encoding = BUFFER;
   if (args.Length() >= 1) {
-    encoding = ParseEncoding(args[0]->ToString(), BUFFER);
+    encoding = ParseEncoding(env->isolate(), args[0]->ToString(), BUFFER);
   }
 
   unsigned char md_value[EVP_MAX_MD_SIZE];
@@ -2730,21 +2774,23 @@ void Hash::HashDigest(const FunctionCallbackInfo<Value>& args) {
   EVP_MD_CTX_cleanup(&hash->mdctx_);
   hash->initialised_ = false;
 
-  Local<Value> rc = StringBytes::Encode(
-      reinterpret_cast<const char*>(md_value), md_len, encoding);
+  Local<Value> rc = StringBytes::Encode(env->isolate(),
+                                        reinterpret_cast<const char*>(md_value),
+                                        md_len,
+                                        encoding);
   args.GetReturnValue().Set(rc);
 }
 
 
 void SignBase::CheckThrow(SignBase::Error error) {
-  HandleScope scope(node_isolate);
+  HandleScope scope(env()->isolate());
 
   switch (error) {
     case kSignUnknownDigest:
-      return ThrowError("Unknown message digest");
+      return env()->ThrowError("Unknown message digest");
 
     case kSignNotInitialised:
-      return ThrowError("Not initialised");
+      return env()->ThrowError("Not initialised");
 
     case kSignInit:
     case kSignUpdate:
@@ -2753,16 +2799,16 @@ void SignBase::CheckThrow(SignBase::Error error) {
       {
         unsigned long err = ERR_get_error();
         if (err)
-          return ThrowCryptoError(err);
+          return ThrowCryptoError(env(), err);
         switch (error) {
           case kSignInit:
-            return ThrowError("EVP_SignInit_ex failed");
+            return env()->ThrowError("EVP_SignInit_ex failed");
           case kSignUpdate:
-            return ThrowError("EVP_SignUpdate failed");
+            return env()->ThrowError("EVP_SignUpdate failed");
           case kSignPrivateKey:
-            return ThrowError("PEM_read_bio_PrivateKey failed");
+            return env()->ThrowError("PEM_read_bio_PrivateKey failed");
           case kSignPublicKey:
-            return ThrowError("PEM_read_bio_PUBKEY failed");
+            return env()->ThrowError("PEM_read_bio_PUBKEY failed");
           default:
             abort();
         }
@@ -2817,11 +2863,11 @@ void Sign::SignInit(const FunctionCallbackInfo<Value>& args) {
   Sign* sign = Unwrap<Sign>(args.This());
 
   if (args.Length() == 0 || !args[0]->IsString()) {
-    return ThrowError("Must give signtype string as argument");
+    return sign->env()->ThrowError("Must give signtype string as argument");
   }
 
   const String::Utf8Value sign_type(args[0]);
-  CheckThrow(sign->SignInit(*sign_type));
+  sign->CheckThrow(sign->SignInit(*sign_type));
 }
 
 
@@ -2835,7 +2881,8 @@ SignBase::Error Sign::SignUpdate(const char* data, int len) {
 
 
 void Sign::SignUpdate(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(args.GetIsolate());
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   Sign* sign = Unwrap<Sign>(args.This());
 
@@ -2845,12 +2892,16 @@ void Sign::SignUpdate(const FunctionCallbackInfo<Value>& args) {
   Error err;
   if (args[0]->IsString()) {
     Local<String> string = args[0].As<String>();
-    enum encoding encoding = ParseEncoding(args[1], BINARY);
-    if (!StringBytes::IsValidString(string, encoding))
-      return ThrowTypeError("Bad input string");
-    size_t buflen = StringBytes::StorageSize(string, encoding);
+    enum encoding encoding = ParseEncoding(env->isolate(), args[1], BINARY);
+    if (!StringBytes::IsValidString(env->isolate(), string, encoding))
+      return env->ThrowTypeError("Bad input string");
+    size_t buflen = StringBytes::StorageSize(env->isolate(), string, encoding);
     char* buf = new char[buflen];
-    size_t written = StringBytes::Write(buf, buflen, string, encoding);
+    size_t written = StringBytes::Write(env->isolate(),
+                                        buf,
+                                        buflen,
+                                        string,
+                                        encoding);
     err = sign->SignUpdate(buf, written);
     delete[] buf;
   } else {
@@ -2859,7 +2910,7 @@ void Sign::SignUpdate(const FunctionCallbackInfo<Value>& args) {
     err = sign->SignUpdate(buf, buflen);
   }
 
-  CheckThrow(err);
+  sign->CheckThrow(err);
 }
 
 
@@ -2910,7 +2961,8 @@ SignBase::Error Sign::SignFinal(const char* key_pem,
 
 
 void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(args.GetIsolate());
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   Sign* sign = Unwrap<Sign>(args.This());
 
@@ -2920,7 +2972,7 @@ void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
   unsigned int len = args.Length();
   enum encoding encoding = BUFFER;
   if (len >= 2 && args[1]->IsString()) {
-    encoding = ParseEncoding(args[1]->ToString(), BUFFER);
+    encoding = ParseEncoding(env->isolate(), args[1]->ToString(), BUFFER);
   }
 
   String::Utf8Value passphrase(args[2]);
@@ -2942,11 +2994,13 @@ void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
     delete[] md_value;
     md_value = NULL;
     md_len = 0;
-    return CheckThrow(err);
+    return sign->CheckThrow(err);
   }
 
-  Local<Value> rc = StringBytes::Encode(
-      reinterpret_cast<const char*>(md_value), md_len, encoding);
+  Local<Value> rc = StringBytes::Encode(env->isolate(),
+                                        reinterpret_cast<const char*>(md_value),
+                                        md_len,
+                                        encoding);
   delete[] md_value;
   args.GetReturnValue().Set(rc);
 }
@@ -2994,11 +3048,11 @@ void Verify::VerifyInit(const FunctionCallbackInfo<Value>& args) {
   Verify* verify = Unwrap<Verify>(args.This());
 
   if (args.Length() == 0 || !args[0]->IsString()) {
-    return ThrowError("Must give verifytype string as argument");
+    return verify->env()->ThrowError("Must give verifytype string as argument");
   }
 
   const String::Utf8Value verify_type(args[0]);
-  CheckThrow(verify->VerifyInit(*verify_type));
+  verify->CheckThrow(verify->VerifyInit(*verify_type));
 }
 
 
@@ -3014,7 +3068,8 @@ SignBase::Error Verify::VerifyUpdate(const char* data, int len) {
 
 
 void Verify::VerifyUpdate(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(args.GetIsolate());
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   Verify* verify = Unwrap<Verify>(args.This());
 
@@ -3024,12 +3079,16 @@ void Verify::VerifyUpdate(const FunctionCallbackInfo<Value>& args) {
   Error err;
   if (args[0]->IsString()) {
     Local<String> string = args[0].As<String>();
-    enum encoding encoding = ParseEncoding(args[1], BINARY);
-    if (!StringBytes::IsValidString(string, encoding))
-      return ThrowTypeError("Bad input string");
-    size_t buflen = StringBytes::StorageSize(string, encoding);
+    enum encoding encoding = ParseEncoding(env->isolate(), args[1], BINARY);
+    if (!StringBytes::IsValidString(env->isolate(), string, encoding))
+      return env->ThrowTypeError("Bad input string");
+    size_t buflen = StringBytes::StorageSize(env->isolate(), string, encoding);
     char* buf = new char[buflen];
-    size_t written = StringBytes::Write(buf, buflen, string, encoding);
+    size_t written = StringBytes::Write(env->isolate(),
+                                        buf,
+                                        buflen,
+                                        string,
+                                        encoding);
     err = verify->VerifyUpdate(buf, written);
     delete[] buf;
   } else {
@@ -3038,7 +3097,7 @@ void Verify::VerifyUpdate(const FunctionCallbackInfo<Value>& args) {
     err = verify->VerifyUpdate(buf, buflen);
   }
 
-  CheckThrow(err);
+  verify->CheckThrow(err);
 }
 
 
@@ -3120,7 +3179,8 @@ SignBase::Error Verify::VerifyFinal(const char* key_pem,
 
 
 void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(args.GetIsolate());
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   Verify* verify = Unwrap<Verify>(args.This());
 
@@ -3132,16 +3192,20 @@ void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) {
   // BINARY works for both buffers and binary strings.
   enum encoding encoding = BINARY;
   if (args.Length() >= 3) {
-    encoding = ParseEncoding(args[2]->ToString(), BINARY);
+    encoding = ParseEncoding(env->isolate(), args[2]->ToString(), BINARY);
   }
 
-  ssize_t hlen = StringBytes::Size(args[1], encoding);
+  ssize_t hlen = StringBytes::Size(env->isolate(), args[1], encoding);
 
   // only copy if we need to, because it's a string.
   char* hbuf;
   if (args[1]->IsString()) {
     hbuf = new char[hlen];
-    ssize_t hwritten = StringBytes::Write(hbuf, hlen, args[1], encoding);
+    ssize_t hwritten = StringBytes::Write(env->isolate(),
+                                          hbuf,
+                                          hlen,
+                                          args[1],
+                                          encoding);
     assert(hwritten == hlen);
   } else {
     hbuf = Buffer::Data(args[1]);
@@ -3152,7 +3216,7 @@ void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) {
   if (args[1]->IsString())
     delete[] hbuf;
   if (err != kSignOk)
-    return CheckThrow(err);
+    return verify->CheckThrow(err);
   args.GetReturnValue().Set(verify_result);
 }
 
@@ -3251,7 +3315,7 @@ void DiffieHellman::DiffieHellmanGroup(
   DiffieHellman* diffieHellman = new DiffieHellman(env, args.This());
 
   if (args.Length() != 1 || !args[0]->IsString()) {
-    return ThrowError("No group name given");
+    return env->ThrowError("No group name given");
   }
 
   bool initialized = false;
@@ -3268,11 +3332,11 @@ void DiffieHellman::DiffieHellmanGroup(
                                       it->gen,
                                       it->gen_size);
     if (!initialized)
-      ThrowError("Initialization failed");
+      env->ThrowError("Initialization failed");
     return;
   }
 
-  ThrowError("Unknown group");
+  env->ThrowError("Unknown group");
 }
 
 
@@ -3305,22 +3369,23 @@ void DiffieHellman::New(const FunctionCallbackInfo<Value>& args) {
   }
 
   if (!initialized) {
-    return ThrowError("Initialization failed");
+    return env->ThrowError("Initialization failed");
   }
 }
 
 
 void DiffieHellman::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(args.GetIsolate());
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.This());
 
   if (!diffieHellman->initialised_) {
-    return ThrowError("Not initialized");
+    return env->ThrowError("Not initialized");
   }
 
   if (!DH_generate_key(diffieHellman->dh)) {
-    return ThrowError("Key generation failed");
+    return env->ThrowError("Key generation failed");
   }
 
   int dataSize = BN_num_bytes(diffieHellman->dh->pub_key);
@@ -3328,58 +3393,61 @@ void DiffieHellman::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
   BN_bn2bin(diffieHellman->dh->pub_key,
             reinterpret_cast<unsigned char*>(data));
 
-  args.GetReturnValue().Set(Encode(data, dataSize, BUFFER));
+  args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
   delete[] data;
 }
 
 
 void DiffieHellman::GetPrime(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(args.GetIsolate());
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.This());
 
   if (!diffieHellman->initialised_) {
-    return ThrowError("Not initialized");
+    return env->ThrowError("Not initialized");
   }
 
   int dataSize = BN_num_bytes(diffieHellman->dh->p);
   char* data = new char[dataSize];
   BN_bn2bin(diffieHellman->dh->p, reinterpret_cast<unsigned char*>(data));
 
-  args.GetReturnValue().Set(Encode(data, dataSize, BUFFER));
+  args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
   delete[] data;
 }
 
 
 void DiffieHellman::GetGenerator(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(args.GetIsolate());
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.This());
 
   if (!diffieHellman->initialised_) {
-    return ThrowError("Not initialized");
+    return env->ThrowError("Not initialized");
   }
 
   int dataSize = BN_num_bytes(diffieHellman->dh->g);
   char* data = new char[dataSize];
   BN_bn2bin(diffieHellman->dh->g, reinterpret_cast<unsigned char*>(data));
 
-  args.GetReturnValue().Set(Encode(data, dataSize, BUFFER));
+  args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
   delete[] data;
 }
 
 
 void DiffieHellman::GetPublicKey(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(args.GetIsolate());
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.This());
 
   if (!diffieHellman->initialised_) {
-    return ThrowError("Not initialized");
+    return env->ThrowError("Not initialized");
   }
 
   if (diffieHellman->dh->pub_key == NULL) {
-    return ThrowError("No public key - did you forget to generate one?");
+    return env->ThrowError("No public key - did you forget to generate one?");
   }
 
   int dataSize = BN_num_bytes(diffieHellman->dh->pub_key);
@@ -3387,22 +3455,23 @@ void DiffieHellman::GetPublicKey(const FunctionCallbackInfo<Value>& args) {
   BN_bn2bin(diffieHellman->dh->pub_key,
             reinterpret_cast<unsigned char*>(data));
 
-  args.GetReturnValue().Set(Encode(data, dataSize, BUFFER));
+  args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
   delete[] data;
 }
 
 
 void DiffieHellman::GetPrivateKey(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(args.GetIsolate());
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.This());
 
   if (!diffieHellman->initialised_) {
-    return ThrowError("Not initialized");
+    return env->ThrowError("Not initialized");
   }
 
   if (diffieHellman->dh->priv_key == NULL) {
-    return ThrowError("No private key - did you forget to generate one?");
+    return env->ThrowError("No private key - did you forget to generate one?");
   }
 
   int dataSize = BN_num_bytes(diffieHellman->dh->priv_key);
@@ -3410,18 +3479,19 @@ void DiffieHellman::GetPrivateKey(const FunctionCallbackInfo<Value>& args) {
   BN_bn2bin(diffieHellman->dh->priv_key,
             reinterpret_cast<unsigned char*>(data));
 
-  args.GetReturnValue().Set(Encode(data, dataSize, BUFFER));
+  args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
   delete[] data;
 }
 
 
 void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(args.GetIsolate());
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.This());
 
   if (!diffieHellman->initialised_) {
-    return ThrowError("Not initialized");
+    return env->ThrowError("Not initialized");
   }
 
   ClearErrorOnReturn clear_error_on_return;
@@ -3429,7 +3499,7 @@ void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
   BIGNUM* key = NULL;
 
   if (args.Length() == 0) {
-    return ThrowError("First argument must be other party's public key");
+    return env->ThrowError("First argument must be other party's public key");
   } else {
     ASSERT_IS_BUFFER(args[0]);
     key = BN_bin2bn(
@@ -3454,17 +3524,17 @@ void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
     delete[] data;
 
     if (!checked) {
-      return ThrowError("Invalid key");
+      return env->ThrowError("Invalid key");
     } else if (checkResult) {
       if (checkResult & DH_CHECK_PUBKEY_TOO_SMALL) {
-        return ThrowError("Supplied key is too small");
+        return env->ThrowError("Supplied key is too small");
       } else if (checkResult & DH_CHECK_PUBKEY_TOO_LARGE) {
-        return ThrowError("Supplied key is too large");
+        return env->ThrowError("Supplied key is too large");
       } else {
-        return ThrowError("Invalid key");
+        return env->ThrowError("Invalid key");
       }
     } else {
-      return ThrowError("Invalid key");
+      return env->ThrowError("Invalid key");
     }
   }
 
@@ -3481,7 +3551,7 @@ void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
     memset(data, 0, dataSize - size);
   }
 
-  args.GetReturnValue().Set(Encode(data, dataSize, BUFFER));
+  args.GetReturnValue().Set(Encode(env->isolate(), data, dataSize, BUFFER));
   delete[] data;
 }
 
@@ -3490,13 +3560,14 @@ void DiffieHellman::SetPublicKey(const FunctionCallbackInfo<Value>& args) {
   HandleScope scope(args.GetIsolate());
 
   DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.This());
+  Environment* env = diffieHellman->env();
 
   if (!diffieHellman->initialised_) {
-    return ThrowError("Not initialized");
+    return env->ThrowError("Not initialized");
   }
 
   if (args.Length() == 0) {
-    return ThrowError("First argument must be public key");
+    return env->ThrowError("First argument must be public key");
   } else {
     ASSERT_IS_BUFFER(args[0]);
     diffieHellman->dh->pub_key = BN_bin2bn(
@@ -3510,13 +3581,14 @@ void DiffieHellman::SetPrivateKey(const FunctionCallbackInfo<Value>& args) {
   HandleScope scope(args.GetIsolate());
 
   DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.This());
+  Environment* env = diffieHellman->env();
 
   if (!diffieHellman->initialised_) {
-    return ThrowError("Not initialized");
+    return env->ThrowError("Not initialized");
   }
 
   if (args.Length() == 0) {
-    return ThrowError("First argument must be private key");
+    return env->ThrowError("First argument must be private key");
   } else {
     ASSERT_IS_BUFFER(args[0]);
     diffieHellman->dh->priv_key = BN_bin2bn(
@@ -3534,7 +3606,7 @@ void DiffieHellman::VerifyErrorGetter(Local<String> property,
   DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.This());
 
   if (!diffieHellman->initialised_)
-    return ThrowError("Not initialized");
+    return diffieHellman->env()->ThrowError("Not initialized");
 
   args.GetReturnValue().Set(diffieHellman->verifyError_);
 }
@@ -3670,13 +3742,12 @@ void EIO_PBKDF2(uv_work_t* work_req) {
 
 void EIO_PBKDF2After(PBKDF2Request* req, Local<Value> argv[2]) {
   if (req->error()) {
-    argv[0] = Undefined(node_isolate);
-    argv[1] = Encode(req->key(), req->keylen(), BUFFER);
+    argv[0] = Undefined(req->env()->isolate());
+    argv[1] = Encode(req->env()->isolate(), req->key(), req->keylen(), BUFFER);
     memset(req->key(), 0, req->keylen());
   } else {
-    argv[0] = Exception::Error(
-        FIXED_ONE_BYTE_STRING(node_isolate, "PBKDF2 error"));
-    argv[1] = Undefined(node_isolate);
+    argv[0] = Exception::Error(req->env()->pbkdf2_error_string());
+    argv[1] = Undefined(req->env()->isolate());
   }
 }
 
@@ -3696,8 +3767,8 @@ void EIO_PBKDF2After(uv_work_t* work_req, int status) {
 
 
 void PBKDF2(const FunctionCallbackInfo<Value>& args) {
-  HandleScope handle_scope(args.GetIsolate());
   Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   const EVP_MD* digest = NULL;
   const char* type_error = NULL;
@@ -3728,7 +3799,7 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
   if (pass == NULL) {
     FatalError("node::PBKDF2()", "Out of Memory");
   }
-  pass_written = DecodeWrite(pass, passlen, args[0], BINARY);
+  pass_written = DecodeWrite(env->isolate(), pass, passlen, args[0], BINARY);
   assert(pass_written == passlen);
 
   ASSERT_IS_BUFFER(args[1]);
@@ -3742,7 +3813,7 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
   if (salt == NULL) {
     FatalError("node::PBKDF2()", "Out of Memory");
   }
-  salt_written = DecodeWrite(salt, saltlen, args[1], BINARY);
+  salt_written = DecodeWrite(env->isolate(), salt, saltlen, args[1], BINARY);
   assert(salt_written == saltlen);
 
   if (!args[2]->IsNumber()) {
@@ -3814,7 +3885,7 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
  err:
   free(salt);
   free(pass);
-  return ThrowTypeError(type_error);
+  return env->ThrowTypeError(type_error);
 }
 
 
@@ -3908,14 +3979,14 @@ void RandomBytesCheck(RandomBytesRequest* req, Local<Value> argv[2]) {
     if (req->error() != static_cast<unsigned long>(-1))
       ERR_error_string_n(req->error(), errmsg, sizeof errmsg);
 
-    argv[0] = Exception::Error(OneByteString(node_isolate, errmsg));
-    argv[1] = Null(node_isolate);
+    argv[0] = Exception::Error(OneByteString(req->env()->isolate(), errmsg));
+    argv[1] = Null(req->env()->isolate());
     req->release();
   } else {
     char* data = NULL;
     size_t size;
     req->return_memory(&data, &size);
-    argv[0] = Null(node_isolate);
+    argv[0] = Null(req->env()->isolate());
     argv[1] = Buffer::Use(data, size);
   }
 }
@@ -3944,12 +4015,12 @@ void RandomBytes(const FunctionCallbackInfo<Value>& args) {
   // maybe allow a buffer to write to? cuts down on object creation
   // when generating random data in a loop
   if (!args[0]->IsUint32()) {
-    return ThrowTypeError("Argument #1 must be number > 0");
+    return env->ThrowTypeError("Argument #1 must be number > 0");
   }
 
   const uint32_t size = args[0]->Uint32Value();
   if (size > Buffer::kMaxLength) {
-    return ThrowTypeError("size > Buffer::kMaxLength");
+    return env->ThrowTypeError("size > Buffer::kMaxLength");
   }
 
   Local<Object> obj = Object::New();
@@ -3980,17 +4051,18 @@ void RandomBytes(const FunctionCallbackInfo<Value>& args) {
 
 
 void GetSSLCiphers(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(args.GetIsolate());
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   SSL_CTX* ctx = SSL_CTX_new(TLSv1_server_method());
   if (ctx == NULL) {
-    return ThrowError("SSL_CTX_new() failed.");
+    return env->ThrowError("SSL_CTX_new() failed.");
   }
 
   SSL* ssl = SSL_new(ctx);
   if (ssl == NULL) {
     SSL_CTX_free(ctx);
-    return ThrowError("SSL_new() failed.");
+    return env->ThrowError("SSL_new() failed.");
   }
 
   Local<Array> arr = Array::New();
@@ -4008,34 +4080,50 @@ void GetSSLCiphers(const FunctionCallbackInfo<Value>& args) {
 }
 
 
+class CipherPushContext {
+ public:
+  explicit CipherPushContext(Environment* env) : arr(Array::New()), env_(env) {
+  }
+
+  inline Environment* env() const { return env_; }
+
+  Local<Array> arr;
+
+ private:
+  Environment* env_;
+};
+
+
 template <class TypeName>
 static void array_push_back(const TypeName* md,
                             const char* from,
                             const char* to,
                             void* arg) {
-  Local<Array>& arr = *static_cast<Local<Array>*>(arg);
-  arr->Set(arr->Length(), OneByteString(node_isolate, from));
+  CipherPushContext* ctx = static_cast<CipherPushContext*>(arg);
+  ctx->arr->Set(ctx->arr->Length(), OneByteString(ctx->env()->isolate(), from));
 }
 
 
 void GetCiphers(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(args.GetIsolate());
-  Local<Array> arr = Array::New();
-  EVP_CIPHER_do_all_sorted(array_push_back<EVP_CIPHER>, &arr);
-  args.GetReturnValue().Set(arr);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
+  CipherPushContext ctx(env);
+  EVP_CIPHER_do_all_sorted(array_push_back<EVP_CIPHER>, &ctx);
+  args.GetReturnValue().Set(ctx.arr);
 }
 
 
 void GetHashes(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(args.GetIsolate());
-  Local<Array> arr = Array::New();
-  EVP_MD_do_all_sorted(array_push_back<EVP_MD>, &arr);
-  args.GetReturnValue().Set(arr);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
+  CipherPushContext ctx(env);
+  EVP_MD_do_all_sorted(array_push_back<EVP_MD>, &ctx);
+  args.GetReturnValue().Set(ctx.arr);
 }
 
 
-void Certificate::Initialize(Handle<Object> target) {
-  HandleScope scope(node_isolate);
+void Certificate::Initialize(Environment* env, Handle<Object> target) {
+  HandleScope scope(env->isolate());
 
   Local<FunctionTemplate> t = FunctionTemplate::New(New);
 
@@ -4045,7 +4133,7 @@ void Certificate::Initialize(Handle<Object> target) {
   NODE_SET_PROTOTYPE_METHOD(t, "exportPublicKey", ExportPublicKey);
   NODE_SET_PROTOTYPE_METHOD(t, "exportChallenge", ExportChallenge);
 
-  target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "Certificate"),
+  target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Certificate"),
               t->GetFunction());
 }
 
@@ -4087,10 +4175,11 @@ void Certificate::VerifySpkac(const FunctionCallbackInfo<Value>& args) {
   HandleScope scope(args.GetIsolate());
 
   Certificate* certificate = Unwrap<Certificate>(args.This());
+  Environment* env = certificate->env();
   bool i = false;
 
   if (args.Length() < 1)
-    return ThrowTypeError("Missing argument");
+    return env->ThrowTypeError("Missing argument");
 
   ASSERT_IS_BUFFER(args[0]);
 
@@ -4149,12 +4238,13 @@ const char* Certificate::ExportPublicKey(const char* data, int len) {
 
 
 void Certificate::ExportPublicKey(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(args.GetIsolate());
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   Certificate* certificate = Unwrap<Certificate>(args.This());
 
   if (args.Length() < 1)
-    return ThrowTypeError("Missing argument");
+    return env->ThrowTypeError("Missing argument");
 
   ASSERT_IS_BUFFER(args[0]);
 
@@ -4169,7 +4259,7 @@ void Certificate::ExportPublicKey(const FunctionCallbackInfo<Value>& args) {
   if (pkey == NULL)
     return args.GetReturnValue().SetEmptyString();
 
-  Local<Value> out = Encode(pkey, strlen(pkey), BUFFER);
+  Local<Value> out = Encode(env->isolate(), pkey, strlen(pkey), BUFFER);
 
   delete[] pkey;
 
@@ -4192,12 +4282,13 @@ const char* Certificate::ExportChallenge(const char* data, int len) {
 
 
 void Certificate::ExportChallenge(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(args.GetIsolate());
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   Certificate* crt = Unwrap<Certificate>(args.This());
 
   if (args.Length() < 1)
-    return ThrowTypeError("Missing argument");
+    return env->ThrowTypeError("Missing argument");
 
   ASSERT_IS_BUFFER(args[0]);
 
@@ -4212,7 +4303,7 @@ void Certificate::ExportChallenge(const FunctionCallbackInfo<Value>& args) {
   if (cert == NULL)
     return args.GetReturnValue().SetEmptyString();
 
-  Local<Value> outString = Encode(cert, strlen(cert), BUFFER);
+  Local<Value> outString = Encode(env->isolate(), cert, strlen(cert), BUFFER);
 
   delete[] cert;
 
@@ -4249,6 +4340,7 @@ void InitCryptoOnce() {
 
 #ifndef OPENSSL_NO_ENGINE
 void SetEngine(const FunctionCallbackInfo<Value>& args) {
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
   CHECK(args.Length() >= 2 && args[0]->IsString());
   unsigned int flags = args[1]->Uint32Value();
 
@@ -4275,16 +4367,16 @@ void SetEngine(const FunctionCallbackInfo<Value>& args) {
     if (err == 0) {
       char tmp[1024];
       snprintf(tmp, sizeof(tmp), "Engine \"%s\" was not found", *engine_id);
-      return ThrowError(tmp);
+      return env->ThrowError(tmp);
     } else {
-      return ThrowCryptoError(err);
+      return ThrowCryptoError(env, err);
     }
   }
 
   int r = ENGINE_set_default(engine, flags);
   ENGINE_free(engine);
   if (r == 0)
-    return ThrowCryptoError(ERR_get_error());
+    return ThrowCryptoError(env, ERR_get_error());
 }
 #endif  // !OPENSSL_NO_ENGINE
 
@@ -4306,7 +4398,7 @@ void InitCrypto(Handle<Object> target,
   Hash::Initialize(env, target);
   Sign::Initialize(env, target);
   Verify::Initialize(env, target);
-  Certificate::Initialize(target);
+  Certificate::Initialize(env, target);
 
 #ifndef OPENSSL_NO_ENGINE
   NODE_SET_METHOD(target, "setEngine", SetEngine);
index 2e75fd5..3fed0d5 100644 (file)
@@ -167,7 +167,7 @@ class SSLWrap {
 
  protected:
   static void InitNPN(SecureContext* sc, Base* base);
-  static void AddMethods(v8::Handle<v8::FunctionTemplate> t);
+  static void AddMethods(Environment* env, v8::Handle<v8::FunctionTemplate> t);
 
   static SSL_SESSION* GetSessionCallback(SSL* s,
                                          unsigned char* key,
@@ -477,7 +477,7 @@ class SignBase : public BaseObject {
   }
 
  protected:
-  static void CheckThrow(Error error);
+  void CheckThrow(Error error);
 
   EVP_MD_CTX mdctx_; /* coverity[member_decl] */
   const EVP_MD* md_; /* coverity[member_decl] */
@@ -579,7 +579,7 @@ class DiffieHellman : public BaseObject {
 
 class Certificate : public AsyncWrap {
  public:
-  static void Initialize(v8::Handle<v8::Object> target);
+  static void Initialize(Environment* env, v8::Handle<v8::Object> target);
 
   v8::Handle<v8::Value> CertificateInit(const char* sign_type);
   bool VerifySpkac(const char* data, unsigned int len);
index df1546c..0b8db1e 100644 (file)
@@ -50,6 +50,9 @@
 #define NODE_GC_DONE(arg0, arg1)
 #endif
 
+#include "env.h"
+#include "env-inl.h"
+
 namespace node {
 
 using v8::FunctionCallbackInfo;
@@ -67,35 +70,38 @@ using v8::Value;
 
 #define SLURP_STRING(obj, member, valp) \
   if (!(obj)->IsObject()) { \
-    return ThrowError( \
+    return env->ThrowError( \
         "expected object for " #obj " to contain string member " #member); \
   } \
-  String::Utf8Value _##member(obj->Get(OneByteString(node_isolate, #member))); \
+  String::Utf8Value _##member(obj->Get(OneByteString(env->isolate(), \
+                                                     #member))); \
   if ((*(const char **)valp = *_##member) == NULL) \
     *(const char **)valp = "<unknown>";
 
 #define SLURP_INT(obj, member, valp) \
   if (!(obj)->IsObject()) { \
-    return ThrowError( \
+    return env->ThrowError( \
       "expected object for " #obj " to contain integer member " #member); \
   } \
-  *valp = obj->Get(OneByteString(node_isolate, #member))->ToInteger()->Value();
+  *valp = obj->Get(OneByteString(env->isolate(), #member)) \
+      ->ToInteger()->Value();
 
 #define SLURP_OBJECT(obj, member, valp) \
   if (!(obj)->IsObject()) { \
-    return ThrowError( \
+    return env->ThrowError( \
       "expected object for " #obj " to contain object member " #member); \
   } \
-  *valp = Local<Object>::Cast(obj->Get(OneByteString(node_isolate, #member)));
+  *valp = Local<Object>::Cast(obj->Get(OneByteString(env->isolate(), #member)));
 
 #define SLURP_CONNECTION(arg, conn) \
   if (!(arg)->IsObject()) { \
-    return ThrowError( \
+    return env->ThrowError( \
       "expected argument " #arg " to be a connection object"); \
   } \
   node_dtrace_connection_t conn; \
   Local<Object> _##conn = Local<Object>::Cast(arg); \
-  Local<Value> _handle = (_##conn)->Get(FIXED_ONE_BYTE_STRING(node_isolate, "_handle")); \
+  Local<Value> _handle = \
+      (_##conn)->Get(FIXED_ONE_BYTE_STRING(env->isolate(), "_handle")); \
   if (_handle->IsObject()) { \
     SLURP_INT(_handle.As<Object>(), fd, &conn.fd); \
   } else { \
@@ -107,7 +113,7 @@ using v8::Value;
 
 #define SLURP_CONNECTION_HTTP_CLIENT(arg, conn) \
   if (!(arg)->IsObject()) { \
-    return ThrowError( \
+    return env->ThrowError( \
       "expected argument " #arg " to be a connection object"); \
   } \
   node_dtrace_connection_t conn; \
@@ -119,11 +125,11 @@ using v8::Value;
 
 #define SLURP_CONNECTION_HTTP_CLIENT_RESPONSE(arg0, arg1, conn) \
   if (!(arg0)->IsObject()) { \
-    return ThrowError( \
+    return env->ThrowError( \
       "expected argument " #arg0 " to be a connection object"); \
   } \
   if (!(arg1)->IsObject()) { \
-    return ThrowError( \
+    return env->ThrowError( \
       "expected argument " #arg1 " to be a connection object"); \
   } \
   node_dtrace_connection_t conn; \
@@ -138,7 +144,8 @@ using v8::Value;
 void DTRACE_NET_SERVER_CONNECTION(const FunctionCallbackInfo<Value>& args) {
   if (!NODE_NET_SERVER_CONNECTION_ENABLED())
     return;
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
   SLURP_CONNECTION(args[0], conn);
   NODE_NET_SERVER_CONNECTION(&conn, conn.remote, conn.port, conn.fd);
 }
@@ -147,7 +154,8 @@ void DTRACE_NET_SERVER_CONNECTION(const FunctionCallbackInfo<Value>& args) {
 void DTRACE_NET_STREAM_END(const FunctionCallbackInfo<Value>& args) {
   if (!NODE_NET_STREAM_END_ENABLED())
     return;
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
   SLURP_CONNECTION(args[0], conn);
   NODE_NET_STREAM_END(&conn, conn.remote, conn.port, conn.fd);
 }
@@ -156,11 +164,12 @@ void DTRACE_NET_STREAM_END(const FunctionCallbackInfo<Value>& args) {
 void DTRACE_NET_SOCKET_READ(const FunctionCallbackInfo<Value>& args) {
   if (!NODE_NET_SOCKET_READ_ENABLED())
     return;
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
   SLURP_CONNECTION(args[0], conn);
 
   if (!args[1]->IsNumber()) {
-    return ThrowError("expected argument 1 to be number of bytes");
+    return env->ThrowError("expected argument 1 to be number of bytes");
   }
 
   int nbytes = args[1]->Int32Value();
@@ -171,11 +180,12 @@ void DTRACE_NET_SOCKET_READ(const FunctionCallbackInfo<Value>& args) {
 void DTRACE_NET_SOCKET_WRITE(const FunctionCallbackInfo<Value>& args) {
   if (!NODE_NET_SOCKET_WRITE_ENABLED())
     return;
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
   SLURP_CONNECTION(args[0], conn);
 
   if (!args[1]->IsNumber()) {
-    return ThrowError("expected argument 1 to be number of bytes");
+    return env->ThrowError("expected argument 1 to be number of bytes");
   }
 
   int nbytes = args[1]->Int32Value();
@@ -189,7 +199,8 @@ void DTRACE_HTTP_SERVER_REQUEST(const FunctionCallbackInfo<Value>& args) {
   if (!NODE_HTTP_SERVER_REQUEST_ENABLED())
     return;
 
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
   Local<Object> arg0 = Local<Object>::Cast(args[0]);
   Local<Object> headers;
 
@@ -200,11 +211,11 @@ void DTRACE_HTTP_SERVER_REQUEST(const FunctionCallbackInfo<Value>& args) {
   SLURP_OBJECT(arg0, headers, &headers);
 
   if (!(headers)->IsObject()) {
-    return ThrowError(
+    return env->ThrowError(
       "expected object for request to contain string member headers");
   }
 
-  Local<Value> strfwdfor = headers->Get(FIXED_ONE_BYTE_STRING(node_isolate, "x-forwarded-for"));
+  Local<Value> strfwdfor = headers->Get(env->x_forwarded_string());
   String::Utf8Value fwdfor(strfwdfor);
 
   if (!strfwdfor->IsString() || (req.forwardedFor = *fwdfor) == NULL)
@@ -219,7 +230,8 @@ void DTRACE_HTTP_SERVER_REQUEST(const FunctionCallbackInfo<Value>& args) {
 void DTRACE_HTTP_SERVER_RESPONSE(const FunctionCallbackInfo<Value>& args) {
   if (!NODE_HTTP_SERVER_RESPONSE_ENABLED())
     return;
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
   SLURP_CONNECTION(args[0], conn);
   NODE_HTTP_SERVER_RESPONSE(&conn, conn.remote, conn.port, conn.fd);
 }
@@ -232,7 +244,8 @@ void DTRACE_HTTP_CLIENT_REQUEST(const FunctionCallbackInfo<Value>& args) {
   if (!NODE_HTTP_CLIENT_REQUEST_ENABLED())
     return;
 
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   /*
    * For the method and URL, we're going to dig them out of the header.  This
@@ -267,7 +280,8 @@ void DTRACE_HTTP_CLIENT_REQUEST(const FunctionCallbackInfo<Value>& args) {
 void DTRACE_HTTP_CLIENT_RESPONSE(const FunctionCallbackInfo<Value>& args) {
   if (!NODE_HTTP_CLIENT_RESPONSE_ENABLED())
     return;
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
   SLURP_CONNECTION_HTTP_CLIENT_RESPONSE(args[0], args[1], conn);
   NODE_HTTP_CLIENT_RESPONSE(&conn, conn.remote, conn.port, conn.fd);
 }
@@ -289,8 +303,8 @@ static int dtrace_gc_done(GCType type, GCCallbackFlags flags) {
 }
 
 
-void InitDTrace(Handle<Object> target) {
-  HandleScope scope(node_isolate);
+void InitDTrace(Environment* env, Handle<Object> target) {
+  HandleScope scope(env->isolate());
 
   static struct {
     const char *name;
@@ -309,7 +323,7 @@ void InitDTrace(Handle<Object> target) {
   };
 
   for (unsigned int i = 0; i < ARRAY_SIZE(tab); i++) {
-    Local<String> key = OneByteString(node_isolate, tab[i].name);
+    Local<String> key = OneByteString(env->isolate(), tab[i].name);
     Local<Value> val = FunctionTemplate::New(tab[i].func)->GetFunction();
     target->Set(key, val);
   }
index 5b6df8f..1169961 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "node.h"
 #include "v8.h"
+#include "env.h"
 
 extern "C" {
 /*
@@ -74,7 +75,7 @@ typedef struct {
 
 namespace node {
 
-void InitDTrace(v8::Handle<v8::Object> target);
+void InitDTrace(Environment* env, v8::Handle<v8::Object> target);
 
 }  // namespace node
 
index c1328e5..9476a13 100644 (file)
@@ -60,7 +60,7 @@ using v8::Value;
 
 #define MIN(a, b) ((a) < (b) ? (a) : (b))
 
-#define TYPE_ERROR(msg) ThrowTypeError(msg)
+#define TYPE_ERROR(msg) env->ThrowTypeError(msg)
 
 #define THROW_BAD_ARGS TYPE_ERROR("Bad argument")
 
@@ -98,11 +98,11 @@ class FSReqWrap: public ReqWrap<uv_fs_t> {
 
 #define ASSERT_OFFSET(a) \
   if (!(a)->IsUndefined() && !(a)->IsNull() && !IsInt64((a)->NumberValue())) { \
-    return ThrowTypeError("Not an integer"); \
+    return env->ThrowTypeError("Not an integer"); \
   }
 #define ASSERT_TRUNCATE_LENGTH(a) \
   if (!(a)->IsUndefined() && !(a)->IsNull() && !IsInt64((a)->NumberValue())) { \
-    return ThrowTypeError("Not an integer"); \
+    return env->ThrowTypeError("Not an integer"); \
   }
 #define GET_OFFSET(a) ((a)->IsNumber() ? (a)->IntegerValue() : -1)
 #define GET_TRUNCATE_LENGTH(a) ((a)->IntegerValue())
@@ -148,7 +148,7 @@ static void After(uv_fs_t *req) {
     }
   } else {
     // error value is empty or null for non-error.
-    argv[0] = Null(node_isolate);
+    argv[0] = Null(env->isolate());
 
     // All have at least two args now.
     argc = 2;
@@ -179,11 +179,11 @@ static void After(uv_fs_t *req) {
         break;
 
       case UV_FS_OPEN:
-        argv[1] = Integer::New(req->result, node_isolate);
+        argv[1] = Integer::New(req->result, env->isolate());
         break;
 
       case UV_FS_WRITE:
-        argv[1] = Integer::New(req->result, node_isolate);
+        argv[1] = Integer::New(req->result, env->isolate());
         break;
 
       case UV_FS_STAT:
@@ -194,13 +194,13 @@ static void After(uv_fs_t *req) {
         break;
 
       case UV_FS_READLINK:
-        argv[1] = String::NewFromUtf8(node_isolate,
+        argv[1] = String::NewFromUtf8(env->isolate(),
                                       static_cast<const char*>(req->ptr));
         break;
 
       case UV_FS_READ:
         // Buffer interface
-        argv[1] = Integer::New(req->result, node_isolate);
+        argv[1] = Integer::New(req->result, env->isolate());
         break;
 
       case UV_FS_READDIR:
@@ -211,7 +211,7 @@ static void After(uv_fs_t *req) {
           Local<Array> names = Array::New(nnames);
 
           for (int i = 0; i < nnames; i++) {
-            Local<String> name = String::NewFromUtf8(node_isolate, namebuf);
+            Local<String> name = String::NewFromUtf8(env->isolate(), namebuf);
             names->Set(i, name);
 #ifndef NDEBUG
             namebuf += strlen(namebuf);
@@ -281,7 +281,6 @@ struct fs_req_wrap {
 
 #define SYNC_DEST_CALL(func, path, dest, ...)                                 \
   fs_req_wrap req_wrap;                                                       \
-  Environment* env = Environment::GetCurrent(args.GetIsolate());              \
   int err = uv_fs_ ## func(env->event_loop(),                                 \
                          &req_wrap.req,                                       \
                          __VA_ARGS__,                                         \
@@ -291,9 +290,9 @@ struct fs_req_wrap {
         (err == UV_EEXIST ||                                                  \
          err == UV_ENOTEMPTY ||                                               \
          err == UV_EPERM)) {                                                  \
-      return ThrowUVException(err, #func, "", dest);                          \
+      return env->ThrowUVException(err, #func, "", dest);                     \
     } else {                                                                  \
-      return ThrowUVException(err, #func, "", path);                          \
+      return env->ThrowUVException(err, #func, "", path);                     \
     }                                                                         \
   }                                                                           \
 
@@ -306,7 +305,8 @@ struct fs_req_wrap {
 
 
 static void Close(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   if (args.Length() < 1 || !args[0]->IsInt32()) {
     return THROW_BAD_ARGS;
@@ -346,7 +346,7 @@ Local<Object> BuildStatsObject(Environment* env, const uv_stat_t* s) {
   // and make sure that we bail out when V8 returns an empty handle.
 #define X(name)                                                               \
   {                                                                           \
-    Local<Value> val = Integer::New(s->st_##name, node_isolate);              \
+    Local<Value> val = Integer::New(s->st_##name, env->isolate());            \
     if (val.IsEmpty())                                                        \
       return Local<Object>();                                                 \
     stats->Set(env->name ## _string(), val);                                  \
@@ -395,7 +395,8 @@ Local<Object> BuildStatsObject(Environment* env, const uv_stat_t* s) {
 }
 
 static void Stat(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   if (args.Length() < 1)
     return TYPE_ERROR("path required");
@@ -414,7 +415,8 @@ static void Stat(const FunctionCallbackInfo<Value>& args) {
 }
 
 static void LStat(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   if (args.Length() < 1)
     return TYPE_ERROR("path required");
@@ -433,7 +435,8 @@ static void LStat(const FunctionCallbackInfo<Value>& args) {
 }
 
 static void FStat(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   if (args.Length() < 1 || !args[0]->IsInt32()) {
     return THROW_BAD_ARGS;
@@ -451,7 +454,8 @@ static void FStat(const FunctionCallbackInfo<Value>& args) {
 }
 
 static void Symlink(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   int len = args.Length();
   if (len < 1)
@@ -474,7 +478,7 @@ static void Symlink(const FunctionCallbackInfo<Value>& args) {
     } else if (strcmp(*mode, "junction") == 0) {
       flags |= UV_FS_SYMLINK_JUNCTION;
     } else if (strcmp(*mode, "file") != 0) {
-      return ThrowError("Unknown symlink type");
+      return env->ThrowError("Unknown symlink type");
     }
   }
 
@@ -486,7 +490,8 @@ static void Symlink(const FunctionCallbackInfo<Value>& args) {
 }
 
 static void Link(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   int len = args.Length();
   if (len < 1)
@@ -509,7 +514,8 @@ static void Link(const FunctionCallbackInfo<Value>& args) {
 }
 
 static void ReadLink(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   if (args.Length() < 1)
     return TYPE_ERROR("path required");
@@ -523,13 +529,14 @@ static void ReadLink(const FunctionCallbackInfo<Value>& args) {
   } else {
     SYNC_CALL(readlink, *path, *path)
     const char* link_path = static_cast<const char*>(SYNC_REQ.ptr);
-    Local<String> rc = String::NewFromUtf8(node_isolate, link_path);
+    Local<String> rc = String::NewFromUtf8(env->isolate(), link_path);
     args.GetReturnValue().Set(rc);
   }
 }
 
 static void Rename(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   int len = args.Length();
   if (len < 1)
@@ -552,7 +559,8 @@ static void Rename(const FunctionCallbackInfo<Value>& args) {
 }
 
 static void FTruncate(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   if (args.Length() < 2 || !args[0]->IsInt32()) {
     return THROW_BAD_ARGS;
@@ -571,7 +579,8 @@ static void FTruncate(const FunctionCallbackInfo<Value>& args) {
 }
 
 static void Fdatasync(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   if (args.Length() < 1 || !args[0]->IsInt32()) {
     return THROW_BAD_ARGS;
@@ -587,7 +596,8 @@ static void Fdatasync(const FunctionCallbackInfo<Value>& args) {
 }
 
 static void Fsync(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   if (args.Length() < 1 || !args[0]->IsInt32()) {
     return THROW_BAD_ARGS;
@@ -603,7 +613,8 @@ static void Fsync(const FunctionCallbackInfo<Value>& args) {
 }
 
 static void Unlink(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   if (args.Length() < 1)
     return TYPE_ERROR("path required");
@@ -620,7 +631,8 @@ static void Unlink(const FunctionCallbackInfo<Value>& args) {
 }
 
 static void RMDir(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   if (args.Length() < 1)
     return TYPE_ERROR("path required");
@@ -637,7 +649,8 @@ static void RMDir(const FunctionCallbackInfo<Value>& args) {
 }
 
 static void MKDir(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   if (args.Length() < 2 || !args[0]->IsString() || !args[1]->IsInt32()) {
     return THROW_BAD_ARGS;
@@ -654,7 +667,8 @@ static void MKDir(const FunctionCallbackInfo<Value>& args) {
 }
 
 static void ReadDir(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   if (args.Length() < 1)
     return TYPE_ERROR("path required");
@@ -674,7 +688,7 @@ static void ReadDir(const FunctionCallbackInfo<Value>& args) {
     Local<Array> names = Array::New(nnames);
 
     for (uint32_t i = 0; i < nnames; ++i) {
-      names->Set(i, String::NewFromUtf8(node_isolate, namebuf));
+      names->Set(i, String::NewFromUtf8(env->isolate(), namebuf));
 #ifndef NDEBUG
       namebuf += strlen(namebuf);
       assert(*namebuf == '\0');
@@ -689,7 +703,8 @@ static void ReadDir(const FunctionCallbackInfo<Value>& args) {
 }
 
 static void Open(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   int len = args.Length();
   if (len < 1)
@@ -728,7 +743,8 @@ static void Open(const FunctionCallbackInfo<Value>& args) {
 // 4 position  if integer, position to write at in the file.
 //             if null, write from the current position
 static void WriteBuffer(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   assert(args[0]->IsInt32());
   assert(Buffer::HasInstance(args[1]));
@@ -743,13 +759,13 @@ static void WriteBuffer(const FunctionCallbackInfo<Value>& args) {
   Local<Value> cb = args[5];
 
   if (off > buffer_length)
-    return ThrowRangeError("offset out of bounds");
+    return env->ThrowRangeError("offset out of bounds");
   if (len > buffer_length)
-    return ThrowRangeError("length out of bounds");
+    return env->ThrowRangeError("length out of bounds");
   if (off + len < off)
-    return ThrowRangeError("off + len overflow");
+    return env->ThrowRangeError("off + len overflow");
   if (!Buffer::IsWithinBounds(off, len, buffer_length))
-    return ThrowRangeError("off + len > buffer.length");
+    return env->ThrowRangeError("off + len > buffer.length");
 
   buf += off;
 
@@ -776,7 +792,7 @@ static void WriteString(const FunctionCallbackInfo<Value>& args) {
   Environment* env = Environment::GetCurrent(args.GetIsolate());
 
   if (!args[0]->IsInt32())
-    return ThrowTypeError("First argument must be file descriptor");
+    return env->ThrowTypeError("First argument must be file descriptor");
 
   Local<Value> cb;
   Local<Value> string = args[1];
@@ -787,15 +803,16 @@ static void WriteString(const FunctionCallbackInfo<Value>& args) {
   bool must_free = false;
 
   // will assign buf and len if string was external
-  if (!StringBytes::GetExternalParts(string,
+  if (!StringBytes::GetExternalParts(env->isolate(),
+                                     string,
                                      const_cast<const char**>(&buf),
                                      &len)) {
     enum encoding enc = ParseEncoding(args[3], UTF8);
-    len = StringBytes::StorageSize(string, enc);
+    len = StringBytes::StorageSize(env->isolate(), string, enc);
     buf = new char[len];
     // StorageSize may return too large a char, so correct the actual length
     // by the write size
-    len = StringBytes::Write(buf, len, args[1], enc);
+    len = StringBytes::Write(env->isolate(), buf, len, args[1], enc);
     must_free = true;
   }
   pos = GET_OFFSET(args[2]);
@@ -842,7 +859,8 @@ static void WriteString(const FunctionCallbackInfo<Value>& args) {
  *
  */
 static void Read(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   if (args.Length() < 2 || !args[0]->IsInt32()) {
     return THROW_BAD_ARGS;
@@ -858,7 +876,7 @@ static void Read(const FunctionCallbackInfo<Value>& args) {
   char * buf = NULL;
 
   if (!Buffer::HasInstance(args[1])) {
-    return ThrowError("Second argument needs to be a buffer");
+    return env->ThrowError("Second argument needs to be a buffer");
   }
 
   Local<Object> buffer_obj = args[1]->ToObject();
@@ -867,12 +885,12 @@ static void Read(const FunctionCallbackInfo<Value>& args) {
 
   size_t off = args[2]->Int32Value();
   if (off >= buffer_length) {
-    return ThrowError("Offset is out of bounds");
+    return env->ThrowError("Offset is out of bounds");
   }
 
   len = args[3]->Int32Value();
   if (!Buffer::IsWithinBounds(off, len, buffer_length))
-    return ThrowRangeError("Length extends beyond buffer");
+    return env->ThrowRangeError("Length extends beyond buffer");
 
   pos = GET_OFFSET(args[4]);
 
@@ -893,7 +911,8 @@ static void Read(const FunctionCallbackInfo<Value>& args) {
  * Wrapper for chmod(1) / EIO_CHMOD
  */
 static void Chmod(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   if (args.Length() < 2 || !args[0]->IsString() || !args[1]->IsInt32()) {
     return THROW_BAD_ARGS;
@@ -913,7 +932,8 @@ static void Chmod(const FunctionCallbackInfo<Value>& args) {
  * Wrapper for fchmod(1) / EIO_FCHMOD
  */
 static void FChmod(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   if (args.Length() < 2 || !args[0]->IsInt32() || !args[1]->IsInt32()) {
     return THROW_BAD_ARGS;
@@ -933,7 +953,8 @@ static void FChmod(const FunctionCallbackInfo<Value>& args) {
  * Wrapper for chown(1) / EIO_CHOWN
  */
 static void Chown(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   int len = args.Length();
   if (len < 1)
@@ -965,7 +986,8 @@ static void Chown(const FunctionCallbackInfo<Value>& args) {
  * Wrapper for fchown(1) / EIO_FCHOWN
  */
 static void FChown(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   int len = args.Length();
   if (len < 1)
@@ -994,7 +1016,8 @@ static void FChown(const FunctionCallbackInfo<Value>& args) {
 
 
 static void UTimes(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   int len = args.Length();
   if (len < 1)
@@ -1022,7 +1045,8 @@ static void UTimes(const FunctionCallbackInfo<Value>& args) {
 }
 
 static void FUTimes(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   int len = args.Length();
   if (len < 1)
@@ -1058,7 +1082,7 @@ void InitFs(Handle<Object> target,
 
   // Initialize the stats object
   Local<Function> constructor = FunctionTemplate::New()->GetFunction();
-  target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "Stats"), constructor);
+  target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Stats"), constructor);
   env->set_stats_constructor_function(constructor);
 
   NODE_SET_METHOD(target, "close", Close);
@@ -1092,7 +1116,7 @@ void InitFs(Handle<Object> target,
   NODE_SET_METHOD(target, "utimes", UTimes);
   NODE_SET_METHOD(target, "futimes", FUTimes);
 
-  StatWatcher::Initialize(target);
+  StatWatcher::Initialize(env, target);
 }
 
 }  // end namespace node
index 1d92f65..7424f4b 100644 (file)
@@ -149,11 +149,11 @@ struct StringPtr {
   }
 
 
-  Local<String> ToString() const {
+  Local<String> ToString(Environment* env) const {
     if (str_)
-      return OneByteString(node_isolate, str_, size_);
+      return OneByteString(env->isolate(), str_, size_);
     else
-      return String::Empty(node_isolate);
+      return String::Empty(env->isolate());
   }
 
 
@@ -252,7 +252,7 @@ class Parser : public BaseObject {
       // Fast case, pass headers and URL to JS land.
       message_info->Set(env()->headers_string(), CreateHeaders());
       if (parser_.type == HTTP_REQUEST)
-        message_info->Set(env()->url_string(), url_.ToString());
+        message_info->Set(env()->url_string(), url_.ToString(env()));
     }
     num_fields_ = num_values_ = 0;
 
@@ -265,24 +265,24 @@ class Parser : public BaseObject {
     // STATUS
     if (parser_.type == HTTP_RESPONSE) {
       message_info->Set(env()->status_code_string(),
-                        Integer::New(parser_.status_code, node_isolate));
+                        Integer::New(parser_.status_code, env()->isolate()));
       message_info->Set(env()->status_message_string(),
-                        status_message_.ToString());
+                        status_message_.ToString(env()));
     }
 
     // VERSION
     message_info->Set(env()->version_major_string(),
-                      Integer::New(parser_.http_major, node_isolate));
+                      Integer::New(parser_.http_major, env()->isolate()));
     message_info->Set(env()->version_minor_string(),
-                      Integer::New(parser_.http_minor, node_isolate));
+                      Integer::New(parser_.http_minor, env()->isolate()));
 
     message_info->Set(env()->should_keep_alive_string(),
-                      http_should_keep_alive(&parser_) ? True(node_isolate)
-                                                       : False(node_isolate));
+                      http_should_keep_alive(&parser_) ?
+                          True(env()->isolate()) : False(env()->isolate()));
 
     message_info->Set(env()->upgrade_string(),
-                      parser_.upgrade ? True(node_isolate)
-                                      : False(node_isolate));
+                      parser_.upgrade ? True(env()->isolate())
+                                      : False(env()->isolate()));
 
     Local<Value> argv[1] = { message_info };
     Local<Value> head_response =
@@ -298,7 +298,7 @@ class Parser : public BaseObject {
 
 
   HTTP_DATA_CB(on_body) {
-    HandleScope scope(node_isolate);
+    HandleScope scope(env()->isolate());
 
     Local<Object> obj = object();
     Local<Value> cb = obj->Get(kOnBody);
@@ -308,8 +308,8 @@ class Parser : public BaseObject {
 
     Local<Value> argv[3] = {
       current_buffer_,
-      Integer::NewFromUnsigned(at - current_buffer_data_, node_isolate),
-      Integer::NewFromUnsigned(length, node_isolate)
+      Integer::NewFromUnsigned(at - current_buffer_data_, env()->isolate()),
+      Integer::NewFromUnsigned(length, env()->isolate())
     };
 
     Local<Value> r = cb.As<Function>()->Call(obj, ARRAY_SIZE(argv), argv);
@@ -324,7 +324,7 @@ class Parser : public BaseObject {
 
 
   HTTP_CB(on_message_complete) {
-    HandleScope scope(node_isolate);
+    HandleScope scope(env()->isolate());
 
     if (num_fields_)
       Flush();  // Flush trailing HTTP headers.
@@ -372,7 +372,8 @@ class Parser : public BaseObject {
 
   // var bytesParsed = parser->execute(buffer);
   static void Execute(const FunctionCallbackInfo<Value>& args) {
-    HandleScope scope(node_isolate);
+    Environment* env = Environment::GetCurrent(args.GetIsolate());
+    HandleScope scope(env->isolate());
 
     Parser* parser = Unwrap<Parser>(args.This());
     assert(parser->current_buffer_.IsEmpty());
@@ -406,18 +407,17 @@ class Parser : public BaseObject {
     if (parser->got_exception_)
       return;
 
-    Local<Integer> nparsed_obj = Integer::New(nparsed, node_isolate);
+    Local<Integer> nparsed_obj = Integer::New(nparsed, env->isolate());
     // If there was a parse error in one of the callbacks
     // TODO(bnoordhuis) What if there is an error on EOF?
     if (!parser->parser_.upgrade && nparsed != buffer_len) {
       enum http_errno err = HTTP_PARSER_ERRNO(&parser->parser_);
 
-      Local<Value> e = Exception::Error(
-          FIXED_ONE_BYTE_STRING(node_isolate, "Parse Error"));
+      Local<Value> e = Exception::Error(env->parse_error_string());
       Local<Object> obj = e->ToObject();
-      obj->Set(FIXED_ONE_BYTE_STRING(node_isolate, "bytesParsed"), nparsed_obj);
-      obj->Set(FIXED_ONE_BYTE_STRING(node_isolate, "code"),
-               OneByteString(node_isolate, http_errno_name(err)));
+      obj->Set(env->bytes_parsed_string(), nparsed_obj);
+      obj->Set(env->code_string(),
+               OneByteString(env->isolate(), http_errno_name(err)));
 
       args.GetReturnValue().Set(e);
     } else {
@@ -427,7 +427,8 @@ class Parser : public BaseObject {
 
 
   static void Finish(const FunctionCallbackInfo<Value>& args) {
-    HandleScope scope(node_isolate);
+    Environment* env = Environment::GetCurrent(args.GetIsolate());
+    HandleScope scope(env->isolate());
 
     Parser* parser = Unwrap<Parser>(args.This());
 
@@ -442,13 +443,11 @@ class Parser : public BaseObject {
     if (rv != 0) {
       enum http_errno err = HTTP_PARSER_ERRNO(&parser->parser_);
 
-      Local<Value> e = Exception::Error(
-          FIXED_ONE_BYTE_STRING(node_isolate, "Parse Error"));
+      Local<Value> e = env->parse_error_string();
       Local<Object> obj = e->ToObject();
-      obj->Set(FIXED_ONE_BYTE_STRING(node_isolate, "bytesParsed"),
-               Integer::New(0, node_isolate));
-      obj->Set(FIXED_ONE_BYTE_STRING(node_isolate, "code"),
-               OneByteString(node_isolate, http_errno_name(err)));
+      obj->Set(env->bytes_parsed_string(), Integer::New(0, env->isolate()));
+      obj->Set(env->code_string(),
+               OneByteString(env->isolate(), http_errno_name(err)));
 
       args.GetReturnValue().Set(e);
     }
@@ -489,8 +488,8 @@ class Parser : public BaseObject {
     Local<Array> headers = Array::New(2 * num_values_);
 
     for (int i = 0; i < num_values_; ++i) {
-      headers->Set(2 * i, fields_[i].ToString());
-      headers->Set(2 * i + 1, values_[i].ToString());
+      headers->Set(2 * i, fields_[i].ToString(env()));
+      headers->Set(2 * i + 1, values_[i].ToString(env()));
     }
 
     return headers;
@@ -499,7 +498,7 @@ class Parser : public BaseObject {
 
   // spill headers and request path to JS land
   void Flush() {
-    HandleScope scope(node_isolate);
+    HandleScope scope(env()->isolate());
 
     Local<Object> obj = object();
     Local<Value> cb = obj->Get(kOnHeaders);
@@ -509,7 +508,7 @@ class Parser : public BaseObject {
 
     Local<Value> argv[2] = {
       CreateHeaders(),
-      url_.ToString()
+      url_.ToString(env())
     };
 
     Local<Value> r = cb.As<Function>()->Call(obj, ARRAY_SIZE(argv), argv);
@@ -565,29 +564,30 @@ void InitHttpParser(Handle<Object> target,
                     Handle<Value> unused,
                     Handle<Context> context,
                     void* priv) {
+  Environment* env = Environment::GetCurrent(context);
   Local<FunctionTemplate> t = FunctionTemplate::New(Parser::New);
   t->InstanceTemplate()->SetInternalFieldCount(1);
-  t->SetClassName(FIXED_ONE_BYTE_STRING(node_isolate, "HTTPParser"));
-
-  t->Set(FIXED_ONE_BYTE_STRING(node_isolate, "REQUEST"),
-         Integer::New(HTTP_REQUEST, node_isolate));
-  t->Set(FIXED_ONE_BYTE_STRING(node_isolate, "RESPONSE"),
-         Integer::New(HTTP_RESPONSE, node_isolate));
-  t->Set(FIXED_ONE_BYTE_STRING(node_isolate, "kOnHeaders"),
-         Integer::NewFromUnsigned(kOnHeaders, node_isolate));
-  t->Set(FIXED_ONE_BYTE_STRING(node_isolate, "kOnHeadersComplete"),
-         Integer::NewFromUnsigned(kOnHeadersComplete, node_isolate));
-  t->Set(FIXED_ONE_BYTE_STRING(node_isolate, "kOnBody"),
-         Integer::NewFromUnsigned(kOnBody, node_isolate));
-  t->Set(FIXED_ONE_BYTE_STRING(node_isolate, "kOnMessageComplete"),
-         Integer::NewFromUnsigned(kOnMessageComplete, node_isolate));
+  t->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "HTTPParser"));
+
+  t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "REQUEST"),
+         Integer::New(HTTP_REQUEST, env->isolate()));
+  t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "RESPONSE"),
+         Integer::New(HTTP_RESPONSE, env->isolate()));
+  t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kOnHeaders"),
+         Integer::NewFromUnsigned(kOnHeaders, env->isolate()));
+  t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kOnHeadersComplete"),
+         Integer::NewFromUnsigned(kOnHeadersComplete, env->isolate()));
+  t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kOnBody"),
+         Integer::NewFromUnsigned(kOnBody, env->isolate()));
+  t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kOnMessageComplete"),
+         Integer::NewFromUnsigned(kOnMessageComplete, env->isolate()));
 
   Local<Array> methods = Array::New();
 #define V(num, name, string)                                                  \
-    methods->Set(num, FIXED_ONE_BYTE_STRING(node_isolate, #string));
+    methods->Set(num, FIXED_ONE_BYTE_STRING(env->isolate(), #string));
   HTTP_METHOD_MAP(V)
 #undef V
-  t->Set(FIXED_ONE_BYTE_STRING(node_isolate, "methods"), methods);
+  t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "methods"), methods);
 
   NODE_SET_PROTOTYPE_METHOD(t, "execute", Parser::Execute);
   NODE_SET_PROTOTYPE_METHOD(t, "finish", Parser::Finish);
@@ -595,7 +595,7 @@ void InitHttpParser(Handle<Object> target,
   NODE_SET_PROTOTYPE_METHOD(t, "pause", Parser::Pause<true>);
   NODE_SET_PROTOTYPE_METHOD(t, "resume", Parser::Pause<false>);
 
-  target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "HTTPParser"),
+  target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "HTTPParser"),
               t->GetFunction());
 }
 
index efd45c4..1b59144 100644 (file)
@@ -22,6 +22,7 @@
 #ifndef SRC_NODE_INTERNALS_H_
 #define SRC_NODE_INTERNALS_H_
 
+#include "node.h"
 #include "env.h"
 #include "util.h"
 #include "util-inl.h"
@@ -36,9 +37,6 @@ struct sockaddr;
 
 namespace node {
 
-// Defined in node.cc
-extern v8::Isolate* node_isolate;
-
 // If persistent.IsWeak() == false, then do not call persistent.Dispose()
 // while the returned Local<T> is still in scope, it will destroy the
 // reference to the object.
@@ -120,41 +118,6 @@ inline static int snprintf(char* buf, unsigned int len, const char* fmt, ...) {
 # define NO_RETURN
 #endif
 
-// this would have been a template function were it not for the fact that g++
-// sometimes fails to resolve it...
-#define THROW_ERROR(fun)                                                      \
-  do {                                                                        \
-    v8::HandleScope scope(node_isolate);                                      \
-    v8::ThrowException(fun(OneByteString(node_isolate, errmsg)));             \
-  }                                                                           \
-  while (0)
-
-inline static void ThrowError(const char* errmsg) {
-  THROW_ERROR(v8::Exception::Error);
-}
-
-inline static void ThrowTypeError(const char* errmsg) {
-  THROW_ERROR(v8::Exception::TypeError);
-}
-
-inline static void ThrowRangeError(const char* errmsg) {
-  THROW_ERROR(v8::Exception::RangeError);
-}
-
-inline static void ThrowErrnoException(int errorno,
-                                       const char* syscall = NULL,
-                                       const char* message = NULL,
-                                       const char* path = NULL) {
-  v8::ThrowException(ErrnoException(errorno, syscall, message, path));
-}
-
-inline static void ThrowUVException(int errorno,
-                                    const char* syscall = NULL,
-                                    const char* message = NULL,
-                                    const char* path = NULL) {
-  v8::ThrowException(UVException(errorno, syscall, message, path));
-}
-
 void AppendExceptionLine(Environment* env,
                          v8::Handle<v8::Value> er,
                          v8::Handle<v8::Message> message);
@@ -205,6 +168,38 @@ inline MUST_USE_RESULT bool ParseArrayIndex(v8::Handle<v8::Value> arg,
   return true;
 }
 
+NODE_DEPRECATED("Use env->ThrowError()",
+                inline void ThrowError(const char* errmsg) {
+  Environment* env = Environment::GetCurrent(v8::Isolate::GetCurrent());
+  return env->ThrowError(errmsg);
+})
+NODE_DEPRECATED("Use env->ThrowTypeError()",
+                inline void ThrowTypeError(const char* errmsg) {
+  Environment* env = Environment::GetCurrent(v8::Isolate::GetCurrent());
+  return env->ThrowTypeError(errmsg);
+})
+NODE_DEPRECATED("Use env->ThrowRangeError()",
+                inline void ThrowRangeError(const char* errmsg) {
+  Environment* env = Environment::GetCurrent(v8::Isolate::GetCurrent());
+  return env->ThrowRangeError(errmsg);
+})
+NODE_DEPRECATED("Use env->ThrowErrnoException()",
+                inline void ThrowErrnoException(int errorno,
+                                                const char* syscall = NULL,
+                                                const char* message = NULL,
+                                                const char* path = NULL) {
+  Environment* env = Environment::GetCurrent(v8::Isolate::GetCurrent());
+  return env->ThrowErrnoException(errorno, syscall, message, path);
+})
+NODE_DEPRECATED("Use env->ThrowUVException()",
+                inline void ThrowUVException(int errorno,
+                                                const char* syscall = NULL,
+                                                const char* message = NULL,
+                                                const char* path = NULL) {
+  Environment* env = Environment::GetCurrent(v8::Isolate::GetCurrent());
+  return env->ThrowUVException(errorno, syscall, message, path);
+})
+
 }  // namespace node
 
 #endif  // SRC_NODE_INTERNALS_H_
index deddbe2..dbf5326 100644 (file)
@@ -22,6 +22,8 @@
 #include "node.h"
 #include "node_natives.h"
 #include "v8.h"
+#include "env.h"
+#include "env-inl.h"
 
 #include <string.h>
 #if !defined(_MSC_VER)
@@ -36,17 +38,17 @@ using v8::Local;
 using v8::Object;
 using v8::String;
 
-Handle<String> MainSource() {
-  return OneByteString(node_isolate, node_native, sizeof(node_native) - 1);
+Handle<String> MainSource(Environment* env) {
+  return OneByteString(env->isolate(), node_native, sizeof(node_native) - 1);
 }
 
-void DefineJavaScript(Handle<Object> target) {
-  HandleScope scope(node_isolate);
+void DefineJavaScript(Environment* env, Handle<Object> target) {
+  HandleScope scope(env->isolate());
 
   for (int i = 0; natives[i].name; i++) {
     if (natives[i].source != node_native) {
-      Local<String> name = String::NewFromUtf8(node_isolate, natives[i].name);
-      Handle<String> source = String::NewFromUtf8(node_isolate,
+      Local<String> name = String::NewFromUtf8(env->isolate(), natives[i].name);
+      Handle<String> source = String::NewFromUtf8(env->isolate(),
                                                   natives[i].source,
                                                   String::kNormalString,
                                                   natives[i].source_len);
index 5193ea5..6b7edcb 100644 (file)
 #define SRC_NODE_JAVASCRIPT_H_
 
 #include "v8.h"
+#include "env.h"
 
 namespace node {
 
-void DefineJavaScript(v8::Handle<v8::Object> target);
-v8::Handle<v8::String> MainSource();
+void DefineJavaScript(Environment* env, v8::Handle<v8::Object> target);
+v8::Handle<v8::String> MainSource(Environment* env);
 
 }  // namespace node
 
index 0c78003..5de6049 100644 (file)
@@ -22,6 +22,8 @@
 
 #include "node.h"
 #include "v8.h"
+#include "env.h"
+#include "env-inl.h"
 
 #include <errno.h>
 #include <string.h>
@@ -59,14 +61,16 @@ using v8::Value;
 
 
 static void GetEndianness(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
   const char* rval = IsBigEndian() ? "BE" : "LE";
-  args.GetReturnValue().Set(OneByteString(node_isolate, rval));
+  args.GetReturnValue().Set(OneByteString(env->isolate(), rval));
 }
 
 
 static void GetHostname(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
   char buf[MAXHOSTNAMELEN + 1];
 
   if (gethostname(buf, sizeof(buf))) {
@@ -75,40 +79,42 @@ static void GetHostname(const FunctionCallbackInfo<Value>& args) {
 #else  // __MINGW32__
     int errorno = WSAGetLastError();
 #endif  // __POSIX__
-    return ThrowErrnoException(errorno, "gethostname");
+    return env->ThrowErrnoException(errorno, "gethostname");
   }
   buf[sizeof(buf) - 1] = '\0';
 
-  args.GetReturnValue().Set(OneByteString(node_isolate, buf));
+  args.GetReturnValue().Set(OneByteString(env->isolate(), buf));
 }
 
 
 static void GetOSType(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
   const char* rval;
 
 #ifdef __POSIX__
   struct utsname info;
   if (uname(&info) < 0) {
-    return ThrowErrnoException(errno, "uname");
+    return env->ThrowErrnoException(errno, "uname");
   }
   rval = info.sysname;
 #else  // __MINGW32__
   rval ="Windows_NT";
 #endif  // __POSIX__
 
-  args.GetReturnValue().Set(OneByteString(node_isolate, rval));
+  args.GetReturnValue().Set(OneByteString(env->isolate(), rval));
 }
 
 
 static void GetOSRelease(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
   const char* rval;
 
 #ifdef __POSIX__
   struct utsname info;
   if (uname(&info) < 0) {
-    return ThrowErrnoException(errno, "uname");
+    return env->ThrowErrnoException(errno, "uname");
   }
   rval = info.release;
 #else  // __MINGW32__
@@ -128,12 +134,13 @@ static void GetOSRelease(const FunctionCallbackInfo<Value>& args) {
   rval = release;
 #endif  // __POSIX__
 
-  args.GetReturnValue().Set(OneByteString(node_isolate, rval));
+  args.GetReturnValue().Set(OneByteString(env->isolate(), rval));
 }
 
 
 static void GetCPUInfo(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
   uv_cpu_info_t* cpu_infos;
   int count, i;
 
@@ -146,23 +153,23 @@ static void GetCPUInfo(const FunctionCallbackInfo<Value>& args) {
     uv_cpu_info_t* ci = cpu_infos + i;
 
     Local<Object> times_info = Object::New();
-    times_info->Set(FIXED_ONE_BYTE_STRING(node_isolate, "user"),
-                    Number::New(node_isolate, ci->cpu_times.user));
-    times_info->Set(FIXED_ONE_BYTE_STRING(node_isolate, "nice"),
-                    Number::New(node_isolate, ci->cpu_times.nice));
-    times_info->Set(FIXED_ONE_BYTE_STRING(node_isolate, "sys"),
-                    Number::New(node_isolate, ci->cpu_times.sys));
-    times_info->Set(FIXED_ONE_BYTE_STRING(node_isolate, "idle"),
-                    Number::New(node_isolate, ci->cpu_times.idle));
-    times_info->Set(FIXED_ONE_BYTE_STRING(node_isolate, "irq"),
-                    Number::New(node_isolate, ci->cpu_times.irq));
+    times_info->Set(env->user_string(),
+                    Number::New(env->isolate(), ci->cpu_times.user));
+    times_info->Set(env->nice_string(),
+                    Number::New(env->isolate(), ci->cpu_times.nice));
+    times_info->Set(env->sys_string(),
+                    Number::New(env->isolate(), ci->cpu_times.sys));
+    times_info->Set(env->idle_string(),
+                    Number::New(env->isolate(), ci->cpu_times.idle));
+    times_info->Set(env->irq_string(),
+                    Number::New(env->isolate(), ci->cpu_times.irq));
 
     Local<Object> cpu_info = Object::New();
-    cpu_info->Set(FIXED_ONE_BYTE_STRING(node_isolate, "model"),
-                  OneByteString(node_isolate, ci->model));
-    cpu_info->Set(FIXED_ONE_BYTE_STRING(node_isolate, "speed"),
-                  Number::New(node_isolate, ci->speed));
-    cpu_info->Set(FIXED_ONE_BYTE_STRING(node_isolate, "times"), times_info);
+    cpu_info->Set(env->model_string(),
+                  OneByteString(env->isolate(), ci->model));
+    cpu_info->Set(env->speed_string(),
+                  Number::New(env->isolate(), ci->speed));
+    cpu_info->Set(env->times_string(), times_info);
 
     (*cpus)->Set(i, cpu_info);
   }
@@ -173,7 +180,8 @@ static void GetCPUInfo(const FunctionCallbackInfo<Value>& args) {
 
 
 static void GetFreeMemory(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
   double amount = uv_get_free_memory();
   if (amount < 0)
     return;
@@ -182,7 +190,8 @@ static void GetFreeMemory(const FunctionCallbackInfo<Value>& args) {
 
 
 static void GetTotalMemory(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
   double amount = uv_get_total_memory();
   if (amount < 0)
     return;
@@ -191,7 +200,8 @@ static void GetTotalMemory(const FunctionCallbackInfo<Value>& args) {
 
 
 static void GetUptime(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
   double uptime;
   int err = uv_uptime(&uptime);
   if (err == 0)
@@ -200,7 +210,8 @@ static void GetUptime(const FunctionCallbackInfo<Value>& args) {
 
 
 static void GetLoadAvg(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
   double loadavg[3];
   uv_loadavg(loadavg);
   Local<Array> loads = Array::New(3);
@@ -212,7 +223,8 @@ static void GetLoadAvg(const FunctionCallbackInfo<Value>& args) {
 
 
 static void GetInterfaceAddresses(const FunctionCallbackInfo<Value>& args) {
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
   uv_interface_address_t* interfaces;
   int count, i;
   char ip[INET6_ADDRSTRLEN];
@@ -229,11 +241,11 @@ static void GetInterfaceAddresses(const FunctionCallbackInfo<Value>& args) {
   if (err == UV_ENOSYS) {
     args.GetReturnValue().Set(ret);
   } else if (err) {
-    return ThrowUVException(err, "uv_interface_addresses");
+    return env->ThrowUVException(err, "uv_interface_addresses");
   }
 
   for (i = 0; i < count; i++) {
-    name = OneByteString(node_isolate, interfaces[i].name);
+    name = OneByteString(env->isolate(), interfaces[i].name);
     if (ret->Has(name)) {
       ifarr = Local<Array>::Cast(ret->Get(name));
     } else {
@@ -254,34 +266,30 @@ static void GetInterfaceAddresses(const FunctionCallbackInfo<Value>& args) {
     if (interfaces[i].address.address4.sin_family == AF_INET) {
       uv_ip4_name(&interfaces[i].address.address4, ip, sizeof(ip));
       uv_ip4_name(&interfaces[i].netmask.netmask4, netmask, sizeof(netmask));
-      family = FIXED_ONE_BYTE_STRING(node_isolate, "IPv4");
+      family = env->ipv4_string();
     } else if (interfaces[i].address.address4.sin_family == AF_INET6) {
       uv_ip6_name(&interfaces[i].address.address6, ip, sizeof(ip));
       uv_ip6_name(&interfaces[i].netmask.netmask6, netmask, sizeof(netmask));
-      family = FIXED_ONE_BYTE_STRING(node_isolate, "IPv6");
+      family = env->ipv6_string();
     } else {
       strncpy(ip, "<unknown sa family>", INET6_ADDRSTRLEN);
-      family = FIXED_ONE_BYTE_STRING(node_isolate, "<unknown>");
+      family = env->unknown_string();
     }
 
     o = Object::New();
-    o->Set(FIXED_ONE_BYTE_STRING(node_isolate, "address"),
-           OneByteString(node_isolate, ip));
-    o->Set(FIXED_ONE_BYTE_STRING(node_isolate, "netmask"),
-           OneByteString(node_isolate, netmask));
-    o->Set(FIXED_ONE_BYTE_STRING(node_isolate, "family"), family);
-    o->Set(FIXED_ONE_BYTE_STRING(node_isolate, "mac"),
-           FIXED_ONE_BYTE_STRING(node_isolate, mac));
+    o->Set(env->address_string(), OneByteString(env->isolate(), ip));
+    o->Set(env->netmask_string(), OneByteString(env->isolate(), netmask));
+    o->Set(env->family_string(), family);
+    o->Set(env->mac_string(), FIXED_ONE_BYTE_STRING(env->isolate(), mac));
 
     if (interfaces[i].address.address4.sin_family == AF_INET6) {
       uint32_t scopeid = interfaces[i].address.address6.sin6_scope_id;
-      o->Set(FIXED_ONE_BYTE_STRING(node_isolate, "scopeid"),
-        Integer::NewFromUnsigned(scopeid));
+      o->Set(env->scopeid_string(), Integer::NewFromUnsigned(scopeid));
     }
 
     const bool internal = interfaces[i].is_internal;
-    o->Set(FIXED_ONE_BYTE_STRING(node_isolate, "internal"),
-           internal ? True(node_isolate) : False(node_isolate));
+    o->Set(env->internal_string(),
+           internal ? True(env->isolate()) : False(env->isolate()));
 
     ifarr->Set(ifarr->Length(), o);
   }
index fadce45..5d72d7c 100644 (file)
@@ -45,17 +45,17 @@ using v8::String;
 using v8::Value;
 
 
-void StatWatcher::Initialize(Handle<Object> target) {
-  HandleScope scope(node_isolate);
+void StatWatcher::Initialize(Environment* env, Handle<Object> target) {
+  HandleScope scope(env->isolate());
 
   Local<FunctionTemplate> t = FunctionTemplate::New(StatWatcher::New);
   t->InstanceTemplate()->SetInternalFieldCount(1);
-  t->SetClassName(FIXED_ONE_BYTE_STRING(node_isolate, "StatWatcher"));
+  t->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "StatWatcher"));
 
   NODE_SET_PROTOTYPE_METHOD(t, "start", StatWatcher::Start);
   NODE_SET_PROTOTYPE_METHOD(t, "stop", StatWatcher::Stop);
 
-  target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "StatWatcher"),
+  target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "StatWatcher"),
               t->GetFunction());
 }
 
@@ -92,7 +92,7 @@ void StatWatcher::Callback(uv_fs_poll_t* handle,
   Local<Value> argv[] = {
     BuildStatsObject(env, curr),
     BuildStatsObject(env, prev),
-    Integer::New(status, node_isolate)
+    Integer::New(status, env->isolate())
   };
   wrap->MakeCallback(env->onchange_string(), ARRAY_SIZE(argv), argv);
 }
@@ -108,7 +108,8 @@ void StatWatcher::New(const FunctionCallbackInfo<Value>& args) {
 
 void StatWatcher::Start(const FunctionCallbackInfo<Value>& args) {
   assert(args.Length() == 3);
-  HandleScope scope(node_isolate);
+  Environment* env = Environment::GetCurrent(args.GetIsolate());
+  HandleScope scope(env->isolate());
 
   StatWatcher* wrap = Unwrap<StatWatcher>(args.This());
   String::Utf8Value path(args[0]);
index f9ad2e6..fb6d5ad 100644 (file)
@@ -34,7 +34,7 @@ class StatWatcher : public AsyncWrap {
  public:
   virtual ~StatWatcher();
 
-  static void Initialize(v8::Handle<v8::Object> target);
+  static void Initialize(Environment* env, v8::Handle<v8::Object> target);
 
  protected:
   StatWatcher(Environment* env, v8::Local<v8::Object> wrap);
index 98cc45c..8762ec4 100644 (file)
@@ -54,7 +54,7 @@ namespace node {
 
 inline uv_stream_t* HandleToStream(Environment* env,
                                    v8::Local<v8::Object> obj) {
-  v8::HandleScope scope(node_isolate);
+  v8::HandleScope scope(env->isolate());
 
   WITH_GENERIC_STREAM(env, obj, {
     return reinterpret_cast<uv_stream_t*>(wrap->UVHandle());
index 90c5e10..db789e2 100644 (file)
@@ -110,11 +110,13 @@ class ZCtx : public AsyncWrap {
 
     if (mode_ == DEFLATE || mode_ == GZIP || mode_ == DEFLATERAW) {
       (void)deflateEnd(&strm_);
-      node_isolate->AdjustAmountOfExternalAllocatedMemory(-kDeflateContextSize);
+      env()->isolate()
+          ->AdjustAmountOfExternalAllocatedMemory(-kDeflateContextSize);
     } else if (mode_ == INFLATE || mode_ == GUNZIP || mode_ == INFLATERAW ||
                mode_ == UNZIP) {
       (void)inflateEnd(&strm_);
-      node_isolate->AdjustAmountOfExternalAllocatedMemory(-kInflateContextSize);
+      env()->isolate()
+          ->AdjustAmountOfExternalAllocatedMemory(-kInflateContextSize);
     }
     mode_ = NONE;
 
@@ -126,7 +128,8 @@ class ZCtx : public AsyncWrap {
 
 
   static void Close(const FunctionCallbackInfo<Value>& args) {
-    HandleScope scope(node_isolate);
+    Environment* env = Environment::GetCurrent(args.GetIsolate());
+    HandleScope scope(env->isolate());
     ZCtx* ctx = Unwrap<ZCtx>(args.This());
     ctx->Close();
   }
@@ -135,7 +138,8 @@ class ZCtx : public AsyncWrap {
   // write(flush, in, in_off, in_len, out, out_off, out_len)
   template <bool async>
   static void Write(const FunctionCallbackInfo<Value>& args) {
-    HandleScope scope(node_isolate);
+    Environment* env = Environment::GetCurrent(args.GetIsolate());
+    HandleScope scope(env->isolate());
     assert(args.Length() == 7);
 
     ZCtx* ctx = Unwrap<ZCtx>(args.This());
@@ -219,8 +223,12 @@ class ZCtx : public AsyncWrap {
 
 
   static void AfterSync(ZCtx* ctx, const FunctionCallbackInfo<Value>& args) {
-    Local<Integer> avail_out = Integer::New(ctx->strm_.avail_out, node_isolate);
-    Local<Integer> avail_in = Integer::New(ctx->strm_.avail_in, node_isolate);
+    Environment* env = Environment::GetCurrent(args.GetIsolate());
+    HandleScope scope(env->isolate());
+    Local<Integer> avail_out = Integer::New(ctx->strm_.avail_out,
+                                            env->isolate());
+    Local<Integer> avail_in = Integer::New(ctx->strm_.avail_in,
+                                           env->isolate());
 
     ctx->write_in_progress_ = false;
 
@@ -321,8 +329,10 @@ class ZCtx : public AsyncWrap {
     if (!CheckError(ctx))
       return;
 
-    Local<Integer> avail_out = Integer::New(ctx->strm_.avail_out, node_isolate);
-    Local<Integer> avail_in = Integer::New(ctx->strm_.avail_in, node_isolate);
+    Local<Integer> avail_out = Integer::New(ctx->strm_.avail_out,
+                                            env->isolate());
+    Local<Integer> avail_in = Integer::New(ctx->strm_.avail_in,
+                                           env->isolate());
 
     ctx->write_in_progress_ = false;
 
@@ -345,9 +355,9 @@ class ZCtx : public AsyncWrap {
       message = ctx->strm_.msg;
     }
 
-    HandleScope scope(node_isolate);
+    HandleScope scope(env->isolate());
     Local<Value> args[2] = {
-      OneByteString(node_isolate, message),
+      OneByteString(env->isolate(), message),
       Number::New(ctx->err_)
     };
     ctx->MakeCallback(env->onerror_string(), ARRAY_SIZE(args), args);
@@ -364,12 +374,12 @@ class ZCtx : public AsyncWrap {
     Environment* env = Environment::GetCurrent(args.GetIsolate());
 
     if (args.Length() < 1 || !args[0]->IsInt32()) {
-      return ThrowTypeError("Bad argument");
+      return env->ThrowTypeError("Bad argument");
     }
     node_zlib_mode mode = static_cast<node_zlib_mode>(args[0]->Int32Value());
 
     if (mode < DEFLATE || mode > UNZIP) {
-      return ThrowTypeError("Bad argument");
+      return env->ThrowTypeError("Bad argument");
     }
 
     new ZCtx(env, args.This(), mode);
@@ -377,7 +387,8 @@ class ZCtx : public AsyncWrap {
 
   // just pull the ints out of the args and call the other Init
   static void Init(const FunctionCallbackInfo<Value>& args) {
-    HandleScope scope(node_isolate);
+    Environment* env = Environment::GetCurrent(args.GetIsolate());
+    HandleScope scope(env->isolate());
 
     assert((args.Length() == 4 || args.Length() == 5) &&
            "init(windowBits, level, memLevel, strategy, [dictionary])");
@@ -417,7 +428,8 @@ class ZCtx : public AsyncWrap {
   }
 
   static void Params(const FunctionCallbackInfo<Value>& args) {
-    HandleScope scope(node_isolate);
+    Environment* env = Environment::GetCurrent(args.GetIsolate());
+    HandleScope scope(env->isolate());
 
     assert(args.Length() == 2 && "params(level, strategy)");
 
@@ -427,7 +439,8 @@ class ZCtx : public AsyncWrap {
   }
 
   static void Reset(const FunctionCallbackInfo<Value> &args) {
-    HandleScope scope(node_isolate);
+    Environment* env = Environment::GetCurrent(args.GetIsolate());
+    HandleScope scope(env->isolate());
 
     ZCtx* ctx = Unwrap<ZCtx>(args.This());
 
@@ -472,16 +485,16 @@ class ZCtx : public AsyncWrap {
                                  ctx->windowBits_,
                                  ctx->memLevel_,
                                  ctx->strategy_);
-        node_isolate->
-                    AdjustAmountOfExternalAllocatedMemory(kDeflateContextSize);
+        ctx->env()->isolate()
+            ->AdjustAmountOfExternalAllocatedMemory(kDeflateContextSize);
         break;
       case INFLATE:
       case GUNZIP:
       case INFLATERAW:
       case UNZIP:
         ctx->err_ = inflateInit2(&ctx->strm_, ctx->windowBits_);
-        node_isolate->
-                    AdjustAmountOfExternalAllocatedMemory(kInflateContextSize);
+        ctx->env()->isolate()
+            ->AdjustAmountOfExternalAllocatedMemory(kInflateContextSize);
         break;
       default:
         assert(0 && "wtf?");
@@ -599,6 +612,7 @@ void InitZlib(Handle<Object> target,
               Handle<Value> unused,
               Handle<Context> context,
               void* priv) {
+  Environment* env = Environment::GetCurrent(context);
   Local<FunctionTemplate> z = FunctionTemplate::New(ZCtx::New);
 
   z->InstanceTemplate()->SetInternalFieldCount(1);
@@ -610,8 +624,8 @@ void InitZlib(Handle<Object> target,
   NODE_SET_PROTOTYPE_METHOD(z, "params", ZCtx::Params);
   NODE_SET_PROTOTYPE_METHOD(z, "reset", ZCtx::Reset);
 
-  z->SetClassName(FIXED_ONE_BYTE_STRING(node_isolate, "Zlib"));
-  target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "Zlib"), z->GetFunction());
+  z->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Zlib"));
+  target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "Zlib"), z->GetFunction());
 
   // valid flush values.
   NODE_DEFINE_CONSTANT(target, Z_NO_FLUSH);
@@ -651,8 +665,8 @@ void InitZlib(Handle<Object> target,
   NODE_DEFINE_CONSTANT(target, INFLATERAW);
   NODE_DEFINE_CONSTANT(target, UNZIP);
 
-  target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "ZLIB_VERSION"),
-              FIXED_ONE_BYTE_STRING(node_isolate, ZLIB_VERSION));
+  target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "ZLIB_VERSION"),
+              FIXED_ONE_BYTE_STRING(env->isolate(), ZLIB_VERSION));
 }
 
 }  // namespace node
index 67a7562..1fc9a56 100644 (file)
@@ -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());
 
index f21fef9..31d0432 100644 (file)
@@ -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,23 +100,20 @@ 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);
@@ -124,7 +121,7 @@ class ProcessWrap : public HandleWrap {
         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);
index dbf4b94..0e61ba6 100644 (file)
@@ -46,9 +46,10 @@ 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);
@@ -56,7 +57,7 @@ class SignalWrap : public HandleWrap {
     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_);
index 7b8e433..347d703 100644 (file)
@@ -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,19 +235,22 @@ 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) {
@@ -252,17 +258,18 @@ void Alloc(Handle<Object> obj, size_t length, enum ExternalArrayType type) {
                " 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,11 +357,12 @@ 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,
@@ -361,18 +370,17 @@ void Alloc(Handle<Object> obj,
            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();
index e042aed..97dda17 100644 (file)
@@ -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
index 481cf03..de0d180 100644 (file)
@@ -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);
index f0fcb46..5a9c4df 100644 (file)
@@ -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,
index 1a05945..0a1bf92 100644 (file)
@@ -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()
   };
index 1735299..cb8a537 100644 (file)
@@ -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,8 +435,10 @@ 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);
 
@@ -425,7 +446,7 @@ size_t StringBytes::Size(Handle<Value> val, enum encoding encoding) {
     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,21 +692,21 @@ 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);
@@ -692,9 +714,9 @@ Local<Value> StringBytes::Encode(const char* buf,
 
     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,10 +727,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;
     }
@@ -716,12 +738,12 @@ Local<Value> StringBytes::Encode(const char* buf,
     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;
     }
index aa32aea..feaf616 100644 (file)
@@ -34,19 +34,26 @@ 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);
 
@@ -54,16 +61,64 @@ class StringBytes {
   // 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
index 728d87a..66935e6 100644 (file)
@@ -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,7 +242,8 @@ 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);
@@ -247,7 +251,8 @@ void TCPWrap::Open(const FunctionCallbackInfo<Value>& args) {
 
 
 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);
index 498bcbb..1352743 100644 (file)
@@ -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,7 +107,8 @@ 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_);
@@ -113,7 +116,8 @@ class TimerWrap : public HandleWrap {
   }
 
   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_);
@@ -121,7 +125,8 @@ class TimerWrap : public HandleWrap {
   }
 
   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);
   }
 
index 0e63444..d7b2d42 100644 (file)
@@ -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,14 +731,15 @@ 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);
   }
@@ -738,15 +747,16 @@ void TLSCallbacks::GetServername(const FunctionCallbackInfo<Value>& args) {
 
 
 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);
index 4b5b858..cd6e319 100644 (file)
@@ -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,8 +141,8 @@ 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);
@@ -147,7 +150,8 @@ void TTYWrap::GetWindowSize(const FunctionCallbackInfo<Value>& args) {
 
 
 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());
 
index 7d5fd94..36ce93d 100644 (file)
@@ -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())
index 32d6a86..1481f73 100644 (file)
--- a/src/uv.cc
+++ b/src/uv.cc
@@ -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
 }