BicaVM/src/intrp.def

1583 lines
34 KiB
Modula-2
Raw Normal View History

/* -*- 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();
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);
var instance = make1DNativeArray(count,false,xl.jvm.classForName(clRef));
OPPUSH(instance);
ENDDEF
DEFOP(ARETURN)
var objectref = OPPOP();
return {return_object: objectref}
ENDDEF
DEFOP(ARRAYLENGTH)
var arrayref = OPPOP();
if (!(arrayref.primitive == true || arrayref.primitive == false)){
PANIC("NOT AN ARRAY");
}
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());
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();
CHECK_NULL(arrayref);
CHECK_ARRAY_INDEX(index,arrayref);
OPPUSHD(arrayref.value[index]);
ENDDEF
DEFOP(DASTORE)
var value = OPPOPD();
var index = OPPOP();
var arrayref = OPPOP();
CHECK_NULL(arrayref);
CHECK_ARRAY_INDEX(index,arrayref);
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()
var index = OPCODE - DSTORE_0;
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();
CHECK_NULL(arrayref);
CHECK_ARRAY_INDEX(index,arrayref);
OPPUSHD(arrayref.value[index]);
ENDDEF
DEFOP(FASTORE)
var value = OPPOPD();
var index = OPPOP();
var arrayref = OPPOP();
CHECK_NULL(arrayref);
CHECK_ARRAY_INDEX(index,arrayref);
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)
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)
var field = xl.constantPool.get((indexbyte1 << 8) | indexbyte2);
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);
ENDDEF
DEFOP(GETSTATIC)
var indexbyte1 = READ_NEXT();
var indexbyte2 = READ_NEXT();
2011-08-06 01:03:21 +01:00
var field = xl.constantPool.get((indexbyte1 << 8) | indexbyte2);
var aClass = field.class_ref.name_ref.str;
//check if static
2011-08-22 18:57:00 +01:00
OPPUSH(xl.jvm.classForName(aClass)[canonicalName(field.class_ref.name_ref) + " " + field.name_and_type_ref.name_ref.str]);
ENDDEF
DEFOP(GOTO)
var branchbyte1 = READ_NEXT();
var branchbyte2 = READ_NEXT();
var branchoffset = (branchbyte1 << 8) | branchbyte2;
PC = PC + branchoffset - 3;
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;
PC = PC + branchoffset - 5;
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)){
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();
var index = OPPOP();
var arrayref = OPPOP();
2011-08-06 01:03:21 +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);
}
var result = Math.round(value1 / value2);
2011-07-21 19:03:57 +01:00
OPPUSH(result);
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;
PC = PC + branchoffset - 3;
}
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;
PC = PC + branchoffset - 3;
}
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;
PC = PC + branchoffset - 3;
}
ENDDEF
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;
PC = PC + branchoffset - 3;
}
ENDDEF
DEFOP(IF_ICMPLT)
var branchbyte1 = READ_NEXT();
var branchbyte2 = READ_NEXT();
var value2 = OPPOP();
var value1 = OPPOP();
if (value1 < value2){
var branchoffset = (branchbyte1 << 8) | branchbyte2;
PC = PC + branchoffset - 3;
}
ENDDEF
DEFOP(IF_ICMPLE)
var branchbyte1 = READ_NEXT();
var branchbyte2 = READ_NEXT();
var value2 = OPPOP();
var value1 = OPPOP();
if (value1 <= value2){
var branchoffset = (branchbyte1 << 8) | branchbyte2;
PC = PC + branchoffset - 3;
}
ENDDEF
DEFOP(IF_ICMPGT)
var branchbyte1 = READ_NEXT();
var branchbyte2 = READ_NEXT();
var value2 = OPPOP();
var value1 = OPPOP();
2011-07-21 16:10:43 +01:00
if (value1 > value2){
var branchoffset = (branchbyte1 << 8) | branchbyte2;
PC = PC + branchoffset - 3;
}
ENDDEF
2011-07-21 16:10:43 +01:00
DEFOP(IF_ICMPGE)
var branchbyte1 = READ_NEXT();
var branchbyte2 = READ_NEXT();
var value2 = OPPOP();
var value1 = OPPOP();
2011-07-21 16:10:43 +01:00
if (value1 >= value2){
var branchoffset = (branchbyte1 << 8) | branchbyte2;
PC = PC + branchoffset - 3;
}
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;
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;
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;
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;
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;
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;
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;
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;
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()
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 = [];
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){
LOG("Calling " + xl.className+ " " + method.name_ref.str + method.descriptor_ref.str)
LOG("!! NATIVE !!")
if (methodId in xl.jvm.internalJNITable[canonicalName(cl.this_class.name_ref)]){
result = xl.jvm.internalJNITable[canonicalName(cl.this_class.name_ref)][methodId].apply(cl,args);
}else if (methodId in xl.jvm.JNITable[canonicalName(cl.this_class.name_ref)][methodId]){
result = xl.jvm.JNITable[canonicalName(cl.this_class.name_ref)][methodId].apply(cl,args)
}else{
PANIC(methodId + " declared as native but not mapped");
}
LOG("Returing from " + xl.className+ " " + method.name_ref.str + method.descriptor_ref.str)
}else{
result = method.invoke(args,cl);
}
if (result != 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];
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();
var value1 = OPPOP();
2011-07-21 19:03:57 +01:00
var result = value1 - value2;
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)
var indexbyte1 = READ_NEXT();
var indexbyte2 = READ_NEXT();
2011-07-21 19:03:57 +01:00
var index = (indexbyte1 << 8) | indexbyte2
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)
var field = xl.constantPool.get((indexbyte1 << 8) | indexbyte2);
2011-08-02 14:08:37 +01:00
//check if static
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();
CHECK_NULL(objectref)
2011-08-06 01:03:21 +01:00
var field = xl.constantPool.get((indexbyte1 << 8) | indexbyte2);
2011-08-02 14:08:37 +01:00
var aClass = field.class_ref.name_ref.str;
//check if static
2011-08-06 01:03:21 +01:00
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)
var byte1 = OPPOP();
var byte2 = OPPOP();
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