BytecodeInterpreter.cpp 101 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733
  1. /*
  2. * Copyright (c) 2021, Ali Mohammad Pur <mpfard@serenityos.org>
  3. * Copyright (c) 2023, Sam Atkins <atkinssj@serenityos.org>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include <AK/ByteReader.h>
  8. #include <AK/Debug.h>
  9. #include <AK/Endian.h>
  10. #include <AK/MemoryStream.h>
  11. #include <AK/NumericLimits.h>
  12. #include <AK/SIMDExtras.h>
  13. #include <LibWasm/AbstractMachine/AbstractMachine.h>
  14. #include <LibWasm/AbstractMachine/BytecodeInterpreter.h>
  15. #include <LibWasm/AbstractMachine/Configuration.h>
  16. #include <LibWasm/AbstractMachine/Operators.h>
  17. #include <LibWasm/Opcode.h>
  18. #include <LibWasm/Printer/Printer.h>
  19. using namespace AK::SIMD;
  20. namespace Wasm {
  21. #define TRAP_IF_NOT(x) \
  22. do { \
  23. if (trap_if_not(x, #x##sv)) { \
  24. dbgln_if(WASM_TRACE_DEBUG, "Trapped because {} failed, at line {}", #x, __LINE__); \
  25. return; \
  26. } \
  27. } while (false)
  28. void BytecodeInterpreter::interpret(Configuration& configuration)
  29. {
  30. m_trap = Empty {};
  31. auto& instructions = configuration.frame().expression().instructions();
  32. auto max_ip_value = InstructionPointer { instructions.size() };
  33. auto& current_ip_value = configuration.ip();
  34. auto const should_limit_instruction_count = configuration.should_limit_instruction_count();
  35. u64 executed_instructions = 0;
  36. while (current_ip_value < max_ip_value) {
  37. if (should_limit_instruction_count) {
  38. if (executed_instructions++ >= Constants::max_allowed_executed_instructions_per_call) [[unlikely]] {
  39. m_trap = Trap { "Exceeded maximum allowed number of instructions" };
  40. return;
  41. }
  42. }
  43. auto& instruction = instructions[current_ip_value.value()];
  44. auto old_ip = current_ip_value;
  45. interpret(configuration, current_ip_value, instruction);
  46. if (did_trap())
  47. return;
  48. if (current_ip_value == old_ip) // If no jump occurred
  49. ++current_ip_value;
  50. }
  51. }
  52. void BytecodeInterpreter::branch_to_label(Configuration& configuration, LabelIndex index)
  53. {
  54. dbgln_if(WASM_TRACE_DEBUG, "Branch to label with index {}...", index.value());
  55. auto label = configuration.nth_label(index.value());
  56. dbgln_if(WASM_TRACE_DEBUG, "...which is actually IP {}, and has {} result(s)", label->continuation().value(), label->arity());
  57. auto results = pop_values(configuration, label->arity());
  58. size_t drop_count = index.value() + 1;
  59. for (; !configuration.stack().is_empty();) {
  60. auto& entry = configuration.stack().peek();
  61. if (entry.has<Label>()) {
  62. if (--drop_count == 0)
  63. break;
  64. }
  65. configuration.stack().pop();
  66. }
  67. for (auto& result : results.in_reverse())
  68. configuration.stack().push(move(result));
  69. configuration.ip() = label->continuation();
  70. }
  71. template<typename ReadType, typename PushType>
  72. void BytecodeInterpreter::load_and_push(Configuration& configuration, Instruction const& instruction)
  73. {
  74. auto& arg = instruction.arguments().get<Instruction::MemoryArgument>();
  75. auto& address = configuration.frame().module().memories()[arg.memory_index.value()];
  76. auto memory = configuration.store().get(address);
  77. auto& entry = configuration.stack().peek();
  78. auto base = *entry.get<Value>().to<i32>();
  79. u64 instance_address = static_cast<u64>(bit_cast<u32>(base)) + arg.offset;
  80. if (instance_address + sizeof(ReadType) > memory->size()) {
  81. m_trap = Trap { "Memory access out of bounds" };
  82. dbgln("LibWasm: Memory access out of bounds (expected {} to be less than or equal to {})", instance_address + sizeof(ReadType), memory->size());
  83. return;
  84. }
  85. dbgln_if(WASM_TRACE_DEBUG, "load({} : {}) -> stack", instance_address, sizeof(ReadType));
  86. auto slice = memory->data().bytes().slice(instance_address, sizeof(ReadType));
  87. configuration.stack().peek() = Value(static_cast<PushType>(read_value<ReadType>(slice)));
  88. }
  89. template<typename TDst, typename TSrc>
  90. ALWAYS_INLINE static TDst convert_vector(TSrc v)
  91. {
  92. return __builtin_convertvector(v, TDst);
  93. }
  94. template<size_t M, size_t N, template<typename> typename SetSign>
  95. void BytecodeInterpreter::load_and_push_mxn(Configuration& configuration, Instruction const& instruction)
  96. {
  97. auto& arg = instruction.arguments().get<Instruction::MemoryArgument>();
  98. auto& address = configuration.frame().module().memories()[arg.memory_index.value()];
  99. auto memory = configuration.store().get(address);
  100. auto& entry = configuration.stack().peek();
  101. auto base = *entry.get<Value>().to<i32>();
  102. u64 instance_address = static_cast<u64>(bit_cast<u32>(base)) + arg.offset;
  103. if (instance_address + M * N / 8 > memory->size()) {
  104. m_trap = Trap { "Memory access out of bounds" };
  105. dbgln("LibWasm: Memory access out of bounds (expected {} to be less than or equal to {})", instance_address + M * N / 8, memory->size());
  106. return;
  107. }
  108. dbgln_if(WASM_TRACE_DEBUG, "vec-load({} : {}) -> stack", instance_address, M * N / 8);
  109. auto slice = memory->data().bytes().slice(instance_address, M * N / 8);
  110. using V64 = NativeVectorType<M, N, SetSign>;
  111. using V128 = NativeVectorType<M * 2, N, SetSign>;
  112. V64 bytes { 0 };
  113. if (bit_cast<FlatPtr>(slice.data()) % sizeof(V64) == 0)
  114. bytes = *bit_cast<V64*>(slice.data());
  115. else
  116. ByteReader::load(slice.data(), bytes);
  117. configuration.stack().peek() = Value(bit_cast<u128>(convert_vector<V128>(bytes)));
  118. }
  119. template<size_t N>
  120. void BytecodeInterpreter::load_and_push_lane_n(Configuration& configuration, Instruction const& instruction)
  121. {
  122. auto memarg_and_lane = instruction.arguments().get<Instruction::MemoryAndLaneArgument>();
  123. auto& address = configuration.frame().module().memories()[memarg_and_lane.memory.memory_index.value()];
  124. auto memory = configuration.store().get(address);
  125. auto vector = *configuration.stack().pop().get<Value>().to<u128>();
  126. auto base = *configuration.stack().pop().get<Value>().to<u32>();
  127. u64 instance_address = static_cast<u64>(bit_cast<u32>(base)) + memarg_and_lane.memory.offset;
  128. if (instance_address + N / 8 > memory->size()) {
  129. m_trap = Trap { "Memory access out of bounds" };
  130. return;
  131. }
  132. auto slice = memory->data().bytes().slice(instance_address, N / 8);
  133. auto dst = bit_cast<u8*>(&vector) + memarg_and_lane.lane * N / 8;
  134. memcpy(dst, slice.data(), N / 8);
  135. configuration.stack().push(Value(vector));
  136. }
  137. template<size_t N>
  138. void BytecodeInterpreter::load_and_push_zero_n(Configuration& configuration, Instruction const& instruction)
  139. {
  140. auto memarg_and_lane = instruction.arguments().get<Instruction::MemoryArgument>();
  141. auto& address = configuration.frame().module().memories()[memarg_and_lane.memory_index.value()];
  142. auto memory = configuration.store().get(address);
  143. auto base = *configuration.stack().pop().get<Value>().to<u32>();
  144. u64 instance_address = static_cast<u64>(bit_cast<u32>(base)) + memarg_and_lane.offset;
  145. if (instance_address + N / 8 > memory->size()) {
  146. m_trap = Trap { "Memory access out of bounds" };
  147. return;
  148. }
  149. auto slice = memory->data().bytes().slice(instance_address, N / 8);
  150. u128 vector = 0;
  151. memcpy(&vector, slice.data(), N / 8);
  152. configuration.stack().push(Value(vector));
  153. }
  154. template<size_t M>
  155. void BytecodeInterpreter::load_and_push_m_splat(Configuration& configuration, Instruction const& instruction)
  156. {
  157. auto& arg = instruction.arguments().get<Instruction::MemoryArgument>();
  158. auto& address = configuration.frame().module().memories()[arg.memory_index.value()];
  159. auto memory = configuration.store().get(address);
  160. auto& entry = configuration.stack().peek();
  161. auto base = *entry.get<Value>().to<i32>();
  162. u64 instance_address = static_cast<u64>(bit_cast<u32>(base)) + arg.offset;
  163. if (instance_address + M / 8 > memory->size()) {
  164. m_trap = Trap { "Memory access out of bounds" };
  165. dbgln("LibWasm: Memory access out of bounds (expected {} to be less than or equal to {})", instance_address + M / 8, memory->size());
  166. return;
  167. }
  168. dbgln_if(WASM_TRACE_DEBUG, "vec-splat({} : {}) -> stack", instance_address, M / 8);
  169. auto slice = memory->data().bytes().slice(instance_address, M / 8);
  170. auto value = read_value<NativeIntegralType<M>>(slice);
  171. set_top_m_splat<M, NativeIntegralType>(configuration, value);
  172. }
  173. template<size_t M, template<size_t> typename NativeType>
  174. void BytecodeInterpreter::set_top_m_splat(Wasm::Configuration& configuration, NativeType<M> value)
  175. {
  176. auto push = [&](auto result) {
  177. configuration.stack().peek() = Value(bit_cast<u128>(result));
  178. };
  179. if constexpr (IsFloatingPoint<NativeType<32>>) {
  180. if constexpr (M == 32) // 32 -> 32x4
  181. push(expand4(value));
  182. else if constexpr (M == 64) // 64 -> 64x2
  183. push(f64x2 { value, value });
  184. else
  185. static_assert(DependentFalse<NativeType<M>>, "Invalid vector size");
  186. } else {
  187. if constexpr (M == 8) // 8 -> 8x4 -> 32x4
  188. push(expand4(bit_cast<u32>(u8x4 { value, value, value, value })));
  189. else if constexpr (M == 16) // 16 -> 16x2 -> 32x4
  190. push(expand4(bit_cast<u32>(u16x2 { value, value })));
  191. else if constexpr (M == 32) // 32 -> 32x4
  192. push(expand4(value));
  193. else if constexpr (M == 64) // 64 -> 64x2
  194. push(u64x2 { value, value });
  195. else
  196. static_assert(DependentFalse<NativeType<M>>, "Invalid vector size");
  197. }
  198. }
  199. template<size_t M, template<size_t> typename NativeType>
  200. void BytecodeInterpreter::pop_and_push_m_splat(Wasm::Configuration& configuration, Instruction const&)
  201. {
  202. using PopT = Conditional<M <= 32, NativeType<32>, NativeType<64>>;
  203. using ReadT = NativeType<M>;
  204. auto entry = configuration.stack().peek();
  205. auto value = static_cast<ReadT>(*entry.get<Value>().to<PopT>());
  206. dbgln_if(WASM_TRACE_DEBUG, "stack({}) -> splat({})", value, M);
  207. set_top_m_splat<M, NativeType>(configuration, value);
  208. }
  209. template<typename M, template<typename> typename SetSign, typename VectorType>
  210. VectorType BytecodeInterpreter::pop_vector(Configuration& configuration)
  211. {
  212. return bit_cast<VectorType>(configuration.stack().pop().get<Value>().value().get<u128>());
  213. }
  214. void BytecodeInterpreter::call_address(Configuration& configuration, FunctionAddress address)
  215. {
  216. TRAP_IF_NOT(m_stack_info.size_free() >= Constants::minimum_stack_space_to_keep_free);
  217. auto instance = configuration.store().get(address);
  218. FunctionType const* type { nullptr };
  219. instance->visit([&](auto const& function) { type = &function.type(); });
  220. TRAP_IF_NOT(configuration.stack().entries().size() > type->parameters().size());
  221. Vector<Value> args;
  222. args.ensure_capacity(type->parameters().size());
  223. auto span = configuration.stack().entries().span().slice_from_end(type->parameters().size());
  224. for (auto& entry : span) {
  225. auto* call_argument = entry.get_pointer<Value>();
  226. TRAP_IF_NOT(call_argument);
  227. args.unchecked_append(move(*call_argument));
  228. }
  229. configuration.stack().entries().remove(configuration.stack().size() - span.size(), span.size());
  230. Result result { Trap { ""sv } };
  231. {
  232. CallFrameHandle handle { *this, configuration };
  233. result = configuration.call(*this, address, move(args));
  234. }
  235. if (result.is_trap()) {
  236. m_trap = move(result.trap());
  237. return;
  238. }
  239. if (result.is_completion()) {
  240. m_trap = move(result.completion());
  241. return;
  242. }
  243. configuration.stack().entries().ensure_capacity(configuration.stack().size() + result.values().size());
  244. for (auto& entry : result.values().in_reverse())
  245. configuration.stack().entries().unchecked_append(move(entry));
  246. }
  247. template<typename PopTypeLHS, typename PushType, typename Operator, typename PopTypeRHS, typename... Args>
  248. void BytecodeInterpreter::binary_numeric_operation(Configuration& configuration, Args&&... args)
  249. {
  250. auto rhs = configuration.stack().pop().get<Value>().to<PopTypeRHS>();
  251. auto& lhs_entry = configuration.stack().peek();
  252. auto lhs = lhs_entry.get<Value>().to<PopTypeLHS>();
  253. PushType result;
  254. auto call_result = Operator { forward<Args>(args)... }(lhs.value(), rhs.value());
  255. if constexpr (IsSpecializationOf<decltype(call_result), AK::ErrorOr>) {
  256. if (call_result.is_error()) {
  257. trap_if_not(false, call_result.error());
  258. return;
  259. }
  260. result = call_result.release_value();
  261. } else {
  262. result = call_result;
  263. }
  264. dbgln_if(WASM_TRACE_DEBUG, "{} {} {} = {}", lhs.value(), Operator::name(), rhs.value(), result);
  265. lhs_entry = Value(result);
  266. }
  267. template<typename PopType, typename PushType, typename Operator, typename... Args>
  268. void BytecodeInterpreter::unary_operation(Configuration& configuration, Args&&... args)
  269. {
  270. auto& entry = configuration.stack().peek();
  271. auto value = entry.get<Value>().to<PopType>();
  272. auto call_result = Operator { forward<Args>(args)... }(*value);
  273. PushType result;
  274. if constexpr (IsSpecializationOf<decltype(call_result), AK::ErrorOr>) {
  275. if (call_result.is_error()) {
  276. trap_if_not(false, call_result.error());
  277. return;
  278. }
  279. result = call_result.release_value();
  280. } else {
  281. result = call_result;
  282. }
  283. dbgln_if(WASM_TRACE_DEBUG, "map({}) {} = {}", Operator::name(), *value, result);
  284. entry = Value(result);
  285. }
  286. template<typename T>
  287. struct ConvertToRaw {
  288. T operator()(T value)
  289. {
  290. return LittleEndian<T>(value);
  291. }
  292. };
  293. template<>
  294. struct ConvertToRaw<float> {
  295. u32 operator()(float value)
  296. {
  297. ReadonlyBytes bytes { &value, sizeof(float) };
  298. FixedMemoryStream stream { bytes };
  299. auto res = stream.read_value<LittleEndian<u32>>().release_value_but_fixme_should_propagate_errors();
  300. return static_cast<u32>(res);
  301. }
  302. };
  303. template<>
  304. struct ConvertToRaw<double> {
  305. u64 operator()(double value)
  306. {
  307. ReadonlyBytes bytes { &value, sizeof(double) };
  308. FixedMemoryStream stream { bytes };
  309. auto res = stream.read_value<LittleEndian<u64>>().release_value_but_fixme_should_propagate_errors();
  310. return static_cast<u64>(res);
  311. }
  312. };
  313. template<typename PopT, typename StoreT>
  314. void BytecodeInterpreter::pop_and_store(Configuration& configuration, Instruction const& instruction)
  315. {
  316. auto& memarg = instruction.arguments().get<Instruction::MemoryArgument>();
  317. auto entry = configuration.stack().pop();
  318. auto value = ConvertToRaw<StoreT> {}(*entry.get<Value>().to<PopT>());
  319. dbgln_if(WASM_TRACE_DEBUG, "stack({}) -> temporary({}b)", value, sizeof(StoreT));
  320. auto base_entry = configuration.stack().pop();
  321. auto base = base_entry.get<Value>().to<i32>();
  322. store_to_memory(configuration, memarg, { &value, sizeof(StoreT) }, *base);
  323. }
  324. template<size_t N>
  325. void BytecodeInterpreter::pop_and_store_lane_n(Configuration& configuration, Instruction const& instruction)
  326. {
  327. auto& memarg_and_lane = instruction.arguments().get<Instruction::MemoryAndLaneArgument>();
  328. auto vector = *configuration.stack().pop().get<Value>().to<u128>();
  329. auto src = bit_cast<u8*>(&vector) + memarg_and_lane.lane * N / 8;
  330. auto base = *configuration.stack().pop().get<Value>().to<u32>();
  331. store_to_memory(configuration, memarg_and_lane.memory, { src, N / 8 }, base);
  332. }
  333. void BytecodeInterpreter::store_to_memory(Configuration& configuration, Instruction::MemoryArgument const& arg, ReadonlyBytes data, u32 base)
  334. {
  335. auto& address = configuration.frame().module().memories()[arg.memory_index.value()];
  336. auto memory = configuration.store().get(address);
  337. u64 instance_address = static_cast<u64>(base) + arg.offset;
  338. Checked addition { instance_address };
  339. addition += data.size();
  340. if (addition.has_overflow() || addition.value() > memory->size()) {
  341. m_trap = Trap { "Memory access out of bounds" };
  342. dbgln("LibWasm: Memory access out of bounds (expected 0 <= {} and {} <= {})", instance_address, instance_address + data.size(), memory->size());
  343. return;
  344. }
  345. dbgln_if(WASM_TRACE_DEBUG, "temporary({}b) -> store({})", data.size(), instance_address);
  346. data.copy_to(memory->data().bytes().slice(instance_address, data.size()));
  347. }
  348. template<typename T>
  349. T BytecodeInterpreter::read_value(ReadonlyBytes data)
  350. {
  351. FixedMemoryStream stream { data };
  352. auto value_or_error = stream.read_value<LittleEndian<T>>();
  353. if (value_or_error.is_error()) {
  354. dbgln("Read from {} failed", data.data());
  355. m_trap = Trap { "Read from memory failed" };
  356. }
  357. return value_or_error.release_value();
  358. }
  359. template<>
  360. float BytecodeInterpreter::read_value<float>(ReadonlyBytes data)
  361. {
  362. FixedMemoryStream stream { data };
  363. auto raw_value_or_error = stream.read_value<LittleEndian<u32>>();
  364. if (raw_value_or_error.is_error())
  365. m_trap = Trap { "Read from memory failed" };
  366. auto raw_value = raw_value_or_error.release_value();
  367. return bit_cast<float>(static_cast<u32>(raw_value));
  368. }
  369. template<>
  370. double BytecodeInterpreter::read_value<double>(ReadonlyBytes data)
  371. {
  372. FixedMemoryStream stream { data };
  373. auto raw_value_or_error = stream.read_value<LittleEndian<u64>>();
  374. if (raw_value_or_error.is_error())
  375. m_trap = Trap { "Read from memory failed" };
  376. auto raw_value = raw_value_or_error.release_value();
  377. return bit_cast<double>(static_cast<u64>(raw_value));
  378. }
  379. Vector<Value> BytecodeInterpreter::pop_values(Configuration& configuration, size_t count)
  380. {
  381. Vector<Value> results;
  382. results.resize(count);
  383. for (size_t i = 0; i < count; ++i)
  384. results[i] = configuration.stack().pop().get<Value>();
  385. return results;
  386. }
  387. void BytecodeInterpreter::interpret(Configuration& configuration, InstructionPointer& ip, Instruction const& instruction)
  388. {
  389. dbgln_if(WASM_TRACE_DEBUG, "Executing instruction {} at ip {}", instruction_name(instruction.opcode()), ip.value());
  390. switch (instruction.opcode().value()) {
  391. case Instructions::unreachable.value():
  392. m_trap = Trap { "Unreachable" };
  393. return;
  394. case Instructions::nop.value():
  395. return;
  396. case Instructions::local_get.value():
  397. configuration.stack().push(Value(configuration.frame().locals()[instruction.arguments().get<LocalIndex>().value()]));
  398. return;
  399. case Instructions::local_set.value(): {
  400. auto entry = configuration.stack().pop();
  401. configuration.frame().locals()[instruction.arguments().get<LocalIndex>().value()] = move(entry.get<Value>());
  402. return;
  403. }
  404. case Instructions::i32_const.value():
  405. configuration.stack().push(Value(ValueType { ValueType::I32 }, static_cast<i64>(instruction.arguments().get<i32>())));
  406. return;
  407. case Instructions::i64_const.value():
  408. configuration.stack().push(Value(ValueType { ValueType::I64 }, instruction.arguments().get<i64>()));
  409. return;
  410. case Instructions::f32_const.value():
  411. configuration.stack().push(Value(Value::AnyValueType(instruction.arguments().get<float>())));
  412. return;
  413. case Instructions::f64_const.value():
  414. configuration.stack().push(Value(Value::AnyValueType(instruction.arguments().get<double>())));
  415. return;
  416. case Instructions::block.value(): {
  417. size_t arity = 0;
  418. size_t parameter_count = 0;
  419. auto& args = instruction.arguments().get<Instruction::StructuredInstructionArgs>();
  420. switch (args.block_type.kind()) {
  421. case BlockType::Empty:
  422. break;
  423. case BlockType::Type:
  424. arity = 1;
  425. break;
  426. case BlockType::Index: {
  427. auto& type = configuration.frame().module().types()[args.block_type.type_index().value()];
  428. arity = type.results().size();
  429. parameter_count = type.parameters().size();
  430. }
  431. }
  432. configuration.stack().entries().insert(configuration.stack().size() - parameter_count, Label(arity, args.end_ip));
  433. return;
  434. }
  435. case Instructions::loop.value(): {
  436. auto& args = instruction.arguments().get<Instruction::StructuredInstructionArgs>();
  437. size_t arity = 0;
  438. if (args.block_type.kind() == BlockType::Index) {
  439. auto& type = configuration.frame().module().types()[args.block_type.type_index().value()];
  440. arity = type.parameters().size();
  441. }
  442. configuration.stack().entries().insert(configuration.stack().size() - arity, Label(arity, ip.value() + 1));
  443. return;
  444. }
  445. case Instructions::if_.value(): {
  446. size_t arity = 0;
  447. size_t parameter_count = 0;
  448. auto& args = instruction.arguments().get<Instruction::StructuredInstructionArgs>();
  449. switch (args.block_type.kind()) {
  450. case BlockType::Empty:
  451. break;
  452. case BlockType::Type:
  453. arity = 1;
  454. break;
  455. case BlockType::Index: {
  456. auto& type = configuration.frame().module().types()[args.block_type.type_index().value()];
  457. arity = type.results().size();
  458. parameter_count = type.parameters().size();
  459. }
  460. }
  461. auto entry = configuration.stack().pop();
  462. auto value = entry.get<Value>().to<i32>();
  463. auto end_label = Label(arity, args.end_ip.value());
  464. if (value.value() == 0) {
  465. if (args.else_ip.has_value()) {
  466. configuration.ip() = args.else_ip.value();
  467. configuration.stack().entries().insert(configuration.stack().size() - parameter_count, end_label);
  468. } else {
  469. configuration.ip() = args.end_ip.value() + 1;
  470. }
  471. } else {
  472. configuration.stack().entries().insert(configuration.stack().size() - parameter_count, end_label);
  473. }
  474. return;
  475. }
  476. case Instructions::structured_end.value():
  477. case Instructions::structured_else.value(): {
  478. auto index = configuration.nth_label_index(0);
  479. auto label = configuration.stack().entries()[*index].get<Label>();
  480. configuration.stack().entries().remove(*index, 1);
  481. if (instruction.opcode() == Instructions::structured_end)
  482. return;
  483. // Jump to the end label
  484. configuration.ip() = label.continuation();
  485. return;
  486. }
  487. case Instructions::return_.value(): {
  488. auto& frame = configuration.frame();
  489. Checked checked_index { configuration.stack().size() };
  490. checked_index -= frame.arity();
  491. VERIFY(!checked_index.has_overflow());
  492. auto index = checked_index.value();
  493. size_t i = 1;
  494. for (; i <= index; ++i) {
  495. auto& entry = configuration.stack().entries()[index - i];
  496. if (entry.has<Label>()) {
  497. if (configuration.stack().entries()[index - i - 1].has<Frame>())
  498. break;
  499. }
  500. }
  501. configuration.stack().entries().remove(index - i + 1, i - 1);
  502. // Jump past the call/indirect instruction
  503. configuration.ip() = configuration.frame().expression().instructions().size();
  504. return;
  505. }
  506. case Instructions::br.value():
  507. return branch_to_label(configuration, instruction.arguments().get<LabelIndex>());
  508. case Instructions::br_if.value(): {
  509. auto entry = configuration.stack().pop();
  510. if (entry.get<Value>().to<i32>().value_or(0) == 0)
  511. return;
  512. return branch_to_label(configuration, instruction.arguments().get<LabelIndex>());
  513. }
  514. case Instructions::br_table.value(): {
  515. auto& arguments = instruction.arguments().get<Instruction::TableBranchArgs>();
  516. auto entry = configuration.stack().pop();
  517. auto maybe_i = entry.get<Value>().to<i32>();
  518. if (0 <= *maybe_i) {
  519. size_t i = *maybe_i;
  520. if (i < arguments.labels.size())
  521. return branch_to_label(configuration, arguments.labels[i]);
  522. }
  523. return branch_to_label(configuration, arguments.default_);
  524. }
  525. case Instructions::call.value(): {
  526. auto index = instruction.arguments().get<FunctionIndex>();
  527. auto address = configuration.frame().module().functions()[index.value()];
  528. dbgln_if(WASM_TRACE_DEBUG, "call({})", address.value());
  529. call_address(configuration, address);
  530. return;
  531. }
  532. case Instructions::call_indirect.value(): {
  533. auto& args = instruction.arguments().get<Instruction::IndirectCallArgs>();
  534. auto table_address = configuration.frame().module().tables()[args.table.value()];
  535. auto table_instance = configuration.store().get(table_address);
  536. auto entry = configuration.stack().pop();
  537. auto index = entry.get<Value>().to<i32>();
  538. TRAP_IF_NOT(index.value() >= 0);
  539. TRAP_IF_NOT(static_cast<size_t>(index.value()) < table_instance->elements().size());
  540. auto element = table_instance->elements()[index.value()];
  541. TRAP_IF_NOT(element.ref().has<Reference::Func>());
  542. auto address = element.ref().get<Reference::Func>().address;
  543. dbgln_if(WASM_TRACE_DEBUG, "call_indirect({} -> {})", index.value(), address.value());
  544. call_address(configuration, address);
  545. return;
  546. }
  547. case Instructions::i32_load.value():
  548. return load_and_push<i32, i32>(configuration, instruction);
  549. case Instructions::i64_load.value():
  550. return load_and_push<i64, i64>(configuration, instruction);
  551. case Instructions::f32_load.value():
  552. return load_and_push<float, float>(configuration, instruction);
  553. case Instructions::f64_load.value():
  554. return load_and_push<double, double>(configuration, instruction);
  555. case Instructions::i32_load8_s.value():
  556. return load_and_push<i8, i32>(configuration, instruction);
  557. case Instructions::i32_load8_u.value():
  558. return load_and_push<u8, i32>(configuration, instruction);
  559. case Instructions::i32_load16_s.value():
  560. return load_and_push<i16, i32>(configuration, instruction);
  561. case Instructions::i32_load16_u.value():
  562. return load_and_push<u16, i32>(configuration, instruction);
  563. case Instructions::i64_load8_s.value():
  564. return load_and_push<i8, i64>(configuration, instruction);
  565. case Instructions::i64_load8_u.value():
  566. return load_and_push<u8, i64>(configuration, instruction);
  567. case Instructions::i64_load16_s.value():
  568. return load_and_push<i16, i64>(configuration, instruction);
  569. case Instructions::i64_load16_u.value():
  570. return load_and_push<u16, i64>(configuration, instruction);
  571. case Instructions::i64_load32_s.value():
  572. return load_and_push<i32, i64>(configuration, instruction);
  573. case Instructions::i64_load32_u.value():
  574. return load_and_push<u32, i64>(configuration, instruction);
  575. case Instructions::i32_store.value():
  576. return pop_and_store<i32, i32>(configuration, instruction);
  577. case Instructions::i64_store.value():
  578. return pop_and_store<i64, i64>(configuration, instruction);
  579. case Instructions::f32_store.value():
  580. return pop_and_store<float, float>(configuration, instruction);
  581. case Instructions::f64_store.value():
  582. return pop_and_store<double, double>(configuration, instruction);
  583. case Instructions::i32_store8.value():
  584. return pop_and_store<i32, i8>(configuration, instruction);
  585. case Instructions::i32_store16.value():
  586. return pop_and_store<i32, i16>(configuration, instruction);
  587. case Instructions::i64_store8.value():
  588. return pop_and_store<i64, i8>(configuration, instruction);
  589. case Instructions::i64_store16.value():
  590. return pop_and_store<i64, i16>(configuration, instruction);
  591. case Instructions::i64_store32.value():
  592. return pop_and_store<i64, i32>(configuration, instruction);
  593. case Instructions::local_tee.value(): {
  594. auto& entry = configuration.stack().peek();
  595. auto value = entry.get<Value>();
  596. auto local_index = instruction.arguments().get<LocalIndex>();
  597. dbgln_if(WASM_TRACE_DEBUG, "stack:peek -> locals({})", local_index.value());
  598. configuration.frame().locals()[local_index.value()] = move(value);
  599. return;
  600. }
  601. case Instructions::global_get.value(): {
  602. auto global_index = instruction.arguments().get<GlobalIndex>();
  603. // This check here is for const expressions. In non-const expressions,
  604. // a validation error would have been thrown.
  605. TRAP_IF_NOT(global_index < configuration.frame().module().globals().size());
  606. auto address = configuration.frame().module().globals()[global_index.value()];
  607. dbgln_if(WASM_TRACE_DEBUG, "global({}) -> stack", address.value());
  608. auto global = configuration.store().get(address);
  609. configuration.stack().push(Value(global->value()));
  610. return;
  611. }
  612. case Instructions::global_set.value(): {
  613. auto global_index = instruction.arguments().get<GlobalIndex>();
  614. auto address = configuration.frame().module().globals()[global_index.value()];
  615. auto entry = configuration.stack().pop();
  616. auto value = entry.get<Value>();
  617. dbgln_if(WASM_TRACE_DEBUG, "stack -> global({})", address.value());
  618. auto global = configuration.store().get(address);
  619. global->set_value(move(value));
  620. return;
  621. }
  622. case Instructions::memory_size.value(): {
  623. auto& args = instruction.arguments().get<Instruction::MemoryIndexArgument>();
  624. auto address = configuration.frame().module().memories()[args.memory_index.value()];
  625. auto instance = configuration.store().get(address);
  626. auto pages = instance->size() / Constants::page_size;
  627. dbgln_if(WASM_TRACE_DEBUG, "memory.size -> stack({})", pages);
  628. configuration.stack().push(Value((i32)pages));
  629. return;
  630. }
  631. case Instructions::memory_grow.value(): {
  632. auto& args = instruction.arguments().get<Instruction::MemoryIndexArgument>();
  633. auto address = configuration.frame().module().memories()[args.memory_index.value()];
  634. auto instance = configuration.store().get(address);
  635. i32 old_pages = instance->size() / Constants::page_size;
  636. auto& entry = configuration.stack().peek();
  637. auto new_pages = entry.get<Value>().to<i32>();
  638. dbgln_if(WASM_TRACE_DEBUG, "memory.grow({}), previously {} pages...", *new_pages, old_pages);
  639. if (instance->grow(new_pages.value() * Constants::page_size))
  640. configuration.stack().peek() = Value((i32)old_pages);
  641. else
  642. configuration.stack().peek() = Value((i32)-1);
  643. return;
  644. }
  645. // https://webassembly.github.io/spec/core/bikeshed/#exec-memory-fill
  646. case Instructions::memory_fill.value(): {
  647. auto& args = instruction.arguments().get<Instruction::MemoryIndexArgument>();
  648. auto address = configuration.frame().module().memories()[args.memory_index.value()];
  649. auto instance = configuration.store().get(address);
  650. auto count = configuration.stack().pop().get<Value>().to<u32>().value();
  651. u8 value = static_cast<u8>(configuration.stack().pop().get<Value>().to<u32>().value());
  652. auto destination_offset = configuration.stack().pop().get<Value>().to<u32>().value();
  653. TRAP_IF_NOT(static_cast<size_t>(destination_offset + count) <= instance->data().size());
  654. if (count == 0)
  655. return;
  656. for (u32 i = 0; i < count; ++i)
  657. store_to_memory(configuration, Instruction::MemoryArgument { 0, 0 }, { &value, sizeof(value) }, destination_offset + i);
  658. return;
  659. }
  660. // https://webassembly.github.io/spec/core/bikeshed/#exec-memory-copy
  661. case Instructions::memory_copy.value(): {
  662. auto& args = instruction.arguments().get<Instruction::MemoryCopyArgs>();
  663. auto source_address = configuration.frame().module().memories()[args.src_index.value()];
  664. auto destination_address = configuration.frame().module().memories()[args.dst_index.value()];
  665. auto source_instance = configuration.store().get(source_address);
  666. auto destination_instance = configuration.store().get(destination_address);
  667. auto count = configuration.stack().pop().get<Value>().to<i32>().value();
  668. auto source_offset = configuration.stack().pop().get<Value>().to<i32>().value();
  669. auto destination_offset = configuration.stack().pop().get<Value>().to<i32>().value();
  670. Checked<size_t> source_position = source_offset;
  671. source_position.saturating_add(count);
  672. Checked<size_t> destination_position = destination_offset;
  673. destination_position.saturating_add(count);
  674. TRAP_IF_NOT(source_position <= source_instance->data().size());
  675. TRAP_IF_NOT(destination_position <= destination_instance->data().size());
  676. if (count == 0)
  677. return;
  678. Instruction::MemoryArgument memarg { 0, 0, args.dst_index };
  679. if (destination_offset <= source_offset) {
  680. for (auto i = 0; i < count; ++i) {
  681. auto value = source_instance->data()[source_offset + i];
  682. store_to_memory(configuration, memarg, { &value, sizeof(value) }, destination_offset + i);
  683. }
  684. } else {
  685. for (auto i = count - 1; i >= 0; --i) {
  686. auto value = source_instance->data()[source_offset + i];
  687. store_to_memory(configuration, memarg, { &value, sizeof(value) }, destination_offset + i);
  688. }
  689. }
  690. return;
  691. }
  692. // https://webassembly.github.io/spec/core/bikeshed/#exec-memory-init
  693. case Instructions::memory_init.value(): {
  694. auto& args = instruction.arguments().get<Instruction::MemoryInitArgs>();
  695. auto& data_address = configuration.frame().module().datas()[args.data_index.value()];
  696. auto& data = *configuration.store().get(data_address);
  697. auto memory_address = configuration.frame().module().memories()[args.memory_index.value()];
  698. auto memory = configuration.store().get(memory_address);
  699. auto count = *configuration.stack().pop().get<Value>().to<u32>();
  700. auto source_offset = *configuration.stack().pop().get<Value>().to<u32>();
  701. auto destination_offset = *configuration.stack().pop().get<Value>().to<u32>();
  702. Checked<size_t> source_position = source_offset;
  703. source_position.saturating_add(count);
  704. Checked<size_t> destination_position = destination_offset;
  705. destination_position.saturating_add(count);
  706. TRAP_IF_NOT(source_position <= data.data().size());
  707. TRAP_IF_NOT(destination_position <= memory->data().size());
  708. if (count == 0)
  709. return;
  710. Instruction::MemoryArgument memarg { 0, 0, args.memory_index };
  711. for (size_t i = 0; i < (size_t)count; ++i) {
  712. auto value = data.data()[source_offset + i];
  713. store_to_memory(configuration, memarg, { &value, sizeof(value) }, destination_offset + i);
  714. }
  715. return;
  716. }
  717. // https://webassembly.github.io/spec/core/bikeshed/#exec-data-drop
  718. case Instructions::data_drop.value(): {
  719. auto data_index = instruction.arguments().get<DataIndex>();
  720. auto data_address = configuration.frame().module().datas()[data_index.value()];
  721. *configuration.store().get(data_address) = DataInstance({});
  722. return;
  723. }
  724. case Instructions::elem_drop.value(): {
  725. auto elem_index = instruction.arguments().get<ElementIndex>();
  726. auto address = configuration.frame().module().elements()[elem_index.value()];
  727. auto elem = configuration.store().get(address);
  728. *configuration.store().get(address) = ElementInstance(elem->type(), {});
  729. return;
  730. }
  731. case Instructions::table_init.value(): {
  732. auto& args = instruction.arguments().get<Instruction::TableElementArgs>();
  733. auto table_address = configuration.frame().module().tables()[args.table_index.value()];
  734. auto table = configuration.store().get(table_address);
  735. auto element_address = configuration.frame().module().elements()[args.element_index.value()];
  736. auto element = configuration.store().get(element_address);
  737. auto count = *configuration.stack().pop().get<Value>().to<u32>();
  738. auto source_offset = *configuration.stack().pop().get<Value>().to<u32>();
  739. auto destination_offset = *configuration.stack().pop().get<Value>().to<u32>();
  740. Checked<u32> checked_source_offset = source_offset;
  741. Checked<u32> checked_destination_offset = destination_offset;
  742. checked_source_offset += count;
  743. checked_destination_offset += count;
  744. TRAP_IF_NOT(!checked_source_offset.has_overflow() && checked_source_offset <= (u32)element->references().size());
  745. TRAP_IF_NOT(!checked_destination_offset.has_overflow() && checked_destination_offset <= (u32)table->elements().size());
  746. for (u32 i = 0; i < count; ++i)
  747. table->elements()[destination_offset + i] = element->references()[source_offset + i];
  748. return;
  749. }
  750. case Instructions::table_copy.value(): {
  751. auto& args = instruction.arguments().get<Instruction::TableTableArgs>();
  752. auto source_address = configuration.frame().module().tables()[args.rhs.value()];
  753. auto destination_address = configuration.frame().module().tables()[args.lhs.value()];
  754. auto source_instance = configuration.store().get(source_address);
  755. auto destination_instance = configuration.store().get(destination_address);
  756. auto count = configuration.stack().pop().get<Value>().to<u32>().value();
  757. auto source_offset = configuration.stack().pop().get<Value>().to<u32>().value();
  758. auto destination_offset = configuration.stack().pop().get<Value>().to<u32>().value();
  759. Checked<size_t> source_position = source_offset;
  760. source_position.saturating_add(count);
  761. Checked<size_t> destination_position = destination_offset;
  762. destination_position.saturating_add(count);
  763. TRAP_IF_NOT(source_position <= source_instance->elements().size());
  764. TRAP_IF_NOT(destination_position <= destination_instance->elements().size());
  765. if (count == 0)
  766. return;
  767. if (destination_offset <= source_offset) {
  768. for (u32 i = 0; i < count; ++i) {
  769. auto value = source_instance->elements()[source_offset + i];
  770. destination_instance->elements()[destination_offset + i] = value;
  771. }
  772. } else {
  773. for (u32 i = count - 1; i != NumericLimits<u32>::max(); --i) {
  774. auto value = source_instance->elements()[source_offset + i];
  775. destination_instance->elements()[destination_offset + i] = value;
  776. }
  777. }
  778. return;
  779. }
  780. case Instructions::table_fill.value(): {
  781. auto table_index = instruction.arguments().get<TableIndex>();
  782. auto address = configuration.frame().module().tables()[table_index.value()];
  783. auto table = configuration.store().get(address);
  784. auto count = *configuration.stack().pop().get<Value>().to<u32>();
  785. auto value = *configuration.stack().pop().get<Value>().to<Reference>();
  786. auto start = *configuration.stack().pop().get<Value>().to<u32>();
  787. Checked<u32> checked_offset = start;
  788. checked_offset += count;
  789. TRAP_IF_NOT(!checked_offset.has_overflow() && checked_offset <= (u32)table->elements().size());
  790. for (u32 i = 0; i < count; ++i)
  791. table->elements()[start + i] = value;
  792. return;
  793. }
  794. case Instructions::table_set.value(): {
  795. auto ref = *configuration.stack().pop().get<Value>().to<Reference>();
  796. auto index = (size_t)(*configuration.stack().pop().get<Value>().to<i32>());
  797. auto table_index = instruction.arguments().get<TableIndex>();
  798. auto address = configuration.frame().module().tables()[table_index.value()];
  799. auto table = configuration.store().get(address);
  800. TRAP_IF_NOT(index < table->elements().size());
  801. table->elements()[index] = ref;
  802. return;
  803. }
  804. case Instructions::table_get.value(): {
  805. auto index = (size_t)(*configuration.stack().pop().get<Value>().to<i32>());
  806. auto table_index = instruction.arguments().get<TableIndex>();
  807. auto address = configuration.frame().module().tables()[table_index.value()];
  808. auto table = configuration.store().get(address);
  809. TRAP_IF_NOT(index < table->elements().size());
  810. auto ref = table->elements()[index];
  811. configuration.stack().push(Value(ref));
  812. return;
  813. }
  814. case Instructions::table_grow.value(): {
  815. auto size = *configuration.stack().pop().get<Value>().to<u32>();
  816. auto fill_value = *configuration.stack().pop().get<Value>().to<Reference>();
  817. auto table_index = instruction.arguments().get<TableIndex>();
  818. auto address = configuration.frame().module().tables()[table_index.value()];
  819. auto table = configuration.store().get(address);
  820. auto previous_size = table->elements().size();
  821. auto did_grow = table->grow(size, fill_value);
  822. if (!did_grow) {
  823. configuration.stack().push(Value((i32)-1));
  824. } else {
  825. configuration.stack().push(Value((i32)previous_size));
  826. }
  827. return;
  828. }
  829. case Instructions::table_size.value(): {
  830. auto table_index = instruction.arguments().get<TableIndex>();
  831. auto address = configuration.frame().module().tables()[table_index.value()];
  832. auto table = configuration.store().get(address);
  833. configuration.stack().push(Value((i32)table->elements().size()));
  834. return;
  835. }
  836. case Instructions::ref_null.value(): {
  837. auto type = instruction.arguments().get<ValueType>();
  838. configuration.stack().push(Value(Reference(Reference::Null { type })));
  839. return;
  840. };
  841. case Instructions::ref_func.value(): {
  842. auto index = instruction.arguments().get<FunctionIndex>().value();
  843. auto& functions = configuration.frame().module().functions();
  844. auto address = functions[index];
  845. configuration.stack().push(Value(ValueType(ValueType::FunctionReference), address.value()));
  846. return;
  847. }
  848. case Instructions::ref_is_null.value(): {
  849. auto top = configuration.stack().peek().get_pointer<Value>();
  850. TRAP_IF_NOT(top->type().is_reference());
  851. auto is_null = top->to<Reference::Null>().has_value();
  852. configuration.stack().peek() = Value(ValueType(ValueType::I32), static_cast<u64>(is_null ? 1 : 0));
  853. return;
  854. }
  855. case Instructions::drop.value():
  856. configuration.stack().pop();
  857. return;
  858. case Instructions::select.value():
  859. case Instructions::select_typed.value(): {
  860. // Note: The type seems to only be used for validation.
  861. auto entry = configuration.stack().pop();
  862. auto value = entry.get<Value>().to<i32>();
  863. dbgln_if(WASM_TRACE_DEBUG, "select({})", value.value());
  864. auto rhs_entry = configuration.stack().pop();
  865. auto& lhs_entry = configuration.stack().peek();
  866. auto rhs = move(rhs_entry.get<Value>());
  867. auto lhs = move(lhs_entry.get<Value>());
  868. configuration.stack().peek() = value.value() != 0 ? move(lhs) : move(rhs);
  869. return;
  870. }
  871. case Instructions::i32_eqz.value():
  872. return unary_operation<i32, i32, Operators::EqualsZero>(configuration);
  873. case Instructions::i32_eq.value():
  874. return binary_numeric_operation<i32, i32, Operators::Equals>(configuration);
  875. case Instructions::i32_ne.value():
  876. return binary_numeric_operation<i32, i32, Operators::NotEquals>(configuration);
  877. case Instructions::i32_lts.value():
  878. return binary_numeric_operation<i32, i32, Operators::LessThan>(configuration);
  879. case Instructions::i32_ltu.value():
  880. return binary_numeric_operation<u32, i32, Operators::LessThan>(configuration);
  881. case Instructions::i32_gts.value():
  882. return binary_numeric_operation<i32, i32, Operators::GreaterThan>(configuration);
  883. case Instructions::i32_gtu.value():
  884. return binary_numeric_operation<u32, i32, Operators::GreaterThan>(configuration);
  885. case Instructions::i32_les.value():
  886. return binary_numeric_operation<i32, i32, Operators::LessThanOrEquals>(configuration);
  887. case Instructions::i32_leu.value():
  888. return binary_numeric_operation<u32, i32, Operators::LessThanOrEquals>(configuration);
  889. case Instructions::i32_ges.value():
  890. return binary_numeric_operation<i32, i32, Operators::GreaterThanOrEquals>(configuration);
  891. case Instructions::i32_geu.value():
  892. return binary_numeric_operation<u32, i32, Operators::GreaterThanOrEquals>(configuration);
  893. case Instructions::i64_eqz.value():
  894. return unary_operation<i64, i32, Operators::EqualsZero>(configuration);
  895. case Instructions::i64_eq.value():
  896. return binary_numeric_operation<i64, i32, Operators::Equals>(configuration);
  897. case Instructions::i64_ne.value():
  898. return binary_numeric_operation<i64, i32, Operators::NotEquals>(configuration);
  899. case Instructions::i64_lts.value():
  900. return binary_numeric_operation<i64, i32, Operators::LessThan>(configuration);
  901. case Instructions::i64_ltu.value():
  902. return binary_numeric_operation<u64, i32, Operators::LessThan>(configuration);
  903. case Instructions::i64_gts.value():
  904. return binary_numeric_operation<i64, i32, Operators::GreaterThan>(configuration);
  905. case Instructions::i64_gtu.value():
  906. return binary_numeric_operation<u64, i32, Operators::GreaterThan>(configuration);
  907. case Instructions::i64_les.value():
  908. return binary_numeric_operation<i64, i32, Operators::LessThanOrEquals>(configuration);
  909. case Instructions::i64_leu.value():
  910. return binary_numeric_operation<u64, i32, Operators::LessThanOrEquals>(configuration);
  911. case Instructions::i64_ges.value():
  912. return binary_numeric_operation<i64, i32, Operators::GreaterThanOrEquals>(configuration);
  913. case Instructions::i64_geu.value():
  914. return binary_numeric_operation<u64, i32, Operators::GreaterThanOrEquals>(configuration);
  915. case Instructions::f32_eq.value():
  916. return binary_numeric_operation<float, i32, Operators::Equals>(configuration);
  917. case Instructions::f32_ne.value():
  918. return binary_numeric_operation<float, i32, Operators::NotEquals>(configuration);
  919. case Instructions::f32_lt.value():
  920. return binary_numeric_operation<float, i32, Operators::LessThan>(configuration);
  921. case Instructions::f32_gt.value():
  922. return binary_numeric_operation<float, i32, Operators::GreaterThan>(configuration);
  923. case Instructions::f32_le.value():
  924. return binary_numeric_operation<float, i32, Operators::LessThanOrEquals>(configuration);
  925. case Instructions::f32_ge.value():
  926. return binary_numeric_operation<float, i32, Operators::GreaterThanOrEquals>(configuration);
  927. case Instructions::f64_eq.value():
  928. return binary_numeric_operation<double, i32, Operators::Equals>(configuration);
  929. case Instructions::f64_ne.value():
  930. return binary_numeric_operation<double, i32, Operators::NotEquals>(configuration);
  931. case Instructions::f64_lt.value():
  932. return binary_numeric_operation<double, i32, Operators::LessThan>(configuration);
  933. case Instructions::f64_gt.value():
  934. return binary_numeric_operation<double, i32, Operators::GreaterThan>(configuration);
  935. case Instructions::f64_le.value():
  936. return binary_numeric_operation<double, i32, Operators::LessThanOrEquals>(configuration);
  937. case Instructions::f64_ge.value():
  938. return binary_numeric_operation<double, i32, Operators::GreaterThanOrEquals>(configuration);
  939. case Instructions::i32_clz.value():
  940. return unary_operation<i32, i32, Operators::CountLeadingZeros>(configuration);
  941. case Instructions::i32_ctz.value():
  942. return unary_operation<i32, i32, Operators::CountTrailingZeros>(configuration);
  943. case Instructions::i32_popcnt.value():
  944. return unary_operation<i32, i32, Operators::PopCount>(configuration);
  945. case Instructions::i32_add.value():
  946. return binary_numeric_operation<u32, i32, Operators::Add>(configuration);
  947. case Instructions::i32_sub.value():
  948. return binary_numeric_operation<u32, i32, Operators::Subtract>(configuration);
  949. case Instructions::i32_mul.value():
  950. return binary_numeric_operation<u32, i32, Operators::Multiply>(configuration);
  951. case Instructions::i32_divs.value():
  952. return binary_numeric_operation<i32, i32, Operators::Divide>(configuration);
  953. case Instructions::i32_divu.value():
  954. return binary_numeric_operation<u32, i32, Operators::Divide>(configuration);
  955. case Instructions::i32_rems.value():
  956. return binary_numeric_operation<i32, i32, Operators::Modulo>(configuration);
  957. case Instructions::i32_remu.value():
  958. return binary_numeric_operation<u32, i32, Operators::Modulo>(configuration);
  959. case Instructions::i32_and.value():
  960. return binary_numeric_operation<i32, i32, Operators::BitAnd>(configuration);
  961. case Instructions::i32_or.value():
  962. return binary_numeric_operation<i32, i32, Operators::BitOr>(configuration);
  963. case Instructions::i32_xor.value():
  964. return binary_numeric_operation<i32, i32, Operators::BitXor>(configuration);
  965. case Instructions::i32_shl.value():
  966. return binary_numeric_operation<u32, i32, Operators::BitShiftLeft>(configuration);
  967. case Instructions::i32_shrs.value():
  968. return binary_numeric_operation<i32, i32, Operators::BitShiftRight>(configuration);
  969. case Instructions::i32_shru.value():
  970. return binary_numeric_operation<u32, i32, Operators::BitShiftRight>(configuration);
  971. case Instructions::i32_rotl.value():
  972. return binary_numeric_operation<u32, i32, Operators::BitRotateLeft>(configuration);
  973. case Instructions::i32_rotr.value():
  974. return binary_numeric_operation<u32, i32, Operators::BitRotateRight>(configuration);
  975. case Instructions::i64_clz.value():
  976. return unary_operation<i64, i64, Operators::CountLeadingZeros>(configuration);
  977. case Instructions::i64_ctz.value():
  978. return unary_operation<i64, i64, Operators::CountTrailingZeros>(configuration);
  979. case Instructions::i64_popcnt.value():
  980. return unary_operation<i64, i64, Operators::PopCount>(configuration);
  981. case Instructions::i64_add.value():
  982. return binary_numeric_operation<u64, i64, Operators::Add>(configuration);
  983. case Instructions::i64_sub.value():
  984. return binary_numeric_operation<u64, i64, Operators::Subtract>(configuration);
  985. case Instructions::i64_mul.value():
  986. return binary_numeric_operation<u64, i64, Operators::Multiply>(configuration);
  987. case Instructions::i64_divs.value():
  988. return binary_numeric_operation<i64, i64, Operators::Divide>(configuration);
  989. case Instructions::i64_divu.value():
  990. return binary_numeric_operation<u64, i64, Operators::Divide>(configuration);
  991. case Instructions::i64_rems.value():
  992. return binary_numeric_operation<i64, i64, Operators::Modulo>(configuration);
  993. case Instructions::i64_remu.value():
  994. return binary_numeric_operation<u64, i64, Operators::Modulo>(configuration);
  995. case Instructions::i64_and.value():
  996. return binary_numeric_operation<i64, i64, Operators::BitAnd>(configuration);
  997. case Instructions::i64_or.value():
  998. return binary_numeric_operation<i64, i64, Operators::BitOr>(configuration);
  999. case Instructions::i64_xor.value():
  1000. return binary_numeric_operation<i64, i64, Operators::BitXor>(configuration);
  1001. case Instructions::i64_shl.value():
  1002. return binary_numeric_operation<u64, i64, Operators::BitShiftLeft>(configuration);
  1003. case Instructions::i64_shrs.value():
  1004. return binary_numeric_operation<i64, i64, Operators::BitShiftRight>(configuration);
  1005. case Instructions::i64_shru.value():
  1006. return binary_numeric_operation<u64, i64, Operators::BitShiftRight>(configuration);
  1007. case Instructions::i64_rotl.value():
  1008. return binary_numeric_operation<u64, i64, Operators::BitRotateLeft>(configuration);
  1009. case Instructions::i64_rotr.value():
  1010. return binary_numeric_operation<u64, i64, Operators::BitRotateRight>(configuration);
  1011. case Instructions::f32_abs.value():
  1012. return unary_operation<float, float, Operators::Absolute>(configuration);
  1013. case Instructions::f32_neg.value():
  1014. return unary_operation<float, float, Operators::Negate>(configuration);
  1015. case Instructions::f32_ceil.value():
  1016. return unary_operation<float, float, Operators::Ceil>(configuration);
  1017. case Instructions::f32_floor.value():
  1018. return unary_operation<float, float, Operators::Floor>(configuration);
  1019. case Instructions::f32_trunc.value():
  1020. return unary_operation<float, float, Operators::Truncate>(configuration);
  1021. case Instructions::f32_nearest.value():
  1022. return unary_operation<float, float, Operators::NearbyIntegral>(configuration);
  1023. case Instructions::f32_sqrt.value():
  1024. return unary_operation<float, float, Operators::SquareRoot>(configuration);
  1025. case Instructions::f32_add.value():
  1026. return binary_numeric_operation<float, float, Operators::Add>(configuration);
  1027. case Instructions::f32_sub.value():
  1028. return binary_numeric_operation<float, float, Operators::Subtract>(configuration);
  1029. case Instructions::f32_mul.value():
  1030. return binary_numeric_operation<float, float, Operators::Multiply>(configuration);
  1031. case Instructions::f32_div.value():
  1032. return binary_numeric_operation<float, float, Operators::Divide>(configuration);
  1033. case Instructions::f32_min.value():
  1034. return binary_numeric_operation<float, float, Operators::Minimum>(configuration);
  1035. case Instructions::f32_max.value():
  1036. return binary_numeric_operation<float, float, Operators::Maximum>(configuration);
  1037. case Instructions::f32_copysign.value():
  1038. return binary_numeric_operation<float, float, Operators::CopySign>(configuration);
  1039. case Instructions::f64_abs.value():
  1040. return unary_operation<double, double, Operators::Absolute>(configuration);
  1041. case Instructions::f64_neg.value():
  1042. return unary_operation<double, double, Operators::Negate>(configuration);
  1043. case Instructions::f64_ceil.value():
  1044. return unary_operation<double, double, Operators::Ceil>(configuration);
  1045. case Instructions::f64_floor.value():
  1046. return unary_operation<double, double, Operators::Floor>(configuration);
  1047. case Instructions::f64_trunc.value():
  1048. return unary_operation<double, double, Operators::Truncate>(configuration);
  1049. case Instructions::f64_nearest.value():
  1050. return unary_operation<double, double, Operators::NearbyIntegral>(configuration);
  1051. case Instructions::f64_sqrt.value():
  1052. return unary_operation<double, double, Operators::SquareRoot>(configuration);
  1053. case Instructions::f64_add.value():
  1054. return binary_numeric_operation<double, double, Operators::Add>(configuration);
  1055. case Instructions::f64_sub.value():
  1056. return binary_numeric_operation<double, double, Operators::Subtract>(configuration);
  1057. case Instructions::f64_mul.value():
  1058. return binary_numeric_operation<double, double, Operators::Multiply>(configuration);
  1059. case Instructions::f64_div.value():
  1060. return binary_numeric_operation<double, double, Operators::Divide>(configuration);
  1061. case Instructions::f64_min.value():
  1062. return binary_numeric_operation<double, double, Operators::Minimum>(configuration);
  1063. case Instructions::f64_max.value():
  1064. return binary_numeric_operation<double, double, Operators::Maximum>(configuration);
  1065. case Instructions::f64_copysign.value():
  1066. return binary_numeric_operation<double, double, Operators::CopySign>(configuration);
  1067. case Instructions::i32_wrap_i64.value():
  1068. return unary_operation<i64, i32, Operators::Wrap<i32>>(configuration);
  1069. case Instructions::i32_trunc_sf32.value():
  1070. return unary_operation<float, i32, Operators::CheckedTruncate<i32>>(configuration);
  1071. case Instructions::i32_trunc_uf32.value():
  1072. return unary_operation<float, i32, Operators::CheckedTruncate<u32>>(configuration);
  1073. case Instructions::i32_trunc_sf64.value():
  1074. return unary_operation<double, i32, Operators::CheckedTruncate<i32>>(configuration);
  1075. case Instructions::i32_trunc_uf64.value():
  1076. return unary_operation<double, i32, Operators::CheckedTruncate<u32>>(configuration);
  1077. case Instructions::i64_trunc_sf32.value():
  1078. return unary_operation<float, i64, Operators::CheckedTruncate<i64>>(configuration);
  1079. case Instructions::i64_trunc_uf32.value():
  1080. return unary_operation<float, i64, Operators::CheckedTruncate<u64>>(configuration);
  1081. case Instructions::i64_trunc_sf64.value():
  1082. return unary_operation<double, i64, Operators::CheckedTruncate<i64>>(configuration);
  1083. case Instructions::i64_trunc_uf64.value():
  1084. return unary_operation<double, i64, Operators::CheckedTruncate<u64>>(configuration);
  1085. case Instructions::i64_extend_si32.value():
  1086. return unary_operation<i32, i64, Operators::Extend<i64>>(configuration);
  1087. case Instructions::i64_extend_ui32.value():
  1088. return unary_operation<u32, i64, Operators::Extend<i64>>(configuration);
  1089. case Instructions::f32_convert_si32.value():
  1090. return unary_operation<i32, float, Operators::Convert<float>>(configuration);
  1091. case Instructions::f32_convert_ui32.value():
  1092. return unary_operation<u32, float, Operators::Convert<float>>(configuration);
  1093. case Instructions::f32_convert_si64.value():
  1094. return unary_operation<i64, float, Operators::Convert<float>>(configuration);
  1095. case Instructions::f32_convert_ui64.value():
  1096. return unary_operation<u64, float, Operators::Convert<float>>(configuration);
  1097. case Instructions::f32_demote_f64.value():
  1098. return unary_operation<double, float, Operators::Demote>(configuration);
  1099. case Instructions::f64_convert_si32.value():
  1100. return unary_operation<i32, double, Operators::Convert<double>>(configuration);
  1101. case Instructions::f64_convert_ui32.value():
  1102. return unary_operation<u32, double, Operators::Convert<double>>(configuration);
  1103. case Instructions::f64_convert_si64.value():
  1104. return unary_operation<i64, double, Operators::Convert<double>>(configuration);
  1105. case Instructions::f64_convert_ui64.value():
  1106. return unary_operation<u64, double, Operators::Convert<double>>(configuration);
  1107. case Instructions::f64_promote_f32.value():
  1108. return unary_operation<float, double, Operators::Promote>(configuration);
  1109. case Instructions::i32_reinterpret_f32.value():
  1110. return unary_operation<float, i32, Operators::Reinterpret<i32>>(configuration);
  1111. case Instructions::i64_reinterpret_f64.value():
  1112. return unary_operation<double, i64, Operators::Reinterpret<i64>>(configuration);
  1113. case Instructions::f32_reinterpret_i32.value():
  1114. return unary_operation<i32, float, Operators::Reinterpret<float>>(configuration);
  1115. case Instructions::f64_reinterpret_i64.value():
  1116. return unary_operation<i64, double, Operators::Reinterpret<double>>(configuration);
  1117. case Instructions::i32_extend8_s.value():
  1118. return unary_operation<i32, i32, Operators::SignExtend<i8>>(configuration);
  1119. case Instructions::i32_extend16_s.value():
  1120. return unary_operation<i32, i32, Operators::SignExtend<i16>>(configuration);
  1121. case Instructions::i64_extend8_s.value():
  1122. return unary_operation<i64, i64, Operators::SignExtend<i8>>(configuration);
  1123. case Instructions::i64_extend16_s.value():
  1124. return unary_operation<i64, i64, Operators::SignExtend<i16>>(configuration);
  1125. case Instructions::i64_extend32_s.value():
  1126. return unary_operation<i64, i64, Operators::SignExtend<i32>>(configuration);
  1127. case Instructions::i32_trunc_sat_f32_s.value():
  1128. return unary_operation<float, i32, Operators::SaturatingTruncate<i32>>(configuration);
  1129. case Instructions::i32_trunc_sat_f32_u.value():
  1130. return unary_operation<float, i32, Operators::SaturatingTruncate<u32>>(configuration);
  1131. case Instructions::i32_trunc_sat_f64_s.value():
  1132. return unary_operation<double, i32, Operators::SaturatingTruncate<i32>>(configuration);
  1133. case Instructions::i32_trunc_sat_f64_u.value():
  1134. return unary_operation<double, i32, Operators::SaturatingTruncate<u32>>(configuration);
  1135. case Instructions::i64_trunc_sat_f32_s.value():
  1136. return unary_operation<float, i64, Operators::SaturatingTruncate<i64>>(configuration);
  1137. case Instructions::i64_trunc_sat_f32_u.value():
  1138. return unary_operation<float, i64, Operators::SaturatingTruncate<u64>>(configuration);
  1139. case Instructions::i64_trunc_sat_f64_s.value():
  1140. return unary_operation<double, i64, Operators::SaturatingTruncate<i64>>(configuration);
  1141. case Instructions::i64_trunc_sat_f64_u.value():
  1142. return unary_operation<double, i64, Operators::SaturatingTruncate<u64>>(configuration);
  1143. case Instructions::v128_const.value():
  1144. configuration.stack().push(Value(instruction.arguments().get<u128>()));
  1145. return;
  1146. case Instructions::v128_load.value():
  1147. return load_and_push<u128, u128>(configuration, instruction);
  1148. case Instructions::v128_load8x8_s.value():
  1149. return load_and_push_mxn<8, 8, MakeSigned>(configuration, instruction);
  1150. case Instructions::v128_load8x8_u.value():
  1151. return load_and_push_mxn<8, 8, MakeUnsigned>(configuration, instruction);
  1152. case Instructions::v128_load16x4_s.value():
  1153. return load_and_push_mxn<16, 4, MakeSigned>(configuration, instruction);
  1154. case Instructions::v128_load16x4_u.value():
  1155. return load_and_push_mxn<16, 4, MakeUnsigned>(configuration, instruction);
  1156. case Instructions::v128_load32x2_s.value():
  1157. return load_and_push_mxn<32, 2, MakeSigned>(configuration, instruction);
  1158. case Instructions::v128_load32x2_u.value():
  1159. return load_and_push_mxn<32, 2, MakeUnsigned>(configuration, instruction);
  1160. case Instructions::v128_load8_splat.value():
  1161. return load_and_push_m_splat<8>(configuration, instruction);
  1162. case Instructions::v128_load16_splat.value():
  1163. return load_and_push_m_splat<16>(configuration, instruction);
  1164. case Instructions::v128_load32_splat.value():
  1165. return load_and_push_m_splat<32>(configuration, instruction);
  1166. case Instructions::v128_load64_splat.value():
  1167. return load_and_push_m_splat<64>(configuration, instruction);
  1168. case Instructions::i8x16_splat.value():
  1169. return pop_and_push_m_splat<8, NativeIntegralType>(configuration, instruction);
  1170. case Instructions::i16x8_splat.value():
  1171. return pop_and_push_m_splat<16, NativeIntegralType>(configuration, instruction);
  1172. case Instructions::i32x4_splat.value():
  1173. return pop_and_push_m_splat<32, NativeIntegralType>(configuration, instruction);
  1174. case Instructions::i64x2_splat.value():
  1175. return pop_and_push_m_splat<64, NativeIntegralType>(configuration, instruction);
  1176. case Instructions::f32x4_splat.value():
  1177. return pop_and_push_m_splat<32, NativeFloatingType>(configuration, instruction);
  1178. case Instructions::f64x2_splat.value():
  1179. return pop_and_push_m_splat<64, NativeFloatingType>(configuration, instruction);
  1180. case Instructions::i8x16_shuffle.value(): {
  1181. auto& arg = instruction.arguments().get<Instruction::ShuffleArgument>();
  1182. auto b = pop_vector<u8, MakeUnsigned>(configuration);
  1183. auto a = pop_vector<u8, MakeUnsigned>(configuration);
  1184. using VectorType = Native128ByteVectorOf<u8, MakeUnsigned>;
  1185. VectorType result;
  1186. for (size_t i = 0; i < 16; ++i)
  1187. if (arg.lanes[i] < 16)
  1188. result[i] = a[arg.lanes[i]];
  1189. else
  1190. result[i] = b[arg.lanes[i] - 16];
  1191. configuration.stack().push(Value(bit_cast<u128>(result)));
  1192. return;
  1193. }
  1194. case Instructions::v128_store.value():
  1195. return pop_and_store<u128, u128>(configuration, instruction);
  1196. case Instructions::i8x16_shl.value():
  1197. return binary_numeric_operation<u128, u128, Operators::VectorShiftLeft<16>, i32>(configuration);
  1198. case Instructions::i8x16_shr_u.value():
  1199. return binary_numeric_operation<u128, u128, Operators::VectorShiftRight<16, MakeUnsigned>, i32>(configuration);
  1200. case Instructions::i8x16_shr_s.value():
  1201. return binary_numeric_operation<u128, u128, Operators::VectorShiftRight<16, MakeSigned>, i32>(configuration);
  1202. case Instructions::i16x8_shl.value():
  1203. return binary_numeric_operation<u128, u128, Operators::VectorShiftLeft<8>, i32>(configuration);
  1204. case Instructions::i16x8_shr_u.value():
  1205. return binary_numeric_operation<u128, u128, Operators::VectorShiftRight<8, MakeUnsigned>, i32>(configuration);
  1206. case Instructions::i16x8_shr_s.value():
  1207. return binary_numeric_operation<u128, u128, Operators::VectorShiftRight<8, MakeSigned>, i32>(configuration);
  1208. case Instructions::i32x4_shl.value():
  1209. return binary_numeric_operation<u128, u128, Operators::VectorShiftLeft<4>, i32>(configuration);
  1210. case Instructions::i32x4_shr_u.value():
  1211. return binary_numeric_operation<u128, u128, Operators::VectorShiftRight<4, MakeUnsigned>, i32>(configuration);
  1212. case Instructions::i32x4_shr_s.value():
  1213. return binary_numeric_operation<u128, u128, Operators::VectorShiftRight<4, MakeSigned>, i32>(configuration);
  1214. case Instructions::i64x2_shl.value():
  1215. return binary_numeric_operation<u128, u128, Operators::VectorShiftLeft<2>, i32>(configuration);
  1216. case Instructions::i64x2_shr_u.value():
  1217. return binary_numeric_operation<u128, u128, Operators::VectorShiftRight<2, MakeUnsigned>, i32>(configuration);
  1218. case Instructions::i64x2_shr_s.value():
  1219. return binary_numeric_operation<u128, u128, Operators::VectorShiftRight<2, MakeSigned>, i32>(configuration);
  1220. case Instructions::i8x16_swizzle.value():
  1221. return binary_numeric_operation<u128, u128, Operators::VectorSwizzle>(configuration);
  1222. case Instructions::i8x16_extract_lane_s.value():
  1223. return unary_operation<u128, i8, Operators::VectorExtractLane<16, MakeSigned>>(configuration, instruction.arguments().get<Instruction::LaneIndex>().lane);
  1224. case Instructions::i8x16_extract_lane_u.value():
  1225. return unary_operation<u128, u8, Operators::VectorExtractLane<16, MakeUnsigned>>(configuration, instruction.arguments().get<Instruction::LaneIndex>().lane);
  1226. case Instructions::i16x8_extract_lane_s.value():
  1227. return unary_operation<u128, i16, Operators::VectorExtractLane<8, MakeSigned>>(configuration, instruction.arguments().get<Instruction::LaneIndex>().lane);
  1228. case Instructions::i16x8_extract_lane_u.value():
  1229. return unary_operation<u128, u16, Operators::VectorExtractLane<8, MakeUnsigned>>(configuration, instruction.arguments().get<Instruction::LaneIndex>().lane);
  1230. case Instructions::i32x4_extract_lane.value():
  1231. return unary_operation<u128, i32, Operators::VectorExtractLane<4, MakeSigned>>(configuration, instruction.arguments().get<Instruction::LaneIndex>().lane);
  1232. case Instructions::i64x2_extract_lane.value():
  1233. return unary_operation<u128, i64, Operators::VectorExtractLane<2, MakeSigned>>(configuration, instruction.arguments().get<Instruction::LaneIndex>().lane);
  1234. case Instructions::f32x4_extract_lane.value():
  1235. return unary_operation<u128, float, Operators::VectorExtractLaneFloat<4>>(configuration, instruction.arguments().get<Instruction::LaneIndex>().lane);
  1236. case Instructions::f64x2_extract_lane.value():
  1237. return unary_operation<u128, double, Operators::VectorExtractLaneFloat<2>>(configuration, instruction.arguments().get<Instruction::LaneIndex>().lane);
  1238. case Instructions::i8x16_replace_lane.value():
  1239. return binary_numeric_operation<u128, u128, Operators::VectorReplaceLane<16, i32>, i32>(configuration, instruction.arguments().get<Instruction::LaneIndex>().lane);
  1240. case Instructions::i16x8_replace_lane.value():
  1241. return binary_numeric_operation<u128, u128, Operators::VectorReplaceLane<8, i32>, i32>(configuration, instruction.arguments().get<Instruction::LaneIndex>().lane);
  1242. case Instructions::i32x4_replace_lane.value():
  1243. return binary_numeric_operation<u128, u128, Operators::VectorReplaceLane<4>, i32>(configuration, instruction.arguments().get<Instruction::LaneIndex>().lane);
  1244. case Instructions::i64x2_replace_lane.value():
  1245. return binary_numeric_operation<u128, u128, Operators::VectorReplaceLane<2>, i64>(configuration, instruction.arguments().get<Instruction::LaneIndex>().lane);
  1246. case Instructions::f32x4_replace_lane.value():
  1247. return binary_numeric_operation<u128, u128, Operators::VectorReplaceLane<4, float>, float>(configuration, instruction.arguments().get<Instruction::LaneIndex>().lane);
  1248. case Instructions::f64x2_replace_lane.value():
  1249. return binary_numeric_operation<u128, u128, Operators::VectorReplaceLane<2, double>, double>(configuration, instruction.arguments().get<Instruction::LaneIndex>().lane);
  1250. case Instructions::i8x16_eq.value():
  1251. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<16, Operators::Equals>>(configuration);
  1252. case Instructions::i8x16_ne.value():
  1253. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<16, Operators::NotEquals>>(configuration);
  1254. case Instructions::i8x16_lt_s.value():
  1255. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<16, Operators::LessThan, MakeSigned>>(configuration);
  1256. case Instructions::i8x16_lt_u.value():
  1257. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<16, Operators::LessThan, MakeUnsigned>>(configuration);
  1258. case Instructions::i8x16_gt_s.value():
  1259. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<16, Operators::GreaterThan, MakeSigned>>(configuration);
  1260. case Instructions::i8x16_gt_u.value():
  1261. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<16, Operators::GreaterThan, MakeUnsigned>>(configuration);
  1262. case Instructions::i8x16_le_s.value():
  1263. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<16, Operators::LessThanOrEquals, MakeSigned>>(configuration);
  1264. case Instructions::i8x16_le_u.value():
  1265. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<16, Operators::LessThanOrEquals, MakeUnsigned>>(configuration);
  1266. case Instructions::i8x16_ge_s.value():
  1267. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<16, Operators::GreaterThanOrEquals, MakeSigned>>(configuration);
  1268. case Instructions::i8x16_ge_u.value():
  1269. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<16, Operators::GreaterThanOrEquals, MakeUnsigned>>(configuration);
  1270. case Instructions::i8x16_abs.value():
  1271. return unary_operation<u128, u128, Operators::VectorIntegerUnaryOp<16, Operators::Absolute>>(configuration);
  1272. case Instructions::i8x16_neg.value():
  1273. return unary_operation<u128, u128, Operators::VectorIntegerUnaryOp<16, Operators::Negate>>(configuration);
  1274. case Instructions::i8x16_all_true.value():
  1275. return unary_operation<u128, i32, Operators::VectorAllTrue<16>>(configuration);
  1276. case Instructions::i8x16_popcnt.value():
  1277. return unary_operation<u128, u128, Operators::VectorIntegerUnaryOp<16, Operators::PopCount>>(configuration);
  1278. case Instructions::i8x16_add.value():
  1279. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<16, Operators::Add>>(configuration);
  1280. case Instructions::i8x16_sub.value():
  1281. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<16, Operators::Subtract>>(configuration);
  1282. case Instructions::i8x16_avgr_u.value():
  1283. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<16, Operators::Average, MakeUnsigned>>(configuration);
  1284. case Instructions::i8x16_add_sat_s.value():
  1285. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<16, Operators::SaturatingOp<i8, Operators::Add>, MakeSigned>>(configuration);
  1286. case Instructions::i8x16_add_sat_u.value():
  1287. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<16, Operators::SaturatingOp<u8, Operators::Add>, MakeUnsigned>>(configuration);
  1288. case Instructions::i8x16_sub_sat_s.value():
  1289. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<16, Operators::SaturatingOp<i8, Operators::Subtract>, MakeSigned>>(configuration);
  1290. case Instructions::i8x16_sub_sat_u.value():
  1291. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<16, Operators::SaturatingOp<u8, Operators::Subtract>, MakeUnsigned>>(configuration);
  1292. case Instructions::i8x16_min_s.value():
  1293. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<16, Operators::Minimum, MakeSigned>>(configuration);
  1294. case Instructions::i8x16_min_u.value():
  1295. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<16, Operators::Minimum, MakeUnsigned>>(configuration);
  1296. case Instructions::i8x16_max_s.value():
  1297. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<16, Operators::Maximum, MakeSigned>>(configuration);
  1298. case Instructions::i8x16_max_u.value():
  1299. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<16, Operators::Maximum, MakeUnsigned>>(configuration);
  1300. case Instructions::i16x8_eq.value():
  1301. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<8, Operators::Equals>>(configuration);
  1302. case Instructions::i16x8_ne.value():
  1303. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<8, Operators::NotEquals>>(configuration);
  1304. case Instructions::i16x8_lt_s.value():
  1305. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<8, Operators::LessThan, MakeSigned>>(configuration);
  1306. case Instructions::i16x8_lt_u.value():
  1307. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<8, Operators::LessThan, MakeUnsigned>>(configuration);
  1308. case Instructions::i16x8_gt_s.value():
  1309. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<8, Operators::GreaterThan, MakeSigned>>(configuration);
  1310. case Instructions::i16x8_gt_u.value():
  1311. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<8, Operators::GreaterThan, MakeUnsigned>>(configuration);
  1312. case Instructions::i16x8_le_s.value():
  1313. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<8, Operators::LessThanOrEquals, MakeSigned>>(configuration);
  1314. case Instructions::i16x8_le_u.value():
  1315. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<8, Operators::LessThanOrEquals, MakeUnsigned>>(configuration);
  1316. case Instructions::i16x8_ge_s.value():
  1317. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<8, Operators::GreaterThanOrEquals, MakeSigned>>(configuration);
  1318. case Instructions::i16x8_ge_u.value():
  1319. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<8, Operators::GreaterThanOrEquals, MakeUnsigned>>(configuration);
  1320. case Instructions::i16x8_abs.value():
  1321. return unary_operation<u128, u128, Operators::VectorIntegerUnaryOp<8, Operators::Absolute>>(configuration);
  1322. case Instructions::i16x8_neg.value():
  1323. return unary_operation<u128, u128, Operators::VectorIntegerUnaryOp<8, Operators::Negate>>(configuration);
  1324. case Instructions::i16x8_all_true.value():
  1325. return unary_operation<u128, i32, Operators::VectorAllTrue<8>>(configuration);
  1326. case Instructions::i16x8_add.value():
  1327. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<8, Operators::Add>>(configuration);
  1328. case Instructions::i16x8_sub.value():
  1329. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<8, Operators::Subtract>>(configuration);
  1330. case Instructions::i16x8_mul.value():
  1331. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<8, Operators::Multiply>>(configuration);
  1332. case Instructions::i16x8_avgr_u.value():
  1333. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<8, Operators::Average, MakeUnsigned>>(configuration);
  1334. case Instructions::i16x8_add_sat_s.value():
  1335. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<8, Operators::SaturatingOp<i16, Operators::Add>, MakeSigned>>(configuration);
  1336. case Instructions::i16x8_add_sat_u.value():
  1337. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<8, Operators::SaturatingOp<u16, Operators::Add>, MakeUnsigned>>(configuration);
  1338. case Instructions::i16x8_sub_sat_s.value():
  1339. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<8, Operators::SaturatingOp<i16, Operators::Subtract>, MakeSigned>>(configuration);
  1340. case Instructions::i16x8_sub_sat_u.value():
  1341. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<8, Operators::SaturatingOp<u16, Operators::Subtract>, MakeUnsigned>>(configuration);
  1342. case Instructions::i16x8_min_s.value():
  1343. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<8, Operators::Minimum, MakeSigned>>(configuration);
  1344. case Instructions::i16x8_min_u.value():
  1345. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<8, Operators::Minimum, MakeUnsigned>>(configuration);
  1346. case Instructions::i16x8_max_s.value():
  1347. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<8, Operators::Maximum, MakeSigned>>(configuration);
  1348. case Instructions::i16x8_max_u.value():
  1349. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<8, Operators::Maximum, MakeUnsigned>>(configuration);
  1350. case Instructions::i16x8_extend_low_i8x16_s.value():
  1351. return unary_operation<u128, u128, Operators::VectorIntegerExt<8, Operators::VectorExt::Low, MakeSigned>>(configuration);
  1352. case Instructions::i16x8_extend_high_i8x16_s.value():
  1353. return unary_operation<u128, u128, Operators::VectorIntegerExt<8, Operators::VectorExt::High, MakeSigned>>(configuration);
  1354. case Instructions::i16x8_extend_low_i8x16_u.value():
  1355. return unary_operation<u128, u128, Operators::VectorIntegerExt<8, Operators::VectorExt::Low, MakeUnsigned>>(configuration);
  1356. case Instructions::i16x8_extend_high_i8x16_u.value():
  1357. return unary_operation<u128, u128, Operators::VectorIntegerExt<8, Operators::VectorExt::High, MakeUnsigned>>(configuration);
  1358. case Instructions::i16x8_extadd_pairwise_i8x16_s.value():
  1359. return unary_operation<u128, u128, Operators::VectorIntegerExtOpPairwise<8, Operators::Add, MakeSigned>>(configuration);
  1360. case Instructions::i16x8_extadd_pairwise_i8x16_u.value():
  1361. return unary_operation<u128, u128, Operators::VectorIntegerExtOpPairwise<8, Operators::Add, MakeUnsigned>>(configuration);
  1362. case Instructions::i16x8_extmul_low_i8x16_s.value():
  1363. return binary_numeric_operation<u128, u128, Operators::VectorIntegerExtOp<8, Operators::Multiply, Operators::VectorExt::Low, MakeSigned>>(configuration);
  1364. case Instructions::i16x8_extmul_high_i8x16_s.value():
  1365. return binary_numeric_operation<u128, u128, Operators::VectorIntegerExtOp<8, Operators::Multiply, Operators::VectorExt::High, MakeSigned>>(configuration);
  1366. case Instructions::i16x8_extmul_low_i8x16_u.value():
  1367. return binary_numeric_operation<u128, u128, Operators::VectorIntegerExtOp<8, Operators::Multiply, Operators::VectorExt::Low, MakeUnsigned>>(configuration);
  1368. case Instructions::i16x8_extmul_high_i8x16_u.value():
  1369. return binary_numeric_operation<u128, u128, Operators::VectorIntegerExtOp<8, Operators::Multiply, Operators::VectorExt::High, MakeUnsigned>>(configuration);
  1370. case Instructions::i32x4_eq.value():
  1371. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<4, Operators::Equals>>(configuration);
  1372. case Instructions::i32x4_ne.value():
  1373. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<4, Operators::NotEquals>>(configuration);
  1374. case Instructions::i32x4_lt_s.value():
  1375. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<4, Operators::LessThan, MakeSigned>>(configuration);
  1376. case Instructions::i32x4_lt_u.value():
  1377. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<4, Operators::LessThan, MakeUnsigned>>(configuration);
  1378. case Instructions::i32x4_gt_s.value():
  1379. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<4, Operators::GreaterThan, MakeSigned>>(configuration);
  1380. case Instructions::i32x4_gt_u.value():
  1381. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<4, Operators::GreaterThan, MakeUnsigned>>(configuration);
  1382. case Instructions::i32x4_le_s.value():
  1383. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<4, Operators::LessThanOrEquals, MakeSigned>>(configuration);
  1384. case Instructions::i32x4_le_u.value():
  1385. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<4, Operators::LessThanOrEquals, MakeUnsigned>>(configuration);
  1386. case Instructions::i32x4_ge_s.value():
  1387. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<4, Operators::GreaterThanOrEquals, MakeSigned>>(configuration);
  1388. case Instructions::i32x4_ge_u.value():
  1389. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<4, Operators::GreaterThanOrEquals, MakeUnsigned>>(configuration);
  1390. case Instructions::i32x4_abs.value():
  1391. return unary_operation<u128, u128, Operators::VectorIntegerUnaryOp<4, Operators::Absolute>>(configuration);
  1392. case Instructions::i32x4_neg.value():
  1393. return unary_operation<u128, u128, Operators::VectorIntegerUnaryOp<4, Operators::Negate, MakeUnsigned>>(configuration);
  1394. case Instructions::i32x4_all_true.value():
  1395. return unary_operation<u128, i32, Operators::VectorAllTrue<4>>(configuration);
  1396. case Instructions::i32x4_add.value():
  1397. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<4, Operators::Add, MakeUnsigned>>(configuration);
  1398. case Instructions::i32x4_sub.value():
  1399. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<4, Operators::Subtract, MakeUnsigned>>(configuration);
  1400. case Instructions::i32x4_mul.value():
  1401. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<4, Operators::Multiply, MakeUnsigned>>(configuration);
  1402. case Instructions::i32x4_min_s.value():
  1403. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<4, Operators::Minimum, MakeSigned>>(configuration);
  1404. case Instructions::i32x4_min_u.value():
  1405. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<4, Operators::Minimum, MakeUnsigned>>(configuration);
  1406. case Instructions::i32x4_max_s.value():
  1407. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<4, Operators::Maximum, MakeSigned>>(configuration);
  1408. case Instructions::i32x4_max_u.value():
  1409. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<4, Operators::Maximum, MakeUnsigned>>(configuration);
  1410. case Instructions::i32x4_extend_low_i16x8_s.value():
  1411. return unary_operation<u128, u128, Operators::VectorIntegerExt<4, Operators::VectorExt::Low, MakeSigned>>(configuration);
  1412. case Instructions::i32x4_extend_high_i16x8_s.value():
  1413. return unary_operation<u128, u128, Operators::VectorIntegerExt<4, Operators::VectorExt::High, MakeSigned>>(configuration);
  1414. case Instructions::i32x4_extend_low_i16x8_u.value():
  1415. return unary_operation<u128, u128, Operators::VectorIntegerExt<4, Operators::VectorExt::Low, MakeUnsigned>>(configuration);
  1416. case Instructions::i32x4_extend_high_i16x8_u.value():
  1417. return unary_operation<u128, u128, Operators::VectorIntegerExt<4, Operators::VectorExt::High, MakeUnsigned>>(configuration);
  1418. case Instructions::i32x4_extadd_pairwise_i16x8_s.value():
  1419. return unary_operation<u128, u128, Operators::VectorIntegerExtOpPairwise<4, Operators::Add, MakeSigned>>(configuration);
  1420. case Instructions::i32x4_extadd_pairwise_i16x8_u.value():
  1421. return unary_operation<u128, u128, Operators::VectorIntegerExtOpPairwise<4, Operators::Add, MakeUnsigned>>(configuration);
  1422. case Instructions::i32x4_extmul_low_i16x8_s.value():
  1423. return binary_numeric_operation<u128, u128, Operators::VectorIntegerExtOp<4, Operators::Multiply, Operators::VectorExt::Low, MakeSigned>>(configuration);
  1424. case Instructions::i32x4_extmul_high_i16x8_s.value():
  1425. return binary_numeric_operation<u128, u128, Operators::VectorIntegerExtOp<4, Operators::Multiply, Operators::VectorExt::High, MakeSigned>>(configuration);
  1426. case Instructions::i32x4_extmul_low_i16x8_u.value():
  1427. return binary_numeric_operation<u128, u128, Operators::VectorIntegerExtOp<4, Operators::Multiply, Operators::VectorExt::Low, MakeUnsigned>>(configuration);
  1428. case Instructions::i32x4_extmul_high_i16x8_u.value():
  1429. return binary_numeric_operation<u128, u128, Operators::VectorIntegerExtOp<4, Operators::Multiply, Operators::VectorExt::High, MakeUnsigned>>(configuration);
  1430. case Instructions::i64x2_eq.value():
  1431. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<2, Operators::Equals>>(configuration);
  1432. case Instructions::i64x2_ne.value():
  1433. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<2, Operators::NotEquals>>(configuration);
  1434. case Instructions::i64x2_lt_s.value():
  1435. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<2, Operators::LessThan, MakeSigned>>(configuration);
  1436. case Instructions::i64x2_gt_s.value():
  1437. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<2, Operators::GreaterThan, MakeSigned>>(configuration);
  1438. case Instructions::i64x2_le_s.value():
  1439. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<2, Operators::LessThanOrEquals, MakeSigned>>(configuration);
  1440. case Instructions::i64x2_ge_s.value():
  1441. return binary_numeric_operation<u128, u128, Operators::VectorCmpOp<2, Operators::GreaterThanOrEquals, MakeSigned>>(configuration);
  1442. case Instructions::i64x2_abs.value():
  1443. return unary_operation<u128, u128, Operators::VectorIntegerUnaryOp<2, Operators::Absolute>>(configuration);
  1444. case Instructions::i64x2_neg.value():
  1445. return unary_operation<u128, u128, Operators::VectorIntegerUnaryOp<2, Operators::Negate, MakeUnsigned>>(configuration);
  1446. case Instructions::i64x2_all_true.value():
  1447. return unary_operation<u128, i32, Operators::VectorAllTrue<2>>(configuration);
  1448. case Instructions::i64x2_add.value():
  1449. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<2, Operators::Add, MakeUnsigned>>(configuration);
  1450. case Instructions::i64x2_sub.value():
  1451. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<2, Operators::Subtract, MakeUnsigned>>(configuration);
  1452. case Instructions::i64x2_mul.value():
  1453. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<2, Operators::Multiply, MakeUnsigned>>(configuration);
  1454. case Instructions::i64x2_extend_low_i32x4_s.value():
  1455. return unary_operation<u128, u128, Operators::VectorIntegerExt<2, Operators::VectorExt::Low, MakeSigned>>(configuration);
  1456. case Instructions::i64x2_extend_high_i32x4_s.value():
  1457. return unary_operation<u128, u128, Operators::VectorIntegerExt<2, Operators::VectorExt::High, MakeSigned>>(configuration);
  1458. case Instructions::i64x2_extend_low_i32x4_u.value():
  1459. return unary_operation<u128, u128, Operators::VectorIntegerExt<2, Operators::VectorExt::Low, MakeUnsigned>>(configuration);
  1460. case Instructions::i64x2_extend_high_i32x4_u.value():
  1461. return unary_operation<u128, u128, Operators::VectorIntegerExt<2, Operators::VectorExt::High, MakeUnsigned>>(configuration);
  1462. case Instructions::i64x2_extmul_low_i32x4_s.value():
  1463. return binary_numeric_operation<u128, u128, Operators::VectorIntegerExtOp<2, Operators::Multiply, Operators::VectorExt::Low, MakeSigned>>(configuration);
  1464. case Instructions::i64x2_extmul_high_i32x4_s.value():
  1465. return binary_numeric_operation<u128, u128, Operators::VectorIntegerExtOp<2, Operators::Multiply, Operators::VectorExt::High, MakeSigned>>(configuration);
  1466. case Instructions::i64x2_extmul_low_i32x4_u.value():
  1467. return binary_numeric_operation<u128, u128, Operators::VectorIntegerExtOp<2, Operators::Multiply, Operators::VectorExt::Low, MakeUnsigned>>(configuration);
  1468. case Instructions::i64x2_extmul_high_i32x4_u.value():
  1469. return binary_numeric_operation<u128, u128, Operators::VectorIntegerExtOp<2, Operators::Multiply, Operators::VectorExt::High, MakeUnsigned>>(configuration);
  1470. case Instructions::f32x4_eq.value():
  1471. return binary_numeric_operation<u128, u128, Operators::VectorFloatCmpOp<4, Operators::Equals>>(configuration);
  1472. case Instructions::f32x4_ne.value():
  1473. return binary_numeric_operation<u128, u128, Operators::VectorFloatCmpOp<4, Operators::NotEquals>>(configuration);
  1474. case Instructions::f32x4_lt.value():
  1475. return binary_numeric_operation<u128, u128, Operators::VectorFloatCmpOp<4, Operators::LessThan>>(configuration);
  1476. case Instructions::f32x4_gt.value():
  1477. return binary_numeric_operation<u128, u128, Operators::VectorFloatCmpOp<4, Operators::GreaterThan>>(configuration);
  1478. case Instructions::f32x4_le.value():
  1479. return binary_numeric_operation<u128, u128, Operators::VectorFloatCmpOp<4, Operators::LessThanOrEquals>>(configuration);
  1480. case Instructions::f32x4_ge.value():
  1481. return binary_numeric_operation<u128, u128, Operators::VectorFloatCmpOp<4, Operators::GreaterThanOrEquals>>(configuration);
  1482. case Instructions::f32x4_min.value():
  1483. return binary_numeric_operation<u128, u128, Operators::VectorFloatBinaryOp<4, Operators::Minimum>>(configuration);
  1484. case Instructions::f32x4_max.value():
  1485. return binary_numeric_operation<u128, u128, Operators::VectorFloatBinaryOp<4, Operators::Maximum>>(configuration);
  1486. case Instructions::f64x2_eq.value():
  1487. return binary_numeric_operation<u128, u128, Operators::VectorFloatCmpOp<2, Operators::Equals>>(configuration);
  1488. case Instructions::f64x2_ne.value():
  1489. return binary_numeric_operation<u128, u128, Operators::VectorFloatCmpOp<2, Operators::NotEquals>>(configuration);
  1490. case Instructions::f64x2_lt.value():
  1491. return binary_numeric_operation<u128, u128, Operators::VectorFloatCmpOp<2, Operators::LessThan>>(configuration);
  1492. case Instructions::f64x2_gt.value():
  1493. return binary_numeric_operation<u128, u128, Operators::VectorFloatCmpOp<2, Operators::GreaterThan>>(configuration);
  1494. case Instructions::f64x2_le.value():
  1495. return binary_numeric_operation<u128, u128, Operators::VectorFloatCmpOp<2, Operators::LessThanOrEquals>>(configuration);
  1496. case Instructions::f64x2_ge.value():
  1497. return binary_numeric_operation<u128, u128, Operators::VectorFloatCmpOp<2, Operators::GreaterThanOrEquals>>(configuration);
  1498. case Instructions::f64x2_min.value():
  1499. return binary_numeric_operation<u128, u128, Operators::VectorFloatBinaryOp<2, Operators::Minimum>>(configuration);
  1500. case Instructions::f64x2_max.value():
  1501. return binary_numeric_operation<u128, u128, Operators::VectorFloatBinaryOp<2, Operators::Maximum>>(configuration);
  1502. case Instructions::f32x4_div.value():
  1503. return binary_numeric_operation<u128, u128, Operators::VectorFloatBinaryOp<4, Operators::Divide>>(configuration);
  1504. case Instructions::f32x4_mul.value():
  1505. return binary_numeric_operation<u128, u128, Operators::VectorFloatBinaryOp<4, Operators::Multiply>>(configuration);
  1506. case Instructions::f32x4_sub.value():
  1507. return binary_numeric_operation<u128, u128, Operators::VectorFloatBinaryOp<4, Operators::Subtract>>(configuration);
  1508. case Instructions::f32x4_add.value():
  1509. return binary_numeric_operation<u128, u128, Operators::VectorFloatBinaryOp<4, Operators::Add>>(configuration);
  1510. case Instructions::f32x4_pmin.value():
  1511. return binary_numeric_operation<u128, u128, Operators::VectorFloatBinaryOp<4, Operators::PseudoMinimum>>(configuration);
  1512. case Instructions::f32x4_pmax.value():
  1513. return binary_numeric_operation<u128, u128, Operators::VectorFloatBinaryOp<4, Operators::PseudoMaximum>>(configuration);
  1514. case Instructions::f64x2_div.value():
  1515. return binary_numeric_operation<u128, u128, Operators::VectorFloatBinaryOp<2, Operators::Divide>>(configuration);
  1516. case Instructions::f64x2_mul.value():
  1517. return binary_numeric_operation<u128, u128, Operators::VectorFloatBinaryOp<2, Operators::Multiply>>(configuration);
  1518. case Instructions::f64x2_sub.value():
  1519. return binary_numeric_operation<u128, u128, Operators::VectorFloatBinaryOp<2, Operators::Subtract>>(configuration);
  1520. case Instructions::f64x2_add.value():
  1521. return binary_numeric_operation<u128, u128, Operators::VectorFloatBinaryOp<2, Operators::Add>>(configuration);
  1522. case Instructions::f64x2_pmin.value():
  1523. return binary_numeric_operation<u128, u128, Operators::VectorFloatBinaryOp<2, Operators::PseudoMinimum>>(configuration);
  1524. case Instructions::f64x2_pmax.value():
  1525. return binary_numeric_operation<u128, u128, Operators::VectorFloatBinaryOp<2, Operators::PseudoMaximum>>(configuration);
  1526. case Instructions::f32x4_ceil.value():
  1527. return unary_operation<u128, u128, Operators::VectorFloatUnaryOp<4, Operators::Ceil>>(configuration);
  1528. case Instructions::f32x4_floor.value():
  1529. return unary_operation<u128, u128, Operators::VectorFloatUnaryOp<4, Operators::Floor>>(configuration);
  1530. case Instructions::f32x4_trunc.value():
  1531. return unary_operation<u128, u128, Operators::VectorFloatUnaryOp<4, Operators::Truncate>>(configuration);
  1532. case Instructions::f32x4_nearest.value():
  1533. return unary_operation<u128, u128, Operators::VectorFloatUnaryOp<4, Operators::NearbyIntegral>>(configuration);
  1534. case Instructions::f32x4_sqrt.value():
  1535. return unary_operation<u128, u128, Operators::VectorFloatUnaryOp<4, Operators::SquareRoot>>(configuration);
  1536. case Instructions::f32x4_neg.value():
  1537. return unary_operation<u128, u128, Operators::VectorFloatUnaryOp<4, Operators::Negate>>(configuration);
  1538. case Instructions::f32x4_abs.value():
  1539. return unary_operation<u128, u128, Operators::VectorFloatUnaryOp<4, Operators::Absolute>>(configuration);
  1540. case Instructions::f64x2_ceil.value():
  1541. return unary_operation<u128, u128, Operators::VectorFloatUnaryOp<2, Operators::Ceil>>(configuration);
  1542. case Instructions::f64x2_floor.value():
  1543. return unary_operation<u128, u128, Operators::VectorFloatUnaryOp<2, Operators::Floor>>(configuration);
  1544. case Instructions::f64x2_trunc.value():
  1545. return unary_operation<u128, u128, Operators::VectorFloatUnaryOp<2, Operators::Truncate>>(configuration);
  1546. case Instructions::f64x2_nearest.value():
  1547. return unary_operation<u128, u128, Operators::VectorFloatUnaryOp<2, Operators::NearbyIntegral>>(configuration);
  1548. case Instructions::f64x2_sqrt.value():
  1549. return unary_operation<u128, u128, Operators::VectorFloatUnaryOp<2, Operators::SquareRoot>>(configuration);
  1550. case Instructions::f64x2_neg.value():
  1551. return unary_operation<u128, u128, Operators::VectorFloatUnaryOp<2, Operators::Negate>>(configuration);
  1552. case Instructions::f64x2_abs.value():
  1553. return unary_operation<u128, u128, Operators::VectorFloatUnaryOp<2, Operators::Absolute>>(configuration);
  1554. case Instructions::v128_and.value():
  1555. return binary_numeric_operation<u128, u128, Operators::BitAnd>(configuration);
  1556. case Instructions::v128_or.value():
  1557. return binary_numeric_operation<u128, u128, Operators::BitOr>(configuration);
  1558. case Instructions::v128_xor.value():
  1559. return binary_numeric_operation<u128, u128, Operators::BitXor>(configuration);
  1560. case Instructions::v128_not.value():
  1561. return unary_operation<u128, u128, Operators::BitNot>(configuration);
  1562. case Instructions::v128_andnot.value():
  1563. return binary_numeric_operation<u128, u128, Operators::BitAndNot>(configuration);
  1564. case Instructions::v128_bitselect.value(): {
  1565. auto mask = *configuration.stack().pop().get<Value>().to<u128>();
  1566. auto false_vector = *configuration.stack().pop().get<Value>().to<u128>();
  1567. auto true_vector = *configuration.stack().pop().get<Value>().to<u128>();
  1568. u128 result = (true_vector & mask) | (false_vector & ~mask);
  1569. configuration.stack().push(Value(result));
  1570. return;
  1571. }
  1572. case Instructions::v128_any_true.value(): {
  1573. auto vector = *configuration.stack().pop().get<Value>().to<u128>();
  1574. configuration.stack().push(Value(static_cast<i32>(vector != 0)));
  1575. return;
  1576. }
  1577. case Instructions::v128_load8_lane.value():
  1578. return load_and_push_lane_n<8>(configuration, instruction);
  1579. case Instructions::v128_load16_lane.value():
  1580. return load_and_push_lane_n<16>(configuration, instruction);
  1581. case Instructions::v128_load32_lane.value():
  1582. return load_and_push_lane_n<32>(configuration, instruction);
  1583. case Instructions::v128_load64_lane.value():
  1584. return load_and_push_lane_n<64>(configuration, instruction);
  1585. case Instructions::v128_load32_zero.value():
  1586. return load_and_push_zero_n<32>(configuration, instruction);
  1587. case Instructions::v128_load64_zero.value():
  1588. return load_and_push_zero_n<64>(configuration, instruction);
  1589. case Instructions::v128_store8_lane.value():
  1590. return pop_and_store_lane_n<8>(configuration, instruction);
  1591. case Instructions::v128_store16_lane.value():
  1592. return pop_and_store_lane_n<16>(configuration, instruction);
  1593. case Instructions::v128_store32_lane.value():
  1594. return pop_and_store_lane_n<32>(configuration, instruction);
  1595. case Instructions::v128_store64_lane.value():
  1596. return pop_and_store_lane_n<64>(configuration, instruction);
  1597. case Instructions::i32x4_trunc_sat_f32x4_s.value():
  1598. return unary_operation<u128, u128, Operators::VectorConvertOp<4, 4, u32, f32, Operators::SaturatingTruncate<i32>>>(configuration);
  1599. case Instructions::i32x4_trunc_sat_f32x4_u.value():
  1600. return unary_operation<u128, u128, Operators::VectorConvertOp<4, 4, u32, f32, Operators::SaturatingTruncate<u32>>>(configuration);
  1601. case Instructions::i8x16_bitmask.value():
  1602. return unary_operation<u128, i32, Operators::VectorBitmask<16>>(configuration);
  1603. case Instructions::i16x8_bitmask.value():
  1604. return unary_operation<u128, i32, Operators::VectorBitmask<8>>(configuration);
  1605. case Instructions::i32x4_bitmask.value():
  1606. return unary_operation<u128, i32, Operators::VectorBitmask<4>>(configuration);
  1607. case Instructions::i64x2_bitmask.value():
  1608. return unary_operation<u128, i32, Operators::VectorBitmask<2>>(configuration);
  1609. case Instructions::i32x4_dot_i16x8_s.value():
  1610. return binary_numeric_operation<u128, u128, Operators::VectorDotProduct<4>>(configuration);
  1611. case Instructions::i8x16_narrow_i16x8_s.value():
  1612. return binary_numeric_operation<u128, u128, Operators::VectorNarrow<16, i8>>(configuration);
  1613. case Instructions::i8x16_narrow_i16x8_u.value():
  1614. return binary_numeric_operation<u128, u128, Operators::VectorNarrow<16, u8>>(configuration);
  1615. case Instructions::i16x8_narrow_i32x4_s.value():
  1616. return binary_numeric_operation<u128, u128, Operators::VectorNarrow<8, i16>>(configuration);
  1617. case Instructions::i16x8_narrow_i32x4_u.value():
  1618. return binary_numeric_operation<u128, u128, Operators::VectorNarrow<8, u16>>(configuration);
  1619. case Instructions::i16x8_q15mulr_sat_s.value():
  1620. return binary_numeric_operation<u128, u128, Operators::VectorIntegerBinaryOp<8, Operators::SaturatingOp<i16, Operators::Q15Mul>, MakeSigned>>(configuration);
  1621. case Instructions::f32x4_convert_i32x4_s.value():
  1622. return unary_operation<u128, u128, Operators::VectorConvertOp<4, 4, u32, i32, Operators::Convert<f32>>>(configuration);
  1623. case Instructions::f32x4_convert_i32x4_u.value():
  1624. return unary_operation<u128, u128, Operators::VectorConvertOp<4, 4, u32, u32, Operators::Convert<f32>>>(configuration);
  1625. case Instructions::f64x2_convert_low_i32x4_s.value():
  1626. return unary_operation<u128, u128, Operators::VectorConvertOp<2, 4, u64, i32, Operators::Convert<f64>>>(configuration);
  1627. case Instructions::f64x2_convert_low_i32x4_u.value():
  1628. return unary_operation<u128, u128, Operators::VectorConvertOp<2, 4, u64, u32, Operators::Convert<f64>>>(configuration);
  1629. case Instructions::f32x4_demote_f64x2_zero.value():
  1630. return unary_operation<u128, u128, Operators::VectorConvertOp<4, 2, u32, f64, Operators::Convert<f32>>>(configuration);
  1631. case Instructions::f64x2_promote_low_f32x4.value():
  1632. return unary_operation<u128, u128, Operators::VectorConvertOp<2, 4, u64, f32, Operators::Convert<f64>>>(configuration);
  1633. case Instructions::i32x4_trunc_sat_f64x2_s_zero.value():
  1634. return unary_operation<u128, u128, Operators::VectorConvertOp<4, 2, u32, f64, Operators::SaturatingTruncate<i32>>>(configuration);
  1635. case Instructions::i32x4_trunc_sat_f64x2_u_zero.value():
  1636. return unary_operation<u128, u128, Operators::VectorConvertOp<4, 2, u32, f64, Operators::SaturatingTruncate<u32>>>(configuration);
  1637. }
  1638. }
  1639. void DebuggerBytecodeInterpreter::interpret(Configuration& configuration, InstructionPointer& ip, Instruction const& instruction)
  1640. {
  1641. if (pre_interpret_hook) {
  1642. auto result = pre_interpret_hook(configuration, ip, instruction);
  1643. if (!result) {
  1644. m_trap = Trap { "Trapped by user request" };
  1645. return;
  1646. }
  1647. }
  1648. BytecodeInterpreter::interpret(configuration, ip, instruction);
  1649. if (post_interpret_hook) {
  1650. auto result = post_interpret_hook(configuration, ip, instruction, *this);
  1651. if (!result) {
  1652. m_trap = Trap { "Trapped by user request" };
  1653. return;
  1654. }
  1655. }
  1656. }
  1657. }