RFR(XS): 8143127: InvokerBytecodeGenerator emitConst should handle Byte, Short, Character
Aleksey Shipilev
aleksey.shipilev at oracle.com
Wed Nov 18 22:26:13 UTC 2015
On 11/18/2015 01:08 AM, Claes Redestad wrote:
> On 2015-11-17 22:13, Remi Forax wrote:
>> Hi Claes,
>> I fail to see how this code will not throw a CCE at runtime
>> if (con instanceof Integer || con instanceof Byte || con instanceof
>> Short || con instanceof Character) {
>> emitIconstInsn((int) con);
>> ...
>>
>> (int)con is translated by the compiler to ((Integer)con).intValue()
>>
>> you have to write something like that
>> (con instanceof Character)? (char)con: ((Number)con).intValue()
>
> Well, this is embarrassing. I was fooled by my own sanity testing since
> javac makes the unboxing+cast work when type is known:
>
> Character c = 'a';
> System.out.println((int)c);
>
> but not when going through an Object reference:
>
> Object o = 'a';
> System.out.println((int)o);
>
> This works better:
>
> if (con instanceof Integer) {
> emitIconstInsn((int) con);
> return;
> }
> if (con instanceof Byte) {
> emitIconstInsn((int)(byte)con);
> return;
> }
> if (con instanceof Short) {
> emitIconstInsn((int)(short)con);
> return;
> }
> if (con instanceof Character) {
> emitIconstInsn((int)(char)con);
> return;
> }
By the way, I see there is a cleaner way to implement emitIconstInsn,
see java.lang.invoke.TypeConvertingMethodAdapter.iconst:
void iconst(final int cst) {
if (cst >= -1 && cst <= 5) {
mv.visitInsn(Opcodes.ICONST_0 + cst);
} else if (cst >= Byte.MIN_VALUE && cst <= Byte.MAX_VALUE) {
mv.visitIntInsn(Opcodes.BIPUSH, cst);
} else if (cst >= Short.MIN_VALUE && cst <= Short.MAX_VALUE) {
mv.visitIntInsn(Opcodes.SIPUSH, cst);
} else {
mv.visitLdcInsn(cst);
}
}
http://hg.openjdk.java.net/jdk9/dev/jdk/file/aa9e8b3916ae/src/java.base/share/classes/java/lang/invoke/TypeConvertingMethodAdapter.java#l285
Thanks,
-Aleksey
More information about the core-libs-dev
mailing list