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: 572 836 68.4 %
Date: 2020-05-27 22:15:15 Branches: 306 892 34.3 %

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
248
inline void Debug(WASI* wasi, Args&&... args) {
18
248
  Debug(wasi->env(), DebugCategory::WASI, std::forward<Args>(args)...);
19
248
}
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
38
WASI::WASI(Environment* env,
124
           Local<Object> object,
125
76
           uvwasi_options_t* options) : BaseObject(env, object) {
126
38
  MakeWeak();
127
38
  alloc_info_ = MakeAllocator();
128
38
  options->allocator = &alloc_info_;
129
38
  int err = uvwasi_init(&uvw_, options);
130
38
  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
148
WASI::~WASI() {
143
37
  uvwasi_destroy(&uvw_);
144
37
  CHECK_EQ(current_uvwasi_memory_, 0);
145
74
}
146
147
void WASI::MemoryInfo(MemoryTracker* tracker) const {
148
  tracker->TrackField("memory", memory_);
149
  tracker->TrackFieldWithSize("uvwasi_memory", current_uvwasi_memory_);
150
}
151
152
1151
void WASI::CheckAllocatedSize(size_t previous_size) const {
153
1151
  CHECK_GE(current_uvwasi_memory_, previous_size);
154
1151
}
155
156
593
void WASI::IncreaseAllocatedSize(size_t size) {
157
593
  current_uvwasi_memory_ += size;
158
593
}
159
160
558
void WASI::DecreaseAllocatedSize(size_t size) {
161
558
  current_uvwasi_memory_ -= size;
162
558
}
163
164
38
void WASI::New(const FunctionCallbackInfo<Value>& args) {
165
38
  CHECK(args.IsConstructCall());
166
38
  CHECK_EQ(args.Length(), 3);
167
76
  CHECK(args[0]->IsArray());
168
76
  CHECK(args[1]->IsArray());
169
76
  CHECK(args[2]->IsArray());
170
171
38
  Environment* env = Environment::GetCurrent(args);
172
38
  Local<Context> context = env->context();
173
76
  Local<Array> argv = args[0].As<Array>();
174
38
  const uint32_t argc = argv->Length();
175
  uvwasi_options_t options;
176
177
38
  options.in = 0;
178
38
  options.out = 1;
179
38
  options.err = 2;
180
38
  options.fd_table_size = 3;
181
38
  options.argc = argc;
182
38
  options.argv =
183
38
    const_cast<const char**>(argc == 0 ? nullptr : new char*[argc]);
184
185
95
  for (uint32_t i = 0; i < argc; i++) {
186
114
    auto arg = argv->Get(context, i).ToLocalChecked();
187
114
    CHECK(arg->IsString());
188
114
    node::Utf8Value str(env->isolate(), arg);
189
57
    options.argv[i] = strdup(*str);
190
57
    CHECK_NOT_NULL(options.argv[i]);
191
  }
192
193
76
  Local<Array> env_pairs = args[1].As<Array>();
194
38
  const uint32_t envc = env_pairs->Length();
195
38
  options.envp = const_cast<const char**>(new char*[envc + 1]);
196
1596
  for (uint32_t i = 0; i < envc; i++) {
197
3116
    auto pair = env_pairs->Get(context, i).ToLocalChecked();
198
3116
    CHECK(pair->IsString());
199
3116
    node::Utf8Value str(env->isolate(), pair);
200
1558
    options.envp[i] = strdup(*str);
201
1558
    CHECK_NOT_NULL(options.envp[i]);
202
  }
203
38
  options.envp[envc] = nullptr;
204
205
76
  Local<Array> preopens = args[2].As<Array>();
206
38
  CHECK_EQ(preopens->Length() % 2, 0);
207
38
  options.preopenc = preopens->Length() / 2;
208
38
  options.preopens = Calloc<uvwasi_preopen_t>(options.preopenc);
209
38
  int index = 0;
210
158
  for (uint32_t i = 0; i < preopens->Length(); i += 2) {
211
82
    auto mapped = preopens->Get(context, i).ToLocalChecked();
212
123
    auto real = preopens->Get(context, i + 1).ToLocalChecked();
213
82
    CHECK(mapped->IsString());
214
82
    CHECK(real->IsString());
215
82
    node::Utf8Value mapped_path(env->isolate(), mapped);
216
82
    node::Utf8Value real_path(env->isolate(), real);
217
41
    options.preopens[index].mapped_path = strdup(*mapped_path);
218
41
    CHECK_NOT_NULL(options.preopens[index].mapped_path);
219
41
    options.preopens[index].real_path = strdup(*real_path);
220
41
    CHECK_NOT_NULL(options.preopens[index].real_path);
221
41
    index++;
222
  }
223
224
38
  new WASI(env, args.This(), &options);
225
226
38
  if (options.argv != nullptr) {
227
76
    for (uint32_t i = 0; i < argc; i++)
228
57
      free(const_cast<char*>(options.argv[i]));
229
19
    delete[] options.argv;
230
  }
231
232
38
  if (options.envp != nullptr) {
233
1596
    for (uint32_t i = 0; options.envp[i]; i++)
234
1558
      free(const_cast<char*>(options.envp[i]));
235
38
    delete[] options.envp;
236
  }
237
238
38
  if (options.preopens != nullptr) {
239
79
    for (uint32_t i = 0; i < options.preopenc; i++) {
240
41
      free(options.preopens[i].mapped_path);
241
41
      free(options.preopens[i].real_path);
242
    }
243
244
38
    free(options.preopens);
245
  }
246
38
}
247
248
249
1
void WASI::ArgsGet(const FunctionCallbackInfo<Value>& args) {
250
  WASI* wasi;
251
  uint32_t argv_offset;
252
  uint32_t argv_buf_offset;
253
  char* memory;
254
  size_t mem_size;
255
1
  RETURN_IF_BAD_ARG_COUNT(args, 2);
256
5
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, argv_offset);
257
5
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, argv_buf_offset);
258

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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