1 5 package com.tc.object.bytecode; 6 7 import com.tc.asm.ClassAdapter; 8 import com.tc.asm.ClassVisitor; 9 import com.tc.asm.Label; 10 import com.tc.asm.MethodAdapter; 11 import com.tc.asm.MethodVisitor; 12 import com.tc.asm.Opcodes; 13 import com.tc.util.runtime.Vm.Version; 14 15 public class StringBufferAdapter extends ClassAdapter implements Opcodes { 16 17 private final Version version; 18 19 public StringBufferAdapter(ClassVisitor cv, Version version) { 20 super(cv); 21 this.version = version; 22 } 23 24 public MethodVisitor visitMethod(int access, String name, String desc, String signature, String [] exceptions) { 25 MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); 26 if ("toString".equals(name) && "()Ljava/lang/String;".equals(desc) && version.isJDK14()) { 27 rewriteToString1_4(mv); 28 return null; 29 } 30 31 return mv; 32 } 33 34 private void rewriteToString1_4(MethodVisitor mv) { 35 mv.visitCode(); 38 Label l0 = new Label(); 39 mv.visitLabel(l0); 40 mv.visitLineNumber(12, l0); 41 mv.visitVarInsn(ALOAD, 0); 42 mv.visitInsn(DUP); 43 mv.visitVarInsn(ASTORE, 1); 44 mv.visitInsn(MONITORENTER); 45 Label l1 = new Label(); 46 mv.visitLabel(l1); 47 mv.visitLineNumber(13, l1); 48 mv.visitVarInsn(ALOAD, 0); 49 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "setShared", "()V"); 50 Label l2 = new Label(); 51 mv.visitLabel(l2); 52 mv.visitLineNumber(14, l2); 53 mv.visitTypeInsn(NEW, "java/lang/String"); 54 mv.visitInsn(DUP); 55 mv.visitInsn(ICONST_0); 56 mv.visitVarInsn(ALOAD, 0); 57 mv.visitFieldInsn(GETFIELD, "java/lang/StringBuffer", "count", "I"); 58 mv.visitVarInsn(ALOAD, 0); 59 mv.visitFieldInsn(GETFIELD, "java/lang/StringBuffer", "value", "[C"); 60 mv.visitMethodInsn(INVOKESPECIAL, "java/lang/String", "<init>", "(II[C)V"); 61 mv.visitVarInsn(ALOAD, 1); 62 mv.visitInsn(MONITOREXIT); 63 Label l3 = new Label(); 64 mv.visitLabel(l3); 65 mv.visitInsn(ARETURN); 66 Label l4 = new Label(); 67 mv.visitLabel(l4); 68 mv.visitLineNumber(12, l4); 69 mv.visitVarInsn(ALOAD, 1); 70 mv.visitInsn(MONITOREXIT); 71 Label l5 = new Label(); 72 mv.visitLabel(l5); 73 mv.visitInsn(ATHROW); 74 Label l6 = new Label(); 75 mv.visitLabel(l6); 76 mv.visitTryCatchBlock(l1, l3, l4, null); 77 mv.visitTryCatchBlock(l4, l5, l4, null); 78 mv.visitMaxs(0, 0); 79 mv.visitEnd(); 80 } 81 82 public static class FixUp extends ClassAdapter { 83 84 private static final String MANAGED_APPEND = DuplicateMethodAdapter.MANAGED_PREFIX + "append"; 85 private final Version version; 86 87 public FixUp(ClassVisitor cv, Version version) { 88 super(cv); 89 this.version = version; 90 } 91 92 public MethodVisitor visitMethod(int access, String name, String desc, String signature, String [] exceptions) { 93 MethodVisitor visitor = super.visitMethod(access, name, desc, signature, exceptions); 94 95 if (MANAGED_APPEND.equals(name) && "([CII)Ljava/lang/StringBuffer;".equals(desc) && version.isJDK14()) { 96 return new CloneCharArrayFixup(visitor); 98 } 99 100 return visitor; 101 } 102 103 private static class CloneCharArrayFixup extends MethodAdapter { 108 public CloneCharArrayFixup(MethodVisitor mv) { 109 super(mv); 110 mv.visitVarInsn(ALOAD, 1); 111 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "clone", "()Ljava/lang/Object;"); 112 mv.visitTypeInsn(CHECKCAST, "[C"); 113 mv.visitVarInsn(ASTORE, 1); 114 } 115 } 116 } 117 118 } 119 | Popular Tags |