List of usage examples for org.objectweb.asm Type getReturnType
public Type getReturnType()
From source file:cn.annoreg.asm.DelegateGenerator.java
License:Open Source License
public static MethodVisitor generateNonStaticMethod(ClassVisitor parentClass, MethodVisitor parent, String className, String methodName, String desc, final Side side) { //convert desc to a non-static method form String nonstaticDesc;//from ww w. ja va2 s.c o m { Type staticType = Type.getMethodType(desc); Type retType = staticType.getReturnType(); Type[] argsType = staticType.getArgumentTypes(); Type[] argsTypeWithThis = new Type[argsType.length + 1]; argsTypeWithThis[0] = Type.getType('L' + className.replace('.', '/') + ';'); System.arraycopy(argsType, 0, argsTypeWithThis, 1, argsType.length); nonstaticDesc = Type.getMethodDescriptor(retType, argsTypeWithThis); } //delegateName is a string used by both sides to identify a network-call delegate. final String delegateName = className + ":" + methodName + ":" + desc; final Type[] args = Type.getArgumentTypes(nonstaticDesc); final Type ret = Type.getReturnType(nonstaticDesc); //Check types for (Type t : args) { //TODO support these types if (!t.getDescriptor().startsWith("L") && !t.getDescriptor().startsWith("[")) { throw new RuntimeException("Unsupported argument type in network call. "); } } if (!ret.equals(Type.VOID_TYPE)) { throw new RuntimeException( "Unsupported return value type in network call. " + "Only void is supported."); } //Generate call to NetworkCallManager in parent. parent.visitCode(); //First parameter parent.visitLdcInsn(delegateName); //Second parameter: object array pushIntegerConst(parent, args.length); //this (0) has been included parent.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object"); for (int i = 0; i < args.length; ++i) { parent.visitInsn(Opcodes.DUP); pushIntegerConst(parent, i); parent.visitVarInsn(Opcodes.ALOAD, i); parent.visitInsn(Opcodes.AASTORE); } //Call cn.annoreg.mc.network.NetworkCallManager.onNetworkCall parent.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(NetworkCallManager.class), "onNetworkCall", "(Ljava/lang/String;[Ljava/lang/Object;)V"); parent.visitInsn(Opcodes.RETURN); parent.visitMaxs(5, args.length); parent.visitEnd(); //Create delegate object. final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); final String delegateId = Integer.toString(delegateNextID++); final Type delegateClassType = Type.getType("cn/annoreg/asm/NetworkCallDelegate_" + delegateId); cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, delegateClassType.getInternalName(), null, Type.getInternalName(Object.class), new String[] { Type.getInternalName(NetworkCallDelegate.class) }); //package cn.annoreg.asm; //class NetworkCallDelegate_? implements NetworkCallDelegate { { MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), "<init>", "()V"); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } //public NetworkCallDelegate_?() {} final String delegateMethodName = methodName + "_delegate_" + delegateId; { MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "invoke", Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(Object[].class)), null, null); mv.visitCode(); //check if this is null mv.visitVarInsn(Opcodes.ALOAD, 1); //0 is this pushIntegerConst(mv, 0); mv.visitInsn(Opcodes.AALOAD); Label lblEnd = new Label(); mv.visitJumpInsn(Opcodes.IFNULL, lblEnd); for (int i = 0; i < args.length; ++i) { mv.visitVarInsn(Opcodes.ALOAD, 1); //0 is this pushIntegerConst(mv, i); mv.visitInsn(Opcodes.AALOAD); mv.visitTypeInsn(Opcodes.CHECKCAST, args[i].getInternalName()); } mv.visitMethodInsn(Opcodes.INVOKESTATIC, //delegateClassType.getInternalName(), className.replace('.', '/'), delegateMethodName, nonstaticDesc); mv.visitLabel(lblEnd); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(args.length + 2, 2); mv.visitEnd(); } //@Override public void invoke(Object[] args) { // delegated((Type0) args[0], (Type1) args[1], ...); //} //The returned MethodVisitor will visit the original version of the method, //including its annotation, where we can get StorageOptions. return new MethodVisitor(Opcodes.ASM4, parentClass.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, delegateMethodName, nonstaticDesc, null, null)) { //Remember storage options for each argument StorageOption.Option[] options = new StorageOption.Option[args.length]; int targetIndex = -1; double sendRange = -1; StorageOption.Target.RangeOption range = StorageOption.Target.RangeOption.SINGLE; { for (int i = 0; i < options.length; ++i) { options[i] = StorageOption.Option.NULL; //set default value } options[0] = StorageOption.Option.INSTANCE; } @Override public AnnotationVisitor visitParameterAnnotation(int parameter_in_func, String desc, boolean visible) { final int parameter = parameter_in_func + 1; //skip this Type type = Type.getType(desc); if (type.equals(Type.getType(StorageOption.Data.class))) { options[parameter] = StorageOption.Option.DATA; } else if (type.equals(Type.getType(StorageOption.Instance.class))) { //INSTANCE as defualt options[parameter] = StorageOption.Option.INSTANCE; //Change to NULLABLE_INSTANCE if nullable set to true return new AnnotationVisitor(this.api, super.visitParameterAnnotation(parameter, desc, visible)) { @Override public void visit(String name, Object value) { if (name.equals("nullable")) { if ((Boolean) value == true) { options[parameter] = StorageOption.Option.NULLABLE_INSTANCE; } } super.visit(name, value); } }; } else if (type.equals(Type.getType(StorageOption.Update.class))) { options[parameter] = StorageOption.Option.UPDATE; } else if (type.equals(Type.getType(StorageOption.Null.class))) { options[parameter] = StorageOption.Option.NULL; } else if (type.equals(Type.getType(StorageOption.Target.class))) { if (!args[parameter].equals(Type.getType(EntityPlayer.class))) { throw new RuntimeException("Target annotation can only be used on EntityPlayer."); } if (targetIndex != -1) { throw new RuntimeException("You can not specify multiple targets."); } options[parameter] = StorageOption.Option.INSTANCE; targetIndex = parameter; return new AnnotationVisitor(this.api, super.visitParameterAnnotation(parameter, desc, visible)) { @Override public void visitEnum(String name, String desc, String value) { super.visitEnum(name, desc, value); range = StorageOption.Target.RangeOption.valueOf(value); } }; } else if (type.equals(Type.getType(StorageOption.RangedTarget.class))) { if (targetIndex != -1) { throw new RuntimeException("You can not specify multiple targets."); } targetIndex = parameter; range = null; return new AnnotationVisitor(this.api, super.visitParameterAnnotation(parameter, desc, visible)) { @Override public void visit(String name, Object value) { super.visit(name, value); sendRange = (double) value; } }; } return super.visitParameterAnnotation(parameter, desc, visible); } //TODO this option (from annotation) @Override public void visitEnd() { super.visitEnd(); //This is the last method in the delegate class. //Finish the class and do the registration. cw.visitEnd(); try { Class<?> clazz = classLoader.defineClass(delegateClassType.getClassName(), cw.toByteArray()); NetworkCallDelegate delegateObj = (NetworkCallDelegate) clazz.newInstance(); if (side == Side.CLIENT) { NetworkCallManager.registerClientDelegateClass(delegateName, delegateObj, options, targetIndex, range, sendRange); } else { NetworkCallManager.registerServerDelegateClass(delegateName, delegateObj, options); } } catch (Throwable e) { throw new RuntimeException("Can not create delegate for network call.", e); } } }; //public static void delegated(Type0 arg0, Type1, arg1, ...) { // //Code generated by caller. //} //} }
From source file:com.android.builder.shrinker.DependencyFinderVisitor.java
License:Apache License
@Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { T method = mGraph.getMemberReference(mClassName, name, desc); if ((access & Opcodes.ACC_STATIC) == 0 && !name.equals(AsmUtils.CONSTRUCTOR) && mVirtualMethods != null) { mVirtualMethods.add(method);/*from w ww . j a va 2 s . c om*/ } Type methodType = Type.getMethodType(desc); handleDeclarationType(method, methodType.getReturnType()); for (Type argType : methodType.getArgumentTypes()) { handleDeclarationType(method, argType); } if (name.equals(AsmUtils.CLASS_INITIALIZER)) { handleDependency(mKlass, method, DependencyType.REQUIRED); } if (mIsAnnotation) { // TODO: Strip annotation members. handleDependency(mKlass, method, DependencyType.REQUIRED); } if (signature != null) { handleClassSignature(method, signature); } return new DependencyFinderMethodVisitor(method, super.visitMethod(access, name, desc, signature, exceptions)); }
From source file:com.devexperts.usages.ClassUsagesAnalyzer.java
License:Open Source License
private void markTypeUse(Type type, Member usedFrom, UseKind useKind) { if (type.getSort() == Type.METHOD) { markTypeUse(type.getReturnType(), usedFrom, UseKind.RETURN); for (Type arg : type.getArgumentTypes()) markTypeUse(arg, usedFrom, UseKind.ARGUMENT); return;//from www . j a v a 2s. co m } while (type.getSort() == Type.ARRAY) type = type.getElementType(); if (type.getSort() == Type.OBJECT) makeTypeUse(type.getClassName(), usedFrom, useKind); }
From source file:com.facebook.buck.jvm.java.abi.ClassReferenceTracker.java
License:Apache License
private void visitType(Type type) { switch (type.getSort()) { case Type.ARRAY: visitType(type.getElementType()); break;/* w w w .java 2 s. c o m*/ case Type.METHOD: visitType(type.getReturnType()); visitTypes(type.getArgumentTypes()); break; case Type.OBJECT: addReferencedClassName(type.getInternalName()); break; // $CASES-OMITTED default: // Others are primitives or void; don't care break; } }
From source file:com.gargoylesoftware.js.nashorn.internal.runtime.linker.JavaAdapterBytecodeGenerator.java
License:Open Source License
private void generateDelegatingConstructor(final Constructor<?> ctor) { final Type originalCtorType = Type.getType(ctor); final Type[] argTypes = originalCtorType.getArgumentTypes(); // All constructors must be public, even if in the superclass they were protected. final InstructionAdapter mv = new InstructionAdapter( cw.visitMethod(ACC_PUBLIC | (ctor.isVarArgs() ? ACC_VARARGS : 0), INIT, Type.getMethodDescriptor(originalCtorType.getReturnType(), argTypes), null, null)); mv.visitCode();//from w w w . jav a 2s . c o m // Invoke super constructor with the same arguments. mv.visitVarInsn(ALOAD, 0); int offset = 1; // First arg is at position 1, after this. for (final Type argType : argTypes) { mv.load(offset, argType); offset += argType.getSize(); } mv.invokespecial(superClassName, INIT, originalCtorType.getDescriptor(), false); endInitMethod(mv); }
From source file:com.gargoylesoftware.js.nashorn.internal.runtime.linker.JavaAdapterBytecodeGenerator.java
License:Open Source License
/** * Generates a constructor for the instance adapter class. This constructor will take the same arguments as the supertype * constructor passed as the argument here, and delegate to it. However, it will take an additional argument of * either ScriptObject or ScriptFunction type (based on the value of the "fromFunction" parameter), and initialize * all the method handle fields of the adapter instance with functions from the script object (or the script * function itself, if that's what's passed). There is one method handle field in the adapter class for every method * that can be implemented or overridden; the name of every field is same as the name of the method, with a number * suffix that makes it unique in case of overloaded methods. The generated constructor will invoke * {@link #getHandle(ScriptFunction, MethodType, boolean)} or {@link #getHandle(Object, String, MethodType, * boolean)} to obtain the method handles; these methods make sure to add the necessary conversions and arity * adjustments so that the resulting method handles can be invoked from generated methods using {@code invokeExact}. * The constructor that takes a script function will only initialize the methods with the same name as the single * abstract method. The constructor will also store the Nashorn global that was current at the constructor * invocation time in a field named "global". The generated constructor will be public, regardless of whether the * supertype constructor was public or protected. The generated constructor will not be variable arity, even if the * supertype constructor was./*from ww w . ja v a2 s. co m*/ * @param ctor the supertype constructor that is serving as the base for the generated constructor. * @param fromFunction true if we're generating a constructor that initializes SAM types from a single * ScriptFunction passed to it, false if we're generating a constructor that initializes an arbitrary type from a * ScriptObject passed to it. */ private void generateOverridingConstructor(final Constructor<?> ctor, final boolean fromFunction) { final Type originalCtorType = Type.getType(ctor); final Type[] originalArgTypes = originalCtorType.getArgumentTypes(); final int argLen = originalArgTypes.length; final Type[] newArgTypes = new Type[argLen + 1]; // Insert ScriptFunction|ScriptObject as the last argument to the constructor final Type extraArgumentType = fromFunction ? SCRIPT_FUNCTION_TYPE : SCRIPT_OBJECT_TYPE; newArgTypes[argLen] = extraArgumentType; System.arraycopy(originalArgTypes, 0, newArgTypes, 0, argLen); // All constructors must be public, even if in the superclass they were protected. // Existing super constructor <init>(this, args...) triggers generating <init>(this, args..., scriptObj). // Any variable arity constructors become fixed-arity with explicit array arguments. final InstructionAdapter mv = new InstructionAdapter(cw.visitMethod(ACC_PUBLIC, INIT, Type.getMethodDescriptor(originalCtorType.getReturnType(), newArgTypes), null, null)); mv.visitCode(); // First, invoke super constructor with original arguments. If the form of the constructor we're generating is // <init>(this, args..., scriptFn), then we're invoking super.<init>(this, args...). mv.visitVarInsn(ALOAD, 0); final Class<?>[] argTypes = ctor.getParameterTypes(); int offset = 1; // First arg is at position 1, after this. for (int i = 0; i < argLen; ++i) { final Type argType = Type.getType(argTypes[i]); mv.load(offset, argType); offset += argType.getSize(); } mv.invokespecial(superClassName, INIT, originalCtorType.getDescriptor(), false); // Get a descriptor to the appropriate "JavaAdapterFactory.getHandle" method. final String getHandleDescriptor = fromFunction ? GET_HANDLE_FUNCTION_DESCRIPTOR : GET_HANDLE_OBJECT_DESCRIPTOR; // Assign MethodHandle fields through invoking getHandle() for (final MethodInfo mi : methodInfos) { mv.visitVarInsn(ALOAD, 0); if (fromFunction && !mi.getName().equals(samName)) { // Constructors initializing from a ScriptFunction only initialize methods with the SAM name. // NOTE: if there's a concrete overloaded method sharing the SAM name, it'll be overridden too. This // is a deliberate design choice. All other method handles are initialized to null. mv.visitInsn(ACONST_NULL); } else { mv.visitVarInsn(ALOAD, offset); if (!fromFunction) { mv.aconst(mi.getName()); } loadMethodTypeAndGetHandle(mv, mi, getHandleDescriptor); } mv.putfield(generatedClassName, mi.methodHandleFieldName, METHOD_HANDLE_TYPE_DESCRIPTOR); } // Assign "this.global = Context.getGlobal()" mv.visitVarInsn(ALOAD, 0); invokeGetGlobalWithNullCheck(mv); mv.putfield(generatedClassName, GLOBAL_FIELD_NAME, GLOBAL_TYPE_DESCRIPTOR); // Initialize converters generateConverterInit(mv, fromFunction); endInitMethod(mv); if (!fromFunction) { newArgTypes[argLen] = OBJECT_TYPE; final InstructionAdapter mv2 = new InstructionAdapter(cw.visitMethod(ACC_PUBLIC, INIT, Type.getMethodDescriptor(originalCtorType.getReturnType(), newArgTypes), null, null)); generateOverridingConstructorWithObjectParam(mv2, ctor, originalCtorType.getDescriptor()); } }
From source file:com.gargoylesoftware.js.nashorn.internal.runtime.linker.JavaAdapterBytecodeGenerator.java
License:Open Source License
private void emitSuperCall(final InstructionAdapter mv, final Class<?> owner, final String name, final String methodDesc) { mv.visitVarInsn(ALOAD, 0);//from w w w . j a va 2 s. co m int nextParam = 1; final Type methodType = Type.getMethodType(methodDesc); for (final Type t : methodType.getArgumentTypes()) { mv.load(nextParam, t); nextParam += t.getSize(); } // default method - non-abstract, interface method if (Modifier.isInterface(owner.getModifiers())) { // we should call default method on the immediate "super" type - not on (possibly) // the indirectly inherited interface class! mv.invokespecial(Type.getInternalName(findInvokespecialOwnerFor(owner)), name, methodDesc, false); } else { mv.invokespecial(superClassName, name, methodDesc, false); } mv.areturn(methodType.getReturnType()); }
From source file:com.github.veithen.phos.enforcer.ReferenceProcessor.java
License:Apache License
public void processType(Type type, boolean isPublic) { switch (type.getSort()) { case Type.OBJECT: referenceCollector.collectClassReference(new Reference<Clazz>(origin, new Clazz(type.getClassName())), this.isPublic && isPublic); break;//from w w w .j av a2s .co m case Type.ARRAY: processType(type.getElementType(), isPublic); break; case Type.METHOD: processType(type.getReturnType(), isPublic); for (Type argumentType : type.getArgumentTypes()) { processType(argumentType, isPublic); } } }
From source file:com.gmail.socraticphoenix.nebula.event.wrappers.BytecodeEventListenerGeneration.java
License:Open Source License
public static void get(Get get, Parameter parameter, Class eventClass, int param, int event, MethodVisitor visitor) {//from ww w . java2 s . com try { String name = EventListenerWrapper.name(get, parameter, eventClass).get(); Type eventType = Type.getType(eventClass); Method rMethod = eventClass.getMethod(name); Type method = Type.getType(rMethod); Type type = Type.getType(parameter.getType()); visitor.visitVarInsn(ALOAD, event); if (eventClass.isInterface()) { visitor.visitMethodInsn(INVOKEINTERFACE, eventType.getInternalName(), name, method.getDescriptor(), true); } else { visitor.visitMethodInsn(INVOKEVIRTUAL, eventType.getInternalName(), name, method.getDescriptor(), false); } if (get.nonnull() && method.getReturnType().getDescriptor().startsWith("L")) { Label continueLabel = new Label(); visitor.visitInsn(DUP); visitor.visitJumpInsn(IFNONNULL, continueLabel); visitor.visitInsn(RETURN); visitor.visitLabel(continueLabel); visitor.visitVarInsn(ASTORE, param); } else { if (!method.getReturnType().getDescriptor().startsWith("L")) { Type boxing = Type.getType(Reflections.boxingType(rMethod.getReturnType())); visitor.visitTypeInsn(NEW, boxing.getInternalName()); visitor.visitInsn(DUP_X1); visitor.visitInsn(SWAP); visitor.visitMethodInsn(INVOKESPECIAL, boxing.getInternalName(), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, method.getReturnType()), false); } visitor.visitVarInsn(ASTORE, param); } } catch (NoSuchMethodException e) { //Meh } }
From source file:com.gmail.socraticphoenix.occurence.wrappers.BytecodeEventListenerGeneration.java
License:Open Source License
public static void get(Get get, Parameter parameter, Class eventClass, int param, int event, MethodVisitor visitor) {// w w w.ja v a 2 s .c o m try { String name = EventListenerWrapper.name(get, parameter, eventClass).get(); Type eventType = Type.getType(eventClass); Method rMethod = eventClass.getMethod(name); Type method = Type.getType(rMethod); visitor.visitVarInsn(ALOAD, event); if (eventClass.isInterface()) { visitor.visitMethodInsn(INVOKEINTERFACE, eventType.getInternalName(), name, method.getDescriptor(), true); } else { visitor.visitMethodInsn(INVOKEVIRTUAL, eventType.getInternalName(), name, method.getDescriptor(), false); } if (get.nonnull() && method.getReturnType().getDescriptor().startsWith("L")) { Label continueLabel = new Label(); visitor.visitInsn(DUP); visitor.visitJumpInsn(IFNONNULL, continueLabel); visitor.visitInsn(RETURN); visitor.visitLabel(continueLabel); visitor.visitVarInsn(ASTORE, param); } else { if (!method.getReturnType().getDescriptor().startsWith("L")) { Type boxing = Type.getType(Reflections.boxingType(rMethod.getReturnType())); visitor.visitTypeInsn(NEW, boxing.getInternalName()); visitor.visitInsn(DUP_X1); visitor.visitInsn(SWAP); visitor.visitMethodInsn(INVOKESPECIAL, boxing.getInternalName(), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, method.getReturnType()), false); } visitor.visitVarInsn(ASTORE, param); } } catch (NoSuchMethodException e) { //Meh } }