Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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