Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 290 lines (252 sloc) 7.984 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
118 default:
f4a48b2 @Benabik disasm: Move printing of type
Benabik authored
119 print(typeof(vi), ' ');
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
120 try {
121 say(get_repr(vi));
122 } catch() {
123 try {
124 say(string(vi));
125 } catch() {
126 say('(Unprintable)');
127 }
128 }
129 }
130 }
131 say(".end\n");
132
133 // Oplibs
134 for (s in packfile.oplibs)
135 if (s != 'core_ops')
d0a2ada @Benabik disasm: switch from say(a + b) to say(a, b)
Benabik authored
136 say('.oplib ', s);
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
137
138 // Subs
139 show_namespace(sub_map, sc_map, packfile.root);
140 }
141
142 function show_namespace(var sub_map, var sc_map, var ns, var path = []) {
143 for (string s in ns.contents) {
144 var v = ns.contents[s];
145 switch(typeof(v)) {
146 case 'PACT;Packfile;Subroutine':
d0a2ada @Benabik disasm: switch from say(a + b) to say(a, b)
Benabik authored
147 say('.sub ', sub_map[v]);
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
148 show_sub(sc_map, v);
149 say('.end');
150 say();
151 break;
152 case 'PACT;Packfile;Namespace':
153 push(path, sc_map[s]);
154 print('.namespace sc');
155 print(path[0]);
156 for(int i = 1; i < elements(path); ++i) {
157 print(', sc');
158 print(path[i]);
159 }
160 say("\n"); // Yes, two newlines
161 show_namespace(sub_map, sc_map, v);
162 break;
05dc11a @Benabik disasm: Print multi candidates
Benabik authored
163
164 case 'PACT;Packfile;Multi':
165 for(var sub in v.canidates) {
d0a2ada @Benabik disasm: switch from say(a + b) to say(a, b)
Benabik authored
166 say('.sub ', sub_map[sub]);
05dc11a @Benabik disasm: Print multi candidates
Benabik authored
167 show_sub(sc_map, sub);
168 say('.end');
169 say();
170 }
171 break;
172
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
173 default:
174 die('Object of unexpected type (' + string(typeof(v))
175 + ') found in namespace');
176 }
177 }
178 }
179
180 function show_sub(var sc_map, var sub) {
181 string label;
182 for(var op in sub.ops) {
183 switch(typeof(op)) {
184 case 'PACT;Packfile;Debug':
d0a2ada @Benabik disasm: switch from say(a + b) to say(a, b)
Benabik authored
185 say('.debug sc', sc_map[op.filename]);
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
186 break;
187 case 'PACT;Packfile;Annotation':
d0a2ada @Benabik disasm: switch from say(a + b) to say(a, b)
Benabik authored
188 print('.annotate sc', sc_map[op.name], ', ');
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
189 var c = op.value;
190 switch(typeof(c)) {
191 case 'PACT;Packfile;Constant;Reference':
192 if(c.type != PARROT_ARG_STRING)
193 die("Unexpected annotation constant reference type " +
194 c.type);
d0a2ada @Benabik disasm: switch from say(a + b) to say(a, b)
Benabik authored
195 say('sc', c.value);
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
196 break;
197
198 case 'PACT;Packfile;Constant':
199 switch(c.type) {
200 case PARROT_ARG_INTVAL:
201 say(c.value);
202 break;
203 case PARROT_ARG_STRING:
d0a2ada @Benabik disasm: switch from say(a + b) to say(a, b)
Benabik authored
204 say('sc', sc_map[c.value]);
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
205 break;
206 default:
207 die("Unexpected annotation constant type " + c.type);
208 }
209 break;
210
211 default:
212 die("Unexpected annotation value type " + string(typeof(c)));
213 }
214 break;
215
216 case 'PACT;Packfile;Label':
217 if (label != null)
d0a2ada @Benabik disasm: switch from say(a + b) to say(a, b)
Benabik authored
218 say(label, ':');
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
219
220 if (length(op.name) < 7)
221 label = op.name;
222 else
d0a2ada @Benabik disasm: switch from say(a + b) to say(a, b)
Benabik authored
223 say(op.name, ':');
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
224
225 break;
226
227 case 'PACT;Packfile;Op':
d0a2ada @Benabik disasm: switch from say(a + b) to say(a, b)
Benabik authored
228 print(label, ":\t");
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
229 label = null;
230 print(op.name);
231
232 var args = op.args;
233 for(int i = 0; i < elements(args); ++i) {
234 print( i == 0 ? ' ' : ', ' );
e8e6a43 @Benabik disasm: Separate out displaying op argument
Benabik authored
235 show_argument(sc_map, args[i]);
236 }
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
237
e8e6a43 @Benabik disasm: Separate out displaying op argument
Benabik authored
238 say();
239 break;
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
240
e8e6a43 @Benabik disasm: Separate out displaying op argument
Benabik authored
241 default:
242 die("Unknown sub contents type " + string(typeof(op)));
243 }
244 }
245 }
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
246
e8e6a43 @Benabik disasm: Separate out displaying op argument
Benabik authored
247 function show_argument(var sc_map, var arg) {
248 switch(typeof(arg)) {
249 case 'PACT;Packfile;Constant;Reference':
250 switch(arg.type) {
251 case PARROT_ARG_INTVAL: die('Integer reference?');
252 case PARROT_ARG_STRING: print('sc'); break;
253 case PARROT_ARG_PMC: print('pc'); break;
254 case PARROT_ARG_FLOATVAL: print('fc'); break;
255 default: die('Unknown constref type ' + string(arg.type));
256 }
257 print(arg.value);
258 break;
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
259
e8e6a43 @Benabik disasm: Separate out displaying op argument
Benabik authored
260 case 'PACT;Packfile;Constant':
261 switch(arg.type) {
262 case PARROT_ARG_INTVAL:
263 print(arg.value);
264 break;
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
265
e8e6a43 @Benabik disasm: Separate out displaying op argument
Benabik authored
266 case PARROT_ARG_STRING:
267 print('sc', string(sc_map[arg.value]));
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
268 break;
269
270 default:
e8e6a43 @Benabik disasm: Separate out displaying op argument
Benabik authored
271 die('Unexpected constant type ' + string(arg.type));
272 }
273 break;
274
275 case 'PACT;Packfile;Register':
276 switch(arg.type) {
277 case PARROT_ARG_INTVAL: print('i'); break;
278 case PARROT_ARG_STRING: print('s'); break;
279 case PARROT_ARG_PMC: print('p'); break;
280 case PARROT_ARG_FLOATVAL: print('f'); break;
281 default: die('Unknown register type ' + string(arg.type));
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
282 }
e8e6a43 @Benabik disasm: Separate out displaying op argument
Benabik authored
283 print(arg.number);
284 break;
285
286 default:
287 die('Unknown argument type ' + string(typeof(arg)));
47b2f25 @Benabik disasm: Initial assembly output
Benabik authored
288 }
a4dd2e5 @Benabik Toy Disassembler
Benabik authored
289 }
Something went wrong with that request. Please try again.