mirror of https://github.com/lukechilds/node.git
Browse Source
This commit makes it possible to use multiple V8 execution contexts within a single event loop. Put another way, handle and request wrap objects now "remember" the context they belong to and switch back to that context when the time comes to call into JS land. This could have been done in a quick and hacky way by calling v8::Object::GetCreationContext() on the wrap object right before making a callback but that leaves a fairly wide margin for bugs. Instead, we make the context explicit through a new Environment class that encapsulates everything (or almost everything) that belongs to the context. Variables that used to be a static or a global are now members of the aforementioned class. An additional benefit is that this approach should make it relatively straightforward to add full isolate support in due course. There is no JavaScript API yet but that will be added in the near future. This work was graciously sponsored by GitHub, Inc.v0.11.8-release
Ben Noordhuis
12 years ago
45 changed files with 2520 additions and 1704 deletions
@ -0,0 +1,289 @@ |
|||
// Copyright Joyent, Inc. and other Node contributors.
|
|||
//
|
|||
// Permission is hereby granted, free of charge, to any person obtaining a
|
|||
// copy of this software and associated documentation files (the
|
|||
// "Software"), to deal in the Software without restriction, including
|
|||
// without limitation the rights to use, copy, modify, merge, publish,
|
|||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|||
// persons to whom the Software is furnished to do so, subject to the
|
|||
// following conditions:
|
|||
//
|
|||
// The above copyright notice and this permission notice shall be included
|
|||
// in all copies or substantial portions of the Software.
|
|||
//
|
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
|||
#ifndef SRC_ENV_INL_H_ |
|||
#define SRC_ENV_INL_H_ |
|||
|
|||
#include "env.h" |
|||
#include "util.h" |
|||
#include "util-inl.h" |
|||
#include "uv.h" |
|||
#include "v8.h" |
|||
|
|||
#include <stddef.h> |
|||
#include <stdint.h> |
|||
|
|||
namespace node { |
|||
|
|||
inline Environment::IsolateData* Environment::IsolateData::GetOrCreate( |
|||
v8::Isolate* isolate) { |
|||
IsolateData* isolate_data = static_cast<IsolateData*>(isolate->GetData()); |
|||
if (isolate_data == NULL) { |
|||
isolate_data = new IsolateData(isolate); |
|||
isolate->SetData(isolate_data); |
|||
} |
|||
isolate_data->ref_count_ += 1; |
|||
return isolate_data; |
|||
} |
|||
|
|||
inline void Environment::IsolateData::Put() { |
|||
if (--ref_count_ == 0) { |
|||
isolate()->SetData(NULL); |
|||
delete this; |
|||
} |
|||
} |
|||
|
|||
inline Environment::IsolateData::IsolateData(v8::Isolate* isolate) |
|||
: event_loop_(uv_default_loop()) |
|||
, isolate_(isolate) |
|||
#define V(PropertyName, StringValue) \ |
|||
, PropertyName ## _index_( \ |
|||
FIXED_ONE_BYTE_STRING(isolate, StringValue).Eternalize(isolate)) |
|||
PER_ISOLATE_STRING_PROPERTIES(V) |
|||
#undef V |
|||
, ref_count_(0) { |
|||
} |
|||
|
|||
inline uv_loop_t* Environment::IsolateData::event_loop() const { |
|||
return event_loop_; |
|||
} |
|||
|
|||
inline v8::Isolate* Environment::IsolateData::isolate() const { |
|||
return isolate_; |
|||
} |
|||
|
|||
inline Environment::DomainFlag::DomainFlag() { |
|||
for (int i = 0; i < kFieldsCount; ++i) fields_[i] = 0; |
|||
} |
|||
|
|||
inline uint32_t* Environment::DomainFlag::fields() { |
|||
return fields_; |
|||
} |
|||
|
|||
inline int Environment::DomainFlag::fields_count() const { |
|||
return kFieldsCount; |
|||
} |
|||
|
|||
inline uint32_t Environment::DomainFlag::count() const { |
|||
return fields_[kCount]; |
|||
} |
|||
|
|||
inline Environment::TickInfo::TickInfo() { |
|||
for (int i = 0; i < kFieldsCount; ++i) fields_[i] = 0; |
|||
} |
|||
|
|||
inline uint32_t* Environment::TickInfo::fields() { |
|||
return fields_; |
|||
} |
|||
|
|||
inline int Environment::TickInfo::fields_count() const { |
|||
return kFieldsCount; |
|||
} |
|||
|
|||
inline uint32_t Environment::TickInfo::in_tick() const { |
|||
return fields_[kInTick]; |
|||
} |
|||
|
|||
inline uint32_t Environment::TickInfo::index() const { |
|||
return fields_[kIndex]; |
|||
} |
|||
|
|||
inline uint32_t Environment::TickInfo::last_threw() const { |
|||
return fields_[kLastThrew]; |
|||
} |
|||
|
|||
inline uint32_t Environment::TickInfo::length() const { |
|||
return fields_[kLength]; |
|||
} |
|||
|
|||
inline void Environment::TickInfo::set_index(uint32_t value) { |
|||
fields_[kIndex] = value; |
|||
} |
|||
|
|||
inline void Environment::TickInfo::set_last_threw(uint32_t value) { |
|||
fields_[kLastThrew] = value; |
|||
} |
|||
|
|||
inline Environment* Environment::New(v8::Local<v8::Context> context) { |
|||
Environment* env = new Environment(context); |
|||
context->SetAlignedPointerInEmbedderData(kContextEmbedderDataIndex, env); |
|||
return env; |
|||
} |
|||
|
|||
inline Environment* Environment::GetCurrent(v8::Isolate* isolate) { |
|||
return GetCurrent(isolate->GetCurrentContext()); |
|||
} |
|||
|
|||
inline Environment* Environment::GetCurrent(v8::Local<v8::Context> context) { |
|||
return static_cast<Environment*>( |
|||
context->GetAlignedPointerFromEmbedderData(kContextEmbedderDataIndex)); |
|||
} |
|||
|
|||
inline Environment* Environment::GetCurrentChecked(v8::Isolate* isolate) { |
|||
if (isolate == NULL) { |
|||
return NULL; |
|||
} else { |
|||
return GetCurrentChecked(isolate->GetCurrentContext()); |
|||
} |
|||
} |
|||
|
|||
inline Environment* Environment::GetCurrentChecked( |
|||
v8::Local<v8::Context> context) { |
|||
if (context.IsEmpty()) { |
|||
return NULL; |
|||
} else { |
|||
return GetCurrent(context); |
|||
} |
|||
} |
|||
|
|||
inline Environment::Environment(v8::Local<v8::Context> context) |
|||
: isolate_(context->GetIsolate()) |
|||
, isolate_data_(IsolateData::GetOrCreate(context->GetIsolate())) |
|||
, using_smalloc_alloc_cb_(false) |
|||
, using_domains_(false) |
|||
, context_(context->GetIsolate(), context) { |
|||
// We'll be creating new objects so make sure we've entered the context.
|
|||
v8::Context::Scope context_scope(context); |
|||
v8::HandleScope handle_scope(isolate()); |
|||
set_binding_cache_object(v8::Object::New()); |
|||
set_module_load_list_array(v8::Array::New()); |
|||
} |
|||
|
|||
inline Environment::~Environment() { |
|||
context()->SetAlignedPointerInEmbedderData(kContextEmbedderDataIndex, NULL); |
|||
#define V(PropertyName, TypeName) PropertyName ## _.Dispose(); |
|||
ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V) |
|||
#undef V |
|||
isolate_data()->Put(); |
|||
} |
|||
|
|||
inline void Environment::Dispose() { |
|||
delete this; |
|||
} |
|||
|
|||
inline v8::Isolate* Environment::isolate() const { |
|||
return isolate_; |
|||
} |
|||
|
|||
inline bool Environment::in_domain() const { |
|||
// The const_cast is okay, it doesn't violate conceptual const-ness.
|
|||
return using_domains() && |
|||
const_cast<Environment*>(this)->domain_flag()->count() > 0; |
|||
} |
|||
|
|||
inline Environment* Environment::from_immediate_check_handle( |
|||
uv_check_t* handle) { |
|||
return CONTAINER_OF(handle, Environment, immediate_check_handle_); |
|||
} |
|||
|
|||
inline uv_check_t* Environment::immediate_check_handle() { |
|||
return &immediate_check_handle_; |
|||
} |
|||
|
|||
inline uv_idle_t* Environment::immediate_idle_handle() { |
|||
return &immediate_idle_handle_; |
|||
} |
|||
|
|||
inline uv_loop_t* Environment::event_loop() const { |
|||
return isolate_data()->event_loop(); |
|||
} |
|||
|
|||
inline Environment::DomainFlag* Environment::domain_flag() { |
|||
return &domain_flag_; |
|||
} |
|||
|
|||
inline Environment::TickInfo* Environment::tick_info() { |
|||
return &tick_info_; |
|||
} |
|||
|
|||
inline bool Environment::using_smalloc_alloc_cb() const { |
|||
return using_smalloc_alloc_cb_; |
|||
} |
|||
|
|||
inline void Environment::set_using_smalloc_alloc_cb(bool value) { |
|||
using_smalloc_alloc_cb_ = value; |
|||
} |
|||
|
|||
inline bool Environment::using_domains() const { |
|||
return using_domains_; |
|||
} |
|||
|
|||
inline void Environment::set_using_domains(bool value) { |
|||
using_domains_ = value; |
|||
} |
|||
|
|||
inline Environment* Environment::from_cares_timer_handle(uv_timer_t* handle) { |
|||
return CONTAINER_OF(handle, Environment, cares_timer_handle_); |
|||
} |
|||
|
|||
inline uv_timer_t* Environment::cares_timer_handle() { |
|||
return &cares_timer_handle_; |
|||
} |
|||
|
|||
inline ares_channel Environment::cares_channel() { |
|||
return cares_channel_; |
|||
} |
|||
|
|||
// Only used in the call to ares_init_options().
|
|||
inline ares_channel* Environment::cares_channel_ptr() { |
|||
return &cares_channel_; |
|||
} |
|||
|
|||
inline ares_task_list* Environment::cares_task_list() { |
|||
return &cares_task_list_; |
|||
} |
|||
|
|||
inline Environment::IsolateData* Environment::isolate_data() const { |
|||
return isolate_data_; |
|||
} |
|||
|
|||
#define V(PropertyName, StringValue) \ |
|||
inline \ |
|||
v8::Local<v8::String> Environment::IsolateData::PropertyName() const { \ |
|||
return v8::Local<v8::String>::GetEternal(isolate(), \ |
|||
PropertyName ## _index_); \ |
|||
} |
|||
PER_ISOLATE_STRING_PROPERTIES(V) |
|||
#undef V |
|||
|
|||
#define V(PropertyName, StringValue) \ |
|||
inline v8::Local<v8::String> Environment::PropertyName() const { \ |
|||
return isolate_data()->PropertyName(); \ |
|||
} |
|||
PER_ISOLATE_STRING_PROPERTIES(V) |
|||
#undef V |
|||
|
|||
#define V(PropertyName, TypeName) \ |
|||
inline v8::Local<TypeName> Environment::PropertyName() const { \ |
|||
return StrongPersistentToLocal(PropertyName ## _); \ |
|||
} \ |
|||
inline void Environment::set_ ## PropertyName(v8::Local<TypeName> value) { \ |
|||
PropertyName ## _.Reset(isolate(), value); \ |
|||
} |
|||
ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V) |
|||
#undef V |
|||
|
|||
#undef ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES |
|||
#undef PER_ISOLATE_STRING_PROPERTIES |
|||
|
|||
} // namespace node
|
|||
|
|||
#endif // SRC_ENV_INL_H_
|
@ -0,0 +1,324 @@ |
|||
// Copyright Joyent, Inc. and other Node contributors.
|
|||
//
|
|||
// Permission is hereby granted, free of charge, to any person obtaining a
|
|||
// copy of this software and associated documentation files (the
|
|||
// "Software"), to deal in the Software without restriction, including
|
|||
// without limitation the rights to use, copy, modify, merge, publish,
|
|||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|||
// persons to whom the Software is furnished to do so, subject to the
|
|||
// following conditions:
|
|||
//
|
|||
// The above copyright notice and this permission notice shall be included
|
|||
// in all copies or substantial portions of the Software.
|
|||
//
|
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
|||
#ifndef SRC_ENV_H_ |
|||
#define SRC_ENV_H_ |
|||
|
|||
#include "ares.h" |
|||
#include "tree.h" |
|||
#include "util.h" |
|||
#include "uv.h" |
|||
#include "v8.h" |
|||
|
|||
#include <stdint.h> |
|||
|
|||
// Caveat emptor: we're going slightly crazy with macros here but the end
|
|||
// hopefully justifies the means. We have a lot of per-context properties
|
|||
// and adding and maintaining their getters and setters by hand would be
|
|||
// a nightmare so let's make the preprocessor generate them for us.
|
|||
//
|
|||
// Make sure that any macros defined here are undefined again at the bottom
|
|||
// of context-inl.h. The sole exception is NODE_CONTEXT_EMBEDDER_DATA_INDEX,
|
|||
// it may have been defined externally.
|
|||
namespace node { |
|||
|
|||
// Pick an index that's hopefully out of the way when we're embedded inside
|
|||
// another application. Performance-wise or memory-wise it doesn't matter:
|
|||
// Context::SetAlignedPointerInEmbedderData() is backed by a FixedArray,
|
|||
// worst case we pay a one-time penalty for resizing the array.
|
|||
#ifndef NODE_CONTEXT_EMBEDDER_DATA_INDEX |
|||
#define NODE_CONTEXT_EMBEDDER_DATA_INDEX 32 |
|||
#endif |
|||
|
|||
// Strings are per-isolate primitives but Environment proxies them
|
|||
// for the sake of convenience.
|
|||
#define PER_ISOLATE_STRING_PROPERTIES(V) \ |
|||
V(DELETE_string, "DELETE") \ |
|||
V(GET_string, "GET") \ |
|||
V(HEAD_string, "HEAD") \ |
|||
V(POST_string, "POST") \ |
|||
V(PUT_string, "PUT") \ |
|||
V(address_string, "address") \ |
|||
V(atime_string, "atime") \ |
|||
V(birthtime_string, "birthtime") \ |
|||
V(blksize_string, "blksize") \ |
|||
V(blocks_string, "blocks") \ |
|||
V(buffer_string, "buffer") \ |
|||
V(bytes_string, "bytes") \ |
|||
V(callback_string, "callback") \ |
|||
V(change_string, "change") \ |
|||
V(close_string, "close") \ |
|||
V(code_string, "code") \ |
|||
V(ctime_string, "ctime") \ |
|||
V(dev_string, "dev") \ |
|||
V(disposed_string, "_disposed") \ |
|||
V(domain_string, "domain") \ |
|||
V(enter_string, "enter") \ |
|||
V(errno_string, "errno") \ |
|||
V(exit_string, "exit") \ |
|||
V(exponent_string, "exponent") \ |
|||
V(exports_string, "exports") \ |
|||
V(ext_key_usage_string, "ext_key_usage") \ |
|||
V(family_string, "family") \ |
|||
V(fatal_exception_string, "_fatalException") \ |
|||
V(fingerprint_string, "fingerprint") \ |
|||
V(gid_string, "gid") \ |
|||
V(handle_string, "handle") \ |
|||
V(headers_string, "headers") \ |
|||
V(heap_total_string, "heapTotal") \ |
|||
V(heap_used_string, "heapUsed") \ |
|||
V(immediate_callback_string, "_immediateCallback") \ |
|||
V(ino_string, "ino") \ |
|||
V(ipv4_string, "IPv4") \ |
|||
V(ipv6_string, "IPv6") \ |
|||
V(issuer_string, "issuer") \ |
|||
V(method_string, "method") \ |
|||
V(mode_string, "mode") \ |
|||
V(modulus_string, "modulus") \ |
|||
V(mtime_string, "mtime") \ |
|||
V(name_string, "name") \ |
|||
V(nlink_string, "nlink") \ |
|||
V(onchange_string, "onchange") \ |
|||
V(onclienthello_string, "onclienthello") \ |
|||
V(oncomplete_string, "oncomplete") \ |
|||
V(onconnection_string, "onconnection") \ |
|||
V(onerror_string, "onerror") \ |
|||
V(onexit_string, "onexit") \ |
|||
V(onhandshakedone_string, "onhandshakedone") \ |
|||
V(onhandshakestart_string, "onhandshakestart") \ |
|||
V(onmessage_string, "onmessage") \ |
|||
V(onnewsession_string, "onnewsession") \ |
|||
V(onread_string, "onread") \ |
|||
V(onsignal_string, "onsignal") \ |
|||
V(onstop_string, "onstop") \ |
|||
V(path_string, "path") \ |
|||
V(port_string, "port") \ |
|||
V(rdev_string, "rdev") \ |
|||
V(rename_string, "rename") \ |
|||
V(rss_string, "rss") \ |
|||
V(servername_string, "servername") \ |
|||
V(session_id_string, "sessionId") \ |
|||
V(should_keep_alive_string, "shouldKeepAlive") \ |
|||
V(size_string, "size") \ |
|||
V(smalloc_p_string, "_smalloc_p") \ |
|||
V(sni_context_string, "sni_context") \ |
|||
V(status_code_string, "statusCode") \ |
|||
V(subject_string, "subject") \ |
|||
V(subjectaltname_string, "subjectaltname") \ |
|||
V(syscall_string, "syscall") \ |
|||
V(tls_ticket_string, "tlsTicket") \ |
|||
V(uid_string, "uid") \ |
|||
V(upgrade_string, "upgrade") \ |
|||
V(url_string, "url") \ |
|||
V(valid_from_string, "valid_from") \ |
|||
V(valid_to_string, "valid_to") \ |
|||
V(version_major_string, "versionMajor") \ |
|||
V(version_minor_string, "versionMinor") \ |
|||
V(version_string, "version") \ |
|||
V(write_queue_size_string, "writeQueueSize") \ |
|||
|
|||
#define ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V) \ |
|||
V(binding_cache_object, v8::Object) \ |
|||
V(buffer_constructor_function, v8::Function) \ |
|||
V(context, v8::Context) \ |
|||
V(domain_array, v8::Array) \ |
|||
V(module_load_list_array, v8::Array) \ |
|||
V(pipe_constructor_template, v8::FunctionTemplate) \ |
|||
V(process_object, v8::Object) \ |
|||
V(script_context_constructor_template, v8::FunctionTemplate) \ |
|||
V(script_data_constructor_function, v8::Function) \ |
|||
V(secure_context_constructor_template, v8::FunctionTemplate) \ |
|||
V(stats_constructor_function, v8::Function) \ |
|||
V(tcp_constructor_template, v8::FunctionTemplate) \ |
|||
V(tick_callback_function, v8::Function) \ |
|||
V(tls_wrap_constructor_function, v8::Function) \ |
|||
V(tty_constructor_template, v8::FunctionTemplate) \ |
|||
V(udp_constructor_function, v8::Function) \ |
|||
|
|||
class Environment; |
|||
|
|||
// TODO(bnoordhuis) Rename struct, the ares_ prefix implies it's part
|
|||
// of the c-ares API while the _t suffix implies it's a typedef.
|
|||
struct ares_task_t { |
|||
Environment* env; |
|||
ares_socket_t sock; |
|||
uv_poll_t poll_watcher; |
|||
RB_ENTRY(ares_task_t) node; |
|||
}; |
|||
|
|||
RB_HEAD(ares_task_list, ares_task_t); |
|||
|
|||
class Environment { |
|||
public: |
|||
class DomainFlag { |
|||
public: |
|||
inline uint32_t* fields(); |
|||
inline int fields_count() const; |
|||
inline uint32_t count() const; |
|||
|
|||
private: |
|||
friend class Environment; // So we can call the constructor.
|
|||
inline DomainFlag(); |
|||
|
|||
enum Fields { |
|||
kCount, |
|||
kFieldsCount |
|||
}; |
|||
|
|||
uint32_t fields_[kFieldsCount]; |
|||
|
|||
DISALLOW_COPY_AND_ASSIGN(DomainFlag); |
|||
}; |
|||
|
|||
class TickInfo { |
|||
public: |
|||
inline uint32_t* fields(); |
|||
inline int fields_count() const; |
|||
inline uint32_t in_tick() const; |
|||
inline uint32_t index() const; |
|||
inline uint32_t last_threw() const; |
|||
inline uint32_t length() const; |
|||
inline void set_index(uint32_t value); |
|||
inline void set_last_threw(uint32_t value); |
|||
|
|||
private: |
|||
friend class Environment; // So we can call the constructor.
|
|||
inline TickInfo(); |
|||
|
|||
enum Fields { |
|||
kInTick, |
|||
kIndex, |
|||
kLastThrew, |
|||
kLength, |
|||
kFieldsCount |
|||
}; |
|||
|
|||
uint32_t fields_[kFieldsCount]; |
|||
|
|||
DISALLOW_COPY_AND_ASSIGN(TickInfo); |
|||
}; |
|||
|
|||
static inline Environment* GetCurrent(v8::Isolate* isolate); |
|||
static inline Environment* GetCurrent(v8::Local<v8::Context> context); |
|||
static inline Environment* GetCurrentChecked(v8::Isolate* isolate); |
|||
static inline Environment* GetCurrentChecked(v8::Local<v8::Context> context); |
|||
|
|||
// See CreateEnvironment() in src/node.cc.
|
|||
static inline Environment* New(v8::Local<v8::Context> context); |
|||
inline void Dispose(); |
|||
|
|||
inline v8::Isolate* isolate() const; |
|||
inline uv_loop_t* event_loop() const; |
|||
inline bool in_domain() const; |
|||
|
|||
static inline Environment* from_immediate_check_handle(uv_check_t* handle); |
|||
inline uv_check_t* immediate_check_handle(); |
|||
inline uv_idle_t* immediate_idle_handle(); |
|||
inline DomainFlag* domain_flag(); |
|||
inline TickInfo* tick_info(); |
|||
|
|||
static inline Environment* from_cares_timer_handle(uv_timer_t* handle); |
|||
inline uv_timer_t* cares_timer_handle(); |
|||
inline ares_channel cares_channel(); |
|||
inline ares_channel* cares_channel_ptr(); |
|||
inline ares_task_list* cares_task_list(); |
|||
|
|||
inline bool using_smalloc_alloc_cb() const; |
|||
inline void set_using_smalloc_alloc_cb(bool value); |
|||
|
|||
inline bool using_domains() const; |
|||
inline void set_using_domains(bool value); |
|||
|
|||
// Strings are shared across shared contexts. The getters simply proxy to
|
|||
// the per-isolate primitive.
|
|||
#define V(PropertyName, StringValue) \ |
|||
inline v8::Local<v8::String> PropertyName() const; |
|||
PER_ISOLATE_STRING_PROPERTIES(V) |
|||
#undef V |
|||
|
|||
#define V(PropertyName, TypeName) \ |
|||
inline v8::Local<TypeName> PropertyName() const; \ |
|||
inline void set_ ## PropertyName(v8::Local<TypeName> value); |
|||
ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V) |
|||
#undef V |
|||
|
|||
private: |
|||
class IsolateData; |
|||
inline explicit Environment(v8::Local<v8::Context> context); |
|||
inline ~Environment(); |
|||
inline IsolateData* isolate_data() const; |
|||
|
|||
enum ContextEmbedderDataIndex { |
|||
kContextEmbedderDataIndex = NODE_CONTEXT_EMBEDDER_DATA_INDEX |
|||
}; |
|||
|
|||
v8::Isolate* const isolate_; |
|||
IsolateData* const isolate_data_; |
|||
uv_check_t immediate_check_handle_; |
|||
uv_idle_t immediate_idle_handle_; |
|||
DomainFlag domain_flag_; |
|||
TickInfo tick_info_; |
|||
uv_timer_t cares_timer_handle_; |
|||
ares_channel cares_channel_; |
|||
ares_task_list cares_task_list_; |
|||
bool using_smalloc_alloc_cb_; |
|||
bool using_domains_; |
|||
|
|||
#define V(PropertyName, TypeName) \ |
|||
v8::Persistent<TypeName> PropertyName ## _; |
|||
ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V) |
|||
#undef V |
|||
|
|||
// Per-thread, reference-counted singleton.
|
|||
class IsolateData { |
|||
public: |
|||
static inline IsolateData* GetOrCreate(v8::Isolate* isolate); |
|||
inline void Put(); |
|||
inline uv_loop_t* event_loop() const; |
|||
|
|||
#define V(PropertyName, StringValue) \ |
|||
inline v8::Local<v8::String> PropertyName() const; |
|||
PER_ISOLATE_STRING_PROPERTIES(V) |
|||
#undef V |
|||
|
|||
private: |
|||
inline explicit IsolateData(v8::Isolate* isolate); |
|||
inline v8::Isolate* isolate() const; |
|||
|
|||
uv_loop_t* const event_loop_; |
|||
v8::Isolate* const isolate_; |
|||
|
|||
#define V(PropertyName, StringValue) \ |
|||
const int PropertyName ## _index_; |
|||
PER_ISOLATE_STRING_PROPERTIES(V) |
|||
#undef V |
|||
|
|||
unsigned int ref_count_; |
|||
|
|||
DISALLOW_COPY_AND_ASSIGN(IsolateData); |
|||
}; |
|||
|
|||
DISALLOW_COPY_AND_ASSIGN(Environment); |
|||
}; |
|||
|
|||
} // namespace node
|
|||
|
|||
#endif // SRC_ENV_H_
|
File diff suppressed because it is too large
@ -0,0 +1,83 @@ |
|||
// Copyright Joyent, Inc. and other Node contributors.
|
|||
//
|
|||
// Permission is hereby granted, free of charge, to any person obtaining a
|
|||
// copy of this software and associated documentation files (the
|
|||
// "Software"), to deal in the Software without restriction, including
|
|||
// without limitation the rights to use, copy, modify, merge, publish,
|
|||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|||
// persons to whom the Software is furnished to do so, subject to the
|
|||
// following conditions:
|
|||
//
|
|||
// The above copyright notice and this permission notice shall be included
|
|||
// in all copies or substantial portions of the Software.
|
|||
//
|
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
|||
#ifndef SRC_UTIL_INL_H_ |
|||
#define SRC_UTIL_INL_H_ |
|||
|
|||
#include "util.h" |
|||
|
|||
namespace node { |
|||
|
|||
template <class TypeName> |
|||
inline v8::Local<TypeName> PersistentToLocal( |
|||
v8::Isolate* isolate, |
|||
const v8::Persistent<TypeName>& persistent) { |
|||
if (persistent.IsWeak()) { |
|||
return WeakPersistentToLocal(isolate, persistent); |
|||
} else { |
|||
return StrongPersistentToLocal(persistent); |
|||
} |
|||
} |
|||
|
|||
template <class TypeName> |
|||
inline v8::Local<TypeName> StrongPersistentToLocal( |
|||
const v8::Persistent<TypeName>& persistent) { |
|||
return *reinterpret_cast<v8::Local<TypeName>*>( |
|||
const_cast<v8::Persistent<TypeName>*>(&persistent)); |
|||
} |
|||
|
|||
template <class TypeName> |
|||
inline v8::Local<TypeName> WeakPersistentToLocal( |
|||
v8::Isolate* isolate, |
|||
const v8::Persistent<TypeName>& persistent) { |
|||
return v8::Local<TypeName>::New(isolate, persistent); |
|||
} |
|||
|
|||
inline v8::Local<v8::String> OneByteString(v8::Isolate* isolate, |
|||
const char* data, |
|||
int length) { |
|||
return v8::String::NewFromOneByte(isolate, |
|||
reinterpret_cast<const uint8_t*>(data), |
|||
v8::String::kNormalString, |
|||
length); |
|||
} |
|||
|
|||
inline v8::Local<v8::String> OneByteString(v8::Isolate* isolate, |
|||
const signed char* data, |
|||
int length) { |
|||
return v8::String::NewFromOneByte(isolate, |
|||
reinterpret_cast<const uint8_t*>(data), |
|||
v8::String::kNormalString, |
|||
length); |
|||
} |
|||
|
|||
inline v8::Local<v8::String> OneByteString(v8::Isolate* isolate, |
|||
const unsigned char* data, |
|||
int length) { |
|||
return v8::String::NewFromOneByte(isolate, |
|||
reinterpret_cast<const uint8_t*>(data), |
|||
v8::String::kNormalString, |
|||
length); |
|||
} |
|||
|
|||
} // namespace node
|
|||
|
|||
#endif // SRC_UTIL_INL_H_
|
@ -0,0 +1,82 @@ |
|||
// Copyright Joyent, Inc. and other Node contributors.
|
|||
//
|
|||
// Permission is hereby granted, free of charge, to any person obtaining a
|
|||
// copy of this software and associated documentation files (the
|
|||
// "Software"), to deal in the Software without restriction, including
|
|||
// without limitation the rights to use, copy, modify, merge, publish,
|
|||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|||
// persons to whom the Software is furnished to do so, subject to the
|
|||
// following conditions:
|
|||
//
|
|||
// The above copyright notice and this permission notice shall be included
|
|||
// in all copies or substantial portions of the Software.
|
|||
//
|
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
|||
#ifndef SRC_UTIL_H_ |
|||
#define SRC_UTIL_H_ |
|||
|
|||
#include "v8.h" |
|||
#include <stddef.h> |
|||
|
|||
namespace node { |
|||
|
|||
#define OFFSET_OF(TypeName, Field) \ |
|||
(reinterpret_cast<uintptr_t>(&(reinterpret_cast<TypeName*>(8)->Field)) - 8) |
|||
|
|||
#define CONTAINER_OF(Pointer, TypeName, Field) \ |
|||
reinterpret_cast<TypeName*>( \ |
|||
reinterpret_cast<uintptr_t>(Pointer) - OFFSET_OF(TypeName, Field)) |
|||
|
|||
#define FIXED_ONE_BYTE_STRING(isolate, string) \ |
|||
(node::OneByteString((isolate), (string), sizeof(string) - 1)) |
|||
|
|||
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ |
|||
void operator=(const TypeName&); \ |
|||
TypeName(const TypeName&) |
|||
|
|||
// 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.
|
|||
template <class TypeName> |
|||
inline v8::Local<TypeName> PersistentToLocal( |
|||
v8::Isolate* isolate, |
|||
const v8::Persistent<TypeName>& persistent); |
|||
|
|||
// Unchecked conversion from a non-weak Persistent<T> to Local<TLocal<T>,
|
|||
// use with care!
|
|||
//
|
|||
// Do not call persistent.Dispose() while the returned Local<T> is still in
|
|||
// scope, it will destroy the reference to the object.
|
|||
template <class TypeName> |
|||
inline v8::Local<TypeName> StrongPersistentToLocal( |
|||
const v8::Persistent<TypeName>& persistent); |
|||
|
|||
template <class TypeName> |
|||
inline v8::Local<TypeName> WeakPersistentToLocal( |
|||
v8::Isolate* isolate, |
|||
const v8::Persistent<TypeName>& persistent); |
|||
|
|||
// Convenience wrapper around v8::String::NewFromOneByte().
|
|||
inline v8::Local<v8::String> OneByteString(v8::Isolate* isolate, |
|||
const char* data, |
|||
int length = -1); |
|||
|
|||
// For the people that compile with -funsigned-char.
|
|||
inline v8::Local<v8::String> OneByteString(v8::Isolate* isolate, |
|||
const signed char* data, |
|||
int length = -1); |
|||
|
|||
inline v8::Local<v8::String> OneByteString(v8::Isolate* isolate, |
|||
const unsigned char* data, |
|||
int length = -1); |
|||
|
|||
} // namespace node
|
|||
|
|||
#endif // SRC_UTIL_H_
|
Loading…
Reference in new issue