Home | History | Annotate | Download | only in convert
      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 
     16 package javassist.convert;
     17 
     18 import javassist.CtClass;
     19 import javassist.CtField;
     20 import javassist.bytecode.*;
     21 
     22 final 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