Browse Source
Conflicts: alethzero/CMakeLists.txt cmake/EthDependenciesDeprecated.cmake libdevcrypto/CryptoPP.h libdevcrypto/EC.cpp third/CMakeLists.txtcl-refactor
sveneh
10 years ago
147 changed files with 10127 additions and 4247 deletions
@ -0,0 +1,36 @@ |
|||||
|
/*
|
||||
|
This file is part of cpp-ethereum. |
||||
|
|
||||
|
cpp-ethereum is free software: you can redistribute it and/or modify |
||||
|
it under the terms of the GNU General Public License as published by |
||||
|
the Free Software Foundation, either version 3 of the License, or |
||||
|
(at your option) any later version. |
||||
|
|
||||
|
cpp-ethereum is distributed in the hope that it will be useful, |
||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
GNU General Public License for more details. |
||||
|
|
||||
|
You should have received a copy of the GNU General Public License |
||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
*/ |
||||
|
/** @file OurWebThreeStubServer.h
|
||||
|
* @author Gav Wood <i@gavwood.com> |
||||
|
* @date 2014 |
||||
|
*/ |
||||
|
|
||||
|
#include "OurWebThreeStubServer.h" |
||||
|
using namespace std; |
||||
|
using namespace dev; |
||||
|
using namespace dev::eth; |
||||
|
|
||||
|
OurWebThreeStubServer::OurWebThreeStubServer(jsonrpc::AbstractServerConnector* _conn, dev::WebThreeDirect& _web3, std::vector<dev::KeyPair> const& _accounts): |
||||
|
WebThreeStubServer(_conn, _web3, _accounts) |
||||
|
{} |
||||
|
|
||||
|
std::string OurWebThreeStubServer::shh_newIdentity() |
||||
|
{ |
||||
|
dev::KeyPair kp = dev::KeyPair::create(); |
||||
|
emit onNewId(QString::fromStdString(toJS(kp.sec()))); |
||||
|
return toJS(kp.pub()); |
||||
|
} |
@ -0,0 +1,38 @@ |
|||||
|
/*
|
||||
|
This file is part of cpp-ethereum. |
||||
|
|
||||
|
cpp-ethereum is free software: you can redistribute it and/or modify |
||||
|
it under the terms of the GNU General Public License as published by |
||||
|
the Free Software Foundation, either version 3 of the License, or |
||||
|
(at your option) any later version. |
||||
|
|
||||
|
cpp-ethereum is distributed in the hope that it will be useful, |
||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
GNU General Public License for more details. |
||||
|
|
||||
|
You should have received a copy of the GNU General Public License |
||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
*/ |
||||
|
/** @file OurWebThreeStubServer.cpp
|
||||
|
* @author Gav Wood <i@gavwood.com> |
||||
|
* @date 2014 |
||||
|
*/ |
||||
|
|
||||
|
#include <QtCore/QObject> |
||||
|
#include <libdevcore/CommonJS.h> |
||||
|
#include <libdevcrypto/Common.h> |
||||
|
#include <libweb3jsonrpc/WebThreeStubServer.h> |
||||
|
|
||||
|
class OurWebThreeStubServer: public QObject, public WebThreeStubServer |
||||
|
{ |
||||
|
Q_OBJECT |
||||
|
|
||||
|
public: |
||||
|
OurWebThreeStubServer(jsonrpc::AbstractServerConnector* _conn, dev::WebThreeDirect& _web3, std::vector<dev::KeyPair> const& _accounts); |
||||
|
|
||||
|
virtual std::string shh_newIdentity() override; |
||||
|
|
||||
|
signals: |
||||
|
void onNewId(QString _s); |
||||
|
}; |
@ -0,0 +1,36 @@ |
|||||
|
/*
|
||||
|
This file is part of cpp-ethereum. |
||||
|
|
||||
|
cpp-ethereum is free software: you can redistribute it and/or modify |
||||
|
it under the terms of the GNU General Public License as published by |
||||
|
the Free Software Foundation, either version 3 of the License, or |
||||
|
(at your option) any later version. |
||||
|
|
||||
|
cpp-ethereum is distributed in the hope that it will be useful, |
||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
GNU General Public License for more details. |
||||
|
|
||||
|
You should have received a copy of the GNU General Public License |
||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
*/ |
||||
|
/** @file Exceptions.h
|
||||
|
* @author Christian <c@ethdev.com> |
||||
|
* @date 2014 |
||||
|
*/ |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include <libdevcore/Exceptions.h> |
||||
|
|
||||
|
namespace dev |
||||
|
{ |
||||
|
namespace eth |
||||
|
{ |
||||
|
|
||||
|
struct AssemblyException: virtual Exception {}; |
||||
|
struct InvalidDeposit: virtual AssemblyException {}; |
||||
|
struct InvalidOpcode: virtual AssemblyException {}; |
||||
|
|
||||
|
} |
||||
|
} |
@ -0,0 +1,337 @@ |
|||||
|
/*
|
||||
|
This file is part of cpp-ethereum. |
||||
|
|
||||
|
cpp-ethereum is free software: you can redistribute it and/or modify |
||||
|
it under the terms of the GNU General Public License as published by |
||||
|
the Free Software Foundation, either version 3 of the License, or |
||||
|
(at your option) any later version. |
||||
|
|
||||
|
cpp-ethereum is distributed in the hope that it will be useful, |
||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
GNU General Public License for more details. |
||||
|
|
||||
|
You should have received a copy of the GNU General Public License |
||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
*/ |
||||
|
/** @file Instruction.cpp
|
||||
|
* @author Gav Wood <i@gavwood.com> |
||||
|
* @date 2014 |
||||
|
*/ |
||||
|
|
||||
|
#include "Instruction.h" |
||||
|
|
||||
|
#include <libdevcore/Common.h> |
||||
|
#include <libdevcore/CommonIO.h> |
||||
|
#include <libdevcore/Log.h> |
||||
|
using namespace std; |
||||
|
using namespace dev; |
||||
|
using namespace dev::eth; |
||||
|
|
||||
|
const std::map<std::string, Instruction> dev::eth::c_instructions = |
||||
|
{ |
||||
|
{ "STOP", Instruction::STOP }, |
||||
|
{ "ADD", Instruction::ADD }, |
||||
|
{ "SUB", Instruction::SUB }, |
||||
|
{ "MUL", Instruction::MUL }, |
||||
|
{ "DIV", Instruction::DIV }, |
||||
|
{ "SDIV", Instruction::SDIV }, |
||||
|
{ "MOD", Instruction::MOD }, |
||||
|
{ "SMOD", Instruction::SMOD }, |
||||
|
{ "EXP", Instruction::EXP }, |
||||
|
{ "BNOT", Instruction::NOT }, |
||||
|
{ "LT", Instruction::LT }, |
||||
|
{ "GT", Instruction::GT }, |
||||
|
{ "SLT", Instruction::SLT }, |
||||
|
{ "SGT", Instruction::SGT }, |
||||
|
{ "EQ", Instruction::EQ }, |
||||
|
{ "NOT", Instruction::ISZERO }, |
||||
|
{ "AND", Instruction::AND }, |
||||
|
{ "OR", Instruction::OR }, |
||||
|
{ "XOR", Instruction::XOR }, |
||||
|
{ "BYTE", Instruction::BYTE }, |
||||
|
{ "ADDMOD", Instruction::ADDMOD }, |
||||
|
{ "MULMOD", Instruction::MULMOD }, |
||||
|
{ "SIGNEXTEND", Instruction::SIGNEXTEND }, |
||||
|
{ "SHA3", Instruction::SHA3 }, |
||||
|
{ "ADDRESS", Instruction::ADDRESS }, |
||||
|
{ "BALANCE", Instruction::BALANCE }, |
||||
|
{ "ORIGIN", Instruction::ORIGIN }, |
||||
|
{ "CALLER", Instruction::CALLER }, |
||||
|
{ "CALLVALUE", Instruction::CALLVALUE }, |
||||
|
{ "CALLDATALOAD", Instruction::CALLDATALOAD }, |
||||
|
{ "CALLDATASIZE", Instruction::CALLDATASIZE }, |
||||
|
{ "CALLDATACOPY", Instruction::CALLDATACOPY }, |
||||
|
{ "CODESIZE", Instruction::CODESIZE }, |
||||
|
{ "CODECOPY", Instruction::CODECOPY }, |
||||
|
{ "GASPRICE", Instruction::GASPRICE }, |
||||
|
{ "EXTCODESIZE", Instruction::EXTCODESIZE }, |
||||
|
{ "EXTCODECOPY", Instruction::EXTCODECOPY }, |
||||
|
{ "PREVHASH", Instruction::PREVHASH }, |
||||
|
{ "COINBASE", Instruction::COINBASE }, |
||||
|
{ "TIMESTAMP", Instruction::TIMESTAMP }, |
||||
|
{ "NUMBER", Instruction::NUMBER }, |
||||
|
{ "DIFFICULTY", Instruction::DIFFICULTY }, |
||||
|
{ "GASLIMIT", Instruction::GASLIMIT }, |
||||
|
{ "POP", Instruction::POP }, |
||||
|
{ "MLOAD", Instruction::MLOAD }, |
||||
|
{ "MSTORE", Instruction::MSTORE }, |
||||
|
{ "MSTORE8", Instruction::MSTORE8 }, |
||||
|
{ "SLOAD", Instruction::SLOAD }, |
||||
|
{ "SSTORE", Instruction::SSTORE }, |
||||
|
{ "JUMP", Instruction::JUMP }, |
||||
|
{ "JUMPI", Instruction::JUMPI }, |
||||
|
{ "PC", Instruction::PC }, |
||||
|
{ "MSIZE", Instruction::MSIZE }, |
||||
|
{ "GAS", Instruction::GAS }, |
||||
|
{ "JUMPDEST", Instruction::JUMPDEST }, |
||||
|
{ "PUSH1", Instruction::PUSH1 }, |
||||
|
{ "PUSH2", Instruction::PUSH2 }, |
||||
|
{ "PUSH3", Instruction::PUSH3 }, |
||||
|
{ "PUSH4", Instruction::PUSH4 }, |
||||
|
{ "PUSH5", Instruction::PUSH5 }, |
||||
|
{ "PUSH6", Instruction::PUSH6 }, |
||||
|
{ "PUSH7", Instruction::PUSH7 }, |
||||
|
{ "PUSH8", Instruction::PUSH8 }, |
||||
|
{ "PUSH9", Instruction::PUSH9 }, |
||||
|
{ "PUSH10", Instruction::PUSH10 }, |
||||
|
{ "PUSH11", Instruction::PUSH11 }, |
||||
|
{ "PUSH12", Instruction::PUSH12 }, |
||||
|
{ "PUSH13", Instruction::PUSH13 }, |
||||
|
{ "PUSH14", Instruction::PUSH14 }, |
||||
|
{ "PUSH15", Instruction::PUSH15 }, |
||||
|
{ "PUSH16", Instruction::PUSH16 }, |
||||
|
{ "PUSH17", Instruction::PUSH17 }, |
||||
|
{ "PUSH18", Instruction::PUSH18 }, |
||||
|
{ "PUSH19", Instruction::PUSH19 }, |
||||
|
{ "PUSH20", Instruction::PUSH20 }, |
||||
|
{ "PUSH21", Instruction::PUSH21 }, |
||||
|
{ "PUSH22", Instruction::PUSH22 }, |
||||
|
{ "PUSH23", Instruction::PUSH23 }, |
||||
|
{ "PUSH24", Instruction::PUSH24 }, |
||||
|
{ "PUSH25", Instruction::PUSH25 }, |
||||
|
{ "PUSH26", Instruction::PUSH26 }, |
||||
|
{ "PUSH27", Instruction::PUSH27 }, |
||||
|
{ "PUSH28", Instruction::PUSH28 }, |
||||
|
{ "PUSH29", Instruction::PUSH29 }, |
||||
|
{ "PUSH30", Instruction::PUSH30 }, |
||||
|
{ "PUSH31", Instruction::PUSH31 }, |
||||
|
{ "PUSH32", Instruction::PUSH32 }, |
||||
|
{ "DUP1", Instruction::DUP1 }, |
||||
|
{ "DUP2", Instruction::DUP2 }, |
||||
|
{ "DUP3", Instruction::DUP3 }, |
||||
|
{ "DUP4", Instruction::DUP4 }, |
||||
|
{ "DUP5", Instruction::DUP5 }, |
||||
|
{ "DUP6", Instruction::DUP6 }, |
||||
|
{ "DUP7", Instruction::DUP7 }, |
||||
|
{ "DUP8", Instruction::DUP8 }, |
||||
|
{ "DUP9", Instruction::DUP9 }, |
||||
|
{ "DUP10", Instruction::DUP10 }, |
||||
|
{ "DUP11", Instruction::DUP11 }, |
||||
|
{ "DUP12", Instruction::DUP12 }, |
||||
|
{ "DUP13", Instruction::DUP13 }, |
||||
|
{ "DUP14", Instruction::DUP14 }, |
||||
|
{ "DUP15", Instruction::DUP15 }, |
||||
|
{ "DUP16", Instruction::DUP16 }, |
||||
|
{ "SWAP1", Instruction::SWAP1 }, |
||||
|
{ "SWAP2", Instruction::SWAP2 }, |
||||
|
{ "SWAP3", Instruction::SWAP3 }, |
||||
|
{ "SWAP4", Instruction::SWAP4 }, |
||||
|
{ "SWAP5", Instruction::SWAP5 }, |
||||
|
{ "SWAP6", Instruction::SWAP6 }, |
||||
|
{ "SWAP7", Instruction::SWAP7 }, |
||||
|
{ "SWAP8", Instruction::SWAP8 }, |
||||
|
{ "SWAP9", Instruction::SWAP9 }, |
||||
|
{ "SWAP10", Instruction::SWAP10 }, |
||||
|
{ "SWAP11", Instruction::SWAP11 }, |
||||
|
{ "SWAP12", Instruction::SWAP12 }, |
||||
|
{ "SWAP13", Instruction::SWAP13 }, |
||||
|
{ "SWAP14", Instruction::SWAP14 }, |
||||
|
{ "SWAP15", Instruction::SWAP15 }, |
||||
|
{ "SWAP16", Instruction::SWAP16 }, |
||||
|
{ "LOG0", Instruction::LOG0 }, |
||||
|
{ "LOG1", Instruction::LOG1 }, |
||||
|
{ "LOG2", Instruction::LOG2 }, |
||||
|
{ "LOG3", Instruction::LOG3 }, |
||||
|
{ "LOG4", Instruction::LOG4 }, |
||||
|
{ "CREATE", Instruction::CREATE }, |
||||
|
{ "CALL", Instruction::CALL }, |
||||
|
{ "CALLCODE", Instruction::CALLCODE }, |
||||
|
{ "RETURN", Instruction::RETURN }, |
||||
|
{ "SUICIDE", Instruction::SUICIDE } |
||||
|
}; |
||||
|
|
||||
|
static const std::map<Instruction, InstructionInfo> c_instructionInfo = |
||||
|
{ // Add, Args, Ret, SideEffects
|
||||
|
{ Instruction::STOP, { "STOP", 0, 0, 0, true } }, |
||||
|
{ Instruction::ADD, { "ADD", 0, 2, 1, false } }, |
||||
|
{ Instruction::SUB, { "SUB", 0, 2, 1, false } }, |
||||
|
{ Instruction::MUL, { "MUL", 0, 2, 1, false } }, |
||||
|
{ Instruction::DIV, { "DIV", 0, 2, 1, false } }, |
||||
|
{ Instruction::SDIV, { "SDIV", 0, 2, 1, false } }, |
||||
|
{ Instruction::MOD, { "MOD", 0, 2, 1, false } }, |
||||
|
{ Instruction::SMOD, { "SMOD", 0, 2, 1, false } }, |
||||
|
{ Instruction::EXP, { "EXP", 0, 2, 1, false } }, |
||||
|
{ Instruction::NOT, { "NOT", 0, 1, 1, false } }, |
||||
|
{ Instruction::LT, { "LT", 0, 2, 1, false } }, |
||||
|
{ Instruction::GT, { "GT", 0, 2, 1, false } }, |
||||
|
{ Instruction::SLT, { "SLT", 0, 2, 1, false } }, |
||||
|
{ Instruction::SGT, { "SGT", 0, 2, 1, false } }, |
||||
|
{ Instruction::EQ, { "EQ", 0, 2, 1, false } }, |
||||
|
{ Instruction::ISZERO, { "ISZERO", 0, 1, 1, false } }, |
||||
|
{ Instruction::AND, { "AND", 0, 2, 1, false } }, |
||||
|
{ Instruction::OR, { "OR", 0, 2, 1, false } }, |
||||
|
{ Instruction::XOR, { "XOR", 0, 2, 1, false } }, |
||||
|
{ Instruction::BYTE, { "BYTE", 0, 2, 1, false } }, |
||||
|
{ Instruction::ADDMOD, { "ADDMOD", 0, 3, 1, false } }, |
||||
|
{ Instruction::MULMOD, { "MULMOD", 0, 3, 1, false } }, |
||||
|
{ Instruction::SIGNEXTEND, { "SIGNEXTEND", 0, 2, 1, false } }, |
||||
|
{ Instruction::SHA3, { "SHA3", 0, 2, 1, false } }, |
||||
|
{ Instruction::ADDRESS, { "ADDRESS", 0, 0, 1, false } }, |
||||
|
{ Instruction::BALANCE, { "BALANCE", 0, 1, 1, false } }, |
||||
|
{ Instruction::ORIGIN, { "ORIGIN", 0, 0, 1, false } }, |
||||
|
{ Instruction::CALLER, { "CALLER", 0, 0, 1, false } }, |
||||
|
{ Instruction::CALLVALUE, { "CALLVALUE", 0, 0, 1, false } }, |
||||
|
{ Instruction::CALLDATALOAD,{ "CALLDATALOAD", 0, 1, 1, false } }, |
||||
|
{ Instruction::CALLDATASIZE,{ "CALLDATASIZE", 0, 0, 1, false } }, |
||||
|
{ Instruction::CALLDATACOPY,{ "CALLDATACOPY", 0, 3, 0, true } }, |
||||
|
{ Instruction::CODESIZE, { "CODESIZE", 0, 0, 1, false } }, |
||||
|
{ Instruction::CODECOPY, { "CODECOPY", 0, 3, 0, true } }, |
||||
|
{ Instruction::GASPRICE, { "GASPRICE", 0, 0, 1, false } }, |
||||
|
{ Instruction::EXTCODESIZE, { "EXTCODESIZE", 0, 1, 1, false } }, |
||||
|
{ Instruction::EXTCODECOPY, { "EXTCODECOPY", 0, 4, 0, true } }, |
||||
|
{ Instruction::PREVHASH, { "PREVHASH", 0, 0, 1, false } }, |
||||
|
{ Instruction::COINBASE, { "COINBASE", 0, 0, 1, false } }, |
||||
|
{ Instruction::TIMESTAMP, { "TIMESTAMP", 0, 0, 1, false } }, |
||||
|
{ Instruction::NUMBER, { "NUMBER", 0, 0, 1, false } }, |
||||
|
{ Instruction::DIFFICULTY, { "DIFFICULTY", 0, 0, 1, false } }, |
||||
|
{ Instruction::GASLIMIT, { "GASLIMIT", 0, 0, 1, false } }, |
||||
|
{ Instruction::POP, { "POP", 0, 1, 0, false } }, |
||||
|
{ Instruction::MLOAD, { "MLOAD", 0, 1, 1, false } }, |
||||
|
{ Instruction::MSTORE, { "MSTORE", 0, 2, 0, true } }, |
||||
|
{ Instruction::MSTORE8, { "MSTORE8", 0, 2, 0, true } }, |
||||
|
{ Instruction::SLOAD, { "SLOAD", 0, 1, 1, false } }, |
||||
|
{ Instruction::SSTORE, { "SSTORE", 0, 2, 0, true } }, |
||||
|
{ Instruction::JUMP, { "JUMP", 0, 1, 0, true } }, |
||||
|
{ Instruction::JUMPI, { "JUMPI", 0, 2, 0, true } }, |
||||
|
{ Instruction::PC, { "PC", 0, 0, 1, false } }, |
||||
|
{ Instruction::MSIZE, { "MSIZE", 0, 0, 1, false } }, |
||||
|
{ Instruction::GAS, { "GAS", 0, 0, 1, false } }, |
||||
|
{ Instruction::JUMPDEST, { "JUMPDEST", 0, 1, 0, true } }, |
||||
|
{ Instruction::PUSH1, { "PUSH1", 1, 0, 1, false } }, |
||||
|
{ Instruction::PUSH2, { "PUSH2", 2, 0, 1, false } }, |
||||
|
{ Instruction::PUSH3, { "PUSH3", 3, 0, 1, false } }, |
||||
|
{ Instruction::PUSH4, { "PUSH4", 4, 0, 1, false } }, |
||||
|
{ Instruction::PUSH5, { "PUSH5", 5, 0, 1, false } }, |
||||
|
{ Instruction::PUSH6, { "PUSH6", 6, 0, 1, false } }, |
||||
|
{ Instruction::PUSH7, { "PUSH7", 7, 0, 1, false } }, |
||||
|
{ Instruction::PUSH8, { "PUSH8", 8, 0, 1, false } }, |
||||
|
{ Instruction::PUSH9, { "PUSH9", 9, 0, 1, false } }, |
||||
|
{ Instruction::PUSH10, { "PUSH10", 10, 0, 1, false } }, |
||||
|
{ Instruction::PUSH11, { "PUSH11", 11, 0, 1, false } }, |
||||
|
{ Instruction::PUSH12, { "PUSH12", 12, 0, 1, false } }, |
||||
|
{ Instruction::PUSH13, { "PUSH13", 13, 0, 1, false } }, |
||||
|
{ Instruction::PUSH14, { "PUSH14", 14, 0, 1, false } }, |
||||
|
{ Instruction::PUSH15, { "PUSH15", 15, 0, 1, false } }, |
||||
|
{ Instruction::PUSH16, { "PUSH16", 16, 0, 1, false } }, |
||||
|
{ Instruction::PUSH17, { "PUSH17", 17, 0, 1, false } }, |
||||
|
{ Instruction::PUSH18, { "PUSH18", 18, 0, 1, false } }, |
||||
|
{ Instruction::PUSH19, { "PUSH19", 19, 0, 1, false } }, |
||||
|
{ Instruction::PUSH20, { "PUSH20", 20, 0, 1, false } }, |
||||
|
{ Instruction::PUSH21, { "PUSH21", 21, 0, 1, false } }, |
||||
|
{ Instruction::PUSH22, { "PUSH22", 22, 0, 1, false } }, |
||||
|
{ Instruction::PUSH23, { "PUSH23", 23, 0, 1, false } }, |
||||
|
{ Instruction::PUSH24, { "PUSH24", 24, 0, 1, false } }, |
||||
|
{ Instruction::PUSH25, { "PUSH25", 25, 0, 1, false } }, |
||||
|
{ Instruction::PUSH26, { "PUSH26", 26, 0, 1, false } }, |
||||
|
{ Instruction::PUSH27, { "PUSH27", 27, 0, 1, false } }, |
||||
|
{ Instruction::PUSH28, { "PUSH28", 28, 0, 1, false } }, |
||||
|
{ Instruction::PUSH29, { "PUSH29", 29, 0, 1, false } }, |
||||
|
{ Instruction::PUSH30, { "PUSH30", 30, 0, 1, false } }, |
||||
|
{ Instruction::PUSH31, { "PUSH31", 31, 0, 1, false } }, |
||||
|
{ Instruction::PUSH32, { "PUSH32", 32, 0, 1, false } }, |
||||
|
{ Instruction::DUP1, { "DUP1", 0, 1, 2, false } }, |
||||
|
{ Instruction::DUP2, { "DUP2", 0, 2, 3, false } }, |
||||
|
{ Instruction::DUP3, { "DUP3", 0, 3, 4, false } }, |
||||
|
{ Instruction::DUP4, { "DUP4", 0, 4, 5, false } }, |
||||
|
{ Instruction::DUP5, { "DUP5", 0, 5, 6, false } }, |
||||
|
{ Instruction::DUP6, { "DUP6", 0, 6, 7, false } }, |
||||
|
{ Instruction::DUP7, { "DUP7", 0, 7, 8, false } }, |
||||
|
{ Instruction::DUP8, { "DUP8", 0, 8, 9, false } }, |
||||
|
{ Instruction::DUP9, { "DUP9", 0, 9, 10, false } }, |
||||
|
{ Instruction::DUP10, { "DUP10", 0, 10, 11, false } }, |
||||
|
{ Instruction::DUP11, { "DUP11", 0, 11, 12, false } }, |
||||
|
{ Instruction::DUP12, { "DUP12", 0, 12, 13, false } }, |
||||
|
{ Instruction::DUP13, { "DUP13", 0, 13, 14, false } }, |
||||
|
{ Instruction::DUP14, { "DUP14", 0, 14, 15, false } }, |
||||
|
{ Instruction::DUP15, { "DUP15", 0, 15, 16, false } }, |
||||
|
{ Instruction::DUP16, { "DUP16", 0, 16, 17, false } }, |
||||
|
{ Instruction::SWAP1, { "SWAP1", 0, 2, 2, false } }, |
||||
|
{ Instruction::SWAP2, { "SWAP2", 0, 3, 3, false } }, |
||||
|
{ Instruction::SWAP3, { "SWAP3", 0, 4, 4, false } }, |
||||
|
{ Instruction::SWAP4, { "SWAP4", 0, 5, 5, false } }, |
||||
|
{ Instruction::SWAP5, { "SWAP5", 0, 6, 6, false } }, |
||||
|
{ Instruction::SWAP6, { "SWAP6", 0, 7, 7, false } }, |
||||
|
{ Instruction::SWAP7, { "SWAP7", 0, 8, 8, false } }, |
||||
|
{ Instruction::SWAP8, { "SWAP8", 0, 9, 9, false } }, |
||||
|
{ Instruction::SWAP9, { "SWAP9", 0, 10, 10, false } }, |
||||
|
{ Instruction::SWAP10, { "SWAP10", 0, 11, 11, false } }, |
||||
|
{ Instruction::SWAP11, { "SWAP11", 0, 12, 12, false } }, |
||||
|
{ Instruction::SWAP12, { "SWAP12", 0, 13, 13, false } }, |
||||
|
{ Instruction::SWAP13, { "SWAP13", 0, 14, 14, false } }, |
||||
|
{ Instruction::SWAP14, { "SWAP14", 0, 15, 15, false } }, |
||||
|
{ Instruction::SWAP15, { "SWAP15", 0, 16, 16, false } }, |
||||
|
{ Instruction::SWAP16, { "SWAP16", 0, 17, 17, false } }, |
||||
|
{ Instruction::LOG0, { "LOG0", 0, 1, 0, true } }, |
||||
|
{ Instruction::LOG1, { "LOG1", 0, 2, 0, true } }, |
||||
|
{ Instruction::LOG2, { "LOG2", 0, 3, 0, true } }, |
||||
|
{ Instruction::LOG3, { "LOG3", 0, 4, 0, true } }, |
||||
|
{ Instruction::LOG4, { "LOG4", 0, 5, 0, true } }, |
||||
|
{ Instruction::CREATE, { "CREATE", 0, 3, 1, true } }, |
||||
|
{ Instruction::CALL, { "CALL", 0, 7, 1, true } }, |
||||
|
{ Instruction::CALLCODE, { "CALLCODE", 0, 7, 1, true } }, |
||||
|
{ Instruction::RETURN, { "RETURN", 0, 2, 0, true } }, |
||||
|
{ Instruction::SUICIDE, { "SUICIDE", 0, 1, 0, true } } |
||||
|
}; |
||||
|
|
||||
|
string dev::eth::disassemble(bytes const& _mem) |
||||
|
{ |
||||
|
stringstream ret; |
||||
|
unsigned numerics = 0; |
||||
|
for (auto it = _mem.begin(); it != _mem.end(); ++it) |
||||
|
{ |
||||
|
byte n = *it; |
||||
|
auto iit = c_instructionInfo.find((Instruction)n); |
||||
|
if (numerics || iit == c_instructionInfo.end() || (byte)iit->first != n) // not an instruction or expecting an argument...
|
||||
|
{ |
||||
|
if (numerics) |
||||
|
numerics--; |
||||
|
ret << "0x" << hex << (int)n << " "; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
auto const& ii = iit->second; |
||||
|
ret << ii.name << " "; |
||||
|
numerics = ii.additional; |
||||
|
} |
||||
|
} |
||||
|
return ret.str(); |
||||
|
} |
||||
|
|
||||
|
InstructionInfo dev::eth::instructionInfo(Instruction _inst) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
return c_instructionInfo.at(_inst); |
||||
|
} |
||||
|
catch (...) |
||||
|
{ |
||||
|
cwarn << "<INVALID_INSTRUCTION: " << toString((unsigned)_inst) << ">\n" << boost::current_exception_diagnostic_information(); |
||||
|
return InstructionInfo({"<INVALID_INSTRUCTION: " + toString((unsigned)_inst) + ">", 0, 0, 0, false}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
bool dev::eth::isValidInstruction(Instruction _inst) |
||||
|
{ |
||||
|
return !!c_instructionInfo.count(_inst); |
||||
|
} |
@ -1,337 +0,0 @@ |
|||||
/*
|
|
||||
This file is part of cpp-ethereum. |
|
||||
|
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify |
|
||||
it under the terms of the GNU General Public License as published by |
|
||||
the Free Software Foundation, either version 3 of the License, or |
|
||||
(at your option) any later version. |
|
||||
|
|
||||
cpp-ethereum is distributed in the hope that it will be useful, |
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||
GNU General Public License for more details. |
|
||||
|
|
||||
You should have received a copy of the GNU General Public License |
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|
||||
*/ |
|
||||
/** @file Instruction.cpp
|
|
||||
* @author Gav Wood <i@gavwood.com> |
|
||||
* @date 2014 |
|
||||
*/ |
|
||||
|
|
||||
#include "Instruction.h" |
|
||||
|
|
||||
#include <libdevcore/Common.h> |
|
||||
#include <libdevcore/CommonIO.h> |
|
||||
#include <libdevcore/Log.h> |
|
||||
using namespace std; |
|
||||
using namespace dev; |
|
||||
using namespace dev::eth; |
|
||||
|
|
||||
const std::map<std::string, Instruction> dev::eth::c_instructions = |
|
||||
{ |
|
||||
{ "STOP", Instruction::STOP }, |
|
||||
{ "ADD", Instruction::ADD }, |
|
||||
{ "SUB", Instruction::SUB }, |
|
||||
{ "MUL", Instruction::MUL }, |
|
||||
{ "DIV", Instruction::DIV }, |
|
||||
{ "SDIV", Instruction::SDIV }, |
|
||||
{ "MOD", Instruction::MOD }, |
|
||||
{ "SMOD", Instruction::SMOD }, |
|
||||
{ "EXP", Instruction::EXP }, |
|
||||
{ "BNOT", Instruction::NOT }, |
|
||||
{ "LT", Instruction::LT }, |
|
||||
{ "GT", Instruction::GT }, |
|
||||
{ "SLT", Instruction::SLT }, |
|
||||
{ "SGT", Instruction::SGT }, |
|
||||
{ "EQ", Instruction::EQ }, |
|
||||
{ "NOT", Instruction::ISZERO }, |
|
||||
{ "AND", Instruction::AND }, |
|
||||
{ "OR", Instruction::OR }, |
|
||||
{ "XOR", Instruction::XOR }, |
|
||||
{ "BYTE", Instruction::BYTE }, |
|
||||
{ "ADDMOD", Instruction::ADDMOD }, |
|
||||
{ "MULMOD", Instruction::MULMOD }, |
|
||||
{ "SIGNEXTEND", Instruction::SIGNEXTEND }, |
|
||||
{ "SHA3", Instruction::SHA3 }, |
|
||||
{ "ADDRESS", Instruction::ADDRESS }, |
|
||||
{ "BALANCE", Instruction::BALANCE }, |
|
||||
{ "ORIGIN", Instruction::ORIGIN }, |
|
||||
{ "CALLER", Instruction::CALLER }, |
|
||||
{ "CALLVALUE", Instruction::CALLVALUE }, |
|
||||
{ "CALLDATALOAD", Instruction::CALLDATALOAD }, |
|
||||
{ "CALLDATASIZE", Instruction::CALLDATASIZE }, |
|
||||
{ "CALLDATACOPY", Instruction::CALLDATACOPY }, |
|
||||
{ "CODESIZE", Instruction::CODESIZE }, |
|
||||
{ "CODECOPY", Instruction::CODECOPY }, |
|
||||
{ "GASPRICE", Instruction::GASPRICE }, |
|
||||
{ "EXTCODESIZE", Instruction::EXTCODESIZE }, |
|
||||
{ "EXTCODECOPY", Instruction::EXTCODECOPY }, |
|
||||
{ "PREVHASH", Instruction::PREVHASH }, |
|
||||
{ "COINBASE", Instruction::COINBASE }, |
|
||||
{ "TIMESTAMP", Instruction::TIMESTAMP }, |
|
||||
{ "NUMBER", Instruction::NUMBER }, |
|
||||
{ "DIFFICULTY", Instruction::DIFFICULTY }, |
|
||||
{ "GASLIMIT", Instruction::GASLIMIT }, |
|
||||
{ "POP", Instruction::POP }, |
|
||||
{ "MLOAD", Instruction::MLOAD }, |
|
||||
{ "MSTORE", Instruction::MSTORE }, |
|
||||
{ "MSTORE8", Instruction::MSTORE8 }, |
|
||||
{ "SLOAD", Instruction::SLOAD }, |
|
||||
{ "SSTORE", Instruction::SSTORE }, |
|
||||
{ "JUMP", Instruction::JUMP }, |
|
||||
{ "JUMPI", Instruction::JUMPI }, |
|
||||
{ "PC", Instruction::PC }, |
|
||||
{ "MSIZE", Instruction::MSIZE }, |
|
||||
{ "GAS", Instruction::GAS }, |
|
||||
{ "JUMPDEST", Instruction::JUMPDEST }, |
|
||||
{ "PUSH1", Instruction::PUSH1 }, |
|
||||
{ "PUSH2", Instruction::PUSH2 }, |
|
||||
{ "PUSH3", Instruction::PUSH3 }, |
|
||||
{ "PUSH4", Instruction::PUSH4 }, |
|
||||
{ "PUSH5", Instruction::PUSH5 }, |
|
||||
{ "PUSH6", Instruction::PUSH6 }, |
|
||||
{ "PUSH7", Instruction::PUSH7 }, |
|
||||
{ "PUSH8", Instruction::PUSH8 }, |
|
||||
{ "PUSH9", Instruction::PUSH9 }, |
|
||||
{ "PUSH10", Instruction::PUSH10 }, |
|
||||
{ "PUSH11", Instruction::PUSH11 }, |
|
||||
{ "PUSH12", Instruction::PUSH12 }, |
|
||||
{ "PUSH13", Instruction::PUSH13 }, |
|
||||
{ "PUSH14", Instruction::PUSH14 }, |
|
||||
{ "PUSH15", Instruction::PUSH15 }, |
|
||||
{ "PUSH16", Instruction::PUSH16 }, |
|
||||
{ "PUSH17", Instruction::PUSH17 }, |
|
||||
{ "PUSH18", Instruction::PUSH18 }, |
|
||||
{ "PUSH19", Instruction::PUSH19 }, |
|
||||
{ "PUSH20", Instruction::PUSH20 }, |
|
||||
{ "PUSH21", Instruction::PUSH21 }, |
|
||||
{ "PUSH22", Instruction::PUSH22 }, |
|
||||
{ "PUSH23", Instruction::PUSH23 }, |
|
||||
{ "PUSH24", Instruction::PUSH24 }, |
|
||||
{ "PUSH25", Instruction::PUSH25 }, |
|
||||
{ "PUSH26", Instruction::PUSH26 }, |
|
||||
{ "PUSH27", Instruction::PUSH27 }, |
|
||||
{ "PUSH28", Instruction::PUSH28 }, |
|
||||
{ "PUSH29", Instruction::PUSH29 }, |
|
||||
{ "PUSH30", Instruction::PUSH30 }, |
|
||||
{ "PUSH31", Instruction::PUSH31 }, |
|
||||
{ "PUSH32", Instruction::PUSH32 }, |
|
||||
{ "DUP1", Instruction::DUP1 }, |
|
||||
{ "DUP2", Instruction::DUP2 }, |
|
||||
{ "DUP3", Instruction::DUP3 }, |
|
||||
{ "DUP4", Instruction::DUP4 }, |
|
||||
{ "DUP5", Instruction::DUP5 }, |
|
||||
{ "DUP6", Instruction::DUP6 }, |
|
||||
{ "DUP7", Instruction::DUP7 }, |
|
||||
{ "DUP8", Instruction::DUP8 }, |
|
||||
{ "DUP9", Instruction::DUP9 }, |
|
||||
{ "DUP10", Instruction::DUP10 }, |
|
||||
{ "DUP11", Instruction::DUP11 }, |
|
||||
{ "DUP12", Instruction::DUP12 }, |
|
||||
{ "DUP13", Instruction::DUP13 }, |
|
||||
{ "DUP14", Instruction::DUP14 }, |
|
||||
{ "DUP15", Instruction::DUP15 }, |
|
||||
{ "DUP16", Instruction::DUP16 }, |
|
||||
{ "SWAP1", Instruction::SWAP1 }, |
|
||||
{ "SWAP2", Instruction::SWAP2 }, |
|
||||
{ "SWAP3", Instruction::SWAP3 }, |
|
||||
{ "SWAP4", Instruction::SWAP4 }, |
|
||||
{ "SWAP5", Instruction::SWAP5 }, |
|
||||
{ "SWAP6", Instruction::SWAP6 }, |
|
||||
{ "SWAP7", Instruction::SWAP7 }, |
|
||||
{ "SWAP8", Instruction::SWAP8 }, |
|
||||
{ "SWAP9", Instruction::SWAP9 }, |
|
||||
{ "SWAP10", Instruction::SWAP10 }, |
|
||||
{ "SWAP11", Instruction::SWAP11 }, |
|
||||
{ "SWAP12", Instruction::SWAP12 }, |
|
||||
{ "SWAP13", Instruction::SWAP13 }, |
|
||||
{ "SWAP14", Instruction::SWAP14 }, |
|
||||
{ "SWAP15", Instruction::SWAP15 }, |
|
||||
{ "SWAP16", Instruction::SWAP16 }, |
|
||||
{ "LOG0", Instruction::LOG0 }, |
|
||||
{ "LOG1", Instruction::LOG1 }, |
|
||||
{ "LOG2", Instruction::LOG2 }, |
|
||||
{ "LOG3", Instruction::LOG3 }, |
|
||||
{ "LOG4", Instruction::LOG4 }, |
|
||||
{ "CREATE", Instruction::CREATE }, |
|
||||
{ "CALL", Instruction::CALL }, |
|
||||
{ "CALLCODE", Instruction::CALLCODE }, |
|
||||
{ "RETURN", Instruction::RETURN }, |
|
||||
{ "SUICIDE", Instruction::SUICIDE } |
|
||||
}; |
|
||||
|
|
||||
static const std::map<Instruction, InstructionInfo> c_instructionInfo = |
|
||||
{ // Add, Args, Ret
|
|
||||
{ Instruction::STOP, { "STOP", 0, 0, 0 } }, |
|
||||
{ Instruction::ADD, { "ADD", 0, 2, 1 } }, |
|
||||
{ Instruction::SUB, { "SUB", 0, 2, 1 } }, |
|
||||
{ Instruction::MUL, { "MUL", 0, 2, 1 } }, |
|
||||
{ Instruction::DIV, { "DIV", 0, 2, 1 } }, |
|
||||
{ Instruction::SDIV, { "SDIV", 0, 2, 1 } }, |
|
||||
{ Instruction::MOD, { "MOD", 0, 2, 1 } }, |
|
||||
{ Instruction::SMOD, { "SMOD", 0, 2, 1 } }, |
|
||||
{ Instruction::EXP, { "EXP", 0, 2, 1 } }, |
|
||||
{ Instruction::NOT, { "BNOT", 0, 1, 1 } }, |
|
||||
{ Instruction::LT, { "LT", 0, 2, 1 } }, |
|
||||
{ Instruction::GT, { "GT", 0, 2, 1 } }, |
|
||||
{ Instruction::SLT, { "SLT", 0, 2, 1 } }, |
|
||||
{ Instruction::SGT, { "SGT", 0, 2, 1 } }, |
|
||||
{ Instruction::EQ, { "EQ", 0, 2, 1 } }, |
|
||||
{ Instruction::ISZERO, { "NOT", 0, 1, 1 } }, |
|
||||
{ Instruction::AND, { "AND", 0, 2, 1 } }, |
|
||||
{ Instruction::OR, { "OR", 0, 2, 1 } }, |
|
||||
{ Instruction::XOR, { "XOR", 0, 2, 1 } }, |
|
||||
{ Instruction::BYTE, { "BYTE", 0, 2, 1 } }, |
|
||||
{ Instruction::ADDMOD, { "ADDMOD", 0, 3, 1 } }, |
|
||||
{ Instruction::MULMOD, { "MULMOD", 0, 3, 1 } }, |
|
||||
{ Instruction::SIGNEXTEND, { "SIGNEXTEND", 0, 2, 1 } }, |
|
||||
{ Instruction::SHA3, { "SHA3", 0, 2, 1 } }, |
|
||||
{ Instruction::ADDRESS, { "ADDRESS", 0, 0, 1 } }, |
|
||||
{ Instruction::BALANCE, { "BALANCE", 0, 1, 1 } }, |
|
||||
{ Instruction::ORIGIN, { "ORIGIN", 0, 0, 1 } }, |
|
||||
{ Instruction::CALLER, { "CALLER", 0, 0, 1 } }, |
|
||||
{ Instruction::CALLVALUE, { "CALLVALUE", 0, 0, 1 } }, |
|
||||
{ Instruction::CALLDATALOAD,{ "CALLDATALOAD", 0, 1, 1 } }, |
|
||||
{ Instruction::CALLDATASIZE,{ "CALLDATASIZE", 0, 0, 1 } }, |
|
||||
{ Instruction::CALLDATACOPY,{ "CALLDATACOPY", 0, 3, 0 } }, |
|
||||
{ Instruction::CODESIZE, { "CODESIZE", 0, 0, 1 } }, |
|
||||
{ Instruction::CODECOPY, { "CODECOPY", 0, 3, 0 } }, |
|
||||
{ Instruction::GASPRICE, { "GASPRICE", 0, 0, 1 } }, |
|
||||
{ Instruction::EXTCODESIZE, { "EXTCODESIZE", 0, 1, 1 } }, |
|
||||
{ Instruction::EXTCODECOPY, { "EXTCODECOPY", 0, 4, 0 } }, |
|
||||
{ Instruction::PREVHASH, { "PREVHASH", 0, 0, 1 } }, |
|
||||
{ Instruction::COINBASE, { "COINBASE", 0, 0, 1 } }, |
|
||||
{ Instruction::TIMESTAMP, { "TIMESTAMP", 0, 0, 1 } }, |
|
||||
{ Instruction::NUMBER, { "NUMBER", 0, 0, 1 } }, |
|
||||
{ Instruction::DIFFICULTY, { "DIFFICULTY", 0, 0, 1 } }, |
|
||||
{ Instruction::GASLIMIT, { "GASLIMIT", 0, 0, 1 } }, |
|
||||
{ Instruction::POP, { "POP", 0, 1, 0 } }, |
|
||||
{ Instruction::MLOAD, { "MLOAD", 0, 1, 1 } }, |
|
||||
{ Instruction::MSTORE, { "MSTORE", 0, 2, 0 } }, |
|
||||
{ Instruction::MSTORE8, { "MSTORE8", 0, 2, 0 } }, |
|
||||
{ Instruction::SLOAD, { "SLOAD", 0, 1, 1 } }, |
|
||||
{ Instruction::SSTORE, { "SSTORE", 0, 2, 0 } }, |
|
||||
{ Instruction::JUMP, { "JUMP", 0, 1, 0 } }, |
|
||||
{ Instruction::JUMPI, { "JUMPI", 0, 2, 0 } }, |
|
||||
{ Instruction::PC, { "PC", 0, 0, 1 } }, |
|
||||
{ Instruction::MSIZE, { "MSIZE", 0, 0, 1 } }, |
|
||||
{ Instruction::GAS, { "GAS", 0, 0, 1 } }, |
|
||||
{ Instruction::JUMPDEST, { "JUMPDEST", 0, 1, 0 } }, |
|
||||
{ Instruction::PUSH1, { "PUSH1", 1, 0, 1 } }, |
|
||||
{ Instruction::PUSH2, { "PUSH2", 2, 0, 1 } }, |
|
||||
{ Instruction::PUSH3, { "PUSH3", 3, 0, 1 } }, |
|
||||
{ Instruction::PUSH4, { "PUSH4", 4, 0, 1 } }, |
|
||||
{ Instruction::PUSH5, { "PUSH5", 5, 0, 1 } }, |
|
||||
{ Instruction::PUSH6, { "PUSH6", 6, 0, 1 } }, |
|
||||
{ Instruction::PUSH7, { "PUSH7", 7, 0, 1 } }, |
|
||||
{ Instruction::PUSH8, { "PUSH8", 8, 0, 1 } }, |
|
||||
{ Instruction::PUSH9, { "PUSH9", 9, 0, 1 } }, |
|
||||
{ Instruction::PUSH10, { "PUSH10", 10, 0, 1 } }, |
|
||||
{ Instruction::PUSH11, { "PUSH11", 11, 0, 1 } }, |
|
||||
{ Instruction::PUSH12, { "PUSH12", 12, 0, 1 } }, |
|
||||
{ Instruction::PUSH13, { "PUSH13", 13, 0, 1 } }, |
|
||||
{ Instruction::PUSH14, { "PUSH14", 14, 0, 1 } }, |
|
||||
{ Instruction::PUSH15, { "PUSH15", 15, 0, 1 } }, |
|
||||
{ Instruction::PUSH16, { "PUSH16", 16, 0, 1 } }, |
|
||||
{ Instruction::PUSH17, { "PUSH17", 17, 0, 1 } }, |
|
||||
{ Instruction::PUSH18, { "PUSH18", 18, 0, 1 } }, |
|
||||
{ Instruction::PUSH19, { "PUSH19", 19, 0, 1 } }, |
|
||||
{ Instruction::PUSH20, { "PUSH20", 20, 0, 1 } }, |
|
||||
{ Instruction::PUSH21, { "PUSH21", 21, 0, 1 } }, |
|
||||
{ Instruction::PUSH22, { "PUSH22", 22, 0, 1 } }, |
|
||||
{ Instruction::PUSH23, { "PUSH23", 23, 0, 1 } }, |
|
||||
{ Instruction::PUSH24, { "PUSH24", 24, 0, 1 } }, |
|
||||
{ Instruction::PUSH25, { "PUSH25", 25, 0, 1 } }, |
|
||||
{ Instruction::PUSH26, { "PUSH26", 26, 0, 1 } }, |
|
||||
{ Instruction::PUSH27, { "PUSH27", 27, 0, 1 } }, |
|
||||
{ Instruction::PUSH28, { "PUSH28", 28, 0, 1 } }, |
|
||||
{ Instruction::PUSH29, { "PUSH29", 29, 0, 1 } }, |
|
||||
{ Instruction::PUSH30, { "PUSH30", 30, 0, 1 } }, |
|
||||
{ Instruction::PUSH31, { "PUSH31", 31, 0, 1 } }, |
|
||||
{ Instruction::PUSH32, { "PUSH32", 32, 0, 1 } }, |
|
||||
{ Instruction::DUP1, { "DUP1", 0, 1, 2 } }, |
|
||||
{ Instruction::DUP2, { "DUP2", 0, 2, 3 } }, |
|
||||
{ Instruction::DUP3, { "DUP3", 0, 3, 4 } }, |
|
||||
{ Instruction::DUP4, { "DUP4", 0, 4, 5 } }, |
|
||||
{ Instruction::DUP5, { "DUP5", 0, 5, 6 } }, |
|
||||
{ Instruction::DUP6, { "DUP6", 0, 6, 7 } }, |
|
||||
{ Instruction::DUP7, { "DUP7", 0, 7, 8 } }, |
|
||||
{ Instruction::DUP8, { "DUP8", 0, 8, 9 } }, |
|
||||
{ Instruction::DUP9, { "DUP9", 0, 9, 10 } }, |
|
||||
{ Instruction::DUP10, { "DUP10", 0, 10, 11 } }, |
|
||||
{ Instruction::DUP11, { "DUP11", 0, 11, 12 } }, |
|
||||
{ Instruction::DUP12, { "DUP12", 0, 12, 13 } }, |
|
||||
{ Instruction::DUP13, { "DUP13", 0, 13, 14 } }, |
|
||||
{ Instruction::DUP14, { "DUP14", 0, 14, 15 } }, |
|
||||
{ Instruction::DUP15, { "DUP15", 0, 15, 16 } }, |
|
||||
{ Instruction::DUP16, { "DUP16", 0, 16, 17 } }, |
|
||||
{ Instruction::SWAP1, { "SWAP1", 0, 2, 2 } }, |
|
||||
{ Instruction::SWAP2, { "SWAP2", 0, 3, 3 } }, |
|
||||
{ Instruction::SWAP3, { "SWAP3", 0, 4, 4 } }, |
|
||||
{ Instruction::SWAP4, { "SWAP4", 0, 5, 5 } }, |
|
||||
{ Instruction::SWAP5, { "SWAP5", 0, 6, 6 } }, |
|
||||
{ Instruction::SWAP6, { "SWAP6", 0, 7, 7 } }, |
|
||||
{ Instruction::SWAP7, { "SWAP7", 0, 8, 8 } }, |
|
||||
{ Instruction::SWAP8, { "SWAP8", 0, 9, 9 } }, |
|
||||
{ Instruction::SWAP9, { "SWAP9", 0, 10, 10 } }, |
|
||||
{ Instruction::SWAP10, { "SWAP10", 0, 11, 11 } }, |
|
||||
{ Instruction::SWAP11, { "SWAP11", 0, 12, 12 } }, |
|
||||
{ Instruction::SWAP12, { "SWAP12", 0, 13, 13 } }, |
|
||||
{ Instruction::SWAP13, { "SWAP13", 0, 14, 14 } }, |
|
||||
{ Instruction::SWAP14, { "SWAP14", 0, 15, 15 } }, |
|
||||
{ Instruction::SWAP15, { "SWAP15", 0, 16, 16 } }, |
|
||||
{ Instruction::SWAP16, { "SWAP16", 0, 17, 17 } }, |
|
||||
{ Instruction::LOG0, { "LOG0", 0, 1, 0 } }, |
|
||||
{ Instruction::LOG1, { "LOG1", 0, 2, 0 } }, |
|
||||
{ Instruction::LOG2, { "LOG2", 0, 3, 0 } }, |
|
||||
{ Instruction::LOG3, { "LOG3", 0, 4, 0 } }, |
|
||||
{ Instruction::LOG4, { "LOG4", 0, 5, 0 } }, |
|
||||
{ Instruction::CREATE, { "CREATE", 0, 3, 1 } }, |
|
||||
{ Instruction::CALL, { "CALL", 0, 7, 1 } }, |
|
||||
{ Instruction::CALLCODE, { "CALLCODE", 0, 7, 1 } }, |
|
||||
{ Instruction::RETURN, { "RETURN", 0, 2, 0 } }, |
|
||||
{ Instruction::SUICIDE, { "SUICIDE", 0, 1, 0} } |
|
||||
}; |
|
||||
|
|
||||
string dev::eth::disassemble(bytes const& _mem) |
|
||||
{ |
|
||||
stringstream ret; |
|
||||
unsigned numerics = 0; |
|
||||
for (auto it = _mem.begin(); it != _mem.end(); ++it) |
|
||||
{ |
|
||||
byte n = *it; |
|
||||
auto iit = c_instructionInfo.find((Instruction)n); |
|
||||
if (numerics || iit == c_instructionInfo.end() || (byte)iit->first != n) // not an instruction or expecting an argument...
|
|
||||
{ |
|
||||
if (numerics) |
|
||||
numerics--; |
|
||||
ret << "0x" << hex << (int)n << " "; |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
auto const& ii = iit->second; |
|
||||
ret << ii.name << " "; |
|
||||
numerics = ii.additional; |
|
||||
} |
|
||||
} |
|
||||
return ret.str(); |
|
||||
} |
|
||||
|
|
||||
InstructionInfo dev::eth::instructionInfo(Instruction _inst) |
|
||||
{ |
|
||||
try |
|
||||
{ |
|
||||
return c_instructionInfo.at(_inst); |
|
||||
} |
|
||||
catch (...) |
|
||||
{ |
|
||||
cwarn << "<INVALID_INSTRUCTION: " << toString((unsigned)_inst) << ">\n" << boost::current_exception_diagnostic_information(); |
|
||||
return InstructionInfo({"<INVALID_INSTRUCTION: " + toString((unsigned)_inst) + ">", 0, 0, 0}); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
bool dev::eth::isValidInstruction(Instruction _inst) |
|
||||
{ |
|
||||
return !!c_instructionInfo.count(_inst); |
|
||||
} |
|
File diff suppressed because it is too large
@ -0,0 +1,87 @@ |
|||||
|
/*
|
||||
|
This file is part of cpp-ethereum. |
||||
|
|
||||
|
cpp-ethereum is free software: you can redistribute it and/or modify |
||||
|
it under the terms of the GNU General Public License as published by |
||||
|
the Free Software Foundation, either version 3 of the License, or |
||||
|
(at your option) any later version. |
||||
|
|
||||
|
cpp-ethereum is distributed in the hope that it will be useful, |
||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
GNU General Public License for more details. |
||||
|
|
||||
|
You should have received a copy of the GNU General Public License |
||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
*/ |
||||
|
/**
|
||||
|
* @author Christian <c@ethdev.com> |
||||
|
* @date 2014 |
||||
|
* Utilities for the solidity compiler. |
||||
|
*/ |
||||
|
|
||||
|
#include <utility> |
||||
|
#include <numeric> |
||||
|
#include <libsolidity/AST.h> |
||||
|
#include <libsolidity/Compiler.h> |
||||
|
|
||||
|
using namespace std; |
||||
|
|
||||
|
namespace dev { |
||||
|
namespace solidity { |
||||
|
|
||||
|
void CompilerContext::addStateVariable(VariableDeclaration const& _declaration) |
||||
|
{ |
||||
|
m_stateVariables[&_declaration] = m_stateVariablesSize; |
||||
|
m_stateVariablesSize += _declaration.getType()->getStorageSize(); |
||||
|
} |
||||
|
|
||||
|
void CompilerContext::initializeLocalVariables(unsigned _numVariables) |
||||
|
{ |
||||
|
if (_numVariables > 0) |
||||
|
{ |
||||
|
*this << u256(0); |
||||
|
for (unsigned i = 1; i < _numVariables; ++i) |
||||
|
*this << eth::Instruction::DUP1; |
||||
|
m_asm.adjustDeposit(-_numVariables); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
bool CompilerContext::isLocalVariable(Declaration const* _declaration) const |
||||
|
{ |
||||
|
return std::find(m_localVariables.begin(), m_localVariables.end(), _declaration) != m_localVariables.end(); |
||||
|
} |
||||
|
|
||||
|
eth::AssemblyItem CompilerContext::getFunctionEntryLabel(FunctionDefinition const& _function) const |
||||
|
{ |
||||
|
auto res = m_functionEntryLabels.find(&_function); |
||||
|
if (asserts(res != m_functionEntryLabels.end())) |
||||
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Function entry label not found.")); |
||||
|
return res->second.tag(); |
||||
|
} |
||||
|
|
||||
|
unsigned CompilerContext::getBaseStackOffsetOfVariable(Declaration const& _declaration) const |
||||
|
{ |
||||
|
auto res = find(begin(m_localVariables), end(m_localVariables), &_declaration); |
||||
|
if (asserts(res != m_localVariables.end())) |
||||
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Variable not found on stack.")); |
||||
|
return unsigned(end(m_localVariables) - res - 1); |
||||
|
} |
||||
|
|
||||
|
unsigned CompilerContext::baseToCurrentStackOffset(unsigned _baseOffset) const |
||||
|
{ |
||||
|
return _baseOffset + m_asm.deposit(); |
||||
|
} |
||||
|
|
||||
|
u256 CompilerContext::getStorageLocationOfVariable(const Declaration& _declaration) const |
||||
|
{ |
||||
|
auto it = m_stateVariables.find(&_declaration); |
||||
|
if (it == m_stateVariables.end()) |
||||
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Variable not found in storage.")); |
||||
|
return it->second; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
||||
|
} |
@ -0,0 +1,102 @@ |
|||||
|
/*
|
||||
|
This file is part of cpp-ethereum. |
||||
|
|
||||
|
cpp-ethereum is free software: you can redistribute it and/or modify |
||||
|
it under the terms of the GNU General Public License as published by |
||||
|
the Free Software Foundation, either version 3 of the License, or |
||||
|
(at your option) any later version. |
||||
|
|
||||
|
cpp-ethereum is distributed in the hope that it will be useful, |
||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
GNU General Public License for more details. |
||||
|
|
||||
|
You should have received a copy of the GNU General Public License |
||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
*/ |
||||
|
/**
|
||||
|
* @author Christian <c@ethdev.com> |
||||
|
* @date 2014 |
||||
|
* Utilities for the solidity compiler. |
||||
|
*/ |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include <ostream> |
||||
|
#include <libevmcore/Instruction.h> |
||||
|
#include <libevmcore/Assembly.h> |
||||
|
#include <libsolidity/Types.h> |
||||
|
|
||||
|
namespace dev { |
||||
|
namespace solidity { |
||||
|
|
||||
|
|
||||
|
/**
|
||||
|
* Context to be shared by all units that compile the same contract. |
||||
|
* It stores the generated bytecode and the position of identifiers in memory and on the stack. |
||||
|
*/ |
||||
|
class CompilerContext |
||||
|
{ |
||||
|
public: |
||||
|
CompilerContext(): m_stateVariablesSize(0) {} |
||||
|
|
||||
|
void addStateVariable(VariableDeclaration const& _declaration); |
||||
|
void startNewFunction() { m_localVariables.clear(); m_asm.setDeposit(0); } |
||||
|
void initializeLocalVariables(unsigned _numVariables); |
||||
|
void addVariable(VariableDeclaration const& _declaration) { m_localVariables.push_back(&_declaration); } |
||||
|
void addFunction(FunctionDefinition const& _function) { m_functionEntryLabels.insert(std::make_pair(&_function, m_asm.newTag())); } |
||||
|
|
||||
|
void adjustStackOffset(int _adjustment) { m_asm.adjustDeposit(_adjustment); } |
||||
|
|
||||
|
bool isFunctionDefinition(Declaration const* _declaration) const { return m_functionEntryLabels.count(_declaration); } |
||||
|
bool isLocalVariable(Declaration const* _declaration) const; |
||||
|
bool isStateVariable(Declaration const* _declaration) const { return m_stateVariables.count(_declaration); } |
||||
|
|
||||
|
eth::AssemblyItem getFunctionEntryLabel(FunctionDefinition const& _function) const; |
||||
|
/// Returns the distance of the given local variable from the top of the local variable stack.
|
||||
|
unsigned getBaseStackOffsetOfVariable(Declaration const& _declaration) const; |
||||
|
/// If supplied by a value returned by @ref getBaseStackOffsetOfVariable(variable), returns
|
||||
|
/// the distance of that variable from the current top of the stack.
|
||||
|
unsigned baseToCurrentStackOffset(unsigned _baseOffset) const; |
||||
|
u256 getStorageLocationOfVariable(Declaration const& _declaration) const; |
||||
|
|
||||
|
/// Appends a JUMPI instruction to a new tag and @returns the tag
|
||||
|
eth::AssemblyItem appendConditionalJump() { return m_asm.appendJumpI().tag(); } |
||||
|
/// Appends a JUMPI instruction to @a _tag
|
||||
|
CompilerContext& appendConditionalJumpTo(eth::AssemblyItem const& _tag) { m_asm.appendJumpI(_tag); return *this; } |
||||
|
/// Appends a JUMP to a new tag and @returns the tag
|
||||
|
eth::AssemblyItem appendJump() { return m_asm.appendJump().tag(); } |
||||
|
/// Appends a JUMP to a specific tag
|
||||
|
CompilerContext& appendJumpTo(eth::AssemblyItem const& _tag) { m_asm.appendJump(_tag); return *this; } |
||||
|
/// Appends pushing of a new tag and @returns the new tag.
|
||||
|
eth::AssemblyItem pushNewTag() { return m_asm.append(m_asm.newPushTag()).tag(); } |
||||
|
/// @returns a new tag without pushing any opcodes or data
|
||||
|
eth::AssemblyItem newTag() { return m_asm.newTag(); } |
||||
|
/// Adds a subroutine to the code (in the data section) and pushes its size (via a tag)
|
||||
|
/// on the stack. @returns the assembly item corresponding to the pushed subroutine, i.e. its offset.
|
||||
|
eth::AssemblyItem addSubroutine(eth::Assembly const& _assembly) { return m_asm.appendSubSize(_assembly); } |
||||
|
|
||||
|
/// Append elements to the current instruction list and adjust @a m_stackOffset.
|
||||
|
CompilerContext& operator<<(eth::AssemblyItem const& _item) { m_asm.append(_item); return *this; } |
||||
|
CompilerContext& operator<<(eth::Instruction _instruction) { m_asm.append(_instruction); return *this; } |
||||
|
CompilerContext& operator<<(u256 const& _value) { m_asm.append(_value); return *this; } |
||||
|
CompilerContext& operator<<(bytes const& _data) { m_asm.append(_data); return *this; } |
||||
|
|
||||
|
eth::Assembly const& getAssembly() const { return m_asm; } |
||||
|
void streamAssembly(std::ostream& _stream) const { _stream << m_asm; } |
||||
|
bytes getAssembledBytecode(bool _optimize = false) { return m_asm.optimise(_optimize).assemble(); } |
||||
|
private: |
||||
|
eth::Assembly m_asm; |
||||
|
|
||||
|
/// Size of the state variables, offset of next variable to be added.
|
||||
|
u256 m_stateVariablesSize; |
||||
|
/// Storage offsets of state variables
|
||||
|
std::map<Declaration const*, u256> m_stateVariables; |
||||
|
/// Offsets of local variables on the stack.
|
||||
|
std::vector<Declaration const*> m_localVariables; |
||||
|
/// Labels pointing to the entry points of funcitons.
|
||||
|
std::map<Declaration const*, eth::AssemblyItem> m_functionEntryLabels; |
||||
|
}; |
||||
|
|
||||
|
} |
||||
|
} |
@ -0,0 +1,50 @@ |
|||||
|
/*
|
||||
|
This file is part of cpp-ethereum. |
||||
|
|
||||
|
cpp-ethereum is free software: you can redistribute it and/or modify |
||||
|
it under the terms of the GNU General Public License as published by |
||||
|
the Free Software Foundation, either version 3 of the License, or |
||||
|
(at your option) any later version. |
||||
|
|
||||
|
cpp-ethereum is distributed in the hope that it will be useful, |
||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
GNU General Public License for more details. |
||||
|
|
||||
|
You should have received a copy of the GNU General Public License |
||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
*/ |
||||
|
/**
|
||||
|
* @author Christian <c@ethdev.com> |
||||
|
* @date 2014 |
||||
|
* Full-stack compiler that converts a source code string to bytecode. |
||||
|
*/ |
||||
|
|
||||
|
#include <libsolidity/AST.h> |
||||
|
#include <libsolidity/Scanner.h> |
||||
|
#include <libsolidity/Parser.h> |
||||
|
#include <libsolidity/NameAndTypeResolver.h> |
||||
|
#include <libsolidity/Compiler.h> |
||||
|
#include <libsolidity/CompilerStack.h> |
||||
|
|
||||
|
using namespace std; |
||||
|
|
||||
|
namespace dev |
||||
|
{ |
||||
|
namespace solidity |
||||
|
{ |
||||
|
|
||||
|
bytes CompilerStack::compile(std::string const& _sourceCode, shared_ptr<Scanner> _scanner, |
||||
|
bool _optimize) |
||||
|
{ |
||||
|
if (!_scanner) |
||||
|
_scanner = make_shared<Scanner>(); |
||||
|
_scanner->reset(CharStream(_sourceCode)); |
||||
|
|
||||
|
ASTPointer<ContractDefinition> contract = Parser().parse(_scanner); |
||||
|
NameAndTypeResolver().resolveNamesAndTypes(*contract); |
||||
|
return Compiler::compile(*contract, _optimize); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
@ -0,0 +1,43 @@ |
|||||
|
/*
|
||||
|
This file is part of cpp-ethereum. |
||||
|
|
||||
|
cpp-ethereum is free software: you can redistribute it and/or modify |
||||
|
it under the terms of the GNU General Public License as published by |
||||
|
the Free Software Foundation, either version 3 of the License, or |
||||
|
(at your option) any later version. |
||||
|
|
||||
|
cpp-ethereum is distributed in the hope that it will be useful, |
||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
GNU General Public License for more details. |
||||
|
|
||||
|
You should have received a copy of the GNU General Public License |
||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
*/ |
||||
|
/**
|
||||
|
* @author Christian <c@ethdev.com> |
||||
|
* @date 2014 |
||||
|
* Full-stack compiler that converts a source code string to bytecode. |
||||
|
*/ |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include <string> |
||||
|
#include <memory> |
||||
|
#include <libdevcore/Common.h> |
||||
|
|
||||
|
namespace dev { |
||||
|
namespace solidity { |
||||
|
|
||||
|
class Scanner; // forward
|
||||
|
|
||||
|
class CompilerStack |
||||
|
{ |
||||
|
public: |
||||
|
/// Compile the given @a _sourceCode to bytecode. If a scanner is provided, it is used for
|
||||
|
/// scanning the source code - this is useful for printing exception information.
|
||||
|
static bytes compile(std::string const& _sourceCode, std::shared_ptr<Scanner> _scanner = std::shared_ptr<Scanner>(), bool _optimize = false); |
||||
|
}; |
||||
|
|
||||
|
} |
||||
|
} |
@ -0,0 +1,436 @@ |
|||||
|
/*
|
||||
|
This file is part of cpp-ethereum. |
||||
|
|
||||
|
cpp-ethereum is free software: you can redistribute it and/or modify |
||||
|
it under the terms of the GNU General Public License as published by |
||||
|
the Free Software Foundation, either version 3 of the License, or |
||||
|
(at your option) any later version. |
||||
|
|
||||
|
cpp-ethereum is distributed in the hope that it will be useful, |
||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
GNU General Public License for more details. |
||||
|
|
||||
|
You should have received a copy of the GNU General Public License |
||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
*/ |
||||
|
/**
|
||||
|
* @author Christian <c@ethdev.com> |
||||
|
* @date 2014 |
||||
|
* Solidity AST to EVM bytecode compiler for expressions. |
||||
|
*/ |
||||
|
|
||||
|
#include <utility> |
||||
|
#include <numeric> |
||||
|
#include <libsolidity/AST.h> |
||||
|
#include <libsolidity/ExpressionCompiler.h> |
||||
|
#include <libsolidity/CompilerContext.h> |
||||
|
|
||||
|
using namespace std; |
||||
|
|
||||
|
namespace dev { |
||||
|
namespace solidity { |
||||
|
|
||||
|
void ExpressionCompiler::compileExpression(CompilerContext& _context, Expression& _expression) |
||||
|
{ |
||||
|
ExpressionCompiler compiler(_context); |
||||
|
_expression.accept(compiler); |
||||
|
} |
||||
|
|
||||
|
void ExpressionCompiler::appendTypeConversion(CompilerContext& _context, |
||||
|
Type const& _typeOnStack, Type const& _targetType) |
||||
|
{ |
||||
|
ExpressionCompiler compiler(_context); |
||||
|
compiler.appendTypeConversion(_typeOnStack, _targetType); |
||||
|
} |
||||
|
|
||||
|
bool ExpressionCompiler::visit(Assignment& _assignment) |
||||
|
{ |
||||
|
_assignment.getRightHandSide().accept(*this); |
||||
|
appendTypeConversion(*_assignment.getRightHandSide().getType(), *_assignment.getType()); |
||||
|
m_currentLValue.reset(); |
||||
|
_assignment.getLeftHandSide().accept(*this); |
||||
|
|
||||
|
Token::Value op = _assignment.getAssignmentOperator(); |
||||
|
if (op != Token::ASSIGN) // compound assignment
|
||||
|
appendOrdinaryBinaryOperatorCode(Token::AssignmentToBinaryOp(op), *_assignment.getType()); |
||||
|
else |
||||
|
m_context << eth::Instruction::POP; |
||||
|
|
||||
|
storeInLValue(_assignment); |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
void ExpressionCompiler::endVisit(UnaryOperation& _unaryOperation) |
||||
|
{ |
||||
|
//@todo type checking and creating code for an operator should be in the same place:
|
||||
|
// the operator should know how to convert itself and to which types it applies, so
|
||||
|
// put this code together with "Type::acceptsBinary/UnaryOperator" into a class that
|
||||
|
// represents the operator
|
||||
|
switch (_unaryOperation.getOperator()) |
||||
|
{ |
||||
|
case Token::NOT: // !
|
||||
|
m_context << eth::Instruction::ISZERO; |
||||
|
break; |
||||
|
case Token::BIT_NOT: // ~
|
||||
|
m_context << eth::Instruction::NOT; |
||||
|
break; |
||||
|
case Token::DELETE: // delete
|
||||
|
{ |
||||
|
// a -> a xor a (= 0).
|
||||
|
// @todo semantics change for complex types
|
||||
|
m_context << eth::Instruction::DUP1 << eth::Instruction::XOR; |
||||
|
storeInLValue(_unaryOperation); |
||||
|
break; |
||||
|
} |
||||
|
case Token::INC: // ++ (pre- or postfix)
|
||||
|
case Token::DEC: // -- (pre- or postfix)
|
||||
|
if (!_unaryOperation.isPrefixOperation()) |
||||
|
m_context << eth::Instruction::DUP1; |
||||
|
m_context << u256(1); |
||||
|
if (_unaryOperation.getOperator() == Token::INC) |
||||
|
m_context << eth::Instruction::ADD; |
||||
|
else |
||||
|
m_context << eth::Instruction::SWAP1 << eth::Instruction::SUB; // @todo avoid the swap
|
||||
|
storeInLValue(_unaryOperation, !_unaryOperation.isPrefixOperation()); |
||||
|
break; |
||||
|
case Token::ADD: // +
|
||||
|
// unary add, so basically no-op
|
||||
|
break; |
||||
|
case Token::SUB: // -
|
||||
|
m_context << u256(0) << eth::Instruction::SUB; |
||||
|
break; |
||||
|
default: |
||||
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid unary operator: " + |
||||
|
string(Token::toString(_unaryOperation.getOperator())))); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
bool ExpressionCompiler::visit(BinaryOperation& _binaryOperation) |
||||
|
{ |
||||
|
Expression& leftExpression = _binaryOperation.getLeftExpression(); |
||||
|
Expression& rightExpression = _binaryOperation.getRightExpression(); |
||||
|
Type const& commonType = _binaryOperation.getCommonType(); |
||||
|
Token::Value const op = _binaryOperation.getOperator(); |
||||
|
|
||||
|
if (op == Token::AND || op == Token::OR) // special case: short-circuiting
|
||||
|
appendAndOrOperatorCode(_binaryOperation); |
||||
|
else |
||||
|
{ |
||||
|
bool cleanupNeeded = false; |
||||
|
if (commonType.getCategory() == Type::Category::INTEGER) |
||||
|
if (Token::isCompareOp(op) || op == Token::DIV || op == Token::MOD) |
||||
|
cleanupNeeded = true; |
||||
|
|
||||
|
rightExpression.accept(*this); |
||||
|
appendTypeConversion(*rightExpression.getType(), commonType, cleanupNeeded); |
||||
|
leftExpression.accept(*this); |
||||
|
appendTypeConversion(*leftExpression.getType(), commonType, cleanupNeeded); |
||||
|
if (Token::isCompareOp(op)) |
||||
|
appendCompareOperatorCode(op, commonType); |
||||
|
else |
||||
|
appendOrdinaryBinaryOperatorCode(op, commonType); |
||||
|
} |
||||
|
|
||||
|
// do not visit the child nodes, we already did that explicitly
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
bool ExpressionCompiler::visit(FunctionCall& _functionCall) |
||||
|
{ |
||||
|
if (_functionCall.isTypeConversion()) |
||||
|
{ |
||||
|
//@todo we only have integers and bools for now which cannot be explicitly converted
|
||||
|
if (asserts(_functionCall.getArguments().size() == 1)) |
||||
|
BOOST_THROW_EXCEPTION(InternalCompilerError()); |
||||
|
Expression& firstArgument = *_functionCall.getArguments().front(); |
||||
|
firstArgument.accept(*this); |
||||
|
appendTypeConversion(*firstArgument.getType(), *_functionCall.getType()); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
// Calling convention: Caller pushes return address and arguments
|
||||
|
// Callee removes them and pushes return values
|
||||
|
m_currentLValue.reset(); |
||||
|
_functionCall.getExpression().accept(*this); |
||||
|
if (asserts(m_currentLValue.isInCode())) |
||||
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Code reference expected.")); |
||||
|
eth::AssemblyItem functionTag(eth::PushTag, m_currentLValue.location); |
||||
|
|
||||
|
FunctionDefinition const& function = dynamic_cast<FunctionType const&>(*_functionCall.getExpression().getType()).getFunction(); |
||||
|
|
||||
|
eth::AssemblyItem returnLabel = m_context.pushNewTag(); |
||||
|
std::vector<ASTPointer<Expression>> const& arguments = _functionCall.getArguments(); |
||||
|
if (asserts(arguments.size() == function.getParameters().size())) |
||||
|
BOOST_THROW_EXCEPTION(InternalCompilerError()); |
||||
|
for (unsigned i = 0; i < arguments.size(); ++i) |
||||
|
{ |
||||
|
arguments[i]->accept(*this); |
||||
|
appendTypeConversion(*arguments[i]->getType(), *function.getParameters()[i]->getType()); |
||||
|
} |
||||
|
|
||||
|
m_context.appendJumpTo(functionTag); |
||||
|
m_context << returnLabel; |
||||
|
|
||||
|
// callee adds return parameters, but removes arguments and return label
|
||||
|
m_context.adjustStackOffset(function.getReturnParameters().size() - arguments.size() - 1); |
||||
|
|
||||
|
// @todo for now, the return value of a function is its first return value, so remove
|
||||
|
// all others
|
||||
|
for (unsigned i = 1; i < function.getReturnParameters().size(); ++i) |
||||
|
m_context << eth::Instruction::POP; |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
void ExpressionCompiler::endVisit(MemberAccess&) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
void ExpressionCompiler::endVisit(IndexAccess&) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
void ExpressionCompiler::endVisit(Identifier& _identifier) |
||||
|
{ |
||||
|
Declaration const* declaration = _identifier.getReferencedDeclaration(); |
||||
|
if (m_context.isLocalVariable(declaration)) |
||||
|
m_currentLValue = LValueLocation(LValueLocation::STACK, |
||||
|
m_context.getBaseStackOffsetOfVariable(*declaration)); |
||||
|
else if (m_context.isStateVariable(declaration)) |
||||
|
m_currentLValue = LValueLocation(LValueLocation::STORAGE, |
||||
|
m_context.getStorageLocationOfVariable(*declaration)); |
||||
|
else if (m_context.isFunctionDefinition(declaration)) |
||||
|
m_currentLValue = LValueLocation(LValueLocation::CODE, |
||||
|
m_context.getFunctionEntryLabel(dynamic_cast<FunctionDefinition const&>(*declaration)).data()); |
||||
|
else |
||||
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Identifier type not supported or identifier not found.")); |
||||
|
|
||||
|
retrieveLValueValue(_identifier); |
||||
|
} |
||||
|
|
||||
|
void ExpressionCompiler::endVisit(Literal& _literal) |
||||
|
{ |
||||
|
switch (_literal.getType()->getCategory()) |
||||
|
{ |
||||
|
case Type::Category::INTEGER: |
||||
|
case Type::Category::BOOL: |
||||
|
m_context << _literal.getType()->literalValue(_literal); |
||||
|
break; |
||||
|
default: |
||||
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Only integer and boolean literals implemented for now.")); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void ExpressionCompiler::appendAndOrOperatorCode(BinaryOperation& _binaryOperation) |
||||
|
{ |
||||
|
Token::Value const op = _binaryOperation.getOperator(); |
||||
|
if (asserts(op == Token::OR || op == Token::AND)) |
||||
|
BOOST_THROW_EXCEPTION(InternalCompilerError()); |
||||
|
|
||||
|
_binaryOperation.getLeftExpression().accept(*this); |
||||
|
m_context << eth::Instruction::DUP1; |
||||
|
if (op == Token::AND) |
||||
|
m_context << eth::Instruction::ISZERO; |
||||
|
eth::AssemblyItem endLabel = m_context.appendConditionalJump(); |
||||
|
m_context << eth::Instruction::POP; |
||||
|
_binaryOperation.getRightExpression().accept(*this); |
||||
|
m_context << endLabel; |
||||
|
} |
||||
|
|
||||
|
void ExpressionCompiler::appendCompareOperatorCode(Token::Value _operator, Type const& _type) |
||||
|
{ |
||||
|
if (_operator == Token::EQ || _operator == Token::NE) |
||||
|
{ |
||||
|
m_context << eth::Instruction::EQ; |
||||
|
if (_operator == Token::NE) |
||||
|
m_context << eth::Instruction::ISZERO; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
IntegerType const& type = dynamic_cast<IntegerType const&>(_type); |
||||
|
bool const isSigned = type.isSigned(); |
||||
|
|
||||
|
switch (_operator) |
||||
|
{ |
||||
|
case Token::GTE: |
||||
|
m_context << (isSigned ? eth::Instruction::SLT : eth::Instruction::LT) |
||||
|
<< eth::Instruction::ISZERO; |
||||
|
break; |
||||
|
case Token::LTE: |
||||
|
m_context << (isSigned ? eth::Instruction::SGT : eth::Instruction::GT) |
||||
|
<< eth::Instruction::ISZERO; |
||||
|
break; |
||||
|
case Token::GT: |
||||
|
m_context << (isSigned ? eth::Instruction::SGT : eth::Instruction::GT); |
||||
|
break; |
||||
|
case Token::LT: |
||||
|
m_context << (isSigned ? eth::Instruction::SLT : eth::Instruction::LT); |
||||
|
break; |
||||
|
default: |
||||
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown comparison operator.")); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void ExpressionCompiler::appendOrdinaryBinaryOperatorCode(Token::Value _operator, Type const& _type) |
||||
|
{ |
||||
|
if (Token::isArithmeticOp(_operator)) |
||||
|
appendArithmeticOperatorCode(_operator, _type); |
||||
|
else if (Token::isBitOp(_operator)) |
||||
|
appendBitOperatorCode(_operator); |
||||
|
else if (Token::isShiftOp(_operator)) |
||||
|
appendShiftOperatorCode(_operator); |
||||
|
else |
||||
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown binary operator.")); |
||||
|
} |
||||
|
|
||||
|
void ExpressionCompiler::appendArithmeticOperatorCode(Token::Value _operator, Type const& _type) |
||||
|
{ |
||||
|
IntegerType const& type = dynamic_cast<IntegerType const&>(_type); |
||||
|
bool const isSigned = type.isSigned(); |
||||
|
|
||||
|
switch (_operator) |
||||
|
{ |
||||
|
case Token::ADD: |
||||
|
m_context << eth::Instruction::ADD; |
||||
|
break; |
||||
|
case Token::SUB: |
||||
|
m_context << eth::Instruction::SUB; |
||||
|
break; |
||||
|
case Token::MUL: |
||||
|
m_context << eth::Instruction::MUL; |
||||
|
break; |
||||
|
case Token::DIV: |
||||
|
m_context << (isSigned ? eth::Instruction::SDIV : eth::Instruction::DIV); |
||||
|
break; |
||||
|
case Token::MOD: |
||||
|
m_context << (isSigned ? eth::Instruction::SMOD : eth::Instruction::MOD); |
||||
|
break; |
||||
|
default: |
||||
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown arithmetic operator.")); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void ExpressionCompiler::appendBitOperatorCode(Token::Value _operator) |
||||
|
{ |
||||
|
switch (_operator) |
||||
|
{ |
||||
|
case Token::BIT_OR: |
||||
|
m_context << eth::Instruction::OR; |
||||
|
break; |
||||
|
case Token::BIT_AND: |
||||
|
m_context << eth::Instruction::AND; |
||||
|
break; |
||||
|
case Token::BIT_XOR: |
||||
|
m_context << eth::Instruction::XOR; |
||||
|
break; |
||||
|
default: |
||||
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown bit operator.")); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void ExpressionCompiler::appendShiftOperatorCode(Token::Value _operator) |
||||
|
{ |
||||
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Shift operators not yet implemented.")); |
||||
|
switch (_operator) |
||||
|
{ |
||||
|
case Token::SHL: |
||||
|
break; |
||||
|
case Token::SAR: |
||||
|
break; |
||||
|
default: |
||||
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown shift operator.")); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type const& _targetType, bool _cleanupNeeded) |
||||
|
{ |
||||
|
// For a type extension, we need to remove all higher-order bits that we might have ignored in
|
||||
|
// previous operations.
|
||||
|
// @todo: store in the AST whether the operand might have "dirty" higher order bits
|
||||
|
|
||||
|
if (_typeOnStack == _targetType && !_cleanupNeeded) |
||||
|
return; |
||||
|
if (_typeOnStack.getCategory() == Type::Category::INTEGER) |
||||
|
appendHighBitsCleanup(dynamic_cast<IntegerType const&>(_typeOnStack)); |
||||
|
else if (_typeOnStack != _targetType) |
||||
|
// All other types should not be convertible to non-equal types.
|
||||
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid type conversion requested.")); |
||||
|
} |
||||
|
|
||||
|
void ExpressionCompiler::appendHighBitsCleanup(IntegerType const& _typeOnStack) |
||||
|
{ |
||||
|
if (_typeOnStack.getNumBits() == 256) |
||||
|
return; |
||||
|
else if (_typeOnStack.isSigned()) |
||||
|
m_context << u256(_typeOnStack.getNumBits() / 8 - 1) << eth::Instruction::SIGNEXTEND; |
||||
|
else |
||||
|
m_context << ((u256(1) << _typeOnStack.getNumBits()) - 1) << eth::Instruction::AND; |
||||
|
} |
||||
|
|
||||
|
void ExpressionCompiler::retrieveLValueValue(Expression const& _expression) |
||||
|
{ |
||||
|
switch (m_currentLValue.locationType) |
||||
|
{ |
||||
|
case LValueLocation::CODE: |
||||
|
// not stored on the stack
|
||||
|
break; |
||||
|
case LValueLocation::STACK: |
||||
|
{ |
||||
|
unsigned stackPos = m_context.baseToCurrentStackOffset(unsigned(m_currentLValue.location)); |
||||
|
if (stackPos >= 15) //@todo correct this by fetching earlier or moving to memory
|
||||
|
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_sourceLocation(_expression.getLocation()) |
||||
|
<< errinfo_comment("Stack too deep.")); |
||||
|
m_context << eth::dupInstruction(stackPos + 1); |
||||
|
break; |
||||
|
} |
||||
|
case LValueLocation::STORAGE: |
||||
|
m_context << m_currentLValue.location << eth::Instruction::SLOAD; |
||||
|
break; |
||||
|
case LValueLocation::MEMORY: |
||||
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Location type not yet implemented.")); |
||||
|
break; |
||||
|
default: |
||||
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unsupported location type.")); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void ExpressionCompiler::storeInLValue(Expression const& _expression, bool _move) |
||||
|
{ |
||||
|
switch (m_currentLValue.locationType) |
||||
|
{ |
||||
|
case LValueLocation::STACK: |
||||
|
{ |
||||
|
unsigned stackPos = m_context.baseToCurrentStackOffset(unsigned(m_currentLValue.location)); |
||||
|
if (stackPos > 16) |
||||
|
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_sourceLocation(_expression.getLocation()) |
||||
|
<< errinfo_comment("Stack too deep.")); |
||||
|
else if (stackPos > 0) |
||||
|
m_context << eth::swapInstruction(stackPos) << eth::Instruction::POP; |
||||
|
if (!_move) |
||||
|
retrieveLValueValue(_expression); |
||||
|
break; |
||||
|
} |
||||
|
case LValueLocation::STORAGE: |
||||
|
if (!_move) |
||||
|
m_context << eth::Instruction::DUP1; |
||||
|
m_context << m_currentLValue.location << eth::Instruction::SSTORE; |
||||
|
break; |
||||
|
case LValueLocation::CODE: |
||||
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Location type does not support assignment.")); |
||||
|
break; |
||||
|
case LValueLocation::MEMORY: |
||||
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Location type not yet implemented.")); |
||||
|
break; |
||||
|
default: |
||||
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unsupported location type.")); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
@ -0,0 +1,117 @@ |
|||||
|
/*
|
||||
|
This file is part of cpp-ethereum. |
||||
|
|
||||
|
cpp-ethereum is free software: you can redistribute it and/or modify |
||||
|
it under the terms of the GNU General Public License as published by |
||||
|
the Free Software Foundation, either version 3 of the License, or |
||||
|
(at your option) any later version. |
||||
|
|
||||
|
cpp-ethereum is distributed in the hope that it will be useful, |
||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
GNU General Public License for more details. |
||||
|
|
||||
|
You should have received a copy of the GNU General Public License |
||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
*/ |
||||
|
/**
|
||||
|
* @author Christian <c@ethdev.com> |
||||
|
* @date 2014 |
||||
|
* Solidity AST to EVM bytecode compiler for expressions. |
||||
|
*/ |
||||
|
|
||||
|
#include <libdevcore/Common.h> |
||||
|
#include <libsolidity/ASTVisitor.h> |
||||
|
|
||||
|
namespace dev { |
||||
|
namespace eth |
||||
|
{ |
||||
|
class AssemblyItem; // forward
|
||||
|
} |
||||
|
namespace solidity { |
||||
|
|
||||
|
class CompilerContext; // forward
|
||||
|
class Type; // forward
|
||||
|
class IntegerType; // forward
|
||||
|
|
||||
|
/**
|
||||
|
* Compiler for expressions, i.e. converts an AST tree whose root is an Expression into a stream |
||||
|
* of EVM instructions. It needs a compiler context that is the same for the whole compilation |
||||
|
* unit. |
||||
|
*/ |
||||
|
class ExpressionCompiler: private ASTVisitor |
||||
|
{ |
||||
|
public: |
||||
|
/// Compile the given @a _expression into the @a _context.
|
||||
|
static void compileExpression(CompilerContext& _context, Expression& _expression); |
||||
|
|
||||
|
/// Appends code to remove dirty higher order bits in case of an implicit promotion to a wider type.
|
||||
|
static void appendTypeConversion(CompilerContext& _context, Type const& _typeOnStack, Type const& _targetType); |
||||
|
|
||||
|
private: |
||||
|
ExpressionCompiler(CompilerContext& _compilerContext): m_context(_compilerContext) {} |
||||
|
|
||||
|
virtual bool visit(Assignment& _assignment) override; |
||||
|
virtual void endVisit(UnaryOperation& _unaryOperation) override; |
||||
|
virtual bool visit(BinaryOperation& _binaryOperation) override; |
||||
|
virtual bool visit(FunctionCall& _functionCall) override; |
||||
|
virtual void endVisit(MemberAccess& _memberAccess) override; |
||||
|
virtual void endVisit(IndexAccess& _indexAccess) override; |
||||
|
virtual void endVisit(Identifier& _identifier) override; |
||||
|
virtual void endVisit(Literal& _literal) override; |
||||
|
|
||||
|
///@{
|
||||
|
///@name Append code for various operator types
|
||||
|
void appendAndOrOperatorCode(BinaryOperation& _binaryOperation); |
||||
|
void appendCompareOperatorCode(Token::Value _operator, Type const& _type); |
||||
|
void appendOrdinaryBinaryOperatorCode(Token::Value _operator, Type const& _type); |
||||
|
|
||||
|
void appendArithmeticOperatorCode(Token::Value _operator, Type const& _type); |
||||
|
void appendBitOperatorCode(Token::Value _operator); |
||||
|
void appendShiftOperatorCode(Token::Value _operator); |
||||
|
/// @}
|
||||
|
|
||||
|
/// Appends an implicit or explicit type conversion. For now this comprises only erasing
|
||||
|
/// higher-order bits (@see appendHighBitCleanup) when widening integer types.
|
||||
|
/// If @a _cleanupNeeded, high order bits cleanup is also done if no type conversion would be
|
||||
|
/// necessary.
|
||||
|
void appendTypeConversion(Type const& _typeOnStack, Type const& _targetType, bool _cleanupNeeded = false); |
||||
|
//// Appends code that cleans higher-order bits for integer types.
|
||||
|
void appendHighBitsCleanup(IntegerType const& _typeOnStack); |
||||
|
|
||||
|
/// Copies the value of the current lvalue to the top of the stack.
|
||||
|
void retrieveLValueValue(Expression const& _expression); |
||||
|
/// Stores the value on top of the stack in the current lvalue. Removes it from the stack if
|
||||
|
/// @a _move is true.
|
||||
|
void storeInLValue(Expression const& _expression, bool _move = false); |
||||
|
|
||||
|
/**
|
||||
|
* Location of an lvalue, either in code (for a function) on the stack, in the storage or memory. |
||||
|
*/ |
||||
|
struct LValueLocation |
||||
|
{ |
||||
|
enum LocationType { INVALID, CODE, STACK, MEMORY, STORAGE }; |
||||
|
|
||||
|
LValueLocation() { reset(); } |
||||
|
LValueLocation(LocationType _type, u256 const& _location): locationType(_type), location(_location) {} |
||||
|
void reset() { locationType = INVALID; location = 0; } |
||||
|
bool isValid() const { return locationType != INVALID; } |
||||
|
bool isInCode() const { return locationType == CODE; } |
||||
|
bool isInOnStack() const { return locationType == STACK; } |
||||
|
bool isInMemory() const { return locationType == MEMORY; } |
||||
|
bool isInStorage() const { return locationType == STORAGE; } |
||||
|
|
||||
|
LocationType locationType; |
||||
|
/// Depending on the type, this is the id of a tag (code), the base offset of a stack
|
||||
|
/// variable (@see CompilerContext::getBaseStackOffsetOfVariable) or the offset in
|
||||
|
/// storage or memory.
|
||||
|
u256 location; |
||||
|
}; |
||||
|
|
||||
|
LValueLocation m_currentLValue; |
||||
|
CompilerContext& m_context; |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
} |
||||
|
} |
@ -1,55 +1,55 @@ |
|||||
[ |
[ |
||||
{ "method": "coinbase", "params": [], "order": [], "returns" : "" }, |
{ "method": "eth_coinbase", "params": [], "order": [], "returns" : "" }, |
||||
{ "method": "setCoinbase", "params": [""], "order": [], "returns" : true }, |
{ "method": "eth_setCoinbase", "params": [""], "order": [], "returns" : true }, |
||||
{ "method": "listening", "params": [], "order": [], "returns" : false }, |
{ "method": "eth_listening", "params": [], "order": [], "returns" : false }, |
||||
{ "method": "setListening", "params": [false], "order" : [], "returns" : true }, |
{ "method": "eth_setListening", "params": [false], "order" : [], "returns" : true }, |
||||
{ "method": "mining", "params": [], "order": [], "returns" : false }, |
{ "method": "eth_mining", "params": [], "order": [], "returns" : false }, |
||||
{ "method": "setMining", "params": [false], "order" : [], "returns" : true }, |
{ "method": "eth_setMining", "params": [false], "order" : [], "returns" : true }, |
||||
{ "method": "gasPrice", "params": [], "order": [], "returns" : "" }, |
{ "method": "eth_gasPrice", "params": [], "order": [], "returns" : "" }, |
||||
{ "method": "account", "params": [], "order": [], "returns" : "" }, |
{ "method": "eth_accounts", "params": [], "order": [], "returns" : [] }, |
||||
{ "method": "accounts", "params": [], "order": [], "returns" : [] }, |
{ "method": "eth_peerCount", "params": [], "order": [], "returns" : 0 }, |
||||
{ "method": "peerCount", "params": [], "order": [], "returns" : 0 }, |
{ "method": "eth_defaultBlock", "params": [], "order": [], "returns" : 0}, |
||||
{ "method": "defaultBlock", "params": [], "order": [], "returns" : 0}, |
{ "method": "eth_setDefaultBlock", "params": [0], "order": [], "returns" : true}, |
||||
{ "method": "setDefaultBlock", "params": [0], "order": [], "returns" : true}, |
{ "method": "eth_number", "params": [], "order": [], "returns" : 0}, |
||||
{ "method": "number", "params": [], "order": [], "returns" : 0}, |
|
||||
|
{ "method": "eth_balanceAt", "params": [""], "order": [], "returns" : ""}, |
||||
{ "method": "balanceAt", "params": [""], "order": [], "returns" : ""}, |
{ "method": "eth_stateAt", "params": ["", ""], "order": [], "returns": ""}, |
||||
{ "method": "stateAt", "params": ["", ""], "order": [], "returns": ""}, |
{ "method": "eth_countAt", "params": [""], "order": [], "returns" : 0.0}, |
||||
{ "method": "countAt", "params": [""], "order": [], "returns" : 0.0}, |
{ "method": "eth_codeAt", "params": [""], "order": [], "returns": ""}, |
||||
{ "method": "codeAt", "params": [""], "order": [], "returns": ""}, |
|
||||
|
{ "method": "eth_transact", "params": [{}], "order": [], "returns": ""}, |
||||
{ "method": "transact", "params": [{}], "order": [], "returns": ""}, |
{ "method": "eth_call", "params": [{}], "order": [], "returns": ""}, |
||||
{ "method": "call", "params": [{}], "order": [], "returns": ""}, |
|
||||
|
{ "method": "eth_blockByHash", "params": [""],"order": [], "returns": {}}, |
||||
{ "method": "blockByHash", "params": [""],"order": [], "returns": {}}, |
{ "method": "eth_blockByNumber", "params": [0],"order": [], "returns": {}}, |
||||
{ "method": "blockByNumber", "params": [0],"order": [], "returns": {}}, |
{ "method": "eth_transactionByHash", "params": ["", 0], "order": [], "returns": {}}, |
||||
{ "method": "transactionByHash", "params": ["", 0], "order": [], "returns": {}}, |
{ "method": "eth_transactionByNumber", "params": [0, 0], "order": [], "returns": {}}, |
||||
{ "method": "transactionByNumber", "params": [0, 0], "order": [], "returns": {}}, |
{ "method": "eth_uncleByHash", "params": ["", 0], "order": [], "returns": {}}, |
||||
{ "method": "uncleByHash", "params": ["", 0], "order": [], "returns": {}}, |
{ "method": "eth_uncleByNumber", "params": [0, 0], "order": [], "returns": {}}, |
||||
{ "method": "uncleByNumber", "params": [0, 0], "order": [], "returns": {}}, |
|
||||
|
{ "method": "eth_lll", "params": [""], "order": [], "returns": ""}, |
||||
{ "method": "compile", "params": [""], "order": [], "returns": ""}, |
{ "method": "eth_compile", "params": [""], "order": [], "returns": ""}, |
||||
|
|
||||
{ "method": "newFilter", "params": [{}], "order": [], "returns": 0}, |
{ "method": "eth_newFilter", "params": [{}], "order": [], "returns": 0}, |
||||
{ "method": "newFilterString", "params": [""], "order": [], "returns": 0}, |
{ "method": "eth_newFilterString", "params": [""], "order": [], "returns": 0}, |
||||
{ "method": "uninstallFilter", "params": [0], "order": [], "returns": true}, |
{ "method": "eth_uninstallFilter", "params": [0], "order": [], "returns": true}, |
||||
{ "method": "changed", "params": [0], "order": [], "returns": false}, |
{ "method": "eth_changed", "params": [0], "order": [], "returns": false}, |
||||
{ "method": "getMessages", "params": [0], "order": [], "returns": []}, |
{ "method": "eth_getMessages", "params": [0], "order": [], "returns": []}, |
||||
|
|
||||
{ "method": "put", "params": ["", "", ""], "order": [], "returns": true}, |
{ "method": "db_put", "params": ["", "", ""], "order": [], "returns": true}, |
||||
{ "method": "get", "params": ["", ""], "order": [], "returns": ""}, |
{ "method": "db_get", "params": ["", ""], "order": [], "returns": ""}, |
||||
{ "method": "putString", "params": ["", "", ""], "order": [], "returns": true}, |
{ "method": "db_putString", "params": ["", "", ""], "order": [], "returns": true}, |
||||
{ "method": "getString", "params": ["", ""], "order": [], "returns": ""}, |
{ "method": "db_getString", "params": ["", ""], "order": [], "returns": ""}, |
||||
|
|
||||
{ "method": "post", "params": [{}], "order": [], "returns": true}, |
{ "method": "shh_post", "params": [{}], "order": [], "returns": true}, |
||||
{ "method": "newIdentity", "params": [], "order": [], "returns": ""}, |
{ "method": "shh_newIdentity", "params": [], "order": [], "returns": ""}, |
||||
{ "method": "haveIdentity", "params": [""], "order": [], "returns": false}, |
{ "method": "shh_haveIdentity", "params": [""], "order": [], "returns": false}, |
||||
{ "method": "newGroup", "params": ["", ""], "order": [], "returns": ""}, |
{ "method": "shh_newGroup", "params": ["", ""], "order": [], "returns": ""}, |
||||
{ "method": "addToGroup", "params": ["", ""], "order": [], "returns": ""}, |
{ "method": "shh_addToGroup", "params": ["", ""], "order": [], "returns": ""}, |
||||
|
|
||||
{ "method": "shhNewFilter", "params": [{}], "order": [], "returns": 0}, |
{ "method": "shh_newFilter", "params": [{}], "order": [], "returns": 0}, |
||||
{ "method": "shhUninstallFilter", "params": [0], "order": [], "returns": true}, |
{ "method": "shh_uninstallFilter", "params": [0], "order": [], "returns": true}, |
||||
{ "method": "shhChanged", "params": [0], "order": [], "returns": []} |
{ "method": "shh_changed", "params": [0], "order": [], "returns": []} |
||||
|
|
||||
] |
] |
||||
|
|
||||
|
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue