mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-06-14 21:31:05 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a57352f9c4 |
@@ -1,5 +1,4 @@
|
||||
name: Nightly Release
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# Run every day at 01:00 UTC
|
||||
@@ -11,8 +10,10 @@ concurrency:
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
RUST_MUSL_CROSS_IMAGE: messense/rust-musl-cross@sha256:c0154e992adb791c3b848dd008939d19862549204f8cb26f5ca7a00f629e6067
|
||||
|
||||
jobs:
|
||||
# check if there were commits yesterday
|
||||
check_commits:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
@@ -21,7 +22,7 @@ jobs:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-depth: 0 # Fetch full history to check previous commits
|
||||
ref: "main"
|
||||
|
||||
- name: Check for commits from yesterday
|
||||
@@ -46,12 +47,229 @@ jobs:
|
||||
fi
|
||||
|
||||
build:
|
||||
# github actions matrix jobs don't support multiple outputs
|
||||
# ugly workaround from https://github.com/orgs/community/discussions/17245#discussioncomment-11222880
|
||||
if: ${{ needs.check_commits.outputs.has_commits == 'true' }}
|
||||
outputs:
|
||||
resolc-x86_64-unknown-linux-musl_url: ${{ steps.set-output.outputs.resolc-x86_64-unknown-linux-musl_url }}
|
||||
resolc-x86_64-unknown-linux-musl_sha: ${{ steps.set-output.outputs.resolc-x86_64-unknown-linux-musl_sha }}
|
||||
resolc-aarch64-apple-darwin_url: ${{ steps.set-output.outputs.resolc-aarch64-apple-darwin_url }}
|
||||
resolc-aarch64-apple-darwin_sha: ${{ steps.set-output.outputs.resolc-aarch64-apple-darwin_sha }}
|
||||
resolc-x86_64-apple-darwin_url: ${{ steps.set-output.outputs.resolc-x86_64-apple-darwin_url }}
|
||||
resolc-x86_64-apple-darwin_sha: ${{ steps.set-output.outputs.resolc-x86_64-apple-darwin_sha }}
|
||||
resolc-x86_64-pc-windows-msvc_url: ${{ steps.set-output.outputs.resolc-x86_64-pc-windows-msvc_url }}
|
||||
resolc-x86_64-pc-windows-msvc_sha: ${{ steps.set-output.outputs.resolc-x86_64-pc-windows-msvc_sha }}
|
||||
strategy:
|
||||
matrix:
|
||||
target:
|
||||
[
|
||||
x86_64-unknown-linux-musl,
|
||||
aarch64-apple-darwin,
|
||||
x86_64-apple-darwin,
|
||||
x86_64-pc-windows-msvc,
|
||||
]
|
||||
include:
|
||||
- target: x86_64-unknown-linux-musl
|
||||
type: musl
|
||||
runner: ubuntu-24.04
|
||||
- target: aarch64-apple-darwin
|
||||
type: native
|
||||
runner: macos-14
|
||||
- target: x86_64-apple-darwin
|
||||
type: native
|
||||
runner: macos-13
|
||||
- target: x86_64-pc-windows-msvc
|
||||
type: native
|
||||
runner: windows-2022
|
||||
runs-on: ${{ matrix.runner }}
|
||||
needs: [check_commits]
|
||||
uses: ./.github/workflows/reusable-build.yml
|
||||
with:
|
||||
is_release: false
|
||||
retention_days: 40
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
# without this it will override our rust flags
|
||||
rustflags: ""
|
||||
cache-key: ${{ matrix.target }}
|
||||
|
||||
- name: Download LLVM
|
||||
uses: ./.github/actions/get-llvm
|
||||
with:
|
||||
target: ${{ matrix.target }}
|
||||
|
||||
- name: Build
|
||||
if: ${{ matrix.type == 'native' }}
|
||||
shell: bash
|
||||
run: |
|
||||
export LLVM_SYS_181_PREFIX=$PWD/llvm-${{ matrix.target }}
|
||||
make install-bin
|
||||
mv target/release/resolc resolc-${{ matrix.target }} || mv target/release/resolc.exe resolc-${{ matrix.target }}.exe
|
||||
|
||||
- name: Build
|
||||
if: ${{ matrix.type == 'musl' }}
|
||||
run: |
|
||||
docker run -v $PWD:/opt/revive $RUST_MUSL_CROSS_IMAGE /bin/bash -c "
|
||||
cd /opt/revive
|
||||
chown -R root:root .
|
||||
apt update && apt upgrade -y && apt install -y pkg-config
|
||||
export LLVM_SYS_181_PREFIX=/opt/revive/llvm-${{ matrix.target }}
|
||||
make install-bin
|
||||
mv target/${{ matrix.target }}/release/resolc resolc-${{ matrix.target }}
|
||||
"
|
||||
sudo chown -R $(id -u):$(id -g) .
|
||||
|
||||
- name: Install Solc
|
||||
uses: ./.github/actions/get-solc
|
||||
|
||||
- name: Basic Sanity Check
|
||||
shell: bash
|
||||
run: |
|
||||
result=$(./resolc-${{ matrix.target }} --bin crates/integration/contracts/flipper.sol)
|
||||
echo $result
|
||||
if [[ $result == *'50564d'* ]]; then exit 0; else exit 1; fi
|
||||
|
||||
- name: Upload artifacts (nightly)
|
||||
uses: actions/upload-artifact@v4
|
||||
id: artifact-upload-step
|
||||
with:
|
||||
name: resolc-${{ matrix.target }}
|
||||
path: resolc-${{ matrix.target }}*
|
||||
retention-days: 40
|
||||
|
||||
- name: Set output variables (nightly)
|
||||
id: set-output
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Artifact URL is ${{ steps.artifact-upload-step.outputs.artifact-url }}"
|
||||
echo "Artifact SHA is ${{ steps.artifact-upload-step.outputs.artifact-digest }}"
|
||||
echo "resolc-${{ matrix.target }}_url=${{ steps.artifact-upload-step.outputs.artifact-url }}"
|
||||
echo "resolc-${{ matrix.target }}_url=${{ steps.artifact-upload-step.outputs.artifact-url }}" >> "$GITHUB_OUTPUT"
|
||||
echo "resolc-${{ matrix.target }}_sha=${{ steps.artifact-upload-step.outputs.artifact-digest }}"
|
||||
echo "resolc-${{ matrix.target }}_sha=${{ steps.artifact-upload-step.outputs.artifact-digest }}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
build-wasm:
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [check_commits]
|
||||
if: ${{ needs.check_commits.outputs.has_commits == 'true' }}
|
||||
outputs:
|
||||
resolc-web.js_url: ${{ steps.set-output.outputs.resolc_web_js_url }}
|
||||
resolc-web.js_sha: ${{ steps.set-output.outputs.resolc_web_js_sha }}
|
||||
env:
|
||||
RELEASE_RESOLC_WASM_URI: https://github.com/paritytech/revive/releases/download/${{ github.ref_name }}/resolc.wasm
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
target: wasm32-unknown-emscripten
|
||||
# without this it will override our rust flags
|
||||
rustflags: ""
|
||||
|
||||
- name: Download Host LLVM
|
||||
uses: ./.github/actions/get-llvm
|
||||
with:
|
||||
target: x86_64-unknown-linux-gnu
|
||||
|
||||
- name: Download Wasm LLVM
|
||||
uses: ./.github/actions/get-llvm
|
||||
with:
|
||||
target: wasm32-unknown-emscripten
|
||||
|
||||
- name: Download EMSDK
|
||||
uses: ./.github/actions/get-emsdk
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export LLVM_SYS_181_PREFIX=$PWD/llvm-x86_64-unknown-linux-gnu
|
||||
export REVIVE_LLVM_TARGET_PREFIX=$PWD/llvm-wasm32-unknown-emscripten
|
||||
source emsdk/emsdk_env.sh
|
||||
make install-wasm
|
||||
chmod -x ./target/wasm32-unknown-emscripten/release/resolc.wasm
|
||||
|
||||
- name: Set Up Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "20"
|
||||
|
||||
- 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
|
||||
node -e "
|
||||
const soljson = require('solc/soljson');
|
||||
const createRevive = require('./target/wasm32-unknown-emscripten/release/resolc.js');
|
||||
|
||||
const compiler = createRevive();
|
||||
compiler.soljson = soljson;
|
||||
|
||||
const standardJsonInput =
|
||||
{
|
||||
language: 'Solidity',
|
||||
sources: {
|
||||
'MyContract.sol': {
|
||||
content: 'pragma solidity ^0.8.0; contract MyContract { function greet() public pure returns (string memory) { return \'Hello\'; } }',
|
||||
},
|
||||
},
|
||||
settings: { optimizer: { enabled: false } }
|
||||
};
|
||||
|
||||
compiler.writeToStdin(JSON.stringify(standardJsonInput));
|
||||
compiler.callMain(['--standard-json']);
|
||||
|
||||
// Collect output
|
||||
const stdout = compiler.readFromStdout();
|
||||
const stderr = compiler.readFromStderr();
|
||||
|
||||
if (stderr) { console.error(stderr); process.exit(1); }
|
||||
|
||||
let out = JSON.parse(stdout);
|
||||
let bytecode = out.contracts['MyContract.sol']['MyContract'].evm.bytecode.object
|
||||
console.log(bytecode);
|
||||
|
||||
if(!bytecode.startsWith('50564d')) { process.exit(1); }
|
||||
"
|
||||
|
||||
- name: Compress Artifact
|
||||
run: |
|
||||
mkdir -p resolc-wasm32-unknown-emscripten
|
||||
mv ./target/wasm32-unknown-emscripten/release/resolc.js ./resolc-wasm32-unknown-emscripten/
|
||||
mv ./target/wasm32-unknown-emscripten/release/resolc.wasm ./resolc-wasm32-unknown-emscripten/
|
||||
mv ./target/wasm32-unknown-emscripten/release/resolc_web.js ./resolc-wasm32-unknown-emscripten/
|
||||
|
||||
# There is no way to upload several files as several artifacts with a single upload-artifact step
|
||||
# It's needed to have resolc_web.js separately for night builds for resolc-bin repo
|
||||
# https://github.com/actions/upload-artifact/issues/331
|
||||
- name: Upload artifact resolc.js (nightly)
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: resolc.js
|
||||
path: resolc-wasm32-unknown-emscripten/resolc.js
|
||||
retention-days: 40
|
||||
|
||||
- name: Upload artifacts resolc.wasm (nightly)
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: resolc.wasm
|
||||
path: resolc-wasm32-unknown-emscripten/resolc.wasm
|
||||
retention-days: 40
|
||||
|
||||
- name: Upload artifacts resolc_web.js (nightly)
|
||||
uses: actions/upload-artifact@v4
|
||||
id: artifact-upload-step
|
||||
with:
|
||||
name: resolc_web.js
|
||||
path: resolc-wasm32-unknown-emscripten/resolc_web.js
|
||||
retention-days: 40
|
||||
|
||||
- name: Set output variables
|
||||
id: set-output
|
||||
env:
|
||||
TARGET: resolc_web_js
|
||||
run: |
|
||||
echo "Artifact URL is ${{ steps.artifact-upload-step.outputs.artifact-url }}"
|
||||
echo "Artifact SHA is ${{ steps.artifact-upload-step.outputs.artifact-digest }}"
|
||||
echo "${TARGET}_url=${{ steps.artifact-upload-step.outputs.artifact-url }}"
|
||||
echo "${TARGET}_url=${{ steps.artifact-upload-step.outputs.artifact-url }}" >> "$GITHUB_OUTPUT"
|
||||
echo "${TARGET}_sha=${{ steps.artifact-upload-step.outputs.artifact-digest }}""
|
||||
echo "${TARGET}_sha=${{ steps.artifact-upload-step.outputs.artifact-digest }}"" >> "$GITHUB_OUTPUT"
|
||||
|
||||
create-macos-fat-binary:
|
||||
if: ${{ needs.check_commits.outputs.has_commits == 'true' }}
|
||||
@@ -85,14 +303,18 @@ jobs:
|
||||
env:
|
||||
TARGET: resolc-universal-apple-darwin
|
||||
run: |
|
||||
echo "Artifact URL is ${{ steps.artifact-upload-step.outputs.artifact-url }}"
|
||||
echo "Artifact SHA is ${{ steps.artifact-upload-step.outputs.artifact-digest }}"
|
||||
echo "${TARGET}_url=${{ steps.artifact-upload-step.outputs.artifact-url }}"
|
||||
echo "${TARGET}_url=${{ steps.artifact-upload-step.outputs.artifact-url }}" >> "$GITHUB_OUTPUT"
|
||||
echo "${TARGET}_sha=${{ steps.artifact-upload-step.outputs.artifact-digest }}" >> "$GITHUB_OUTPUT"
|
||||
echo "${TARGET}_sha=${{ steps.artifact-upload-step.outputs.artifact-digest }}""
|
||||
echo "${TARGET}_sha=${{ steps.artifact-upload-step.outputs.artifact-digest }}"" >> "$GITHUB_OUTPUT"
|
||||
|
||||
generate-nightly-json:
|
||||
runs-on: ubuntu-24.04
|
||||
if: ${{ needs.check_commits.outputs.has_commits == 'true' }}
|
||||
environment: tags
|
||||
needs: [build, create-macos-fat-binary, check_commits]
|
||||
needs: [build-wasm, build, create-macos-fat-binary, check_commits]
|
||||
steps:
|
||||
- name: Checkout revive
|
||||
uses: actions/checkout@v4
|
||||
@@ -130,6 +352,8 @@ jobs:
|
||||
echo '[' > data.json
|
||||
echo '${{ toJSON(needs.build.outputs) }}' >> data.json
|
||||
echo ',' >> data.json
|
||||
echo '${{ toJSON(needs.build-wasm.outputs) }}' >> data.json
|
||||
echo ',' >> data.json
|
||||
echo '${{ toJSON(needs.create-macos-fat-binary.outputs) }}' >> data.json
|
||||
echo ']' >> data.json
|
||||
chmod +x bins/resolc-x86_64-unknown-linux-musl
|
||||
|
||||
+183
-19
@@ -1,5 +1,4 @@
|
||||
name: Build & Release
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["main"]
|
||||
@@ -15,6 +14,8 @@ concurrency:
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
# if changed, dont forget to update the env var in release-nightly.yml
|
||||
RUST_MUSL_CROSS_IMAGE: messense/rust-musl-cross@sha256:c0154e992adb791c3b848dd008939d19862549204f8cb26f5ca7a00f629e6067
|
||||
|
||||
jobs:
|
||||
check-version-changed:
|
||||
@@ -28,28 +29,33 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
# Check that tag and version in Cargo.toml match
|
||||
- name: Check versions
|
||||
id: versions
|
||||
run: |
|
||||
if [[ $CURRENT_TAG == 'main' ]]; then
|
||||
echo "::notice::Tag $CURRENT_TAG is not a release tag, skipping the check in the main branch"
|
||||
exit 0
|
||||
fi
|
||||
if [[ $CURRENT_TAG == 'main' ]];
|
||||
then
|
||||
echo "::notice::Tag $CURRENT_TAG is not a release tag, skipping the check in the main branch";
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ $CURRENT_TAG != "v"* ]]; then
|
||||
echo "::notice::Tag $CURRENT_TAG is not a release tag, skipping the check in a PR"
|
||||
exit 0
|
||||
fi
|
||||
if [[ $CURRENT_TAG != "v"* ]];
|
||||
then
|
||||
echo "::notice::Tag $CURRENT_TAG is not a release tag, skipping the check in a PR";
|
||||
exit 0
|
||||
fi
|
||||
|
||||
export PKG_VER=v$(cat crates/resolc/Cargo.toml | grep -A 5 package] | grep version | cut -d '=' -f 2 | tr -d '"' | tr -d " ")
|
||||
echo "Current tag $CURRENT_TAG"
|
||||
echo "Package version $PKG_VER"
|
||||
#
|
||||
if [[ $CURRENT_TAG != $PKG_VER ]];
|
||||
then
|
||||
echo "::error::Tag $CURRENT_TAG doesn't match package version $PKG_VER in Cargo.toml, please fix";
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $CURRENT_TAG != $PKG_VER ]]; then
|
||||
echo "::error::Tag $CURRENT_TAG doesn't match package version $PKG_VER in Cargo.toml, please fix"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Generating release notes early, in order to avoid checkout at the last step
|
||||
export RELEASE_NOTES="$(sed '/^## '${CURRENT_TAG}'/,/^## v/!d' CHANGELOG.md | sed -e '1d' -e '$d')"
|
||||
|
||||
echo "Release notes:"
|
||||
@@ -60,15 +66,173 @@ jobs:
|
||||
echo 'EOF' >> $GITHUB_OUTPUT
|
||||
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
target:
|
||||
[
|
||||
x86_64-unknown-linux-musl,
|
||||
aarch64-apple-darwin,
|
||||
x86_64-apple-darwin,
|
||||
x86_64-pc-windows-msvc,
|
||||
]
|
||||
include:
|
||||
- target: x86_64-unknown-linux-musl
|
||||
type: musl
|
||||
runner: ubuntu-24.04
|
||||
- target: aarch64-apple-darwin
|
||||
type: native
|
||||
runner: macos-14
|
||||
- target: x86_64-apple-darwin
|
||||
type: native
|
||||
runner: macos-13
|
||||
- target: x86_64-pc-windows-msvc
|
||||
type: native
|
||||
runner: windows-2022
|
||||
runs-on: ${{ matrix.runner }}
|
||||
needs: [check-version-changed]
|
||||
uses: ./.github/workflows/reusable-build.yml
|
||||
with:
|
||||
is_release: true
|
||||
retention_days: 1
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
# without this it will override our rust flags
|
||||
rustflags: ""
|
||||
cache-key: ${{ matrix.target }}
|
||||
|
||||
- name: Download LLVM
|
||||
uses: ./.github/actions/get-llvm
|
||||
with:
|
||||
target: ${{ matrix.target }}
|
||||
|
||||
- name: Build
|
||||
if: ${{ matrix.type == 'native' }}
|
||||
shell: bash
|
||||
run: |
|
||||
export LLVM_SYS_181_PREFIX=$PWD/llvm-${{ matrix.target }}
|
||||
make install-bin
|
||||
mv target/release/resolc resolc-${{ matrix.target }} || mv target/release/resolc.exe resolc-${{ matrix.target }}.exe
|
||||
|
||||
- name: Build
|
||||
if: ${{ matrix.type == 'musl' }}
|
||||
run: |
|
||||
docker run -v $PWD:/opt/revive $RUST_MUSL_CROSS_IMAGE /bin/bash -c "
|
||||
cd /opt/revive
|
||||
chown -R root:root .
|
||||
apt update && apt upgrade -y && apt install -y pkg-config
|
||||
export LLVM_SYS_181_PREFIX=/opt/revive/llvm-${{ matrix.target }}
|
||||
make install-bin
|
||||
mv target/${{ matrix.target }}/release/resolc resolc-${{ matrix.target }}
|
||||
"
|
||||
sudo chown -R $(id -u):$(id -g) .
|
||||
|
||||
- name: Install Solc
|
||||
uses: ./.github/actions/get-solc
|
||||
|
||||
- name: Basic Sanity Check
|
||||
shell: bash
|
||||
run: |
|
||||
result=$(./resolc-${{ matrix.target }} --bin crates/integration/contracts/flipper.sol)
|
||||
echo $result
|
||||
if [[ $result == *'50564d'* ]]; then exit 0; else exit 1; fi
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: resolc-${{ matrix.target }}
|
||||
path: resolc-${{ matrix.target }}*
|
||||
retention-days: 1
|
||||
|
||||
build-wasm:
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [check-version-changed]
|
||||
env:
|
||||
RELEASE_RESOLC_WASM_URI: https://github.com/paritytech/revive/releases/download/${{ github.ref_name }}/resolc.wasm
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
target: wasm32-unknown-emscripten
|
||||
# without this it will override our rust flags
|
||||
rustflags: ""
|
||||
|
||||
- name: Download Host LLVM
|
||||
uses: ./.github/actions/get-llvm
|
||||
with:
|
||||
target: x86_64-unknown-linux-gnu
|
||||
|
||||
- name: Download Wasm LLVM
|
||||
uses: ./.github/actions/get-llvm
|
||||
with:
|
||||
target: wasm32-unknown-emscripten
|
||||
|
||||
- name: Download EMSDK
|
||||
uses: ./.github/actions/get-emsdk
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export LLVM_SYS_181_PREFIX=$PWD/llvm-x86_64-unknown-linux-gnu
|
||||
export REVIVE_LLVM_TARGET_PREFIX=$PWD/llvm-wasm32-unknown-emscripten
|
||||
source emsdk/emsdk_env.sh
|
||||
make install-wasm
|
||||
chmod -x ./target/wasm32-unknown-emscripten/release/resolc.wasm
|
||||
|
||||
- name: Set Up Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "20"
|
||||
|
||||
- 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
|
||||
node -e "
|
||||
const soljson = require('solc/soljson');
|
||||
const createRevive = require('./target/wasm32-unknown-emscripten/release/resolc.js');
|
||||
|
||||
const compiler = createRevive();
|
||||
compiler.soljson = soljson;
|
||||
|
||||
const standardJsonInput =
|
||||
{
|
||||
language: 'Solidity',
|
||||
sources: {
|
||||
'MyContract.sol': {
|
||||
content: 'pragma solidity ^0.8.0; contract MyContract { function greet() public pure returns (string memory) { return \'Hello\'; } }',
|
||||
},
|
||||
},
|
||||
settings: { optimizer: { enabled: false } }
|
||||
};
|
||||
|
||||
compiler.writeToStdin(JSON.stringify(standardJsonInput));
|
||||
compiler.callMain(['--standard-json']);
|
||||
|
||||
// Collect output
|
||||
const stdout = compiler.readFromStdout();
|
||||
const stderr = compiler.readFromStderr();
|
||||
|
||||
if (stderr) { console.error(stderr); process.exit(1); }
|
||||
|
||||
let out = JSON.parse(stdout);
|
||||
let bytecode = out.contracts['MyContract.sol']['MyContract'].evm.bytecode.object
|
||||
console.log(bytecode);
|
||||
|
||||
if(!bytecode.startsWith('50564d')) { process.exit(1); }
|
||||
"
|
||||
|
||||
- name: Compress Artifact
|
||||
run: |
|
||||
mkdir -p resolc-wasm32-unknown-emscripten
|
||||
mv ./target/wasm32-unknown-emscripten/release/resolc.js ./resolc-wasm32-unknown-emscripten/
|
||||
mv ./target/wasm32-unknown-emscripten/release/resolc.wasm ./resolc-wasm32-unknown-emscripten/
|
||||
mv ./target/wasm32-unknown-emscripten/release/resolc_web.js ./resolc-wasm32-unknown-emscripten/
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: resolc-wasm32-unknown-emscripten
|
||||
path: resolc-wasm32-unknown-emscripten/*
|
||||
retention-days: 1
|
||||
|
||||
create-release:
|
||||
if: startsWith(github.ref_name, 'v')
|
||||
needs: [check-version-changed, build]
|
||||
needs: [check-version-changed, build-wasm]
|
||||
runs-on: macos-14
|
||||
environment: tags
|
||||
steps:
|
||||
|
||||
@@ -1,262 +0,0 @@
|
||||
name: Reusable Build
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
is_release:
|
||||
description: "Whether this is a release build"
|
||||
required: true
|
||||
type: boolean
|
||||
retention_days:
|
||||
description: "Artifact retention days"
|
||||
required: false
|
||||
type: number
|
||||
default: 1
|
||||
outputs:
|
||||
resolc-x86_64-unknown-linux-musl_url:
|
||||
value: ${{ jobs.build.outputs.resolc-x86_64-unknown-linux-musl_url }}
|
||||
resolc-x86_64-unknown-linux-musl_sha:
|
||||
value: ${{ jobs.build.outputs.resolc-x86_64-unknown-linux-musl_sha }}
|
||||
resolc-aarch64-apple-darwin_url:
|
||||
value: ${{ jobs.build.outputs.resolc-aarch64-apple-darwin_url }}
|
||||
resolc-aarch64-apple-darwin_sha:
|
||||
value: ${{ jobs.build.outputs.resolc-aarch64-apple-darwin_sha }}
|
||||
resolc-x86_64-apple-darwin_url:
|
||||
value: ${{ jobs.build.outputs.resolc-x86_64-apple-darwin_url }}
|
||||
resolc-x86_64-apple-darwin_sha:
|
||||
value: ${{ jobs.build.outputs.resolc-x86_64-apple-darwin_sha }}
|
||||
resolc-x86_64-pc-windows-msvc_url:
|
||||
value: ${{ jobs.build.outputs.resolc-x86_64-pc-windows-msvc_url }}
|
||||
resolc-x86_64-pc-windows-msvc_sha:
|
||||
value: ${{ jobs.build.outputs.resolc-x86_64-pc-windows-msvc_sha }}
|
||||
resolc-web_js_url:
|
||||
value: ${{ jobs.build-wasm.outputs.resolc_web_js_url }}
|
||||
resolc-web_js_sha:
|
||||
value: ${{ jobs.build-wasm.outputs.resolc_web_js_sha }}
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
RUST_MUSL_CROSS_IMAGE: messense/rust-musl-cross@sha256:c0154e992adb791c3b848dd008939d19862549204f8cb26f5ca7a00f629e6067
|
||||
|
||||
jobs:
|
||||
build:
|
||||
# github actions matrix jobs don't support multiple outputs
|
||||
# ugly workaround from https://github.com/orgs/community/discussions/17245#discussioncomment-11222880
|
||||
outputs:
|
||||
resolc-x86_64-unknown-linux-musl_url: ${{ steps.set-output.outputs.resolc-x86_64-unknown-linux-musl_url }}
|
||||
resolc-x86_64-unknown-linux-musl_sha: ${{ steps.set-output.outputs.resolc-x86_64-unknown-linux-musl_sha }}
|
||||
resolc-aarch64-apple-darwin_url: ${{ steps.set-output.outputs.resolc-aarch64-apple-darwin_url }}
|
||||
resolc-aarch64-apple-darwin_sha: ${{ steps.set-output.outputs.resolc-aarch64-apple-darwin_sha }}
|
||||
resolc-x86_64-apple-darwin_url: ${{ steps.set-output.outputs.resolc-x86_64-apple-darwin_url }}
|
||||
resolc-x86_64-apple-darwin_sha: ${{ steps.set-output.outputs.resolc-x86_64-apple-darwin_sha }}
|
||||
resolc-x86_64-pc-windows-msvc_url: ${{ steps.set-output.outputs.resolc-x86_64-pc-windows-msvc_url }}
|
||||
resolc-x86_64-pc-windows-msvc_sha: ${{ steps.set-output.outputs.resolc-x86_64-pc-windows-msvc_sha }}
|
||||
strategy:
|
||||
matrix:
|
||||
target:
|
||||
[
|
||||
x86_64-unknown-linux-musl,
|
||||
aarch64-apple-darwin,
|
||||
x86_64-apple-darwin,
|
||||
x86_64-pc-windows-msvc,
|
||||
]
|
||||
include:
|
||||
- target: x86_64-unknown-linux-musl
|
||||
type: musl
|
||||
runner: ubuntu-24.04
|
||||
- target: aarch64-apple-darwin
|
||||
type: native
|
||||
runner: macos-14
|
||||
- target: x86_64-apple-darwin
|
||||
type: native
|
||||
runner: macos-13
|
||||
- target: x86_64-pc-windows-msvc
|
||||
type: native
|
||||
runner: windows-2022
|
||||
runs-on: ${{ matrix.runner }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
rustflags: ""
|
||||
cache-key: ${{ matrix.target }}
|
||||
|
||||
- name: Download LLVM
|
||||
uses: ./.github/actions/get-llvm
|
||||
with:
|
||||
target: ${{ matrix.target }}
|
||||
|
||||
- name: Build (Native)
|
||||
if: ${{ matrix.type == 'native' }}
|
||||
shell: bash
|
||||
run: |
|
||||
export LLVM_SYS_181_PREFIX=$PWD/llvm-${{ matrix.target }}
|
||||
make install-bin
|
||||
mv target/release/resolc resolc-${{ matrix.target }} || mv target/release/resolc.exe resolc-${{ matrix.target }}.exe
|
||||
|
||||
- name: Build (MUSL)
|
||||
if: ${{ matrix.type == 'musl' }}
|
||||
run: |
|
||||
docker run -v $PWD:/opt/revive $RUST_MUSL_CROSS_IMAGE /bin/bash -c "
|
||||
cd /opt/revive
|
||||
chown -R root:root .
|
||||
apt update && apt upgrade -y && apt install -y pkg-config
|
||||
export LLVM_SYS_181_PREFIX=/opt/revive/llvm-${{ matrix.target }}
|
||||
make install-bin
|
||||
mv target/${{ matrix.target }}/release/resolc resolc-${{ matrix.target }}
|
||||
"
|
||||
sudo chown -R $(id -u):$(id -g) .
|
||||
|
||||
- name: Install Solc
|
||||
uses: ./.github/actions/get-solc
|
||||
|
||||
- name: Basic Sanity Check
|
||||
shell: bash
|
||||
run: |
|
||||
result=$(./resolc-${{ matrix.target }} --bin crates/integration/contracts/flipper.sol)
|
||||
echo $result
|
||||
if [[ $result == *'50564d'* ]]; then exit 0; else exit 1; fi
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
id: artifact-upload-step
|
||||
with:
|
||||
name: resolc-${{ matrix.target }}
|
||||
path: resolc-${{ matrix.target }}*
|
||||
retention-days: ${{ inputs.retention_days }}
|
||||
|
||||
- name: Set output variables
|
||||
if: ${{ !inputs.is_release }}
|
||||
id: set-output
|
||||
shell: bash
|
||||
run: |
|
||||
echo "resolc-${{ matrix.target }}_url=${{ steps.artifact-upload-step.outputs.artifact-url }}" >> "$GITHUB_OUTPUT"
|
||||
echo "resolc-${{ matrix.target }}_sha=${{ steps.artifact-upload-step.outputs.artifact-digest }}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
build-wasm:
|
||||
runs-on: ubuntu-24.04
|
||||
outputs:
|
||||
resolc_web_js_url: ${{ steps.set-output.outputs.resolc_web_js_url }}
|
||||
resolc_web_js_sha: ${{ steps.set-output.outputs.resolc_web_js_sha }}
|
||||
env:
|
||||
RELEASE_RESOLC_WASM_URI: https://github.com/paritytech/revive/releases/download/${{ github.ref_name }}/resolc.wasm
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
target: wasm32-unknown-emscripten
|
||||
rustflags: ""
|
||||
|
||||
- name: Download Host LLVM
|
||||
uses: ./.github/actions/get-llvm
|
||||
with:
|
||||
target: x86_64-unknown-linux-gnu
|
||||
|
||||
- name: Download Wasm LLVM
|
||||
uses: ./.github/actions/get-llvm
|
||||
with:
|
||||
target: wasm32-unknown-emscripten
|
||||
|
||||
- name: Download EMSDK
|
||||
uses: ./.github/actions/get-emsdk
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export LLVM_SYS_181_PREFIX=$PWD/llvm-x86_64-unknown-linux-gnu
|
||||
export REVIVE_LLVM_TARGET_PREFIX=$PWD/llvm-wasm32-unknown-emscripten
|
||||
source emsdk/emsdk_env.sh
|
||||
make install-wasm
|
||||
chmod -x ./target/wasm32-unknown-emscripten/release/resolc.wasm
|
||||
|
||||
- name: Set Up Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "20"
|
||||
|
||||
- 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
|
||||
node -e "
|
||||
const soljson = require('solc/soljson');
|
||||
const createRevive = require('./target/wasm32-unknown-emscripten/release/resolc.js');
|
||||
|
||||
const compiler = createRevive();
|
||||
compiler.soljson = soljson;
|
||||
|
||||
const standardJsonInput =
|
||||
{
|
||||
language: 'Solidity',
|
||||
sources: {
|
||||
'MyContract.sol': {
|
||||
content: 'pragma solidity ^0.8.0; contract MyContract { function greet() public pure returns (string memory) { return \'Hello\'; } }',
|
||||
},
|
||||
},
|
||||
settings: { optimizer: { enabled: false } }
|
||||
};
|
||||
|
||||
compiler.writeToStdin(JSON.stringify(standardJsonInput));
|
||||
compiler.callMain(['--standard-json']);
|
||||
|
||||
const stdout = compiler.readFromStdout();
|
||||
const stderr = compiler.readFromStderr();
|
||||
|
||||
if (stderr) { console.error(stderr); process.exit(1); }
|
||||
|
||||
let out = JSON.parse(stdout);
|
||||
let bytecode = out.contracts['MyContract.sol']['MyContract'].evm.bytecode.object
|
||||
console.log(bytecode);
|
||||
|
||||
if(!bytecode.startsWith('50564d')) { process.exit(1); }
|
||||
"
|
||||
|
||||
- name: Compress Artifact
|
||||
run: |
|
||||
mkdir -p resolc-wasm32-unknown-emscripten
|
||||
mv ./target/wasm32-unknown-emscripten/release/resolc.js ./resolc-wasm32-unknown-emscripten/
|
||||
mv ./target/wasm32-unknown-emscripten/release/resolc.wasm ./resolc-wasm32-unknown-emscripten/
|
||||
mv ./target/wasm32-unknown-emscripten/release/resolc_web.js ./resolc-wasm32-unknown-emscripten/
|
||||
|
||||
- name: Upload artifacts (Release)
|
||||
if: ${{ inputs.is_release }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: resolc-wasm32-unknown-emscripten
|
||||
path: resolc-wasm32-unknown-emscripten/*
|
||||
retention-days: ${{ inputs.retention_days }}
|
||||
|
||||
# There is no way to upload several files as several artifacts with a single upload-artifact step
|
||||
# It's needed to have resolc_web.js separately for night builds for resolc-bin repo
|
||||
# https://github.com/actions/upload-artifact/issues/331
|
||||
- name: Upload artifact resolc.js (Nightly)
|
||||
if: ${{ !inputs.is_release }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: resolc.js
|
||||
path: resolc-wasm32-unknown-emscripten/resolc.js
|
||||
retention-days: ${{ inputs.retention_days }}
|
||||
|
||||
- name: Upload artifacts resolc.wasm (Nightly)
|
||||
if: ${{ !inputs.is_release }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: resolc.wasm
|
||||
path: resolc-wasm32-unknown-emscripten/resolc.wasm
|
||||
retention-days: ${{ inputs.retention_days }}
|
||||
|
||||
- name: Upload artifacts resolc_web.js (Nightly)
|
||||
if: ${{ !inputs.is_release }}
|
||||
uses: actions/upload-artifact@v4
|
||||
id: artifact-upload-step
|
||||
with:
|
||||
name: resolc_web.js
|
||||
path: resolc-wasm32-unknown-emscripten/resolc_web.js
|
||||
retention-days: ${{ inputs.retention_days }}
|
||||
|
||||
- name: Set output variables
|
||||
if: ${{ !inputs.is_release }}
|
||||
id: set-output
|
||||
env:
|
||||
TARGET: resolc_web_js
|
||||
run: |
|
||||
echo "${TARGET}_url=${{ steps.artifact-upload-step.outputs.artifact-url }}" >> "$GITHUB_OUTPUT"
|
||||
echo "${TARGET}_sha=${{ steps.artifact-upload-step.outputs.artifact-digest }}" >> "$GITHUB_OUTPUT"
|
||||
@@ -4,35 +4,8 @@
|
||||
|
||||
This is a development pre-release.
|
||||
|
||||
Supported `polkadot-sdk` rev: `2509.0.0`
|
||||
|
||||
## v0.5.0
|
||||
|
||||
This is a development pre-release.
|
||||
|
||||
Supported `polkadot-sdk` rev: `2509.0.0`
|
||||
|
||||
### Added
|
||||
- Support for `SELFDESTRUCT`.
|
||||
|
||||
### Changed
|
||||
- Emulated EVM heap memory accesses of zero length are never out of bounds.
|
||||
- Switched to newer and cheaper storage syscalls (omits reads and writes of `0` values).
|
||||
|
||||
### Fixed
|
||||
- Introduced a workaround avoiding compiler crashes caused by a bug in LLVM affecting `SDIV`.
|
||||
- An off-by-one bug affecting `SDIV` overflow semantics.
|
||||
|
||||
## v0.4.1
|
||||
|
||||
This is a development pre-release.
|
||||
|
||||
Supported `polkadot-sdk` rev: `2503.0.1`
|
||||
|
||||
### Changed
|
||||
- The `ast` output is no longer pruned in standard JSON mode (required for foundry).
|
||||
- Support `standard_json.output_selection` to also look at per file settings.
|
||||
|
||||
## v0.4.0
|
||||
|
||||
This is a development pre-release.
|
||||
|
||||
Generated
+1919
-2558
File diff suppressed because it is too large
Load Diff
+18
-18
@@ -15,21 +15,21 @@ rust-version = "1.85.0"
|
||||
|
||||
[workspace.dependencies]
|
||||
lld-sys = { version = "0.1.0", path = "crates/lld-sys" }
|
||||
resolc = { version = "0.5.0", path = "crates/resolc", default-features = false }
|
||||
resolc = { version = "0.4.0", path = "crates/resolc", default-features = false }
|
||||
revive-benchmarks = { version = "0.1.0", path = "crates/benchmarks" }
|
||||
revive-build-utils = { version = "0.2.0", path = "crates/build-utils" }
|
||||
revive-builtins = { version = "0.1.0", path = "crates/builtins" }
|
||||
revive-common = { version = "0.2.1", path = "crates/common" }
|
||||
revive-common = { version = "0.2.0", path = "crates/common" }
|
||||
revive-differential = { version = "0.2.0", path = "crates/differential" }
|
||||
revive-explorer = { version = "0.1.0", path = "crates/explore" }
|
||||
revive-integration = { version = "0.3.0", path = "crates/integration" }
|
||||
revive-integration = { version = "0.2.0", path = "crates/integration" }
|
||||
revive-linker = { version = "0.2.0", path = "crates/linker" }
|
||||
revive-llvm-context = { version = "0.5.0", path = "crates/llvm-context" }
|
||||
revive-runner = { version = "0.3.0", path = "crates/runner" }
|
||||
revive-runtime-api = { version = "0.4.0", path = "crates/runtime-api" }
|
||||
revive-solc-json-interface = { version = "0.4.0", path = "crates/solc-json-interface", default-features = false }
|
||||
revive-llvm-context = { version = "0.4.0", path = "crates/llvm-context" }
|
||||
revive-runner = { version = "0.2.0", path = "crates/runner" }
|
||||
revive-runtime-api = { version = "0.3.0", path = "crates/runtime-api" }
|
||||
revive-solc-json-interface = { version = "0.3.0", path = "crates/solc-json-interface", default-features = false }
|
||||
revive-stdlib = { version = "0.2.0", path = "crates/stdlib" }
|
||||
revive-yul = { version = "0.4.0", path = "crates/yul" }
|
||||
revive-yul = { version = "0.3.0", path = "crates/yul" }
|
||||
|
||||
hex = "0.4.3"
|
||||
cc = "1.2"
|
||||
@@ -46,21 +46,21 @@ num = "0.4.3"
|
||||
sha1 = "0.10"
|
||||
sha3 = "0.10"
|
||||
thiserror = "2.0"
|
||||
which = "8.0"
|
||||
which = "7.0"
|
||||
path-slash = "0.2"
|
||||
rayon = "1.10"
|
||||
clap = { version = "4", default-features = false, features = ["derive"] }
|
||||
polkavm-common = "0.29.0"
|
||||
polkavm-linker = "0.29.0"
|
||||
polkavm-disassembler = "0.29.0"
|
||||
polkavm = "0.29.0"
|
||||
polkavm-common = "0.24.0"
|
||||
polkavm-linker = "0.24.0"
|
||||
polkavm-disassembler = "0.24.0"
|
||||
polkavm = "0.24.0"
|
||||
alloy-primitives = { version = "1.1", features = ["serde"] }
|
||||
alloy-sol-types = "1.1"
|
||||
alloy-genesis = "1.0.41"
|
||||
alloy-genesis = "1.0"
|
||||
alloy-serde = "1.0"
|
||||
env_logger = { version = "0.11.8", default-features = false }
|
||||
serde_stacker = "0.1.12"
|
||||
criterion = { version = "0.7", features = ["html_reports"] }
|
||||
criterion = { version = "0.6", features = ["html_reports"] }
|
||||
log = { version = "0.4.27" }
|
||||
git2 = { version = "0.20.2", default-features = false }
|
||||
downloader = "0.2.8"
|
||||
@@ -68,15 +68,15 @@ flate2 = "1.1"
|
||||
fs_extra = "1.3"
|
||||
num_cpus = "1"
|
||||
tar = "0.4"
|
||||
toml = "0.9"
|
||||
assert_cmd = "2"
|
||||
toml = "0.8"
|
||||
assert_cmd = "2.0"
|
||||
assert_fs = "1.1"
|
||||
normpath = "1.3"
|
||||
|
||||
# polkadot-sdk and friends
|
||||
codec = { version = "3.7.5", default-features = false, package = "parity-scale-codec" }
|
||||
scale-info = { version = "2.11.6", default-features = false }
|
||||
polkadot-sdk = { version = "2509.0.0" }
|
||||
polkadot-sdk = { version = "2503.0.1" }
|
||||
|
||||
# llvm
|
||||
[workspace.dependencies.inkwell]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "revive-common"
|
||||
version = "0.2.1"
|
||||
version = "0.2.0"
|
||||
license.workspace = true
|
||||
edition.workspace = true
|
||||
repository.workspace = true
|
||||
|
||||
@@ -30,8 +30,8 @@ impl FromStr for ObjectFormat {
|
||||
"PVM" => Ok(Self::PVM),
|
||||
_ => anyhow::bail!(
|
||||
"Unknown object format: {value}. Supported formats: {}, {}",
|
||||
Self::ELF,
|
||||
Self::PVM,
|
||||
Self::ELF.to_string(),
|
||||
Self::PVM.to_string()
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "revive-integration"
|
||||
version = "0.3.0"
|
||||
version = "0.2.0"
|
||||
license.workspace = true
|
||||
edition.workspace = true
|
||||
repository.workspace = true
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"Baseline": 914,
|
||||
"Computation": 2295,
|
||||
"DivisionArithmetics": 14496,
|
||||
"ERC20": 17482,
|
||||
"Events": 1674,
|
||||
"FibonacciIterative": 1490,
|
||||
"Flipper": 2086,
|
||||
"SHA1": 8158
|
||||
"Baseline": 932,
|
||||
"Computation": 2313,
|
||||
"DivisionArithmetics": 9103,
|
||||
"ERC20": 17479,
|
||||
"Events": 1692,
|
||||
"FibonacciIterative": 1508,
|
||||
"Flipper": 2098,
|
||||
"SHA1": 8176
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.24;
|
||||
|
||||
/* runner.json
|
||||
{
|
||||
"differential": true,
|
||||
"actions": [
|
||||
{
|
||||
"Instantiate": {
|
||||
"code": {
|
||||
"Solidity": {
|
||||
"contract": "MemoryBounds"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Call": {
|
||||
"dest": {
|
||||
"Instantiated": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
*/
|
||||
|
||||
contract MemoryBounds {
|
||||
fallback() external {
|
||||
assembly {
|
||||
// Accessing OOB offsets should always work when the length is 0.
|
||||
return(100000, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8;
|
||||
|
||||
// TODO: This currently fails the differential test.
|
||||
// The pallet doesn't send the correct balance back.
|
||||
|
||||
/* runner.json
|
||||
{
|
||||
"differential": false,
|
||||
"actions": [
|
||||
{
|
||||
"Upload": {
|
||||
"code": {
|
||||
"Solidity": {
|
||||
"contract": "SelfdestructTester"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Instantiate": {
|
||||
"code": {
|
||||
"Solidity": {
|
||||
"contract": "Selfdestruct"
|
||||
}
|
||||
},
|
||||
"value": 123456789
|
||||
}
|
||||
},
|
||||
{
|
||||
"Call": {
|
||||
"dest": {
|
||||
"Instantiated": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
*/
|
||||
|
||||
contract Selfdestruct {
|
||||
address tester;
|
||||
uint value;
|
||||
|
||||
constructor() payable {
|
||||
require(msg.value > 0, "the test should have value");
|
||||
value = msg.value;
|
||||
|
||||
SelfdestructTester s = new SelfdestructTester{value: msg.value}();
|
||||
tester = address(s);
|
||||
}
|
||||
|
||||
fallback() external {
|
||||
(bool success, ) = tester.call(hex"");
|
||||
require(success, "the call to the self destructing contract should succeed");
|
||||
}
|
||||
}
|
||||
|
||||
contract SelfdestructTester {
|
||||
constructor() payable {}
|
||||
|
||||
fallback() external {
|
||||
selfdestruct(payable(msg.sender));
|
||||
}
|
||||
}
|
||||
@@ -62,8 +62,6 @@ test_spec!(function_type, "FunctionType", "FunctionType.sol");
|
||||
test_spec!(layout_at, "LayoutAt", "LayoutAt.sol");
|
||||
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");
|
||||
|
||||
fn instantiate(path: &str, contract: &str) -> Vec<SpecsAction> {
|
||||
vec![Instantiate {
|
||||
@@ -170,8 +168,6 @@ fn signed_division() {
|
||||
(minus_five, two),
|
||||
(I256::MINUS_ONE, I256::MIN),
|
||||
(one, I256::ZERO),
|
||||
(I256::MIN, I256::MINUS_ONE),
|
||||
(I256::MIN + I256::ONE, I256::MINUS_ONE),
|
||||
] {
|
||||
actions.push(Call {
|
||||
origin: TestAddress::Alice,
|
||||
|
||||
@@ -6,7 +6,7 @@ authors = [
|
||||
"Anton Baliasnikov <aba@matterlabs.dev>",
|
||||
"Cyrill Leutwiler <cyrill@parity.io>",
|
||||
]
|
||||
version = "0.4.0"
|
||||
version = "0.3.0"
|
||||
license.workspace = true
|
||||
edition.workspace = true
|
||||
repository.workspace = true
|
||||
|
||||
@@ -2,20 +2,20 @@ pub mod common;
|
||||
|
||||
use std::process::Command;
|
||||
|
||||
use assert_cmd::{cargo, prelude::*};
|
||||
use assert_cmd::prelude::*;
|
||||
|
||||
/// This test verifies that the LLVM repository can be successfully cloned, built, and cleaned.
|
||||
#[test]
|
||||
fn clone_build_and_clean() -> anyhow::Result<()> {
|
||||
let test_dir = common::TestDir::with_lockfile(None)?;
|
||||
|
||||
Command::new(cargo::cargo_bin!("revive-llvm"))
|
||||
Command::cargo_bin(common::REVIVE_LLVM)?
|
||||
.current_dir(test_dir.path())
|
||||
.arg("clone")
|
||||
.assert()
|
||||
.success();
|
||||
|
||||
Command::new(cargo::cargo_bin!("revive-llvm"))
|
||||
Command::cargo_bin(common::REVIVE_LLVM)?
|
||||
.current_dir(test_dir.path())
|
||||
.arg("build")
|
||||
.arg("--llvm-projects")
|
||||
@@ -25,13 +25,13 @@ fn clone_build_and_clean() -> anyhow::Result<()> {
|
||||
.assert()
|
||||
.success();
|
||||
|
||||
Command::new(cargo::cargo_bin!("revive-llvm"))
|
||||
Command::cargo_bin(common::REVIVE_LLVM)?
|
||||
.current_dir(test_dir.path())
|
||||
.arg("builtins")
|
||||
.assert()
|
||||
.success();
|
||||
|
||||
Command::new(cargo::cargo_bin!("revive-llvm"))
|
||||
Command::cargo_bin(common::REVIVE_LLVM)?
|
||||
.current_dir(test_dir.path())
|
||||
.arg("clean")
|
||||
.assert()
|
||||
@@ -47,13 +47,13 @@ fn clone_build_and_clean() -> anyhow::Result<()> {
|
||||
fn clone_build_and_clean_musl() -> anyhow::Result<()> {
|
||||
let test_dir = common::TestDir::with_lockfile(None)?;
|
||||
|
||||
Command::new(cargo::cargo_bin!("revive-llvm"))
|
||||
Command::cargo_bin(common::REVIVE_LLVM)?
|
||||
.arg("clone")
|
||||
.current_dir(test_dir.path())
|
||||
.assert()
|
||||
.success();
|
||||
|
||||
Command::new(cargo::cargo_bin!("revive-llvm"))
|
||||
Command::cargo_bin(common::REVIVE_LLVM)?
|
||||
.current_dir(test_dir.path())
|
||||
.arg("build")
|
||||
.arg("--llvm-projects")
|
||||
@@ -63,7 +63,7 @@ fn clone_build_and_clean_musl() -> anyhow::Result<()> {
|
||||
.assert()
|
||||
.success();
|
||||
|
||||
Command::new(cargo::cargo_bin!("revive-llvm"))
|
||||
Command::cargo_bin(common::REVIVE_LLVM)?
|
||||
.arg("--target-env")
|
||||
.arg("musl")
|
||||
.arg("build")
|
||||
@@ -75,7 +75,7 @@ fn clone_build_and_clean_musl() -> anyhow::Result<()> {
|
||||
.assert()
|
||||
.success();
|
||||
|
||||
Command::new(cargo::cargo_bin!("revive-llvm"))
|
||||
Command::cargo_bin(common::REVIVE_LLVM)?
|
||||
.current_dir(test_dir.path())
|
||||
.arg("clean")
|
||||
.assert()
|
||||
@@ -91,13 +91,13 @@ fn clone_build_and_clean_musl() -> anyhow::Result<()> {
|
||||
fn debug_build_with_tests_coverage() -> anyhow::Result<()> {
|
||||
let test_dir = common::TestDir::with_lockfile(None)?;
|
||||
|
||||
Command::new(cargo::cargo_bin!("revive-llvm"))
|
||||
Command::cargo_bin(common::REVIVE_LLVM)?
|
||||
.current_dir(test_dir.path())
|
||||
.arg("clone")
|
||||
.assert()
|
||||
.success();
|
||||
|
||||
Command::new(cargo::cargo_bin!("revive-llvm"))
|
||||
Command::cargo_bin(common::REVIVE_LLVM)?
|
||||
.current_dir(test_dir.path())
|
||||
.arg("build")
|
||||
.arg("--enable-coverage")
|
||||
@@ -120,13 +120,13 @@ fn debug_build_with_tests_coverage() -> anyhow::Result<()> {
|
||||
fn build_with_sanitizers() -> anyhow::Result<()> {
|
||||
let test_dir = common::TestDir::with_lockfile(None)?;
|
||||
|
||||
Command::new(cargo::cargo_bin!("revive-llvm"))
|
||||
Command::cargo_bin(common::REVIVE_LLVM)?
|
||||
.current_dir(test_dir.path())
|
||||
.arg("clone")
|
||||
.assert()
|
||||
.success();
|
||||
|
||||
Command::new(cargo::cargo_bin!("revive-llvm"))
|
||||
Command::cargo_bin(common::REVIVE_LLVM)?
|
||||
.current_dir(test_dir.path())
|
||||
.arg("build")
|
||||
.arg("--sanitizer")
|
||||
@@ -146,16 +146,16 @@ fn build_with_sanitizers() -> anyhow::Result<()> {
|
||||
#[cfg(target_os = "linux")]
|
||||
fn clone_build_and_clean_emscripten() -> anyhow::Result<()> {
|
||||
let test_dir = common::TestDir::with_lockfile(None)?;
|
||||
let command = Command::new(cargo::cargo_bin!("revive-llvm"));
|
||||
let command = Command::cargo_bin(common::REVIVE_LLVM)?;
|
||||
let program = command.get_program().to_string_lossy();
|
||||
|
||||
Command::new(cargo::cargo_bin!("revive-llvm"))
|
||||
Command::cargo_bin(common::REVIVE_LLVM)?
|
||||
.current_dir(test_dir.path())
|
||||
.arg("clone")
|
||||
.assert()
|
||||
.success();
|
||||
|
||||
Command::new(cargo::cargo_bin!("revive-llvm"))
|
||||
Command::cargo_bin(common::REVIVE_LLVM)?
|
||||
.current_dir(test_dir.path())
|
||||
.arg("build")
|
||||
.arg("--llvm-projects")
|
||||
@@ -183,7 +183,7 @@ fn clone_build_and_clean_emscripten() -> anyhow::Result<()> {
|
||||
.assert()
|
||||
.success();
|
||||
|
||||
Command::new(cargo::cargo_bin!("revive-llvm"))
|
||||
Command::cargo_bin(common::REVIVE_LLVM)?
|
||||
.arg("clean")
|
||||
.current_dir(test_dir.path())
|
||||
.assert()
|
||||
|
||||
@@ -2,7 +2,7 @@ pub mod common;
|
||||
|
||||
use std::process::Command;
|
||||
|
||||
use assert_cmd::{cargo, prelude::*};
|
||||
use assert_cmd::prelude::*;
|
||||
|
||||
/// This test verifies that after cloning the LLVM repository, checking out a specific branch
|
||||
/// or reference works as expected.
|
||||
@@ -10,13 +10,13 @@ use assert_cmd::{cargo, prelude::*};
|
||||
fn checkout_after_clone() -> anyhow::Result<()> {
|
||||
let test_dir = common::TestDir::with_lockfile(None)?;
|
||||
|
||||
Command::new(cargo::cargo_bin!("revive-llvm"))
|
||||
Command::cargo_bin(common::REVIVE_LLVM)?
|
||||
.current_dir(test_dir.path())
|
||||
.arg("clone")
|
||||
.assert()
|
||||
.success();
|
||||
|
||||
Command::new(cargo::cargo_bin!("revive-llvm"))
|
||||
Command::cargo_bin(common::REVIVE_LLVM)?
|
||||
.current_dir(test_dir.path())
|
||||
.arg("checkout")
|
||||
.assert()
|
||||
@@ -31,13 +31,13 @@ fn checkout_after_clone() -> anyhow::Result<()> {
|
||||
fn force_checkout() -> anyhow::Result<()> {
|
||||
let test_dir = common::TestDir::with_lockfile(None)?;
|
||||
|
||||
Command::new(cargo::cargo_bin!("revive-llvm"))
|
||||
Command::cargo_bin(common::REVIVE_LLVM)?
|
||||
.current_dir(test_dir.path())
|
||||
.arg("clone")
|
||||
.assert()
|
||||
.success();
|
||||
|
||||
Command::new(cargo::cargo_bin!("revive-llvm"))
|
||||
Command::cargo_bin(common::REVIVE_LLVM)?
|
||||
.current_dir(test_dir.path())
|
||||
.arg("checkout")
|
||||
.arg("--force")
|
||||
|
||||
@@ -2,7 +2,7 @@ pub mod common;
|
||||
|
||||
use std::process::Command;
|
||||
|
||||
use assert_cmd::{cargo, prelude::*};
|
||||
use assert_cmd::prelude::*;
|
||||
|
||||
/// This test verifies that the LLVM repository can be successfully cloned using a specific branch
|
||||
/// and reference.
|
||||
@@ -10,7 +10,7 @@ use assert_cmd::{cargo, prelude::*};
|
||||
fn clone() -> anyhow::Result<()> {
|
||||
let test_dir = common::TestDir::with_lockfile(None)?;
|
||||
|
||||
Command::new(cargo::cargo_bin!("revive-llvm"))
|
||||
Command::cargo_bin(common::REVIVE_LLVM)?
|
||||
.current_dir(test_dir.path())
|
||||
.arg("clone")
|
||||
.assert()
|
||||
@@ -25,7 +25,7 @@ fn clone() -> anyhow::Result<()> {
|
||||
fn clone_deep() -> anyhow::Result<()> {
|
||||
let test_dir = common::TestDir::with_lockfile(None)?;
|
||||
|
||||
Command::new(cargo::cargo_bin!("revive-llvm"))
|
||||
Command::cargo_bin(common::REVIVE_LLVM)?
|
||||
.current_dir(test_dir.path())
|
||||
.arg("clone")
|
||||
.arg("--deep")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "revive-llvm-context"
|
||||
version = "0.5.0"
|
||||
version = "0.4.0"
|
||||
license.workspace = true
|
||||
edition.workspace = true
|
||||
repository.workspace = true
|
||||
|
||||
@@ -92,7 +92,7 @@ impl RuntimeFunction for SignedDivision {
|
||||
"max_uint",
|
||||
)?;
|
||||
let is_operand_1_overflow = context.builder().build_int_compare(
|
||||
inkwell::IntPredicate::SLT,
|
||||
inkwell::IntPredicate::EQ,
|
||||
operand_1,
|
||||
context.builder().build_int_neg(max_uint, "min_uint")?,
|
||||
"is_operand_1_overflow",
|
||||
|
||||
@@ -47,17 +47,6 @@ impl RuntimeFunction for Sbrk {
|
||||
let offset = Self::paramater(context, 0).into_int_value();
|
||||
let size = Self::paramater(context, 1).into_int_value();
|
||||
|
||||
let return_block = context.append_basic_block("return_pointer");
|
||||
let body_block = context.append_basic_block("body");
|
||||
let is_size_zero = context.builder().build_int_compare(
|
||||
inkwell::IntPredicate::EQ,
|
||||
size,
|
||||
context.xlen_type().const_zero(),
|
||||
"is_size_zero",
|
||||
)?;
|
||||
context.build_conditional_branch(is_size_zero, return_block, body_block)?;
|
||||
|
||||
context.set_basic_block(body_block);
|
||||
let trap_block = context.append_basic_block("trap");
|
||||
let offset_in_bounds_block = context.append_basic_block("offset_in_bounds");
|
||||
let is_offset_out_of_bounds = context.builder().build_int_compare(
|
||||
@@ -102,6 +91,7 @@ impl RuntimeFunction for Sbrk {
|
||||
)?;
|
||||
|
||||
context.set_basic_block(size_in_bounds_block);
|
||||
let return_block = context.append_basic_block("return_pointer");
|
||||
let new_size_block = context.append_basic_block("new_size");
|
||||
let is_new_size = context.builder().build_int_compare(
|
||||
inkwell::IntPredicate::UGT,
|
||||
|
||||
@@ -8,7 +8,6 @@ use inkwell::debug_info::AsDIScope;
|
||||
use inkwell::debug_info::DIScope;
|
||||
use inkwell::types::BasicType;
|
||||
use inkwell::values::BasicValue;
|
||||
use inkwell::values::InstructionOpcode;
|
||||
use revive_solc_json_interface::PolkaVMDefaultHeapMemorySize;
|
||||
use revive_solc_json_interface::PolkaVMDefaultStackMemorySize;
|
||||
use revive_solc_json_interface::SolcStandardJsonInputSettingsPolkaVMMemory;
|
||||
@@ -289,17 +288,6 @@ impl<'ctx> Context<'ctx> {
|
||||
)
|
||||
})?;
|
||||
|
||||
// Remove MinSize on functions that perform large integer div/rem to
|
||||
// avoid compiler crash that happens when large integer div/rem by
|
||||
// power-of-2 are not being expanded by ExpandLargeIntDivRem pass as
|
||||
// it expects peephole from DAGCombine, which doesn't happen due to the
|
||||
// MinSize attribute being set on the function.
|
||||
// NOTE: As soon as it strips attribute from a function where large
|
||||
// integer div/rem is used, it's crucial to call it after inlining.
|
||||
// TODO: Remove this once LLVM fix is backported to LLVM 21 and we
|
||||
// switch to corresponding inkwell version.
|
||||
self.strip_minsize_for_divrem();
|
||||
|
||||
self.debug_config
|
||||
.dump_llvm_ir_optimized(contract_path, self.module())?;
|
||||
|
||||
@@ -1406,38 +1394,4 @@ impl<'ctx> Context<'ctx> {
|
||||
name.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
/// Scans all functions in the module and removes the `MinSize` attribute
|
||||
/// if the function contains any large sdiv, udiv, srem, urem instructions with either unknown
|
||||
/// NOTE: The check here could be relaxed by checking denominator: if the denominator is
|
||||
/// unknown or is a power-of-2 constant, then need to strip the `minsize` attribute; otherwise
|
||||
/// instruction can be ignored as backend will expand it correctly.
|
||||
fn strip_minsize_for_divrem(&self) {
|
||||
self.module().get_functions().for_each(|func| {
|
||||
let has_divrem = func.get_basic_block_iter().any(|b| {
|
||||
b.get_instructions().any(|inst| match inst.get_opcode() {
|
||||
InstructionOpcode::SDiv
|
||||
| InstructionOpcode::UDiv
|
||||
| InstructionOpcode::SRem
|
||||
| InstructionOpcode::URem => {
|
||||
inst.get_type().into_int_type().get_bit_width() >= 256
|
||||
}
|
||||
_ => false,
|
||||
})
|
||||
});
|
||||
if has_divrem
|
||||
&& func
|
||||
.get_enum_attribute(
|
||||
inkwell::attributes::AttributeLoc::Function,
|
||||
Attribute::MinSize as u32,
|
||||
)
|
||||
.is_some()
|
||||
{
|
||||
func.remove_enum_attribute(
|
||||
inkwell::attributes::AttributeLoc::Function,
|
||||
Attribute::MinSize as u32,
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,10 +157,6 @@ fn emit_load<'ctx>(
|
||||
key: BasicValueEnum<'ctx>,
|
||||
transient: bool,
|
||||
) -> anyhow::Result<BasicValueEnum<'ctx>> {
|
||||
let is_transient = context.xlen_type().const_int(transient as u64, false);
|
||||
let key_pointer = context.build_alloca_at_entry(context.word_type(), "key_pointer");
|
||||
let value_pointer = context.build_alloca_at_entry(context.word_type(), "value_pointer");
|
||||
|
||||
let mut key = context.build_load(
|
||||
super::Pointer::new(
|
||||
context.word_type(),
|
||||
@@ -172,17 +168,33 @@ fn emit_load<'ctx>(
|
||||
if !transient {
|
||||
key = context.build_byte_swap(key)?;
|
||||
}
|
||||
|
||||
let key_pointer = context.build_alloca_at_entry(context.word_type(), "key_pointer");
|
||||
let value_pointer = context.build_alloca_at_entry(context.word_type(), "value_pointer");
|
||||
let length_pointer = context.build_alloca_at_entry(context.xlen_type(), "length_pointer");
|
||||
|
||||
context.builder().build_store(key_pointer.value, key)?;
|
||||
context.build_store(value_pointer, context.word_const(0))?;
|
||||
context.build_store(
|
||||
length_pointer,
|
||||
context
|
||||
.xlen_type()
|
||||
.const_int(revive_common::BYTE_LENGTH_WORD as u64, false),
|
||||
)?;
|
||||
|
||||
let is_transient = context.xlen_type().const_int(transient as u64, false);
|
||||
|
||||
let arguments = [
|
||||
is_transient.into(),
|
||||
key_pointer.to_int(context).into(),
|
||||
context.xlen_type().const_all_ones().into(),
|
||||
value_pointer.to_int(context).into(),
|
||||
length_pointer.to_int(context).into(),
|
||||
];
|
||||
context.build_runtime_call(revive_runtime_api::polkavm_imports::GET_STORAGE, &arguments);
|
||||
|
||||
// We do not to check the return value: Solidity assumes infallible loads.
|
||||
// If a key doesn't exist the syscall returns zero.
|
||||
// If a key doesn't exist the "zero" value is returned (ensured by above write).
|
||||
|
||||
let value = context.build_load(value_pointer, "storage_value")?;
|
||||
Ok(if transient {
|
||||
@@ -198,10 +210,6 @@ fn emit_store<'ctx>(
|
||||
value: BasicValueEnum<'ctx>,
|
||||
transient: bool,
|
||||
) -> anyhow::Result<()> {
|
||||
let is_transient = context.xlen_type().const_int(transient as u64, false);
|
||||
let key_pointer = context.build_alloca_at_entry(context.word_type(), "key_pointer");
|
||||
let value_pointer = context.build_alloca_at_entry(context.word_type(), "value_pointer");
|
||||
|
||||
let mut key = context.build_load(
|
||||
super::Pointer::new(
|
||||
context.word_type(),
|
||||
@@ -216,20 +224,27 @@ fn emit_store<'ctx>(
|
||||
Default::default(),
|
||||
value.into_pointer_value(),
|
||||
),
|
||||
"value",
|
||||
"key",
|
||||
)?;
|
||||
if !transient {
|
||||
key = context.build_byte_swap(key)?;
|
||||
value = context.build_byte_swap(value)?;
|
||||
}
|
||||
|
||||
let key_pointer = context.build_alloca_at_entry(context.word_type(), "key_pointer");
|
||||
let value_pointer = context.build_alloca_at_entry(context.word_type(), "value_pointer");
|
||||
|
||||
context.build_store(key_pointer, key)?;
|
||||
context.build_store(value_pointer, value)?;
|
||||
|
||||
let is_transient = context.xlen_type().const_int(transient as u64, false);
|
||||
|
||||
let arguments = [
|
||||
is_transient.into(),
|
||||
key_pointer.to_int(context).into(),
|
||||
context.xlen_type().const_all_ones().into(),
|
||||
value_pointer.to_int(context).into(),
|
||||
context.integer_const(crate::polkavm::XLEN, 32).into(),
|
||||
];
|
||||
context.build_runtime_call(revive_runtime_api::polkavm_imports::SET_STORAGE, &arguments);
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ pub fn call<'ctx>(
|
||||
let is_success = context.builder().build_int_compare(
|
||||
inkwell::IntPredicate::EQ,
|
||||
success,
|
||||
context.integer_const(revive_common::BIT_LENGTH_X32, 0),
|
||||
context.integer_const(revive_common::BIT_LENGTH_X64, 0),
|
||||
"is_success",
|
||||
)?;
|
||||
|
||||
@@ -178,7 +178,7 @@ pub fn delegate_call<'ctx>(
|
||||
let is_success = context.builder().build_int_compare(
|
||||
inkwell::IntPredicate::EQ,
|
||||
success,
|
||||
context.integer_const(revive_common::BIT_LENGTH_X32, 0),
|
||||
context.integer_const(revive_common::BIT_LENGTH_X64, 0),
|
||||
"is_success",
|
||||
)?;
|
||||
|
||||
|
||||
@@ -60,16 +60,3 @@ pub fn invalid(context: &mut Context) -> anyhow::Result<()> {
|
||||
context.build_call(context.intrinsics().trap, &[], "invalid_trap");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Translates the `selfdestruct` instruction.
|
||||
pub fn selfdestruct<'ctx>(
|
||||
context: &mut Context<'ctx>,
|
||||
address: inkwell::values::IntValue<'ctx>,
|
||||
) -> anyhow::Result<()> {
|
||||
let address_pointer = context.build_address_argument_store(address)?;
|
||||
context.build_runtime_call(
|
||||
revive_runtime_api::polkavm_imports::TERMINATE,
|
||||
&[address_pointer.to_int(context).into()],
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "resolc"
|
||||
version = "0.5.0"
|
||||
version = "0.4.0"
|
||||
license.workspace = true
|
||||
edition.workspace = true
|
||||
repository.workspace = true
|
||||
|
||||
@@ -88,7 +88,7 @@ impl Compiler for SolcCompiler {
|
||||
anyhow::bail!(
|
||||
"{} error: {}",
|
||||
self.executable,
|
||||
String::from_utf8_lossy(output.stderr.as_slice())
|
||||
String::from_utf8_lossy(output.stderr.as_slice()).to_string()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ impl Compiler for SolcCompiler {
|
||||
anyhow::bail!(
|
||||
"{} error: {}",
|
||||
self.executable,
|
||||
String::from_utf8_lossy(output.stderr.as_slice())
|
||||
String::from_utf8_lossy(output.stderr.as_slice()).to_string()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
use crate::tests::cli::utils::{
|
||||
self, assert_command_failure, assert_command_success, assert_equal_exit_codes, execute_resolc,
|
||||
execute_solc, RESOLC_YUL_FLAG, SOLIDITY_CONTRACT_PATH, SOLIDITY_LARGE_DIV_REM_CONTRACT_PATH,
|
||||
YUL_MEMSET_CONTRACT_PATH,
|
||||
execute_solc, RESOLC_YUL_FLAG, SOLIDITY_CONTRACT_PATH, YUL_MEMSET_CONTRACT_PATH,
|
||||
};
|
||||
|
||||
const LEVELS: &[char] = &['0', '1', '2', '3', 's', 'z'];
|
||||
@@ -57,26 +56,3 @@ fn disable_solc_optimzer() {
|
||||
|
||||
assert_ne!(enabled.stdout, disabled.stdout);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_large_div_rem_expansion() {
|
||||
for level in LEVELS {
|
||||
let optimization_argument = format!("-O{level}");
|
||||
let arguments = &[SOLIDITY_LARGE_DIV_REM_CONTRACT_PATH, &optimization_argument];
|
||||
let resolc_result = utils::execute_resolc(arguments);
|
||||
assert!(
|
||||
resolc_result.success,
|
||||
"Providing the level `{optimization_argument}` should succeed with exit code {}, got {}.\nDetails: {}",
|
||||
revive_common::EXIT_CODE_SUCCESS,
|
||||
resolc_result.code,
|
||||
resolc_result.stderr
|
||||
);
|
||||
|
||||
assert!(
|
||||
resolc_result
|
||||
.stderr
|
||||
.contains("Compiler run successful. No output requested"),
|
||||
"Expected the output to contain a success message when providing the level `{optimization_argument}`."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,10 +22,6 @@ pub const YUL_MEMSET_CONTRACT_PATH: &str = "src/tests/data/yul/memset.yul";
|
||||
pub const STANDARD_JSON_CONTRACTS_PATH: &str =
|
||||
"src/tests/data/standard_json/solidity_contracts.json";
|
||||
|
||||
/// The simple Solidity contract containing i256 divisions and remains that should be compiled
|
||||
/// correctly
|
||||
pub const SOLIDITY_LARGE_DIV_REM_CONTRACT_PATH: &str = "src/tests/data/solidity/large_div_rem.sol";
|
||||
|
||||
/// The `resolc` YUL mode flag.
|
||||
pub const RESOLC_YUL_FLAG: &str = "--yul";
|
||||
/// The `--yul` option was deprecated in Solidity 0.8.27 in favor of `--strict-assembly`.
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8;
|
||||
|
||||
contract LargeDivRem {
|
||||
function rem_2(int n) public pure returns (int q) {
|
||||
assembly {
|
||||
q := smod(n, 2)
|
||||
}
|
||||
}
|
||||
|
||||
function div_2(int n) public pure returns (int q) {
|
||||
assembly {
|
||||
q := sdiv(n, 2)
|
||||
}
|
||||
}
|
||||
|
||||
function rem_7(int n) public pure returns (int q) {
|
||||
assembly {
|
||||
q := smod(n, 7)
|
||||
}
|
||||
}
|
||||
|
||||
function div_7(int n) public pure returns (int q) {
|
||||
assembly {
|
||||
q := sdiv(n, 2)
|
||||
}
|
||||
}
|
||||
|
||||
function rem_k(int n, int k) public pure returns (int q) {
|
||||
assembly {
|
||||
q := smod(n, k)
|
||||
}
|
||||
}
|
||||
|
||||
function div_k(int n, int k) public pure returns (int q) {
|
||||
assembly {
|
||||
q := sdiv(n, k)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -98,3 +98,26 @@ contract ExternalCodeCopy {
|
||||
|
||||
build_solidity(sources(&[("test.sol", code)])).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "The `SELFDESTRUCT` instruction is not supported")]
|
||||
fn selfdestruct_yul() {
|
||||
let solidity = r#"
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
contract MinimalDestructible {
|
||||
address payable public owner;
|
||||
|
||||
constructor() {
|
||||
owner = payable(msg.sender);
|
||||
}
|
||||
|
||||
function destroy() public {
|
||||
require(msg.sender == owner, "Only the owner can call this function.");
|
||||
selfdestruct(owner);
|
||||
}
|
||||
}"#;
|
||||
|
||||
build_solidity(sources(&[("test.sol", solidity)])).unwrap();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "revive-runner"
|
||||
version = "0.3.0"
|
||||
version = "0.2.0"
|
||||
license.workspace = true
|
||||
edition.workspace = true
|
||||
repository.workspace = true
|
||||
|
||||
@@ -27,8 +27,6 @@ use std::time::Duration;
|
||||
|
||||
use hex::{FromHex, ToHex};
|
||||
use pallet_revive::{AddressMapper, ExecReturnValue, InstantiateReturnValue};
|
||||
use polkadot_sdk::frame_support::traits::Currency;
|
||||
use polkadot_sdk::pallet_revive::{Config, Pallet};
|
||||
use polkadot_sdk::*;
|
||||
use polkadot_sdk::{
|
||||
pallet_revive::ContractResult,
|
||||
@@ -60,8 +58,6 @@ pub const CHARLIE: H160 = H160([3u8; 20]);
|
||||
pub const GAS_LIMIT: Weight = Weight::from_parts(100_000_000_000_000, 3 * 1024 * 1024 * 1024);
|
||||
/// Default deposit limit
|
||||
pub const DEPOSIT_LIMIT: Balance = 10_000_000;
|
||||
/// The native to ETH balance factor.
|
||||
pub const ETH_RATIO: Balance = 1_000_000;
|
||||
|
||||
/// Externalities builder
|
||||
#[derive(Default)]
|
||||
@@ -84,28 +80,18 @@ impl ExtBuilder {
|
||||
/// Build the externalities
|
||||
pub fn build(self) -> sp_io::TestExternalities {
|
||||
sp_tracing::try_init_simple();
|
||||
|
||||
let mut t = frame_system::GenesisConfig::<Runtime>::default()
|
||||
.build_storage()
|
||||
.unwrap();
|
||||
|
||||
pallet_balances::GenesisConfig::<Runtime> {
|
||||
balances: self.balance_genesis_config,
|
||||
dev_accounts: None,
|
||||
}
|
||||
.assimilate_storage(&mut t)
|
||||
.unwrap();
|
||||
|
||||
let mut ext = sp_io::TestExternalities::new(t);
|
||||
ext.register_extension(KeystoreExt::new(MemoryKeystore::new()));
|
||||
ext.execute_with(|| {
|
||||
let _ = <Runtime as Config>::Currency::deposit_creating(
|
||||
&Pallet::<Runtime>::account_id(),
|
||||
<Runtime as Config>::Currency::minimum_balance(),
|
||||
);
|
||||
|
||||
System::set_block_number(1);
|
||||
});
|
||||
ext.execute_with(|| System::set_block_number(1));
|
||||
|
||||
ext
|
||||
}
|
||||
|
||||
@@ -74,18 +74,19 @@ parameter_types! {
|
||||
impl pallet_revive::Config for Runtime {
|
||||
type Time = Timestamp;
|
||||
type Currency = Balances;
|
||||
type CallFilter = ();
|
||||
type ChainExtension = ();
|
||||
type DepositPerByte = DepositPerByte;
|
||||
type DepositPerItem = DepositPerItem;
|
||||
type AddressMapper = AccountId32Mapper<Self>;
|
||||
type RuntimeMemory = ConstU32<{ 512 * 1024 * 1024 }>;
|
||||
type PVFMemory = ConstU32<{ 1024 * 1024 * 1024 }>;
|
||||
type UnsafeUnstableInterface = UnstableInterface;
|
||||
type UploadOrigin = EnsureSigned<Self::AccountId>;
|
||||
type InstantiateOrigin = EnsureSigned<Self::AccountId>;
|
||||
type UploadOrigin = EnsureSigned<AccountId32>;
|
||||
type InstantiateOrigin = EnsureSigned<AccountId32>;
|
||||
type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent;
|
||||
type ChainId = ConstU64<420_420_420>;
|
||||
type FindAuthor = Self;
|
||||
type NativeToEthRatio = ConstU32<{ crate::ETH_RATIO as u32 }>;
|
||||
}
|
||||
|
||||
impl FindAuthor<<Runtime as frame_system::Config>::AccountId> for Runtime {
|
||||
|
||||
+11
-12
@@ -1,6 +1,5 @@
|
||||
use std::{str::FromStr, time::Instant};
|
||||
|
||||
use polkadot_sdk::pallet_revive::Pallet;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::*;
|
||||
@@ -446,13 +445,12 @@ impl Specs {
|
||||
let time_start = Instant::now();
|
||||
let result = Contracts::bare_instantiate(
|
||||
origin,
|
||||
value.into(),
|
||||
value,
|
||||
gas_limit.unwrap_or(GAS_LIMIT),
|
||||
storage_deposit_limit.unwrap_or(DEPOSIT_LIMIT).into(),
|
||||
code,
|
||||
data,
|
||||
salt.0,
|
||||
pallet_revive::BumpNonce::No,
|
||||
);
|
||||
results.push(CallResult::Instantiate {
|
||||
result,
|
||||
@@ -485,7 +483,7 @@ impl Specs {
|
||||
let result = Contracts::bare_call(
|
||||
RuntimeOrigin::signed(origin.to_account_id(&results)),
|
||||
dest.to_eth_addr(&results),
|
||||
value.into(),
|
||||
value,
|
||||
gas_limit.unwrap_or(GAS_LIMIT),
|
||||
storage_deposit_limit.unwrap_or(DEPOSIT_LIMIT).into(),
|
||||
data,
|
||||
@@ -499,10 +497,8 @@ impl Specs {
|
||||
expectation.verify(results.last().expect("No call to verify"));
|
||||
}
|
||||
VerifyBalance { origin, expected } => {
|
||||
assert_eq!(
|
||||
Pallet::<Runtime>::evm_balance(&origin.to_eth_addr(&results)),
|
||||
expected.into()
|
||||
);
|
||||
let balance = Balances::usable_balance(origin.to_account_id(&results));
|
||||
assert_eq!(balance, expected);
|
||||
}
|
||||
VerifyStorage {
|
||||
contract,
|
||||
@@ -510,10 +506,13 @@ impl Specs {
|
||||
expected,
|
||||
} => {
|
||||
let address = contract.to_eth_addr(&results);
|
||||
let value = Contracts::get_storage(address, key)
|
||||
.unwrap_or_else(|error| panic!("at {address}: {error:?}"))
|
||||
.unwrap_or_else(|| vec![0; 32]);
|
||||
assert_eq!(value, expected, "at {address} key 0x{}", hex::encode(key));
|
||||
let Ok(value) = Contracts::get_storage(address, key) else {
|
||||
panic!("error reading storage for address {address}");
|
||||
};
|
||||
let Some(value) = value else {
|
||||
panic!("no value at {address} key 0x{}", hex::encode(key));
|
||||
};
|
||||
assert_eq!(value, expected, "at key 0x{}", hex::encode(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "revive-runtime-api"
|
||||
version = "0.4.0"
|
||||
version = "0.3.0"
|
||||
license.workspace = true
|
||||
edition.workspace = true
|
||||
repository.workspace = true
|
||||
|
||||
@@ -53,11 +53,11 @@ POLKAVM_IMPORT(void, block_hash, uint32_t, uint32_t)
|
||||
|
||||
POLKAVM_IMPORT(void, block_number, uint32_t)
|
||||
|
||||
POLKAVM_IMPORT(uint32_t, call, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t)
|
||||
POLKAVM_IMPORT(uint64_t, call, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t)
|
||||
|
||||
POLKAVM_IMPORT(void, call_data_copy, uint32_t, uint32_t, uint32_t)
|
||||
POLKAVM_IMPORT(uint64_t, call_data_copy, uint32_t, uint32_t, uint32_t)
|
||||
|
||||
POLKAVM_IMPORT(void, call_data_load, uint32_t, uint32_t)
|
||||
POLKAVM_IMPORT(uint64_t, call_data_load, uint32_t, uint32_t)
|
||||
|
||||
POLKAVM_IMPORT(uint64_t, call_data_size)
|
||||
|
||||
@@ -69,7 +69,7 @@ POLKAVM_IMPORT(uint64_t, code_size, uint32_t)
|
||||
|
||||
POLKAVM_IMPORT(void, code_hash, uint32_t, uint32_t)
|
||||
|
||||
POLKAVM_IMPORT(uint32_t, delegate_call, uint64_t, uint64_t, uint64_t, uint32_t, uint64_t, uint64_t)
|
||||
POLKAVM_IMPORT(uint64_t, delegate_call, uint64_t, uint64_t, uint64_t, uint32_t, uint64_t, uint64_t)
|
||||
|
||||
POLKAVM_IMPORT(void, deposit_event, uint32_t, uint32_t, uint32_t, uint32_t)
|
||||
|
||||
@@ -79,11 +79,11 @@ POLKAVM_IMPORT(uint64_t, gas_price);
|
||||
|
||||
POLKAVM_IMPORT(void, get_immutable_data, uint32_t, uint32_t);
|
||||
|
||||
POLKAVM_IMPORT(void, get_storage_or_zero, 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(uint32_t, instantiate, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t)
|
||||
POLKAVM_IMPORT(uint64_t, instantiate, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t)
|
||||
|
||||
POLKAVM_IMPORT(void, now, uint32_t)
|
||||
|
||||
@@ -99,8 +99,8 @@ POLKAVM_IMPORT(uint64_t, return_data_size)
|
||||
|
||||
POLKAVM_IMPORT(void, set_immutable_data, uint32_t, uint32_t);
|
||||
|
||||
POLKAVM_IMPORT(uint32_t, set_storage_or_clear, uint32_t, uint32_t, uint32_t)
|
||||
|
||||
POLKAVM_IMPORT(void, terminate, 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, weight_to_fee, uint64_t, uint64_t, uint32_t);
|
||||
|
||||
@@ -42,7 +42,7 @@ pub static GAS_PRICE: &str = "gas_price";
|
||||
|
||||
pub static GET_IMMUTABLE_DATA: &str = "get_immutable_data";
|
||||
|
||||
pub static GET_STORAGE: &str = "get_storage_or_zero";
|
||||
pub static GET_STORAGE: &str = "get_storage";
|
||||
|
||||
pub static HASH_KECCAK_256: &str = "hash_keccak_256";
|
||||
|
||||
@@ -62,12 +62,12 @@ pub static RETURNDATASIZE: &str = "return_data_size";
|
||||
|
||||
pub static SET_IMMUTABLE_DATA: &str = "set_immutable_data";
|
||||
|
||||
pub static SET_STORAGE: &str = "set_storage_or_clear";
|
||||
|
||||
pub static TERMINATE: &str = "terminate";
|
||||
pub static SET_STORAGE: &str = "set_storage";
|
||||
|
||||
pub static VALUE_TRANSFERRED: &str = "value_transferred";
|
||||
|
||||
pub static WEIGHT_TO_FEE: &str = "weight_to_fee";
|
||||
|
||||
/// All imported runtime API symbols.
|
||||
/// Useful for configuring common attributes and linkage.
|
||||
pub static IMPORTS: [&str; 33] = [
|
||||
@@ -102,8 +102,8 @@ pub static IMPORTS: [&str; 33] = [
|
||||
RETURNDATASIZE,
|
||||
SET_IMMUTABLE_DATA,
|
||||
SET_STORAGE,
|
||||
TERMINATE,
|
||||
VALUE_TRANSFERRED,
|
||||
WEIGHT_TO_FEE,
|
||||
];
|
||||
|
||||
/// Creates a LLVM module from the [BITCODE].
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "revive-solc-json-interface"
|
||||
version = "0.4.0"
|
||||
version = "0.3.0"
|
||||
authors.workspace = true
|
||||
license.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
@@ -47,3 +47,24 @@ pub enum Flag {
|
||||
#[serde(rename = "ir")]
|
||||
Ir,
|
||||
}
|
||||
|
||||
//impl std::fmt::Display for Flag {
|
||||
// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
// match self {
|
||||
// Self::ABI => write!(f, "abi"),
|
||||
// Self::Metadata => write!(f, "metadata"),
|
||||
// Self::Devdoc => write!(f, "devdoc"),
|
||||
// Self::Userdoc => write!(f, "userdoc"),
|
||||
// Self::MethodIdentifiers => write!(f, "evm.methodIdentifiers"),
|
||||
// Self::StorageLayout => write!(f, "storageLayout"),
|
||||
// Self::AST => write!(f, "ast"),
|
||||
// Self::Yul => write!(f, "irOptimized"),
|
||||
// Self::EVM => write!(f, "evm"),
|
||||
// Self::EVMLA => write!(f, "evm.legacyAssembly"),
|
||||
// Self::EVMBC => write!(f, "evm.bytecode"),
|
||||
// Self::EVMDBC => write!(f, "evm.deployedBytecode"),
|
||||
// Self::Assembly => write!(f, "evm.assembly"),
|
||||
// Self::Ir => write!(f, "ir"),
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
@@ -40,6 +40,17 @@ impl File {
|
||||
per_contract,
|
||||
}
|
||||
}
|
||||
/// Creates the selection required for production compilation (excludes EVM bytecode).
|
||||
pub fn new_required() -> Self {
|
||||
Self {
|
||||
per_file: HashSet::from_iter([SelectionFlag::AST]),
|
||||
per_contract: HashSet::from_iter([
|
||||
SelectionFlag::MethodIdentifiers,
|
||||
SelectionFlag::Metadata,
|
||||
SelectionFlag::Yul,
|
||||
]),
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates the selection required for test compilation (includes EVM bytecode).
|
||||
pub fn new_required_for_tests() -> Self {
|
||||
@@ -55,6 +66,16 @@ impl File {
|
||||
}
|
||||
}
|
||||
|
||||
/// Extends the user's output selection with flag required by our compilation process.
|
||||
pub fn extend_with_required(&mut self) -> &mut Self {
|
||||
let required = Self::new_required();
|
||||
|
||||
self.per_file.extend(required.per_file);
|
||||
self.per_contract.extend(required.per_contract);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// Extends the output selection with another one.
|
||||
pub fn extend(&mut self, other: Self) -> &mut Self {
|
||||
self.per_file.extend(other.per_file);
|
||||
|
||||
@@ -10,63 +10,15 @@ use serde::Serialize;
|
||||
use self::file::flag::Flag;
|
||||
use self::file::File as FileSelection;
|
||||
|
||||
/// The `solc --standard-json` per-file output selection.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, Default, PartialEq)]
|
||||
pub struct PerFileSelection {
|
||||
/// Individual file selection configuration, required for foundry.
|
||||
#[serde(skip_serializing_if = "BTreeMap::is_empty", flatten)]
|
||||
pub files: BTreeMap<String, FileSelection>,
|
||||
}
|
||||
|
||||
impl PerFileSelection {
|
||||
/// Extends the output selection with another one.
|
||||
pub fn extend(&mut self, other: Self) {
|
||||
for (entry, file) in other.files {
|
||||
self.files
|
||||
.entry(entry)
|
||||
.and_modify(|v| {
|
||||
v.extend(file.clone());
|
||||
})
|
||||
.or_insert(file);
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns flags that are going to be automatically added by the compiler,
|
||||
/// but were not explicitly requested by the user.
|
||||
///
|
||||
/// Afterwards, the flags are used to prune JSON output before returning it.
|
||||
pub fn selection_to_prune(&self) -> Self {
|
||||
let files = self
|
||||
.files
|
||||
.iter()
|
||||
.map(|(k, v)| (k.to_owned(), v.selection_to_prune()))
|
||||
.collect();
|
||||
Self { files }
|
||||
}
|
||||
|
||||
/// Returns whether `path` contains the `flag` or `None` if there is no selection for `path`.
|
||||
pub fn contains(&self, path: &String, flag: &Flag) -> Option<bool> {
|
||||
if let Some(file) = self.files.get(path) {
|
||||
return Some(file.contains(flag));
|
||||
};
|
||||
None
|
||||
}
|
||||
|
||||
/// Returns whether this is the empty per file selection.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.files.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
/// The `solc --standard-json` output selection.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, Default, PartialEq)]
|
||||
pub struct Selection {
|
||||
/// Only the 'all' wildcard is available for robustness reasons.
|
||||
#[serde(default, rename = "*", skip_serializing_if = "FileSelection::is_empty")]
|
||||
/// Individual file selection configuration, required for foundry.
|
||||
pub all: FileSelection,
|
||||
#[serde(skip_serializing_if = "PerFileSelection::is_empty", flatten)]
|
||||
files: PerFileSelection,
|
||||
all: FileSelection,
|
||||
|
||||
#[serde(skip_serializing_if = "BTreeMap::is_empty", flatten)]
|
||||
pub files: BTreeMap<String, FileSelection>,
|
||||
}
|
||||
|
||||
impl Selection {
|
||||
@@ -80,19 +32,17 @@ impl Selection {
|
||||
|
||||
/// Creates the selection required by our compilation process.
|
||||
pub fn new_required() -> Self {
|
||||
Self::new(vec![
|
||||
Flag::AST,
|
||||
Flag::MethodIdentifiers,
|
||||
Flag::Metadata,
|
||||
Flag::Yul,
|
||||
])
|
||||
Self {
|
||||
all: FileSelection::new_required(),
|
||||
files: BTreeMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates the selection required for test compilation (includes EVM bytecode).
|
||||
pub fn new_required_for_tests() -> Self {
|
||||
Self {
|
||||
all: FileSelection::new_required_for_tests(),
|
||||
files: Default::default(),
|
||||
files: BTreeMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +54,6 @@ impl Selection {
|
||||
/// Extends the output selection with another one.
|
||||
pub fn extend(&mut self, other: Self) -> &mut Self {
|
||||
self.all.extend(other.all);
|
||||
self.files.extend(other.files);
|
||||
self
|
||||
}
|
||||
|
||||
@@ -115,14 +64,12 @@ impl Selection {
|
||||
pub fn selection_to_prune(&self) -> Self {
|
||||
Self {
|
||||
all: self.all.selection_to_prune(),
|
||||
files: self.files.selection_to_prune(),
|
||||
files: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether the flag is requested.
|
||||
pub fn contains(&self, path: &String, flag: &Flag) -> bool {
|
||||
self.files
|
||||
.contains(path, flag)
|
||||
.unwrap_or(self.all.contains(flag))
|
||||
pub fn contains(&self, flag: &Flag) -> bool {
|
||||
self.all.contains(flag)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
|
||||
pub mod evm;
|
||||
|
||||
#[cfg(feature = "resolc")]
|
||||
use std::collections::BTreeMap;
|
||||
#[cfg(feature = "resolc")]
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
use serde::Deserialize;
|
||||
@@ -47,24 +45,19 @@ pub struct Contract {
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub hash: Option<String>,
|
||||
/// Unlinked factory dependencies.
|
||||
#[cfg(feature = "resolc")]
|
||||
#[serde(default, skip_deserializing)]
|
||||
pub factory_dependencies_unlinked: BTreeSet<String>,
|
||||
/// The contract factory dependencies.
|
||||
#[cfg(feature = "resolc")]
|
||||
#[serde(default, skip_deserializing)]
|
||||
pub factory_dependencies: BTreeMap<String, String>,
|
||||
/// Missing linkable libraries.
|
||||
#[cfg(feature = "resolc")]
|
||||
#[serde(default, skip_deserializing)]
|
||||
pub missing_libraries: BTreeSet<String>,
|
||||
/// Binary object format.
|
||||
#[cfg(feature = "resolc")]
|
||||
#[serde(default, skip_deserializing, skip_serializing_if = "Option::is_none")]
|
||||
#[serde(default, skip_deserializing)]
|
||||
pub object_format: Option<revive_common::ObjectFormat>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "resolc")]
|
||||
impl Contract {
|
||||
/// Checks if all fields are unset or empty.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
|
||||
@@ -12,7 +12,7 @@ use crate::standard_json::output::error::error_handler::ErrorHandler;
|
||||
use crate::SolcStandardJsonInputSettingsSelection;
|
||||
#[cfg(feature = "resolc")]
|
||||
use crate::SolcStandardJsonInputSource;
|
||||
#[cfg(all(feature = "parallel", feature = "resolc"))]
|
||||
#[cfg(feature = "parallel")]
|
||||
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
|
||||
|
||||
use self::contract::Contract;
|
||||
@@ -56,22 +56,14 @@ impl Output {
|
||||
messages: &mut Vec<SolcStandardJsonOutputError>,
|
||||
) -> Self {
|
||||
let sources = sources
|
||||
.iter()
|
||||
.keys()
|
||||
.enumerate()
|
||||
.map(|(index, (path, source))| {
|
||||
(
|
||||
path.to_owned(),
|
||||
Source {
|
||||
id: index,
|
||||
ast: source.content().map(|x| serde_json::to_value(x).unwrap()),
|
||||
},
|
||||
)
|
||||
})
|
||||
.map(|(index, path)| (path.to_owned(), Source::new(index)))
|
||||
.collect::<BTreeMap<String, Source>>();
|
||||
|
||||
Self {
|
||||
contracts: BTreeMap::new(),
|
||||
sources: sources.clone(),
|
||||
sources,
|
||||
errors: std::mem::take(messages),
|
||||
|
||||
version: None,
|
||||
@@ -100,27 +92,36 @@ impl Output {
|
||||
mut self,
|
||||
selection_to_prune: SolcStandardJsonInputSettingsSelection,
|
||||
) -> ! {
|
||||
for (path, contracts) in self.contracts.iter_mut() {
|
||||
for contract in contracts.values_mut() {
|
||||
let sources = self.sources.values_mut().collect::<Vec<&mut Source>>();
|
||||
for source in sources.into_iter() {
|
||||
if selection_to_prune
|
||||
.contains(&crate::SolcStandardJsonInputSettingsSelectionFileFlag::AST)
|
||||
{
|
||||
source.ast = None;
|
||||
}
|
||||
}
|
||||
|
||||
let contracts = self
|
||||
.contracts
|
||||
.values_mut()
|
||||
.flat_map(|contracts| contracts.values_mut())
|
||||
.collect::<Vec<&mut Contract>>();
|
||||
for contract in contracts.into_iter() {
|
||||
if selection_to_prune
|
||||
.contains(&crate::SolcStandardJsonInputSettingsSelectionFileFlag::Metadata)
|
||||
{
|
||||
contract.metadata = serde_json::Value::Null;
|
||||
}
|
||||
if selection_to_prune
|
||||
.contains(&crate::SolcStandardJsonInputSettingsSelectionFileFlag::Yul)
|
||||
{
|
||||
contract.ir_optimized = String::new();
|
||||
}
|
||||
if let Some(ref mut evm) = contract.evm {
|
||||
if selection_to_prune.contains(
|
||||
path,
|
||||
&crate::SolcStandardJsonInputSettingsSelectionFileFlag::Metadata,
|
||||
&crate::SolcStandardJsonInputSettingsSelectionFileFlag::MethodIdentifiers,
|
||||
) {
|
||||
contract.metadata = serde_json::Value::Null;
|
||||
}
|
||||
if selection_to_prune.contains(
|
||||
path,
|
||||
&crate::SolcStandardJsonInputSettingsSelectionFileFlag::Yul,
|
||||
) {
|
||||
contract.ir_optimized = String::new();
|
||||
}
|
||||
if let Some(ref mut evm) = contract.evm {
|
||||
if selection_to_prune.contains(
|
||||
path,
|
||||
&crate::SolcStandardJsonInputSettingsSelectionFileFlag::MethodIdentifiers,
|
||||
) {
|
||||
evm.method_identifiers.clear();
|
||||
}
|
||||
evm.method_identifiers.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "revive-yul"
|
||||
description = "The revive YUL parser library."
|
||||
version = "0.4.0"
|
||||
version = "0.3.0"
|
||||
authors.workspace = true
|
||||
license.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
@@ -661,14 +661,6 @@ impl FunctionCall {
|
||||
Name::Invalid => {
|
||||
revive_llvm_context::polkavm_evm_return::invalid(context).map(|_| None)
|
||||
}
|
||||
Name::SelfDestruct => {
|
||||
let arguments = self.pop_arguments_llvm::<1>(context)?;
|
||||
revive_llvm_context::polkavm_evm_return::selfdestruct(
|
||||
context,
|
||||
arguments[0].into_int_value(),
|
||||
)
|
||||
.map(|_| None)
|
||||
}
|
||||
|
||||
Name::Log0 => {
|
||||
let arguments = self.pop_arguments_llvm::<2>(context)?;
|
||||
@@ -970,6 +962,13 @@ impl FunctionCall {
|
||||
location
|
||||
)
|
||||
}
|
||||
Name::SelfDestruct => {
|
||||
let _arguments = self.pop_arguments_llvm::<1>(context)?;
|
||||
anyhow::bail!(
|
||||
"{} The `SELFDESTRUCT` instruction is not supported",
|
||||
location
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ impl Expression {
|
||||
anyhow::anyhow!(
|
||||
"{} Invalid literal `{}`: {}",
|
||||
literal.location,
|
||||
literal.inner,
|
||||
literal.inner.to_string(),
|
||||
error
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@parity/resolc",
|
||||
"license": "Apache-2.0",
|
||||
"version": "0.5.0",
|
||||
"version": "0.4.0",
|
||||
"author": "Parity <admin@parity.io> (https://parity.io)",
|
||||
"module": "index.ts",
|
||||
"types": "./dist/index.d.ts",
|
||||
|
||||
Generated
+1
-6
@@ -31,7 +31,7 @@
|
||||
},
|
||||
"js/resolc": {
|
||||
"name": "@parity/resolc",
|
||||
"version": "0.5.0",
|
||||
"version": "0.4.0",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@types/node": "^22.9.0",
|
||||
@@ -1585,7 +1585,6 @@
|
||||
"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",
|
||||
@@ -1753,7 +1752,6 @@
|
||||
"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"
|
||||
},
|
||||
@@ -2363,7 +2361,6 @@
|
||||
"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",
|
||||
@@ -2522,7 +2519,6 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@ethersproject/abi": "5.8.0",
|
||||
"@ethersproject/abstract-provider": "5.8.0",
|
||||
@@ -4397,7 +4393,6 @@
|
||||
"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