1/*
2 * Javassist, a Java-bytecode translator toolkit.
3 * Copyright (C) 1999-2007 Shigeru Chiba. All Rights Reserved.
4 *
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License.  Alternatively, the contents of this file may be used under
8 * the terms of the GNU Lesser General Public License Version 2.1 or later.
9 *
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
16package javassist.convert;
17
18import javassist.CtClass;
19import javassist.CtField;
20import javassist.bytecode.*;
21
22final public class TransformWriteField extends TransformReadField {
23    public TransformWriteField(Transformer next, CtField field,
24                               String methodClassname, String methodName)
25    {
26        super(next, field, methodClassname, methodName);
27    }
28
29    public int transform(CtClass tclazz, int pos, CodeIterator iterator,
30                         ConstPool cp) throws BadBytecode
31    {
32        int c = iterator.byteAt(pos);
33        if (c == PUTFIELD || c == PUTSTATIC) {
34            int index = iterator.u16bitAt(pos + 1);
35            String typedesc = isField(tclazz.getClassPool(), cp,
36                                fieldClass, fieldname, isPrivate, index);
37            if (typedesc != null) {
38                if (c == PUTSTATIC) {
39                    CodeAttribute ca = iterator.get();
40                    iterator.move(pos);
41                    char c0 = typedesc.charAt(0);
42                    if (c0 == 'J' || c0 == 'D') {       // long or double
43                        // insertGap() may insert 4 bytes.
44                        pos = iterator.insertGap(3);
45                        iterator.writeByte(ACONST_NULL, pos);
46                        iterator.writeByte(DUP_X2, pos + 1);
47                        iterator.writeByte(POP, pos + 2);
48                        ca.setMaxStack(ca.getMaxStack() + 2);
49                    }
50                    else {
51                        // insertGap() may insert 4 bytes.
52                        pos = iterator.insertGap(2);
53                        iterator.writeByte(ACONST_NULL, pos);
54                        iterator.writeByte(SWAP, pos + 1);
55                        ca.setMaxStack(ca.getMaxStack() + 1);
56                    }
57
58                    pos = iterator.next();
59                }
60
61                int mi = cp.addClassInfo(methodClassname);
62                String type = "(Ljava/lang/Object;" + typedesc + ")V";
63                int methodref = cp.addMethodrefInfo(mi, methodName, type);
64                iterator.writeByte(INVOKESTATIC, pos);
65                iterator.write16bit(methodref, pos + 1);
66            }
67        }
68
69        return pos;
70    }
71}
72