Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ jobs:

b_osx:
macos:
xcode: "10.0.0"
xcode: "11.0.0"
environment:
TERM: xterm
CMAKE_BUILD_TYPE: Debug
Expand All @@ -445,7 +445,7 @@ jobs:

t_osx_cli:
macos:
xcode: "10.0.0"
xcode: "11.0.0"
environment:
TERM: xterm
steps:
Expand Down
2 changes: 1 addition & 1 deletion .circleci/docker/Dockerfile.clang.ubuntu1904
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ RUN git clone --recursive -b boost-1.69.0 https://github.com/boostorg/boost.git
./bootstrap.sh --with-toolset=clang --prefix=/usr; \
./b2 toolset=clang headers; \
./b2 toolset=clang variant=release \
system regex filesystem unit_test_framework program_options \
system filesystem unit_test_framework program_options \
install -j $(($(nproc)/2)); \
rm -rf /usr/src/boost

Expand Down
2 changes: 1 addition & 1 deletion .circleci/docker/Dockerfile.ubuntu1804
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ RUN set -ex; \
build-essential \
software-properties-common \
cmake ninja-build clang++-8 \
libboost-regex-dev libboost-filesystem-dev libboost-test-dev libboost-system-dev \
libboost-filesystem-dev libboost-test-dev libboost-system-dev \
libboost-program-options-dev \
libjsoncpp-dev \
llvm-8-dev libz3-static-dev \
Expand Down
2 changes: 1 addition & 1 deletion .circleci/docker/Dockerfile.ubuntu1904
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ RUN set -ex; \
build-essential \
software-properties-common \
cmake ninja-build clang++-8 libc++-8-dev libc++abi-8-dev \
libboost-regex-dev libboost-filesystem-dev libboost-test-dev libboost-system-dev \
libboost-filesystem-dev libboost-test-dev libboost-system-dev \
libboost-program-options-dev \
libjsoncpp-dev \
llvm-8-dev libcvc4-dev libz3-static-dev libleveldb1d \
Expand Down
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Language Features:


Compiler Features:
* Code Generator: Use SELFBALANCE for ``address(this).balance`` if using Istanbul EVM


Bugfixes:
Expand Down
2 changes: 2 additions & 0 deletions cmake/EthCompilerSettings.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ elseif (DEFINED MSVC)
add_compile_options(-D_WIN32_WINNT=0x0600) # declare Windows Vista API requirement
add_compile_options(-DNOMINMAX) # undefine windows.h MAX && MIN macros cause it cause conflicts with std::min && std::max functions
add_compile_options(/utf-8) # enable utf-8 encoding (solves warning 4819)
add_compile_options(-DBOOST_REGEX_NO_LIB) # disable automatic boost::regex library selection
add_compile_options(-D_REGEX_MAX_STACK_COUNT=200000L) # increase std::regex recursion depth limit

# disable empty object file warning
set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4221")
Expand Down
2 changes: 1 addition & 1 deletion cmake/EthDependencies.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ set(ETH_SCRIPTS_DIR ${ETH_CMAKE_DIR}/scripts)
set(Boost_USE_MULTITHREADED ON)
option(Boost_USE_STATIC_LIBS "Link Boost statically" ON)

set(BOOST_COMPONENTS "regex;filesystem;unit_test_framework;program_options;system")
set(BOOST_COMPONENTS "filesystem;unit_test_framework;program_options;system")

find_package(Boost 1.65.0 QUIET REQUIRED COMPONENTS ${BOOST_COMPONENTS})

Expand Down
2 changes: 1 addition & 1 deletion docs/assembly.rst
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ In the grammar, opcodes are represented as pre-defined identifiers.
| create2(v, p, n, s) | | C | create new contract with code mem[p...(p+n)) at address |
| | | | keccak256(0xff . this . s . keccak256(mem[p...(p+n))) |
| | | | and send v wei and return the new address, where ``0xff`` is a |
| | | | 8 byte value, ``this`` is the current contract's address |
| | | | 1 byte value, ``this`` is the current contract's address |
| | | | as a 20 byte value and ``s`` is a big-endian 256-bit value |
+-------------------------+-----+---+-----------------------------------------------------------------+
| call(g, a, v, in, | | F | call contract at address a with input mem[in...(in+insize)) |
Expand Down
2 changes: 1 addition & 1 deletion libdevcore/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ set(sources
)

add_library(devcore ${sources})
target_link_libraries(devcore PUBLIC jsoncpp Boost::boost Boost::filesystem Boost::regex Boost::system)
target_link_libraries(devcore PUBLIC jsoncpp Boost::boost Boost::filesystem Boost::system)
target_include_directories(devcore PUBLIC "${CMAKE_SOURCE_DIR}")
add_dependencies(devcore solidity_BuildInfo.h)

Expand Down
35 changes: 30 additions & 5 deletions libdevcore/Whiskers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

#include <libdevcore/Assertions.h>

#include <boost/regex.hpp>
#include <regex>

using namespace std;
using namespace dev;
Expand Down Expand Up @@ -72,9 +72,9 @@ string Whiskers::render() const

void Whiskers::checkParameterValid(string const& _parameter) const
{
static boost::regex validParam("^" + paramRegex() + "$");
static regex validParam("^" + paramRegex() + "$");
assertThrow(
boost::regex_match(_parameter, validParam),
regex_match(_parameter, validParam),
WhiskersError,
"Parameter" + _parameter + " contains invalid characters."
);
Expand All @@ -99,15 +99,40 @@ void Whiskers::checkParameterUnknown(string const& _parameter) const
);
}

namespace
{
template<class ReplaceCallback>
string regex_replace(
string const& _source,
regex const& _pattern,
ReplaceCallback _replace,
regex_constants::match_flag_type _flags = regex_constants::match_default
)
{
sregex_iterator curMatch(_source.begin(), _source.end(), _pattern, _flags);
sregex_iterator matchEnd;
string::const_iterator lastMatchedPos(_source.cbegin());
string result;
while (curMatch != matchEnd)
{
result.append(curMatch->prefix().first, curMatch->prefix().second);
result.append(_replace(*curMatch));
lastMatchedPos = (*curMatch)[0].second;
++curMatch;
}
result.append(lastMatchedPos, _source.cend());
return result;
}
}

string Whiskers::replace(
string const& _template,
StringMap const& _parameters,
map<string, bool> const& _conditions,
map<string, vector<StringMap>> const& _listParameters
)
{
using namespace boost;
static regex listOrTag("<(" + paramRegex() + ")>|<#(" + paramRegex() + ")>(.*?)</\\2>|<\\?(" + paramRegex() + ")>(.*?)(<!\\4>(.*?))?</\\4>");
static regex listOrTag("<(" + paramRegex() + ")>|<#(" + paramRegex() + ")>((?:.|\\r|\\n)*?)</\\2>|<\\?(" + paramRegex() + ")>((?:.|\\r|\\n)*?)(<!\\4>((?:.|\\r|\\n)*?))?</\\4>");
return regex_replace(_template, listOrTag, [&](match_results<string::const_iterator> _match) -> string
{
string tagName(_match[1]);
Expand Down
22 changes: 22 additions & 0 deletions libsolidity/codegen/ExpressionCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1229,6 +1229,28 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
utils().leftShiftNumberOnStack(224);
return false;
}
// Another special case for `address(this).balance`. Post-Istanbul, we can use the selfbalance
// opcode.
if (
m_context.evmVersion().hasSelfBalance() &&
member == "balance" &&
_memberAccess.expression().annotation().type->category() == Type::Category::Address
)
if (FunctionCall const* funCall = dynamic_cast<FunctionCall const*>(&_memberAccess.expression()))
if (auto const* addr = dynamic_cast<ElementaryTypeNameExpression const*>(&funCall->expression()))
if (
addr->typeName().token() == Token::Address &&
funCall->arguments().size() == 1
)
if (auto arg = dynamic_cast<Identifier const*>( funCall->arguments().front().get()))
if (
arg->name() == "this" &&
dynamic_cast<MagicVariableDeclaration const*>(arg->annotation().referencedDeclaration)
)
{
m_context << Instruction::SELFBALANCE;
return false;
}

_memberAccess.expression().accept(*this);
switch (_memberAccess.expression().annotation().type->category())
Expand Down
16 changes: 16 additions & 0 deletions libyul/optimiser/Suite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include <libyul/optimiser/SSATransform.h>
#include <libyul/optimiser/StackCompressor.h>
#include <libyul/optimiser/StructuralSimplifier.h>
#include <libyul/optimiser/SyntacticalEquality.h>
#include <libyul/optimiser/RedundantAssignEliminator.h>
#include <libyul/optimiser/VarNameCleaner.h>
#include <libyul/optimiser/LoadResolver.h>
Expand Down Expand Up @@ -343,10 +344,25 @@ map<string, unique_ptr<OptimiserStep>> const& OptimiserSuite::allSteps()

void OptimiserSuite::runSequence(std::vector<string> const& _steps, Block& _ast)
{
unique_ptr<Block> copy;
if (m_debug == Debug::PrintChanges)
copy = make_unique<Block>(boost::get<Block>(ASTCopier{}(_ast)));
for (string const& step: _steps)
{
if (m_debug == Debug::PrintStep)
cout << "Running " << step << endl;
allSteps().at(step)->run(m_context, _ast);
if (m_debug == Debug::PrintChanges)
{
// TODO should add switch to also compare variable names!
if (SyntacticallyEqual{}.statementEqual(_ast, *copy))
cout << "== Running " << step << " did not cause changes." << endl;
else
{
cout << "== Running " << step << " changed the AST." << endl;
cout << AsmPrinter{}(_ast) << endl;
copy = make_unique<Block>(boost::get<Block>(ASTCopier{}(_ast)));
}
}
}
}
3 changes: 2 additions & 1 deletion libyul/optimiser/Suite.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ class OptimiserSuite
enum class Debug
{
None,
PrintStep
PrintStep,
PrintChanges
};
static void run(
Dialect const& _dialect,
Expand Down
2 changes: 1 addition & 1 deletion scripts/travis-emscripten/build_emscripten.sh
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ echo -en 'travis_fold:start:compiling_boost\\r'
test -e "$WORKSPACE"/boost_1_70_0_install/include/boost/version.hpp || (
cd "$WORKSPACE"/boost_1_70_0
./b2 toolset=emscripten link=static variant=release threading=single runtime-link=static \
--with-system --with-regex --with-filesystem --with-test --with-program_options cxxflags="-Wno-unused-local-typedef -Wno-variadic-macros -Wno-c99-extensions -Wno-all" \
--with-system --with-filesystem --with-test --with-program_options cxxflags="-Wno-unused-local-typedef -Wno-variadic-macros -Wno-c99-extensions -Wno-all" \
--prefix="$WORKSPACE"/boost_1_70_0_install install
)
ln -sf "$WORKSPACE"/boost_1_70_0_install/lib/* /emsdk_portable/sdk/system/lib
Expand Down
19 changes: 19 additions & 0 deletions test/libsolidity/SolidityExpressionCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,25 @@ BOOST_AUTO_TEST_CASE(gas_left)
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}

BOOST_AUTO_TEST_CASE(selfbalance)
{
char const* sourceCode = R"(
contract test {
function f() returns (uint) {
return address(this).balance;
}
}
)";

bytes code = compileFirstExpression(sourceCode, {}, {});

if (dev::test::Options::get().evmVersion() == EVMVersion::istanbul())
{
bytes expectation({uint8_t(Instruction::SELFBALANCE)});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
}

BOOST_AUTO_TEST_SUITE_END()

}
Expand Down
11 changes: 10 additions & 1 deletion test/libsolidity/util/BytesUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ string BytesUtils::formatBytes(
os << formatHexString(_bytes);
break;
case ABIType::String:
os << formatString(_bytes);
os << formatString(_bytes, _bytes.size() - countRightPaddedZeros(_bytes));
break;
case ABIType::Failure:
break;
Expand Down Expand Up @@ -311,3 +311,12 @@ string BytesUtils::formatBytesRange(
return os.str();
}

size_t BytesUtils::countRightPaddedZeros(bytes const& _bytes)
{
return find_if(
_bytes.rbegin(),
_bytes.rend(),
[](uint8_t b) { return b != '\0'; }
) - _bytes.rbegin();
}

4 changes: 4 additions & 0 deletions test/libsolidity/util/BytesUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ class BytesUtils
ParameterList const& _parameters,
bool _highlight
);

/// Count the number of zeros between the last non-zero byte and the end of
/// \param _bytes.
static size_t countRightPaddedZeros(bytes const& _bytes);
};

}
Expand Down
2 changes: 1 addition & 1 deletion test/libsolidity/util/TestFunctionCall.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class TestFunctionCall
TestFunctionCall(FunctionCall _call): m_call(std::move(_call)) {}

/// Formats this function call test and applies the format that was detected during parsing.
/// If _renderResult is false, the expected result of the call will is used, if it's false
/// If _renderResult is false, the expected result of the call will be used, if it's true
/// the actual result is used.
/// If _highlight is false, it's formatted without colorized highlighting. If it's true, AnsiColorized is
/// used to apply a colorized highlighting.
Expand Down