Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
sysio::vm::execution_context< Host > Class Template Reference

#include <execution_context.hpp>

Inheritance diagram for sysio::vm::execution_context< Host >:
Collaboration diagram for sysio::vm::execution_context< Host >:

Public Member Functions

 execution_context (module &m, uint32_t max_call_depth)
 
void set_max_call_depth (uint32_t max_call_depth)
 
void call (uint32_t index)
 
void print_stack ()
 
uint32_t table_elem (uint32_t i)
 
void push_operand (operand_stack_elem el)
 
operand_stack_elem get_operand (uint32_t index) const
 
void eat_operands (uint32_t index)
 
void compact_operand (uint32_t index)
 
void set_operand (uint32_t index, const operand_stack_elem &el)
 
uint32_t current_operands_index () const
 
void push_call (activation_frame &&el)
 
activation_frame pop_call ()
 
uint32_t call_depth () const
 
template<bool Should_Exit = false>
void push_call (uint32_t index)
 
void apply_pop_call (uint32_t num_locals, uint16_t return_count)
 
operand_stack_elem pop_operand ()
 
operand_stack_elempeek_operand (size_t i=0)
 
operand_stack_elem get_global (uint32_t index)
 
void set_global (uint32_t index, const operand_stack_elem &el)
 
bool is_true (const operand_stack_elem &el)
 
void type_check (const func_type &ft)
 
opcodeget_pc () const
 
void set_relative_pc (uint32_t pc_offset)
 
void set_pc (opcode *pc)
 
void inc_pc (uint32_t offset=1)
 
void exit (std::error_code err=std::error_code())
 
void reset ()
 
template<typename Visitor , typename... Args>
std::optional< operand_stack_elemexecute_func_table (host_type *host, Visitor &&visitor, uint32_t table_index, Args... args)
 
template<typename Visitor , typename... Args>
std::optional< operand_stack_elemexecute (host_type *host, Visitor &&visitor, const std::string_view func, Args... args)
 
template<typename Visitor , typename... Args>
void execute_start (host_type *host, Visitor &&visitor)
 
template<typename Visitor , typename... Args>
std::optional< operand_stack_elemexecute (host_type *host, Visitor &&visitor, uint32_t func_index, Args... args)
 
void jump (uint32_t pop_info, uint32_t new_pc)
 
int backtrace (void **data, int limit, void *uc) const
 
 execution_context (module &m, uint32_t max_call_depth)
 
void set_max_call_depth (uint32_t max_call_depth)
 
void call (uint32_t index)
 
void print_stack ()
 
uint32_t table_elem (uint32_t i)
 
void push_operand (operand_stack_elem el)
 
operand_stack_elem get_operand (uint32_t index) const
 
void eat_operands (uint32_t index)
 
void compact_operand (uint32_t index)
 
void set_operand (uint32_t index, const operand_stack_elem &el)
 
uint32_t current_operands_index () const
 
void push_call (activation_frame &&el)
 
activation_frame pop_call ()
 
uint32_t call_depth () const
 
template<bool Should_Exit = false>
void push_call (uint32_t index)
 
void apply_pop_call (uint32_t num_locals, uint16_t return_count)
 
operand_stack_elem pop_operand ()
 
operand_stack_elempeek_operand (size_t i=0)
 
operand_stack_elem get_global (uint32_t index)
 
void set_global (uint32_t index, const operand_stack_elem &el)
 
bool is_true (const operand_stack_elem &el)
 
void type_check (const func_type &ft)
 
opcodeget_pc () const
 
void set_relative_pc (uint32_t pc_offset)
 
void set_pc (opcode *pc)
 
void inc_pc (uint32_t offset=1)
 
void exit (std::error_code err=std::error_code())
 
void reset ()
 
template<typename Visitor , typename... Args>
std::optional< operand_stack_elemexecute_func_table (host_type *host, Visitor &&visitor, uint32_t table_index, Args... args)
 
template<typename Visitor , typename... Args>
std::optional< operand_stack_elemexecute (host_type *host, Visitor &&visitor, const std::string_view func, Args... args)
 
template<typename Visitor , typename... Args>
void execute_start (host_type *host, Visitor &&visitor)
 
template<typename Visitor , typename... Args>
std::optional< operand_stack_elemexecute (host_type *host, Visitor &&visitor, uint32_t func_index, Args... args)
 
void jump (uint32_t pop_info, uint32_t new_pc)
 
int backtrace (void **data, int limit, void *uc) const
 
- Public Member Functions inherited from sysio::vm::execution_context_base< execution_context< Host >, Host >
execution_context< Host > & derived ()
 
execution_context< Host > & derived ()
 
 execution_context_base (module &m)
 
 execution_context_base (module &m)
 
int32_t grow_linear_memory (int32_t pages)
 
int32_t grow_linear_memory (int32_t pages)
 
int32_t current_linear_memory () const
 
int32_t current_linear_memory () const
 
void exit (std::error_code err=std::error_code())
 
void exit (std::error_code err=std::error_code())
 
moduleget_module ()
 
moduleget_module ()
 
void set_wasm_allocator (wasm_allocator *alloc)
 
void set_wasm_allocator (wasm_allocator *alloc)
 
auto get_wasm_allocator ()
 
auto get_wasm_allocator ()
 
char * linear_memory ()
 
char * linear_memory ()
 
auto & get_operand_stack ()
 
const auto & get_operand_stack () const
 
auto & get_operand_stack ()
 
const auto & get_operand_stack () const
 
auto get_interface ()
 
auto get_interface ()
 
void set_max_pages (std::uint32_t max_pages)
 
void set_max_pages (std::uint32_t max_pages)
 
std::error_code get_error_code () const
 
std::error_code get_error_code () const
 
void reset ()
 
void reset ()
 
std::optional< operand_stack_elemexecute (host_type *host, Visitor &&visitor, const std::string_view func, Args... args)
 
std::optional< operand_stack_elemexecute (host_type *host, Visitor &&visitor, const std::string_view func, Args... args)
 
void execute_start (host_type *host, Visitor &&visitor)
 
void execute_start (host_type *host, Visitor &&visitor)
 

Additional Inherited Members

- Static Protected Member Functions inherited from sysio::vm::execution_context_base< execution_context< Host >, Host >
static void type_check_args (const func_type &ft, Args &&...)
 
static void type_check_args (const func_type &ft, Args &&...)
 
static void handle_signal (int sig)
 
static void handle_signal (int sig)
 
- Protected Attributes inherited from sysio::vm::execution_context_base< execution_context< Host >, Host >
char * _linear_memory
 
module_mod
 
wasm_allocator_wasm_alloc
 
uint32_t _max_pages
 
detail::host_invoker_t< Host > _rhf
 
std::error_code _error_code
 
operand_stack _os
 

Detailed Description

template<typename Host>
class sysio::vm::execution_context< Host >

Definition at line 483 of file execution_context.hpp.

Constructor & Destructor Documentation

◆ execution_context() [1/2]

template<typename Host >
sysio::vm::execution_context< Host >::execution_context ( module & m,
uint32_t max_call_depth )
inline

Definition at line 495 of file execution_context.hpp.

496 : base_type(m), _base_allocator{max_call_depth*sizeof(activation_frame)},
497 _as{max_call_depth, _base_allocator}, _halt(exit_t{}) {}

◆ execution_context() [2/2]

template<typename Host >
sysio::vm::execution_context< Host >::execution_context ( module & m,
uint32_t max_call_depth )
inline

Definition at line 495 of file execution_context.hpp.

496 : base_type(m), _base_allocator{max_call_depth*sizeof(activation_frame)},
497 _as{max_call_depth, _base_allocator}, _halt(exit_t{}) {}

Member Function Documentation

◆ apply_pop_call() [1/2]

template<typename Host >
void sysio::vm::execution_context< Host >::apply_pop_call ( uint32_t num_locals,
uint16_t return_count )
inline

Definition at line 563 of file execution_context.hpp.

563 {
564 const auto& af = _as.pop();
565 _state.pc = af.pc;
566 _last_op_index = af.last_op_index;
567 if (return_count)
568 compact_operand(get_operand_stack().size() - num_locals - 1);
569 else
570 eat_operands(get_operand_stack().size() - num_locals);
571 }
void compact_operand(uint32_t index)

◆ apply_pop_call() [2/2]

template<typename Host >
void sysio::vm::execution_context< Host >::apply_pop_call ( uint32_t num_locals,
uint16_t return_count )
inline

Definition at line 563 of file execution_context.hpp.

563 {
564 const auto& af = _as.pop();
565 _state.pc = af.pc;
566 _last_op_index = af.last_op_index;
567 if (return_count)
568 compact_operand(get_operand_stack().size() - num_locals - 1);
569 else
570 eat_operands(get_operand_stack().size() - num_locals);
571 }

◆ backtrace() [1/2]

template<typename Host >
int sysio::vm::execution_context< Host >::backtrace ( void ** data,
int limit,
void * uc ) const
inline

Definition at line 740 of file execution_context.hpp.

740 {
741 int out = 0;
742 if(limit != 0) {
743 data[out++] = _state.pc;
744 }
745 for(int i = 0; out < limit && i < _as.size(); ++i) {
746 data[out++] = _as.get_back(i).pc;
747 }
748 return out;
749 }
ElemT & get_back(size_t i)
size_t size() const

◆ backtrace() [2/2]

template<typename Host >
int sysio::vm::execution_context< Host >::backtrace ( void ** data,
int limit,
void * uc ) const
inline

Definition at line 740 of file execution_context.hpp.

740 {
741 int out = 0;
742 if(limit != 0) {
743 data[out++] = _state.pc;
744 }
745 for(int i = 0; out < limit && i < _as.size(); ++i) {
746 data[out++] = _as.get_back(i).pc;
747 }
748 return out;
749 }

◆ call() [1/2]

template<typename Host >
void sysio::vm::execution_context< Host >::call ( uint32_t index)
inline

Definition at line 511 of file execution_context.hpp.

511 {
512 // TODO validate index is valid
513 if (index < _mod.get_imported_functions_size()) {
514 // TODO validate only importing functions
515 const auto& ft = _mod.types[_mod.imports[index].type.func_t];
516 type_check(ft);
517 inc_pc();
518 push_call( activation_frame{ nullptr, 0 } );
519 _rhf(_state.host, get_interface(), _mod.import_functions[index]);
520 pop_call();
521 } else {
522 // const auto& ft = _mod.types[_mod.functions[index - _mod.get_imported_functions_size()]];
523 // type_check(ft);
524 push_call(index);
525 setup_locals(index);
526 set_pc( _mod.get_function_pc(index) );
527 }
528 }
void type_check(const func_type &ft)
void push_call(activation_frame &&el)
void inc_pc(uint32_t offset=1)
guarded_vector< import_entry > imports
Definition types.hpp:170
uint32_t get_imported_functions_size() const
Definition types.hpp:197
guarded_vector< uint32_t > import_functions
Definition types.hpp:184
opcode * get_function_pc(uint32_t fidx) const
Definition types.hpp:207
guarded_vector< func_type > types
Definition types.hpp:169

◆ call() [2/2]

template<typename Host >
void sysio::vm::execution_context< Host >::call ( uint32_t index)
inline

Definition at line 511 of file execution_context.hpp.

511 {
512 // TODO validate index is valid
513 if (index < _mod.get_imported_functions_size()) {
514 // TODO validate only importing functions
515 const auto& ft = _mod.types[_mod.imports[index].type.func_t];
516 type_check(ft);
517 inc_pc();
518 push_call( activation_frame{ nullptr, 0 } );
519 _rhf(_state.host, get_interface(), _mod.import_functions[index]);
520 pop_call();
521 } else {
522 // const auto& ft = _mod.types[_mod.functions[index - _mod.get_imported_functions_size()]];
523 // type_check(ft);
524 push_call(index);
525 setup_locals(index);
526 set_pc( _mod.get_function_pc(index) );
527 }
528 }

◆ call_depth() [1/2]

template<typename Host >
uint32_t sysio::vm::execution_context< Host >::call_depth ( ) const
inline

Definition at line 552 of file execution_context.hpp.

552{ return _as.size(); }

◆ call_depth() [2/2]

template<typename Host >
uint32_t sysio::vm::execution_context< Host >::call_depth ( ) const
inline

Definition at line 552 of file execution_context.hpp.

552{ return _as.size(); }

◆ compact_operand() [1/2]

template<typename Host >
void sysio::vm::execution_context< Host >::compact_operand ( uint32_t index)
inline

Definition at line 547 of file execution_context.hpp.

547{ get_operand_stack().compact(index); }

◆ compact_operand() [2/2]

template<typename Host >
void sysio::vm::execution_context< Host >::compact_operand ( uint32_t index)
inline

Definition at line 547 of file execution_context.hpp.

547{ get_operand_stack().compact(index); }

◆ current_operands_index() [1/2]

template<typename Host >
uint32_t sysio::vm::execution_context< Host >::current_operands_index ( ) const
inline

Definition at line 549 of file execution_context.hpp.

549{ return get_operand_stack().current_index(); }

◆ current_operands_index() [2/2]

template<typename Host >
uint32_t sysio::vm::execution_context< Host >::current_operands_index ( ) const
inline

Definition at line 549 of file execution_context.hpp.

549{ return get_operand_stack().current_index(); }

◆ eat_operands() [1/2]

template<typename Host >
void sysio::vm::execution_context< Host >::eat_operands ( uint32_t index)
inline

Definition at line 546 of file execution_context.hpp.

546{ get_operand_stack().eat(index); }

◆ eat_operands() [2/2]

template<typename Host >
void sysio::vm::execution_context< Host >::eat_operands ( uint32_t index)
inline

Definition at line 546 of file execution_context.hpp.

546{ get_operand_stack().eat(index); }

◆ execute() [1/4]

template<typename Host >
template<typename Visitor , typename... Args>
std::optional< operand_stack_elem > sysio::vm::execution_context< Host >::execute ( host_type * host,
Visitor && visitor,
const std::string_view func,
Args... args )
inline

Definition at line 672 of file execution_context.hpp.

673 {
675 return execute(host, std::forward<Visitor>(visitor), func_index, std::forward<Args>(args)...);
676 }
std::optional< operand_stack_elem > execute(host_type *host, Visitor &&visitor, const std::string_view func, Args... args)
unsigned int uint32_t
Definition stdint.h:126
uint32_t get_exported_function(const std::string_view str)
Definition types.hpp:227

◆ execute() [2/4]

template<typename Host >
template<typename Visitor , typename... Args>
std::optional< operand_stack_elem > sysio::vm::execution_context< Host >::execute ( host_type * host,
Visitor && visitor,
const std::string_view func,
Args... args )
inline

Definition at line 672 of file execution_context.hpp.

673 {
675 return execute(host, std::forward<Visitor>(visitor), func_index, std::forward<Args>(args)...);
676 }

◆ execute() [3/4]

template<typename Host >
template<typename Visitor , typename... Args>
std::optional< operand_stack_elem > sysio::vm::execution_context< Host >::execute ( host_type * host,
Visitor && visitor,
uint32_t func_index,
Args... args )
inline

Definition at line 685 of file execution_context.hpp.

685 {
686 SYS_VM_ASSERT(func_index < std::numeric_limits<uint32_t>::max(), wasm_interpreter_exception,
687 "cannot execute function, function not found");
688
689 auto last_last_op_index = _last_op_index;
690
691 // save the state of the original calling context
692 execution_state saved_state = _state;
693
694 _state.host = host;
695 _state.as_index = _as.size();
696 _state.os_index = get_operand_stack().size();
697
698 auto cleanup = scope_guard([&]() {
699 get_operand_stack().eat(_state.os_index);
700 _as.eat(_state.as_index);
701 _state = saved_state;
702
703 _last_op_index = last_last_op_index;
704 });
705
706 this->type_check_args(_mod.get_function_type(func_index), static_cast<Args&&>(args)...);
707 push_args(args...);
708 push_call<true>(func_index);
709
710 if (func_index < _mod.get_imported_functions_size()) {
711 _rhf(_state.host, get_interface(), _mod.import_functions[func_index]);
712 } else {
713 _state.pc = _mod.get_function_pc(func_index);
714 setup_locals(func_index);
716 execute(visitor);
717 }, &handle_signal);
718 }
719
720 if (_mod.get_function_type(func_index).return_count && !_state.exiting) {
721 return pop_operand();
722 } else {
723 return {};
724 }
725 }
void eat(uint32_t index)
auto invoke_with_signal_handler(F &&f, E &&e)
Definition signals.hpp:123
schedule config_dir_name data_dir_name p2p_port http_port file_size name host(p2p_endpoint)) FC_REFLECT(tn_node_def
auto & get_function_type(uint32_t index) const
Definition types.hpp:221
#define SYS_VM_ASSERT(expr, exc_type, msg)
Definition exceptions.hpp:8
Here is the call graph for this function:

◆ execute() [4/4]

template<typename Host >
template<typename Visitor , typename... Args>
std::optional< operand_stack_elem > sysio::vm::execution_context< Host >::execute ( host_type * host,
Visitor && visitor,
uint32_t func_index,
Args... args )
inline

Definition at line 685 of file execution_context.hpp.

685 {
686 SYS_VM_ASSERT(func_index < std::numeric_limits<uint32_t>::max(), wasm_interpreter_exception,
687 "cannot execute function, function not found");
688
689 auto last_last_op_index = _last_op_index;
690
691 // save the state of the original calling context
692 execution_state saved_state = _state;
693
694 _state.host = host;
695 _state.as_index = _as.size();
696 _state.os_index = get_operand_stack().size();
697
698 auto cleanup = scope_guard([&]() {
699 get_operand_stack().eat(_state.os_index);
700 _as.eat(_state.as_index);
701 _state = saved_state;
702
703 _last_op_index = last_last_op_index;
704 });
705
706 this->type_check_args(_mod.get_function_type(func_index), static_cast<Args&&>(args)...);
707 push_args(args...);
708 push_call<true>(func_index);
709
710 if (func_index < _mod.get_imported_functions_size()) {
711 _rhf(_state.host, get_interface(), _mod.import_functions[func_index]);
712 } else {
713 _state.pc = _mod.get_function_pc(func_index);
714 setup_locals(func_index);
716 execute(visitor);
717 }, &handle_signal);
718 }
719
720 if (_mod.get_function_type(func_index).return_count && !_state.exiting) {
721 return pop_operand();
722 } else {
723 return {};
724 }
725 }
Here is the call graph for this function:

◆ execute_func_table() [1/2]

template<typename Host >
template<typename Visitor , typename... Args>
std::optional< operand_stack_elem > sysio::vm::execution_context< Host >::execute_func_table ( host_type * host,
Visitor && visitor,
uint32_t table_index,
Args... args )
inline

Definition at line 666 of file execution_context.hpp.

667 {
668 return execute(host, std::forward<Visitor>(visitor), table_elem(table_index), std::forward<Args>(args)...);
669 }

◆ execute_func_table() [2/2]

template<typename Host >
template<typename Visitor , typename... Args>
std::optional< operand_stack_elem > sysio::vm::execution_context< Host >::execute_func_table ( host_type * host,
Visitor && visitor,
uint32_t table_index,
Args... args )
inline

Definition at line 666 of file execution_context.hpp.

667 {
668 return execute(host, std::forward<Visitor>(visitor), table_elem(table_index), std::forward<Args>(args)...);
669 }

◆ execute_start() [1/2]

template<typename Host >
template<typename Visitor , typename... Args>
void sysio::vm::execution_context< Host >::execute_start ( host_type * host,
Visitor && visitor )
inline

Definition at line 679 of file execution_context.hpp.

679 {
680 if (_mod.start != std::numeric_limits<uint32_t>::max())
681 execute(host, std::forward<Visitor>(visitor), _mod.start);
682 }
uint32_t start
Definition types.hpp:168

◆ execute_start() [2/2]

template<typename Host >
template<typename Visitor , typename... Args>
void sysio::vm::execution_context< Host >::execute_start ( host_type * host,
Visitor && visitor )
inline

Definition at line 679 of file execution_context.hpp.

679 {
680 if (_mod.start != std::numeric_limits<uint32_t>::max())
681 execute(host, std::forward<Visitor>(visitor), _mod.start);
682 }

◆ exit() [1/2]

template<typename Host >
void sysio::vm::execution_context< Host >::exit ( std::error_code err = std::error_code())
inline

Definition at line 652 of file execution_context.hpp.

652 {
653 _error_code = err;
654 _state.pc = &_halt;
655 _state.exiting = true;
656 }

◆ exit() [2/2]

template<typename Host >
void sysio::vm::execution_context< Host >::exit ( std::error_code err = std::error_code())
inline

Definition at line 652 of file execution_context.hpp.

652 {
653 _error_code = err;
654 _state.pc = &_halt;
655 _state.exiting = true;
656 }

◆ get_global() [1/2]

template<typename Host >
operand_stack_elem sysio::vm::execution_context< Host >::get_global ( uint32_t index)
inline

Definition at line 574 of file execution_context.hpp.

574 {
575 SYS_VM_ASSERT(index < _mod.globals.size(), wasm_interpreter_exception, "global index out of range");
576 const auto& gl = _mod.globals[index];
577 switch (gl.type.content_type) {
578 case types::i32: return i32_const_t{ *(uint32_t*)&gl.current.value.i32 };
579 case types::i64: return i64_const_t{ *(uint64_t*)&gl.current.value.i64 };
580 case types::f32: return f32_const_t{ gl.current.value.f32 };
581 case types::f64: return f64_const_t{ gl.current.value.f64 };
582 default: throw wasm_interpreter_exception{ "invalid global type" };
583 }
584 }
unsigned __int64 uint64_t
Definition stdint.h:136
guarded_vector< global_variable > globals
Definition types.hpp:174

◆ get_global() [2/2]

template<typename Host >
operand_stack_elem sysio::vm::execution_context< Host >::get_global ( uint32_t index)
inline

Definition at line 574 of file execution_context.hpp.

574 {
575 SYS_VM_ASSERT(index < _mod.globals.size(), wasm_interpreter_exception, "global index out of range");
576 const auto& gl = _mod.globals[index];
577 switch (gl.type.content_type) {
578 case types::i32: return i32_const_t{ *(uint32_t*)&gl.current.value.i32 };
579 case types::i64: return i64_const_t{ *(uint64_t*)&gl.current.value.i64 };
580 case types::f32: return f32_const_t{ gl.current.value.f32 };
581 case types::f64: return f64_const_t{ gl.current.value.f64 };
582 default: throw wasm_interpreter_exception{ "invalid global type" };
583 }
584 }

◆ get_operand() [1/2]

template<typename Host >
operand_stack_elem sysio::vm::execution_context< Host >::get_operand ( uint32_t index) const
inline

Definition at line 545 of file execution_context.hpp.

545{ return get_operand_stack().get(_last_op_index + index); }
Here is the call graph for this function:

◆ get_operand() [2/2]

template<typename Host >
operand_stack_elem sysio::vm::execution_context< Host >::get_operand ( uint32_t index) const
inline

Definition at line 545 of file execution_context.hpp.

545{ return get_operand_stack().get(_last_op_index + index); }
Here is the call graph for this function:

◆ get_pc() [1/2]

template<typename Host >
opcode * sysio::vm::execution_context< Host >::get_pc ( ) const
inline

Definition at line 646 of file execution_context.hpp.

646{ return _state.pc; }

◆ get_pc() [2/2]

template<typename Host >
opcode * sysio::vm::execution_context< Host >::get_pc ( ) const
inline

Definition at line 646 of file execution_context.hpp.

646{ return _state.pc; }

◆ inc_pc() [1/2]

template<typename Host >
void sysio::vm::execution_context< Host >::inc_pc ( uint32_t offset = 1)
inline

Definition at line 651 of file execution_context.hpp.

651{ _state.pc += offset; }

◆ inc_pc() [2/2]

template<typename Host >
void sysio::vm::execution_context< Host >::inc_pc ( uint32_t offset = 1)
inline

Definition at line 651 of file execution_context.hpp.

651{ _state.pc += offset; }

◆ is_true() [1/2]

template<typename Host >
bool sysio::vm::execution_context< Host >::is_true ( const operand_stack_elem & el)
inline

Definition at line 614 of file execution_context.hpp.

614 {
615 bool ret_val = false;
616 visit(overloaded{ [&](const i32_const_t& i32) { ret_val = i32.data.ui; },
617 [&](auto) { throw wasm_invalid_element{ "should be an i32 type" }; } },
618 el);
619 return ret_val;
620 }
overloaded(Ts...) -> overloaded< Ts... >
constexpr auto visit(Visitor &&vis, Variant &&var)
Definition variant.hpp:156
Here is the call graph for this function:

◆ is_true() [2/2]

template<typename Host >
bool sysio::vm::execution_context< Host >::is_true ( const operand_stack_elem & el)
inline

Definition at line 614 of file execution_context.hpp.

614 {
615 bool ret_val = false;
616 visit(overloaded{ [&](const i32_const_t& i32) { ret_val = i32.data.ui; },
617 [&](auto) { throw wasm_invalid_element{ "should be an i32 type" }; } },
618 el);
619 return ret_val;
620 }
Here is the call graph for this function:

◆ jump() [1/2]

template<typename Host >
void sysio::vm::execution_context< Host >::jump ( uint32_t pop_info,
uint32_t new_pc )
inline

Definition at line 727 of file execution_context.hpp.

727 {
728 set_relative_pc(new_pc);
729 if ((pop_info & 0x80000000u)) {
730 const auto& op = pop_operand();
731 eat_operands(get_operand_stack().size() - ((pop_info & 0x7FFFFFFFu) - 1));
733 } else {
734 eat_operands(get_operand_stack().size() - pop_info);
735 }
736 }
void push_operand(operand_stack_elem el)
void set_relative_pc(uint32_t pc_offset)

◆ jump() [2/2]

template<typename Host >
void sysio::vm::execution_context< Host >::jump ( uint32_t pop_info,
uint32_t new_pc )
inline

Definition at line 727 of file execution_context.hpp.

727 {
728 set_relative_pc(new_pc);
729 if ((pop_info & 0x80000000u)) {
730 const auto& op = pop_operand();
731 eat_operands(get_operand_stack().size() - ((pop_info & 0x7FFFFFFFu) - 1));
733 } else {
734 eat_operands(get_operand_stack().size() - pop_info);
735 }
736 }

◆ peek_operand() [1/2]

template<typename Host >
operand_stack_elem & sysio::vm::execution_context< Host >::peek_operand ( size_t i = 0)
inline

Definition at line 573 of file execution_context.hpp.

573{ return get_operand_stack().peek(i); }

◆ peek_operand() [2/2]

template<typename Host >
operand_stack_elem & sysio::vm::execution_context< Host >::peek_operand ( size_t i = 0)
inline

Definition at line 573 of file execution_context.hpp.

573{ return get_operand_stack().peek(i); }

◆ pop_call() [1/2]

template<typename Host >
activation_frame sysio::vm::execution_context< Host >::pop_call ( )
inline

Definition at line 551 of file execution_context.hpp.

551{ return _as.pop(); }

◆ pop_call() [2/2]

template<typename Host >
activation_frame sysio::vm::execution_context< Host >::pop_call ( )
inline

Definition at line 551 of file execution_context.hpp.

551{ return _as.pop(); }

◆ pop_operand() [1/2]

template<typename Host >
operand_stack_elem sysio::vm::execution_context< Host >::pop_operand ( )
inline

Definition at line 572 of file execution_context.hpp.

572{ return get_operand_stack().pop(); }

◆ pop_operand() [2/2]

template<typename Host >
operand_stack_elem sysio::vm::execution_context< Host >::pop_operand ( )
inline

Definition at line 572 of file execution_context.hpp.

572{ return get_operand_stack().pop(); }

◆ print_stack() [1/2]

template<typename Host >
void sysio::vm::execution_context< Host >::print_stack ( )
inline

Definition at line 530 of file execution_context.hpp.

530 {
531 std::cout << "STACK { ";
532 for (int i = 0; i < get_operand_stack().size(); i++) {
533 std::cout << "(" << i << ")";
534 visit(overloaded { [&](i32_const_t el) { std::cout << "i32:" << el.data.ui << ", "; },
535 [&](i64_const_t el) { std::cout << "i64:" << el.data.ui << ", "; },
536 [&](f32_const_t el) { std::cout << "f32:" << el.data.f << ", "; },
537 [&](f64_const_t el) { std::cout << "f64:" << el.data.f << ", "; },
538 [&](auto el) { std::cout << "(INDEX " << el.index() << "), "; } }, get_operand_stack().get(i));
539 }
540 std::cout << " }\n";
541 }
Here is the call graph for this function:

◆ print_stack() [2/2]

template<typename Host >
void sysio::vm::execution_context< Host >::print_stack ( )
inline

Definition at line 530 of file execution_context.hpp.

530 {
531 std::cout << "STACK { ";
532 for (int i = 0; i < get_operand_stack().size(); i++) {
533 std::cout << "(" << i << ")";
534 visit(overloaded { [&](i32_const_t el) { std::cout << "i32:" << el.data.ui << ", "; },
535 [&](i64_const_t el) { std::cout << "i64:" << el.data.ui << ", "; },
536 [&](f32_const_t el) { std::cout << "f32:" << el.data.f << ", "; },
537 [&](f64_const_t el) { std::cout << "f64:" << el.data.f << ", "; },
538 [&](auto el) { std::cout << "(INDEX " << el.index() << "), "; } }, get_operand_stack().get(i));
539 }
540 std::cout << " }\n";
541 }
Here is the call graph for this function:

◆ push_call() [1/4]

template<typename Host >
void sysio::vm::execution_context< Host >::push_call ( activation_frame && el)
inline

Definition at line 550 of file execution_context.hpp.

550{ _as.push(std::move(el)); }
void push(ElemT &&e)

◆ push_call() [2/4]

template<typename Host >
void sysio::vm::execution_context< Host >::push_call ( activation_frame && el)
inline

Definition at line 550 of file execution_context.hpp.

550{ _as.push(std::move(el)); }

◆ push_call() [3/4]

template<typename Host >
template<bool Should_Exit = false>
void sysio::vm::execution_context< Host >::push_call ( uint32_t index)
inline

Definition at line 554 of file execution_context.hpp.

554 {
555 opcode* return_pc = static_cast<opcode*>(&_halt);
556 if constexpr (!Should_Exit)
557 return_pc = _state.pc + 1;
558
559 _as.push( activation_frame{ return_pc, _last_op_index } );
560 _last_op_index = get_operand_stack().size() - _mod.get_function_type(index).param_types.size();
561 }
variant< > opcode
Definition opcodes.hpp:79

◆ push_call() [4/4]

template<typename Host >
template<bool Should_Exit = false>
void sysio::vm::execution_context< Host >::push_call ( uint32_t index)
inline

Definition at line 554 of file execution_context.hpp.

554 {
555 opcode* return_pc = static_cast<opcode*>(&_halt);
556 if constexpr (!Should_Exit)
557 return_pc = _state.pc + 1;
558
559 _as.push( activation_frame{ return_pc, _last_op_index } );
560 _last_op_index = get_operand_stack().size() - _mod.get_function_type(index).param_types.size();
561 }

◆ push_operand() [1/2]

template<typename Host >
void sysio::vm::execution_context< Host >::push_operand ( operand_stack_elem el)
inline

Definition at line 544 of file execution_context.hpp.

544{ get_operand_stack().push(std::move(el)); }

◆ push_operand() [2/2]

template<typename Host >
void sysio::vm::execution_context< Host >::push_operand ( operand_stack_elem el)
inline

Definition at line 544 of file execution_context.hpp.

544{ get_operand_stack().push(std::move(el)); }

◆ reset() [1/2]

template<typename Host >
void sysio::vm::execution_context< Host >::reset ( )
inline

Definition at line 658 of file execution_context.hpp.

658 {
660 _state = execution_state{};
661 get_operand_stack().eat(_state.os_index);
662 _as.eat(_state.as_index);
663 }

◆ reset() [2/2]

template<typename Host >
void sysio::vm::execution_context< Host >::reset ( )
inline

Definition at line 658 of file execution_context.hpp.

658 {
660 _state = execution_state{};
661 get_operand_stack().eat(_state.os_index);
662 _as.eat(_state.as_index);
663 }

◆ set_global() [1/2]

template<typename Host >
void sysio::vm::execution_context< Host >::set_global ( uint32_t index,
const operand_stack_elem & el )
inline

Definition at line 586 of file execution_context.hpp.

586 {
587 SYS_VM_ASSERT(index < _mod.globals.size(), wasm_interpreter_exception, "global index out of range");
588 auto& gl = _mod.globals[index];
589 SYS_VM_ASSERT(gl.type.mutability, wasm_interpreter_exception, "global is not mutable");
590 visit(overloaded{ [&](const i32_const_t& i) {
591 SYS_VM_ASSERT(gl.type.content_type == types::i32, wasm_interpreter_exception,
592 "expected i32 global type");
593 gl.current.value.i32 = i.data.ui;
594 },
595 [&](const i64_const_t& i) {
596 SYS_VM_ASSERT(gl.type.content_type == types::i64, wasm_interpreter_exception,
597 "expected i64 global type");
598 gl.current.value.i64 = i.data.ui;
599 },
600 [&](const f32_const_t& f) {
601 SYS_VM_ASSERT(gl.type.content_type == types::f32, wasm_interpreter_exception,
602 "expected f32 global type");
603 gl.current.value.f32 = f.data.ui;
604 },
605 [&](const f64_const_t& f) {
606 SYS_VM_ASSERT(gl.type.content_type == types::f64, wasm_interpreter_exception,
607 "expected f64 global type");
608 gl.current.value.f64 = f.data.ui;
609 },
610 [](auto) { throw wasm_interpreter_exception{ "invalid global type" }; } },
611 el);
612 }
Here is the call graph for this function:

◆ set_global() [2/2]

template<typename Host >
void sysio::vm::execution_context< Host >::set_global ( uint32_t index,
const operand_stack_elem & el )
inline

Definition at line 586 of file execution_context.hpp.

586 {
587 SYS_VM_ASSERT(index < _mod.globals.size(), wasm_interpreter_exception, "global index out of range");
588 auto& gl = _mod.globals[index];
589 SYS_VM_ASSERT(gl.type.mutability, wasm_interpreter_exception, "global is not mutable");
590 visit(overloaded{ [&](const i32_const_t& i) {
591 SYS_VM_ASSERT(gl.type.content_type == types::i32, wasm_interpreter_exception,
592 "expected i32 global type");
593 gl.current.value.i32 = i.data.ui;
594 },
595 [&](const i64_const_t& i) {
596 SYS_VM_ASSERT(gl.type.content_type == types::i64, wasm_interpreter_exception,
597 "expected i64 global type");
598 gl.current.value.i64 = i.data.ui;
599 },
600 [&](const f32_const_t& f) {
601 SYS_VM_ASSERT(gl.type.content_type == types::f32, wasm_interpreter_exception,
602 "expected f32 global type");
603 gl.current.value.f32 = f.data.ui;
604 },
605 [&](const f64_const_t& f) {
606 SYS_VM_ASSERT(gl.type.content_type == types::f64, wasm_interpreter_exception,
607 "expected f64 global type");
608 gl.current.value.f64 = f.data.ui;
609 },
610 [](auto) { throw wasm_interpreter_exception{ "invalid global type" }; } },
611 el);
612 }
Here is the call graph for this function:

◆ set_max_call_depth() [1/2]

template<typename Host >
void sysio::vm::execution_context< Host >::set_max_call_depth ( uint32_t max_call_depth)
inline

Definition at line 499 of file execution_context.hpp.

499 {
500 static_assert(std::is_trivially_move_assignable_v<call_stack>, "This is seriously broken if call_stack move assignment might use the existing memory");
501 std::size_t mem_size = max_call_depth*sizeof(activation_frame);
502 if(mem_size > _base_allocator.mem_size) {
503 _base_allocator = bounded_allocator{mem_size};
504 _as = call_stack{max_call_depth, _base_allocator};
505 } else if (max_call_depth != _as.capacity()){
506 _base_allocator.index = 0;
507 _as = call_stack{max_call_depth, _base_allocator};
508 }
509 }
size_t capacity() const
stack< activation_frame, constants::max_call_depth+1, bounded_allocator > call_stack

◆ set_max_call_depth() [2/2]

template<typename Host >
void sysio::vm::execution_context< Host >::set_max_call_depth ( uint32_t max_call_depth)
inline

Definition at line 499 of file execution_context.hpp.

499 {
500 static_assert(std::is_trivially_move_assignable_v<call_stack>, "This is seriously broken if call_stack move assignment might use the existing memory");
501 std::size_t mem_size = max_call_depth*sizeof(activation_frame);
502 if(mem_size > _base_allocator.mem_size) {
503 _base_allocator = bounded_allocator{mem_size};
504 _as = call_stack{max_call_depth, _base_allocator};
505 } else if (max_call_depth != _as.capacity()){
506 _base_allocator.index = 0;
507 _as = call_stack{max_call_depth, _base_allocator};
508 }
509 }

◆ set_operand() [1/2]

template<typename Host >
void sysio::vm::execution_context< Host >::set_operand ( uint32_t index,
const operand_stack_elem & el )
inline

Definition at line 548 of file execution_context.hpp.

548{ get_operand_stack().set(_last_op_index + index, el); }

◆ set_operand() [2/2]

template<typename Host >
void sysio::vm::execution_context< Host >::set_operand ( uint32_t index,
const operand_stack_elem & el )
inline

Definition at line 548 of file execution_context.hpp.

548{ get_operand_stack().set(_last_op_index + index, el); }

◆ set_pc() [1/2]

template<typename Host >
void sysio::vm::execution_context< Host >::set_pc ( opcode * pc)
inline

Definition at line 650 of file execution_context.hpp.

650{ _state.pc = pc; }

◆ set_pc() [2/2]

template<typename Host >
void sysio::vm::execution_context< Host >::set_pc ( opcode * pc)
inline

Definition at line 650 of file execution_context.hpp.

650{ _state.pc = pc; }

◆ set_relative_pc() [1/2]

template<typename Host >
void sysio::vm::execution_context< Host >::set_relative_pc ( uint32_t pc_offset)
inline

Definition at line 647 of file execution_context.hpp.

647 {
648 _state.pc = _mod.code[0].code + pc_offset;
649 }
guarded_vector< function_body > code
Definition types.hpp:177

◆ set_relative_pc() [2/2]

template<typename Host >
void sysio::vm::execution_context< Host >::set_relative_pc ( uint32_t pc_offset)
inline

Definition at line 647 of file execution_context.hpp.

647 {
648 _state.pc = _mod.code[0].code + pc_offset;
649 }

◆ table_elem() [1/2]

template<typename Host >
uint32_t sysio::vm::execution_context< Host >::table_elem ( uint32_t i)
inline

Definition at line 543 of file execution_context.hpp.

543{ return _mod.tables[0].table[i]; }
guarded_vector< table_type > tables
Definition types.hpp:172

◆ table_elem() [2/2]

template<typename Host >
uint32_t sysio::vm::execution_context< Host >::table_elem ( uint32_t i)
inline

Definition at line 543 of file execution_context.hpp.

543{ return _mod.tables[0].table[i]; }

◆ type_check() [1/2]

template<typename Host >
void sysio::vm::execution_context< Host >::type_check ( const func_type & ft)
inline

Definition at line 622 of file execution_context.hpp.

622 {
623 for (uint32_t i = 0; i < ft.param_types.size(); i++) {
624 const auto& op = peek_operand((ft.param_types.size() - 1) - i);
625 visit(overloaded{ [&](const i32_const_t&) {
626 SYS_VM_ASSERT(ft.param_types[i] == types::i32, wasm_interpreter_exception,
627 "function param type mismatch");
628 },
629 [&](const f32_const_t&) {
630 SYS_VM_ASSERT(ft.param_types[i] == types::f32, wasm_interpreter_exception,
631 "function param type mismatch");
632 },
633 [&](const i64_const_t&) {
634 SYS_VM_ASSERT(ft.param_types[i] == types::i64, wasm_interpreter_exception,
635 "function param type mismatch");
636 },
637 [&](const f64_const_t&) {
638 SYS_VM_ASSERT(ft.param_types[i] == types::f64, wasm_interpreter_exception,
639 "function param type mismatch");
640 },
641 [&](auto) { throw wasm_interpreter_exception{ "function param invalid type" }; } },
642 op);
643 }
644 }
operand_stack_elem & peek_operand(size_t i=0)
Here is the call graph for this function:

◆ type_check() [2/2]

template<typename Host >
void sysio::vm::execution_context< Host >::type_check ( const func_type & ft)
inline

Definition at line 622 of file execution_context.hpp.

622 {
623 for (uint32_t i = 0; i < ft.param_types.size(); i++) {
624 const auto& op = peek_operand((ft.param_types.size() - 1) - i);
625 visit(overloaded{ [&](const i32_const_t&) {
626 SYS_VM_ASSERT(ft.param_types[i] == types::i32, wasm_interpreter_exception,
627 "function param type mismatch");
628 },
629 [&](const f32_const_t&) {
630 SYS_VM_ASSERT(ft.param_types[i] == types::f32, wasm_interpreter_exception,
631 "function param type mismatch");
632 },
633 [&](const i64_const_t&) {
634 SYS_VM_ASSERT(ft.param_types[i] == types::i64, wasm_interpreter_exception,
635 "function param type mismatch");
636 },
637 [&](const f64_const_t&) {
638 SYS_VM_ASSERT(ft.param_types[i] == types::f64, wasm_interpreter_exception,
639 "function param type mismatch");
640 },
641 [&](auto) { throw wasm_interpreter_exception{ "function param invalid type" }; } },
642 op);
643 }
644 }
Here is the call graph for this function:

The documentation for this class was generated from the following files: