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: 96 111 86.5 %
Date: 2019-02-23 22:23:05 Branches: 43 96 44.8 %

Line Branch Exec Source
1
#include "js_stream.h"
2
3
#include "async_wrap.h"
4
#include "env-inl.h"
5
#include "node_buffer.h"
6
#include "node_errors.h"
7
#include "stream_base-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::String;
23
using v8::Value;
24
25
26
10570
JSStream::JSStream(Environment* env, Local<Object> obj)
27
    : AsyncWrap(env, obj, AsyncWrap::PROVIDER_JSSTREAM),
28
10570
      StreamBase(env) {
29
10570
  MakeWeak();
30
10570
}
31
32
33
609
AsyncWrap* JSStream::GetAsyncWrap() {
34
609
  return static_cast<AsyncWrap*>(this);
35
}
36
37
38
10587
bool JSStream::IsAlive() {
39
10587
  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
      FatalException(env()->isolate(), try_catch);
51
    return true;
52
  }
53
  return value->IsTrue();
54
}
55
56
57
10564
int JSStream::ReadStart() {
58
10564
  HandleScope scope(env()->isolate());
59
10564
  Context::Scope context_scope(env()->context());
60
21128
  TryCatchScope try_catch(env());
61
  Local<Value> value;
62
10564
  int value_int = UV_EPROTO;
63


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


20
  if (!MakeCallback(env()->onreadstop_string(), 0, nullptr).ToLocal(&value) ||
79
16
      !value->Int32Value(env()->context()).To(&value_int)) {
80
    if (try_catch.HasCaught() && !try_catch.HasTerminated())
81
      FatalException(env()->isolate(), try_catch);
82
  }
83
8
  return value_int;
84
}
85
86
87
6
int JSStream::DoShutdown(ShutdownWrap* req_wrap) {
88
6
  HandleScope scope(env()->isolate());
89
6
  Context::Scope context_scope(env()->context());
90
91
  Local<Value> argv[] = {
92
    req_wrap->object()
93
12
  };
94
95
12
  TryCatchScope try_catch(env());
96
  Local<Value> value;
97
6
  int value_int = UV_EPROTO;
98
12
  if (!MakeCallback(env()->onshutdown_string(),
99
6
                    arraysize(argv),
100

42
                    argv).ToLocal(&value) ||
101
24
      !value->Int32Value(env()->context()).To(&value_int)) {
102
    if (try_catch.HasCaught() && !try_catch.HasTerminated())
103
      FatalException(env()->isolate(), try_catch);
104
  }
105
12
  return value_int;
106
}
107
108
109
592
int JSStream::DoWrite(WriteWrap* w,
110
                      uv_buf_t* bufs,
111
                      size_t count,
112
                      uv_stream_t* send_handle) {
113
592
  CHECK_NULL(send_handle);
114
115
592
  HandleScope scope(env()->isolate());
116
592
  Context::Scope context_scope(env()->context());
117
118
592
  Local<Array> bufs_arr = Array::New(env()->isolate(), count);
119
  Local<Object> buf;
120
1227
  for (size_t i = 0; i < count; i++) {
121
1270
    buf = Buffer::Copy(env(), bufs[i].base, bufs[i].len).ToLocalChecked();
122
1905
    bufs_arr->Set(env()->context(), i, buf).FromJust();
123
  }
124
125
  Local<Value> argv[] = {
126
    w->object(),
127
    bufs_arr
128
1776
  };
129
130
1183
  TryCatchScope try_catch(env());
131
  Local<Value> value;
132
592
  int value_int = UV_EPROTO;
133
1184
  if (!MakeCallback(env()->onwrite_string(),
134
592
                    arraysize(argv),
135

4138
                    argv).ToLocal(&value) ||
136
2359
      !value->Int32Value(env()->context()).To(&value_int)) {
137

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

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

1184
  CHECK(args[1]->IsInt32());
160
1776
  w->Done(args[1].As<Int32>()->Value());
161
592
}
162
163
164
614
void JSStream::ReadBuffer(const FunctionCallbackInfo<Value>& args) {
165
  JSStream* wrap;
166
1227
  ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
167
168
614
  CHECK(Buffer::HasInstance(args[0]));
169
614
  char* data = Buffer::Data(args[0]);
170
614
  int len = Buffer::Length(args[0]);
171
172
  // Repeatedly ask the stream's owner for memory, copy the data that we
173
  // just read from JS into those buffers and emit them as reads.
174
1866
  while (len != 0) {
175
639
    uv_buf_t buf = wrap->EmitAlloc(len);
176
639
    ssize_t avail = len;
177
639
    if (static_cast<ssize_t>(buf.len) < avail)
178
25
      avail = buf.len;
179
180
639
    memcpy(buf.base, data, avail);
181
639
    data += avail;
182
639
    len -= avail;
183
639
    wrap->EmitRead(avail, buf);
184
  }
185
}
186
187
188
9
void JSStream::EmitEOF(const FunctionCallbackInfo<Value>& args) {
189
  JSStream* wrap;
190
18
  ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
191
192
9
  wrap->EmitRead(UV_EOF);
193
}
194
195
196
464
void JSStream::Initialize(Local<Object> target,
197
                          Local<Value> unused,
198
                          Local<Context> context,
199
                          void* priv) {
200
464
  Environment* env = Environment::GetCurrent(context);
201
202
464
  Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
203
  Local<String> jsStreamString =
204
464
      FIXED_ONE_BYTE_STRING(env->isolate(), "JSStream");
205
464
  t->SetClassName(jsStreamString);
206
928
  t->InstanceTemplate()->SetInternalFieldCount(1);
207
928
  t->Inherit(AsyncWrap::GetConstructorTemplate(env));
208
209
464
  env->SetProtoMethod(t, "finishWrite", Finish<WriteWrap>);
210
464
  env->SetProtoMethod(t, "finishShutdown", Finish<ShutdownWrap>);
211
464
  env->SetProtoMethod(t, "readBuffer", ReadBuffer);
212
464
  env->SetProtoMethod(t, "emitEOF", EmitEOF);
213
214
464
  StreamBase::AddMethods<JSStream>(env, t);
215
  target->Set(env->context(),
216
              jsStreamString,
217
1856
              t->GetFunction(context).ToLocalChecked()).FromJust();
218
464
}
219
220
}  // namespace node
221
222
4288
NODE_MODULE_CONTEXT_AWARE_INTERNAL(js_stream, node::JSStream::Initialize)