aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--circle.yml30
-rw-r--r--docs/assembly.rst6
-rw-r--r--libevmasm/Instruction.cpp6
-rw-r--r--libevmasm/Instruction.h5
-rw-r--r--libsolidity/inlineasm/AsmAnalysis.cpp14
-rwxr-xr-xscripts/install_deps.sh13
-rwxr-xr-xscripts/tests.sh100
-rwxr-xr-xtest/cmdlineTests.sh2
-rw-r--r--test/libsolidity/InlineAssembly.cpp14
9 files changed, 134 insertions, 56 deletions
diff --git a/circle.yml b/circle.yml
index 94c711b0..add8a815 100644
--- a/circle.yml
+++ b/circle.yml
@@ -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");