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: 98 113 86.7 %
Date: 2019-05-05 22:32:45 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
10574
JSStream::JSStream(Environment* env, Local<Object> obj)
27
    : AsyncWrap(env, obj, AsyncWrap::PROVIDER_JSSTREAM),
28
10574
      StreamBase(env) {
29
10574
  MakeWeak();
30
10574
  StreamBase::AttachToObject(obj);
31
10574
}
32
33
34
11191
AsyncWrap* JSStream::GetAsyncWrap() {
35
11191
  return static_cast<AsyncWrap*>(this);
36
}
37
38
39
10594
bool JSStream::IsAlive() {
40
10594
  return true;
41
}
42
43
44
bool JSStream::IsClosing() {
45
  HandleScope scope(env()->isolate());
46
  Context::Scope context_scope(env()->context());
47
  TryCatchScope try_catch(env());
48
  Local<Value> value;
49
  if (!MakeCallback(env()->isclosing_string(), 0, nullptr).ToLocal(&value)) {
50
    if (try_catch.HasCaught() && !try_catch.HasTerminated())
51
      FatalException(env()->isolate(), try_catch);
52
    return true;
53
  }
54
  return value->IsTrue();
55
}
56
57
58
10568
int JSStream::ReadStart() {
59
10568
  HandleScope scope(env()->isolate());
60
10568
  Context::Scope context_scope(env()->context());
61
21136
  TryCatchScope try_catch(env());
62
  Local<Value> value;
63
10568
  int value_int = UV_EPROTO;
64


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


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

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

4173
                    argv).ToLocal(&value) ||
137
2379
      !value->Int32Value(env()->context()).To(&value_int)) {
138

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

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

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