GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: node_wasi.cc Lines: 598 804 74.4 %
Date: 2022-05-22 04:15:48 Branches: 408 1098 37.2 %

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
588
inline void Debug(WASI* wasi, Args&&... args) {
18
588
  Debug(wasi->env(), DebugCategory::WASI, std::forward<Args>(args)...);
19
}
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
  if (!Exception::Error(js_msg)->ToObject(context).ToLocal(&e))
109
    return MaybeLocal<Value>();
110
111
2
  if (e->Set(context,
112
             env->errno_string(),
113
3
             Integer::New(isolate, errorno)).IsNothing() ||
114

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

3
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, argv_offset);
262
3
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, argv_buf_offset);
263

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

3
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, argc_offset);
301
3
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, argv_buf_offset);
302

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

12
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, clock_id);
335
12
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, resolution_ptr);
336

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

24
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, clock_id);
363

24
  UNWRAP_BIGINT_OR_RETURN(args, args[1], Uint64, precision);
364
24
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, time_ptr);
365

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

72
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, environ_offset);
392
72
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, environ_buf_offset);
393

24
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
394
24
  Debug(wasi, "environ_get(%d, %d)\n", environ_offset, environ_buf_offset);
395
24
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
396
24
  CHECK_BOUNDS_OR_RETURN(args,
397
                         mem_size,
398
                         environ_buf_offset,
399
                         wasi->uvw_.env_buf_size);
400
24
  CHECK_BOUNDS_OR_RETURN(args,
401
                         mem_size,
402
                         environ_offset,
403
                         wasi->uvw_.envc * UVWASI_SERDES_SIZE_uint32_t);
404
24
  std::vector<char*> environment(wasi->uvw_.envc);
405
24
  char* environ_buf = &memory[environ_buf_offset];
406
24
  uvwasi_errno_t err = uvwasi_environ_get(&wasi->uvw_,
407
                                          environment.data(),
408
                                          environ_buf);
409
410
24
  if (err == UVWASI_ESUCCESS) {
411
1795
    for (size_t i = 0; i < wasi->uvw_.envc; i++) {
412
      uint32_t offset = static_cast<uint32_t>(
413
1771
          environ_buf_offset + (environment[i] - environment[0]));
414
415
3542
      uvwasi_serdes_write_uint32_t(memory,
416
                                   environ_offset +
417
1771
                                   (i * UVWASI_SERDES_SIZE_uint32_t),
418
                                   offset);
419
    }
420
  }
421
422
48
  args.GetReturnValue().Set(err);
423
}
424
425
426
27
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
27
  RETURN_IF_BAD_ARG_COUNT(args, 2);
433

81
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, envc_offset);
434
81
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, env_buf_offset);
435

27
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
436
27
  Debug(wasi, "environ_sizes_get(%d, %d)\n", envc_offset, env_buf_offset);
437
27
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
438
27
  CHECK_BOUNDS_OR_RETURN(args,
439
                         mem_size,
440
                         envc_offset,
441
                         UVWASI_SERDES_SIZE_size_t);
442
27
  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
27
  uvwasi_errno_t err = uvwasi_environ_sizes_get(&wasi->uvw_,
449
                                                &envc,
450
                                                &env_buf_size);
451
27
  if (err == UVWASI_ESUCCESS) {
452
27
    uvwasi_serdes_write_size_t(memory, envc_offset, envc);
453
27
    uvwasi_serdes_write_size_t(memory, env_buf_offset, env_buf_size);
454
  }
455
456
54
  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
5
void WASI::FdClose(const FunctionCallbackInfo<Value>& args) {
495
  WASI* wasi;
496
  uint32_t fd;
497
6
  RETURN_IF_BAD_ARG_COUNT(args, 1);
498
15
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
499

4
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
500
4
  Debug(wasi, "fd_close(%d)\n", fd);
501
4
  uvwasi_errno_t err = uvwasi_fd_close(&wasi->uvw_, fd);
502
8
  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
26
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
26
  RETURN_IF_BAD_ARG_COUNT(args, 2);
525

78
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
526
78
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, buf);
527

26
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
528
26
  Debug(wasi, "fd_fdstat_get(%d, %d)\n", fd, buf);
529
26
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
530
26
  CHECK_BOUNDS_OR_RETURN(args, mem_size, buf, UVWASI_SERDES_SIZE_fdstat_t);
531
  uvwasi_fdstat_t stats;
532
26
  uvwasi_errno_t err = uvwasi_fd_fdstat_get(&wasi->uvw_, fd, &stats);
533
534
26
  if (err == UVWASI_ESUCCESS)
535
26
    uvwasi_serdes_write_fdstat_t(memory, buf, &stats);
536
537
52
  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
5
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
5
  RETURN_IF_BAD_ARG_COUNT(args, 2);
585

15
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
586
15
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, buf);
587

5
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
588
5
  Debug(wasi, "fd_filestat_get(%d, %d)\n", fd, buf);
589
5
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
590
5
  CHECK_BOUNDS_OR_RETURN(args, mem_size, buf, UVWASI_SERDES_SIZE_filestat_t);
591
  uvwasi_filestat_t stats;
592
5
  uvwasi_errno_t err = uvwasi_fd_filestat_get(&wasi->uvw_, fd, &stats);
593
594
5
  if (err == UVWASI_ESUCCESS)
595
5
    uvwasi_serdes_write_filestat_t(memory, buf, &stats);
596
597
10
  args.GetReturnValue().Set(err);
598
}
599
600
601
2
void WASI::FdFilestatSetSize(const FunctionCallbackInfo<Value>& args) {
602
  WASI* wasi;
603
  uint32_t fd;
604
  uint64_t st_size;
605
2
  RETURN_IF_BAD_ARG_COUNT(args, 2);
606

6
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
607
6
  UNWRAP_BIGINT_OR_RETURN(args, args[1], Uint64, st_size);
608

2
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
609
2
  Debug(wasi, "fd_filestat_set_size(%d, %d)\n", fd, st_size);
610
2
  uvwasi_errno_t err = uvwasi_fd_filestat_set_size(&wasi->uvw_, fd, st_size);
611
4
  args.GetReturnValue().Set(err);
612
}
613
614
615
1
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
1
  RETURN_IF_BAD_ARG_COUNT(args, 4);
622

3
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
623

3
  UNWRAP_BIGINT_OR_RETURN(args, args[1], Uint64, st_atim);
624

3
  UNWRAP_BIGINT_OR_RETURN(args, args[2], Uint64, st_mtim);
625
3
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, fst_flags);
626

1
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
627
1
  Debug(wasi,
628
        "fd_filestat_set_times(%d, %d, %d, %d)\n",
629
        fd,
630
        st_atim,
631
        st_mtim,
632
        fst_flags);
633
1
  uvwasi_errno_t err = uvwasi_fd_filestat_set_times(&wasi->uvw_,
634
                                                    fd,
635
                                                    st_atim,
636
                                                    st_mtim,
637
                                                    fst_flags);
638
2
  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
76
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
77
  RETURN_IF_BAD_ARG_COUNT(args, 2);
700

228
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
701
228
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, buf);
702

76
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
703
75
  Debug(wasi, "fd_prestat_get(%d, %d)\n", fd, buf);
704
75
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
705
75
  CHECK_BOUNDS_OR_RETURN(args, mem_size, buf, UVWASI_SERDES_SIZE_prestat_t);
706
  uvwasi_prestat_t prestat;
707
75
  uvwasi_errno_t err = uvwasi_fd_prestat_get(&wasi->uvw_, fd, &prestat);
708
709
75
  if (err == UVWASI_ESUCCESS)
710
48
    uvwasi_serdes_write_prestat_t(memory, buf, &prestat);
711
712
150
  args.GetReturnValue().Set(err);
713
}
714
715
716
48
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
48
  RETURN_IF_BAD_ARG_COUNT(args, 3);
724

144
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
725

144
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, path_ptr);
726
144
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_len);
727

48
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
728
48
  Debug(wasi, "fd_prestat_dir_name(%d, %d, %d)\n", fd, path_ptr, path_len);
729
48
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
730
48
  CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len);
731
48
  uvwasi_errno_t err = uvwasi_fd_prestat_dir_name(&wasi->uvw_,
732
                                                  fd,
733
                                                  &memory[path_ptr],
734
                                                  path_len);
735
96
  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

45
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
808

45
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, iovs_ptr);
809

45
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, iovs_len);
810
45
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, nread_ptr);
811

15
  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
15
  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
                                    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
30
  args.GetReturnValue().Set(err);
838
}
839
840
841
1
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
1
  RETURN_IF_BAD_ARG_COUNT(args, 5);
851

3
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
852

3
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, buf_ptr);
853

3
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, buf_len);
854

3
  UNWRAP_BIGINT_OR_RETURN(args, args[3], Uint64, cookie);
855
3
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, bufused_ptr);
856

1
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
857
1
  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
1
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
865
1
  CHECK_BOUNDS_OR_RETURN(args, mem_size, buf_ptr, buf_len);
866
1
  CHECK_BOUNDS_OR_RETURN(args,
867
                         mem_size,
868
                         bufused_ptr,
869
                         UVWASI_SERDES_SIZE_size_t);
870
  uvwasi_size_t bufused;
871
2
  uvwasi_errno_t err = uvwasi_fd_readdir(&wasi->uvw_,
872
                                         fd,
873
1
                                         &memory[buf_ptr],
874
                                         buf_len,
875
                                         cookie,
876
                                         &bufused);
877
1
  if (err == UVWASI_ESUCCESS)
878
1
    uvwasi_serdes_write_size_t(memory, bufused_ptr, bufused);
879
880
2
  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

3
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, from);
890
3
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, to);
891

1
  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
2
  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

6
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
908

6
  UNWRAP_BIGINT_OR_RETURN(args, args[1], Int64, offset);
909

6
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, whence);
910
6
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, newoffset_ptr);
911

2
  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
                                      &newoffset);
924
2
  if (err == UVWASI_ESUCCESS)
925
2
    uvwasi_serdes_write_filesize_t(memory, newoffset_ptr, newoffset);
926
927
4
  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
3
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
3
  RETURN_IF_BAD_ARG_COUNT(args, 2);
950

9
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
951
9
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, offset_ptr);
952

3
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
953
3
  Debug(wasi, "fd_tell(%d, %d)\n", fd, offset_ptr);
954
3
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
955
3
  CHECK_BOUNDS_OR_RETURN(args,
956
                         mem_size,
957
                         offset_ptr,
958
                         UVWASI_SERDES_SIZE_filesize_t);
959
  uvwasi_filesize_t offset;
960
3
  uvwasi_errno_t err = uvwasi_fd_tell(&wasi->uvw_, fd, &offset);
961
962
3
  if (err == UVWASI_ESUCCESS)
963
3
    uvwasi_serdes_write_filesize_t(memory, offset_ptr, offset);
964
965
6
  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

30
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
979

30
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, iovs_ptr);
980

30
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, iovs_len);
981
30
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, nwritten_ptr);
982

10
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
983
10
  Debug(wasi,
984
        "fd_write(%d, %d, %d, %d)\n",
985
        fd,
986
        iovs_ptr,
987
        iovs_len,
988
        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
10
  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
                                     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
20
  args.GetReturnValue().Set(err);
1017
}
1018
1019
1020
2
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
2
  RETURN_IF_BAD_ARG_COUNT(args, 3);
1028

6
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
1029

6
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, path_ptr);
1030
6
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_len);
1031

2
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
1032
2
  Debug(wasi, "path_create_directory(%d, %d, %d)\n", fd, path_ptr, path_len);
1033
2
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1034
2
  CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len);
1035
4
  uvwasi_errno_t err = uvwasi_path_create_directory(&wasi->uvw_,
1036
                                                    fd,
1037
2
                                                    &memory[path_ptr],
1038
                                                    path_len);
1039
4
  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

21
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
1054

21
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, flags);
1055

21
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_ptr);
1056

21
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, path_len);
1057
21
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, buf_ptr);
1058

7
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
1059
7
  Debug(wasi,
1060
        "path_filestat_get(%d, %d, %d)\n",
1061
        fd,
1062
        path_ptr,
1063
        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
                                                &stats);
1077
7
  if (err == UVWASI_ESUCCESS)
1078
5
    uvwasi_serdes_write_filestat_t(memory, buf_ptr, &stats);
1079
1080
14
  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

3
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, old_fd);
1140

3
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, old_flags);
1141

3
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, old_path_ptr);
1142

3
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, old_path_len);
1143

3
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, new_fd);
1144

3
  CHECK_TO_TYPE_OR_RETURN(args, args[5], Uint32, new_path_ptr);
1145
3
  CHECK_TO_TYPE_OR_RETURN(args, args[6], Uint32, new_path_len);
1146

1
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
1147
1
  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
        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
                                        new_path_len);
1167
2
  args.GetReturnValue().Set(err);
1168
}
1169
1170
1171
15
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
15
  RETURN_IF_BAD_ARG_COUNT(args, 9);
1185

45
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, dirfd);
1186

45
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, dirflags);
1187

45
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_ptr);
1188

45
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, path_len);
1189

45
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, o_flags);
1190

45
  UNWRAP_BIGINT_OR_RETURN(args, args[5], Uint64, fs_rights_base);
1191

45
  UNWRAP_BIGINT_OR_RETURN(args, args[6], Uint64, fs_rights_inheriting);
1192

45
  CHECK_TO_TYPE_OR_RETURN(args, args[7], Uint32, fs_flags);
1193
45
  CHECK_TO_TYPE_OR_RETURN(args, args[8], Uint32, fd_ptr);
1194

15
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
1195
15
  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
        fd_ptr);
1206
15
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1207
15
  CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len);
1208
15
  CHECK_BOUNDS_OR_RETURN(args, mem_size, fd_ptr, UVWASI_SERDES_SIZE_fd_t);
1209
  uvwasi_fd_t fd;
1210
30
  uvwasi_errno_t err = uvwasi_path_open(&wasi->uvw_,
1211
                                        dirfd,
1212
                                        dirflags,
1213
15
                                        &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
                                        &fd);
1220
15
  if (err == UVWASI_ESUCCESS)
1221
11
    uvwasi_serdes_write_size_t(memory, fd_ptr, fd);
1222
1223
30
  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

3
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
1239

3
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, path_ptr);
1240

3
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_len);
1241

3
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, buf_ptr);
1242

3
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, buf_len);
1243
3
  CHECK_TO_TYPE_OR_RETURN(args, args[5], Uint32, bufused_ptr);
1244

1
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
1245
1
  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
        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
                                            &bufused);
1268
1
  if (err == UVWASI_ESUCCESS)
1269
1
    uvwasi_serdes_write_size_t(memory, bufused_ptr, bufused);
1270
1271
2
  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

3
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
1284

3
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, path_ptr);
1285
3
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_len);
1286

1
  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
                                                    path_len);
1294
2
  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

3
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, old_path_ptr);
1349

3
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, old_path_len);
1350

3
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, fd);
1351

3
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, new_path_ptr);
1352
3
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, new_path_len);
1353

1
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
1354
1
  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
        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
                                           new_path_len);
1370
2
  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

3
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
1383

3
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, path_ptr);
1384
3
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_len);
1385

1
  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
                                               path_len);
1393
2
  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

15
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, in_ptr);
1407

15
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, out_ptr);
1408

15
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, nsubscriptions);
1409
15
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, nevents_ptr);
1410

5
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
1411
5
  Debug(wasi,
1412
        "poll_oneoff(%d, %d, %d, %d)\n",
1413
        in_ptr,
1414
        out_ptr,
1415
        nsubscriptions,
1416
        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
5
  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
                                          &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
10
  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
3
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, code);
1462

1
  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

3
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, buf_ptr);
1488
3
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, buf_len);
1489

1
  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
                                         buf_len);
1496
2
  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
38
void WASI::_SetMemory(const FunctionCallbackInfo<Value>& args) {
1644
  WASI* wasi;
1645
38
  CHECK_EQ(args.Length(), 1);
1646
38
  CHECK(args[0]->IsObject());
1647
38
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
1648
152
  wasi->memory_.Reset(wasi->env()->isolate(), args[0].As<Object>());
1649
}
1650
1651
1652
285
uvwasi_errno_t WASI::backingStore(char** store, size_t* byte_length) {
1653
285
  Environment* env = this->env();
1654
285
  Local<Object> memory = PersistentToLocal::Strong(this->memory_);
1655
  Local<Value> prop;
1656
1657
855
  if (!memory->Get(env->context(), env->buffer_string()).ToLocal(&prop))
1658
    return UVWASI_EINVAL;
1659
1660
285
  if (!prop->IsArrayBuffer())
1661
    return UVWASI_EINVAL;
1662
1663
285
  Local<ArrayBuffer> ab = prop.As<ArrayBuffer>();
1664
285
  std::shared_ptr<BackingStore> backing_store = ab->GetBackingStore();
1665
285
  *byte_length = backing_store->ByteLength();
1666
285
  *store = static_cast<char*>(backing_store->Data());
1667
285
  CHECK_NOT_NULL(*store);
1668
285
  return UVWASI_ESUCCESS;
1669
}
1670
1671
1672
33
static void Initialize(Local<Object> target,
1673
                       Local<Value> unused,
1674
                       Local<Context> context,
1675
                       void* priv) {
1676
33
  Environment* env = Environment::GetCurrent(context);
1677
1678
33
  Local<FunctionTemplate> tmpl = env->NewFunctionTemplate(WASI::New);
1679
66
  tmpl->InstanceTemplate()->SetInternalFieldCount(WASI::kInternalFieldCount);
1680
33
  tmpl->Inherit(BaseObject::GetConstructorTemplate(env));
1681
1682
33
  env->SetProtoMethod(tmpl, "args_get", WASI::ArgsGet);
1683
33
  env->SetProtoMethod(tmpl, "args_sizes_get", WASI::ArgsSizesGet);
1684
33
  env->SetProtoMethod(tmpl, "clock_res_get", WASI::ClockResGet);
1685
33
  env->SetProtoMethod(tmpl, "clock_time_get", WASI::ClockTimeGet);
1686
33
  env->SetProtoMethod(tmpl, "environ_get", WASI::EnvironGet);
1687
33
  env->SetProtoMethod(tmpl, "environ_sizes_get", WASI::EnvironSizesGet);
1688
33
  env->SetProtoMethod(tmpl, "fd_advise", WASI::FdAdvise);
1689
33
  env->SetProtoMethod(tmpl, "fd_allocate", WASI::FdAllocate);
1690
33
  env->SetProtoMethod(tmpl, "fd_close", WASI::FdClose);
1691
33
  env->SetProtoMethod(tmpl, "fd_datasync", WASI::FdDatasync);
1692
33
  env->SetProtoMethod(tmpl, "fd_fdstat_get", WASI::FdFdstatGet);
1693
33
  env->SetProtoMethod(tmpl, "fd_fdstat_set_flags", WASI::FdFdstatSetFlags);
1694
33
  env->SetProtoMethod(tmpl, "fd_fdstat_set_rights", WASI::FdFdstatSetRights);
1695
33
  env->SetProtoMethod(tmpl, "fd_filestat_get", WASI::FdFilestatGet);
1696
33
  env->SetProtoMethod(tmpl, "fd_filestat_set_size", WASI::FdFilestatSetSize);
1697
33
  env->SetProtoMethod(tmpl, "fd_filestat_set_times", WASI::FdFilestatSetTimes);
1698
33
  env->SetProtoMethod(tmpl, "fd_pread", WASI::FdPread);
1699
33
  env->SetProtoMethod(tmpl, "fd_prestat_get", WASI::FdPrestatGet);
1700
33
  env->SetProtoMethod(tmpl, "fd_prestat_dir_name", WASI::FdPrestatDirName);
1701
33
  env->SetProtoMethod(tmpl, "fd_pwrite", WASI::FdPwrite);
1702
33
  env->SetProtoMethod(tmpl, "fd_read", WASI::FdRead);
1703
33
  env->SetProtoMethod(tmpl, "fd_readdir", WASI::FdReaddir);
1704
33
  env->SetProtoMethod(tmpl, "fd_renumber", WASI::FdRenumber);
1705
33
  env->SetProtoMethod(tmpl, "fd_seek", WASI::FdSeek);
1706
33
  env->SetProtoMethod(tmpl, "fd_sync", WASI::FdSync);
1707
33
  env->SetProtoMethod(tmpl, "fd_tell", WASI::FdTell);
1708
33
  env->SetProtoMethod(tmpl, "fd_write", WASI::FdWrite);
1709
33
  env->SetProtoMethod(tmpl, "path_create_directory", WASI::PathCreateDirectory);
1710
33
  env->SetProtoMethod(tmpl, "path_filestat_get", WASI::PathFilestatGet);
1711
33
  env->SetProtoMethod(tmpl,
1712
                      "path_filestat_set_times",
1713
                      WASI::PathFilestatSetTimes);
1714
33
  env->SetProtoMethod(tmpl, "path_link", WASI::PathLink);
1715
33
  env->SetProtoMethod(tmpl, "path_open", WASI::PathOpen);
1716
33
  env->SetProtoMethod(tmpl, "path_readlink", WASI::PathReadlink);
1717
33
  env->SetProtoMethod(tmpl, "path_remove_directory", WASI::PathRemoveDirectory);
1718
33
  env->SetProtoMethod(tmpl, "path_rename", WASI::PathRename);
1719
33
  env->SetProtoMethod(tmpl, "path_symlink", WASI::PathSymlink);
1720
33
  env->SetProtoMethod(tmpl, "path_unlink_file", WASI::PathUnlinkFile);
1721
33
  env->SetProtoMethod(tmpl, "poll_oneoff", WASI::PollOneoff);
1722
33
  env->SetProtoMethod(tmpl, "proc_exit", WASI::ProcExit);
1723
33
  env->SetProtoMethod(tmpl, "proc_raise", WASI::ProcRaise);
1724
33
  env->SetProtoMethod(tmpl, "random_get", WASI::RandomGet);
1725
33
  env->SetProtoMethod(tmpl, "sched_yield", WASI::SchedYield);
1726
33
  env->SetProtoMethod(tmpl, "sock_recv", WASI::SockRecv);
1727
33
  env->SetProtoMethod(tmpl, "sock_send", WASI::SockSend);
1728
33
  env->SetProtoMethod(tmpl, "sock_shutdown", WASI::SockShutdown);
1729
1730
33
  env->SetInstanceMethod(tmpl, "_setMemory", WASI::_SetMemory);
1731
1732
33
  env->SetConstructorFunction(target, "WASI", tmpl);
1733
33
}
1734
1735
1736
}  // namespace wasi
1737
}  // namespace node
1738
1739
5252
NODE_MODULE_CONTEXT_AWARE_INTERNAL(wasi, node::wasi::Initialize)