aboutsummaryrefslogtreecommitdiffstats
path: root/Assembly.cpp
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2015-06-01 23:45:55 +0800
committerchriseth <c@ethdev.com>2015-06-01 23:45:55 +0800
commitd309c3c76827606c4cabd5660035df394a16b601 (patch)
tree5868b922ff18bec1cdc4404c810ec5b00bb3bc31 /Assembly.cpp
parentbeab869e1443a9ef8c4bbf27affda0265e8d1947 (diff)
parentda4cd45a85c1b3fe7b72ca53ba4263a309d40ed1 (diff)
downloaddexon-solidity-d309c3c76827606c4cabd5660035df394a16b601.tar.gz
dexon-solidity-d309c3c76827606c4cabd5660035df394a16b601.tar.zst
dexon-solidity-d309c3c76827606c4cabd5660035df394a16b601.zip
Merge pull request #1975 from LianaHus/sol_EVMExceptions
"error jump" instead of STOP instraction in case of exception
Diffstat (limited to 'Assembly.cpp')
-rw-r--r--Assembly.cpp32
1 files changed, 25 insertions, 7 deletions
diff --git a/Assembly.cpp b/Assembly.cpp
index 8c659188..a9ee9619 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -127,7 +127,10 @@ ostream& Assembly::streamAsm(ostream& _out, string const& _prefix, StringMap con
_out << " PUSH \"" << m_strings.at((h256)i.data()) << "\"";
break;
case PushTag:
- _out << " PUSH [tag" << dec << i.data() << "]";
+ if (i.data() == 0)
+ _out << " PUSH [ErrorTag]";
+ else
+ _out << " PUSH [tag" << dec << i.data() << "]";
break;
case PushSub:
_out << " PUSH [$" << h256(i.data()).abridged() << "]";
@@ -207,8 +210,12 @@ Json::Value Assembly::streamAsmJson(ostream& _out, StringMap const& _sourceCodes
createJsonValue("PUSH tag", i.getLocation().start, i.getLocation().end, m_strings.at((h256)i.data())));
break;
case PushTag:
- collection.append(
- createJsonValue("PUSH [tag]", i.getLocation().start, i.getLocation().end, string(i.data())));
+ if (i.data() == 0)
+ collection.append(
+ createJsonValue("PUSH [ErrorTag]", i.getLocation().start, i.getLocation().end, ""));
+ else
+ collection.append(
+ createJsonValue("PUSH [tag]", i.getLocation().start, i.getLocation().end, string(i.data())));
break;
case PushSub:
collection.append(
@@ -226,7 +233,7 @@ Json::Value Assembly::streamAsmJson(ostream& _out, StringMap const& _sourceCodes
collection.append(
createJsonValue("tag", i.getLocation().start, i.getLocation().end, string(i.data())));
collection.append(
- createJsonValue("JUMDEST", i.getLocation().start, i.getLocation().end));
+ createJsonValue("JUMPDEST", i.getLocation().start, i.getLocation().end));
break;
case PushData:
collection.append(createJsonValue("PUSH data", i.getLocation().start, i.getLocation().end, toStringInHex(i.data())));
@@ -387,6 +394,11 @@ bytes Assembly::assemble() const
// m_data must not change from here on
for (AssemblyItem const& i: m_items)
+ {
+ // store position of the invalid jump destination
+ if (i.type() != Tag && tagPos[0] == 0)
+ tagPos[0] = ret.size();
+
switch (i.type())
{
case Operation:
@@ -448,17 +460,23 @@ bytes Assembly::assemble() const
}
case Tag:
tagPos[(unsigned)i.data()] = ret.size();
+ assertThrow(i.data() != 0, AssemblyException, "");
ret.push_back((byte)Instruction::JUMPDEST);
break;
default:
BOOST_THROW_EXCEPTION(InvalidOpcode());
}
-
+ }
for (auto const& i: tagRef)
{
bytesRef r(ret.data() + i.first, bytesPerTag);
- //@todo in the failure case, we could use the position of the invalid jumpdest
- toBigEndian(i.second < tagPos.size() ? tagPos[i.second] : (1 << (8 * bytesPerTag)) - 1, r);
+ auto tag = i.second;
+ if (tag >= tagPos.size())
+ tag = 0;
+ if (tag == 0)
+ assertThrow(tagPos[tag] != 0, AssemblyException, "");
+
+ toBigEndian(tagPos[tag], r);
}
if (!m_data.empty())