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: 100 114 87.7 %
Date: 2020-07-19 22:14:24 Branches: 39 82 47.6 %

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::String;
23
using v8::Value;
24
25
26
10580
JSStream::JSStream(Environment* env, Local<Object> obj)
27
    : AsyncWrap(env, obj, AsyncWrap::PROVIDER_JSSTREAM),
28
10580
      StreamBase(env) {
29
10580
  MakeWeak();
30
10580
  StreamBase::AttachToObject(obj);
31
10580
}
32
33
34
12789
AsyncWrap* JSStream::GetAsyncWrap() {
35
12789
  return static_cast<AsyncWrap*>(this);
36
}
37
38
39
10631
bool JSStream::IsAlive() {
40
10631
  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
      errors::TriggerUncaughtException(env()->isolate(), try_catch);
52
    return true;
53
  }
54
  return value->IsTrue();
55
}
56
57
58
10610
int JSStream::ReadStart() {
59
21220
  HandleScope scope(env()->isolate());
60
10610
  Context::Scope context_scope(env()->context());
61
21220
  TryCatchScope try_catch(env());
62
  Local<Value> value;
63
10610
  int value_int = UV_EPROTO;
64

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

251
  if (!MakeCallback(env()->onreadstop_string(), 0, nullptr).ToLocal(&value) ||
80
249
      !value->Int32Value(env()->context()).To(&value_int)) {
81

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

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

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

3
    if (try_catch.HasCaught() && !try_catch.HasTerminated())
138
2
      errors::TriggerUncaughtException(env()->isolate(), try_catch);
139
  }
140
1230
  return value_int;
141
}
142
143
144
10580
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
10580
  CHECK(args.IsConstructCall());
149
10580
  Environment* env = Environment::GetCurrent(args);
150
10580
  new JSStream(env, args.This());
151
10580
}
152
153
154
template <class Wrap>
155
616
void JSStream::Finish(const FunctionCallbackInfo<Value>& args) {
156

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

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

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