From beb92dddc8bf2a02cf553525e267aeba40ff21fa Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Mon, 20 Jul 2020 20:31:46 -0700 Subject: [PATCH 1/2] Add binaryen.js bindings --- .gitmodules | 3 + binaryen.opam | 3 + dune | 2 +- esy.json | 3 + esy.lock/index.json | 129 ++- esy.lock/opam/js_of_ocaml-compiler.3.6.0/opam | 38 + esy.lock/opam/js_of_ocaml-ppx.3.6.0/opam | 30 + esy.lock/opam/js_of_ocaml.3.6.0/opam | 33 + esy.lock/opam/ppx_tools_versioned.5.4.0/opam | 27 + js/binaryen.js | 1 + js/dune | 10 + js/export.ml | 23 + js/expression.ml | 176 ++++ js/features.ml | 27 + js/function.ml | 29 + js/function_table.ml | 11 + js/global.ml | 19 + js/import.ml | 45 + js/literal.ml | 25 + js/memory.ml | 37 + js/module.ml | 125 +++ js/op.ml | 784 ++++++++++++++++++ js/postlude.js | 2 + js/type.ml | 31 + src/literal.ml | 13 + test/dune | 50 +- test/test_js.expected | 10 + virtual/literal.mli | 11 + 28 files changed, 1693 insertions(+), 4 deletions(-) create mode 100644 esy.lock/opam/js_of_ocaml-compiler.3.6.0/opam create mode 100644 esy.lock/opam/js_of_ocaml-ppx.3.6.0/opam create mode 100644 esy.lock/opam/js_of_ocaml.3.6.0/opam create mode 100644 esy.lock/opam/ppx_tools_versioned.5.4.0/opam create mode 160000 js/binaryen.js create mode 100644 js/dune create mode 100644 js/export.ml create mode 100644 js/expression.ml create mode 100644 js/features.ml create mode 100644 js/function.ml create mode 100644 js/function_table.ml create mode 100644 js/global.ml create mode 100644 js/import.ml create mode 100644 js/literal.ml create mode 100644 js/memory.ml create mode 100644 js/module.ml create mode 100644 js/op.ml create mode 100644 js/postlude.js create mode 100644 js/type.ml create mode 100644 test/test_js.expected diff --git a/.gitmodules b/.gitmodules index ff847f1c..f6f309e7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "src/binaryen"] path = src/binaryen url = https://github.com/WebAssembly/binaryen +[submodule "js/binaryen.js"] + path = js/binaryen.js + url = https://github.com/AssemblyScript/binaryen.js diff --git a/binaryen.opam b/binaryen.opam index 62afaed0..3537b8f8 100644 --- a/binaryen.opam +++ b/binaryen.opam @@ -14,4 +14,7 @@ depends: [ "dune" {>= "2.6"} "conf-cmake" {build} "conf-python-3" {build} + "js_of_ocaml" {>= "3.6.0"} + "js_of_ocaml-ppx" {>= "3.6.0"} + "js_of_ocaml-compiler" {>= "3.6.0"} ] diff --git a/dune b/dune index 445e45d7..493dfe54 100644 --- a/dune +++ b/dune @@ -1 +1 @@ -(dirs :standard virtual) +(dirs :standard virtual js) diff --git a/esy.json b/esy.json index 8fd2e930..419a3f7b 100644 --- a/esy.json +++ b/esy.json @@ -11,6 +11,9 @@ "devDependencies": { "@opam/conf-cmake": "*", "@opam/conf-python-3": "*", + "@opam/js_of_ocaml": ">=3.6.0", + "@opam/js_of_ocaml-ppx": ">=3.6.0", + "@opam/js_of_ocaml-compiler": ">=3.6.0", "@opam/ocamlformat": "*", "@opam/ocaml-lsp-server": "ocaml/ocaml-lsp:ocaml-lsp-server.opam#ce1840355541ff60b999e39388835027f89d8798" }, diff --git a/esy.lock/index.json b/esy.lock/index.json index 9239030a..152a38dd 100644 --- a/esy.lock/index.json +++ b/esy.lock/index.json @@ -1,5 +1,5 @@ { - "checksum": "e6317ffd713abac96421a223fb5366d1", + "checksum": "ae69fc835c66ccd49060ec45aa231317", "root": "binaryen.ml@link-dev:./esy.json", "node": { "ocaml@4.10.0@d41d8cd9": { @@ -28,6 +28,9 @@ "devDependencies": [ "@opam/ocamlformat@opam:0.14.2@d742ffd5", "@opam/ocaml-lsp-server@github:ocaml/ocaml-lsp:ocaml-lsp-server.opam#ce1840355541ff60b999e39388835027f89d8798@d41d8cd9", + "@opam/js_of_ocaml-ppx@opam:3.6.0@92f19746", + "@opam/js_of_ocaml-compiler@opam:3.6.0@bda9e5de", + "@opam/js_of_ocaml@opam:3.6.0@92f53867", "@opam/conf-python-3@opam:1.0.0@a6b2949d", "@opam/conf-cmake@opam:1@75ae6bc3" ], @@ -396,6 +399,34 @@ "@opam/dune@opam:2.6.1@e1bf507c" ] }, + "@opam/ppx_tools_versioned@opam:5.4.0@48c10ee1": { + "id": "@opam/ppx_tools_versioned@opam:5.4.0@48c10ee1", + "name": "@opam/ppx_tools_versioned", + "version": "opam:5.4.0", + "source": { + "type": "install", + "source": [ + "archive:https://opam.ocaml.org/cache/md5/3e/3e809a11cae99f57c051d3d0100311f6#md5:3e809a11cae99f57c051d3d0100311f6", + "archive:https://github.com/ocaml-ppx/ppx_tools_versioned/archive/5.4.0.tar.gz#md5:3e809a11cae99f57c051d3d0100311f6" + ], + "opam": { + "name": "ppx_tools_versioned", + "version": "5.4.0", + "path": "esy.lock/opam/ppx_tools_versioned.5.4.0" + } + }, + "overrides": [], + "dependencies": [ + "ocaml@4.10.0@d41d8cd9", + "@opam/ocaml-migrate-parsetree@opam:1.7.3@dbcf3b47", + "@opam/dune@opam:2.6.1@e1bf507c", "@esy-ocaml/substs@0.0.1@d41d8cd9" + ], + "devDependencies": [ + "ocaml@4.10.0@d41d8cd9", + "@opam/ocaml-migrate-parsetree@opam:1.7.3@dbcf3b47", + "@opam/dune@opam:2.6.1@e1bf507c" + ] + }, "@opam/ppx_derivers@opam:1.2.1@ecf0aa45": { "id": "@opam/ppx_derivers@opam:1.2.1@ecf0aa45", "name": "@opam/ppx_derivers", @@ -753,6 +784,102 @@ "@opam/dune@opam:2.6.1@e1bf507c" ] }, + "@opam/js_of_ocaml-ppx@opam:3.6.0@92f19746": { + "id": "@opam/js_of_ocaml-ppx@opam:3.6.0@92f19746", + "name": "@opam/js_of_ocaml-ppx", + "version": "opam:3.6.0", + "source": { + "type": "install", + "source": [ + "archive:https://opam.ocaml.org/cache/sha256/51/51eaa89c83ef3168ef270bf7997cbc35a747936d3f51aa6fac58fb0323b4cbb0#sha256:51eaa89c83ef3168ef270bf7997cbc35a747936d3f51aa6fac58fb0323b4cbb0", + "archive:https://github.com/ocsigen/js_of_ocaml/releases/download/3.6.0/js_of_ocaml-3.6.0.tbz#sha256:51eaa89c83ef3168ef270bf7997cbc35a747936d3f51aa6fac58fb0323b4cbb0" + ], + "opam": { + "name": "js_of_ocaml-ppx", + "version": "3.6.0", + "path": "esy.lock/opam/js_of_ocaml-ppx.3.6.0" + } + }, + "overrides": [], + "dependencies": [ + "ocaml@4.10.0@d41d8cd9", + "@opam/ppx_tools_versioned@opam:5.4.0@48c10ee1", + "@opam/ocaml-migrate-parsetree@opam:1.7.3@dbcf3b47", + "@opam/js_of_ocaml@opam:3.6.0@92f53867", + "@opam/dune@opam:2.6.1@e1bf507c", "@esy-ocaml/substs@0.0.1@d41d8cd9" + ], + "devDependencies": [ + "ocaml@4.10.0@d41d8cd9", + "@opam/ppx_tools_versioned@opam:5.4.0@48c10ee1", + "@opam/ocaml-migrate-parsetree@opam:1.7.3@dbcf3b47", + "@opam/js_of_ocaml@opam:3.6.0@92f53867", + "@opam/dune@opam:2.6.1@e1bf507c" + ] + }, + "@opam/js_of_ocaml-compiler@opam:3.6.0@bda9e5de": { + "id": "@opam/js_of_ocaml-compiler@opam:3.6.0@bda9e5de", + "name": "@opam/js_of_ocaml-compiler", + "version": "opam:3.6.0", + "source": { + "type": "install", + "source": [ + "archive:https://opam.ocaml.org/cache/sha256/51/51eaa89c83ef3168ef270bf7997cbc35a747936d3f51aa6fac58fb0323b4cbb0#sha256:51eaa89c83ef3168ef270bf7997cbc35a747936d3f51aa6fac58fb0323b4cbb0", + "archive:https://github.com/ocsigen/js_of_ocaml/releases/download/3.6.0/js_of_ocaml-3.6.0.tbz#sha256:51eaa89c83ef3168ef270bf7997cbc35a747936d3f51aa6fac58fb0323b4cbb0" + ], + "opam": { + "name": "js_of_ocaml-compiler", + "version": "3.6.0", + "path": "esy.lock/opam/js_of_ocaml-compiler.3.6.0" + } + }, + "overrides": [], + "dependencies": [ + "ocaml@4.10.0@d41d8cd9", "@opam/yojson@opam:1.7.0@7056d985", + "@opam/ocamlfind@opam:1.8.1@ff07b0f9", + "@opam/ocaml-migrate-parsetree@opam:1.7.3@dbcf3b47", + "@opam/dune@opam:2.6.1@e1bf507c", + "@opam/cmdliner@opam:1.0.4@93208aac", + "@esy-ocaml/substs@0.0.1@d41d8cd9" + ], + "devDependencies": [ + "ocaml@4.10.0@d41d8cd9", "@opam/yojson@opam:1.7.0@7056d985", + "@opam/ocaml-migrate-parsetree@opam:1.7.3@dbcf3b47", + "@opam/dune@opam:2.6.1@e1bf507c", + "@opam/cmdliner@opam:1.0.4@93208aac" + ] + }, + "@opam/js_of_ocaml@opam:3.6.0@92f53867": { + "id": "@opam/js_of_ocaml@opam:3.6.0@92f53867", + "name": "@opam/js_of_ocaml", + "version": "opam:3.6.0", + "source": { + "type": "install", + "source": [ + "archive:https://opam.ocaml.org/cache/sha256/51/51eaa89c83ef3168ef270bf7997cbc35a747936d3f51aa6fac58fb0323b4cbb0#sha256:51eaa89c83ef3168ef270bf7997cbc35a747936d3f51aa6fac58fb0323b4cbb0", + "archive:https://github.com/ocsigen/js_of_ocaml/releases/download/3.6.0/js_of_ocaml-3.6.0.tbz#sha256:51eaa89c83ef3168ef270bf7997cbc35a747936d3f51aa6fac58fb0323b4cbb0" + ], + "opam": { + "name": "js_of_ocaml", + "version": "3.6.0", + "path": "esy.lock/opam/js_of_ocaml.3.6.0" + } + }, + "overrides": [], + "dependencies": [ + "ocaml@4.10.0@d41d8cd9", "@opam/uchar@opam:0.0.2@c8218eea", + "@opam/ppx_tools_versioned@opam:5.4.0@48c10ee1", + "@opam/ocaml-migrate-parsetree@opam:1.7.3@dbcf3b47", + "@opam/js_of_ocaml-compiler@opam:3.6.0@bda9e5de", + "@opam/dune@opam:2.6.1@e1bf507c", "@esy-ocaml/substs@0.0.1@d41d8cd9" + ], + "devDependencies": [ + "ocaml@4.10.0@d41d8cd9", "@opam/uchar@opam:0.0.2@c8218eea", + "@opam/ppx_tools_versioned@opam:5.4.0@48c10ee1", + "@opam/ocaml-migrate-parsetree@opam:1.7.3@dbcf3b47", + "@opam/js_of_ocaml-compiler@opam:3.6.0@bda9e5de", + "@opam/dune@opam:2.6.1@e1bf507c" + ] + }, "@opam/fpath@opam:0.7.2@45477b93": { "id": "@opam/fpath@opam:0.7.2@45477b93", "name": "@opam/fpath", diff --git a/esy.lock/opam/js_of_ocaml-compiler.3.6.0/opam b/esy.lock/opam/js_of_ocaml-compiler.3.6.0/opam new file mode 100644 index 00000000..407ffb86 --- /dev/null +++ b/esy.lock/opam/js_of_ocaml-compiler.3.6.0/opam @@ -0,0 +1,38 @@ +opam-version: "2.0" +maintainer: "dev@ocsigen.org" +authors: "Ocsigen team" +bug-reports: "https://github.com/ocsigen/js_of_ocaml/issues" +homepage: "http://ocsigen.github.io/js_of_ocaml" +dev-repo: "git+https://github.com/ocsigen/js_of_ocaml.git" +synopsis: "Compiler from OCaml bytecode to Javascript" +description: """ +Js_of_ocaml is a compiler from OCaml bytecode to JavaScript. +It makes it possible to run pure OCaml programs in JavaScript +environment like browsers and Node.js +""" + +build: [["dune" "build" "-p" name "-j" jobs]] + +depends: [ + "ocaml" {>= "4.02.0" & < "4.11"} + "dune" {>= "2.5"} + "ppx_expect" {with-test & >= "v0.12.0" & < "v0.15"} + "cmdliner" + "ocaml-migrate-parsetree" + "yojson" # It's optional, but we want users to be able to use source-map without pain. +] + +depopts: [ "ocamlfind" ] + +conflicts: [ + "ocamlfind" {< "1.5.1"} + "js_of_ocaml" {< "3.0"} +] +url { + src: + "https://github.com/ocsigen/js_of_ocaml/releases/download/3.6.0/js_of_ocaml-3.6.0.tbz" + checksum: [ + "sha256=51eaa89c83ef3168ef270bf7997cbc35a747936d3f51aa6fac58fb0323b4cbb0" + "sha512=a2171a2583e9a1be6b4a87c9958aa2b4936b1f19030f09d787c4824d04db864773dd1da10d0dd56822f279309c8217093552b94e2e93c8b01eba5f432afc7718" + ] +} diff --git a/esy.lock/opam/js_of_ocaml-ppx.3.6.0/opam b/esy.lock/opam/js_of_ocaml-ppx.3.6.0/opam new file mode 100644 index 00000000..4d21d9be --- /dev/null +++ b/esy.lock/opam/js_of_ocaml-ppx.3.6.0/opam @@ -0,0 +1,30 @@ +opam-version: "2.0" +maintainer: "dev@ocsigen.org" +authors: "Ocsigen team" +bug-reports: "https://github.com/ocsigen/js_of_ocaml/issues" +homepage: "http://ocsigen.github.io/js_of_ocaml" +dev-repo: "git+https://github.com/ocsigen/js_of_ocaml.git" +synopsis: "Compiler from OCaml bytecode to Javascript" +description: """ +Js_of_ocaml is a compiler from OCaml bytecode to JavaScript. +It makes it possible to run pure OCaml programs in JavaScript +environment like browsers and Node.js +""" + +build: [["dune" "build" "-p" name "-j" jobs]] + +depends: [ + "ocaml" {>= "4.02.0"} + "dune" {>= "2.5"} + "ocaml-migrate-parsetree" {>= "1.4"} + "ppx_tools_versioned" {>= "5.2.3"} + "js_of_ocaml" {= version} +] +url { + src: + "https://github.com/ocsigen/js_of_ocaml/releases/download/3.6.0/js_of_ocaml-3.6.0.tbz" + checksum: [ + "sha256=51eaa89c83ef3168ef270bf7997cbc35a747936d3f51aa6fac58fb0323b4cbb0" + "sha512=a2171a2583e9a1be6b4a87c9958aa2b4936b1f19030f09d787c4824d04db864773dd1da10d0dd56822f279309c8217093552b94e2e93c8b01eba5f432afc7718" + ] +} diff --git a/esy.lock/opam/js_of_ocaml.3.6.0/opam b/esy.lock/opam/js_of_ocaml.3.6.0/opam new file mode 100644 index 00000000..2af80e4e --- /dev/null +++ b/esy.lock/opam/js_of_ocaml.3.6.0/opam @@ -0,0 +1,33 @@ +opam-version: "2.0" +maintainer: "dev@ocsigen.org" +authors: "Ocsigen team" +bug-reports: "https://github.com/ocsigen/js_of_ocaml/issues" +homepage: "http://ocsigen.github.io/js_of_ocaml" +dev-repo: "git+https://github.com/ocsigen/js_of_ocaml.git" +synopsis: "Compiler from OCaml bytecode to Javascript" +description: """ +Js_of_ocaml is a compiler from OCaml bytecode to JavaScript. +It makes it possible to run pure OCaml programs in JavaScript +environment like browsers and Node.js +""" + +name: "js_of_ocaml" + +build: [["dune" "build" "-p" name "-j" jobs]] + +depends: [ + "ocaml" {>= "4.02.0"} + "dune" {>= "2.5"} + "ocaml-migrate-parsetree" {>= "1.4"} + "ppx_tools_versioned" {>= "5.2.3"} + "uchar" + "js_of_ocaml-compiler" {= version} +] +url { + src: + "https://github.com/ocsigen/js_of_ocaml/releases/download/3.6.0/js_of_ocaml-3.6.0.tbz" + checksum: [ + "sha256=51eaa89c83ef3168ef270bf7997cbc35a747936d3f51aa6fac58fb0323b4cbb0" + "sha512=a2171a2583e9a1be6b4a87c9958aa2b4936b1f19030f09d787c4824d04db864773dd1da10d0dd56822f279309c8217093552b94e2e93c8b01eba5f432afc7718" + ] +} diff --git a/esy.lock/opam/ppx_tools_versioned.5.4.0/opam b/esy.lock/opam/ppx_tools_versioned.5.4.0/opam new file mode 100644 index 00000000..4f5f1258 --- /dev/null +++ b/esy.lock/opam/ppx_tools_versioned.5.4.0/opam @@ -0,0 +1,27 @@ +opam-version: "2.0" +version: "5.4.0" +maintainer: "frederic.bour@lakaban.net" +authors: [ + "Frédéric Bour " + "Alain Frisch " +] +license: "MIT" +homepage: "https://github.com/ocaml-ppx/ppx_tools_versioned" +bug-reports: "https://github.com/ocaml-ppx/ppx_tools_versioned/issues" +dev-repo: "git://github.com/ocaml-ppx/ppx_tools_versioned.git" +tags: [ "syntax" ] +build: [ + ["dune" "subst"] {pinned} + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +depends: [ + "ocaml" {>= "4.02.0"} + "dune" {>= "1.0"} + "ocaml-migrate-parsetree" {>= "1.7.0"} +] +synopsis: "A variant of ppx_tools based on ocaml-migrate-parsetree" +url { + src: "https://github.com/ocaml-ppx/ppx_tools_versioned/archive/5.4.0.tar.gz" + checksum: "md5=3e809a11cae99f57c051d3d0100311f6" +} diff --git a/js/binaryen.js b/js/binaryen.js new file mode 160000 index 00000000..aed6e379 --- /dev/null +++ b/js/binaryen.js @@ -0,0 +1 @@ +Subproject commit aed6e379e2845fee6e051149f65077e95e2c9ac5 diff --git a/js/dune b/js/dune new file mode 100644 index 00000000..3a73ce3e --- /dev/null +++ b/js/dune @@ -0,0 +1,10 @@ +(library + (name binaryen_js) + (public_name binaryen.js) + (implements binaryen) + (libraries js_of_ocaml) + (preprocess + (pps js_of_ocaml-ppx)) + (js_of_ocaml + (flags --no-sourcemap) + (javascript_files binaryen.js/index.js postlude.js))) diff --git a/js/export.ml b/js/export.ml new file mode 100644 index 00000000..ffd7b66f --- /dev/null +++ b/js/export.ml @@ -0,0 +1,23 @@ +open Js_of_ocaml.Js +open Js_of_ocaml.Js.Unsafe + +type t + +let add_function_export wasm_mod internal_name external_name = + meth_call wasm_mod "addFunctionExport" + [| inject (string internal_name); inject (string external_name) |] + +let add_table_export wasm_mod internal_name external_name = + meth_call wasm_mod "addTableExport" + [| inject (string internal_name); inject (string external_name) |] + +let add_memory_export wasm_mod internal_name external_name = + meth_call wasm_mod "addMemoryExport" + [| inject (string internal_name); inject (string external_name) |] + +let add_global_export wasm_mod internal_name external_name = + meth_call wasm_mod "addGlobalExport" + [| inject (string internal_name); inject (string external_name) |] + +let remove_export wasm_mod external_name = + meth_call wasm_mod "removeExport" [| inject (string external_name) |] diff --git a/js/expression.ml b/js/expression.ml new file mode 100644 index 00000000..bc280436 --- /dev/null +++ b/js/expression.ml @@ -0,0 +1,176 @@ +open Js_of_ocaml.Js +open Js_of_ocaml.Js.Unsafe + +type t = int + +let block wasm_mod name children = + meth_call wasm_mod "block" + [| + inject (string name); + inject (array (Array.of_list children)); + inject Type.auto; + |] + +let if_ wasm_mod cond if_true if_false = + meth_call wasm_mod "if" [| inject cond; inject if_true; inject if_false |] + +let loop wasm_mod name body = + meth_call wasm_mod "loop" [| inject (string name); inject body |] + +let break wasm_mod name cond res = + meth_call wasm_mod "br" [| inject (string name); inject cond; inject res |] + +let switch wasm_mod names default_name cond value = + meth_call wasm_mod "switch" + [| + inject (array (Array.of_list (List.map string names))); + inject (string default_name); + inject cond; + inject value; + |] + +let call wasm_mod name params return_typ = + meth_call wasm_mod "call" + [| + inject (string name); + inject (array (Array.of_list params)); + inject return_typ; + |] + +let call_indirect wasm_mod target params params_typ return_typ = + meth_call wasm_mod "call_indirect" + [| + inject target; + inject (array (Array.of_list params)); + inject params_typ; + inject return_typ; + |] + +let return_call wasm_mod name params return_typ = + meth_call wasm_mod "return_call" + [| + inject (string name); + inject (array (Array.of_list params)); + inject return_typ; + |] + +let return_call_indirect wasm_mod target params params_typ return_typ = + meth_call wasm_mod "return_call_indirect" + [| + inject target; + inject (array (Array.of_list params)); + inject params_typ; + inject return_typ; + |] + +let local_get wasm_mod slot typ = + let scope = get wasm_mod "local" in + meth_call scope "get" [| inject slot; inject typ |] + +let local_set wasm_mod slot value = + let scope = get wasm_mod "local" in + meth_call scope "set" [| inject slot; inject value |] + +let local_tee wasm_mod slot value typ = + let scope = get wasm_mod "local" in + meth_call scope "tee" [| inject slot; inject value; inject typ |] + +let global_get wasm_mod name typ = + let scope = get wasm_mod "global" in + meth_call scope "get" [| inject (string name); inject typ |] + +let global_set wasm_mod name value = + let scope = get wasm_mod "global" in + meth_call scope "set" [| inject (string name); inject value |] + +let load wasm_mod byts offset align typ ptr = + meth_call global##.binaryen "_BinaryenLoad" + [| + inject wasm_mod; + inject byts; + inject offset; + inject align; + inject typ; + inject ptr; + |] + +let store wasm_mod byts offset align ptr value typ = + meth_call global##.binaryen "_BinaryenStore" + [| + inject wasm_mod; + inject byts; + inject offset; + inject align; + inject ptr; + inject value; + inject typ; + |] + +let const wasm_mod lit = + let lit_hack = Literal.to_jsoo lit in + match lit_hack with + | Int32 value -> + let scope = get wasm_mod "i32" in + meth_call scope "const" [| inject value |] + | Int64 value -> + let scope = get wasm_mod "i64" in + meth_call scope "const" [| inject value |] + | Float32Bits value -> + let scope = get wasm_mod "f32" in + meth_call scope "const_bits" [| inject value |] + | Float64Bits value -> + let scope = get wasm_mod "f64" in + meth_call scope "const_bits" [| inject value |] + | Float32 value -> + let scope = get wasm_mod "f32" in + (* TODO: Investigate if this needs the Int32 conversion stuff *) + meth_call scope "const" [| inject value |] + | Float64 value -> + let scope = get wasm_mod "f64" in + meth_call scope "const" [| inject value |] + +let unary wasm_mod op p = + meth_call global##.binaryen "_BinaryenUnary" + [| inject wasm_mod; inject op; inject p |] + +let binary wasm_mod op a b = + meth_call global##.binaryen "_BinaryenBinary" + [| inject wasm_mod; inject op; inject a; inject b |] + +let select wasm_mod cond if_true if_false = + meth_call wasm_mod "select" + [| inject cond; inject if_true; inject if_false; inject Type.auto |] + +let drop wasm_mod value = meth_call wasm_mod "drop" [| inject value |] + +let return wasm_mod value = meth_call wasm_mod "return" [| inject value |] + +let nop wasm_mod = meth_call wasm_mod "nop" [||] + +let unreachable wasm_mod = meth_call wasm_mod "unreachable" [||] + +let memory_copy wasm_mod dest source size = + let scope = get wasm_mod "memory" in + meth_call scope "copy" [| inject dest; inject source; inject size |] + +let memory_fill wasm_mod dest value size = + let scope = get wasm_mod "memory" in + meth_call scope "fill" [| inject dest; inject value; inject size |] + +let tuple_make wasm_mod operands = + let scope = get wasm_mod "tuple" in + meth_call scope "make" [| inject (array (Array.of_list operands)) |] + +let tuple_extract wasm_mod tuple index = + let scope = get wasm_mod "tuple" in + meth_call scope "extract" [| inject tuple; inject index |] + +let pop wasm_mod typ = + meth_call global##.binaryen "_BinaryenPop" [| inject wasm_mod; inject typ |] + +(* TODO: Figure this out *) +let null () = Obj.magic () + +let print expr = + let text = meth_call global##.binaryen "emitText" [| inject expr |] in + print_string (to_string text) diff --git a/js/features.ml b/js/features.ml new file mode 100644 index 00000000..1ac6f40e --- /dev/null +++ b/js/features.ml @@ -0,0 +1,27 @@ +open Js_of_ocaml.Js.Unsafe + +let mvp : int = global ##. binaryen ##. Features ##. MVP + +let atomics : int = global ##. binaryen ##. Features ##. Atomics + +let bulk_memory : int = global ##. binaryen ##. Features ##. BulkMemory + +let mutable_globals : int = global ##. binaryen ##. Features ##. MutableGlobals + +let nontrapping_fp_to_int : int = + global ##. binaryen ##. Features ##. NontrappingFPToInt + +let sign_ext : int = global ##. binaryen ##. Features ##. SignExt + +let simd128 : int = global ##. binaryen ##. Features ##. SIMD128 + +let exception_handling : int = + global ##. binaryen ##. Features ##. ExceptionHandling + +let tail_call : int = global ##. binaryen ##. Features ##. TailCall + +let reference_types : int = global ##. binaryen ##. Features ##. ReferenceTypes + +let multivalue : int = global ##. binaryen ##. Features ##. Multivalue + +let all : int = global ##. binaryen ##. Features ##. All diff --git a/js/function.ml b/js/function.ml new file mode 100644 index 00000000..4a3cfcd4 --- /dev/null +++ b/js/function.ml @@ -0,0 +1,29 @@ +open Js_of_ocaml.Js +open Js_of_ocaml.Js.Unsafe + +type t + +let add_function wasm_mod name params results vars body = + meth_call wasm_mod "addFunction" + [| + inject (string name); + inject params; + inject results; + inject (array vars); + inject body; + |] + +let set_start wasm_mod func = meth_call wasm_mod "setStart" [| inject func |] + +let set_debug_location func expr file line column = + ignore + (meth_call global##.binaryen "_BinaryenFunctionSetDebugLocation" + [| inject func; inject expr; inject file; inject line; inject column |]) + +let get_function wasm_mod name = + meth_call wasm_mod "getFunction" [| inject (string name) |] + +let remove_function wasm_mod name = + meth_call wasm_mod "removeFunction" [| inject (string name) |] + +let get_num_functions wasm_mod = meth_call wasm_mod "getNumFunctions" [||] diff --git a/js/function_table.ml b/js/function_table.ml new file mode 100644 index 00000000..4ec8f06b --- /dev/null +++ b/js/function_table.ml @@ -0,0 +1,11 @@ +open Js_of_ocaml.Js +open Js_of_ocaml.Js.Unsafe + +let set_function_table wasm_mod initial maximum funcnames offset = + meth_call wasm_mod "setFunctionTable" + [| + inject initial; + inject maximum; + inject (array (Array.of_list (List.map string funcnames))); + inject offset; + |] diff --git a/js/global.ml b/js/global.ml new file mode 100644 index 00000000..6c8a5ace --- /dev/null +++ b/js/global.ml @@ -0,0 +1,19 @@ +open Js_of_ocaml.Js +open Js_of_ocaml.Js.Unsafe + +type t + +let add_global wasm_mod name typ is_mut init = + meth_call wasm_mod "addGlobal" + [| + inject (string name); + inject typ; + inject (if is_mut then 1 else 0); + inject init; + |] + +let get_global wasm_mod name = + meth_call wasm_mod "getGlobal" [| inject (string name) |] + +let remove_global wasm_mod name = + meth_call wasm_mod "removeGlobal" [| inject (string name) |] diff --git a/js/import.ml b/js/import.ml new file mode 100644 index 00000000..30ad4f1c --- /dev/null +++ b/js/import.ml @@ -0,0 +1,45 @@ +open Js_of_ocaml.Js +open Js_of_ocaml.Js.Unsafe + +let add_function_import wasm_mod internal_name external_module_name + external_base_name params result = + meth_call wasm_mod "addFunctionImport" + [| + inject (string internal_name); + inject (string external_module_name); + inject (string external_base_name); + inject params; + inject result; + |] + +let add_table_import wasm_mod internal_name external_module_name + external_base_name = + meth_call wasm_mod "addTableImport" + [| + inject (string internal_name); + inject (string external_module_name); + inject (string external_base_name); + |] + +(* TODO: Check this bool conversion *) +let add_memory_import wasm_mod internal_name external_module_name + external_base_name shared = + meth_call wasm_mod "addMemoryImport" + [| + inject (string internal_name); + inject (string external_module_name); + inject (string external_base_name); + inject (if shared then 1 else 0); + |] + +(* TODO: Check this bool conversion *) +let add_global_import wasm_mod internal_name external_module_name + external_base_name typ is_mut = + meth_call wasm_mod "addGlobalImport" + [| + inject (string internal_name); + inject (string external_module_name); + inject (string external_base_name); + inject typ; + inject (if is_mut then 1 else 0); + |] diff --git a/js/literal.ml b/js/literal.ml new file mode 100644 index 00000000..ce0a2b00 --- /dev/null +++ b/js/literal.ml @@ -0,0 +1,25 @@ +(* This is a hack around Binaryen's stack allocations *) +type jsoo = + | Int32 of int32 + | Int64 of int64 + | Float32Bits of int32 + | Float64Bits of int64 + | Float32 of float + | Float64 of float + +type t = jsoo + +let int32 value = Int32 value + +let int64 value = Int64 value + +let float32_bits value = Float32Bits value + +let float64_bits value = Float64Bits value + +let float32 value = Float32 value + +let float64 value = Float64 value + +(* This makes our `t` public so we can match on it *) +let to_jsoo lit = lit diff --git a/js/memory.ml b/js/memory.ml new file mode 100644 index 00000000..c24a02d1 --- /dev/null +++ b/js/memory.ml @@ -0,0 +1,37 @@ +open Js_of_ocaml +open Js_of_ocaml.Js +open Js_of_ocaml.Js.Unsafe + +type segment = { + name : string; + passive : bool; + offset : Expression.t; + size : int; +} + +(** Module, initial size, maximum size, export name, segments, shared. *) +let set_memory wasm_mod initial maximum export_name (segments : segment list) + shared = + let segs = + List.map + (fun { name; passive; offset; _ } -> + let data = + meth_call Typed_array.uint8Array "from" [| inject (string name) |] + in + obj + [| + ("data", data); + ("passive", inject passive); + ("offset", inject offset); + |]) + segments + in + ignore + (meth_call wasm_mod "setMemory" + [| + inject initial; + inject maximum; + inject (string export_name); + inject (array (Array.of_list segs)); + inject (if shared then _true else _false); + |]) diff --git a/js/module.ml b/js/module.ml new file mode 100644 index 00000000..6e3e13ab --- /dev/null +++ b/js/module.ml @@ -0,0 +1,125 @@ +open Js_of_ocaml +open Js_of_ocaml.Js +open Js_of_ocaml.Js.Unsafe + +type t + +let create () = new_obj global ##. binaryen ##. Module [||] + +let dispose wasm_mod = ignore (meth_call wasm_mod "dispose" [||]) + +(* TODO: Check the unit8Array conversion *) +let add_custom_section wasm_mod name contents = + let contents = + meth_call Typed_array.uint8Array "from" [| inject (string contents) |] + in + ignore + (meth_call wasm_mod "addCustomSection" + [| inject (string name); inject contents |]) + +let parse text = + meth_call global##.binaryen "parseText" [| inject (string text) |] + +let print wasm_mod = + let text = meth_call wasm_mod "emitText" [||] in + print_string (to_string text) + +let print_asmjs wasm_mod = + let asm = meth_call wasm_mod "emitAsmjs" [||] in + print_string (to_string asm) + +let validate wasm_mod = meth_call wasm_mod "validate" [||] + +let optimize wasm_mod = meth_call wasm_mod "optimize" [||] + +let set_features wasm_mod features = + meth_call wasm_mod "setFeatures" + [| inject (List.fold_left ( lor ) 0 features) |] + +let get_optimize_level () = meth_call global##.binaryen "getOptimizeLevel" [||] + +let set_optimize_level level = + meth_call global##.binaryen "setOptimizeLevel" [| inject level |] + +let get_shrink_level () = meth_call global##.binaryen "getShrinkLevel" [||] + +let set_shrink_level level = + meth_call global##.binaryen "setShrinkLevel" [| inject level |] + +let get_debug_info () = meth_call global##.binaryen "getDebugInfo" [||] + +let set_debug_info on = + meth_call global##.binaryen "setDebugInfo" [| inject on |] + +let get_low_memory_unused () = + meth_call global##.binaryen "getLowMemoryUnused" [||] + +let set_low_memory_unused on = + meth_call global##.binaryen "setLowMemoryUnused" [| inject on |] + +let get_pass_argument key = + meth_call global##.binaryen "getPassArgument" [| inject (string key) |] + +let set_pass_argument key value = + meth_call global##.binaryen "setPassArgument" + [| inject (string key); inject (string value) |] + +let get_always_inline_max_size () = + meth_call global##.binaryen "getAlwaysInlineMaxSize" [||] + +let set_always_inline_max_size size = + meth_call global##.binaryen "setAlwaysInlineMaxSize" [| inject size |] + +let get_flexible_inline_max_size () = + meth_call global##.binaryen "getFlexibleInlineMaxSize" [||] + +let set_flexible_inline_max_size size = + meth_call global##.binaryen "setFlexibleInlineMaxSize" [| inject size |] + +let get_one_caller_inline_max_size () = + meth_call global##.binaryen "getOneCallerInlineMaxSize" [||] + +let set_one_caller_inline_max_size size = + meth_call global##.binaryen "setOneCallerInlineMaxSize" [| inject size |] + +let run_passes wasm_mod passes = + meth_call wasm_mod "runPasses" + [| inject (array (Array.of_list (List.map string passes))) |] + +let auto_drop wasm_mod = meth_call wasm_mod "autoDrop" [||] + +let uint8array_to_bytes u8a = + Bytes.of_string (Typed_array.String.of_uint8Array u8a) + +let bytes_to_uint8array byts = + meth_call Typed_array.uint8Array "from" + [| inject (string (Bytes.to_string byts)) |] + +(* TODO: This returns the wrong type, need to convert from `Uint8Array` to `bytes` *) +let write wasm_mod sourcemap_url = + match sourcemap_url with + | Some url -> + let obj = meth_call wasm_mod "emitBinary" [| inject url |] in + let binary = get obj "binary" in + let soucemap = get obj "soureMap" in + (uint8array_to_bytes binary, Some soucemap) + | None -> + let binary = meth_call wasm_mod "emitBinary" [||] in + (uint8array_to_bytes binary, None) + +let write_text wasm_mod = + let text = meth_call wasm_mod "emitText" [||] in + to_string text + +(* TODO: This doesn't handle `bytes` correctly *) +let read byts = + let data = bytes_to_uint8array byts in + meth_call global##.binaryen "readBinary" [| inject data |] + +let interpret wasm_mod = meth_call wasm_mod "interpret" [||] + +let add_debug_info_filename wasm_mod filename = + meth_call wasm_mod "addDebugInfoFileName" [| inject (string filename) |] + +let get_debug_info_filename wasm_mod index = + meth_call wasm_mod "getDebugInfoFileName" [| inject index |] diff --git a/js/op.ml b/js/op.ml new file mode 100644 index 00000000..3583801d --- /dev/null +++ b/js/op.ml @@ -0,0 +1,784 @@ +open Js_of_ocaml.Js.Unsafe + +type t = int + +let clz_int32 : t = global ##. binaryen ##. Operations ##. ClzInt32 + +let ctz_int32 : t = global ##. binaryen ##. Operations ##. CtzInt32 + +let popcnt_int32 : t = global ##. binaryen ##. Operations ##. PopcntInt32 + +let neg_float32 : t = global ##. binaryen ##. Operations ##. NegFloat32 + +let abs_float32 : t = global ##. binaryen ##. Operations ##. AbsFloat32 + +let ceil_float32 : t = global ##. binaryen ##. Operations ##. CeilFloat32 + +let floor_float32 : t = global ##. binaryen ##. Operations ##. FloorFloat32 + +let trunc_float32 : t = global ##. binaryen ##. Operations ##. TruncFloat32 + +let nearest_float32 : t = global ##. binaryen ##. Operations ##. NearestFloat32 + +let sqrt_float32 : t = global ##. binaryen ##. Operations ##. SqrtFloat32 + +let eq_z_int32 : t = global ##. binaryen ##. Operations ##. EqZInt32 + +let clz_int64 : t = global ##. binaryen ##. Operations ##. ClzInt64 + +let ctz_int64 : t = global ##. binaryen ##. Operations ##. CtzInt64 + +let popcnt_int64 : t = global ##. binaryen ##. Operations ##. PopcntInt64 + +let neg_float64 : t = global ##. binaryen ##. Operations ##. NegFloat64 + +let abs_float64 : t = global ##. binaryen ##. Operations ##. AbsFloat64 + +let ceil_float64 : t = global ##. binaryen ##. Operations ##. CeilFloat64 + +let floor_float64 : t = global ##. binaryen ##. Operations ##. FloorFloat64 + +let trunc_float64 : t = global ##. binaryen ##. Operations ##. TruncFloat64 + +let nearest_float64 : t = global ##. binaryen ##. Operations ##. NearestFloat64 + +let sqrt_float64 : t = global ##. binaryen ##. Operations ##. SqrtFloat64 + +let eq_z_int64 : t = global ##. binaryen ##. Operations ##. EqZInt64 + +let extend_s_int32 : t = global ##. binaryen ##. Operations ##. ExtendSInt32 + +let extend_u_int32 : t = global ##. binaryen ##. Operations ##. ExtendUInt32 + +let wrap_int64 : t = global ##. binaryen ##. Operations ##. WrapInt64 + +let trunc_s_float32_to_int32 : t = + global ##. binaryen ##. Operations ##. TruncSFloat32ToInt32 + +let trunc_s_float32_to_int64 : t = + global ##. binaryen ##. Operations ##. TruncSFloat32ToInt64 + +let trunc_u_float32_to_int32 : t = + global ##. binaryen ##. Operations ##. TruncUFloat32ToInt32 + +let trunc_u_float32_to_int64 : t = + global ##. binaryen ##. Operations ##. TruncUFloat32ToInt64 + +let trunc_s_float64_to_int32 : t = + global ##. binaryen ##. Operations ##. TruncSFloat64ToInt32 + +let trunc_s_float64_to_int64 : t = + global ##. binaryen ##. Operations ##. TruncSFloat64ToInt64 + +let trunc_u_float64_to_int32 : t = + global ##. binaryen ##. Operations ##. TruncUFloat64ToInt32 + +let trunc_u_float64_to_int64 : t = + global ##. binaryen ##. Operations ##. TruncUFloat64ToInt64 + +let reinterpret_float32 : t = + global ##. binaryen ##. Operations ##. ReinterpretFloat32 + +let reinterpret_float64 : t = + global ##. binaryen ##. Operations ##. ReinterpretFloat64 + +let convert_s_int32_to_float32 : t = + global ##. binaryen ##. Operations ##. ConvertSInt32ToFloat32 + +let convert_s_int32_to_float64 : t = + global ##. binaryen ##. Operations ##. ConvertSInt32ToFloat64 + +let convert_u_int32_to_float32 : t = + global ##. binaryen ##. Operations ##. ConvertUInt32ToFloat32 + +let convert_u_int32_to_float64 : t = + global ##. binaryen ##. Operations ##. ConvertUInt32ToFloat64 + +let convert_s_int64_to_float32 : t = + global ##. binaryen ##. Operations ##. ConvertSInt64ToFloat32 + +let convert_s_int64_to_float64 : t = + global ##. binaryen ##. Operations ##. ConvertSInt64ToFloat64 + +let convert_u_int64_to_float32 : t = + global ##. binaryen ##. Operations ##. ConvertUInt64ToFloat32 + +let convert_u_int64_to_float64 : t = + global ##. binaryen ##. Operations ##. ConvertUInt64ToFloat64 + +let promote_float32 : t = global ##. binaryen ##. Operations ##. PromoteFloat32 + +let demote_float64 : t = global ##. binaryen ##. Operations ##. DemoteFloat64 + +let reinterpret_int32 : t = + global ##. binaryen ##. Operations ##. ReinterpretInt32 + +let reinterpret_int64 : t = + global ##. binaryen ##. Operations ##. ReinterpretInt64 + +let extend_s8_int32 : t = global ##. binaryen ##. Operations ##. ExtendS8Int32 + +let extend_s16_int32 : t = global ##. binaryen ##. Operations ##. ExtendS16Int32 + +let extend_s8_int64 : t = global ##. binaryen ##. Operations ##. ExtendS8Int64 + +let extend_s16_int64 : t = global ##. binaryen ##. Operations ##. ExtendS16Int64 + +let extend_s32_int64 : t = global ##. binaryen ##. Operations ##. ExtendS32Int64 + +let add_int32 : t = global ##. binaryen ##. Operations ##. AddInt32 + +let sub_int32 : t = global ##. binaryen ##. Operations ##. SubInt32 + +let mul_int32 : t = global ##. binaryen ##. Operations ##. MulInt32 + +let div_s_int32 : t = global ##. binaryen ##. Operations ##. DivSInt32 + +let div_u_int32 : t = global ##. binaryen ##. Operations ##. DivUInt32 + +let rem_s_int32 : t = global ##. binaryen ##. Operations ##. RemSInt32 + +let rem_u_int32 : t = global ##. binaryen ##. Operations ##. RemUInt32 + +let and_int32 : t = global ##. binaryen ##. Operations ##. AndInt32 + +let or_int32 : t = global ##. binaryen ##. Operations ##. OrInt32 + +let xor_int32 : t = global ##. binaryen ##. Operations ##. XorInt32 + +let shl_int32 : t = global ##. binaryen ##. Operations ##. ShlInt32 + +let shr_u_int32 : t = global ##. binaryen ##. Operations ##. ShrUInt32 + +let shr_s_int32 : t = global ##. binaryen ##. Operations ##. ShrSInt32 + +let rot_l_int32 : t = global ##. binaryen ##. Operations ##. RotLInt32 + +let rot_r_int32 : t = global ##. binaryen ##. Operations ##. RotRInt32 + +let eq_int32 : t = global ##. binaryen ##. Operations ##. EqInt32 + +let ne_int32 : t = global ##. binaryen ##. Operations ##. NeInt32 + +let lt_s_int32 : t = global ##. binaryen ##. Operations ##. LtSInt32 + +let lt_u_int32 : t = global ##. binaryen ##. Operations ##. LtUInt32 + +let le_s_int32 : t = global ##. binaryen ##. Operations ##. LeSInt32 + +let le_u_int32 : t = global ##. binaryen ##. Operations ##. LeUInt32 + +let gt_s_int32 : t = global ##. binaryen ##. Operations ##. GtSInt32 + +let gt_u_int32 : t = global ##. binaryen ##. Operations ##. GtUInt32 + +let ge_s_int32 : t = global ##. binaryen ##. Operations ##. GeSInt32 + +let ge_u_int32 : t = global ##. binaryen ##. Operations ##. GeUInt32 + +let add_int64 : t = global ##. binaryen ##. Operations ##. AddInt64 + +let sub_int64 : t = global ##. binaryen ##. Operations ##. SubInt64 + +let mul_int64 : t = global ##. binaryen ##. Operations ##. MulInt64 + +let div_s_int64 : t = global ##. binaryen ##. Operations ##. DivSInt64 + +let div_u_int64 : t = global ##. binaryen ##. Operations ##. DivUInt64 + +let rem_s_int64 : t = global ##. binaryen ##. Operations ##. RemSInt64 + +let rem_u_int64 : t = global ##. binaryen ##. Operations ##. RemUInt64 + +let and_int64 : t = global ##. binaryen ##. Operations ##. AndInt64 + +let or_int64 : t = global ##. binaryen ##. Operations ##. OrInt64 + +let xor_int64 : t = global ##. binaryen ##. Operations ##. XorInt64 + +let shl_int64 : t = global ##. binaryen ##. Operations ##. ShlInt64 + +let shr_u_int64 : t = global ##. binaryen ##. Operations ##. ShrUInt64 + +let shr_s_int64 : t = global ##. binaryen ##. Operations ##. ShrSInt64 + +let rot_l_int64 : t = global ##. binaryen ##. Operations ##. RotLInt64 + +let rot_r_int64 : t = global ##. binaryen ##. Operations ##. RotRInt64 + +let eq_int64 : t = global ##. binaryen ##. Operations ##. EqInt64 + +let ne_int64 : t = global ##. binaryen ##. Operations ##. NeInt64 + +let lt_s_int64 : t = global ##. binaryen ##. Operations ##. LtSInt64 + +let lt_u_int64 : t = global ##. binaryen ##. Operations ##. LtUInt64 + +let le_s_int64 : t = global ##. binaryen ##. Operations ##. LeSInt64 + +let le_u_int64 : t = global ##. binaryen ##. Operations ##. LeUInt64 + +let gt_s_int64 : t = global ##. binaryen ##. Operations ##. GtSInt64 + +let gt_u_int64 : t = global ##. binaryen ##. Operations ##. GtUInt64 + +let ge_s_int64 : t = global ##. binaryen ##. Operations ##. GeSInt64 + +let ge_u_int64 : t = global ##. binaryen ##. Operations ##. GeUInt64 + +let add_float32 : t = global ##. binaryen ##. Operations ##. AddFloat32 + +let sub_float32 : t = global ##. binaryen ##. Operations ##. SubFloat32 + +let mul_float32 : t = global ##. binaryen ##. Operations ##. MulFloat32 + +let div_float32 : t = global ##. binaryen ##. Operations ##. DivFloat32 + +let copy_sign_float32 : t = + global ##. binaryen ##. Operations ##. CopySignFloat32 + +let min_float32 : t = global ##. binaryen ##. Operations ##. MinFloat32 + +let max_float32 : t = global ##. binaryen ##. Operations ##. MaxFloat32 + +let eq_float32 : t = global ##. binaryen ##. Operations ##. EqFloat32 + +let ne_float32 : t = global ##. binaryen ##. Operations ##. NeFloat32 + +let lt_float32 : t = global ##. binaryen ##. Operations ##. LtFloat32 + +let le_float32 : t = global ##. binaryen ##. Operations ##. LeFloat32 + +let gt_float32 : t = global ##. binaryen ##. Operations ##. GtFloat32 + +let ge_float32 : t = global ##. binaryen ##. Operations ##. GeFloat32 + +let add_float64 : t = global ##. binaryen ##. Operations ##. AddFloat64 + +let sub_float64 : t = global ##. binaryen ##. Operations ##. SubFloat64 + +let mul_float64 : t = global ##. binaryen ##. Operations ##. MulFloat64 + +let div_float64 : t = global ##. binaryen ##. Operations ##. DivFloat64 + +let copy_sign_float64 : t = + global ##. binaryen ##. Operations ##. CopySignFloat64 + +let min_float64 : t = global ##. binaryen ##. Operations ##. MinFloat64 + +let max_float64 : t = global ##. binaryen ##. Operations ##. MaxFloat64 + +let eq_float64 : t = global ##. binaryen ##. Operations ##. EqFloat64 + +let ne_float64 : t = global ##. binaryen ##. Operations ##. NeFloat64 + +let lt_float64 : t = global ##. binaryen ##. Operations ##. LtFloat64 + +let le_float64 : t = global ##. binaryen ##. Operations ##. LeFloat64 + +let gt_float64 : t = global ##. binaryen ##. Operations ##. GtFloat64 + +let ge_float64 : t = global ##. binaryen ##. Operations ##. GeFloat64 + +let memory_size : t = global ##. binaryen ##. Operations ##. MemorySize + +let memory_grow : t = global ##. binaryen ##. Operations ##. MemoryGrow + +let atomic_rmw_add : t = global ##. binaryen ##. Operations ##. AtomicRMWAdd + +let atomic_rmw_sub : t = global ##. binaryen ##. Operations ##. AtomicRMWSub + +let atomic_rmw_and : t = global ##. binaryen ##. Operations ##. AtomicRMWAnd + +let atomic_rmw_or : t = global ##. binaryen ##. Operations ##. AtomicRMWOr + +let atomic_rmw_xor : t = global ##. binaryen ##. Operations ##. AtomicRMWXor + +let atomic_rmw_xchg : t = global ##. binaryen ##. Operations ##. AtomicRMWXchg + +let trunc_sat_s_float32_to_int32 : t = + global ##. binaryen ##. Operations ##. TruncSatSFloat32ToInt32 + +let trunc_sat_s_float32_to_int64 : t = + global ##. binaryen ##. Operations ##. TruncSatSFloat32ToInt64 + +let trunc_sat_u_float32_to_int32 : t = + global ##. binaryen ##. Operations ##. TruncSatUFloat32ToInt32 + +let trunc_sat_u_float32_to_int64 : t = + global ##. binaryen ##. Operations ##. TruncSatUFloat32ToInt64 + +let trunc_sat_s_float64_to_int32 : t = + global ##. binaryen ##. Operations ##. TruncSatSFloat64ToInt32 + +let trunc_sat_s_float64_to_int64 : t = + global ##. binaryen ##. Operations ##. TruncSatSFloat64ToInt64 + +let trunc_sat_u_float64_to_int32 : t = + global ##. binaryen ##. Operations ##. TruncSatUFloat64ToInt32 + +let trunc_sat_u_float64_to_int64 : t = + global ##. binaryen ##. Operations ##. TruncSatUFloat64ToInt64 + +let splat_vec_i8x16 : t = global ##. binaryen ##. Operations ##. SplatVecI8x16 + +let extract_lane_s_vec_i8x16 : t = + global ##. binaryen ##. Operations ##. ExtractLaneSVecI8x16 + +let extract_lane_u_vec_i8x16 : t = + global ##. binaryen ##. Operations ##. ExtractLaneUVecI8x16 + +let replace_lane_vec_i8x16 : t = + global ##. binaryen ##. Operations ##. ReplaceLaneVecI8x16 + +let splat_vec_i16x8 : t = global ##. binaryen ##. Operations ##. SplatVecI16x8 + +let extract_lane_s_vec_i16x8 : t = + global ##. binaryen ##. Operations ##. ExtractLaneSVecI16x8 + +let extract_lane_u_vec_i16x8 : t = + global ##. binaryen ##. Operations ##. ExtractLaneUVecI16x8 + +let replace_lane_vec_i16x8 : t = + global ##. binaryen ##. Operations ##. ReplaceLaneVecI16x8 + +let splat_vec_i32x4 : t = global ##. binaryen ##. Operations ##. SplatVecI32x4 + +let extract_lane_vec_i32x4 : t = + global ##. binaryen ##. Operations ##. ExtractLaneVecI32x4 + +let replace_lane_vec_i32x4 : t = + global ##. binaryen ##. Operations ##. ReplaceLaneVecI32x4 + +let splat_vec_i64x2 : t = global ##. binaryen ##. Operations ##. SplatVecI64x2 + +let extract_lane_vec_i64x2 : t = + global ##. binaryen ##. Operations ##. ExtractLaneVecI64x2 + +let replace_lane_vec_i64x2 : t = + global ##. binaryen ##. Operations ##. ReplaceLaneVecI64x2 + +let splat_vec_f32x4 : t = global ##. binaryen ##. Operations ##. SplatVecF32x4 + +let extract_lane_vec_f32x4 : t = + global ##. binaryen ##. Operations ##. ExtractLaneVecF32x4 + +let replace_lane_vec_f32x4 : t = + global ##. binaryen ##. Operations ##. ReplaceLaneVecF32x4 + +let splat_vec_f64x2 : t = global ##. binaryen ##. Operations ##. SplatVecF64x2 + +let extract_lane_vec_f64x2 : t = + global ##. binaryen ##. Operations ##. ExtractLaneVecF64x2 + +let replace_lane_vec_f64x2 : t = + global ##. binaryen ##. Operations ##. ReplaceLaneVecF64x2 + +let eq_vec_i8x16 : t = global ##. binaryen ##. Operations ##. EqVecI8x16 + +let ne_vec_i8x16 : t = global ##. binaryen ##. Operations ##. NeVecI8x16 + +let lt_s_vec_i8x16 : t = global ##. binaryen ##. Operations ##. LtSVecI8x16 + +let lt_u_vec_i8x16 : t = global ##. binaryen ##. Operations ##. LtUVecI8x16 + +let gt_s_vec_i8x16 : t = global ##. binaryen ##. Operations ##. GtSVecI8x16 + +let gt_u_vec_i8x16 : t = global ##. binaryen ##. Operations ##. GtUVecI8x16 + +let le_s_vec_i8x16 : t = global ##. binaryen ##. Operations ##. LeSVecI8x16 + +let le_u_vec_i8x16 : t = global ##. binaryen ##. Operations ##. LeUVecI8x16 + +let ge_s_vec_i8x16 : t = global ##. binaryen ##. Operations ##. GeSVecI8x16 + +let ge_u_vec_i8x16 : t = global ##. binaryen ##. Operations ##. GeUVecI8x16 + +let eq_vec_i16x8 : t = global ##. binaryen ##. Operations ##. EqVecI16x8 + +let ne_vec_i16x8 : t = global ##. binaryen ##. Operations ##. NeVecI16x8 + +let lt_s_vec_i16x8 : t = global ##. binaryen ##. Operations ##. LtSVecI16x8 + +let lt_u_vec_i16x8 : t = global ##. binaryen ##. Operations ##. LtUVecI16x8 + +let gt_s_vec_i16x8 : t = global ##. binaryen ##. Operations ##. GtSVecI16x8 + +let gt_u_vec_i16x8 : t = global ##. binaryen ##. Operations ##. GtUVecI16x8 + +let le_s_vec_i16x8 : t = global ##. binaryen ##. Operations ##. LeSVecI16x8 + +let le_u_vec_i16x8 : t = global ##. binaryen ##. Operations ##. LeUVecI16x8 + +let ge_s_vec_i16x8 : t = global ##. binaryen ##. Operations ##. GeSVecI16x8 + +let ge_u_vec_i16x8 : t = global ##. binaryen ##. Operations ##. GeUVecI16x8 + +let eq_vec_i32x4 : t = global ##. binaryen ##. Operations ##. EqVecI32x4 + +let ne_vec_i32x4 : t = global ##. binaryen ##. Operations ##. NeVecI32x4 + +let lt_s_vec_i32x4 : t = global ##. binaryen ##. Operations ##. LtSVecI32x4 + +let lt_u_vec_i32x4 : t = global ##. binaryen ##. Operations ##. LtUVecI32x4 + +let gt_s_vec_i32x4 : t = global ##. binaryen ##. Operations ##. GtSVecI32x4 + +let gt_u_vec_i32x4 : t = global ##. binaryen ##. Operations ##. GtUVecI32x4 + +let le_s_vec_i32x4 : t = global ##. binaryen ##. Operations ##. LeSVecI32x4 + +let le_u_vec_i32x4 : t = global ##. binaryen ##. Operations ##. LeUVecI32x4 + +let ge_s_vec_i32x4 : t = global ##. binaryen ##. Operations ##. GeSVecI32x4 + +let ge_u_vec_i32x4 : t = global ##. binaryen ##. Operations ##. GeUVecI32x4 + +let eq_vec_f32x4 : t = global ##. binaryen ##. Operations ##. EqVecF32x4 + +let ne_vec_f32x4 : t = global ##. binaryen ##. Operations ##. NeVecF32x4 + +let lt_vec_f32x4 : t = global ##. binaryen ##. Operations ##. LtVecF32x4 + +let gt_vec_f32x4 : t = global ##. binaryen ##. Operations ##. GtVecF32x4 + +let le_vec_f32x4 : t = global ##. binaryen ##. Operations ##. LeVecF32x4 + +let ge_vec_f32x4 : t = global ##. binaryen ##. Operations ##. GeVecF32x4 + +let eq_vec_f64x2 : t = global ##. binaryen ##. Operations ##. EqVecF64x2 + +let ne_vec_f64x2 : t = global ##. binaryen ##. Operations ##. NeVecF64x2 + +let lt_vec_f64x2 : t = global ##. binaryen ##. Operations ##. LtVecF64x2 + +let gt_vec_f64x2 : t = global ##. binaryen ##. Operations ##. GtVecF64x2 + +let le_vec_f64x2 : t = global ##. binaryen ##. Operations ##. LeVecF64x2 + +let ge_vec_f64x2 : t = global ##. binaryen ##. Operations ##. GeVecF64x2 + +let not_vec128 : t = global ##. binaryen ##. Operations ##. NotVec128 + +let and_vec128 : t = global ##. binaryen ##. Operations ##. AndVec128 + +let or_vec128 : t = global ##. binaryen ##. Operations ##. OrVec128 + +let xor_vec128 : t = global ##. binaryen ##. Operations ##. XorVec128 + +let and_not_vec128 : t = global ##. binaryen ##. Operations ##. AndNotVec128 + +let bitselect_vec128 : t = + global ##. binaryen ##. Operations ##. BitselectVec128 + +let abs_vec_i8x16 : t = global ##. binaryen ##. Operations ##. AbsVecI8x16 + +let neg_vec_i8x16 : t = global ##. binaryen ##. Operations ##. NegVecI8x16 + +let any_true_vec_i8x16 : t = + global ##. binaryen ##. Operations ##. AnyTrueVecI8x16 + +let all_true_vec_i8x16 : t = + global ##. binaryen ##. Operations ##. AllTrueVecI8x16 + +let bitmask_vec_i8x16 : t = + global ##. binaryen ##. Operations ##. BitmaskVecI8x16 + +let shl_vec_i8x16 : t = global ##. binaryen ##. Operations ##. ShlVecI8x16 + +let shr_s_vec_i8x16 : t = global ##. binaryen ##. Operations ##. ShrSVecI8x16 + +let shr_u_vec_i8x16 : t = global ##. binaryen ##. Operations ##. ShrUVecI8x16 + +let add_vec_i8x16 : t = global ##. binaryen ##. Operations ##. AddVecI8x16 + +let add_sat_s_vec_i8x16 : t = + global ##. binaryen ##. Operations ##. AddSatSVecI8x16 + +let add_sat_u_vec_i8x16 : t = + global ##. binaryen ##. Operations ##. AddSatUVecI8x16 + +let sub_vec_i8x16 : t = global ##. binaryen ##. Operations ##. SubVecI8x16 + +let sub_sat_s_vec_i8x16 : t = + global ##. binaryen ##. Operations ##. SubSatSVecI8x16 + +let sub_sat_u_vec_i8x16 : t = + global ##. binaryen ##. Operations ##. SubSatUVecI8x16 + +let mul_vec_i8x16 : t = global ##. binaryen ##. Operations ##. MulVecI8x16 + +let min_s_vec_i8x16 : t = global ##. binaryen ##. Operations ##. MinSVecI8x16 + +let min_u_vec_i8x16 : t = global ##. binaryen ##. Operations ##. MinUVecI8x16 + +let max_s_vec_i8x16 : t = global ##. binaryen ##. Operations ##. MaxSVecI8x16 + +let max_u_vec_i8x16 : t = global ##. binaryen ##. Operations ##. MaxUVecI8x16 + +let avgr_u_vec_i8x16 : t = global ##. binaryen ##. Operations ##. AvgrUVecI8x16 + +let abs_vec_i16x8 : t = global ##. binaryen ##. Operations ##. AbsVecI16x8 + +let neg_vec_i16x8 : t = global ##. binaryen ##. Operations ##. NegVecI16x8 + +let any_true_vec_i16x8 : t = + global ##. binaryen ##. Operations ##. AnyTrueVecI16x8 + +let all_true_vec_i16x8 : t = + global ##. binaryen ##. Operations ##. AllTrueVecI16x8 + +let bitmask_vec_i16x8 : t = + global ##. binaryen ##. Operations ##. BitmaskVecI16x8 + +let shl_vec_i16x8 : t = global ##. binaryen ##. Operations ##. ShlVecI16x8 + +let shr_s_vec_i16x8 : t = global ##. binaryen ##. Operations ##. ShrSVecI16x8 + +let shr_u_vec_i16x8 : t = global ##. binaryen ##. Operations ##. ShrUVecI16x8 + +let add_vec_i16x8 : t = global ##. binaryen ##. Operations ##. AddVecI16x8 + +let add_sat_s_vec_i16x8 : t = + global ##. binaryen ##. Operations ##. AddSatSVecI16x8 + +let add_sat_u_vec_i16x8 : t = + global ##. binaryen ##. Operations ##. AddSatUVecI16x8 + +let sub_vec_i16x8 : t = global ##. binaryen ##. Operations ##. SubVecI16x8 + +let sub_sat_s_vec_i16x8 : t = + global ##. binaryen ##. Operations ##. SubSatSVecI16x8 + +let sub_sat_u_vec_i16x8 : t = + global ##. binaryen ##. Operations ##. SubSatUVecI16x8 + +let mul_vec_i16x8 : t = global ##. binaryen ##. Operations ##. MulVecI16x8 + +let min_s_vec_i16x8 : t = global ##. binaryen ##. Operations ##. MinSVecI16x8 + +let min_u_vec_i16x8 : t = global ##. binaryen ##. Operations ##. MinUVecI16x8 + +let max_s_vec_i16x8 : t = global ##. binaryen ##. Operations ##. MaxSVecI16x8 + +let max_u_vec_i16x8 : t = global ##. binaryen ##. Operations ##. MaxUVecI16x8 + +let avgr_u_vec_i16x8 : t = global ##. binaryen ##. Operations ##. AvgrUVecI16x8 + +let abs_vec_i32x4 : t = global ##. binaryen ##. Operations ##. AbsVecI32x4 + +let neg_vec_i32x4 : t = global ##. binaryen ##. Operations ##. NegVecI32x4 + +let any_true_vec_i32x4 : t = + global ##. binaryen ##. Operations ##. AnyTrueVecI32x4 + +let all_true_vec_i32x4 : t = + global ##. binaryen ##. Operations ##. AllTrueVecI32x4 + +let bitmask_vec_i32x4 : t = + global ##. binaryen ##. Operations ##. BitmaskVecI32x4 + +let shl_vec_i32x4 : t = global ##. binaryen ##. Operations ##. ShlVecI32x4 + +let shr_s_vec_i32x4 : t = global ##. binaryen ##. Operations ##. ShrSVecI32x4 + +let shr_u_vec_i32x4 : t = global ##. binaryen ##. Operations ##. ShrUVecI32x4 + +let add_vec_i32x4 : t = global ##. binaryen ##. Operations ##. AddVecI32x4 + +let sub_vec_i32x4 : t = global ##. binaryen ##. Operations ##. SubVecI32x4 + +let mul_vec_i32x4 : t = global ##. binaryen ##. Operations ##. MulVecI32x4 + +let min_s_vec_i32x4 : t = global ##. binaryen ##. Operations ##. MinSVecI32x4 + +let min_u_vec_i32x4 : t = global ##. binaryen ##. Operations ##. MinUVecI32x4 + +let max_s_vec_i32x4 : t = global ##. binaryen ##. Operations ##. MaxSVecI32x4 + +let max_u_vec_i32x4 : t = global ##. binaryen ##. Operations ##. MaxUVecI32x4 + +let dot_s_vec_i16x8_to_vec_i32x4 : t = + global ##. binaryen ##. Operations ##. DotSVecI16x8ToVecI32x4 + +let neg_vec_i64x2 : t = global ##. binaryen ##. Operations ##. NegVecI64x2 + +let any_true_vec_i64x2 : t = + global ##. binaryen ##. Operations ##. AnyTrueVecI64x2 + +let all_true_vec_i64x2 : t = + global ##. binaryen ##. Operations ##. AllTrueVecI64x2 + +let shl_vec_i64x2 : t = global ##. binaryen ##. Operations ##. ShlVecI64x2 + +let shr_s_vec_i64x2 : t = global ##. binaryen ##. Operations ##. ShrSVecI64x2 + +let shr_u_vec_i64x2 : t = global ##. binaryen ##. Operations ##. ShrUVecI64x2 + +let add_vec_i64x2 : t = global ##. binaryen ##. Operations ##. AddVecI64x2 + +let sub_vec_i64x2 : t = global ##. binaryen ##. Operations ##. SubVecI64x2 + +let mul_vec_i64x2 : t = global ##. binaryen ##. Operations ##. MulVecI64x2 + +let abs_vec_f32x4 : t = global ##. binaryen ##. Operations ##. AbsVecF32x4 + +let neg_vec_f32x4 : t = global ##. binaryen ##. Operations ##. NegVecF32x4 + +let sqrt_vec_f32x4 : t = global ##. binaryen ##. Operations ##. SqrtVecF32x4 + +let qfma_vec_f32x4 : t = global ##. binaryen ##. Operations ##. QFMAVecF32x4 + +let qfms_vec_f32x4 : t = global ##. binaryen ##. Operations ##. QFMSVecF32x4 + +let add_vec_f32x4 : t = global ##. binaryen ##. Operations ##. AddVecF32x4 + +let sub_vec_f32x4 : t = global ##. binaryen ##. Operations ##. SubVecF32x4 + +let mul_vec_f32x4 : t = global ##. binaryen ##. Operations ##. MulVecF32x4 + +let div_vec_f32x4 : t = global ##. binaryen ##. Operations ##. DivVecF32x4 + +let min_vec_f32x4 : t = global ##. binaryen ##. Operations ##. MinVecF32x4 + +let max_vec_f32x4 : t = global ##. binaryen ##. Operations ##. MaxVecF32x4 + +let p_min_vec_f32x4 : t = global ##. binaryen ##. Operations ##. PMinVecF32x4 + +let p_max_vec_f32x4 : t = global ##. binaryen ##. Operations ##. PMaxVecF32x4 + +let ceil_vec_f32x4 : t = global ##. binaryen ##. Operations ##. CeilVecF32x4 + +let floor_vec_f32x4 : t = global ##. binaryen ##. Operations ##. FloorVecF32x4 + +let trunc_vec_f32x4 : t = global ##. binaryen ##. Operations ##. TruncVecF32x4 + +let nearest_vec_f32x4 : t = + global ##. binaryen ##. Operations ##. NearestVecF32x4 + +let abs_vec_f64x2 : t = global ##. binaryen ##. Operations ##. AbsVecF64x2 + +let neg_vec_f64x2 : t = global ##. binaryen ##. Operations ##. NegVecF64x2 + +let sqrt_vec_f64x2 : t = global ##. binaryen ##. Operations ##. SqrtVecF64x2 + +let qfma_vec_f64x2 : t = global ##. binaryen ##. Operations ##. QFMAVecF64x2 + +let qfms_vec_f64x2 : t = global ##. binaryen ##. Operations ##. QFMSVecF64x2 + +let add_vec_f64x2 : t = global ##. binaryen ##. Operations ##. AddVecF64x2 + +let sub_vec_f64x2 : t = global ##. binaryen ##. Operations ##. SubVecF64x2 + +let mul_vec_f64x2 : t = global ##. binaryen ##. Operations ##. MulVecF64x2 + +let div_vec_f64x2 : t = global ##. binaryen ##. Operations ##. DivVecF64x2 + +let min_vec_f64x2 : t = global ##. binaryen ##. Operations ##. MinVecF64x2 + +let max_vec_f64x2 : t = global ##. binaryen ##. Operations ##. MaxVecF64x2 + +let p_min_vec_f64x2 : t = global ##. binaryen ##. Operations ##. PMinVecF64x2 + +let p_max_vec_f64x2 : t = global ##. binaryen ##. Operations ##. PMaxVecF64x2 + +let ceil_vec_f64x2 : t = global ##. binaryen ##. Operations ##. CeilVecF64x2 + +let floor_vec_f64x2 : t = global ##. binaryen ##. Operations ##. FloorVecF64x2 + +let trunc_vec_f64x2 : t = global ##. binaryen ##. Operations ##. TruncVecF64x2 + +let nearest_vec_f64x2 : t = + global ##. binaryen ##. Operations ##. NearestVecF64x2 + +let trunc_sat_s_vec_f32x4_to_vec_i32x4 : t = + global ##. binaryen ##. Operations ##. TruncSatSVecF32x4ToVecI32x4 + +let trunc_sat_u_vec_f32x4_to_vec_i32x4 : t = + global ##. binaryen ##. Operations ##. TruncSatUVecF32x4ToVecI32x4 + +let trunc_sat_s_vec_f64x2_to_vec_i64x2 : t = + global ##. binaryen ##. Operations ##. TruncSatSVecF64x2ToVecI64x2 + +let trunc_sat_u_vec_f64x2_to_vec_i64x2 : t = + global ##. binaryen ##. Operations ##. TruncSatUVecF64x2ToVecI64x2 + +let convert_s_vec_i32x4_to_vec_f32x4 : t = + global ##. binaryen ##. Operations ##. ConvertSVecI32x4ToVecF32x4 + +let convert_u_vec_i32x4_to_vec_f32x4 : t = + global ##. binaryen ##. Operations ##. ConvertUVecI32x4ToVecF32x4 + +let convert_s_vec_i64x2_to_vec_f64x2 : t = + global ##. binaryen ##. Operations ##. ConvertSVecI64x2ToVecF64x2 + +let convert_u_vec_i64x2_to_vec_f64x2 : t = + global ##. binaryen ##. Operations ##. ConvertUVecI64x2ToVecF64x2 + +let load_splat_vec8x16 : t = + global ##. binaryen ##. Operations ##. LoadSplatVec8x16 + +let load_splat_vec16x8 : t = + global ##. binaryen ##. Operations ##. LoadSplatVec16x8 + +let load_splat_vec32x4 : t = + global ##. binaryen ##. Operations ##. LoadSplatVec32x4 + +let load_splat_vec64x2 : t = + global ##. binaryen ##. Operations ##. LoadSplatVec64x2 + +let load_ext_s_vec8x8_to_vec_i16x8 : t = + global ##. binaryen ##. Operations ##. LoadExtSVec8x8ToVecI16x8 + +let load_ext_u_vec8x8_to_vec_i16x8 : t = + global ##. binaryen ##. Operations ##. LoadExtUVec8x8ToVecI16x8 + +let load_ext_s_vec16x4_to_vec_i32x4 : t = + global ##. binaryen ##. Operations ##. LoadExtSVec16x4ToVecI32x4 + +let load_ext_u_vec16x4_to_vec_i32x4 : t = + global ##. binaryen ##. Operations ##. LoadExtUVec16x4ToVecI32x4 + +let load_ext_s_vec32x2_to_vec_i64x2 : t = + global ##. binaryen ##. Operations ##. LoadExtSVec32x2ToVecI64x2 + +let load_ext_u_vec32x2_to_vec_i64x2 : t = + global ##. binaryen ##. Operations ##. LoadExtUVec32x2ToVecI64x2 + +let narrow_s_vec_i16x8_to_vec_i8x16 : t = + global ##. binaryen ##. Operations ##. NarrowSVecI16x8ToVecI8x16 + +let narrow_u_vec_i16x8_to_vec_i8x16 : t = + global ##. binaryen ##. Operations ##. NarrowUVecI16x8ToVecI8x16 + +let narrow_s_vec_i32x4_to_vec_i16x8 : t = + global ##. binaryen ##. Operations ##. NarrowSVecI32x4ToVecI16x8 + +let narrow_u_vec_i32x4_to_vec_i16x8 : t = + global ##. binaryen ##. Operations ##. NarrowUVecI32x4ToVecI16x8 + +let widen_low_s_vec_i8x16_to_vec_i16x8 : t = + global ##. binaryen ##. Operations ##. WidenLowSVecI8x16ToVecI16x8 + +let widen_high_s_vec_i8x16_to_vec_i16x8 : t = + global ##. binaryen ##. Operations ##. WidenHighSVecI8x16ToVecI16x8 + +let widen_low_u_vec_i8x16_to_vec_i16x8 : t = + global ##. binaryen ##. Operations ##. WidenLowUVecI8x16ToVecI16x8 + +let widen_high_u_vec_i8x16_to_vec_i16x8 : t = + global ##. binaryen ##. Operations ##. WidenHighUVecI8x16ToVecI16x8 + +let widen_low_s_vec_i16x8_to_vec_i32x4 : t = + global ##. binaryen ##. Operations ##. WidenLowSVecI16x8ToVecI32x4 + +let widen_high_s_vec_i16x8_to_vec_i32x4 : t = + global ##. binaryen ##. Operations ##. WidenHighSVecI16x8ToVecI32x4 + +let widen_low_u_vec_i16x8_to_vec_i32x4 : t = + global ##. binaryen ##. Operations ##. WidenLowUVecI16x8ToVecI32x4 + +let widen_high_u_vec_i16x8_to_vec_i32x4 : t = + global ##. binaryen ##. Operations ##. WidenHighUVecI16x8ToVecI32x4 + +let swizzle_vec8x16 : t = global ##. binaryen ##. Operations ##. SwizzleVec8x16 diff --git a/js/postlude.js b/js/postlude.js new file mode 100644 index 00000000..c44ccc5f --- /dev/null +++ b/js/postlude.js @@ -0,0 +1,2 @@ +// Attach binaryen to our global +global.binaryen = module.exports; diff --git a/js/type.ml b/js/type.ml new file mode 100644 index 00000000..8ab59d56 --- /dev/null +++ b/js/type.ml @@ -0,0 +1,31 @@ +open Js_of_ocaml.Js +open Js_of_ocaml.Js.Unsafe + +type t = int + +let none : t = global##.binaryen##.none + +let int32 : t = global##.binaryen##.i32 + +let int64 : t = global##.binaryen##.i64 + +let float32 : t = global##.binaryen##.f32 + +let float64 : t = global##.binaryen##.f64 + +let vec128 : t = global##.binaryen##.v128 + +let funcref : t = global##.binaryen##.funcref + +let externref : t = global##.binaryen##.externref + +let nullref : t = global##.binaryen##.nullref + +let exnref : t = global##.binaryen##.exnref + +let unreachable : t = global##.binaryen##.unreachable + +let auto : t = global##.binaryen##.auto + +let create typs = + meth_call global##.binaryen "createType" [| inject (array typs) |] diff --git a/src/literal.ml b/src/literal.ml index 85fd32b7..d0eceb14 100644 --- a/src/literal.ml +++ b/src/literal.ml @@ -11,3 +11,16 @@ external float64_bits : int64 -> t = "caml_binaryen_literal_float64_bits" let float32 n = float32_bits @@ Int32.bits_of_float n external float64 : float -> t = "caml_binaryen_literal_float64" + +(* Hacks for Binaryen.js stack allocations, Don't use in binaryen.native *) +type jsoo = + | Int32 of int32 + | Int64 of int64 + | Float32Bits of int32 + | Float64Bits of int64 + | Float32 of float + | Float64 of float + +exception Invalid_usage + +let to_jsoo _ = raise Invalid_usage diff --git a/test/dune b/test/dune index 58cee3ae..7dc20dee 100644 --- a/test/dune +++ b/test/dune @@ -1,8 +1,54 @@ +; Tests for the default_implementation (mirrors 0.2.2 usage) + +(rule + (target test_default.ml) + (action + (progn + (copy %{dep:test.ml} %{target}) + (copy test.expected test_default.expected)))) + (test - (name test) + (name test_default) + (modules test_default) (modes (best exe)) (libraries binaryen) - (modules test) (action (run %{test}))) + +; Tests for binaryen.native implementation + +(rule + (target test_native.ml) + (action + (progn + (copy %{dep:test.ml} %{target}) + (copy test.expected test_native.expected)))) + +(test + (name test_native) + (modules test_native) + (modes + (best exe)) + (libraries binaryen binaryen.native) + (action + (run %{test}))) + +; Tests for binaryen.js implementation + +(rule + (target test_js.ml) + (action + (progn + (copy %{dep:test.ml} %{target})))) + +(test + (name test_js) + (modules test_js) + (modes + (byte js)) + (libraries binaryen binaryen.js) + (action + (run node %{dep:test_js.bc.js})) + (js_of_ocaml + (flags --no-sourcemap))) diff --git a/test/test_js.expected b/test/test_js.expected new file mode 100644 index 00000000..e17750b9 --- /dev/null +++ b/test/test_js.expected @@ -0,0 +1,10 @@ +(module + (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) + (func $adder (param $0 i32) (param $1 i32) (result i32) + (i32.add + (local.get $0) + (local.get $1) + ) + ) +) +OK! diff --git a/virtual/literal.mli b/virtual/literal.mli index 41e46c81..ee3976fe 100644 --- a/virtual/literal.mli +++ b/virtual/literal.mli @@ -11,3 +11,14 @@ val float64_bits : int64 -> t val float32 : float -> t val float64 : float -> t + +(* Hacks for Binaryen.js stack allocations *) +type jsoo = + | Int32 of int32 + | Int64 of int64 + | Float32Bits of int32 + | Float64Bits of int64 + | Float32 of float + | Float64 of float + +val to_jsoo : t -> jsoo From 2671a76157f3380bf71652f881cad795befe5692 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Tue, 21 Jul 2020 19:01:15 -0700 Subject: [PATCH 2/2] Cleanup test generation --- test/dune | 3 ++- test/test.expected | 1 - test/test.ml | 2 -- test/test_js.expected | 10 ---------- 4 files changed, 2 insertions(+), 14 deletions(-) delete mode 100644 test/test_js.expected diff --git a/test/dune b/test/dune index 7dc20dee..5f0dda2e 100644 --- a/test/dune +++ b/test/dune @@ -40,7 +40,8 @@ (target test_js.ml) (action (progn - (copy %{dep:test.ml} %{target})))) + (copy %{dep:test.ml} %{target}) + (copy test.expected test_js.expected)))) (test (name test_js) diff --git a/test/test.expected b/test/test.expected index 8fc9e0ba..92737a9b 100644 --- a/test/test.expected +++ b/test/test.expected @@ -1,4 +1,3 @@ -OK! (module (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (func $adder (param $0 i32) (param $1 i32) (result i32) diff --git a/test/test.ml b/test/test.ml index 23843f3e..ef87b77e 100644 --- a/test/test.ml +++ b/test/test.ml @@ -20,5 +20,3 @@ let adder = Function.add_function wasm_mod "adder" params results [||] add let _ = Module.print wasm_mod let _ = Module.dispose wasm_mod - -let _ = Printf.printf "OK!\n" diff --git a/test/test_js.expected b/test/test_js.expected deleted file mode 100644 index e17750b9..00000000 --- a/test/test_js.expected +++ /dev/null @@ -1,10 +0,0 @@ -(module - (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) - (func $adder (param $0 i32) (param $1 i32) (result i32) - (i32.add - (local.get $0) - (local.get $1) - ) - ) -) -OK!