7#include <softfloat.hpp>
17#include <boost/hana/string.hpp>
19namespace sysio {
namespace chain {
namespace webassembly {
namespace eosvmoc {
33 std::unique_ptr<wasm_instantiated_module_interface>
instantiate_module(
const char* code_bytes,
size_t code_size, std::vector<uint8_t> initial_memory,
68 size_t end = ptr + length*
sizeof(
T);
70 asm volatile(
"cmp %%gs:%c[firstInvalidMemory], %[End]\n"
72 "mov %%gs:%c[firstInvalidMemory], %[End]\n"
73 "add %[sizeOfOneWASMPage], %[End]\n"
74 "mov %%gs:(%[End]), %[Ptr]\n"
76 "add %%gs:%c[linearMemoryStart], %[Ptr]\n"
79 : [linearMemoryStart]
"i" (cb_full_linear_memory_start_segment_offset),
80 [firstInvalidMemory]
"i" (cb_first_invalid_memory_address_segment_offset),
81 [sizeOfOneWASMPage]
"i" (wasm_constraints::wasm_page_size)
100 asm volatile(
"mov %%gs:(%[Ptr]), %[Dumpster]\n"
101 "mov %%gs:%c[firstInvalidMemory], %[Scratch]\n"
102 "cmpb $0, %%gs:-1(%[Scratch])\n"
104 "mov %[Ptr],%[Scratch]\n"
107 "cmpb $0,%%gs:-1(%[Scratch])\n"
110 "add %%gs:%c[linearMemoryStart], %[Ptr]\n"
112 [Dumpster]
"=r" (dumpster),
113 [Scratch]
"=r" (scratch)
114 : [linearMemoryStart]
"i" (cb_full_linear_memory_start_segment_offset),
115 [firstInvalidMemory]
"i" (cb_first_invalid_memory_address_segment_offset)
124 char* full_linear_memory_start;
125 asm(
"mov %%gs:%c[fullLinearMemOffset], %[fullLinearMem]\n"
126 : [fullLinearMem]
"=r" (full_linear_memory_start)
127 : [fullLinearMemOffset]
"i" (cb_full_linear_memory_start_offset)
129 U64 delta = (
U64)(ptr - full_linear_memory_start);
139 static constexpr auto value = ValueType::f32;
144 static constexpr auto value = ValueType::f64;
148 static constexpr auto value = ValueType::i32;
152 static constexpr auto value = ValueType::i64;
162 static constexpr auto value = ResultType::f32;
166 static constexpr auto value = ResultType::f64;
170 static constexpr auto value = ResultType::i32;
174 static constexpr auto value = ResultType::i64;
178 static constexpr auto value = ResultType::none;
195template<
typename Ret,
typename ...Args>
209 using base_type::type_converter;
220 return {
d,
s, size };
226 return {
l,
r, size };
232 return {
d, val, size };
235 template <
typename T>
237 -> std::enable_if_t< std::is_pointer_v<T>,
243 template <
typename T>
245 -> std::enable_if_t<vm::is_span_type_v<T>,
T> {
247 return {
static_cast<typename T::pointer
>(
p),
len};
250 template <
typename T>
252 -> std::enable_if_t< vm::is_argument_proxy_type_v<T> &&
253 vm::is_span_type_v<typename T::proxy_type>,
T> {
258 template <
typename T>
260 -> std::enable_if_t< vm::is_argument_proxy_type_v<T> &&
261 std::is_pointer_v<typename T::proxy_type>,
T> {
262 if constexpr(T::is_legacy()) {
263 SYS_ASSERT(ptr != 0, wasm_execution_error,
"references cannot be created for null pointers");
271 return {
static_cast<const char*
>(
p)};
283 if constexpr (std::is_integral_v<T> &&
sizeof(
T) == 4)
284 return static_cast<T>(val.
i32);
285 else if constexpr (std::is_integral_v<T> &&
sizeof(
T) == 8)
286 return static_cast<T>(val.
i64);
287 else if constexpr (std::is_floating_point_v<T> &&
sizeof(
T) == 4)
288 return static_cast<T>(val.
f32);
289 else if constexpr (std::is_floating_point_v<T> &&
sizeof(
T) == 8)
290 return static_cast<T>(val.
f64);
297template<
typename Args, std::size_t... Is>
305template<
typename TC,
typename Args, std::size_t... Is>
307 return std::tuple<decltype(make_native_type(std::declval<TC>().as_result(std::declval<std::tuple_element_t<Is, Args>>())))...>();
310template<
typename TC,
typename T>
312 if constexpr (vm::detail::has_from_wasm_v<T, TC>) {
316 return std::tuple<decltype(make_native_type(std::declval<TC>().as_result(std::declval<T>())))>();
320template<
typename Args, std::size_t... Is>
335template<
auto F,
typename Interface,
typename Preconditions,
bool is_injected,
typename...
A>
338 if constexpr(!is_injected) {
342 asm volatile(
"cmpl $1,%%gs:%c[callDepthRemainOffset]\n"
344 "callq *%%gs:%c[depthAssertionIntrinsicOffset]\n"
347 : [callDepthRemainOffset]
"i" (cb_current_call_depth_remaining_segment_offset),
348 [depthAssertionIntrinsicOffset]
"i" (depth_assertion_intrinsic_offset)
355 asm(
"mov %%gs:%c[applyContextOffset], %[cPtr]\n"
357 : [applyContextOffset]
"i" (cb_ctx_ptr_offset)
367 __builtin_unreachable();
370template<
auto F,
typename Preconditions,
typename Args,
bool is_injected, std::size_t... Is>
375template<auto F,
typename Preconditions,
bool is_injected>
382template<auto F,
bool injected,
typename Preconditions,
typename Name>
385 if(n == BOOST_HANA_STRING(
"env.sysio_exit"))
return;
391 reinterpret_cast<void*
>(
fn),
#define SYS_ASSERT(expr, exc_type, FORMAT,...)
#define OFFSET_OF_CONTROL_BLOCK_MEMBER(M)
#define OFFSET_OF_FIRST_INTRINSIC
eosvmoc_runtime(const boost::filesystem::path data_dir, const eosvmoc::config &eosvmoc_config, const chainbase::database &db)
void immediately_exit_currently_running_module() override
eosvmoc::code_cache_sync cc
friend eosvmoc_instantiated_module
std::unique_ptr< wasm_instantiated_module_interface > instantiate_module(const char *code_bytes, size_t code_size, std::vector< uint8_t > initial_memory, const digest_type &code_hash, const uint8_t &vm_type, const uint8_t &vm_version) override
sigjmp_buf * eos_vm_oc_get_jmp_buf()
void * eos_vm_oc_get_exception_ptr()
constexpr std::size_t find_intrinsic_index(std::string_view hf)
void * array_ptr_impl(size_t ptr, size_t length)
uint32_t make_native_type(vm::i32_const_t x)
char * null_terminated_ptr_impl(uint64_t ptr)
constexpr auto create_function()
auto get_ct_args(std::index_sequence< Is... >)
void register_eosvm_oc(Name n)
auto convert_native_to_wasm(char *ptr)
constexpr auto wasm_to_value_type_v
auto get_ct_args_one(std::index_sequence< Is... >)
constexpr auto wasm_to_rvalue_type_v
constexpr auto resolve_result(Type_Converter &tc, T &&val)
strip_tag< flatten_parameters_t<&TC::template from_wasm< T > > > from_wasm_type_deducer_t
decltype(auto) invoke_with_host(Type_Converter &tc, Host *host, std::index_sequence< Is... >)
decltype(flatten_parameters(AUTO_PARAM_WORKAROUND(FN))) flatten_parameters_t
std::uint32_t wasm_size_t
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
#define T(meth, val, expected)
schedule config_dir_name data_dir_name p2p_port http_port file_size name host(p2p_endpoint)) FC_REFLECT(tn_node_def
unsigned __int64 uint64_t
static IR_API const FunctionType * get(ResultType ret, const std::initializer_list< ValueType > ¶meters)
Immutable except for fc::from_variant.
const auto & operand_from_back(std::size_t index) const
sysio::vm::native_value * os
SYS_VM_FROM_WASM(bool,(uint32_t value))
auto from_wasm(vm::wasm_ptr_t ptr, vm::wasm_size_t len, vm::tag< T >={}) const -> std::enable_if_t< vm::is_argument_proxy_type_v< T > &&vm::is_span_type_v< typename T::proxy_type >, T >
SYS_VM_FROM_WASM(name,(uint64_t e))
SYS_VM_FROM_WASM(null_terminated_ptr,(vm::wasm_ptr_t ptr))
SYS_VM_FROM_WASM(memcmp_params,(vm::wasm_ptr_t lhs, vm::wasm_ptr_t rhs, vm::wasm_size_t size))
decltype(auto) as_value(const vm::native_value &val) const
SYS_VM_FROM_WASM(float32_t,(float f))
auto from_wasm(vm::wasm_ptr_t ptr) const -> std::enable_if_t< std::is_pointer_v< T >, vm::argument_proxy< T > >
auto from_wasm(vm::wasm_ptr_t ptr, vm::wasm_size_t len, vm::tag< T >={}) const -> std::enable_if_t< vm::is_span_type_v< T >, T >
SYS_VM_FROM_WASM(float64_t,(double f))
vm::wasm_ptr_t to_wasm(void *&&ptr)
auto from_wasm(vm::wasm_ptr_t ptr, vm::tag< T >={}) const -> std::enable_if_t< vm::is_argument_proxy_type_v< T > &&std::is_pointer_v< typename T::proxy_type >, T >
uint64_t to_wasm(name &&n)
SYS_VM_FROM_WASM(memset_params,(vm::wasm_ptr_t dst, int32_t val, vm::wasm_size_t size))
SYS_VM_FROM_WASM(memcpy_params,(vm::wasm_ptr_t dst, vm::wasm_ptr_t src, vm::wasm_size_t size))
result_resolver(eos_vm_oc_type_converter &tc)
eos_vm_oc_type_converter & tc
static const FunctionType * type()
constexpr auto as_result(T &&val) const
decltype(auto) get_host()
uint32_t to_wasm(bool &&value)
#define AUTO_PARAM_WORKAROUND(X)