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>
Debug(WASI * wasi,Args &&...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 using v8::Array;
76 using v8::BigInt;
77 using v8::Context;
78 using v8::Exception;
79 using v8::FunctionCallbackInfo;
80 using v8::FunctionTemplate;
81 using v8::Integer;
82 using v8::Isolate;
83 using v8::Local;
84 using v8::MaybeLocal;
85 using v8::Object;
86 using v8::String;
87 using v8::Uint32;
88 using v8::Value;
89 using v8::WasmMemoryObject;
90
WASIException(Local<Context> context,int errorno,const char * syscall)91 static 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
WASI(Environment * env,Local<Object> object,uvwasi_options_t * options)120 WASI::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
~WASI()137 WASI::~WASI() {
138 uvwasi_destroy(&uvw_);
139 CHECK_EQ(current_uvwasi_memory_, 0);
140 }
141
MemoryInfo(MemoryTracker * tracker) const142 void WASI::MemoryInfo(MemoryTracker* tracker) const {
143 tracker->TrackField("memory", memory_);
144 tracker->TrackFieldWithSize("uvwasi_memory", current_uvwasi_memory_);
145 }
146
CheckAllocatedSize(size_t previous_size) const147 void WASI::CheckAllocatedSize(size_t previous_size) const {
148 CHECK_GE(current_uvwasi_memory_, previous_size);
149 }
150
IncreaseAllocatedSize(size_t size)151 void WASI::IncreaseAllocatedSize(size_t size) {
152 current_uvwasi_memory_ += size;
153 }
154
DecreaseAllocatedSize(size_t size)155 void WASI::DecreaseAllocatedSize(size_t size) {
156 current_uvwasi_memory_ -= size;
157 }
158
New(const FunctionCallbackInfo<Value> & args)159 void 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
ArgsGet(const FunctionCallbackInfo<Value> & args)251 void WASI::ArgsGet(const FunctionCallbackInfo<Value>& args) {
252 WASI* wasi;
253 uint32_t argv_offset;
254 uint32_t argv_buf_offset;
255 char* memory;
256 size_t mem_size;
257 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
ArgsSizesGet(const FunctionCallbackInfo<Value> & args)290 void WASI::ArgsSizesGet(const FunctionCallbackInfo<Value>& args) {
291 WASI* wasi;
292 uint32_t argc_offset;
293 uint32_t argv_buf_offset;
294 char* memory;
295 size_t mem_size;
296 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
ClockResGet(const FunctionCallbackInfo<Value> & args)324 void WASI::ClockResGet(const FunctionCallbackInfo<Value>& args) {
325 WASI* wasi;
326 uint32_t clock_id;
327 uint32_t resolution_ptr;
328 char* memory;
329 size_t mem_size;
330 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
ClockTimeGet(const FunctionCallbackInfo<Value> & args)351 void WASI::ClockTimeGet(const FunctionCallbackInfo<Value>& args) {
352 WASI* wasi;
353 uint32_t clock_id;
354 uint64_t precision;
355 uint32_t time_ptr;
356 char* memory;
357 size_t mem_size;
358 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
EnvironGet(const FunctionCallbackInfo<Value> & args)381 void WASI::EnvironGet(const FunctionCallbackInfo<Value>& args) {
382 WASI* wasi;
383 uint32_t environ_offset;
384 uint32_t environ_buf_offset;
385 char* memory;
386 size_t mem_size;
387 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
EnvironSizesGet(const FunctionCallbackInfo<Value> & args)423 void WASI::EnvironSizesGet(const FunctionCallbackInfo<Value>& args) {
424 WASI* wasi;
425 uint32_t envc_offset;
426 uint32_t env_buf_offset;
427 char* memory;
428 size_t mem_size;
429 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
FdAdvise(const FunctionCallbackInfo<Value> & args)457 void WASI::FdAdvise(const FunctionCallbackInfo<Value>& args) {
458 WASI* wasi;
459 uint32_t fd;
460 uint64_t offset;
461 uint64_t len;
462 uint8_t advice;
463 RETURN_IF_BAD_ARG_COUNT(args, 4);
464 CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
465 UNWRAP_BIGINT_OR_RETURN(args, args[1], Uint64, offset);
466 UNWRAP_BIGINT_OR_RETURN(args, args[2], Uint64, len);
467 CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, advice);
468 ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
469 Debug(wasi, "fd_advise(%d, %d, %d, %d)\n", fd, offset, len, advice);
470 uvwasi_errno_t err = uvwasi_fd_advise(&wasi->uvw_, fd, offset, len, advice);
471 args.GetReturnValue().Set(err);
472 }
473
474
FdAllocate(const FunctionCallbackInfo<Value> & args)475 void WASI::FdAllocate(const FunctionCallbackInfo<Value>& args) {
476 WASI* wasi;
477 uint32_t fd;
478 uint64_t offset;
479 uint64_t len;
480 RETURN_IF_BAD_ARG_COUNT(args, 3);
481 CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
482 UNWRAP_BIGINT_OR_RETURN(args, args[1], Uint64, offset);
483 UNWRAP_BIGINT_OR_RETURN(args, args[2], Uint64, len);
484 ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
485 Debug(wasi, "fd_allocate(%d, %d, %d)\n", fd, offset, len);
486 uvwasi_errno_t err = uvwasi_fd_allocate(&wasi->uvw_, fd, offset, len);
487 args.GetReturnValue().Set(err);
488 }
489
490
FdClose(const FunctionCallbackInfo<Value> & args)491 void 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
FdDatasync(const FunctionCallbackInfo<Value> & args)503 void WASI::FdDatasync(const FunctionCallbackInfo<Value>& args) {
504 WASI* wasi;
505 uint32_t fd;
506 RETURN_IF_BAD_ARG_COUNT(args, 1);
507 CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
508 ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
509 Debug(wasi, "fd_datasync(%d)\n", fd);
510 uvwasi_errno_t err = uvwasi_fd_datasync(&wasi->uvw_, fd);
511 args.GetReturnValue().Set(err);
512 }
513
514
FdFdstatGet(const FunctionCallbackInfo<Value> & args)515 void WASI::FdFdstatGet(const FunctionCallbackInfo<Value>& args) {
516 WASI* wasi;
517 uint32_t fd;
518 uint32_t buf;
519 char* memory;
520 size_t mem_size;
521 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
FdFdstatSetFlags(const FunctionCallbackInfo<Value> & args)538 void WASI::FdFdstatSetFlags(const FunctionCallbackInfo<Value>& args) {
539 WASI* wasi;
540 uint32_t fd;
541 uint16_t flags;
542 RETURN_IF_BAD_ARG_COUNT(args, 2);
543 CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
544 CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, flags);
545 ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
546 Debug(wasi, "fd_fdstat_set_flags(%d, %d)\n", fd, flags);
547 uvwasi_errno_t err = uvwasi_fd_fdstat_set_flags(&wasi->uvw_, fd, flags);
548 args.GetReturnValue().Set(err);
549 }
550
551
FdFdstatSetRights(const FunctionCallbackInfo<Value> & args)552 void WASI::FdFdstatSetRights(const FunctionCallbackInfo<Value>& args) {
553 WASI* wasi;
554 uint32_t fd;
555 uint64_t fs_rights_base;
556 uint64_t fs_rights_inheriting;
557 RETURN_IF_BAD_ARG_COUNT(args, 3);
558 CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
559 UNWRAP_BIGINT_OR_RETURN(args, args[1], Uint64, fs_rights_base);
560 UNWRAP_BIGINT_OR_RETURN(args, args[2], Uint64, fs_rights_inheriting);
561 ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
562 Debug(wasi,
563 "fd_fdstat_set_rights(%d, %d, %d)\n",
564 fd,
565 fs_rights_base,
566 fs_rights_inheriting);
567 uvwasi_errno_t err = uvwasi_fd_fdstat_set_rights(&wasi->uvw_,
568 fd,
569 fs_rights_base,
570 fs_rights_inheriting);
571 args.GetReturnValue().Set(err);
572 }
573
574
FdFilestatGet(const FunctionCallbackInfo<Value> & args)575 void WASI::FdFilestatGet(const FunctionCallbackInfo<Value>& args) {
576 WASI* wasi;
577 uint32_t fd;
578 uint32_t buf;
579 char* memory;
580 size_t mem_size;
581 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
FdFilestatSetSize(const FunctionCallbackInfo<Value> & args)598 void 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
FdFilestatSetTimes(const FunctionCallbackInfo<Value> & args)612 void WASI::FdFilestatSetTimes(const FunctionCallbackInfo<Value>& args) {
613 WASI* wasi;
614 uint32_t fd;
615 uint64_t st_atim;
616 uint64_t st_mtim;
617 uint16_t fst_flags;
618 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
FdPread(const FunctionCallbackInfo<Value> & args)639 void WASI::FdPread(const FunctionCallbackInfo<Value>& args) {
640 WASI* wasi;
641 uint32_t fd;
642 uint32_t iovs_ptr;
643 uint32_t iovs_len;
644 uint64_t offset;
645 uint32_t nread_ptr;
646 char* memory;
647 size_t mem_size;
648 RETURN_IF_BAD_ARG_COUNT(args, 5);
649 CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
650 CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, iovs_ptr);
651 CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, iovs_len);
652 UNWRAP_BIGINT_OR_RETURN(args, args[3], Uint64, offset);
653 CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, nread_ptr);
654 ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
655 Debug(wasi,
656 "uvwasi_fd_pread(%d, %d, %d, %d, %d)\n",
657 fd,
658 iovs_ptr,
659 iovs_len,
660 offset,
661 nread_ptr);
662 GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
663 CHECK_BOUNDS_OR_RETURN(args,
664 mem_size,
665 iovs_ptr,
666 iovs_len * UVWASI_SERDES_SIZE_iovec_t);
667 CHECK_BOUNDS_OR_RETURN(args, mem_size, nread_ptr, UVWASI_SERDES_SIZE_size_t);
668 std::vector<uvwasi_iovec_t> iovs(iovs_len);
669 uvwasi_errno_t err;
670
671 err = uvwasi_serdes_readv_iovec_t(memory,
672 mem_size,
673 iovs_ptr,
674 iovs.data(),
675 iovs_len);
676 if (err != UVWASI_ESUCCESS) {
677 args.GetReturnValue().Set(err);
678 return;
679 }
680
681 uvwasi_size_t nread;
682 err = uvwasi_fd_pread(&wasi->uvw_, fd, iovs.data(), iovs_len, offset, &nread);
683 if (err == UVWASI_ESUCCESS)
684 uvwasi_serdes_write_size_t(memory, nread_ptr, nread);
685
686 args.GetReturnValue().Set(err);
687 }
688
689
FdPrestatGet(const FunctionCallbackInfo<Value> & args)690 void WASI::FdPrestatGet(const FunctionCallbackInfo<Value>& args) {
691 WASI* wasi;
692 uint32_t fd;
693 uint32_t buf;
694 char* memory;
695 size_t mem_size;
696 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
FdPrestatDirName(const FunctionCallbackInfo<Value> & args)713 void WASI::FdPrestatDirName(const FunctionCallbackInfo<Value>& args) {
714 WASI* wasi;
715 uint32_t fd;
716 uint32_t path_ptr;
717 uint32_t path_len;
718 char* memory;
719 size_t mem_size;
720 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
FdPwrite(const FunctionCallbackInfo<Value> & args)736 void WASI::FdPwrite(const FunctionCallbackInfo<Value>& args) {
737 WASI* wasi;
738 uint32_t fd;
739 uint32_t iovs_ptr;
740 uint32_t iovs_len;
741 uint64_t offset;
742 uint32_t nwritten_ptr;
743 char* memory;
744 size_t mem_size;
745 RETURN_IF_BAD_ARG_COUNT(args, 5);
746 CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
747 CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, iovs_ptr);
748 CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, iovs_len);
749 UNWRAP_BIGINT_OR_RETURN(args, args[3], Uint64, offset);
750 CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, nwritten_ptr);
751 ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
752 Debug(wasi,
753 "uvwasi_fd_pwrite(%d, %d, %d, %d, %d)\n",
754 fd,
755 iovs_ptr,
756 iovs_len,
757 offset,
758 nwritten_ptr);
759 GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
760 CHECK_BOUNDS_OR_RETURN(args,
761 mem_size,
762 iovs_ptr,
763 iovs_len * UVWASI_SERDES_SIZE_ciovec_t);
764 CHECK_BOUNDS_OR_RETURN(args,
765 mem_size,
766 nwritten_ptr,
767 UVWASI_SERDES_SIZE_size_t);
768 std::vector<uvwasi_ciovec_t> iovs(iovs_len);
769 uvwasi_errno_t err;
770
771 err = uvwasi_serdes_readv_ciovec_t(memory,
772 mem_size,
773 iovs_ptr,
774 iovs.data(),
775 iovs_len);
776 if (err != UVWASI_ESUCCESS) {
777 args.GetReturnValue().Set(err);
778 return;
779 }
780
781 uvwasi_size_t nwritten;
782 err = uvwasi_fd_pwrite(&wasi->uvw_,
783 fd,
784 iovs.data(),
785 iovs_len,
786 offset,
787 &nwritten);
788 if (err == UVWASI_ESUCCESS)
789 uvwasi_serdes_write_size_t(memory, nwritten_ptr, nwritten);
790
791 args.GetReturnValue().Set(err);
792 }
793
794
FdRead(const FunctionCallbackInfo<Value> & args)795 void WASI::FdRead(const FunctionCallbackInfo<Value>& args) {
796 WASI* wasi;
797 uint32_t fd;
798 uint32_t iovs_ptr;
799 uint32_t iovs_len;
800 uint32_t nread_ptr;
801 char* memory;
802 size_t mem_size;
803 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
FdReaddir(const FunctionCallbackInfo<Value> & args)838 void WASI::FdReaddir(const FunctionCallbackInfo<Value>& args) {
839 WASI* wasi;
840 uint32_t fd;
841 uint32_t buf_ptr;
842 uint32_t buf_len;
843 uint64_t cookie;
844 uint32_t bufused_ptr;
845 char* memory;
846 size_t mem_size;
847 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
FdRenumber(const FunctionCallbackInfo<Value> & args)881 void 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
FdSeek(const FunctionCallbackInfo<Value> & args)895 void WASI::FdSeek(const FunctionCallbackInfo<Value>& args) {
896 WASI* wasi;
897 uint32_t fd;
898 int64_t offset;
899 uint8_t whence;
900 uint32_t newoffset_ptr;
901 char* memory;
902 size_t mem_size;
903 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
FdSync(const FunctionCallbackInfo<Value> & args)928 void WASI::FdSync(const FunctionCallbackInfo<Value>& args) {
929 WASI* wasi;
930 uint32_t fd;
931 RETURN_IF_BAD_ARG_COUNT(args, 1);
932 CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
933 ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
934 Debug(wasi, "fd_sync(%d)\n", fd);
935 uvwasi_errno_t err = uvwasi_fd_sync(&wasi->uvw_, fd);
936 args.GetReturnValue().Set(err);
937 }
938
939
FdTell(const FunctionCallbackInfo<Value> & args)940 void WASI::FdTell(const FunctionCallbackInfo<Value>& args) {
941 WASI* wasi;
942 uint32_t fd;
943 uint32_t offset_ptr;
944 char* memory;
945 size_t mem_size;
946 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
FdWrite(const FunctionCallbackInfo<Value> & args)966 void WASI::FdWrite(const FunctionCallbackInfo<Value>& args) {
967 WASI* wasi;
968 uint32_t fd;
969 uint32_t iovs_ptr;
970 uint32_t iovs_len;
971 uint32_t nwritten_ptr;
972 char* memory;
973 size_t mem_size;
974 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
PathCreateDirectory(const FunctionCallbackInfo<Value> & args)1017 void WASI::PathCreateDirectory(const FunctionCallbackInfo<Value>& args) {
1018 WASI* wasi;
1019 uint32_t fd;
1020 uint32_t path_ptr;
1021 uint32_t path_len;
1022 char* memory;
1023 size_t mem_size;
1024 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
PathFilestatGet(const FunctionCallbackInfo<Value> & args)1040 void WASI::PathFilestatGet(const FunctionCallbackInfo<Value>& args) {
1041 WASI* wasi;
1042 uint32_t fd;
1043 uint32_t flags;
1044 uint32_t path_ptr;
1045 uint32_t path_len;
1046 uint32_t buf_ptr;
1047 char* memory;
1048 size_t mem_size;
1049 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
PathFilestatSetTimes(const FunctionCallbackInfo<Value> & args)1081 void WASI::PathFilestatSetTimes(const FunctionCallbackInfo<Value>& args) {
1082 WASI* wasi;
1083 uint32_t fd;
1084 uint32_t flags;
1085 uint32_t path_ptr;
1086 uint32_t path_len;
1087 uint64_t st_atim;
1088 uint64_t st_mtim;
1089 uint16_t fst_flags;
1090 char* memory;
1091 size_t mem_size;
1092 RETURN_IF_BAD_ARG_COUNT(args, 7);
1093 CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
1094 CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, flags);
1095 CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_ptr);
1096 CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, path_len);
1097 UNWRAP_BIGINT_OR_RETURN(args, args[4], Uint64, st_atim);
1098 UNWRAP_BIGINT_OR_RETURN(args, args[5], Uint64, st_mtim);
1099 CHECK_TO_TYPE_OR_RETURN(args, args[6], Uint32, fst_flags);
1100 ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
1101 Debug(wasi,
1102 "path_filestat_set_times(%d, %d, %d, %d, %d, %d, %d)\n",
1103 fd,
1104 flags,
1105 path_ptr,
1106 path_len,
1107 st_atim,
1108 st_mtim,
1109 fst_flags);
1110 GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1111 CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len);
1112 uvwasi_errno_t err = uvwasi_path_filestat_set_times(&wasi->uvw_,
1113 fd,
1114 flags,
1115 &memory[path_ptr],
1116 path_len,
1117 st_atim,
1118 st_mtim,
1119 fst_flags);
1120 args.GetReturnValue().Set(err);
1121 }
1122
1123
PathLink(const FunctionCallbackInfo<Value> & args)1124 void WASI::PathLink(const FunctionCallbackInfo<Value>& args) {
1125 WASI* wasi;
1126 uint32_t old_fd;
1127 uint32_t old_flags;
1128 uint32_t old_path_ptr;
1129 uint32_t old_path_len;
1130 uint32_t new_fd;
1131 uint32_t new_path_ptr;
1132 uint32_t new_path_len;
1133 char* memory;
1134 size_t mem_size;
1135 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
PathOpen(const FunctionCallbackInfo<Value> & args)1168 void WASI::PathOpen(const FunctionCallbackInfo<Value>& args) {
1169 WASI* wasi;
1170 uint32_t dirfd;
1171 uint32_t dirflags;
1172 uint32_t path_ptr;
1173 uint32_t path_len;
1174 uint32_t o_flags;
1175 uint64_t fs_rights_base;
1176 uint64_t fs_rights_inheriting;
1177 uint32_t fs_flags;
1178 uint32_t fd_ptr;
1179 char* memory;
1180 size_t mem_size;
1181 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
PathReadlink(const FunctionCallbackInfo<Value> & args)1224 void WASI::PathReadlink(const FunctionCallbackInfo<Value>& args) {
1225 WASI* wasi;
1226 uint32_t fd;
1227 uint32_t path_ptr;
1228 uint32_t path_len;
1229 uint32_t buf_ptr;
1230 uint32_t buf_len;
1231 uint32_t bufused_ptr;
1232 char* memory;
1233 size_t mem_size;
1234 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
PathRemoveDirectory(const FunctionCallbackInfo<Value> & args)1272 void WASI::PathRemoveDirectory(const FunctionCallbackInfo<Value>& args) {
1273 WASI* wasi;
1274 uint32_t fd;
1275 uint32_t path_ptr;
1276 uint32_t path_len;
1277 char* memory;
1278 size_t mem_size;
1279 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
PathRename(const FunctionCallbackInfo<Value> & args)1295 void WASI::PathRename(const FunctionCallbackInfo<Value>& args) {
1296 WASI* wasi;
1297 uint32_t old_fd;
1298 uint32_t old_path_ptr;
1299 uint32_t old_path_len;
1300 uint32_t new_fd;
1301 uint32_t new_path_ptr;
1302 uint32_t new_path_len;
1303 char* memory;
1304 size_t mem_size;
1305 RETURN_IF_BAD_ARG_COUNT(args, 6);
1306 CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, old_fd);
1307 CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, old_path_ptr);
1308 CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, old_path_len);
1309 CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, new_fd);
1310 CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, new_path_ptr);
1311 CHECK_TO_TYPE_OR_RETURN(args, args[5], Uint32, new_path_len);
1312 ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
1313 Debug(wasi,
1314 "path_rename(%d, %d, %d, %d, %d, %d)\n",
1315 old_fd,
1316 old_path_ptr,
1317 old_path_len,
1318 new_fd,
1319 new_path_ptr,
1320 new_path_len);
1321 GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
1322 CHECK_BOUNDS_OR_RETURN(args, mem_size, old_path_ptr, old_path_len);
1323 CHECK_BOUNDS_OR_RETURN(args, mem_size, new_path_ptr, new_path_len);
1324 uvwasi_errno_t err = uvwasi_path_rename(&wasi->uvw_,
1325 old_fd,
1326 &memory[old_path_ptr],
1327 old_path_len,
1328 new_fd,
1329 &memory[new_path_ptr],
1330 new_path_len);
1331 args.GetReturnValue().Set(err);
1332 }
1333
1334
PathSymlink(const FunctionCallbackInfo<Value> & args)1335 void WASI::PathSymlink(const FunctionCallbackInfo<Value>& args) {
1336 WASI* wasi;
1337 uint32_t old_path_ptr;
1338 uint32_t old_path_len;
1339 uint32_t fd;
1340 uint32_t new_path_ptr;
1341 uint32_t new_path_len;
1342 char* memory;
1343 size_t mem_size;
1344 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
PathUnlinkFile(const FunctionCallbackInfo<Value> & args)1371 void WASI::PathUnlinkFile(const FunctionCallbackInfo<Value>& args) {
1372 WASI* wasi;
1373 uint32_t fd;
1374 uint32_t path_ptr;
1375 uint32_t path_len;
1376 char* memory;
1377 size_t mem_size;
1378 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
PollOneoff(const FunctionCallbackInfo<Value> & args)1394 void WASI::PollOneoff(const FunctionCallbackInfo<Value>& args) {
1395 WASI* wasi;
1396 uint32_t in_ptr;
1397 uint32_t out_ptr;
1398 uint32_t nsubscriptions;
1399 uint32_t nevents_ptr;
1400 char* memory;
1401 size_t mem_size;
1402 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
ProcExit(const FunctionCallbackInfo<Value> & args)1454 void 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
ProcRaise(const FunctionCallbackInfo<Value> & args)1465 void WASI::ProcRaise(const FunctionCallbackInfo<Value>& args) {
1466 WASI* wasi;
1467 uint32_t sig;
1468 RETURN_IF_BAD_ARG_COUNT(args, 1);
1469 CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, sig);
1470 ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
1471 Debug(wasi, "proc_raise(%d)\n", sig);
1472 uvwasi_errno_t err = uvwasi_proc_raise(&wasi->uvw_, sig);
1473 args.GetReturnValue().Set(err);
1474 }
1475
1476
RandomGet(const FunctionCallbackInfo<Value> & args)1477 void WASI::RandomGet(const FunctionCallbackInfo<Value>& args) {
1478 WASI* wasi;
1479 uint32_t buf_ptr;
1480 uint32_t buf_len;
1481 char* memory;
1482 size_t mem_size;
1483 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
SchedYield(const FunctionCallbackInfo<Value> & args)1497 void WASI::SchedYield(const FunctionCallbackInfo<Value>& args) {
1498 WASI* wasi;
1499 RETURN_IF_BAD_ARG_COUNT(args, 0);
1500 ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This());
1501 Debug(wasi, "sched_yield()\n");
1502 uvwasi_errno_t err = uvwasi_sched_yield(&wasi->uvw_);
1503 args.GetReturnValue().Set(err);
1504 }
1505
SockAccept(const FunctionCallbackInfo<Value> & args)1506 void 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
SockRecv(const FunctionCallbackInfo<Value> & args)1538 void 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
SockSend(const FunctionCallbackInfo<Value> & args)1600 void 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
SockShutdown(const FunctionCallbackInfo<Value> & args)1657 void 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
_SetMemory(const FunctionCallbackInfo<Value> & args)1671 void 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
backingStore(char ** store,size_t * byte_length)1685 uvwasi_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
Initialize(Local<Object> target,Local<Value> unused,Local<Context> context,void * priv)1695 static 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
1768 NODE_BINDING_CONTEXT_AWARE_INTERNAL(wasi, node::wasi::Initialize)
1769