KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > python > compiler > Code


1 // Copyright (c) Corporation for National Research Initiatives
2

3 package org.python.compiler;
4
5 import java.io.*;
6 import java.util.Vector JavaDoc;
7
8 class ExceptionLabel
9 {
10     public Label start, end, handler;
11     public int exc;
12
13     public ExceptionLabel(Label start, Label end, Label handler, int exc) {
14         this.start = start;
15         this.end = end;
16         this.handler = handler;
17         this.exc = exc;
18     }
19 }
20
21
22 public class Code extends Attribute
23 {
24     ConstantPool pool;
25     public int stack;
26     int max_stack;
27     public DataOutputStream code;
28     ByteArrayOutputStream stream;
29     String JavaDoc sig;
30     String JavaDoc locals[];
31     int nlocals;
32     int argcount;
33     int att_name;
34     Vector JavaDoc labels, exceptions;
35     LineNumberTable linenumbers;
36     int returnLocal;
37
38     public Label getLabel() {
39         Label l = new Label(this);
40         addLabel(l);
41         return l;
42     }
43
44     public void addLabel(Label l) {
45         labels.addElement(l);
46     }
47
48     public int size() {
49         return stream.size();
50     }
51
52     public Code(String JavaDoc sig, ConstantPool pool, boolean isStatic) {
53         this.sig = sig;
54         max_stack = 2;
55         stack = 0;
56         this.pool = pool;
57         stream = new ByteArrayOutputStream();
58         code = new DataOutputStream(stream);
59         nlocals = -ConstantPool.sigSize(sig, false);
60         if (!isStatic) nlocals = nlocals+1;
61         argcount = nlocals;
62         locals = new String JavaDoc[nlocals+128];
63         labels = new Vector JavaDoc();
64         exceptions = new Vector JavaDoc();
65         try {
66             att_name = pool.UTF8("Code");
67         } catch (IOException e) {
68             att_name=0;
69         }
70     }
71
72     public int getLocal(String JavaDoc type) {
73         //Could optimize this to skip arguments?
74
for(int l = argcount; l<nlocals; l++) {
75             if (locals[l] == null) {
76                 locals[l] = type;
77                 return l;
78             }
79         }
80         if (nlocals >= locals.length) {
81             String JavaDoc[] new_locals = new String JavaDoc[locals.length*2];
82             System.arraycopy(locals, 0, new_locals, 0, locals.length);
83             locals = new_locals;
84         }
85         locals[nlocals] = type;
86         nlocals += 1;
87         return nlocals-1;
88     }
89
90     public void freeLocal(int l) {
91         if (locals[l] == null)
92             System.out.println("Double free:" + l);
93         locals[l] = null;
94     }
95
96
97     java.util.BitSet JavaDoc finallyLocals = new java.util.BitSet JavaDoc();
98
99     public int getFinallyLocal(String JavaDoc type) {
100         int l = getLocal(type);
101         finallyLocals.set(l);
102         return l;
103     }
104
105     public void freeFinallyLocal(int l) {
106         finallyLocals.clear(l);
107         freeLocal(l);
108     }
109
110     public int getReturnLocal() {
111         if (returnLocal == 0)
112             returnLocal = getLocal("return");
113         return returnLocal;
114     }
115
116     public Vector JavaDoc getActiveLocals() {
117         Vector JavaDoc ret = new Vector JavaDoc();
118         ret.setSize(nlocals);
119         for (int l = argcount; l<nlocals; l++) {
120             if (l == returnLocal || finallyLocals.get(l))
121                 continue;
122             ret.setElementAt(locals[l], l);
123         }
124         return ret;
125     }
126
127     public void addExceptionHandler(Label begin, Label end,
128                                     Label handler, int exc)
129     {
130         exceptions.addElement(new ExceptionLabel(begin, end, handler, exc));
131     }
132
133     /*
134       cl = self.code_length()
135       self.length = cl+12+8*len(self.exc_table)
136       cw.put2(self.name)
137       cw.put4(self.length)
138       cw.put2(self.max_stack)
139       cw.put2(len(self.locals))
140       cw.put4(cl)
141       self.dump_code(cw)
142       cw.put2(len(self.exc_table))
143       for start, end, handler, exc in self.exc_table:
144       cw.put2(self.labels[start])
145       cw.put2(self.labels[end])
146       cw.put2(self.labels[handler])
147       cw.put2(exc)
148       cw.dump_attributes(self.attributes)
149     */

150
151     public void fixLabels(byte[] bytes) throws IOException {
152         for(int i=0; i<labels.size(); i++) {
153             ((Label)labels.elementAt(i)).fix(bytes);
154         }
155     }
156
157     public void write(DataOutputStream stream) throws IOException {
158         byte[] bytes = this.stream.toByteArray();
159
160         fixLabels(bytes);
161
162         int n = exceptions.size();
163         int length = bytes.length+12+8*n;;
164         if (linenumbers != null)
165             length += linenumbers.length();
166         stream.writeShort(att_name);
167         stream.writeInt(length);
168         stream.writeShort(max_stack);
169         stream.writeShort(nlocals);
170         stream.writeInt(bytes.length);
171         stream.write(bytes);
172
173         //No Exceptions for now
174
stream.writeShort(n);
175         for(int i=0; i<n; i++) {
176             ExceptionLabel e = (ExceptionLabel)exceptions.elementAt(i);
177             stream.writeShort(e.start.getPosition());
178             stream.writeShort(e.end.getPosition());
179             stream.writeShort(e.handler.getPosition());
180             stream.writeShort(e.exc);
181         }
182         if (linenumbers != null)
183             ClassFile.writeAttributes(stream,
184                                       new Attribute[] { linenumbers });
185         else
186             ClassFile.writeAttributes(stream, new Attribute[0]);
187     }
188
189     public void push(int i) {
190         //System.out.println("push: "+i+" : "+stack);
191
stack = stack+i;
192         if (stack > max_stack) max_stack = stack;
193         if (stack < 0)
194             throw new InternalError JavaDoc("stack < 0: "+stack);
195     }
196
197     public void branch(int b, Label label) throws IOException {
198         int offset = size();
199         code.writeByte(b);
200         label.setBranch(offset, 2);
201         label.setStack(stack);
202     }
203
204     public void print(String JavaDoc s) throws IOException {
205         getstatic("java/lang/System", "out", "Ljava/io/PrintStream;");
206         ldc(s);
207         invokevirtual("java/io/PrintStream", "println",
208                       "(Ljava/lang/String;)V");
209     }
210
211
212     public void aaload() throws IOException {
213         code.writeByte(50);
214         push(-1);
215     }
216
217     public void aastore() throws IOException {
218         code.writeByte(83);
219         push(-3);
220     }
221
222     public void aconst_null() throws IOException {
223         code.writeByte(1);
224         push(1);
225     }
226
227     public void aload(int i) throws IOException {
228         if (i >= 0 && i < 4) {
229             code.writeByte(42+i);
230         } else {
231             code.writeByte(25);
232             code.writeByte(i);
233         }
234         push(1);
235     }
236
237     public void anewarray(int c) throws IOException {
238         code.writeByte(189);
239         code.writeShort(c);
240         //push(-1); push(1);
241
}
242
243     public void areturn() throws IOException {
244         code.writeByte(176);
245         push(-1);
246     }
247
248     public void arraylength() throws IOException {
249         code.writeByte(190);
250         //push(-1); push(1);
251
}
252
253     public void astore(int i) throws IOException {
254         if (i >= 0 && i < 4) {
255             code.writeByte(75+i);
256         } else {
257             code.writeByte(58);
258             code.writeByte(i);
259         }
260         push(-1);
261     }
262
263     public void athrow() throws IOException {
264         code.writeByte(191);
265         push(-1);
266     }
267
268     public void checkcast(int c) throws IOException {
269         code.writeByte(192);
270         code.writeShort(c);
271     }
272
273     public void dload(int i) throws IOException {
274         if (i >= 0 && i < 4) {
275             code.writeByte(38+i);
276         } else {
277             code.writeByte(24);
278             code.writeByte(i);
279         }
280         push(2);
281     }
282
283     public void dreturn() throws IOException {
284         code.writeByte(175);
285         push(-2);
286     }
287
288     public void dup() throws IOException {
289         code.writeByte(89);
290         push(1);
291     }
292
293     public void dup_x1() throws IOException {
294         code.writeByte(90);
295         push(1);
296     }
297
298     public void fload(int i) throws IOException {
299         if (i >= 0 && i < 4) {
300             code.writeByte(34+i);
301         } else {
302             code.writeByte(23);
303             code.writeByte(i);
304         }
305         push(1);
306     }
307
308     public void freturn() throws IOException {
309         code.writeByte(174);
310         push(-1);
311     }
312
313     public void getfield(int c) throws IOException {
314         code.writeByte(180);
315         code.writeShort(c);
316         push(pool.sizes[c]-1);
317     }
318
319     public void getfield(String JavaDoc c, String JavaDoc name, String JavaDoc type)
320         throws IOException
321     {
322         getfield(pool.Fieldref(c, name, type));
323     }
324
325     public void getstatic(int c) throws IOException {
326         code.writeByte(178);
327         code.writeShort(c);
328         push(pool.sizes[c]);
329     }
330
331     public void getstatic(String JavaDoc c, String JavaDoc name, String JavaDoc type)
332         throws IOException
333     {
334         getstatic(pool.Fieldref(c, name, type));
335     }
336
337     public void goto_(Label label) throws IOException {
338         branch(167, label);
339     }
340
341     public void iconst(int i) throws IOException {
342         if (i >= -1 && i <= 5) {
343             code.writeByte(3+i);
344         } else {
345             if (i > -127 && i < 128) {
346                 code.writeByte(16);
347                 if (i < 0) i = 256+i;
348                 code.writeByte(i);
349             } else {
350                 if (i > -32767 && i < 32768) {
351                     code.writeByte(17);
352                     if (i < 0) i = i+65536;
353                     code.writeShort(i);
354                 } else {
355                     ldc(pool.Integer(i));
356                 }
357             }
358         }
359         push(1);
360     }
361
362     public void if_icmpne(Label label) throws IOException {
363         push(-2);
364         branch(160, label);
365     }
366
367     public void ifeq(Label label) throws IOException {
368         push(-1);
369         branch(153, label);
370     }
371
372     public void ifne(Label label) throws IOException {
373         push(-1);
374         branch(154, label);
375     }
376
377     public void ifnonnull(Label label) throws IOException {
378         push(-1);
379         branch(199, label);
380     }
381
382     public void ifnull(Label label) throws IOException {
383         push(-1);
384         branch(198, label);
385     }
386
387     public void iinc(int i, int increment) throws IOException {
388         code.writeByte(132);
389         code.writeByte(i);
390         code.writeByte(increment);
391     }
392
393     public void iinc(int i) throws IOException {
394         iinc(i, 1);
395     }
396
397     public void iload(int i) throws IOException {
398         if (i >= 0 && i < 4) {
399             code.writeByte(26+i);
400         } else {
401             code.writeByte(21);
402             code.writeByte(i);
403         }
404         push(1);
405     }
406
407     public void invokespecial(int c) throws IOException {
408         code.writeByte(183);
409         code.writeShort(c);
410         push(pool.sizes[c]-1);
411     }
412
413     public void invokestatic(int c) throws IOException {
414         code.writeByte(184);
415         code.writeShort(c);
416         push(pool.sizes[c]);
417     }
418
419     public void invokevirtual(int c) throws IOException {
420         code.writeByte(182);
421         code.writeShort(c);
422         push(pool.sizes[c]-1);
423     }
424
425     public void invokevirtual(String JavaDoc c, String JavaDoc name, String JavaDoc type)
426         throws IOException
427     {
428         invokevirtual(pool.Methodref(c, name, type));
429     }
430
431     public void ireturn() throws IOException {
432         code.writeByte(172);
433         push(-1);
434     }
435
436     public void istore(int i) throws IOException {
437         if (i >= 0 && i < 4) {
438             code.writeByte(59+i);
439         } else {
440             code.writeByte(54);
441             code.writeByte(i);
442         }
443         push(-1);
444     }
445
446     public void jsr(Label label) throws IOException {
447         //push(-1);
448
int offset = size();
449         code.writeByte(168);
450         label.setBranch(offset, 2);
451         label.setStack(stack+1);
452     }
453
454     public void ldc(int c) throws IOException {
455         int size = pool.sizes[c];
456         if (size == 1) {
457             if (c < 256) {
458                 code.writeByte(18);
459                 code.writeByte(c);
460             } else {
461                 code.writeByte(19);
462                 code.writeShort(c);
463             }
464         } else {
465             code.writeByte(20);
466             code.writeShort(c);
467         }
468
469         push(pool.sizes[c]);
470     }
471
472     public void ldc(String JavaDoc s) throws IOException {
473         ldc(pool.String(s));
474     }
475
476     public void lload(int i) throws IOException {
477         if (i >= 0 && i < 4) {
478             code.writeByte(30+i);
479         } else {
480             code.writeByte(22);
481             code.writeByte(i);
482         }
483         push(2);
484     }
485
486     public void lreturn() throws IOException {
487         code.writeByte(173);
488         push(-2);
489     }
490
491     public void new_(int c) throws IOException {
492             code.writeByte(187);
493             code.writeShort(c);
494             push(1);
495         }
496
497     public void pop() throws IOException {
498         code.writeByte(87);
499         push(-1);
500     }
501
502     public void putfield(int c) throws IOException {
503         code.writeByte(181);
504         code.writeShort(c);
505         push(-pool.sizes[c]-1);
506     }
507
508     public void putfield(String JavaDoc c, String JavaDoc name, String JavaDoc type)
509         throws IOException
510     {
511         putfield(pool.Fieldref(c, name, type));
512     }
513
514     public void putstatic(int c) throws IOException {
515         code.writeByte(179);
516         code.writeShort(c);
517         push(-pool.sizes[c]);
518     }
519
520     public void putstatic(String JavaDoc c, String JavaDoc name, String JavaDoc type)
521         throws IOException
522     {
523         putstatic(pool.Fieldref(c, name, type));
524     }
525
526     public void return_() throws IOException {
527         code.writeByte(177);
528     }
529
530     public void ret(int index) throws IOException {
531         code.writeByte(169);
532         code.writeByte(index);
533     }
534
535     public void swap() throws IOException {
536         code.writeByte(95);
537     }
538
539     public void tableswitch(Label def, int low, Label[] labels)
540         throws IOException
541     {
542         int position = size();
543         push(-1);
544         code.writeByte(170);
545         for(int j=0; j < 3-(position%4); j++) code.writeByte(0);
546         def.setBranch(position, 4);
547         code.writeInt(low);
548         code.writeInt(labels.length-1);
549         for(int i=0; i<labels.length; i++) {
550             labels[i].setBranch(position, 4);
551         }
552     }
553
554     public void setline(int line) throws IOException {
555         if (linenumbers == null)
556             linenumbers = new LineNumberTable(pool);
557         linenumbers.addLine(size(), line);
558     }
559 }
560
Popular Tags