This commit is contained in:
debris 2015-09-08 17:11:02 +02:00
parent aea7e04bf4
commit 3ca3fb492d
6 changed files with 59 additions and 59 deletions

View File

@ -91,7 +91,7 @@ unsigned Assembly::bytesRequired() const
} }
} }
string Assembly::getLocationFromSources(StringMap const& _sourceCodes, SourceLocation const& _location) const string Assembly::locationFromSources(StringMap const& _sourceCodes, SourceLocation const& _location) const
{ {
if (_location.isEmpty() || _sourceCodes.empty() || _location.start >= _location.end || _location.start < 0) if (_location.isEmpty() || _sourceCodes.empty() || _location.start >= _location.end || _location.start < 0)
return ""; return "";
@ -153,7 +153,7 @@ ostream& Assembly::streamAsm(ostream& _out, string const& _prefix, StringMap con
default: default:
BOOST_THROW_EXCEPTION(InvalidOpcode()); BOOST_THROW_EXCEPTION(InvalidOpcode());
} }
_out << "\t\t" << getLocationFromSources(_sourceCodes, i.getLocation()) << endl; _out << "\t\t" << locationFromSources(_sourceCodes, i.location()) << endl;
} }
if (!m_data.empty() || !m_subs.empty()) if (!m_data.empty() || !m_subs.empty())
@ -202,44 +202,44 @@ Json::Value Assembly::streamAsmJson(ostream& _out, StringMap const& _sourceCodes
{ {
case Operation: case Operation:
collection.append( collection.append(
createJsonValue(instructionInfo(i.instruction()).name, i.getLocation().start, i.getLocation().end, i.getJumpTypeAsString())); createJsonValue(instructionInfo(i.instruction()).name, i.location().start, i.location().end, i.getJumpTypeAsString()));
break; break;
case Push: case Push:
collection.append( collection.append(
createJsonValue("PUSH", i.getLocation().start, i.getLocation().end, toStringInHex(i.data()), i.getJumpTypeAsString())); createJsonValue("PUSH", i.location().start, i.location().end, toStringInHex(i.data()), i.getJumpTypeAsString()));
break; break;
case PushString: case PushString:
collection.append( collection.append(
createJsonValue("PUSH tag", i.getLocation().start, i.getLocation().end, m_strings.at((h256)i.data()))); createJsonValue("PUSH tag", i.location().start, i.location().end, m_strings.at((h256)i.data())));
break; break;
case PushTag: case PushTag:
if (i.data() == 0) if (i.data() == 0)
collection.append( collection.append(
createJsonValue("PUSH [ErrorTag]", i.getLocation().start, i.getLocation().end, "")); createJsonValue("PUSH [ErrorTag]", i.location().start, i.location().end, ""));
else else
collection.append( collection.append(
createJsonValue("PUSH [tag]", i.getLocation().start, i.getLocation().end, string(i.data()))); createJsonValue("PUSH [tag]", i.location().start, i.location().end, string(i.data())));
break; break;
case PushSub: case PushSub:
collection.append( collection.append(
createJsonValue("PUSH [$]", i.getLocation().start, i.getLocation().end, dev::toString(h256(i.data())))); createJsonValue("PUSH [$]", i.location().start, i.location().end, dev::toString(h256(i.data()))));
break; break;
case PushSubSize: case PushSubSize:
collection.append( collection.append(
createJsonValue("PUSH #[$]", i.getLocation().start, i.getLocation().end, dev::toString(h256(i.data())))); createJsonValue("PUSH #[$]", i.location().start, i.location().end, dev::toString(h256(i.data()))));
break; break;
case PushProgramSize: case PushProgramSize:
collection.append( collection.append(
createJsonValue("PUSHSIZE", i.getLocation().start, i.getLocation().end)); createJsonValue("PUSHSIZE", i.location().start, i.location().end));
break; break;
case Tag: case Tag:
collection.append( collection.append(
createJsonValue("tag", i.getLocation().start, i.getLocation().end, string(i.data()))); createJsonValue("tag", i.location().start, i.location().end, string(i.data())));
collection.append( collection.append(
createJsonValue("JUMPDEST", i.getLocation().start, i.getLocation().end)); createJsonValue("JUMPDEST", i.location().start, i.location().end));
break; break;
case PushData: case PushData:
collection.append(createJsonValue("PUSH data", i.getLocation().start, i.getLocation().end, toStringInHex(i.data()))); collection.append(createJsonValue("PUSH data", i.location().start, i.location().end, toStringInHex(i.data())));
break; break;
default: default:
BOOST_THROW_EXCEPTION(InvalidOpcode()); BOOST_THROW_EXCEPTION(InvalidOpcode());
@ -282,7 +282,7 @@ AssemblyItem const& Assembly::append(AssemblyItem const& _i)
{ {
m_deposit += _i.deposit(); m_deposit += _i.deposit();
m_items.push_back(_i); m_items.push_back(_i);
if (m_items.back().getLocation().isEmpty() && !m_currentSourceLocation.isEmpty()) if (m_items.back().location().isEmpty() && !m_currentSourceLocation.isEmpty())
m_items.back().setLocation(m_currentSourceLocation); m_items.back().setLocation(m_currentSourceLocation);
return back(); return back();
} }

View File

@ -49,7 +49,7 @@ public:
AssemblyItem newPushTag() { return AssemblyItem(PushTag, m_usedTags++); } AssemblyItem newPushTag() { return AssemblyItem(PushTag, m_usedTags++); }
AssemblyItem newData(bytes const& _data) { h256 h = (u256)std::hash<std::string>()(asString(_data)); m_data[h] = _data; return AssemblyItem(PushData, h); } AssemblyItem newData(bytes const& _data) { h256 h = (u256)std::hash<std::string>()(asString(_data)); m_data[h] = _data; return AssemblyItem(PushData, h); }
AssemblyItem newSub(Assembly const& _sub) { m_subs.push_back(_sub); return AssemblyItem(PushSub, m_subs.size() - 1); } AssemblyItem newSub(Assembly const& _sub) { m_subs.push_back(_sub); return AssemblyItem(PushSub, m_subs.size() - 1); }
Assembly const& getSub(size_t _sub) const { return m_subs.at(_sub); } Assembly const& sub(size_t _sub) const { return m_subs.at(_sub); }
AssemblyItem newPushString(std::string const& _data) { h256 h = (u256)std::hash<std::string>()(_data); m_strings[h] = _data; return AssemblyItem(PushString, h); } AssemblyItem newPushString(std::string const& _data) { h256 h = (u256)std::hash<std::string>()(_data); m_strings[h] = _data; return AssemblyItem(PushString, h); }
AssemblyItem newPushSubSize(u256 const& _subId) { return AssemblyItem(PushSubSize, _subId); } AssemblyItem newPushSubSize(u256 const& _subId) { return AssemblyItem(PushSubSize, _subId); }
@ -71,7 +71,7 @@ public:
AssemblyItem errorTag() { return AssemblyItem(PushTag, 0); } AssemblyItem errorTag() { return AssemblyItem(PushTag, 0); }
template <class T> Assembly& operator<<(T const& _d) { append(_d); return *this; } template <class T> Assembly& operator<<(T const& _d) { append(_d); return *this; }
AssemblyItems const& getItems() const { return m_items; } AssemblyItems const& items() const { return m_items; }
AssemblyItem const& back() const { return m_items.back(); } AssemblyItem const& back() const { return m_items.back(); }
std::string backString() const { return m_items.size() && m_items.back().type() == PushString ? m_strings.at((h256)m_items.back().data()) : std::string(); } std::string backString() const { return m_items.size() && m_items.back().type() == PushString ? m_strings.at((h256)m_items.back().data()) : std::string(); }
@ -107,7 +107,7 @@ public:
bool _inJsonFormat = false bool _inJsonFormat = false
) const; ) const;
protected: protected:
std::string getLocationFromSources(StringMap const& _sourceCodes, SourceLocation const& _location) const; std::string locationFromSources(StringMap const& _sourceCodes, SourceLocation const& _location) const;
void donePath() { if (m_totalDeposit != INT_MAX && m_totalDeposit != m_deposit) BOOST_THROW_EXCEPTION(InvalidDeposit()); } void donePath() { if (m_totalDeposit != INT_MAX && m_totalDeposit != m_deposit) BOOST_THROW_EXCEPTION(InvalidDeposit()); }
unsigned bytesRequired() const; unsigned bytesRequired() const;

View File

@ -78,7 +78,7 @@ public:
bool match(AssemblyItem const& _i) const { return _i.m_type == UndefinedItem || (m_type == _i.m_type && (m_type != Operation || m_data == _i.m_data)); } bool match(AssemblyItem const& _i) const { return _i.m_type == UndefinedItem || (m_type == _i.m_type && (m_type != Operation || m_data == _i.m_data)); }
void setLocation(SourceLocation const& _location) { m_location = _location; } void setLocation(SourceLocation const& _location) { m_location = _location; }
SourceLocation const& getLocation() const { return m_location; } SourceLocation const& location() const { return m_location; }
void setJumpType(JumpType _jumpType) { m_jumpType = _jumpType; } void setJumpType(JumpType _jumpType) { m_jumpType = _jumpType; }
JumpType getJumpType() const { return m_jumpType; } JumpType getJumpType() const { return m_jumpType; }

View File

@ -83,24 +83,24 @@ void CommonSubexpressionEliminator::optimizeBreakingItem()
return; return;
ExpressionClasses& classes = m_state.expressionClasses(); ExpressionClasses& classes = m_state.expressionClasses();
SourceLocation const& location = m_breakingItem->getLocation(); SourceLocation const& itemLocation = m_breakingItem->location();
if (*m_breakingItem == AssemblyItem(Instruction::JUMPI)) if (*m_breakingItem == AssemblyItem(Instruction::JUMPI))
{ {
AssemblyItem::JumpType jumpType = m_breakingItem->getJumpType(); AssemblyItem::JumpType jumpType = m_breakingItem->getJumpType();
Id condition = m_state.stackElement(m_state.stackHeight() - 1, location); Id condition = m_state.stackElement(m_state.stackHeight() - 1, itemLocation);
if (classes.knownNonZero(condition)) if (classes.knownNonZero(condition))
{ {
feedItem(AssemblyItem(Instruction::SWAP1, location), true); feedItem(AssemblyItem(Instruction::SWAP1, itemLocation), true);
feedItem(AssemblyItem(Instruction::POP, location), true); feedItem(AssemblyItem(Instruction::POP, itemLocation), true);
AssemblyItem item(Instruction::JUMP, location); AssemblyItem item(Instruction::JUMP, itemLocation);
item.setJumpType(jumpType); item.setJumpType(jumpType);
m_breakingItem = classes.storeItem(item); m_breakingItem = classes.storeItem(item);
} }
else if (classes.knownZero(condition)) else if (classes.knownZero(condition))
{ {
AssemblyItem it(Instruction::POP, location); AssemblyItem it(Instruction::POP, itemLocation);
feedItem(it, true); feedItem(it, true);
feedItem(it, true); feedItem(it, true);
m_breakingItem = nullptr; m_breakingItem = nullptr;
@ -108,12 +108,12 @@ void CommonSubexpressionEliminator::optimizeBreakingItem()
} }
else if (*m_breakingItem == AssemblyItem(Instruction::RETURN)) else if (*m_breakingItem == AssemblyItem(Instruction::RETURN))
{ {
Id size = m_state.stackElement(m_state.stackHeight() - 1, location); Id size = m_state.stackElement(m_state.stackHeight() - 1, itemLocation);
if (classes.knownZero(size)) if (classes.knownZero(size))
{ {
feedItem(AssemblyItem(Instruction::POP, location), true); feedItem(AssemblyItem(Instruction::POP, itemLocation), true);
feedItem(AssemblyItem(Instruction::POP, location), true); feedItem(AssemblyItem(Instruction::POP, itemLocation), true);
AssemblyItem item(Instruction::STOP, location); AssemblyItem item(Instruction::STOP, itemLocation);
m_breakingItem = classes.storeItem(item); m_breakingItem = classes.storeItem(item);
} }
} }
@ -179,16 +179,16 @@ AssemblyItems CSECodeGenerator::generateCode(
assertThrow(!m_classPositions[targetItem.second].empty(), OptimizerException, ""); assertThrow(!m_classPositions[targetItem.second].empty(), OptimizerException, "");
if (m_classPositions[targetItem.second].count(targetItem.first)) if (m_classPositions[targetItem.second].count(targetItem.first))
continue; continue;
SourceLocation location; SourceLocation sourceLocation;
if (m_expressionClasses.representative(targetItem.second).item) if (m_expressionClasses.representative(targetItem.second).item)
location = m_expressionClasses.representative(targetItem.second).item->getLocation(); sourceLocation = m_expressionClasses.representative(targetItem.second).item->location();
int position = classElementPosition(targetItem.second); int position = classElementPosition(targetItem.second);
if (position < targetItem.first) if (position < targetItem.first)
// it is already at its target, we need another copy // it is already at its target, we need another copy
appendDup(position, location); appendDup(position, sourceLocation);
else else
appendOrRemoveSwap(position, location); appendOrRemoveSwap(position, sourceLocation);
appendOrRemoveSwap(targetItem.first, location); appendOrRemoveSwap(targetItem.first, sourceLocation);
} }
// remove surplus elements // remove surplus elements
@ -263,7 +263,7 @@ void CSECodeGenerator::addDependencies(Id _c)
case Instruction::SHA3: case Instruction::SHA3:
{ {
Id length = expr.arguments.at(1); Id length = expr.arguments.at(1);
AssemblyItem offsetInstr(Instruction::SUB, expr.item->getLocation()); AssemblyItem offsetInstr(Instruction::SUB, expr.item->location());
Id offsetToStart = m_expressionClasses.find(offsetInstr, {slot, slotToLoadFrom}); Id offsetToStart = m_expressionClasses.find(offsetInstr, {slot, slotToLoadFrom});
u256 const* o = m_expressionClasses.knownConstant(offsetToStart); u256 const* o = m_expressionClasses.knownConstant(offsetToStart);
u256 const* l = m_expressionClasses.knownConstant(length); u256 const* l = m_expressionClasses.knownConstant(length);
@ -332,7 +332,7 @@ void CSECodeGenerator::generateClassElement(Id _c, bool _allowSequenced)
for (Id arg: boost::adaptors::reverse(arguments)) for (Id arg: boost::adaptors::reverse(arguments))
generateClassElement(arg); generateClassElement(arg);
SourceLocation const& location = expr.item->getLocation(); SourceLocation const& itemLocation = expr.item->location();
// The arguments are somewhere on the stack now, so it remains to move them at the correct place. // The arguments are somewhere on the stack now, so it remains to move them at the correct place.
// This is quite difficult as sometimes, the values also have to removed in this process // This is quite difficult as sometimes, the values also have to removed in this process
// (if canBeRemoved() returns true) and the two arguments can be equal. For now, this is // (if canBeRemoved() returns true) and the two arguments can be equal. For now, this is
@ -340,42 +340,42 @@ void CSECodeGenerator::generateClassElement(Id _c, bool _allowSequenced)
if (arguments.size() == 1) if (arguments.size() == 1)
{ {
if (canBeRemoved(arguments[0], _c)) if (canBeRemoved(arguments[0], _c))
appendOrRemoveSwap(classElementPosition(arguments[0]), location); appendOrRemoveSwap(classElementPosition(arguments[0]), itemLocation);
else else
appendDup(classElementPosition(arguments[0]), location); appendDup(classElementPosition(arguments[0]), itemLocation);
} }
else if (arguments.size() == 2) else if (arguments.size() == 2)
{ {
if (canBeRemoved(arguments[1], _c)) if (canBeRemoved(arguments[1], _c))
{ {
appendOrRemoveSwap(classElementPosition(arguments[1]), location); appendOrRemoveSwap(classElementPosition(arguments[1]), itemLocation);
if (arguments[0] == arguments[1]) if (arguments[0] == arguments[1])
appendDup(m_stackHeight, location); appendDup(m_stackHeight, itemLocation);
else if (canBeRemoved(arguments[0], _c)) else if (canBeRemoved(arguments[0], _c))
{ {
appendOrRemoveSwap(m_stackHeight - 1, location); appendOrRemoveSwap(m_stackHeight - 1, itemLocation);
appendOrRemoveSwap(classElementPosition(arguments[0]), location); appendOrRemoveSwap(classElementPosition(arguments[0]), itemLocation);
} }
else else
appendDup(classElementPosition(arguments[0]), location); appendDup(classElementPosition(arguments[0]), itemLocation);
} }
else else
{ {
if (arguments[0] == arguments[1]) if (arguments[0] == arguments[1])
{ {
appendDup(classElementPosition(arguments[0]), location); appendDup(classElementPosition(arguments[0]), itemLocation);
appendDup(m_stackHeight, location); appendDup(m_stackHeight, itemLocation);
} }
else if (canBeRemoved(arguments[0], _c)) else if (canBeRemoved(arguments[0], _c))
{ {
appendOrRemoveSwap(classElementPosition(arguments[0]), location); appendOrRemoveSwap(classElementPosition(arguments[0]), itemLocation);
appendDup(classElementPosition(arguments[1]), location); appendDup(classElementPosition(arguments[1]), itemLocation);
appendOrRemoveSwap(m_stackHeight - 1, location); appendOrRemoveSwap(m_stackHeight - 1, itemLocation);
} }
else else
{ {
appendDup(classElementPosition(arguments[1]), location); appendDup(classElementPosition(arguments[1]), itemLocation);
appendDup(classElementPosition(arguments[0]), location); appendDup(classElementPosition(arguments[0]), itemLocation);
} }
} }
} }
@ -392,7 +392,7 @@ void CSECodeGenerator::generateClassElement(Id _c, bool _allowSequenced)
!m_generatedItems.empty() && !m_generatedItems.empty() &&
m_generatedItems.back() == AssemblyItem(Instruction::SWAP1)) m_generatedItems.back() == AssemblyItem(Instruction::SWAP1))
// this will not append a swap but remove the one that is already there // this will not append a swap but remove the one that is already there
appendOrRemoveSwap(m_stackHeight - 1, location); appendOrRemoveSwap(m_stackHeight - 1, itemLocation);
for (size_t i = 0; i < arguments.size(); ++i) for (size_t i = 0; i < arguments.size(); ++i)
{ {
m_classPositions[m_stack[m_stackHeight - i]].erase(m_stackHeight - i); m_classPositions[m_stack[m_stackHeight - i]].erase(m_stackHeight - i);

View File

@ -356,7 +356,7 @@ ExpressionClasses::Id ExpressionClasses::tryToSimplify(Expression const& _expr,
//cout << "with rule " << rule.first.toString() << endl; //cout << "with rule " << rule.first.toString() << endl;
//ExpressionTemplate t(rule.second()); //ExpressionTemplate t(rule.second());
//cout << "to " << rule.second().toString() << endl; //cout << "to " << rule.second().toString() << endl;
return rebuildExpression(ExpressionTemplate(rule.second(), _expr.item->getLocation())); return rebuildExpression(ExpressionTemplate(rule.second(), _expr.item->location()));
} }
} }

View File

@ -107,39 +107,39 @@ KnownState::StoreOperation KnownState::feedItem(AssemblyItem const& _item, bool
m_stackHeight + 1, m_stackHeight + 1,
stackElement( stackElement(
m_stackHeight - int(instruction) + int(Instruction::DUP1), m_stackHeight - int(instruction) + int(Instruction::DUP1),
_item.getLocation() _item.location()
) )
); );
else if (SemanticInformation::isSwapInstruction(_item)) else if (SemanticInformation::isSwapInstruction(_item))
swapStackElements( swapStackElements(
m_stackHeight, m_stackHeight,
m_stackHeight - 1 - int(instruction) + int(Instruction::SWAP1), m_stackHeight - 1 - int(instruction) + int(Instruction::SWAP1),
_item.getLocation() _item.location()
); );
else if (instruction != Instruction::POP) else if (instruction != Instruction::POP)
{ {
vector<Id> arguments(info.args); vector<Id> arguments(info.args);
for (int i = 0; i < info.args; ++i) for (int i = 0; i < info.args; ++i)
arguments[i] = stackElement(m_stackHeight - i, _item.getLocation()); arguments[i] = stackElement(m_stackHeight - i, _item.location());
if (_item.instruction() == Instruction::SSTORE) if (_item.instruction() == Instruction::SSTORE)
op = storeInStorage(arguments[0], arguments[1], _item.getLocation()); op = storeInStorage(arguments[0], arguments[1], _item.location());
else if (_item.instruction() == Instruction::SLOAD) else if (_item.instruction() == Instruction::SLOAD)
setStackElement( setStackElement(
m_stackHeight + _item.deposit(), m_stackHeight + _item.deposit(),
loadFromStorage(arguments[0], _item.getLocation()) loadFromStorage(arguments[0], _item.location())
); );
else if (_item.instruction() == Instruction::MSTORE) else if (_item.instruction() == Instruction::MSTORE)
op = storeInMemory(arguments[0], arguments[1], _item.getLocation()); op = storeInMemory(arguments[0], arguments[1], _item.location());
else if (_item.instruction() == Instruction::MLOAD) else if (_item.instruction() == Instruction::MLOAD)
setStackElement( setStackElement(
m_stackHeight + _item.deposit(), m_stackHeight + _item.deposit(),
loadFromMemory(arguments[0], _item.getLocation()) loadFromMemory(arguments[0], _item.location())
); );
else if (_item.instruction() == Instruction::SHA3) else if (_item.instruction() == Instruction::SHA3)
setStackElement( setStackElement(
m_stackHeight + _item.deposit(), m_stackHeight + _item.deposit(),
applySha3(arguments.at(0), arguments.at(1), _item.getLocation()) applySha3(arguments.at(0), arguments.at(1), _item.location())
); );
else else
{ {