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