Compare commits

...

32 Commits

Author SHA1 Message Date
Cyrill Leutwiler 952c5cc894 resolc-0.1.0-dev.7 (#143)
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2024-12-20 14:33:08 +01:00
Cyrill Leutwiler d8752ec6b5 the basefee opcode (#142)
Signed-off-by: xermicus <cyrill@parity.io>
2024-12-19 18:59:10 +01:00
Cyrill Leutwiler 6ad846a285 the base fee opcode (#141)
Signed-off-by: xermicus <cyrill@parity.io>
2024-12-19 12:44:15 +01:00
Cyrill Leutwiler 3f9771f838 update and fix the linker (#140) 2024-12-18 23:11:06 +01:00
Cyrill Leutwiler 22070a824d the gas limit opcode (#139)
Signed-off-by: xermicus <cyrill@parity.io>
2024-12-18 20:31:42 +01:00
Cyrill Leutwiler d299dd1a19 change getters to register version (#138) 2024-12-18 17:56:37 +01:00
Cyrill Leutwiler 14a598e840 implement the gas opcode (#136) 2024-12-18 17:19:32 +01:00
Cyrill Leutwiler 55ec0988e8 fix the CI runner version (#137)
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2024-12-18 17:03:29 +01:00
Cyrill Leutwiler 909de515c4 Allow arbitrary call data size (#135)
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2024-12-18 14:04:46 +01:00
Sebastian Miasojed afe44ad21b JS: Fix encoding conversion from utf16 to utf8 (#131) 2024-12-11 09:23:02 +01:00
Cyrill Leutwiler 2cb8f82266 calls: supply max ref_time and proof_size limits (#133)
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2024-12-10 16:31:44 +01:00
Cyrill Leutwiler 6f2f158ef1 fix new clippy lint (#132)
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2024-12-10 15:24:25 +01:00
Cyrill Leutwiler 4e5482bad2 fix the commit sha in the version (#129)
Signed-off-by: xermicus <cyrill@parity.io>
2024-12-03 12:34:17 +01:00
Cyrill Leutwiler 0110258d81 release 0.1.0 dev.6 (#128) 2024-11-29 17:45:47 +01:00
Cyrill Leutwiler f0d9d44dce Implement the gasprice opcode (#127) 2024-11-29 17:14:27 +01:00
Cyrill Leutwiler 3f6cd115ee update warnings (#126)
Signed-off-by: xermicus <cyrill@parity.io>
2024-11-29 16:23:36 +01:00
Cyrill Leutwiler 7c00bbb0fc remove unneeded utils (#125)
Signed-off-by: xermicus <cyrill@parity.io>
2024-11-29 16:21:24 +01:00
Cyrill Leutwiler 423a494621 Switch target to 64bit and enable the zbb feature (#120) 2024-11-29 15:56:10 +01:00
Cyrill Leutwiler 08112e3449 Fix broken link in README.md 2024-11-29 10:39:42 +01:00
Jeeyong Um db6ca1fcfa Fix broken link to introduction in README.md (#124) 2024-11-29 10:38:09 +01:00
Sebastian Miasojed 54d154a73c Merge pull request #123 from smiasojed/web
Add web worker compatibility
2024-11-29 10:22:59 +01:00
dependabot[bot] 93f1deb6a5 Bump rustls from 0.23.17 to 0.23.18 (#121)
Bumps [rustls](https://github.com/rustls/rustls) from 0.23.17 to 0.23.18.
- [Release notes](https://github.com/rustls/rustls/releases)
- [Changelog](https://github.com/rustls/rustls/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rustls/rustls/compare/v/0.23.17...v/0.23.18)

---
updated-dependencies:
- dependency-name: rustls
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-29 09:50:29 +01:00
Sebastian Miasojed 9a150b13f3 Remove hardcoded soljson 2024-11-28 16:54:27 +01:00
Sebastian Miasojed 677cef9c0f Remove comment 2024-11-27 15:30:49 +01:00
Sebastian Miasojed d25be523c1 Update deps 2024-11-27 15:28:04 +01:00
Sebastian Miasojed 6a4fd1e991 Add web worker compatibility 2024-11-27 15:17:26 +01:00
Sebastian Miasojed 81915ddbcb Merge pull request #122 from smiasojed/sync
Remove async JS calls
2024-11-27 14:03:26 +01:00
Sebastian Miasojed 0f25bac4bd Fix CI 2024-11-27 08:49:07 +01:00
Sebastian Miasojed 7d41495587 Fmt 2024-11-27 08:30:07 +01:00
Sebastian Miasojed d6d5acfcce Remove deps on solc 2024-11-26 22:35:18 +01:00
Sebastian Miasojed 130ac48bf0 Fix revive wasm CI 2024-11-26 22:11:26 +01:00
Sebastian Miasojed b65fa2e42c Remove async calls from revive 2024-11-26 22:03:57 +01:00
71 changed files with 1699 additions and 2263 deletions
+1 -1
View File
@@ -14,7 +14,7 @@ env:
jobs: jobs:
build-revive-debian-x86: build-revive-debian-x86:
name: debian-container-x86 name: debian-container-x86
runs-on: ubuntu-latest runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
+2 -3
View File
@@ -8,12 +8,12 @@ on:
env: env:
CARGO_TERM_COLOR: always CARGO_TERM_COLOR: always
REVIVE_WASM_INSTALL_DIR: ${{ github.workspace }}/js/dist/revive-cjs REVIVE_WASM_INSTALL_DIR: ${{ github.workspace }}/target/wasm32-unknown-emscripten/release
EMSCRIPTEN_VERSION: 3.1.64 EMSCRIPTEN_VERSION: 3.1.64
jobs: jobs:
build-revive-wasm: build-revive-wasm:
runs-on: ubuntu-latest runs-on: ubuntu-22.04
defaults: defaults:
run: run:
shell: bash shell: bash
@@ -75,6 +75,5 @@ jobs:
name: revive-wasm name: revive-wasm
path: | path: |
${{ env.REVIVE_WASM_INSTALL_DIR }}/resolc.js ${{ env.REVIVE_WASM_INSTALL_DIR }}/resolc.js
${{ env.REVIVE_WASM_INSTALL_DIR }}/worker.js
${{ env.REVIVE_WASM_INSTALL_DIR }}/resolc.wasm ${{ env.REVIVE_WASM_INSTALL_DIR }}/resolc.wasm
retention-days: 1 retention-days: 1
+1 -1
View File
@@ -11,7 +11,7 @@ env:
jobs: jobs:
build-ubuntu-x86: build-ubuntu-x86:
runs-on: ubuntu-latest runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
+1 -2
View File
@@ -14,6 +14,5 @@ artifacts
tmp tmp
package-lock.json package-lock.json
/*.html /*.html
/js/src/resolc.*
/js/dist/
/build /build
soljson.js
+39
View File
@@ -2,6 +2,45 @@
## Unreleased ## Unreleased
## v0.1.0-dev.7
This is a development pre-release.
### Added
- Implement the `GASPRICE` opcode.
- Implement the `BASEFEE` opcode.
- Implement the `GASLIMIT` opcode.
### Changed
- The `GAS` opcode now returns the remaining `ref_time`.
- Contracts can now be supplied call data input of arbitrary size.
- Some syscalls now return the value in a register, slightly improving emitted contract code.
- Calls forward maximum weight limits instead of 0, anticipating a change in polkadot-sdk where weight limits of 0 no longer interprets as uncapped limit.
### Fixed
- A linker bug which was preventing certain contracts from linking with the PVM linker.
- JS: Fix encoding conversion from JS string (UTF-16) to UTF-8.
- The git commit hash slug is always displayed in the version string.
## v0.1.0-dev.6
This is a development pre-release.
# Added
- Implement the `BLOCKHASH` opcode.
- Implement delegate calls.
- Implement the `GASPRICE` opcode. Currently hard-coded to return `1`.
- The ELF shared object contract artifact is dumped into the debug output directory.
- Initial support for emitting debug info (opt in via the `-g` flag)
# Changed
- resolc now emits 64bit PolkaVM blobs, reducing contract code size and execution time.
- The RISC-V bit-manipulation target feature (`zbb`) is enabled.
# Fixed
- Compilation to Wasm (for usage in node and web browsers)
## v0.1.0-dev.5 ## v0.1.0-dev.5
This is development pre-release. This is development pre-release.
Generated
+1070 -1677
View File
File diff suppressed because it is too large Load Diff
+19 -18
View File
@@ -3,7 +3,7 @@ resolver = "2"
members = ["crates/*"] members = ["crates/*"]
[workspace.package] [workspace.package]
version = "0.1.0-dev.5" version = "0.1.0-dev.7"
authors = [ authors = [
"Cyrill Leutwiler <cyrill@parity.io>", "Cyrill Leutwiler <cyrill@parity.io>",
"Parity Technologies <admin@parity.io>", "Parity Technologies <admin@parity.io>",
@@ -14,18 +14,18 @@ repository = "https://github.com/paritytech/revive"
rust-version = "1.80.0" rust-version = "1.80.0"
[workspace.dependencies] [workspace.dependencies]
revive-benchmarks = { version = "0.1.0-dev.5", path = "crates/benchmarks" } revive-benchmarks = { version = "0.1.0-dev.7", path = "crates/benchmarks" }
revive-builtins = { version = "0.1.0-dev.5", path = "crates/builtins" } revive-builtins = { version = "0.1.0-dev.7", path = "crates/builtins" }
revive-common = { version = "0.1.0-dev.5", path = "crates/common" } revive-common = { version = "0.1.0-dev.7", path = "crates/common" }
revive-differential = { version = "0.1.0-dev.5", path = "crates/differential" } revive-differential = { version = "0.1.0-dev.7", path = "crates/differential" }
revive-integration = { version = "0.1.0-dev.5", path = "crates/integration" } revive-integration = { version = "0.1.0-dev.7", path = "crates/integration" }
revive-linker = { version = "0.1.0-dev.5", path = "crates/linker" } revive-linker = { version = "0.1.0-dev.7", path = "crates/linker" }
lld-sys = { version = "0.1.0-dev.5", path = "crates/lld-sys" } lld-sys = { version = "0.1.0-dev.7", path = "crates/lld-sys" }
revive-llvm-context = { version = "0.1.0-dev.5", path = "crates/llvm-context" } revive-llvm-context = { version = "0.1.0-dev.7", path = "crates/llvm-context" }
revive-runtime-api = { version = "0.1.0-dev.5", path = "crates/runtime-api" } revive-runtime-api = { version = "0.1.0-dev.7", path = "crates/runtime-api" }
revive-runner = { version = "0.1.0-dev.5", path = "crates/runner" } revive-runner = { version = "0.1.0-dev.7", path = "crates/runner" }
revive-solidity = { version = "0.1.0-dev.5", path = "crates/solidity" } revive-solidity = { version = "0.1.0-dev.7", path = "crates/solidity" }
revive-stdlib = { version = "0.1.0-dev.5", path = "crates/stdlib" } revive-stdlib = { version = "0.1.0-dev.7", path = "crates/stdlib" }
hex = "0.4" hex = "0.4"
petgraph = "0.6" petgraph = "0.6"
@@ -51,10 +51,10 @@ path-slash = "0.2"
rayon = "1.8" rayon = "1.8"
clap = { version = "4", default-features = false, features = ["derive"] } clap = { version = "4", default-features = false, features = ["derive"] }
rand = "0.8" rand = "0.8"
polkavm-common = "0.14" polkavm-common = "0.18"
polkavm-linker = "0.14" polkavm-linker = "0.18"
polkavm-disassembler = "0.14" polkavm-disassembler = "0.18"
polkavm = "0.14" polkavm = "0.18"
alloy-primitives = { version = "0.8", features = ["serde"] } alloy-primitives = { version = "0.8", features = ["serde"] }
alloy-sol-types = "0.8" alloy-sol-types = "0.8"
alloy-genesis = "0.3" alloy-genesis = "0.3"
@@ -63,11 +63,12 @@ env_logger = { version = "0.10.0", default-features = false }
serde_stacker = "0.1" serde_stacker = "0.1"
criterion = { version = "0.5", features = ["html_reports"] } criterion = { version = "0.5", features = ["html_reports"] }
log = { version = "0.4" } log = { version = "0.4" }
git2 = "0.19.0"
# polkadot-sdk and friends # polkadot-sdk and friends
codec = { version = "3.6.12", default-features = false, package = "parity-scale-codec" } codec = { version = "3.6.12", default-features = false, package = "parity-scale-codec" }
scale-info = { version = "2.11.1", default-features = false } scale-info = { version = "2.11.1", default-features = false }
polkadot-sdk = { git = "https://github.com/paritytech/polkadot-sdk", rev = "0449b214accd0f0fbf7ea3e8f3a8d8b7f99445e4" } polkadot-sdk = { git = "https://github.com/paritytech/polkadot-sdk", rev = "243b751abbb94369bbd92c83d8ab159ddfc3c556" }
# llvm # llvm
[workspace.dependencies.inkwell] [workspace.dependencies.inkwell]
+12 -10
View File
@@ -2,17 +2,20 @@
RUSTFLAGS_EMSCRIPTEN := \ RUSTFLAGS_EMSCRIPTEN := \
-C link-arg=-sEXPORTED_FUNCTIONS=_main,_free,_malloc \ -C link-arg=-sEXPORTED_FUNCTIONS=_main,_free,_malloc \
-Clink-arg=-sNO_INVOKE_RUN \ -C link-arg=-sNO_INVOKE_RUN=1 \
-Clink-arg=-sEXIT_RUNTIME \ -C link-arg=-sEXIT_RUNTIME=1 \
-Clink-arg=-sINITIAL_MEMORY=64MB \ -C link-arg=-sALLOW_MEMORY_GROWTH=1 \
-Clink-arg=-sTOTAL_MEMORY=3GB \ -C link-arg=-sEXPORTED_RUNTIME_METHODS=FS,callMain,stringToNewUTF8 \
-Clink-arg=-sALLOW_MEMORY_GROWTH \ -C link-arg=-sMODULARIZE=1 \
-Clink-arg=-sEXPORTED_RUNTIME_METHODS=FS,callMain,stringToNewUTF8,cwrap \
-Clink-arg=-sMODULARIZE \
-Clink-arg=-sEXPORT_ES6 \
-C link-arg=-sEXPORT_NAME=createRevive \ -C link-arg=-sEXPORT_NAME=createRevive \
-C link-arg=-sWASM_ASYNC_COMPILATION=0 \
-C link-arg=-sDYNAMIC_EXECUTION=0 \
-C link-arg=-sALLOW_TABLE_GROWTH=1 \
-C link-arg=--js-library=js/embed/soljson_interface.js \ -C link-arg=--js-library=js/embed/soljson_interface.js \
-Clink-arg=--pre-js=js/embed/pre.js -C link-arg=--pre-js=js/embed/pre.js \
-C link-arg=-sNODEJS_CATCH_EXIT=0 \
-C link-arg=-sDISABLE_EXCEPTION_CATCHING=0 \
-C opt-level=3
install: install-bin install-npm install: install-bin install-npm
@@ -25,7 +28,6 @@ install-npm:
install-wasm: install-wasm:
RUSTFLAGS='$(RUSTFLAGS_EMSCRIPTEN)' cargo build --target wasm32-unknown-emscripten -p revive-solidity --release --no-default-features RUSTFLAGS='$(RUSTFLAGS_EMSCRIPTEN)' cargo build --target wasm32-unknown-emscripten -p revive-solidity --release --no-default-features
npm install npm install
npm run build:revive
# install-revive: Build and install to the directory specified in REVIVE_INSTALL_DIR # install-revive: Build and install to the directory specified in REVIVE_INSTALL_DIR
ifeq ($(origin REVIVE_INSTALL_DIR), undefined) ifeq ($(origin REVIVE_INSTALL_DIR), undefined)
+10 -7
View File
@@ -1,11 +1,11 @@
![CI](https://github.com/paritytech/revive/actions/workflows/rust.yml/badge.svg) ![CI](https://github.com/paritytech/revive/actions/workflows/rust.yml/badge.svg)
[![Docs](https://img.shields.io/badge/Docs-contracts.polkadot.io-brightgreen.svg)](https://contracts.polakdot.io) [![Docs](https://img.shields.io/badge/Docs-contracts.polkadot.io-brightgreen.svg)](https://contracts.polkadot.io)
# revive # revive
YUL and EVM assembly recompiler to LLVM, targetting RISC-V on [PolkaVM](https://github.com/koute/polkavm). YUL and EVM assembly recompiler to LLVM, targetting RISC-V on [PolkaVM](https://github.com/koute/polkavm).
Visit [contracts.polkadot.io](contracts.polkadot.io) to learn more about contracts on Polkadot! Visit [contracts.polkadot.io](https://contracts.polkadot.io) to learn more about contracts on Polkadot!
## Status ## Status
@@ -17,6 +17,14 @@ Discussion around the development is hosted on the [Polkadot Forum](https://foru
`resolc` depends on the [solc](https://github.com/ethereum/solidity) binary installed on your system. `resolc` depends on the [solc](https://github.com/ethereum/solidity) binary installed on your system.
Building from source requires a compatible LLVM build.
### LLVM
`revive` requires a build of LLVM 18.1.4 or later with the RISC-V _embedded_ target, including `compiler-rt`. Use the provided [build-llvm.sh](build-llvm.sh) build script to compile a compatible LLVM build locally in `$PWD/llvm18.0` (don't forget to add that to `$PATH` afterwards).
### The `resolc` Solidity frontend
To install the `resolc` Solidity frontend executable: To install the `resolc` Solidity frontend executable:
```bash ```bash
@@ -25,11 +33,6 @@ export PATH=${PWD}/llvm18.0/bin:$PATH
make install-bin make install-bin
resolc --version resolc --version
``` ```
### LLVM
`revive` requires a build of LLVM 18.1.4 or later including `compiler-rt`. Use the provided [build-llvm.sh](build-llvm.sh) build script to compile a compatible LLVM build locally in `$PWD/llvm18.0` (don't forget to add that to `$PATH` afterwards).
### Cross-compilation to WASM ### Cross-compilation to WASM
Cross-compiles the Revive compiler to WASM for running it in a Node.js or browser environment. Cross-compiles the Revive compiler to WASM for running it in a Node.js or browser environment.
+2 -1
View File
@@ -8,4 +8,5 @@ To create a new pre-release:
2. Push a release tag to `main` 2. Push a release tag to `main`
3. Manually trigger the `Build revive-debian` action 3. Manually trigger the `Build revive-debian` action
4. Create a __pre-release__ from the tag and manually upload the build artifact generated by the action 4. Create a __pre-release__ from the tag and manually upload the build artifact generated by the action
5. Update the [contract-docs](https://github.com/paritytech/contract-docs/) accordingly 5. Manually upload `resolc.js` and `resolc.wasm` from the `build-revive-wasm` action artifacts.
6. Update the [contract-docs](https://github.com/paritytech/contract-docs/) accordingly
+24 -24
View File
@@ -17,56 +17,56 @@
| | `EVM` | `PVMInterpreter` | | | `EVM` | `PVMInterpreter` |
|:--------|:------------------------|:-------------------------------- | |:--------|:------------------------|:-------------------------------- |
| **`0`** | `5.97 us` (✅ **1.00x**) | `27.04 us` (❌ *4.53x slower*) | | **`0`** | `3.36 us` (✅ **1.00x**) | `11.84 us` (❌ *3.52x slower*) |
### OddPorduct ### OddPorduct
| | `EVM` | `PVMInterpreter` | | | `EVM` | `PVMInterpreter` |
|:-------------|:--------------------------|:-------------------------------- | |:-------------|:-------------------------|:-------------------------------- |
| **`10000`** | `4.26 ms` (✅ **1.00x**) | `2.88 ms` ( **1.48x faster**) | | **`10000`** | `3.11 ms` (✅ **1.00x**) | `1.53 ms` (🚀 **2.03x faster**) |
| **`100000`** | `42.37 ms` (✅ **1.00x**) | `28.35 ms` ( **1.49x faster**) | | **`100000`** | `30.70 ms` (✅ **1.00x**) | `15.54 ms` (🚀 **1.98x faster**) |
| **`300000`** | `127.88 ms` (✅ **1.00x**) | `88.43 ms` ( **1.45x faster**) | | **`300000`** | `92.68 ms` (✅ **1.00x**) | `45.47 ms` (🚀 **2.04x faster**) |
### TriangleNumber ### TriangleNumber
| | `EVM` | `PVMInterpreter` | | | `EVM` | `PVMInterpreter` |
|:-------------|:--------------------------|:-------------------------------- | |:-------------|:-------------------------|:-------------------------------- |
| **`10000`** | `2.85 ms` (✅ **1.00x**) | `2.37 ms` ( **1.20x faster**) | | **`10000`** | `2.29 ms` (✅ **1.00x**) | `1.09 ms` (🚀 **2.11x faster**) |
| **`100000`** | `27.85 ms` (✅ **1.00x**) | `23.01 ms` ( **1.21x faster**) | | **`100000`** | `22.84 ms` (✅ **1.00x**) | `10.66 ms` (🚀 **2.14x faster**) |
| **`360000`** | `103.01 ms` (✅ **1.00x**) | `83.66 ms` ( **1.23x faster**) | | **`360000`** | `82.29 ms` (✅ **1.00x**) | `37.01 ms` (🚀 **2.22x faster**) |
### FibonacciRecursive ### FibonacciRecursive
| | `EVM` | `PVMInterpreter` | | | `EVM` | `PVMInterpreter` |
|:---------|:--------------------------|:--------------------------------- | |:---------|:--------------------------|:--------------------------------- |
| **`12`** | `195.19 us` (✅ **1.00x**) | `333.53 us` (*1.71x slower*) | | **`12`** | `135.67 us` (✅ **1.00x**) | `125.02 us` (**1.09x faster**) |
| **`16`** | `1.22 ms` (✅ **1.00x**) | `1.97 ms` (❌ *1.62x slower*) | | **`16`** | `903.75 us` (✅ **1.00x**) | `762.79 us` (✅ **1.18x faster**) |
| **`20`** | `8.14 ms` (✅ **1.00x**) | `13.20 ms` (*1.62x slower*) | | **`20`** | `6.12 ms` (✅ **1.00x**) | `4.96 ms` (**1.23x faster**) |
| **`24`** | `55.09 ms` (✅ **1.00x**) | `88.56 ms` (*1.61x slower*) | | **`24`** | `42.05 ms` (✅ **1.00x**) | `33.86 ms` (**1.24x faster**) |
### FibonacciIterative ### FibonacciIterative
| | `EVM` | `PVMInterpreter` | | | `EVM` | `PVMInterpreter` |
|:----------|:-------------------------|:--------------------------------- | |:----------|:-------------------------|:-------------------------------- |
| **`64`** | `33.39 us` (✅ **1.00x**) | `86.02 us` (❌ *2.58x slower*) | | **`64`** | `15.04 us` (✅ **1.00x**) | `29.45 us` (❌ *1.96x slower*) |
| **`128`** | `52.91 us` (✅ **1.00x**) | `126.38 us` (❌ *2.39x slower*) | | **`128`** | `26.36 us` (✅ **1.00x**) | `42.19 us` (❌ *1.60x slower*) |
| **`256`** | `82.33 us` (✅ **1.00x**) | `208.74 us` (❌ *2.54x slower*) | | **`256`** | `48.61 us` (✅ **1.00x**) | `65.71 us` (❌ *1.35x slower*) |
### FibonacciBinet ### FibonacciBinet
| | `EVM` | `PVMInterpreter` | | | `EVM` | `PVMInterpreter` |
|:----------|:-------------------------|:--------------------------------- | |:----------|:-------------------------|:-------------------------------- |
| **`64`** | `32.29 us` (✅ **1.00x**) | `161.75 us` (❌ *5.01x slower*) | | **`64`** | `15.22 us` (✅ **1.00x**) | `41.46 us` (❌ *2.72x slower*) |
| **`128`** | `36.02 us` (✅ **1.00x**) | `172.59 us` (❌ *4.79x slower*) | | **`128`** | `17.05 us` (✅ **1.00x**) | `42.84 us` (❌ *2.51x slower*) |
| **`256`** | `41.21 us` (✅ **1.00x**) | `185.30 us` (❌ *4.50x slower*) | | **`256`** | `19.00 us` (✅ **1.00x**) | `44.36 us` (❌ *2.34x slower*) |
### SHA1 ### SHA1
| | `EVM` | `PVMInterpreter` | | | `EVM` | `PVMInterpreter` |
|:----------|:--------------------------|:--------------------------------- | |:----------|:--------------------------|:--------------------------------- |
| **`1`** | `160.17 us` (✅ **1.00x**) | `403.46 us` (❌ *2.52x slower*) | | **`1`** | `110.04 us` (✅ **1.00x**) | `216.11 us` (❌ *1.96x slower*) |
| **`64`** | `286.69 us` (✅ **1.00x**) | `479.79 us` (❌ *1.67x slower*) | | **`64`** | `209.04 us` (✅ **1.00x**) | `309.48 us` (❌ *1.48x slower*) |
| **`512`** | `1.18 ms` (✅ **1.00x**) | `1.37 ms` (❌ *1.16x slower*) | | **`512`** | `903.65 us` (✅ **1.00x**) | `980.49 us` (✅ **1.09x slower**) |
--- ---
Made with [criterion-table](https://github.com/nu11ptr/criterion-table) Made with [criterion-table](https://github.com/nu11ptr/criterion-table)
+1 -1
View File
@@ -46,7 +46,7 @@ fn group<'error, M>(c: &'error mut Criterion<M>, group_name: &str) -> BenchmarkG
where where
M: Measurement, M: Measurement,
{ {
return c.benchmark_group(group_name); c.benchmark_group(group_name)
} }
fn bench_baseline(c: &mut Criterion) { fn bench_baseline(c: &mut Criterion) {
-3
View File
@@ -8,7 +8,4 @@ authors.workspace = true
build = "build.rs" build = "build.rs"
description = "compiler builtins for the revive compiler" description = "compiler builtins for the revive compiler"
[features]
riscv-64 = []
[dependencies] [dependencies]
-3
View File
@@ -1,8 +1,5 @@
use std::{env, fs, io::Read, path::Path, process::Command}; use std::{env, fs, io::Read, path::Path, process::Command};
#[cfg(not(feature = "riscv-64"))]
pub const BUILTINS_ARCHIVE_FILE: &str = "libclang_rt.builtins-riscv32.a";
#[cfg(feature = "riscv-64")]
pub const BUILTINS_ARCHIVE_FILE: &str = "libclang_rt.builtins-riscv64.a"; pub const BUILTINS_ARCHIVE_FILE: &str = "libclang_rt.builtins-riscv64.a";
fn main() { fn main() {
-3
View File
@@ -13,9 +13,6 @@ description = "Shared constants of the revive compiler"
[lib] [lib]
doctest = false doctest = false
[features]
riscv-64 = []
[dependencies] [dependencies]
anyhow = { workspace = true } anyhow = { workspace = true }
serde = { workspace = true, features = ["derive"] } serde = { workspace = true, features = ["derive"] }
+8 -8
View File
@@ -1,10 +1,10 @@
{ {
"Baseline": 961, "Baseline": 1110,
"Computation": 4024, "Computation": 2389,
"DivisionArithmetics": 31789, "DivisionArithmetics": 14822,
"ERC20": 44214, "ERC20": 23973,
"Events": 1737, "Events": 1605,
"FibonacciIterative": 2929, "FibonacciIterative": 2023,
"Flipper": 3402, "Flipper": 1989,
"SHA1": 26003 "SHA1": 17026
} }
+31
View File
@@ -0,0 +1,31 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8;
/* runner.json
{
"differential": false,
"actions": [
{
"Instantiate": {
"code": {
"Solidity": {
"contract": "BaseFee"
}
}
}
},
{
"VerifyCall": {
"success": true
}
}
]
}
*/
contract BaseFee {
constructor() payable {
assert(block.basefee == 0);
}
}
+32
View File
@@ -0,0 +1,32 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8;
/* runner.json
{
"differential": false,
"actions": [
{
"Instantiate": {
"code": {
"Solidity": {
"contract": "GasLeft"
}
}
}
},
{
"VerifyCall": {
"success": true
}
}
]
}
*/
contract GasLeft {
constructor() payable {
assert(gasleft() > gasleft());
assert(gasleft() > 0 && gasleft() < 0xffffffffffffffff);
}
}
+31
View File
@@ -0,0 +1,31 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8;
/* runner.json
{
"differential": false,
"actions": [
{
"Instantiate": {
"code": {
"Solidity": {
"contract": "GasLimit"
}
}
}
},
{
"VerifyCall": {
"success": true
}
}
]
}
*/
contract GasLimit {
constructor() payable {
assert(block.gaslimit == 2000000000000);
}
}
+31
View File
@@ -0,0 +1,31 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8;
/* runner.json
{
"differential": false,
"actions": [
{
"Instantiate": {
"code": {
"Solidity": {
"contract": "GasPrice"
}
}
}
},
{
"VerifyCall": {
"success": true
}
}
]
}
*/
contract GasPrice {
constructor() payable {
assert(tx.gasprice == 1);
}
}
+4
View File
@@ -46,6 +46,10 @@ test_spec!(immutables, "Immutables", "Immutables.sol");
test_spec!(transaction, "Transaction", "Transaction.sol"); test_spec!(transaction, "Transaction", "Transaction.sol");
test_spec!(block_hash, "BlockHash", "BlockHash.sol"); test_spec!(block_hash, "BlockHash", "BlockHash.sol");
test_spec!(delegate, "Delegate", "Delegate.sol"); test_spec!(delegate, "Delegate", "Delegate.sol");
test_spec!(gas_price, "GasPrice", "GasPrice.sol");
test_spec!(gas_left, "GasLeft", "GasLeft.sol");
test_spec!(gas_limit, "GasLimit", "GasLimit.sol");
test_spec!(base_fee, "BaseFee", "BaseFee.sol");
fn instantiate(path: &str, contract: &str) -> Vec<SpecsAction> { fn instantiate(path: &str, contract: &str) -> Vec<SpecsAction> {
vec![Instantiate { vec![Instantiate {
-3
View File
@@ -7,9 +7,6 @@ repository.workspace = true
authors.workspace = true authors.workspace = true
description = "revive compiler linker utils" description = "revive compiler linker utils"
[features]
riscv-64 = []
[dependencies] [dependencies]
inkwell = { workspace = true } inkwell = { workspace = true }
tempfile = { workspace = true } tempfile = { workspace = true }
+1 -7
View File
@@ -8,14 +8,7 @@ SECTIONS {
.text : { KEEP(*(.text.polkavm_export)) *(.text .text.*) } .text : { KEEP(*(.text.polkavm_export)) *(.text .text.*) }
}"#; }"#;
#[cfg(not(feature = "riscv-64"))]
const BUILTINS_ARCHIVE_FILE: &str = "libclang_rt.builtins-riscv32.a";
#[cfg(feature = "riscv-64")]
const BUILTINS_ARCHIVE_FILE: &str = "libclang_rt.builtins-riscv64.a"; const BUILTINS_ARCHIVE_FILE: &str = "libclang_rt.builtins-riscv64.a";
#[cfg(not(feature = "riscv-64"))]
const BUILTINS_LIB_NAME: &str = "clang_rt.builtins-riscv32";
#[cfg(feature = "riscv-64")]
const BUILTINS_LIB_NAME: &str = "clang_rt.builtins-riscv64"; const BUILTINS_LIB_NAME: &str = "clang_rt.builtins-riscv64";
fn invoke_lld(cmd_args: &[&str]) -> bool { fn invoke_lld(cmd_args: &[&str]) -> bool {
@@ -64,6 +57,7 @@ pub fn link<T: AsRef<[u8]>>(input: T) -> anyhow::Result<Vec<u8>> {
"--relocatable", "--relocatable",
"--emit-relocs", "--emit-relocs",
"--no-relax", "--no-relax",
"--unique",
"--gc-sections", "--gc-sections",
"--library-path", "--library-path",
dir.path().to_str().expect("should be utf8"), dir.path().to_str().expect("should be utf8"),
-9
View File
@@ -13,15 +13,6 @@ description = "Shared front end code of the revive PolkaVM compilers"
[lib] [lib]
doctest = false doctest = false
[features]
riscv-zbb = []
riscv-64 = [
"revive-linker/riscv-64",
"revive-builtins/riscv-64",
"revive-runtime-api/riscv-64",
"revive-common/riscv-64",
]
[dependencies] [dependencies]
anyhow = { workspace = true } anyhow = { workspace = true }
semver = { workspace = true } semver = { workspace = true }
-1
View File
@@ -61,7 +61,6 @@ pub use self::polkavm::evm::return_data as polkavm_evm_return_data;
pub use self::polkavm::evm::storage as polkavm_evm_storage; pub use self::polkavm::evm::storage as polkavm_evm_storage;
pub use self::polkavm::metadata_hash::MetadataHash as PolkaVMMetadataHash; pub use self::polkavm::metadata_hash::MetadataHash as PolkaVMMetadataHash;
pub use self::polkavm::r#const as polkavm_const; pub use self::polkavm::r#const as polkavm_const;
pub use self::polkavm::utils as polkavm_utils;
pub use self::polkavm::Dependency as PolkaVMDependency; pub use self::polkavm::Dependency as PolkaVMDependency;
pub use self::polkavm::DummyDependency as PolkaVMDummyDependency; pub use self::polkavm::DummyDependency as PolkaVMDummyDependency;
pub use self::polkavm::DummyLLVMWritable as PolkaVMDummyLLVMWritable; pub use self::polkavm::DummyLLVMWritable as PolkaVMDummyLLVMWritable;
+1 -4
View File
@@ -3,15 +3,12 @@
/// The LLVM framework version. /// The LLVM framework version.
pub const LLVM_VERSION: semver::Version = semver::Version::new(18, 1, 4); pub const LLVM_VERSION: semver::Version = semver::Version::new(18, 1, 4);
/// The register width sized type /// The pointer width sized type.
pub static XLEN: usize = revive_common::BIT_LENGTH_X32; pub static XLEN: usize = revive_common::BIT_LENGTH_X32;
/// The heap memory pointer pointer global variable name. /// The heap memory pointer pointer global variable name.
pub static GLOBAL_HEAP_MEMORY_POINTER: &str = "memory_pointer"; pub static GLOBAL_HEAP_MEMORY_POINTER: &str = "memory_pointer";
/// The calldata pointer global variable name.
pub static GLOBAL_CALLDATA_POINTER: &str = "ptr_calldata";
/// The calldata size global variable name. /// The calldata size global variable name.
pub static GLOBAL_CALLDATA_SIZE: &str = "calldatasize"; pub static GLOBAL_CALLDATA_SIZE: &str = "calldatasize";
@@ -13,7 +13,7 @@ pub struct EVMLAData<'ctx> {
pub stack: Vec<Argument<'ctx>>, pub stack: Vec<Argument<'ctx>>,
} }
impl<'ctx> EVMLAData<'ctx> { impl EVMLAData<'_> {
/// The default stack size. /// The default stack size.
pub const DEFAULT_STACK_SIZE: usize = 64; pub const DEFAULT_STACK_SIZE: usize = 64;
@@ -18,23 +18,12 @@ impl Entry {
/// The call flags argument index. /// The call flags argument index.
pub const ARGUMENT_INDEX_CALL_FLAGS: usize = 0; pub const ARGUMENT_INDEX_CALL_FLAGS: usize = 0;
/// Reserve 1kb for calldata.
pub const MAX_CALLDATA_SIZE: usize = 1024;
/// Initializes the global variables. /// Initializes the global variables.
/// The pointers are not initialized, because it's not possible to create a null pointer. /// The pointers are not initialized, because it's not possible to create a null pointer.
pub fn initialize_globals<D>(context: &mut Context<D>) -> anyhow::Result<()> pub fn initialize_globals<D>(context: &mut Context<D>) -> anyhow::Result<()>
where where
D: Dependency + Clone, D: Dependency + Clone,
{ {
let calldata_type = context.array_type(context.byte_type(), Self::MAX_CALLDATA_SIZE);
context.set_global(
crate::polkavm::GLOBAL_CALLDATA_POINTER,
calldata_type,
AddressSpace::Stack,
calldata_type.get_undef(),
);
context.set_global( context.set_global(
crate::polkavm::GLOBAL_HEAP_MEMORY_POINTER, crate::polkavm::GLOBAL_HEAP_MEMORY_POINTER,
context.llvm().ptr_type(AddressSpace::Heap.into()), context.llvm().ptr_type(AddressSpace::Heap.into()),
@@ -53,9 +42,9 @@ impl Entry {
context.set_global( context.set_global(
crate::polkavm::GLOBAL_CALLDATA_SIZE, crate::polkavm::GLOBAL_CALLDATA_SIZE,
context.word_type(), context.xlen_type(),
AddressSpace::Stack, AddressSpace::Stack,
context.word_undef(), context.xlen_type().get_undef(),
); );
context.set_global( context.set_global(
@@ -68,53 +57,22 @@ impl Entry {
Ok(()) Ok(())
} }
/// Load the calldata via seal `input` and initialize the calldata end /// Populate the calldata size global value.
/// and calldata size globals. pub fn load_calldata_size<D>(context: &mut Context<D>) -> anyhow::Result<()>
pub fn load_calldata<D>(context: &mut Context<D>) -> anyhow::Result<()>
where where
D: Dependency + Clone, D: Dependency + Clone,
{ {
let input_pointer = context let call_data_size_pointer = context
.get_global(crate::polkavm::GLOBAL_CALLDATA_POINTER)? .get_global(crate::polkavm::GLOBAL_CALLDATA_SIZE)?
.value .value
.as_pointer_value(); .as_pointer_value();
let input_pointer_casted = context.builder.build_ptr_to_int( let call_data_size_value = context
input_pointer, .build_runtime_call(revive_runtime_api::polkavm_imports::CALL_DATA_SIZE, &[])
context.xlen_type(), .expect("the call_data_size syscall method should return a value")
"input_pointer_casted",
)?;
let length_pointer = context.build_alloca_at_entry(context.xlen_type(), "len_ptr");
let length_pointer_casted = context.builder.build_ptr_to_int(
length_pointer.value,
context.xlen_type(),
"length_pointer_casted",
)?;
context.build_store(
length_pointer,
context.integer_const(crate::polkavm::XLEN, Self::MAX_CALLDATA_SIZE as u64),
)?;
context.build_runtime_call(
revive_runtime_api::polkavm_imports::INPUT,
&[input_pointer_casted.into(), length_pointer_casted.into()],
);
// Store the calldata size
let calldata_size = context
.build_load(length_pointer, "input_size")?
.into_int_value(); .into_int_value();
let calldata_size_casted = context.builder().build_int_z_extend( context
calldata_size, .builder()
context.word_type(), .build_store(call_data_size_pointer, call_data_size_value)?;
"zext_input_len",
)?;
context.set_global(
crate::polkavm::GLOBAL_CALLDATA_SIZE,
context.word_type(),
AddressSpace::Stack,
calldata_size_casted,
);
Ok(()) Ok(())
} }
@@ -220,7 +178,7 @@ where
context.set_basic_block(context.current_function().borrow().entry_block()); context.set_basic_block(context.current_function().borrow().entry_block());
Self::initialize_globals(context)?; Self::initialize_globals(context)?;
Self::load_calldata(context)?; Self::load_calldata_size(context)?;
Self::leave_entry(context)?; Self::leave_entry(context)?;
context.build_unconditional_branch(context.current_function().borrow().return_block()); context.build_unconditional_branch(context.current_function().borrow().return_block());
@@ -27,7 +27,7 @@ where
runtime::FUNCTION_LOAD_IMMUTABLE_DATA, runtime::FUNCTION_LOAD_IMMUTABLE_DATA,
context.void_type().fn_type(Default::default(), false), context.void_type().fn_type(Default::default(), false),
0, 0,
Some(inkwell::module::Linkage::Private), Some(inkwell::module::Linkage::External),
)?; )?;
Ok(()) Ok(())
@@ -37,7 +37,7 @@ impl<'ctx> Global<'ctx> {
.add_global(r#type, Some(address_space.into()), name); .add_global(r#type, Some(address_space.into()), name);
let global = Self { r#type, value }; let global = Self { r#type, value };
global.value.set_linkage(inkwell::module::Linkage::Private); global.value.set_linkage(inkwell::module::Linkage::External);
global global
.value .value
.set_visibility(inkwell::GlobalVisibility::Default); .set_visibility(inkwell::GlobalVisibility::Default);
+15 -3
View File
@@ -165,8 +165,9 @@ where
fn link_immutable_data(&self, contract_path: &str) -> anyhow::Result<()> { fn link_immutable_data(&self, contract_path: &str) -> anyhow::Result<()> {
let size = self.solidity().immutables_size() as u32; let size = self.solidity().immutables_size() as u32;
let exports = revive_runtime_api::immutable_data::module(self.llvm(), size); let immutables = revive_runtime_api::immutable_data::module(self.llvm(), size);
self.module.link_in_module(exports).map_err(|error| {
self.module.link_in_module(immutables).map_err(|error| {
anyhow::anyhow!( anyhow::anyhow!(
"The contract `{}` immutable data module linking error: {}", "The contract `{}` immutable data module linking error: {}",
contract_path, contract_path,
@@ -202,6 +203,16 @@ where
); );
} }
/// Configure the revive datalayout.
fn set_data_layout(
llvm: &'ctx inkwell::context::Context,
module: &inkwell::module::Module<'ctx>,
) {
let source_module = revive_stdlib::module(llvm, "revive_stdlib").unwrap();
let data_layout = source_module.get_data_layout();
module.set_data_layout(&data_layout);
}
/// Initializes a new LLVM context. /// Initializes a new LLVM context.
pub fn new( pub fn new(
llvm: &'ctx inkwell::context::Context, llvm: &'ctx inkwell::context::Context,
@@ -211,6 +222,7 @@ where
include_metadata_hash: bool, include_metadata_hash: bool,
debug_config: DebugConfig, debug_config: DebugConfig,
) -> Self { ) -> Self {
Self::set_data_layout(llvm, &module);
Self::link_stdlib_module(llvm, &module); Self::link_stdlib_module(llvm, &module);
Self::link_polkavm_imports(llvm, &module); Self::link_polkavm_imports(llvm, &module);
Self::set_polkavm_stack_size(llvm, &module, Self::POLKAVM_STACK_SIZE); Self::set_polkavm_stack_size(llvm, &module, Self::POLKAVM_STACK_SIZE);
@@ -261,7 +273,7 @@ where
self.link_immutable_data(contract_path)?; self.link_immutable_data(contract_path)?;
let target_machine = TargetMachine::new(Target::PVM, self.optimizer.settings())?; let target_machine = TargetMachine::new(Target::PVM, self.optimizer.settings())?;
target_machine.set_target_data(self.module()); self.module().set_triple(&target_machine.get_triple());
self.debug_config self.debug_config
.dump_llvm_ir_unoptimized(contract_path, self.module())?; .dump_llvm_ir_unoptimized(contract_path, self.module())?;
+10 -6
View File
@@ -60,8 +60,8 @@ where
let arguments = &[ let arguments = &[
flags.as_basic_value_enum(), flags.as_basic_value_enum(),
address_pointer.value.as_basic_value_enum(), address_pointer.value.as_basic_value_enum(),
context.integer_const(64, 0).as_basic_value_enum(), context.integer_const(64, u64::MAX).as_basic_value_enum(),
context.integer_const(64, 0).as_basic_value_enum(), context.integer_const(64, u64::MAX).as_basic_value_enum(),
context.sentinel_pointer().value.as_basic_value_enum(), context.sentinel_pointer().value.as_basic_value_enum(),
value_pointer.value.as_basic_value_enum(), value_pointer.value.as_basic_value_enum(),
input_pointer.value.as_basic_value_enum(), input_pointer.value.as_basic_value_enum(),
@@ -90,7 +90,7 @@ where
let is_success = context.builder().build_int_compare( let is_success = context.builder().build_int_compare(
inkwell::IntPredicate::EQ, inkwell::IntPredicate::EQ,
success, success,
context.xlen_type().const_zero(), context.integer_const(revive_common::BIT_LENGTH_X64, 0),
"is_success", "is_success",
)?; )?;
@@ -139,8 +139,12 @@ where
let arguments = &[ let arguments = &[
flags.as_basic_value_enum(), flags.as_basic_value_enum(),
address_pointer.value.as_basic_value_enum(), address_pointer.value.as_basic_value_enum(),
context.integer_const(64, 0).as_basic_value_enum(), context
context.integer_const(64, 0).as_basic_value_enum(), .integer_const(revive_common::BIT_LENGTH_X64, u64::MAX)
.as_basic_value_enum(),
context
.integer_const(revive_common::BIT_LENGTH_X64, u64::MAX)
.as_basic_value_enum(),
context.sentinel_pointer().value.as_basic_value_enum(), context.sentinel_pointer().value.as_basic_value_enum(),
input_pointer.value.as_basic_value_enum(), input_pointer.value.as_basic_value_enum(),
input_length.as_basic_value_enum(), input_length.as_basic_value_enum(),
@@ -168,7 +172,7 @@ where
let is_success = context.builder().build_int_compare( let is_success = context.builder().build_int_compare(
inkwell::IntPredicate::EQ, inkwell::IntPredicate::EQ,
success, success,
context.xlen_type().const_zero(), context.integer_const(revive_common::BIT_LENGTH_X64, 0),
"is_success", "is_success",
)?; )?;
+27 -29
View File
@@ -1,10 +1,7 @@
//! Translates the calldata instructions. //! Translates the calldata instructions.
use crate::polkavm::context::address_space::AddressSpace;
use crate::polkavm::context::pointer::Pointer;
use crate::polkavm::context::Context; use crate::polkavm::context::Context;
use crate::polkavm::Dependency; use crate::polkavm::Dependency;
use inkwell::types::BasicType;
/// Translates the calldata load. /// Translates the calldata load.
pub fn load<'ctx, D>( pub fn load<'ctx, D>(
@@ -14,19 +11,15 @@ pub fn load<'ctx, D>(
where where
D: Dependency + Clone, D: Dependency + Clone,
{ {
let calldata_pointer = context let output_pointer = context.build_alloca_at_entry(context.word_type(), "call_data_output");
.get_global(crate::polkavm::GLOBAL_CALLDATA_POINTER)? let offset = context.safe_truncate_int_to_xlen(offset)?;
.value
.as_pointer_value(); context.build_runtime_call(
let offset = context.build_gep( revive_runtime_api::polkavm_imports::CALL_DATA_LOAD,
Pointer::new(context.byte_type(), AddressSpace::Stack, calldata_pointer), &[output_pointer.to_int(context).into(), offset.into()],
&[offset],
context.word_type().as_basic_type_enum(),
"calldata_pointer_with_offset",
); );
context
.build_load(offset, "calldata_value") context.build_load(output_pointer, "call_data_load_value")
.and_then(|value| context.build_byte_swap(value))
} }
/// Translates the calldata size. /// Translates the calldata size.
@@ -37,8 +30,14 @@ where
D: Dependency + Clone, D: Dependency + Clone,
{ {
let value = context.get_global_value(crate::polkavm::GLOBAL_CALLDATA_SIZE)?; let value = context.get_global_value(crate::polkavm::GLOBAL_CALLDATA_SIZE)?;
Ok(context
Ok(value) .builder()
.build_int_z_extend(
value.into_int_value(),
context.word_type(),
"call_data_size_value",
)?
.into())
} }
/// Translates the calldata copy. /// Translates the calldata copy.
@@ -51,20 +50,19 @@ pub fn copy<'ctx, D>(
where where
D: Dependency + Clone, D: Dependency + Clone,
{ {
let offset = context.safe_truncate_int_to_xlen(destination_offset)?; let source_offset = context.safe_truncate_int_to_xlen(source_offset)?;
let size = context.safe_truncate_int_to_xlen(size)?; let size = context.safe_truncate_int_to_xlen(size)?;
let destination = context.build_heap_gep(offset, size)?; let destination_offset = context.safe_truncate_int_to_xlen(destination_offset)?;
let output_pointer = context.build_heap_gep(destination_offset, size)?;
let calldata_pointer = context context.build_runtime_call(
.get_global(crate::polkavm::GLOBAL_CALLDATA_POINTER)? revive_runtime_api::polkavm_imports::CALL_DATA_COPY,
.value &[
.as_pointer_value(); output_pointer.to_int(context).into(),
let source = context.build_gep( size.into(),
Pointer::new(context.byte_type(), AddressSpace::Stack, calldata_pointer), source_offset.into(),
&[context.safe_truncate_int_to_xlen(source_offset)?], ],
context.byte_type(),
"calldata_pointer_with_offset",
); );
context.build_memcpy(destination, source, size, "calldata_copy_memcpy_from_child") Ok(())
} }
+21 -5
View File
@@ -7,22 +7,38 @@ use crate::polkavm::Dependency;
/// Translates the `gas_limit` instruction. /// Translates the `gas_limit` instruction.
pub fn gas_limit<'ctx, D>( pub fn gas_limit<'ctx, D>(
_context: &mut Context<'ctx, D>, context: &mut Context<'ctx, D>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>> ) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where where
D: Dependency + Clone, D: Dependency + Clone,
{ {
todo!() let gas_limit_value = context
.build_runtime_call(revive_runtime_api::polkavm_imports::GAS_LIMIT, &[])
.expect("the gas_limit syscall method should return a value")
.into_int_value();
Ok(context
.builder()
.build_int_z_extend(gas_limit_value, context.word_type(), "gas_limit")?
.into())
} }
/// Translates the `gas_price` instruction. /// Translates the `gas_price` instruction.
pub fn gas_price<'ctx, D>( pub fn gas_price<'ctx, D>(
_context: &mut Context<'ctx, D>, context: &mut Context<'ctx, D>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>> ) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
where where
D: Dependency + Clone, D: Dependency + Clone,
{ {
todo!() let gas_price_value = context
.build_runtime_call(revive_runtime_api::polkavm_imports::GAS_PRICE, &[])
.expect("the gas_price syscall method should return a value")
.into_int_value();
Ok(context
.builder()
.build_int_z_extend(gas_price_value, context.word_type(), "gas_price")?
.into())
} }
/// Translates the `tx.origin` instruction. /// Translates the `tx.origin` instruction.
@@ -121,7 +137,7 @@ pub fn basefee<'ctx, D>(
where where
D: Dependency + Clone, D: Dependency + Clone,
{ {
Ok(context.word_const(0).as_basic_value_enum()) context.build_runtime_call_to_getter(revive_runtime_api::polkavm_imports::BASE_FEE)
} }
/// Translates the `address` instruction. /// Translates the `address` instruction.
@@ -1,7 +1,5 @@
//! Translates the value and balance operations. //! Translates the value and balance operations.
use inkwell::values::BasicValue;
use crate::polkavm::context::Context; use crate::polkavm::context::Context;
use crate::polkavm::Dependency; use crate::polkavm::Dependency;
@@ -12,7 +10,15 @@ pub fn gas<'ctx, D>(
where where
D: Dependency + Clone, D: Dependency + Clone,
{ {
Ok(context.integer_const(256, 0).as_basic_value_enum()) let ref_time_left_value = context
.build_runtime_call(revive_runtime_api::polkavm_imports::REF_TIME_LEFT, &[])
.expect("the ref_time_left syscall method should return a value")
.into_int_value();
Ok(context
.builder()
.build_int_z_extend(ref_time_left_value, context.word_type(), "gas_left")?
.into())
} }
/// Translates the `value` instruction. /// Translates the `value` instruction.
@@ -16,19 +16,20 @@ where
Some(address) => address, Some(address) => address,
None => super::context::address(context)?.into_int_value(), None => super::context::address(context)?.into_int_value(),
}; };
let address_pointer = context.build_address_argument_store(address)?; let address_pointer = context.build_address_argument_store(address)?;
let output_pointer = context.build_alloca_at_entry(context.word_type(), "output_pointer");
context.build_runtime_call( let code_size_value = context
.build_runtime_call(
revive_runtime_api::polkavm_imports::CODE_SIZE, revive_runtime_api::polkavm_imports::CODE_SIZE,
&[ &[address_pointer.to_int(context).into()],
address_pointer.to_int(context).into(), )
output_pointer.to_int(context).into(), .expect("the code_size syscall method should return a value")
], .into_int_value();
);
context.build_load(output_pointer, "code_size") Ok(context
.builder()
.build_int_z_extend(code_size_value, context.word_type(), "code_size")?
.into())
} }
/// Translates the `extcodehash` instruction. /// Translates the `extcodehash` instruction.
@@ -10,17 +10,19 @@ pub fn size<'ctx, D>(
where where
D: Dependency + Clone, D: Dependency + Clone,
{ {
let output_pointer = context.build_alloca_at_entry(context.word_type(), "return_data_size"); let return_data_size_value = context
let output_pointer_parameter = context.builder().build_ptr_to_int( .build_runtime_call(revive_runtime_api::polkavm_imports::RETURNDATASIZE, &[])
output_pointer.value, .expect("the return_data_size syscall method should return a value")
context.xlen_type(), .into_int_value();
"return_data_copy_output_pointer",
)?; Ok(context
context.build_runtime_call( .builder()
revive_runtime_api::polkavm_imports::RETURNDATASIZE, .build_int_z_extend(
&[output_pointer_parameter.into()], return_data_size_value,
); context.word_type(),
context.build_load(output_pointer, "return_data_size_load") "return_data_size",
)?
.into())
} }
/// Translates the return data copy, trapping if /// Translates the return data copy, trapping if
+2 -3
View File
@@ -4,10 +4,8 @@ pub mod r#const;
pub mod context; pub mod context;
pub mod evm; pub mod evm;
pub mod metadata_hash; pub mod metadata_hash;
pub mod utils;
pub use self::r#const::*; pub use self::r#const::*;
use self::utils::keccak256;
use crate::debug_config::DebugConfig; use crate::debug_config::DebugConfig;
use crate::optimizer::settings::Settings as OptimizerSettings; use crate::optimizer::settings::Settings as OptimizerSettings;
@@ -15,6 +13,7 @@ use crate::optimizer::settings::Settings as OptimizerSettings;
use anyhow::Context as AnyhowContext; use anyhow::Context as AnyhowContext;
use polkavm_common::program::ProgramBlob; use polkavm_common::program::ProgramBlob;
use polkavm_disassembler::{Disassembler, DisassemblyFormat}; use polkavm_disassembler::{Disassembler, DisassemblyFormat};
use sha3::Digest;
use self::context::build::Build; use self::context::build::Build;
use self::context::Context; use self::context::Context;
@@ -55,7 +54,7 @@ pub fn build_assembly_text(
assembly_text.to_owned(), assembly_text.to_owned(),
metadata_hash, metadata_hash,
bytecode.to_owned(), bytecode.to_owned(),
keccak256(bytecode), hex::encode(sha3::Keccak256::digest(bytecode)),
)) ))
} }
-60
View File
@@ -1,60 +0,0 @@
//! Some LLVM IR generator utilies.
use crate::polkavm::context::Context;
use crate::polkavm::Dependency;
/// Clamps `value` to `max_value`, if `value` is bigger than `max_value`.
pub fn clamp<'ctx, D>(
context: &mut Context<'ctx, D>,
value: inkwell::values::IntValue<'ctx>,
max_value: inkwell::values::IntValue<'ctx>,
name: &str,
) -> anyhow::Result<inkwell::values::IntValue<'ctx>>
where
D: Dependency + Clone,
{
let in_bounds_block = context.append_basic_block(format!("{name}_is_bounds_block").as_str());
let join_block = context.append_basic_block(format!("{name}_join_block").as_str());
let pointer = context.build_alloca(context.word_type(), format!("{name}_pointer").as_str());
context.build_store(pointer, max_value)?;
let is_in_bounds = context.builder().build_int_compare(
inkwell::IntPredicate::ULE,
value,
max_value,
format!("{name}_is_in_bounds").as_str(),
)?;
context.build_conditional_branch(is_in_bounds, in_bounds_block, join_block)?;
context.set_basic_block(in_bounds_block);
context.build_store(pointer, value)?;
context.build_unconditional_branch(join_block);
context.set_basic_block(join_block);
let result = context.build_load(pointer, name)?;
Ok(result.into_int_value())
}
/// Computes the `keccak256` hash for `preimage`.
pub fn keccak256(preimage: &[u8]) -> String {
use sha3::Digest;
let hash_bytes = sha3::Keccak256::digest(preimage);
hash_bytes
.into_iter()
.map(|byte| format!("{byte:02x}"))
.collect::<Vec<String>>()
.join("")
}
#[cfg(test)]
mod tests {
#[test]
fn keccak256() {
assert_eq!(
super::keccak256("zksync".as_bytes()),
"0238fb1ab06c28c32885f9a4842207ac480c2467df26b6c58e201679628c5a5b"
);
}
}
+2 -20
View File
@@ -20,28 +20,16 @@ pub struct TargetMachine {
impl TargetMachine { impl TargetMachine {
/// The LLVM target name. /// The LLVM target name.
#[cfg(not(feature = "riscv-64"))]
pub const VM_TARGET_NAME: &'static str = "riscv32";
#[cfg(feature = "riscv-64")]
pub const VM_TARGET_NAME: &'static str = "riscv64"; pub const VM_TARGET_NAME: &'static str = "riscv64";
/// The LLVM target triple. /// The LLVM target triple.
#[cfg(not(feature = "riscv-64"))]
pub const VM_TARGET_TRIPLE: &'static str = "riscv32-unknown-unknown-elf";
#[cfg(feature = "riscv-64")]
pub const VM_TARGET_TRIPLE: &'static str = "riscv64-unknown-unknown-elf"; pub const VM_TARGET_TRIPLE: &'static str = "riscv64-unknown-unknown-elf";
/// The LLVM target cpu
#[cfg(not(feature = "riscv-64"))]
pub const VM_TARGET_CPU: &'static str = "generic-rv32";
#[cfg(feature = "riscv-64")]
pub const VM_TARGET_CPU: &'static str = "generic-rv64"; pub const VM_TARGET_CPU: &'static str = "generic-rv64";
/// LLVM target features. /// LLVM target features.
#[cfg(feature = "riscv-zbb")] pub const VM_FEATURES: &'static str =
pub const VM_FEATURES: &'static str = "+zbb,+a,+e,+m,+c,+fast-unaligned-access,+xtheadcondmov"; "+e,+m,+a,+c,+zbb,+auipc-addi-fusion,+ld-add-fusion,+lui-addi-fusion,+xtheadcondmov";
#[cfg(not(feature = "riscv-zbb"))]
pub const VM_FEATURES: &'static str = "+a,+e,+m,+c,+fast-unaligned-access,+xtheadcondmov";
/// A shortcut constructor. /// A shortcut constructor.
/// A separate instance for every optimization level is created. /// A separate instance for every optimization level is created.
@@ -70,12 +58,6 @@ impl TargetMachine {
}) })
} }
/// Sets the target-specific data in the module.
pub fn set_target_data(&self, module: &inkwell::module::Module) {
module.set_triple(&self.target_machine.get_triple());
module.set_data_layout(&self.target_machine.get_target_data().get_data_layout());
}
/// Writes the LLVM module to a memory buffer. /// Writes the LLVM module to a memory buffer.
pub fn write_to_memory_buffer( pub fn write_to_memory_buffer(
&self, &self,
@@ -13,9 +13,6 @@ impl Target {
/// Returns the target name. /// Returns the target name.
pub fn name(&self) -> &str { pub fn name(&self) -> &str {
match self { match self {
#[cfg(not(feature = "riscv-64"))]
Self::PVM => "riscv32",
#[cfg(feature = "riscv-64")]
Self::PVM => "riscv64", Self::PVM => "riscv64",
} }
} }
@@ -23,9 +20,6 @@ impl Target {
/// Returns the target triple. /// Returns the target triple.
pub fn triple(&self) -> &str { pub fn triple(&self) -> &str {
match self { match self {
#[cfg(not(feature = "riscv-64"))]
Self::PVM => "riscv32-unknown-unknown-elf",
#[cfg(feature = "riscv-64")]
Self::PVM => "riscv64-unknown-unknown-elf", Self::PVM => "riscv64-unknown-unknown-elf",
} }
} }
@@ -43,9 +37,6 @@ impl FromStr for Target {
fn from_str(string: &str) -> Result<Self, Self::Err> { fn from_str(string: &str) -> Result<Self, Self::Err> {
match string { match string {
#[cfg(not(feature = "riscv-64"))]
"riscv32" => Ok(Self::PVM),
#[cfg(feature = "riscv-64")]
"riscv64" => Ok(Self::PVM), "riscv64" => Ok(Self::PVM),
_ => Err(anyhow::anyhow!( _ => Err(anyhow::anyhow!(
"Unknown target `{}`. Supported targets: {:?}", "Unknown target `{}`. Supported targets: {:?}",
@@ -59,9 +50,6 @@ impl FromStr for Target {
impl std::fmt::Display for Target { impl std::fmt::Display for Target {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
#[cfg(not(feature = "riscv-64"))]
Target::PVM => write!(f, "riscv32"),
#[cfg(feature = "riscv-64")]
Target::PVM => write!(f, "riscv64"), Target::PVM => write!(f, "riscv64"),
} }
} }
Binary file not shown.
+1 -1
View File
@@ -55,7 +55,7 @@ pub const BOB: H160 = H160([2u8; 20]);
/// The charlie test account /// The charlie test account
pub const CHARLIE: H160 = H160([3u8; 20]); pub const CHARLIE: H160 = H160([3u8; 20]);
/// Default gas limit /// Default gas limit
pub const GAS_LIMIT: Weight = Weight::from_parts(100_000_000_000, 3 * 1024 * 1024); pub const GAS_LIMIT: Weight = Weight::from_parts(100_000_000_000_000, 3 * 1024 * 1024 * 1024);
/// Default deposit limit /// Default deposit limit
pub const DEPOSIT_LIMIT: Balance = 10_000_000; pub const DEPOSIT_LIMIT: Balance = 10_000_000;
+6 -1
View File
@@ -1,4 +1,4 @@
use frame_support::runtime; use frame_support::{runtime, weights::constants::WEIGHT_REF_TIME_PER_SECOND};
use pallet_revive::AccountId32Mapper; use pallet_revive::AccountId32Mapper;
use polkadot_sdk::*; use polkadot_sdk::*;
@@ -46,6 +46,7 @@ mod runtime {
#[derive_impl(frame_system::config_preludes::SolochainDefaultConfig)] #[derive_impl(frame_system::config_preludes::SolochainDefaultConfig)]
impl frame_system::Config for Runtime { impl frame_system::Config for Runtime {
type Block = Block; type Block = Block;
type BlockWeights = BlockWeights;
type AccountId = AccountId32; type AccountId = AccountId32;
type AccountData = pallet_balances::AccountData<<Runtime as pallet_balances::Config>::Balance>; type AccountData = pallet_balances::AccountData<<Runtime as pallet_balances::Config>::Balance>;
} }
@@ -65,6 +66,10 @@ parameter_types! {
pub const DepositPerByte: Balance = 1; pub const DepositPerByte: Balance = 1;
pub const DepositPerItem: Balance = 2; pub const DepositPerItem: Balance = 2;
pub const CodeHashLockupDepositPercent: Perbill = Perbill::from_percent(0); pub const CodeHashLockupDepositPercent: Perbill = Perbill::from_percent(0);
pub BlockWeights: frame_system::limits::BlockWeights =
frame_system::limits::BlockWeights::simple_max(
Weight::from_parts(2u64 * WEIGHT_REF_TIME_PER_SECOND, u64::MAX),
);
} }
#[derive_impl(pallet_revive::config_preludes::TestDefaultConfig)] #[derive_impl(pallet_revive::config_preludes::TestDefaultConfig)]
+2 -2
View File
@@ -421,7 +421,7 @@ impl Specs {
origin, origin,
value, value,
gas_limit.unwrap_or(GAS_LIMIT), gas_limit.unwrap_or(GAS_LIMIT),
storage_deposit_limit.unwrap_or(DEPOSIT_LIMIT), storage_deposit_limit.unwrap_or(DEPOSIT_LIMIT).into(),
code, code,
data, data,
salt.0, salt.0,
@@ -461,7 +461,7 @@ impl Specs {
dest.to_eth_addr(&results), dest.to_eth_addr(&results),
value, value,
gas_limit.unwrap_or(GAS_LIMIT), gas_limit.unwrap_or(GAS_LIMIT),
storage_deposit_limit.unwrap_or(DEPOSIT_LIMIT), storage_deposit_limit.unwrap_or(DEPOSIT_LIMIT).into(),
data, data,
DebugInfo::Skip, DebugInfo::Skip,
CollectEvents::Skip, CollectEvents::Skip,
-3
View File
@@ -7,9 +7,6 @@ repository.workspace = true
authors.workspace = true authors.workspace = true
description = "Implements the low level runtime API bindings with pallet contracts" description = "Implements the low level runtime API bindings with pallet contracts"
[features]
riscv-64 = []
[dependencies] [dependencies]
anyhow = { workspace = true } anyhow = { workspace = true }
inkwell = { workspace = true, features = ["target-riscv", "no-libffi-linking", "llvm18-0"] } inkwell = { workspace = true, features = ["target-riscv", "no-libffi-linking", "llvm18-0"] }
-15
View File
@@ -1,23 +1,8 @@
use std::{env, fs, path::Path, process::Command}; use std::{env, fs, path::Path, process::Command};
#[cfg(not(feature = "riscv-64"))]
const TARGET_TRIPLE_FLAG: &str = "-triple=riscv32-unknown-unknown-elf";
#[cfg(feature = "riscv-64")]
const TARGET_TRIPLE_FLAG: &str = "-triple=riscv64-unknown-unknown-elf"; const TARGET_TRIPLE_FLAG: &str = "-triple=riscv64-unknown-unknown-elf";
#[cfg(not(feature = "riscv-64"))]
const TARGET_FLAG: &str = "--target=riscv32";
#[cfg(feature = "riscv-64")]
const TARGET_FLAG: &str = "--target=riscv64"; const TARGET_FLAG: &str = "--target=riscv64";
#[cfg(not(feature = "riscv-64"))]
const TARGET_ARCH_FLAG: &str = "-march=rv32emac";
#[cfg(feature = "riscv-64")]
const TARGET_ARCH_FLAG: &str = "-march=rv64emac"; const TARGET_ARCH_FLAG: &str = "-march=rv64emac";
#[cfg(not(feature = "riscv-64"))]
const TARGET_ABI_FLAG: &str = "-mabi=ilp32e";
#[cfg(feature = "riscv-64")]
const TARGET_ABI_FLAG: &str = "-mabi=lp64e"; const TARGET_ABI_FLAG: &str = "-mabi=lp64e";
const IMPORTS_SOUCE: &str = "src/polkavm_imports.c"; const IMPORTS_SOUCE: &str = "src/polkavm_imports.c";
+22 -22
View File
@@ -52,29 +52,29 @@ pub fn instantiate(context: &Context) -> StructType {
context.struct_type( context.struct_type(
&[ &[
// code_hash_ptr: u32, // code_hash_ptr: u32,
context.ptr_type(Default::default()).as_basic_type_enum(), context.i32_type().as_basic_type_enum(),
// ref_time_limit: u64, // ref_time_limit: u64,
context.i64_type().as_basic_type_enum(), context.i64_type().as_basic_type_enum(),
// proof_size_limit: u64, // proof_size_limit: u64,
context.i64_type().as_basic_type_enum(), context.i64_type().as_basic_type_enum(),
// deposit_ptr: u32, // deposit_ptr: u32,
context.ptr_type(Default::default()).as_basic_type_enum(), context.i32_type().as_basic_type_enum(),
// value_ptr: u32, // value_ptr: u32,
context.ptr_type(Default::default()).as_basic_type_enum(), context.i32_type().as_basic_type_enum(),
// input_data_ptr: u32, // input_data_ptr: u32,
context.ptr_type(Default::default()).as_basic_type_enum(), context.i32_type().as_basic_type_enum(),
// input_data_len: u32, // input_data_len: u32,
context.i32_type().as_basic_type_enum(), context.i32_type().as_basic_type_enum(),
// address_ptr: u32, // address_ptr: u32,
context.ptr_type(Default::default()).as_basic_type_enum(), context.i32_type().as_basic_type_enum(),
// output_ptr: u32, // output_ptr: u32,
context.ptr_type(Default::default()).as_basic_type_enum(), context.i32_type().as_basic_type_enum(),
// output_len_ptr: u32, // output_len_ptr: u32,
context.ptr_type(Default::default()).as_basic_type_enum(), context.i32_type().as_basic_type_enum(),
// salt_ptr: u32, // salt_ptr: u32,
context.ptr_type(Default::default()).as_basic_type_enum(), context.i32_type().as_basic_type_enum(),
], ],
true, false,
) )
} }
@@ -85,25 +85,25 @@ pub fn call(context: &Context) -> StructType {
// flags: u32, // flags: u32,
context.i32_type().as_basic_type_enum(), context.i32_type().as_basic_type_enum(),
// address_ptr: // address_ptr:
context.ptr_type(Default::default()).as_basic_type_enum(), context.i32_type().as_basic_type_enum(),
// ref_time_limit: u64, // ref_time_limit: u64,
context.i64_type().as_basic_type_enum(), context.i64_type().as_basic_type_enum(),
// proof_size_limit: u64, // proof_size_limit: u64,
context.i64_type().as_basic_type_enum(), context.i64_type().as_basic_type_enum(),
// deposit_ptr: u32, // deposit_ptr: u32,
context.ptr_type(Default::default()).as_basic_type_enum(), context.i32_type().as_basic_type_enum(),
// value_ptr: u32, // value_ptr: u32,
context.ptr_type(Default::default()).as_basic_type_enum(), context.i32_type().as_basic_type_enum(),
// input_data_ptr: u32, // input_data_ptr: u32,
context.ptr_type(Default::default()).as_basic_type_enum(), context.i32_type().as_basic_type_enum(),
// input_data_len: u32, // input_data_len: u32,
context.i32_type().as_basic_type_enum(), context.i32_type().as_basic_type_enum(),
// output_ptr: u32, // output_ptr: u32,
context.ptr_type(Default::default()).as_basic_type_enum(), context.i32_type().as_basic_type_enum(),
// output_len_ptr: u32, // output_len_ptr: u32,
context.ptr_type(Default::default()).as_basic_type_enum(), context.i32_type().as_basic_type_enum(),
], ],
true, false,
) )
} }
@@ -114,22 +114,22 @@ pub fn delegate_call(context: &Context) -> StructType {
// flags: u32, // flags: u32,
context.i32_type().as_basic_type_enum(), context.i32_type().as_basic_type_enum(),
// address_ptr: // address_ptr:
context.ptr_type(Default::default()).as_basic_type_enum(), context.i32_type().as_basic_type_enum(),
// ref_time_limit: u64, // ref_time_limit: u64,
context.i64_type().as_basic_type_enum(), context.i64_type().as_basic_type_enum(),
// proof_size_limit: u64, // proof_size_limit: u64,
context.i64_type().as_basic_type_enum(), context.i64_type().as_basic_type_enum(),
// deposit_ptr: u32, // deposit_ptr: u32,
context.ptr_type(Default::default()).as_basic_type_enum(), context.i32_type().as_basic_type_enum(),
// input_data_ptr: u32, // input_data_ptr: u32,
context.ptr_type(Default::default()).as_basic_type_enum(), context.i32_type().as_basic_type_enum(),
// input_data_len: u32, // input_data_len: u32,
context.i32_type().as_basic_type_enum(), context.i32_type().as_basic_type_enum(),
// output_ptr: u32, // output_ptr: u32,
context.ptr_type(Default::default()).as_basic_type_enum(), context.i32_type().as_basic_type_enum(),
// output_len_ptr: u32, // output_len_ptr: u32,
context.ptr_type(Default::default()).as_basic_type_enum(), context.i32_type().as_basic_type_enum(),
], ],
true, false,
) )
} }
+23 -9
View File
@@ -70,33 +70,43 @@ POLKAVM_IMPORT(void, balance, uint32_t)
POLKAVM_IMPORT(void, balance_of, uint32_t, uint32_t) POLKAVM_IMPORT(void, balance_of, uint32_t, uint32_t)
POLKAVM_IMPORT(void, base_fee, uint32_t)
POLKAVM_IMPORT(void, block_hash, uint32_t, uint32_t) POLKAVM_IMPORT(void, block_hash, uint32_t, uint32_t)
POLKAVM_IMPORT(void, block_number, uint32_t) POLKAVM_IMPORT(void, block_number, uint32_t)
POLKAVM_IMPORT(uint32_t, call, uint32_t) POLKAVM_IMPORT(uint64_t, call, uint32_t)
POLKAVM_IMPORT(uint32_t, delegate_call, uint32_t) POLKAVM_IMPORT(uint64_t, call_data_copy, uint32_t, uint32_t, uint32_t)
POLKAVM_IMPORT(uint64_t, call_data_load, uint32_t, uint32_t)
POLKAVM_IMPORT(uint64_t, call_data_size)
POLKAVM_IMPORT(void, caller, uint32_t) POLKAVM_IMPORT(void, caller, uint32_t)
POLKAVM_IMPORT(void, chain_id, uint32_t) POLKAVM_IMPORT(void, chain_id, uint32_t)
POLKAVM_IMPORT(uint32_t, code_size, uint32_t, uint32_t) POLKAVM_IMPORT(uint64_t, code_size, uint32_t)
POLKAVM_IMPORT(void, code_hash, uint32_t, uint32_t) POLKAVM_IMPORT(void, code_hash, uint32_t, uint32_t)
POLKAVM_IMPORT(uint64_t, delegate_call, uint32_t)
POLKAVM_IMPORT(void, deposit_event, uint32_t, uint32_t, uint32_t, uint32_t) POLKAVM_IMPORT(void, deposit_event, uint32_t, uint32_t, uint32_t, uint32_t)
POLKAVM_IMPORT(uint64_t, gas_limit);
POLKAVM_IMPORT(uint64_t, gas_price);
POLKAVM_IMPORT(void, get_immutable_data, uint32_t, uint32_t); POLKAVM_IMPORT(void, get_immutable_data, uint32_t, uint32_t);
POLKAVM_IMPORT(uint32_t, get_storage, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t) POLKAVM_IMPORT(uint64_t, get_storage, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t)
POLKAVM_IMPORT(void, hash_keccak_256, uint32_t, uint32_t, uint32_t) POLKAVM_IMPORT(void, hash_keccak_256, uint32_t, uint32_t, uint32_t)
POLKAVM_IMPORT(void, input, uint32_t, uint32_t) POLKAVM_IMPORT(uint64_t, instantiate, uint32_t)
POLKAVM_IMPORT(uint32_t, instantiate, uint32_t)
POLKAVM_IMPORT(void, now, uint32_t) POLKAVM_IMPORT(void, now, uint32_t)
@@ -104,12 +114,16 @@ POLKAVM_IMPORT(void, origin, uint32_t)
POLKAVM_IMPORT(void, seal_return, uint32_t, uint32_t, uint32_t) POLKAVM_IMPORT(void, seal_return, uint32_t, uint32_t, uint32_t)
POLKAVM_IMPORT(uint32_t, set_storage, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t) POLKAVM_IMPORT(uint64_t, ref_time_left)
POLKAVM_IMPORT(void, return_data_copy, uint32_t, uint32_t, uint32_t) POLKAVM_IMPORT(void, return_data_copy, uint32_t, uint32_t, uint32_t)
POLKAVM_IMPORT(void, return_data_size, uint32_t) POLKAVM_IMPORT(uint64_t, return_data_size)
POLKAVM_IMPORT(void, set_immutable_data, uint32_t, uint32_t); POLKAVM_IMPORT(void, set_immutable_data, uint32_t, uint32_t);
POLKAVM_IMPORT(uint64_t, set_storage, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t)
POLKAVM_IMPORT(void, value_transferred, uint32_t) POLKAVM_IMPORT(void, value_transferred, uint32_t)
POLKAVM_IMPORT(void, weight_to_fee, uint64_t, uint64_t, uint32_t);
+29 -8
View File
@@ -20,13 +20,19 @@ pub static BALANCE: &str = "balance";
pub static BALANCE_OF: &str = "balance_of"; pub static BALANCE_OF: &str = "balance_of";
pub static BASE_FEE: &str = "base_fee";
pub static BLOCK_HASH: &str = "block_hash"; pub static BLOCK_HASH: &str = "block_hash";
pub static BLOCK_NUMBER: &str = "block_number"; pub static BLOCK_NUMBER: &str = "block_number";
pub static CALL: &str = "call"; pub static CALL: &str = "call";
pub static DELEGATE_CALL: &str = "delegate_call"; pub static CALL_DATA_COPY: &str = "call_data_copy";
pub static CALL_DATA_LOAD: &str = "call_data_load";
pub static CALL_DATA_SIZE: &str = "call_data_size";
pub static CALLER: &str = "caller"; pub static CALLER: &str = "caller";
@@ -36,25 +42,29 @@ pub static CODE_SIZE: &str = "code_size";
pub static CODE_HASH: &str = "code_hash"; pub static CODE_HASH: &str = "code_hash";
pub static DELEGATE_CALL: &str = "delegate_call";
pub static DEPOSIT_EVENT: &str = "deposit_event"; pub static DEPOSIT_EVENT: &str = "deposit_event";
pub static GAS_LIMIT: &str = "gas_limit";
pub static GAS_PRICE: &str = "gas_price";
pub static GET_IMMUTABLE_DATA: &str = "get_immutable_data"; pub static GET_IMMUTABLE_DATA: &str = "get_immutable_data";
pub static GET_STORAGE: &str = "get_storage"; pub static GET_STORAGE: &str = "get_storage";
pub static HASH_KECCAK_256: &str = "hash_keccak_256"; pub static HASH_KECCAK_256: &str = "hash_keccak_256";
pub static INPUT: &str = "input";
pub static INSTANTIATE: &str = "instantiate"; pub static INSTANTIATE: &str = "instantiate";
pub static NOW: &str = "now"; pub static NOW: &str = "now";
pub static ORIGIN: &str = "origin"; pub static ORIGIN: &str = "origin";
pub static RETURN: &str = "seal_return"; pub static REF_TIME_LEFT: &str = "ref_time_left";
pub static SET_STORAGE: &str = "set_storage"; pub static RETURN: &str = "seal_return";
pub static RETURNDATACOPY: &str = "return_data_copy"; pub static RETURNDATACOPY: &str = "return_data_copy";
@@ -62,38 +72,49 @@ pub static RETURNDATASIZE: &str = "return_data_size";
pub static SET_IMMUTABLE_DATA: &str = "set_immutable_data"; pub static SET_IMMUTABLE_DATA: &str = "set_immutable_data";
pub static SET_STORAGE: &str = "set_storage";
pub static VALUE_TRANSFERRED: &str = "value_transferred"; pub static VALUE_TRANSFERRED: &str = "value_transferred";
pub static WEIGHT_TO_FEE: &str = "weight_to_fee";
/// All imported runtime API symbols. /// All imported runtime API symbols.
/// Useful for configuring common attributes and linkage. /// Useful for configuring common attributes and linkage.
pub static IMPORTS: [&str; 27] = [ pub static IMPORTS: [&str; 34] = [
SBRK, SBRK,
MEMORY_SIZE, MEMORY_SIZE,
ADDRESS, ADDRESS,
BALANCE, BALANCE,
BALANCE_OF, BALANCE_OF,
BASE_FEE,
BLOCK_HASH, BLOCK_HASH,
BLOCK_NUMBER, BLOCK_NUMBER,
CALL, CALL,
DELEGATE_CALL, CALL_DATA_COPY,
CALL_DATA_LOAD,
CALL_DATA_SIZE,
CALLER, CALLER,
CHAIN_ID, CHAIN_ID,
CODE_SIZE, CODE_SIZE,
CODE_HASH, CODE_HASH,
DELEGATE_CALL,
DEPOSIT_EVENT, DEPOSIT_EVENT,
GAS_LIMIT,
GAS_PRICE,
GET_IMMUTABLE_DATA, GET_IMMUTABLE_DATA,
GET_STORAGE, GET_STORAGE,
HASH_KECCAK_256, HASH_KECCAK_256,
INPUT,
INSTANTIATE, INSTANTIATE,
NOW, NOW,
ORIGIN, ORIGIN,
REF_TIME_LEFT,
RETURN, RETURN,
RETURNDATACOPY, RETURNDATACOPY,
RETURNDATASIZE, RETURNDATASIZE,
SET_IMMUTABLE_DATA, SET_IMMUTABLE_DATA,
SET_STORAGE, SET_STORAGE,
VALUE_TRANSFERRED, VALUE_TRANSFERRED,
WEIGHT_TO_FEE,
]; ];
/// Creates a LLVM module from the [BITCODE]. /// Creates a LLVM module from the [BITCODE].
+3
View File
@@ -48,6 +48,9 @@ mimalloc = { version = "*", default-features = false }
libc = { workspace = true } libc = { workspace = true }
inkwell = { workspace = true, features = ["target-riscv", "llvm18-0-no-llvm-linking"]} inkwell = { workspace = true, features = ["target-riscv", "llvm18-0-no-llvm-linking"]}
[build-dependencies]
git2 = { workspace = true }
[features] [features]
parallel = ["rayon"] parallel = ["rayon"]
default = ["parallel"] default = ["parallel"]
+5 -7
View File
@@ -1,9 +1,7 @@
fn main() { fn main() {
let git_rev = std::process::Command::new("git") let repo = git2::Repository::open("../..").expect("should be a repository");
.args(["rev-parse", "--short", "HEAD"]) let head = repo.head().expect("should have head");
.output() let commit = head.peel_to_commit().expect("should have commit");
.map(|out| String::from_utf8(out.stdout).unwrap_or_default()) let id = &commit.id().to_string()[..7];
.unwrap_or("unknown".to_owned()); println!("cargo:rustc-env=GIT_COMMIT_HASH={id}");
println!("cargo:rustc-env=GIT_COMMIT_HASH={}", git_rev.trim());
} }
+2 -1
View File
@@ -8,6 +8,7 @@ use std::collections::HashSet;
use serde::Deserialize; use serde::Deserialize;
use serde::Serialize; use serde::Serialize;
use sha3::Digest;
use crate::evmla::ethereal_ir::entry_link::EntryLink; use crate::evmla::ethereal_ir::entry_link::EntryLink;
use crate::evmla::ethereal_ir::EtherealIR; use crate::evmla::ethereal_ir::EtherealIR;
@@ -45,7 +46,7 @@ impl Assembly {
/// Gets the contract `keccak256` hash. /// Gets the contract `keccak256` hash.
pub fn keccak256(&self) -> String { pub fn keccak256(&self) -> String {
let json = serde_json::to_vec(self).expect("Always valid"); let json = serde_json::to_vec(self).expect("Always valid");
revive_llvm_context::polkavm_utils::keccak256(json.as_slice()) hex::encode(sha3::Keccak256::digest(json.as_slice()))
} }
/// Sets the full contract path. /// Sets the full contract path.
@@ -1163,7 +1163,7 @@ where
self.name.as_str(), self.name.as_str(),
function_type, function_type,
output_size, output_size,
Some(inkwell::module::Linkage::Private), Some(inkwell::module::Linkage::External),
)?; )?;
function function
.borrow_mut() .borrow_mut()
@@ -35,10 +35,9 @@ impl Error {
let message = r#" let message = r#"
Warning: It looks like you are using 'ecrecover' to validate a signature of a user account. Warning: It looks like you are using 'ecrecover' to validate a signature of a user account.
zkSync Era comes with native account abstraction support, therefore it is highly recommended NOT Polkadot comes with native account abstraction support, therefore it is highly recommended NOT
to rely on the fact that the account has an ECDSA private key attached to it since accounts might to rely on the fact that the account has an ECDSA private key attached to it since accounts might
implement other signature schemes. implement other signature schemes.
Read more about Account Abstraction at https://v2-docs.zksync.io/dev/developer-guides/aa.html │
"# "#
.to_owned(); .to_owned();
@@ -109,10 +108,9 @@ impl Error {
let message = r#" let message = r#"
Warning: You are checking for 'tx.origin' in your code, which might lead to unexpected behavior. Warning: You are checking for 'tx.origin' in your code, which might lead to unexpected behavior.
zkSync Era comes with native account abstraction support, and therefore the initiator of a Polkadot comes with native account abstraction support, and therefore the initiator of a
transaction might be different from the contract calling your code. It is highly recommended NOT transaction might be different from the contract calling your code. It is highly recommended NOT
to rely on tx.origin, but use msg.sender instead. to rely on tx.origin, but use msg.sender instead.
Read more about Account Abstraction at https://v2-docs.zksync.io/dev/developer-guides/aa.html │
"# "#
.to_owned(); .to_owned();
@@ -202,8 +202,8 @@ pub enum Name {
/// size of memory, i.e. largest accessed memory index /// size of memory, i.e. largest accessed memory index
MSize, MSize,
/// verbatim instruction with 0 inputs and 0 outputs /// verbatim instruction with 0 inputs and 0 outputs only works in the Yul mode,
/// only works in the Yul mode, so it is mostly used as a tool for extending Yul for zkSync /// so it is mostly used as a tool for extending Yul for PolkaVM
Verbatim { Verbatim {
/// the number of input arguments /// the number of input arguments
input_size: usize, input_size: usize,
@@ -211,7 +211,7 @@ where
self.identifier.as_str(), self.identifier.as_str(),
function_type, function_type,
self.result.len(), self.result.len(),
Some(inkwell::module::Linkage::Private), Some(inkwell::module::Linkage::External),
)?; )?;
revive_llvm_context::PolkaVMFunction::set_attributes( revive_llvm_context::PolkaVMFunction::set_attributes(
context.llvm(), context.llvm(),
+2 -2
View File
@@ -1,7 +1,7 @@
; Adapted from: https://github.com/matter-labs/era-compiler-llvm/blob/v1.4.0/llvm/lib/Target/EraVM/eravm-stdlib.ll ; Adapted from: https://github.com/matter-labs/era-compiler-llvm/blob/v1.4.0/llvm/lib/Target/EraVM/eravm-stdlib.ll
target datalayout = "e-m:e-p:32:32-i64:64-n32-S128" target datalayout = "e-m:e-p:32:64-p1:32:64-i64:64-i128:128-n32:64-S64"
target triple = "riscv32-unknown-unknown-elf" target triple = "riscv64-unknown-none-elf"
define i256 @__addmod(i256 %arg1, i256 %arg2, i256 %modulo) #4 { define i256 @__addmod(i256 %arg1, i256 %arg2, i256 %modulo) #4 {
entry: entry:
+26 -21
View File
@@ -1,47 +1,52 @@
var Module = { var Module = {
stdinData: "", stdinData: null,
stdoutCallback: null, stdinDataPosition: 0,
stderrCallback: null, stdoutData: [],
stderrData: [],
// Function to set a callback for stdout // Function to read and return all collected stdout data as a string
setStdoutCallback: function(callback) { readFromStdout: function() {
this.stdoutCallback = callback; if (!this.stdoutData.length) return "";
const decoder = new TextDecoder('utf-8');
const data = decoder.decode(new Uint8Array(this.stdoutData));
this.stdoutData = [];
return data;
}, },
// Function to set a callback for stderr // Function to read and return all collected stderr data as a string
setStderrCallback: function(callback) { readFromStderr: function() {
this.stderrCallback = callback; if (!this.stderrData.length) return "";
const decoder = new TextDecoder('utf-8');
const data = decoder.decode(new Uint8Array(this.stderrData));
this.stderrData = [];
return data;
}, },
// Function to set input data for stdin // Function to set input data for stdin
setStdinData: function(data) { writeToStdin: function(data) {
this.stdinData = data; const encoder = new TextEncoder();
this.stdinData = encoder.encode(data);
this.stdinDataPosition = 0;
}, },
// `preRun` is called before the program starts running // `preRun` is called before the program starts running
preRun: function() { preRun: function() {
// Define a custom stdin function // Define a custom stdin function
function customStdin() { function customStdin() {
if (Module.stdinData.length === 0) { if (!Module.stdinData || Module.stdinDataPosition >= Module.stdinData.length) {
return null; // End of input (EOF) return null; // End of input (EOF)
} }
const char = Module.stdinData.charCodeAt(0); return Module.stdinData[Module.stdinDataPosition++];
Module.stdinData = Module.stdinData.slice(1); // Remove the character from input
return char;
} }
// Define a custom stdout function // Define a custom stdout function
function customStdout(char) { function customStdout(char) {
if (Module.stdoutCallback) { Module.stdoutData.push(char);
Module.stdoutCallback(String.fromCharCode(char));
}
} }
// Define a custom stderr function // Define a custom stderr function
function customStderr(char) { function customStderr(char) {
if (Module.stderrCallback) { Module.stderrData.push(char);
Module.stderrCallback(String.fromCharCode(char));
}
} }
FS.init(customStdin, customStdout, customStderr); FS.init(customStdin, customStdout, customStderr);
+28 -46
View File
@@ -1,60 +1,42 @@
mergeInto(LibraryManager.library, { mergeInto(LibraryManager.library, {
soljson_compile: function(inputPtr, inputLen) { soljson_compile: function(inputPtr, inputLen) {
const inputJson = UTF8ToString(inputPtr, inputLen); const inputJson = UTF8ToString(inputPtr, inputLen);
const output = Module.solc.compile(inputJson) const output = Module.soljson.cwrap('solidity_compile', 'string', ['string'])(inputJson);
return stringToNewUTF8(output) return stringToNewUTF8(output);
}, },
soljson_version: function() { soljson_version: function() {
var version = Module.solc.version(); const version = Module.soljson.cwrap("solidity_version", "string", [])();
return stringToNewUTF8(version) return stringToNewUTF8(version);
}, },
resolc_compile: function(inputPtr, inputLen) { resolc_compile: function(inputPtr, inputLen) {
const { Worker } = require('worker_threads'); const inputJson = UTF8ToString(inputPtr, inputLen);
const deasync = require('deasync');
var inputJson = UTF8ToString(inputPtr, inputLen); // Check if running in a web worker or node.js
if (typeof importScripts === 'function') {
function compileWithWorker(inputJson, callback) { // Running in a web worker
return new Promise((resolve, reject) => { importScripts('./resolc.js');
const worker = new Worker(new URL('./worker.js', import.meta.url), { var revive = createRevive()
type: 'module', } else if (typeof require === 'function') {
}); // Running in Node.js
const path = require('path');
// Listen for messages from the worker createRevive = require(path.resolve(__dirname, './resolc.js'));
worker.on('message', (message) => { var revive = createRevive();
resolve(message.output); // Resolve the promise with the output } else {
callback(null, message.output); throw new Error('Unknown environment: Unable to load resolc.js');
worker.terminate(); // Terminate the worker after processing
});
// Listen for errors from the worker
worker.on('error', (error) => {
reject(error);
callback(error);
worker.terminate();
});
// Send the input JSON to the worker
worker.postMessage(inputJson);
});
} }
let result = null; revive.writeToStdin(inputJson);
let error = null;
// Use deasync to block until promise resolves // Call main on the new instance
compileWithWorker(inputJson, function (err, res) { const result = revive.callMain(['--recursive-process']);
error = err;
result = res;
});
// TODO: deasync is not present in browsers, another solution needs to be implemented
deasync.loopWhile(() => result === null && error === null);
if (error) { if (result) {
const errorJson = JSON.stringify({ type: 'error', message: error.message || "Unknown error" }); const stderrString = revive.readFromStderr();
return stringToNewUTF8(errorJson) const error = JSON.stringify({ type: 'error', message: stderrString || "Unknown error" });
return stringToNewUTF8(error);
} else {
const stdoutString = revive.readFromStdout();
const json = JSON.stringify({ type: 'success', data: stdoutString });
return stringToNewUTF8(json);
} }
const resultJson = JSON.stringify({ type: 'success', data: result });
return stringToNewUTF8(resultJson);
}, },
}); });
+1
View File
@@ -0,0 +1 @@
../../../target/wasm32-unknown-emscripten/release/resolc.js
+1
View File
@@ -0,0 +1 @@
../../../target/wasm32-unknown-emscripten/release/resolc.wasm
@@ -1,6 +1,5 @@
import solc from 'solc'; const soljson = require('solc/soljson');
// Import the Emscripten module const createRevive = require('./resolc.js');
import createRevive from './dist/revive-esm/resolc.js';
const compilerStandardJsonInput = { const compilerStandardJsonInput = {
language: 'Solidity', language: 'Solidity',
@@ -31,30 +30,16 @@ const compilerStandardJsonInput = {
}; };
async function runCompiler() { async function runCompiler() {
const m = await createRevive(); const m = createRevive();
m.solc = solc; m.soljson = soljson;
// Set input data for stdin // Set input data for stdin
m.setStdinData(JSON.stringify(compilerStandardJsonInput)); m.writeToStdin(JSON.stringify(compilerStandardJsonInput));
var stdoutString = "";
m.setStdoutCallback(function(char) {
if (char.charCodeAt(0) === '\n') {
console.log("new line")
exit
}
stdoutString += char;
});
var stderrString = "";
m.setStderrCallback(function(char) {
stderrString += char;
});
// Compile the Solidity source code // Compile the Solidity source code
let x = m.callMain(['--standard-json']); let x = m.callMain(['--standard-json']);
console.log("Stdout: " + stdoutString) console.log("Stdout: " + m.readFromStdout());
console.error("Stderr: " + stderrString) console.error("Stderr: " + m.readFromStderr());
} }
runCompiler().catch(err => { runCompiler().catch(err => {
+35
View File
@@ -0,0 +1,35 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Web Worker Example</title>
<style>
/* Ensure the pre tag wraps long lines */
pre {
white-space: pre-wrap; /* Wrap long lines */
word-wrap: break-word; /* Break long words */
max-width: 100%; /* Optional: Ensures it doesn't overflow container */
overflow-wrap: break-word; /* Another method for wrapping */
}
</style>
</head>
<body>
<h1>Revive Compilation Output</h1>
<pre id="output"></pre>
<script>
var outputElement = document.getElementById('output');
var worker = new Worker('./worker.js');
worker.addEventListener('message', function (e) {
const output = e.data.output
outputElement.textContent = output;
}, false);
worker.postMessage({
contractCode: 'contract C { function f() public { } }',
})
</script>
</body>
</html>
+1
View File
@@ -0,0 +1 @@
../../../target/wasm32-unknown-emscripten/release/resolc.js
+1
View File
@@ -0,0 +1 @@
../../../target/wasm32-unknown-emscripten/release/resolc.wasm
+38
View File
@@ -0,0 +1,38 @@
importScripts('./soljson.js');
importScripts('./resolc.js');
// Handle messages from the main thread
onmessage = async function (e) {
const contractCode = e.data.contractCode
const sourceCode = {
language: 'Solidity',
sources: {
contract: {
content: contractCode,
}
},
settings: {
optimizer: {
enabled: true,
runs: 200,
},
outputSelection: {
'*': {
'*': ['abi'],
}
}
}
};
const m = createRevive();
m.soljson = Module;
// Set input data for stdin
m.writeToStdin(JSON.stringify(sourceCode));
// Compile the Solidity source code
m.callMain(['--standard-json']);
postMessage({output: m.readFromStdout() || m.readFromStderr()});
};
+5 -13
View File
@@ -1,23 +1,15 @@
{ {
"name": "revive", "name": "revive",
"version": "1.0.0", "private": true,
"description": "Revive compiler",
"main": "run_revive.js",
"type": "module",
"dependencies": { "dependencies": {
"deasync": "^0.1.15",
"solc": "^0.8.28" "solc": "^0.8.28"
}, },
"scripts": { "scripts": {
"build": "cp ../target/wasm32-unknown-emscripten/release/resolc.js ../target/wasm32-unknown-emscripten/release/resolc.wasm ./src && npx rollup -c", "fetch:soljson": "wget https://binaries.soliditylang.org/wasm/soljson-v0.8.28+commit.7893614a.js -O ./examples/web/soljson.js",
"test": "npm run build && node run_revive.js" "example:web": "npm run fetch:soljson && http-server ./examples/web/",
"example:node": "node ./examples/node/run_revive.js"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.26.0", "http-server": "^14.1.1"
"@babel/preset-env": "^7.26.0",
"@rollup/plugin-babel": "^6.0.4",
"@rollup/plugin-node-resolve": "^15.3.0",
"rollup": "^4.27.3",
"rollup-plugin-copy": "^3.5.0"
} }
} }
-35
View File
@@ -1,35 +0,0 @@
import babel from '@rollup/plugin-babel';
import copy from 'rollup-plugin-copy';
import resolve from '@rollup/plugin-node-resolve';
const outputDirCJS = 'dist/revive-cjs';
const outputDirESM = 'dist/revive-esm';
export default {
input: ['src/resolc.js', 'src/worker.js'], // Adjust this to your main entry file
output: [
{
dir: outputDirCJS,
format: 'cjs',
exports: 'auto',
},
{
dir: outputDirESM,
format: 'esm',
},
],
plugins: [
babel({
exclude: 'node_modules/**',
presets: ['@babel/preset-env'],
babelHelpers: 'inline',
}),
resolve(),
copy({
targets: [
{ src: 'src/resolc.wasm', dest: outputDirCJS },
{ src: 'src/resolc.wasm', dest: outputDirESM },
],
})
],
};
-32
View File
@@ -1,32 +0,0 @@
import { parentPort } from 'worker_threads';
parentPort.on('message', async (inputJson) => {
const { default: createRevive } = await import(new URL('./resolc.js', import.meta.url));
const revive = await createRevive();
revive.setStdinData(inputJson);
let stdoutString = "";
revive.setStdoutCallback(function(char) {
if (char.charCodeAt(0) === '\n') {
console.log("new line")
exit
}
stdoutString += char;
});
let stderrString = "";
revive.setStderrCallback(function(char) {
stderrString += char;
});
// Call main on the new instance
const output = revive.callMain(['--recursive-process']);
if (stderrString.length > 0) {
// If /err is not empty, throw an error with its content
throw new Error(stderrString);
} else {
parentPort.postMessage({ output: stdoutString });
}
});
+1 -2
View File
@@ -3,8 +3,7 @@
"private": true, "private": true,
"scripts": { "scripts": {
"test:cli": "npm run test -w crates/solidity/src/tests/cli-tests", "test:cli": "npm run test -w crates/solidity/src/tests/cli-tests",
"build:revive": "npm run build -w js", "test:revive": "npm run example:node -w js"
"test:revive": "npm run test -w js"
}, },
"workspaces": [ "workspaces": [
"crates/solidity/src/tests/cli-tests", "crates/solidity/src/tests/cli-tests",