Browse Source

Recursive LLL-copmiler.

cl-refactor
Gav Wood 11 years ago
parent
commit
21b15bfb1a
  1. 2
      alethzero/MainWin.cpp
  2. 2
      libethereum/Common.h
  3. 139
      libethereum/Instruction.cpp
  4. 4
      libethereum/Instruction.h
  5. 11
      libethereum/State.cpp

2
alethzero/MainWin.cpp

@ -372,7 +372,7 @@ void Main::on_destination_textChanged()
void Main::on_data_textChanged()
{
string code = ui->data->toPlainText().toStdString();
m_data = code[0] == '(' ? compileLisp(code, true) : assemble(code);
m_data = code[0] == '(' ? compileLisp(code, true) : assemble(code, true);
ui->code->setPlainText(QString::fromStdString(disassemble(m_data)));
updateFee();
}

2
libethereum/Common.h

@ -216,7 +216,7 @@ public:
char buf[24];
if (strftime(buf, 24, "%X", localtime(&rawTime)) == 0)
buf[0] = '\0'; // empty if case strftime fails
sstr << Id::name << " [ " << buf << " | " << *(t_logThreadName.m_name.get()) << (_term ? " ] " : "");
sstr << Id::name() << " [ " << buf << " | " << *(t_logThreadName.m_name.get()) << (_term ? " ] " : "");
}
}
~LogOutputStream() { if (Id::verbosity <= g_logVerbosity) g_logPost(sstr.str(), Id::name()); }

139
libethereum/Instruction.cpp

@ -25,45 +25,60 @@
using namespace std;
using namespace eth;
u256s eth::assemble(std::string const& _code)
u256s eth::assemble(std::string const& _code, bool _quiet)
{
u256s ret;
map<string, unsigned> known;
map<unsigned, string> req;
char const* d = _code.data();
char const* e = _code.data() + _code.size();
while (d != e)
{
// skip to next token
for (; d != e && !isalnum(*d) && *d != '_'; ++d) {}
for (; d != e && !isalnum(*d) && *d != '_' && *d != ':'; ++d) {}
if (d == e)
break;
char const* s = d;
for (; d != e && (isalnum(*d) || *d == '_'); ++d) {}
for (; d != e && (isalnum(*d) || *d == '_' || *d == ':'); ++d) {}
string t = string(s, d - s);
if (isdigit(t[0]))
ret.push_back(u256(t));
try
{
ret.push_back(u256(t));
}
catch (...)
{
cwarn << "Invalid numeric" << t;
}
else if (t.back() == ':')
known[t.substr(0, t.size() - 1)] = ret.size();
else
{
boost::algorithm::to_upper(t);
auto it = c_instructions.find(t);
auto it = c_instructions.find(boost::algorithm::to_upper_copy(t));
if (it != c_instructions.end())
ret.push_back((u256)it->second);
else
cwarn << "Unknown assembler token" << t;
{
req[ret.size()] = t;
ret.push_back(0);
}
}
}
for (auto i: req)
if (known.count(i.second))
ret[i.first] = known[i.second];
else
cwarn << "Unknown assembler token" << i.second << "at address" << i.first;
return ret;
}
u256s eth::compileLisp(std::string const& _code, bool _quiet)
static bool compileLispFragment(char const*& d, char const* e, bool _quiet, unsigned _off, u256s& o_code, vector<unsigned>& o_locs)
{
u256s ret;
vector<pair<Instruction, int>> inStack;
bool exec = false;
char const* d = _code.data();
char const* e = _code.data() + _code.size();
while (d != e)
{
// skip to next token
@ -74,59 +89,105 @@ u256s eth::compileLisp(std::string const& _code, bool _quiet)
switch (*d)
{
case '(':
inStack.push_back(make_pair(Instruction::STOP, 0));
exec = true;
++d;
break;
case ')':
++d;
if (inStack.size())
ret.push_back(inStack.back().first);
inStack.pop_back();
if (inStack.size())
inStack.back().second++;
break;
if (exec)
{
++d;
return true;
}
else
// unexpected - return false as we don't know what to do with it.
return false;
default:
{
char const* s = d;
for (; d != e && isalnum(*d); ++d) {}
for (; d != e && (isalnum(*d) || *d == '_'); ++d) {}
string t = string(s, d - s);
string t(s, d - s);
if (isdigit(t[0]))
if (inStack.size() && !inStack.back().second)
{
if (exec)
{
if (!_quiet)
cwarn << "Cannot execute numeric" << t;
cwarn << "Cannot execute numeric" << t;
}
else
{
ret.push_back(Instruction::PUSH);
ret.push_back(u256(t));
o_code.push_back(Instruction::PUSH);
try
{
o_code.push_back(u256(t));
}
catch (...)
{
cwarn << "Invalid numeric" << t;
}
}
}
else
{
boost::algorithm::to_upper(t);
auto it = c_instructions.find(t);
if (it != c_instructions.end())
if (t == "IF")
{
}
else
{
if (inStack.size())
auto it = c_instructions.find(t);
if (it != c_instructions.end())
{
if (!inStack.back().second)
inStack.back().first = it->second;
if (exec)
{
vector<pair<u256s, vector<unsigned>>> codes(1);
while (d != e && compileLispFragment(d, e, _quiet, o_code.size(), codes.back().first, codes.back().second))
codes.push_back(pair<u256s, vector<unsigned>>());
for (auto it = codes.rbegin(); it != codes.rend(); ++it)
{
for (auto i: it->second)
it->first[i] += o_code.size();
o_code.reserve(o_code.size() + it->first.size());
for (auto i: it->first)
o_code.push_back(i);
}
o_code.push_back((u256)it->second);
}
else
ret.push_back((u256)it->second);
inStack.back().second++;
{
o_code.push_back(Instruction::PUSH);
try
{
o_code.push_back((u256)it->second);
}
catch (...)
{
cwarn << "Invalid numeric" << t;
o_code.push_back(u256(t));
}
}
}
else if (!_quiet)
cwarn << "Instruction outside parens" << t;
cwarn << "Unknown assembler token" << t;
}
else if (!_quiet)
cwarn << "Unknown assembler token" << t;
}
if (!exec)
return true;
}
}
}
return ret;
return false;
}
u256s eth::compileLisp(std::string const& _code, bool _quiet)
{
char const* d = _code.data();
char const* e = _code.data() + _code.size();
u256s ret;
vector<unsigned> locs;
compileLispFragment(d, e, _quiet, 0, ret, locs);
return ret;
}
string eth::disassemble(u256s const& _mem)

4
libethereum/Instruction.h

@ -143,7 +143,7 @@ static const std::map<Instruction, InstructionInfo> c_instructionInfo =
{ Instruction::IND, { "IND", 0, 0, 1 } },
{ Instruction::EXTRO, { "EXTRO", 0, 2, 1 } },
{ Instruction::BALANCE, { "BALANCE", 0, 1, 1 } },
{ Instruction::MKTX, { "MKTX", 0, 4, 0 } },
{ Instruction::MKTX, { "MKTX", 0, -3, 0 } },
{ Instruction::SUICIDE, { "SUICIDE", 0, 1, 0} }
};
@ -202,7 +202,7 @@ static const std::map<std::string, Instruction> c_instructions =
{ "SUICIDE", Instruction::SUICIDE }
};
u256s assemble(std::string const& _code);
u256s assemble(std::string const& _code, bool _quiet = false);
std::string disassemble(u256s const& _mem);
u256s compileLisp(std::string const& _code, bool _quiet = false);

11
libethereum/State.cpp

@ -278,6 +278,10 @@ void State::resetCurrent()
m_currentBlock.parentHash = m_previousBlock.hash;
m_currentBlock.sha3Transactions = h256();
m_currentBlock.sha3Uncles = h256();
// Update timestamp according to clock.
m_currentBlock.timestamp = time(0);
m_state.setRoot(m_currentBlock.stateRoot);
}
@ -489,9 +493,6 @@ void State::commitToMine(BlockChain const& _bc)
MineInfo State::mine(uint _msTimeout)
{
// Update timestamp according to clock.
m_currentBlock.timestamp = time(0);
// Update difficulty according to timestamp.
m_currentBlock.difficulty = m_currentBlock.calculateDifficulty(m_previousBlock);
@ -927,7 +928,7 @@ void State::execute(Address _myAddress, Address _txSender, u256 _txValue, u256s
stack.push_back((u160)m_currentBlock.coinbaseAddress);
break;
case Instruction::BLK_TIMESTAMP:
stack.push_back(m_currentBlock.timestamp);
stack.push_back(m_previousBlock.timestamp);
break;
case Instruction::BLK_NUMBER:
stack.push_back(m_currentNumber);
@ -936,7 +937,7 @@ void State::execute(Address _myAddress, Address _txSender, u256 _txValue, u256s
stack.push_back(m_currentBlock.difficulty);
break;
case Instruction::BLK_NONCE:
stack.push_back(m_currentBlock.nonce);
stack.push_back(m_previousBlock.nonce);
break;
case Instruction::BASEFEE:
stack.push_back(m_fees.multiplier());

Loading…
Cancel
Save