diff options
42 files changed, 1841 insertions, 1232 deletions
diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index 558d6d5872..567b159807 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -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 diff --git a/src/env-inl.h b/src/env-inl.h index 7d0a9ddb4e..bcc7995fa3 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -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 { \ @@ -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) \ diff --git a/src/fs_event_wrap.cc b/src/fs_event_wrap.cc index 28b20ac47c..ee28c44afb 100644 --- a/src/fs_event_wrap.cc +++ b/src/fs_event_wrap.cc @@ -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()); diff --git a/src/handle_wrap.cc b/src/handle_wrap.cc index b7ee48da18..3df1e497d3 100644 --- a/src/handle_wrap.cc +++ b/src/handle_wrap.cc @@ -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); diff --git a/src/node.cc b/src/node.cc index 434682fad6..7c0bb33926 100644 --- a/src/node.cc +++ b/src/node.cc @@ -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); diff --git a/src/node.h b/src/node.h index c07b3ae3de..3c48c79805 100644 --- a/src/node.h +++ b/src/node.h @@ -61,19 +61,47 @@ #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); diff --git a/src/node_buffer.cc b/src/node_buffer.cc index 5a3803e978..8304c4f02f 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -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()); } diff --git a/src/node_buffer.h b/src/node_buffer.h index 9b004bdc82..1d58c309bc 100644 --- a/src/node_buffer.h +++ b/src/node_buffer.h @@ -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) { diff --git a/src/node_contextify.cc b/src/node_contextify.cc index 4ef6126a46..05d2b11c3f 100644 --- a/src/node_contextify.cc +++ b/src/node_contextify.cc @@ -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; } diff --git a/src/node_counters.cc b/src/node_counters.cc index 1350a08d0b..9e351ac5f4 100644 --- a/src/node_counters.cc +++ b/src/node_counters.cc @@ -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); } diff --git a/src/node_counters.h b/src/node_counters.h index 670f38e804..8340ffcbd2 100644 --- a/src/node_counters.h +++ b/src/node_counters.h @@ -43,10 +43,11 @@ #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 diff --git a/src/node_crypto.cc b/src/node_crypto.cc index fe7e0b3b28..0991f543f3 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -51,13 +51,13 @@ #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); diff --git a/src/node_crypto.h b/src/node_crypto.h index 2e75fd591d..3fed0d5678 100644 --- a/src/node_crypto.h +++ b/src/node_crypto.h @@ -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); diff --git a/src/node_dtrace.cc b/src/node_dtrace.cc index df1546c239..0b8db1e070 100644 --- a/src/node_dtrace.cc +++ b/src/node_dtrace.cc @@ -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); } diff --git a/src/node_dtrace.h b/src/node_dtrace.h index 5b6df8f4a7..1169961896 100644 --- a/src/node_dtrace.h +++ b/src/node_dtrace.h @@ -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 diff --git a/src/node_file.cc b/src/node_file.cc index c1328e5351..9476a1340c 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -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 diff --git a/src/node_http_parser.cc b/src/node_http_parser.cc index 1d92f65426..7424f4b8bc 100644 --- a/src/node_http_parser.cc +++ b/src/node_http_parser.cc @@ -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()); } diff --git a/src/node_internals.h b/src/node_internals.h index efd45c4857..1b5914443d 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -22,6 +22,7 @@ #ifndef SRC_NODE_INTERNALS_H_ #define SRC_NODE_INTERNALS_H_ +#include "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_ diff --git a/src/node_javascript.cc b/src/node_javascript.cc index deddbe233a..dbf5326d4f 100644 --- a/src/node_javascript.cc +++ b/src/node_javascript.cc @@ -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); diff --git a/src/node_javascript.h b/src/node_javascript.h index 5193ea5350..6b7edcb744 100644 --- a/src/node_javascript.h +++ b/src/node_javascript.h @@ -23,11 +23,12 @@ #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 diff --git a/src/node_os.cc b/src/node_os.cc index 0c78003683..5de6049296 100644 --- a/src/node_os.cc +++ b/src/node_os.cc @@ -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); } diff --git a/src/node_stat_watcher.cc b/src/node_stat_watcher.cc index fadce4557b..5d72d7c244 100644 --- a/src/node_stat_watcher.cc +++ b/src/node_stat_watcher.cc @@ -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]); diff --git a/src/node_stat_watcher.h b/src/node_stat_watcher.h index f9ad2e6541..fb6d5ad3e7 100644 --- a/src/node_stat_watcher.h +++ b/src/node_stat_watcher.h @@ -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); diff --git a/src/node_wrap.h b/src/node_wrap.h index 98cc45c993..8762ec40c7 100644 --- a/src/node_wrap.h +++ b/src/node_wrap.h @@ -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()); diff --git a/src/node_zlib.cc b/src/node_zlib.cc index 90c5e10c47..db789e2132 100644 --- a/src/node_zlib.cc +++ b/src/node_zlib.cc @@ -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 diff --git a/src/pipe_wrap.cc b/src/pipe_wrap.cc index 67a756294e..1fc9a560fa 100644 --- a/src/pipe_wrap.cc +++ b/src/pipe_wrap.cc @@ -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()); diff --git a/src/process_wrap.cc b/src/process_wrap.cc index f21fef9b8e..31d0432e41 100644 --- a/src/process_wrap.cc +++ b/src/process_wrap.cc @@ -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); diff --git a/src/signal_wrap.cc b/src/signal_wrap.cc index dbf4b949e6..0e61ba63ea 100644 --- a/src/signal_wrap.cc +++ b/src/signal_wrap.cc @@ -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_); diff --git a/src/smalloc.cc b/src/smalloc.cc index 7b8e433361..347d7035b9 100644 --- a/src/smalloc.cc +++ b/src/smalloc.cc @@ -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(); diff --git a/src/smalloc.h b/src/smalloc.h index e042aed0f4..97dda17b64 100644 --- a/src/smalloc.h +++ b/src/smalloc.h @@ -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 diff --git a/src/spawn_sync.cc b/src/spawn_sync.cc index 481cf0302d..de0d180e3b 100644 --- a/src/spawn_sync.cc +++ b/src/spawn_sync.cc @@ -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); diff --git a/src/spawn_sync.h b/src/spawn_sync.h index f0fcb464ed..5a9c4dfc84 100644 --- a/src/spawn_sync.h +++ b/src/spawn_sync.h @@ -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, diff --git a/src/stream_wrap.cc b/src/stream_wrap.cc index 1a05945fbb..0a1bf92d6e 100644 --- a/src/stream_wrap.cc +++ b/src/stream_wrap.cc @@ -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() }; diff --git a/src/string_bytes.cc b/src/string_bytes.cc index 17352995f5..cb8a537c71 100644 --- a/src/string_bytes.cc +++ b/src/string_bytes.cc @@ -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; } diff --git a/src/string_bytes.h b/src/string_bytes.h index aa32aea5f8..feaf61617c 100644 --- a/src/string_bytes.h +++ b/src/string_bytes.h @@ -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 diff --git a/src/tcp_wrap.cc b/src/tcp_wrap.cc index 728d87a698..66935e6b60 100644 --- a/src/tcp_wrap.cc +++ b/src/tcp_wrap.cc @@ -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); diff --git a/src/timer_wrap.cc b/src/timer_wrap.cc index 498bcbb846..13527433b1 100644 --- a/src/timer_wrap.cc +++ b/src/timer_wrap.cc @@ -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); } diff --git a/src/tls_wrap.cc b/src/tls_wrap.cc index 0e63444d7f..d7b2d42b0d 100644 --- a/src/tls_wrap.cc +++ b/src/tls_wrap.cc @@ -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); diff --git a/src/tty_wrap.cc b/src/tty_wrap.cc index 4b5b8587c0..cd6e319fc0 100644 --- a/src/tty_wrap.cc +++ b/src/tty_wrap.cc @@ -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()); diff --git a/src/udp_wrap.cc b/src/udp_wrap.cc index 7d5fd942ba..36ce93d63b 100644 --- a/src/udp_wrap.cc +++ b/src/udp_wrap.cc @@ -93,11 +93,11 @@ void UDPWrap::Initialize(Handle<Object> target, Local<FunctionTemplate> t = FunctionTemplate::New(New); t->InstanceTemplate()->SetInternalFieldCount(1); - t->SetClassName(FIXED_ONE_BYTE_STRING(node_isolate, "UDP")); + t->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "UDP")); enum PropertyAttribute attributes = static_cast<PropertyAttribute>(v8::ReadOnly | v8::DontDelete); - t->InstanceTemplate()->SetAccessor(FIXED_ONE_BYTE_STRING(node_isolate, "fd"), + t->InstanceTemplate()->SetAccessor(env->fd_string(), UDPWrap::GetFD, NULL, Handle<Value>(), @@ -122,7 +122,7 @@ void UDPWrap::Initialize(Handle<Object> target, NODE_SET_PROTOTYPE_METHOD(t, "ref", HandleWrap::Ref); NODE_SET_PROTOTYPE_METHOD(t, "unref", HandleWrap::Unref); - target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "UDP"), t->GetFunction()); + target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "UDP"), t->GetFunction()); env->set_udp_constructor_function(t->GetFunction()); } @@ -137,7 +137,8 @@ void UDPWrap::New(const FunctionCallbackInfo<Value>& args) { void UDPWrap::GetFD(Local<String>, const PropertyCallbackInfo<Value>& args) { #if !defined(_WIN32) - HandleScope scope(node_isolate); + Environment* env = Environment::GetCurrent(args.GetIsolate()); + HandleScope scope(env->isolate()); UDPWrap* wrap = Unwrap<UDPWrap>(args.This()); int fd = (wrap == NULL) ? -1 : wrap->handle_.io_watcher.fd; args.GetReturnValue().Set(fd); @@ -146,7 +147,8 @@ void UDPWrap::GetFD(Local<String>, const PropertyCallbackInfo<Value>& args) { void UDPWrap::DoBind(const FunctionCallbackInfo<Value>& args, int family) { - HandleScope scope(node_isolate); + Environment* env = Environment::GetCurrent(args.GetIsolate()); + HandleScope scope(env->isolate()); UDPWrap* wrap = Unwrap<UDPWrap>(args.This()); @@ -193,7 +195,7 @@ void UDPWrap::Bind6(const FunctionCallbackInfo<Value>& args) { #define X(name, fn) \ void UDPWrap::name(const FunctionCallbackInfo<Value>& args) { \ - HandleScope scope(node_isolate); \ + HandleScope scope(args.GetIsolate()); \ UDPWrap* wrap = Unwrap<UDPWrap>(args.This()); \ assert(args.Length() == 1); \ int flag = args[0]->Int32Value(); \ @@ -211,7 +213,8 @@ X(SetMulticastLoopback, uv_udp_set_multicast_loop) void UDPWrap::SetMembership(const FunctionCallbackInfo<Value>& args, uv_membership membership) { - HandleScope scope(node_isolate); + Environment* env = Environment::GetCurrent(args.GetIsolate()); + HandleScope scope(env->isolate()); UDPWrap* wrap = Unwrap<UDPWrap>(args.This()); assert(args.Length() == 2); @@ -315,7 +318,8 @@ void UDPWrap::Send6(const FunctionCallbackInfo<Value>& args) { void UDPWrap::RecvStart(const FunctionCallbackInfo<Value>& args) { - HandleScope scope(node_isolate); + Environment* env = Environment::GetCurrent(args.GetIsolate()); + HandleScope scope(env->isolate()); UDPWrap* wrap = Unwrap<UDPWrap>(args.This()); int err = uv_udp_recv_start(&wrap->handle_, OnAlloc, OnRecv); @@ -327,7 +331,8 @@ void UDPWrap::RecvStart(const FunctionCallbackInfo<Value>& args) { void UDPWrap::RecvStop(const FunctionCallbackInfo<Value>& args) { - HandleScope scope(node_isolate); + Environment* env = Environment::GetCurrent(args.GetIsolate()); + HandleScope scope(env->isolate()); UDPWrap* wrap = Unwrap<UDPWrap>(args.This()); int r = uv_udp_recv_stop(&wrap->handle_); @@ -366,7 +371,7 @@ void UDPWrap::OnSend(uv_udp_send_t* req, int status) { Environment* env = req_wrap->env(); HandleScope handle_scope(env->isolate()); Context::Scope context_scope(env->context()); - Local<Value> arg = Integer::New(status, node_isolate); + Local<Value> arg = Integer::New(status, env->isolate()); req_wrap->MakeCallback(env->oncomplete_string(), 1, &arg); } delete req_wrap; @@ -405,7 +410,7 @@ void UDPWrap::OnRecv(uv_udp_t* handle, Local<Object> wrap_obj = wrap->object(); Local<Value> argv[] = { - Integer::New(nread, node_isolate), + Integer::New(nread, env->isolate()), wrap_obj, Undefined(env->isolate()), Undefined(env->isolate()) @@ -21,6 +21,8 @@ #include "uv.h" #include "node.h" +#include "env.h" +#include "env-inl.h" namespace node { namespace uv { @@ -37,23 +39,25 @@ using v8::Value; void ErrName(const FunctionCallbackInfo<Value>& args) { - v8::HandleScope handle_scope(node_isolate); + Environment* env = Environment::GetCurrent(args.GetIsolate()); + HandleScope scope(env->isolate()); int err = args[0]->Int32Value(); if (err >= 0) - return ThrowError("err >= 0"); + return env->ThrowError("err >= 0"); const char* name = uv_err_name(err); - args.GetReturnValue().Set(OneByteString(node_isolate, name)); + args.GetReturnValue().Set(OneByteString(env->isolate(), name)); } void Initialize(Handle<Object> target, Handle<Value> unused, Handle<Context> context) { - target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "errname"), + Environment* env = Environment::GetCurrent(context); + target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "errname"), FunctionTemplate::New(ErrName)->GetFunction()); #define V(name, _) \ - target->Set(FIXED_ONE_BYTE_STRING(node_isolate, "UV_" # name), \ - Integer::New(UV_ ## name, node_isolate)); + target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "UV_" # name), \ + Integer::New(UV_ ## name, env->isolate())); UV_ERRNO_MAP(V) #undef V } |