mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 07:30:19 +00:00
LibWasm+LibWeb: Parse and validate all Wasm SIMD instructions
This commit is contained in:
parent
b005691497
commit
2462064fcd
Notes:
sideshowbarker
2024-07-16 20:39:14 +09:00
Author: https://github.com/alimpfard Commit: https://github.com/SerenityOS/serenity/commit/2462064fcd Pull-request: https://github.com/SerenityOS/serenity/pull/19623 Reviewed-by: https://github.com/ADKaster Reviewed-by: https://github.com/DanShaders
13 changed files with 2474 additions and 78 deletions
|
@ -711,7 +711,7 @@ if (BUILD_LAGOM)
|
|||
add_executable(test-wasm
|
||||
../../Tests/LibWasm/test-wasm.cpp
|
||||
../../Userland/Libraries/LibTest/JavaScriptTestRunnerMain.cpp)
|
||||
target_link_libraries(test-wasm LibCore LibFileSystem LibTest LibWasm LibJS)
|
||||
target_link_libraries(test-wasm LibCore LibFileSystem LibTest LibWasm LibJS LibCrypto)
|
||||
add_test(
|
||||
NAME WasmParser
|
||||
COMMAND test-wasm --show-progress=false ${CMAKE_CURRENT_BINARY_DIR}/Userland/Libraries/LibWasm/Tests
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
serenity_testjs_test(test-wasm.cpp test-wasm LIBS LibWasm LibJS)
|
||||
serenity_testjs_test(test-wasm.cpp test-wasm LIBS LibWasm LibJS LibCrypto)
|
||||
install(TARGETS test-wasm RUNTIME DESTINATION bin OPTIONAL)
|
||||
|
|
|
@ -173,6 +173,7 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyModule::get_export)
|
|||
[&](auto const& value) -> JS::Value { return JS::Value(static_cast<double>(value)); },
|
||||
[&](i32 value) { return JS::Value(static_cast<double>(value)); },
|
||||
[&](i64 value) -> JS::Value { return JS::BigInt::create(vm, Crypto::SignedBigInteger { value }); },
|
||||
[&](u128 value) -> JS::Value { return JS::BigInt::create(vm, Crypto::SignedBigInteger::import_data(bit_cast<u8 const*>(&value), sizeof(value))); },
|
||||
[&](Wasm::Reference const& reference) -> JS::Value {
|
||||
return reference.ref().visit(
|
||||
[&](const Wasm::Reference::Null&) -> JS::Value { return JS::js_null(); },
|
||||
|
@ -225,6 +226,19 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyModule::wasm_invoke)
|
|||
case Wasm::ValueType::Kind::F64:
|
||||
arguments.append(Wasm::Value(static_cast<double>(double_value)));
|
||||
break;
|
||||
case Wasm::ValueType::Kind::V128: {
|
||||
if (!argument.is_bigint()) {
|
||||
if (argument.is_number())
|
||||
argument = JS::BigInt::create(vm, Crypto::SignedBigInteger { TRY(argument.to_double(vm)) });
|
||||
else
|
||||
argument = TRY(argument.to_bigint(vm));
|
||||
}
|
||||
|
||||
u128 bits;
|
||||
(void)argument.as_bigint().big_integer().export_data({ bit_cast<u8*>(&bits), sizeof(bits) });
|
||||
arguments.append(Wasm::Value(bits));
|
||||
break;
|
||||
}
|
||||
case Wasm::ValueType::Kind::FunctionReference:
|
||||
arguments.append(Wasm::Value(Wasm::Reference { Wasm::Reference::Func { static_cast<u64>(double_value) } }));
|
||||
break;
|
||||
|
@ -255,6 +269,7 @@ JS_DEFINE_NATIVE_FUNCTION(WebAssemblyModule::wasm_invoke)
|
|||
[](auto const& value) { return JS::Value(static_cast<double>(value)); },
|
||||
[](i32 value) { return JS::Value(static_cast<double>(value)); },
|
||||
[&](i64 value) { return JS::Value(JS::BigInt::create(vm, Crypto::SignedBigInteger { value })); },
|
||||
[&](u128 value) { return JS::Value(JS::BigInt::create(vm, Crypto::SignedBigInteger::import_data(bit_cast<u8 const*>(&value), sizeof(value)))); },
|
||||
[](Wasm::Reference const& reference) {
|
||||
return reference.ref().visit(
|
||||
[](const Wasm::Reference::Null&) { return JS::js_null(); },
|
||||
|
|
|
@ -330,6 +330,7 @@ InstantiationResult AbstractMachine::instantiate(Module const& module, Vector<Ex
|
|||
size_t offset = 0;
|
||||
result.values().first().value().visit(
|
||||
[&](auto const& value) { offset = value; },
|
||||
[&](u128 const&) { instantiation_result = InstantiationError { "Data segment offset returned a vector type"sv }; },
|
||||
[&](Reference const&) { instantiation_result = InstantiationError { "Data segment offset returned a reference"sv }; });
|
||||
if (instantiation_result.has_value() && instantiation_result->is_error())
|
||||
return;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <AK/OwnPtr.h>
|
||||
#include <AK/Result.h>
|
||||
#include <AK/StackInfo.h>
|
||||
#include <AK/UFixedBigInt.h>
|
||||
#include <LibWasm/Types.h>
|
||||
|
||||
// NOTE: Special case for Wasm::Result.
|
||||
|
@ -74,7 +75,7 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
using AnyValueType = Variant<i32, i64, float, double, Reference>;
|
||||
using AnyValueType = Variant<i32, i64, float, double, u128, Reference>;
|
||||
explicit Value(AnyValueType value)
|
||||
: m_value(move(value))
|
||||
{
|
||||
|
@ -111,11 +112,20 @@ public:
|
|||
VERIFY(raw_value == 0);
|
||||
m_value = Reference { Reference::Null { ValueType(ValueType::Kind::ExternReference) } };
|
||||
break;
|
||||
case ValueType::Kind::V128:
|
||||
m_value = u128(0ull, bit_cast<u64>(raw_value));
|
||||
break;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
template<SameAs<u128> T>
|
||||
explicit Value(T raw_value)
|
||||
: m_value(raw_value)
|
||||
{
|
||||
}
|
||||
|
||||
ALWAYS_INLINE Value(Value const& value) = default;
|
||||
ALWAYS_INLINE Value(Value&& value) = default;
|
||||
ALWAYS_INLINE Value& operator=(Value&& value) = default;
|
||||
|
@ -158,6 +168,7 @@ public:
|
|||
[](i64) { return ValueType::Kind::I64; },
|
||||
[](float) { return ValueType::Kind::F32; },
|
||||
[](double) { return ValueType::Kind::F64; },
|
||||
[](u128) { return ValueType::Kind::V128; },
|
||||
[&](Reference const& type) {
|
||||
return type.ref().visit(
|
||||
[](Reference::Func const&) { return ValueType::Kind::FunctionReference; },
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -221,6 +221,17 @@ public:
|
|||
return result;
|
||||
}
|
||||
|
||||
template<auto... kinds>
|
||||
ErrorOr<void, ValidationError> take_and_put(Wasm::ValueType::Kind kind, SourceLocation location = SourceLocation::current())
|
||||
{
|
||||
ErrorOr<void, ValidationError> result;
|
||||
if (((result = take(Wasm::ValueType(kinds), location)).is_error(), ...)) {
|
||||
return result;
|
||||
}
|
||||
append(Wasm::ValueType(kind));
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t actual_size() const { return Vector<StackEntry>::size(); }
|
||||
size_t size() const { return m_did_insert_unknown_entry ? static_cast<size_t>(-1) : actual_size(); }
|
||||
|
||||
|
@ -238,7 +249,7 @@ public:
|
|||
};
|
||||
ErrorOr<ExpressionTypeResult, ValidationError> validate(Expression const&, Vector<ValueType> const&);
|
||||
ErrorOr<void, ValidationError> validate(Instruction const& instruction, Stack& stack, bool& is_constant);
|
||||
template<u32 opcode>
|
||||
template<u64 opcode>
|
||||
ErrorOr<void, ValidationError> validate_instruction(Instruction const&, Stack& stack, bool& is_constant);
|
||||
|
||||
// Types
|
||||
|
|
|
@ -15,6 +15,7 @@ static constexpr auto i32_tag = 0x7f;
|
|||
static constexpr auto i64_tag = 0x7e;
|
||||
static constexpr auto f32_tag = 0x7d;
|
||||
static constexpr auto f64_tag = 0x7c;
|
||||
static constexpr auto v128_tag = 0x7b;
|
||||
static constexpr auto function_reference_tag = 0x70;
|
||||
static constexpr auto extern_reference_tag = 0x6f;
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
namespace Wasm {
|
||||
|
||||
AK_TYPEDEF_DISTINCT_ORDERED_ID(u32, OpCode);
|
||||
AK_TYPEDEF_DISTINCT_ORDERED_ID(u64, OpCode);
|
||||
|
||||
namespace Instructions {
|
||||
|
||||
|
@ -198,27 +198,263 @@ namespace Instructions {
|
|||
M(ref_func, 0xd2)
|
||||
|
||||
// These are synthetic opcodes, they are _not_ seen in wasm with these values.
|
||||
#define ENUMERATE_MULTI_BYTE_WASM_OPCODES(M) \
|
||||
M(i32_trunc_sat_f32_s, 0xfc00) \
|
||||
M(i32_trunc_sat_f32_u, 0xfc01) \
|
||||
M(i32_trunc_sat_f64_s, 0xfc02) \
|
||||
M(i32_trunc_sat_f64_u, 0xfc03) \
|
||||
M(i64_trunc_sat_f32_s, 0xfc04) \
|
||||
M(i64_trunc_sat_f32_u, 0xfc05) \
|
||||
M(i64_trunc_sat_f64_s, 0xfc06) \
|
||||
M(i64_trunc_sat_f64_u, 0xfc07) \
|
||||
M(memory_init, 0xfc08) \
|
||||
M(data_drop, 0xfc09) \
|
||||
M(memory_copy, 0xfc0a) \
|
||||
M(memory_fill, 0x0fc0b) \
|
||||
M(table_init, 0xfc0c) \
|
||||
M(elem_drop, 0xfc0d) \
|
||||
M(table_copy, 0xfc0e) \
|
||||
M(table_grow, 0xfc0f) \
|
||||
M(table_size, 0xfc10) \
|
||||
M(table_fill, 0xfc11) \
|
||||
M(structured_else, 0xff00) \
|
||||
M(structured_end, 0xff01)
|
||||
#define ENUMERATE_MULTI_BYTE_WASM_OPCODES(M) \
|
||||
M(i32_trunc_sat_f32_s, 0xfc00000000000000ull) \
|
||||
M(i32_trunc_sat_f32_u, 0xfc00000000000001ull) \
|
||||
M(i32_trunc_sat_f64_s, 0xfc00000000000002ull) \
|
||||
M(i32_trunc_sat_f64_u, 0xfc00000000000003ull) \
|
||||
M(i64_trunc_sat_f32_s, 0xfc00000000000004ull) \
|
||||
M(i64_trunc_sat_f32_u, 0xfc00000000000005ull) \
|
||||
M(i64_trunc_sat_f64_s, 0xfc00000000000006ull) \
|
||||
M(i64_trunc_sat_f64_u, 0xfc00000000000007ull) \
|
||||
M(memory_init, 0xfc00000000000008ull) \
|
||||
M(data_drop, 0xfc00000000000009ull) \
|
||||
M(memory_copy, 0xfc0000000000000aull) \
|
||||
M(memory_fill, 0xfc0000000000000bull) \
|
||||
M(table_init, 0xfc0000000000000cull) \
|
||||
M(elem_drop, 0xfc0000000000000dull) \
|
||||
M(table_copy, 0xfc0000000000000eull) \
|
||||
M(table_grow, 0xfc0000000000000full) \
|
||||
M(table_size, 0xfc00000000000010ull) \
|
||||
M(table_fill, 0xfc00000000000011ull) \
|
||||
M(structured_else, 0xff00000000000000ull) \
|
||||
M(structured_end, 0xff00000000000001ull) \
|
||||
M(v128_load, 0xfd00000000000000ull) \
|
||||
M(v128_load8x8_s, 0xfd00000000000001ull) \
|
||||
M(v128_load8x8_u, 0xfd00000000000002ull) \
|
||||
M(v128_load16x4_s, 0xfd00000000000003ull) \
|
||||
M(v128_load16x4_u, 0xfd00000000000004ull) \
|
||||
M(v128_load32x2_s, 0xfd00000000000005ull) \
|
||||
M(v128_load32x2_u, 0xfd00000000000006ull) \
|
||||
M(v128_load8_splat, 0xfd00000000000007ull) \
|
||||
M(v128_load16_splat, 0xfd00000000000008ull) \
|
||||
M(v128_load32_splat, 0xfd00000000000009ull) \
|
||||
M(v128_load64_splat, 0xfd0000000000000aull) \
|
||||
M(v128_store, 0xfd0000000000000bull) \
|
||||
M(v128_const, 0xfd0000000000000cull) \
|
||||
M(i8x16_shuffle, 0xfd0000000000000dull) \
|
||||
M(i8x16_swizzle, 0xfd0000000000000eull) \
|
||||
M(i8x16_splat, 0xfd0000000000000full) \
|
||||
M(i16x8_splat, 0xfd00000000000010ull) \
|
||||
M(i32x4_splat, 0xfd00000000000011ull) \
|
||||
M(i64x2_splat, 0xfd00000000000012ull) \
|
||||
M(f32x4_splat, 0xfd00000000000013ull) \
|
||||
M(f64x2_splat, 0xfd00000000000014ull) \
|
||||
M(i8x16_extract_lane_s, 0xfd00000000000015ull) \
|
||||
M(i8x16_extract_lane_u, 0xfd00000000000016ull) \
|
||||
M(i8x16_replace_lane, 0xfd00000000000017ull) \
|
||||
M(i16x8_extract_lane_s, 0xfd00000000000018ull) \
|
||||
M(i16x8_extract_lane_u, 0xfd00000000000019ull) \
|
||||
M(i16x8_replace_lane, 0xfd0000000000001aull) \
|
||||
M(i32x4_extract_lane, 0xfd0000000000001bull) \
|
||||
M(i32x4_replace_lane, 0xfd0000000000001cull) \
|
||||
M(i64x2_extract_lane, 0xfd0000000000001dull) \
|
||||
M(i64x2_replace_lane, 0xfd0000000000001eull) \
|
||||
M(f32x4_extract_lane, 0xfd0000000000001full) \
|
||||
M(f32x4_replace_lane, 0xfd00000000000020ull) \
|
||||
M(f64x2_extract_lane, 0xfd00000000000021ull) \
|
||||
M(f64x2_replace_lane, 0xfd00000000000022ull) \
|
||||
M(i8x16_eq, 0xfd00000000000023ull) \
|
||||
M(i8x16_ne, 0xfd00000000000024ull) \
|
||||
M(i8x16_lt_s, 0xfd00000000000025ull) \
|
||||
M(i8x16_lt_u, 0xfd00000000000026ull) \
|
||||
M(i8x16_gt_s, 0xfd00000000000027ull) \
|
||||
M(i8x16_gt_u, 0xfd00000000000028ull) \
|
||||
M(i8x16_le_s, 0xfd00000000000029ull) \
|
||||
M(i8x16_le_u, 0xfd0000000000002aull) \
|
||||
M(i8x16_ge_s, 0xfd0000000000002bull) \
|
||||
M(i8x16_ge_u, 0xfd0000000000002cull) \
|
||||
M(i16x8_eq, 0xfd0000000000002dull) \
|
||||
M(i16x8_ne, 0xfd0000000000002eull) \
|
||||
M(i16x8_lt_s, 0xfd0000000000002full) \
|
||||
M(i16x8_lt_u, 0xfd00000000000030ull) \
|
||||
M(i16x8_gt_s, 0xfd00000000000031ull) \
|
||||
M(i16x8_gt_u, 0xfd00000000000032ull) \
|
||||
M(i16x8_le_s, 0xfd00000000000033ull) \
|
||||
M(i16x8_le_u, 0xfd00000000000034ull) \
|
||||
M(i16x8_ge_s, 0xfd00000000000035ull) \
|
||||
M(i16x8_ge_u, 0xfd00000000000036ull) \
|
||||
M(i32x4_eq, 0xfd00000000000037ull) \
|
||||
M(i32x4_ne, 0xfd00000000000038ull) \
|
||||
M(i32x4_lt_s, 0xfd00000000000039ull) \
|
||||
M(i32x4_lt_u, 0xfd0000000000003aull) \
|
||||
M(i32x4_gt_s, 0xfd0000000000003bull) \
|
||||
M(i32x4_gt_u, 0xfd0000000000003cull) \
|
||||
M(i32x4_le_s, 0xfd0000000000003dull) \
|
||||
M(i32x4_le_u, 0xfd0000000000003eull) \
|
||||
M(i32x4_ge_s, 0xfd0000000000003full) \
|
||||
M(i32x4_ge_u, 0xfd00000000000040ull) \
|
||||
M(f32x4_eq, 0xfd00000000000041ull) \
|
||||
M(f32x4_ne, 0xfd00000000000042ull) \
|
||||
M(f32x4_lt, 0xfd00000000000043ull) \
|
||||
M(f32x4_gt, 0xfd00000000000044ull) \
|
||||
M(f32x4_le, 0xfd00000000000045ull) \
|
||||
M(f32x4_ge, 0xfd00000000000046ull) \
|
||||
M(f64x2_eq, 0xfd00000000000047ull) \
|
||||
M(f64x2_ne, 0xfd00000000000048ull) \
|
||||
M(f64x2_lt, 0xfd00000000000049ull) \
|
||||
M(f64x2_gt, 0xfd0000000000004aull) \
|
||||
M(f64x2_le, 0xfd0000000000004bull) \
|
||||
M(f64x2_ge, 0xfd0000000000004cull) \
|
||||
M(v128_not, 0xfd0000000000004dull) \
|
||||
M(v128_and, 0xfd0000000000004eull) \
|
||||
M(v128_andnot, 0xfd0000000000004full) \
|
||||
M(v128_or, 0xfd00000000000050ull) \
|
||||
M(v128_xor, 0xfd00000000000051ull) \
|
||||
M(v128_bitselect, 0xfd00000000000052ull) \
|
||||
M(v128_any_true, 0xfd00000000000053ull) \
|
||||
M(v128_load8_lane, 0xfd00000000000054ull) \
|
||||
M(v128_load16_lane, 0xfd00000000000055ull) \
|
||||
M(v128_load32_lane, 0xfd00000000000056ull) \
|
||||
M(v128_load64_lane, 0xfd00000000000057ull) \
|
||||
M(v128_store8_lane, 0xfd00000000000058ull) \
|
||||
M(v128_store16_lane, 0xfd00000000000059ull) \
|
||||
M(v128_store32_lane, 0xfd0000000000005aull) \
|
||||
M(v128_store64_lane, 0xfd0000000000005bull) \
|
||||
M(v128_load32_zero, 0xfd0000000000005cull) \
|
||||
M(v128_load64_zero, 0xfd0000000000005dull) \
|
||||
M(f32x4_demote_f64x2_zero, 0xfd0000000000005eull) \
|
||||
M(f64x2_promote_low_f32x4, 0xfd0000000000005full) \
|
||||
M(i8x16_abs, 0xfd00000000000060ull) \
|
||||
M(i8x16_neg, 0xfd00000000000061ull) \
|
||||
M(i8x16_popcnt, 0xfd00000000000062ull) \
|
||||
M(i8x16_all_true, 0xfd00000000000063ull) \
|
||||
M(i8x16_bitmask, 0xfd00000000000064ull) \
|
||||
M(i8x16_narrow_i16x8_s, 0xfd00000000000065ull) \
|
||||
M(i8x16_narrow_i16x8_u, 0xfd00000000000066ull) \
|
||||
M(f32x4_ceil, 0xfd00000000000067ull) \
|
||||
M(f32x4_floor, 0xfd00000000000068ull) \
|
||||
M(f32x4_trunc, 0xfd00000000000069ull) \
|
||||
M(f32x4_nearest, 0xfd0000000000006aull) \
|
||||
M(i8x16_shl, 0xfd0000000000006bull) \
|
||||
M(i8x16_shr_s, 0xfd0000000000006cull) \
|
||||
M(i8x16_shr_u, 0xfd0000000000006dull) \
|
||||
M(i8x16_add, 0xfd0000000000006eull) \
|
||||
M(i8x16_add_sat_s, 0xfd0000000000006full) \
|
||||
M(i8x16_add_sat_u, 0xfd00000000000070ull) \
|
||||
M(i8x16_sub, 0xfd00000000000071ull) \
|
||||
M(i8x16_sub_sat_s, 0xfd00000000000072ull) \
|
||||
M(i8x16_sub_sat_u, 0xfd00000000000073ull) \
|
||||
M(f64x2_ceil, 0xfd00000000000074ull) \
|
||||
M(f64x2_floor, 0xfd00000000000075ull) \
|
||||
M(i8x16_min_s, 0xfd00000000000076ull) \
|
||||
M(i8x16_min_u, 0xfd00000000000077ull) \
|
||||
M(i8x16_max_s, 0xfd00000000000078ull) \
|
||||
M(i8x16_max_u, 0xfd00000000000079ull) \
|
||||
M(f64x2_trunc, 0xfd0000000000007aull) \
|
||||
M(i8x16_avgr_u, 0xfd0000000000007bull) \
|
||||
M(i16x8_extadd_pairwise_i8x16_s, 0xfd0000000000007cull) \
|
||||
M(i16x8_extadd_pairwise_i8x16_u, 0xfd0000000000007dull) \
|
||||
M(i32x4_extadd_pairwise_i16x8_s, 0xfd0000000000007eull) \
|
||||
M(i32x4_extadd_pairwise_i16x8_u, 0xfd0000000000007full) \
|
||||
M(i16x8_abs, 0xfd00000000000080ull) \
|
||||
M(i16x8_neg, 0xfd00000000000081ull) \
|
||||
M(i16x8_q15mulr_sat_s, 0xfd00000000000082ull) \
|
||||
M(i16x8_all_true, 0xfd00000000000083ull) \
|
||||
M(i16x8_bitmask, 0xfd00000000000084ull) \
|
||||
M(i16x8_narrow_i32x4_s, 0xfd00000000000085ull) \
|
||||
M(i16x8_narrow_i32x4_u, 0xfd00000000000086ull) \
|
||||
M(i16x8_extend_low_i8x16_s, 0xfd00000000000087ull) \
|
||||
M(i16x8_extend_high_i8x16_s, 0xfd00000000000088ull) \
|
||||
M(i16x8_extend_low_i8x16_u, 0xfd00000000000089ull) \
|
||||
M(i16x8_extend_high_i8x16_u, 0xfd0000000000008aull) \
|
||||
M(i16x8_shl, 0xfd0000000000008bull) \
|
||||
M(i16x8_shr_s, 0xfd0000000000008cull) \
|
||||
M(i16x8_shr_u, 0xfd0000000000008dull) \
|
||||
M(i16x8_add, 0xfd0000000000008eull) \
|
||||
M(i16x8_add_sat_s, 0xfd0000000000008full) \
|
||||
M(i16x8_add_sat_u, 0xfd00000000000090ull) \
|
||||
M(i16x8_sub, 0xfd00000000000091ull) \
|
||||
M(i16x8_sub_sat_s, 0xfd00000000000092ull) \
|
||||
M(i16x8_sub_sat_u, 0xfd00000000000093ull) \
|
||||
M(f64x2_nearest, 0xfd00000000000094ull) \
|
||||
M(i16x8_mul, 0xfd00000000000095ull) \
|
||||
M(i16x8_min_s, 0xfd00000000000096ull) \
|
||||
M(i16x8_min_u, 0xfd00000000000097ull) \
|
||||
M(i16x8_max_s, 0xfd00000000000098ull) \
|
||||
M(i16x8_max_u, 0xfd00000000000099ull) \
|
||||
M(i16x8_avgr_u, 0xfd0000000000009bull) \
|
||||
M(i16x8_extmul_low_i8x16_s, 0xfd0000000000009cull) \
|
||||
M(i16x8_extmul_high_i8x16_s, 0xfd0000000000009dull) \
|
||||
M(i16x8_extmul_low_i8x16_u, 0xfd0000000000009eull) \
|
||||
M(i16x8_extmul_high_i8x16_u, 0xfd0000000000009full) \
|
||||
M(i32x4_abs, 0xfd000000000000a0ull) \
|
||||
M(i32x4_neg, 0xfd000000000000a1ull) \
|
||||
M(i32x4_all_true, 0xfd000000000000a3ull) \
|
||||
M(i32x4_bitmask, 0xfd000000000000a4ull) \
|
||||
M(i32x4_extend_low_i16x8_s, 0xfd000000000000a7ull) \
|
||||
M(i32x4_extend_high_i16x8_s, 0xfd000000000000a8ull) \
|
||||
M(i32x4_extend_low_i16x8_u, 0xfd000000000000a9ull) \
|
||||
M(i32x4_extend_high_i16x8_u, 0xfd000000000000aaull) \
|
||||
M(i32x4_shl, 0xfd000000000000abull) \
|
||||
M(i32x4_shr_s, 0xfd000000000000acull) \
|
||||
M(i32x4_shr_u, 0xfd000000000000adull) \
|
||||
M(i32x4_add, 0xfd000000000000aeull) \
|
||||
M(i32x4_sub, 0xfd000000000000b1ull) \
|
||||
M(i32x4_mul, 0xfd000000000000b5ull) \
|
||||
M(i32x4_min_s, 0xfd000000000000b6ull) \
|
||||
M(i32x4_min_u, 0xfd000000000000b7ull) \
|
||||
M(i32x4_max_s, 0xfd000000000000b8ull) \
|
||||
M(i32x4_max_u, 0xfd000000000000b9ull) \
|
||||
M(i32x4_dot_i16x8_s, 0xfd000000000000baull) \
|
||||
M(i32x4_extmul_low_i16x8_s, 0xfd000000000000bcull) \
|
||||
M(i32x4_extmul_high_i16x8_s, 0xfd000000000000bdull) \
|
||||
M(i32x4_extmul_low_i16x8_u, 0xfd000000000000beull) \
|
||||
M(i32x4_extmul_high_i16x8_u, 0xfd000000000000bfull) \
|
||||
M(i64x2_abs, 0xfd000000000000c0ull) \
|
||||
M(i64x2_neg, 0xfd000000000000c1ull) \
|
||||
M(i64x2_all_true, 0xfd000000000000c3ull) \
|
||||
M(i64x2_bitmask, 0xfd000000000000c4ull) \
|
||||
M(i64x2_extend_low_i32x4_s, 0xfd000000000000c7ull) \
|
||||
M(i64x2_extend_high_i32x4_s, 0xfd000000000000c8ull) \
|
||||
M(i64x2_extend_low_i32x4_u, 0xfd000000000000c9ull) \
|
||||
M(i64x2_extend_high_i32x4_u, 0xfd000000000000caull) \
|
||||
M(i64x2_shl, 0xfd000000000000cbull) \
|
||||
M(i64x2_shr_s, 0xfd000000000000ccull) \
|
||||
M(i64x2_shr_u, 0xfd000000000000cdull) \
|
||||
M(i64x2_add, 0xfd000000000000ceull) \
|
||||
M(i64x2_sub, 0xfd000000000000d1ull) \
|
||||
M(i64x2_mul, 0xfd000000000000d5ull) \
|
||||
M(i64x2_eq, 0xfd000000000000d6ull) \
|
||||
M(i64x2_ne, 0xfd000000000000d7ull) \
|
||||
M(i64x2_lt_s, 0xfd000000000000d8ull) \
|
||||
M(i64x2_gt_s, 0xfd000000000000d9ull) \
|
||||
M(i64x2_le_s, 0xfd000000000000daull) \
|
||||
M(i64x2_ge_s, 0xfd000000000000dbull) \
|
||||
M(i64x2_extmul_low_i32x4_s, 0xfd000000000000dcull) \
|
||||
M(i64x2_extmul_high_i32x4_s, 0xfd000000000000ddull) \
|
||||
M(i64x2_extmul_low_i32x4_u, 0xfd000000000000deull) \
|
||||
M(i64x2_extmul_high_i32x4_u, 0xfd000000000000dfull) \
|
||||
M(f32x4_abs, 0xfd000000000000e0ull) \
|
||||
M(f32x4_neg, 0xfd000000000000e1ull) \
|
||||
M(f32x4_sqrt, 0xfd000000000000e3ull) \
|
||||
M(f32x4_add, 0xfd000000000000e4ull) \
|
||||
M(f32x4_sub, 0xfd000000000000e5ull) \
|
||||
M(f32x4_mul, 0xfd000000000000e6ull) \
|
||||
M(f32x4_div, 0xfd000000000000e7ull) \
|
||||
M(f32x4_min, 0xfd000000000000e8ull) \
|
||||
M(f32x4_max, 0xfd000000000000e9ull) \
|
||||
M(f32x4_pmin, 0xfd000000000000eaull) \
|
||||
M(f32x4_pmax, 0xfd000000000000ebull) \
|
||||
M(f64x2_abs, 0xfd000000000000ecull) \
|
||||
M(f64x2_neg, 0xfd000000000000edull) \
|
||||
M(f64x2_sqrt, 0xfd000000000000efull) \
|
||||
M(f64x2_add, 0xfd000000000000f0ull) \
|
||||
M(f64x2_sub, 0xfd000000000000f1ull) \
|
||||
M(f64x2_mul, 0xfd000000000000f2ull) \
|
||||
M(f64x2_div, 0xfd000000000000f3ull) \
|
||||
M(f64x2_min, 0xfd000000000000f4ull) \
|
||||
M(f64x2_max, 0xfd000000000000f5ull) \
|
||||
M(f64x2_pmin, 0xfd000000000000f6ull) \
|
||||
M(f64x2_pmax, 0xfd000000000000f7ull) \
|
||||
M(i32x4_trunc_sat_f32x4_s, 0xfd000000000000f8ull) \
|
||||
M(i32x4_trunc_sat_f32x4_u, 0xfd000000000000f9ull) \
|
||||
M(f32x4_convert_i32x4_s, 0xfd000000000000faull) \
|
||||
M(f32x4_convert_i32x4_u, 0xfd000000000000fbull) \
|
||||
M(i32x4_trunc_sat_f64x2_s_zero, 0xfd000000000000fcull) \
|
||||
M(i32x4_trunc_sat_f64x2_u_zero, 0xfd000000000000fdull) \
|
||||
M(f64x2_convert_low_i32x4_s, 0xfd000000000000feull) \
|
||||
M(f64x2_convert_low_i32x4_u, 0xfd000000000000ffull)
|
||||
|
||||
#define ENUMERATE_WASM_OPCODES(M) \
|
||||
ENUMERATE_SINGLE_BYTE_WASM_OPCODES(M) \
|
||||
|
@ -228,25 +464,6 @@ namespace Instructions {
|
|||
ENUMERATE_WASM_OPCODES(M)
|
||||
#undef M
|
||||
|
||||
static constexpr u32 i32_trunc_sat_f32_s_second = 0,
|
||||
i32_trunc_sat_f32_u_second = 1,
|
||||
i32_trunc_sat_f64_s_second = 2,
|
||||
i32_trunc_sat_f64_u_second = 3,
|
||||
i64_trunc_sat_f32_s_second = 4,
|
||||
i64_trunc_sat_f32_u_second = 5,
|
||||
i64_trunc_sat_f64_s_second = 6,
|
||||
i64_trunc_sat_f64_u_second = 7,
|
||||
memory_init_second = 8,
|
||||
data_drop_second = 9,
|
||||
memory_copy_second = 10,
|
||||
memory_fill_second = 11,
|
||||
table_init_second = 12,
|
||||
elem_drop_second = 13,
|
||||
table_copy_second = 14,
|
||||
table_grow_second = 15,
|
||||
table_size_second = 16,
|
||||
table_fill_second = 17;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <AK/MemoryStream.h>
|
||||
#include <AK/ScopeGuard.h>
|
||||
#include <AK/ScopeLogger.h>
|
||||
#include <AK/UFixedBigInt.h>
|
||||
#include <LibWasm/Types.h>
|
||||
|
||||
namespace Wasm {
|
||||
|
@ -138,6 +139,8 @@ ParseResult<ValueType> ValueType::parse(Stream& stream)
|
|||
return ValueType(F32);
|
||||
case Constants::f64_tag:
|
||||
return ValueType(F64);
|
||||
case Constants::v128_tag:
|
||||
return ValueType(V128);
|
||||
case Constants::function_reference_tag:
|
||||
return ValueType(FunctionReference);
|
||||
case Constants::extern_reference_tag:
|
||||
|
@ -677,24 +680,27 @@ ParseResult<Vector<Instruction>> Instruction::parse(Stream& stream, InstructionP
|
|||
case Instructions::i64_extend32_s.value():
|
||||
resulting_instructions.append(Instruction { opcode });
|
||||
break;
|
||||
case 0xfc: {
|
||||
case 0xfc:
|
||||
case 0xfd: {
|
||||
// These are multibyte instructions.
|
||||
auto selector_or_error = stream.read_value<LEB128<u32>>();
|
||||
if (selector_or_error.is_error())
|
||||
return with_eof_check(stream, ParseError::InvalidInput);
|
||||
u32 selector = selector_or_error.release_value();
|
||||
switch (selector) {
|
||||
case Instructions::i32_trunc_sat_f32_s_second:
|
||||
case Instructions::i32_trunc_sat_f32_u_second:
|
||||
case Instructions::i32_trunc_sat_f64_s_second:
|
||||
case Instructions::i32_trunc_sat_f64_u_second:
|
||||
case Instructions::i64_trunc_sat_f32_s_second:
|
||||
case Instructions::i64_trunc_sat_f32_u_second:
|
||||
case Instructions::i64_trunc_sat_f64_s_second:
|
||||
case Instructions::i64_trunc_sat_f64_u_second:
|
||||
resulting_instructions.append(Instruction { OpCode { 0xfc00 | selector } });
|
||||
OpCode full_opcode = static_cast<u64>(opcode.value()) << 56 | selector;
|
||||
|
||||
switch (full_opcode.value()) {
|
||||
case Instructions::i32_trunc_sat_f32_s.value():
|
||||
case Instructions::i32_trunc_sat_f32_u.value():
|
||||
case Instructions::i32_trunc_sat_f64_s.value():
|
||||
case Instructions::i32_trunc_sat_f64_u.value():
|
||||
case Instructions::i64_trunc_sat_f32_s.value():
|
||||
case Instructions::i64_trunc_sat_f32_u.value():
|
||||
case Instructions::i64_trunc_sat_f64_s.value():
|
||||
case Instructions::i64_trunc_sat_f64_u.value():
|
||||
resulting_instructions.append(Instruction { full_opcode });
|
||||
break;
|
||||
case Instructions::memory_init_second: {
|
||||
case Instructions::memory_init.value(): {
|
||||
auto index = GenericIndexParser<DataIndex>::parse(stream);
|
||||
if (index.is_error())
|
||||
return index.error();
|
||||
|
@ -705,17 +711,17 @@ ParseResult<Vector<Instruction>> Instruction::parse(Stream& stream, InstructionP
|
|||
auto unused = unused_or_error.release_value();
|
||||
if (unused != 0x00)
|
||||
return ParseError::InvalidImmediate;
|
||||
resulting_instructions.append(Instruction { OpCode { 0xfc00 | selector }, index.release_value() });
|
||||
resulting_instructions.append(Instruction { full_opcode, index.release_value() });
|
||||
break;
|
||||
}
|
||||
case Instructions::data_drop_second: {
|
||||
case Instructions::data_drop.value(): {
|
||||
auto index = GenericIndexParser<DataIndex>::parse(stream);
|
||||
if (index.is_error())
|
||||
return index.error();
|
||||
resulting_instructions.append(Instruction { OpCode { 0xfc00 | selector }, index.release_value() });
|
||||
resulting_instructions.append(Instruction { full_opcode, index.release_value() });
|
||||
break;
|
||||
}
|
||||
case Instructions::memory_copy_second: {
|
||||
case Instructions::memory_copy.value(): {
|
||||
for (size_t i = 0; i < 2; ++i) {
|
||||
auto unused_or_error = stream.read_value<u8>();
|
||||
if (unused_or_error.is_error())
|
||||
|
@ -725,10 +731,10 @@ ParseResult<Vector<Instruction>> Instruction::parse(Stream& stream, InstructionP
|
|||
if (unused != 0x00)
|
||||
return ParseError::InvalidImmediate;
|
||||
}
|
||||
resulting_instructions.append(Instruction { OpCode { 0xfc00 | selector } });
|
||||
resulting_instructions.append(Instruction { full_opcode });
|
||||
break;
|
||||
}
|
||||
case Instructions::memory_fill_second: {
|
||||
case Instructions::memory_fill.value(): {
|
||||
auto unused_or_error = stream.read_value<u8>();
|
||||
if (unused_or_error.is_error())
|
||||
return with_eof_check(stream, ParseError::InvalidInput);
|
||||
|
@ -736,45 +742,341 @@ ParseResult<Vector<Instruction>> Instruction::parse(Stream& stream, InstructionP
|
|||
auto unused = unused_or_error.release_value();
|
||||
if (unused != 0x00)
|
||||
return ParseError::InvalidImmediate;
|
||||
resulting_instructions.append(Instruction { OpCode { 0xfc00 | selector } });
|
||||
resulting_instructions.append(Instruction { full_opcode });
|
||||
break;
|
||||
}
|
||||
case Instructions::table_init_second: {
|
||||
case Instructions::table_init.value(): {
|
||||
auto element_index = GenericIndexParser<ElementIndex>::parse(stream);
|
||||
if (element_index.is_error())
|
||||
return element_index.error();
|
||||
auto table_index = GenericIndexParser<TableIndex>::parse(stream);
|
||||
if (table_index.is_error())
|
||||
return table_index.error();
|
||||
resulting_instructions.append(Instruction { OpCode { 0xfc00 | selector }, TableElementArgs { element_index.release_value(), table_index.release_value() } });
|
||||
resulting_instructions.append(Instruction { full_opcode, TableElementArgs { element_index.release_value(), table_index.release_value() } });
|
||||
break;
|
||||
}
|
||||
case Instructions::elem_drop_second: {
|
||||
case Instructions::elem_drop.value(): {
|
||||
auto element_index = GenericIndexParser<ElementIndex>::parse(stream);
|
||||
if (element_index.is_error())
|
||||
return element_index.error();
|
||||
resulting_instructions.append(Instruction { OpCode { 0xfc00 | selector }, element_index.release_value() });
|
||||
resulting_instructions.append(Instruction { full_opcode, element_index.release_value() });
|
||||
break;
|
||||
}
|
||||
case Instructions::table_copy_second: {
|
||||
case Instructions::table_copy.value(): {
|
||||
auto lhs = GenericIndexParser<TableIndex>::parse(stream);
|
||||
if (lhs.is_error())
|
||||
return lhs.error();
|
||||
auto rhs = GenericIndexParser<TableIndex>::parse(stream);
|
||||
if (rhs.is_error())
|
||||
return rhs.error();
|
||||
resulting_instructions.append(Instruction { OpCode { 0xfc00 | selector }, TableTableArgs { lhs.release_value(), rhs.release_value() } });
|
||||
resulting_instructions.append(Instruction { full_opcode, TableTableArgs { lhs.release_value(), rhs.release_value() } });
|
||||
break;
|
||||
}
|
||||
case Instructions::table_grow_second:
|
||||
case Instructions::table_size_second:
|
||||
case Instructions::table_fill_second: {
|
||||
case Instructions::table_grow.value():
|
||||
case Instructions::table_size.value():
|
||||
case Instructions::table_fill.value(): {
|
||||
auto index = GenericIndexParser<TableIndex>::parse(stream);
|
||||
if (index.is_error())
|
||||
return index.error();
|
||||
resulting_instructions.append(Instruction { OpCode { 0xfc00 | selector }, index.release_value() });
|
||||
resulting_instructions.append(Instruction { full_opcode, index.release_value() });
|
||||
break;
|
||||
}
|
||||
case Instructions::v128_load.value():
|
||||
case Instructions::v128_load8x8_s.value():
|
||||
case Instructions::v128_load8x8_u.value():
|
||||
case Instructions::v128_load16x4_s.value():
|
||||
case Instructions::v128_load16x4_u.value():
|
||||
case Instructions::v128_load32x2_s.value():
|
||||
case Instructions::v128_load32x2_u.value():
|
||||
case Instructions::v128_load8_splat.value():
|
||||
case Instructions::v128_load16_splat.value():
|
||||
case Instructions::v128_load32_splat.value():
|
||||
case Instructions::v128_load64_splat.value():
|
||||
case Instructions::v128_store.value(): {
|
||||
// op (align offset)
|
||||
auto align_or_error = stream.read_value<LEB128<size_t>>();
|
||||
if (align_or_error.is_error())
|
||||
return with_eof_check(stream, ParseError::ExpectedIndex);
|
||||
size_t align = align_or_error.release_value();
|
||||
auto offset_or_error = stream.read_value<LEB128<size_t>>();
|
||||
if (offset_or_error.is_error())
|
||||
return with_eof_check(stream, ParseError::ExpectedIndex);
|
||||
size_t offset = offset_or_error.release_value();
|
||||
|
||||
resulting_instructions.append(Instruction { full_opcode, MemoryArgument { static_cast<u32>(align), static_cast<u32>(offset) } });
|
||||
break;
|
||||
}
|
||||
case Instructions::v128_load8_lane.value():
|
||||
case Instructions::v128_load16_lane.value():
|
||||
case Instructions::v128_load32_lane.value():
|
||||
case Instructions::v128_load64_lane.value():
|
||||
case Instructions::v128_store8_lane.value():
|
||||
case Instructions::v128_store16_lane.value():
|
||||
case Instructions::v128_store32_lane.value():
|
||||
case Instructions::v128_store64_lane.value(): {
|
||||
// op (align offset) (index)
|
||||
auto align_or_error = stream.read_value<LEB128<size_t>>();
|
||||
if (align_or_error.is_error())
|
||||
return with_eof_check(stream, ParseError::ExpectedIndex);
|
||||
size_t align = align_or_error.release_value();
|
||||
auto offset_or_error = stream.read_value<LEB128<size_t>>();
|
||||
if (offset_or_error.is_error())
|
||||
return with_eof_check(stream, ParseError::ExpectedIndex);
|
||||
size_t offset = offset_or_error.release_value();
|
||||
|
||||
auto index_or_error = stream.read_value<u8>();
|
||||
if (index_or_error.is_error())
|
||||
return with_eof_check(stream, ParseError::InvalidInput);
|
||||
auto index = index_or_error.release_value();
|
||||
|
||||
resulting_instructions.append(Instruction { full_opcode, MemoryAndLaneArgument { { static_cast<u32>(align), static_cast<u32>(offset) }, index } });
|
||||
break;
|
||||
}
|
||||
case Instructions::v128_const.value(): {
|
||||
// op (literal:16)
|
||||
auto value_or_error = stream.read_value<LittleEndian<u128>>();
|
||||
if (value_or_error.is_error())
|
||||
return with_eof_check(stream, ParseError::InvalidImmediate);
|
||||
resulting_instructions.append(Instruction { full_opcode, value_or_error.release_value() });
|
||||
break;
|
||||
}
|
||||
case Instructions::i8x16_shuffle.value(): {
|
||||
// op 16x(lane)
|
||||
u8 lanes[16];
|
||||
for (size_t i = 0; i < 16; ++i) {
|
||||
auto value_or_error = stream.read_value<u8>();
|
||||
if (value_or_error.is_error())
|
||||
return with_eof_check(stream, ParseError::InvalidInput);
|
||||
lanes[i] = value_or_error.release_value();
|
||||
}
|
||||
resulting_instructions.append(Instruction { full_opcode, ShuffleArgument(lanes) });
|
||||
break;
|
||||
}
|
||||
case Instructions::i8x16_extract_lane_s.value():
|
||||
case Instructions::i8x16_extract_lane_u.value():
|
||||
case Instructions::i8x16_replace_lane.value():
|
||||
case Instructions::i16x8_extract_lane_s.value():
|
||||
case Instructions::i16x8_extract_lane_u.value():
|
||||
case Instructions::i16x8_replace_lane.value():
|
||||
case Instructions::i32x4_extract_lane.value():
|
||||
case Instructions::i32x4_replace_lane.value():
|
||||
case Instructions::i64x2_extract_lane.value():
|
||||
case Instructions::i64x2_replace_lane.value():
|
||||
case Instructions::f32x4_extract_lane.value():
|
||||
case Instructions::f32x4_replace_lane.value():
|
||||
case Instructions::f64x2_extract_lane.value():
|
||||
case Instructions::f64x2_replace_lane.value(): {
|
||||
// op (lane)
|
||||
auto lane_or_error = stream.read_value<u8>();
|
||||
if (lane_or_error.is_error())
|
||||
return with_eof_check(stream, ParseError::InvalidInput);
|
||||
auto lane = lane_or_error.release_value();
|
||||
resulting_instructions.append(Instruction { full_opcode, LaneIndex { lane } });
|
||||
break;
|
||||
}
|
||||
case Instructions::i8x16_swizzle.value():
|
||||
case Instructions::i8x16_splat.value():
|
||||
case Instructions::i16x8_splat.value():
|
||||
case Instructions::i32x4_splat.value():
|
||||
case Instructions::i64x2_splat.value():
|
||||
case Instructions::f32x4_splat.value():
|
||||
case Instructions::f64x2_splat.value():
|
||||
case Instructions::i8x16_eq.value():
|
||||
case Instructions::i8x16_ne.value():
|
||||
case Instructions::i8x16_lt_s.value():
|
||||
case Instructions::i8x16_lt_u.value():
|
||||
case Instructions::i8x16_gt_s.value():
|
||||
case Instructions::i8x16_gt_u.value():
|
||||
case Instructions::i8x16_le_s.value():
|
||||
case Instructions::i8x16_le_u.value():
|
||||
case Instructions::i8x16_ge_s.value():
|
||||
case Instructions::i8x16_ge_u.value():
|
||||
case Instructions::i16x8_eq.value():
|
||||
case Instructions::i16x8_ne.value():
|
||||
case Instructions::i16x8_lt_s.value():
|
||||
case Instructions::i16x8_lt_u.value():
|
||||
case Instructions::i16x8_gt_s.value():
|
||||
case Instructions::i16x8_gt_u.value():
|
||||
case Instructions::i16x8_le_s.value():
|
||||
case Instructions::i16x8_le_u.value():
|
||||
case Instructions::i16x8_ge_s.value():
|
||||
case Instructions::i16x8_ge_u.value():
|
||||
case Instructions::i32x4_eq.value():
|
||||
case Instructions::i32x4_ne.value():
|
||||
case Instructions::i32x4_lt_s.value():
|
||||
case Instructions::i32x4_lt_u.value():
|
||||
case Instructions::i32x4_gt_s.value():
|
||||
case Instructions::i32x4_gt_u.value():
|
||||
case Instructions::i32x4_le_s.value():
|
||||
case Instructions::i32x4_le_u.value():
|
||||
case Instructions::i32x4_ge_s.value():
|
||||
case Instructions::i32x4_ge_u.value():
|
||||
case Instructions::f32x4_eq.value():
|
||||
case Instructions::f32x4_ne.value():
|
||||
case Instructions::f32x4_lt.value():
|
||||
case Instructions::f32x4_gt.value():
|
||||
case Instructions::f32x4_le.value():
|
||||
case Instructions::f32x4_ge.value():
|
||||
case Instructions::f64x2_eq.value():
|
||||
case Instructions::f64x2_ne.value():
|
||||
case Instructions::f64x2_lt.value():
|
||||
case Instructions::f64x2_gt.value():
|
||||
case Instructions::f64x2_le.value():
|
||||
case Instructions::f64x2_ge.value():
|
||||
case Instructions::v128_not.value():
|
||||
case Instructions::v128_and.value():
|
||||
case Instructions::v128_andnot.value():
|
||||
case Instructions::v128_or.value():
|
||||
case Instructions::v128_xor.value():
|
||||
case Instructions::v128_bitselect.value():
|
||||
case Instructions::v128_any_true.value():
|
||||
case Instructions::v128_load32_zero.value():
|
||||
case Instructions::v128_load64_zero.value():
|
||||
case Instructions::f32x4_demote_f64x2_zero.value():
|
||||
case Instructions::f64x2_promote_low_f32x4.value():
|
||||
case Instructions::i8x16_abs.value():
|
||||
case Instructions::i8x16_neg.value():
|
||||
case Instructions::i8x16_popcnt.value():
|
||||
case Instructions::i8x16_all_true.value():
|
||||
case Instructions::i8x16_bitmask.value():
|
||||
case Instructions::i8x16_narrow_i16x8_s.value():
|
||||
case Instructions::i8x16_narrow_i16x8_u.value():
|
||||
case Instructions::f32x4_ceil.value():
|
||||
case Instructions::f32x4_floor.value():
|
||||
case Instructions::f32x4_trunc.value():
|
||||
case Instructions::f32x4_nearest.value():
|
||||
case Instructions::i8x16_shl.value():
|
||||
case Instructions::i8x16_shr_s.value():
|
||||
case Instructions::i8x16_shr_u.value():
|
||||
case Instructions::i8x16_add.value():
|
||||
case Instructions::i8x16_add_sat_s.value():
|
||||
case Instructions::i8x16_add_sat_u.value():
|
||||
case Instructions::i8x16_sub.value():
|
||||
case Instructions::i8x16_sub_sat_s.value():
|
||||
case Instructions::i8x16_sub_sat_u.value():
|
||||
case Instructions::f64x2_ceil.value():
|
||||
case Instructions::f64x2_floor.value():
|
||||
case Instructions::i8x16_min_s.value():
|
||||
case Instructions::i8x16_min_u.value():
|
||||
case Instructions::i8x16_max_s.value():
|
||||
case Instructions::i8x16_max_u.value():
|
||||
case Instructions::f64x2_trunc.value():
|
||||
case Instructions::i8x16_avgr_u.value():
|
||||
case Instructions::i16x8_extadd_pairwise_i8x16_s.value():
|
||||
case Instructions::i16x8_extadd_pairwise_i8x16_u.value():
|
||||
case Instructions::i32x4_extadd_pairwise_i16x8_s.value():
|
||||
case Instructions::i32x4_extadd_pairwise_i16x8_u.value():
|
||||
case Instructions::i16x8_abs.value():
|
||||
case Instructions::i16x8_neg.value():
|
||||
case Instructions::i16x8_q15mulr_sat_s.value():
|
||||
case Instructions::i16x8_all_true.value():
|
||||
case Instructions::i16x8_bitmask.value():
|
||||
case Instructions::i16x8_narrow_i32x4_s.value():
|
||||
case Instructions::i16x8_narrow_i32x4_u.value():
|
||||
case Instructions::i16x8_extend_low_i8x16_s.value():
|
||||
case Instructions::i16x8_extend_high_i8x16_s.value():
|
||||
case Instructions::i16x8_extend_low_i8x16_u.value():
|
||||
case Instructions::i16x8_extend_high_i8x16_u.value():
|
||||
case Instructions::i16x8_shl.value():
|
||||
case Instructions::i16x8_shr_s.value():
|
||||
case Instructions::i16x8_shr_u.value():
|
||||
case Instructions::i16x8_add.value():
|
||||
case Instructions::i16x8_add_sat_s.value():
|
||||
case Instructions::i16x8_add_sat_u.value():
|
||||
case Instructions::i16x8_sub.value():
|
||||
case Instructions::i16x8_sub_sat_s.value():
|
||||
case Instructions::i16x8_sub_sat_u.value():
|
||||
case Instructions::f64x2_nearest.value():
|
||||
case Instructions::i16x8_mul.value():
|
||||
case Instructions::i16x8_min_s.value():
|
||||
case Instructions::i16x8_min_u.value():
|
||||
case Instructions::i16x8_max_s.value():
|
||||
case Instructions::i16x8_max_u.value():
|
||||
case Instructions::i16x8_avgr_u.value():
|
||||
case Instructions::i16x8_extmul_low_i8x16_s.value():
|
||||
case Instructions::i16x8_extmul_high_i8x16_s.value():
|
||||
case Instructions::i16x8_extmul_low_i8x16_u.value():
|
||||
case Instructions::i16x8_extmul_high_i8x16_u.value():
|
||||
case Instructions::i32x4_abs.value():
|
||||
case Instructions::i32x4_neg.value():
|
||||
case Instructions::i32x4_all_true.value():
|
||||
case Instructions::i32x4_bitmask.value():
|
||||
case Instructions::i32x4_extend_low_i16x8_s.value():
|
||||
case Instructions::i32x4_extend_high_i16x8_s.value():
|
||||
case Instructions::i32x4_extend_low_i16x8_u.value():
|
||||
case Instructions::i32x4_extend_high_i16x8_u.value():
|
||||
case Instructions::i32x4_shl.value():
|
||||
case Instructions::i32x4_shr_s.value():
|
||||
case Instructions::i32x4_shr_u.value():
|
||||
case Instructions::i32x4_add.value():
|
||||
case Instructions::i32x4_sub.value():
|
||||
case Instructions::i32x4_mul.value():
|
||||
case Instructions::i32x4_min_s.value():
|
||||
case Instructions::i32x4_min_u.value():
|
||||
case Instructions::i32x4_max_s.value():
|
||||
case Instructions::i32x4_max_u.value():
|
||||
case Instructions::i32x4_dot_i16x8_s.value():
|
||||
case Instructions::i32x4_extmul_low_i16x8_s.value():
|
||||
case Instructions::i32x4_extmul_high_i16x8_s.value():
|
||||
case Instructions::i32x4_extmul_low_i16x8_u.value():
|
||||
case Instructions::i32x4_extmul_high_i16x8_u.value():
|
||||
case Instructions::i64x2_abs.value():
|
||||
case Instructions::i64x2_neg.value():
|
||||
case Instructions::i64x2_all_true.value():
|
||||
case Instructions::i64x2_bitmask.value():
|
||||
case Instructions::i64x2_extend_low_i32x4_s.value():
|
||||
case Instructions::i64x2_extend_high_i32x4_s.value():
|
||||
case Instructions::i64x2_extend_low_i32x4_u.value():
|
||||
case Instructions::i64x2_extend_high_i32x4_u.value():
|
||||
case Instructions::i64x2_shl.value():
|
||||
case Instructions::i64x2_shr_s.value():
|
||||
case Instructions::i64x2_shr_u.value():
|
||||
case Instructions::i64x2_add.value():
|
||||
case Instructions::i64x2_sub.value():
|
||||
case Instructions::i64x2_mul.value():
|
||||
case Instructions::i64x2_eq.value():
|
||||
case Instructions::i64x2_ne.value():
|
||||
case Instructions::i64x2_lt_s.value():
|
||||
case Instructions::i64x2_gt_s.value():
|
||||
case Instructions::i64x2_le_s.value():
|
||||
case Instructions::i64x2_ge_s.value():
|
||||
case Instructions::i64x2_extmul_low_i32x4_s.value():
|
||||
case Instructions::i64x2_extmul_high_i32x4_s.value():
|
||||
case Instructions::i64x2_extmul_low_i32x4_u.value():
|
||||
case Instructions::i64x2_extmul_high_i32x4_u.value():
|
||||
case Instructions::f32x4_abs.value():
|
||||
case Instructions::f32x4_neg.value():
|
||||
case Instructions::f32x4_sqrt.value():
|
||||
case Instructions::f32x4_add.value():
|
||||
case Instructions::f32x4_sub.value():
|
||||
case Instructions::f32x4_mul.value():
|
||||
case Instructions::f32x4_div.value():
|
||||
case Instructions::f32x4_min.value():
|
||||
case Instructions::f32x4_max.value():
|
||||
case Instructions::f32x4_pmin.value():
|
||||
case Instructions::f32x4_pmax.value():
|
||||
case Instructions::f64x2_abs.value():
|
||||
case Instructions::f64x2_neg.value():
|
||||
case Instructions::f64x2_sqrt.value():
|
||||
case Instructions::f64x2_add.value():
|
||||
case Instructions::f64x2_sub.value():
|
||||
case Instructions::f64x2_mul.value():
|
||||
case Instructions::f64x2_div.value():
|
||||
case Instructions::f64x2_min.value():
|
||||
case Instructions::f64x2_max.value():
|
||||
case Instructions::f64x2_pmin.value():
|
||||
case Instructions::f64x2_pmax.value():
|
||||
case Instructions::i32x4_trunc_sat_f32x4_s.value():
|
||||
case Instructions::i32x4_trunc_sat_f32x4_u.value():
|
||||
case Instructions::f32x4_convert_i32x4_s.value():
|
||||
case Instructions::f32x4_convert_i32x4_u.value():
|
||||
case Instructions::i32x4_trunc_sat_f64x2_s_zero.value():
|
||||
case Instructions::i32x4_trunc_sat_f64x2_u_zero.value():
|
||||
case Instructions::f64x2_convert_low_i32x4_s.value():
|
||||
case Instructions::f64x2_convert_low_i32x4_u.value():
|
||||
// op
|
||||
resulting_instructions.append(Instruction { full_opcode });
|
||||
break;
|
||||
default:
|
||||
return ParseError::UnknownInstruction;
|
||||
}
|
||||
|
|
|
@ -433,6 +433,15 @@ void Printer::print(Wasm::Instruction const& instruction)
|
|||
[&](TableIndex const& index) { print("(table index {})", index.value()); },
|
||||
[&](Instruction::IndirectCallArgs const& args) { print("(indirect (type index {}) (table index {}))", args.type.value(), args.table.value()); },
|
||||
[&](Instruction::MemoryArgument const& args) { print("(memory (align {}) (offset {}))", args.align, args.offset); },
|
||||
[&](Instruction::MemoryAndLaneArgument const& args) { print("(memory (align {}) (offset {})) (lane {})", args.memory.align, args.memory.offset, args.lane); },
|
||||
[&](Instruction::LaneIndex const& args) { print("(lane {})", args.lane); },
|
||||
[&](Instruction::ShuffleArgument const& args) {
|
||||
print("{{ {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} }}",
|
||||
args.lanes[0], args.lanes[1], args.lanes[2], args.lanes[3],
|
||||
args.lanes[4], args.lanes[5], args.lanes[6], args.lanes[7],
|
||||
args.lanes[8], args.lanes[9], args.lanes[10], args.lanes[11],
|
||||
args.lanes[12], args.lanes[13], args.lanes[14], args.lanes[15]);
|
||||
},
|
||||
[&](Instruction::StructuredInstructionArgs const& args) {
|
||||
print("(structured\n");
|
||||
TemporaryChange change { m_indent, m_indent + 1 };
|
||||
|
@ -637,14 +646,17 @@ void Printer::print(Wasm::Value const& value)
|
|||
{
|
||||
print_indent();
|
||||
print("{} ", value.value().visit([&]<typename T>(T const& value) {
|
||||
if constexpr (IsSame<Wasm::Reference, T>)
|
||||
if constexpr (IsSame<Wasm::Reference, T>) {
|
||||
return DeprecatedString::formatted(
|
||||
"addr({})",
|
||||
value.ref().visit(
|
||||
[](Wasm::Reference::Null const&) { return DeprecatedString("null"); },
|
||||
[](auto const& ref) { return DeprecatedString::number(ref.address.value()); }));
|
||||
else
|
||||
} else if constexpr (IsSame<u128, T>) {
|
||||
return DeprecatedString::formatted("v128({:x})", value);
|
||||
} else {
|
||||
return DeprecatedString::formatted("{}", value);
|
||||
}
|
||||
}));
|
||||
TemporaryChange<size_t> change { m_indent, 0 };
|
||||
print(value.type());
|
||||
|
@ -861,6 +873,242 @@ HashMap<Wasm::OpCode, DeprecatedString> Wasm::Names::instruction_names {
|
|||
{ Instructions::table_grow, "table.grow" },
|
||||
{ Instructions::table_size, "table.size" },
|
||||
{ Instructions::table_fill, "table.fill" },
|
||||
{ Instructions::v128_load, "v128.load" },
|
||||
{ Instructions::v128_load8x8_s, "v128.load8x8_s" },
|
||||
{ Instructions::v128_load8x8_u, "v128.load8x8_u" },
|
||||
{ Instructions::v128_load16x4_s, "v128.load16x4_s" },
|
||||
{ Instructions::v128_load16x4_u, "v128.load16x4_u" },
|
||||
{ Instructions::v128_load32x2_s, "v128.load32x2_s" },
|
||||
{ Instructions::v128_load32x2_u, "v128.load32x2_u" },
|
||||
{ Instructions::v128_load8_splat, "v128.load8_splat" },
|
||||
{ Instructions::v128_load16_splat, "v128.load16_splat" },
|
||||
{ Instructions::v128_load32_splat, "v128.load32_splat" },
|
||||
{ Instructions::v128_load64_splat, "v128.load64_splat" },
|
||||
{ Instructions::v128_store, "v128.store" },
|
||||
{ Instructions::v128_const, "v128.const" },
|
||||
{ Instructions::i8x16_shuffle, "i8x16.shuffle" },
|
||||
{ Instructions::i8x16_swizzle, "i8x16.swizzle" },
|
||||
{ Instructions::i8x16_splat, "i8x16.splat" },
|
||||
{ Instructions::i16x8_splat, "i16x8.splat" },
|
||||
{ Instructions::i32x4_splat, "i32x4.splat" },
|
||||
{ Instructions::i64x2_splat, "i64x2.splat" },
|
||||
{ Instructions::f32x4_splat, "f32x4.splat" },
|
||||
{ Instructions::f64x2_splat, "f64x2.splat" },
|
||||
{ Instructions::i8x16_extract_lane_s, "i8x16.extract_lane_s" },
|
||||
{ Instructions::i8x16_extract_lane_u, "i8x16.extract_lane_u" },
|
||||
{ Instructions::i8x16_replace_lane, "i8x16.replace_lane" },
|
||||
{ Instructions::i16x8_extract_lane_s, "i16x8.extract_lane_s" },
|
||||
{ Instructions::i16x8_extract_lane_u, "i16x8.extract_lane_u" },
|
||||
{ Instructions::i16x8_replace_lane, "i16x8.replace_lane" },
|
||||
{ Instructions::i32x4_extract_lane, "i32x4.extract_lane" },
|
||||
{ Instructions::i32x4_replace_lane, "i32x4.replace_lane" },
|
||||
{ Instructions::i64x2_extract_lane, "i64x2.extract_lane" },
|
||||
{ Instructions::i64x2_replace_lane, "i64x2.replace_lane" },
|
||||
{ Instructions::f32x4_extract_lane, "f32x4.extract_lane" },
|
||||
{ Instructions::f32x4_replace_lane, "f32x4.replace_lane" },
|
||||
{ Instructions::f64x2_extract_lane, "f64x2.extract_lane" },
|
||||
{ Instructions::f64x2_replace_lane, "f64x2.replace_lane" },
|
||||
{ Instructions::i8x16_eq, "i8x16.eq" },
|
||||
{ Instructions::i8x16_ne, "i8x16.ne" },
|
||||
{ Instructions::i8x16_lt_s, "i8x16.lt_s" },
|
||||
{ Instructions::i8x16_lt_u, "i8x16.lt_u" },
|
||||
{ Instructions::i8x16_gt_s, "i8x16.gt_s" },
|
||||
{ Instructions::i8x16_gt_u, "i8x16.gt_u" },
|
||||
{ Instructions::i8x16_le_s, "i8x16.le_s" },
|
||||
{ Instructions::i8x16_le_u, "i8x16.le_u" },
|
||||
{ Instructions::i8x16_ge_s, "i8x16.ge_s" },
|
||||
{ Instructions::i8x16_ge_u, "i8x16.ge_u" },
|
||||
{ Instructions::i16x8_eq, "i16x8.eq" },
|
||||
{ Instructions::i16x8_ne, "i16x8.ne" },
|
||||
{ Instructions::i16x8_lt_s, "i16x8.lt_s" },
|
||||
{ Instructions::i16x8_lt_u, "i16x8.lt_u" },
|
||||
{ Instructions::i16x8_gt_s, "i16x8.gt_s" },
|
||||
{ Instructions::i16x8_gt_u, "i16x8.gt_u" },
|
||||
{ Instructions::i16x8_le_s, "i16x8.le_s" },
|
||||
{ Instructions::i16x8_le_u, "i16x8.le_u" },
|
||||
{ Instructions::i16x8_ge_s, "i16x8.ge_s" },
|
||||
{ Instructions::i16x8_ge_u, "i16x8.ge_u" },
|
||||
{ Instructions::i32x4_eq, "i32x4.eq" },
|
||||
{ Instructions::i32x4_ne, "i32x4.ne" },
|
||||
{ Instructions::i32x4_lt_s, "i32x4.lt_s" },
|
||||
{ Instructions::i32x4_lt_u, "i32x4.lt_u" },
|
||||
{ Instructions::i32x4_gt_s, "i32x4.gt_s" },
|
||||
{ Instructions::i32x4_gt_u, "i32x4.gt_u" },
|
||||
{ Instructions::i32x4_le_s, "i32x4.le_s" },
|
||||
{ Instructions::i32x4_le_u, "i32x4.le_u" },
|
||||
{ Instructions::i32x4_ge_s, "i32x4.ge_s" },
|
||||
{ Instructions::i32x4_ge_u, "i32x4.ge_u" },
|
||||
{ Instructions::f32x4_eq, "f32x4.eq" },
|
||||
{ Instructions::f32x4_ne, "f32x4.ne" },
|
||||
{ Instructions::f32x4_lt, "f32x4.lt" },
|
||||
{ Instructions::f32x4_gt, "f32x4.gt" },
|
||||
{ Instructions::f32x4_le, "f32x4.le" },
|
||||
{ Instructions::f32x4_ge, "f32x4.ge" },
|
||||
{ Instructions::f64x2_eq, "f64x2.eq" },
|
||||
{ Instructions::f64x2_ne, "f64x2.ne" },
|
||||
{ Instructions::f64x2_lt, "f64x2.lt" },
|
||||
{ Instructions::f64x2_gt, "f64x2.gt" },
|
||||
{ Instructions::f64x2_le, "f64x2.le" },
|
||||
{ Instructions::f64x2_ge, "f64x2.ge" },
|
||||
{ Instructions::v128_not, "v128.not" },
|
||||
{ Instructions::v128_and, "v128.and" },
|
||||
{ Instructions::v128_andnot, "v128.andnot" },
|
||||
{ Instructions::v128_or, "v128.or" },
|
||||
{ Instructions::v128_xor, "v128.xor" },
|
||||
{ Instructions::v128_bitselect, "v128.bitselect" },
|
||||
{ Instructions::v128_any_true, "v128.any_true" },
|
||||
{ Instructions::v128_load8_lane, "v128.load8_lane" },
|
||||
{ Instructions::v128_load16_lane, "v128.load16_lane" },
|
||||
{ Instructions::v128_load32_lane, "v128.load32_lane" },
|
||||
{ Instructions::v128_load64_lane, "v128.load64_lane" },
|
||||
{ Instructions::v128_store8_lane, "v128.store8_lane" },
|
||||
{ Instructions::v128_store16_lane, "v128.store16_lane" },
|
||||
{ Instructions::v128_store32_lane, "v128.store32_lane" },
|
||||
{ Instructions::v128_store64_lane, "v128.store64_lane" },
|
||||
{ Instructions::v128_load32_zero, "v128.load32_zero" },
|
||||
{ Instructions::v128_load64_zero, "v128.load64_zero" },
|
||||
{ Instructions::f32x4_demote_f64x2_zero, "f32x4.demote_f64x2_zero" },
|
||||
{ Instructions::f64x2_promote_low_f32x4, "f64x2.promote_low_f32x4" },
|
||||
{ Instructions::i8x16_abs, "i8x16.abs" },
|
||||
{ Instructions::i8x16_neg, "i8x16.neg" },
|
||||
{ Instructions::i8x16_popcnt, "i8x16.popcnt" },
|
||||
{ Instructions::i8x16_all_true, "i8x16.all_true" },
|
||||
{ Instructions::i8x16_bitmask, "i8x16.bitmask" },
|
||||
{ Instructions::i8x16_narrow_i16x8_s, "i8x16.narrow_i16x8_s" },
|
||||
{ Instructions::i8x16_narrow_i16x8_u, "i8x16.narrow_i16x8_u" },
|
||||
{ Instructions::f32x4_ceil, "f32x4.ceil" },
|
||||
{ Instructions::f32x4_floor, "f32x4.floor" },
|
||||
{ Instructions::f32x4_trunc, "f32x4.trunc" },
|
||||
{ Instructions::f32x4_nearest, "f32x4.nearest" },
|
||||
{ Instructions::i8x16_shl, "i8x16.shl" },
|
||||
{ Instructions::i8x16_shr_s, "i8x16.shr_s" },
|
||||
{ Instructions::i8x16_shr_u, "i8x16.shr_u" },
|
||||
{ Instructions::i8x16_add, "i8x16.add" },
|
||||
{ Instructions::i8x16_add_sat_s, "i8x16.add_sat_s" },
|
||||
{ Instructions::i8x16_add_sat_u, "i8x16.add_sat_u" },
|
||||
{ Instructions::i8x16_sub, "i8x16.sub" },
|
||||
{ Instructions::i8x16_sub_sat_s, "i8x16.sub_sat_s" },
|
||||
{ Instructions::i8x16_sub_sat_u, "i8x16.sub_sat_u" },
|
||||
{ Instructions::f64x2_ceil, "f64x2.ceil" },
|
||||
{ Instructions::f64x2_floor, "f64x2.floor" },
|
||||
{ Instructions::i8x16_min_s, "i8x16.min_s" },
|
||||
{ Instructions::i8x16_min_u, "i8x16.min_u" },
|
||||
{ Instructions::i8x16_max_s, "i8x16.max_s" },
|
||||
{ Instructions::i8x16_max_u, "i8x16.max_u" },
|
||||
{ Instructions::f64x2_trunc, "f64x2.trunc" },
|
||||
{ Instructions::i8x16_avgr_u, "i8x16.avgr_u" },
|
||||
{ Instructions::i16x8_extadd_pairwise_i8x16_s, "i16x8.extadd_pairwise_i8x16_s" },
|
||||
{ Instructions::i16x8_extadd_pairwise_i8x16_u, "i16x8.extadd_pairwise_i8x16_u" },
|
||||
{ Instructions::i32x4_extadd_pairwise_i16x8_s, "i32x4.extadd_pairwise_i16x8_s" },
|
||||
{ Instructions::i32x4_extadd_pairwise_i16x8_u, "i32x4.extadd_pairwise_i16x8_u" },
|
||||
{ Instructions::i16x8_abs, "i16x8.abs" },
|
||||
{ Instructions::i16x8_neg, "i16x8.neg" },
|
||||
{ Instructions::i16x8_q15mulr_sat_s, "i16x8.q15mulr_sat_s" },
|
||||
{ Instructions::i16x8_all_true, "i16x8.all_true" },
|
||||
{ Instructions::i16x8_bitmask, "i16x8.bitmask" },
|
||||
{ Instructions::i16x8_narrow_i32x4_s, "i16x8.narrow_i32x4_s" },
|
||||
{ Instructions::i16x8_narrow_i32x4_u, "i16x8.narrow_i32x4_u" },
|
||||
{ Instructions::i16x8_extend_low_i8x16_s, "i16x8.extend_low_i8x16_s" },
|
||||
{ Instructions::i16x8_extend_high_i8x16_s, "i16x8.extend_high_i8x16_s" },
|
||||
{ Instructions::i16x8_extend_low_i8x16_u, "i16x8.extend_low_i8x16_u" },
|
||||
{ Instructions::i16x8_extend_high_i8x16_u, "i16x8.extend_high_i8x16_u" },
|
||||
{ Instructions::i16x8_shl, "i16x8.shl" },
|
||||
{ Instructions::i16x8_shr_s, "i16x8.shr_s" },
|
||||
{ Instructions::i16x8_shr_u, "i16x8.shr_u" },
|
||||
{ Instructions::i16x8_add, "i16x8.add" },
|
||||
{ Instructions::i16x8_add_sat_s, "i16x8.add_sat_s" },
|
||||
{ Instructions::i16x8_add_sat_u, "i16x8.add_sat_u" },
|
||||
{ Instructions::i16x8_sub, "i16x8.sub" },
|
||||
{ Instructions::i16x8_sub_sat_s, "i16x8.sub_sat_s" },
|
||||
{ Instructions::i16x8_sub_sat_u, "i16x8.sub_sat_u" },
|
||||
{ Instructions::f64x2_nearest, "f64x2.nearest" },
|
||||
{ Instructions::i16x8_mul, "i16x8.mul" },
|
||||
{ Instructions::i16x8_min_s, "i16x8.min_s" },
|
||||
{ Instructions::i16x8_min_u, "i16x8.min_u" },
|
||||
{ Instructions::i16x8_max_s, "i16x8.max_s" },
|
||||
{ Instructions::i16x8_max_u, "i16x8.max_u" },
|
||||
{ Instructions::i16x8_avgr_u, "i16x8.avgr_u" },
|
||||
{ Instructions::i16x8_extmul_low_i8x16_s, "i16x8.extmul_low_i8x16_s" },
|
||||
{ Instructions::i16x8_extmul_high_i8x16_s, "i16x8.extmul_high_i8x16_s" },
|
||||
{ Instructions::i16x8_extmul_low_i8x16_u, "i16x8.extmul_low_i8x16_u" },
|
||||
{ Instructions::i16x8_extmul_high_i8x16_u, "i16x8.extmul_high_i8x16_u" },
|
||||
{ Instructions::i32x4_abs, "i32x4.abs" },
|
||||
{ Instructions::i32x4_neg, "i32x4.neg" },
|
||||
{ Instructions::i32x4_all_true, "i32x4.all_true" },
|
||||
{ Instructions::i32x4_bitmask, "i32x4.bitmask" },
|
||||
{ Instructions::i32x4_extend_low_i16x8_s, "i32x4.extend_low_i16x8_s" },
|
||||
{ Instructions::i32x4_extend_high_i16x8_s, "i32x4.extend_high_i16x8_s" },
|
||||
{ Instructions::i32x4_extend_low_i16x8_u, "i32x4.extend_low_i16x8_u" },
|
||||
{ Instructions::i32x4_extend_high_i16x8_u, "i32x4.extend_high_i16x8_u" },
|
||||
{ Instructions::i32x4_shl, "i32x4.shl" },
|
||||
{ Instructions::i32x4_shr_s, "i32x4.shr_s" },
|
||||
{ Instructions::i32x4_shr_u, "i32x4.shr_u" },
|
||||
{ Instructions::i32x4_add, "i32x4.add" },
|
||||
{ Instructions::i32x4_sub, "i32x4.sub" },
|
||||
{ Instructions::i32x4_mul, "i32x4.mul" },
|
||||
{ Instructions::i32x4_min_s, "i32x4.min_s" },
|
||||
{ Instructions::i32x4_min_u, "i32x4.min_u" },
|
||||
{ Instructions::i32x4_max_s, "i32x4.max_s" },
|
||||
{ Instructions::i32x4_max_u, "i32x4.max_u" },
|
||||
{ Instructions::i32x4_dot_i16x8_s, "i32x4.dot_i16x8_s" },
|
||||
{ Instructions::i32x4_extmul_low_i16x8_s, "i32x4.extmul_low_i16x8_s" },
|
||||
{ Instructions::i32x4_extmul_high_i16x8_s, "i32x4.extmul_high_i16x8_s" },
|
||||
{ Instructions::i32x4_extmul_low_i16x8_u, "i32x4.extmul_low_i16x8_u" },
|
||||
{ Instructions::i32x4_extmul_high_i16x8_u, "i32x4.extmul_high_i16x8_u" },
|
||||
{ Instructions::i64x2_abs, "i64x2.abs" },
|
||||
{ Instructions::i64x2_neg, "i64x2.neg" },
|
||||
{ Instructions::i64x2_all_true, "i64x2.all_true" },
|
||||
{ Instructions::i64x2_bitmask, "i64x2.bitmask" },
|
||||
{ Instructions::i64x2_extend_low_i32x4_s, "i64x2.extend_low_i32x4_s" },
|
||||
{ Instructions::i64x2_extend_high_i32x4_s, "i64x2.extend_high_i32x4_s" },
|
||||
{ Instructions::i64x2_extend_low_i32x4_u, "i64x2.extend_low_i32x4_u" },
|
||||
{ Instructions::i64x2_extend_high_i32x4_u, "i64x2.extend_high_i32x4_u" },
|
||||
{ Instructions::i64x2_shl, "i64x2.shl" },
|
||||
{ Instructions::i64x2_shr_s, "i64x2.shr_s" },
|
||||
{ Instructions::i64x2_shr_u, "i64x2.shr_u" },
|
||||
{ Instructions::i64x2_add, "i64x2.add" },
|
||||
{ Instructions::i64x2_sub, "i64x2.sub" },
|
||||
{ Instructions::i64x2_mul, "i64x2.mul" },
|
||||
{ Instructions::i64x2_eq, "i64x2.eq" },
|
||||
{ Instructions::i64x2_ne, "i64x2.ne" },
|
||||
{ Instructions::i64x2_lt_s, "i64x2.lt_s" },
|
||||
{ Instructions::i64x2_gt_s, "i64x2.gt_s" },
|
||||
{ Instructions::i64x2_le_s, "i64x2.le_s" },
|
||||
{ Instructions::i64x2_ge_s, "i64x2.ge_s" },
|
||||
{ Instructions::i64x2_extmul_low_i32x4_s, "i64x2.extmul_low_i32x4_s" },
|
||||
{ Instructions::i64x2_extmul_high_i32x4_s, "i64x2.extmul_high_i32x4_s" },
|
||||
{ Instructions::i64x2_extmul_low_i32x4_u, "i64x2.extmul_low_i32x4_u" },
|
||||
{ Instructions::i64x2_extmul_high_i32x4_u, "i64x2.extmul_high_i32x4_u" },
|
||||
{ Instructions::f32x4_abs, "f32x4.abs" },
|
||||
{ Instructions::f32x4_neg, "f32x4.neg" },
|
||||
{ Instructions::f32x4_sqrt, "f32x4.sqrt" },
|
||||
{ Instructions::f32x4_add, "f32x4.add" },
|
||||
{ Instructions::f32x4_sub, "f32x4.sub" },
|
||||
{ Instructions::f32x4_mul, "f32x4.mul" },
|
||||
{ Instructions::f32x4_div, "f32x4.div" },
|
||||
{ Instructions::f32x4_min, "f32x4.min" },
|
||||
{ Instructions::f32x4_max, "f32x4.max" },
|
||||
{ Instructions::f32x4_pmin, "f32x4.pmin" },
|
||||
{ Instructions::f32x4_pmax, "f32x4.pmax" },
|
||||
{ Instructions::f64x2_abs, "f64x2.abs" },
|
||||
{ Instructions::f64x2_neg, "f64x2.neg" },
|
||||
{ Instructions::f64x2_sqrt, "f64x2.sqrt" },
|
||||
{ Instructions::f64x2_add, "f64x2.add" },
|
||||
{ Instructions::f64x2_sub, "f64x2.sub" },
|
||||
{ Instructions::f64x2_mul, "f64x2.mul" },
|
||||
{ Instructions::f64x2_div, "f64x2.div" },
|
||||
{ Instructions::f64x2_min, "f64x2.min" },
|
||||
{ Instructions::f64x2_max, "f64x2.max" },
|
||||
{ Instructions::f64x2_pmin, "f64x2.pmin" },
|
||||
{ Instructions::f64x2_pmax, "f64x2.pmax" },
|
||||
{ Instructions::i32x4_trunc_sat_f32x4_s, "i32x4.trunc_sat_f32x4_s" },
|
||||
{ Instructions::i32x4_trunc_sat_f32x4_u, "i32x4.trunc_sat_f32x4_u" },
|
||||
{ Instructions::f32x4_convert_i32x4_s, "f32x4.convert_i32x4_s" },
|
||||
{ Instructions::f32x4_convert_i32x4_u, "f32x4.convert_i32x4_u" },
|
||||
{ Instructions::i32x4_trunc_sat_f64x2_s_zero, "i32x4.trunc_sat_f64x2_s_zero" },
|
||||
{ Instructions::i32x4_trunc_sat_f64x2_u_zero, "i32x4.trunc_sat_f64x2_u_zero" },
|
||||
{ Instructions::f64x2_convert_low_i32x4_s, "f64x2.convert_low_i32x4_s" },
|
||||
{ Instructions::f64x2_convert_low_i32x4_u, "f64x2.convert_low_i32x4_u" },
|
||||
{ Instructions::structured_else, "synthetic:else" },
|
||||
{ Instructions::structured_end, "synthetic:end" },
|
||||
};
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#include <AK/DistinctNumeric.h>
|
||||
#include <AK/LEB128.h>
|
||||
#include <AK/Result.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/UFixedBigInt.h>
|
||||
#include <AK/Variant.h>
|
||||
#include <LibWasm/Constants.h>
|
||||
#include <LibWasm/Forward.h>
|
||||
|
@ -143,6 +145,7 @@ public:
|
|||
I64,
|
||||
F32,
|
||||
F64,
|
||||
V128,
|
||||
FunctionReference,
|
||||
ExternReference,
|
||||
NullFunctionReference,
|
||||
|
@ -157,7 +160,8 @@ public:
|
|||
bool operator==(ValueType const&) const = default;
|
||||
|
||||
auto is_reference() const { return m_kind == ExternReference || m_kind == FunctionReference || m_kind == NullExternReference || m_kind == NullFunctionReference; }
|
||||
auto is_numeric() const { return !is_reference(); }
|
||||
auto is_vector() const { return m_kind == V128; }
|
||||
auto is_numeric() const { return !is_reference() && !is_vector(); }
|
||||
auto kind() const { return m_kind; }
|
||||
|
||||
static ParseResult<ValueType> parse(Stream& stream);
|
||||
|
@ -173,6 +177,8 @@ public:
|
|||
return "f32";
|
||||
case F64:
|
||||
return "f64";
|
||||
case V128:
|
||||
return "v128";
|
||||
case FunctionReference:
|
||||
return "funcref";
|
||||
case ExternReference:
|
||||
|
@ -394,6 +400,27 @@ public:
|
|||
u32 offset;
|
||||
};
|
||||
|
||||
struct MemoryAndLaneArgument {
|
||||
MemoryArgument memory;
|
||||
u8 lane;
|
||||
};
|
||||
|
||||
struct LaneIndex {
|
||||
u8 lane;
|
||||
};
|
||||
|
||||
struct ShuffleArgument {
|
||||
explicit ShuffleArgument(u8 (&lanes)[16])
|
||||
: lanes {
|
||||
lanes[0], lanes[1], lanes[2], lanes[3], lanes[4], lanes[5], lanes[6], lanes[7],
|
||||
lanes[8], lanes[9], lanes[10], lanes[11], lanes[12], lanes[13], lanes[14], lanes[15]
|
||||
}
|
||||
{
|
||||
}
|
||||
|
||||
u8 lanes[16];
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
explicit Instruction(OpCode opcode, T argument)
|
||||
: m_opcode(opcode)
|
||||
|
@ -417,9 +444,12 @@ private:
|
|||
GlobalIndex,
|
||||
IndirectCallArgs,
|
||||
LabelIndex,
|
||||
LaneIndex,
|
||||
LocalIndex,
|
||||
MemoryArgument,
|
||||
MemoryAndLaneArgument,
|
||||
StructuredInstructionArgs,
|
||||
ShuffleArgument,
|
||||
TableBranchArgs,
|
||||
TableElementArgs,
|
||||
TableIndex,
|
||||
|
@ -430,6 +460,7 @@ private:
|
|||
float,
|
||||
i32,
|
||||
i64,
|
||||
u128,
|
||||
u8 // Empty state
|
||||
> m_arguments;
|
||||
// clang-format on
|
||||
|
|
|
@ -416,6 +416,8 @@ JS::ThrowCompletionOr<Wasm::Value> to_webassembly_value(JS::VM& vm, JS::Value va
|
|||
case Wasm::ValueType::ExternReference:
|
||||
case Wasm::ValueType::NullExternReference:
|
||||
TODO();
|
||||
case Wasm::ValueType::V128:
|
||||
return vm.throw_completion<JS::TypeError>("Cannot convert a vector value to a javascript value"sv);
|
||||
}
|
||||
|
||||
VERIFY_NOT_REACHED();
|
||||
|
@ -438,6 +440,7 @@ JS::Value to_js_value(JS::VM& vm, Wasm::Value& wasm_value)
|
|||
return create_native_function(vm, wasm_value.to<Wasm::Reference::Func>().value().address, "FIXME_IHaveNoIdeaWhatThisShouldBeCalled");
|
||||
case Wasm::ValueType::NullFunctionReference:
|
||||
return JS::js_null();
|
||||
case Wasm::ValueType::V128:
|
||||
case Wasm::ValueType::ExternReference:
|
||||
case Wasm::ValueType::NullExternReference:
|
||||
TODO();
|
||||
|
|
Loading…
Reference in a new issue