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: 99 113 87.6 %
Date: 2019-09-16 22:31:04 Branches: 47 94 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 "stream_base-inl.h"
8
#include "util-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
10577
JSStream::JSStream(Environment* env, Local<Object> obj)
28
    : AsyncWrap(env, obj, AsyncWrap::PROVIDER_JSSTREAM),
29
10577
      StreamBase(env) {
30
10577
  MakeWeak();
31
10577
  StreamBase::AttachToObject(obj);
32
10577
}
33
34
35
11200
AsyncWrap* JSStream::GetAsyncWrap() {
36
11200
  return static_cast<AsyncWrap*>(this);
37
}
38
39
40
10597
bool JSStream::IsAlive() {
41
10597
  return true;
42
}
43
44
45
bool JSStream::IsClosing() {
46
  HandleScope scope(env()->isolate());
47
  Context::Scope context_scope(env()->context());
48
  TryCatchScope try_catch(env());
49
  Local<Value> value;
50
  if (!MakeCallback(env()->isclosing_string(), 0, nullptr).ToLocal(&value)) {
51
    if (try_catch.HasCaught() && !try_catch.HasTerminated())
52
      errors::TriggerUncaughtException(env()->isolate(), try_catch);
53
    return true;
54
  }
55
  return value->IsTrue();
56
}
57
58
59
10603
int JSStream::ReadStart() {
60
10603
  HandleScope scope(env()->isolate());
61
10603
  Context::Scope context_scope(env()->context());
62
21206
  TryCatchScope try_catch(env());
63
  Local<Value> value;
64
10603
  int value_int = UV_EPROTO;
65


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


188
  if (!MakeCallback(env()->onreadstop_string(), 0, nullptr).ToLocal(&value) ||
81
149
      !value->Int32Value(env()->context()).To(&value_int)) {
82

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

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

4215
                    argv).ToLocal(&value) ||
138
2403
      !value->Int32Value(env()->context()).To(&value_int)) {
139

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

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

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