internal JavaConstant.MethodHandle ToConstant(JavaWriter wtr) { int referenceIndex = -1; if (Kind <= HandleKind.PutStatic) { referenceIndex = wtr.ConstField(Class, Field); } else if (Kind <= HandleKind.NewInvokeSpecial) { if (IsInterfaceMethod) { referenceIndex = wtr.ConstInterfaceMethod(Class, Method); } else { referenceIndex = wtr.ConstMethod(Class, Method); } } else if (Kind == HandleKind.InvokeInterface && IsInterfaceMethod) { referenceIndex = wtr.ConstInterfaceMethod(Class, Method); } if (referenceIndex == -1) { throw wtr.Where.Exception("invalid method handle"); } return(new JavaConstant.MethodHandle((byte)Kind, (ushort)referenceIndex)); }
void FillInstruction_ConstLoad(JavaWriter wtr, Instruction inst) { int constantIndex = -1; byte op = 0; if (inst.Data is long vLong) { if (FillInstruction_ConstLoad_Long(inst, vLong)) { return; } constantIndex = wtr.ConstLong(vLong); op = 0x14; } else if (inst.Data is double vDouble) { if (FillInstruction_ConstLoad_Double(inst, vDouble)) { return; } constantIndex = wtr.ConstDouble(vDouble); op = 0x14; } else { if (inst.Class != null) { if (inst.Data is JavaFieldRef vField) { constantIndex = wtr.ConstField(inst.Class, vField); } else if (inst.Data is JavaMethodRef vMethod) { constantIndex = wtr.ConstMethod(inst.Class, vMethod); } else if (inst.Data == null) { constantIndex = wtr.ConstClass(inst.Class); } } else if (inst.Data is int vInteger) { if (FillInstruction_ConstLoad_Integer(inst, vInteger)) { return; } constantIndex = wtr.ConstInteger(vInteger); } else if (inst.Data is float vFloat) { if (FillInstruction_ConstLoad_Float(inst, vFloat)) { return; } constantIndex = wtr.ConstFloat(vFloat); } else if (inst.Data is string vString) { constantIndex = wtr.ConstString(vString); } op = (byte)((constantIndex <= 255) ? 0x12 : 0x13); inst.Opcode = op; } if (constantIndex == -1) { throw wtr.Where.Exception("invalid constant in ldc/ldc_w/ldc2_w instruction"); } if (op == 0x12) { inst.Bytes = new byte[2]; inst.Bytes[1] = (byte)constantIndex; } else { inst.Bytes = new byte[3]; inst.Bytes[1] = (byte)(constantIndex >> 8); inst.Bytes[2] = (byte)constantIndex; } inst.Bytes[0] = op; }
bool FillInstruction_Const(JavaWriter wtr, Instruction inst, byte op) { int length = 3; int count = 0; if (op >= 0x12 && op <= 0x14) { FillInstruction_ConstLoad(wtr, inst); return(true); } int constantIndex = -1; if (op >= 0xB2 && op <= 0xB5) { // getstatic/putstatic/getfield/putfield if (inst.Data is JavaFieldRef vField) { constantIndex = wtr.ConstField(inst.Class, vField); } } else if (op >= 0xB6 && op <= 0xB8) { // invokevirtual/invokespecial/invokestatic if (inst.Data is JavaMethodRef vMethod) { constantIndex = wtr.ConstMethod(inst.Class, vMethod); } } else if (op == 0xB9) { // invokeinterface if (inst.Data is JavaMethodRef vMethod) { constantIndex = wtr.ConstInterfaceMethod(inst.Class, vMethod); length = 5; count = 1; // 'this' argument int numArgs = vMethod.Parameters.Count; for (int i = 0; i < numArgs; i++) { count += vMethod.Parameters[i].Type.Category; } } } else if (op == 0xBA) { // invokedynamic if (inst.Data is JavaCallSite vCallSite) { constantIndex = wtr.ConstInvokeDynamic(vCallSite); length = 5; } } else if (op >= 0xBB) { // new/anewarray/checkcast/instanceof/multianewarray constantIndex = wtr.ConstClass(inst.Class); if (op == 0xC5) { length++; count = (int)inst.Data; } } if (constantIndex == -1) { return(false); } inst.Bytes = new byte[length]; inst.Bytes[0] = op; inst.Bytes[1] = (byte)(constantIndex >> 8); inst.Bytes[2] = (byte)constantIndex; if (op == 0xB9 || op == 0xC5) { inst.Bytes[3] = (byte)count; } return(true); }