GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/js_stream.cc Lines: 95 110 86.4 %
Date: 2021-06-05 04:12:00 Branches: 38 82 46.3 %

Line Branch Exec Source
1
#include "js_stream.h"
2
3
#include "async_wrap.h"
4
#include "env-inl.h"
5
#include "node_errors.h"
6
#include "stream_base-inl.h"
7
#include "util-inl.h"
8
#include "v8.h"
9
10
namespace node {
11
12
using errors::TryCatchScope;
13
14
using v8::Array;
15
using v8::Context;
16
using v8::FunctionCallbackInfo;
17
using v8::FunctionTemplate;
18
using v8::HandleScope;
19
using v8::Int32;
20
using v8::Local;
21
using v8::Object;
22
using v8::Value;
23
24
25
10579
JSStream::JSStream(Environment* env, Local<Object> obj)
26
    : AsyncWrap(env, obj, AsyncWrap::PROVIDER_JSSTREAM),
27
10579
      StreamBase(env) {
28
10579
  MakeWeak();
29
10579
  StreamBase::AttachToObject(obj);
30
10579
}
31
32
33
11231
AsyncWrap* JSStream::GetAsyncWrap() {
34
11231
  return static_cast<AsyncWrap*>(this);
35
}
36
37
38
10617
bool JSStream::IsAlive() {
39
10617
  return true;
40
}
41
42
43
bool JSStream::IsClosing() {
44
  HandleScope scope(env()->isolate());
45
  Context::Scope context_scope(env()->context());
46
  TryCatchScope try_catch(env());
47
  Local<Value> value;
48
  if (!MakeCallback(env()->isclosing_string(), 0, nullptr).ToLocal(&value)) {
49
    if (try_catch.HasCaught() && !try_catch.HasTerminated())
50
      errors::TriggerUncaughtException(env()->isolate(), try_catch);
51
    return true;
52
  }
53
  return value->IsTrue();
54
}
55
56
57
10608
int JSStream::ReadStart() {
58
21216
  HandleScope scope(env()->isolate());
59
10608
  Context::Scope context_scope(env()->context());
60
21216
  TryCatchScope try_catch(env());
61
  Local<Value> value;
62
10608
  int value_int = UV_EPROTO;
63

42432
  if (!MakeCallback(env()->onreadstart_string(), 0, nullptr).ToLocal(&value) ||
64
42432
      !value->Int32Value(env()->context()).To(&value_int)) {
65
    if (try_catch.HasCaught() && !try_catch.HasTerminated())
66
      errors::TriggerUncaughtException(env()->isolate(), try_catch);
67
  }
68
21216
  return value_int;
69
}
70
71
72
61
int JSStream::ReadStop() {
73
122
  HandleScope scope(env()->isolate());
74
61
  Context::Scope context_scope(env()->context());
75
122
  TryCatchScope try_catch(env());
76
  Local<Value> value;
77
61
  int value_int = UV_EPROTO;
78

243
  if (!MakeCallback(env()->onreadstop_string(), 0, nullptr).ToLocal(&value) ||
79
241
      !value->Int32Value(env()->context()).To(&value_int)) {
80

1
    if (try_catch.HasCaught() && !try_catch.HasTerminated())
81
      errors::TriggerUncaughtException(env()->isolate(), try_catch);
82
  }
83
122
  return value_int;
84
}
85
86
87
12
int JSStream::DoShutdown(ShutdownWrap* req_wrap) {
88
24
  HandleScope scope(env()->isolate());
89
12
  Context::Scope context_scope(env()->context());
90
91
  Local<Value> argv[] = {
92
    req_wrap->object()
93
24
  };
94
95
24
  TryCatchScope try_catch(env());
96
  Local<Value> value;
97
12
  int value_int = UV_EPROTO;
98
48
  if (!MakeCallback(env()->onshutdown_string(),
99
12
                    arraysize(argv),
100

48
                    argv).ToLocal(&value) ||
101
48
      !value->Int32Value(env()->context()).To(&value_int)) {
102
    if (try_catch.HasCaught() && !try_catch.HasTerminated())
103
      errors::TriggerUncaughtException(env()->isolate(), try_catch);
104
  }
105
24
  return value_int;
106
}
107
108
109
606
int JSStream::DoWrite(WriteWrap* w,
110
                      uv_buf_t* bufs,
111
                      size_t count,
112
                      uv_stream_t* send_handle) {
113
606
  CHECK_NULL(send_handle);
114
115
1211
  HandleScope scope(env()->isolate());
116
606
  Context::Scope context_scope(env()->context());
117
118
1211
  MaybeStackBuffer<Local<Value>, 16> bufs_arr(count);
119
1268
  for (size_t i = 0; i < count; i++) {
120
1324
    bufs_arr[i] =
121
1324
        Buffer::Copy(env(), bufs[i].base, bufs[i].len).ToLocalChecked();
122
  }
123
124
  Local<Value> argv[] = {
125
    w->object(),
126
    Array::New(env()->isolate(), bufs_arr.out(), count)
127
1818
  };
128
129
1211
  TryCatchScope try_catch(env());
130
  Local<Value> value;
131
606
  int value_int = UV_EPROTO;
132
2424
  if (!MakeCallback(env()->onwrite_string(),
133
606
                    arraysize(argv),
134

2421
                    argv).ToLocal(&value) ||
135
2415
      !value->Int32Value(env()->context()).To(&value_int)) {
136

3
    if (try_catch.HasCaught() && !try_catch.HasTerminated())
137
2
      errors::TriggerUncaughtException(env()->isolate(), try_catch);
138
  }
139
1210
  return value_int;
140
}
141
142
143
10579
void JSStream::New(const FunctionCallbackInfo<Value>& args) {
144
  // This constructor should not be exposed to public javascript.
145
  // Therefore we assert that we are not trying to call this as a
146
  // normal function.
147
10579
  CHECK(args.IsConstructCall());
148
10579
  Environment* env = Environment::GetCurrent(args);
149
10579
  new JSStream(env, args.This());
150
10579
}
151
152
153
template <class Wrap>
154
609
void JSStream::Finish(const FunctionCallbackInfo<Value>& args) {
155

1218
  CHECK(args[0]->IsObject());
156
1218
  Wrap* w = static_cast<Wrap*>(StreamReq::FromObject(args[0].As<Object>()));
157
158

1218
  CHECK(args[1]->IsInt32());
159
1827
  w->Done(args[1].As<Int32>()->Value());
160
609
}
161
162
163
639
void JSStream::ReadBuffer(const FunctionCallbackInfo<Value>& args) {
164
  JSStream* wrap;
165
639
  ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
166
167
639
  ArrayBufferViewContents<char> buffer(args[0]);
168
639
  const char* data = buffer.data();
169
639
  int len = buffer.length();
170
171
  // Repeatedly ask the stream's owner for memory, copy the data that we
172
  // just read from JS into those buffers and emit them as reads.
173
1915
  while (len != 0) {
174
639
    uv_buf_t buf = wrap->EmitAlloc(len);
175
639
    ssize_t avail = len;
176
639
    if (static_cast<ssize_t>(buf.len) < avail)
177
      avail = buf.len;
178
179
639
    memcpy(buf.base, data, avail);
180
639
    data += avail;
181
639
    len -= static_cast<int>(avail);
182
639
    wrap->EmitRead(avail, buf);
183
  }
184
}
185
186
187
8
void JSStream::EmitEOF(const FunctionCallbackInfo<Value>& args) {
188
  JSStream* wrap;
189
8
  ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
190
191
8
  wrap->EmitRead(UV_EOF);
192
}
193
194
195
543
void JSStream::Initialize(Local<Object> target,
196
                          Local<Value> unused,
197
                          Local<Context> context,
198
                          void* priv) {
199
543
  Environment* env = Environment::GetCurrent(context);
200
201
  Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
202
1086
  t->InstanceTemplate()
203
543
    ->SetInternalFieldCount(StreamBase::kInternalFieldCount);
204
1086
  t->Inherit(AsyncWrap::GetConstructorTemplate(env));
205
206
543
  env->SetProtoMethod(t, "finishWrite", Finish<WriteWrap>);
207
543
  env->SetProtoMethod(t, "finishShutdown", Finish<ShutdownWrap>);
208
543
  env->SetProtoMethod(t, "readBuffer", ReadBuffer);
209
543
  env->SetProtoMethod(t, "emitEOF", EmitEOF);
210
211
543
  StreamBase::AddMethods(env, t);
212
543
  env->SetConstructorFunction(target, "JSStream", t);
213
543
}
214
215
}  // namespace node
216
217

19368
NODE_MODULE_CONTEXT_AWARE_INTERNAL(js_stream, node::JSStream::Initialize)