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: 172 179 96.1 %
Date: 2020-06-24 22:13:30 Branches: 52 77 67.5 %

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

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

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