diff options
-rw-r--r-- | circle.yml | 30 | ||||
-rw-r--r-- | docs/assembly.rst | 6 | ||||
-rw-r--r-- | libevmasm/Instruction.cpp | 6 | ||||
-rw-r--r-- | libevmasm/Instruction.h | 5 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmAnalysis.cpp | 14 | ||||
-rwxr-xr-x | scripts/install_deps.sh | 13 | ||||
-rwxr-xr-x | scripts/tests.sh | 100 | ||||
-rwxr-xr-x | test/cmdlineTests.sh | 2 | ||||
-rw-r--r-- | test/libsolidity/InlineAssembly.cpp | 14 |
9 files changed, 134 insertions, 56 deletions
@@ -93,7 +93,7 @@ jobs: name: Install build dependencies command: | apt-get -qq update - apt-get -qy install ccache cmake libboost-all-dev libz3-dev libleveldb1v5 + apt-get -qy install ccache cmake libboost-all-dev libz3-dev - run: name: Init submodules command: | @@ -114,15 +114,34 @@ jobs: key: ccache-{{ arch }}-{{ .Branch }} paths: - ~/.ccache + - store_artifacts: + path: build/solc/solc + destination: solc + - persist_to_workspace: + root: build + paths: + - solc/solc + - test/soltest + - test/solfuzzer + + test_x86: + docker: + - image: buildpack-deps:artful + steps: + - checkout + - attach_workspace: + at: build + - run: + name: Install dependencies + command: | + apt-get -qq update + apt-get -qy install libz3-dev libleveldb1v5 - run: mkdir -p test_results - run: name: Tests command: scripts/tests.sh --junit_report test_results - store_test_results: path: test_results/ - - store_artifacts: - path: build/solc/solc - destination: solc docs: docker: @@ -158,4 +177,7 @@ workflows: requires: - build_emscripten - build_x86 + - test_x86: + requires: + - build_x86 - docs diff --git a/docs/assembly.rst b/docs/assembly.rst index 46416142..cf9bf840 100644 --- a/docs/assembly.rst +++ b/docs/assembly.rst @@ -206,6 +206,12 @@ In the grammar, opcodes are represented as pre-defined identifiers. +-------------------------+-----+---+-----------------------------------------------------------------+ | byte(n, x) | | F | nth byte of x, where the most significant byte is the 0th byte | +-------------------------+-----+---+-----------------------------------------------------------------+ +| shl(x, y) | | C | logical shift left y by x bits | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| shr(x, y) | | C | logical shift right y by x bits | ++-------------------------+-----+---+-----------------------------------------------------------------+ +| sar(x, y) | | C | arithmetic shift right y by x bits | ++-------------------------+-----+---+-----------------------------------------------------------------+ | addmod(x, y, m) | | F | (x + y) % m with arbitrary precision arithmetics | +-------------------------+-----+---+-----------------------------------------------------------------+ | mulmod(x, y, m) | | F | (x * y) % m with arbitrary precision arithmetics | diff --git a/libevmasm/Instruction.cpp b/libevmasm/Instruction.cpp index b38981d2..a677a631 100644 --- a/libevmasm/Instruction.cpp +++ b/libevmasm/Instruction.cpp @@ -50,6 +50,9 @@ const std::map<std::string, Instruction> dev::solidity::c_instructions = { "OR", Instruction::OR }, { "XOR", Instruction::XOR }, { "BYTE", Instruction::BYTE }, + { "SHL", Instruction::SHL }, + { "SHR", Instruction::SHR }, + { "SAR", Instruction::SAR }, { "ADDMOD", Instruction::ADDMOD }, { "MULMOD", Instruction::MULMOD }, { "SIGNEXTEND", Instruction::SIGNEXTEND }, @@ -190,6 +193,9 @@ static const std::map<Instruction, InstructionInfo> c_instructionInfo = { Instruction::OR, { "OR", 0, 2, 1, false, Tier::VeryLow } }, { Instruction::XOR, { "XOR", 0, 2, 1, false, Tier::VeryLow } }, { Instruction::BYTE, { "BYTE", 0, 2, 1, false, Tier::VeryLow } }, + { Instruction::SHL, { "SHL", 0, 2, 1, false, Tier::VeryLow } }, + { Instruction::SHR, { "SHR", 0, 2, 1, false, Tier::VeryLow } }, + { Instruction::SAR, { "SAR", 0, 2, 1, false, Tier::VeryLow } }, { Instruction::ADDMOD, { "ADDMOD", 0, 3, 1, false, Tier::Mid } }, { Instruction::MULMOD, { "MULMOD", 0, 3, 1, false, Tier::Mid } }, { Instruction::SIGNEXTEND, { "SIGNEXTEND", 0, 2, 1, false, Tier::Low } }, diff --git a/libevmasm/Instruction.h b/libevmasm/Instruction.h index d9c53900..be788ddb 100644 --- a/libevmasm/Instruction.h +++ b/libevmasm/Instruction.h @@ -59,8 +59,11 @@ enum class Instruction: uint8_t AND, ///< bitwise AND operation OR, ///< bitwise OR operation XOR, ///< bitwise XOR operation - NOT, ///< bitwise NOT opertation + NOT, ///< bitwise NOT operation BYTE, ///< retrieve single byte from word + SHL, ///< bitwise SHL operation + SHR, ///< bitwise SHR operation + SAR, ///< bitwise SAR operation KECCAK256 = 0x20, ///< compute KECCAK-256 hash diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp index a05ac57d..1030523a 100644 --- a/libsolidity/inlineasm/AsmAnalysis.cpp +++ b/libsolidity/inlineasm/AsmAnalysis.cpp @@ -548,6 +548,20 @@ void AsmAnalyzer::warnOnInstructions(solidity::Instruction _instr, SourceLocatio "the Metropolis hard fork. Before that it acts as an invalid instruction." ); + static set<solidity::Instruction> experimentalInstructions{ + solidity::Instruction::SHL, + solidity::Instruction::SHR, + solidity::Instruction::SAR + }; + if (experimentalInstructions.count(_instr)) + m_errorReporter.warning( + _location, + "The \"" + + boost::to_lower_copy(instructionInfo(_instr).name) + + "\" instruction is only available after " + + "the Constantinople hard fork. Before that it acts as an invalid instruction." + ); + if (_instr == solidity::Instruction::JUMP || _instr == solidity::Instruction::JUMPI || _instr == solidity::Instruction::JUMPDEST) m_errorReporter.warning( _location, diff --git a/scripts/install_deps.sh b/scripts/install_deps.sh index d62cffb7..e884ed65 100755 --- a/scripts/install_deps.sh +++ b/scripts/install_deps.sh @@ -168,11 +168,12 @@ case $(uname -s) in # Debian #------------------------------------------------------------------------------ - Debian) + Debian*) #Debian + . /etc/os-release install_z3="" - case $(lsb_release -cs) in - wheezy) + case $VERSION_ID in + 7) #wheezy echo "Installing solidity dependencies on Debian Wheezy (7.x)." echo "ERROR - 'install_deps.sh' doesn't have Debian Wheezy support yet." @@ -182,16 +183,16 @@ case $(uname -s) in echo "See also https://github.com/ethereum/webthree-umbrella/issues/495 where we are working through Alpine support." exit 1 ;; - jessie) + 8) #jessie echo "Installing solidity dependencies on Debian Jesse (8.x)." ;; - stretch) + 9) #stretch echo "Installing solidity dependencies on Debian Stretch (9.x)." install_z3="libz3-dev" ;; - buster) + 10) #buster echo "Installing solidity dependencies on Debian Buster (10.x)." install_z3="libz3-dev" diff --git a/scripts/tests.sh b/scripts/tests.sh index d414643b..3c80adc5 100755 --- a/scripts/tests.sh +++ b/scripts/tests.sh @@ -45,54 +45,66 @@ else fi echo "Running commandline tests..." -"$REPO_ROOT/test/cmdlineTests.sh" +"$REPO_ROOT/test/cmdlineTests.sh" & +CMDLINE_PID=$! +# Only run in parallel if this is run on CI infrastructure +if [ -z "$CI" ] +then + wait $CMDLINE_PID +fi -# This conditional is only needed because we don't have a working Homebrew -# install for `eth` at the time of writing, so we unzip the ZIP file locally -# instead. This will go away soon. -if [[ "$OSTYPE" == "darwin"* ]]; then - ETH_PATH="$REPO_ROOT/eth" -elif [ -z $CI ]; then - ETH_PATH="eth" -else - mkdir -p /tmp/test - ETH_BINARY=eth_byzantium_artful - ETH_HASH="e527dd3e3dc17b983529dd7dcfb74a0d3a5aed4e" - if grep -i trusty /etc/lsb-release >/dev/null 2>&1 - then - ETH_BINARY=eth_byzantium2 - ETH_HASH="4dc3f208475f622be7c8e53bee720e14cd254c6f" +function download_eth() +{ + if [[ "$OSTYPE" == "darwin"* ]]; then + ETH_PATH="$REPO_ROOT/eth" + elif [ -z $CI ]; then + ETH_PATH="eth" + else + mkdir -p /tmp/test + ETH_BINARY=eth_byzantium_artful + ETH_HASH="e527dd3e3dc17b983529dd7dcfb74a0d3a5aed4e" + if grep -i trusty /etc/lsb-release >/dev/null 2>&1 + then + ETH_BINARY=eth_byzantium2 + ETH_HASH="4dc3f208475f622be7c8e53bee720e14cd254c6f" + fi + wget -q -O /tmp/test/eth https://github.com/ethereum/cpp-ethereum/releases/download/solidityTester/$ETH_BINARY + test "$(shasum /tmp/test/eth)" = "$ETH_HASH /tmp/test/eth" + sync + chmod +x /tmp/test/eth + sync # Otherwise we might get a "text file busy" error + ETH_PATH="/tmp/test/eth" fi - wget -q -O /tmp/test/eth https://github.com/ethereum/cpp-ethereum/releases/download/solidityTester/$ETH_BINARY - test "$(shasum /tmp/test/eth)" = "$ETH_HASH /tmp/test/eth" - sync - chmod +x /tmp/test/eth - sync # Otherwise we might get a "text file busy" error - ETH_PATH="/tmp/test/eth" -fi -# This trailing ampersand directs the shell to run the command in the background, -# that is, it is forked and run in a separate sub-shell, as a job, -# asynchronously. The shell will immediately return the return status of 0 for -# true and continue as normal, either processing further commands in a script -# or returning the cursor focus back to the user in a Linux terminal. -$ETH_PATH --test -d /tmp/test & -ETH_PID=$! +} + +# $1: data directory +# echos the PID +function run_eth() +{ + $ETH_PATH --test -d "$1" >/dev/null 2>&1 & + echo $! + # Wait until the IPC endpoint is available. + while [ ! -S "$1"/geth.ipc ] ; do sleep 1; done + sleep 2 +} + +download_eth +ETH_PID=$(run_eth /tmp/test) + +progress="--show-progress" +if [ "$CI" ] +then + progress="" +fi -# Wait until the IPC endpoint is available. That won't be available instantly. -# The node needs to get a little way into its startup sequence before the IPC -# is available and is ready for the unit-tests to start talking to it. -while [ ! -S /tmp/test/geth.ipc ]; do sleep 2; done -echo "--> IPC available." -sleep 2 -# And then run the Solidity unit-tests (once without optimization, once with), -# pointing to that IPC endpoint. echo "--> Running tests without optimizer..." - "$REPO_ROOT"/build/test/soltest --show-progress $testargs_no_opt -- --ipcpath /tmp/test/geth.ipc && \ - echo "--> Running tests WITH optimizer..." && \ - "$REPO_ROOT"/build/test/soltest --show-progress $testargs_opt -- --optimize --ipcpath /tmp/test/geth.ipc -ERROR_CODE=$? +"$REPO_ROOT"/build/test/soltest $testargs_no_opt $progress -- --ipcpath /tmp/test/geth.ipc +echo "--> Running tests WITH optimizer..." +"$REPO_ROOT"/build/test/soltest $testargs_opt $progress -- --optimize --ipcpath /tmp/test/geth.ipc + +wait $CMDLINE_PID + pkill "$ETH_PID" || true sleep 4 -pgrep "$ETH_PID" && pkill -9 "$ETH_PID" || true -exit $ERROR_CODE +pgrep "$ETH_PID" && pkill -9 "$ETH_PID" || true
\ No newline at end of file diff --git a/test/cmdlineTests.sh b/test/cmdlineTests.sh index a249b601..32456fd0 100755 --- a/test/cmdlineTests.sh +++ b/test/cmdlineTests.sh @@ -172,4 +172,4 @@ TMPDIR=$(mktemp -d) done ) rm -rf "$TMPDIR" -echo "Done." +echo "Commandline tests successful." diff --git a/test/libsolidity/InlineAssembly.cpp b/test/libsolidity/InlineAssembly.cpp index 45fb54f8..ea120657 100644 --- a/test/libsolidity/InlineAssembly.cpp +++ b/test/libsolidity/InlineAssembly.cpp @@ -774,6 +774,20 @@ BOOST_AUTO_TEST_CASE(create2) BOOST_CHECK(successAssemble("{ pop(create2(10, 0x123, 32, 64)) }")); } +BOOST_AUTO_TEST_CASE(shift) +{ + BOOST_CHECK(successAssemble("{ pop(shl(10, 32)) }")); + BOOST_CHECK(successAssemble("{ pop(shr(10, 32)) }")); + BOOST_CHECK(successAssemble("{ pop(sar(10, 32)) }")); +} + +BOOST_AUTO_TEST_CASE(shift_constantinople_warning) +{ + CHECK_PARSE_WARNING("{ pop(shl(10, 32)) }", Warning, "The \"shl\" instruction is only available after the Constantinople hard fork"); + CHECK_PARSE_WARNING("{ pop(shr(10, 32)) }", Warning, "The \"shr\" instruction is only available after the Constantinople hard fork"); + CHECK_PARSE_WARNING("{ pop(sar(10, 32)) }", Warning, "The \"sar\" instruction is only available after the Constantinople hard fork"); +} + BOOST_AUTO_TEST_CASE(jump_warning) { CHECK_PARSE_WARNING("{ 1 jump }", Warning, "Jump instructions"); |