private static bool Object_getClass(DynamicTypeWrapper.FinishContext context, CodeEmitter ilgen, MethodWrapper method, MethodAnalyzer ma, int opcodeIndex, MethodWrapper caller, ClassFile classFile, Instruction[] code, InstructionFlags[] flags) { // this is the null-check idiom that javac uses (both in its own source and in the code it generates) if (code[opcodeIndex + 1].NormalizedOpCode == NormalizedByteCode.__pop) { ilgen.Emit(OpCodes.Dup); ilgen.EmitNullCheck(); return(true); } // this optimizes obj1.getClass() ==/!= obj2.getClass() else if (opcodeIndex + 3 < code.Length && (flags[opcodeIndex + 1] & InstructionFlags.BranchTarget) == 0 && (flags[opcodeIndex + 2] & InstructionFlags.BranchTarget) == 0 && (flags[opcodeIndex + 3] & InstructionFlags.BranchTarget) == 0 && code[opcodeIndex + 1].NormalizedOpCode == NormalizedByteCode.__aload && code[opcodeIndex + 2].NormalizedOpCode == NormalizedByteCode.__invokevirtual && (code[opcodeIndex + 3].NormalizedOpCode == NormalizedByteCode.__if_acmpeq || code[opcodeIndex + 3].NormalizedOpCode == NormalizedByteCode.__if_acmpne) && (IsSafeForGetClassOptimization(ma.GetStackTypeWrapper(opcodeIndex, 0)) || IsSafeForGetClassOptimization(ma.GetStackTypeWrapper(opcodeIndex + 2, 0)))) { ClassFile.ConstantPoolItemMI cpi = classFile.GetMethodref(code[opcodeIndex + 2].Arg1); if (cpi.Class == "java.lang.Object" && cpi.Name == "getClass" && cpi.Signature == "()Ljava.lang.Class;") { // we can't patch the current opcode, so we have to emit the first call to GetTypeHandle here ilgen.Emit(OpCodes.Callvirt, Compiler.getTypeMethod); code[opcodeIndex + 2].PatchOpCode(NormalizedByteCode.__intrinsic_gettype); return(true); } } return(false); }