Source code: com/chaoswg/xtc4y/classdesc/code/Code.java
1 //$Header: /cvsroot/xtc4y/xtc4y/src/com/chaoswg/xtc4y/classdesc/code/Code.java,v 1.2 2003/08/26 12:38:22 toggm Exp $
2 /******************************************************************************
3 * XTC4y - eXtreme Testing Collection 4 you *
4 * -------------------------------------------------------------------------- *
5 * URL: http://www.chaoswg.com/xtc4y *
6 * Author: Mike Toggweiler (2.dog@gmx.ch) *
7 * *
8 * Last Updated: $Date: 2003/08/26 12:38:22 $, by $Author: toggm $ *
9 * Version: $Revision: 1.2 $ *
10 * -------------------------------------------------------------------------- *
11 * COPYRIGHT: (c) 2003 by Mike Toggweiler *
12 * *
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU General Public License as published by *
15 * the Free Software Foundation; either version 2 of the License, or *
16 * (at your option) any later version. *
17 *****************************************************************************/
18 package com.chaoswg.xtc4y.classdesc.code;
19
20 import java.util.Vector;
21
22 import java.io.DataInputStream;
23 import java.io.DataOutputStream;
24 import java.io.IOException;
25
26 import com.chaoswg.xtc4y.classdesc.ConstantPool;
27 import com.chaoswg.xtc4y.classdesc.code.instructions.InstructionDisassembler;
28 import com.chaoswg.xtc4y.classdesc.code.instructions.Instruction;
29
30 /**
31 * This class represents the code of a method. It consists of a set of
32 * instructions
33 * @author Mike Toggweiler
34 **/
35 public class Code {
36 private Vector instructions = new Vector();
37
38 /**
39 * Creates the Code and initializes it from a DataInputStream
40 * @param dis the DataInputStream to read from
41 * @param cp the constant pool to resolve indices
42 * @param length the length of the code
43 **/
44 public Code(DataInputStream dis, ConstantPool cp, int length)
45 throws IOException {
46 for (int i=0; i<length; ) {
47 Instruction instr =
48 InstructionDisassembler.fetchInstruction(dis, cp);
49 //set the index of the instruction
50 instr.setIndex((short)i);
51 instructions.add(instr);
52 int size = instr.getNumberOfUsedBytes();
53 //fill vector with dummy entries that indices are still correct
54 for (int j=1; j<size; ++j) {
55 instructions.add(new Object());
56 }
57 i += size;
58 }
59
60 //resolve indices
61 for (int i=0; i<instructions.size(); ++i) {
62 Object obj = instructions.elementAt(i);
63 if (obj instanceof Instruction) {
64 ((Instruction)obj).resolveIndices(this);
65 }
66 }
67 }
68
69 /**
70 * Create a new empty code container
71 **/
72 public Code() {
73 }
74
75 /**
76 * @return the instruction at a given position
77 **/
78 public Instruction getInstructionAt(short index) {
79 if (instructions.elementAt(index) instanceof Instruction) {
80 return (Instruction)instructions.elementAt(index);
81 }
82 return null;
83 }
84
85 /**
86 * @return the index of the last instruction
87 **/
88 public short getLastInstructionIndex() {
89 for (int i=instructions.size()-1; i>0; --i) {
90 if (instructions.elementAt(i) instanceof Instruction) {
91 return (short)i;
92 }
93 }
94 return (short)-1;
95 }
96
97 /**
98 * Add an instruction
99 * @param instruction
100 **/
101 public void addInstruction(Instruction instruction) {
102 instructions.add(instruction);
103 //set index of instruction
104 instruction.setIndex((short)(instructions.size()-1));
105
106 int size = instruction.getNumberOfUsedBytes();
107 //fill vector with dummy entries that indices are still correct
108 for (int i=1; i<size; ++i) {
109 instructions.add(new Object());
110 }
111 }
112
113 /**
114 * Insert an instruction at a given position
115 * @param instruction to add
116 * @param index the index, beginning by 0
117 **/
118 public void insertInstructionAt(Instruction instruction, int index) {
119 instructions.insertElementAt(instruction, index);
120 //set index of instruction
121 instruction.setIndex((short)index);
122
123 int size = instruction.getNumberOfUsedBytes();
124 //fill vector with dummy entries that indices are still correct
125 for (int i=1; i<size; ++i) {
126 instructions.insertElementAt(new Object(), index+1);
127 }
128 }
129
130 /**
131 * @return the index of an instruction
132 **/
133 public short getIndexOf(Instruction instr) {
134 return (short)instructions.indexOf(instr);
135 }
136
137 /**
138 * @return the length of the code (number of used bytes)
139 **/
140 public int getLength() {
141 return instructions.size();
142 }
143
144 /**
145 * Write the instruction onto the DataOutputStream, using the
146 * constant pool to register variables. .
147 * @param dos the DataOutputStream to write on
148 * @param cp The constant pool to register variables
149 **/
150 public void write(DataOutputStream dos, ConstantPool cp)
151 throws IOException {
152 //first reset all indices for a correct resolution if the code
153 //was modified
154 for (int i=0; i<instructions.size(); ++i) {
155 Object obj = instructions.elementAt(i);
156 if (obj instanceof Instruction) {
157 //set the current index, may have changed since read in
158 ((Instruction)obj).setIndex((short)i);
159 }
160 }
161 for (int i=0; i<instructions.size(); ++i) {
162 Object obj = instructions.elementAt(i);
163 if (obj instanceof Instruction) {
164 //ignore dummy entries
165 ((Instruction)obj).write(dos, cp);
166 }
167 }
168 }
169
170 /**
171 * Write code in a readable way
172 **/
173 public String toString() {
174 int index = 0;
175 String ret = "";
176 for (int i=0; i<instructions.size(); ++i, ++index) {
177 Object obj = instructions.elementAt(i);
178 if (obj instanceof Instruction) {
179 ret += ((Instruction)obj).toString() + "\n";
180 }
181 }
182
183 return ret;
184 }
185 }
186