001: /*
002: * All content copyright (c) 2003-2007 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package org.terracotta.modules.lucene_2_0_0;
006:
007: import com.tc.asm.ClassAdapter;
008: import com.tc.asm.ClassVisitor;
009: import com.tc.asm.MethodAdapter;
010: import com.tc.asm.MethodVisitor;
011: import com.tc.asm.Opcodes;
012: import com.tc.object.bytecode.ClassAdapterFactory;
013:
014: public class RAMFileExternalAccessAdatper extends ClassAdapter
015: implements ClassAdapterFactory {
016:
017: public RAMFileExternalAccessAdatper(ClassVisitor cv) {
018: super (cv);
019: }
020:
021: public RAMFileExternalAccessAdatper() {
022: super (null);
023: }
024:
025: public ClassAdapter create(ClassVisitor visitor, ClassLoader loader) {
026: return new RAMFileExternalAccessAdatper(visitor);
027: }
028:
029: public MethodVisitor visitMethod(int access, String name,
030: String desc, String signature, String[] exceptions) {
031: return new RewriteFieldAccessAdapter(super .visitMethod(access,
032: name, desc, signature, exceptions));
033: }
034:
035: private static class RewriteFieldAccessAdapter extends
036: MethodAdapter implements Opcodes {
037:
038: private static final String RAMFile_CLASS = "org/apache/lucene/store/RAMFile";
039:
040: private boolean delegateVectorCall = false;
041:
042: public RewriteFieldAccessAdapter(MethodVisitor mv) {
043: super (mv);
044: }
045:
046: public void visitMethodInsn(int opcode, String owner,
047: String name, String desc) {
048: if ("java/util/Vector".equals(owner)) {
049: if (delegateVectorCall) {
050: delegateVectorCall = false;
051:
052: // RAMFile instance should still be on the stack here since we removed the field insn
053: super .visitMethodInsn(INVOKEVIRTUAL, RAMFile_CLASS,
054: RAMFileAdapter.BUFFERS_FIELD + name, desc);
055: return;
056: }
057: }
058:
059: super .visitMethodInsn(opcode, owner, name, desc);
060: }
061:
062: public void visitFieldInsn(int opcode, String owner,
063: String name, String desc) {
064: if (RAMFile_CLASS.equals(owner)) {
065: switch (opcode) {
066: case GETFIELD: {
067: if (RAMFileAdapter.BUFFERS_FIELD.equals(name)) {
068: if (delegateVectorCall) {
069: throw new AssertionError(
070: "a previous vector call not delegated");
071: }
072: delegateVectorCall = true;
073: return;
074: }
075:
076: super .visitMethodInsn(INVOKEVIRTUAL, RAMFile_CLASS,
077: "get" + name, "()" + desc);
078: break;
079: }
080: case PUTFIELD: {
081: super .visitMethodInsn(INVOKEVIRTUAL, RAMFile_CLASS,
082: "set" + name, "(" + desc + ")V");
083: break;
084: }
085: default: {
086: throw new AssertionError("unexpected field op: "
087: + opcode + ", " + owner + ", " + name
088: + ", " + desc);
089: }
090: }
091: } else {
092: super .visitFieldInsn(opcode, owner, name, desc);
093: }
094: }
095:
096: public void visitEnd() {
097: // This assertion will be wrong if there is code that simply reads the vector field from RAMFile,
098: // but calls no method on it
099: if (delegateVectorCall) {
100: throw new AssertionError(
101: "a remaining vector call not delegated");
102: }
103: super.visitEnd();
104: }
105:
106: }
107:
108: }
|