aboutsummaryrefslogtreecommitdiffstats
path: root/libevmasm/AssemblyItem.cpp
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2016-11-15 21:01:11 +0800
committerchriseth <c@ethdev.com>2017-01-03 21:13:49 +0800
commita285ca44f228236ab92eb8dc9d878053829276b4 (patch)
tree68040d0309c0d4de80514a7f58f27dbe7a72a71b /libevmasm/AssemblyItem.cpp
parent0bd8c204f04f679b4371199d876bc6160d913782 (diff)
downloaddexon-solidity-a285ca44f228236ab92eb8dc9d878053829276b4.tar.gz
dexon-solidity-a285ca44f228236ab92eb8dc9d878053829276b4.tar.zst
dexon-solidity-a285ca44f228236ab92eb8dc9d878053829276b4.zip
Assembly output for Assembly object.
Diffstat (limited to 'libevmasm/AssemblyItem.cpp')
-rw-r--r--libevmasm/AssemblyItem.cpp82
1 files changed, 82 insertions, 0 deletions
diff --git a/libevmasm/AssemblyItem.cpp b/libevmasm/AssemblyItem.cpp
index 54e38de8..8b3f920a 100644
--- a/libevmasm/AssemblyItem.cpp
+++ b/libevmasm/AssemblyItem.cpp
@@ -20,6 +20,7 @@
*/
#include "AssemblyItem.h"
+#include <libevmasm/SemanticInformation.h>
#include <fstream>
using namespace std;
@@ -97,6 +98,28 @@ int AssemblyItem::deposit() const
return 0;
}
+bool AssemblyItem::canBeFunctional() const
+{
+ switch (m_type)
+ {
+ case Operation:
+ return !SemanticInformation::isDupInstruction(*this) && !SemanticInformation::isSwapInstruction(*this);
+ case Push:
+ case PushString:
+ case PushTag:
+ case PushData:
+ case PushSub:
+ case PushSubSize:
+ case PushProgramSize:
+ case PushLibraryAddress:
+ return true;
+ case Tag:
+ return false;
+ default:;
+ }
+ return 0;
+}
+
string AssemblyItem::getJumpTypeAsString() const
{
switch (m_jumpType)
@@ -111,6 +134,65 @@ string AssemblyItem::getJumpTypeAsString() const
}
}
+string AssemblyItem::toAssemblyText() const
+{
+ string text;
+ switch (type())
+ {
+ case Operation:
+ {
+ assertThrow(isValidInstruction(instruction()), AssemblyException, "Invalid instruction.");
+ string name = instructionInfo(instruction()).name;
+ transform(name.begin(), name.end(), name.begin(), [](unsigned char _c) { return tolower(_c); });
+ text = name;
+ break;
+ }
+ case Push:
+ text = toHex(toCompactBigEndian(data(), 1), 1, HexPrefix::Add);
+ break;
+ case PushString:
+ assertThrow(false, AssemblyException, "Push string assembly output not implemented.");
+ break;
+ case PushTag:
+ assertThrow(data() < 0x10000, AssemblyException, "Sub-assembly tags not yet implemented.");
+ text = string("tag_") + to_string(size_t(data()));
+ break;
+ case Tag:
+ assertThrow(data() < 0x10000, AssemblyException, "Sub-assembly tags not yet implemented.");
+ text = string("tag_") + to_string(size_t(data())) + ":";
+ break;
+ case PushData:
+ assertThrow(false, AssemblyException, "Push data not implemented.");
+ break;
+ case PushSub:
+ text = string("dataOffset(sub_") + to_string(size_t(data())) + ")";
+ break;
+ case PushSubSize:
+ text = string("dataSize(sub_") + to_string(size_t(data())) + ")";
+ break;
+ case PushProgramSize:
+ text = string("programSize");
+ break;
+ case PushLibraryAddress:
+ text = string("linkerSymbol(\"") + toHex(data()) + string("\")");
+ break;
+ case UndefinedItem:
+ assertThrow(false, AssemblyException, "Invalid assembly item.");
+ break;
+ default:
+ BOOST_THROW_EXCEPTION(InvalidOpcode());
+ }
+ if (m_jumpType == JumpType::IntoFunction || m_jumpType == JumpType::OutOfFunction)
+ {
+ text += "\t//";
+ if (m_jumpType == JumpType::IntoFunction)
+ text += " in";
+ else
+ text += " out";
+ }
+ return text;
+}
+
ostream& dev::eth::operator<<(ostream& _out, AssemblyItem const& _item)
{
switch (_item.type())