diff --git a/src/node_wasi.cc b/src/node_wasi.cc index 5bbf7d9871fd98..5d7f5a4dff50ec 100644 --- a/src/node_wasi.cc +++ b/src/node_wasi.cc @@ -14,68 +14,24 @@ namespace node { namespace wasi { template -inline void Debug(WASI* wasi, Args&&... args) { - Debug(wasi->env(), DebugCategory::WASI, std::forward(args)...); +inline void Debug(const WASI& wasi, Args&&... args) { + Debug(wasi.env(), DebugCategory::WASI, std::forward(args)...); } -#define ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(ptr, obj) \ +#define CHECK_BOUNDS_OR_RETURN(mem_size, offset, buf_size) \ do { \ - ASSIGN_OR_RETURN_UNWRAP(ptr, obj); \ - if ((*(ptr))->memory_.IsEmpty()) { \ - THROW_ERR_WASI_NOT_STARTED(Environment::GetCurrent(args)); \ - return; \ + if (!uvwasi_serdes_check_bounds((offset), (mem_size), (buf_size))) { \ + return UVWASI_EOVERFLOW; \ } \ } while (0) -#define RETURN_IF_BAD_ARG_COUNT(args, expected) \ - do { \ - if ((args).Length() != (expected)) { \ - (args).GetReturnValue().Set(UVWASI_EINVAL); \ - return; \ - } \ - } while (0) - -#define CHECK_TO_TYPE_OR_RETURN(args, input, type, result) \ - do { \ - if (!(input)->Is##type()) { \ - (args).GetReturnValue().Set(UVWASI_EINVAL); \ - return; \ - } \ - (result) = (input).As()->Value(); \ - } while (0) - -#define UNWRAP_BIGINT_OR_RETURN(args, input, type, result) \ - do { \ - if (!(input)->IsBigInt()) { \ - (args).GetReturnValue().Set(UVWASI_EINVAL); \ - return; \ - } \ - Local js_value = (input).As(); \ - bool lossless; \ - (result) = js_value->type ## Value(&lossless); \ - } while (0) - -#define GET_BACKING_STORE_OR_RETURN(wasi, args, mem_ptr, mem_size) \ - do { \ - uvwasi_errno_t err = (wasi)->backingStore((mem_ptr), (mem_size)); \ - if (err != UVWASI_ESUCCESS) { \ - (args).GetReturnValue().Set(err); \ - return; \ - } \ - } while (0) - -#define CHECK_BOUNDS_OR_RETURN(args, mem_size, offset, buf_size) \ - do { \ - if (!uvwasi_serdes_check_bounds((offset), (mem_size), (buf_size))) { \ - (args).GetReturnValue().Set(UVWASI_EOVERFLOW); \ - return; \ - } \ - } while (0) - using v8::Array; +using v8::ArrayBuffer; using v8::BigInt; +using v8::CFunction; using v8::Context; using v8::Exception; +using v8::FastApiCallbackOptions; using v8::FunctionCallbackInfo; using v8::FunctionTemplate; using v8::Integer; @@ -83,6 +39,7 @@ using v8::Isolate; using v8::Local; using v8::MaybeLocal; using v8::Object; +using v8::Signature; using v8::String; using v8::Uint32; using v8::Value; @@ -247,411 +204,429 @@ void WASI::New(const FunctionCallbackInfo& args) { } } +template +void WASI::WasiFunction::SetFunction( + Environment* env, const char* name, Local tmpl) { + auto c_function = CFunction::Make(FastCallback); + Local t = + FunctionTemplate::New(env->isolate(), + SlowCallback, + Local(), + Local(), + sizeof...(Args), + v8::ConstructorBehavior::kThrow, + v8::SideEffectType::kHasSideEffect, + &c_function); + const v8::NewStringType type = v8::NewStringType::kInternalized; + Local name_string = + String::NewFromUtf8(env->isolate(), name, type).ToLocalChecked(); + tmpl->PrototypeTemplate()->Set(name_string, t); + t->SetClassName(name_string); +} + +namespace { +template +inline R EinvalError(); + +template <> +inline uint32_t EinvalError() { + return UVWASI_EINVAL; +} + +template <> +inline void EinvalError() {} +} // namespace + +template +R WASI::WasiFunction::FastCallback( + Local receiver, + Args... args, + // NOLINTNEXTLINE(runtime/references) This is V8 api. + FastApiCallbackOptions& options) { + WASI* wasi = reinterpret_cast(BaseObject::FromJSObject(receiver)); + if (UNLIKELY(wasi == nullptr)) return EinvalError(); + + if (UNLIKELY(options.wasm_memory == nullptr || wasi->memory_.IsEmpty())) { + // fallback to slow path which to throw an error about missing memory. + options.fallback = true; + return EinvalError(); + } + uint8_t* memory = nullptr; + CHECK(LIKELY(options.wasm_memory->getStorageIfAligned(&memory))); + + return F(*wasi, + {reinterpret_cast(memory), options.wasm_memory->length()}, + args...); +} + +namespace { +template +static bool CheckType(Local v); + +template +static VT ConvertType(Local V); + +template <> +bool CheckType(Local value) { + return value->IsUint32(); +} + +template <> +uint32_t ConvertType(Local value) { + return value.As()->Value(); +} + +template <> +bool CheckType(Local value) { + return value->IsBigInt(); +} + +template <> +uint64_t ConvertType(Local value) { + Local js_value = value.As(); + bool lossless; + return js_value->Uint64Value(&lossless); +} + +template <> +bool CheckType(Local value) { + return value->IsBigInt(); +} + +template <> +int64_t ConvertType(Local value) { + Local js_value = value.As(); + bool lossless; + return js_value->Int64Value(&lossless); +} + +template +bool CheckTypes(const FunctionCallbackInfo& info, int i, T) { + return CheckType(info[i]); +} + +template +bool CheckTypes(const FunctionCallbackInfo& info, + int i, + T arg, + Ts... args) { + if (!CheckTypes(info, i, arg)) return false; + return CheckTypes(info, i + 1, args...); +} + +template +bool CheckTypes(const FunctionCallbackInfo& info) { + return CheckTypes(info, 0, Args()...); +} + +template <> +bool CheckTypes(const FunctionCallbackInfo& info) { + return true; +} + +template ::value, bool> = true> +inline void CallAndSetReturn(std::index_sequence, + const FunctionCallbackInfo& args, + WASI* wasi, + WasmMemory memory) { + args.GetReturnValue().Set( + F(*wasi, memory, ConvertType(args[Indices])...)); +} + +template ::value, bool> = true> +inline void CallAndSetReturn(std::index_sequence, + const FunctionCallbackInfo& args, + WASI* wasi, + WasmMemory memory) { + F(*wasi, memory, ConvertType(args[Indices])...); +} + +} // namespace + +template +void WASI::WasiFunction::SlowCallback( + const FunctionCallbackInfo& args) { + if (args.Length() != sizeof...(Args)) { + args.GetReturnValue().Set(UVWASI_EINVAL); + return; + } + if (!CheckTypes(args)) { + args.GetReturnValue().Set(UVWASI_EINVAL); + return; + } -void WASI::ArgsGet(const FunctionCallbackInfo& args) { WASI* wasi; - uint32_t argv_offset; - uint32_t argv_buf_offset; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 2); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, argv_offset); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, argv_buf_offset); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); + ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This()); + if (wasi->memory_.IsEmpty()) { + THROW_ERR_WASI_NOT_STARTED(Environment::GetCurrent(args)); + return; + } + + Local memory = PersistentToLocal::Strong(wasi->memory_); + Local ab = memory->Buffer(); + size_t mem_size = ab->ByteLength(); + char* mem_data = static_cast(ab->Data()); + CHECK_NOT_NULL(mem_data); + + CallAndSetReturn( + std::make_index_sequence{}, + args, + wasi, + {mem_data, mem_size}); +} + +template +static void SetFunction(R (*f)(WASI&, WasmMemory, Args...), + Environment* env, + const char* name, + Local tmpl) { + WASI::WasiFunction::SetFunction(env, name, tmpl); +} + +uint32_t WASI::ArgsGet(WASI& wasi, + WasmMemory memory, + uint32_t argv_offset, + uint32_t argv_buf_offset) { Debug(wasi, "args_get(%d, %d)\n", argv_offset, argv_buf_offset); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, - mem_size, - argv_buf_offset, - wasi->uvw_.argv_buf_size); - CHECK_BOUNDS_OR_RETURN(args, - mem_size, - argv_offset, - wasi->uvw_.argc * UVWASI_SERDES_SIZE_uint32_t); - std::vector argv(wasi->uvw_.argc); - char* argv_buf = &memory[argv_buf_offset]; - uvwasi_errno_t err = uvwasi_args_get(&wasi->uvw_, argv.data(), argv_buf); + + CHECK_BOUNDS_OR_RETURN(memory.size, argv_buf_offset, wasi.uvw_.argv_buf_size); + CHECK_BOUNDS_OR_RETURN( + memory.size, argv_offset, wasi.uvw_.argc * UVWASI_SERDES_SIZE_uint32_t); + std::vector argv(wasi.uvw_.argc); + char* argv_buf = &memory.data[argv_buf_offset]; + uvwasi_errno_t err = uvwasi_args_get(&wasi.uvw_, argv.data(), argv_buf); if (err == UVWASI_ESUCCESS) { - for (size_t i = 0; i < wasi->uvw_.argc; i++) { + for (size_t i = 0; i < wasi.uvw_.argc; i++) { uint32_t offset = static_cast(argv_buf_offset + (argv[i] - argv[0])); - uvwasi_serdes_write_uint32_t(memory, - argv_offset + - (i * UVWASI_SERDES_SIZE_uint32_t), - offset); + uvwasi_serdes_write_uint32_t( + memory.data, argv_offset + (i * UVWASI_SERDES_SIZE_uint32_t), offset); } } - args.GetReturnValue().Set(err); + return err; } - -void WASI::ArgsSizesGet(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t argc_offset; - uint32_t argv_buf_offset; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 2); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, argc_offset); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, argv_buf_offset); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::ArgsSizesGet(WASI& wasi, + WasmMemory memory, + uint32_t argc_offset, + uint32_t argv_buf_offset) { Debug(wasi, "args_sizes_get(%d, %d)\n", argc_offset, argv_buf_offset); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, - mem_size, - argc_offset, - UVWASI_SERDES_SIZE_size_t); - CHECK_BOUNDS_OR_RETURN(args, - mem_size, - argv_buf_offset, - UVWASI_SERDES_SIZE_size_t); + CHECK_BOUNDS_OR_RETURN(memory.size, argc_offset, UVWASI_SERDES_SIZE_size_t); + CHECK_BOUNDS_OR_RETURN( + memory.size, argv_buf_offset, UVWASI_SERDES_SIZE_size_t); uvwasi_size_t argc; uvwasi_size_t argv_buf_size; - uvwasi_errno_t err = uvwasi_args_sizes_get(&wasi->uvw_, - &argc, - &argv_buf_size); + uvwasi_errno_t err = uvwasi_args_sizes_get(&wasi.uvw_, &argc, &argv_buf_size); if (err == UVWASI_ESUCCESS) { - uvwasi_serdes_write_size_t(memory, argc_offset, argc); - uvwasi_serdes_write_size_t(memory, argv_buf_offset, argv_buf_size); + uvwasi_serdes_write_size_t(memory.data, argc_offset, argc); + uvwasi_serdes_write_size_t(memory.data, argv_buf_offset, argv_buf_size); } - args.GetReturnValue().Set(err); + return err; } - -void WASI::ClockResGet(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t clock_id; - uint32_t resolution_ptr; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 2); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, clock_id); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, resolution_ptr); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::ClockResGet(WASI& wasi, + WasmMemory memory, + uint32_t clock_id, + uint32_t resolution_ptr) { Debug(wasi, "clock_res_get(%d, %d)\n", clock_id, resolution_ptr); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, - mem_size, - resolution_ptr, - UVWASI_SERDES_SIZE_timestamp_t); + CHECK_BOUNDS_OR_RETURN( + memory.size, resolution_ptr, UVWASI_SERDES_SIZE_timestamp_t); uvwasi_timestamp_t resolution; - uvwasi_errno_t err = uvwasi_clock_res_get(&wasi->uvw_, - clock_id, - &resolution); + uvwasi_errno_t err = uvwasi_clock_res_get(&wasi.uvw_, clock_id, &resolution); if (err == UVWASI_ESUCCESS) - uvwasi_serdes_write_timestamp_t(memory, resolution_ptr, resolution); + uvwasi_serdes_write_timestamp_t(memory.data, resolution_ptr, resolution); - args.GetReturnValue().Set(err); + return err; } - -void WASI::ClockTimeGet(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t clock_id; - uint64_t precision; - uint32_t time_ptr; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 3); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, clock_id); - UNWRAP_BIGINT_OR_RETURN(args, args[1], Uint64, precision); - CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, time_ptr); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::ClockTimeGet(WASI& wasi, + WasmMemory memory, + uint32_t clock_id, + uint64_t precision, + uint32_t time_ptr) { Debug(wasi, "clock_time_get(%d, %d, %d)\n", clock_id, precision, time_ptr); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, - mem_size, - time_ptr, - UVWASI_SERDES_SIZE_timestamp_t); + CHECK_BOUNDS_OR_RETURN(memory.size, time_ptr, UVWASI_SERDES_SIZE_timestamp_t); uvwasi_timestamp_t time; - uvwasi_errno_t err = uvwasi_clock_time_get(&wasi->uvw_, - clock_id, - precision, - &time); + uvwasi_errno_t err = + uvwasi_clock_time_get(&wasi.uvw_, clock_id, precision, &time); if (err == UVWASI_ESUCCESS) - uvwasi_serdes_write_timestamp_t(memory, time_ptr, time); + uvwasi_serdes_write_timestamp_t(memory.data, time_ptr, time); - args.GetReturnValue().Set(err); + return err; } - -void WASI::EnvironGet(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t environ_offset; - uint32_t environ_buf_offset; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 2); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, environ_offset); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, environ_buf_offset); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::EnvironGet(WASI& wasi, + WasmMemory memory, + uint32_t environ_offset, + uint32_t environ_buf_offset) { Debug(wasi, "environ_get(%d, %d)\n", environ_offset, environ_buf_offset); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, - mem_size, - environ_buf_offset, - wasi->uvw_.env_buf_size); - CHECK_BOUNDS_OR_RETURN(args, - mem_size, + CHECK_BOUNDS_OR_RETURN( + memory.size, environ_buf_offset, wasi.uvw_.env_buf_size); + CHECK_BOUNDS_OR_RETURN(memory.size, environ_offset, - wasi->uvw_.envc * UVWASI_SERDES_SIZE_uint32_t); - std::vector environment(wasi->uvw_.envc); - char* environ_buf = &memory[environ_buf_offset]; - uvwasi_errno_t err = uvwasi_environ_get(&wasi->uvw_, - environment.data(), - environ_buf); + wasi.uvw_.envc * UVWASI_SERDES_SIZE_uint32_t); + std::vector environment(wasi.uvw_.envc); + char* environ_buf = &memory.data[environ_buf_offset]; + uvwasi_errno_t err = + uvwasi_environ_get(&wasi.uvw_, environment.data(), environ_buf); if (err == UVWASI_ESUCCESS) { - for (size_t i = 0; i < wasi->uvw_.envc; i++) { + for (size_t i = 0; i < wasi.uvw_.envc; i++) { uint32_t offset = static_cast( environ_buf_offset + (environment[i] - environment[0])); - uvwasi_serdes_write_uint32_t(memory, - environ_offset + - (i * UVWASI_SERDES_SIZE_uint32_t), - offset); + uvwasi_serdes_write_uint32_t( + memory.data, + environ_offset + (i * UVWASI_SERDES_SIZE_uint32_t), + offset); } } - args.GetReturnValue().Set(err); + return err; } - -void WASI::EnvironSizesGet(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t envc_offset; - uint32_t env_buf_offset; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 2); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, envc_offset); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, env_buf_offset); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::EnvironSizesGet(WASI& wasi, + WasmMemory memory, + uint32_t envc_offset, + uint32_t env_buf_offset) { Debug(wasi, "environ_sizes_get(%d, %d)\n", envc_offset, env_buf_offset); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, - mem_size, - envc_offset, - UVWASI_SERDES_SIZE_size_t); - CHECK_BOUNDS_OR_RETURN(args, - mem_size, - env_buf_offset, - UVWASI_SERDES_SIZE_size_t); + CHECK_BOUNDS_OR_RETURN(memory.size, envc_offset, UVWASI_SERDES_SIZE_size_t); + CHECK_BOUNDS_OR_RETURN( + memory.size, env_buf_offset, UVWASI_SERDES_SIZE_size_t); uvwasi_size_t envc; uvwasi_size_t env_buf_size; - uvwasi_errno_t err = uvwasi_environ_sizes_get(&wasi->uvw_, - &envc, - &env_buf_size); + uvwasi_errno_t err = + uvwasi_environ_sizes_get(&wasi.uvw_, &envc, &env_buf_size); if (err == UVWASI_ESUCCESS) { - uvwasi_serdes_write_size_t(memory, envc_offset, envc); - uvwasi_serdes_write_size_t(memory, env_buf_offset, env_buf_size); + uvwasi_serdes_write_size_t(memory.data, envc_offset, envc); + uvwasi_serdes_write_size_t(memory.data, env_buf_offset, env_buf_size); } - args.GetReturnValue().Set(err); + return err; } - -void WASI::FdAdvise(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t fd; - uint64_t offset; - uint64_t len; - uint8_t advice; - RETURN_IF_BAD_ARG_COUNT(args, 4); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd); - UNWRAP_BIGINT_OR_RETURN(args, args[1], Uint64, offset); - UNWRAP_BIGINT_OR_RETURN(args, args[2], Uint64, len); - CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, advice); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::FdAdvise(WASI& wasi, + WasmMemory, + uint32_t fd, + uint64_t offset, + uint64_t len, + uint32_t advice) { Debug(wasi, "fd_advise(%d, %d, %d, %d)\n", fd, offset, len, advice); - uvwasi_errno_t err = uvwasi_fd_advise(&wasi->uvw_, fd, offset, len, advice); - args.GetReturnValue().Set(err); + return uvwasi_fd_advise(&wasi.uvw_, fd, offset, len, advice); } - -void WASI::FdAllocate(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t fd; - uint64_t offset; - uint64_t len; - RETURN_IF_BAD_ARG_COUNT(args, 3); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd); - UNWRAP_BIGINT_OR_RETURN(args, args[1], Uint64, offset); - UNWRAP_BIGINT_OR_RETURN(args, args[2], Uint64, len); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::FdAllocate( + WASI& wasi, WasmMemory, uint32_t fd, uint64_t offset, uint64_t len) { Debug(wasi, "fd_allocate(%d, %d, %d)\n", fd, offset, len); - uvwasi_errno_t err = uvwasi_fd_allocate(&wasi->uvw_, fd, offset, len); - args.GetReturnValue().Set(err); + return uvwasi_fd_allocate(&wasi.uvw_, fd, offset, len); } - -void WASI::FdClose(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t fd; - RETURN_IF_BAD_ARG_COUNT(args, 1); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::FdClose(WASI& wasi, WasmMemory, uint32_t fd) { Debug(wasi, "fd_close(%d)\n", fd); - uvwasi_errno_t err = uvwasi_fd_close(&wasi->uvw_, fd); - args.GetReturnValue().Set(err); + return uvwasi_fd_close(&wasi.uvw_, fd); } - -void WASI::FdDatasync(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t fd; - RETURN_IF_BAD_ARG_COUNT(args, 1); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::FdDatasync(WASI& wasi, WasmMemory, uint32_t fd) { Debug(wasi, "fd_datasync(%d)\n", fd); - uvwasi_errno_t err = uvwasi_fd_datasync(&wasi->uvw_, fd); - args.GetReturnValue().Set(err); + return uvwasi_fd_datasync(&wasi.uvw_, fd); } - -void WASI::FdFdstatGet(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t fd; - uint32_t buf; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 2); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, buf); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::FdFdstatGet(WASI& wasi, + WasmMemory memory, + uint32_t fd, + uint32_t buf) { Debug(wasi, "fd_fdstat_get(%d, %d)\n", fd, buf); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, mem_size, buf, UVWASI_SERDES_SIZE_fdstat_t); + CHECK_BOUNDS_OR_RETURN(memory.size, buf, UVWASI_SERDES_SIZE_fdstat_t); uvwasi_fdstat_t stats; - uvwasi_errno_t err = uvwasi_fd_fdstat_get(&wasi->uvw_, fd, &stats); + uvwasi_errno_t err = uvwasi_fd_fdstat_get(&wasi.uvw_, fd, &stats); if (err == UVWASI_ESUCCESS) - uvwasi_serdes_write_fdstat_t(memory, buf, &stats); + uvwasi_serdes_write_fdstat_t(memory.data, buf, &stats); - args.GetReturnValue().Set(err); + return err; } - -void WASI::FdFdstatSetFlags(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t fd; - uint16_t flags; - RETURN_IF_BAD_ARG_COUNT(args, 2); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, flags); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::FdFdstatSetFlags(WASI& wasi, + WasmMemory, + uint32_t fd, + uint32_t flags) { Debug(wasi, "fd_fdstat_set_flags(%d, %d)\n", fd, flags); - uvwasi_errno_t err = uvwasi_fd_fdstat_set_flags(&wasi->uvw_, fd, flags); - args.GetReturnValue().Set(err); + return uvwasi_fd_fdstat_set_flags(&wasi.uvw_, fd, flags); } - -void WASI::FdFdstatSetRights(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t fd; - uint64_t fs_rights_base; - uint64_t fs_rights_inheriting; - RETURN_IF_BAD_ARG_COUNT(args, 3); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd); - UNWRAP_BIGINT_OR_RETURN(args, args[1], Uint64, fs_rights_base); - UNWRAP_BIGINT_OR_RETURN(args, args[2], Uint64, fs_rights_inheriting); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::FdFdstatSetRights(WASI& wasi, + WasmMemory, + uint32_t fd, + uint64_t fs_rights_base, + uint64_t fs_rights_inheriting) { Debug(wasi, "fd_fdstat_set_rights(%d, %d, %d)\n", fd, fs_rights_base, fs_rights_inheriting); - uvwasi_errno_t err = uvwasi_fd_fdstat_set_rights(&wasi->uvw_, - fd, - fs_rights_base, - fs_rights_inheriting); - args.GetReturnValue().Set(err); + return uvwasi_fd_fdstat_set_rights( + &wasi.uvw_, fd, fs_rights_base, fs_rights_inheriting); } - -void WASI::FdFilestatGet(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t fd; - uint32_t buf; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 2); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, buf); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::FdFilestatGet(WASI& wasi, + WasmMemory memory, + uint32_t fd, + uint32_t buf) { Debug(wasi, "fd_filestat_get(%d, %d)\n", fd, buf); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, mem_size, buf, UVWASI_SERDES_SIZE_filestat_t); + CHECK_BOUNDS_OR_RETURN(memory.size, buf, UVWASI_SERDES_SIZE_filestat_t); uvwasi_filestat_t stats; - uvwasi_errno_t err = uvwasi_fd_filestat_get(&wasi->uvw_, fd, &stats); + uvwasi_errno_t err = uvwasi_fd_filestat_get(&wasi.uvw_, fd, &stats); if (err == UVWASI_ESUCCESS) - uvwasi_serdes_write_filestat_t(memory, buf, &stats); + uvwasi_serdes_write_filestat_t(memory.data, buf, &stats); - args.GetReturnValue().Set(err); + return err; } - -void WASI::FdFilestatSetSize(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t fd; - uint64_t st_size; - RETURN_IF_BAD_ARG_COUNT(args, 2); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd); - UNWRAP_BIGINT_OR_RETURN(args, args[1], Uint64, st_size); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::FdFilestatSetSize(WASI& wasi, + WasmMemory, + uint32_t fd, + uint64_t st_size) { Debug(wasi, "fd_filestat_set_size(%d, %d)\n", fd, st_size); - uvwasi_errno_t err = uvwasi_fd_filestat_set_size(&wasi->uvw_, fd, st_size); - args.GetReturnValue().Set(err); + return uvwasi_fd_filestat_set_size(&wasi.uvw_, fd, st_size); } - -void WASI::FdFilestatSetTimes(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t fd; - uint64_t st_atim; - uint64_t st_mtim; - uint16_t fst_flags; - RETURN_IF_BAD_ARG_COUNT(args, 4); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd); - UNWRAP_BIGINT_OR_RETURN(args, args[1], Uint64, st_atim); - UNWRAP_BIGINT_OR_RETURN(args, args[2], Uint64, st_mtim); - CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, fst_flags); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::FdFilestatSetTimes(WASI& wasi, + WasmMemory, + uint32_t fd, + uint64_t st_atim, + uint64_t st_mtim, + uint32_t fst_flags) { Debug(wasi, "fd_filestat_set_times(%d, %d, %d, %d)\n", fd, st_atim, st_mtim, fst_flags); - uvwasi_errno_t err = uvwasi_fd_filestat_set_times(&wasi->uvw_, - fd, - st_atim, - st_mtim, - fst_flags); - args.GetReturnValue().Set(err); + return uvwasi_fd_filestat_set_times( + &wasi.uvw_, fd, st_atim, st_mtim, fst_flags); } - -void WASI::FdPread(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t fd; - uint32_t iovs_ptr; - uint32_t iovs_len; - uint64_t offset; - uint32_t nread_ptr; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 5); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, iovs_ptr); - CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, iovs_len); - UNWRAP_BIGINT_OR_RETURN(args, args[3], Uint64, offset); - CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, nread_ptr); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::FdPread(WASI& wasi, + WasmMemory memory, + uint32_t fd, + uint32_t iovs_ptr, + uint32_t iovs_len, + uint64_t offset, + uint32_t nread_ptr) { Debug(wasi, "uvwasi_fd_pread(%d, %d, %d, %d, %d)\n", fd, @@ -659,96 +634,59 @@ void WASI::FdPread(const FunctionCallbackInfo& args) { iovs_len, offset, nread_ptr); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, - mem_size, - iovs_ptr, - iovs_len * UVWASI_SERDES_SIZE_iovec_t); - CHECK_BOUNDS_OR_RETURN(args, mem_size, nread_ptr, UVWASI_SERDES_SIZE_size_t); + CHECK_BOUNDS_OR_RETURN( + memory.size, iovs_ptr, iovs_len * UVWASI_SERDES_SIZE_iovec_t); + CHECK_BOUNDS_OR_RETURN(memory.size, nread_ptr, UVWASI_SERDES_SIZE_size_t); std::vector iovs(iovs_len); uvwasi_errno_t err; - err = uvwasi_serdes_readv_iovec_t(memory, - mem_size, - iovs_ptr, - iovs.data(), - iovs_len); + err = uvwasi_serdes_readv_iovec_t( + memory.data, memory.size, iovs_ptr, iovs.data(), iovs_len); if (err != UVWASI_ESUCCESS) { - args.GetReturnValue().Set(err); - return; + return err; } uvwasi_size_t nread; - err = uvwasi_fd_pread(&wasi->uvw_, fd, iovs.data(), iovs_len, offset, &nread); + err = uvwasi_fd_pread(&wasi.uvw_, fd, iovs.data(), iovs_len, offset, &nread); if (err == UVWASI_ESUCCESS) - uvwasi_serdes_write_size_t(memory, nread_ptr, nread); + uvwasi_serdes_write_size_t(memory.data, nread_ptr, nread); - args.GetReturnValue().Set(err); + return err; } - -void WASI::FdPrestatGet(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t fd; - uint32_t buf; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 2); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, buf); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::FdPrestatGet(WASI& wasi, + WasmMemory memory, + uint32_t fd, + uint32_t buf) { Debug(wasi, "fd_prestat_get(%d, %d)\n", fd, buf); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, mem_size, buf, UVWASI_SERDES_SIZE_prestat_t); + CHECK_BOUNDS_OR_RETURN(memory.size, buf, UVWASI_SERDES_SIZE_prestat_t); uvwasi_prestat_t prestat; - uvwasi_errno_t err = uvwasi_fd_prestat_get(&wasi->uvw_, fd, &prestat); + uvwasi_errno_t err = uvwasi_fd_prestat_get(&wasi.uvw_, fd, &prestat); if (err == UVWASI_ESUCCESS) - uvwasi_serdes_write_prestat_t(memory, buf, &prestat); + uvwasi_serdes_write_prestat_t(memory.data, buf, &prestat); - args.GetReturnValue().Set(err); + return err; } - -void WASI::FdPrestatDirName(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t fd; - uint32_t path_ptr; - uint32_t path_len; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 3); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, path_ptr); - CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_len); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::FdPrestatDirName(WASI& wasi, + WasmMemory memory, + uint32_t fd, + uint32_t path_ptr, + uint32_t path_len) { Debug(wasi, "fd_prestat_dir_name(%d, %d, %d)\n", fd, path_ptr, path_len); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len); - uvwasi_errno_t err = uvwasi_fd_prestat_dir_name(&wasi->uvw_, - fd, - &memory[path_ptr], - path_len); - args.GetReturnValue().Set(err); + CHECK_BOUNDS_OR_RETURN(memory.size, path_ptr, path_len); + return uvwasi_fd_prestat_dir_name( + &wasi.uvw_, fd, &memory.data[path_ptr], path_len); } - -void WASI::FdPwrite(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t fd; - uint32_t iovs_ptr; - uint32_t iovs_len; - uint64_t offset; - uint32_t nwritten_ptr; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 5); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, iovs_ptr); - CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, iovs_len); - UNWRAP_BIGINT_OR_RETURN(args, args[3], Uint64, offset); - CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, nwritten_ptr); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::FdPwrite(WASI& wasi, + WasmMemory memory, + uint32_t fd, + uint32_t iovs_ptr, + uint32_t iovs_len, + uint64_t offset, + uint32_t nwritten_ptr) { Debug(wasi, "uvwasi_fd_pwrite(%d, %d, %d, %d, %d)\n", fd, @@ -756,101 +694,61 @@ void WASI::FdPwrite(const FunctionCallbackInfo& args) { iovs_len, offset, nwritten_ptr); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, - mem_size, - iovs_ptr, - iovs_len * UVWASI_SERDES_SIZE_ciovec_t); - CHECK_BOUNDS_OR_RETURN(args, - mem_size, - nwritten_ptr, - UVWASI_SERDES_SIZE_size_t); + CHECK_BOUNDS_OR_RETURN( + memory.size, iovs_ptr, iovs_len * UVWASI_SERDES_SIZE_ciovec_t); + CHECK_BOUNDS_OR_RETURN(memory.size, nwritten_ptr, UVWASI_SERDES_SIZE_size_t); std::vector iovs(iovs_len); uvwasi_errno_t err; - err = uvwasi_serdes_readv_ciovec_t(memory, - mem_size, - iovs_ptr, - iovs.data(), - iovs_len); + err = uvwasi_serdes_readv_ciovec_t( + memory.data, memory.size, iovs_ptr, iovs.data(), iovs_len); if (err != UVWASI_ESUCCESS) { - args.GetReturnValue().Set(err); - return; + return err; } uvwasi_size_t nwritten; - err = uvwasi_fd_pwrite(&wasi->uvw_, - fd, - iovs.data(), - iovs_len, - offset, - &nwritten); + err = uvwasi_fd_pwrite( + &wasi.uvw_, fd, iovs.data(), iovs_len, offset, &nwritten); if (err == UVWASI_ESUCCESS) - uvwasi_serdes_write_size_t(memory, nwritten_ptr, nwritten); + uvwasi_serdes_write_size_t(memory.data, nwritten_ptr, nwritten); - args.GetReturnValue().Set(err); + return err; } - -void WASI::FdRead(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t fd; - uint32_t iovs_ptr; - uint32_t iovs_len; - uint32_t nread_ptr; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 4); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, iovs_ptr); - CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, iovs_len); - CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, nread_ptr); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::FdRead(WASI& wasi, + WasmMemory memory, + uint32_t fd, + uint32_t iovs_ptr, + uint32_t iovs_len, + uint32_t nread_ptr) { Debug(wasi, "fd_read(%d, %d, %d, %d)\n", fd, iovs_ptr, iovs_len, nread_ptr); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, - mem_size, - iovs_ptr, - iovs_len * UVWASI_SERDES_SIZE_iovec_t); - CHECK_BOUNDS_OR_RETURN(args, mem_size, nread_ptr, UVWASI_SERDES_SIZE_size_t); + CHECK_BOUNDS_OR_RETURN( + memory.size, iovs_ptr, iovs_len * UVWASI_SERDES_SIZE_iovec_t); + CHECK_BOUNDS_OR_RETURN(memory.size, nread_ptr, UVWASI_SERDES_SIZE_size_t); std::vector iovs(iovs_len); uvwasi_errno_t err; - err = uvwasi_serdes_readv_iovec_t(memory, - mem_size, - iovs_ptr, - iovs.data(), - iovs_len); + err = uvwasi_serdes_readv_iovec_t( + memory.data, memory.size, iovs_ptr, iovs.data(), iovs_len); if (err != UVWASI_ESUCCESS) { - args.GetReturnValue().Set(err); - return; + return err; } uvwasi_size_t nread; - err = uvwasi_fd_read(&wasi->uvw_, fd, iovs.data(), iovs_len, &nread); + err = uvwasi_fd_read(&wasi.uvw_, fd, iovs.data(), iovs_len, &nread); if (err == UVWASI_ESUCCESS) - uvwasi_serdes_write_size_t(memory, nread_ptr, nread); + uvwasi_serdes_write_size_t(memory.data, nread_ptr, nread); - args.GetReturnValue().Set(err); + return err; } - -void WASI::FdReaddir(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t fd; - uint32_t buf_ptr; - uint32_t buf_len; - uint64_t cookie; - uint32_t bufused_ptr; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 5); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, buf_ptr); - CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, buf_len); - UNWRAP_BIGINT_OR_RETURN(args, args[3], Uint64, cookie); - CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, bufused_ptr); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::FdReaddir(WASI& wasi, + WasmMemory memory, + uint32_t fd, + uint32_t buf_ptr, + uint32_t buf_len, + uint64_t cookie, + uint32_t bufused_ptr) { Debug(wasi, "uvwasi_fd_readdir(%d, %d, %d, %d, %d)\n", fd, @@ -858,246 +756,137 @@ void WASI::FdReaddir(const FunctionCallbackInfo& args) { buf_len, cookie, bufused_ptr); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, mem_size, buf_ptr, buf_len); - CHECK_BOUNDS_OR_RETURN(args, - mem_size, - bufused_ptr, - UVWASI_SERDES_SIZE_size_t); + CHECK_BOUNDS_OR_RETURN(memory.size, buf_ptr, buf_len); + CHECK_BOUNDS_OR_RETURN(memory.size, bufused_ptr, UVWASI_SERDES_SIZE_size_t); uvwasi_size_t bufused; - uvwasi_errno_t err = uvwasi_fd_readdir(&wasi->uvw_, - fd, - &memory[buf_ptr], - buf_len, - cookie, - &bufused); + uvwasi_errno_t err = uvwasi_fd_readdir( + &wasi.uvw_, fd, &memory.data[buf_ptr], buf_len, cookie, &bufused); if (err == UVWASI_ESUCCESS) - uvwasi_serdes_write_size_t(memory, bufused_ptr, bufused); + uvwasi_serdes_write_size_t(memory.data, bufused_ptr, bufused); - args.GetReturnValue().Set(err); + return err; } - -void WASI::FdRenumber(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t from; - uint32_t to; - RETURN_IF_BAD_ARG_COUNT(args, 2); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, from); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, to); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::FdRenumber(WASI& wasi, WasmMemory, uint32_t from, uint32_t to) { Debug(wasi, "fd_renumber(%d, %d)\n", from, to); - uvwasi_errno_t err = uvwasi_fd_renumber(&wasi->uvw_, from, to); - args.GetReturnValue().Set(err); + return uvwasi_fd_renumber(&wasi.uvw_, from, to); } - -void WASI::FdSeek(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t fd; - int64_t offset; - uint8_t whence; - uint32_t newoffset_ptr; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 4); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd); - UNWRAP_BIGINT_OR_RETURN(args, args[1], Int64, offset); - CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, whence); - CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, newoffset_ptr); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::FdSeek(WASI& wasi, + WasmMemory memory, + uint32_t fd, + int64_t offset, + uint32_t whence, + uint32_t newoffset_ptr) { Debug(wasi, "fd_seek(%d, %d, %d, %d)\n", fd, offset, whence, newoffset_ptr); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, - mem_size, - newoffset_ptr, - UVWASI_SERDES_SIZE_filesize_t); + CHECK_BOUNDS_OR_RETURN( + memory.size, newoffset_ptr, UVWASI_SERDES_SIZE_filesize_t); uvwasi_filesize_t newoffset; - uvwasi_errno_t err = uvwasi_fd_seek(&wasi->uvw_, - fd, - offset, - whence, - &newoffset); + uvwasi_errno_t err = + uvwasi_fd_seek(&wasi.uvw_, fd, offset, whence, &newoffset); if (err == UVWASI_ESUCCESS) - uvwasi_serdes_write_filesize_t(memory, newoffset_ptr, newoffset); + uvwasi_serdes_write_filesize_t(memory.data, newoffset_ptr, newoffset); - args.GetReturnValue().Set(err); + return err; } - -void WASI::FdSync(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t fd; - RETURN_IF_BAD_ARG_COUNT(args, 1); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::FdSync(WASI& wasi, WasmMemory, uint32_t fd) { Debug(wasi, "fd_sync(%d)\n", fd); - uvwasi_errno_t err = uvwasi_fd_sync(&wasi->uvw_, fd); - args.GetReturnValue().Set(err); + return uvwasi_fd_sync(&wasi.uvw_, fd); } - -void WASI::FdTell(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t fd; - uint32_t offset_ptr; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 2); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, offset_ptr); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::FdTell(WASI& wasi, + WasmMemory memory, + uint32_t fd, + uint32_t offset_ptr) { Debug(wasi, "fd_tell(%d, %d)\n", fd, offset_ptr); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, - mem_size, - offset_ptr, - UVWASI_SERDES_SIZE_filesize_t); + CHECK_BOUNDS_OR_RETURN( + memory.size, offset_ptr, UVWASI_SERDES_SIZE_filesize_t); uvwasi_filesize_t offset; - uvwasi_errno_t err = uvwasi_fd_tell(&wasi->uvw_, fd, &offset); + uvwasi_errno_t err = uvwasi_fd_tell(&wasi.uvw_, fd, &offset); if (err == UVWASI_ESUCCESS) - uvwasi_serdes_write_filesize_t(memory, offset_ptr, offset); + uvwasi_serdes_write_filesize_t(memory.data, offset_ptr, offset); - args.GetReturnValue().Set(err); + return err; } - -void WASI::FdWrite(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t fd; - uint32_t iovs_ptr; - uint32_t iovs_len; - uint32_t nwritten_ptr; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 4); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, iovs_ptr); - CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, iovs_len); - CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, nwritten_ptr); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::FdWrite(WASI& wasi, + WasmMemory memory, + uint32_t fd, + uint32_t iovs_ptr, + uint32_t iovs_len, + uint32_t nwritten_ptr) { Debug(wasi, "fd_write(%d, %d, %d, %d)\n", fd, iovs_ptr, iovs_len, nwritten_ptr); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, - mem_size, - iovs_ptr, - iovs_len * UVWASI_SERDES_SIZE_ciovec_t); - CHECK_BOUNDS_OR_RETURN(args, - mem_size, - nwritten_ptr, - UVWASI_SERDES_SIZE_size_t); + CHECK_BOUNDS_OR_RETURN( + memory.size, iovs_ptr, iovs_len * UVWASI_SERDES_SIZE_ciovec_t); + CHECK_BOUNDS_OR_RETURN(memory.size, nwritten_ptr, UVWASI_SERDES_SIZE_size_t); std::vector iovs(iovs_len); uvwasi_errno_t err; - err = uvwasi_serdes_readv_ciovec_t(memory, - mem_size, - iovs_ptr, - iovs.data(), - iovs_len); + err = uvwasi_serdes_readv_ciovec_t( + memory.data, memory.size, iovs_ptr, iovs.data(), iovs_len); if (err != UVWASI_ESUCCESS) { - args.GetReturnValue().Set(err); - return; + return err; } uvwasi_size_t nwritten; - err = uvwasi_fd_write(&wasi->uvw_, fd, iovs.data(), iovs_len, &nwritten); + err = uvwasi_fd_write(&wasi.uvw_, fd, iovs.data(), iovs_len, &nwritten); if (err == UVWASI_ESUCCESS) - uvwasi_serdes_write_size_t(memory, nwritten_ptr, nwritten); + uvwasi_serdes_write_size_t(memory.data, nwritten_ptr, nwritten); - args.GetReturnValue().Set(err); + return err; } - -void WASI::PathCreateDirectory(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t fd; - uint32_t path_ptr; - uint32_t path_len; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 3); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, path_ptr); - CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_len); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::PathCreateDirectory(WASI& wasi, + WasmMemory memory, + uint32_t fd, + uint32_t path_ptr, + uint32_t path_len) { Debug(wasi, "path_create_directory(%d, %d, %d)\n", fd, path_ptr, path_len); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len); - uvwasi_errno_t err = uvwasi_path_create_directory(&wasi->uvw_, - fd, - &memory[path_ptr], - path_len); - args.GetReturnValue().Set(err); + CHECK_BOUNDS_OR_RETURN(memory.size, path_ptr, path_len); + uvwasi_errno_t err = uvwasi_path_create_directory( + &wasi.uvw_, fd, &memory.data[path_ptr], path_len); + return err; } - -void WASI::PathFilestatGet(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t fd; - uint32_t flags; - uint32_t path_ptr; - uint32_t path_len; - uint32_t buf_ptr; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 5); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, flags); - CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_ptr); - CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, path_len); - CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, buf_ptr); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::PathFilestatGet(WASI& wasi, + WasmMemory memory, + uint32_t fd, + uint32_t flags, + uint32_t path_ptr, + uint32_t path_len, + uint32_t buf_ptr) { Debug(wasi, "path_filestat_get(%d, %d, %d)\n", fd, path_ptr, path_len); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len); - CHECK_BOUNDS_OR_RETURN(args, - mem_size, - buf_ptr, - UVWASI_SERDES_SIZE_filestat_t); + CHECK_BOUNDS_OR_RETURN(memory.size, path_ptr, path_len); + CHECK_BOUNDS_OR_RETURN(memory.size, buf_ptr, UVWASI_SERDES_SIZE_filestat_t); uvwasi_filestat_t stats; - uvwasi_errno_t err = uvwasi_path_filestat_get(&wasi->uvw_, - fd, - flags, - &memory[path_ptr], - path_len, - &stats); + uvwasi_errno_t err = uvwasi_path_filestat_get( + &wasi.uvw_, fd, flags, &memory.data[path_ptr], path_len, &stats); if (err == UVWASI_ESUCCESS) - uvwasi_serdes_write_filestat_t(memory, buf_ptr, &stats); + uvwasi_serdes_write_filestat_t(memory.data, buf_ptr, &stats); - args.GetReturnValue().Set(err); + return err; } - -void WASI::PathFilestatSetTimes(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t fd; - uint32_t flags; - uint32_t path_ptr; - uint32_t path_len; - uint64_t st_atim; - uint64_t st_mtim; - uint16_t fst_flags; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 7); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, flags); - CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_ptr); - CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, path_len); - UNWRAP_BIGINT_OR_RETURN(args, args[4], Uint64, st_atim); - UNWRAP_BIGINT_OR_RETURN(args, args[5], Uint64, st_mtim); - CHECK_TO_TYPE_OR_RETURN(args, args[6], Uint32, fst_flags); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::PathFilestatSetTimes(WASI& wasi, + WasmMemory memory, + uint32_t fd, + uint32_t flags, + uint32_t path_ptr, + uint32_t path_len, + uint64_t st_atim, + uint64_t st_mtim, + uint32_t fst_flags) { Debug(wasi, "path_filestat_set_times(%d, %d, %d, %d, %d, %d, %d)\n", fd, @@ -1107,40 +896,26 @@ void WASI::PathFilestatSetTimes(const FunctionCallbackInfo& args) { st_atim, st_mtim, fst_flags); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len); - uvwasi_errno_t err = uvwasi_path_filestat_set_times(&wasi->uvw_, - fd, - flags, - &memory[path_ptr], - path_len, - st_atim, - st_mtim, - fst_flags); - args.GetReturnValue().Set(err); + CHECK_BOUNDS_OR_RETURN(memory.size, path_ptr, path_len); + return uvwasi_path_filestat_set_times(&wasi.uvw_, + fd, + flags, + &memory.data[path_ptr], + path_len, + st_atim, + st_mtim, + fst_flags); } - -void WASI::PathLink(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t old_fd; - uint32_t old_flags; - uint32_t old_path_ptr; - uint32_t old_path_len; - uint32_t new_fd; - uint32_t new_path_ptr; - uint32_t new_path_len; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 7); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, old_fd); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, old_flags); - CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, old_path_ptr); - CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, old_path_len); - CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, new_fd); - CHECK_TO_TYPE_OR_RETURN(args, args[5], Uint32, new_path_ptr); - CHECK_TO_TYPE_OR_RETURN(args, args[6], Uint32, new_path_len); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::PathLink(WASI& wasi, + WasmMemory memory, + uint32_t old_fd, + uint32_t old_flags, + uint32_t old_path_ptr, + uint32_t old_path_len, + uint32_t new_fd, + uint32_t new_path_ptr, + uint32_t new_path_len) { Debug(wasi, "path_link(%d, %d, %d, %d, %d, %d, %d)\n", old_fd, @@ -1150,45 +925,29 @@ void WASI::PathLink(const FunctionCallbackInfo& args) { new_fd, new_path_ptr, new_path_len); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, mem_size, old_path_ptr, old_path_len); - CHECK_BOUNDS_OR_RETURN(args, mem_size, new_path_ptr, new_path_len); - uvwasi_errno_t err = uvwasi_path_link(&wasi->uvw_, - old_fd, - old_flags, - &memory[old_path_ptr], - old_path_len, - new_fd, - &memory[new_path_ptr], - new_path_len); - args.GetReturnValue().Set(err); -} - - -void WASI::PathOpen(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t dirfd; - uint32_t dirflags; - uint32_t path_ptr; - uint32_t path_len; - uint32_t o_flags; - uint64_t fs_rights_base; - uint64_t fs_rights_inheriting; - uint32_t fs_flags; - uint32_t fd_ptr; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 9); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, dirfd); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, dirflags); - CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_ptr); - CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, path_len); - CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, o_flags); - UNWRAP_BIGINT_OR_RETURN(args, args[5], Uint64, fs_rights_base); - UNWRAP_BIGINT_OR_RETURN(args, args[6], Uint64, fs_rights_inheriting); - CHECK_TO_TYPE_OR_RETURN(args, args[7], Uint32, fs_flags); - CHECK_TO_TYPE_OR_RETURN(args, args[8], Uint32, fd_ptr); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); + CHECK_BOUNDS_OR_RETURN(memory.size, old_path_ptr, old_path_len); + CHECK_BOUNDS_OR_RETURN(memory.size, new_path_ptr, new_path_len); + return uvwasi_path_link(&wasi.uvw_, + old_fd, + old_flags, + &memory.data[old_path_ptr], + old_path_len, + new_fd, + &memory.data[new_path_ptr], + new_path_len); +} + +uint32_t WASI::PathOpen(WASI& wasi, + WasmMemory memory, + uint32_t dirfd, + uint32_t dirflags, + uint32_t path_ptr, + uint32_t path_len, + uint32_t o_flags, + uint64_t fs_rights_base, + uint64_t fs_rights_inheriting, + uint32_t fs_flags, + uint32_t fd_ptr) { Debug(wasi, "path_open(%d, %d, %d, %d, %d, %d, %d, %d, %d)\n", dirfd, @@ -1200,14 +959,13 @@ void WASI::PathOpen(const FunctionCallbackInfo& args) { fs_rights_inheriting, fs_flags, fd_ptr); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len); - CHECK_BOUNDS_OR_RETURN(args, mem_size, fd_ptr, UVWASI_SERDES_SIZE_fd_t); + CHECK_BOUNDS_OR_RETURN(memory.size, path_ptr, path_len); + CHECK_BOUNDS_OR_RETURN(memory.size, fd_ptr, UVWASI_SERDES_SIZE_fd_t); uvwasi_fd_t fd; - uvwasi_errno_t err = uvwasi_path_open(&wasi->uvw_, + uvwasi_errno_t err = uvwasi_path_open(&wasi.uvw_, dirfd, dirflags, - &memory[path_ptr], + &memory.data[path_ptr], path_len, static_cast(o_flags), fs_rights_base, @@ -1215,30 +973,19 @@ void WASI::PathOpen(const FunctionCallbackInfo& args) { static_cast(fs_flags), &fd); if (err == UVWASI_ESUCCESS) - uvwasi_serdes_write_size_t(memory, fd_ptr, fd); + uvwasi_serdes_write_size_t(memory.data, fd_ptr, fd); - args.GetReturnValue().Set(err); + return err; } - -void WASI::PathReadlink(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t fd; - uint32_t path_ptr; - uint32_t path_len; - uint32_t buf_ptr; - uint32_t buf_len; - uint32_t bufused_ptr; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 6); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, path_ptr); - CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_len); - CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, buf_ptr); - CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, buf_len); - CHECK_TO_TYPE_OR_RETURN(args, args[5], Uint32, bufused_ptr); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::PathReadlink(WASI& wasi, + WasmMemory memory, + uint32_t fd, + uint32_t path_ptr, + uint32_t path_len, + uint32_t buf_ptr, + uint32_t buf_len, + uint32_t bufused_ptr) { Debug(wasi, "path_readlink(%d, %d, %d, %d, %d, %d)\n", fd, @@ -1247,69 +994,42 @@ void WASI::PathReadlink(const FunctionCallbackInfo& args) { buf_ptr, buf_len, bufused_ptr); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len); - CHECK_BOUNDS_OR_RETURN(args, mem_size, buf_ptr, buf_len); - CHECK_BOUNDS_OR_RETURN(args, - mem_size, - bufused_ptr, - UVWASI_SERDES_SIZE_size_t); + CHECK_BOUNDS_OR_RETURN(memory.size, path_ptr, path_len); + CHECK_BOUNDS_OR_RETURN(memory.size, buf_ptr, buf_len); + CHECK_BOUNDS_OR_RETURN(memory.size, bufused_ptr, UVWASI_SERDES_SIZE_size_t); uvwasi_size_t bufused; - uvwasi_errno_t err = uvwasi_path_readlink(&wasi->uvw_, + uvwasi_errno_t err = uvwasi_path_readlink(&wasi.uvw_, fd, - &memory[path_ptr], + &memory.data[path_ptr], path_len, - &memory[buf_ptr], + &memory.data[buf_ptr], buf_len, &bufused); if (err == UVWASI_ESUCCESS) - uvwasi_serdes_write_size_t(memory, bufused_ptr, bufused); + uvwasi_serdes_write_size_t(memory.data, bufused_ptr, bufused); - args.GetReturnValue().Set(err); + return err; } - -void WASI::PathRemoveDirectory(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t fd; - uint32_t path_ptr; - uint32_t path_len; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 3); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, path_ptr); - CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_len); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::PathRemoveDirectory(WASI& wasi, + WasmMemory memory, + uint32_t fd, + uint32_t path_ptr, + uint32_t path_len) { Debug(wasi, "path_remove_directory(%d, %d, %d)\n", fd, path_ptr, path_len); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len); - uvwasi_errno_t err = uvwasi_path_remove_directory(&wasi->uvw_, - fd, - &memory[path_ptr], - path_len); - args.GetReturnValue().Set(err); + CHECK_BOUNDS_OR_RETURN(memory.size, path_ptr, path_len); + return uvwasi_path_remove_directory( + &wasi.uvw_, fd, &memory.data[path_ptr], path_len); } - -void WASI::PathRename(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t old_fd; - uint32_t old_path_ptr; - uint32_t old_path_len; - uint32_t new_fd; - uint32_t new_path_ptr; - uint32_t new_path_len; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 6); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, old_fd); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, old_path_ptr); - CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, old_path_len); - CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, new_fd); - CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, new_path_ptr); - CHECK_TO_TYPE_OR_RETURN(args, args[5], Uint32, new_path_len); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::PathRename(WASI& wasi, + WasmMemory memory, + uint32_t old_fd, + uint32_t old_path_ptr, + uint32_t old_path_len, + uint32_t new_fd, + uint32_t new_path_ptr, + uint32_t new_path_len) { Debug(wasi, "path_rename(%d, %d, %d, %d, %d, %d)\n", old_fd, @@ -1318,36 +1038,24 @@ void WASI::PathRename(const FunctionCallbackInfo& args) { new_fd, new_path_ptr, new_path_len); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, mem_size, old_path_ptr, old_path_len); - CHECK_BOUNDS_OR_RETURN(args, mem_size, new_path_ptr, new_path_len); - uvwasi_errno_t err = uvwasi_path_rename(&wasi->uvw_, - old_fd, - &memory[old_path_ptr], - old_path_len, - new_fd, - &memory[new_path_ptr], - new_path_len); - args.GetReturnValue().Set(err); + CHECK_BOUNDS_OR_RETURN(memory.size, old_path_ptr, old_path_len); + CHECK_BOUNDS_OR_RETURN(memory.size, new_path_ptr, new_path_len); + return uvwasi_path_rename(&wasi.uvw_, + old_fd, + &memory.data[old_path_ptr], + old_path_len, + new_fd, + &memory.data[new_path_ptr], + new_path_len); } - -void WASI::PathSymlink(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t old_path_ptr; - uint32_t old_path_len; - uint32_t fd; - uint32_t new_path_ptr; - uint32_t new_path_len; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 5); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, old_path_ptr); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, old_path_len); - CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, fd); - CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, new_path_ptr); - CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, new_path_len); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::PathSymlink(WASI& wasi, + WasmMemory memory, + uint32_t old_path_ptr, + uint32_t old_path_len, + uint32_t fd, + uint32_t new_path_ptr, + uint32_t new_path_len) { Debug(wasi, "path_symlink(%d, %d, %d, %d, %d)\n", old_path_ptr, @@ -1355,173 +1063,99 @@ void WASI::PathSymlink(const FunctionCallbackInfo& args) { fd, new_path_ptr, new_path_len); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, mem_size, old_path_ptr, old_path_len); - CHECK_BOUNDS_OR_RETURN(args, mem_size, new_path_ptr, new_path_len); - uvwasi_errno_t err = uvwasi_path_symlink(&wasi->uvw_, - &memory[old_path_ptr], - old_path_len, - fd, - &memory[new_path_ptr], - new_path_len); - args.GetReturnValue().Set(err); + CHECK_BOUNDS_OR_RETURN(memory.size, old_path_ptr, old_path_len); + CHECK_BOUNDS_OR_RETURN(memory.size, new_path_ptr, new_path_len); + return uvwasi_path_symlink(&wasi.uvw_, + &memory.data[old_path_ptr], + old_path_len, + fd, + &memory.data[new_path_ptr], + new_path_len); } - -void WASI::PathUnlinkFile(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t fd; - uint32_t path_ptr; - uint32_t path_len; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 3); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, path_ptr); - CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, path_len); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::PathUnlinkFile(WASI& wasi, + WasmMemory memory, + uint32_t fd, + uint32_t path_ptr, + uint32_t path_len) { Debug(wasi, "path_unlink_file(%d, %d, %d)\n", fd, path_ptr, path_len); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, mem_size, path_ptr, path_len); - uvwasi_errno_t err = uvwasi_path_unlink_file(&wasi->uvw_, - fd, - &memory[path_ptr], - path_len); - args.GetReturnValue().Set(err); + CHECK_BOUNDS_OR_RETURN(memory.size, path_ptr, path_len); + return uvwasi_path_unlink_file( + &wasi.uvw_, fd, &memory.data[path_ptr], path_len); } - -void WASI::PollOneoff(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t in_ptr; - uint32_t out_ptr; - uint32_t nsubscriptions; - uint32_t nevents_ptr; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 4); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, in_ptr); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, out_ptr); - CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, nsubscriptions); - CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, nevents_ptr); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::PollOneoff(WASI& wasi, + WasmMemory memory, + uint32_t in_ptr, + uint32_t out_ptr, + uint32_t nsubscriptions, + uint32_t nevents_ptr) { Debug(wasi, "poll_oneoff(%d, %d, %d, %d)\n", in_ptr, out_ptr, nsubscriptions, nevents_ptr); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, - mem_size, - in_ptr, - nsubscriptions * UVWASI_SERDES_SIZE_subscription_t); - CHECK_BOUNDS_OR_RETURN(args, - mem_size, - out_ptr, - nsubscriptions * UVWASI_SERDES_SIZE_event_t); - CHECK_BOUNDS_OR_RETURN(args, - mem_size, - nevents_ptr, - UVWASI_SERDES_SIZE_size_t); + CHECK_BOUNDS_OR_RETURN( + memory.size, in_ptr, nsubscriptions * UVWASI_SERDES_SIZE_subscription_t); + CHECK_BOUNDS_OR_RETURN( + memory.size, out_ptr, nsubscriptions * UVWASI_SERDES_SIZE_event_t); + CHECK_BOUNDS_OR_RETURN(memory.size, nevents_ptr, UVWASI_SERDES_SIZE_size_t); std::vector in(nsubscriptions); std::vector out(nsubscriptions); for (uint32_t i = 0; i < nsubscriptions; ++i) { - uvwasi_serdes_read_subscription_t(memory, in_ptr, &in[i]); + uvwasi_serdes_read_subscription_t(memory.data, in_ptr, &in[i]); in_ptr += UVWASI_SERDES_SIZE_subscription_t; } uvwasi_size_t nevents; - uvwasi_errno_t err = uvwasi_poll_oneoff(&wasi->uvw_, - in.data(), - out.data(), - nsubscriptions, - &nevents); + uvwasi_errno_t err = uvwasi_poll_oneoff( + &wasi.uvw_, in.data(), out.data(), nsubscriptions, &nevents); if (err == UVWASI_ESUCCESS) { - uvwasi_serdes_write_size_t(memory, nevents_ptr, nevents); + uvwasi_serdes_write_size_t(memory.data, nevents_ptr, nevents); for (uint32_t i = 0; i < nsubscriptions; ++i) { - uvwasi_serdes_write_event_t(memory, out_ptr, &out[i]); + uvwasi_serdes_write_event_t(memory.data, out_ptr, &out[i]); out_ptr += UVWASI_SERDES_SIZE_event_t; } } - args.GetReturnValue().Set(err); + return err; } - -void WASI::ProcExit(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t code; - RETURN_IF_BAD_ARG_COUNT(args, 1); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, code); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +void WASI::ProcExit(WASI& wasi, WasmMemory, uint32_t code) { Debug(wasi, "proc_exit(%d)\n", code); - args.GetReturnValue().Set(uvwasi_proc_exit(&wasi->uvw_, code)); + uvwasi_proc_exit(&wasi.uvw_, code); } - -void WASI::ProcRaise(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t sig; - RETURN_IF_BAD_ARG_COUNT(args, 1); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, sig); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::ProcRaise(WASI& wasi, WasmMemory, uint32_t sig) { Debug(wasi, "proc_raise(%d)\n", sig); - uvwasi_errno_t err = uvwasi_proc_raise(&wasi->uvw_, sig); - args.GetReturnValue().Set(err); + return uvwasi_proc_raise(&wasi.uvw_, sig); } - -void WASI::RandomGet(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t buf_ptr; - uint32_t buf_len; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 2); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, buf_ptr); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, buf_len); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::RandomGet(WASI& wasi, + WasmMemory memory, + uint32_t buf_ptr, + uint32_t buf_len) { Debug(wasi, "random_get(%d, %d)\n", buf_ptr, buf_len); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, mem_size, buf_ptr, buf_len); - uvwasi_errno_t err = uvwasi_random_get(&wasi->uvw_, - &memory[buf_ptr], - buf_len); - args.GetReturnValue().Set(err); + CHECK_BOUNDS_OR_RETURN(memory.size, buf_ptr, buf_len); + return uvwasi_random_get(&wasi.uvw_, &memory.data[buf_ptr], buf_len); } - -void WASI::SchedYield(const FunctionCallbackInfo& args) { - WASI* wasi; - RETURN_IF_BAD_ARG_COUNT(args, 0); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::SchedYield(WASI& wasi, WasmMemory) { Debug(wasi, "sched_yield()\n"); - uvwasi_errno_t err = uvwasi_sched_yield(&wasi->uvw_); - args.GetReturnValue().Set(err); + return uvwasi_sched_yield(&wasi.uvw_); } - -void WASI::SockRecv(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t sock; - uint32_t ri_data_ptr; - uint32_t ri_data_len; - uint16_t ri_flags; - uint32_t ro_datalen_ptr; - uint16_t ro_flags_ptr; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 6); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, sock); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, ri_data_ptr); - CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, ri_data_len); - CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, ri_flags); - CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, ro_datalen_ptr); - CHECK_TO_TYPE_OR_RETURN(args, args[5], Uint32, ro_flags_ptr); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::SockRecv(WASI& wasi, + WasmMemory memory, + uint32_t sock, + uint32_t ri_data_ptr, + uint32_t ri_data_len, + uint32_t ri_flags, + uint32_t ro_datalen_ptr, + uint32_t ro_flags_ptr) { Debug(wasi, "sock_recv(%d, %d, %d, %d, %d, %d)\n", sock, @@ -1530,27 +1164,20 @@ void WASI::SockRecv(const FunctionCallbackInfo& args) { ri_flags, ro_datalen_ptr, ro_flags_ptr); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, - mem_size, - ri_data_ptr, - ri_data_len * UVWASI_SERDES_SIZE_iovec_t); - CHECK_BOUNDS_OR_RETURN(args, mem_size, ro_datalen_ptr, 4); - CHECK_BOUNDS_OR_RETURN(args, mem_size, ro_flags_ptr, 4); + CHECK_BOUNDS_OR_RETURN( + memory.size, ri_data_ptr, ri_data_len * UVWASI_SERDES_SIZE_iovec_t); + CHECK_BOUNDS_OR_RETURN(memory.size, ro_datalen_ptr, 4); + CHECK_BOUNDS_OR_RETURN(memory.size, ro_flags_ptr, 4); std::vector ri_data(ri_data_len); - uvwasi_errno_t err = uvwasi_serdes_readv_iovec_t(memory, - mem_size, - ri_data_ptr, - ri_data.data(), - ri_data_len); + uvwasi_errno_t err = uvwasi_serdes_readv_iovec_t( + memory.data, memory.size, ri_data_ptr, ri_data.data(), ri_data_len); if (err != UVWASI_ESUCCESS) { - args.GetReturnValue().Set(err); - return; + return err; } uvwasi_size_t ro_datalen; uvwasi_roflags_t ro_flags; - err = uvwasi_sock_recv(&wasi->uvw_, + err = uvwasi_sock_recv(&wasi.uvw_, sock, ri_data.data(), ri_data_len, @@ -1558,30 +1185,20 @@ void WASI::SockRecv(const FunctionCallbackInfo& args) { &ro_datalen, &ro_flags); if (err == UVWASI_ESUCCESS) { - uvwasi_serdes_write_size_t(memory, ro_datalen_ptr, ro_datalen); - uvwasi_serdes_write_roflags_t(memory, ro_flags_ptr, ro_flags); + uvwasi_serdes_write_size_t(memory.data, ro_datalen_ptr, ro_datalen); + uvwasi_serdes_write_roflags_t(memory.data, ro_flags_ptr, ro_flags); } - args.GetReturnValue().Set(err); + return err; } - -void WASI::SockSend(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t sock; - uint32_t si_data_ptr; - uint32_t si_data_len; - uint16_t si_flags; - uint32_t so_datalen_ptr; - char* memory; - size_t mem_size; - RETURN_IF_BAD_ARG_COUNT(args, 5); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, sock); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, si_data_ptr); - CHECK_TO_TYPE_OR_RETURN(args, args[2], Uint32, si_data_len); - CHECK_TO_TYPE_OR_RETURN(args, args[3], Uint32, si_flags); - CHECK_TO_TYPE_OR_RETURN(args, args[4], Uint32, so_datalen_ptr); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::SockSend(WASI& wasi, + WasmMemory memory, + uint32_t sock, + uint32_t si_data_ptr, + uint32_t si_data_len, + uint32_t si_flags, + uint32_t so_datalen_ptr) { Debug(wasi, "sock_send(%d, %d, %d, %d, %d)\n", sock, @@ -1589,54 +1206,34 @@ void WASI::SockSend(const FunctionCallbackInfo& args) { si_data_len, si_flags, so_datalen_ptr); - GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size); - CHECK_BOUNDS_OR_RETURN(args, - mem_size, - si_data_ptr, - si_data_len * UVWASI_SERDES_SIZE_ciovec_t); - CHECK_BOUNDS_OR_RETURN(args, - mem_size, - so_datalen_ptr, - UVWASI_SERDES_SIZE_size_t); + CHECK_BOUNDS_OR_RETURN( + memory.size, si_data_ptr, si_data_len * UVWASI_SERDES_SIZE_ciovec_t); + CHECK_BOUNDS_OR_RETURN( + memory.size, so_datalen_ptr, UVWASI_SERDES_SIZE_size_t); std::vector si_data(si_data_len); - uvwasi_errno_t err = uvwasi_serdes_readv_ciovec_t(memory, - mem_size, - si_data_ptr, - si_data.data(), - si_data_len); + uvwasi_errno_t err = uvwasi_serdes_readv_ciovec_t( + memory.data, memory.size, si_data_ptr, si_data.data(), si_data_len); if (err != UVWASI_ESUCCESS) { - args.GetReturnValue().Set(err); - return; + return err; } uvwasi_size_t so_datalen; - err = uvwasi_sock_send(&wasi->uvw_, - sock, - si_data.data(), - si_data_len, - si_flags, - &so_datalen); + err = uvwasi_sock_send( + &wasi.uvw_, sock, si_data.data(), si_data_len, si_flags, &so_datalen); if (err == UVWASI_ESUCCESS) - uvwasi_serdes_write_size_t(memory, so_datalen_ptr, so_datalen); + uvwasi_serdes_write_size_t(memory.data, so_datalen_ptr, so_datalen); - args.GetReturnValue().Set(err); + return err; } - -void WASI::SockShutdown(const FunctionCallbackInfo& args) { - WASI* wasi; - uint32_t sock; - uint8_t how; - RETURN_IF_BAD_ARG_COUNT(args, 2); - CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, sock); - CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, how); - ASSIGN_INITIALIZED_OR_RETURN_UNWRAP(&wasi, args.This()); +uint32_t WASI::SockShutdown(WASI& wasi, + WasmMemory, + uint32_t sock, + uint32_t how) { Debug(wasi, "sock_shutdown(%d, %d)\n", sock, how); - uvwasi_errno_t err = uvwasi_sock_shutdown(&wasi->uvw_, sock, how); - args.GetReturnValue().Set(err); + return uvwasi_sock_shutdown(&wasi.uvw_, sock, how); } - void WASI::_SetMemory(const FunctionCallbackInfo& args) { WASI* wasi; ASSIGN_OR_RETURN_UNWRAP(&wasi, args.This()); @@ -1650,17 +1247,6 @@ void WASI::_SetMemory(const FunctionCallbackInfo& args) { wasi->memory_.Reset(wasi->env()->isolate(), args[0].As()); } - -uvwasi_errno_t WASI::backingStore(char** store, size_t* byte_length) { - Local memory = PersistentToLocal::Strong(this->memory_); - Local ab = memory->Buffer(); - *byte_length = ab->ByteLength(); - *store = static_cast(ab->Data()); - CHECK_NOT_NULL(*store); - return UVWASI_ESUCCESS; -} - - static void Initialize(Local target, Local unused, Local context, @@ -1672,57 +1258,55 @@ static void Initialize(Local target, tmpl->InstanceTemplate()->SetInternalFieldCount(WASI::kInternalFieldCount); tmpl->Inherit(BaseObject::GetConstructorTemplate(env)); - SetProtoMethod(isolate, tmpl, "args_get", WASI::ArgsGet); - SetProtoMethod(isolate, tmpl, "args_sizes_get", WASI::ArgsSizesGet); - SetProtoMethod(isolate, tmpl, "clock_res_get", WASI::ClockResGet); - SetProtoMethod(isolate, tmpl, "clock_time_get", WASI::ClockTimeGet); - SetProtoMethod(isolate, tmpl, "environ_get", WASI::EnvironGet); - SetProtoMethod(isolate, tmpl, "environ_sizes_get", WASI::EnvironSizesGet); - SetProtoMethod(isolate, tmpl, "fd_advise", WASI::FdAdvise); - SetProtoMethod(isolate, tmpl, "fd_allocate", WASI::FdAllocate); - SetProtoMethod(isolate, tmpl, "fd_close", WASI::FdClose); - SetProtoMethod(isolate, tmpl, "fd_datasync", WASI::FdDatasync); - SetProtoMethod(isolate, tmpl, "fd_fdstat_get", WASI::FdFdstatGet); - SetProtoMethod(isolate, tmpl, "fd_fdstat_set_flags", WASI::FdFdstatSetFlags); - SetProtoMethod( - isolate, tmpl, "fd_fdstat_set_rights", WASI::FdFdstatSetRights); - SetProtoMethod(isolate, tmpl, "fd_filestat_get", WASI::FdFilestatGet); - SetProtoMethod( - isolate, tmpl, "fd_filestat_set_size", WASI::FdFilestatSetSize); - SetProtoMethod( - isolate, tmpl, "fd_filestat_set_times", WASI::FdFilestatSetTimes); - SetProtoMethod(isolate, tmpl, "fd_pread", WASI::FdPread); - SetProtoMethod(isolate, tmpl, "fd_prestat_get", WASI::FdPrestatGet); - SetProtoMethod(isolate, tmpl, "fd_prestat_dir_name", WASI::FdPrestatDirName); - SetProtoMethod(isolate, tmpl, "fd_pwrite", WASI::FdPwrite); - SetProtoMethod(isolate, tmpl, "fd_read", WASI::FdRead); - SetProtoMethod(isolate, tmpl, "fd_readdir", WASI::FdReaddir); - SetProtoMethod(isolate, tmpl, "fd_renumber", WASI::FdRenumber); - SetProtoMethod(isolate, tmpl, "fd_seek", WASI::FdSeek); - SetProtoMethod(isolate, tmpl, "fd_sync", WASI::FdSync); - SetProtoMethod(isolate, tmpl, "fd_tell", WASI::FdTell); - SetProtoMethod(isolate, tmpl, "fd_write", WASI::FdWrite); - SetProtoMethod( - isolate, tmpl, "path_create_directory", WASI::PathCreateDirectory); - SetProtoMethod(isolate, tmpl, "path_filestat_get", WASI::PathFilestatGet); - SetProtoMethod( - isolate, tmpl, "path_filestat_set_times", WASI::PathFilestatSetTimes); - SetProtoMethod(isolate, tmpl, "path_link", WASI::PathLink); - SetProtoMethod(isolate, tmpl, "path_open", WASI::PathOpen); - SetProtoMethod(isolate, tmpl, "path_readlink", WASI::PathReadlink); - SetProtoMethod( - isolate, tmpl, "path_remove_directory", WASI::PathRemoveDirectory); - SetProtoMethod(isolate, tmpl, "path_rename", WASI::PathRename); - SetProtoMethod(isolate, tmpl, "path_symlink", WASI::PathSymlink); - SetProtoMethod(isolate, tmpl, "path_unlink_file", WASI::PathUnlinkFile); - SetProtoMethod(isolate, tmpl, "poll_oneoff", WASI::PollOneoff); - SetProtoMethod(isolate, tmpl, "proc_exit", WASI::ProcExit); - SetProtoMethod(isolate, tmpl, "proc_raise", WASI::ProcRaise); - SetProtoMethod(isolate, tmpl, "random_get", WASI::RandomGet); - SetProtoMethod(isolate, tmpl, "sched_yield", WASI::SchedYield); - SetProtoMethod(isolate, tmpl, "sock_recv", WASI::SockRecv); - SetProtoMethod(isolate, tmpl, "sock_send", WASI::SockSend); - SetProtoMethod(isolate, tmpl, "sock_shutdown", WASI::SockShutdown); +#define V(F, name) \ + SetFunction(WASI::F, env, name, tmpl); + + V(ArgsGet, "args_get") + V(ArgsSizesGet, "args_sizes_get") + V(ClockResGet, "clock_res_get") + V(ClockTimeGet, "clock_time_get") + V(EnvironGet, "environ_get") + V(EnvironSizesGet, "environ_sizes_get") + V(FdAdvise, "fd_advise") + V(FdAllocate, "fd_allocate") + V(FdClose, "fd_close") + V(FdDatasync, "fd_datasync") + V(FdFdstatGet, "fd_fdstat_get") + V(FdFdstatSetFlags, "fd_fdstat_set_flags") + V(FdFdstatSetRights, "fd_fdstat_set_rights") + V(FdFilestatGet, "fd_filestat_get") + V(FdFilestatSetSize, "fd_filestat_set_size") + V(FdFilestatSetTimes, "fd_filestat_set_times") + V(FdPread, "fd_pread") + V(FdPrestatGet, "fd_prestat_get") + V(FdPrestatDirName, "fd_prestat_dir_name") + V(FdPwrite, "fd_pwrite") + V(FdRead, "fd_read") + V(FdReaddir, "fd_readdir") + V(FdRenumber, "fd_renumber") + V(FdSeek, "fd_seek") + V(FdSync, "fd_sync") + V(FdTell, "fd_tell") + V(FdWrite, "fd_write") + V(PathCreateDirectory, "path_create_directory") + V(PathFilestatGet, "path_filestat_get") + V(PathFilestatSetTimes, "path_filestat_set_times") + V(PathLink, "path_link") + V(PathOpen, "path_open") + V(PathReadlink, "path_readlink") + V(PathRemoveDirectory, "path_remove_directory") + V(PathRename, "path_rename") + V(PathSymlink, "path_symlink") + V(PathUnlinkFile, "path_unlink_file") + V(PollOneoff, "poll_oneoff") + V(ProcExit, "proc_exit") + V(ProcRaise, "proc_raise") + V(RandomGet, "random_get") + V(SchedYield, "sched_yield") + V(SockRecv, "sock_recv") + V(SockSend, "sock_send") + V(SockShutdown, "sock_shutdown") +#undef V SetInstanceMethod(isolate, tmpl, "_setMemory", WASI::_SetMemory); diff --git a/src/node_wasi.h b/src/node_wasi.h index b3814ddc31033a..a28bdd8ad1bfa6 100644 --- a/src/node_wasi.h +++ b/src/node_wasi.h @@ -6,10 +6,15 @@ #include "base_object.h" #include "node_mem.h" #include "uvwasi.h" +#include "v8-fast-api-calls.h" namespace node { namespace wasi { +struct WasmMemory { + char* data; + size_t size; +}; class WASI : public BaseObject, public mem::NgLibMemoryManager { @@ -23,57 +28,120 @@ class WASI : public BaseObject, SET_MEMORY_INFO_NAME(WASI) SET_SELF_SIZE(WASI) - static void ArgsGet(const v8::FunctionCallbackInfo& args); - static void ArgsSizesGet(const v8::FunctionCallbackInfo& args); - static void ClockResGet(const v8::FunctionCallbackInfo& args); - static void ClockTimeGet(const v8::FunctionCallbackInfo& args); - static void EnvironGet(const v8::FunctionCallbackInfo& args); - static void EnvironSizesGet(const v8::FunctionCallbackInfo& args); - static void FdAdvise(const v8::FunctionCallbackInfo& args); - static void FdAllocate(const v8::FunctionCallbackInfo& args); - static void FdClose(const v8::FunctionCallbackInfo& args); - static void FdDatasync(const v8::FunctionCallbackInfo& args); - static void FdFdstatGet(const v8::FunctionCallbackInfo& args); - static void FdFdstatSetFlags(const v8::FunctionCallbackInfo& args); - static void FdFdstatSetRights( - const v8::FunctionCallbackInfo& args); - static void FdFilestatGet(const v8::FunctionCallbackInfo& args); - static void FdFilestatSetSize( - const v8::FunctionCallbackInfo& args); - static void FdFilestatSetTimes( - const v8::FunctionCallbackInfo& args); - static void FdPread(const v8::FunctionCallbackInfo& args); - static void FdPrestatGet(const v8::FunctionCallbackInfo& args); - static void FdPrestatDirName(const v8::FunctionCallbackInfo& args); - static void FdPwrite(const v8::FunctionCallbackInfo& args); - static void FdRead(const v8::FunctionCallbackInfo& args); - static void FdReaddir(const v8::FunctionCallbackInfo& args); - static void FdRenumber(const v8::FunctionCallbackInfo& args); - static void FdSeek(const v8::FunctionCallbackInfo& args); - static void FdSync(const v8::FunctionCallbackInfo& args); - static void FdTell(const v8::FunctionCallbackInfo& args); - static void FdWrite(const v8::FunctionCallbackInfo& args); - static void PathCreateDirectory( - const v8::FunctionCallbackInfo& args); - static void PathFilestatGet(const v8::FunctionCallbackInfo& args); - static void PathFilestatSetTimes( - const v8::FunctionCallbackInfo& args); - static void PathLink(const v8::FunctionCallbackInfo& args); - static void PathOpen(const v8::FunctionCallbackInfo& args); - static void PathReadlink(const v8::FunctionCallbackInfo& args); - static void PathRemoveDirectory( - const v8::FunctionCallbackInfo& args); - static void PathRename(const v8::FunctionCallbackInfo& args); - static void PathSymlink(const v8::FunctionCallbackInfo& args); - static void PathUnlinkFile(const v8::FunctionCallbackInfo& args); - static void PollOneoff(const v8::FunctionCallbackInfo& args); - static void ProcExit(const v8::FunctionCallbackInfo& args); - static void ProcRaise(const v8::FunctionCallbackInfo& args); - static void RandomGet(const v8::FunctionCallbackInfo& args); - static void SchedYield(const v8::FunctionCallbackInfo& args); - static void SockRecv(const v8::FunctionCallbackInfo& args); - static void SockSend(const v8::FunctionCallbackInfo& args); - static void SockShutdown(const v8::FunctionCallbackInfo& args); + static uint32_t ArgsGet(WASI&, WasmMemory, uint32_t, uint32_t); + static uint32_t ArgsSizesGet(WASI&, WasmMemory, uint32_t, uint32_t); + static uint32_t ClockResGet(WASI&, WasmMemory, uint32_t, uint32_t); + static uint32_t ClockTimeGet(WASI&, WasmMemory, uint32_t, uint64_t, uint32_t); + static uint32_t EnvironGet(WASI&, WasmMemory, uint32_t, uint32_t); + static uint32_t EnvironSizesGet(WASI&, WasmMemory, uint32_t, uint32_t); + static uint32_t FdAdvise( + WASI&, WasmMemory, uint32_t, uint64_t, uint64_t, uint32_t); + static uint32_t FdAllocate(WASI&, WasmMemory, uint32_t, uint64_t, uint64_t); + static uint32_t FdClose(WASI&, WasmMemory, uint32_t); + static uint32_t FdDatasync(WASI&, WasmMemory, uint32_t); + static uint32_t FdFdstatGet(WASI&, WasmMemory, uint32_t, uint32_t); + static uint32_t FdFdstatSetFlags(WASI&, WasmMemory, uint32_t, uint32_t); + static uint32_t FdFdstatSetRights( + WASI&, WasmMemory, uint32_t, uint64_t, uint64_t); + static uint32_t FdFilestatGet(WASI&, WasmMemory, uint32_t, uint32_t); + static uint32_t FdFilestatSetSize(WASI&, WasmMemory, uint32_t, uint64_t); + static uint32_t FdFilestatSetTimes( + WASI&, WasmMemory, uint32_t, uint64_t, uint64_t, uint32_t); + static uint32_t FdPread(WASI&, + WasmMemory memory, + uint32_t, + uint32_t, + uint32_t, + uint64_t, + uint32_t); + static uint32_t FdPrestatGet(WASI&, WasmMemory, uint32_t, uint32_t); + static uint32_t FdPrestatDirName( + WASI&, WasmMemory, uint32_t, uint32_t, uint32_t); + static uint32_t FdPwrite( + WASI&, WasmMemory, uint32_t, uint32_t, uint32_t, uint64_t, uint32_t); + static uint32_t FdRead( + WASI&, WasmMemory, uint32_t, uint32_t, uint32_t, uint32_t); + static uint32_t FdReaddir( + WASI&, WasmMemory, uint32_t, uint32_t, uint32_t, uint64_t, uint32_t); + static uint32_t FdRenumber(WASI&, WasmMemory, uint32_t, uint32_t); + static uint32_t FdSeek( + WASI&, WasmMemory, uint32_t, int64_t, uint32_t, uint32_t); + static uint32_t FdSync(WASI&, WasmMemory, uint32_t); + static uint32_t FdTell(WASI&, WasmMemory, uint32_t, uint32_t); + static uint32_t FdWrite( + WASI&, WasmMemory, uint32_t, uint32_t, uint32_t, uint32_t); + static uint32_t PathCreateDirectory( + WASI&, WasmMemory, uint32_t, uint32_t, uint32_t); + static uint32_t PathFilestatGet( + WASI&, WasmMemory, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); + static uint32_t PathFilestatSetTimes(WASI&, + WasmMemory, + uint32_t, + uint32_t, + uint32_t, + uint32_t, + uint64_t, + uint64_t, + uint32_t); + static uint32_t PathLink(WASI&, + WasmMemory, + uint32_t, + uint32_t, + uint32_t, + uint32_t, + uint32_t, + uint32_t, + uint32_t); + static uint32_t PathOpen(WASI&, + WasmMemory, + uint32_t, + uint32_t, + uint32_t, + uint32_t, + uint32_t, + uint64_t, + uint64_t, + uint32_t, + uint32_t); + static uint32_t PathReadlink(WASI&, + WasmMemory, + uint32_t, + uint32_t, + uint32_t, + uint32_t, + uint32_t, + uint32_t); + static uint32_t PathRemoveDirectory( + WASI&, WasmMemory, uint32_t, uint32_t, uint32_t); + static uint32_t PathRename(WASI&, + WasmMemory, + uint32_t, + uint32_t, + uint32_t, + uint32_t, + uint32_t, + uint32_t); + static uint32_t PathSymlink( + WASI&, WasmMemory, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); + static uint32_t PathUnlinkFile( + WASI&, WasmMemory, uint32_t, uint32_t, uint32_t); + static uint32_t PollOneoff( + WASI&, WasmMemory, uint32_t, uint32_t, uint32_t, uint32_t); + static void ProcExit(WASI&, WasmMemory, uint32_t); + static uint32_t ProcRaise(WASI&, WasmMemory, uint32_t); + static uint32_t RandomGet(WASI&, WasmMemory, uint32_t, uint32_t); + static uint32_t SchedYield(WASI&, WasmMemory); + static uint32_t SockRecv(WASI&, + WasmMemory, + uint32_t, + uint32_t, + uint32_t, + uint32_t, + uint32_t, + uint32_t); + static uint32_t SockSend( + WASI&, WasmMemory, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); + static uint32_t SockShutdown(WASI&, WasmMemory, uint32_t, uint32_t); static void _SetMemory(const v8::FunctionCallbackInfo& args); @@ -82,17 +150,24 @@ class WASI : public BaseObject, void IncreaseAllocatedSize(size_t size); void DecreaseAllocatedSize(size_t size); + // as a C++14 desugaring of `` + template + class WasiFunction { + public: + static void SetFunction(Environment*, + const char*, + v8::Local); + + private: + static R FastCallback(v8::Local receiver, + Args..., + v8::FastApiCallbackOptions&); + + static void SlowCallback(const v8::FunctionCallbackInfo&); + }; + private: ~WASI() override; - inline void readUInt8(char* memory, uint8_t* value, uint32_t offset); - inline void readUInt16(char* memory, uint16_t* value, uint32_t offset); - inline void readUInt32(char* memory, uint32_t* value, uint32_t offset); - inline void readUInt64(char* memory, uint64_t* value, uint32_t offset); - inline void writeUInt8(char* memory, uint8_t value, uint32_t offset); - inline void writeUInt16(char* memory, uint16_t value, uint32_t offset); - inline void writeUInt32(char* memory, uint32_t value, uint32_t offset); - inline void writeUInt64(char* memory, uint64_t value, uint32_t offset); - uvwasi_errno_t backingStore(char** store, size_t* byte_length); uvwasi_t uvw_; v8::Global memory_; uvwasi_mem_t alloc_info_; diff --git a/test/wasi/Makefile b/test/wasi/Makefile index 42d3b4e3fa7a80..14563feda50961 100644 --- a/test/wasi/Makefile +++ b/test/wasi/Makefile @@ -1,12 +1,13 @@ CC = /opt/wasi-sdk/bin/clang -TARGET = wasm32-unknown-wasi +TARGET = wasm32-wasi SYSROOT = +CFLAGS = -D_WASI_EMULATED_PROCESS_CLOCKS -lwasi-emulated-process-clocks OBJ = $(patsubst c/%.c, wasm/%.wasm, $(wildcard c/*.c)) all: $(OBJ) wasm/%.wasm : c/%.c - $(CC) $< --target=$(TARGET) --sysroot=$(SYSROOT) -s -o $@ + $(CC) $< $(CFLAGS) --target=$(TARGET) --sysroot=$(SYSROOT) -s -o $@ .PHONY clean: rm -f $(OBJ) diff --git a/test/wasi/test-wasi.js b/test/wasi/test-wasi.js index 949fc77e97a7a3..e262d4a45c3718 100644 --- a/test/wasi/test-wasi.js +++ b/test/wasi/test-wasi.js @@ -35,7 +35,7 @@ if (process.argv[2] === 'wasi-child') { const cp = require('child_process'); const { checkoutEOL } = common; - function runWASI(options) { + function innerRunWASI(options, args) { console.log('executing', options.test); const opts = { env: { @@ -49,6 +49,7 @@ if (process.argv[2] === 'wasi-child') { opts.input = options.stdin; const child = cp.spawnSync(process.execPath, [ + ...args, '--experimental-wasi-unstable-preview1', __filename, 'wasi-child', @@ -60,6 +61,11 @@ if (process.argv[2] === 'wasi-child') { assert.strictEqual(child.stdout.toString(), options.stdout || ''); } + function runWASI(options) { + innerRunWASI(options, ['--no-turbo-fast-api-calls']); + innerRunWASI(options, ['--turbo-fast-api-calls']); + } + runWASI({ test: 'cant_dotdot' }); // Tests that are currently unsupported on IBM i PASE. diff --git a/test/wasi/wasm/cant_dotdot.wasm b/test/wasi/wasm/cant_dotdot.wasm index 1ffbe23c6afdb2..b078dfca1afbc9 100755 Binary files a/test/wasi/wasm/cant_dotdot.wasm and b/test/wasi/wasm/cant_dotdot.wasm differ diff --git a/test/wasi/wasm/clock_getres.wasm b/test/wasi/wasm/clock_getres.wasm index 510049dca4a009..9d47599c7b9478 100755 Binary files a/test/wasi/wasm/clock_getres.wasm and b/test/wasi/wasm/clock_getres.wasm differ diff --git a/test/wasi/wasm/create_symlink.wasm b/test/wasi/wasm/create_symlink.wasm index 1612e975d87e5d..291f17eedcfa76 100755 Binary files a/test/wasi/wasm/create_symlink.wasm and b/test/wasi/wasm/create_symlink.wasm differ diff --git a/test/wasi/wasm/exitcode.wasm b/test/wasi/wasm/exitcode.wasm index ceb797f8b31ddf..0472e62d851095 100755 Binary files a/test/wasi/wasm/exitcode.wasm and b/test/wasi/wasm/exitcode.wasm differ diff --git a/test/wasi/wasm/fd_prestat_get_refresh.wasm b/test/wasi/wasm/fd_prestat_get_refresh.wasm index 159cfa9e4c8159..d645b42c806791 100755 Binary files a/test/wasi/wasm/fd_prestat_get_refresh.wasm and b/test/wasi/wasm/fd_prestat_get_refresh.wasm differ diff --git a/test/wasi/wasm/follow_symlink.wasm b/test/wasi/wasm/follow_symlink.wasm index f5f236c53f2440..b79242eb13141a 100755 Binary files a/test/wasi/wasm/follow_symlink.wasm and b/test/wasi/wasm/follow_symlink.wasm differ diff --git a/test/wasi/wasm/freopen.wasm b/test/wasi/wasm/freopen.wasm index fb417fbe21fa69..5f774d782332f2 100755 Binary files a/test/wasi/wasm/freopen.wasm and b/test/wasi/wasm/freopen.wasm differ diff --git a/test/wasi/wasm/ftruncate.wasm b/test/wasi/wasm/ftruncate.wasm index a16e90d98ddb28..60542eeb6a0ff6 100755 Binary files a/test/wasi/wasm/ftruncate.wasm and b/test/wasi/wasm/ftruncate.wasm differ diff --git a/test/wasi/wasm/getentropy.wasm b/test/wasi/wasm/getentropy.wasm index 527ac6a17d3008..f9e4cb52869892 100755 Binary files a/test/wasi/wasm/getentropy.wasm and b/test/wasi/wasm/getentropy.wasm differ diff --git a/test/wasi/wasm/getrusage.wasm b/test/wasi/wasm/getrusage.wasm index c9546e232c7956..ff131ee42a09b6 100755 Binary files a/test/wasi/wasm/getrusage.wasm and b/test/wasi/wasm/getrusage.wasm differ diff --git a/test/wasi/wasm/gettimeofday.wasm b/test/wasi/wasm/gettimeofday.wasm index 7629b119d8895d..408a5cfc9ef209 100755 Binary files a/test/wasi/wasm/gettimeofday.wasm and b/test/wasi/wasm/gettimeofday.wasm differ diff --git a/test/wasi/wasm/link.wasm b/test/wasi/wasm/link.wasm index 60f5c07601a2af..4a9719df3035d5 100755 Binary files a/test/wasi/wasm/link.wasm and b/test/wasi/wasm/link.wasm differ diff --git a/test/wasi/wasm/main_args.wasm b/test/wasi/wasm/main_args.wasm index 60cb69defe2d32..1e14b8351b71e6 100755 Binary files a/test/wasi/wasm/main_args.wasm and b/test/wasi/wasm/main_args.wasm differ diff --git a/test/wasi/wasm/notdir.wasm b/test/wasi/wasm/notdir.wasm index 6b592fc17b032f..ae22933603d049 100755 Binary files a/test/wasi/wasm/notdir.wasm and b/test/wasi/wasm/notdir.wasm differ diff --git a/test/wasi/wasm/poll.wasm b/test/wasi/wasm/poll.wasm index 37e17b8d880ad2..22c0fe859d7ad3 100755 Binary files a/test/wasi/wasm/poll.wasm and b/test/wasi/wasm/poll.wasm differ diff --git a/test/wasi/wasm/preopen_populates.wasm b/test/wasi/wasm/preopen_populates.wasm index 618050b3b4c210..1236bbe1cc6e6e 100755 Binary files a/test/wasi/wasm/preopen_populates.wasm and b/test/wasi/wasm/preopen_populates.wasm differ diff --git a/test/wasi/wasm/read_file.wasm b/test/wasi/wasm/read_file.wasm index 1c5e8107e0a9f7..bc1433e09e961e 100755 Binary files a/test/wasi/wasm/read_file.wasm and b/test/wasi/wasm/read_file.wasm differ diff --git a/test/wasi/wasm/read_file_twice.wasm b/test/wasi/wasm/read_file_twice.wasm index 6917a105eb4c08..6b73ae11309fde 100755 Binary files a/test/wasi/wasm/read_file_twice.wasm and b/test/wasi/wasm/read_file_twice.wasm differ diff --git a/test/wasi/wasm/readdir.wasm b/test/wasi/wasm/readdir.wasm index ce6cb4999524db..c315d2d5b8e87e 100755 Binary files a/test/wasi/wasm/readdir.wasm and b/test/wasi/wasm/readdir.wasm differ diff --git a/test/wasi/wasm/stat.wasm b/test/wasi/wasm/stat.wasm index 4a50c0282bb60a..6f924b74d9b22c 100755 Binary files a/test/wasi/wasm/stat.wasm and b/test/wasi/wasm/stat.wasm differ diff --git a/test/wasi/wasm/stdin.wasm b/test/wasi/wasm/stdin.wasm index 3cc548607af2e0..f9ea0fd336d50e 100755 Binary files a/test/wasi/wasm/stdin.wasm and b/test/wasi/wasm/stdin.wasm differ diff --git a/test/wasi/wasm/symlink_escape.wasm b/test/wasi/wasm/symlink_escape.wasm index fcb8cfd5790782..4ff589da7d438c 100755 Binary files a/test/wasi/wasm/symlink_escape.wasm and b/test/wasi/wasm/symlink_escape.wasm differ diff --git a/test/wasi/wasm/symlink_loop.wasm b/test/wasi/wasm/symlink_loop.wasm index 98e5c62f4b8355..409102d7ee21a0 100755 Binary files a/test/wasi/wasm/symlink_loop.wasm and b/test/wasi/wasm/symlink_loop.wasm differ diff --git a/test/wasi/wasm/write_file.wasm b/test/wasi/wasm/write_file.wasm index c21d0c2bfef5c7..005c3da09de043 100755 Binary files a/test/wasi/wasm/write_file.wasm and b/test/wasi/wasm/write_file.wasm differ