Fabcoin Core  0.16.2
P2P Digital Currency
VM.h
Go to the documentation of this file.
1 /*
2  This file is part of cpp-ethereum.
3 
4  cpp-ethereum is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  cpp-ethereum is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
16 */
22 #pragma once
23 
24 #include <unordered_map>
25 #include <libdevcore/Exceptions.h>
26 #include <libethcore/Common.h>
27 #include <libevmcore/Instruction.h>
28 #include <libdevcore/SHA3.h>
29 #include <libethcore/BlockHeader.h>
30 #include "VMFace.h"
31 
32 namespace dev
33 {
34 namespace eth
35 {
36 
37 // Convert from a 256-bit integer stack/memory entry into a 160-bit Address hash.
38 // Currently we just pull out the right (low-order in BE) 160-bits.
39 inline Address asAddress(u256 _item)
40 {
41  return right160(h256(_item));
42 }
43 
45 {
46  return (u160)_a;
47 }
48 
49 
51 {
53  int args;
54  int ret;
55 };
56 
57 
60 class VM: public VMFace
61 {
62 public:
63  virtual owning_bytes_ref exec(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp) override final;
64 
65 #if EVM_JUMPS_AND_SUBS
66  // invalid code will throw an exeption
67  void validate(ExtVMFace& _ext);
68  void validateSubroutine(uint64_t _PC, uint64_t* _RP, u256* _SP);
69 #endif
70 
71  bytes const& memory() const { return m_mem; }
72  u256s stack() const { assert(m_stack <= m_SP + 1); return u256s(m_stack, m_SP + 1); };
73 
74 private:
75 
76  u256* io_gas = 0;
77  uint64_t m_io_gas = 0;
78  ExtVMFace* m_ext = 0;
80 
81  static std::array<InstructionMetric, 256> c_metrics;
82  static void initMetrics();
83  static u256 exp256(u256 _base, u256 _exponent);
84  void copyCode(int);
85  const void* const* c_jumpTable = 0;
86  bool m_caseInit = false;
87 
88  typedef void (VM::*MemFnPtr)();
89  MemFnPtr m_bounce = 0;
90  MemFnPtr m_onFail = 0;
91  uint64_t m_nSteps = 0;
92  EVMSchedule const* m_schedule = nullptr;
93 
94  // return bytes
96 
97  // space for memory
99 
100  // space for code and pointer to data
102  byte* m_code = nullptr;
103 
104  // space for stack and pointer to data
105  u256 m_stackSpace[1025];
106  u256* m_stack = m_stackSpace + 1;
107  ptrdiff_t stackSize() { return m_SP - m_stack; }
108 
109 #if EVM_JUMPS_AND_SUBS
110  // space for return stack and pointer to data
111  uint64_t m_returnSpace[1025];
112  uint64_t* m_return = m_returnSpace + 1;
113 
114  // mark PCs with frame size to detect cycles and stack mismatch
115  std::vector<size_t> m_frameSize;
116 #endif
117 
118  // constant pool
119  u256 m_pool[256];
120 
121  // interpreter state
122  Instruction m_OP; // current operator
123  uint64_t m_PC = 0; // program counter
124  u256* m_SP = m_stack - 1; // stack pointer
125 #if EVM_JUMPS_AND_SUBS
126  uint64_t* m_RP = m_return - 1; // return pointer
127 #endif
128 
129  // metering and memory state
130  uint64_t m_runGas = 0;
131  uint64_t m_newMemSize = 0;
132  uint64_t m_copyMemSize = 0;
133 
134  // initialize interpreter
135  void initEntry();
136  void optimize();
137 
138  // interpreter loop & switch
139  void interpretCases();
140 
141  // interpreter cases that call out
142  void caseCreate();
143  bool caseCallSetup(CallParameters*, bytesRef& o_output);
144  void caseCall();
145 
146  void copyDataToMemory(bytesConstRef _data, u256*& m_SP);
147  uint64_t memNeed(u256 _offset, u256 _size);
148 
149  void throwOutOfGas();
150  void throwBadInstruction();
151  void throwBadJumpDestination();
152  void throwBadStack(unsigned _size, unsigned _n, unsigned _d);
153 
154  void reportStackUse();
155 
156  std::vector<uint64_t> m_beginSubs;
157  std::vector<uint64_t> m_jumpDests;
158  int64_t verifyJumpDest(u256 const& _dest, bool _throw = true);
159 
160  int poolConstant(const u256&);
161 
162  void onOperation();
163  void checkStack(unsigned _n, unsigned _d);
164  uint64_t gasForMem(u512 _size);
165  void updateIOGas();
166  void updateGas();
167  void updateMem();
168  void logGasMem();
169  void fetchInstruction();
170 
171  uint64_t decodeJumpDest(const byte* const _code, uint64_t& _pc);
172  uint64_t decodeJumpvDest(const byte* const _code, uint64_t& _pc, u256*& _sp);
173 
174  template<class T> uint64_t toInt63(T v)
175  {
176  // check for overflow
177  if (v > 0x7FFFFFFFFFFFFFFF)
178  throwOutOfGas();
179  uint64_t w = uint64_t(v);
180  return w;
181  }
182  };
183 
184 }
185 }
bytes m_mem
Definition: VM.h:98
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
Definition: Arith256.cpp:15
A modifiable reference to an existing object or vector in memory.
Definition: vector_ref.h:20
u256s stack() const
Definition: VM.h:72
uint8_t byte
Definition: Common.h:57
h160 right160(h256 const &_t)
Convert the given value into h160 (160-bit unsigned integer) using the right 20 bytes.
Definition: FixedHash.h:353
std::vector< uint64_t > m_jumpDests
Definition: VM.h:157
#define T(i, x)
static std::array< InstructionMetric, 256 > c_metrics
Definition: VM.h:81
OnOpFunc m_onOp
Definition: VM.h:79
assert(len-trim+(2 *lenIndices)<=WIDTH)
bytes m_codeSpace
Definition: VM.h:101
u256 fromAddress(Address _a)
Definition: VM.h:44
uint64_t toInt63(T v)
Definition: VM.h:174
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 160, 160, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void >> u160
Definition: Common.h:127
owning_bytes_ref m_output
Definition: VM.h:95
std::vector< u256 > u256s
Definition: Common.h:131
Instruction m_OP
Definition: VM.h:122
std::vector< byte > bytes
Definition: Common.h:75
bytes const & memory() const
Definition: VM.h:71
Fixed-size raw-byte array container type, with an API optimised for storing hashes.
Definition: FixedHash.h:47
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 512, 512, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void >> u512
Definition: Common.h:129
std::function< void(uint64_t, uint64_t, Instruction, bigint, bigint, bigint, VM *, ExtVMFace const *)> OnOpFunc
Definition: ExtVMFace.h:193
FixedHash< 32 > h256
Definition: FixedHash.h:340
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void >> u256
Definition: Common.h:125
ptrdiff_t stackSize()
Definition: VM.h:107
EVM Virtual Machine interface.
Definition: VMFace.h:39
Instruction
Virtual machine bytecode instruction.
Definition: Instruction.h:39
Interface and null implementation of the class for specifying VM externalities.
Definition: ExtVMFace.h:265
Reference to a slice of buffer that also owns the buffer.
Definition: ExtVMFace.h:56
Address asAddress(u256 _item)
Definition: VM.h:39
bool optimize(llvm::Module &_module)
Definition: Optimizer.cpp:74
std::vector< uint64_t > m_beginSubs
Definition: VM.h:156