Browse Source

Prevent optimizer from changing certain parts of the code.

cl-refactor
Christian 10 years ago
parent
commit
57d25f7a54
  1. 26
      libevmcore/Assembly.cpp
  2. 2
      libevmcore/Assembly.h
  3. 5
      libsolidity/Compiler.cpp

26
libevmcore/Assembly.cpp

@ -70,6 +70,8 @@ unsigned Assembly::bytesRequired() const
case PushData:
case PushSub:
ret += 1 + br;
case NoOptimizeBegin:
case NoOptimizeEnd:
default:;
}
if (dev::bytesRequired(ret) <= br)
@ -140,6 +142,12 @@ ostream& dev::eth::operator<<(ostream& _out, AssemblyItemsConstRef _i)
case PushSubSize:
_out << " PUSHss[" << hex << h256(i.data()).abridged() << "]";
break;
case NoOptimizeBegin:
_out << " DoNotOptimze{{";
break;
case NoOptimizeEnd:
_out << " DoNotOptimze}}";
break;
case UndefinedItem:
_out << " ???";
default:;
@ -177,6 +185,12 @@ ostream& Assembly::streamRLP(ostream& _out, string const& _prefix) const
case PushData:
_out << _prefix << " PUSH [" << hex << (unsigned)i.m_data << "]" << endl;
break;
case NoOptimizeBegin:
_out << _prefix << "DoNotOptimze{{" << endl;
break;
case NoOptimizeEnd:
_out << _prefix << "DoNotOptimze}}" << endl;
break;
default:;
}
@ -269,9 +283,14 @@ Assembly& Assembly::optimise(bool _enable)
for (unsigned count = 1; count > 0; total += count)
{
count = 0;
map<u256, unsigned> tags;
for (unsigned i = 0; i < m_items.size(); ++i)
{
if (m_items[i].type() == NoOptimizeBegin)
{
while (i < m_items.size() && m_items[i].type() != NoOptimizeEnd)
++i;
continue;
}
for (auto const& r: rules)
{
auto vr = AssemblyItemsConstRef(&m_items).cropped(i, r.first.size());
@ -297,6 +316,8 @@ Assembly& Assembly::optimise(bool _enable)
bool o = false;
while (m_items.size() > i + 1 && m_items[i + 1].type() != Tag)
{
if (m_items[i + 1].type() == NoOptimizeBegin)
break;
m_items.erase(m_items.begin() + i + 1);
o = true;
}
@ -308,6 +329,7 @@ Assembly& Assembly::optimise(bool _enable)
}
}
map<u256, unsigned> tags;
for (unsigned i = 0; i < m_items.size(); ++i)
if (m_items[i].type() == Tag)
tags.insert(make_pair(m_items[i].data(), i));
@ -416,6 +438,8 @@ bytes Assembly::assemble() const
tagPos[(unsigned)i.m_data] = ret.size();
ret.push_back((byte)Instruction::JUMPDEST);
break;
case NoOptimizeBegin:
case NoOptimizeEnd:
default:;
}

2
libevmcore/Assembly.h

@ -32,7 +32,7 @@ namespace dev
namespace eth
{
enum AssemblyItemType { UndefinedItem, Operation, Push, PushString, PushTag, PushSub, PushSubSize, Tag, PushData };
enum AssemblyItemType { UndefinedItem, Operation, Push, PushString, PushTag, PushSub, PushSubSize, Tag, PushData, NoOptimizeBegin, NoOptimizeEnd };
class Assembly;

5
libsolidity/Compiler.cpp

@ -89,10 +89,11 @@ void Compiler::appendFunctionSelector(vector<ASTPointer<FunctionDefinition>> con
eth::AssemblyItem jumpTableStart = m_context.pushNewTag();
m_context << eth::Instruction::ADD << eth::Instruction::JUMP;
// jump table @todo it could be that the optimizer destroys this
m_context << jumpTableStart;
// jump table, tell the optimizer not to remove the JUMPDESTs
m_context << eth::AssemblyItem(eth::NoOptimizeBegin) << jumpTableStart;
for (pair<string, pair<FunctionDefinition const*, eth::AssemblyItem>> const& f: publicFunctions)
m_context.appendJumpTo(f.second.second) << eth::Instruction::JUMPDEST;
m_context << eth::AssemblyItem(eth::NoOptimizeEnd);
m_context << returnTag << eth::Instruction::STOP;

Loading…
Cancel
Save