Ethereum  PoC-8
The C++ Implementation of Ethereum
LegacyVMConfig.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 */
17 #pragma once
18 
19 namespace dev
20  {
21  namespace eth
22  {
24 //
25 // interpreter configuration macros for development, optimizations and tracing
26 //
27 // EIP_615 - subroutines and static jumps
28 // EIP_616 - SIMD
29 //
30 // EVM_OPTIMIZE - all optimizations off when false (TO DO - MAKE DYNAMIC)
31 //
32 // EVM_SWITCH_DISPATCH - dispatch via loop and switch
33 // EVM_JUMP_DISPATCH - dispatch via a jump table - available only on GCC
34 //
35 // EVM_USE_CONSTANT_POOL - constants unpacked and ready to assign to stack
36 //
37 // EVM_REPLACE_CONST_JUMP - pre-verified jumps to save runtime lookup
38 //
39 // EVM_TRACE - provides various levels of tracing
40 
41 #ifndef EIP_615
42 #define EIP_615 false
43 #endif
44 
45 #ifndef EIP_616
46 #define EIP_616 false
47 #endif
48 
49 #ifndef EVM_JUMP_DISPATCH
50 #ifdef __GNUC__
51 #define EVM_JUMP_DISPATCH true
52 #else
53 #define EVM_JUMP_DISPATCH false
54 #endif
55 #endif
56 #if EVM_JUMP_DISPATCH
57  #ifndef __GNUC__
58 #error "address of label extension available only on Gnu"
59 #endif
60 #else
61 #define EVM_SWITCH_DISPATCH true
62 #endif
63 
64 #ifndef EVM_OPTIMIZE
65 #define EVM_OPTIMIZE false
66 #endif
67 #if EVM_OPTIMIZE
68  #define EVM_REPLACE_CONST_JUMP true
69 #define EVM_USE_CONSTANT_POOL true
70 #define EVM_DO_FIRST_PASS_OPTIMIZATION (EVM_REPLACE_CONST_JUMP || EVM_USE_CONSTANT_POOL)
71 #endif
72 
73 
75 //
76 // set EVM_TRACE to 3, 2, 1, or 0 for lots to no tracing to cerr
77 //
78 #ifndef EVM_TRACE
79 #define EVM_TRACE 0
80 #endif
81 #if EVM_TRACE > 0
82 
83  #undef ON_OP
84 #if EVM_TRACE > 2
85 #define ON_OP() \
86  (cerr << "### " << ++m_nSteps << ": " << m_PC << " " << instructionInfo(m_OP).name << endl)
87 #else
88 #define ON_OP() onOperation()
89 #endif
90 
91 #define TRACE_STR(level, str) \
92  if ((level) <= EVM_TRACE) \
93  cerr << "$$$ " << (str) << endl;
94 
95 #define TRACE_VAL(level, name, val) \
96  if ((level) <= EVM_TRACE) \
97  cerr << "=== " << (name) << " " << hex << (val) << endl;
98 #define TRACE_OP(level, pc, op) \
99  if ((level) <= EVM_TRACE) \
100  cerr << "*** " << (pc) << " " << instructionInfo(op).name << endl;
101 
102 #define TRACE_PRE_OPT(level, pc, op) \
103  if ((level) <= EVM_TRACE) \
104  cerr << "<<< " << (pc) << " " << instructionInfo(op).name << endl;
105 
106 #define TRACE_POST_OPT(level, pc, op) \
107  if ((level) <= EVM_TRACE) \
108  cerr << ">>> " << (pc) << " " << instructionInfo(op).name << endl;
109 #else
110 #define TRACE_STR(level, str)
111 #define TRACE_VAL(level, name, val)
112 #define TRACE_OP(level, pc, op)
113 #define TRACE_PRE_OPT(level, pc, op)
114 #define TRACE_POST_OPT(level, pc, op)
115 #define ON_OP() onOperation()
116 #endif
117 
118 // Executive swallows exceptions in some circumstances
119 #if 0
120 #define THROW_EXCEPTION(X) ((cerr << "!!! EVM EXCEPTION " << (X).what() << endl), abort())
121 #else
122 #if EVM_TRACE > 0
123  #define THROW_EXCEPTION(X) \
124  ((cerr << "!!! EVM EXCEPTION " << (X).what() << endl), BOOST_THROW_EXCEPTION(X))
125 #else
126 #define THROW_EXCEPTION(X) BOOST_THROW_EXCEPTION(X)
127 #endif
128 #endif
129 
130 
132 //
133 // build a simple loop-and-switch interpreter
134 //
135 #if EVM_SWITCH_DISPATCH
136 
137  #define INIT_CASES
138 #define DO_CASES \
139  for (;;) \
140  { \
141  fetchInstruction(); \
142  switch (m_OP) \
143  {
144 #define CASE(name) case Instruction::name:
145 #define NEXT \
146  ++m_PC; \
147  break;
148 #define CONTINUE continue;
149 #define BREAK return;
150 #define DEFAULT default:
151 #define WHILE_CASES \
152  } \
153  }
154 
155 
157 //
158 // build an indirect-threaded interpreter using a jump table of
159 // label addresses (a gcc extension)
160 //
161 #elif EVM_JUMP_DISPATCH
162 
163 #define INIT_CASES \
164  \
165  static const void* const jumpTable[256] = { \
166  &&STOP, /* 00 */ \
167  &&ADD, \
168  &&MUL, \
169  &&SUB, \
170  &&DIV, \
171  &&SDIV, \
172  &&MOD, \
173  &&SMOD, \
174  &&ADDMOD, \
175  &&MULMOD, \
176  &&EXP, \
177  &&SIGNEXTEND, \
178  &&INVALID, \
179  &&INVALID, \
180  &&INVALID, \
181  &&INVALID, \
182  &&LT, /* 10, */ \
183  &&GT, \
184  &&SLT, \
185  &&SGT, \
186  &&EQ, \
187  &&ISZERO, \
188  &&AND, \
189  &&OR, \
190  &&XOR, \
191  &&NOT, \
192  &&BYTE, \
193  &&SHL, \
194  &&SHR, \
195  &&SAR, \
196  &&INVALID, \
197  &&INVALID, \
198  &&SHA3, /* 20, */ \
199  &&INVALID, \
200  &&INVALID, \
201  &&INVALID, \
202  &&INVALID, \
203  &&INVALID, \
204  &&INVALID, \
205  &&INVALID, \
206  &&INVALID, \
207  &&INVALID, \
208  &&INVALID, \
209  &&INVALID, \
210  &&INVALID, \
211  &&INVALID, \
212  &&INVALID, \
213  &&INVALID, \
214  &&ADDRESS, /* 30, */ \
215  &&BALANCE, \
216  &&ORIGIN, \
217  &&CALLER, \
218  &&CALLVALUE, \
219  &&CALLDATALOAD, \
220  &&CALLDATASIZE, \
221  &&CALLDATACOPY, \
222  &&CODESIZE, \
223  &&CODECOPY, \
224  &&GASPRICE, \
225  &&EXTCODESIZE, \
226  &&EXTCODECOPY, \
227  &&RETURNDATASIZE, \
228  &&RETURNDATACOPY, \
229  &&EXTCODEHASH, \
230  &&BLOCKHASH, /* 40, */ \
231  &&COINBASE, \
232  &&TIMESTAMP, \
233  &&NUMBER, \
234  &&DIFFICULTY, \
235  &&GASLIMIT, \
236  &&INVALID, \
237  &&INVALID, \
238  &&INVALID, \
239  &&INVALID, \
240  &&INVALID, \
241  &&INVALID, \
242  &&INVALID, \
243  &&INVALID, \
244  &&INVALID, \
245  &&INVALID, \
246  &&POP, /* 50, */ \
247  &&MLOAD, \
248  &&MSTORE, \
249  &&MSTORE8, \
250  &&SLOAD, \
251  &&SSTORE, \
252  &&JUMP, \
253  &&JUMPI, \
254  &&PC, \
255  &&MSIZE, \
256  &&GAS, \
257  &&JUMPDEST, \
258  &&BEGINDATA, \
259  &&BEGINSUB, \
260  &&INVALID, \
261  &&INVALID, \
262  &&PUSH1, /* 60, */ \
263  &&PUSH2, \
264  &&PUSH3, \
265  &&PUSH4, \
266  &&PUSH5, \
267  &&PUSH6, \
268  &&PUSH7, \
269  &&PUSH8, \
270  &&PUSH9, \
271  &&PUSH10, \
272  &&PUSH11, \
273  &&PUSH12, \
274  &&PUSH13, \
275  &&PUSH14, \
276  &&PUSH15, \
277  &&PUSH16, \
278  &&PUSH17, /* 70, */ \
279  &&PUSH18, \
280  &&PUSH19, \
281  &&PUSH20, \
282  &&PUSH21, \
283  &&PUSH22, \
284  &&PUSH23, \
285  &&PUSH24, \
286  &&PUSH25, \
287  &&PUSH26, \
288  &&PUSH27, \
289  &&PUSH28, \
290  &&PUSH29, \
291  &&PUSH30, \
292  &&PUSH31, \
293  &&PUSH32, \
294  &&DUP1, /* 80, */ \
295  &&DUP2, \
296  &&DUP3, \
297  &&DUP4, \
298  &&DUP5, \
299  &&DUP6, \
300  &&DUP7, \
301  &&DUP8, \
302  &&DUP9, \
303  &&DUP10, \
304  &&DUP11, \
305  &&DUP12, \
306  &&DUP13, \
307  &&DUP14, \
308  &&DUP15, \
309  &&DUP16, \
310  &&SWAP1, /* 90, */ \
311  &&SWAP2, \
312  &&SWAP3, \
313  &&SWAP4, \
314  &&SWAP5, \
315  &&SWAP6, \
316  &&SWAP7, \
317  &&SWAP8, \
318  &&SWAP9, \
319  &&SWAP10, \
320  &&SWAP11, \
321  &&SWAP12, \
322  &&SWAP13, \
323  &&SWAP14, \
324  &&SWAP15, \
325  &&SWAP16, \
326  &&LOG0, /* A0, */ \
327  &&LOG1, \
328  &&LOG2, \
329  &&LOG3, \
330  &&LOG4, \
331  &&INVALID, \
332  &&INVALID, \
333  &&INVALID, \
334  &&INVALID, \
335  &&INVALID, \
336  &&INVALID, \
337  &&INVALID, \
338  &&PUSHC, \
339  &&JUMPC, \
340  &&JUMPCI, \
341  &&INVALID, \
342  &&JUMPTO, /* B0, */ \
343  &&JUMPIF, \
344  &&JUMPSUB, \
345  &&JUMPV, \
346  &&JUMPSUBV, \
347  &&BEGINSUB, \
348  &&BEGINDATA, \
349  &&RETURNSUB, \
350  &&PUTLOCAL, \
351  &&GETLOCAL, \
352  &&INVALID, \
353  &&INVALID, \
354  &&INVALID, \
355  &&INVALID, \
356  &&INVALID, \
357  &&INVALID, \
358  &&INVALID, /* C0, */ \
359  &&XADD, \
360  &&XMUL, \
361  &&XSUB, \
362  &&XDIV, \
363  &&XSDIV, \
364  &&XMOD, \
365  &&XSMOD, \
366  &&INVALID, \
367  &&INVALID, \
368  &&INVALID, \
369  &&INVALID, \
370  &&INVALID, \
371  &&INVALID, \
372  &&INVALID, \
373  &&INVALID, \
374  &&XLT, /* D0 */ \
375  &&XGT, \
376  &&XSLT, \
377  &&XSGT, \
378  &&XEQ, \
379  &&XISZERO, \
380  &&XAND, \
381  &&XOOR, \
382  &&XXOR, \
383  &&XNOT, \
384  &&INVALID, \
385  &&XSHL, \
386  &&XSHR, \
387  &&XSAR, \
388  &&XROL, \
389  &&XROR, \
390  &&XPUSH, /* E0, */ \
391  &&XMLOAD, \
392  &&XMSTORE, \
393  &&INVALID, \
394  &&XSLOAD, \
395  &&XSSTORE, \
396  &&XVTOWIDE, \
397  &&XWIDETOV, \
398  &&XGET, \
399  &&XPUT, \
400  &&XSWIZZLE, \
401  &&XSHUFFLE, \
402  &&INVALID, \
403  &&INVALID, \
404  &&INVALID, \
405  &&INVALID, \
406  &&CREATE, /* F0, */ \
407  &&CALL, \
408  &&CALLCODE, \
409  &&RETURN, \
410  &&DELEGATECALL, \
411  &&CREATE2, \
412  &&INVALID, \
413  &&INVALID, \
414  &&INVALID, \
415  &&INVALID, \
416  &&STATICCALL, \
417  &&INVALID, \
418  &&INVALID, \
419  &&REVERT, \
420  &&INVALID, \
421  &&SUICIDE, \
422  };
423 
424 #define DO_CASES \
425  fetchInstruction(); \
426  goto* jumpTable[(int)m_OP];
427 #define CASE(name) \
428  name:
429 #define NEXT \
430  ++m_PC; \
431  fetchInstruction(); \
432  goto* jumpTable[(int)m_OP];
433 #define CONTINUE \
434  fetchInstruction(); \
435  goto* jumpTable[(int)m_OP];
436 #define BREAK return;
437 #define DEFAULT
438 #define WHILE_CASES
439 
440 #else
441 #error No opcode dispatch configured
442 #endif
443  }
444  }
dev
Definition: Address.cpp:21