2 * Copyright (C) 2014, United States Government, as represented by the
3 * Administrator of the National Aeronautics and Space Administration.
6 * The Java Pathfinder core (jpf-core) platform is licensed under the
7 * Apache License, Version 2.0 (the "License"); you may not use this file except
8 * in compliance with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0.
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package gov.nasa.jpf.vm;
20 import com.sun.org.apache.bcel.internal.generic.InstructionConstants;
21 import gov.nasa.jpf.Config;
22 import gov.nasa.jpf.JPF;
23 import gov.nasa.jpf.JPFException;
24 import gov.nasa.jpf.JPFListener;
25 import gov.nasa.jpf.vm.serialize.UnknownJPFClass;
27 import java.util.Date;
28 import java.util.Locale;
32 * MJIEnv is the call environment for "native" methods, i.e. code that
33 * is executed by the VM, not by JPF.
35 * Since library abstractions are supposed to be "user code", we provide
36 * this class as a (little bit of) insulation towards the inner JPF workings.
38 * There are two APIs exported by this class. The public methods (like
39 * getStringObject) don't expose JPF internals, and can be used from non
40 * gov.nasa.jpf.vm NativePeer classes). The rest is package-default
41 * and can be used to fiddle around as much as you like to (if you are in
44 * Note that MJIEnv objects are now per-ThreadInfo (i.e. the variable
45 * call envionment only includes MethodInfo and ClassInfo), which means
46 * MJIEnv can be used in non-native methods (but only carefully, if you
47 * don't need mi or ciMth).
49 * Note also this only works because we are not getting recursive in
50 * native method calls. In fact, the whole DirectCallStackFrame / repeatTopInstruction
51 * mechanism is there to turn logial recursion (JPF calling native, calling
52 * JPF, calling native,..) into iteration. Otherwise we couldn't backtrack
55 public static final int NULL = 0;
58 ClassInfo ciMth; // the ClassInfo of the method this is called from
63 // those are various attributes set by the execution. note that
64 // NativePeer.invoke never gets recursive in a roundtrip (at least if
65 // used correctly, so we don't have to be afraid to overwrite any of these
69 // exception to be thrown upon return from native method
70 // NOTE: this is only transient - don't expect this to be preserved over
71 // transition boundaries
74 MJIEnv (ThreadInfo ti) {
77 // set those here so that we don't have an inconsistent state between
78 // creation of an MJI object and the first native method call in
79 // this thread (where any access to the heap or sa would bomb)
90 public JPF getJPF () {
94 public boolean isBigEndianPlatform(){
95 return vm.isBigEndianPlatform();
98 public void addListener (JPFListener l){
99 vm.getJPF().addListener(l);
102 public void removeListener (JPFListener l){
103 vm.getJPF().removeListener(l);
106 public Config getConfig() {
107 return vm.getConfig();
114 public void forceState (){
115 getSystemState().setForced(true);
118 public void ignoreTransition () {
119 getSystemState().setIgnored(true);
122 public boolean isArray (int objref) {
123 return heap.get(objref).isArray();
126 public int getArrayLength (int objref) {
127 if (isArray(objref)) {
128 return heap.get(objref).arrayLength();
130 throwException("java.lang.IllegalArgumentException");
136 public String getArrayType (int objref) {
137 return heap.get(objref).getArrayType();
140 public int getArrayTypeSize (int objref) {
141 return Types.getTypeSize(getArrayType(objref));
144 //=== various attribute accessors ============================================
145 // we only support some attribute APIs here, since MJIEnv adds little value
146 // other than hiding the ElementInfo access. If the client already has
147 // an ElementInfo reference, it should use that one to retrieve/enumerate/set
148 // attributes since this avoids repeated Heap.get() calls
150 //--- object attributes
152 public boolean hasObjectAttr (int objref){
154 ElementInfo ei = heap.get(objref);
155 return ei.hasObjectAttr();
161 public boolean hasObjectAttr (int objref, Class<?> type){
163 ElementInfo ei = heap.get(objref);
164 return ei.hasObjectAttr(type);
171 * this returns all of them - use either if you know there will be only
172 * one attribute at a time, or check/process result with ObjectList
174 public Object getObjectAttr (int objref){
176 ElementInfo ei = heap.get(objref);
177 return ei.getObjectAttr();
183 * this replaces all of them - use only if you know
184 * - there will be only one attribute at a time
185 * - you obtained the value you set by a previous getXAttr()
186 * - you constructed a multi value list with ObjectList.createList()
188 public void setObjectAttr (int objref, Object a){
190 ElementInfo ei = heap.get(objref);
195 public void addObjectAttr (int objref, Object a){
197 ElementInfo ei = heap.getModifiable(objref);
204 * this only returns the first attr of this type, there can be more
205 * if you don't use client private types or the provided type is too general
207 public <T> T getObjectAttr (int objref, Class<T> attrType){
208 ElementInfo ei = heap.get(objref);
209 return ei.getObjectAttr(attrType);
212 //--- field attributes
214 public boolean hasFieldAttr (int objref){
216 ElementInfo ei = heap.get(objref);
217 return ei.hasFieldAttr();
223 public boolean hasFieldAttr (int objref, Class<?> type){
225 ElementInfo ei = heap.get(objref);
226 return ei.hasFieldAttr(type);
233 * this returns all of them - use either if you know there will be only
234 * one attribute at a time, or check/process result with ObjectList
236 public Object getFieldAttr (int objref, String fname){
237 ElementInfo ei = heap.get(objref);
238 FieldInfo fi = ei.getFieldInfo(fname);
240 return ei.getFieldAttr(fi);
242 throw new JPFException("no such field: " + fname);
247 * this replaces all of them - use only if you know
248 * - there will be only one attribute at a time
249 * - you obtained the value you set by a previous getXAttr()
250 * - you constructed a multi value list with ObjectList.createList()
252 public void setFieldAttr (int objref, String fname, Object a){
254 ElementInfo ei = heap.get(objref);
255 FieldInfo fi = ei.getFieldInfo(fname);
256 ei.setFieldAttr(fi, a);
260 public void addFieldAttr (int objref, String fname, Object a){
262 ElementInfo ei = heap.getModifiable(objref);
263 FieldInfo fi = ei.getFieldInfo(fname);
264 ei.addFieldAttr(fi, a);
270 * this only returns the first attr of this type, there can be more
271 * if you don't use client private types or the provided type is too general
273 public <T> T getFieldAttr (int objref, String fname, Class<T> attrType){
274 ElementInfo ei = heap.get(objref);
275 FieldInfo fi = ei.getFieldInfo(fname);
277 return ei.getFieldAttr(fi, attrType);
279 throw new JPFException("no such field: " + fname);
286 public boolean hasElementdAttr (int objref){
288 ElementInfo ei = heap.get(objref);
289 return ei.hasElementAttr();
295 public boolean hasElementAttr (int objref, Class<?> type){
297 ElementInfo ei = heap.get(objref);
298 return ei.hasElementAttr(type);
305 * this returns all of them - use either if you know there will be only
306 * one attribute at a time, or check/process result with ObjectList
308 public Object getElementAttr (int objref, int idx){
309 ElementInfo ei = heap.get(objref);
310 return ei.getElementAttr(idx);
314 * this replaces all of them - use only if you know
315 * - there will be only one attribute at a time
316 * - you obtained the value you set by a previous getXAttr()
317 * - you constructed a multi value list with ObjectList.createList()
319 public void setElementAttr (int objref, int idx, Object a){
320 ElementInfo ei = heap.get(objref);
321 ei.setElementAttr(idx, a);
324 public void addElementAttr (int objref, int idx, Object a){
325 ElementInfo ei = heap.getModifiable(objref);
326 ei.addElementAttr(idx, a);
331 * this only returns the first attr of this type, there can be more
332 * if you don't use client private types or the provided type is too general
334 public <T> T getElementAttr (int objref, int idx, Class<T> attrType){
336 ElementInfo ei = heap.get(objref);
337 return ei.getElementAttr(idx, attrType);
348 // the instance field setters
349 public void setBooleanField (int objref, String fname, boolean val) {
350 heap.getModifiable(objref).setBooleanField(fname, val);
353 public boolean getBooleanField (int objref, String fname) {
354 return heap.get(objref).getBooleanField(fname);
357 public boolean getBooleanArrayElement (int objref, int index) {
358 return heap.get(objref).getBooleanElement(index);
361 public void setBooleanArrayElement (int objref, int index, boolean value) {
362 heap.getModifiable(objref).setBooleanElement(index, value);
366 public void setByteField (int objref, String fname, byte val) {
367 heap.getModifiable(objref).setByteField(fname, val);
370 public byte getByteField (int objref, String fname) {
371 return heap.get(objref).getByteField(fname);
374 public void setCharField (int objref, String fname, char val) {
375 heap.getModifiable(objref).setCharField(fname, val);
378 public char getCharField (int objref, String fname) {
379 return heap.get(objref).getCharField(fname);
382 public void setDoubleField (int objref, String fname, double val) {
383 heap.getModifiable(objref).setDoubleField(fname, val);
386 public double getDoubleField (int objref, String fname) {
387 return heap.get(objref).getDoubleField(fname);
390 public void setFloatField (int objref, String fname, float val) {
391 heap.getModifiable(objref).setFloatField(fname, val);
394 public float getFloatField (int objref, String fname) {
395 return heap.get(objref).getFloatField(fname);
399 public void setByteArrayElement (int objref, int index, byte value) {
400 heap.getModifiable(objref).setByteElement(index, value);
403 public byte getByteArrayElement (int objref, int index) {
404 return heap.get(objref).getByteElement(index);
407 public void setCharArrayElement (int objref, int index, char value) {
408 heap.getModifiable(objref).setCharElement(index, value);
411 public void setIntArrayElement (int objref, int index, int value) {
412 heap.getModifiable(objref).setIntElement(index, value);
415 public void setShortArrayElement (int objref, int index, short value) {
416 heap.getModifiable(objref).setShortElement(index, value);
419 public void setFloatArrayElement (int objref, int index, float value) {
420 heap.getModifiable(objref).setFloatElement(index, value);
423 public float getFloatArrayElement (int objref, int index) {
424 return heap.get(objref).getFloatElement(index);
427 public double getDoubleArrayElement (int objref, int index) {
428 return heap.get(objref).getDoubleElement(index);
430 public void setDoubleArrayElement (int objref, int index, double value) {
431 heap.getModifiable(objref).setDoubleElement(index, value);
434 public short getShortArrayElement (int objref, int index) {
435 return heap.get(objref).getShortElement(index);
438 public int getIntArrayElement (int objref, int index) {
439 return heap.get(objref).getIntElement(index);
442 public char getCharArrayElement (int objref, int index) {
443 return heap.get(objref).getCharElement(index);
446 public void setIntField (int objref, String fname, int val) {
447 ElementInfo ei = heap.getModifiable(objref);
448 ei.setIntField(fname, val);
451 // these two are the workhorses
452 public void setDeclaredIntField (int objref, String refType, String fname, int val) {
453 ElementInfo ei = heap.getModifiable(objref);
454 ei.setDeclaredIntField(fname, refType, val);
457 public int getIntField (int objref, String fname) {
458 ElementInfo ei = heap.get(objref);
459 return ei.getIntField(fname);
462 public int getDeclaredIntField (int objref, String refType, String fname) {
463 ElementInfo ei = heap.get(objref);
464 return ei.getDeclaredIntField(fname, refType);
467 // these two are the workhorses
468 public void setDeclaredReferenceField (int objref, String refType, String fname, int val) {
469 ElementInfo ei = heap.getModifiable(objref);
470 ei.setDeclaredReferenceField(fname, refType, val);
473 public void setReferenceField (int objref, String fname, int ref) {
474 ElementInfo ei = heap.getModifiable(objref);
475 ei.setReferenceField(fname, ref);
478 public int getReferenceField (int objref, String fname) {
479 ElementInfo ei = heap.get(objref);
480 return ei.getReferenceField(fname);
483 // we need this in case of a masked field
484 public int getReferenceField (int objref, FieldInfo fi) {
485 ElementInfo ei = heap.get(objref);
486 return ei.getReferenceField(fi);
489 public String getStringField (int objref, String fname){
490 int ref = getReferenceField(objref, fname);
491 return getStringObject(ref);
494 // the box object accessors (should probably test for the appropriate class)
495 public boolean getBooleanValue (int objref) {
496 return getBooleanField(objref, "value");
499 public byte getByteValue (int objref) {
500 return getByteField(objref, "value");
503 public char getCharValue (int objref) {
504 return getCharField(objref, "value");
507 public short getShortValue (int objref) {
508 return getShortField(objref, "value");
511 public int getIntValue (int objref) {
512 return getIntField(objref, "value");
515 public long getLongValue (int objref) {
516 return getLongField(objref, "value");
519 public float getFloatValue (int objref) {
520 return getFloatField(objref, "value");
523 public double getDoubleValue (int objref) {
524 return getDoubleField(objref, "value");
528 public void setLongArrayElement (int objref, int index, long value) {
529 heap.getModifiable(objref).setLongElement(index, value);
532 public long getLongArrayElement (int objref, int index) {
533 return heap.get(objref).getLongElement(index);
536 public void setLongField (int objref, String fname, long val) {
537 ElementInfo ei = heap.getModifiable(objref);
538 ei.setLongField(fname, val);
541 // public void setLongField (int objref, String refType, String fname, long val) {
542 // ElementInfo ei = heap.get(objref);
543 // ei.setLongField(fname, refType, val);
546 public long getLongField (int objref, String fname) {
547 ElementInfo ei = heap.get(objref);
548 return ei.getLongField(fname);
551 // public long getLongField (int objref, String refType, String fname) {
552 // ElementInfo ei = heap.get(objref);
553 // return ei.getLongField(fname, refType);
556 public void setReferenceArrayElement (int objref, int index, int eRef) {
557 heap.getModifiable(objref).setReferenceElement(index, eRef);
560 public int getReferenceArrayElement (int objref, int index) {
561 return heap.get(objref).getReferenceElement(index);
564 public void setShortField (int objref, String fname, short val) {
565 ElementInfo ei = heap.getModifiable(objref);
566 ei.setShortField(fname, val);
569 public short getShortField (int objref, String fname) {
570 ElementInfo ei = heap.get(objref);
571 return ei.getShortField(fname);
575 * NOTE - this doesn't support element type checks or overlapping in-array copy
577 public void arrayCopy (int srcRef, int srcPos, int dstRef, int dstPos, int len){
578 ElementInfo eiSrc = heap.get(srcRef);
579 ElementInfo eiDst = heap.get(dstRef);
581 eiDst.arrayCopy(eiSrc, srcPos, dstPos, len);
584 public String getTypeName (int objref) {
585 return heap.get(objref).getType();
588 public boolean isInstanceOf (int objref, String clsName) {
589 ClassInfo ci = getClassInfo(objref);
590 return ci.isInstanceOf(clsName);
593 public boolean isInstanceOf (int objref, ClassInfo cls) {
594 ClassInfo ci = getClassInfo(objref);
595 return ci.isInstanceOf(cls);
598 //--- the static field accessors
599 // NOTE - it is the callers responsibility to ensure the class is
600 // properly initialized, since calling <clinit> requires a roundtrip
601 // (i.e. cannot be done synchronously from one of the following methods)
603 // <2do> this uses the current system CL, we should probably use an explicit CL argument
605 public void setStaticBooleanField (String clsName, String fname,
607 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
608 ci.getStaticElementInfo().setBooleanField(fname, value);
610 public void setStaticBooleanField (int clsObjRef, String fname, boolean val) {
611 ElementInfo cei = getStaticElementInfo(clsObjRef);
612 cei.setBooleanField(fname, val);
615 public boolean getStaticBooleanField (String clsName, String fname) {
616 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
617 return ci.getStaticElementInfo().getBooleanField(fname);
620 public void setStaticByteField (String clsName, String fname, byte value) {
621 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
622 ci.getStaticElementInfo().setByteField(fname, value); }
624 public byte getStaticByteField (String clsName, String fname) {
625 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
626 return ci.getStaticElementInfo().getByteField(fname);
629 public void setStaticCharField (String clsName, String fname, char value) {
630 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
631 ci.getStaticElementInfo().setCharField(fname, value); }
633 public char getStaticCharField (String clsName, String fname) {
634 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
635 return ci.getStaticElementInfo().getCharField(fname);
638 public void setStaticDoubleField (String clsName, String fname, double val) {
639 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
640 ci.getStaticElementInfo().setDoubleField(fname, val);
643 public double getStaticDoubleField (String clsName, String fname) {
644 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
645 return ci.getStaticElementInfo().getDoubleField(fname);
648 public double getStaticDoubleField (int clsObjRef, String fname) {
649 ElementInfo cei = getStaticElementInfo(clsObjRef);
650 return cei.getDoubleField(fname);
653 public double getStaticDoubleField (ClassInfo ci, String fname) {
654 ElementInfo ei = ci.getStaticElementInfo();
655 return ei.getDoubleField(fname);
658 public void setStaticFloatField (String clsName, String fname, float val) {
659 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
660 ci.getStaticElementInfo().setFloatField(fname, val);
663 public float getStaticFloatField (String clsName, String fname) {
664 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
665 return ci.getStaticElementInfo().getFloatField(fname);
668 public void setStaticIntField (String clsName, String fname, int val) {
669 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
670 ci.getStaticElementInfo().setIntField(fname, val);
673 public void setStaticIntField (int clsObjRef, String fname, int val) {
674 ElementInfo cei = getStaticElementInfo(clsObjRef);
675 cei.setIntField(fname, val);
678 public int getStaticIntField (String clsName, String fname) {
679 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
680 return ci.getStaticElementInfo().getIntField(fname);
683 public int getStaticIntField (int clsObjRef, String fname) {
684 ElementInfo cei = getStaticElementInfo(clsObjRef);
685 return cei.getIntField(fname);
688 public int getStaticIntField (ClassInfo ci, String fname) {
689 ElementInfo ei = ci.getStaticElementInfo();
690 return ei.getIntField(fname);
693 public void setStaticLongField (String clsName, String fname, long value) {
694 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
695 ci.getStaticElementInfo().setLongField(fname, value);
698 public void setStaticLongField (int clsObjRef, String fname, long val) {
699 ElementInfo cei = getModifiableStaticElementInfo(clsObjRef);
700 cei.setLongField(fname, val);
703 public long getStaticLongField (int clsRef, String fname) {
704 ClassInfo ci = getReferredClassInfo(clsRef);
705 return getStaticLongField(ci, fname);
708 public long getStaticLongField (String clsName, String fname) {
709 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
710 return getStaticLongField(ci, fname);
713 public long getStaticLongField (ClassInfo ci, String fname){
714 ElementInfo ei = ci.getStaticElementInfo();
715 return ei.getLongField(fname);
718 public void setStaticReferenceField (String clsName, String fname, int objref) {
719 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
721 // <2do> - we should REALLY check for type compatibility here
722 ci.getModifiableStaticElementInfo().setReferenceField(fname, objref);
725 public void setStaticReferenceField (int clsObjRef, String fname, int objref) {
726 ElementInfo cei = getModifiableStaticElementInfo(clsObjRef);
728 // <2do> - we should REALLY check for type compatibility here
729 cei.setReferenceField(fname, objref);
732 public int getStaticReferenceField (String clsName, String fname) {
733 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
734 return ci.getStaticElementInfo().getReferenceField(fname);
737 public int getStaticReferenceField (int clsObjRef, String fname) {
738 ElementInfo cei = getStaticElementInfo(clsObjRef);
739 return cei.getReferenceField(fname);
742 public int getStaticReferenceField (ClassInfo ci, String fname){
743 return ci.getStaticElementInfo().getReferenceField(fname);
746 public short getStaticShortField (String clsName, String fname) {
747 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
748 return ci.getStaticElementInfo().getShortField(fname);
751 public char[] getStringChars (int objRef){
752 if (objRef != MJIEnv.NULL) {
753 ElementInfo ei = getElementInfo(objRef);
754 return ei.getStringChars();
763 * turn JPF String object into a VM String object
764 * (this is a method available for non gov..jvm NativePeer classes)
766 public String getStringObject (int objRef) {
767 if (objRef != MJIEnv.NULL) {
768 ElementInfo ei = getElementInfo(objRef);
769 return ei.asString();
776 public String[] getStringArrayObject (int aRef){
779 if (aRef == NULL) return sa;
781 ClassInfo aci = getClassInfo(aRef);
783 ClassInfo eci = aci.getComponentClassInfo();
784 if (eci.getName().equals("java.lang.String")){
785 int len = getArrayLength(aRef);
786 sa = new String[len];
788 for (int i=0; i<len; i++){
789 int sRef = getReferenceArrayElement(aRef,i);
790 sa[i] = getStringObject(sRef);
796 throw new IllegalArgumentException("not a String[] array: " + aci.getName());
799 throw new IllegalArgumentException("not an array reference: " + aci.getName());
803 public Date getDateObject (int objref) {
804 if (objref != MJIEnv.NULL) {
805 ElementInfo ei = getElementInfo(objref);
806 if (ei.getClassInfo().getName().equals("java.util.Date")) {
807 // <2do> this is not complete yet
808 long fastTime = ei.getLongField("fastTime");
809 Date d = new Date(fastTime);
812 throw new JPFException("not a Date object reference: " + ei);
820 public Object[] getArgumentArray (int argRef) {
821 Object[] args = null;
822 if (argRef == NULL) return args;
824 int nArgs = getArrayLength(argRef);
825 args = new Object[nArgs];
827 for (int i=0; i<nArgs; i++){
828 int aref = getReferenceArrayElement(argRef,i);
829 ClassInfo ci = getClassInfo(aref);
830 String clsName = ci.getName();
831 if (clsName.equals("java.lang.Boolean")){
832 args[i] = Boolean.valueOf(getBooleanField(aref,"value"));
833 } else if (clsName.equals("java.lang.Integer")){
834 args[i] = Integer.valueOf(getIntField(aref,"value"));
835 } else if (clsName.equals("java.lang.Double")){
836 args[i] = Double.valueOf(getDoubleField(aref,"value"));
837 } else if (clsName.equals("java.lang.String")){
838 args[i] = getStringObject(aref);
845 public Boolean getBooleanObject (int objref){
846 return Boolean.valueOf(getBooleanField(objref, "value"));
849 public Byte getByteObject (int objref){
850 return new Byte(getByteField(objref, "value"));
853 public Character getCharObject (int objref){
854 return new Character(getCharField(objref, "value"));
857 public Short getShortObject (int objref){
858 return new Short(getShortField(objref, "value"));
861 public Integer getIntegerObject (int objref){
862 return new Integer(getIntField(objref, "value"));
865 public Long getLongObject (int objref){
866 return new Long(getLongField(objref, "value"));
869 public Float getFloatObject (int objref){
870 return new Float(getFloatField(objref, "value"));
873 public Double getDoubleObject (int objref){
874 return new Double(getDoubleField(objref, "value"));
877 // danger - the returned arrays could be used to modify contents of stored objects
879 public byte[] getByteArrayObject (int objref) {
880 ElementInfo ei = getElementInfo(objref);
881 byte[] a = ei.asByteArray();
886 public char[] getCharArrayObject (int objref) {
887 ElementInfo ei = getElementInfo(objref);
888 char[] a = ei.asCharArray();
893 public short[] getShortArrayObject (int objref) {
894 ElementInfo ei = getElementInfo(objref);
895 short[] a = ei.asShortArray();
900 public int[] getIntArrayObject (int objref) {
901 ElementInfo ei = getElementInfo(objref);
902 int[] a = ei.asIntArray();
907 public long[] getLongArrayObject (int objref) {
908 ElementInfo ei = getElementInfo(objref);
909 long[] a = ei.asLongArray();
914 public float[] getFloatArrayObject (int objref) {
915 ElementInfo ei = getElementInfo(objref);
916 float[] a = ei.asFloatArray();
921 public double[] getDoubleArrayObject (int objref) {
922 ElementInfo ei = getElementInfo(objref);
923 double[] a = ei.asDoubleArray();
928 public boolean[] getBooleanArrayObject (int objref) {
929 ElementInfo ei = getElementInfo(objref);
930 boolean[] a = ei.asBooleanArray();
935 public int[] getReferenceArrayObject (int objref){
936 ElementInfo ei = getElementInfo(objref);
937 int[] a = ei.asReferenceArray();
942 public boolean canLock (int objref) {
943 ElementInfo ei = getElementInfo(objref);
945 return ei.canLock(ti);
948 public int newBooleanArray (int size) {
949 return heap.newArray("Z", size, ti).getObjectRef();
952 public int newByteArray (int size) {
953 return heap.newArray("B", size, ti).getObjectRef();
956 public int newByteArray (byte[] buf){
957 ElementInfo eiArray = heap.newArray("B", buf.length, ti);
958 for (int i=0; i<buf.length; i++){
959 eiArray.setByteElement( i, buf[i]);
961 return eiArray.getObjectRef();
964 public int newCharArray (int size) {
965 return heap.newArray("C", size, ti).getObjectRef();
968 public int newCharArray (char[] buf){
969 ElementInfo eiArray = heap.newArray("C", buf.length, ti);
970 for (int i=0; i<buf.length; i++){
971 eiArray.setCharElement( i, buf[i]);
973 return eiArray.getObjectRef();
976 public int newShortArray (int size) {
977 return heap.newArray("S", size, ti).getObjectRef();
980 public int newShortArray (short[] buf){
981 ElementInfo eiArray = heap.newArray("S", buf.length, ti);
982 for (int i=0; i<buf.length; i++){
983 eiArray.setShortElement(i, buf[i]);
985 return eiArray.getObjectRef();
988 public int newDoubleArray (int size) {
989 return heap.newArray("D", size, ti).getObjectRef();
992 public int newDoubleArray (double[] buf){
993 ElementInfo eiArray = heap.newArray("D", buf.length, ti);
994 for (int i=0; i<buf.length; i++){
995 eiArray.setDoubleElement(i, buf[i]);
997 return eiArray.getObjectRef();
1000 public int newFloatArray (int size) {
1001 return heap.newArray("F", size, ti).getObjectRef();
1004 public int newFloatArray (float[] buf){
1005 ElementInfo eiArray = heap.newArray("F", buf.length, ti);
1006 for (int i=0; i<buf.length; i++){
1007 eiArray.setFloatElement( i, buf[i]);
1009 return eiArray.getObjectRef();
1012 public int newIntArray (int size) {
1013 return heap.newArray("I", size, ti).getObjectRef();
1016 public int newIntArray (int[] buf){
1017 ElementInfo eiArray = heap.newArray("I", buf.length, ti);
1018 for (int i=0; i<buf.length; i++){
1019 eiArray.setIntElement( i, buf[i]);
1021 return eiArray.getObjectRef();
1024 public int newLongArray (int size) {
1025 return heap.newArray("J", size, ti).getObjectRef();
1028 public int newLongArray (long[] buf){
1029 ElementInfo eiArray = heap.newArray("J", buf.length, ti);
1030 for (int i=0; i<buf.length; i++){
1031 eiArray.setLongElement( i, buf[i]);
1033 return eiArray.getObjectRef();
1036 public int newObjectArray (String elementClsName, int size) {
1037 if (!elementClsName.endsWith(";")) {
1038 elementClsName = Types.getTypeSignature(elementClsName, false);
1041 return heap.newArray(elementClsName, size, ti).getObjectRef();
1044 public ElementInfo newElementInfo (ClassInfo ci) throws ClinitRequired {
1045 if (ci.initializeClass(ti)){
1046 throw new ClinitRequired(ci);
1049 return heap.newObject(ci, ti);
1053 * check if the ClassInfo is properly initialized
1054 * if yes, create a new instance of it but don't call any ctor
1055 * if no, throw a ClinitRequired exception
1057 public int newObject (ClassInfo ci) throws ClinitRequired {
1058 ElementInfo ei = newElementInfo(ci);
1059 return ei.getObjectRef();
1063 * this creates a new object without checking if the ClassInfo needs
1064 * initialization. This is useful in a context that already
1065 * is aware and handles re-execution
1067 public int newObjectOfUncheckedClass (ClassInfo ci){
1068 ElementInfo ei = heap.newObject(ci, ti);
1069 return ei.getObjectRef();
1072 public ElementInfo newElementInfo (String clsName) throws ClinitRequired, UnknownJPFClass {
1073 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
1075 return newElementInfo(ci);
1077 throw new UnknownJPFClass(clsName);
1081 public int newObject (String clsName) throws ClinitRequired, UnknownJPFClass {
1082 ElementInfo ei = newElementInfo(clsName);
1083 return (ei != null) ? ei.getObjectRef() : NULL;
1086 public int newString (String s) {
1090 return heap.newString(s, ti).getObjectRef();
1094 public int newStringArray (String[] a){
1095 int aref = newObjectArray("Ljava/lang/String;", a.length);
1097 for (int i=0; i<a.length; i++){
1098 setReferenceArrayElement(aref, i, newString(a[i]));
1104 public int newString (int arrayRef) {
1105 String t = getArrayType(arrayRef);
1108 if ("C".equals(t)) { // character array
1109 char[] ca = getCharArrayObject(arrayRef);
1111 } else if ("B".equals(t)) { // byte array
1112 byte[] ba = getByteArrayObject(arrayRef);
1120 return newString(s);
1123 public String format (int fmtRef, int argRef){
1124 String format = getStringObject(fmtRef);
1125 int len = getArrayLength(argRef);
1126 Object[] arg = new Object[len];
1128 for (int i=0; i<len; i++){
1129 int ref = getReferenceArrayElement(argRef,i);
1131 String clsName = getClassName(ref);
1132 if (clsName.equals("java.lang.String")) {
1133 arg[i] = getStringObject(ref);
1134 } else if (clsName.equals("java.lang.Boolean")){
1135 arg[i] = getBooleanObject(ref);
1136 } else if (clsName.equals("java.lang.Byte")) {
1137 arg[i] = getByteObject(ref);
1138 } else if (clsName.equals("java.lang.Char")) {
1139 arg[i] = getCharObject(ref);
1140 } else if (clsName.equals("java.lang.Short")) {
1141 arg[i] = getShortObject(ref);
1142 } else if (clsName.equals("java.lang.Integer")) {
1143 arg[i] = getIntegerObject(ref);
1144 } else if (clsName.equals("java.lang.Long")) {
1145 arg[i] = getLongObject(ref);
1146 } else if (clsName.equals("java.lang.Float")) {
1147 arg[i] = getFloatObject(ref);
1148 } else if (clsName.equals("java.lang.Double")) {
1149 arg[i] = getDoubleObject(ref);
1151 // need a toString() here
1157 return String.format(format,arg);
1160 public String format (Locale l,int fmtRef, int argRef){
1161 String format = getStringObject(fmtRef);
1162 int len = getArrayLength(argRef);
1163 Object[] arg = new Object[len];
1165 for (int i=0; i<len; i++){
1166 int ref = getReferenceArrayElement(argRef,i);
1168 String clsName = getClassName(ref);
1169 if (clsName.equals("java.lang.String")) {
1170 arg[i] = getStringObject(ref);
1171 } else if (clsName.equals("java.lang.Byte")) {
1172 arg[i] = getByteObject(ref);
1173 } else if (clsName.equals("java.lang.Char")) {
1174 arg[i] = getCharObject(ref);
1175 } else if (clsName.equals("java.lang.Short")) {
1176 arg[i] = getShortObject(ref);
1177 } else if (clsName.equals("java.lang.Integer")) {
1178 arg[i] = getIntegerObject(ref);
1179 } else if (clsName.equals("java.lang.Long")) {
1180 arg[i] = getLongObject(ref);
1181 } else if (clsName.equals("java.lang.Float")) {
1182 arg[i] = getFloatObject(ref);
1183 } else if (clsName.equals("java.lang.Double")) {
1184 arg[i] = getDoubleObject(ref);
1186 // need a toString() here
1192 return String.format(l,format,arg);
1196 public int newBoolean (boolean b){
1197 return getStaticReferenceField("java.lang.Boolean", b ? "TRUE" : "FALSE");
1200 public int newInteger (int n){
1201 ElementInfo ei = heap.newObject(ClassLoaderInfo.getSystemResolvedClassInfo("java.lang.Integer"), ti);
1202 ei.setIntField("value",n);
1203 return ei.getObjectRef();
1206 public int newLong (long l){
1207 ElementInfo ei = heap.newObject(ClassLoaderInfo.getSystemResolvedClassInfo("java.lang.Long"), ti);
1208 ei.setLongField("value",l);
1209 return ei.getObjectRef();
1212 public int newDouble (double d){
1213 ElementInfo ei = heap.newObject(ClassLoaderInfo.getSystemResolvedClassInfo("java.lang.Double"), ti);
1214 ei.setDoubleField("value",d);
1215 return ei.getObjectRef();
1218 public int newFloat (float f){
1219 ElementInfo ei = heap.newObject(ClassLoaderInfo.getSystemResolvedClassInfo("java.lang.Float"), ti);
1220 ei.setFloatField("value",f);
1221 return ei.getObjectRef();
1224 public int newByte (byte b){
1225 ElementInfo ei = heap.newObject(ClassLoaderInfo.getSystemResolvedClassInfo("java.lang.Byte"), ti);
1226 ei.setByteField("value",b);
1227 return ei.getObjectRef();
1230 public int newShort (short s){
1231 ElementInfo ei = heap.newObject(ClassLoaderInfo.getSystemResolvedClassInfo("java.lang.Short"), ti);
1232 ei.setShortField("value",s);
1233 return ei.getObjectRef();
1236 public int newCharacter (char c){
1237 ElementInfo ei = heap.newObject(ClassLoaderInfo.getSystemResolvedClassInfo("java.lang.Character"), ti);
1238 ei.setCharField("value",c);
1239 return ei.getObjectRef();
1243 public boolean notify (int objref) {
1244 // objref can't be NULL since the corresponding INVOKE would have failed
1245 ElementInfo ei = getModifiableElementInfo(objref);
1249 public boolean notify (ElementInfo ei) {
1250 if (!ei.isLockedBy(ti)){
1251 throwException("java.lang.IllegalMonitorStateException",
1252 "un-synchronized notify");
1256 return ei.notifies(getSystemState(), ti);
1259 public boolean notifyAll (int objref) {
1260 // objref can't be NULL since the corresponding INVOKE would have failed
1261 ElementInfo ei = getElementInfo(objref);
1262 return notifyAll(ei);
1265 public boolean notifyAll (ElementInfo ei) {
1266 if (!ei.isLockedBy(ti)){
1267 throwException("java.lang.IllegalMonitorStateException",
1268 "un-synchronized notifyAll");
1272 return ei.notifiesAll();
1275 public void registerPinDown(int objref){
1276 heap.registerPinDown(objref);
1278 public void registerPinDown (ElementInfo ei){
1279 registerPinDown(ei.getObjectRef());
1282 public void releasePinDown(int objref){
1283 heap.releasePinDown(objref);
1285 public void releasePinDown (ElementInfo ei){
1286 releasePinDown(ei.getObjectRef());
1290 * use this whenever a peer performs an operation on a class that might not be initialized yet
1291 * Do a repeatInvocation() in this case
1293 public boolean requiresClinitExecution(ClassInfo ci) {
1294 return ci.initializeClass(ti);
1298 * repeat execution of the instruction that caused a native method call
1299 * NOTE - this does NOT mean it's the NEXT executed insn, since the native method
1300 * might have pushed direct call frames on the stack before asking us to repeat it.
1302 public void repeatInvocation () {
1306 public boolean isInvocationRepeated() {
1311 public boolean setNextChoiceGenerator (ChoiceGenerator<?> cg){
1312 return vm.getSystemState().setNextChoiceGenerator(cg);
1315 public void setMandatoryNextChoiceGenerator(ChoiceGenerator<?> cg, String failMsg){
1316 vm.getSystemState().setMandatoryNextChoiceGenerator(cg, failMsg);
1319 public ChoiceGenerator<?> getChoiceGenerator () {
1320 return vm.getSystemState().getChoiceGenerator();
1323 // note this only makes sense if we actually do return something
1324 public void setReturnAttribute (Object attr) {
1329 * return attr list of all arguments. Use ObjectList to retrieve values
1332 * NOTE - this can only be called from a native method context, since
1333 * otherwise the top frame is the callee
1335 public Object[] getArgAttributes () {
1336 StackFrame caller = getCallerStackFrame();
1337 return caller.getArgumentAttrs(mi);
1340 public Object getReturnAttribute() {
1344 // if any of the next methods is called from the bottom
1345 // half of a CG method, you might want to check if another thread
1346 // or a listener has already set an exception you don't want to override
1347 // (this is for instance used in Thread.stop())
1349 public void throwException (int xRef){
1350 assert isInstanceOf(xRef, "java.lang.Throwable");
1351 exceptionRef = xRef;
1354 public void throwException (String clsName) {
1355 ClassInfo ciX = ClassInfo.getInitializedClassInfo(clsName, ti);
1356 assert ciX.isInstanceOf("java.lang.Throwable");
1357 exceptionRef = ti.createException(ciX, null, NULL);
1360 public void throwException (String clsName, String details) {
1361 ClassInfo ciX = ClassInfo.getInitializedClassInfo(clsName, ti);
1362 assert ciX.isInstanceOf("java.lang.Throwable");
1363 exceptionRef = ti.createException(ciX, details, NULL);
1366 public void throwAssertion (String details) {
1367 throwException("java.lang.AssertionError", details);
1370 public void throwInterrupt(){
1371 throwException("java.lang.InterruptedException");
1374 public void stopThread(){
1375 stopThreadWithException(MJIEnv.NULL);
1378 public void stopThreadWithException (int xRef){
1379 // this will call throwException(xRef) with the proper Throwable
1380 ti.setStopped(xRef);
1383 void setCallEnvironment (MethodInfo mi) {
1387 ciMth = mi.getClassInfo();
1396 // we should NOT reset exceptionRef here because it might have been set
1397 // at the beginning of the transition. It gets reset upon return from the
1399 //exceptionRef = NULL;
1402 void clearCallEnvironment () {
1403 setCallEnvironment(null);
1406 ElementInfo getStaticElementInfo (int clsObjRef) {
1407 ClassInfo ci = getReferredClassInfo( clsObjRef);
1409 return ci.getStaticElementInfo();
1415 ElementInfo getModifiableStaticElementInfo (int clsObjRef) {
1416 ClassInfo ci = getReferredClassInfo( clsObjRef);
1418 return ci.getModifiableStaticElementInfo();
1425 ClassInfo getClassInfo () {
1429 public ClassInfo getReferredClassInfo (int clsObjRef) {
1430 ElementInfo ei = getElementInfo(clsObjRef);
1431 if (ei.getClassInfo().getName().equals("java.lang.Class")) {
1432 int ciId = ei.getIntField( ClassInfo.ID_FIELD);
1433 int clref = ei.getReferenceField("classLoader");
1435 ElementInfo eiCl = getElementInfo(clref);
1436 int cliId = eiCl.getIntField(ClassLoaderInfo.ID_FIELD);
1438 ClassLoaderInfo cli = getVM().getClassLoader(cliId);
1439 ClassInfo referredCi = cli.getClassInfo(ciId);
1444 throw new JPFException("not a java.lang.Class object: " + ei);
1448 public ClassInfo getClassInfo (int objref) {
1449 ElementInfo ei = getElementInfo(objref);
1451 return ei.getClassInfo();
1457 public String getClassName (int objref) {
1458 return getClassInfo(objref).getName();
1461 public Heap getHeap () {
1462 return vm.getHeap();
1465 public ElementInfo getElementInfo (int objref) {
1466 return heap.get(objref);
1469 public ElementInfo getModifiableElementInfo (int objref) {
1470 return heap.getModifiable(objref);
1474 public int getStateId () {
1475 return VM.getVM().getStateId();
1478 void clearException(){
1479 exceptionRef = MJIEnv.NULL;
1482 public int peekException () {
1483 return exceptionRef;
1486 public int popException () {
1487 int ret = exceptionRef;
1488 exceptionRef = NULL;
1492 public boolean hasException(){
1493 return (exceptionRef != NULL);
1496 public boolean hasPendingInterrupt(){
1497 return (exceptionRef != NULL && isInstanceOf(exceptionRef, "java.lang.InterruptedException"));
1500 //-- time is managed by the VM
1501 public long currentTimeMillis(){
1502 return vm.currentTimeMillis();
1505 public long nanoTime(){
1506 return vm.nanoTime();
1509 //--- those are not public since they refer to JPF internals
1510 public KernelState getKernelState () {
1511 return VM.getVM().getKernelState();
1514 public MethodInfo getMethodInfo () {
1518 public Instruction getInstruction () {
1523 * It returns the ClassLoaderInfo corresponding to the given classloader object
1526 public ClassLoaderInfo getClassLoaderInfo(int clObjRef) {
1527 if(clObjRef == MJIEnv.NULL) {
1531 int cliId = heap.get(clObjRef).getIntField(ClassLoaderInfo.ID_FIELD);
1532 return getVM().getClassLoader(cliId);
1535 // <2do> that's not correct - it should return the current SystemClassLoader, NOT the startup SystemClassLoader
1536 // (we can instantiate them explicitly)
1537 public ClassLoaderInfo getSystemClassLoaderInfo() {
1538 return ti.getSystemClassLoaderInfo();
1541 public SystemState getSystemState () {
1542 return ti.getVM().getSystemState();
1545 public ApplicationContext getApplicationContext (){
1546 return ti.getApplicationContext();
1549 public ThreadInfo getThreadInfo () {
1554 * NOTE - callers have to be prepared this might return null in case
1555 * the thread got already terminated
1557 public ThreadInfo getThreadInfoForId (int id){
1558 return vm.getThreadList().getThreadInfoForId(id);
1561 public ThreadInfo getLiveThreadInfoForId (int id){
1562 ThreadInfo ti = vm.getThreadList().getThreadInfoForId(id);
1563 if (ti != null && ti.isAlive()){
1571 * NOTE - callers have to be prepared this might return null in case
1572 * the thread got already terminated
1574 public ThreadInfo getThreadInfoForObjRef (int id){
1575 return vm.getThreadList().getThreadInfoForObjRef(id);
1578 public ThreadInfo getLiveThreadInfoForObjRef (int id){
1579 ThreadInfo ti = vm.getThreadList().getThreadInfoForObjRef(id);
1580 if (ti != null && ti.isAlive()){
1589 public ThreadInfo[] getLiveThreads(){
1590 return getVM().getLiveThreads();
1593 // <2do> - naming? not very intuitive
1594 void lockNotified (int objref) {
1595 ElementInfo ei = getModifiableElementInfo(objref);
1596 ei.lockNotified(ti);
1599 void initAnnotationProxyField (int proxyRef, FieldInfo fi, Object v) throws ClinitRequired {
1600 String fname = fi.getName();
1601 String ftype = fi.getType();
1603 if (v instanceof String){
1604 setReferenceField(proxyRef, fname, newString((String)v));
1605 } else if (v instanceof Boolean){
1606 setBooleanField(proxyRef, fname, ((Boolean)v).booleanValue());
1607 } else if (v instanceof Integer){
1608 setIntField(proxyRef, fname, ((Integer)v).intValue());
1609 } else if (v instanceof Long){
1610 setLongField(proxyRef, fname, ((Long)v).longValue());
1611 } else if (v instanceof Float){
1612 setFloatField(proxyRef, fname, ((Float)v).floatValue());
1613 } else if (v instanceof Short){
1614 setShortField(proxyRef, fname, ((Short)v).shortValue());
1615 } else if (v instanceof Character){
1616 setCharField(proxyRef, fname, ((Character)v).charValue());
1617 } else if (v instanceof Byte){
1618 setByteField(proxyRef, fname, ((Byte)v).byteValue());
1619 } else if (v instanceof Double){
1620 setDoubleField(proxyRef, fname, ((Double)v).doubleValue());
1622 } else if (v instanceof AnnotationInfo.EnumValue){ // an enum constant
1623 AnnotationInfo.EnumValue ev = (AnnotationInfo.EnumValue)v;
1624 String eCls = ev.getEnumClassName();
1625 String eConst = ev.getEnumConstName();
1627 ClassInfo eci = ClassLoaderInfo.getCurrentResolvedClassInfo(eCls);
1628 if (!eci.isInitialized()){
1629 throw new ClinitRequired(eci);
1632 StaticElementInfo sei = eci.getStaticElementInfo();
1633 int eref = sei.getReferenceField(eConst);
1634 setReferenceField(proxyRef, fname, eref);
1636 } else if (v instanceof AnnotationInfo.ClassValue){ // a class
1637 String clsName = v.toString();
1638 ClassInfo cci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
1639 // <2do> should throw ClassNotFoundError here if cci is null
1641 if (!cci.isInitialized()){
1642 throw new ClinitRequired(cci);
1645 int cref = cci.getClassObjectRef();
1646 setReferenceField(proxyRef, fname, cref);
1648 } else if (v.getClass().isArray()){ // ..or arrays thereof
1649 Object[] a = (Object[])v;
1652 if (ftype.equals("java.lang.String[]")){
1653 aref = newObjectArray("Ljava/lang/String;", a.length);
1654 for (int i=0; i<a.length; i++){
1655 setReferenceArrayElement(aref,i,newString(a[i].toString()));
1657 } else if (ftype.equals("int[]")){
1658 aref = newIntArray(a.length);
1659 for (int i=0; i<a.length; i++){
1660 setIntArrayElement(aref,i,((Number)a[i]).intValue());
1662 } else if (ftype.equals("boolean[]")){
1663 aref = newBooleanArray(a.length);
1664 for (int i=0; i<a.length; i++){
1665 setBooleanArrayElement(aref,i,((Boolean)a[i]).booleanValue());
1667 } else if (ftype.equals("long[]")){
1668 aref = newLongArray(a.length);
1669 for (int i=0; i<a.length; i++){
1670 setLongArrayElement(aref,i,((Number)a[i]).longValue());
1672 } else if (ftype.equals("double[]")){
1673 aref = newDoubleArray(a.length);
1674 for (int i=0; i<a.length; i++){
1675 setDoubleArrayElement(aref,i,((Number)a[i]).doubleValue());
1677 } else if (ftype.equals("java.lang.Class[]")){
1678 aref = newObjectArray("java.lang.Class", a.length);
1679 for (int i=0; i<a.length; i++){
1680 String clsName = ((AnnotationInfo.ClassValue)a[i]).getName();
1681 ClassInfo cci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
1682 if (!cci.isInitialized()){
1683 throw new ClinitRequired(cci);
1685 int cref = cci.getClassObjectRef();
1686 setReferenceArrayElement(aref,i,cref);
1691 setReferenceField(proxyRef, fname, aref);
1693 throwException("AnnotationElement type not supported: " + ftype);
1697 throwException("AnnotationElement type not supported: " + ftype);
1701 int newAnnotationProxy (ClassInfo aciProxy, AnnotationInfo ai) throws ClinitRequired {
1703 int proxyRef = newObject(aciProxy);
1705 // init fields of the new object from the AnnotationInfo
1706 for (AnnotationInfo.Entry e : ai.getEntries()){
1707 Object v = e.getValue();
1708 String fname = e.getKey();
1709 FieldInfo fi = aciProxy.getInstanceField(fname);
1711 initAnnotationProxyField(proxyRef, fi, v);
1717 int newAnnotationProxies (AnnotationInfo[] ai) throws ClinitRequired {
1719 if ((ai != null) && (ai.length > 0)){
1720 int aref = newObjectArray("Ljava/lang/annotation/Annotation;", ai.length);
1721 for (int i=0; i<ai.length; i++){
1722 ClassInfo aci = ClassLoaderInfo.getCurrentResolvedClassInfo(ai[i].getName());
1723 ClassInfo aciProxy = aci.getAnnotationProxy();
1725 int ar = newAnnotationProxy(aciProxy, ai[i]);
1726 setReferenceArrayElement(aref, i, ar);
1731 // on demand init (not too many programs use annotation reflection)
1732 int aref = getStaticReferenceField("java.lang.Class", "emptyAnnotations");
1734 aref = newObjectArray("Ljava/lang/annotation/Annotation;", 0);
1735 setStaticReferenceField("java.lang.Class", "emptyAnnotations", aref);
1741 public void handleClinitRequest (ClassInfo ci) {
1742 ThreadInfo ti = getThreadInfo();
1744 // NOTE: we have to repeat no matter what, since this is called from
1745 // a handler context (if we only had to create a class object w/o
1746 // calling clinit, we can't just go on)
1747 ci.initializeClass(ti);
1751 public StackFrame getCallerStackFrame() {
1752 // since native methods are now executed within their own stack frames
1753 // we provide a little helper to get the caller
1754 return ti.getLastNonSyntheticStackFrame();
1757 public StackFrame getModifiableCallerStackFrame() {
1758 // since native methods are now executed within their own stack frames
1759 // we provide a little helper to get the caller
1760 return ti.getModifiableLastNonSyntheticStackFrame();
1764 public int valueOfBoolean(boolean b) {
1765 return BoxObjectCacheManager.valueOfBoolean(ti, b);
1768 public int valueOfByte(byte b) {
1769 return BoxObjectCacheManager.valueOfByte(ti, b);
1772 public int valueOfCharacter(char c) {
1773 return BoxObjectCacheManager.valueOfCharacter(ti, c);
1776 public int valueOfShort(short s) {
1777 return BoxObjectCacheManager.valueOfShort(ti, s);
1780 public int valueOfInteger(int i) {
1781 return BoxObjectCacheManager.valueOfInteger(ti, i);
1784 public int valueOfLong(long l) {
1785 return BoxObjectCacheManager.valueOfLong(ti, l);