00001 package de.fub.bytecode.generic;
00002
00003 import de.fub.bytecode.Constants;
00004 import de.fub.bytecode.classfile.*;
00005 import java.util.Hashtable;
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 public class ConstantPoolGen {
00022 protected int size = 1024;
00023 protected Constant[] constants = new Constant[size];
00024 protected int index = 1;
00025
00026 private static final String METHODREF_DELIM = ":";
00027 private static final String IMETHODREF_DELIM = "#";
00028 private static final String FIELDREF_DELIM = "&";
00029 private static final String NAT_DELIM = "%";
00030
00031 private static class Index {
00032 int index;
00033 Index(int i) { index = i; }
00034 }
00035
00036 private Hashtable string_table = new Hashtable();
00037
00038 private Hashtable class_table = new Hashtable();
00039
00040 private Hashtable n_a_t_table = new Hashtable();
00041
00042 private Hashtable cp_table = new Hashtable();
00043
00044
00045
00046
00047 public ConstantPoolGen() {}
00048
00049
00050
00051
00052
00053 public ConstantPoolGen(Constant[] cs) {
00054 if(cs.length > size) {
00055 size = cs.length;
00056 constants = new Constant[size];
00057 }
00058
00059 System.arraycopy(cs, 0, constants, 0, cs.length);
00060
00061 if(cs.length > 0)
00062 index = cs.length;
00063
00064 for(int i=1; i < index; i++) {
00065 Constant c = constants[i];
00066
00067 if(c instanceof ConstantString) {
00068 ConstantString s = (ConstantString)c;
00069 ConstantUtf8 u8 = (ConstantUtf8)constants[s.getStringIndex()];
00070
00071 string_table.put(u8.getBytes(), new Index(i));
00072 } else if(c instanceof ConstantClass) {
00073 ConstantClass s = (ConstantClass)c;
00074 ConstantUtf8 u8 = (ConstantUtf8)constants[s.getNameIndex()];
00075
00076 class_table.put(u8.getBytes(), new Index(i));
00077 } else if(c instanceof ConstantNameAndType) {
00078 ConstantNameAndType n = (ConstantNameAndType)c;
00079 ConstantUtf8 u8 = (ConstantUtf8)constants[n.getNameIndex()];
00080 ConstantUtf8 u8_2 = (ConstantUtf8)constants[n.getSignatureIndex()];
00081
00082 n_a_t_table.put(u8.getBytes() + NAT_DELIM + u8_2.getBytes(), new Index(i));
00083 } else if(c instanceof ConstantCP) {
00084 ConstantCP m = (ConstantCP)c;
00085 ConstantClass clazz = (ConstantClass)constants[m.getClassIndex()];
00086 ConstantNameAndType n = (ConstantNameAndType)constants[m.getNameAndTypeIndex()];
00087
00088 ConstantUtf8 u8 = (ConstantUtf8)constants[clazz.getNameIndex()];
00089 String class_name = u8.getBytes().replace('/', '.');
00090
00091 u8 = (ConstantUtf8)constants[n.getNameIndex()];
00092 String method_name = u8.getBytes();
00093
00094 u8 = (ConstantUtf8)constants[n.getSignatureIndex()];
00095 String signature = u8.getBytes();
00096
00097 String delim = METHODREF_DELIM;
00098
00099 if(c instanceof ConstantInterfaceMethodref)
00100 delim = IMETHODREF_DELIM;
00101 else if(c instanceof ConstantFieldref)
00102 delim = FIELDREF_DELIM;
00103
00104 cp_table.put(class_name + delim + method_name + delim + signature, new Index(i));
00105 }
00106 }
00107 }
00108
00109
00110
00111 public ConstantPoolGen(ConstantPool cp) {
00112 this(cp.getConstantPool());
00113 }
00114
00115
00116
00117
00118
00119
00120
00121 public int addArrayClass(ArrayType type) {
00122 return addClass_(type.getSignature());
00123 }
00124
00125
00126
00127
00128
00129
00130 public int addClass(ObjectType type) {
00131 return addClass(type.getClassName());
00132 }
00133
00134
00135
00136
00137
00138
00139 public int addClass(String str) {
00140 return addClass_(str.replace('.', '/'));
00141 }
00142 private int addClass_(String clazz) {
00143 int ret;
00144
00145 if((ret = lookupClass(clazz)) != -1)
00146 return ret;
00147
00148 adjustSize();
00149
00150 ConstantClass c = new ConstantClass(addUtf8(clazz));
00151
00152 ret = index;
00153 constants[index++] = c;
00154
00155 class_table.put(clazz, new Index(ret));
00156
00157 return ret;
00158 }
00159
00160
00161
00162
00163
00164
00165 public int addDouble(double n) {
00166 int ret;
00167
00168 if((ret = lookupDouble(n)) != -1)
00169 return ret;
00170
00171 adjustSize();
00172
00173 ret = index;
00174 constants[index] = new ConstantDouble(n);
00175 index += 2;
00176
00177 return ret;
00178 }
00179
00180
00181
00182
00183
00184
00185
00186 public int addFieldref(String class_name, String field_name, String signature) {
00187 int ret;
00188 int class_index, name_and_type_index;
00189
00190 if((ret = lookupFieldref(class_name, field_name, signature)) != -1)
00191 return ret;
00192
00193 adjustSize();
00194
00195 class_index = addClass(class_name);
00196 name_and_type_index = addNameAndType(field_name, signature);
00197 ret = index;
00198 constants[index++] = new ConstantFieldref(class_index, name_and_type_index);
00199
00200 cp_table.put(class_name + FIELDREF_DELIM + field_name + FIELDREF_DELIM + signature, new Index(ret));
00201
00202 return ret;
00203 }
00204
00205
00206
00207
00208
00209
00210 public int addFloat(float n) {
00211 int ret;
00212
00213 if((ret = lookupFloat(n)) != -1)
00214 return ret;
00215
00216 adjustSize();
00217
00218 ret = index;
00219 constants[index++] = new ConstantFloat(n);
00220
00221 return ret;
00222 }
00223
00224
00225
00226
00227
00228
00229 public int addInteger(int n) {
00230 int ret;
00231
00232 if((ret = lookupInteger(n)) != -1)
00233 return ret;
00234
00235 adjustSize();
00236
00237 ret = index;
00238 constants[index++] = new ConstantInteger(n);
00239
00240 return ret;
00241 }
00242 public int addInterfaceMethodref(MethodGen method) {
00243 return addInterfaceMethodref(method.getClassName(), method.getName(),
00244 method.getSignature());
00245 }
00246
00247
00248
00249
00250
00251
00252
00253 public int addInterfaceMethodref(String class_name, String method_name, String signature) {
00254 int ret, class_index, name_and_type_index;
00255
00256 if((ret = lookupInterfaceMethodref(class_name, method_name, signature)) != -1)
00257 return ret;
00258
00259 adjustSize();
00260
00261 class_index = addClass(class_name);
00262 name_and_type_index = addNameAndType(method_name, signature);
00263 ret = index;
00264 constants[index++] = new ConstantInterfaceMethodref(class_index, name_and_type_index);
00265
00266 cp_table.put(class_name + IMETHODREF_DELIM + method_name +
00267 IMETHODREF_DELIM + signature, new Index(ret));
00268
00269 return ret;
00270 }
00271
00272
00273
00274
00275
00276
00277 public int addLong(long n) {
00278 int ret;
00279
00280 if((ret = lookupLong(n)) != -1)
00281 return ret;
00282
00283 adjustSize();
00284
00285 ret = index;
00286 constants[index] = new ConstantLong(n);
00287 index += 2;
00288
00289 return ret;
00290 }
00291 public int addMethodref(MethodGen method) {
00292 return addMethodref(method.getClassName(), method.getName(),
00293 method.getSignature());
00294 }
00295
00296
00297
00298
00299
00300
00301
00302 public int addMethodref(String class_name, String method_name, String signature) {
00303 int ret, class_index, name_and_type_index;
00304
00305 if((ret = lookupMethodref(class_name, method_name, signature)) != -1)
00306 return ret;
00307
00308 adjustSize();
00309
00310 name_and_type_index = addNameAndType(method_name, signature);
00311 class_index = addClass(class_name);
00312 ret = index;
00313 constants[index++] = new ConstantMethodref(class_index, name_and_type_index);
00314
00315 cp_table.put(class_name + METHODREF_DELIM + method_name +
00316 METHODREF_DELIM + signature, new Index(ret));
00317
00318 return ret;
00319 }
00320
00321
00322
00323
00324
00325
00326
00327 public int addNameAndType(String name, String signature) {
00328 int ret;
00329 int name_index, signature_index;
00330
00331 if((ret = lookupNameAndType(name, signature)) != -1)
00332 return ret;
00333
00334 adjustSize();
00335
00336 name_index = addUtf8(name);
00337 signature_index = addUtf8(signature);
00338 ret = index;
00339 constants[index++] = new ConstantNameAndType(name_index, signature_index);
00340
00341 n_a_t_table.put(name + NAT_DELIM + signature, new Index(ret));
00342 return ret;
00343 }
00344
00345
00346
00347
00348
00349
00350 public int addString(String str) {
00351 int ret;
00352
00353 if((ret = lookupString(str)) != -1)
00354 return ret;
00355
00356 adjustSize();
00357
00358 ConstantUtf8 u8 = new ConstantUtf8(str);
00359 ConstantString s = new ConstantString(index);
00360
00361 constants[index++] = u8;
00362 ret = index;
00363 constants[index++] = s;
00364
00365 string_table.put(str, new Index(ret));
00366
00367 return ret;
00368 }
00369
00370
00371
00372
00373
00374
00375 public int addUtf8(String n) {
00376 int ret;
00377
00378 if((ret = lookupUtf8(n)) != -1)
00379 return ret;
00380
00381 adjustSize();
00382
00383 ret = index;
00384 constants[index++] = new ConstantUtf8(n);
00385
00386 return ret;
00387 }
00388
00389
00390 protected void adjustSize() {
00391 if(index + 3 >= size) {
00392 Constant[] cs = constants;
00393
00394 size *= 2;
00395 constants = new Constant[size];
00396 System.arraycopy(cs, 0, constants, 0, index);
00397 }
00398 }
00399
00400
00401
00402
00403 public Constant getConstant(int i) { return constants[i]; }
00404
00405
00406
00407 public ConstantPool getConstantPool() {
00408 return new ConstantPool(constants);
00409 }
00410
00411
00412
00413 public ConstantPool getFinalConstantPool() {
00414 Constant[] cs = new Constant[index];
00415
00416 System.arraycopy(constants, 0, cs, 0, index);
00417
00418 return new ConstantPool(cs);
00419 }
00420
00421
00422
00423 public int getSize() {
00424 return index;
00425 }
00426
00427
00428
00429
00430
00431
00432 public int lookupClass(String str) {
00433 Index index = (Index)class_table.get(str.replace('.', '/'));
00434 return (index != null)? index.index : -1;
00435 }
00436
00437
00438
00439
00440
00441
00442 public int lookupDouble(double n) {
00443 for(int i=1; i < index; i++) {
00444 if(constants[i] instanceof ConstantDouble) {
00445 ConstantDouble c = (ConstantDouble)constants[i];
00446
00447 if(c.getBytes() == n)
00448 return i;
00449 }
00450 }
00451
00452 return -1;
00453 }
00454
00455
00456
00457
00458
00459
00460
00461
00462 public int lookupFieldref(String class_name, String field_name, String signature) {
00463 Index index = (Index)cp_table.get(class_name + FIELDREF_DELIM + field_name +
00464 FIELDREF_DELIM + signature);
00465 return (index != null)? index.index : -1;
00466 }
00467
00468
00469
00470
00471
00472
00473 public int lookupFloat(float n) {
00474 for(int i=1; i < index; i++) {
00475 if(constants[i] instanceof ConstantFloat) {
00476 ConstantFloat c = (ConstantFloat)constants[i];
00477
00478 if(c.getBytes() == n)
00479 return i;
00480 }
00481 }
00482
00483 return -1;
00484 }
00485
00486
00487
00488
00489
00490
00491 public int lookupInteger(int n) {
00492 for(int i=1; i < index; i++) {
00493 if(constants[i] instanceof ConstantInteger) {
00494 ConstantInteger c = (ConstantInteger)constants[i];
00495
00496 if(c.getBytes() == n)
00497 return i;
00498 }
00499 }
00500
00501 return -1;
00502 }
00503 public int lookupInterfaceMethodref(MethodGen method) {
00504 return lookupInterfaceMethodref(method.getClassName(), method.getName(),
00505 method.getSignature());
00506 }
00507
00508
00509
00510
00511
00512
00513
00514
00515 public int lookupInterfaceMethodref(String class_name, String method_name, String signature) {
00516 Index index = (Index)cp_table.get(class_name + IMETHODREF_DELIM + method_name +
00517 IMETHODREF_DELIM + signature);
00518 return (index != null)? index.index : -1;
00519 }
00520
00521
00522
00523
00524
00525
00526 public int lookupLong(long n) {
00527 for(int i=1; i < index; i++) {
00528 if(constants[i] instanceof ConstantLong) {
00529 ConstantLong c = (ConstantLong)constants[i];
00530
00531 if(c.getBytes() == n)
00532 return i;
00533 }
00534 }
00535
00536 return -1;
00537 }
00538 public int lookupMethodref(MethodGen method) {
00539 return lookupMethodref(method.getClassName(), method.getName(),
00540 method.getSignature());
00541 }
00542
00543
00544
00545
00546
00547
00548
00549
00550 public int lookupMethodref(String class_name, String method_name, String signature) {
00551 Index index = (Index)cp_table.get(class_name + METHODREF_DELIM + method_name +
00552 METHODREF_DELIM + signature);
00553 return (index != null)? index.index : -1;
00554 }
00555
00556
00557
00558
00559
00560
00561
00562 public int lookupNameAndType(String name, String signature) {
00563 Index index = (Index)n_a_t_table.get(name + NAT_DELIM + signature);
00564 return (index != null)? index.index : -1;
00565 }
00566
00567
00568
00569
00570
00571
00572 public int lookupString(String str) {
00573 Index index = (Index)string_table.get(str);
00574 return (index != null)? index.index : -1;
00575 }
00576
00577
00578
00579
00580
00581
00582 public int lookupUtf8(String n) {
00583 for(int i=1; i < index; i++) {
00584 if(constants[i] instanceof ConstantUtf8) {
00585 ConstantUtf8 c = (ConstantUtf8)constants[i];
00586
00587 if(c.getBytes().equals(n))
00588 return i;
00589 }
00590 }
00591
00592 return -1;
00593 }
00594
00595
00596
00597
00598
00599
00600 public void setConstant(int i, Constant c) { constants[i] = c; }
00601
00602
00603
00604 public String toString() {
00605 StringBuffer buf = new StringBuffer();
00606
00607 for(int i=1; i < index; i++)
00608 buf.append(i + ")" + constants[i] + "\n");
00609
00610 return buf.toString();
00611 }
00612 }