Serenity Operating System
at master 866 lines 28 kB view raw
1/* 2 * Copyright (c) 2021, Ali Mohammad Pur <mpfard@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/HashMap.h> 8#include <AK/TemporaryChange.h> 9#include <LibWasm/AbstractMachine/AbstractMachine.h> 10#include <LibWasm/Printer/Printer.h> 11 12namespace Wasm { 13 14struct Names { 15 static HashMap<OpCode, DeprecatedString> instruction_names; 16 static HashMap<DeprecatedString, OpCode> instructions_by_name; 17}; 18 19DeprecatedString instruction_name(OpCode const& opcode) 20{ 21 return Names::instruction_names.get(opcode).value_or("<unknown>"); 22} 23 24Optional<OpCode> instruction_from_name(StringView name) 25{ 26 if (Names::instructions_by_name.is_empty()) { 27 for (auto& entry : Names::instruction_names) 28 Names::instructions_by_name.set(entry.value, entry.key); 29 } 30 31 return Names::instructions_by_name.get(name); 32} 33 34void Printer::print_indent() 35{ 36 for (size_t i = 0; i < m_indent; ++i) 37 m_stream.write_until_depleted(" "sv.bytes()).release_value_but_fixme_should_propagate_errors(); 38} 39 40void Printer::print(Wasm::BlockType const& type) 41{ 42 print_indent(); 43 print("(type block "); 44 switch (type.kind()) { 45 case Wasm::BlockType::Kind::Index: 46 print("index {})\n", type.type_index().value()); 47 return; 48 case Wasm::BlockType::Kind::Type: { 49 print("type\n"); 50 { 51 TemporaryChange change { m_indent, m_indent + 1 }; 52 print(type.value_type()); 53 } 54 print_indent(); 55 print(")\n"); 56 return; 57 } 58 case Wasm::BlockType::Kind ::Empty: 59 print("empty)\n"); 60 return; 61 } 62 VERIFY_NOT_REACHED(); 63} 64 65void Printer::print(Wasm::CodeSection const& section) 66{ 67 print_indent(); 68 print("(section code\n"); 69 { 70 TemporaryChange change { m_indent, m_indent + 1 }; 71 for (auto& code : section.functions()) 72 print(code); 73 } 74 print_indent(); 75 print(")\n"); 76} 77 78void Printer::print(Wasm::CodeSection::Code const& code) 79{ 80 print(code.func()); 81} 82 83void Printer::print(Wasm::CustomSection const& section) 84{ 85 print_indent(); 86 print("(section custom\n"); 87 { 88 TemporaryChange change { m_indent, m_indent + 1 }; 89 print_indent(); 90 print("(name `{}')\n", section.name()); 91 print_indent(); 92 print("(contents {} bytes)\n", section.contents().size()); 93 } 94 print_indent(); 95 print(")\n"); 96} 97 98void Printer::print(Wasm::DataCountSection const& section) 99{ 100 print_indent(); 101 print("(section data count\n"); 102 if (section.count().has_value()) { 103 TemporaryChange change { m_indent, m_indent + 1 }; 104 print_indent(); 105 print("(count `{}')\n", *section.count()); 106 } 107 print_indent(); 108 print(")\n"); 109} 110 111void Printer::print(Wasm::DataSection const& section) 112{ 113 print_indent(); 114 print("(section data\n"); 115 { 116 TemporaryChange change { m_indent, m_indent + 1 }; 117 for (auto& entry : section.data()) 118 print(entry); 119 } 120 print_indent(); 121 print(")\n"); 122} 123 124void Printer::print(Wasm::DataSection::Data const& data) 125{ 126 print_indent(); 127 print("(data with value\n"); 128 { 129 TemporaryChange change { m_indent, m_indent + 1 }; 130 data.value().visit( 131 [this](DataSection::Data::Passive const& value) { 132 print_indent(); 133 print("(passive init {}xu8 (", value.init.size()); 134 print(DeprecatedString::join(' ', value.init, "{:x}"sv)); 135 print(")\n"); 136 }, 137 [this](DataSection::Data::Active const& value) { 138 print_indent(); 139 print("(active init {}xu8 (", value.init.size()); 140 print(DeprecatedString::join(' ', value.init, "{:x}"sv)); 141 print("\n"); 142 { 143 TemporaryChange change { m_indent, m_indent + 1 }; 144 print_indent(); 145 print("(offset\n"); 146 { 147 TemporaryChange change { m_indent, m_indent + 1 }; 148 print(value.offset); 149 } 150 print_indent(); 151 print(")\n"); 152 } 153 { 154 TemporaryChange change { m_indent, m_indent + 1 }; 155 print_indent(); 156 print("(index {})\n", value.index.value()); 157 } 158 }); 159 } 160 print_indent(); 161 print(")\n"); 162} 163 164void Printer::print(Wasm::ElementSection const& section) 165{ 166 print_indent(); 167 print("(section element\n"); 168 { 169 TemporaryChange change { m_indent, m_indent + 1 }; 170 for (auto& entry : section.segments()) 171 print(entry); 172 } 173 print_indent(); 174 print(")\n"); 175} 176 177void Printer::print(Wasm::ElementSection::Element const& element) 178{ 179 print_indent(); 180 print("(element "); 181 { 182 TemporaryChange<size_t> change { m_indent, 0 }; 183 print(element.type); 184 } 185 { 186 TemporaryChange change { m_indent, m_indent + 1 }; 187 print_indent(); 188 print("(init\n"); 189 { 190 TemporaryChange change { m_indent, m_indent + 1 }; 191 for (auto& entry : element.init) 192 print(entry); 193 } 194 print_indent(); 195 print(")\n"); 196 print_indent(); 197 print("(mode "); 198 element.mode.visit( 199 [this](ElementSection::Active const& active) { 200 print("\n"); 201 { 202 TemporaryChange change { m_indent, m_indent + 1 }; 203 print_indent(); 204 print("(active index {}\n", active.index.value()); 205 { 206 print(active.expression); 207 } 208 print_indent(); 209 print(")\n"); 210 } 211 print_indent(); 212 }, 213 [this](ElementSection::Passive const&) { print("passive"); }, 214 [this](ElementSection::Declarative const&) { print("declarative"); }); 215 print(")\n"); 216 } 217} 218 219void Printer::print(Wasm::ExportSection const& section) 220{ 221 print_indent(); 222 print("(section export\n"); 223 { 224 TemporaryChange change { m_indent, m_indent + 1 }; 225 for (auto& entry : section.entries()) 226 print(entry); 227 } 228 print_indent(); 229 print(")\n"); 230} 231 232void Printer::print(Wasm::ExportSection::Export const& entry) 233{ 234 print_indent(); 235 print("(export `{}' as\n", entry.name()); 236 { 237 TemporaryChange change { m_indent, m_indent + 1 }; 238 print_indent(); 239 entry.description().visit( 240 [this](FunctionIndex const& index) { print("(function index {})\n", index.value()); }, 241 [this](TableIndex const& index) { print("(table index {})\n", index.value()); }, 242 [this](MemoryIndex const& index) { print("(memory index {})\n", index.value()); }, 243 [this](GlobalIndex const& index) { print("(global index {})\n", index.value()); }); 244 } 245 print_indent(); 246 print(")\n"); 247} 248 249void Printer::print(Wasm::Expression const& expression) 250{ 251 TemporaryChange change { m_indent, m_indent + 1 }; 252 for (auto& instr : expression.instructions()) 253 print(instr); 254} 255 256void Printer::print(Wasm::CodeSection::Func const& func) 257{ 258 print_indent(); 259 print("(function\n"); 260 { 261 TemporaryChange change { m_indent, m_indent + 1 }; 262 { 263 print_indent(); 264 print("(locals\n"); 265 { 266 TemporaryChange change { m_indent, m_indent + 1 }; 267 for (auto& locals : func.locals()) 268 print(locals); 269 } 270 print_indent(); 271 print(")\n"); 272 } 273 print_indent(); 274 print("(body\n"); 275 print(func.body()); 276 print_indent(); 277 print(")\n"); 278 } 279 print_indent(); 280 print(")\n"); 281} 282 283void Printer::print(Wasm::FunctionSection const& section) 284{ 285 print_indent(); 286 print("(section function\n"); 287 { 288 TemporaryChange change { m_indent, m_indent + 1 }; 289 for (auto& index : section.types()) { 290 print_indent(); 291 print("(type index {})\n", index.value()); 292 } 293 } 294 print_indent(); 295 print(")\n"); 296} 297 298void Printer::print(Wasm::FunctionType const& type) 299{ 300 print_indent(); 301 print("(type function\n"); 302 { 303 TemporaryChange change { m_indent, m_indent + 1 }; 304 print_indent(); 305 print("(parameters\n"); 306 { 307 TemporaryChange change { m_indent, m_indent + 1 }; 308 for (auto& param : type.parameters()) 309 print(param); 310 } 311 print_indent(); 312 print(")\n"); 313 } 314 { 315 TemporaryChange change { m_indent, m_indent + 1 }; 316 print_indent(); 317 print("(results\n"); 318 { 319 TemporaryChange change { m_indent, m_indent + 1 }; 320 for (auto& type : type.results()) 321 print(type); 322 } 323 print_indent(); 324 print(")\n"); 325 } 326 print_indent(); 327 print(")\n"); 328} 329 330void Printer::print(Wasm::GlobalSection const& section) 331{ 332 print_indent(); 333 print("(section global\n"); 334 { 335 TemporaryChange change { m_indent, m_indent + 1 }; 336 for (auto& entry : section.entries()) 337 print(entry); 338 } 339 print_indent(); 340 print(")\n"); 341} 342 343void Printer::print(Wasm::GlobalSection::Global const& entry) 344{ 345 print_indent(); 346 print("(global\n"); 347 { 348 TemporaryChange change { m_indent, m_indent + 1 }; 349 print_indent(); 350 print("(type\n"); 351 { 352 TemporaryChange change { m_indent, m_indent + 1 }; 353 print(entry.type()); 354 } 355 print_indent(); 356 print(")\n"); 357 } 358 { 359 TemporaryChange change { m_indent, m_indent + 1 }; 360 print_indent(); 361 print("(init\n"); 362 { 363 TemporaryChange change { m_indent, m_indent + 1 }; 364 print(entry.expression()); 365 } 366 print_indent(); 367 print(")\n"); 368 } 369 print_indent(); 370 print(")\n"); 371} 372 373void Printer::print(Wasm::GlobalType const& type) 374{ 375 print_indent(); 376 print("(type global {}mutable\n", type.is_mutable() ? "" : "im"); 377 { 378 TemporaryChange change { m_indent, m_indent + 1 }; 379 print(type.type()); 380 } 381 print_indent(); 382 print(")\n"); 383} 384 385void Printer::print(Wasm::ImportSection const& section) 386{ 387 print_indent(); 388 print("(section import\n"); 389 { 390 TemporaryChange change { m_indent, m_indent + 1 }; 391 for (auto& import : section.imports()) 392 print(import); 393 } 394 print_indent(); 395 print(")\n"); 396} 397 398void Printer::print(Wasm::ImportSection::Import const& import) 399{ 400 print_indent(); 401 print("(import `{}' from `{}' as\n", import.name(), import.module()); 402 { 403 TemporaryChange change { m_indent, m_indent + 1 }; 404 import.description().visit( 405 [this](auto const& type) { print(type); 406 }, 407 [this](TypeIndex const& index) { 408 print_indent(); 409 print("(type index {})\n", index.value()); 410 }); 411} 412print_indent(); 413print(")\n"); 414} 415 416void Printer::print(Wasm::Instruction const& instruction) 417{ 418 print_indent(); 419 print("({}", instruction_name(instruction.opcode())); 420 if (instruction.arguments().has<u8>()) { 421 print(")\n"); 422 } else { 423 print(" "); 424 instruction.arguments().visit( 425 [&](BlockType const& type) { print(type); }, 426 [&](DataIndex const& index) { print("(data index {})", index.value()); }, 427 [&](ElementIndex const& index) { print("(element index {})", index.value()); }, 428 [&](FunctionIndex const& index) { print("(function index {})", index.value()); }, 429 [&](GlobalIndex const& index) { print("(global index {})", index.value()); }, 430 [&](LabelIndex const& index) { print("(label index {})", index.value()); }, 431 [&](LocalIndex const& index) { print("(local index {})", index.value()); }, 432 [&](TableIndex const& index) { print("(table index {})", index.value()); }, 433 [&](Instruction::IndirectCallArgs const& args) { print("(indirect (type index {}) (table index {}))", args.type.value(), args.table.value()); }, 434 [&](Instruction::MemoryArgument const& args) { print("(memory (align {}) (offset {}))", args.align, args.offset); }, 435 [&](Instruction::StructuredInstructionArgs const& args) { 436 print("(structured\n"); 437 TemporaryChange change { m_indent, m_indent + 1 }; 438 print(args.block_type); 439 print_indent(); 440 print("(else {}) (end {}))", args.else_ip.has_value() ? DeprecatedString::number(args.else_ip->value()) : "(none)", args.end_ip.value()); 441 }, 442 [&](Instruction::TableBranchArgs const& args) { 443 print("(table_branch"); 444 for (auto& label : args.labels) 445 print(" (label {})", label.value()); 446 print(" (label {}))", args.default_.value()); 447 }, 448 [&](Instruction::TableElementArgs const& args) { print("(table_element (table index {}) (element index {}))", args.table_index.value(), args.element_index.value()); }, 449 [&](Instruction::TableTableArgs const& args) { print("(table_table (table index {}) (table index {}))", args.lhs.value(), args.rhs.value()); }, 450 [&](ValueType const& type) { print(type); }, 451 [&](Vector<ValueType> const&) { print("(types...)"); }, 452 [&](auto const& value) { print("{}", value); }); 453 454 print(")\n"); 455 } 456} 457 458void Printer::print(Wasm::Limits const& limits) 459{ 460 print_indent(); 461 print("(limits min={}", limits.min()); 462 if (limits.max().has_value()) 463 print(" max={}", limits.max().value()); 464 else 465 print(" unbounded"); 466 print(")\n"); 467} 468 469void Printer::print(Wasm::Locals const& local) 470{ 471 print_indent(); 472 print("(local x{} of type\n", local.n()); 473 { 474 TemporaryChange change { m_indent, m_indent + 1 }; 475 print(local.type()); 476 } 477 print_indent(); 478 print(")\n"); 479} 480 481void Printer::print(Wasm::MemorySection const& section) 482{ 483 print_indent(); 484 print("(section memory\n"); 485 { 486 TemporaryChange change { m_indent, m_indent + 1 }; 487 for (auto& memory : section.memories()) 488 print(memory); 489 } 490 print_indent(); 491 print(")\n"); 492} 493 494void Printer::print(Wasm::MemorySection::Memory const& memory) 495{ 496 print_indent(); 497 print("(memory\n"); 498 { 499 TemporaryChange change { m_indent, m_indent + 1 }; 500 print(memory.type()); 501 } 502 print_indent(); 503 print(")\n"); 504} 505 506void Printer::print(Wasm::MemoryType const& type) 507{ 508 print_indent(); 509 print("(type memory\n"); 510 { 511 TemporaryChange change { m_indent, m_indent + 1 }; 512 print(type.limits()); 513 } 514 print_indent(); 515 print(")\n"); 516} 517 518void Printer::print(Wasm::Module const& module) 519{ 520 print_indent(); 521 { 522 TemporaryChange change { m_indent, m_indent + 1 }; 523 print("(module\n"); 524 for (auto& section : module.sections()) 525 section.visit([this](auto const& value) { print(value); }); 526 } 527 print_indent(); 528 print(")\n"); 529} 530 531void Printer::print(Wasm::Module::Function const& func) 532{ 533 print_indent(); 534 print("(function\n"); 535 { 536 TemporaryChange change { m_indent, m_indent + 1 }; 537 { 538 print_indent(); 539 print("(locals\n"); 540 { 541 TemporaryChange change { m_indent, m_indent + 1 }; 542 for (auto& locals : func.locals()) 543 print(locals); 544 } 545 print_indent(); 546 print(")\n"); 547 } 548 print_indent(); 549 print("(body\n"); 550 print(func.body()); 551 print_indent(); 552 print(")\n"); 553 } 554 print_indent(); 555 print(")\n"); 556} 557 558void Printer::print(Wasm::StartSection const& section) 559{ 560 print_indent(); 561 print("(section start\n"); 562 { 563 TemporaryChange change { m_indent, m_indent + 1 }; 564 print(section.function()); 565 } 566 print_indent(); 567 print(")\n"); 568} 569 570void Printer::print(Wasm::StartSection::StartFunction const& function) 571{ 572 print_indent(); 573 print("(start function index {})\n", function.index().value()); 574} 575 576void Printer::print(Wasm::TableSection const& section) 577{ 578 print_indent(); 579 print("(section table\n"); 580 { 581 TemporaryChange change { m_indent, m_indent + 1 }; 582 for (auto& table : section.tables()) 583 print(table); 584 } 585 print_indent(); 586 print(")\n"); 587} 588 589void Printer::print(Wasm::TableSection::Table const& table) 590{ 591 print_indent(); 592 print("(table\n"); 593 { 594 TemporaryChange change { m_indent, m_indent + 1 }; 595 print(table.type()); 596 } 597 print_indent(); 598 print(")\n"); 599} 600 601void Printer::print(Wasm::TableType const& type) 602{ 603 print_indent(); 604 print("(type table min:{}", type.limits().min()); 605 if (type.limits().max().has_value()) 606 print(" max:{}", type.limits().max().value()); 607 print("\n"); 608 { 609 TemporaryChange change { m_indent, m_indent + 1 }; 610 print(type.element_type()); 611 } 612 print_indent(); 613 print(")\n"); 614} 615 616void Printer::print(Wasm::TypeSection const& section) 617{ 618 print_indent(); 619 print("(section type\n"); 620 { 621 TemporaryChange change { m_indent, m_indent + 1 }; 622 for (auto& type : section.types()) 623 print(type); 624 } 625 print_indent(); 626 print(")\n"); 627} 628 629void Printer::print(Wasm::ValueType const& type) 630{ 631 print_indent(); 632 print("(type {})\n", ValueType::kind_name(type.kind())); 633} 634 635void Printer::print(Wasm::Value const& value) 636{ 637 print_indent(); 638 print("{} ", value.value().visit([&]<typename T>(T const& value) { 639 if constexpr (IsSame<Wasm::Reference, T>) 640 return DeprecatedString::formatted( 641 "addr({})", 642 value.ref().visit( 643 [](Wasm::Reference::Null const&) { return DeprecatedString("null"); }, 644 [](auto const& ref) { return DeprecatedString::number(ref.address.value()); })); 645 else 646 return DeprecatedString::formatted("{}", value); 647 })); 648 TemporaryChange<size_t> change { m_indent, 0 }; 649 print(value.type()); 650} 651 652void Printer::print(Wasm::Reference const& value) 653{ 654 print_indent(); 655 print( 656 "addr({})\n", 657 value.ref().visit( 658 [](Wasm::Reference::Null const&) { return DeprecatedString("null"); }, 659 [](auto const& ref) { return DeprecatedString::number(ref.address.value()); })); 660} 661} 662 663HashMap<Wasm::OpCode, DeprecatedString> Wasm::Names::instruction_names { 664 { Instructions::unreachable, "unreachable" }, 665 { Instructions::nop, "nop" }, 666 { Instructions::block, "block" }, 667 { Instructions::loop, "loop" }, 668 { Instructions::if_, "if" }, 669 { Instructions::br, "br" }, 670 { Instructions::br_if, "br.if" }, 671 { Instructions::br_table, "br.table" }, 672 { Instructions::return_, "return" }, 673 { Instructions::call, "call" }, 674 { Instructions::call_indirect, "call.indirect" }, 675 { Instructions::drop, "drop" }, 676 { Instructions::select, "select" }, 677 { Instructions::select_typed, "select.typed" }, 678 { Instructions::local_get, "local.get" }, 679 { Instructions::local_set, "local.set" }, 680 { Instructions::local_tee, "local.tee" }, 681 { Instructions::global_get, "global.get" }, 682 { Instructions::global_set, "global.set" }, 683 { Instructions::table_get, "table.get" }, 684 { Instructions::table_set, "table.set" }, 685 { Instructions::i32_load, "i32.load" }, 686 { Instructions::i64_load, "i64.load" }, 687 { Instructions::f32_load, "f32.load" }, 688 { Instructions::f64_load, "f64.load" }, 689 { Instructions::i32_load8_s, "i32.load8_s" }, 690 { Instructions::i32_load8_u, "i32.load8_u" }, 691 { Instructions::i32_load16_s, "i32.load16_s" }, 692 { Instructions::i32_load16_u, "i32.load16_u" }, 693 { Instructions::i64_load8_s, "i64.load8_s" }, 694 { Instructions::i64_load8_u, "i64.load8_u" }, 695 { Instructions::i64_load16_s, "i64.load16_s" }, 696 { Instructions::i64_load16_u, "i64.load16_u" }, 697 { Instructions::i64_load32_s, "i64.load32_s" }, 698 { Instructions::i64_load32_u, "i64.load32_u" }, 699 { Instructions::i32_store, "i32.store" }, 700 { Instructions::i64_store, "i64.store" }, 701 { Instructions::f32_store, "f32.store" }, 702 { Instructions::f64_store, "f64.store" }, 703 { Instructions::i32_store8, "i32.store8" }, 704 { Instructions::i32_store16, "i32.store16" }, 705 { Instructions::i64_store8, "i64.store8" }, 706 { Instructions::i64_store16, "i64.store16" }, 707 { Instructions::i64_store32, "i64.store32" }, 708 { Instructions::memory_size, "memory.size" }, 709 { Instructions::memory_grow, "memory.grow" }, 710 { Instructions::i32_const, "i32.const" }, 711 { Instructions::i64_const, "i64.const" }, 712 { Instructions::f32_const, "f32.const" }, 713 { Instructions::f64_const, "f64.const" }, 714 { Instructions::i32_eqz, "i32.eqz" }, 715 { Instructions::i32_eq, "i32.eq" }, 716 { Instructions::i32_ne, "i32.ne" }, 717 { Instructions::i32_lts, "i32.lts" }, 718 { Instructions::i32_ltu, "i32.ltu" }, 719 { Instructions::i32_gts, "i32.gts" }, 720 { Instructions::i32_gtu, "i32.gtu" }, 721 { Instructions::i32_les, "i32.les" }, 722 { Instructions::i32_leu, "i32.leu" }, 723 { Instructions::i32_ges, "i32.ges" }, 724 { Instructions::i32_geu, "i32.geu" }, 725 { Instructions::i64_eqz, "i64.eqz" }, 726 { Instructions::i64_eq, "i64.eq" }, 727 { Instructions::i64_ne, "i64.ne" }, 728 { Instructions::i64_lts, "i64.lts" }, 729 { Instructions::i64_ltu, "i64.ltu" }, 730 { Instructions::i64_gts, "i64.gts" }, 731 { Instructions::i64_gtu, "i64.gtu" }, 732 { Instructions::i64_les, "i64.les" }, 733 { Instructions::i64_leu, "i64.leu" }, 734 { Instructions::i64_ges, "i64.ges" }, 735 { Instructions::i64_geu, "i64.geu" }, 736 { Instructions::f32_eq, "f32.eq" }, 737 { Instructions::f32_ne, "f32.ne" }, 738 { Instructions::f32_lt, "f32.lt" }, 739 { Instructions::f32_gt, "f32.gt" }, 740 { Instructions::f32_le, "f32.le" }, 741 { Instructions::f32_ge, "f32.ge" }, 742 { Instructions::f64_eq, "f64.eq" }, 743 { Instructions::f64_ne, "f64.ne" }, 744 { Instructions::f64_lt, "f64.lt" }, 745 { Instructions::f64_gt, "f64.gt" }, 746 { Instructions::f64_le, "f64.le" }, 747 { Instructions::f64_ge, "f64.ge" }, 748 { Instructions::i32_clz, "i32.clz" }, 749 { Instructions::i32_ctz, "i32.ctz" }, 750 { Instructions::i32_popcnt, "i32.popcnt" }, 751 { Instructions::i32_add, "i32.add" }, 752 { Instructions::i32_sub, "i32.sub" }, 753 { Instructions::i32_mul, "i32.mul" }, 754 { Instructions::i32_divs, "i32.divs" }, 755 { Instructions::i32_divu, "i32.divu" }, 756 { Instructions::i32_rems, "i32.rems" }, 757 { Instructions::i32_remu, "i32.remu" }, 758 { Instructions::i32_and, "i32.and" }, 759 { Instructions::i32_or, "i32.or" }, 760 { Instructions::i32_xor, "i32.xor" }, 761 { Instructions::i32_shl, "i32.shl" }, 762 { Instructions::i32_shrs, "i32.shrs" }, 763 { Instructions::i32_shru, "i32.shru" }, 764 { Instructions::i32_rotl, "i32.rotl" }, 765 { Instructions::i32_rotr, "i32.rotr" }, 766 { Instructions::i64_clz, "i64.clz" }, 767 { Instructions::i64_ctz, "i64.ctz" }, 768 { Instructions::i64_popcnt, "i64.popcnt" }, 769 { Instructions::i64_add, "i64.add" }, 770 { Instructions::i64_sub, "i64.sub" }, 771 { Instructions::i64_mul, "i64.mul" }, 772 { Instructions::i64_divs, "i64.divs" }, 773 { Instructions::i64_divu, "i64.divu" }, 774 { Instructions::i64_rems, "i64.rems" }, 775 { Instructions::i64_remu, "i64.remu" }, 776 { Instructions::i64_and, "i64.and" }, 777 { Instructions::i64_or, "i64.or" }, 778 { Instructions::i64_xor, "i64.xor" }, 779 { Instructions::i64_shl, "i64.shl" }, 780 { Instructions::i64_shrs, "i64.shrs" }, 781 { Instructions::i64_shru, "i64.shru" }, 782 { Instructions::i64_rotl, "i64.rotl" }, 783 { Instructions::i64_rotr, "i64.rotr" }, 784 { Instructions::f32_abs, "f32.abs" }, 785 { Instructions::f32_neg, "f32.neg" }, 786 { Instructions::f32_ceil, "f32.ceil" }, 787 { Instructions::f32_floor, "f32.floor" }, 788 { Instructions::f32_trunc, "f32.trunc" }, 789 { Instructions::f32_nearest, "f32.nearest" }, 790 { Instructions::f32_sqrt, "f32.sqrt" }, 791 { Instructions::f32_add, "f32.add" }, 792 { Instructions::f32_sub, "f32.sub" }, 793 { Instructions::f32_mul, "f32.mul" }, 794 { Instructions::f32_div, "f32.div" }, 795 { Instructions::f32_min, "f32.min" }, 796 { Instructions::f32_max, "f32.max" }, 797 { Instructions::f32_copysign, "f32.copysign" }, 798 { Instructions::f64_abs, "f64.abs" }, 799 { Instructions::f64_neg, "f64.neg" }, 800 { Instructions::f64_ceil, "f64.ceil" }, 801 { Instructions::f64_floor, "f64.floor" }, 802 { Instructions::f64_trunc, "f64.trunc" }, 803 { Instructions::f64_nearest, "f64.nearest" }, 804 { Instructions::f64_sqrt, "f64.sqrt" }, 805 { Instructions::f64_add, "f64.add" }, 806 { Instructions::f64_sub, "f64.sub" }, 807 { Instructions::f64_mul, "f64.mul" }, 808 { Instructions::f64_div, "f64.div" }, 809 { Instructions::f64_min, "f64.min" }, 810 { Instructions::f64_max, "f64.max" }, 811 { Instructions::f64_copysign, "f64.copysign" }, 812 { Instructions::i32_wrap_i64, "i32.wrap_i64" }, 813 { Instructions::i32_trunc_sf32, "i32.trunc_sf32" }, 814 { Instructions::i32_trunc_uf32, "i32.trunc_uf32" }, 815 { Instructions::i32_trunc_sf64, "i32.trunc_sf64" }, 816 { Instructions::i32_trunc_uf64, "i32.trunc_uf64" }, 817 { Instructions::i64_extend_si32, "i64.extend_si32" }, 818 { Instructions::i64_extend_ui32, "i64.extend_ui32" }, 819 { Instructions::i64_trunc_sf32, "i64.trunc_sf32" }, 820 { Instructions::i64_trunc_uf32, "i64.trunc_uf32" }, 821 { Instructions::i64_trunc_sf64, "i64.trunc_sf64" }, 822 { Instructions::i64_trunc_uf64, "i64.trunc_uf64" }, 823 { Instructions::f32_convert_si32, "f32.convert_si32" }, 824 { Instructions::f32_convert_ui32, "f32.convert_ui32" }, 825 { Instructions::f32_convert_si64, "f32.convert_si64" }, 826 { Instructions::f32_convert_ui64, "f32.convert_ui64" }, 827 { Instructions::f32_demote_f64, "f32.demote_f64" }, 828 { Instructions::f64_convert_si32, "f64.convert_si32" }, 829 { Instructions::f64_convert_ui32, "f64.convert_ui32" }, 830 { Instructions::f64_convert_si64, "f64.convert_si64" }, 831 { Instructions::f64_convert_ui64, "f64.convert_ui64" }, 832 { Instructions::f64_promote_f32, "f64.promote_f32" }, 833 { Instructions::i32_reinterpret_f32, "i32.reinterpret_f32" }, 834 { Instructions::i64_reinterpret_f64, "i64.reinterpret_f64" }, 835 { Instructions::f32_reinterpret_i32, "f32.reinterpret_i32" }, 836 { Instructions::f64_reinterpret_i64, "f64.reinterpret_i64" }, 837 { Instructions::i32_extend8_s, "i32.extend8_s" }, 838 { Instructions::i32_extend16_s, "i32.extend16_s" }, 839 { Instructions::i64_extend8_s, "i64.extend8_s" }, 840 { Instructions::i64_extend16_s, "i64.extend16_s" }, 841 { Instructions::i64_extend32_s, "i64.extend32_s" }, 842 { Instructions::ref_null, "ref.null" }, 843 { Instructions::ref_is_null, "ref.is.null" }, 844 { Instructions::ref_func, "ref.func" }, 845 { Instructions::i32_trunc_sat_f32_s, "i32.trunc_sat_f32_s" }, 846 { Instructions::i32_trunc_sat_f32_u, "i32.trunc_sat_f32_u" }, 847 { Instructions::i32_trunc_sat_f64_s, "i32.trunc_sat_f64_s" }, 848 { Instructions::i32_trunc_sat_f64_u, "i32.trunc_sat_f64_u" }, 849 { Instructions::i64_trunc_sat_f32_s, "i64.trunc_sat_f32_s" }, 850 { Instructions::i64_trunc_sat_f32_u, "i64.trunc_sat_f32_u" }, 851 { Instructions::i64_trunc_sat_f64_s, "i64.trunc_sat_f64_s" }, 852 { Instructions::i64_trunc_sat_f64_u, "i64.trunc_sat_f64_u" }, 853 { Instructions::memory_init, "memory.init" }, 854 { Instructions::data_drop, "data.drop" }, 855 { Instructions::memory_copy, "memory.copy" }, 856 { Instructions::memory_fill, "memory.fill" }, 857 { Instructions::table_init, "table.init" }, 858 { Instructions::elem_drop, "elem.drop" }, 859 { Instructions::table_copy, "table.copy" }, 860 { Instructions::table_grow, "table.grow" }, 861 { Instructions::table_size, "table.size" }, 862 { Instructions::table_fill, "table.fill" }, 863 { Instructions::structured_else, "synthetic:else" }, 864 { Instructions::structured_end, "synthetic:end" }, 865}; 866HashMap<DeprecatedString, Wasm::OpCode> Wasm::Names::instructions_by_name;