2021-06-04 21:54:20 +10:00
/*
* Copyright ( c ) 2021 , Ali Mohammad Pur < mpfard @ serenityos . org >
2023-01-28 14:56:18 +00:00
* Copyright ( c ) 2023 , Sam Atkins < atkinssj @ serenityos . org >
2021-06-04 21:54:20 +10:00
*
* SPDX - License - Identifier : BSD - 2 - Clause
*/
2023-06-12 13:38:22 +03:30
# include <AK/ByteReader.h>
2021-06-04 21:54:20 +10:00
# include <AK/Debug.h>
2023-02-09 03:11:50 +01:00
# include <AK/Endian.h>
2023-01-25 20:19:05 +01:00
# include <AK/MemoryStream.h>
2024-06-15 11:13:15 -07:00
# include <AK/NumericLimits.h>
2023-06-12 13:38:22 +03:30
# include <AK/SIMDExtras.h>
2021-06-04 21:54:20 +10:00
# include <LibWasm/AbstractMachine/AbstractMachine.h>
# include <LibWasm/AbstractMachine/BytecodeInterpreter.h>
# include <LibWasm/AbstractMachine/Configuration.h>
2021-08-09 02:55:01 +04:30
# include <LibWasm/AbstractMachine/Operators.h>
2021-06-04 21:54:20 +10:00
# include <LibWasm/Opcode.h>
# include <LibWasm/Printer/Printer.h>
2023-06-12 13:38:22 +03:30
using namespace AK : : SIMD ;
2021-06-04 21:54:20 +10:00
namespace Wasm {
2025-05-21 16:15:34 +02:00
# define TRAP_IF_NOT(x, ...) \
2021-06-04 21:54:20 +10:00
do { \
2025-05-21 16:15:34 +02:00
if ( trap_if_not ( x , # x # # sv __VA_OPT__ ( , ) __VA_ARGS__ ) ) { \
2021-06-04 21:54:20 +10:00
dbgln_if ( WASM_TRACE_DEBUG , " Trapped because {} failed, at line {} " , # x , __LINE__ ) ; \
return ; \
} \
} while ( false )
void BytecodeInterpreter : : interpret ( Configuration & configuration )
{
2023-02-25 11:15:11 +03:30
m_trap = Empty { } ;
2021-06-04 21:54:20 +10:00
auto & instructions = configuration . frame ( ) . expression ( ) . instructions ( ) ;
auto max_ip_value = InstructionPointer { instructions . size ( ) } ;
auto & current_ip_value = configuration . ip ( ) ;
2021-07-15 00:00:45 +04:30
auto const should_limit_instruction_count = configuration . should_limit_instruction_count ( ) ;
2021-06-21 21:03:08 +04:30
u64 executed_instructions = 0 ;
2021-06-04 21:54:20 +10:00
while ( current_ip_value < max_ip_value ) {
2021-07-15 00:00:45 +04:30
if ( should_limit_instruction_count ) {
if ( executed_instructions + + > = Constants : : max_allowed_executed_instructions_per_call ) [[unlikely]] {
2025-04-22 09:48:26 +02:00
m_trap = Trap : : from_string ( " Exceeded maximum allowed number of instructions " ) ;
2021-07-15 00:00:45 +04:30
return ;
}
2021-06-21 21:03:08 +04:30
}
2021-06-04 21:54:20 +10:00
auto & instruction = instructions [ current_ip_value . value ( ) ] ;
auto old_ip = current_ip_value ;
2024-08-02 20:58:15 -07:00
interpret_instruction ( configuration , current_ip_value , instruction ) ;
2023-02-25 11:15:11 +03:30
if ( did_trap ( ) )
2021-06-04 21:54:20 +10:00
return ;
if ( current_ip_value = = old_ip ) // If no jump occurred
+ + current_ip_value ;
}
}
void BytecodeInterpreter : : branch_to_label ( Configuration & configuration , LabelIndex index )
{
dbgln_if ( WASM_TRACE_DEBUG , " Branch to label with index {}... " , index . value ( ) ) ;
2024-08-02 20:51:40 -07:00
for ( size_t i = 0 ; i < index . value ( ) ; + + i )
configuration . label_stack ( ) . take_last ( ) ;
auto label = configuration . label_stack ( ) . last ( ) ;
dbgln_if ( WASM_TRACE_DEBUG , " ...which is actually IP {}, and has {} result(s) " , label . continuation ( ) . value ( ) , label . arity ( ) ) ;
2021-06-04 21:54:20 +10:00
2024-08-02 21:12:20 -07:00
configuration . value_stack ( ) . remove ( label . stack_height ( ) , configuration . value_stack ( ) . size ( ) - label . stack_height ( ) - label . arity ( ) ) ;
2024-08-02 20:51:40 -07:00
configuration . ip ( ) = label . continuation ( ) ;
2021-06-04 21:54:20 +10:00
}
template < typename ReadType , typename PushType >
void BytecodeInterpreter : : load_and_push ( Configuration & configuration , Instruction const & instruction )
{
2023-10-23 00:19:28 +03:30
auto & arg = instruction . arguments ( ) . get < Instruction : : MemoryArgument > ( ) ;
auto & address = configuration . frame ( ) . module ( ) . memories ( ) [ arg . memory_index . value ( ) ] ;
2021-06-04 21:54:20 +10:00
auto memory = configuration . store ( ) . get ( address ) ;
2024-08-02 20:51:40 -07:00
auto & entry = configuration . value_stack ( ) . last ( ) ;
2024-08-04 08:06:50 -07:00
auto base = entry . to < i32 > ( ) ;
2024-07-18 13:29:17 -07:00
u64 instance_address = static_cast < u64 > ( bit_cast < u32 > ( base ) ) + arg . offset ;
if ( instance_address + sizeof ( ReadType ) > memory - > size ( ) ) {
2025-04-22 09:48:26 +02:00
m_trap = Trap : : from_string ( " Memory access out of bounds " ) ;
2025-05-21 16:22:12 +02:00
dbgln_if ( WASM_TRACE_DEBUG , " LibWasm: Memory access out of bounds (expected {} to be less than or equal to {}) " , instance_address + sizeof ( ReadType ) , memory - > size ( ) ) ;
2021-06-04 21:54:20 +10:00
return ;
}
dbgln_if ( WASM_TRACE_DEBUG , " load({} : {}) -> stack " , instance_address , sizeof ( ReadType ) ) ;
auto slice = memory - > data ( ) . bytes ( ) . slice ( instance_address , sizeof ( ReadType ) ) ;
2024-08-02 20:51:40 -07:00
entry = Value ( static_cast < PushType > ( read_value < ReadType > ( slice ) ) ) ;
2021-06-04 21:54:20 +10:00
}
2023-06-12 13:38:22 +03:30
template < typename TDst , typename TSrc >
ALWAYS_INLINE static TDst convert_vector ( TSrc v )
{
return __builtin_convertvector ( v , TDst ) ;
}
template < size_t M , size_t N , template < typename > typename SetSign >
void BytecodeInterpreter : : load_and_push_mxn ( Configuration & configuration , Instruction const & instruction )
{
2023-10-23 00:19:28 +03:30
auto & arg = instruction . arguments ( ) . get < Instruction : : MemoryArgument > ( ) ;
auto & address = configuration . frame ( ) . module ( ) . memories ( ) [ arg . memory_index . value ( ) ] ;
2023-06-12 13:38:22 +03:30
auto memory = configuration . store ( ) . get ( address ) ;
2024-08-02 20:51:40 -07:00
auto & entry = configuration . value_stack ( ) . last ( ) ;
2024-08-04 08:06:50 -07:00
auto base = entry . to < i32 > ( ) ;
2024-07-18 13:29:17 -07:00
u64 instance_address = static_cast < u64 > ( bit_cast < u32 > ( base ) ) + arg . offset ;
if ( instance_address + M * N / 8 > memory - > size ( ) ) {
2025-04-22 09:48:26 +02:00
m_trap = Trap : : from_string ( " Memory access out of bounds " ) ;
2025-05-21 16:22:12 +02:00
dbgln_if ( WASM_TRACE_DEBUG , " LibWasm: Memory access out of bounds (expected {} to be less than or equal to {}) " , instance_address + M * N / 8 , memory - > size ( ) ) ;
2023-06-12 13:38:22 +03:30
return ;
}
dbgln_if ( WASM_TRACE_DEBUG , " vec-load({} : {}) -> stack " , instance_address , M * N / 8 ) ;
auto slice = memory - > data ( ) . bytes ( ) . slice ( instance_address , M * N / 8 ) ;
using V64 = NativeVectorType < M , N , SetSign > ;
using V128 = NativeVectorType < M * 2 , N , SetSign > ;
V64 bytes { 0 } ;
if ( bit_cast < FlatPtr > ( slice . data ( ) ) % sizeof ( V64 ) = = 0 )
bytes = * bit_cast < V64 * > ( slice . data ( ) ) ;
else
ByteReader : : load ( slice . data ( ) , bytes ) ;
2024-08-02 20:51:40 -07:00
entry = Value ( bit_cast < u128 > ( convert_vector < V128 > ( bytes ) ) ) ;
2023-06-12 13:38:22 +03:30
}
2024-07-14 21:09:09 -07:00
template < size_t N >
void BytecodeInterpreter : : load_and_push_lane_n ( Configuration & configuration , Instruction const & instruction )
{
auto memarg_and_lane = instruction . arguments ( ) . get < Instruction : : MemoryAndLaneArgument > ( ) ;
auto & address = configuration . frame ( ) . module ( ) . memories ( ) [ memarg_and_lane . memory . memory_index . value ( ) ] ;
auto memory = configuration . store ( ) . get ( address ) ;
2024-08-04 08:06:50 -07:00
auto vector = configuration . value_stack ( ) . take_last ( ) . to < u128 > ( ) ;
auto base = configuration . value_stack ( ) . take_last ( ) . to < u32 > ( ) ;
2024-07-14 21:09:09 -07:00
u64 instance_address = static_cast < u64 > ( bit_cast < u32 > ( base ) ) + memarg_and_lane . memory . offset ;
2024-07-18 13:29:17 -07:00
if ( instance_address + N / 8 > memory - > size ( ) ) {
2025-04-22 09:48:26 +02:00
m_trap = Trap : : from_string ( " Memory access out of bounds " ) ;
2024-07-14 21:09:09 -07:00
return ;
}
auto slice = memory - > data ( ) . bytes ( ) . slice ( instance_address , N / 8 ) ;
auto dst = bit_cast < u8 * > ( & vector ) + memarg_and_lane . lane * N / 8 ;
memcpy ( dst , slice . data ( ) , N / 8 ) ;
2024-08-02 20:51:40 -07:00
configuration . value_stack ( ) . append ( Value ( vector ) ) ;
2024-07-14 21:09:09 -07:00
}
template < size_t N >
void BytecodeInterpreter : : load_and_push_zero_n ( Configuration & configuration , Instruction const & instruction )
{
auto memarg_and_lane = instruction . arguments ( ) . get < Instruction : : MemoryArgument > ( ) ;
auto & address = configuration . frame ( ) . module ( ) . memories ( ) [ memarg_and_lane . memory_index . value ( ) ] ;
auto memory = configuration . store ( ) . get ( address ) ;
2024-08-04 08:06:50 -07:00
auto base = configuration . value_stack ( ) . take_last ( ) . to < u32 > ( ) ;
2024-07-14 21:09:09 -07:00
u64 instance_address = static_cast < u64 > ( bit_cast < u32 > ( base ) ) + memarg_and_lane . offset ;
2024-07-18 13:29:17 -07:00
if ( instance_address + N / 8 > memory - > size ( ) ) {
2025-04-22 09:48:26 +02:00
m_trap = Trap : : from_string ( " Memory access out of bounds " ) ;
2024-07-14 21:09:09 -07:00
return ;
}
auto slice = memory - > data ( ) . bytes ( ) . slice ( instance_address , N / 8 ) ;
u128 vector = 0 ;
memcpy ( & vector , slice . data ( ) , N / 8 ) ;
2024-08-02 20:51:40 -07:00
configuration . value_stack ( ) . append ( Value ( vector ) ) ;
2024-07-14 21:09:09 -07:00
}
2023-06-12 13:38:22 +03:30
template < size_t M >
void BytecodeInterpreter : : load_and_push_m_splat ( Configuration & configuration , Instruction const & instruction )
{
2023-10-23 00:19:28 +03:30
auto & arg = instruction . arguments ( ) . get < Instruction : : MemoryArgument > ( ) ;
auto & address = configuration . frame ( ) . module ( ) . memories ( ) [ arg . memory_index . value ( ) ] ;
2023-06-12 13:38:22 +03:30
auto memory = configuration . store ( ) . get ( address ) ;
2024-08-02 20:51:40 -07:00
auto & entry = configuration . value_stack ( ) . last ( ) ;
2024-08-04 08:06:50 -07:00
auto base = entry . to < i32 > ( ) ;
2024-07-18 13:29:17 -07:00
u64 instance_address = static_cast < u64 > ( bit_cast < u32 > ( base ) ) + arg . offset ;
if ( instance_address + M / 8 > memory - > size ( ) ) {
2025-04-22 09:48:26 +02:00
m_trap = Trap : : from_string ( " Memory access out of bounds " ) ;
2025-05-21 16:22:12 +02:00
dbgln_if ( WASM_TRACE_DEBUG , " LibWasm: Memory access out of bounds (expected {} to be less than or equal to {}) " , instance_address + M / 8 , memory - > size ( ) ) ;
2023-06-12 13:38:22 +03:30
return ;
}
dbgln_if ( WASM_TRACE_DEBUG , " vec-splat({} : {}) -> stack " , instance_address , M / 8 ) ;
auto slice = memory - > data ( ) . bytes ( ) . slice ( instance_address , M / 8 ) ;
auto value = read_value < NativeIntegralType < M > > ( slice ) ;
set_top_m_splat < M , NativeIntegralType > ( configuration , value ) ;
}
template < size_t M , template < size_t > typename NativeType >
void BytecodeInterpreter : : set_top_m_splat ( Wasm : : Configuration & configuration , NativeType < M > value )
{
auto push = [ & ] ( auto result ) {
2024-08-02 20:51:40 -07:00
configuration . value_stack ( ) . last ( ) = Value ( bit_cast < u128 > ( result ) ) ;
2023-06-12 13:38:22 +03:30
} ;
if constexpr ( IsFloatingPoint < NativeType < 32 > > ) {
if constexpr ( M = = 32 ) // 32 -> 32x4
push ( expand4 ( value ) ) ;
else if constexpr ( M = = 64 ) // 64 -> 64x2
push ( f64x2 { value , value } ) ;
else
static_assert ( DependentFalse < NativeType < M > > , " Invalid vector size " ) ;
} else {
if constexpr ( M = = 8 ) // 8 -> 8x4 -> 32x4
push ( expand4 ( bit_cast < u32 > ( u8x4 { value , value , value , value } ) ) ) ;
else if constexpr ( M = = 16 ) // 16 -> 16x2 -> 32x4
push ( expand4 ( bit_cast < u32 > ( u16x2 { value , value } ) ) ) ;
else if constexpr ( M = = 32 ) // 32 -> 32x4
push ( expand4 ( value ) ) ;
else if constexpr ( M = = 64 ) // 64 -> 64x2
push ( u64x2 { value , value } ) ;
else
static_assert ( DependentFalse < NativeType < M > > , " Invalid vector size " ) ;
}
}
template < size_t M , template < size_t > typename NativeType >
void BytecodeInterpreter : : pop_and_push_m_splat ( Wasm : : Configuration & configuration , Instruction const & )
{
using PopT = Conditional < M < = 32 , NativeType < 32 > , NativeType < 64 > > ;
using ReadT = NativeType < M > ;
2024-08-02 20:51:40 -07:00
auto entry = configuration . value_stack ( ) . last ( ) ;
2024-08-04 08:06:50 -07:00
auto value = static_cast < ReadT > ( entry . to < PopT > ( ) ) ;
2023-06-12 13:38:22 +03:30
dbgln_if ( WASM_TRACE_DEBUG , " stack({}) -> splat({}) " , value , M ) ;
set_top_m_splat < M , NativeType > ( configuration , value ) ;
}
template < typename M , template < typename > typename SetSign , typename VectorType >
2024-07-23 10:16:32 -07:00
VectorType BytecodeInterpreter : : pop_vector ( Configuration & configuration )
2023-06-12 13:38:22 +03:30
{
2024-08-04 08:06:50 -07:00
return bit_cast < VectorType > ( configuration . value_stack ( ) . take_last ( ) . to < u128 > ( ) ) ;
2023-06-12 13:38:22 +03:30
}
2025-05-21 16:16:28 +02:00
void BytecodeInterpreter : : call_address ( Configuration & configuration , FunctionAddress address , CallAddressSource source )
2021-06-04 21:54:20 +10:00
{
2025-05-21 16:15:34 +02:00
TRAP_IF_NOT ( m_stack_info . size_free ( ) > = Constants : : minimum_stack_space_to_keep_free , " {}: {} " , Constants : : stack_exhaustion_message ) ;
2021-06-21 21:03:08 +04:30
2021-06-04 21:54:20 +10:00
auto instance = configuration . store ( ) . get ( address ) ;
FunctionType const * type { nullptr } ;
instance - > visit ( [ & ] ( auto const & function ) { type = & function . type ( ) ; } ) ;
2025-05-21 16:16:28 +02:00
if ( source = = CallAddressSource : : IndirectCall ) {
TRAP_IF_NOT ( type - > parameters ( ) . size ( ) < = configuration . value_stack ( ) . size ( ) ) ;
}
2021-06-04 21:54:20 +10:00
Vector < Value > args ;
args . ensure_capacity ( type - > parameters ( ) . size ( ) ) ;
2024-08-02 20:51:40 -07:00
auto span = configuration . value_stack ( ) . span ( ) . slice_from_end ( type - > parameters ( ) . size ( ) ) ;
for ( auto & value : span )
args . unchecked_append ( value ) ;
2021-06-04 21:54:20 +10:00
2024-08-02 20:51:40 -07:00
configuration . value_stack ( ) . remove ( configuration . value_stack ( ) . size ( ) - span . size ( ) , span . size ( ) ) ;
2021-06-04 21:54:20 +10:00
2025-04-22 09:48:26 +02:00
Result result { Trap : : from_string ( " " ) } ;
2024-08-02 20:51:40 -07:00
if ( instance - > has < WasmFunction > ( ) ) {
2021-06-04 21:54:20 +10:00
CallFrameHandle handle { * this , configuration } ;
result = configuration . call ( * this , address , move ( args ) ) ;
2024-08-02 20:51:40 -07:00
} else {
result = configuration . call ( * this , address , move ( args ) ) ;
2021-06-04 21:54:20 +10:00
}
if ( result . is_trap ( ) ) {
2021-07-01 17:03:17 +04:30
m_trap = move ( result . trap ( ) ) ;
2021-06-04 21:54:20 +10:00
return ;
}
2024-08-02 20:51:40 -07:00
configuration . value_stack ( ) . ensure_capacity ( configuration . value_stack ( ) . size ( ) + result . values ( ) . size ( ) ) ;
2022-04-22 11:02:41 +04:30
for ( auto & entry : result . values ( ) . in_reverse ( ) )
2024-08-02 20:51:40 -07:00
configuration . value_stack ( ) . unchecked_append ( entry ) ;
2021-06-04 21:54:20 +10:00
}
2024-02-07 17:31:38 +03:30
template < typename PopTypeLHS , typename PushType , typename Operator , typename PopTypeRHS , typename . . . Args >
void BytecodeInterpreter : : binary_numeric_operation ( Configuration & configuration , Args & & . . . args )
2021-08-09 02:55:01 +04:30
{
2024-08-02 20:51:40 -07:00
auto rhs = configuration . value_stack ( ) . take_last ( ) . to < PopTypeRHS > ( ) ;
auto & lhs_entry = configuration . value_stack ( ) . last ( ) ;
auto lhs = lhs_entry . to < PopTypeLHS > ( ) ;
2021-08-09 02:55:01 +04:30
PushType result ;
2024-08-04 08:06:50 -07:00
auto call_result = Operator { forward < Args > ( args ) . . . } ( lhs , rhs ) ;
2024-03-11 22:57:59 +01:00
if constexpr ( IsSpecializationOf < decltype ( call_result ) , AK : : ErrorOr > ) {
2021-08-09 02:55:01 +04:30
if ( call_result . is_error ( ) ) {
trap_if_not ( false , call_result . error ( ) ) ;
return ;
}
result = call_result . release_value ( ) ;
} else {
result = call_result ;
}
2025-05-19 02:45:19 +01:00
dbgln_if ( WASM_TRACE_DEBUG , " {} {} {} = {} " , lhs , Operator : : name ( ) , rhs , result ) ;
2021-08-12 00:59:00 +04:30
lhs_entry = Value ( result ) ;
2021-08-09 02:55:01 +04:30
}
2021-06-04 21:54:20 +10:00
2024-02-07 17:31:38 +03:30
template < typename PopType , typename PushType , typename Operator , typename . . . Args >
void BytecodeInterpreter : : unary_operation ( Configuration & configuration , Args & & . . . args )
2021-08-09 02:55:01 +04:30
{
2024-08-02 20:51:40 -07:00
auto & entry = configuration . value_stack ( ) . last ( ) ;
auto value = entry . to < PopType > ( ) ;
2024-08-04 08:06:50 -07:00
auto call_result = Operator { forward < Args > ( args ) . . . } ( value ) ;
2021-08-09 02:55:01 +04:30
PushType result ;
2024-03-11 22:57:59 +01:00
if constexpr ( IsSpecializationOf < decltype ( call_result ) , AK : : ErrorOr > ) {
2021-08-09 02:55:01 +04:30
if ( call_result . is_error ( ) ) {
trap_if_not ( false , call_result . error ( ) ) ;
return ;
}
result = call_result . release_value ( ) ;
} else {
result = call_result ;
}
2025-05-19 02:45:19 +01:00
dbgln_if ( WASM_TRACE_DEBUG , " map({}) {} = {} " , Operator : : name ( ) , value , result ) ;
2021-08-12 00:59:00 +04:30
entry = Value ( result ) ;
2021-08-09 02:55:01 +04:30
}
2021-06-04 21:54:20 +10:00
2021-08-11 22:16:05 +04:30
template < typename T >
struct ConvertToRaw {
T operator ( ) ( T value )
{
return LittleEndian < T > ( value ) ;
}
} ;
template < >
struct ConvertToRaw < float > {
u32 operator ( ) ( float value )
{
ReadonlyBytes bytes { & value , sizeof ( float ) } ;
2023-01-30 11:05:43 +01:00
FixedMemoryStream stream { bytes } ;
2023-04-12 12:05:06 +02:00
auto res = stream . read_value < LittleEndian < u32 > > ( ) . release_value_but_fixme_should_propagate_errors ( ) ;
2021-08-11 22:16:05 +04:30
return static_cast < u32 > ( res ) ;
}
} ;
template < >
struct ConvertToRaw < double > {
u64 operator ( ) ( double value )
{
ReadonlyBytes bytes { & value , sizeof ( double ) } ;
2023-01-30 11:05:43 +01:00
FixedMemoryStream stream { bytes } ;
2023-04-12 12:05:06 +02:00
auto res = stream . read_value < LittleEndian < u64 > > ( ) . release_value_but_fixme_should_propagate_errors ( ) ;
2021-08-11 22:16:05 +04:30
return static_cast < u64 > ( res ) ;
}
} ;
template < typename PopT , typename StoreT >
void BytecodeInterpreter : : pop_and_store ( Configuration & configuration , Instruction const & instruction )
{
2024-07-18 13:29:17 -07:00
auto & memarg = instruction . arguments ( ) . get < Instruction : : MemoryArgument > ( ) ;
2024-08-02 20:51:40 -07:00
auto entry = configuration . value_stack ( ) . take_last ( ) ;
2024-08-04 08:06:50 -07:00
auto value = ConvertToRaw < StoreT > { } ( entry . to < PopT > ( ) ) ;
2021-08-11 22:16:05 +04:30
dbgln_if ( WASM_TRACE_DEBUG , " stack({}) -> temporary({}b) " , value , sizeof ( StoreT ) ) ;
2024-08-02 20:51:40 -07:00
auto base = configuration . value_stack ( ) . take_last ( ) . to < i32 > ( ) ;
2024-08-04 08:06:50 -07:00
store_to_memory ( configuration , memarg , { & value , sizeof ( StoreT ) } , base ) ;
2021-08-11 22:16:05 +04:30
}
2024-07-14 21:09:09 -07:00
template < size_t N >
void BytecodeInterpreter : : pop_and_store_lane_n ( Configuration & configuration , Instruction const & instruction )
{
auto & memarg_and_lane = instruction . arguments ( ) . get < Instruction : : MemoryAndLaneArgument > ( ) ;
2024-08-04 08:06:50 -07:00
auto vector = configuration . value_stack ( ) . take_last ( ) . to < u128 > ( ) ;
2024-07-14 21:09:09 -07:00
auto src = bit_cast < u8 * > ( & vector ) + memarg_and_lane . lane * N / 8 ;
2024-08-04 08:06:50 -07:00
auto base = configuration . value_stack ( ) . take_last ( ) . to < u32 > ( ) ;
2024-07-18 13:29:17 -07:00
store_to_memory ( configuration , memarg_and_lane . memory , { src , N / 8 } , base ) ;
2024-07-14 21:09:09 -07:00
}
2024-07-18 13:29:17 -07:00
void BytecodeInterpreter : : store_to_memory ( Configuration & configuration , Instruction : : MemoryArgument const & arg , ReadonlyBytes data , u32 base )
2021-08-11 22:16:05 +04:30
{
2023-10-23 00:19:28 +03:30
auto & address = configuration . frame ( ) . module ( ) . memories ( ) [ arg . memory_index . value ( ) ] ;
auto memory = configuration . store ( ) . get ( address ) ;
2024-06-12 22:15:04 -07:00
u64 instance_address = static_cast < u64 > ( base ) + arg . offset ;
2021-08-11 22:16:05 +04:30
Checked addition { instance_address } ;
addition + = data . size ( ) ;
if ( addition . has_overflow ( ) | | addition . value ( ) > memory - > size ( ) ) {
2025-04-22 09:48:26 +02:00
m_trap = Trap : : from_string ( " Memory access out of bounds " ) ;
2025-05-21 16:22:12 +02:00
dbgln_if ( WASM_TRACE_DEBUG , " LibWasm: Memory access out of bounds (expected 0 <= {} and {} <= {}) " , instance_address , instance_address + data . size ( ) , memory - > size ( ) ) ;
2021-08-11 22:16:05 +04:30
return ;
}
2022-01-06 07:07:15 -07:00
dbgln_if ( WASM_TRACE_DEBUG , " temporary({}b) -> store({}) " , data . size ( ) , instance_address ) ;
2021-08-11 22:16:05 +04:30
data . copy_to ( memory - > data ( ) . bytes ( ) . slice ( instance_address , data . size ( ) ) ) ;
}
2021-06-04 21:54:20 +10:00
template < typename T >
T BytecodeInterpreter : : read_value ( ReadonlyBytes data )
{
2023-01-30 11:05:43 +01:00
FixedMemoryStream stream { data } ;
2023-04-12 12:05:06 +02:00
auto value_or_error = stream . read_value < LittleEndian < T > > ( ) ;
if ( value_or_error . is_error ( ) ) {
2021-06-04 21:54:20 +10:00
dbgln ( " Read from {} failed " , data . data ( ) ) ;
2025-04-22 09:48:26 +02:00
m_trap = Trap : : from_string ( " Read from memory failed " ) ;
2021-06-04 21:54:20 +10:00
}
2023-04-12 12:05:06 +02:00
return value_or_error . release_value ( ) ;
2021-06-04 21:54:20 +10:00
}
template < >
float BytecodeInterpreter : : read_value < float > ( ReadonlyBytes data )
{
2023-01-30 11:05:43 +01:00
FixedMemoryStream stream { data } ;
2023-04-12 12:05:06 +02:00
auto raw_value_or_error = stream . read_value < LittleEndian < u32 > > ( ) ;
if ( raw_value_or_error . is_error ( ) )
2025-04-22 09:48:26 +02:00
m_trap = Trap : : from_string ( " Read from memory failed " ) ;
2023-04-12 12:05:06 +02:00
auto raw_value = raw_value_or_error . release_value ( ) ;
2021-06-04 21:54:20 +10:00
return bit_cast < float > ( static_cast < u32 > ( raw_value ) ) ;
}
template < >
double BytecodeInterpreter : : read_value < double > ( ReadonlyBytes data )
{
2023-01-30 11:05:43 +01:00
FixedMemoryStream stream { data } ;
2023-04-12 12:05:06 +02:00
auto raw_value_or_error = stream . read_value < LittleEndian < u64 > > ( ) ;
if ( raw_value_or_error . is_error ( ) )
2025-04-22 09:48:26 +02:00
m_trap = Trap : : from_string ( " Read from memory failed " ) ;
2023-04-12 12:05:06 +02:00
auto raw_value = raw_value_or_error . release_value ( ) ;
2021-06-04 21:54:20 +10:00
return bit_cast < double > ( static_cast < u64 > ( raw_value ) ) ;
}
2024-08-02 20:58:15 -07:00
ALWAYS_INLINE void BytecodeInterpreter : : interpret_instruction ( Configuration & configuration , InstructionPointer & ip , Instruction const & instruction )
2021-06-04 21:54:20 +10:00
{
dbgln_if ( WASM_TRACE_DEBUG , " Executing instruction {} at ip {} " , instruction_name ( instruction . opcode ( ) ) , ip . value ( ) ) ;
switch ( instruction . opcode ( ) . value ( ) ) {
case Instructions : : unreachable . value ( ) :
2025-04-22 09:48:26 +02:00
m_trap = Trap : : from_string ( " Unreachable " ) ;
2021-06-04 21:54:20 +10:00
return ;
case Instructions : : nop . value ( ) :
return ;
case Instructions : : local_get . value ( ) :
2024-08-02 20:51:40 -07:00
configuration . value_stack ( ) . append ( Value ( configuration . frame ( ) . locals ( ) [ instruction . arguments ( ) . get < LocalIndex > ( ) . value ( ) ] ) ) ;
2021-06-04 21:54:20 +10:00
return ;
case Instructions : : local_set . value ( ) : {
2024-08-02 20:51:40 -07:00
auto value = configuration . value_stack ( ) . take_last ( ) ;
configuration . frame ( ) . locals ( ) [ instruction . arguments ( ) . get < LocalIndex > ( ) . value ( ) ] = value ;
2021-06-04 21:54:20 +10:00
return ;
}
case Instructions : : i32_const . value ( ) :
2024-08-04 08:06:50 -07:00
configuration . value_stack ( ) . append ( Value ( instruction . arguments ( ) . get < i32 > ( ) ) ) ;
2021-06-04 21:54:20 +10:00
return ;
case Instructions : : i64_const . value ( ) :
2024-08-04 08:06:50 -07:00
configuration . value_stack ( ) . append ( Value ( instruction . arguments ( ) . get < i64 > ( ) ) ) ;
2021-06-04 21:54:20 +10:00
return ;
case Instructions : : f32_const . value ( ) :
2024-08-04 08:06:50 -07:00
configuration . value_stack ( ) . append ( Value ( instruction . arguments ( ) . get < float > ( ) ) ) ;
2021-06-04 21:54:20 +10:00
return ;
case Instructions : : f64_const . value ( ) :
2024-08-04 08:06:50 -07:00
configuration . value_stack ( ) . append ( Value ( instruction . arguments ( ) . get < double > ( ) ) ) ;
2021-06-04 21:54:20 +10:00
return ;
case Instructions : : block . value ( ) : {
size_t arity = 0 ;
2024-08-02 20:51:40 -07:00
size_t param_arity = 0 ;
2021-06-04 21:54:20 +10:00
auto & args = instruction . arguments ( ) . get < Instruction : : StructuredInstructionArgs > ( ) ;
2021-12-04 17:57:48 +03:30
switch ( args . block_type . kind ( ) ) {
case BlockType : : Empty :
break ;
case BlockType : : Type :
2021-06-04 21:54:20 +10:00
arity = 1 ;
2021-12-04 17:57:48 +03:30
break ;
case BlockType : : Index : {
auto & type = configuration . frame ( ) . module ( ) . types ( ) [ args . block_type . type_index ( ) . value ( ) ] ;
arity = type . results ( ) . size ( ) ;
2024-08-02 20:51:40 -07:00
param_arity = type . parameters ( ) . size ( ) ;
2021-12-04 17:57:48 +03:30
}
}
2024-08-02 20:51:40 -07:00
configuration . label_stack ( ) . append ( Label ( arity , args . end_ip , configuration . value_stack ( ) . size ( ) - param_arity ) ) ;
2021-06-04 21:54:20 +10:00
return ;
}
case Instructions : : loop . value ( ) : {
auto & args = instruction . arguments ( ) . get < Instruction : : StructuredInstructionArgs > ( ) ;
2024-07-10 14:02:28 -07:00
size_t arity = 0 ;
if ( args . block_type . kind ( ) = = BlockType : : Index ) {
2021-12-04 17:57:48 +03:30
auto & type = configuration . frame ( ) . module ( ) . types ( ) [ args . block_type . type_index ( ) . value ( ) ] ;
2024-06-12 21:26:05 -07:00
arity = type . parameters ( ) . size ( ) ;
2021-12-04 17:57:48 +03:30
}
2024-08-02 20:51:40 -07:00
configuration . label_stack ( ) . append ( Label ( arity , ip . value ( ) + 1 , configuration . value_stack ( ) . size ( ) - arity ) ) ;
2021-06-04 21:54:20 +10:00
return ;
}
case Instructions : : if_ . value ( ) : {
size_t arity = 0 ;
2024-08-02 20:51:40 -07:00
size_t param_arity = 0 ;
2021-06-04 21:54:20 +10:00
auto & args = instruction . arguments ( ) . get < Instruction : : StructuredInstructionArgs > ( ) ;
2021-12-04 17:57:48 +03:30
switch ( args . block_type . kind ( ) ) {
case BlockType : : Empty :
break ;
case BlockType : : Type :
2021-06-04 21:54:20 +10:00
arity = 1 ;
2021-12-04 17:57:48 +03:30
break ;
case BlockType : : Index : {
auto & type = configuration . frame ( ) . module ( ) . types ( ) [ args . block_type . type_index ( ) . value ( ) ] ;
arity = type . results ( ) . size ( ) ;
2024-08-02 20:51:40 -07:00
param_arity = type . parameters ( ) . size ( ) ;
2021-12-04 17:57:48 +03:30
}
}
2021-06-04 21:54:20 +10:00
2024-08-02 20:51:40 -07:00
auto value = configuration . value_stack ( ) . take_last ( ) . to < i32 > ( ) ;
auto end_label = Label ( arity , args . end_ip . value ( ) , configuration . value_stack ( ) . size ( ) - param_arity ) ;
if ( value = = 0 ) {
2021-06-04 21:54:20 +10:00
if ( args . else_ip . has_value ( ) ) {
configuration . ip ( ) = args . else_ip . value ( ) ;
2024-08-02 20:51:40 -07:00
configuration . label_stack ( ) . append ( end_label ) ;
2021-06-04 21:54:20 +10:00
} else {
configuration . ip ( ) = args . end_ip . value ( ) + 1 ;
}
} else {
2024-08-02 20:51:40 -07:00
configuration . label_stack ( ) . append ( end_label ) ;
2021-06-04 21:54:20 +10:00
}
return ;
}
case Instructions : : structured_end . value ( ) :
2024-08-02 20:51:40 -07:00
configuration . label_stack ( ) . take_last ( ) ;
return ;
2021-06-04 21:54:20 +10:00
case Instructions : : structured_else . value ( ) : {
2024-08-02 20:51:40 -07:00
auto label = configuration . label_stack ( ) . take_last ( ) ;
2021-06-04 21:54:20 +10:00
// Jump to the end label
2021-08-09 02:55:01 +04:30
configuration . ip ( ) = label . continuation ( ) ;
2021-06-04 21:54:20 +10:00
return ;
}
case Instructions : : return_ . value ( ) : {
2024-08-02 20:51:40 -07:00
while ( configuration . label_stack ( ) . size ( ) - 1 ! = configuration . frame ( ) . label_index ( ) )
configuration . label_stack ( ) . take_last ( ) ;
2021-06-04 21:54:20 +10:00
configuration . ip ( ) = configuration . frame ( ) . expression ( ) . instructions ( ) . size ( ) ;
return ;
}
case Instructions : : br . value ( ) :
return branch_to_label ( configuration , instruction . arguments ( ) . get < LabelIndex > ( ) ) ;
case Instructions : : br_if . value ( ) : {
2024-08-02 20:51:40 -07:00
auto cond = configuration . value_stack ( ) . take_last ( ) . to < i32 > ( ) ;
2024-08-04 08:06:50 -07:00
if ( cond = = 0 )
2021-06-04 21:54:20 +10:00
return ;
return branch_to_label ( configuration , instruction . arguments ( ) . get < LabelIndex > ( ) ) ;
}
case Instructions : : br_table . value ( ) : {
auto & arguments = instruction . arguments ( ) . get < Instruction : : TableBranchArgs > ( ) ;
2024-08-04 08:06:50 -07:00
auto i = configuration . value_stack ( ) . take_last ( ) . to < u32 > ( ) ;
2024-08-02 20:51:40 -07:00
if ( i > = arguments . labels . size ( ) ) {
return branch_to_label ( configuration , arguments . default_ ) ;
2021-07-06 13:01:28 +04:30
}
2024-08-02 20:51:40 -07:00
return branch_to_label ( configuration , arguments . labels [ i ] ) ;
2021-06-04 21:54:20 +10:00
}
case Instructions : : call . value ( ) : {
auto index = instruction . arguments ( ) . get < FunctionIndex > ( ) ;
auto address = configuration . frame ( ) . module ( ) . functions ( ) [ index . value ( ) ] ;
dbgln_if ( WASM_TRACE_DEBUG , " call({}) " , address . value ( ) ) ;
call_address ( configuration , address ) ;
return ;
}
case Instructions : : call_indirect . value ( ) : {
auto & args = instruction . arguments ( ) . get < Instruction : : IndirectCallArgs > ( ) ;
auto table_address = configuration . frame ( ) . module ( ) . tables ( ) [ args . table . value ( ) ] ;
auto table_instance = configuration . store ( ) . get ( table_address ) ;
2024-08-02 20:51:40 -07:00
auto index = configuration . value_stack ( ) . take_last ( ) . to < i32 > ( ) ;
2024-08-04 08:06:50 -07:00
TRAP_IF_NOT ( index > = 0 ) ;
TRAP_IF_NOT ( static_cast < size_t > ( index ) < table_instance - > elements ( ) . size ( ) ) ;
auto element = table_instance - > elements ( ) [ index ] ;
2024-05-31 17:14:49 -07:00
TRAP_IF_NOT ( element . ref ( ) . has < Reference : : Func > ( ) ) ;
auto address = element . ref ( ) . get < Reference : : Func > ( ) . address ;
2025-05-21 16:16:28 +02:00
auto const & type_actual = configuration . store ( ) . get ( address ) - > visit ( [ ] ( auto & f ) - > decltype ( auto ) { return f . type ( ) ; } ) ;
auto const & type_expected = configuration . frame ( ) . module ( ) . types ( ) [ args . type . value ( ) ] ;
TRAP_IF_NOT ( type_actual . parameters ( ) . size ( ) = = type_expected . parameters ( ) . size ( ) ) ;
TRAP_IF_NOT ( type_actual . results ( ) . size ( ) = = type_expected . results ( ) . size ( ) ) ;
TRAP_IF_NOT ( type_actual . parameters ( ) = = type_expected . parameters ( ) ) ;
TRAP_IF_NOT ( type_actual . results ( ) = = type_expected . results ( ) ) ;
2024-08-04 08:06:50 -07:00
dbgln_if ( WASM_TRACE_DEBUG , " call_indirect({} -> {}) " , index , address . value ( ) ) ;
2025-05-21 16:16:28 +02:00
call_address ( configuration , address , CallAddressSource : : IndirectCall ) ;
2021-06-04 21:54:20 +10:00
return ;
}
case Instructions : : i32_load . value ( ) :
2021-08-10 23:39:26 +04:30
return load_and_push < i32 , i32 > ( configuration , instruction ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_load . value ( ) :
2021-08-10 23:39:26 +04:30
return load_and_push < i64 , i64 > ( configuration , instruction ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f32_load . value ( ) :
2021-08-10 23:39:26 +04:30
return load_and_push < float , float > ( configuration , instruction ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f64_load . value ( ) :
2021-08-10 23:39:26 +04:30
return load_and_push < double , double > ( configuration , instruction ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_load8_s . value ( ) :
2021-08-10 23:39:26 +04:30
return load_and_push < i8 , i32 > ( configuration , instruction ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_load8_u . value ( ) :
2021-08-10 23:39:26 +04:30
return load_and_push < u8 , i32 > ( configuration , instruction ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_load16_s . value ( ) :
2021-08-10 23:39:26 +04:30
return load_and_push < i16 , i32 > ( configuration , instruction ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_load16_u . value ( ) :
2021-08-10 23:39:26 +04:30
return load_and_push < u16 , i32 > ( configuration , instruction ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_load8_s . value ( ) :
2021-08-10 23:39:26 +04:30
return load_and_push < i8 , i64 > ( configuration , instruction ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_load8_u . value ( ) :
2021-08-10 23:39:26 +04:30
return load_and_push < u8 , i64 > ( configuration , instruction ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_load16_s . value ( ) :
2021-08-10 23:39:26 +04:30
return load_and_push < i16 , i64 > ( configuration , instruction ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_load16_u . value ( ) :
2021-08-10 23:39:26 +04:30
return load_and_push < u16 , i64 > ( configuration , instruction ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_load32_s . value ( ) :
2021-08-10 23:39:26 +04:30
return load_and_push < i32 , i64 > ( configuration , instruction ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_load32_u . value ( ) :
2021-08-10 23:39:26 +04:30
return load_and_push < u32 , i64 > ( configuration , instruction ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_store . value ( ) :
2021-08-11 22:16:05 +04:30
return pop_and_store < i32 , i32 > ( configuration , instruction ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_store . value ( ) :
2021-08-11 22:16:05 +04:30
return pop_and_store < i64 , i64 > ( configuration , instruction ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f32_store . value ( ) :
2021-08-11 22:16:05 +04:30
return pop_and_store < float , float > ( configuration , instruction ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f64_store . value ( ) :
2021-08-11 22:16:05 +04:30
return pop_and_store < double , double > ( configuration , instruction ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_store8 . value ( ) :
2021-08-11 22:16:05 +04:30
return pop_and_store < i32 , i8 > ( configuration , instruction ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_store16 . value ( ) :
2021-08-11 22:16:05 +04:30
return pop_and_store < i32 , i16 > ( configuration , instruction ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_store8 . value ( ) :
2021-08-11 22:16:05 +04:30
return pop_and_store < i64 , i8 > ( configuration , instruction ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_store16 . value ( ) :
2021-08-11 22:16:05 +04:30
return pop_and_store < i64 , i16 > ( configuration , instruction ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_store32 . value ( ) :
2021-08-11 22:16:05 +04:30
return pop_and_store < i64 , i32 > ( configuration , instruction ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : local_tee . value ( ) : {
2024-08-02 20:51:40 -07:00
auto value = configuration . value_stack ( ) . last ( ) ;
2021-06-04 21:54:20 +10:00
auto local_index = instruction . arguments ( ) . get < LocalIndex > ( ) ;
dbgln_if ( WASM_TRACE_DEBUG , " stack:peek -> locals({}) " , local_index . value ( ) ) ;
2024-08-02 20:51:40 -07:00
configuration . frame ( ) . locals ( ) [ local_index . value ( ) ] = value ;
2021-06-04 21:54:20 +10:00
return ;
}
case Instructions : : global_get . value ( ) : {
auto global_index = instruction . arguments ( ) . get < GlobalIndex > ( ) ;
2024-06-16 09:55:51 -07:00
// This check here is for const expressions. In non-const expressions,
// a validation error would have been thrown.
TRAP_IF_NOT ( global_index < configuration . frame ( ) . module ( ) . globals ( ) . size ( ) ) ;
2021-06-04 21:54:20 +10:00
auto address = configuration . frame ( ) . module ( ) . globals ( ) [ global_index . value ( ) ] ;
dbgln_if ( WASM_TRACE_DEBUG , " global({}) -> stack " , address . value ( ) ) ;
auto global = configuration . store ( ) . get ( address ) ;
2024-08-02 20:51:40 -07:00
configuration . value_stack ( ) . append ( global - > value ( ) ) ;
2021-06-04 21:54:20 +10:00
return ;
}
case Instructions : : global_set . value ( ) : {
auto global_index = instruction . arguments ( ) . get < GlobalIndex > ( ) ;
auto address = configuration . frame ( ) . module ( ) . globals ( ) [ global_index . value ( ) ] ;
2024-08-02 20:51:40 -07:00
auto value = configuration . value_stack ( ) . take_last ( ) ;
2021-06-04 21:54:20 +10:00
dbgln_if ( WASM_TRACE_DEBUG , " stack -> global({}) " , address . value ( ) ) ;
auto global = configuration . store ( ) . get ( address ) ;
2024-08-02 20:51:40 -07:00
global - > set_value ( value ) ;
2021-06-04 21:54:20 +10:00
return ;
}
case Instructions : : memory_size . value ( ) : {
2023-10-23 00:19:28 +03:30
auto & args = instruction . arguments ( ) . get < Instruction : : MemoryIndexArgument > ( ) ;
auto address = configuration . frame ( ) . module ( ) . memories ( ) [ args . memory_index . value ( ) ] ;
2021-06-04 21:54:20 +10:00
auto instance = configuration . store ( ) . get ( address ) ;
auto pages = instance - > size ( ) / Constants : : page_size ;
dbgln_if ( WASM_TRACE_DEBUG , " memory.size -> stack({}) " , pages ) ;
2024-08-02 20:51:40 -07:00
configuration . value_stack ( ) . append ( Value ( ( i32 ) pages ) ) ;
2021-06-04 21:54:20 +10:00
return ;
}
case Instructions : : memory_grow . value ( ) : {
2023-10-23 00:19:28 +03:30
auto & args = instruction . arguments ( ) . get < Instruction : : MemoryIndexArgument > ( ) ;
auto address = configuration . frame ( ) . module ( ) . memories ( ) [ args . memory_index . value ( ) ] ;
2021-06-04 21:54:20 +10:00
auto instance = configuration . store ( ) . get ( address ) ;
i32 old_pages = instance - > size ( ) / Constants : : page_size ;
2024-08-02 20:51:40 -07:00
auto & entry = configuration . value_stack ( ) . last ( ) ;
auto new_pages = entry . to < i32 > ( ) ;
2024-08-04 08:06:50 -07:00
dbgln_if ( WASM_TRACE_DEBUG , " memory.grow({}), previously {} pages... " , new_pages , old_pages ) ;
if ( instance - > grow ( new_pages * Constants : : page_size ) )
2024-08-02 20:51:40 -07:00
entry = Value ( ( i32 ) old_pages ) ;
2021-06-04 21:54:20 +10:00
else
2024-08-02 20:51:40 -07:00
entry = Value ( ( i32 ) - 1 ) ;
2021-06-04 21:54:20 +10:00
return ;
}
2023-01-28 14:56:18 +00:00
// https://webassembly.github.io/spec/core/bikeshed/#exec-memory-fill
case Instructions : : memory_fill . value ( ) : {
2023-10-23 00:19:28 +03:30
auto & args = instruction . arguments ( ) . get < Instruction : : MemoryIndexArgument > ( ) ;
auto address = configuration . frame ( ) . module ( ) . memories ( ) [ args . memory_index . value ( ) ] ;
2023-01-28 14:56:18 +00:00
auto instance = configuration . store ( ) . get ( address ) ;
2024-08-04 08:06:50 -07:00
auto count = configuration . value_stack ( ) . take_last ( ) . to < u32 > ( ) ;
u8 value = static_cast < u8 > ( configuration . value_stack ( ) . take_last ( ) . to < u32 > ( ) ) ;
auto destination_offset = configuration . value_stack ( ) . take_last ( ) . to < u32 > ( ) ;
2023-01-28 14:56:18 +00:00
TRAP_IF_NOT ( static_cast < size_t > ( destination_offset + count ) < = instance - > data ( ) . size ( ) ) ;
if ( count = = 0 )
return ;
2025-05-21 16:22:32 +02:00
for ( u32 i = 0 ; i < count ; + + i ) {
2024-07-18 13:29:17 -07:00
store_to_memory ( configuration , Instruction : : MemoryArgument { 0 , 0 } , { & value , sizeof ( value ) } , destination_offset + i ) ;
2025-05-21 16:22:32 +02:00
if ( did_trap ( ) )
return ;
}
2023-01-28 14:56:18 +00:00
return ;
}
2023-01-28 15:24:04 +00:00
// https://webassembly.github.io/spec/core/bikeshed/#exec-memory-copy
case Instructions : : memory_copy . value ( ) : {
2023-10-23 00:19:28 +03:30
auto & args = instruction . arguments ( ) . get < Instruction : : MemoryCopyArgs > ( ) ;
auto source_address = configuration . frame ( ) . module ( ) . memories ( ) [ args . src_index . value ( ) ] ;
auto destination_address = configuration . frame ( ) . module ( ) . memories ( ) [ args . dst_index . value ( ) ] ;
auto source_instance = configuration . store ( ) . get ( source_address ) ;
auto destination_instance = configuration . store ( ) . get ( destination_address ) ;
2024-08-04 08:06:50 -07:00
auto count = configuration . value_stack ( ) . take_last ( ) . to < i32 > ( ) ;
auto source_offset = configuration . value_stack ( ) . take_last ( ) . to < i32 > ( ) ;
auto destination_offset = configuration . value_stack ( ) . take_last ( ) . to < i32 > ( ) ;
2023-01-28 15:24:04 +00:00
2024-06-01 15:41:16 -07:00
Checked < size_t > source_position = source_offset ;
source_position . saturating_add ( count ) ;
Checked < size_t > destination_position = destination_offset ;
destination_position . saturating_add ( count ) ;
TRAP_IF_NOT ( source_position < = source_instance - > data ( ) . size ( ) ) ;
TRAP_IF_NOT ( destination_position < = destination_instance - > data ( ) . size ( ) ) ;
2023-01-28 15:24:04 +00:00
if ( count = = 0 )
return ;
2024-07-18 13:29:17 -07:00
Instruction : : MemoryArgument memarg { 0 , 0 , args . dst_index } ;
2023-01-28 15:24:04 +00:00
if ( destination_offset < = source_offset ) {
for ( auto i = 0 ; i < count ; + + i ) {
2023-10-23 00:19:28 +03:30
auto value = source_instance - > data ( ) [ source_offset + i ] ;
2024-07-18 13:29:17 -07:00
store_to_memory ( configuration , memarg , { & value , sizeof ( value ) } , destination_offset + i ) ;
2023-01-28 15:24:04 +00:00
}
} else {
for ( auto i = count - 1 ; i > = 0 ; - - i ) {
2023-10-23 00:19:28 +03:30
auto value = source_instance - > data ( ) [ source_offset + i ] ;
2024-07-18 13:29:17 -07:00
store_to_memory ( configuration , memarg , { & value , sizeof ( value ) } , destination_offset + i ) ;
2023-01-28 15:24:04 +00:00
}
}
return ;
}
2023-01-28 15:28:54 +00:00
// https://webassembly.github.io/spec/core/bikeshed/#exec-memory-init
case Instructions : : memory_init . value ( ) : {
2023-10-23 00:19:28 +03:30
auto & args = instruction . arguments ( ) . get < Instruction : : MemoryInitArgs > ( ) ;
auto & data_address = configuration . frame ( ) . module ( ) . datas ( ) [ args . data_index . value ( ) ] ;
2023-01-28 15:28:54 +00:00
auto & data = * configuration . store ( ) . get ( data_address ) ;
2024-06-21 16:28:27 -07:00
auto memory_address = configuration . frame ( ) . module ( ) . memories ( ) [ args . memory_index . value ( ) ] ;
auto memory = configuration . store ( ) . get ( memory_address ) ;
2024-08-04 08:06:50 -07:00
auto count = configuration . value_stack ( ) . take_last ( ) . to < u32 > ( ) ;
auto source_offset = configuration . value_stack ( ) . take_last ( ) . to < u32 > ( ) ;
auto destination_offset = configuration . value_stack ( ) . take_last ( ) . to < u32 > ( ) ;
2024-06-12 22:15:04 -07:00
2024-06-21 16:28:27 -07:00
Checked < size_t > source_position = source_offset ;
source_position . saturating_add ( count ) ;
Checked < size_t > destination_position = destination_offset ;
destination_position . saturating_add ( count ) ;
TRAP_IF_NOT ( source_position < = data . data ( ) . size ( ) ) ;
TRAP_IF_NOT ( destination_position < = memory - > data ( ) . size ( ) ) ;
2024-06-12 22:15:04 -07:00
if ( count = = 0 )
return ;
2023-01-28 15:28:54 +00:00
2024-07-18 13:29:17 -07:00
Instruction : : MemoryArgument memarg { 0 , 0 , args . memory_index } ;
2023-01-28 15:28:54 +00:00
for ( size_t i = 0 ; i < ( size_t ) count ; + + i ) {
auto value = data . data ( ) [ source_offset + i ] ;
2024-07-18 13:29:17 -07:00
store_to_memory ( configuration , memarg , { & value , sizeof ( value ) } , destination_offset + i ) ;
2023-01-28 15:28:54 +00:00
}
return ;
}
2023-01-28 15:37:59 +00:00
// https://webassembly.github.io/spec/core/bikeshed/#exec-data-drop
case Instructions : : data_drop . value ( ) : {
auto data_index = instruction . arguments ( ) . get < DataIndex > ( ) ;
auto data_address = configuration . frame ( ) . module ( ) . datas ( ) [ data_index . value ( ) ] ;
* configuration . store ( ) . get ( data_address ) = DataInstance ( { } ) ;
return ;
}
2024-05-31 17:14:49 -07:00
case Instructions : : elem_drop . value ( ) : {
auto elem_index = instruction . arguments ( ) . get < ElementIndex > ( ) ;
auto address = configuration . frame ( ) . module ( ) . elements ( ) [ elem_index . value ( ) ] ;
auto elem = configuration . store ( ) . get ( address ) ;
* configuration . store ( ) . get ( address ) = ElementInstance ( elem - > type ( ) , { } ) ;
return ;
}
2024-06-15 11:13:15 -07:00
case Instructions : : table_init . value ( ) : {
auto & args = instruction . arguments ( ) . get < Instruction : : TableElementArgs > ( ) ;
auto table_address = configuration . frame ( ) . module ( ) . tables ( ) [ args . table_index . value ( ) ] ;
auto table = configuration . store ( ) . get ( table_address ) ;
auto element_address = configuration . frame ( ) . module ( ) . elements ( ) [ args . element_index . value ( ) ] ;
auto element = configuration . store ( ) . get ( element_address ) ;
2024-08-04 08:06:50 -07:00
auto count = configuration . value_stack ( ) . take_last ( ) . to < u32 > ( ) ;
auto source_offset = configuration . value_stack ( ) . take_last ( ) . to < u32 > ( ) ;
auto destination_offset = configuration . value_stack ( ) . take_last ( ) . to < u32 > ( ) ;
2024-06-15 11:13:15 -07:00
Checked < u32 > checked_source_offset = source_offset ;
Checked < u32 > checked_destination_offset = destination_offset ;
checked_source_offset + = count ;
checked_destination_offset + = count ;
TRAP_IF_NOT ( ! checked_source_offset . has_overflow ( ) & & checked_source_offset < = ( u32 ) element - > references ( ) . size ( ) ) ;
TRAP_IF_NOT ( ! checked_destination_offset . has_overflow ( ) & & checked_destination_offset < = ( u32 ) table - > elements ( ) . size ( ) ) ;
for ( u32 i = 0 ; i < count ; + + i )
table - > elements ( ) [ destination_offset + i ] = element - > references ( ) [ source_offset + i ] ;
return ;
}
case Instructions : : table_copy . value ( ) : {
auto & args = instruction . arguments ( ) . get < Instruction : : TableTableArgs > ( ) ;
auto source_address = configuration . frame ( ) . module ( ) . tables ( ) [ args . rhs . value ( ) ] ;
auto destination_address = configuration . frame ( ) . module ( ) . tables ( ) [ args . lhs . value ( ) ] ;
auto source_instance = configuration . store ( ) . get ( source_address ) ;
auto destination_instance = configuration . store ( ) . get ( destination_address ) ;
2024-08-04 08:06:50 -07:00
auto count = configuration . value_stack ( ) . take_last ( ) . to < u32 > ( ) ;
auto source_offset = configuration . value_stack ( ) . take_last ( ) . to < u32 > ( ) ;
auto destination_offset = configuration . value_stack ( ) . take_last ( ) . to < u32 > ( ) ;
2024-06-15 11:13:15 -07:00
Checked < size_t > source_position = source_offset ;
source_position . saturating_add ( count ) ;
Checked < size_t > destination_position = destination_offset ;
destination_position . saturating_add ( count ) ;
TRAP_IF_NOT ( source_position < = source_instance - > elements ( ) . size ( ) ) ;
TRAP_IF_NOT ( destination_position < = destination_instance - > elements ( ) . size ( ) ) ;
if ( count = = 0 )
return ;
if ( destination_offset < = source_offset ) {
for ( u32 i = 0 ; i < count ; + + i ) {
auto value = source_instance - > elements ( ) [ source_offset + i ] ;
destination_instance - > elements ( ) [ destination_offset + i ] = value ;
}
} else {
for ( u32 i = count - 1 ; i ! = NumericLimits < u32 > : : max ( ) ; - - i ) {
auto value = source_instance - > elements ( ) [ source_offset + i ] ;
destination_instance - > elements ( ) [ destination_offset + i ] = value ;
}
}
return ;
}
case Instructions : : table_fill . value ( ) : {
auto table_index = instruction . arguments ( ) . get < TableIndex > ( ) ;
auto address = configuration . frame ( ) . module ( ) . tables ( ) [ table_index . value ( ) ] ;
auto table = configuration . store ( ) . get ( address ) ;
2024-08-04 08:06:50 -07:00
auto count = configuration . value_stack ( ) . take_last ( ) . to < u32 > ( ) ;
auto value = configuration . value_stack ( ) . take_last ( ) . to < Reference > ( ) ;
auto start = configuration . value_stack ( ) . take_last ( ) . to < u32 > ( ) ;
2024-06-15 11:13:15 -07:00
Checked < u32 > checked_offset = start ;
checked_offset + = count ;
TRAP_IF_NOT ( ! checked_offset . has_overflow ( ) & & checked_offset < = ( u32 ) table - > elements ( ) . size ( ) ) ;
for ( u32 i = 0 ; i < count ; + + i )
table - > elements ( ) [ start + i ] = value ;
return ;
}
2024-05-31 17:14:49 -07:00
case Instructions : : table_set . value ( ) : {
2024-08-04 08:06:50 -07:00
auto ref = configuration . value_stack ( ) . take_last ( ) . to < Reference > ( ) ;
auto index = ( size_t ) ( configuration . value_stack ( ) . take_last ( ) . to < i32 > ( ) ) ;
2024-05-31 17:14:49 -07:00
auto table_index = instruction . arguments ( ) . get < TableIndex > ( ) ;
auto address = configuration . frame ( ) . module ( ) . tables ( ) [ table_index . value ( ) ] ;
auto table = configuration . store ( ) . get ( address ) ;
TRAP_IF_NOT ( index < table - > elements ( ) . size ( ) ) ;
table - > elements ( ) [ index ] = ref ;
return ;
}
case Instructions : : table_get . value ( ) : {
2024-08-04 08:06:50 -07:00
auto index = ( size_t ) ( configuration . value_stack ( ) . take_last ( ) . to < i32 > ( ) ) ;
2024-05-31 17:14:49 -07:00
auto table_index = instruction . arguments ( ) . get < TableIndex > ( ) ;
auto address = configuration . frame ( ) . module ( ) . tables ( ) [ table_index . value ( ) ] ;
auto table = configuration . store ( ) . get ( address ) ;
TRAP_IF_NOT ( index < table - > elements ( ) . size ( ) ) ;
auto ref = table - > elements ( ) [ index ] ;
2024-08-02 20:51:40 -07:00
configuration . value_stack ( ) . append ( Value ( ref ) ) ;
2024-05-31 17:14:49 -07:00
return ;
}
case Instructions : : table_grow . value ( ) : {
2024-08-04 08:06:50 -07:00
auto size = configuration . value_stack ( ) . take_last ( ) . to < u32 > ( ) ;
auto fill_value = configuration . value_stack ( ) . take_last ( ) . to < Reference > ( ) ;
2024-05-31 17:14:49 -07:00
auto table_index = instruction . arguments ( ) . get < TableIndex > ( ) ;
auto address = configuration . frame ( ) . module ( ) . tables ( ) [ table_index . value ( ) ] ;
auto table = configuration . store ( ) . get ( address ) ;
auto previous_size = table - > elements ( ) . size ( ) ;
auto did_grow = table - > grow ( size , fill_value ) ;
if ( ! did_grow ) {
2024-08-02 20:51:40 -07:00
configuration . value_stack ( ) . append ( Value ( ( i32 ) - 1 ) ) ;
2024-05-31 17:14:49 -07:00
} else {
2024-08-02 20:51:40 -07:00
configuration . value_stack ( ) . append ( Value ( ( i32 ) previous_size ) ) ;
2024-05-31 17:14:49 -07:00
}
return ;
}
case Instructions : : table_size . value ( ) : {
auto table_index = instruction . arguments ( ) . get < TableIndex > ( ) ;
auto address = configuration . frame ( ) . module ( ) . tables ( ) [ table_index . value ( ) ] ;
auto table = configuration . store ( ) . get ( address ) ;
2024-08-02 20:51:40 -07:00
configuration . value_stack ( ) . append ( Value ( ( i32 ) table - > elements ( ) . size ( ) ) ) ;
2024-05-31 17:14:49 -07:00
return ;
}
2021-06-04 21:54:20 +10:00
case Instructions : : ref_null . value ( ) : {
auto type = instruction . arguments ( ) . get < ValueType > ( ) ;
2024-08-02 20:51:40 -07:00
configuration . value_stack ( ) . append ( Value ( Reference ( Reference : : Null { type } ) ) ) ;
2021-06-04 21:54:20 +10:00
return ;
} ;
case Instructions : : ref_func . value ( ) : {
auto index = instruction . arguments ( ) . get < FunctionIndex > ( ) . value ( ) ;
auto & functions = configuration . frame ( ) . module ( ) . functions ( ) ;
auto address = functions [ index ] ;
2024-08-22 01:13:37 +02:00
configuration . value_stack ( ) . append ( Value ( Reference { Reference : : Func { address , configuration . store ( ) . get_module_for ( address ) } } ) ) ;
2021-06-04 21:54:20 +10:00
return ;
}
case Instructions : : ref_is_null . value ( ) : {
2024-08-04 08:06:50 -07:00
auto ref = configuration . value_stack ( ) . take_last ( ) . to < Reference > ( ) ;
configuration . value_stack ( ) . append ( Value ( static_cast < i32 > ( ref . ref ( ) . has < Reference : : Null > ( ) ? 1 : 0 ) ) ) ;
2021-06-04 21:54:20 +10:00
return ;
}
case Instructions : : drop . value ( ) :
2024-08-02 20:51:40 -07:00
configuration . value_stack ( ) . take_last ( ) ;
2021-06-04 21:54:20 +10:00
return ;
case Instructions : : select . value ( ) :
case Instructions : : select_typed . value ( ) : {
// Note: The type seems to only be used for validation.
2024-08-02 20:51:40 -07:00
auto value = configuration . value_stack ( ) . take_last ( ) . to < i32 > ( ) ;
2024-08-04 08:06:50 -07:00
dbgln_if ( WASM_TRACE_DEBUG , " select({}) " , value ) ;
2024-08-02 20:51:40 -07:00
auto rhs = configuration . value_stack ( ) . take_last ( ) ;
auto & lhs = configuration . value_stack ( ) . last ( ) ;
2024-08-04 08:06:50 -07:00
lhs = value ! = 0 ? lhs : rhs ;
2021-06-04 21:54:20 +10:00
return ;
}
case Instructions : : i32_eqz . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < i32 , i32 , Operators : : EqualsZero > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_eq . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < i32 , i32 , Operators : : Equals > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_ne . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < i32 , i32 , Operators : : NotEquals > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_lts . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < i32 , i32 , Operators : : LessThan > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_ltu . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < u32 , i32 , Operators : : LessThan > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_gts . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < i32 , i32 , Operators : : GreaterThan > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_gtu . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < u32 , i32 , Operators : : GreaterThan > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_les . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < i32 , i32 , Operators : : LessThanOrEquals > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_leu . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < u32 , i32 , Operators : : LessThanOrEquals > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_ges . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < i32 , i32 , Operators : : GreaterThanOrEquals > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_geu . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < u32 , i32 , Operators : : GreaterThanOrEquals > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_eqz . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < i64 , i32 , Operators : : EqualsZero > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_eq . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < i64 , i32 , Operators : : Equals > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_ne . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < i64 , i32 , Operators : : NotEquals > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_lts . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < i64 , i32 , Operators : : LessThan > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_ltu . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < u64 , i32 , Operators : : LessThan > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_gts . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < i64 , i32 , Operators : : GreaterThan > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_gtu . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < u64 , i32 , Operators : : GreaterThan > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_les . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < i64 , i32 , Operators : : LessThanOrEquals > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_leu . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < u64 , i32 , Operators : : LessThanOrEquals > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_ges . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < i64 , i32 , Operators : : GreaterThanOrEquals > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_geu . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < u64 , i32 , Operators : : GreaterThanOrEquals > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f32_eq . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < float , i32 , Operators : : Equals > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f32_ne . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < float , i32 , Operators : : NotEquals > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f32_lt . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < float , i32 , Operators : : LessThan > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f32_gt . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < float , i32 , Operators : : GreaterThan > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f32_le . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < float , i32 , Operators : : LessThanOrEquals > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f32_ge . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < float , i32 , Operators : : GreaterThanOrEquals > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f64_eq . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < double , i32 , Operators : : Equals > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f64_ne . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < double , i32 , Operators : : NotEquals > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f64_lt . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < double , i32 , Operators : : LessThan > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f64_gt . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < double , i32 , Operators : : GreaterThan > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f64_le . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < double , i32 , Operators : : LessThanOrEquals > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f64_ge . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < double , i32 , Operators : : GreaterThanOrEquals > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_clz . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < i32 , i32 , Operators : : CountLeadingZeros > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_ctz . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < i32 , i32 , Operators : : CountTrailingZeros > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_popcnt . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < i32 , i32 , Operators : : PopCount > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_add . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < u32 , i32 , Operators : : Add > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_sub . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < u32 , i32 , Operators : : Subtract > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_mul . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < u32 , i32 , Operators : : Multiply > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_divs . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < i32 , i32 , Operators : : Divide > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_divu . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < u32 , i32 , Operators : : Divide > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_rems . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < i32 , i32 , Operators : : Modulo > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_remu . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < u32 , i32 , Operators : : Modulo > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_and . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < i32 , i32 , Operators : : BitAnd > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_or . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < i32 , i32 , Operators : : BitOr > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_xor . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < i32 , i32 , Operators : : BitXor > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_shl . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < u32 , i32 , Operators : : BitShiftLeft > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_shrs . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < i32 , i32 , Operators : : BitShiftRight > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_shru . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < u32 , i32 , Operators : : BitShiftRight > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_rotl . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < u32 , i32 , Operators : : BitRotateLeft > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_rotr . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < u32 , i32 , Operators : : BitRotateRight > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_clz . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < i64 , i64 , Operators : : CountLeadingZeros > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_ctz . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < i64 , i64 , Operators : : CountTrailingZeros > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_popcnt . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < i64 , i64 , Operators : : PopCount > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_add . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < u64 , i64 , Operators : : Add > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_sub . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < u64 , i64 , Operators : : Subtract > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_mul . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < u64 , i64 , Operators : : Multiply > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_divs . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < i64 , i64 , Operators : : Divide > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_divu . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < u64 , i64 , Operators : : Divide > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_rems . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < i64 , i64 , Operators : : Modulo > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_remu . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < u64 , i64 , Operators : : Modulo > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_and . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < i64 , i64 , Operators : : BitAnd > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_or . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < i64 , i64 , Operators : : BitOr > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_xor . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < i64 , i64 , Operators : : BitXor > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_shl . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < u64 , i64 , Operators : : BitShiftLeft > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_shrs . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < i64 , i64 , Operators : : BitShiftRight > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_shru . value ( ) :
2021-08-25 22:58:39 +04:30
return binary_numeric_operation < u64 , i64 , Operators : : BitShiftRight > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_rotl . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < u64 , i64 , Operators : : BitRotateLeft > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_rotr . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < u64 , i64 , Operators : : BitRotateRight > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f32_abs . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < float , float , Operators : : Absolute > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f32_neg . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < float , float , Operators : : Negate > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f32_ceil . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < float , float , Operators : : Ceil > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f32_floor . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < float , float , Operators : : Floor > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f32_trunc . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < float , float , Operators : : Truncate > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f32_nearest . value ( ) :
2021-08-30 16:21:21 +04:30
return unary_operation < float , float , Operators : : NearbyIntegral > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f32_sqrt . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < float , float , Operators : : SquareRoot > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f32_add . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < float , float , Operators : : Add > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f32_sub . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < float , float , Operators : : Subtract > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f32_mul . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < float , float , Operators : : Multiply > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f32_div . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < float , float , Operators : : Divide > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f32_min . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < float , float , Operators : : Minimum > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f32_max . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < float , float , Operators : : Maximum > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f32_copysign . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < float , float , Operators : : CopySign > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f64_abs . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < double , double , Operators : : Absolute > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f64_neg . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < double , double , Operators : : Negate > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f64_ceil . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < double , double , Operators : : Ceil > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f64_floor . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < double , double , Operators : : Floor > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f64_trunc . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < double , double , Operators : : Truncate > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f64_nearest . value ( ) :
2021-08-30 16:21:21 +04:30
return unary_operation < double , double , Operators : : NearbyIntegral > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f64_sqrt . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < double , double , Operators : : SquareRoot > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f64_add . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < double , double , Operators : : Add > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f64_sub . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < double , double , Operators : : Subtract > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f64_mul . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < double , double , Operators : : Multiply > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f64_div . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < double , double , Operators : : Divide > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f64_min . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < double , double , Operators : : Minimum > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f64_max . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < double , double , Operators : : Maximum > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f64_copysign . value ( ) :
2021-08-09 02:55:01 +04:30
return binary_numeric_operation < double , double , Operators : : CopySign > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_wrap_i64 . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < i64 , i32 , Operators : : Wrap < i32 > > ( configuration ) ;
case Instructions : : i32_trunc_sf32 . value ( ) :
return unary_operation < float , i32 , Operators : : CheckedTruncate < i32 > > ( configuration ) ;
case Instructions : : i32_trunc_uf32 . value ( ) :
return unary_operation < float , i32 , Operators : : CheckedTruncate < u32 > > ( configuration ) ;
case Instructions : : i32_trunc_sf64 . value ( ) :
return unary_operation < double , i32 , Operators : : CheckedTruncate < i32 > > ( configuration ) ;
case Instructions : : i32_trunc_uf64 . value ( ) :
return unary_operation < double , i32 , Operators : : CheckedTruncate < u32 > > ( configuration ) ;
case Instructions : : i64_trunc_sf32 . value ( ) :
return unary_operation < float , i64 , Operators : : CheckedTruncate < i64 > > ( configuration ) ;
case Instructions : : i64_trunc_uf32 . value ( ) :
return unary_operation < float , i64 , Operators : : CheckedTruncate < u64 > > ( configuration ) ;
case Instructions : : i64_trunc_sf64 . value ( ) :
return unary_operation < double , i64 , Operators : : CheckedTruncate < i64 > > ( configuration ) ;
case Instructions : : i64_trunc_uf64 . value ( ) :
return unary_operation < double , i64 , Operators : : CheckedTruncate < u64 > > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_extend_si32 . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < i32 , i64 , Operators : : Extend < i64 > > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_extend_ui32 . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < u32 , i64 , Operators : : Extend < i64 > > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f32_convert_si32 . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < i32 , float , Operators : : Convert < float > > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f32_convert_ui32 . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < u32 , float , Operators : : Convert < float > > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f32_convert_si64 . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < i64 , float , Operators : : Convert < float > > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f32_convert_ui64 . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < u64 , float , Operators : : Convert < float > > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f32_demote_f64 . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < double , float , Operators : : Demote > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f64_convert_si32 . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < i32 , double , Operators : : Convert < double > > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f64_convert_ui32 . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < u32 , double , Operators : : Convert < double > > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f64_convert_si64 . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < i64 , double , Operators : : Convert < double > > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f64_convert_ui64 . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < u64 , double , Operators : : Convert < double > > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f64_promote_f32 . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < float , double , Operators : : Promote > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_reinterpret_f32 . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < float , i32 , Operators : : Reinterpret < i32 > > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_reinterpret_f64 . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < double , i64 , Operators : : Reinterpret < i64 > > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f32_reinterpret_i32 . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < i32 , float , Operators : : Reinterpret < float > > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : f64_reinterpret_i64 . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < i64 , double , Operators : : Reinterpret < double > > ( configuration ) ;
2021-06-09 17:13:38 +04:30
case Instructions : : i32_extend8_s . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < i32 , i32 , Operators : : SignExtend < i8 > > ( configuration ) ;
2021-06-09 17:13:38 +04:30
case Instructions : : i32_extend16_s . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < i32 , i32 , Operators : : SignExtend < i16 > > ( configuration ) ;
2021-06-09 17:13:38 +04:30
case Instructions : : i64_extend8_s . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < i64 , i64 , Operators : : SignExtend < i8 > > ( configuration ) ;
2021-06-09 17:13:38 +04:30
case Instructions : : i64_extend16_s . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < i64 , i64 , Operators : : SignExtend < i16 > > ( configuration ) ;
2021-06-09 17:13:38 +04:30
case Instructions : : i64_extend32_s . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < i64 , i64 , Operators : : SignExtend < i32 > > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_trunc_sat_f32_s . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < float , i32 , Operators : : SaturatingTruncate < i32 > > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_trunc_sat_f32_u . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < float , i32 , Operators : : SaturatingTruncate < u32 > > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_trunc_sat_f64_s . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < double , i32 , Operators : : SaturatingTruncate < i32 > > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i32_trunc_sat_f64_u . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < double , i32 , Operators : : SaturatingTruncate < u32 > > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_trunc_sat_f32_s . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < float , i64 , Operators : : SaturatingTruncate < i64 > > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_trunc_sat_f32_u . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < float , i64 , Operators : : SaturatingTruncate < u64 > > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_trunc_sat_f64_s . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < double , i64 , Operators : : SaturatingTruncate < i64 > > ( configuration ) ;
2021-06-04 21:54:20 +10:00
case Instructions : : i64_trunc_sat_f64_u . value ( ) :
2021-08-09 02:55:01 +04:30
return unary_operation < double , i64 , Operators : : SaturatingTruncate < u64 > > ( configuration ) ;
2023-06-12 13:38:22 +03:30
case Instructions : : v128_const . value ( ) :
2024-08-02 20:51:40 -07:00
configuration . value_stack ( ) . append ( Value ( instruction . arguments ( ) . get < u128 > ( ) ) ) ;
2023-06-12 13:38:22 +03:30
return ;
case Instructions : : v128_load . value ( ) :
return load_and_push < u128 , u128 > ( configuration , instruction ) ;
case Instructions : : v128_load8x8_s . value ( ) :
return load_and_push_mxn < 8 , 8 , MakeSigned > ( configuration , instruction ) ;
case Instructions : : v128_load8x8_u . value ( ) :
return load_and_push_mxn < 8 , 8 , MakeUnsigned > ( configuration , instruction ) ;
case Instructions : : v128_load16x4_s . value ( ) :
return load_and_push_mxn < 16 , 4 , MakeSigned > ( configuration , instruction ) ;
case Instructions : : v128_load16x4_u . value ( ) :
return load_and_push_mxn < 16 , 4 , MakeUnsigned > ( configuration , instruction ) ;
case Instructions : : v128_load32x2_s . value ( ) :
return load_and_push_mxn < 32 , 2 , MakeSigned > ( configuration , instruction ) ;
case Instructions : : v128_load32x2_u . value ( ) :
return load_and_push_mxn < 32 , 2 , MakeUnsigned > ( configuration , instruction ) ;
case Instructions : : v128_load8_splat . value ( ) :
return load_and_push_m_splat < 8 > ( configuration , instruction ) ;
case Instructions : : v128_load16_splat . value ( ) :
return load_and_push_m_splat < 16 > ( configuration , instruction ) ;
case Instructions : : v128_load32_splat . value ( ) :
return load_and_push_m_splat < 32 > ( configuration , instruction ) ;
case Instructions : : v128_load64_splat . value ( ) :
return load_and_push_m_splat < 64 > ( configuration , instruction ) ;
case Instructions : : i8x16_splat . value ( ) :
return pop_and_push_m_splat < 8 , NativeIntegralType > ( configuration , instruction ) ;
case Instructions : : i16x8_splat . value ( ) :
return pop_and_push_m_splat < 16 , NativeIntegralType > ( configuration , instruction ) ;
case Instructions : : i32x4_splat . value ( ) :
return pop_and_push_m_splat < 32 , NativeIntegralType > ( configuration , instruction ) ;
case Instructions : : i64x2_splat . value ( ) :
return pop_and_push_m_splat < 64 , NativeIntegralType > ( configuration , instruction ) ;
case Instructions : : f32x4_splat . value ( ) :
return pop_and_push_m_splat < 32 , NativeFloatingType > ( configuration , instruction ) ;
case Instructions : : f64x2_splat . value ( ) :
return pop_and_push_m_splat < 64 , NativeFloatingType > ( configuration , instruction ) ;
case Instructions : : i8x16_shuffle . value ( ) : {
2024-07-23 10:08:55 -07:00
auto & arg = instruction . arguments ( ) . get < Instruction : : ShuffleArgument > ( ) ;
2024-07-23 10:16:32 -07:00
auto b = pop_vector < u8 , MakeUnsigned > ( configuration ) ;
auto a = pop_vector < u8 , MakeUnsigned > ( configuration ) ;
2024-07-23 10:08:55 -07:00
using VectorType = Native128ByteVectorOf < u8 , MakeUnsigned > ;
VectorType result ;
for ( size_t i = 0 ; i < 16 ; + + i )
if ( arg . lanes [ i ] < 16 )
result [ i ] = a [ arg . lanes [ i ] ] ;
else
result [ i ] = b [ arg . lanes [ i ] - 16 ] ;
2024-08-02 20:51:40 -07:00
configuration . value_stack ( ) . append ( Value ( bit_cast < u128 > ( result ) ) ) ;
2023-06-12 13:38:22 +03:30
return ;
}
case Instructions : : v128_store . value ( ) :
return pop_and_store < u128 , u128 > ( configuration , instruction ) ;
case Instructions : : i8x16_shl . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorShiftLeft < 16 > , i32 > ( configuration ) ;
case Instructions : : i8x16_shr_u . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorShiftRight < 16 , MakeUnsigned > , i32 > ( configuration ) ;
case Instructions : : i8x16_shr_s . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorShiftRight < 16 , MakeSigned > , i32 > ( configuration ) ;
case Instructions : : i16x8_shl . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorShiftLeft < 8 > , i32 > ( configuration ) ;
case Instructions : : i16x8_shr_u . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorShiftRight < 8 , MakeUnsigned > , i32 > ( configuration ) ;
case Instructions : : i16x8_shr_s . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorShiftRight < 8 , MakeSigned > , i32 > ( configuration ) ;
case Instructions : : i32x4_shl . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorShiftLeft < 4 > , i32 > ( configuration ) ;
case Instructions : : i32x4_shr_u . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorShiftRight < 4 , MakeUnsigned > , i32 > ( configuration ) ;
case Instructions : : i32x4_shr_s . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorShiftRight < 4 , MakeSigned > , i32 > ( configuration ) ;
case Instructions : : i64x2_shl . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorShiftLeft < 2 > , i32 > ( configuration ) ;
case Instructions : : i64x2_shr_u . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorShiftRight < 2 , MakeUnsigned > , i32 > ( configuration ) ;
case Instructions : : i64x2_shr_s . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorShiftRight < 2 , MakeSigned > , i32 > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i8x16_swizzle . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorSwizzle > ( configuration ) ;
case Instructions : : i8x16_extract_lane_s . value ( ) :
return unary_operation < u128 , i8 , Operators : : VectorExtractLane < 16 , MakeSigned > > ( configuration , instruction . arguments ( ) . get < Instruction : : LaneIndex > ( ) . lane ) ;
case Instructions : : i8x16_extract_lane_u . value ( ) :
return unary_operation < u128 , u8 , Operators : : VectorExtractLane < 16 , MakeUnsigned > > ( configuration , instruction . arguments ( ) . get < Instruction : : LaneIndex > ( ) . lane ) ;
case Instructions : : i16x8_extract_lane_s . value ( ) :
return unary_operation < u128 , i16 , Operators : : VectorExtractLane < 8 , MakeSigned > > ( configuration , instruction . arguments ( ) . get < Instruction : : LaneIndex > ( ) . lane ) ;
case Instructions : : i16x8_extract_lane_u . value ( ) :
return unary_operation < u128 , u16 , Operators : : VectorExtractLane < 8 , MakeUnsigned > > ( configuration , instruction . arguments ( ) . get < Instruction : : LaneIndex > ( ) . lane ) ;
case Instructions : : i32x4_extract_lane . value ( ) :
return unary_operation < u128 , i32 , Operators : : VectorExtractLane < 4 , MakeSigned > > ( configuration , instruction . arguments ( ) . get < Instruction : : LaneIndex > ( ) . lane ) ;
case Instructions : : i64x2_extract_lane . value ( ) :
return unary_operation < u128 , i64 , Operators : : VectorExtractLane < 2 , MakeSigned > > ( configuration , instruction . arguments ( ) . get < Instruction : : LaneIndex > ( ) . lane ) ;
case Instructions : : f32x4_extract_lane . value ( ) :
return unary_operation < u128 , float , Operators : : VectorExtractLaneFloat < 4 > > ( configuration , instruction . arguments ( ) . get < Instruction : : LaneIndex > ( ) . lane ) ;
case Instructions : : f64x2_extract_lane . value ( ) :
return unary_operation < u128 , double , Operators : : VectorExtractLaneFloat < 2 > > ( configuration , instruction . arguments ( ) . get < Instruction : : LaneIndex > ( ) . lane ) ;
case Instructions : : i8x16_replace_lane . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorReplaceLane < 16 , i32 > , i32 > ( configuration , instruction . arguments ( ) . get < Instruction : : LaneIndex > ( ) . lane ) ;
case Instructions : : i16x8_replace_lane . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorReplaceLane < 8 , i32 > , i32 > ( configuration , instruction . arguments ( ) . get < Instruction : : LaneIndex > ( ) . lane ) ;
case Instructions : : i32x4_replace_lane . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorReplaceLane < 4 > , i32 > ( configuration , instruction . arguments ( ) . get < Instruction : : LaneIndex > ( ) . lane ) ;
case Instructions : : i64x2_replace_lane . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorReplaceLane < 2 > , i64 > ( configuration , instruction . arguments ( ) . get < Instruction : : LaneIndex > ( ) . lane ) ;
case Instructions : : f32x4_replace_lane . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorReplaceLane < 4 , float > , float > ( configuration , instruction . arguments ( ) . get < Instruction : : LaneIndex > ( ) . lane ) ;
case Instructions : : f64x2_replace_lane . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorReplaceLane < 2 , double > , double > ( configuration , instruction . arguments ( ) . get < Instruction : : LaneIndex > ( ) . lane ) ;
case Instructions : : i8x16_eq . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 16 , Operators : : Equals > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i8x16_ne . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 16 , Operators : : NotEquals > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i8x16_lt_s . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 16 , Operators : : LessThan , MakeSigned > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i8x16_lt_u . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 16 , Operators : : LessThan , MakeUnsigned > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i8x16_gt_s . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 16 , Operators : : GreaterThan , MakeSigned > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i8x16_gt_u . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 16 , Operators : : GreaterThan , MakeUnsigned > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i8x16_le_s . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 16 , Operators : : LessThanOrEquals , MakeSigned > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i8x16_le_u . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 16 , Operators : : LessThanOrEquals , MakeUnsigned > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i8x16_ge_s . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 16 , Operators : : GreaterThanOrEquals , MakeSigned > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i8x16_ge_u . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 16 , Operators : : GreaterThanOrEquals , MakeUnsigned > > ( configuration ) ;
2024-06-13 22:59:55 +02:00
case Instructions : : i8x16_abs . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorIntegerUnaryOp < 16 , Operators : : Absolute > > ( configuration ) ;
case Instructions : : i8x16_neg . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorIntegerUnaryOp < 16 , Operators : : Negate > > ( configuration ) ;
case Instructions : : i8x16_all_true . value ( ) :
return unary_operation < u128 , i32 , Operators : : VectorAllTrue < 16 > > ( configuration ) ;
case Instructions : : i8x16_popcnt . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorIntegerUnaryOp < 16 , Operators : : PopCount > > ( configuration ) ;
case Instructions : : i8x16_add . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 16 , Operators : : Add > > ( configuration ) ;
case Instructions : : i8x16_sub . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 16 , Operators : : Subtract > > ( configuration ) ;
case Instructions : : i8x16_avgr_u . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 16 , Operators : : Average , MakeUnsigned > > ( configuration ) ;
case Instructions : : i8x16_add_sat_s . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 16 , Operators : : SaturatingOp < i8 , Operators : : Add > , MakeSigned > > ( configuration ) ;
case Instructions : : i8x16_add_sat_u . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 16 , Operators : : SaturatingOp < u8 , Operators : : Add > , MakeUnsigned > > ( configuration ) ;
case Instructions : : i8x16_sub_sat_s . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 16 , Operators : : SaturatingOp < i8 , Operators : : Subtract > , MakeSigned > > ( configuration ) ;
case Instructions : : i8x16_sub_sat_u . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 16 , Operators : : SaturatingOp < u8 , Operators : : Subtract > , MakeUnsigned > > ( configuration ) ;
case Instructions : : i8x16_min_s . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 16 , Operators : : Minimum , MakeSigned > > ( configuration ) ;
case Instructions : : i8x16_min_u . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 16 , Operators : : Minimum , MakeUnsigned > > ( configuration ) ;
case Instructions : : i8x16_max_s . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 16 , Operators : : Maximum , MakeSigned > > ( configuration ) ;
case Instructions : : i8x16_max_u . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 16 , Operators : : Maximum , MakeUnsigned > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i16x8_eq . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 8 , Operators : : Equals > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i16x8_ne . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 8 , Operators : : NotEquals > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i16x8_lt_s . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 8 , Operators : : LessThan , MakeSigned > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i16x8_lt_u . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 8 , Operators : : LessThan , MakeUnsigned > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i16x8_gt_s . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 8 , Operators : : GreaterThan , MakeSigned > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i16x8_gt_u . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 8 , Operators : : GreaterThan , MakeUnsigned > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i16x8_le_s . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 8 , Operators : : LessThanOrEquals , MakeSigned > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i16x8_le_u . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 8 , Operators : : LessThanOrEquals , MakeUnsigned > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i16x8_ge_s . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 8 , Operators : : GreaterThanOrEquals , MakeSigned > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i16x8_ge_u . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 8 , Operators : : GreaterThanOrEquals , MakeUnsigned > > ( configuration ) ;
2024-06-13 22:59:55 +02:00
case Instructions : : i16x8_abs . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorIntegerUnaryOp < 8 , Operators : : Absolute > > ( configuration ) ;
case Instructions : : i16x8_neg . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorIntegerUnaryOp < 8 , Operators : : Negate > > ( configuration ) ;
case Instructions : : i16x8_all_true . value ( ) :
return unary_operation < u128 , i32 , Operators : : VectorAllTrue < 8 > > ( configuration ) ;
case Instructions : : i16x8_add . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 8 , Operators : : Add > > ( configuration ) ;
case Instructions : : i16x8_sub . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 8 , Operators : : Subtract > > ( configuration ) ;
case Instructions : : i16x8_mul . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 8 , Operators : : Multiply > > ( configuration ) ;
case Instructions : : i16x8_avgr_u . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 8 , Operators : : Average , MakeUnsigned > > ( configuration ) ;
case Instructions : : i16x8_add_sat_s . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 8 , Operators : : SaturatingOp < i16 , Operators : : Add > , MakeSigned > > ( configuration ) ;
case Instructions : : i16x8_add_sat_u . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 8 , Operators : : SaturatingOp < u16 , Operators : : Add > , MakeUnsigned > > ( configuration ) ;
case Instructions : : i16x8_sub_sat_s . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 8 , Operators : : SaturatingOp < i16 , Operators : : Subtract > , MakeSigned > > ( configuration ) ;
case Instructions : : i16x8_sub_sat_u . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 8 , Operators : : SaturatingOp < u16 , Operators : : Subtract > , MakeUnsigned > > ( configuration ) ;
case Instructions : : i16x8_min_s . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 8 , Operators : : Minimum , MakeSigned > > ( configuration ) ;
case Instructions : : i16x8_min_u . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 8 , Operators : : Minimum , MakeUnsigned > > ( configuration ) ;
case Instructions : : i16x8_max_s . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 8 , Operators : : Maximum , MakeSigned > > ( configuration ) ;
case Instructions : : i16x8_max_u . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 8 , Operators : : Maximum , MakeUnsigned > > ( configuration ) ;
case Instructions : : i16x8_extend_low_i8x16_s . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorIntegerExt < 8 , Operators : : VectorExt : : Low , MakeSigned > > ( configuration ) ;
case Instructions : : i16x8_extend_high_i8x16_s . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorIntegerExt < 8 , Operators : : VectorExt : : High , MakeSigned > > ( configuration ) ;
case Instructions : : i16x8_extend_low_i8x16_u . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorIntegerExt < 8 , Operators : : VectorExt : : Low , MakeUnsigned > > ( configuration ) ;
case Instructions : : i16x8_extend_high_i8x16_u . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorIntegerExt < 8 , Operators : : VectorExt : : High , MakeUnsigned > > ( configuration ) ;
case Instructions : : i16x8_extadd_pairwise_i8x16_s . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorIntegerExtOpPairwise < 8 , Operators : : Add , MakeSigned > > ( configuration ) ;
case Instructions : : i16x8_extadd_pairwise_i8x16_u . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorIntegerExtOpPairwise < 8 , Operators : : Add , MakeUnsigned > > ( configuration ) ;
case Instructions : : i16x8_extmul_low_i8x16_s . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerExtOp < 8 , Operators : : Multiply , Operators : : VectorExt : : Low , MakeSigned > > ( configuration ) ;
case Instructions : : i16x8_extmul_high_i8x16_s . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerExtOp < 8 , Operators : : Multiply , Operators : : VectorExt : : High , MakeSigned > > ( configuration ) ;
case Instructions : : i16x8_extmul_low_i8x16_u . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerExtOp < 8 , Operators : : Multiply , Operators : : VectorExt : : Low , MakeUnsigned > > ( configuration ) ;
case Instructions : : i16x8_extmul_high_i8x16_u . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerExtOp < 8 , Operators : : Multiply , Operators : : VectorExt : : High , MakeUnsigned > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i32x4_eq . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 4 , Operators : : Equals > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i32x4_ne . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 4 , Operators : : NotEquals > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i32x4_lt_s . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 4 , Operators : : LessThan , MakeSigned > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i32x4_lt_u . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 4 , Operators : : LessThan , MakeUnsigned > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i32x4_gt_s . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 4 , Operators : : GreaterThan , MakeSigned > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i32x4_gt_u . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 4 , Operators : : GreaterThan , MakeUnsigned > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i32x4_le_s . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 4 , Operators : : LessThanOrEquals , MakeSigned > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i32x4_le_u . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 4 , Operators : : LessThanOrEquals , MakeUnsigned > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i32x4_ge_s . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 4 , Operators : : GreaterThanOrEquals , MakeSigned > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i32x4_ge_u . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 4 , Operators : : GreaterThanOrEquals , MakeUnsigned > > ( configuration ) ;
2024-06-13 22:59:55 +02:00
case Instructions : : i32x4_abs . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorIntegerUnaryOp < 4 , Operators : : Absolute > > ( configuration ) ;
case Instructions : : i32x4_neg . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorIntegerUnaryOp < 4 , Operators : : Negate , MakeUnsigned > > ( configuration ) ;
case Instructions : : i32x4_all_true . value ( ) :
return unary_operation < u128 , i32 , Operators : : VectorAllTrue < 4 > > ( configuration ) ;
case Instructions : : i32x4_add . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 4 , Operators : : Add , MakeUnsigned > > ( configuration ) ;
case Instructions : : i32x4_sub . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 4 , Operators : : Subtract , MakeUnsigned > > ( configuration ) ;
case Instructions : : i32x4_mul . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 4 , Operators : : Multiply , MakeUnsigned > > ( configuration ) ;
case Instructions : : i32x4_min_s . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 4 , Operators : : Minimum , MakeSigned > > ( configuration ) ;
case Instructions : : i32x4_min_u . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 4 , Operators : : Minimum , MakeUnsigned > > ( configuration ) ;
case Instructions : : i32x4_max_s . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 4 , Operators : : Maximum , MakeSigned > > ( configuration ) ;
case Instructions : : i32x4_max_u . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 4 , Operators : : Maximum , MakeUnsigned > > ( configuration ) ;
case Instructions : : i32x4_extend_low_i16x8_s . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorIntegerExt < 4 , Operators : : VectorExt : : Low , MakeSigned > > ( configuration ) ;
case Instructions : : i32x4_extend_high_i16x8_s . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorIntegerExt < 4 , Operators : : VectorExt : : High , MakeSigned > > ( configuration ) ;
case Instructions : : i32x4_extend_low_i16x8_u . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorIntegerExt < 4 , Operators : : VectorExt : : Low , MakeUnsigned > > ( configuration ) ;
case Instructions : : i32x4_extend_high_i16x8_u . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorIntegerExt < 4 , Operators : : VectorExt : : High , MakeUnsigned > > ( configuration ) ;
case Instructions : : i32x4_extadd_pairwise_i16x8_s . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorIntegerExtOpPairwise < 4 , Operators : : Add , MakeSigned > > ( configuration ) ;
case Instructions : : i32x4_extadd_pairwise_i16x8_u . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorIntegerExtOpPairwise < 4 , Operators : : Add , MakeUnsigned > > ( configuration ) ;
case Instructions : : i32x4_extmul_low_i16x8_s . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerExtOp < 4 , Operators : : Multiply , Operators : : VectorExt : : Low , MakeSigned > > ( configuration ) ;
case Instructions : : i32x4_extmul_high_i16x8_s . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerExtOp < 4 , Operators : : Multiply , Operators : : VectorExt : : High , MakeSigned > > ( configuration ) ;
case Instructions : : i32x4_extmul_low_i16x8_u . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerExtOp < 4 , Operators : : Multiply , Operators : : VectorExt : : Low , MakeUnsigned > > ( configuration ) ;
case Instructions : : i32x4_extmul_high_i16x8_u . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerExtOp < 4 , Operators : : Multiply , Operators : : VectorExt : : High , MakeUnsigned > > ( configuration ) ;
case Instructions : : i64x2_eq . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 2 , Operators : : Equals > > ( configuration ) ;
case Instructions : : i64x2_ne . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 2 , Operators : : NotEquals > > ( configuration ) ;
case Instructions : : i64x2_lt_s . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 2 , Operators : : LessThan , MakeSigned > > ( configuration ) ;
case Instructions : : i64x2_gt_s . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 2 , Operators : : GreaterThan , MakeSigned > > ( configuration ) ;
case Instructions : : i64x2_le_s . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 2 , Operators : : LessThanOrEquals , MakeSigned > > ( configuration ) ;
case Instructions : : i64x2_ge_s . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorCmpOp < 2 , Operators : : GreaterThanOrEquals , MakeSigned > > ( configuration ) ;
case Instructions : : i64x2_abs . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorIntegerUnaryOp < 2 , Operators : : Absolute > > ( configuration ) ;
case Instructions : : i64x2_neg . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorIntegerUnaryOp < 2 , Operators : : Negate , MakeUnsigned > > ( configuration ) ;
case Instructions : : i64x2_all_true . value ( ) :
return unary_operation < u128 , i32 , Operators : : VectorAllTrue < 2 > > ( configuration ) ;
case Instructions : : i64x2_add . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 2 , Operators : : Add , MakeUnsigned > > ( configuration ) ;
case Instructions : : i64x2_sub . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 2 , Operators : : Subtract , MakeUnsigned > > ( configuration ) ;
case Instructions : : i64x2_mul . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 2 , Operators : : Multiply , MakeUnsigned > > ( configuration ) ;
case Instructions : : i64x2_extend_low_i32x4_s . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorIntegerExt < 2 , Operators : : VectorExt : : Low , MakeSigned > > ( configuration ) ;
case Instructions : : i64x2_extend_high_i32x4_s . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorIntegerExt < 2 , Operators : : VectorExt : : High , MakeSigned > > ( configuration ) ;
case Instructions : : i64x2_extend_low_i32x4_u . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorIntegerExt < 2 , Operators : : VectorExt : : Low , MakeUnsigned > > ( configuration ) ;
case Instructions : : i64x2_extend_high_i32x4_u . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorIntegerExt < 2 , Operators : : VectorExt : : High , MakeUnsigned > > ( configuration ) ;
case Instructions : : i64x2_extmul_low_i32x4_s . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerExtOp < 2 , Operators : : Multiply , Operators : : VectorExt : : Low , MakeSigned > > ( configuration ) ;
case Instructions : : i64x2_extmul_high_i32x4_s . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerExtOp < 2 , Operators : : Multiply , Operators : : VectorExt : : High , MakeSigned > > ( configuration ) ;
case Instructions : : i64x2_extmul_low_i32x4_u . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerExtOp < 2 , Operators : : Multiply , Operators : : VectorExt : : Low , MakeUnsigned > > ( configuration ) ;
case Instructions : : i64x2_extmul_high_i32x4_u . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerExtOp < 2 , Operators : : Multiply , Operators : : VectorExt : : High , MakeUnsigned > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : f32x4_eq . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorFloatCmpOp < 4 , Operators : : Equals > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : f32x4_ne . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorFloatCmpOp < 4 , Operators : : NotEquals > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : f32x4_lt . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorFloatCmpOp < 4 , Operators : : LessThan > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : f32x4_gt . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorFloatCmpOp < 4 , Operators : : GreaterThan > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : f32x4_le . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorFloatCmpOp < 4 , Operators : : LessThanOrEquals > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : f32x4_ge . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorFloatCmpOp < 4 , Operators : : GreaterThanOrEquals > > ( configuration ) ;
2024-06-08 23:18:21 +02:00
case Instructions : : f32x4_min . value ( ) :
2024-07-12 14:54:10 -07:00
return binary_numeric_operation < u128 , u128 , Operators : : VectorFloatBinaryOp < 4 , Operators : : Minimum > > ( configuration ) ;
2024-06-08 23:18:21 +02:00
case Instructions : : f32x4_max . value ( ) :
2024-07-12 14:54:10 -07:00
return binary_numeric_operation < u128 , u128 , Operators : : VectorFloatBinaryOp < 4 , Operators : : Maximum > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : f64x2_eq . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorFloatCmpOp < 2 , Operators : : Equals > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : f64x2_ne . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorFloatCmpOp < 2 , Operators : : NotEquals > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : f64x2_lt . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorFloatCmpOp < 2 , Operators : : LessThan > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : f64x2_gt . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorFloatCmpOp < 2 , Operators : : GreaterThan > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : f64x2_le . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorFloatCmpOp < 2 , Operators : : LessThanOrEquals > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : f64x2_ge . value ( ) :
2024-02-18 06:16:44 +03:30
return binary_numeric_operation < u128 , u128 , Operators : : VectorFloatCmpOp < 2 , Operators : : GreaterThanOrEquals > > ( configuration ) ;
2024-06-08 23:18:21 +02:00
case Instructions : : f64x2_min . value ( ) :
2024-07-12 14:54:10 -07:00
return binary_numeric_operation < u128 , u128 , Operators : : VectorFloatBinaryOp < 2 , Operators : : Minimum > > ( configuration ) ;
2024-06-08 23:18:21 +02:00
case Instructions : : f64x2_max . value ( ) :
2024-07-12 14:54:10 -07:00
return binary_numeric_operation < u128 , u128 , Operators : : VectorFloatBinaryOp < 2 , Operators : : Maximum > > ( configuration ) ;
2024-06-08 23:18:21 +02:00
case Instructions : : f32x4_div . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorFloatBinaryOp < 4 , Operators : : Divide > > ( configuration ) ;
case Instructions : : f32x4_mul . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorFloatBinaryOp < 4 , Operators : : Multiply > > ( configuration ) ;
case Instructions : : f32x4_sub . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorFloatBinaryOp < 4 , Operators : : Subtract > > ( configuration ) ;
case Instructions : : f32x4_add . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorFloatBinaryOp < 4 , Operators : : Add > > ( configuration ) ;
case Instructions : : f32x4_pmin . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorFloatBinaryOp < 4 , Operators : : PseudoMinimum > > ( configuration ) ;
case Instructions : : f32x4_pmax . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorFloatBinaryOp < 4 , Operators : : PseudoMaximum > > ( configuration ) ;
case Instructions : : f64x2_div . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorFloatBinaryOp < 2 , Operators : : Divide > > ( configuration ) ;
case Instructions : : f64x2_mul . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorFloatBinaryOp < 2 , Operators : : Multiply > > ( configuration ) ;
case Instructions : : f64x2_sub . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorFloatBinaryOp < 2 , Operators : : Subtract > > ( configuration ) ;
case Instructions : : f64x2_add . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorFloatBinaryOp < 2 , Operators : : Add > > ( configuration ) ;
case Instructions : : f64x2_pmin . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorFloatBinaryOp < 2 , Operators : : PseudoMinimum > > ( configuration ) ;
case Instructions : : f64x2_pmax . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorFloatBinaryOp < 2 , Operators : : PseudoMaximum > > ( configuration ) ;
case Instructions : : f32x4_ceil . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorFloatUnaryOp < 4 , Operators : : Ceil > > ( configuration ) ;
case Instructions : : f32x4_floor . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorFloatUnaryOp < 4 , Operators : : Floor > > ( configuration ) ;
case Instructions : : f32x4_trunc . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorFloatUnaryOp < 4 , Operators : : Truncate > > ( configuration ) ;
case Instructions : : f32x4_nearest . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorFloatUnaryOp < 4 , Operators : : NearbyIntegral > > ( configuration ) ;
case Instructions : : f32x4_sqrt . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorFloatUnaryOp < 4 , Operators : : SquareRoot > > ( configuration ) ;
case Instructions : : f32x4_neg . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorFloatUnaryOp < 4 , Operators : : Negate > > ( configuration ) ;
case Instructions : : f32x4_abs . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorFloatUnaryOp < 4 , Operators : : Absolute > > ( configuration ) ;
case Instructions : : f64x2_ceil . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorFloatUnaryOp < 2 , Operators : : Ceil > > ( configuration ) ;
case Instructions : : f64x2_floor . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorFloatUnaryOp < 2 , Operators : : Floor > > ( configuration ) ;
case Instructions : : f64x2_trunc . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorFloatUnaryOp < 2 , Operators : : Truncate > > ( configuration ) ;
case Instructions : : f64x2_nearest . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorFloatUnaryOp < 2 , Operators : : NearbyIntegral > > ( configuration ) ;
case Instructions : : f64x2_sqrt . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorFloatUnaryOp < 2 , Operators : : SquareRoot > > ( configuration ) ;
case Instructions : : f64x2_neg . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorFloatUnaryOp < 2 , Operators : : Negate > > ( configuration ) ;
case Instructions : : f64x2_abs . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorFloatUnaryOp < 2 , Operators : : Absolute > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : v128_and . value ( ) :
2024-07-10 13:42:46 -07:00
return binary_numeric_operation < u128 , u128 , Operators : : BitAnd > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : v128_or . value ( ) :
2024-07-10 13:42:46 -07:00
return binary_numeric_operation < u128 , u128 , Operators : : BitOr > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : v128_xor . value ( ) :
2024-07-10 13:42:46 -07:00
return binary_numeric_operation < u128 , u128 , Operators : : BitXor > ( configuration ) ;
case Instructions : : v128_not . value ( ) :
return unary_operation < u128 , u128 , Operators : : BitNot > ( configuration ) ;
case Instructions : : v128_andnot . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : BitAndNot > ( configuration ) ;
case Instructions : : v128_bitselect . value ( ) : {
2024-08-04 08:06:50 -07:00
auto mask = configuration . value_stack ( ) . take_last ( ) . to < u128 > ( ) ;
auto false_vector = configuration . value_stack ( ) . take_last ( ) . to < u128 > ( ) ;
auto true_vector = configuration . value_stack ( ) . take_last ( ) . to < u128 > ( ) ;
2024-07-10 13:42:46 -07:00
u128 result = ( true_vector & mask ) | ( false_vector & ~ mask ) ;
2024-08-02 20:51:40 -07:00
configuration . value_stack ( ) . append ( Value ( result ) ) ;
2024-07-10 13:42:46 -07:00
return ;
}
2024-07-14 21:09:09 -07:00
case Instructions : : v128_any_true . value ( ) : {
2024-08-04 08:06:50 -07:00
auto vector = configuration . value_stack ( ) . take_last ( ) . to < u128 > ( ) ;
2024-08-02 20:51:40 -07:00
configuration . value_stack ( ) . append ( Value ( static_cast < i32 > ( vector ! = 0 ) ) ) ;
2024-07-14 21:09:09 -07:00
return ;
}
2024-02-07 17:31:38 +03:30
case Instructions : : v128_load8_lane . value ( ) :
2024-07-14 21:09:09 -07:00
return load_and_push_lane_n < 8 > ( configuration , instruction ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : v128_load16_lane . value ( ) :
2024-07-14 21:09:09 -07:00
return load_and_push_lane_n < 16 > ( configuration , instruction ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : v128_load32_lane . value ( ) :
2024-07-14 21:09:09 -07:00
return load_and_push_lane_n < 32 > ( configuration , instruction ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : v128_load64_lane . value ( ) :
2024-07-14 21:09:09 -07:00
return load_and_push_lane_n < 64 > ( configuration , instruction ) ;
case Instructions : : v128_load32_zero . value ( ) :
return load_and_push_zero_n < 32 > ( configuration , instruction ) ;
case Instructions : : v128_load64_zero . value ( ) :
return load_and_push_zero_n < 64 > ( configuration , instruction ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : v128_store8_lane . value ( ) :
2024-07-14 21:09:09 -07:00
return pop_and_store_lane_n < 8 > ( configuration , instruction ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : v128_store16_lane . value ( ) :
2024-07-14 21:09:09 -07:00
return pop_and_store_lane_n < 16 > ( configuration , instruction ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : v128_store32_lane . value ( ) :
2024-07-14 21:09:09 -07:00
return pop_and_store_lane_n < 32 > ( configuration , instruction ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : v128_store64_lane . value ( ) :
2024-07-14 21:09:09 -07:00
return pop_and_store_lane_n < 64 > ( configuration , instruction ) ;
2024-07-17 20:40:58 -07:00
case Instructions : : i32x4_trunc_sat_f32x4_s . value ( ) :
2024-07-19 08:19:31 -07:00
return unary_operation < u128 , u128 , Operators : : VectorConvertOp < 4 , 4 , u32 , f32 , Operators : : SaturatingTruncate < i32 > > > ( configuration ) ;
2024-07-17 20:40:58 -07:00
case Instructions : : i32x4_trunc_sat_f32x4_u . value ( ) :
2024-07-19 08:19:31 -07:00
return unary_operation < u128 , u128 , Operators : : VectorConvertOp < 4 , 4 , u32 , f32 , Operators : : SaturatingTruncate < u32 > > > ( configuration ) ;
2024-07-17 20:40:58 -07:00
case Instructions : : i8x16_bitmask . value ( ) :
return unary_operation < u128 , i32 , Operators : : VectorBitmask < 16 > > ( configuration ) ;
case Instructions : : i16x8_bitmask . value ( ) :
return unary_operation < u128 , i32 , Operators : : VectorBitmask < 8 > > ( configuration ) ;
case Instructions : : i32x4_bitmask . value ( ) :
return unary_operation < u128 , i32 , Operators : : VectorBitmask < 4 > > ( configuration ) ;
case Instructions : : i64x2_bitmask . value ( ) :
return unary_operation < u128 , i32 , Operators : : VectorBitmask < 2 > > ( configuration ) ;
2024-07-18 19:41:08 -07:00
case Instructions : : i32x4_dot_i16x8_s . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorDotProduct < 4 > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i8x16_narrow_i16x8_s . value ( ) :
2024-07-18 19:41:08 -07:00
return binary_numeric_operation < u128 , u128 , Operators : : VectorNarrow < 16 , i8 > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i8x16_narrow_i16x8_u . value ( ) :
2024-07-18 19:41:08 -07:00
return binary_numeric_operation < u128 , u128 , Operators : : VectorNarrow < 16 , u8 > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i16x8_narrow_i32x4_s . value ( ) :
2024-07-18 19:41:08 -07:00
return binary_numeric_operation < u128 , u128 , Operators : : VectorNarrow < 8 , i16 > > ( configuration ) ;
2024-02-07 17:31:38 +03:30
case Instructions : : i16x8_narrow_i32x4_u . value ( ) :
2024-07-18 19:41:08 -07:00
return binary_numeric_operation < u128 , u128 , Operators : : VectorNarrow < 8 , u16 > > ( configuration ) ;
case Instructions : : i16x8_q15mulr_sat_s . value ( ) :
return binary_numeric_operation < u128 , u128 , Operators : : VectorIntegerBinaryOp < 8 , Operators : : SaturatingOp < i16 , Operators : : Q15Mul > , MakeSigned > > ( configuration ) ;
2024-07-17 20:40:58 -07:00
case Instructions : : f32x4_convert_i32x4_s . value ( ) :
2024-07-19 08:19:31 -07:00
return unary_operation < u128 , u128 , Operators : : VectorConvertOp < 4 , 4 , u32 , i32 , Operators : : Convert < f32 > > > ( configuration ) ;
2024-07-17 20:40:58 -07:00
case Instructions : : f32x4_convert_i32x4_u . value ( ) :
2024-07-19 08:19:31 -07:00
return unary_operation < u128 , u128 , Operators : : VectorConvertOp < 4 , 4 , u32 , u32 , Operators : : Convert < f32 > > > ( configuration ) ;
case Instructions : : f64x2_convert_low_i32x4_s . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorConvertOp < 2 , 4 , u64 , i32 , Operators : : Convert < f64 > > > ( configuration ) ;
case Instructions : : f64x2_convert_low_i32x4_u . value ( ) :
return unary_operation < u128 , u128 , Operators : : VectorConvertOp < 2 , 4 , u64 , u32 , Operators : : Convert < f64 > > > ( configuration ) ;
2024-07-18 19:41:08 -07:00
case Instructions : : f32x4_demote_f64x2_zero . value ( ) :
2024-07-19 08:19:31 -07:00
return unary_operation < u128 , u128 , Operators : : VectorConvertOp < 4 , 2 , u32 , f64 , Operators : : Convert < f32 > > > ( configuration ) ;
2024-07-18 19:41:08 -07:00
case Instructions : : f64x2_promote_low_f32x4 . value ( ) :
2024-07-19 08:19:31 -07:00
return unary_operation < u128 , u128 , Operators : : VectorConvertOp < 2 , 4 , u64 , f32 , Operators : : Convert < f64 > > > ( configuration ) ;
2024-07-18 19:41:08 -07:00
case Instructions : : i32x4_trunc_sat_f64x2_s_zero . value ( ) :
2024-07-19 08:19:31 -07:00
return unary_operation < u128 , u128 , Operators : : VectorConvertOp < 4 , 2 , u32 , f64 , Operators : : SaturatingTruncate < i32 > > > ( configuration ) ;
2024-07-18 19:41:08 -07:00
case Instructions : : i32x4_trunc_sat_f64x2_u_zero . value ( ) :
2024-07-19 08:19:31 -07:00
return unary_operation < u128 , u128 , Operators : : VectorConvertOp < 4 , 2 , u32 , f64 , Operators : : SaturatingTruncate < u32 > > > ( configuration ) ;
2021-06-04 21:54:20 +10:00
}
}
2024-08-02 20:58:15 -07:00
void DebuggerBytecodeInterpreter : : interpret_instruction ( Configuration & configuration , InstructionPointer & ip , Instruction const & instruction )
2021-06-04 21:54:20 +10:00
{
if ( pre_interpret_hook ) {
auto result = pre_interpret_hook ( configuration , ip , instruction ) ;
if ( ! result ) {
2025-04-22 09:48:26 +02:00
m_trap = Trap : : from_string ( " Trapped by user request " ) ;
2021-06-04 21:54:20 +10:00
return ;
}
}
2024-08-02 20:58:15 -07:00
BytecodeInterpreter : : interpret_instruction ( configuration , ip , instruction ) ;
2021-07-16 23:16:14 +04:30
if ( post_interpret_hook ) {
auto result = post_interpret_hook ( configuration , ip , instruction , * this ) ;
if ( ! result ) {
2025-04-22 09:48:26 +02:00
m_trap = Trap : : from_string ( " Trapped by user request " ) ;
2021-07-16 23:16:14 +04:30
return ;
}
}
2021-06-04 21:54:20 +10:00
}
2025-05-13 07:06:33 -04:00
2021-06-04 21:54:20 +10:00
}