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