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: 141 146 96.6 %
Date: 2019-02-26 22:23:30 Branches: 28 44 63.6 %

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