下面列出了org.objectweb.asm.Opcodes# ACC_SYNTHETIC 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public FieldVisitor visitField(final int access, final String name, final String desc, final String signature, final Object value) {
if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
cp.newUTF8("Synthetic");
}
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
cp.newUTF8("Deprecated");
}
cp.newUTF8(name);
cp.newUTF8(desc);
if (signature != null) {
cp.newUTF8("Signature");
cp.newUTF8(signature);
}
if (value != null) {
cp.newConst(value);
}
return new FieldConstantsCollector(cv.visitField(access, name, desc, signature, value), cp);
}
@Override
public MethodVisitor visitMethod(int access, String methodName, String descriptor, String signature,
String[] exceptions) {
userMethods.add(methodName + "/" + descriptor);
MethodVisitor superVisitor = super.visitMethod(access, methodName, descriptor, signature, exceptions);
if (Modifier.isStatic(access)
&& Modifier.isPublic(access)
&& (access & Opcodes.ACC_SYNTHETIC) == 0
&& !methodCustomizers.isEmpty()) {
org.jboss.jandex.Type[] argTypes = AsmUtil.getParameterTypes(descriptor);
MethodInfo method = this.entityInfo.method(methodName, argTypes);
if (method == null) {
throw new IllegalStateException(
"Could not find indexed method: " + thisClass + "." + methodName + " with descriptor " + descriptor
+ " and arg types " + Arrays.toString(argTypes));
}
superVisitor = new PanacheMethodCustomizerVisitor(superVisitor, method, thisClass, methodCustomizers);
}
return new PanacheFieldAccessMethodVisitor(superVisitor, thisClass.getInternalName(), methodName, descriptor,
modelInfo);
}
/**
* Called when a method is visited
*
* @see org.objectweb.asm.tree.ClassNode#visitMethod(int, java.lang.String, java.lang.String, java.lang.String, java.lang.String[])
*/
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
logger.info(MessageFormat.format(InstrumentationMessageLoader.getMessage(MessageConstants.LOG_INSTRUMENTING_METHOD), getClassName() + "##"
+ name));
MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
// no need to instrument synthetic method
if ((access & Opcodes.ACC_SYNTHETIC) == 0) {
return new BlockLogMethodAdapter(getConfig(), access, name, desc, signature, exceptions, mv, getClassName(), getLogClazzName(), env);
} else {
return mv;
}
}
private static String getAccessString(int access) {
List<String> tokens = new ArrayList<String>();
if ((access & Opcodes.ACC_PUBLIC) != 0)
tokens.add("public");
if ((access & Opcodes.ACC_PRIVATE) != 0)
tokens.add("private");
if ((access & Opcodes.ACC_PROTECTED) != 0)
tokens.add("protected");
if ((access & Opcodes.ACC_SYNTHETIC) != 0)
tokens.add("synthetic");
if ((access & Opcodes.ACC_STATIC) != 0)
tokens.add("static");
if ((access & Opcodes.ACC_FINAL) != 0)
tokens.add("final");
if ((access & Opcodes.ACC_TRANSIENT) != 0)
tokens.add("transient");
if ((access & Opcodes.ACC_VOLATILE) != 0)
tokens.add("volatile");
if (tokens.size() == 0)
return "";
// hackery delimeters
StringBuilder sb = new StringBuilder(tokens.get(0));
for (int i = 1; i < tokens.size(); i++) {
sb.append(" ");
sb.append(tokens.get(i));
}
return sb.toString();
}
public FieldVisitor visitField(
final int access,
final String name,
final String desc,
final String signature,
final Object value)
{
if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
cp.newUTF8("Synthetic");
}
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
cp.newUTF8("Deprecated");
}
cp.newUTF8(name);
cp.newUTF8(desc);
if (signature != null) {
cp.newUTF8("Signature");
cp.newUTF8(signature);
}
if (value != null) {
cp.newConst(value);
}
return new FieldConstantsCollector(cv.visitField(access,
name,
desc,
signature,
value), cp);
}
@Override
public void process(ProcessorCallback callback, ClassNode node) {
if (!enabled.getObject()) return;
if ((node.access & Opcodes.ACC_INTERFACE) == 0) {
for (MethodNode method : node.methods) {
// if ((method.access & Opcodes.ACC_BRIDGE) == 0 && (method.access & Opcodes.ACC_STATIC) == 0 && !method.name.startsWith("<")) {
// method.access |= Opcodes.ACC_BRIDGE;
// }
// if ((method.access & Opcodes.ACC_SYNTHETIC) == 0) {
if (method.name.startsWith("<"))
continue;
if ((method.access & Opcodes.ACC_NATIVE) == 0) {
continue;
}
method.access = method.access | Opcodes.ACC_BRIDGE;
method.access = method.access | Opcodes.ACC_SYNTHETIC;
// }
}
}
for (FieldNode field : node.fields) {
// if ((field.access & Opcodes.ACC_FINAL) == 0)
field.access = field.access | Opcodes.ACC_SYNTHETIC;
}
// if ((node.access & Opcodes.ACC_FINAL) == 0) {
// node.access = node.access | Opcodes.ACC_SYNTHETIC;
// }
inst.setWorkDone();
}
@Test
public void shouldReportWhenClassIsSynthetic() {
this.data.access = Opcodes.ACC_SYNTHETIC | Opcodes.ACC_PUBLIC;
final ClassInfo testee = new ClassInfo(emptyClassPointer(),
emptyClassPointer(), this.data);
assertTrue(testee.isSynthetic());
}
private static boolean isSyntheticOrBridged(int access) {
return (((access & Opcodes.ACC_SYNTHETIC) | (access & Opcodes.ACC_BRIDGE)) > 0);
}
/**
* Initialise a ClassInfo from the supplied {@link ClassNode}
*
* @param classNode Class node to inspect
*/
private ClassInfo(ClassNode classNode) {
Section timer = ClassInfo.profiler.begin(Profiler.ROOT, "class.meta");
try {
this.name = classNode.name;
this.superName = classNode.superName != null ? classNode.superName : ClassInfo.JAVA_LANG_OBJECT;
this.initialisers = new HashSet<Method>();
this.methods = new HashSet<Method>();
this.fields = new HashSet<Field>();
this.isInterface = ((classNode.access & Opcodes.ACC_INTERFACE) != 0);
this.interfaces = new HashSet<String>();
this.access = classNode.access;
this.isMixin = classNode instanceof MixinClassNode;
this.mixin = this.isMixin ? ((MixinClassNode)classNode).getMixin() : null;
this.mixins = this.isMixin ? Collections.<MixinInfo>emptySet() : new HashSet<MixinInfo>();
this.interfaces.addAll(classNode.interfaces);
for (MethodNode method : classNode.methods) {
this.addMethod(method, this.isMixin);
}
boolean isProbablyStatic = true;
String outerName = classNode.outerClass;
for (FieldNode field : classNode.fields) {
if ((field.access & Opcodes.ACC_SYNTHETIC) != 0) {
if (field.name.startsWith("this$")) {
isProbablyStatic = false;
if (outerName == null) {
outerName = field.desc;
if (outerName != null && outerName.startsWith("L")) {
outerName = outerName.substring(1, outerName.length() - 1);
}
}
}
}
this.fields.add(new Field(field, this.isMixin));
}
this.isProbablyStatic = isProbablyStatic;
this.outerName = outerName;
this.methodMapper = new MethodMapper(MixinEnvironment.getCurrentEnvironment(), this);
this.signature = ClassSignature.ofLazy(classNode);
} finally {
timer.end();
}
}
public FieldVisitor visitField(final int access, final String name, final String descriptor, final String signature, final Object value) {
// int ACC_PUBLIC = 0x0001; // class, field, method
// int ACC_PRIVATE = 0x0002; // class, field, method
// int ACC_PROTECTED = 0x0004; // class, field, method
// int ACC_STATIC = 0x0008; // field, method
// int ACC_FINAL = 0x0010; // class, field, method, parameter
// int ACC_SUPER = 0x0020; // class
// int ACC_SYNCHRONIZED = 0x0020; // method
// int ACC_OPEN = 0x0020; // module
// int ACC_TRANSITIVE = 0x0020; // module requires
// int ACC_VOLATILE = 0x0040; // field
// int ACC_BRIDGE = 0x0040; // method
// int ACC_STATIC_PHASE = 0x0040; // module requires
// int ACC_VARARGS = 0x0080; // method
// int ACC_TRANSIENT = 0x0080; // field
// int ACC_NATIVE = 0x0100; // method
// int ACC_INTERFACE = 0x0200; // class
// int ACC_ABSTRACT = 0x0400; // class, method
// int ACC_STRICT = 0x0800; // method
// int ACC_SYNTHETIC = 0x1000; // class, field, method, parameter, module *
// int ACC_ANNOTATION = 0x2000; // class
// int ACC_ENUM = 0x4000; // class(?) field inner
// int ACC_MANDATED = 0x8000; // parameter, module, module *
// int ACC_MODULE = 0x8000; // class
append("// Access:");
for (int mods = access; mods != 0;) {
int mod = Integer.lowestOneBit(mods);
switch (mod) {
case Opcodes.ACC_PUBLIC: {
append(" public");
break;
}
case Opcodes.ACC_PRIVATE: {
append(" private");
break;
}
case Opcodes.ACC_PROTECTED: {
append(" protected");
break;
}
case Opcodes.ACC_STATIC: {
append(" static");
break;
}
case Opcodes.ACC_FINAL: {
append(" final");
break;
}
case Opcodes.ACC_VOLATILE: {
append(" volatile");
break;
}
case Opcodes.ACC_TRANSIENT: {
append(" transient");
break;
}
case Opcodes.ACC_SYNTHETIC: {
append(" synthetic");
break;
}
case Opcodes.ACC_ENUM: {
append(" enum");
break;
}
}
mods ^= mod;
}
newLine();
append("Field ").append(name).append(" : ").append(Type.getType(descriptor)).newLine().newLine();
return super.visitField(access, name, descriptor, signature, value);
}
/**
* Utility method to get the access modifiers of a Host
* @param modVal The bitset representation of the Host's modifiers
* @param host The Host (SootClass, SootField or SootMethod) the modifiers are to be retrieved from
* @return A bitset representation of the Host's modifiers in ASM's internal representation
*/
protected static int getModifiers(int modVal, Host host) {
int modifier = 0;
// Retrieve visibility-modifier
if (Modifier.isPublic(modVal)) {
modifier |= Opcodes.ACC_PUBLIC;
} else if (Modifier.isPrivate(modVal)) {
modifier |= Opcodes.ACC_PRIVATE;
} else if (Modifier.isProtected(modVal)) {
modifier |= Opcodes.ACC_PROTECTED;
}
// Retrieve static-modifier
if (Modifier.isStatic(modVal)
&& ((host instanceof SootField) || (host instanceof SootMethod))) {
modifier |= Opcodes.ACC_STATIC;
}
// Retrieve final-modifier
if (Modifier.isFinal(modVal)) {
modifier |= Opcodes.ACC_FINAL;
}
// Retrieve synchronized-modifier
if (Modifier.isSynchronized(modVal) && host instanceof SootMethod) {
modifier |= Opcodes.ACC_SYNCHRONIZED;
}
// Retrieve volatile/bridge-modifier
if (Modifier.isVolatile(modVal) && !(host instanceof SootClass)) {
modifier |= Opcodes.ACC_VOLATILE;
}
// Retrieve transient/varargs-modifier
if (Modifier.isTransient(modVal) && !(host instanceof SootClass)) {
modifier |= Opcodes.ACC_TRANSIENT;
}
// Retrieve native-modifier
if (Modifier.isNative(modVal) && host instanceof SootMethod) {
modifier |= Opcodes.ACC_NATIVE;
}
// Retrieve interface-modifier
if (Modifier.isInterface(modVal) && host instanceof SootClass) {
modifier |= Opcodes.ACC_INTERFACE;
} else if (host instanceof SootClass) {
/*
* For all classes except for interfaces the super-flag should be
* set. See JVM 8-Specification section 4.1, page 72.
*/
modifier |= Opcodes.ACC_SUPER;
}
// Retrieve abstract-modifier
if (Modifier.isAbstract(modVal) && !(host instanceof SootField)) {
modifier |= Opcodes.ACC_ABSTRACT;
}
// Retrieve strictFP-modifier
if (Modifier.isStrictFP(modVal) && host instanceof SootMethod) {
modifier |= Opcodes.ACC_STRICT;
}
/*
* Retrieve synthetic-modifier. Class not present in source-code but
* generated by e.g. compiler TODO Do we need both checks?
*/
if (Modifier.isSynthetic(modVal) || host.hasTag("SyntheticTag")) {
modifier |= Opcodes.ACC_SYNTHETIC;
}
// Retrieve annotation-modifier
if (Modifier.isAnnotation(modVal) && host instanceof SootClass) {
modifier |= Opcodes.ACC_ANNOTATION;
}
// Retrieve enum-modifier
if (Modifier.isEnum(modVal) && !(host instanceof SootMethod)) {
modifier |= Opcodes.ACC_ENUM;
}
return modifier;
}
@Override
@Nullable
public MethodVisitor visitMethod(
int access, String name, String desc, String signature, String[] exceptions) {
if (methodsWithRetainedBody.contains(name)
|| (name.endsWith("$default")
&& methodsWithRetainedBody.contains(name.substring(0, name.length() - 8)))) {
if (name.equals("<init>") && (access & (Opcodes.ACC_PRIVATE | Opcodes.ACC_SYNTHETIC)) == 0) {
hasVisibleConstructor = true;
}
return super.visitMethod(access, name, desc, signature, exceptions);
}
// Per JVMS8 2.9, "Class and interface initialization methods are invoked
// implicitly by the Java Virtual Machine; they are never invoked directly from any
// Java Virtual Machine instruction, but are invoked only indirectly as part of the class
// initialization process." Thus we don't need to emit a stub of <clinit>.
if (!shouldInclude(access) || (name.equals("<clinit>") && (access & Opcodes.ACC_STATIC) > 0)) {
return null;
}
// We don't stub private constructors, but if stripping these constructors results in no
// constructors at all, we want to include a default private constructor. This is because
// removing all these private methods will make the class look like it has no constructors at
// all, which is not possible. We track if this class has a public, non-synthetic constructor
// and is not an interface or annotation to determine if a default private constructor is
// generated when visitEnd() is called.
if (name.equals("<init>") && (access & Opcodes.ACC_SYNTHETIC) == 0) {
hasVisibleConstructor = true;
}
// Bridge methods are created by the compiler, and don't appear in source. It would be nice to
// skip them, but they're used by the compiler to cover the fact that type erasure has occurred.
// Normally the compiler adds these as public methods, but if you're compiling against a stub
// produced using our ABI generator, we don't want people calling it accidentally. Oh well, I
// guess it happens IRL too.
//
// Synthetic methods are also generated by the compiler, unless it's one of the methods named in
// section 4.7.8 of the JVM spec, which are "<init>" and "Enum.valueOf()" and "Enum.values".
// None of these are actually harmful to the ABI, so we allow synthetic methods through.
// http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.8
return new SkipCodeMethodVisitor(
Opcodes.ASM7, super.visitMethod(access, name, desc, signature, exceptions));
}
/**
* {@inheritDoc}
*/
public int getModifiers() {
return Opcodes.ACC_SYNTHETIC | Opcodes.ACC_PRIVATE;
}
@Override
public MethodVisitor visitMethod(int access, final String name, final String desc, String signature, String[] exceptions) {
if (isAnnotation) {
return null;
}
boolean isSynthetic = (access & Opcodes.ACC_SYNTHETIC) != 0;
boolean isPackagePrivate = (access & (Opcodes.ACC_PRIVATE | Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED)) == 0;
if (isSynthetic) {
final boolean isAccessor = isPackagePrivate && name.startsWith("access$") && (access & Opcodes.ACC_STATIC) != 0;
final boolean isBridge = (access & Opcodes.ACC_BRIDGE) != 0;
if (isAccessor || isBridge) {
return new MethodAdapter(NOP) {
@Override
public void visitMethodInsn(int opcode, String owner, String targetName, String targetDesc) {
if (selfclass.equals(owner)) {
if (isAccessor) {
actual2accessor.put(targetName + targetDesc, name + desc);
}
if (isBridge) {
bridge2specialization.put(name + desc, targetName + targetDesc);
}
}
}
};
}
}
// If this method is desugared lambda body
if ( isSynthetic && isPackagePrivate && name.startsWith("lambda$") ) {
// RetroLambda desugars method body to package private
desugaredLambdaBodies.add(name + desc);
return null;
}
return new MethodAdapter(NOP) {
private boolean methodContinuableAnnotationFound = false;
@Override
public AnnotationVisitor visitAnnotation(String description, boolean visible) {
if (!methodContinuableAnnotationFound) {
methodContinuableAnnotationFound = cciResolver.isContinuableAnnotation(description);
}
return null;
}
@Override
public void visitEnd() {
if (methodContinuableAnnotationFound) {
continuableMethods.add(name + desc);
}
}
};
}
private static boolean isSyntheticClass(ClassNode node) {
return ((node.access & Opcodes.ACC_SYNTHETIC) == Opcodes.ACC_SYNTHETIC);
}
@Override
public MethodVisitor visitMethod(int access, final String name, final String desc, String signature, String[] exceptions) {
if (isAnnotation) {
return null;
}
boolean isSynthetic = (access & Opcodes.ACC_SYNTHETIC) != 0;
boolean isPackagePrivate = (access & (Opcodes.ACC_PRIVATE | Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED)) == 0;
if (isSynthetic) {
final boolean isAccessor = isPackagePrivate && name.startsWith("access$") && (access & Opcodes.ACC_STATIC) != 0;
final boolean isBridge = (access & Opcodes.ACC_BRIDGE) != 0;
if (isAccessor || isBridge) {
return new MethodVisitor(this.api) {
@Override
public void visitMethodInsn(int opcode, String owner, String targetName, String targetDesc) {
if (selfclass.equals(owner)) {
if (isAccessor) {
actual2accessor.put(targetName + targetDesc, name + desc);
}
if (isBridge) {
bridge2specialization.put(name + desc, targetName + targetDesc);
}
}
}
};
}
}
// If this method is desugared lambda body
if ( isSynthetic && isPackagePrivate && name.startsWith("lambda$") ) {
// RetroLambda desugars method body to package private
desugaredLambdaBodies.add(name + desc);
return null;
}
return new MethodVisitor(this.api) {
private boolean methodContinuableAnnotationFound = false;
@Override
public AnnotationVisitor visitAnnotation(String description, boolean visible) {
if (!methodContinuableAnnotationFound) {
methodContinuableAnnotationFound = cciResolver.isContinuableAnnotation(description);
}
return null;
}
@Override
public void visitEnd() {
if (methodContinuableAnnotationFound) {
continuableMethods.add(name + desc);
}
}
};
}
/**
* Get whether this class has ACC_SYNTHETIC
*/
public boolean isSynthetic() {
return (this.access & Opcodes.ACC_SYNTHETIC) != 0;
}
public boolean isSynthetic() {
return (this.classReader.getAccess() & Opcodes.ACC_SYNTHETIC) != 0;
}
public boolean isSynthetic()
{
return (accessFlags & Opcodes.ACC_SYNTHETIC) != 0;
}
private void generateJvmBridge(MethodInfo method) {
// get a bounds-erased descriptor
String descriptor = AsmUtil.getDescriptor(method, name -> null);
// make sure we need a bridge
if (!userMethods.contains(method.name() + "/" + descriptor)) {
MethodVisitor mv = super.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_BRIDGE,
method.name(),
descriptor,
null,
null);
List<org.jboss.jandex.Type> parameters = method.parameters();
for (int i = 0; i < parameters.size(); i++) {
mv.visitParameter(method.parameterName(i), 0 /* modifiers */);
}
mv.visitCode();
// this
mv.visitIntInsn(Opcodes.ALOAD, 0);
// each param
for (int i = 0; i < parameters.size(); i++) {
org.jboss.jandex.Type paramType = parameters.get(i);
if (paramType.kind() == Kind.PRIMITIVE)
throw new IllegalStateException("BUG: Don't know how to generate JVM bridge method for " + method
+ ": has primitive parameters");
mv.visitIntInsn(Opcodes.ALOAD, i + 1);
if (paramType.kind() == Kind.TYPE_VARIABLE) {
String typeParamName = paramType.asTypeVariable().identifier();
switch (typeParamName) {
case "Entity":
mv.visitTypeInsn(Opcodes.CHECKCAST, entityBinaryType);
break;
case "Id":
mv.visitTypeInsn(Opcodes.CHECKCAST, idBinaryType);
break;
}
}
}
String targetDescriptor = AsmUtil.getDescriptor(method, name -> typeArguments.get(name));
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
daoBinaryName,
method.name(),
targetDescriptor, false);
String targetReturnTypeDescriptor = targetDescriptor.substring(targetDescriptor.indexOf(')') + 1);
mv.visitInsn(AsmUtil.getReturnInstruction(targetReturnTypeDescriptor));
mv.visitMaxs(0, 0);
mv.visitEnd();
}
}