Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace static_cast of forwarding references with std::forward #27

Merged
merged 3 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 22 additions & 22 deletions include/eosio/vm/backend.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,60 +246,60 @@ namespace eosio { namespace vm {
}

template <typename... Args>
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>(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>(args)...);
}
return true;
}

template <typename... Args>
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>(args)...);
} else {
ctx->execute(host, interpret_visitor(*ctx), func_index, args...);
ctx->execute(host, interpret_visitor(*ctx), func_index, std::forward<Args>(args)...);
}
return true;
}

template <typename... Args>
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>(args)...);
} else {
ctx->execute(&host, interpret_visitor(*ctx), func, args...);
ctx->execute(&host, interpret_visitor(*ctx), func, std::forward<Args>(args)...);
}
return true;
}

template <typename... Args>
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>(args)...);
} else {
ctx->execute(nullptr, interpret_visitor(*ctx), func, args...);
ctx->execute(nullptr, interpret_visitor(*ctx), func, std::forward<Args>(args)...);
}
return true;
}

template <typename... Args>
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>(args)...);
} else {
return ctx->execute(&host, interpret_visitor(*ctx), func, args...);
return ctx->execute(&host, interpret_visitor(*ctx), func, std::forward<Args>(args)...);
}
}

template <typename... Args>
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>(args)...);
} else {
return ctx->execute(nullptr, interpret_visitor(*ctx), func, args...);
return ctx->execute(nullptr, interpret_visitor(*ctx), func, std::forward<Args>(args)...);
}
}

Expand All @@ -312,11 +312,11 @@ namespace eosio { namespace vm {
}
}};
try {
auto wd_guard = wd.scoped_run([this,&_timed_out]() {
auto wd_guard = std::forward<Watchdog>(wd).scoped_run([this,&_timed_out]() {
_timed_out = true;
mod->allocator.disable_code();
});
static_cast<F&&>(f)();
std::forward<F>(f)();
} catch(wasm_memory_exception&) {
if (_timed_out) {
throw timeout_exception{ "execution timed out" };
Expand All @@ -328,7 +328,7 @@ namespace eosio { namespace vm {

template <typename Watchdog>
inline void execute_all(Watchdog&& wd, host_t& host) {
timed_run(static_cast<Watchdog&&>(wd), [&]() {
timed_run(std::forward<Watchdog>(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() };
Expand All @@ -340,7 +340,7 @@ namespace eosio { namespace vm {

template <typename Watchdog>
inline void execute_all(Watchdog&& wd) {
timed_run(static_cast<Watchdog&&>(wd), [&]() {
timed_run(std::forward<Watchdog>(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() };
Expand Down
26 changes: 13 additions & 13 deletions include/eosio/vm/execution_context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ namespace eosio { namespace vm {

template <typename Visitor, typename... Args>
inline std::optional<operand_stack_elem> 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>(visitor), func_index, std::forward<Args>(args)...);
}
Expand Down Expand Up @@ -311,22 +311,22 @@ namespace eosio { namespace vm {
}

template <typename... Args>
inline std::optional<operand_stack_elem> execute(host_type* host, jit_visitor, uint32_t func_index, Args... args) {
inline std::optional<operand_stack_elem> 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); });

_host = host;

const auto& ft = _mod->jit_mod->get_function_type(func_index);
this->type_check_args(ft, static_cast<Args&&>(args)...);
this->type_check_args(ft, std::forward<Args>(args)... ); // args not modified by type_check_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&&>(args))... };
native_value args_raw[] = { transform_arg( std::forward<Args>(args))... };
#pragma GCC diagnostic pop

try {
Expand Down Expand Up @@ -482,7 +482,7 @@ namespace eosio { namespace vm {
native_value result;
std::memset(&result, 0, sizeof(result));
auto tc = detail::type_converter_t<Host>{_host, get_interface()};
auto transformed_value = detail::resolve_result(tc, static_cast<T&&>(value)).data;
auto transformed_value = detail::resolve_result(tc, std::forward<T>(value)).data;
std::memcpy(&result, &transformed_value, sizeof(transformed_value));
return result;
}
Expand Down Expand Up @@ -750,13 +750,13 @@ namespace eosio { namespace vm {

template <typename Visitor, typename... Args>
inline std::optional<operand_stack_elem> execute_func_table(host_type* host, Visitor&& visitor, uint32_t table_index,
Args... args) {
Args&&... args) {
return execute(host, std::forward<Visitor>(visitor), table_elem(table_index), std::forward<Args>(args)...);
}

template <typename Visitor, typename... Args>
inline std::optional<operand_stack_elem> 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>(visitor), func_index, std::forward<Args>(args)...);
}
Expand All @@ -768,7 +768,7 @@ namespace eosio { namespace vm {
}

template <typename Visitor, typename... Args>
inline std::optional<operand_stack_elem> execute(host_type* host, Visitor&& visitor, uint32_t func_index, Args... args) {
inline std::optional<operand_stack_elem> execute(host_type* host, Visitor&& visitor, uint32_t func_index, Args&&... args) {
EOS_VM_ASSERT(func_index < std::numeric_limits<uint32_t>::max(), wasm_interpreter_exception,
"cannot execute function, function not found");

Expand All @@ -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), static_cast<Args&&>(args)...);
push_args(args...);
this->type_check_args(_mod->get_function_type(func_index), std::forward<Args>(args)...); // args not modified
push_args(std::forward<Args>(args)...);
push_call<true>(func_index);

if (func_index < _mod->get_imported_functions_size()) {
Expand All @@ -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>(visitor));
}, &handle_signal, {_mod->allocator.get_code_span(), base_type::get_wasm_allocator()->get_span()});
}

Expand Down Expand Up @@ -840,7 +840,7 @@ namespace eosio { namespace vm {
void push_args(Args&&... args) {
auto tc = detail::type_converter_t<Host>{ _host, get_interface() };
(void)tc;
(... , push_operand(detail::resolve_result(tc, std::move(args))));
(... , push_operand(detail::resolve_result(tc, std::forward<Args>(args))));
}

inline void setup_locals(uint32_t index) {
Expand All @@ -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<eosio::vm::EOS_VM_OPCODE_T(NAME)>()); \
ev_label_##NAME : std::forward<Visitor>(visitor)(ev_variant->template get<eosio::vm::EOS_VM_OPCODE_T(NAME)>()); \
ev_variant = _state.pc; \
goto* dispatch_table[ev_variant->index()];
#define CREATE_EXIT_LABEL(NAME, CODE) ev_label_##NAME : \
Expand Down
2 changes: 1 addition & 1 deletion include/eosio/vm/function_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ namespace eosio { namespace vm {
};

template <typename T, typename U>
inline constexpr U&& make_dependent(U&& u) { return static_cast<U&&>(u); }
inline constexpr U&& make_dependent(U&& u) { return std::forward<U>(u); }
}

template <typename F>
Expand Down
14 changes: 7 additions & 7 deletions include/eosio/vm/host_function.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,9 @@ namespace eosio { namespace vm {
template <typename Type_Converter, typename T>
constexpr auto resolve_result(Type_Converter& tc, T&& val) {
if constexpr (has_to_wasm_v<T, Type_Converter>) {
return tc.as_result(tc.to_wasm(static_cast<T&&>(val)));
return tc.as_result(tc.to_wasm(std::forward<T>(val)));
} else {
return tc.as_result(static_cast<T&&>(val));
return tc.as_result(std::forward<T>(val));
}
}

Expand Down Expand Up @@ -281,7 +281,7 @@ namespace eosio { namespace vm {

template <bool Once, typename T, typename F, typename... Args>
void invoke_on(F&& func, const Args&... args) {
detail::invoke_on_impl<Once, 0, T>(static_cast<F&&>(func), args...);
detail::invoke_on_impl<Once, 0, T>(std::forward<F>(func), args...);
}

#define EOS_VM_INVOKE_ON(TYPE, CONDITION) \
Expand All @@ -304,15 +304,15 @@ namespace eosio { namespace vm {
template <auto F, typename Preconditions, typename Type_Converter, typename Host, typename... Args>
decltype(auto) invoke_impl(Type_Converter& tc, Host* host, Args&&... args) {
if constexpr (std::is_same_v<Host, standalone_function_t>)
return std::invoke(F, static_cast<Args&&>(args)...);
return std::invoke(F, std::forward<Args>(args)...);
else
return std::invoke(F, host, static_cast<Args&&>(args)...);
return std::invoke(F, host, std::forward<Args>(args)...);
}

template <auto F, typename Preconditions, typename Host, typename Args, typename Type_Converter, std::size_t... Is>
decltype(auto) invoke_with_host_impl(Type_Converter& tc, Host* host, Args&& args, std::index_sequence<Is...>) {
detail::preconditions_runner<0, Preconditions>(tc, args);
return invoke_impl<F, Preconditions>(tc, host, std::get<Is>(static_cast<Args&&>(args))...);
return invoke_impl<F, Preconditions>(tc, host, std::get<Is>(std::forward<Args>(args))...);
}

template <auto F, typename Preconditions, typename Args, typename Type_Converter, typename Host, std::size_t... Is>
Expand All @@ -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<std::decay_t<T>, maybe_void_t>) {
tc.get_interface().trim_operands(trim_amt);
tc.get_interface().push_operand(detail::resolve_result(tc, static_cast<T&&>(res)));
tc.get_interface().push_operand(detail::resolve_result(tc, std::forward<T>(res)));
} else {
tc.get_interface().trim_operands(trim_amt);
}
Expand Down
2 changes: 1 addition & 1 deletion include/eosio/vm/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ namespace eosio { namespace vm {

template<typename F>
struct scope_guard {
scope_guard(F&& f) : _f(static_cast<F&&>(f)) {}
scope_guard(F&& f) : _f(std::move(f)) {}
~scope_guard() { _f(); }
F _f;
};
Expand Down
18 changes: 9 additions & 9 deletions include/eosio/vm/variant.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ namespace eosio { namespace vm {
union variant_storage<T0, T1, T2, T3, T...> {
V4
template<typename A>
constexpr variant_storage(A&& arg) : _tail{static_cast<A&&>(arg)} {}
constexpr variant_storage(A&& arg) : _tail{std::forward<A>(arg)} {}
variant_storage<T...> _tail;
};
template<typename T0>
Expand Down Expand Up @@ -139,15 +139,15 @@ namespace eosio { namespace vm {
template<int I, typename Storage>
constexpr decltype(auto) variant_storage_get(Storage&& val) {
if constexpr (I == 0) {
return (static_cast<Storage&&>(val)._t0);
return (std::forward<Storage>(val)._t0);
} else if constexpr (I == 1) {
return (static_cast<Storage&&>(val)._t1);
return (std::forward<Storage>(val)._t1);
} else if constexpr (I == 2) {
return (static_cast<Storage&&>(val)._t2);
return (std::forward<Storage>(val)._t2);
} else if constexpr (I == 3) {
return (static_cast<Storage&&>(val)._t3);
return (std::forward<Storage>(val)._t3);
} else {
return detail::variant_storage_get<I - 4>(static_cast<Storage&&>(val)._tail);
return detail::variant_storage_get<I - 4>(std::forward<Storage>(val)._tail);
}
}
} // namespace detail
Expand Down Expand Up @@ -177,7 +177,7 @@ namespace eosio { namespace vm {
template <typename T, typename = std::enable_if_t<detail::is_valid_alternative_v<std::decay_t<T>, Alternatives...>>>
constexpr variant(T&& alt) :
_which(detail::get_alternatives_index_v<std::decay_t<T>, Alternatives...>),
_storage(static_cast<T&&>(alt)) {
_storage(std::forward<T>(alt)) {
}

template <typename T,
Expand All @@ -186,10 +186,10 @@ namespace eosio { namespace vm {
#if (defined(__GNUC__) && !defined(__clang__))
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
_storage = static_cast<T&&>(alt);
_storage = std::forward<T>(alt);
#pragma GCC diagnostic pop
#else
_storage = static_cast<T&&>(alt);
_storage = std::forward<T>(alt);
#endif
_which = detail::get_alternatives_index_v<std::decay_t<T>, Alternatives...>;
return *this;
Expand Down
4 changes: 2 additions & 2 deletions include/eosio/vm/watchdog.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ namespace eosio { namespace vm {
/// be called.
template<typename F>
[[nodiscard]] guard scoped_run(F&& callback) {
return guard(_duration, static_cast<F&&>(callback));
return guard(_duration, std::forward<F>(callback));
}

private:
Expand All @@ -35,7 +35,7 @@ namespace eosio { namespace vm {

template <typename TimeUnits, typename F>
guard(const TimeUnits& duration, F&& callback)
: _callback(static_cast<F&&>(callback)),
: _callback(std::forward<F>(callback)),
_run_state(running),
_duration(duration),
_start(std::chrono::steady_clock::now()) {
Expand Down
2 changes: 1 addition & 1 deletion tools/interp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ int main(int argc, char** argv) {
backend<std::nullptr_t, interpreter, default_options> 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";
Expand Down