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