001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tc.object.bytecode;
005:
006: import com.tc.asm.ClassVisitor;
007: import com.tc.asm.Label;
008: import com.tc.asm.MethodAdapter;
009: import com.tc.asm.MethodVisitor;
010: import com.tc.asm.Opcodes;
011:
012: public class THashMapAdapter {
013:
014: public static class TransformValuesAdapter extends
015: AbstractMethodAdapter {
016: private final static String STATIC_EXECUTE_DESC = "(Lgnu/trove/TObjectFunction;Ljava/lang/Object;Lgnu/trove/THashMap;Ljava/lang/Object;)Ljava/lang/Object;";
017:
018: public MethodVisitor adapt(ClassVisitor classVisitor) {
019: addStaticExecuteMethod(classVisitor);
020: MethodVisitor mv = visitOriginal(classVisitor);
021: return new Adapter(mv);
022: }
023:
024: private void addStaticExecuteMethod(ClassVisitor cv) {
025: MethodVisitor mv = cv.visitMethod(ACC_PRIVATE + ACC_STATIC
026: + ACC_SYNTHETIC, "execute", STATIC_EXECUTE_DESC,
027: null, null);
028: mv.visitCode();
029: Label l0 = new Label();
030: mv.visitLabel(l0);
031: mv.visitLineNumber(468, l0);
032: mv.visitVarInsn(ALOAD, 0);
033: mv.visitVarInsn(ALOAD, 1);
034: mv.visitMethodInsn(INVOKEINTERFACE,
035: "gnu/trove/TObjectFunction", "execute",
036: "(Ljava/lang/Object;)Ljava/lang/Object;");
037: mv.visitVarInsn(ASTORE, 4);
038: Label l1 = new Label();
039: mv.visitLabel(l1);
040: mv.visitLineNumber(469, l1);
041: mv.visitVarInsn(ALOAD, 4);
042: mv.visitVarInsn(ALOAD, 1);
043: mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object",
044: "equals", "(Ljava/lang/Object;)Z");
045: Label l2 = new Label();
046: mv.visitJumpInsn(IFNE, l2);
047: Label l3 = new Label();
048: mv.visitLabel(l3);
049: mv.visitLineNumber(470, l3);
050: mv.visitVarInsn(ALOAD, 2);
051: mv
052: .visitLdcInsn("put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
053: mv.visitInsn(ICONST_2);
054: mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
055: mv.visitInsn(DUP);
056: mv.visitInsn(ICONST_0);
057: mv.visitVarInsn(ALOAD, 3);
058: mv.visitInsn(AASTORE);
059: mv.visitInsn(DUP);
060: mv.visitInsn(ICONST_1);
061: mv.visitVarInsn(ALOAD, 4);
062: mv.visitInsn(AASTORE);
063: mv
064: .visitMethodInsn(INVOKESTATIC,
065: "com/tc/object/bytecode/ManagerUtil",
066: "logicalInvoke",
067: "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V");
068: mv.visitLabel(l2);
069: mv.visitLineNumber(472, l2);
070: mv.visitVarInsn(ALOAD, 4);
071: mv.visitInsn(ARETURN);
072: Label l4 = new Label();
073: mv.visitLabel(l4);
074: mv.visitMaxs(0, 0);
075: mv.visitEnd();
076: }
077:
078: public boolean doesOriginalNeedAdapting() {
079: return false;
080: }
081:
082: private static class Adapter extends MethodAdapter implements
083: Opcodes {
084:
085: public Adapter(MethodVisitor mv) {
086: super (mv);
087: }
088:
089: public void visitCode() {
090: super .visitCode();
091: ByteCodeUtil.pushThis(mv);
092: mv.visitMethodInsn(INVOKEVIRTUAL, "gnu/trove/THashMap",
093: "__tc_managed", "()Lcom/tc/object/TCObject;");
094: Label l1 = new Label();
095: mv.visitJumpInsn(IFNULL, l1);
096: ByteCodeUtil.pushThis(mv);
097: mv.visitMethodInsn(INVOKESTATIC,
098: "com/tc/object/bytecode/ManagerUtil",
099: "checkWriteAccess", "(Ljava/lang/Object;)V");
100: mv.visitLabel(l1);
101: }
102:
103: public void visitMethodInsn(int opcode, String owner,
104: String name, String desc) {
105: if ((opcode == INVOKEINTERFACE)
106: && "gnu/trove/TObjectFunction".equals(owner)
107: && "execute".equals(name)
108: && "(Ljava/lang/Object;)Ljava/lang/Object;"
109: .equals(desc)) {
110: mv.visitVarInsn(ALOAD, 0);
111: mv.visitVarInsn(ALOAD, 3);
112: mv.visitVarInsn(ILOAD, 4);
113: mv.visitInsn(AALOAD);
114: opcode = INVOKESTATIC;
115: owner = "gnu/trove/THashMap";
116: desc = STATIC_EXECUTE_DESC;
117: }
118: super.visitMethodInsn(opcode, owner, name, desc);
119: }
120: }
121: }
122:
123: }
|