Commit 85a5bcd197e051e35c4d05c3471529481eeddeda
Merge pull request #13 from ewasm/stackTrace
Stack tracewanderer authored on 8/5/2016, 7:12:18 PM
GitHub committed on 8/5/2016, 7:12:18 PM
Parent: bea202f2fdf8d657062f28fac0fbd23060d6fad3
Parent: 29003849d596ca5f1379096bd408c4c1f82c460f
Files changed
debugInterface.js | changed |
opcodes.js | added |
debugInterface.js | ||
---|---|---|
@@ -1,4 +1,6 @@ | ||
1 | +const opcodes = require('./opcodes.js') | |
2 | + | |
1 | 3 | /** |
2 | 4 | * Debug Interface |
3 | 5 | * This expose some functions that can help with debugging wast |
4 | 6 | */ |
@@ -8,13 +10,9 @@ | ||
8 | 10 | return String.fromCharCode.apply(null, input) |
9 | 11 | } |
10 | 12 | |
11 | 13 | function Uint8ArrayToHexString (input) { |
12 | - var ret = '' | |
13 | - for (var i = 0; i < input.length; i++) { | |
14 | - ret += input[i].toString(16) | |
15 | - } | |
16 | - return ret | |
14 | + return new Buffer(input).toString('hex') | |
17 | 15 | } |
18 | 16 | |
19 | 17 | module.exports = class DebugInterface { |
20 | 18 | setModule (mod) { |
@@ -28,8 +26,21 @@ | ||
28 | 26 | }.bind(this), |
29 | 27 | |
30 | 28 | 'printHex': function (offset, length) { |
31 | 29 | console.log(`<DEBUG(hex): ${Uint8ArrayToHexString(new Uint8Array(this.module.exports.memory, offset, length))}>`) |
30 | + }.bind(this), | |
31 | + | |
32 | + 'evmStackTrace': function (sp, op) { | |
33 | + const opcode = opcodes(op) | |
34 | + if (opcode.number) { | |
35 | + opcode.name += opcode.number | |
36 | + } | |
37 | + console.error(opcode.name) | |
38 | + console.log('-------------stack--------------') | |
39 | + for (let i = sp; i > 0; i -= 32) { | |
40 | + console.log(`${(sp - i) / 32} ${Uint8ArrayToHexString(new Uint8Array(this.module.exports.memory, i - 24, 32))}`) | |
41 | + } | |
42 | + return sp | |
32 | 43 | }.bind(this) |
33 | 44 | } |
34 | 45 | } |
35 | 46 | } |
opcodes.js | ||
---|---|---|
@@ -1,0 +1,187 @@ | ||
1 | +const codes = { | |
2 | + // 0x0 range - arithmetic ops | |
3 | + // name, baseCost, off stack, on stack, dynamic | |
4 | + 0x00: ['STOP', 0, 0, 0, false], | |
5 | + 0x01: ['ADD', 3, 2, 1, false], | |
6 | + 0x02: ['MUL', 5, 2, 1, false], | |
7 | + 0x03: ['SUB', 3, 2, 1, false], | |
8 | + 0x04: ['DIV', 5, 2, 1, false], | |
9 | + 0x05: ['SDIV', 5, 2, 1, false], | |
10 | + 0x06: ['MOD', 5, 2, 1, false], | |
11 | + 0x07: ['SMOD', 5, 2, 1, false], | |
12 | + 0x08: ['ADDMOD', 8, 3, 1, false], | |
13 | + 0x09: ['MULMOD', 8, 3, 1, false], | |
14 | + 0x0a: ['EXP', 10, 2, 1, false], | |
15 | + 0x0b: ['SIGNEXTEND', 5, 1, 1, false], | |
16 | + | |
17 | + // 0x10 range - bit ops | |
18 | + 0x10: ['LT', 3, 2, 1, false], | |
19 | + 0x11: ['GT', 3, 2, 1, false], | |
20 | + 0x12: ['SLT', 3, 2, 1, false], | |
21 | + 0x13: ['SGT', 3, 2, 1, false], | |
22 | + 0x14: ['EQ', 3, 2, 1, false], | |
23 | + 0x15: ['ISZERO', 3, 1, 1, false], | |
24 | + 0x16: ['AND', 3, 2, 1, false], | |
25 | + 0x17: ['OR', 3, 2, 1, false], | |
26 | + 0x18: ['XOR', 3, 2, 1, false], | |
27 | + 0x19: ['NOT', 3, 1, 1, false], | |
28 | + 0x1a: ['BYTE', 3, 2, 1, false], | |
29 | + | |
30 | + // 0x20 range - crypto | |
31 | + 0x20: ['SHA3', 30, 2, 1, false], | |
32 | + | |
33 | + // 0x30 range - closure state | |
34 | + 0x30: ['ADDRESS', 2, 0, 1, true], | |
35 | + 0x31: ['BALANCE', 20, 1, 1, true], | |
36 | + 0x32: ['ORIGIN', 2, 0, 1, true], | |
37 | + 0x33: ['CALLER', 2, 0, 1, true], | |
38 | + 0x34: ['CALLVALUE', 2, 0, 1, true], | |
39 | + 0x35: ['CALLDATALOAD', 3, 1, 1, true], | |
40 | + 0x36: ['CALLDATASIZE', 2, 0, 1, true], | |
41 | + 0x37: ['CALLDATACOPY', 3, 3, 0, true], | |
42 | + 0x38: ['CODESIZE', 2, 0, 1, false], | |
43 | + 0x39: ['CODECOPY', 3, 3, 0, false], | |
44 | + 0x3a: ['GASPRICE', 2, 0, 1, false], | |
45 | + 0x3b: ['EXTCODESIZE', 20, 1, 1, true], | |
46 | + 0x3c: ['EXTCODECOPY', 20, 4, 0, true], | |
47 | + | |
48 | + // '0x40' range - block operations | |
49 | + 0x40: ['BLOCKHASH', 20, 1, 1, true], | |
50 | + 0x41: ['COINBASE', 2, 0, 1, true], | |
51 | + 0x42: ['TIMESTAMP', 2, 0, 1, true], | |
52 | + 0x43: ['NUMBER', 2, 0, 1, true], | |
53 | + 0x44: ['DIFFICULTY', 2, 0, 1, true], | |
54 | + 0x45: ['GASLIMIT', 2, 0, 1, true], | |
55 | + | |
56 | + // 0x50 range - 'storage' and execution | |
57 | + 0x50: ['POP', 2, 1, 0, false], | |
58 | + 0x51: ['MLOAD', 3, 1, 1, false], | |
59 | + 0x52: ['MSTORE', 3, 2, 0, false], | |
60 | + 0x53: ['MSTORE8', 3, 2, 0, false], | |
61 | + 0x54: ['SLOAD', 50, 1, 1, true], | |
62 | + 0x55: ['SSTORE', 5000, 2, 0, true], | |
63 | + 0x56: ['JUMP', 8, 1, 0, false], | |
64 | + 0x57: ['JUMPI', 10, 2, 0, false], | |
65 | + 0x58: ['PC', 2, 0, 1, false], | |
66 | + 0x59: ['MSIZE', 2, 0, 1, false], | |
67 | + 0x5a: ['GAS', 2, 0, 1, false], | |
68 | + 0x5b: ['JUMPDEST', 1, 0, 0, false], | |
69 | + | |
70 | + // 0x60, range | |
71 | + 0x60: ['PUSH', 3, 0, 1, false], | |
72 | + 0x61: ['PUSH', 3, 0, 1, false], | |
73 | + 0x62: ['PUSH', 3, 0, 1, false], | |
74 | + 0x63: ['PUSH', 3, 0, 1, false], | |
75 | + 0x64: ['PUSH', 3, 0, 1, false], | |
76 | + 0x65: ['PUSH', 3, 0, 1, false], | |
77 | + 0x66: ['PUSH', 3, 0, 1, false], | |
78 | + 0x67: ['PUSH', 3, 0, 1, false], | |
79 | + 0x68: ['PUSH', 3, 0, 1, false], | |
80 | + 0x69: ['PUSH', 3, 0, 1, false], | |
81 | + 0x6a: ['PUSH', 3, 0, 1, false], | |
82 | + 0x6b: ['PUSH', 3, 0, 1, false], | |
83 | + 0x6c: ['PUSH', 3, 0, 1, false], | |
84 | + 0x6d: ['PUSH', 3, 0, 1, false], | |
85 | + 0x6e: ['PUSH', 3, 0, 1, false], | |
86 | + 0x6f: ['PUSH', 3, 0, 1, false], | |
87 | + 0x70: ['PUSH', 3, 0, 1, false], | |
88 | + 0x71: ['PUSH', 3, 0, 1, false], | |
89 | + 0x72: ['PUSH', 3, 0, 1, false], | |
90 | + 0x73: ['PUSH', 3, 0, 1, false], | |
91 | + 0x74: ['PUSH', 3, 0, 1, false], | |
92 | + 0x75: ['PUSH', 3, 0, 1, false], | |
93 | + 0x76: ['PUSH', 3, 0, 1, false], | |
94 | + 0x77: ['PUSH', 3, 0, 1, false], | |
95 | + 0x78: ['PUSH', 3, 0, 1, false], | |
96 | + 0x79: ['PUSH', 3, 0, 1, false], | |
97 | + 0x7a: ['PUSH', 3, 0, 1, false], | |
98 | + 0x7b: ['PUSH', 3, 0, 1, false], | |
99 | + 0x7c: ['PUSH', 3, 0, 1, false], | |
100 | + 0x7d: ['PUSH', 3, 0, 1, false], | |
101 | + 0x7e: ['PUSH', 3, 0, 1, false], | |
102 | + 0x7f: ['PUSH', 3, 0, 1, false], | |
103 | + | |
104 | + 0x80: ['DUP', 3, 0, 1, false], | |
105 | + 0x81: ['DUP', 3, 0, 1, false], | |
106 | + 0x82: ['DUP', 3, 0, 1, false], | |
107 | + 0x83: ['DUP', 3, 0, 1, false], | |
108 | + 0x84: ['DUP', 3, 0, 1, false], | |
109 | + 0x85: ['DUP', 3, 0, 1, false], | |
110 | + 0x86: ['DUP', 3, 0, 1, false], | |
111 | + 0x87: ['DUP', 3, 0, 1, false], | |
112 | + 0x88: ['DUP', 3, 0, 1, false], | |
113 | + 0x89: ['DUP', 3, 0, 1, false], | |
114 | + 0x8a: ['DUP', 3, 0, 1, false], | |
115 | + 0x8b: ['DUP', 3, 0, 1, false], | |
116 | + 0x8c: ['DUP', 3, 0, 1, false], | |
117 | + 0x8d: ['DUP', 3, 0, 1, false], | |
118 | + 0x8e: ['DUP', 3, 0, 1, false], | |
119 | + 0x8f: ['DUP', 3, 0, 1, false], | |
120 | + | |
121 | + 0x90: ['SWAP', 3, 0, 0, false], | |
122 | + 0x91: ['SWAP', 3, 0, 0, false], | |
123 | + 0x92: ['SWAP', 3, 0, 0, false], | |
124 | + 0x93: ['SWAP', 3, 0, 0, false], | |
125 | + 0x94: ['SWAP', 3, 0, 0, false], | |
126 | + 0x95: ['SWAP', 3, 0, 0, false], | |
127 | + 0x96: ['SWAP', 3, 0, 0, false], | |
128 | + 0x97: ['SWAP', 3, 0, 0, false], | |
129 | + 0x98: ['SWAP', 3, 0, 0, false], | |
130 | + 0x99: ['SWAP', 3, 0, 0, false], | |
131 | + 0x9a: ['SWAP', 3, 0, 0, false], | |
132 | + 0x9b: ['SWAP', 3, 0, 0, false], | |
133 | + 0x9c: ['SWAP', 3, 0, 0, false], | |
134 | + 0x9d: ['SWAP', 3, 0, 0, false], | |
135 | + 0x9e: ['SWAP', 3, 0, 0, false], | |
136 | + 0x9f: ['SWAP', 3, 0, 0, false], | |
137 | + | |
138 | + 0xa0: ['LOG', 375, 2, 0, false], | |
139 | + 0xa1: ['LOG', 375, 3, 0, false], | |
140 | + 0xa2: ['LOG', 375, 4, 0, false], | |
141 | + 0xa3: ['LOG', 375, 5, 0, false], | |
142 | + 0xa4: ['LOG', 375, 6, 0, false], | |
143 | + | |
144 | + // '0xf0' range - closures | |
145 | + 0xf0: ['CREATE', 32000, 3, 1, true], | |
146 | + 0xf1: ['CALL', 40, 7, 1, true], | |
147 | + 0xf2: ['CALLCODE', 40, 7, 1, true], | |
148 | + 0xf3: ['RETURN', 0, 2, 0, false], | |
149 | + 0xf4: ['DELEGATECALL', 40, 6, 1, true], | |
150 | + | |
151 | + // '0x70', range - other | |
152 | + 0xff: ['SUICIDE', 0, 1, 0, false] | |
153 | +} | |
154 | + | |
155 | +module.exports = function (op) { | |
156 | + const code = codes[op] ? codes[op] : ['INVALID', 0] | |
157 | + let opcode = code[0] | |
158 | + let number | |
159 | + | |
160 | + switch (opcode) { | |
161 | + case 'LOG': | |
162 | + number = op - 0xa0 | |
163 | + break | |
164 | + | |
165 | + case 'PUSH': | |
166 | + number = op - 0x5f | |
167 | + break | |
168 | + | |
169 | + case 'DUP': | |
170 | + number = op - 0x7f | |
171 | + break | |
172 | + | |
173 | + case 'SWAP': | |
174 | + number = op - 0x8f | |
175 | + break | |
176 | + } | |
177 | + | |
178 | + return { | |
179 | + name: opcode, | |
180 | + fee: code[1], | |
181 | + in: code[2], | |
182 | + out: code[3], | |
183 | + dynamic: code[4], | |
184 | + async: code[5], | |
185 | + number: number | |
186 | + } | |
187 | +} |
Built with git-ssb-web