From 340309f301fe1469a05e48ee47f8349deb2a6559 Mon Sep 17 00:00:00 2001 From: Andrei Maiboroda Date: Tue, 27 Oct 2020 14:03:56 +0100 Subject: [PATCH] Add metering to execute --- include/fizzy/fizzy.h | 6 +- lib/fizzy/capi.cpp | 8 +- lib/fizzy/execute.cpp | 30 ++- lib/fizzy/execute.hpp | 7 +- lib/fizzy/instantiate.cpp | 13 +- lib/fizzy/instantiate.hpp | 4 +- lib/fizzy/instructions.cpp | 220 ++++++++++++++++++ lib/fizzy/instructions.hpp | 2 + test/spectests/spectests.cpp | 2 +- test/testfloat/testfloat.cpp | 2 +- test/unittests/api_test.cpp | 15 +- test/unittests/capi_test.cpp | 49 ++-- test/unittests/end_to_end_test.cpp | 1 + test/unittests/execute_call_test.cpp | 51 ++-- test/unittests/execute_control_test.cpp | 8 +- test/unittests/execute_death_test.cpp | 2 +- .../unittests/execute_floating_point_test.cpp | 1 + test/unittests/execute_test.cpp | 18 +- test/unittests/instantiate_test.cpp | 14 +- test/utils/execute_helpers.hpp | 11 + test/utils/fizzy_c_engine.cpp | 5 +- test/utils/fizzy_engine.cpp | 6 +- tools/wasi/wasi.cpp | 17 +- 23 files changed, 379 insertions(+), 113 deletions(-) diff --git a/include/fizzy/fizzy.h b/include/fizzy/fizzy.h index c2e570244a..fc582f6e8a 100644 --- a/include/fizzy/fizzy.h +++ b/include/fizzy/fizzy.h @@ -47,7 +47,7 @@ typedef struct FizzyExecutionResult /// @param args Pointer to the argument array. Can be NULL iff function has no inputs. /// @param depth Call stack depth. typedef FizzyExecutionResult (*FizzyExternalFn)( - void* context, FizzyInstance* instance, const union FizzyValue* args, int depth); + void* context, FizzyInstance* instance, const union FizzyValue* args, int64_t gas, int depth); /// Value type. typedef uint8_t FizzyValueType; @@ -189,8 +189,8 @@ size_t fizzy_get_instance_memory_size(FizzyInstance* instance); /// No validation is done on the number of arguments passed in @p args, nor on their types. /// When number of passed arguments or their types are different from the ones defined by the /// function type, behaviour is undefined. -FizzyExecutionResult fizzy_execute( - FizzyInstance* instance, uint32_t func_idx, const union FizzyValue* args, int depth); +FizzyExecutionResult fizzy_execute(FizzyInstance* instance, uint32_t func_idx, + const union FizzyValue* args, int64_t gas, int depth); #ifdef __cplusplus } diff --git a/lib/fizzy/capi.cpp b/lib/fizzy/capi.cpp index 5bc1bdce7c..5798905d32 100644 --- a/lib/fizzy/capi.cpp +++ b/lib/fizzy/capi.cpp @@ -103,9 +103,9 @@ inline fizzy::ExecutionResult unwrap(const FizzyExecutionResult& result) noexcep inline auto unwrap(FizzyExternalFn func, void* context) noexcept { - return [func, context](fizzy::Instance& instance, const fizzy::Value* args, + return [func, context](fizzy::Instance& instance, const fizzy::Value* args, int64_t gas, int depth) noexcept -> fizzy::ExecutionResult { - const auto result = func(context, wrap(&instance), wrap(args), depth); + const auto result = func(context, wrap(&instance), wrap(args), gas, depth); return unwrap(result); }; } @@ -261,9 +261,9 @@ size_t fizzy_get_instance_memory_size(FizzyInstance* instance) } FizzyExecutionResult fizzy_execute( - FizzyInstance* instance, uint32_t func_idx, const FizzyValue* args, int depth) + FizzyInstance* instance, uint32_t func_idx, const FizzyValue* args, int64_t gas, int depth) { - const auto result = fizzy::execute(*unwrap(instance), func_idx, unwrap(args), depth); + const auto result = fizzy::execute(*unwrap(instance), func_idx, unwrap(args), gas, depth); return wrap(result); } } diff --git a/lib/fizzy/execute.cpp b/lib/fizzy/execute.cpp index ff54229560..c8ea6d432f 100644 --- a/lib/fizzy/execute.cpp +++ b/lib/fizzy/execute.cpp @@ -5,6 +5,7 @@ #include "execute.hpp" #include "asserts.hpp" #include "cxx20/bit.hpp" +#include "instructions.hpp" #include "stack.hpp" #include "trunc_boundaries.hpp" #include "types.hpp" @@ -478,14 +479,14 @@ void branch(const Code& code, OperandStack& stack, const uint8_t*& pc, const uin } template -inline bool invoke_function( - const FuncType& func_type, const F& func, Instance& instance, OperandStack& stack, int depth) +inline bool invoke_function(const FuncType& func_type, const F& func, Instance& instance, + OperandStack& stack, int64_t gas, int depth) { const auto num_args = func_type.inputs.size(); assert(stack.size() >= num_args); const auto call_args = stack.rend() - num_args; - const auto ret = func(instance, call_args, depth + 1); + const auto ret = func(instance, call_args, gas, depth + 1); // Bubble up traps if (ret.trapped) return false; @@ -504,16 +505,17 @@ inline bool invoke_function( } inline bool invoke_function(const FuncType& func_type, uint32_t func_idx, Instance& instance, - OperandStack& stack, int depth) + OperandStack& stack, int64_t gas, int depth) { - const auto func = [func_idx](Instance& _instance, const Value* args, int _depth) { - return execute(_instance, func_idx, args, _depth); + const auto func = [func_idx](Instance& _instance, const Value* args, int64_t _gas, int _depth) { + return execute(_instance, func_idx, args, _gas, _depth); }; - return invoke_function(func_type, func, instance, stack, depth); + return invoke_function(func_type, func, instance, stack, gas, depth); } } // namespace -ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args, int depth) +ExecutionResult execute( + Instance& instance, FuncIdx func_idx, const Value* args, int64_t gas, int depth) { assert(depth >= 0); if (depth > CallStackLimit) @@ -523,7 +525,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, depth); + return instance.imported_functions[func_idx].function(instance, args, gas, depth); const auto& code = instance.module->get_code(func_idx); auto* const memory = instance.memory.get(); @@ -534,9 +536,15 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args, const uint8_t* pc = code.instructions.data(); const uint8_t* immediates = code.immediates.data(); + const auto cost_table = get_instruction_cost_table(); + while (true) { const auto instruction = static_cast(*pc++); + + if ((gas -= cost_table[static_cast(instruction)]) < 0) + goto trap; + switch (instruction) { case Instr::unreachable: @@ -614,7 +622,7 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args, const auto called_func_idx = read(immediates); const auto& called_func_type = instance.module->get_function_type(called_func_idx); - if (!invoke_function(called_func_type, called_func_idx, instance, stack, depth)) + if (!invoke_function(called_func_type, called_func_idx, instance, stack, gas, depth)) goto trap; break; } @@ -639,7 +647,7 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args, if (expected_type != actual_type) goto trap; - if (!invoke_function(actual_type, called_func->function, instance, stack, depth)) + if (!invoke_function(actual_type, called_func->function, instance, stack, gas, depth)) goto trap; break; } diff --git a/lib/fizzy/execute.hpp b/lib/fizzy/execute.hpp index 6e955eab20..ac40c567f3 100644 --- a/lib/fizzy/execute.hpp +++ b/lib/fizzy/execute.hpp @@ -37,12 +37,13 @@ constexpr ExecutionResult Void{true}; constexpr ExecutionResult Trap{false}; // Execute a function on an instance. -ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args, int depth = 0); +ExecutionResult execute( + Instance& instance, FuncIdx func_idx, const Value* args, int64_t gas, int depth = 0); inline ExecutionResult execute( - Instance& instance, FuncIdx func_idx, std::initializer_list args) + Instance& instance, FuncIdx func_idx, std::initializer_list args, int64_t gas) { assert(args.size() == instance.module->get_function_type(func_idx).inputs.size()); - return execute(instance, func_idx, args.begin()); + return execute(instance, func_idx, args.begin(), gas); } } // namespace fizzy diff --git a/lib/fizzy/instantiate.cpp b/lib/fizzy/instantiate.cpp index 57fd6834e7..3cc163ee61 100644 --- a/lib/fizzy/instantiate.cpp +++ b/lib/fizzy/instantiate.cpp @@ -331,7 +331,8 @@ std::unique_ptr instantiate(std::unique_ptr module, for (const auto idx : instance->module->elementsec[i].init) { auto func = [idx, &instance_ref = *instance](fizzy::Instance&, const Value* args, - int depth) { return execute(instance_ref, idx, args, depth); }; + int64_t gas, + int depth) { return execute(instance_ref, idx, args, gas, depth); }; *it_table++ = ExternalFunction{std::move(func), instance->module->get_function_type(idx)}; @@ -343,7 +344,7 @@ std::unique_ptr instantiate(std::unique_ptr module, { const auto funcidx = *instance->module->startfunc; assert(funcidx < instance->imported_functions.size() + instance->module->funcsec.size()); - if (execute(*instance, funcidx, {}).trapped) + if (execute(*instance, funcidx, {}, 1000000).trapped) { // When element section modified imported table, and then start function trapped, // modifications to the table are not rolled back. @@ -364,7 +365,9 @@ std::unique_ptr instantiate(std::unique_ptr module, auto& table_function = (*it_table)->function; table_function = [shared_instance, func = std::move(table_function)]( fizzy::Instance& _instance, const Value* args, - int depth) { return func(_instance, args, depth); }; + int64_t gas, int depth) { + return func(_instance, args, gas, depth); + }; ++it_table; } } @@ -435,8 +438,8 @@ std::optional find_exported_function(Instance& instance, std:: return std::nullopt; const auto idx = *opt_index; - auto func = [idx, &instance](fizzy::Instance&, const Value* args, int depth) { - return execute(instance, idx, args, depth); + auto func = [idx, &instance](fizzy::Instance&, const Value* args, int64_t gas, int depth) { + return execute(instance, idx, args, gas, depth); }; return ExternalFunction{std::move(func), instance.module->get_function_type(idx)}; diff --git a/lib/fizzy/instantiate.hpp b/lib/fizzy/instantiate.hpp index b66cd98f92..fb767bdfc5 100644 --- a/lib/fizzy/instantiate.hpp +++ b/lib/fizzy/instantiate.hpp @@ -24,7 +24,7 @@ struct Instance; struct ExternalFunction { - std::function function; + std::function function; FuncType type; }; @@ -101,7 +101,7 @@ struct ImportedFunction std::string name; std::vector inputs; std::optional output; - std::function function; + std::function function; }; // Create vector of ExternalFunctions ready to be passed to instantiate. diff --git a/lib/fizzy/instructions.cpp b/lib/fizzy/instructions.cpp index 68904d6c3d..c03432d403 100644 --- a/lib/fizzy/instructions.cpp +++ b/lib/fizzy/instructions.cpp @@ -444,6 +444,222 @@ constexpr uint8_t instruction_max_align_table[256] = { /* f32_reinterpret_i32 = 0xbe */ 0, /* f64_reinterpret_i64 = 0xbf */ 0, }; + +constexpr int16_t instruction_cost_table[256] = { + // 5.4.1 Control instructions + /* unreachable = 0x00 */ 1, + /* nop = 0x01 */ 1, + /* block = 0x02 */ 1, + /* loop = 0x03 */ 1, + /* if_ = 0x04 */ 1, + /* else_ = 0x05 */ 1, + /* 0x06 */ 1, + /* 0x07 */ 1, + /* 0x08 */ 1, + /* 0x09 */ 1, + /* 0x0a */ 1, + /* end = 0x0b */ 1, + /* br = 0x0c */ 1, + /* br_if = 0x0d */ 1, + /* br_table = 0x0e */ 1, + /* return_ = 0x0f */ 1, + /* call = 0x10 */ 1, + /* call_indirect = 0x11 */ 1, + + /* 0x12 */ 1, + /* 0x13 */ 1, + /* 0x14 */ 1, + /* 0x15 */ 1, + /* 0x16 */ 1, + /* 0x17 */ 1, + /* 0x18 */ 1, + /* 0x19 */ 1, + + // 5.4.2 Parametric instructions + /* drop = 0x1a */ 1, + /* select = 0x1b */ 1, + + /* 0x1c */ 1, + /* 0x1d */ 1, + /* 0x1e */ 1, + /* 0x1f */ 1, + + // 5.4.3 Variable instructions + /* local_get = 0x20 */ 1, + /* local_set = 0x21 */ 1, + /* local_tee = 0x22 */ 1, + /* global_get = 0x23 */ 1, + /* global_set = 0x24 */ 1, + + /* 0x25 */ 1, + /* 0x26 */ 1, + /* 0x27 */ 1, + + // 5.4.4 Memory instructions + /* i32_load = 0x28 */ 1, + /* i64_load = 0x29 */ 1, + /* f32_load = 0x2a */ 1, + /* f64_load = 0x2b */ 1, + /* i32_load8_s = 0x2c */ 1, + /* i32_load8_u = 0x2d */ 1, + /* i32_load16_s = 0x2e */ 1, + /* i32_load16_u = 0x2f */ 1, + /* i64_load8_s = 0x30 */ 1, + /* i64_load8_u = 0x31 */ 1, + /* i64_load16_s = 0x32 */ 1, + /* i64_load16_u = 0x33 */ 1, + /* i64_load32_s = 0x34 */ 1, + /* i64_load32_u = 0x35 */ 1, + /* i32_store = 0x36 */ 1, + /* i64_store = 0x37 */ 1, + /* f32_store = 0x38 */ 1, + /* f64_store = 0x39 */ 1, + /* i32_store8 = 0x3a */ 1, + /* i32_store16 = 0x3b */ 1, + /* i64_store8 = 0x3c */ 1, + /* i64_store16 = 0x3d */ 1, + /* i64_store32 = 0x3e */ 1, + /* memory_size = 0x3f */ 1, + /* memory_grow = 0x40 */ 1, + + // 5.4.5 Numeric instructions + /* i32_const = 0x41 */ 1, + /* i64_const = 0x42 */ 1, + /* f32_const = 0x43 */ 1, + /* f64_const = 0x44 */ 1, + + /* i32_eqz = 0x45 */ 1, + /* i32_eq = 0x46 */ 1, + /* i32_ne = 0x47 */ 1, + /* i32_lt_s = 0x48 */ 1, + /* i32_lt_u = 0x49 */ 1, + /* i32_gt_s = 0x4a */ 1, + /* i32_gt_u = 0x4b */ 1, + /* i32_le_s = 0x4c */ 1, + /* i32_le_u = 0x4d */ 1, + /* i32_ge_s = 0x4e */ 1, + /* i32_ge_u = 0x4f */ 1, + + /* i64_eqz = 0x50 */ 1, + /* i64_eq = 0x51 */ 1, + /* i64_ne = 0x52 */ 1, + /* i64_lt_s = 0x53 */ 1, + /* i64_lt_u = 0x54 */ 1, + /* i64_gt_s = 0x55 */ 1, + /* i64_gt_u = 0x56 */ 1, + /* i64_le_s = 0x57 */ 1, + /* i64_le_u = 0x58 */ 1, + /* i64_ge_s = 0x59 */ 1, + /* i64_ge_u = 0x5a */ 1, + + /* f32_eq = 0x5b */ 1, + /* f32_ne = 0x5c */ 1, + /* f32_lt = 0x5d */ 1, + /* f32_gt = 0x5e */ 1, + /* f32_le = 0x5f */ 1, + /* f32_ge = 0x60 */ 1, + + /* f64_eq = 0x61 */ 1, + /* f64_ne = 0x62 */ 1, + /* f64_lt = 0x63 */ 1, + /* f64_gt = 0x64 */ 1, + /* f64_le = 0x65 */ 1, + /* f64_ge = 0x66 */ 1, + + /* i32_clz = 0x67 */ 1, + /* i32_ctz = 0x68 */ 1, + /* i32_popcnt = 0x69 */ 1, + /* i32_add = 0x6a */ 1, + /* i32_sub = 0x6b */ 1, + /* i32_mul = 0x6c */ 1, + /* i32_div_s = 0x6d */ 1, + /* i32_div_u = 0x6e */ 1, + /* i32_rem_s = 0x6f */ 1, + /* i32_rem_u = 0x70 */ 1, + /* i32_and = 0x71 */ 1, + /* i32_or = 0x72 */ 1, + /* i32_xor = 0x73 */ 1, + /* i32_shl = 0x74 */ 1, + /* i32_shr_s = 0x75 */ 1, + /* i32_shr_u = 0x76 */ 1, + /* i32_rotl = 0x77 */ 1, + /* i32_rotr = 0x78 */ 1, + + /* i64_clz = 0x79 */ 1, + /* i64_ctz = 0x7a */ 1, + /* i64_popcnt = 0x7b */ 1, + /* i64_add = 0x7c */ 1, + /* i64_sub = 0x7d */ 1, + /* i64_mul = 0x7e */ 1, + /* i64_div_s = 0x7f */ 1, + /* i64_div_u = 0x80 */ 1, + /* i64_rem_s = 0x81 */ 1, + /* i64_rem_u = 0x82 */ 1, + /* i64_and = 0x83 */ 1, + /* i64_or = 0x84 */ 1, + /* i64_xor = 0x85 */ 1, + /* i64_shl = 0x86 */ 1, + /* i64_shr_s = 0x87 */ 1, + /* i64_shr_u = 0x88 */ 1, + /* i64_rotl = 0x89 */ 1, + /* i64_rotr = 0x8a */ 1, + + /* f32_abs = 0x8b */ 1, + /* f32_neg = 0x8c */ 1, + /* f32_ceil = 0x8d */ 1, + /* f32_floor = 0x8e */ 1, + /* f32_trunc = 0x8f */ 1, + /* f32_nearest = 0x90 */ 1, + /* f32_sqrt = 0x91 */ 1, + /* f32_add = 0x92 */ 1, + /* f32_sub = 0x93 */ 1, + /* f32_mul = 0x94 */ 1, + /* f32_div = 0x95 */ 1, + /* f32_min = 0x96 */ 1, + /* f32_max = 0x97 */ 1, + /* f32_copysign = 0x98 */ 1, + + /* f64_abs = 0x99 */ 1, + /* f64_neg = 0x9a */ 1, + /* f64_ceil = 0x9b */ 1, + /* f64_floor = 0x9c */ 1, + /* f64_trunc = 0x9d */ 1, + /* f64_nearest = 0x9e */ 1, + /* f64_sqrt = 0x9f */ 1, + /* f64_add = 0xa0 */ 1, + /* f64_sub = 0xa1 */ 1, + /* f64_mul = 0xa2 */ 1, + /* f64_div = 0xa3 */ 1, + /* f64_min = 0xa4 */ 1, + /* f64_max = 0xa5 */ 1, + /* f64_copysign = 0xa6 */ 1, + + /* i32_wrap_i64 = 0xa7 */ 1, + /* i32_trunc_f32_s = 0xa8 */ 1, + /* i32_trunc_f32_u = 0xa9 */ 1, + /* i32_trunc_f64_s = 0xaa */ 1, + /* i32_trunc_f64_u = 0xab */ 1, + /* i64_extend_i32_s = 0xac */ 1, + /* i64_extend_i32_u = 0xad */ 1, + /* i64_trunc_f32_s = 0xae */ 1, + /* i64_trunc_f32_u = 0xaf */ 1, + /* i64_trunc_f64_s = 0xb0 */ 1, + /* i64_trunc_f64_u = 0xb1 */ 1, + /* f32_convert_i32_s = 0xb2 */ 1, + /* f32_convert_i32_u = 0xb3 */ 1, + /* f32_convert_i64_s = 0xb4 */ 1, + /* f32_convert_i64_u = 0xb5 */ 1, + /* f32_demote_f64 = 0xb6 */ 1, + /* f64_convert_i32_s = 0xb7 */ 1, + /* f64_convert_i32_u = 0xb8 */ 1, + /* f64_convert_i64_s = 0xb9 */ 1, + /* f64_convert_i64_u = 0xba */ 1, + /* f64_promote_f32 = 0xbb */ 1, + /* i32_reinterpret_f32 = 0xbc */ 1, + /* i64_reinterpret_f64 = 0xbd */ 1, + /* f32_reinterpret_i32 = 0xbe */ 1, + /* f64_reinterpret_i64 = 0xbf */ 1, +}; } // namespace const InstructionType* get_instruction_type_table() noexcept @@ -456,4 +672,8 @@ const uint8_t* get_instruction_max_align_table() noexcept return instruction_max_align_table; } +const int16_t* get_instruction_cost_table() noexcept +{ + return instruction_cost_table; +} } // namespace fizzy diff --git a/lib/fizzy/instructions.hpp b/lib/fizzy/instructions.hpp index 3dec5937e2..d8fd47dee3 100644 --- a/lib/fizzy/instructions.hpp +++ b/lib/fizzy/instructions.hpp @@ -27,4 +27,6 @@ const InstructionType* get_instruction_type_table() noexcept; /// It may contain invalid value for instructions not needing it. const uint8_t* get_instruction_max_align_table() noexcept; +const int16_t* get_instruction_cost_table() noexcept; + } // namespace fizzy diff --git a/test/spectests/spectests.cpp b/test/spectests/spectests.cpp index edc560fc58..f124242a1b 100644 --- a/test/spectests/spectests.cpp +++ b/test/spectests/spectests.cpp @@ -482,7 +482,7 @@ class test_runner } assert(args.size() == instance->module->get_function_type(*func_idx).inputs.size()); - return fizzy::execute(*instance, *func_idx, args.data()); + return fizzy::execute(*instance, *func_idx, args.data(), 10000000); } bool check_integer_result(fizzy::Value actual_value, const json& expected) diff --git a/test/testfloat/testfloat.cpp b/test/testfloat/testfloat.cpp index e68b950c23..b5f4141296 100644 --- a/test/testfloat/testfloat.cpp +++ b/test/testfloat/testfloat.cpp @@ -336,7 +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, args); + const auto r = fizzy::execute(instance, func.idx, args, 1000000); if (func.options == Options::TrapIsInvalidOperation) { diff --git a/test/unittests/api_test.cpp b/test/unittests/api_test.cpp index 61e317d1b3..60df0c8a2a 100644 --- a/test/unittests/api_test.cpp +++ b/test/unittests/api_test.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -17,10 +18,10 @@ namespace { auto function_returning_value(Value value) noexcept { - return [value](Instance&, const Value*, int) { return value; }; + return [value](Instance&, const Value*, int64_t, int) { return value; }; } -ExecutionResult function_returning_void(Instance&, const Value*, int) noexcept +ExecutionResult function_returning_void(Instance&, const Value*, int64_t, int) noexcept { return Void; } @@ -244,7 +245,7 @@ TEST(api, find_exported_function) auto opt_function = find_exported_function(*instance, "foo"); ASSERT_TRUE(opt_function); - EXPECT_THAT(opt_function->function(*instance, {}, 0), Result(42)); + EXPECT_THAT(opt_function->function(*instance, {}, 1000000, 0), Result(42)); EXPECT_TRUE(opt_function->type.inputs.empty()); ASSERT_EQ(opt_function->type.outputs.size(), 1); EXPECT_EQ(opt_function->type.outputs[0], ValType::i32); @@ -263,7 +264,7 @@ TEST(api, find_exported_function) "0061736d010000000105016000017f021001087370656374657374036261720000040401700000050401010102" "0606017f0041000b07170403666f6f000001670300037461620100036d656d0200"); - auto bar = [](Instance&, const Value*, int) { return Value{42}; }; + auto bar = [](Instance&, const Value*, int64_t, int) { return Value{42}; }; const auto bar_type = FuncType{{}, {ValType::i32}}; auto instance_reexported_function = @@ -271,7 +272,7 @@ TEST(api, find_exported_function) opt_function = find_exported_function(*instance_reexported_function, "foo"); ASSERT_TRUE(opt_function); - EXPECT_THAT(opt_function->function(*instance, {}, 0), Result(42)); + EXPECT_THAT(opt_function->function(*instance, {}, 1000000, 0), Result(42)); EXPECT_TRUE(opt_function->type.inputs.empty()); ASSERT_EQ(opt_function->type.outputs.size(), 1); EXPECT_EQ(opt_function->type.outputs[0], ValType::i32); @@ -412,8 +413,8 @@ TEST(api, find_exported_table) ASSERT_TRUE(opt_table); EXPECT_EQ(opt_table->table, instance->table.get()); EXPECT_EQ(opt_table->table->size(), 2); - EXPECT_THAT((*opt_table->table)[0]->function(*instance, {}, 0), Result(2)); - EXPECT_THAT((*opt_table->table)[1]->function(*instance, {}, 0), Result(1)); + EXPECT_THAT((*opt_table->table)[0]->function(*instance, {}, 1000000, 0), Result(2)); + EXPECT_THAT((*opt_table->table)[1]->function(*instance, {}, 1000000, 0), Result(1)); EXPECT_EQ(opt_table->limits.min, 2); ASSERT_TRUE(opt_table->limits.max.has_value()); EXPECT_EQ(opt_table->limits.max, 20); diff --git a/test/unittests/capi_test.cpp b/test/unittests/capi_test.cpp index 367e87b067..586239b980 100644 --- a/test/unittests/capi_test.cpp +++ b/test/unittests/capi_test.cpp @@ -125,7 +125,7 @@ TEST(capi, instantiate_imported_function) ASSERT_NE(module, nullptr); FizzyExternalFunction host_funcs[] = {{{FizzyValueTypeI32, nullptr, 0}, - [](void*, FizzyInstance*, const FizzyValue*, int) { + [](void*, FizzyInstance*, const FizzyValue*, int64_t, int) { return FizzyExecutionResult{false, true, {42}}; }, nullptr}}; @@ -155,7 +155,9 @@ TEST(capi, resolve_instantiate_no_imports) FizzyImportedFunction host_funcs[] = {{"mod", "foo", {{FizzyValueTypeVoid, nullptr, 0}, - [](void*, FizzyInstance*, const FizzyValue*, int) { return FizzyExecutionResult{}; }, + [](void*, FizzyInstance*, const FizzyValue*, int64_t, int) { + return FizzyExecutionResult{}; + }, nullptr}}}; instance = fizzy_resolve_instantiate(module, host_funcs, 1); @@ -183,7 +185,7 @@ TEST(capi, resolve_instantiate) module = fizzy_parse(wasm.data(), wasm.size()); ASSERT_NE(module, nullptr); - FizzyExternalFn host_fn = [](void* context, FizzyInstance*, const FizzyValue*, int) { + FizzyExternalFn host_fn = [](void* context, FizzyInstance*, const FizzyValue*, int64_t, int) { return FizzyExecutionResult{true, false, *static_cast(context)}; }; @@ -302,7 +304,7 @@ TEST(capi, memory_access) memory[0] = 0xaa; memory[1] = 0xbb; - EXPECT_EQ(fizzy_execute(instance, 0, nullptr, 0).value.i64, 0x22bbaa); + EXPECT_EQ(fizzy_execute(instance, 0, nullptr, 1000000, 0).value.i64, 0x22bbaa); fizzy_free_instance(instance); } @@ -340,11 +342,11 @@ TEST(capi, execute) auto instance = fizzy_instantiate(module, nullptr, 0); ASSERT_NE(instance, nullptr); - EXPECT_THAT(fizzy_execute(instance, 0, nullptr, 0), Result()); - EXPECT_THAT(fizzy_execute(instance, 1, nullptr, 0), Result(42)); + EXPECT_THAT(fizzy_execute(instance, 0, nullptr, 1000000, 0), Result()); + EXPECT_THAT(fizzy_execute(instance, 1, nullptr, 1000000, 0), Result(42)); FizzyValue args[] = {{42}, {2}}; - EXPECT_THAT(fizzy_execute(instance, 2, args, 0), Result(21)); - EXPECT_THAT(fizzy_execute(instance, 3, nullptr, 0), Traps()); + EXPECT_THAT(fizzy_execute(instance, 2, args, 1000000, 0), Result(21)); + EXPECT_THAT(fizzy_execute(instance, 3, nullptr, 1000000, 0), Traps()); fizzy_free_instance(instance); } @@ -363,13 +365,14 @@ TEST(capi, execute_with_host_function) const FizzyValueType inputs[] = {FizzyValueTypeI32, FizzyValueTypeI32}; - FizzyExternalFunction host_funcs[] = {{{FizzyValueTypeI32, nullptr, 0}, - [](void*, FizzyInstance*, const FizzyValue*, int) { - return FizzyExecutionResult{false, true, {42}}; - }, - nullptr}, + FizzyExternalFunction host_funcs[] = { + {{FizzyValueTypeI32, nullptr, 0}, + [](void*, FizzyInstance*, const FizzyValue*, int64_t, int) { + return FizzyExecutionResult{false, true, {42}}; + }, + nullptr}, {{FizzyValueTypeI32, &inputs[0], 2}, - [](void*, FizzyInstance*, const FizzyValue* args, int) { + [](void*, FizzyInstance*, const FizzyValue* args, int64_t, int) { return FizzyExecutionResult{false, true, {args[0].i64 / args[1].i64}}; }, nullptr}}; @@ -377,10 +380,10 @@ TEST(capi, execute_with_host_function) auto instance = fizzy_instantiate(module, host_funcs, 2); ASSERT_NE(instance, nullptr); - EXPECT_THAT(fizzy_execute(instance, 0, nullptr, 0), Result(42)); + EXPECT_THAT(fizzy_execute(instance, 0, nullptr, 1000000, 0), Result(42)); FizzyValue args[] = {{42}, {2}}; - EXPECT_THAT(fizzy_execute(instance, 1, args, 0), Result(21)); + EXPECT_THAT(fizzy_execute(instance, 1, args, 1000000, 0), Result(21)); fizzy_free_instance(instance); } @@ -399,7 +402,7 @@ TEST(capi, imported_function_traps) ASSERT_NE(module, nullptr); FizzyExternalFunction host_funcs[] = {{{FizzyValueTypeI32, nullptr, 0}, - [](void*, FizzyInstance*, const FizzyValue*, int) { + [](void*, FizzyInstance*, const FizzyValue*, int64_t, int) { return FizzyExecutionResult{true, false, {}}; }, nullptr}}; @@ -407,7 +410,7 @@ TEST(capi, imported_function_traps) auto instance = fizzy_instantiate(module, host_funcs, 1); ASSERT_NE(instance, nullptr); - EXPECT_THAT(fizzy_execute(instance, 1, nullptr, 0), Traps()); + EXPECT_THAT(fizzy_execute(instance, 1, nullptr, 1000000, 0), Traps()); fizzy_free_instance(instance); } @@ -427,7 +430,7 @@ TEST(capi, imported_function_void) bool called = false; FizzyExternalFunction host_funcs[] = {{{}, - [](void* context, FizzyInstance*, const FizzyValue*, int) { + [](void* context, FizzyInstance*, const FizzyValue*, int64_t, int) { *static_cast(context) = true; return FizzyExecutionResult{false, false, {}}; }, @@ -436,7 +439,7 @@ TEST(capi, imported_function_void) auto instance = fizzy_instantiate(module, host_funcs, 1); ASSERT_NE(instance, nullptr); - EXPECT_THAT(fizzy_execute(instance, 1, nullptr, 0), Result()); + EXPECT_THAT(fizzy_execute(instance, 1, nullptr, 1000000, 0), Result()); EXPECT_TRUE(called); fizzy_free_instance(instance); @@ -482,12 +485,12 @@ TEST(capi, imported_function_from_another_module) auto host_context = std::make_pair(instance1, func_idx); - auto sub = [](void* context, FizzyInstance*, const FizzyValue* args, + auto sub = [](void* context, FizzyInstance*, const FizzyValue* args, int64_t gas, int depth) -> FizzyExecutionResult { const auto* instance_and_func_idx = static_cast*>(context); return fizzy_execute( - instance_and_func_idx->first, instance_and_func_idx->second, args, depth + 1); + instance_and_func_idx->first, instance_and_func_idx->second, args, gas, depth + 1); }; const FizzyValueType inputs[] = {FizzyValueTypeI32, FizzyValueTypeI32}; @@ -498,7 +501,7 @@ TEST(capi, imported_function_from_another_module) ASSERT_NE(instance2, nullptr); FizzyValue args[] = {{44}, {2}}; - EXPECT_THAT(fizzy_execute(instance2, 1, args, 0), Result(42)); + EXPECT_THAT(fizzy_execute(instance2, 1, args, 1000000, 0), Result(42)); fizzy_free_instance(instance2); fizzy_free_instance(instance1); diff --git a/test/unittests/end_to_end_test.cpp b/test/unittests/end_to_end_test.cpp index 2577dd433f..32c290c6dc 100644 --- a/test/unittests/end_to_end_test.cpp +++ b/test/unittests/end_to_end_test.cpp @@ -6,6 +6,7 @@ #include "parser.hpp" #include #include +#include #include #include diff --git a/test/unittests/execute_call_test.cpp b/test/unittests/execute_call_test.cpp index 1bb4b5cc53..9e38dd8350 100644 --- a/test/unittests/execute_call_test.cpp +++ b/test/unittests/execute_call_test.cpp @@ -171,11 +171,11 @@ TEST(execute_call, call_indirect_imported_table) "0061736d01000000010a026000017f60017f017f020a01016d01740170010514030201010a0901070020001100" "000b"); - 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 f1 = [](Instance&, const Value*, int64_t, int) { return Value{1}; }; + auto f2 = [](Instance&, const Value*, int64_t, int) { return Value{2}; }; + auto f3 = [](Instance&, const Value*, int64_t, int) { return Value{3}; }; + auto f4 = [](Instance&, const Value*, int64_t, int) { return Value{4}; }; + auto f5 = [](Instance&, const Value*, int64_t, int) { return Trap; }; auto out_i32 = FuncType{{}, {ValType::i32}}; auto out_i64 = FuncType{{}, {ValType::i64}}; @@ -270,7 +270,7 @@ TEST(execute_call, imported_function_call) const auto module = parse(wasm); - constexpr auto host_foo = [](Instance&, const Value*, int) { return Value{42}; }; + constexpr auto host_foo = [](Instance&, const Value*, int64_t, int) { return Value{42}; }; const auto host_foo_type = module->typesec[0]; auto instance = instantiate(*module, {{host_foo, host_foo_type}}); @@ -295,7 +295,9 @@ TEST(execute_call, imported_function_call_with_arguments) const auto module = parse(wasm); - auto host_foo = [](Instance&, const Value* args, int) { return Value{as_uint32(args[0]) * 2}; }; + auto host_foo = [](Instance&, const Value* args, int64_t, 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}}); @@ -337,11 +339,11 @@ TEST(execute_call, imported_functions_call_indirect) ASSERT_EQ(module->importsec.size(), 2); ASSERT_EQ(module->codesec.size(), 2); - constexpr auto sqr = [](Instance&, const Value* args, int) { + constexpr auto sqr = [](Instance&, const Value* args, int64_t, int) { const auto x = as_uint32(args[0]); return Value{uint64_t{x} * uint64_t{x}}; }; - constexpr auto isqrt = [](Instance&, const Value* args, int) { + constexpr auto isqrt = [](Instance&, const Value* args, int64_t, int) { const auto x = as_uint32(args[0]); return Value{(11 + uint64_t{x} / 11) / 2}; }; @@ -386,8 +388,9 @@ 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&, const Value* args, int) -> ExecutionResult { - return fizzy::execute(*instance1, *func_idx, args); + auto sub = [&instance1, func_idx]( + Instance&, const Value* args, int64_t gas, int) -> ExecutionResult { + return fizzy::execute(*instance1, *func_idx, args, gas); }; auto instance2 = instantiate(parse(bin2), {{sub, module1->typesec[0]}}); @@ -523,8 +526,8 @@ TEST(execute_call, call_max_depth) auto instance = instantiate(parse(bin)); - EXPECT_THAT(execute(*instance, 0, {}, MaxDepth), Result(42)); - EXPECT_THAT(execute(*instance, 1, {}, MaxDepth), Traps()); + EXPECT_THAT(execute(*instance, 0, {}, 1000000, MaxDepth), Result(42)); + EXPECT_THAT(execute(*instance, 1, {}, 1000000, MaxDepth), Traps()); } // A regression test for incorrect number of arguments passed to a call. @@ -558,9 +561,10 @@ TEST(execute_call, call_imported_infinite_recursion) const auto wasm = from_hex("0061736d010000000105016000017f020b01036d6f6403666f6f0000"); const auto module = parse(wasm); - auto host_foo = [](Instance& instance, const Value* args, int depth) -> ExecutionResult { + auto host_foo = [](Instance& instance, const Value* args, int64_t gas, + int depth) -> ExecutionResult { EXPECT_LE(depth, MaxDepth); - return execute(instance, 0, args, depth + 1); + return execute(instance, 0, args, gas, depth + 1); }; const auto host_foo_type = module->typesec[0]; @@ -581,10 +585,11 @@ TEST(execute_call, call_via_imported_infinite_recursion) "0061736d010000000105016000017f020b01036d6f6403666f6f0000030201000a0601040010000b"); const auto module = parse(wasm); - auto host_foo = [](Instance& instance, const Value* args, int depth) -> ExecutionResult { + auto host_foo = [](Instance& instance, const Value* args, int64_t gas, + int depth) -> ExecutionResult { // Function $f will increase depth. This means each iteration goes 2 steps deeper. EXPECT_LE(depth, MaxDepth - 1); - return execute(instance, 1, args, depth + 1); + return execute(instance, 1, args, gas, depth + 1); }; const auto host_foo_type = module->typesec[0]; @@ -601,10 +606,11 @@ TEST(execute_call, call_imported_max_depth_recursion) const auto wasm = from_hex("0061736d010000000105016000017f020b01036d6f6403666f6f0000"); const auto module = parse(wasm); - auto host_foo = [](Instance& instance, const Value* args, int depth) -> ExecutionResult { + auto host_foo = [](Instance& instance, const Value* args, int64_t gas, + int depth) -> ExecutionResult { if (depth == MaxDepth) return Value{uint32_t{1}}; // Terminate recursion on the max depth. - return execute(instance, 0, args, depth + 1); + return execute(instance, 0, args, gas, depth + 1); }; const auto host_foo_type = module->typesec[0]; @@ -625,11 +631,12 @@ TEST(execute_call, call_via_imported_max_depth_recursion) "0061736d010000000105016000017f020b01036d6f6403666f6f0000030201000a0601040010000b"); const auto module = parse(wasm); - auto host_foo = [](Instance& instance, const Value* args, int depth) -> ExecutionResult { + auto host_foo = [](Instance& instance, const Value* args, int64_t gas, + int depth) -> ExecutionResult { // Function $f will increase depth. This means each iteration goes 2 steps deeper. if (depth == (MaxDepth - 1)) return Value{uint32_t{1}}; // Terminate recursion on the max depth. - return execute(instance, 1, args, depth + 1); + return execute(instance, 1, args, gas, depth + 1); }; const auto host_foo_type = module->typesec[0]; @@ -697,5 +704,5 @@ TEST(execute_call, drop_call_result) EXPECT_EQ(module->codesec[1].max_stack_height, 1); const auto func_idx = find_exported_function(*module, "drop_call_result"); auto instance = instantiate(*module); - EXPECT_THAT(fizzy::execute(*instance, *func_idx, {}), Result()); + EXPECT_THAT(execute(*instance, *func_idx, {}), Result()); } diff --git a/test/unittests/execute_control_test.cpp b/test/unittests/execute_control_test.cpp index b20df346d5..b85cdc14d2 100644 --- a/test/unittests/execute_control_test.cpp +++ b/test/unittests/execute_control_test.cpp @@ -664,7 +664,7 @@ TEST(execute_control, br_1_out_of_function_and_imported_function) "0061736d010000000108026000006000017f02150108696d706f727465640866756e6374696f6e000003020101" "0a0d010b00034041010c010b41000b"); - constexpr auto fake_imported_function = [](Instance&, const Value*, + constexpr auto fake_imported_function = [](Instance&, const Value*, int64_t, int) noexcept -> ExecutionResult { return Void; }; const auto module = parse(bin); @@ -977,9 +977,9 @@ TEST(execute_control, br_table_arity) const auto wasm = from_hex( "0061736d0100000001060160017f017f030201000a15011300027f027f410120000e0101000b1a41020b0b"); - auto instance = parse(wasm); - EXPECT_THAT(execute(instance, 0, {0}), Result(1)); - EXPECT_THAT(execute(instance, 0, {1}), Result(2)); + auto module = parse(wasm); + EXPECT_THAT(execute(module, 0, {0}), Result(1)); + EXPECT_THAT(execute(module, 0, {1}), Result(2)); /* wat2wasm (func (param $x i32) (result i32) diff --git a/test/unittests/execute_death_test.cpp b/test/unittests/execute_death_test.cpp index 51539671bd..9bedd3e656 100644 --- a/test/unittests/execute_death_test.cpp +++ b/test/unittests/execute_death_test.cpp @@ -23,6 +23,6 @@ TEST(execute_death, malformed_instruction_opcode) module->codesec.emplace_back(std::move(code)); auto instance = instantiate(std::move(module)); - EXPECT_DEATH(execute(*instance, 0, nullptr), "unreachable"); + EXPECT_DEATH(execute(*instance, 0, nullptr, 1000000), "unreachable"); } #endif diff --git a/test/unittests/execute_floating_point_test.cpp b/test/unittests/execute_floating_point_test.cpp index 82ffef464c..86721739d1 100644 --- a/test/unittests/execute_floating_point_test.cpp +++ b/test/unittests/execute_floating_point_test.cpp @@ -8,6 +8,7 @@ #include "trunc_boundaries.hpp" #include #include +#include #include #include #include diff --git a/test/unittests/execute_test.cpp b/test/unittests/execute_test.cpp index 8611afe4a9..dca82a3402 100644 --- a/test/unittests/execute_test.cpp +++ b/test/unittests/execute_test.cpp @@ -774,7 +774,7 @@ TEST(execute, imported_function) const auto module = parse(wasm); ASSERT_EQ(module->typesec.size(), 1); - constexpr auto host_foo = [](Instance&, const Value* args, int) { + constexpr auto host_foo = [](Instance&, const Value* args, int64_t, int) { return Value{as_uint32(args[0]) + as_uint32(args[1])}; }; @@ -794,10 +794,10 @@ TEST(execute, imported_two_functions) const auto module = parse(wasm); ASSERT_EQ(module->typesec.size(), 1); - constexpr auto host_foo1 = [](Instance&, const Value* args, int) { + constexpr auto host_foo1 = [](Instance&, const Value* args, int64_t, int) { return Value{as_uint32(args[0]) + as_uint32(args[1])}; }; - constexpr auto host_foo2 = [](Instance&, const Value* args, int) { + constexpr auto host_foo2 = [](Instance&, const Value* args, int64_t, int) { return Value{as_uint32(args[0]) * as_uint32(args[1])}; }; @@ -821,10 +821,10 @@ TEST(execute, imported_functions_and_regular_one) "0061736d0100000001070160027f7f017f021702036d6f6404666f6f310000036d6f6404666f6f320000030201" "000a0901070041aa80a8010b"); - constexpr auto host_foo1 = [](Instance&, const Value* args, int) { + constexpr auto host_foo1 = [](Instance&, const Value* args, int64_t, int) { return Value{as_uint32(args[0]) + as_uint32(args[1])}; }; - constexpr auto host_foo2 = [](Instance&, const Value* args, int) { + constexpr auto host_foo2 = [](Instance&, const Value* args, int64_t, int) { return Value{as_uint32(args[0]) * as_uint32(args[1])}; }; @@ -851,10 +851,10 @@ TEST(execute, imported_two_functions_different_type) "0061736d01000000010c0260027f7f017f60017e017e021702036d6f6404666f6f310000036d6f6404666f6f32" "0001030201010a0901070042aa80a8010b"); - constexpr auto host_foo1 = [](Instance&, const Value* args, int) { + constexpr auto host_foo1 = [](Instance&, const Value* args, int64_t, int) { return Value{as_uint32(args[0]) + as_uint32(args[1])}; }; - constexpr auto host_foo2 = [](Instance&, const Value* args, int) { + constexpr auto host_foo2 = [](Instance&, const Value* args, int64_t, int) { return Value{args[0].i64 * args[0].i64}; }; @@ -875,7 +875,9 @@ TEST(execute, imported_function_traps) */ const auto wasm = from_hex("0061736d0100000001070160027f7f017f020b01036d6f6403666f6f0000"); - constexpr auto host_foo = [](Instance&, const Value*, int) -> ExecutionResult { return Trap; }; + constexpr auto host_foo = [](Instance&, const Value*, int64_t, int) -> ExecutionResult { + return Trap; + }; const auto module = parse(wasm); auto instance = instantiate(*module, {{host_foo, module->typesec[0]}}); diff --git a/test/unittests/instantiate_test.cpp b/test/unittests/instantiate_test.cpp index abf0af6a42..1fe6503646 100644 --- a/test/unittests/instantiate_test.cpp +++ b/test/unittests/instantiate_test.cpp @@ -18,7 +18,7 @@ namespace uint32_t call_table_func(Instance& instance, size_t idx) { const auto& elem = (*instance.table)[idx]; - const auto res = elem->function(instance, {}, 0); + const auto res = elem->function(instance, {}, 1000000, 0); EXPECT_TRUE(res.has_value); return as_uint32(res.value); } @@ -32,7 +32,7 @@ TEST(instantiate, imported_functions) const auto bin = from_hex("0061736d0100000001060160017f017f020b01036d6f6403666f6f0000"); const auto module = parse(bin); - auto host_foo = [](Instance&, const Value*, int) { return Trap; }; + auto host_foo = [](Instance&, const Value*, int64_t, int) { return Trap; }; auto instance = instantiate(*module, {{host_foo, module->typesec[0]}}); ASSERT_EQ(instance->imported_functions.size(), 1); @@ -53,8 +53,8 @@ TEST(instantiate, imported_functions_multiple) "0061736d0100000001090260017f017f600000021702036d6f6404666f6f310000036d6f6404666f6f320001"); const auto module = parse(bin); - auto host_foo1 = [](Instance&, const Value*, int) { return Trap; }; - auto host_foo2 = [](Instance&, const Value*, int) { return Trap; }; + auto host_foo1 = [](Instance&, const Value*, int64_t, int) { return Trap; }; + auto host_foo2 = [](Instance&, const Value*, int64_t, int) { return Trap; }; auto instance = instantiate(*module, {{host_foo1, module->typesec[0]}, {host_foo2, module->typesec[1]}}); @@ -87,7 +87,7 @@ TEST(instantiate, imported_function_wrong_type) */ const auto bin = from_hex("0061736d0100000001060160017f017f020b01036d6f6403666f6f0000"); - auto host_foo = [](Instance&, const Value*, int) { return Trap; }; + auto host_foo = [](Instance&, const Value*, int64_t, int) { return Trap; }; const auto host_foo_type = FuncType{{}, {}}; EXPECT_THROW_MESSAGE(instantiate(parse(bin), {{host_foo, host_foo_type}}), instantiate_error, @@ -637,7 +637,7 @@ TEST(instantiate, element_section_fills_imported_table) "0061736d010000000105016000017f020b01016d037461620170000403050400000000090f020041010b020001" "0041020b0202030a1504040041010b040041020b040041030b040041040b"); - auto f0 = [](Instance&, const Value*, int) { return Value{0}; }; + auto f0 = [](Instance&, const Value*, int64_t, int) { return Value{0}; }; table_elements table(4); table[0] = ExternalFunction{f0, FuncType{{}, {ValType::i32}}}; @@ -664,7 +664,7 @@ TEST(instantiate, element_section_out_of_bounds_doesnt_change_imported_table) "0061736d010000000105016000017f020b01016d037461620170000303020100090f020041000b020000004102" "0b0200000a0601040041010b"); - auto f0 = [](Instance&, const Value*, int) { return Value{0}; }; + auto f0 = [](Instance&, const Value*, int64_t, int) { return Value{0}; }; table_elements table(3); table[0] = ExternalFunction{f0, FuncType{{}, {ValType::i32}}}; diff --git a/test/utils/execute_helpers.hpp b/test/utils/execute_helpers.hpp index 0a76374c2d..dd78e434f3 100644 --- a/test/utils/execute_helpers.hpp +++ b/test/utils/execute_helpers.hpp @@ -10,6 +10,17 @@ namespace fizzy::test { +inline ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args) +{ + return execute(instance, func_idx, args, 1000000, 0); +} + +inline ExecutionResult execute( + Instance& instance, FuncIdx func_idx, std::initializer_list args) +{ + return execute(instance, func_idx, args, 1000000); +} + inline ExecutionResult execute(const std::unique_ptr& module, FuncIdx func_idx, std::initializer_list args) { diff --git a/test/utils/fizzy_c_engine.cpp b/test/utils/fizzy_c_engine.cpp index f1a3cb694c..c08b9c68e8 100644 --- a/test/utils/fizzy_c_engine.cpp +++ b/test/utils/fizzy_c_engine.cpp @@ -28,7 +28,8 @@ class FizzyCEngine final : public WasmEngine namespace { -FizzyExecutionResult env_adler32(void*, FizzyInstance* instance, const FizzyValue* args, int) +FizzyExecutionResult env_adler32( + void*, FizzyInstance* instance, const FizzyValue* args, int64_t, int) { auto* memory = fizzy_get_instance_memory_data(instance); assert(memory != nullptr); @@ -110,7 +111,7 @@ WasmEngine::Result FizzyCEngine::execute( static_assert(sizeof(uint64_t) == sizeof(FizzyValue)); const auto first_arg = reinterpret_cast(args.data()); const auto status = - fizzy_execute(m_instance.get(), static_cast(func_ref), first_arg, 0); + fizzy_execute(m_instance.get(), static_cast(func_ref), first_arg, 1000000, 0); if (status.trapped) return {true, std::nullopt}; else if (status.has_value) diff --git a/test/utils/fizzy_engine.cpp b/test/utils/fizzy_engine.cpp index 9c3286a962..c549247759 100644 --- a/test/utils/fizzy_engine.cpp +++ b/test/utils/fizzy_engine.cpp @@ -53,7 +53,8 @@ FuncType translate_signature(std::string_view signature) return func_type; } -fizzy::ExecutionResult env_adler32(fizzy::Instance& instance, const fizzy::Value* args, int) +fizzy::ExecutionResult env_adler32( + fizzy::Instance& instance, const fizzy::Value* args, int64_t, int) { assert(instance.memory != nullptr); const auto ret = fizzy::test::adler32( @@ -138,7 +139,8 @@ WasmEngine::Result FizzyEngine::execute( const auto first_arg = reinterpret_cast(args.data()); assert(args.size() == m_instance->module->get_function_type(static_cast(func_ref)).inputs.size()); - const auto status = fizzy::execute(*m_instance, static_cast(func_ref), first_arg); + const auto status = + fizzy::execute(*m_instance, static_cast(func_ref), first_arg, 1000000); if (status.trapped) return {true, std::nullopt}; else if (status.has_value) diff --git a/tools/wasi/wasi.cpp b/tools/wasi/wasi.cpp index 4e9c5146aa..3393e0d65b 100644 --- a/tools/wasi/wasi.cpp +++ b/tools/wasi/wasi.cpp @@ -18,19 +18,20 @@ 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(fizzy::Instance&, const fizzy::Value*, int) +fizzy::ExecutionResult wasi_return_enosys(fizzy::Instance&, const fizzy::Value*, int64_t, int) { return fizzy::Value{uint32_t{UVWASI_ENOSYS}}; } -fizzy::ExecutionResult wasi_proc_exit(fizzy::Instance&, const fizzy::Value* args, int) +fizzy::ExecutionResult wasi_proc_exit(fizzy::Instance&, const fizzy::Value* args, int64_t, int) { uvwasi_proc_exit(&state, static_cast(args[0].as())); // Should not reach this. return fizzy::Trap; } -fizzy::ExecutionResult wasi_fd_write(fizzy::Instance& instance, const fizzy::Value* args, int) +fizzy::ExecutionResult wasi_fd_write( + fizzy::Instance& instance, const fizzy::Value* args, int64_t, int) { const auto fd = args[0].as(); const auto iov_ptr = args[1].as(); @@ -51,7 +52,8 @@ fizzy::ExecutionResult wasi_fd_write(fizzy::Instance& instance, const fizzy::Val return fizzy::Value{uint32_t{ret}}; } -fizzy::ExecutionResult wasi_fd_read(fizzy::Instance& instance, const fizzy::Value* args, int) +fizzy::ExecutionResult wasi_fd_read( + fizzy::Instance& instance, const fizzy::Value* args, int64_t, int) { const auto fd = args[0].as(); const auto iov_ptr = args[1].as(); @@ -72,7 +74,8 @@ fizzy::ExecutionResult wasi_fd_read(fizzy::Instance& instance, const fizzy::Valu return fizzy::Value{uint32_t{ret}}; } -fizzy::ExecutionResult wasi_fd_prestat_get(fizzy::Instance& instance, const fizzy::Value* args, int) +fizzy::ExecutionResult wasi_fd_prestat_get( + fizzy::Instance& instance, const fizzy::Value* args, int64_t, int) { const auto fd = args[0].as(); const auto prestat_ptr = args[1].as(); @@ -86,7 +89,7 @@ fizzy::ExecutionResult wasi_fd_prestat_get(fizzy::Instance& instance, const fizz } fizzy::ExecutionResult wasi_environ_sizes_get( - fizzy::Instance& instance, const fizzy::Value* args, int) + fizzy::Instance& instance, const fizzy::Value* args, int64_t, int) { const auto environc = args[0].as(); const auto environ_buf_size = args[1].as(); @@ -179,7 +182,7 @@ bool run(int argc, const char** argv) return false; } - const auto result = fizzy::execute(*instance, *start_function, {}); + const auto result = fizzy::execute(*instance, *start_function, {}, 1000000); if (result.trapped) { std::cerr << "Execution aborted with WebAssembly trap\n";