00001 package gov.nasa.arc.ase.jpf.jvm.reflection;
00002
00003 import gov.nasa.arc.ase.jpf.InternalErrorException;
00004 import gov.nasa.arc.ase.util.*;
00005 import gov.nasa.arc.ase.jpf.jvm.*;
00006 import gov.nasa.arc.ase.jpf.jvm.bytecode.ATHROW;
00007 import gov.nasa.arc.ase.util.Debug;
00008 import de.fub.bytecode.Constants;
00009 import gov.nasa.arc.ase.jpf.jvm.bytecode.Instruction;
00010
00011 public class Reflection implements Cloneable, Constants {
00012
00013
00014
00015 private static String[] reflectionPath = {
00016 "gov.nasa.arc.ase.jpf.jvm.reflection", ""
00017 };
00018
00019
00020
00021
00022 protected ClassInfo ci;
00023
00024
00025
00026
00027 protected int objref;
00028
00029
00030
00031
00032 protected SystemState ss;
00033
00034
00035
00036
00037 protected KernelState ks;
00038
00039
00040
00041
00042 protected ThreadInfo th;
00043
00044
00045
00046
00047 protected DynamicArea da;
00048
00049
00050
00051
00052 protected StaticArea sa;
00053
00054
00055
00056
00057 public Reflection() {
00058 ci = null;
00059 objref = -1;
00060 ss = null;
00061 ks = null;
00062 th = null;
00063 da = null;
00064 sa = null;
00065 }
00066
00067
00068
00069 protected boolean[] asBooleanArray() {
00070 return da.get(objref).asBooleanArray();
00071 }
00072
00073
00074
00075 protected byte[] asByteArray() {
00076 return da.get(objref).asByteArray();
00077 }
00078
00079
00080
00081 protected char[] asCharArray() {
00082 return da.get(objref).asCharArray();
00083 }
00084
00085
00086
00087 protected double[] asDoubleArray() {
00088 return da.get(objref).asDoubleArray();
00089 }
00090
00091
00092
00093 protected float[] asFloatArray() {
00094 return da.get(objref).asFloatArray();
00095 }
00096
00097
00098
00099 protected int[] asIntArray() {
00100 return da.get(objref).asIntArray();
00101 }
00102
00103
00104
00105 protected long[] asLongArray() {
00106 return da.get(objref).asLongArray();
00107 }
00108
00109
00110
00111 protected Reflection[] asObjectArray() {
00112 return da.get(objref).asObjectArray();
00113 }
00114
00115
00116
00117 protected short[] asShortArray() {
00118 return da.get(objref).asShortArray();
00119 }
00120
00121
00122
00123 protected String asString() {
00124 return da.get(objref).asString();
00125 }
00126
00127
00128
00129
00130 protected Instruction executeMethod(MethodInfo mi) {
00131 if(mi.isNative()) {
00132 throw new NativeMethodException(mi.getFullName());
00133 }
00134
00135 mi.enter(th);
00136
00137 return start();
00138 }
00139
00140
00141
00142 public final Instruction executeMethod(ThreadInfo th, MethodInfo mi) {
00143 setThreadInfo(th);
00144 Instruction i = executeMethod(mi);
00145 setThreadInfo(null);
00146
00147 return i;
00148 }
00149
00150
00151
00152
00153 protected Instruction executeStaticMethod(MethodInfo mi) {
00154 if(mi.isNative()) {
00155 throw new NativeMethodException(mi.getFullName());
00156 }
00157
00158 mi.enter(th);
00159
00160 return start();
00161 }
00162
00163
00164
00165 public final Instruction executeStaticMethod(ThreadInfo th, MethodInfo mi) {
00166 setThreadInfo(th);
00167 Instruction i = executeStaticMethod(mi);
00168 setThreadInfo(null);
00169
00170 return i;
00171 }
00172
00173
00174
00175 protected final Instruction exit() {
00176 MethodInfo mi = th.getMethod();
00177 th.popFrame();
00178 th.removeArguments(mi);
00179
00180 if(th.getPC() == null) return null;
00181
00182 return th.getPC().getNext();
00183 }
00184
00185
00186
00187 protected Instruction exit(byte retval) {
00188 return exit((int)retval);
00189 }
00190
00191
00192
00193 protected Instruction exit(char retval) {
00194 return exit((int)retval);
00195 }
00196
00197
00198
00199 protected Instruction exit(double retval) {
00200 return exit(Types.doubleToLong(retval));
00201 }
00202
00203
00204
00205 protected Instruction exit(float retval) {
00206 return exit(Types.floatToInt(retval));
00207 }
00208
00209
00210
00211 protected Instruction exit(int retval) {
00212 MethodInfo mi = th.getMethod();
00213 th.popFrame();
00214 th.removeArguments(mi);
00215 th.push(retval, false);
00216
00217 return th.getPC().getNext();
00218 }
00219
00220
00221
00222 protected Instruction exit(long retval) {
00223 MethodInfo mi = th.getMethod();
00224 th.popFrame();
00225 th.removeArguments(mi);
00226 th.longPush(retval);
00227
00228 return th.getPC().getNext();
00229 }
00230
00231
00232
00233 protected Instruction exit(Reflection retval) {
00234 return exitReference(retval.objref);
00235 }
00236
00237
00238
00239 protected Instruction exit(short retval) {
00240 return exit((int)retval);
00241 }
00242
00243
00244
00245 protected Instruction exit(boolean retval) {
00246 return exit(Types.booleanToInt(retval));
00247 }
00248
00249
00250
00251 protected Instruction exitReference(int retval) {
00252 MethodInfo mi = th.getMethod();
00253 th.popFrame();
00254 th.removeArguments(mi);
00255 th.push(retval, true);
00256
00257 return th.getPC().getNext();
00258 }
00259 public String getArrayType() {
00260 return da.get(objref).getArrayType();
00261 }
00262 public int getArrayTypeSize() {
00263 return Types.getTypeSize(getArrayType());
00264 }
00265
00266
00267
00268 protected boolean getBooleanArgument(int index) {
00269 return Types.intToBoolean(getIntArgument(index));
00270 }
00271
00272
00273
00274 public boolean getBooleanArrayElement(int index) {
00275 return Types.intToBoolean(getIntArrayElement(index * getArrayTypeSize()));
00276 }
00277
00278
00279
00280 public boolean getBooleanField(String fname) {
00281 return Types.intToBoolean(getIntField(fname));
00282 }
00283
00284
00285
00286 public boolean getBooleanStaticField(String fname) {
00287 return Types.intToBoolean(getIntStaticField(fname));
00288 }
00289
00290
00291
00292 protected byte getByteArgument(int index) {
00293 return (byte)getIntArgument(index);
00294 }
00295
00296
00297
00298 public byte getByteArrayElement(int index) {
00299 return (byte)getIntArrayElement(index * getArrayTypeSize());
00300 }
00301
00302
00303
00304 public byte getByteField(String fname) {
00305 return (byte)getIntField(fname);
00306 }
00307
00308
00309
00310 public byte getByteStaticField(String fname) {
00311 return (byte)getIntStaticField(fname);
00312 }
00313
00314
00315
00316 protected char getCharArgument(int index) {
00317 return (char)getIntArgument(index);
00318 }
00319
00320
00321
00322 public char getCharArrayElement(int index) {
00323 return (char)getIntArrayElement(index * getArrayTypeSize());
00324 }
00325
00326
00327
00328 public char getCharField(String fname) {
00329 return (char)getIntField(fname);
00330 }
00331
00332
00333
00334 public char getCharStaticField(String fname) {
00335 return (char)getIntStaticField(fname);
00336 }
00337
00338
00339
00340 protected double getDoubleArgument(int index) {
00341 return Types.longToDouble(getLongArgument(index));
00342 }
00343
00344
00345
00346 public double getDoubleArrayElement(int index) {
00347 return Types.longToDouble(getLongArrayElement(index * getArrayTypeSize()));
00348 }
00349
00350
00351
00352 public double getDoubleField(String fname) {
00353 return Types.longToDouble(getLongField(fname));
00354 }
00355
00356
00357
00358 public double getDoubleStaticField(String fname) {
00359 return Types.longToDouble(getLongStaticField(fname));
00360 }
00361
00362
00363
00364 protected float getFloatArgument(int index) {
00365 return Types.intToFloat(getIntArgument(index));
00366 }
00367
00368
00369
00370 public float getFloatArrayElement(int index) {
00371 return Types.intToFloat(getIntArrayElement(index * getArrayTypeSize()));
00372 }
00373
00374
00375
00376 public float getFloatField(String fname) {
00377 return Types.intToFloat(getIntField(fname));
00378 }
00379
00380
00381
00382 public float getFloatStaticField(String fname) {
00383 return Types.intToFloat(getIntStaticField(fname));
00384 }
00385
00386
00387
00388 protected int getIntArgument(int idx) {
00389 return th.getLocalVariable(idx);
00390 }
00391
00392
00393
00394 public int getIntArrayElement(int index) {
00395 return da.get(objref).getField(index);
00396 }
00397
00398
00399
00400 public int getIntField(String fname) {
00401 return da.get(objref).getField(fname);
00402 }
00403
00404
00405
00406 public int getIntStaticField(String fname) {
00407 return sa.get(ci.getName()).getField(fname);
00408 }
00409
00410
00411
00412 protected long getLongArgument(int idx) {
00413 return th.getLongLocalVariable(idx);
00414 }
00415
00416
00417
00418 public long getLongArrayElement(int index) {
00419 return da.get(objref).getLongField(index);
00420 }
00421
00422
00423
00424 public long getLongField(String fname) {
00425 return da.get(objref).getLongField(fname);
00426 }
00427
00428
00429
00430 public long getLongStaticField(String fname) {
00431 return sa.get(ci.getName()).getLongField(fname);
00432 }
00433
00434
00435
00436 protected Reflection getObjectArgument(int idx) {
00437 Reflection r = da.get(getIntArgument(idx)).getReflection();
00438 r.setThreadInfo(th);
00439
00440 return r;
00441 }
00442
00443
00444
00445 public Reflection getObjectArrayElement(int index) {
00446 Reflection r = da.get(getIntArrayElement(index * getArrayTypeSize())).getReflection();
00447 r.setThreadInfo(th);
00448
00449 return r;
00450 }
00451
00452
00453
00454 public Reflection getObjectField(String fname) {
00455 Reflection r = da.get(getIntField(fname)).getReflection();
00456 r.setThreadInfo(th);
00457
00458 return r;
00459 }
00460
00461
00462
00463 public Reflection getObjectStaticField(String fname) {
00464 Reflection r = da.get(getIntStaticField(fname)).getReflection();
00465 r.setThreadInfo(th);
00466
00467 return r;
00468 }
00469
00470
00471
00472 protected static Reflection getReflection(String classname) {
00473 return ClassInfo.getClassInfo(classname).getReflection();
00474 }
00475
00476
00477
00478 protected short getShortArgument(int index) {
00479 return (short)getIntArgument(index);
00480 }
00481
00482
00483
00484 public short getShortArrayElement(int index) {
00485 return (short)getIntArrayElement(index * getArrayTypeSize());
00486 }
00487
00488
00489
00490 public short getShortField(String fname) {
00491 return (short)getIntField(fname);
00492 }
00493
00494
00495
00496 public short getShortStaticField(String fname) {
00497 return (short)getIntStaticField(fname);
00498 }
00499
00500
00501
00502 protected String getStringArgument(int index) {
00503 return da.get(getIntArgument(index)).asString();
00504 }
00505 public Reflection instantiate() {
00506 try {
00507 Reflection r = (Reflection)clone();
00508 r.objref = -1;
00509
00510 return r;
00511 } catch(CloneNotSupportedException e) {
00512 return null;
00513 }
00514 }
00515
00516
00517
00518 public Reflection instantiate(int objref) {
00519 try {
00520 Reflection r = (Reflection)clone();
00521 r.objref = objref;
00522
00523 return r;
00524 } catch(CloneNotSupportedException e) {
00525 return null;
00526 }
00527 }
00528
00529
00530
00531 protected boolean isMethodDeterministic(MethodInfo mi) {
00532 return true;
00533 }
00534
00535
00536
00537 public final boolean isMethodDeterministic(ThreadInfo th, MethodInfo mi) {
00538 setThreadInfo(th);
00539 boolean result = isMethodDeterministic(mi);
00540 setThreadInfo(null);
00541
00542 return result;
00543 }
00544
00545
00546
00547 protected boolean isMethodExecutable(MethodInfo mi) {
00548 return mi.canEnter(th);
00549 }
00550
00551
00552
00553 public final boolean isMethodExecutable(ThreadInfo th, MethodInfo mi) {
00554 setThreadInfo(th);
00555 boolean result = isMethodExecutable(mi);
00556 setThreadInfo(null);
00557
00558 return result;
00559 }
00560
00561
00562
00563 protected boolean isStaticMethodDeterministic(MethodInfo mi) {
00564 return true;
00565 }
00566
00567
00568
00569 public final boolean isStaticMethodDeterministic(ThreadInfo th, MethodInfo mi) {
00570 setThreadInfo(th);
00571 boolean result = isStaticMethodDeterministic(mi);
00572 setThreadInfo(null);
00573
00574 return result;
00575 }
00576
00577
00578
00579 protected boolean isStaticMethodExecutable(MethodInfo mi) {
00580 return mi.canEnter(th);
00581 }
00582
00583
00584
00585 public final boolean isStaticMethodExecutable(ThreadInfo th, MethodInfo mi) {
00586 setThreadInfo(th);
00587 boolean result = isStaticMethodExecutable(mi);
00588 setThreadInfo(null);
00589
00590 return result;
00591 }
00592
00593
00594
00595 public static Reflection load(String name) {
00596 Reflection r = null;
00597 int l = reflectionPath.length;
00598
00599 for(int i = 0; i < l && r == null; i++) {
00600 String cn;
00601
00602 if(reflectionPath[i].equals(""))
00603 cn = name + "Reflection";
00604 else
00605 cn = reflectionPath[i] + "." + name + "Reflection";
00606
00607 try {
00608 Class clazz = Class.forName(cn);
00609 r = (Reflection)clazz.newInstance();
00610 Debug.println(Debug.MESSAGE, "Loading class " + cn);
00611 } catch(InstantiationException e) {
00612 throw new InternalErrorException("Can't instantiate " + cn);
00613 } catch(IllegalAccessException e) {
00614 throw new InternalErrorException("Can't instantiate " + cn);
00615 } catch(ClassNotFoundException e) {
00616 }
00617 }
00618
00619 for(int i = 0; i < l && r == null; i++) {
00620 String cn;
00621
00622 if(reflectionPath[i].equals(""))
00623 cn = reflectionClassName(name) + "Reflection";
00624 else
00625 cn = reflectionPath[i] + "." + reflectionClassName(name) + "Reflection";
00626
00627 try {
00628 Class clazz = Class.forName(cn);
00629 r = (Reflection)clazz.newInstance();
00630 Debug.println(Debug.WARNING, "Loading class " + cn);
00631 } catch(InstantiationException e) {
00632 throw new InternalErrorException("Can't instantiate " + cn);
00633 } catch(IllegalAccessException e) {
00634 throw new InternalErrorException("Can't instantiate " + cn);
00635 } catch(ClassNotFoundException e) {
00636 }
00637 }
00638
00639 if(r == null) r = new Reflection();
00640
00641 return r;
00642 }
00643
00644
00645
00646
00647 private static String reflectionClassName(String name) {
00648 int index = 0;
00649 int last = 0;
00650 StringBuffer sb = new StringBuffer();
00651
00652 while((index = name.indexOf(".", last)) != -1) {
00653 sb.append(Character.toUpperCase(name.charAt(last)));
00654 sb.append(name.substring(last + 1, index));
00655 last = index + 1;
00656 }
00657
00658 sb.append(name.substring(last));
00659
00660 return sb.toString();
00661 }
00662
00663
00664
00665 protected Instruction repeat() {
00666 th.popFrame();
00667
00668 return th.getPC();
00669 }
00670
00671
00672
00673 public void setBooleanStaticField(String fname, boolean value) {
00674 setIntStaticField(fname, Types.booleanToInt(value));
00675 }
00676
00677
00678
00679 public void setBooleanValue(int index, boolean value) {
00680 setIntArrayElement(index * getArrayTypeSize(), Types.booleanToInt(value));
00681 }
00682
00683
00684
00685 public void setBooleanValue(String fname, boolean value) {
00686 setIntField(fname, Types.booleanToInt(value));
00687 }
00688
00689
00690
00691 public void setByteArrayElement(int index, byte value) {
00692 setIntArrayElement(index * getArrayTypeSize(), (int)value);
00693 }
00694
00695
00696
00697 public void setByteField(String fname, byte value) {
00698 setIntField(fname, (int)value);
00699 }
00700
00701
00702
00703 public void setByteStaticField(String fname, byte value) {
00704 setIntStaticField(fname, (int)value);
00705 }
00706
00707
00708
00709 public void setCharArrayElement(int index, char value) {
00710 setIntArrayElement(index * getArrayTypeSize(), (int)value);
00711 }
00712
00713
00714
00715 public void setCharField(String fname, char value) {
00716 setIntField(fname, (int)value);
00717 }
00718
00719
00720
00721 public void setCharStaticField(String fname, char value) {
00722 setIntStaticField(fname, (int)value);
00723 }
00724
00725
00726
00727 public void setClassInfo(ClassInfo c) {
00728 ci = c;
00729 }
00730
00731
00732
00733 public void setDoubleArrayElement(int index, double value) {
00734 setLongArrayElement(index * getArrayTypeSize(), Types.doubleToLong(value));
00735 }
00736
00737
00738
00739 public void setDoubleField(String fname, double value) {
00740 setLongField(fname, Types.doubleToLong(value));
00741 }
00742
00743
00744
00745 public void setDoubleStaticField(String fname, double value) {
00746 setLongStaticField(fname, Types.doubleToLong(value));
00747 }
00748
00749
00750
00751 public void setFloatArrayElement(int index, float value) {
00752 setIntArrayElement(index * getArrayTypeSize(), Types.floatToInt(value));
00753 }
00754
00755
00756
00757 public void setFloatField(String fname, float value) {
00758 setIntField(fname, Types.floatToInt(value));
00759 }
00760
00761
00762
00763 public void setFloatStaticField(String fname, float value) {
00764 setIntStaticField(fname, Types.floatToInt(value));
00765 }
00766
00767
00768
00769 public void setIntArrayElement(int index, int value) {
00770 da.get(objref).setField(index, value);
00771 }
00772
00773
00774
00775 public void setIntField(String fname, int value) {
00776 da.get(objref).setField(fname, value);
00777 }
00778
00779
00780
00781 public void setIntStaticField(String fname, int value) {
00782 sa.get(ci.getName()).setField(fname, value);
00783 }
00784
00785
00786
00787 public void setLongArrayElement(int index, long value) {
00788 da.get(objref).setLongField(index, value);
00789 }
00790
00791
00792
00793 public void setLongField(String fname, long value) {
00794 da.get(objref).setLongField(fname, value);
00795 }
00796
00797
00798
00799 public void setLongStaticField(String fname, long value) {
00800 sa.get(ci.getName()).setLongField(fname, value);
00801 }
00802
00803
00804
00805 public void setObjectArrayElement(int index, Reflection value) {
00806 if(value == null)
00807 setIntArrayElement(index * getArrayTypeSize(), -1);
00808 else
00809 setIntArrayElement(index * getArrayTypeSize(), value.objref);
00810 }
00811
00812
00813
00814 public void setObjectField(String fname, Reflection value) {
00815 if(value == null)
00816 setIntField(fname, -1);
00817 else
00818 setIntField(fname, value.objref);
00819 }
00820
00821
00822
00823 public void setObjectStaticField(String fname, Reflection value) {
00824 if(value == null)
00825 setIntStaticField(fname, -1);
00826 else
00827 setIntStaticField(fname, value.objref);
00828 }
00829
00830
00831
00832 public void setReferenceField(String fname, int value) {
00833 setIntField(fname, value);
00834 }
00835
00836
00837
00838 public void setReferenceStaticField(String fname, int value) {
00839 setIntStaticField(fname, value);
00840 }
00841
00842
00843
00844 public void setShortArrayElement(int index, short value) {
00845 setIntArrayElement(index * getArrayTypeSize(), (int)value);
00846 }
00847
00848
00849
00850 public void setShortField(String fname, short value) {
00851 setIntField(fname, (int)value);
00852 }
00853
00854
00855
00856 public void setShortStaticField(String fname, short value) {
00857 setIntStaticField(fname, (int)value);
00858 }
00859
00860
00861
00862 private void setThreadInfo(ThreadInfo th) {
00863 if(th == null) {
00864 this.th = null;
00865 ss = null;
00866 ks = null;
00867 da = null;
00868 sa = null;
00869 } else {
00870 this.th = th;
00871 ks = th.list.ks;
00872 ss = ks.ss;
00873 da = ks.da;
00874 sa = ks.sa;
00875 }
00876 }
00877
00878
00879
00880 protected final Instruction start() {
00881 return th.getPC();
00882 }
00883
00884
00885
00886 protected Instruction throwException(String classname) {
00887 ClassInfo ci = ClassInfo.getClassInfo(classname);
00888
00889 MethodInfo mi = th.getMethod();
00890 th.popFrame();
00891 th.removeArguments(mi);
00892
00893 return th.createAndThrowException(ci);
00894 }
00895 }