mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-06-14 20:21:07 +00:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3184397c43 | |||
| 9c44eeac06 | |||
| f49d145e9a | |||
| 952c5cc894 | |||
| d8752ec6b5 | |||
| 6ad846a285 | |||
| 3f9771f838 | |||
| 22070a824d | |||
| d299dd1a19 | |||
| 14a598e840 | |||
| 55ec0988e8 | |||
| 909de515c4 | |||
| afe44ad21b | |||
| 2cb8f82266 | |||
| 6f2f158ef1 | |||
| 4e5482bad2 |
@@ -9,12 +9,12 @@ env:
|
|||||||
DEBIAN_CONTAINER_RUNNER: run-debian-builder.sh
|
DEBIAN_CONTAINER_RUNNER: run-debian-builder.sh
|
||||||
REVIVE_DEBIAN_INSTALL: ${{ github.workspace }}/target/release
|
REVIVE_DEBIAN_INSTALL: ${{ github.workspace }}/target/release
|
||||||
REVIVE_DEBIAN_BINARY: resolc
|
REVIVE_DEBIAN_BINARY: resolc
|
||||||
RUST_VERSION: "1.80"
|
RUST_VERSION: "1.81"
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ env:
|
|||||||
|
|
||||||
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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -15,3 +15,4 @@ tmp
|
|||||||
package-lock.json
|
package-lock.json
|
||||||
/*.html
|
/*.html
|
||||||
/build
|
/build
|
||||||
|
soljson.js
|
||||||
|
|||||||
@@ -2,6 +2,26 @@
|
|||||||
|
|
||||||
## 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
|
## v0.1.0-dev.6
|
||||||
|
|
||||||
This is a development pre-release.
|
This is a development pre-release.
|
||||||
|
|||||||
Generated
+990
-1590
File diff suppressed because it is too large
Load Diff
+20
-19
@@ -3,7 +3,7 @@ resolver = "2"
|
|||||||
members = ["crates/*"]
|
members = ["crates/*"]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "0.1.0-dev.6"
|
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>",
|
||||||
@@ -11,21 +11,21 @@ authors = [
|
|||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
repository = "https://github.com/paritytech/revive"
|
repository = "https://github.com/paritytech/revive"
|
||||||
rust-version = "1.80.0"
|
rust-version = "1.81.0"
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
revive-benchmarks = { version = "0.1.0-dev.6", path = "crates/benchmarks" }
|
revive-benchmarks = { version = "0.1.0-dev.7", path = "crates/benchmarks" }
|
||||||
revive-builtins = { version = "0.1.0-dev.6", path = "crates/builtins" }
|
revive-builtins = { version = "0.1.0-dev.7", path = "crates/builtins" }
|
||||||
revive-common = { version = "0.1.0-dev.6", path = "crates/common" }
|
revive-common = { version = "0.1.0-dev.7", path = "crates/common" }
|
||||||
revive-differential = { version = "0.1.0-dev.6", path = "crates/differential" }
|
revive-differential = { version = "0.1.0-dev.7", path = "crates/differential" }
|
||||||
revive-integration = { version = "0.1.0-dev.6", path = "crates/integration" }
|
revive-integration = { version = "0.1.0-dev.7", path = "crates/integration" }
|
||||||
revive-linker = { version = "0.1.0-dev.6", path = "crates/linker" }
|
revive-linker = { version = "0.1.0-dev.7", path = "crates/linker" }
|
||||||
lld-sys = { version = "0.1.0-dev.6", path = "crates/lld-sys" }
|
lld-sys = { version = "0.1.0-dev.7", path = "crates/lld-sys" }
|
||||||
revive-llvm-context = { version = "0.1.0-dev.6", 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.6", path = "crates/runtime-api" }
|
revive-runtime-api = { version = "0.1.0-dev.7", path = "crates/runtime-api" }
|
||||||
revive-runner = { version = "0.1.0-dev.6", path = "crates/runner" }
|
revive-runner = { version = "0.1.0-dev.7", path = "crates/runner" }
|
||||||
revive-solidity = { version = "0.1.0-dev.6", path = "crates/solidity" }
|
revive-solidity = { version = "0.1.0-dev.7", path = "crates/solidity" }
|
||||||
revive-stdlib = { version = "0.1.0-dev.6", 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.17"
|
polkavm-common = "0.18"
|
||||||
polkavm-linker = "0.17"
|
polkavm-linker = "0.18"
|
||||||
polkavm-disassembler = "0.17"
|
polkavm-disassembler = "0.18"
|
||||||
polkavm = "0.17"
|
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 = "447902eff4a574e66894ad60cb41999b05bf5e84" }
|
polkadot-sdk = { git = "https://github.com/paritytech/polkadot-sdk", rev = "243b751abbb94369bbd92c83d8ab159ddfc3c556" }
|
||||||
|
|
||||||
# llvm
|
# llvm
|
||||||
[workspace.dependencies.inkwell]
|
[workspace.dependencies.inkwell]
|
||||||
|
|||||||
@@ -1,18 +1,21 @@
|
|||||||
.PHONY: install format test test-solidity test-cli test-integration test-workspace clean docs docs-build
|
.PHONY: install format test test-solidity test-cli test-integration test-workspace clean docs docs-build
|
||||||
|
|
||||||
RUSTFLAGS_EMSCRIPTEN := \
|
RUSTFLAGS_EMSCRIPTEN := \
|
||||||
-Clink-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 \
|
-C link-arg=-sEXPORT_NAME=createRevive \
|
||||||
-Clink-arg=-sMODULARIZE \
|
-C link-arg=-sWASM_ASYNC_COMPILATION=0 \
|
||||||
-Clink-arg=-sEXPORT_NAME=createRevive \
|
-C link-arg=-sDYNAMIC_EXECUTION=0 \
|
||||||
-Clink-arg=-sWASM_ASYNC_COMPILATION=0 \
|
-C link-arg=-sALLOW_TABLE_GROWTH=1 \
|
||||||
-Clink-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
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"Baseline": 1073,
|
"Baseline": 1110,
|
||||||
"Computation": 2469,
|
"Computation": 2389,
|
||||||
"DivisionArithmetics": 15041,
|
"DivisionArithmetics": 14822,
|
||||||
"ERC20": 23282,
|
"ERC20": 23973,
|
||||||
"Events": 1615,
|
"Events": 1605,
|
||||||
"FibonacciIterative": 1676,
|
"FibonacciIterative": 2023,
|
||||||
"Flipper": 2378,
|
"Flipper": 1989,
|
||||||
"SHA1": 17076
|
"SHA1": 17026
|
||||||
}
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -47,6 +47,9 @@ 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_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 {
|
||||||
|
|||||||
@@ -57,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,9 +9,6 @@ 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);
|
||||||
|
|||||||
@@ -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(),
|
||||||
@@ -140,10 +140,10 @@ where
|
|||||||
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
|
context
|
||||||
.integer_const(revive_common::BIT_LENGTH_X64, 0)
|
.integer_const(revive_common::BIT_LENGTH_X64, u64::MAX)
|
||||||
.as_basic_value_enum(),
|
.as_basic_value_enum(),
|
||||||
context
|
context
|
||||||
.integer_const(revive_common::BIT_LENGTH_X64, 0)
|
.integer_const(revive_common::BIT_LENGTH_X64, u64::MAX)
|
||||||
.as_basic_value_enum(),
|
.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(),
|
||||||
|
|||||||
@@ -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(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,12 +7,20 @@ 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.
|
||||||
@@ -22,7 +30,15 @@ pub fn gas_price<'ctx, D>(
|
|||||||
where
|
where
|
||||||
D: Dependency + Clone,
|
D: Dependency + Clone,
|
||||||
{
|
{
|
||||||
Ok(context.word_const(1).as_basic_value_enum())
|
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
|
||||||
revive_runtime_api::polkavm_imports::CODE_SIZE,
|
.build_runtime_call(
|
||||||
&[
|
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
|
||||||
|
|||||||
Binary file not shown.
@@ -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)]
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -70,32 +70,42 @@ 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(uint64_t, call, uint32_t)
|
POLKAVM_IMPORT(uint64_t, call, uint32_t)
|
||||||
|
|
||||||
POLKAVM_IMPORT(uint64_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(void, 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(uint64_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(uint64_t, instantiate, uint32_t)
|
||||||
|
|
||||||
POLKAVM_IMPORT(void, now, uint32_t)
|
POLKAVM_IMPORT(void, now, uint32_t)
|
||||||
@@ -104,14 +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(uint64_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);
|
POLKAVM_IMPORT(void, weight_to_fee, uint64_t, uint64_t, uint32_t);
|
||||||
|
|||||||
@@ -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,34 +72,42 @@ 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";
|
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; 28] = [
|
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,
|
||||||
|
|||||||
@@ -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"]
|
||||||
|
|||||||
@@ -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());
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ pub use self::warning::Warning;
|
|||||||
pub mod test_utils;
|
pub mod test_utils;
|
||||||
pub mod tests;
|
pub mod tests;
|
||||||
|
|
||||||
use std::collections::BTreeSet;
|
use std::collections::{BTreeMap, BTreeSet};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
/// Runs the Yul mode.
|
/// Runs the Yul mode.
|
||||||
@@ -149,7 +149,7 @@ pub fn standard_output<T: Compiler>(
|
|||||||
suppressed_warnings,
|
suppressed_warnings,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let source_code_files = solc_input
|
let mut source_code_files: BTreeMap<String, String> = solc_input
|
||||||
.sources
|
.sources
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(path, source)| (path.to_owned(), source.content.to_owned()))
|
.map(|(path, source)| (path.to_owned(), source.content.to_owned()))
|
||||||
@@ -180,6 +180,18 @@ pub fn standard_output<T: Compiler>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// load import callbacks unspecified in input
|
||||||
|
if let Some(sources) = &solc_output.sources {
|
||||||
|
for source_path in sources.keys() {
|
||||||
|
if !source_code_files.contains_key(source_path) {
|
||||||
|
let source = std::fs::read_to_string(source_path).map_err(|e| {
|
||||||
|
anyhow::anyhow!("Can't read source file at `{}`: {}", source_path, e)
|
||||||
|
})?;
|
||||||
|
let _ = source_code_files.insert(source_path.clone(), source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let project = solc_output.try_to_project(
|
let project = solc_output.try_to_project(
|
||||||
source_code_files,
|
source_code_files,
|
||||||
libraries,
|
libraries,
|
||||||
|
|||||||
@@ -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(),
|
||||||
|
|||||||
+26
-21
@@ -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);
|
||||||
|
|||||||
@@ -24,28 +24,17 @@ mergeInto(LibraryManager.library, {
|
|||||||
} else {
|
} else {
|
||||||
throw new Error('Unknown environment: Unable to load resolc.js');
|
throw new Error('Unknown environment: Unable to load resolc.js');
|
||||||
}
|
}
|
||||||
revive.setStdinData(inputJson);
|
revive.writeToStdin(inputJson);
|
||||||
|
|
||||||
let stdoutString = "";
|
|
||||||
revive.setStdoutCallback(function(char) {
|
|
||||||
if (char.charCodeAt(0) === '\n') {
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
stdoutString += char;
|
|
||||||
});
|
|
||||||
|
|
||||||
let stderrString = "";
|
|
||||||
revive.setStderrCallback(function(char) {
|
|
||||||
stderrString += char;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Call main on the new instance
|
// Call main on the new instance
|
||||||
const result = revive.callMain(['--recursive-process']);
|
const result = revive.callMain(['--recursive-process']);
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
|
const stderrString = revive.readFromStderr();
|
||||||
const error = JSON.stringify({ type: 'error', message: stderrString || "Unknown error" });
|
const error = JSON.stringify({ type: 'error', message: stderrString || "Unknown error" });
|
||||||
return stringToNewUTF8(error);
|
return stringToNewUTF8(error);
|
||||||
} else {
|
} else {
|
||||||
|
const stdoutString = revive.readFromStdout();
|
||||||
const json = JSON.stringify({ type: 'success', data: stdoutString });
|
const json = JSON.stringify({ type: 'success', data: stdoutString });
|
||||||
return stringToNewUTF8(json);
|
return stringToNewUTF8(json);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,26 +34,12 @@ async function runCompiler() {
|
|||||||
m.soljson = soljson;
|
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 => {
|
||||||
|
|||||||
@@ -29,24 +29,10 @@ onmessage = async function (e) {
|
|||||||
m.soljson = Module;
|
m.soljson = Module;
|
||||||
|
|
||||||
// Set input data for stdin
|
// Set input data for stdin
|
||||||
m.setStdinData(JSON.stringify(sourceCode));
|
m.writeToStdin(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
|
// Compile the Solidity source code
|
||||||
m.callMain(['--standard-json']);
|
m.callMain(['--standard-json']);
|
||||||
|
|
||||||
postMessage({output: stdoutString || stderrString});
|
postMessage({output: m.readFromStdout() || m.readFromStderr()});
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user