KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jarg > MethodReshaper


1 /* ====================================================================
2  * Copyright (c) 2002, Hidetoshi Ohuchi <hchacha@users.sourceforge.net>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * Neither the name of the hchacha nor the names of its contributors
17  * may be used to endorse or promote products derived from this
18  * software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  * ====================================================================
33  */

34 package jarg;
35
36 import org.apache.bcel.classfile.*;
37 import org.apache.bcel.generic.*;
38 import org.apache.bcel.Constants;
39
40 /**
41  * The class for reshaping methods in the class.
42  *
43  * @version $Id: MethodReshaper.java,v 1.6 2002/07/26 18:22:52 hchacha Exp $
44  * @author Hidetoshi Ohuchi &lt;hchacha@users.sourceforge.net&gt;
45  */

46 class MethodReshaper {
47    private Jarg app;
48    private PackageHandler pkgh;
49
50    MethodReshaper(Jarg app, PackageHandler pkgh) {
51       this.app = app;
52       this.pkgh = pkgh;
53    }
54
55    Method reshapeMethod(JavaClass jcls, ConstantPoolGen cpg0, ClassGen cg, ConstantPoolGen cpg, Method m) {
56       m.setConstantPool(jcls.getConstantPool());
57
58       MethodGen mg0 = new MethodGen(m, jcls.getClassName(), cpg0);
59
60       int m_access_flags = m.getAccessFlags();
61       Type m_return_type = mg0.getReturnType();
62       Type[] m_arg_types = mg0.getArgumentTypes();
63       String JavaDoc[] m_arg_names = null;
64       String JavaDoc m_old_class_name = jcls.getClassName();
65       String JavaDoc m_class_name = pkgh.convClassName(m_old_class_name);
66       String JavaDoc m_method_name = pkgh.convMethodName(m_old_class_name, m.getName(), m.getSignature());
67       Code m_code = m.getCode();
68       InstructionList m_il = null;
69 // System.out.println(" reshaping method " + m_method_name);
70

71       if (m_code != null) {
72          m_il = new InstructionList(m_code.getCode());
73       }
74
75       LocalVariableGen[] lvs = mg0.getLocalVariables();
76
77       if (!mg0.isAbstract() && !mg0.isNative()) {
78          m_arg_names = new String JavaDoc[m_arg_types.length];
79          if (mg0.isStatic()) {
80             for (int j=0; j < m_arg_names.length && j < lvs.length; j++) {
81                LocalVariableGen lv = lvs[j];
82                m_arg_names[j] = lv.getName();
83             }
84          } else {
85             for (int j=0; j < m_arg_names.length && j < lvs.length-1; j++) {
86                LocalVariableGen lv = lvs[j+1];
87                m_arg_names[j] = lv.getName();
88             }
89          }
90       }
91
92       // argument
93
for (int j=0; j<m_arg_types.length; j++) {
94          Type t = m_arg_types[j];
95          Type tt = Type.getType(pkgh.convSignature(t.getSignature()));
96          m_arg_types[j] = tt;
97       }
98
99       // return type
100
m_return_type = Type.getType(pkgh.convSignature(m_return_type.getSignature()));
101
102       //
103
MethodGen mg = new MethodGen(m_access_flags, m_return_type, m_arg_types, m_arg_names, m_method_name, m_class_name, m_il, cpg);
104       if (app.isRemoveLocalVariable) {
105          mg.stripAttributes(true);
106       }
107
108       // Exceptions
109
if (!app.isRemoveExceptions) {
110          String JavaDoc[] es = mg0.getExceptions();
111          for (int j=0; j < es.length; j++) {
112             mg.addException(es[j]);
113          }
114       }
115
116       if (!mg0.isAbstract() && !mg0.isNative()) {
117          // local variables
118
int localstart = m_arg_names.length;
119          if (!mg0.isStatic()) {
120             localstart ++;
121          }
122          for (int j=localstart; j < lvs.length; j++) {
123             LocalVariableGen lv = lvs[j];
124             mg.addLocalVariable(lv.getName(), lv.getType(), lv.getIndex(), lv.getStart(), lv.getEnd());
125          }
126
127          // instructions
128
InstructionList il = mg.getInstructionList();
129          InstructionHandle[] ihs = il.getInstructionHandles();
130          for (int j=0; j < ihs.length; j++) {
131             InstructionHandle ih = ihs[j];
132             reshapeMethodInstruction(cpg0, cpg, m, ih);
133          }
134
135          // exceptions
136
InstructionList il0 = mg0.getInstructionList();
137          InstructionHandle[] ihs0 = il0.getInstructionHandles();
138          CodeExceptionGen[] cegs = mg0.getExceptionHandlers();
139          for (int j=0; j < cegs.length; j++) {
140             CodeExceptionGen ceg = cegs[j];
141             reshapeMethodCodeException(mg, ceg, ihs0, ihs);
142          }
143
144          // line numbers
145
LineNumberGen[] lgs = mg0.getLineNumbers();
146          for (int j=0; j < lgs.length; j++) {
147             LineNumberGen lg = lgs[j];
148             mg.addLineNumber(lg.getInstruction(), lg.getSourceLine());
149          }
150
151          // code attributes
152
{
153             Attribute[] ats = mg0.getCodeAttributes();
154             for (int j=0; j<ats.length; j++) {
155                Attribute at = ats[j];
156                if (at instanceof StackMap) {
157 // StackMap oldsm = (StackMap)at;
158
// reshapeCodeAttributeStackMap(cpg0, cpg, mg, oldsm);
159
} else {
160                   System.err.println("[ERR CODE ATTR]" + at);
161                }
162             }
163          }
164       }
165
166       // method attributes
167
{
168          Attribute[] ats = mg0.getAttributes();
169          for (int j=0; j<ats.length; j++) {
170             Attribute at = ats[j];
171             if (at instanceof Synthetic) {
172                if (!app.isRemoveSynthetic) {
173                   Synthetic st = (Synthetic)at;
174                   int s_name_index = cpg.addUtf8("Synthetic");
175                   int s_len = st.getLength();
176                   byte[] s_bytes = st.getBytes();
177                   mg.addAttribute(new Synthetic(s_name_index, s_len, s_bytes, cpg.getConstantPool()));
178                }
179             } else if (at instanceof Deprecated JavaDoc) {
180                Deprecated JavaDoc dp = (Deprecated JavaDoc)at;
181                int s_name_index = cpg.addUtf8("Deprecated");
182                int s_len = dp.getLength();
183                byte[] s_bytes = dp.getBytes();
184                mg.addAttribute(new Deprecated JavaDoc(s_name_index, s_len, s_bytes, cpg.getConstantPool()));
185             } else {
186                System.err.println("[ERR METHOD ATTR]" + ats[j]);
187             }
188          }
189       }
190
191       // calc max locals
192
{
193          mg.setMaxLocals();
194          int mxl = mg.getMaxLocals();
195          int a2;
196          if (mg.isStatic()) {
197             a2 = m_arg_types.length;
198          } else {
199             a2 = m_arg_types.length + 1;
200          }
201          for (int j=0; j<m_arg_types.length; j++) {
202             Type t = m_arg_types[j];
203             byte b = t.getType();
204             if (b == Type.LONG.getType()) {
205                a2 ++;
206             } else if (b == Type.DOUBLE.getType()) {
207                a2 ++;
208             }
209          }
210          if (mxl < a2) {
211             mg.setMaxLocals(a2);
212          }
213       }
214       mg.setMaxStack();
215
216       if (app.isRemoveLocalVariable) {
217          mg.removeLocalVariables();
218       }
219       if (app.isRemoveLineNumber) {
220          mg.removeLineNumbers();
221       }
222
223       return mg.getMethod();
224    }
225
226    private void reshapeMethodInstruction(ConstantPoolGen cpg0, ConstantPoolGen cpg, Method m, InstructionHandle ih) {
227       Instruction is = ih.getInstruction();
228       int idx;
229       if (is instanceof FieldInstruction) {
230          FieldInstruction fis = (FieldInstruction)is;
231          String JavaDoc fr_old_class_name = fis.getClassName(cpg0);
232          String JavaDoc fr_class_name = pkgh.convClassName(fr_old_class_name);
233          String JavaDoc fr_field_name = pkgh.convFieldName(fr_old_class_name, fis.getFieldName(cpg0));
234          String JavaDoc fr_signature = pkgh.convSignature(fis.getSignature(cpg0));
235          idx = cpg.addFieldref(fr_class_name, fr_field_name, fr_signature);
236          fis.setIndex(idx);
237       } else if (is instanceof InvokeInstruction) {
238          InvokeInstruction mis = (InvokeInstruction)is;
239          String JavaDoc mr_old_class_name = mis.getClassName(cpg0);
240          String JavaDoc mr_old_signature = mis.getSignature(cpg0);
241          String JavaDoc mr_class_name = pkgh.convClassName(mr_old_class_name);
242          String JavaDoc mr_method_name = pkgh.convMethodName(mr_old_class_name, mis.getMethodName(cpg0), mr_old_signature);
243          String JavaDoc mr_signature = pkgh.convSignatureM(mr_old_signature);
244          if (mis instanceof INVOKEINTERFACE) {
245             idx = cpg.addInterfaceMethodref(mr_class_name, mr_method_name, mr_signature);
246          } else {
247             idx = cpg.addMethodref(mr_class_name, mr_method_name, mr_signature);
248          }
249          mis.setIndex(idx);
250       } else if (is instanceof CPInstruction) {
251          CPInstruction cpis = (CPInstruction)is;
252          idx = cpis.getIndex();
253          ConstantUtf8 c8;
254          ConstantClass ccls;
255          ConstantNameAndType cnt;
256          ConstantPool cc = m.getConstantPool();
257          Constant c = cc.getConstant(idx);
258          switch (c.getTag()) {
259          case Constants.CONSTANT_Utf8:
260             break;
261          case Constants.CONSTANT_String:
262             idx = ((ConstantString)c).getStringIndex();
263             c8 = (ConstantUtf8)cc.getConstant(idx);
264             idx = cpg.addString(c8.getBytes());
265             cpis.setIndex(idx);
266             break;
267          case Constants.CONSTANT_Integer:
268             idx = cpg.addInteger(((ConstantInteger)c).getBytes());
269             cpis.setIndex(idx);
270             break;
271          case Constants.CONSTANT_Float:
272             idx = cpg.addFloat(((ConstantFloat)c).getBytes());
273             cpis.setIndex(idx);
274             break;
275          case Constants.CONSTANT_Long:
276             idx = cpg.addLong(((ConstantLong)c).getBytes());
277             cpis.setIndex(idx);
278             break;
279          case Constants.CONSTANT_Double:
280             idx = cpg.addDouble(((ConstantDouble)c).getBytes());
281             cpis.setIndex(idx);
282             break;
283          case Constants.CONSTANT_Class:
284             idx = ((ConstantClass)c).getNameIndex();
285             c8 = (ConstantUtf8)cc.getConstant(idx);
286             idx = cpg.addClass(pkgh.convClassName(c8.getBytes()));
287             cpis.setIndex(idx);
288             break;
289          case Constants.CONSTANT_Fieldref:
290             break;
291          case Constants.CONSTANT_InterfaceMethodref:
292             break;
293          case Constants.CONSTANT_NameAndType:
294             break;
295          default:
296             break;
297          }
298       }
299    }
300
301    private void reshapeMethodCodeException(MethodGen mg, CodeExceptionGen ceg, InstructionHandle[] ihs0, InstructionHandle[] ihs) {
302       InstructionHandle start_pc = null;
303       InstructionHandle end_pc = null;
304       InstructionHandle handler_pc = null;
305
306       InstructionHandle start_pc0 = ceg.getStartPC();
307       InstructionHandle end_pc0 = ceg.getEndPC();
308       InstructionHandle handler_pc0 = ceg.getHandlerPC();
309
310       for (int x=0; x < ihs0.length; x++) {
311          if (start_pc0 == ihs0[x]) {
312             start_pc = ihs[x];
313          }
314          if (end_pc0 == ihs0[x]) {
315             end_pc = ihs[x];
316          }
317          if (handler_pc0 == ihs0[x]) {
318             handler_pc = ihs[x];
319          }
320       }
321
322       ObjectType catch_type0 = ceg.getCatchType();
323       ObjectType catch_type = null;
324       if (catch_type0 != null) {
325          catch_type = new ObjectType(pkgh.convClassName(catch_type0.getClassName()));
326       }
327       mg.addExceptionHandler(start_pc, end_pc, handler_pc, catch_type);
328    }
329
330 /*
331    private void reshapeCodeAttributeStackMap(ConstantPoolGen cpg0, ConstantPoolGen cpg, MethodGen mg, StackMap oldsm) {
332       StackMapEntry[] old_smes = oldsm.getStackMap();
333       StackMapEntry[] new_smes = new StackMapEntry[old_smes.length];
334       for (int k=0; k<old_smes.length; k++) {
335          StackMapEntry old_sme = old_smes[k];
336          StackMapType[] old_types_of_locals = old_sme.getTypesOfLocals();
337          StackMapType[] new_types_of_locals = new StackMapType[old_types_of_locals.length];
338          for (int x=0; x<old_types_of_locals.length; x++) {
339             StackMapType old_smt = old_types_of_locals[x];
340             byte type = old_smt.getType();
341             int index = old_smt.getIndex();
342             if (type == Constants.ITEM_Object) {
343                ConstantPool cc = cpg0.getConstantPool();
344                Constant c = cc.getConstant(index);
345                switch (c.getTag()) {
346                case Constants.CONSTANT_Class:
347                   int idx = ((ConstantClass)c).getNameIndex();
348                   ConstantUtf8 c8 = (ConstantUtf8)cc.getConstant(idx);
349                   idx = cpg.addClass(pkgh.convClassName(c8.getBytes()));
350                   index = idx;
351                   break;
352                default:
353                   System.err.println("[ERR CODE ATTR StackMapType]" + c);
354                   break;
355                }
356             }
357             StackMapType new_smt = new StackMapType(type, index, cpg.getConstantPool());
358             new_types_of_locals[x] = new_smt;
359          }
360          StackMapType[] old_types_of_stack_items = old_sme.getTypesOfStackItems();
361          StackMapType[] new_types_of_stack_items = new StackMapType[old_types_of_stack_items.length];
362          for (int x=0; x<old_types_of_stack_items.length; x++) {
363             StackMapType old_smt = old_types_of_stack_items[x];
364             byte type = old_smt.getType();
365             int index = old_smt.getIndex();
366             if (type == Constants.ITEM_Object) {
367                ConstantPool cc = cpg0.getConstantPool();
368                Constant c = cc.getConstant(index);
369                switch (c.getTag()) {
370                case Constants.CONSTANT_Class:
371                   int idx = ((ConstantClass)c).getNameIndex();
372                   ConstantUtf8 c8 = (ConstantUtf8)cc.getConstant(idx);
373                   idx = cpg.addClass(pkgh.convClassName(c8.getBytes()));
374                   index = idx;
375                   break;
376                default:
377                   System.err.println("[ERR CODE ATTR StackMapType]" + c);
378                   break;
379                }
380             }
381             StackMapType new_smt = new StackMapType(type, index, cpg.getConstantPool());
382             new_types_of_stack_items[x] = new_smt;
383          }
384
385          StackMapEntry new_sme = new StackMapEntry(
386             old_sme.getByteCodeOffset(),
387             new_types_of_locals.length, new_types_of_locals,
388             new_types_of_stack_items.length, new_types_of_stack_items,
389             cpg.getConstantPool());
390          new_smes[k] = new_sme;
391       }
392
393       int name_index = 0;
394       {
395          int index = oldsm.getNameIndex();
396          ConstantPool cc = cpg0.getConstantPool();
397          Constant c = cc.getConstant(index);
398          switch (c.getTag()) {
399          case Constants.CONSTANT_Utf8:
400             ConstantUtf8 c8 = (ConstantUtf8)c;
401             name_index = cpg.addUtf8(c8.getBytes());
402             break;
403          default:
404             System.err.println("[ERR CODE ATTR StackMap]" + c);
405             break;
406          }
407       }
408       StackMap sm = new StackMap(name_index, new_smes.length, new_smes, cpg.getConstantPool());
409       mg.addCodeAttribute(sm);
410    }
411 */

412 }
413
Popular Tags