From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- third_party/wasm2c/LICENSE | 202 + third_party/wasm2c/include/wabt/apply-names.h | 45 + third_party/wasm2c/include/wabt/base-types.h | 35 + third_party/wasm2c/include/wabt/binary-reader-ir.h | 37 + .../wasm2c/include/wabt/binary-reader-logging.h | 424 ++ .../wasm2c/include/wabt/binary-reader-nop.h | 589 +++ .../wasm2c/include/wabt/binary-reader-objdump.h | 98 + .../wasm2c/include/wabt/binary-reader-opcnt.h | 96 + third_party/wasm2c/include/wabt/binary-reader.h | 505 ++ .../wasm2c/include/wabt/binary-writer-spec.h | 60 + third_party/wasm2c/include/wabt/binary-writer.h | 62 + third_party/wasm2c/include/wabt/binary.h | 106 + third_party/wasm2c/include/wabt/binding-hash.h | 72 + third_party/wasm2c/include/wabt/c-writer.h | 59 + third_party/wasm2c/include/wabt/cast.h | 109 + third_party/wasm2c/include/wabt/circular-array.h | 123 + third_party/wasm2c/include/wabt/color.h | 72 + third_party/wasm2c/include/wabt/common.h | 456 ++ third_party/wasm2c/include/wabt/decompiler-ast.h | 406 ++ third_party/wasm2c/include/wabt/decompiler-ls.h | 267 + .../wasm2c/include/wabt/decompiler-naming.h | 205 + third_party/wasm2c/include/wabt/decompiler.h | 35 + third_party/wasm2c/include/wabt/error-formatter.h | 54 + third_party/wasm2c/include/wabt/error.h | 58 + third_party/wasm2c/include/wabt/expr-visitor.h | 222 + third_party/wasm2c/include/wabt/feature.def | 42 + third_party/wasm2c/include/wabt/feature.h | 58 + third_party/wasm2c/include/wabt/filenames.h | 51 + third_party/wasm2c/include/wabt/generate-names.h | 46 + third_party/wasm2c/include/wabt/intrusive-list.h | 631 +++ third_party/wasm2c/include/wabt/ir-util.h | 77 + third_party/wasm2c/include/wabt/ir.h | 1483 ++++++ third_party/wasm2c/include/wabt/leb128.h | 70 + .../wasm2c/include/wabt/lexer-source-line-finder.h | 61 + third_party/wasm2c/include/wabt/lexer-source.h | 53 + third_party/wasm2c/include/wabt/literal.h | 129 + .../wasm2c/include/wabt/opcode-code-table.h | 43 + third_party/wasm2c/include/wabt/opcode.def | 593 +++ third_party/wasm2c/include/wabt/opcode.h | 172 + third_party/wasm2c/include/wabt/option-parser.h | 99 + third_party/wasm2c/include/wabt/range.h | 37 + third_party/wasm2c/include/wabt/resolve-names.h | 33 + third_party/wasm2c/include/wabt/result.h | 63 + third_party/wasm2c/include/wabt/sha256.h | 31 + third_party/wasm2c/include/wabt/shared-validator.h | 330 ++ third_party/wasm2c/include/wabt/stream.h | 229 + third_party/wasm2c/include/wabt/string-format.h | 68 + third_party/wasm2c/include/wabt/string-util.h | 82 + third_party/wasm2c/include/wabt/token.def | 175 + third_party/wasm2c/include/wabt/token.h | 134 + third_party/wasm2c/include/wabt/tracing.h | 73 + third_party/wasm2c/include/wabt/type-checker.h | 207 + third_party/wasm2c/include/wabt/type.h | 164 + third_party/wasm2c/include/wabt/utf8.h | 28 + third_party/wasm2c/include/wabt/validator.h | 36 + third_party/wasm2c/include/wabt/wast-lexer.h | 117 + third_party/wasm2c/include/wabt/wast-parser.h | 276 ++ third_party/wasm2c/include/wabt/wat-writer.h | 41 + third_party/wasm2c/src/apply-names.cc | 581 +++ third_party/wasm2c/src/binary-reader-ir.cc | 1757 +++++++ third_party/wasm2c/src/binary-reader-logging.cc | 971 ++++ third_party/wasm2c/src/binary-reader-objdump.cc | 2408 +++++++++ third_party/wasm2c/src/binary-reader-opcnt.cc | 314 ++ third_party/wasm2c/src/binary-reader.cc | 3027 +++++++++++ third_party/wasm2c/src/binary-writer-spec.cc | 672 +++ third_party/wasm2c/src/binary-writer.cc | 1798 +++++++ third_party/wasm2c/src/binary.cc | 68 + third_party/wasm2c/src/binding-hash.cc | 91 + third_party/wasm2c/src/c-writer.cc | 5241 ++++++++++++++++++++ third_party/wasm2c/src/color.cc | 86 + third_party/wasm2c/src/common.cc | 148 + third_party/wasm2c/src/config.cc | 162 + third_party/wasm2c/src/config.h.in | 332 ++ third_party/wasm2c/src/decompiler.cc | 857 ++++ third_party/wasm2c/src/emscripten-exports.txt | 72 + third_party/wasm2c/src/emscripten-helpers.cc | 403 ++ third_party/wasm2c/src/error-formatter.cc | 127 + third_party/wasm2c/src/expr-visitor.cc | 472 ++ third_party/wasm2c/src/feature.cc | 56 + third_party/wasm2c/src/filenames.cc | 57 + third_party/wasm2c/src/generate-names.cc | 433 ++ third_party/wasm2c/src/ir-util.cc | 271 + third_party/wasm2c/src/ir.cc | 701 +++ third_party/wasm2c/src/leb128.cc | 361 ++ third_party/wasm2c/src/lexer-keywords.txt | 609 +++ third_party/wasm2c/src/lexer-source-line-finder.cc | 152 + third_party/wasm2c/src/lexer-source.cc | 67 + third_party/wasm2c/src/literal.cc | 829 ++++ third_party/wasm2c/src/opcode-code-table.c | 41 + third_party/wasm2c/src/opcode.cc | 429 ++ third_party/wasm2c/src/option-parser.cc | 351 ++ third_party/wasm2c/src/prebuilt/.clang-format | 2 + third_party/wasm2c/src/prebuilt/lexer-keywords.cc | 1796 +++++++ .../wasm2c/src/prebuilt/wasm2c_header_bottom.cc | 7 + .../wasm2c/src/prebuilt/wasm2c_header_top.cc | 64 + .../src/prebuilt/wasm2c_source_declarations.cc | 1339 +++++ .../wasm2c/src/prebuilt/wasm2c_source_includes.cc | 33 + third_party/wasm2c/src/resolve-names.cc | 649 +++ third_party/wasm2c/src/sha256.cc | 48 + third_party/wasm2c/src/shared-validator.cc | 1203 +++++ third_party/wasm2c/src/stream.cc | 330 ++ third_party/wasm2c/src/test-binary-reader.cc | 75 + third_party/wasm2c/src/test-circular-array.cc | 284 ++ third_party/wasm2c/src/test-filenames.cc | 61 + third_party/wasm2c/src/test-hexfloat.cc | 264 + third_party/wasm2c/src/test-interp.cc | 723 +++ third_party/wasm2c/src/test-intrusive-list.cc | 583 +++ third_party/wasm2c/src/test-literal.cc | 838 ++++ third_party/wasm2c/src/test-option-parser.cc | 180 + third_party/wasm2c/src/test-utf8.cc | 167 + third_party/wasm2c/src/test-wast-parser.cc | 88 + third_party/wasm2c/src/token.cc | 99 + third_party/wasm2c/src/tools/wasm2c.cc | 217 + third_party/wasm2c/src/tracing.cc | 71 + third_party/wasm2c/src/type-checker.cc | 989 ++++ third_party/wasm2c/src/utf8.cc | 106 + third_party/wasm2c/src/validator.cc | 1086 ++++ third_party/wasm2c/src/wabt.post.js | 387 ++ third_party/wasm2c/src/wast-lexer.cc | 626 +++ third_party/wasm2c/src/wast-parser.cc | 3616 ++++++++++++++ third_party/wasm2c/src/wat-writer.cc | 1789 +++++++ third_party/wasm2c/wasm2c/.gitignore | 11 + third_party/wasm2c/wasm2c/README.md | 631 +++ third_party/wasm2c/wasm2c/wasm-rt-impl.c | 422 ++ third_party/wasm2c/wasm2c/wasm-rt-impl.h | 66 + third_party/wasm2c/wasm2c/wasm-rt.h | 455 ++ 126 files changed, 53378 insertions(+) create mode 100644 third_party/wasm2c/LICENSE create mode 100644 third_party/wasm2c/include/wabt/apply-names.h create mode 100644 third_party/wasm2c/include/wabt/base-types.h create mode 100644 third_party/wasm2c/include/wabt/binary-reader-ir.h create mode 100644 third_party/wasm2c/include/wabt/binary-reader-logging.h create mode 100644 third_party/wasm2c/include/wabt/binary-reader-nop.h create mode 100644 third_party/wasm2c/include/wabt/binary-reader-objdump.h create mode 100644 third_party/wasm2c/include/wabt/binary-reader-opcnt.h create mode 100644 third_party/wasm2c/include/wabt/binary-reader.h create mode 100644 third_party/wasm2c/include/wabt/binary-writer-spec.h create mode 100644 third_party/wasm2c/include/wabt/binary-writer.h create mode 100644 third_party/wasm2c/include/wabt/binary.h create mode 100644 third_party/wasm2c/include/wabt/binding-hash.h create mode 100644 third_party/wasm2c/include/wabt/c-writer.h create mode 100644 third_party/wasm2c/include/wabt/cast.h create mode 100644 third_party/wasm2c/include/wabt/circular-array.h create mode 100644 third_party/wasm2c/include/wabt/color.h create mode 100644 third_party/wasm2c/include/wabt/common.h create mode 100644 third_party/wasm2c/include/wabt/decompiler-ast.h create mode 100644 third_party/wasm2c/include/wabt/decompiler-ls.h create mode 100644 third_party/wasm2c/include/wabt/decompiler-naming.h create mode 100644 third_party/wasm2c/include/wabt/decompiler.h create mode 100644 third_party/wasm2c/include/wabt/error-formatter.h create mode 100644 third_party/wasm2c/include/wabt/error.h create mode 100644 third_party/wasm2c/include/wabt/expr-visitor.h create mode 100644 third_party/wasm2c/include/wabt/feature.def create mode 100644 third_party/wasm2c/include/wabt/feature.h create mode 100644 third_party/wasm2c/include/wabt/filenames.h create mode 100644 third_party/wasm2c/include/wabt/generate-names.h create mode 100644 third_party/wasm2c/include/wabt/intrusive-list.h create mode 100644 third_party/wasm2c/include/wabt/ir-util.h create mode 100644 third_party/wasm2c/include/wabt/ir.h create mode 100644 third_party/wasm2c/include/wabt/leb128.h create mode 100644 third_party/wasm2c/include/wabt/lexer-source-line-finder.h create mode 100644 third_party/wasm2c/include/wabt/lexer-source.h create mode 100644 third_party/wasm2c/include/wabt/literal.h create mode 100644 third_party/wasm2c/include/wabt/opcode-code-table.h create mode 100644 third_party/wasm2c/include/wabt/opcode.def create mode 100644 third_party/wasm2c/include/wabt/opcode.h create mode 100644 third_party/wasm2c/include/wabt/option-parser.h create mode 100644 third_party/wasm2c/include/wabt/range.h create mode 100644 third_party/wasm2c/include/wabt/resolve-names.h create mode 100644 third_party/wasm2c/include/wabt/result.h create mode 100644 third_party/wasm2c/include/wabt/sha256.h create mode 100644 third_party/wasm2c/include/wabt/shared-validator.h create mode 100644 third_party/wasm2c/include/wabt/stream.h create mode 100644 third_party/wasm2c/include/wabt/string-format.h create mode 100644 third_party/wasm2c/include/wabt/string-util.h create mode 100644 third_party/wasm2c/include/wabt/token.def create mode 100644 third_party/wasm2c/include/wabt/token.h create mode 100644 third_party/wasm2c/include/wabt/tracing.h create mode 100644 third_party/wasm2c/include/wabt/type-checker.h create mode 100644 third_party/wasm2c/include/wabt/type.h create mode 100644 third_party/wasm2c/include/wabt/utf8.h create mode 100644 third_party/wasm2c/include/wabt/validator.h create mode 100644 third_party/wasm2c/include/wabt/wast-lexer.h create mode 100644 third_party/wasm2c/include/wabt/wast-parser.h create mode 100644 third_party/wasm2c/include/wabt/wat-writer.h create mode 100644 third_party/wasm2c/src/apply-names.cc create mode 100644 third_party/wasm2c/src/binary-reader-ir.cc create mode 100644 third_party/wasm2c/src/binary-reader-logging.cc create mode 100644 third_party/wasm2c/src/binary-reader-objdump.cc create mode 100644 third_party/wasm2c/src/binary-reader-opcnt.cc create mode 100644 third_party/wasm2c/src/binary-reader.cc create mode 100644 third_party/wasm2c/src/binary-writer-spec.cc create mode 100644 third_party/wasm2c/src/binary-writer.cc create mode 100644 third_party/wasm2c/src/binary.cc create mode 100644 third_party/wasm2c/src/binding-hash.cc create mode 100644 third_party/wasm2c/src/c-writer.cc create mode 100644 third_party/wasm2c/src/color.cc create mode 100644 third_party/wasm2c/src/common.cc create mode 100644 third_party/wasm2c/src/config.cc create mode 100644 third_party/wasm2c/src/config.h.in create mode 100644 third_party/wasm2c/src/decompiler.cc create mode 100644 third_party/wasm2c/src/emscripten-exports.txt create mode 100644 third_party/wasm2c/src/emscripten-helpers.cc create mode 100644 third_party/wasm2c/src/error-formatter.cc create mode 100644 third_party/wasm2c/src/expr-visitor.cc create mode 100644 third_party/wasm2c/src/feature.cc create mode 100644 third_party/wasm2c/src/filenames.cc create mode 100644 third_party/wasm2c/src/generate-names.cc create mode 100644 third_party/wasm2c/src/ir-util.cc create mode 100644 third_party/wasm2c/src/ir.cc create mode 100644 third_party/wasm2c/src/leb128.cc create mode 100644 third_party/wasm2c/src/lexer-keywords.txt create mode 100644 third_party/wasm2c/src/lexer-source-line-finder.cc create mode 100644 third_party/wasm2c/src/lexer-source.cc create mode 100644 third_party/wasm2c/src/literal.cc create mode 100644 third_party/wasm2c/src/opcode-code-table.c create mode 100644 third_party/wasm2c/src/opcode.cc create mode 100644 third_party/wasm2c/src/option-parser.cc create mode 100644 third_party/wasm2c/src/prebuilt/.clang-format create mode 100644 third_party/wasm2c/src/prebuilt/lexer-keywords.cc create mode 100644 third_party/wasm2c/src/prebuilt/wasm2c_header_bottom.cc create mode 100644 third_party/wasm2c/src/prebuilt/wasm2c_header_top.cc create mode 100644 third_party/wasm2c/src/prebuilt/wasm2c_source_declarations.cc create mode 100644 third_party/wasm2c/src/prebuilt/wasm2c_source_includes.cc create mode 100644 third_party/wasm2c/src/resolve-names.cc create mode 100644 third_party/wasm2c/src/sha256.cc create mode 100644 third_party/wasm2c/src/shared-validator.cc create mode 100644 third_party/wasm2c/src/stream.cc create mode 100644 third_party/wasm2c/src/test-binary-reader.cc create mode 100644 third_party/wasm2c/src/test-circular-array.cc create mode 100644 third_party/wasm2c/src/test-filenames.cc create mode 100644 third_party/wasm2c/src/test-hexfloat.cc create mode 100644 third_party/wasm2c/src/test-interp.cc create mode 100644 third_party/wasm2c/src/test-intrusive-list.cc create mode 100644 third_party/wasm2c/src/test-literal.cc create mode 100644 third_party/wasm2c/src/test-option-parser.cc create mode 100644 third_party/wasm2c/src/test-utf8.cc create mode 100644 third_party/wasm2c/src/test-wast-parser.cc create mode 100644 third_party/wasm2c/src/token.cc create mode 100644 third_party/wasm2c/src/tools/wasm2c.cc create mode 100644 third_party/wasm2c/src/tracing.cc create mode 100644 third_party/wasm2c/src/type-checker.cc create mode 100644 third_party/wasm2c/src/utf8.cc create mode 100644 third_party/wasm2c/src/validator.cc create mode 100644 third_party/wasm2c/src/wabt.post.js create mode 100644 third_party/wasm2c/src/wast-lexer.cc create mode 100644 third_party/wasm2c/src/wast-parser.cc create mode 100644 third_party/wasm2c/src/wat-writer.cc create mode 100644 third_party/wasm2c/wasm2c/.gitignore create mode 100644 third_party/wasm2c/wasm2c/README.md create mode 100644 third_party/wasm2c/wasm2c/wasm-rt-impl.c create mode 100644 third_party/wasm2c/wasm2c/wasm-rt-impl.h create mode 100644 third_party/wasm2c/wasm2c/wasm-rt.h (limited to 'third_party/wasm2c') diff --git a/third_party/wasm2c/LICENSE b/third_party/wasm2c/LICENSE new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/third_party/wasm2c/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/third_party/wasm2c/include/wabt/apply-names.h b/third_party/wasm2c/include/wabt/apply-names.h new file mode 100644 index 0000000000..4d30fbd887 --- /dev/null +++ b/third_party/wasm2c/include/wabt/apply-names.h @@ -0,0 +1,45 @@ +/* + * Copyright 2016 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_APPLY_NAMES_H_ +#define WABT_APPLY_NAMES_H_ + +#include "wabt/common.h" + +namespace wabt { + +struct Module; + +/* Use function, import, function type, parameter and local names in Vars + * that reference them. + * + * e.g. transform this: + * + * (func $foo ...) + * ... + * (call 0 ...) + * + * to this: + * + * (func $foo ...) + * ... + * (call $foo ...) + */ +Result ApplyNames(struct Module*); + +} // namespace wabt + +#endif /* WABT_APPLY_NAMES_H_ */ diff --git a/third_party/wasm2c/include/wabt/base-types.h b/third_party/wasm2c/include/wabt/base-types.h new file mode 100644 index 0000000000..9e33835330 --- /dev/null +++ b/third_party/wasm2c/include/wabt/base-types.h @@ -0,0 +1,35 @@ +/* + * Copyright 2021 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_BASE_TYPES_H_ +#define WABT_BASE_TYPES_H_ + +#include +#include + +namespace wabt { + +using Index = uint32_t; // An index into one of the many index spaces. +using Address = uint64_t; // An address or size in linear memory. +using Offset = size_t; // An offset into a host's file or memory buffer. + +constexpr Address kInvalidAddress = ~0; +constexpr Index kInvalidIndex = ~0; +constexpr Offset kInvalidOffset = ~0; + +} // namespace wabt + +#endif // WABT_BASE_TYPES_H_ diff --git a/third_party/wasm2c/include/wabt/binary-reader-ir.h b/third_party/wasm2c/include/wabt/binary-reader-ir.h new file mode 100644 index 0000000000..4de0ee7099 --- /dev/null +++ b/third_party/wasm2c/include/wabt/binary-reader-ir.h @@ -0,0 +1,37 @@ +/* + * Copyright 2016 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_BINARY_READER_IR_H_ +#define WABT_BINARY_READER_IR_H_ + +#include "wabt/common.h" +#include "wabt/error.h" + +namespace wabt { + +struct Module; +struct ReadBinaryOptions; + +Result ReadBinaryIr(const char* filename, + const void* data, + size_t size, + const ReadBinaryOptions& options, + Errors*, + Module* out_module); + +} // namespace wabt + +#endif /* WABT_BINARY_READER_IR_H_ */ diff --git a/third_party/wasm2c/include/wabt/binary-reader-logging.h b/third_party/wasm2c/include/wabt/binary-reader-logging.h new file mode 100644 index 0000000000..9ce32aca5e --- /dev/null +++ b/third_party/wasm2c/include/wabt/binary-reader-logging.h @@ -0,0 +1,424 @@ +/* + * Copyright 2017 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_BINARY_READER_LOGGING_H_ +#define WABT_BINARY_READER_LOGGING_H_ + +#include "wabt/binary-reader.h" + +namespace wabt { + +class Stream; + +class BinaryReaderLogging : public BinaryReaderDelegate { + public: + BinaryReaderLogging(Stream*, BinaryReaderDelegate* forward); + + bool OnError(const Error&) override; + void OnSetState(const State* s) override; + + Result BeginModule(uint32_t version) override; + Result EndModule() override; + + Result BeginSection(Index section_index, + BinarySection section_type, + Offset size) override; + + Result BeginCustomSection(Index section_index, + Offset size, + std::string_view section_name) override; + Result EndCustomSection() override; + + Result BeginTypeSection(Offset size) override; + Result OnTypeCount(Index count) override; + Result OnFuncType(Index index, + Index param_count, + Type* param_types, + Index result_count, + Type* result_types) override; + Result OnStructType(Index index, Index field_count, TypeMut* fields) override; + Result OnArrayType(Index index, TypeMut field) override; + Result EndTypeSection() override; + + Result BeginImportSection(Offset size) override; + Result OnImportCount(Index count) override; + Result OnImport(Index index, + ExternalKind kind, + std::string_view module_name, + std::string_view field_name) override; + Result OnImportFunc(Index import_index, + std::string_view module_name, + std::string_view field_name, + Index func_index, + Index sig_index) override; + Result OnImportTable(Index import_index, + std::string_view module_name, + std::string_view field_name, + Index table_index, + Type elem_type, + const Limits* elem_limits) override; + Result OnImportMemory(Index import_index, + std::string_view module_name, + std::string_view field_name, + Index memory_index, + const Limits* page_limits) override; + Result OnImportGlobal(Index import_index, + std::string_view module_name, + std::string_view field_name, + Index global_index, + Type type, + bool mutable_) override; + Result OnImportTag(Index import_index, + std::string_view module_name, + std::string_view field_name, + Index tag_index, + Index sig_index) override; + Result EndImportSection() override; + + Result BeginFunctionSection(Offset size) override; + Result OnFunctionCount(Index count) override; + Result OnFunction(Index index, Index sig_index) override; + Result EndFunctionSection() override; + + Result BeginTableSection(Offset size) override; + Result OnTableCount(Index count) override; + Result OnTable(Index index, + Type elem_type, + const Limits* elem_limits) override; + Result EndTableSection() override; + + Result BeginMemorySection(Offset size) override; + Result OnMemoryCount(Index count) override; + Result OnMemory(Index index, const Limits* limits) override; + Result EndMemorySection() override; + + Result BeginGlobalSection(Offset size) override; + Result OnGlobalCount(Index count) override; + Result BeginGlobal(Index index, Type type, bool mutable_) override; + Result BeginGlobalInitExpr(Index index) override; + Result EndGlobalInitExpr(Index index) override; + Result EndGlobal(Index index) override; + Result EndGlobalSection() override; + + Result BeginExportSection(Offset size) override; + Result OnExportCount(Index count) override; + Result OnExport(Index index, + ExternalKind kind, + Index item_index, + std::string_view name) override; + Result EndExportSection() override; + + Result BeginStartSection(Offset size) override; + Result OnStartFunction(Index func_index) override; + Result EndStartSection() override; + + Result BeginCodeSection(Offset size) override; + Result OnFunctionBodyCount(Index count) override; + Result BeginFunctionBody(Index index, Offset size) override; + Result OnLocalDeclCount(Index count) override; + Result OnLocalDecl(Index decl_index, Index count, Type type) override; + + Result OnOpcode(Opcode opcode) override; + Result OnOpcodeBare() override; + Result OnOpcodeIndex(Index value) override; + Result OnOpcodeIndexIndex(Index value, Index value2) override; + Result OnOpcodeUint32(uint32_t value) override; + Result OnOpcodeUint32Uint32(uint32_t value, uint32_t value2) override; + Result OnOpcodeUint32Uint32Uint32(uint32_t value, + uint32_t value2, + uint32_t value3) override; + Result OnOpcodeUint32Uint32Uint32Uint32(uint32_t value, + uint32_t value2, + uint32_t value3, + uint32_t value4) override; + Result OnOpcodeUint64(uint64_t value) override; + Result OnOpcodeF32(uint32_t value) override; + Result OnOpcodeF64(uint64_t value) override; + Result OnOpcodeV128(v128 value) override; + Result OnOpcodeBlockSig(Type sig_type) override; + Result OnOpcodeType(Type type) override; + Result OnAtomicLoadExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset) override; + Result OnAtomicStoreExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset) override; + Result OnAtomicRmwExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset) override; + Result OnAtomicRmwCmpxchgExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset) override; + Result OnBinaryExpr(Opcode opcode) override; + Result OnBlockExpr(Type sig_type) override; + Result OnBrExpr(Index depth) override; + Result OnBrIfExpr(Index depth) override; + Result OnBrTableExpr(Index num_targets, + Index* target_depths, + Index default_target_depth) override; + Result OnCallExpr(Index func_index) override; + Result OnCatchExpr(Index tag_index) override; + Result OnCatchAllExpr() override; + Result OnCallIndirectExpr(Index sig_index, Index table_index) override; + Result OnCallRefExpr() override; + Result OnCompareExpr(Opcode opcode) override; + Result OnConvertExpr(Opcode opcode) override; + Result OnDelegateExpr(Index depth) override; + Result OnDropExpr() override; + Result OnElseExpr() override; + Result OnEndExpr() override; + Result OnF32ConstExpr(uint32_t value_bits) override; + Result OnF64ConstExpr(uint64_t value_bits) override; + Result OnV128ConstExpr(v128 value_bits) override; + Result OnGlobalGetExpr(Index global_index) override; + Result OnGlobalSetExpr(Index global_index) override; + Result OnI32ConstExpr(uint32_t value) override; + Result OnI64ConstExpr(uint64_t value) override; + Result OnIfExpr(Type sig_type) override; + Result OnLoadExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset) override; + Result OnLocalGetExpr(Index local_index) override; + Result OnLocalSetExpr(Index local_index) override; + Result OnLocalTeeExpr(Index local_index) override; + Result OnLoopExpr(Type sig_type) override; + Result OnMemoryCopyExpr(Index srcmemidx, Index destmemidx) override; + Result OnDataDropExpr(Index segment_index) override; + Result OnMemoryFillExpr(Index memidx) override; + Result OnMemoryGrowExpr(Index memidx) override; + Result OnMemoryInitExpr(Index segment_index, Index memidx) override; + Result OnMemorySizeExpr(Index memidx) override; + Result OnTableCopyExpr(Index dst_index, Index src_index) override; + Result OnElemDropExpr(Index segment_index) override; + Result OnTableInitExpr(Index segment_index, Index table_index) override; + Result OnTableGetExpr(Index table) override; + Result OnTableSetExpr(Index table) override; + Result OnTableGrowExpr(Index table) override; + Result OnTableSizeExpr(Index table) override; + Result OnTableFillExpr(Index table) override; + Result OnRefFuncExpr(Index index) override; + Result OnRefNullExpr(Type type) override; + Result OnRefIsNullExpr() override; + Result OnNopExpr() override; + Result OnRethrowExpr(Index depth) override; + Result OnReturnCallExpr(Index func_index) override; + Result OnReturnCallIndirectExpr(Index sig_index, Index table_index) override; + Result OnReturnExpr() override; + Result OnSelectExpr(Index result_count, Type* result_types) override; + Result OnStoreExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset) override; + Result OnThrowExpr(Index tag_index) override; + Result OnTryExpr(Type sig_type) override; + Result OnUnaryExpr(Opcode opcode) override; + Result OnTernaryExpr(Opcode opcode) override; + Result OnUnreachableExpr() override; + Result OnAtomicWaitExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset) override; + Result OnAtomicFenceExpr(uint32_t consistency_model) override; + Result OnAtomicNotifyExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset) override; + Result EndFunctionBody(Index index) override; + Result EndCodeSection() override; + Result OnSimdLaneOpExpr(Opcode opcode, uint64_t value) override; + Result OnSimdLoadLaneExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset, + uint64_t value) override; + Result OnSimdStoreLaneExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset, + uint64_t value) override; + Result OnSimdShuffleOpExpr(Opcode opcode, v128 value) override; + Result OnLoadSplatExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset) override; + Result OnLoadZeroExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset) override; + + Result BeginElemSection(Offset size) override; + Result OnElemSegmentCount(Index count) override; + Result BeginElemSegment(Index index, + Index table_index, + uint8_t flags) override; + Result BeginElemSegmentInitExpr(Index index) override; + Result EndElemSegmentInitExpr(Index index) override; + Result OnElemSegmentElemType(Index index, Type elem_type) override; + Result OnElemSegmentElemExprCount(Index index, Index count) override; + Result OnElemSegmentElemExpr_RefNull(Index segment_index, Type type) override; + Result OnElemSegmentElemExpr_RefFunc(Index segment_index, + Index func_index) override; + Result EndElemSegment(Index index) override; + Result EndElemSection() override; + + Result BeginDataSection(Offset size) override; + Result OnDataSegmentCount(Index count) override; + Result BeginDataSegment(Index index, + Index memory_index, + uint8_t flags) override; + Result BeginDataSegmentInitExpr(Index index) override; + Result EndDataSegmentInitExpr(Index index) override; + Result OnDataSegmentData(Index index, + const void* data, + Address size) override; + Result EndDataSegment(Index index) override; + Result EndDataSection() override; + + Result BeginDataCountSection(Offset size) override; + Result OnDataCount(Index count) override; + Result EndDataCountSection() override; + + Result BeginNamesSection(Offset size) override; + Result OnModuleNameSubsection(Index index, + uint32_t name_type, + Offset subsection_size) override; + Result OnModuleName(std::string_view name) override; + Result OnFunctionNameSubsection(Index index, + uint32_t name_type, + Offset subsection_size) override; + Result OnFunctionNamesCount(Index num_functions) override; + Result OnFunctionName(Index function_index, + std::string_view function_name) override; + Result OnLocalNameSubsection(Index index, + uint32_t name_type, + Offset subsection_size) override; + Result OnLocalNameFunctionCount(Index num_functions) override; + Result OnLocalNameLocalCount(Index function_index, Index num_locals) override; + Result OnLocalName(Index function_index, + Index local_index, + std::string_view local_name) override; + Result OnNameSubsection(Index index, + NameSectionSubsection subsection_type, + Offset subsection_size) override; + Result OnNameEntry(NameSectionSubsection type, + Index index, + std::string_view name) override; + Result OnNameCount(Index num_names) override; + Result EndNamesSection() override; + + Result BeginRelocSection(Offset size) override; + Result OnRelocCount(Index count, Index section_index) override; + Result OnReloc(RelocType type, + Offset offset, + Index index, + uint32_t addend) override; + Result EndRelocSection() override; + + Result BeginDylinkSection(Offset size) override; + Result OnDylinkInfo(uint32_t mem_size, + uint32_t mem_align, + uint32_t table_size, + uint32_t table_align) override; + Result OnDylinkNeededCount(Index count) override; + Result OnDylinkNeeded(std::string_view needed) override; + Result OnDylinkImportCount(Index count) override; + Result OnDylinkExportCount(Index count) override; + Result OnDylinkImport(std::string_view module, + std::string_view name, + uint32_t flags) override; + Result OnDylinkExport(std::string_view name, uint32_t flags) override; + Result EndDylinkSection() override; + + Result BeginTargetFeaturesSection(Offset size) override; + Result OnFeatureCount(Index count) override; + Result OnFeature(uint8_t prefix, std::string_view name) override; + Result EndTargetFeaturesSection() override; + + Result BeginLinkingSection(Offset size) override; + Result OnSymbolCount(Index count) override; + Result OnDataSymbol(Index index, + uint32_t flags, + std::string_view name, + Index segment, + uint32_t offset, + uint32_t size) override; + Result OnFunctionSymbol(Index index, + uint32_t flags, + std::string_view name, + Index func_index) override; + Result OnGlobalSymbol(Index index, + uint32_t flags, + std::string_view name, + Index global_index) override; + Result OnSectionSymbol(Index index, + uint32_t flags, + Index section_index) override; + Result OnTagSymbol(Index index, + uint32_t flags, + std::string_view name, + Index tag_index) override; + Result OnTableSymbol(Index index, + uint32_t flags, + std::string_view name, + Index tag_index) override; + Result OnSegmentInfoCount(Index count) override; + Result OnSegmentInfo(Index index, + std::string_view name, + Address alignment, + uint32_t flags) override; + Result OnInitFunctionCount(Index count) override; + Result OnInitFunction(uint32_t priority, Index symbol_index) override; + Result OnComdatCount(Index count) override; + Result OnComdatBegin(std::string_view name, + uint32_t flags, + Index count) override; + Result OnComdatEntry(ComdatType kind, Index index) override; + Result EndLinkingSection() override; + + Result BeginTagSection(Offset size) override; + Result OnTagCount(Index count) override; + Result OnTagType(Index index, Index sig_index) override; + Result EndTagSection() override; + + /* Code Metadata sections */ + Result BeginCodeMetadataSection(std::string_view name, Offset size) override; + Result OnCodeMetadataFuncCount(Index count) override; + Result OnCodeMetadataCount(Index function_index, Index count) override; + Result OnCodeMetadata(Offset offset, const void* data, Address size) override; + Result EndCodeMetadataSection() override; + + private: + void Indent(); + void Dedent(); + void WriteIndent(); + void LogType(Type type); + void LogTypes(Index type_count, Type* types); + void LogTypes(TypeVector& types); + void LogField(TypeMut field); + + Stream* stream_; + BinaryReaderDelegate* reader_; + int indent_; +}; + +} // namespace wabt + +#endif // WABT_BINARY_READER_LOGGING_H_ diff --git a/third_party/wasm2c/include/wabt/binary-reader-nop.h b/third_party/wasm2c/include/wabt/binary-reader-nop.h new file mode 100644 index 0000000000..0c9ebc6487 --- /dev/null +++ b/third_party/wasm2c/include/wabt/binary-reader-nop.h @@ -0,0 +1,589 @@ +/* + * Copyright 2016 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_BINARY_READER_NOP_H_ +#define WABT_BINARY_READER_NOP_H_ + +#include "wabt/binary-reader.h" + +namespace wabt { + +class BinaryReaderNop : public BinaryReaderDelegate { + public: + bool OnError(const Error&) override { return false; } + + /* Module */ + Result BeginModule(uint32_t version) override { return Result::Ok; } + Result EndModule() override { return Result::Ok; } + + Result BeginSection(Index section_index, + BinarySection section_type, + Offset size) override { + return Result::Ok; + } + + /* Custom section */ + Result BeginCustomSection(Index section_index, + Offset size, + std::string_view section_name) override { + return Result::Ok; + } + Result EndCustomSection() override { return Result::Ok; } + + /* Type section */ + Result BeginTypeSection(Offset size) override { return Result::Ok; } + Result OnTypeCount(Index count) override { return Result::Ok; } + Result OnFuncType(Index index, + Index param_count, + Type* param_types, + Index result_count, + Type* result_types) override { + return Result::Ok; + } + Result OnStructType(Index index, + Index field_count, + TypeMut* fields) override { + return Result::Ok; + } + Result OnArrayType(Index index, TypeMut field) override { return Result::Ok; } + Result EndTypeSection() override { return Result::Ok; } + + /* Import section */ + Result BeginImportSection(Offset size) override { return Result::Ok; } + Result OnImportCount(Index count) override { return Result::Ok; } + Result OnImport(Index index, + ExternalKind kind, + std::string_view module_name, + std::string_view field_name) override { + return Result::Ok; + } + Result OnImportFunc(Index import_index, + std::string_view module_name, + std::string_view field_name, + Index func_index, + Index sig_index) override { + return Result::Ok; + } + Result OnImportTable(Index import_index, + std::string_view module_name, + std::string_view field_name, + Index table_index, + Type elem_type, + const Limits* elem_limits) override { + return Result::Ok; + } + Result OnImportMemory(Index import_index, + std::string_view module_name, + std::string_view field_name, + Index memory_index, + const Limits* page_limits) override { + return Result::Ok; + } + Result OnImportGlobal(Index import_index, + std::string_view module_name, + std::string_view field_name, + Index global_index, + Type type, + bool mutable_) override { + return Result::Ok; + } + Result OnImportTag(Index import_index, + std::string_view module_name, + std::string_view field_name, + Index tag_index, + Index sig_index) override { + return Result::Ok; + } + Result EndImportSection() override { return Result::Ok; } + + /* Function section */ + Result BeginFunctionSection(Offset size) override { return Result::Ok; } + Result OnFunctionCount(Index count) override { return Result::Ok; } + Result OnFunction(Index index, Index sig_index) override { + return Result::Ok; + } + Result EndFunctionSection() override { return Result::Ok; } + + /* Table section */ + Result BeginTableSection(Offset size) override { return Result::Ok; } + Result OnTableCount(Index count) override { return Result::Ok; } + Result OnTable(Index index, + Type elem_type, + const Limits* elem_limits) override { + return Result::Ok; + } + Result EndTableSection() override { return Result::Ok; } + + /* Memory section */ + Result BeginMemorySection(Offset size) override { return Result::Ok; } + Result OnMemoryCount(Index count) override { return Result::Ok; } + Result OnMemory(Index index, const Limits* limits) override { + return Result::Ok; + } + Result EndMemorySection() override { return Result::Ok; } + + /* Global section */ + Result BeginGlobalSection(Offset size) override { return Result::Ok; } + Result OnGlobalCount(Index count) override { return Result::Ok; } + Result BeginGlobal(Index index, Type type, bool mutable_) override { + return Result::Ok; + } + Result BeginGlobalInitExpr(Index index) override { return Result::Ok; } + Result EndGlobalInitExpr(Index index) override { return Result::Ok; } + Result EndGlobal(Index index) override { return Result::Ok; } + Result EndGlobalSection() override { return Result::Ok; } + + /* Exports section */ + Result BeginExportSection(Offset size) override { return Result::Ok; } + Result OnExportCount(Index count) override { return Result::Ok; } + Result OnExport(Index index, + ExternalKind kind, + Index item_index, + std::string_view name) override { + return Result::Ok; + } + Result EndExportSection() override { return Result::Ok; } + + /* Start section */ + Result BeginStartSection(Offset size) override { return Result::Ok; } + Result OnStartFunction(Index func_index) override { return Result::Ok; } + Result EndStartSection() override { return Result::Ok; } + + /* Code section */ + Result BeginCodeSection(Offset size) override { return Result::Ok; } + Result OnFunctionBodyCount(Index count) override { return Result::Ok; } + Result BeginFunctionBody(Index index, Offset size) override { + return Result::Ok; + } + Result OnLocalDeclCount(Index count) override { return Result::Ok; } + Result OnLocalDecl(Index decl_index, Index count, Type type) override { + return Result::Ok; + } + + /* Function expressions; called between BeginFunctionBody and + EndFunctionBody */ + Result OnOpcode(Opcode Opcode) override { return Result::Ok; } + Result OnOpcodeBare() override { return Result::Ok; } + Result OnOpcodeIndex(Index value) override { return Result::Ok; } + Result OnOpcodeIndexIndex(Index value, Index value2) override { + return Result::Ok; + } + Result OnOpcodeUint32(uint32_t value) override { return Result::Ok; } + Result OnOpcodeUint32Uint32(uint32_t value, uint32_t value2) override { + return Result::Ok; + } + Result OnOpcodeUint32Uint32Uint32(uint32_t value, + uint32_t value2, + uint32_t value3) override { + return Result::Ok; + } + Result OnOpcodeUint32Uint32Uint32Uint32(uint32_t value, + uint32_t value2, + uint32_t value3, + uint32_t value4) override { + return Result::Ok; + } + Result OnOpcodeUint64(uint64_t value) override { return Result::Ok; } + Result OnOpcodeF32(uint32_t value) override { return Result::Ok; } + Result OnOpcodeF64(uint64_t value) override { return Result::Ok; } + Result OnOpcodeV128(v128 value) override { return Result::Ok; } + Result OnOpcodeBlockSig(Type sig_type) override { return Result::Ok; } + Result OnOpcodeType(Type type) override { return Result::Ok; } + Result OnAtomicLoadExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset) override { + return Result::Ok; + } + Result OnAtomicStoreExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset) override { + return Result::Ok; + } + Result OnAtomicRmwExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset) override { + return Result::Ok; + } + Result OnAtomicRmwCmpxchgExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset) override { + return Result::Ok; + } + Result OnAtomicWaitExpr(Opcode, Index, Address, Address) override { + return Result::Ok; + } + Result OnAtomicFenceExpr(uint32_t) override { return Result::Ok; } + Result OnAtomicNotifyExpr(Opcode, Index, Address, Address) override { + return Result::Ok; + } + Result OnBinaryExpr(Opcode opcode) override { return Result::Ok; } + Result OnBlockExpr(Type sig_type) override { return Result::Ok; } + Result OnBrExpr(Index depth) override { return Result::Ok; } + Result OnBrIfExpr(Index depth) override { return Result::Ok; } + Result OnBrTableExpr(Index num_targets, + Index* target_depths, + Index default_target_depth) override { + return Result::Ok; + } + Result OnCallExpr(Index func_index) override { return Result::Ok; } + Result OnCallIndirectExpr(Index sig_index, Index table_index) override { + return Result::Ok; + } + Result OnCallRefExpr() override { return Result::Ok; } + Result OnCatchExpr(Index tag_index) override { return Result::Ok; } + Result OnCatchAllExpr() override { return Result::Ok; } + Result OnCompareExpr(Opcode opcode) override { return Result::Ok; } + Result OnConvertExpr(Opcode opcode) override { return Result::Ok; } + Result OnDelegateExpr(Index depth) override { return Result::Ok; } + Result OnDropExpr() override { return Result::Ok; } + Result OnElseExpr() override { return Result::Ok; } + Result OnEndExpr() override { return Result::Ok; } + Result OnF32ConstExpr(uint32_t value_bits) override { return Result::Ok; } + Result OnF64ConstExpr(uint64_t value_bits) override { return Result::Ok; } + Result OnV128ConstExpr(v128 value_bits) override { return Result::Ok; } + Result OnGlobalGetExpr(Index global_index) override { return Result::Ok; } + Result OnGlobalSetExpr(Index global_index) override { return Result::Ok; } + Result OnI32ConstExpr(uint32_t value) override { return Result::Ok; } + Result OnI64ConstExpr(uint64_t value) override { return Result::Ok; } + Result OnIfExpr(Type sig_type) override { return Result::Ok; } + Result OnLoadExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset) override { + return Result::Ok; + } + Result OnLocalGetExpr(Index local_index) override { return Result::Ok; } + Result OnLocalSetExpr(Index local_index) override { return Result::Ok; } + Result OnLocalTeeExpr(Index local_index) override { return Result::Ok; } + Result OnLoopExpr(Type sig_type) override { return Result::Ok; } + Result OnMemoryCopyExpr(Index srcmemidx, Index destmemidx) override { + return Result::Ok; + } + Result OnDataDropExpr(Index segment_index) override { return Result::Ok; } + Result OnMemoryFillExpr(Index memidx) override { return Result::Ok; } + Result OnMemoryGrowExpr(Index memidx) override { return Result::Ok; } + Result OnMemoryInitExpr(Index segment_index, Index memidx) override { + return Result::Ok; + } + Result OnMemorySizeExpr(Index memidx) override { return Result::Ok; } + Result OnTableCopyExpr(Index dst_index, Index src_index) override { + return Result::Ok; + } + Result OnElemDropExpr(Index segment_index) override { return Result::Ok; } + Result OnTableInitExpr(Index segment_index, Index table_index) override { + return Result::Ok; + } + Result OnTableGetExpr(Index table_index) override { return Result::Ok; } + Result OnTableSetExpr(Index table_index) override { return Result::Ok; } + Result OnTableGrowExpr(Index table_index) override { return Result::Ok; } + Result OnTableSizeExpr(Index table_index) override { return Result::Ok; } + Result OnTableFillExpr(Index table_index) override { return Result::Ok; } + Result OnRefFuncExpr(Index func_index) override { return Result::Ok; } + Result OnRefNullExpr(Type type) override { return Result::Ok; } + Result OnRefIsNullExpr() override { return Result::Ok; } + Result OnNopExpr() override { return Result::Ok; } + Result OnRethrowExpr(Index depth) override { return Result::Ok; } + Result OnReturnCallExpr(Index sig_index) override { return Result::Ok; } + Result OnReturnCallIndirectExpr(Index sig_index, Index table_index) override { + return Result::Ok; + } + Result OnReturnExpr() override { return Result::Ok; } + Result OnSelectExpr(Index result_count, Type* result_types) override { + return Result::Ok; + } + Result OnStoreExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset) override { + return Result::Ok; + } + Result OnThrowExpr(Index depth) override { return Result::Ok; } + Result OnTryExpr(Type sig_type) override { return Result::Ok; } + Result OnUnaryExpr(Opcode opcode) override { return Result::Ok; } + Result OnTernaryExpr(Opcode opcode) override { return Result::Ok; } + Result OnUnreachableExpr() override { return Result::Ok; } + Result EndFunctionBody(Index index) override { return Result::Ok; } + Result EndCodeSection() override { return Result::Ok; } + Result OnSimdLaneOpExpr(Opcode opcode, uint64_t value) override { + return Result::Ok; + } + Result OnSimdLoadLaneExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset, + uint64_t value) override { + return Result::Ok; + } + Result OnSimdStoreLaneExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset, + uint64_t value) override { + return Result::Ok; + } + Result OnSimdShuffleOpExpr(Opcode opcode, v128 value) override { + return Result::Ok; + } + Result OnLoadSplatExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset) override { + return Result::Ok; + } + Result OnLoadZeroExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset) override { + return Result::Ok; + } + + /* Elem section */ + Result BeginElemSection(Offset size) override { return Result::Ok; } + Result OnElemSegmentCount(Index count) override { return Result::Ok; } + Result BeginElemSegment(Index index, + Index table_index, + uint8_t flags) override { + return Result::Ok; + } + Result BeginElemSegmentInitExpr(Index index) override { return Result::Ok; } + Result EndElemSegmentInitExpr(Index index) override { return Result::Ok; } + Result OnElemSegmentElemType(Index index, Type elem_type) override { + return Result::Ok; + } + Result OnElemSegmentElemExprCount(Index index, Index count) override { + return Result::Ok; + } + Result OnElemSegmentElemExpr_RefNull(Index segment_index, + Type type) override { + return Result::Ok; + } + Result OnElemSegmentElemExpr_RefFunc(Index segment_index, + Index func_index) override { + return Result::Ok; + } + Result EndElemSegment(Index index) override { return Result::Ok; } + Result EndElemSection() override { return Result::Ok; } + + /* Data section */ + Result BeginDataSection(Offset size) override { return Result::Ok; } + Result OnDataSegmentCount(Index count) override { return Result::Ok; } + Result BeginDataSegment(Index index, + Index memory_index, + uint8_t flags) override { + return Result::Ok; + } + Result BeginDataSegmentInitExpr(Index index) override { return Result::Ok; } + Result EndDataSegmentInitExpr(Index index) override { return Result::Ok; } + Result OnDataSegmentData(Index index, + const void* data, + Address size) override { + return Result::Ok; + } + Result EndDataSegment(Index index) override { return Result::Ok; } + Result EndDataSection() override { return Result::Ok; } + + /* DataCount section */ + Result BeginDataCountSection(Offset size) override { return Result::Ok; } + Result OnDataCount(Index count) override { return Result::Ok; } + Result EndDataCountSection() override { return Result::Ok; } + + /* Names section */ + Result BeginNamesSection(Offset size) override { return Result::Ok; } + Result OnModuleNameSubsection(Index index, + uint32_t name_type, + Offset subsection_size) override { + return Result::Ok; + } + Result OnModuleName(std::string_view name) override { return Result::Ok; } + Result OnFunctionNameSubsection(Index index, + uint32_t name_type, + Offset subsection_size) override { + return Result::Ok; + } + Result OnFunctionNamesCount(Index num_functions) override { + return Result::Ok; + } + Result OnFunctionName(Index function_index, + std::string_view function_name) override { + return Result::Ok; + } + Result OnLocalNameSubsection(Index index, + uint32_t name_type, + Offset subsection_size) override { + return Result::Ok; + } + Result OnLocalNameFunctionCount(Index num_functions) override { + return Result::Ok; + } + Result OnLocalNameLocalCount(Index function_index, + Index num_locals) override { + return Result::Ok; + } + Result OnLocalName(Index function_index, + Index local_index, + std::string_view local_name) override { + return Result::Ok; + } + Result EndNamesSection() override { return Result::Ok; } + + Result OnNameSubsection(Index index, + NameSectionSubsection subsection_type, + Offset subsection_size) override { + return Result::Ok; + } + Result OnNameCount(Index num_names) override { return Result::Ok; } + Result OnNameEntry(NameSectionSubsection type, + Index index, + std::string_view name) override { + return Result::Ok; + } + + /* Reloc section */ + Result BeginRelocSection(Offset size) override { return Result::Ok; } + Result OnRelocCount(Index count, Index section_code) override { + return Result::Ok; + } + Result OnReloc(RelocType type, + Offset offset, + Index index, + uint32_t addend) override { + return Result::Ok; + } + Result EndRelocSection() override { return Result::Ok; } + + /* Tag section */ + Result BeginTagSection(Offset size) override { return Result::Ok; } + Result OnTagCount(Index count) override { return Result::Ok; } + Result OnTagType(Index index, Index sig_index) override { return Result::Ok; } + Result EndTagSection() override { return Result::Ok; } + + /* Code Metadata sections */ + Result BeginCodeMetadataSection(std::string_view name, Offset size) override { + return Result::Ok; + } + Result OnCodeMetadataFuncCount(Index count) override { return Result::Ok; } + Result OnCodeMetadataCount(Index function_index, Index count) override { + return Result::Ok; + } + Result OnCodeMetadata(Offset offset, + const void* data, + Address size) override { + return Result::Ok; + } + Result EndCodeMetadataSection() override { return Result::Ok; } + + /* Dylink section */ + Result BeginDylinkSection(Offset size) override { return Result::Ok; } + Result OnDylinkInfo(uint32_t mem_size, + uint32_t mem_align, + uint32_t table_size, + uint32_t table_align) override { + return Result::Ok; + } + Result OnDylinkNeededCount(Index count) override { return Result::Ok; } + Result OnDylinkNeeded(std::string_view so_name) override { + return Result::Ok; + } + Result OnDylinkImportCount(Index count) override { return Result::Ok; } + Result OnDylinkExportCount(Index count) override { return Result::Ok; } + Result OnDylinkImport(std::string_view module, + std::string_view name, + uint32_t flags) override { + return Result::Ok; + } + Result OnDylinkExport(std::string_view name, uint32_t flags) override { + return Result::Ok; + } + Result EndDylinkSection() override { return Result::Ok; } + + /* target_features section */ + Result BeginTargetFeaturesSection(Offset size) override { return Result::Ok; } + Result OnFeatureCount(Index count) override { return Result::Ok; } + Result OnFeature(uint8_t prefix, std::string_view name) override { + return Result::Ok; + } + Result EndTargetFeaturesSection() override { return Result::Ok; } + + /* Linking section */ + Result BeginLinkingSection(Offset size) override { return Result::Ok; } + Result OnSymbolCount(Index count) override { return Result::Ok; } + Result OnDataSymbol(Index index, + uint32_t flags, + std::string_view name, + Index segment, + uint32_t offset, + uint32_t size) override { + return Result::Ok; + } + Result OnFunctionSymbol(Index index, + uint32_t flags, + std::string_view name, + Index func_index) override { + return Result::Ok; + } + Result OnGlobalSymbol(Index index, + uint32_t flags, + std::string_view name, + Index global_index) override { + return Result::Ok; + } + Result OnSectionSymbol(Index index, + uint32_t flags, + Index section_index) override { + return Result::Ok; + } + Result OnTagSymbol(Index index, + uint32_t flags, + std::string_view name, + Index tag_index) override { + return Result::Ok; + } + Result OnTableSymbol(Index index, + uint32_t flags, + std::string_view name, + Index table_index) override { + return Result::Ok; + } + Result OnSegmentInfoCount(Index count) override { return Result::Ok; } + Result OnSegmentInfo(Index index, + std::string_view name, + Address alignment, + uint32_t flags) override { + return Result::Ok; + } + Result OnInitFunctionCount(Index count) override { return Result::Ok; } + Result OnInitFunction(uint32_t priority, Index symbol_index) override { + return Result::Ok; + } + Result OnComdatCount(Index count) override { return Result::Ok; } + Result OnComdatBegin(std::string_view name, + uint32_t flags, + Index count) override { + return Result::Ok; + } + Result OnComdatEntry(ComdatType kind, Index index) override { + return Result::Ok; + } + Result EndLinkingSection() override { return Result::Ok; } +}; + +} // namespace wabt + +#endif /* WABT_BINARY_READER_H_ */ diff --git a/third_party/wasm2c/include/wabt/binary-reader-objdump.h b/third_party/wasm2c/include/wabt/binary-reader-objdump.h new file mode 100644 index 0000000000..0ca7458f8e --- /dev/null +++ b/third_party/wasm2c/include/wabt/binary-reader-objdump.h @@ -0,0 +1,98 @@ +/* + * Copyright 2016 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_BINARY_READER_OBJDUMP_H_ +#define WABT_BINARY_READER_OBJDUMP_H_ + +#include +#include + +#include "wabt/common.h" +#include "wabt/feature.h" +#include "wabt/stream.h" + +namespace wabt { + +struct Module; +struct ReadBinaryOptions; + +enum class ObjdumpMode { + Prepass, + Headers, + Details, + Disassemble, + RawData, +}; + +struct ObjdumpOptions { + Stream* log_stream; + bool headers; + bool details; + bool raw; + bool disassemble; + bool debug; + bool relocs; + bool section_offsets; + ObjdumpMode mode; + const char* filename; + const char* section_name; +}; + +struct ObjdumpSymbol { + wabt::SymbolType kind; + std::string name; + Index index; +}; + +struct ObjdumpNames { + std::string_view Get(Index index) const; + void Set(Index index, std::string_view name); + + std::map names; +}; + +struct ObjdumpLocalNames { + std::string_view Get(Index function_index, Index local_index) const; + void Set(Index function_index, Index local_index, std::string_view name); + + std::map, std::string> names; +}; + +// read_binary_objdump uses this state to store information from previous runs +// and use it to display more useful information. +struct ObjdumpState { + std::vector code_relocations; + std::vector data_relocations; + ObjdumpNames type_names; + ObjdumpNames function_names; + ObjdumpNames global_names; + ObjdumpNames section_names; + ObjdumpNames tag_names; + ObjdumpNames segment_names; + ObjdumpNames table_names; + ObjdumpLocalNames local_names; + std::vector symtab; + std::map function_param_counts; +}; + +Result ReadBinaryObjdump(const uint8_t* data, + size_t size, + ObjdumpOptions* options, + ObjdumpState* state); + +} // namespace wabt + +#endif /* WABT_BINARY_READER_OBJDUMP_H_ */ diff --git a/third_party/wasm2c/include/wabt/binary-reader-opcnt.h b/third_party/wasm2c/include/wabt/binary-reader-opcnt.h new file mode 100644 index 0000000000..8c3a9aba8d --- /dev/null +++ b/third_party/wasm2c/include/wabt/binary-reader-opcnt.h @@ -0,0 +1,96 @@ +/* + * Copyright 2016 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_BINARY_READER_OPCNT_H_ +#define WABT_BINARY_READER_OPCNT_H_ + +#include +#include + +#include "wabt/common.h" +#include "wabt/opcode.h" + +namespace wabt { + +struct Module; +struct ReadBinaryOptions; +class Stream; + +class OpcodeInfo { + public: + enum class Kind { + Bare, + Uint32, + Uint64, + Index, + Float32, + Float64, + Uint32Uint32, + Uint32Uint32Uint32, + Uint32Uint32Uint32Uint32, + BlockSig, + BrTable, + V128, + }; + + explicit OpcodeInfo(Opcode, Kind); + template + OpcodeInfo(Opcode, Kind, T* data, size_t count = 1); + template + OpcodeInfo(Opcode, Kind, T* data, size_t count, T extra); + + Opcode opcode() const { return opcode_; } + + void Write(Stream&); + + private: + template + std::pair GetDataArray() const; + template + const T* GetData(size_t expected_size = 1) const; + + template + void WriteArray(Stream& stream, F&& write_func); + + Opcode opcode_; + Kind kind_; + std::vector data_; + + friend bool operator==(const OpcodeInfo&, const OpcodeInfo&); + friend bool operator!=(const OpcodeInfo&, const OpcodeInfo&); + friend bool operator<(const OpcodeInfo&, const OpcodeInfo&); + friend bool operator<=(const OpcodeInfo&, const OpcodeInfo&); + friend bool operator>(const OpcodeInfo&, const OpcodeInfo&); + friend bool operator>=(const OpcodeInfo&, const OpcodeInfo&); +}; + +bool operator==(const OpcodeInfo&, const OpcodeInfo&); +bool operator!=(const OpcodeInfo&, const OpcodeInfo&); +bool operator<(const OpcodeInfo&, const OpcodeInfo&); +bool operator<=(const OpcodeInfo&, const OpcodeInfo&); +bool operator>(const OpcodeInfo&, const OpcodeInfo&); +bool operator>=(const OpcodeInfo&, const OpcodeInfo&); + +using OpcodeInfoCounts = std::map; + +Result ReadBinaryOpcnt(const void* data, + size_t size, + const ReadBinaryOptions& options, + OpcodeInfoCounts* opcode_counts); + +} // namespace wabt + +#endif /* WABT_BINARY_READER_OPCNT_H_ */ diff --git a/third_party/wasm2c/include/wabt/binary-reader.h b/third_party/wasm2c/include/wabt/binary-reader.h new file mode 100644 index 0000000000..825d562cb0 --- /dev/null +++ b/third_party/wasm2c/include/wabt/binary-reader.h @@ -0,0 +1,505 @@ +/* + * Copyright 2016 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_BINARY_READER_H_ +#define WABT_BINARY_READER_H_ + +#include +#include +#include + +#include "wabt/binary.h" +#include "wabt/common.h" +#include "wabt/error.h" +#include "wabt/feature.h" +#include "wabt/opcode.h" + +namespace wabt { + +class Stream; + +struct ReadBinaryOptions { + ReadBinaryOptions() = default; + ReadBinaryOptions(const Features& features, + Stream* log_stream, + bool read_debug_names, + bool stop_on_first_error, + bool fail_on_custom_section_error) + : features(features), + log_stream(log_stream), + read_debug_names(read_debug_names), + stop_on_first_error(stop_on_first_error), + fail_on_custom_section_error(fail_on_custom_section_error) {} + + Features features; + Stream* log_stream = nullptr; + bool read_debug_names = false; + bool stop_on_first_error = true; + bool fail_on_custom_section_error = true; + bool skip_function_bodies = false; +}; + +// TODO: Move somewhere else? +struct TypeMut { + Type type; + bool mutable_; +}; +using TypeMutVector = std::vector; + +class BinaryReaderDelegate { + public: + struct State { + State(const uint8_t* data, Offset size) + : data(data), size(size), offset(0) {} + + const uint8_t* data; + Offset size; + Offset offset; + }; + + virtual ~BinaryReaderDelegate() {} + + virtual bool OnError(const Error&) = 0; + virtual void OnSetState(const State* s) { state = s; } + + /* Module */ + virtual Result BeginModule(uint32_t version) = 0; + virtual Result EndModule() = 0; + + virtual Result BeginSection(Index section_index, + BinarySection section_type, + Offset size) = 0; + + /* Custom section */ + virtual Result BeginCustomSection(Index section_index, + Offset size, + std::string_view section_name) = 0; + virtual Result EndCustomSection() = 0; + + /* Type section */ + virtual Result BeginTypeSection(Offset size) = 0; + virtual Result OnTypeCount(Index count) = 0; + virtual Result OnFuncType(Index index, + Index param_count, + Type* param_types, + Index result_count, + Type* result_types) = 0; + virtual Result OnStructType(Index index, + Index field_count, + TypeMut* fields) = 0; + virtual Result OnArrayType(Index index, TypeMut field) = 0; + virtual Result EndTypeSection() = 0; + + /* Import section */ + virtual Result BeginImportSection(Offset size) = 0; + virtual Result OnImportCount(Index count) = 0; + virtual Result OnImport(Index index, + ExternalKind kind, + std::string_view module_name, + std::string_view field_name) = 0; + virtual Result OnImportFunc(Index import_index, + std::string_view module_name, + std::string_view field_name, + Index func_index, + Index sig_index) = 0; + virtual Result OnImportTable(Index import_index, + std::string_view module_name, + std::string_view field_name, + Index table_index, + Type elem_type, + const Limits* elem_limits) = 0; + virtual Result OnImportMemory(Index import_index, + std::string_view module_name, + std::string_view field_name, + Index memory_index, + const Limits* page_limits) = 0; + virtual Result OnImportGlobal(Index import_index, + std::string_view module_name, + std::string_view field_name, + Index global_index, + Type type, + bool mutable_) = 0; + virtual Result OnImportTag(Index import_index, + std::string_view module_name, + std::string_view field_name, + Index tag_index, + Index sig_index) = 0; + virtual Result EndImportSection() = 0; + + /* Function section */ + virtual Result BeginFunctionSection(Offset size) = 0; + virtual Result OnFunctionCount(Index count) = 0; + virtual Result OnFunction(Index index, Index sig_index) = 0; + virtual Result EndFunctionSection() = 0; + + /* Table section */ + virtual Result BeginTableSection(Offset size) = 0; + virtual Result OnTableCount(Index count) = 0; + virtual Result OnTable(Index index, + Type elem_type, + const Limits* elem_limits) = 0; + virtual Result EndTableSection() = 0; + + /* Memory section */ + virtual Result BeginMemorySection(Offset size) = 0; + virtual Result OnMemoryCount(Index count) = 0; + virtual Result OnMemory(Index index, const Limits* limits) = 0; + virtual Result EndMemorySection() = 0; + + /* Global section */ + virtual Result BeginGlobalSection(Offset size) = 0; + virtual Result OnGlobalCount(Index count) = 0; + virtual Result BeginGlobal(Index index, Type type, bool mutable_) = 0; + virtual Result BeginGlobalInitExpr(Index index) = 0; + virtual Result EndGlobalInitExpr(Index index) = 0; + virtual Result EndGlobal(Index index) = 0; + virtual Result EndGlobalSection() = 0; + + /* Exports section */ + virtual Result BeginExportSection(Offset size) = 0; + virtual Result OnExportCount(Index count) = 0; + virtual Result OnExport(Index index, + ExternalKind kind, + Index item_index, + std::string_view name) = 0; + virtual Result EndExportSection() = 0; + + /* Start section */ + virtual Result BeginStartSection(Offset size) = 0; + virtual Result OnStartFunction(Index func_index) = 0; + virtual Result EndStartSection() = 0; + + /* Code section */ + virtual Result BeginCodeSection(Offset size) = 0; + virtual Result OnFunctionBodyCount(Index count) = 0; + virtual Result BeginFunctionBody(Index index, Offset size) = 0; + virtual Result OnLocalDeclCount(Index count) = 0; + virtual Result OnLocalDecl(Index decl_index, Index count, Type type) = 0; + + /* Function expressions; called between BeginFunctionBody and + EndFunctionBody */ + virtual Result OnOpcode(Opcode Opcode) = 0; + virtual Result OnOpcodeBare() = 0; + virtual Result OnOpcodeUint32(uint32_t value) = 0; + virtual Result OnOpcodeIndex(Index value) = 0; + virtual Result OnOpcodeIndexIndex(Index value, Index value2) = 0; + virtual Result OnOpcodeUint32Uint32(uint32_t value, uint32_t value2) = 0; + virtual Result OnOpcodeUint32Uint32Uint32(uint32_t value, + uint32_t value2, + uint32_t value3) = 0; + virtual Result OnOpcodeUint32Uint32Uint32Uint32(uint32_t value, + uint32_t value2, + uint32_t value3, + uint32_t value4) = 0; + virtual Result OnOpcodeUint64(uint64_t value) = 0; + virtual Result OnOpcodeF32(uint32_t value) = 0; + virtual Result OnOpcodeF64(uint64_t value) = 0; + virtual Result OnOpcodeV128(v128 value) = 0; + virtual Result OnOpcodeBlockSig(Type sig_type) = 0; + virtual Result OnOpcodeType(Type type) = 0; + virtual Result OnAtomicLoadExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset) = 0; + virtual Result OnAtomicStoreExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset) = 0; + virtual Result OnAtomicRmwExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset) = 0; + virtual Result OnAtomicRmwCmpxchgExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset) = 0; + virtual Result OnAtomicWaitExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset) = 0; + virtual Result OnAtomicFenceExpr(uint32_t consistency_model) = 0; + virtual Result OnAtomicNotifyExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset) = 0; + virtual Result OnBinaryExpr(Opcode opcode) = 0; + virtual Result OnBlockExpr(Type sig_type) = 0; + virtual Result OnBrExpr(Index depth) = 0; + virtual Result OnBrIfExpr(Index depth) = 0; + virtual Result OnBrTableExpr(Index num_targets, + Index* target_depths, + Index default_target_depth) = 0; + virtual Result OnCallExpr(Index func_index) = 0; + virtual Result OnCallIndirectExpr(Index sig_index, Index table_index) = 0; + virtual Result OnCallRefExpr() = 0; + virtual Result OnCatchExpr(Index tag_index) = 0; + virtual Result OnCatchAllExpr() = 0; + virtual Result OnCompareExpr(Opcode opcode) = 0; + virtual Result OnConvertExpr(Opcode opcode) = 0; + virtual Result OnDelegateExpr(Index depth) = 0; + virtual Result OnDropExpr() = 0; + virtual Result OnElseExpr() = 0; + virtual Result OnEndExpr() = 0; + virtual Result OnF32ConstExpr(uint32_t value_bits) = 0; + virtual Result OnF64ConstExpr(uint64_t value_bits) = 0; + virtual Result OnV128ConstExpr(v128 value_bits) = 0; + virtual Result OnGlobalGetExpr(Index global_index) = 0; + virtual Result OnGlobalSetExpr(Index global_index) = 0; + virtual Result OnI32ConstExpr(uint32_t value) = 0; + virtual Result OnI64ConstExpr(uint64_t value) = 0; + virtual Result OnIfExpr(Type sig_type) = 0; + virtual Result OnLoadExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset) = 0; + virtual Result OnLocalGetExpr(Index local_index) = 0; + virtual Result OnLocalSetExpr(Index local_index) = 0; + virtual Result OnLocalTeeExpr(Index local_index) = 0; + virtual Result OnLoopExpr(Type sig_type) = 0; + virtual Result OnMemoryCopyExpr(Index srcmemidx, Index destmemidx) = 0; + virtual Result OnDataDropExpr(Index segment_index) = 0; + virtual Result OnMemoryFillExpr(Index memidx) = 0; + virtual Result OnMemoryGrowExpr(Index memidx) = 0; + virtual Result OnMemoryInitExpr(Index segment_index, Index memidx) = 0; + virtual Result OnMemorySizeExpr(Index memidx) = 0; + virtual Result OnTableCopyExpr(Index dst_index, Index src_index) = 0; + virtual Result OnElemDropExpr(Index segment_index) = 0; + virtual Result OnTableInitExpr(Index segment_index, Index table_index) = 0; + virtual Result OnTableGetExpr(Index table_index) = 0; + virtual Result OnTableSetExpr(Index table_index) = 0; + virtual Result OnTableGrowExpr(Index table_index) = 0; + virtual Result OnTableSizeExpr(Index table_index) = 0; + virtual Result OnTableFillExpr(Index table_index) = 0; + virtual Result OnRefFuncExpr(Index func_index) = 0; + virtual Result OnRefNullExpr(Type type) = 0; + virtual Result OnRefIsNullExpr() = 0; + virtual Result OnNopExpr() = 0; + virtual Result OnRethrowExpr(Index depth) = 0; + virtual Result OnReturnExpr() = 0; + virtual Result OnReturnCallExpr(Index func_index) = 0; + virtual Result OnReturnCallIndirectExpr(Index sig_index, + Index table_index) = 0; + virtual Result OnSelectExpr(Index result_count, Type* result_types) = 0; + virtual Result OnStoreExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset) = 0; + virtual Result OnThrowExpr(Index tag_index) = 0; + virtual Result OnTryExpr(Type sig_type) = 0; + + virtual Result OnUnaryExpr(Opcode opcode) = 0; + virtual Result OnTernaryExpr(Opcode opcode) = 0; + virtual Result OnUnreachableExpr() = 0; + virtual Result EndFunctionBody(Index index) = 0; + virtual Result EndCodeSection() = 0; + + /* Simd instructions with Lane Imm operand*/ + virtual Result OnSimdLaneOpExpr(Opcode opcode, uint64_t value) = 0; + virtual Result OnSimdShuffleOpExpr(Opcode opcode, v128 value) = 0; + virtual Result OnSimdLoadLaneExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset, + uint64_t value) = 0; + virtual Result OnSimdStoreLaneExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset, + uint64_t value) = 0; + + virtual Result OnLoadSplatExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset) = 0; + virtual Result OnLoadZeroExpr(Opcode opcode, + Index memidx, + Address alignment_log2, + Address offset) = 0; + + /* Elem section */ + virtual Result BeginElemSection(Offset size) = 0; + virtual Result OnElemSegmentCount(Index count) = 0; + virtual Result BeginElemSegment(Index index, + Index table_index, + uint8_t flags) = 0; + virtual Result BeginElemSegmentInitExpr(Index index) = 0; + virtual Result EndElemSegmentInitExpr(Index index) = 0; + virtual Result OnElemSegmentElemType(Index index, Type elem_type) = 0; + virtual Result OnElemSegmentElemExprCount(Index index, Index count) = 0; + virtual Result OnElemSegmentElemExpr_RefNull(Index segment_index, + Type type) = 0; + virtual Result OnElemSegmentElemExpr_RefFunc(Index segment_index, + Index func_index) = 0; + virtual Result EndElemSegment(Index index) = 0; + virtual Result EndElemSection() = 0; + + /* Data section */ + virtual Result BeginDataSection(Offset size) = 0; + virtual Result OnDataSegmentCount(Index count) = 0; + virtual Result BeginDataSegment(Index index, + Index memory_index, + uint8_t flags) = 0; + virtual Result BeginDataSegmentInitExpr(Index index) = 0; + virtual Result EndDataSegmentInitExpr(Index index) = 0; + virtual Result OnDataSegmentData(Index index, + const void* data, + Address size) = 0; + virtual Result EndDataSegment(Index index) = 0; + virtual Result EndDataSection() = 0; + + /* DataCount section */ + virtual Result BeginDataCountSection(Offset size) = 0; + virtual Result OnDataCount(Index count) = 0; + virtual Result EndDataCountSection() = 0; + + /* Names section */ + virtual Result BeginNamesSection(Offset size) = 0; + virtual Result OnModuleNameSubsection(Index index, + uint32_t name_type, + Offset subsection_size) = 0; + virtual Result OnModuleName(std::string_view name) = 0; + virtual Result OnFunctionNameSubsection(Index index, + uint32_t name_type, + Offset subsection_size) = 0; + virtual Result OnFunctionNamesCount(Index num_functions) = 0; + virtual Result OnFunctionName(Index function_index, + std::string_view function_name) = 0; + virtual Result OnLocalNameSubsection(Index index, + uint32_t name_type, + Offset subsection_size) = 0; + virtual Result OnLocalNameFunctionCount(Index num_functions) = 0; + virtual Result OnLocalNameLocalCount(Index function_index, + Index num_locals) = 0; + virtual Result OnLocalName(Index function_index, + Index local_index, + std::string_view local_name) = 0; + virtual Result OnNameSubsection(Index index, + NameSectionSubsection subsection_type, + Offset subsection_size) = 0; + virtual Result OnNameCount(Index num_names) = 0; + virtual Result OnNameEntry(NameSectionSubsection type, + Index index, + std::string_view name) = 0; + virtual Result EndNamesSection() = 0; + + /* Reloc section */ + virtual Result BeginRelocSection(Offset size) = 0; + virtual Result OnRelocCount(Index count, Index section_index) = 0; + virtual Result OnReloc(RelocType type, + Offset offset, + Index index, + uint32_t addend) = 0; + virtual Result EndRelocSection() = 0; + + /* Dylink section */ + virtual Result BeginDylinkSection(Offset size) = 0; + virtual Result OnDylinkInfo(uint32_t mem_size, + uint32_t mem_align_log2, + uint32_t table_size, + uint32_t table_align_log2) = 0; + virtual Result OnDylinkImportCount(Index count) = 0; + virtual Result OnDylinkExportCount(Index count) = 0; + virtual Result OnDylinkImport(std::string_view module, + std::string_view name, + uint32_t flags) = 0; + virtual Result OnDylinkExport(std::string_view name, uint32_t flags) = 0; + virtual Result OnDylinkNeededCount(Index count) = 0; + virtual Result OnDylinkNeeded(std::string_view so_name) = 0; + virtual Result EndDylinkSection() = 0; + + /* target_features section */ + virtual Result BeginTargetFeaturesSection(Offset size) = 0; + virtual Result OnFeatureCount(Index count) = 0; + virtual Result OnFeature(uint8_t prefix, std::string_view name) = 0; + virtual Result EndTargetFeaturesSection() = 0; + + /* Linking section */ + virtual Result BeginLinkingSection(Offset size) = 0; + virtual Result OnSymbolCount(Index count) = 0; + virtual Result OnDataSymbol(Index index, + uint32_t flags, + std::string_view name, + Index segment, + uint32_t offset, + uint32_t size) = 0; + virtual Result OnFunctionSymbol(Index index, + uint32_t flags, + std::string_view name, + Index function_index) = 0; + virtual Result OnGlobalSymbol(Index index, + uint32_t flags, + std::string_view name, + Index global_index) = 0; + virtual Result OnSectionSymbol(Index index, + uint32_t flags, + Index section_index) = 0; + virtual Result OnTagSymbol(Index index, + uint32_t flags, + std::string_view name, + Index tag_index) = 0; + virtual Result OnTableSymbol(Index index, + uint32_t flags, + std::string_view name, + Index table_index) = 0; + virtual Result OnSegmentInfoCount(Index count) = 0; + virtual Result OnSegmentInfo(Index index, + std::string_view name, + Address alignment_log2, + uint32_t flags) = 0; + virtual Result OnInitFunctionCount(Index count) = 0; + virtual Result OnInitFunction(uint32_t priority, Index symbol_index) = 0; + virtual Result OnComdatCount(Index count) = 0; + virtual Result OnComdatBegin(std::string_view name, + uint32_t flags, + Index count) = 0; + virtual Result OnComdatEntry(ComdatType kind, Index index) = 0; + virtual Result EndLinkingSection() = 0; + + /* Tag section */ + virtual Result BeginTagSection(Offset size) = 0; + virtual Result OnTagCount(Index count) = 0; + virtual Result OnTagType(Index index, Index sig_index) = 0; + virtual Result EndTagSection() = 0; + + /* Code Metadata sections */ + virtual Result BeginCodeMetadataSection(std::string_view name, + Offset size) = 0; + virtual Result OnCodeMetadataFuncCount(Index count) = 0; + virtual Result OnCodeMetadataCount(Index function_index, Index count) = 0; + virtual Result OnCodeMetadata(Offset offset, + const void* data, + Address size) = 0; + virtual Result EndCodeMetadataSection() = 0; + + const State* state = nullptr; +}; + +Result ReadBinary(const void* data, + size_t size, + BinaryReaderDelegate* reader, + const ReadBinaryOptions& options); + +size_t ReadU32Leb128(const uint8_t* ptr, + const uint8_t* end, + uint32_t* out_value); + +size_t ReadI32Leb128(const uint8_t* ptr, + const uint8_t* end, + uint32_t* out_value); + +} // namespace wabt + +#endif /* WABT_BINARY_READER_H_ */ diff --git a/third_party/wasm2c/include/wabt/binary-writer-spec.h b/third_party/wasm2c/include/wabt/binary-writer-spec.h new file mode 100644 index 0000000000..168c65efdf --- /dev/null +++ b/third_party/wasm2c/include/wabt/binary-writer-spec.h @@ -0,0 +1,60 @@ +/* + * Copyright 2016 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_BINARY_WRITER_SPEC_H_ +#define WABT_BINARY_WRITER_SPEC_H_ + +#include +#include +#include + +#include "wabt/binary-writer.h" +#include "wabt/common.h" +#include "wabt/ir.h" + +namespace wabt { + +struct FilenameMemoryStreamPair { + FilenameMemoryStreamPair(std::string_view filename, + std::unique_ptr stream) + : filename(filename), stream(std::move(stream)) {} + std::string filename; + std::unique_ptr stream; +}; + +using WriteBinarySpecStreamFactory = + std::function; + +Result WriteBinarySpecScript(Stream* json_stream, + WriteBinarySpecStreamFactory module_stream_factory, + Script*, + std::string_view source_filename, + std::string_view module_filename_noext, + const WriteBinaryOptions&); + +// Convenience function for producing MemoryStream outputs all modules. +Result WriteBinarySpecScript( + Stream* json_stream, + Script*, + std::string_view source_filename, + std::string_view module_filename_noext, + const WriteBinaryOptions&, + std::vector* out_module_streams, + Stream* log_stream = nullptr); + +} // namespace wabt + +#endif /* WABT_BINARY_WRITER_SPEC_H_ */ diff --git a/third_party/wasm2c/include/wabt/binary-writer.h b/third_party/wasm2c/include/wabt/binary-writer.h new file mode 100644 index 0000000000..dedba1bdcf --- /dev/null +++ b/third_party/wasm2c/include/wabt/binary-writer.h @@ -0,0 +1,62 @@ +/* + * Copyright 2016 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_BINARY_WRITER_H_ +#define WABT_BINARY_WRITER_H_ + +#include "wabt/common.h" +#include "wabt/feature.h" +#include "wabt/opcode.h" +#include "wabt/stream.h" + +namespace wabt { + +struct Module; +struct Script; + +struct WriteBinaryOptions { + WriteBinaryOptions() = default; + WriteBinaryOptions(const Features& features, + bool canonicalize_lebs, + bool relocatable, + bool write_debug_names) + : features(features), + canonicalize_lebs(canonicalize_lebs), + relocatable(relocatable), + write_debug_names(write_debug_names) {} + + Features features; + bool canonicalize_lebs = true; + bool relocatable = false; + bool write_debug_names = false; +}; + +Result WriteBinaryModule(Stream*, const Module*, const WriteBinaryOptions&); + +void WriteType(Stream* stream, Type type, const char* desc = nullptr); + +void WriteStr(Stream* stream, + std::string_view s, + const char* desc, + PrintChars print_chars = PrintChars::No); + +void WriteOpcode(Stream* stream, Opcode opcode); + +void WriteLimits(Stream* stream, const Limits* limits); + +} // namespace wabt + +#endif /* WABT_BINARY_WRITER_H_ */ diff --git a/third_party/wasm2c/include/wabt/binary.h b/third_party/wasm2c/include/wabt/binary.h new file mode 100644 index 0000000000..485f15cbd3 --- /dev/null +++ b/third_party/wasm2c/include/wabt/binary.h @@ -0,0 +1,106 @@ +/* + * Copyright 2016 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_BINARY_H_ +#define WABT_BINARY_H_ + +#include "wabt/common.h" + +#define WABT_BINARY_MAGIC 0x6d736100 +#define WABT_BINARY_VERSION 1 +#define WABT_BINARY_LIMITS_HAS_MAX_FLAG 0x1 +#define WABT_BINARY_LIMITS_IS_SHARED_FLAG 0x2 +#define WABT_BINARY_LIMITS_IS_64_FLAG 0x4 +#define WABT_BINARY_LIMITS_ALL_FLAGS \ + (WABT_BINARY_LIMITS_HAS_MAX_FLAG | WABT_BINARY_LIMITS_IS_SHARED_FLAG | \ + WABT_BINARY_LIMITS_IS_64_FLAG) + +#define WABT_BINARY_SECTION_NAME "name" +#define WABT_BINARY_SECTION_RELOC "reloc" +#define WABT_BINARY_SECTION_LINKING "linking" +#define WABT_BINARY_SECTION_TARGET_FEATURES "target_features" +#define WABT_BINARY_SECTION_DYLINK "dylink" +#define WABT_BINARY_SECTION_DYLINK0 "dylink.0" +#define WABT_BINARY_SECTION_CODE_METADATA "metadata.code." + +#define WABT_FOREACH_BINARY_SECTION(V) \ + V(Custom, custom, 0) \ + V(Type, type, 1) \ + V(Import, import, 2) \ + V(Function, function, 3) \ + V(Table, table, 4) \ + V(Memory, memory, 5) \ + V(Tag, tag, 13) \ + V(Global, global, 6) \ + V(Export, export, 7) \ + V(Start, start, 8) \ + V(Elem, elem, 9) \ + V(DataCount, data_count, 12) \ + V(Code, code, 10) \ + V(Data, data, 11) + +namespace wabt { + +/* clang-format off */ +enum class BinarySection { +#define V(Name, name, code) Name = code, + WABT_FOREACH_BINARY_SECTION(V) +#undef V + Invalid = ~0, + + First = Custom, + Last = Tag, +}; +/* clang-format on */ +constexpr int kBinarySectionCount = WABT_ENUM_COUNT(BinarySection); + +enum class BinarySectionOrder { +#define V(Name, name, code) Name, + WABT_FOREACH_BINARY_SECTION(V) +#undef V +}; + +BinarySectionOrder GetSectionOrder(BinarySection); +const char* GetSectionName(BinarySection); + +// See +// https://github.com/WebAssembly/extended-name-section/blob/main/proposals/extended-name-section/Overview.md +enum class NameSectionSubsection { + Module = 0, + Function = 1, + Local = 2, + Label = 3, + Type = 4, + Table = 5, + Memory = 6, + Global = 7, + ElemSegment = 8, + DataSegment = 9, + // tag names are yet part of the extended-name-section proposal (because it + // only deals with naming things that are in the spec already). However, we + // include names for Tags in wabt using this enum value on the basis that tags + // can only exist when exceptions are enabled and that engines should ignore + // unknown name types. + Tag = 10, + + First = Module, + Last = Tag, +}; +const char* GetNameSectionSubsectionName(NameSectionSubsection subsec); + +} // namespace wabt + +#endif /* WABT_BINARY_H_ */ diff --git a/third_party/wasm2c/include/wabt/binding-hash.h b/third_party/wasm2c/include/wabt/binding-hash.h new file mode 100644 index 0000000000..5d43cd7202 --- /dev/null +++ b/third_party/wasm2c/include/wabt/binding-hash.h @@ -0,0 +1,72 @@ +/* + * Copyright 2016 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_BINDING_HASH_H_ +#define WABT_BINDING_HASH_H_ + +#include +#include +#include +#include +#include + +#include "wabt/common.h" + +namespace wabt { + +struct Var; + +struct Binding { + explicit Binding(Index index) : index(index) {} + Binding(const Location& loc, Index index) : loc(loc), index(index) {} + + Location loc; + Index index; +}; + +// This class derives from a C++ container, which is usually not advisable +// because they don't have virtual destructors. So don't delete a BindingHash +// object through a pointer to std::unordered_multimap. +class BindingHash : public std::unordered_multimap { + public: + using DuplicateCallback = + std::function; + + void FindDuplicates(DuplicateCallback callback) const; + + Index FindIndex(const Var&) const; + + Index FindIndex(const std::string& name) const { + auto iter = find(name); + return iter != end() ? iter->second.index : kInvalidIndex; + } + + Index FindIndex(std::string_view name) const { + return FindIndex(std::string(name)); + } + + private: + using ValueTypeVector = std::vector; + + void CreateDuplicatesVector(ValueTypeVector* out_duplicates) const; + void SortDuplicatesVectorByLocation(ValueTypeVector* duplicates) const; + void CallCallbacks(const ValueTypeVector& duplicates, + DuplicateCallback callback) const; +}; + +} // namespace wabt + +#endif /* WABT_BINDING_HASH_H_ */ diff --git a/third_party/wasm2c/include/wabt/c-writer.h b/third_party/wasm2c/include/wabt/c-writer.h new file mode 100644 index 0000000000..7d9ff6ad74 --- /dev/null +++ b/third_party/wasm2c/include/wabt/c-writer.h @@ -0,0 +1,59 @@ +/* + * Copyright 2017 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_C_WRITER_H_ +#define WABT_C_WRITER_H_ + +#include +#include "wabt/common.h" +#include "wabt/feature.h" +#include "wabt/ir.h" + +namespace wabt { + +struct Module; +class Stream; + +struct WriteCOptions { + std::string_view module_name; + /* Set of wasm features enabled for wasm2c */ + Features* features; + /* + * name_to_output_file_index takes const iterators to begin and end of a list + * of all functions in the module, number of imported functions, and number of + * .c outputs as argument, returns a vector where vector[i] the index of the + * .c output that funcs_begin + i goes into. Only called when --num-outputs is + * used. + */ + std::function( + std::vector::const_iterator funcs_begin, + std::vector::const_iterator funcs_end, + size_t num_imported_functions, + size_t num_outputs)> + name_to_output_file_index; +}; + +Result WriteC(std::vector&& c_streams, + Stream* h_stream, + Stream* h_impl_stream, + const char* header_name, + const char* header_impl_name, + const Module*, + const WriteCOptions&); + +} // namespace wabt + +#endif /* WABT_C_WRITER_H_ */ diff --git a/third_party/wasm2c/include/wabt/cast.h b/third_party/wasm2c/include/wabt/cast.h new file mode 100644 index 0000000000..f089e2f18e --- /dev/null +++ b/third_party/wasm2c/include/wabt/cast.h @@ -0,0 +1,109 @@ +/* + * Copyright 2017 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_CAST_H_ +#define WABT_CAST_H_ + +#include +#include + +#include "wabt/common.h" + +// Modeled after LLVM's dynamic casts: +// http://llvm.org/docs/ProgrammersManual.html#the-isa-cast-and-dyn-cast-templates +// +// Use isa(foo) to check whether foo is a T*: +// +// if (isa(car)) { +// ... +// } +// +// Use cast(foo) when you know that foo is a T* -- it will assert that the +// type matches: +// +// switch (car.type) { +// case CarType::Minivan: { +// auto minivan = cast(car); +// ... +// } +// } +// +// Use dyn_cast(foo) as a combination if isa and cast, it will return +// nullptr if the type doesn't match: +// +// if (auto minivan = dyn_cast(car)) { +// ... +// } +// +// +// To use these classes in a type hierarchy, you must implement classof: +// +// enum CarType { Minivan, ... }; +// struct Car { CarType type; ... }; +// struct Minivan : Car { +// static bool classof(const Car* car) { return car->type == Minivan; } +// ... +// }; +// + +namespace wabt { + +template +bool isa(const Base* base) { + WABT_STATIC_ASSERT((std::is_base_of::value)); + return Derived::classof(base); +} + +template +const Derived* cast(const Base* base) { + assert(isa(base)); + return static_cast(base); +}; + +template +Derived* cast(Base* base) { + assert(isa(base)); + return static_cast(base); +}; + +template +const Derived* dyn_cast(const Base* base) { + return isa(base) ? static_cast(base) : nullptr; +}; + +template +Derived* dyn_cast(Base* base) { + return isa(base) ? static_cast(base) : nullptr; +}; + +// Cast functionality for unique_ptr. isa and dyn_cast are not included because +// they won't always pass ownership back to the caller. + +template +std::unique_ptr cast(std::unique_ptr&& base) { + assert(isa(base.get())); + return std::unique_ptr(static_cast(base.release())); +}; + +template +std::unique_ptr cast(std::unique_ptr&& base) { + assert(isa(base.get())); + return std::unique_ptr(static_cast(base.release())); +}; + +} // namespace wabt + +#endif // WABT_CAST_H_ diff --git a/third_party/wasm2c/include/wabt/circular-array.h b/third_party/wasm2c/include/wabt/circular-array.h new file mode 100644 index 0000000000..9e2d38004b --- /dev/null +++ b/third_party/wasm2c/include/wabt/circular-array.h @@ -0,0 +1,123 @@ +/* + * Copyright 2017 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_CIRCULAR_ARRAY_H_ +#define WABT_CIRCULAR_ARRAY_H_ + +#include +#include +#include +#include + +namespace wabt { + +// TODO(karlschimpf) Complete the API +// Note: Capacity must be a power of 2. +template +class CircularArray { + public: + using value_type = T; + using reference = value_type&; + using const_reference = const value_type&; + using size_type = size_t; + using difference_type = ptrdiff_t; + + CircularArray() { + static_assert(kCapacity && ((kCapacity & (kCapacity - 1)) == 0), + "Capacity must be a power of 2."); + } + + CircularArray(const CircularArray&) = default; + CircularArray& operator=(const CircularArray&) = default; + + CircularArray(CircularArray&&) = default; + CircularArray& operator=(CircularArray&&) = default; + + ~CircularArray() { clear(); } + + reference at(size_type index) { + assert(index < size_); + return (*this)[index]; + } + + const_reference at(size_type index) const { + assert(index < size_); + return (*this)[index]; + } + + reference operator[](size_type index) { return contents_[position(index)]; } + + const_reference operator[](size_type index) const { + return contents_[position(index)]; + } + + reference back() { return at(size_ - 1); } + + const_reference back() const { return at(size_ - 1); } + + bool empty() const { return size_ == 0; } + + reference front() { return at(0); } + + const_reference front() const { return at(0); } + + size_type max_size() const { return kCapacity; } + + void pop_back() { + assert(size_ > 0); + SetElement(back()); + --size_; + } + + void pop_front() { + assert(size_ > 0); + SetElement(front()); + front_ = (front_ + 1) & kMask; + --size_; + } + + void push_back(const value_type& value) { + assert(size_ < kCapacity); + SetElement(at(size_++), value); + } + + size_type size() const { return size_; } + + void clear() { + while (!empty()) { + pop_back(); + } + } + + private: + static constexpr size_type kMask = kCapacity - 1; + + size_t position(size_t index) const { return (front_ + index) & kMask; } + + template + void SetElement(reference element, Args&&... args) { + element.~T(); + new (&element) T(std::forward(args)...); + } + + std::array contents_; + size_type size_ = 0; + size_type front_ = 0; +}; + +} // namespace wabt + +#endif // WABT_CIRCULAR_ARRAY_H_ diff --git a/third_party/wasm2c/include/wabt/color.h b/third_party/wasm2c/include/wabt/color.h new file mode 100644 index 0000000000..8af57f33f7 --- /dev/null +++ b/third_party/wasm2c/include/wabt/color.h @@ -0,0 +1,72 @@ +/* + * Copyright 2017 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_COLOR_H_ +#define WABT_COLOR_H_ + +#include + +namespace wabt { + +#define WABT_FOREACH_COLOR_CODE(V) \ + V(Default, "\x1b[0m") \ + V(Bold, "\x1b[1m") \ + V(NoBold, "\x1b[22m") \ + V(Black, "\x1b[30m") \ + V(Red, "\x1b[31m") \ + V(Green, "\x1b[32m") \ + V(Yellow, "\x1b[33m") \ + V(Blue, "\x1b[34m") \ + V(Magenta, "\x1b[35m") \ + V(Cyan, "\x1b[36m") \ + V(White, "\x1b[37m") + +class Color { + public: + Color() : file_(nullptr), enabled_(false) {} + Color(FILE*, bool enabled = true); + +// Write the given color to the file, if enabled. +#define WABT_COLOR(Name, code) \ + void Name() const { WriteCode(Name##Code()); } + WABT_FOREACH_COLOR_CODE(WABT_COLOR) +#undef WABT_COLOR + +// Get the color code as a string, if enabled. +#define WABT_COLOR(Name, code) \ + const char* Maybe##Name##Code() const { return enabled_ ? Name##Code() : ""; } + WABT_FOREACH_COLOR_CODE(WABT_COLOR) +#undef WABT_COLOR + +// Get the color code as a string. +#define WABT_COLOR(Name, code) \ + static const char* Name##Code() { return code; } + WABT_FOREACH_COLOR_CODE(WABT_COLOR) +#undef WABT_COLOR + + private: + static bool SupportsColor(FILE*); + void WriteCode(const char*) const; + + FILE* file_; + bool enabled_; +}; + +#undef WABT_FOREACH_COLOR_CODE + +} // namespace wabt + +#endif // WABT_COLOR_H_ diff --git a/third_party/wasm2c/include/wabt/common.h b/third_party/wasm2c/include/wabt/common.h new file mode 100644 index 0000000000..2ae1fa1fe9 --- /dev/null +++ b/third_party/wasm2c/include/wabt/common.h @@ -0,0 +1,456 @@ +/* + * Copyright 2016 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_COMMON_H_ +#define WABT_COMMON_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wabt/config.h" + +#include "wabt/base-types.h" +#include "wabt/result.h" +#include "wabt/string-format.h" +#include "wabt/type.h" + +#define WABT_FATAL(...) fprintf(stderr, __VA_ARGS__), exit(1) +#define WABT_ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) + +#define WABT_USE(x) static_cast(x) + +// 64k +#define WABT_PAGE_SIZE 0x10000 +// # of pages that fit in 32-bit address space +#define WABT_MAX_PAGES32 0x10000 +// # of pages that fit in 64-bit address space +#define WABT_MAX_PAGES64 0x1000000000000 +#define WABT_BYTES_TO_PAGES(x) ((x) >> 16) +#define WABT_ALIGN_UP_TO_PAGE(x) \ + (((x) + WABT_PAGE_SIZE - 1) & ~(WABT_PAGE_SIZE - 1)) + +#define WABT_ENUM_COUNT(name) \ + (static_cast(name::Last) - static_cast(name::First) + 1) + +#define WABT_DISALLOW_COPY_AND_ASSIGN(type) \ + type(const type&) = delete; \ + type& operator=(const type&) = delete; + +#if WITH_EXCEPTIONS +#define WABT_TRY try { +#define WABT_CATCH_BAD_ALLOC \ + } \ + catch (std::bad_alloc&) { \ + } +#define WABT_CATCH_BAD_ALLOC_AND_EXIT \ + } \ + catch (std::bad_alloc&) { \ + WABT_FATAL("Memory allocation failure.\n"); \ + } +#else +#define WABT_TRY +#define WABT_CATCH_BAD_ALLOC +#define WABT_CATCH_BAD_ALLOC_AND_EXIT +#endif + +#define PRIindex "u" +#define PRIaddress PRIu64 +#define PRIoffset PRIzx + +namespace wabt { +inline void MemcpyEndianAware(void* dst, + const void* src, + size_t dsize, + size_t ssize, + size_t doff, + size_t soff, + size_t len) { +#if WABT_BIG_ENDIAN + memcpy(static_cast(dst) + (dsize) - (len) - (doff), + static_cast(src) + (ssize) - (len) - (soff), (len)); +#else + memcpy(static_cast(dst) + (doff), + static_cast(src) + (soff), (len)); +#endif +} +} + +struct v128 { + v128() = default; + v128(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3) { + set_u32(0, x0); + set_u32(1, x1); + set_u32(2, x2); + set_u32(3, x3); + } + + bool operator==(const v128& other) const { + return std::equal(std::begin(v), std::end(v), std::begin(other.v)); + } + bool operator!=(const v128& other) const { return !(*this == other); } + + uint8_t u8(int lane) const { return To(lane); } + uint16_t u16(int lane) const { return To(lane); } + uint32_t u32(int lane) const { return To(lane); } + uint64_t u64(int lane) const { return To(lane); } + uint32_t f32_bits(int lane) const { return To(lane); } + uint64_t f64_bits(int lane) const { return To(lane); } + + void set_u8(int lane, uint8_t x) { return From(lane, x); } + void set_u16(int lane, uint16_t x) { return From(lane, x); } + void set_u32(int lane, uint32_t x) { return From(lane, x); } + void set_u64(int lane, uint64_t x) { return From(lane, x); } + void set_f32_bits(int lane, uint32_t x) { return From(lane, x); } + void set_f64_bits(int lane, uint64_t x) { return From(lane, x); } + + bool is_zero() const { + return std::all_of(std::begin(v), std::end(v), + [](uint8_t x) { return x == 0; }); + } + void set_zero() { std::fill(std::begin(v), std::end(v), 0); } + + template + T To(int lane) const { + static_assert(sizeof(T) <= sizeof(v), "Invalid cast!"); + assert((lane + 1) * sizeof(T) <= sizeof(v)); + T result; + wabt::MemcpyEndianAware(&result, v, sizeof(result), sizeof(v), 0, + lane * sizeof(T), sizeof(result)); + return result; + } + + template + void From(int lane, T data) { + static_assert(sizeof(T) <= sizeof(v), "Invalid cast!"); + assert((lane + 1) * sizeof(T) <= sizeof(v)); + wabt::MemcpyEndianAware(v, &data, sizeof(v), sizeof(data), lane * sizeof(T), + 0, sizeof(data)); + } + + uint8_t v[16]; +}; + +namespace wabt { + +template +Dst WABT_VECTORCALL Bitcast(Src&& value) { + static_assert(sizeof(Src) == sizeof(Dst), "Bitcast sizes must match."); + Dst result; + memcpy(&result, &value, sizeof(result)); + return result; +} + +template +void ZeroMemory(T& v) { + WABT_STATIC_ASSERT(std::is_pod::value); + memset(&v, 0, sizeof(v)); +} + +// Placement construct +template +void Construct(T& placement, Args&&... args) { + new (&placement) T(std::forward(args)...); +} + +// Placement destruct +template +void Destruct(T& placement) { + placement.~T(); +} + +enum class LabelType { + Func, + InitExpr, + Block, + Loop, + If, + Else, + Try, + Catch, + + First = Func, + Last = Catch, +}; +constexpr int kLabelTypeCount = WABT_ENUM_COUNT(LabelType); + +struct Location { + enum class Type { + Text, + Binary, + }; + + Location() : line(0), first_column(0), last_column(0) {} + Location(std::string_view filename, + int line, + int first_column, + int last_column) + : filename(filename), + line(line), + first_column(first_column), + last_column(last_column) {} + explicit Location(size_t offset) : offset(offset) {} + + std::string_view filename; + union { + // For text files. + struct { + int line; + int first_column; + int last_column; + }; + // For binary files. + struct { + size_t offset; + }; + }; +}; + +enum class SegmentKind { + Active, + Passive, + Declared, +}; + +// Used in test asserts for special expected values "nan:canonical" and +// "nan:arithmetic" +enum class ExpectedNan { + None, + Canonical, + Arithmetic, +}; + +// Matches binary format, do not change. +enum SegmentFlags : uint8_t { + SegFlagsNone = 0, + SegPassive = 1, // bit 0: Is passive + SegExplicitIndex = 2, // bit 1: Has explict index (Implies table 0 if absent) + SegDeclared = 3, // Only used for declared segments + SegUseElemExprs = 4, // bit 2: Is elemexpr (Or else index sequence) + + SegFlagMax = (SegUseElemExprs << 1) - 1, // All bits set. +}; + +enum class RelocType { + FuncIndexLEB = 0, // e.g. Immediate of call instruction + TableIndexSLEB = 1, // e.g. Loading address of function + TableIndexI32 = 2, // e.g. Function address in DATA + MemoryAddressLEB = 3, // e.g. Memory address in load/store offset immediate + MemoryAddressSLEB = 4, // e.g. Memory address in i32.const + MemoryAddressI32 = 5, // e.g. Memory address in DATA + TypeIndexLEB = 6, // e.g. Immediate type in call_indirect + GlobalIndexLEB = 7, // e.g. Immediate of global.get inst + FunctionOffsetI32 = 8, // e.g. Code offset in DWARF metadata + SectionOffsetI32 = 9, // e.g. Section offset in DWARF metadata + TagIndexLEB = 10, // Used in throw instructions + MemoryAddressRelSLEB = 11, // In PIC code, addr relative to __memory_base + TableIndexRelSLEB = 12, // In PIC code, table index relative to __table_base + GlobalIndexI32 = 13, // e.g. Global index in data (e.g. DWARF) + MemoryAddressLEB64 = 14, // Memory64: Like MemoryAddressLEB + MemoryAddressSLEB64 = 15, // Memory64: Like MemoryAddressSLEB + MemoryAddressI64 = 16, // Memory64: Like MemoryAddressI32 + MemoryAddressRelSLEB64 = 17, // Memory64: Like MemoryAddressRelSLEB + TableIndexSLEB64 = 18, // Memory64: Like TableIndexSLEB + TableIndexI64 = 19, // Memory64: Like TableIndexI32 + TableNumberLEB = 20, // e.g. Immediate of table.get + MemoryAddressTLSSLEB = 21, // Address relative to __tls_base + MemoryAddressTLSI32 = 22, // Address relative to __tls_base + + First = FuncIndexLEB, + Last = MemoryAddressTLSI32, +}; +constexpr int kRelocTypeCount = WABT_ENUM_COUNT(RelocType); + +struct Reloc { + Reloc(RelocType, size_t offset, Index index, int32_t addend = 0); + + RelocType type; + size_t offset; + Index index; + int32_t addend; +}; + +enum class LinkingEntryType { + SegmentInfo = 5, + InitFunctions = 6, + ComdatInfo = 7, + SymbolTable = 8, +}; + +enum class DylinkEntryType { + MemInfo = 1, + Needed = 2, + ExportInfo = 3, + ImportInfo = 4, +}; + +enum class SymbolType { + Function = 0, + Data = 1, + Global = 2, + Section = 3, + Tag = 4, + Table = 5, +}; + +enum class ComdatType { + Data = 0x0, + Function = 0x1, +}; + +#define WABT_SYMBOL_MASK_VISIBILITY 0x4 +#define WABT_SYMBOL_MASK_BINDING 0x3 +#define WABT_SYMBOL_FLAG_UNDEFINED 0x10 +#define WABT_SYMBOL_FLAG_EXPORTED 0x20 +#define WABT_SYMBOL_FLAG_EXPLICIT_NAME 0x40 +#define WABT_SYMBOL_FLAG_NO_STRIP 0x80 +#define WABT_SYMBOL_FLAG_TLS 0x100 +#define WABT_SYMBOL_FLAG_MAX 0x1ff + +#define WABT_SEGMENT_FLAG_STRINGS 0x1 +#define WABT_SEGMENT_FLAG_TLS 0x2 +#define WABT_SEGMENT_FLAG_MAX 0xff + +enum class SymbolVisibility { + Default = 0, + Hidden = 4, +}; + +enum class SymbolBinding { + Global = 0, + Weak = 1, + Local = 2, +}; + +/* matches binary format, do not change */ +enum class ExternalKind { + Func = 0, + Table = 1, + Memory = 2, + Global = 3, + Tag = 4, + + First = Func, + Last = Tag, +}; +constexpr int kExternalKindCount = WABT_ENUM_COUNT(ExternalKind); + +struct Limits { + Limits() = default; + explicit Limits(uint64_t initial) : initial(initial) {} + Limits(uint64_t initial, uint64_t max) + : initial(initial), max(max), has_max(true) {} + Limits(uint64_t initial, uint64_t max, bool is_shared) + : initial(initial), max(max), has_max(true), is_shared(is_shared) {} + Limits(uint64_t initial, uint64_t max, bool is_shared, bool is_64) + : initial(initial), + max(max), + has_max(true), + is_shared(is_shared), + is_64(is_64) {} + Type IndexType() const { return is_64 ? Type::I64 : Type::I32; } + + uint64_t initial = 0; + uint64_t max = 0; + bool has_max = false; + bool is_shared = false; + bool is_64 = false; +}; + +enum { WABT_USE_NATURAL_ALIGNMENT = 0xFFFFFFFFFFFFFFFF }; + +Result ReadFile(std::string_view filename, std::vector* out_data); + +void InitStdio(); + +/* external kind */ + +extern const char* g_kind_name[]; + +static inline const char* GetKindName(ExternalKind kind) { + return static_cast(kind) < kExternalKindCount + ? g_kind_name[static_cast(kind)] + : ""; +} + +/* reloc */ + +extern const char* g_reloc_type_name[]; + +static inline const char* GetRelocTypeName(RelocType reloc) { + return static_cast(reloc) < kRelocTypeCount + ? g_reloc_type_name[static_cast(reloc)] + : ""; +} + +/* symbol */ + +static inline const char* GetSymbolTypeName(SymbolType type) { + switch (type) { + case SymbolType::Function: + return "func"; + case SymbolType::Global: + return "global"; + case SymbolType::Data: + return "data"; + case SymbolType::Section: + return "section"; + case SymbolType::Tag: + return "tag"; + case SymbolType::Table: + return "table"; + default: + return ""; + } +} + +template +void ConvertBackslashToSlash(T begin, T end) { + std::replace(begin, end, '\\', '/'); +} + +inline void ConvertBackslashToSlash(char* s, size_t length) { + ConvertBackslashToSlash(s, s + length); +} + +inline void ConvertBackslashToSlash(char* s) { + ConvertBackslashToSlash(s, strlen(s)); +} + +inline void ConvertBackslashToSlash(std::string* s) { + ConvertBackslashToSlash(s->begin(), s->end()); +} + +inline void SwapBytesSized(void* addr, size_t size) { + auto bytes = static_cast(addr); + for (size_t i = 0; i < size / 2; i++) { + std::swap(bytes[i], bytes[size - 1 - i]); + } +} + +} // namespace wabt + +#endif // WABT_COMMON_H_ diff --git a/third_party/wasm2c/include/wabt/decompiler-ast.h b/third_party/wasm2c/include/wabt/decompiler-ast.h new file mode 100644 index 0000000000..33cc26c113 --- /dev/null +++ b/third_party/wasm2c/include/wabt/decompiler-ast.h @@ -0,0 +1,406 @@ +/* + * Copyright 2016 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_DECOMPILER_AST_H_ +#define WABT_DECOMPILER_AST_H_ + +#include "wabt/cast.h" +#include "wabt/generate-names.h" +#include "wabt/ir-util.h" +#include "wabt/ir.h" + +#include + +namespace wabt { + +enum class NodeType { + Uninitialized, + FlushToVars, + FlushedVar, + Statements, + EndReturn, + Decl, + DeclInit, + Expr +}; + +// The AST we're going to convert the standard IR into. +struct Node { + NodeType ntype; + ExprType etype; // Only if ntype == Expr. + const Expr* e; + std::vector children; + // Node specific annotations. + union { + struct { + Index var_start, var_count; // FlushedVar/FlushToVars + }; + const Var* var; // Decl/DeclInit. + LabelType lt; // br/br_if target. + } u; + + Node() : ntype(NodeType::Uninitialized), etype(ExprType::Nop), e(nullptr) {} + Node(NodeType ntype, ExprType etype, const Expr* e, const Var* v) + : ntype(ntype), etype(etype), e(e) { + u.var = v; + } + + // This value should really never be copied, only moved. + Node(const Node& rhs) = delete; + Node& operator=(const Node& rhs) = delete; + + Node(Node&& rhs) { *this = std::move(rhs); } + Node& operator=(Node&& rhs) { + ntype = rhs.ntype; + // Reset ntype to avoid moved from values still being used. + rhs.ntype = NodeType::Uninitialized; + etype = rhs.etype; + rhs.etype = ExprType::Nop; + e = rhs.e; + std::swap(children, rhs.children); + u = rhs.u; + return *this; + } +}; + +struct AST { + AST(ModuleContext& mc, const Func* f) : mc(mc), f(f) { + if (f) { + mc.BeginFunc(*f); + for (Index i = 0; i < f->GetNumParams(); i++) { + auto name = "$" + IndexToAlphaName(i); + vars_defined.insert({name, {0, false}}); + } + } + } + + ~AST() { + if (f) { + mc.EndFunc(); + } + } + + // Create a new node, take nargs existing nodes on the exp stack as children. + Node& InsertNode(NodeType ntype, ExprType etype, const Expr* e, Index nargs) { + assert(exp_stack.size() >= nargs); + Node n{ntype, etype, e, nullptr}; + n.children.reserve(nargs); + std::move(exp_stack.end() - nargs, exp_stack.end(), + std::back_inserter(n.children)); + exp_stack.erase(exp_stack.end() - nargs, exp_stack.end()); + exp_stack.push_back(std::move(n)); + return exp_stack.back(); + } + + template + void PreDecl(const VarExpr& ve) { + // FIXME: this is slow, and would be better to avoid in callers. + // See https://github.com/WebAssembly/wabt/issues/1565 + // And https://github.com/WebAssembly/wabt/issues/1665 + for (auto& n : predecls) { + if (n.u.var->name() == ve.var.name()) { + return; + } + } + predecls.emplace_back(NodeType::Decl, ExprType::Nop, nullptr, &ve.var); + } + + template + void Get(const VarExpr& ve, bool local) { + if (local) { + auto ret = vars_defined.insert({ve.var.name(), {cur_block_id, false}}); + if (ret.second) { + // Use before def, may happen since locals are guaranteed 0. + PreDecl(ve); + } else if (blocks_closed[ret.first->second.block_id]) { + // This is a use of a variable that was defined in a block that has + // already ended. This happens rarely, but we should cater for this + // case by lifting it to the top scope. + PreDecl(ve); + } + } + InsertNode(NodeType::Expr, T, &ve, 0); + } + + template + void Set(const VarExpr& ve, bool local) { + // Seen this var before? + if (local && + vars_defined.insert({ve.var.name(), {cur_block_id, false}}).second) { + if (value_stack_depth == 1) { + // Top level, declare it here. + InsertNode(NodeType::DeclInit, ExprType::Nop, nullptr, 1).u.var = + &ve.var; + return; + } else { + // Inside exp, better leave it as assignment exp and lift the decl out. + PreDecl(ve); + } + } + InsertNode(NodeType::Expr, T, &ve, 1); + } + + template + void Block(const BlockExprBase& be, LabelType label) { + mc.BeginBlock(label, be.block); + Construct(be.block.exprs, be.block.decl.GetNumResults(), + be.block.decl.GetNumParams(), false); + mc.EndBlock(); + InsertNode(NodeType::Expr, T, &be, 1); + } + + void Construct(const Expr& e) { + auto arity = mc.GetExprArity(e); + switch (e.type()) { + case ExprType::LocalGet: { + Get(*cast(&e), true); + return; + } + case ExprType::GlobalGet: { + Get(*cast(&e), false); + return; + } + case ExprType::LocalSet: { + Set(*cast(&e), true); + return; + } + case ExprType::GlobalSet: { + Set(*cast(&e), false); + return; + } + case ExprType::LocalTee: { + auto& lt = *cast(&e); + Set(lt, true); + if (value_stack_depth == 1) { // Tee is the only thing on there. + Get(lt, true); // Now Set + Get instead. + } else { + // Things are above us on the stack so the Tee can't be eliminated. + // The Set makes this work as a Tee when consumed by a parent. + } + return; + } + case ExprType::If: { + auto ife = cast(&e); + value_stack_depth--; // Condition. + mc.BeginBlock(LabelType::Block, ife->true_); + Construct(ife->true_.exprs, ife->true_.decl.GetNumResults(), + ife->true_.decl.GetNumParams(), false); + if (!ife->false_.empty()) { + Construct(ife->false_, ife->true_.decl.GetNumResults(), + ife->true_.decl.GetNumParams(), false); + } + mc.EndBlock(); + value_stack_depth++; // Put Condition back. + InsertNode(NodeType::Expr, ExprType::If, &e, + ife->false_.empty() ? 2 : 3); + return; + } + case ExprType::Block: { + Block(*cast(&e), LabelType::Block); + return; + } + case ExprType::Loop: { + Block(*cast(&e), LabelType::Loop); + return; + } + case ExprType::Br: { + InsertNode(NodeType::Expr, ExprType::Br, &e, 0).u.lt = + mc.GetLabel(cast(&e)->var)->label_type; + return; + } + case ExprType::BrIf: { + InsertNode(NodeType::Expr, ExprType::BrIf, &e, 1).u.lt = + mc.GetLabel(cast(&e)->var)->label_type; + return; + } + case ExprType::BrTable: { + InsertNode(NodeType::Expr, ExprType::BrTable, &e, 1).u.lt = + mc.GetLabel(cast(&e)->default_target)->label_type; + return; + } + default: { + InsertNode(NodeType::Expr, e.type(), &e, arity.nargs); + return; + } + } + } + + void Construct(const ExprList& es, + Index nresults, + Index nparams, + bool is_function_body) { + block_stack.push_back(cur_block_id); + cur_block_id = blocks_closed.size(); + blocks_closed.push_back(false); + auto start = exp_stack.size(); + int value_stack_depth_start = value_stack_depth - nparams; + auto value_stack_in_variables = value_stack_depth; + bool unreachable = false; + for (auto& e : es) { + Construct(e); + auto arity = mc.GetExprArity(e); + value_stack_depth -= arity.nargs; + value_stack_in_variables = + std::min(value_stack_in_variables, value_stack_depth); + unreachable = unreachable || arity.unreachable; + assert(unreachable || value_stack_depth >= value_stack_depth_start); + value_stack_depth += arity.nreturns; + // We maintain the invariant that a value_stack_depth of N is represented + // by the last N exp_stack items (each of which returning exactly 1 + // value), all exp_stack items before it return void ("statements"). + // In particular for the wasm stack: + // - The values between 0 and value_stack_depth_start are part of the + // parent block, and not touched here. + // - The values from there up to value_stack_in_variables are variables + // to be used, representing previous statements that flushed the + // stack into variables. + // - Values on top of that up to value_stack_depth are exps returning + // a single value. + // The code below maintains the above invariants. With this in place + // code "falls into place" the way you expect it. + if (arity.nreturns != 1) { + auto num_vars = value_stack_in_variables - value_stack_depth_start; + auto num_vals = value_stack_depth - value_stack_in_variables; + auto GenFlushVars = [&](int nargs) { + auto& ftv = + InsertNode(NodeType::FlushToVars, ExprType::Nop, nullptr, nargs); + ftv.u.var_start = flushed_vars; + ftv.u.var_count = num_vals; + }; + auto MoveStatementsBelowVars = [&](size_t amount) { + std::rotate(exp_stack.end() - num_vars - amount, + exp_stack.end() - amount, exp_stack.end()); + }; + auto GenFlushedVars = [&]() { + // Re-generate these values as vars. + for (int i = 0; i < num_vals; i++) { + auto& fv = + InsertNode(NodeType::FlushedVar, ExprType::Nop, nullptr, 0); + fv.u.var_start = flushed_vars++; + fv.u.var_count = 1; + } + }; + if (arity.nreturns == 0 && + value_stack_depth > value_stack_depth_start) { + // We have a void item on top of the exp_stack, so we must "lift" the + // previous values around it. + // We track what part of the stack is in variables to avoid doing + // this unnecessarily. + if (num_vals > 0) { + // We have actual new values that need lifting. + // This puts the part of the stack that wasn't already a variable + // (before the current void exp) into a FlushToVars. + auto void_exp = std::move(exp_stack.back()); + exp_stack.pop_back(); + GenFlushVars(num_vals); + exp_stack.push_back(std::move(void_exp)); + // Put this flush statement + void statement before any + // existing variables. + MoveStatementsBelowVars(2); + // Now re-generate these values after the void exp as vars. + GenFlushedVars(); + } else { + // We have existing variables that need lifting, but no need to + // create them anew. + std::rotate(exp_stack.end() - num_vars - 1, exp_stack.end() - 1, + exp_stack.end()); + } + value_stack_in_variables = value_stack_depth; + } else if (arity.nreturns > 1) { + // Multivalue: we flush the stack also. + // Number of other non-variable values that may be present: + assert(num_vals >= static_cast(arity.nreturns)); + // Flush multi-value exp + others. + GenFlushVars(num_vals - arity.nreturns + 1); + // Put this flush statement before any existing variables. + MoveStatementsBelowVars(1); + GenFlushedVars(); + value_stack_in_variables = value_stack_depth; + } + } else { + // Special optimisation: for constant instructions, we can mark these + // as if they were variables, so they can be re-ordered for free with + // the above code, without needing new variables! + // TODO: this would be nice to also do for local.get and maybe others, + // though that needs a way to ensure there's no local.set in between + // when they get lifted, so complicates matters a bit. + if (e.type() == ExprType::Const && + value_stack_in_variables == value_stack_depth - 1) { + value_stack_in_variables++; + } + } + } + assert(unreachable || value_stack_depth - value_stack_depth_start == + static_cast(nresults)); + // Undo any changes to value_stack_depth, since parent takes care of arity + // changes. + value_stack_depth = value_stack_depth_start; + auto end = exp_stack.size(); + assert(end >= start); + if (is_function_body) { + if (!exp_stack.empty()) { + if (exp_stack.back().etype == ExprType::Return) { + if (exp_stack.back().children.empty()) { + // Return statement at the end of a void function. + exp_stack.pop_back(); + } + } else if (nresults) { + // Combine nresults into a return statement, for when this is used as + // a function body. + // TODO: if this is some other kind of block and >1 value is being + // returned, probably need some kind of syntax to make that clearer. + InsertNode(NodeType::EndReturn, ExprType::Nop, nullptr, nresults); + } + } + // TODO: these predecls are always at top level, but in the case of + // use inside an exp, it be nice to do it in the current block. Can't + // do that for predecls that are "out if scope" however. + std::move(predecls.begin(), predecls.end(), + std::back_inserter(exp_stack)); + std::rotate(exp_stack.begin(), exp_stack.end() - predecls.size(), + exp_stack.end()); + predecls.clear(); + } + end = exp_stack.size(); + assert(end >= start); + auto size = end - start; + if (size != 1) { + InsertNode(NodeType::Statements, ExprType::Nop, nullptr, size); + } + blocks_closed[cur_block_id] = true; + cur_block_id = block_stack.back(); + block_stack.pop_back(); + } + + ModuleContext& mc; + std::vector exp_stack; + std::vector predecls; + const Func* f; + int value_stack_depth = 0; + struct Variable { + size_t block_id; + bool defined; + }; + std::map vars_defined; + Index flushed_vars = 0; + size_t cur_block_id = 0; + std::vector block_stack; + std::vector blocks_closed; +}; + +} // namespace wabt + +#endif // WABT_DECOMPILER_AST_H_ diff --git a/third_party/wasm2c/include/wabt/decompiler-ls.h b/third_party/wasm2c/include/wabt/decompiler-ls.h new file mode 100644 index 0000000000..c2612fa32a --- /dev/null +++ b/third_party/wasm2c/include/wabt/decompiler-ls.h @@ -0,0 +1,267 @@ +/* + * Copyright 2019 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_DECOMPILER_LS_H_ +#define WABT_DECOMPILER_LS_H_ + +#include "wabt/decompiler-ast.h" +#include "wabt/string-util.h" + +#include + +namespace wabt { + +// Names starting with "u" are unsigned, the rest are "signed or doesn't matter" +inline const char* GetDecompTypeName(Type t) { + switch (t) { + case Type::I8: return "byte"; + case Type::I8U: return "ubyte"; + case Type::I16: return "short"; + case Type::I16U: return "ushort"; + case Type::I32: return "int"; + case Type::I32U: return "uint"; + case Type::I64: return "long"; + case Type::F32: return "float"; + case Type::F64: return "double"; + case Type::V128: return "simd"; + case Type::Func: return "func"; + case Type::FuncRef: return "funcref"; + case Type::ExternRef: return "externref"; + case Type::Void: return "void"; + default: return "ILLEGAL"; + } +} + +inline Type GetMemoryType(Type operand_type, Opcode opc) { + // TODO: something something SIMD. + // TODO: this loses information of the type it is read into. + // That may well not be the biggest deal since that is usually obvious + // from context, if not, we should probably represent that as a cast around + // the access, since it should not be part of the field type. + if (operand_type == Type::I32 || operand_type == Type::I64) { + auto name = std::string_view(opc.GetName()); + // FIXME: change into a new column in opcode.def instead? + auto is_unsigned = name.substr(name.size() - 2) == "_u"; + switch (opc.GetMemorySize()) { + case 1: return is_unsigned ? Type::I8U : Type::I8; + case 2: return is_unsigned ? Type::I16U : Type::I16; + case 4: return is_unsigned ? Type::I32U : Type::I32; + } + } + return operand_type; +} + +// Track all loads and stores inside a single function, to be able to detect +// struct layouts we can use to annotate variables with, to make code more +// readable. +struct LoadStoreTracking { + struct LSAccess { + Address byte_size = 0; + Type type = Type::Any; + Address align = 0; + uint32_t idx = 0; + bool is_uniform = true; + }; + + struct LSVar { + std::map accesses; + bool struct_layout = true; + Type same_type = Type::Any; + Address same_align = kInvalidAddress; + Opcode last_opc; + }; + + void Track(const Node& n) { + for (auto& c : n.children) { + Track(c); + } + switch (n.etype) { + case ExprType::Load: { + auto& le = *cast(n.e); + LoadStore(le.offset, le.opcode, le.opcode.GetResultType(), le.align, + n.children[0]); + break; + } + case ExprType::Store: { + auto& se = *cast(n.e); + LoadStore(se.offset, se.opcode, se.opcode.GetParamType2(), se.align, + n.children[0]); + break; + } + default: + break; + } + } + + const std::string AddrExpName(const Node& addr_exp) const { + // TODO: expand this to more kinds of address expressions. + switch (addr_exp.etype) { + case ExprType::LocalGet: + return cast(addr_exp.e)->var.name(); + break; + case ExprType::LocalTee: + return cast(addr_exp.e)->var.name(); + break; + default: + return ""; + } + } + + void LoadStore(uint64_t offset, + Opcode opc, + Type type, + Address align, + const Node& addr_exp) { + auto byte_size = opc.GetMemorySize(); + type = GetMemoryType(type, opc); + // We want to associate memory ops of a certain offset & size as being + // relative to a uniquely identifiable pointer, such as a local. + auto name = AddrExpName(addr_exp); + if (name.empty()) { + return; + } + auto& var = vars[name]; + auto& access = var.accesses[offset]; + // Check if previous access at this offset (if any) is of same size + // and type (see Checklayouts below). + if (access.byte_size && ((access.byte_size != byte_size) || + (access.type != type) || (access.align != align))) + access.is_uniform = false; + // Also exclude weird alignment accesses from structs. + if (!opc.IsNaturallyAligned(align)) + access.is_uniform = false; + access.byte_size = byte_size; + access.type = type; + access.align = align; + // Additionally, check if all accesses are to the same type, so + // if layout check fails, we can at least declare it as pointer to + // a type. + if ((var.same_type == type || var.same_type == Type::Any) && + (var.same_align == align || var.same_align == kInvalidAddress)) { + var.same_type = type; + var.same_align = align; + var.last_opc = opc; + } else { + var.same_type = Type::Void; + var.same_align = kInvalidAddress; + } + } + + void CheckLayouts() { + // Here we check if the set of accesses we have collected form a sequence + // we could declare as a struct, meaning they are properly aligned, + // contiguous, and have no overlaps between different types and sizes. + // We do this because an int access of size 2 at offset 0 followed by + // a float access of size 4 at offset 4 can compactly represented as a + // struct { short, float }, whereas something that reads from overlapping + // or discontinuous offsets would need a more complicated syntax that + // involves explicit offsets. + // We assume that the bulk of memory accesses are of this very regular kind, + // so we choose not to even emit struct layouts for irregular ones, + // given that they are rare and confusing, and thus do not benefit from + // being represented as if they were structs. + for (auto& var : vars) { + if (var.second.accesses.size() == 1) { + // If we have just one access, this is better represented as a pointer + // than a struct. + var.second.struct_layout = false; + continue; + } + uint64_t cur_offset = 0; + uint32_t idx = 0; + for (auto& access : var.second.accesses) { + access.second.idx = idx++; + if (!access.second.is_uniform) { + var.second.struct_layout = false; + break; + } + // Align to next access: all elements are expected to be aligned to + // a memory address thats a multiple of their own size. + auto mask = static_cast(access.second.byte_size - 1); + cur_offset = (cur_offset + mask) & ~mask; + if (cur_offset != access.first) { + var.second.struct_layout = false; + break; + } + cur_offset += access.second.byte_size; + } + } + } + + std::string IdxToName(uint32_t idx) const { + return IndexToAlphaName(idx); // TODO: more descriptive names? + } + + std::string GenAlign(Address align, Opcode opc) const { + return opc.IsNaturallyAligned(align) ? "" : cat("@", std::to_string(align)); + } + + std::string GenTypeDecl(const std::string& name) const { + auto it = vars.find(name); + if (it == vars.end()) { + return ""; + } + if (it->second.struct_layout) { + std::string s = "{ "; + for (auto& access : it->second.accesses) { + if (access.second.idx) { + s += ", "; + } + s += IdxToName(access.second.idx); + s += ':'; + s += GetDecompTypeName(access.second.type); + } + s += " }"; + return s; + } + // We don't have a struct layout, or the struct has just one field, + // so maybe we can just declare it as a pointer to one type? + if (it->second.same_type != Type::Void) { + return cat(GetDecompTypeName(it->second.same_type), "_ptr", + GenAlign(it->second.same_align, it->second.last_opc)); + } + return ""; + } + + std::string GenAccess(uint64_t offset, const Node& addr_exp) const { + auto name = AddrExpName(addr_exp); + if (name.empty()) { + return ""; + } + auto it = vars.find(name); + if (it == vars.end()) { + return ""; + } + if (it->second.struct_layout) { + auto ait = it->second.accesses.find(offset); + assert(ait != it->second.accesses.end()); + return IdxToName(ait->second.idx); + } + // Not a struct, see if it is a typed pointer. + if (it->second.same_type != Type::Void) { + return "*"; + } + return ""; + } + + void Clear() { vars.clear(); } + + std::map vars; +}; + +} // namespace wabt + +#endif // WABT_DECOMPILER_LS_H_ diff --git a/third_party/wasm2c/include/wabt/decompiler-naming.h b/third_party/wasm2c/include/wabt/decompiler-naming.h new file mode 100644 index 0000000000..12c40e04fc --- /dev/null +++ b/third_party/wasm2c/include/wabt/decompiler-naming.h @@ -0,0 +1,205 @@ +/* + * Copyright 2019 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_DECOMPILER_NAMING_H_ +#define WABT_DECOMPILER_NAMING_H_ + +#include "wabt/decompiler-ast.h" + +#include + +namespace wabt { + +inline void RenameToIdentifier(std::string& name, + Index i, + BindingHash& bh, + const std::set* filter) { + // Filter out non-identifier characters, and try to reduce the size of + // gigantic C++ signature names. + std::string s; + size_t nesting = 0; + size_t read = 0; + size_t word_start = 0; + for (auto c : name) { + read++; + // We most certainly don't want to parse the entirety of C++ signatures, + // but these names are sometimes several lines long, so would be great + // to trim down. One quick way to do that is to remove anything between + // nested (), which usually means the parameter list. + if (c == '(') { + nesting++; + } + if (c == ')') { + nesting--; + } + if (nesting) { + continue; + } + if (!isalnum(static_cast(c))) { + c = '_'; + } + if (c == '_') { + if (s.empty()) { + continue; // Skip leading. + } + if (s.back() == '_') { + continue; // Consecutive. + } + } + s += c; + if (filter && (c == '_' || read == name.size())) { + // We found a "word" inside a snake_case identifier. + auto word_end = s.size(); + if (c == '_') { + word_end--; + } + assert(word_end > word_start); + auto word = + std::string_view(s.c_str() + word_start, word_end - word_start); + if (filter->find(word) != filter->end()) { + s.resize(word_start); + } + word_start = s.size(); + } + } + if (!s.empty() && s.back() == '_') { + s.pop_back(); // Trailing. + } + // If after all this culling, we're still gigantic (STL identifier can + // easily be hundreds of chars in size), just cut the identifier + // down, it will be disambiguated below, if needed. + const size_t max_identifier_length = 100; + if (s.size() > max_identifier_length) { + s.resize(max_identifier_length); + } + if (s.empty()) { + s = "__empty"; + } + // Remove original binding first, such that it doesn't match with our + // new name. + bh.erase(name); + // Find a unique name. + Index disambiguator = 0; + auto base_len = s.size(); + for (;;) { + if (bh.count(s) == 0) { + break; + } + disambiguator++; + s.resize(base_len); + s += '_'; + s += std::to_string(disambiguator); + } + // Replace name in bindings. + name = s; + bh.emplace(s, Binding(i)); +} + +template +void RenameToIdentifiers(std::vector& things, + BindingHash& bh, + const std::set* filter) { + Index i = 0; + for (auto thing : things) { + RenameToIdentifier(thing->name, i++, bh, filter); + } +} + +enum { + // This a bit arbitrary, change at will. + min_content_identifier_size = 7, + max_content_identifier_size = 30 +}; + +void RenameToContents(std::vector& segs, BindingHash& bh) { + std::string s; + for (auto seg : segs) { + if (seg->name.substr(0, 2) != "d_") { + // This segment was named explicitly by a symbol. + // FIXME: this is not a great check, a symbol could start with d_. + continue; + } + s = "d_"; + for (auto c : seg->data) { + if (isalnum(c) || c == '_') { + s += static_cast(c); + } + if (s.size() >= max_content_identifier_size) { + // We truncate any very long names, since those make for hard to + // format output. They can be somewhat long though, since data segment + // references tend to not occur that often. + break; + } + } + if (s.size() < min_content_identifier_size) { + // It is useful to have a minimum, since if there few printable characters + // in a data section, that is probably a sign of binary, and those few + // characters are not going to be very significant. + continue; + } + // We could do the same disambiguition as RenameToIdentifier and + // GenerateNames do, but if we come up with a clashing name here it is + // likely a sign of not very meaningful binary data, so it is easier to + // just keep the original generated name in that case. + if (bh.count(s) != 0) { + continue; + } + // Remove original entry. + bh.erase(seg->name); + seg->name = s; + bh.emplace(s, Binding(static_cast(&seg - &segs[0]))); + } +} + +// Function names may contain arbitrary C++ syntax, so we want to +// filter those to look like identifiers. A function name may be set +// by a name section (applied in ReadBinaryIr, called before this function) +// or by an export (applied by GenerateNames, called before this function), +// to both the Func and func_bindings. +// Those names then further perculate down the IR in ApplyNames (called after +// this function). +// To not have to add too many decompiler-specific code into those systems +// (using a callback??) we instead rename everything here. +// Also do data section renaming here. +void RenameAll(Module& module) { + // We also filter common C++ keywords/STL idents that make for huge + // identifiers. + // FIXME: this can obviously give bad results if the input is not C++.. + std::set filter = { + {"const"}, {"std"}, {"allocator"}, {"char"}, {"basic"}, + {"traits"}, {"wchar"}, {"t"}, {"void"}, {"int"}, + {"unsigned"}, {"2"}, {"cxxabiv1"}, {"short"}, {"4096ul"}, + }; + RenameToIdentifiers(module.funcs, module.func_bindings, &filter); + // Also do this for some other kinds of names, but without the keyword + // substitution. + RenameToIdentifiers(module.globals, module.global_bindings, nullptr); + RenameToIdentifiers(module.tables, module.table_bindings, nullptr); + RenameToIdentifiers(module.tags, module.tag_bindings, nullptr); + RenameToIdentifiers(module.exports, module.export_bindings, nullptr); + RenameToIdentifiers(module.types, module.type_bindings, nullptr); + RenameToIdentifiers(module.memories, module.memory_bindings, nullptr); + RenameToIdentifiers(module.data_segments, module.data_segment_bindings, + nullptr); + RenameToIdentifiers(module.elem_segments, module.elem_segment_bindings, + nullptr); + // Special purpose naming for data segments. + RenameToContents(module.data_segments, module.data_segment_bindings); +} + +} // namespace wabt + +#endif // WABT_DECOMPILER_NAMING_H_ diff --git a/third_party/wasm2c/include/wabt/decompiler.h b/third_party/wasm2c/include/wabt/decompiler.h new file mode 100644 index 0000000000..375a4b0371 --- /dev/null +++ b/third_party/wasm2c/include/wabt/decompiler.h @@ -0,0 +1,35 @@ +/* + * Copyright 2016 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_DECOMPILER_H_ +#define WABT_DECOMPILER_H_ + +#include "wabt/common.h" + +namespace wabt { + +struct Module; +class Stream; + +struct DecompileOptions {}; + +void RenameAll(Module&); + +std::string Decompile(const Module&, const DecompileOptions&); + +} // namespace wabt + +#endif /* WABT_DECOMPILER_H_ */ diff --git a/third_party/wasm2c/include/wabt/error-formatter.h b/third_party/wasm2c/include/wabt/error-formatter.h new file mode 100644 index 0000000000..a66c57ab0c --- /dev/null +++ b/third_party/wasm2c/include/wabt/error-formatter.h @@ -0,0 +1,54 @@ +/* + * Copyright 2018 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_ERROR_FORMATTER_H_ +#define WABT_ERROR_FORMATTER_H_ + +#include +#include +#include + +#include "wabt/color.h" +#include "wabt/error.h" +#include "wabt/lexer-source-line-finder.h" + +namespace wabt { + +enum class PrintHeader { + Never, + Once, + Always, +}; + +std::string FormatErrorsToString(const Errors&, + Location::Type, + LexerSourceLineFinder* = nullptr, + const Color& color = Color(nullptr, false), + const std::string& header = {}, + PrintHeader print_header = PrintHeader::Never, + int source_line_max_length = 80); + +void FormatErrorsToFile(const Errors&, + Location::Type, + LexerSourceLineFinder* = nullptr, + FILE* = stderr, + const std::string& header = {}, + PrintHeader print_header = PrintHeader::Never, + int source_line_max_length = 80); + +} // namespace wabt + +#endif // WABT_ERROR_FORMATTER_H_ diff --git a/third_party/wasm2c/include/wabt/error.h b/third_party/wasm2c/include/wabt/error.h new file mode 100644 index 0000000000..d16e1e6559 --- /dev/null +++ b/third_party/wasm2c/include/wabt/error.h @@ -0,0 +1,58 @@ +/* + * Copyright 2018 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_ERROR_H_ +#define WABT_ERROR_H_ + +#include +#include +#include + +#include "wabt/common.h" + +namespace wabt { + +enum class ErrorLevel { + Warning, + Error, +}; + +static inline const char* GetErrorLevelName(ErrorLevel error_level) { + switch (error_level) { + case ErrorLevel::Warning: + return "warning"; + case ErrorLevel::Error: + return "error"; + } + WABT_UNREACHABLE; +} + +class Error { + public: + Error() : error_level(ErrorLevel::Error) {} + Error(ErrorLevel error_level, Location loc, std::string_view message) + : error_level(error_level), loc(loc), message(message) {} + + ErrorLevel error_level; + Location loc; + std::string message; +}; + +using Errors = std::vector; + +} // namespace wabt + +#endif // WABT_ERROR_H_ diff --git a/third_party/wasm2c/include/wabt/expr-visitor.h b/third_party/wasm2c/include/wabt/expr-visitor.h new file mode 100644 index 0000000000..cbc317cde5 --- /dev/null +++ b/third_party/wasm2c/include/wabt/expr-visitor.h @@ -0,0 +1,222 @@ +/* + * Copyright 2017 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_EXPR_VISITOR_H_ +#define WABT_EXPR_VISITOR_H_ + +#include "wabt/common.h" +#include "wabt/ir.h" + +namespace wabt { + +class ExprVisitor { + public: + class Delegate; + class DelegateNop; + + explicit ExprVisitor(Delegate* delegate); + + Result VisitExpr(Expr*); + Result VisitExprList(ExprList&); + Result VisitFunc(Func*); + + private: + enum class State { + Default, + Block, + IfTrue, + IfFalse, + Loop, + Try, + Catch, + }; + + Result HandleDefaultState(Expr*); + void PushDefault(Expr*); + void PopDefault(); + void PushExprlist(State state, Expr*, ExprList&); + void PopExprlist(); + void PushCatch(Expr*, Index catch_index, ExprList&); + void PopCatch(); + + Delegate* delegate_; + + // Use parallel arrays instead of array of structs so we can avoid allocating + // unneeded objects. ExprList::iterator has no default constructor, so it + // must only be allocated for states that use it. + std::vector state_stack_; + std::vector expr_stack_; + std::vector expr_iter_stack_; + std::vector catch_index_stack_; +}; + +class ExprVisitor::Delegate { + public: + virtual ~Delegate() {} + + virtual Result OnBinaryExpr(BinaryExpr*) = 0; + virtual Result BeginBlockExpr(BlockExpr*) = 0; + virtual Result EndBlockExpr(BlockExpr*) = 0; + virtual Result OnBrExpr(BrExpr*) = 0; + virtual Result OnBrIfExpr(BrIfExpr*) = 0; + virtual Result OnBrTableExpr(BrTableExpr*) = 0; + virtual Result OnCallExpr(CallExpr*) = 0; + virtual Result OnCallIndirectExpr(CallIndirectExpr*) = 0; + virtual Result OnCallRefExpr(CallRefExpr*) = 0; + virtual Result OnCodeMetadataExpr(CodeMetadataExpr*) = 0; + virtual Result OnCompareExpr(CompareExpr*) = 0; + virtual Result OnConstExpr(ConstExpr*) = 0; + virtual Result OnConvertExpr(ConvertExpr*) = 0; + virtual Result OnDropExpr(DropExpr*) = 0; + virtual Result OnGlobalGetExpr(GlobalGetExpr*) = 0; + virtual Result OnGlobalSetExpr(GlobalSetExpr*) = 0; + virtual Result BeginIfExpr(IfExpr*) = 0; + virtual Result AfterIfTrueExpr(IfExpr*) = 0; + virtual Result EndIfExpr(IfExpr*) = 0; + virtual Result OnLoadExpr(LoadExpr*) = 0; + virtual Result OnLocalGetExpr(LocalGetExpr*) = 0; + virtual Result OnLocalSetExpr(LocalSetExpr*) = 0; + virtual Result OnLocalTeeExpr(LocalTeeExpr*) = 0; + virtual Result BeginLoopExpr(LoopExpr*) = 0; + virtual Result EndLoopExpr(LoopExpr*) = 0; + virtual Result OnMemoryCopyExpr(MemoryCopyExpr*) = 0; + virtual Result OnDataDropExpr(DataDropExpr*) = 0; + virtual Result OnMemoryFillExpr(MemoryFillExpr*) = 0; + virtual Result OnMemoryGrowExpr(MemoryGrowExpr*) = 0; + virtual Result OnMemoryInitExpr(MemoryInitExpr*) = 0; + virtual Result OnMemorySizeExpr(MemorySizeExpr*) = 0; + virtual Result OnTableCopyExpr(TableCopyExpr*) = 0; + virtual Result OnElemDropExpr(ElemDropExpr*) = 0; + virtual Result OnTableInitExpr(TableInitExpr*) = 0; + virtual Result OnTableGetExpr(TableGetExpr*) = 0; + virtual Result OnTableSetExpr(TableSetExpr*) = 0; + virtual Result OnTableGrowExpr(TableGrowExpr*) = 0; + virtual Result OnTableSizeExpr(TableSizeExpr*) = 0; + virtual Result OnTableFillExpr(TableFillExpr*) = 0; + virtual Result OnRefFuncExpr(RefFuncExpr*) = 0; + virtual Result OnRefNullExpr(RefNullExpr*) = 0; + virtual Result OnRefIsNullExpr(RefIsNullExpr*) = 0; + virtual Result OnNopExpr(NopExpr*) = 0; + virtual Result OnReturnExpr(ReturnExpr*) = 0; + virtual Result OnReturnCallExpr(ReturnCallExpr*) = 0; + virtual Result OnReturnCallIndirectExpr(ReturnCallIndirectExpr*) = 0; + virtual Result OnSelectExpr(SelectExpr*) = 0; + virtual Result OnStoreExpr(StoreExpr*) = 0; + virtual Result OnUnaryExpr(UnaryExpr*) = 0; + virtual Result OnUnreachableExpr(UnreachableExpr*) = 0; + virtual Result BeginTryExpr(TryExpr*) = 0; + virtual Result OnCatchExpr(TryExpr*, Catch*) = 0; + virtual Result OnDelegateExpr(TryExpr*) = 0; + virtual Result EndTryExpr(TryExpr*) = 0; + virtual Result OnThrowExpr(ThrowExpr*) = 0; + virtual Result OnRethrowExpr(RethrowExpr*) = 0; + virtual Result OnAtomicWaitExpr(AtomicWaitExpr*) = 0; + virtual Result OnAtomicFenceExpr(AtomicFenceExpr*) = 0; + virtual Result OnAtomicNotifyExpr(AtomicNotifyExpr*) = 0; + virtual Result OnAtomicLoadExpr(AtomicLoadExpr*) = 0; + virtual Result OnAtomicStoreExpr(AtomicStoreExpr*) = 0; + virtual Result OnAtomicRmwExpr(AtomicRmwExpr*) = 0; + virtual Result OnAtomicRmwCmpxchgExpr(AtomicRmwCmpxchgExpr*) = 0; + virtual Result OnTernaryExpr(TernaryExpr*) = 0; + virtual Result OnSimdLaneOpExpr(SimdLaneOpExpr*) = 0; + virtual Result OnSimdLoadLaneExpr(SimdLoadLaneExpr*) = 0; + virtual Result OnSimdStoreLaneExpr(SimdStoreLaneExpr*) = 0; + virtual Result OnSimdShuffleOpExpr(SimdShuffleOpExpr*) = 0; + virtual Result OnLoadSplatExpr(LoadSplatExpr*) = 0; + virtual Result OnLoadZeroExpr(LoadZeroExpr*) = 0; +}; + +class ExprVisitor::DelegateNop : public ExprVisitor::Delegate { + public: + Result OnBinaryExpr(BinaryExpr*) override { return Result::Ok; } + Result BeginBlockExpr(BlockExpr*) override { return Result::Ok; } + Result EndBlockExpr(BlockExpr*) override { return Result::Ok; } + Result OnBrExpr(BrExpr*) override { return Result::Ok; } + Result OnBrIfExpr(BrIfExpr*) override { return Result::Ok; } + Result OnBrTableExpr(BrTableExpr*) override { return Result::Ok; } + Result OnCallExpr(CallExpr*) override { return Result::Ok; } + Result OnCallIndirectExpr(CallIndirectExpr*) override { return Result::Ok; } + Result OnCallRefExpr(CallRefExpr*) override { return Result::Ok; } + Result OnCodeMetadataExpr(CodeMetadataExpr*) override { return Result::Ok; } + Result OnCompareExpr(CompareExpr*) override { return Result::Ok; } + Result OnConstExpr(ConstExpr*) override { return Result::Ok; } + Result OnConvertExpr(ConvertExpr*) override { return Result::Ok; } + Result OnDropExpr(DropExpr*) override { return Result::Ok; } + Result OnGlobalGetExpr(GlobalGetExpr*) override { return Result::Ok; } + Result OnGlobalSetExpr(GlobalSetExpr*) override { return Result::Ok; } + Result BeginIfExpr(IfExpr*) override { return Result::Ok; } + Result AfterIfTrueExpr(IfExpr*) override { return Result::Ok; } + Result EndIfExpr(IfExpr*) override { return Result::Ok; } + Result OnLoadExpr(LoadExpr*) override { return Result::Ok; } + Result OnLocalGetExpr(LocalGetExpr*) override { return Result::Ok; } + Result OnLocalSetExpr(LocalSetExpr*) override { return Result::Ok; } + Result OnLocalTeeExpr(LocalTeeExpr*) override { return Result::Ok; } + Result BeginLoopExpr(LoopExpr*) override { return Result::Ok; } + Result EndLoopExpr(LoopExpr*) override { return Result::Ok; } + Result OnMemoryCopyExpr(MemoryCopyExpr*) override { return Result::Ok; } + Result OnDataDropExpr(DataDropExpr*) override { return Result::Ok; } + Result OnMemoryFillExpr(MemoryFillExpr*) override { return Result::Ok; } + Result OnMemoryGrowExpr(MemoryGrowExpr*) override { return Result::Ok; } + Result OnMemoryInitExpr(MemoryInitExpr*) override { return Result::Ok; } + Result OnMemorySizeExpr(MemorySizeExpr*) override { return Result::Ok; } + Result OnTableCopyExpr(TableCopyExpr*) override { return Result::Ok; } + Result OnElemDropExpr(ElemDropExpr*) override { return Result::Ok; } + Result OnTableInitExpr(TableInitExpr*) override { return Result::Ok; } + Result OnTableGetExpr(TableGetExpr*) override { return Result::Ok; } + Result OnTableSetExpr(TableSetExpr*) override { return Result::Ok; } + Result OnTableGrowExpr(TableGrowExpr*) override { return Result::Ok; } + Result OnTableSizeExpr(TableSizeExpr*) override { return Result::Ok; } + Result OnTableFillExpr(TableFillExpr*) override { return Result::Ok; } + Result OnRefFuncExpr(RefFuncExpr*) override { return Result::Ok; } + Result OnRefNullExpr(RefNullExpr*) override { return Result::Ok; } + Result OnRefIsNullExpr(RefIsNullExpr*) override { return Result::Ok; } + Result OnNopExpr(NopExpr*) override { return Result::Ok; } + Result OnReturnExpr(ReturnExpr*) override { return Result::Ok; } + Result OnReturnCallExpr(ReturnCallExpr*) override { return Result::Ok; } + Result OnReturnCallIndirectExpr(ReturnCallIndirectExpr*) override { + return Result::Ok; + } + Result OnSelectExpr(SelectExpr*) override { return Result::Ok; } + Result OnStoreExpr(StoreExpr*) override { return Result::Ok; } + Result OnUnaryExpr(UnaryExpr*) override { return Result::Ok; } + Result OnUnreachableExpr(UnreachableExpr*) override { return Result::Ok; } + Result BeginTryExpr(TryExpr*) override { return Result::Ok; } + Result OnCatchExpr(TryExpr*, Catch*) override { return Result::Ok; } + Result OnDelegateExpr(TryExpr*) override { return Result::Ok; } + Result EndTryExpr(TryExpr*) override { return Result::Ok; } + Result OnThrowExpr(ThrowExpr*) override { return Result::Ok; } + Result OnRethrowExpr(RethrowExpr*) override { return Result::Ok; } + Result OnAtomicWaitExpr(AtomicWaitExpr*) override { return Result::Ok; } + Result OnAtomicFenceExpr(AtomicFenceExpr*) override { return Result::Ok; } + Result OnAtomicNotifyExpr(AtomicNotifyExpr*) override { return Result::Ok; } + Result OnAtomicLoadExpr(AtomicLoadExpr*) override { return Result::Ok; } + Result OnAtomicStoreExpr(AtomicStoreExpr*) override { return Result::Ok; } + Result OnAtomicRmwExpr(AtomicRmwExpr*) override { return Result::Ok; } + Result OnAtomicRmwCmpxchgExpr(AtomicRmwCmpxchgExpr*) override { + return Result::Ok; + } + Result OnTernaryExpr(TernaryExpr*) override { return Result::Ok; } + Result OnSimdLaneOpExpr(SimdLaneOpExpr*) override { return Result::Ok; } + Result OnSimdLoadLaneExpr(SimdLoadLaneExpr*) override { return Result::Ok; } + Result OnSimdStoreLaneExpr(SimdStoreLaneExpr*) override { return Result::Ok; } + Result OnSimdShuffleOpExpr(SimdShuffleOpExpr*) override { return Result::Ok; } + Result OnLoadSplatExpr(LoadSplatExpr*) override { return Result::Ok; } + Result OnLoadZeroExpr(LoadZeroExpr*) override { return Result::Ok; } +}; + +} // namespace wabt + +#endif // WABT_EXPR_VISITOR_H_ diff --git a/third_party/wasm2c/include/wabt/feature.def b/third_party/wasm2c/include/wabt/feature.def new file mode 100644 index 0000000000..00a4e7f238 --- /dev/null +++ b/third_party/wasm2c/include/wabt/feature.def @@ -0,0 +1,42 @@ +/* + * Copyright 2017 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_FEATURE +#error "You must define WABT_FEATURE before including this file." +#endif + +/* + * variable flag default help + * ========================================================================= */ + +WABT_FEATURE(exceptions, "exceptions", false, "Experimental exception handling") +WABT_FEATURE(mutable_globals, "mutable-globals", true, "Import/export mutable globals") +WABT_FEATURE(sat_float_to_int, "saturating-float-to-int", true, "Saturating float-to-int operators") +WABT_FEATURE(sign_extension, "sign-extension", true, "Sign-extension operators") +WABT_FEATURE(simd, "simd", true, "SIMD support") +WABT_FEATURE(threads, "threads", false, "Threading support") +WABT_FEATURE(function_references, "function-references", false, "Typed function references") +WABT_FEATURE(multi_value, "multi-value", true, "Multi-value") +WABT_FEATURE(tail_call, "tail-call", false, "Tail-call support") +WABT_FEATURE(bulk_memory, "bulk-memory", true, "Bulk-memory operations") +WABT_FEATURE(reference_types, "reference-types", true, "Reference types (externref)") +WABT_FEATURE(annotations, "annotations", false, "Custom annotation syntax") +WABT_FEATURE(code_metadata, "code-metadata", false, "Code metadata") +WABT_FEATURE(gc, "gc", false, "Garbage collection") +WABT_FEATURE(memory64, "memory64", false, "64-bit memory") +WABT_FEATURE(multi_memory, "multi-memory", false, "Multi-memory") +WABT_FEATURE(extended_const, "extended-const", false, "Extended constant expressions") +WABT_FEATURE(relaxed_simd, "relaxed-simd", false, "Relaxed SIMD") diff --git a/third_party/wasm2c/include/wabt/feature.h b/third_party/wasm2c/include/wabt/feature.h new file mode 100644 index 0000000000..5a2886586b --- /dev/null +++ b/third_party/wasm2c/include/wabt/feature.h @@ -0,0 +1,58 @@ +/* + * Copyright 2017 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_FEATURE_H_ +#define WABT_FEATURE_H_ + +#include "wabt/common.h" + +namespace wabt { + +class OptionParser; + +class Features { + public: + void AddOptions(OptionParser*); + + void EnableAll() { +#define WABT_FEATURE(variable, flag, default_, help) enable_##variable(); +#include "wabt/feature.def" +#undef WABT_FEATURE + } + +#define WABT_FEATURE(variable, flag, default_, help) \ + bool variable##_enabled() const { return variable##_enabled_; } \ + void enable_##variable() { set_##variable##_enabled(true); } \ + void disable_##variable() { set_##variable##_enabled(false); } \ + void set_##variable##_enabled(bool value) { \ + variable##_enabled_ = value; \ + UpdateDependencies(); \ + } +#include "wabt/feature.def" +#undef WABT_FEATURE + + private: + void UpdateDependencies(); + +#define WABT_FEATURE(variable, flag, default_, help) \ + bool variable##_enabled_ = default_; +#include "wabt/feature.def" +#undef WABT_FEATURE +}; + +} // namespace wabt + +#endif // WABT_FEATURE_H_ diff --git a/third_party/wasm2c/include/wabt/filenames.h b/third_party/wasm2c/include/wabt/filenames.h new file mode 100644 index 0000000000..983d2fbf52 --- /dev/null +++ b/third_party/wasm2c/include/wabt/filenames.h @@ -0,0 +1,51 @@ +/* + * Copyright 2016 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_FILENAMES_H_ +#define WABT_FILENAMES_H_ + +#include "wabt/common.h" + +namespace wabt { + +extern const char* kWasmExtension; +extern const char* kWatExtension; + +// Return only the file extension, e.g.: +// +// "foo.txt", => ".txt" +// "foo" => "" +// "/foo/bar/foo.wasm" => ".wasm" +std::string_view GetExtension(std::string_view filename); + +// Strip extension, e.g.: +// +// "foo", => "foo" +// "foo.bar" => "foo" +// "/path/to/foo.bar" => "/path/to/foo" +// "\\path\\to\\foo.bar" => "\\path\\to\\foo" +std::string_view StripExtension(std::string_view s); + +// Strip everything up to and including the last slash, e.g.: +// +// "/foo/bar/baz", => "baz" +// "/usr/local/include/stdio.h", => "stdio.h" +// "foo.bar", => "foo.bar" +std::string_view GetBasename(std::string_view filename); + +} // namespace wabt + +#endif /* WABT_FILENAMES_H_ */ diff --git a/third_party/wasm2c/include/wabt/generate-names.h b/third_party/wasm2c/include/wabt/generate-names.h new file mode 100644 index 0000000000..69dae8e20d --- /dev/null +++ b/third_party/wasm2c/include/wabt/generate-names.h @@ -0,0 +1,46 @@ +/* + * Copyright 2016 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_GENERATE_NAMES_H_ +#define WABT_GENERATE_NAMES_H_ + +#include "wabt/common.h" + +namespace wabt { + +struct Module; + +enum NameOpts { + None = 0, + AlphaNames = 1 << 0, +}; + +Result GenerateNames(struct Module*, NameOpts opts = NameOpts::None); + +inline std::string IndexToAlphaName(Index index) { + std::string s; + do { + // For multiple chars, put most frequently changing char first. + s += 'a' + (index % 26); + index /= 26; + // Continue remaining sequence with 'a' rather than 'b'. + } while (index--); + return s; +} + +} // namespace wabt + +#endif /* WABT_GENERATE_NAMES_H_ */ diff --git a/third_party/wasm2c/include/wabt/intrusive-list.h b/third_party/wasm2c/include/wabt/intrusive-list.h new file mode 100644 index 0000000000..34332345a2 --- /dev/null +++ b/third_party/wasm2c/include/wabt/intrusive-list.h @@ -0,0 +1,631 @@ +/* + * Copyright 2017 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_INTRUSIVE_LIST_H_ +#define WABT_INTRUSIVE_LIST_H_ + +#include +#include +#include + +// This uses a similar interface as std::list, but is missing the following +// features: +// +// * Add "extract_" functions that remove an element from the list and return +// it. +// * Only supports move-only operations +// * No allocator support +// * No initializer lists +// * Asserts instead of exceptions +// * Some functions are not implemented (merge, remove, remove_if, reverse, +// unique, sort, non-member comparison operators) + +namespace wabt { + +template +class intrusive_list; + +template +class intrusive_list_base { + private: + friend class intrusive_list; + + mutable T* next_ = nullptr; + mutable T* prev_ = nullptr; +}; + +template +class intrusive_list { + public: + // types: + using value_type = T; + using reference = value_type&; + using const_reference = const value_type&; + class iterator; + class const_iterator; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + // construct/copy/destroy: + intrusive_list(); + explicit intrusive_list(std::unique_ptr node); + explicit intrusive_list(T&& node); + intrusive_list(const intrusive_list&) = delete; + intrusive_list(intrusive_list&&); + ~intrusive_list(); + intrusive_list& operator=(const intrusive_list& other) = delete; + intrusive_list& operator=(intrusive_list&& other); + + // iterators: + iterator begin() noexcept; + const_iterator begin() const noexcept; + iterator end() noexcept; + const_iterator end() const noexcept; + + reverse_iterator rbegin() noexcept; + const_reverse_iterator rbegin() const noexcept; + reverse_iterator rend() noexcept; + const_reverse_iterator rend() const noexcept; + + const_iterator cbegin() const noexcept; + const_iterator cend() const noexcept; + const_reverse_iterator crbegin() const noexcept; + const_reverse_iterator crend() const noexcept; + + // capacity: + size_type size() const noexcept; + bool empty() const noexcept; + + // element access: + reference front(); + const_reference front() const; + reference back(); + const_reference back() const; + + // modifiers: + template + void emplace_front(Args&&... args); + template + void emplace_back(Args&&... args); + void push_front(std::unique_ptr node); + void push_front(T&& node); + void push_back(std::unique_ptr node); + void push_back(T&& node); + void pop_front(); + void pop_back(); + std::unique_ptr extract_front(); + std::unique_ptr extract_back(); + + template + iterator emplace(iterator pos, Args&&... args); + iterator insert(iterator pos, std::unique_ptr node); + iterator insert(iterator pos, T&& node); + std::unique_ptr extract(iterator it); + + iterator erase(iterator pos); + iterator erase(iterator first, iterator last); + void swap(intrusive_list&); + void clear() noexcept; + + void splice(iterator pos, intrusive_list& node); + void splice(iterator pos, intrusive_list&& node); + void splice(iterator pos, intrusive_list& node, iterator it); + void splice(iterator pos, + intrusive_list& node, + iterator first, + iterator last); + + private: + T* first_ = nullptr; + T* last_ = nullptr; + size_t size_ = 0; +}; + +/// iterator +template +class intrusive_list::iterator { + public: + using difference_type = std::ptrdiff_t; + using iterator_category = std::bidirectional_iterator_tag; + using value_type = T; + using pointer = T*; + using reference = T&; + + iterator(const intrusive_list& list, T* node) + : list_(&list), node_(node) {} + + reference operator*() const { + assert(node_); + return *node_; + } + + pointer operator->() const { + assert(node_); + return node_; + } + + iterator& operator++() { + assert(node_); + node_ = node_->next_; + return *this; + } + + iterator operator++(int) { + iterator tmp = *this; + operator++(); + return tmp; + } + + iterator& operator--() { + node_ = node_ ? node_->prev_ : list_->last_; + return *this; + } + + iterator operator--(int) { + iterator tmp = *this; + operator--(); + return tmp; + } + + bool operator==(iterator rhs) const { + assert(list_ == rhs.list_); + return node_ == rhs.node_; + } + + bool operator!=(iterator rhs) const { + assert(list_ == rhs.list_); + return node_ != rhs.node_; + } + + private: + friend class const_iterator; + + const intrusive_list* list_; + T* node_; +}; + +/// const_iterator +template +class intrusive_list::const_iterator { + public: + using difference_type = std::ptrdiff_t; + using iterator_category = std::bidirectional_iterator_tag; + using value_type = T; + using pointer = const T*; + using reference = const T&; + + const_iterator(const intrusive_list& list, T* node) + : list_(&list), node_(node) {} + + const_iterator(const iterator& other) + : list_(other.list_), node_(other.node_) {} + + reference operator*() const { + assert(node_); + return *node_; + } + + pointer operator->() const { + assert(node_); + return node_; + } + + const_iterator& operator++() { + assert(node_); + node_ = node_->next_; + return *this; + } + + const_iterator operator++(int) { + const_iterator tmp = *this; + operator++(); + return tmp; + } + + const_iterator& operator--() { + node_ = node_ ? node_->prev_ : list_->last_; + return *this; + } + + const_iterator operator--(int) { + const_iterator tmp = *this; + operator--(); + return tmp; + } + + bool operator==(const_iterator rhs) const { + assert(list_ == rhs.list_); + return node_ == rhs.node_; + } + + bool operator!=(const_iterator rhs) const { + assert(list_ == rhs.list_); + return node_ != rhs.node_; + } + + private: + const intrusive_list* list_; + T* node_; +}; + +template +inline intrusive_list::intrusive_list() {} + +template +inline intrusive_list::intrusive_list(std::unique_ptr node) { + push_back(std::move(node)); +} + +template +inline intrusive_list::intrusive_list(T&& node) { + push_back(std::move(node)); +} + +template +inline intrusive_list::intrusive_list(intrusive_list&& other) + : first_(other.first_), last_(other.last_), size_(other.size_) { + other.first_ = other.last_ = nullptr; + other.size_ = 0; +} + +template +inline intrusive_list::~intrusive_list() { + clear(); +} + +template +inline intrusive_list& intrusive_list::operator=( + intrusive_list&& other) { + clear(); + first_ = other.first_; + last_ = other.last_; + size_ = other.size_; + other.first_ = other.last_ = nullptr; + other.size_ = 0; + return *this; +} + +template +inline typename intrusive_list::iterator +intrusive_list::begin() noexcept { + return iterator(*this, first_); +} + +template +inline typename intrusive_list::const_iterator intrusive_list::begin() + const noexcept { + return const_iterator(*this, first_); +} + +template +inline typename intrusive_list::iterator intrusive_list::end() noexcept { + return iterator(*this, nullptr); +} + +template +inline typename intrusive_list::const_iterator intrusive_list::end() + const noexcept { + return const_iterator(*this, nullptr); +} + +template +inline typename intrusive_list::reverse_iterator +intrusive_list::rbegin() noexcept { + return reverse_iterator(iterator(*this, nullptr)); +} + +template +inline typename intrusive_list::const_reverse_iterator +intrusive_list::rbegin() const noexcept { + return const_reverse_iterator(const_iterator(*this, nullptr)); +} + +template +inline typename intrusive_list::reverse_iterator +intrusive_list::rend() noexcept { + return reverse_iterator(iterator(*this, first_)); +} + +template +inline typename intrusive_list::const_reverse_iterator +intrusive_list::rend() const noexcept { + return const_reverse_iterator(const_iterator(*this, first_)); +} + +template +inline typename intrusive_list::const_iterator intrusive_list::cbegin() + const noexcept { + return const_iterator(*this, first_); +} + +template +inline typename intrusive_list::const_iterator intrusive_list::cend() + const noexcept { + return const_iterator(*this, nullptr); +} + +template +inline typename intrusive_list::const_reverse_iterator +intrusive_list::crbegin() const noexcept { + return const_reverse_iterator(const_iterator(*this, nullptr)); +} + +template +inline typename intrusive_list::const_reverse_iterator +intrusive_list::crend() const noexcept { + return const_reverse_iterator(const_iterator(*this, first_)); +} + +template +inline typename intrusive_list::size_type intrusive_list::size() + const noexcept { + return size_; +} + +template +inline bool intrusive_list::empty() const noexcept { + return size_ == 0; +} + +template +inline typename intrusive_list::reference intrusive_list::front() { + assert(!empty()); + return *first_; +} + +template +inline typename intrusive_list::const_reference intrusive_list::front() + const { + assert(!empty()); + return *first_; +} + +template +inline typename intrusive_list::reference intrusive_list::back() { + assert(!empty()); + return *last_; +} + +template +inline typename intrusive_list::const_reference intrusive_list::back() + const { + assert(!empty()); + return *last_; +} + +template +template +inline void intrusive_list::emplace_front(Args&&... args) { + push_front(std::make_unique(std::forward(args)...)); +} + +template +template +inline void intrusive_list::emplace_back(Args&&... args) { + push_back(std::make_unique(std::forward(args)...)); +} + +template +inline void intrusive_list::push_front(std::unique_ptr node) { + assert(node->prev_ == nullptr && node->next_ == nullptr); + + T* node_p = node.release(); + if (first_) { + node_p->next_ = first_; + first_->prev_ = node_p; + } else { + last_ = node_p; + } + first_ = node_p; + size_++; +} + +template +inline void intrusive_list::push_front(T&& node) { + push_front(std::make_unique(std::move(node))); +} + +template +inline void intrusive_list::push_back(std::unique_ptr node) { + assert(node->prev_ == nullptr && node->next_ == nullptr); + + T* node_p = node.release(); + if (last_) { + node_p->prev_ = last_; + last_->next_ = node_p; + } else { + first_ = node_p; + } + last_ = node_p; + size_++; +} + +template +inline void intrusive_list::push_back(T&& node) { + push_back(std::make_unique(std::move(node))); +} + +template +inline void intrusive_list::pop_front() { + extract_front(); +} + +template +inline void intrusive_list::pop_back() { + extract_back(); +} + +template +inline std::unique_ptr intrusive_list::extract_front() { + assert(!empty()); + T* node = first_; + if (first_ == last_) { + first_ = last_ = nullptr; + } else { + first_ = first_->next_; + first_->prev_ = nullptr; + } + node->next_ = node->prev_ = nullptr; + size_--; + return std::unique_ptr(node); +} + +template +inline std::unique_ptr intrusive_list::extract_back() { + assert(!empty()); + T* node = last_; + if (first_ == last_) { + first_ = last_ = nullptr; + } else { + last_ = last_->prev_; + last_->next_ = nullptr; + } + node->next_ = node->prev_ = nullptr; + size_--; + return std::unique_ptr(node); +} + +template +template +inline typename intrusive_list::iterator intrusive_list::emplace( + iterator pos, + Args&&... args) { + return insert(pos, std::make_unique(std::forward(args)...)); +} + +template +inline typename intrusive_list::iterator intrusive_list::insert( + iterator pos, + std::unique_ptr node) { + assert(node->prev_ == nullptr && node->next_ == nullptr); + + T* node_p; + if (pos == end()) { + push_back(std::move(node)); + node_p = &back(); + } else { + node_p = node.release(); + node_p->prev_ = pos->prev_; + node_p->next_ = &*pos; + if (pos->prev_) { + pos->prev_->next_ = node_p; + } else { + first_ = node_p; + } + pos->prev_ = node_p; + size_++; + } + return iterator(*this, node_p); +} + +template +inline typename intrusive_list::iterator intrusive_list::insert( + iterator pos, + T&& node) { + return insert(pos, std::make_unique(std::move(node))); +} + +template +inline std::unique_ptr intrusive_list::extract(iterator pos) { + assert(!empty()); + assert(pos != end()); + T* node = &*pos; + if (first_ == last_) { + first_ = last_ = nullptr; + } else { + if (node->prev_) { + node->prev_->next_ = node->next_; + } else { + first_ = node->next_; + } + + if (node->next_) { + node->next_->prev_ = node->prev_; + } else { + last_ = node->prev_; + } + } + node->next_ = node->prev_ = nullptr; + size_--; + return std::unique_ptr(node); +} + +template +inline typename intrusive_list::iterator intrusive_list::erase( + iterator pos) { + iterator next = std::next(pos); + extract(pos); + return next; +} + +template +inline typename intrusive_list::iterator intrusive_list::erase( + iterator first, + iterator last) { + while (first != last) + first = erase(first); + return first; +} + +template +inline void intrusive_list::swap(intrusive_list& other) { + std::swap(first_, other.first_); + std::swap(last_, other.last_); + std::swap(size_, other.size_); +} + +template +inline void intrusive_list::clear() noexcept { + for (T* iter = first_; iter;) { + T* next = iter->next_; + delete iter; + iter = next; + } + first_ = last_ = nullptr; + size_ = 0; +} + +template +inline void intrusive_list::splice(iterator pos, intrusive_list& other) { + splice(pos, other, other.begin(), other.end()); +} + +template +inline void intrusive_list::splice(iterator pos, intrusive_list&& other) { + splice(pos, other, other.begin(), other.end()); +} + +template +inline void intrusive_list::splice(iterator pos, + intrusive_list& other, + iterator it) { + insert(pos, other.extract(it)); +} + +template +inline void intrusive_list::splice(iterator pos, + intrusive_list& other, + iterator first, + iterator last) { + while (first != last) + insert(pos, other.extract(first++)); +} + +} // namespace wabt + +#endif // WABT_INTRUSIVE_LIST_H_ diff --git a/third_party/wasm2c/include/wabt/ir-util.h b/third_party/wasm2c/include/wabt/ir-util.h new file mode 100644 index 0000000000..7d06121902 --- /dev/null +++ b/third_party/wasm2c/include/wabt/ir-util.h @@ -0,0 +1,77 @@ +/* + * Copyright 2016 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_IR_UTIL_H_ +#define WABT_IR_UTIL_H_ + +#include "wabt/common.h" +#include "wabt/ir.h" + +namespace wabt { + +struct Label { + Label(LabelType label_type, + const std::string& name, + const TypeVector& param_types, + const TypeVector& result_types) + : name(name), + label_type(label_type), + param_types(param_types), + result_types(result_types) {} + + std::string name; + LabelType label_type; + TypeVector param_types; + TypeVector result_types; +}; + +struct ModuleContext { + ModuleContext(const Module& module) : module(module) {} + + Index GetLabelStackSize() const { return label_stack_.size(); } + const Label* GetLabel(const Var& var) const; + Index GetLabelArity(const Var& var) const; + void SetTopLabelType(LabelType label_type) { + label_stack_.back().label_type = label_type; + } + + Index GetFuncParamCount(const Var& var) const; + Index GetFuncResultCount(const Var& var) const; + + void BeginBlock(LabelType label_type, const Block& block); + void EndBlock(); + void BeginFunc(const Func& func); + void EndFunc(); + + struct Arities { + Index nargs; + Index nreturns; + bool unreachable; + Arities(Index na, Index nr, bool ur = false) + : nargs(na), nreturns(nr), unreachable(ur) {} + }; + Arities GetExprArity(const Expr& expr) const; + + const Module& module; + + private: + const Func* current_func_ = nullptr; + std::vector