public boolean checkAccess() { ClassInfo clazzInfo = method.getClazzInfo(); BytecodeInfo bytecode = method.getBytecode(); Handler[] excHandlers = bytecode.getExceptionHandlers(); boolean dupSeen = false; if (excHandlers != null && excHandlers.length != 0) return false; if (method.isStatic()) { if (checkStaticAccess()) return true; } Iterator iter = bytecode.getInstructions().iterator(); Instruction instr = (Instruction) iter.next(); while (instr.getOpcode() == opc_nop && iter.hasNext()) instr = (Instruction) iter.next(); if (instr.getOpcode() != opc_aload || instr.getLocalSlot() != 0) return false; instr = (Instruction) iter.next(); while (instr.getOpcode() == opc_nop && iter.hasNext()) instr = (Instruction) iter.next(); if (instr.getOpcode() == opc_getfield) { Reference ref = instr.getReference(); ClassInfo refClazz = TypeSignature.getClassInfo(ref.getClazz()); if (!refClazz.superClassOf(clazzInfo)) return false; FieldInfo refField = refClazz.findField(ref.getName(), ref.getType()); if ((refField.getModifiers() & modifierMask) != 0) return false; instr = (Instruction) iter.next(); while (instr.getOpcode() == opc_nop && iter.hasNext()) instr = (Instruction) iter.next(); if (instr.getOpcode() < opc_ireturn || instr.getOpcode() > opc_areturn) return false; /* For valid bytecode the type matches automatically */ reference = ref; kind = ACCESSGETFIELD; return true; } int params = 0, slot = 1; while (instr.getOpcode() >= opc_iload && instr.getOpcode() <= opc_aload && instr.getLocalSlot() == slot) { params++; slot += (instr.getOpcode() == opc_lload || instr.getOpcode() == opc_dload) ? 2 : 1; instr = (Instruction) iter.next(); while (instr.getOpcode() == opc_nop && iter.hasNext()) instr = (Instruction) iter.next(); } if (instr.getOpcode() == (opc_dup_x1 - 6) + 3 * slot) { /* * This is probably a opc_dup_x1 or opc_dup2_x1, preceding a * opc_putfield */ instr = (Instruction) iter.next(); while (instr.getOpcode() == opc_nop && iter.hasNext()) instr = (Instruction) iter.next(); if (instr.getOpcode() != opc_putfield) return false; dupSeen = true; } if (instr.getOpcode() == opc_putfield) { if (params != 1) return false; /* For valid bytecode the type of param matches automatically */ Reference ref = instr.getReference(); ClassInfo refClazz = TypeSignature.getClassInfo(ref.getClazz()); if (!refClazz.superClassOf(clazzInfo)) return false; FieldInfo refField = refClazz.findField(ref.getName(), ref.getType()); if ((refField.getModifiers() & modifierMask) != 0) return false; instr = (Instruction) iter.next(); while (instr.getOpcode() == opc_nop && iter.hasNext()) instr = (Instruction) iter.next(); if (dupSeen) { if (instr.getOpcode() < opc_ireturn || instr.getOpcode() > opc_areturn) return false; kind = ACCESSDUPPUTFIELD; } else { if (instr.getOpcode() != opc_return) return false; kind = ACCESSPUTFIELD; } reference = ref; return true; } if (instr.getOpcode() == opc_invokespecial) { Reference ref = instr.getReference(); ClassInfo refClazz = TypeSignature.getClassInfo(ref.getClazz()); if (!refClazz.superClassOf(clazzInfo)) return false; MethodInfo refMethod = refClazz.findMethod(ref.getName(), ref.getType()); MethodType refType = Type.tMethod(ref.getType()); if ((refMethod.getModifiers() & modifierMask) != 0 || refType.getParameterTypes().length != params) return false; instr = (Instruction) iter.next(); while (instr.getOpcode() == opc_nop && iter.hasNext()) instr = (Instruction) iter.next(); if (refType.getReturnType() == Type.tVoid) { if (instr.getOpcode() != opc_return) return false; } else { if (instr.getOpcode() < opc_ireturn || instr.getOpcode() > opc_areturn) return false; } /* For valid bytecode the types matches automatically */ reference = ref; kind = ACCESSMETHOD; return true; } return false; }