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