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: 213 217 98.2 %
Date: 2021-04-19 04:11:46 Branches: 56 85 65.9 %

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::BigInt;
13
using v8::Boolean;
14
using v8::Context;
15
using v8::External;
16
using v8::FunctionCallbackInfo;
17
using v8::FunctionTemplate;
18
using v8::Global;
19
using v8::IndexFilter;
20
using v8::Integer;
21
using v8::Isolate;
22
using v8::KeyCollectionMode;
23
using v8::Local;
24
using v8::Object;
25
using v8::ONLY_CONFIGURABLE;
26
using v8::ONLY_ENUMERABLE;
27
using v8::ONLY_WRITABLE;
28
using v8::Private;
29
using v8::Promise;
30
using v8::PropertyFilter;
31
using v8::Proxy;
32
using v8::SKIP_STRINGS;
33
using v8::SKIP_SYMBOLS;
34
using v8::String;
35
using v8::Uint32;
36
using v8::Value;
37
38
142493
static void GetOwnNonIndexProperties(
39
    const FunctionCallbackInfo<Value>& args) {
40
142493
  Environment* env = Environment::GetCurrent(args);
41
142493
  Local<Context> context = env->context();
42
43
284986
  CHECK(args[0]->IsObject());
44
284986
  CHECK(args[1]->IsUint32());
45
46
284986
  Local<Object> object = args[0].As<Object>();
47
48
  Local<Array> properties;
49
50
  PropertyFilter filter =
51
427479
    static_cast<PropertyFilter>(args[1].As<Uint32>()->Value());
52
53
284986
  if (!object->GetPropertyNames(
54
        context, KeyCollectionMode::kOwnOnly,
55
        filter,
56
142493
        IndexFilter::kSkipIndices)
57
142493
          .ToLocal(&properties)) {
58
2
    return;
59
  }
60
284982
  args.GetReturnValue().Set(properties);
61
}
62
63
2050
static void GetConstructorName(
64
    const FunctionCallbackInfo<Value>& args) {
65
4100
  CHECK(args[0]->IsObject());
66
67
4100
  Local<Object> object = args[0].As<Object>();
68
2050
  Local<String> name = object->GetConstructorName();
69
70
4100
  args.GetReturnValue().Set(name);
71
2050
}
72
73
42
static void GetExternalValue(
74
    const FunctionCallbackInfo<Value>& args) {
75
84
  CHECK(args[0]->IsExternal());
76
42
  Isolate* isolate = args.GetIsolate();
77
84
  Local<External> external = args[0].As<External>();
78
79
42
  void* ptr = external->Value();
80
42
  uint64_t value = reinterpret_cast<uint64_t>(ptr);
81
42
  Local<BigInt> ret = BigInt::NewFromUnsigned(isolate, value);
82
84
  args.GetReturnValue().Set(ret);
83
42
}
84
85
66
static void GetPromiseDetails(const FunctionCallbackInfo<Value>& args) {
86
  // Return undefined if it's not a Promise.
87
132
  if (!args[0]->IsPromise())
88
    return;
89
90
66
  auto isolate = args.GetIsolate();
91
92
132
  Local<Promise> promise = args[0].As<Promise>();
93
94
66
  int state = promise->State();
95
198
  Local<Value> values[2] = { Integer::New(isolate, state) };
96
66
  size_t number_of_values = 1;
97
66
  if (state != Promise::PromiseState::kPending)
98
98
    values[number_of_values++] = promise->Result();
99
66
  Local<Array> ret = Array::New(isolate, values, number_of_values);
100
132
  args.GetReturnValue().Set(ret);
101
}
102
103
269543
static void GetProxyDetails(const FunctionCallbackInfo<Value>& args) {
104
  // Return undefined if it's not a proxy.
105
539086
  if (!args[0]->IsProxy())
106
269345
    return;
107
108
396
  Local<Proxy> proxy = args[0].As<Proxy>();
109
110
  // TODO(BridgeAR): Remove the length check as soon as we prohibit access to
111
  // the util binding layer. It's accessed in the wild and `esm` would break in
112
  // case the check is removed.
113

592
  if (args.Length() == 1 || args[1]->IsTrue()) {
114
    Local<Value> ret[] = {
115
43
      proxy->GetTarget(),
116
43
      proxy->GetHandler()
117
129
    };
118
119
172
    args.GetReturnValue().Set(
120
        Array::New(args.GetIsolate(), ret, arraysize(ret)));
121
  } else {
122
155
    Local<Value> ret = proxy->GetTarget();
123
124
310
    args.GetReturnValue().Set(ret);
125
  }
126
}
127
128
120
static void PreviewEntries(const FunctionCallbackInfo<Value>& args) {
129
240
  if (!args[0]->IsObject())
130
    return;
131
132
120
  Environment* env = Environment::GetCurrent(args);
133
  bool is_key_value;
134
  Local<Array> entries;
135
480
  if (!args[0].As<Object>()->PreviewEntries(&is_key_value).ToLocal(&entries))
136
    return;
137
  // Fast path for WeakMap and WeakSet.
138
120
  if (args.Length() == 1)
139
16
    return args.GetReturnValue().Set(entries);
140
141
  Local<Value> ret[] = {
142
    entries,
143
    Boolean::New(env->isolate(), is_key_value)
144
336
  };
145
336
  return args.GetReturnValue().Set(
146
112
      Array::New(env->isolate(), ret, arraysize(ret)));
147
}
148
149
4498
inline Local<Private> IndexToPrivateSymbol(Environment* env, uint32_t index) {
150
#define V(name, _) &Environment::name,
151
  static Local<Private> (Environment::*const methods[])() const = {
152
    PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(V)
153
  };
154
#undef V
155
4498
  CHECK_LT(index, arraysize(methods));
156
4498
  return (env->*methods[index])();
157
}
158
159
159
static void GetHiddenValue(const FunctionCallbackInfo<Value>& args) {
160
159
  Environment* env = Environment::GetCurrent(args);
161
162
318
  CHECK(args[0]->IsObject());
163
318
  CHECK(args[1]->IsUint32());
164
165
318
  Local<Object> obj = args[0].As<Object>();
166
477
  uint32_t index = args[1].As<Uint32>()->Value();
167
159
  Local<Private> private_symbol = IndexToPrivateSymbol(env, index);
168
  Local<Value> ret;
169
477
  if (obj->GetPrivate(env->context(), private_symbol).ToLocal(&ret))
170
318
    args.GetReturnValue().Set(ret);
171
159
}
172
173
4339
static void SetHiddenValue(const FunctionCallbackInfo<Value>& args) {
174
4339
  Environment* env = Environment::GetCurrent(args);
175
176
8678
  CHECK(args[0]->IsObject());
177
8678
  CHECK(args[1]->IsUint32());
178
179
8678
  Local<Object> obj = args[0].As<Object>();
180
13017
  uint32_t index = args[1].As<Uint32>()->Value();
181
4339
  Local<Private> private_symbol = IndexToPrivateSymbol(env, index);
182
  bool ret;
183
13017
  if (obj->SetPrivate(env->context(), private_symbol, args[2]).To(&ret))
184
13017
    args.GetReturnValue().Set(ret);
185
4339
}
186
187
10
static void Sleep(const FunctionCallbackInfo<Value>& args) {
188
20
  CHECK(args[0]->IsUint32());
189
30
  uint32_t msec = args[0].As<Uint32>()->Value();
190
10
  uv_sleep(msec);
191
10
}
192
193
56
void ArrayBufferViewHasBuffer(const FunctionCallbackInfo<Value>& args) {
194
112
  CHECK(args[0]->IsArrayBufferView());
195
280
  args.GetReturnValue().Set(args[0].As<ArrayBufferView>()->HasBuffer());
196
56
}
197
198
5145
class WeakReference : public BaseObject {
199
 public:
200
1800
  WeakReference(Environment* env, Local<Object> object, Local<Object> target)
201
3600
    : BaseObject(env, object) {
202
1800
    MakeWeak();
203
1800
    target_.Reset(env->isolate(), target);
204
1800
    target_.SetWeak();
205
1800
  }
206
207
1800
  static void New(const FunctionCallbackInfo<Value>& args) {
208
1800
    Environment* env = Environment::GetCurrent(args);
209
1800
    CHECK(args.IsConstructCall());
210
3600
    CHECK(args[0]->IsObject());
211
5400
    new WeakReference(env, args.This(), args[0].As<Object>());
212
1800
  }
213
214
1595
  static void Get(const FunctionCallbackInfo<Value>& args) {
215
1595
    WeakReference* weak_ref = Unwrap<WeakReference>(args.Holder());
216
1595
    Isolate* isolate = args.GetIsolate();
217
3190
    if (!weak_ref->target_.IsEmpty())
218
4782
      args.GetReturnValue().Set(weak_ref->target_.Get(isolate));
219
1595
  }
220
221
796
  static void IncRef(const FunctionCallbackInfo<Value>& args) {
222
796
    WeakReference* weak_ref = Unwrap<WeakReference>(args.Holder());
223
796
    weak_ref->reference_count_++;
224
1592
    if (weak_ref->target_.IsEmpty()) return;
225
796
    if (weak_ref->reference_count_ == 1) weak_ref->target_.ClearWeak();
226
  }
227
228
793
  static void DecRef(const FunctionCallbackInfo<Value>& args) {
229
793
    WeakReference* weak_ref = Unwrap<WeakReference>(args.Holder());
230
793
    CHECK_GE(weak_ref->reference_count_, 1);
231
793
    weak_ref->reference_count_--;
232
1586
    if (weak_ref->target_.IsEmpty()) return;
233
793
    if (weak_ref->reference_count_ == 0) weak_ref->target_.SetWeak();
234
  }
235
236
4
  SET_MEMORY_INFO_NAME(WeakReference)
237
4
  SET_SELF_SIZE(WeakReference)
238
4
  SET_NO_MEMORY_INFO()
239
240
 private:
241
  Global<Object> target_;
242
  uint64_t reference_count_ = 0;
243
};
244
245
4474
static void GuessHandleType(const FunctionCallbackInfo<Value>& args) {
246
4474
  Environment* env = Environment::GetCurrent(args);
247
  int fd;
248
17896
  if (!args[0]->Int32Value(env->context()).To(&fd)) return;
249
4474
  CHECK_GE(fd, 0);
250
251
4474
  uv_handle_type t = uv_guess_handle(fd);
252
4474
  const char* type = nullptr;
253
254

4474
  switch (t) {
255
    case UV_TCP:
256
4
      type = "TCP";
257
4
      break;
258
    case UV_TTY:
259
35
      type = "TTY";
260
35
      break;
261
    case UV_UDP:
262
6
      type = "UDP";
263
6
      break;
264
    case UV_FILE:
265
2332
      type = "FILE";
266
2332
      break;
267
    case UV_NAMED_PIPE:
268
2092
      type = "PIPE";
269
2092
      break;
270
    case UV_UNKNOWN_HANDLE:
271
5
      type = "UNKNOWN";
272
5
      break;
273
    default:
274
      ABORT();
275
  }
276
277
13422
  args.GetReturnValue().Set(OneByteString(env->isolate(), type));
278
}
279
280
8
static void IsConstructor(const FunctionCallbackInfo<Value>& args) {
281
16
  CHECK(args[0]->IsFunction());
282
40
  args.GetReturnValue().Set(args[0].As<v8::Function>()->IsConstructor());
283
8
}
284
285
4703
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
286
4703
  registry->Register(GetHiddenValue);
287
4703
  registry->Register(SetHiddenValue);
288
4703
  registry->Register(GetPromiseDetails);
289
4703
  registry->Register(GetProxyDetails);
290
4703
  registry->Register(PreviewEntries);
291
4703
  registry->Register(GetOwnNonIndexProperties);
292
4703
  registry->Register(GetConstructorName);
293
4703
  registry->Register(GetExternalValue);
294
4703
  registry->Register(Sleep);
295
4703
  registry->Register(ArrayBufferViewHasBuffer);
296
4703
  registry->Register(WeakReference::New);
297
4703
  registry->Register(WeakReference::Get);
298
4703
  registry->Register(WeakReference::IncRef);
299
4703
  registry->Register(WeakReference::DecRef);
300
4703
  registry->Register(GuessHandleType);
301
4703
  registry->Register(IsConstructor);
302
4703
}
303
304
461
void Initialize(Local<Object> target,
305
                Local<Value> unused,
306
                Local<Context> context,
307
                void* priv) {
308
461
  Environment* env = Environment::GetCurrent(context);
309
310
#define V(name, _)                                                            \
311
  target->Set(context,                                                        \
312
              FIXED_ONE_BYTE_STRING(env->isolate(), #name),                   \
313
              Integer::NewFromUnsigned(env->isolate(), index++)).Check();
314
  {
315
461
    uint32_t index = 0;
316
5532
    PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(V)
317
  }
318
#undef V
319
320
2766
#define V(name)                                                               \
321
1844
  target->Set(context,                                                        \
322
1844
              FIXED_ONE_BYTE_STRING(env->isolate(), #name),                   \
323
922
              Integer::New(env->isolate(), Promise::PromiseState::name))      \
324
2766
    .FromJust()
325
3227
  V(kPending);
326
1844
  V(kFulfilled);
327
1844
  V(kRejected);
328
#undef V
329
330
461
  env->SetMethodNoSideEffect(target, "getHiddenValue", GetHiddenValue);
331
461
  env->SetMethod(target, "setHiddenValue", SetHiddenValue);
332
461
  env->SetMethodNoSideEffect(target, "getPromiseDetails", GetPromiseDetails);
333
461
  env->SetMethodNoSideEffect(target, "getProxyDetails", GetProxyDetails);
334
461
  env->SetMethodNoSideEffect(target, "previewEntries", PreviewEntries);
335
  env->SetMethodNoSideEffect(target, "getOwnNonIndexProperties",
336
461
                                     GetOwnNonIndexProperties);
337
461
  env->SetMethodNoSideEffect(target, "getConstructorName", GetConstructorName);
338
461
  env->SetMethodNoSideEffect(target, "getExternalValue", GetExternalValue);
339
461
  env->SetMethod(target, "sleep", Sleep);
340
461
  env->SetMethodNoSideEffect(target, "isConstructor", IsConstructor);
341
342
461
  env->SetMethod(target, "arrayBufferViewHasBuffer", ArrayBufferViewHasBuffer);
343
461
  Local<Object> constants = Object::New(env->isolate());
344
922
  NODE_DEFINE_CONSTANT(constants, ALL_PROPERTIES);
345
461
  NODE_DEFINE_CONSTANT(constants, ONLY_WRITABLE);
346
2305
  NODE_DEFINE_CONSTANT(constants, ONLY_ENUMERABLE);
347
3688
  NODE_DEFINE_CONSTANT(constants, ONLY_CONFIGURABLE);
348
4610
  NODE_DEFINE_CONSTANT(constants, SKIP_STRINGS);
349
4610
  NODE_DEFINE_CONSTANT(constants, SKIP_SYMBOLS);
350
4610
  target->Set(context,
351
2766
              FIXED_ONE_BYTE_STRING(env->isolate(), "propertyFilter"),
352
3688
              constants).Check();
353
922
354
  Local<String> should_abort_on_uncaught_toggle =
355
461
      FIXED_ONE_BYTE_STRING(env->isolate(), "shouldAbortOnUncaughtToggle");
356
1844
  CHECK(target
357
            ->Set(env->context(),
358
                  should_abort_on_uncaught_toggle,
359
                  env->should_abort_on_uncaught_toggle().GetJSArray())
360
            .FromJust());
361
362
  Local<FunctionTemplate> weak_ref =
363
461
      env->NewFunctionTemplate(WeakReference::New);
364
1383
  weak_ref->InstanceTemplate()->SetInternalFieldCount(
365
461
      WeakReference::kInternalFieldCount);
366
922
  weak_ref->Inherit(BaseObject::GetConstructorTemplate(env));
367
461
  env->SetProtoMethod(weak_ref, "get", WeakReference::Get);
368
461
  env->SetProtoMethod(weak_ref, "incRef", WeakReference::IncRef);
369
461
  env->SetProtoMethod(weak_ref, "decRef", WeakReference::DecRef);
370
461
  env->SetConstructorFunction(target, "WeakReference", weak_ref);
371
372
461
  env->SetMethod(target, "guessHandleType", GuessHandleType);
373
461
}
374
375
}  // namespace util
376
}  // namespace node
377
378
4762
NODE_MODULE_CONTEXT_AWARE_INTERNAL(util, node::util::Initialize)
379

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