Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 304 lines (264 sloc) 8.337 kb
c709187 @Benabik Add copyright and license information
Benabik authored
1 // Copyright (C) 2011-2012, Parrot Foundation.
2
0751553 @Benabik disasm: read packfile into Packfile classes
Benabik authored
3 // Basic disassembler to demonstrate the PACT.Packfile classes
a4dd2e5 @Benabik Toy Disassembler
Benabik authored
4
d05e70f @Benabik disasm: Use Winxed $directives
Benabik authored
5 // Load disassembler
6 $include 'PACT/Packfile/Decompile.winxed';
7 $load 'PACT/Packfile/Decompile.pbc';
a4dd2e5 @Benabik Toy Disassembler
Benabik authored
8
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
9 $include_const 'call_bits.pasm';
b2b50d7 @Benabik disasm: Catch up with the new Subroutine world
Benabik authored
10 $include_const 'hash_key_type.pasm';
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
11
12 // Useful opcode
13 inline get_repr(var v) return string {
14 string ret;
15 ${ get_repr ret, v };
16 return ret;
17 }
18
d05e70f @Benabik disasm: Use Winxed $directives
Benabik authored
19 function main[main](var argv) {
0751553 @Benabik disasm: read packfile into Packfile classes
Benabik authored
20 // Process arguments
21 string progname = argv[0];
22 if (elements(argv) != 2) {
23 cry('Usage: ', progname, ' <PBC file>');
24 exit(1);
25 }
26 string filename = argv[1];
27
28 // Get a Packfile
29 var packfile;
30 try {
e1b0435 @Benabik Introducing PACT.Packfile.Decompile
Benabik authored
31 :PACT.Packfile.Decompile decomp(filename);
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
32 packfile = decomp.pact;
0751553 @Benabik disasm: read packfile into Packfile classes
Benabik authored
33 } catch (e) {
34 cry( progname, ': Error during disassembly ', filename );
35 cry( e.message );
36 for ( string bt in e.backtrace_strings() )
37 cry(bt);
38 exit(1);
39 }
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
40
41 // Version number
42 say(".pact pbc 0\n");
43
44 // Constants
45 int i;
46 string s;
47 var v;
48 var vi;
49 var sc_map = {};
50 say('.constants num');
51 v = packfile.floats;
52 for (i = 0; i < elements(v); ++i)
d0a2ada @Benabik disasm: switch from say(a + b) to say(a, b)
Benabik authored
53 say(i, ' ', v[i]);
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
54 say(".end\n");
55
56 say('.constants string');
57 v = packfile.strings;
58 for (i = 0; i < elements(v); ++i) {
59 s = v[i];
60 print(string(i));
61 if(s == null) {
1e6843f @Benabik disasm: minor change to null output
Benabik authored
62 say(' # null');
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
63 } else {
d0a2ada @Benabik disasm: switch from say(a + b) to say(a, b)
Benabik authored
64 say(' ', encoding_name(s), ' "', escape(s), '"');
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
65 sc_map[s] = i;
66 }
67 }
68 say(".end\n");
69
70 say('.constants pmc');
71 v = packfile.pmcs;
72 var sub_map = {};
b2b50d7 @Benabik disasm: Catch up with the new Subroutine world
Benabik authored
73 sub_map.set_key_type(Hash_key_type_PMC_ptr);
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
74 for (i = 0; i < elements(v); ++i) {
75 vi = v[i];
f4a48b2 @Benabik disasm: Move printing of type
Benabik authored
76 print(i, ' ');
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
77 switch(typeof(vi)) {
b2b50d7 @Benabik disasm: Catch up with the new Subroutine world
Benabik authored
78 case 'PACT;Packfile;Subroutine':
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
79 // label, name, options
80 sub_map[vi] = s = '_sub' + string(i);
f4a48b2 @Benabik disasm: Move printing of type
Benabik authored
81 print('Sub ', s, ', sc', sc_map[vi.name]);
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
82 // TODO: main, tags, subid, multi, etc
73b1149 @Benabik Store and print multisigs
Benabik authored
83
84 if (vi.multi_sig != null) {
85 print(', multi (');
86 int comma = 0;
87 for (var arg in vi.multi_sig) {
88 if (comma)
89 print(', ');
90 else
91 comma = 1;
92
93 switch(typeof(arg)) {
94 case 'Integer':
95 switch(int(arg)) {
96 case -1: print('i'); break;
97 case -2: print('f'); break;
98 case -3: print('s'); break;
99 case -4: print('p'); break;
100 default: print(arg); break; // XXX: What is this?
101 }
102 break;
103
104 case 'String':
d0a2ada @Benabik disasm: switch from say(a + b) to say(a, b)
Benabik authored
105 print('sc', sc_map[arg]);
73b1149 @Benabik Store and print multisigs
Benabik authored
106 break;
107
108 default:
109 die('Unexpected type in multi_sig');
110 }
111 }
112 print(')');
113 }
114
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
115 say();
116 break;
117
d17a7b4 @Benabik disasm: Show Keys
Benabik authored
118 case 'PACT;Packfile;Constant;Key':
119 print('Key [ ');
120 int comma = 0;
121 for (var arg in vi.value) {
122 if (comma)
123 print(', ');
124 else
125 comma = 1;
126
127 show_argument(sc_map, arg);
128 }
129 say(' ]');
130 break;
131
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
132 default:
f4a48b2 @Benabik disasm: Move printing of type
Benabik authored
133 print(typeof(vi), ' ');
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
134 try {
135 say(get_repr(vi));
136 } catch() {
137 try {
138 say(string(vi));
139 } catch() {
140 say('(Unprintable)');
141 }
142 }
143 }
144 }
145 say(".end\n");
146
147 // Oplibs
148 for (s in packfile.oplibs)
149 if (s != 'core_ops')
d0a2ada @Benabik disasm: switch from say(a + b) to say(a, b)
Benabik authored
150 say('.oplib ', s);
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
151
152 // Subs
153 show_namespace(sub_map, sc_map, packfile.root);
154 }
155
156 function show_namespace(var sub_map, var sc_map, var ns, var path = []) {
157 for (string s in ns.contents) {
158 var v = ns.contents[s];
159 switch(typeof(v)) {
160 case 'PACT;Packfile;Subroutine':
d0a2ada @Benabik disasm: switch from say(a + b) to say(a, b)
Benabik authored
161 say('.sub ', sub_map[v]);
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
162 show_sub(sc_map, v);
163 say('.end');
164 say();
165 break;
166 case 'PACT;Packfile;Namespace':
167 push(path, sc_map[s]);
168 print('.namespace sc');
169 print(path[0]);
170 for(int i = 1; i < elements(path); ++i) {
171 print(', sc');
172 print(path[i]);
173 }
174 say("\n"); // Yes, two newlines
175 show_namespace(sub_map, sc_map, v);
176 break;
05dc11a @Benabik disasm: Print multi candidates
Benabik authored
177
178 case 'PACT;Packfile;Multi':
179 for(var sub in v.canidates) {
d0a2ada @Benabik disasm: switch from say(a + b) to say(a, b)
Benabik authored
180 say('.sub ', sub_map[sub]);
05dc11a @Benabik disasm: Print multi candidates
Benabik authored
181 show_sub(sc_map, sub);
182 say('.end');
183 say();
184 }
185 break;
186
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
187 default:
188 die('Object of unexpected type (' + string(typeof(v))
189 + ') found in namespace');
190 }
191 }
192 }
193
194 function show_sub(var sc_map, var sub) {
195 string label;
196 for(var op in sub.ops) {
197 switch(typeof(op)) {
198 case 'PACT;Packfile;Debug':
d0a2ada @Benabik disasm: switch from say(a + b) to say(a, b)
Benabik authored
199 say('.debug sc', sc_map[op.filename]);
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
200 break;
201 case 'PACT;Packfile;Annotation':
d0a2ada @Benabik disasm: switch from say(a + b) to say(a, b)
Benabik authored
202 print('.annotate sc', sc_map[op.name], ', ');
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
203 var c = op.value;
204 switch(typeof(c)) {
205 case 'PACT;Packfile;Constant;Reference':
206 if(c.type != PARROT_ARG_STRING)
207 die("Unexpected annotation constant reference type " +
208 c.type);
d0a2ada @Benabik disasm: switch from say(a + b) to say(a, b)
Benabik authored
209 say('sc', c.value);
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
210 break;
211
212 case 'PACT;Packfile;Constant':
213 switch(c.type) {
214 case PARROT_ARG_INTVAL:
215 say(c.value);
216 break;
217 case PARROT_ARG_STRING:
d0a2ada @Benabik disasm: switch from say(a + b) to say(a, b)
Benabik authored
218 say('sc', sc_map[c.value]);
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
219 break;
220 default:
221 die("Unexpected annotation constant type " + c.type);
222 }
223 break;
224
225 default:
226 die("Unexpected annotation value type " + string(typeof(c)));
227 }
228 break;
229
230 case 'PACT;Packfile;Label':
231 if (label != null)
d0a2ada @Benabik disasm: switch from say(a + b) to say(a, b)
Benabik authored
232 say(label, ':');
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
233
234 if (length(op.name) < 7)
235 label = op.name;
236 else
d0a2ada @Benabik disasm: switch from say(a + b) to say(a, b)
Benabik authored
237 say(op.name, ':');
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
238
239 break;
240
241 case 'PACT;Packfile;Op':
d0a2ada @Benabik disasm: switch from say(a + b) to say(a, b)
Benabik authored
242 print(label, ":\t");
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
243 label = null;
244 print(op.name);
245
246 var args = op.args;
247 for(int i = 0; i < elements(args); ++i) {
248 print( i == 0 ? ' ' : ', ' );
e8e6a43 @Benabik disasm: Separate out displaying op argument
Benabik authored
249 show_argument(sc_map, args[i]);
250 }
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
251
e8e6a43 @Benabik disasm: Separate out displaying op argument
Benabik authored
252 say();
253 break;
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
254
e8e6a43 @Benabik disasm: Separate out displaying op argument
Benabik authored
255 default:
256 die("Unknown sub contents type " + string(typeof(op)));
257 }
258 }
259 }
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
260
e8e6a43 @Benabik disasm: Separate out displaying op argument
Benabik authored
261 function show_argument(var sc_map, var arg) {
262 switch(typeof(arg)) {
263 case 'PACT;Packfile;Constant;Reference':
264 switch(arg.type) {
265 case PARROT_ARG_INTVAL: die('Integer reference?');
266 case PARROT_ARG_STRING: print('sc'); break;
267 case PARROT_ARG_PMC: print('pc'); break;
268 case PARROT_ARG_FLOATVAL: print('fc'); break;
269 default: die('Unknown constref type ' + string(arg.type));
270 }
271 print(arg.value);
272 break;
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
273
e8e6a43 @Benabik disasm: Separate out displaying op argument
Benabik authored
274 case 'PACT;Packfile;Constant':
275 switch(arg.type) {
276 case PARROT_ARG_INTVAL:
277 print(arg.value);
278 break;
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
279
e8e6a43 @Benabik disasm: Separate out displaying op argument
Benabik authored
280 case PARROT_ARG_STRING:
281 print('sc', string(sc_map[arg.value]));
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
282 break;
283
284 default:
e8e6a43 @Benabik disasm: Separate out displaying op argument
Benabik authored
285 die('Unexpected constant type ' + string(arg.type));
286 }
287 break;
288
289 case 'PACT;Packfile;Register':
290 switch(arg.type) {
291 case PARROT_ARG_INTVAL: print('i'); break;
292 case PARROT_ARG_STRING: print('s'); break;
293 case PARROT_ARG_PMC: print('p'); break;
294 case PARROT_ARG_FLOATVAL: print('f'); break;
295 default: die('Unknown register type ' + string(arg.type));
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
296 }
e8e6a43 @Benabik disasm: Separate out displaying op argument
Benabik authored
297 print(arg.number);
298 break;
299
300 default:
301 die('Unknown argument type ' + string(typeof(arg)));
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
302 }
a4dd2e5 @Benabik Toy Disassembler
Benabik authored
303 }
Something went wrong with that request. Please try again.