1 // Copyright Joyent, Inc. and other Node contributors.
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to permit
8 // persons to whom the Software is furnished to do so, subject to the
9 // following conditions:
11 // The above copyright notice and this permission notice shall be included
12 // in all copies or substantial portions of the Software.
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 // USE OR OTHER DEALINGS IN THE SOFTWARE.
22 #ifndef SRC_ENV_INL_H_
23 #define SRC_ENV_INL_H_
36 inline Environment::IsolateData* Environment::IsolateData::GetOrCreate(
37 v8::Isolate* isolate) {
38 IsolateData* isolate_data = static_cast<IsolateData*>(isolate->GetData());
39 if (isolate_data == NULL) {
40 isolate_data = new IsolateData(isolate);
41 isolate->SetData(isolate_data);
43 isolate_data->ref_count_ += 1;
47 inline void Environment::IsolateData::Put() {
48 if (--ref_count_ == 0) {
49 isolate()->SetData(NULL);
54 inline Environment::IsolateData::IsolateData(v8::Isolate* isolate)
55 : event_loop_(uv_default_loop()),
57 #define V(PropertyName, StringValue) \
58 PropertyName ## _(isolate, FIXED_ONE_BYTE_STRING(isolate, StringValue)),
59 PER_ISOLATE_STRING_PROPERTIES(V)
64 inline uv_loop_t* Environment::IsolateData::event_loop() const {
68 inline v8::Isolate* Environment::IsolateData::isolate() const {
72 inline Environment::AsyncListener::AsyncListener() {
73 for (int i = 0; i < kFieldsCount; ++i)
77 inline uint32_t* Environment::AsyncListener::fields() {
81 inline int Environment::AsyncListener::fields_count() const {
85 inline uint32_t Environment::AsyncListener::count() const {
86 return fields_[kCount];
89 inline Environment::TickInfo::TickInfo() : in_tick_(false), last_threw_(false) {
90 for (int i = 0; i < kFieldsCount; ++i)
94 inline uint32_t* Environment::TickInfo::fields() {
98 inline int Environment::TickInfo::fields_count() const {
102 inline bool Environment::TickInfo::in_tick() const {
106 inline uint32_t Environment::TickInfo::index() const {
107 return fields_[kIndex];
110 inline bool Environment::TickInfo::last_threw() const {
114 inline uint32_t Environment::TickInfo::length() const {
115 return fields_[kLength];
118 inline void Environment::TickInfo::set_in_tick(bool value) {
122 inline void Environment::TickInfo::set_index(uint32_t value) {
123 fields_[kIndex] = value;
126 inline void Environment::TickInfo::set_last_threw(bool value) {
130 inline Environment* Environment::New(v8::Local<v8::Context> context) {
131 Environment* env = new Environment(context);
132 context->SetAlignedPointerInEmbedderData(kContextEmbedderDataIndex, env);
136 inline Environment* Environment::GetCurrent(v8::Isolate* isolate) {
137 return GetCurrent(isolate->GetCurrentContext());
140 inline Environment* Environment::GetCurrent(v8::Local<v8::Context> context) {
141 return static_cast<Environment*>(
142 context->GetAlignedPointerFromEmbedderData(kContextEmbedderDataIndex));
145 inline Environment* Environment::GetCurrentChecked(v8::Isolate* isolate) {
146 if (isolate == NULL) {
149 return GetCurrentChecked(isolate->GetCurrentContext());
153 inline Environment* Environment::GetCurrentChecked(
154 v8::Local<v8::Context> context) {
155 if (context.IsEmpty()) {
158 return GetCurrent(context);
162 inline Environment::Environment(v8::Local<v8::Context> context)
163 : isolate_(context->GetIsolate()),
164 isolate_data_(IsolateData::GetOrCreate(context->GetIsolate())),
165 using_smalloc_alloc_cb_(false),
166 context_(context->GetIsolate(), context) {
167 // We'll be creating new objects so make sure we've entered the context.
168 v8::HandleScope handle_scope(isolate());
169 v8::Context::Scope context_scope(context);
170 set_binding_cache_object(v8::Object::New());
171 set_module_load_list_array(v8::Array::New());
172 RB_INIT(&cares_task_list_);
175 inline Environment::~Environment() {
176 context()->SetAlignedPointerInEmbedderData(kContextEmbedderDataIndex, NULL);
177 #define V(PropertyName, TypeName) PropertyName ## _.Dispose();
178 ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V)
180 isolate_data()->Put();
183 inline void Environment::Dispose() {
187 inline v8::Isolate* Environment::isolate() const {
191 inline bool Environment::has_async_listeners() const {
192 // The const_cast is okay, it doesn't violate conceptual const-ness.
193 return const_cast<Environment*>(this)->async_listener()->count() > 0;
196 inline Environment* Environment::from_immediate_check_handle(
197 uv_check_t* handle) {
198 return CONTAINER_OF(handle, Environment, immediate_check_handle_);
201 inline uv_check_t* Environment::immediate_check_handle() {
202 return &immediate_check_handle_;
205 inline uv_idle_t* Environment::immediate_idle_handle() {
206 return &immediate_idle_handle_;
209 inline Environment* Environment::from_idle_prepare_handle(
210 uv_prepare_t* handle) {
211 return CONTAINER_OF(handle, Environment, idle_prepare_handle_);
214 inline uv_prepare_t* Environment::idle_prepare_handle() {
215 return &idle_prepare_handle_;
218 inline Environment* Environment::from_idle_check_handle(uv_check_t* handle) {
219 return CONTAINER_OF(handle, Environment, idle_check_handle_);
222 inline uv_check_t* Environment::idle_check_handle() {
223 return &idle_check_handle_;
226 inline uv_loop_t* Environment::event_loop() const {
227 return isolate_data()->event_loop();
230 inline Environment::AsyncListener* Environment::async_listener() {
231 return &async_listener_count_;
234 inline Environment::TickInfo* Environment::tick_info() {
238 inline bool Environment::using_smalloc_alloc_cb() const {
239 return using_smalloc_alloc_cb_;
242 inline void Environment::set_using_smalloc_alloc_cb(bool value) {
243 using_smalloc_alloc_cb_ = value;
246 inline Environment* Environment::from_cares_timer_handle(uv_timer_t* handle) {
247 return CONTAINER_OF(handle, Environment, cares_timer_handle_);
250 inline uv_timer_t* Environment::cares_timer_handle() {
251 return &cares_timer_handle_;
254 inline ares_channel Environment::cares_channel() {
255 return cares_channel_;
258 // Only used in the call to ares_init_options().
259 inline ares_channel* Environment::cares_channel_ptr() {
260 return &cares_channel_;
263 inline ares_task_list* Environment::cares_task_list() {
264 return &cares_task_list_;
267 inline Environment::IsolateData* Environment::isolate_data() const {
268 return isolate_data_;
271 #define V(PropertyName, StringValue) \
273 v8::Local<v8::String> Environment::IsolateData::PropertyName() const { \
274 /* Strings are immutable so casting away const-ness here is okay. */ \
275 return const_cast<IsolateData*>(this)->PropertyName ## _.Get(isolate()); \
277 PER_ISOLATE_STRING_PROPERTIES(V)
280 #define V(PropertyName, StringValue) \
281 inline v8::Local<v8::String> Environment::PropertyName() const { \
282 return isolate_data()->PropertyName(); \
284 PER_ISOLATE_STRING_PROPERTIES(V)
287 #define V(PropertyName, TypeName) \
288 inline v8::Local<TypeName> Environment::PropertyName() const { \
289 return StrongPersistentToLocal(PropertyName ## _); \
291 inline void Environment::set_ ## PropertyName(v8::Local<TypeName> value) { \
292 PropertyName ## _.Reset(isolate(), value); \
294 ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V)
297 #undef ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES
298 #undef PER_ISOLATE_STRING_PROPERTIES
302 #endif // SRC_ENV_INL_H_