GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/node_wasi.cc Lines: 587 982 59.8 %
Date: 2020-02-27 22:14:15 Branches: 262 852 30.8 %

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

6
      e->Set(context, env->code_string(), js_code).IsNothing() ||
111
4
      e->Set(context, env->syscall_string(), js_syscall).IsNothing()) {
112
    return MaybeLocal<Value>();
113
  }
114
115
1
  return e;
116
}
117
118
119
27
WASI::WASI(Environment* env,
120
           Local<Object> object,
121
54
           uvwasi_options_t* options) : BaseObject(env, object) {
122
27
  MakeWeak();
123
27
  alloc_info_ = MakeAllocator();
124
27
  options->allocator = &alloc_info_;
125
27
  int err = uvwasi_init(&uvw_, options);
126
27
  if (err != UVWASI_ESUCCESS) {
127
1
    Local<Context> context = env->context();
128
1
    MaybeLocal<Value> exception = WASIException(context, err, "uvwasi_init");
129
130
1
    if (exception.IsEmpty())
131
      return;
132
133
1
    context->GetIsolate()->ThrowException(exception.ToLocalChecked());
134
  }
135
}
136
137
138
104
WASI::~WASI() {
139
26
  uvwasi_destroy(&uvw_);
140
26
  CHECK_EQ(current_uvwasi_memory_, 0);
141
52
}
142
143
void WASI::MemoryInfo(MemoryTracker* tracker) const {
144
  tracker->TrackField("memory", memory_);
145
  tracker->TrackFieldWithSize("uvwasi_memory", current_uvwasi_memory_);
146
}
147
148
914
void WASI::CheckAllocatedSize(size_t previous_size) const {
149
914
  CHECK_GE(current_uvwasi_memory_, previous_size);
150
914
}
151
152
473
void WASI::IncreaseAllocatedSize(size_t size) {
153
473
  current_uvwasi_memory_ += size;
154
473
}
155
156
441
void WASI::DecreaseAllocatedSize(size_t size) {
157
441
  current_uvwasi_memory_ -= size;
158
441
}
159
160
27
void WASI::New(const FunctionCallbackInfo<Value>& args) {
161
27
  CHECK(args.IsConstructCall());
162
27
  CHECK_EQ(args.Length(), 3);
163
54
  CHECK(args[0]->IsArray());
164
54
  CHECK(args[1]->IsArray());
165
54
  CHECK(args[2]->IsArray());
166
167
27
  Environment* env = Environment::GetCurrent(args);
168
27
  Local<Context> context = env->context();
169
54
  Local<Array> argv = args[0].As<Array>();
170
27
  const uint32_t argc = argv->Length();
171
  uvwasi_options_t options;
172
173
27
  options.fd_table_size = 3;
174
27
  options.argc = argc;
175
27
  options.argv = argc == 0 ? nullptr : new char*[argc];
176
177
75
  for (uint32_t i = 0; i < argc; i++) {
178
96
    auto arg = argv->Get(context, i).ToLocalChecked();
179
96
    CHECK(arg->IsString());
180
96
    node::Utf8Value str(env->isolate(), arg);
181
48
    options.argv[i] = strdup(*str);
182
48
    CHECK_NOT_NULL(options.argv[i]);
183
  }
184
185
54
  Local<Array> env_pairs = args[1].As<Array>();
186
27
  const uint32_t envc = env_pairs->Length();
187
27
  options.envp = new char*[envc + 1];
188
1407
  for (uint32_t i = 0; i < envc; i++) {
189
2760
    auto pair = env_pairs->Get(context, i).ToLocalChecked();
190
2760
    CHECK(pair->IsString());
191
2760
    node::Utf8Value str(env->isolate(), pair);
192
1380
    options.envp[i] = strdup(*str);
193
1380
    CHECK_NOT_NULL(options.envp[i]);
194
  }
195
27
  options.envp[envc] = nullptr;
196
197
54
  Local<Array> preopens = args[2].As<Array>();
198
27
  CHECK_EQ(preopens->Length() % 2, 0);
199
27
  options.preopenc = preopens->Length() / 2;
200
27
  options.preopens = Calloc<uvwasi_preopen_t>(options.preopenc);
201
27
  int index = 0;
202
128
  for (uint32_t i = 0; i < preopens->Length(); i += 2) {
203
74
    auto mapped = preopens->Get(context, i).ToLocalChecked();
204
111
    auto real = preopens->Get(context, i + 1).ToLocalChecked();
205
74
    CHECK(mapped->IsString());
206
74
    CHECK(real->IsString());
207
74
    node::Utf8Value mapped_path(env->isolate(), mapped);
208
74
    node::Utf8Value real_path(env->isolate(), real);
209
37
    options.preopens[index].mapped_path = strdup(*mapped_path);
210
37
    CHECK_NOT_NULL(options.preopens[index].mapped_path);
211
37
    options.preopens[index].real_path = strdup(*real_path);
212
37
    CHECK_NOT_NULL(options.preopens[index].real_path);
213
37
    index++;
214
  }
215
216
27
  new WASI(env, args.This(), &options);
217
218
27
  if (options.argv != nullptr) {
219
64
    for (uint32_t i = 0; i < argc; i++)
220
48
      free(options.argv[i]);
221
16
    delete[] options.argv;
222
  }
223
224
27
  if (options.envp != nullptr) {
225
1407
    for (uint32_t i = 0; options.envp[i]; i++)
226
1380
      free(options.envp[i]);
227
27
    delete[] options.envp;
228
  }
229
230
27
  if (options.preopens != nullptr) {
231
64
    for (uint32_t i = 0; i < options.preopenc; i++) {
232
37
      free(options.preopens[i].mapped_path);
233
37
      free(options.preopens[i].real_path);
234
    }
235
236
27
    delete[] options.preopens;
237
  }
238
27
}
239
240
241
1
void WASI::ArgsGet(const FunctionCallbackInfo<Value>& args) {
242
  WASI* wasi;
243
  uint32_t argv_offset;
244
  uint32_t argv_buf_offset;
245
  char* memory;
246
  size_t mem_size;
247
1
  RETURN_IF_BAD_ARG_COUNT(args, 2);
248
5
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, argv_offset);
249
5
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, argv_buf_offset);
250
1
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
251
1
  Debug(wasi, "args_get(%d, %d)\n", argv_offset, argv_buf_offset);
252
1
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
253
1
  CHECK_BOUNDS_OR_RETURN(args,
254
                         mem_size,
255
                         argv_buf_offset,
256
                         wasi->uvw_.argv_buf_size);
257
1
  CHECK_BOUNDS_OR_RETURN(args, mem_size, argv_offset, wasi->uvw_.argc * 4);
258
2
  std::vector<char*> argv(wasi->uvw_.argc);
259
1
  char* argv_buf = &memory[argv_buf_offset];
260
1
  uvwasi_errno_t err = uvwasi_args_get(&wasi->uvw_, argv.data(), argv_buf);
261
262
1
  if (err == UVWASI_ESUCCESS) {
263
4
    for (size_t i = 0; i < wasi->uvw_.argc; i++) {
264
3
      uint32_t offset = argv_buf_offset + (argv[i] - argv[0]);
265
3
      wasi->writeUInt32(memory, offset, argv_offset + (i * 4));
266
    }
267
  }
268
269
3
  args.GetReturnValue().Set(err);
270
}
271
272
273
1
void WASI::ArgsSizesGet(const FunctionCallbackInfo<Value>& args) {
274
  WASI* wasi;
275
  uint32_t argc_offset;
276
  uint32_t argv_buf_offset;
277
  char* memory;
278
  size_t mem_size;
279
1
  RETURN_IF_BAD_ARG_COUNT(args, 2);
280
5
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, argc_offset);
281
5
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, argv_buf_offset);
282
1
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
283
1
  Debug(wasi, "args_sizes_get(%d, %d)\n", argc_offset, argv_buf_offset);
284
1
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
285
1
  CHECK_BOUNDS_OR_RETURN(args, mem_size, argc_offset, 4);
286
1
  CHECK_BOUNDS_OR_RETURN(args, mem_size, argv_buf_offset, 4);
287
  size_t argc;
288
  size_t argv_buf_size;
289
1
  uvwasi_errno_t err = uvwasi_args_sizes_get(&wasi->uvw_,
290
                                             &argc,
291
1
                                             &argv_buf_size);
292
1
  if (err == UVWASI_ESUCCESS) {
293
1
    wasi->writeUInt32(memory, argc, argc_offset);
294
1
    wasi->writeUInt32(memory, argv_buf_size, argv_buf_offset);
295
  }
296
297
3
  args.GetReturnValue().Set(err);
298
}
299
300
301
4
void WASI::ClockResGet(const FunctionCallbackInfo<Value>& args) {
302
  WASI* wasi;
303
  uint32_t clock_id;
304
  uint32_t resolution_ptr;
305
  char* memory;
306
  size_t mem_size;
307
4
  RETURN_IF_BAD_ARG_COUNT(args, 2);
308
20
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, clock_id);
309
20
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, resolution_ptr);
310
4
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
311
4
  Debug(wasi, "clock_res_get(%d, %d)\n", clock_id, resolution_ptr);
312
4
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
313
4
  CHECK_BOUNDS_OR_RETURN(args, mem_size, resolution_ptr, 8);
314
  uvwasi_timestamp_t resolution;
315
4
  uvwasi_errno_t err = uvwasi_clock_res_get(&wasi->uvw_,
316
                                            clock_id,
317
4
                                            &resolution);
318
4
  if (err == UVWASI_ESUCCESS)
319
4
    wasi->writeUInt64(memory, resolution, resolution_ptr);
320
321
12
  args.GetReturnValue().Set(err);
322
}
323
324
325
4
void WASI::ClockTimeGet(const FunctionCallbackInfo<Value>& args) {
326
  WASI* wasi;
327
  uint32_t clock_id;
328
  uint64_t precision;
329
  uint32_t time_ptr;
330
  char* memory;
331
  size_t mem_size;
332
4
  RETURN_IF_BAD_ARG_COUNT(args, 3);
333
20
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, clock_id);
334
20
  UNWRAP_BIGINT_OR_RETURN(args, args[1], Uint64, precision);
335
20
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, time_ptr);
336
4
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
337
4
  Debug(wasi, "clock_time_get(%d, %d, %d)\n", clock_id, precision, time_ptr);
338
4
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
339
4
  CHECK_BOUNDS_OR_RETURN(args, mem_size, time_ptr, 8);
340
  uvwasi_timestamp_t time;
341
4
  uvwasi_errno_t err = uvwasi_clock_time_get(&wasi->uvw_,
342
                                             clock_id,
343
                                             precision,
344
4
                                             &time);
345
4
  if (err == UVWASI_ESUCCESS)
346
4
    wasi->writeUInt64(memory, time, time_ptr);
347
348
12
  args.GetReturnValue().Set(err);
349
}
350
351
352
20
void WASI::EnvironGet(const FunctionCallbackInfo<Value>& args) {
353
  WASI* wasi;
354
  uint32_t environ_offset;
355
  uint32_t environ_buf_offset;
356
  char* memory;
357
  size_t mem_size;
358
20
  RETURN_IF_BAD_ARG_COUNT(args, 2);
359
100
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, environ_offset);
360
100
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, environ_buf_offset);
361
20
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
362
20
  Debug(wasi, "environ_get(%d, %d)\n", environ_offset, environ_buf_offset);
363
20
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
364
20
  CHECK_BOUNDS_OR_RETURN(args,
365
                         mem_size,
366
                         environ_buf_offset,
367
                         wasi->uvw_.env_buf_size);
368
20
  CHECK_BOUNDS_OR_RETURN(args, mem_size, environ_offset, wasi->uvw_.envc * 4);
369
40
  std::vector<char*> environment(wasi->uvw_.envc);
370
20
  char* environ_buf = &memory[environ_buf_offset];
371
20
  uvwasi_errno_t err = uvwasi_environ_get(&wasi->uvw_,
372
                                          environment.data(),
373
20
                                          environ_buf);
374
375
20
  if (err == UVWASI_ESUCCESS) {
376
1400
    for (size_t i = 0; i < wasi->uvw_.envc; i++) {
377
1380
      uint32_t offset = environ_buf_offset + (environment[i] - environment[0]);
378
1380
      wasi->writeUInt32(memory, offset, environ_offset + (i * 4));
379
    }
380
  }
381
382
60
  args.GetReturnValue().Set(err);
383
}
384
385
386
20
void WASI::EnvironSizesGet(const FunctionCallbackInfo<Value>& args) {
387
  WASI* wasi;
388
  uint32_t envc_offset;
389
  uint32_t env_buf_offset;
390
  char* memory;
391
  size_t mem_size;
392
20
  RETURN_IF_BAD_ARG_COUNT(args, 2);
393
100
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, envc_offset);
394
100
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, env_buf_offset);
395
20
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
396
20
  Debug(wasi, "environ_sizes_get(%d, %d)\n", envc_offset, env_buf_offset);
397
20
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
398
20
  CHECK_BOUNDS_OR_RETURN(args, mem_size, envc_offset, 4);
399
20
  CHECK_BOUNDS_OR_RETURN(args, mem_size, env_buf_offset, 4);
400
  size_t envc;
401
  size_t env_buf_size;
402
20
  uvwasi_errno_t err = uvwasi_environ_sizes_get(&wasi->uvw_,
403
                                                &envc,
404
20
                                                &env_buf_size);
405
20
  if (err == UVWASI_ESUCCESS) {
406
20
    wasi->writeUInt32(memory, envc, envc_offset);
407
20
    wasi->writeUInt32(memory, env_buf_size, env_buf_offset);
408
  }
409
410
60
  args.GetReturnValue().Set(err);
411
}
412
413
414
void WASI::FdAdvise(const FunctionCallbackInfo<Value>& args) {
415
  WASI* wasi;
416
  uint32_t fd;
417
  uint64_t offset;
418
  uint64_t len;
419
  uint8_t advice;
420
  RETURN_IF_BAD_ARG_COUNT(args, 4);
421
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
422
  UNWRAP_BIGINT_OR_RETURN(args, args[1], Uint64, offset);
423
  UNWRAP_BIGINT_OR_RETURN(args, args[2], Uint64, len);
424
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, advice);
425
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
426
  Debug(wasi, "fd_advise(%d, %d, %d, %d)\n", fd, offset, len, advice);
427
  uvwasi_errno_t err = uvwasi_fd_advise(&wasi->uvw_, fd, offset, len, advice);
428
  args.GetReturnValue().Set(err);
429
}
430
431
432
void WASI::FdAllocate(const FunctionCallbackInfo<Value>& args) {
433
  WASI* wasi;
434
  uint32_t fd;
435
  uint64_t offset;
436
  uint64_t len;
437
  RETURN_IF_BAD_ARG_COUNT(args, 3);
438
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
439
  UNWRAP_BIGINT_OR_RETURN(args, args[1], Uint64, offset);
440
  UNWRAP_BIGINT_OR_RETURN(args, args[2], Uint64, len);
441
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
442
  Debug(wasi, "fd_allocate(%d, %d, %d)\n", fd, offset, len);
443
  uvwasi_errno_t err = uvwasi_fd_allocate(&wasi->uvw_, fd, offset, len);
444
  args.GetReturnValue().Set(err);
445
}
446
447
448
3
void WASI::FdClose(const FunctionCallbackInfo<Value>& args) {
449
  WASI* wasi;
450
  uint32_t fd;
451
4
  RETURN_IF_BAD_ARG_COUNT(args, 1);
452
14
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
453
2
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
454
2
  Debug(wasi, "fd_close(%d)\n", fd);
455
2
  uvwasi_errno_t err = uvwasi_fd_close(&wasi->uvw_, fd);
456
6
  args.GetReturnValue().Set(err);
457
}
458
459
460
void WASI::FdDatasync(const FunctionCallbackInfo<Value>& args) {
461
  WASI* wasi;
462
  uint32_t fd;
463
  RETURN_IF_BAD_ARG_COUNT(args, 1);
464
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
465
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
466
  Debug(wasi, "fd_datasync(%d)\n", fd);
467
  uvwasi_errno_t err = uvwasi_fd_datasync(&wasi->uvw_, fd);
468
  args.GetReturnValue().Set(err);
469
}
470
471
472
23
void WASI::FdFdstatGet(const FunctionCallbackInfo<Value>& args) {
473
  WASI* wasi;
474
  uint32_t fd;
475
  uint32_t buf;
476
  char* memory;
477
  size_t mem_size;
478
23
  RETURN_IF_BAD_ARG_COUNT(args, 2);
479
115
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
480
115
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, buf);
481
23
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
482
23
  Debug(wasi, "fd_fdstat_get(%d, %d)\n", fd, buf);
483
23
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
484
23
  CHECK_BOUNDS_OR_RETURN(args, mem_size, buf, 24);
485
  uvwasi_fdstat_t stats;
486
23
  uvwasi_errno_t err = uvwasi_fd_fdstat_get(&wasi->uvw_, fd, &stats);
487
488
23
  if (err == UVWASI_ESUCCESS) {
489
23
    wasi->writeUInt8(memory, stats.fs_filetype, buf);
490
23
    wasi->writeUInt16(memory, stats.fs_flags, buf + 2);
491
23
    wasi->writeUInt64(memory, stats.fs_rights_base, buf + 8);
492
23
    wasi->writeUInt64(memory, stats.fs_rights_inheriting, buf + 16);
493
  }
494
495
69
  args.GetReturnValue().Set(err);
496
}
497
498
499
void WASI::FdFdstatSetFlags(const FunctionCallbackInfo<Value>& args) {
500
  WASI* wasi;
501
  uint32_t fd;
502
  uint16_t flags;
503
  RETURN_IF_BAD_ARG_COUNT(args, 2);
504
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
505
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, flags);
506
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
507
  Debug(wasi, "fd_fdstat_set_flags(%d, %d)\n", fd, flags);
508
  uvwasi_errno_t err = uvwasi_fd_fdstat_set_flags(&wasi->uvw_, fd, flags);
509
  args.GetReturnValue().Set(err);
510
}
511
512
513
void WASI::FdFdstatSetRights(const FunctionCallbackInfo<Value>& args) {
514
  WASI* wasi;
515
  uint32_t fd;
516
  uint64_t fs_rights_base;
517
  uint64_t fs_rights_inheriting;
518
  RETURN_IF_BAD_ARG_COUNT(args, 3);
519
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
520
  UNWRAP_BIGINT_OR_RETURN(args, args[1], Uint64, fs_rights_base);
521
  UNWRAP_BIGINT_OR_RETURN(args, args[2], Uint64, fs_rights_inheriting);
522
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
523
  Debug(wasi,
524
        "fd_fdstat_set_rights(%d, %d, %d)\n",
525
        fd,
526
        fs_rights_base,
527
        fs_rights_inheriting);
528
  uvwasi_errno_t err = uvwasi_fd_fdstat_set_rights(&wasi->uvw_,
529
                                                   fd,
530
                                                   fs_rights_base,
531
                                                   fs_rights_inheriting);
532
  args.GetReturnValue().Set(err);
533
}
534
535
536
1
void WASI::FdFilestatGet(const FunctionCallbackInfo<Value>& args) {
537
  WASI* wasi;
538
  uint32_t fd;
539
  uint32_t buf;
540
  char* memory;
541
  size_t mem_size;
542
1
  RETURN_IF_BAD_ARG_COUNT(args, 2);
543
5
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
544
5
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, buf);
545
1
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
546
1
  Debug(wasi, "fd_filestat_get(%d, %d)\n", fd, buf);
547
1
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
548
1
  CHECK_BOUNDS_OR_RETURN(args, mem_size, buf, 64);
549
  uvwasi_filestat_t stats;
550
1
  uvwasi_errno_t err = uvwasi_fd_filestat_get(&wasi->uvw_, fd, &stats);
551
552
1
  if (err == UVWASI_ESUCCESS) {
553
1
    wasi->writeUInt64(memory, stats.st_dev, buf);
554
1
    wasi->writeUInt64(memory, stats.st_ino, buf + 8);
555
1
    wasi->writeUInt8(memory, stats.st_filetype, buf + 16);
556
1
    wasi->writeUInt64(memory, stats.st_nlink, buf + 24);
557
1
    wasi->writeUInt64(memory, stats.st_size, buf + 32);
558
1
    wasi->writeUInt64(memory, stats.st_atim, buf + 40);
559
1
    wasi->writeUInt64(memory, stats.st_mtim, buf + 48);
560
1
    wasi->writeUInt64(memory, stats.st_ctim, buf + 56);
561
  }
562
563
3
  args.GetReturnValue().Set(err);
564
}
565
566
567
void WASI::FdFilestatSetSize(const FunctionCallbackInfo<Value>& args) {
568
  WASI* wasi;
569
  uint32_t fd;
570
  uint64_t st_size;
571
  RETURN_IF_BAD_ARG_COUNT(args, 2);
572
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
573
  UNWRAP_BIGINT_OR_RETURN(args, args[1], Uint64, st_size);
574
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
575
  Debug(wasi, "fd_filestat_set_size(%d, %d)\n", fd, st_size);
576
  uvwasi_errno_t err = uvwasi_fd_filestat_set_size(&wasi->uvw_, fd, st_size);
577
  args.GetReturnValue().Set(err);
578
}
579
580
581
void WASI::FdFilestatSetTimes(const FunctionCallbackInfo<Value>& args) {
582
  WASI* wasi;
583
  uint32_t fd;
584
  uint64_t st_atim;
585
  uint64_t st_mtim;
586
  uint16_t fst_flags;
587
  RETURN_IF_BAD_ARG_COUNT(args, 4);
588
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
589
  UNWRAP_BIGINT_OR_RETURN(args, args[1], Uint64, st_atim);
590
  UNWRAP_BIGINT_OR_RETURN(args, args[2], Uint64, st_mtim);
591
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, fst_flags);
592
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
593
  Debug(wasi,
594
        "fd_filestat_set_times(%d, %d, %d, %d)\n",
595
        fd,
596
        st_atim,
597
        st_mtim,
598
        fst_flags);
599
  uvwasi_errno_t err = uvwasi_fd_filestat_set_times(&wasi->uvw_,
600
                                                    fd,
601
                                                    st_atim,
602
                                                    st_mtim,
603
                                                    fst_flags);
604
  args.GetReturnValue().Set(err);
605
}
606
607
608
void WASI::FdPread(const FunctionCallbackInfo<Value>& args) {
609
  WASI* wasi;
610
  uint32_t fd;
611
  uint32_t iovs_ptr;
612
  uint32_t iovs_len;
613
  uint64_t offset;
614
  uint32_t nread_ptr;
615
  char* memory;
616
  size_t mem_size;
617
  RETURN_IF_BAD_ARG_COUNT(args, 5);
618
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
619
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, iovs_ptr);
620
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, iovs_len);
621
  UNWRAP_BIGINT_OR_RETURN(args, args[3], Uint64, offset);
622
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, nread_ptr);
623
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
624
  Debug(wasi,
625
        "uvwasi_fd_pread(%d, %d, %d, %d, %d)\n",
626
        fd,
627
        iovs_ptr,
628
        iovs_len,
629
        offset,
630
        nread_ptr);
631
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
632
  CHECK_BOUNDS_OR_RETURN(args, mem_size, iovs_ptr, iovs_len * 8);
633
  CHECK_BOUNDS_OR_RETURN(args, mem_size, nread_ptr, 4);
634
  uvwasi_iovec_t* iovs = UncheckedCalloc<uvwasi_iovec_t>(iovs_len);
635
636
  if (iovs == nullptr) {
637
    args.GetReturnValue().Set(UVWASI_ENOMEM);
638
    return;
639
  }
640
641
  for (uint32_t i = 0; i < iovs_len; ++i) {
642
    uint32_t buf_ptr;
643
    uint32_t buf_len;
644
645
    wasi->readUInt32(memory, &buf_ptr, iovs_ptr);
646
    wasi->readUInt32(memory, &buf_len, iovs_ptr + 4);
647
648
    if (is_access_oob(mem_size, buf_ptr, buf_len)) {
649
      free(iovs);
650
      args.GetReturnValue().Set(UVWASI_EOVERFLOW);
651
      return;
652
    }
653
654
    iovs_ptr += 8;
655
    iovs[i].buf = static_cast<void*>(&memory[buf_ptr]);
656
    iovs[i].buf_len = buf_len;
657
  }
658
659
  size_t nread;
660
  uvwasi_errno_t err = uvwasi_fd_pread(&wasi->uvw_,
661
                                       fd,
662
                                       iovs,
663
                                       iovs_len,
664
                                       offset,
665
                                       &nread);
666
  if (err == UVWASI_ESUCCESS)
667
    wasi->writeUInt32(memory, nread, nread_ptr);
668
669
  free(iovs);
670
  args.GetReturnValue().Set(err);
671
}
672
673
674
56
void WASI::FdPrestatGet(const FunctionCallbackInfo<Value>& args) {
675
  WASI* wasi;
676
  uint32_t fd;
677
  uint32_t buf;
678
  char* memory;
679
  size_t mem_size;
680
56
  RETURN_IF_BAD_ARG_COUNT(args, 2);
681
280
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
682
280
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, buf);
683
56
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
684
56
  Debug(wasi, "fd_prestat_get(%d, %d)\n", fd, buf);
685
56
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
686
56
  CHECK_BOUNDS_OR_RETURN(args, mem_size, buf, 8);
687
  uvwasi_prestat_t prestat;
688
56
  uvwasi_errno_t err = uvwasi_fd_prestat_get(&wasi->uvw_, fd, &prestat);
689
690
56
  if (err == UVWASI_ESUCCESS) {
691
36
    wasi->writeUInt32(memory, prestat.pr_type, buf);
692
36
    wasi->writeUInt32(memory, prestat.u.dir.pr_name_len, buf + 4);
693
  }
694
695
168
  args.GetReturnValue().Set(err);
696
}
697
698
699
36
void WASI::FdPrestatDirName(const FunctionCallbackInfo<Value>& args) {
700
  WASI* wasi;
701
  uint32_t fd;
702
  uint32_t path_ptr;
703
  uint32_t path_len;
704
  char* memory;
705
  size_t mem_size;
706
36
  RETURN_IF_BAD_ARG_COUNT(args, 3);
707
180
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
708
180
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, path_ptr);
709
180
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_len);
710
36
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
711
36
  Debug(wasi, "fd_prestat_dir_name(%d, %d, %d)\n", fd, path_ptr, path_len);
712
36
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
713
36
  CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len);
714
36
  uvwasi_errno_t err = uvwasi_fd_prestat_dir_name(&wasi->uvw_,
715
                                                  fd,
716
                                                  &memory[path_ptr],
717
36
                                                  path_len);
718
108
  args.GetReturnValue().Set(err);
719
}
720
721
722
void WASI::FdPwrite(const FunctionCallbackInfo<Value>& args) {
723
  WASI* wasi;
724
  uint32_t fd;
725
  uint32_t iovs_ptr;
726
  uint32_t iovs_len;
727
  uint64_t offset;
728
  uint32_t nwritten_ptr;
729
  char* memory;
730
  size_t mem_size;
731
  RETURN_IF_BAD_ARG_COUNT(args, 5);
732
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
733
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, iovs_ptr);
734
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, iovs_len);
735
  UNWRAP_BIGINT_OR_RETURN(args, args[3], Uint64, offset);
736
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, nwritten_ptr);
737
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
738
  Debug(wasi,
739
        "uvwasi_fd_pwrite(%d, %d, %d, %d, %d)\n",
740
        fd,
741
        iovs_ptr,
742
        iovs_len,
743
        offset,
744
        nwritten_ptr);
745
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
746
  CHECK_BOUNDS_OR_RETURN(args, mem_size, iovs_ptr, iovs_len * 8);
747
  CHECK_BOUNDS_OR_RETURN(args, mem_size, nwritten_ptr, 4);
748
  uvwasi_ciovec_t* iovs = UncheckedCalloc<uvwasi_ciovec_t>(iovs_len);
749
750
  if (iovs == nullptr) {
751
    args.GetReturnValue().Set(UVWASI_ENOMEM);
752
    return;
753
  }
754
755
  for (uint32_t i = 0; i < iovs_len; ++i) {
756
    uint32_t buf_ptr;
757
    uint32_t buf_len;
758
759
    wasi->readUInt32(memory, &buf_ptr, iovs_ptr);
760
    wasi->readUInt32(memory, &buf_len, iovs_ptr + 4);
761
762
    if (is_access_oob(mem_size, buf_ptr, buf_len)) {
763
      free(iovs);
764
      args.GetReturnValue().Set(UVWASI_EOVERFLOW);
765
      return;
766
    }
767
768
    iovs_ptr += 8;
769
    iovs[i].buf = static_cast<void*>(&memory[buf_ptr]);
770
    iovs[i].buf_len = buf_len;
771
  }
772
773
  size_t nwritten;
774
  uvwasi_errno_t err = uvwasi_fd_pwrite(&wasi->uvw_,
775
                                        fd,
776
                                        iovs,
777
                                        iovs_len,
778
                                        offset,
779
                                        &nwritten);
780
  if (err == UVWASI_ESUCCESS)
781
    wasi->writeUInt32(memory, nwritten, nwritten_ptr);
782
783
  free(iovs);
784
  args.GetReturnValue().Set(err);
785
}
786
787
788
14
void WASI::FdRead(const FunctionCallbackInfo<Value>& args) {
789
  WASI* wasi;
790
  uint32_t fd;
791
  uint32_t iovs_ptr;
792
  uint32_t iovs_len;
793
  uint32_t nread_ptr;
794
  char* memory;
795
  size_t mem_size;
796
14
  RETURN_IF_BAD_ARG_COUNT(args, 4);
797
70
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
798
70
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, iovs_ptr);
799
70
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, iovs_len);
800
70
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, nread_ptr);
801
14
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
802
14
  Debug(wasi, "fd_read(%d, %d, %d, %d)\n", fd, iovs_ptr, iovs_len, nread_ptr);
803
14
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
804
14
  CHECK_BOUNDS_OR_RETURN(args, mem_size, iovs_ptr, iovs_len * 8);
805
14
  CHECK_BOUNDS_OR_RETURN(args, mem_size, nread_ptr, 4);
806
14
  uvwasi_iovec_t* iovs = UncheckedCalloc<uvwasi_iovec_t>(iovs_len);
807
808
14
  if (iovs == nullptr) {
809
    args.GetReturnValue().Set(UVWASI_ENOMEM);
810
    return;
811
  }
812
813
28
  for (uint32_t i = 0; i < iovs_len; ++i) {
814
    uint32_t buf_ptr;
815
    uint32_t buf_len;
816
817
14
    wasi->readUInt32(memory, &buf_ptr, iovs_ptr);
818
14
    wasi->readUInt32(memory, &buf_len, iovs_ptr + 4);
819
820
14
    if (is_access_oob(mem_size, buf_ptr, buf_len)) {
821
      free(iovs);
822
      args.GetReturnValue().Set(UVWASI_EOVERFLOW);
823
      return;
824
    }
825
826
14
    iovs_ptr += 8;
827
14
    iovs[i].buf = static_cast<void*>(&memory[buf_ptr]);
828
14
    iovs[i].buf_len = buf_len;
829
  }
830
831
  size_t nread;
832
14
  uvwasi_errno_t err = uvwasi_fd_read(&wasi->uvw_,
833
                                      fd,
834
                                      iovs,
835
                                      iovs_len,
836
14
                                      &nread);
837
14
  if (err == UVWASI_ESUCCESS)
838
14
    wasi->writeUInt32(memory, nread, nread_ptr);
839
840
14
  free(iovs);
841
42
  args.GetReturnValue().Set(err);
842
}
843
844
845
void WASI::FdReaddir(const FunctionCallbackInfo<Value>& args) {
846
  WASI* wasi;
847
  uint32_t fd;
848
  uint32_t buf_ptr;
849
  uint32_t buf_len;
850
  uint64_t cookie;
851
  uint32_t bufused_ptr;
852
  char* memory;
853
  size_t mem_size;
854
  RETURN_IF_BAD_ARG_COUNT(args, 5);
855
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
856
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, buf_ptr);
857
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, buf_len);
858
  UNWRAP_BIGINT_OR_RETURN(args, args[3], Uint64, cookie);
859
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, bufused_ptr);
860
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
861
  Debug(wasi,
862
        "uvwasi_fd_readdir(%d, %d, %d, %d, %d)\n",
863
        fd,
864
        buf_ptr,
865
        buf_len,
866
        cookie,
867
        bufused_ptr);
868
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
869
  CHECK_BOUNDS_OR_RETURN(args, mem_size, buf_ptr, buf_len);
870
  CHECK_BOUNDS_OR_RETURN(args, mem_size, bufused_ptr, 4);
871
  size_t bufused;
872
  uvwasi_errno_t err = uvwasi_fd_readdir(&wasi->uvw_,
873
                                         fd,
874
                                         &memory[buf_ptr],
875
                                         buf_len,
876
                                         cookie,
877
                                         &bufused);
878
  if (err == UVWASI_ESUCCESS)
879
    wasi->writeUInt32(memory, bufused, bufused_ptr);
880
881
  args.GetReturnValue().Set(err);
882
}
883
884
885
1
void WASI::FdRenumber(const FunctionCallbackInfo<Value>& args) {
886
  WASI* wasi;
887
  uint32_t from;
888
  uint32_t to;
889
1
  RETURN_IF_BAD_ARG_COUNT(args, 2);
890
5
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, from);
891
5
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, to);
892
1
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
893
1
  Debug(wasi, "fd_renumber(%d, %d)\n", from, to);
894
1
  uvwasi_errno_t err = uvwasi_fd_renumber(&wasi->uvw_, from, to);
895
3
  args.GetReturnValue().Set(err);
896
}
897
898
899
1
void WASI::FdSeek(const FunctionCallbackInfo<Value>& args) {
900
  WASI* wasi;
901
  uint32_t fd;
902
  int64_t offset;
903
  uint8_t whence;
904
  uint32_t newoffset_ptr;
905
  char* memory;
906
  size_t mem_size;
907
1
  RETURN_IF_BAD_ARG_COUNT(args, 4);
908
5
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
909
5
  UNWRAP_BIGINT_OR_RETURN(args, args[1], Int64, offset);
910
5
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, whence);
911
5
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, newoffset_ptr);
912
1
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
913
1
  Debug(wasi, "fd_seek(%d, %d, %d, %d)\n", fd, offset, whence, newoffset_ptr);
914
1
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
915
1
  CHECK_BOUNDS_OR_RETURN(args, mem_size, newoffset_ptr, 8);
916
  uvwasi_filesize_t newoffset;
917
1
  uvwasi_errno_t err = uvwasi_fd_seek(&wasi->uvw_,
918
                                      fd,
919
                                      offset,
920
                                      whence,
921
1
                                      &newoffset);
922
1
  if (err == UVWASI_ESUCCESS)
923
1
    wasi->writeUInt64(memory, newoffset, newoffset_ptr);
924
925
3
  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_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
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
  RETURN_IF_BAD_ARG_COUNT(args, 2);
948
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
949
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, offset_ptr);
950
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
951
  Debug(wasi, "fd_tell(%d, %d)\n", fd, offset_ptr);
952
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
953
  CHECK_BOUNDS_OR_RETURN(args, mem_size, offset_ptr, 8);
954
  uvwasi_filesize_t offset;
955
  uvwasi_errno_t err = uvwasi_fd_tell(&wasi->uvw_, fd, &offset);
956
957
  if (err == UVWASI_ESUCCESS)
958
    wasi->writeUInt64(memory, offset, offset_ptr);
959
960
  args.GetReturnValue().Set(err);
961
}
962
963
964
9
void WASI::FdWrite(const FunctionCallbackInfo<Value>& args) {
965
  WASI* wasi;
966
  uint32_t fd;
967
  uint32_t iovs_ptr;
968
  uint32_t iovs_len;
969
  uint32_t nwritten_ptr;
970
  char* memory;
971
  size_t mem_size;
972
9
  RETURN_IF_BAD_ARG_COUNT(args, 4);
973
45
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
974
45
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, iovs_ptr);
975
45
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, iovs_len);
976
45
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, nwritten_ptr);
977
9
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
978
  Debug(wasi,
979
        "fd_write(%d, %d, %d, %d)\n",
980
        fd,
981
        iovs_ptr,
982
        iovs_len,
983
9
        nwritten_ptr);
984
9
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
985
9
  CHECK_BOUNDS_OR_RETURN(args, mem_size, iovs_ptr, iovs_len * 8);
986
9
  CHECK_BOUNDS_OR_RETURN(args, mem_size, nwritten_ptr, 4);
987
9
  uvwasi_ciovec_t* iovs = UncheckedCalloc<uvwasi_ciovec_t>(iovs_len);
988
989
9
  if (iovs == nullptr) {
990
    args.GetReturnValue().Set(UVWASI_ENOMEM);
991
    return;
992
  }
993
994
26
  for (uint32_t i = 0; i < iovs_len; ++i) {
995
    uint32_t buf_ptr;
996
    uint32_t buf_len;
997
998
17
    wasi->readUInt32(memory, &buf_ptr, iovs_ptr);
999
17
    wasi->readUInt32(memory, &buf_len, iovs_ptr + 4);
1000
1001
17
    if (is_access_oob(mem_size, buf_ptr, buf_len)) {
1002
      free(iovs);
1003
      args.GetReturnValue().Set(UVWASI_EOVERFLOW);
1004
      return;
1005
    }
1006
1007
17
    iovs_ptr += 8;
1008
17
    iovs[i].buf = static_cast<void*>(&memory[buf_ptr]);
1009
17
    iovs[i].buf_len = buf_len;
1010
  }
1011
1012
  size_t nwritten;
1013
9
  uvwasi_errno_t err = uvwasi_fd_write(&wasi->uvw_,
1014
                                       fd,
1015
                                       iovs,
1016
                                       iovs_len,
1017
9
                                       &nwritten);
1018
9
  if (err == UVWASI_ESUCCESS)
1019
9
    wasi->writeUInt32(memory, nwritten, nwritten_ptr);
1020
1021
9
  free(iovs);
1022
27
  args.GetReturnValue().Set(err);
1023
}
1024
1025
1026
1
void WASI::PathCreateDirectory(const FunctionCallbackInfo<Value>& args) {
1027
  WASI* wasi;
1028
  uint32_t fd;
1029
  uint32_t path_ptr;
1030
  uint32_t path_len;
1031
  char* memory;
1032
  size_t mem_size;
1033
1
  RETURN_IF_BAD_ARG_COUNT(args, 3);
1034
5
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
1035
5
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, path_ptr);
1036
5
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_len);
1037
1
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
1038
1
  Debug(wasi, "path_create_directory(%d, %d, %d)\n", fd, path_ptr, path_len);
1039
1
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1040
1
  CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len);
1041
2
  uvwasi_errno_t err = uvwasi_path_create_directory(&wasi->uvw_,
1042
                                                    fd,
1043
1
                                                    &memory[path_ptr],
1044
1
                                                    path_len);
1045
3
  args.GetReturnValue().Set(err);
1046
}
1047
1048
1049
5
void WASI::PathFilestatGet(const FunctionCallbackInfo<Value>& args) {
1050
  WASI* wasi;
1051
  uint32_t fd;
1052
  uint32_t flags;
1053
  uint32_t path_ptr;
1054
  uint32_t path_len;
1055
  uint32_t buf_ptr;
1056
  char* memory;
1057
  size_t mem_size;
1058
5
  RETURN_IF_BAD_ARG_COUNT(args, 5);
1059
25
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
1060
25
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, flags);
1061
25
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_ptr);
1062
25
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, path_len);
1063
25
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, buf_ptr);
1064
5
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
1065
  Debug(wasi,
1066
        "path_filestat_get(%d, %d, %d)\n",
1067
        fd,
1068
        path_ptr,
1069
5
        path_len);
1070
5
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1071
5
  CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len);
1072
5
  CHECK_BOUNDS_OR_RETURN(args, mem_size, buf_ptr, 64);
1073
  uvwasi_filestat_t stats;
1074
10
  uvwasi_errno_t err = uvwasi_path_filestat_get(&wasi->uvw_,
1075
                                                fd,
1076
                                                flags,
1077
5
                                                &memory[path_ptr],
1078
                                                path_len,
1079
5
                                                &stats);
1080
5
  if (err == UVWASI_ESUCCESS) {
1081
3
    wasi->writeUInt64(memory, stats.st_dev, buf_ptr);
1082
3
    wasi->writeUInt64(memory, stats.st_ino, buf_ptr + 8);
1083
3
    wasi->writeUInt8(memory, stats.st_filetype, buf_ptr + 16);
1084
3
    wasi->writeUInt64(memory, stats.st_nlink, buf_ptr + 24);
1085
3
    wasi->writeUInt64(memory, stats.st_size, buf_ptr + 32);
1086
3
    wasi->writeUInt64(memory, stats.st_atim, buf_ptr + 40);
1087
3
    wasi->writeUInt64(memory, stats.st_mtim, buf_ptr + 48);
1088
3
    wasi->writeUInt64(memory, stats.st_ctim, buf_ptr + 56);
1089
  }
1090
1091
15
  args.GetReturnValue().Set(err);
1092
}
1093
1094
1095
void WASI::PathFilestatSetTimes(const FunctionCallbackInfo<Value>& args) {
1096
  WASI* wasi;
1097
  uint32_t fd;
1098
  uint32_t flags;
1099
  uint32_t path_ptr;
1100
  uint32_t path_len;
1101
  uint64_t st_atim;
1102
  uint64_t st_mtim;
1103
  uint16_t fst_flags;
1104
  char* memory;
1105
  size_t mem_size;
1106
  RETURN_IF_BAD_ARG_COUNT(args, 7);
1107
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
1108
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, flags);
1109
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_ptr);
1110
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, path_len);
1111
  UNWRAP_BIGINT_OR_RETURN(args, args[4], Uint64, st_atim);
1112
  UNWRAP_BIGINT_OR_RETURN(args, args[5], Uint64, st_mtim);
1113
  CHECK_TO_TYPE_OR_RETURN(args, args[6], Uint32, fst_flags);
1114
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
1115
  Debug(wasi,
1116
        "path_filestat_set_times(%d, %d, %d, %d, %d, %d, %d)\n",
1117
        fd,
1118
        flags,
1119
        path_ptr,
1120
        path_len,
1121
        st_atim,
1122
        st_mtim,
1123
        fst_flags);
1124
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1125
  CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len);
1126
  uvwasi_errno_t err = uvwasi_path_filestat_set_times(&wasi->uvw_,
1127
                                                      fd,
1128
                                                      flags,
1129
                                                      &memory[path_ptr],
1130
                                                      path_len,
1131
                                                      st_atim,
1132
                                                      st_mtim,
1133
                                                      fst_flags);
1134
  args.GetReturnValue().Set(err);
1135
}
1136
1137
1138
void WASI::PathLink(const FunctionCallbackInfo<Value>& args) {
1139
  WASI* wasi;
1140
  uint32_t old_fd;
1141
  uint32_t old_flags;
1142
  uint32_t old_path_ptr;
1143
  uint32_t old_path_len;
1144
  uint32_t new_fd;
1145
  uint32_t new_path_ptr;
1146
  uint32_t new_path_len;
1147
  char* memory;
1148
  size_t mem_size;
1149
  RETURN_IF_BAD_ARG_COUNT(args, 7);
1150
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, old_fd);
1151
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, old_flags);
1152
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, old_path_ptr);
1153
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, old_path_len);
1154
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, new_fd);
1155
  CHECK_TO_TYPE_OR_RETURN(args, args[5], Uint32, new_path_ptr);
1156
  CHECK_TO_TYPE_OR_RETURN(args, args[6], Uint32, new_path_len);
1157
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
1158
  Debug(wasi,
1159
        "path_link(%d, %d, %d, %d, %d, %d, %d)\n",
1160
        old_fd,
1161
        old_flags,
1162
        old_path_ptr,
1163
        old_path_len,
1164
        new_fd,
1165
        new_path_ptr,
1166
        new_path_len);
1167
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1168
  CHECK_BOUNDS_OR_RETURN(args, mem_size, old_path_ptr, old_path_len);
1169
  CHECK_BOUNDS_OR_RETURN(args, mem_size, new_path_ptr, new_path_len);
1170
  uvwasi_errno_t err = uvwasi_path_link(&wasi->uvw_,
1171
                                        old_fd,
1172
                                        old_flags,
1173
                                        &memory[old_path_ptr],
1174
                                        old_path_len,
1175
                                        new_fd,
1176
                                        &memory[new_path_ptr],
1177
                                        new_path_len);
1178
  args.GetReturnValue().Set(err);
1179
}
1180
1181
1182
13
void WASI::PathOpen(const FunctionCallbackInfo<Value>& args) {
1183
  WASI* wasi;
1184
  uint32_t dirfd;
1185
  uint32_t dirflags;
1186
  uint32_t path_ptr;
1187
  uint32_t path_len;
1188
  uint32_t o_flags;
1189
  uint64_t fs_rights_base;
1190
  uint64_t fs_rights_inheriting;
1191
  uint32_t fs_flags;
1192
  uint32_t fd_ptr;
1193
  char* memory;
1194
  size_t mem_size;
1195
13
  RETURN_IF_BAD_ARG_COUNT(args, 9);
1196
65
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, dirfd);
1197
65
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, dirflags);
1198
65
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_ptr);
1199
65
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, path_len);
1200
65
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, o_flags);
1201
65
  UNWRAP_BIGINT_OR_RETURN(args, args[5], Uint64, fs_rights_base);
1202
65
  UNWRAP_BIGINT_OR_RETURN(args, args[6], Uint64, fs_rights_inheriting);
1203
65
  CHECK_TO_TYPE_OR_RETURN(args, args[7], Uint32, fs_flags);
1204
65
  CHECK_TO_TYPE_OR_RETURN(args, args[8], Uint32, fd_ptr);
1205
13
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
1206
  Debug(wasi,
1207
        "path_open(%d, %d, %d, %d, %d, %d, %d, %d, %d)\n",
1208
        dirfd,
1209
        dirflags,
1210
        path_ptr,
1211
        path_len,
1212
        o_flags,
1213
        fs_rights_base,
1214
        fs_rights_inheriting,
1215
        fs_flags,
1216
13
        fd_ptr);
1217
13
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1218
13
  CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len);
1219
13
  CHECK_BOUNDS_OR_RETURN(args, mem_size, fd_ptr, 4);
1220
  uvwasi_fd_t fd;
1221
26
  uvwasi_errno_t err = uvwasi_path_open(&wasi->uvw_,
1222
                                        dirfd,
1223
                                        dirflags,
1224
13
                                        &memory[path_ptr],
1225
                                        path_len,
1226
                                        static_cast<uvwasi_oflags_t>(o_flags),
1227
                                        fs_rights_base,
1228
                                        fs_rights_inheriting,
1229
                                        static_cast<uvwasi_fdflags_t>(fs_flags),
1230
13
                                        &fd);
1231
13
  if (err == UVWASI_ESUCCESS)
1232
9
    wasi->writeUInt32(memory, fd, fd_ptr);
1233
1234
39
  args.GetReturnValue().Set(err);
1235
}
1236
1237
1238
1
void WASI::PathReadlink(const FunctionCallbackInfo<Value>& args) {
1239
  WASI* wasi;
1240
  uint32_t fd;
1241
  uint32_t path_ptr;
1242
  uint32_t path_len;
1243
  uint32_t buf_ptr;
1244
  uint32_t buf_len;
1245
  uint32_t bufused_ptr;
1246
  char* memory;
1247
  size_t mem_size;
1248
1
  RETURN_IF_BAD_ARG_COUNT(args, 6);
1249
5
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
1250
5
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, path_ptr);
1251
5
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_len);
1252
5
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, buf_ptr);
1253
5
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, buf_len);
1254
5
  CHECK_TO_TYPE_OR_RETURN(args, args[5], Uint32, bufused_ptr);
1255
1
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
1256
  Debug(wasi,
1257
        "path_readlink(%d, %d, %d, %d, %d, %d)\n",
1258
        fd,
1259
        path_ptr,
1260
        path_len,
1261
        buf_ptr,
1262
        buf_len,
1263
1
        bufused_ptr);
1264
1
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1265
1
  CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len);
1266
1
  CHECK_BOUNDS_OR_RETURN(args, mem_size, buf_ptr, buf_len);
1267
1
  CHECK_BOUNDS_OR_RETURN(args, mem_size, bufused_ptr, 4);
1268
  size_t bufused;
1269
2
  uvwasi_errno_t err = uvwasi_path_readlink(&wasi->uvw_,
1270
                                        fd,
1271
1
                                        &memory[path_ptr],
1272
                                        path_len,
1273
                                        &memory[buf_ptr],
1274
                                        buf_len,
1275
1
                                        &bufused);
1276
1
  if (err == UVWASI_ESUCCESS)
1277
1
    wasi->writeUInt32(memory, bufused, bufused_ptr);
1278
1279
3
  args.GetReturnValue().Set(err);
1280
}
1281
1282
1283
1
void WASI::PathRemoveDirectory(const FunctionCallbackInfo<Value>& args) {
1284
  WASI* wasi;
1285
  uint32_t fd;
1286
  uint32_t path_ptr;
1287
  uint32_t path_len;
1288
  char* memory;
1289
  size_t mem_size;
1290
1
  RETURN_IF_BAD_ARG_COUNT(args, 3);
1291
5
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
1292
5
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, path_ptr);
1293
5
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_len);
1294
1
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
1295
1
  Debug(wasi, "path_remove_directory(%d, %d, %d)\n", fd, path_ptr, path_len);
1296
1
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1297
1
  CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len);
1298
2
  uvwasi_errno_t err = uvwasi_path_remove_directory(&wasi->uvw_,
1299
                                                    fd,
1300
1
                                                    &memory[path_ptr],
1301
1
                                                    path_len);
1302
3
  args.GetReturnValue().Set(err);
1303
}
1304
1305
1306
void WASI::PathRename(const FunctionCallbackInfo<Value>& args) {
1307
  WASI* wasi;
1308
  uint32_t old_fd;
1309
  uint32_t old_path_ptr;
1310
  uint32_t old_path_len;
1311
  uint32_t new_fd;
1312
  uint32_t new_path_ptr;
1313
  uint32_t new_path_len;
1314
  char* memory;
1315
  size_t mem_size;
1316
  RETURN_IF_BAD_ARG_COUNT(args, 6);
1317
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, old_fd);
1318
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, old_path_ptr);
1319
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, old_path_len);
1320
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, new_fd);
1321
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, new_path_ptr);
1322
  CHECK_TO_TYPE_OR_RETURN(args, args[5], Uint32, new_path_len);
1323
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
1324
  Debug(wasi,
1325
        "path_rename(%d, %d, %d, %d, %d, %d)\n",
1326
        old_fd,
1327
        old_path_ptr,
1328
        old_path_len,
1329
        new_fd,
1330
        new_path_ptr,
1331
        new_path_len);
1332
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1333
  CHECK_BOUNDS_OR_RETURN(args, mem_size, old_path_ptr, old_path_len);
1334
  CHECK_BOUNDS_OR_RETURN(args, mem_size, new_path_ptr, new_path_len);
1335
  uvwasi_errno_t err = uvwasi_path_rename(&wasi->uvw_,
1336
                                          old_fd,
1337
                                          &memory[old_path_ptr],
1338
                                          old_path_len,
1339
                                          new_fd,
1340
                                          &memory[new_path_ptr],
1341
                                          new_path_len);
1342
  args.GetReturnValue().Set(err);
1343
}
1344
1345
1346
1
void WASI::PathSymlink(const FunctionCallbackInfo<Value>& args) {
1347
  WASI* wasi;
1348
  uint32_t old_path_ptr;
1349
  uint32_t old_path_len;
1350
  uint32_t fd;
1351
  uint32_t new_path_ptr;
1352
  uint32_t new_path_len;
1353
  char* memory;
1354
  size_t mem_size;
1355
1
  RETURN_IF_BAD_ARG_COUNT(args, 5);
1356
5
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, old_path_ptr);
1357
5
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, old_path_len);
1358
5
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, fd);
1359
5
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, new_path_ptr);
1360
5
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, new_path_len);
1361
1
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
1362
  Debug(wasi,
1363
        "path_symlink(%d, %d, %d, %d, %d)\n",
1364
        old_path_ptr,
1365
        old_path_len,
1366
        fd,
1367
        new_path_ptr,
1368
1
        new_path_len);
1369
1
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1370
1
  CHECK_BOUNDS_OR_RETURN(args, mem_size, old_path_ptr, old_path_len);
1371
1
  CHECK_BOUNDS_OR_RETURN(args, mem_size, new_path_ptr, new_path_len);
1372
3
  uvwasi_errno_t err = uvwasi_path_symlink(&wasi->uvw_,
1373
1
                                           &memory[old_path_ptr],
1374
                                           old_path_len,
1375
                                           fd,
1376
1
                                           &memory[new_path_ptr],
1377
1
                                           new_path_len);
1378
3
  args.GetReturnValue().Set(err);
1379
}
1380
1381
1382
1
void WASI::PathUnlinkFile(const FunctionCallbackInfo<Value>& args) {
1383
  WASI* wasi;
1384
  uint32_t fd;
1385
  uint32_t path_ptr;
1386
  uint32_t path_len;
1387
  char* memory;
1388
  size_t mem_size;
1389
1
  RETURN_IF_BAD_ARG_COUNT(args, 3);
1390
5
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
1391
5
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, path_ptr);
1392
5
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_len);
1393
1
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
1394
1
  Debug(wasi, "path_unlink_file(%d, %d, %d)\n", fd, path_ptr, path_len);
1395
1
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1396
1
  CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len);
1397
2
  uvwasi_errno_t err = uvwasi_path_unlink_file(&wasi->uvw_,
1398
                                               fd,
1399
1
                                               &memory[path_ptr],
1400
1
                                               path_len);
1401
3
  args.GetReturnValue().Set(err);
1402
}
1403
1404
1405
void WASI::PollOneoff(const FunctionCallbackInfo<Value>& args) {
1406
  WASI* wasi;
1407
  uint32_t in_ptr;
1408
  uint32_t out_ptr;
1409
  uint32_t nsubscriptions;
1410
  uint32_t nevents_ptr;
1411
  char* memory;
1412
  size_t mem_size;
1413
  RETURN_IF_BAD_ARG_COUNT(args, 4);
1414
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, in_ptr);
1415
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, out_ptr);
1416
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, nsubscriptions);
1417
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, nevents_ptr);
1418
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
1419
  Debug(wasi,
1420
        "poll_oneoff(%d, %d, %d, %d)\n",
1421
        in_ptr,
1422
        out_ptr,
1423
        nsubscriptions,
1424
        nevents_ptr);
1425
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1426
  CHECK_BOUNDS_OR_RETURN(args, mem_size, in_ptr, nsubscriptions * 48);
1427
  CHECK_BOUNDS_OR_RETURN(args, mem_size, out_ptr, nsubscriptions * 32);
1428
  CHECK_BOUNDS_OR_RETURN(args, mem_size, nevents_ptr, 4);
1429
  uvwasi_subscription_t* in =
1430
      UncheckedCalloc<uvwasi_subscription_t>(nsubscriptions);
1431
1432
  if (in == nullptr) {
1433
    args.GetReturnValue().Set(UVWASI_ENOMEM);
1434
    return;
1435
  }
1436
1437
  uvwasi_event_t* out = UncheckedCalloc<uvwasi_event_t>(nsubscriptions);
1438
1439
  if (out == nullptr) {
1440
    free(in);
1441
    args.GetReturnValue().Set(UVWASI_ENOMEM);
1442
    return;
1443
  }
1444
1445
  for (uint32_t i = 0; i < nsubscriptions; ++i) {
1446
    uvwasi_subscription_t sub = in[i];
1447
    wasi->readUInt64(memory, &sub.userdata, in_ptr);
1448
    wasi->readUInt8(memory, &sub.type, in_ptr + 8);
1449
1450
    if (sub.type == UVWASI_EVENTTYPE_CLOCK) {
1451
      wasi->readUInt32(memory, &sub.u.clock.clock_id, in_ptr + 16);
1452
      wasi->readUInt64(memory, &sub.u.clock.timeout, in_ptr + 24);
1453
      wasi->readUInt64(memory, &sub.u.clock.precision, in_ptr + 32);
1454
      wasi->readUInt16(memory, &sub.u.clock.flags, in_ptr + 40);
1455
    } else if (sub.type == UVWASI_EVENTTYPE_FD_READ ||
1456
               sub.type == UVWASI_EVENTTYPE_FD_WRITE) {
1457
      wasi->readUInt32(memory, &sub.u.fd_readwrite.fd, in_ptr + 16);
1458
    }
1459
1460
    in_ptr += 56;
1461
  }
1462
1463
  size_t nevents;
1464
  uvwasi_errno_t err = uvwasi_poll_oneoff(&wasi->uvw_,
1465
                                          in,
1466
                                          out,
1467
                                          nsubscriptions,
1468
                                          &nevents);
1469
  if (err == UVWASI_ESUCCESS) {
1470
    wasi->writeUInt32(memory, nevents, nevents_ptr);
1471
1472
    for (uint32_t i = 0; i < nsubscriptions; ++i) {
1473
      uvwasi_event_t event = out[i];
1474
1475
      wasi->writeUInt64(memory, event.userdata, out_ptr);
1476
      wasi->writeUInt16(memory, event.error, out_ptr + 8);
1477
      wasi->writeUInt8(memory, event.type, out_ptr + 10);
1478
1479
      if (event.type == UVWASI_EVENTTYPE_FD_READ ||
1480
          event.type == UVWASI_EVENTTYPE_FD_WRITE) {
1481
        wasi->writeUInt64(memory, event.u.fd_readwrite.nbytes, out_ptr + 16);
1482
        wasi->writeUInt16(memory, event.u.fd_readwrite.flags, out_ptr + 24);
1483
      }
1484
1485
      out_ptr += 32;
1486
    }
1487
  }
1488
1489
  free(in);
1490
  free(out);
1491
  args.GetReturnValue().Set(err);
1492
}
1493
1494
1495
1
void WASI::ProcExit(const FunctionCallbackInfo<Value>& args) {
1496
  WASI* wasi;
1497
  uint32_t code;
1498
1
  RETURN_IF_BAD_ARG_COUNT(args, 1);
1499
5
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, code);
1500
1
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
1501
1
  Debug(wasi, "proc_exit(%d)\n", code);
1502
1
  args.GetReturnValue().Set(uvwasi_proc_exit(&wasi->uvw_, code));
1503
}
1504
1505
1506
void WASI::ProcRaise(const FunctionCallbackInfo<Value>& args) {
1507
  WASI* wasi;
1508
  uint32_t sig;
1509
  RETURN_IF_BAD_ARG_COUNT(args, 1);
1510
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, sig);
1511
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
1512
  Debug(wasi, "proc_raise(%d)\n", sig);
1513
  uvwasi_errno_t err = uvwasi_proc_raise(&wasi->uvw_, sig);
1514
  args.GetReturnValue().Set(err);
1515
}
1516
1517
1518
1
void WASI::RandomGet(const FunctionCallbackInfo<Value>& args) {
1519
  WASI* wasi;
1520
  uint32_t buf_ptr;
1521
  uint32_t buf_len;
1522
  char* memory;
1523
  size_t mem_size;
1524
1
  RETURN_IF_BAD_ARG_COUNT(args, 2);
1525
5
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, buf_ptr);
1526
5
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, buf_len);
1527
1
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
1528
1
  Debug(wasi, "random_get(%d, %d)\n", buf_ptr, buf_len);
1529
1
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1530
1
  CHECK_BOUNDS_OR_RETURN(args, mem_size, buf_ptr, buf_len);
1531
2
  uvwasi_errno_t err = uvwasi_random_get(&wasi->uvw_,
1532
1
                                         &memory[buf_ptr],
1533
1
                                         buf_len);
1534
3
  args.GetReturnValue().Set(err);
1535
}
1536
1537
1538
void WASI::SchedYield(const FunctionCallbackInfo<Value>& args) {
1539
  WASI* wasi;
1540
  RETURN_IF_BAD_ARG_COUNT(args, 0);
1541
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
1542
  Debug(wasi, "sched_yield()\n");
1543
  uvwasi_errno_t err = uvwasi_sched_yield(&wasi->uvw_);
1544
  args.GetReturnValue().Set(err);
1545
}
1546
1547
1548
void WASI::SockRecv(const FunctionCallbackInfo<Value>& args) {
1549
  WASI* wasi;
1550
  uint32_t sock;
1551
  uint32_t ri_data_ptr;
1552
  uint32_t ri_data_len;
1553
  uint16_t ri_flags;
1554
  uint32_t ro_datalen_ptr;
1555
  uint16_t ro_flags_ptr;
1556
  char* memory;
1557
  size_t mem_size;
1558
  RETURN_IF_BAD_ARG_COUNT(args, 6);
1559
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, sock);
1560
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, ri_data_ptr);
1561
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, ri_data_len);
1562
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, ri_flags);
1563
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, ro_datalen_ptr);
1564
  CHECK_TO_TYPE_OR_RETURN(args, args[5], Uint32, ro_flags_ptr);
1565
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
1566
  Debug(wasi,
1567
        "sock_recv(%d, %d, %d, %d, %d, %d)\n",
1568
        sock,
1569
        ri_data_ptr,
1570
        ri_data_len,
1571
        ri_flags,
1572
        ro_datalen_ptr,
1573
        ro_flags_ptr);
1574
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1575
  CHECK_BOUNDS_OR_RETURN(args, mem_size, ri_data_ptr, ri_data_len * 8);
1576
  CHECK_BOUNDS_OR_RETURN(args, mem_size, ro_datalen_ptr, 4);
1577
  CHECK_BOUNDS_OR_RETURN(args, mem_size, ro_flags_ptr, 4);
1578
  uvwasi_iovec_t* ri_data = UncheckedCalloc<uvwasi_iovec_t>(ri_data_len);
1579
1580
  if (ri_data == nullptr) {
1581
    args.GetReturnValue().Set(UVWASI_ENOMEM);
1582
    return;
1583
  }
1584
1585
  for (uint32_t i = 0; i < ri_data_len; ++i) {
1586
    uint32_t buf_ptr;
1587
    uint32_t buf_len;
1588
1589
    wasi->readUInt32(memory, &buf_ptr, ri_data_ptr);
1590
    wasi->readUInt32(memory, &buf_len, ri_data_ptr + 4);
1591
1592
    if (is_access_oob(mem_size, buf_ptr, buf_len)) {
1593
      free(ri_data);
1594
      args.GetReturnValue().Set(UVWASI_EOVERFLOW);
1595
      return;
1596
    }
1597
1598
    ri_data_ptr += 8;
1599
    ri_data[i].buf = static_cast<void*>(&memory[buf_ptr]);
1600
    ri_data[i].buf_len = buf_len;
1601
  }
1602
1603
  size_t ro_datalen;
1604
  uvwasi_roflags_t ro_flags;
1605
  uvwasi_errno_t err = uvwasi_sock_recv(&wasi->uvw_,
1606
                                        sock,
1607
                                        ri_data,
1608
                                        ri_data_len,
1609
                                        ri_flags,
1610
                                        &ro_datalen,
1611
                                        &ro_flags);
1612
  if (err == UVWASI_ESUCCESS) {
1613
    wasi->writeUInt32(memory, ro_datalen, ro_datalen_ptr);
1614
    wasi->writeUInt32(memory, ro_flags, ro_flags_ptr);
1615
  }
1616
1617
  free(ri_data);
1618
  args.GetReturnValue().Set(err);
1619
}
1620
1621
1622
void WASI::SockSend(const FunctionCallbackInfo<Value>& args) {
1623
  WASI* wasi;
1624
  uint32_t sock;
1625
  uint32_t si_data_ptr;
1626
  uint32_t si_data_len;
1627
  uint16_t si_flags;
1628
  uint32_t so_datalen_ptr;
1629
  char* memory;
1630
  size_t mem_size;
1631
  RETURN_IF_BAD_ARG_COUNT(args, 5);
1632
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, sock);
1633
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, si_data_ptr);
1634
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, si_data_len);
1635
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, si_flags);
1636
  CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, so_datalen_ptr);
1637
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
1638
  Debug(wasi,
1639
        "sock_send(%d, %d, %d, %d, %d)\n",
1640
        sock,
1641
        si_data_ptr,
1642
        si_data_len,
1643
        si_flags,
1644
        so_datalen_ptr);
1645
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1646
  CHECK_BOUNDS_OR_RETURN(args, mem_size, si_data_ptr, si_data_len * 8);
1647
  CHECK_BOUNDS_OR_RETURN(args, mem_size, so_datalen_ptr, 4);
1648
  uvwasi_ciovec_t* si_data = UncheckedCalloc<uvwasi_ciovec_t>(si_data_len);
1649
1650
  if (si_data == nullptr) {
1651
    args.GetReturnValue().Set(UVWASI_ENOMEM);
1652
    return;
1653
  }
1654
1655
  for (uint32_t i = 0; i < si_data_len; ++i) {
1656
    uint32_t buf_ptr;
1657
    uint32_t buf_len;
1658
1659
    wasi->readUInt32(memory, &buf_ptr, si_data_ptr);
1660
    wasi->readUInt32(memory, &buf_len, si_data_ptr + 4);
1661
1662
    if (is_access_oob(mem_size, buf_ptr, buf_len)) {
1663
      free(si_data);
1664
      args.GetReturnValue().Set(UVWASI_EOVERFLOW);
1665
      return;
1666
    }
1667
1668
    si_data_ptr += 8;
1669
    si_data[i].buf = static_cast<void*>(&memory[buf_ptr]);
1670
    si_data[i].buf_len = buf_len;
1671
  }
1672
1673
  size_t so_datalen;
1674
  uvwasi_errno_t err = uvwasi_sock_send(&wasi->uvw_,
1675
                                        sock,
1676
                                        si_data,
1677
                                        si_data_len,
1678
                                        si_flags,
1679
                                        &so_datalen);
1680
  if (err == UVWASI_ESUCCESS)
1681
    wasi->writeUInt32(memory, so_datalen, so_datalen_ptr);
1682
1683
  free(si_data);
1684
  args.GetReturnValue().Set(err);
1685
}
1686
1687
1688
void WASI::SockShutdown(const FunctionCallbackInfo<Value>& args) {
1689
  WASI* wasi;
1690
  uint32_t sock;
1691
  uint8_t how;
1692
  RETURN_IF_BAD_ARG_COUNT(args, 2);
1693
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, sock);
1694
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, how);
1695
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
1696
  Debug(wasi, "sock_shutdown(%d, %d)\n", sock, how);
1697
  uvwasi_errno_t err = uvwasi_sock_shutdown(&wasi->uvw_, sock, how);
1698
  args.GetReturnValue().Set(err);
1699
}
1700
1701
1702
22
void WASI::_SetMemory(const FunctionCallbackInfo<Value>& args) {
1703
  WASI* wasi;
1704
22
  CHECK_EQ(args.Length(), 1);
1705
44
  CHECK(args[0]->IsObject());
1706
22
  ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This());
1707
66
  wasi->memory_.Reset(wasi->env()->isolate(), args[0].As<Object>());
1708
}
1709
1710
1711
void WASI::readUInt8(char* memory, uint8_t* value, uint32_t offset) {
1712
  CHECK_NOT_NULL(memory);
1713
  CHECK_NOT_NULL(value);
1714
  *value = memory[offset] & 0xFF;
1715
}
1716
1717
1718
void WASI::readUInt16(char* memory, uint16_t* value, uint32_t offset) {
1719
  CHECK_NOT_NULL(memory);
1720
  CHECK_NOT_NULL(value);
1721
  *value = (memory[offset] & 0xFF) |
1722
           ((memory[offset + 1] & 0xFF) << 8);
1723
}
1724
1725
1726
62
void WASI::readUInt32(char* memory, uint32_t* value, uint32_t offset) {
1727
62
  CHECK_NOT_NULL(memory);
1728
62
  CHECK_NOT_NULL(value);
1729
186
  *value = (memory[offset] & 0xFF) |
1730
124
           ((memory[offset + 1] & 0xFF) << 8) |
1731
124
           ((memory[offset + 2] & 0xFF) << 16) |
1732
62
           ((memory[offset + 3] & 0xFF) << 24);
1733
62
}
1734
1735
1736
void WASI::readUInt64(char* memory, uint64_t* value, uint32_t offset) {
1737
  CHECK_NOT_NULL(memory);
1738
  CHECK_NOT_NULL(value);
1739
  uint64_t low = (memory[offset] & 0xFF) |
1740
                 ((memory[offset + 1] & 0xFF) << 8) |
1741
                 ((memory[offset + 2] & 0xFF) << 16) |
1742
                 ((memory[offset + 3] & 0xFF) << 24);
1743
  uint64_t high = (memory[offset + 4] & 0xFF) |
1744
                  ((memory[offset + 5] & 0xFF) << 8) |
1745
                  ((memory[offset + 6] & 0xFF) << 16) |
1746
                  ((memory[offset + 7] & 0xFF) << 24);
1747
  *value = (high << 32) + low;
1748
}
1749
1750
1751
27
void WASI::writeUInt8(char* memory, uint8_t value, uint32_t offset) {
1752
27
  CHECK_NOT_NULL(memory);
1753
27
  memory[offset] = value & 0xFF;
1754
27
}
1755
1756
1757
23
void WASI::writeUInt16(char* memory, uint16_t value, uint32_t offset) {
1758
23
  CHECK_NOT_NULL(memory);
1759
23
  memory[offset++] = value & 0xFF;
1760
23
  memory[offset] = (value >> 8) & 0xFF;
1761
23
}
1762
1763
1764
1530
void WASI::writeUInt32(char* memory, uint32_t value, uint32_t offset) {
1765
1530
  CHECK_NOT_NULL(memory);
1766
1530
  memory[offset++] = value & 0xFF;
1767
1530
  memory[offset++] = (value >> 8) & 0xFF;
1768
1530
  memory[offset++] = (value >> 16) & 0xFF;
1769
1530
  memory[offset] = (value >> 24) & 0xFF;
1770
1530
}
1771
1772
1773
83
void WASI::writeUInt64(char* memory, uint64_t value, uint32_t offset) {
1774
83
  CHECK_NOT_NULL(memory);
1775
83
  memory[offset++] = value & 0xFF;
1776
83
  memory[offset++] = (value >> 8) & 0xFF;
1777
83
  memory[offset++] = (value >> 16) & 0xFF;
1778
83
  memory[offset++] = (value >> 24) & 0xFF;
1779
83
  memory[offset++] = (value >> 32) & 0xFF;
1780
83
  memory[offset++] = (value >> 40) & 0xFF;
1781
83
  memory[offset++] = (value >> 48) & 0xFF;
1782
83
  memory[offset] = (value >> 56) & 0xFF;
1783
83
}
1784
1785
1786
214
uvwasi_errno_t WASI::backingStore(char** store, size_t* byte_length) {
1787
214
  Environment* env = this->env();
1788
214
  Local<Object> memory = PersistentToLocal::Strong(this->memory_);
1789
  Local<Value> prop;
1790
1791
856
  if (!memory->Get(env->context(), env->buffer_string()).ToLocal(&prop))
1792
    return UVWASI_EINVAL;
1793
1794
214
  if (!prop->IsArrayBuffer())
1795
    return UVWASI_EINVAL;
1796
1797
214
  Local<ArrayBuffer> ab = prop.As<ArrayBuffer>();
1798
428
  std::shared_ptr<BackingStore> backing_store = ab->GetBackingStore();
1799
214
  *byte_length = backing_store->ByteLength();
1800
214
  *store = static_cast<char*>(backing_store->Data());
1801
214
  return UVWASI_ESUCCESS;
1802
}
1803
1804
1805
22
static void Initialize(Local<Object> target,
1806
                       Local<Value> unused,
1807
                       Local<Context> context,
1808
                       void* priv) {
1809
22
  Environment* env = Environment::GetCurrent(context);
1810
1811
22
  Local<FunctionTemplate> tmpl = env->NewFunctionTemplate(WASI::New);
1812
22
  auto wasi_wrap_string = FIXED_ONE_BYTE_STRING(env->isolate(), "WASI");
1813
44
  tmpl->InstanceTemplate()->SetInternalFieldCount(1);
1814
22
  tmpl->SetClassName(wasi_wrap_string);
1815
1816
22
  env->SetProtoMethod(tmpl, "args_get", WASI::ArgsGet);
1817
22
  env->SetProtoMethod(tmpl, "args_sizes_get", WASI::ArgsSizesGet);
1818
22
  env->SetProtoMethod(tmpl, "clock_res_get", WASI::ClockResGet);
1819
22
  env->SetProtoMethod(tmpl, "clock_time_get", WASI::ClockTimeGet);
1820
22
  env->SetProtoMethod(tmpl, "environ_get", WASI::EnvironGet);
1821
22
  env->SetProtoMethod(tmpl, "environ_sizes_get", WASI::EnvironSizesGet);
1822
22
  env->SetProtoMethod(tmpl, "fd_advise", WASI::FdAdvise);
1823
22
  env->SetProtoMethod(tmpl, "fd_allocate", WASI::FdAllocate);
1824
22
  env->SetProtoMethod(tmpl, "fd_close", WASI::FdClose);
1825
22
  env->SetProtoMethod(tmpl, "fd_datasync", WASI::FdDatasync);
1826
22
  env->SetProtoMethod(tmpl, "fd_fdstat_get", WASI::FdFdstatGet);
1827
22
  env->SetProtoMethod(tmpl, "fd_fdstat_set_flags", WASI::FdFdstatSetFlags);
1828
22
  env->SetProtoMethod(tmpl, "fd_fdstat_set_rights", WASI::FdFdstatSetRights);
1829
22
  env->SetProtoMethod(tmpl, "fd_filestat_get", WASI::FdFilestatGet);
1830
22
  env->SetProtoMethod(tmpl, "fd_filestat_set_size", WASI::FdFilestatSetSize);
1831
22
  env->SetProtoMethod(tmpl, "fd_filestat_set_times", WASI::FdFilestatSetTimes);
1832
22
  env->SetProtoMethod(tmpl, "fd_pread", WASI::FdPread);
1833
22
  env->SetProtoMethod(tmpl, "fd_prestat_get", WASI::FdPrestatGet);
1834
22
  env->SetProtoMethod(tmpl, "fd_prestat_dir_name", WASI::FdPrestatDirName);
1835
22
  env->SetProtoMethod(tmpl, "fd_pwrite", WASI::FdPwrite);
1836
22
  env->SetProtoMethod(tmpl, "fd_read", WASI::FdRead);
1837
22
  env->SetProtoMethod(tmpl, "fd_readdir", WASI::FdReaddir);
1838
22
  env->SetProtoMethod(tmpl, "fd_renumber", WASI::FdRenumber);
1839
22
  env->SetProtoMethod(tmpl, "fd_seek", WASI::FdSeek);
1840
22
  env->SetProtoMethod(tmpl, "fd_sync", WASI::FdSync);
1841
22
  env->SetProtoMethod(tmpl, "fd_tell", WASI::FdTell);
1842
22
  env->SetProtoMethod(tmpl, "fd_write", WASI::FdWrite);
1843
22
  env->SetProtoMethod(tmpl, "path_create_directory", WASI::PathCreateDirectory);
1844
22
  env->SetProtoMethod(tmpl, "path_filestat_get", WASI::PathFilestatGet);
1845
  env->SetProtoMethod(tmpl,
1846
                      "path_filestat_set_times",
1847
22
                      WASI::PathFilestatSetTimes);
1848
22
  env->SetProtoMethod(tmpl, "path_link", WASI::PathLink);
1849
22
  env->SetProtoMethod(tmpl, "path_open", WASI::PathOpen);
1850
22
  env->SetProtoMethod(tmpl, "path_readlink", WASI::PathReadlink);
1851
22
  env->SetProtoMethod(tmpl, "path_remove_directory", WASI::PathRemoveDirectory);
1852
22
  env->SetProtoMethod(tmpl, "path_rename", WASI::PathRename);
1853
22
  env->SetProtoMethod(tmpl, "path_symlink", WASI::PathSymlink);
1854
22
  env->SetProtoMethod(tmpl, "path_unlink_file", WASI::PathUnlinkFile);
1855
22
  env->SetProtoMethod(tmpl, "poll_oneoff", WASI::PollOneoff);
1856
22
  env->SetProtoMethod(tmpl, "proc_exit", WASI::ProcExit);
1857
22
  env->SetProtoMethod(tmpl, "proc_raise", WASI::ProcRaise);
1858
22
  env->SetProtoMethod(tmpl, "random_get", WASI::RandomGet);
1859
22
  env->SetProtoMethod(tmpl, "sched_yield", WASI::SchedYield);
1860
22
  env->SetProtoMethod(tmpl, "sock_recv", WASI::SockRecv);
1861
22
  env->SetProtoMethod(tmpl, "sock_send", WASI::SockSend);
1862
22
  env->SetProtoMethod(tmpl, "sock_shutdown", WASI::SockShutdown);
1863
1864
22
  env->SetInstanceMethod(tmpl, "_setMemory", WASI::_SetMemory);
1865
1866
44
  target->Set(env->context(),
1867
              wasi_wrap_string,
1868
88
              tmpl->GetFunction(context).ToLocalChecked()).ToChecked();
1869
22
}
1870
1871
1872
}  // namespace wasi
1873
}  // namespace node
1874
1875
4201
NODE_MODULE_CONTEXT_AWARE_INTERNAL(wasi, node::wasi::Initialize)