-
Notifications
You must be signed in to change notification settings - Fork 9
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
GSoC 2020: Webassembly backend #147
Closed
Closed
Conversation
This file contains 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
Signed-off-by: Jerome Simeon <[email protected]>
Signed-off-by: Patrik Keller <[email protected]>
I'm struggling with RuntimeOpRecDot. make -C tests wasm I need debugger access to the generated wasm and provided ejson argument.
This PoC demonstrates how Assemblyscript could be used to implement a runtime for imp_ejson. The next step on this road would be to implement a pair functions that read/write JS Ejson from/to Assemblyscript's managed memory.
This commit adds a pair of functions that read/write JS Ejson from/to Assemblyscript's managed memory. Executing a imp function compiled to wasm is now easy. Next steps: - Test the set op implemented operators. - Hook the new runtime into the compiler pipeline.
The runtime allows to run qcert queries compiled to wasm modules in chrome. DevTools enable stepwise debugging. This predates the recent effort to implement the IMP operators in Assemblyscript.
This commit removes the Imp(Wasm) runtime operators that have been implemented before. Instead we call imported functions. These functions are defined in an Assemblyscript module. As a side effect, we lost support for constants and EjsonRuntimeOperator(s). Next steps: - Unit test the set op implemented operators. - Provide engine that links the compiled module with the runtime. - Compile constants - Support EjsonRuntimeOperator(s).
This commit add a PoC engine that executes a compiled to wasm qcert query on NodeJS. It dynamically links the IMP runtime that we implement in AssemblyScript and compile to a separate wasm module.
We can compile the following OQL queries: 3.14 not (true or false) 3.14 <. 4.5 pi pi <. e greet And execute them on input: { "pi" : 3.14, "e" : 2.72, "greet" : "Hello World!" }
Before, each use of an IMP constant lead to a fresh allocation in the AssemblyScript runtime. Additionally, strings were entirely encoded in the AST (as function that allocate and inititalize the corresponding string in the runtime). Now, constants are serialized into the linear memory of the compiled module. On first use, a corresponding value is allocated in the memory of the AssemblyScript runtime. Repeated use of a constant uses the same value on the runtime side.
We now use the AssemblyScript runtime. The old runtime is not needed anymore.
- Make explicit, that be transfer bytes of an UTF8 string. - Allocate a single, correctly sized buffer on the runtime side.
Avoids headache on Javascript/Wasm interface.
Signed-off-by: Jerome Simeon <[email protected]>
Signed-off-by: Jerome Simeon <[email protected]>
Signed-off-by: Jerome Simeon <[email protected]>
Signed-off-by: Jerome Simeon <[email protected]>
Signed-off-by: Jerome Simeon <[email protected]>
- fixes incompatibility with node ("invalid block type error" when loading compiled wasm module) - removes dependencies to wat2wasm/wasm2wat
Before, if-then-else became if-then-then Signed-off-by: Patrik Keller <[email protected]>
Q*cert's `EJsonRuntimeCompare a b` returns sign(b - a). Before this fix the Wasm implementation of this operator returned sign(a - b). Signed-off-by: Patrik Keller <[email protected]>
Signed-off-by: Jerome Simeon <[email protected]>
Signed-off-by: Jerome Simeon <[email protected]>
Signed-off-by: Patrik Keller <[email protected]>
Signed-off-by: Jerome Simeon <[email protected]>
Signed-off-by: Jerome Simeon <[email protected]>
Signed-off-by: Jerome Simeon <[email protected]>
- derive the expected output from Imp eval. - avoid bash for loop for iteration
Signed-off-by: Jerome Simeon <[email protected]>
Signed-off-by: Jerome Simeon <[email protected]>
Signed-off-by: Jerome Simeon <[email protected]>
Signed-off-by: Jerome Simeon <[email protected]>
Signed-off-by: Jerome Simeon <[email protected]>
Signed-off-by: Jerome Simeon <[email protected]>
- add a small binary (tools/binary_to_string.(ml|exe) that escapes a binary string to a valid OCaml string using hex codes. - add a dune rule that reads binary runtime.wasm into a generated ml file. - use the resulting OCaml value in for the wasm spec eval.
Signed-off-by: Jerome Simeon <[email protected]>
Closed
Merged
Some other pages link to this PR as my GSoC project report. Let's keep it as is. We can track progress in #153. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
I worked on translating Ergo smart contracts to Webassembly (Wasm) as part of Google Summer of Code (GSoC) 2020. You can find an overview of my project in PR #777 on the Ergo repo. TL;DR: Ergo adds a smart contract language frontend to the Q*cert compiler. I extend Q*cert with a proof-of-concept Webassembly backend.
This PR constitutes my GSoC project submission. It's meant to be frozen on the GSoC deadline on 8/31/2020. Future edits should go to Jerome's working PR #142.
In the following, I will try to wrap up some technical aspects of my implementation.
Overview
The Wasm specification contains a reference implementation in OCaml. I implement a translation from Imp(Ejson) to the Wasm reference Ast. We also hook up the reference interpreter as Q*Cert evaluation function for testing. All my code is OCaml and not verified. Jerome did some plumbing on the Coq side.
Preliminaries
wasm.1.0.1
.Code generation and evaluation
Code generation and evaluation is implemented in
/compiler/wasm/
. The main component is the functor inwasm_backend.ml
which is instantiated inwasm_ast.ml
. The latter provides all functions necessary to extend Q*cert with a newWasm_ast
language target. The functorization is needed since Ergo's extracts its own Imp and OCaml cannot infer their equality.The translation functions in
wasm_backend.ml
rely on an incomplete intermediate representation for Wasm (wasm_ir.mli
). In Wasm, functions, types, and variables are addressed by their integer index within the module. The IR replaces these integers with OCaml variables for more convenient addressing. It also provides concise constructors for Wasm AST elements.Another convenience module is
wasm_util.ml
. It contains a small lookup table implementation based onHashtable
which is used all over the place to get from OCaml values to integer indexes.In contrast to Imp's block-scoped variables, Wasm has only function-scoped variables. The translation in
wasm_backend.ml
does not take this into account and relies on unique variable names. We pre-process the Imp using the translation inwasm_imp_scoping.ml
in order to resolve this conflict (see #145).I implement a binary encoding for EJson values in
wasm_binary_ejson.ml
. This encoding is used for storing constants in the linear memory of the generated Wasm module. It's also used at runtime for communication between the interpreter and the runtime module (see Ergo PR #777). I briefly describe the encoding in the header of source file.Runtime
The generated wasm module relies on a Wasm runtime for execution (see Ergo PR #777). This runtime is implemented in Assemblyscript (NPM ecosystem) and lives in
/runtimes/assemblyscript/
. We build the runtime withnpm run asbuild:untouched
and run some tests withnpm test
. The Assemblyscript source resides inassembly/index.ts
, the compiled Wasm inbuild/untouched.wasm
.We add a dune rule that encodes the binary runtime
build/untouched.wasm
into anwasm_runtime.ml
file and bundles it intowasm_backend.ml
.Tests
We provide some rudimentary tests under
/tests/imp_ejson/
which can be run all at once using the commandmake -C tests wasm-imp-spec
. The tests evaluate pieces of Imp(Ejson) on a given input in order to produce the expected output. Then the Imp code gets translated to Wasm and executed with the same input on the Wasm reference interpreter. The resulting output is compared with the expected output (should be equal).Issues