@SuppressWarnings("unused") protected void onMethodEnter() { if (done) return; overridden = true; Label start = new Label(); Label normal = new Label(); super.visitLabel(start); super.visitFieldInsn(Opcodes.GETSTATIC, CONFIGURATION, CONFIGURATION_FIELD_NAME, Type.INT_TYPE.getDescriptor()); super.visitInsn(Opcodes.DUP); super.visitJumpInsn(Opcodes.IFEQ, normal); super.visitInsn(Opcodes.IRETURN); super.visitLabel(normal); super.visitInsn(Opcodes.POP); Label end = new Label(); super.visitJumpInsn(Opcodes.GOTO, end); super.visitLabel(end); super.visitTryCatchBlock(start, normal, end, Type.getType(Throwable.class).getDescriptor()); }
/** * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a * MethodHandle of kind invoke interface. The target method is a default method into an interface * that is at the end of a chain of interfaces. */ private void generateMethodTest6(ClassVisitor cv) { MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test6", "()V", null, null); MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, MethodHandle.class); Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "bsmCreateCallCallingtargetMethodTest7", mt.toMethodDescriptorString(), false); mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class)); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn( Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false); mv.visitInvokeDynamicInsn("targetMethodTest7", "(Linvokecustom/J;)V", bootstrap, new Handle(Opcodes.H_INVOKEINTERFACE, Type.getInternalName(J.class), "targetMethodTest7", "()V", true)); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(-1, -1); }
private boolean checkAnnotation(AnnotationNode a) { if (a.desc.equals("Lcom/rakuten/tech/mobile/perf/core/annotations/Exists;")) { if (!exists(((Type) a.values.get(1)).getClassName())) { return false; } } else if (a.desc .equals("Lcom/rakuten/tech/mobile/perf/core/annotations/MinCompileSdkVersion;")) { if (_compileSdkVersion < (int) a.values.get(1)) { return false; } } else if (a.desc .equals("Lcom/rakuten/tech/mobile/perf/core/annotations/MaxCompileSdkVersion;")) { if (_compileSdkVersion > (int) a.values.get(1)) { return false; } } return true; }
/** * (none-javadoc) * * @see com.fuxi.javaagent.hook.AbstractClassHook#hookMethod(int, String, String, String, String[], MethodVisitor) (String) */ @Override protected MethodVisitor hookMethod(int access, String name, String desc, String signature, String[] exceptions, MethodVisitor mv) { if ("resolveClass".equals(name) && "(Ljava/io/ObjectStreamClass;)Ljava/lang/Class;".equals(desc)) { return new AdviceAdapter(Opcodes.ASM5, mv, access, name, desc) { @Override protected void onMethodEnter() { loadArg(0); invokeStatic(Type.getType(DeserializationHook.class), new Method("checkDeserializationClass", "(Ljava/io/ObjectStreamClass;)V")); } }; } return mv; }
public void putMethod(MethodRef a, MethodRef b) { Method descriptor = new Method(b.getMethodName(), b.getMethodDesc()); TypeNameEnforcer returnType = new TypeNameEnforcer(descriptor.getReturnType() .getClassName()); if (classMappings.containsKey(returnType.getJvmStandard())) { returnType = new TypeNameEnforcer(classMappings.get(returnType.getJvmStandard())); } List<TypeNameEnforcer> parameterTypes = new ArrayList<>(); for (Type type : descriptor.getArgumentTypes()) { if (classMappings.containsKey(new TypeNameEnforcer(type.getClassName()).getJvmStandard())) { parameterTypes.add(new TypeNameEnforcer(classMappings.get(new TypeNameEnforcer (type.getClassName()).getJvmStandard()))); } else { parameterTypes.add(new TypeNameEnforcer(type.getClassName())); } } MethodRef newB = new MethodRef(b.getClassName(), b.getMethodName(), createDescriptor (returnType, parameterTypes)); methodMappings.put(a, newB); }
@Override public MethodTransformer[] getMethodTransformers() { MethodTransformer loadWorldTransformer = new MethodTransformer() { public String getMethodName() {return CoreLoader.isObfuscated ? "a" : "loadWorld";} public String getDescName() {return "(L" + (CoreLoader.isObfuscated ? "bnq" : Type.getInternalName(WorldClient.class)) + ";Ljava/lang/String;)V";} public void transform(ClassNode classNode, MethodNode method, boolean obfuscated) { CLTLog.info("Found method: " + method.name + " " + method.desc); CLTLog.info("begining at start of method " + getMethodName()); //TransformerUtil.onWorldLoad(WorldClient worldClientIn) InsnList toInsert = new InsnList(); toInsert.add(new VarInsnNode(ALOAD, 1)); //worldClientIn toInsert.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(TransformerUtil.class), "onWorldLoad", "(L" + Type.getInternalName(WorldClient.class) + ";)V", false)); method.instructions.insertBefore(method.instructions.getFirst(), toInsert); } }; return new MethodTransformer[] {loadWorldTransformer}; }
private void unboxType(MethodVisitor methodVisitor, Class<?> primitiveClass) { // Float f = (Float) tmp // f==null?0:f.floatValue() Class<?> boxedType = BOXED_TYPES.get(primitiveClass); Type primitiveType = Type.getType(primitiveClass); methodVisitor.visitTypeInsn(CHECKCAST, Type.getInternalName(boxedType)); methodVisitor.visitInsn(DUP); Label exit = new Label(); Label elseValue = new Label(); methodVisitor.visitJumpInsn(IFNONNULL, elseValue); methodVisitor.visitInsn(POP); pushDefaultValue(methodVisitor, primitiveClass); methodVisitor.visitJumpInsn(GOTO, exit); methodVisitor.visitLabel(elseValue); methodVisitor.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(boxedType), primitiveClass.getSimpleName() + "Value", Type.getMethodDescriptor(primitiveType), false); methodVisitor.visitLabel(exit); }
@Override public void visit(Branch.Condition.NumLoopEnd cond) { assert (destLabel != null); il.add(new VarInsnNode(ALOAD, slot(cond.var()))); il.add(new TypeInsnNode(CHECKCAST, Type.getInternalName(Number.class))); il.add(new VarInsnNode(ALOAD, slot(cond.limit()))); il.add(new TypeInsnNode(CHECKCAST, Type.getInternalName(Number.class))); il.add(new VarInsnNode(ALOAD, slot(cond.step()))); il.add(new TypeInsnNode(CHECKCAST, Type.getInternalName(Number.class))); il.add(DispatchMethods.continueLoop()); if (!isSub() || resolver.isLocalLabel(destLabel)) { // local jump il.add(new JumpInsnNode(IFEQ, l(destLabel))); } else { // non-local jump LabelNode l_nojump = new LabelNode(); il.add(new JumpInsnNode(IFNE, l_nojump)); il.add(_nonLocalGoto(destLabel)); il.add(l_nojump); il.add(new FrameNode(F_SAME, 0, null, 0, null)); } }
@Override public void visitTypeInsn(final int opcode, final String type) { Type t = Type.getObjectType(type); switch (opcode) { case Opcodes.NEW: anew(t); break; case Opcodes.ANEWARRAY: newarray(t); break; case Opcodes.CHECKCAST: checkcast(t); break; case Opcodes.INSTANCEOF: instanceOf(t); break; default: throw new IllegalArgumentException(); } }
/** * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a * MethodHandle of kind invoke interface. The target method is a method into an interface * that is shadowed by another definition into a sub interfaces. */ private void generateMethodTest7(ClassVisitor cv) { MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test7", "()V", null, null); MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, MethodHandle.class); Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "bsmCreateCallCallingtargetMethodTest8", mt.toMethodDescriptorString(), false); mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class)); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn( Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false); mv.visitInvokeDynamicInsn("targetMethodTest8", "(Linvokecustom/J;)V", bootstrap, new Handle(Opcodes.H_INVOKEINTERFACE, Type.getInternalName(J.class), "targetMethodTest8", "()V", true)); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(-1, -1); }
@Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append(String.format("CLASS[states=%d]{", className.getStateCount())); Iterator<State> it = Arrays.asList(State.values()).iterator(); boolean needsSeparator = false; while(it.hasNext()) { State next = it.next(); Type type = className.getByState(next); if(type != null) { if(needsSeparator) builder.append(","); builder.append(next.name()); builder.append("="); builder.append(type.getInternalName()); needsSeparator = true; } } builder.append("}"); return builder.toString(); }
@Override protected boolean isSubTypeOf(final BasicValue value, final BasicValue expected) { Type expectedType = expected.getType(); Type type = value.getType(); switch (expectedType.getSort()) { case Type.INT: case Type.FLOAT: case Type.LONG: case Type.DOUBLE: return type.equals(expectedType); case Type.ARRAY: case Type.OBJECT: if ("Lnull;".equals(type.getDescriptor())) { return true; } else if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) { return isAssignableFrom(expectedType, type); } else { return false; } default: throw new Error("Internal error"); } }
private void boxParameterAndLoad(int argIndex) { Type type = argTypes[argIndex]; int stackIndex = getStackIndex(argIndex); switch (type.getSort()) { case Type.OBJECT: //no need to box Object aa.visitVarInsn(ALOAD, stackIndex); break; default: // aa.loadArg(argIndex); //doesn't work... aa.visitVarInsn(type.getOpcode(Opcodes.ILOAD), stackIndex); aa.valueOf(type); break; } }
@Override public void visitLabel(Label label) { //这个super.xx必须放到第一行 super.visitLabel(label); ArrayList<String> exceptions = matchHandle.get(label); if(label != null && exceptions != null){ logger.log(Level.INFO,"instrument "+exceptions); Label matched = new Label(); Label end = new Label(); //捕获的是目标exception的实例才进行处理 final int N = exceptions.size() - 1; if (N >= 1) { for (int i = 0; i < N; i++) { compareInstance(IFNE, exceptions.get(i), matched); } } compareInstance(IFEQ, exceptions.get(N), end); visitLabel(matched); dup(); invokeStatic(Type.getObjectType("test/github/monitor/Monitor") , new Method("pushException", "(Ljava/lang/Throwable;)V")); visitLabel(end); } }
public static AbstractInsnNode rawBinaryOperator(String methodName, Type returnType, Type argType) { return new MethodInsnNode( INVOKESTATIC, Type.getInternalName(LuaMathOperators.class), methodName, Type.getMethodDescriptor( returnType, argType, argType), false); }
@Override public BasicValue newValue(final Type type) { if (type == null) { return BasicValue.UNINITIALIZED_VALUE; } boolean isArray = type.getSort() == Type.ARRAY; if (isArray) { switch (type.getElementType().getSort()) { case Type.BOOLEAN: case Type.CHAR: case Type.BYTE: case Type.SHORT: return new BasicValue(type); } } BasicValue v = super.newValue(type); if (BasicValue.REFERENCE_VALUE.equals(v)) { if (isArray) { v = newValue(type.getElementType()); String desc = v.getType().getDescriptor(); for (int i = 0; i < type.getDimensions(); ++i) { desc = '[' + desc; } v = new BasicValue(Type.getType(desc)); } else { v = new BasicValue(type); } } return v; }
public static MethodInsnNode registerTicks() { return new MethodInsnNode( INVOKEINTERFACE, selfTpe().getInternalName(), "registerTicks", Type.getMethodDescriptor( Type.VOID_TYPE, Type.INT_TYPE), true); }
private MethodInfo(Method method, int index) { super(method.getName(), index, Type.getMethodDescriptor(method)); invokeOpcode = method.getDeclaringClass().isInterface() ? INVOKEINTERFACE : Modifier.isStatic(method.getModifiers()) ? INVOKESTATIC : INVOKEVIRTUAL; this.method = method; parameterCount = method.getParameterCount(); parameters = Collections.unmodifiableList( Arrays.stream(method.getParameterTypes()) .map(ParameterInfo::new) .collect(toList()) ); }
/** * 命令执行hook点 * * @param command 命令列表 */ public static void checkCommand(List<String> command) { if (command != null && !command.isEmpty()) { JSContext cx = JSContextFactory.enterAndInitContext(); Scriptable params = cx.newObject(cx.getScope()); Scriptable array = cx.newArray(cx.getScope(), command.toArray()); params.put("command", params, array); HookHandler.doCheck(CheckParameter.Type.COMMAND, params); } }
protected Class<?> getClass(final Type t) { try { if (t.getSort() == Type.ARRAY) { return Class.forName(t.getDescriptor().replace('/', '.'), false, loader); } return Class.forName(t.getClassName(), false, loader); } catch (ClassNotFoundException e) { throw new RuntimeException(e.toString()); } }
private static void initType(int offset, Type t, DirectSorter v) { switch(t.getSort()) { case Type.BOOLEAN: case Type.BYTE: case Type.CHAR: case Type.SHORT: case Type.INT: v.visitInsn(Opcodes.ICONST_0); v.directVarInsn(Opcodes.ISTORE, offset); break; case Type.LONG: v.visitInsn(Opcodes.LCONST_0); v.directVarInsn(Opcodes.LSTORE, offset); break; case Type.FLOAT: v.visitInsn(Opcodes.FCONST_0); v.directVarInsn(Opcodes.FSTORE, offset); break; case Type.DOUBLE: v.visitInsn(Opcodes.DCONST_0); v.directVarInsn(Opcodes.DSTORE, offset); break; case Type.OBJECT: v.visitInsn(Opcodes.ACONST_NULL); v.directVarInsn(Opcodes.ASTORE, offset); break; default: throw new UnsupportedOperationException(); } }
private static AccessInfo forPrimitiveWrapper(String memberType, Class<?> clazz) { Class<?> primitiveClass = ClassUtils.wrapperToPrimitive(clazz); String camelCaseClassName = WordUtils.capitalize(primitiveClass.getName()); String capitalizedMemberType = WordUtils.capitalize(memberType); return new AccessInfo( memberType, "getBoxed" + camelCaseClassName + capitalizedMemberType, "setBoxed" + camelCaseClassName + capitalizedMemberType, clazz.getName(), Type.getDescriptor(clazz), ALOAD, ARETURN); }
/** * Generates unboxing bytecode for the passed type. An {@link Object} is expected to be on the * stack when these bytecodes are inserted. * * ASM takes a short cut when dealing with short/byte types and convert them into int rather * than short/byte types. This is not an issue on the jvm nor Android's ART but it is an issue * on Dalvik. * * @param mv the {@link GeneratorAdapter} generating a method implementation. * @param type the expected un-boxed type. */ public static void unbox(GeneratorAdapter mv, Type type) { if (type.equals(Type.SHORT_TYPE)) { mv.checkCast(NUMBER_TYPE); mv.invokeVirtual(NUMBER_TYPE, SHORT_VALUE); } else if (type.equals(Type.BYTE_TYPE)) { mv.checkCast(NUMBER_TYPE); mv.invokeVirtual(NUMBER_TYPE, BYTE_VALUE); } else { mv.unbox(type); } }
public void createObjectArray(){ push(types.size()); newArray(Type.getType(Object.class)); int stack = 0; for (int i=0; i<types.size(); i++){ Type type = types.get(i); dup(); push(i); visitVarInsn(type.getOpcode(ILOAD), stack); box(type); // System.out.println("Otype ===> " + Type.getType(Object.class)); arrayStore(Type.getType(Object.class)); stack += type.getSize(); } }
/** * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a * MethodHandle of kind put instance. The method handle write an instance field in a class and * then print its value. */ private void generateMethodTest13(ClassVisitor cv) { MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test13", "()V", null, null); MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, MethodHandle.class); Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "bsmCreateCallCallingtargetMethod", mt.toMethodDescriptorString(), false); mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class)); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn( Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false); mv.visitVarInsn(Opcodes.ASTORE, 0); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitLdcInsn("Write instance field"); mv.visitInvokeDynamicInsn("instanceField1", "(Linvokecustom/InvokeCustom;Ljava/lang/String;)V", bootstrap, new Handle(Opcodes.H_PUTFIELD, Type.getInternalName(InvokeCustom.class), "instanceField1", "Ljava/lang/String;", false)); mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, Type.getInternalName(InvokeCustom.class), "instanceField1", "Ljava/lang/String;"); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(-1, -1); }
private static Set<DomainBuilders.BuilderWithBuildParameter<JavaClass, JavaMethod>> methodBuildersFor(Class<?> inputClass, ClassesByTypeName importedClasses) { final Set<DomainBuilders.BuilderWithBuildParameter<JavaClass, JavaMethod>> methodBuilders = new HashSet<>(); for (Method method : inputClass.getDeclaredMethods()) { methodBuilders.add(new DomainBuilders.JavaMethodBuilder() .withReturnType(JavaType.From.name(method.getReturnType().getName())) .withParameters(typesFrom(method.getParameterTypes())) .withName(method.getName()) .withDescriptor(Type.getMethodDescriptor(method)) .withAnnotations(javaAnnotationBuildersFrom(method.getAnnotations(), importedClasses)) .withModifiers(JavaModifier.getModifiersForMethod(method.getModifiers()))); } return methodBuilders; }
protected Type getSuperClass(final Type t) { if (currentClass != null && t.equals(currentClass)) { return currentSuperClass; } Class<?> c = getClass(t).getSuperclass(); return c == null ? null : Type.getType(c); }
private void writeGetter(ClassVisitor visitor, Type generatedType, String propertyName, Class<?> propertyClass, WeaklyTypeReferencingMethod<?, ?> weakGetter) { Method getter = weakGetter.getMethod(); Type propertyType = Type.getType(propertyClass); MethodVisitor methodVisitor = declareMethod( visitor, getter.getName(), Type.getMethodDescriptor(propertyType), AsmClassGeneratorUtils.signature(getter)); putStateFieldValueOnStack(methodVisitor, generatedType); putConstantOnStack(methodVisitor, propertyName); invokeStateGetMethod(methodVisitor); castFirstStackElement(methodVisitor, propertyClass); finishVisitingMethod(methodVisitor, returnCode(propertyType)); }
/** * Transforms an existin <clinit> method. Adds bytecode before the return, if * exists. * @param className * @param target */ private void transformClassInit(String className, MethodNode target) { Type classType = Type.getObjectType(className); if (target.instructions.size() > 0) { if (target.instructions.getLast().getOpcode() == Opcodes.RETURN) { target.instructions.remove(target.instructions.getLast()); } } // ldc target.visitLdcInsn(classType); // invokevirtual --> classloader on stack target.visitMethodInsn( Opcodes.INVOKEVIRTUAL, JAVA_LANG_CLASS, CLASS_GET_CLASSLODER_METHOD, CLASS_GET_CLASSLOADER_DESC, false ); // putstatic target.visitFieldInsn( Opcodes.PUTSTATIC, AGENT_CLASS, AGENT_CLASSLOADER_FIELD, AGENT_CLASSLOADER_DESC ); target.visitInsn(Opcodes.RETURN); // ldc || classloader instance target.maxStack = Math.max(target.maxStack, 1); target.maxLocals = Math.max(target.maxLocals, 1); target.visitEnd(); }
void checkLDCConstant(final Object cst) { if (cst instanceof Type) { int s = ((Type) cst).getSort(); if (s != Type.OBJECT && s != Type.ARRAY && s != Type.METHOD) { throw new IllegalArgumentException("Illegal LDC constant value"); } if (s != Type.METHOD && (version & 0xFFFF) < Opcodes.V1_5) { throw new IllegalArgumentException( "ldc of a constant class requires at least version 1.5"); } if (s == Type.METHOD && (version & 0xFFFF) < Opcodes.V1_7) { throw new IllegalArgumentException( "ldc of a method type requires at least version 1.7"); } } else if (cst instanceof Handle) { if ((version & 0xFFFF) < Opcodes.V1_7) { throw new IllegalArgumentException( "ldc of a handle requires at least version 1.7"); } int tag = ((Handle) cst).getTag(); if (tag < Opcodes.H_GETFIELD || tag > Opcodes.H_INVOKEINTERFACE) { throw new IllegalArgumentException("invalid handle tag " + tag); } } else { checkConstant(cst); } }
@Nullable private static Method findMethod(Class<?> clazz, String methodName, Type[] params, Type returnType) { Class<?> scanClass = clazz; Method method = null; /* Scan superclasses */ do { method = Arrays.stream(scanClass.getDeclaredMethods()) .filter(m -> methodName.equals(m.getName()) && Arrays.equals(Type.getArgumentTypes(m), params) && Type.getType(m.getReturnType()).equals(returnType) ) .findFirst().orElse(null); } while (method == null && (scanClass = scanClass.getSuperclass()) != null); if(method != null) return method; /* No interfaces to scan :( */ if(clazz.getInterfaces().length == 0) return null; /* Scan interfaces */ int i = 0; scanClass = clazz.getInterfaces()[i]; do { method = Arrays.stream(scanClass.getDeclaredMethods()) .filter(m -> methodName.equals(m.getName()) && Arrays.equals(Type.getArgumentTypes(m), params) && Type.getType(m.getReturnType()).equals(returnType) && (m.isDefault() || Modifier.isStatic(m.getModifiers())) ) .findFirst().orElse(null); i++; } while(method == null && i < scanClass.getInterfaces().length && (scanClass = scanClass.getInterfaces()[i]) != null); return method; }
/** * Transfer the member variables of this holder to local variables. * * <p>If this is used, the maximum stack size must be increased by one * to accommodate the extra DUP instruction this will generate. * * @param adder a visitor that will be called to add the necessary instructions * @param localVariable the offset of the first local variable to use */ public void transferToLocal(final DirectSorter adder, final int localVariable) { for (int i = 0; i < types.length; i++) { final Type t = types[i]; if (i + 1 < types.length) { adder.visitInsn(Opcodes.DUP); // not size dependent: always the objectref from which we'll GETFIELD } adder.visitFieldInsn(Opcodes.GETFIELD, type.getInternalName(), names[i], t.getDescriptor()); adder.directVarInsn(t.getOpcode(Opcodes.ISTORE), localVariable + offsets[i]); } }
public static byte[] generateMethodArgsUpdater(Class<?> classToProxy, Method method, int methodId) throws Exception { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); String classToProxyDescriptor = Type.getDescriptor(classToProxy); String classToProxyInternalName = Type.getInternalName(classToProxy); String suffix = SUFFIX_START + method.getName() + methodId; String selfClassInternalName = classToProxyInternalName + suffix; String selfClassDescriptor = BytecodeGenUtils.makeSuffixClassDescriptor(classToProxyDescriptor, suffix); String argsClassInternalName = classToProxyInternalName + MethodArgumentsGenerator.SUFFIX_START + method.getName() + methodId; String constDesc = Type.getMethodDescriptor(Type.VOID_TYPE, Stream.concat(Stream.of(List.class), Stream.of(method.getParameterTypes())).map(Type::getType) .toArray(Type[]::new)); cw.visit(52, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, selfClassInternalName, null, "java/lang/Object", new String[] { "io/primeval/reflex/arguments/ArgumentsUpdater" }); Parameter[] parameters = method.getParameters(); generateFields(method, cw, parameters); generateConstructor(method, cw, selfClassInternalName, selfClassDescriptor, constDesc, parameters); generateHashCodeMethod(cw, selfClassInternalName, selfClassDescriptor, parameters); generateEqualsMethod(cw, selfClassInternalName, selfClassDescriptor, parameters); generateToStringMethod(cw, selfClassInternalName, selfClassDescriptor, parameters); generateUpdateMethod(cw, selfClassInternalName, selfClassDescriptor, argsClassInternalName, constDesc, parameters); generateParametersGetter(cw, selfClassInternalName, selfClassDescriptor); generateArgumentSetters(cw, selfClassInternalName, selfClassDescriptor, parameters); generateArgumentGetters(cw, selfClassInternalName, selfClassDescriptor, parameters); cw.visitEnd(); return cw.toByteArray(); }
public void addConstructor(Constructor<?> constructor) throws Exception { List<Type> paramTypes = new ArrayList<Type>(); for (Class<?> paramType : constructor.getParameterTypes()) { paramTypes.add(Type.getType(paramType)); } String methodDescriptor = Type.getMethodDescriptor(VOID_TYPE, paramTypes.toArray(EMPTY_TYPES)); MethodVisitor methodVisitor = visitor.visitMethod(Opcodes.ACC_PUBLIC, "<init>", methodDescriptor, signature(constructor), EMPTY_STRINGS); for (Annotation annotation : constructor.getDeclaredAnnotations()) { if (annotation.annotationType().getAnnotation(Inherited.class) != null) { continue; } Retention retention = annotation.annotationType().getAnnotation(Retention.class); AnnotationVisitor annotationVisitor = methodVisitor.visitAnnotation(Type.getType(annotation.annotationType()).getDescriptor(), retention != null && retention.value() == RetentionPolicy.RUNTIME); annotationVisitor.visitEnd(); } methodVisitor.visitCode(); // this.super(p0 .. pn) methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); for (int i = 0; i < constructor.getParameterTypes().length; i++) { methodVisitor.visitVarInsn(Type.getType(constructor.getParameterTypes()[i]).getOpcode(Opcodes.ILOAD), i + 1); } methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, superclassType.getInternalName(), "<init>", methodDescriptor, false); methodVisitor.visitInsn(Opcodes.RETURN); methodVisitor.visitMaxs(0, 0); methodVisitor.visitEnd(); }
private void addSetter(Method method, MethodCodeBody body) throws Exception { String methodDescriptor = Type.getMethodDescriptor(method); MethodVisitor methodVisitor = visitor.visitMethod(Opcodes.ACC_PUBLIC, method.getName(), methodDescriptor, null, EMPTY_STRINGS); methodVisitor.visitCode(); body.add(methodVisitor); methodVisitor.visitInsn(Opcodes.RETURN); methodVisitor.visitMaxs(0, 0); methodVisitor.visitEnd(); }
public static MethodInsnNode checkCallYield() { return new MethodInsnNode( INVOKEINTERFACE, selfTpe().getInternalName(), "pauseIfRequested", Type.getMethodDescriptor( Type.VOID_TYPE), true); }
@Override public void injectAtVisitMaxs(int maxStack, int maxLocals) { Label endFinally = new Label(); aa.visitTryCatchBlock(startFinally, endFinally, endFinally, null); aa.visitLabel(endFinally); aa.visitFieldInsn(GETSTATIC, className, staticFinalFieldName(metric), Type.getDescriptor(Counted.getCoreType())); injectLabelsToStack(metric); aa.visitMethodInsn(INVOKESTATIC, METRIC_REPORTER_CLASSNAME, METHOD, SIGNATURE, false); aa.visitInsn(ATHROW); }
public static AbstractInsnNode numeric(String methodName, int numArgs) { Type[] args = new Type[numArgs]; Arrays.fill(args, Type.getType(Number.class)); return new MethodInsnNode( INVOKESTATIC, Type.getInternalName(Dispatch.class), methodName, Type.getMethodDescriptor( Type.getType(Number.class), args), false); }