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: 189 196 96.4 %
Date: 2020-07-19 22:14:24 Branches: 54 81 66.7 %

Line Branch Exec Source
1
#include "base_object-inl.h"
2
#include "node_errors.h"
3
#include "node_external_reference.h"
4
#include "util-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::FunctionCallbackInfo;
15
using v8::FunctionTemplate;
16
using v8::Global;
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
137789
static void GetOwnNonIndexProperties(
37
    const FunctionCallbackInfo<Value>& args) {
38
137789
  Environment* env = Environment::GetCurrent(args);
39
137789
  Local<Context> context = env->context();
40
41
275578
  CHECK(args[0]->IsObject());
42
275578
  CHECK(args[1]->IsUint32());
43
44
275578
  Local<Object> object = args[0].As<Object>();
45
46
  Local<Array> properties;
47
48
  PropertyFilter filter =
49
413367
    static_cast<PropertyFilter>(args[1].As<Uint32>()->Value());
50
51
275578
  if (!object->GetPropertyNames(
52
        context, KeyCollectionMode::kOwnOnly,
53
        filter,
54
137789
        IndexFilter::kSkipIndices)
55
137789
          .ToLocal(&properties)) {
56
2
    return;
57
  }
58
275574
  args.GetReturnValue().Set(properties);
59
}
60
61
1047
static void GetConstructorName(
62
    const FunctionCallbackInfo<Value>& args) {
63
2094
  CHECK(args[0]->IsObject());
64
65
2094
  Local<Object> object = args[0].As<Object>();
66
1047
  Local<String> name = object->GetConstructorName();
67
68
2094
  args.GetReturnValue().Set(name);
69
1047
}
70
71
62
static void GetPromiseDetails(const FunctionCallbackInfo<Value>& args) {
72
  // Return undefined if it's not a Promise.
73
124
  if (!args[0]->IsPromise())
74
    return;
75
76
62
  auto isolate = args.GetIsolate();
77
78
124
  Local<Promise> promise = args[0].As<Promise>();
79
80
62
  int state = promise->State();
81
186
  Local<Value> values[2] = { Integer::New(isolate, state) };
82
62
  size_t number_of_values = 1;
83
62
  if (state != Promise::PromiseState::kPending)
84
98
    values[number_of_values++] = promise->Result();
85
62
  Local<Array> ret = Array::New(isolate, values, number_of_values);
86
124
  args.GetReturnValue().Set(ret);
87
}
88
89
260059
static void GetProxyDetails(const FunctionCallbackInfo<Value>& args) {
90
  // Return undefined if it's not a proxy.
91
520118
  if (!args[0]->IsProxy())
92
259956
    return;
93
94
206
  Local<Proxy> proxy = args[0].As<Proxy>();
95
96
  // TODO(BridgeAR): Remove the length check as soon as we prohibit access to
97
  // the util binding layer. It's accessed in the wild and `esm` would break in
98
  // case the check is removed.
99

307
  if (args.Length() == 1 || args[1]->IsTrue()) {
100
    Local<Value> ret[] = {
101
43
      proxy->GetTarget(),
102
43
      proxy->GetHandler()
103
129
    };
104
105
172
    args.GetReturnValue().Set(
106
        Array::New(args.GetIsolate(), ret, arraysize(ret)));
107
  } else {
108
60
    Local<Value> ret = proxy->GetTarget();
109
110
120
    args.GetReturnValue().Set(ret);
111
  }
112
}
113
114
120
static void PreviewEntries(const FunctionCallbackInfo<Value>& args) {
115
240
  if (!args[0]->IsObject())
116
    return;
117
118
120
  Environment* env = Environment::GetCurrent(args);
119
  bool is_key_value;
120
  Local<Array> entries;
121
480
  if (!args[0].As<Object>()->PreviewEntries(&is_key_value).ToLocal(&entries))
122
    return;
123
  // Fast path for WeakMap and WeakSet.
124
120
  if (args.Length() == 1)
125
16
    return args.GetReturnValue().Set(entries);
126
127
  Local<Value> ret[] = {
128
    entries,
129
    Boolean::New(env->isolate(), is_key_value)
130
336
  };
131
336
  return args.GetReturnValue().Set(
132
112
      Array::New(env->isolate(), ret, arraysize(ret)));
133
}
134
135
6977
inline Local<Private> IndexToPrivateSymbol(Environment* env, uint32_t index) {
136
#define V(name, _) &Environment::name,
137
  static Local<Private> (Environment::*const methods[])() const = {
138
    PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(V)
139
  };
140
#undef V
141
6977
  CHECK_LT(index, arraysize(methods));
142
6977
  return (env->*methods[index])();
143
}
144
145
142
static void GetHiddenValue(const FunctionCallbackInfo<Value>& args) {
146
142
  Environment* env = Environment::GetCurrent(args);
147
148
284
  CHECK(args[0]->IsObject());
149
284
  CHECK(args[1]->IsUint32());
150
151
284
  Local<Object> obj = args[0].As<Object>();
152
426
  uint32_t index = args[1].As<Uint32>()->Value();
153
142
  Local<Private> private_symbol = IndexToPrivateSymbol(env, index);
154
  Local<Value> ret;
155
426
  if (obj->GetPrivate(env->context(), private_symbol).ToLocal(&ret))
156
284
    args.GetReturnValue().Set(ret);
157
142
}
158
159
6835
static void SetHiddenValue(const FunctionCallbackInfo<Value>& args) {
160
6835
  Environment* env = Environment::GetCurrent(args);
161
162
13670
  CHECK(args[0]->IsObject());
163
13670
  CHECK(args[1]->IsUint32());
164
165
13670
  Local<Object> obj = args[0].As<Object>();
166
20505
  uint32_t index = args[1].As<Uint32>()->Value();
167
6835
  Local<Private> private_symbol = IndexToPrivateSymbol(env, index);
168
  bool ret;
169
20505
  if (obj->SetPrivate(env->context(), private_symbol, args[2]).To(&ret))
170
20505
    args.GetReturnValue().Set(ret);
171
6835
}
172
173
10
static void Sleep(const FunctionCallbackInfo<Value>& args) {
174
20
  CHECK(args[0]->IsUint32());
175
30
  uint32_t msec = args[0].As<Uint32>()->Value();
176
10
  uv_sleep(msec);
177
10
}
178
179
56
void ArrayBufferViewHasBuffer(const FunctionCallbackInfo<Value>& args) {
180
112
  CHECK(args[0]->IsArrayBufferView());
181
280
  args.GetReturnValue().Set(args[0].As<ArrayBufferView>()->HasBuffer());
182
56
}
183
184
786
class WeakReference : public BaseObject {
185
 public:
186
301
  WeakReference(Environment* env, Local<Object> object, Local<Object> target)
187
602
    : BaseObject(env, object) {
188
301
    MakeWeak();
189
301
    target_.Reset(env->isolate(), target);
190
301
    target_.SetWeak();
191
301
  }
192
193
301
  static void New(const FunctionCallbackInfo<Value>& args) {
194
301
    Environment* env = Environment::GetCurrent(args);
195
301
    CHECK(args.IsConstructCall());
196
602
    CHECK(args[0]->IsObject());
197
903
    new WeakReference(env, args.This(), args[0].As<Object>());
198
301
  }
199
200
1547
  static void Get(const FunctionCallbackInfo<Value>& args) {
201
1547
    WeakReference* weak_ref = Unwrap<WeakReference>(args.Holder());
202
1547
    Isolate* isolate = args.GetIsolate();
203
3094
    if (!weak_ref->target_.IsEmpty())
204
4638
      args.GetReturnValue().Set(weak_ref->target_.Get(isolate));
205
1547
  }
206
207
774
  static void IncRef(const FunctionCallbackInfo<Value>& args) {
208
774
    WeakReference* weak_ref = Unwrap<WeakReference>(args.Holder());
209
774
    weak_ref->reference_count_++;
210
1548
    if (weak_ref->target_.IsEmpty()) return;
211
774
    if (weak_ref->reference_count_ == 1) weak_ref->target_.ClearWeak();
212
  }
213
214
771
  static void DecRef(const FunctionCallbackInfo<Value>& args) {
215
771
    WeakReference* weak_ref = Unwrap<WeakReference>(args.Holder());
216
771
    CHECK_GE(weak_ref->reference_count_, 1);
217
771
    weak_ref->reference_count_--;
218
1542
    if (weak_ref->target_.IsEmpty()) return;
219
771
    if (weak_ref->reference_count_ == 0) weak_ref->target_.SetWeak();
220
  }
221
222
  SET_MEMORY_INFO_NAME(WeakReference)
223
  SET_SELF_SIZE(WeakReference)
224
  SET_NO_MEMORY_INFO()
225
226
 private:
227
  Global<Object> target_;
228
  uint64_t reference_count_ = 0;
229
};
230
231
4528
static void GuessHandleType(const FunctionCallbackInfo<Value>& args) {
232
4528
  Environment* env = Environment::GetCurrent(args);
233
  int fd;
234
18112
  if (!args[0]->Int32Value(env->context()).To(&fd)) return;
235
4528
  CHECK_GE(fd, 0);
236
237
4528
  uv_handle_type t = uv_guess_handle(fd);
238
4528
  const char* type = nullptr;
239
240

4528
  switch (t) {
241
    case UV_TCP:
242
4
      type = "TCP";
243
4
      break;
244
    case UV_TTY:
245
35
      type = "TTY";
246
35
      break;
247
    case UV_UDP:
248
6
      type = "UDP";
249
6
      break;
250
    case UV_FILE:
251
2334
      type = "FILE";
252
2334
      break;
253
    case UV_NAMED_PIPE:
254
2144
      type = "PIPE";
255
2144
      break;
256
    case UV_UNKNOWN_HANDLE:
257
5
      type = "UNKNOWN";
258
5
      break;
259
    default:
260
      ABORT();
261
  }
262
263
13584
  args.GetReturnValue().Set(OneByteString(env->isolate(), type));
264
}
265
266
4920
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
267
4920
  registry->Register(GetHiddenValue);
268
4920
  registry->Register(SetHiddenValue);
269
4920
  registry->Register(GetPromiseDetails);
270
4920
  registry->Register(GetProxyDetails);
271
4920
  registry->Register(PreviewEntries);
272
4920
  registry->Register(GetOwnNonIndexProperties);
273
4920
  registry->Register(GetConstructorName);
274
4920
  registry->Register(Sleep);
275
4920
  registry->Register(ArrayBufferViewHasBuffer);
276
4920
  registry->Register(WeakReference::New);
277
4920
  registry->Register(WeakReference::Get);
278
4920
  registry->Register(WeakReference::IncRef);
279
4920
  registry->Register(WeakReference::DecRef);
280
4920
  registry->Register(GuessHandleType);
281
4920
}
282
283
384
void Initialize(Local<Object> target,
284
                Local<Value> unused,
285
                Local<Context> context,
286
                void* priv) {
287
384
  Environment* env = Environment::GetCurrent(context);
288
289
#define V(name, _)                                                            \
290
  target->Set(context,                                                        \
291
              FIXED_ONE_BYTE_STRING(env->isolate(), #name),                   \
292
              Integer::NewFromUnsigned(env->isolate(), index++)).Check();
293
  {
294
384
    uint32_t index = 0;
295
8448
    PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(V)
296
  }
297
#undef V
298
299
#define V(name)                                                               \
300
  target->Set(context,                                                        \
301
              FIXED_ONE_BYTE_STRING(env->isolate(), #name),                   \
302
              Integer::New(env->isolate(), Promise::PromiseState::name))      \
303
    .FromJust()
304
1536
  V(kPending);
305
1536
  V(kFulfilled);
306
1536
  V(kRejected);
307
#undef V
308
309
384
  env->SetMethodNoSideEffect(target, "getHiddenValue", GetHiddenValue);
310
384
  env->SetMethod(target, "setHiddenValue", SetHiddenValue);
311
384
  env->SetMethodNoSideEffect(target, "getPromiseDetails", GetPromiseDetails);
312
384
  env->SetMethodNoSideEffect(target, "getProxyDetails", GetProxyDetails);
313
384
  env->SetMethodNoSideEffect(target, "previewEntries", PreviewEntries);
314
  env->SetMethodNoSideEffect(target, "getOwnNonIndexProperties",
315
384
                                     GetOwnNonIndexProperties);
316
384
  env->SetMethodNoSideEffect(target, "getConstructorName", GetConstructorName);
317
384
  env->SetMethod(target, "sleep", Sleep);
318
319
384
  env->SetMethod(target, "arrayBufferViewHasBuffer", ArrayBufferViewHasBuffer);
320
384
  Local<Object> constants = Object::New(env->isolate());
321
1536
  NODE_DEFINE_CONSTANT(constants, ALL_PROPERTIES);
322
1536
  NODE_DEFINE_CONSTANT(constants, ONLY_WRITABLE);
323
1536
  NODE_DEFINE_CONSTANT(constants, ONLY_ENUMERABLE);
324
1536
  NODE_DEFINE_CONSTANT(constants, ONLY_CONFIGURABLE);
325
1536
  NODE_DEFINE_CONSTANT(constants, SKIP_STRINGS);
326
1536
  NODE_DEFINE_CONSTANT(constants, SKIP_SYMBOLS);
327
768
  target->Set(context,
328
              FIXED_ONE_BYTE_STRING(env->isolate(), "propertyFilter"),
329
1152
              constants).Check();
330
331
  Local<String> should_abort_on_uncaught_toggle =
332
384
      FIXED_ONE_BYTE_STRING(env->isolate(), "shouldAbortOnUncaughtToggle");
333
1536
  CHECK(target
334
            ->Set(env->context(),
335
                  should_abort_on_uncaught_toggle,
336
                  env->should_abort_on_uncaught_toggle().GetJSArray())
337
            .FromJust());
338
339
  Local<String> weak_ref_string =
340
384
      FIXED_ONE_BYTE_STRING(env->isolate(), "WeakReference");
341
  Local<FunctionTemplate> weak_ref =
342
384
      env->NewFunctionTemplate(WeakReference::New);
343
1152
  weak_ref->InstanceTemplate()->SetInternalFieldCount(
344
384
      WeakReference::kInternalFieldCount);
345
384
  weak_ref->SetClassName(weak_ref_string);
346
768
  weak_ref->Inherit(BaseObject::GetConstructorTemplate(env));
347
384
  env->SetProtoMethod(weak_ref, "get", WeakReference::Get);
348
384
  env->SetProtoMethod(weak_ref, "incRef", WeakReference::IncRef);
349
384
  env->SetProtoMethod(weak_ref, "decRef", WeakReference::DecRef);
350
768
  target->Set(context, weak_ref_string,
351
1152
              weak_ref->GetFunction(context).ToLocalChecked()).Check();
352
353
384
  env->SetMethod(target, "guessHandleType", GuessHandleType);
354
384
}
355
356
}  // namespace util
357
}  // namespace node
358
359
4989
NODE_MODULE_CONTEXT_AWARE_INTERNAL(util, node::util::Initialize)
360

19890
NODE_MODULE_EXTERNAL_REFERENCE(util, node::util::RegisterExternalReferences)