GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage/nodes/benchmark/out/../src/js_stream.cc Lines: 95 111 85.6 %
Date: 2019-01-07 12:15:22 Branches: 38 76 50.0 %

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 "node_internals.h"
8
#include "stream_base-inl.h"
9
#include "v8.h"
10
11
namespace node {
12
13
using errors::TryCatchScope;
14
15
using v8::Array;
16
using v8::Context;
17
using v8::FunctionCallbackInfo;
18
using v8::FunctionTemplate;
19
using v8::HandleScope;
20
using v8::Int32;
21
using v8::Local;
22
using v8::Object;
23
using v8::String;
24
using v8::Value;
25
26
27
10564
JSStream::JSStream(Environment* env, Local<Object> obj)
28
    : AsyncWrap(env, obj, AsyncWrap::PROVIDER_JSSTREAM),
29
10564
      StreamBase(env) {
30
10564
  MakeWeak();
31
10564
}
32
33
34
597
AsyncWrap* JSStream::GetAsyncWrap() {
35
597
  return static_cast<AsyncWrap*>(this);
36
}
37
38
39
10578
bool JSStream::IsAlive() {
40
10578
  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.HasTerminated())
51
      FatalException(env()->isolate(), try_catch);
52
    return true;
53
  }
54
  return value->IsTrue();
55
}
56
57
58
10558
int JSStream::ReadStart() {
59
10558
  HandleScope scope(env()->isolate());
60
10558
  Context::Scope context_scope(env()->context());
61
21116
  TryCatchScope try_catch(env());
62
  Local<Value> value;
63
10558
  int value_int = UV_EPROTO;
64


52790
  if (!MakeCallback(env()->onreadstart_string(), 0, nullptr).ToLocal(&value) ||
65
42232
      !value->Int32Value(env()->context()).To(&value_int)) {
66
    if (!try_catch.HasTerminated())
67
      FatalException(env()->isolate(), try_catch);
68
  }
69
21116
  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.HasTerminated())
82
      FatalException(env()->isolate(), try_catch);
83
  }
84
8
  return value_int;
85
}
86
87
88
6
int JSStream::DoShutdown(ShutdownWrap* req_wrap) {
89
6
  HandleScope scope(env()->isolate());
90
6
  Context::Scope context_scope(env()->context());
91
92
  Local<Value> argv[] = {
93
    req_wrap->object()
94
12
  };
95
96
12
  TryCatchScope try_catch(env());
97
  Local<Value> value;
98
6
  int value_int = UV_EPROTO;
99
12
  if (!MakeCallback(env()->onshutdown_string(),
100
6
                    arraysize(argv),
101

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

4063
                    argv).ToLocal(&value) ||
137
2318
      !value->Int32Value(env()->context()).To(&value_int)) {
138
2
    if (!try_catch.HasTerminated())
139
2
      FatalException(env()->isolate(), try_catch);
140
  }
141
1160
  return value_int;
142
}
143
144
145
10564
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
10564
  CHECK(args.IsConstructCall());
150
10564
  Environment* env = Environment::GetCurrent(args);
151
10564
  new JSStream(env, args.This());
152
10564
}
153
154
155
template <class Wrap>
156
584
void JSStream::Finish(const FunctionCallbackInfo<Value>& args) {
157

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

1168
  CHECK(args[1]->IsInt32());
161
1752
  w->Done(args[1].As<Int32>()->Value());
162
584
}
163
164
165
602
void JSStream::ReadBuffer(const FunctionCallbackInfo<Value>& args) {
166
  JSStream* wrap;
167
1203
  ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
168
169
602
  CHECK(Buffer::HasInstance(args[0]));
170
602
  char* data = Buffer::Data(args[0]);
171
602
  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
1805
  while (len != 0) {
176
602
    uv_buf_t buf = wrap->EmitAlloc(len);
177
602
    ssize_t avail = len;
178
602
    if (static_cast<ssize_t>(buf.len) < avail)
179
      avail = buf.len;
180
181
602
    memcpy(buf.base, data, avail);
182
602
    data += avail;
183
602
    len -= avail;
184
602
    wrap->EmitRead(avail, buf);
185
  }
186
}
187
188
189
6
void JSStream::EmitEOF(const FunctionCallbackInfo<Value>& args) {
190
  JSStream* wrap;
191
12
  ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
192
193
6
  wrap->EmitRead(UV_EOF);
194
}
195
196
197
431
void JSStream::Initialize(Local<Object> target,
198
                          Local<Value> unused,
199
                          Local<Context> context,
200
                          void* priv) {
201
431
  Environment* env = Environment::GetCurrent(context);
202
203
431
  Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
204
  Local<String> jsStreamString =
205
431
      FIXED_ONE_BYTE_STRING(env->isolate(), "JSStream");
206
431
  t->SetClassName(jsStreamString);
207
862
  t->InstanceTemplate()->SetInternalFieldCount(1);
208
862
  t->Inherit(AsyncWrap::GetConstructorTemplate(env));
209
210
431
  env->SetProtoMethod(t, "finishWrite", Finish<WriteWrap>);
211
431
  env->SetProtoMethod(t, "finishShutdown", Finish<ShutdownWrap>);
212
431
  env->SetProtoMethod(t, "readBuffer", ReadBuffer);
213
431
  env->SetProtoMethod(t, "emitEOF", EmitEOF);
214
215
431
  StreamBase::AddMethods<JSStream>(env, t);
216
  target->Set(env->context(),
217
              jsStreamString,
218
1724
              t->GetFunction(context).ToLocalChecked()).FromJust();
219
431
}
220
221
}  // namespace node
222
223
3596
NODE_MODULE_CONTEXT_AWARE_INTERNAL(js_stream, node::JSStream::Initialize)