aboutsummaryrefslogtreecommitdiffstats
path: root/libevmasm/Assembly.cpp
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2018-11-14 02:33:35 +0800
committerGitHub <noreply@github.com>2018-11-14 02:33:35 +0800
commit1d4f565a64988a3400847d2655ca24f73f234bc6 (patch)
treecaaa6c26e307513505349b50ca4f2a8a9506752b /libevmasm/Assembly.cpp
parent59dbf8f1085b8b92e8b7eb0ce380cbeb642e97eb (diff)
parent91b6b8a88e76016e0324036cb7a7f9300a1e2439 (diff)
downloaddexon-solidity-1d4f565a64988a3400847d2655ca24f73f234bc6.tar
dexon-solidity-1d4f565a64988a3400847d2655ca24f73f234bc6.tar.gz
dexon-solidity-1d4f565a64988a3400847d2655ca24f73f234bc6.tar.bz2
dexon-solidity-1d4f565a64988a3400847d2655ca24f73f234bc6.tar.lz
dexon-solidity-1d4f565a64988a3400847d2655ca24f73f234bc6.tar.xz
dexon-solidity-1d4f565a64988a3400847d2655ca24f73f234bc6.tar.zst
dexon-solidity-1d4f565a64988a3400847d2655ca24f73f234bc6.zip
Merge pull request #5416 from ethereum/develop
Merge develop into release for 0.5.0
Diffstat (limited to 'libevmasm/Assembly.cpp')
-rw-r--r--libevmasm/Assembly.cpp75
1 files changed, 42 insertions, 33 deletions
diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp
index b71bc80c..e63194a0 100644
--- a/libevmasm/Assembly.cpp
+++ b/libevmasm/Assembly.cpp
@@ -41,10 +41,19 @@ void Assembly::append(Assembly const& _a)
auto newDeposit = m_deposit + _a.deposit();
for (AssemblyItem i: _a.m_items)
{
- if (i.type() == Tag || i.type() == PushTag)
+ switch (i.type())
+ {
+ case Tag:
+ case PushTag:
i.setData(i.data() + m_usedTags);
- else if (i.type() == PushSub || i.type() == PushSubSize)
+ break;
+ case PushSub:
+ case PushSubSize:
i.setData(i.data() + m_subs.size());
+ break;
+ default:
+ break;
+ }
append(i);
}
m_deposit = newDeposit;
@@ -69,6 +78,21 @@ void Assembly::append(Assembly const& _a, int _deposit)
append(Instruction::POP);
}
+AssemblyItem const& Assembly::append(AssemblyItem const& _i)
+{
+ assertThrow(m_deposit >= 0, AssemblyException, "Stack underflow.");
+ m_deposit += _i.deposit();
+ m_items.push_back(_i);
+ if (m_items.back().location().isEmpty() && !m_currentSourceLocation.isEmpty())
+ m_items.back().setLocation(m_currentSourceLocation);
+ return back();
+}
+
+void Assembly::injectStart(AssemblyItem const& _i)
+{
+ m_items.insert(m_items.begin(), _i);
+}
+
unsigned Assembly::bytesRequired(unsigned subTagSize) const
{
for (unsigned tagSize = subTagSize; true; ++tagSize)
@@ -264,7 +288,7 @@ Json::Value Assembly::assemblyJSON(StringMap const& _sourceCodes) const
createJsonValue("PUSH [ErrorTag]", i.location().start, i.location().end, ""));
else
collection.append(
- createJsonValue("PUSH [tag]", i.location().start, i.location().end, string(i.data())));
+ createJsonValue("PUSH [tag]", i.location().start, i.location().end, dev::toString(i.data())));
break;
case PushSub:
collection.append(
@@ -290,7 +314,7 @@ Json::Value Assembly::assemblyJSON(StringMap const& _sourceCodes) const
break;
case Tag:
collection.append(
- createJsonValue("tag", i.location().start, i.location().end, string(i.data())));
+ createJsonValue("tag", i.location().start, i.location().end, dev::toString(i.data())));
collection.append(
createJsonValue("JUMPDEST", i.location().start, i.location().end));
break;
@@ -323,16 +347,6 @@ Json::Value Assembly::assemblyJSON(StringMap const& _sourceCodes) const
return root;
}
-AssemblyItem const& Assembly::append(AssemblyItem const& _i)
-{
- assertThrow(m_deposit >= 0, AssemblyException, "Stack underflow.");
- m_deposit += _i.deposit();
- m_items.push_back(_i);
- if (m_items.back().location().isEmpty() && !m_currentSourceLocation.isEmpty())
- m_items.back().setLocation(m_currentSourceLocation);
- return back();
-}
-
AssemblyItem Assembly::namedTag(string const& _name)
{
assertThrow(!_name.empty(), AssemblyException, "Empty named tag.");
@@ -348,11 +362,6 @@ AssemblyItem Assembly::newPushLibraryAddress(string const& _identifier)
return AssemblyItem(PushLibraryAddress, h);
}
-void Assembly::injectStart(AssemblyItem const& _i)
-{
- m_items.insert(m_items.begin(), _i);
-}
-
Assembly& Assembly::optimise(bool _enable, EVMVersion _evmVersion, bool _isCreation, size_t _runs)
{
OptimiserSettings settings;
@@ -516,14 +525,14 @@ LinkerObject const& Assembly::assemble() const
multimap<size_t, size_t> subRef;
vector<unsigned> sizeRef; ///< Pointers to code locations where the size of the program is inserted
unsigned bytesPerTag = dev::bytesRequired(bytesRequiredForCode);
- byte tagPush = (byte)Instruction::PUSH1 - 1 + bytesPerTag;
+ uint8_t tagPush = (uint8_t)Instruction::PUSH1 - 1 + bytesPerTag;
unsigned bytesRequiredIncludingData = bytesRequiredForCode + 1 + m_auxiliaryData.size();
for (auto const& sub: m_subs)
bytesRequiredIncludingData += sub->assemble().bytecode.size();
unsigned bytesPerDataRef = dev::bytesRequired(bytesRequiredIncludingData);
- byte dataRefPush = (byte)Instruction::PUSH1 - 1 + bytesPerDataRef;
+ uint8_t dataRefPush = (uint8_t)Instruction::PUSH1 - 1 + bytesPerDataRef;
ret.bytecode.reserve(bytesRequiredIncludingData);
for (AssemblyItem const& i: m_items)
@@ -535,25 +544,25 @@ LinkerObject const& Assembly::assemble() const
switch (i.type())
{
case Operation:
- ret.bytecode.push_back((byte)i.instruction());
+ ret.bytecode.push_back((uint8_t)i.instruction());
break;
case PushString:
{
- ret.bytecode.push_back((byte)Instruction::PUSH32);
+ ret.bytecode.push_back((uint8_t)Instruction::PUSH32);
unsigned ii = 0;
for (auto j: m_strings.at((h256)i.data()))
if (++ii > 32)
break;
else
- ret.bytecode.push_back((byte)j);
+ ret.bytecode.push_back((uint8_t)j);
while (ii++ < 32)
ret.bytecode.push_back(0);
break;
}
case Push:
{
- byte b = max<unsigned>(1, dev::bytesRequired(i.data()));
- ret.bytecode.push_back((byte)Instruction::PUSH1 - 1 + b);
+ uint8_t b = max<unsigned>(1, dev::bytesRequired(i.data()));
+ ret.bytecode.push_back((uint8_t)Instruction::PUSH1 - 1 + b);
ret.bytecode.resize(ret.bytecode.size() + b);
bytesRef byr(&ret.bytecode.back() + 1 - b, b);
toBigEndian(i.data(), byr);
@@ -580,8 +589,8 @@ LinkerObject const& Assembly::assemble() const
{
auto s = m_subs.at(size_t(i.data()))->assemble().bytecode.size();
i.setPushedValue(u256(s));
- byte b = max<unsigned>(1, dev::bytesRequired(s));
- ret.bytecode.push_back((byte)Instruction::PUSH1 - 1 + b);
+ uint8_t b = max<unsigned>(1, dev::bytesRequired(s));
+ ret.bytecode.push_back((uint8_t)Instruction::PUSH1 - 1 + b);
ret.bytecode.resize(ret.bytecode.size() + b);
bytesRef byr(&ret.bytecode.back() + 1 - b, b);
toBigEndian(s, byr);
@@ -595,12 +604,12 @@ LinkerObject const& Assembly::assemble() const
break;
}
case PushLibraryAddress:
- ret.bytecode.push_back(byte(Instruction::PUSH20));
+ ret.bytecode.push_back(uint8_t(Instruction::PUSH20));
ret.linkReferences[ret.bytecode.size()] = m_libraries.at(i.data());
ret.bytecode.resize(ret.bytecode.size() + 20);
break;
case PushDeployTimeAddress:
- ret.bytecode.push_back(byte(Instruction::PUSH20));
+ ret.bytecode.push_back(uint8_t(Instruction::PUSH20));
ret.bytecode.resize(ret.bytecode.size() + 20);
break;
case Tag:
@@ -609,7 +618,7 @@ LinkerObject const& Assembly::assemble() const
assertThrow(ret.bytecode.size() < 0xffffffffL, AssemblyException, "Tag too large.");
assertThrow(m_tagPositionsInBytecode[size_t(i.data())] == size_t(-1), AssemblyException, "Duplicate tag position.");
m_tagPositionsInBytecode[size_t(i.data())] = ret.bytecode.size();
- ret.bytecode.push_back((byte)Instruction::JUMPDEST);
+ ret.bytecode.push_back((uint8_t)Instruction::JUMPDEST);
break;
default:
BOOST_THROW_EXCEPTION(InvalidOpcode());
@@ -617,8 +626,8 @@ LinkerObject const& Assembly::assemble() const
}
if (!m_subs.empty() || !m_data.empty() || !m_auxiliaryData.empty())
- // Append a STOP just to be sure.
- ret.bytecode.push_back(0);
+ // Append an INVALID here to help tests find miscompilation.
+ ret.bytecode.push_back(uint8_t(Instruction::INVALID));
for (size_t i = 0; i < m_subs.size(); ++i)
{