KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > object > bytecode > JavaUtilConcurrentLinkedBlockingQueueIteratorClassAdapter


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.tc.object.bytecode;
5 import com.tc.asm.ClassAdapter;
6 import com.tc.asm.ClassVisitor;
7 import com.tc.asm.Label;
8 import com.tc.asm.MethodVisitor;
9 import com.tc.asm.Opcodes;
10 import com.tc.asm.commons.LocalVariablesSorter;
11 import com.tc.object.bytecode.JavaUtilConcurrentLinkedBlockingQueueClassAdapter.NodeMethodAdapter;
12
13 public class JavaUtilConcurrentLinkedBlockingQueueIteratorClassAdapter extends ClassAdapter implements Opcodes {
14
15   public JavaUtilConcurrentLinkedBlockingQueueIteratorClassAdapter(ClassVisitor cv) {
16     super(cv);
17   }
18   
19   public MethodVisitor visitMethod(int access, String JavaDoc name, String JavaDoc desc, String JavaDoc signature, String JavaDoc[] exceptions) {
20     MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
21     mv = new NodeMethodAdapter(mv);
22     if ("remove".equals(name) && "()V".equals(desc)) {
23       mv = new RemoveMethodAdapter(access, desc, mv);
24     }
25     return mv;
26   }
27   
28   // This is a hack for the remove() method of the LinkedBlockingQueue.iterator.
29
private static class RemoveMethodAdapter extends LocalVariablesSorter implements Opcodes {
30     private final int newLocalVar;
31     private boolean incNext = false;
32     private boolean incDone = false;
33     
34     public RemoveMethodAdapter(int access, String JavaDoc desc, MethodVisitor mv) {
35       super(access, desc, mv);
36       newLocalVar = newLocal(1);
37     }
38     
39     public void visitCode() {
40       super.visitCode();
41       mv.visitInsn(ICONST_0);
42       mv.visitVarInsn(ISTORE, newLocalVar);
43     }
44     
45     public void visitFieldInsn(int opcode, String JavaDoc owner, String JavaDoc name, String JavaDoc desc) {
46       super.visitFieldInsn(opcode, owner, name, desc);
47       if (GETFIELD == opcode && "next".equals(name)) {
48         if (!incNext) {
49           incNext = true;
50         } else if (!incDone) {
51           mv.visitIincInsn(newLocalVar, 1);
52           incDone = true;
53         }
54       } else if (PUTFIELD == opcode && "item".equals(name)) {
55         addLogicalInvokeMethod();
56       }
57     }
58     
59     private void addLogicalInvokeMethod() {
60       mv.visitVarInsn(ALOAD, 0);
61       mv.visitFieldInsn(GETFIELD, "java/util/concurrent/LinkedBlockingQueue$Itr", "this$0", "Ljava/util/concurrent/LinkedBlockingQueue;");
62       mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "isManaged", "(Ljava/lang/Object;)Z");
63       Label l21 = new Label();
64       mv.visitJumpInsn(IFEQ, l21);
65       Label l22 = new Label();
66       mv.visitLabel(l22);
67       mv.visitVarInsn(ALOAD, 0);
68       mv.visitFieldInsn(GETFIELD, "java/util/concurrent/LinkedBlockingQueue$Itr", "this$0", "Ljava/util/concurrent/LinkedBlockingQueue;");
69       mv.visitLdcInsn("remove(I)Ljava/lang/Object;");
70       mv.visitInsn(ICONST_1);
71       mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
72       mv.visitInsn(DUP);
73       mv.visitInsn(ICONST_0);
74       mv.visitTypeInsn(NEW, "java/lang/Integer");
75       mv.visitInsn(DUP);
76       mv.visitVarInsn(ILOAD, newLocalVar);
77       mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Integer", "<init>", "(I)V");
78       mv.visitInsn(AASTORE);
79       mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "logicalInvoke", "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V");
80       mv.visitLabel(l21);
81     }
82   }
83   
84 }
Popular Tags