Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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