GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/node_task_queue.cc Lines: 52 54 96.3 %
Date: 2019-03-02 22:23:06 Branches: 20 26 76.9 %

Line Branch Exec Source
1
#include "env-inl.h"
2
#include "node.h"
3
#include "node_internals.h"
4
#include "v8.h"
5
6
#include <atomic>
7
8
namespace node {
9
10
using v8::Array;
11
using v8::Context;
12
using v8::Function;
13
using v8::FunctionCallbackInfo;
14
using v8::Isolate;
15
using v8::kPromiseHandlerAddedAfterReject;
16
using v8::kPromiseRejectAfterResolved;
17
using v8::kPromiseRejectWithNoHandler;
18
using v8::kPromiseResolveAfterResolved;
19
using v8::Local;
20
using v8::Number;
21
using v8::Object;
22
using v8::Promise;
23
using v8::PromiseRejectEvent;
24
using v8::PromiseRejectMessage;
25
using v8::Value;
26
27
namespace task_queue {
28
29
608938
static void RunMicrotasks(const FunctionCallbackInfo<Value>& args) {
30
608938
  args.GetIsolate()->RunMicrotasks();
31
608931
}
32
33
4408
static void SetTickCallback(const FunctionCallbackInfo<Value>& args) {
34
4408
  Environment* env = Environment::GetCurrent(args);
35
8816
  CHECK(args[0]->IsFunction());
36
8816
  env->set_tick_callback_function(args[0].As<Function>());
37
4408
}
38
39
1475
void PromiseRejectCallback(PromiseRejectMessage message) {
40
  static std::atomic<uint64_t> unhandledRejections{0};
41
  static std::atomic<uint64_t> rejectionsHandledAfter{0};
42
43
1475
  Local<Promise> promise = message.GetPromise();
44
1475
  Isolate* isolate = promise->GetIsolate();
45
1475
  PromiseRejectEvent event = message.GetEvent();
46
47
1475
  Environment* env = Environment::GetCurrent(isolate);
48
49
1475
  if (env == nullptr) return;
50
51
1475
  Local<Function> callback = env->promise_reject_callback();
52
  // The promise is rejected before JS land calls SetPromiseRejectCallback
53
  // to initializes the promise reject callback during bootstrap.
54
1475
  CHECK(!callback.IsEmpty());
55
56
  Local<Value> value;
57
1475
  Local<Value> type = Number::New(env->isolate(), event);
58
59
1475
  if (event == kPromiseRejectWithNoHandler) {
60
1260
    value = message.GetValue();
61
1260
    unhandledRejections++;
62

2520
    TRACE_COUNTER2(TRACING_CATEGORY_NODE2(promises, rejections),
63
                  "rejections",
64
                  "unhandled", unhandledRejections,
65
                  "handledAfter", rejectionsHandledAfter);
66
215
  } else if (event == kPromiseHandlerAddedAfterReject) {
67
154
    value = Undefined(isolate);
68
154
    rejectionsHandledAfter++;
69

308
    TRACE_COUNTER2(TRACING_CATEGORY_NODE2(promises, rejections),
70
                  "rejections",
71
                  "unhandled", unhandledRejections,
72
                  "handledAfter", rejectionsHandledAfter);
73
61
  } else if (event == kPromiseResolveAfterResolved) {
74
58
    value = message.GetValue();
75
3
  } else if (event == kPromiseRejectAfterResolved) {
76
3
    value = message.GetValue();
77
  } else {
78
    return;
79
  }
80
81
1475
  if (value.IsEmpty()) {
82
    value = Undefined(isolate);
83
  }
84
85
2950
  Local<Value> args[] = { type, promise, value };
86
  USE(callback->Call(
87
4425
      env->context(), Undefined(isolate), arraysize(args), args));
88
}
89
90
4408
static void SetPromiseRejectCallback(
91
    const FunctionCallbackInfo<Value>& args) {
92
4408
  Environment* env = Environment::GetCurrent(args);
93
94
8816
  CHECK(args[0]->IsFunction());
95
8816
  env->set_promise_reject_callback(args[0].As<Function>());
96
4408
}
97
98
4408
static void Initialize(Local<Object> target,
99
                       Local<Value> unused,
100
                       Local<Context> context,
101
                       void* priv) {
102
4408
  Environment* env = Environment::GetCurrent(context);
103
4408
  Isolate* isolate = env->isolate();
104
105
4408
  env->SetMethod(target, "setTickCallback", SetTickCallback);
106
4408
  env->SetMethod(target, "runMicrotasks", RunMicrotasks);
107
  target->Set(env->context(),
108
              FIXED_ONE_BYTE_STRING(isolate, "tickInfo"),
109
22040
              env->tick_info()->fields().GetJSArray()).FromJust();
110
111
4408
  Local<Object> events = Object::New(isolate);
112
17632
  NODE_DEFINE_CONSTANT(events, kPromiseRejectWithNoHandler);
113
17632
  NODE_DEFINE_CONSTANT(events, kPromiseHandlerAddedAfterReject);
114
17632
  NODE_DEFINE_CONSTANT(events, kPromiseResolveAfterResolved);
115
17632
  NODE_DEFINE_CONSTANT(events, kPromiseRejectAfterResolved);
116
117
  target->Set(env->context(),
118
              FIXED_ONE_BYTE_STRING(isolate, "promiseRejectEvents"),
119
17632
              events).FromJust();
120
  env->SetMethod(target,
121
                 "setPromiseRejectCallback",
122
4408
                 SetPromiseRejectCallback);
123
4408
}
124
125
}  // namespace task_queue
126
}  // namespace node
127
128
4292
NODE_MODULE_CONTEXT_AWARE_INTERNAL(task_queue, node::task_queue::Initialize)