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