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 setIntField(objref, fname, /*(int)*/ val);
568 public short getShortField (int objref, String fname) {
569 return (short) getIntField(objref, fname);
573 * NOTE - this doesn't support element type checks or overlapping in-array copy
575 public void arrayCopy (int srcRef, int srcPos, int dstRef, int dstPos, int len){
576 ElementInfo eiSrc = heap.get(srcRef);
577 ElementInfo eiDst = heap.get(dstRef);
579 eiDst.arrayCopy(eiSrc, srcPos, dstPos, len);
582 public String getTypeName (int objref) {
583 return heap.get(objref).getType();
586 public boolean isInstanceOf (int objref, String clsName) {
587 ClassInfo ci = getClassInfo(objref);
588 return ci.isInstanceOf(clsName);
591 public boolean isInstanceOf (int objref, ClassInfo cls) {
592 ClassInfo ci = getClassInfo(objref);
593 return ci.isInstanceOf(cls);
596 //--- the static field accessors
597 // NOTE - it is the callers responsibility to ensure the class is
598 // properly initialized, since calling <clinit> requires a roundtrip
599 // (i.e. cannot be done synchronously from one of the following methods)
601 // <2do> this uses the current system CL, we should probably use an explicit CL argument
603 public void setStaticBooleanField (String clsName, String fname,
605 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
606 ci.getStaticElementInfo().setBooleanField(fname, value);
608 public void setStaticBooleanField (int clsObjRef, String fname, boolean val) {
609 ElementInfo cei = getStaticElementInfo(clsObjRef);
610 cei.setBooleanField(fname, val);
613 public boolean getStaticBooleanField (String clsName, String fname) {
614 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
615 return ci.getStaticElementInfo().getBooleanField(fname);
618 public void setStaticByteField (String clsName, String fname, byte value) {
619 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
620 ci.getStaticElementInfo().setByteField(fname, value); }
622 public byte getStaticByteField (String clsName, String fname) {
623 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
624 return ci.getStaticElementInfo().getByteField(fname);
627 public void setStaticCharField (String clsName, String fname, char value) {
628 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
629 ci.getStaticElementInfo().setCharField(fname, value); }
631 public char getStaticCharField (String clsName, String fname) {
632 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
633 return ci.getStaticElementInfo().getCharField(fname);
636 public void setStaticDoubleField (String clsName, String fname, double val) {
637 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
638 ci.getStaticElementInfo().setDoubleField(fname, val);
641 public double getStaticDoubleField (String clsName, String fname) {
642 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
643 return ci.getStaticElementInfo().getDoubleField(fname);
646 public double getStaticDoubleField (int clsObjRef, String fname) {
647 ElementInfo cei = getStaticElementInfo(clsObjRef);
648 return cei.getDoubleField(fname);
651 public double getStaticDoubleField (ClassInfo ci, String fname) {
652 ElementInfo ei = ci.getStaticElementInfo();
653 return ei.getDoubleField(fname);
656 public void setStaticFloatField (String clsName, String fname, float val) {
657 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
658 ci.getStaticElementInfo().setFloatField(fname, val);
661 public float getStaticFloatField (String clsName, String fname) {
662 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
663 return ci.getStaticElementInfo().getFloatField(fname);
666 public void setStaticIntField (String clsName, String fname, int val) {
667 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
668 ci.getStaticElementInfo().setIntField(fname, val);
671 public void setStaticIntField (int clsObjRef, String fname, int val) {
672 ElementInfo cei = getStaticElementInfo(clsObjRef);
673 cei.setIntField(fname, val);
676 public int getStaticIntField (String clsName, String fname) {
677 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
678 return ci.getStaticElementInfo().getIntField(fname);
681 public int getStaticIntField (int clsObjRef, String fname) {
682 ElementInfo cei = getStaticElementInfo(clsObjRef);
683 return cei.getIntField(fname);
686 public int getStaticIntField (ClassInfo ci, String fname) {
687 ElementInfo ei = ci.getStaticElementInfo();
688 return ei.getIntField(fname);
691 public void setStaticLongField (String clsName, String fname, long value) {
692 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
693 ci.getStaticElementInfo().setLongField(fname, value);
696 public void setStaticLongField (int clsObjRef, String fname, long val) {
697 ElementInfo cei = getModifiableStaticElementInfo(clsObjRef);
698 cei.setLongField(fname, val);
701 public long getStaticLongField (int clsRef, String fname) {
702 ClassInfo ci = getReferredClassInfo(clsRef);
703 return getStaticLongField(ci, fname);
706 public long getStaticLongField (String clsName, String fname) {
707 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
708 return getStaticLongField(ci, fname);
711 public long getStaticLongField (ClassInfo ci, String fname){
712 ElementInfo ei = ci.getStaticElementInfo();
713 return ei.getLongField(fname);
716 public void setStaticReferenceField (String clsName, String fname, int objref) {
717 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
719 // <2do> - we should REALLY check for type compatibility here
720 ci.getModifiableStaticElementInfo().setReferenceField(fname, objref);
723 public void setStaticReferenceField (int clsObjRef, String fname, int objref) {
724 ElementInfo cei = getModifiableStaticElementInfo(clsObjRef);
726 // <2do> - we should REALLY check for type compatibility here
727 cei.setReferenceField(fname, objref);
730 public int getStaticReferenceField (String clsName, String fname) {
731 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
732 return ci.getStaticElementInfo().getReferenceField(fname);
735 public int getStaticReferenceField (int clsObjRef, String fname) {
736 ElementInfo cei = getStaticElementInfo(clsObjRef);
737 return cei.getReferenceField(fname);
740 public int getStaticReferenceField (ClassInfo ci, String fname){
741 return ci.getStaticElementInfo().getReferenceField(fname);
744 public short getStaticShortField (String clsName, String fname) {
745 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
746 return ci.getStaticElementInfo().getShortField(fname);
749 public char[] getStringChars (int objRef){
750 if (objRef != MJIEnv.NULL) {
751 ElementInfo ei = getElementInfo(objRef);
752 return ei.getStringChars();
761 * turn JPF String object into a VM String object
762 * (this is a method available for non gov..jvm NativePeer classes)
764 public String getStringObject (int objRef) {
765 if (objRef != MJIEnv.NULL) {
766 ElementInfo ei = getElementInfo(objRef);
767 return ei.asString();
774 public String[] getStringArrayObject (int aRef){
777 if (aRef == NULL) return sa;
779 ClassInfo aci = getClassInfo(aRef);
781 ClassInfo eci = aci.getComponentClassInfo();
782 if (eci.getName().equals("java.lang.String")){
783 int len = getArrayLength(aRef);
784 sa = new String[len];
786 for (int i=0; i<len; i++){
787 int sRef = getReferenceArrayElement(aRef,i);
788 sa[i] = getStringObject(sRef);
794 throw new IllegalArgumentException("not a String[] array: " + aci.getName());
797 throw new IllegalArgumentException("not an array reference: " + aci.getName());
801 public Date getDateObject (int objref) {
802 if (objref != MJIEnv.NULL) {
803 ElementInfo ei = getElementInfo(objref);
804 if (ei.getClassInfo().getName().equals("java.util.Date")) {
805 // <2do> this is not complete yet
806 long fastTime = ei.getLongField("fastTime");
807 Date d = new Date(fastTime);
810 throw new JPFException("not a Date object reference: " + ei);
818 public Object[] getArgumentArray (int argRef) {
819 Object[] args = null;
820 if (argRef == NULL) return args;
822 int nArgs = getArrayLength(argRef);
823 args = new Object[nArgs];
825 for (int i=0; i<nArgs; i++){
826 int aref = getReferenceArrayElement(argRef,i);
827 ClassInfo ci = getClassInfo(aref);
828 String clsName = ci.getName();
829 if (clsName.equals("java.lang.Boolean")){
830 args[i] = Boolean.valueOf(getBooleanField(aref,"value"));
831 } else if (clsName.equals("java.lang.Integer")){
832 args[i] = Integer.valueOf(getIntField(aref,"value"));
833 } else if (clsName.equals("java.lang.Double")){
834 args[i] = Double.valueOf(getDoubleField(aref,"value"));
835 } else if (clsName.equals("java.lang.String")){
836 args[i] = getStringObject(aref);
843 public Boolean getBooleanObject (int objref){
844 return Boolean.valueOf(getBooleanField(objref, "value"));
847 public Byte getByteObject (int objref){
848 return new Byte(getByteField(objref, "value"));
851 public Character getCharObject (int objref){
852 return new Character(getCharField(objref, "value"));
855 public Short getShortObject (int objref){
856 return new Short(getShortField(objref, "value"));
859 public Integer getIntegerObject (int objref){
860 return new Integer(getIntField(objref, "value"));
863 public Long getLongObject (int objref){
864 return new Long(getLongField(objref, "value"));
867 public Float getFloatObject (int objref){
868 return new Float(getFloatField(objref, "value"));
871 public Double getDoubleObject (int objref){
872 return new Double(getDoubleField(objref, "value"));
875 // danger - the returned arrays could be used to modify contents of stored objects
877 public byte[] getByteArrayObject (int objref) {
878 ElementInfo ei = getElementInfo(objref);
879 byte[] a = ei.asByteArray();
884 public char[] getCharArrayObject (int objref) {
885 ElementInfo ei = getElementInfo(objref);
886 char[] a = ei.asCharArray();
891 public short[] getShortArrayObject (int objref) {
892 ElementInfo ei = getElementInfo(objref);
893 short[] a = ei.asShortArray();
898 public int[] getIntArrayObject (int objref) {
899 ElementInfo ei = getElementInfo(objref);
900 int[] a = ei.asIntArray();
905 public long[] getLongArrayObject (int objref) {
906 ElementInfo ei = getElementInfo(objref);
907 long[] a = ei.asLongArray();
912 public float[] getFloatArrayObject (int objref) {
913 ElementInfo ei = getElementInfo(objref);
914 float[] a = ei.asFloatArray();
919 public double[] getDoubleArrayObject (int objref) {
920 ElementInfo ei = getElementInfo(objref);
921 double[] a = ei.asDoubleArray();
926 public boolean[] getBooleanArrayObject (int objref) {
927 ElementInfo ei = getElementInfo(objref);
928 boolean[] a = ei.asBooleanArray();
933 public int[] getReferenceArrayObject (int objref){
934 ElementInfo ei = getElementInfo(objref);
935 int[] a = ei.asReferenceArray();
940 public boolean canLock (int objref) {
941 ElementInfo ei = getElementInfo(objref);
943 return ei.canLock(ti);
946 public int newBooleanArray (int size) {
947 return heap.newArray("Z", size, ti).getObjectRef();
950 public int newByteArray (int size) {
951 return heap.newArray("B", size, ti).getObjectRef();
954 public int newByteArray (byte[] buf){
955 ElementInfo eiArray = heap.newArray("B", buf.length, ti);
956 for (int i=0; i<buf.length; i++){
957 eiArray.setByteElement( i, buf[i]);
959 return eiArray.getObjectRef();
962 public int newCharArray (int size) {
963 return heap.newArray("C", size, ti).getObjectRef();
966 public int newCharArray (char[] buf){
967 ElementInfo eiArray = heap.newArray("C", buf.length, ti);
968 for (int i=0; i<buf.length; i++){
969 eiArray.setCharElement( i, buf[i]);
971 return eiArray.getObjectRef();
974 public int newShortArray (int size) {
975 return heap.newArray("S", size, ti).getObjectRef();
978 public int newShortArray (short[] buf){
979 ElementInfo eiArray = heap.newArray("S", buf.length, ti);
980 for (int i=0; i<buf.length; i++){
981 eiArray.setShortElement(i, buf[i]);
983 return eiArray.getObjectRef();
986 public int newDoubleArray (int size) {
987 return heap.newArray("D", size, ti).getObjectRef();
990 public int newDoubleArray (double[] buf){
991 ElementInfo eiArray = heap.newArray("D", buf.length, ti);
992 for (int i=0; i<buf.length; i++){
993 eiArray.setDoubleElement(i, buf[i]);
995 return eiArray.getObjectRef();
998 public int newFloatArray (int size) {
999 return heap.newArray("F", size, ti).getObjectRef();
1002 public int newFloatArray (float[] buf){
1003 ElementInfo eiArray = heap.newArray("F", buf.length, ti);
1004 for (int i=0; i<buf.length; i++){
1005 eiArray.setFloatElement( i, buf[i]);
1007 return eiArray.getObjectRef();
1010 public int newIntArray (int size) {
1011 return heap.newArray("I", size, ti).getObjectRef();
1014 public int newIntArray (int[] buf){
1015 ElementInfo eiArray = heap.newArray("I", buf.length, ti);
1016 for (int i=0; i<buf.length; i++){
1017 eiArray.setIntElement( i, buf[i]);
1019 return eiArray.getObjectRef();
1022 public int newLongArray (int size) {
1023 return heap.newArray("J", size, ti).getObjectRef();
1026 public int newLongArray (long[] buf){
1027 ElementInfo eiArray = heap.newArray("J", buf.length, ti);
1028 for (int i=0; i<buf.length; i++){
1029 eiArray.setLongElement( i, buf[i]);
1031 return eiArray.getObjectRef();
1034 public int newObjectArray (String elementClsName, int size) {
1035 if (!elementClsName.endsWith(";")) {
1036 elementClsName = Types.getTypeSignature(elementClsName, false);
1039 return heap.newArray(elementClsName, size, ti).getObjectRef();
1042 public ElementInfo newElementInfo (ClassInfo ci) throws ClinitRequired {
1043 if (ci.initializeClass(ti)){
1044 throw new ClinitRequired(ci);
1047 return heap.newObject(ci, ti);
1051 * check if the ClassInfo is properly initialized
1052 * if yes, create a new instance of it but don't call any ctor
1053 * if no, throw a ClinitRequired exception
1055 public int newObject (ClassInfo ci) throws ClinitRequired {
1056 ElementInfo ei = newElementInfo(ci);
1057 return ei.getObjectRef();
1061 * this creates a new object without checking if the ClassInfo needs
1062 * initialization. This is useful in a context that already
1063 * is aware and handles re-execution
1065 public int newObjectOfUncheckedClass (ClassInfo ci){
1066 ElementInfo ei = heap.newObject(ci, ti);
1067 return ei.getObjectRef();
1070 public ElementInfo newElementInfo (String clsName) throws ClinitRequired, UnknownJPFClass {
1071 ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
1073 return newElementInfo(ci);
1075 throw new UnknownJPFClass(clsName);
1079 public int newObject (String clsName) throws ClinitRequired, UnknownJPFClass {
1080 ElementInfo ei = newElementInfo(clsName);
1081 return (ei != null) ? ei.getObjectRef() : NULL;
1084 public int newString (String s) {
1088 return heap.newString(s, ti).getObjectRef();
1092 public int newStringArray (String[] a){
1093 int aref = newObjectArray("Ljava/lang/String;", a.length);
1095 for (int i=0; i<a.length; i++){
1096 setReferenceArrayElement(aref, i, newString(a[i]));
1102 public int newString (int arrayRef) {
1103 String t = getArrayType(arrayRef);
1106 if ("C".equals(t)) { // character array
1107 char[] ca = getCharArrayObject(arrayRef);
1109 } else if ("B".equals(t)) { // byte array
1110 byte[] ba = getByteArrayObject(arrayRef);
1118 return newString(s);
1121 public String format (int fmtRef, int argRef){
1122 String format = getStringObject(fmtRef);
1123 int len = getArrayLength(argRef);
1124 Object[] arg = new Object[len];
1126 for (int i=0; i<len; i++){
1127 int ref = getReferenceArrayElement(argRef,i);
1129 String clsName = getClassName(ref);
1130 if (clsName.equals("java.lang.String")) {
1131 arg[i] = getStringObject(ref);
1132 } else if (clsName.equals("java.lang.Boolean")){
1133 arg[i] = getBooleanObject(ref);
1134 } else if (clsName.equals("java.lang.Byte")) {
1135 arg[i] = getByteObject(ref);
1136 } else if (clsName.equals("java.lang.Char")) {
1137 arg[i] = getCharObject(ref);
1138 } else if (clsName.equals("java.lang.Short")) {
1139 arg[i] = getShortObject(ref);
1140 } else if (clsName.equals("java.lang.Integer")) {
1141 arg[i] = getIntegerObject(ref);
1142 } else if (clsName.equals("java.lang.Long")) {
1143 arg[i] = getLongObject(ref);
1144 } else if (clsName.equals("java.lang.Float")) {
1145 arg[i] = getFloatObject(ref);
1146 } else if (clsName.equals("java.lang.Double")) {
1147 arg[i] = getDoubleObject(ref);
1149 // need a toString() here
1155 return String.format(format,arg);
1158 public String format (Locale l,int fmtRef, int argRef){
1159 String format = getStringObject(fmtRef);
1160 int len = getArrayLength(argRef);
1161 Object[] arg = new Object[len];
1163 for (int i=0; i<len; i++){
1164 int ref = getReferenceArrayElement(argRef,i);
1166 String clsName = getClassName(ref);
1167 if (clsName.equals("java.lang.String")) {
1168 arg[i] = getStringObject(ref);
1169 } else if (clsName.equals("java.lang.Byte")) {
1170 arg[i] = getByteObject(ref);
1171 } else if (clsName.equals("java.lang.Char")) {
1172 arg[i] = getCharObject(ref);
1173 } else if (clsName.equals("java.lang.Short")) {
1174 arg[i] = getShortObject(ref);
1175 } else if (clsName.equals("java.lang.Integer")) {
1176 arg[i] = getIntegerObject(ref);
1177 } else if (clsName.equals("java.lang.Long")) {
1178 arg[i] = getLongObject(ref);
1179 } else if (clsName.equals("java.lang.Float")) {
1180 arg[i] = getFloatObject(ref);
1181 } else if (clsName.equals("java.lang.Double")) {
1182 arg[i] = getDoubleObject(ref);
1184 // need a toString() here
1190 return String.format(l,format,arg);
1194 public int newBoolean (boolean b){
1195 return getStaticReferenceField("java.lang.Boolean", b ? "TRUE" : "FALSE");
1198 public int newInteger (int n){
1199 ElementInfo ei = heap.newObject(ClassLoaderInfo.getSystemResolvedClassInfo("java.lang.Integer"), ti);
1200 ei.setIntField("value",n);
1201 return ei.getObjectRef();
1204 public int newLong (long l){
1205 ElementInfo ei = heap.newObject(ClassLoaderInfo.getSystemResolvedClassInfo("java.lang.Long"), ti);
1206 ei.setLongField("value",l);
1207 return ei.getObjectRef();
1210 public int newDouble (double d){
1211 ElementInfo ei = heap.newObject(ClassLoaderInfo.getSystemResolvedClassInfo("java.lang.Double"), ti);
1212 ei.setDoubleField("value",d);
1213 return ei.getObjectRef();
1216 public int newFloat (float f){
1217 ElementInfo ei = heap.newObject(ClassLoaderInfo.getSystemResolvedClassInfo("java.lang.Float"), ti);
1218 ei.setFloatField("value",f);
1219 return ei.getObjectRef();
1222 public int newByte (byte b){
1223 ElementInfo ei = heap.newObject(ClassLoaderInfo.getSystemResolvedClassInfo("java.lang.Byte"), ti);
1224 ei.setByteField("value",b);
1225 return ei.getObjectRef();
1228 public int newShort (short s){
1229 ElementInfo ei = heap.newObject(ClassLoaderInfo.getSystemResolvedClassInfo("java.lang.Short"), ti);
1230 ei.setShortField("value",s);
1231 return ei.getObjectRef();
1234 public int newCharacter (char c){
1235 ElementInfo ei = heap.newObject(ClassLoaderInfo.getSystemResolvedClassInfo("java.lang.Character"), ti);
1236 ei.setCharField("value",c);
1237 return ei.getObjectRef();
1241 public boolean notify (int objref) {
1242 // objref can't be NULL since the corresponding INVOKE would have failed
1243 ElementInfo ei = getModifiableElementInfo(objref);
1247 public boolean notify (ElementInfo ei) {
1248 if (!ei.isLockedBy(ti)){
1249 throwException("java.lang.IllegalMonitorStateException",
1250 "un-synchronized notify");
1254 return ei.notifies(getSystemState(), ti);
1257 public boolean notifyAll (int objref) {
1258 // objref can't be NULL since the corresponding INVOKE would have failed
1259 ElementInfo ei = getElementInfo(objref);
1260 return notifyAll(ei);
1263 public boolean notifyAll (ElementInfo ei) {
1264 if (!ei.isLockedBy(ti)){
1265 throwException("java.lang.IllegalMonitorStateException",
1266 "un-synchronized notifyAll");
1270 return ei.notifiesAll();
1273 public void registerPinDown(int objref){
1274 heap.registerPinDown(objref);
1276 public void registerPinDown (ElementInfo ei){
1277 registerPinDown(ei.getObjectRef());
1280 public void releasePinDown(int objref){
1281 heap.releasePinDown(objref);
1283 public void releasePinDown (ElementInfo ei){
1284 releasePinDown(ei.getObjectRef());
1288 * use this whenever a peer performs an operation on a class that might not be initialized yet
1289 * Do a repeatInvocation() in this case
1291 public boolean requiresClinitExecution(ClassInfo ci) {
1292 return ci.initializeClass(ti);
1296 * repeat execution of the instruction that caused a native method call
1297 * NOTE - this does NOT mean it's the NEXT executed insn, since the native method
1298 * might have pushed direct call frames on the stack before asking us to repeat it.
1300 public void repeatInvocation () {
1304 public boolean isInvocationRepeated() {
1309 public boolean setNextChoiceGenerator (ChoiceGenerator<?> cg){
1310 return vm.getSystemState().setNextChoiceGenerator(cg);
1313 public void setMandatoryNextChoiceGenerator(ChoiceGenerator<?> cg, String failMsg){
1314 vm.getSystemState().setMandatoryNextChoiceGenerator(cg, failMsg);
1317 public ChoiceGenerator<?> getChoiceGenerator () {
1318 return vm.getSystemState().getChoiceGenerator();
1321 // note this only makes sense if we actually do return something
1322 public void setReturnAttribute (Object attr) {
1327 * return attr list of all arguments. Use ObjectList to retrieve values
1330 * NOTE - this can only be called from a native method context, since
1331 * otherwise the top frame is the callee
1333 public Object[] getArgAttributes () {
1334 StackFrame caller = getCallerStackFrame();
1335 return caller.getArgumentAttrs(mi);
1338 public Object getReturnAttribute() {
1342 // if any of the next methods is called from the bottom
1343 // half of a CG method, you might want to check if another thread
1344 // or a listener has already set an exception you don't want to override
1345 // (this is for instance used in Thread.stop())
1347 public void throwException (int xRef){
1348 assert isInstanceOf(xRef, "java.lang.Throwable");
1349 exceptionRef = xRef;
1352 public void throwException (String clsName) {
1353 ClassInfo ciX = ClassInfo.getInitializedClassInfo(clsName, ti);
1354 assert ciX.isInstanceOf("java.lang.Throwable");
1355 exceptionRef = ti.createException(ciX, null, NULL);
1358 public void throwException (String clsName, String details) {
1359 ClassInfo ciX = ClassInfo.getInitializedClassInfo(clsName, ti);
1360 assert ciX.isInstanceOf("java.lang.Throwable");
1361 exceptionRef = ti.createException(ciX, details, NULL);
1364 public void throwAssertion (String details) {
1365 throwException("java.lang.AssertionError", details);
1368 public void throwInterrupt(){
1369 throwException("java.lang.InterruptedException");
1372 public void stopThread(){
1373 stopThreadWithException(MJIEnv.NULL);
1376 public void stopThreadWithException (int xRef){
1377 // this will call throwException(xRef) with the proper Throwable
1378 ti.setStopped(xRef);
1381 void setCallEnvironment (MethodInfo mi) {
1385 ciMth = mi.getClassInfo();
1394 // we should NOT reset exceptionRef here because it might have been set
1395 // at the beginning of the transition. It gets reset upon return from the
1397 //exceptionRef = NULL;
1400 void clearCallEnvironment () {
1401 setCallEnvironment(null);
1404 ElementInfo getStaticElementInfo (int clsObjRef) {
1405 ClassInfo ci = getReferredClassInfo( clsObjRef);
1407 return ci.getStaticElementInfo();
1413 ElementInfo getModifiableStaticElementInfo (int clsObjRef) {
1414 ClassInfo ci = getReferredClassInfo( clsObjRef);
1416 return ci.getModifiableStaticElementInfo();
1423 ClassInfo getClassInfo () {
1427 public ClassInfo getReferredClassInfo (int clsObjRef) {
1428 ElementInfo ei = getElementInfo(clsObjRef);
1429 if (ei.getClassInfo().getName().equals("java.lang.Class")) {
1430 int ciId = ei.getIntField( ClassInfo.ID_FIELD);
1431 int clref = ei.getReferenceField("classLoader");
1433 ElementInfo eiCl = getElementInfo(clref);
1434 int cliId = eiCl.getIntField(ClassLoaderInfo.ID_FIELD);
1436 ClassLoaderInfo cli = getVM().getClassLoader(cliId);
1437 ClassInfo referredCi = cli.getClassInfo(ciId);
1442 throw new JPFException("not a java.lang.Class object: " + ei);
1446 public ClassInfo getClassInfo (int objref) {
1447 ElementInfo ei = getElementInfo(objref);
1449 return ei.getClassInfo();
1455 public String getClassName (int objref) {
1456 return getClassInfo(objref).getName();
1459 public Heap getHeap () {
1460 return vm.getHeap();
1463 public ElementInfo getElementInfo (int objref) {
1464 return heap.get(objref);
1467 public ElementInfo getModifiableElementInfo (int objref) {
1468 return heap.getModifiable(objref);
1472 public int getStateId () {
1473 return VM.getVM().getStateId();
1476 void clearException(){
1477 exceptionRef = MJIEnv.NULL;
1480 public int peekException () {
1481 return exceptionRef;
1484 public int popException () {
1485 int ret = exceptionRef;
1486 exceptionRef = NULL;
1490 public boolean hasException(){
1491 return (exceptionRef != NULL);
1494 public boolean hasPendingInterrupt(){
1495 return (exceptionRef != NULL && isInstanceOf(exceptionRef, "java.lang.InterruptedException"));
1498 //-- time is managed by the VM
1499 public long currentTimeMillis(){
1500 return vm.currentTimeMillis();
1503 public long nanoTime(){
1504 return vm.nanoTime();
1507 //--- those are not public since they refer to JPF internals
1508 public KernelState getKernelState () {
1509 return VM.getVM().getKernelState();
1512 public MethodInfo getMethodInfo () {
1516 public Instruction getInstruction () {
1521 * It returns the ClassLoaderInfo corresponding to the given classloader object
1524 public ClassLoaderInfo getClassLoaderInfo(int clObjRef) {
1525 if(clObjRef == MJIEnv.NULL) {
1529 int cliId = heap.get(clObjRef).getIntField(ClassLoaderInfo.ID_FIELD);
1530 return getVM().getClassLoader(cliId);
1533 // <2do> that's not correct - it should return the current SystemClassLoader, NOT the startup SystemClassLoader
1534 // (we can instantiate them explicitly)
1535 public ClassLoaderInfo getSystemClassLoaderInfo() {
1536 return ti.getSystemClassLoaderInfo();
1539 public SystemState getSystemState () {
1540 return ti.getVM().getSystemState();
1543 public ApplicationContext getApplicationContext (){
1544 return ti.getApplicationContext();
1547 public ThreadInfo getThreadInfo () {
1552 * NOTE - callers have to be prepared this might return null in case
1553 * the thread got already terminated
1555 public ThreadInfo getThreadInfoForId (int id){
1556 return vm.getThreadList().getThreadInfoForId(id);
1559 public ThreadInfo getLiveThreadInfoForId (int id){
1560 ThreadInfo ti = vm.getThreadList().getThreadInfoForId(id);
1561 if (ti != null && ti.isAlive()){
1569 * NOTE - callers have to be prepared this might return null in case
1570 * the thread got already terminated
1572 public ThreadInfo getThreadInfoForObjRef (int id){
1573 return vm.getThreadList().getThreadInfoForObjRef(id);
1576 public ThreadInfo getLiveThreadInfoForObjRef (int id){
1577 ThreadInfo ti = vm.getThreadList().getThreadInfoForObjRef(id);
1578 if (ti != null && ti.isAlive()){
1587 public ThreadInfo[] getLiveThreads(){
1588 return getVM().getLiveThreads();
1591 // <2do> - naming? not very intuitive
1592 void lockNotified (int objref) {
1593 ElementInfo ei = getModifiableElementInfo(objref);
1594 ei.lockNotified(ti);
1597 void initAnnotationProxyField (int proxyRef, FieldInfo fi, Object v) throws ClinitRequired {
1598 String fname = fi.getName();
1599 String ftype = fi.getType();
1601 if (v instanceof String){
1602 setReferenceField(proxyRef, fname, newString((String)v));
1603 } else if (v instanceof Boolean){
1604 setBooleanField(proxyRef, fname, ((Boolean)v).booleanValue());
1605 } else if (v instanceof Integer){
1606 setIntField(proxyRef, fname, ((Integer)v).intValue());
1607 } else if (v instanceof Long){
1608 setLongField(proxyRef, fname, ((Long)v).longValue());
1609 } else if (v instanceof Float){
1610 setFloatField(proxyRef, fname, ((Float)v).floatValue());
1611 } else if (v instanceof Short){
1612 setShortField(proxyRef, fname, ((Short)v).shortValue());
1613 } else if (v instanceof Character){
1614 setCharField(proxyRef, fname, ((Character)v).charValue());
1615 } else if (v instanceof Byte){
1616 setByteField(proxyRef, fname, ((Byte)v).byteValue());
1617 } else if (v instanceof Double){
1618 setDoubleField(proxyRef, fname, ((Double)v).doubleValue());
1620 } else if (v instanceof AnnotationInfo.EnumValue){ // an enum constant
1621 AnnotationInfo.EnumValue ev = (AnnotationInfo.EnumValue)v;
1622 String eCls = ev.getEnumClassName();
1623 String eConst = ev.getEnumConstName();
1625 ClassInfo eci = ClassLoaderInfo.getCurrentResolvedClassInfo(eCls);
1626 if (!eci.isInitialized()){
1627 throw new ClinitRequired(eci);
1630 StaticElementInfo sei = eci.getStaticElementInfo();
1631 int eref = sei.getReferenceField(eConst);
1632 setReferenceField(proxyRef, fname, eref);
1634 } else if (v instanceof AnnotationInfo.ClassValue){ // a class
1635 String clsName = v.toString();
1636 ClassInfo cci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
1637 // <2do> should throw ClassNotFoundError here if cci is null
1639 if (!cci.isInitialized()){
1640 throw new ClinitRequired(cci);
1643 int cref = cci.getClassObjectRef();
1644 setReferenceField(proxyRef, fname, cref);
1646 } else if (v.getClass().isArray()){ // ..or arrays thereof
1647 Object[] a = (Object[])v;
1650 if (ftype.equals("java.lang.String[]")){
1651 aref = newObjectArray("Ljava/lang/String;", a.length);
1652 for (int i=0; i<a.length; i++){
1653 setReferenceArrayElement(aref,i,newString(a[i].toString()));
1655 } else if (ftype.equals("int[]")){
1656 aref = newIntArray(a.length);
1657 for (int i=0; i<a.length; i++){
1658 setIntArrayElement(aref,i,((Number)a[i]).intValue());
1660 } else if (ftype.equals("boolean[]")){
1661 aref = newBooleanArray(a.length);
1662 for (int i=0; i<a.length; i++){
1663 setBooleanArrayElement(aref,i,((Boolean)a[i]).booleanValue());
1665 } else if (ftype.equals("long[]")){
1666 aref = newLongArray(a.length);
1667 for (int i=0; i<a.length; i++){
1668 setLongArrayElement(aref,i,((Number)a[i]).longValue());
1670 } else if (ftype.equals("double[]")){
1671 aref = newDoubleArray(a.length);
1672 for (int i=0; i<a.length; i++){
1673 setDoubleArrayElement(aref,i,((Number)a[i]).doubleValue());
1675 } else if (ftype.equals("java.lang.Class[]")){
1676 aref = newObjectArray("java.lang.Class", a.length);
1677 for (int i=0; i<a.length; i++){
1678 String clsName = ((AnnotationInfo.ClassValue)a[i]).getName();
1679 ClassInfo cci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName);
1680 if (!cci.isInitialized()){
1681 throw new ClinitRequired(cci);
1683 int cref = cci.getClassObjectRef();
1684 setReferenceArrayElement(aref,i,cref);
1689 setReferenceField(proxyRef, fname, aref);
1691 throwException("AnnotationElement type not supported: " + ftype);
1695 throwException("AnnotationElement type not supported: " + ftype);
1699 int newAnnotationProxy (ClassInfo aciProxy, AnnotationInfo ai) throws ClinitRequired {
1701 int proxyRef = newObject(aciProxy);
1703 // init fields of the new object from the AnnotationInfo
1704 for (AnnotationInfo.Entry e : ai.getEntries()){
1705 Object v = e.getValue();
1706 String fname = e.getKey();
1707 FieldInfo fi = aciProxy.getInstanceField(fname);
1709 initAnnotationProxyField(proxyRef, fi, v);
1715 int newAnnotationProxies (AnnotationInfo[] ai) throws ClinitRequired {
1717 if ((ai != null) && (ai.length > 0)){
1718 int aref = newObjectArray("Ljava/lang/annotation/Annotation;", ai.length);
1719 for (int i=0; i<ai.length; i++){
1720 ClassInfo aci = ClassLoaderInfo.getCurrentResolvedClassInfo(ai[i].getName());
1721 ClassInfo aciProxy = aci.getAnnotationProxy();
1723 int ar = newAnnotationProxy(aciProxy, ai[i]);
1724 setReferenceArrayElement(aref, i, ar);
1729 // on demand init (not too many programs use annotation reflection)
1730 int aref = getStaticReferenceField("java.lang.Class", "emptyAnnotations");
1732 aref = newObjectArray("Ljava/lang/annotation/Annotation;", 0);
1733 setStaticReferenceField("java.lang.Class", "emptyAnnotations", aref);
1739 public void handleClinitRequest (ClassInfo ci) {
1740 ThreadInfo ti = getThreadInfo();
1742 // NOTE: we have to repeat no matter what, since this is called from
1743 // a handler context (if we only had to create a class object w/o
1744 // calling clinit, we can't just go on)
1745 ci.initializeClass(ti);
1749 public StackFrame getCallerStackFrame() {
1750 // since native methods are now executed within their own stack frames
1751 // we provide a little helper to get the caller
1752 return ti.getLastNonSyntheticStackFrame();
1755 public StackFrame getModifiableCallerStackFrame() {
1756 // since native methods are now executed within their own stack frames
1757 // we provide a little helper to get the caller
1758 return ti.getModifiableLastNonSyntheticStackFrame();
1762 public int valueOfBoolean(boolean b) {
1763 return BoxObjectCacheManager.valueOfBoolean(ti, b);
1766 public int valueOfByte(byte b) {
1767 return BoxObjectCacheManager.valueOfByte(ti, b);
1770 public int valueOfCharacter(char c) {
1771 return BoxObjectCacheManager.valueOfCharacter(ti, c);
1774 public int valueOfShort(short s) {
1775 return BoxObjectCacheManager.valueOfShort(ti, s);
1778 public int valueOfInteger(int i) {
1779 return BoxObjectCacheManager.valueOfInteger(ti, i);
1782 public int valueOfLong(long l) {
1783 return BoxObjectCacheManager.valueOfLong(ti, l);