Skip to content

Commit

Permalink
Make execution noexcept
Browse files Browse the repository at this point in the history
  • Loading branch information
gumb0 committed Mar 1, 2021
1 parent 1996489 commit 61d30e2
Show file tree
Hide file tree
Showing 10 changed files with 69 additions and 53 deletions.
5 changes: 3 additions & 2 deletions lib/fizzy/capi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,10 @@ inline fizzy::ExecutionResult unwrap(const FizzyExecutionResult& result) noexcep
inline fizzy::ExecuteFunction unwrap(FizzyExternalFn c_function, void* c_host_context)
{
static constexpr fizzy::HostFunctionPtr function =
[](std::any& host_context, fizzy::Instance& instance, const fizzy::Value* args, int depth) {
[](std::any& host_context, fizzy::Instance& instance, const fizzy::Value* args,
int depth) noexcept {
const auto [c_func, c_host_ctx] =
std::any_cast<std::pair<FizzyExternalFn, void*>>(host_context);
*std::any_cast<std::pair<FizzyExternalFn, void*>>(&host_context);
return unwrap(c_func(c_host_ctx, wrap(&instance), wrap(args), depth));
};

Expand Down
4 changes: 2 additions & 2 deletions lib/fizzy/execute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ void branch(const Code& code, OperandStack& stack, const uint8_t*& pc, uint32_t
}

inline bool invoke_function(const FuncType& func_type, uint32_t func_idx, Instance& instance,
OperandStack& stack, int depth)
OperandStack& stack, int depth) noexcept
{
const auto num_args = func_type.inputs.size();
assert(stack.size() >= num_args);
Expand All @@ -549,7 +549,7 @@ inline bool invoke_function(const FuncType& func_type, uint32_t func_idx, Instan

} // namespace

ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args, int depth)
ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args, int depth) noexcept
{
assert(depth >= 0);
if (depth >= CallStackLimit)
Expand Down
3 changes: 2 additions & 1 deletion lib/fizzy/execute.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,6 @@ constexpr ExecutionResult Trap{false};
/// behaviour (including crash) happens.
/// @param depth The call depth (indexing starts at 0). Can be left at the default setting.
/// @return The result of the execution.
ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args, int depth = 0);
ExecutionResult execute(
Instance& instance, FuncIdx func_idx, const Value* args, int depth = 0) noexcept;
} // namespace fizzy
3 changes: 2 additions & 1 deletion lib/fizzy/instantiate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,8 @@ std::optional<FuncIdx> find_exported_function(const Module& module, std::string_
return find_export(module, ExternalKind::Function, name);
}

ExecutionResult ExecuteFunction::operator()(Instance& instance, const Value* args, int depth)
ExecutionResult ExecuteFunction::operator()(
Instance& instance, const Value* args, int depth) noexcept
{
if (m_instance)
return execute(*m_instance, m_func_idx, args, depth);
Expand Down
4 changes: 2 additions & 2 deletions lib/fizzy/instantiate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ struct Instance;

/// Function pointer to the execution function.
using HostFunctionPtr = ExecutionResult (*)(
std::any& host_context, Instance&, const Value* args, int depth);
std::any& host_context, Instance&, const Value* args, int depth) noexcept;

/// Function representing either WebAssembly or host function execution.
class ExecuteFunction
Expand Down Expand Up @@ -63,7 +63,7 @@ class ExecuteFunction
{}

/// Function call operator.
ExecutionResult operator()(Instance& instance, const Value* args, int depth);
ExecutionResult operator()(Instance& instance, const Value* args, int depth) noexcept;

/// Function pointer stored inside this object.
HostFunctionPtr get_host_function() const noexcept { return m_host_function; }
Expand Down
10 changes: 5 additions & 5 deletions test/unittests/api_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ namespace
ExecuteFunction function_returning_value(Value value)
{
static constexpr HostFunctionPtr func = [](std::any& host_context, Instance&, const Value*,
int) -> ExecutionResult {
return std::any_cast<Value>(host_context);
int) noexcept -> ExecutionResult {
return *std::any_cast<Value>(&host_context);
};

return {func, std::make_any<Value>(value)};
Expand Down Expand Up @@ -227,8 +227,8 @@ TEST(api, resolve_imported_function_duplicate_with_context)
"0061736d01000000010401600000021902046d6f643104666f6f310000046d6f643104666f6f310000");
const auto module = parse(wasm);

constexpr auto host_func = [](std::any& context, Instance&, const Value*, int) {
auto* counter = std::any_cast<int*>(context);
constexpr auto host_func = [](std::any& context, Instance&, const Value*, int) noexcept {
auto* counter = *std::any_cast<int*>(&context);
++(*counter);
return Void;
};
Expand Down Expand Up @@ -466,7 +466,7 @@ TEST(api, find_exported_function)
"0061736d010000000105016000017f021001087370656374657374036261720000040401700000050401010102"
"0606017f0041000b07170403666f6f000001670300037461620100036d656d0200");

constexpr auto bar = [](std::any&, Instance&, const Value*, int) -> ExecutionResult {
constexpr auto bar = [](std::any&, Instance&, const Value*, int) noexcept -> ExecutionResult {
return Value{42};
};
const auto bar_type = FuncType{{}, {ValType::i32}};
Expand Down
54 changes: 29 additions & 25 deletions test/unittests/execute_call_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -340,9 +340,8 @@ TEST(execute_call, imported_function_call)

const auto module = parse(wasm);

constexpr auto host_foo = [](std::any&, Instance&, const Value*, int) -> ExecutionResult {
return Value{42};
};
constexpr auto host_foo = [](std::any&, Instance&, const Value*,
int) noexcept -> ExecutionResult { return Value{42}; };
const auto& host_foo_type = module->typesec[0];

auto instance = instantiate(*module, {{{host_foo}, host_foo_type}});
Expand All @@ -364,7 +363,7 @@ TEST(execute_call, imported_function_call_void)
const auto module = parse(wasm);

static bool called = false;
constexpr auto host_foo = [](std::any&, Instance&, const Value*, int) {
constexpr auto host_foo = [](std::any&, Instance&, const Value*, int) noexcept {
called = true;
return Void;
};
Expand Down Expand Up @@ -392,7 +391,8 @@ TEST(execute_call, imported_function_call_with_arguments)

const auto module = parse(wasm);

constexpr auto host_foo = [](std::any&, Instance&, const Value* args, int) -> ExecutionResult {
constexpr auto host_foo = [](std::any&, Instance&, const Value* args,
int) noexcept -> ExecutionResult {
return Value{args[0].i32 * 2};
};
const auto host_foo_type = module->typesec[0];
Expand Down Expand Up @@ -436,11 +436,13 @@ TEST(execute_call, imported_functions_call_indirect)
ASSERT_EQ(module->importsec.size(), 2);
ASSERT_EQ(module->codesec.size(), 2);

constexpr auto sqr = [](std::any&, Instance&, const Value* args, int) -> ExecutionResult {
constexpr auto sqr = [](std::any&, Instance&, const Value* args,
int) noexcept -> ExecutionResult {
const auto x = args[0].i32;
return Value{uint64_t{x} * uint64_t{x}};
};
constexpr auto isqrt = [](std::any&, Instance&, const Value* args, int) -> ExecutionResult {
constexpr auto isqrt = [](std::any&, Instance&, const Value* args,
int) noexcept -> ExecutionResult {
const auto x = args[0].i32;
return Value{(11 + uint64_t{x} / 11) / 2};
};
Expand Down Expand Up @@ -563,8 +565,9 @@ TEST(execute_call, imported_function_from_another_module_via_host_function)
const auto func_idx = fizzy::find_exported_function(*module1, "sub");
ASSERT_TRUE(func_idx.has_value());

constexpr auto sub = [](std::any& host_context, Instance&, const Value* args, int depth) {
auto [inst1, idx] = std::any_cast<std::pair<Instance*, FuncIdx>>(host_context);
constexpr auto sub = [](std::any& host_context, Instance&, const Value* args,
int depth) noexcept {
auto [inst1, idx] = *std::any_cast<std::pair<Instance*, FuncIdx>>(&host_context);
return fizzy::execute(*inst1, idx, args, depth);
};

Expand All @@ -590,9 +593,8 @@ TEST(execute_call, imported_function_with_cotext)

const auto module = parse(wasm);

constexpr auto host_func = [](std::any& host_context, Instance&, const Value*,
int) -> ExecutionResult {
++(*std::any_cast<int*>(host_context));
constexpr auto host_func = [](std::any& host_context, Instance&, const Value*, int) noexcept {
++(**std::any_cast<int*>(&host_context));
return Void;
};
const auto& host_func_type = module->typesec[0];
Expand Down Expand Up @@ -624,14 +626,13 @@ TEST(execute_call, imported_functions_with_shared_cotext)

const auto module = parse(wasm);

constexpr auto host_func1 = [](std::any& host_context, Instance&, const Value*,
int) -> ExecutionResult {
++(*std::any_cast<uint32_t*>(host_context));
constexpr auto host_func1 = [](std::any& host_context, Instance&, const Value*, int) noexcept {
++(**std::any_cast<uint32_t*>(&host_context));
return Void;
};
constexpr auto host_func2 = [](std::any& host_context, Instance&, const Value*,
int) -> ExecutionResult {
return Value{*std::any_cast<uint32_t*>(host_context)};
int) noexcept -> ExecutionResult {
return Value{**std::any_cast<uint32_t*>(&host_context)};
};

uint32_t counter = 0;
Expand Down Expand Up @@ -774,7 +775,7 @@ TEST(execute_call, call_initial_depth)
const auto wasm = from_hex("0061736d01000000010401600000020b01036d6f6403666f6f0000");

auto module = parse(wasm);
constexpr auto host_foo = [](std::any&, Instance&, const Value*, int depth) {
constexpr auto host_foo = [](std::any&, Instance&, const Value*, int depth) noexcept {
EXPECT_EQ(depth, 0);
return Void;
};
Expand Down Expand Up @@ -811,7 +812,7 @@ TEST(execute_call, execute_imported_max_depth)
from_hex("0061736d01000000010401600000020b01036d6f6403666f6f0000030201000a040102000b");

auto module = parse(wasm);
constexpr auto host_foo = [](std::any&, Instance&, const Value*, int depth) {
constexpr auto host_foo = [](std::any&, Instance&, const Value*, int depth) noexcept {
EXPECT_LE(depth, TestCallStackLimit - 1);
return Void;
};
Expand Down Expand Up @@ -853,8 +854,9 @@ TEST(execute_call, imported_function_from_another_module_max_depth)
const auto func_idx = fizzy::find_exported_function(*instance1->module, "f");
ASSERT_TRUE(func_idx.has_value());

constexpr auto sub = [](std::any& host_context, Instance&, const Value* args, int depth) {
auto [inst1, idx] = std::any_cast<std::pair<Instance*, FuncIdx>>(host_context);
constexpr auto sub = [](std::any& host_context, Instance&, const Value* args,
int depth) noexcept {
auto [inst1, idx] = *std::any_cast<std::pair<Instance*, FuncIdx>>(&host_context);
return fizzy::execute(*inst1, idx, args, depth + 1);
};

Expand Down Expand Up @@ -933,7 +935,8 @@ TEST(execute_call, call_imported_infinite_recursion)

const auto module = parse(wasm);
static int counter = 0;
constexpr auto host_foo = [](std::any&, Instance& instance, const Value* args, int depth) {
constexpr auto host_foo = [](std::any&, Instance& instance, const Value* args,
int depth) noexcept {
++counter;
return execute(instance, 0, args, depth + 1);
};
Expand Down Expand Up @@ -963,7 +966,8 @@ TEST(execute_call, call_imported_interleaved_infinite_recursion)

const auto module = parse(wasm);
static int counter = 0;
constexpr auto host_foo = [](std::any&, Instance& instance, const Value* args, int depth) {
constexpr auto host_foo = [](std::any&, Instance& instance, const Value* args,
int depth) noexcept {
// Function $f will increase depth. This means each iteration goes 2 steps deeper.
EXPECT_LT(depth, CallStackLimit);
++counter;
Expand Down Expand Up @@ -993,7 +997,7 @@ TEST(execute_call, call_imported_max_depth_recursion)

const auto module = parse(wasm);
constexpr auto host_foo = [](std::any&, Instance& instance, const Value* args,
int depth) -> ExecutionResult {
int depth) noexcept -> ExecutionResult {
if (depth == TestCallStackLimit - 1)
return Value{uint32_t{1}}; // Terminate recursion on the max depth.
return execute(instance, 0, args, depth + 1);
Expand All @@ -1018,7 +1022,7 @@ TEST(execute_call, call_via_imported_max_depth_recursion)

const auto module = parse(wasm);
auto host_foo = [](std::any&, Instance& instance, const Value* args,
int depth) -> ExecutionResult {
int depth) noexcept -> ExecutionResult {
// Function $f will increase depth. This means each iteration goes 2 steps deeper.
if (depth == TestCallStackLimit - 1)
return Value{uint32_t{1}}; // Terminate recursion on the max depth.
Expand Down
23 changes: 15 additions & 8 deletions test/unittests/execute_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,8 @@ TEST(execute, imported_function)
const auto module = parse(wasm);
ASSERT_EQ(module->typesec.size(), 1);

constexpr auto host_foo = [](std::any&, Instance&, const Value* args, int) -> ExecutionResult {
constexpr auto host_foo = [](std::any&, Instance&, const Value* args,
int) noexcept -> ExecutionResult {
return Value{args[0].i32 + args[1].i32};
};

Expand All @@ -830,10 +831,12 @@ TEST(execute, imported_two_functions)
const auto module = parse(wasm);
ASSERT_EQ(module->typesec.size(), 1);

constexpr auto host_foo1 = [](std::any&, Instance&, const Value* args, int) -> ExecutionResult {
constexpr auto host_foo1 = [](std::any&, Instance&, const Value* args,
int) noexcept -> ExecutionResult {
return Value{args[0].i32 + args[1].i32};
};
constexpr auto host_foo2 = [](std::any&, Instance&, const Value* args, int) -> ExecutionResult {
constexpr auto host_foo2 = [](std::any&, Instance&, const Value* args,
int) noexcept -> ExecutionResult {
return Value{args[0].i32 * args[1].i32};
};

Expand All @@ -857,10 +860,12 @@ TEST(execute, imported_functions_and_regular_one)
"0061736d0100000001070160027f7f017f021702036d6f6404666f6f310000036d6f6404666f6f320000030201"
"000a0901070041aa80a8010b");

constexpr auto host_foo1 = [](std::any&, Instance&, const Value* args, int) -> ExecutionResult {
constexpr auto host_foo1 = [](std::any&, Instance&, const Value* args,
int) noexcept -> ExecutionResult {
return Value{args[0].i32 + args[1].i32};
};
constexpr auto host_foo2 = [](std::any&, Instance&, const Value* args, int) -> ExecutionResult {
constexpr auto host_foo2 = [](std::any&, Instance&, const Value* args,
int) noexcept -> ExecutionResult {
return Value{args[0].i32 * args[1].i32};
};

Expand All @@ -887,10 +892,12 @@ TEST(execute, imported_two_functions_different_type)
"0061736d01000000010c0260027f7f017f60017e017e021702036d6f6404666f6f310000036d6f6404666f6f32"
"0001030201010a0901070042aa80a8010b");

constexpr auto host_foo1 = [](std::any&, Instance&, const Value* args, int) -> ExecutionResult {
constexpr auto host_foo1 = [](std::any&, Instance&, const Value* args,
int) noexcept -> ExecutionResult {
return Value{args[0].i32 + args[1].i32};
};
constexpr auto host_foo2 = [](std::any&, Instance&, const Value* args, int) -> ExecutionResult {
constexpr auto host_foo2 = [](std::any&, Instance&, const Value* args,
int) noexcept -> ExecutionResult {
return Value{args[0].i64 * args[0].i64};
};

Expand All @@ -911,7 +918,7 @@ TEST(execute, imported_function_traps)
*/
const auto wasm = from_hex("0061736d0100000001070160027f7f017f020b01036d6f6403666f6f0000");

constexpr auto host_foo = [](std::any&, Instance&, const Value*, int) { return Trap; };
constexpr auto host_foo = [](std::any&, Instance&, const Value*, int) noexcept { return Trap; };

const auto module = parse(wasm);
auto instance = instantiate(*module, {{{host_foo}, module->typesec[0]}});
Expand Down
2 changes: 1 addition & 1 deletion test/utils/fizzy_engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class FizzyEngine final : public WasmEngine
namespace
{
fizzy::ExecutionResult env_adler32(
std::any&, fizzy::Instance& instance, const fizzy::Value* args, int)
std::any&, fizzy::Instance& instance, const fizzy::Value* args, int) noexcept
{
assert(instance.memory != nullptr);
const auto ret = fizzy::test::adler32(
Expand Down
14 changes: 8 additions & 6 deletions tools/wasi/wasi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,22 @@ namespace
// and we are a single-run tool. This may change in the future and should reevaluate.
uvwasi_t state;

fizzy::ExecutionResult wasi_return_enosys(std::any&, fizzy::Instance&, const fizzy::Value*, int)
fizzy::ExecutionResult wasi_return_enosys(
std::any&, fizzy::Instance&, const fizzy::Value*, int) noexcept
{
return fizzy::Value{uint32_t{UVWASI_ENOSYS}};
}

fizzy::ExecutionResult wasi_proc_exit(std::any&, fizzy::Instance&, const fizzy::Value* args, int)
fizzy::ExecutionResult wasi_proc_exit(
std::any&, fizzy::Instance&, const fizzy::Value* args, int) noexcept
{
uvwasi_proc_exit(&state, static_cast<uvwasi_exitcode_t>(args[0].as<uint32_t>()));
// Should not reach this.
return fizzy::Trap;
}

fizzy::ExecutionResult wasi_fd_write(
std::any&, fizzy::Instance& instance, const fizzy::Value* args, int)
std::any&, fizzy::Instance& instance, const fizzy::Value* args, int) noexcept
{
const auto fd = args[0].as<uint32_t>();
const auto iov_ptr = args[1].as<uint32_t>();
Expand All @@ -53,7 +55,7 @@ fizzy::ExecutionResult wasi_fd_write(
}

fizzy::ExecutionResult wasi_fd_read(
std::any&, fizzy::Instance& instance, const fizzy::Value* args, int)
std::any&, fizzy::Instance& instance, const fizzy::Value* args, int) noexcept
{
const auto fd = args[0].as<uint32_t>();
const auto iov_ptr = args[1].as<uint32_t>();
Expand All @@ -75,7 +77,7 @@ fizzy::ExecutionResult wasi_fd_read(
}

fizzy::ExecutionResult wasi_fd_prestat_get(
std::any&, fizzy::Instance& instance, const fizzy::Value* args, int)
std::any&, fizzy::Instance& instance, const fizzy::Value* args, int) noexcept
{
const auto fd = args[0].as<uint32_t>();
const auto prestat_ptr = args[1].as<uint32_t>();
Expand All @@ -89,7 +91,7 @@ fizzy::ExecutionResult wasi_fd_prestat_get(
}

fizzy::ExecutionResult wasi_environ_sizes_get(
std::any&, fizzy::Instance& instance, const fizzy::Value* args, int)
std::any&, fizzy::Instance& instance, const fizzy::Value* args, int) noexcept
{
const auto environc = args[0].as<uint32_t>();
const auto environ_buf_size = args[1].as<uint32_t>();
Expand Down

0 comments on commit 61d30e2

Please sign in to comment.