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