├── .github ├── badges │ └── SponsoredbyIgalia.svg └── workflows │ ├── api-check.yml │ ├── deploy-docs.yml │ └── test.yml ├── .gitignore ├── LICENSE ├── README.md ├── common.rkt ├── exports.rkt ├── expressions.rkt ├── features.rkt ├── functions.rkt ├── indices.rkt ├── info.rkt ├── literals.rkt ├── main.rkt ├── modules.rkt ├── optimizations.rkt ├── private ├── binaryen-ffi.rkt ├── features.rkt ├── functions.rkt ├── modules.rkt └── types.rkt ├── scribblings ├── api.scrbl ├── binaryen.scrbl ├── exports.scrbl ├── expressions.scrbl ├── features.scrbl ├── functions.scrbl ├── gettingstarted.scrbl ├── literals.scrbl ├── main.scrbl~ ├── modules.scrbl ├── optimizations.scrbl └── types.scrbl ├── scripts └── find-good-api.sh ├── test-utils.rkt ├── tests ├── square.rkt ├── wingo-input │ ├── wingo_const.scm │ ├── wingo_fact.scm │ └── wingo_zero.scm ├── wingo-raw.rkt └── wingo.rkt └── types.rkt /.github/badges/SponsoredbyIgalia.svg: -------------------------------------------------------------------------------- 1 | Sponsored by: IgaliaSponsored byIgalia -------------------------------------------------------------------------------- /.github/workflows/api-check.yml: -------------------------------------------------------------------------------- 1 | name: Check API 2 | 3 | on: 4 | push: 5 | schedule: 6 | - cron: '0 0 * * *' 7 | 8 | jobs: 9 | 10 | test: 11 | runs-on: ubuntu-20.04 12 | 13 | steps: 14 | - uses: actions/checkout@v2 15 | - name: Checkout binaryen HEAD 16 | run: git clone --depth 1 https://github.com/WebAssembly/binaryen.git binaryen-src 17 | - name: Check API SHA 18 | run: diff <(sha1sum binaryen-src/src/binaryen-c.h | cut -d ' ' -f1) <(grep ';==;' private/binaryen-ffi.rkt | cut -d ';' -f 3) 19 | - name: Find last good commit 20 | if: ${{ failure() }} 21 | run: scripts/find-good-api.sh $(grep ';==;' private/binaryen-ffi.rkt | cut -d ';' -f 3) 22 | -------------------------------------------------------------------------------- /.github/workflows/deploy-docs.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Documentation 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | deploy: 10 | runs-on: ubuntu-latest 11 | env: 12 | LD_LIBRARY_PATH: "/usr/local/lib" 13 | 14 | steps: 15 | - name: Checkout 🛎️ 16 | uses: actions/checkout@v2.3.1 # If you're using actions/checkout@v2 you must set persist-credentials to false in most cases for the deployment to work correctly. 17 | with: 18 | persist-credentials: false 19 | - uses: Bogdanp/setup-racket@v1.5 20 | with: 21 | architecture: 'x64' 22 | distribution: 'full' 23 | variant: 'CS' 24 | version: 'current' 25 | - name: Install package locally 26 | run: raco pkg install --auto --link -D $PWD 27 | - name: Install dependencies 28 | run: | 29 | sudo apt-get update 30 | sudo apt-get install -y g++ python cmake 31 | - name: Compile binaryen 32 | run: | 33 | git clone --depth 1 https://github.com/WebAssembly/binaryen.git binaryen-src 34 | cd binaryen-src 35 | cmake . 36 | make -j2 37 | sudo make install 38 | - name: Build docs 39 | run: raco scribble --html +m --redirect-main "https://docs.racket-lang.org/" --dest documentation --dest-name index scribblings/binaryen.scrbl 40 | - name: Install SSH Client 🔑 41 | uses: webfactory/ssh-agent@v0.5.0 42 | with: 43 | ssh-private-key: ${{ secrets.DEPLOY_KEY }} 44 | 45 | - name: Deploy 🚀 46 | uses: JamesIves/github-pages-deploy-action@4.1.0 47 | with: 48 | ssh-key: ${{ secrets.DEPLOY_KEY }} 49 | branch: gh-pages 50 | folder: documentation 51 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | 7 | test: 8 | strategy: 9 | matrix: 10 | os: [ubuntu-18.04, macos-latest] 11 | racket-variant: ['CS', 'BC'] 12 | racket-version: ['8.0', '8.1', '8.2', 'current'] 13 | 14 | runs-on: ${{ matrix.os }} 15 | 16 | steps: 17 | - uses: actions/checkout@v2 18 | - uses: Bogdanp/setup-racket@v1.5 19 | with: 20 | architecture: 'x64' 21 | distribution: 'full' 22 | variant: ${{ matrix.racket-variant }} 23 | version: ${{ matrix.racket-version }} 24 | - name: Install dependencies on Linux 25 | if: ${{ matrix.os == 'ubuntu-18.04' }} 26 | run: | 27 | sudo apt-get update 28 | sudo apt-get install -y g++ python cmake 29 | - name: Install dependencies on Macos 30 | if: ${{ matrix.os == 'macos-latest' }} 31 | run: brew install python cmake ninja 32 | - name: Compile binaryen 33 | run: | 34 | git clone --depth 1 https://github.com/WebAssembly/binaryen.git binaryen-src 35 | cd binaryen-src 36 | cmake . 37 | make -j2 38 | sudo make install 39 | - name: Install pkg 40 | run: raco pkg install -D --auto $PWD 41 | - name: Run unit tests 42 | run: raco test . 43 | - name: Run wingo_fact.scm with wingo-raw 44 | run: racket tests/wingo-raw.rkt tests/wingo-input/wingo_fact.scm 45 | - name: Run wingo_zero.scm with wingo-raw 46 | run: racket tests/wingo-raw.rkt tests/wingo-input/wingo_zero.scm 47 | - name: Run wingo_const.scm with wingo-raw 48 | run: racket tests/wingo-raw.rkt tests/wingo-input/wingo_const.scm 49 | - name: Run wingo_fact.scm with wingo 50 | run: racket tests/wingo.rkt tests/wingo-input/wingo_fact.scm 51 | - name: Run wingo_zero.scm with wingo 52 | run: racket tests/wingo.rkt tests/wingo-input/wingo_zero.scm 53 | - name: Run wingo_const.scm with wingo 54 | run: racket tests/wingo.rkt tests/wingo-input/wingo_const.scm 55 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | compiled/ 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![](.github/badges/SponsoredbyIgalia.svg)](https://www.igalia.com) 2 | [![CI](https://github.com/pmatos/racket-binaryen/workflows/Test/badge.svg?branch=main)](https://github.com/pmatos/racket-binaryen/actions) 3 | [![Scribble](https://img.shields.io/badge/Docs-Scribble-blue.svg)](https://pmatos.github.io/racket-binaryen) 4 | 5 | # racket-binaryen 6 | 7 | [Binaryen](https://github.com/WebAssembly/binaryen) bindings for [Racket](https://www.racket-lang.org). 8 | 9 | Currently, this work is experimental. There is some [initial documentation](https://pmatos.github.io/racket-binaryen) evolving together with the implementation of safe bindings but it's highly incomplete. 10 | 11 | Andy Wingo gave a ["Compiling to WebAssembly"](https://fosdem.org/2021/schedule/event/webassembly/) presentation at FOSDEM'21, and published his [artifacts](https://github.com/wingo/compiling-to-webassembly). 12 | 13 | I implemented the same compiler in Racket using the binaryen bindings (see `tests/wingo-raw.rkt`). To run it on the same example Andy presented try: 14 | 15 | ``` 16 | $ racket test/wingo-raw.rkt test/wingo_fact.scm 17 | "Compiled module:" 18 | (module 19 | (type $i32_=>_i32 (func (param i32) (result i32))) 20 | (export "fac" (func $fac)) 21 | (func $fac (param $0 i32) (result i32) 22 | (if (result i32) 23 | (i32.eqz 24 | (local.get $0) 25 | ) 26 | (i32.const 1) 27 | (i32.mul 28 | (local.get $0) 29 | (call $fac 30 | (i32.sub 31 | (local.get $0) 32 | (i32.const 1) 33 | ) 34 | ) 35 | ) 36 | ) 37 | ) 38 | ) 39 | "Optimized module:" 40 | (module 41 | (type $i32_=>_i32 (func (param i32) (result i32))) 42 | (export "fac" (func $fac)) 43 | (func $fac (; has Stack IR ;) (param $0 i32) (result i32) 44 | (if (result i32) 45 | (local.get $0) 46 | (i32.mul 47 | (call $fac 48 | (i32.sub 49 | (local.get $0) 50 | (i32.const 1) 51 | ) 52 | ) 53 | (local.get $0) 54 | ) 55 | (i32.const 1) 56 | ) 57 | ) 58 | ) 59 | ``` 60 | -------------------------------------------------------------------------------- /common.rkt: -------------------------------------------------------------------------------- 1 | #lang typed/racket/base 2 | ;; --------------------------------------------------------------------------------------------------- 3 | 4 | (provide fits-int? fits-uint?) 5 | 6 | ;; --------------------------------------------------------------------------------------------------- 7 | 8 | (: fits-int? (-> Integer Integer Boolean)) 9 | (define (fits-int? n bits) 10 | (<= (expt 2 (- bits 1)) 11 | n 12 | (- (expt 2 (- bits 1)) 1))) 13 | 14 | (: fits-uint? (-> Integer Integer Boolean)) 15 | (define (fits-uint? n bits) 16 | (<= 0 17 | n 18 | (- (expt 2 bits) 1))) 19 | -------------------------------------------------------------------------------- /exports.rkt: -------------------------------------------------------------------------------- 1 | #lang racket/base 2 | ;; --------------------------------------------------------------------------------------------------- 3 | 4 | (require "private/binaryen-ffi.rkt" 5 | "modules.rkt" 6 | racket/contract) 7 | 8 | (provide 9 | module-export-function) 10 | 11 | ;; --------------------------------------------------------------------------------------------------- 12 | 13 | (struct export (ref)) 14 | 15 | (define/contract (module-export-function internal external 16 | #:module [mod (current-module)]) 17 | ((string? string?) (#:module module?) . ->* . export?) 18 | (export 19 | (BinaryenAddFunctionExport (module-ref mod) internal external))) 20 | 21 | 22 | ;; --------------------------------------------------------------------------------------------------- 23 | 24 | (module+ test 25 | 26 | (require rackunit) 27 | 28 | (test-case "pass" 29 | (check-true #true))) 30 | -------------------------------------------------------------------------------- /expressions.rkt: -------------------------------------------------------------------------------- 1 | #lang racket/base 2 | ;; --------------------------------------------------------------------------------------------------- 3 | 4 | (require "private/binaryen-ffi.rkt" 5 | "private/types.rkt" 6 | "modules.rkt" 7 | "literals.rkt" 8 | "types.rkt" 9 | "indices.rkt" 10 | (for-syntax racket/base racket/syntax) 11 | racket/contract) 12 | 13 | (provide expression? 14 | expression-ref 15 | if-expression? 16 | const-expression? 17 | binary-expression? 18 | unary-expression? 19 | localget-expression? 20 | localset-expression? 21 | localtee-expression? 22 | make-call 23 | make-call-indirect 24 | make-return-call 25 | 26 | ;; block 27 | make-block 28 | block-name 29 | set-block-name! 30 | block-children-count 31 | block-children-ref 32 | block-children-append 33 | 34 | ;; load 35 | make-load 36 | load-atomic? 37 | set-load-atomic! 38 | load-signed? 39 | set-load-signed! 40 | load-offset 41 | set-load-offset! 42 | load-bytes 43 | set-load-bytes! 44 | load-align 45 | set-load-align! 46 | load-ptr 47 | set-load-ptr! 48 | 49 | make-store 50 | make-if 51 | make-const 52 | make-localget 53 | make-localset 54 | make-localtee 55 | make-globalget 56 | make-globalset) 57 | 58 | ;; --------------------------------------------------------------------------------------------------- 59 | 60 | ; Capitalize helper 61 | ; n is the size of the prefix to capitalize 62 | (define-for-syntax (upcase sym [n 1]) 63 | (define pat (format "^~a" (make-string n #\.))) 64 | (regexp-replace (regexp pat) (symbol->string sym) string-upcase)) 65 | 66 | (define-for-syntax (downcase sym) 67 | (string-downcase (symbol->string sym))) 68 | 69 | ;; --------------------------------------------------------------------------------------------------- 70 | 71 | (struct expression (ref)) 72 | 73 | (struct unary-expression expression ()) 74 | 75 | (define-syntax (define-unary-op stx) 76 | (syntax-case stx () 77 | [(_ name (sfxs ...)) 78 | #`(define-unary-op name (sfxs ...) #:binaryen-name #,(upcase (syntax->datum #'name)))] 79 | [(_ name (sfxs ...) #:binaryen-name bname) 80 | #`(define-unary-op name (sfxs ...) 81 | #:binaryen-name bname 82 | #:suffix-upcase 1)] 83 | [(_ name (sfxs ...) #:suffix-upcase n) 84 | #`(define-unary-op name (sfxs ...) 85 | #:binaryen-name #,(upcase (syntax->datum #'name)) 86 | #:suffix-upcase n)] 87 | [(_ name (sfxs ...) #:binaryen-name bname #:suffix-upcase n) 88 | #`(begin 89 | #,@(for/list ([sfx (in-list (syntax->list #'(sfxs ...)))]) 90 | (with-syntax ([fnname (format-id sfx "make-~a-~a" 91 | (syntax->datum #'name) 92 | (syntax->datum sfx))] 93 | [binaryenop (format-id sfx "Binaryen~a~a" 94 | (syntax->datum #'bname) 95 | (upcase (syntax->datum sfx) 96 | (syntax->datum #'n)))]) 97 | #'(begin 98 | (define/contract (fnname x #:module [mod (current-module)]) 99 | ((expression?) (#:module module?) . ->* . unary-expression?) 100 | (unary-expression 101 | (BinaryenUnary (module-ref mod) (binaryenop) (expression-ref x)))) 102 | (provide fnname)))))])) 103 | 104 | (define-syntax (define-unary-op/raw stx) 105 | (syntax-case stx () 106 | [(_ name (sfxs ...)) 107 | #`(begin 108 | #,@(for/list ([sfx (in-list (syntax->list #'(sfxs ...)))]) 109 | (with-syntax ([fnname (format-id sfx "make-~a-~a" 110 | (downcase (syntax->datum #'name)) 111 | (downcase (syntax->datum sfx)))] 112 | [binaryenop (format-id sfx "Binaryen~a~a" 113 | (syntax->datum #'name) 114 | (syntax->datum sfx))]) 115 | #'(begin 116 | (define/contract (fnname x #:module [mod (current-module)]) 117 | ((expression?) (#:module module?) . ->* . unary-expression?) 118 | (unary-expression 119 | (BinaryenUnary (module-ref mod) (binaryenop) (expression-ref x)))) 120 | (provide fnname)))))])) 121 | 122 | 123 | ; int 124 | (define-unary-op clz (int32 int64)) 125 | (define-unary-op ctz (int32 int64)) 126 | (define-unary-op popcnt (int32 int64)) 127 | 128 | ; float 129 | (define-unary-op neg (float32 float64)) 130 | (define-unary-op abs (float32 float64)) 131 | (define-unary-op ceil (float32 float64)) 132 | (define-unary-op floor (float32 float64)) 133 | (define-unary-op nearest (float32 float64)) 134 | (define-unary-op sqrt (float32 float64)) 135 | 136 | ; relational 137 | (define-unary-op eqz (int32 int64) 138 | #:binaryen-name EqZ) 139 | 140 | ; conversions 141 | (define-unary-op extend (sint32 uint32) 142 | #:suffix-upcase 2) 143 | ; i64 to i32 144 | (define-unary-op wrap (int64)) 145 | 146 | ; float to int 147 | (define-unary-op/raw Trunc (SFloat32ToInt32 148 | SFloat32ToInt64 149 | UFloat32ToInt32 150 | UFloat32ToInt64 151 | SFloat64ToInt32 152 | SFloat64ToInt64 153 | UFloat64ToInt32 154 | UFloat64ToInt64)) 155 | 156 | ; reintepret bits to int 157 | (define-unary-op reinterpret (float32 float64)) 158 | 159 | ; int to float 160 | (define-unary-op/raw Convert (SInt32ToFloat32 161 | SInt32ToFloat64 162 | UInt32ToFloat32 163 | UInt32ToFloat64 164 | SInt64ToFloat32 165 | SInt64ToFloat64 166 | UInt64ToFloat32 167 | UInt64ToFloat64)) 168 | 169 | ; f32 to f64 170 | (define-unary-op promote (float32)) 171 | 172 | ; f64 to f32 173 | (define-unary-op demote (float64)) 174 | 175 | ; reinterpret bits to float 176 | (define-unary-op reinterpret (int32 int64)) 177 | 178 | ; Extend signed subword-sized integer. This differs from e.g. ExtendSInt32 179 | ; because the input integer is in an i64 value insetad of an i32 value. 180 | (define-unary-op/raw Extend (S8Int32 181 | S16Int32 182 | S8Int64 183 | S16Int64 184 | S32Int64)) 185 | 186 | ; Saturating float-to-int 187 | (define-unary-op/raw TruncSat (SFloat32ToInt32 188 | UFloat32ToInt32 189 | SFloat64ToInt32 190 | UFloat64ToInt32 191 | SFloat32ToInt64 192 | UFloat32ToInt64 193 | SFloat64ToInt64 194 | UFloat64ToInt64)) 195 | 196 | ; SIMD splats 197 | (define-unary-op/raw Splat (VecI8x16 198 | VecI16x8 199 | VecI32x4 200 | VecI64x2 201 | VecF32x4 202 | VecF64x2)) 203 | 204 | ;; SIMD arithmetic 205 | (define-unary-op not (vec128)) 206 | (define-unary-op/raw AnyTrue (Vec128)) 207 | (define-unary-op/raw Abs (VecI8x16 VecI16x8 VecI32x4 VecI64x2 VecF32x4 VecF64x2)) 208 | (define-unary-op/raw Neg (VecI8x16 VecI16x8 VecI32x4 VecI64x2 VecF32x4 VecF64x2)) 209 | (define-unary-op/raw AllTrue (VecI8x16 VecI16x8 VecI32x4 VecI64x2)) 210 | (define-unary-op/raw Bitmask (VecI8x16 VecI16x8 VecI32x4 VecI64x2)) 211 | (define-unary-op/raw Popcnt (VecI8x16)) 212 | (define-unary-op/raw Sqrt (VecF32x4 VecF64x2)) 213 | (define-unary-op/raw Ceil (VecF32x4 VecF64x2)) 214 | (define-unary-op/raw Floor (VecF32x4 VecF64x2)) 215 | (define-unary-op/raw Trunc (VecF32x4 VecF64x2)) 216 | (define-unary-op/raw Nearest (VecF32x4 VecF64x2)) 217 | (define-unary-op/raw ExtAddPairwise (SVecI8x16ToI16x8 218 | UVecI8x16ToI16x8 219 | SVecI16x8ToI32x4 220 | UVecI16x8ToI32x4)) 221 | 222 | ;; SIMD conversions 223 | 224 | (define-unary-op/raw TruncSat (SVecF32x4ToVecI32x4 UVecF32x4ToVecI32x4)) 225 | (define-unary-op/raw Convert (SVecI32x4ToVecF32x4 UVecI32x4ToVecF32x4)) 226 | (define-unary-op/raw ExtendLow (SVecI8x16ToVecI16x8 227 | UVecI8x16ToVecI16x8 228 | SVecI16x8ToVecI32x4 229 | UVecI16x8ToVecI32x4 230 | SVecI32x4ToVecI64x2 231 | UVecI32x4ToVecI64x2)) 232 | (define-unary-op/raw ExtendHigh (SVecI8x16ToVecI16x8 233 | UVecI8x16ToVecI16x8 234 | SVecI16x8ToVecI32x4 235 | UVecI16x8ToVecI32x4 236 | SVecI32x4ToVecI64x2 237 | UVecI32x4ToVecI64x2)) 238 | (define-unary-op/raw ConvertLow (SVecI32x4ToVecF64x2 UVecI32x4ToVecF64x2)) 239 | (define-unary-op/raw TruncSatZero (SVecF64x2ToVecI32x4 UVecF64x2ToVecI32x4)) 240 | (define-unary-op/raw DemoteZero (VecF64x2ToVecF32x4)) 241 | (define-unary-op/raw PromoteLow (VecF32x4ToVecF64x2)) 242 | 243 | ;; --------------------------------------------------------------------------------------------------- 244 | 245 | (define-syntax (define-binary-op/raw stx) 246 | (syntax-case stx () 247 | [(_ name (sfxs ...)) 248 | #`(begin 249 | #,@(for/list ([sfx (in-list (syntax->list #'(sfxs ...)))]) 250 | (with-syntax ([fnname (format-id sfx "make-~a-~a" 251 | (downcase (syntax->datum #'name)) 252 | (downcase (syntax->datum sfx)))] 253 | [binaryenop (format-id sfx "Binaryen~a~a" 254 | (syntax->datum #'name) 255 | (syntax->datum sfx))]) 256 | #'(begin 257 | (define/contract (fnname x y #:module [mod (current-module)]) 258 | ((expression? expression?) (#:module module?) . ->* . binary-expression?) 259 | (binary-expression 260 | (BinaryenBinary (module-ref mod) (binaryenop) (expression-ref x) (expression-ref y)))) 261 | (provide fnname)))))])) 262 | 263 | (struct binary-expression expression ()) 264 | 265 | (define-binary-op/raw Add (Int32 Int64 Float32 Float64)) 266 | (define-binary-op/raw Sub (Int32 Int64 Float32 Float64)) 267 | (define-binary-op/raw Mul (Int32 Int64 Float32 Float64)) 268 | 269 | (define-binary-op/raw Div (SInt32 UInt32 SInt64 UInt64 Float32 Float64)) 270 | (define-binary-op/raw Rem (SInt32 UInt32 SInt64 UInt64)) 271 | (define-binary-op/raw And (Int32 Int64)) 272 | (define-binary-op/raw Or (Int32 Int64)) 273 | (define-binary-op/raw Xor (Int32 Int64)) 274 | (define-binary-op/raw Shl (Int32 Int64)) 275 | 276 | (define-binary-op/raw CopySign (Float32 Float64)) 277 | (define-binary-op/raw Min (Float32 Float64)) 278 | (define-binary-op/raw Max (Float32 Float64)) 279 | 280 | (define-binary-op/raw Shr (SInt32 UInt32 SInt64 UInt64)) 281 | (define-binary-op/raw RotL (Int32 Int64)) 282 | (define-binary-op/raw RotR (Int32 Int64)) 283 | 284 | (define-binary-op/raw Eq (Int32 Int64 Float32 Float64)) 285 | (define-binary-op/raw Ne (Int32 Int64 Float32 Float64)) 286 | 287 | (define-binary-op/raw Lt (SInt32 UInt32 SInt64 UInt64 Float32 Float64)) 288 | (define-binary-op/raw Le (SInt32 UInt32 SInt64 UInt64 Float32 Float64)) 289 | (define-binary-op/raw Gt (SInt32 UInt32 SInt64 UInt64 Float32 Float64)) 290 | (define-binary-op/raw Ge (SInt32 UInt32 SInt64 UInt64 Float32 Float64)) 291 | 292 | ;; --------------------------------------------------------------------------------------------------- 293 | 294 | (struct call-expression expression ()) 295 | 296 | (define/contract (make-call name operands return-type #:module [mod (current-module)]) 297 | ((string? (listof expression?) type?) (#:module module?) . ->* . call-expression?) 298 | (call-expression 299 | (BinaryenCall (module-ref mod) 300 | name 301 | (map expression-ref operands) 302 | (type-ref return-type)))) 303 | 304 | ;; --------------------------------------------------------------------------------------------------- 305 | 306 | (struct call-indirect-expression expression ()) 307 | 308 | (define/contract (make-call-indirect table target operands params results #:module [mod (current-module)]) 309 | ((string? expression? (listof expression?) (listof type?) (listof type?)) (#:module module?) . ->* . call-indirect-expression?) 310 | (call-indirect-expression 311 | (BinaryenCallIndirect (module-ref mod) 312 | table 313 | (expression-ref target) 314 | (map expression-ref operands) 315 | (map type-ref params) 316 | (map type-ref results)))) 317 | 318 | ;; --------------------------------------------------------------------------------------------------- 319 | 320 | (struct return-call-expression expression ()) 321 | 322 | (define/contract (make-return-call target operands return-type #:module [mod (current-module)]) 323 | ((string? (listof expression?) type?) (#:module module?) . ->* . return-call-expression?) 324 | (return-call-expression 325 | (BinaryenReturnCall (module-ref mod) 326 | target 327 | (expression-ref target) 328 | (map expression-ref operands) 329 | (type-ref return-type)))) 330 | 331 | ;; --------------------------------------------------------------------------------------------------- 332 | 333 | (struct if-expression expression ()) 334 | 335 | (define/contract (make-if cnd thn els #:module [mod (current-module)]) 336 | ((expression? expression? expression?) (#:module module?) . ->* . if-expression?) 337 | (if-expression 338 | (BinaryenIf (module-ref mod) 339 | (expression-ref cnd) 340 | (expression-ref thn) 341 | (expression-ref els)))) 342 | 343 | ;; --------------------------------------------------------------------------------------------------- 344 | 345 | (struct const-expression expression ()) 346 | 347 | (define/contract (make-const literal #:module [mod (current-module)]) 348 | ((literal?) (#:module module?) . ->* . const-expression?) 349 | (const-expression 350 | (BinaryenConst (module-ref mod) (literal-ref literal)))) 351 | 352 | ;; --------------------------------------------------------------------------------------------------- 353 | 354 | (struct localget-expression expression ()) 355 | 356 | (define/contract (make-localget idx type #:module [mod (current-module)]) 357 | ((index? type?) (#:module module?) . ->* . localget-expression?) 358 | (localget-expression 359 | (BinaryenLocalGet (module-ref mod) 360 | idx 361 | (type-ref type)))) 362 | 363 | ;; --------------------------------------------------------------------------------------------------- 364 | 365 | (struct localset-expression expression ()) 366 | 367 | (define/contract (make-localset idx exp #:module [mod (current-module)]) 368 | ((index? expression?) (#:module module?) . ->* . localset-expression?) 369 | (localtee-expression 370 | (BinaryenLocalSet (module-ref mod) 371 | idx 372 | (expression-ref exp)))) 373 | 374 | ;; --------------------------------------------------------------------------------------------------- 375 | 376 | (struct localtee-expression expression ()) 377 | 378 | (define/contract (make-localtee idx exp type #:module [mod (current-module)]) 379 | ((index? expression? type?) (#:module module?) . ->* . localtee-expression?) 380 | (localtee-expression 381 | (BinaryenLocalTee (module-ref mod) 382 | idx 383 | (expression-ref exp) 384 | (type-ref type)))) 385 | 386 | ;; --------------------------------------------------------------------------------------------------- 387 | 388 | (struct globalget-expression expression ()) 389 | 390 | (define/contract (make-globalget str type #:module [mod (current-module)]) 391 | ((string? type?) (#:module module?) . ->* . globalget-expression?) 392 | (globalget-expression 393 | (BinaryenGlobalGet (module-ref mod) 394 | str 395 | (type-ref type)))) 396 | 397 | ;; --------------------------------------------------------------------------------------------------- 398 | 399 | (struct globalset-expression expression ()) 400 | 401 | (define/contract (make-globalset str exp #:module [mod (current-module)]) 402 | ((string? expression?) (#:module module?) . ->* . globalset-expression?) 403 | (globalset-expression 404 | (BinaryenGlobalSet (module-ref mod) 405 | str 406 | (expression-ref exp)))) 407 | 408 | ;; --------------------------------------------------------------------------------------------------- 409 | 410 | (struct block-expression expression ()) 411 | 412 | (define/contract (make-block name exps type #:module [mod (current-module)]) 413 | ((string? (listof expression?) type?) (#:module module?) . ->* . block-expression?) 414 | (block-expression 415 | (BinaryenBlock (module-ref mod) 416 | name 417 | exps 418 | type))) 419 | 420 | (define/contract (block-name blk) 421 | (block-expression? . -> . string?) 422 | (BinaryenBlockGetName (expression-ref blk))) 423 | 424 | (define/contract (set-block-name! blk name) 425 | (block-expression? string? . -> . void?) 426 | (BinaryenBlockSetName (expression-ref blk) name)) 427 | 428 | (define/contract (block-children-count blk) 429 | (block-expression? . -> . exact-nonnegative-integer?) 430 | (BinaryenBlockGetNumChildren (expression-ref blk))) 431 | 432 | (define/contract (block-children-ref blk idx) 433 | (block-expression? exact-nonnegative-integer? . -> . expression?) 434 | (expression (BinaryenBlockGetChildAt (expression-ref blk) idx))) 435 | 436 | (define/contract (block-children-append blk chd) 437 | (block-expression? expression? . -> . exact-nonnegative-integer?) 438 | (BinaryenBlockAppendChild (expression-ref blk) (expression-ref chd))) 439 | 440 | ;; --------------------------------------------------------------------------------------------------- 441 | 442 | (struct load-expression expression ()) 443 | 444 | (define/contract (make-load bytes signed? offset align type ptr #:module [mod (current-module)]) 445 | ((exact-nonnegative-integer? boolean? exact-nonnegative-integer? exact-nonnegative-integer? type? expression?) (#:module module?) . ->* . load-expression?) 446 | (load-expression 447 | (BinaryenLoad (module-ref mod) 448 | bytes signed? offset align 449 | (type-ref type) 450 | (expression-ref ptr)))) 451 | 452 | 453 | (define/contract (load-atomic? ld) 454 | (load-expression? . -> . boolean?) 455 | (BinaryenLoadIsAtomic (expression-ref ld))) 456 | 457 | (define/contract (set-load-atomic! ld atomic?) 458 | (load-expression? boolean? . -> . void?) 459 | (BinaryenLoadSetAtomic (expression-ref ld) atomic?)) 460 | 461 | (define/contract (load-signed? ld) 462 | (load-expression? . -> . boolean?) 463 | (BinaryenLoadIsSigned (expression-ref ld))) 464 | 465 | (define/contract (set-load-signed! ld signed?) 466 | (load-expression? boolean? . -> . void?) 467 | (BinaryenLoadSetSigned (expression-ref ld) signed?)) 468 | 469 | (define/contract (load-offset ld) 470 | (load-expression? . -> . exact-nonnegative-integer?) 471 | (BinaryenLoadGetOffset (expression-ref ld))) 472 | 473 | (define/contract (set-load-offset! ld offset) 474 | (load-expression? exact-nonnegative-integer? . -> . void?) 475 | (BinaryenLoadSetOffset (expression-ref ld) offset)) 476 | 477 | (define/contract (load-bytes ld) 478 | (load-expression? . -> . exact-nonnegative-integer?) 479 | (BinaryenLoadGetBytes (expression-ref ld))) 480 | 481 | (define/contract (set-load-bytes! ld bytes) 482 | (load-expression? exact-nonnegative-integer? . -> . void?) 483 | (BinaryenLoadSetBytes (expression-ref ld) bytes)) 484 | 485 | (define/contract (load-align ld) 486 | (load-expression? . -> . exact-nonnegative-integer?) 487 | (BinaryenLoadGetAlign (expression-ref ld))) 488 | 489 | (define/contract (set-load-align! ld align) 490 | (load-expression? exact-nonnegative-integer? . -> . void?) 491 | (BinaryenLoadSetAlign (expression-ref ld) align)) 492 | 493 | (define/contract (load-ptr ld) 494 | (load-expression? . -> . expression?) 495 | (expression (BinaryenLoadGetPtr (expression-ref ld)))) 496 | 497 | (define/contract (set-load-ptr! ld ptr) 498 | (load-expression? expression? . -> . void?) 499 | (BinaryenLoadSetPtr (expression-ref ld) (expression-ref ptr))) 500 | 501 | ;; --------------------------------------------------------------------------------------------------- 502 | 503 | (struct store-expression expression ()) 504 | 505 | (define/contract (make-store bytes offset align ptr value type #:module [mod (current-module)]) 506 | ((exact-nonnegative-integer? exact-nonnegative-integer? exact-nonnegative-integer? expression? expression? type?) (#:module module?) . ->* . store-expression?) 507 | (store-expression 508 | (BinaryenStore (module-ref mod) 509 | bytes offset align 510 | (expression-ref ptr) 511 | (expression-ref value) 512 | (type-ref type)))) 513 | 514 | ;; --------------------------------------------------------------------------------------------------- 515 | 516 | (module+ test 517 | 518 | (require rackunit) 519 | 520 | (test-case "pass" 521 | (check-true #true))) 522 | -------------------------------------------------------------------------------- /features.rkt: -------------------------------------------------------------------------------- 1 | #lang racket/base 2 | ;; --------------------------------------------------------------------------------------------------- 3 | 4 | (require "private/binaryen-ffi.rkt" 5 | "private/features.rkt" 6 | "private/modules.rkt" 7 | racket/contract) 8 | 9 | (provide 10 | feature-mvp 11 | feature-atomics 12 | feature-bulk-memory 13 | feature-mutable-globals 14 | feature-nontrapping-fptoint 15 | feature-sign-extension 16 | feature-simd128 17 | feature-exception-handling 18 | feature-tail-call 19 | feature-reference-types 20 | feature-multivalue 21 | feature-gc 22 | feature-memory64 23 | feature-typed-function-references 24 | feature-all 25 | 26 | module-features 27 | set-module-features! 28 | 29 | feature? 30 | ) 31 | 32 | ;; --------------------------------------------------------------------------------------------------- 33 | 34 | (define feature-mvp (feature (BinaryenFeatureMVP))) 35 | (define feature-atomics (feature (BinaryenFeatureAtomics))) 36 | (define feature-bulk-memory (feature (BinaryenFeatureBulkMemory))) 37 | (define feature-mutable-globals (feature (BinaryenFeatureMutableGlobals))) 38 | (define feature-nontrapping-fptoint (feature (BinaryenFeatureNontrappingFPToInt))) 39 | (define feature-sign-extension (feature (BinaryenFeatureSignExt))) 40 | (define feature-simd128 (feature (BinaryenFeatureSIMD128))) 41 | (define feature-exception-handling (feature (BinaryenFeatureExceptionHandling))) 42 | (define feature-tail-call (feature (BinaryenFeatureTailCall))) 43 | (define feature-reference-types (feature (BinaryenFeatureReferenceTypes))) 44 | (define feature-multivalue (feature (BinaryenFeatureMultivalue))) 45 | (define feature-gc (feature (BinaryenFeatureGC))) 46 | (define feature-memory64 (feature (BinaryenFeatureMemory64))) 47 | (define feature-typed-function-references (feature (BinaryenFeatureTypedFunctionReferences))) 48 | 49 | (define feature-all (list feature-mvp 50 | feature-atomics 51 | feature-bulk-memory 52 | feature-mutable-globals 53 | feature-nontrapping-fptoint 54 | feature-sign-extension 55 | feature-simd128 56 | feature-exception-handling 57 | feature-tail-call 58 | feature-reference-types 59 | feature-multivalue 60 | feature-gc 61 | feature-memory64 62 | feature-typed-function-references)) 63 | 64 | (define (features-contains? features f) 65 | (not (= (bitwise-and (feature-ref features) (feature-ref f)) 0))) 66 | 67 | (define (features->mask features) 68 | (for/fold ([mask 0]) 69 | ([f (in-list features)]) 70 | (bitwise-ior mask (feature-ref f)))) 71 | 72 | (define (mask->features mask) 73 | (filter (lambda (f) (= (feature-ref f) 74 | (bitwise-and (feature-ref f) mask))) 75 | feature-all)) 76 | 77 | (define/contract (module-features [mod (current-module)]) 78 | (() (module?) . ->* . (listof feature?)) 79 | (mask->features 80 | (BinaryenModuleGetFeatures (module-ref mod)))) 81 | 82 | (define/contract (set-module-features! features #:module [mod (current-module)]) 83 | (((listof feature?)) (#:module module?) . ->* . void?) 84 | (BinaryenModuleSetFeatures (module-ref mod) (features->mask features))) 85 | 86 | ;; --------------------------------------------------------------------------------------------------- 87 | 88 | (module+ test 89 | 90 | (require rackunit) 91 | 92 | (test-case "pass" 93 | (check-true #true))) 94 | -------------------------------------------------------------------------------- /functions.rkt: -------------------------------------------------------------------------------- 1 | #lang racket/base 2 | ;; --------------------------------------------------------------------------------------------------- 3 | 4 | (require "private/binaryen-ffi.rkt" 5 | "private/functions.rkt" 6 | "private/types.rkt" 7 | "expressions.rkt" 8 | "modules.rkt" 9 | racket/contract) 10 | 11 | (provide 12 | module-add-function 13 | module-function-count 14 | function-name 15 | function-parameter-types 16 | function-result-types 17 | function-variable-type 18 | (contract-out 19 | [function-variable-count 20 | (function? . -> . exact-nonnegative-integer?)] 21 | 22 | [module-function 23 | (->i ([n (mod) (or/c string? 24 | (and/c exact-nonnegative-integer? 25 | (* (string? (listof type?) (listof type?) (listof type?) expression?) (#:module module?) 34 | function?) 35 | (function 36 | (BinaryenAddFunction (module-ref mod) 37 | name 38 | (type-ref (type-create arg-types)) 39 | (type-ref (type-create result-types)) 40 | (map type-ref var-types) 41 | (expression-ref body)))) 42 | 43 | (define/contract (module-function-count [mod (current-module)]) 44 | (() (module?) . ->* . exact-positive-integer?) 45 | (BinaryenGetNumFunctions (module-ref mod))) 46 | 47 | (define (module-function n [mod (current-module)]) 48 | (function 49 | (if (string? n) 50 | (BinaryenGetFunction (module-ref mod) n) 51 | (BinaryenGetFunctionByIndex (module-ref mod) n)))) 52 | 53 | (define/contract (function-name f) 54 | (function? . -> . string?) 55 | (BinaryenFunctionGetName (function-ref f))) 56 | 57 | (define/contract (function-parameter-types f) 58 | (function? . -> . (listof type?)) 59 | (type-expand 60 | (type 61 | (BinaryenFunctionGetParams (function-ref f))))) 62 | 63 | (define/contract (function-result-types f) 64 | (function? . -> . (listof type?)) 65 | (type-expand 66 | (type 67 | (BinaryenFunctionGetResults (function-ref f))))) 68 | 69 | (define (function-variable-count f) 70 | (BinaryenFunctionGetNumVars (function-ref f))) 71 | 72 | (define/contract (function-variable-type f n) 73 | (->i ([f function?] 74 | [n (f) (and/c exact-positive-integer? 75 | ( . exact-nonnegative-integer?) 81 | (BinaryenFunctionGetNumLocals (function-ref f))) 82 | 83 | (define/contract (function-local-has-name? f n) 84 | (function? exact-nonnegative-integer? . -> . boolean?) 85 | (BinaryenFunctionHasLocalName (function-ref f) n)) 86 | 87 | ;; --------------------------------------------------------------------------------------------------- 88 | 89 | (module+ test 90 | 91 | (require rackunit 92 | "test-utils.rkt") 93 | 94 | (test-case "Module Function Check" 95 | (with-test-mod 96 | '(module 97 | (func (export "this_is_zero") (result i32) 98 | (i32.const 0))) 99 | (check = 1 (module-function-count)) 100 | (check = 0 (function-variable-count (module-function 0))))) 101 | 102 | 103 | (test-case "pass" 104 | (check-true #true))) 105 | -------------------------------------------------------------------------------- /indices.rkt: -------------------------------------------------------------------------------- 1 | #lang racket/base 2 | ;; --------------------------------------------------------------------------------------------------- 3 | 4 | (require racket/contract 5 | "common.rkt") 6 | 7 | (provide index?) 8 | 9 | ;; --------------------------------------------------------------------------------------------------- 10 | 11 | (define/contract (index? v) 12 | (any/c . -> . boolean?) 13 | (and (exact-integer? v) (fits-uint? v 32))) 14 | 15 | ;; --------------------------------------------------------------------------------------------------- 16 | 17 | (module+ test 18 | 19 | (require rackunit) 20 | 21 | (test-case "pass" 22 | (check-true #true))) 23 | -------------------------------------------------------------------------------- /info.rkt: -------------------------------------------------------------------------------- 1 | #lang info 2 | 3 | (define version "0.1") 4 | 5 | (define collection "binaryen") 6 | 7 | (define scribblings 8 | '(("scribblings/binaryen.scrbl" (multi-page)))) 9 | 10 | (define deps 11 | (list "base")) 12 | 13 | (define build-deps 14 | (list "reprovide-lang-lib")) 15 | 16 | (define compile-omit-paths '("tests")) 17 | 18 | (define test-omit-paths 19 | (list 20 | "info.rkt" 21 | "tests/" 22 | "private/" 23 | #rx"\\.scrbl$")) 24 | -------------------------------------------------------------------------------- /literals.rkt: -------------------------------------------------------------------------------- 1 | #lang racket/base 2 | ;; --------------------------------------------------------------------------------------------------- 3 | 4 | (require "private/binaryen-ffi.rkt" 5 | "modules.rkt" 6 | racket/contract) 7 | 8 | (provide literal? 9 | literal-ref 10 | make-literal-int32) 11 | 12 | ;; --------------------------------------------------------------------------------------------------- 13 | 14 | (struct literal (ref)) 15 | 16 | (define/contract (make-literal-int32 x) 17 | ((integer-in -2147483648 2147483647) . -> . literal?) 18 | (literal 19 | (BinaryenLiteralInt32 x))) 20 | 21 | ;; --------------------------------------------------------------------------------------------------- 22 | 23 | (module+ test 24 | 25 | (require rackunit) 26 | 27 | (test-case "pass" 28 | (check-true #true))) 29 | -------------------------------------------------------------------------------- /main.rkt: -------------------------------------------------------------------------------- 1 | #lang reprovide 2 | ;; --------------------------------------------------------------------------------------------------- 3 | 4 | ;; The following filenames are sorted alphabetically 5 | ;; - keep them that way. 6 | "exports.rkt" 7 | "expressions.rkt" 8 | "features.rkt" 9 | "functions.rkt" 10 | "indices.rkt" 11 | "literals.rkt" 12 | "modules.rkt" 13 | "optimizations.rkt" 14 | "types.rkt" 15 | -------------------------------------------------------------------------------- /modules.rkt: -------------------------------------------------------------------------------- 1 | #lang racket/base 2 | ;; --------------------------------------------------------------------------------------------------- 3 | 4 | (require "private/binaryen-ffi.rkt" 5 | "private/modules.rkt" 6 | racket/contract) 7 | 8 | (provide 9 | module? 10 | module-ref 11 | module-create 12 | module-valid? 13 | module-print 14 | module-optimize! 15 | module-read 16 | (contract-out 17 | [module-parse (string? . -> . module?)] 18 | [current-module (parameter/c (or/c #false module?))]) 19 | module-write) 20 | 21 | ;; --------------------------------------------------------------------------------------------------- 22 | 23 | (define/contract (module-create) 24 | (-> module?) 25 | (make-module (BinaryenModuleCreate))) 26 | 27 | (define/contract (module-valid? [mod (current-module)]) 28 | (() (module?) . ->* . boolean?) 29 | (BinaryenModuleValidate (module-ref mod))) 30 | 31 | (define/contract (module-print [mod (current-module)]) 32 | (() (module?) . ->* . void?) 33 | ;; This should be using BinaryenModulePrint, but it doesn't because there's no 34 | ;; straightforward way in racket to redirect the stdout to current-output-port. 35 | ;; See: https://groups.google.com/g/racket-users/c/c3RaYvSD4nE 36 | ;; We use BinaryenModuleAllocateAndWriteText 37 | ;; This is not the same as BinaryenModulePrint because this function uses 38 | ;; syntax highlighting that's lost when you use BinaryenModuleAllocateAndWriteText 39 | ;; FIXME In the future, it might be useful to revisit this issue. 40 | (fprintf (current-output-port) "~a" 41 | (bytes->string/utf-8 (module-write mod #true)))) 42 | 43 | (define/contract (module-optimize! [mod (current-module)]) 44 | (() (module?) . ->* . void?) 45 | (BinaryenModuleOptimize (module-ref mod))) 46 | 47 | (define/contract (module-read in) 48 | (bytes? . -> . module?) 49 | (make-module (BinaryenModuleRead in))) 50 | 51 | (define/contract (module-write mod textual? #:sourcemap [sm #false]) 52 | ((module? boolean?) (#:sourcemap (or/c string? #false)) . ->* . bytes?) 53 | (if textual? 54 | (string->bytes/utf-8 (BinaryenModuleAllocateAndWriteText (module-ref mod))) 55 | (BinaryenModuleAllocateAndWriteResult-binary (BinaryenModuleAllocateAndWrite (module-ref mod) sm)))) 56 | 57 | ;; --------------------------------------------------------------------------------------------------- 58 | 59 | (module+ test 60 | 61 | (require rackunit 62 | "test-utils.rkt" 63 | racket/port) 64 | 65 | (test-case "Module creation" 66 | (void 67 | (for/list ([i (in-range 1000)]) 68 | (module-create)))) 69 | 70 | (test-case "Module Parsing" 71 | (with-test-mod 72 | '(module 73 | (func (export "this_is_zero") (result i32) 74 | (i32.const 0))) 75 | 76 | (check-true (module-valid?)))) 77 | 78 | (test-case "Module Printing" 79 | (with-test-mod 80 | '(module 81 | (func (export "this_is_zero") (result i32) 82 | (i32.const 0))) 83 | 84 | (check-true (> (string-length (with-output-to-string 85 | (lambda () (module-print)))) 86 | 0)))) 87 | 88 | (test-case "pass" 89 | (check-true #true))) 90 | -------------------------------------------------------------------------------- /optimizations.rkt: -------------------------------------------------------------------------------- 1 | #lang racket/base 2 | ;; --------------------------------------------------------------------------------------------------- 3 | 4 | (require racket/contract 5 | "private/binaryen-ffi.rkt") 6 | 7 | (provide optimize-level? 8 | shrink-level? 9 | optimize-level 10 | shrink-level 11 | set-optimize-level! 12 | set-shrink-level! 13 | with-optimize-level 14 | with-shrink-level) 15 | 16 | ;; --------------------------------------------------------------------------------------------------- 17 | 18 | (define optimize-level? exact-nonnegative-integer?) 19 | (define shrink-level? exact-nonnegative-integer?) 20 | 21 | (define/contract (optimize-level) 22 | (-> exact-nonnegative-integer?) 23 | (BinaryenGetOptimizeLevel)) 24 | 25 | (define/contract (set-optimize-level! n) 26 | (exact-nonnegative-integer? . -> . void?) 27 | (BinaryenSetOptimizeLevel n)) 28 | 29 | (define/contract (shrink-level) 30 | (-> exact-nonnegative-integer?) 31 | (BinaryenGetShrinkLevel)) 32 | 33 | (define/contract (set-shrink-level! n) 34 | (exact-nonnegative-integer? . -> . void?) 35 | (BinaryenSetShrinkLevel n)) 36 | 37 | (define-syntax-rule (with-optimize-level n body ...) 38 | (let ([current-optimize-level (optimize-level)]) 39 | (dynamic-wind 40 | (lambda () (void)) 41 | (lambda () 42 | (set-optimize-level! n) 43 | (begin body ...)) 44 | (lambda () 45 | (set-optimize-level! current-optimize-level))))) 46 | 47 | (define-syntax-rule (with-shrink-level n body ...) 48 | (let ([current-shrink-level (shrink-level)]) 49 | (dynamic-wind 50 | (lambda () (void)) 51 | (lambda () 52 | (set-shrink-level! n) 53 | (begin body ...)) 54 | (lambda () 55 | (set-shrink-level! current-shrink-level))))) 56 | 57 | ;; --------------------------------------------------------------------------------------------------- 58 | 59 | (module+ test 60 | 61 | (require rackunit) 62 | 63 | (test-case "default level" 64 | (check = 2 (optimize-level)) 65 | (check = 1 (shrink-level))) 66 | 67 | (test-case "with-optimize-level" 68 | (set-optimize-level! 1) 69 | (with-optimize-level 3 70 | (check = 3 (optimize-level))) 71 | (check = 1 (optimize-level))) 72 | 73 | (test-case "with-shrink-level" 74 | (set-shrink-level! 3) 75 | (with-shrink-level 0 76 | (check = 0 (shrink-level))) 77 | (check = 3 (shrink-level))) 78 | 79 | (test-case "pass" 80 | (check-true #true))) 81 | -------------------------------------------------------------------------------- /private/binaryen-ffi.rkt: -------------------------------------------------------------------------------- 1 | #lang racket/base 2 | ;; --------------------------------------------------------------------------------------------------- 3 | 4 | (require ffi/unsafe 5 | ffi/unsafe/define 6 | ffi/unsafe/alloc 7 | setup/dirs 8 | (for-syntax racket/base 9 | racket/syntax 10 | racket/list)) 11 | 12 | ;; --------------------------------------------------------------------------------------------------- 13 | 14 | ; !DO NOT REMOVE OR EDIT THE FOLLOWING LINES! 15 | ; Based on binaryen-c.h with sha: 16 | ;==;e151552a7ee28b3948c1104ff8783a37c7db1273 17 | 18 | ;; WARNING: Does not include deprecated bindings! 19 | 20 | (define (get-lib-search-dirs/local) 21 | (cons (string->path "/usr/local/lib") 22 | (cons (string->path "/home/pmatos/dev/binaryen/out/lib") 23 | (get-lib-search-dirs)))) 24 | 25 | (define libbinaryen (ffi-lib "libbinaryen" 26 | #:get-lib-dirs get-lib-search-dirs/local)) 27 | 28 | 29 | (define-ffi-definer define-binaryen libbinaryen) 30 | 31 | (define-syntax defbinaryen 32 | (syntax-rules (:) 33 | [(_ name : type ...) 34 | (define name 35 | (get-ffi-obj 'name libbinaryen (_fun type ...)))])) 36 | 37 | (define-syntax defbinaryen* 38 | (syntax-rules (:) 39 | [(_ name : type ...) 40 | (begin 41 | (provide name) 42 | (defbinaryen name : type ...))])) 43 | 44 | 45 | ; Module creation 46 | 47 | (define BinaryenIndex _uint32) 48 | (define BinaryenType _uintptr) 49 | 50 | (defbinaryen* BinaryenTypeNone : -> BinaryenType) 51 | (defbinaryen* BinaryenTypeInt32 : -> BinaryenType) 52 | (defbinaryen* BinaryenTypeInt64 : -> BinaryenType) 53 | (defbinaryen* BinaryenTypeFloat32 : -> BinaryenType) 54 | (defbinaryen* BinaryenTypeFloat64 : -> BinaryenType) 55 | (defbinaryen* BinaryenTypeVec128 : -> BinaryenType) 56 | (defbinaryen* BinaryenTypeFuncref : -> BinaryenType) 57 | (defbinaryen* BinaryenTypeExternref : -> BinaryenType) 58 | (defbinaryen* BinaryenTypeAnyref : -> BinaryenType) 59 | (defbinaryen* BinaryenTypeEqref : -> BinaryenType) 60 | (defbinaryen* BinaryenTypeI31ref : -> BinaryenType) 61 | (defbinaryen* BinaryenTypeDataref : -> BinaryenType) 62 | (defbinaryen* BinaryenTypeUnreachable : -> BinaryenType) 63 | 64 | (defbinaryen* BinaryenTypeAuto : -> BinaryenType) 65 | (defbinaryen* BinaryenTypeCreate : 66 | [vec : (_list i BinaryenType)] [_int = (length vec)] 67 | -> BinaryenType) 68 | (defbinaryen* BinaryenTypeArity : BinaryenType -> _uint32) 69 | (defbinaryen* BinaryenTypeExpand : 70 | [t : BinaryenType] [vec : (_list o BinaryenType (BinaryenTypeArity t))] 71 | -> _void 72 | -> vec) 73 | 74 | (define BinaryenExpressionId _uint32) 75 | 76 | (defbinaryen BinaryenInvalidId : -> BinaryenExpressionId) 77 | 78 | (define BinaryenExternalKind _uint32) 79 | 80 | (defbinaryen* BinaryenExternalFunction : -> BinaryenExternalKind) 81 | (defbinaryen* BinaryenExternalTable : -> BinaryenExternalKind) 82 | (defbinaryen* BinaryenExternalMemory : -> BinaryenExternalKind) 83 | (defbinaryen* BinaryenExternalGlobal : -> BinaryenExternalKind) 84 | (defbinaryen* BinaryenExternalTag : -> BinaryenExternalKind) 85 | 86 | (define BinaryenFeatures _uint32) 87 | 88 | (defbinaryen* BinaryenFeatureMVP : -> BinaryenFeatures) 89 | (defbinaryen* BinaryenFeatureAtomics : -> BinaryenFeatures) 90 | (defbinaryen* BinaryenFeatureBulkMemory : -> BinaryenFeatures) 91 | (defbinaryen* BinaryenFeatureMutableGlobals : -> BinaryenFeatures) 92 | (defbinaryen* BinaryenFeatureNontrappingFPToInt : -> BinaryenFeatures) 93 | (defbinaryen* BinaryenFeatureSignExt : -> BinaryenFeatures) 94 | (defbinaryen* BinaryenFeatureSIMD128 : -> BinaryenFeatures) 95 | (defbinaryen* BinaryenFeatureExceptionHandling : -> BinaryenFeatures) 96 | (defbinaryen* BinaryenFeatureTailCall : -> BinaryenFeatures) 97 | (defbinaryen* BinaryenFeatureReferenceTypes : -> BinaryenFeatures) 98 | (defbinaryen* BinaryenFeatureMultivalue : -> BinaryenFeatures) 99 | (defbinaryen* BinaryenFeatureGC : -> BinaryenFeatures) 100 | (defbinaryen* BinaryenFeatureMemory64 : -> BinaryenFeatures) 101 | (defbinaryen* BinaryenFeatureTypedFunctionReferences : -> BinaryenFeatures) 102 | (defbinaryen* BinaryenFeatureRelaxedSIMD : -> BinaryenFeatures) 103 | (defbinaryen* BinaryenFeatureAll : -> BinaryenFeatures) 104 | 105 | (define BinaryenModuleRef (_cpointer 'BinaryenModuleRef)) 106 | 107 | ; using definer explicitly to allow wrappers 108 | (provide BinaryenModuleDispose) 109 | (define-binaryen BinaryenModuleDispose 110 | (_fun BinaryenModuleRef -> _void) 111 | #:wrap (deallocator)) 112 | 113 | (provide BinaryenModuleCreate) 114 | (define-binaryen BinaryenModuleCreate 115 | (_fun -> BinaryenModuleRef) 116 | #:wrap (allocator BinaryenModuleDispose)) 117 | 118 | ; Literals 119 | 120 | (define _litunion 121 | (make-union-type 122 | _int32 123 | _int64 124 | _float 125 | _double 126 | (_array _uint8 16) 127 | _string)) 128 | 129 | (define-cstruct _BinaryenLiteral 130 | ([type _uintptr] 131 | [lit-rest _litunion])) 132 | 133 | (defbinaryen* BinaryenLiteralInt32 : _int32 -> _BinaryenLiteral) 134 | (defbinaryen* BinaryenLiteralInt64 : _int64 -> _BinaryenLiteral) 135 | (defbinaryen* BinaryenLiteralFloat32 : _float -> _BinaryenLiteral) 136 | (defbinaryen* BinaryenLiteralFloat64 : _double -> _BinaryenLiteral) 137 | (defbinaryen* BinaryenLiteralVec128 : (_array _uint8 16) -> _BinaryenLiteral) 138 | (defbinaryen* BinaryenLiteralFloat32Bits : _int32 -> _BinaryenLiteral) 139 | (defbinaryen* BinaryenLiteralFloat64Bits : _int64 -> _BinaryenLiteral) 140 | 141 | ; Expressions 142 | 143 | (define BinaryenOp _int32) 144 | 145 | (define-syntax (define-binaryops stx) 146 | (syntax-case stx () 147 | [(_ name ...) 148 | #`(begin 149 | #,@(for/list ([n (in-list (syntax->list #'(name ...)))]) 150 | (with-syntax ([fullname (format-id n "Binaryen~a" (syntax->datum n))]) 151 | #'(defbinaryen* fullname : -> BinaryenOp))))])) 152 | 153 | (define-binaryops 154 | ClzInt32 155 | CtzInt32 156 | PopcntInt32 157 | NegFloat32 158 | AbsFloat32 159 | CeilFloat32 160 | FloorFloat32 161 | TruncFloat32 162 | NearestFloat32 163 | SqrtFloat32 164 | EqZInt32 165 | ClzInt64 166 | CtzInt64 167 | PopcntInt64 168 | NegFloat64 169 | AbsFloat64 170 | CeilFloat64 171 | FloorFloat64 172 | TruncFloat64 173 | NearestFloat64 174 | SqrtFloat64 175 | EqZInt64 176 | ExtendSInt32 177 | ExtendUInt32 178 | WrapInt64 179 | TruncSFloat32ToInt32 180 | TruncSFloat32ToInt64 181 | TruncUFloat32ToInt32 182 | TruncUFloat32ToInt64 183 | TruncSFloat64ToInt32 184 | TruncSFloat64ToInt64 185 | TruncUFloat64ToInt32 186 | TruncUFloat64ToInt64 187 | ReinterpretFloat32 188 | ReinterpretFloat64 189 | ConvertSInt32ToFloat32 190 | ConvertSInt32ToFloat64 191 | ConvertUInt32ToFloat32 192 | ConvertUInt32ToFloat64 193 | ConvertSInt64ToFloat32 194 | ConvertSInt64ToFloat64 195 | ConvertUInt64ToFloat32 196 | ConvertUInt64ToFloat64 197 | PromoteFloat32 198 | DemoteFloat64 199 | ReinterpretInt32 200 | ReinterpretInt64 201 | ExtendS8Int32 202 | ExtendS16Int32 203 | ExtendS8Int64 204 | ExtendS16Int64 205 | ExtendS32Int64 206 | AddInt32 207 | SubInt32 208 | MulInt32 209 | DivSInt32 210 | DivUInt32 211 | RemSInt32 212 | RemUInt32 213 | AndInt32 214 | OrInt32 215 | XorInt32 216 | ShlInt32 217 | ShrUInt32 218 | ShrSInt32 219 | RotLInt32 220 | RotRInt32 221 | EqInt32 222 | NeInt32 223 | LtSInt32 224 | LtUInt32 225 | LeSInt32 226 | LeUInt32 227 | GtSInt32 228 | GtUInt32 229 | GeSInt32 230 | GeUInt32 231 | AddInt64 232 | SubInt64 233 | MulInt64 234 | DivSInt64 235 | DivUInt64 236 | RemSInt64 237 | RemUInt64 238 | AndInt64 239 | OrInt64 240 | XorInt64 241 | ShlInt64 242 | ShrUInt64 243 | ShrSInt64 244 | RotLInt64 245 | RotRInt64 246 | EqInt64 247 | NeInt64 248 | LtSInt64 249 | LtUInt64 250 | LeSInt64 251 | LeUInt64 252 | GtSInt64 253 | GtUInt64 254 | GeSInt64 255 | GeUInt64 256 | AddFloat32 257 | SubFloat32 258 | MulFloat32 259 | DivFloat32 260 | CopySignFloat32 261 | MinFloat32 262 | MaxFloat32 263 | EqFloat32 264 | NeFloat32 265 | LtFloat32 266 | LeFloat32 267 | GtFloat32 268 | GeFloat32 269 | AddFloat64 270 | SubFloat64 271 | MulFloat64 272 | DivFloat64 273 | CopySignFloat64 274 | MinFloat64 275 | MaxFloat64 276 | EqFloat64 277 | NeFloat64 278 | LtFloat64 279 | LeFloat64 280 | GtFloat64 281 | GeFloat64 282 | AtomicRMWAdd 283 | AtomicRMWSub 284 | AtomicRMWAnd 285 | AtomicRMWOr 286 | AtomicRMWXor 287 | AtomicRMWXchg 288 | TruncSatSFloat32ToInt32 289 | TruncSatSFloat32ToInt64 290 | TruncSatUFloat32ToInt32 291 | TruncSatUFloat32ToInt64 292 | TruncSatSFloat64ToInt32 293 | TruncSatSFloat64ToInt64 294 | TruncSatUFloat64ToInt32 295 | TruncSatUFloat64ToInt64 296 | SplatVecI8x16 297 | ExtractLaneSVecI8x16 298 | ExtractLaneUVecI8x16 299 | ReplaceLaneVecI8x16 300 | SplatVecI16x8 301 | ExtractLaneSVecI16x8 302 | ExtractLaneUVecI16x8 303 | ReplaceLaneVecI16x8 304 | SplatVecI32x4 305 | ExtractLaneVecI32x4 306 | ReplaceLaneVecI32x4 307 | SplatVecI64x2 308 | ExtractLaneVecI64x2 309 | ReplaceLaneVecI64x2 310 | SplatVecF32x4 311 | ExtractLaneVecF32x4 312 | ReplaceLaneVecF32x4 313 | SplatVecF64x2 314 | ExtractLaneVecF64x2 315 | ReplaceLaneVecF64x2 316 | EqVecI8x16 317 | NeVecI8x16 318 | LtSVecI8x16 319 | LtUVecI8x16 320 | GtSVecI8x16 321 | GtUVecI8x16 322 | LeSVecI8x16 323 | LeUVecI8x16 324 | GeSVecI8x16 325 | GeUVecI8x16 326 | EqVecI16x8 327 | NeVecI16x8 328 | LtSVecI16x8 329 | LtUVecI16x8 330 | GtSVecI16x8 331 | GtUVecI16x8 332 | LeSVecI16x8 333 | LeUVecI16x8 334 | GeSVecI16x8 335 | GeUVecI16x8 336 | EqVecI32x4 337 | NeVecI32x4 338 | LtSVecI32x4 339 | LtUVecI32x4 340 | GtSVecI32x4 341 | GtUVecI32x4 342 | LeSVecI32x4 343 | LeUVecI32x4 344 | GeSVecI32x4 345 | GeUVecI32x4 346 | EqVecI64x2 347 | NeVecI64x2 348 | LtSVecI64x2 349 | GtSVecI64x2 350 | LeSVecI64x2 351 | GeSVecI64x2 352 | EqVecF32x4 353 | NeVecF32x4 354 | LtVecF32x4 355 | GtVecF32x4 356 | LeVecF32x4 357 | GeVecF32x4 358 | EqVecF64x2 359 | NeVecF64x2 360 | LtVecF64x2 361 | GtVecF64x2 362 | LeVecF64x2 363 | GeVecF64x2 364 | NotVec128 365 | AndVec128 366 | OrVec128 367 | XorVec128 368 | AndNotVec128 369 | BitselectVec128 370 | AnyTrueVec128 371 | PopcntVecI8x16 372 | AbsVecI8x16 373 | NegVecI8x16 374 | AllTrueVecI8x16 375 | BitmaskVecI8x16 376 | ShlVecI8x16 377 | ShrSVecI8x16 378 | ShrUVecI8x16 379 | AddVecI8x16 380 | AddSatSVecI8x16 381 | AddSatUVecI8x16 382 | SubVecI8x16 383 | SubSatSVecI8x16 384 | SubSatUVecI8x16 385 | MinSVecI8x16 386 | MinUVecI8x16 387 | MaxSVecI8x16 388 | MaxUVecI8x16 389 | AvgrUVecI8x16 390 | AbsVecI16x8 391 | NegVecI16x8 392 | AllTrueVecI16x8 393 | BitmaskVecI16x8 394 | ShlVecI16x8 395 | ShrSVecI16x8 396 | ShrUVecI16x8 397 | AddVecI16x8 398 | AddSatSVecI16x8 399 | AddSatUVecI16x8 400 | SubVecI16x8 401 | SubSatSVecI16x8 402 | SubSatUVecI16x8 403 | MulVecI16x8 404 | MinSVecI16x8 405 | MinUVecI16x8 406 | MaxSVecI16x8 407 | MaxUVecI16x8 408 | AvgrUVecI16x8 409 | Q15MulrSatSVecI16x8 410 | ExtMulLowSVecI16x8 411 | ExtMulHighSVecI16x8 412 | ExtMulLowUVecI16x8 413 | ExtMulHighUVecI16x8 414 | AbsVecI32x4 415 | NegVecI32x4 416 | AllTrueVecI32x4 417 | BitmaskVecI32x4 418 | ShlVecI32x4 419 | ShrSVecI32x4 420 | ShrUVecI32x4 421 | AddVecI32x4 422 | SubVecI32x4 423 | MulVecI32x4 424 | MinSVecI32x4 425 | MinUVecI32x4 426 | MaxSVecI32x4 427 | MaxUVecI32x4 428 | DotSVecI16x8ToVecI32x4 429 | ExtMulLowSVecI32x4 430 | ExtMulHighSVecI32x4 431 | ExtMulLowUVecI32x4 432 | ExtMulHighUVecI32x4 433 | AbsVecI64x2 434 | NegVecI64x2 435 | AllTrueVecI64x2 436 | BitmaskVecI64x2 437 | ShlVecI64x2 438 | ShrSVecI64x2 439 | ShrUVecI64x2 440 | AddVecI64x2 441 | SubVecI64x2 442 | MulVecI64x2 443 | ExtMulLowSVecI64x2 444 | ExtMulHighSVecI64x2 445 | ExtMulLowUVecI64x2 446 | ExtMulHighUVecI64x2 447 | AbsVecF32x4 448 | NegVecF32x4 449 | SqrtVecF32x4 450 | AddVecF32x4 451 | SubVecF32x4 452 | MulVecF32x4 453 | DivVecF32x4 454 | MinVecF32x4 455 | MaxVecF32x4 456 | PMinVecF32x4 457 | PMaxVecF32x4 458 | CeilVecF32x4 459 | FloorVecF32x4 460 | TruncVecF32x4 461 | NearestVecF32x4 462 | AbsVecF64x2 463 | NegVecF64x2 464 | SqrtVecF64x2 465 | AddVecF64x2 466 | SubVecF64x2 467 | MulVecF64x2 468 | DivVecF64x2 469 | MinVecF64x2 470 | MaxVecF64x2 471 | PMinVecF64x2 472 | PMaxVecF64x2 473 | CeilVecF64x2 474 | FloorVecF64x2 475 | TruncVecF64x2 476 | NearestVecF64x2 477 | ExtAddPairwiseSVecI8x16ToI16x8 478 | ExtAddPairwiseUVecI8x16ToI16x8 479 | ExtAddPairwiseSVecI16x8ToI32x4 480 | ExtAddPairwiseUVecI16x8ToI32x4 481 | TruncSatSVecF32x4ToVecI32x4 482 | TruncSatUVecF32x4ToVecI32x4 483 | ConvertSVecI32x4ToVecF32x4 484 | ConvertUVecI32x4ToVecF32x4 485 | Load8SplatVec128 486 | Load16SplatVec128 487 | Load32SplatVec128 488 | Load64SplatVec128 489 | Load8x8SVec128 490 | Load8x8UVec128 491 | Load16x4SVec128 492 | Load16x4UVec128 493 | Load32x2SVec128 494 | Load32x2UVec128 495 | Load32ZeroVec128 496 | Load64ZeroVec128 497 | Load8LaneVec128 498 | Load16LaneVec128 499 | Load32LaneVec128 500 | Load64LaneVec128 501 | Store8LaneVec128 502 | Store16LaneVec128 503 | Store32LaneVec128 504 | Store64LaneVec128 505 | NarrowSVecI16x8ToVecI8x16 506 | NarrowUVecI16x8ToVecI8x16 507 | NarrowSVecI32x4ToVecI16x8 508 | NarrowUVecI32x4ToVecI16x8 509 | ExtendLowSVecI8x16ToVecI16x8 510 | ExtendHighSVecI8x16ToVecI16x8 511 | ExtendLowUVecI8x16ToVecI16x8 512 | ExtendHighUVecI8x16ToVecI16x8 513 | ExtendLowSVecI16x8ToVecI32x4 514 | ExtendHighSVecI16x8ToVecI32x4 515 | ExtendLowUVecI16x8ToVecI32x4 516 | ExtendHighUVecI16x8ToVecI32x4 517 | ExtendLowSVecI32x4ToVecI64x2 518 | ExtendHighSVecI32x4ToVecI64x2 519 | ExtendLowUVecI32x4ToVecI64x2 520 | ExtendHighUVecI32x4ToVecI64x2 521 | ConvertLowSVecI32x4ToVecF64x2 522 | ConvertLowUVecI32x4ToVecF64x2 523 | TruncSatZeroSVecF64x2ToVecI32x4 524 | TruncSatZeroUVecF64x2ToVecI32x4 525 | DemoteZeroVecF64x2ToVecF32x4 526 | PromoteLowVecF32x4ToVecF64x2 527 | SwizzleVec8x16 528 | RefIsNull 529 | RefIsFunc 530 | RefIsData 531 | RefIsI31 532 | RefAsNonNull 533 | RefAsFunc 534 | RefAsData 535 | RefAsI31) 536 | 537 | ;; 538 | ;; Many of the operations have a well-defined name and define a setter and getter for it. 539 | ;; This macros hopefully make it easier to create the ffi bindings. 540 | ;; 541 | (define-syntax (defbinaryen*-get stx) 542 | (syntax-case stx (:) 543 | [(_ struct field [ extra-args ... ] field-type) 544 | (with-syntax ([getter (format-id #'field "Binaryen~aGet~a" 545 | (syntax->datum #'struct) (syntax->datum #'field))]) 546 | #'(defbinaryen* getter : BinaryenExpressionRef extra-args ... -> field-type))] 547 | [(_ struct field field-type) 548 | #'(defbinaryen*-get struct field [] field-type)])) 549 | 550 | (define-syntax (defbinaryen*-get/set stx) 551 | (syntax-case stx (:) 552 | [(_ struct field [ extra-args ... ] field-type) 553 | (with-syntax ([getter (format-id #'field "Binaryen~aGet~a" 554 | (syntax->datum #'struct) (syntax->datum #'field))] 555 | [setter (format-id #'field "Binaryen~aSet~a" 556 | (syntax->datum #'struct) (syntax->datum #'field))]) 557 | #'(begin 558 | (defbinaryen* getter : BinaryenExpressionRef extra-args ... -> field-type) 559 | (defbinaryen* setter : BinaryenExpressionRef extra-args ... field-type -> _void)))] 560 | [(_ struct field field-type) 561 | #'(defbinaryen*-get/set struct field [] field-type)])) 562 | 563 | (define-syntax (defbinaryen*-get/set-fields stx) 564 | (syntax-case stx () 565 | [(_ struct fields/types ...) 566 | #`(begin 567 | #,@(for/list ([ft (in-list (syntax->list #'(fields/types ...)))]) 568 | (cond 569 | [(= (length (syntax->datum ft)) 2) 570 | #`(defbinaryen*-get/set struct 571 | #,(first (syntax->datum ft)) 572 | #,(second (syntax->datum ft)))] 573 | [(= (length (syntax->datum ft)) 3) 574 | #`(defbinaryen*-get/set struct 575 | #,(first (syntax->datum ft)) 576 | #,(second (syntax->datum ft)) 577 | #,(third (syntax->datum ft)))] 578 | [else 579 | (raise-syntax-error "unknown number of fields in fields/types list")])))])) 580 | 581 | 582 | (define BinaryenExpressionRef (_cpointer/null 'BinaryenExpressionRef)) 583 | 584 | (defbinaryen* BinaryenBlock : 585 | BinaryenModuleRef _string [children : (_list i BinaryenExpressionRef)] [BinaryenIndex = (length children)] BinaryenType 586 | -> BinaryenExpressionRef) 587 | 588 | (defbinaryen* BinaryenIf : 589 | BinaryenModuleRef BinaryenExpressionRef BinaryenExpressionRef BinaryenExpressionRef 590 | -> BinaryenExpressionRef) 591 | 592 | (defbinaryen* BinaryenLoop : 593 | BinaryenModuleRef _string BinaryenExpressionRef 594 | -> BinaryenExpressionRef) 595 | 596 | (defbinaryen* BinaryenBreak : 597 | BinaryenModuleRef _string BinaryenExpressionRef BinaryenExpressionRef 598 | -> BinaryenExpressionRef) 599 | 600 | (defbinaryen* BinaryenSwitch : 601 | BinaryenModuleRef [names : (_list i _string)] [BinaryenIndex = (length names)] _string BinaryenExpressionRef BinaryenExpressionRef 602 | -> BinaryenExpressionRef) 603 | 604 | (defbinaryen* BinaryenCall : 605 | BinaryenModuleRef _string [operands : (_list i BinaryenExpressionRef)] [BinaryenIndex = (length operands)] BinaryenType 606 | -> BinaryenExpressionRef) 607 | 608 | (defbinaryen* BinaryenCallIndirect : 609 | BinaryenModuleRef _string BinaryenExpressionRef [operands : (_list i BinaryenExpressionRef)] [BinaryenIndex = (length operands)] BinaryenType BinaryenType 610 | -> BinaryenExpressionRef) 611 | 612 | (defbinaryen* BinaryenReturnCall : 613 | BinaryenModuleRef _string [operands : (_list i BinaryenExpressionRef)] [BinaryenIndex = (length operands)] BinaryenType 614 | -> BinaryenExpressionRef) 615 | 616 | (defbinaryen* BinaryenReturnCallIndirect : 617 | BinaryenModuleRef _string BinaryenExpressionRef [operands : (_list i BinaryenExpressionRef)] [BinaryenIndex = (length operands)] BinaryenType BinaryenType 618 | -> BinaryenExpressionRef) 619 | 620 | (defbinaryen* BinaryenLocalGet : 621 | BinaryenModuleRef BinaryenIndex BinaryenType 622 | -> BinaryenExpressionRef) 623 | 624 | (defbinaryen* BinaryenLocalSet : 625 | BinaryenModuleRef BinaryenIndex BinaryenExpressionRef 626 | -> BinaryenExpressionRef) 627 | 628 | (defbinaryen* BinaryenLocalTee : 629 | BinaryenModuleRef BinaryenIndex BinaryenExpressionRef BinaryenType 630 | -> BinaryenExpressionRef) 631 | 632 | (defbinaryen* BinaryenGlobalGet : 633 | BinaryenModuleRef _string BinaryenType 634 | -> BinaryenExpressionRef) 635 | 636 | (defbinaryen* BinaryenGlobalSet : 637 | BinaryenModuleRef _string BinaryenExpressionRef 638 | -> BinaryenExpressionRef) 639 | 640 | (defbinaryen* BinaryenLoad : 641 | BinaryenModuleRef _uint32 _stdbool _uint32 _uint32 BinaryenType BinaryenExpressionRef 642 | -> BinaryenExpressionRef) 643 | 644 | (defbinaryen* BinaryenStore : 645 | BinaryenModuleRef _uint32 _uint32 _uint32 BinaryenExpressionRef BinaryenExpressionRef BinaryenType 646 | -> BinaryenExpressionRef) 647 | 648 | (defbinaryen* BinaryenConst : 649 | BinaryenModuleRef _BinaryenLiteral 650 | -> BinaryenExpressionRef) 651 | 652 | (defbinaryen* BinaryenUnary : 653 | BinaryenModuleRef BinaryenOp BinaryenExpressionRef 654 | -> BinaryenExpressionRef) 655 | 656 | (defbinaryen* BinaryenBinary : 657 | BinaryenModuleRef BinaryenOp BinaryenExpressionRef BinaryenExpressionRef 658 | -> BinaryenExpressionRef) 659 | 660 | (defbinaryen* BinaryenSelect : 661 | BinaryenModuleRef BinaryenExpressionRef BinaryenExpressionRef BinaryenExpressionRef BinaryenType 662 | -> BinaryenExpressionRef) 663 | 664 | (defbinaryen* BinaryenDrop : 665 | BinaryenModuleRef BinaryenExpressionRef 666 | -> BinaryenExpressionRef) 667 | 668 | (defbinaryen* BinaryenReturn : 669 | BinaryenModuleRef BinaryenExpressionRef -> BinaryenExpressionRef) 670 | 671 | (defbinaryen* BinaryenMemorySize : BinaryenModuleRef -> BinaryenExpressionRef) 672 | 673 | (defbinaryen* BinaryenMemoryGrow : BinaryenModuleRef BinaryenExpressionRef -> BinaryenExpressionRef) 674 | 675 | (defbinaryen* BinaryenNop : BinaryenModuleRef -> BinaryenExpressionRef) 676 | 677 | (defbinaryen* BinaryenUnreachable : BinaryenModuleRef -> BinaryenExpressionRef) 678 | 679 | (defbinaryen* BinaryenAtomicLoad : 680 | BinaryenModuleRef _uint32 _uint32 BinaryenType BinaryenExpressionRef 681 | -> BinaryenExpressionRef) 682 | 683 | (defbinaryen* BinaryenAtomicStore : 684 | BinaryenModuleRef _uint32 _uint32 BinaryenExpressionRef BinaryenExpressionRef BinaryenType 685 | -> BinaryenExpressionRef) 686 | 687 | (defbinaryen* BinaryenAtomicRMW : 688 | BinaryenModuleRef BinaryenOp BinaryenIndex BinaryenIndex BinaryenExpressionRef BinaryenExpressionRef BinaryenType 689 | -> BinaryenExpressionRef) 690 | 691 | (defbinaryen* BinaryenAtomicCmpxchg : 692 | BinaryenModuleRef BinaryenIndex BinaryenIndex BinaryenExpressionRef BinaryenExpressionRef BinaryenExpressionRef BinaryenType 693 | -> BinaryenExpressionRef) 694 | 695 | (defbinaryen* BinaryenAtomicWait : 696 | BinaryenModuleRef BinaryenExpressionRef BinaryenExpressionRef BinaryenExpressionRef BinaryenType 697 | -> BinaryenExpressionRef) 698 | 699 | (defbinaryen* BinaryenAtomicNotify : 700 | BinaryenModuleRef BinaryenExpressionRef BinaryenExpressionRef 701 | -> BinaryenExpressionRef) 702 | 703 | (defbinaryen* BinaryenAtomicFence : BinaryenModuleRef -> BinaryenExpressionRef) 704 | 705 | (defbinaryen* BinaryenSIMDExtract : BinaryenModuleRef BinaryenOp BinaryenExpressionRef _uint8 -> BinaryenExpressionRef) 706 | 707 | (defbinaryen* BinaryenSIMDReplace : BinaryenModuleRef BinaryenOp BinaryenExpressionRef _uint8 BinaryenExpressionRef 708 | -> BinaryenExpressionRef) 709 | 710 | (defbinaryen* BinaryenSIMDShuffle : 711 | BinaryenModuleRef BinaryenExpressionRef BinaryenExpressionRef (_array _uint8 16) 712 | -> BinaryenExpressionRef) 713 | 714 | (defbinaryen* BinaryenSIMDShift : 715 | BinaryenModuleRef BinaryenOp BinaryenExpressionRef BinaryenExpressionRef 716 | -> BinaryenExpressionRef) 717 | 718 | (defbinaryen* BinaryenSIMDLoad : 719 | BinaryenModuleRef BinaryenOp _uint32 _uint32 BinaryenExpressionRef 720 | -> BinaryenExpressionRef) 721 | 722 | (defbinaryen* BinaryenSIMDLoadStoreLane : 723 | BinaryenModuleRef BinaryenOp _uint32 _uint32 _uint8 BinaryenExpressionRef BinaryenExpressionRef 724 | -> BinaryenExpressionRef) 725 | 726 | (defbinaryen* BinaryenMemoryInit : 727 | BinaryenModuleRef _uint32 BinaryenExpressionRef BinaryenExpressionRef BinaryenExpressionRef 728 | -> BinaryenExpressionRef) 729 | 730 | (defbinaryen* BinaryenDataDrop : 731 | BinaryenModuleRef _uint32 732 | -> BinaryenExpressionRef) 733 | 734 | (defbinaryen* BinaryenMemoryCopy : 735 | BinaryenModuleRef BinaryenExpressionRef BinaryenExpressionRef BinaryenExpressionRef 736 | -> BinaryenExpressionRef) 737 | 738 | (defbinaryen* BinaryenMemoryFill : 739 | BinaryenModuleRef BinaryenExpressionRef BinaryenExpressionRef BinaryenExpressionRef 740 | -> BinaryenExpressionRef) 741 | 742 | (defbinaryen* BinaryenRefNull : 743 | BinaryenModuleRef BinaryenType 744 | -> BinaryenExpressionRef) 745 | 746 | (defbinaryen* BinaryenRefIs : 747 | BinaryenModuleRef BinaryenOp BinaryenExpressionRef 748 | -> BinaryenExpressionRef) 749 | 750 | (defbinaryen* BinaryenRefAs : 751 | BinaryenModuleRef BinaryenOp BinaryenExpressionRef 752 | -> BinaryenExpressionRef) 753 | 754 | (defbinaryen* BinaryenRefFunc : 755 | BinaryenModuleRef _string BinaryenType 756 | -> BinaryenExpressionRef) 757 | 758 | (defbinaryen* BinaryenRefEq : 759 | BinaryenModuleRef BinaryenExpressionRef BinaryenExpressionRef 760 | -> BinaryenExpressionRef) 761 | 762 | (defbinaryen* BinaryenTableGet : 763 | BinaryenModuleRef _string BinaryenExpressionRef BinaryenType 764 | -> BinaryenExpressionRef) 765 | 766 | (defbinaryen* BinaryenTableSet : 767 | BinaryenModuleRef _string BinaryenExpressionRef BinaryenExpressionRef 768 | -> BinaryenExpressionRef) 769 | 770 | (defbinaryen* BinaryenTableSize : 771 | BinaryenModuleRef _string 772 | -> BinaryenExpressionRef) 773 | 774 | (defbinaryen* BinaryenTableGrow : 775 | BinaryenModuleRef _string BinaryenExpressionRef BinaryenExpressionRef 776 | -> BinaryenExpressionRef) 777 | 778 | ; TODO 779 | ; Try: name can be NULL. delegateTarget should be NULL in try-catch. 780 | (defbinaryen* BinaryenTry : 781 | BinaryenModuleRef 782 | [name : _string] 783 | BinaryenExpressionRef 784 | [catchTags : (_list i _string)] [BinaryenIndex = (length catchTags)] 785 | [catchBodies : (_list i BinaryenExpressionRef)] [BinaryenIndex = (length catchBodies)] 786 | [delegateTarget : _string] 787 | -> BinaryenExpressionRef) 788 | 789 | (defbinaryen* BinaryenThrow : 790 | BinaryenModuleRef _string [operands : (_list i BinaryenExpressionRef)] [BinaryenIndex = (length operands)] 791 | -> BinaryenExpressionRef) 792 | 793 | (defbinaryen* BinaryenRethrow : 794 | BinaryenModuleRef _string -> BinaryenExpressionRef) 795 | 796 | (defbinaryen* BinaryenTupleMake : 797 | BinaryenModuleRef [operands : (_list i BinaryenExpressionRef)] [BinaryenIndex = (length operands)] 798 | -> BinaryenExpressionRef) 799 | 800 | (defbinaryen* BinaryenTupleExtract : 801 | BinaryenModuleRef BinaryenExpressionRef BinaryenIndex 802 | -> BinaryenExpressionRef) 803 | 804 | (defbinaryen* BinaryenPop : 805 | BinaryenModuleRef BinaryenType 806 | -> BinaryenExpressionRef) 807 | 808 | (defbinaryen* BinaryenI31New : 809 | BinaryenModuleRef BinaryenExpressionRef 810 | -> BinaryenExpressionRef) 811 | 812 | (defbinaryen* BinaryenI31Get : 813 | BinaryenModuleRef BinaryenExpressionRef _stdbool 814 | -> BinaryenExpressionRef) 815 | 816 | (defbinaryen* BinaryenExpressionGetId : 817 | BinaryenExpressionRef -> BinaryenExpressionId) 818 | 819 | (defbinaryen* BinaryenExpressionGetType : 820 | BinaryenExpressionRef -> BinaryenType) 821 | 822 | (defbinaryen* BinaryenExpressionSetType : 823 | BinaryenExpressionRef BinaryenType -> _void) 824 | 825 | (defbinaryen* BinaryenExpressionPrint : BinaryenExpressionRef -> _void) 826 | 827 | (defbinaryen* BinaryenExpressionFinalize : BinaryenExpressionRef -> _void) 828 | 829 | (defbinaryen* BinaryenExpressionCopy : BinaryenExpressionRef BinaryenModuleRef 830 | -> BinaryenExpressionRef) 831 | 832 | 833 | ;; BinaryenBlock 834 | 835 | (defbinaryen*-get/set-fields Block 836 | (Name _string) 837 | (ChildAt [BinaryenIndex] BinaryenExpressionRef)) 838 | 839 | (defbinaryen* BinaryenBlockGetNumChildren : BinaryenExpressionRef -> BinaryenIndex) 840 | 841 | (defbinaryen* BinaryenBlockAppendChild : BinaryenExpressionRef BinaryenExpressionRef -> BinaryenIndex) 842 | 843 | (defbinaryen* BinaryenBlockInsertChildAt : BinaryenExpressionRef BinaryenIndex BinaryenExpressionRef -> _void) 844 | 845 | (defbinaryen* BinaryenBlockRemoveChildAt : BinaryenExpressionRef BinaryenIndex -> BinaryenExpressionRef) 846 | 847 | 848 | ; If 849 | (defbinaryen* BinaryenIfGetCondition : BinaryenExpressionRef -> BinaryenExpressionRef) 850 | 851 | (defbinaryen* BinaryenIfSetCondition : BinaryenExpressionRef BinaryenExpressionRef -> _void) 852 | 853 | (defbinaryen* BinaryenIfGetIfTrue : BinaryenExpressionRef -> BinaryenExpressionRef) 854 | 855 | (defbinaryen* BinaryenIfSetIfTrue : BinaryenExpressionRef BinaryenExpressionRef -> _void) 856 | 857 | (defbinaryen* BinaryenIfGetIfFalse : BinaryenExpressionRef -> BinaryenExpressionRef) 858 | 859 | (defbinaryen* BinaryenIfSetIfFalse : BinaryenExpressionRef BinaryenExpressionRef -> _void) 860 | 861 | ; Loop 862 | (defbinaryen* BinaryenLoopGetName : BinaryenExpressionRef -> _string) 863 | 864 | (defbinaryen* BinaryenLoopSetName : BinaryenExpressionRef _string -> _void) 865 | 866 | (defbinaryen* BinaryenLoopGetBody : BinaryenExpressionRef -> BinaryenExpressionRef) 867 | 868 | (defbinaryen* BinaryenLoopSetBody : BinaryenExpressionRef BinaryenExpressionRef -> _void) 869 | 870 | ; Break 871 | (defbinaryen* BinaryenBreakGetName : BinaryenExpressionRef -> _string) 872 | 873 | (defbinaryen* BinaryenBreakSetName : BinaryenExpressionRef _string -> _void) 874 | 875 | (defbinaryen* BinaryenBreakGetCondition : BinaryenExpressionRef -> BinaryenExpressionRef) 876 | 877 | (defbinaryen* BinaryenBreakSetCondition : BinaryenExpressionRef BinaryenExpressionRef -> _void) 878 | 879 | (defbinaryen* BinaryenBreakGetValue : BinaryenExpressionRef -> BinaryenExpressionRef) 880 | 881 | (defbinaryen* BinaryenBreakSetValue : BinaryenExpressionRef BinaryenExpressionRef -> _void) 882 | 883 | ; Switch 884 | 885 | (defbinaryen* BinaryenSwitchGetNumNames : BinaryenExpressionRef -> BinaryenIndex) 886 | 887 | (defbinaryen* BinaryenSwitchGetNameAt : 888 | BinaryenExpressionRef BinaryenIndex -> _string) 889 | 890 | (defbinaryen* BinaryenSwitchSetNameAt : 891 | BinaryenExpressionRef BinaryenIndex _string -> _void) 892 | 893 | (defbinaryen* BinaryenSwitchAppendName : 894 | BinaryenExpressionRef _string -> BinaryenIndex) 895 | 896 | (defbinaryen* BinaryenSwitchInsertNameAt : 897 | BinaryenExpressionRef BinaryenIndex _string -> _void) 898 | 899 | (defbinaryen* BinaryenSwitchRemoveNameAt : 900 | BinaryenExpressionRef BinaryenIndex -> _void) 901 | 902 | (defbinaryen* BinaryenSwitchGetDefaultName : 903 | BinaryenExpressionRef -> _string) 904 | 905 | (defbinaryen* BinaryenSwitchSetDefaultName : 906 | BinaryenExpressionRef _string -> _void) 907 | 908 | (defbinaryen* BinaryenSwitchGetCondition : 909 | BinaryenExpressionRef -> BinaryenExpressionRef) 910 | 911 | (defbinaryen* BinaryenSwitchSetCondition : 912 | BinaryenExpressionRef BinaryenExpressionRef -> _void) 913 | 914 | (defbinaryen* BinaryenSwitchGetValue : 915 | BinaryenExpressionRef -> BinaryenExpressionRef) 916 | 917 | (defbinaryen* BinaryenSwitchSetValue : BinaryenExpressionRef BinaryenExpressionRef -> _void) 918 | 919 | 920 | ; Call 921 | 922 | (defbinaryen* BinaryenCallGetTarget : BinaryenExpressionRef -> _string) 923 | 924 | (defbinaryen* BinaryenCallSetTarget : BinaryenExpressionRef _string -> _void) 925 | 926 | (defbinaryen* BinaryenCallGetNumOperands : BinaryenExpressionRef -> BinaryenIndex) 927 | 928 | (defbinaryen* BinaryenCallGetOperandAt : BinaryenExpressionRef BinaryenIndex -> BinaryenExpressionRef) 929 | 930 | (defbinaryen* BinaryenCallSetOperandAt : BinaryenExpressionRef BinaryenIndex BinaryenExpressionRef -> _void) 931 | 932 | (defbinaryen* BinaryenCallAppendOperand : BinaryenExpressionRef BinaryenExpressionRef -> BinaryenIndex) 933 | 934 | (defbinaryen* BinaryenCallInsertOperandAt : BinaryenExpressionRef BinaryenIndex BinaryenExpressionRef -> _void) 935 | 936 | (defbinaryen* BinaryenCallRemoveOperandAt : BinaryenExpressionRef BinaryenIndex -> BinaryenExpressionRef) 937 | 938 | (defbinaryen* BinaryenCallIsReturn : BinaryenExpressionRef -> _stdbool) 939 | 940 | (defbinaryen* BinaryenCallSetReturn : BinaryenExpressionRef _stdbool -> _void) 941 | 942 | ; Call indirect 943 | 944 | (defbinaryen* BinaryenCallIndirectGetTarget : BinaryenExpressionRef -> BinaryenExpressionRef) 945 | 946 | (defbinaryen* BinaryenCallIndirectSetTarget : BinaryenExpressionRef BinaryenExpressionRef -> _void) 947 | 948 | (defbinaryen* BinaryenCallIndirectGetTable : BinaryenExpressionRef -> _string) 949 | 950 | (defbinaryen* BinaryenCallIndirectSetTable : BinaryenExpressionRef _string -> _void) 951 | 952 | (defbinaryen* BinaryenCallIndirectGetNumOperands : BinaryenExpressionRef -> BinaryenIndex) 953 | 954 | (defbinaryen* BinaryenCallIndirectGetOperandAt : BinaryenExpressionRef BinaryenIndex -> BinaryenExpressionRef) 955 | 956 | (defbinaryen* BinaryenCallIndirectSetOperandAt : BinaryenExpressionRef BinaryenIndex BinaryenExpressionRef -> _void) 957 | 958 | (defbinaryen* BinaryenCallIndirectAppendOperand : BinaryenExpressionRef BinaryenExpressionRef -> BinaryenIndex) 959 | 960 | (defbinaryen* BinaryenCallIndirectInsertOperandAt : BinaryenExpressionRef BinaryenIndex BinaryenExpressionRef -> _void) 961 | 962 | (defbinaryen* BinaryenCallIndirectRemoveOperandAt : BinaryenExpressionRef BinaryenIndex -> BinaryenExpressionRef) 963 | 964 | (defbinaryen* BinaryenCallIndirectIsReturn : BinaryenExpressionRef -> _stdbool) 965 | 966 | (defbinaryen* BinaryenCallIndirectSetReturn : BinaryenExpressionRef _stdbool -> _void) 967 | 968 | (defbinaryen* BinaryenCallIndirectGetParams : BinaryenExpressionRef -> BinaryenType) 969 | 970 | (defbinaryen* BinaryenCallIndirectSetParams : BinaryenExpressionRef BinaryenType -> _void) 971 | 972 | (defbinaryen* BinaryenCallIndirectGetResults : BinaryenExpressionRef -> BinaryenType) 973 | 974 | (defbinaryen* BinaryenCallIndirectSetResults : BinaryenExpressionRef BinaryenType -> _void) 975 | 976 | ; LocalGet 977 | 978 | (defbinaryen* BinaryenLocalGetGetIndex : BinaryenExpressionRef -> BinaryenIndex) 979 | 980 | (defbinaryen* BinaryenLocalGetSetIndex : BinaryenExpressionRef BinaryenIndex -> _void) 981 | 982 | ; LocalSet 983 | 984 | (defbinaryen* BinaryenLocalSetIsTee : BinaryenExpressionRef -> _stdbool) 985 | 986 | (defbinaryen* BinaryenLocalSetGetIndex : BinaryenExpressionRef -> BinaryenIndex) 987 | 988 | (defbinaryen* BinaryenLocalSetSetIndex : BinaryenExpressionRef BinaryenIndex -> _void) 989 | 990 | (defbinaryen* BinaryenLocalSetGetValue : BinaryenExpressionRef -> BinaryenExpressionRef) 991 | 992 | (defbinaryen* BinaryenLocalSetSetValue : BinaryenExpressionRef BinaryenExpressionRef -> _void) 993 | 994 | ; GlobalGet 995 | 996 | (defbinaryen* BinaryenGlobalGetGetName : BinaryenExpressionRef -> _string) 997 | 998 | (defbinaryen* BinaryenGlobalGetSetName : BinaryenExpressionRef _string -> _void) 999 | 1000 | ; GlobalSet 1001 | 1002 | (defbinaryen* BinaryenGlobalSetGetName : BinaryenExpressionRef -> _string) 1003 | 1004 | (defbinaryen* BinaryenGlobalSetSetName : BinaryenExpressionRef _string -> _void) 1005 | 1006 | (defbinaryen* BinaryenGlobalSetGetValue : BinaryenExpressionRef -> BinaryenExpressionRef) 1007 | 1008 | (defbinaryen* BinaryenGlobalSetSetValue : BinaryenExpressionRef BinaryenExpressionRef -> _void) 1009 | 1010 | ; TableGet 1011 | 1012 | (defbinaryen* BinaryenTableGetGetTable : BinaryenExpressionRef -> _string) 1013 | 1014 | (defbinaryen* BinaryenTableGetSetTable : BinaryenExpressionRef _string -> _void) 1015 | 1016 | (defbinaryen* BinaryenTableGetGetIndex : BinaryenExpressionRef -> BinaryenExpressionRef) 1017 | 1018 | (defbinaryen* BinaryenTableGetSetIndex : BinaryenExpressionRef BinaryenExpressionRef -> _void) 1019 | 1020 | ; TableSet 1021 | 1022 | (defbinaryen* BinaryenTableSetGetTable : BinaryenExpressionRef -> _string) 1023 | 1024 | (defbinaryen* BinaryenTableSetSetTable : BinaryenExpressionRef _string -> _void) 1025 | 1026 | (defbinaryen* BinaryenTableSetGetIndex : BinaryenExpressionRef -> BinaryenExpressionRef) 1027 | 1028 | (defbinaryen* BinaryenTableSetSetIndex : BinaryenExpressionRef BinaryenExpressionRef -> _void) 1029 | 1030 | (defbinaryen* BinaryenTableSetGetValue : BinaryenExpressionRef -> BinaryenExpressionRef) 1031 | 1032 | (defbinaryen* BinaryenTableSetSetValue : BinaryenExpressionRef BinaryenExpressionRef -> _void) 1033 | 1034 | ; TableSize 1035 | 1036 | (defbinaryen* BinaryenTableSizeGetTable : BinaryenExpressionRef -> _string) 1037 | 1038 | (defbinaryen* BinaryenTableSizeSetTable : BinaryenExpressionRef _string -> _void) 1039 | 1040 | ; TableGrow 1041 | 1042 | (defbinaryen*-get/set-fields TableGrow 1043 | (Table _string) 1044 | (Value BinaryenExpressionRef) 1045 | (Delta BinaryenExpressionRef)) 1046 | 1047 | ; MemoryGrow 1048 | 1049 | (defbinaryen* BinaryenMemoryGrowGetDelta : BinaryenExpressionRef -> BinaryenExpressionRef) 1050 | 1051 | (defbinaryen* BinaryenMemoryGrowSetDelta : BinaryenExpressionRef BinaryenExpressionRef -> _void) 1052 | 1053 | ; Load 1054 | 1055 | (defbinaryen* BinaryenLoadIsAtomic : BinaryenExpressionRef -> _stdbool) 1056 | 1057 | (defbinaryen* BinaryenLoadSetAtomic : BinaryenExpressionRef _stdbool -> _void) 1058 | 1059 | (defbinaryen* BinaryenLoadIsSigned : BinaryenExpressionRef -> _stdbool) 1060 | 1061 | (defbinaryen* BinaryenLoadSetSigned : BinaryenExpressionRef _stdbool -> _void) 1062 | 1063 | (defbinaryen* BinaryenLoadGetOffset : BinaryenExpressionRef -> _uint32) 1064 | 1065 | (defbinaryen* BinaryenLoadSetOffset : BinaryenExpressionRef _uint32 -> _void) 1066 | 1067 | (defbinaryen* BinaryenLoadGetBytes : BinaryenExpressionRef -> _uint32) 1068 | 1069 | (defbinaryen* BinaryenLoadSetBytes : BinaryenExpressionRef _uint32 -> _void) 1070 | 1071 | (defbinaryen* BinaryenLoadGetAlign : BinaryenExpressionRef -> _uint32) 1072 | 1073 | (defbinaryen* BinaryenLoadSetAlign : BinaryenExpressionRef _uint32 -> _void) 1074 | 1075 | (defbinaryen* BinaryenLoadGetPtr : BinaryenExpressionRef -> BinaryenExpressionRef) 1076 | 1077 | (defbinaryen* BinaryenLoadSetPtr : BinaryenExpressionRef BinaryenExpressionRef -> _void) 1078 | 1079 | ; Store 1080 | 1081 | (defbinaryen* BinaryenStoreIsAtomic : BinaryenExpressionRef -> _stdbool) 1082 | 1083 | (defbinaryen* BinaryenStoreSetAtomic : BinaryenExpressionRef _stdbool -> _void) 1084 | 1085 | (defbinaryen* BinaryenStoreGetBytes : BinaryenExpressionRef -> _uint32) 1086 | 1087 | (defbinaryen* BinaryenStoreSetBytes : BinaryenExpressionRef _uint32 -> _void) 1088 | 1089 | (defbinaryen* BinaryenStoreGetOffset : BinaryenExpressionRef -> _uint32) 1090 | 1091 | (defbinaryen* BinaryenStoreSetOffset : BinaryenExpressionRef _uint32 -> _void) 1092 | 1093 | (defbinaryen* BinaryenStoreGetAlign : BinaryenExpressionRef -> _uint32) 1094 | 1095 | (defbinaryen* BinaryenStoreSetAlign : BinaryenExpressionRef _uint32 -> _void) 1096 | 1097 | (defbinaryen* BinaryenStoreGetPtr : BinaryenExpressionRef -> BinaryenExpressionRef) 1098 | 1099 | (defbinaryen* BinaryenStoreSetPtr : BinaryenExpressionRef BinaryenExpressionRef -> _void) 1100 | 1101 | (defbinaryen* BinaryenStoreGetValue : BinaryenExpressionRef -> BinaryenExpressionRef) 1102 | 1103 | (defbinaryen* BinaryenStoreSetValue : BinaryenExpressionRef BinaryenExpressionRef -> _void) 1104 | 1105 | ; Const 1106 | 1107 | (defbinaryen* BinaryenConstGetValueI32 : BinaryenExpressionRef -> _int32) 1108 | (defbinaryen* BinaryenConstSetValueI32 : BinaryenExpressionRef _int32 -> _void) 1109 | 1110 | (defbinaryen* BinaryenConstGetValueI64 : BinaryenExpressionRef -> _int64) 1111 | (defbinaryen* BinaryenConstSetValueI64 : BinaryenExpressionRef _int64 -> _void) 1112 | 1113 | (defbinaryen* BinaryenConstGetValueI64Low : BinaryenExpressionRef -> _int32) 1114 | (defbinaryen* BinaryenConstSetValueI64Low : BinaryenExpressionRef _int32 -> _void) 1115 | 1116 | (defbinaryen* BinaryenConstGetValueI64High : BinaryenExpressionRef -> _int32) 1117 | (defbinaryen* BinaryenConstSetValueI64High : BinaryenExpressionRef _int32 -> _void) 1118 | 1119 | (defbinaryen* BinaryenConstGetValueF32 : BinaryenExpressionRef -> _float) 1120 | (defbinaryen* BinaryenConstSetValueF32 : BinaryenExpressionRef _float -> _void) 1121 | 1122 | (defbinaryen* BinaryenConstGetValueF64 : BinaryenExpressionRef -> _double) 1123 | (defbinaryen* BinaryenConstSetValueF64 : BinaryenExpressionRef _double -> _void) 1124 | 1125 | (defbinaryen* BinaryenConstGetValueV128 : BinaryenExpressionRef -> (_array _uint8 16)) 1126 | (defbinaryen* BinaryenConstSetValueV128 : BinaryenExpressionRef (_array _uint8 16) -> _void) 1127 | 1128 | ; Unary 1129 | 1130 | (defbinaryen* BinaryenUnaryGetOp : BinaryenExpressionRef -> BinaryenOp) 1131 | (defbinaryen* BinaryenUnarySetOp : BinaryenExpressionRef BinaryenOp -> _void) 1132 | 1133 | (defbinaryen* BinaryenUnaryGetValue : BinaryenExpressionRef -> BinaryenExpressionRef) 1134 | (defbinaryen* BinaryenUnarySetValue : BinaryenExpressionRef BinaryenExpressionRef -> _void) 1135 | 1136 | ; Binary 1137 | 1138 | (defbinaryen* BinaryenBinaryGetOp : BinaryenExpressionRef -> BinaryenOp) 1139 | (defbinaryen* BinaryenBinarySetOp : BinaryenExpressionRef BinaryenOp -> _void) 1140 | 1141 | (defbinaryen* BinaryenBinaryGetLeft : BinaryenExpressionRef -> BinaryenExpressionRef) 1142 | (defbinaryen* BinaryenBinarySetLeft : BinaryenExpressionRef BinaryenExpressionRef -> _void) 1143 | 1144 | (defbinaryen* BinaryenBinaryGetRight : BinaryenExpressionRef -> BinaryenExpressionRef) 1145 | (defbinaryen* BinaryenBinarySetRight : BinaryenExpressionRef BinaryenExpressionRef -> _void) 1146 | 1147 | ; Select 1148 | 1149 | (defbinaryen* BinaryenSelectGetIfTrue : BinaryenExpressionRef -> BinaryenExpressionRef) 1150 | (defbinaryen* BinaryenSelectSetIfTrue : BinaryenExpressionRef BinaryenExpressionRef -> _void) 1151 | 1152 | (defbinaryen* BinaryenSelectGetIfFalse : BinaryenExpressionRef -> BinaryenExpressionRef) 1153 | (defbinaryen* BinaryenSelectSetIfFalse : BinaryenExpressionRef BinaryenExpressionRef -> _void) 1154 | 1155 | (defbinaryen* BinaryenSelectGetCondition : BinaryenExpressionRef -> BinaryenExpressionRef) 1156 | (defbinaryen* BinaryenSelectSetCondition : BinaryenExpressionRef BinaryenExpressionRef -> _void) 1157 | 1158 | ; Drop 1159 | 1160 | (defbinaryen* BinaryenDropGetValue : BinaryenExpressionRef -> BinaryenExpressionRef) 1161 | (defbinaryen* BinaryenDropSetValue : BinaryenExpressionRef BinaryenExpressionRef -> _void) 1162 | 1163 | ; Return 1164 | 1165 | (defbinaryen* BinaryenReturnGetValue : BinaryenExpressionRef -> BinaryenExpressionRef) 1166 | (defbinaryen* BinaryenReturnSetValue : BinaryenExpressionRef BinaryenExpressionRef -> _void) 1167 | 1168 | ; AtomicRMW 1169 | 1170 | (defbinaryen*-get/set-fields AtomicRMW 1171 | (Op BinaryenOp) 1172 | (Bytes _uint32) 1173 | (Offset _uint32) 1174 | (Ptr BinaryenExpressionRef) 1175 | (Value BinaryenExpressionRef)) 1176 | 1177 | ; AtomicCmpxchg 1178 | 1179 | (defbinaryen*-get/set-fields AtomicCmpxchg 1180 | (Bytes _uint32) 1181 | (Offset _uint32) 1182 | (Ptr BinaryenExpressionRef) 1183 | (Expected BinaryenExpressionRef) 1184 | (Replacement BinaryenExpressionRef)) 1185 | 1186 | ; AtomicWait 1187 | 1188 | (defbinaryen*-get/set-fields AtomicWait 1189 | (Ptr BinaryenExpressionRef) 1190 | (Expected BinaryenExpressionRef) 1191 | (Timeout BinaryenExpressionRef) 1192 | (ExpectedType BinaryenType)) 1193 | 1194 | ; AtomicNotify 1195 | 1196 | (defbinaryen*-get/set-fields AtomicNotify 1197 | (Ptr BinaryenExpressionRef) 1198 | (NotifyCount BinaryenExpressionRef)) 1199 | 1200 | ; AtomicFence 1201 | 1202 | (defbinaryen*-get/set AtomicFence Order _uint8) 1203 | 1204 | ; SIMDExtract 1205 | 1206 | (defbinaryen*-get/set-fields SIMDExtract 1207 | (Op BinaryenExpressionRef) 1208 | (Vec BinaryenExpressionRef) 1209 | (Index _uint8)) 1210 | 1211 | ; SIMDReplace 1212 | 1213 | (defbinaryen*-get/set-fields SIMDReplace 1214 | (Op BinaryenExpressionRef) 1215 | (Vec BinaryenExpressionRef) 1216 | (Index _uint8) 1217 | (Value BinaryenExpressionRef)) 1218 | 1219 | ; SIMDShuffle 1220 | 1221 | (defbinaryen*-get/set-fields SIMDShuffle 1222 | (Left BinaryenExpressionRef) 1223 | (Right BinaryenExpressionRef)) 1224 | 1225 | (defbinaryen* BinaryenSIMDShuffleGetMask : 1226 | BinaryenExpressionRef (_list o _uint8 16) -> _void) 1227 | (defbinaryen* BinaryenSIMDShuffleSetMask : 1228 | BinaryenExpressionRef -> (_array _uint8 16)) 1229 | 1230 | ; SIMDTernary 1231 | 1232 | (defbinaryen*-get/set-fields SIMDTernary 1233 | (Op BinaryenExpressionRef) 1234 | (A BinaryenExpressionRef) 1235 | (B BinaryenExpressionRef) 1236 | (C BinaryenExpressionRef)) 1237 | 1238 | ; SIMDShift 1239 | 1240 | (defbinaryen*-get/set-fields SIMDShift 1241 | (Op BinaryenOp) 1242 | (Vec BinaryenExpressionRef) 1243 | (Shift BinaryenExpressionRef)) 1244 | 1245 | ; SIMDLoad 1246 | 1247 | (defbinaryen*-get/set-fields SIMDLoad 1248 | (Op BinaryenOp) 1249 | (Offset _uint32) 1250 | (Align _uint32) 1251 | (Ptr BinaryenExpressionRef)) 1252 | 1253 | ; SIMDLoadStoreLane 1254 | 1255 | (defbinaryen*-get/set-fields SIMDLoadStoreLane 1256 | (Op BinaryenOp) 1257 | (Offset _uint32) 1258 | (Align _uint32) 1259 | (Index _uint8) 1260 | (Ptr BinaryenExpressionRef) 1261 | (Vec BinaryenExpressionRef)) 1262 | 1263 | (defbinaryen* BinaryenSIMDLoadStoreLaneIsStore : 1264 | BinaryenExpressionRef -> _bool) 1265 | 1266 | 1267 | ; MemoryInit 1268 | 1269 | (defbinaryen*-get/set-fields MemoryInit 1270 | (Segment _uint32) 1271 | (Dest BinaryenExpressionRef) 1272 | (Offset BinaryenExpressionRef) 1273 | (Size BinaryenExpressionRef)) 1274 | 1275 | ; DataDrop 1276 | 1277 | (defbinaryen*-get/set DataDrop Segment _uint32) 1278 | 1279 | ; MemoryCopy 1280 | 1281 | (defbinaryen*-get/set-fields MemoryCopy 1282 | (Dest BinaryenExpressionRef) 1283 | (Source BinaryenExpressionRef) 1284 | (Size BinaryenExpressionRef)) 1285 | 1286 | ; MemoryFill 1287 | 1288 | (defbinaryen*-get/set-fields MemoryFill 1289 | (Dest BinaryenExpressionRef) 1290 | (Value BinaryenExpressionRef) 1291 | (Size BinaryenExpressionRef)) 1292 | 1293 | ; RefIs 1294 | 1295 | (defbinaryen*-get/set-fields RefIs 1296 | (Op BinaryenOp) 1297 | (Value BinaryenExpressionRef)) 1298 | 1299 | ; RefAs 1300 | 1301 | (defbinaryen*-get/set-fields RefAs 1302 | (Op BinaryenOp) 1303 | (Value BinaryenExpressionRef)) 1304 | 1305 | ; RefFunc 1306 | 1307 | (defbinaryen*-get/set-fields RefFunc 1308 | (Func _string)) 1309 | 1310 | ; RefEq 1311 | 1312 | (defbinaryen*-get/set-fields RefEq 1313 | (Left BinaryenExpressionRef) 1314 | (Right BinaryenExpressionRef)) 1315 | 1316 | ; Try 1317 | 1318 | (defbinaryen*-get/set-fields Try 1319 | (Name _string) 1320 | (Body BinaryenExpressionRef) 1321 | (DelegateTarget _string)) 1322 | 1323 | (defbinaryen* BinaryenTryGetNumCatchTags : BinaryenExpressionRef -> BinaryenIndex) 1324 | (defbinaryen* BinaryenTryGetNumCatchBodies : BinaryenExpressionRef -> BinaryenIndex) 1325 | 1326 | (defbinaryen* BinaryenTryGetCatchTagAt : BinaryenExpressionRef BinaryenIndex -> _string) 1327 | (defbinaryen* BinaryenTrySetCatchTagAt : BinaryenExpressionRef BinaryenIndex _string -> _void) 1328 | 1329 | (defbinaryen* BinaryenTryAppendCatchTag : BinaryenExpressionRef _string -> BinaryenIndex) 1330 | 1331 | (defbinaryen* BinaryenTryInsertCatchTagAt : BinaryenExpressionRef BinaryenIndex _string -> _void) 1332 | 1333 | (defbinaryen* BinaryenTryRemoveCatchTagAt : BinaryenExpressionRef BinaryenIndex -> _string) 1334 | 1335 | (defbinaryen* BinaryenTryGetCatchBodyAt : BinaryenExpressionRef BinaryenIndex -> BinaryenExpressionRef) 1336 | (defbinaryen* BinaryenTrySetCatchBodyAt : BinaryenExpressionRef BinaryenIndex BinaryenExpressionRef -> _void) 1337 | 1338 | (defbinaryen* BinaryenTryAppendCatchBody : BinaryenExpressionRef BinaryenExpressionRef -> BinaryenIndex) 1339 | 1340 | (defbinaryen* BinaryenTryInsertCatchBodyAt : BinaryenExpressionRef BinaryenIndex BinaryenExpressionRef -> _void) 1341 | 1342 | (defbinaryen* BinaryenTryRemoveCatchBodyAt : BinaryenExpressionRef BinaryenIndex -> BinaryenExpressionRef) 1343 | 1344 | (defbinaryen* BinaryenTryHasCatchAll : BinaryenExpressionRef -> _stdbool) 1345 | 1346 | (defbinaryen* BinaryenTryIsDelegate : BinaryenExpressionRef -> _stdbool) 1347 | 1348 | ; Throw 1349 | 1350 | (defbinaryen*-get/set-fields Throw 1351 | (Tag _string)) 1352 | 1353 | (defbinaryen* BinaryenThrowGetNumOperands : BinaryenExpressionRef -> BinaryenIndex) 1354 | 1355 | (defbinaryen* BinaryenThrowGetOperandAt : 1356 | BinaryenExpressionRef BinaryenIndex -> BinaryenExpressionRef) 1357 | (defbinaryen* BinaryenThrowSetOperandAt : 1358 | BinaryenExpressionRef BinaryenIndex BinaryenExpressionRef -> _void) 1359 | 1360 | (defbinaryen* BinaryenThrowAppendOperand : 1361 | BinaryenExpressionRef BinaryenExpressionRef -> BinaryenIndex) 1362 | 1363 | (defbinaryen* BinaryenThrowInsertOperandAt : BinaryenExpressionRef BinaryenIndex BinaryenExpressionRef -> _void) 1364 | 1365 | (defbinaryen* BinaryenThrowRemoveOperandAt : BinaryenExpressionRef BinaryenIndex -> BinaryenExpressionRef) 1366 | 1367 | ; Rethrow 1368 | 1369 | (defbinaryen*-get/set-fields Rethrow 1370 | (Target _string)) 1371 | 1372 | ; TupleMake 1373 | 1374 | (defbinaryen*-get TupleMake NumOperands BinaryenIndex) 1375 | 1376 | (defbinaryen*-get/set TupleMake OperandAt [BinaryenIndex] BinaryenExpressionRef) 1377 | 1378 | (defbinaryen* BinaryenTupleMakeAppendOperand : 1379 | BinaryenExpressionRef BinaryenExpressionRef -> BinaryenIndex) 1380 | 1381 | (defbinaryen* BinaryenTupleMakeInsertOperandAt : 1382 | BinaryenExpressionRef BinaryenIndex BinaryenExpressionRef -> _void) 1383 | 1384 | (defbinaryen* BinaryenTupleMakeRemoveOperandAt : 1385 | BinaryenExpressionRef BinaryenIndex -> BinaryenExpressionRef) 1386 | 1387 | ; TupleExtract 1388 | 1389 | (defbinaryen*-get/set-fields TupleExtract 1390 | (Tuple BinaryenExpressionRef) 1391 | (Index BinaryenIndex)) 1392 | 1393 | ; I31New 1394 | 1395 | (defbinaryen*-get/set-fields I31New 1396 | (Value BinaryenExpressionRef)) 1397 | 1398 | ; I31Get 1399 | 1400 | (defbinaryen*-get/set-fields I31Get 1401 | (I31 BinaryenExpressionRef)) 1402 | 1403 | ;; We use I31 only here due to binaryen #3613 1404 | (defbinaryen*-get I31 IsSigned _stdbool) 1405 | 1406 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1407 | ; 1408 | ; FUNCTIONS 1409 | ; 1410 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1411 | 1412 | (define BinaryenFunctionRef (_cpointer 'BinaryenFunction)) 1413 | 1414 | (defbinaryen* BinaryenAddFunction : 1415 | BinaryenModuleRef 1416 | _string 1417 | BinaryenType 1418 | BinaryenType 1419 | [varTypes : (_list i BinaryenType)] 1420 | [BinaryenIndex = (length varTypes)] 1421 | BinaryenExpressionRef 1422 | -> BinaryenFunctionRef) 1423 | 1424 | (defbinaryen* BinaryenGetFunction : 1425 | BinaryenModuleRef _string -> BinaryenFunctionRef) 1426 | 1427 | (defbinaryen* BinaryenGetNumFunctions : 1428 | BinaryenModuleRef -> BinaryenIndex) 1429 | 1430 | (defbinaryen* BinaryenGetFunctionByIndex : 1431 | BinaryenModuleRef BinaryenIndex -> BinaryenFunctionRef) 1432 | 1433 | (defbinaryen* BinaryenAddFunctionImport : 1434 | BinaryenModuleRef _string _string _string BinaryenType BinaryenType -> _void) 1435 | 1436 | (defbinaryen* BinaryenAddTableImport : 1437 | BinaryenModuleRef _string _string _string -> _void) 1438 | 1439 | (defbinaryen* BinaryenAddMemoryImport : 1440 | BinaryenModuleRef _string _string _string _uint8 -> _void) 1441 | 1442 | (defbinaryen* BinaryenAddGlobalImport : 1443 | BinaryenModuleRef _string _string _string BinaryenType _stdbool -> _void) 1444 | 1445 | (defbinaryen* BinaryenAddTagImport : 1446 | BinaryenModuleRef _string _string _string BinaryenType BinaryenType -> _void) 1447 | 1448 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1449 | ; 1450 | ; EXPORTS 1451 | ; 1452 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1453 | 1454 | (define BinaryenExportRef (_cpointer 'BinaryenExportRef)) 1455 | 1456 | (defbinaryen* BinaryenAddFunctionExport : 1457 | BinaryenModuleRef _string _string -> BinaryenExportRef) 1458 | 1459 | (defbinaryen* BinaryenAddTableExport : 1460 | BinaryenModuleRef _string _string -> BinaryenExportRef) 1461 | 1462 | (defbinaryen* BinaryenAddMemoryExport : 1463 | BinaryenModuleRef _string _string -> BinaryenExportRef) 1464 | 1465 | (defbinaryen* BinaryenAddGlobalExport : 1466 | BinaryenModuleRef _string _string -> BinaryenExportRef) 1467 | 1468 | (defbinaryen* BinaryenAddTagExport : 1469 | BinaryenModuleRef _string _string -> BinaryenExportRef) 1470 | 1471 | (defbinaryen* BinaryenGetExport : 1472 | BinaryenModuleRef _string -> BinaryenExportRef) 1473 | 1474 | (defbinaryen* BinaryenRemoveExport : 1475 | BinaryenModuleRef _string -> _void) 1476 | 1477 | (defbinaryen* BinaryenGetNumExports : 1478 | BinaryenModuleRef -> BinaryenIndex) 1479 | 1480 | (defbinaryen* BinaryenGetExportByIndex : 1481 | BinaryenModuleRef BinaryenIndex -> BinaryenExportRef) 1482 | 1483 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1484 | ; 1485 | ; GLOBALS 1486 | ; 1487 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1488 | 1489 | (define BinaryenGlobalRef (_cpointer 'BinaryenGlobalRef)) 1490 | 1491 | 1492 | (defbinaryen* BinaryenAddGlobal : 1493 | BinaryenModuleRef _string BinaryenType _stdbool BinaryenExpressionRef -> BinaryenGlobalRef) 1494 | 1495 | (defbinaryen* BinaryenGetGlobal : 1496 | BinaryenModuleRef _string -> BinaryenGlobalRef) 1497 | 1498 | (defbinaryen* BinaryenRemoveGlobal : 1499 | BinaryenModuleRef _string -> _void) 1500 | 1501 | (defbinaryen* BinaryenGetNumGlobals : BinaryenModuleRef -> BinaryenIndex) 1502 | 1503 | (defbinaryen* BinaryenGetGlobalByIndex : 1504 | BinaryenModuleRef BinaryenIndex -> BinaryenGlobalRef) 1505 | 1506 | 1507 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1508 | ; 1509 | ; EVENTS 1510 | ; 1511 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1512 | 1513 | (define BinaryenTagRef (_cpointer 'BinaryenTag)) 1514 | 1515 | (defbinaryen* BinaryenAddTag : 1516 | BinaryenModuleRef _string BinaryenType BinaryenType -> BinaryenTagRef) 1517 | 1518 | (defbinaryen* BinaryenGetTag : 1519 | BinaryenModuleRef _string -> BinaryenTagRef) 1520 | 1521 | (defbinaryen* BinaryenRemoveTag : 1522 | BinaryenModuleRef _string -> _void) 1523 | 1524 | ;; Table 1525 | (define BinaryenTableRef (_cpointer 'BinaryenTable)) 1526 | 1527 | (defbinaryen* BinaryenAddTable : 1528 | BinaryenModuleRef _string BinaryenIndex BinaryenIndex BinaryenType -> BinaryenTableRef) 1529 | 1530 | (defbinaryen* BinaryenRemoveTable : 1531 | BinaryenModuleRef _string -> _void) 1532 | 1533 | (defbinaryen* BinaryenGetNumTables : 1534 | BinaryenModuleRef -> BinaryenIndex) 1535 | 1536 | (defbinaryen* BinaryenGetTable : BinaryenModuleRef _string -> BinaryenTableRef) 1537 | 1538 | (defbinaryen* BinaryenGetTableByIndex : BinaryenModuleRef BinaryenIndex -> BinaryenTableRef) 1539 | 1540 | ;; Elem segments 1541 | (define BinaryenElementSegmentRef (_cpointer 'BinaryenElementSegment)) 1542 | 1543 | (defbinaryen* BinaryenAddActiveElementSegment : 1544 | BinaryenModuleRef 1545 | _string 1546 | _string 1547 | [funcNames : (_list i _string)] 1548 | [BinaryenIndex = (length funcNames)] 1549 | BinaryenExpressionRef 1550 | -> BinaryenElementSegmentRef) 1551 | 1552 | (defbinaryen* BinaryenAddPassiveElementSegment : 1553 | BinaryenModuleRef 1554 | _string 1555 | [funcNames : (_list i _string)] 1556 | [BinaryenIndex = (length funcNames)] 1557 | -> BinaryenElementSegmentRef) 1558 | 1559 | (defbinaryen* BinaryenRemoveElementSegment : 1560 | BinaryenModuleRef _string -> _void) 1561 | 1562 | (defbinaryen* BinaryenGetNumElementSegments : 1563 | BinaryenModuleRef -> BinaryenIndex) 1564 | 1565 | (defbinaryen* BinaryenGetElementSegment : 1566 | BinaryenModuleRef _string -> BinaryenElementSegmentRef) 1567 | 1568 | (defbinaryen* BinaryenGetElementSegmentByIndex : 1569 | BinaryenModuleRef BinaryenIndex -> BinaryenElementSegmentRef) 1570 | 1571 | ;; Memory - one per module 1572 | 1573 | (defbinaryen* BinaryenSetMemory : 1574 | BinaryenModuleRef BinaryenIndex BinaryenIndex _string 1575 | [segments : (_list i _string)] 1576 | [segmentPassing : (_list i _stdbool)] 1577 | [segmentOffsets : (_list i BinaryenExpressionRef)] 1578 | [segmentSizes : (_list i BinaryenIndex)] 1579 | [BinaryenIndex = (length segments)] ; all lists here need to have the same length 1580 | _stdbool -> _void) 1581 | 1582 | (defbinaryen* BinaryenGetNumMemorySegments : 1583 | BinaryenModuleRef -> _uint32) 1584 | 1585 | (defbinaryen* BinaryenGetMemorySegmentByteOffset : 1586 | BinaryenModuleRef BinaryenIndex -> _uint32) 1587 | 1588 | (defbinaryen* BinaryenGetMemorySegmentByteLength : 1589 | BinaryenModuleRef BinaryenIndex -> _size) 1590 | 1591 | (defbinaryen* BinaryenGetMemorySegmentPassive : 1592 | BinaryenModuleRef BinaryenIndex -> _stdbool) 1593 | 1594 | (defbinaryen* BinaryenCopyMemorySegmentData : 1595 | BinaryenModuleRef BinaryenIndex _string -> _void) 1596 | 1597 | ; Start function - one per module 1598 | 1599 | (defbinaryen* BinaryenSetStart : 1600 | BinaryenModuleRef BinaryenFunctionRef -> _void) 1601 | 1602 | ; Features 1603 | 1604 | (defbinaryen* BinaryenModuleGetFeatures : BinaryenModuleRef -> BinaryenFeatures) 1605 | (defbinaryen* BinaryenModuleSetFeatures : BinaryenModuleRef BinaryenFeatures -> _void) 1606 | 1607 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1608 | ; 1609 | ; MODULE OPERATIONS 1610 | ; 1611 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1612 | 1613 | (defbinaryen* BinaryenModuleParse : _string -> BinaryenModuleRef) 1614 | 1615 | (defbinaryen* BinaryenModulePrint : BinaryenModuleRef -> _void) 1616 | 1617 | (defbinaryen* BinaryenModulePrintAsmjs : BinaryenModuleRef -> _void) 1618 | 1619 | (defbinaryen* BinaryenModuleValidate : BinaryenModuleRef -> _stdbool) 1620 | 1621 | (defbinaryen* BinaryenModuleOptimize : BinaryenModuleRef -> _void) 1622 | 1623 | (defbinaryen* BinaryenModuleUpdateMaps : BinaryenModuleRef -> _void) 1624 | 1625 | (defbinaryen* BinaryenGetOptimizeLevel : -> _int) 1626 | 1627 | (defbinaryen* BinaryenSetOptimizeLevel : _int -> _void) 1628 | 1629 | (defbinaryen* BinaryenGetShrinkLevel : -> _int) 1630 | 1631 | (defbinaryen* BinaryenSetShrinkLevel : _int -> _void) 1632 | 1633 | (defbinaryen* BinaryenGetDebugInfo : -> _stdbool) 1634 | 1635 | (defbinaryen* BinaryenSetDebugInfo : _stdbool -> _void) 1636 | 1637 | (defbinaryen* BinaryenGetLowMemoryUnused : -> _stdbool) 1638 | 1639 | (defbinaryen* BinaryenSetLowMemoryUnused : _stdbool -> _void) 1640 | 1641 | (defbinaryen* BinaryenGetZeroFilledMemory : -> _stdbool) 1642 | 1643 | (defbinaryen* BinaryenSetZeroFilledMemory : _stdbool -> _void) 1644 | 1645 | (defbinaryen* BinaryenGetFastMath : -> _stdbool) 1646 | 1647 | (defbinaryen* BinaryenSetFastMath : _stdbool -> _void) 1648 | 1649 | (defbinaryen* BinaryenGetPassArgument : _string -> _string) 1650 | 1651 | (defbinaryen* BinaryenSetPassArgument : _string _string -> _void) 1652 | 1653 | (defbinaryen* BinaryenClearPassArguments : -> _void) 1654 | 1655 | (defbinaryen* BinaryenGetAlwaysInlineMaxSize : -> BinaryenIndex) 1656 | 1657 | (defbinaryen* BinaryenSetAlwaysInlineMaxSize : BinaryenIndex -> _void) 1658 | 1659 | (defbinaryen* BinaryenGetFlexibleInlineMaxSize : -> BinaryenIndex) 1660 | 1661 | (defbinaryen* BinaryenSetFlexibleInlineMaxSize : BinaryenIndex -> _void) 1662 | 1663 | (defbinaryen* BinaryenGetOneCallerInlineMaxSize : -> BinaryenIndex) 1664 | 1665 | (defbinaryen* BinaryenSetOneCallerInlineMaxSize : BinaryenIndex -> _void) 1666 | 1667 | (defbinaryen* BinaryenGetAllowInliningFunctionsWithLoops : -> _stdbool) 1668 | 1669 | (defbinaryen* BinaryenSetAllowInliningFunctionsWithLoops : _stdbool -> _void) 1670 | 1671 | (defbinaryen* BinaryenModuleRunPasses : 1672 | BinaryenModuleRef [passes : (_list i _string)] [BinaryenIndex = (length passes)] -> _void) 1673 | 1674 | (defbinaryen* BinaryenModuleAutoDrop : BinaryenModuleRef -> _void) 1675 | 1676 | (defbinaryen* BinaryenModuleWrite : BinaryenModuleRef [output : _bytes] [_size = (length output)] -> _size) 1677 | 1678 | (defbinaryen* BinaryenModuleWriteText : 1679 | BinaryenModuleRef [output : _bytes] [_size = (length output)] -> _size) 1680 | 1681 | (define-cstruct _BinaryenBufferSizes 1682 | ([outputBytes _size] 1683 | [sourceMapBytes _size])) 1684 | 1685 | (defbinaryen* BinaryenModuleWriteWithSourceMap : 1686 | BinaryenModuleRef _string 1687 | [output : (_bytes o outputSize)] 1688 | [outputSize : _size] 1689 | [sourceMap : (_bytes o sourceMapSize)] 1690 | [sourceMapSize : _size] 1691 | -> [res : _BinaryenBufferSizes] 1692 | -> (values res output sourceMap)) 1693 | 1694 | (define-cstruct _BinaryenModuleAllocateAndWriteResult 1695 | ([binary _bytes] 1696 | [binaryBytes _size] 1697 | [sourceMap _string])) ; need to explicit free buffers 1698 | ; TODO can we move the returned buffers into gc? 1699 | (provide BinaryenModuleAllocateAndWriteResult-binary) 1700 | 1701 | 1702 | (defbinaryen* BinaryenModuleAllocateAndWrite : 1703 | BinaryenModuleRef _string -> _BinaryenModuleAllocateAndWriteResult) 1704 | 1705 | (define _string/free 1706 | (make-ctype _pointer 1707 | #false 1708 | (lambda (x) 1709 | (begin0 (cast x _pointer _string) 1710 | (free x))))) 1711 | 1712 | (defbinaryen* BinaryenModuleAllocateAndWriteText : 1713 | BinaryenModuleRef -> _string/free) 1714 | 1715 | (defbinaryen* BinaryenModuleRead : 1716 | [input : _bytes] 1717 | [inputSize : _size = (bytes-length input)] -> BinaryenModuleRef) 1718 | 1719 | (defbinaryen* BinaryenModuleInterpret : 1720 | BinaryenModuleRef -> _void) 1721 | 1722 | (defbinaryen* BinaryenModuleAddDebugInfoFileName : 1723 | BinaryenModuleRef _path -> BinaryenIndex) 1724 | 1725 | (defbinaryen* BinaryenModuleGetDebugInfoFileName : 1726 | BinaryenModuleRef BinaryenIndex -> _path) 1727 | 1728 | 1729 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1730 | ; 1731 | ; FUNCTION OPERATIONS 1732 | ; 1733 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1734 | 1735 | (defbinaryen* BinaryenFunctionGetName : 1736 | BinaryenFunctionRef -> _string) 1737 | 1738 | (defbinaryen* BinaryenFunctionGetParams : BinaryenFunctionRef -> BinaryenType) 1739 | 1740 | (defbinaryen* BinaryenFunctionGetResults : BinaryenFunctionRef -> BinaryenType) 1741 | 1742 | (defbinaryen* BinaryenFunctionGetNumVars : BinaryenFunctionRef -> BinaryenIndex) 1743 | 1744 | (defbinaryen* BinaryenFunctionGetVar : BinaryenFunctionRef BinaryenIndex -> BinaryenType) 1745 | 1746 | (defbinaryen* BinaryenFunctionGetNumLocals : BinaryenFunctionRef -> BinaryenIndex) 1747 | 1748 | (defbinaryen* BinaryenFunctionHasLocalName : BinaryenFunctionRef BinaryenIndex -> _stdbool) 1749 | 1750 | (defbinaryen* BinaryenFunctionGetLocalName : BinaryenFunctionRef BinaryenIndex -> _string) 1751 | 1752 | (defbinaryen* BinaryenFunctionSetLocalName : BinaryenFunctionRef BinaryenIndex _string -> _void) 1753 | 1754 | (defbinaryen* BinaryenFunctionGetBody : BinaryenFunctionRef -> BinaryenExpressionRef) 1755 | 1756 | (defbinaryen* BinaryenFunctionSetBody : BinaryenFunctionRef BinaryenExpressionRef -> _void) 1757 | 1758 | (defbinaryen* BinaryenFunctionOptimize : BinaryenFunctionRef BinaryenModuleRef -> _void) 1759 | 1760 | (defbinaryen* BinaryenFunctionRunPasses : BinaryenFunctionRef BinaryenModuleRef [passes : (_list i _string)] [BinaryenIndex = (length passes)] -> _void) 1761 | 1762 | (defbinaryen* BinaryenFunctionSetDebugLocation : 1763 | BinaryenFunctionRef 1764 | BinaryenExpressionRef 1765 | BinaryenIndex 1766 | BinaryenIndex 1767 | BinaryenIndex 1768 | -> _void) 1769 | 1770 | 1771 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1772 | ; 1773 | ; TABLE OPERATIONS 1774 | ; 1775 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1776 | 1777 | (defbinaryen* BinaryenTableGetName : BinaryenTableRef -> _string) 1778 | 1779 | (defbinaryen* BinaryenTableSetName : BinaryenTableRef _string -> _void) 1780 | 1781 | (defbinaryen* BinaryenTableGetInitial : BinaryenTableRef -> BinaryenIndex) 1782 | 1783 | (defbinaryen* BinaryenTableSetInitial : BinaryenTableRef BinaryenIndex -> _void) 1784 | 1785 | (defbinaryen* BinaryenTableHasMax : BinaryenTableRef -> _stdbool) 1786 | 1787 | (defbinaryen* BinaryenTableGetMax : BinaryenTableRef -> BinaryenIndex) 1788 | 1789 | (defbinaryen* BinaryenTableSetMax : BinaryenTableRef BinaryenIndex -> _void) 1790 | 1791 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1792 | ; 1793 | ; ELEM SEGMENT OPERATIONS 1794 | ; 1795 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1796 | 1797 | (defbinaryen*-get/set-fields ElementSegment 1798 | (Name _string) 1799 | (Table _string)) 1800 | 1801 | (defbinaryen*-get ElementSegment 1802 | Offset BinaryenExpressionRef) 1803 | (defbinaryen*-get ElementSegment 1804 | Length BinaryenIndex) 1805 | (defbinaryen*-get ElementSegment 1806 | Data _string) 1807 | (defbinaryen* BinaryenElementSegmentIsPassive : 1808 | BinaryenElementSegmentRef -> _stdbool) 1809 | 1810 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1811 | ; 1812 | ; GLOBAL OPERATIONS 1813 | ; 1814 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1815 | 1816 | 1817 | (defbinaryen* BinaryenGlobalGetName : BinaryenGlobalRef -> _string) 1818 | 1819 | (defbinaryen* BinaryenGlobalGetType : BinaryenGlobalRef -> BinaryenType) 1820 | 1821 | (defbinaryen* BinaryenGlobalIsMutable : BinaryenGlobalRef -> _stdbool) 1822 | 1823 | (defbinaryen* BinaryenGlobalGetInitExpr : BinaryenGlobalRef -> BinaryenExpressionRef) 1824 | 1825 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1826 | ; 1827 | ; TAG OPERATIONS 1828 | ; 1829 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1830 | 1831 | (defbinaryen* BinaryenTagGetName : BinaryenTagRef -> _string) 1832 | 1833 | (defbinaryen* BinaryenTagGetParams : BinaryenTagRef -> BinaryenType) 1834 | 1835 | (defbinaryen* BinaryenTagGetResults : BinaryenTagRef -> BinaryenType) 1836 | 1837 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1838 | ; 1839 | ; IMPORT OPERATIONS 1840 | ; 1841 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1842 | 1843 | (defbinaryen* BinaryenFunctionImportGetModule : BinaryenFunctionRef -> _string) 1844 | 1845 | (defbinaryen* BinaryenTableImportGetModule : BinaryenTableRef -> _string) 1846 | 1847 | (defbinaryen* BinaryenGlobalImportGetModule : BinaryenGlobalRef -> _string) 1848 | 1849 | (defbinaryen* BinaryenTagImportGetModule : BinaryenTagRef -> _string) 1850 | 1851 | (defbinaryen* BinaryenFunctionImportGetBase : BinaryenFunctionRef -> _string) 1852 | 1853 | (defbinaryen* BinaryenTableImportGetBase : BinaryenTableRef -> _string) 1854 | 1855 | (defbinaryen* BinaryenGlobalImportGetBase : BinaryenGlobalRef -> _string) 1856 | 1857 | (defbinaryen* BinaryenTagImportGetBase : BinaryenTagRef -> _string) 1858 | 1859 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1860 | ; 1861 | ; EXPORT OPERATIONS 1862 | ; 1863 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1864 | 1865 | (defbinaryen* BinaryenExportGetKind : BinaryenExportRef -> BinaryenExternalKind) 1866 | 1867 | (defbinaryen* BinaryenExportGetName : BinaryenExportRef -> _string) 1868 | 1869 | (defbinaryen* BinaryenExportGetValue : BinaryenExportRef -> _string) 1870 | 1871 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1872 | ; 1873 | ; CUSTOM SECTIONS 1874 | ; 1875 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1876 | 1877 | (defbinaryen* BinaryenAddCustomSection : 1878 | BinaryenModuleRef _string 1879 | [contents : _bytes] 1880 | [contentsSize : BinaryenIndex = (bytes-length contents)] -> _void) 1881 | 1882 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1883 | ; 1884 | ; EFFECT ANALYZER 1885 | ; 1886 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1887 | 1888 | (define BinaryenSideEffects _uint32) 1889 | 1890 | (defbinaryen* BinaryenSideEffectNone : -> BinaryenSideEffects) 1891 | (defbinaryen* BinaryenSideEffectBranches : -> BinaryenSideEffects) 1892 | (defbinaryen* BinaryenSideEffectCalls : -> BinaryenSideEffects) 1893 | (defbinaryen* BinaryenSideEffectReadsLocal : -> BinaryenSideEffects) 1894 | (defbinaryen* BinaryenSideEffectWritesLocal : -> BinaryenSideEffects) 1895 | (defbinaryen* BinaryenSideEffectReadsGlobal : -> BinaryenSideEffects) 1896 | (defbinaryen* BinaryenSideEffectWritesGlobal : -> BinaryenSideEffects) 1897 | (defbinaryen* BinaryenSideEffectReadsMemory : -> BinaryenSideEffects) 1898 | (defbinaryen* BinaryenSideEffectWritesMemory : -> BinaryenSideEffects) 1899 | (defbinaryen* BinaryenSideEffectReadsTable : -> BinaryenSideEffects) 1900 | (defbinaryen* BinaryenSideEffectWritesTable : -> BinaryenSideEffects) 1901 | (defbinaryen* BinaryenSideEffectImplicitTrap : -> BinaryenSideEffects) 1902 | (defbinaryen* BinaryenSideEffectTrapsNeverHappen : -> BinaryenSideEffects) 1903 | (defbinaryen* BinaryenSideEffectIsAtomic : -> BinaryenSideEffects) 1904 | (defbinaryen* BinaryenSideEffectThrows : -> BinaryenSideEffects) 1905 | (defbinaryen* BinaryenSideEffectDanglingPop : -> BinaryenSideEffects) 1906 | (defbinaryen* BinaryenSideEffectAny : -> BinaryenSideEffects) 1907 | 1908 | (defbinaryen* BinaryenExpressionGetSideEffects : BinaryenExpressionRef BinaryenModuleRef -> BinaryenSideEffects) 1909 | 1910 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1911 | ; 1912 | ; CFG / Relooper 1913 | ; 1914 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1915 | 1916 | (define RelooperRef (_cpointer 'Relooper)) 1917 | (define RelooperBlockRef (_cpointer 'RelooperBlock)) 1918 | 1919 | (defbinaryen* RelooperCreate : BinaryenModuleRef -> RelooperRef) 1920 | 1921 | (defbinaryen* RelooperAddBlock : RelooperRef BinaryenExpressionRef -> RelooperBlockRef) 1922 | 1923 | (defbinaryen* RelooperAddBranch : RelooperBlockRef RelooperBlockRef BinaryenExpressionRef BinaryenExpressionRef -> _void) 1924 | 1925 | (defbinaryen* RelooperAddBlockWithSwitch : 1926 | RelooperRef BinaryenExpressionRef BinaryenExpressionRef -> _void) 1927 | 1928 | (defbinaryen* RelooperAddBranchForSwitch : 1929 | RelooperBlockRef RelooperBlockRef 1930 | [indexes : (_list i BinaryenIndex)] [BinaryenIndex = (length indexes)] BinaryenExpressionRef -> _void) 1931 | 1932 | (defbinaryen* RelooperRenderAndDispose : 1933 | RelooperRef RelooperBlockRef BinaryenIndex -> BinaryenExpressionRef) 1934 | 1935 | 1936 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1937 | ; 1938 | ; Expression Runner 1939 | ; 1940 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1941 | 1942 | (define ExpressionRunnerRef (_cpointer 'CEExpressionRunner)) 1943 | (define ExpressionRunnerFlags _uint32) 1944 | 1945 | (defbinaryen* ExpressionRunnerFlagsDefault : -> ExpressionRunnerFlags) 1946 | 1947 | (defbinaryen* ExpressionRunnerFlagsPreserveSideeffects : -> ExpressionRunnerFlags) 1948 | 1949 | (defbinaryen* ExpressionRunnerFlagsTraverseCalls : -> ExpressionRunnerFlags) 1950 | 1951 | (defbinaryen* ExpressionRunnerCreate : BinaryenModuleRef ExpressionRunnerFlags BinaryenIndex BinaryenIndex -> ExpressionRunnerRef) 1952 | 1953 | (defbinaryen* ExpressionRunnerSetLocalValue : ExpressionRunnerRef BinaryenIndex BinaryenExpressionRef -> _stdbool) 1954 | 1955 | (defbinaryen* ExpressionRunnerSetGlobalValue : ExpressionRunnerRef _string BinaryenExpressionRef -> _stdbool) 1956 | 1957 | (defbinaryen* ExpressionRunnerRunAndDispose : ExpressionRunnerRef BinaryenExpressionRef -> BinaryenExpressionRef) 1958 | 1959 | 1960 | 1961 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1962 | ; 1963 | ; Utilities 1964 | ; 1965 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1966 | 1967 | (defbinaryen* BinaryenSetColorsEnabled : _stdbool -> _void) 1968 | 1969 | (defbinaryen* BinaryenAreColorsEnabled : -> _stdbool) 1970 | -------------------------------------------------------------------------------- /private/features.rkt: -------------------------------------------------------------------------------- 1 | #lang racket/base 2 | ;; --------------------------------------------------------------------------------------------------- 3 | 4 | (require "binaryen-ffi.rkt" 5 | racket/contract) 6 | 7 | (provide 8 | (struct-out feature)) 9 | 10 | ;; --------------------------------------------------------------------------------------------------- 11 | 12 | (struct feature (ref)) 13 | 14 | ;; --------------------------------------------------------------------------------------------------- 15 | 16 | (module+ test 17 | 18 | (require rackunit) 19 | 20 | (test-case "pass" 21 | (check-true #true))) 22 | 23 | -------------------------------------------------------------------------------- /private/functions.rkt: -------------------------------------------------------------------------------- 1 | #lang racket/base 2 | ;; --------------------------------------------------------------------------------------------------- 3 | 4 | (require "binaryen-ffi.rkt") 5 | 6 | (provide 7 | function 8 | function-ref 9 | function?) 10 | 11 | ;; --------------------------------------------------------------------------------------------------- 12 | 13 | (struct function (ref)) 14 | 15 | ;; --------------------------------------------------------------------------------------------------- 16 | 17 | (module+ test 18 | 19 | (require rackunit 20 | racket/port) 21 | 22 | (test-case "pass" 23 | (check-true #true))) 24 | -------------------------------------------------------------------------------- /private/modules.rkt: -------------------------------------------------------------------------------- 1 | #lang racket/base 2 | ;; --------------------------------------------------------------------------------------------------- 3 | 4 | (require "binaryen-ffi.rkt") 5 | 6 | (provide 7 | (struct-out module) 8 | current-module 9 | module-parse) 10 | 11 | 12 | ;; --------------------------------------------------------------------------------------------------- 13 | 14 | ; Module is just an opaque type representing a module 15 | (struct module (ref) 16 | #:constructor-name make-module) 17 | 18 | (define current-module (make-parameter #false)) 19 | 20 | (define (module-parse s) 21 | (make-module (BinaryenModuleParse s))) 22 | -------------------------------------------------------------------------------- /private/types.rkt: -------------------------------------------------------------------------------- 1 | #lang racket/base 2 | ;; --------------------------------------------------------------------------------------------------- 3 | 4 | (require "binaryen-ffi.rkt" 5 | racket/contract) 6 | 7 | (provide 8 | (struct-out type) 9 | type-create 10 | type-expand) 11 | 12 | ;; --------------------------------------------------------------------------------------------------- 13 | 14 | (struct type (ref)) 15 | 16 | (define/contract (type-create types) 17 | ((listof type?) . -> . type?) 18 | (type (BinaryenTypeCreate (map type-ref types)))) 19 | 20 | (define/contract (type-expand ty) 21 | (type? . -> . (listof type?)) 22 | (BinaryenTypeExpand (type-ref ty))) 23 | 24 | ;; --------------------------------------------------------------------------------------------------- 25 | 26 | (module+ test 27 | 28 | (require rackunit) 29 | 30 | (test-case "pass" 31 | (check-true #true))) 32 | 33 | -------------------------------------------------------------------------------- /scribblings/api.scrbl: -------------------------------------------------------------------------------- 1 | #lang scribble/manual 2 | 3 | @(require (for-label binaryen)) 4 | 5 | @title{API} 6 | 7 | @include-section[(lib "binaryen/scribblings/types.scrbl")] 8 | @include-section[(lib "binaryen/scribblings/optimizations.scrbl")] 9 | @include-section[(lib "binaryen/scribblings/modules.scrbl")] 10 | @include-section[(lib "binaryen/scribblings/features.scrbl")] 11 | @include-section[(lib "binaryen/scribblings/functions.scrbl")] 12 | @include-section[(lib "binaryen/scribblings/literals.scrbl")] 13 | @include-section[(lib "binaryen/scribblings/exports.scrbl")] 14 | @include-section[(lib "binaryen/scribblings/expressions.scrbl")] 15 | -------------------------------------------------------------------------------- /scribblings/binaryen.scrbl: -------------------------------------------------------------------------------- 1 | #lang scribble/manual 2 | 3 | @(require (for-label binaryen)) 4 | 5 | @title{Racket binaryen bindings} 6 | @defmodule[binaryen] 7 | 8 | This is a wrapper for the Binaryen suite of WebAssembly tools. @deftech{WebAssembly} (or @deftech{Wasm}) is a binary instruction format for a stack-based virtual machine. More information can be found in its @link["https://webassembly.org/"]{webpage}. 9 | 10 | @table-of-contents[] 11 | 12 | @include-section[(lib "binaryen/scribblings/gettingstarted.scrbl")] 13 | @include-section[(lib "binaryen/scribblings/api.scrbl")] 14 | -------------------------------------------------------------------------------- /scribblings/exports.scrbl: -------------------------------------------------------------------------------- 1 | #lang scribble/manual 2 | 3 | @title{Exports} 4 | 5 | An @deftech{export} represent a value that is exported from a WebAssembly @tech{module}. 6 | 7 | @defproc[(export? [x any/c]) boolean?]{ 8 | Checks if the value @racket[x] is a WebAssembly @tech{export}.} 9 | 10 | @defproc[(module-export-function [in string?] [out string?] [#:module mod module? (current-module)]) export?]{ 11 | Exports the function with internal name @racket[in] in module @racket[mod] as @racket[out], returning a reference to the export.} 12 | -------------------------------------------------------------------------------- /scribblings/expressions.scrbl: -------------------------------------------------------------------------------- 1 | #lang scribble/manual 2 | 3 | @title{Expressions} 4 | 5 | An @deftech{expression} is a way to transform @tech{Wasm} values through computation. 6 | 7 | @defproc[(expression? [x any/c]) boolean?]{ 8 | Checks if the value @racket[x] is an expression.} 9 | 10 | @section{Unary expressions} 11 | 12 | A @deftech{unary expression} is an @tech{expression} that operates on one value. 13 | Constructors for unary operations will take the form @tt{make--}, 14 | where @tt{} is the operation name, and @tt{} is the type of the value 15 | expected by the operation. Value types are not checked at the compile time, therefore 16 | it is possible to create invalid WebAssembly modules. Use @racket[module-valid?] to 17 | validate your modules. 18 | 19 | @section{Binary Expressions} 20 | 21 | A @deftech{binary expression} is an @tech{expression} that operates on two values. 22 | 23 | @defproc[(binary-expression? [x any/c]) boolean?]{ 24 | Checks if the value @racket[x] is a binary expression.} 25 | 26 | @defproc[(make-add-int32 [a expression?] [b expression?] [#:module mod module? (current-module)]) binary-expression?]{ 27 | Creates a @tech{binary expression} that represents the addition of @racket[a] to @racket[b], both of which must have type @racket[type-int32].} 28 | 29 | @defproc[(make-sub-int32 [a expression?] [b expression?] [#:module mod module? (current-module)]) binary-expression?]{ 30 | Creates a @tech{binary expression} that represents the subtraction of @racket[b] from @racket[a], both of which must have type @racket[type-int32].} 31 | 32 | @defproc[(make-mult-int32 [a expression?] [b expression?] [#:module mod module? (current-module)]) binary-expression?]{ 33 | Creates a @tech{binary expression} that represents the multiplication between @racket[a] and @racket[b], both of which must have type @racket[type-int32].} 34 | 35 | 36 | @section{Load expression} 37 | 38 | A @deftech{load expression} is an @tech{expression} that loads a value from memory. 39 | 40 | @defproc[(make-load [bytes exact-nonnegative-integer?] 41 | [signed? boolean?] 42 | [offset exact-nonnegative-integer?] 43 | [align exact-nonnegative-integer?] 44 | [type type?] 45 | [ptr expression?] 46 | [#:module mod module? (current-module)]) 47 | load-expression?]{ 48 | Creates a @tech{load expression} that represents the load of @racket[bytes] bytes from memory. The expression @racket[ptr] evaluates to a value through which to access memory, and the loaded value is specified as having type @racket[type].} 49 | 50 | @defproc[(load-atomic? [ld load-expression?]) boolean?]{ 51 | Returns @racket[#true] if the @tech{load-expression} @racket[ld] is atomic, @racket[#false] otherwise.} 52 | 53 | @defproc[(set-load-atomic! [ld load-expression?] [atomic? boolean]) void?]{ 54 | Turns the @tech{load expression} @racket[ld] into an atomic load conditional on the value of @racket[atomic?].} 55 | 56 | -------------------------------------------------------------------------------- /scribblings/features.scrbl: -------------------------------------------------------------------------------- 1 | #lang scribble/manual 2 | 3 | @title{Features} 4 | 5 | Features refer to WebAssembly features that are enabled in a module and generally refer to which WebAssembly proposals have been implemented in Binaryen. 6 | 7 | @defproc[(feature? [x any/c]) boolean?]{ 8 | Predicate to check if value @racket[x] is a feature.} 9 | 10 | @defthing[feature-mvp feature?]{ 11 | This feature refers to the language implemented in the @hyperlink["https://webassembly.github.io/spec/core/"]{WebAssembly MVP}.} 12 | 13 | @defthing[feature-atomics feature?]{ 14 | This feature refers to the @hyperlink["https://github.com/WebAssembly/threads"]{Threads and Atomics WebAssembly} proposal.} 15 | 16 | @defthing[feature-bulk-memory feature?]{ 17 | This feature refers to the @hyperlink["https://github.com/WebAssembly/bulk-memory-operations"]{Bulk Memory proposal}.} 18 | 19 | @defthing[feature-mutable-globals feature?]{ 20 | This feature refers to the @hyperlink["https://github.com/WebAssembly/mutable-global"]{Import and Export of mutable globals proposal}.} 21 | 22 | @defthing[feature-nontrapping-fptoint feature?]{ 23 | This feature refers to the @hyperlink["https://github.com/WebAssembly/nontrapping-float-to-int-conversions"]{Non-trapping float-to-int conversions proposal}.} 24 | 25 | @defthing[feature-sign-extension feature?]{ 26 | This feature refers to the @hyperlink["https://github.com/WebAssembly/sign-extension-ops"]{Sign extension proposal}.} 27 | 28 | @defthing[feature-simd128 feature?]{ 29 | This feature refers to the @hyperlink["https://github.com/webassembly/simd"]{SIMD proposal}.} 30 | 31 | @defthing[feature-exception-handling feature?]{ 32 | This feature refers to the @hyperlink["https://github.com/WebAssembly/exception-handling"]{Exception Handling proposal}.} 33 | 34 | @defthing[feature-tail-call feature?]{ 35 | This feature refers to the @hyperlink["https://github.com/WebAssembly/tail-call"]{Tail calls proposal}.} 36 | 37 | @defthing[feature-reference-types feature?]{ 38 | This feature refers to the @hyperlink["https://github.com/WebAssembly/reference-types"]{Reference Types proposal}.} 39 | 40 | @defthing[feature-multivalue feature?]{ 41 | This feature refers to the @hyperlink["https://github.com/WebAssembly/multi-value"]{Multivalue proposal}.} 42 | 43 | @defthing[feature-gc feature?]{ 44 | This feature refers to the @hyperlink["https://github.com/WebAssembly/gc/"]{Garbage Collection proposal}.} 45 | 46 | @defthing[feature-memory64 feature?]{ 47 | This feature refers to the @hyperlink["https://github.com/WebAssembly/memory64"]{Memory with 64bit indexes proposal}.} 48 | 49 | @defthing[feature-typed-function-references feature?]{ 50 | This feature refers to the @hyperlink["https://github.com/WebAssembly/function-references"]{Typed Function References proposal}.} 51 | 52 | @defthing[feature-all (listof feature?)]{ 53 | List containing all supported features.} 54 | 55 | @defproc[(module-features [mod module? (current-module)]) (listof feature?)]{ 56 | Returns the list of WebAssembly features required by module @racket[mod].} 57 | 58 | @defproc[(set-module-features! [features (listof feature?)] [#:module mod module? (current-module)]) void?]{ 59 | Sets the required features by module @racket[mod] to be @racket[features].} 60 | -------------------------------------------------------------------------------- /scribblings/functions.scrbl: -------------------------------------------------------------------------------- 1 | #lang scribble/manual 2 | 3 | @(require (for-label binaryen)) 4 | 5 | @title{Functions} 6 | 7 | A @deftech{function} is the representation of a @tech{WebAssembly} function. 8 | 9 | @defproc[(module-add-function [name string?] 10 | [arg-types (listof type?)] 11 | [result-types (listof type?)] 12 | [var-types (listof type?)] 13 | [body expression?] 14 | [#:module mod module? (current-module)]) function?]{ 15 | Adds a function to module @racket[mod]. The function's name is @racket[name] and its argument types are given by the types in the list @racket[arg-types]. It returns as many results as there are elements in @racket[result-types], and its elements describe the type of each of the result values. The expression @racket[body] is the expression that computes the result of the function. The list @racket[var-types] contains the types of the local variables of the body of the function. It might seem strange that @racket[var-types] is required at this point but take into consideration that in WebAssembly variables share an index space with arguments. So the locals in the function are arguments whose index starts at 0, followed by the the variables whose index starts at @racket[(length arg-types)]. To setup this index space, we need to know the variable types at the point the function is created. 16 | } 17 | 18 | @defproc[(module-function-count [#:module mod module? (current-module)]) exact-positive-integer?]{ 19 | Takes a module as an argument and it returns the number of functions in the module.} 20 | 21 | @defproc[(module-function [idx exact-nonnegative-integer?] [#:module mod module? (current-module)]) function?]{ 22 | Returns the @tech{function} in @racket[mod] indexed by @racket[idx], where @racket[idx < (module-function-count mod)].} 23 | 24 | @defproc[(function-name [f function?]) string?]{ 25 | Returns the name of function @racket[f].} 26 | 27 | @defproc[(function-parameter-types [f function?]) (listof type?)]{ 28 | Returns the list of types corresponding to the parameters of function @racket[f].} 29 | 30 | @defproc[(function-result-types [f function?]) (listof type?)]{ 31 | Returns the list of types corresponding to the results of function @racket[f].} 32 | 33 | @defproc[(function-variable-count [f function?]) exact-positive-integer?]{ 34 | Returns the number of variables in function @racket[f].} 35 | 36 | @defproc[(function-variable-type [f function?] [n exact-positive-integer?]) type?]{ 37 | Returns the type of the variable with index @racket[n - 1] of function @racket[f].} 38 | 39 | @defproc[(function-get-locals-count [f function?]) exact-nonnegative-integer?]{ 40 | Returns the number of locals in function @racket[f], including parameters.} 41 | 42 | @defproc[(function-local-has-name? [f function?] [n exact-nonnegtive-integer?]) boolean?]{ 43 | Returns @racket[true] if the local indexed by @racket[n] in function @racket[f] has a name, and @racket[false] otherwise.} 44 | -------------------------------------------------------------------------------- /scribblings/gettingstarted.scrbl: -------------------------------------------------------------------------------- 1 | #lang scribble/manual 2 | 3 | @(require (for-label binaryen) 4 | racket/sandbox 5 | scribble/example) 6 | 7 | @(define binaryen-eval 8 | (parameterize ([sandbox-output 'string] 9 | [sandbox-error-output 'string] 10 | [sandbox-memory-limit 50]) 11 | (make-evaluator 'racket/base))) 12 | 13 | @title{Getting Started} 14 | 15 | You are interested in Racket and WebAssembly and somehow found this package? However, you have no idea where to start... well, you came to the right place! 16 | 17 | This package is a set of (experimental) safe high level bindings for @link["https://github.com/WebAssembly/binaryen"]{binaryen}. Binaryen itself is a library written in C++ with a C API, that aims to make compiling to WebAssembly easy, fast, and effective. It is very versatile allowing you to read wasm files, do some transformation and spit it out again, or create your own WebAssembly module from scratch. @margin-note{There will be times when a binaryen function is not available yet in this package. I add more support on a regular basis but might have not done so for the functions you need. In that case, @link["https://github.com/pmatos/racket-binaryen/issues/new"]{open an issue} and I will prioritize your requirements.} 18 | 19 | @section{Reading WebAssembly} 20 | 21 | Consider the following Wasm module in text format: 22 | 23 | @codeblock|{ 24 | (module 25 | (func $double (export "wasm_double") 26 | (param $x i32) (result i32) 27 | (i32.mul (i32.const 2) (local.get $x))) 28 | (func $collatz_iteration (export "wasm_col_iter") 29 | (param $x i32) (result i32) 30 | (i32.add (i32.const 1) 31 | (i32.mul (i32.const 3) (local.get $x))))) 32 | }| 33 | 34 | This example defines two functions that are exported from the module: @tt{double} and @tt{collatz_iteration}. The function @tt{double} is exported with the name @tt{wasm_double} and the function @tt{collatz_iteration} is exported with the name @tt{wasm_col_iter}. 35 | 36 | To parse a module from a string, use the function @racket[module-parse]. 37 | 38 | @examples[#:eval binaryen-eval 39 | (require binaryen 40 | racket/port) 41 | 42 | (define wasm-mod 43 | '(module 44 | (func $double (export "wasm_double") 45 | (param $x i32) (result i32) 46 | (i32.mul (i32.const 2) (local.get $x))) 47 | (func $collatz_iteration (export "wasm_col_iter") 48 | (param $x i32) (result i32) 49 | (i32.add (i32.const 1) 50 | (i32.mul (i32.const 3) (local.get $x)))))) 51 | 52 | (define mod (module-parse (with-output-to-string 53 | (lambda () (write wasm-mod))))) 54 | 55 | (module-valid? mod)] 56 | 57 | We have read the module in, and checked it's valid. We can perform a 58 | number of queries on the module. 59 | 60 | @examples[#:eval binaryen-eval 61 | (module-function-count mod) 62 | ] 63 | 64 | You can see how it is printed to standard output. 65 | 66 | @examples[#:eval binaryen-eval 67 | (module-print mod) 68 | ] 69 | 70 | @section{Writing WebAssembly} 71 | 72 | You can also create WebAssembly on the fly, have it optimized and write it to a file. Lets say that we want to manually create a module that contains a function @tt{square}, that multiplies a number with itself. 73 | 74 | What we want to create is something like this: 75 | 76 | @codeblock|{ 77 | (module 78 | (func $square (export "square") 79 | (param $x i32) 80 | (result $i32) 81 | (i32.mul (local.get $x) (local.get $x)))) 82 | }| 83 | 84 | Most functions in this library will receive an optional @racket[module] to use as last parameter. If not provided, they will the value of @racket[current-module] which is useful to create WebAssembly code since you tend to work on a module at a time. 85 | 86 | The racket code will take this shape: 87 | 88 | @examples[#:eval #false #:no-result 89 | (require racket/contract 90 | binaryen) 91 | 92 | (define/contract (create-square) 93 | (-> module?) 94 | (parameterize ([current-module (module-create)]) 95 | (module-add-function "square" 96 | (list type-int32) 97 | (list type-int32) 98 | '() 99 | (make-mul-int32 (make-localget 0 type-int32) 100 | (make-localget 0 type-int32))) 101 | (module-export-function "$square" "square") 102 | (current-module))) 103 | ] 104 | 105 | In this example we create an empty module with @racket[(module-create)] and set it as the @racket[current-module] so that we don't need to pass it around. Then we add a function withe name @racket["square"], receiving one 32bit integer, returning one 32bit integer, and without any locals. The body is created in-place and passed into the function. The function @racket[module-add-function] creates the function and adds it to the @racket[current-module]. 106 | 107 | @section{Optimization} 108 | 109 | @section{A Longer Example} 110 | -------------------------------------------------------------------------------- /scribblings/literals.scrbl: -------------------------------------------------------------------------------- 1 | #lang scribble/manual 2 | 3 | @(require (for-label binaryen)) 4 | 5 | @title{Literals} 6 | -------------------------------------------------------------------------------- /scribblings/main.scrbl~: -------------------------------------------------------------------------------- 1 | #lang scribble/manual 2 | ;; --------------------------------------------------------------------------------------------------- 3 | 4 | @(require (for-label binaryen)) 5 | 6 | ;; --------------------------------------------------------------------------------------------------- 7 | 8 | @title{racket-binaryen} 9 | @defmodule[binaryen] 10 | 11 | This is a wrapper for the Binaryen suite of WebAssembly tools. 12 | 13 | @table-of-contents[] 14 | @include-section[(lib "binaryen/types.scrbl")] 15 | @include-section[(lib "binaryen/modules.scrbl")] 16 | @include-section[(lib "binaryen/functions.scrbl")] 17 | -------------------------------------------------------------------------------- /scribblings/modules.scrbl: -------------------------------------------------------------------------------- 1 | #lang scribble/manual 2 | 3 | @(require (for-label binaryen)) 4 | 5 | @title{Modules} 6 | 7 | A @deftech{module} is the representation of a @tech{WebAssembly} module into which you add functions, etc. 8 | 9 | @defproc[(module? [x any/c]) boolean?]{ 10 | Checks if the value @racket[x] is a WebAssembly module.} 11 | 12 | @defparam[current-module module module? 13 | #:value #false]{ 14 | A parameter that defines the current module to use.} 15 | 16 | @defproc[(module-create) void?]{ 17 | Creates an empty WebAssembly module.} 18 | 19 | @defproc[(module-valid? [mod module? (current-module)]) boolean?]{ 20 | Validates the Wasm module @racket[mod], returning @racket[#true] if it is a valid module and @racket[#false] otherwise.} 21 | 22 | @defproc[(module-print [mod module? (current-module)]) void?]{ 23 | Prints the Wasm module @racket[mod] to standard output.} 24 | 25 | @defproc[(module-optimize! [mod module? (current-module)]) void?]{ 26 | Optimizes the Wasm module @racket[mod] in-place.} 27 | 28 | @defproc[(module-read [in bytes?]) module?]{ 29 | Reads a module in binary format from bytes @racket[in] and returns a Wasm module.} 30 | 31 | @defproc[(module-parse [s string?]) module?]{ 32 | Reads a module from string @racket[s] and returns a Wasm module. } 33 | 34 | @defproc[(module-write [mod module?] [textual? boolean?] [#:source-map sm (or/c string? #false) #false]) bytes?]{ 35 | Writes module @racket[mod] to a byte string using source map @racket[sm], if provided. Returns the byte string. The module is read in text format if @racket[textual?] is true, and in binary format otherwise.} 36 | -------------------------------------------------------------------------------- /scribblings/optimizations.scrbl: -------------------------------------------------------------------------------- 1 | #lang scribble/manual 2 | 3 | @title{Optimizations} 4 | 5 | Binaryen can optimize your webassembly program and many functions depends on the global optimization levels set. This API section describes which levels can be tuned and which facilities are provided to change the levels. 6 | 7 | @defproc[(optimize-level? [x any/c]) boolean?]{ 8 | Checks if the value @racket[x] is a valid optimize level.} 9 | 10 | @defproc[(shrink-level? [x any/c]) boolean?]{ 11 | Checks if the value @racket[x] is a valid shrink level.} 12 | 13 | @defproc[(optimize-level) exact-nonnegative-integer?]{ 14 | Returns the current global optimize level.} 15 | 16 | @defproc[(shrink-level) exact-nonnegative-integer?]{ 17 | Returns the current global shrink level.} 18 | 19 | @defproc[(set-optimize-level! [n exact-nonnegative-integer?]) void?]{ 20 | Sets the current optimize level to @racket[n]. Any positive value is positive but it only makes a different until @racket[4], inclusive. So @racket[0] stands for the usual @tt{-O0}, @racket[1] for @tt{-O1}, etc, until @racket[4] standing for @tt{-O4}.} 21 | 22 | @defproc[(set-shrink-level! [n exact-nonnegative-integer?]) void?]{ 23 | Sets the current shrink level to @racket[n]. Any positive value is positive but it only makes a different until @racket[2], inclusive. So @racket[0] stands for the usual @tt{-O0}, @racket[1] for @tt{-Os}, and @racket[2] for @tt{-Oz}.} 24 | 25 | @defform[(with-optimize-level n body ...)]{ 26 | Evaluates the @racket[body ...] forms in sequence with the optimize level set to @racket[n]. After the evaluation of all the forms or if the control jumps out of this form, the optimize level is reset to its old value.} 27 | 28 | @defform[(with-shrink-level n body ...)]{ 29 | Evaluates the @racket[body ...] forms in sequence with the shrink level set to @racket[n]. After the evaluation of all the forms or if the control jumps out of this form, the shrink level is reset to its old value.} 30 | 31 | 32 | -------------------------------------------------------------------------------- /scribblings/types.scrbl: -------------------------------------------------------------------------------- 1 | #lang scribble/manual 2 | 3 | @title{Types} 4 | 5 | Types refer to WebAssembly types such as @tt{int32}, @tt{int64}, etc. There are basic types and ways to aggregate a type from these basic types. 6 | 7 | @defproc[(type? [x any/c]) boolean?]{ 8 | Predicate to check if value @racket[x] is a WebAssembly type.} 9 | 10 | @defthing[type-none type?]{ 11 | The type @tt{None}.} 12 | 13 | @defthing[type-int32 type?]{ 14 | The type @tt{Int32}.} 15 | 16 | @defthing[type-int64 type?]{ 17 | The type @tt{Int64}.} 18 | 19 | @defthing[type-float32 type?]{ 20 | The type @tt{Float32}.} 21 | 22 | @defthing[type-float64 type?]{ 23 | The type @tt{Float64}.} 24 | 25 | @defthing[type-vec128 type?]{ 26 | The type @tt{Vec128}.} 27 | 28 | @defthing[type-funcref type?]{ 29 | The type @tt{Funcref}.} 30 | 31 | @defthing[type-externref type?]{ 32 | The type @tt{Externref}.} 33 | 34 | @defthing[type-anyref type?]{ 35 | The type @tt{Anyref}.} 36 | 37 | @defthing[type-eqref type?]{ 38 | The type @tt{Eqref}.} 39 | 40 | @defthing[type-i31ref type?]{ 41 | The type @tt{I31ref}.} 42 | 43 | @defthing[type-dataref type?]{ 44 | The type @tt{Dataref}.} 45 | 46 | @defthing[type-unreachable type?]{ 47 | The type @tt{Unreachable}.} 48 | 49 | @defthing[type-auto type?]{ 50 | The type @tt{Auto}.} 51 | 52 | -------------------------------------------------------------------------------- /scripts/find-good-api.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | # 3 | # Returns the SHA of the last good binaryen sha for which this API works 4 | 5 | set -e 6 | 7 | EXPECTED_SHA=$1 8 | BINARYEN_PATH=$(mktemp -d) 9 | 10 | git clone -q https://github.com/WebAssembly/binaryen.git ${BINARYEN_PATH} 11 | 12 | FOUND_SHA= 13 | 14 | cd $BINARYEN_PATH 15 | for sha in `git log --pretty=format:"%H" --no-merges`; do 16 | git checkout -q $sha 17 | sum=`sha1sum src/binaryen-c.h | cut -d ' ' -f1` 18 | if diff -q <(echo ${EXPECTED_SHA}) <(echo ${sum}); then 19 | break; 20 | fi 21 | BROKEN_SHA=$sha 22 | done 23 | 24 | echo "First broken: ${BROKEN_SHA}" 25 | echo "Last good: $sha" 26 | 27 | git checkout main 28 | git --no-pager diff $sha..HEAD -- src/binaryen-c.h 29 | 30 | rm -r ${BINARYEN_PATH} 31 | -------------------------------------------------------------------------------- /test-utils.rkt: -------------------------------------------------------------------------------- 1 | #lang racket/base 2 | ;; --------------------------------------------------------------------------------------------------- 3 | 4 | (require "private/modules.rkt" 5 | racket/port) 6 | 7 | (provide with-test-mod) 8 | 9 | ;; --------------------------------------------------------------------------------------------------- 10 | 11 | (define-syntax-rule (with-test-mod wasm body ...) 12 | (let ([mod (module-parse 13 | (with-output-to-string (lambda () (write wasm))))]) 14 | (parameterize ([current-module mod]) 15 | body ...))) 16 | -------------------------------------------------------------------------------- /tests/square.rkt: -------------------------------------------------------------------------------- 1 | #lang racket/base 2 | ;; --------------------------------------------------------------------------------------------------- 3 | (require racket/contract 4 | racket/port 5 | racket/string 6 | rackunit 7 | binaryen) 8 | 9 | ;; --------------------------------------------------------------------------------------------------- 10 | 11 | (define/contract (create-square) 12 | (-> module?) 13 | (parameterize ([current-module (module-create)]) 14 | (module-add-function "square" 15 | (list type-int32) 16 | (list type-int32) 17 | '() 18 | (make-mul-int32 (make-localget 0 type-int32) 19 | (make-localget 0 type-int32))) 20 | (module-export-function "$square" "square") 21 | (current-module))) 22 | 23 | (test-case "module printing" 24 | (define s 25 | (with-output-to-string 26 | (lambda () (module-print (create-square) #:colors #false)))) 27 | (check-true (string-contains? s "(module")) 28 | (check-true (string-contains? s "(param $0 i32) (result i32)"))) 29 | -------------------------------------------------------------------------------- /tests/wingo-input/wingo_const.scm: -------------------------------------------------------------------------------- 1 | (define (ret2) 2) 2 | -------------------------------------------------------------------------------- /tests/wingo-input/wingo_fact.scm: -------------------------------------------------------------------------------- 1 | (define (fac n) 2 | (if (zero? n) 3 | 1 4 | (* n (fac (- n 1))))) 5 | -------------------------------------------------------------------------------- /tests/wingo-input/wingo_zero.scm: -------------------------------------------------------------------------------- 1 | (define (two-zero?) 2 | (zero? 2)) 3 | -------------------------------------------------------------------------------- /tests/wingo-raw.rkt: -------------------------------------------------------------------------------- 1 | #lang racket/base 2 | ;; --------------------------------------------------------------------------------------------------- 3 | (require "../private/binaryen-ffi.rkt" 4 | racket/match) 5 | 6 | ;; --------------------------------------------------------------------------------------------------- 7 | ; 8 | ; This uses the raw binaryen API which is not recommended for normal use. 9 | ; It implements the Scheme to Wasm compiler presented by Andy Wingo at FOSDEM2021 10 | ; https://github.com/wingo/compiling-to-webassembly/blob/main/compile.scm 11 | 12 | (define (compile port) 13 | ; Create module where our definitions will be places 14 | (define mod (BinaryenModuleCreate)) 15 | 16 | (let lp () 17 | (let ([datum (read port)]) 18 | (unless (eof-object? datum) 19 | (compile-def mod datum) 20 | (lp)))) 21 | 22 | (unless (BinaryenModuleValidate mod) 23 | (error "internal error: validation failed")) 24 | 25 | (println "Compiled module:") 26 | (BinaryenModulePrint mod) 27 | 28 | (BinaryenModuleOptimize mod) 29 | (println "Optimized module:") 30 | (BinaryenModulePrint mod)) 31 | 32 | (define (compile-def mod def) 33 | (match def 34 | [`(define (,f ,args ...) ,exp) 35 | (compile-func mod f args exp)])) 36 | 37 | (define (compile-func mod name args body) 38 | (define name-str (symbol->string name)) 39 | (define env 40 | (for/list ([arg (in-list args)] 41 | [i (in-naturals)]) 42 | (cons arg i))) 43 | 44 | (define compiled-body 45 | (compile-exp mod env body)) 46 | (BinaryenAddFunction mod 47 | name-str 48 | (BinaryenTypeCreate (map (lambda (x) (BinaryenTypeInt32)) args)) 49 | (BinaryenTypeInt32) 50 | '() 51 | compiled-body) 52 | (BinaryenAddFunctionExport mod name-str name-str)) 53 | 54 | (define (compile-exp mod env texp) 55 | (match texp 56 | [(? symbol? v) 57 | (cond 58 | [(assq v env) 59 | => (lambda (p) 60 | (define idx (cdr p)) 61 | (BinaryenLocalGet mod idx (BinaryenTypeInt32)))] 62 | [else (error "no symbol ~a in environment" v)])] 63 | [(? exact-integer? n) 64 | (BinaryenConst mod (BinaryenLiteralInt32 n))] 65 | [`(zero? ,exp) 66 | (BinaryenUnary mod 67 | (BinaryenEqZInt32) 68 | (compile-exp mod env exp))] 69 | [`(if ,tst ,thn ,els) 70 | (BinaryenIf mod 71 | (compile-exp mod env tst) 72 | (compile-exp mod env thn) 73 | (compile-exp mod env els))] 74 | [`(- ,a ,b) 75 | (BinaryenBinary mod 76 | (BinaryenSubInt32) 77 | (compile-exp mod env a) 78 | (compile-exp mod env b))] 79 | [`(* ,a ,b) 80 | (BinaryenBinary mod 81 | (BinaryenMulInt32) 82 | (compile-exp mod env a) 83 | (compile-exp mod env b))] 84 | [`(,f ,args ...) 85 | (BinaryenCall mod 86 | (symbol->string f) 87 | (map (lambda (arg) (compile-exp mod env arg)) args) 88 | (BinaryenTypeInt32))])) 89 | 90 | 91 | ;; --------------------------------------------------------------------------------------------------- 92 | 93 | (module+ main 94 | 95 | (require racket/cmdline) 96 | 97 | (define file-to-compile 98 | (command-line 99 | #:program "compiler" 100 | #:args (filename) ; expect one command-line argument: 101 | ; return the argument as a filename to compile 102 | (unless (file-exists? filename) 103 | (error "file ~a not found" filename)) 104 | filename)) 105 | 106 | (call-with-input-file file-to-compile compile)) 107 | 108 | -------------------------------------------------------------------------------- /tests/wingo.rkt: -------------------------------------------------------------------------------- 1 | #lang racket/base 2 | ;; --------------------------------------------------------------------------------------------------- 3 | (require binaryen 4 | racket/match) 5 | 6 | ;; --------------------------------------------------------------------------------------------------- 7 | ; 8 | ; It implements the Scheme to Wasm compiler presented by Andy Wingo at FOSDEM2021 9 | ; https://github.com/wingo/compiling-to-webassembly/blob/main/compile.scm 10 | 11 | (define (compile port) 12 | ; Create module where our definitions will be places 13 | (parameterize ([current-module (module-create)]) 14 | 15 | (let lp () 16 | (let ([datum (read port)]) 17 | (unless (eof-object? datum) 18 | (compile-def datum) 19 | (lp)))) 20 | 21 | (unless (module-valid?) 22 | (error "internal error: validation failed")) 23 | 24 | (println "Compiled module:") 25 | (module-print) 26 | 27 | (module-optimize!) 28 | (println "Optimized module:") 29 | (module-print))) 30 | 31 | (define (compile-def def) 32 | (match def 33 | [`(define (,f ,args ...) ,exp) 34 | (compile-func f args exp)])) 35 | 36 | (define (compile-func name args body) 37 | (define name-str (symbol->string name)) 38 | (define env 39 | (for/list ([arg (in-list args)] 40 | [i (in-naturals)]) 41 | (cons arg i))) 42 | 43 | (define compiled-body 44 | (compile-exp env body)) 45 | (module-add-function name-str 46 | (map (lambda (x) type-int32) args) 47 | (list type-int32) 48 | '() 49 | compiled-body) 50 | (module-export-function name-str name-str)) 51 | 52 | (define (compile-exp env texp) 53 | (match texp 54 | [(? symbol? v) 55 | (cond 56 | [(assq v env) 57 | => (lambda (p) 58 | (define idx (cdr p)) 59 | (make-localget idx type-int32))] 60 | [else (error "no symbol ~a in environment" v)])] 61 | [(? exact-integer? n) 62 | (make-const (make-literal-int32 n))] 63 | [`(zero? ,exp) 64 | (make-eqz-int32 (compile-exp env exp))] 65 | [`(if ,tst ,thn ,els) 66 | (make-if (compile-exp env tst) 67 | (compile-exp env thn) 68 | (compile-exp env els))] 69 | [`(- ,a ,b) 70 | (make-sub-int32 (compile-exp env a) 71 | (compile-exp env b))] 72 | [`(* ,a ,b) 73 | (make-add-int32 (compile-exp env a) 74 | (compile-exp env b))] 75 | [`(,f ,args ...) 76 | (make-call (symbol->string f) 77 | (map (lambda (arg) (compile-exp env arg)) args) 78 | type-int32)])) 79 | 80 | 81 | ;; --------------------------------------------------------------------------------------------------- 82 | 83 | (module+ main 84 | 85 | (require racket/cmdline) 86 | 87 | (define file-to-compile 88 | (command-line 89 | #:program "compiler" 90 | #:args (filename) ; expect one command-line argument: 91 | ; return the argument as a filename to compile 92 | (unless (file-exists? filename) 93 | (error "file ~a not found" filename)) 94 | filename)) 95 | 96 | (call-with-input-file file-to-compile compile)) 97 | 98 | -------------------------------------------------------------------------------- /types.rkt: -------------------------------------------------------------------------------- 1 | #lang racket/base 2 | ;; --------------------------------------------------------------------------------------------------- 3 | 4 | (require "private/binaryen-ffi.rkt" 5 | "private/types.rkt" 6 | racket/contract) 7 | 8 | (provide 9 | type-none 10 | type-int32 11 | type-int64 12 | type-float32 13 | type-float64 14 | type-vec128 15 | type-funcref 16 | type-externref 17 | type-anyref 18 | type-eqref 19 | type-i31ref 20 | type-dataref 21 | type-unreachable 22 | type-auto) 23 | 24 | ;; --------------------------------------------------------------------------------------------------- 25 | 26 | (define type-none (type (BinaryenTypeNone))) 27 | (define type-int32 (type (BinaryenTypeInt32))) 28 | (define type-int64 (type (BinaryenTypeInt64))) 29 | (define type-float32 (type (BinaryenTypeFloat32))) 30 | (define type-float64 (type (BinaryenTypeFloat64))) 31 | (define type-vec128 (type (BinaryenTypeVec128))) 32 | (define type-funcref (type (BinaryenTypeFuncref))) 33 | (define type-externref (type (BinaryenTypeExternref))) 34 | (define type-anyref (type (BinaryenTypeAnyref))) 35 | (define type-eqref (type (BinaryenTypeEqref))) 36 | (define type-i31ref (type (BinaryenTypeI31ref))) 37 | (define type-dataref (type (BinaryenTypeDataref))) 38 | (define type-unreachable (type (BinaryenTypeUnreachable))) 39 | (define type-auto (type (BinaryenTypeAuto))) 40 | 41 | ;; --------------------------------------------------------------------------------------------------- 42 | 43 | (module+ test 44 | 45 | (require rackunit) 46 | 47 | (test-case "pass" 48 | (check-true #true))) 49 | 50 | --------------------------------------------------------------------------------