GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
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 "aliased_buffer.h" |
||
28 |
#include "callback_queue-inl.h" |
||
29 |
#include "env.h" |
||
30 |
#include "node.h" |
||
31 |
#include "util-inl.h" |
||
32 |
#include "uv.h" |
||
33 |
#include "v8.h" |
||
34 |
#include "node_perf_common.h" |
||
35 |
#include "node_context_data.h" |
||
36 |
|||
37 |
#include <cstddef> |
||
38 |
#include <cstdint> |
||
39 |
|||
40 |
#include <utility> |
||
41 |
|||
42 |
namespace node { |
||
43 |
|||
44 |
inline v8::Isolate* IsolateData::isolate() const { |
||
45 |
return isolate_; |
||
46 |
} |
||
47 |
|||
48 |
851699 |
inline uv_loop_t* IsolateData::event_loop() const { |
|
49 |
851699 |
return event_loop_; |
|
50 |
} |
||
51 |
|||
52 |
656893 |
inline NodeArrayBufferAllocator* IsolateData::node_allocator() const { |
|
53 |
656893 |
return node_allocator_; |
|
54 |
} |
||
55 |
|||
56 |
28446 |
inline MultiIsolatePlatform* IsolateData::platform() const { |
|
57 |
28446 |
return platform_; |
|
58 |
} |
||
59 |
|||
60 |
405 |
inline void IsolateData::set_worker_context(worker::Worker* context) { |
|
61 |
✗✓ | 405 |
CHECK_NULL(worker_context_); // Should be set only once. |
62 |
405 |
worker_context_ = context; |
|
63 |
405 |
} |
|
64 |
|||
65 |
12198 |
inline worker::Worker* IsolateData::worker_context() const { |
|
66 |
12198 |
return worker_context_; |
|
67 |
} |
||
68 |
|||
69 |
216654 |
inline v8::Local<v8::String> IsolateData::async_wrap_provider(int index) const { |
|
70 |
433308 |
return async_wrap_providers_[index].Get(isolate_); |
|
71 |
} |
||
72 |
|||
73 |
4429562 |
inline AliasedUint32Array& AsyncHooks::fields() { |
|
74 |
4429562 |
return fields_; |
|
75 |
} |
||
76 |
|||
77 |
2499554 |
inline AliasedFloat64Array& AsyncHooks::async_id_fields() { |
|
78 |
2499554 |
return async_id_fields_; |
|
79 |
} |
||
80 |
|||
81 |
444 |
inline AliasedFloat64Array& AsyncHooks::async_ids_stack() { |
|
82 |
444 |
return async_ids_stack_; |
|
83 |
} |
||
84 |
|||
85 |
1357940 |
v8::Local<v8::Array> AsyncHooks::js_execution_async_resources() { |
|
86 |
✓✓ | 2715880 |
if (UNLIKELY(js_execution_async_resources_.IsEmpty())) { |
87 |
444 |
js_execution_async_resources_.Reset( |
|
88 |
888 |
env()->isolate(), v8::Array::New(env()->isolate())); |
|
89 |
} |
||
90 |
1357940 |
return PersistentToLocal::Strong(js_execution_async_resources_); |
|
91 |
} |
||
92 |
|||
93 |
278 |
v8::Local<v8::Object> AsyncHooks::native_execution_async_resource(size_t i) { |
|
94 |
✗✓ | 278 |
if (i >= native_execution_async_resources_.size()) return {}; |
95 |
278 |
return PersistentToLocal::Strong(native_execution_async_resources_[i]); |
|
96 |
} |
||
97 |
|||
98 |
216190 |
inline v8::Local<v8::String> AsyncHooks::provider_string(int idx) { |
|
99 |
216190 |
return env()->isolate_data()->async_wrap_provider(idx); |
|
100 |
} |
||
101 |
|||
102 |
1 |
inline void AsyncHooks::no_force_checks() { |
|
103 |
1 |
fields_[kCheck] -= 1; |
|
104 |
1 |
} |
|
105 |
|||
106 |
1853568 |
inline Environment* AsyncHooks::env() { |
|
107 |
1853568 |
return Environment::ForAsyncHooks(this); |
|
108 |
} |
||
109 |
|||
110 |
// Remember to keep this code aligned with pushAsyncContext() in JS. |
||
111 |
1267574 |
inline void AsyncHooks::push_async_context(double async_id, |
|
112 |
double trigger_async_id, |
||
113 |
v8::Local<v8::Object> resource) { |
||
114 |
// Since async_hooks is experimental, do only perform the check |
||
115 |
// when async_hooks is enabled. |
||
116 |
✓✓ | 1267574 |
if (fields_[kCheck] > 0) { |
117 |
✗✓ | 1267488 |
CHECK_GE(async_id, -1); |
118 |
✗✓ | 1267488 |
CHECK_GE(trigger_async_id, -1); |
119 |
} |
||
120 |
|||
121 |
1267563 |
uint32_t offset = fields_[kStackLength]; |
|
122 |
✓✓ | 1267520 |
if (offset * 2 >= async_ids_stack_.Length()) |
123 |
10 |
grow_async_ids_stack(); |
|
124 |
1267506 |
async_ids_stack_[2 * offset] = async_id_fields_[kExecutionAsyncId]; |
|
125 |
1267398 |
async_ids_stack_[2 * offset + 1] = async_id_fields_[kTriggerAsyncId]; |
|
126 |
1267453 |
fields_[kStackLength] += 1; |
|
127 |
1267479 |
async_id_fields_[kExecutionAsyncId] = async_id; |
|
128 |
1267517 |
async_id_fields_[kTriggerAsyncId] = trigger_async_id; |
|
129 |
|||
130 |
#ifdef DEBUG |
||
131 |
for (uint32_t i = offset; i < native_execution_async_resources_.size(); i++) |
||
132 |
CHECK(native_execution_async_resources_[i].IsEmpty()); |
||
133 |
#endif |
||
134 |
|||
135 |
// When this call comes from JS (as a way of increasing the stack size), |
||
136 |
// `resource` will be empty, because JS caches these values anyway, and |
||
137 |
// we should avoid creating strong global references that might keep |
||
138 |
// these JS resource objects alive longer than necessary. |
||
139 |
✓✗ | 1267486 |
if (!resource.IsEmpty()) { |
140 |
1267492 |
native_execution_async_resources_.resize(offset + 1); |
|
141 |
1267153 |
native_execution_async_resources_[offset].Reset(env()->isolate(), resource); |
|
142 |
} |
||
143 |
1267525 |
} |
|
144 |
|||
145 |
// Remember to keep this code aligned with popAsyncContext() in JS. |
||
146 |
1267089 |
inline bool AsyncHooks::pop_async_context(double async_id) { |
|
147 |
// In case of an exception then this may have already been reset, if the |
||
148 |
// stack was multiple MakeCallback()'s deep. |
||
149 |
✓✓ | 1267089 |
if (fields_[kStackLength] == 0) return false; |
150 |
|||
151 |
// Ask for the async_id to be restored as a check that the stack |
||
152 |
// hasn't been corrupted. |
||
153 |
// Since async_hooks is experimental, do only perform the check |
||
154 |
// when async_hooks is enabled. |
||
155 |
✓✗✓✓ ✓✓ |
1266066 |
if (fields_[kCheck] > 0 && async_id_fields_[kExecutionAsyncId] != async_id) { |
156 |
4 |
fprintf(stderr, |
|
157 |
"Error: async hook stack has become corrupted (" |
||
158 |
"actual: %.f, expected: %.f)\n", |
||
159 |
async_id_fields_.GetValue(kExecutionAsyncId), |
||
160 |
4 |
async_id); |
|
161 |
4 |
DumpBacktrace(stderr); |
|
162 |
4 |
fflush(stderr); |
|
163 |
✓✗ | 4 |
if (!env()->abort_on_uncaught_exception()) |
164 |
4 |
exit(1); |
|
165 |
fprintf(stderr, "\n"); |
||
166 |
fflush(stderr); |
||
167 |
ABORT_NO_BACKTRACE(); |
||
168 |
} |
||
169 |
|||
170 |
1266034 |
uint32_t offset = fields_[kStackLength] - 1; |
|
171 |
1266041 |
async_id_fields_[kExecutionAsyncId] = async_ids_stack_[2 * offset]; |
|
172 |
1266044 |
async_id_fields_[kTriggerAsyncId] = async_ids_stack_[2 * offset + 1]; |
|
173 |
1266081 |
fields_[kStackLength] = offset; |
|
174 |
|||
175 |
✓✓✓✗ ✓✓ |
2532141 |
if (LIKELY(offset < native_execution_async_resources_.size() && |
176 |
!native_execution_async_resources_[offset].IsEmpty())) { |
||
177 |
#ifdef DEBUG |
||
178 |
for (uint32_t i = offset + 1; |
||
179 |
i < native_execution_async_resources_.size(); |
||
180 |
i++) { |
||
181 |
CHECK(native_execution_async_resources_[i].IsEmpty()); |
||
182 |
} |
||
183 |
#endif |
||
184 |
1266063 |
native_execution_async_resources_.resize(offset); |
|
185 |
✗✓ | 2532328 |
if (native_execution_async_resources_.size() < |
186 |
✓✓✗✓ |
1492949 |
native_execution_async_resources_.capacity() / 2 && |
187 |
226786 |
native_execution_async_resources_.size() > 16) { |
|
188 |
native_execution_async_resources_.shrink_to_fit(); |
||
189 |
} |
||
190 |
} |
||
191 |
|||
192 |
✓✓ | 2532303 |
if (UNLIKELY(js_execution_async_resources()->Length() > offset)) { |
193 |
182682 |
v8::HandleScope handle_scope(env()->isolate()); |
|
194 |
274023 |
USE(js_execution_async_resources()->Set( |
|
195 |
env()->context(), |
||
196 |
env()->length_string(), |
||
197 |
456705 |
v8::Integer::NewFromUnsigned(env()->isolate(), offset))); |
|
198 |
} |
||
199 |
|||
200 |
1266155 |
return fields_[kStackLength] > 0; |
|
201 |
} |
||
202 |
|||
203 |
1718 |
void AsyncHooks::clear_async_id_stack() { |
|
204 |
1718 |
v8::Isolate* isolate = env()->isolate(); |
|
205 |
3436 |
v8::HandleScope handle_scope(isolate); |
|
206 |
✓✓ | 3436 |
if (!js_execution_async_resources_.IsEmpty()) { |
207 |
3822 |
USE(PersistentToLocal::Strong(js_execution_async_resources_)->Set( |
|
208 |
env()->context(), |
||
209 |
env()->length_string(), |
||
210 |
6370 |
v8::Integer::NewFromUnsigned(isolate, 0))); |
|
211 |
} |
||
212 |
1718 |
native_execution_async_resources_.clear(); |
|
213 |
1718 |
native_execution_async_resources_.shrink_to_fit(); |
|
214 |
|||
215 |
1718 |
async_id_fields_[kExecutionAsyncId] = 0; |
|
216 |
1718 |
async_id_fields_[kTriggerAsyncId] = 0; |
|
217 |
1718 |
fields_[kStackLength] = 0; |
|
218 |
1718 |
} |
|
219 |
|||
220 |
// The DefaultTriggerAsyncIdScope(AsyncWrap*) constructor is defined in |
||
221 |
// async_wrap-inl.h to avoid a circular dependency. |
||
222 |
|||
223 |
512006 |
inline AsyncHooks::DefaultTriggerAsyncIdScope ::DefaultTriggerAsyncIdScope( |
|
224 |
512006 |
Environment* env, double default_trigger_async_id) |
|
225 |
512006 |
: async_hooks_(env->async_hooks()) { |
|
226 |
✓✗ | 512006 |
if (env->async_hooks()->fields()[AsyncHooks::kCheck] > 0) { |
227 |
✗✓ | 512006 |
CHECK_GE(default_trigger_async_id, 0); |
228 |
} |
||
229 |
|||
230 |
512006 |
old_default_trigger_async_id_ = |
|
231 |
1024012 |
async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId]; |
|
232 |
512006 |
async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId] = |
|
233 |
512006 |
default_trigger_async_id; |
|
234 |
512006 |
} |
|
235 |
|||
236 |
1024010 |
inline AsyncHooks::DefaultTriggerAsyncIdScope ::~DefaultTriggerAsyncIdScope() { |
|
237 |
512005 |
async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId] = |
|
238 |
1024010 |
old_default_trigger_async_id_; |
|
239 |
512005 |
} |
|
240 |
|||
241 |
1853519 |
Environment* Environment::ForAsyncHooks(AsyncHooks* hooks) { |
|
242 |
1853519 |
return ContainerOf(&Environment::async_hooks_, hooks); |
|
243 |
} |
||
244 |
|||
245 |
1256560 |
inline size_t Environment::async_callback_scope_depth() const { |
|
246 |
1256560 |
return async_callback_scope_depth_; |
|
247 |
} |
||
248 |
|||
249 |
1267130 |
inline void Environment::PushAsyncCallbackScope() { |
|
250 |
1267130 |
async_callback_scope_depth_++; |
|
251 |
1267130 |
} |
|
252 |
|||
253 |
1266892 |
inline void Environment::PopAsyncCallbackScope() { |
|
254 |
1266892 |
async_callback_scope_depth_--; |
|
255 |
1266892 |
} |
|
256 |
|||
257 |
444 |
inline AliasedUint32Array& ImmediateInfo::fields() { |
|
258 |
444 |
return fields_; |
|
259 |
} |
||
260 |
|||
261 |
481747 |
inline uint32_t ImmediateInfo::count() const { |
|
262 |
481747 |
return fields_[kCount]; |
|
263 |
} |
||
264 |
|||
265 |
635429 |
inline uint32_t ImmediateInfo::ref_count() const { |
|
266 |
635429 |
return fields_[kRefCount]; |
|
267 |
} |
||
268 |
|||
269 |
107631 |
inline bool ImmediateInfo::has_outstanding() const { |
|
270 |
107631 |
return fields_[kHasOutstanding] == 1; |
|
271 |
} |
||
272 |
|||
273 |
33411 |
inline void ImmediateInfo::ref_count_inc(uint32_t increment) { |
|
274 |
33411 |
fields_[kRefCount] += increment; |
|
275 |
33411 |
} |
|
276 |
|||
277 |
495325 |
inline void ImmediateInfo::ref_count_dec(uint32_t decrement) { |
|
278 |
495325 |
fields_[kRefCount] -= decrement; |
|
279 |
495327 |
} |
|
280 |
|||
281 |
444 |
inline AliasedUint8Array& TickInfo::fields() { |
|
282 |
444 |
return fields_; |
|
283 |
} |
||
284 |
|||
285 |
2348298 |
inline bool TickInfo::has_tick_scheduled() const { |
|
286 |
2348298 |
return fields_[kHasTickScheduled] == 1; |
|
287 |
} |
||
288 |
|||
289 |
761039 |
inline bool TickInfo::has_rejection_to_warn() const { |
|
290 |
761039 |
return fields_[kHasRejectionToWarn] == 1; |
|
291 |
} |
||
292 |
|||
293 |
5595 |
inline void Environment::AssignToContext(v8::Local<v8::Context> context, |
|
294 |
const ContextInfo& info) { |
||
295 |
5595 |
context->SetAlignedPointerInEmbedderData( |
|
296 |
5595 |
ContextEmbedderIndex::kEnvironment, this); |
|
297 |
// Used by Environment::GetCurrent to know that we are on a node context. |
||
298 |
11190 |
context->SetAlignedPointerInEmbedderData( |
|
299 |
5595 |
ContextEmbedderIndex::kContextTag, Environment::kNodeContextTagPtr); |
|
300 |
// Used to retrieve bindings |
||
301 |
5595 |
context->SetAlignedPointerInEmbedderData( |
|
302 |
11190 |
ContextEmbedderIndex::kBindingListIndex, &(this->bindings_)); |
|
303 |
|||
304 |
#if HAVE_INSPECTOR |
||
305 |
5595 |
inspector_agent()->ContextCreated(context, info); |
|
306 |
#endif // HAVE_INSPECTOR |
||
307 |
5595 |
} |
|
308 |
|||
309 |
1306938 |
inline Environment* Environment::GetCurrent(v8::Isolate* isolate) { |
|
310 |
✓✓ | 1306938 |
if (UNLIKELY(!isolate->InContext())) return nullptr; |
311 |
2609937 |
v8::HandleScope handle_scope(isolate); |
|
312 |
1304909 |
return GetCurrent(isolate->GetCurrentContext()); |
|
313 |
} |
||
314 |
|||
315 |
6727406 |
inline Environment* Environment::GetCurrent(v8::Local<v8::Context> context) { |
|
316 |
✓✓ | 6727406 |
if (UNLIKELY(context.IsEmpty())) { |
317 |
1 |
return nullptr; |
|
318 |
} |
||
319 |
✓✓ | 6727405 |
if (UNLIKELY(context->GetNumberOfEmbedderDataFields() <= |
320 |
ContextEmbedderIndex::kContextTag)) { |
||
321 |
11 |
return nullptr; |
|
322 |
} |
||
323 |
✗✓ | 13455594 |
if (UNLIKELY(context->GetAlignedPointerFromEmbedderData( |
324 |
ContextEmbedderIndex::kContextTag) != |
||
325 |
Environment::kNodeContextTagPtr)) { |
||
326 |
return nullptr; |
||
327 |
} |
||
328 |
return static_cast<Environment*>( |
||
329 |
6727797 |
context->GetAlignedPointerFromEmbedderData( |
|
330 |
6727797 |
ContextEmbedderIndex::kEnvironment)); |
|
331 |
} |
||
332 |
|||
333 |
3746109 |
inline Environment* Environment::GetCurrent( |
|
334 |
const v8::FunctionCallbackInfo<v8::Value>& info) { |
||
335 |
3746109 |
return GetCurrent(info.GetIsolate()->GetCurrentContext()); |
|
336 |
} |
||
337 |
|||
338 |
template <typename T> |
||
339 |
1273710 |
inline Environment* Environment::GetCurrent( |
|
340 |
const v8::PropertyCallbackInfo<T>& info) { |
||
341 |
1273710 |
return GetCurrent(info.GetIsolate()->GetCurrentContext()); |
|
342 |
} |
||
343 |
|||
344 |
template <typename T, typename U> |
||
345 |
inline T* Environment::GetBindingData(const v8::PropertyCallbackInfo<U>& info) { |
||
346 |
return GetBindingData<T>(info.GetIsolate()->GetCurrentContext()); |
||
347 |
} |
||
348 |
|||
349 |
template <typename T> |
||
350 |
669851 |
inline T* Environment::GetBindingData( |
|
351 |
const v8::FunctionCallbackInfo<v8::Value>& info) { |
||
352 |
669851 |
return GetBindingData<T>(info.GetIsolate()->GetCurrentContext()); |
|
353 |
} |
||
354 |
|||
355 |
template <typename T> |
||
356 |
669853 |
inline T* Environment::GetBindingData(v8::Local<v8::Context> context) { |
|
357 |
BindingDataStore* map = static_cast<BindingDataStore*>( |
||
358 |
669853 |
context->GetAlignedPointerFromEmbedderData( |
|
359 |
669853 |
ContextEmbedderIndex::kBindingListIndex)); |
|
360 |
DCHECK_NOT_NULL(map); |
||
361 |
669853 |
auto it = map->find(T::type_name); |
|
362 |
✗✓ | 669853 |
if (UNLIKELY(it == map->end())) return nullptr; |
363 |
669851 |
T* result = static_cast<T*>(it->second.get()); |
|
364 |
DCHECK_NOT_NULL(result); |
||
365 |
DCHECK_EQ(result->env(), GetCurrent(context)); |
||
366 |
669851 |
return result; |
|
367 |
} |
||
368 |
|||
369 |
template <typename T> |
||
370 |
6655 |
inline T* Environment::AddBindingData( |
|
371 |
v8::Local<v8::Context> context, |
||
372 |
v8::Local<v8::Object> target) { |
||
373 |
DCHECK_EQ(GetCurrent(context), this); |
||
374 |
// This won't compile if T is not a BaseObject subclass. |
||
375 |
13310 |
BaseObjectPtr<T> item = MakeDetachedBaseObject<T>(this, target); |
|
376 |
BindingDataStore* map = static_cast<BindingDataStore*>( |
||
377 |
6655 |
context->GetAlignedPointerFromEmbedderData( |
|
378 |
6655 |
ContextEmbedderIndex::kBindingListIndex)); |
|
379 |
DCHECK_NOT_NULL(map); |
||
380 |
6655 |
auto result = map->emplace(T::type_name, item); |
|
381 |
✗✓ | 6655 |
CHECK(result.second); |
382 |
DCHECK_EQ(GetBindingData<T>(context), item.get()); |
||
383 |
13310 |
return item.get(); |
|
384 |
} |
||
385 |
|||
386 |
29411991 |
inline v8::Isolate* Environment::isolate() const { |
|
387 |
29411991 |
return isolate_; |
|
388 |
} |
||
389 |
|||
390 |
5216 |
inline Environment* Environment::from_timer_handle(uv_timer_t* handle) { |
|
391 |
5216 |
return ContainerOf(&Environment::timer_handle_, handle); |
|
392 |
} |
||
393 |
|||
394 |
22747 |
inline uv_timer_t* Environment::timer_handle() { |
|
395 |
22747 |
return &timer_handle_; |
|
396 |
} |
||
397 |
|||
398 |
481744 |
inline Environment* Environment::from_immediate_check_handle( |
|
399 |
uv_check_t* handle) { |
||
400 |
481744 |
return ContainerOf(&Environment::immediate_check_handle_, handle); |
|
401 |
} |
||
402 |
|||
403 |
20096 |
inline uv_check_t* Environment::immediate_check_handle() { |
|
404 |
20096 |
return &immediate_check_handle_; |
|
405 |
} |
||
406 |
|||
407 |
523645 |
inline uv_idle_t* Environment::immediate_idle_handle() { |
|
408 |
523645 |
return &immediate_idle_handle_; |
|
409 |
} |
||
410 |
|||
411 |
20096 |
inline void Environment::RegisterHandleCleanup(uv_handle_t* handle, |
|
412 |
HandleCleanupCb cb, |
||
413 |
void* arg) { |
||
414 |
20096 |
handle_cleanup_queue_.push_back(HandleCleanup{handle, cb, arg}); |
|
415 |
20096 |
} |
|
416 |
|||
417 |
template <typename T, typename OnCloseCallback> |
||
418 |
22696 |
inline void Environment::CloseHandle(T* handle, OnCloseCallback callback) { |
|
419 |
22696 |
handle_cleanup_waiting_++; |
|
420 |
static_assert(sizeof(T) >= sizeof(uv_handle_t), "T is a libuv handle"); |
||
421 |
static_assert(offsetof(T, data) == offsetof(uv_handle_t, data), |
||
422 |
"T is a libuv handle"); |
||
423 |
static_assert(offsetof(T, close_cb) == offsetof(uv_handle_t, close_cb), |
||
424 |
"T is a libuv handle"); |
||
425 |
struct CloseData { |
||
426 |
Environment* env; |
||
427 |
OnCloseCallback callback; |
||
428 |
void* original_data; |
||
429 |
}; |
||
430 |
22696 |
handle->data = new CloseData { this, callback, handle->data }; |
|
431 |
90800 |
uv_close(reinterpret_cast<uv_handle_t*>(handle), [](uv_handle_t* handle) { |
|
432 |
45397 |
std::unique_ptr<CloseData> data { static_cast<CloseData*>(handle->data) }; |
|
433 |
22697 |
data->env->handle_cleanup_waiting_--; |
|
434 |
22698 |
handle->data = data->original_data; |
|
435 |
22698 |
data->callback(reinterpret_cast<T*>(handle)); |
|
436 |
22700 |
}); |
|
437 |
22699 |
} |
|
438 |
|||
439 |
83585 |
void Environment::IncreaseWaitingRequestCounter() { |
|
440 |
83585 |
request_waiting_++; |
|
441 |
83585 |
} |
|
442 |
|||
443 |
83579 |
void Environment::DecreaseWaitingRequestCounter() { |
|
444 |
83579 |
request_waiting_--; |
|
445 |
✗✓ | 83579 |
CHECK_GE(request_waiting_, 0); |
446 |
83579 |
} |
|
447 |
|||
448 |
846642 |
inline uv_loop_t* Environment::event_loop() const { |
|
449 |
846642 |
return isolate_data()->event_loop(); |
|
450 |
} |
||
451 |
|||
452 |
160 |
inline void Environment::TryLoadAddon( |
|
453 |
const char* filename, |
||
454 |
int flags, |
||
455 |
const std::function<bool(binding::DLib*)>& was_loaded) { |
||
456 |
160 |
loaded_addons_.emplace_back(filename, flags); |
|
457 |
✓✓ | 160 |
if (!was_loaded(&loaded_addons_.back())) { |
458 |
8 |
loaded_addons_.pop_back(); |
|
459 |
} |
||
460 |
160 |
} |
|
461 |
|||
462 |
#if HAVE_INSPECTOR |
||
463 |
17769 |
inline bool Environment::is_in_inspector_console_call() const { |
|
464 |
17769 |
return is_in_inspector_console_call_; |
|
465 |
} |
||
466 |
|||
467 |
35536 |
inline void Environment::set_is_in_inspector_console_call(bool value) { |
|
468 |
35536 |
is_in_inspector_console_call_ = value; |
|
469 |
35536 |
} |
|
470 |
#endif |
||
471 |
|||
472 |
7264556 |
inline AsyncHooks* Environment::async_hooks() { |
|
473 |
7264556 |
return &async_hooks_; |
|
474 |
} |
||
475 |
|||
476 |
1753985 |
inline ImmediateInfo* Environment::immediate_info() { |
|
477 |
1753985 |
return &immediate_info_; |
|
478 |
} |
||
479 |
|||
480 |
1174677 |
inline TickInfo* Environment::tick_info() { |
|
481 |
1174677 |
return &tick_info_; |
|
482 |
} |
||
483 |
|||
484 |
51789 |
inline uint64_t Environment::timer_base() const { |
|
485 |
51789 |
return timer_base_; |
|
486 |
} |
||
487 |
|||
488 |
1286712 |
inline std::shared_ptr<KVStore> Environment::env_vars() { |
|
489 |
1286712 |
return env_vars_; |
|
490 |
} |
||
491 |
|||
492 |
5447 |
inline void Environment::set_env_vars(std::shared_ptr<KVStore> env_vars) { |
|
493 |
5447 |
env_vars_ = env_vars; |
|
494 |
5447 |
} |
|
495 |
|||
496 |
17 |
inline bool Environment::printed_error() const { |
|
497 |
17 |
return printed_error_; |
|
498 |
} |
||
499 |
|||
500 |
17 |
inline void Environment::set_printed_error(bool value) { |
|
501 |
17 |
printed_error_ = value; |
|
502 |
17 |
} |
|
503 |
|||
504 |
9249 |
inline void Environment::set_trace_sync_io(bool value) { |
|
505 |
9249 |
trace_sync_io_ = value; |
|
506 |
9249 |
} |
|
507 |
|||
508 |
80 |
inline bool Environment::abort_on_uncaught_exception() const { |
|
509 |
80 |
return options_->abort_on_uncaught_exception; |
|
510 |
} |
||
511 |
|||
512 |
inline void Environment::set_force_context_aware(bool value) { |
||
513 |
options_->force_context_aware = value; |
||
514 |
} |
||
515 |
|||
516 |
42 |
inline bool Environment::force_context_aware() const { |
|
517 |
42 |
return options_->force_context_aware; |
|
518 |
} |
||
519 |
|||
520 |
393 |
inline void Environment::set_abort_on_uncaught_exception(bool value) { |
|
521 |
393 |
options_->abort_on_uncaught_exception = value; |
|
522 |
393 |
} |
|
523 |
|||
524 |
474 |
inline AliasedUint32Array& Environment::should_abort_on_uncaught_toggle() { |
|
525 |
474 |
return should_abort_on_uncaught_toggle_; |
|
526 |
} |
||
527 |
|||
528 |
1296328 |
inline AliasedInt32Array& Environment::stream_base_state() { |
|
529 |
1296328 |
return stream_base_state_; |
|
530 |
} |
||
531 |
|||
532 |
33719 |
inline uint32_t Environment::get_next_module_id() { |
|
533 |
33719 |
return module_id_counter_++; |
|
534 |
} |
||
535 |
1978 |
inline uint32_t Environment::get_next_script_id() { |
|
536 |
1978 |
return script_id_counter_++; |
|
537 |
} |
||
538 |
31008 |
inline uint32_t Environment::get_next_function_id() { |
|
539 |
31008 |
return function_id_counter_++; |
|
540 |
} |
||
541 |
|||
542 |
69174 |
ShouldNotAbortOnUncaughtScope::ShouldNotAbortOnUncaughtScope( |
|
543 |
69174 |
Environment* env) |
|
544 |
69174 |
: env_(env) { |
|
545 |
69174 |
env_->PushShouldNotAbortOnUncaughtScope(); |
|
546 |
69174 |
} |
|
547 |
|||
548 |
138346 |
ShouldNotAbortOnUncaughtScope::~ShouldNotAbortOnUncaughtScope() { |
|
549 |
69173 |
Close(); |
|
550 |
69173 |
} |
|
551 |
|||
552 |
69357 |
void ShouldNotAbortOnUncaughtScope::Close() { |
|
553 |
✓✓ | 69357 |
if (env_ != nullptr) { |
554 |
69173 |
env_->PopShouldNotAbortOnUncaughtScope(); |
|
555 |
69173 |
env_ = nullptr; |
|
556 |
} |
||
557 |
69357 |
} |
|
558 |
|||
559 |
69174 |
inline void Environment::PushShouldNotAbortOnUncaughtScope() { |
|
560 |
69174 |
should_not_abort_scope_counter_++; |
|
561 |
69174 |
} |
|
562 |
|||
563 |
69173 |
inline void Environment::PopShouldNotAbortOnUncaughtScope() { |
|
564 |
69173 |
should_not_abort_scope_counter_--; |
|
565 |
69173 |
} |
|
566 |
|||
567 |
1 |
inline bool Environment::inside_should_not_abort_on_uncaught_scope() const { |
|
568 |
1 |
return should_not_abort_scope_counter_ > 0; |
|
569 |
} |
||
570 |
|||
571 |
382026 |
inline std::vector<double>* Environment::destroy_async_id_list() { |
|
572 |
382026 |
return &destroy_async_id_list_; |
|
573 |
} |
||
574 |
|||
575 |
216778 |
inline double Environment::new_async_id() { |
|
576 |
216778 |
async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter] += 1; |
|
577 |
216778 |
return async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter]; |
|
578 |
} |
||
579 |
|||
580 |
248209 |
inline double Environment::execution_async_id() { |
|
581 |
248209 |
return async_hooks()->async_id_fields()[AsyncHooks::kExecutionAsyncId]; |
|
582 |
} |
||
583 |
|||
584 |
64555 |
inline double Environment::trigger_async_id() { |
|
585 |
64555 |
return async_hooks()->async_id_fields()[AsyncHooks::kTriggerAsyncId]; |
|
586 |
} |
||
587 |
|||
588 |
216775 |
inline double Environment::get_default_trigger_async_id() { |
|
589 |
double default_trigger_async_id = |
||
590 |
216775 |
async_hooks()->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId]; |
|
591 |
// If defaultTriggerAsyncId isn't set, use the executionAsyncId |
||
592 |
✓✓ | 216775 |
if (default_trigger_async_id < 0) |
593 |
172969 |
default_trigger_async_id = execution_async_id(); |
|
594 |
216775 |
return default_trigger_async_id; |
|
595 |
} |
||
596 |
|||
597 |
57165 |
inline std::shared_ptr<EnvironmentOptions> Environment::options() { |
|
598 |
57165 |
return options_; |
|
599 |
} |
||
600 |
|||
601 |
14581 |
inline const std::vector<std::string>& Environment::argv() { |
|
602 |
14581 |
return argv_; |
|
603 |
} |
||
604 |
|||
605 |
5560 |
inline const std::vector<std::string>& Environment::exec_argv() { |
|
606 |
5560 |
return exec_argv_; |
|
607 |
} |
||
608 |
|||
609 |
10048 |
inline const std::string& Environment::exec_path() const { |
|
610 |
10048 |
return exec_path_; |
|
611 |
} |
||
612 |
|||
613 |
11 |
inline std::string Environment::GetCwd() { |
|
614 |
char cwd[PATH_MAX_BYTES]; |
||
615 |
11 |
size_t size = PATH_MAX_BYTES; |
|
616 |
11 |
const int err = uv_cwd(cwd, &size); |
|
617 |
|||
618 |
✓✗ | 11 |
if (err == 0) { |
619 |
✗✓ | 11 |
CHECK_GT(size, 0); |
620 |
11 |
return cwd; |
|
621 |
} |
||
622 |
|||
623 |
// This can fail if the cwd is deleted. In that case, fall back to |
||
624 |
// exec_path. |
||
625 |
const std::string& exec_path = exec_path_; |
||
626 |
return exec_path.substr(0, exec_path.find_last_of(kPathSeparator)); |
||
627 |
} |
||
628 |
|||
629 |
#if HAVE_INSPECTOR |
||
630 |
5018 |
inline void Environment::set_coverage_directory(const char* dir) { |
|
631 |
5018 |
coverage_directory_ = std::string(dir); |
|
632 |
5018 |
} |
|
633 |
|||
634 |
5038 |
inline void Environment::set_coverage_connection( |
|
635 |
std::unique_ptr<profiler::V8CoverageConnection> connection) { |
||
636 |
✗✓ | 5038 |
CHECK_NULL(coverage_connection_); |
637 |
5039 |
std::swap(coverage_connection_, connection); |
|
638 |
5039 |
} |
|
639 |
|||
640 |
15118 |
inline profiler::V8CoverageConnection* Environment::coverage_connection() { |
|
641 |
15118 |
return coverage_connection_.get(); |
|
642 |
} |
||
643 |
|||
644 |
5006 |
inline const std::string& Environment::coverage_directory() const { |
|
645 |
5006 |
return coverage_directory_; |
|
646 |
} |
||
647 |
|||
648 |
12 |
inline void Environment::set_cpu_profiler_connection( |
|
649 |
std::unique_ptr<profiler::V8CpuProfilerConnection> connection) { |
||
650 |
✗✓ | 12 |
CHECK_NULL(cpu_profiler_connection_); |
651 |
12 |
std::swap(cpu_profiler_connection_, connection); |
|
652 |
12 |
} |
|
653 |
|||
654 |
inline profiler::V8CpuProfilerConnection* |
||
655 |
5058 |
Environment::cpu_profiler_connection() { |
|
656 |
5058 |
return cpu_profiler_connection_.get(); |
|
657 |
} |
||
658 |
|||
659 |
12 |
inline void Environment::set_cpu_prof_interval(uint64_t interval) { |
|
660 |
12 |
cpu_prof_interval_ = interval; |
|
661 |
12 |
} |
|
662 |
|||
663 |
12 |
inline uint64_t Environment::cpu_prof_interval() const { |
|
664 |
12 |
return cpu_prof_interval_; |
|
665 |
} |
||
666 |
|||
667 |
12 |
inline void Environment::set_cpu_prof_name(const std::string& name) { |
|
668 |
12 |
cpu_prof_name_ = name; |
|
669 |
12 |
} |
|
670 |
|||
671 |
12 |
inline const std::string& Environment::cpu_prof_name() const { |
|
672 |
12 |
return cpu_prof_name_; |
|
673 |
} |
||
674 |
|||
675 |
12 |
inline void Environment::set_cpu_prof_dir(const std::string& dir) { |
|
676 |
12 |
cpu_prof_dir_ = dir; |
|
677 |
12 |
} |
|
678 |
|||
679 |
12 |
inline const std::string& Environment::cpu_prof_dir() const { |
|
680 |
12 |
return cpu_prof_dir_; |
|
681 |
} |
||
682 |
|||
683 |
12 |
inline void Environment::set_heap_profiler_connection( |
|
684 |
std::unique_ptr<profiler::V8HeapProfilerConnection> connection) { |
||
685 |
✗✓ | 12 |
CHECK_NULL(heap_profiler_connection_); |
686 |
12 |
std::swap(heap_profiler_connection_, connection); |
|
687 |
12 |
} |
|
688 |
|||
689 |
inline profiler::V8HeapProfilerConnection* |
||
690 |
5046 |
Environment::heap_profiler_connection() { |
|
691 |
5046 |
return heap_profiler_connection_.get(); |
|
692 |
} |
||
693 |
|||
694 |
12 |
inline void Environment::set_heap_prof_name(const std::string& name) { |
|
695 |
12 |
heap_prof_name_ = name; |
|
696 |
12 |
} |
|
697 |
|||
698 |
12 |
inline const std::string& Environment::heap_prof_name() const { |
|
699 |
12 |
return heap_prof_name_; |
|
700 |
} |
||
701 |
|||
702 |
12 |
inline void Environment::set_heap_prof_dir(const std::string& dir) { |
|
703 |
12 |
heap_prof_dir_ = dir; |
|
704 |
12 |
} |
|
705 |
|||
706 |
12 |
inline const std::string& Environment::heap_prof_dir() const { |
|
707 |
12 |
return heap_prof_dir_; |
|
708 |
} |
||
709 |
|||
710 |
12 |
inline void Environment::set_heap_prof_interval(uint64_t interval) { |
|
711 |
12 |
heap_prof_interval_ = interval; |
|
712 |
12 |
} |
|
713 |
|||
714 |
12 |
inline uint64_t Environment::heap_prof_interval() const { |
|
715 |
12 |
return heap_prof_interval_; |
|
716 |
} |
||
717 |
|||
718 |
#endif // HAVE_INSPECTOR |
||
719 |
|||
720 |
inline |
||
721 |
10208 |
std::shared_ptr<ExclusiveAccess<HostPort>> Environment::inspector_host_port() { |
|
722 |
10208 |
return inspector_host_port_; |
|
723 |
} |
||
724 |
|||
725 |
69140 |
inline std::shared_ptr<PerIsolateOptions> IsolateData::options() { |
|
726 |
69140 |
return options_; |
|
727 |
} |
||
728 |
|||
729 |
102 |
inline void IsolateData::set_options( |
|
730 |
std::shared_ptr<PerIsolateOptions> options) { |
||
731 |
102 |
options_ = std::move(options); |
|
732 |
102 |
} |
|
733 |
|||
734 |
template <typename Fn> |
||
735 |
55816 |
void Environment::SetImmediate(Fn&& cb, CallbackFlags::Flags flags) { |
|
736 |
111632 |
auto callback = native_immediates_.CreateCallback(std::move(cb), flags); |
|
737 |
55816 |
native_immediates_.Push(std::move(callback)); |
|
738 |
|||
739 |
✓✓✓✓ ✓✗✓✗ ✓✗ |
55816 |
if (flags & CallbackFlags::kRefed) { |
740 |
✓✓✓✓ ✓✓✓✗ ✓✓ |
33411 |
if (immediate_info()->ref_count() == 0) |
741 |
25135 |
ToggleImmediateRef(true); |
|
742 |
33411 |
immediate_info()->ref_count_inc(1); |
|
743 |
} |
||
744 |
55816 |
} |
|
745 |
|||
746 |
template <typename Fn> |
||
747 |
1224 |
void Environment::SetImmediateThreadsafe(Fn&& cb, CallbackFlags::Flags flags) { |
|
748 |
auto callback = native_immediates_threadsafe_.CreateCallback( |
||
749 |
2448 |
std::move(cb), flags); |
|
750 |
{ |
||
751 |
2448 |
Mutex::ScopedLock lock(native_immediates_threadsafe_mutex_); |
|
752 |
1224 |
native_immediates_threadsafe_.Push(std::move(callback)); |
|
753 |
✓✓✓✗ |
1224 |
if (task_queues_async_initialized_) |
754 |
966 |
uv_async_send(&task_queues_async_); |
|
755 |
} |
||
756 |
1224 |
} |
|
757 |
|||
758 |
template <typename Fn> |
||
759 |
8324 |
void Environment::RequestInterrupt(Fn&& cb) { |
|
760 |
auto callback = native_immediates_interrupts_.CreateCallback( |
||
761 |
16648 |
std::move(cb), CallbackFlags::kRefed); |
|
762 |
{ |
||
763 |
16648 |
Mutex::ScopedLock lock(native_immediates_threadsafe_mutex_); |
|
764 |
8324 |
native_immediates_interrupts_.Push(std::move(callback)); |
|
765 |
✓✓ | 8324 |
if (task_queues_async_initialized_) |
766 |
3156 |
uv_async_send(&task_queues_async_); |
|
767 |
} |
||
768 |
8324 |
RequestInterruptFromV8(); |
|
769 |
8324 |
} |
|
770 |
|||
771 |
4497546 |
inline bool Environment::can_call_into_js() const { |
|
772 |
✓✓✓✓ |
4497546 |
return can_call_into_js_ && !is_stopping(); |
773 |
} |
||
774 |
|||
775 |
911 |
inline void Environment::set_can_call_into_js(bool can_call_into_js) { |
|
776 |
911 |
can_call_into_js_ = can_call_into_js; |
|
777 |
913 |
} |
|
778 |
|||
779 |
1413722 |
inline bool Environment::has_run_bootstrapping_code() const { |
|
780 |
1413722 |
return has_run_bootstrapping_code_; |
|
781 |
} |
||
782 |
|||
783 |
5057 |
inline void Environment::DoneBootstrapping() { |
|
784 |
5057 |
has_run_bootstrapping_code_ = true; |
|
785 |
// This adjusts the return value of base_object_created_after_bootstrap() so |
||
786 |
// that tests that check the count do not have to account for internally |
||
787 |
// created BaseObjects. |
||
788 |
5057 |
base_object_created_by_bootstrap_ = base_object_count_; |
|
789 |
5057 |
} |
|
790 |
|||
791 |
19 |
inline bool Environment::has_serialized_options() const { |
|
792 |
19 |
return has_serialized_options_; |
|
793 |
} |
||
794 |
|||
795 |
5024 |
inline void Environment::set_has_serialized_options(bool value) { |
|
796 |
5024 |
has_serialized_options_ = value; |
|
797 |
5024 |
} |
|
798 |
|||
799 |
6800 |
inline bool Environment::is_main_thread() const { |
|
800 |
6800 |
return worker_context() == nullptr; |
|
801 |
} |
||
802 |
|||
803 |
5024 |
inline bool Environment::should_not_register_esm_loader() const { |
|
804 |
5024 |
return flags_ & EnvironmentFlags::kNoRegisterESMLoader; |
|
805 |
} |
||
806 |
|||
807 |
12394 |
inline bool Environment::owns_process_state() const { |
|
808 |
12394 |
return flags_ & EnvironmentFlags::kOwnsProcessState; |
|
809 |
} |
||
810 |
|||
811 |
5048 |
inline bool Environment::owns_inspector() const { |
|
812 |
5048 |
return flags_ & EnvironmentFlags::kOwnsInspector; |
|
813 |
} |
||
814 |
|||
815 |
103279 |
inline bool Environment::tracks_unmanaged_fds() const { |
|
816 |
103279 |
return flags_ & EnvironmentFlags::kTrackUnmanagedFds; |
|
817 |
} |
||
818 |
|||
819 |
2 |
bool Environment::filehandle_close_warning() const { |
|
820 |
2 |
return emit_filehandle_warning_; |
|
821 |
} |
||
822 |
|||
823 |
2 |
void Environment::set_filehandle_close_warning(bool on) { |
|
824 |
2 |
emit_filehandle_warning_ = on; |
|
825 |
2 |
} |
|
826 |
|||
827 |
16 |
void Environment::set_source_maps_enabled(bool on) { |
|
828 |
16 |
source_maps_enabled_ = on; |
|
829 |
16 |
} |
|
830 |
|||
831 |
906 |
bool Environment::source_maps_enabled() const { |
|
832 |
906 |
return source_maps_enabled_; |
|
833 |
} |
||
834 |
|||
835 |
5919 |
inline uint64_t Environment::thread_id() const { |
|
836 |
5919 |
return thread_id_; |
|
837 |
} |
||
838 |
|||
839 |
12198 |
inline worker::Worker* Environment::worker_context() const { |
|
840 |
12198 |
return isolate_data()->worker_context(); |
|
841 |
} |
||
842 |
|||
843 |
633 |
inline void Environment::add_sub_worker_context(worker::Worker* context) { |
|
844 |
633 |
sub_worker_contexts_.insert(context); |
|
845 |
633 |
} |
|
846 |
|||
847 |
658 |
inline void Environment::remove_sub_worker_context(worker::Worker* context) { |
|
848 |
658 |
sub_worker_contexts_.erase(context); |
|
849 |
658 |
} |
|
850 |
|||
851 |
template <typename Fn> |
||
852 |
22 |
inline void Environment::ForEachWorker(Fn&& iterator) { |
|
853 |
✓✓ | 22 |
for (worker::Worker* w : sub_worker_contexts_) iterator(w); |
854 |
22 |
} |
|
855 |
|||
856 |
1250 |
inline void Environment::add_refs(int64_t diff) { |
|
857 |
1250 |
task_queues_async_refs_ += diff; |
|
858 |
✗✓ | 1250 |
CHECK_GE(task_queues_async_refs_, 0); |
859 |
✓✓ | 1250 |
if (task_queues_async_refs_ == 0) |
860 |
162 |
uv_unref(reinterpret_cast<uv_handle_t*>(&task_queues_async_)); |
|
861 |
else |
||
862 |
1088 |
uv_ref(reinterpret_cast<uv_handle_t*>(&task_queues_async_)); |
|
863 |
1250 |
} |
|
864 |
|||
865 |
6946048 |
inline bool Environment::is_stopping() const { |
|
866 |
6946048 |
return is_stopping_.load(); |
|
867 |
} |
||
868 |
|||
869 |
4726 |
inline void Environment::set_stopping(bool value) { |
|
870 |
4726 |
is_stopping_.store(value); |
|
871 |
4727 |
} |
|
872 |
|||
873 |
3 |
inline std::list<node_module>* Environment::extra_linked_bindings() { |
|
874 |
3 |
return &extra_linked_bindings_; |
|
875 |
} |
||
876 |
|||
877 |
7 |
inline node_module* Environment::extra_linked_bindings_head() { |
|
878 |
✓✓ | 10 |
return extra_linked_bindings_.size() > 0 ? |
879 |
10 |
&extra_linked_bindings_.front() : nullptr; |
|
880 |
} |
||
881 |
|||
882 |
7 |
inline const Mutex& Environment::extra_linked_bindings_mutex() const { |
|
883 |
7 |
return extra_linked_bindings_mutex_; |
|
884 |
} |
||
885 |
|||
886 |
43060 |
inline performance::PerformanceState* Environment::performance_state() { |
|
887 |
43060 |
return performance_state_.get(); |
|
888 |
} |
||
889 |
|||
890 |
inline std::unordered_map<std::string, uint64_t>* |
||
891 |
50 |
Environment::performance_marks() { |
|
892 |
50 |
return &performance_marks_; |
|
893 |
} |
||
894 |
|||
895 |
5644399 |
inline IsolateData* Environment::isolate_data() const { |
|
896 |
5644399 |
return isolate_data_; |
|
897 |
} |
||
898 |
|||
899 |
std::unordered_map<char*, std::unique_ptr<v8::BackingStore>>* |
||
900 |
625768 |
Environment::released_allocated_buffers() { |
|
901 |
625768 |
return &released_allocated_buffers_; |
|
902 |
} |
||
903 |
|||
904 |
7 |
inline void Environment::ThrowError(const char* errmsg) { |
|
905 |
7 |
ThrowError(v8::Exception::Error, errmsg); |
|
906 |
7 |
} |
|
907 |
|||
908 |
inline void Environment::ThrowTypeError(const char* errmsg) { |
||
909 |
ThrowError(v8::Exception::TypeError, errmsg); |
||
910 |
} |
||
911 |
|||
912 |
inline void Environment::ThrowRangeError(const char* errmsg) { |
||
913 |
ThrowError(v8::Exception::RangeError, errmsg); |
||
914 |
} |
||
915 |
|||
916 |
7 |
inline void Environment::ThrowError( |
|
917 |
v8::Local<v8::Value> (*fun)(v8::Local<v8::String>), |
||
918 |
const char* errmsg) { |
||
919 |
14 |
v8::HandleScope handle_scope(isolate()); |
|
920 |
7 |
isolate()->ThrowException(fun(OneByteString(isolate(), errmsg))); |
|
921 |
7 |
} |
|
922 |
|||
923 |
7 |
inline void Environment::ThrowErrnoException(int errorno, |
|
924 |
const char* syscall, |
||
925 |
const char* message, |
||
926 |
const char* path) { |
||
927 |
isolate()->ThrowException( |
||
928 |
7 |
ErrnoException(isolate(), errorno, syscall, message, path)); |
|
929 |
7 |
} |
|
930 |
|||
931 |
14 |
inline void Environment::ThrowUVException(int errorno, |
|
932 |
const char* syscall, |
||
933 |
const char* message, |
||
934 |
const char* path, |
||
935 |
const char* dest) { |
||
936 |
isolate()->ThrowException( |
||
937 |
14 |
UVException(isolate(), errorno, syscall, message, path, dest)); |
|
938 |
14 |
} |
|
939 |
|||
940 |
inline v8::Local<v8::FunctionTemplate> |
||
941 |
1230389 |
Environment::NewFunctionTemplate(v8::FunctionCallback callback, |
|
942 |
v8::Local<v8::Signature> signature, |
||
943 |
v8::ConstructorBehavior behavior, |
||
944 |
v8::SideEffectType side_effect_type) { |
||
945 |
return v8::FunctionTemplate::New(isolate(), callback, v8::Local<v8::Value>(), |
||
946 |
1230389 |
signature, 0, behavior, side_effect_type); |
|
947 |
} |
||
948 |
|||
949 |
442185 |
inline void Environment::SetMethod(v8::Local<v8::Object> that, |
|
950 |
const char* name, |
||
951 |
v8::FunctionCallback callback) { |
||
952 |
442185 |
v8::Local<v8::Context> context = isolate()->GetCurrentContext(); |
|
953 |
v8::Local<v8::Function> function = |
||
954 |
884364 |
NewFunctionTemplate(callback, v8::Local<v8::Signature>(), |
|
955 |
v8::ConstructorBehavior::kThrow, |
||
956 |
442186 |
v8::SideEffectType::kHasSideEffect) |
|
957 |
884372 |
->GetFunction(context) |
|
958 |
442186 |
.ToLocalChecked(); |
|
959 |
// kInternalized strings are created in the old space. |
||
960 |
442186 |
const v8::NewStringType type = v8::NewStringType::kInternalized; |
|
961 |
v8::Local<v8::String> name_string = |
||
962 |
884370 |
v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked(); |
|
963 |
884367 |
that->Set(context, name_string, function).Check(); |
|
964 |
442183 |
function->SetName(name_string); // NODE_SET_METHOD() compatibility. |
|
965 |
442189 |
} |
|
966 |
|||
967 |
52595 |
inline void Environment::SetMethodNoSideEffect(v8::Local<v8::Object> that, |
|
968 |
const char* name, |
||
969 |
v8::FunctionCallback callback) { |
||
970 |
52595 |
v8::Local<v8::Context> context = isolate()->GetCurrentContext(); |
|
971 |
v8::Local<v8::Function> function = |
||
972 |
105190 |
NewFunctionTemplate(callback, v8::Local<v8::Signature>(), |
|
973 |
v8::ConstructorBehavior::kThrow, |
||
974 |
52595 |
v8::SideEffectType::kHasNoSideEffect) |
|
975 |
105190 |
->GetFunction(context) |
|
976 |
52595 |
.ToLocalChecked(); |
|
977 |
// kInternalized strings are created in the old space. |
||
978 |
52595 |
const v8::NewStringType type = v8::NewStringType::kInternalized; |
|
979 |
v8::Local<v8::String> name_string = |
||
980 |
105190 |
v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked(); |
|
981 |
105192 |
that->Set(context, name_string, function).Check(); |
|
982 |
52597 |
function->SetName(name_string); // NODE_SET_METHOD() compatibility. |
|
983 |
52597 |
} |
|
984 |
|||
985 |
516448 |
inline void Environment::SetProtoMethod(v8::Local<v8::FunctionTemplate> that, |
|
986 |
const char* name, |
||
987 |
v8::FunctionCallback callback) { |
||
988 |
516448 |
v8::Local<v8::Signature> signature = v8::Signature::New(isolate(), that); |
|
989 |
v8::Local<v8::FunctionTemplate> t = |
||
990 |
NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow, |
||
991 |
516445 |
v8::SideEffectType::kHasSideEffect); |
|
992 |
// kInternalized strings are created in the old space. |
||
993 |
516449 |
const v8::NewStringType type = v8::NewStringType::kInternalized; |
|
994 |
v8::Local<v8::String> name_string = |
||
995 |
1032898 |
v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked(); |
|
996 |
1032896 |
that->PrototypeTemplate()->Set(name_string, t); |
|
997 |
516445 |
t->SetClassName(name_string); // NODE_SET_PROTOTYPE_METHOD() compatibility. |
|
998 |
516448 |
} |
|
999 |
|||
1000 |
49860 |
inline void Environment::SetProtoMethodNoSideEffect( |
|
1001 |
v8::Local<v8::FunctionTemplate> that, |
||
1002 |
const char* name, |
||
1003 |
v8::FunctionCallback callback) { |
||
1004 |
49860 |
v8::Local<v8::Signature> signature = v8::Signature::New(isolate(), that); |
|
1005 |
v8::Local<v8::FunctionTemplate> t = |
||
1006 |
NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow, |
||
1007 |
49860 |
v8::SideEffectType::kHasNoSideEffect); |
|
1008 |
// kInternalized strings are created in the old space. |
||
1009 |
49860 |
const v8::NewStringType type = v8::NewStringType::kInternalized; |
|
1010 |
v8::Local<v8::String> name_string = |
||
1011 |
99720 |
v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked(); |
|
1012 |
99720 |
that->PrototypeTemplate()->Set(name_string, t); |
|
1013 |
49860 |
t->SetClassName(name_string); // NODE_SET_PROTOTYPE_METHOD() compatibility. |
|
1014 |
49860 |
} |
|
1015 |
|||
1016 |
32 |
inline void Environment::SetInstanceMethod(v8::Local<v8::FunctionTemplate> that, |
|
1017 |
const char* name, |
||
1018 |
v8::FunctionCallback callback) { |
||
1019 |
32 |
v8::Local<v8::Signature> signature = v8::Signature::New(isolate(), that); |
|
1020 |
v8::Local<v8::FunctionTemplate> t = |
||
1021 |
NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow, |
||
1022 |
32 |
v8::SideEffectType::kHasSideEffect); |
|
1023 |
// kInternalized strings are created in the old space. |
||
1024 |
32 |
const v8::NewStringType type = v8::NewStringType::kInternalized; |
|
1025 |
v8::Local<v8::String> name_string = |
||
1026 |
64 |
v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked(); |
|
1027 |
64 |
that->InstanceTemplate()->Set(name_string, t); |
|
1028 |
32 |
t->SetClassName(name_string); |
|
1029 |
32 |
} |
|
1030 |
|||
1031 |
105239 |
inline void Environment::SetConstructorFunction( |
|
1032 |
v8::Local<v8::Object> that, |
||
1033 |
const char* name, |
||
1034 |
v8::Local<v8::FunctionTemplate> tmpl) { |
||
1035 |
105239 |
SetConstructorFunction(that, OneByteString(isolate(), name), tmpl); |
|
1036 |
105239 |
} |
|
1037 |
|||
1038 |
112211 |
inline void Environment::SetConstructorFunction( |
|
1039 |
v8::Local<v8::Object> that, |
||
1040 |
v8::Local<v8::String> name, |
||
1041 |
v8::Local<v8::FunctionTemplate> tmpl) { |
||
1042 |
112211 |
tmpl->SetClassName(name); |
|
1043 |
224424 |
that->Set( |
|
1044 |
context(), |
||
1045 |
name, |
||
1046 |
561057 |
tmpl->GetFunction(context()).ToLocalChecked()).Check(); |
|
1047 |
112212 |
} |
|
1048 |
|||
1049 |
333374 |
void Environment::AddCleanupHook(CleanupCallback fn, void* arg) { |
|
1050 |
666750 |
auto insertion_info = cleanup_hooks_.emplace(CleanupHookCallback { |
|
1051 |
333374 |
fn, arg, cleanup_hook_counter_++ |
|
1052 |
333374 |
}); |
|
1053 |
// Make sure there was no existing element with these values. |
||
1054 |
✗✓ | 333376 |
CHECK_EQ(insertion_info.second, true); |
1055 |
333376 |
} |
|
1056 |
|||
1057 |
322486 |
void Environment::RemoveCleanupHook(CleanupCallback fn, void* arg) { |
|
1058 |
322486 |
CleanupHookCallback search { fn, arg, 0 }; |
|
1059 |
322491 |
cleanup_hooks_.erase(search); |
|
1060 |
322493 |
} |
|
1061 |
|||
1062 |
885838 |
size_t CleanupHookCallback::Hash::operator()( |
|
1063 |
const CleanupHookCallback& cb) const { |
||
1064 |
885838 |
return std::hash<void*>()(cb.arg_); |
|
1065 |
} |
||
1066 |
|||
1067 |
441440 |
bool CleanupHookCallback::Equal::operator()( |
|
1068 |
const CleanupHookCallback& a, const CleanupHookCallback& b) const { |
||
1069 |
✓✓✓✗ |
441440 |
return a.fn_ == b.fn_ && a.arg_ == b.arg_; |
1070 |
} |
||
1071 |
|||
1072 |
406 |
BaseObject* CleanupHookCallback::GetBaseObject() const { |
|
1073 |
✓✓ | 406 |
if (fn_ == BaseObject::DeleteMe) |
1074 |
384 |
return static_cast<BaseObject*>(arg_); |
|
1075 |
else |
||
1076 |
22 |
return nullptr; |
|
1077 |
} |
||
1078 |
|||
1079 |
template <typename T> |
||
1080 |
22 |
void Environment::ForEachBaseObject(T&& iterator) { |
|
1081 |
✗✗✓✓ ✗✗ |
428 |
for (const auto& hook : cleanup_hooks_) { |
1082 |
406 |
BaseObject* obj = hook.GetBaseObject(); |
|
1083 |
✓✓✗✗ ✗✗ |
406 |
if (obj != nullptr) |
1084 |
384 |
iterator(obj); |
|
1085 |
} |
||
1086 |
22 |
} |
|
1087 |
|||
1088 |
644070 |
void Environment::modify_base_object_count(int64_t delta) { |
|
1089 |
644070 |
base_object_count_ += delta; |
|
1090 |
644070 |
} |
|
1091 |
|||
1092 |
14 |
int64_t Environment::base_object_created_after_bootstrap() const { |
|
1093 |
14 |
return base_object_count_ - base_object_created_by_bootstrap_; |
|
1094 |
} |
||
1095 |
|||
1096 |
2 |
int64_t Environment::base_object_count() const { |
|
1097 |
2 |
return base_object_count_; |
|
1098 |
} |
||
1099 |
|||
1100 |
15 |
void Environment::set_main_utf16(std::unique_ptr<v8::String::Value> str) { |
|
1101 |
✗✓ | 15 |
CHECK(!main_utf16_); |
1102 |
15 |
main_utf16_ = std::move(str); |
|
1103 |
15 |
} |
|
1104 |
|||
1105 |
393 |
void Environment::set_process_exit_handler( |
|
1106 |
std::function<void(Environment*, int)>&& handler) { |
||
1107 |
393 |
process_exit_handler_ = std::move(handler); |
|
1108 |
393 |
} |
|
1109 |
|||
1110 |
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName) |
||
1111 |
#define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName) |
||
1112 |
#define VS(PropertyName, StringValue) V(v8::String, PropertyName) |
||
1113 |
#define V(TypeName, PropertyName) \ |
||
1114 |
inline \ |
||
1115 |
v8::Local<TypeName> IsolateData::PropertyName() const { \ |
||
1116 |
return PropertyName ## _ .Get(isolate_); \ |
||
1117 |
} |
||
1118 |
212 |
PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP) |
|
1119 |
4399 |
PER_ISOLATE_SYMBOL_PROPERTIES(VY) |
|
1120 |
6833690 |
PER_ISOLATE_STRING_PROPERTIES(VS) |
|
1121 |
242589 |
#undef V |
|
1122 |
16245 |
#undef VS |
|
1123 |
8401 |
#undef VY |
|
1124 |
4582 |
#undef VP |
|
1125 |
29221 |
||
1126 |
114677 |
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName) |
|
1127 |
16816 |
#define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName) |
|
1128 |
26949 |
#define VS(PropertyName, StringValue) V(v8::String, PropertyName) |
|
1129 |
61473 |
#define V(TypeName, PropertyName) \ |
|
1130 |
24538 |
inline v8::Local<TypeName> Environment::PropertyName() const { \ |
|
1131 |
101 |
return isolate_data()->PropertyName(); \ |
|
1132 |
118 |
} |
|
1133 |
31269 |
PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP) |
|
1134 |
64718 |
PER_ISOLATE_SYMBOL_PROPERTIES(VY) |
|
1135 |
3511918 |
PER_ISOLATE_STRING_PROPERTIES(VS) |
|
1136 |
113530 |
#undef V |
|
1137 |
2389 |
#undef VS |
|
1138 |
12952 |
#undef VY |
|
1139 |
3062 |
#undef VP |
|
1140 |
46500 |
||
1141 |
99059 |
#define V(PropertyName, TypeName) \ |
|
1142 |
8233 |
inline v8::Local<TypeName> Environment::PropertyName() const { \ |
|
1143 |
14768 |
return PersistentToLocal::Strong(PropertyName ## _); \ |
|
1144 |
15293 |
} \ |
|
1145 |
1518 |
inline void Environment::set_ ## PropertyName(v8::Local<TypeName> value) { \ |
|
1146 |
64 |
PropertyName ## _.Reset(isolate(), value); \ |
|
1147 |
64 |
} |
|
1148 |
320944 |
ENVIRONMENT_STRONG_PERSISTENT_TEMPLATES(V) |
|
1149 |
2125960 |
ENVIRONMENT_STRONG_PERSISTENT_VALUES(V) |
|
1150 |
83342 |
#undef V |
|
1151 |
74051 |
||
1152 |
8523568 |
v8::Local<v8::Context> Environment::context() const { |
|
1153 |
9225666 |
return PersistentToLocal::Strong(context_); |
|
1154 |
769656 |
} |
|
1155 |
109758 |
||
1156 |
94627 |
} // namespace node |
|
1157 |
15246 |
||
1158 |
27514 |
// These two files depend on each other. Including base_object-inl.h after this |
|
1159 |
27886 |
// file is the easiest way to avoid issues with that circular dependency. |
|
1160 |
49621 |
#include "base_object-inl.h" |
|
1161 |
44572 |
||
1162 |
64070 |
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS |
|
1163 |
62688 |
||
1164 |
15547 |
#endif // SRC_ENV_INL_H_ |
Generated by: GCOVR (Version 3.4) |