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 |
846799 |
inline uv_loop_t* IsolateData::event_loop() const { |
|
49 |
846799 |
return event_loop_; |
|
50 |
} |
||
51 |
|||
52 |
656598 |
inline NodeArrayBufferAllocator* IsolateData::node_allocator() const { |
|
53 |
656598 |
return node_allocator_; |
|
54 |
} |
||
55 |
|||
56 |
27977 |
inline MultiIsolatePlatform* IsolateData::platform() const { |
|
57 |
27977 |
return platform_; |
|
58 |
} |
||
59 |
|||
60 |
408 |
inline void IsolateData::set_worker_context(worker::Worker* context) { |
|
61 |
✗✓ | 408 |
CHECK_NULL(worker_context_); // Should be set only once. |
62 |
408 |
worker_context_ = context; |
|
63 |
408 |
} |
|
64 |
|||
65 |
12131 |
inline worker::Worker* IsolateData::worker_context() const { |
|
66 |
12131 |
return worker_context_; |
|
67 |
} |
||
68 |
|||
69 |
215128 |
inline v8::Local<v8::String> IsolateData::async_wrap_provider(int index) const { |
|
70 |
430256 |
return async_wrap_providers_[index].Get(isolate_); |
|
71 |
} |
||
72 |
|||
73 |
4384125 |
inline AliasedUint32Array& AsyncHooks::fields() { |
|
74 |
4384125 |
return fields_; |
|
75 |
} |
||
76 |
|||
77 |
2489633 |
inline AliasedFloat64Array& AsyncHooks::async_id_fields() { |
|
78 |
2489633 |
return async_id_fields_; |
|
79 |
} |
||
80 |
|||
81 |
445 |
inline AliasedFloat64Array& AsyncHooks::async_ids_stack() { |
|
82 |
445 |
return async_ids_stack_; |
|
83 |
} |
||
84 |
|||
85 |
1337637 |
v8::Local<v8::Array> AsyncHooks::js_execution_async_resources() { |
|
86 |
✓✓ | 2675274 |
if (UNLIKELY(js_execution_async_resources_.IsEmpty())) { |
87 |
445 |
js_execution_async_resources_.Reset( |
|
88 |
890 |
env()->isolate(), v8::Array::New(env()->isolate())); |
|
89 |
} |
||
90 |
1337637 |
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 |
214640 |
inline v8::Local<v8::String> AsyncHooks::provider_string(int idx) { |
|
99 |
214640 |
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 |
1813979 |
inline Environment* AsyncHooks::env() { |
|
107 |
1813979 |
return Environment::ForAsyncHooks(this); |
|
108 |
} |
||
109 |
|||
110 |
// Remember to keep this code aligned with pushAsyncContext() in JS. |
||
111 |
1252994 |
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 |
✓✓ | 1252994 |
if (fields_[kCheck] > 0) { |
117 |
✗✓ | 1253194 |
CHECK_GE(async_id, -1); |
118 |
✗✓ | 1253194 |
CHECK_GE(trigger_async_id, -1); |
119 |
} |
||
120 |
|||
121 |
1253237 |
uint32_t offset = fields_[kStackLength]; |
|
122 |
✓✓ | 1253257 |
if (offset * 2 >= async_ids_stack_.Length()) |
123 |
10 |
grow_async_ids_stack(); |
|
124 |
1253232 |
async_ids_stack_[2 * offset] = async_id_fields_[kExecutionAsyncId]; |
|
125 |
1253186 |
async_ids_stack_[2 * offset + 1] = async_id_fields_[kTriggerAsyncId]; |
|
126 |
1253254 |
fields_[kStackLength] += 1; |
|
127 |
1253239 |
async_id_fields_[kExecutionAsyncId] = async_id; |
|
128 |
1253269 |
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 |
✓✗ | 1253201 |
if (!resource.IsEmpty()) { |
140 |
1253212 |
native_execution_async_resources_.resize(offset + 1); |
|
141 |
1252983 |
native_execution_async_resources_[offset].Reset(env()->isolate(), resource); |
|
142 |
} |
||
143 |
1253241 |
} |
|
144 |
|||
145 |
// Remember to keep this code aligned with popAsyncContext() in JS. |
||
146 |
1252793 |
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 |
✓✓ | 1252793 |
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 |
✓✓✓✓ ✓✓ |
1251784 |
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 |
1251769 |
uint32_t offset = fields_[kStackLength] - 1; |
|
171 |
1251772 |
async_id_fields_[kExecutionAsyncId] = async_ids_stack_[2 * offset]; |
|
172 |
1251771 |
async_id_fields_[kTriggerAsyncId] = async_ids_stack_[2 * offset + 1]; |
|
173 |
1251780 |
fields_[kStackLength] = offset; |
|
174 |
|||
175 |
✓✗✓✓ ✓✓ |
2503592 |
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 |
1251788 |
native_execution_async_resources_.resize(offset); |
|
185 |
✗✓ | 2503625 |
if (native_execution_async_resources_.size() < |
186 |
✓✓✗✓ |
1476393 |
native_execution_async_resources_.capacity() / 2 && |
187 |
224583 |
native_execution_async_resources_.size() > 16) { |
|
188 |
native_execution_async_resources_.shrink_to_fit(); |
||
189 |
} |
||
190 |
} |
||
191 |
|||
192 |
✓✓ | 2503600 |
if (UNLIKELY(js_execution_async_resources()->Length() > offset)) { |
193 |
170788 |
v8::HandleScope handle_scope(env()->isolate()); |
|
194 |
256182 |
USE(js_execution_async_resources()->Set( |
|
195 |
env()->context(), |
||
196 |
env()->length_string(), |
||
197 |
426970 |
v8::Integer::NewFromUnsigned(env()->isolate(), offset))); |
|
198 |
} |
||
199 |
|||
200 |
1251801 |
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 |
3819 |
USE(PersistentToLocal::Strong(js_execution_async_resources_)->Set( |
|
208 |
env()->context(), |
||
209 |
env()->length_string(), |
||
210 |
6365 |
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 |
510865 |
inline AsyncHooks::DefaultTriggerAsyncIdScope ::DefaultTriggerAsyncIdScope( |
|
224 |
510865 |
Environment* env, double default_trigger_async_id) |
|
225 |
510865 |
: async_hooks_(env->async_hooks()) { |
|
226 |
✓✗ | 510865 |
if (env->async_hooks()->fields()[AsyncHooks::kCheck] > 0) { |
227 |
✗✓ | 510865 |
CHECK_GE(default_trigger_async_id, 0); |
228 |
} |
||
229 |
|||
230 |
510865 |
old_default_trigger_async_id_ = |
|
231 |
1021730 |
async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId]; |
|
232 |
510865 |
async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId] = |
|
233 |
510865 |
default_trigger_async_id; |
|
234 |
510865 |
} |
|
235 |
|||
236 |
1021728 |
inline AsyncHooks::DefaultTriggerAsyncIdScope ::~DefaultTriggerAsyncIdScope() { |
|
237 |
510864 |
async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId] = |
|
238 |
1021728 |
old_default_trigger_async_id_; |
|
239 |
510864 |
} |
|
240 |
|||
241 |
1813534 |
Environment* Environment::ForAsyncHooks(AsyncHooks* hooks) { |
|
242 |
1813534 |
return ContainerOf(&Environment::async_hooks_, hooks); |
|
243 |
} |
||
244 |
|||
245 |
1242194 |
inline size_t Environment::async_callback_scope_depth() const { |
|
246 |
1242194 |
return async_callback_scope_depth_; |
|
247 |
} |
||
248 |
|||
249 |
1252490 |
inline void Environment::PushAsyncCallbackScope() { |
|
250 |
1252490 |
async_callback_scope_depth_++; |
|
251 |
1252490 |
} |
|
252 |
|||
253 |
1252364 |
inline void Environment::PopAsyncCallbackScope() { |
|
254 |
1252364 |
async_callback_scope_depth_--; |
|
255 |
1252364 |
} |
|
256 |
|||
257 |
445 |
inline AliasedUint32Array& ImmediateInfo::fields() { |
|
258 |
445 |
return fields_; |
|
259 |
} |
||
260 |
|||
261 |
475294 |
inline uint32_t ImmediateInfo::count() const { |
|
262 |
475294 |
return fields_[kCount]; |
|
263 |
} |
||
264 |
|||
265 |
622426 |
inline uint32_t ImmediateInfo::ref_count() const { |
|
266 |
622426 |
return fields_[kRefCount]; |
|
267 |
} |
||
268 |
|||
269 |
101550 |
inline bool ImmediateInfo::has_outstanding() const { |
|
270 |
101550 |
return fields_[kHasOutstanding] == 1; |
|
271 |
} |
||
272 |
|||
273 |
33169 |
inline void ImmediateInfo::ref_count_inc(uint32_t increment) { |
|
274 |
33169 |
fields_[kRefCount] += increment; |
|
275 |
33169 |
} |
|
276 |
|||
277 |
488638 |
inline void ImmediateInfo::ref_count_dec(uint32_t decrement) { |
|
278 |
488638 |
fields_[kRefCount] -= decrement; |
|
279 |
488649 |
} |
|
280 |
|||
281 |
445 |
inline AliasedUint8Array& TickInfo::fields() { |
|
282 |
445 |
return fields_; |
|
283 |
} |
||
284 |
|||
285 |
2320679 |
inline bool TickInfo::has_tick_scheduled() const { |
|
286 |
2320679 |
return fields_[kHasTickScheduled] == 1; |
|
287 |
} |
||
288 |
|||
289 |
749069 |
inline bool TickInfo::has_rejection_to_warn() const { |
|
290 |
749069 |
return fields_[kHasRejectionToWarn] == 1; |
|
291 |
} |
||
292 |
|||
293 |
5563 |
inline void Environment::AssignToContext(v8::Local<v8::Context> context, |
|
294 |
const ContextInfo& info) { |
||
295 |
5563 |
context->SetAlignedPointerInEmbedderData( |
|
296 |
5563 |
ContextEmbedderIndex::kEnvironment, this); |
|
297 |
// Used by Environment::GetCurrent to know that we are on a node context. |
||
298 |
11126 |
context->SetAlignedPointerInEmbedderData( |
|
299 |
5563 |
ContextEmbedderIndex::kContextTag, Environment::kNodeContextTagPtr); |
|
300 |
// Used to retrieve bindings |
||
301 |
5563 |
context->SetAlignedPointerInEmbedderData( |
|
302 |
11126 |
ContextEmbedderIndex::kBindingListIndex, &(this->bindings_)); |
|
303 |
|||
304 |
#if HAVE_INSPECTOR |
||
305 |
5563 |
inspector_agent()->ContextCreated(context, info); |
|
306 |
#endif // HAVE_INSPECTOR |
||
307 |
5563 |
} |
|
308 |
|||
309 |
1284366 |
inline Environment* Environment::GetCurrent(v8::Isolate* isolate) { |
|
310 |
✓✓ | 1284366 |
if (UNLIKELY(!isolate->InContext())) return nullptr; |
311 |
2565927 |
v8::HandleScope handle_scope(isolate); |
|
312 |
1282829 |
return GetCurrent(isolate->GetCurrentContext()); |
|
313 |
} |
||
314 |
|||
315 |
6170302 |
inline Environment* Environment::GetCurrent(v8::Local<v8::Context> context) { |
|
316 |
✓✓ | 6170302 |
if (UNLIKELY(context.IsEmpty())) { |
317 |
1 |
return nullptr; |
|
318 |
} |
||
319 |
✓✓ | 6170301 |
if (UNLIKELY(context->GetNumberOfEmbedderDataFields() <= |
320 |
ContextEmbedderIndex::kContextTag)) { |
||
321 |
11 |
return nullptr; |
|
322 |
} |
||
323 |
✗✓ | 12341432 |
if (UNLIKELY(context->GetAlignedPointerFromEmbedderData( |
324 |
ContextEmbedderIndex::kContextTag) != |
||
325 |
Environment::kNodeContextTagPtr)) { |
||
326 |
return nullptr; |
||
327 |
} |
||
328 |
return static_cast<Environment*>( |
||
329 |
6170716 |
context->GetAlignedPointerFromEmbedderData( |
|
330 |
6170716 |
ContextEmbedderIndex::kEnvironment)); |
|
331 |
} |
||
332 |
|||
333 |
3227260 |
inline Environment* Environment::GetCurrent( |
|
334 |
const v8::FunctionCallbackInfo<v8::Value>& info) { |
||
335 |
3227260 |
return GetCurrent(info.GetIsolate()->GetCurrentContext()); |
|
336 |
} |
||
337 |
|||
338 |
template <typename T> |
||
339 |
1266480 |
inline Environment* Environment::GetCurrent( |
|
340 |
const v8::PropertyCallbackInfo<T>& info) { |
||
341 |
1266480 |
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 |
670222 |
inline T* Environment::GetBindingData( |
|
351 |
const v8::FunctionCallbackInfo<v8::Value>& info) { |
||
352 |
670222 |
return GetBindingData<T>(info.GetIsolate()->GetCurrentContext()); |
|
353 |
} |
||
354 |
|||
355 |
template <typename T> |
||
356 |
670233 |
inline T* Environment::GetBindingData(v8::Local<v8::Context> context) { |
|
357 |
BindingDataStore* map = static_cast<BindingDataStore*>( |
||
358 |
670233 |
context->GetAlignedPointerFromEmbedderData( |
|
359 |
670233 |
ContextEmbedderIndex::kBindingListIndex)); |
|
360 |
DCHECK_NOT_NULL(map); |
||
361 |
670233 |
auto it = map->find(T::binding_data_name); |
|
362 |
✗✓ | 670233 |
if (UNLIKELY(it == map->end())) return nullptr; |
363 |
670232 |
T* result = static_cast<T*>(it->second.get()); |
|
364 |
DCHECK_NOT_NULL(result); |
||
365 |
DCHECK_EQ(result->env(), GetCurrent(context)); |
||
366 |
670231 |
return result; |
|
367 |
} |
||
368 |
|||
369 |
template <typename T> |
||
370 |
6617 |
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 |
13234 |
BaseObjectPtr<T> item = MakeDetachedBaseObject<T>(this, target); |
|
376 |
BindingDataStore* map = static_cast<BindingDataStore*>( |
||
377 |
6617 |
context->GetAlignedPointerFromEmbedderData( |
|
378 |
6617 |
ContextEmbedderIndex::kBindingListIndex)); |
|
379 |
DCHECK_NOT_NULL(map); |
||
380 |
6617 |
auto result = map->emplace(T::binding_data_name, item); |
|
381 |
✗✓ | 6617 |
CHECK(result.second); |
382 |
DCHECK_EQ(GetBindingData<T>(context), item.get()); |
||
383 |
13234 |
return item.get(); |
|
384 |
} |
||
385 |
|||
386 |
28573445 |
inline v8::Isolate* Environment::isolate() const { |
|
387 |
28573445 |
return isolate_; |
|
388 |
} |
||
389 |
|||
390 |
5230 |
inline Environment* Environment::from_timer_handle(uv_timer_t* handle) { |
|
391 |
5230 |
return ContainerOf(&Environment::timer_handle_, handle); |
|
392 |
} |
||
393 |
|||
394 |
22636 |
inline uv_timer_t* Environment::timer_handle() { |
|
395 |
22636 |
return &timer_handle_; |
|
396 |
} |
||
397 |
|||
398 |
475292 |
inline Environment* Environment::from_immediate_check_handle( |
|
399 |
uv_check_t* handle) { |
||
400 |
475292 |
return ContainerOf(&Environment::immediate_check_handle_, handle); |
|
401 |
} |
||
402 |
|||
403 |
20020 |
inline uv_check_t* Environment::immediate_check_handle() { |
|
404 |
20020 |
return &immediate_check_handle_; |
|
405 |
} |
||
406 |
|||
407 |
516946 |
inline uv_idle_t* Environment::immediate_idle_handle() { |
|
408 |
516946 |
return &immediate_idle_handle_; |
|
409 |
} |
||
410 |
|||
411 |
20020 |
inline void Environment::RegisterHandleCleanup(uv_handle_t* handle, |
|
412 |
HandleCleanupCb cb, |
||
413 |
void* arg) { |
||
414 |
20020 |
handle_cleanup_queue_.push_back(HandleCleanup{handle, cb, arg}); |
|
415 |
20020 |
} |
|
416 |
|||
417 |
template <typename T, typename OnCloseCallback> |
||
418 |
22388 |
inline void Environment::CloseHandle(T* handle, OnCloseCallback callback) { |
|
419 |
22388 |
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 |
22388 |
handle->data = new CloseData { this, callback, handle->data }; |
|
431 |
89566 |
uv_close(reinterpret_cast<uv_handle_t*>(handle), [](uv_handle_t* handle) { |
|
432 |
44779 |
std::unique_ptr<CloseData> data { static_cast<CloseData*>(handle->data) }; |
|
433 |
22393 |
data->env->handle_cleanup_waiting_--; |
|
434 |
22392 |
handle->data = data->original_data; |
|
435 |
22392 |
data->callback(reinterpret_cast<T*>(handle)); |
|
436 |
22392 |
}); |
|
437 |
22390 |
} |
|
438 |
|||
439 |
82807 |
void Environment::IncreaseWaitingRequestCounter() { |
|
440 |
82807 |
request_waiting_++; |
|
441 |
82807 |
} |
|
442 |
|||
443 |
82801 |
void Environment::DecreaseWaitingRequestCounter() { |
|
444 |
82801 |
request_waiting_--; |
|
445 |
✗✓ | 82801 |
CHECK_GE(request_waiting_, 0); |
446 |
82801 |
} |
|
447 |
|||
448 |
841760 |
inline uv_loop_t* Environment::event_loop() const { |
|
449 |
841760 |
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 |
17438 |
inline bool Environment::is_in_inspector_console_call() const { |
|
464 |
17438 |
return is_in_inspector_console_call_; |
|
465 |
} |
||
466 |
|||
467 |
34874 |
inline void Environment::set_is_in_inspector_console_call(bool value) { |
|
468 |
34874 |
is_in_inspector_console_call_ = value; |
|
469 |
34874 |
} |
|
470 |
#endif |
||
471 |
|||
472 |
7198143 |
inline AsyncHooks* Environment::async_hooks() { |
|
473 |
7198143 |
return &async_hooks_; |
|
474 |
} |
||
475 |
|||
476 |
1721529 |
inline ImmediateInfo* Environment::immediate_info() { |
|
477 |
1721529 |
return &immediate_info_; |
|
478 |
} |
||
479 |
|||
480 |
1160866 |
inline TickInfo* Environment::tick_info() { |
|
481 |
1160866 |
return &tick_info_; |
|
482 |
} |
||
483 |
|||
484 |
50739 |
inline uint64_t Environment::timer_base() const { |
|
485 |
50739 |
return timer_base_; |
|
486 |
} |
||
487 |
|||
488 |
1279402 |
inline std::shared_ptr<KVStore> Environment::env_vars() { |
|
489 |
1279402 |
return env_vars_; |
|
490 |
} |
||
491 |
|||
492 |
5431 |
inline void Environment::set_env_vars(std::shared_ptr<KVStore> env_vars) { |
|
493 |
5431 |
env_vars_ = env_vars; |
|
494 |
5431 |
} |
|
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 |
9125 |
inline void Environment::set_trace_sync_io(bool value) { |
|
505 |
9125 |
trace_sync_io_ = value; |
|
506 |
9125 |
} |
|
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 |
396 |
inline void Environment::set_abort_on_uncaught_exception(bool value) { |
|
521 |
396 |
options_->abort_on_uncaught_exception = value; |
|
522 |
396 |
} |
|
523 |
|||
524 |
475 |
inline AliasedUint32Array& Environment::should_abort_on_uncaught_toggle() { |
|
525 |
475 |
return should_abort_on_uncaught_toggle_; |
|
526 |
} |
||
527 |
|||
528 |
1294493 |
inline AliasedInt32Array& Environment::stream_base_state() { |
|
529 |
1294493 |
return stream_base_state_; |
|
530 |
} |
||
531 |
|||
532 |
33592 |
inline uint32_t Environment::get_next_module_id() { |
|
533 |
33592 |
return module_id_counter_++; |
|
534 |
} |
||
535 |
1961 |
inline uint32_t Environment::get_next_script_id() { |
|
536 |
1961 |
return script_id_counter_++; |
|
537 |
} |
||
538 |
30592 |
inline uint32_t Environment::get_next_function_id() { |
|
539 |
30592 |
return function_id_counter_++; |
|
540 |
} |
||
541 |
|||
542 |
68901 |
ShouldNotAbortOnUncaughtScope::ShouldNotAbortOnUncaughtScope( |
|
543 |
68901 |
Environment* env) |
|
544 |
68901 |
: env_(env) { |
|
545 |
68901 |
env_->PushShouldNotAbortOnUncaughtScope(); |
|
546 |
68901 |
} |
|
547 |
|||
548 |
137799 |
ShouldNotAbortOnUncaughtScope::~ShouldNotAbortOnUncaughtScope() { |
|
549 |
68899 |
Close(); |
|
550 |
68900 |
} |
|
551 |
|||
552 |
69083 |
void ShouldNotAbortOnUncaughtScope::Close() { |
|
553 |
✓✓ | 69083 |
if (env_ != nullptr) { |
554 |
68899 |
env_->PopShouldNotAbortOnUncaughtScope(); |
|
555 |
68900 |
env_ = nullptr; |
|
556 |
} |
||
557 |
69084 |
} |
|
558 |
|||
559 |
68901 |
inline void Environment::PushShouldNotAbortOnUncaughtScope() { |
|
560 |
68901 |
should_not_abort_scope_counter_++; |
|
561 |
68901 |
} |
|
562 |
|||
563 |
68900 |
inline void Environment::PopShouldNotAbortOnUncaughtScope() { |
|
564 |
68900 |
should_not_abort_scope_counter_--; |
|
565 |
68900 |
} |
|
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 |
371553 |
inline std::vector<double>* Environment::destroy_async_id_list() { |
|
572 |
371553 |
return &destroy_async_id_list_; |
|
573 |
} |
||
574 |
|||
575 |
215226 |
inline double Environment::new_async_id() { |
|
576 |
215226 |
async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter] += 1; |
|
577 |
215226 |
return async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter]; |
|
578 |
} |
||
579 |
|||
580 |
246666 |
inline double Environment::execution_async_id() { |
|
581 |
246666 |
return async_hooks()->async_id_fields()[AsyncHooks::kExecutionAsyncId]; |
|
582 |
} |
||
583 |
|||
584 |
64259 |
inline double Environment::trigger_async_id() { |
|
585 |
64259 |
return async_hooks()->async_id_fields()[AsyncHooks::kTriggerAsyncId]; |
|
586 |
} |
||
587 |
|||
588 |
215223 |
inline double Environment::get_default_trigger_async_id() { |
|
589 |
double default_trigger_async_id = |
||
590 |
215223 |
async_hooks()->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId]; |
|
591 |
// If defaultTriggerAsyncId isn't set, use the executionAsyncId |
||
592 |
✓✓ | 215223 |
if (default_trigger_async_id < 0) |
593 |
171706 |
default_trigger_async_id = execution_async_id(); |
|
594 |
215223 |
return default_trigger_async_id; |
|
595 |
} |
||
596 |
|||
597 |
56898 |
inline std::shared_ptr<EnvironmentOptions> Environment::options() { |
|
598 |
56898 |
return options_; |
|
599 |
} |
||
600 |
|||
601 |
14520 |
inline const std::vector<std::string>& Environment::argv() { |
|
602 |
14520 |
return argv_; |
|
603 |
} |
||
604 |
|||
605 |
5538 |
inline const std::vector<std::string>& Environment::exec_argv() { |
|
606 |
5538 |
return exec_argv_; |
|
607 |
} |
||
608 |
|||
609 |
10010 |
inline const std::string& Environment::exec_path() const { |
|
610 |
10010 |
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 |
4999 |
inline void Environment::set_coverage_directory(const char* dir) { |
|
631 |
4999 |
coverage_directory_ = std::string(dir); |
|
632 |
4999 |
} |
|
633 |
|||
634 |
5020 |
inline void Environment::set_coverage_connection( |
|
635 |
std::unique_ptr<profiler::V8CoverageConnection> connection) { |
||
636 |
✗✓ | 5020 |
CHECK_NULL(coverage_connection_); |
637 |
5020 |
std::swap(coverage_connection_, connection); |
|
638 |
5020 |
} |
|
639 |
|||
640 |
15062 |
inline profiler::V8CoverageConnection* Environment::coverage_connection() { |
|
641 |
15062 |
return coverage_connection_.get(); |
|
642 |
} |
||
643 |
|||
644 |
4987 |
inline const std::string& Environment::coverage_directory() const { |
|
645 |
4987 |
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 |
5038 |
Environment::cpu_profiler_connection() { |
|
656 |
5038 |
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 |
5026 |
Environment::heap_profiler_connection() { |
|
691 |
5026 |
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 |
10169 |
std::shared_ptr<ExclusiveAccess<HostPort>> Environment::inspector_host_port() { |
|
722 |
10169 |
return inspector_host_port_; |
|
723 |
} |
||
724 |
|||
725 |
68801 |
inline std::shared_ptr<PerIsolateOptions> IsolateData::options() { |
|
726 |
68801 |
return options_; |
|
727 |
} |
||
728 |
|||
729 |
100 |
inline void IsolateData::set_options( |
|
730 |
std::shared_ptr<PerIsolateOptions> options) { |
||
731 |
100 |
options_ = std::move(options); |
|
732 |
100 |
} |
|
733 |
|||
734 |
template <typename Fn> |
||
735 |
55434 |
void Environment::SetImmediate(Fn&& cb, CallbackFlags::Flags flags) { |
|
736 |
110868 |
auto callback = native_immediates_.CreateCallback(std::move(cb), flags); |
|
737 |
55434 |
native_immediates_.Push(std::move(callback)); |
|
738 |
|||
739 |
✓✓✓✓ ✓✗✓✗ ✓✗ |
55434 |
if (flags & CallbackFlags::kRefed) { |
740 |
✓✓✓✓ ✓✓✓✗ ✓✓ |
33169 |
if (immediate_info()->ref_count() == 0) |
741 |
24984 |
ToggleImmediateRef(true); |
|
742 |
33169 |
immediate_info()->ref_count_inc(1); |
|
743 |
} |
||
744 |
55434 |
} |
|
745 |
|||
746 |
template <typename Fn> |
||
747 |
1227 |
void Environment::SetImmediateThreadsafe(Fn&& cb, CallbackFlags::Flags flags) { |
|
748 |
auto callback = native_immediates_threadsafe_.CreateCallback( |
||
749 |
2458 |
std::move(cb), flags); |
|
750 |
{ |
||
751 |
2458 |
Mutex::ScopedLock lock(native_immediates_threadsafe_mutex_); |
|
752 |
1231 |
native_immediates_threadsafe_.Push(std::move(callback)); |
|
753 |
✓✓✓✗ |
1231 |
if (task_queues_async_initialized_) |
754 |
961 |
uv_async_send(&task_queues_async_); |
|
755 |
} |
||
756 |
1231 |
} |
|
757 |
|||
758 |
template <typename Fn> |
||
759 |
8076 |
void Environment::RequestInterrupt(Fn&& cb) { |
|
760 |
auto callback = native_immediates_interrupts_.CreateCallback( |
||
761 |
16152 |
std::move(cb), CallbackFlags::kRefed); |
|
762 |
{ |
||
763 |
16152 |
Mutex::ScopedLock lock(native_immediates_threadsafe_mutex_); |
|
764 |
8076 |
native_immediates_interrupts_.Push(std::move(callback)); |
|
765 |
✓✓ | 8076 |
if (task_queues_async_initialized_) |
766 |
2932 |
uv_async_send(&task_queues_async_); |
|
767 |
} |
||
768 |
8076 |
RequestInterruptFromV8(); |
|
769 |
8076 |
} |
|
770 |
|||
771 |
4435545 |
inline bool Environment::can_call_into_js() const { |
|
772 |
✓✓✓✓ |
4435545 |
return can_call_into_js_ && !is_stopping(); |
773 |
} |
||
774 |
|||
775 |
955 |
inline void Environment::set_can_call_into_js(bool can_call_into_js) { |
|
776 |
955 |
can_call_into_js_ = can_call_into_js; |
|
777 |
956 |
} |
|
778 |
|||
779 |
1405621 |
inline bool Environment::has_run_bootstrapping_code() const { |
|
780 |
1405621 |
return has_run_bootstrapping_code_; |
|
781 |
} |
||
782 |
|||
783 |
5039 |
inline void Environment::set_has_run_bootstrapping_code(bool value) { |
|
784 |
5039 |
has_run_bootstrapping_code_ = value; |
|
785 |
5039 |
} |
|
786 |
|||
787 |
19 |
inline bool Environment::has_serialized_options() const { |
|
788 |
19 |
return has_serialized_options_; |
|
789 |
} |
||
790 |
|||
791 |
5005 |
inline void Environment::set_has_serialized_options(bool value) { |
|
792 |
5005 |
has_serialized_options_ = value; |
|
793 |
5005 |
} |
|
794 |
|||
795 |
6747 |
inline bool Environment::is_main_thread() const { |
|
796 |
6747 |
return worker_context() == nullptr; |
|
797 |
} |
||
798 |
|||
799 |
5005 |
inline bool Environment::should_not_register_esm_loader() const { |
|
800 |
5005 |
return flags_ & EnvironmentFlags::kNoRegisterESMLoader; |
|
801 |
} |
||
802 |
|||
803 |
12346 |
inline bool Environment::owns_process_state() const { |
|
804 |
12346 |
return flags_ & EnvironmentFlags::kOwnsProcessState; |
|
805 |
} |
||
806 |
|||
807 |
5030 |
inline bool Environment::owns_inspector() const { |
|
808 |
5030 |
return flags_ & EnvironmentFlags::kOwnsInspector; |
|
809 |
} |
||
810 |
|||
811 |
104589 |
inline bool Environment::tracks_unmanaged_fds() const { |
|
812 |
104589 |
return flags_ & EnvironmentFlags::kTrackUnmanagedFds; |
|
813 |
} |
||
814 |
|||
815 |
2 |
bool Environment::filehandle_close_warning() const { |
|
816 |
2 |
return emit_filehandle_warning_; |
|
817 |
} |
||
818 |
|||
819 |
2 |
void Environment::set_filehandle_close_warning(bool on) { |
|
820 |
2 |
emit_filehandle_warning_ = on; |
|
821 |
2 |
} |
|
822 |
|||
823 |
15 |
void Environment::set_source_maps_enabled(bool on) { |
|
824 |
15 |
source_maps_enabled_ = on; |
|
825 |
15 |
} |
|
826 |
|||
827 |
904 |
bool Environment::source_maps_enabled() const { |
|
828 |
904 |
return source_maps_enabled_; |
|
829 |
} |
||
830 |
|||
831 |
5902 |
inline uint64_t Environment::thread_id() const { |
|
832 |
5902 |
return thread_id_; |
|
833 |
} |
||
834 |
|||
835 |
12131 |
inline worker::Worker* Environment::worker_context() const { |
|
836 |
12131 |
return isolate_data()->worker_context(); |
|
837 |
} |
||
838 |
|||
839 |
629 |
inline void Environment::add_sub_worker_context(worker::Worker* context) { |
|
840 |
629 |
sub_worker_contexts_.insert(context); |
|
841 |
629 |
} |
|
842 |
|||
843 |
655 |
inline void Environment::remove_sub_worker_context(worker::Worker* context) { |
|
844 |
655 |
sub_worker_contexts_.erase(context); |
|
845 |
655 |
} |
|
846 |
|||
847 |
template <typename Fn> |
||
848 |
22 |
inline void Environment::ForEachWorker(Fn&& iterator) { |
|
849 |
✓✓ | 22 |
for (worker::Worker* w : sub_worker_contexts_) iterator(w); |
850 |
22 |
} |
|
851 |
|||
852 |
1242 |
inline void Environment::add_refs(int64_t diff) { |
|
853 |
1242 |
task_queues_async_refs_ += diff; |
|
854 |
✗✓ | 1242 |
CHECK_GE(task_queues_async_refs_, 0); |
855 |
✓✓ | 1242 |
if (task_queues_async_refs_ == 0) |
856 |
158 |
uv_unref(reinterpret_cast<uv_handle_t*>(&task_queues_async_)); |
|
857 |
else |
||
858 |
1084 |
uv_ref(reinterpret_cast<uv_handle_t*>(&task_queues_async_)); |
|
859 |
1242 |
} |
|
860 |
|||
861 |
6856916 |
inline bool Environment::is_stopping() const { |
|
862 |
6856916 |
return is_stopping_.load(); |
|
863 |
} |
||
864 |
|||
865 |
4663 |
inline void Environment::set_stopping(bool value) { |
|
866 |
4663 |
is_stopping_.store(value); |
|
867 |
4664 |
} |
|
868 |
|||
869 |
3 |
inline std::list<node_module>* Environment::extra_linked_bindings() { |
|
870 |
3 |
return &extra_linked_bindings_; |
|
871 |
} |
||
872 |
|||
873 |
7 |
inline node_module* Environment::extra_linked_bindings_head() { |
|
874 |
✓✓ | 10 |
return extra_linked_bindings_.size() > 0 ? |
875 |
10 |
&extra_linked_bindings_.front() : nullptr; |
|
876 |
} |
||
877 |
|||
878 |
7 |
inline const Mutex& Environment::extra_linked_bindings_mutex() const { |
|
879 |
7 |
return extra_linked_bindings_mutex_; |
|
880 |
} |
||
881 |
|||
882 |
42904 |
inline performance::PerformanceState* Environment::performance_state() { |
|
883 |
42904 |
return performance_state_.get(); |
|
884 |
} |
||
885 |
|||
886 |
inline std::unordered_map<std::string, uint64_t>* |
||
887 |
49 |
Environment::performance_marks() { |
|
888 |
49 |
return &performance_marks_; |
|
889 |
} |
||
890 |
|||
891 |
5570673 |
inline IsolateData* Environment::isolate_data() const { |
|
892 |
5570673 |
return isolate_data_; |
|
893 |
} |
||
894 |
|||
895 |
std::unordered_map<char*, std::unique_ptr<v8::BackingStore>>* |
||
896 |
625472 |
Environment::released_allocated_buffers() { |
|
897 |
625472 |
return &released_allocated_buffers_; |
|
898 |
} |
||
899 |
|||
900 |
7 |
inline void Environment::ThrowError(const char* errmsg) { |
|
901 |
7 |
ThrowError(v8::Exception::Error, errmsg); |
|
902 |
7 |
} |
|
903 |
|||
904 |
inline void Environment::ThrowTypeError(const char* errmsg) { |
||
905 |
ThrowError(v8::Exception::TypeError, errmsg); |
||
906 |
} |
||
907 |
|||
908 |
inline void Environment::ThrowRangeError(const char* errmsg) { |
||
909 |
ThrowError(v8::Exception::RangeError, errmsg); |
||
910 |
} |
||
911 |
|||
912 |
7 |
inline void Environment::ThrowError( |
|
913 |
v8::Local<v8::Value> (*fun)(v8::Local<v8::String>), |
||
914 |
const char* errmsg) { |
||
915 |
14 |
v8::HandleScope handle_scope(isolate()); |
|
916 |
7 |
isolate()->ThrowException(fun(OneByteString(isolate(), errmsg))); |
|
917 |
7 |
} |
|
918 |
|||
919 |
3 |
inline void Environment::ThrowErrnoException(int errorno, |
|
920 |
const char* syscall, |
||
921 |
const char* message, |
||
922 |
const char* path) { |
||
923 |
isolate()->ThrowException( |
||
924 |
3 |
ErrnoException(isolate(), errorno, syscall, message, path)); |
|
925 |
3 |
} |
|
926 |
|||
927 |
14 |
inline void Environment::ThrowUVException(int errorno, |
|
928 |
const char* syscall, |
||
929 |
const char* message, |
||
930 |
const char* path, |
||
931 |
const char* dest) { |
||
932 |
isolate()->ThrowException( |
||
933 |
14 |
UVException(isolate(), errorno, syscall, message, path, dest)); |
|
934 |
14 |
} |
|
935 |
|||
936 |
inline v8::Local<v8::FunctionTemplate> |
||
937 |
1214465 |
Environment::NewFunctionTemplate(v8::FunctionCallback callback, |
|
938 |
v8::Local<v8::Signature> signature, |
||
939 |
v8::ConstructorBehavior behavior, |
||
940 |
v8::SideEffectType side_effect_type) { |
||
941 |
return v8::FunctionTemplate::New(isolate(), callback, v8::Local<v8::Value>(), |
||
942 |
1214465 |
signature, 0, behavior, side_effect_type); |
|
943 |
} |
||
944 |
|||
945 |
436832 |
inline void Environment::SetMethod(v8::Local<v8::Object> that, |
|
946 |
const char* name, |
||
947 |
v8::FunctionCallback callback) { |
||
948 |
436832 |
v8::Local<v8::Context> context = isolate()->GetCurrentContext(); |
|
949 |
v8::Local<v8::Function> function = |
||
950 |
873663 |
NewFunctionTemplate(callback, v8::Local<v8::Signature>(), |
|
951 |
v8::ConstructorBehavior::kThrow, |
||
952 |
436835 |
v8::SideEffectType::kHasSideEffect) |
|
953 |
873674 |
->GetFunction(context) |
|
954 |
436835 |
.ToLocalChecked(); |
|
955 |
// kInternalized strings are created in the old space. |
||
956 |
436835 |
const v8::NewStringType type = v8::NewStringType::kInternalized; |
|
957 |
v8::Local<v8::String> name_string = |
||
958 |
873675 |
v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked(); |
|
959 |
873670 |
that->Set(context, name_string, function).Check(); |
|
960 |
436830 |
function->SetName(name_string); // NODE_SET_METHOD() compatibility. |
|
961 |
436841 |
} |
|
962 |
|||
963 |
51970 |
inline void Environment::SetMethodNoSideEffect(v8::Local<v8::Object> that, |
|
964 |
const char* name, |
||
965 |
v8::FunctionCallback callback) { |
||
966 |
51970 |
v8::Local<v8::Context> context = isolate()->GetCurrentContext(); |
|
967 |
v8::Local<v8::Function> function = |
||
968 |
103938 |
NewFunctionTemplate(callback, v8::Local<v8::Signature>(), |
|
969 |
v8::ConstructorBehavior::kThrow, |
||
970 |
51969 |
v8::SideEffectType::kHasNoSideEffect) |
|
971 |
103940 |
->GetFunction(context) |
|
972 |
51969 |
.ToLocalChecked(); |
|
973 |
// kInternalized strings are created in the old space. |
||
974 |
51969 |
const v8::NewStringType type = v8::NewStringType::kInternalized; |
|
975 |
v8::Local<v8::String> name_string = |
||
976 |
103941 |
v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked(); |
|
977 |
103944 |
that->Set(context, name_string, function).Check(); |
|
978 |
51972 |
function->SetName(name_string); // NODE_SET_METHOD() compatibility. |
|
979 |
51972 |
} |
|
980 |
|||
981 |
510775 |
inline void Environment::SetProtoMethod(v8::Local<v8::FunctionTemplate> that, |
|
982 |
const char* name, |
||
983 |
v8::FunctionCallback callback) { |
||
984 |
510775 |
v8::Local<v8::Signature> signature = v8::Signature::New(isolate(), that); |
|
985 |
v8::Local<v8::FunctionTemplate> t = |
||
986 |
NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow, |
||
987 |
510775 |
v8::SideEffectType::kHasSideEffect); |
|
988 |
// kInternalized strings are created in the old space. |
||
989 |
510774 |
const v8::NewStringType type = v8::NewStringType::kInternalized; |
|
990 |
v8::Local<v8::String> name_string = |
||
991 |
1021550 |
v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked(); |
|
992 |
1021552 |
that->PrototypeTemplate()->Set(name_string, t); |
|
993 |
510776 |
t->SetClassName(name_string); // NODE_SET_PROTOTYPE_METHOD() compatibility. |
|
994 |
510777 |
} |
|
995 |
|||
996 |
48414 |
inline void Environment::SetProtoMethodNoSideEffect( |
|
997 |
v8::Local<v8::FunctionTemplate> that, |
||
998 |
const char* name, |
||
999 |
v8::FunctionCallback callback) { |
||
1000 |
48414 |
v8::Local<v8::Signature> signature = v8::Signature::New(isolate(), that); |
|
1001 |
v8::Local<v8::FunctionTemplate> t = |
||
1002 |
NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow, |
||
1003 |
48413 |
v8::SideEffectType::kHasNoSideEffect); |
|
1004 |
// kInternalized strings are created in the old space. |
||
1005 |
48414 |
const v8::NewStringType type = v8::NewStringType::kInternalized; |
|
1006 |
v8::Local<v8::String> name_string = |
||
1007 |
96828 |
v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked(); |
|
1008 |
96828 |
that->PrototypeTemplate()->Set(name_string, t); |
|
1009 |
48414 |
t->SetClassName(name_string); // NODE_SET_PROTOTYPE_METHOD() compatibility. |
|
1010 |
48414 |
} |
|
1011 |
|||
1012 |
32 |
inline void Environment::SetInstanceMethod(v8::Local<v8::FunctionTemplate> that, |
|
1013 |
const char* name, |
||
1014 |
v8::FunctionCallback callback) { |
||
1015 |
32 |
v8::Local<v8::Signature> signature = v8::Signature::New(isolate(), that); |
|
1016 |
v8::Local<v8::FunctionTemplate> t = |
||
1017 |
NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow, |
||
1018 |
32 |
v8::SideEffectType::kHasSideEffect); |
|
1019 |
// kInternalized strings are created in the old space. |
||
1020 |
32 |
const v8::NewStringType type = v8::NewStringType::kInternalized; |
|
1021 |
v8::Local<v8::String> name_string = |
||
1022 |
64 |
v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked(); |
|
1023 |
64 |
that->InstanceTemplate()->Set(name_string, t); |
|
1024 |
32 |
t->SetClassName(name_string); |
|
1025 |
32 |
} |
|
1026 |
|||
1027 |
319919 |
void Environment::AddCleanupHook(void (*fn)(void*), void* arg) { |
|
1028 |
639840 |
auto insertion_info = cleanup_hooks_.emplace(CleanupHookCallback { |
|
1029 |
319919 |
fn, arg, cleanup_hook_counter_++ |
|
1030 |
319921 |
}); |
|
1031 |
// Make sure there was no existing element with these values. |
||
1032 |
✗✓ | 319921 |
CHECK_EQ(insertion_info.second, true); |
1033 |
319921 |
} |
|
1034 |
|||
1035 |
308277 |
void Environment::RemoveCleanupHook(void (*fn)(void*), void* arg) { |
|
1036 |
308277 |
CleanupHookCallback search { fn, arg, 0 }; |
|
1037 |
308276 |
cleanup_hooks_.erase(search); |
|
1038 |
308284 |
} |
|
1039 |
|||
1040 |
853039 |
size_t CleanupHookCallback::Hash::operator()( |
|
1041 |
const CleanupHookCallback& cb) const { |
||
1042 |
853039 |
return std::hash<void*>()(cb.arg_); |
|
1043 |
} |
||
1044 |
|||
1045 |
424638 |
bool CleanupHookCallback::Equal::operator()( |
|
1046 |
const CleanupHookCallback& a, const CleanupHookCallback& b) const { |
||
1047 |
✓✓✓✗ |
424638 |
return a.fn_ == b.fn_ && a.arg_ == b.arg_; |
1048 |
} |
||
1049 |
|||
1050 |
406 |
BaseObject* CleanupHookCallback::GetBaseObject() const { |
|
1051 |
✓✓ | 406 |
if (fn_ == BaseObject::DeleteMe) |
1052 |
384 |
return static_cast<BaseObject*>(arg_); |
|
1053 |
else |
||
1054 |
22 |
return nullptr; |
|
1055 |
} |
||
1056 |
|||
1057 |
template <typename T> |
||
1058 |
22 |
void Environment::ForEachBaseObject(T&& iterator) { |
|
1059 |
✗✗✓✓ ✗✗ |
428 |
for (const auto& hook : cleanup_hooks_) { |
1060 |
406 |
BaseObject* obj = hook.GetBaseObject(); |
|
1061 |
✓✓✗✗ ✗✗ |
406 |
if (obj != nullptr) |
1062 |
384 |
iterator(obj); |
|
1063 |
} |
||
1064 |
22 |
} |
|
1065 |
|||
1066 |
616407 |
void Environment::modify_base_object_count(int64_t delta) { |
|
1067 |
616407 |
base_object_count_ += delta; |
|
1068 |
616407 |
} |
|
1069 |
|||
1070 |
10093 |
int64_t Environment::base_object_count() const { |
|
1071 |
10093 |
return base_object_count_ - initial_base_object_count_; |
|
1072 |
} |
||
1073 |
|||
1074 |
13 |
void Environment::set_main_utf16(std::unique_ptr<v8::String::Value> str) { |
|
1075 |
✗✓ | 13 |
CHECK(!main_utf16_); |
1076 |
13 |
main_utf16_ = std::move(str); |
|
1077 |
13 |
} |
|
1078 |
|||
1079 |
396 |
void Environment::set_process_exit_handler( |
|
1080 |
std::function<void(Environment*, int)>&& handler) { |
||
1081 |
396 |
process_exit_handler_ = std::move(handler); |
|
1082 |
396 |
} |
|
1083 |
|||
1084 |
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName) |
||
1085 |
#define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName) |
||
1086 |
#define VS(PropertyName, StringValue) V(v8::String, PropertyName) |
||
1087 |
#define V(TypeName, PropertyName) \ |
||
1088 |
inline \ |
||
1089 |
v8::Local<TypeName> IsolateData::PropertyName() const { \ |
||
1090 |
return PropertyName ## _ .Get(isolate_); \ |
||
1091 |
} |
||
1092 |
209 |
PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP) |
|
1093 |
4390 |
PER_ISOLATE_SYMBOL_PROPERTIES(VY) |
|
1094 |
6703616 |
PER_ISOLATE_STRING_PROPERTIES(VS) |
|
1095 |
241385 |
#undef V |
|
1096 |
16150 |
#undef VS |
|
1097 |
8350 |
#undef VY |
|
1098 |
4575 |
#undef VP |
|
1099 |
29118 |
||
1100 |
114384 |
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName) |
|
1101 |
16788 |
#define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName) |
|
1102 |
26853 |
#define VS(PropertyName, StringValue) V(v8::String, PropertyName) |
|
1103 |
61234 |
#define V(TypeName, PropertyName) \ |
|
1104 |
24444 |
inline v8::Local<TypeName> Environment::PropertyName() const { \ |
|
1105 |
101 |
return isolate_data()->PropertyName(); \ |
|
1106 |
118 |
} |
|
1107 |
30850 |
PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP) |
|
1108 |
63879 |
PER_ISOLATE_SYMBOL_PROPERTIES(VY) |
|
1109 |
3446121 |
PER_ISOLATE_STRING_PROPERTIES(VS) |
|
1110 |
112714 |
#undef V |
|
1111 |
2369 |
#undef VS |
|
1112 |
12813 |
#undef VY |
|
1113 |
3055 |
#undef VP |
|
1114 |
46340 |
||
1115 |
98769 |
#define V(PropertyName, TypeName) \ |
|
1116 |
8202 |
inline v8::Local<TypeName> Environment::PropertyName() const { \ |
|
1117 |
14700 |
return PersistentToLocal::Strong(PropertyName ## _); \ |
|
1118 |
15210 |
} \ |
|
1119 |
1519 |
inline void Environment::set_ ## PropertyName(v8::Local<TypeName> value) { \ |
|
1120 |
64 |
PropertyName ## _.Reset(isolate(), value); \ |
|
1121 |
64 |
} |
|
1122 |
624846 |
ENVIRONMENT_STRONG_PERSISTENT_TEMPLATES(V) |
|
1123 |
1963802 |
ENVIRONMENT_STRONG_PERSISTENT_VALUES(V) |
|
1124 |
72915 |
#undef V |
|
1125 |
73758 |
||
1126 |
7147736 |
v8::Local<v8::Context> Environment::context() const { |
|
1127 |
7777737 |
return PersistentToLocal::Strong(context_); |
|
1128 |
692261 |
} |
|
1129 |
10076 |
||
1130 |
40 |
} // namespace node |
|
1131 |
5038 |
||
1132 |
27290 |
// These two files depend on each other. Including base_object-inl.h after this |
|
1133 |
27735 |
// file is the easiest way to avoid issues with that circular dependency. |
|
1134 |
49443 |
#include "base_object-inl.h" |
|
1135 |
43960 |
||
1136 |
32166 |
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS |
|
1137 |
26683 |
||
1138 |
5483 |
#endif // SRC_ENV_INL_H_ |
Generated by: GCOVR (Version 3.4) |