-
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 3 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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,224 @@ | ||
| # Wasm Engines | ||
|
|
||
| Binaryen and Wabt are two WebAssembly Engines which also provides a set of tools | ||
| for compiling and decompiling wasm binary files. Both are official WebAssembly Projects. | ||
|
|
||
| # Binaryen | ||
|
|
||
| ## Getting and compiling binaryen | ||
|
|
||
| Install development tools (`build-essential`) `cmake` and `make`: | ||
|
hugo-dc marked this conversation as resolved.
Outdated
|
||
|
|
||
| ``` | ||
| sudo apt-get install build-essential cmake make | ||
| ``` | ||
|
|
||
| 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.
|
||
|
|
||
| ``` | ||
| cmake . && make | ||
| ``` | ||
|
|
||
| Now you have the following binaryen tools compiled in the `bin/` directory: | ||
|
|
||
| - **asm2wasm**: An asm.js to WebAssembly compiler. | ||
|
hugo-dc marked this conversation as resolved.
Outdated
|
||
| - **wasm2js**: A WebAssembly to Javascript compiler (experimental). | ||
| - **wasm-as**: Assembles WebAssembly in text format (s-expression format) into binary format. | ||
| - **wasm-ctor-eval**: A tool that can execute C++ global constructors ahead of time. | ||
| - **wasm-dis**: Un-assembles WebAssembly in binary format into text format. | ||
| - **wasm-emscripten-finalize**: Takes a wasm binary produced by llvm+lld and performs emscripten-specific passes over it. | ||
| - **wasm.js**: Contains Binaryen components compiled to JavaScript, including the interpreter, `asm2wasm`, the S-Expression parser, etc. | ||
| - **wasm-merge**: Combines wasm files into a single big wasm file. | ||
| - **wasm-metadce**: Performs dead code elimination (DCE) on a larger space that the wasm module is just part of. | ||
| - **wasm-opt**: Loads WebAssembly and runs Binaryen IR passes on it. | ||
| - **wasm-reduce**: Reduce a wasm file to a smaller one that has the same behavior on a given command. | ||
| - **wasm-shell**: A shell that can load and interpret WebAssembly code. | ||
|
|
||
| ## 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 other | ||
| compiler and convert it to WebAssembly Text format (`wast`). Example: running | ||
| `./wasm-dis contract.wasm -o new_contract.wast` will create the following wast | ||
| codee: | ||
|
|
||
|
|
||
| ```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 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 parameter, 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 you can not execute ewasm contracts using `wasm-shell` because the | ||
| `ethereum` namespace is not provided. | ||
|
|
||
| # Wabt | ||
|
|
||
| ## Getting and compiling wabt | ||
|
|
||
| Install development tools (`build-essential`) `cmake`, `make` and `clang`: | ||
|
hugo-dc marked this conversation as resolved.
Outdated
|
||
|
|
||
| ``` | ||
| sudo apt-get install build-essential cmake make clang | ||
| ``` | ||
|
|
||
| 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 creating | ||
| containing the following wabt tools: | ||
|
|
||
| - **wat2wasm**: Translate from WebAssembly Text format (`wast`) to the WebAssembly Binary format (`wasm`). | ||
| - **wasm2wat**: Translate from WebAssembly Binary format to WebAssembly Text format. | ||
| - **wasm2c**: Convert a WebAssembly binary file to a C source and header. | ||
| - **wasm-objdump**: Print information about a wasm binary. | ||
| - **wasm-interp**: Decode and run a WebAssembly binary file using a stack-based interpreter. | ||
| - **wat-desugar**: Parse .wast text form as supported by the spec interpreter and print "canonical" flat format. | ||
| - **wasm-opcodecnt**: Read a file in the wasm binary format, and count opcode usage for instructions. | ||
| - **wasm-strip**: Removes sections of a WebAssembly binary file. | ||
| - **wasm-validate**: Read a file in the WebAssembly binary format and validate it. | ||
| - **spectest-interp**: Read a Spectest JSON file, and run its tests in the interpreter. | ||
|
|
||
| ## Using Wabt tools | ||
|
|
||
| ### wat2wasm | ||
|
|
||
| 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 | ||
|
|
||
| Using this tool we can 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))) | ||
| ``` | ||
|
|
||
| Note this is not _exactly_ the same code we wrote as it was generated based on the | ||
| wasm 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.