Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
gumb0 committed Apr 21, 2021
1 parent 47cf11a commit fa35d0c
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 48 deletions.
52 changes: 16 additions & 36 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 "wasi_uvwasi.hpp"
#include <cassert>
#include <filesystem>
#include <fstream>
Expand All @@ -19,7 +20,7 @@ WASI* wasi_impl = nullptr;

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

ExecutionResult proc_exit(std::any&, Instance&, const Value* args, int) noexcept
Expand All @@ -36,18 +37,7 @@ ExecutionResult fd_write(std::any&, Instance& instance, const Value* args, int)
const auto iov_cnt = args[2].as<uint32_t>();
const auto nwritten_ptr = args[3].as<uint32_t>();


std::vector<uvwasi_ciovec_t> iovs(iov_cnt);
// TODO: not sure what to pass as end, passing memory size...
uvwasi_errno_t ret = uvwasi_serdes_readv_ciovec_t(
instance.memory->data(), instance.memory->size(), iov_ptr, iovs.data(), iov_cnt);
if (ret != UVWASI_ESUCCESS)
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);
uvwasi_serdes_write_uint32_t(instance.memory->data(), nwritten_ptr, nwritten);

const auto ret = wasi_impl->fd_write(*instance.memory, fd, iov_ptr, iov_cnt, nwritten_ptr);
return Value{uint32_t{ret}};
}

Expand All @@ -58,17 +48,7 @@ ExecutionResult fd_read(std::any&, Instance& instance, const Value* args, int) n
const auto iov_cnt = args[2].as<uint32_t>();
const auto nread_ptr = args[3].as<uint32_t>();

std::vector<uvwasi_iovec_t> iovs(iov_cnt);
// TODO: not sure what to pass as end, passing memory size...
uvwasi_errno_t ret = uvwasi_serdes_readv_iovec_t(
instance.memory->data(), instance.memory->size(), iov_ptr, iovs.data(), iov_cnt);
if (ret != UVWASI_ESUCCESS)
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);
uvwasi_serdes_write_uint32_t(instance.memory->data(), nread_ptr, nread);

const auto ret = wasi_impl->fd_read(*instance.memory, fd, iov_ptr, iov_cnt, nread_ptr);
return Value{uint32_t{ret}};
}

Expand All @@ -77,25 +57,22 @@ ExecutionResult fd_prestat_get(std::any&, Instance& instance, const Value* args,
const auto fd = args[0].as<uint32_t>();
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_serdes_write_prestat_t(instance.memory->data(), prestat_ptr, &buf);

const auto ret = wasi_impl->fd_prestat_get(*instance.memory, fd, prestat_ptr);
return Value{uint32_t{ret}};
}

ExecutionResult environ_sizes_get(std::any&, Instance& instance, const Value* args, int) noexcept
{
const auto environc = args[0].as<uint32_t>();
const auto environ_buf_size = args[1].as<uint32_t>();
// TODO: implement properly (only returns 0 now)
uvwasi_serdes_write_uint32_t(instance.memory->data(), environc, 0);
uvwasi_serdes_write_uint32_t(instance.memory->data(), environ_buf_size, 0);
return Value{uint32_t{UVWASI_ESUCCESS}};

const auto ret = wasi_impl->environ_sizes_get(*instance.memory, environc, environ_buf_size);
return Value{uint32_t{ret}};
}
} // namespace

WASI::~WASI() {}

std::optional<bytes> load_file(std::string_view file, std::ostream& err) noexcept
{
try
Expand Down Expand Up @@ -146,10 +123,13 @@ bool run(bytes_view wasm_binary, int argc, const char* argv[], std::ostream& err
};


const uvwasi_errno_t uvwasi_err = uvwasi_init(&state, &options);
if (uvwasi_err != UVWASI_ESUCCESS)
wasi_impl = create_uvwasi().release();

const auto uvwasi_err = wasi_impl->init(argc, argv);
if (uvwasi_err != 0)
{
err << "Failed to initialise UVWASI: " << uvwasi_embedder_err_code_to_string(uvwasi_err)
err << "Failed to initialise UVWASI: "
<< /* TODO uvwasi_embedder_err_code_to_string(uvwasi_err) */ ""
<< "\n";
return false;
}
Expand Down
17 changes: 15 additions & 2 deletions tools/wasi/wasi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// Copyright 2021 The Fizzy Authors.
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include <bytes.hpp>
#include <iosfwd>
#include <optional>
Expand All @@ -16,14 +18,25 @@ using error_code = uint16_t;
class WASI
{
public:
virtual ~WASI() noexcept = 0;
virtual ~WASI();

virtual error_code init(int argc, const char* argv[]) noexcept = 0;

virtual error_code return_enosys() noexcept = 0;

virtual error_code proc_exit(uint32_t exit_code) noexcept = 0;

virtual error_code fd_write(uint8_t* memory, uint32_t fd, uint32_t iov_ptr, uint32_t iov_cnt,
virtual error_code fd_write(bytes& memory, uint32_t fd, uint32_t iov_ptr, uint32_t iov_cnt,
uint32_t nwritten_ptr) noexcept = 0;

virtual error_code fd_read(bytes& memory, uint32_t fd, uint32_t iov_ptr, uint32_t iov_cnt,
uint32_t nread_ptr) noexcept = 0;

virtual error_code fd_prestat_get(
bytes& memory, uint32_t fd, uint32_t prestat_ptr) noexcept = 0;

virtual error_code environ_sizes_get(
bytes& memory, uint32_t environc, uint32_t environ_buf_size) noexcept = 0;
};

/// Loads a binary file at the given path.
Expand Down
58 changes: 48 additions & 10 deletions tools/wasi/wasi_uvwasi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,27 +38,65 @@ class UVWASI final : public WASI
return uvwasi_init(&m_state, &options);
}

error_code fd_write(uint8_t* memory, uint32_t fd, uint32_t iov_ptr, uint32_t iov_cnt,
uint32_t nwritten_ptr) noexcept
error_code proc_exit(uint32_t exit_code) noexcept final
{
return uvwasi_proc_exit(&m_state, exit_code);
}

error_code return_enosys() noexcept final { return UVWASI_ENOSYS; }

error_code fd_write(bytes& memory, uint32_t fd, uint32_t iov_ptr, uint32_t iov_cnt,
uint32_t nwritten_ptr) noexcept final
{
std::vector<uvwasi_ciovec_t> iovs(iov_cnt);
// TODO: not sure what to pass as end, passing memory size...
uvwasi_errno_t ret = uvwasi_serdes_readv_ciovec_t(
instance.memory->data(), instance.memory->size(), iov_ptr, iovs.data(), iov_cnt);
memory.data(), memory.size(), iov_ptr, iovs.data(), iov_cnt);
if (ret != UVWASI_ESUCCESS)
return Value{uint32_t{ret}};
return ret;

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

return Value{uint32_t{ret}};
return ret;
}

error_code proc_exit(uint32_t exit_code) noexcept final
error_code fd_read(bytes& memory, uint32_t fd, uint32_t iov_ptr, uint32_t iov_cnt,
uint32_t nread_ptr) noexcept final
{
return uvwasi_proc_exit(&m_state, exit_code);
std::vector<uvwasi_iovec_t> iovs(iov_cnt);
// TODO: not sure what to pass as end, passing memory size...
uvwasi_errno_t ret = uvwasi_serdes_readv_iovec_t(
memory.data(), memory.size(), iov_ptr, iovs.data(), iov_cnt);
if (ret != UVWASI_ESUCCESS)
return ret;

uvwasi_size_t nread;
ret = uvwasi_fd_read(&m_state, static_cast<uvwasi_fd_t>(fd), iovs.data(), iov_cnt, &nread);
uvwasi_serdes_write_uint32_t(memory.data(), nread_ptr, nread);

return ret;
}

error_code fd_prestat_get(bytes& memory, uint32_t fd, uint32_t prestat_ptr) noexcept final
{
uvwasi_prestat_t buf;
uvwasi_errno_t ret = uvwasi_fd_prestat_get(&m_state, fd, &buf);

uvwasi_serdes_write_prestat_t(memory.data(), prestat_ptr, &buf);

return ret;
}

error_code environ_sizes_get(
bytes& memory, uint32_t environc, uint32_t environ_buf_size) noexcept final
{
// TODO: implement properly (only returns 0 now)
uvwasi_serdes_write_uint32_t(memory.data(), environc, 0);
uvwasi_serdes_write_uint32_t(memory.data(), environ_buf_size, 0);
return UVWASI_ESUCCESS;
}
};
} // namespace
Expand Down
2 changes: 2 additions & 0 deletions tools/wasi/wasi_uvwasi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// Copyright 2021 The Fizzy Authors.
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include "wasi.hpp"
#include <memory>

Expand Down

0 comments on commit fa35d0c

Please sign in to comment.