src: update after v8 api changes
[platform/upstream/nodejs.git] / src / env-inl.h
1 // Copyright Joyent, Inc. and other Node contributors.
2 //
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:
10 //
11 // The above copyright notice and this permission notice shall be included
12 // in all copies or substantial portions of the Software.
13 //
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.
21
22 #ifndef SRC_ENV_INL_H_
23 #define SRC_ENV_INL_H_
24
25 #include "env.h"
26 #include "util.h"
27 #include "util-inl.h"
28 #include "uv.h"
29 #include "v8.h"
30
31 #include <stddef.h>
32 #include <stdint.h>
33
34 namespace node {
35
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);
42   }
43   isolate_data->ref_count_ += 1;
44   return isolate_data;
45 }
46
47 inline void Environment::IsolateData::Put() {
48   if (--ref_count_ == 0) {
49     isolate()->SetData(NULL);
50     delete this;
51   }
52 }
53
54 inline Environment::IsolateData::IsolateData(v8::Isolate* isolate)
55     : event_loop_(uv_default_loop()),
56       isolate_(isolate),
57 #define V(PropertyName, StringValue)                                          \
58     PropertyName ## _(isolate, FIXED_ONE_BYTE_STRING(isolate, StringValue)),
59     PER_ISOLATE_STRING_PROPERTIES(V)
60 #undef V
61     ref_count_(0) {
62 }
63
64 inline uv_loop_t* Environment::IsolateData::event_loop() const {
65   return event_loop_;
66 }
67
68 inline v8::Isolate* Environment::IsolateData::isolate() const {
69   return isolate_;
70 }
71
72 inline Environment::DomainFlag::DomainFlag() {
73   for (int i = 0; i < kFieldsCount; ++i) fields_[i] = 0;
74 }
75
76 inline uint32_t* Environment::DomainFlag::fields() {
77   return fields_;
78 }
79
80 inline int Environment::DomainFlag::fields_count() const {
81   return kFieldsCount;
82 }
83
84 inline uint32_t Environment::DomainFlag::count() const {
85   return fields_[kCount];
86 }
87
88 inline Environment::TickInfo::TickInfo() {
89   for (int i = 0; i < kFieldsCount; ++i) fields_[i] = 0;
90 }
91
92 inline uint32_t* Environment::TickInfo::fields() {
93   return fields_;
94 }
95
96 inline int Environment::TickInfo::fields_count() const {
97   return kFieldsCount;
98 }
99
100 inline uint32_t Environment::TickInfo::in_tick() const {
101   return fields_[kInTick];
102 }
103
104 inline uint32_t Environment::TickInfo::index() const {
105   return fields_[kIndex];
106 }
107
108 inline uint32_t Environment::TickInfo::last_threw() const {
109   return fields_[kLastThrew];
110 }
111
112 inline uint32_t Environment::TickInfo::length() const {
113   return fields_[kLength];
114 }
115
116 inline void Environment::TickInfo::set_index(uint32_t value) {
117   fields_[kIndex] = value;
118 }
119
120 inline void Environment::TickInfo::set_last_threw(uint32_t value) {
121   fields_[kLastThrew] = value;
122 }
123
124 inline Environment* Environment::New(v8::Local<v8::Context> context) {
125   Environment* env = new Environment(context);
126   context->SetAlignedPointerInEmbedderData(kContextEmbedderDataIndex, env);
127   return env;
128 }
129
130 inline Environment* Environment::GetCurrent(v8::Isolate* isolate) {
131   return GetCurrent(isolate->GetCurrentContext());
132 }
133
134 inline Environment* Environment::GetCurrent(v8::Local<v8::Context> context) {
135   return static_cast<Environment*>(
136       context->GetAlignedPointerFromEmbedderData(kContextEmbedderDataIndex));
137 }
138
139 inline Environment* Environment::GetCurrentChecked(v8::Isolate* isolate) {
140   if (isolate == NULL) {
141     return NULL;
142   } else {
143     return GetCurrentChecked(isolate->GetCurrentContext());
144   }
145 }
146
147 inline Environment* Environment::GetCurrentChecked(
148     v8::Local<v8::Context> context) {
149   if (context.IsEmpty()) {
150     return NULL;
151   } else {
152     return GetCurrent(context);
153   }
154 }
155
156 inline Environment::Environment(v8::Local<v8::Context> context)
157     : isolate_(context->GetIsolate()),
158       isolate_data_(IsolateData::GetOrCreate(context->GetIsolate())),
159       using_smalloc_alloc_cb_(false),
160       using_domains_(false),
161       context_(context->GetIsolate(), context) {
162   // We'll be creating new objects so make sure we've entered the context.
163   v8::Context::Scope context_scope(context);
164   v8::HandleScope handle_scope(isolate());
165   set_binding_cache_object(v8::Object::New());
166   set_module_load_list_array(v8::Array::New());
167   RB_INIT(&cares_task_list_);
168 }
169
170 inline Environment::~Environment() {
171   context()->SetAlignedPointerInEmbedderData(kContextEmbedderDataIndex, NULL);
172 #define V(PropertyName, TypeName) PropertyName ## _.Dispose();
173   ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V)
174 #undef V
175   isolate_data()->Put();
176 }
177
178 inline void Environment::Dispose() {
179   delete this;
180 }
181
182 inline v8::Isolate* Environment::isolate() const {
183   return isolate_;
184 }
185
186 inline bool Environment::in_domain() const {
187   // The const_cast is okay, it doesn't violate conceptual const-ness.
188   return using_domains() &&
189          const_cast<Environment*>(this)->domain_flag()->count() > 0;
190 }
191
192 inline Environment* Environment::from_immediate_check_handle(
193     uv_check_t* handle) {
194   return CONTAINER_OF(handle, Environment, immediate_check_handle_);
195 }
196
197 inline uv_check_t* Environment::immediate_check_handle() {
198   return &immediate_check_handle_;
199 }
200
201 inline uv_idle_t* Environment::immediate_idle_handle() {
202   return &immediate_idle_handle_;
203 }
204
205 inline Environment* Environment::from_idle_prepare_handle(
206     uv_prepare_t* handle) {
207   return CONTAINER_OF(handle, Environment, idle_prepare_handle_);
208 }
209
210 inline uv_prepare_t* Environment::idle_prepare_handle() {
211   return &idle_prepare_handle_;
212 }
213
214 inline Environment* Environment::from_idle_check_handle(uv_check_t* handle) {
215   return CONTAINER_OF(handle, Environment, idle_check_handle_);
216 }
217
218 inline uv_check_t* Environment::idle_check_handle() {
219   return &idle_check_handle_;
220 }
221
222 inline uv_loop_t* Environment::event_loop() const {
223   return isolate_data()->event_loop();
224 }
225
226 inline Environment::DomainFlag* Environment::domain_flag() {
227   return &domain_flag_;
228 }
229
230 inline Environment::TickInfo* Environment::tick_info() {
231   return &tick_info_;
232 }
233
234 inline bool Environment::using_smalloc_alloc_cb() const {
235   return using_smalloc_alloc_cb_;
236 }
237
238 inline void Environment::set_using_smalloc_alloc_cb(bool value) {
239   using_smalloc_alloc_cb_ = value;
240 }
241
242 inline bool Environment::using_domains() const {
243   return using_domains_;
244 }
245
246 inline void Environment::set_using_domains(bool value) {
247   using_domains_ = value;
248 }
249
250 inline Environment* Environment::from_cares_timer_handle(uv_timer_t* handle) {
251   return CONTAINER_OF(handle, Environment, cares_timer_handle_);
252 }
253
254 inline uv_timer_t* Environment::cares_timer_handle() {
255   return &cares_timer_handle_;
256 }
257
258 inline ares_channel Environment::cares_channel() {
259   return cares_channel_;
260 }
261
262 // Only used in the call to ares_init_options().
263 inline ares_channel* Environment::cares_channel_ptr() {
264   return &cares_channel_;
265 }
266
267 inline ares_task_list* Environment::cares_task_list() {
268   return &cares_task_list_;
269 }
270
271 inline Environment::IsolateData* Environment::isolate_data() const {
272   return isolate_data_;
273 }
274
275 #define V(PropertyName, StringValue)                                          \
276   inline                                                                      \
277   v8::Local<v8::String> Environment::IsolateData::PropertyName() const {      \
278     /* Strings are immutable so casting away const-ness here is okay. */      \
279     return const_cast<IsolateData*>(this)->PropertyName ## _.Get(isolate());  \
280   }
281   PER_ISOLATE_STRING_PROPERTIES(V)
282 #undef V
283
284 #define V(PropertyName, StringValue)                                          \
285   inline v8::Local<v8::String> Environment::PropertyName() const {            \
286     return isolate_data()->PropertyName();                                    \
287   }
288   PER_ISOLATE_STRING_PROPERTIES(V)
289 #undef V
290
291 #define V(PropertyName, TypeName)                                             \
292   inline v8::Local<TypeName> Environment::PropertyName() const {              \
293     return StrongPersistentToLocal(PropertyName ## _);                        \
294   }                                                                           \
295   inline void Environment::set_ ## PropertyName(v8::Local<TypeName> value) {  \
296     PropertyName ## _.Reset(isolate(), value);                                \
297   }
298   ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V)
299 #undef V
300
301 #undef ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES
302 #undef PER_ISOLATE_STRING_PROPERTIES
303
304 }  // namespace node
305
306 #endif  // SRC_ENV_INL_H_