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: 611 844 72.4 %
Date: 2020-09-06 22:14:11 Branches: 330 900 36.7 %

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

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

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

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

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

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

46
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
397
23
  Debug(wasi, "environ_get(%d, %d)\n", environ_offset, environ_buf_offset);
398
23
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
399
23
  CHECK_BOUNDS_OR_RETURN(args,
400
                         mem_size,
401
                         environ_buf_offset,
402
                         wasi->uvw_.env_buf_size);
403
23
  CHECK_BOUNDS_OR_RETURN(args,
404
                         mem_size,
405
                         environ_offset,
406
                         wasi->uvw_.envc * UVWASI_SERDES_SIZE_uint32_t);
407
46
  std::vector<char*> environment(wasi->uvw_.envc);
408
23
  char* environ_buf = &memory[environ_buf_offset];
409
23
  uvwasi_errno_t err = uvwasi_environ_get(&wasi->uvw_,
410
                                          environment.data(),
411
23
                                          environ_buf);
412
413
23
  if (err == UVWASI_ESUCCESS) {
414
1698
    for (size_t i = 0; i < wasi->uvw_.envc; i++) {
415
1675
      uint32_t offset = environ_buf_offset + (environment[i] - environment[0]);
416
417
3350
      uvwasi_serdes_write_uint32_t(memory,
418
                                   environ_offset +
419
1675
                                   (i * UVWASI_SERDES_SIZE_uint32_t),
420
1675
                                   offset);
421
    }
422
  }
423
424
69
  args.GetReturnValue().Set(err);
425
}
426
427
428
26
void WASI::EnvironSizesGet(const FunctionCallbackInfo<Value>& args) {
429
  WASI* wasi;
430
  uint32_t envc_offset;
431
  uint32_t env_buf_offset;
432
  char* memory;
433
  size_t mem_size;
434
26
  RETURN_IF_BAD_ARG_COUNT(args, 2);
435
130
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, envc_offset);
436
130
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, env_buf_offset);
437

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

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

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

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

4
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
611
2
  Debug(wasi, "fd_filestat_set_size(%d, %d)\n", fd, st_size);
612
2
  uvwasi_errno_t err = uvwasi_fd_filestat_set_size(&wasi->uvw_, fd, st_size);
613
6
  args.GetReturnValue().Set(err);
614
}
615
616
617
1
void WASI::FdFilestatSetTimes(const FunctionCallbackInfo<Value>& args) {
618
  WASI* wasi;
619
  uint32_t fd;
620
  uint64_t st_atim;
621
  uint64_t st_mtim;
622
  uint16_t fst_flags;
623
1
  RETURN_IF_BAD_ARG_COUNT(args, 4);
624
5
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
625
5
  UNWRAP_BIGINT_OR_RETURN(args, args[1], Uint64, st_atim);
626
5
  UNWRAP_BIGINT_OR_RETURN(args, args[2], Uint64, st_mtim);
627
5
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, fst_flags);
628

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

138
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
705
68
  Debug(wasi, "fd_prestat_get(%d, %d)\n", fd, buf);
706
68
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
707
68
  CHECK_BOUNDS_OR_RETURN(args, mem_size, buf, UVWASI_SERDES_SIZE_prestat_t);
708
  uvwasi_prestat_t prestat;
709
68
  uvwasi_errno_t err = uvwasi_fd_prestat_get(&wasi->uvw_, fd, &prestat);
710
711
68
  if (err == UVWASI_ESUCCESS)
712
42
    uvwasi_serdes_write_prestat_t(memory, buf, &prestat);
713
714
204
  args.GetReturnValue().Set(err);
715
}
716
717
718
42
void WASI::FdPrestatDirName(const FunctionCallbackInfo<Value>& args) {
719
  WASI* wasi;
720
  uint32_t fd;
721
  uint32_t path_ptr;
722
  uint32_t path_len;
723
  char* memory;
724
  size_t mem_size;
725
42
  RETURN_IF_BAD_ARG_COUNT(args, 3);
726
210
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
727
210
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, path_ptr);
728
210
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_len);
729

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

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

2
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
894
1
  Debug(wasi, "fd_renumber(%d, %d)\n", from, to);
895
1
  uvwasi_errno_t err = uvwasi_fd_renumber(&wasi->uvw_, from, to);
896
3
  args.GetReturnValue().Set(err);
897
}
898
899
900
2
void WASI::FdSeek(const FunctionCallbackInfo<Value>& args) {
901
  WASI* wasi;
902
  uint32_t fd;
903
  int64_t offset;
904
  uint8_t whence;
905
  uint32_t newoffset_ptr;
906
  char* memory;
907
  size_t mem_size;
908
2
  RETURN_IF_BAD_ARG_COUNT(args, 4);
909
10
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
910
10
  UNWRAP_BIGINT_OR_RETURN(args, args[1], Int64, offset);
911
10
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, whence);
912
10
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, newoffset_ptr);
913

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

6
  ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
955
3
  Debug(wasi, "fd_tell(%d, %d)\n", fd, offset_ptr);
956
3
  GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
957
3
  CHECK_BOUNDS_OR_RETURN(args,
958
                         mem_size,
959
                         offset_ptr,
960
                         UVWASI_SERDES_SIZE_filesize_t);
961
  uvwasi_filesize_t offset;
962
3
  uvwasi_errno_t err = uvwasi_fd_tell(&wasi->uvw_, fd, &offset);
963
964
3
  if (err == UVWASI_ESUCCESS)
965
3
    uvwasi_serdes_write_filesize_t(memory, offset_ptr, offset);
966
967
9
  args.GetReturnValue().Set(err);
968
}
969
970
971
10
void WASI::FdWrite(const FunctionCallbackInfo<Value>& args) {
972
  WASI* wasi;
973
  uint32_t fd;
974
  uint32_t iovs_ptr;
975
  uint32_t iovs_len;
976
  uint32_t nwritten_ptr;
977
  char* memory;
978
  size_t mem_size;
979
10
  RETURN_IF_BAD_ARG_COUNT(args, 4);
980
50
  CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
981
50
  CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, iovs_ptr);
982
50
  CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, iovs_len);
983
50
  CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, nwritten_ptr);
984

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

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

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

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

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

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

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

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

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

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

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

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

17891
NODE_MODULE_CONTEXT_AWARE_INTERNAL(wasi, node::wasi::Initialize)