From 8d1d14c1b665dd6d2b3740f78334351eaf9e08d3 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 24 May 2014 11:01:08 +0200 Subject: [PATCH] seq and asm. --- libethereum/Instruction.cpp | 61 +++++++++++++++++++++++++++++-------- libethereum/Instruction.h | 1 + 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/libethereum/Instruction.cpp b/libethereum/Instruction.cpp index f6b9bfcae..4f23ba608 100644 --- a/libethereum/Instruction.cpp +++ b/libethereum/Instruction.cpp @@ -1163,7 +1163,7 @@ class CodeFragment friend class CodeLocation; public: - CodeFragment(sp::utree const& _t, CompileState const& _s = CompileState()); + CodeFragment(sp::utree const& _t, CompileState const& _s = CompileState(), bool _allowASM = false); bytes const& code() const { return m_code; } @@ -1234,14 +1234,18 @@ void CodeLocation::increase(unsigned _val) void CodeFragment::appendFragment(CodeFragment const& _f) { m_locs.reserve(m_locs.size() + _f.m_locs.size()); - for (auto i: _f.m_locs) - { - CodeLocation(this, i).increase((unsigned)m_code.size()); - m_locs.push_back(i + (unsigned)m_code.size()); - } m_code.reserve(m_code.size() + _f.m_code.size()); + + unsigned os = m_code.size(); for (auto i: _f.m_code) m_code.push_back(i); + + for (auto i: _f.m_locs) + { + CodeLocation(this, i + os).increase(os); + m_locs.push_back(i + os); + } + m_deposit += _f.m_deposit; } void CodeFragment::appendFragment(CodeFragment const& _f, unsigned _deposit) @@ -1301,7 +1305,7 @@ void debugOutAST(ostream& _out, sp::utree const& _this) } } -CodeFragment::CodeFragment(sp::utree const& _t, CompileState const& _s) +CodeFragment::CodeFragment(sp::utree const& _t, CompileState const& _s, bool _allowASM) { switch (_t.which()) { @@ -1322,7 +1326,22 @@ CodeFragment::CodeFragment(sp::utree const& _t, CompileState const& _s) } case sp::utree_type::symbol_type: { - error(); + if (_allowASM) + { + auto sr = _t.get, sp::utree_type::symbol_type>>(); + string s(sr.begin(), sr.end()); + boost::algorithm::to_upper(s); + if (c_instructions.count(s)) + { + auto it = c_instructions.find(s); + m_deposit = c_instructionInfo.at(it->second).ret - c_instructionInfo.at(it->second).args; + m_code.push_back((byte)it->second); + } + else + error(); + } + else + error(); break; } case sp::utree_type::any_type: @@ -1345,15 +1364,28 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompileState const& _ error(); else { + auto sr = _t.front().get, sp::utree_type::symbol_type>>(); + string s(sr.begin(), sr.end()); + boost::algorithm::to_upper(s); + + if (s == "ASM") + { + int c = 0; + for (auto const& i: _t) + if (c++) + appendFragment(CodeFragment(i, _s, true)); + return; + } + + std::map const c_arith = { { "+", Instruction::ADD }, { "-", Instruction::SUB }, { "*", Instruction::MUL }, { "/", Instruction::DIV }, { "%", Instruction::MOD }, { "&", Instruction::AND }, { "|", Instruction::OR }, { "^", Instruction::XOR } }; + std::map> const c_binary = { { "<", { Instruction::LT, false } }, { "<=", { Instruction::GT, true } }, { ">", { Instruction::GT, false } }, { ">=", { Instruction::LT, true } }, { "S<", { Instruction::SLT, false } }, { "S<=", { Instruction::SGT, true } }, { "S>", { Instruction::SGT, false } }, { "S>=", { Instruction::SLT, true } }, { "=", { Instruction::EQ, false } }, { "!=", { Instruction::EQ, true } } }; + std::map const c_unary = { { "!", Instruction::NOT } }; + vector code; int c = 0; for (auto const& i: _t) if (c++) code.push_back(CodeFragment(i, _s)); - - auto sr = _t.front().get, sp::utree_type::symbol_type>>(); - string s(sr.begin(), sr.end()); - boost::algorithm::to_upper(s); auto requireSize = [&](unsigned s) { if (code.size() != s) error(); }; auto requireMinSize = [&](unsigned s) { if (code.size() < s) error(); }; auto requireDeposit = [&](unsigned i, int s) { if (code[i].m_deposit != s) error(); }; @@ -1400,6 +1432,11 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompileState const& _ donePaths(); end.anchor(); } + else if (s == "SEQ") + { + for (auto const& i: code) + appendFragment(i, 0); + } } } diff --git a/libethereum/Instruction.h b/libethereum/Instruction.h index 5588970b9..e4cab4d91 100644 --- a/libethereum/Instruction.h +++ b/libethereum/Instruction.h @@ -160,6 +160,7 @@ class EmptyList: public CompilerException {}; class DataNotExecutable: public CompilerException {}; class IncorrectParameterCount: public CompilerException {}; class InvalidDeposit: public CompilerException {}; +class InvalidOpCode: public CompilerException {}; bytes compileLLL(std::string const& _s, std::vector* _errors); /// Append an appropriate PUSH instruction together with the literal value onto the given code.