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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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