/* This file is part of cpp-ethereum. cpp-ethereum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. cpp-ethereum is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ /** @file Assembly.cpp * @author Gav Wood * @date 2014 */ #include "AssemblyItem.h" #include using namespace std; using namespace dev; using namespace dev::eth; unsigned AssemblyItem::bytesRequired(unsigned _addressLength) const { switch (m_type) { case Operation: case Tag: // 1 byte for the JUMPDEST return 1; case PushString: return 33; case Push: return 1 + max(1, dev::bytesRequired(m_data)); case PushSubSize: case PushProgramSize: return 4; // worst case: a 16MB program case PushTag: case PushData: case PushSub: return 1 + _addressLength; default: break; } BOOST_THROW_EXCEPTION(InvalidOpcode()); } int AssemblyItem::deposit() const { switch (m_type) { case Operation: return instructionInfo(instruction()).ret - instructionInfo(instruction()).args; case Push: case PushString: case PushTag: case PushData: case PushSub: case PushSubSize: case PushProgramSize: return 1; case Tag: return 0; default:; } return 0; } string AssemblyItem::getJumpTypeAsString() const { switch (m_jumpType) { case JumpType::IntoFunction: return "[in]"; case JumpType::OutOfFunction: return "[out]"; case JumpType::Ordinary: default: return ""; } } ostream& dev::eth::operator<<(ostream& _out, AssemblyItem const& _item) { switch (_item.type()) { case Operation: _out << " " << instructionInfo(_item.instruction()).name; if (_item.instruction() == eth::Instruction::JUMP || _item.instruction() == eth::Instruction::JUMPI) _out << "\t" << _item.getJumpTypeAsString(); break; case Push: _out << " PUSH " << hex << _item.data(); break; case PushString: _out << " PushString" << hex << (unsigned)_item.data(); break; case PushTag: _out << " PushTag " << _item.data(); break; case Tag: _out << " Tag " << _item.data(); break; case PushData: _out << " PushData " << hex << (unsigned)_item.data(); break; case PushSub: _out << " PushSub " << hex << h256(_item.data()).abridged(); break; case PushSubSize: _out << " PushSubSize " << hex << h256(_item.data()).abridged(); break; case PushProgramSize: _out << " PushProgramSize"; break; case UndefinedItem: _out << " ???"; break; default: BOOST_THROW_EXCEPTION(InvalidOpcode()); } return _out; } ostream& dev::eth::operator<<(ostream& _out, AssemblyItemsConstRef _i) { for (AssemblyItem const& i: _i) _out << i; return _out; }