GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/node_wasi.cc Lines: 579 843 68.7 %
Date: 2020-06-24 22:13:30 Branches: 308 896 34.4 %

Line Branch Exec Source
1
#include "env-inl.h"
2
#include "base_object-inl.h"
3
#include "debug_utils-inl.h"
4
#include "memory_tracker-inl.h"
5
#include "node_mem-inl.h"
6
#include "util-inl.h"
7
#include "node.h"
8
#include "node_errors.h"
9
#include "uv.h"
10
#include "uvwasi.h"
11
#include "node_wasi.h"
12
13
namespace node {
14
namespace wasi {
15
16
template <typename... Args>
17
254
inline void Debug(WASI* wasi, Args&&... args) {
18
254
  Debug(wasi->env(), DebugCategory::WASI, std::forward<Args>(args)...);
19
254
}
20
21
#define ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(ptr, obj)                          \
22
  do {                                                                         \
23
    ASSIGN_OR_RETURN_UNWRAP(ptr, obj);                                         \
24
    if ((*(ptr))->memory_.IsEmpty()) {                                         \
25
      THROW_ERR_WASI_NOT_STARTED(Environment::GetCurrent(args));               \
26
      return;                                                                  \
27
    }                                                                          \
28
  } while (0)
29
30
#define RETURN_IF_BAD_ARG_COUNT(args, expected)                               \
31
  do {                                                                        \
32
    if ((args).Length() != (expected)) {                                      \
33
      (args).GetReturnValue().Set(UVWASI_EINVAL);                             \
34
      return;                                                                 \
35
    }                                                                         \
36
  } while (0)
37
38
#define CHECK_TO_TYPE_OR_RETURN(args, input, type, result)                    \
39
  do {                                                                        \
40
    if (!(input)->Is##type()) {                                               \
41
      (args).GetReturnValue().Set(UVWASI_EINVAL);                             \
42
      return;                                                                 \
43
    }                                                                         \
44
    (result) = (input).As<type>()->Value();                                   \
45
  } while (0)
46
47
#define UNWRAP_BIGINT_OR_RETURN(args, input, type, result)                    \
48
  do {                                                                        \
49
    if (!(input)->IsBigInt()) {                                               \
50
      (args).GetReturnValue().Set(UVWASI_EINVAL);                             \
51
      return;                                                                 \
52
    }                                                                         \
53
    Local<BigInt> js_value = (input).As<BigInt>();                            \
54
    bool lossless;                                                            \
55
    (result) = js_value->type ## Value(&lossless);                            \
56
  } while (0)
57
58
#define GET_BACKING_STORE_OR_RETURN(wasi, args, mem_ptr, mem_size)            \
59
  do {                                                                        \
60
    uvwasi_errno_t err = (wasi)->backingStore((mem_ptr), (mem_size));         \
61
    if (err != UVWASI_ESUCCESS) {                                             \
62
      (args).GetReturnValue().Set(err);                                       \
63
      return;                                                                 \
64
    }                                                                         \
65
  } while (0)
66
67
#define CHECK_BOUNDS_OR_RETURN(args, mem_size, offset, buf_size)              \
68
  do {                                                                        \
69
    if (!uvwasi_serdes_check_bounds((offset), (mem_size), (buf_size))) {      \
70
      (args).GetReturnValue().Set(UVWASI_EOVERFLOW);                          \
71
      return;                                                                 \
72
    }                                                                         \
73
  } while (0)
74
75
76
using v8::Array;
77
using v8::ArrayBuffer;
78
using v8::BackingStore;
79
using v8::BigInt;
80
using v8::Context;
81
using v8::Exception;
82
using v8::FunctionCallbackInfo;
83
using v8::FunctionTemplate;
84
using v8::Integer;
85
using v8::Isolate;
86
using v8::Local;
87
using v8::MaybeLocal;
88
using v8::Object;
89
using v8::String;
90
using v8::Uint32;
91
using v8::Value;
92
93
94
1
static MaybeLocal<Value> WASIException(Local<Context> context,
95
                                       int errorno,
96
                                       const char* syscall) {
97
1
  Isolate* isolate = context->GetIsolate();
98
1
  Environment* env = Environment::GetCurrent(context);
99
1
  CHECK_NOT_NULL(env);
100
1
  const char* err_name = uvwasi_embedder_err_code_to_string(errorno);
101
1
  Local<String> js_code = OneByteString(isolate, err_name);
102
1
  Local<String> js_syscall = OneByteString(isolate, syscall);
103
1
  Local<String> js_msg = js_code;
104
  js_msg =
105
1
      String::Concat(isolate, js_msg, FIXED_ONE_BYTE_STRING(isolate, ", "));
106
1
  js_msg = String::Concat(isolate, js_msg, js_syscall);
107
  Local<Object> e =
108
3
    Exception::Error(js_msg)->ToObject(context)
109
1
      .ToLocalChecked();
110
111
4
  if (e->Set(context,
112
             env->errno_string(),
113
6
             Integer::New(isolate, errorno)).IsNothing() ||
114

6
      e->Set(context, env->code_string(), js_code).IsNothing() ||
115
4
      e->Set(context, env->syscall_string(), js_syscall).IsNothing()) {
116
    return MaybeLocal<Value>();
117
  }
118
119
1
  return e;
120
}
121
122
123
39
WASI::WASI(Environment* env,
124
           Local<Object> object,
125
78
           uvwasi_options_t* options) : BaseObject(env, object) {
126
39
  MakeWeak();
127
39
  alloc_info_ = MakeAllocator();
128
39
  options->allocator = &alloc_info_;
129
39
  int err = uvwasi_init(&uvw_, options);
130
39
  if (err != UVWASI_ESUCCESS) {
131
1
    Local<Context> context = env->context();
132
1
    MaybeLocal<Value> exception = WASIException(context, err, "uvwasi_init");
133
134
1
    if (exception.IsEmpty())
135
      return;
136
137
1
    context->GetIsolate()->ThrowException(exception.ToLocalChecked());
138
  }
139
}
140
141
142
152
WASI::~WASI() {
143
38
  uvwasi_destroy(&uvw_);
144
38
  CHECK_EQ(current_uvwasi_memory_, 0);
145
76
}
146
147
void WASI::MemoryInfo(MemoryTracker* tracker) const {
148
  tracker->TrackField("memory", memory_);
149
  tracker->TrackFieldWithSize("uvwasi_memory", current_uvwasi_memory_);
150
}
151
152
1165
void WASI::CheckAllocatedSize(size_t previous_size) const {
153
1165
  CHECK_GE(current_uvwasi_memory_, previous_size);
154
1165
}
155
156
600
void WASI::IncreaseAllocatedSize(size_t size) {
157
600
  current_uvwasi_memory_ += size;
158
600
}
159
160
565
void WASI::DecreaseAllocatedSize(size_t size) {
161
565
  current_uvwasi_memory_ -= size;
162
565
}
163
164
39
void WASI::New(const FunctionCallbackInfo<Value>& args) {
165
39
  CHECK(args.IsConstructCall());
166
39
  CHECK_EQ(args.Length(), 4);
167
78
  CHECK(args[0]->IsArray());
168
78
  CHECK(args[1]->IsArray());
169
78
  CHECK(args[2]->IsArray());
170
78
  CHECK(args[3]->IsArray());
171
172
39
  Environment* env = Environment::GetCurrent(args);
173
39
  Local<Context> context = env->context();
174
78
  Local<Array> argv = args[0].As<Array>();
175
39
  const uint32_t argc = argv->Length();
176
  uvwasi_options_t options;
177
178
78
  Local<Array> stdio = args[3].As<Array>();
179
39
  CHECK_EQ(stdio->Length(), 3);
180
156
  options.in = stdio->Get(context, 0).ToLocalChecked()->
181
117
    Int32Value(context).FromJust();
182
156
  options.out = stdio->Get(context, 1).ToLocalChecked()->
183
117
    Int32Value(context).FromJust();
184
156
  options.err = stdio->Get(context, 2).ToLocalChecked()->
185
117
    Int32Value(context).FromJust();
186
187
39
  options.fd_table_size = 3;
188
39
  options.argc = argc;
189
39
  options.argv =
190
39
    const_cast<const char**>(argc == 0 ? nullptr : new char*[argc]);
191
192
96
  for (uint32_t i = 0; i < argc; i++) {
193
114
    auto arg = argv->Get(context, i).ToLocalChecked();
194
114
    CHECK(arg->IsString());
195
114
    node::Utf8Value str(env->isolate(), arg);
196
57
    options.argv[i] = strdup(*str);
197
57
    CHECK_NOT_NULL(options.argv[i]);
198
  }
199
200
78
  Local<Array> env_pairs = args[1].As<Array>();
201
39
  const uint32_t envc = env_pairs->Length();
202
39
  options.envp = const_cast<const char**>(new char*[envc + 1]);
203
1597
  for (uint32_t i = 0; i < envc; i++) {
204
3116
    auto pair = env_pairs->Get(context, i).ToLocalChecked();
205
3116
    CHECK(pair->IsString());
206
3116
    node::Utf8Value str(env->isolate(), pair);
207
1558
    options.envp[i] = strdup(*str);
208
1558
    CHECK_NOT_NULL(options.envp[i]);
209
  }
210
39
  options.envp[envc] = nullptr;
211
212
78
  Local<Array> preopens = args[2].As<Array>();
213
39
  CHECK_EQ(preopens->Length() % 2, 0);
214
39
  options.preopenc = preopens->Length() / 2;
215
39
  options.preopens = Calloc<uvwasi_preopen_t>(options.preopenc);
216
39
  int index = 0;
217
160
  for (uint32_t i = 0; i < preopens->Length(); i += 2) {
218
82
    auto mapped = preopens->Get(context, i).ToLocalChecked();
219
123
    auto real = preopens->Get(context, i + 1).ToLocalChecked();
220
82
    CHECK(mapped->IsString());
221
82
    CHECK(real->IsString());
222
82
    node::Utf8Value mapped_path(env->isolate(), mapped);
223
82
    node::Utf8Value real_path(env->isolate(), real);
224
41
    options.preopens[index].mapped_path = strdup(*mapped_path);
225
41
    CHECK_NOT_NULL(options.preopens[index].mapped_path);
226
41
    options.preopens[index].real_path = strdup(*real_path);
227
41
    CHECK_NOT_NULL(options.preopens[index].real_path);
228
41
    index++;
229
  }
230
231
39
  new WASI(env, args.This(), &options);
232
233
39
  if (options.argv != nullptr) {
234
76
    for (uint32_t i = 0; i < argc; i++)
235
57
      free(const_cast<char*>(options.argv[i]));
236
19
    delete[] options.argv;
237
  }
238
239
39
  if (options.envp != nullptr) {
240
1597
    for (uint32_t i = 0; options.envp[i]; i++)
241
1558
      free(const_cast<char*>(options.envp[i]));
242
39
    delete[] options.envp;
243
  }
244
245
39
  if (options.preopens != nullptr) {
246
80
    for (uint32_t i = 0; i < options.preopenc; i++) {
247
41
      free(options.preopens[i].mapped_path);
248
41
      free(options.preopens[i].real_path);
249
    }
250
251
39
    free(options.preopens);
252
  }
253
39
}
254
255
256
1
void WASI::ArgsGet(const FunctionCallbackInfo<Value>& args) {
257
  WASI* wasi;
258
  uint32_t argv_offset;
259
  uint32_t argv_buf_offset;
260
  char* memory;
261
  size_t mem_size;
262
1
  RETURN_IF_BAD_ARG_COUNT(args, 2);
263
5
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, argv_offset);
264
5
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, argv_buf_offset);
265

2
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
266
1
  Debug(wasi, "args_get(%d, %d)\n", argv_offset, argv_buf_offset);
267
1
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
268
1
  CHECK_BOUNDS_OR_RETURN(args,
269
                         mem_size,
270
                         argv_buf_offset,
271
                         wasi->uvw_.argv_buf_size);
272
1
  CHECK_BOUNDS_OR_RETURN(args,
273
                         mem_size,
274
                         argv_offset,
275
                         wasi->uvw_.argc * UVWASI_SERDES_SIZE_uint32_t);
276
2
  std::vector<char*> argv(wasi->uvw_.argc);
277
1
  char* argv_buf = &memory[argv_buf_offset];
278
1
  uvwasi_errno_t err = uvwasi_args_get(&wasi->uvw_, argv.data(), argv_buf);
279
280
1
  if (err == UVWASI_ESUCCESS) {
281
4
    for (size_t i = 0; i < wasi->uvw_.argc; i++) {
282
3
      uint32_t offset = argv_buf_offset + (argv[i] - argv[0]);
283
6
      uvwasi_serdes_write_uint32_t(memory,
284
                                   argv_offset +
285
3
                                   (i * UVWASI_SERDES_SIZE_uint32_t),
286
3
                                   offset);
287
    }
288
  }
289
290
3
  args.GetReturnValue().Set(err);
291
}
292
293
294
1
void WASI::ArgsSizesGet(const FunctionCallbackInfo<Value>& args) {
295
  WASI* wasi;
296
  uint32_t argc_offset;
297
  uint32_t argv_buf_offset;
298
  char* memory;
299
  size_t mem_size;
300
1
  RETURN_IF_BAD_ARG_COUNT(args, 2);
301
5
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, argc_offset);
302
5
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, argv_buf_offset);
303

2
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
304
1
  Debug(wasi, "args_sizes_get(%d, %d)\n", argc_offset, argv_buf_offset);
305
1
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
306
1
  CHECK_BOUNDS_OR_RETURN(args,
307
                         mem_size,
308
                         argc_offset,
309
                         UVWASI_SERDES_SIZE_size_t);
310
1
  CHECK_BOUNDS_OR_RETURN(args,
311
                         mem_size,
312
                         argv_buf_offset,
313
                         UVWASI_SERDES_SIZE_size_t);
314
  uvwasi_size_t argc;
315
  uvwasi_size_t argv_buf_size;
316
1
  uvwasi_errno_t err = uvwasi_args_sizes_get(&wasi->uvw_,
317
                                             &argc,
318
1
                                             &argv_buf_size);
319
1
  if (err == UVWASI_ESUCCESS) {
320
1
    uvwasi_serdes_write_size_t(memory, argc_offset, argc);
321
1
    uvwasi_serdes_write_size_t(memory, argv_buf_offset, argv_buf_size);
322
  }
323
324
3
  args.GetReturnValue().Set(err);
325
}
326
327
328
4
void WASI::ClockResGet(const FunctionCallbackInfo<Value>& args) {
329
  WASI* wasi;
330
  uint32_t clock_id;
331
  uint32_t resolution_ptr;
332
  char* memory;
333
  size_t mem_size;
334
4
  RETURN_IF_BAD_ARG_COUNT(args, 2);
335
20
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, clock_id);
336
20
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, resolution_ptr);
337

8
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
338
4
  Debug(wasi, "clock_res_get(%d, %d)\n", clock_id, resolution_ptr);
339
4
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
340
4
  CHECK_BOUNDS_OR_RETURN(args,
341
                         mem_size,
342
                         resolution_ptr,
343
                         UVWASI_SERDES_SIZE_timestamp_t);
344
  uvwasi_timestamp_t resolution;
345
4
  uvwasi_errno_t err = uvwasi_clock_res_get(&wasi->uvw_,
346
                                            clock_id,
347
4
                                            &resolution);
348
4
  if (err == UVWASI_ESUCCESS)
349
4
    uvwasi_serdes_write_timestamp_t(memory, resolution_ptr, resolution);
350
351
12
  args.GetReturnValue().Set(err);
352
}
353
354
355
8
void WASI::ClockTimeGet(const FunctionCallbackInfo<Value>& args) {
356
  WASI* wasi;
357
  uint32_t clock_id;
358
  uint64_t precision;
359
  uint32_t time_ptr;
360
  char* memory;
361
  size_t mem_size;
362
8
  RETURN_IF_BAD_ARG_COUNT(args, 3);
363
40
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, clock_id);
364
40
  UNWRAP_BIGINT_OR_RETURN(args, args[1], Uint64, precision);
365
40
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, time_ptr);
366

16
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
367
8
  Debug(wasi, "clock_time_get(%d, %d, %d)\n", clock_id, precision, time_ptr);
368
8
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
369
8
  CHECK_BOUNDS_OR_RETURN(args,
370
                         mem_size,
371
                         time_ptr,
372
                         UVWASI_SERDES_SIZE_timestamp_t);
373
  uvwasi_timestamp_t time;
374
8
  uvwasi_errno_t err = uvwasi_clock_time_get(&wasi->uvw_,
375
                                             clock_id,
376
                                             precision,
377
8
                                             &time);
378
8
  if (err == UVWASI_ESUCCESS)
379
8
    uvwasi_serdes_write_timestamp_t(memory, time_ptr, time);
380
381
24
  args.GetReturnValue().Set(err);
382
}
383
384
385
22
void WASI::EnvironGet(const FunctionCallbackInfo<Value>& args) {
386
  WASI* wasi;
387
  uint32_t environ_offset;
388
  uint32_t environ_buf_offset;
389
  char* memory;
390
  size_t mem_size;
391
22
  RETURN_IF_BAD_ARG_COUNT(args, 2);
392
110
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, environ_offset);
393
110
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, environ_buf_offset);
394

44
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
395
22
  Debug(wasi, "environ_get(%d, %d)\n", environ_offset, environ_buf_offset);
396
22
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
397
22
  CHECK_BOUNDS_OR_RETURN(args,
398
                         mem_size,
399
                         environ_buf_offset,
400
                         wasi->uvw_.env_buf_size);
401
22
  CHECK_BOUNDS_OR_RETURN(args,
402
                         mem_size,
403
                         environ_offset,
404
                         wasi->uvw_.envc * UVWASI_SERDES_SIZE_uint32_t);
405
44
  std::vector<char*> environment(wasi->uvw_.envc);
406
22
  char* environ_buf = &memory[environ_buf_offset];
407
22
  uvwasi_errno_t err = uvwasi_environ_get(&wasi->uvw_,
408
                                          environment.data(),
409
22
                                          environ_buf);
410
411
22
  if (err == UVWASI_ESUCCESS) {
412
1580
    for (size_t i = 0; i < wasi->uvw_.envc; i++) {
413
1558
      uint32_t offset = environ_buf_offset + (environment[i] - environment[0]);
414
415
3116
      uvwasi_serdes_write_uint32_t(memory,
416
                                   environ_offset +
417
1558
                                   (i * UVWASI_SERDES_SIZE_uint32_t),
418
1558
                                   offset);
419
    }
420
  }
421
422
66
  args.GetReturnValue().Set(err);
423
}
424
425
426
25
void WASI::EnvironSizesGet(const FunctionCallbackInfo<Value>& args) {
427
  WASI* wasi;
428
  uint32_t envc_offset;
429
  uint32_t env_buf_offset;
430
  char* memory;
431
  size_t mem_size;
432
25
  RETURN_IF_BAD_ARG_COUNT(args, 2);
433
125
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, envc_offset);
434
125
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, env_buf_offset);
435

50
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
436
25
  Debug(wasi, "environ_sizes_get(%d, %d)\n", envc_offset, env_buf_offset);
437
25
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
438
25
  CHECK_BOUNDS_OR_RETURN(args,
439
                         mem_size,
440
                         envc_offset,
441
                         UVWASI_SERDES_SIZE_size_t);
442
25
  CHECK_BOUNDS_OR_RETURN(args,
443
                         mem_size,
444
                         env_buf_offset,
445
                         UVWASI_SERDES_SIZE_size_t);
446
  uvwasi_size_t envc;
447
  uvwasi_size_t env_buf_size;
448
25
  uvwasi_errno_t err = uvwasi_environ_sizes_get(&wasi->uvw_,
449
                                                &envc,
450
25
                                                &env_buf_size);
451
25
  if (err == UVWASI_ESUCCESS) {
452
25
    uvwasi_serdes_write_size_t(memory, envc_offset, envc);
453
25
    uvwasi_serdes_write_size_t(memory, env_buf_offset, env_buf_size);
454
  }
455
456
75
  args.GetReturnValue().Set(err);
457
}
458
459
460
void WASI::FdAdvise(const FunctionCallbackInfo<Value>& args) {
461
  WASI* wasi;
462
  uint32_t fd;
463
  uint64_t offset;
464
  uint64_t len;
465
  uint8_t advice;
466
  RETURN_IF_BAD_ARG_COUNT(args, 4);
467
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
468
  UNWRAP_BIGINT_OR_RETURN(args, args[1], Uint64, offset);
469
  UNWRAP_BIGINT_OR_RETURN(args, args[2], Uint64, len);
470
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, advice);
471
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
472
  Debug(wasi, "fd_advise(%d, %d, %d, %d)\n", fd, offset, len, advice);
473
  uvwasi_errno_t err = uvwasi_fd_advise(&wasi->uvw_, fd, offset, len, advice);
474
  args.GetReturnValue().Set(err);
475
}
476
477
478
void WASI::FdAllocate(const FunctionCallbackInfo<Value>& args) {
479
  WASI* wasi;
480
  uint32_t fd;
481
  uint64_t offset;
482
  uint64_t len;
483
  RETURN_IF_BAD_ARG_COUNT(args, 3);
484
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
485
  UNWRAP_BIGINT_OR_RETURN(args, args[1], Uint64, offset);
486
  UNWRAP_BIGINT_OR_RETURN(args, args[2], Uint64, len);
487
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
488
  Debug(wasi, "fd_allocate(%d, %d, %d)\n", fd, offset, len);
489
  uvwasi_errno_t err = uvwasi_fd_allocate(&wasi->uvw_, fd, offset, len);
490
  args.GetReturnValue().Set(err);
491
}
492
493
494
3
void WASI::FdClose(const FunctionCallbackInfo<Value>& args) {
495
  WASI* wasi;
496
  uint32_t fd;
497
4
  RETURN_IF_BAD_ARG_COUNT(args, 1);
498
14
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
499

4
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
500
2
  Debug(wasi, "fd_close(%d)\n", fd);
501
2
  uvwasi_errno_t err = uvwasi_fd_close(&wasi->uvw_, fd);
502
6
  args.GetReturnValue().Set(err);
503
}
504
505
506
void WASI::FdDatasync(const FunctionCallbackInfo<Value>& args) {
507
  WASI* wasi;
508
  uint32_t fd;
509
  RETURN_IF_BAD_ARG_COUNT(args, 1);
510
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
511
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
512
  Debug(wasi, "fd_datasync(%d)\n", fd);
513
  uvwasi_errno_t err = uvwasi_fd_datasync(&wasi->uvw_, fd);
514
  args.GetReturnValue().Set(err);
515
}
516
517
518
24
void WASI::FdFdstatGet(const FunctionCallbackInfo<Value>& args) {
519
  WASI* wasi;
520
  uint32_t fd;
521
  uint32_t buf;
522
  char* memory;
523
  size_t mem_size;
524
24
  RETURN_IF_BAD_ARG_COUNT(args, 2);
525
120
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
526
120
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, buf);
527

48
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
528
24
  Debug(wasi, "fd_fdstat_get(%d, %d)\n", fd, buf);
529
24
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
530
24
  CHECK_BOUNDS_OR_RETURN(args, mem_size, buf, UVWASI_SERDES_SIZE_fdstat_t);
531
  uvwasi_fdstat_t stats;
532
24
  uvwasi_errno_t err = uvwasi_fd_fdstat_get(&wasi->uvw_, fd, &stats);
533
534
24
  if (err == UVWASI_ESUCCESS)
535
24
    uvwasi_serdes_write_fdstat_t(memory, buf, &stats);
536
537
72
  args.GetReturnValue().Set(err);
538
}
539
540
541
void WASI::FdFdstatSetFlags(const FunctionCallbackInfo<Value>& args) {
542
  WASI* wasi;
543
  uint32_t fd;
544
  uint16_t flags;
545
  RETURN_IF_BAD_ARG_COUNT(args, 2);
546
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
547
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, flags);
548
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
549
  Debug(wasi, "fd_fdstat_set_flags(%d, %d)\n", fd, flags);
550
  uvwasi_errno_t err = uvwasi_fd_fdstat_set_flags(&wasi->uvw_, fd, flags);
551
  args.GetReturnValue().Set(err);
552
}
553
554
555
void WASI::FdFdstatSetRights(const FunctionCallbackInfo<Value>& args) {
556
  WASI* wasi;
557
  uint32_t fd;
558
  uint64_t fs_rights_base;
559
  uint64_t fs_rights_inheriting;
560
  RETURN_IF_BAD_ARG_COUNT(args, 3);
561
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
562
  UNWRAP_BIGINT_OR_RETURN(args, args[1], Uint64, fs_rights_base);
563
  UNWRAP_BIGINT_OR_RETURN(args, args[2], Uint64, fs_rights_inheriting);
564
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
565
  Debug(wasi,
566
        "fd_fdstat_set_rights(%d, %d, %d)\n",
567
        fd,
568
        fs_rights_base,
569
        fs_rights_inheriting);
570
  uvwasi_errno_t err = uvwasi_fd_fdstat_set_rights(&wasi->uvw_,
571
                                                   fd,
572
                                                   fs_rights_base,
573
                                                   fs_rights_inheriting);
574
  args.GetReturnValue().Set(err);
575
}
576
577
578
1
void WASI::FdFilestatGet(const FunctionCallbackInfo<Value>& args) {
579
  WASI* wasi;
580
  uint32_t fd;
581
  uint32_t buf;
582
  char* memory;
583
  size_t mem_size;
584
1
  RETURN_IF_BAD_ARG_COUNT(args, 2);
585
5
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
586
5
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, buf);
587

2
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
588
1
  Debug(wasi, "fd_filestat_get(%d, %d)\n", fd, buf);
589
1
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
590
1
  CHECK_BOUNDS_OR_RETURN(args, mem_size, buf, UVWASI_SERDES_SIZE_filestat_t);
591
  uvwasi_filestat_t stats;
592
1
  uvwasi_errno_t err = uvwasi_fd_filestat_get(&wasi->uvw_, fd, &stats);
593
594
1
  if (err == UVWASI_ESUCCESS)
595
1
    uvwasi_serdes_write_filestat_t(memory, buf, &stats);
596
597
3
  args.GetReturnValue().Set(err);
598
}
599
600
601
void WASI::FdFilestatSetSize(const FunctionCallbackInfo<Value>& args) {
602
  WASI* wasi;
603
  uint32_t fd;
604
  uint64_t st_size;
605
  RETURN_IF_BAD_ARG_COUNT(args, 2);
606
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
607
  UNWRAP_BIGINT_OR_RETURN(args, args[1], Uint64, st_size);
608
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
609
  Debug(wasi, "fd_filestat_set_size(%d, %d)\n", fd, st_size);
610
  uvwasi_errno_t err = uvwasi_fd_filestat_set_size(&wasi->uvw_, fd, st_size);
611
  args.GetReturnValue().Set(err);
612
}
613
614
615
void WASI::FdFilestatSetTimes(const FunctionCallbackInfo<Value>& args) {
616
  WASI* wasi;
617
  uint32_t fd;
618
  uint64_t st_atim;
619
  uint64_t st_mtim;
620
  uint16_t fst_flags;
621
  RETURN_IF_BAD_ARG_COUNT(args, 4);
622
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
623
  UNWRAP_BIGINT_OR_RETURN(args, args[1], Uint64, st_atim);
624
  UNWRAP_BIGINT_OR_RETURN(args, args[2], Uint64, st_mtim);
625
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, fst_flags);
626
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
627
  Debug(wasi,
628
        "fd_filestat_set_times(%d, %d, %d, %d)\n",
629
        fd,
630
        st_atim,
631
        st_mtim,
632
        fst_flags);
633
  uvwasi_errno_t err = uvwasi_fd_filestat_set_times(&wasi->uvw_,
634
                                                    fd,
635
                                                    st_atim,
636
                                                    st_mtim,
637
                                                    fst_flags);
638
  args.GetReturnValue().Set(err);
639
}
640
641
642
void WASI::FdPread(const FunctionCallbackInfo<Value>& args) {
643
  WASI* wasi;
644
  uint32_t fd;
645
  uint32_t iovs_ptr;
646
  uint32_t iovs_len;
647
  uint64_t offset;
648
  uint32_t nread_ptr;
649
  char* memory;
650
  size_t mem_size;
651
  RETURN_IF_BAD_ARG_COUNT(args, 5);
652
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
653
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, iovs_ptr);
654
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, iovs_len);
655
  UNWRAP_BIGINT_OR_RETURN(args, args[3], Uint64, offset);
656
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, nread_ptr);
657
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
658
  Debug(wasi,
659
        "uvwasi_fd_pread(%d, %d, %d, %d, %d)\n",
660
        fd,
661
        iovs_ptr,
662
        iovs_len,
663
        offset,
664
        nread_ptr);
665
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
666
  CHECK_BOUNDS_OR_RETURN(args,
667
                         mem_size,
668
                         iovs_ptr,
669
                         iovs_len * UVWASI_SERDES_SIZE_iovec_t);
670
  CHECK_BOUNDS_OR_RETURN(args, mem_size, nread_ptr, UVWASI_SERDES_SIZE_size_t);
671
  std::vector<uvwasi_iovec_t> iovs(iovs_len);
672
  uvwasi_errno_t err;
673
674
  err = uvwasi_serdes_readv_iovec_t(memory,
675
                                    mem_size,
676
                                    iovs_ptr,
677
                                    iovs.data(),
678
                                    iovs_len);
679
  if (err != UVWASI_ESUCCESS) {
680
    args.GetReturnValue().Set(err);
681
    return;
682
  }
683
684
  uvwasi_size_t nread;
685
  err = uvwasi_fd_pread(&wasi->uvw_, fd, iovs.data(), iovs_len, offset, &nread);
686
  if (err == UVWASI_ESUCCESS)
687
    uvwasi_serdes_write_size_t(memory, nread_ptr, nread);
688
689
  args.GetReturnValue().Set(err);
690
}
691
692
693
66
void WASI::FdPrestatGet(const FunctionCallbackInfo<Value>& args) {
694
  WASI* wasi;
695
  uint32_t fd;
696
  uint32_t buf;
697
  char* memory;
698
  size_t mem_size;
699
67
  RETURN_IF_BAD_ARG_COUNT(args, 2);
700
330
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
701
330
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, buf);
702

132
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
703
65
  Debug(wasi, "fd_prestat_get(%d, %d)\n", fd, buf);
704
65
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
705
65
  CHECK_BOUNDS_OR_RETURN(args, mem_size, buf, UVWASI_SERDES_SIZE_prestat_t);
706
  uvwasi_prestat_t prestat;
707
65
  uvwasi_errno_t err = uvwasi_fd_prestat_get(&wasi->uvw_, fd, &prestat);
708
709
65
  if (err == UVWASI_ESUCCESS)
710
40
    uvwasi_serdes_write_prestat_t(memory, buf, &prestat);
711
712
195
  args.GetReturnValue().Set(err);
713
}
714
715
716
40
void WASI::FdPrestatDirName(const FunctionCallbackInfo<Value>& args) {
717
  WASI* wasi;
718
  uint32_t fd;
719
  uint32_t path_ptr;
720
  uint32_t path_len;
721
  char* memory;
722
  size_t mem_size;
723
40
  RETURN_IF_BAD_ARG_COUNT(args, 3);
724
200
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
725
200
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, path_ptr);
726
200
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_len);
727

80
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
728
40
  Debug(wasi, "fd_prestat_dir_name(%d, %d, %d)\n", fd, path_ptr, path_len);
729
40
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
730
40
  CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len);
731
40
  uvwasi_errno_t err = uvwasi_fd_prestat_dir_name(&wasi->uvw_,
732
                                                  fd,
733
                                                  &memory[path_ptr],
734
40
                                                  path_len);
735
120
  args.GetReturnValue().Set(err);
736
}
737
738
739
void WASI::FdPwrite(const FunctionCallbackInfo<Value>& args) {
740
  WASI* wasi;
741
  uint32_t fd;
742
  uint32_t iovs_ptr;
743
  uint32_t iovs_len;
744
  uint64_t offset;
745
  uint32_t nwritten_ptr;
746
  char* memory;
747
  size_t mem_size;
748
  RETURN_IF_BAD_ARG_COUNT(args, 5);
749
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
750
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, iovs_ptr);
751
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, iovs_len);
752
  UNWRAP_BIGINT_OR_RETURN(args, args[3], Uint64, offset);
753
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, nwritten_ptr);
754
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
755
  Debug(wasi,
756
        "uvwasi_fd_pwrite(%d, %d, %d, %d, %d)\n",
757
        fd,
758
        iovs_ptr,
759
        iovs_len,
760
        offset,
761
        nwritten_ptr);
762
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
763
  CHECK_BOUNDS_OR_RETURN(args,
764
                         mem_size,
765
                         iovs_ptr,
766
                         iovs_len * UVWASI_SERDES_SIZE_ciovec_t);
767
  CHECK_BOUNDS_OR_RETURN(args,
768
                         mem_size,
769
                         nwritten_ptr,
770
                         UVWASI_SERDES_SIZE_size_t);
771
  std::vector<uvwasi_ciovec_t> iovs(iovs_len);
772
  uvwasi_errno_t err;
773
774
  err = uvwasi_serdes_readv_ciovec_t(memory,
775
                                     mem_size,
776
                                     iovs_ptr,
777
                                     iovs.data(),
778
                                     iovs_len);
779
  if (err != UVWASI_ESUCCESS) {
780
    args.GetReturnValue().Set(err);
781
    return;
782
  }
783
784
  uvwasi_size_t nwritten;
785
  err = uvwasi_fd_pwrite(&wasi->uvw_,
786
                         fd,
787
                         iovs.data(),
788
                         iovs_len,
789
                         offset,
790
                         &nwritten);
791
  if (err == UVWASI_ESUCCESS)
792
    uvwasi_serdes_write_size_t(memory, nwritten_ptr, nwritten);
793
794
  args.GetReturnValue().Set(err);
795
}
796
797
798
15
void WASI::FdRead(const FunctionCallbackInfo<Value>& args) {
799
  WASI* wasi;
800
  uint32_t fd;
801
  uint32_t iovs_ptr;
802
  uint32_t iovs_len;
803
  uint32_t nread_ptr;
804
  char* memory;
805
  size_t mem_size;
806
15
  RETURN_IF_BAD_ARG_COUNT(args, 4);
807
75
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
808
75
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, iovs_ptr);
809
75
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, iovs_len);
810
75
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, nread_ptr);
811

30
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
812
15
  Debug(wasi, "fd_read(%d, %d, %d, %d)\n", fd, iovs_ptr, iovs_len, nread_ptr);
813
15
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
814
15
  CHECK_BOUNDS_OR_RETURN(args,
815
                         mem_size,
816
                         iovs_ptr,
817
                         iovs_len * UVWASI_SERDES_SIZE_iovec_t);
818
15
  CHECK_BOUNDS_OR_RETURN(args, mem_size, nread_ptr, UVWASI_SERDES_SIZE_size_t);
819
30
  std::vector<uvwasi_iovec_t> iovs(iovs_len);
820
  uvwasi_errno_t err;
821
822
15
  err = uvwasi_serdes_readv_iovec_t(memory,
823
                                    mem_size,
824
                                    iovs_ptr,
825
                                    iovs.data(),
826
15
                                    iovs_len);
827
15
  if (err != UVWASI_ESUCCESS) {
828
    args.GetReturnValue().Set(err);
829
    return;
830
  }
831
832
  uvwasi_size_t nread;
833
15
  err = uvwasi_fd_read(&wasi->uvw_, fd, iovs.data(), iovs_len, &nread);
834
15
  if (err == UVWASI_ESUCCESS)
835
15
    uvwasi_serdes_write_size_t(memory, nread_ptr, nread);
836
837
45
  args.GetReturnValue().Set(err);
838
}
839
840
841
void WASI::FdReaddir(const FunctionCallbackInfo<Value>& args) {
842
  WASI* wasi;
843
  uint32_t fd;
844
  uint32_t buf_ptr;
845
  uint32_t buf_len;
846
  uint64_t cookie;
847
  uint32_t bufused_ptr;
848
  char* memory;
849
  size_t mem_size;
850
  RETURN_IF_BAD_ARG_COUNT(args, 5);
851
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
852
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, buf_ptr);
853
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, buf_len);
854
  UNWRAP_BIGINT_OR_RETURN(args, args[3], Uint64, cookie);
855
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, bufused_ptr);
856
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
857
  Debug(wasi,
858
        "uvwasi_fd_readdir(%d, %d, %d, %d, %d)\n",
859
        fd,
860
        buf_ptr,
861
        buf_len,
862
        cookie,
863
        bufused_ptr);
864
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
865
  CHECK_BOUNDS_OR_RETURN(args, mem_size, buf_ptr, buf_len);
866
  CHECK_BOUNDS_OR_RETURN(args,
867
                         mem_size,
868
                         bufused_ptr,
869
                         UVWASI_SERDES_SIZE_size_t);
870
  uvwasi_size_t bufused;
871
  uvwasi_errno_t err = uvwasi_fd_readdir(&wasi->uvw_,
872
                                         fd,
873
                                         &memory[buf_ptr],
874
                                         buf_len,
875
                                         cookie,
876
                                         &bufused);
877
  if (err == UVWASI_ESUCCESS)
878
    uvwasi_serdes_write_size_t(memory, bufused_ptr, bufused);
879
880
  args.GetReturnValue().Set(err);
881
}
882
883
884
1
void WASI::FdRenumber(const FunctionCallbackInfo<Value>& args) {
885
  WASI* wasi;
886
  uint32_t from;
887
  uint32_t to;
888
1
  RETURN_IF_BAD_ARG_COUNT(args, 2);
889
5
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, from);
890
5
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, to);
891

2
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
892
1
  Debug(wasi, "fd_renumber(%d, %d)\n", from, to);
893
1
  uvwasi_errno_t err = uvwasi_fd_renumber(&wasi->uvw_, from, to);
894
3
  args.GetReturnValue().Set(err);
895
}
896
897
898
2
void WASI::FdSeek(const FunctionCallbackInfo<Value>& args) {
899
  WASI* wasi;
900
  uint32_t fd;
901
  int64_t offset;
902
  uint8_t whence;
903
  uint32_t newoffset_ptr;
904
  char* memory;
905
  size_t mem_size;
906
2
  RETURN_IF_BAD_ARG_COUNT(args, 4);
907
10
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
908
10
  UNWRAP_BIGINT_OR_RETURN(args, args[1], Int64, offset);
909
10
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, whence);
910
10
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, newoffset_ptr);
911

4
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
912
2
  Debug(wasi, "fd_seek(%d, %d, %d, %d)\n", fd, offset, whence, newoffset_ptr);
913
2
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
914
2
  CHECK_BOUNDS_OR_RETURN(args,
915
                         mem_size,
916
                         newoffset_ptr,
917
                         UVWASI_SERDES_SIZE_filesize_t);
918
  uvwasi_filesize_t newoffset;
919
2
  uvwasi_errno_t err = uvwasi_fd_seek(&wasi->uvw_,
920
                                      fd,
921
                                      offset,
922
                                      whence,
923
2
                                      &newoffset);
924
2
  if (err == UVWASI_ESUCCESS)
925
2
    uvwasi_serdes_write_filesize_t(memory, newoffset_ptr, newoffset);
926
927
6
  args.GetReturnValue().Set(err);
928
}
929
930
931
void WASI::FdSync(const FunctionCallbackInfo<Value>& args) {
932
  WASI* wasi;
933
  uint32_t fd;
934
  RETURN_IF_BAD_ARG_COUNT(args, 1);
935
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
936
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
937
  Debug(wasi, "fd_sync(%d)\n", fd);
938
  uvwasi_errno_t err = uvwasi_fd_sync(&wasi->uvw_, fd);
939
  args.GetReturnValue().Set(err);
940
}
941
942
943
void WASI::FdTell(const FunctionCallbackInfo<Value>& args) {
944
  WASI* wasi;
945
  uint32_t fd;
946
  uint32_t offset_ptr;
947
  char* memory;
948
  size_t mem_size;
949
  RETURN_IF_BAD_ARG_COUNT(args, 2);
950
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
951
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, offset_ptr);
952
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
953
  Debug(wasi, "fd_tell(%d, %d)\n", fd, offset_ptr);
954
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
955
  CHECK_BOUNDS_OR_RETURN(args,
956
                         mem_size,
957
                         offset_ptr,
958
                         UVWASI_SERDES_SIZE_filesize_t);
959
  uvwasi_filesize_t offset;
960
  uvwasi_errno_t err = uvwasi_fd_tell(&wasi->uvw_, fd, &offset);
961
962
  if (err == UVWASI_ESUCCESS)
963
    uvwasi_serdes_write_filesize_t(memory, offset_ptr, offset);
964
965
  args.GetReturnValue().Set(err);
966
}
967
968
969
10
void WASI::FdWrite(const FunctionCallbackInfo<Value>& args) {
970
  WASI* wasi;
971
  uint32_t fd;
972
  uint32_t iovs_ptr;
973
  uint32_t iovs_len;
974
  uint32_t nwritten_ptr;
975
  char* memory;
976
  size_t mem_size;
977
10
  RETURN_IF_BAD_ARG_COUNT(args, 4);
978
50
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
979
50
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, iovs_ptr);
980
50
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, iovs_len);
981
50
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, nwritten_ptr);
982

20
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
983
  Debug(wasi,
984
        "fd_write(%d, %d, %d, %d)\n",
985
        fd,
986
        iovs_ptr,
987
        iovs_len,
988
10
        nwritten_ptr);
989
10
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
990
10
  CHECK_BOUNDS_OR_RETURN(args,
991
                         mem_size,
992
                         iovs_ptr,
993
                         iovs_len * UVWASI_SERDES_SIZE_ciovec_t);
994
10
  CHECK_BOUNDS_OR_RETURN(args,
995
                         mem_size,
996
                         nwritten_ptr,
997
                         UVWASI_SERDES_SIZE_size_t);
998
20
  std::vector<uvwasi_ciovec_t> iovs(iovs_len);
999
  uvwasi_errno_t err;
1000
1001
10
  err = uvwasi_serdes_readv_ciovec_t(memory,
1002
                                     mem_size,
1003
                                     iovs_ptr,
1004
                                     iovs.data(),
1005
10
                                     iovs_len);
1006
10
  if (err != UVWASI_ESUCCESS) {
1007
    args.GetReturnValue().Set(err);
1008
    return;
1009
  }
1010
1011
  uvwasi_size_t nwritten;
1012
10
  err = uvwasi_fd_write(&wasi->uvw_, fd, iovs.data(), iovs_len, &nwritten);
1013
10
  if (err == UVWASI_ESUCCESS)
1014
10
    uvwasi_serdes_write_size_t(memory, nwritten_ptr, nwritten);
1015
1016
30
  args.GetReturnValue().Set(err);
1017
}
1018
1019
1020
1
void WASI::PathCreateDirectory(const FunctionCallbackInfo<Value>& args) {
1021
  WASI* wasi;
1022
  uint32_t fd;
1023
  uint32_t path_ptr;
1024
  uint32_t path_len;
1025
  char* memory;
1026
  size_t mem_size;
1027
1
  RETURN_IF_BAD_ARG_COUNT(args, 3);
1028
5
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
1029
5
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, path_ptr);
1030
5
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_len);
1031

2
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
1032
1
  Debug(wasi, "path_create_directory(%d, %d, %d)\n", fd, path_ptr, path_len);
1033
1
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1034
1
  CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len);
1035
2
  uvwasi_errno_t err = uvwasi_path_create_directory(&wasi->uvw_,
1036
                                                    fd,
1037
1
                                                    &memory[path_ptr],
1038
1
                                                    path_len);
1039
3
  args.GetReturnValue().Set(err);
1040
}
1041
1042
1043
7
void WASI::PathFilestatGet(const FunctionCallbackInfo<Value>& args) {
1044
  WASI* wasi;
1045
  uint32_t fd;
1046
  uint32_t flags;
1047
  uint32_t path_ptr;
1048
  uint32_t path_len;
1049
  uint32_t buf_ptr;
1050
  char* memory;
1051
  size_t mem_size;
1052
7
  RETURN_IF_BAD_ARG_COUNT(args, 5);
1053
35
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
1054
35
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, flags);
1055
35
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_ptr);
1056
35
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, path_len);
1057
35
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, buf_ptr);
1058

14
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
1059
  Debug(wasi,
1060
        "path_filestat_get(%d, %d, %d)\n",
1061
        fd,
1062
        path_ptr,
1063
7
        path_len);
1064
7
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1065
7
  CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len);
1066
7
  CHECK_BOUNDS_OR_RETURN(args,
1067
                         mem_size,
1068
                         buf_ptr,
1069
                         UVWASI_SERDES_SIZE_filestat_t);
1070
  uvwasi_filestat_t stats;
1071
14
  uvwasi_errno_t err = uvwasi_path_filestat_get(&wasi->uvw_,
1072
                                                fd,
1073
                                                flags,
1074
7
                                                &memory[path_ptr],
1075
                                                path_len,
1076
7
                                                &stats);
1077
7
  if (err == UVWASI_ESUCCESS)
1078
5
    uvwasi_serdes_write_filestat_t(memory, buf_ptr, &stats);
1079
1080
21
  args.GetReturnValue().Set(err);
1081
}
1082
1083
1084
void WASI::PathFilestatSetTimes(const FunctionCallbackInfo<Value>& args) {
1085
  WASI* wasi;
1086
  uint32_t fd;
1087
  uint32_t flags;
1088
  uint32_t path_ptr;
1089
  uint32_t path_len;
1090
  uint64_t st_atim;
1091
  uint64_t st_mtim;
1092
  uint16_t fst_flags;
1093
  char* memory;
1094
  size_t mem_size;
1095
  RETURN_IF_BAD_ARG_COUNT(args, 7);
1096
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
1097
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, flags);
1098
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_ptr);
1099
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, path_len);
1100
  UNWRAP_BIGINT_OR_RETURN(args, args[4], Uint64, st_atim);
1101
  UNWRAP_BIGINT_OR_RETURN(args, args[5], Uint64, st_mtim);
1102
  CHECK_TO_TYPE_OR_RETURN(args, args[6], Uint32, fst_flags);
1103
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
1104
  Debug(wasi,
1105
        "path_filestat_set_times(%d, %d, %d, %d, %d, %d, %d)\n",
1106
        fd,
1107
        flags,
1108
        path_ptr,
1109
        path_len,
1110
        st_atim,
1111
        st_mtim,
1112
        fst_flags);
1113
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1114
  CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len);
1115
  uvwasi_errno_t err = uvwasi_path_filestat_set_times(&wasi->uvw_,
1116
                                                      fd,
1117
                                                      flags,
1118
                                                      &memory[path_ptr],
1119
                                                      path_len,
1120
                                                      st_atim,
1121
                                                      st_mtim,
1122
                                                      fst_flags);
1123
  args.GetReturnValue().Set(err);
1124
}
1125
1126
1127
1
void WASI::PathLink(const FunctionCallbackInfo<Value>& args) {
1128
  WASI* wasi;
1129
  uint32_t old_fd;
1130
  uint32_t old_flags;
1131
  uint32_t old_path_ptr;
1132
  uint32_t old_path_len;
1133
  uint32_t new_fd;
1134
  uint32_t new_path_ptr;
1135
  uint32_t new_path_len;
1136
  char* memory;
1137
  size_t mem_size;
1138
1
  RETURN_IF_BAD_ARG_COUNT(args, 7);
1139
5
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, old_fd);
1140
5
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, old_flags);
1141
5
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, old_path_ptr);
1142
5
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, old_path_len);
1143
5
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, new_fd);
1144
5
  CHECK_TO_TYPE_OR_RETURN(args, args[5], Uint32, new_path_ptr);
1145
5
  CHECK_TO_TYPE_OR_RETURN(args, args[6], Uint32, new_path_len);
1146

2
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
1147
  Debug(wasi,
1148
        "path_link(%d, %d, %d, %d, %d, %d, %d)\n",
1149
        old_fd,
1150
        old_flags,
1151
        old_path_ptr,
1152
        old_path_len,
1153
        new_fd,
1154
        new_path_ptr,
1155
1
        new_path_len);
1156
1
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1157
1
  CHECK_BOUNDS_OR_RETURN(args, mem_size, old_path_ptr, old_path_len);
1158
1
  CHECK_BOUNDS_OR_RETURN(args, mem_size, new_path_ptr, new_path_len);
1159
3
  uvwasi_errno_t err = uvwasi_path_link(&wasi->uvw_,
1160
                                        old_fd,
1161
                                        old_flags,
1162
1
                                        &memory[old_path_ptr],
1163
                                        old_path_len,
1164
                                        new_fd,
1165
1
                                        &memory[new_path_ptr],
1166
1
                                        new_path_len);
1167
3
  args.GetReturnValue().Set(err);
1168
}
1169
1170
1171
13
void WASI::PathOpen(const FunctionCallbackInfo<Value>& args) {
1172
  WASI* wasi;
1173
  uint32_t dirfd;
1174
  uint32_t dirflags;
1175
  uint32_t path_ptr;
1176
  uint32_t path_len;
1177
  uint32_t o_flags;
1178
  uint64_t fs_rights_base;
1179
  uint64_t fs_rights_inheriting;
1180
  uint32_t fs_flags;
1181
  uint32_t fd_ptr;
1182
  char* memory;
1183
  size_t mem_size;
1184
13
  RETURN_IF_BAD_ARG_COUNT(args, 9);
1185
65
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, dirfd);
1186
65
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, dirflags);
1187
65
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_ptr);
1188
65
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, path_len);
1189
65
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, o_flags);
1190
65
  UNWRAP_BIGINT_OR_RETURN(args, args[5], Uint64, fs_rights_base);
1191
65
  UNWRAP_BIGINT_OR_RETURN(args, args[6], Uint64, fs_rights_inheriting);
1192
65
  CHECK_TO_TYPE_OR_RETURN(args, args[7], Uint32, fs_flags);
1193
65
  CHECK_TO_TYPE_OR_RETURN(args, args[8], Uint32, fd_ptr);
1194

26
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
1195
  Debug(wasi,
1196
        "path_open(%d, %d, %d, %d, %d, %d, %d, %d, %d)\n",
1197
        dirfd,
1198
        dirflags,
1199
        path_ptr,
1200
        path_len,
1201
        o_flags,
1202
        fs_rights_base,
1203
        fs_rights_inheriting,
1204
        fs_flags,
1205
13
        fd_ptr);
1206
13
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1207
13
  CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len);
1208
13
  CHECK_BOUNDS_OR_RETURN(args, mem_size, fd_ptr, UVWASI_SERDES_SIZE_fd_t);
1209
  uvwasi_fd_t fd;
1210
26
  uvwasi_errno_t err = uvwasi_path_open(&wasi->uvw_,
1211
                                        dirfd,
1212
                                        dirflags,
1213
13
                                        &memory[path_ptr],
1214
                                        path_len,
1215
                                        static_cast<uvwasi_oflags_t>(o_flags),
1216
                                        fs_rights_base,
1217
                                        fs_rights_inheriting,
1218
                                        static_cast<uvwasi_fdflags_t>(fs_flags),
1219
13
                                        &fd);
1220
13
  if (err == UVWASI_ESUCCESS)
1221
9
    uvwasi_serdes_write_size_t(memory, fd_ptr, fd);
1222
1223
39
  args.GetReturnValue().Set(err);
1224
}
1225
1226
1227
1
void WASI::PathReadlink(const FunctionCallbackInfo<Value>& args) {
1228
  WASI* wasi;
1229
  uint32_t fd;
1230
  uint32_t path_ptr;
1231
  uint32_t path_len;
1232
  uint32_t buf_ptr;
1233
  uint32_t buf_len;
1234
  uint32_t bufused_ptr;
1235
  char* memory;
1236
  size_t mem_size;
1237
1
  RETURN_IF_BAD_ARG_COUNT(args, 6);
1238
5
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
1239
5
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, path_ptr);
1240
5
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_len);
1241
5
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, buf_ptr);
1242
5
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, buf_len);
1243
5
  CHECK_TO_TYPE_OR_RETURN(args, args[5], Uint32, bufused_ptr);
1244

2
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
1245
  Debug(wasi,
1246
        "path_readlink(%d, %d, %d, %d, %d, %d)\n",
1247
        fd,
1248
        path_ptr,
1249
        path_len,
1250
        buf_ptr,
1251
        buf_len,
1252
1
        bufused_ptr);
1253
1
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1254
1
  CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len);
1255
1
  CHECK_BOUNDS_OR_RETURN(args, mem_size, buf_ptr, buf_len);
1256
1
  CHECK_BOUNDS_OR_RETURN(args,
1257
                         mem_size,
1258
                         bufused_ptr,
1259
                         UVWASI_SERDES_SIZE_size_t);
1260
  uvwasi_size_t bufused;
1261
2
  uvwasi_errno_t err = uvwasi_path_readlink(&wasi->uvw_,
1262
                                            fd,
1263
1
                                            &memory[path_ptr],
1264
                                            path_len,
1265
                                            &memory[buf_ptr],
1266
                                            buf_len,
1267
1
                                            &bufused);
1268
1
  if (err == UVWASI_ESUCCESS)
1269
1
    uvwasi_serdes_write_size_t(memory, bufused_ptr, bufused);
1270
1271
3
  args.GetReturnValue().Set(err);
1272
}
1273
1274
1275
1
void WASI::PathRemoveDirectory(const FunctionCallbackInfo<Value>& args) {
1276
  WASI* wasi;
1277
  uint32_t fd;
1278
  uint32_t path_ptr;
1279
  uint32_t path_len;
1280
  char* memory;
1281
  size_t mem_size;
1282
1
  RETURN_IF_BAD_ARG_COUNT(args, 3);
1283
5
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
1284
5
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, path_ptr);
1285
5
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_len);
1286

2
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
1287
1
  Debug(wasi, "path_remove_directory(%d, %d, %d)\n", fd, path_ptr, path_len);
1288
1
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1289
1
  CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len);
1290
2
  uvwasi_errno_t err = uvwasi_path_remove_directory(&wasi->uvw_,
1291
                                                    fd,
1292
1
                                                    &memory[path_ptr],
1293
1
                                                    path_len);
1294
3
  args.GetReturnValue().Set(err);
1295
}
1296
1297
1298
void WASI::PathRename(const FunctionCallbackInfo<Value>& args) {
1299
  WASI* wasi;
1300
  uint32_t old_fd;
1301
  uint32_t old_path_ptr;
1302
  uint32_t old_path_len;
1303
  uint32_t new_fd;
1304
  uint32_t new_path_ptr;
1305
  uint32_t new_path_len;
1306
  char* memory;
1307
  size_t mem_size;
1308
  RETURN_IF_BAD_ARG_COUNT(args, 6);
1309
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, old_fd);
1310
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, old_path_ptr);
1311
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, old_path_len);
1312
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, new_fd);
1313
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, new_path_ptr);
1314
  CHECK_TO_TYPE_OR_RETURN(args, args[5], Uint32, new_path_len);
1315
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
1316
  Debug(wasi,
1317
        "path_rename(%d, %d, %d, %d, %d, %d)\n",
1318
        old_fd,
1319
        old_path_ptr,
1320
        old_path_len,
1321
        new_fd,
1322
        new_path_ptr,
1323
        new_path_len);
1324
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1325
  CHECK_BOUNDS_OR_RETURN(args, mem_size, old_path_ptr, old_path_len);
1326
  CHECK_BOUNDS_OR_RETURN(args, mem_size, new_path_ptr, new_path_len);
1327
  uvwasi_errno_t err = uvwasi_path_rename(&wasi->uvw_,
1328
                                          old_fd,
1329
                                          &memory[old_path_ptr],
1330
                                          old_path_len,
1331
                                          new_fd,
1332
                                          &memory[new_path_ptr],
1333
                                          new_path_len);
1334
  args.GetReturnValue().Set(err);
1335
}
1336
1337
1338
1
void WASI::PathSymlink(const FunctionCallbackInfo<Value>& args) {
1339
  WASI* wasi;
1340
  uint32_t old_path_ptr;
1341
  uint32_t old_path_len;
1342
  uint32_t fd;
1343
  uint32_t new_path_ptr;
1344
  uint32_t new_path_len;
1345
  char* memory;
1346
  size_t mem_size;
1347
1
  RETURN_IF_BAD_ARG_COUNT(args, 5);
1348
5
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, old_path_ptr);
1349
5
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, old_path_len);
1350
5
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, fd);
1351
5
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, new_path_ptr);
1352
5
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, new_path_len);
1353

2
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
1354
  Debug(wasi,
1355
        "path_symlink(%d, %d, %d, %d, %d)\n",
1356
        old_path_ptr,
1357
        old_path_len,
1358
        fd,
1359
        new_path_ptr,
1360
1
        new_path_len);
1361
1
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1362
1
  CHECK_BOUNDS_OR_RETURN(args, mem_size, old_path_ptr, old_path_len);
1363
1
  CHECK_BOUNDS_OR_RETURN(args, mem_size, new_path_ptr, new_path_len);
1364
3
  uvwasi_errno_t err = uvwasi_path_symlink(&wasi->uvw_,
1365
1
                                           &memory[old_path_ptr],
1366
                                           old_path_len,
1367
                                           fd,
1368
1
                                           &memory[new_path_ptr],
1369
1
                                           new_path_len);
1370
3
  args.GetReturnValue().Set(err);
1371
}
1372
1373
1374
1
void WASI::PathUnlinkFile(const FunctionCallbackInfo<Value>& args) {
1375
  WASI* wasi;
1376
  uint32_t fd;
1377
  uint32_t path_ptr;
1378
  uint32_t path_len;
1379
  char* memory;
1380
  size_t mem_size;
1381
1
  RETURN_IF_BAD_ARG_COUNT(args, 3);
1382
5
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
1383
5
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, path_ptr);
1384
5
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_len);
1385

2
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
1386
1
  Debug(wasi, "path_unlink_file(%d, %d, %d)\n", fd, path_ptr, path_len);
1387
1
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1388
1
  CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len);
1389
2
  uvwasi_errno_t err = uvwasi_path_unlink_file(&wasi->uvw_,
1390
                                               fd,
1391
1
                                               &memory[path_ptr],
1392
1
                                               path_len);
1393
3
  args.GetReturnValue().Set(err);
1394
}
1395
1396
1397
5
void WASI::PollOneoff(const FunctionCallbackInfo<Value>& args) {
1398
  WASI* wasi;
1399
  uint32_t in_ptr;
1400
  uint32_t out_ptr;
1401
  uint32_t nsubscriptions;
1402
  uint32_t nevents_ptr;
1403
  char* memory;
1404
  size_t mem_size;
1405
5
  RETURN_IF_BAD_ARG_COUNT(args, 4);
1406
25
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, in_ptr);
1407
25
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, out_ptr);
1408
25
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, nsubscriptions);
1409
25
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, nevents_ptr);
1410

10
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
1411
  Debug(wasi,
1412
        "poll_oneoff(%d, %d, %d, %d)\n",
1413
        in_ptr,
1414
        out_ptr,
1415
        nsubscriptions,
1416
5
        nevents_ptr);
1417
5
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1418
5
  CHECK_BOUNDS_OR_RETURN(args,
1419
                         mem_size,
1420
                         in_ptr,
1421
                         nsubscriptions * UVWASI_SERDES_SIZE_subscription_t);
1422
5
  CHECK_BOUNDS_OR_RETURN(args,
1423
                         mem_size,
1424
                         out_ptr,
1425
                         nsubscriptions * UVWASI_SERDES_SIZE_event_t);
1426
5
  CHECK_BOUNDS_OR_RETURN(args,
1427
                         mem_size,
1428
                         nevents_ptr,
1429
                         UVWASI_SERDES_SIZE_size_t);
1430
10
  std::vector<uvwasi_subscription_t> in(nsubscriptions);
1431
10
  std::vector<uvwasi_event_t> out(nsubscriptions);
1432
1433
13
  for (uint32_t i = 0; i < nsubscriptions; ++i) {
1434
8
    uvwasi_serdes_read_subscription_t(memory, in_ptr, &in[i]);
1435
8
    in_ptr += UVWASI_SERDES_SIZE_subscription_t;
1436
  }
1437
1438
  uvwasi_size_t nevents;
1439
10
  uvwasi_errno_t err = uvwasi_poll_oneoff(&wasi->uvw_,
1440
5
                                          in.data(),
1441
                                          out.data(),
1442
                                          nsubscriptions,
1443
5
                                          &nevents);
1444
5
  if (err == UVWASI_ESUCCESS) {
1445
5
    uvwasi_serdes_write_size_t(memory, nevents_ptr, nevents);
1446
1447
13
    for (uint32_t i = 0; i < nsubscriptions; ++i) {
1448
8
      uvwasi_serdes_write_event_t(memory, out_ptr, &out[i]);
1449
8
      out_ptr += UVWASI_SERDES_SIZE_event_t;
1450
    }
1451
  }
1452
1453
15
  args.GetReturnValue().Set(err);
1454
}
1455
1456
1457
1
void WASI::ProcExit(const FunctionCallbackInfo<Value>& args) {
1458
  WASI* wasi;
1459
  uint32_t code;
1460
1
  RETURN_IF_BAD_ARG_COUNT(args, 1);
1461
5
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, code);
1462

2
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
1463
1
  Debug(wasi, "proc_exit(%d)\n", code);
1464
1
  args.GetReturnValue().Set(uvwasi_proc_exit(&wasi->uvw_, code));
1465
}
1466
1467
1468
void WASI::ProcRaise(const FunctionCallbackInfo<Value>& args) {
1469
  WASI* wasi;
1470
  uint32_t sig;
1471
  RETURN_IF_BAD_ARG_COUNT(args, 1);
1472
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, sig);
1473
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
1474
  Debug(wasi, "proc_raise(%d)\n", sig);
1475
  uvwasi_errno_t err = uvwasi_proc_raise(&wasi->uvw_, sig);
1476
  args.GetReturnValue().Set(err);
1477
}
1478
1479
1480
1
void WASI::RandomGet(const FunctionCallbackInfo<Value>& args) {
1481
  WASI* wasi;
1482
  uint32_t buf_ptr;
1483
  uint32_t buf_len;
1484
  char* memory;
1485
  size_t mem_size;
1486
1
  RETURN_IF_BAD_ARG_COUNT(args, 2);
1487
5
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, buf_ptr);
1488
5
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, buf_len);
1489

2
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
1490
1
  Debug(wasi, "random_get(%d, %d)\n", buf_ptr, buf_len);
1491
1
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1492
1
  CHECK_BOUNDS_OR_RETURN(args, mem_size, buf_ptr, buf_len);
1493
2
  uvwasi_errno_t err = uvwasi_random_get(&wasi->uvw_,
1494
1
                                         &memory[buf_ptr],
1495
1
                                         buf_len);
1496
3
  args.GetReturnValue().Set(err);
1497
}
1498
1499
1500
void WASI::SchedYield(const FunctionCallbackInfo<Value>& args) {
1501
  WASI* wasi;
1502
  RETURN_IF_BAD_ARG_COUNT(args, 0);
1503
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
1504
  Debug(wasi, "sched_yield()\n");
1505
  uvwasi_errno_t err = uvwasi_sched_yield(&wasi->uvw_);
1506
  args.GetReturnValue().Set(err);
1507
}
1508
1509
1510
void WASI::SockRecv(const FunctionCallbackInfo<Value>& args) {
1511
  WASI* wasi;
1512
  uint32_t sock;
1513
  uint32_t ri_data_ptr;
1514
  uint32_t ri_data_len;
1515
  uint16_t ri_flags;
1516
  uint32_t ro_datalen_ptr;
1517
  uint16_t ro_flags_ptr;
1518
  char* memory;
1519
  size_t mem_size;
1520
  RETURN_IF_BAD_ARG_COUNT(args, 6);
1521
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, sock);
1522
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, ri_data_ptr);
1523
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, ri_data_len);
1524
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, ri_flags);
1525
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, ro_datalen_ptr);
1526
  CHECK_TO_TYPE_OR_RETURN(args, args[5], Uint32, ro_flags_ptr);
1527
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
1528
  Debug(wasi,
1529
        "sock_recv(%d, %d, %d, %d, %d, %d)\n",
1530
        sock,
1531
        ri_data_ptr,
1532
        ri_data_len,
1533
        ri_flags,
1534
        ro_datalen_ptr,
1535
        ro_flags_ptr);
1536
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1537
  CHECK_BOUNDS_OR_RETURN(args,
1538
                         mem_size,
1539
                         ri_data_ptr,
1540
                         ri_data_len * UVWASI_SERDES_SIZE_iovec_t);
1541
  CHECK_BOUNDS_OR_RETURN(args, mem_size, ro_datalen_ptr, 4);
1542
  CHECK_BOUNDS_OR_RETURN(args, mem_size, ro_flags_ptr, 4);
1543
  std::vector<uvwasi_iovec_t> ri_data(ri_data_len);
1544
  uvwasi_errno_t err = uvwasi_serdes_readv_iovec_t(memory,
1545
                                                   mem_size,
1546
                                                   ri_data_ptr,
1547
                                                   ri_data.data(),
1548
                                                   ri_data_len);
1549
  if (err != UVWASI_ESUCCESS) {
1550
    args.GetReturnValue().Set(err);
1551
    return;
1552
  }
1553
1554
  uvwasi_size_t ro_datalen;
1555
  uvwasi_roflags_t ro_flags;
1556
  err = uvwasi_sock_recv(&wasi->uvw_,
1557
                         sock,
1558
                         ri_data.data(),
1559
                         ri_data_len,
1560
                         ri_flags,
1561
                         &ro_datalen,
1562
                         &ro_flags);
1563
  if (err == UVWASI_ESUCCESS) {
1564
    uvwasi_serdes_write_size_t(memory, ro_datalen_ptr, ro_datalen);
1565
    uvwasi_serdes_write_roflags_t(memory, ro_flags_ptr, ro_flags);
1566
  }
1567
1568
  args.GetReturnValue().Set(err);
1569
}
1570
1571
1572
void WASI::SockSend(const FunctionCallbackInfo<Value>& args) {
1573
  WASI* wasi;
1574
  uint32_t sock;
1575
  uint32_t si_data_ptr;
1576
  uint32_t si_data_len;
1577
  uint16_t si_flags;
1578
  uint32_t so_datalen_ptr;
1579
  char* memory;
1580
  size_t mem_size;
1581
  RETURN_IF_BAD_ARG_COUNT(args, 5);
1582
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, sock);
1583
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, si_data_ptr);
1584
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, si_data_len);
1585
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, si_flags);
1586
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, so_datalen_ptr);
1587
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
1588
  Debug(wasi,
1589
        "sock_send(%d, %d, %d, %d, %d)\n",
1590
        sock,
1591
        si_data_ptr,
1592
        si_data_len,
1593
        si_flags,
1594
        so_datalen_ptr);
1595
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1596
  CHECK_BOUNDS_OR_RETURN(args,
1597
                         mem_size,
1598
                         si_data_ptr,
1599
                         si_data_len * UVWASI_SERDES_SIZE_ciovec_t);
1600
  CHECK_BOUNDS_OR_RETURN(args,
1601
                         mem_size,
1602
                         so_datalen_ptr,
1603
                         UVWASI_SERDES_SIZE_size_t);
1604
  std::vector<uvwasi_ciovec_t> si_data(si_data_len);
1605
  uvwasi_errno_t err = uvwasi_serdes_readv_ciovec_t(memory,
1606
                                                    mem_size,
1607
                                                    si_data_ptr,
1608
                                                    si_data.data(),
1609
                                                    si_data_len);
1610
  if (err != UVWASI_ESUCCESS) {
1611
    args.GetReturnValue().Set(err);
1612
    return;
1613
  }
1614
1615
  uvwasi_size_t so_datalen;
1616
  err = uvwasi_sock_send(&wasi->uvw_,
1617
                         sock,
1618
                         si_data.data(),
1619
                         si_data_len,
1620
                         si_flags,
1621
                         &so_datalen);
1622
  if (err == UVWASI_ESUCCESS)
1623
    uvwasi_serdes_write_size_t(memory, so_datalen_ptr, so_datalen);
1624
1625
  args.GetReturnValue().Set(err);
1626
}
1627
1628
1629
void WASI::SockShutdown(const FunctionCallbackInfo<Value>& args) {
1630
  WASI* wasi;
1631
  uint32_t sock;
1632
  uint8_t how;
1633
  RETURN_IF_BAD_ARG_COUNT(args, 2);
1634
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, sock);
1635
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, how);
1636
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
1637
  Debug(wasi, "sock_shutdown(%d, %d)\n", sock, how);
1638
  uvwasi_errno_t err = uvwasi_sock_shutdown(&wasi->uvw_, sock, how);
1639
  args.GetReturnValue().Set(err);
1640
}
1641
1642
1643
29
void WASI::_SetMemory(const FunctionCallbackInfo<Value>& args) {
1644
  WASI* wasi;
1645
29
  CHECK_EQ(args.Length(), 1);
1646
58
  CHECK(args[0]->IsObject());
1647
29
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
1648
87
  wasi->memory_.Reset(wasi->env()->isolate(), args[0].As<Object>());
1649
}
1650
1651
1652
250
uvwasi_errno_t WASI::backingStore(char** store, size_t* byte_length) {
1653
250
  Environment* env = this->env();
1654
250
  Local<Object> memory = PersistentToLocal::Strong(this->memory_);
1655
  Local<Value> prop;
1656
1657
1000
  if (!memory->Get(env->context(), env->buffer_string()).ToLocal(&prop))
1658
    return UVWASI_EINVAL;
1659
1660
250
  if (!prop->IsArrayBuffer())
1661
    return UVWASI_EINVAL;
1662
1663
250
  Local<ArrayBuffer> ab = prop.As<ArrayBuffer>();
1664
500
  std::shared_ptr<BackingStore> backing_store = ab->GetBackingStore();
1665
250
  *byte_length = backing_store->ByteLength();
1666
250
  *store = static_cast<char*>(backing_store->Data());
1667
250
  CHECK_NOT_NULL(*store);
1668
250
  return UVWASI_ESUCCESS;
1669
}
1670
1671
1672
29
static void Initialize(Local<Object> target,
1673
                       Local<Value> unused,
1674
                       Local<Context> context,
1675
                       void* priv) {
1676
29
  Environment* env = Environment::GetCurrent(context);
1677
1678
29
  Local<FunctionTemplate> tmpl = env->NewFunctionTemplate(WASI::New);
1679
29
  auto wasi_wrap_string = FIXED_ONE_BYTE_STRING(env->isolate(), "WASI");
1680
58
  tmpl->InstanceTemplate()->SetInternalFieldCount(WASI::kInternalFieldCount);
1681
29
  tmpl->SetClassName(wasi_wrap_string);
1682
58
  tmpl->Inherit(BaseObject::GetConstructorTemplate(env));
1683
1684
29
  env->SetProtoMethod(tmpl, "args_get", WASI::ArgsGet);
1685
29
  env->SetProtoMethod(tmpl, "args_sizes_get", WASI::ArgsSizesGet);
1686
29
  env->SetProtoMethod(tmpl, "clock_res_get", WASI::ClockResGet);
1687
29
  env->SetProtoMethod(tmpl, "clock_time_get", WASI::ClockTimeGet);
1688
29
  env->SetProtoMethod(tmpl, "environ_get", WASI::EnvironGet);
1689
29
  env->SetProtoMethod(tmpl, "environ_sizes_get", WASI::EnvironSizesGet);
1690
29
  env->SetProtoMethod(tmpl, "fd_advise", WASI::FdAdvise);
1691
29
  env->SetProtoMethod(tmpl, "fd_allocate", WASI::FdAllocate);
1692
29
  env->SetProtoMethod(tmpl, "fd_close", WASI::FdClose);
1693
29
  env->SetProtoMethod(tmpl, "fd_datasync", WASI::FdDatasync);
1694
29
  env->SetProtoMethod(tmpl, "fd_fdstat_get", WASI::FdFdstatGet);
1695
29
  env->SetProtoMethod(tmpl, "fd_fdstat_set_flags", WASI::FdFdstatSetFlags);
1696
29
  env->SetProtoMethod(tmpl, "fd_fdstat_set_rights", WASI::FdFdstatSetRights);
1697
29
  env->SetProtoMethod(tmpl, "fd_filestat_get", WASI::FdFilestatGet);
1698
29
  env->SetProtoMethod(tmpl, "fd_filestat_set_size", WASI::FdFilestatSetSize);
1699
29
  env->SetProtoMethod(tmpl, "fd_filestat_set_times", WASI::FdFilestatSetTimes);
1700
29
  env->SetProtoMethod(tmpl, "fd_pread", WASI::FdPread);
1701
29
  env->SetProtoMethod(tmpl, "fd_prestat_get", WASI::FdPrestatGet);
1702
29
  env->SetProtoMethod(tmpl, "fd_prestat_dir_name", WASI::FdPrestatDirName);
1703
29
  env->SetProtoMethod(tmpl, "fd_pwrite", WASI::FdPwrite);
1704
29
  env->SetProtoMethod(tmpl, "fd_read", WASI::FdRead);
1705
29
  env->SetProtoMethod(tmpl, "fd_readdir", WASI::FdReaddir);
1706
29
  env->SetProtoMethod(tmpl, "fd_renumber", WASI::FdRenumber);
1707
29
  env->SetProtoMethod(tmpl, "fd_seek", WASI::FdSeek);
1708
29
  env->SetProtoMethod(tmpl, "fd_sync", WASI::FdSync);
1709
29
  env->SetProtoMethod(tmpl, "fd_tell", WASI::FdTell);
1710
29
  env->SetProtoMethod(tmpl, "fd_write", WASI::FdWrite);
1711
29
  env->SetProtoMethod(tmpl, "path_create_directory", WASI::PathCreateDirectory);
1712
29
  env->SetProtoMethod(tmpl, "path_filestat_get", WASI::PathFilestatGet);
1713
  env->SetProtoMethod(tmpl,
1714
                      "path_filestat_set_times",
1715
29
                      WASI::PathFilestatSetTimes);
1716
29
  env->SetProtoMethod(tmpl, "path_link", WASI::PathLink);
1717
29
  env->SetProtoMethod(tmpl, "path_open", WASI::PathOpen);
1718
29
  env->SetProtoMethod(tmpl, "path_readlink", WASI::PathReadlink);
1719
29
  env->SetProtoMethod(tmpl, "path_remove_directory", WASI::PathRemoveDirectory);
1720
29
  env->SetProtoMethod(tmpl, "path_rename", WASI::PathRename);
1721
29
  env->SetProtoMethod(tmpl, "path_symlink", WASI::PathSymlink);
1722
29
  env->SetProtoMethod(tmpl, "path_unlink_file", WASI::PathUnlinkFile);
1723
29
  env->SetProtoMethod(tmpl, "poll_oneoff", WASI::PollOneoff);
1724
29
  env->SetProtoMethod(tmpl, "proc_exit", WASI::ProcExit);
1725
29
  env->SetProtoMethod(tmpl, "proc_raise", WASI::ProcRaise);
1726
29
  env->SetProtoMethod(tmpl, "random_get", WASI::RandomGet);
1727
29
  env->SetProtoMethod(tmpl, "sched_yield", WASI::SchedYield);
1728
29
  env->SetProtoMethod(tmpl, "sock_recv", WASI::SockRecv);
1729
29
  env->SetProtoMethod(tmpl, "sock_send", WASI::SockSend);
1730
29
  env->SetProtoMethod(tmpl, "sock_shutdown", WASI::SockShutdown);
1731
1732
29
  env->SetInstanceMethod(tmpl, "_setMemory", WASI::_SetMemory);
1733
1734
58
  target->Set(env->context(),
1735
              wasi_wrap_string,
1736
116
              tmpl->GetFunction(context).ToLocalChecked()).ToChecked();
1737
29
}
1738
1739
1740
}  // namespace wasi
1741
}  // namespace node
1742
1743
4398
NODE_MODULE_CONTEXT_AWARE_INTERNAL(wasi, node::wasi::Initialize)