private void emitI2X(Wrapper type) { switch (type.name()) { case "BYTE": ilgen.Emit(OpCodes.Conv_I1); break; case "SHORT": ilgen.Emit(OpCodes.Conv_I2); break; case "CHAR": ilgen.Emit(OpCodes.Conv_U2); break; case "INT": /* naught */ break; case "LONG": ilgen.Emit(OpCodes.Conv_I8); break; case "FLOAT": ilgen.Emit(OpCodes.Conv_R4); break; case "DOUBLE": ilgen.Emit(OpCodes.Conv_R8); break; case "BOOLEAN": // For compatibility with ValueConversions and explicitCastArguments: ilgen.EmitLdc_I4(1); ilgen.Emit(OpCodes.And); break; default: throw new BailoutException(Bailout.PreconditionViolated, "unknown type: " + type); } }
private byte arrayTypeCode(Wrapper elementType) { switch (elementType.name()) { case "BOOLEAN": return(Opcodes.T_BOOLEAN); case "BYTE": return(Opcodes.T_BYTE); case "CHAR": return(Opcodes.T_CHAR); case "SHORT": return(Opcodes.T_SHORT); case "INT": return(Opcodes.T_INT); case "LONG": return(Opcodes.T_LONG); case "FLOAT": return(Opcodes.T_FLOAT); case "DOUBLE": return(Opcodes.T_DOUBLE); case "OBJECT": return(0); // in place of Opcodes.T_OBJECT default: throw new BailoutException(Bailout.PreconditionViolated, "elemendType = " + elementType); } }
private void emitX2I(Wrapper type) { switch (type.name()) { case "LONG": ilgen.Emit(OpCodes.Conv_I4); break; case "FLOAT": ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.f2i); break; case "DOUBLE": ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.d2i); break; default: throw new BailoutException(Bailout.PreconditionViolated, "unknown type: " + type); } }
/** * Emit a type conversion bytecode casting from "from" to "to". */ private void emitPrimCast(Wrapper from, Wrapper to) { // Here's how. // - indicates forbidden // <-> indicates implicit // to ----> boolean byte short char int long float double // from boolean <-> - - - - - - - // byte - <-> i2s i2c <-> i2l i2f i2d // short - i2b <-> i2c <-> i2l i2f i2d // char - i2b i2s <-> <-> i2l i2f i2d // int - i2b i2s i2c <-> i2l i2f i2d // long - l2i,i2b l2i,i2s l2i,i2c l2i <-> l2f l2d // float - f2i,i2b f2i,i2s f2i,i2c f2i f2l <-> f2d // double - d2i,i2b d2i,i2s d2i,i2c d2i d2l d2f <-> if (from == to) { // no cast required, should be dead code anyway return; } if (from.isSubwordOrInt()) { // cast from {byte,short,char,int} to anything emitI2X(to); } else { // cast from {long,float,double} to anything if (to.isSubwordOrInt()) { // cast to {byte,short,char,int} emitX2I(from); if (to.bitWidth() < 32) { // targets other than int require another conversion emitI2X(to); } } else { // cast to {long,float,double} - this is verbose bool error = false; switch (from.name()) { case "LONG": switch (to.name()) { case "FLOAT": ilgen.Emit(OpCodes.Conv_R4); break; case "DOUBLE": ilgen.Emit(OpCodes.Conv_R8); break; default: error = true; break; } break; case "FLOAT": switch (to.name()) { case "LONG": ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.f2l); break; case "DOUBLE": ilgen.Emit(OpCodes.Conv_R8); break; default: error = true; break; } break; case "DOUBLE": switch (to.name()) { case "LONG": ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.d2l); break; case "FLOAT": ilgen.Emit(OpCodes.Conv_R4); break; default: error = true; break; } break; default: error = true; break; } if (error) { throw new BailoutException(Bailout.PreconditionViolated, "unhandled prim cast: " + from + "2" + to); } } } }
/** * Emit a type conversion bytecode casting from "from" to "to". */ private void emitPrimCast(Wrapper from, Wrapper to) { // Here's how. // - indicates forbidden // <-> indicates implicit // to ----> boolean byte short char int long float double // from boolean <-> - - - - - - - // byte - <-> i2s i2c <-> i2l i2f i2d // short - i2b <-> i2c <-> i2l i2f i2d // char - i2b i2s <-> <-> i2l i2f i2d // int - i2b i2s i2c <-> i2l i2f i2d // long - l2i,i2b l2i,i2s l2i,i2c l2i <-> l2f l2d // float - f2i,i2b f2i,i2s f2i,i2c f2i f2l <-> f2d // double - d2i,i2b d2i,i2s d2i,i2c d2i d2l d2f <-> if (from == to) { // no cast required, should be dead code anyway return; } if (from.isSubwordOrInt()) { // cast from {byte,short,char,int} to anything emitI2X(to); } else { // cast from {long,float,double} to anything if (to.isSubwordOrInt()) { // cast to {byte,short,char,int} emitX2I(from); if (to.bitWidth() < 32) { // targets other than int require another conversion emitI2X(to); } } else { // cast to {long,float,double} - this is verbose bool error = false; switch (from.name()) { case "LONG": switch (to.name()) { case "FLOAT": ilgen.Emit(OpCodes.Conv_R4); break; case "DOUBLE": ilgen.Emit(OpCodes.Conv_R8); break; default: error = true; break; } break; case "FLOAT": switch (to.name()) { case "LONG": ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.f2l); break; case "DOUBLE": ilgen.Emit(OpCodes.Conv_R8); break; default: error = true; break; } break; case "DOUBLE": switch (to.name()) { case "LONG" : ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.d2l); break; case "FLOAT": ilgen.Emit(OpCodes.Conv_R4); break; default: error = true; break; } break; default: error = true; break; } if (error) { throw new BailoutException(Bailout.PreconditionViolated, "unhandled prim cast: " + from + "2" + to); } } } }
private byte arrayTypeCode(Wrapper elementType) { switch (elementType.name()) { case "BOOLEAN": return Opcodes.T_BOOLEAN; case "BYTE": return Opcodes.T_BYTE; case "CHAR": return Opcodes.T_CHAR; case "SHORT": return Opcodes.T_SHORT; case "INT": return Opcodes.T_INT; case "LONG": return Opcodes.T_LONG; case "FLOAT": return Opcodes.T_FLOAT; case "DOUBLE": return Opcodes.T_DOUBLE; case "OBJECT": return 0; // in place of Opcodes.T_OBJECT default: throw new BailoutException(Bailout.PreconditionViolated, "elemendType = " + elementType); } }