Compare commits

..

19 Commits

Author SHA1 Message Date
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
49 changed files with 867 additions and 938 deletions
+1 -2
View File
@@ -8,7 +8,7 @@ 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:
@@ -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
-2
View File
@@ -14,6 +14,4 @@ artifacts
tmp tmp
package-lock.json package-lock.json
/*.html /*.html
/js/src/resolc.*
/js/dist/
/build /build
+19
View File
@@ -2,6 +2,25 @@
## Unreleased ## Unreleased
## 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
+544 -551
View File
File diff suppressed because it is too large Load Diff
+18 -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.6"
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.6", path = "crates/benchmarks" }
revive-builtins = { version = "0.1.0-dev.5", path = "crates/builtins" } revive-builtins = { version = "0.1.0-dev.6", path = "crates/builtins" }
revive-common = { version = "0.1.0-dev.5", path = "crates/common" } revive-common = { version = "0.1.0-dev.6", path = "crates/common" }
revive-differential = { version = "0.1.0-dev.5", path = "crates/differential" } revive-differential = { version = "0.1.0-dev.6", path = "crates/differential" }
revive-integration = { version = "0.1.0-dev.5", path = "crates/integration" } revive-integration = { version = "0.1.0-dev.6", path = "crates/integration" }
revive-linker = { version = "0.1.0-dev.5", path = "crates/linker" } revive-linker = { version = "0.1.0-dev.6", path = "crates/linker" }
lld-sys = { version = "0.1.0-dev.5", path = "crates/lld-sys" } lld-sys = { version = "0.1.0-dev.6", 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.6", 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.6", path = "crates/runtime-api" }
revive-runner = { version = "0.1.0-dev.5", path = "crates/runner" } revive-runner = { version = "0.1.0-dev.6", path = "crates/runner" }
revive-solidity = { version = "0.1.0-dev.5", path = "crates/solidity" } revive-solidity = { version = "0.1.0-dev.6", path = "crates/solidity" }
revive-stdlib = { version = "0.1.0-dev.5", path = "crates/stdlib" } revive-stdlib = { version = "0.1.0-dev.6", 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.17"
polkavm-linker = "0.14" polkavm-linker = "0.17"
polkavm-disassembler = "0.14" polkavm-disassembler = "0.17"
polkavm = "0.14" polkavm = "0.17"
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"
@@ -67,7 +67,7 @@ log = { version = "0.4" }
# 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 = "447902eff4a574e66894ad60cb41999b05bf5e84" }
# llvm # llvm
[workspace.dependencies.inkwell] [workspace.dependencies.inkwell]
+1 -2
View File
@@ -9,8 +9,8 @@ RUSTFLAGS_EMSCRIPTEN := \
-Clink-arg=-sALLOW_MEMORY_GROWTH \ -Clink-arg=-sALLOW_MEMORY_GROWTH \
-Clink-arg=-sEXPORTED_RUNTIME_METHODS=FS,callMain,stringToNewUTF8,cwrap \ -Clink-arg=-sEXPORTED_RUNTIME_METHODS=FS,callMain,stringToNewUTF8,cwrap \
-Clink-arg=-sMODULARIZE \ -Clink-arg=-sMODULARIZE \
-Clink-arg=-sEXPORT_ES6 \
-Clink-arg=-sEXPORT_NAME=createRevive \ -Clink-arg=-sEXPORT_NAME=createRevive \
-Clink-arg=-sWASM_ASYNC_COMPILATION=0 \
-Clink-arg=--js-library=js/embed/soljson_interface.js \ -Clink-arg=--js-library=js/embed/soljson_interface.js \
-Clink-arg=--pre-js=js/embed/pre.js -Clink-arg=--pre-js=js/embed/pre.js
@@ -25,7 +25,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)
+2 -2
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
+28 -28
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)
-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": 1073,
"Computation": 4024, "Computation": 2469,
"DivisionArithmetics": 31789, "DivisionArithmetics": 15041,
"ERC20": 44214, "ERC20": 23282,
"Events": 1737, "Events": 1615,
"FibonacciIterative": 2929, "FibonacciIterative": 1676,
"Flipper": 3402, "Flipper": 2378,
"SHA1": 26003 "SHA1": 17076
} }
+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);
}
}
+1
View File
@@ -46,6 +46,7 @@ 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");
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 }
-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 {
-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 -1
View File
@@ -3,7 +3,7 @@
/// 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.
+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())?;
+8 -4
View File
@@ -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, 0)
.as_basic_value_enum(),
context
.integer_const(revive_common::BIT_LENGTH_X64, 0)
.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",
)?; )?;
@@ -17,12 +17,12 @@ where
/// 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!() Ok(context.word_const(1).as_basic_value_enum())
} }
/// Translates the `tx.origin` instruction. /// Translates the `tx.origin` instruction.
+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;
-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,
) )
} }
+8 -6
View File
@@ -74,15 +74,15 @@ 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, delegate_call, uint32_t)
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(void, code_size, uint32_t, uint32_t)
POLKAVM_IMPORT(void, code_hash, uint32_t, uint32_t) POLKAVM_IMPORT(void, code_hash, uint32_t, uint32_t)
@@ -90,13 +90,13 @@ POLKAVM_IMPORT(void, deposit_event, uint32_t, uint32_t, uint32_t, uint32_t)
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(void, input, uint32_t, uint32_t)
POLKAVM_IMPORT(uint32_t, instantiate, uint32_t) POLKAVM_IMPORT(uint64_t, instantiate, uint32_t)
POLKAVM_IMPORT(void, now, uint32_t) POLKAVM_IMPORT(void, now, uint32_t)
@@ -104,7 +104,7 @@ 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, set_storage, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t)
POLKAVM_IMPORT(void, return_data_copy, uint32_t, uint32_t, uint32_t) POLKAVM_IMPORT(void, return_data_copy, uint32_t, uint32_t, uint32_t)
@@ -113,3 +113,5 @@ POLKAVM_IMPORT(void, return_data_size, uint32_t)
POLKAVM_IMPORT(void, set_immutable_data, uint32_t, uint32_t); POLKAVM_IMPORT(void, set_immutable_data, 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);
+4 -1
View File
@@ -64,9 +64,11 @@ pub static SET_IMMUTABLE_DATA: &str = "set_immutable_data";
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; 28] = [
SBRK, SBRK,
MEMORY_SIZE, MEMORY_SIZE,
ADDRESS, ADDRESS,
@@ -94,6 +96,7 @@ pub static IMPORTS: [&str; 27] = [
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].
+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.
@@ -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,
+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:
+38 -45
View File
@@ -1,60 +1,53 @@
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.setStdinData(inputJson);
let error = null;
// Use deasync to block until promise resolves let stdoutString = "";
compileWithWorker(inputJson, function (err, res) { revive.setStdoutCallback(function(char) {
error = err; if (char.charCodeAt(0) === '\n') {
result = res; exit;
}
stdoutString += char;
}); });
// TODO: deasync is not present in browsers, another solution needs to be implemented
deasync.loopWhile(() => result === null && error === null);
if (error) { let stderrString = "";
const errorJson = JSON.stringify({ type: 'error', message: error.message || "Unknown error" }); revive.setStderrCallback(function(char) {
return stringToNewUTF8(errorJson) stderrString += char;
});
// Call main on the new instance
const result = revive.callMain(['--recursive-process']);
if (result) {
const error = JSON.stringify({ type: 'error', message: stderrString || "Unknown error" });
return stringToNewUTF8(error);
} else {
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,8 +30,8 @@ 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.setStdinData(JSON.stringify(compilerStandardJsonInput));
@@ -53,8 +52,8 @@ async function runCompiler() {
// 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: " + stdoutString);
console.error("Stderr: " + stderrString) console.error("Stderr: " + stderrString);
} }
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
+52
View File
@@ -0,0 +1,52 @@
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.setStdinData(JSON.stringify(sourceCode));
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
m.callMain(['--standard-json']);
postMessage({output: stdoutString || stderrString});
};
+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",