From 195fb85cfd97072057f6fc16d2d5c210a7066a99 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Tue, 22 Oct 2024 14:21:38 -0400 Subject: [PATCH 1/3] Replace `static_cast` of forwarding references with `std::forward` --- include/eosio/vm/backend.hpp | 8 ++++---- include/eosio/vm/execution_context.hpp | 12 ++++++------ include/eosio/vm/function_traits.hpp | 2 +- include/eosio/vm/host_function.hpp | 14 +++++++------- include/eosio/vm/utils.hpp | 2 +- include/eosio/vm/variant.hpp | 18 +++++++++--------- include/eosio/vm/watchdog.hpp | 4 ++-- 7 files changed, 30 insertions(+), 30 deletions(-) diff --git a/include/eosio/vm/backend.hpp b/include/eosio/vm/backend.hpp index b0af3e0c..53c58f20 100644 --- a/include/eosio/vm/backend.hpp +++ b/include/eosio/vm/backend.hpp @@ -312,11 +312,11 @@ namespace eosio { namespace vm { } }}; try { - auto wd_guard = wd.scoped_run([this,&_timed_out]() { + auto wd_guard = std::forward(wd).scoped_run([this,&_timed_out]() { _timed_out = true; mod->allocator.disable_code(); }); - static_cast(f)(); + std::forward(f)(); } catch(wasm_memory_exception&) { if (_timed_out) { throw timeout_exception{ "execution timed out" }; @@ -328,7 +328,7 @@ namespace eosio { namespace vm { template inline void execute_all(Watchdog&& wd, host_t& host) { - timed_run(static_cast(wd), [&]() { + timed_run(std::forward(wd), [&]() { for (int i = 0; i < mod->exports.size(); i++) { if (mod->exports[i].kind == external_kind::Function) { std::string s{ (const char*)mod->exports[i].field_str.raw(), mod->exports[i].field_str.size() }; @@ -340,7 +340,7 @@ namespace eosio { namespace vm { template inline void execute_all(Watchdog&& wd) { - timed_run(static_cast(wd), [&]() { + timed_run(std::forward(wd), [&]() { for (int i = 0; i < mod->exports.size(); i++) { if (mod->exports[i].kind == external_kind::Function) { std::string s{ (const char*)mod->exports[i].field_str.raw(), mod->exports[i].field_str.size() }; diff --git a/include/eosio/vm/execution_context.hpp b/include/eosio/vm/execution_context.hpp index e6ac59ce..5dac348f 100644 --- a/include/eosio/vm/execution_context.hpp +++ b/include/eosio/vm/execution_context.hpp @@ -319,14 +319,14 @@ namespace eosio { namespace vm { _host = host; const auto& ft = _mod->jit_mod->get_function_type(func_index); - this->type_check_args(ft, static_cast(args)...); + this->type_check_args(ft, std::forward(args)...); native_value result; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-value" // Calling execute() with no `args` (i.e. `execute(host_type,jit_visitor,uint32_t)`) results in a "statement has no // effect [-Werror=unused-value]" warning on this line. Dissable warning. - native_value args_raw[] = { transform_arg( static_cast(args))... }; + native_value args_raw[] = { transform_arg( std::forward(args))... }; #pragma GCC diagnostic pop try { @@ -482,7 +482,7 @@ namespace eosio { namespace vm { native_value result; std::memset(&result, 0, sizeof(result)); auto tc = detail::type_converter_t{_host, get_interface()}; - auto transformed_value = detail::resolve_result(tc, static_cast(value)).data; + auto transformed_value = detail::resolve_result(tc, std::forward(value)).data; std::memcpy(&result, &transformed_value, sizeof(transformed_value)); return result; } @@ -789,7 +789,7 @@ namespace eosio { namespace vm { _last_op_index = last_last_op_index; }); - this->type_check_args(_mod->get_function_type(func_index), static_cast(args)...); + this->type_check_args(_mod->get_function_type(func_index), std::forward(args)...); push_args(args...); push_call(func_index); @@ -799,7 +799,7 @@ namespace eosio { namespace vm { _state.pc = _mod->get_function_pc(func_index); setup_locals(func_index); vm::invoke_with_signal_handler([&]() { - execute(visitor); + execute(std::forward(visitor)); }, &handle_signal, {_mod->allocator.get_code_span(), base_type::get_wasm_allocator()->get_span()}); } @@ -859,7 +859,7 @@ namespace eosio { namespace vm { #define CREATE_TABLE_ENTRY(NAME, CODE) &&ev_label_##NAME, #define CREATE_LABEL(NAME, CODE) \ - ev_label_##NAME : visitor(ev_variant->template get()); \ + ev_label_##NAME : std::forward(visitor)(ev_variant->template get()); \ ev_variant = _state.pc; \ goto* dispatch_table[ev_variant->index()]; #define CREATE_EXIT_LABEL(NAME, CODE) ev_label_##NAME : \ diff --git a/include/eosio/vm/function_traits.hpp b/include/eosio/vm/function_traits.hpp index 6cea1389..dca5090c 100644 --- a/include/eosio/vm/function_traits.hpp +++ b/include/eosio/vm/function_traits.hpp @@ -69,7 +69,7 @@ namespace eosio { namespace vm { }; template - inline constexpr U&& make_dependent(U&& u) { return static_cast(u); } + inline constexpr U&& make_dependent(U&& u) { return std::forward(u); } } template diff --git a/include/eosio/vm/host_function.hpp b/include/eosio/vm/host_function.hpp index 5ef8fc4c..fe72920f 100644 --- a/include/eosio/vm/host_function.hpp +++ b/include/eosio/vm/host_function.hpp @@ -238,9 +238,9 @@ namespace eosio { namespace vm { template constexpr auto resolve_result(Type_Converter& tc, T&& val) { if constexpr (has_to_wasm_v) { - return tc.as_result(tc.to_wasm(static_cast(val))); + return tc.as_result(tc.to_wasm(std::forward(val))); } else { - return tc.as_result(static_cast(val)); + return tc.as_result(std::forward(val)); } } @@ -281,7 +281,7 @@ namespace eosio { namespace vm { template void invoke_on(F&& func, const Args&... args) { - detail::invoke_on_impl(static_cast(func), args...); + detail::invoke_on_impl(std::forward(func), args...); } #define EOS_VM_INVOKE_ON(TYPE, CONDITION) \ @@ -304,15 +304,15 @@ namespace eosio { namespace vm { template decltype(auto) invoke_impl(Type_Converter& tc, Host* host, Args&&... args) { if constexpr (std::is_same_v) - return std::invoke(F, static_cast(args)...); + return std::invoke(F, std::forward(args)...); else - return std::invoke(F, host, static_cast(args)...); + return std::invoke(F, host, std::forward(args)...); } template decltype(auto) invoke_with_host_impl(Type_Converter& tc, Host* host, Args&& args, std::index_sequence) { detail::preconditions_runner<0, Preconditions>(tc, args); - return invoke_impl(tc, host, std::get(static_cast(args))...); + return invoke_impl(tc, host, std::get(std::forward(args))...); } template @@ -325,7 +325,7 @@ namespace eosio { namespace vm { void maybe_push_result(Type_Converter& tc, T&& res, std::size_t trim_amt) { if constexpr (!std::is_same_v, maybe_void_t>) { tc.get_interface().trim_operands(trim_amt); - tc.get_interface().push_operand(detail::resolve_result(tc, static_cast(res))); + tc.get_interface().push_operand(detail::resolve_result(tc, std::forward(res))); } else { tc.get_interface().trim_operands(trim_amt); } diff --git a/include/eosio/vm/utils.hpp b/include/eosio/vm/utils.hpp index 36e70095..60f5a790 100644 --- a/include/eosio/vm/utils.hpp +++ b/include/eosio/vm/utils.hpp @@ -92,7 +92,7 @@ namespace eosio { namespace vm { template struct scope_guard { - scope_guard(F&& f) : _f(static_cast(f)) {} + scope_guard(F&& f) : _f(std::move(f)) {} ~scope_guard() { _f(); } F _f; }; diff --git a/include/eosio/vm/variant.hpp b/include/eosio/vm/variant.hpp index eba3fc51..6dae518f 100644 --- a/include/eosio/vm/variant.hpp +++ b/include/eosio/vm/variant.hpp @@ -109,7 +109,7 @@ namespace eosio { namespace vm { union variant_storage { V4 template - constexpr variant_storage(A&& arg) : _tail{static_cast(arg)} {} + constexpr variant_storage(A&& arg) : _tail{std::forward(arg)} {} variant_storage _tail; }; template @@ -139,15 +139,15 @@ namespace eosio { namespace vm { template constexpr decltype(auto) variant_storage_get(Storage&& val) { if constexpr (I == 0) { - return (static_cast(val)._t0); + return (std::forward(val)._t0); } else if constexpr (I == 1) { - return (static_cast(val)._t1); + return (std::forward(val)._t1); } else if constexpr (I == 2) { - return (static_cast(val)._t2); + return (std::forward(val)._t2); } else if constexpr (I == 3) { - return (static_cast(val)._t3); + return (std::forward(val)._t3); } else { - return detail::variant_storage_get(static_cast(val)._tail); + return detail::variant_storage_get(std::forward(val)._tail); } } } // namespace detail @@ -177,7 +177,7 @@ namespace eosio { namespace vm { template , Alternatives...>>> constexpr variant(T&& alt) : _which(detail::get_alternatives_index_v, Alternatives...>), - _storage(static_cast(alt)) { + _storage(std::forward(alt)) { } template (alt); + _storage = std::forward(alt); #pragma GCC diagnostic pop #else - _storage = static_cast(alt); + _storage = std::forward(alt); #endif _which = detail::get_alternatives_index_v, Alternatives...>; return *this; diff --git a/include/eosio/vm/watchdog.hpp b/include/eosio/vm/watchdog.hpp index 5e79ea6a..b253148e 100644 --- a/include/eosio/vm/watchdog.hpp +++ b/include/eosio/vm/watchdog.hpp @@ -24,7 +24,7 @@ namespace eosio { namespace vm { /// be called. template [[nodiscard]] guard scoped_run(F&& callback) { - return guard(_duration, static_cast(callback)); + return guard(_duration, std::forward(callback)); } private: @@ -35,7 +35,7 @@ namespace eosio { namespace vm { template guard(const TimeUnits& duration, F&& callback) - : _callback(static_cast(callback)), + : _callback(std::forward(callback)), _run_state(running), _duration(duration), _start(std::chrono::steady_clock::now()) { From a842945b5ab8b52ef6f0c3da9e3a4dd6c1723824 Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Tue, 22 Oct 2024 14:57:10 -0400 Subject: [PATCH 2/3] Fix some `args` usage (not passed as forwarding references, forward only once and last) --- include/eosio/vm/backend.hpp | 36 +++++++++++++------------- include/eosio/vm/execution_context.hpp | 18 ++++++------- tools/interp.cpp | 2 +- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/include/eosio/vm/backend.hpp b/include/eosio/vm/backend.hpp index 53c58f20..1af26a5c 100644 --- a/include/eosio/vm/backend.hpp +++ b/include/eosio/vm/backend.hpp @@ -246,60 +246,60 @@ namespace eosio { namespace vm { } template - inline bool call_indirect(host_t* host, uint32_t func_index, Args... args) { + inline bool call_indirect(host_t* host, uint32_t func_index, Args&&... args) { if constexpr (eos_vm_debug) { - ctx->execute_func_table(host, debug_visitor(*ctx), func_index, args...); + ctx->execute_func_table(host, debug_visitor(*ctx), func_index, std::forward(args)...); } else { - ctx->execute_func_table(host, interpret_visitor(*ctx), func_index, args...); + ctx->execute_func_table(host, interpret_visitor(*ctx), func_index, std::forward(args)...); } return true; } template - inline bool call(host_t* host, uint32_t func_index, Args... args) { + inline bool call(host_t* host, uint32_t func_index, Args&&... args) { if constexpr (eos_vm_debug) { - ctx->execute(host, debug_visitor(*ctx), func_index, args...); + ctx->execute(host, debug_visitor(*ctx), func_index, std::forward(args)...); } else { - ctx->execute(host, interpret_visitor(*ctx), func_index, args...); + ctx->execute(host, interpret_visitor(*ctx), func_index, std::forward(args)...); } return true; } template - inline bool call(host_t& host, const std::string_view& mod, const std::string_view& func, Args... args) { + inline bool call(host_t& host, const std::string_view& mod, const std::string_view& func, Args&&... args) { if constexpr (eos_vm_debug) { - ctx->execute(&host, debug_visitor(*ctx), func, args...); + ctx->execute(&host, debug_visitor(*ctx), func, std::forward(args)...); } else { - ctx->execute(&host, interpret_visitor(*ctx), func, args...); + ctx->execute(&host, interpret_visitor(*ctx), func, std::forward(args)...); } return true; } template - inline bool call(const std::string_view& mod, const std::string_view& func, Args... args) { + inline bool call(const std::string_view& mod, const std::string_view& func, Args&&... args) { if constexpr (eos_vm_debug) { - ctx->execute(nullptr, debug_visitor(*ctx), func, args...); + ctx->execute(nullptr, debug_visitor(*ctx), func, std::forward(args)...); } else { - ctx->execute(nullptr, interpret_visitor(*ctx), func, args...); + ctx->execute(nullptr, interpret_visitor(*ctx), func, std::forward(args)...); } return true; } template - inline auto call_with_return(host_t& host, const std::string_view& mod, const std::string_view& func, Args... args ) { + inline auto call_with_return(host_t& host, const std::string_view& mod, const std::string_view& func, Args&&... args ) { if constexpr (eos_vm_debug) { - return ctx->execute(&host, debug_visitor(*ctx), func, args...); + return ctx->execute(&host, debug_visitor(*ctx), func, std::forward(args)...); } else { - return ctx->execute(&host, interpret_visitor(*ctx), func, args...); + return ctx->execute(&host, interpret_visitor(*ctx), func, std::forward(args)...); } } template - inline auto call_with_return(const std::string_view& mod, const std::string_view& func, Args... args) { + inline auto call_with_return(const std::string_view& mod, const std::string_view& func, Args&&... args) { if constexpr (eos_vm_debug) { - return ctx->execute(nullptr, debug_visitor(*ctx), func, args...); + return ctx->execute(nullptr, debug_visitor(*ctx), func, std::forward(args)...); } else { - return ctx->execute(nullptr, interpret_visitor(*ctx), func, args...); + return ctx->execute(nullptr, interpret_visitor(*ctx), func, std::forward(args)...); } } diff --git a/include/eosio/vm/execution_context.hpp b/include/eosio/vm/execution_context.hpp index 5dac348f..c8c0117e 100644 --- a/include/eosio/vm/execution_context.hpp +++ b/include/eosio/vm/execution_context.hpp @@ -186,7 +186,7 @@ namespace eosio { namespace vm { template inline std::optional execute(host_type* host, Visitor&& visitor, const std::string_view func, - Args... args) { + Args&&... args) { uint32_t func_index = _mod->get_exported_function(func); return derived().execute(host, std::forward(visitor), func_index, std::forward(args)...); } @@ -311,7 +311,7 @@ namespace eosio { namespace vm { } template - inline std::optional execute(host_type* host, jit_visitor, uint32_t func_index, Args... args) { + inline std::optional execute(host_type* host, jit_visitor, uint32_t func_index, Args&&... args) { auto saved_host = _host; auto saved_os_size = get_operand_stack().size(); auto g = scope_guard([&](){ _host = saved_host; get_operand_stack().eat(saved_os_size); }); @@ -319,7 +319,7 @@ namespace eosio { namespace vm { _host = host; const auto& ft = _mod->jit_mod->get_function_type(func_index); - this->type_check_args(ft, std::forward(args)...); + this->type_check_args(ft, args...); native_value result; #pragma GCC diagnostic push @@ -750,13 +750,13 @@ namespace eosio { namespace vm { template inline std::optional execute_func_table(host_type* host, Visitor&& visitor, uint32_t table_index, - Args... args) { + Args&&... args) { return execute(host, std::forward(visitor), table_elem(table_index), std::forward(args)...); } template inline std::optional execute(host_type* host, Visitor&& visitor, const std::string_view func, - Args... args) { + Args&&... args) { uint32_t func_index = _mod->get_exported_function(func); return execute(host, std::forward(visitor), func_index, std::forward(args)...); } @@ -768,7 +768,7 @@ namespace eosio { namespace vm { } template - inline std::optional execute(host_type* host, Visitor&& visitor, uint32_t func_index, Args... args) { + inline std::optional execute(host_type* host, Visitor&& visitor, uint32_t func_index, Args&&... args) { EOS_VM_ASSERT(func_index < std::numeric_limits::max(), wasm_interpreter_exception, "cannot execute function, function not found"); @@ -789,8 +789,8 @@ namespace eosio { namespace vm { _last_op_index = last_last_op_index; }); - this->type_check_args(_mod->get_function_type(func_index), std::forward(args)...); - push_args(args...); + this->type_check_args(_mod->get_function_type(func_index), args...); + push_args(std::forward(args)...); push_call(func_index); if (func_index < _mod->get_imported_functions_size()) { @@ -840,7 +840,7 @@ namespace eosio { namespace vm { void push_args(Args&&... args) { auto tc = detail::type_converter_t{ _host, get_interface() }; (void)tc; - (... , push_operand(detail::resolve_result(tc, std::move(args)))); + (... , push_operand(detail::resolve_result(tc, std::forward(args)))); } inline void setup_locals(uint32_t index) { diff --git a/tools/interp.cpp b/tools/interp.cpp index 1e39e4e8..d9894468 100644 --- a/tools/interp.cpp +++ b/tools/interp.cpp @@ -31,7 +31,7 @@ int main(int argc, char** argv) { backend bkend( code, &wa ); // Execute any exported functions provided by the wasm. - bkend.execute_all(wd); + bkend.execute_all(std::move(wd)); } catch ( const eosio::vm::exception& ex ) { std::cerr << "eos-vm interpreter error\n"; From 6f2591fad2c4b87d00896730b19be8050334f79c Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Tue, 22 Oct 2024 15:40:21 -0400 Subject: [PATCH 3/3] Fix compilation issue in `this->type_check_args` --- include/eosio/vm/execution_context.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/eosio/vm/execution_context.hpp b/include/eosio/vm/execution_context.hpp index c8c0117e..c49d8437 100644 --- a/include/eosio/vm/execution_context.hpp +++ b/include/eosio/vm/execution_context.hpp @@ -319,7 +319,7 @@ namespace eosio { namespace vm { _host = host; const auto& ft = _mod->jit_mod->get_function_type(func_index); - this->type_check_args(ft, args...); + this->type_check_args(ft, std::forward(args)... ); // args not modified by type_check_args native_value result; #pragma GCC diagnostic push @@ -789,7 +789,7 @@ namespace eosio { namespace vm { _last_op_index = last_last_op_index; }); - this->type_check_args(_mod->get_function_type(func_index), args...); + this->type_check_args(_mod->get_function_type(func_index), std::forward(args)...); // args not modified push_args(std::forward(args)...); push_call(func_index);