GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: node_wasi.cc Lines: 596 800 74.5 %
Date: 2022-07-06 04:16:15 Branches: 407 1094 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
using v8::Array;
76
using v8::BackingStore;
77
using v8::BigInt;
78
using v8::Context;
79
using v8::Exception;
80
using v8::FunctionCallbackInfo;
81
using v8::FunctionTemplate;
82
using v8::Integer;
83
using v8::Isolate;
84
using v8::Local;
85
using v8::MaybeLocal;
86
using v8::Object;
87
using v8::String;
88
using v8::Uint32;
89
using v8::Value;
90
using v8::WasmMemoryObject;
91
92
1
static MaybeLocal<Value> WASIException(Local<Context> context,
93
                                       int errorno,
94
                                       const char* syscall) {
95
1
  Isolate* isolate = context->GetIsolate();
96
1
  Environment* env = Environment::GetCurrent(context);
97
1
  CHECK_NOT_NULL(env);
98
1
  const char* err_name = uvwasi_embedder_err_code_to_string(errorno);
99
1
  Local<String> js_code = OneByteString(isolate, err_name);
100
1
  Local<String> js_syscall = OneByteString(isolate, syscall);
101
1
  Local<String> js_msg = js_code;
102
  js_msg =
103
1
      String::Concat(isolate, js_msg, FIXED_ONE_BYTE_STRING(isolate, ", "));
104
1
  js_msg = String::Concat(isolate, js_msg, js_syscall);
105
  Local<Object> e;
106
3
  if (!Exception::Error(js_msg)->ToObject(context).ToLocal(&e))
107
    return MaybeLocal<Value>();
108
109
2
  if (e->Set(context,
110
             env->errno_string(),
111
3
             Integer::New(isolate, errorno)).IsNothing() ||
112

5
      e->Set(context, env->code_string(), js_code).IsNothing() ||
113

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

3
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, argv_offset);
260
3
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, argv_buf_offset);
261

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

3
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, argc_offset);
299
3
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, argv_buf_offset);
300

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

12
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, clock_id);
333
12
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, resolution_ptr);
334

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

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

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

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

72
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, environ_offset);
390
72
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, environ_buf_offset);
391

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

81
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, envc_offset);
432
81
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, env_buf_offset);
433

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

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

78
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
524
78
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, buf);
525

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

15
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
584
15
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, buf);
585

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

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

2
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
607
2
  Debug(wasi, "fd_filestat_set_size(%d, %d)\n", fd, st_size);
608
2
  uvwasi_errno_t err = uvwasi_fd_filestat_set_size(&wasi->uvw_, fd, st_size);
609
4
  args.GetReturnValue().Set(err);
610
}
611
612
613
1
void WASI::FdFilestatSetTimes(const FunctionCallbackInfo<Value>& args) {
614
  WASI* wasi;
615
  uint32_t fd;
616
  uint64_t st_atim;
617
  uint64_t st_mtim;
618
  uint16_t fst_flags;
619
1
  RETURN_IF_BAD_ARG_COUNT(args, 4);
620

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

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

3
  UNWRAP_BIGINT_OR_RETURN(args, args[2], Uint64, st_mtim);
623
3
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, fst_flags);
624

1
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
625
1
  Debug(wasi,
626
        "fd_filestat_set_times(%d, %d, %d, %d)\n",
627
        fd,
628
        st_atim,
629
        st_mtim,
630
        fst_flags);
631
1
  uvwasi_errno_t err = uvwasi_fd_filestat_set_times(&wasi->uvw_,
632
                                                    fd,
633
                                                    st_atim,
634
                                                    st_mtim,
635
                                                    fst_flags);
636
2
  args.GetReturnValue().Set(err);
637
}
638
639
640
void WASI::FdPread(const FunctionCallbackInfo<Value>& args) {
641
  WASI* wasi;
642
  uint32_t fd;
643
  uint32_t iovs_ptr;
644
  uint32_t iovs_len;
645
  uint64_t offset;
646
  uint32_t nread_ptr;
647
  char* memory;
648
  size_t mem_size;
649
  RETURN_IF_BAD_ARG_COUNT(args, 5);
650
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
651
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, iovs_ptr);
652
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, iovs_len);
653
  UNWRAP_BIGINT_OR_RETURN(args, args[3], Uint64, offset);
654
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, nread_ptr);
655
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
656
  Debug(wasi,
657
        "uvwasi_fd_pread(%d, %d, %d, %d, %d)\n",
658
        fd,
659
        iovs_ptr,
660
        iovs_len,
661
        offset,
662
        nread_ptr);
663
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
664
  CHECK_BOUNDS_OR_RETURN(args,
665
                         mem_size,
666
                         iovs_ptr,
667
                         iovs_len * UVWASI_SERDES_SIZE_iovec_t);
668
  CHECK_BOUNDS_OR_RETURN(args, mem_size, nread_ptr, UVWASI_SERDES_SIZE_size_t);
669
  std::vector<uvwasi_iovec_t> iovs(iovs_len);
670
  uvwasi_errno_t err;
671
672
  err = uvwasi_serdes_readv_iovec_t(memory,
673
                                    mem_size,
674
                                    iovs_ptr,
675
                                    iovs.data(),
676
                                    iovs_len);
677
  if (err != UVWASI_ESUCCESS) {
678
    args.GetReturnValue().Set(err);
679
    return;
680
  }
681
682
  uvwasi_size_t nread;
683
  err = uvwasi_fd_pread(&wasi->uvw_, fd, iovs.data(), iovs_len, offset, &nread);
684
  if (err == UVWASI_ESUCCESS)
685
    uvwasi_serdes_write_size_t(memory, nread_ptr, nread);
686
687
  args.GetReturnValue().Set(err);
688
}
689
690
691
76
void WASI::FdPrestatGet(const FunctionCallbackInfo<Value>& args) {
692
  WASI* wasi;
693
  uint32_t fd;
694
  uint32_t buf;
695
  char* memory;
696
  size_t mem_size;
697
77
  RETURN_IF_BAD_ARG_COUNT(args, 2);
698

228
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
699
228
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, buf);
700

76
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
701
75
  Debug(wasi, "fd_prestat_get(%d, %d)\n", fd, buf);
702
75
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
703
75
  CHECK_BOUNDS_OR_RETURN(args, mem_size, buf, UVWASI_SERDES_SIZE_prestat_t);
704
  uvwasi_prestat_t prestat;
705
75
  uvwasi_errno_t err = uvwasi_fd_prestat_get(&wasi->uvw_, fd, &prestat);
706
707
75
  if (err == UVWASI_ESUCCESS)
708
48
    uvwasi_serdes_write_prestat_t(memory, buf, &prestat);
709
710
150
  args.GetReturnValue().Set(err);
711
}
712
713
714
48
void WASI::FdPrestatDirName(const FunctionCallbackInfo<Value>& args) {
715
  WASI* wasi;
716
  uint32_t fd;
717
  uint32_t path_ptr;
718
  uint32_t path_len;
719
  char* memory;
720
  size_t mem_size;
721
48
  RETURN_IF_BAD_ARG_COUNT(args, 3);
722

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

144
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, path_ptr);
724
144
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_len);
725

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

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

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

45
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, iovs_len);
808
45
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, nread_ptr);
809

15
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
810
15
  Debug(wasi, "fd_read(%d, %d, %d, %d)\n", fd, iovs_ptr, iovs_len, nread_ptr);
811
15
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
812
15
  CHECK_BOUNDS_OR_RETURN(args,
813
                         mem_size,
814
                         iovs_ptr,
815
                         iovs_len * UVWASI_SERDES_SIZE_iovec_t);
816
15
  CHECK_BOUNDS_OR_RETURN(args, mem_size, nread_ptr, UVWASI_SERDES_SIZE_size_t);
817
15
  std::vector<uvwasi_iovec_t> iovs(iovs_len);
818
  uvwasi_errno_t err;
819
820
15
  err = uvwasi_serdes_readv_iovec_t(memory,
821
                                    mem_size,
822
                                    iovs_ptr,
823
                                    iovs.data(),
824
                                    iovs_len);
825
15
  if (err != UVWASI_ESUCCESS) {
826
    args.GetReturnValue().Set(err);
827
    return;
828
  }
829
830
  uvwasi_size_t nread;
831
15
  err = uvwasi_fd_read(&wasi->uvw_, fd, iovs.data(), iovs_len, &nread);
832
15
  if (err == UVWASI_ESUCCESS)
833
15
    uvwasi_serdes_write_size_t(memory, nread_ptr, nread);
834
835
30
  args.GetReturnValue().Set(err);
836
}
837
838
839
1
void WASI::FdReaddir(const FunctionCallbackInfo<Value>& args) {
840
  WASI* wasi;
841
  uint32_t fd;
842
  uint32_t buf_ptr;
843
  uint32_t buf_len;
844
  uint64_t cookie;
845
  uint32_t bufused_ptr;
846
  char* memory;
847
  size_t mem_size;
848
1
  RETURN_IF_BAD_ARG_COUNT(args, 5);
849

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

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

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

3
  UNWRAP_BIGINT_OR_RETURN(args, args[3], Uint64, cookie);
853
3
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, bufused_ptr);
854

1
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
855
1
  Debug(wasi,
856
        "uvwasi_fd_readdir(%d, %d, %d, %d, %d)\n",
857
        fd,
858
        buf_ptr,
859
        buf_len,
860
        cookie,
861
        bufused_ptr);
862
1
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
863
1
  CHECK_BOUNDS_OR_RETURN(args, mem_size, buf_ptr, buf_len);
864
1
  CHECK_BOUNDS_OR_RETURN(args,
865
                         mem_size,
866
                         bufused_ptr,
867
                         UVWASI_SERDES_SIZE_size_t);
868
  uvwasi_size_t bufused;
869
2
  uvwasi_errno_t err = uvwasi_fd_readdir(&wasi->uvw_,
870
                                         fd,
871
1
                                         &memory[buf_ptr],
872
                                         buf_len,
873
                                         cookie,
874
                                         &bufused);
875
1
  if (err == UVWASI_ESUCCESS)
876
1
    uvwasi_serdes_write_size_t(memory, bufused_ptr, bufused);
877
878
2
  args.GetReturnValue().Set(err);
879
}
880
881
882
1
void WASI::FdRenumber(const FunctionCallbackInfo<Value>& args) {
883
  WASI* wasi;
884
  uint32_t from;
885
  uint32_t to;
886
1
  RETURN_IF_BAD_ARG_COUNT(args, 2);
887

3
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, from);
888
3
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, to);
889

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

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

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

6
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, whence);
908
6
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, newoffset_ptr);
909

2
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
910
2
  Debug(wasi, "fd_seek(%d, %d, %d, %d)\n", fd, offset, whence, newoffset_ptr);
911
2
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
912
2
  CHECK_BOUNDS_OR_RETURN(args,
913
                         mem_size,
914
                         newoffset_ptr,
915
                         UVWASI_SERDES_SIZE_filesize_t);
916
  uvwasi_filesize_t newoffset;
917
2
  uvwasi_errno_t err = uvwasi_fd_seek(&wasi->uvw_,
918
                                      fd,
919
                                      offset,
920
                                      whence,
921
                                      &newoffset);
922
2
  if (err == UVWASI_ESUCCESS)
923
2
    uvwasi_serdes_write_filesize_t(memory, newoffset_ptr, newoffset);
924
925
4
  args.GetReturnValue().Set(err);
926
}
927
928
929
void WASI::FdSync(const FunctionCallbackInfo<Value>& args) {
930
  WASI* wasi;
931
  uint32_t fd;
932
  RETURN_IF_BAD_ARG_COUNT(args, 1);
933
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
934
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
935
  Debug(wasi, "fd_sync(%d)\n", fd);
936
  uvwasi_errno_t err = uvwasi_fd_sync(&wasi->uvw_, fd);
937
  args.GetReturnValue().Set(err);
938
}
939
940
941
3
void WASI::FdTell(const FunctionCallbackInfo<Value>& args) {
942
  WASI* wasi;
943
  uint32_t fd;
944
  uint32_t offset_ptr;
945
  char* memory;
946
  size_t mem_size;
947
3
  RETURN_IF_BAD_ARG_COUNT(args, 2);
948

9
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
949
9
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, offset_ptr);
950

3
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
951
3
  Debug(wasi, "fd_tell(%d, %d)\n", fd, offset_ptr);
952
3
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
953
3
  CHECK_BOUNDS_OR_RETURN(args,
954
                         mem_size,
955
                         offset_ptr,
956
                         UVWASI_SERDES_SIZE_filesize_t);
957
  uvwasi_filesize_t offset;
958
3
  uvwasi_errno_t err = uvwasi_fd_tell(&wasi->uvw_, fd, &offset);
959
960
3
  if (err == UVWASI_ESUCCESS)
961
3
    uvwasi_serdes_write_filesize_t(memory, offset_ptr, offset);
962
963
6
  args.GetReturnValue().Set(err);
964
}
965
966
967
10
void WASI::FdWrite(const FunctionCallbackInfo<Value>& args) {
968
  WASI* wasi;
969
  uint32_t fd;
970
  uint32_t iovs_ptr;
971
  uint32_t iovs_len;
972
  uint32_t nwritten_ptr;
973
  char* memory;
974
  size_t mem_size;
975
10
  RETURN_IF_BAD_ARG_COUNT(args, 4);
976

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

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

30
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, iovs_len);
979
30
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, nwritten_ptr);
980

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

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

6
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, path_ptr);
1028
6
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_len);
1029

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

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

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

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

21
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, path_len);
1055
21
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, buf_ptr);
1056

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

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

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

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

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

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

3
  CHECK_TO_TYPE_OR_RETURN(args, args[5], Uint32, new_path_ptr);
1143
3
  CHECK_TO_TYPE_OR_RETURN(args, args[6], Uint32, new_path_len);
1144

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

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

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

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

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

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

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

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

45
  CHECK_TO_TYPE_OR_RETURN(args, args[7], Uint32, fs_flags);
1191
45
  CHECK_TO_TYPE_OR_RETURN(args, args[8], Uint32, fd_ptr);
1192

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

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

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

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

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

3
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, buf_len);
1241
3
  CHECK_TO_TYPE_OR_RETURN(args, args[5], Uint32, bufused_ptr);
1242

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

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

3
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, path_ptr);
1283
3
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_len);
1284

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

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

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

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

3
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, new_path_ptr);
1350
3
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, new_path_len);
1351

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

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

3
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, path_ptr);
1382
3
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_len);
1383

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

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

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

15
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, nsubscriptions);
1407
15
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, nevents_ptr);
1408

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

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

3
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, buf_ptr);
1486
3
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, buf_len);
1487

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