diff options
author | chriseth <c@ethdev.com> | 2015-10-06 20:13:07 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2015-10-06 20:20:06 +0800 |
commit | 99351aebe0c9ebbb06e34c18ecc19bc0c87d9d54 (patch) | |
tree | fd0c7d5797454be93d4c767142ed6042ebf4d00f | |
parent | 44e42bf52e481f4f653a669291812b4d31f06022 (diff) | |
download | dexon-solidity-99351aebe0c9ebbb06e34c18ecc19bc0c87d9d54.tar.gz dexon-solidity-99351aebe0c9ebbb06e34c18ecc19bc0c87d9d54.tar.zst dexon-solidity-99351aebe0c9ebbb06e34c18ecc19bc0c87d9d54.zip |
Compiler version stamp.
-rw-r--r-- | libsolidity/Compiler.cpp | 6 | ||||
-rw-r--r-- | libsolidity/CompilerContext.cpp | 9 | ||||
-rw-r--r-- | libsolidity/CompilerContext.h | 3 | ||||
-rw-r--r-- | libsolidity/Utils.h | 1 | ||||
-rw-r--r-- | libsolidity/Version.cpp | 36 | ||||
-rw-r--r-- | libsolidity/Version.h | 6 | ||||
-rw-r--r-- | test/libsolidity/SolidityEndToEndTest.cpp | 11 |
7 files changed, 70 insertions, 2 deletions
diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp index 1ef63bbf..6fb09def 100644 --- a/libsolidity/Compiler.cpp +++ b/libsolidity/Compiler.cpp @@ -68,6 +68,12 @@ void Compiler::compileContract( packIntoContractCreator(_contract, m_runtimeContext); if (m_optimize) m_context.optimise(m_optimizeRuns); + + if (_contract.isLibrary()) + { + solAssert(m_runtimeSub != size_t(-1), ""); + m_context.injectVersionStampIntoSub(m_runtimeSub); + } } void Compiler::compileClone( diff --git a/libsolidity/CompilerContext.cpp b/libsolidity/CompilerContext.cpp index 717627a5..fa7f9c77 100644 --- a/libsolidity/CompilerContext.cpp +++ b/libsolidity/CompilerContext.cpp @@ -20,10 +20,12 @@ * Utilities for the solidity compiler. */ +#include <libsolidity/CompilerContext.h> #include <utility> #include <numeric> #include <libsolidity/AST.h> #include <libsolidity/Compiler.h> +#include <libsolidity/Version.h> using namespace std; @@ -177,6 +179,13 @@ void CompilerContext::resetVisitedNodes(ASTNode const* _node) updateSourceLocation(); } +void CompilerContext::injectVersionStampIntoSub(size_t _subIndex) +{ + eth::Assembly& sub = m_asm.sub(_subIndex); + sub.injectStart(eth::Instruction::POP); + sub.injectStart(fromBigEndian<u256>(binaryVersion())); +} + eth::AssemblyItem CompilerContext::virtualFunctionEntryLabel( FunctionDefinition const& _function, vector<ContractDefinition const*>::const_iterator _searchStart diff --git a/libsolidity/CompilerContext.h b/libsolidity/CompilerContext.h index 46ebfcf8..18865091 100644 --- a/libsolidity/CompilerContext.h +++ b/libsolidity/CompilerContext.h @@ -128,6 +128,9 @@ public: CompilerContext& operator<<(u256 const& _value) { m_asm.append(_value); return *this; } CompilerContext& operator<<(bytes const& _data) { m_asm.append(_data); return *this; } + /// Prepends "PUSH <compiler version number> POP" + void injectVersionStampIntoSub(size_t _subIndex); + void optimise(unsigned _runs = 200) { m_asm.optimise(true, true, _runs); } eth::Assembly const& assembly() const { return m_asm; } diff --git a/libsolidity/Utils.h b/libsolidity/Utils.h index 05c5fa6f..6c8e3b33 100644 --- a/libsolidity/Utils.h +++ b/libsolidity/Utils.h @@ -23,6 +23,7 @@ #pragma once #include <libdevcore/Assertions.h> +#include <libsolidity/Exceptions.h> /// Assertion that throws an InternalCompilerError containing the given description if it is not met. #define solAssert(CONDITION, DESCRIPTION) \ diff --git a/libsolidity/Version.cpp b/libsolidity/Version.cpp index c6b5c509..09a6d84b 100644 --- a/libsolidity/Version.cpp +++ b/libsolidity/Version.cpp @@ -22,16 +22,19 @@ #include <libsolidity/Version.h> #include <string> +#include <libdevcore/CommonData.h> +#include <libdevcore/Common.h> #include <libevmasm/Version.h> +#include <libsolidity/Utils.h> #include <solidity/BuildInfo.h> -#include <libdevcore/Common.h> using namespace dev; using namespace dev::solidity; using namespace std; char const* dev::solidity::VersionNumber = ETH_PROJECT_VERSION; -extern string const dev::solidity::VersionString = + +string const dev::solidity::VersionString = string(dev::solidity::VersionNumber) + "-" + string(DEV_QUOTED(ETH_COMMIT_HASH)).substr(0, 8) + @@ -39,3 +42,32 @@ extern string const dev::solidity::VersionString = "/" DEV_QUOTED(ETH_BUILD_TYPE) "-" DEV_QUOTED(ETH_BUILD_PLATFORM) " linked to libethereum-" + eth::VersionStringLibEvmAsm; + +bytes dev::solidity::binaryVersion() +{ + bytes ret{0}; + size_t i = 0; + auto parseDecimal = [&]() + { + size_t ret = 0; + solAssert('0' <= VersionString[i] && VersionString[i] <= '9', ""); + for (; i < VersionString.size() && '0' <= VersionString[i] && VersionString[i] <= '9'; ++i) + ret = ret * 10 + (VersionString[i] - '0'); + return ret; + }; + ret.push_back(byte(parseDecimal())); + solAssert(i < VersionString.size() && VersionString[i] == '.', ""); + ++i; + ret.push_back(byte(parseDecimal())); + solAssert(i < VersionString.size() && VersionString[i] == '.', ""); + ++i; + ret.push_back(byte(parseDecimal())); + solAssert(i < VersionString.size() && VersionString[i] == '-', ""); + ++i; + solAssert(i + 7 < VersionString.size(), ""); + ret += fromHex(VersionString.substr(i, 8)); + solAssert(ret.size() == 1 + 3 + 4, ""); + + return ret; +} + diff --git a/libsolidity/Version.h b/libsolidity/Version.h index 6e00f07b..fea73997 100644 --- a/libsolidity/Version.h +++ b/libsolidity/Version.h @@ -23,6 +23,7 @@ #pragma once #include <string> +#include <libdevcore/Common.h> namespace dev { @@ -32,5 +33,10 @@ namespace solidity extern char const* VersionNumber; extern std::string const VersionString; +/// @returns a binary form of the version string, where A.B.C-HASH is encoded such that +/// the first byte is zero, the following three bytes encode A B and C (interpreted as decimals) +/// and HASH is interpreted as 8 hex digits and encoded into the last four bytes. +bytes binaryVersion(); + } } diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index b46b405d..3cfe4975 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -5539,6 +5539,17 @@ BOOST_AUTO_TEST_CASE(calldata_offset) BOOST_CHECK(callContractFunction("last()", encodeArgs()) == encodeDyn(string("nd"))); } +BOOST_AUTO_TEST_CASE(version_stamp_for_libraries) +{ + char const* sourceCode = "library lib {}"; + m_optimize = true; + bytes runtimeCode = compileAndRun(sourceCode, 0, "lib"); + BOOST_CHECK(runtimeCode.size() >= 8); + BOOST_CHECK_EQUAL(runtimeCode[0], int(eth::Instruction::PUSH6)); // might change once we switch to 1.x.x + BOOST_CHECK_EQUAL(runtimeCode[1], 1); // might change once we switch away from x.1.x + BOOST_CHECK_EQUAL(runtimeCode[7], int(eth::Instruction::POP)); +} + BOOST_AUTO_TEST_SUITE_END() } |