Skip to content
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

add C/C++ guide #134

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open

add C/C++ guide #134

wants to merge 20 commits into from

Conversation

poemm
Copy link
Collaborator

@poemm poemm commented Dec 6, 2018

No description provided.

c_cpp_guide.md Outdated Show resolved Hide resolved
c_cpp_guide.md Outdated
@@ -0,0 +1,68 @@
# C/C++ to ewasm contracts
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems the de facto consensus is to use Ewasm with the capital E.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought it was eWASM, no?
Based on this first line from the PR ethereum/go-ethereum#16957

c_cpp_guide.md Outdated Show resolved Hide resolved
c_cpp_guide.md Outdated Show resolved Hide resolved
c_cpp_guide.md Outdated Show resolved Hide resolved
c_cpp_guide.md Outdated Show resolved Hide resolved
c_cpp_guide.md Outdated Show resolved Hide resolved
c_cpp_guide.md Outdated Show resolved Hide resolved
c_cpp_guide.md Outdated Show resolved Hide resolved
c_cpp_guide.md Outdated Show resolved Hide resolved
c_cpp_guide.md Outdated

The output is `main.wasm`, but it needs some cleanup to remove some of it's extra import and export junk. For this, we use PyWebAssembly.

Aside: Alternatively, one can use a rust implementation of `wasm_chisel`. But that requires a rust compiler.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For python one needs a python interpreter :)

(and it is broken on default mac installation)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm. I want to add a link to wasm chisel in rust. Do you have a link?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Installation instruction is though as simple as cargo install chisel.

@poemm
Copy link
Collaborator Author

poemm commented Dec 6, 2018

Wow, you guys are lightning quick!

@axic
Copy link
Member

axic commented Dec 6, 2018

I'd prefer if the two C/C++ documentations could be merged into a single file, because they have a lot common (binaryen, chisel, etc.)

c_cpp_guide.md Outdated
cd ..
git clone https://github.com/poemm/pywebassembly.git
cd pywebassembly/examples/
python3 ewasm_chisel.py ../../cwrc20/main.wasm
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just checked, https://github.com/poemm/pywebassembly/blob/master/examples/ewasm_chisel.py doesn't behave like wasm-chisel (well, chisel is configurable through a config file, but talkinb about default behaviour).

chisel translates the form env:ethereum_useGas to ethereum:useGas, but only on recognised import names. ewasm_chisel translates any env namespace to ethereum. As a result it has a different naming requirement.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, ewasm_chisel.py is minimalist. It would be easy for ewasm_chisel.py to check against a list of eei method names, but I don't want to update it every time the eei changes. I have a similar problem with main.syms, which I instructed to user to check. It would be wise to just update a parsable list of current eei methods which can automate this.

My solution is to change the guide to reflect that they are different.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main difference is although the two tools are named similarly, they expect a different naming scheme from the user.

chisel expects the user to use functions like ethereum_useGas in C, while ewasm_chisel expects the user to use useGas.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. Changed ewasm_chisel.py to ewasmify.py.

@poemm
Copy link
Collaborator Author

poemm commented Dec 7, 2018

My C/C++ guide is focused on ewasm tips and concrete examples. Perhaps the other one might be an advanced section in my guide.

Feel free to copy whatever you want from mine and close this PR, or push to this PR.

@poemm poemm requested a review from lrettig December 21, 2018 03:41
poemm and others added 6 commits December 20, 2018 21:51
Reformat into bulleted lists. Tweak some wording.
Make some things clearer, and add a few more links for reference
Copy link
Member

@lrettig lrettig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This definitely needs to be reconciled/merged with #46 since the two present similar, somewhat contradictory sets of instructions. That doc is pretty thin so I don't think it should be too much work to merge them. Let me know if you'd like a hand.

c_cpp_guide.md Outdated
@@ -0,0 +1,111 @@
# Compiling C/C++ to Ewasm

First an introduction, then a basic step-by-step guide, then advanced things. Warning: the Ewasm spec and tools below are subject to change.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning: the Ewasm spec and tools below are subject to change.

I understand why you'd add this caveat here, but I don't find it constructive or helpful on its own, i.e., it just makes the reader worry that the instructions aren't going to work. Consider making this more constructive by saying something like, "Every effort is made to keep this document up to date, but if you notice anything wrong please feel free to submit a PR or an issue to report and/or fix it."

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. It is understood that things are subject to change. I completely removed it so that the guide is more concise.

c_cpp_guide.md Outdated Show resolved Hide resolved
c_cpp_guide.md Outdated Show resolved Hide resolved
c_cpp_guide.md Outdated

1. The output of compilers is a `.wasm` binary which may have imports and exports which do not meet Ewasm requirements. We have tools to fix the imports and exports.

1. There are no tutorials for debugging/testing a contract. Hera supports extra Ewasm helper functions to print things, which have helped in writing test cases. A tutorial is needed to allow early adopters to debug/test their contracts without having to do it on the testnet.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hera supports extra Ewasm helper functions to print things, which have helped in writing test cases

Could you link to a doc on these, or otherwise make it more explicit here? Assume you are talking about things like printmemhex?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should mention the state of debugging tools since it is important for developers. I changed it to say that early adoptors can debug on the testnet for now. I am left feeling that there is a great need for tools.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, was not suggesting removing this, but instead linking to docs we have elsewhere in this repo on debug tools.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you suggest a link? Do you think that it is reasonable to link instructions on how to write test fillers?

c_cpp_guide.md Outdated Show resolved Hide resolved
c_cpp_guide.md Outdated

1. WebAssembly is still primitive and lacks features. For example, WebAssembly lacks support for exceptions and we have no way to do system calls in Ewasm. Compilers and libraries are still primitive. For example, we have a patched version of libc to allow `malloc`, but the patches are not yet enough for `std::vector` because other memory managment calls are unavailable. But perhaps any memory management beyond memory allocation may be unwanted for Ewasm contracts since it costs gas. This situation will improve as WebAssembly, compilers, and libraries mature.

1. In the current Ewasm design, all communication between the contract and the client is done through the module's memory. For example, the message data ("call data") sent to the contract is accessed by calling `callDataCopy()`, which puts this data to WebAssembly memory at a location given by a pointer. This pointer must be to either to a statically allocated array, or to dynamically allocated memory using `malloc`. For example, before calling `callDataCopy()`, one may use `getCallDataSize()` to see how many bytes of memory to `malloc`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

callDataCopy()
getCallDataSize()

Consider linking to the EEI specs for these two methods.

Also, this would all be much clearer with an example using code. Could you maybe link to the wrc20 example code in C++, or even include it inline here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just tried including an example, but ended up having to explain too many things. This may overwhelm a first-time user. I think it is better to just give a concise high-level explanation, and allow the user to explore concrete examples when they know the basics. I overhauled this paragraph.

c_cpp_guide.md Outdated

When writing Ewasm contracts in C/C++, one should bear in mind the following caveats:

1. WebAssembly is still primitive and [lacks features](https://github.com/WebAssembly/design/blob/master/FutureFeatures.md). For example, WebAssembly lacks support for exceptions and we have no way to do system calls in Ewasm. Compilers and libraries are still primitive. For example, we have a patched version of libc to allow `malloc`, but the patches are not yet enough for `std::vector` because other memory managment calls are unavailable. But perhaps any memory management beyond memory allocation may be unwanted for Ewasm contracts since it costs gas. This situation will improve as WebAssembly, compilers, and libraries mature.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But perhaps any memory management beyond memory allocation may be unwanted for Ewasm contracts since it costs gas.

I don't think this statement belongs here, it leaves the reader with too many unanswered questions. I think the best thing to do would be to compile a list of open design questions in one place (not specific to C/C++) and provide a link to it somewhere in this doc. A link to open issues on the ewasm/design repo might suffice for now if we don't have a more mature doc.

To make this more helpful and constructive, it would be nice to conclude this section by saying something along the lines of, "For now, to work around these issues, ensure that you only use basic structs and malloc calls" (or whatever the advice should be). "To join the conversation and contribute to ongoing Ewasm interface design, see X" (link to another doc).

This situation will improve as WebAssembly, compilers, and libraries mature.

Consider dropping, I don't think this is critical.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed that a guide is not a place for design discussions. I overhauled this paragraph.

c_cpp_guide.md Outdated

```sh
# checkout LLVM, clang, and lld
svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use git instead of svn? The instructions from Jake's doc seem reasonable no?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mentioned that the official guide http://llvm.org/docs/GettingStarted.html uses svn. But changed our guide to use git.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am still compiling the git version to test it. Will revert to svn if there is a problem.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The git version successfully compiles wrc20. Compiling the git version of LLVM had a few errors along the way, but restarted each time and finally it finished.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't realize svn was in the official guide. Glad to hear it works with git too!

c_cpp_guide.md Outdated

Check whether the command line output of `ewasmify.py` above lists only valid Ewasm imports and exports. To troubleshoot, you may wish to also inspect `main.wasm` in its text representation, so proceed to the next step with binaryen or wabt.

We can convert from the `.wasm` binary format to the `.wat` (or `.wast`) text format (these are equivalent formats and can be converted back-and-forth). This conversion can be done with Binaryen's `wasm-dis`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.wat (or .wast) text format (these are equivalent formats and can be converted back-and-forth)

Strictly speaking, this is not true. wast defines a "scripted" format with certain extensions to the grammar, and my understanding is that it's a superset of the wat format. See https://github.com/WebAssembly/design/blob/master/TextFormat.md#text-format. We've tended to elide over this in our docs thus far but I think it might be helpful to be more explicit about it. What do you think?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. I removed .wast. I think that we should start using the correct extension .wat.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool. It's clearly not critical but we can bring it up on a call and try to get everyone on the same page.


We can convert from the `.wasm` binary format to the `.wat` (or `.wast`) text format (these are equivalent formats and can be converted back-and-forth). This conversion can be done with Binaryen's `wasm-dis`.

Aside: Alternatively one can use Wabt's `wasm2wat`. But Binaryen's `wasm-dis` is recommended because Ewasm studio uses Binaryen internally, and Binaryen can be quirky and fail to read a `.wat` generated by another program. Another tip: if Binaryen's `wasm-dis` can't read the `.wasm`, try using Wabt's `wasm2wat` then `wat2wasm` before trying again with Binaryen.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's link to @hugo-dc's new doc on binaryen and wabt here. Maybe we could rebase this against #141?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this binaryen section should be removed and replaced with a link to Hugo's doc once it is merged.

@lrettig
Copy link
Member

lrettig commented Dec 28, 2018

@poemm and I discussed yesterday and I understand that he wrote this doc from scratch and feels that it covers everything covered in #46. I just reviewed them both again and I agree with the caveat that the compilation steps are more explicit in #46, whereas this doc basically says:

make sure to modify the Makefile to clang++, use extern "C" around the helper function declarations.
run make

Basically, if the content in Compile C/C++ to WebAssembly could be brought into this doc, or else if it's no longer relevant (@axic said s2wasm was removed), then I think we're good to go with this one instead.

@axic, you suggested you wanted to cherry pick from #46 -- are we good to merge this and then bring anything required over from that one?

@poemm
Copy link
Collaborator Author

poemm commented Dec 28, 2018

make sure to modify the Makefile to clang++, use extern "C" around the helper function declarations.
run make

I agree that this is awkward, so I replaced this text with a link to a C++ example.

@lrettig Do you think that we should leave compilation steps in the makefiles, explicitly write compilation steps in the doc, or put compilation steps in both the makefiles and doc? I personally prefer only makefiles, but I trust your judgement.

@poemm
Copy link
Collaborator Author

poemm commented Dec 28, 2018

Did anyone try following the steps in this doc? Would be nice to have at least one confirmation that it works.

@poemm
Copy link
Collaborator Author

poemm commented Jan 3, 2019

Included downloading LLVM 7 from repositories, since LLVM 7 supports Wasm by default, so no need to compile your own. Also put compilation commands in the doc instead of just in the makefile.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants