Merge remote-tracking branch 'origin/master' into feature/polymorphic-v2

This commit is contained in:
losfair 2020-03-04 01:56:52 +08:00
commit f499dea0a7
23 changed files with 1908 additions and 2139 deletions

View File

@ -28,9 +28,16 @@ script:
before_deploy: before_deploy:
# Release # Release
- make release-singlepass - make release-singlepass
- make wapm
- make build-install-package
- mkdir -p artifacts - mkdir -p artifacts
# Make capi
- make test-capi-singlepass
- make capi-singlepass
- make build-capi-package
- cp ./wasmer-c-api.tar.gz ./artifacts/$(./scripts/capi-name.sh)
# Build WAPM
- make build-wapm
# Make package
- make build-install-package
- cp ./wasmer.tar.gz ./artifacts/$(./scripts/binary-name.sh) - cp ./wasmer.tar.gz ./artifacts/$(./scripts/binary-name.sh)
# before_deploy: # before_deploy:

View File

@ -3,6 +3,7 @@
## **[Unreleased]** ## **[Unreleased]**
- [#1217](https://github.com/wasmerio/wasmer/pull/1217) Polymorphic host functions based on dynamic trampoline generation. - [#1217](https://github.com/wasmerio/wasmer/pull/1217) Polymorphic host functions based on dynamic trampoline generation.
- [#1252](https://github.com/wasmerio/wasmer/pull/1252) Allow `/` in wasi `--mapdir` wasm path.
- [#1212](https://github.com/wasmerio/wasmer/pull/1212) Add support for GDB JIT debugging: - [#1212](https://github.com/wasmerio/wasmer/pull/1212) Add support for GDB JIT debugging:
- Add `--generate-debug-info` and `-g` flags to `wasmer run` to generate debug information during compilation. The debug info is passed via the GDB JIT interface to a debugger to allow source-level debugging of Wasm files. Currently only available on clif-backend. - Add `--generate-debug-info` and `-g` flags to `wasmer run` to generate debug information during compilation. The debug info is passed via the GDB JIT interface to a debugger to allow source-level debugging of Wasm files. Currently only available on clif-backend.
- Break public middleware APIs: there is now a `source_loc` parameter that should be passed through if applicable. - Break public middleware APIs: there is now a `source_loc` parameter that should be passed through if applicable.

179
Cargo.lock generated
View File

@ -2,9 +2,9 @@
# It is not intended for manual editing. # It is not intended for manual editing.
[[package]] [[package]]
name = "aho-corasick" name = "aho-corasick"
version = "0.7.8" version = "0.7.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "743ad5a418686aad3b87fd14c43badd828cf26e214a00f92a384291cf22e1811" checksum = "d5e63fd144e18ba274ae7095c0197a870a7b9468abc801dd62f190d80817d2ec"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
@ -143,11 +143,11 @@ checksum = "9daec6140ab4dcd38c3dd57e580b59a621172a526ac79f1527af760a55afeafd"
dependencies = [ dependencies = [
"clap", "clap",
"log", "log",
"proc-macro2 1.0.8", "proc-macro2 1.0.9",
"quote 1.0.2", "quote 1.0.2",
"serde", "serde",
"serde_json", "serde_json",
"syn 1.0.14", "syn 1.0.16",
"tempfile", "tempfile",
"toml", "toml",
] ]
@ -210,9 +210,9 @@ dependencies = [
[[package]] [[package]]
name = "colored" name = "colored"
version = "1.9.2" version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8815e2ab78f3a59928fc32e141fbeece88320a240e43f47b2fd64ea3a88a5b3d" checksum = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59"
dependencies = [ dependencies = [
"atty", "atty",
"lazy_static", "lazy_static",
@ -331,24 +331,26 @@ dependencies = [
[[package]] [[package]]
name = "crossbeam-deque" name = "crossbeam-deque"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3aa945d63861bfe624b55d153a39684da1e8c0bc8fba932f7ee3a3c16cea3ca" checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285"
dependencies = [ dependencies = [
"crossbeam-epoch", "crossbeam-epoch",
"crossbeam-utils", "crossbeam-utils",
"maybe-uninit",
] ]
[[package]] [[package]]
name = "crossbeam-epoch" name = "crossbeam-epoch"
version = "0.8.0" version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac" checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
dependencies = [ dependencies = [
"autocfg 0.1.7", "autocfg 1.0.0",
"cfg-if", "cfg-if",
"crossbeam-utils", "crossbeam-utils",
"lazy_static", "lazy_static",
"maybe-uninit",
"memoffset", "memoffset",
"scopeguard", "scopeguard",
] ]
@ -365,11 +367,11 @@ dependencies = [
[[package]] [[package]]
name = "crossbeam-utils" name = "crossbeam-utils"
version = "0.7.0" version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4" checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
dependencies = [ dependencies = [
"autocfg 0.1.7", "autocfg 1.0.0",
"cfg-if", "cfg-if",
"lazy_static", "lazy_static",
] ]
@ -399,21 +401,21 @@ dependencies = [
[[package]] [[package]]
name = "csv-core" name = "csv-core"
version = "0.1.7" version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "076bbef4255ffbc67b0358f2c92b5635928260c4cd28f3a65fa4b07c7a4f546d" checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
[[package]] [[package]]
name = "ctor" name = "ctor"
version = "0.1.12" version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd8ce37ad4184ab2ce004c33bf6379185d3b1c95801cab51026bd271bf68eedc" checksum = "47c5e5ac752e18207b12e16b10631ae5f7f68f8805f335f9b817ead83d9ffce1"
dependencies = [ dependencies = [
"quote 1.0.2", "quote 1.0.2",
"syn 1.0.14", "syn 1.0.16",
] ]
[[package]] [[package]]
@ -435,9 +437,9 @@ dependencies = [
"byteorder", "byteorder",
"lazy_static", "lazy_static",
"owning_ref", "owning_ref",
"proc-macro2 1.0.8", "proc-macro2 1.0.9",
"quote 1.0.2", "quote 1.0.2",
"syn 1.0.14", "syn 1.0.16",
] ]
[[package]] [[package]]
@ -567,9 +569,9 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a36606a68532b5640dc86bb1f33c64b45c4682aad4c50f3937b317ea387f3d6" checksum = "2a36606a68532b5640dc86bb1f33c64b45c4682aad4c50f3937b317ea387f3d6"
dependencies = [ dependencies = [
"proc-macro2 1.0.8", "proc-macro2 1.0.9",
"quote 1.0.2", "quote 1.0.2",
"syn 1.0.14", "syn 1.0.16",
] ]
[[package]] [[package]]
@ -631,9 +633,9 @@ dependencies = [
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
version = "0.1.6" version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772" checksum = "1010591b26bbfe835e9faeabeb11866061cc7dcebffd56ad7d0942d0e61aefd8"
dependencies = [ dependencies = [
"libc", "libc",
] ]
@ -695,9 +697,9 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a8e30575afe28eea36a9a39136b70b2fb6b0dd0a212a5bd1f30a498395c0274" checksum = "0a8e30575afe28eea36a9a39136b70b2fb6b0dd0a212a5bd1f30a498395c0274"
dependencies = [ dependencies = [
"proc-macro2 1.0.8", "proc-macro2 1.0.9",
"quote 1.0.2", "quote 1.0.2",
"syn 1.0.14", "syn 1.0.16",
] ]
[[package]] [[package]]
@ -733,9 +735,9 @@ checksum = "3576a87f2ba00f6f106fdfcd16db1d698d648a26ad8e0573cad8537c3c362d2a"
[[package]] [[package]]
name = "lexical-core" name = "lexical-core"
version = "0.4.6" version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304bccb228c4b020f3a4835d247df0a02a7c4686098d4167762cfbbe4c5cb14" checksum = "d7043aa5c05dd34fb73b47acb8c3708eac428de4545ea3682ed2f11293ebd890"
dependencies = [ dependencies = [
"arrayvec 0.4.12", "arrayvec 0.4.12",
"cfg-if", "cfg-if",
@ -795,9 +797,9 @@ checksum = "7e6bcd6433cff03a4bfc3d9834d504467db1f1cf6d0ea765d37d330249ed629d"
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.3.2" version = "2.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53445de381a1f436797497c61d851644d0e8e88e6140f22872ad33a704933978" checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
[[package]] [[package]]
name = "memmap" name = "memmap"
@ -859,9 +861,9 @@ checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
[[package]] [[package]]
name = "nom" name = "nom"
version = "5.1.0" version = "5.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c433f4d505fe6ce7ff78523d2fa13a0b9f2690e181fc26168bcbe5ccc5d14e07" checksum = "0b471253da97532da4b61552249c521e01e736071f71c1a4f7ebbfbf0a06aad6"
dependencies = [ dependencies = [
"lexical-core", "lexical-core",
"memchr", "memchr",
@ -937,9 +939,9 @@ dependencies = [
[[package]] [[package]]
name = "owning_ref" name = "owning_ref"
version = "0.4.0" version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" checksum = "6ff55baddef9e4ad00f88b6c743a2a8062d4c6ade126c2a528644b8e444d52ce"
dependencies = [ dependencies = [
"stable_deref_trait", "stable_deref_trait",
] ]
@ -1020,28 +1022,28 @@ checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
[[package]] [[package]]
name = "proc-macro-error" name = "proc-macro-error"
version = "0.4.8" version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "875077759af22fa20b610ad4471d8155b321c89c3f2785526c9839b099be4e0a" checksum = "e7959c6467d962050d639361f7703b2051c43036d03493c36f01d440fdd3138a"
dependencies = [ dependencies = [
"proc-macro-error-attr", "proc-macro-error-attr",
"proc-macro2 1.0.8", "proc-macro2 1.0.9",
"quote 1.0.2", "quote 1.0.2",
"rustversion", "syn 1.0.16",
"syn 1.0.14", "version_check",
] ]
[[package]] [[package]]
name = "proc-macro-error-attr" name = "proc-macro-error-attr"
version = "0.4.8" version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5717d9fa2664351a01ed73ba5ef6df09c01a521cb42cb65a061432a826f3c7a" checksum = "e4002d9f55991d5e019fb940a90e1a95eb80c24e77cb2462dd4dc869604d543a"
dependencies = [ dependencies = [
"proc-macro2 1.0.8", "proc-macro2 1.0.9",
"quote 1.0.2", "quote 1.0.2",
"rustversion", "syn 1.0.16",
"syn 1.0.14",
"syn-mid", "syn-mid",
"version_check",
] ]
[[package]] [[package]]
@ -1055,9 +1057,9 @@ dependencies = [
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.8" version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548" checksum = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435"
dependencies = [ dependencies = [
"unicode-xid 0.2.0", "unicode-xid 0.2.0",
] ]
@ -1077,7 +1079,7 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" checksum = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
dependencies = [ dependencies = [
"proc-macro2 1.0.8", "proc-macro2 1.0.9",
] ]
[[package]] [[package]]
@ -1316,9 +1318,9 @@ dependencies = [
[[package]] [[package]]
name = "regex-syntax" name = "regex-syntax"
version = "0.6.14" version = "0.6.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b28dfe3fe9badec5dbf0a79a9cccad2cfc2ab5484bdb3e44cbd1ae8b3ba2be06" checksum = "7246cd0a0a6ec2239a5405b2b16e3f404fa0dcc6d28f5f5b877bf80e33e0f294"
[[package]] [[package]]
name = "remove_dir_all" name = "remove_dir_all"
@ -1338,17 +1340,6 @@ dependencies = [
"semver", "semver",
] ]
[[package]]
name = "rustversion"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6"
dependencies = [
"proc-macro2 1.0.8",
"quote 1.0.2",
"syn 1.0.14",
]
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.2" version = "1.0.2"
@ -1366,9 +1357,9 @@ dependencies = [
[[package]] [[package]]
name = "scopeguard" name = "scopeguard"
version = "1.0.0" version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]] [[package]]
name = "scroll" name = "scroll"
@ -1406,9 +1397,9 @@ version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8584eea9b9ff42825b46faf46a8c24d2cff13ec152fa2a50df788b87c07ee28" checksum = "f8584eea9b9ff42825b46faf46a8c24d2cff13ec152fa2a50df788b87c07ee28"
dependencies = [ dependencies = [
"proc-macro2 1.0.8", "proc-macro2 1.0.9",
"quote 1.0.2", "quote 1.0.2",
"syn 1.0.14", "syn 1.0.16",
] ]
[[package]] [[package]]
@ -1484,9 +1475,9 @@ version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" checksum = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64"
dependencies = [ dependencies = [
"proc-macro2 1.0.8", "proc-macro2 1.0.9",
"quote 1.0.2", "quote 1.0.2",
"syn 1.0.14", "syn 1.0.16",
] ]
[[package]] [[package]]
@ -1544,9 +1535,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]] [[package]]
name = "structopt" name = "structopt"
version = "0.3.9" version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1bcbed7d48956fcbb5d80c6b95aedb553513de0a1b451ea92679d999c010e98" checksum = "3fe43617218c0805c6eb37160119dc3c548110a67786da7218d1c6555212f073"
dependencies = [ dependencies = [
"clap", "clap",
"lazy_static", "lazy_static",
@ -1555,15 +1546,15 @@ dependencies = [
[[package]] [[package]]
name = "structopt-derive" name = "structopt-derive"
version = "0.4.2" version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "095064aa1f5b94d14e635d0a5684cf140c43ae40a0fd990708d38f5d669e5f64" checksum = "c6e79c80e0f4efd86ca960218d4e056249be189ff1c42824dcd9a7f51a56f0bd"
dependencies = [ dependencies = [
"heck", "heck",
"proc-macro-error", "proc-macro-error",
"proc-macro2 1.0.8", "proc-macro2 1.0.9",
"quote 1.0.2", "quote 1.0.2",
"syn 1.0.14", "syn 1.0.16",
] ]
[[package]] [[package]]
@ -1585,11 +1576,11 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.14" version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5" checksum = "123bd9499cfb380418d509322d7a6d52e5315f064fe4b3ad18a53d6b92c07859"
dependencies = [ dependencies = [
"proc-macro2 1.0.8", "proc-macro2 1.0.9",
"quote 1.0.2", "quote 1.0.2",
"unicode-xid 0.2.0", "unicode-xid 0.2.0",
] ]
@ -1600,9 +1591,9 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a"
dependencies = [ dependencies = [
"proc-macro2 1.0.8", "proc-macro2 1.0.9",
"quote 1.0.2", "quote 1.0.2",
"syn 1.0.14", "syn 1.0.16",
] ]
[[package]] [[package]]
@ -1642,22 +1633,22 @@ dependencies = [
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.10" version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "205684fd018ca14432b12cce6ea3d46763311a571c3d294e71ba3f01adcf1aad" checksum = "ee14bf8e6767ab4c687c9e8bc003879e042a96fd67a3ba5934eadb6536bef4db"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "1.0.10" version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57e4d2e50ca050ed44fb58309bdce3efa79948f84f9993ad1978de5eebdce5a7" checksum = "a7b51e1fbc44b5a0840be594fbc0f960be09050f2617e61e6aa43bef97cd3ef4"
dependencies = [ dependencies = [
"proc-macro2 1.0.8", "proc-macro2 1.0.9",
"quote 1.0.2", "quote 1.0.2",
"syn 1.0.14", "syn 1.0.16",
] ]
[[package]] [[package]]
@ -1724,9 +1715,9 @@ version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b63fd4799e4d0ec5cf0b055ebb8e2c3a657bbf76a84f6edc77ca60780e000204" checksum = "b63fd4799e4d0ec5cf0b055ebb8e2c3a657bbf76a84f6edc77ca60780e000204"
dependencies = [ dependencies = [
"proc-macro2 1.0.8", "proc-macro2 1.0.9",
"quote 1.0.2", "quote 1.0.2",
"syn 1.0.14", "syn 1.0.16",
] ]
[[package]] [[package]]
@ -1761,9 +1752,9 @@ checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.1.5" version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce"
[[package]] [[package]]
name = "void" name = "void"
@ -1879,7 +1870,7 @@ dependencies = [
"wasmer-clif-fork-wasm", "wasmer-clif-fork-wasm",
"wasmer-runtime-core", "wasmer-runtime-core",
"wasmer-win-exception-handler", "wasmer-win-exception-handler",
"wasmparser 0.51.3", "wasmparser 0.51.4",
"winapi", "winapi",
] ]
@ -1906,7 +1897,7 @@ dependencies = [
"log", "log",
"thiserror", "thiserror",
"wasmer-clif-fork-frontend", "wasmer-clif-fork-frontend",
"wasmparser 0.51.3", "wasmparser 0.51.4",
] ]
[[package]] [[package]]
@ -1976,7 +1967,7 @@ dependencies = [
"smallvec 0.6.13", "smallvec 0.6.13",
"wabt", "wabt",
"wasmer-runtime-core", "wasmer-runtime-core",
"wasmparser 0.51.3", "wasmparser 0.51.4",
"winapi", "winapi",
] ]
@ -2063,7 +2054,7 @@ dependencies = [
"smallvec 0.6.13", "smallvec 0.6.13",
"target-lexicon 0.9.0", "target-lexicon 0.9.0",
"wasm-debug", "wasm-debug",
"wasmparser 0.51.3", "wasmparser 0.51.4",
"winapi", "winapi",
] ]
@ -2168,9 +2159,9 @@ checksum = "c702914acda5feeeffbc29e4d953e5b9ce79d8b98da4dbf18a77086e116c5470"
[[package]] [[package]]
name = "wasmparser" name = "wasmparser"
version = "0.51.3" version = "0.51.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "447465bb5cf5ecd5918919ef3a0002e0839c87fb2a9483d4816d9b2cc36221fa" checksum = "aeb1956b19469d1c5e63e459d29e7b5aa0f558d9f16fcef09736f8a265e6c10a"
[[package]] [[package]]
name = "wast" name = "wast"

View File

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2019 Wasmer, Inc. and its affiliates. Copyright (c) 2019-present Wasmer, Inc. and its affiliates.
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -315,6 +315,11 @@ endif
cp lib/runtime-c-api/doc/index.md ./capi/README.md cp lib/runtime-c-api/doc/index.md ./capi/README.md
tar -C ./capi -zcvf wasmer-c-api.tar.gz lib include README.md LICENSE tar -C ./capi -zcvf wasmer-c-api.tar.gz lib include README.md LICENSE
WAPM_VERSION = 0.4.3
build-wapm:
git clone --branch $(WAPM_VERSION) https://github.com/wasmerio/wapm-cli.git
cargo build --release --manifest-path wapm-cli/Cargo.toml --features "telemetry update-notifications"
# For installing the contents locally # For installing the contents locally
do-install: do-install:
tar -C ~/.wasmer -zxvf wasmer.tar.gz tar -C ~/.wasmer -zxvf wasmer.tar.gz

View File

@ -1,35 +1,49 @@
<p align="center"> <div align="center">
<a href="https://wasmer.io" target="_blank" rel="noopener noreferrer"> <a href="https://wasmer.io" target="_blank" rel="noopener noreferrer">
<img width="300" src="https://raw.githubusercontent.com/wasmerio/wasmer/master/assets/logo.png" alt="Wasmer logo"> <img width="300" src="https://raw.githubusercontent.com/wasmerio/wasmer/master/assets/logo.png" alt="Wasmer logo">
</a> </a>
</p>
<p align="center"> <p>
<a href="https://dev.azure.com/wasmerio/wasmer/_build/latest?definitionId=3&branchName=master"> <a href="https://dev.azure.com/wasmerio/wasmer/_build/latest?definitionId=3&branchName=master">
<img src="https://img.shields.io/azure-devops/build/wasmerio/wasmer/3.svg?style=flat-square" alt="Build Status"> <img src="https://img.shields.io/azure-devops/build/wasmerio/wasmer/3.svg?style=flat-square" alt="Build Status">
</a> </a>
<a href="https://slack.wasmer.io">
<img src="https://img.shields.io/static/v1?label=Slack&message=join%20chat&color=brighgreen&style=flat-square" alt="Slack channel">
</a>
<a href="https://github.com/wasmerio/wasmer/blob/master/LICENSE"> <a href="https://github.com/wasmerio/wasmer/blob/master/LICENSE">
<img src="https://img.shields.io/github/license/wasmerio/wasmer.svg?style=flat-square" alt="License"> <img src="https://img.shields.io/github/license/wasmerio/wasmer.svg?style=flat-square" alt="License">
</a> </a>
<a href="https://spectrum.chat/wasmer">
<img src="https://withspectrum.github.io/badge/badge.svg" alt="Join the Wasmer Community">
</a>
</p> </p>
[Website](https://wasmer.io) • [Docs](https://docs.wasmer.io/) • [Examples](https://github.com/wasmerio/wasmer/tree/master/examples) • [Blog](https://medium.com/wasmer) • [Slack](https://slack.wasmer.io/) • [Twitter](https://twitter.com/wasmerio) <h3>
<a href="https://wasmer.io/">Website</a>
<span></span>
<a href="https://docs.wasmer.io">Docs</a>
<span></span>
<a href="https://medium.com/wasmer/">Blog</a>
<span></span>
<a href="https://slack.wasmer.io/">Slack</a>
<span></span>
<a href="https://twitter.com/wasmerio">Twitter</a>
</h3>
[Wasmer](https://wasmer.io/) is a standalone WebAssembly runtime for running WebAssembly [outside of the browser](https://webassembly.org/docs/non-web/): </div>
* *Universal*: Wasmer is available in **Linux, macOS and Windows** (for both Desktop and [ARM](https://medium.com/wasmer/running-webassembly-on-arm-7d365ed0e50c))
* *Pluggable*: Wasmer can be used from almost **any programming language** <br />
* *Safe*: supporting [WASI](https://github.com/WebAssembly/WASI) and [Emscripten](https://emscripten.org/)
[Wasmer](https://wasmer.io/) is a standalone [WebAssembly](https://webassembly.org/) runtime:
* **Universal**: Wasmer is available in *Linux, macOS and Windows* (for both Desktop and [ARM](https://medium.com/wasmer/running-webassembly-on-arm-7d365ed0e50c))
* **Fast**: Wasmer aims to run WebAssembly at near-native speed
* **Pluggable**: Wasmer can be used from almost **any programming language**
* **Safe**: supporting [WASI](https://github.com/WebAssembly/WASI) and [Emscripten](https://emscripten.org/)
It is used to run software fast, universally and safely: standalone applications and universal libraries. It is used to run software fast, universally and safely: standalone applications and universal libraries.
## Contents ## Contents
- [Quickstart](#quickstart) - [Quickstart](#quickstart)
- [Language Integrations](#examples) - [Language Integrations](#language-integrations)
- [Contribute](#contribute) - [Contribute](#contribute)
- [Community](#community) - [Community](#community)

View File

@ -143,13 +143,10 @@ jobs:
displayName: Build (Windows) displayName: Build (Windows)
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT')) condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
- bash: | - bash: |
git clone --branch $WAPM_VERSION https://github.com/wasmerio/wapm-cli.git make build-wapm
cargo build --release --manifest-path wapm-cli/Cargo.toml --features "telemetry update-notifications"
displayName: Build WAPM displayName: Build WAPM
condition: | condition: |
startsWith(variables['Build.SourceBranch'], 'refs/tags') startsWith(variables['Build.SourceBranch'], 'refs/tags')
env:
WAPM_VERSION: 0.4.3
- bash: | - bash: |
make build-install-package make build-install-package
cp ./wasmer.tar.gz ./artifacts/$(./scripts/binary-name.sh) cp ./wasmer.tar.gz ./artifacts/$(./scripts/binary-name.sh)

View File

@ -7,26 +7,29 @@ use std::str;
/// Represents the types supported by WIT. /// Represents the types supported by WIT.
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
pub enum InterfaceType { pub enum InterfaceType {
/// An integer. /// A 8-bits signed integer.
Int, S8,
/// A float. /// A 16-bits signed integer.
Float, S16,
/// Opaque reference. /// A 32-bits signed integer.
Any, S32,
/// A string. /// A 64-bits signed integer.
String, S64,
/// A sequence. /// A 8-bits unsigned integer.
Seq, U8,
/// A 32-bits integer. /// A 16-bits unsigned integer.
I32, U16,
/// A 64-bits integer. /// A 32-bits unsigned integer.
I64, U32,
/// A 64-bits unsigned integer.
U64,
/// A 32-bits float. /// A 32-bits float.
F32, F32,
@ -34,37 +37,30 @@ pub enum InterfaceType {
/// A 64-bits float. /// A 64-bits float.
F64, F64,
/// A string.
String,
/// An `any` reference. /// An `any` reference.
AnyRef, Anyref,
/// A 32-bits integer (as defined in WebAssembly core).
I32,
/// A 64-bits integer (as defiend in WebAssembly core).
I64,
} }
/// Represents the kind of adapter. /// Represents a type signature.
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
pub(crate) enum AdapterKind { pub struct Type {
/// An adapter defined for an imported function of a WebAssembly instance. /// Types for the parameters.
Import, pub inputs: Vec<InterfaceType>,
/// An adapter defined for an exported function of a WebAssembly instance. /// Types for the results.
Export, pub outputs: Vec<InterfaceType>,
/// A helper function.
HelperFunction,
} }
/// Represents an exported function signature. /// Represents an imported function.
#[derive(PartialEq, Debug)]
pub struct Export<'input> {
/// The function name.
pub name: &'input str,
/// The function input types.
pub input_types: Vec<InterfaceType>,
/// The function output types.
pub output_types: Vec<InterfaceType>,
}
/// Represents an imported function signature.
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
pub struct Import<'input> { pub struct Import<'input> {
/// The function namespace. /// The function namespace.
@ -73,130 +69,65 @@ pub struct Import<'input> {
/// The function name. /// The function name.
pub name: &'input str, pub name: &'input str,
/// The function input types. /// The type signature.
pub input_types: Vec<InterfaceType>, pub signature_type: u32,
/// The function output types.
pub output_types: Vec<InterfaceType>,
} }
/// Represents a structural type. /// Represents an exported function signature.
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
pub struct Type<'input> { pub struct Export<'input> {
/// The type name. /// The export name.
pub name: &'input str, pub name: &'input str,
/// The field names. /// The WIT function type being exported.
field_names: Vec<&'input str>, pub function_type: u32,
/// The field types.
field_types: Vec<InterfaceType>,
}
impl<'input> Type<'input> {
/// Creates a new `Type`.
///
/// The constructor panics if there is the length of `names` is
/// different than the length of `types`.
pub fn new(type_name: &'input str, names: Vec<&'input str>, types: Vec<InterfaceType>) -> Self {
assert_eq!(
names.len(),
types.len(),
"There must be the same number of field names than field types."
);
Self {
name: type_name,
field_names: names,
field_types: types,
}
}
/// Adds a new field to the type.
pub fn add_field(&mut self, name: &'input str, ty: InterfaceType) {
self.field_names.push(name);
self.field_types.push(ty);
}
/// Returns the field names.
pub fn field_names(&self) -> &Vec<&'input str> {
&self.field_names
}
/// Returns the field types.
pub fn field_types(&self) -> &Vec<InterfaceType> {
&self.field_types
}
} }
/// Represents an adapter. /// Represents an adapter.
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
pub enum Adapter<'input> { pub struct Adapter<'input> {
/// An adapter for an imported function. /// The adapter function type.
Import { pub function_type: u32,
/// The function namespace.
namespace: &'input str,
/// The function name. /// The instructions.
name: &'input str, pub instructions: Vec<Instruction<'input>>,
/// The function input types.
input_types: Vec<InterfaceType>,
/// The function output types.
output_types: Vec<InterfaceType>,
/// The instructions of the adapter.
instructions: Vec<Instruction<'input>>,
},
/// An adapter for an exported function.
Export {
/// The function name.
name: &'input str,
/// The function input types.
input_types: Vec<InterfaceType>,
/// The function output types.
output_types: Vec<InterfaceType>,
/// The instructions of the adapter.
instructions: Vec<Instruction<'input>>,
},
/// An adapter for a helper function.
HelperFunction {
/// The helper name.
name: &'input str,
/// The helper input types.
input_types: Vec<InterfaceType>,
/// The helper output types.
output_types: Vec<InterfaceType>,
/// The instructions of the adapter.
instructions: Vec<Instruction<'input>>,
},
} }
/// Represented a forwarded export. /// Represents an implementation.
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
pub struct Forward<'input> { pub struct Implementation {
/// The forwarded export name. /// The core function type.
pub name: &'input str, pub core_function_type: u32,
/// The adapter function type.
pub adapter_function_type: u32,
}
/// Represents the kind of interface.
#[derive(PartialEq, Debug)]
pub(crate) enum InterfaceKind {
/// A type.
Type,
/// An imported function.
Import,
/// An adapter.
Adapter,
/// An exported function.
Export,
/// An implementation.
Implementation,
} }
/// Represents a set of interfaces, i.e. it entirely describes a WIT /// Represents a set of interfaces, i.e. it entirely describes a WIT
/// definition. /// definition.
#[derive(PartialEq, Default, Debug)] #[derive(PartialEq, Default, Debug)]
pub struct Interfaces<'input> { pub struct Interfaces<'input> {
/// All the exported functions.
pub exports: Vec<Export<'input>>,
/// All the types. /// All the types.
pub types: Vec<Type<'input>>, pub types: Vec<Type>,
/// All the imported functions. /// All the imported functions.
pub imports: Vec<Import<'input>>, pub imports: Vec<Import<'input>>,
@ -204,6 +135,9 @@ pub struct Interfaces<'input> {
/// All the adapters. /// All the adapters.
pub adapters: Vec<Adapter<'input>>, pub adapters: Vec<Adapter<'input>>,
/// All the forwarded functions. /// All the exported functions.
pub forwards: Vec<Forward<'input>>, pub exports: Vec<Export<'input>>,
/// All the implementations.
pub implementations: Vec<Implementation>,
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,6 @@
//! Writes the AST into bytes representing WIT with its binary format. //! Writes the AST into bytes representing WIT with its binary format.
use crate::{ use crate::{ast::*, interpreter::Instruction};
ast::{Adapter, AdapterKind, Export, Forward, Import, InterfaceType, Interfaces, Type},
interpreter::Instruction,
};
use std::io::{self, Write}; use std::io::{self, Write};
/// A trait for converting a value to bytes. /// A trait for converting a value to bytes.
@ -97,61 +94,50 @@ where
{ {
fn to_bytes(&self, writer: &mut W) -> io::Result<()> { fn to_bytes(&self, writer: &mut W) -> io::Result<()> {
match self { match self {
InterfaceType::Int => 0x7fff_u64.to_bytes(writer), InterfaceType::S8 => 0x00_u8.to_bytes(writer),
InterfaceType::Float => 0x7ffe_u64.to_bytes(writer), InterfaceType::S16 => 0x01_u8.to_bytes(writer),
InterfaceType::Any => 0x7ffd_u64.to_bytes(writer), InterfaceType::S32 => 0x02_u8.to_bytes(writer),
InterfaceType::String => 0x7ffc_u64.to_bytes(writer), InterfaceType::S64 => 0x03_u8.to_bytes(writer),
InterfaceType::Seq => 0x7ffb_u64.to_bytes(writer), InterfaceType::U8 => 0x04_u8.to_bytes(writer),
InterfaceType::I32 => 0x7f_u64.to_bytes(writer), InterfaceType::U16 => 0x05_u8.to_bytes(writer),
InterfaceType::I64 => 0x7e_u64.to_bytes(writer), InterfaceType::U32 => 0x06_u8.to_bytes(writer),
InterfaceType::F32 => 0x7d_u64.to_bytes(writer), InterfaceType::U64 => 0x07_u8.to_bytes(writer),
InterfaceType::F64 => 0x7c_u64.to_bytes(writer), InterfaceType::F32 => 0x08_u8.to_bytes(writer),
InterfaceType::AnyRef => 0x6f_u64.to_bytes(writer), InterfaceType::F64 => 0x09_u8.to_bytes(writer),
InterfaceType::String => 0x0a_u8.to_bytes(writer),
InterfaceType::Anyref => 0x0b_u8.to_bytes(writer),
InterfaceType::I32 => 0x0c_u8.to_bytes(writer),
InterfaceType::I64 => 0x0d_u8.to_bytes(writer),
} }
} }
} }
/// Encode an `AdapterKind` into bytes. /// Encode an `InterfaceKind` into bytes.
impl<W> ToBytes<W> for AdapterKind impl<W> ToBytes<W> for InterfaceKind
where where
W: Write, W: Write,
{ {
fn to_bytes(&self, writer: &mut W) -> io::Result<()> { fn to_bytes(&self, writer: &mut W) -> io::Result<()> {
match self { match self {
AdapterKind::Import => 0x00_u8.to_bytes(writer), Self::Type => 0x00_u8.to_bytes(writer),
AdapterKind::Export => 0x01_u8.to_bytes(writer), Self::Import => 0x01_u8.to_bytes(writer),
AdapterKind::HelperFunction => 0x02_u8.to_bytes(writer), Self::Adapter => 0x02_u8.to_bytes(writer),
Self::Export => 0x03_u8.to_bytes(writer),
Self::Implementation => 0x04_u8.to_bytes(writer),
} }
} }
} }
/// Encode an `Export` into bytes.
///
/// Decoder is in `decoders::binary::exports`.
impl<W> ToBytes<W> for Export<'_>
where
W: Write,
{
fn to_bytes(&self, writer: &mut W) -> io::Result<()> {
self.name.to_bytes(writer)?;
self.input_types.to_bytes(writer)?;
self.output_types.to_bytes(writer)?;
Ok(())
}
}
/// Encode a `Type` into bytes. /// Encode a `Type` into bytes.
/// ///
/// Decoder is in `decoders::binary::types`. /// Decoder is in `decoders::binary::types`.
impl<W> ToBytes<W> for Type<'_> impl<W> ToBytes<W> for Type
where where
W: Write, W: Write,
{ {
fn to_bytes(&self, writer: &mut W) -> io::Result<()> { fn to_bytes(&self, writer: &mut W) -> io::Result<()> {
self.name.to_bytes(writer)?; self.inputs.to_bytes(writer)?;
self.field_names().to_bytes(writer)?; self.outputs.to_bytes(writer)?;
self.field_types().to_bytes(writer)?;
Ok(()) Ok(())
} }
@ -167,8 +153,7 @@ where
fn to_bytes(&self, writer: &mut W) -> io::Result<()> { fn to_bytes(&self, writer: &mut W) -> io::Result<()> {
self.namespace.to_bytes(writer)?; self.namespace.to_bytes(writer)?;
self.name.to_bytes(writer)?; self.name.to_bytes(writer)?;
self.input_types.to_bytes(writer)?; (self.signature_type as u64).to_bytes(writer)?;
self.output_types.to_bytes(writer)?;
Ok(()) Ok(())
} }
@ -176,68 +161,46 @@ where
/// Encode an `Adapter` into bytes. /// Encode an `Adapter` into bytes.
/// ///
/// Decoder is in `decoders::binary::imports`. /// Decoder is in `decoders::binary::adapters`.
impl<W> ToBytes<W> for Adapter<'_> impl<W> ToBytes<W> for Adapter<'_>
where where
W: Write, W: Write,
{ {
fn to_bytes(&self, writer: &mut W) -> io::Result<()> { fn to_bytes(&self, writer: &mut W) -> io::Result<()> {
match self { (self.function_type as u64).to_bytes(writer)?;
Adapter::Import { self.instructions.to_bytes(writer)?;
namespace,
name,
input_types,
output_types,
instructions,
} => {
AdapterKind::Import.to_bytes(writer)?;
namespace.to_bytes(writer)?;
name.to_bytes(writer)?;
input_types.to_bytes(writer)?;
output_types.to_bytes(writer)?;
instructions.to_bytes(writer)?;
}
Adapter::Export {
name,
input_types,
output_types,
instructions,
} => {
AdapterKind::Export.to_bytes(writer)?;
name.to_bytes(writer)?;
input_types.to_bytes(writer)?;
output_types.to_bytes(writer)?;
instructions.to_bytes(writer)?;
}
Adapter::HelperFunction {
name,
input_types,
output_types,
instructions,
} => {
AdapterKind::HelperFunction.to_bytes(writer)?;
name.to_bytes(writer)?;
input_types.to_bytes(writer)?;
output_types.to_bytes(writer)?;
instructions.to_bytes(writer)?;
}
}
Ok(()) Ok(())
} }
} }
/// Encode an `Forward` into bytes. /// Encode an `Export` into bytes.
/// ///
/// Decoder is `decoders::binary::forwards`. /// Decoder is in `decoders::binary::exports`.
impl<W> ToBytes<W> for Forward<'_> impl<W> ToBytes<W> for Export<'_>
where where
W: Write, W: Write,
{ {
fn to_bytes(&self, writer: &mut W) -> io::Result<()> { fn to_bytes(&self, writer: &mut W) -> io::Result<()> {
self.name.to_bytes(writer) self.name.to_bytes(writer)?;
(self.function_type as u64).to_bytes(writer)?;
Ok(())
}
}
/// Encode an `Implementation` into bytes.
///
/// Decoder is in `decoders::binary::implementations`.
impl<W> ToBytes<W> for Implementation
where
W: Write,
{
fn to_bytes(&self, writer: &mut W) -> io::Result<()> {
(self.core_function_type as u64).to_bytes(writer)?;
(self.adapter_function_type as u64).to_bytes(writer)?;
Ok(())
} }
} }
@ -249,11 +212,30 @@ where
W: Write, W: Write,
{ {
fn to_bytes(&self, writer: &mut W) -> io::Result<()> { fn to_bytes(&self, writer: &mut W) -> io::Result<()> {
self.exports.to_bytes(writer)?; if !self.types.is_empty() {
InterfaceKind::Type.to_bytes(writer)?;
self.types.to_bytes(writer)?; self.types.to_bytes(writer)?;
}
if !self.imports.is_empty() {
InterfaceKind::Import.to_bytes(writer)?;
self.imports.to_bytes(writer)?; self.imports.to_bytes(writer)?;
}
if !self.adapters.is_empty() {
InterfaceKind::Adapter.to_bytes(writer)?;
self.adapters.to_bytes(writer)?; self.adapters.to_bytes(writer)?;
self.forwards.to_bytes(writer)?; }
if !self.exports.is_empty() {
InterfaceKind::Export.to_bytes(writer)?;
self.exports.to_bytes(writer)?;
}
if !self.implementations.is_empty() {
InterfaceKind::Implementation.to_bytes(writer)?;
self.implementations.to_bytes(writer)?;
}
Ok(()) Ok(())
} }
@ -270,7 +252,7 @@ where
match self { match self {
Instruction::ArgumentGet { index } => { Instruction::ArgumentGet { index } => {
0x00_u8.to_bytes(writer)?; 0x00_u8.to_bytes(writer)?;
index.to_bytes(writer)?; (*index as u64).to_bytes(writer)?;
} }
Instruction::Call { function_index } => { Instruction::Call { function_index } => {
@ -290,76 +272,45 @@ where
allocator_name.to_bytes(writer)?; allocator_name.to_bytes(writer)?;
} }
Instruction::AsWasm(interface_type) => { Instruction::I32ToS8 => 0x07_u8.to_bytes(writer)?,
0x05_u8.to_bytes(writer)?; Instruction::I32ToS8X => 0x08_u8.to_bytes(writer)?,
interface_type.to_bytes(writer)?; Instruction::I32ToU8 => 0x09_u8.to_bytes(writer)?,
} Instruction::I32ToS16 => 0x0a_u8.to_bytes(writer)?,
Instruction::I32ToS16X => 0x0b_u8.to_bytes(writer)?,
Instruction::AsInterface(interface_type) => { Instruction::I32ToU16 => 0x0c_u8.to_bytes(writer)?,
0x06_u8.to_bytes(writer)?; Instruction::I32ToS32 => 0x0d_u8.to_bytes(writer)?,
interface_type.to_bytes(writer)?; Instruction::I32ToU32 => 0x0e_u8.to_bytes(writer)?,
} Instruction::I32ToS64 => 0x0f_u8.to_bytes(writer)?,
Instruction::I32ToU64 => 0x10_u8.to_bytes(writer)?,
Instruction::TableRefAdd => 0x07_u8.to_bytes(writer)?, Instruction::I64ToS8 => 0x11_u8.to_bytes(writer)?,
Instruction::I64ToS8X => 0x12_u8.to_bytes(writer)?,
Instruction::TableRefGet => 0x08_u8.to_bytes(writer)?, Instruction::I64ToU8 => 0x13_u8.to_bytes(writer)?,
Instruction::I64ToS16 => 0x14_u8.to_bytes(writer)?,
Instruction::CallMethod(function_index) => { Instruction::I64ToS16X => 0x15_u8.to_bytes(writer)?,
0x09_u8.to_bytes(writer)?; Instruction::I64ToU16 => 0x16_u8.to_bytes(writer)?,
function_index.to_bytes(writer)?; Instruction::I64ToS32 => 0x17_u8.to_bytes(writer)?,
} Instruction::I64ToS32X => 0x18_u8.to_bytes(writer)?,
Instruction::I64ToU32 => 0x19_u8.to_bytes(writer)?,
Instruction::MakeRecord(interface_type) => { Instruction::I64ToS64 => 0x1a_u8.to_bytes(writer)?,
0x0a_u8.to_bytes(writer)?; Instruction::I64ToU64 => 0x1b_u8.to_bytes(writer)?,
interface_type.to_bytes(writer)?; Instruction::S8ToI32 => 0x1c_u8.to_bytes(writer)?,
} Instruction::U8ToI32 => 0x1d_u8.to_bytes(writer)?,
Instruction::S16ToI32 => 0x1e_u8.to_bytes(writer)?,
Instruction::GetField(interface_type, field_index) => { Instruction::U16ToI32 => 0x1f_u8.to_bytes(writer)?,
0x0c_u8.to_bytes(writer)?; Instruction::S32ToI32 => 0x20_u8.to_bytes(writer)?,
interface_type.to_bytes(writer)?; Instruction::U32ToI32 => 0x21_u8.to_bytes(writer)?,
field_index.to_bytes(writer)?; Instruction::S64ToI32 => 0x22_u8.to_bytes(writer)?,
} Instruction::S64ToI32X => 0x23_u8.to_bytes(writer)?,
Instruction::U64ToI32 => 0x24_u8.to_bytes(writer)?,
Instruction::Const(interface_type, index) => { Instruction::U64ToI32X => 0x25_u8.to_bytes(writer)?,
0x0d_u8.to_bytes(writer)?; Instruction::S8ToI64 => 0x26_u8.to_bytes(writer)?,
interface_type.to_bytes(writer)?; Instruction::U8ToI64 => 0x27_u8.to_bytes(writer)?,
index.to_bytes(writer)?; Instruction::S16ToI64 => 0x28_u8.to_bytes(writer)?,
} Instruction::U16ToI64 => 0x29_u8.to_bytes(writer)?,
Instruction::S32ToI64 => 0x2a_u8.to_bytes(writer)?,
Instruction::FoldSeq(index) => { Instruction::U32ToI64 => 0x2b_u8.to_bytes(writer)?,
0x0e_u8.to_bytes(writer)?; Instruction::S64ToI64 => 0x2c_u8.to_bytes(writer)?,
index.to_bytes(writer)?; Instruction::U64ToI64 => 0x2d_u8.to_bytes(writer)?,
}
Instruction::Add(interface_type) => {
0x0f_u8.to_bytes(writer)?;
interface_type.to_bytes(writer)?;
}
Instruction::MemToSeq(interface_type, string) => {
0x10_u8.to_bytes(writer)?;
interface_type.to_bytes(writer)?;
string.to_bytes(writer)?;
}
Instruction::Load(interface_type, string) => {
0x11_u8.to_bytes(writer)?;
interface_type.to_bytes(writer)?;
string.to_bytes(writer)?;
}
Instruction::SeqNew(interface_type) => {
0x12_u8.to_bytes(writer)?;
interface_type.to_bytes(writer)?;
}
Instruction::ListPush => 0x13_u8.to_bytes(writer)?,
Instruction::RepeatUntil(index1, index2) => {
0x14_u8.to_bytes(writer)?;
index1.to_bytes(writer)?;
index2.to_bytes(writer)?;
}
} }
Ok(()) Ok(())
@ -444,23 +395,29 @@ mod tests {
#[test] #[test]
fn test_interface_type() { fn test_interface_type() {
assert_to_bytes!(InterfaceType::Int, &[0xff, 0xff, 0x01]); assert_to_bytes!(InterfaceType::S8, &[0x00]);
assert_to_bytes!(InterfaceType::Float, &[0xfe, 0xff, 0x01]); assert_to_bytes!(InterfaceType::S16, &[0x01]);
assert_to_bytes!(InterfaceType::Any, &[0xfd, 0xff, 0x01]); assert_to_bytes!(InterfaceType::S32, &[0x02]);
assert_to_bytes!(InterfaceType::String, &[0xfc, 0xff, 0x01]); assert_to_bytes!(InterfaceType::S64, &[0x03]);
assert_to_bytes!(InterfaceType::Seq, &[0xfb, 0xff, 0x01]); assert_to_bytes!(InterfaceType::U8, &[0x04]);
assert_to_bytes!(InterfaceType::I32, &[0x7f]); assert_to_bytes!(InterfaceType::U16, &[0x05]);
assert_to_bytes!(InterfaceType::I64, &[0x7e]); assert_to_bytes!(InterfaceType::U32, &[0x06]);
assert_to_bytes!(InterfaceType::F32, &[0x7d]); assert_to_bytes!(InterfaceType::U64, &[0x07]);
assert_to_bytes!(InterfaceType::F64, &[0x7c]); assert_to_bytes!(InterfaceType::F32, &[0x08]);
assert_to_bytes!(InterfaceType::AnyRef, &[0x6f]); assert_to_bytes!(InterfaceType::F64, &[0x09]);
assert_to_bytes!(InterfaceType::String, &[0x0a]);
assert_to_bytes!(InterfaceType::Anyref, &[0x0b]);
assert_to_bytes!(InterfaceType::I32, &[0x0c]);
assert_to_bytes!(InterfaceType::I64, &[0x0d]);
} }
#[test] #[test]
fn test_adapter_kind() { fn test_interface_kind() {
assert_to_bytes!(AdapterKind::Import, &[0x00]); assert_to_bytes!(InterfaceKind::Type, &[0x00]);
assert_to_bytes!(AdapterKind::Export, &[0x01]); assert_to_bytes!(InterfaceKind::Import, &[0x01]);
assert_to_bytes!(AdapterKind::HelperFunction, &[0x02]); assert_to_bytes!(InterfaceKind::Adapter, &[0x02]);
assert_to_bytes!(InterfaceKind::Export, &[0x03]);
assert_to_bytes!(InterfaceKind::Implementation, &[0x04]);
} }
#[test] #[test]
@ -468,19 +425,14 @@ mod tests {
assert_to_bytes!( assert_to_bytes!(
Export { Export {
name: "abc", name: "abc",
input_types: vec![InterfaceType::I32, InterfaceType::I64], function_type: 0,
output_types: vec![InterfaceType::I32]
}, },
&[ &[
0x03, // string of length 3 0x03, // string of length 3
0x61, // "a" 0x61, // "a"
0x62, // "b" 0x62, // "b"
0x63, // "c" 0x63, // "c"
0x02, // list of 2 items 0x00, // function type
0x7f, // I32
0x7e, // I64
0x01, // list of 1 items
0x7f, // I32
] ]
); );
} }
@ -488,22 +440,16 @@ mod tests {
#[test] #[test]
fn test_type() { fn test_type() {
assert_to_bytes!( assert_to_bytes!(
Type::new( Type {
"a", inputs: vec![InterfaceType::I32, InterfaceType::I64],
vec!["b", "c"], outputs: vec![InterfaceType::S32],
vec![InterfaceType::I32, InterfaceType::I64], },
),
&[ &[
0x01, // string of length 1
0x61, // "a"
0x02, // list of 2 items 0x02, // list of 2 items
0x01, // string of length 1 0x0c, // I32
0x62, // "b" 0x0d, // I64
0x01, // string of length 1 0x01, // list of 1 items
0x63, // "c" 0x02, // I64
0x02, // list of 2 items
0x7f, // I32
0x7e, // I64
] ]
); );
} }
@ -514,182 +460,91 @@ mod tests {
Import { Import {
namespace: "a", namespace: "a",
name: "b", name: "b",
input_types: vec![InterfaceType::I32, InterfaceType::I64], signature_type: 0,
output_types: vec![InterfaceType::I32],
}, },
&[ &[
0x01, // string of length 1 0x01, // string of length 1
0x61, // "a" 0x61, // "a"
0x01, // string of length 1 0x01, // string of length 1
0x62, // "b" 0x62, // "b"
0x02, // list of 2 items 0x00, // signature typr
0x7f, // I32
0x7e, // I64
0x01, // list of 1 items
0x7f, // I32
] ]
); );
} }
#[test] #[test]
fn test_adapter_import() { fn test_adapter() {
assert_to_bytes!( assert_to_bytes!(
Adapter::Import { Adapter {
namespace: "a", function_type: 0,
name: "b",
input_types: vec![InterfaceType::I32, InterfaceType::I64],
output_types: vec![InterfaceType::I32],
instructions: vec![Instruction::ArgumentGet { index: 1 }], instructions: vec![Instruction::ArgumentGet { index: 1 }],
}, },
&[ &[
0x00, // AdapterKind::Import 0x00, // function type
0x01, // string of length 1
0x61, // "a"
0x01, // string of length 1
0x62, // "b"
0x02, // list of 2 items
0x7f, // I32
0x7e, // I64
0x01, // list of 1 items
0x7f, // I32
0x01, // list of 1 item 0x01, // list of 1 item
0x00, 0x01, // ArgumentGet { index: 1 } 0x00, 0x01, // ArgumentGet { index: 1 }
] ]
); );
} }
#[test]
fn test_adapter_export() {
assert_to_bytes!(
Adapter::Export {
name: "a",
input_types: vec![InterfaceType::I32, InterfaceType::I64],
output_types: vec![InterfaceType::I32],
instructions: vec![Instruction::ArgumentGet { index: 1 }],
},
&[
0x01, // AdapterKind::Export
0x01, // string of length 1
0x61, // "a"
0x02, // list of 2 items
0x7f, // I32
0x7e, // I64
0x01, // list of 1 items
0x7f, // I32
0x01, // list of 1 item
0x00, 0x01, // ArgumentGet { index: 1 }
]
);
}
#[test]
fn test_adapter_helper_function() {
assert_to_bytes!(
Adapter::HelperFunction {
name: "a",
input_types: vec![InterfaceType::I32, InterfaceType::I64],
output_types: vec![InterfaceType::I32],
instructions: vec![Instruction::ArgumentGet { index: 1 }],
},
&[
0x02, // AdapterKind::HelperFunction
0x01, // string of length 1
0x61, // "a"
0x02, // list of 2 items
0x7f, // I32
0x7e, // I64
0x01, // list of 1 items
0x7f, // I32
0x01, // list of 1 item
0x00, 0x01, // ArgumentGet { index: 1 }
]
);
}
#[test]
fn test_forward() {
assert_to_bytes!(
Forward { name: "ab" },
&[
0x02, // string of length 2
0x61, // "a"
0x62, // "b"
]
);
}
#[test] #[test]
fn test_interfaces() { fn test_interfaces() {
assert_to_bytes!( assert_to_bytes!(
Interfaces { Interfaces {
exports: vec![Export { types: vec![Type {
name: "ab", inputs: vec![InterfaceType::S8],
input_types: vec![InterfaceType::I32], outputs: vec![InterfaceType::S16],
output_types: vec![InterfaceType::I32],
}], }],
types: vec![Type::new(
"ab",
vec!["cd", "e"],
vec![InterfaceType::I32, InterfaceType::I32],
)],
imports: vec![Import { imports: vec![Import {
namespace: "a", namespace: "ab",
name: "b", name: "c",
input_types: vec![InterfaceType::I32], signature_type: 0,
output_types: vec![InterfaceType::I64],
}], }],
adapters: vec![Adapter::Import { adapters: vec![Adapter {
namespace: "a", function_type: 0,
name: "b",
input_types: vec![InterfaceType::I32],
output_types: vec![InterfaceType::I32],
instructions: vec![Instruction::ArgumentGet { index: 1 }], instructions: vec![Instruction::ArgumentGet { index: 1 }],
}], }],
forwards: vec![Forward { name: "a" }], exports: vec![Export {
name: "ab",
function_type: 1,
}],
implementations: vec![Implementation {
core_function_type: 2,
adapter_function_type: 3,
}],
}, },
&[ &[
0x00, // type section
0x01, // 1 type
0x01, // list of 1 item
0x00, // S8
0x01, // list of 1 item
0x01, // S16
//
0x01, // import section
0x01, // 1 import
0x02, // string of 2 bytes
0x61, 0x62, // "a", "b"
0x01, // string of 1 byte
0x63, // "c"
0x00, // signature type
//
0x02, // adapter section
0x01, // 1 adapter
0x00, // function type
0x01, // list of 1 item
0x00, 0x01, // ArgumentGet { index: 1 }
//
0x03, // export section
0x01, // 1 export 0x01, // 1 export
0x02, // string of 2 bytes 0x02, // string of 2 bytes
0x61, 0x62, // "a", "b" 0x61, 0x62, // "a", "b"
0x01, // list of 1 item 0x01, // function type
0x7f, // I32 //
0x01, // list of 1 item 0x04, // implementation section
0x7f, // I32 0x01, // 1 implementation
0x01, // 1 type 0x02, // core function type
0x02, // string of 2 bytes 0x03, // adapter function type
0x61, 0x62, // "a", "b"
0x02, // list of 2 items
0x02, // string of 2 bytes
0x63, 0x64, // "c", "d"
0x01, // string of 1 byte
0x65, // "e"
0x02, // list of 2 items
0x7f, // I32
0x7f, // I32
0x01, // 1 import
0x01, // string of 1 byte
0x61, // "a"
0x01, // string of 1 byte
0x62, // "b"
0x01, // list of 1 item
0x7f, // I32
0x01, // list of 1 item
0x7e, // I64
0x01, // 1 adapter
0x00, // adapter kind: import
0x01, // string of 1 byte
0x61, // "a"
0x01, // string of 1 byte
0x62, // "b"
0x01, // list of 1 item
0x7f, // I32
0x01, // list of 1 item
0x7f, // I32
0x01, // list of 1 item
0x00, 0x01, // ArgumentGet { index: 1 }
0x01, // 1 adapter
0x01, // string of 1 byte
0x61, // "a"
] ]
); );
} }
@ -705,44 +560,92 @@ mod tests {
Instruction::WriteUtf8 { Instruction::WriteUtf8 {
allocator_name: "abc", allocator_name: "abc",
}, },
Instruction::AsWasm(InterfaceType::Int), Instruction::I32ToS8,
Instruction::AsInterface(InterfaceType::I64), Instruction::I32ToS8X,
Instruction::TableRefAdd, Instruction::I32ToU8,
Instruction::TableRefGet, Instruction::I32ToS16,
Instruction::CallMethod(1), Instruction::I32ToS16X,
Instruction::MakeRecord(InterfaceType::I32), Instruction::I32ToU16,
Instruction::GetField(InterfaceType::Int, 2), Instruction::I32ToS32,
Instruction::Const(InterfaceType::I32, 1), Instruction::I32ToU32,
Instruction::FoldSeq(1), Instruction::I32ToS64,
Instruction::Add(InterfaceType::I32), Instruction::I32ToU64,
Instruction::MemToSeq(InterfaceType::I32, "abc"), Instruction::I64ToS8,
Instruction::Load(InterfaceType::I32, "abc"), Instruction::I64ToS8X,
Instruction::SeqNew(InterfaceType::I32), Instruction::I64ToU8,
Instruction::ListPush, Instruction::I64ToS16,
Instruction::RepeatUntil(1, 2), Instruction::I64ToS16X,
Instruction::I64ToU16,
Instruction::I64ToS32,
Instruction::I64ToS32X,
Instruction::I64ToU32,
Instruction::I64ToS64,
Instruction::I64ToU64,
Instruction::S8ToI32,
Instruction::U8ToI32,
Instruction::S16ToI32,
Instruction::U16ToI32,
Instruction::S32ToI32,
Instruction::U32ToI32,
Instruction::S64ToI32,
Instruction::S64ToI32X,
Instruction::U64ToI32,
Instruction::U64ToI32X,
Instruction::S8ToI64,
Instruction::U8ToI64,
Instruction::S16ToI64,
Instruction::U16ToI64,
Instruction::S32ToI64,
Instruction::U32ToI64,
Instruction::S64ToI64,
Instruction::U64ToI64,
], ],
&[ &[
0x14, // list of 20 items 0x2c, // list of 44 items
0x00, 0x01, // ArgumentGet { index: 1 } 0x00, 0x01, // ArgumentGet { index: 1 }
0x01, 0x01, // Call { function_index: 1 } 0x01, 0x01, // Call { function_index: 1 }
0x02, 0x03, 0x61, 0x62, 0x63, // CallExport { export_name: "abc" } 0x02, 0x03, 0x61, 0x62, 0x63, // CallExport { export_name: "abc" }
0x03, // ReadUtf8 0x03, // ReadUtf8
0x04, 0x03, 0x61, 0x62, 0x63, // WriteUtf8 { allocator_name: "abc" } 0x04, 0x03, 0x61, 0x62, 0x63, // WriteUtf8 { allocator_name: "abc" }
0x05, 0xff, 0xff, 0x01, // AsWasm(Int) 0x07, // I32ToS8
0x06, 0x7e, // AsInterface(I64) 0x08, // I32ToS8X
0x07, // TableRefAdd 0x09, // I32ToU8
0x08, // TableRefGet 0x0a, // I32ToS16
0x09, 0x01, // CallMethod(1) 0x0b, // I32ToS16X
0x0a, 0x7f, // MakeRecord(I32) 0x0c, // I32ToU16
0x0c, 0xff, 0xff, 0x01, 0x02, // GetField(Int, 2) 0x0d, // I32ToS32
0x0d, 0x7f, 0x01, // Const(I32, 1) 0x0e, // I32ToU32
0x0e, 0x01, // FoldSeq(1) 0x0f, // I32ToS64
0x0f, 0x7f, // Add(I32) 0x10, // I32ToU64
0x10, 0x7f, 0x03, 0x61, 0x62, 0x63, // MemToSeq(I32, "abc") 0x11, // I64ToS8
0x11, 0x7f, 0x03, 0x61, 0x62, 0x63, // Load(I32, "abc") 0x12, // I64ToS8X
0x12, 0x7f, // SeqNew(I32) 0x13, // I64ToU8
0x13, // ListPush 0x14, // I64ToS16
0x14, 0x01, 0x02, // RepeatUntil(1, 2) 0x15, // I64ToS16X
0x16, // I64ToU16
0x17, // I64ToS32
0x18, // I64ToS32X
0x19, // I64ToU32
0x1a, // I64ToS64
0x1b, // I64ToU64
0x1c, // S8ToI32
0x1d, // U8ToI32
0x1e, // S16ToI32
0x1f, // U16ToI32
0x20, // S32ToI32
0x21, // U32ToI32
0x22, // S64ToI32
0x23, // S64ToI32X
0x24, // U64ToI32
0x25, // U64ToI32X
0x26, // S8ToI64
0x27, // U8ToI64
0x28, // S16ToI64
0x29, // U16ToI64
0x2a, // S32ToI64
0x2b, // U32ToI64
0x2c, // S64ToI64
0x2d, // U64ToI64
] ]
); );
} }

View File

@ -9,105 +9,72 @@
//! interpreter::Instruction, //! interpreter::Instruction,
//! }; //! };
//! //!
//! # fn main() {
//! let input: String = (&Interfaces { //! let input: String = (&Interfaces {
//! exports: vec![ //! types: vec![Type {
//! Export { //! inputs: vec![InterfaceType::I32],
//! name: "foo", //! outputs: vec![InterfaceType::S8],
//! input_types: vec![InterfaceType::I32], //! }],
//! output_types: vec![], //! imports: vec![Import {
//! },
//! Export {
//! name: "bar",
//! input_types: vec![],
//! output_types: vec![],
//! },
//! ],
//! types: vec![],
//! imports: vec![
//! Import {
//! namespace: "ns", //! namespace: "ns",
//! name: "foo", //! name: "foo",
//! input_types: vec![], //! signature_type: 0,
//! output_types: vec![InterfaceType::I32], //! }],
//! }, //! adapters: vec![Adapter {
//! Import { //! function_type: 0,
//! namespace: "ns",
//! name: "bar",
//! input_types: vec![],
//! output_types: vec![],
//! },
//! ],
//! adapters: vec![
//! Adapter::Import {
//! namespace: "ns",
//! name: "foo",
//! input_types: vec![InterfaceType::I32],
//! output_types: vec![],
//! instructions: vec![Instruction::ArgumentGet { index: 42 }], //! instructions: vec![Instruction::ArgumentGet { index: 42 }],
//! }, //! }],
//! Adapter::Export { //! exports: vec![Export {
//! name: "bar", //! name: "bar",
//! input_types: vec![], //! function_type: 0,
//! output_types: vec![], //! }],
//! instructions: vec![Instruction::ArgumentGet { index: 42 }], //! implementations: vec![Implementation {
//! }, //! core_function_type: 0,
//! ], //! adapter_function_type: 1,
//! forwards: vec![Forward { name: "main" }], //! }],
//! }) //! })
//! .to_string(); //! .to_string();
//! let output = r#";; Interfaces //! let output = r#";; Types
//! //! (@interface type (func
//! ;; Interface, Export foo
//! (@interface export "foo"
//! (param i32))
//!
//! ;; Interface, Export bar
//! (@interface export "bar")
//!
//! ;; Interface, Import ns.foo
//! (@interface func $ns_foo (import "ns" "foo")
//! (result i32))
//!
//! ;; Interface, Import ns.bar
//! (@interface func $ns_bar (import "ns" "bar"))
//!
//! ;; Interface, Adapter ns.foo
//! (@interface adapt (import "ns" "foo")
//! (param i32) //! (param i32)
//! (result s8)))
//!
//! ;; Imports
//! (@interface import "ns" "foo" (func (type 0)))
//!
//! ;; Adapters
//! (@interface func (type 0)
//! arg.get 42) //! arg.get 42)
//! //!
//! ;; Interface, Adapter bar //! ;; Exports
//! (@interface adapt (export "bar") //! (@interface export "bar" (func 0))
//! arg.get 42)
//! //!
//! ;; Interface, Forward main //! ;; Implementations
//! (@interface forward (export "main"))"#; //! (@interface implement (func 0) (func 1))"#;
//! //!
//! assert_eq!(input, output); //! assert_eq!(input, output);
//! # }
//! ``` //! ```
use crate::{ use crate::{ast::*, interpreter::Instruction};
ast::{Adapter, Export, Forward, Import, InterfaceType, Interfaces, Type},
interpreter::Instruction,
};
use std::string::ToString; use std::string::ToString;
/// Encode an `InterfaceType` into a string. /// Encode an `InterfaceType` into a string.
impl ToString for &InterfaceType { impl ToString for &InterfaceType {
fn to_string(&self) -> String { fn to_string(&self) -> String {
match self { match self {
InterfaceType::Int => "Int".into(), InterfaceType::S8 => "s8".into(),
InterfaceType::Float => "Float".into(), InterfaceType::S16 => "s16".into(),
InterfaceType::Any => "Any".into(), InterfaceType::S32 => "s32".into(),
InterfaceType::String => "String".into(), InterfaceType::S64 => "s64".into(),
InterfaceType::Seq => "Seq".into(), InterfaceType::U8 => "u8".into(),
InterfaceType::I32 => "i32".into(), InterfaceType::U16 => "u16".into(),
InterfaceType::I64 => "i64".into(), InterfaceType::U32 => "u32".into(),
InterfaceType::U64 => "u64".into(),
InterfaceType::F32 => "f32".into(), InterfaceType::F32 => "f32".into(),
InterfaceType::F64 => "f64".into(), InterfaceType::F64 => "f64".into(),
InterfaceType::AnyRef => "anyref".into(), InterfaceType::String => "string".into(),
InterfaceType::Anyref => "anyref".into(),
InterfaceType::I32 => "i32".into(),
InterfaceType::I64 => "i64".into(),
} }
} }
} }
@ -123,39 +90,45 @@ impl<'input> ToString for &Instruction<'input> {
Instruction::WriteUtf8 { allocator_name } => { Instruction::WriteUtf8 { allocator_name } => {
format!(r#"write-utf8 "{}""#, allocator_name) format!(r#"write-utf8 "{}""#, allocator_name)
} }
Instruction::AsWasm(interface_type) => { Instruction::I32ToS8 => "i32-to-s8".into(),
format!("as-wasm {}", interface_type.to_string()) Instruction::I32ToS8X => "i32-to-s8x".into(),
} Instruction::I32ToU8 => "i32-to-u8".into(),
Instruction::AsInterface(interface_type) => { Instruction::I32ToS16 => "i32-to-s16".into(),
format!("as-interface {}", interface_type.to_string()) Instruction::I32ToS16X => "i32-to-s16x".into(),
} Instruction::I32ToU16 => "i32-to-u16".into(),
Instruction::TableRefAdd => "table-ref-add".into(), Instruction::I32ToS32 => "i32-to-s32".into(),
Instruction::TableRefGet => "table-ref-get".into(), Instruction::I32ToU32 => "i32-to-u32".into(),
Instruction::CallMethod(index) => format!("call-method {}", index), Instruction::I32ToS64 => "i32-to-s64".into(),
Instruction::MakeRecord(interface_type) => { Instruction::I32ToU64 => "i32-to-u64".into(),
format!("make-record {}", interface_type.to_string()) Instruction::I64ToS8 => "i64-to-s8".into(),
} Instruction::I64ToS8X => "i64-to-s8x".into(),
Instruction::GetField(interface_type, field_index) => { Instruction::I64ToU8 => "i64-to-u8".into(),
format!("get-field {} {}", interface_type.to_string(), field_index) Instruction::I64ToS16 => "i64-to-s16".into(),
} Instruction::I64ToS16X => "i64-to-s16x".into(),
Instruction::Const(interface_type, value) => { Instruction::I64ToU16 => "i64-to-u16".into(),
format!("const {} {}", interface_type.to_string(), value) Instruction::I64ToS32 => "i64-to-s32".into(),
} Instruction::I64ToS32X => "i64-to-s32x".into(),
Instruction::FoldSeq(import_index) => format!("fold-seq {}", import_index), Instruction::I64ToU32 => "i64-to-u32".into(),
Instruction::Add(interface_type) => format!("add {}", interface_type.to_string()), Instruction::I64ToS64 => "i64-to-s64".into(),
Instruction::MemToSeq(interface_type, memory) => { Instruction::I64ToU64 => "i64-to-u64".into(),
format!(r#"mem-to-seq {} "{}""#, interface_type.to_string(), memory) Instruction::S8ToI32 => "s8-to-i32".into(),
} Instruction::U8ToI32 => "u8-to-i32".into(),
Instruction::Load(interface_type, memory) => { Instruction::S16ToI32 => "s16-to-i32".into(),
format!(r#"load {} "{}""#, interface_type.to_string(), memory) Instruction::U16ToI32 => "u16-to-i32".into(),
} Instruction::S32ToI32 => "s32-to-i32".into(),
Instruction::SeqNew(interface_type) => { Instruction::U32ToI32 => "u32-to-i32".into(),
format!("seq.new {}", interface_type.to_string()) Instruction::S64ToI32 => "s64-to-i32".into(),
} Instruction::S64ToI32X => "s64-to-i32x".into(),
Instruction::ListPush => "list.push".into(), Instruction::U64ToI32 => "u64-to-i32".into(),
Instruction::RepeatUntil(condition_index, step_index) => { Instruction::U64ToI32X => "u64-to-i32x".into(),
format!("repeat-until {} {}", condition_index, step_index) Instruction::S8ToI64 => "s8-to-i64".into(),
} Instruction::U8ToI64 => "u8-to-i64".into(),
Instruction::S16ToI64 => "s16-to-i64".into(),
Instruction::U16ToI64 => "u16-to-i64".into(),
Instruction::S32ToI64 => "s32-to-i64".into(),
Instruction::U32ToI64 => "u32-to-i64".into(),
Instruction::S64ToI64 => "s64-to-i64".into(),
Instruction::U64ToI64 => "u64-to-i64".into(),
} }
} }
} }
@ -198,34 +171,25 @@ fn output_types_to_result(output_types: &[InterfaceType]) -> String {
} }
} }
/// Encode an `Export` into a string. /// Encode a `Type` into a string.
impl<'input> ToString for &Export<'input> { impl<'input> ToString for &Type {
fn to_string(&self) -> String { fn to_string(&self) -> String {
format!( format!(
r#"(@interface export "{name}"{inputs}{outputs})"#, r#"(@interface type (func{inputs}{outputs}))"#,
name = self.name, inputs = input_types_to_param(&self.inputs),
inputs = input_types_to_param(&self.input_types), outputs = output_types_to_result(&self.outputs),
outputs = output_types_to_result(&self.output_types),
) )
} }
} }
/// Encode a `Type` into a string.
impl<'input> ToString for &Type<'input> {
fn to_string(&self) -> String {
todo!("To be implemented.")
}
}
/// Encode an `Import` into a string. /// Encode an `Import` into a string.
impl<'input> ToString for &Import<'input> { impl<'input> ToString for &Import<'input> {
fn to_string(&self) -> String { fn to_string(&self) -> String {
format!( format!(
r#"(@interface func ${namespace}_{name} (import "{namespace}" "{name}"){inputs}{outputs})"#, r#"(@interface import "{namespace}" "{name}" (func (type {type})))"#,
namespace = self.namespace, namespace = self.namespace,
name = self.name, name = self.name,
inputs = input_types_to_param(&self.input_types), type = self.signature_type,
outputs = output_types_to_result(&self.output_types),
) )
} }
} }
@ -233,60 +197,39 @@ impl<'input> ToString for &Import<'input> {
/// Encode an `Adapter` into a string. /// Encode an `Adapter` into a string.
impl<'input> ToString for &Adapter<'input> { impl<'input> ToString for &Adapter<'input> {
fn to_string(&self) -> String { fn to_string(&self) -> String {
match self { format!(
Adapter::Import { r#"(@interface func (type {function_type}){instructions})"#,
namespace, function_type = self.function_type,
name,
input_types,
output_types,
instructions,
} => format!(
r#"(@interface adapt (import "{namespace}" "{name}"){inputs}{outputs}{instructions})"#,
namespace = namespace,
name = name,
inputs = input_types_to_param(&input_types),
outputs = output_types_to_result(&output_types),
instructions = instructions =
instructions self.instructions
.iter() .iter()
.fold(String::new(), |mut accumulator, instruction| { .fold(String::new(), |mut accumulator, instruction| {
accumulator.push_str("\n "); accumulator.push_str("\n ");
accumulator.push_str(&instruction.to_string()); accumulator.push_str(&instruction.to_string());
accumulator accumulator
}), }),
), )
Adapter::Export {
name,
input_types,
output_types,
instructions,
} => format!(
r#"(@interface adapt (export "{name}"){inputs}{outputs}{instructions})"#,
name = name,
inputs = input_types_to_param(&input_types),
outputs = output_types_to_result(&output_types),
instructions =
instructions
.iter()
.fold(String::new(), |mut accumulator, instruction| {
accumulator.push_str("\n ");
accumulator.push_str(&instruction.to_string());
accumulator
}),
),
_ => todo!("To be implemented."),
}
} }
} }
/// Encode a `Forward` into a string. /// Encode an `Export` into a string.
impl<'input> ToString for &Forward<'input> { impl<'input> ToString for &Export<'input> {
fn to_string(&self) -> String { fn to_string(&self) -> String {
format!( format!(
r#"(@interface forward (export "{name}"))"#, r#"(@interface export "{name}" (func {type}))"#,
name = self.name, name = self.name,
type = self.function_type,
)
}
}
/// Encode an `Implementation` into a string.
impl<'input> ToString for &Implementation {
fn to_string(&self) -> String {
format!(
r#"(@interface implement (func {core_function_type}) (func {adapter_function_type}))"#,
core_function_type = self.core_function_type,
adapter_function_type = self.adapter_function_type,
) )
} }
} }
@ -294,22 +237,13 @@ impl<'input> ToString for &Forward<'input> {
/// Encode an `Interfaces` into a string. /// Encode an `Interfaces` into a string.
impl<'input> ToString for &Interfaces<'input> { impl<'input> ToString for &Interfaces<'input> {
fn to_string(&self) -> String { fn to_string(&self) -> String {
let mut output = String::from(";; Interfaces"); let mut output = String::new();
let exports = self
.exports
.iter()
.fold(String::new(), |mut accumulator, export| {
accumulator.push_str(&format!("\n\n;; Interface, Export {}\n", export.name));
accumulator.push_str(&export.to_string());
accumulator
});
let types = self let types = self
.types .types
.iter() .iter()
.fold(String::new(), |mut accumulator, ty| { .fold(String::new(), |mut accumulator, ty| {
accumulator.push_str(&format!("\n\n;; Interface, Ty {}\n", ty.name)); accumulator.push('\n');
accumulator.push_str(&ty.to_string()); accumulator.push_str(&ty.to_string());
accumulator accumulator
}); });
@ -318,10 +252,7 @@ impl<'input> ToString for &Interfaces<'input> {
.imports .imports
.iter() .iter()
.fold(String::new(), |mut accumulator, import| { .fold(String::new(), |mut accumulator, import| {
accumulator.push_str(&format!( accumulator.push('\n');
"\n\n;; Interface, Import {}.{}\n",
import.namespace, import.name
));
accumulator.push_str(&import.to_string()); accumulator.push_str(&import.to_string());
accumulator accumulator
}); });
@ -330,38 +261,67 @@ impl<'input> ToString for &Interfaces<'input> {
.adapters .adapters
.iter() .iter()
.fold(String::new(), |mut accumulator, adapter| { .fold(String::new(), |mut accumulator, adapter| {
match adapter { accumulator.push('\n');
Adapter::Import {
namespace, name, ..
} => accumulator.push_str(&format!(
"\n\n;; Interface, Adapter {}.{}\n",
namespace, name
)),
Adapter::Export { name, .. } => {
accumulator.push_str(&format!("\n\n;; Interface, Adapter {}\n", name))
}
_ => todo!("To be implemented."),
}
accumulator.push_str(&adapter.to_string()); accumulator.push_str(&adapter.to_string());
accumulator accumulator
}); });
let forwards = self let exports = self
.forwards .exports
.iter() .iter()
.fold(String::new(), |mut accumulator, forward| { .fold(String::new(), |mut accumulator, export| {
accumulator.push_str(&format!("\n\n;; Interface, Forward {}\n", forward.name)); accumulator.push('\n');
accumulator.push_str(&forward.to_string()); accumulator.push_str(&export.to_string());
accumulator accumulator
}); });
output.push_str(&exports); let implementations =
self.implementations
.iter()
.fold(String::new(), |mut accumulator, implementation| {
accumulator.push('\n');
accumulator.push_str(&implementation.to_string());
accumulator
});
let separator = |output: &mut String| {
if !output.is_empty() {
output.push_str("\n\n");
}
};
if !types.is_empty() {
output.push_str(";; Types");
output.push_str(&types); output.push_str(&types);
}
separator(&mut output);
if !imports.is_empty() {
output.push_str(";; Imports");
output.push_str(&imports); output.push_str(&imports);
}
separator(&mut output);
if !adapters.is_empty() {
output.push_str(";; Adapters");
output.push_str(&adapters); output.push_str(&adapters);
output.push_str(&forwards); }
separator(&mut output);
if !exports.is_empty() {
output.push_str(";; Exports");
output.push_str(&exports);
}
separator(&mut output);
if !implementations.is_empty() {
output.push_str(";; Implementations");
output.push_str(&implementations);
}
output output
} }
@ -374,19 +334,24 @@ mod tests {
#[test] #[test]
fn test_interface_types() { fn test_interface_types() {
let inputs: Vec<String> = vec![ let inputs: Vec<String> = vec![
(&InterfaceType::Int).to_string(), (&InterfaceType::S8).to_string(),
(&InterfaceType::Float).to_string(), (&InterfaceType::S16).to_string(),
(&InterfaceType::Any).to_string(), (&InterfaceType::S32).to_string(),
(&InterfaceType::String).to_string(), (&InterfaceType::S64).to_string(),
(&InterfaceType::Seq).to_string(), (&InterfaceType::U8).to_string(),
(&InterfaceType::I32).to_string(), (&InterfaceType::U16).to_string(),
(&InterfaceType::I64).to_string(), (&InterfaceType::U32).to_string(),
(&InterfaceType::U64).to_string(),
(&InterfaceType::F32).to_string(), (&InterfaceType::F32).to_string(),
(&InterfaceType::F64).to_string(), (&InterfaceType::F64).to_string(),
(&InterfaceType::AnyRef).to_string(), (&InterfaceType::String).to_string(),
(&InterfaceType::Anyref).to_string(),
(&InterfaceType::I32).to_string(),
(&InterfaceType::I64).to_string(),
]; ];
let outputs = vec![ let outputs = vec![
"Int", "Float", "Any", "String", "Seq", "i32", "i64", "f32", "f64", "anyref", "s8", "s16", "s32", "s64", "u8", "u16", "u32", "u64", "f32", "f64", "string", "anyref",
"i32", "i64",
]; ];
assert_eq!(inputs, outputs); assert_eq!(inputs, outputs);
@ -403,21 +368,45 @@ mod tests {
allocator_name: "foo", allocator_name: "foo",
}) })
.to_string(), .to_string(),
(&Instruction::AsWasm(InterfaceType::Int)).to_string(), (&Instruction::I32ToS8).to_string(),
(&Instruction::AsInterface(InterfaceType::AnyRef)).to_string(), (&Instruction::I32ToS8X).to_string(),
(&Instruction::TableRefAdd).to_string(), (&Instruction::I32ToU8).to_string(),
(&Instruction::TableRefGet).to_string(), (&Instruction::I32ToS16).to_string(),
(&Instruction::CallMethod(7)).to_string(), (&Instruction::I32ToS16X).to_string(),
(&Instruction::MakeRecord(InterfaceType::Int)).to_string(), (&Instruction::I32ToU16).to_string(),
(&Instruction::GetField(InterfaceType::Int, 7)).to_string(), (&Instruction::I32ToS32).to_string(),
(&Instruction::Const(InterfaceType::I32, 7)).to_string(), (&Instruction::I32ToU32).to_string(),
(&Instruction::FoldSeq(7)).to_string(), (&Instruction::I32ToS64).to_string(),
(&Instruction::Add(InterfaceType::Int)).to_string(), (&Instruction::I32ToU64).to_string(),
(&Instruction::MemToSeq(InterfaceType::Int, "foo")).to_string(), (&Instruction::I64ToS8).to_string(),
(&Instruction::Load(InterfaceType::Int, "foo")).to_string(), (&Instruction::I64ToS8X).to_string(),
(&Instruction::SeqNew(InterfaceType::Int)).to_string(), (&Instruction::I64ToU8).to_string(),
(&Instruction::ListPush).to_string(), (&Instruction::I64ToS16).to_string(),
(&Instruction::RepeatUntil(1, 2)).to_string(), (&Instruction::I64ToS16X).to_string(),
(&Instruction::I64ToU16).to_string(),
(&Instruction::I64ToS32).to_string(),
(&Instruction::I64ToS32X).to_string(),
(&Instruction::I64ToU32).to_string(),
(&Instruction::I64ToS64).to_string(),
(&Instruction::I64ToU64).to_string(),
(&Instruction::S8ToI32).to_string(),
(&Instruction::U8ToI32).to_string(),
(&Instruction::S16ToI32).to_string(),
(&Instruction::U16ToI32).to_string(),
(&Instruction::S32ToI32).to_string(),
(&Instruction::U32ToI32).to_string(),
(&Instruction::S64ToI32).to_string(),
(&Instruction::S64ToI32X).to_string(),
(&Instruction::U64ToI32).to_string(),
(&Instruction::U64ToI32X).to_string(),
(&Instruction::S8ToI64).to_string(),
(&Instruction::U8ToI64).to_string(),
(&Instruction::S16ToI64).to_string(),
(&Instruction::U16ToI64).to_string(),
(&Instruction::S32ToI64).to_string(),
(&Instruction::U32ToI64).to_string(),
(&Instruction::S64ToI64).to_string(),
(&Instruction::U64ToI64).to_string(),
]; ];
let outputs = vec![ let outputs = vec![
"arg.get 7", "arg.get 7",
@ -425,21 +414,83 @@ mod tests {
r#"call-export "foo""#, r#"call-export "foo""#,
"read-utf8", "read-utf8",
r#"write-utf8 "foo""#, r#"write-utf8 "foo""#,
"as-wasm Int", "i32-to-s8",
"as-interface anyref", "i32-to-s8x",
"table-ref-add", "i32-to-u8",
"table-ref-get", "i32-to-s16",
"call-method 7", "i32-to-s16x",
"make-record Int", "i32-to-u16",
"get-field Int 7", "i32-to-s32",
"const i32 7", "i32-to-u32",
"fold-seq 7", "i32-to-s64",
"add Int", "i32-to-u64",
r#"mem-to-seq Int "foo""#, "i64-to-s8",
r#"load Int "foo""#, "i64-to-s8x",
"seq.new Int", "i64-to-u8",
"list.push", "i64-to-s16",
"repeat-until 1 2", "i64-to-s16x",
"i64-to-u16",
"i64-to-s32",
"i64-to-s32x",
"i64-to-u32",
"i64-to-s64",
"i64-to-u64",
"s8-to-i32",
"u8-to-i32",
"s16-to-i32",
"u16-to-i32",
"s32-to-i32",
"u32-to-i32",
"s64-to-i32",
"s64-to-i32x",
"u64-to-i32",
"u64-to-i32x",
"s8-to-i64",
"u8-to-i64",
"s16-to-i64",
"u16-to-i64",
"s32-to-i64",
"u32-to-i64",
"s64-to-i64",
"u64-to-i64",
];
assert_eq!(inputs, outputs);
}
#[test]
fn test_types() {
let inputs: Vec<String> = vec![
(&Type {
inputs: vec![InterfaceType::I32, InterfaceType::F32],
outputs: vec![InterfaceType::I32],
})
.to_string(),
(&Type {
inputs: vec![InterfaceType::I32],
outputs: vec![],
})
.to_string(),
(&Type {
inputs: vec![],
outputs: vec![InterfaceType::I32],
})
.to_string(),
(&Type {
inputs: vec![],
outputs: vec![],
})
.to_string(),
];
let outputs = vec![
r#"(@interface type (func
(param i32 f32)
(result i32)))"#,
r#"(@interface type (func
(param i32)))"#,
r#"(@interface type (func
(result i32)))"#,
r#"(@interface type (func))"#,
]; ];
assert_eq!(inputs, outputs); assert_eq!(inputs, outputs);
@ -447,187 +498,38 @@ mod tests {
#[test] #[test]
fn test_exports() { fn test_exports() {
let inputs: Vec<String> = vec![ let input = (&Export {
(&Export {
name: "foo", name: "foo",
input_types: vec![InterfaceType::I32, InterfaceType::F32], function_type: 0,
output_types: vec![InterfaceType::I32],
}) })
.to_string(), .to_string();
(&Export { let output = r#"(@interface export "foo" (func 0))"#;
name: "foo",
input_types: vec![InterfaceType::I32],
output_types: vec![],
})
.to_string(),
(&Export {
name: "foo",
input_types: vec![],
output_types: vec![InterfaceType::I32],
})
.to_string(),
(&Export {
name: "foo",
input_types: vec![],
output_types: vec![],
})
.to_string(),
];
let outputs = vec![
r#"(@interface export "foo"
(param i32 f32)
(result i32))"#,
r#"(@interface export "foo"
(param i32))"#,
r#"(@interface export "foo"
(result i32))"#,
r#"(@interface export "foo")"#,
];
assert_eq!(inputs, outputs); assert_eq!(input, output);
} }
#[test] #[test]
fn test_imports() { fn test_imports() {
let inputs: Vec<String> = vec![ let input = (&Import {
(&Import {
namespace: "ns", namespace: "ns",
name: "foo", name: "foo",
input_types: vec![InterfaceType::Int, InterfaceType::String], signature_type: 0,
output_types: vec![InterfaceType::String],
}) })
.to_string(), .to_string();
(&Import { let output = r#"(@interface import "ns" "foo" (func (type 0)))"#;
namespace: "ns",
name: "foo",
input_types: vec![InterfaceType::String],
output_types: vec![],
})
.to_string(),
(&Import {
namespace: "ns",
name: "foo",
input_types: vec![],
output_types: vec![InterfaceType::String],
})
.to_string(),
(&Import {
namespace: "ns",
name: "foo",
input_types: vec![],
output_types: vec![],
})
.to_string(),
];
let outputs = vec![
r#"(@interface func $ns_foo (import "ns" "foo")
(param Int String)
(result String))"#,
r#"(@interface func $ns_foo (import "ns" "foo")
(param String))"#,
r#"(@interface func $ns_foo (import "ns" "foo")
(result String))"#,
r#"(@interface func $ns_foo (import "ns" "foo"))"#,
];
assert_eq!(inputs, outputs); assert_eq!(input, output);
} }
#[test] #[test]
fn test_adapters() { fn test_adapter() {
let inputs: Vec<String> = vec![ let input = (&Adapter {
(&Adapter::Import { function_type: 0,
namespace: "ns", instructions: vec![Instruction::ArgumentGet { index: 42 }],
name: "foo",
input_types: vec![InterfaceType::I32, InterfaceType::F32],
output_types: vec![InterfaceType::I32],
instructions: vec![
Instruction::ArgumentGet { index: 0 },
Instruction::WriteUtf8 {
allocator_name: "hello",
},
Instruction::CallExport { export_name: "f" },
],
}) })
.to_string(), .to_string();
(&Adapter::Import { let output = r#"(@interface func (type 0)
namespace: "ns", arg.get 42)"#;
name: "foo",
input_types: vec![InterfaceType::I32],
output_types: vec![],
instructions: vec![Instruction::CallExport { export_name: "f" }],
})
.to_string(),
(&Adapter::Import {
namespace: "ns",
name: "foo",
input_types: vec![],
output_types: vec![InterfaceType::I32],
instructions: vec![Instruction::CallExport { export_name: "f" }],
})
.to_string(),
(&Adapter::Export {
name: "foo",
input_types: vec![InterfaceType::I32, InterfaceType::F32],
output_types: vec![InterfaceType::I32],
instructions: vec![
Instruction::ArgumentGet { index: 0 },
Instruction::WriteUtf8 {
allocator_name: "hello",
},
Instruction::CallExport { export_name: "f" },
],
})
.to_string(),
(&Adapter::Export {
name: "foo",
input_types: vec![InterfaceType::I32],
output_types: vec![],
instructions: vec![Instruction::CallExport { export_name: "f" }],
})
.to_string(),
(&Adapter::Export {
name: "foo",
input_types: vec![],
output_types: vec![InterfaceType::I32],
instructions: vec![Instruction::CallExport { export_name: "f" }],
})
.to_string(),
];
let outputs = vec![
r#"(@interface adapt (import "ns" "foo")
(param i32 f32)
(result i32)
arg.get 0
write-utf8 "hello"
call-export "f")"#,
r#"(@interface adapt (import "ns" "foo")
(param i32)
call-export "f")"#,
r#"(@interface adapt (import "ns" "foo")
(result i32)
call-export "f")"#,
r#"(@interface adapt (export "foo")
(param i32 f32)
(result i32)
arg.get 0
write-utf8 "hello"
call-export "f")"#,
r#"(@interface adapt (export "foo")
(param i32)
call-export "f")"#,
r#"(@interface adapt (export "foo")
(result i32)
call-export "f")"#,
];
assert_eq!(inputs, outputs);
}
#[test]
fn test_forward() {
let input: String = (&Forward { name: "main" }).to_string();
let output = r#"(@interface forward (export "main"))"#;
assert_eq!(input, output); assert_eq!(input, output);
} }
@ -635,78 +537,46 @@ mod tests {
#[test] #[test]
fn test_interfaces() { fn test_interfaces() {
let input: String = (&Interfaces { let input: String = (&Interfaces {
exports: vec![ types: vec![Type {
Export { inputs: vec![InterfaceType::I32],
name: "foo", outputs: vec![InterfaceType::S8],
input_types: vec![InterfaceType::I32], }],
output_types: vec![], imports: vec![Import {
},
Export {
name: "bar",
input_types: vec![],
output_types: vec![],
},
],
types: vec![],
imports: vec![
Import {
namespace: "ns", namespace: "ns",
name: "foo", name: "foo",
input_types: vec![], signature_type: 0,
output_types: vec![InterfaceType::I32], }],
}, adapters: vec![Adapter {
Import { function_type: 0,
namespace: "ns",
name: "bar",
input_types: vec![],
output_types: vec![],
},
],
adapters: vec![
Adapter::Import {
namespace: "ns",
name: "foo",
input_types: vec![InterfaceType::I32],
output_types: vec![],
instructions: vec![Instruction::ArgumentGet { index: 42 }], instructions: vec![Instruction::ArgumentGet { index: 42 }],
}, }],
Adapter::Export { exports: vec![Export {
name: "bar", name: "bar",
input_types: vec![], function_type: 0,
output_types: vec![], }],
instructions: vec![Instruction::ArgumentGet { index: 42 }], implementations: vec![Implementation {
}, core_function_type: 0,
], adapter_function_type: 1,
forwards: vec![Forward { name: "main" }], }],
}) })
.to_string(); .to_string();
let output = r#";; Interfaces let output = r#";; Types
(@interface type (func
;; Interface, Export foo
(@interface export "foo"
(param i32))
;; Interface, Export bar
(@interface export "bar")
;; Interface, Import ns.foo
(@interface func $ns_foo (import "ns" "foo")
(result i32))
;; Interface, Import ns.bar
(@interface func $ns_bar (import "ns" "bar"))
;; Interface, Adapter ns.foo
(@interface adapt (import "ns" "foo")
(param i32) (param i32)
(result s8)))
;; Imports
(@interface import "ns" "foo" (func (type 0)))
;; Adapters
(@interface func (type 0)
arg.get 42) arg.get 42)
;; Interface, Adapter bar ;; Exports
(@interface adapt (export "bar") (@interface export "bar" (func 0))
arg.get 42)
;; Interface, Forward main ;; Implementations
(@interface forward (export "main"))"#; (@interface implement (func 0) (func 1))"#;
assert_eq!(input, output); assert_eq!(input, output);
} }

View File

@ -1,4 +1,4 @@
use crate::ast::InterfaceType; //use crate::ast::InterfaceType;
/// Represents all the possible WIT instructions. /// Represents all the possible WIT instructions.
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
@ -6,7 +6,7 @@ pub enum Instruction<'input> {
/// The `arg.get` instruction. /// The `arg.get` instruction.
ArgumentGet { ArgumentGet {
/// The argument index. /// The argument index.
index: u64, index: u32,
}, },
/// The `call` instruction. /// The `call` instruction.
@ -30,48 +30,120 @@ pub enum Instruction<'input> {
allocator_name: &'input str, allocator_name: &'input str,
}, },
/// The `as-wasm` instruction. /// The `i32-to-s8,` instruction.
AsWasm(InterfaceType), I32ToS8,
/// The `as-interface` instruction. /// The `i32-to-s8x,` instruction.
AsInterface(InterfaceType), I32ToS8X,
/// The `table-ref-add` instruction. /// The `i32-to-u8,` instruction.
TableRefAdd, I32ToU8,
/// The `table-ref-get` instruction. /// The `i32-to-s16,` instruction.
TableRefGet, I32ToS16,
/// The `call-method` instruction. /// The `i32-to-s16x,` instruction.
CallMethod(u64), I32ToS16X,
/// The `make-record` instruction. /// The `i32-to-u16,` instruction.
MakeRecord(InterfaceType), I32ToU16,
/// The `get-field` instruction. /// The `i32-to-s32,` instruction.
GetField(InterfaceType, u64), I32ToS32,
/// The `const` instruction. /// The `i32-to-u32,` instruction.
Const(InterfaceType, u64), I32ToU32,
/// The `fold-seq` instruction. /// The `i32-to-s64,` instruction.
FoldSeq(u64), I32ToS64,
/// The `add` instruction. /// The `i32-to-u64,` instruction.
Add(InterfaceType), I32ToU64,
/// The `mem-to-seq` instruction. /// The `i64-to-s8,` instruction.
MemToSeq(InterfaceType, &'input str), I64ToS8,
/// The `load` instruction. /// The `i64-to-s8x,` instruction.
Load(InterfaceType, &'input str), I64ToS8X,
/// The `seq.new` instruction. /// The `i64-to-u8,` instruction.
SeqNew(InterfaceType), I64ToU8,
/// The `list.push` instruction. /// The `i64-to-s16,` instruction.
ListPush, I64ToS16,
/// The `repeat-until` instruction. /// The `i64-to-s16x,` instruction.
RepeatUntil(u64, u64), I64ToS16X,
/// The `i64-to-u16,` instruction.
I64ToU16,
/// The `i64-to-s32,` instruction.
I64ToS32,
/// The `i64-to-s32x,` instruction.
I64ToS32X,
/// The `i64-to-u32,` instruction.
I64ToU32,
/// The `i64-to-s64,` instruction.
I64ToS64,
/// The `i64-to-u64,` instruction.
I64ToU64,
/// The `s8-to-i32,` instruction.
S8ToI32,
/// The `u8-to-i32,` instruction.
U8ToI32,
/// The `s16-to-i32,` instruction.
S16ToI32,
/// The `u16-to-i32,` instruction.
U16ToI32,
/// The `s32-to-i32,` instruction.
S32ToI32,
/// The `u32-to-i32,` instruction.
U32ToI32,
/// The `s64-to-i32,` instruction.
S64ToI32,
/// The `s64-to-i32x,` instruction.
S64ToI32X,
/// The `u64-to-i32,` instruction.
U64ToI32,
/// The `u64-to-i32x,` instruction.
U64ToI32X,
/// The `s8-to-i64,` instruction.
S8ToI64,
/// The `u8-to-i64,` instruction.
U8ToI64,
/// The `s16-to-i64,` instruction.
S16ToI64,
/// The `u16-to-i64,` instruction.
U16ToI64,
/// The `s32-to-i64,` instruction.
S32ToI64,
/// The `u32-to-i64,` instruction.
U32ToI64,
/// The `s64-to-i64,` instruction.
S64ToI64,
/// The `u64-to-i64,` instruction.
U64ToI64,
} }

View File

@ -1,9 +1,9 @@
executable_instruction!( executable_instruction!(
argument_get(index: u64, instruction_name: String) -> _ { argument_get(index: u32, instruction_name: String) -> _ {
move |runtime| -> _ { move |runtime| -> _ {
let invocation_inputs = runtime.invocation_inputs; let invocation_inputs = runtime.invocation_inputs;
if index >= (invocation_inputs.len() as u64) { if index >= (invocation_inputs.len() as u32) {
return Err(format!( return Err(format!(
"`{}` cannot access argument #{} because it doesn't exist.", "`{}` cannot access argument #{} because it doesn't exist.",
instruction_name, index instruction_name, index

View File

@ -66,7 +66,6 @@ pub(crate) type ExecutableInstruction<Instance, Export, LocalImport, Memory, Mem
/// Instruction, Interpreter, /// Instruction, Interpreter,
/// }; /// };
/// ///
/// # fn main() {
/// // 1. Creates an interpreter from a set of instructions. They will /// // 1. Creates an interpreter from a set of instructions. They will
/// // be transformed into executable instructions. /// // be transformed into executable instructions.
/// let interpreter: Interpreter<Instance, Export, LocalImport, Memory, MemoryView> = (&vec![ /// let interpreter: Interpreter<Instance, Export, LocalImport, Memory, MemoryView> = (&vec![
@ -116,7 +115,6 @@ pub(crate) type ExecutableInstruction<Instance, Export, LocalImport, Memory, Mem
/// ///
/// // 5. Read the stack to get the result. /// // 5. Read the stack to get the result.
/// assert_eq!(stack.as_slice(), &[InterfaceValue::I32(7)]); /// assert_eq!(stack.as_slice(), &[InterfaceValue::I32(7)]);
/// # }
/// ``` /// ```
pub struct Interpreter<Instance, Export, LocalImport, Memory, MemoryView> pub struct Interpreter<Instance, Export, LocalImport, Memory, MemoryView>
where where

View File

@ -6,29 +6,39 @@ pub use crate::ast::InterfaceType;
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub enum InterfaceValue { pub enum InterfaceValue {
Int(isize), S8(i8),
Float(f64), S16(i16),
Any(isize), S32(i32),
String(String), S64(i64),
// Seq(…), U8(u8),
I32(i32), U16(u16),
I64(i64), U32(u32),
U64(u64),
F32(f32), F32(f32),
F64(f64), F64(f64),
// AnyRef(…), String(String),
//Anyref(?),
I32(i32),
I64(i64),
} }
impl From<&InterfaceValue> for InterfaceType { impl From<&InterfaceValue> for InterfaceType {
fn from(value: &InterfaceValue) -> Self { fn from(value: &InterfaceValue) -> Self {
match value { match value {
InterfaceValue::Int(_) => Self::Int, InterfaceValue::S8(_) => Self::S8,
InterfaceValue::Float(_) => Self::Float, InterfaceValue::S16(_) => Self::S16,
InterfaceValue::Any(_) => Self::Any, InterfaceValue::S32(_) => Self::S32,
InterfaceValue::String(_) => Self::String, InterfaceValue::S64(_) => Self::S64,
InterfaceValue::I32(_) => Self::I32, InterfaceValue::U8(_) => Self::U8,
InterfaceValue::I64(_) => Self::I64, InterfaceValue::U16(_) => Self::U16,
InterfaceValue::U32(_) => Self::U32,
InterfaceValue::U64(_) => Self::U64,
InterfaceValue::F32(_) => Self::F32, InterfaceValue::F32(_) => Self::F32,
InterfaceValue::F64(_) => Self::F64, InterfaceValue::F64(_) => Self::F64,
InterfaceValue::String(_) => Self::String,
//InterfaceValue::Anyref(_) => Self::Anyref,
InterfaceValue::I32(_) => Self::I32,
InterfaceValue::I64(_) => Self::I64,
} }
} }
} }
@ -60,8 +70,14 @@ macro_rules! from_x_for_interface_value {
}; };
} }
from_x_for_interface_value!(i8, S8);
from_x_for_interface_value!(i16, S16);
from_x_for_interface_value!(u8, U8);
from_x_for_interface_value!(u16, U16);
from_x_for_interface_value!(u32, U32);
from_x_for_interface_value!(u64, U64);
from_x_for_interface_value!(f32, F32);
from_x_for_interface_value!(f64, F64);
from_x_for_interface_value!(String, String); from_x_for_interface_value!(String, String);
from_x_for_interface_value!(i32, I32); from_x_for_interface_value!(i32, I32);
from_x_for_interface_value!(i64, I64); from_x_for_interface_value!(i64, I64);
from_x_for_interface_value!(f32, F32);
from_x_for_interface_value!(f64, F64);

View File

@ -5,6 +5,11 @@ macro_rules! consume {
let (next_input, $parser_output) = $parser_expression; let (next_input, $parser_output) = $parser_expression;
$input = next_input; $input = next_input;
}; };
(($input:ident, mut $parser_output:ident) = $parser_expression:expr) => {
let (next_input, mut $parser_output) = $parser_expression;
$input = next_input;
};
} }
/// This macro creates an executable instruction for the interpreter. /// This macro creates an executable instruction for the interpreter.

View File

@ -6,30 +6,33 @@ use wasmer_interface_types::{
#[test] #[test]
fn test_binary_encoding_decoding_roundtrip() { fn test_binary_encoding_decoding_roundtrip() {
let original_ast = Interfaces { let original_ast = Interfaces {
exports: vec![Export { types: vec![
name: "ab", Type {
input_types: vec![InterfaceType::I32], inputs: vec![],
output_types: vec![InterfaceType::I32], outputs: vec![],
}], },
types: vec![Type::new( Type {
"ab", inputs: vec![InterfaceType::I32, InterfaceType::I32],
vec!["cd", "e"], outputs: vec![InterfaceType::S32],
vec![InterfaceType::I32, InterfaceType::I32], },
)], ],
imports: vec![Import { imports: vec![Import {
namespace: "a", namespace: "a",
name: "b", name: "b",
input_types: vec![InterfaceType::I32], signature_type: 0,
output_types: vec![InterfaceType::I64],
}], }],
adapters: vec![Adapter::Import { adapters: vec![Adapter {
namespace: "a", function_type: 0,
name: "b",
input_types: vec![InterfaceType::I32],
output_types: vec![InterfaceType::I32],
instructions: vec![Instruction::ArgumentGet { index: 1 }], instructions: vec![Instruction::ArgumentGet { index: 1 }],
}], }],
forwards: vec![Forward { name: "a" }], exports: vec![Export {
name: "ab",
function_type: 1,
}],
implementations: vec![Implementation {
core_function_type: 0,
adapter_function_type: 0,
}],
}; };
let mut binary = vec![]; let mut binary = vec![];

View File

@ -335,7 +335,7 @@ typedef struct {
} wasmer_instance_context_t; } wasmer_instance_context_t;
/** /**
* The `wasmer_limit_option_t` struct repreesents an optional limit * The `wasmer_limit_option_t` struct represents an optional limit
* for `wasmer_limits_t`. * for `wasmer_limits_t`.
*/ */
typedef struct { typedef struct {
@ -448,7 +448,7 @@ void wasmer_emscripten_destroy_globals(wasmer_emscripten_globals_t *globals);
* `wasmer_emscripten_globals_t` from a `wasmer_module_t`. * `wasmer_emscripten_globals_t` from a `wasmer_module_t`.
* *
* WARNING: * WARNING:
*1 *
* This `import_object_t` contains thin-wrappers around host system calls. * This `import_object_t` contains thin-wrappers around host system calls.
* Do not use this to execute untrusted code without additional sandboxing. * Do not use this to execute untrusted code without additional sandboxing.
*/ */

View File

@ -269,7 +269,7 @@ struct wasmer_instance_context_t {
}; };
/// The `wasmer_limit_option_t` struct repreesents an optional limit /// The `wasmer_limit_option_t` struct represents an optional limit
/// for `wasmer_limits_t`. /// for `wasmer_limits_t`.
struct wasmer_limit_option_t { struct wasmer_limit_option_t {
/// Whether the limit is set. /// Whether the limit is set.
@ -360,7 +360,7 @@ void wasmer_emscripten_destroy_globals(wasmer_emscripten_globals_t *globals);
/// `wasmer_emscripten_globals_t` from a `wasmer_module_t`. /// `wasmer_emscripten_globals_t` from a `wasmer_module_t`.
/// ///
/// WARNING: /// WARNING:
///1 ///
/// This `import_object_t` contains thin-wrappers around host system calls. /// This `import_object_t` contains thin-wrappers around host system calls.
/// Do not use this to execute untrusted code without additional sandboxing. /// Do not use this to execute untrusted code without additional sandboxing.
wasmer_import_object_t *wasmer_emscripten_generate_import_object(wasmer_emscripten_globals_t *globals); wasmer_import_object_t *wasmer_emscripten_generate_import_object(wasmer_emscripten_globals_t *globals);

View File

@ -267,7 +267,7 @@ pub fn read_module<
} }
let info_read = info.read().unwrap(); let info_read = info.read().unwrap();
let mut cur_pos = parser.current_poisiton() as u32; let mut cur_pos = parser.current_position() as u32;
let mut state = parser.read(); let mut state = parser.read();
// loop until the function body starts // loop until the function body starts
loop { loop {
@ -297,7 +297,7 @@ pub fn read_module<
ParserState::EndFunctionBody => break, ParserState::EndFunctionBody => break,
_ => unreachable!(), _ => unreachable!(),
} }
cur_pos = parser.current_poisiton() as u32; cur_pos = parser.current_position() as u32;
state = parser.read(); state = parser.read();
} }
@ -313,7 +313,7 @@ pub fn read_module<
ParserState::EndFunctionBody => break, ParserState::EndFunctionBody => break,
_ => unreachable!(), _ => unreachable!(),
} }
cur_pos = parser.current_poisiton() as u32; cur_pos = parser.current_position() as u32;
state = parser.read(); state = parser.read();
} }
middlewares middlewares

View File

@ -97,6 +97,11 @@ mod tests {
"windows" "windows"
} }
#[cfg(target_os = "freebsd")]
fn get_target_os() -> &'static str {
"freebsd"
}
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
fn get_target_os() -> &'static str { fn get_target_os() -> &'static str {
"linux" "linux"

View File

@ -71,11 +71,6 @@ pub enum WasiStateCreationError {
fn validate_mapped_dir_alias(alias: &str) -> Result<(), WasiStateCreationError> { fn validate_mapped_dir_alias(alias: &str) -> Result<(), WasiStateCreationError> {
for byte in alias.bytes() { for byte in alias.bytes() {
match byte { match byte {
b'/' => {
return Err(WasiStateCreationError::MappedDirAliasFormattingError(
format!("Alias \"{}\" contains the character '/'", alias),
));
}
b'\0' => { b'\0' => {
return Err(WasiStateCreationError::MappedDirAliasFormattingError( return Err(WasiStateCreationError::MappedDirAliasFormattingError(
format!("Alias \"{}\" contains a nul byte", alias), format!("Alias \"{}\" contains a nul byte", alias),