Skip to content

Commit

Permalink
Pass arguments to host function as const Value*
Browse files Browse the repository at this point in the history
  • Loading branch information
chfast committed Oct 5, 2020
1 parent e64884e commit 51e41db
Show file tree
Hide file tree
Showing 9 changed files with 42 additions and 72 deletions.
9 changes: 4 additions & 5 deletions lib/fizzy/execute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ inline bool invoke_function(const FuncType& func_type, const F& func, Instance&
{
const auto num_args = func_type.inputs.size();
assert(stack.size() >= num_args);
span<const Value> call_args{stack.rend() - num_args, num_args};
const auto call_args = stack.rend() - num_args;

const auto ret = func(instance, call_args, depth + 1);
// Bubble up traps
Expand All @@ -454,8 +454,8 @@ inline bool invoke_function(const FuncType& func_type, const F& func, Instance&
inline bool invoke_function(const FuncType& func_type, uint32_t func_idx, Instance& instance,
OperandStack& stack, int depth) noexcept
{
const auto func = [func_idx](Instance& _instance, span<const Value> args, int _depth) noexcept {
return execute(_instance, func_idx, args.data(), _depth);
const auto func = [func_idx](Instance& _instance, const Value* args, int _depth) noexcept {
return execute(_instance, func_idx, args, _depth);
};
return invoke_function(func_type, func, instance, stack, depth);
}
Expand All @@ -471,8 +471,7 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args,

assert(instance.module.imported_function_types.size() == instance.imported_functions.size());
if (func_idx < instance.imported_functions.size())
return instance.imported_functions[func_idx].function(
instance, {args, func_type.inputs.size()}, depth);
return instance.imported_functions[func_idx].function(instance, args, depth);

const auto& code = instance.module.get_code(func_idx);
auto* const memory = instance.memory.get();
Expand Down
10 changes: 5 additions & 5 deletions lib/fizzy/instantiate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,8 +327,8 @@ std::unique_ptr<Instance> instantiate(Module module,
auto it_table = instance->table->begin() + elementsec_offsets[i];
for (const auto idx : instance->module.elementsec[i].init)
{
auto func = [idx, &instance_ref = *instance](fizzy::Instance&, span<const Value> args,
int depth) { return execute(instance_ref, idx, args.data(), depth); };
auto func = [idx, &instance_ref = *instance](fizzy::Instance&, const Value* args,
int depth) { return execute(instance_ref, idx, args, depth); };

*it_table++ =
ExternalFunction{std::move(func), instance->module.get_function_type(idx)};
Expand Down Expand Up @@ -360,7 +360,7 @@ std::unique_ptr<Instance> instantiate(Module module,
// Wrap the function with the lambda capturing shared instance
auto& table_function = (*it_table)->function;
table_function = [shared_instance, func = std::move(table_function)](
fizzy::Instance& _instance, span<const Value> args,
fizzy::Instance& _instance, const Value* args,
int depth) { return func(_instance, args, depth); };
++it_table;
}
Expand Down Expand Up @@ -432,8 +432,8 @@ std::optional<ExternalFunction> find_exported_function(Instance& instance, std::
return std::nullopt;

const auto idx = *opt_index;
auto func = [idx, &instance](fizzy::Instance&, span<const Value> args, int depth) {
return execute(instance, idx, args.data(), depth);
auto func = [idx, &instance](fizzy::Instance&, const Value* args, int depth) {
return execute(instance, idx, args, depth);
};

return ExternalFunction{std::move(func), instance.module.get_function_type(idx)};
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;

struct ExternalFunction
{
std::function<ExecutionResult(Instance&, span<const Value>, int depth)> function;
std::function<ExecutionResult(Instance&, const Value*, int depth)> function;
FuncType type;
};

Expand Down Expand Up @@ -102,7 +102,7 @@ struct ImportedFunction
std::string name;
std::vector<ValType> inputs;
std::optional<ValType> output;
std::function<ExecutionResult(Instance&, span<const Value>, int depth)> function;
std::function<ExecutionResult(Instance&, const Value*, int depth)> function;
};

// Create vector of ExternalFunctions ready to be passed to instantiate.
Expand Down
6 changes: 3 additions & 3 deletions test/unittests/api_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ namespace
{
auto function_returning_value(Value value) noexcept
{
return [value](Instance&, span<const Value>, int) { return value; };
return [value](Instance&, const Value*, int) { return value; };
}

ExecutionResult function_returning_void(Instance&, span<const Value>, int) noexcept
ExecutionResult function_returning_void(Instance&, const Value*, int) noexcept
{
return Void;
}
Expand Down Expand Up @@ -262,7 +262,7 @@ TEST(api, find_exported_function)
"0061736d010000000105016000017f021001087370656374657374036261720000040401700000050401010102"
"0606017f0041000b07170403666f6f000001670300037461620100036d656d0200");

auto bar = [](Instance&, span<const Value>, int) { return Value{42}; };
auto bar = [](Instance&, const Value*, int) { return Value{42}; };
const auto bar_type = FuncType{{}, {ValType::i32}};

auto instance_reexported_function =
Expand Down
26 changes: 12 additions & 14 deletions test/unittests/execute_call_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,11 @@ TEST(execute_call, call_indirect_imported_table)

const Module module = parse(bin);

auto f1 = [](Instance&, span<const Value>, int) { return Value{1}; };
auto f2 = [](Instance&, span<const Value>, int) { return Value{2}; };
auto f3 = [](Instance&, span<const Value>, int) { return Value{3}; };
auto f4 = [](Instance&, span<const Value>, int) { return Value{4}; };
auto f5 = [](Instance&, span<const Value>, int) { return Trap; };
auto f1 = [](Instance&, const Value*, int) { return Value{1}; };
auto f2 = [](Instance&, const Value*, int) { return Value{2}; };
auto f3 = [](Instance&, const Value*, int) { return Value{3}; };
auto f4 = [](Instance&, const Value*, int) { return Value{4}; };
auto f5 = [](Instance&, const Value*, int) { return Trap; };

auto out_i32 = FuncType{{}, {ValType::i32}};
auto out_i64 = FuncType{{}, {ValType::i64}};
Expand Down Expand Up @@ -218,7 +218,7 @@ TEST(execute_call, imported_function_call)

const auto module = parse(wasm);

constexpr auto host_foo = [](Instance&, span<const Value>, int) { return Value{42}; };
constexpr auto host_foo = [](Instance&, const Value*, int) { return Value{42}; };
const auto host_foo_type = module.typesec[0];

auto instance = instantiate(module, {{host_foo, host_foo_type}});
Expand All @@ -243,9 +243,7 @@ TEST(execute_call, imported_function_call_with_arguments)

const auto module = parse(wasm);

auto host_foo = [](Instance&, span<const Value> args, int) {
return Value{as_uint32(args[0]) * 2};
};
auto host_foo = [](Instance&, const Value* args, int) { return Value{as_uint32(args[0]) * 2}; };
const auto host_foo_type = module.typesec[0];

auto instance = instantiate(module, {{host_foo, host_foo_type}});
Expand Down Expand Up @@ -287,11 +285,11 @@ TEST(execute_call, imported_functions_call_indirect)
ASSERT_EQ(module.importsec.size(), 2);
ASSERT_EQ(module.codesec.size(), 2);

constexpr auto sqr = [](Instance&, span<const Value> args, int) {
constexpr auto sqr = [](Instance&, const Value* args, int) {
const auto x = as_uint32(args[0]);
return Value{uint64_t{x} * uint64_t{x}};
};
constexpr auto isqrt = [](Instance&, span<const Value> args, int) {
constexpr auto isqrt = [](Instance&, const Value* args, int) {
const auto x = as_uint32(args[0]);
return Value{(11 + uint64_t{x} / 11) / 2};
};
Expand Down Expand Up @@ -337,8 +335,8 @@ TEST(execute_call, imported_function_from_another_module)
const auto func_idx = fizzy::find_exported_function(module1, "sub");
ASSERT_TRUE(func_idx.has_value());

auto sub = [&instance1, func_idx](Instance&, span<const Value> args, int) -> ExecutionResult {
return fizzy::execute(*instance1, *func_idx, args.data());
auto sub = [&instance1, func_idx](Instance&, const Value* args, int) -> ExecutionResult {
return fizzy::execute(*instance1, *func_idx, args);
};

auto instance2 = instantiate(module2, {{sub, module1.typesec[0]}});
Expand Down Expand Up @@ -515,7 +513,7 @@ TEST(execute_call, call_imported_infinite_recursion)
"0061736d010000000105016000017f020b01036d6f6403666f6f0000030201000a0601040010000b");

const auto module = parse(wasm);
auto host_foo = [](Instance& instance, span<const Value>, int depth) -> ExecutionResult {
auto host_foo = [](Instance& instance, const Value*, int depth) -> ExecutionResult {
return execute(instance, 0, {}, depth + 1);
};
const auto host_foo_type = module.typesec[0];
Expand Down
2 changes: 1 addition & 1 deletion test/unittests/execute_control_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,7 @@ TEST(execute_control, br_1_out_of_function_and_imported_function)
"0061736d010000000108026000006000017f02150108696d706f727465640866756e6374696f6e000003020101"
"0a0d010b00034041010c010b41000b");

constexpr auto fake_imported_function = [](Instance&, span<const Value>,
constexpr auto fake_imported_function = [](Instance&, const Value*,
int) noexcept -> ExecutionResult { return Void; };

const auto module = parse(bin);
Expand Down
43 changes: 8 additions & 35 deletions test/unittests/execute_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,7 @@ TEST(execute, imported_function)
const auto module = parse(wasm);
ASSERT_EQ(module.typesec.size(), 1);

constexpr auto host_foo = [](Instance&, span<const Value> args, int) {
constexpr auto host_foo = [](Instance&, const Value* args, int) {
return Value{as_uint32(args[0]) + as_uint32(args[1])};
};

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

constexpr auto host_foo1 = [](Instance&, span<const Value> args, int) {
constexpr auto host_foo1 = [](Instance&, const Value* args, int) {
return Value{as_uint32(args[0]) + as_uint32(args[1])};
};
constexpr auto host_foo2 = [](Instance&, span<const Value> args, int) {
constexpr auto host_foo2 = [](Instance&, const Value* args, int) {
return Value{as_uint32(args[0]) * as_uint32(args[1])};
};

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

constexpr auto host_foo1 = [](Instance&, span<const Value> args, int) {
constexpr auto host_foo1 = [](Instance&, const Value* args, int) {
return Value{as_uint32(args[0]) + as_uint32(args[1])};
};
constexpr auto host_foo2 = [](Instance&, span<const Value> args, int) {
constexpr auto host_foo2 = [](Instance&, const Value* args, int) {
return Value{as_uint32(args[0]) * as_uint32(args[1])};
};

Expand All @@ -838,31 +838,6 @@ TEST(execute, imported_functions_and_regular_one)
EXPECT_THAT(execute(*instance, 1, {20, 10}), Result(200));
}

TEST(execute, imported_functions_count_args)
{
/* wat2wasm
(type (func (param i32 i32) (result i32)))
(type (func (param i32) (result i32)))
(import "mod" "foo1" (func (type 0)))
(import "mod" "foo2" (func (type 1)))
*/
const auto wasm = from_hex(
"0061736d01000000010c0260027f7f017f60017f017f021702036d6f6404666f6f310000036d6f6404666f6f32"
"0001");

// Check if correct number of arguments is passed to host functions.
constexpr auto count_args = [](Instance&, span<const Value> args, int) {
return Value{args.size()};
};

const auto module = parse(wasm);
ASSERT_EQ(module.typesec.size(), 2);
auto instance_counter =
instantiate(module, {{count_args, module.typesec[0]}, {count_args, module.typesec[1]}});
EXPECT_THAT(execute(*instance_counter, 0, {20, 22}), Result(2));
EXPECT_THAT(execute(*instance_counter, 1, {20}), Result(1));
}

TEST(execute, imported_two_functions_different_type)
{
/* wat2wasm
Expand All @@ -878,10 +853,10 @@ TEST(execute, imported_two_functions_different_type)
"0061736d01000000010c0260027f7f017f60017e017e021702036d6f6404666f6f310000036d6f6404666f6f32"
"0001030201010a0901070042aa80a8010b");

constexpr auto host_foo1 = [](Instance&, span<const Value> args, int) {
constexpr auto host_foo1 = [](Instance&, const Value* args, int) {
return Value{as_uint32(args[0]) + as_uint32(args[1])};
};
constexpr auto host_foo2 = [](Instance&, span<const Value> args, int) {
constexpr auto host_foo2 = [](Instance&, const Value* args, int) {
return Value{args[0].i64 * args[0].i64};
};

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

constexpr auto host_foo = [](Instance&, span<const Value>, int) -> ExecutionResult {
return Trap;
};
constexpr auto host_foo = [](Instance&, const Value*, int) -> ExecutionResult { return Trap; };

const auto module = parse(wasm);
auto instance = instantiate(module, {{host_foo, module.typesec[0]}});
Expand Down
12 changes: 6 additions & 6 deletions test/unittests/instantiate_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ TEST(instantiate, imported_functions)
const auto bin = from_hex("0061736d0100000001060160017f017f020b01036d6f6403666f6f0000");
const auto module = parse(bin);

auto host_foo = [](Instance&, span<const Value>, int) { return Trap; };
auto host_foo = [](Instance&, const Value*, int) { return Trap; };
auto instance = instantiate(module, {{host_foo, module.typesec[0]}});

ASSERT_EQ(instance->imported_functions.size(), 1);
Expand All @@ -52,8 +52,8 @@ TEST(instantiate, imported_functions_multiple)
"0061736d0100000001090260017f017f600000021702036d6f6404666f6f310000036d6f6404666f6f320001");
const auto module = parse(bin);

auto host_foo1 = [](Instance&, span<const Value>, int) { return Trap; };
auto host_foo2 = [](Instance&, span<const Value>, int) { return Trap; };
auto host_foo1 = [](Instance&, const Value*, int) { return Trap; };
auto host_foo2 = [](Instance&, const Value*, int) { return Trap; };
auto instance =
instantiate(module, {{host_foo1, module.typesec[0]}, {host_foo2, module.typesec[1]}});

Expand Down Expand Up @@ -88,7 +88,7 @@ TEST(instantiate, imported_function_wrong_type)
const auto bin = from_hex("0061736d0100000001060160017f017f020b01036d6f6403666f6f0000");
const auto module = parse(bin);

auto host_foo = [](Instance&, span<const Value>, int) { return Trap; };
auto host_foo = [](Instance&, const Value*, int) { return Trap; };
const auto host_foo_type = FuncType{{}, {}};

EXPECT_THROW_MESSAGE(instantiate(module, {{host_foo, host_foo_type}}), instantiate_error,
Expand Down Expand Up @@ -654,7 +654,7 @@ TEST(instantiate, element_section_fills_imported_table)
"0061736d010000000105016000017f020b01016d037461620170000403050400000000090f020041010b020001"
"0041020b0202030a1504040041010b040041020b040041030b040041040b");

auto f0 = [](Instance&, span<const Value>, int) { return Value{0}; };
auto f0 = [](Instance&, const Value*, int) { return Value{0}; };

table_elements table(4);
table[0] = ExternalFunction{f0, FuncType{{}, {ValType::i32}}};
Expand Down Expand Up @@ -682,7 +682,7 @@ TEST(instantiate, element_section_out_of_bounds_doesnt_change_imported_table)
"0b0200000a0601040041010b");
Module module = parse(bin);

auto f0 = [](Instance&, span<const Value>, int) { return Value{0}; };
auto f0 = [](Instance&, const Value*, int) { return Value{0}; };

table_elements table(3);
table[0] = ExternalFunction{f0, FuncType{{}, {ValType::i32}}};
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 @@ -53,7 +53,7 @@ FuncType translate_signature(std::string_view signature)
return func_type;
}

fizzy::ExecutionResult env_adler32(fizzy::Instance& instance, fizzy::span<const Value> args, int)
fizzy::ExecutionResult env_adler32(fizzy::Instance& instance, const fizzy::Value* args, int)
{
assert(instance.memory != nullptr);
const auto ret = fizzy::test::adler32(
Expand Down

0 comments on commit 51e41db

Please sign in to comment.