mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-04-21 23:48:05 +00:00
Support solc v0.8.31 (#430)
- Support for solc v0.8.31. - Support for the `clz` Yul builtin. --------- Signed-off-by: xermicus <cyrill@parity.io>
This commit is contained in:
@@ -19,7 +19,7 @@ runs:
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p solc
|
||||
curl -sSL --output solc/solc https://github.com/ethereum/solidity/releases/download/v0.8.30/${SOLC_NAME}
|
||||
curl -sSL --output solc/solc https://github.com/ethereum/solidity/releases/download/v0.8.31/${SOLC_NAME}
|
||||
|
||||
- name: Make Solc Executable
|
||||
if: ${{ runner.os == 'Windows' }}
|
||||
|
||||
@@ -177,7 +177,7 @@ jobs:
|
||||
- name: Basic Sanity Check
|
||||
run: |
|
||||
mkdir -p solc
|
||||
curl -sSLo solc/soljson.js https://github.com/ethereum/solidity/releases/download/v0.8.30/soljson.js
|
||||
curl -sSLo solc/soljson.js https://github.com/ethereum/solidity/releases/download/v0.8.31/soljson.js
|
||||
node -e "
|
||||
const soljson = require('solc/soljson');
|
||||
const createRevive = require('./target/wasm32-unknown-emscripten/release/resolc.js');
|
||||
|
||||
@@ -8,6 +8,8 @@ Supported `polkadot-sdk` rev: `2509.0.0`
|
||||
|
||||
### Added
|
||||
- The comprehensive revive compiler book documentation page: https://paritytech.github.io/revive/
|
||||
- Support for solc v0.8.31.
|
||||
- Support for the `clz` Yul builtin.
|
||||
|
||||
### Changed
|
||||
- Instruct the LLVM backend and linker to `--relax` (may lead to smaller contract code size).
|
||||
|
||||
@@ -43,6 +43,12 @@ pub enum EVMVersion {
|
||||
/// The corresponding EVM version.
|
||||
#[serde(rename = "cancun")]
|
||||
Cancun,
|
||||
/// The corresponding EVM version.
|
||||
#[serde(rename = "prague")]
|
||||
Prague,
|
||||
/// The corresponding EVM version.
|
||||
#[serde(rename = "osaka")]
|
||||
Osaka,
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for EVMVersion {
|
||||
@@ -62,6 +68,8 @@ impl TryFrom<&str> for EVMVersion {
|
||||
"paris" => Self::Paris,
|
||||
"shanghai" => Self::Shanghai,
|
||||
"cancun" => Self::Cancun,
|
||||
"prague" => Self::Prague,
|
||||
"osaka" => Self::Osaka,
|
||||
_ => anyhow::bail!("Invalid EVM version: {}", value),
|
||||
})
|
||||
}
|
||||
@@ -82,6 +90,8 @@ impl std::fmt::Display for EVMVersion {
|
||||
Self::Paris => write!(f, "paris"),
|
||||
Self::Shanghai => write!(f, "shanghai"),
|
||||
Self::Cancun => write!(f, "cancun"),
|
||||
Self::Prague => write!(f, "prague"),
|
||||
Self::Osaka => write!(f, "osaka"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
"grayGlacierBlock": 0,
|
||||
"shanghaiTime": 0,
|
||||
"cancunTime": 0,
|
||||
"pragueTime": 0,
|
||||
"osakaTime": 0,
|
||||
"terminalTotalDifficulty": 0,
|
||||
"terminalTotalDifficultyPassed": true,
|
||||
"blobSchedule": {
|
||||
@@ -22,6 +24,16 @@
|
||||
"target": 3,
|
||||
"max": 6,
|
||||
"baseFeeUpdateFraction": 3338477
|
||||
},
|
||||
"prague": {
|
||||
"target": 6,
|
||||
"max": 9,
|
||||
"baseFeeUpdateFraction": 5007716
|
||||
},
|
||||
"osaka": {
|
||||
"target": 6,
|
||||
"max": 9,
|
||||
"baseFeeUpdateFraction": 5007716
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -44,4 +56,4 @@
|
||||
"balance": "1000000000"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.31;
|
||||
|
||||
/* runner.json
|
||||
{
|
||||
"differential": true,
|
||||
"actions": [
|
||||
{
|
||||
"Instantiate": {
|
||||
"code": {
|
||||
"Solidity": {
|
||||
"contract": "CountLeadingZeros"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
*/
|
||||
|
||||
/// The EIP-7939 test vectors:
|
||||
/// https://eips.ethereum.org/EIPS/eip-7939#test-cases
|
||||
contract CountLeadingZeros {
|
||||
function clz(uint256 x) internal pure returns (uint256 r) {
|
||||
assembly {
|
||||
r := clz(x)
|
||||
}
|
||||
}
|
||||
|
||||
constructor() payable {
|
||||
assert(
|
||||
clz(0x000000000000000000000000000000000000000000000000000000000000000)
|
||||
== 0x0000000000000000000000000000000000000000000000000000000000000100
|
||||
);
|
||||
assert(
|
||||
clz(0x8000000000000000000000000000000000000000000000000000000000000000)
|
||||
== 0x0000000000000000000000000000000000000000000000000000000000000000
|
||||
);
|
||||
assert(
|
||||
clz(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
|
||||
== 0x0000000000000000000000000000000000000000000000000000000000000000
|
||||
);
|
||||
assert(
|
||||
clz(0x4000000000000000000000000000000000000000000000000000000000000000)
|
||||
== 0x0000000000000000000000000000000000000000000000000000000000000001
|
||||
);
|
||||
assert(
|
||||
clz(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
|
||||
== 0x0000000000000000000000000000000000000000000000000000000000000001
|
||||
);
|
||||
assert(
|
||||
clz(0x0000000000000000000000000000000000000000000000000000000000000001)
|
||||
== 0x00000000000000000000000000000000000000000000000000000000000000ff
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -65,6 +65,7 @@ test_spec!(shift_arithmetic_right, "SAR", "SAR.sol");
|
||||
test_spec!(add_mod_mul_mod, "AddModMulModTester", "AddModMulMod.sol");
|
||||
test_spec!(memory_bounds, "MemoryBounds", "MemoryBounds.sol");
|
||||
test_spec!(selfdestruct, "Selfdestruct", "Selfdestruct.sol");
|
||||
test_spec!(clz, "CountLeadingZeros", "CountLeadingZeros.sol");
|
||||
|
||||
fn instantiate(path: &str, contract: &str) -> Vec<SpecsAction> {
|
||||
vec![Instantiate {
|
||||
|
||||
@@ -14,6 +14,8 @@ pub struct Intrinsics<'ctx> {
|
||||
pub byte_swap_word: FunctionDeclaration<'ctx>,
|
||||
/// Performs endianness swaps on i160 values
|
||||
pub byte_swap_eth_address: FunctionDeclaration<'ctx>,
|
||||
/// Counts leading zeroes.
|
||||
pub count_leading_zeros: FunctionDeclaration<'ctx>,
|
||||
}
|
||||
|
||||
impl<'ctx> Intrinsics<'ctx> {
|
||||
@@ -26,6 +28,9 @@ impl<'ctx> Intrinsics<'ctx> {
|
||||
/// The corresponding intrinsic function name.
|
||||
pub const FUNCTION_BYTE_SWAP_ETH_ADDRESS: &'static str = "llvm.bswap.i160";
|
||||
|
||||
/// The corresponding intrinsic function name.
|
||||
pub const FUNCTION_COUNT_LEADING_ZEROS: &'static str = "llvm.ctlz.i256";
|
||||
|
||||
/// A shortcut constructor.
|
||||
pub fn new(
|
||||
llvm: &'ctx inkwell::context::Context,
|
||||
@@ -53,11 +58,18 @@ impl<'ctx> Intrinsics<'ctx> {
|
||||
Self::FUNCTION_BYTE_SWAP_ETH_ADDRESS,
|
||||
address_type.fn_type(&[address_type.as_basic_type_enum().into()], false),
|
||||
);
|
||||
let count_leading_zeros = Self::declare(
|
||||
llvm,
|
||||
module,
|
||||
Self::FUNCTION_COUNT_LEADING_ZEROS,
|
||||
word_type.fn_type(&[word_type.into(), llvm.bool_type().into()], false),
|
||||
);
|
||||
|
||||
Self {
|
||||
trap,
|
||||
byte_swap_word,
|
||||
byte_swap_eth_address,
|
||||
count_leading_zeros,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,12 +97,15 @@ impl<'ctx> Intrinsics<'ctx> {
|
||||
let word_type = llvm.custom_width_int_type(revive_common::BIT_LENGTH_WORD as u32);
|
||||
|
||||
match name {
|
||||
name if name == Self::FUNCTION_BYTE_SWAP_WORD => vec![word_type.as_basic_type_enum()],
|
||||
name if name == Self::FUNCTION_BYTE_SWAP_ETH_ADDRESS => {
|
||||
_ if name == Self::FUNCTION_BYTE_SWAP_WORD => vec![word_type.as_basic_type_enum()],
|
||||
_ if name == Self::FUNCTION_BYTE_SWAP_ETH_ADDRESS => {
|
||||
vec![llvm
|
||||
.custom_width_int_type(revive_common::BIT_LENGTH_ETH_ADDRESS as u32)
|
||||
.as_basic_type_enum()]
|
||||
}
|
||||
_ if name == Self::FUNCTION_COUNT_LEADING_ZEROS => {
|
||||
vec![word_type.as_basic_type_enum()]
|
||||
}
|
||||
_ => vec![],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,3 +261,20 @@ pub fn byte<'ctx>(
|
||||
|
||||
Ok(byte.as_basic_value_enum())
|
||||
}
|
||||
|
||||
/// Translates the CLZ instruction.
|
||||
pub fn count_leading_zeros<'ctx>(
|
||||
context: &mut Context<'ctx>,
|
||||
value: inkwell::values::IntValue<'ctx>,
|
||||
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>> {
|
||||
Ok(context
|
||||
.builder()
|
||||
.build_call(
|
||||
context.intrinsics().count_leading_zeros.function_value(),
|
||||
&[value.into(), context.bool_const(false).into()],
|
||||
"clz",
|
||||
)?
|
||||
.try_as_basic_value()
|
||||
.left()
|
||||
.expect("the llvm.ctlz should return a value"))
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ pub mod version;
|
||||
pub const FIRST_SUPPORTED_VERSION: semver::Version = semver::Version::new(0, 8, 0);
|
||||
|
||||
/// The last supported version of `solc`.
|
||||
pub const LAST_SUPPORTED_VERSION: semver::Version = semver::Version::new(0, 8, 30);
|
||||
pub const LAST_SUPPORTED_VERSION: semver::Version = semver::Version::new(0, 8, 31);
|
||||
|
||||
/// The Solidity compiler.
|
||||
pub trait Compiler {
|
||||
|
||||
@@ -348,6 +348,14 @@ impl FunctionCall {
|
||||
)
|
||||
.map(Some)
|
||||
}
|
||||
Name::Clz => {
|
||||
let arguments = self.pop_arguments_llvm::<1>(context)?;
|
||||
revive_llvm_context::polkavm_evm_bitwise::count_leading_zeros(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
)
|
||||
.map(Some)
|
||||
}
|
||||
Name::Byte => {
|
||||
let arguments = self.pop_arguments_llvm::<2>(context)?;
|
||||
revive_llvm_context::polkavm_evm_bitwise::byte(
|
||||
|
||||
@@ -54,6 +54,8 @@ pub enum Name {
|
||||
Shr,
|
||||
/// signed arithmetic shift right `y` by `x` bits
|
||||
Sar,
|
||||
/// number of leading zero bits of x, 256 if x == 0
|
||||
Clz,
|
||||
/// `n`th byte of `x`, where the most significant byte is the `0`th byte
|
||||
Byte,
|
||||
/// discard value x
|
||||
@@ -270,6 +272,7 @@ impl From<&str> for Name {
|
||||
"shl" => Self::Shl,
|
||||
"shr" => Self::Shr,
|
||||
"sar" => Self::Sar,
|
||||
"clz" => Self::Clz,
|
||||
"byte" => Self::Byte,
|
||||
"pop" => Self::Pop,
|
||||
|
||||
@@ -393,6 +396,7 @@ impl fmt::Display for Name {
|
||||
Self::Shl => "shl",
|
||||
Self::Shr => "shr",
|
||||
Self::Sar => "sar",
|
||||
Self::Clz => "clz",
|
||||
Self::Byte => "byte",
|
||||
Self::Pop => "pop",
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ const path = require("path");
|
||||
const { minify } = require("terser");
|
||||
|
||||
const SOLJSON_URI =
|
||||
"https://binaries.soliditylang.org/wasm/soljson-v0.8.30+commit.73712a01.js";
|
||||
"https://binaries.soliditylang.org/wasm/soljson-v0.8.31+commit.fd3a2265.js";
|
||||
const RESOLC_WASM_URI =
|
||||
process.env.RELEASE_RESOLC_WASM_URI || "http://127.0.0.1:8080/resolc.wasm";
|
||||
const RESOLC_WASM_TARGET_DIR = path.join(
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "revive",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"solc": ">=0.8.0 <=0.8.30"
|
||||
"solc": ">=0.8.0 <=0.8.31"
|
||||
},
|
||||
"scripts": {
|
||||
"example:web": "http-server ./examples/web/",
|
||||
|
||||
@@ -34,6 +34,6 @@
|
||||
"commander": "^13.1.0",
|
||||
"package-json": "^10.0.1",
|
||||
"resolve-pkg": "^2.0.0",
|
||||
"solc": ">=0.8.0 <=0.8.30"
|
||||
"solc": ">=0.8.0 <=0.8.31"
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+7
-2
@@ -18,7 +18,7 @@
|
||||
"js/emscripten": {
|
||||
"name": "revive",
|
||||
"dependencies": {
|
||||
"solc": ">=0.8.0 <=0.8.30"
|
||||
"solc": ">=0.8.0 <=0.8.31"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.49.1",
|
||||
@@ -38,7 +38,7 @@
|
||||
"commander": "^13.1.0",
|
||||
"package-json": "^10.0.1",
|
||||
"resolve-pkg": "^2.0.0",
|
||||
"solc": ">=0.8.0 <=0.8.30"
|
||||
"solc": ">=0.8.0 <=0.8.31"
|
||||
},
|
||||
"bin": {
|
||||
"resolc": "dist/bin.js"
|
||||
@@ -1585,6 +1585,7 @@
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.32.1.tgz",
|
||||
"integrity": "sha512-LKMrmwCPoLhM45Z00O1ulb6jwyVr2kr3XJp+G+tSEZcbauNnScewcQwtJqXDhXeYPDEjZ8C1SjXm015CirEmGg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "8.32.1",
|
||||
"@typescript-eslint/types": "8.32.1",
|
||||
@@ -1752,6 +1753,7 @@
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
|
||||
"integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
@@ -2361,6 +2363,7 @@
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.27.0.tgz",
|
||||
"integrity": "sha512-ixRawFQuMB9DZ7fjU3iGGganFDp3+45bPOdaRurcFHSXO1e/sYwUX/FtQZpLZJR6SjMoJH8hR2pPEAfDyCoU2Q==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.2.0",
|
||||
"@eslint-community/regexpp": "^4.12.1",
|
||||
@@ -2519,6 +2522,7 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@ethersproject/abi": "5.8.0",
|
||||
"@ethersproject/abstract-provider": "5.8.0",
|
||||
@@ -4393,6 +4397,7 @@
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
|
||||
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
|
||||
Reference in New Issue
Block a user