-
Notifications
You must be signed in to change notification settings - Fork 17
Add documentation on Binaryen and Wabt #141
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
hugo-dc
wants to merge
10
commits into
master
Choose a base branch
from
doc-wasm-eng
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
801faf1
Add documentation on Binaryen and Wabt
hugo-dc 7afb011
formatting and syntax highlight
hugo-dc 25f20b8
formatting
hugo-dc 92272b4
Minor cleanup
60f7333
link to already existing documentation, add a description about binar…
hugo-dc 195fc5c
Minor cleanup
34d6333
Some minor cleanup
e59ed25
Clarify info on hera engine support
494ec1c
explain wabt/binaryen compatibility issues
hugo-dc 4037c97
Some minor tweaks
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,216 @@ | ||
| # Wasm Engines | ||
|
|
||
| [Binaryen](https://github.com/WebAssembly/binaryen.git) and | ||
| [Wabt](https://github.com/WebAssembly/wabt.git) are two [official WebAssembly | ||
| Projects](https://github.com/WebAssembly/) providing a set of tools to interact | ||
| with WebAssembly. | ||
|
|
||
| Wabt's focus is on the manipulation of WebAssembly binary files (`wasm`) and | ||
| text format (`wast`) and conversion between the two formats. Binaryen provides a | ||
| compiler and toolchain infrastructure library for WebAssembly. It aims to make | ||
| compiling to WebAssembly easy and provides a C API, internal IR, and optimizer. | ||
| Similar to Wabt, binaryen also provides a set of tools to interact with | ||
| WebAssembly binary files and WebAssembly in | ||
| [text format](https://github.com/WebAssembly/design/blob/master/TextFormat.md). | ||
| The rest of this document explains how to use these tools to work with Ewasm | ||
| contracts. | ||
|
|
||
| By default, [Hera](https://github.com/ewasm/hera) ships with binaryen support, | ||
| but it can also be compiled with wabt support. See | ||
| [build options](https://github.com/ewasm/hera#build-options) for more information. | ||
|
|
||
| Binaryen's and Wabt's WebAssembly text formats are not fully compatible with each | ||
| other, so if you decompile a `wasm` contract using `wasm-dis` (binaryen) you may | ||
| not be able to compile the resulting `wast` back to `wasm` using `wat2wasm` | ||
| (Wabt). For compatibility purposes, the same wasm engine used by Hera should be | ||
| used to generate the `wasm` or `wast` files. | ||
|
|
||
| # Binaryen | ||
|
|
||
| ## Getting and compiling binaryen | ||
|
|
||
| Make sure development tools are already installed (cmake, make, C++ compiler). | ||
| Instructions can be found [here](./README.md#manual-configuration). | ||
|
|
||
| Clone the official binaryen repository: | ||
|
|
||
| ``` | ||
| git clone https://github.com/WebAssembly/binaryen.git | ||
| ``` | ||
|
|
||
| Move to the new `binaryen` directory and run this command to build the tools: | ||
hugo-dc marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| ``` | ||
| cmake . && make | ||
| ``` | ||
|
|
||
| Now you have the following binaryen tools compiled in the `bin/` directory. A | ||
| description of each tool can be found | ||
| [here](https://github.com/WebAssembly/binaryen#tools). | ||
|
|
||
| More information on how to build binaryen can be found in the [master repository](https://github.com/WebAssembly/binaryen#building). | ||
|
|
||
| ## Using binaryen tools | ||
|
|
||
| In this section we show how to use some of the binaryen tools: | ||
|
|
||
| ### wasm-as | ||
|
|
||
| This tool allows to compile WebAssembly Text Format (wast) to | ||
| WebAssembly Binary Format (wasm). Example: We have a file called | ||
| `contract.wast` containing this wast code: | ||
|
|
||
| ```wast | ||
| (module | ||
| (import "ethereum" "storageStore" (func $storageStore (param i32 i32))) | ||
| (import "ethereum" "getCodeSize" (func $getCodeSize (result i32))) | ||
| (memory 1) | ||
| (export "main" (func $main)) | ||
| (export "memory" (memory 0)) | ||
| (func $main | ||
| (i32.store (i32.const 32) (call $getCodeSize)) | ||
| (call $storageStore (i32.const 0) (i32.const 32)))) | ||
| ``` | ||
|
|
||
| Running `./wasm-as contract.wast` will generate a `contract.wasm` file. | ||
|
|
||
| ### wasm-dis | ||
|
|
||
| You can take `contract.wasm` or any other `.wasm` file generated by another | ||
| compiler and convert it to WebAssembly Text format (`wast`). Example: running | ||
| `./wasm-dis contract.wasm -o new_contract.wast` will create the following wast | ||
| code: | ||
|
|
||
| ```wast | ||
| (module | ||
| (type $0 (func (param i32 i32))) | ||
| (type $1 (func (result i32))) | ||
| (type $2 (func)) | ||
| (import "ethereum" "storageStore" (func $fimport$0 (param i32 i32))) | ||
| (import "ethereum" "getCodeSize" (func $fimport$1 (result i32))) | ||
| (memory $0 1) | ||
| (export "main" (func $0)) | ||
| (export "memory" (memory $0)) | ||
| (func $0 (; 2 ;) (type $2) | ||
| (i32.store | ||
| (i32.const 32) | ||
| (call $fimport$1) | ||
| ) | ||
| (call $fimport$0 | ||
| (i32.const 0) | ||
| (i32.const 32) | ||
| ) | ||
| ) | ||
| ) | ||
| ``` | ||
|
|
||
| Note it is not _exactly_ the same code we wrote in the first place, it is more | ||
| verbose and the variable names have changed as it was generated based on the wasm binary file. | ||
|
|
||
| ### wasm-shell | ||
|
|
||
| This tool allows you to execute wast files. | ||
|
|
||
| Example: This WebAssembly program contains two functions, `main` and `sum`. | ||
| `sum` receives two parameters `$a` and `$b` and returns the sum of both | ||
| parameters. `main` calls `sum` using `2` and `3` as parameters, then calls a | ||
| `wasm-shell` provided function called `$print` to show the result. | ||
|
|
||
| ```wast | ||
| (module | ||
| (import "spectest" "print" (func $print (param i32))) | ||
| (memory 1) | ||
| (export "main" (func $main)) | ||
| (export "memory" (memory 0)) | ||
| (func $main | ||
| (call $print (call $sum (i32.const 2) (i32.const 3)))) | ||
| (func $sum (param $a i32) (param $b i32) (result i32) | ||
| (return (i32.add (get_local $a) (get_local $b))))) | ||
| ``` | ||
|
|
||
| You can execute this code by calling the command: `./wasm-shell --entry main | ||
| mycode.wast`, and you will get the following result: | ||
|
|
||
| ``` | ||
| BUILDING MODULE [line: 1] | ||
| (i32.const 5) | ||
| ``` | ||
|
|
||
| Note that you cannot currently execute ewasm contracts using `wasm-shell` because the | ||
| `ethereum` namespace is not provided. | ||
|
|
||
| # Wabt | ||
|
|
||
| ## Getting and compiling wabt | ||
|
|
||
| Clone the wabt repository and its submodules: | ||
|
|
||
| ``` | ||
| git clone --recursive https://github.com/WebAssembly/wabt.git | ||
| cd wabt | ||
| ``` | ||
|
|
||
| Execute `make` | ||
|
|
||
| ``` | ||
| make | ||
| ``` | ||
|
|
||
| After successfully executing this command, a new `bin` directory is created | ||
| containing the wabt tools. A description of the wabt tools can be found [here](https://github.com/WebAssembly/wabt#wabt-the-webassembly-binary-toolkit). | ||
|
|
||
| ## Using Wabt tools | ||
|
|
||
| ### wat2wasm | ||
|
|
||
| Similar to `wasm-as`, above, `wat2wasm` can be used to compile wast code to a wasm binary. | ||
|
|
||
| Consider this ewasm contract: | ||
|
|
||
| ```wast | ||
| (module | ||
| (import "ethereum" "storageStore" (func $storageStore (param i32 i32))) | ||
| (import "ethereum" "getCodeSize" (func $getCodeSize (result i32))) | ||
| (memory 1) | ||
| (export "main" (func $main)) | ||
| (export "memory" (memory 0)) | ||
| (func $main | ||
| (i32.store (i32.const 32) (call $getCodeSize)) | ||
| (call $storageStore (i32.const 0) (i32.const 32)))) | ||
| ``` | ||
|
|
||
| Running `./wat2wasm contract.wast` generates a new binary file called `contract.wasm`. | ||
|
|
||
| ### wasm2wat | ||
|
|
||
| Similar to `wasm-dis`, above, this tool allows us to decompile the wasm file back into text format: | ||
|
|
||
| ``` | ||
| ./wasm2wat contract.wasm -o my_contract.wat | ||
| ``` | ||
|
|
||
| In this case we specify an output file `my_contract.wat` in order to not | ||
| overwrite the original `wast` file. | ||
|
|
||
| This is the content of the new generated wast code: | ||
|
|
||
| ```wast | ||
| (module | ||
| (type (;0;) (func (param i32 i32))) | ||
| (type (;1;) (func (result i32))) | ||
| (type (;2;) (func)) | ||
| (import "ethereum" "storageStore" (func (;0;) (type 0))) | ||
| (import "ethereum" "getCodeSize" (func (;1;) (type 1))) | ||
| (func (;2;) (type 2) | ||
| i32.const 32 | ||
| call 1 | ||
| i32.store | ||
| i32.const 0 | ||
| i32.const 32 | ||
| call 0) | ||
| (memory (;0;) 1) | ||
| (export "main" (func 2)) | ||
| (export "memory" (memory 0))) | ||
| ``` | ||
|
|
||
| As with `wasm-dis`, note this is not _exactly_ the same code we wrote as it was generated based on the wasm binary file. | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.