paritytech / revive

Solidity compiler for PolkaVM
Apache License 2.0
38 stars 5 forks source link

Browser support #24

Open xermicus opened 4 months ago

xermicus commented 4 months ago

We want easy integration for browser-based contract IDEs. Which in turn requires the compiler to be able to run in web browsers.

xermicus commented 4 months ago

Note that the resolc binary (the solidity frontend) uses stdlib features heavily (threads via rayon, creates processes, calls itself recursively, reads from STDIN, writes files, etc.). I'd expect at least some of those things to work out of the box but I lack experience with the emscripten target.

The compilation process roughly looks like this (in a very simple case):

|
| -> resolc
  |-> solc
  |-> resolc
    |-> ld.lld
    |-> polkavm linker

The resolc binary depends on LLVM and solc. solc already runs fine in the browser. The polkavm linker is used as rust dependency directly so this should just work (altough might require changes how it is invoked).

Rough order of tasks (that can be more or less worked on independently):

ghost commented 4 months ago

There is a webassembly SDK at https://github.com/WebAssembly/wasi-sdk. This has a compiler that targets wasm and an implementation of libc in wasm. The compiler is LLVM-19 which is reported to support webassembly as a target.

There is also an effort from the YoWASP project to build LLVM to run in a wasm runtime. There is a discussion on the LLVM forum and PR. They have repositories for the patched LLVM and a build script and tools.

smiasojed commented 3 months ago

solidity is compiled to wasm with emscripten https://github.com/ethereum/solidity/blob/develop/scripts/ci/build_emscripten.sh llvm to wasm using emscripten https://github.com/jprendes/emception/tree/master https://github.com/soedirgo/llvm-wasm

xermicus commented 3 months ago

Note that dependency resolution (parallel compilation) is done in separate processes. AFAIC LLVM uses globals. If creating multiple instances in different "processes" doesn't just work like that in the browser, the LLVM objects need to be mutexed.

smiasojed commented 3 months ago

emscripten does not allow to call Module.callMain from Module.callMain as it is implemented in revive so it is an issue

xermicus commented 3 months ago

I think it might be easier to split the compilation process up and process the YUL files one by one using revives YUL mode (i.e. solc --ir + revive --yul)?

smiasojed commented 3 months ago

Does it change anything? revive -> soljson-> yul works yul -> RiscV has the issue that binary is calling itself in compile function

xermicus commented 3 months ago

Ah yes of course you are right, the recursive call happens regardless of the pipeline.

However the code compiles fine regardless for emscripten? What does actually happen on process creation, how is this supposed to work?

smiasojed commented 3 months ago

Revive is compiled as an ES6 module. I think that for recursive execution, we need to instantiate an isolated module. Maybe Web Workers could be used. Simply reloading the module for a recursive call does not work.