/* -*- 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) 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); } var clRef = xl.constantPool.get((indexbyte1 << 8) | indexbyte2); var instance = make1DNativeArray(count,false,xl.jvm.classForName(clRef.jvmClassName)); 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) 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 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(); var field = xl.constantPool.get((indexbyte1 << 8) | indexbyte2); var aClass = canonicalName(field.class_ref.name_ref); //check if static OPPUSH(xl.jvm.classForName(aClass)[field.class_ref.name_ref.str + " " + 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; 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) var value = OPPOP(); var index = OPPOP(); var arrayref = OPPOP(); 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); 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(); if (value1 > value2){ var branchoffset = (branchbyte1 << 8) | branchbyte2; PC = PC + branchoffset - 3; } ENDDEF DEFOP(IF_ICMPGE) 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(IFEQ) var branchbyte1 = READ_NEXT(); var branchbyte2 = READ_NEXT(); var value = OPPOP(); if (value == 0){ var branchoffset = (branchbyte1 << 8) | branchbyte2; PC = PC + branchoffset - 3; } 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; } 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; } 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; } 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; } 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; } 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; } 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; } 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)); 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(); if (objectref == null){ OPPUSH(0); break; } var className = canonicalName(xl.constantPool.get((indexbyte1 << 8) | indexbyte2).name_ref); if(objectref["class"].isAssignable(jvm.classForName(className))){ OPPUSH(1); }else{ OPPUSH(0); } ENDDEF //############################### //## INVOKES ! //############################### DEFOP(INVOKEINTERFACE) var indexbyte1 = READ_NEXT(); var indexbyte2 = READ_NEXT(); var count = READ_NEXT(); /* expected 0*/ READ_NEXT(); var args = []; var method = xl.constantPool.get((indexbyte1 << 8) | indexbyte2); for(var i=0; i> (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() LOCAL_VAR(OPCODE - ISTORE_0) = OPPOP(); ENDDEF DEFOP(ISUB) var value2 = OPPOP(); var value1 = OPPOP(); var result = value1 - value2; if (IS_UNDERFLOW(result,INT_MIN_VALUE)){ 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(); var cstt = xl.constantPool.get(index); switch(cstt.id){ case CONSTANT_Integer: case CONSTANT_Float: OPPUSH(cstt.value); break; case CONSTANT_String: OPPUSH(xl.jvm.makeInstanceOfStringFromJSSTring(cstt.string_ref.str)); break; default: PANIC("What now?"); break; } ENDDEF DEFOP(LDC_W) var index1 = READ_NEXT(); var index2 = READ_NEXT(); var index = (indexbyte1 << 8) | indexbyte2 var cstt = xl.constantPool.get(index); switch(cstt.id){ case CONSTANT_Integer: OPPUSHD(cstt.value); break; case CONSTANT_Float: OPPUSH(cstt.value); break; case CONSTANT_String: PANIC("NEW STRING FROM CONSTANT POOL NOT IMPLEMENTED"); break; default: PANIC("What now?"); } ENDDEF DEFOP(LDC2_W) var indexbyte1 = READ_NEXT(); var indexbyte2 = READ_NEXT(); var index = (indexbyte1 << 8) | indexbyte2 var cstt = xl.constantPool.get(index); 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 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> (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 high){ var length = high - low + 2; for(var i=0; i