//gery-angy else
//gery-angy throw new IllegalProceedUsageException("incompatible argument or return type for 'proceed()'");
} catch(ClassNotFoundException e) {throw new JVMAIRuntimeException(e.getMessage());}
if(!(inType instanceof ObjectType) && !(outType instanceof ObjectType))
throw new IllegalProceedUsageException("cannot convert from " + inType + " to " + outType + " for 'proceed()' statement (wrong type for an argument or return value)");
if(inType instanceof ObjectType) {
// outboxing (object -> primitive type)
//
// NOTE: insert inserts always at the begining of the instruction list
// so the instructions are inserted in reverse order
// (the last inserted instruction will be the first in the list).
//
// Casting may cause runtime exceptions, it may be safer to not
// insert the 'CHECKCAST' instruction.
//
try {
ObjectType rType = (ObjectType)inType;
boolean noCast;
if(Type.BOOLEAN.equals(outType)) {
if(
(noCast = rType.isAssignmentCompatibleWith(booleanType))
|| booleanType.isAssignmentCompatibleWith(rType)
) {
instructions.insert(new INVOKEVIRTUAL(cpGen.addMethodref("java.lang.Boolean", "booleanValue", "()Z")));
if(!noCast)
instructions.insert(new CHECKCAST(cpGen.addClass("java.lang.Boolean")));
return;
}
}
else if(Type.BYTE.equals(outType)) {
if(
(noCast = rType.isAssignmentCompatibleWith(byteType))
|| byteType.isAssignmentCompatibleWith(rType)
) {
instructions.insert(new INVOKEVIRTUAL(cpGen.addMethodref("java.lang.Byte", "byteValue", "()B")));
if(!noCast)
instructions.insert(new CHECKCAST(cpGen.addClass("java.lang.Byte")));
return;
}
}
else if(Type.CHAR.equals(outType)) {
if(
(noCast = rType.isAssignmentCompatibleWith(characterType))
|| characterType.isAssignmentCompatibleWith(rType)
) {
instructions.insert(new INVOKEVIRTUAL(cpGen.addMethodref("java.lang.Character", "charValue", "()C")));
if(!noCast)
instructions.insert(new CHECKCAST(cpGen.addClass("java.lang.Character")));
return;
}
}
else if(Type.DOUBLE.equals(outType)) {
if(
(noCast = rType.isAssignmentCompatibleWith(doubleType))
|| doubleType.isAssignmentCompatibleWith(rType)
) {
instructions.insert(new INVOKEVIRTUAL(cpGen.addMethodref("java.lang.Double", "doubleValue", "()D")));
if(!noCast)
instructions.insert(new CHECKCAST(cpGen.addClass("java.lang.Double")));
return;
}
}
else if(Type.FLOAT.equals(outType)) {
if(
(noCast = rType.isAssignmentCompatibleWith(floatType))
|| floatType.isAssignmentCompatibleWith(rType)
) {
instructions.insert(new INVOKEVIRTUAL(cpGen.addMethodref("java.lang.Float", "floatValue", "()F")));
if(!noCast)
instructions.insert(new CHECKCAST(cpGen.addClass("java.lang.Float")));
return;
}
}
else if(Type.INT.equals(outType)) {
if(
(noCast = rType.isAssignmentCompatibleWith(integerType))
|| integerType.isAssignmentCompatibleWith(rType)
) {
instructions.insert(new INVOKEVIRTUAL(cpGen.addMethodref("java.lang.Integer", "intValue", "()I")));
if(!noCast)
instructions.insert(new CHECKCAST(cpGen.addClass("java.lang.Integer")));
return;
}
}
else if(Type.LONG.equals(outType)) {
if(
(noCast = rType.isAssignmentCompatibleWith(longType))
|| longType.isAssignmentCompatibleWith(rType)
) {
instructions.insert(new INVOKEVIRTUAL(cpGen.addMethodref("java.lang.Long", "longValue", "()J")));
if(!noCast)
instructions.insert(new CHECKCAST(cpGen.addClass("java.lang.Long")));
return;
}
}
else if(Type.SHORT.equals(outType)) {
if(
(noCast = rType.isAssignmentCompatibleWith(shortType))
|| shortType.isAssignmentCompatibleWith(rType)
) {
instructions.insert(new INVOKEVIRTUAL(cpGen.addMethodref("java.lang.Short", "shortValue", "()S")));
if(!noCast)
instructions.insert(new CHECKCAST(cpGen.addClass("java.lang.Short")));
return;
}
}
else { //gery-angy
instructions.insert(new CHECKCAST(cpGen.addClass(outType.toString()))); //gery-angy
return; //gery-angy
} //gery-angy
// throw new IllegalProceedUsageException("cannot outbox from " + inType + " to " + outType); //BEFORE
} catch(ClassNotFoundException e) { throw new JVMAIRuntimeException(e.getMessage()); }
}
else {
// inboxing (primitive type -> object)
//
// Stack instructions have to move the arguments for the constructor
// into the right position on the stack.
// for types that need one word:
// word2, word1 -> word1, word1, word2
// for types that need two words:
// word3, word2, word1 -> word1, word1, word3, word2
//
try {
if(Type.BOOLEAN.equals(inType)) {
if(booleanType.isAssignmentCompatibleWith(outType)) {
//instructions.insert(new INVOKESTATIC(cpGen.addMethodref("java.lang.Boolean", "valueOf", "(Z)Ljava/lang/Boolean;"))); // Only for JDK > 5
instructions.insert(new INVOKESPECIAL(cpGen.addMethodref("java.lang.Boolean", "<init>", "(Z)V"))); // For JDK < 5 (works also with newer JDKs)
instructions.insert(new SWAP()); // For JDK < 5 (works also with newer JDKs)
instructions.insert(new DUP_X1()); // For JDK < 5 (works also with newer JDKs)
instructions.insert(new NEW(cpGen.addClass("java.lang.Boolean"))); // For JDK < 5 (works also with newer JDKs)
return;
}
}
else if(Type.BYTE.equals(inType)) {
if(byteType.isAssignmentCompatibleWith(outType)) {
//instructions.insert(new INVOKESTATIC(cpGen.addMethodref("java.lang.Byte", "valueOf", "(B)Ljava/lang/Byte;"))); // Only for JDK > 5
instructions.insert(new INVOKESPECIAL(cpGen.addMethodref("java.lang.Byte", "<init>", "(B)V"))); // For JDK < 5 (works also with newer JDKs)
instructions.insert(new SWAP()); // For JDK < 5 (works also with newer JDKs)
instructions.insert(new DUP_X1()); // For JDK < 5 (works also with newer JDKs)
instructions.insert(new NEW(cpGen.addClass("java.lang.Byte"))); // For JDK < 5 (works also with newer JDKs)
return;
}
}
else if(Type.CHAR.equals(inType)) {
if(characterType.isAssignmentCompatibleWith(outType)) {
//instructions.insert(new INVOKESTATIC(cpGen.addMethodref("java.lang.Character", "valueOf", "(C)Ljava/lang/Character;"))); // Only for JDK > 5
instructions.insert(new INVOKESPECIAL(cpGen.addMethodref("java.lang.Character", "<init>", "(C)V"))); // For JDK < 5 (works also with newer JDKs)
instructions.insert(new SWAP()); // For JDK < 5 (works also with newer JDKs)
instructions.insert(new DUP_X1()); // For JDK < 5 (works also with newer JDKs)
instructions.insert(new NEW(cpGen.addClass("java.lang.Character"))); // For JDK < 5 (works also with newer JDKs)
return;
}
}
else if(Type.DOUBLE.equals(inType)) {
if(doubleType.isAssignmentCompatibleWith(outType)) {
//instructions.insert(new INVOKESTATIC(cpGen.addMethodref("java.lang.Double", "valueOf", "(D)Ljava/lang/Double;"))); // Only for JDK > 5
instructions.insert(new INVOKESPECIAL(cpGen.addMethodref("java.lang.Double", "<init>", "(D)V"))); // For JDK < 5 (works also with newer JDKs)
instructions.insert(new POP2()); // For JDK < 5 (works also with newer JDKs)
instructions.insert(new DUP2_X2()); // For JDK < 5 (works also with newer JDKs)
instructions.insert(new DUP()); // For JDK < 5 (works also with newer JDKs)
instructions.insert(new NEW(cpGen.addClass("java.lang.Double"))); // For JDK < 5 (works also with newer JDKs)
return;
}
}
else if(Type.FLOAT.equals(inType)) {
if(floatType.isAssignmentCompatibleWith(outType)) {
//instructions.insert(new INVOKESTATIC(cpGen.addMethodref("java.lang.Float", "valueOf", "(F)Ljava/lang/Float;"))); // Only for JDK > 5
instructions.insert(new INVOKESPECIAL(cpGen.addMethodref("java.lang.Float", "<init>", "(F)V"))); // For JDK < 5 (works also with newer JDKs)
instructions.insert(new SWAP()); // For JDK < 5 (works also with newer JDKs)
instructions.insert(new DUP_X1()); // For JDK < 5 (works also with newer JDKs)
instructions.insert(new NEW(cpGen.addClass("java.lang.Float"))); // For JDK < 5 (works also with newer JDKs)
return;
}
}
else if(Type.INT.equals(inType)) {
if(integerType.isAssignmentCompatibleWith(outType)) {
//instructions.insert(new INVOKESTATIC(cpGen.addMethodref("java.lang.Integer", "valueOf", "(I)Ljava/lang/Integer;"))); // Only for JDK > 5
instructions.insert(new INVOKESPECIAL(cpGen.addMethodref("java.lang.Integer", "<init>", "(I)V"))); // For JDK < 5 (works also with newer JDKs)
instructions.insert(new SWAP()); // For JDK < 5 (works also with newer JDKs)
instructions.insert(new DUP_X1()); // For JDK < 5 (works also with newer JDKs)
instructions.insert(new NEW(cpGen.addClass("java.lang.Integer"))); // For JDK < 5 (works also with newer JDKs)
return;
}
}
else if(Type.LONG.equals(inType)) {
if(longType.isAssignmentCompatibleWith(outType)) {
//instructions.insert(new INVOKESTATIC(cpGen.addMethodref("java.lang.Long", "valueOf", "(J)Ljava/lang/Long;"))); // Only for JDK > 5
instructions.insert(new INVOKESPECIAL(cpGen.addMethodref("java.lang.Long", "<init>", "(J)V"))); // For JDK < 5 (works also with newer JDKs)
instructions.insert(new POP2()); // For JDK < 5 (works also with newer JDKs)
instructions.insert(new DUP2_X2()); // For JDK < 5 (works also with newer JDKs)
instructions.insert(new DUP()); // For JDK < 5 (works also with newer JDKs)
instructions.insert(new NEW(cpGen.addClass("java.lang.Long"))); // For JDK < 5 (works also with newer JDKs)
return;
}
}
else if(Type.SHORT.equals(inType)) {
if(shortType.isAssignmentCompatibleWith(outType)) {
//instructions.insert(new INVOKESTATIC(cpGen.addMethodref("java.lang.Short", "valueOf", "(S)Ljava/lang/Short;"))); // Only for JDK > 5
instructions.insert(new INVOKESPECIAL(cpGen.addMethodref("java.lang.Short", "<init>", "(S)V"))); // For JDK < 5 (works also with newer JDKs)
instructions.insert(new SWAP()); // For JDK < 5 (works also with newer JDKs)
instructions.insert(new DUP_X1()); // For JDK < 5 (works also with newer JDKs)
instructions.insert(new NEW(cpGen.addClass("java.lang.Short"))); // For JDK < 5 (works also with newer JDKs)
return;
}
}
throw new IllegalProceedUsageException("cannot inboxing from " + inType + " to " + outType);
} catch(ClassNotFoundException e) { throw new JVMAIRuntimeException(e.getMessage()); }
}
}