2011-07-19 14:05:08 +01:00
|
|
|
/* -*- Mode: Javascript -*-
|
|
|
|
* -*- coding: UTF-8 -*-
|
|
|
|
* Copyright (C) 2011 by Artur Ventura
|
|
|
|
*
|
|
|
|
* File: intrp.js
|
|
|
|
* Time-stamp: Fri Jul 15 02:46:27 2011
|
|
|
|
*
|
|
|
|
* Author: Artur Ventura
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
DEFOP(AALOAD)
|
|
|
|
/*
|
|
|
|
* ..., array ref, index -> ..., ref value
|
|
|
|
*/
|
|
|
|
var index = OPPOP();
|
|
|
|
var arrayref = OPPOP();
|
|
|
|
|
|
|
|
CHECK_NULL(arrayref);
|
|
|
|
CHECK_ARRAY_INDEX(index,arrayref);
|
|
|
|
|
|
|
|
OPPUSH(arrayref.value[index]);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(AASTORE)
|
|
|
|
var value = OPPOP();
|
|
|
|
var index = OPPOP();
|
|
|
|
var arrayref = OPPOP();
|
|
|
|
|
|
|
|
CHECK_NULL(arrayref);
|
|
|
|
CHECK_ARRAY_INDEX(index,arrayref);
|
|
|
|
|
|
|
|
if (!arrayref.classRef.isAssignable(value.cl)){
|
|
|
|
JVM_THROWS_NEW(java.lang.ArrayStoreException);
|
|
|
|
}
|
|
|
|
|
|
|
|
arrayref.value[index] = value;
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(ACONST_NULL)
|
|
|
|
OPPUSH(null);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(ALOAD)
|
2011-08-06 01:03:21 +01:00
|
|
|
var i = READ_NEXT();
|
2011-07-19 14:05:08 +01:00
|
|
|
OPPUSH(LOCAL_VAR(i))
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFALIAS(ALOAD_0)
|
|
|
|
DEFALIAS(ALOAD_1)
|
|
|
|
DEFALIAS(ALOAD_2)
|
|
|
|
DEFALIAS(ALOAD_3)
|
|
|
|
DEFNOP()
|
|
|
|
OPPUSH(LOCAL_VAR(OPCODE - ALOAD_0));
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(ANEWARRAY)
|
|
|
|
var indexbyte1 = READ_NEXT();
|
|
|
|
var indexbyte2 = READ_NEXT();
|
|
|
|
var count = OPPOP();
|
|
|
|
if (count < 0){
|
|
|
|
JVM_THROWS_NEW(java.lang.NegativeArraySizeException);
|
|
|
|
}
|
2011-08-06 01:03:21 +01:00
|
|
|
var clRef = xl.constantPool.get((indexbyte1 << 8) | indexbyte2);
|
2011-11-10 23:14:01 +00:00
|
|
|
var instance = make1DNativeArray(count,false,xl.jvm.classForName(clRef.jvmClassName));
|
2011-07-19 14:05:08 +01:00
|
|
|
OPPUSH(instance);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(ARETURN)
|
|
|
|
var objectref = OPPOP();
|
|
|
|
return {return_object: objectref}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(ARRAYLENGTH)
|
|
|
|
var arrayref = OPPOP();
|
2011-08-09 00:39:43 +01:00
|
|
|
if (!(arrayref.primitive == true || arrayref.primitive == false)){
|
|
|
|
PANIC("NOT AN ARRAY");
|
|
|
|
}
|
2011-07-19 14:05:08 +01:00
|
|
|
OPPUSH(arrayref.length);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(ASTORE)
|
|
|
|
var objectref = OPPOP();
|
|
|
|
LOCAL_VAR(READ_NEXT()) = objectref;
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFALIAS(ASTORE_0)
|
|
|
|
DEFALIAS(ASTORE_1)
|
|
|
|
DEFALIAS(ASTORE_2)
|
|
|
|
DEFALIAS(ASTORE_3)
|
|
|
|
DEFNOP()
|
|
|
|
var objectref = OPPOP();
|
|
|
|
LOCAL_VAR(OPCODE-ASTORE_0) = objectref;
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
|
|
|
|
DEFOP(ATHROW)
|
|
|
|
var objectref = OPPOP();
|
|
|
|
CHECK_NULL(objectref);
|
|
|
|
throw [objectref.classRef.name_ref.str,objectref];
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(BALOAD)
|
|
|
|
var value = OPPOP();
|
|
|
|
var index = OPPOP();
|
|
|
|
var arrayref = OPPOP();
|
|
|
|
|
|
|
|
CHECK_NULL(arrayref);
|
|
|
|
CHECK_ARRAY_INDEX(index,arrayref);
|
|
|
|
|
|
|
|
arrayref.value[index] = value;
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(BIPUSH)
|
2011-08-03 00:32:54 +01:00
|
|
|
OPPUSH(READ_NEXT());
|
2011-07-19 14:05:08 +01:00
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(CALOAD)
|
|
|
|
var index = OPPOP();
|
|
|
|
var arrayref = OPPOP();
|
|
|
|
|
|
|
|
OPPUSH(arrayref.value[index]);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(CASTORE)
|
|
|
|
var value = OPPOP();
|
|
|
|
var index = OPPOP();
|
|
|
|
var arrayref = OPPOP();
|
|
|
|
|
|
|
|
CHECK_NULL(arrayref);
|
|
|
|
CHECK_ARRAY_INDEX(index,arrayref);
|
|
|
|
|
|
|
|
arrayref.value[index] = value;
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(CHECKCAST)
|
|
|
|
var objectref = OPPOP();
|
|
|
|
var indexbyte1 = READ_NEXT();
|
|
|
|
var indexbyte2 = READ_NEXT();
|
|
|
|
var clRef = frame.classRef.constantPool.get((indexbyte1 << 8) | indexbyte2);
|
|
|
|
if (objectref.classRef.isAssignable(clRef)){
|
|
|
|
OPPUSH(objectref);
|
|
|
|
}else{
|
|
|
|
JVM_THROWS_NEW(java.lang.ClassCastException);
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(D2F)
|
|
|
|
var value = OPPOPD();
|
|
|
|
TO_FLOAT(value)
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(D2I)
|
|
|
|
var value = OPPOPD();
|
|
|
|
TO_INT(value);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(D2L)
|
|
|
|
var value = OPPOPD();
|
|
|
|
TO_LONG(value);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(DADD)
|
|
|
|
var value1 = OPPOPD();
|
|
|
|
var value2 = OPPOPD();
|
|
|
|
var result = value1 + value2;
|
|
|
|
if (IS_OVERFLOW(result,DOUBLE_MAX_VALUE)){
|
|
|
|
OPPUSHD(POSITIVE_INF);
|
|
|
|
}else if(IS_UNDERFLOW(result,DOUBLE_MIN_VALUE)){
|
|
|
|
OPPUSHD(NEGATIVE_INF);
|
|
|
|
}else{
|
|
|
|
OPPUSHD(result);
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(DALOAD)
|
|
|
|
var index = OPPOP();
|
|
|
|
var arrayref = OPPOP();
|
2011-07-21 09:05:18 +01:00
|
|
|
|
|
|
|
CHECK_NULL(arrayref);
|
|
|
|
CHECK_ARRAY_INDEX(index,arrayref);
|
|
|
|
|
2011-07-19 14:05:08 +01:00
|
|
|
OPPUSHD(arrayref.value[index]);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(DASTORE)
|
|
|
|
var value = OPPOPD();
|
|
|
|
var index = OPPOP();
|
|
|
|
var arrayref = OPPOP();
|
2011-07-21 09:05:18 +01:00
|
|
|
|
|
|
|
CHECK_NULL(arrayref);
|
|
|
|
CHECK_ARRAY_INDEX(index,arrayref);
|
|
|
|
|
2011-07-19 14:05:08 +01:00
|
|
|
arrayref.value[index] = value;
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFALIAS(DCMPG)
|
|
|
|
DEFALIAS(DCMPL)
|
|
|
|
DEFNOP()
|
|
|
|
var value2 = OPPOPD();
|
|
|
|
var value1 = OPPOPD();
|
|
|
|
if (isNaN(value1) || isNaN(value2)) { OPPUSH((OPCODE == DCMPG)?1:0)}
|
|
|
|
if (value1 > value2){
|
|
|
|
OPPUSH(1);
|
|
|
|
}else if(value1 == value2){
|
|
|
|
OPPUSH(0);
|
|
|
|
}else{
|
|
|
|
OPPUSH(-1);
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFALIAS(DCONST_1)
|
|
|
|
DEFALIAS(DCONST_0)
|
|
|
|
DEFNOP()
|
|
|
|
OPPUSHD(OPCODE-DCONST_0);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(DDIV)
|
|
|
|
var value2 = OPPOPD();
|
|
|
|
var value1 = OPPOPD();
|
|
|
|
var result = value1/value2;
|
|
|
|
|
|
|
|
if (IS_OVERFLOW(result,DOUBLE_MAX_VALUE)){
|
|
|
|
OPPUSHD(POSITIVE_INF);
|
|
|
|
}else if(IS_UNDERFLOW(result,DOUBLE_MIN_VALUE)){
|
|
|
|
OPPUSHD(NEGATIVE_INF);
|
|
|
|
}else{
|
|
|
|
OPPUSHD(result);
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(DLOAD)
|
|
|
|
var index = READ_NEXT();
|
|
|
|
OPPUSHD(LOCAL_VAR(index));
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFALIAS(DLOAD_0)
|
|
|
|
DEFALIAS(DLOAD_1)
|
|
|
|
DEFALIAS(DLOAD_2)
|
|
|
|
DEFALIAS(DLOAD_3)
|
|
|
|
DEFNOP()
|
|
|
|
var index = OPCODE - DLOAD_0;
|
|
|
|
OPPUSHD(LOCAL_VAR(index));
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(DMUL)
|
|
|
|
var value2 = OPPOPD();
|
|
|
|
var value1 = OPPOPD();
|
|
|
|
var result = value1*value2;
|
|
|
|
|
|
|
|
if (IS_OVERFLOW(result,DOUBLE_MAX_VALUE)){
|
|
|
|
OPPUSHD(POSITIVE_INF);
|
|
|
|
}else if(IS_UNDERFLOW(result,DOUBLE_MIN_VALUE)){
|
|
|
|
OPPUSHD(NEGATIVE_INF);
|
|
|
|
}else{
|
|
|
|
OPPUSHD(result);
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(DNEG)
|
|
|
|
OPPUSHD(NEG(OPPOPD()));
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(DREM)
|
|
|
|
var value2 = OPPOPD()
|
|
|
|
var value1 = OPPOPD()
|
|
|
|
var result = value2 % value1
|
|
|
|
|
|
|
|
if (IS_OVERFLOW(result,DOUBLE_MAX_VALUE)){
|
|
|
|
OPPUSHD(POSITIVE_INF);
|
|
|
|
}else if(IS_UNDERFLOW(result,DOUBLE_MIN_VALUE)){
|
|
|
|
OPPUSHD(NEGATIVE_INF);
|
|
|
|
}else{
|
|
|
|
OPPUSHD(result);
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(DRETURN)
|
|
|
|
var objectref = OPPOPD()
|
|
|
|
return {return_object: objectref}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(DSTORE)
|
|
|
|
var index = READ_NEXT();
|
|
|
|
var value = OPPOPD();
|
|
|
|
LOCAL_VAR(index) = value;
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFALIAS(DSTORE_0)
|
|
|
|
DEFALIAS(DSTORE_1)
|
|
|
|
DEFALIAS(DSTORE_2)
|
|
|
|
DEFALIAS(DSTORE_3)
|
|
|
|
DEFNOP()
|
2011-08-04 16:40:14 +01:00
|
|
|
var index = OPCODE - DSTORE_0;
|
2011-07-19 14:05:08 +01:00
|
|
|
var value = OPPOPD();
|
|
|
|
LOCAL_VAR(index) = value;
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(DSUB)
|
|
|
|
var value2 = OPPOPD()
|
|
|
|
var value1 = OPPOPD()
|
|
|
|
var result = value2 % value1
|
|
|
|
|
|
|
|
if (IS_OVERFLOW(result,DOUBLE_MAX_VALUE)){
|
|
|
|
OPPUSHD(POSITIVE_INF);
|
|
|
|
}else if(IS_UNDERFLOW(result,DOUBLE_MIN_VALUE)){
|
|
|
|
OPPUSHD(NEGATIVE_INF);
|
|
|
|
}else{
|
|
|
|
OPPUSHD(result);
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(DUP)
|
|
|
|
STACK_MOVE(0,1)
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(DUP_X1)
|
|
|
|
STACK_MOVE(0,1)
|
|
|
|
STACK_MOVE(1,2)
|
|
|
|
STACK_MOVE(2,0)
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(DUP_X2)
|
|
|
|
STACK_MOVE(0,1)
|
|
|
|
STACK_MOVE(1,2)
|
|
|
|
STACK_MOVE(2,3)
|
|
|
|
STACK_MOVE(3,0)
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(DUP2)
|
|
|
|
STACK_MOVE(0,2)
|
|
|
|
STACK_MOVE(1,3)
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(DUP2_X1)
|
|
|
|
STACK_MOVE(0,2)
|
|
|
|
STACK_MOVE(1,3)
|
|
|
|
STACK_MOVE(2,4)
|
|
|
|
STACK_MOVE(3,0)
|
|
|
|
STACK_MOVE(4,1)
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(DUP2)
|
|
|
|
STACK_MOVE(0, 2);
|
|
|
|
STACK_MOVE(1, 3);
|
|
|
|
STACK_MOVE(2, 4);
|
|
|
|
STACK_MOVE(3, 5);
|
|
|
|
STACK_MOVE(4, 0);
|
|
|
|
STACK_MOVE(5, 1);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(F2D)
|
|
|
|
// No Op, can box in the same space.
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(F2I)
|
|
|
|
var value = OPPOPD();
|
|
|
|
TO_INT(value);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(F2L)
|
|
|
|
var value = OPPOPD();
|
|
|
|
TO_LONG(value);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(FADD)
|
|
|
|
var value1 = OPPOPD();
|
|
|
|
var value2 = OPPOPD();
|
|
|
|
var result = value1 + value2;
|
|
|
|
if (IS_OVERFLOW(result,FLOAT_MAX_VALUE)){
|
|
|
|
OPPUSHD(POSITIVE_INF);
|
|
|
|
}else if(IS_UNDERFLOW(result,FLOAT_MIN_VALUE)){
|
|
|
|
OPPUSHD(NEGATIVE_INF);
|
|
|
|
}else{
|
|
|
|
OPPUSHD(result);
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(FALOAD)
|
|
|
|
var index = OPPOP();
|
|
|
|
var arrayref = OPPOP();
|
2011-07-21 09:05:18 +01:00
|
|
|
|
|
|
|
CHECK_NULL(arrayref);
|
|
|
|
CHECK_ARRAY_INDEX(index,arrayref);
|
|
|
|
|
2011-07-19 14:05:08 +01:00
|
|
|
OPPUSHD(arrayref.value[index]);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(FASTORE)
|
|
|
|
var value = OPPOPD();
|
|
|
|
var index = OPPOP();
|
|
|
|
var arrayref = OPPOP();
|
2011-07-21 09:05:18 +01:00
|
|
|
|
|
|
|
CHECK_NULL(arrayref);
|
|
|
|
CHECK_ARRAY_INDEX(index,arrayref);
|
|
|
|
|
2011-07-19 14:05:08 +01:00
|
|
|
arrayref.value[index] = value;
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFALIAS(FCMPG)
|
|
|
|
DEFALIAS(FCMPL)
|
|
|
|
DEFNOP()
|
|
|
|
var value2 = OPPOPD();
|
|
|
|
var value1 = OPPOPD();
|
|
|
|
if (isNaN(value1) || isNaN(value2)) { OPPUSH((OPCODE == FCMPG)?1:0)}
|
|
|
|
if (value1 > value2){
|
|
|
|
OPPUSH(1);
|
|
|
|
}else if(value1 == value2){
|
|
|
|
OPPUSH(0);
|
|
|
|
}else{
|
|
|
|
OPPUSH(-1);
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFALIAS(FCONST_1)
|
|
|
|
DEFALIAS(FCONST_0)
|
|
|
|
DEFNOP()
|
|
|
|
OPPUSHD(OPCODE-FCONST_0);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(FDIV)
|
|
|
|
var value2 = OPPOPD();
|
|
|
|
var value1 = OPPOPD();
|
|
|
|
var result = value1*value2;
|
|
|
|
|
|
|
|
if (IS_OVERFLOW(result,FLOAT_MAX_VALUE)){
|
|
|
|
OPPUSHD(POSITIVE_INF);
|
|
|
|
}else if(IS_UNDERFLOW(result,FLOAT_MIN_VALUE)){
|
|
|
|
OPPUSHD(NEGATIVE_INF);
|
|
|
|
}else{
|
|
|
|
OPPUSHD(result);
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(FLOAD)
|
|
|
|
var index = READ_NEXT();
|
|
|
|
OPPUSHD(LOCAL_VAR(index));
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFALIAS(FLOAD_0)
|
|
|
|
DEFALIAS(FLOAD_1)
|
|
|
|
DEFALIAS(FLOAD_2)
|
|
|
|
DEFALIAS(FLOAD_3)
|
|
|
|
DEFNOP()
|
|
|
|
var index = OPCODE - FLOAD_0;
|
|
|
|
OPPUSHD(LOCAL_VAR(index));
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(FMUL)
|
|
|
|
var value2 = OPPOPD();
|
|
|
|
var value1 = OPPOPD();
|
|
|
|
var result = value1*value2;
|
|
|
|
|
|
|
|
if (IS_OVERFLOW(result,FLOAT_MAX_VALUE)){
|
|
|
|
OPPUSHD(POSITIVE_INF);
|
|
|
|
}else if(IS_UNDERFLOW(result,FLOAT_MIN_VALUE)){
|
|
|
|
OPPUSHD(NEGATIVE_INF);
|
|
|
|
}else{
|
|
|
|
OPPUSHD(result);
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(FNEG)
|
|
|
|
OPPUSHD(NEG(OPPOPD()));
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(FREM)
|
|
|
|
var value2 = OPPOPD()
|
|
|
|
var value1 = OPPOPD()
|
|
|
|
var result = value2 % value1
|
|
|
|
|
|
|
|
if (IS_OVERFLOW(result,FLOAT_MAX_VALUE)){
|
|
|
|
OPPUSHD(POSITIVE_INF);
|
|
|
|
}else if(IS_UNDERFLOW(result,FLOAT_MIN_VALUE)){
|
|
|
|
OPPUSHD(NEGATIVE_INF);
|
|
|
|
}else{
|
|
|
|
OPPUSHD(result);
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(FRETURN)
|
|
|
|
var objectref = OPPOPD()
|
|
|
|
return {return_object: objectref}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(FSTORE)
|
|
|
|
var index = READ_NEXT();
|
|
|
|
var value = OPPOPD();
|
|
|
|
LOCAL_VAR(index) = value;
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFALIAS(FSTORE_0)
|
|
|
|
DEFALIAS(FSTORE_1)
|
|
|
|
DEFALIAS(FSTORE_2)
|
|
|
|
DEFALIAS(FSTORE_3)
|
|
|
|
DEFNOP()
|
|
|
|
var index = OPCODE - DLOAD_0;
|
|
|
|
var value = OPPOPD();
|
|
|
|
LOCAL_VAR(index) = value;
|
|
|
|
ENDDEF
|
|
|
|
|
2011-07-21 19:03:57 +01:00
|
|
|
DEFOP(FLOAT_MAX_VALUE)
|
2011-07-19 14:05:08 +01:00
|
|
|
var value2 = OPPOPD()
|
|
|
|
var value1 = OPPOPD()
|
|
|
|
var result = value2 % value1
|
|
|
|
|
|
|
|
if (IS_OVERFLOW(result,FLOAT_MAX_VALUE)){
|
|
|
|
OPPUSHD(POSITIVE_INF);
|
|
|
|
}else if(IS_UNDERFLOW(result,FLOAT_MIN_VALUE)){
|
|
|
|
OPPUSHD(NEGATIVE_INF);
|
|
|
|
}else{
|
|
|
|
OPPUSHD(result);
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(GETFIELD)
|
|
|
|
var indexbyte1 = READ_NEXT();
|
|
|
|
var indexbyte2 = READ_NEXT();
|
|
|
|
var objectref = OPPOP();
|
|
|
|
|
|
|
|
CHECK_NULL(objectref)
|
2011-08-09 00:39:43 +01:00
|
|
|
var field = xl.constantPool.get((indexbyte1 << 8) | indexbyte2);
|
2011-08-11 19:07:48 +01:00
|
|
|
var fieldSig = field.class_ref.name_ref.str + " " + field.name_and_type_ref.name_ref.str ;
|
|
|
|
if (!(fieldSig in objectref)){
|
|
|
|
fieldSig = xl.resolveField(field.name_and_type_ref.name_ref.str);
|
|
|
|
}
|
|
|
|
OPPUSH(objectref[fieldSig]);
|
|
|
|
LOG(fieldSig);
|
2011-07-19 14:05:08 +01:00
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(GETSTATIC)
|
2011-07-21 09:05:18 +01:00
|
|
|
var indexbyte1 = READ_NEXT();
|
|
|
|
var indexbyte2 = READ_NEXT();
|
|
|
|
|
2011-08-06 01:03:21 +01:00
|
|
|
var field = xl.constantPool.get((indexbyte1 << 8) | indexbyte2);
|
2011-11-10 23:14:01 +00:00
|
|
|
var aClass = canonicalName(field.class_ref.name_ref);
|
2011-07-21 09:05:18 +01:00
|
|
|
|
|
|
|
//check if static
|
2011-11-10 23:14:01 +00:00
|
|
|
OPPUSH(xl.jvm.classForName(aClass)[field.class_ref.name_ref.str + " " + field.name_and_type_ref.name_ref.str]);
|
2011-07-21 09:05:18 +01:00
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(GOTO)
|
|
|
|
var branchbyte1 = READ_NEXT();
|
|
|
|
var branchbyte2 = READ_NEXT();
|
|
|
|
|
|
|
|
var branchoffset = (branchbyte1 << 8) | branchbyte2;
|
2011-08-09 00:39:43 +01:00
|
|
|
PC = PC + branchoffset - 3;
|
2011-07-21 09:05:18 +01:00
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(GOTO_W)
|
|
|
|
var branchbyte1 = READ_NEXT();
|
|
|
|
var branchbyte2 = READ_NEXT();
|
|
|
|
var branchbyte3 = READ_NEXT();
|
|
|
|
var branchbyte4 = READ_NEXT();
|
|
|
|
|
|
|
|
var branchoffset = (branchbyte1 << 24) | (branchbyte2 << 16) | (branchbyte3 << 8) | branchbyte4;
|
2011-08-09 00:39:43 +01:00
|
|
|
PC = PC + branchoffset - 5;
|
2011-07-21 09:05:18 +01:00
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(I2B)
|
|
|
|
var value = OPPOP();
|
|
|
|
|
|
|
|
if (IS_OVERFLOW(value,BYTE_MAX_VALUE) || IS_UNDERFLOW(result,BYTE_MIN_VALUE)){
|
|
|
|
OPPUSH(BYTE_OVERFLOW(value));
|
|
|
|
}else{
|
|
|
|
OPPUSH(value);
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(I2C)
|
|
|
|
var value = OPPOP()
|
|
|
|
|
|
|
|
if (IS_OVERFLOW(value,CHAR_MAX_VALUE) || IS_UNDERFLOW(result,CHAR_MIN_VALUE)){
|
|
|
|
OPPUSH(CHAR_OVERFLOW(value));
|
|
|
|
}else{
|
|
|
|
OPPUSH(value);
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(I2D)
|
|
|
|
OPPUSH(null);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(I2F)
|
|
|
|
OPPUSH(null);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(I2L)
|
|
|
|
//NOP because it is the same size.
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(IADD)
|
|
|
|
var value1 = OPPOP();
|
|
|
|
var value2 = OPPOP();
|
|
|
|
var result = value1 + value2;
|
2011-07-21 16:10:43 +01:00
|
|
|
if (IS_OVERFLOW(result,INT_MAX_VALUE)){
|
2011-07-21 09:05:18 +01:00
|
|
|
OPPUSH(INT_OVERFLOW(result));
|
|
|
|
}else{
|
|
|
|
OPPUSH(result);
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(IALOAD)
|
|
|
|
var index = OPPOP();
|
|
|
|
var arrayref = OPPOP();
|
|
|
|
|
|
|
|
CHECK_NULL(arrayref);
|
|
|
|
CHECK_ARRAY_INDEX(index,arrayref);
|
|
|
|
|
|
|
|
OPPUSH(arrayref.value[index]);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(IAND)
|
|
|
|
var value1 = OPPOP()
|
|
|
|
var value2 = OPPOP()
|
|
|
|
var result = value1 & value2
|
|
|
|
OPPUSH(result);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(IASTORE)
|
2011-08-06 01:03:21 +01:00
|
|
|
var value = OPPOP();
|
2011-07-21 09:05:18 +01:00
|
|
|
var index = OPPOP();
|
|
|
|
var arrayref = OPPOP();
|
2011-08-06 01:03:21 +01:00
|
|
|
|
2011-07-21 09:05:18 +01:00
|
|
|
CHECK_NULL(arrayref);
|
|
|
|
CHECK_ARRAY_INDEX(index,arrayref);
|
|
|
|
|
|
|
|
arrayref.value[index] = value;
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFALIAS(ICONST_M1)
|
|
|
|
DEFALIAS(ICONST_0)
|
|
|
|
DEFALIAS(ICONST_1)
|
|
|
|
DEFALIAS(ICONST_2)
|
|
|
|
DEFALIAS(ICONST_3)
|
|
|
|
DEFALIAS(ICONST_4)
|
|
|
|
DEFALIAS(ICONST_5)
|
|
|
|
DEFNOP()
|
|
|
|
OPPUSH(OPCODE - ICONST_0)
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(IDIV)
|
|
|
|
var value1 = OPPOP();
|
|
|
|
var value2 = OPPOP();
|
|
|
|
if(value2 == 0){
|
|
|
|
JVM_THROWS_NEW(java.lang.ArithmeticException);
|
|
|
|
}
|
2011-07-19 14:05:08 +01:00
|
|
|
|
2011-07-21 09:05:18 +01:00
|
|
|
var result = Math.round(value1 / value2);
|
2011-07-21 19:03:57 +01:00
|
|
|
OPPUSH(result);
|
2011-07-21 09:05:18 +01:00
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(IF_ACMPEQ)
|
|
|
|
var branchbyte1 = READ_NEXT();
|
|
|
|
var branchbyte2 = READ_NEXT();
|
|
|
|
var value1 = OPPOP();
|
|
|
|
var value2 = OPPOP();
|
|
|
|
if (value1 == value2){
|
|
|
|
var branchoffset = (branchbyte1 << 8) | branchbyte2;
|
2011-08-09 00:39:43 +01:00
|
|
|
PC = PC + branchoffset - 3;
|
2011-07-21 09:05:18 +01:00
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(IF_ACMPNE)
|
|
|
|
var branchbyte1 = READ_NEXT();
|
|
|
|
var branchbyte2 = READ_NEXT();
|
|
|
|
var value1 = OPPOP();
|
|
|
|
var value2 = OPPOP();
|
|
|
|
if (value1 != value2){
|
|
|
|
var branchoffset = (branchbyte1 << 8) | branchbyte2;
|
2011-08-09 00:39:43 +01:00
|
|
|
PC = PC + branchoffset - 3;
|
2011-07-21 09:05:18 +01:00
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(IF_ICMPEQ)
|
|
|
|
var branchbyte1 = READ_NEXT();
|
|
|
|
var branchbyte2 = READ_NEXT();
|
|
|
|
var value1 = OPPOP();
|
|
|
|
var value2 = OPPOP();
|
|
|
|
if (value1 == value2){
|
|
|
|
var branchoffset = (branchbyte1 << 8) | branchbyte2;
|
2011-08-09 00:39:43 +01:00
|
|
|
PC = PC + branchoffset - 3;
|
2011-07-21 09:05:18 +01:00
|
|
|
}
|
2011-07-19 14:05:08 +01:00
|
|
|
ENDDEF
|
2011-07-21 09:05:18 +01:00
|
|
|
|
|
|
|
DEFOP(IF_ICMPNE)
|
|
|
|
var branchbyte1 = READ_NEXT();
|
|
|
|
var branchbyte2 = READ_NEXT();
|
|
|
|
var value1 = OPPOP();
|
|
|
|
var value2 = OPPOP();
|
|
|
|
if (value1 != value2){
|
|
|
|
var branchoffset = (branchbyte1 << 8) | branchbyte2;
|
2011-08-09 00:39:43 +01:00
|
|
|
PC = PC + branchoffset - 3;
|
2011-07-21 09:05:18 +01:00
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(IF_ICMPLT)
|
|
|
|
var branchbyte1 = READ_NEXT();
|
|
|
|
var branchbyte2 = READ_NEXT();
|
|
|
|
var value2 = OPPOP();
|
2011-08-09 00:39:43 +01:00
|
|
|
var value1 = OPPOP();
|
2011-07-21 09:05:18 +01:00
|
|
|
if (value1 < value2){
|
|
|
|
var branchoffset = (branchbyte1 << 8) | branchbyte2;
|
2011-08-09 00:39:43 +01:00
|
|
|
PC = PC + branchoffset - 3;
|
2011-07-21 09:05:18 +01:00
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(IF_ICMPLE)
|
|
|
|
var branchbyte1 = READ_NEXT();
|
|
|
|
var branchbyte2 = READ_NEXT();
|
|
|
|
var value2 = OPPOP();
|
2011-08-09 00:39:43 +01:00
|
|
|
var value1 = OPPOP();
|
2011-07-21 09:05:18 +01:00
|
|
|
if (value1 <= value2){
|
|
|
|
var branchoffset = (branchbyte1 << 8) | branchbyte2;
|
2011-08-09 00:39:43 +01:00
|
|
|
PC = PC + branchoffset - 3;
|
2011-07-21 09:05:18 +01:00
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(IF_ICMPGT)
|
|
|
|
var branchbyte1 = READ_NEXT();
|
|
|
|
var branchbyte2 = READ_NEXT();
|
|
|
|
var value2 = OPPOP();
|
2011-08-09 00:39:43 +01:00
|
|
|
var value1 = OPPOP();
|
2011-07-21 16:10:43 +01:00
|
|
|
if (value1 > value2){
|
2011-07-21 09:05:18 +01:00
|
|
|
var branchoffset = (branchbyte1 << 8) | branchbyte2;
|
2011-08-09 00:39:43 +01:00
|
|
|
PC = PC + branchoffset - 3;
|
2011-07-21 09:05:18 +01:00
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
2011-07-21 16:10:43 +01:00
|
|
|
DEFOP(IF_ICMPGE)
|
2011-07-21 09:05:18 +01:00
|
|
|
var branchbyte1 = READ_NEXT();
|
|
|
|
var branchbyte2 = READ_NEXT();
|
|
|
|
var value2 = OPPOP();
|
2011-08-09 00:39:43 +01:00
|
|
|
var value1 = OPPOP();
|
2011-07-21 16:10:43 +01:00
|
|
|
if (value1 >= value2){
|
2011-07-21 09:05:18 +01:00
|
|
|
var branchoffset = (branchbyte1 << 8) | branchbyte2;
|
2011-08-09 00:39:43 +01:00
|
|
|
PC = PC + branchoffset - 3;
|
2011-07-21 09:05:18 +01:00
|
|
|
}
|
2011-07-21 16:10:43 +01:00
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(IFEQ)
|
|
|
|
var branchbyte1 = READ_NEXT();
|
|
|
|
var branchbyte2 = READ_NEXT();
|
|
|
|
var value = OPPOP();
|
|
|
|
|
|
|
|
if (value == 0){
|
|
|
|
var branchoffset = (branchbyte1 << 8) | branchbyte2;
|
2011-08-09 00:39:43 +01:00
|
|
|
PC = PC + branchoffset - 3;
|
2011-07-21 16:10:43 +01:00
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(IFNE)
|
|
|
|
var branchbyte1 = READ_NEXT();
|
|
|
|
var branchbyte2 = READ_NEXT();
|
|
|
|
var value = OPPOP();
|
|
|
|
|
|
|
|
if (value != 0){
|
|
|
|
var branchoffset = (branchbyte1 << 8) | branchbyte2;
|
2011-08-09 00:39:43 +01:00
|
|
|
PC = PC + branchoffset - 3;
|
2011-07-21 16:10:43 +01:00
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(IFLT)
|
|
|
|
var branchbyte1 = READ_NEXT();
|
|
|
|
var branchbyte2 = READ_NEXT();
|
|
|
|
var value = OPPOP();
|
|
|
|
|
|
|
|
if (value < 0){
|
|
|
|
var branchoffset = (branchbyte1 << 8) | branchbyte2;
|
2011-08-09 00:39:43 +01:00
|
|
|
PC = PC + branchoffset - 3;
|
2011-07-21 16:10:43 +01:00
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(IFLE)
|
|
|
|
var branchbyte1 = READ_NEXT();
|
|
|
|
var branchbyte2 = READ_NEXT();
|
|
|
|
var value = OPPOP();
|
|
|
|
|
|
|
|
if (value <= 0){
|
|
|
|
var branchoffset = (branchbyte1 << 8) | branchbyte2;
|
2011-08-09 00:39:43 +01:00
|
|
|
PC = PC + branchoffset - 3;
|
2011-07-21 16:10:43 +01:00
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(IFGT)
|
|
|
|
var branchbyte1 = READ_NEXT();
|
|
|
|
var branchbyte2 = READ_NEXT();
|
|
|
|
var value = OPPOP();
|
|
|
|
|
|
|
|
if (value > 0){
|
|
|
|
var branchoffset = (branchbyte1 << 8) | branchbyte2;
|
2011-08-09 00:39:43 +01:00
|
|
|
PC = PC + branchoffset - 3;
|
2011-07-21 16:10:43 +01:00
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(IFGE)
|
|
|
|
var branchbyte1 = READ_NEXT();
|
|
|
|
var branchbyte2 = READ_NEXT();
|
|
|
|
var value = OPPOP();
|
|
|
|
|
|
|
|
if (value >= 0){
|
|
|
|
var branchoffset = (branchbyte1 << 8) | branchbyte2;
|
2011-08-09 00:39:43 +01:00
|
|
|
PC = PC + branchoffset - 3;
|
2011-07-21 16:10:43 +01:00
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(IFNONNULL)
|
|
|
|
var branchbyte1 = READ_NEXT();
|
|
|
|
var branchbyte2 = READ_NEXT();
|
|
|
|
var value = OPPOP();
|
|
|
|
|
|
|
|
if (value != NULL){
|
|
|
|
var branchoffset = (branchbyte1 << 8) | branchbyte2;
|
2011-08-09 00:39:43 +01:00
|
|
|
PC = PC + branchoffset - 3;
|
2011-07-21 16:10:43 +01:00
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(IFNULL)
|
|
|
|
var branchbyte1 = READ_NEXT();
|
|
|
|
var branchbyte2 = READ_NEXT();
|
|
|
|
var value = OPPOP();
|
|
|
|
|
|
|
|
if (value != NULL){
|
|
|
|
var branchoffset = (branchbyte1 << 8) | branchbyte2;
|
2011-08-09 00:39:43 +01:00
|
|
|
PC = PC + branchoffset - 3;
|
2011-07-21 16:10:43 +01:00
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(IINC)
|
|
|
|
var index = READ_NEXT();
|
|
|
|
var aConst = READ_NEXT();
|
|
|
|
LOCAL_VAR(index)++;
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(ILOAD)
|
|
|
|
var index = READ_NEXT();
|
|
|
|
OPPUSH(LOCAL_VAR(index));
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFALIAS(ILOAD_0)
|
|
|
|
DEFALIAS(ILOAD_1)
|
|
|
|
DEFALIAS(ILOAD_2)
|
|
|
|
DEFALIAS(ILOAD_3)
|
|
|
|
DEFNOP()
|
2011-08-09 00:39:43 +01:00
|
|
|
OPPUSH(LOCAL_VAR(OPCODE - ILOAD_0));
|
2011-07-21 16:10:43 +01:00
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(IMUL)
|
|
|
|
var value1 = OPPOP();
|
|
|
|
var value2 = OPPOP();
|
|
|
|
var result = value1 * value2;
|
|
|
|
if (IS_OVERFLOW(result,INT_MAX_VALUE)){
|
|
|
|
OPPUSH(INT_OVERFLOW(result));
|
|
|
|
}else{
|
|
|
|
OPPUSH(result);
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(INEG)
|
|
|
|
var value = OPPOP();
|
|
|
|
var result = 0 - value;
|
|
|
|
if (IS_OVERFLOW(result,INT_MAX_VALUE) || IS_UNDERFLOW(result,INT_MINVALUE)){
|
|
|
|
OPPUSH(INT_OVERFLOW(result));
|
|
|
|
}else{
|
|
|
|
OPPUSH(result);
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(INSTANCEOF)
|
|
|
|
var indexbyte1 = READ_NEXT();
|
|
|
|
var indexbyte2 = READ_NEXT();
|
|
|
|
|
|
|
|
var objectref = OPPOP();
|
2011-07-21 19:03:57 +01:00
|
|
|
if (objectref == null){
|
|
|
|
OPPUSH(0);
|
|
|
|
break;
|
|
|
|
}
|
2011-08-06 01:03:21 +01:00
|
|
|
var className = canonicalName(xl.constantPool.get((indexbyte1 << 8) | indexbyte2).name_ref);
|
2011-07-21 16:10:43 +01:00
|
|
|
|
2011-07-21 19:03:57 +01:00
|
|
|
if(objectref["class"].isAssignable(jvm.classForName(className))){
|
|
|
|
OPPUSH(1);
|
|
|
|
}else{
|
|
|
|
OPPUSH(0);
|
|
|
|
}
|
2011-07-21 16:10:43 +01:00
|
|
|
ENDDEF
|
|
|
|
|
2011-07-21 19:03:57 +01:00
|
|
|
//###############################
|
|
|
|
//## INVOKES !
|
|
|
|
//###############################
|
|
|
|
|
2011-07-21 16:10:43 +01:00
|
|
|
DEFOP(INVOKEINTERFACE)
|
|
|
|
var indexbyte1 = READ_NEXT();
|
|
|
|
var indexbyte2 = READ_NEXT();
|
|
|
|
var count = READ_NEXT();
|
|
|
|
/* expected 0*/ READ_NEXT();
|
2011-07-21 19:03:57 +01:00
|
|
|
var args = [];
|
2011-07-21 16:10:43 +01:00
|
|
|
|
2011-08-06 01:03:21 +01:00
|
|
|
var method = xl.constantPool.get((indexbyte1 << 8) | indexbyte2);
|
2011-07-21 19:03:57 +01:00
|
|
|
for(var i=0; i<method.descriptor.args.length; i++){
|
|
|
|
args.push(OPPOP());
|
|
|
|
}
|
|
|
|
var objectref = OPPOP();
|
|
|
|
|
|
|
|
PANIC("NOT IMPLEMENTED YET");
|
2011-07-21 16:10:43 +01:00
|
|
|
ENDDEF
|
2011-07-21 19:03:57 +01:00
|
|
|
|
|
|
|
DEFOP(INVOKESPECIAL)
|
|
|
|
var indexbyte1 = READ_NEXT();
|
|
|
|
var indexbyte2 = READ_NEXT();
|
|
|
|
|
2011-08-06 01:03:21 +01:00
|
|
|
var methodDesrc = xl.constantPool.get((indexbyte1 << 8) | indexbyte2);
|
|
|
|
var cl = xl.jvm.classForName(methodDesrc.class_ref.jvmClassName);
|
|
|
|
var methodId = "method " + methodDesrc.name_and_type_ref.name_ref.str + methodDesrc.name_and_type_ref.descriptor_ref.str
|
|
|
|
var method = cl[methodId];
|
|
|
|
var args = OPSTACK_MULTIPOP(OPSTACK_LENGTH() - method.descriptor.args.length-1);
|
|
|
|
var result;
|
|
|
|
if(method.access_flags & ACC_NATIVE){
|
|
|
|
PANIC("INVOKESPECIAL NATIVE CALL")
|
|
|
|
}else{
|
|
|
|
result = method.invoke(args,cl);
|
|
|
|
}
|
|
|
|
if (result != undefined){
|
|
|
|
OPPUSH(result.return_object);
|
2011-07-21 19:03:57 +01:00
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(INVOKESTATIC)
|
|
|
|
var indexbyte1 = READ_NEXT();
|
|
|
|
var indexbyte2 = READ_NEXT();
|
|
|
|
var args = [];
|
|
|
|
|
2011-08-09 00:39:43 +01:00
|
|
|
var methodDesrc = xl.constantPool.get((indexbyte1 << 8) | indexbyte2);
|
|
|
|
var cl = xl.jvm.classForName(methodDesrc.class_ref.jvmClassName);
|
|
|
|
var methodId = "method " + methodDesrc.name_and_type_ref.name_ref.str + methodDesrc.name_and_type_ref.descriptor_ref.str
|
|
|
|
var method = cl[methodId];
|
|
|
|
var args = OPSTACK_MULTIPOP(OPSTACK_LENGTH() - method.descriptor.args.length);
|
|
|
|
var result;
|
|
|
|
if(method.access_flags & ACC_NATIVE){
|
2011-11-10 23:14:01 +00:00
|
|
|
var className = canonicalName(cl.this_class.name_ref);
|
2011-11-15 11:26:58 +00:00
|
|
|
LOG("Calling " + className + " " + method.name_ref.str + method.descriptor_ref.str)
|
|
|
|
LOG("!! NATIVE !!")
|
|
|
|
if (xl.jvm.internalJNITable[className] && methodId in xl.jvm.internalJNITable[className]){
|
2011-11-17 03:09:48 +00:00
|
|
|
result = {return_object: xl.jvm.internalJNITable[className][methodId].apply(cl,args)};
|
2011-11-15 11:26:58 +00:00
|
|
|
}else if (xl.jvm.JNITable[className] && methodId in xl.jvm.JNITable[className]){
|
2011-11-17 03:09:48 +00:00
|
|
|
result = {return_object: xl.jvm.JNITable[className][methodId].apply(cl,args)};s
|
2011-08-09 00:39:43 +01:00
|
|
|
}else{
|
|
|
|
PANIC(methodId + " declared as native but not mapped");
|
|
|
|
}
|
2011-11-15 11:26:58 +00:00
|
|
|
LOG("Returing from " + className + " " + method.name_ref.str + method.descriptor_ref.str)
|
2011-08-09 00:39:43 +01:00
|
|
|
}else{
|
|
|
|
result = method.invoke(args,cl);
|
|
|
|
}
|
2011-11-17 03:09:48 +00:00
|
|
|
if (result != undefined && result.return_object!= undefined){
|
|
|
|
OPPUSH(result.return_object);
|
2011-07-21 19:03:57 +01:00
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
2011-08-03 00:32:54 +01:00
|
|
|
DEFOP(INVOKEVIRTUAL)
|
2011-07-21 19:03:57 +01:00
|
|
|
var indexbyte1 = READ_NEXT();
|
|
|
|
var indexbyte2 = READ_NEXT();
|
|
|
|
var args = [];
|
|
|
|
|
2011-08-06 01:03:21 +01:00
|
|
|
var methodDesrc = xl.constantPool.get((indexbyte1 << 8) | indexbyte2);
|
|
|
|
var cl = xl.jvm.classForName(methodDesrc.class_ref.jvmClassName);
|
|
|
|
var methodId = "method " + methodDesrc.name_and_type_ref.name_ref.str + methodDesrc.name_and_type_ref.descriptor_ref.str
|
|
|
|
var method = cl[methodId];
|
2011-08-09 00:39:43 +01:00
|
|
|
var args = OPSTACK_MULTIPOP(OPSTACK_LENGTH() - method.descriptor.args.length - 1);
|
2011-08-06 01:03:21 +01:00
|
|
|
var result;
|
|
|
|
if(method.access_flags & ACC_NATIVE){
|
|
|
|
PANIC("INVOKEVIRTUAL NATIVE CALL")
|
|
|
|
}else{
|
|
|
|
result = method.invoke(args,cl);
|
|
|
|
}
|
|
|
|
if (result != undefined){
|
|
|
|
OPPUSH(result.return_object);
|
2011-07-21 19:03:57 +01:00
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(IOR)
|
|
|
|
var value1 = OPPOP();
|
|
|
|
var value2 = OPPOP();
|
|
|
|
|
|
|
|
OPPUSH(INT_OVERFLOW(value1 | value2));
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(IREM)
|
|
|
|
var value1 = OPPOP();
|
|
|
|
var value2 = OPPOP();
|
|
|
|
if(value2 == 0){
|
|
|
|
JVM_THROWS_NEW(java.lang.ArithmeticException);
|
|
|
|
}
|
|
|
|
|
|
|
|
var result = value1 - Math.round(value1 / value2) * value2
|
|
|
|
if (IS_OVERFLOW(result,INT_MAX_VALUE) || IS_UNDERFLOW(result,INT_MIN_VALUE)){
|
|
|
|
OPPUSH(INT_OVERFLOW(result));
|
|
|
|
}else{
|
|
|
|
OPPUSH(result);
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(IRETURN)
|
|
|
|
var objectref = OPPOP();
|
|
|
|
return {return_object: objectref}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(ISHL)
|
|
|
|
var value2 = OPPOP();
|
|
|
|
var value1 = OPPOP();
|
|
|
|
var result = value1 << (value2 & 0x1f);
|
|
|
|
|
|
|
|
if (IS_OVERFLOW(result,INT_MAX_VALUE) || IS_UNDERFLOW(result,INT_MIN_VALUE)){
|
|
|
|
OPPUSH(INT_OVERFLOW(result));
|
|
|
|
}else{
|
|
|
|
OPPUSH(result);
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(ISHR)
|
|
|
|
var value2 = OPPOP();
|
|
|
|
var value1 = OPPOP();
|
|
|
|
var result = value1 >> (value2 & 0x1f);
|
|
|
|
|
|
|
|
if (IS_OVERFLOW(result,INT_MAX_VALUE) || IS_UNDERFLOW(result,INT_MIN_VALUE)){
|
|
|
|
OPPUSH(INT_OVERFLOW(result));
|
|
|
|
}else{
|
|
|
|
OPPUSH(result);
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(ISTORE)
|
|
|
|
var index = READ_NEXT();
|
|
|
|
LOCAL_VAR(index) = OPPOP();
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFALIAS(ISTORE_0)
|
|
|
|
DEFALIAS(ISTORE_1)
|
|
|
|
DEFALIAS(ISTORE_2)
|
|
|
|
DEFALIAS(ISTORE_3)
|
|
|
|
DEFNOP()
|
2011-08-03 00:32:54 +01:00
|
|
|
LOCAL_VAR(OPCODE - ISTORE_0) = OPPOP();
|
2011-07-21 19:03:57 +01:00
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(ISUB)
|
|
|
|
var value2 = OPPOP();
|
2011-08-09 00:39:43 +01:00
|
|
|
var value1 = OPPOP();
|
2011-07-21 19:03:57 +01:00
|
|
|
var result = value1 - value2;
|
2011-08-09 00:39:43 +01:00
|
|
|
if (IS_UNDERFLOW(result,INT_MIN_VALUE)){
|
2011-07-21 19:03:57 +01:00
|
|
|
OPPUSH(INT_OVERFLOW(result));
|
|
|
|
}else{
|
|
|
|
OPPUSH(result);
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(IUSHR)
|
|
|
|
var value2 = OPPOP();
|
|
|
|
var value1 = OPPOP();
|
|
|
|
OPPUSH((value1<0)?(value1 >> (value2 & 0x1f)) + (2 << ~s):value1 >> (value2 & 0x1f))
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(IXOR)
|
|
|
|
var value2 = OPPOP();
|
|
|
|
var value1 = OPPOP();
|
|
|
|
OPPUSH(INT_OVERFLOW(value1 ^ value2));
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(JSR)
|
|
|
|
var branchbyte1 = READ_NEXT();
|
|
|
|
var branchbyte2 = READ_NEXT();
|
|
|
|
OPPUSH(PC + 1);
|
|
|
|
PC = (branchbyte1 << 8) | branchbyte2
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(JSR_W)
|
|
|
|
var branchbyte1 = READ_NEXT();
|
|
|
|
var branchbyte2 = READ_NEXT();
|
|
|
|
var branchbyte3 = READ_NEXT();
|
|
|
|
var branchbyte4 = READ_NEXT();
|
|
|
|
|
|
|
|
OPPUSH(PC + 1);
|
|
|
|
PC = (branchbyte1 << 24) | (branchbyte2 << 16) | (branchbyte3 << 8) | branchbyte4
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(L2D)
|
|
|
|
OPPUSH(null);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(L2F)
|
|
|
|
OPPUSH(null);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(L2I)
|
|
|
|
var value = OPPOP()
|
|
|
|
|
|
|
|
if (IS_OVERFLOW(value,LONG_MAX_VALUE) || IS_UNDERFLOW(result,LONG_MIN_VALUE)){
|
|
|
|
OPPUSH(LONG_OVERFLOW(value));
|
|
|
|
}else{
|
|
|
|
OPPUSH(value);
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(LADD)
|
|
|
|
var value1 = OPPOP();
|
|
|
|
var value2 = OPPOP();
|
|
|
|
var result = value1 + value2;
|
|
|
|
if (IS_OVERFLOW(result,LONG_MAX_VALUE)){
|
|
|
|
OPPUSH(LONG_OVERFLOW(result));
|
|
|
|
}else{
|
|
|
|
OPPUSH(result);
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(LALOAD)
|
|
|
|
var index = OPPOP();
|
|
|
|
var arrayref = OPPOP();
|
|
|
|
|
|
|
|
CHECK_NULL(arrayref);
|
|
|
|
CHECK_ARRAY_INDEX(index,arrayref);
|
|
|
|
|
|
|
|
OPPUSH(arrayref.value[index]);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(LAND)
|
|
|
|
var value1 = OPPOP()
|
|
|
|
var value2 = OPPOP()
|
|
|
|
var result = value1 & value2
|
|
|
|
OPPUSH(result);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(LASTORE)
|
|
|
|
var index = OPPOP();
|
|
|
|
var arrayref = OPPOP();
|
|
|
|
var value = OPPOP();
|
|
|
|
|
|
|
|
CHECK_NULL(arrayref);
|
|
|
|
CHECK_ARRAY_INDEX(index,arrayref);
|
|
|
|
|
|
|
|
arrayref.value[index] = value;
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(LCMP)
|
|
|
|
var value2 = OPPOP();
|
|
|
|
var value1 = OPPOP();
|
|
|
|
|
|
|
|
if (value1 > value2){
|
|
|
|
OPPUSH(1);
|
|
|
|
}else if (value1 == value2){
|
|
|
|
OPPUSH(0);
|
|
|
|
}else{
|
|
|
|
OPPUSH(-1)
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
|
|
|
|
DEFALIAS(LCONST_0)
|
|
|
|
DEFALIAS(LCONST_1)
|
|
|
|
DEFNOP()
|
|
|
|
OPPUSH(OPCODE - LCONST_0)
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(LDC)
|
|
|
|
var index = READ_NEXT();
|
2011-08-06 01:03:21 +01:00
|
|
|
var cstt = xl.constantPool.get(index);
|
2011-07-21 19:03:57 +01:00
|
|
|
switch(cstt.id){
|
|
|
|
case CONSTANT_Integer:
|
|
|
|
case CONSTANT_Float:
|
|
|
|
OPPUSH(cstt.value);
|
2011-07-22 13:50:11 +01:00
|
|
|
break;
|
2011-07-21 19:03:57 +01:00
|
|
|
case CONSTANT_String:
|
2011-08-06 01:03:21 +01:00
|
|
|
OPPUSH(xl.jvm.makeInstanceOfStringFromJSSTring(cstt.string_ref.str));
|
2011-07-22 13:50:11 +01:00
|
|
|
break;
|
2011-07-21 19:03:57 +01:00
|
|
|
default:
|
|
|
|
PANIC("What now?");
|
2011-07-22 13:50:11 +01:00
|
|
|
break;
|
2011-07-21 19:03:57 +01:00
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(LDC_W)
|
|
|
|
var index1 = READ_NEXT();
|
|
|
|
var index2 = READ_NEXT();
|
|
|
|
var index = (indexbyte1 << 8) | indexbyte2
|
2011-08-06 01:03:21 +01:00
|
|
|
var cstt = xl.constantPool.get(index);
|
2011-07-21 19:03:57 +01:00
|
|
|
switch(cstt.id){
|
|
|
|
case CONSTANT_Integer:
|
|
|
|
OPPUSHD(cstt.value);
|
2011-07-22 13:50:11 +01:00
|
|
|
break;
|
2011-07-21 19:03:57 +01:00
|
|
|
case CONSTANT_Float:
|
|
|
|
OPPUSH(cstt.value);
|
2011-07-22 13:50:11 +01:00
|
|
|
break;
|
2011-07-21 19:03:57 +01:00
|
|
|
case CONSTANT_String:
|
|
|
|
PANIC("NEW STRING FROM CONSTANT POOL NOT IMPLEMENTED");
|
2011-07-22 13:50:11 +01:00
|
|
|
break;
|
2011-07-21 19:03:57 +01:00
|
|
|
default:
|
|
|
|
PANIC("What now?");
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(LDC2_W)
|
2011-08-04 16:40:14 +01:00
|
|
|
var indexbyte1 = READ_NEXT();
|
|
|
|
var indexbyte2 = READ_NEXT();
|
2011-07-21 19:03:57 +01:00
|
|
|
var index = (indexbyte1 << 8) | indexbyte2
|
2011-08-04 16:40:14 +01:00
|
|
|
var cstt = xl.constantPool.get(index);
|
2011-07-21 19:03:57 +01:00
|
|
|
OPPUSHD(cstt.value);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(LDIV)
|
|
|
|
var value1 = OPPOP();
|
|
|
|
var value2 = OPPOP();
|
|
|
|
if(value2 == 0){
|
|
|
|
JVM_THROWS_NEW(java.lang.ArithmeticException);
|
|
|
|
}
|
|
|
|
|
|
|
|
var result = Math.round(value1 / value2);
|
|
|
|
OPPUSH(result);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(LLOAD)
|
|
|
|
var index = READ_NEXT();
|
|
|
|
OPPUSH(LOCAL_VAR(index));
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFALIAS(LLOAD_0)
|
|
|
|
DEFALIAS(LLOAD_1)
|
|
|
|
DEFALIAS(LLOAD_2)
|
|
|
|
DEFALIAS(LLOAD_3)
|
|
|
|
DEFNOP()
|
|
|
|
OPPUSH(OPCODE - LLOAD_0);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(LMUL)
|
|
|
|
var value1 = OPPOP();
|
|
|
|
var value2 = OPPOP();
|
|
|
|
var result = value1 * value2;
|
|
|
|
if (IS_OVERFLOW(result,INT_MAX_VALUE)){
|
|
|
|
OPPUSH(INT_OVERFLOW(result));
|
|
|
|
}else{
|
|
|
|
OPPUSH(result);
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(LNEG)
|
|
|
|
var value = OPPOP();
|
|
|
|
var result = 0 - value;
|
|
|
|
if (IS_OVERFLOW(result,INT_MAX_VALUE) || IS_UNDERFLOW(result,INT_MINVALUE)){
|
|
|
|
OPPUSH(INT_OVERFLOW(result));
|
|
|
|
}else{
|
|
|
|
OPPUSH(result);
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
2011-08-02 14:08:37 +01:00
|
|
|
DEFOP(LOOKUPSWITCH)
|
|
|
|
var shift = PC % 4;
|
|
|
|
var instrPC = PC - 1
|
|
|
|
if (shift != 0){
|
|
|
|
switch(shift){
|
|
|
|
case 1:
|
|
|
|
READ_NEXT();
|
|
|
|
case 2:
|
|
|
|
READ_NEXT();
|
|
|
|
case 3:
|
|
|
|
READ_NEXT();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var stack_key = OPPOP();
|
|
|
|
|
|
|
|
var defaultbyte1 = READ_NEXT();
|
|
|
|
var defaultbyte2 = READ_NEXT();
|
|
|
|
var defaultbyte3 = READ_NEXT();
|
|
|
|
var defaultbyte4 = READ_NEXT();
|
|
|
|
var jmp = QWORD(defaultbyte1,defaultbyte2,defaultbyte3,defaultbyte4);
|
|
|
|
|
|
|
|
var npair1 = READ_NEXT();
|
|
|
|
var npair2 = READ_NEXT();
|
|
|
|
var npair3 = READ_NEXT();
|
|
|
|
var npair4 = READ_NEXT();
|
|
|
|
var npair = QWORD(npair1,npair2,npair3,npair4);
|
|
|
|
|
|
|
|
for(var i=0; i<npair; i++){
|
|
|
|
var key1 = READ_NEXT();
|
|
|
|
var key2 = READ_NEXT();
|
|
|
|
var key3 = READ_NEXT();
|
|
|
|
var key4 = READ_NEXT();
|
|
|
|
var key = QWORD(key1,key2,key3,key4);
|
|
|
|
|
|
|
|
var value1 = READ_NEXT();
|
|
|
|
var value2 = READ_NEXT();
|
|
|
|
var value3 = READ_NEXT();
|
|
|
|
var value4 = READ_NEXT();
|
|
|
|
var value = QWORD(value1,value2,value3,value4);
|
|
|
|
|
|
|
|
if(key == stack_key){
|
|
|
|
jmp = instrPC + value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
PC = instrPC + jmp;
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(LOR)
|
|
|
|
var value1 = OPPOP();
|
|
|
|
var value2 = OPPOP();
|
|
|
|
|
|
|
|
OPPUSH(LONG_OVERFLOW(value1 | value2));
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(LREM)
|
|
|
|
var value1 = OPPOP();
|
|
|
|
var value2 = OPPOP();
|
|
|
|
if(value2 == 0){
|
|
|
|
JVM_THROWS_NEW(java.lang.ArithmeticException);
|
|
|
|
}
|
|
|
|
|
|
|
|
var result = value1 - Math.round(value1 / value2) * value2
|
|
|
|
if (IS_OVERFLOW(result,LONG_MAX_VALUE) || IS_UNDERFLOW(result,LONG_MIN_VALUE)){
|
|
|
|
OPPUSH(LONG_OVERFLOW(result));
|
|
|
|
}else{
|
|
|
|
OPPUSH(result);
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(LRETURN)
|
|
|
|
var objectref = OPPOP();
|
|
|
|
return {return_object: objectref}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(LSHL)
|
|
|
|
var value2 = OPPOP();
|
|
|
|
var value1 = OPPOP();
|
|
|
|
var result = value1 << (value2 & 0x1f);
|
|
|
|
|
|
|
|
if (IS_OVERFLOW(result,LONG_MAX_VALUE) || IS_UNDERFLOW(result,LONG_MIN_VALUE)){
|
|
|
|
OPPUSH(LONG_OVERFLOW(result));
|
|
|
|
}else{
|
|
|
|
OPPUSH(result);
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(LSHR)
|
|
|
|
var value2 = OPPOP();
|
|
|
|
var value1 = OPPOP();
|
|
|
|
var result = value1 >> (value2 & 0x1f);
|
|
|
|
|
|
|
|
if (IS_OVERFLOW(result,LONG_MAX_VALUE) || IS_UNDERFLOW(result,LONG_MIN_VALUE)){
|
|
|
|
OPPUSH(LONG_OVERFLOW(result));
|
|
|
|
}else{
|
|
|
|
OPPUSH(result);
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(LSTORE)
|
|
|
|
var index = READ_NEXT();
|
|
|
|
LOCAL_VAR(index) = OPPOP();
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFALIAS(LSTORE_0)
|
|
|
|
DEFALIAS(LSTORE_1)
|
|
|
|
DEFALIAS(LSTORE_2)
|
|
|
|
DEFALIAS(LSTORE_3)
|
|
|
|
DEFNOP()
|
|
|
|
LOCAL_VAR(READ_NEXT()) = (OPCODE - LSTORE_0);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(LSUB)
|
|
|
|
var value1 = OPPOP();
|
|
|
|
var value2 = OPPOP();
|
|
|
|
var result = value1 - value2;
|
|
|
|
if (IS_UNDERFLOW(result,LONG_MAX_VALUE)){
|
|
|
|
OPPUSH(LONG_OVERFLOW(result));
|
|
|
|
}else{
|
|
|
|
OPPUSH(result);
|
|
|
|
}
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(LUSHR)
|
|
|
|
var value2 = OPPOP();
|
|
|
|
var value1 = OPPOP();
|
|
|
|
OPPUSH((value1<0)?(value1 >> (value2 & 0x1f)) + (2 << ~s):value1 >> (value2 & 0x1f))
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(LXOR)
|
|
|
|
var value2 = OPPOP();
|
|
|
|
var value1 = OPPOP();
|
|
|
|
OPPUSH(LONG_OVERFLOW(value1 ^ value2));
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(MONITORENTER)
|
|
|
|
PANIC("THREADING NOT IMPLEMENTED YET");
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(MONITOREXIT)
|
|
|
|
PANIC("THREADING NOT IMPLEMENTED YET");
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(MULTIANEWARRAY)
|
|
|
|
var indexbyte1 = READ_NEXT();
|
|
|
|
var indexbyte2 = READ_NEXT();
|
|
|
|
var dimensions = READ_NEXT();
|
|
|
|
var counts = [];
|
|
|
|
for(var i=0; i<dimensions; i++){
|
|
|
|
counts.add(OPPOP());
|
|
|
|
}
|
2011-08-06 01:03:21 +01:00
|
|
|
var clRef = xl.constantPool.get((indexbyte1 << 8) | indexbyte2);
|
2011-08-02 14:08:37 +01:00
|
|
|
var instance = {length:counts, dimensions:dimensions, value:[], 'class':xl.jvm.classForName(clRef)};
|
|
|
|
OPPUSH(instance);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(NEW)
|
|
|
|
var indexbyte1 = READ_NEXT();
|
|
|
|
var indexbyte2 = READ_NEXT();
|
|
|
|
|
2011-08-06 01:03:21 +01:00
|
|
|
var clRef = xl.constantPool.get((indexbyte1 << 8) | indexbyte2);
|
|
|
|
var newInstance = xl.jvm.classForName(clRef.jvmClassName).makeInstance();
|
2011-08-02 14:08:37 +01:00
|
|
|
OPPUSH(newInstance);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(NOP)
|
|
|
|
ENDDEF
|
|
|
|
|
2011-08-06 01:03:21 +01:00
|
|
|
DEFOP(NEWARRAY)
|
|
|
|
var atype = READ_NEXT();
|
|
|
|
var count = OPPOP();
|
|
|
|
if (count < 0){
|
|
|
|
JVM_THROWS_NEW(java.lang.NegativeArraySizeException);
|
|
|
|
}
|
|
|
|
var clRef = xl.constantPool.get((indexbyte1 << 8) | indexbyte2);
|
|
|
|
var instance = make1DNativeArray(count,true,atype);
|
|
|
|
OPPUSH(instance);
|
|
|
|
ENDDEF
|
|
|
|
|
2011-08-02 14:08:37 +01:00
|
|
|
DEFOP(POP)
|
|
|
|
OPPOP();
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(POP2)
|
|
|
|
OPPOP();
|
|
|
|
OPPOP();
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(PUTFIELD)
|
|
|
|
var indexbyte1 = READ_NEXT();
|
|
|
|
var indexbyte2 = READ_NEXT();
|
|
|
|
var value = OPPOP();
|
|
|
|
var objectref = OPPOP();
|
|
|
|
|
|
|
|
CHECK_NULL(objectref)
|
2011-08-09 00:39:43 +01:00
|
|
|
var field = xl.constantPool.get((indexbyte1 << 8) | indexbyte2);
|
2011-08-02 14:08:37 +01:00
|
|
|
//check if static
|
2011-08-09 00:39:43 +01:00
|
|
|
objectref[field.class_ref.name_ref.str + " " + field.name_and_type_ref.name_ref.str] = value;
|
2011-08-02 14:08:37 +01:00
|
|
|
ENDDEF
|
|
|
|
|
2011-08-22 18:57:00 +01:00
|
|
|
DEFOP(PUTSTATIC)
|
2011-08-02 14:08:37 +01:00
|
|
|
var indexbyte1 = READ_NEXT();
|
|
|
|
var indexbyte2 = READ_NEXT();
|
|
|
|
var value = OPPOP();
|
|
|
|
|
2011-08-06 01:03:21 +01:00
|
|
|
var field = xl.constantPool.get((indexbyte1 << 8) | indexbyte2);
|
2011-11-15 11:26:58 +00:00
|
|
|
var aClass = field.class_ref.jvmClassName;
|
2011-08-02 14:08:37 +01:00
|
|
|
|
|
|
|
//check if static
|
2011-11-15 11:26:58 +00:00
|
|
|
xl.jvm.classForName(aClass)[canonicalName(field.class_ref.name_ref) + " " + field.name_and_type_ref.name_ref.str] = value;
|
2011-08-02 14:08:37 +01:00
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(RET)
|
|
|
|
var index = READ_NEXT();
|
|
|
|
PC = LOCAL_VAR(index);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(RETURN)
|
|
|
|
return;
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(SALOAD)
|
|
|
|
var index = OPPOP();
|
|
|
|
var arrayref = OPPOP();
|
|
|
|
|
|
|
|
CHECK_NULL(arrayref);
|
|
|
|
CHECK_ARRAY_INDEX(index,arrayref);
|
|
|
|
|
|
|
|
OPPUSH(arrayref.value[index]);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(SASTORE)
|
|
|
|
var index = OPPOP();
|
|
|
|
var arrayref = OPPOP();
|
|
|
|
var value = OPPOP();
|
|
|
|
|
|
|
|
CHECK_NULL(arrayref);
|
|
|
|
CHECK_ARRAY_INDEX(index,arrayref);
|
|
|
|
|
|
|
|
arrayref.value[index] = value;
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(SIPUSH)
|
2011-11-15 11:26:58 +00:00
|
|
|
var byte1 = READ_NEXT();
|
|
|
|
var byte2 = READ_NEXT();
|
2011-08-02 14:08:37 +01:00
|
|
|
OPPUSH((byte1 << 8) | byte2);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(SWAP)
|
|
|
|
var value1 = OPPOP();
|
|
|
|
var value2 = OPPOP();
|
|
|
|
OPPUSH(value2); OPPUSH(value1);
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(TABLESWITCH)
|
|
|
|
var shift = PC % 4;
|
|
|
|
var instrPC = PC - 1
|
|
|
|
if (shift != 0){
|
|
|
|
switch(shift){
|
|
|
|
case 1:
|
|
|
|
READ_NEXT();
|
|
|
|
case 2:
|
|
|
|
READ_NEXT();
|
|
|
|
case 3:
|
|
|
|
READ_NEXT();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var stack_key = OPPOP();
|
|
|
|
|
|
|
|
var defaultbyte1 = READ_NEXT();
|
|
|
|
var defaultbyte2 = READ_NEXT();
|
|
|
|
var defaultbyte3 = READ_NEXT();
|
|
|
|
var defaultbyte4 = READ_NEXT();
|
|
|
|
var defaultbyte = QWORD(defaultbyte1,defaultbyte2,defaultbyte3,defaultbyte4);
|
|
|
|
|
|
|
|
var low1 = READ_NEXT();
|
|
|
|
var low2 = READ_NEXT();
|
|
|
|
var low3 = READ_NEXT();
|
|
|
|
var low4 = READ_NEXT();
|
|
|
|
var low= QWORD(low1,low2,low3,low4);
|
|
|
|
|
|
|
|
var high1 = READ_NEXT();
|
|
|
|
var high2 = READ_NEXT();
|
|
|
|
var high3 = READ_NEXT();
|
|
|
|
var high4 = READ_NEXT();
|
|
|
|
var high= QWORD(high1,high2,high3,high4);
|
|
|
|
|
|
|
|
|
|
|
|
var index = OPPOP();
|
|
|
|
var jmp = defaultbyte;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (index < low || index > high){
|
|
|
|
var length = high - low + 2;
|
|
|
|
for(var i=0; i<length; i++){
|
|
|
|
var jump1 = READ_NEXT();
|
|
|
|
var jump2 = READ_NEXT();
|
|
|
|
var jump3 = READ_NEXT();
|
|
|
|
var jump4 = READ_NEXT();
|
|
|
|
var jump = QWORD(jump1,jump2,jump3,jump4);
|
|
|
|
|
|
|
|
if (index-low == i){
|
|
|
|
jmp = jump;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
PC = instrPC + jmp;
|
|
|
|
ENDDEF
|
|
|
|
|
|
|
|
DEFOP(WIDE)
|
|
|
|
var op = READ_NEXT();
|
|
|
|
var indexbyte1 = READ_NEXT();
|
|
|
|
var indexbyte2 = READ_NEXT();
|
|
|
|
switch(op){
|
|
|
|
case ILOAD:
|
|
|
|
case ALOAD:
|
|
|
|
case LLOAD:
|
|
|
|
OPPUSH(LOCAL_VAR((indexbyte1 << 8) | indexbyte2));
|
|
|
|
break;
|
|
|
|
case FLOAD:
|
|
|
|
case DLOAD:
|
|
|
|
OPPUSHD(LOCAL_VAR((indexbyte1 << 8) | indexbyte2));
|
|
|
|
break;
|
|
|
|
case ISTORE:
|
|
|
|
case ASTORE:
|
|
|
|
case LSTORE:
|
|
|
|
LOCAL_VAR((indexbyte1 << 8) | indexbyte2) = OPPOP();
|
|
|
|
break;
|
|
|
|
case FSTORE:
|
|
|
|
case DSTORE:
|
|
|
|
LOCAL_VAR((indexbyte1 << 8) | indexbyte2) = OPPOPD();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
ENDDEF
|