Skip to content

Commit

Permalink
Merge pull request #552 from wasmx/args_span_size
Browse files Browse the repository at this point in the history
Pass arguments as const Value*
  • Loading branch information
chfast authored Oct 2, 2020
2 parents a9b0e0f + 4816192 commit a74e152
Show file tree
Hide file tree
Showing 13 changed files with 49 additions and 46 deletions.
13 changes: 7 additions & 6 deletions lib/fizzy/execute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -454,29 +454,30 @@ inline bool invoke_function(const FuncType& func_type, uint32_t func_idx, Instan
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, _depth);
return execute(_instance, func_idx, args.data(), _depth);
};
return invoke_function(func_type, func, instance, stack, depth);
}
} // namespace

ExecutionResult execute(
Instance& instance, FuncIdx func_idx, span<const Value> args, int depth) noexcept
ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args, int depth) noexcept
{
assert(depth >= 0);
if (depth > CallStackLimit)
return Trap;

assert(args.size() == instance.module.get_function_type(func_idx).inputs.size());
const auto& func_type = instance.module.get_function_type(func_idx);

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, depth);
return instance.imported_functions[func_idx].function(
instance, {args, func_type.inputs.size()}, depth);

const auto& code = instance.module.get_code(func_idx);
auto* const memory = instance.memory.get();

OperandStack stack(args, code.local_count, static_cast<size_t>(code.max_stack_height));
OperandStack stack(args, func_type.inputs.size(), code.local_count,
static_cast<size_t>(code.max_stack_height));

const Instr* pc = code.instructions.data();
const uint8_t* immediates = code.immediates.data();
Expand Down
5 changes: 3 additions & 2 deletions lib/fizzy/execute.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,12 @@ constexpr ExecutionResult Trap{false};

// Execute a function on an instance.
ExecutionResult execute(
Instance& instance, FuncIdx func_idx, span<const Value> args, int depth = 0) noexcept;
Instance& instance, FuncIdx func_idx, const Value* args, int depth = 0) noexcept;

inline ExecutionResult execute(
Instance& instance, FuncIdx func_idx, std::initializer_list<Value> args) noexcept
{
return execute(instance, func_idx, span<const Value>{args});
assert(args.size() == instance.module.get_function_type(func_idx).inputs.size());
return execute(instance, func_idx, args.begin());
}
} // namespace fizzy
4 changes: 2 additions & 2 deletions lib/fizzy/instantiate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ std::unique_ptr<Instance> instantiate(Module module,
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, depth); };
int depth) { return execute(instance_ref, idx, args.data(), depth); };

*it_table++ =
ExternalFunction{std::move(func), instance->module.get_function_type(idx)};
Expand Down Expand Up @@ -433,7 +433,7 @@ std::optional<ExternalFunction> find_exported_function(Instance& instance, std::

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

return ExternalFunction{std::move(func), instance.module.get_function_type(idx)};
Expand Down
10 changes: 5 additions & 5 deletions lib/fizzy/stack.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

#pragma once

#include "cxx20/span.hpp"
#include "value.hpp"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <memory>
Expand Down Expand Up @@ -96,9 +96,9 @@ class OperandStack
/// after the arguments.
/// @param max_stack_height The maximum operand stack height in the function. This excludes
/// args and num_local_variables.
OperandStack(span<const Value> args, size_t num_local_variables, size_t max_stack_height)
OperandStack(
const Value* args, size_t num_args, size_t num_local_variables, size_t max_stack_height)
{
const auto num_args = args.size();
const auto storage_size_required = num_args + num_local_variables + max_stack_height;

if (storage_size_required <= small_storage_size)
Expand All @@ -114,8 +114,8 @@ class OperandStack
m_bottom = m_locals + num_args + num_local_variables;
m_top = m_bottom - 1;

std::copy(std::begin(args), std::end(args), m_locals);
std::fill_n(m_locals + num_args, num_local_variables, 0);
const auto local_variables = std::copy_n(args, num_args, m_locals);
std::fill_n(local_variables, num_local_variables, 0);
}

OperandStack(const OperandStack&) = delete;
Expand Down
3 changes: 2 additions & 1 deletion test/spectests/spectests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,8 @@ class test_runner
args.push_back(*arg_value);
}

return fizzy::execute(*instance, *func_idx, args);
assert(args.size() == instance->module.get_function_type(*func_idx).inputs.size());
return fizzy::execute(*instance, *func_idx, args.data());
}

bool check_integer_result(fizzy::Value actual_value, const json& expected)
Expand Down
3 changes: 1 addition & 2 deletions test/testfloat/testfloat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -336,8 +336,7 @@ bool check(const FunctionDescription& func, fizzy::Instance& instance, const uin
for (size_t i = 0; i < func.num_arguments; ++i)
args[i] = make_value(func.param_types[i], inputs[i]);

const auto r = fizzy::execute(
instance, func.idx, fizzy::span<const fizzy::Value>(args, func.num_arguments));
const auto r = fizzy::execute(instance, func.idx, args);

if (func.options == Options::TrapIsInvalidOperation)
{
Expand Down
12 changes: 6 additions & 6 deletions test/unittests/api_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ TEST(api, resolve_imported_functions)
module, external_functions, {}, {}, std::vector<ExternalGlobal>(external_globals));

EXPECT_THAT(execute(*instance, 0, {}), Result(0));
EXPECT_THAT(execute(*instance, 1, {0}), Result(1));
EXPECT_THAT(execute(*instance, 2, {0}), Result(2));
EXPECT_THAT(execute(*instance, 1, {Value{0}}), Result(1));
EXPECT_THAT(execute(*instance, 2, {Value{0}}), Result(2));
EXPECT_THAT(execute(*instance, 3, {0, 0}), Result());


Expand All @@ -119,8 +119,8 @@ TEST(api, resolve_imported_functions)
std::vector<ExternalGlobal>(external_globals));

EXPECT_THAT(execute(*instance_reordered, 0, {}), Result(0));
EXPECT_THAT(execute(*instance_reordered, 1, {0}), Result(1));
EXPECT_THAT(execute(*instance_reordered, 2, {0}), Result(2));
EXPECT_THAT(execute(*instance_reordered, 1, {Value{0}}), Result(1));
EXPECT_THAT(execute(*instance_reordered, 2, {Value{0}}), Result(2));
EXPECT_THAT(execute(*instance_reordered, 3, {0, 0}), Result());


Expand All @@ -141,8 +141,8 @@ TEST(api, resolve_imported_functions)
module, external_functions_extra, {}, {}, std::vector<ExternalGlobal>(external_globals));

EXPECT_THAT(execute(*instance_extra, 0, {}), Result(0));
EXPECT_THAT(execute(*instance_extra, 1, {0}), Result(1));
EXPECT_THAT(execute(*instance_extra, 2, {0}), Result(2));
EXPECT_THAT(execute(*instance_extra, 1, {Value{0}}), Result(1));
EXPECT_THAT(execute(*instance_extra, 2, {Value{0}}), Result(2));
EXPECT_THAT(execute(*instance_extra, 3, {0, 0}), Result());


Expand Down
2 changes: 1 addition & 1 deletion test/unittests/execute_call_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ TEST(execute_call, imported_function_from_another_module)
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);
return fizzy::execute(*instance1, *func_idx, args.data());
};

auto instance2 = instantiate(module2, {{sub, module1.typesec[0]}});
Expand Down
8 changes: 4 additions & 4 deletions test/unittests/execute_floating_point_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1893,7 +1893,7 @@ TEST(execute_floating_point, f32_load_overflow)
auto instance = instantiate(parse(wasm));

// Offset is 0x7fffffff + 0 => 0x7fffffff
EXPECT_THAT(execute(*instance, 0, {0}), Traps());
EXPECT_THAT(execute(*instance, 0, {Value{0}}), Traps());
// Offset is 0x7fffffff + 0x80000000 => 0xffffffff
EXPECT_THAT(execute(*instance, 0, {0x80000000}), Traps());
// Offset is 0x7fffffff + 0x80000001 => 0x100000000
Expand Down Expand Up @@ -1966,7 +1966,7 @@ TEST(execute_floating_point, f64_load_overflow)
auto instance = instantiate(parse(wasm));

// Offset is 0x7fffffff + 0 => 0x7fffffff
EXPECT_THAT(execute(*instance, 0, {0}), Traps());
EXPECT_THAT(execute(*instance, 0, {Value{0}}), Traps());
// Offset is 0x7fffffff + 0x80000000 => 0xffffffff
EXPECT_THAT(execute(*instance, 0, {0x80000000}), Traps());
// Offset is 0x7fffffff + 0x80000001 => 0x100000000
Expand Down Expand Up @@ -2043,7 +2043,7 @@ TEST(execute_floating_point, f32_store_overflow)
auto instance = instantiate(parse(wasm));

// Offset is 0x7fffffff + 0 => 0x7fffffff
EXPECT_THAT(execute(*instance, 0, {0}), Traps());
EXPECT_THAT(execute(*instance, 0, {Value{0}}), Traps());
// Offset is 0x7fffffff + 0x80000000 => 0xffffffff
EXPECT_THAT(execute(*instance, 0, {0x80000000}), Traps());
// Offset is 0x7fffffff + 0x80000001 => 0x100000000
Expand Down Expand Up @@ -2120,7 +2120,7 @@ TEST(execute_floating_point, f64_store_overflow)
auto instance = instantiate(parse(wasm));

// Offset is 0x7fffffff + 0 => 0x7fffffff
EXPECT_THAT(execute(*instance, 0, {0}), Traps());
EXPECT_THAT(execute(*instance, 0, {Value{0}}), Traps());
// Offset is 0x7fffffff + 0x80000000 => 0xffffffff
EXPECT_THAT(execute(*instance, 0, {0x80000000}), Traps());
// Offset is 0x7fffffff + 0x80000001 => 0x100000000
Expand Down
10 changes: 5 additions & 5 deletions test/unittests/execute_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ TEST(execute, i32_load_overflow)
auto instance = instantiate(parse(wasm));

// Offset is 0x7fffffff + 0 => 0x7fffffff
EXPECT_THAT(execute(*instance, 0, {0}), Traps());
EXPECT_THAT(execute(*instance, 0, {Value{0}}), Traps());
// Offset is 0x7fffffff + 0x80000000 => 0xffffffff
EXPECT_THAT(execute(*instance, 0, {0x80000000}), Traps());
// Offset is 0x7fffffff + 0x80000001 => 0x100000000
Expand All @@ -362,7 +362,7 @@ TEST(execute, i64_load_overflow)
auto instance = instantiate(parse(wasm));

// Offset is 0x7fffffff + 0 => 0x7fffffff
EXPECT_THAT(execute(*instance, 0, {0}), Traps());
EXPECT_THAT(execute(*instance, 0, {Value{0}}), Traps());
// Offset is 0x7fffffff + 0x80000000 => 0xffffffff
EXPECT_THAT(execute(*instance, 0, {0x80000000}), Traps());
// Offset is 0x7fffffff + 0x80000001 => 0x100000000
Expand Down Expand Up @@ -486,7 +486,7 @@ TEST(execute, i32_store_overflow)
auto instance = instantiate(parse(wasm));

// Offset is 0x7fffffff + 0 => 0x7fffffff
EXPECT_THAT(execute(*instance, 0, {0}), Traps());
EXPECT_THAT(execute(*instance, 0, {Value{0}}), Traps());
// Offset is 0x7fffffff + 0x80000000 => 0xffffffff
EXPECT_THAT(execute(*instance, 0, {0x80000000}), Traps());
// Offset is 0x7fffffff + 0x80000001 => 0x100000000
Expand All @@ -510,7 +510,7 @@ TEST(execute, i64_store_overflow)
auto instance = instantiate(parse(wasm));

// Offset is 0x7fffffff + 0 => 0x7fffffff
EXPECT_THAT(execute(*instance, 0, {0}), Traps());
EXPECT_THAT(execute(*instance, 0, {Value{0}}), Traps());
// Offset is 0x7fffffff + 0x80000000 => 0xffffffff
EXPECT_THAT(execute(*instance, 0, {0x80000000}), Traps());
// Offset is 0x7fffffff + 0x80000001 => 0x100000000
Expand Down Expand Up @@ -980,7 +980,7 @@ TEST(execute, reuse_args)

const std::vector<Value> args{20, 3};
const auto expected = args[0].i64 % (args[0].i64 / args[1].i64);
EXPECT_THAT(execute(*instance, 0, args), Result(expected));
EXPECT_THAT(execute(*instance, 0, args.data()), Result(expected));
EXPECT_THAT(args[0].i64, 20);
EXPECT_THAT(args[1].i64, 3);

Expand Down
2 changes: 1 addition & 1 deletion test/unittests/span_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ TEST(span, array)

TEST(span, stack)
{
OperandStack stack({}, 0, 4);
OperandStack stack(nullptr, 0, 0, 4);
stack.push(10);
stack.push(11);
stack.push(12);
Expand Down
18 changes: 9 additions & 9 deletions test/unittests/stack_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,13 @@ TEST(stack, struct_item)

TEST(operand_stack, construct)
{
OperandStack stack({}, 0, 0);
OperandStack stack(nullptr, 0, 0, 0);
EXPECT_EQ(stack.size(), 0);
}

TEST(operand_stack, top)
{
OperandStack stack({}, 0, 1);
OperandStack stack(nullptr, 0, 0, 1);
EXPECT_EQ(stack.size(), 0);

stack.push(1);
Expand Down Expand Up @@ -158,7 +158,7 @@ TEST(operand_stack, top)

TEST(operand_stack, small)
{
OperandStack stack({}, 0, 3);
OperandStack stack(nullptr, 0, 0, 3);
ASSERT_LT(address_diff(&stack, stack.rbegin()), 100) << "not allocated on the system stack";

EXPECT_EQ(stack.size(), 0);
Expand Down Expand Up @@ -189,7 +189,7 @@ TEST(operand_stack, small)
TEST(operand_stack, small_with_locals)
{
const fizzy::Value args[] = {0xa1, 0xa2};
OperandStack stack(args, 3, 1);
OperandStack stack(args, std::size(args), 3, 1);
ASSERT_LT(address_diff(&stack, stack.rbegin()), 100) << "not allocated on the system stack";

EXPECT_EQ(stack.size(), 0);
Expand Down Expand Up @@ -229,7 +229,7 @@ TEST(operand_stack, small_with_locals)
TEST(operand_stack, large)
{
constexpr auto max_height = 33;
OperandStack stack({}, 0, max_height);
OperandStack stack(nullptr, 0, 0, max_height);
ASSERT_GT(address_diff(&stack, stack.rbegin()), 100) << "not allocated on the heap";

for (unsigned i = 0; i < max_height; ++i)
Expand All @@ -247,7 +247,7 @@ TEST(operand_stack, large_with_locals)
constexpr auto max_height = 33;
constexpr auto num_locals = 5;
constexpr auto num_args = std::size(args);
OperandStack stack(args, num_locals, max_height);
OperandStack stack(args, num_args, num_locals, max_height);
ASSERT_GT(address_diff(&stack, stack.rbegin()), 100) << "not allocated on the heap";

for (unsigned i = 0; i < max_height; ++i)
Expand Down Expand Up @@ -279,7 +279,7 @@ TEST(operand_stack, large_with_locals)

TEST(operand_stack, rbegin_rend)
{
OperandStack stack({}, 0, 3);
OperandStack stack(nullptr, 0, 0, 3);
EXPECT_EQ(stack.rbegin(), stack.rend());

stack.push(1);
Expand All @@ -293,7 +293,7 @@ TEST(operand_stack, rbegin_rend)
TEST(operand_stack, rbegin_rend_locals)
{
const fizzy::Value args[] = {0xa1};
OperandStack stack(args, 4, 2);
OperandStack stack(args, std::size(args), 4, 2);
EXPECT_EQ(stack.rbegin(), stack.rend());

stack.push(1);
Expand All @@ -313,7 +313,7 @@ TEST(operand_stack, rbegin_rend_locals)

TEST(operand_stack, to_vector)
{
OperandStack stack({}, 0, 3);
OperandStack stack(nullptr, 0, 0, 3);
EXPECT_THAT(std::vector(stack.rbegin(), stack.rend()), IsEmpty());

stack.push(1);
Expand Down
5 changes: 3 additions & 2 deletions test/utils/fizzy_engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,9 @@ WasmEngine::Result FizzyEngine::execute(
{
static_assert(sizeof(uint64_t) == sizeof(Value));
const auto first_arg = reinterpret_cast<const Value*>(args.data());
const auto status = fizzy::execute(
*m_instance, static_cast<uint32_t>(func_ref), span<const Value>(first_arg, args.size()));
assert(args.size() ==
m_instance->module.get_function_type(static_cast<uint32_t>(func_ref)).inputs.size());
const auto status = fizzy::execute(*m_instance, static_cast<uint32_t>(func_ref), first_arg);
if (status.trapped)
return {true, std::nullopt};
else if (status.has_value)
Expand Down

0 comments on commit a74e152

Please sign in to comment.