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

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