protected byte[] instrumentClass(ClassNode cn, ClassReader cr, boolean methodBodyOnly) { TxClassVisitor visitor = new TxClassVisitor(cn, new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES), methodBodyOnly); cr.accept(visitor, ClassReader.EXPAND_FRAMES); return visitor.getClassData(); }
protected void instrument(AppInstrumentContext context, AppInstrumentClass ic, ClassReader cr, ClassWriter cw) { ClassNode cn = ASM.getClassNode(cr); transformClass(cr,cw, cn); instrumentDelegates(cr,cw); cw.visitEnd(); byte[] data = cw.toByteArray(); context.updateInstrumented(ic, this, data, false); }
/** * Returns the index of the common super type of the two given types. This * method calls {@link #getCommonSuperClass} and caches the result in the * {@link #items} hash table to speedup future calls with the same * parameters. * * @param type1 * index of an internal name in {@link #typeTable}. * @param type2 * index of an internal name in {@link #typeTable}. * @return the index of the common super type of the two given types. */ int getMergedType(final int type1, final int type2) { key2.type = TYPE_MERGED; key2.longVal = type1 | (((long) type2) << 32); key2.hashCode = 0x7FFFFFFF & (TYPE_MERGED + type1 + type2); Item result = get(key2); if (result == null) { String t = typeTable[type1].strVal1; String u = typeTable[type2].strVal1; key2.intVal = addType(getCommonSuperClass(t, u)); result = new Item((short) 0, key2); put(result); } return result.intVal; }
/** * Adds the given "uninitialized" type to {@link #typeTable} and returns its * index. This method is used for UNINITIALIZED types, made of an internal * name and a bytecode offset. * * @param type * the internal name to be added to the type table. * @param offset * the bytecode offset of the NEW instruction that created this * UNINITIALIZED type value. * @return the index of this internal name in the type table. */ int addUninitializedType(final String type, final int offset) { key.type = TYPE_UNINIT; key.intVal = offset; key.strVal1 = type; key.hashCode = 0x7FFFFFFF & (TYPE_UNINIT + type.hashCode() + offset); Item result = get(key); if (result == null) { result = addType(key); } return result.index; }
/** * Adds a name and type to the constant pool of the class being build. Does * nothing if the constant pool already contains a similar item. * * @param name * a name. * @param desc * a type descriptor. * @return a new or already existing name and type item. */ Item newNameTypeItem(final String name, final String desc) { key2.set(NAME_TYPE, name, desc, null); Item result = get(key2); if (result == null) { put122(NAME_TYPE, newUTF8(name), newUTF8(desc)); result = new Item(index++, key2); put(result); } return result; }
String typeClassNameInternal = typeClassName.replace('.', '/'); ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); cw.visitEnd(); byte[] data = cw.toByteArray(); accessorClass = loader.defineClass(accessorClassName, data);
public static void pintASMifiedCode(Class cls) { Resource r = Resources.getResource(cls); Try.throwUnchecked(() -> { try(InputStream is = r.getInputStream()) { ClassReader cr = new ClassReader(is); ClassWriter cw = new ClassWriter(cr,ClassWriter.COMPUTE_FRAMES); cr.accept(cw, 0); ASM.printASMifiedCode(cw.toByteArray(), new PrintWriter(System.out)); } }); }
bootstrapMethods.putShort(newHandle(bsm.tag, bsm.owner, bsm.name, bsm.desc)); Object bsmArg = bsmArgs[i]; hashCode ^= bsmArg.hashCode(); bootstrapMethods.putShort(newConst(bsmArg)); result = new Item(bootstrapMethodIndex); result.set(position, hashCode); put(result); result = get(key3); if (result == null) { put122(INDY, bootstrapMethodIndex, newNameType(name, desc)); result = new Item(index++, key3); put(result);
/** * Adds a method reference to the constant pool of the class being build. * Does nothing if the constant pool already contains a similar item. * * @param owner * the internal name of the method's owner class. * @param name * the method's name. * @param desc * the method's descriptor. * @param itf * <tt>true</tt> if <tt>owner</tt> is an interface. * @return a new or already existing method reference item. */ Item newMethodItem(final String owner, final String name, final String desc, final boolean itf) { int type = itf ? IMETH : METH; key3.set(type, owner, name, desc); Item result = get(key3); if (result == null) { put122(type, newClass(owner), newNameType(name, desc)); result = new Item(index++, key3); put(result); } return result; }
final String desc) { key4.set(HANDLE_BASE + tag, owner, name, desc); Item result = get(key4); if (result == null) { if (tag <= Opcodes.H_PUTSTATIC) { put112(HANDLE, tag, newField(owner, name, desc)); } else { put112(HANDLE, tag, newMethod(owner, name, desc, tag == Opcodes.H_INVOKEINTERFACE)); put(result);
private static void defineNewInstance(String classNameInternal,ClassWriter cw){ MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "newInstance", "()Ljava/lang/Object;", null, null); mv.visitCode(); mv.visitTypeInsn(NEW, classNameInternal); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL,classNameInternal, "<init>", "()V"); mv.visitInsn(ARETURN); mv.visitMaxs(1, 1); mv.visitEnd(); }
public byte[] getClassData() { return cw.toByteArray(); }
/** * Adds a class reference to the constant pool of the class being build. * Does nothing if the constant pool already contains a similar item. * <i>This method is intended for {@link Attribute} sub classes, and is * normally not needed by class generators or adapters.</i> * * @param value * the internal name of the class. * @return a new or already existing class reference item. */ Item newClassItem(final String value) { key2.set(CLASS, value, null, null); Item result = get(key2); if (result == null) { pool.put12(CLASS, newUTF8(value)); result = new Item(index++, key2); put(result); } return result; }
/** * Adds an integer to the constant pool of the class being build. Does * nothing if the constant pool already contains a similar item. * * @param value * the int value. * @return a new or already existing int item. */ Item newInteger(final int value) { key.set(value); Item result = get(key); if (result == null) { pool.putByte(INT).putInt(value); result = new Item(index++, key); put(result); } return result; }
newUTF8("BootstrapMethods"); newUTF8("Signature"); newUTF8("SourceFile"); newUTF8("SourceDebugExtension"); newUTF8("EnclosingMethod"); newUTF8("Deprecated"); ++attributeCount; size += 6; newUTF8("Synthetic"); ++attributeCount; size += 8 + innerClasses.length; newUTF8("InnerClasses"); newUTF8("RuntimeVisibleAnnotations"); newUTF8("RuntimeInvisibleAnnotations"); newUTF8("RuntimeVisibleTypeAnnotations"); newUTF8("RuntimeInvisibleTypeAnnotations"); out.putShort(newUTF8("BootstrapMethods"));
cw.visitInnerClass(LOOKUP_TYPE.getInternalName(), HANDLES_TYPE.getInternalName(), LOOKUP_NAME, ACC_PUBLIC + ACC_FINAL + ACC_STATIC); MethodVisitor real = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null); ClinitMethodVisitor mv = new ClinitMethodVisitor(real, ACC_STATIC, "<clinit>", "()V"); mv.visitCode(); FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC, PROVIDER_FIELD, PROVIDER_TYPE.getDescriptor(), null, null); fv = cw.visitField(Opcodes.ACC_PRIVATE, field.getValue(), ASM.getObjectTypeDescriptor(field.getKey()), null, null); fv = cw.visitField(Opcodes.ACC_PRIVATE, field.getValue(), INTERCEPTOR_TYPE.getDescriptor(), null, null); fv = cw.visitField(ACC_PRIVATE + ACC_FINAL + ACC_STATIC, am.field, METHOD_TYPE.getDescriptor(), null, null); fv.visitEnd();
private static void defineAccessorConstructor(String accessorClassNameInternal,ClassWriter cw){ cw.visit(V1_6, ACC_PUBLIC, accessorClassNameInternal, null, CLASS_NAME, null); MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, CLASS_NAME, "<init>", "()V"); mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); }
@Override public void visitEnd() { if(!methodBodyOnly) { FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC, PROVIDER_FIELD, PROVIDER_TYPE.getDescriptor(), null, null); fv.visitEnd(); if (!visitStaticInit) { int access = Opcodes.ACC_STATIC; MethodVisitor real = cw.visitMethod(access, "<clinit>", "()V", null, null); ClinitMethodVisitor mv = new ClinitMethodVisitor(real, access, "<clinit>", "()V"); mv.visitCode(); mv.returnValue(); mv.visitMaxs(0, 0); mv.visitEnd(); } } super.visitEnd(); }
if (local[i] instanceof String) { frame[frameIndex++] = Frame.OBJECT | cw.addType((String) local[i]); } else if (local[i] instanceof Integer) { frame[frameIndex++] = ((Integer) local[i]).intValue(); } else { frame[frameIndex++] = Frame.UNINITIALIZED | cw.addUninitializedType("", ((Label) local[i]).position); if (stack[i] instanceof String) { frame[frameIndex++] = Frame.OBJECT | cw.addType((String) stack[i]); } else if (stack[i] instanceof Integer) { frame[frameIndex++] = ((Integer) stack[i]).intValue(); } else { frame[frameIndex++] = Frame.UNINITIALIZED | cw.addUninitializedType("", ((Label) stack[i]).position);
| cw.getMergedType(t & BASE_VALUE, u & BASE_VALUE); } else { v = vdim | OBJECT | cw.addType("java/lang/Object"); : ELEMENT_OF) + (u & DIM); v = Math.min(tdim, udim) | OBJECT | cw.addType("java/lang/Object"); } else {