001: //
002: // Copyright (C) 2005 United States Government as represented by the
003: // Administrator of the National Aeronautics and Space Administration
004: // (NASA). All Rights Reserved.
005: //
006: // This software is distributed under the NASA Open Source Agreement
007: // (NOSA), version 1.3. The NOSA has been approved by the Open Source
008: // Initiative. See the file NOSA-1.3-JPF at the top of the distribution
009: // directory tree for the complete NOSA document.
010: //
011: // THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY
012: // KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT
013: // LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO
014: // SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
015: // A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT
016: // THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT
017: // DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE.
018: //
019: package gov.nasa.jpf.jvm;
020:
021: /**
022: * MJI NativePeer class for java.lang.Class library abstraction
023: */
024: public class JPF_java_lang_Class {
025: public static boolean isArray(MJIEnv env, int robj) {
026: return getReferringClassInfo(env, robj).isArray();
027: }
028:
029: public static int getComponentType(MJIEnv env, int robj) {
030: if (isArray(env, robj)) {
031: ClassInfo ci = getReferringClassInfo(env, robj)
032: .getComponentClassInfo();
033:
034: if (ci != null) {
035: return ci.getClassObjectRef();
036: }
037: }
038:
039: return MJIEnv.NULL;
040: }
041:
042: public static boolean isInstance__Ljava_lang_Object_2(MJIEnv env,
043: int robj, int r1) {
044: ElementInfo sei = env.getClassElementInfo(robj);
045: ClassInfo ci = sei.getClassInfo();
046: ClassInfo ciOther = env.getClassInfo(r1);
047:
048: return (ciOther.instanceOf(ci.getName()));
049: }
050:
051: public static boolean isAssignableFrom__Ljava_lang_Class_2(
052: MJIEnv env, int rcls, int r1) {
053: ElementInfo sei1 = env.getClassElementInfo(rcls);
054: ClassInfo ci1 = sei1.getClassInfo();
055:
056: ElementInfo sei2 = env.getClassElementInfo(r1);
057: ClassInfo ci2 = sei2.getClassInfo();
058:
059: return ci2.instanceOf(ci1.getName());
060: }
061:
062: public static boolean isPrimitiveClass__(MJIEnv env, int robj) {
063: return false;
064: }
065:
066: public static int getPrimitiveClass__Ljava_lang_String_2(
067: MJIEnv env, int rcls, int stringRef) {
068: String clsName = env.getStringObject(stringRef);
069:
070: // we don't really have to check for a valid class name here, since
071: // this is a package default method that just gets called from
072: // the clinit of box classes
073: // note this does NOT return the box class (e.g. java.lang.Integer), which
074: // is a normal, functional class, but a primitive class (e.g. 'int') that
075: // is rather a strange beast (not even Object derived)
076: StaticArea sa = env.getStaticArea();
077: StaticElementInfo ei = sa.get(clsName);
078: int cref = ei.getClassObjectRef();
079: env.setBooleanField(cref, "isPrimitive", true);
080:
081: return cref;
082: }
083:
084: public static boolean desiredAssertionStatus(MJIEnv env, int robj) {
085: ClassInfo ci = getReferringClassInfo(env, robj);
086: return ci.areAssertionsEnabled();
087: }
088:
089: public static int forName__Ljava_lang_String_2(MJIEnv env,
090: int rcls, int stringRef) {
091: String clsName = env.getStringObject(stringRef);
092: StaticElementInfo ei = env.getStaticArea().get(clsName);
093: int ref = ei.getClassObjectRef();
094:
095: return ref;
096: }
097:
098: public static int newInstance(MJIEnv env, int robj) {
099: ClassInfo ci = getReferringClassInfo(env, robj); // what are we
100: ThreadInfo ti = env.getThreadInfo();
101: int ref = env.getDynamicArea().newObject(ci, ti); // create the thing
102:
103: MethodInfo mi = ci.getMethod("<init>()", true);
104:
105: if (mi != null) {
106: // <2do> that's still overly simplistic - leave alone SecurityManager, we have to deal with
107: // IllegalAccessException - if the class or its nullary constructor is not accessible.
108: // InstantiationException - if this Class represents an abstract class, interface,
109: // array class, a primitive type, or has no nullary ctor
110: // ExceptionInInitializerError - if the initialization provoked by this method fails.
111: //
112: // for now, this mostly serves as an example of how to call back into JPF execution
113: // from native methods, BUT be aware of this is executed atomically - any blocked insn
114: // in the called method, and it locks up with an BlockedInAtomicException
115:
116: ti.push(ref, true);
117: ti.executeMethod(mi);
118: }
119:
120: return ref;
121: }
122:
123: public static int getSuperclass(MJIEnv env, int robj) {
124: ClassInfo ci = getReferringClassInfo(env, robj);
125: ClassInfo sci = ci.getSuperClass();
126: if (sci != null) {
127: return sci.getClassObjectRef();
128: } else {
129: return MJIEnv.NULL;
130: }
131: }
132:
133: static ClassInfo getReferringClassInfo(MJIEnv env, int robj) {
134: // this is only the ElementInfo for the java.lang.Class object
135: ElementInfo ei = env.getElementInfo(robj);
136:
137: // get the ClassInfo it refers to
138: int idx = env.getIntField(robj, "cref");
139: StaticArea sa = env.getStaticArea();
140: ElementInfo sei = sa.get(idx);
141:
142: return sei.getClassInfo();
143: }
144: }
|