git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@399 379699f6-c40d-0410-875b-85095c16579estable
parent
4e93ed861f
commit
d5c76c287d
@ -0,0 +1,812 @@ |
|||||||
|
/* |
||||||
|
* Opcodes (c) 1998 Jochen Hoenicke |
||||||
|
* |
||||||
|
* You may distribute under the terms of the GNU General Public License. |
||||||
|
* |
||||||
|
* IN NO EVENT SHALL JOCHEN HOENICKE BE LIABLE TO ANY PARTY FOR DIRECT, |
||||||
|
* INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF |
||||||
|
* THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF JOCHEN HOENICKE |
||||||
|
* HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
* JOCHEN HOENICKE SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
||||||
|
* PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" |
||||||
|
* BASIS, AND JOCHEN HOENICKE HAS NO OBLIGATION TO PROVIDE MAINTENANCE, |
||||||
|
* SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
||||||
|
* |
||||||
|
* $Id$ |
||||||
|
*/ |
||||||
|
package jode.jvm; |
||||||
|
import jode.bytecode.*; |
||||||
|
import java.lang.reflect.*; |
||||||
|
|
||||||
|
/** |
||||||
|
* This class is a java virtual machine written in java :-). Well not |
||||||
|
* exactly. It does only handle a subset of the opcodes and is mainly |
||||||
|
* written do deobfuscate Strings. |
||||||
|
* |
||||||
|
* @author Jochen Hoenicke |
||||||
|
*/ |
||||||
|
public class Interpreter implements Opcodes { |
||||||
|
public static Object interpretMethod |
||||||
|
(ClassInfo currentClass, byte[] code, Value[] locals, Value[] stack) |
||||||
|
throws InterpreterException, ClassFormatException { |
||||||
|
try { |
||||||
|
ConstantPool cpool = currentClass.getConstantPool(); |
||||||
|
int pc = 0; |
||||||
|
int stacktop = 0; |
||||||
|
for(;;) { |
||||||
|
int opcode = code[pc++] & 0xff; |
||||||
|
switch (opcode) { |
||||||
|
case opc_nop: |
||||||
|
break; |
||||||
|
case opc_aconst_null: |
||||||
|
stack[stacktop++].setObject(null); |
||||||
|
break; |
||||||
|
case opc_iconst_m1: |
||||||
|
case opc_iconst_0: case opc_iconst_1: case opc_iconst_2: |
||||||
|
case opc_iconst_3: case opc_iconst_4: case opc_iconst_5: |
||||||
|
stack[stacktop++].setInt(opcode - opc_iconst_0); |
||||||
|
break; |
||||||
|
case opc_lconst_0: case opc_lconst_1: |
||||||
|
stack[stacktop++].setLong(opcode - opc_lconst_0); |
||||||
|
break; |
||||||
|
case opc_fconst_0: case opc_fconst_1: case opc_fconst_2: |
||||||
|
stack[stacktop++].setFloat(opcode - opc_fconst_0); |
||||||
|
break; |
||||||
|
case opc_dconst_0: case opc_dconst_1: |
||||||
|
stack[stacktop++].setDouble(opcode - opc_dconst_0); |
||||||
|
break; |
||||||
|
case opc_bipush: |
||||||
|
stack[stacktop++].setInt(code[pc++]); |
||||||
|
break; |
||||||
|
case opc_sipush: |
||||||
|
stack[stacktop++].setInt((code[pc++] << 8) |
||||||
|
| (code[pc++] & 0xff)); |
||||||
|
break; |
||||||
|
case opc_ldc: |
||||||
|
stack[stacktop++].setObject |
||||||
|
(cpool.getConstant(code[pc++] & 0xff)); |
||||||
|
break; |
||||||
|
case opc_ldc_w: |
||||||
|
case opc_ldc2_w: { |
||||||
|
int index = (code[pc++] << 8) & 0xff00 | code[pc++] & 0xff; |
||||||
|
stack[stacktop++].setObject(cpool.getConstant(index)); |
||||||
|
break; |
||||||
|
} |
||||||
|
case opc_iload: case opc_lload: |
||||||
|
case opc_fload: case opc_dload: case opc_aload: |
||||||
|
stack[stacktop++].setValue(locals[code[pc++]]); |
||||||
|
break; |
||||||
|
case opc_iload_0: case opc_iload_1: |
||||||
|
case opc_iload_2: case opc_iload_3: |
||||||
|
case opc_lload_0: case opc_lload_1: |
||||||
|
case opc_lload_2: case opc_lload_3: |
||||||
|
case opc_fload_0: case opc_fload_1: |
||||||
|
case opc_fload_2: case opc_fload_3: |
||||||
|
case opc_dload_0: case opc_dload_1: |
||||||
|
case opc_dload_2: case opc_dload_3: |
||||||
|
case opc_aload_0: case opc_aload_1: |
||||||
|
case opc_aload_2: case opc_aload_3: |
||||||
|
stack[stacktop++].setValue(locals[(opcode - opc_iload_0) & 3]); |
||||||
|
break; |
||||||
|
case opc_iaload: case opc_laload: |
||||||
|
case opc_faload: case opc_daload: case opc_aaload: |
||||||
|
case opc_baload: case opc_caload: case opc_saload: { |
||||||
|
int index = stack[--stacktop].intValue(); |
||||||
|
Object array = stack[--stacktop].objectValue(); |
||||||
|
switch(opcode) { |
||||||
|
case opc_baload: |
||||||
|
stack[stacktop++].setInt(((byte[])array)[index]); |
||||||
|
break; |
||||||
|
case opc_caload: |
||||||
|
stack[stacktop++].setInt(((char[])array)[index]); |
||||||
|
break; |
||||||
|
case opc_saload: |
||||||
|
stack[stacktop++].setInt(((short[])array)[index]); |
||||||
|
break; |
||||||
|
case opc_iaload: |
||||||
|
stack[stacktop++].setInt(((int[])array)[index]); |
||||||
|
break; |
||||||
|
case opc_laload: |
||||||
|
stack[stacktop++].setLong(((long[])array)[index]); |
||||||
|
break; |
||||||
|
case opc_faload: |
||||||
|
stack[stacktop++].setFloat(((float[])array)[index]); |
||||||
|
break; |
||||||
|
case opc_daload: |
||||||
|
stack[stacktop++].setDouble(((double[])array)[index]); |
||||||
|
break; |
||||||
|
case opc_aaload: |
||||||
|
stack[stacktop++].setObject(((Object[])array)[index]); |
||||||
|
break; |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
case opc_istore: case opc_lstore: |
||||||
|
case opc_fstore: case opc_dstore: case opc_astore: |
||||||
|
locals[code[pc++]].setValue(stack[--stacktop]); |
||||||
|
break; |
||||||
|
case opc_istore_0: case opc_istore_1: |
||||||
|
case opc_istore_2: case opc_istore_3: |
||||||
|
case opc_lstore_0: case opc_lstore_1: |
||||||
|
case opc_lstore_2: case opc_lstore_3: |
||||||
|
case opc_fstore_0: case opc_fstore_1: |
||||||
|
case opc_fstore_2: case opc_fstore_3: |
||||||
|
case opc_dstore_0: case opc_dstore_1: |
||||||
|
case opc_dstore_2: case opc_dstore_3: |
||||||
|
case opc_astore_0: case opc_astore_1: |
||||||
|
case opc_astore_2: case opc_astore_3: |
||||||
|
locals[(opcode-opc_istore_0) & 3].setValue(stack[--stacktop]); |
||||||
|
break; |
||||||
|
case opc_iastore: case opc_lastore: |
||||||
|
case opc_fastore: case opc_dastore: case opc_aastore: |
||||||
|
case opc_bastore: case opc_castore: case opc_sastore: { |
||||||
|
Value value = stack[--stacktop]; |
||||||
|
int index = stack[--stacktop].intValue(); |
||||||
|
Object array = stack[--stacktop].objectValue(); |
||||||
|
switch(opcode) { |
||||||
|
case opc_baload: |
||||||
|
((byte[])array)[index] = (byte) value.intValue(); |
||||||
|
break; |
||||||
|
case opc_caload: |
||||||
|
((char[])array)[index] = (char) value.intValue(); |
||||||
|
break; |
||||||
|
case opc_saload: |
||||||
|
((short[])array)[index] = (short) value.intValue(); |
||||||
|
break; |
||||||
|
case opc_iaload: |
||||||
|
((int[])array)[index] = value.intValue(); |
||||||
|
break; |
||||||
|
case opc_laload: |
||||||
|
((long[])array)[index] = value.longValue(); |
||||||
|
break; |
||||||
|
case opc_faload: |
||||||
|
((float[])array)[index] = value.floatValue(); |
||||||
|
break; |
||||||
|
case opc_daload: |
||||||
|
((double[])array)[index] = value.doubleValue(); |
||||||
|
break; |
||||||
|
case opc_aaload: |
||||||
|
((Object[])array)[index] = value.objectValue(); |
||||||
|
break; |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
case opc_pop: case opc_pop2: |
||||||
|
stacktop -= opcode - (opc_pop-1); |
||||||
|
break; |
||||||
|
case opc_dup: case opc_dup_x1: case opc_dup_x2: { |
||||||
|
int depth = (opcode - opc_dup)%3; |
||||||
|
for (int i=0; i < depth+1; i++) |
||||||
|
stack[stacktop+1-i].setValue(stack[stacktop-i]); |
||||||
|
stack[stacktop-depth].setValue(stack[stacktop]); |
||||||
|
stacktop++; |
||||||
|
break; |
||||||
|
} |
||||||
|
case opc_dup2: case opc_dup2_x1: case opc_dup2_x2: { |
||||||
|
int depth = (opcode - opc_dup)%3; |
||||||
|
for (int i=0; i < depth+2; i++) |
||||||
|
stack[stacktop+2-i] = stack[stacktop-i]; |
||||||
|
stack[stacktop-depth].setValue(stack[stacktop+1]); |
||||||
|
stack[stacktop-depth-1].setValue(stack[stacktop]); |
||||||
|
stacktop += 2; |
||||||
|
} |
||||||
|
case opc_swap: { |
||||||
|
Value tmp = stack[stacktop-1]; |
||||||
|
stack[stacktop-1] = stack[stacktop-2]; |
||||||
|
stack[stacktop-2] = tmp; |
||||||
|
} |
||||||
|
case opc_iadd: |
||||||
|
stack[stacktop-2].setInt(stack[stacktop-2].intValue() |
||||||
|
+ stack[stacktop-1].intValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
case opc_isub: |
||||||
|
stack[stacktop-2].setInt(stack[stacktop-2].intValue() |
||||||
|
- stack[stacktop-1].intValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
case opc_imul: |
||||||
|
stack[stacktop-2].setInt(stack[stacktop-2].intValue() |
||||||
|
* stack[stacktop-1].intValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
case opc_idiv: |
||||||
|
stack[stacktop-2].setInt(stack[stacktop-2].intValue() |
||||||
|
/ stack[stacktop-1].intValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
case opc_irem: |
||||||
|
stack[stacktop-2].setInt(stack[stacktop-2].intValue() |
||||||
|
% stack[stacktop-1].intValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
|
||||||
|
case opc_ladd: |
||||||
|
stack[stacktop-2].setLong(stack[stacktop-2].longValue() |
||||||
|
+ stack[stacktop-1].longValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
case opc_lsub: |
||||||
|
stack[stacktop-2].setLong(stack[stacktop-2].longValue() |
||||||
|
- stack[stacktop-1].longValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
case opc_lmul: |
||||||
|
stack[stacktop-2].setLong(stack[stacktop-2].longValue() |
||||||
|
* stack[stacktop-1].longValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
case opc_ldiv: |
||||||
|
stack[stacktop-2].setLong(stack[stacktop-2].longValue() |
||||||
|
/ stack[stacktop-1].longValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
case opc_lrem: |
||||||
|
stack[stacktop-2].setLong(stack[stacktop-2].longValue() |
||||||
|
% stack[stacktop-1].longValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
|
||||||
|
case opc_fadd: |
||||||
|
stack[stacktop-2].setFloat(stack[stacktop-2].floatValue() |
||||||
|
+ stack[stacktop-1].floatValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
case opc_fsub: |
||||||
|
stack[stacktop-2].setFloat(stack[stacktop-2].floatValue() |
||||||
|
- stack[stacktop-1].floatValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
case opc_fmul: |
||||||
|
stack[stacktop-2].setFloat(stack[stacktop-2].floatValue() |
||||||
|
* stack[stacktop-1].floatValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
case opc_fdiv: |
||||||
|
stack[stacktop-2].setFloat(stack[stacktop-2].floatValue() |
||||||
|
/ stack[stacktop-1].floatValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
case opc_frem: |
||||||
|
stack[stacktop-2].setFloat(stack[stacktop-2].floatValue() |
||||||
|
% stack[stacktop-1].floatValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
|
||||||
|
case opc_dadd: |
||||||
|
stack[stacktop-2].setDouble(stack[stacktop-2].doubleValue() |
||||||
|
+ stack[stacktop-1].doubleValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
case opc_dsub: |
||||||
|
stack[stacktop-2].setDouble(stack[stacktop-2].doubleValue() |
||||||
|
- stack[stacktop-1].doubleValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
case opc_dmul: |
||||||
|
stack[stacktop-2].setDouble(stack[stacktop-2].doubleValue() |
||||||
|
* stack[stacktop-1].doubleValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
case opc_ddiv: |
||||||
|
stack[stacktop-2].setDouble(stack[stacktop-2].doubleValue() |
||||||
|
/ stack[stacktop-1].doubleValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
case opc_drem: |
||||||
|
stack[stacktop-2].setDouble(stack[stacktop-2].doubleValue() |
||||||
|
% stack[stacktop-1].doubleValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
|
||||||
|
case opc_ineg: |
||||||
|
stack[stacktop-1].setInt(-stack[stacktop-1].intValue()); |
||||||
|
break; |
||||||
|
case opc_lneg: |
||||||
|
stack[stacktop-1].setLong(-stack[stacktop-1].longValue()); |
||||||
|
break; |
||||||
|
case opc_fneg: |
||||||
|
stack[stacktop-1].setFloat(-stack[stacktop-1].floatValue()); |
||||||
|
break; |
||||||
|
case opc_dneg: |
||||||
|
stack[stacktop-1].setDouble(-stack[stacktop-1].doubleValue()); |
||||||
|
break; |
||||||
|
|
||||||
|
case opc_ishl: |
||||||
|
stack[stacktop-2].setInt(stack[stacktop-2].intValue() |
||||||
|
<< stack[stacktop-1].intValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
case opc_ishr: |
||||||
|
stack[stacktop-2].setInt(stack[stacktop-2].intValue() |
||||||
|
>> stack[stacktop-1].intValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
case opc_iushr: |
||||||
|
stack[stacktop-2].setInt(stack[stacktop-2].intValue() |
||||||
|
>>> stack[stacktop-1].intValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
case opc_iand: |
||||||
|
stack[stacktop-2].setInt(stack[stacktop-2].intValue() |
||||||
|
& stack[stacktop-1].intValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
case opc_ior : |
||||||
|
stack[stacktop-2].setInt(stack[stacktop-2].intValue() |
||||||
|
| stack[stacktop-1].intValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
case opc_ixor: |
||||||
|
stack[stacktop-2].setInt(stack[stacktop-2].intValue() |
||||||
|
^ stack[stacktop-1].intValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
|
||||||
|
case opc_lshl: |
||||||
|
stack[stacktop-2].setLong(stack[stacktop-2].longValue() |
||||||
|
<< stack[stacktop-1].longValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
case opc_lshr: |
||||||
|
stack[stacktop-2].setLong(stack[stacktop-2].longValue() |
||||||
|
>> stack[stacktop-1].longValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
case opc_lushr: |
||||||
|
stack[stacktop-2].setLong(stack[stacktop-2].longValue() |
||||||
|
>>> stack[stacktop-1].longValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
case opc_land: |
||||||
|
stack[stacktop-2].setLong(stack[stacktop-2].longValue() |
||||||
|
& stack[stacktop-1].longValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
case opc_lor : |
||||||
|
stack[stacktop-2].setLong(stack[stacktop-2].longValue() |
||||||
|
| stack[stacktop-1].longValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
case opc_lxor: |
||||||
|
stack[stacktop-2].setLong(stack[stacktop-2].longValue() |
||||||
|
^ stack[stacktop-1].longValue()); |
||||||
|
stacktop--; |
||||||
|
break; |
||||||
|
|
||||||
|
case opc_iinc: { |
||||||
|
int slot = code[pc++] & 0xff; |
||||||
|
locals[slot].setInt(locals[slot].intValue() + code[pc++]); |
||||||
|
break; |
||||||
|
} |
||||||
|
case opc_i2l: |
||||||
|
stack[stacktop-1] |
||||||
|
.setLong((long)stack[stacktop-1].intValue()); |
||||||
|
break; |
||||||
|
case opc_i2f: |
||||||
|
stack[stacktop-1] |
||||||
|
.setFloat((float)stack[stacktop-1].intValue()); |
||||||
|
break; |
||||||
|
case opc_i2d: |
||||||
|
stack[stacktop-1] |
||||||
|
.setDouble((double)stack[stacktop-1].intValue()); |
||||||
|
break; |
||||||
|
|
||||||
|
case opc_l2i: |
||||||
|
stack[stacktop-1] |
||||||
|
.setInt((int)stack[stacktop-1].longValue()); |
||||||
|
break; |
||||||
|
case opc_l2f: |
||||||
|
stack[stacktop-1] |
||||||
|
.setFloat((float)stack[stacktop-1].longValue()); |
||||||
|
break; |
||||||
|
case opc_l2d: |
||||||
|
stack[stacktop-1] |
||||||
|
.setDouble((double)stack[stacktop-1].longValue()); |
||||||
|
break; |
||||||
|
|
||||||
|
case opc_f2i: |
||||||
|
stack[stacktop-1] |
||||||
|
.setInt((int)stack[stacktop-1].floatValue()); |
||||||
|
break; |
||||||
|
case opc_f2l: |
||||||
|
stack[stacktop-1] |
||||||
|
.setLong((long)stack[stacktop-1].floatValue()); |
||||||
|
break; |
||||||
|
case opc_f2d: |
||||||
|
stack[stacktop-1] |
||||||
|
.setDouble((double)stack[stacktop-1].floatValue()); |
||||||
|
break; |
||||||
|
|
||||||
|
case opc_d2i: |
||||||
|
stack[stacktop-1] |
||||||
|
.setInt((int)stack[stacktop-1].doubleValue()); |
||||||
|
break; |
||||||
|
case opc_d2l: |
||||||
|
stack[stacktop-1] |
||||||
|
.setLong((long)stack[stacktop-1].doubleValue()); |
||||||
|
break; |
||||||
|
case opc_d2f: |
||||||
|
stack[stacktop-1] |
||||||
|
.setFloat((float)stack[stacktop-1].doubleValue()); |
||||||
|
break; |
||||||
|
|
||||||
|
case opc_i2b: |
||||||
|
stack[stacktop-1] |
||||||
|
.setInt((byte)stack[stacktop-1].intValue()); |
||||||
|
break; |
||||||
|
case opc_i2c: |
||||||
|
stack[stacktop-1] |
||||||
|
.setInt((char)stack[stacktop-1].intValue()); |
||||||
|
break; |
||||||
|
case opc_i2s: |
||||||
|
stack[stacktop-1] |
||||||
|
.setInt((short)stack[stacktop-1].intValue()); |
||||||
|
break; |
||||||
|
case opc_lcmp: { |
||||||
|
long val1 = stack[stacktop-2].longValue(); |
||||||
|
long val2 = stack[--stacktop].longValue(); |
||||||
|
stack[stacktop-1].setInt |
||||||
|
(val1 == val2 ? 0 : val1 < val2 ? -1 : 1); |
||||||
|
break; |
||||||
|
} |
||||||
|
case opc_fcmpl: case opc_fcmpg: { |
||||||
|
float val1 = stack[stacktop-2].floatValue(); |
||||||
|
float val2 = stack[--stacktop].floatValue(); |
||||||
|
stack[stacktop-1].setInt |
||||||
|
(val1 == val2 ? 0 |
||||||
|
: ( opcode == opc_fcmpg |
||||||
|
? (val1 < val2 ? -1 : 1) |
||||||
|
: (val1 > val2 ? 1 : -1))); |
||||||
|
break; |
||||||
|
} |
||||||
|
case opc_dcmpl: case opc_dcmpg: { |
||||||
|
double val1 = stack[stacktop-2].doubleValue(); |
||||||
|
double val2 = stack[--stacktop].doubleValue(); |
||||||
|
stack[stacktop-1].setInt |
||||||
|
(val1 == val2 ? 0 |
||||||
|
: ( opcode == opc_dcmpg |
||||||
|
? (val1 < val2 ? -1 : 1) |
||||||
|
: (val1 > val2 ? 1 : -1))); |
||||||
|
break; |
||||||
|
} |
||||||
|
case opc_ifeq: case opc_ifne: |
||||||
|
case opc_iflt: case opc_ifge: |
||||||
|
case opc_ifgt: case opc_ifle: |
||||||
|
case opc_if_icmpeq: case opc_if_icmpne: |
||||||
|
case opc_if_icmplt: case opc_if_icmpge: |
||||||
|
case opc_if_icmpgt: case opc_if_icmple: |
||||||
|
case opc_if_acmpeq: case opc_if_acmpne: |
||||||
|
case opc_ifnull: case opc_ifnonnull: { |
||||||
|
int value; |
||||||
|
if (opcode >= opc_if_acmpeq) { |
||||||
|
if (opcode >= opc_ifnull) { |
||||||
|
value = |
||||||
|
stack[--stacktop].objectValue() == null ? 0 : 1; |
||||||
|
opcode += opc_ifeq - opc_ifnull; |
||||||
|
} else { |
||||||
|
value = |
||||||
|
stack[--stacktop].objectValue() |
||||||
|
== stack[--stacktop].objectValue() ? 0 : 1; |
||||||
|
opcode += opc_ifeq - opc_if_acmpeq; |
||||||
|
} |
||||||
|
} else { |
||||||
|
value = stack[--stacktop].intValue(); |
||||||
|
if (opcode >= opc_if_icmpeq) { |
||||||
|
int val1 = stack[--stacktop].intValue(); |
||||||
|
value = (val1 == value ? 0 |
||||||
|
: val1 < value ? -1 : 1); |
||||||
|
opcode += opc_ifeq - opc_if_icmpeq; |
||||||
|
} |
||||||
|
} |
||||||
|
int offset = ((code[pc++] << 8) | (code[pc++] & 0xff)) - 3; |
||||||
|
if (value > 0 && (opcode == opc_ifgt || opcode == opc_ifge) |
||||||
|
|| value < 0 && (opcode == opc_iflt || opcode == opc_ifle) |
||||||
|
|| value == 0 && (opcode == opc_ifge || opcode == opc_ifle |
||||||
|
|| opcode == opc_ifeq)) |
||||||
|
pc += opcode; |
||||||
|
break; |
||||||
|
} |
||||||
|
case opc_jsr: |
||||||
|
stack[stacktop++].setObject(new ReturnAddress(pc)); |
||||||
|
/* fall through */ |
||||||
|
case opc_goto: |
||||||
|
pc = (pc-1) + ((code[pc] << 8) | (code[pc+1] & 0xff)); |
||||||
|
break; |
||||||
|
case opc_ret: |
||||||
|
pc = ((ReturnAddress) locals[code[pc] & 0xff].objectValue()) |
||||||
|
.getPC(); |
||||||
|
break; |
||||||
|
case opc_tableswitch: { |
||||||
|
int value = stack[--stacktop].intValue(); |
||||||
|
int start = pc - 1; |
||||||
|
pc += 3-(start % 4); |
||||||
|
int dest = ((code[pc++] << 8) | (code[pc++] & 0xff)); |
||||||
|
int low = ((code[pc++] << 8) | (code[pc++] & 0xff)); |
||||||
|
int high = ((code[pc++] << 8) | (code[pc++] & 0xff)); |
||||||
|
if (value >= low && value <= high) { |
||||||
|
pc += (value - low) << 1; |
||||||
|
dest = ((code[pc] << 8) | (code[pc+1] & 0xff)); |
||||||
|
} |
||||||
|
pc = start + dest; |
||||||
|
break; |
||||||
|
} |
||||||
|
case opc_lookupswitch: { |
||||||
|
int value = stack[--stacktop].intValue(); |
||||||
|
int start = pc - 1; |
||||||
|
pc += 3-(start % 4); |
||||||
|
int dest = ((code[pc++] << 8) | (code[pc++] & 0xff)); |
||||||
|
int npairs = ((code[pc++] << 8) | (code[pc++] & 0xff)); |
||||||
|
for (int i=0; i < npairs; i++) { |
||||||
|
if (value == ((code[pc++] << 8) | (code[pc++] & 0xff))) { |
||||||
|
dest = ((code[pc++] << 8) | (code[pc++] & 0xff)); |
||||||
|
break; |
||||||
|
} |
||||||
|
pc+=2; |
||||||
|
} |
||||||
|
pc = start + dest; |
||||||
|
break; |
||||||
|
} |
||||||
|
case opc_ireturn: case opc_lreturn: |
||||||
|
case opc_freturn: case opc_dreturn: case opc_areturn: |
||||||
|
return stack[--stacktop].objectValue(); |
||||||
|
case opc_return: |
||||||
|
return Void.TYPE; |
||||||
|
case opc_getstatic: |
||||||
|
case opc_getfield: |
||||||
|
case opc_putstatic: |
||||||
|
case opc_putfield: |
||||||
|
throw new InterpreterException |
||||||
|
("Implement get/put-static/field?"); |
||||||
|
case opc_invokevirtual: |
||||||
|
case opc_invokespecial: |
||||||
|
case opc_invokestatic : |
||||||
|
case opc_invokeinterface: { |
||||||
|
String[] ref = cpool.getRef((code[pc++] << 8) & 0xff00 |
||||||
|
| code[pc++] & 0xff); |
||||||
|
int argcount= (opcode == opc_invokeinterface) |
||||||
|
? (code[pc++] << 8) | (code[pc++] & 0xff) : -1; |
||||||
|
|
||||||
|
// if (ref[0] == currentClass.getName()) {
|
||||||
|
// /* invoke interpreter again */
|
||||||
|
// } else {
|
||||||
|
Class clazz; |
||||||
|
try { |
||||||
|
clazz = Class.forName |
||||||
|
(cpool.getClassName((code[pc++] << 8) & 0xff00 |
||||||
|
| code[pc++] & 0xff) |
||||||
|
.replace('/','.')); |
||||||
|
} catch (ClassNotFoundException ex) { |
||||||
|
throw new InterpreterException |
||||||
|
("Class "+ref[0]+" not found"); |
||||||
|
} |
||||||
|
try { |
||||||
|
if (ref[1].equals("<init>")) { |
||||||
|
Constructor[] cs = clazz.getConstructors(); |
||||||
|
Constructor c = null; |
||||||
|
for (int i=0; i< cs.length; i++) { |
||||||
|
/* check types XXX */ |
||||||
|
c = cs[i]; |
||||||
|
break; |
||||||
|
} |
||||||
|
if (c == null) |
||||||
|
throw new InterpreterException("Constructor " |
||||||
|
+ref[0]+"." |
||||||
|
+ref[1]+" not found."); |
||||||
|
Object[] args |
||||||
|
= new Object[c.getParameterTypes().length]; |
||||||
|
for (int i=args.length - 1; i >= 0; i--) |
||||||
|
args[i] = stack[--stacktop].objectValue(); |
||||||
|
NewObject newObj = |
||||||
|
(NewObject) stack[--stacktop].objectValue(); |
||||||
|
if (!newObj.getClass().equals(ref[0])) |
||||||
|
throw new InterpreterException("constructor not called" |
||||||
|
+" on new instance"); |
||||||
|
newObj.setObject(c.newInstance(args)); |
||||||
|
} else { |
||||||
|
Method[] ms = clazz.getMethods(); |
||||||
|
Method m = null; |
||||||
|
for (int i=0; i< ms.length; i++) { |
||||||
|
if (ms[i].getName().equals(ref[1])) { |
||||||
|
/* check types XXX */ |
||||||
|
m = ms[i]; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
if (m == null) |
||||||
|
throw new InterpreterException("Method "+ref[0]+"." |
||||||
|
+ref[1]+" not found."); |
||||||
|
Object obj = null; |
||||||
|
Object[] args |
||||||
|
= new Object[m.getParameterTypes().length]; |
||||||
|
for (int i=args.length - 1; i >= 0; i--) |
||||||
|
args[i] = stack[--stacktop].objectValue(); |
||||||
|
if (opcode != opc_invokestatic) |
||||||
|
obj = stack[--stacktop].objectValue(); |
||||||
|
/* special and constructor? XXX*/ |
||||||
|
Object result = m.invoke(obj, args); |
||||||
|
if (m.getReturnType() != Void.TYPE) |
||||||
|
stack[stacktop++].setObject(result); |
||||||
|
} |
||||||
|
} catch (IllegalAccessException ex) { |
||||||
|
throw new InterpreterException |
||||||
|
("Method "+ref[0]+"."+ref[1]+" not accessible"); |
||||||
|
} catch (InstantiationException ex) { |
||||||
|
throw new InterpreterException |
||||||
|
("InstantiationException in "+ref[0]+"."+ref[1]+"."); |
||||||
|
} catch (InvocationTargetException ex) { |
||||||
|
throw new InterpreterException |
||||||
|
("Method "+ref[0]+"."+ref[1]+" throwed an exception"); |
||||||
|
/*XXX exception handler?*/ |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
case opc_new: { |
||||||
|
String clazz = cpool.getClassName((code[pc++] << 8) & 0xff00 |
||||||
|
| code[pc++] & 0xff); |
||||||
|
stack[stacktop++].setObject(new NewObject(clazz)); |
||||||
|
break; |
||||||
|
} |
||||||
|
case opc_newarray: { |
||||||
|
int length = stack[--stacktop].intValue(); |
||||||
|
switch (code[pc++]) { |
||||||
|
case 4: |
||||||
|
stack[stacktop++].setObject(new boolean[length]); |
||||||
|
break; |
||||||
|
case 5: |
||||||
|
stack[stacktop++].setObject(new char[length]); |
||||||
|
break; |
||||||
|
case 6: |
||||||
|
stack[stacktop++].setObject(new float[length]); |
||||||
|
break; |
||||||
|
case 7: |
||||||
|
stack[stacktop++].setObject(new double[length]); |
||||||
|
break; |
||||||
|
case 8: |
||||||
|
stack[stacktop++].setObject(new byte[length]); |
||||||
|
break; |
||||||
|
case 9: |
||||||
|
stack[stacktop++].setObject(new short[length]); |
||||||
|
break; |
||||||
|
case 10: |
||||||
|
stack[stacktop++].setObject(new int[length]); |
||||||
|
break; |
||||||
|
case 11: |
||||||
|
stack[stacktop++].setObject(new long[length]); |
||||||
|
break; |
||||||
|
default: |
||||||
|
throw new ClassFormatException("Invalid newarray operand"); |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
case opc_anewarray: { |
||||||
|
int length = stack[--stacktop].intValue(); |
||||||
|
Class clazz; |
||||||
|
try { |
||||||
|
clazz = Class.forName |
||||||
|
(cpool.getClassName((code[pc++] << 8) & 0xff00 |
||||||
|
| code[pc++] & 0xff) |
||||||
|
.replace('/','.')); |
||||||
|
} catch (ClassNotFoundException ex) { |
||||||
|
throw new InterpreterException |
||||||
|
("Class "+ex.getMessage()+" not found"); |
||||||
|
} |
||||||
|
stack[stacktop++].setObject(Array.newInstance(clazz, length)); |
||||||
|
break; |
||||||
|
} |
||||||
|
case opc_arraylength: { |
||||||
|
Object array = stack[--stacktop].objectValue(); |
||||||
|
stack[stacktop++].setInt(Array.getLength(array)); |
||||||
|
break; |
||||||
|
} |
||||||
|
case opc_athrow: |
||||||
|
/*XXX Throw and catch ?? */ |
||||||
|
throw new InterpreterException("Throw not implemented"); |
||||||
|
case opc_checkcast: { |
||||||
|
Class clazz; |
||||||
|
try { |
||||||
|
clazz = Class.forName |
||||||
|
(cpool.getClassName((code[pc++] << 8) & 0xff00 |
||||||
|
| code[pc++] & 0xff) |
||||||
|
.replace('/','.')); |
||||||
|
} catch (ClassNotFoundException ex) { |
||||||
|
throw new InterpreterException |
||||||
|
("Class "+ex.getMessage()+" not found"); |
||||||
|
} |
||||||
|
Object obj = stack[--stacktop].objectValue(); |
||||||
|
if (obj != null && !clazz.isInstance(obj)) { |
||||||
|
/*XXX*/ |
||||||
|
throw new InterpreterException |
||||||
|
("Throw ClassCastException not implemented"); |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
case opc_instanceof: { |
||||||
|
Class clazz; |
||||||
|
try { |
||||||
|
clazz = Class.forName |
||||||
|
(cpool.getClassName((code[pc++] << 8) & 0xff00 |
||||||
|
| code[pc++] & 0xff) |
||||||
|
.replace('/','.')); |
||||||
|
} catch (ClassNotFoundException ex) { |
||||||
|
throw new InterpreterException |
||||||
|
("Class "+ex.getMessage()+" not found"); |
||||||
|
} |
||||||
|
Object obj = stack[--stacktop].objectValue(); |
||||||
|
if (obj != null && !clazz.isInstance(obj)) { |
||||||
|
/*XXX*/ |
||||||
|
throw new InterpreterException |
||||||
|
("Throw ClassCastException not implemented"); |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
case opc_monitorenter: |
||||||
|
case opc_monitorexit: |
||||||
|
throw new InterpreterException |
||||||
|
("MonitorEnter/Exit not implemented"); |
||||||
|
case opc_wide: { |
||||||
|
opcode = code[pc++] & 0xff; |
||||||
|
switch (opcode) { |
||||||
|
case opc_iload: case opc_lload: |
||||||
|
case opc_fload: case opc_dload: case opc_aload: { |
||||||
|
int slot = (code[pc++] << 8) | (code[pc++] & 0xff); |
||||||
|
stack[stacktop++].setValue(locals[slot & 0xffff]); |
||||||
|
break; |
||||||
|
} |
||||||
|
case opc_istore: case opc_lstore: |
||||||
|
case opc_fstore: case opc_dstore: case opc_astore: { |
||||||
|
int slot = (code[pc++] << 8) & 0xff00 | code[pc++] & 0xff; |
||||||
|
locals[slot & 0xffff].setValue(stack[--stacktop]); |
||||||
|
break; |
||||||
|
} |
||||||
|
case opc_iinc: { |
||||||
|
int slot = (code[pc++] << 8) & 0xff00 | code[pc++] & 0xff; |
||||||
|
int value = (code[pc++] << 8) | code[pc++] & 0xff; |
||||||
|
locals[slot].setInt(locals[slot].intValue() |
||||||
|
+ value); |
||||||
|
} |
||||||
|
case opc_ret: { |
||||||
|
int slot = (code[pc++] << 8) & 0xff00 | code[pc++] & 0xff; |
||||||
|
pc = ((ReturnAddress)locals[slot].objectValue()).getPC(); |
||||||
|
} |
||||||
|
default: |
||||||
|
throw new |
||||||
|
ClassFormatException("Invalid wide opcode "+opcode); |
||||||
|
} |
||||||
|
} |
||||||
|
case opc_multianewarray: { |
||||||
|
Class clazz; |
||||||
|
try { |
||||||
|
clazz = Class.forName |
||||||
|
(cpool.getClassName((code[pc++] << 8) & 0xff00 |
||||||
|
| code[pc++] & 0xff) |
||||||
|
.replace('/','.')); |
||||||
|
} catch (ClassNotFoundException ex) { |
||||||
|
throw new InterpreterException |
||||||
|
("Class "+ex.getMessage()+" not found"); |
||||||
|
} |
||||||
|
int dimension = code[pc++] & 0xff; |
||||||
|
int[] dims = new int[dimension]; |
||||||
|
for (int i=dimension-1; i >= 0; i--) |
||||||
|
dims[i-1] = stack[--stacktop].intValue(); |
||||||
|
stack[stacktop++].setObject(Array.newInstance(clazz, dims)); |
||||||
|
break; |
||||||
|
} |
||||||
|
case opc_jsr_w: |
||||||
|
stack[stacktop++].setObject(new ReturnAddress(pc)); |
||||||
|
/* fall through */ |
||||||
|
case opc_goto_w: |
||||||
|
pc = pc-1 + (code[pc] << 24 | ((code[pc+1]&0xff) << 16) |
||||||
|
| ((code[pc+2]&0xff) << 8) | code[pc+3]&0xff); |
||||||
|
default: |
||||||
|
throw new ClassFormatException("Invalid opcode "+opcode); |
||||||
|
} |
||||||
|
} |
||||||
|
} catch(RuntimeException ex) { |
||||||
|
throw new InterpreterException("Caught RuntimeException: " |
||||||
|
+ ex.toString()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,35 @@ |
|||||||
|
/* |
||||||
|
* InterpreterException (c) 1998 Jochen Hoenicke |
||||||
|
* |
||||||
|
* You may distribute under the terms of the GNU General Public License. |
||||||
|
* |
||||||
|
* IN NO EVENT SHALL JOCHEN HOENICKE BE LIABLE TO ANY PARTY FOR DIRECT, |
||||||
|
* INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF |
||||||
|
* THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF JOCHEN HOENICKE |
||||||
|
* HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
* JOCHEN HOENICKE SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
||||||
|
* PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" |
||||||
|
* BASIS, AND JOCHEN HOENICKE HAS NO OBLIGATION TO PROVIDE MAINTENANCE, |
||||||
|
* SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
||||||
|
* |
||||||
|
* $Id$ |
||||||
|
*/ |
||||||
|
package jode.jvm; |
||||||
|
import jode.bytecode.*; |
||||||
|
|
||||||
|
/** |
||||||
|
* This exception is thrown by the interpreter on various conditions. |
||||||
|
* |
||||||
|
* @author Jochen Hoenicke |
||||||
|
*/ |
||||||
|
public class InterpreterException extends Exception { |
||||||
|
public InterpreterException(String detail) { |
||||||
|
super(detail); |
||||||
|
} |
||||||
|
public InterpreterException() { |
||||||
|
super(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,43 @@ |
|||||||
|
/* |
||||||
|
* NewObject (c) 1998 Jochen Hoenicke |
||||||
|
* |
||||||
|
* You may distribute under the terms of the GNU General Public License. |
||||||
|
* |
||||||
|
* IN NO EVENT SHALL JOCHEN HOENICKE BE LIABLE TO ANY PARTY FOR DIRECT, |
||||||
|
* INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF |
||||||
|
* THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF JOCHEN HOENICKE |
||||||
|
* HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
* JOCHEN HOENICKE SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
||||||
|
* PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" |
||||||
|
* BASIS, AND JOCHEN HOENICKE HAS NO OBLIGATION TO PROVIDE MAINTENANCE, |
||||||
|
* SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
||||||
|
* |
||||||
|
* $Id$ |
||||||
|
*/ |
||||||
|
package jode.jvm; |
||||||
|
import jode.bytecode.*; |
||||||
|
|
||||||
|
/** |
||||||
|
* This class represents a new object, that may not be initialized yet. |
||||||
|
* |
||||||
|
* @author Jochen Hoenicke |
||||||
|
*/ |
||||||
|
public class NewObject { |
||||||
|
Object instance; |
||||||
|
String type; |
||||||
|
|
||||||
|
public NewObject(String type) { |
||||||
|
this.type = type; |
||||||
|
} |
||||||
|
|
||||||
|
public void setObject(Object obj) { |
||||||
|
instance = obj; |
||||||
|
} |
||||||
|
|
||||||
|
public Object objectValue() { |
||||||
|
return instance; |
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,30 @@ |
|||||||
|
/* |
||||||
|
* ReturnAddress (c) 1998 Jochen Hoenicke |
||||||
|
* |
||||||
|
* You may distribute under the terms of the GNU General Public License. |
||||||
|
* |
||||||
|
* IN NO EVENT SHALL JOCHEN HOENICKE BE LIABLE TO ANY PARTY FOR DIRECT, |
||||||
|
* INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF |
||||||
|
* THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF JOCHEN HOENICKE |
||||||
|
* HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
* JOCHEN HOENICKE SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
||||||
|
* PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" |
||||||
|
* BASIS, AND JOCHEN HOENICKE HAS NO OBLIGATION TO PROVIDE MAINTENANCE, |
||||||
|
* SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
||||||
|
* |
||||||
|
* $Id$ |
||||||
|
*/ |
||||||
|
package jode.jvm; |
||||||
|
|
||||||
|
class ReturnAddress { |
||||||
|
int pc; |
||||||
|
public ReturnAddress(int pc) { |
||||||
|
this.pc = pc; |
||||||
|
} |
||||||
|
|
||||||
|
public int getPC() { |
||||||
|
return pc; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,86 @@ |
|||||||
|
/* |
||||||
|
* Value (c) 1998 Jochen Hoenicke |
||||||
|
* |
||||||
|
* You may distribute under the terms of the GNU General Public License. |
||||||
|
* |
||||||
|
* IN NO EVENT SHALL JOCHEN HOENICKE BE LIABLE TO ANY PARTY FOR DIRECT, |
||||||
|
* INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF |
||||||
|
* THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF JOCHEN HOENICKE |
||||||
|
* HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
* JOCHEN HOENICKE SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
||||||
|
* PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" |
||||||
|
* BASIS, AND JOCHEN HOENICKE HAS NO OBLIGATION TO PROVIDE MAINTENANCE, |
||||||
|
* SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
||||||
|
* |
||||||
|
* $Id$ |
||||||
|
*/ |
||||||
|
package jode.jvm; |
||||||
|
import jode.bytecode.*; |
||||||
|
|
||||||
|
/** |
||||||
|
* This class represents a stack value. |
||||||
|
* |
||||||
|
* @author Jochen Hoenicke |
||||||
|
*/ |
||||||
|
public class Value { |
||||||
|
Object value; |
||||||
|
NewObject newObj; |
||||||
|
|
||||||
|
public void setObject(Object obj) { |
||||||
|
value = obj; |
||||||
|
} |
||||||
|
|
||||||
|
public Object objectValue() { |
||||||
|
if (newObj != null) |
||||||
|
return newObj.objectValue(); |
||||||
|
return value; |
||||||
|
} |
||||||
|
|
||||||
|
public void setInt(int i) { |
||||||
|
value = new Integer(i); |
||||||
|
} |
||||||
|
|
||||||
|
public int intValue() { |
||||||
|
return ((Integer)value).intValue(); |
||||||
|
} |
||||||
|
|
||||||
|
public void setLong(long i) { |
||||||
|
value = new Long(i); |
||||||
|
} |
||||||
|
|
||||||
|
public long longValue() { |
||||||
|
return ((Long)value).longValue(); |
||||||
|
} |
||||||
|
|
||||||
|
public void setFloat(float i) { |
||||||
|
value = new Float(i); |
||||||
|
} |
||||||
|
|
||||||
|
public float floatValue() { |
||||||
|
return ((Float)value).floatValue(); |
||||||
|
} |
||||||
|
|
||||||
|
public void setDouble(double i) { |
||||||
|
value = new Double(i); |
||||||
|
} |
||||||
|
|
||||||
|
public double doubleValue() { |
||||||
|
return ((Double)value).doubleValue(); |
||||||
|
} |
||||||
|
|
||||||
|
public void setNewObject(NewObject n) { |
||||||
|
newObj = n; |
||||||
|
} |
||||||
|
|
||||||
|
public NewObject getNewObject() { |
||||||
|
return newObj; |
||||||
|
} |
||||||
|
|
||||||
|
public void setValue(Value val) { |
||||||
|
value = val.value; |
||||||
|
newObj = val.newObj; |
||||||
|
} |
||||||
|
} |
||||||
|
|
Loading…
Reference in new issue