01: /*
02: * Javassist, a Java-bytecode translator toolkit.
03: * Copyright (C) 1999-2006 Shigeru Chiba. All Rights Reserved.
04: *
05: * The contents of this file are subject to the Mozilla Public License Version
06: * 1.1 (the "License"); you may not use this file except in compliance with
07: * the License. Alternatively, the contents of this file may be used under
08: * the terms of the GNU Lesser General Public License Version 2.1 or later.
09: *
10: * Software distributed under the License is distributed on an "AS IS" basis,
11: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12: * for the specific language governing rights and limitations under the
13: * License.
14: */
15:
16: package javassist.convert;
17:
18: import javassist.bytecode.*;
19: import javassist.ClassPool;
20: import javassist.CtClass;
21: import javassist.CtField;
22: import javassist.NotFoundException;
23: import javassist.Modifier;
24:
25: public class TransformReadField extends Transformer {
26: protected String fieldname;
27: protected CtClass fieldClass;
28: protected boolean isPrivate;
29: protected String methodClassname, methodName;
30:
31: public TransformReadField(Transformer next, CtField field,
32: String methodClassname, String methodName) {
33: super (next);
34: this .fieldClass = field.getDeclaringClass();
35: this .fieldname = field.getName();
36: this .methodClassname = methodClassname;
37: this .methodName = methodName;
38: this .isPrivate = Modifier.isPrivate(field.getModifiers());
39: }
40:
41: static String isField(ClassPool pool, ConstPool cp, CtClass fclass,
42: String fname, boolean is_private, int index) {
43: if (!cp.getFieldrefName(index).equals(fname))
44: return null;
45:
46: try {
47: CtClass c = pool.get(cp.getFieldrefClassName(index));
48: if (c == fclass
49: || (!is_private && isFieldInSuper(c, fclass, fname)))
50: return cp.getFieldrefType(index);
51: } catch (NotFoundException e) {
52: }
53: return null;
54: }
55:
56: static boolean isFieldInSuper(CtClass clazz, CtClass fclass,
57: String fname) {
58: if (!clazz.subclassOf(fclass))
59: return false;
60:
61: try {
62: CtField f = clazz.getField(fname);
63: return f.getDeclaringClass() == fclass;
64: } catch (NotFoundException e) {
65: }
66: return false;
67: }
68:
69: public int transform(CtClass tclazz, int pos,
70: CodeIterator iterator, ConstPool cp) throws BadBytecode {
71: int c = iterator.byteAt(pos);
72: if (c == GETFIELD || c == GETSTATIC) {
73: int index = iterator.u16bitAt(pos + 1);
74: String typedesc = isField(tclazz.getClassPool(), cp,
75: fieldClass, fieldname, isPrivate, index);
76: if (typedesc != null) {
77: if (c == GETSTATIC) {
78: iterator.move(pos);
79: iterator.insertGap(1); // insertGap() may insert 4 bytes.
80: iterator.writeByte(ACONST_NULL, pos);
81: pos = iterator.next();
82: }
83:
84: String type = "(Ljava/lang/Object;)" + typedesc;
85: int mi = cp.addClassInfo(methodClassname);
86: int methodref = cp.addMethodrefInfo(mi, methodName,
87: type);
88: iterator.writeByte(INVOKESTATIC, pos);
89: iterator.write16bit(methodref, pos + 1);
90: return pos;
91: }
92: }
93:
94: return pos;
95: }
96: }
|