GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/node_util.cc Lines: 43 111 38.7 %
Date: 2019-02-01 22:03:38 Branches: 4 36 11.1 %

Line Branch Exec Source
1
#include "node_errors.h"
2
#include "node_watchdog.h"
3
#include "util.h"
4
5
namespace node {
6
namespace util {
7
8
using v8::ALL_PROPERTIES;
9
using v8::Array;
10
using v8::Boolean;
11
using v8::Context;
12
using v8::Function;
13
using v8::FunctionCallbackInfo;
14
using v8::IndexFilter;
15
using v8::Integer;
16
using v8::Isolate;
17
using v8::KeyCollectionMode;
18
using v8::Local;
19
using v8::Object;
20
using v8::ONLY_CONFIGURABLE;
21
using v8::ONLY_ENUMERABLE;
22
using v8::ONLY_WRITABLE;
23
using v8::Private;
24
using v8::Promise;
25
using v8::PropertyFilter;
26
using v8::Proxy;
27
using v8::SKIP_STRINGS;
28
using v8::SKIP_SYMBOLS;
29
using v8::String;
30
using v8::Uint32;
31
using v8::Value;
32
33
933
static void GetOwnNonIndexProperties(
34
    const FunctionCallbackInfo<Value>& args) {
35
933
  Environment* env = Environment::GetCurrent(args);
36
933
  Local<Context> context = env->context();
37
38
1866
  CHECK(args[0]->IsObject());
39
1866
  CHECK(args[1]->IsUint32());
40
41
1866
  Local<Object> object = args[0].As<Object>();
42
43
  Local<Array> properties;
44
45
  PropertyFilter filter =
46
2799
    static_cast<PropertyFilter>(args[1].As<Uint32>()->Value());
47
48
1866
  if (!object->GetPropertyNames(
49
        context, KeyCollectionMode::kOwnOnly,
50
        filter,
51
933
        IndexFilter::kSkipIndices)
52
2799
          .ToLocal(&properties)) {
53
933
    return;
54
  }
55
1866
  args.GetReturnValue().Set(properties);
56
}
57
58
static void GetPromiseDetails(const FunctionCallbackInfo<Value>& args) {
59
  // Return undefined if it's not a Promise.
60
  if (!args[0]->IsPromise())
61
    return;
62
63
  auto isolate = args.GetIsolate();
64
65
  Local<Promise> promise = args[0].As<Promise>();
66
67
  int state = promise->State();
68
  Local<Value> values[2] = { Integer::New(isolate, state) };
69
  size_t number_of_values = 1;
70
  if (state != Promise::PromiseState::kPending)
71
    values[number_of_values++] = promise->Result();
72
  Local<Array> ret = Array::New(isolate, values, number_of_values);
73
  args.GetReturnValue().Set(ret);
74
}
75
76
static void GetProxyDetails(const FunctionCallbackInfo<Value>& args) {
77
  // Return undefined if it's not a proxy.
78
  if (!args[0]->IsProxy())
79
    return;
80
81
  Local<Proxy> proxy = args[0].As<Proxy>();
82
83
  Local<Value> ret[] = {
84
    proxy->GetTarget(),
85
    proxy->GetHandler()
86
  };
87
88
  args.GetReturnValue().Set(
89
      Array::New(args.GetIsolate(), ret, arraysize(ret)));
90
}
91
92
static void PreviewEntries(const FunctionCallbackInfo<Value>& args) {
93
  if (!args[0]->IsObject())
94
    return;
95
96
  Environment* env = Environment::GetCurrent(args);
97
  bool is_key_value;
98
  Local<Array> entries;
99
  if (!args[0].As<Object>()->PreviewEntries(&is_key_value).ToLocal(&entries))
100
    return;
101
  // Fast path for WeakMap, WeakSet and Set iterators.
102
  if (args.Length() == 1)
103
    return args.GetReturnValue().Set(entries);
104
105
  Local<Value> ret[] = {
106
    entries,
107
    Boolean::New(env->isolate(), is_key_value)
108
  };
109
  return args.GetReturnValue().Set(
110
      Array::New(env->isolate(), ret, arraysize(ret)));
111
}
112
113
// Side effect-free stringification that will never throw exceptions.
114
static void SafeToString(const FunctionCallbackInfo<Value>& args) {
115
  auto context = args.GetIsolate()->GetCurrentContext();
116
  args.GetReturnValue().Set(args[0]->ToDetailString(context).ToLocalChecked());
117
}
118
119
inline Local<Private> IndexToPrivateSymbol(Environment* env, uint32_t index) {
120
#define V(name, _) &Environment::name,
121
  static Local<Private> (Environment::*const methods[])() const = {
122
    PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(V)
123
  };
124
#undef V
125
  CHECK_LT(index, arraysize(methods));
126
  return (env->*methods[index])();
127
}
128
129
static void GetHiddenValue(const FunctionCallbackInfo<Value>& args) {
130
  Environment* env = Environment::GetCurrent(args);
131
132
  CHECK(args[0]->IsObject());
133
  CHECK(args[1]->IsUint32());
134
135
  Local<Object> obj = args[0].As<Object>();
136
  auto index = args[1]->Uint32Value(env->context()).FromJust();
137
  auto private_symbol = IndexToPrivateSymbol(env, index);
138
  auto maybe_value = obj->GetPrivate(env->context(), private_symbol);
139
140
  args.GetReturnValue().Set(maybe_value.ToLocalChecked());
141
}
142
143
static void SetHiddenValue(const FunctionCallbackInfo<Value>& args) {
144
  Environment* env = Environment::GetCurrent(args);
145
146
  CHECK(args[0]->IsObject());
147
  CHECK(args[1]->IsUint32());
148
149
  Local<Object> obj = args[0].As<Object>();
150
  auto index = args[1]->Uint32Value(env->context()).FromJust();
151
  auto private_symbol = IndexToPrivateSymbol(env, index);
152
  auto maybe_value = obj->SetPrivate(env->context(), private_symbol, args[2]);
153
154
  args.GetReturnValue().Set(maybe_value.FromJust());
155
}
156
157
158
void StartSigintWatchdog(const FunctionCallbackInfo<Value>& args) {
159
  int ret = SigintWatchdogHelper::GetInstance()->Start();
160
  args.GetReturnValue().Set(ret == 0);
161
}
162
163
164
void StopSigintWatchdog(const FunctionCallbackInfo<Value>& args) {
165
  bool had_pending_signals = SigintWatchdogHelper::GetInstance()->Stop();
166
  args.GetReturnValue().Set(had_pending_signals);
167
}
168
169
170
void WatchdogHasPendingSigint(const FunctionCallbackInfo<Value>& args) {
171
  bool ret = SigintWatchdogHelper::GetInstance()->HasPendingSignal();
172
  args.GetReturnValue().Set(ret);
173
}
174
175
void EnqueueMicrotask(const FunctionCallbackInfo<Value>& args) {
176
  Environment* env = Environment::GetCurrent(args);
177
  Isolate* isolate = env->isolate();
178
179
  CHECK(args[0]->IsFunction());
180
181
  isolate->EnqueueMicrotask(args[0].As<Function>());
182
}
183
184
164
void Initialize(Local<Object> target,
185
                Local<Value> unused,
186
                Local<Context> context,
187
                void* priv) {
188
164
  Environment* env = Environment::GetCurrent(context);
189
190
#define V(name, _)                                                            \
191
  target->Set(context,                                                        \
192
              FIXED_ONE_BYTE_STRING(env->isolate(), #name),                   \
193
              Integer::NewFromUnsigned(env->isolate(), index++)).FromJust();
194
  {
195
164
    uint32_t index = 0;
196
4100
    PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(V)
197
  }
198
#undef V
199
200
#define V(name)                                                               \
201
  target->Set(context,                                                        \
202
              FIXED_ONE_BYTE_STRING(env->isolate(), #name),                   \
203
              Integer::New(env->isolate(), Promise::PromiseState::name))      \
204
    .FromJust()
205
656
  V(kPending);
206
656
  V(kFulfilled);
207
656
  V(kRejected);
208
#undef V
209
210
164
  env->SetMethodNoSideEffect(target, "getHiddenValue", GetHiddenValue);
211
164
  env->SetMethod(target, "setHiddenValue", SetHiddenValue);
212
164
  env->SetMethodNoSideEffect(target, "getPromiseDetails", GetPromiseDetails);
213
164
  env->SetMethodNoSideEffect(target, "getProxyDetails", GetProxyDetails);
214
164
  env->SetMethodNoSideEffect(target, "safeToString", SafeToString);
215
164
  env->SetMethodNoSideEffect(target, "previewEntries", PreviewEntries);
216
  env->SetMethodNoSideEffect(target, "getOwnNonIndexProperties",
217
164
                                     GetOwnNonIndexProperties);
218
219
164
  env->SetMethod(target, "startSigintWatchdog", StartSigintWatchdog);
220
164
  env->SetMethod(target, "stopSigintWatchdog", StopSigintWatchdog);
221
  env->SetMethodNoSideEffect(target, "watchdogHasPendingSigint",
222
164
                             WatchdogHasPendingSigint);
223
224
164
  env->SetMethod(target, "enqueueMicrotask", EnqueueMicrotask);
225
164
  env->SetMethod(target, "triggerFatalException", FatalException);
226
164
  Local<Object> constants = Object::New(env->isolate());
227
656
  NODE_DEFINE_CONSTANT(constants, ALL_PROPERTIES);
228
656
  NODE_DEFINE_CONSTANT(constants, ONLY_WRITABLE);
229
656
  NODE_DEFINE_CONSTANT(constants, ONLY_ENUMERABLE);
230
656
  NODE_DEFINE_CONSTANT(constants, ONLY_CONFIGURABLE);
231
656
  NODE_DEFINE_CONSTANT(constants, SKIP_STRINGS);
232
656
  NODE_DEFINE_CONSTANT(constants, SKIP_SYMBOLS);
233
  target->Set(context,
234
              FIXED_ONE_BYTE_STRING(env->isolate(), "propertyFilter"),
235
492
              constants).FromJust();
236
237
  Local<String> should_abort_on_uncaught_toggle =
238
164
      FIXED_ONE_BYTE_STRING(env->isolate(), "shouldAbortOnUncaughtToggle");
239
656
  CHECK(target
240
            ->Set(env->context(),
241
                  should_abort_on_uncaught_toggle,
242
                  env->should_abort_on_uncaught_toggle().GetJSArray())
243
            .FromJust());
244
164
}
245
246
}  // namespace util
247
}  // namespace node
248
249
164
NODE_MODULE_CONTEXT_AWARE_INTERNAL(util, node::util::Initialize)