Node.js  v8.x
Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine
env-inl.h
Go to the documentation of this file.
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 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
26 
27 #include "env.h"
28 #include "node.h"
29 #include "util.h"
30 #include "util-inl.h"
31 #include "uv.h"
32 #include "v8.h"
33 
34 #include <stddef.h>
35 #include <stdint.h>
36 
37 namespace node {
38 
39 inline IsolateData::IsolateData(v8::Isolate* isolate, uv_loop_t* event_loop,
40  uint32_t* zero_fill_field) :
41 
42 // Create string and private symbol properties as internalized one byte strings.
43 //
44 // Internalized because it makes property lookups a little faster and because
45 // the string is created in the old space straight away. It's going to end up
46 // in the old space sooner or later anyway but now it doesn't go through
47 // v8::Eternal's new space handling first.
48 //
49 // One byte because our strings are ASCII and we can safely skip V8's UTF-8
50 // decoding step. It's a one-time cost, but why pay it when you don't have to?
51 #define V(PropertyName, StringValue) \
52  PropertyName ## _( \
53  isolate, \
54  v8::Private::New( \
55  isolate, \
56  v8::String::NewFromOneByte( \
57  isolate, \
58  reinterpret_cast<const uint8_t*>(StringValue), \
59  v8::NewStringType::kInternalized, \
60  sizeof(StringValue) - 1).ToLocalChecked())),
61  PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(V)
62 #undef V
63 #define V(PropertyName, StringValue) \
64  PropertyName ## _( \
65  isolate, \
66  v8::String::NewFromOneByte( \
67  isolate, \
68  reinterpret_cast<const uint8_t*>(StringValue), \
69  v8::NewStringType::kInternalized, \
70  sizeof(StringValue) - 1).ToLocalChecked()),
71  PER_ISOLATE_STRING_PROPERTIES(V)
72 #undef V
73  event_loop_(event_loop), zero_fill_field_(zero_fill_field) {}
74 
75 inline uv_loop_t* IsolateData::event_loop() const {
76  return event_loop_;
77 }
78 
79 inline uint32_t* IsolateData::zero_fill_field() const {
80  return zero_fill_field_;
81 }
82 
83 inline Environment::AsyncHooks::AsyncHooks(v8::Isolate* isolate)
84  : isolate_(isolate),
85  fields_(),
86  uid_fields_() {
87  v8::HandleScope handle_scope(isolate_);
88 
89  // kAsyncUidCntr should start at 1 because that'll be the id the execution
90  // context during bootstrap (code that runs before entering uv_run()).
91  uid_fields_[AsyncHooks::kAsyncUidCntr] = 1;
92 
93  // Create all the provider strings that will be passed to JS. Place them in
94  // an array so the array index matches the PROVIDER id offset. This way the
95  // strings can be retrieved quickly.
96 #define V(Provider) \
97  providers_[AsyncWrap::PROVIDER_ ## Provider].Set( \
98  isolate_, \
99  v8::String::NewFromOneByte( \
100  isolate_, \
101  reinterpret_cast<const uint8_t*>(#Provider), \
102  v8::NewStringType::kInternalized, \
103  sizeof(#Provider) - 1).ToLocalChecked());
104  NODE_ASYNC_PROVIDER_TYPES(V)
105 #undef V
106 }
107 
108 inline uint32_t* Environment::AsyncHooks::fields() {
109  return fields_;
110 }
111 
112 inline int Environment::AsyncHooks::fields_count() const {
113  return kFieldsCount;
114 }
115 
116 inline double* Environment::AsyncHooks::uid_fields() {
117  return uid_fields_;
118 }
119 
120 inline int Environment::AsyncHooks::uid_fields_count() const {
121  return kUidFieldsCount;
122 }
123 
124 inline v8::Local<v8::String> Environment::AsyncHooks::provider_string(int idx) {
125  return providers_[idx].Get(isolate_);
126 }
127 
128 inline void Environment::AsyncHooks::push_ids(double async_id,
129  double trigger_id) {
130  CHECK_GE(async_id, -1);
131  CHECK_GE(trigger_id, -1);
132 
133  ids_stack_.push({ uid_fields_[kCurrentAsyncId],
134  uid_fields_[kCurrentTriggerId] });
135  uid_fields_[kCurrentAsyncId] = async_id;
136  uid_fields_[kCurrentTriggerId] = trigger_id;
137 }
138 
139 inline bool Environment::AsyncHooks::pop_ids(double async_id) {
140  // In case of an exception then this may have already been reset, if the
141  // stack was multiple MakeCallback()'s deep.
142  if (ids_stack_.empty()) return false;
143 
144  // Ask for the async_id to be restored as a sanity check that the stack
145  // hasn't been corrupted.
146  if (uid_fields_[kCurrentAsyncId] != async_id) {
147  fprintf(stderr,
148  "Error: async hook stack has become corrupted ("
149  "actual: %.f, expected: %.f)\n",
150  uid_fields_[kCurrentAsyncId],
151  async_id);
152  Environment* env = Environment::GetCurrent(isolate_);
153  DumpBacktrace(stderr);
154  fflush(stderr);
155  if (!env->abort_on_uncaught_exception())
156  exit(1);
157  fprintf(stderr, "\n");
158  fflush(stderr);
159  ABORT_NO_BACKTRACE();
160  }
161 
162  auto ids = ids_stack_.top();
163  ids_stack_.pop();
164  uid_fields_[kCurrentAsyncId] = ids.async_id;
165  uid_fields_[kCurrentTriggerId] = ids.trigger_id;
166  return !ids_stack_.empty();
167 }
168 
169 inline size_t Environment::AsyncHooks::stack_size() {
170  return ids_stack_.size();
171 }
172 
173 inline void Environment::AsyncHooks::clear_id_stack() {
174  while (!ids_stack_.empty())
175  ids_stack_.pop();
176  uid_fields_[kCurrentAsyncId] = 0;
177  uid_fields_[kCurrentTriggerId] = 0;
178 }
179 
180 inline Environment::AsyncHooks::InitScope::InitScope(
181  Environment* env, double init_trigger_id)
182  : env_(env),
183  uid_fields_ref_(env->async_hooks()->uid_fields()) {
184  CHECK_GE(init_trigger_id, -1);
185  env->async_hooks()->push_ids(uid_fields_ref_[AsyncHooks::kCurrentAsyncId],
186  init_trigger_id);
187 }
188 
189 inline Environment::AsyncHooks::InitScope::~InitScope() {
190  env_->async_hooks()->pop_ids(uid_fields_ref_[AsyncHooks::kCurrentAsyncId]);
191 }
192 
193 inline Environment::AsyncHooks::ExecScope::ExecScope(
194  Environment* env, double async_id, double trigger_id)
195  : env_(env),
196  async_id_(async_id),
197  disposed_(false) {
198  CHECK_GE(async_id, -1);
199  CHECK_GE(trigger_id, -1);
200  env->async_hooks()->push_ids(async_id, trigger_id);
201 }
202 
203 inline Environment::AsyncHooks::ExecScope::~ExecScope() {
204  if (disposed_) return;
205  Dispose();
206 }
207 
208 inline void Environment::AsyncHooks::ExecScope::Dispose() {
209  disposed_ = true;
210  env_->async_hooks()->pop_ids(async_id_);
211 }
212 
213 inline Environment::AsyncCallbackScope::AsyncCallbackScope(Environment* env)
214  : env_(env) {
215  env_->makecallback_cntr_++;
216 }
217 
218 inline Environment::AsyncCallbackScope::~AsyncCallbackScope() {
219  env_->makecallback_cntr_--;
220 }
221 
222 inline bool Environment::AsyncCallbackScope::in_makecallback() {
223  return env_->makecallback_cntr_ > 1;
224 }
225 
226 inline Environment::DomainFlag::DomainFlag() {
227  for (int i = 0; i < kFieldsCount; ++i) fields_[i] = 0;
228 }
229 
230 inline uint32_t* Environment::DomainFlag::fields() {
231  return fields_;
232 }
233 
234 inline int Environment::DomainFlag::fields_count() const {
235  return kFieldsCount;
236 }
237 
238 inline uint32_t Environment::DomainFlag::count() const {
239  return fields_[kCount];
240 }
241 
242 inline Environment::TickInfo::TickInfo() {
243  for (int i = 0; i < kFieldsCount; ++i)
244  fields_[i] = 0;
245 }
246 
247 inline uint32_t* Environment::TickInfo::fields() {
248  return fields_;
249 }
250 
251 inline int Environment::TickInfo::fields_count() const {
252  return kFieldsCount;
253 }
254 
255 inline uint32_t Environment::TickInfo::index() const {
256  return fields_[kIndex];
257 }
258 
259 inline uint32_t Environment::TickInfo::length() const {
260  return fields_[kLength];
261 }
262 
263 inline void Environment::TickInfo::set_index(uint32_t value) {
264  fields_[kIndex] = value;
265 }
266 
267 inline void Environment::AssignToContext(v8::Local<v8::Context> context) {
268  context->SetAlignedPointerInEmbedderData(kContextEmbedderDataIndex, this);
269 #if HAVE_INSPECTOR
270  inspector_agent()->ContextCreated(context);
271 #endif // HAVE_INSPECTOR
272 }
273 
274 inline Environment* Environment::GetCurrent(v8::Isolate* isolate) {
275  return GetCurrent(isolate->GetCurrentContext());
276 }
277 
278 inline Environment* Environment::GetCurrent(v8::Local<v8::Context> context) {
279  return static_cast<Environment*>(
280  context->GetAlignedPointerFromEmbedderData(kContextEmbedderDataIndex));
281 }
282 
283 inline Environment* Environment::GetCurrent(
284  const v8::FunctionCallbackInfo<v8::Value>& info) {
285  CHECK(info.Data()->IsExternal());
286  return static_cast<Environment*>(info.Data().As<v8::External>()->Value());
287 }
288 
289 template <typename T>
290 inline Environment* Environment::GetCurrent(
291  const v8::PropertyCallbackInfo<T>& info) {
292  CHECK(info.Data()->IsExternal());
293  return static_cast<Environment*>(
294  info.Data().template As<v8::External>()->Value());
295 }
296 
297 inline Environment::Environment(IsolateData* isolate_data,
298  v8::Local<v8::Context> context)
299  : isolate_(context->GetIsolate()),
300  isolate_data_(isolate_data),
301  async_hooks_(context->GetIsolate()),
302  timer_base_(uv_now(isolate_data->event_loop())),
303  using_domains_(false),
304  printed_error_(false),
305  trace_sync_io_(false),
306  abort_on_uncaught_exception_(false),
307  makecallback_cntr_(0),
308 #if HAVE_INSPECTOR
309  inspector_agent_(this),
310 #endif
311  handle_cleanup_waiting_(0),
312  http_parser_buffer_(nullptr),
313  fs_stats_field_array_(nullptr),
314  context_(context->GetIsolate(), context) {
315  // We'll be creating new objects so make sure we've entered the context.
316  v8::HandleScope handle_scope(isolate());
317  v8::Context::Scope context_scope(context);
318  set_as_external(v8::External::New(isolate(), this));
319  set_binding_cache_object(v8::Object::New(isolate()));
320  set_module_load_list_array(v8::Array::New(isolate()));
321 
322  AssignToContext(context);
323 
324  destroy_ids_list_.reserve(512);
325  performance_state_ = Calloc<performance::performance_state>(1);
326  performance_state_->milestones[
327  performance::NODE_PERFORMANCE_MILESTONE_ENVIRONMENT] =
328  PERFORMANCE_NOW();
329  performance_state_->milestones[
330  performance::NODE_PERFORMANCE_MILESTONE_NODE_START] =
332  performance_state_->milestones[
333  performance::NODE_PERFORMANCE_MILESTONE_V8_START] =
335 }
336 
337 inline Environment::~Environment() {
338  v8::HandleScope handle_scope(isolate());
339 
340  context()->SetAlignedPointerInEmbedderData(kContextEmbedderDataIndex,
341  nullptr);
342 #define V(PropertyName, TypeName) PropertyName ## _.Reset();
343  ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V)
344 #undef V
345 
346  delete[] heap_statistics_buffer_;
347  delete[] heap_space_statistics_buffer_;
348  delete[] http_parser_buffer_;
349  free(http2_state_buffer_);
350  free(performance_state_);
351 }
352 
353 inline v8::Isolate* Environment::isolate() const {
354  return isolate_;
355 }
356 
357 inline bool Environment::in_domain() const {
358  // The const_cast is okay, it doesn't violate conceptual const-ness.
359  return using_domains() &&
360  const_cast<Environment*>(this)->domain_flag()->count() > 0;
361 }
362 
363 inline Environment* Environment::from_immediate_check_handle(
364  uv_check_t* handle) {
365  return ContainerOf(&Environment::immediate_check_handle_, handle);
366 }
367 
368 inline uv_check_t* Environment::immediate_check_handle() {
369  return &immediate_check_handle_;
370 }
371 
372 inline uv_idle_t* Environment::immediate_idle_handle() {
373  return &immediate_idle_handle_;
374 }
375 
376 inline Environment* Environment::from_destroy_ids_timer_handle(
377  uv_timer_t* handle) {
378  return ContainerOf(&Environment::destroy_ids_timer_handle_, handle);
379 }
380 
381 inline uv_timer_t* Environment::destroy_ids_timer_handle() {
382  return &destroy_ids_timer_handle_;
383 }
384 
385 inline void Environment::RegisterHandleCleanup(uv_handle_t* handle,
386  HandleCleanupCb cb,
387  void *arg) {
388  handle_cleanup_queue_.PushBack(new HandleCleanup(handle, cb, arg));
389 }
390 
391 inline void Environment::FinishHandleCleanup(uv_handle_t* handle) {
392  handle_cleanup_waiting_--;
393 }
394 
395 inline uv_loop_t* Environment::event_loop() const {
396  return isolate_data()->event_loop();
397 }
398 
399 inline Environment::AsyncHooks* Environment::async_hooks() {
400  return &async_hooks_;
401 }
402 
403 inline Environment::DomainFlag* Environment::domain_flag() {
404  return &domain_flag_;
405 }
406 
407 inline Environment::TickInfo* Environment::tick_info() {
408  return &tick_info_;
409 }
410 
411 inline uint64_t Environment::timer_base() const {
412  return timer_base_;
413 }
414 
415 inline bool Environment::using_domains() const {
416  return using_domains_;
417 }
418 
419 inline void Environment::set_using_domains(bool value) {
420  using_domains_ = value;
421 }
422 
423 inline bool Environment::printed_error() const {
424  return printed_error_;
425 }
426 
427 inline void Environment::set_printed_error(bool value) {
428  printed_error_ = value;
429 }
430 
431 inline void Environment::set_trace_sync_io(bool value) {
432  trace_sync_io_ = value;
433 }
434 
435 inline bool Environment::abort_on_uncaught_exception() const {
436  return abort_on_uncaught_exception_;
437 }
438 
439 inline void Environment::set_abort_on_uncaught_exception(bool value) {
440  abort_on_uncaught_exception_ = value;
441 }
442 
443 inline std::vector<double>* Environment::destroy_ids_list() {
444  return &destroy_ids_list_;
445 }
446 
447 inline double Environment::new_async_id() {
448  return ++async_hooks()->uid_fields()[AsyncHooks::kAsyncUidCntr];
449 }
450 
451 inline double Environment::current_async_id() {
452  return async_hooks()->uid_fields()[AsyncHooks::kCurrentAsyncId];
453 }
454 
455 inline double Environment::trigger_id() {
456  return async_hooks()->uid_fields()[AsyncHooks::kCurrentTriggerId];
457 }
458 
459 inline double Environment::get_init_trigger_id() {
460  double* uid_fields = async_hooks()->uid_fields();
461  double tid = uid_fields[AsyncHooks::kInitTriggerId];
462  uid_fields[AsyncHooks::kInitTriggerId] = 0;
463  if (tid <= 0) tid = current_async_id();
464  return tid;
465 }
466 
467 inline void Environment::set_init_trigger_id(const double id) {
468  async_hooks()->uid_fields()[AsyncHooks::kInitTriggerId] = id;
469 }
470 
471 inline double* Environment::heap_statistics_buffer() const {
472  CHECK_NE(heap_statistics_buffer_, nullptr);
473  return heap_statistics_buffer_;
474 }
475 
476 inline void Environment::set_heap_statistics_buffer(double* pointer) {
477  CHECK_EQ(heap_statistics_buffer_, nullptr); // Should be set only once.
478  heap_statistics_buffer_ = pointer;
479 }
480 
481 inline double* Environment::heap_space_statistics_buffer() const {
482  CHECK_NE(heap_space_statistics_buffer_, nullptr);
483  return heap_space_statistics_buffer_;
484 }
485 
486 inline void Environment::set_heap_space_statistics_buffer(double* pointer) {
487  CHECK_EQ(heap_space_statistics_buffer_, nullptr); // Should be set only once.
488  heap_space_statistics_buffer_ = pointer;
489 }
490 
491 inline char* Environment::http_parser_buffer() const {
492  return http_parser_buffer_;
493 }
494 
495 inline void Environment::set_http_parser_buffer(char* buffer) {
496  CHECK_EQ(http_parser_buffer_, nullptr); // Should be set only once.
497  http_parser_buffer_ = buffer;
498 }
499 
500 inline http2::http2_state* Environment::http2_state_buffer() const {
501  return http2_state_buffer_;
502 }
503 
504 inline void Environment::set_http2_state_buffer(http2::http2_state* buffer) {
505  CHECK_EQ(http2_state_buffer_, nullptr); // Should be set only once.
506  http2_state_buffer_ = buffer;
507 }
508 
509 inline double* Environment::fs_stats_field_array() const {
510  return fs_stats_field_array_;
511 }
512 
513 inline void Environment::set_fs_stats_field_array(double* fields) {
514  CHECK_EQ(fs_stats_field_array_, nullptr); // Should be set only once.
515  fs_stats_field_array_ = fields;
516 }
517 
518 inline performance::performance_state* Environment::performance_state() {
519  return performance_state_;
520 }
521 
522 inline std::map<std::string, uint64_t>* Environment::performance_marks() {
523  return &performance_marks_;
524 }
525 
526 inline Environment* Environment::from_performance_check_handle(
527  uv_check_t* handle) {
528  return ContainerOf(&Environment::performance_check_handle_, handle);
529 }
530 
531 inline Environment* Environment::from_performance_idle_handle(
532  uv_idle_t* handle) {
533  return ContainerOf(&Environment::performance_idle_handle_, handle);
534 }
535 
536 inline Environment* Environment::from_performance_prepare_handle(
537  uv_prepare_t* handle) {
538  return ContainerOf(&Environment::performance_prepare_handle_, handle);
539 }
540 
541 inline uv_check_t* Environment::performance_check_handle() {
542  return &performance_check_handle_;
543 }
544 
545 inline uv_idle_t* Environment::performance_idle_handle() {
546  return &performance_idle_handle_;
547 }
548 
549 inline uv_prepare_t* Environment::performance_prepare_handle() {
550  return &performance_prepare_handle_;
551 }
552 
553 inline IsolateData* Environment::isolate_data() const {
554  return isolate_data_;
555 }
556 
557 inline void Environment::ThrowError(const char* errmsg) {
558  ThrowError(v8::Exception::Error, errmsg);
559 }
560 
561 inline void Environment::ThrowTypeError(const char* errmsg) {
562  ThrowError(v8::Exception::TypeError, errmsg);
563 }
564 
565 inline void Environment::ThrowRangeError(const char* errmsg) {
566  ThrowError(v8::Exception::RangeError, errmsg);
567 }
568 
569 inline void Environment::ThrowError(
570  v8::Local<v8::Value> (*fun)(v8::Local<v8::String>),
571  const char* errmsg) {
572  v8::HandleScope handle_scope(isolate());
573  isolate()->ThrowException(fun(OneByteString(isolate(), errmsg)));
574 }
575 
576 inline void Environment::ThrowErrnoException(int errorno,
577  const char* syscall,
578  const char* message,
579  const char* path) {
580  isolate()->ThrowException(
581  ErrnoException(isolate(), errorno, syscall, message, path));
582 }
583 
584 inline void Environment::ThrowUVException(int errorno,
585  const char* syscall,
586  const char* message,
587  const char* path,
588  const char* dest) {
589  isolate()->ThrowException(
590  UVException(isolate(), errorno, syscall, message, path, dest));
591 }
592 
593 inline v8::Local<v8::FunctionTemplate>
594  Environment::NewFunctionTemplate(v8::FunctionCallback callback,
595  v8::Local<v8::Signature> signature) {
596  v8::Local<v8::External> external = as_external();
597  return v8::FunctionTemplate::New(isolate(), callback, external, signature);
598 }
599 
600 inline void Environment::SetMethod(v8::Local<v8::Object> that,
601  const char* name,
602  v8::FunctionCallback callback) {
603  v8::Local<v8::Function> function =
604  NewFunctionTemplate(callback)->GetFunction();
605  // kInternalized strings are created in the old space.
606  const v8::NewStringType type = v8::NewStringType::kInternalized;
607  v8::Local<v8::String> name_string =
608  v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
609  that->Set(name_string, function);
610  function->SetName(name_string); // NODE_SET_METHOD() compatibility.
611 }
612 
613 inline void Environment::SetProtoMethod(v8::Local<v8::FunctionTemplate> that,
614  const char* name,
615  v8::FunctionCallback callback) {
616  v8::Local<v8::Signature> signature = v8::Signature::New(isolate(), that);
617  v8::Local<v8::FunctionTemplate> t = NewFunctionTemplate(callback, signature);
618  // kInternalized strings are created in the old space.
619  const v8::NewStringType type = v8::NewStringType::kInternalized;
620  v8::Local<v8::String> name_string =
621  v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
622  that->PrototypeTemplate()->Set(name_string, t);
623  t->SetClassName(name_string); // NODE_SET_PROTOTYPE_METHOD() compatibility.
624 }
625 
626 inline void Environment::SetTemplateMethod(v8::Local<v8::FunctionTemplate> that,
627  const char* name,
628  v8::FunctionCallback callback) {
629  v8::Local<v8::FunctionTemplate> t = NewFunctionTemplate(callback);
630  // kInternalized strings are created in the old space.
631  const v8::NewStringType type = v8::NewStringType::kInternalized;
632  v8::Local<v8::String> name_string =
633  v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
634  that->Set(name_string, t);
635  t->SetClassName(name_string); // NODE_SET_METHOD() compatibility.
636 }
637 
638 #define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
639 #define VS(PropertyName, StringValue) V(v8::String, PropertyName)
640 #define V(TypeName, PropertyName) \
641  inline \
642  v8::Local<TypeName> IsolateData::PropertyName(v8::Isolate* isolate) const { \
643  /* Strings are immutable so casting away const-ness here is okay. */ \
644  return const_cast<IsolateData*>(this)->PropertyName ## _.Get(isolate); \
645  }
646  PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
647  PER_ISOLATE_STRING_PROPERTIES(VS)
648 #undef V
649 #undef VS
650 #undef VP
651 
652 #define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
653 #define VS(PropertyName, StringValue) V(v8::String, PropertyName)
654 #define V(TypeName, PropertyName) \
655  inline v8::Local<TypeName> Environment::PropertyName() const { \
656  return isolate_data()->PropertyName(isolate()); \
657  }
658  PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
659  PER_ISOLATE_STRING_PROPERTIES(VS)
660 #undef V
661 #undef VS
662 #undef VP
663 
664 #define V(PropertyName, TypeName) \
665  inline v8::Local<TypeName> Environment::PropertyName() const { \
666  return StrongPersistentToLocal(PropertyName ## _); \
667  } \
668  inline void Environment::set_ ## PropertyName(v8::Local<TypeName> value) { \
669  PropertyName ## _.Reset(isolate(), value); \
670  }
671  ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V)
672 #undef V
673 
674 } // namespace node
675 
676 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
677 
678 #endif // SRC_ENV_INL_H_
uint64_t performance_v8_start
Definition: node_perf.cc:32
Environment *const env_
#define PERFORMANCE_NOW()
Persistent< Context > context_
Local< Value > ErrnoException(Isolate *isolate, int errorno, const char *syscall, const char *msg, const char *path)
Definition: node.cc:879
dtrace t
Definition: v8ustack.d:582
#define V(PROVIDER)
double async_id
Definition: node.h:541
void DumpBacktrace(FILE *fp)
MaybeLocal< Object > New(Isolate *isolate, Local< String > string, enum encoding enc)
Definition: node_buffer.cc:241
node::Environment::AsyncHooks AsyncHooks
Definition: async-wrap.cc:60
StringPtr fields_[32]
uint64_t performance_node_start
Definition: node_perf.cc:31
Local< Value > UVException(Isolate *isolate, int errorno, const char *syscall, const char *msg, const char *path)
Definition: node.cc:940