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: 146 151 96.7 %
Date: 2019-03-02 22:23:06 Branches: 29 46 63.0 %

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