List of usage examples for org.objectweb.asm Opcodes ACC_VARARGS
int ACC_VARARGS
To view the source code for org.objectweb.asm Opcodes ACC_VARARGS.
Click Source Link
From source file:ca.weblite.asm.JavaExtendedStubCompiler.java
License:Apache License
public Map<String, byte[]> compile(List<Type> types, File sourceFile) throws IOException { final Map<String, byte[]> outMap = new HashMap<>(); final Set<String> typeNames = (types == null) ? null : new HashSet<String>(); if (types != null) { for (Type type : types) { typeNames.add(type.getInternalName()); }//www .j a va 2s.co m } JavaCompiler compiler = JavacTool.create(); MyFileObject[] fos = new MyFileObject[] { new MyFileObject(sourceFile) }; JavacTask task = (JavacTask) compiler.getTask(null, null, null, null, null, Arrays.asList(fos)); Iterable<? extends CompilationUnitTree> asts = task.parse(); TreePathScanner scanner; final LinkedList<ClassFinder> scopeStack = new LinkedList<>(); scanner = new TreePathScanner() { String packageName; ClassNode superClass; LinkedList<String> stack = new LinkedList<>(); LinkedList<ClassInfo> classInfoStack = new LinkedList<>(); LinkedList<ClassWriter> cwStack = new LinkedList<>(); LinkedList<List<? extends TypeParameterTree>> typeParametersStack = new LinkedList<>(); @Override public Object visitCompilationUnit(CompilationUnitTree cut, Object p) { packageName = cut.getPackageName().toString(); ClassFinder scope = new ClassFinder(context.get(ClassLoader.class), null); scopeStack.push(scope); scope.addImport(packageName + ".*"); return super.visitCompilationUnit(cut, p); } private String getThisInternalName(String simpleName) { simpleName = simpleName.replaceAll("\\.", "$"); StringBuilder sb = new StringBuilder(); Iterator<String> it = stack.descendingIterator(); sb.append(packageName.replaceAll("\\.", "/")); sb.append("/"); while (it.hasNext()) { sb.append(it.next()).append("$"); } sb.append(simpleName); return sb.toString(); } @Override public Object visitImport(ImportTree it, Object p) { if (!it.isStatic()) { String path = it.getQualifiedIdentifier().toString(); scopeStack.peek().addImport(path); } return super.visitImport(it, p); } Object visitConstructor(final MethodTree mt, Object p) { ClassWriter classWriter = cwStack.peek(); List<Type> argTypes = new ArrayList<Type>(); boolean isVarArgs = false; for (VariableTree v : mt.getParameters()) { if (v.toString().endsWith("... " + v.getName())) { isVarArgs = true; } String type = v.getType().toString(); String fullType = type; String signature = null; try { signature = TypeUtil.getTypeSignature(type, scopeStack.peek()); } catch (Throwable t) { System.out.println("Failed to find signature for type"); } if (type.indexOf("<") != -1) { type = type.substring(0, type.indexOf("<")); } int dim = 0; if (TypeUtil.isArrayType(type)) { dim = TypeUtil.getArrayTypeDimension(type); type = TypeUtil.getArrayElementType(type); } if (TypeUtil.isPrimitiveType(type)) { String descriptor = TypeUtil.getDescriptor(type); argTypes.add(Type.getType(TypeUtil.getArrayDescriptor(descriptor, dim))); } else { ClassNode stub = scopeStack.peek().findStub(type); assert stub != null; argTypes.add(Type.getObjectType(stub.name)); } } String methodDescriptor = null; String methodSignature = null; if (argTypes.isEmpty()) { methodDescriptor = Type.getMethodDescriptor(Type.getType("V")); } else { methodDescriptor = Type.getMethodDescriptor(Type.getType("V"), argTypes.toArray(new Type[0])); } int flags = getFlags(mt.getModifiers().getFlags()); if (isVarArgs) { flags |= Opcodes.ACC_VARARGS; } classWriter.visitMethod(flags, mt.getName().toString(), methodDescriptor, null, null); classInfoStack.peek().numConstructors++; return null; } @Override public Object visitMethod(MethodTree mt, Object p) { if (mt.getReturnType() == null) { // It's a constructor return visitConstructor(mt, p); } else { boolean isVarArgs = false; ClassWriter classWriter = cwStack.peek(); List<Type> argTypes = new ArrayList<>(); List<String> sigArgTypes = new ArrayList<>(); for (VariableTree v : mt.getParameters()) { String type = v.getType().toString(); if (v.toString().endsWith("... " + v.getName())) { isVarArgs = true; } sigArgTypes.add(type); int dim = 0; if (TypeUtil.isArrayType(type)) { dim = TypeUtil.getArrayTypeDimension(type); type = TypeUtil.getArrayElementType(type); } if (TypeUtil.isPrimitiveType(type)) { String descriptor = TypeUtil.getDescriptor(type); argTypes.add(Type.getType(TypeUtil.getArrayDescriptor(descriptor, dim))); } else { if (isGenericType(type)) { type = "Object"; } int arrowPos = type.indexOf("<"); if (arrowPos != -1) { type = type.substring(0, arrowPos); } ClassNode stub = scopeStack.peek().findStub(type); if (stub == null) { throw new RuntimeException("Could not find class for " + type); } Type argType = Type.getObjectType(stub.name); argType = Type.getType(TypeUtil.getArrayDescriptor(argType.getInternalName(), dim)); argTypes.add(argType); } } String returnType = mt.getReturnType().toString(); if (isGenericType(returnType)) { returnType = "Object"; } String methodSignature = null; try { methodSignature = TypeUtil.getMethodSignature(scopeStack.peek(), returnType, sigArgTypes.toArray(new String[0])); } catch (Exception ex) { System.out.println( "Failed to get signature for method " + mt + " message: " + ex.getMessage()); } int dim = 0; Type returnTypeType = null; if (TypeUtil.isArrayType(returnType)) { dim = TypeUtil.getArrayTypeDimension(returnType); returnType = TypeUtil.getArrayElementType(returnType); if (isGenericType(returnType)) { returnType = "Object"; } } if (TypeUtil.isPrimitiveType(returnType)) { String descriptor = TypeUtil.getDescriptor(returnType); returnTypeType = Type.getType(TypeUtil.getArrayDescriptor(descriptor, dim)); } else { int arrowPos = returnType.indexOf("<"); if (arrowPos != -1) { returnType = returnType.substring(0, arrowPos); } ClassNode stub = scopeStack.peek().findStub(returnType); if (stub == null) { System.out.println("Type params is " + mt.getTypeParameters()); System.out.println("Type kind is " + mt.getReturnType().getKind()); throw new RuntimeException("Could not find class for " + returnType); } returnTypeType = Type.getObjectType(stub.name); returnTypeType = Type .getType(TypeUtil.getArrayDescriptor(returnTypeType.getInternalName(), dim)); } String methodDescriptor = null; if (argTypes.isEmpty()) { methodDescriptor = Type.getMethodDescriptor(returnTypeType); } else { methodDescriptor = Type.getMethodDescriptor(returnTypeType, argTypes.toArray(new Type[0])); } int flags = getFlags(mt.getModifiers().getFlags()); if (isVarArgs) { flags |= Opcodes.ACC_VARARGS; //System.out.println("VarArgs "+flags); } classWriter.visitMethod(flags, mt.getName().toString(), methodDescriptor, methodSignature, null); } //methodStack.push(mt); //Object out= super.visitMethod(mt, p); //methodStack.pop(); return null; } //private boolean LinkedList<MethodTree> methodStack =new LinkedList<>(); @Override public Object visitVariable(VariableTree vt, Object p) { ClassWriter classWriter = cwStack.peek(); String varType = vt.getType().toString(); if (isGenericType(varType)) { varType = "Object"; } String signature = null; try { signature = TypeUtil.getTypeSignature(varType, scopeStack.peek()); } catch (Exception ex) { System.out.println("Failed to generate signature for type " + varType); } int dim = 0; Type varTypeType = null; if (TypeUtil.isArrayType(varType)) { dim = TypeUtil.getArrayTypeDimension(varType); varType = TypeUtil.getArrayElementType(varType); } if (TypeUtil.isPrimitiveType(varType)) { String descriptor = TypeUtil.getDescriptor(varType); varTypeType = Type.getType(TypeUtil.getArrayDescriptor(descriptor, dim)); } else { int arrowPos = varType.indexOf("<"); if (arrowPos != -1) { varType = varType.substring(0, arrowPos); } ClassNode stub = scopeStack.peek().findStub(varType); if (stub == null) { throw new RuntimeException("Could not find class for " + varType); } varTypeType = Type.getObjectType(stub.name); varTypeType = Type.getType(TypeUtil.getArrayDescriptor(varTypeType.getInternalName(), dim)); } classWriter.visitField(getFlags(vt.getModifiers().getFlags()), vt.getName().toString(), varTypeType.toString(), signature, null); return super.visitVariable(vt, p); //To change body of generated methods, choose Tools | Templates. } boolean isGenericType(String type) { for (List<? extends TypeParameterTree> types : typeParametersStack) { for (TypeParameterTree tree : types) { if (type.equals(tree.getName().toString())) { return true; } } } return false; } /** * Converts modifier flags from Javac Tree into int flags usable in * TypeMirror * @param mods * @return */ int getFlags(Set<Modifier> mods) { int flags = 0; for (Modifier m : mods) { switch (m) { case ABSTRACT: flags |= Opcodes.ACC_ABSTRACT; break; case FINAL: flags |= Opcodes.ACC_FINAL; break; case PRIVATE: flags |= Opcodes.ACC_PRIVATE; break; case PROTECTED: flags |= Opcodes.ACC_PROTECTED; break; case PUBLIC: flags |= Opcodes.ACC_PUBLIC; break; case STATIC: flags |= Opcodes.ACC_STATIC; break; } } return flags; } @Override public Object visitClass(ClassTree ct, Object p) { //System.out.println("Visiting class "+ct); //System.out.println("Type parameters: "+ct.getTypeParameters()); typeParametersStack.push(ct.getTypeParameters()); String simpleName = ct.getSimpleName().toString(); String internalName = getThisInternalName(simpleName); int lastDollar = internalName.lastIndexOf("$"); String externalName = lastDollar == -1 ? null : internalName.substring(0, lastDollar); String supername = "java.lang.Object"; String[] interfaces = null; boolean targetClass = false; if (!cwStack.isEmpty()) { cwStack.peek().visitInnerClass(internalName, externalName, simpleName, getFlags(ct.getModifiers().getFlags())); } targetClass = true; // This is the one that we' //String supername = "java.lang.Object"; if (ct.getExtendsClause() != null) { supername = ct.getExtendsClause().toString().trim(); } String unresolvedSuperName = supername; int bracketPos = supername.indexOf("<"); supername = bracketPos == -1 ? supername : supername.substring(0, bracketPos); ClassNode node = scopeStack.peek().findStub(supername); if (node == null) { throw new RuntimeException("Could not find super stub " + supername); } supername = node.name; String impl = ct.getImplementsClause().toString(); String[] unresolvedInterfaces = null; if (impl != null && !"".equals(impl)) { interfaces = impl.split(","); unresolvedInterfaces = new String[interfaces.length]; for (int i = 0; i < interfaces.length; i++) { String iface = interfaces[i]; unresolvedInterfaces[i] = interfaces[i]; iface = iface.trim(); ClassNode inode = scopeStack.peek().findStub(iface); assert inode != null; if (inode == null) { throw new RuntimeException("Could not find stub for interface " + iface); } System.out.println("interface " + iface); interfaces[i] = inode.name; } } String signature = TypeUtil.getClassSignature(scopeStack.peek(), null, unresolvedSuperName, unresolvedInterfaces); int flags = getFlags(ct.getModifiers().getFlags()); switch (ct.getKind()) { case INTERFACE: flags |= Opcodes.ACC_INTERFACE; break; case ENUM: flags |= Opcodes.ACC_ENUM; break; } ClassWriter classWriter = new ClassWriter(49); classWriter.visit(49, flags, internalName, signature, supername, interfaces ); cwStack.push(classWriter); classInfoStack.push(new ClassInfo()); stack.push(simpleName); ClassFinder scope = new ClassFinder(context.get(ClassLoader.class), scopeStack.peek()); scope.addImport(internalName.replaceAll("/", ".").replaceAll("\\$", ".") + ".*" ); scope.addImport(internalName.replaceAll("/", ".").replaceAll("\\$", ".")); scope.addImport(supername.replaceAll("/", ".").replaceAll("\\$", ".") + ".*" ); scope.addImport(supername.replaceAll("/", ".").replaceAll("\\$", ".")); if (interfaces != null) { for (int i = 0; i < interfaces.length; i++) { scope.addImport(interfaces[i].replaceAll("/", ".").replaceAll("\\$", ".") + ".*" ); scope.addImport(interfaces[i].replaceAll("/", ".").replaceAll("\\$", ".")); } } for (TypeParameterTree tpTree : ct.getTypeParameters()) { //System.out.println("Name: "+tpTree.getName()); //System.out.println("Kind: "+tpTree.getKind().name()); //System.out.println("Bounds: "+tpTree.getBounds()); String bounds = (tpTree.getBounds() != null && !tpTree.getBounds().isEmpty()) ? tpTree.getBounds().get(0).toString() : "java.lang.Object"; scope.addTypeParameter(tpTree.getName().toString(), bounds); } scopeStack.push(scope); Object out = super.visitClass(ct, p); stack.pop(); scopeStack.pop(); ClassInfo classInfo = classInfoStack.pop(); if (classInfo.numConstructors == 0) { // there are no declared constructors in this class // we need to add a default constructor. cwStack.peek().visitMethod(Opcodes.ACC_PUBLIC, "<init>", Type.getMethodDescriptor(Type.getType("V")), null, null); classInfo.numConstructors++; } if (targetClass) { byte[] bytes = cwStack.peek().toByteArray(); outMap.put(internalName, bytes); cwStack.pop(); } typeParametersStack.pop(); return out; } }; scanner.scan(asts, null); return outMap; }
From source file:com.android.build.gradle.internal.incremental.IncrementalChangeVisitor.java
License:Apache License
/** * To each class, add the dispatch method called by the original code that acts as a trampoline to * invoke the changed methods./* w ww . j a v a2 s . c om*/ * <p> * Pseudo code: * <code> * Object access$dispatch(String name, object[] args) { * if (name.equals( * "firstMethod.(L$type;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;")) { * return firstMethod(($type)arg[0], (String)arg[1], arg[2]); * } * if (name.equals("secondMethod.(L$type;Ljava/lang/String;I;)V")) { * secondMethod(($type)arg[0], (String)arg[1], (int)arg[2]); * return; * } * ... * StringBuilder $local1 = new StringBuilder(); * $local1.append("Method not found "); * $local1.append(name); * $local1.append(" in " + visitedClassName + * "$dispatch implementation, restart the application"); * throw new $package/InstantReloadException($local1.toString()); * } * </code> */ private void addDispatchMethod() { int access = Opcodes.ACC_PUBLIC | Opcodes.ACC_VARARGS; Method m = new Method("access$dispatch", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;"); MethodVisitor visitor = super.visitMethod(access, m.getName(), m.getDescriptor(), null, null); final GeneratorAdapter mv = new GeneratorAdapter(access, m, visitor); if (TRACING_ENABLED) { mv.push("Redirecting "); mv.loadArg(0); trace(mv, 2); } List<MethodNode> allMethods = new ArrayList<>(); // if we are disabled, do not generate any dispatch, the method will throw an exception // if invoked which should never happen. if (!instantRunDisabled) { //noinspection unchecked allMethods.addAll(classNode.methods); allMethods.addAll(addedMethods); } final Map<String, MethodNode> methods = new HashMap<>(); for (MethodNode methodNode : allMethods) { if (methodNode.name.equals("<clinit>") || methodNode.name.equals("<init>")) { continue; } if (!isAccessCompatibleWithInstantRun(methodNode.access)) { continue; } methods.put(methodNode.name + "." + methodNode.desc, methodNode); } new StringSwitch() { @Override void visitString() { mv.visitVarInsn(Opcodes.ALOAD, 1); } @Override void visitCase(String methodName) { MethodNode methodNode = methods.get(methodName); String name = methodNode.name; boolean isStatic = (methodNode.access & Opcodes.ACC_STATIC) != 0; String newDesc = computeOverrideMethodDesc(methodNode.desc, isStatic); if (TRACING_ENABLED) { trace(mv, "M: " + name + " P:" + newDesc); } Type[] args = Type.getArgumentTypes(newDesc); int argc = 0; for (Type t : args) { mv.visitVarInsn(Opcodes.ALOAD, 2); mv.push(argc); mv.visitInsn(Opcodes.AALOAD); ByteCodeUtils.unbox(mv, t); argc++; } mv.visitMethodInsn(Opcodes.INVOKESTATIC, visitedClassName + "$override", isStatic ? computeOverrideMethodName(name, methodNode.desc) : name, newDesc, false); Type ret = Type.getReturnType(methodNode.desc); if (ret.getSort() == Type.VOID) { mv.visitInsn(Opcodes.ACONST_NULL); } else { mv.box(ret); } mv.visitInsn(Opcodes.ARETURN); } @Override void visitDefault() { writeMissingMessageWithHash(mv, visitedClassName); } }.visit(mv, methods.keySet()); mv.visitMaxs(0, 0); mv.visitEnd(); super.visitEnd(); }
From source file:com.android.build.gradle.internal.incremental.IncrementalSupportVisitor.java
License:Apache License
/*** * Inserts a trampoline to this class so that the updated methods can make calls to super * class methods.// w w w . ja va 2 s .c o m * <p> * Pseudo code for this trampoline: * <code> * Object access$super($classType instance, String name, object[] args) { * switch(name) { * case "firstMethod.(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;": * return super~instance.firstMethod((String)arg[0], arg[1]); * case "secondMethod.(Ljava/lang/String;I)V": * return super~instance.firstMethod((String)arg[0], arg[1]); * * default: * StringBuilder $local1 = new StringBuilder(); * $local1.append("Method not found "); * $local1.append(name); * $local1.append(" in " $classType $super implementation"); * throw new $package/InstantReloadException($local1.toString()); * } * </code> */ private void createAccessSuper() { int access = Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_VARARGS; Method m = new Method("access$super", "(L" + visitedClassName + ";Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;"); MethodVisitor visitor = super.visitMethod(access, m.getName(), m.getDescriptor(), null, null); final GeneratorAdapter mv = new GeneratorAdapter(access, m, visitor); // Gather all methods from itself and its superclasses to generate a giant access$super // implementation. // This will work fine as long as we don't support adding methods to a class. final Map<String, MethodReference> uniqueMethods = new HashMap<>(); if (parentNodes.isEmpty()) { // if we cannot determine the parents for this class, let's blindly add all the // method of the current class as a gateway to a possible parent version. addAllNewMethods(classNode, classNode, uniqueMethods); } else { // otherwise, use the parent list. for (ClassNode parentNode : parentNodes) { addAllNewMethods(classNode, parentNode, uniqueMethods); } } new StringSwitch() { @Override void visitString() { mv.visitVarInsn(Opcodes.ALOAD, 1); } @Override void visitCase(String methodName) { MethodReference methodRef = uniqueMethods.get(methodName); mv.visitVarInsn(Opcodes.ALOAD, 0); Type[] args = Type.getArgumentTypes(methodRef.method.desc); int argc = 0; for (Type t : args) { mv.visitVarInsn(Opcodes.ALOAD, 2); mv.push(argc); mv.visitInsn(Opcodes.AALOAD); ByteCodeUtils.unbox(mv, t); argc++; } if (TRACING_ENABLED) { trace(mv, "super selected ", methodRef.owner.name, methodRef.method.name, methodRef.method.desc); } String parentName = findParentClassForMethod(methodRef); logger.verbose("Generating access$super for %1$s recev %2$s", methodRef.method.name, parentName); // Call super on the other object, yup this works cos we are on the right place to // call from. mv.visitMethodInsn(Opcodes.INVOKESPECIAL, parentName, methodRef.method.name, methodRef.method.desc, false); Type ret = Type.getReturnType(methodRef.method.desc); if (ret.getSort() == Type.VOID) { mv.visitInsn(Opcodes.ACONST_NULL); } else { mv.box(ret); } mv.visitInsn(Opcodes.ARETURN); } @Override void visitDefault() { writeMissingMessageWithHash(mv, visitedClassName); } }.visit(mv, uniqueMethods.keySet()); mv.visitMaxs(0, 0); mv.visitEnd(); }
From source file:com.android.build.gradle.internal2.incremental.IncrementalChangeVisitor.java
License:Apache License
/** * To each class, add the dispatch method called by the original code that acts as a trampoline to * invoke the changed methods./*from www . j av a 2 s . co m*/ * <p> * Pseudo code: * <code> * Object access$dispatch(String name, object[] args) { * if (name.equals( * "firstMethod.(L$type;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;")) { * return firstMethod(($type)arg[0], (String)arg[1], arg[2]); * } * if (name.equals("secondMethod.(L$type;Ljava/lang/String;I;)V")) { * secondMethod(($type)arg[0], (String)arg[1], (int)arg[2]); * return; * } * ... * StringBuilder $local1 = new StringBuilder(); * $local1.append("Method not found "); * $local1.append(name); * $local1.append(" in " + visitedClassName + * "$dispatch implementation, restart the application"); * throw new $package/InstantReloadException($local1.toString()); * } * </code> */ private void addDispatchMethod() { int access = Opcodes.ACC_PUBLIC | Opcodes.ACC_VARARGS; Method m = new Method("access$dispatch", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;"); MethodVisitor visitor = super.visitMethod(access, m.getName(), m.getDescriptor(), null, null); final GeneratorAdapter mv = new GeneratorAdapter(access, m, visitor); if (TRACING_ENABLED) { mv.push("Redirecting "); mv.loadArg(0); trace(mv, 2); } List<MethodNode> allMethods = new ArrayList<>(); // if we are disabled, do not generate any dispatch, the method will throw an exception // if invoked which should never happen. if (!instantRunDisabled) { //noinspection unchecked allMethods.addAll(classNode.methods); allMethods.addAll(addedMethods); } final Map<String, MethodNode> methods = new HashMap<>(); for (MethodNode methodNode : allMethods) { if (methodNode.name.equals(ByteCodeUtils.CLASS_INITIALIZER) || methodNode.name.equals(ByteCodeUtils.CONSTRUCTOR)) { continue; } if (!isAccessCompatibleWithInstantRun(methodNode.access)) { continue; } methods.put(methodNode.name + "." + methodNode.desc, methodNode); } new StringSwitch() { @Override void visitString() { mv.visitVarInsn(Opcodes.ALOAD, 1); } @Override void visitCase(String methodName) { MethodNode methodNode = methods.get(methodName); String name = methodNode.name; boolean isStatic = (methodNode.access & Opcodes.ACC_STATIC) != 0; String newDesc = computeOverrideMethodDesc(methodNode.desc, isStatic); if (TRACING_ENABLED) { trace(mv, "M: " + name + " P:" + newDesc); } Type[] args = Type.getArgumentTypes(newDesc); int argc = 0; for (Type t : args) { mv.visitVarInsn(Opcodes.ALOAD, 2); mv.push(argc); mv.visitInsn(Opcodes.AALOAD); ByteCodeUtils.unbox(mv, t); argc++; } mv.visitMethodInsn(Opcodes.INVOKESTATIC, visitedClassName + "$override", isStatic ? computeOverrideMethodName(name, methodNode.desc) : name, newDesc, false); Type ret = Type.getReturnType(methodNode.desc); if (ret.getSort() == Type.VOID) { mv.visitInsn(Opcodes.ACONST_NULL); } else { mv.box(ret); } mv.visitInsn(Opcodes.ARETURN); } @Override void visitDefault() { writeMissingMessageWithHash(mv, visitedClassName); } }.visit(mv, methods.keySet()); mv.visitMaxs(0, 0); mv.visitEnd(); super.visitEnd(); }
From source file:com.android.build.gradle.internal2.incremental.IncrementalSupportVisitor.java
License:Apache License
/*** * Inserts a trampoline to this class so that the updated methods can make calls to super * class methods.//from w w w . j a va2 s . co m * <p> * Pseudo code for this trampoline: * <code> * Object access$super($classType instance, String name, object[] args) { * switch(name) { * case "firstMethod.(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;": * return super~instance.firstMethod((String)arg[0], arg[1]); * case "secondMethod.(Ljava/lang/String;I)V": * return super~instance.firstMethod((String)arg[0], arg[1]); * * default: * StringBuilder $local1 = new StringBuilder(); * $local1.append("Method not found "); * $local1.append(name); * $local1.append(" in " $classType $super implementation"); * throw new $package/InstantReloadException($local1.toString()); * } * </code> */ private void createAccessSuper() { int access = Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_VARARGS; Method m = new Method("access$super", "(L" + visitedClassName + ";Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;"); MethodVisitor visitor = super.visitMethod(access, m.getName(), m.getDescriptor(), null, null); final GeneratorAdapter mv = new GeneratorAdapter(access, m, visitor); // Gather all methods from itself and its superclasses to generate a giant access$super // implementation. // This will work fine as long as we don't support adding methods to a class. final Map<String, MethodReference> uniqueMethods = new HashMap<>(); if (parentNodes.isEmpty()) { // if we cannot determine the parents for this class, let's blindly add all the // method of the current class as a gateway to a possible parent version. addAllNewMethods(classNode, classNode, uniqueMethods); } else { // otherwise, use the parent list. for (ClassNode parentNode : parentNodes) { addAllNewMethods(classNode, parentNode, uniqueMethods); } } new StringSwitch() { @Override void visitString() { mv.visitVarInsn(Opcodes.ALOAD, 1); } @Override void visitCase(String methodName) { MethodReference methodRef = uniqueMethods.get(methodName); mv.visitVarInsn(Opcodes.ALOAD, 0); Type[] args = Type.getArgumentTypes(methodRef.method.desc); int argc = 0; for (Type t : args) { mv.visitVarInsn(Opcodes.ALOAD, 2); mv.push(argc); mv.visitInsn(Opcodes.AALOAD); ByteCodeUtils.unbox(mv, t); argc++; } if (TRACING_ENABLED) { trace(mv, "super selected ", methodRef.owner.name, methodRef.method.name, methodRef.method.desc); } String parentName = findParentClassForMethod(methodRef); LOG.verbose("Generating access$super for " + methodRef.method.name + " recv " + parentName); // Call super on the other object, yup this works cos we are on the right place to // call from. mv.visitMethodInsn(Opcodes.INVOKESPECIAL, parentName, methodRef.method.name, methodRef.method.desc, false); Type ret = Type.getReturnType(methodRef.method.desc); if (ret.getSort() == Type.VOID) { mv.visitInsn(Opcodes.ACONST_NULL); } else { mv.box(ret); } mv.visitInsn(Opcodes.ARETURN); } @Override void visitDefault() { writeMissingMessageWithHash(mv, visitedClassName); } }.visit(mv, uniqueMethods.keySet()); mv.visitMaxs(0, 0); mv.visitEnd(); }
From source file:com.facebook.buck.jvm.java.abi.AccessFlags.java
License:Apache License
/** * Gets the method access flags (see JVMS8 4.6) for the given executable element, augmented by the * special ASM pseudo-access flag for @Deprecated methods. */// w w w .j a v a 2 s. co m public int getAccessFlags(ExecutableElement executableElement) { int result = getCommonAccessFlags(executableElement); if (executableElement.isVarArgs()) { result = result | Opcodes.ACC_VARARGS; } return result; }
From source file:com.facebook.buck.jvm.java.abi.AccessFlagsTest.java
License:Apache License
@Test public void testVarArgsFlag() throws IOException { compile(Joiner.on('\n').join("class Foo {", " void method(String... s) { }", "}")); assertEquals(Opcodes.ACC_VARARGS, accessFlags.getAccessFlags(findMethod("method", elements.getTypeElement("Foo")))); }
From source file:com.gargoylesoftware.js.nashorn.internal.ir.debug.NashornTextifier.java
License:Open Source License
@Override public NashornTextifier visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) { graph = new Graph(name); final List<Label> extraLabels = cr.getExtraLabels(currentClassName, name, desc); this.labelIter = extraLabels == null ? null : extraLabels.iterator(); final StringBuilder sb = new StringBuilder(); sb.append('\n'); if ((access & Opcodes.ACC_DEPRECATED) != 0) { sb.append(tab).append("// DEPRECATED\n"); }// ww w . j a v a 2 s. c o m sb.append(tab).append("// access flags 0x").append(Integer.toHexString(access).toUpperCase()).append('\n'); if (signature != null) { sb.append(tab); appendDescriptor(sb, METHOD_SIGNATURE, signature); final TraceSignatureVisitor v = new TraceSignatureVisitor(0); final SignatureReader r = new SignatureReader(signature); r.accept(v); final String genericDecl = v.getDeclaration(); final String genericReturn = v.getReturnType(); final String genericExceptions = v.getExceptions(); sb.append(tab).append("// declaration: ").append(genericReturn).append(' ').append(name) .append(genericDecl); if (genericExceptions != null) { sb.append(" throws ").append(genericExceptions); } sb.append('\n'); } sb.append(tab); appendAccess(sb, access); if ((access & Opcodes.ACC_NATIVE) != 0) { sb.append("native "); } if ((access & Opcodes.ACC_VARARGS) != 0) { sb.append("varargs "); } if ((access & Opcodes.ACC_BRIDGE) != 0) { sb.append("bridge "); } sb.append(name); appendDescriptor(sb, METHOD_DESCRIPTOR, desc); if (exceptions != null && exceptions.length > 0) { sb.append(" throws "); for (final String exception : exceptions) { appendDescriptor(sb, INTERNAL_NAME, exception); sb.append(' '); } } sb.append('\n'); addText(sb); final NashornTextifier t = createNashornTextifier(); addText(t.getText()); return t; }
From source file:com.github.jasmo.obfuscate.FullAccessFlags.java
License:Open Source License
private int access(int access) { int a = Opcodes.ACC_PUBLIC; if ((access & Opcodes.ACC_NATIVE) != 0) a |= Opcodes.ACC_NATIVE;/* w ww . j av a 2 s . co m*/ if ((access & Opcodes.ACC_ABSTRACT) != 0) a |= Opcodes.ACC_ABSTRACT; if ((access & Opcodes.ACC_ANNOTATION) != 0) a |= Opcodes.ACC_ANNOTATION; if ((access & Opcodes.ACC_BRIDGE) != 0) a |= Opcodes.ACC_BRIDGE; //if ((access & Opcodes.ACC_DEPRECATED) != 0) a |= Opcodes.ACC_DEPRECATED; if ((access & Opcodes.ACC_ENUM) != 0) a |= Opcodes.ACC_ENUM; if ((access & Opcodes.ACC_FINAL) != 0) a |= Opcodes.ACC_FINAL; if ((access & Opcodes.ACC_INTERFACE) != 0) a |= Opcodes.ACC_INTERFACE; if ((access & Opcodes.ACC_MANDATED) != 0) a |= Opcodes.ACC_MANDATED; if ((access & Opcodes.ACC_MODULE) != 0) a |= Opcodes.ACC_MODULE; if ((access & Opcodes.ACC_OPEN) != 0) a |= Opcodes.ACC_OPEN; if ((access & Opcodes.ACC_STATIC) != 0) a |= Opcodes.ACC_STATIC; if ((access & Opcodes.ACC_STATIC_PHASE) != 0) a |= Opcodes.ACC_STATIC_PHASE; if ((access & Opcodes.ACC_STRICT) != 0) a |= Opcodes.ACC_STRICT; if ((access & Opcodes.ACC_SUPER) != 0) a |= Opcodes.ACC_SUPER; if ((access & Opcodes.ACC_SYNCHRONIZED) != 0) a |= Opcodes.ACC_SYNCHRONIZED; if ((access & Opcodes.ACC_SYNTHETIC) != 0) a |= Opcodes.ACC_SYNTHETIC; if ((access & Opcodes.ACC_TRANSIENT) != 0) a |= Opcodes.ACC_TRANSIENT; if ((access & Opcodes.ACC_TRANSITIVE) != 0) a |= Opcodes.ACC_TRANSITIVE; if ((access & Opcodes.ACC_VARARGS) != 0) a |= Opcodes.ACC_VARARGS; if ((access & Opcodes.ACC_VOLATILE) != 0) a |= Opcodes.ACC_VOLATILE; return a; }
From source file:com.google.gwt.dev.javac.CompilationUnitTypeOracleUpdater.java
License:Apache License
private boolean resolveMethod(TreeLogger logger, JRealClassType unresolvedType, CollectMethodData methodData, TypeParameterLookup typeParamLookup, TypeOracleBuildContext context) { Map<Class<? extends Annotation>, Annotation> declaredAnnotations = Maps.newHashMap(); resolveAnnotations(logger, methodData.getAnnotations(), declaredAnnotations); String name = methodData.getName(); if ("<clinit>".equals(name) || (methodData.getAccess() & Opcodes.ACC_SYNTHETIC) != 0) { // Ignore the following and leave them out of TypeOracle: // - static initializers // - synthetic methods return true; }//from w w w .j av a2s . co m if (unresolvedType.isEnum() != null && "<init>".equals(name)) { // Leave enum constructors out of TypeOracle return true; } JAbstractMethod method; // Declare the type parameters. We will pass them into the constructors for // JConstructor/JMethod/JAnnotatedMethod. Then, we'll do a second pass to // resolve the bounds on each JTypeParameter object. JTypeParameter[] typeParams = collectTypeParams(methodData.getSignature()); typeParamLookup.pushScope(typeParams); boolean hasReturnType = true; if ("<init>".equals(name)) { name = unresolvedType.getSimpleSourceName(); method = newConstructor(unresolvedType, name, declaredAnnotations, typeParams); hasReturnType = false; } else { if (unresolvedType.isAnnotation() != null) { // TODO(jat): actually resolve the default annotation value. method = newAnnotationMethod(unresolvedType, name, declaredAnnotations, typeParams, null); } else { method = newMethod(unresolvedType, name, declaredAnnotations, typeParams); } } addModifierBits(method, mapBits(ASM_TO_SHARED_MODIFIERS, methodData.getAccess())); if (unresolvedType.isInterface() != null) { // Always add implicit modifiers on interface methods. addModifierBits(method, Shared.MOD_PUBLIC | Shared.MOD_ABSTRACT); } if ((methodData.getAccess() & Opcodes.ACC_VARARGS) != 0) { setVarArgs(method); } String signature = methodData.getSignature(); if (signature != null) { // If we have a signature, use it for superclass and interfaces SignatureReader reader = new SignatureReader(signature); ResolveMethodSignature methodResolver = new ResolveMethodSignature(context.resolver, logger, method, typeParamLookup, hasReturnType, methodData, methodData.getArgTypes(), methodData.getArgNames(), methodData.hasActualArgNames(), context.allMethodArgs); reader.accept(methodResolver); if (!methodResolver.finish()) { logger.log(TreeLogger.ERROR, "Failed to resolve."); return false; } } else { if (hasReturnType) { Type returnType = Type.getReturnType(methodData.getDesc()); JType returnJType = resolveType(returnType); if (returnJType == null) { logger.log(TreeLogger.ERROR, "Unable to resolve return type " + returnType.getInternalName()); return false; } setReturnType(method, returnJType); } if (!resolveParameters(logger, method, methodData, context)) { // Already logged. return false; } } // The signature might not actually include the exceptions if they don't // include a type variable, so resolveThrows is always used (it does // nothing if there are already exceptions defined) if (!resolveThrows(logger, method, methodData)) { // Already logged. return false; } typeParamLookup.popScope(); return true; }