Skip to content

Commit

Permalink
wasi: Add UVWASI interface
Browse files Browse the repository at this point in the history
  • Loading branch information
gumb0 committed May 6, 2021
1 parent 25850f8 commit 585c9e8
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 21 deletions.
2 changes: 1 addition & 1 deletion tools/wasi/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ add_library(wasi)
add_library(fizzy::wasi ALIAS wasi)
target_include_directories(wasi PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(wasi PUBLIC fizzy::fizzy-internal PRIVATE uvwasi::uvwasi)
target_sources(wasi PRIVATE wasi.cpp wasi.hpp)
target_sources(wasi PRIVATE wasi.cpp wasi.hpp uvwasi.hpp uvwasi.cpp)

add_executable(fizzy-wasi)
target_link_libraries(fizzy-wasi PRIVATE fizzy::wasi)
Expand Down
69 changes: 69 additions & 0 deletions tools/wasi/uvwasi.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Fizzy: A fast WebAssembly interpreter
// Copyright 2021 The Fizzy Authors.
// SPDX-License-Identifier: Apache-2.0

#include "uvwasi.hpp"
#include <uvwasi.h>

namespace fizzy::wasi
{
namespace
{
class UVWASIImpl final : public UVWASI
{
/// UVWASI state.
uvwasi_t m_state{};

public:
uvwasi_errno_t init(uvwasi_size_t argc, const char** argv) noexcept final
{
// Initialisation settings.
// TODO: Make const after https://github.com/nodejs/uvwasi/pull/155 is merged.
uvwasi_options_t options = {
3, // sizeof fd_table
0, nullptr, // NOTE: no remappings
argc, argv,
nullptr, // TODO: support env
0, 1, 2,
nullptr, // NOTE: no special allocator
};
return uvwasi_init(&m_state, &options);
}

uvwasi_errno_t proc_exit(uvwasi_exitcode_t exit_code) noexcept final
{
return uvwasi_proc_exit(&m_state, exit_code);
}

uvwasi_errno_t fd_write(uvwasi_fd_t fd, const uvwasi_ciovec_t* iovs, uvwasi_size_t iovs_len,
uvwasi_size_t* nwritten) noexcept final
{
return uvwasi_fd_write(&m_state, fd, iovs, iovs_len, nwritten);
}

uvwasi_errno_t fd_read(uvwasi_fd_t fd, const uvwasi_iovec_t* iovs, uvwasi_size_t iovs_len,
uvwasi_size_t* nread) noexcept final
{
return uvwasi_fd_read(&m_state, fd, iovs, iovs_len, nread);
}

uvwasi_errno_t fd_prestat_get(uvwasi_fd_t fd, uvwasi_prestat_t* buf) noexcept final
{
return uvwasi_fd_prestat_get(&m_state, fd, buf);
}

uvwasi_errno_t environ_sizes_get(
uvwasi_size_t* environ_count, uvwasi_size_t* environ_buf_size) noexcept final
{
return uvwasi_environ_sizes_get(&m_state, environ_count, environ_buf_size);
}
};
} // namespace

UVWASI::~UVWASI() {}

std::unique_ptr<UVWASI> create_uvwasi()
{
return std::make_unique<UVWASIImpl>();
}
} // namespace fizzy::wasi
36 changes: 36 additions & 0 deletions tools/wasi/uvwasi.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Fizzy: A fast WebAssembly interpreter
// Copyright 2021 The Fizzy Authors.
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include <wasi_types.h>
#include <memory>

namespace fizzy::wasi
{
/// UVWASI interface.
class UVWASI
{
public:
virtual ~UVWASI();

virtual uvwasi_errno_t init(uvwasi_size_t argc, const char** argv) noexcept = 0;

virtual uvwasi_errno_t proc_exit(uvwasi_exitcode_t exit_code) noexcept = 0;

virtual uvwasi_errno_t fd_write(uvwasi_fd_t fd, const uvwasi_ciovec_t* iovs,
uvwasi_size_t iovs_len, uvwasi_size_t* nwritten) noexcept = 0;

virtual uvwasi_errno_t fd_read(uvwasi_fd_t fd, const uvwasi_iovec_t* iovs,
uvwasi_size_t iovs_len, uvwasi_size_t* nread) noexcept = 0;

virtual uvwasi_errno_t fd_prestat_get(uvwasi_fd_t fd, uvwasi_prestat_t* buf) noexcept = 0;

virtual uvwasi_errno_t environ_sizes_get(
uvwasi_size_t* environ_count, uvwasi_size_t* environ_buf_size) noexcept = 0;
};

std::unique_ptr<UVWASI> create_uvwasi();

} // namespace fizzy::wasi
30 changes: 10 additions & 20 deletions tools/wasi/wasi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "execute.hpp"
#include "limits.hpp"
#include "parser.hpp"
#include "uvwasi.hpp"
#include <uvwasi.h>
#include <cassert>
#include <filesystem>
Expand All @@ -14,21 +15,18 @@

namespace fizzy::wasi
{
UVWASI* uvwasi;

namespace
{
// Global state.
// NOTE: we do not care about uvwasi_destroy(), because it only clears file descriptors (currently)
// and we are a single-run tool. This may change in the future and should reevaluate.
uvwasi_t state;

ExecutionResult return_enosys(std::any&, Instance&, const Value*, ExecutionContext&) noexcept
{
return Value{uint32_t{UVWASI_ENOSYS}};
}

ExecutionResult proc_exit(std::any&, Instance&, const Value* args, ExecutionContext&) noexcept
{
uvwasi_proc_exit(&state, static_cast<uvwasi_exitcode_t>(args[0].as<uint32_t>()));
uvwasi->proc_exit(static_cast<uvwasi_exitcode_t>(args[0].as<uint32_t>()));
// Should not reach this.
return Trap;
}
Expand All @@ -49,7 +47,7 @@ ExecutionResult fd_write(
return Value{uint32_t{ret}};

uvwasi_size_t nwritten;
ret = uvwasi_fd_write(&state, static_cast<uvwasi_fd_t>(fd), iovs.data(), iov_cnt, &nwritten);
ret = uvwasi->fd_write(static_cast<uvwasi_fd_t>(fd), iovs.data(), iov_cnt, &nwritten);
uvwasi_serdes_write_uint32_t(instance.memory->data(), nwritten_ptr, nwritten);

return Value{uint32_t{ret}};
Expand All @@ -71,7 +69,7 @@ ExecutionResult fd_read(
return Value{uint32_t{ret}};

uvwasi_size_t nread;
ret = uvwasi_fd_read(&state, static_cast<uvwasi_fd_t>(fd), iovs.data(), iov_cnt, &nread);
ret = uvwasi->fd_read(static_cast<uvwasi_fd_t>(fd), iovs.data(), iov_cnt, &nread);
uvwasi_serdes_write_uint32_t(instance.memory->data(), nread_ptr, nread);

return Value{uint32_t{ret}};
Expand All @@ -84,7 +82,7 @@ ExecutionResult fd_prestat_get(
const auto prestat_ptr = args[1].as<uint32_t>();

uvwasi_prestat_t buf;
uvwasi_errno_t ret = uvwasi_fd_prestat_get(&state, fd, &buf);
uvwasi_errno_t ret = uvwasi->fd_prestat_get(fd, &buf);

uvwasi_serdes_write_prestat_t(instance.memory->data(), prestat_ptr, &buf);

Expand Down Expand Up @@ -159,18 +157,10 @@ std::unique_ptr<Instance> instantiate(bytes_view wasm_binary)

bool run(Instance& instance, int argc, const char* argv[], std::ostream& err)
{
// Initialisation settings.
// TODO: Make const after https://github.com/nodejs/uvwasi/pull/155 is merged.
uvwasi_options_t options = {
3, // sizeof fd_table
0, nullptr, // NOTE: no remappings
static_cast<uvwasi_size_t>(argc), argv,
nullptr, // TODO: support env
0, 1, 2,
nullptr, // NOTE: no special allocator
};
if (!uvwasi)
uvwasi = create_uvwasi().release();

const uvwasi_errno_t uvwasi_err = uvwasi_init(&state, &options);
const uvwasi_errno_t uvwasi_err = uvwasi->init(static_cast<uvwasi_size_t>(argc), argv);
if (uvwasi_err != UVWASI_ESUCCESS)
{
err << "Failed to initialise UVWASI: " << uvwasi_embedder_err_code_to_string(uvwasi_err)
Expand Down

0 comments on commit 585c9e8

Please sign in to comment.