List of usage examples for org.objectweb.asm Opcodes ACC_STATIC
int ACC_STATIC
To view the source code for org.objectweb.asm Opcodes ACC_STATIC.
Click Source Link
From source file:com.google.devtools.build.android.desugar.CoreLibrarySupport.java
License:Open Source License
/** Includes the given method definition in any applicable core interface emulation logic. */ public void registerIfEmulatedCoreInterface(int access, String owner, String name, String desc, String[] exceptions) {//w ww . ja v a 2 s .c o m Class<?> emulated = getEmulatedCoreClassOrInterface(owner); if (emulated == null) { return; } checkArgument(emulated.isInterface(), "Shouldn't be called for a class: %s.%s", owner, name); checkArgument( BitFlags.noneSet(access, Opcodes.ACC_ABSTRACT | Opcodes.ACC_NATIVE | Opcodes.ACC_STATIC | Opcodes.ACC_BRIDGE), "Should only be called for default methods: %s.%s", owner, name); emulatedDefaultMethods.put(name + ":" + desc, EmulatedMethod.create(access, emulated, name, desc, exceptions)); }
From source file:com.google.devtools.build.android.desugar.CoreLibrarySupport.java
License:Open Source License
private void makeDispatchHelperMethod(ClassVisitor helper, EmulatedMethod method, ImmutableList<Class<?>> typechecks) { checkArgument(method.owner().isInterface()); String owner = method.owner().getName().replace('.', '/'); Type methodType = Type.getMethodType(method.descriptor()); String companionDesc = InterfaceDesugaring.companionDefaultMethodDescriptor(owner, method.descriptor()); MethodVisitor dispatchMethod = helper.visitMethod(method.access() | Opcodes.ACC_STATIC, method.name(), companionDesc, /*signature=*/ null, // signature is invalid due to extra "receiver" argument method.exceptions().toArray(EMPTY_LIST)); dispatchMethod.visitCode();/*from ww w.ja v a2 s. c o m*/ { // See if the receiver might come with its own implementation of the method, and call it. // We do this by testing for the interface type created by EmulatedInterfaceRewriter Label fallthrough = new Label(); String emulationInterface = renameCoreLibrary(owner); dispatchMethod.visitVarInsn(Opcodes.ALOAD, 0); // load "receiver" dispatchMethod.visitTypeInsn(Opcodes.INSTANCEOF, emulationInterface); dispatchMethod.visitJumpInsn(Opcodes.IFEQ, fallthrough); dispatchMethod.visitVarInsn(Opcodes.ALOAD, 0); // load "receiver" dispatchMethod.visitTypeInsn(Opcodes.CHECKCAST, emulationInterface); visitLoadArgs(dispatchMethod, methodType, 1 /* receiver already loaded above */); dispatchMethod.visitMethodInsn(Opcodes.INVOKEINTERFACE, emulationInterface, method.name(), method.descriptor(), /*itf=*/ true); dispatchMethod.visitInsn(methodType.getReturnType().getOpcode(Opcodes.IRETURN)); dispatchMethod.visitLabel(fallthrough); // Trivial frame for the branch target: same empty stack as before dispatchMethod.visitFrame(Opcodes.F_SAME, 0, EMPTY_FRAME, 0, EMPTY_FRAME); } // Next, check for subtypes with specialized implementations and call them for (Class<?> tested : typechecks) { Label fallthrough = new Label(); String testedName = tested.getName().replace('.', '/'); // In case of a class this must be a member move; for interfaces use the companion. String target = tested.isInterface() ? InterfaceDesugaring.getCompanionClassName(testedName) : checkNotNull(memberMoves.get(rewriter.unprefix(testedName) + '#' + method.name())); dispatchMethod.visitVarInsn(Opcodes.ALOAD, 0); // load "receiver" dispatchMethod.visitTypeInsn(Opcodes.INSTANCEOF, testedName); dispatchMethod.visitJumpInsn(Opcodes.IFEQ, fallthrough); dispatchMethod.visitVarInsn(Opcodes.ALOAD, 0); // load "receiver" dispatchMethod.visitTypeInsn(Opcodes.CHECKCAST, testedName); // make verifier happy visitLoadArgs(dispatchMethod, methodType, 1 /* receiver already loaded above */); dispatchMethod.visitMethodInsn(Opcodes.INVOKESTATIC, target, method.name(), InterfaceDesugaring.companionDefaultMethodDescriptor(testedName, method.descriptor()), /*itf=*/ false); dispatchMethod.visitInsn(methodType.getReturnType().getOpcode(Opcodes.IRETURN)); dispatchMethod.visitLabel(fallthrough); // Trivial frame for the branch target: same empty stack as before dispatchMethod.visitFrame(Opcodes.F_SAME, 0, EMPTY_FRAME, 0, EMPTY_FRAME); } // Call static type's default implementation in companion class dispatchMethod.visitVarInsn(Opcodes.ALOAD, 0); // load "receiver" visitLoadArgs(dispatchMethod, methodType, 1 /* receiver already loaded above */); dispatchMethod.visitMethodInsn(Opcodes.INVOKESTATIC, InterfaceDesugaring.getCompanionClassName(owner), method.name(), companionDesc, /*itf=*/ false); dispatchMethod.visitInsn(methodType.getReturnType().getOpcode(Opcodes.IRETURN)); dispatchMethod.visitMaxs(0, 0); dispatchMethod.visitEnd(); }
From source file:com.google.devtools.build.android.desugar.DefaultMethodClassFixer.java
License:Open Source License
private void recordIfInstanceMethod(int access, String name, String desc) { if (BitFlags.noneSet(access, Opcodes.ACC_STATIC)) { // Record all declared instance methods, including abstract, bridge, and native methods, as // they all take precedence over default methods. instanceMethods.add(name + ":" + desc); }//from w w w .j a v a2 s . c o m }
From source file:com.google.devtools.build.android.desugar.DefaultMethodClassFixer.java
License:Open Source License
/** * Returns {@code true} for non-bridge default methods not in {@link #instanceMethods}. *//* w w w . j a v a 2s . c o m*/ private boolean shouldStub(int access, String name, String desc) { // Ignore private methods, which technically aren't default methods and can only be called from // other methods defined in the interface. This also ignores lambda body methods, which is fine // as we don't want or need to stub those. Also ignore bridge methods as javac adds them to // concrete classes as needed anyway and we handle them separately for generated lambda classes. return BitFlags.noneSet(access, Opcodes.ACC_ABSTRACT | Opcodes.ACC_STATIC | Opcodes.ACC_BRIDGE | Opcodes.ACC_PRIVATE) && !instanceMethods.contains(name + ":" + desc); }
From source file:com.google.devtools.build.android.desugar.InterfaceDesugaring.java
License:Open Source License
@Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { MethodVisitor result;/*from w w w. j av a 2s. c o m*/ if (BitFlags.isSet(accessFlags, Opcodes.ACC_INTERFACE) && BitFlags.noneSet(access, Opcodes.ACC_ABSTRACT | Opcodes.ACC_BRIDGE) && !"<clinit>".equals(name)) { checkArgument(BitFlags.noneSet(access, Opcodes.ACC_NATIVE), "Forbidden per JLS ch 9.4"); boolean isLambdaBody = name.startsWith("lambda$") && BitFlags.isSet(access, Opcodes.ACC_SYNTHETIC); if (isLambdaBody) { access &= ~Opcodes.ACC_PUBLIC; // undo visibility change from LambdaDesugaring // Rename lambda method to reflect the new owner. Not doing so confuses LambdaDesugaring // if it's run over this class again. name += COMPANION_SUFFIX; } if (BitFlags.isSet(access, Opcodes.ACC_STATIC)) { // Completely move static interface methods, which requires rewriting call sites result = companion().visitMethod(access & ~Opcodes.ACC_PRIVATE, name, desc, signature, exceptions); } else { MethodVisitor abstractDest; if (isLambdaBody) { // Completely move lambda bodies, which requires rewriting call sites access &= ~Opcodes.ACC_PRIVATE; abstractDest = null; } else { // Make default methods abstract but move their implementation into a static method with // corresponding signature. Doesn't require callsite rewriting but implementing classes // may need to implement default methods explicitly. checkArgument(BitFlags.noneSet(access, Opcodes.ACC_PRIVATE), "Unexpected private interface method %s.%s : %s", name, internalName, desc); abstractDest = super.visitMethod(access | Opcodes.ACC_ABSTRACT, name, desc, signature, exceptions); } // TODO(b/37110951): adjust signature with explicit receiver type, which may be generic MethodVisitor codeDest = companion().visitMethod(access | Opcodes.ACC_STATIC, name, companionDefaultMethodDescriptor(internalName, desc), (String) null, // drop signature, since given one doesn't include the new param exceptions); result = abstractDest != null ? new MultiplexAnnotations(codeDest, abstractDest) : codeDest; } } else { result = super.visitMethod(access, name, desc, signature, exceptions); } return result != null ? new InterfaceInvocationRewriter(result) : null; }
From source file:com.google.devtools.build.android.desugar.Java7Compatibility.java
License:Open Source License
@Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { // Remove bridge default methods in interfaces; javac generates them again for implementing // classes anyways. if (isInterface && (access & (Opcodes.ACC_BRIDGE | Opcodes.ACC_ABSTRACT | Opcodes.ACC_STATIC)) == Opcodes.ACC_BRIDGE) { return null; }//w w w .j a v a 2 s .c o m if (isInterface && "$jacocoInit".equals(name) && BitFlags.isSet(access, Opcodes.ACC_SYNTHETIC | Opcodes.ACC_STATIC)) { // Drop static interface method that Jacoco generates--we'll inline it into the static // initializer instead return null; } // TODO(b/31547323): Avoid stack trace and report errors more user-friendly checkArgument(!isInterface || BitFlags.isSet(access, Opcodes.ACC_ABSTRACT) || "<clinit>".equals(name), "Interface %s defines non-abstract method %s%s, which is not supported", internalName, name, desc); MethodVisitor result = super.visitMethod(access, name, desc, signature, exceptions); return (isInterface && "<clinit>".equals(name)) ? new InlineJacocoInit(result) : result; }
From source file:com.google.devtools.build.android.desugar.LambdaClassFixer.java
License:Open Source License
@Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { if (name.equals("writeReplace") && BitFlags.noneSet(access, Opcodes.ACC_STATIC) && desc.equals("()Ljava/lang/Object;")) { // Lambda serialization hooks use java/lang/invoke/SerializedLambda, which isn't available on // Android. Since Jack doesn't do anything special for serializable lambdas we just drop these // serialization hooks. // https://docs.oracle.com/javase/8/docs/platform/serialization/spec/output.html#a5324 gives // details on the role and signature of this method. return null; }// ww w . ja v a2 s .c om if (BitFlags.noneSet(access, Opcodes.ACC_ABSTRACT | Opcodes.ACC_STATIC)) { // Keep track of instance methods implemented in this class for later. Since this visitor // is intended for lambda classes, no need to look at the superclass. implementedMethods.add(name + ":" + desc); } if (FACTORY_METHOD_NAME.equals(name)) { hasFactory = true; if (!lambdaInfo.needFactory()) { return null; // drop generated factory method if we won't call it } access &= ~Opcodes.ACC_PRIVATE; // make factory method accessible } else if ("<init>".equals(name)) { this.desc = desc; this.signature = signature; if (!lambdaInfo.needFactory() && !desc.startsWith("()")) { access &= ~Opcodes.ACC_PRIVATE; // make constructor accessible if we'll call it directly } } MethodVisitor methodVisitor = new LambdaClassMethodRewriter( super.visitMethod(access, name, desc, signature, exceptions)); if (!lambdaInfo.bridgeMethod().equals(lambdaInfo.methodReference())) { // Skip UseBridgeMethod unless we actually need it methodVisitor = new UseBridgeMethod(methodVisitor, lambdaInfo, access, name, desc, signature, exceptions); } if (!FACTORY_METHOD_NAME.equals(name) && !"<init>".equals(name)) { methodVisitor = new LambdaClassInvokeSpecialRewriter(methodVisitor); } return methodVisitor; }
From source file:com.google.devtools.build.android.desugar.LambdaClassFixer.java
License:Open Source License
@Override public void visitEnd() { checkState(!hasState || hasFactory, "Expected factory method for capturing lambda %s", getInternalName()); if (!hasState) { checkState(signature == null, "Didn't expect generic constructor signature %s %s", getInternalName(), signature);/*from w w w .ja va 2s . c o m*/ checkState(lambdaInfo.factoryMethodDesc().startsWith("()"), "Expected 0-arg factory method for %s but found %s", getInternalName(), lambdaInfo.factoryMethodDesc()); // Since this is a stateless class we populate and use a static singleton field "$instance". // Field is package-private so we can read it from the class that had the invokedynamic. String singletonFieldDesc = lambdaInfo.factoryMethodDesc().substring("()".length()); super.visitField(Opcodes.ACC_STATIC | Opcodes.ACC_FINAL, SINGLETON_FIELD_NAME, singletonFieldDesc, (String) null, (Object) null).visitEnd(); MethodVisitor codeBuilder = super.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", (String) null, new String[0]); codeBuilder.visitTypeInsn(Opcodes.NEW, getInternalName()); codeBuilder.visitInsn(Opcodes.DUP); codeBuilder.visitMethodInsn(Opcodes.INVOKESPECIAL, getInternalName(), "<init>", checkNotNull(desc, "didn't see a constructor for %s", getInternalName()), /*itf*/ false); codeBuilder.visitFieldInsn(Opcodes.PUTSTATIC, getInternalName(), SINGLETON_FIELD_NAME, singletonFieldDesc); codeBuilder.visitInsn(Opcodes.RETURN); codeBuilder.visitMaxs(2, 0); // two values are pushed onto the stack codeBuilder.visitEnd(); } copyRewrittenLambdaMethods(); if (!allowDefaultMethods) { copyBridgeMethods(interfaces); } super.visitEnd(); }
From source file:com.google.devtools.build.android.desugar.LambdaDesugaring.java
License:Open Source License
@Override public void visitEnd() { for (Map.Entry<Handle, MethodReferenceBridgeInfo> bridge : bridgeMethods.entrySet()) { Handle original = bridge.getKey(); Handle neededMethod = bridge.getValue().bridgeMethod(); checkState(// w w w. ja v a2 s . c o m neededMethod.getTag() == Opcodes.H_INVOKESTATIC || neededMethod.getTag() == Opcodes.H_INVOKEVIRTUAL, "Cannot generate bridge method %s to reach %s", neededMethod, original); checkState(bridge.getValue().referenced() != null, "Need referenced method %s to generate bridge %s", original, neededMethod); int access = Opcodes.ACC_BRIDGE | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_FINAL; if (neededMethod.getTag() == Opcodes.H_INVOKESTATIC) { access |= Opcodes.ACC_STATIC; } MethodVisitor bridgeMethod = super.visitMethod(access, neededMethod.getName(), neededMethod.getDesc(), (String) null, toInternalNames(bridge.getValue().referenced().getExceptionTypes())); // Bridge is a factory method calling a constructor if (original.getTag() == Opcodes.H_NEWINVOKESPECIAL) { bridgeMethod.visitTypeInsn(Opcodes.NEW, original.getOwner()); bridgeMethod.visitInsn(Opcodes.DUP); } int slot = 0; if (neededMethod.getTag() != Opcodes.H_INVOKESTATIC) { bridgeMethod.visitVarInsn(Opcodes.ALOAD, slot++); } Type neededType = Type.getMethodType(neededMethod.getDesc()); for (Type arg : neededType.getArgumentTypes()) { bridgeMethod.visitVarInsn(arg.getOpcode(Opcodes.ILOAD), slot); slot += arg.getSize(); } bridgeMethod.visitMethodInsn(invokeOpcode(original), original.getOwner(), original.getName(), original.getDesc(), original.isInterface()); bridgeMethod.visitInsn(neededType.getReturnType().getOpcode(Opcodes.IRETURN)); bridgeMethod.visitMaxs(0, 0); // rely on class writer to compute these bridgeMethod.visitEnd(); } super.visitEnd(); }
From source file:com.google.devtools.build.android.desugar.LambdaDesugaring.java
License:Open Source License
@Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { if (name.equals("$deserializeLambda$") && BitFlags.isSet(access, Opcodes.ACC_SYNTHETIC)) { // Android doesn't do anything special for lambda serialization so drop the special // deserialization hook that javac generates. This also makes sure we don't reference // java/lang/invoke/SerializedLambda, which doesn't exist on Android. return null; }//from w ww . ja v a 2s.c o m if (name.startsWith("lambda$") && BitFlags.isSet(access, Opcodes.ACC_SYNTHETIC)) { if (!allowDefaultMethods && isInterface && BitFlags.isSet(access, Opcodes.ACC_STATIC)) { // There must be a lambda in the interface (which in the absence of hand-written default or // static interface methods must mean it's in the <clinit> method or inside another lambda). // We'll move this method out of this class, so just record and drop it here. // (Note lambda body methods have unique names, so we don't need to remember desc here.) aggregateInterfaceLambdaMethods.add(internalName + '#' + name); return null; } if (BitFlags.isSet(access, Opcodes.ACC_PRIVATE)) { // Make lambda body method accessible from lambda class access &= ~Opcodes.ACC_PRIVATE; if (allowDefaultMethods && isInterface) { // java 8 requires interface methods to have exactly one of ACC_PUBLIC and ACC_PRIVATE access |= Opcodes.ACC_PUBLIC; } else { // Method was private so it can be final, which should help VMs perform dispatch. access |= Opcodes.ACC_FINAL; } } // Guarantee unique lambda body method name to avoid accidental overriding. This wouldn't be // be necessary for static methods but in visitOuterClass we don't know whether a potential // outer lambda$ method is static or not, so we just always do it. name = uniqueInPackage(internalName, name); } MethodVisitor dest = super.visitMethod(access, name, desc, signature, exceptions); return dest != null ? new InvokedynamicRewriter(dest, access, name, desc, signature, exceptions) : null; }