mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
applied changes from https://github.com/ethereum/cpp-ethereum/pull/2953
This commit is contained in:
parent
aea7e04bf4
commit
3ca3fb492d
28
Assembly.cpp
28
Assembly.cpp
@ -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)
|
||||
return "";
|
||||
@ -153,7 +153,7 @@ ostream& Assembly::streamAsm(ostream& _out, string const& _prefix, StringMap con
|
||||
default:
|
||||
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())
|
||||
@ -202,44 +202,44 @@ Json::Value Assembly::streamAsmJson(ostream& _out, StringMap const& _sourceCodes
|
||||
{
|
||||
case Operation:
|
||||
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;
|
||||
case Push:
|
||||
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;
|
||||
case PushString:
|
||||
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;
|
||||
case PushTag:
|
||||
if (i.data() == 0)
|
||||
collection.append(
|
||||
createJsonValue("PUSH [ErrorTag]", i.getLocation().start, i.getLocation().end, ""));
|
||||
createJsonValue("PUSH [ErrorTag]", i.location().start, i.location().end, ""));
|
||||
else
|
||||
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;
|
||||
case PushSub:
|
||||
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;
|
||||
case PushSubSize:
|
||||
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;
|
||||
case PushProgramSize:
|
||||
collection.append(
|
||||
createJsonValue("PUSHSIZE", i.getLocation().start, i.getLocation().end));
|
||||
createJsonValue("PUSHSIZE", i.location().start, i.location().end));
|
||||
break;
|
||||
case Tag:
|
||||
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(
|
||||
createJsonValue("JUMPDEST", i.getLocation().start, i.getLocation().end));
|
||||
createJsonValue("JUMPDEST", i.location().start, i.location().end));
|
||||
break;
|
||||
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;
|
||||
default:
|
||||
BOOST_THROW_EXCEPTION(InvalidOpcode());
|
||||
@ -282,7 +282,7 @@ AssemblyItem const& Assembly::append(AssemblyItem const& _i)
|
||||
{
|
||||
m_deposit += _i.deposit();
|
||||
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);
|
||||
return back();
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ public:
|
||||
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 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 newPushSubSize(u256 const& _subId) { return AssemblyItem(PushSubSize, _subId); }
|
||||
|
||||
@ -71,7 +71,7 @@ public:
|
||||
AssemblyItem errorTag() { return AssemblyItem(PushTag, 0); }
|
||||
|
||||
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(); }
|
||||
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
|
||||
) const;
|
||||
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()); }
|
||||
unsigned bytesRequired() const;
|
||||
|
||||
|
@ -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)); }
|
||||
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; }
|
||||
JumpType getJumpType() const { return m_jumpType; }
|
||||
|
@ -83,24 +83,24 @@ void CommonSubexpressionEliminator::optimizeBreakingItem()
|
||||
return;
|
||||
|
||||
ExpressionClasses& classes = m_state.expressionClasses();
|
||||
SourceLocation const& location = m_breakingItem->getLocation();
|
||||
SourceLocation const& itemLocation = m_breakingItem->location();
|
||||
if (*m_breakingItem == AssemblyItem(Instruction::JUMPI))
|
||||
{
|
||||
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))
|
||||
{
|
||||
feedItem(AssemblyItem(Instruction::SWAP1, location), true);
|
||||
feedItem(AssemblyItem(Instruction::POP, location), true);
|
||||
feedItem(AssemblyItem(Instruction::SWAP1, itemLocation), true);
|
||||
feedItem(AssemblyItem(Instruction::POP, itemLocation), true);
|
||||
|
||||
AssemblyItem item(Instruction::JUMP, location);
|
||||
AssemblyItem item(Instruction::JUMP, itemLocation);
|
||||
item.setJumpType(jumpType);
|
||||
m_breakingItem = classes.storeItem(item);
|
||||
}
|
||||
else if (classes.knownZero(condition))
|
||||
{
|
||||
AssemblyItem it(Instruction::POP, location);
|
||||
AssemblyItem it(Instruction::POP, itemLocation);
|
||||
feedItem(it, true);
|
||||
feedItem(it, true);
|
||||
m_breakingItem = nullptr;
|
||||
@ -108,12 +108,12 @@ void CommonSubexpressionEliminator::optimizeBreakingItem()
|
||||
}
|
||||
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))
|
||||
{
|
||||
feedItem(AssemblyItem(Instruction::POP, location), true);
|
||||
feedItem(AssemblyItem(Instruction::POP, location), true);
|
||||
AssemblyItem item(Instruction::STOP, location);
|
||||
feedItem(AssemblyItem(Instruction::POP, itemLocation), true);
|
||||
feedItem(AssemblyItem(Instruction::POP, itemLocation), true);
|
||||
AssemblyItem item(Instruction::STOP, itemLocation);
|
||||
m_breakingItem = classes.storeItem(item);
|
||||
}
|
||||
}
|
||||
@ -179,16 +179,16 @@ AssemblyItems CSECodeGenerator::generateCode(
|
||||
assertThrow(!m_classPositions[targetItem.second].empty(), OptimizerException, "");
|
||||
if (m_classPositions[targetItem.second].count(targetItem.first))
|
||||
continue;
|
||||
SourceLocation location;
|
||||
SourceLocation sourceLocation;
|
||||
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);
|
||||
if (position < targetItem.first)
|
||||
// it is already at its target, we need another copy
|
||||
appendDup(position, location);
|
||||
appendDup(position, sourceLocation);
|
||||
else
|
||||
appendOrRemoveSwap(position, location);
|
||||
appendOrRemoveSwap(targetItem.first, location);
|
||||
appendOrRemoveSwap(position, sourceLocation);
|
||||
appendOrRemoveSwap(targetItem.first, sourceLocation);
|
||||
}
|
||||
|
||||
// remove surplus elements
|
||||
@ -263,7 +263,7 @@ void CSECodeGenerator::addDependencies(Id _c)
|
||||
case Instruction::SHA3:
|
||||
{
|
||||
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});
|
||||
u256 const* o = m_expressionClasses.knownConstant(offsetToStart);
|
||||
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))
|
||||
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.
|
||||
// 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
|
||||
@ -340,42 +340,42 @@ void CSECodeGenerator::generateClassElement(Id _c, bool _allowSequenced)
|
||||
if (arguments.size() == 1)
|
||||
{
|
||||
if (canBeRemoved(arguments[0], _c))
|
||||
appendOrRemoveSwap(classElementPosition(arguments[0]), location);
|
||||
appendOrRemoveSwap(classElementPosition(arguments[0]), itemLocation);
|
||||
else
|
||||
appendDup(classElementPosition(arguments[0]), location);
|
||||
appendDup(classElementPosition(arguments[0]), itemLocation);
|
||||
}
|
||||
else if (arguments.size() == 2)
|
||||
{
|
||||
if (canBeRemoved(arguments[1], _c))
|
||||
{
|
||||
appendOrRemoveSwap(classElementPosition(arguments[1]), location);
|
||||
appendOrRemoveSwap(classElementPosition(arguments[1]), itemLocation);
|
||||
if (arguments[0] == arguments[1])
|
||||
appendDup(m_stackHeight, location);
|
||||
appendDup(m_stackHeight, itemLocation);
|
||||
else if (canBeRemoved(arguments[0], _c))
|
||||
{
|
||||
appendOrRemoveSwap(m_stackHeight - 1, location);
|
||||
appendOrRemoveSwap(classElementPosition(arguments[0]), location);
|
||||
appendOrRemoveSwap(m_stackHeight - 1, itemLocation);
|
||||
appendOrRemoveSwap(classElementPosition(arguments[0]), itemLocation);
|
||||
}
|
||||
else
|
||||
appendDup(classElementPosition(arguments[0]), location);
|
||||
appendDup(classElementPosition(arguments[0]), itemLocation);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (arguments[0] == arguments[1])
|
||||
{
|
||||
appendDup(classElementPosition(arguments[0]), location);
|
||||
appendDup(m_stackHeight, location);
|
||||
appendDup(classElementPosition(arguments[0]), itemLocation);
|
||||
appendDup(m_stackHeight, itemLocation);
|
||||
}
|
||||
else if (canBeRemoved(arguments[0], _c))
|
||||
{
|
||||
appendOrRemoveSwap(classElementPosition(arguments[0]), location);
|
||||
appendDup(classElementPosition(arguments[1]), location);
|
||||
appendOrRemoveSwap(m_stackHeight - 1, location);
|
||||
appendOrRemoveSwap(classElementPosition(arguments[0]), itemLocation);
|
||||
appendDup(classElementPosition(arguments[1]), itemLocation);
|
||||
appendOrRemoveSwap(m_stackHeight - 1, itemLocation);
|
||||
}
|
||||
else
|
||||
{
|
||||
appendDup(classElementPosition(arguments[1]), location);
|
||||
appendDup(classElementPosition(arguments[0]), location);
|
||||
appendDup(classElementPosition(arguments[1]), itemLocation);
|
||||
appendDup(classElementPosition(arguments[0]), itemLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -392,7 +392,7 @@ void CSECodeGenerator::generateClassElement(Id _c, bool _allowSequenced)
|
||||
!m_generatedItems.empty() &&
|
||||
m_generatedItems.back() == AssemblyItem(Instruction::SWAP1))
|
||||
// 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)
|
||||
{
|
||||
m_classPositions[m_stack[m_stackHeight - i]].erase(m_stackHeight - i);
|
||||
|
@ -356,7 +356,7 @@ ExpressionClasses::Id ExpressionClasses::tryToSimplify(Expression const& _expr,
|
||||
//cout << "with rule " << rule.first.toString() << endl;
|
||||
//ExpressionTemplate t(rule.second());
|
||||
//cout << "to " << rule.second().toString() << endl;
|
||||
return rebuildExpression(ExpressionTemplate(rule.second(), _expr.item->getLocation()));
|
||||
return rebuildExpression(ExpressionTemplate(rule.second(), _expr.item->location()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,39 +107,39 @@ KnownState::StoreOperation KnownState::feedItem(AssemblyItem const& _item, bool
|
||||
m_stackHeight + 1,
|
||||
stackElement(
|
||||
m_stackHeight - int(instruction) + int(Instruction::DUP1),
|
||||
_item.getLocation()
|
||||
_item.location()
|
||||
)
|
||||
);
|
||||
else if (SemanticInformation::isSwapInstruction(_item))
|
||||
swapStackElements(
|
||||
m_stackHeight,
|
||||
m_stackHeight - 1 - int(instruction) + int(Instruction::SWAP1),
|
||||
_item.getLocation()
|
||||
_item.location()
|
||||
);
|
||||
else if (instruction != Instruction::POP)
|
||||
{
|
||||
vector<Id> arguments(info.args);
|
||||
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)
|
||||
op = storeInStorage(arguments[0], arguments[1], _item.getLocation());
|
||||
op = storeInStorage(arguments[0], arguments[1], _item.location());
|
||||
else if (_item.instruction() == Instruction::SLOAD)
|
||||
setStackElement(
|
||||
m_stackHeight + _item.deposit(),
|
||||
loadFromStorage(arguments[0], _item.getLocation())
|
||||
loadFromStorage(arguments[0], _item.location())
|
||||
);
|
||||
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)
|
||||
setStackElement(
|
||||
m_stackHeight + _item.deposit(),
|
||||
loadFromMemory(arguments[0], _item.getLocation())
|
||||
loadFromMemory(arguments[0], _item.location())
|
||||
);
|
||||
else if (_item.instruction() == Instruction::SHA3)
|
||||
setStackElement(
|
||||
m_stackHeight + _item.deposit(),
|
||||
applySha3(arguments.at(0), arguments.at(1), _item.getLocation())
|
||||
applySha3(arguments.at(0), arguments.at(1), _item.location())
|
||||
);
|
||||
else
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user