KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jode > jvm > Interpreter


1 /* Interpreter Copyright (C) 1999-2002 Jochen Hoenicke.
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU Lesser General Public License as published by
5  * the Free Software Foundation; either version 2, or (at your option)
6  * any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program; see the file COPYING.LESSER. If not, write to
15  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
16  *
17  * $Id: Interpreter.java.in,v 1.5.2.1 2002/05/28 17:34:12 hoenicke Exp $
18  */

19
20 package jode.jvm;
21 import jode.AssertError;
22 import jode.GlobalOptions;
23 import jode.bytecode.BytecodeInfo;
24 import jode.bytecode.Handler;
25 import jode.bytecode.Instruction;
26 import jode.bytecode.Opcodes;
27 import jode.bytecode.Reference;
28 import jode.bytecode.TypeSignature;
29
30 import java.lang.reflect.Array JavaDoc;
31 import java.lang.reflect.InvocationTargetException JavaDoc;
32 import java.util.Arrays JavaDoc;
33
34 /**
35  * This class is a java virtual machine written in java :-). Well not
36  * exactly. It does only handle a subset of the opcodes and is mainly
37  * written do deobfuscate Strings.
38  *
39  * @author Jochen Hoenicke
40  */

41 public class Interpreter implements Opcodes {
42
43     private final static int CMP_EQ = 0;
44     private final static int CMP_NE = 1;
45     private final static int CMP_LT = 2;
46     private final static int CMP_GE = 3;
47     private final static int CMP_GT = 4;
48     private final static int CMP_LE = 5;
49     private final static int CMP_GREATER_MASK
50     = (1 << CMP_GT)|(1 << CMP_GE)|(1 << CMP_NE);
51     private final static int CMP_LESS_MASK
52     = (1 << CMP_LT)|(1 << CMP_LE)|(1 << CMP_NE);
53     private final static int CMP_EQUAL_MASK
54     = (1 << CMP_GE)|(1 << CMP_LE)|(1 << CMP_EQ);
55
56     private RuntimeEnvironment env;
57
58     public Interpreter(RuntimeEnvironment env) {
59     this.env = env;
60     }
61
62     private Value[] fillParameters(BytecodeInfo code,
63                    Object JavaDoc cls, Object JavaDoc[] params) {
64     Value[] locals = new Value[code.getMaxLocals()];
65     for (int i=0; i< locals.length; i++)
66         locals[i] = new Value();
67
68     String JavaDoc myType = code.getMethodInfo().getType();
69     String JavaDoc[] myParamTypes = TypeSignature.getParameterTypes(myType);
70     int slot = 0;
71     if (!code.getMethodInfo().isStatic())
72         locals[slot++].setObject(cls);
73     for (int i=0; i< myParamTypes.length; i++) {
74         locals[slot].setObject(params[i]);
75         slot += TypeSignature.getTypeSize(myParamTypes[i]);
76     }
77     return locals;
78     }
79
80     public Object JavaDoc interpretMethod(BytecodeInfo code,
81                   Object JavaDoc instance, Object JavaDoc[] myParams)
82     throws InterpreterException, InvocationTargetException JavaDoc {
83     if ((GlobalOptions.debuggingFlags
84          & GlobalOptions.DEBUG_INTERPRT) != 0)
85         GlobalOptions.err.println("Interpreting "+code);
86
87     Value[] locals = fillParameters(code, instance, myParams);
88     Value[] stack = new Value[code.getMaxStack()];
89     for (int i=0; i < stack.length; i++)
90         stack[i] = new Value();
91
92     Instruction pc = (Instruction) code.getInstructions().get(0);
93     int stacktop = 0;
94     big_loop:
95     for(;;) {
96         try {
97         Instruction instr = pc;
98         if ((GlobalOptions.debuggingFlags
99              & GlobalOptions.DEBUG_INTERPRT) != 0) {
100             GlobalOptions.err.println(instr.getDescription());
101             GlobalOptions.err.print("stack: [");
102             for (int i=0; i<stacktop; i++) {
103             if (i>0)
104                 GlobalOptions.err.print(",");
105             GlobalOptions.err.print(stack[i]);
106             if (stack[i].objectValue() instanceof char[]) {
107                 GlobalOptions.err.print
108                 (new String JavaDoc((char[])stack[i].objectValue()));
109             }
110             }
111             GlobalOptions.err.println("]");
112             GlobalOptions.err.print("local: [");
113             for (int i=0; i<locals.length; i++)
114             GlobalOptions.err.print(locals[i]+",");
115             GlobalOptions.err.println("]");
116         }
117         pc = instr.getNextByAddr();
118         int opcode = instr.getOpcode();
119         switch (opcode) {
120         case opc_nop:
121             break;
122         case opc_ldc:
123             stack[stacktop++].setObject(instr.getConstant());
124             break;
125         case opc_ldc2_w:
126             stack[stacktop].setObject(instr.getConstant());
127             stacktop += 2;
128             break;
129         case opc_iload: case opc_fload: case opc_aload:
130             stack[stacktop++].setValue(locals[instr.getLocalSlot()]);
131             break;
132         case opc_lload: case opc_dload:
133             stack[stacktop].setValue(locals[instr.getLocalSlot()]);
134             stacktop += 2;
135             break;
136         case opc_iaload: case opc_laload:
137         case opc_faload: case opc_daload: case opc_aaload:
138         case opc_baload: case opc_caload: case opc_saload: {
139             int index = stack[--stacktop].intValue();
140             Object JavaDoc array = stack[--stacktop].objectValue();
141             Object JavaDoc result;
142             try {
143             switch(opcode) {
144             case opc_baload:
145                 result = new Integer JavaDoc
146                 (array instanceof byte[]
147                  ? ((byte[])array)[index]
148                  : ((boolean[])array)[index] ? 1 : 0);
149                 break;
150             case opc_caload:
151                 result = new Integer JavaDoc(((char[])array)[index]);
152                 break;
153             case opc_saload:
154                 result = new Integer JavaDoc(((short[])array)[index]);
155                 break;
156             default:
157                 result = Array.get(array, index);
158                 break;
159             }
160             } catch (NullPointerException JavaDoc ex) {
161             throw new InvocationTargetException JavaDoc(ex);
162             } catch (ArrayIndexOutOfBoundsException JavaDoc ex) {
163             throw new InvocationTargetException JavaDoc(ex);
164             }
165             stack[stacktop++].setObject(result);
166             if (opcode == opc_laload || opcode == opc_daload)
167             stacktop++;
168             break;
169         }
170         case opc_istore: case opc_fstore: case opc_astore:
171             locals[instr.getLocalSlot()].setValue(stack[--stacktop]);
172             break;
173         case opc_lstore: case opc_dstore:
174             locals[instr.getLocalSlot()].setValue(stack[stacktop -= 2]);
175             break;
176
177         case opc_lastore: case opc_dastore:
178             stacktop--;
179             /* fall through */
180         case opc_iastore: case opc_fastore: case opc_aastore:
181         case opc_bastore: case opc_castore: case opc_sastore: {
182             Value value = stack[--stacktop];
183             int index = stack[--stacktop].intValue();
184             Object JavaDoc array = stack[--stacktop].objectValue();
185             try {
186             switch(opcode) {
187             case opc_bastore:
188                 if (array instanceof byte[])
189                 ((byte[])array)[index]
190                     = (byte) value.intValue();
191                 else
192                 ((boolean[])array)[index]
193                     = value.intValue() != 0;
194                 break;
195             case opc_castore:
196                 ((char[])array)[index] = (char) value.intValue();
197                 break;
198             case opc_sastore:
199                 ((short[])array)[index] = (short) value.intValue();
200                 break;
201             default:
202                 Array.set(array, index, value.objectValue());
203             }
204             } catch (NullPointerException JavaDoc ex) {
205             throw new InvocationTargetException JavaDoc(ex);
206             } catch (ArrayIndexOutOfBoundsException JavaDoc ex) {
207             throw new InvocationTargetException JavaDoc(ex);
208             } catch (ArrayStoreException JavaDoc ex) {
209             throw new InvocationTargetException JavaDoc(ex);
210             }
211             break;
212         }
213         case opc_pop: case opc_pop2:
214             stacktop -= opcode - (opc_pop-1);
215             break;
216         case opc_dup: case opc_dup_x1: case opc_dup_x2: {
217             int depth = opcode - opc_dup;
218             for (int i=0; i < depth+1; i++)
219             stack[stacktop-i].setValue(stack[stacktop-i-1]);
220             stack[stacktop-depth-1].setValue(stack[stacktop]);
221             stacktop++;
222             break;
223         }
224         case opc_dup2: case opc_dup2_x1: case opc_dup2_x2: {
225             int depth = opcode - opc_dup2;
226             for (int i=0; i < depth+2; i++)
227             stack[stacktop+1-i].setValue(stack[stacktop-1-i]);
228             stack[stacktop-depth-1].setValue(stack[stacktop+1]);
229             stack[stacktop-depth-2].setValue(stack[stacktop]);
230             stacktop += 2;
231             break;
232         }
233         case opc_swap: {
234             Value tmp = stack[stacktop-1];
235             stack[stacktop-1] = stack[stacktop-2];
236             stack[stacktop-2] = tmp;
237             break;
238         }
239         case opc_iadd:
240             stack[stacktop-2].setInt(stack[stacktop-2].intValue()
241                          + stack[stacktop-1].intValue());
242             stacktop--;
243             break;
244         case opc_isub:
245             stack[stacktop-2].setInt(stack[stacktop-2].intValue()
246                          - stack[stacktop-1].intValue());
247             stacktop--;
248             break;
249         case opc_imul:
250             stack[stacktop-2].setInt(stack[stacktop-2].intValue()
251                          * stack[stacktop-1].intValue());
252             stacktop--;
253             break;
254         case opc_idiv:
255             try {
256             stack[stacktop-2].setInt
257                 (stack[stacktop-2].intValue()
258                  / stack[stacktop-1].intValue());
259             } catch (ArithmeticException JavaDoc ex) {
260             throw new InvocationTargetException JavaDoc(ex);
261             }
262             stacktop--;
263             break;
264         case opc_irem:
265             try {
266             stack[stacktop-2].setInt
267                 (stack[stacktop-2].intValue()
268                  % stack[stacktop-1].intValue());
269             } catch (ArithmeticException JavaDoc ex) {
270             throw new InvocationTargetException JavaDoc(ex);
271             }
272             stacktop--;
273             break;
274
275         case opc_ladd:
276             stacktop-=2;
277             stack[stacktop-2].setLong(stack[stacktop-2].longValue()
278                           + stack[stacktop].longValue());
279             break;
280         case opc_lsub:
281             stacktop-=2;
282             stack[stacktop-2].setLong(stack[stacktop-2].longValue()
283                           - stack[stacktop].longValue());
284             break;
285         case opc_lmul:
286             stacktop-=2;
287             stack[stacktop-2].setLong(stack[stacktop-2].longValue()
288                           * stack[stacktop].longValue());
289             break;
290         case opc_ldiv:
291             stacktop-=2;
292             try {
293             stack[stacktop-2].setLong
294                 (stack[stacktop-2].longValue()
295                  / stack[stacktop].longValue());
296             } catch (ArithmeticException JavaDoc ex) {
297             throw new InvocationTargetException JavaDoc(ex);
298             }
299             break;
300         case opc_lrem:
301             stacktop-=2;
302             try {
303             stack[stacktop-2].setLong
304                 (stack[stacktop-2].longValue()
305                  % stack[stacktop].longValue());
306             } catch (ArithmeticException JavaDoc ex) {
307             throw new InvocationTargetException JavaDoc(ex);
308             }
309             break;
310
311         case opc_fadd:
312             stack[stacktop-2].setFloat(stack[stacktop-2].floatValue()
313                            + stack[stacktop-1].floatValue());
314             stacktop--;
315             break;
316         case opc_fsub:
317             stack[stacktop-2].setFloat(stack[stacktop-2].floatValue()
318                            - stack[stacktop-1].floatValue());
319             stacktop--;
320             break;
321         case opc_fmul:
322             stack[stacktop-2].setFloat(stack[stacktop-2].floatValue()
323                            * stack[stacktop-1].floatValue());
324             stacktop--;
325             break;
326         case opc_fdiv:
327             stack[stacktop-2].setFloat(stack[stacktop-2].floatValue()
328                            / stack[stacktop-1].floatValue());
329             stacktop--;
330             break;
331         case opc_frem:
332             stack[stacktop-2].setFloat(stack[stacktop-2].floatValue()
333                            % stack[stacktop-1].floatValue());
334             stacktop--;
335             break;
336
337         case opc_dadd:
338             stacktop-=2;
339             stack[stacktop-2].setDouble(stack[stacktop-2].doubleValue()
340                         + stack[stacktop].doubleValue());
341             break;
342         case opc_dsub:
343             stacktop-=2;
344             stack[stacktop-2].setDouble(stack[stacktop-2].doubleValue()
345                         - stack[stacktop].doubleValue());
346             break;
347         case opc_dmul:
348             stacktop-=2;
349             stack[stacktop-2].setDouble(stack[stacktop-2].doubleValue()
350                         * stack[stacktop].doubleValue());
351             break;
352         case opc_ddiv:
353             stacktop-=2;
354             stack[stacktop-2].setDouble(stack[stacktop-2].doubleValue()
355                         / stack[stacktop].doubleValue());
356             break;
357         case opc_drem:
358             stacktop-=2;
359             stack[stacktop-2].setDouble(stack[stacktop-2].doubleValue()
360                         % stack[stacktop].doubleValue());
361             break;
362
363         case opc_ineg:
364             stack[stacktop-1].setInt(-stack[stacktop-1].intValue());
365             break;
366         case opc_lneg:
367             stack[stacktop-2].setLong(-stack[stacktop-2].longValue());
368             break;
369         case opc_fneg:
370             stack[stacktop-1].setFloat(-stack[stacktop-1].floatValue());
371             break;
372         case opc_dneg:
373             stack[stacktop-2].setDouble(-stack[stacktop-2].doubleValue());
374             break;
375
376         case opc_ishl:
377             stack[stacktop-2].setInt(stack[stacktop-2].intValue()
378                          << stack[stacktop-1].intValue());
379             stacktop--;
380             break;
381         case opc_ishr:
382             stack[stacktop-2].setInt(stack[stacktop-2].intValue()
383                          >> stack[stacktop-1].intValue());
384             stacktop--;
385             break;
386         case opc_iushr:
387             stack[stacktop-2].setInt(stack[stacktop-2].intValue()
388                          >>> stack[stacktop-1].intValue());
389             stacktop--;
390             break;
391         case opc_iand:
392             stack[stacktop-2].setInt(stack[stacktop-2].intValue()
393                          & stack[stacktop-1].intValue());
394             stacktop--;
395             break;
396         case opc_ior :
397             stack[stacktop-2].setInt(stack[stacktop-2].intValue()
398                          | stack[stacktop-1].intValue());
399             stacktop--;
400             break;
401         case opc_ixor:
402             stack[stacktop-2].setInt(stack[stacktop-2].intValue()
403                          ^ stack[stacktop-1].intValue());
404             stacktop--;
405             break;
406
407         case opc_lshl:
408             stack[stacktop-3].setLong(stack[stacktop-3].longValue()
409                           << stack[stacktop-1].intValue());
410             stacktop--;
411             break;
412         case opc_lshr:
413             stack[stacktop-3].setLong(stack[stacktop-3].longValue()
414                           >> stack[stacktop-1].intValue());
415             stacktop--;
416             break;
417         case opc_lushr:
418             stack[stacktop-3].setLong(stack[stacktop-3].longValue()
419                           >>> stack[stacktop-1].intValue());
420             stacktop--;
421             break;
422         case opc_land:
423             stacktop-=2;
424             stack[stacktop-2].setLong(stack[stacktop-2].longValue()
425                           & stack[stacktop].longValue());
426             break;
427         case opc_lor :
428             stacktop-=2;
429             stack[stacktop-2].setLong(stack[stacktop-2].longValue()
430                           | stack[stacktop].longValue());
431             break;
432         case opc_lxor:
433             stacktop-=2;
434             stack[stacktop-2].setLong(stack[stacktop-2].longValue()
435                           ^ stack[stacktop].longValue());
436             break;
437
438         case opc_iinc:
439             locals[instr.getLocalSlot()].setInt
440             (locals[instr.getLocalSlot()].intValue() + instr.getIncrement());
441             break;
442         case opc_i2l:
443             stack[stacktop-1]
444             .setLong((long)stack[stacktop-1].intValue());
445             stacktop++;
446             break;
447         case opc_i2f:
448             stack[stacktop-1]
449             .setFloat((float)stack[stacktop-1].intValue());
450             break;
451         case opc_i2d:
452             stack[stacktop-1]
453             .setDouble((double)stack[stacktop-1].intValue());
454             stacktop++;
455             break;
456
457         case opc_l2i:
458             stacktop--;
459             stack[stacktop-1]
460             .setInt((int)stack[stacktop-1].longValue());
461             break;
462         case opc_l2f:
463             stacktop--;
464             stack[stacktop-1]
465             .setFloat((float)stack[stacktop-1].longValue());
466             break;
467         case opc_l2d:
468             stack[stacktop-2]
469             .setDouble((double)stack[stacktop-2].longValue());
470             break;
471
472         case opc_f2i:
473             stack[stacktop-1]
474             .setInt((int)stack[stacktop-1].floatValue());
475             break;
476         case opc_f2l:
477             stack[stacktop-1]
478             .setLong((long)stack[stacktop-1].floatValue());
479             stacktop++;
480             break;
481         case opc_f2d:
482             stack[stacktop-1]
483             .setDouble((double)stack[stacktop-1].floatValue());
484             stacktop++;
485             break;
486
487         case opc_d2i:
488             stacktop--;
489             stack[stacktop-1]
490             .setInt((int)stack[stacktop-1].doubleValue());
491             break;
492         case opc_d2l:
493             stack[stacktop-2]
494             .setLong((long)stack[stacktop-2].doubleValue());
495             break;
496         case opc_d2f:
497             stacktop--;
498             stack[stacktop-1]
499             .setFloat((float)stack[stacktop-1].doubleValue());
500             break;
501
502         case opc_i2b:
503             stack[stacktop-1]
504             .setInt((byte)stack[stacktop-1].intValue());
505             break;
506         case opc_i2c:
507             stack[stacktop-1]
508             .setInt((char)stack[stacktop-1].intValue());
509             break;
510         case opc_i2s:
511             stack[stacktop-1]
512             .setInt((short)stack[stacktop-1].intValue());
513             break;
514         case opc_lcmp: {
515             stacktop -= 3;
516             long val1 = stack[stacktop-1].longValue();
517             long val2 = stack[stacktop+1].longValue();
518             stack[stacktop-1].setInt
519             (val1 == val2 ? 0 : val1 < val2 ? -1 : 1);
520             break;
521         }
522         case opc_fcmpl: case opc_fcmpg: {
523             float val1 = stack[stacktop-2].floatValue();
524             float val2 = stack[--stacktop].floatValue();
525             stack[stacktop-1].setInt
526             (val1 == val2 ? 0
527              : ( opcode == opc_fcmpg
528                  ? (val1 < val2 ? -1 : 1)
529                  : (val1 > val2 ? 1 : -1)));
530             break;
531         }
532         case opc_dcmpl: case opc_dcmpg: {
533             stacktop -= 3;
534             double val1 = stack[stacktop-1].doubleValue();
535             double val2 = stack[stacktop+1].doubleValue();
536             stack[stacktop-1].setInt
537             (val1 == val2 ? 0
538              : ( opcode == opc_dcmpg
539                  ? (val1 < val2 ? -1 : 1)
540                  : (val1 > val2 ? 1 : -1)));
541             break;
542         }
543         case opc_ifeq: case opc_ifne:
544         case opc_iflt: case opc_ifge:
545         case opc_ifgt: case opc_ifle:
546         case opc_if_icmpeq: case opc_if_icmpne:
547         case opc_if_icmplt: case opc_if_icmpge:
548         case opc_if_icmpgt: case opc_if_icmple:
549         case opc_if_acmpeq: case opc_if_acmpne:
550         case opc_ifnull: case opc_ifnonnull: {
551             int value;
552             if (opcode >= opc_if_acmpeq) {
553             Object JavaDoc objValue = stack[--stacktop].objectValue();
554             if (opcode >= opc_ifnull) {
555                 value = objValue == null ? 0 : 1;
556                 opcode -= opc_ifnull;
557             } else {
558                 value = objValue
559                 == stack[--stacktop].objectValue() ? 0 : 1;
560                 opcode -= opc_if_acmpeq;
561             }
562             } else {
563             value = stack[--stacktop].intValue();
564             if (opcode >= opc_if_icmpeq) {
565                 int val1 = stack[--stacktop].intValue();
566                 value = (val1 == value ? 0
567                      : val1 < value ? -1 : 1);
568                 opcode -= opc_if_icmpeq;
569             } else
570                 opcode -= opc_ifeq;
571             }
572             int opc_mask = 1 << opcode;
573             if (value > 0 && (opc_mask & CMP_GREATER_MASK) != 0
574             || value < 0 && (opc_mask & CMP_LESS_MASK) != 0
575             || value == 0 && (opc_mask & CMP_EQUAL_MASK) != 0)
576             pc = instr.getSingleSucc();
577             break;
578         }
579         case opc_jsr:
580         case opc_jsr_w:
581             stack[stacktop++].setObject(instr);
582             /* fall through */
583         case opc_goto:
584         case opc_goto_w:
585             pc = instr.getSingleSucc();
586             break;
587         case opc_ret:
588             pc = (Instruction)locals[instr.getLocalSlot()].objectValue();
589             break;
590         case opc_lookupswitch: {
591             int value = stack[--stacktop].intValue();
592             int[] values = instr.getValues();
593             int pos = Arrays.binarySearch(values, value);
594             pc = pos < 0
595             ? instr.getSuccs()[values.length]
596             : instr.getSuccs()[pos];
597             break;
598         }
599         case opc_ireturn: case opc_freturn: case opc_areturn:
600             return stack[--stacktop].objectValue();
601         case opc_lreturn: case opc_dreturn:
602             return stack[stacktop -= 2].objectValue();
603         case opc_return:
604             return Void.TYPE;
605         case opc_getstatic: {
606             Reference ref = instr.getReference();
607             Object JavaDoc result = env.getField(instr.getReference(), null);
608             stack[stacktop].setObject(result);
609             stacktop += TypeSignature.getTypeSize(ref.getType());
610             break;
611         }
612         case opc_getfield: {
613             Reference ref = instr.getReference();
614             Object JavaDoc cls = stack[--stacktop].objectValue();
615             if (cls == null)
616             throw new InvocationTargetException JavaDoc
617                 (new NullPointerException JavaDoc());
618             Object JavaDoc result = env.getField(instr.getReference(), cls);
619             stack[stacktop].setObject(result);
620             stacktop += TypeSignature.getTypeSize(ref.getType());
621             break;
622         }
623         case opc_putstatic: {
624             Reference ref = instr.getReference();
625             stacktop -= TypeSignature.getTypeSize(ref.getType());
626             Object JavaDoc value = stack[stacktop].objectValue();
627             env.putField(instr.getReference(), null, value);
628             break;
629         }
630         case opc_putfield: {
631             Reference ref = instr.getReference();
632             stacktop -= TypeSignature.getTypeSize(ref.getType());
633             Object JavaDoc value = stack[stacktop].objectValue();
634             Object JavaDoc cls = stack[--stacktop].objectValue();
635             if (cls == null)
636             throw new InvocationTargetException JavaDoc
637                 (new NullPointerException JavaDoc());
638             env.putField(instr.getReference(), cls, value);
639             break;
640         }
641         case opc_invokevirtual:
642         case opc_invokespecial:
643         case opc_invokestatic :
644         case opc_invokeinterface: {
645             Reference ref = instr.getReference();
646             String JavaDoc[] paramTypes
647             = TypeSignature.getParameterTypes(ref.getType());
648             Object JavaDoc[] args = new Object JavaDoc[paramTypes.length];
649             for (int i = paramTypes.length - 1; i >= 0; i--) {
650             stacktop -= TypeSignature.getTypeSize(paramTypes[i]);
651             args[i] = stack[stacktop].objectValue();
652             }
653         
654             Object JavaDoc result = null;
655             if (opcode == opc_invokespecial
656             && ref.getName().equals("<init>")
657             && stack[--stacktop].getNewObject() != null) {
658             NewObject newObj = stack[stacktop].getNewObject();
659             if (!newObj.getType().equals(ref.getClazz()))
660                 throw new InterpreterException
661                 ("constructor doesn't match new");
662             newObj.setObject(env.invokeConstructor(ref, args));
663             } else if (opcode == opc_invokestatic) {
664             result = env.invokeMethod(ref, false, null, args);
665             } else {
666             Object JavaDoc cls = stack[--stacktop].objectValue();
667             if (cls == null)
668                 throw new InvocationTargetException JavaDoc
669                 (new NullPointerException JavaDoc());
670             result = env.invokeMethod
671                 (ref, opcode != opc_invokespecial, cls, args);
672             }
673             String JavaDoc retType
674             = TypeSignature.getReturnType(ref.getType());
675             if (!retType.equals("V")) {
676             stack[stacktop].setObject(result);
677             stacktop += TypeSignature.getTypeSize(retType);
678             }
679             break;
680         }
681         case opc_new: {
682             String JavaDoc clazz = instr.getClazzType();
683             stack[stacktop++].setNewObject(new NewObject(clazz));
684             break;
685         }
686         case opc_arraylength: {
687             Object JavaDoc array = stack[--stacktop].objectValue();
688             if (array == null)
689             throw new InvocationTargetException JavaDoc
690                 (new NullPointerException JavaDoc());
691             stack[stacktop++].setInt(Array.getLength(array));
692             break;
693         }
694         case opc_athrow: {
695             Throwable JavaDoc exc =
696             (Throwable JavaDoc) stack[--stacktop].objectValue();
697             throw new InvocationTargetException JavaDoc
698             (exc == null ? new NullPointerException JavaDoc() : exc);
699         }
700         case opc_checkcast: {
701             Object JavaDoc obj = stack[stacktop-1].objectValue();
702             if (obj != null
703             && !env.instanceOf(obj, instr.getClazzType()))
704             throw new InvocationTargetException JavaDoc
705                 (new ClassCastException JavaDoc(obj.getClass().getName()));
706             break;
707         }
708         case opc_instanceof: {
709             Object JavaDoc obj = stack[--stacktop].objectValue();
710             stack[stacktop++].setInt
711             (env.instanceOf(obj, instr.getClazzType()) ? 1 : 0);
712             break;
713         }
714         case opc_monitorenter:
715             env.enterMonitor(stack[--stacktop].objectValue());
716             break;
717         case opc_monitorexit:
718             env.exitMonitor(stack[--stacktop].objectValue());
719             break;
720         case opc_multianewarray: {
721             int dimension = instr.getDimensions();
722             int[] dims = new int[dimension];
723             for (int i=dimension - 1; i >= 0; i--)
724             dims[i] = stack[--stacktop].intValue();
725             try {
726             stack[stacktop++].setObject
727                 (env.newArray(instr.getClazzType(), dims));
728             } catch (NegativeArraySizeException JavaDoc ex) {
729             throw new InvocationTargetException JavaDoc(ex);
730             }
731             break;
732         }
733         default:
734             throw new AssertError("Invalid opcode "+opcode);
735         }
736         } catch (InvocationTargetException JavaDoc ex) {
737         Handler[] handlers = code.getExceptionHandlers();
738         Throwable JavaDoc obj = ex.getTargetException();
739         for (int i=0; i< handlers.length; i++) {
740             if (handlers[i].start.compareTo(pc) <= 0
741             && handlers[i].end.compareTo(pc) >= 0
742             && (handlers[i].type == null
743                 || env.instanceOf(obj, handlers[i].type))) {
744             stacktop = 0;
745             stack[stacktop++].setObject(obj);
746             pc = handlers[i].catcher;
747             continue big_loop;
748             }
749         }
750         throw ex;
751         }
752     }
753     }
754 }
755
Popular Tags