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 gov.nasa.jpf.Config;
21 import gov.nasa.jpf.annotation.MJI;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.util.ArrayList;
26 import java.util.HashMap;
31 * MJI NativePeer class for java.lang.Class library abstraction
33 public class JPF_java_lang_Class extends NativePeer {
35 static final String FIELD_CLASSNAME = "java.lang.reflect.Field";
36 static final String METHOD_CLASSNAME = "java.lang.reflect.Method";
37 static final String CONSTRUCTOR_CLASSNAME = "java.lang.reflect.Constructor";
39 public static boolean init (Config conf){
40 // we create Method and Constructor objects, so we better make sure these
41 // classes are initialized (they already might be)
42 JPF_java_lang_reflect_Method.init(conf);
43 JPF_java_lang_reflect_Constructor.init(conf);
48 public boolean isArray____Z (MJIEnv env, int robj) {
49 ClassInfo ci = env.getReferredClassInfo( robj);
54 public int getComponentType____Ljava_lang_Class_2 (MJIEnv env, int robj) {
55 if (isArray____Z(env, robj)) {
56 ThreadInfo ti = env.getThreadInfo();
57 Instruction insn = ti.getPC();
58 ClassInfo ci = env.getReferredClassInfo( robj).getComponentClassInfo();
60 if (ci.initializeClass(ti)){
61 env.repeatInvocation();
65 return ci.getClassObjectRef();
72 public boolean isInstance__Ljava_lang_Object_2__Z (MJIEnv env, int robj,
74 ElementInfo sei = env.getStaticElementInfo(robj);
75 ClassInfo ci = sei.getClassInfo();
76 ClassInfo ciOther = env.getClassInfo(r1);
77 return (ciOther.isInstanceOf(ci));
81 public boolean isInterface____Z (MJIEnv env, int robj){
82 ClassInfo ci = env.getReferredClassInfo( robj);
83 return ci.isInterface();
87 public boolean isAssignableFrom__Ljava_lang_Class_2__Z (MJIEnv env, int rcls,
89 ElementInfo sei1 = env.getStaticElementInfo(rcls);
90 ClassInfo ci1 = sei1.getClassInfo();
92 ElementInfo sei2 = env.getStaticElementInfo(r1);
93 ClassInfo ci2 = sei2.getClassInfo();
95 return ci2.isInstanceOf( ci1);
99 public int getAnnotations_____3Ljava_lang_annotation_Annotation_2 (MJIEnv env, int robj){
100 ClassInfo ci = env.getReferredClassInfo( robj);
101 AnnotationInfo[] ai = ci.getAnnotations();
104 return env.newAnnotationProxies(ai);
105 } catch (ClinitRequired x){
106 env.handleClinitRequest(x.getRequiredClassInfo());
112 public int getAnnotation__Ljava_lang_Class_2__Ljava_lang_annotation_Annotation_2 (MJIEnv env, int robj,
114 ClassInfo ci = env.getReferredClassInfo( robj);
115 ClassInfo aci = env.getReferredClassInfo(annoClsRef);
117 AnnotationInfo ai = ci.getAnnotation(aci.getName());
119 ClassInfo aciProxy = aci.getAnnotationProxy();
122 return env.newAnnotationProxy(aciProxy, ai);
123 } catch (ClinitRequired x){
124 env.handleClinitRequest(x.getRequiredClassInfo());
133 public int getPrimitiveClass__Ljava_lang_String_2__Ljava_lang_Class_2 (MJIEnv env,
134 int rcls, int stringRef) {
135 // we don't really have to check for a valid class name here, since
136 // this is a package default method that just gets called from
137 // the clinit of box classes
138 // note this does NOT return the box class (e.g. java.lang.Integer), which
139 // is a normal, functional class, but a primitive class (e.g. 'int') that
140 // is rather a strange beast (not even Object derived)
142 ClassLoaderInfo scli = env.getSystemClassLoaderInfo(); // this is the one responsible for builtin classes
143 String primClsName = env.getStringObject(stringRef); // always initialized
145 ClassInfo ci = scli.getResolvedClassInfo(primClsName);
146 return ci.getClassObjectRef();
150 public boolean desiredAssertionStatus____Z (MJIEnv env, int robj) {
151 ClassInfo ci = env.getReferredClassInfo(robj);
152 return ci.desiredAssertionStatus();
155 public static int getClassObject (MJIEnv env, ClassInfo ci){
156 ThreadInfo ti = env.getThreadInfo();
157 Instruction insn = ti.getPC();
159 if (ci.initializeClass(ti)){
160 env.repeatInvocation();
164 StaticElementInfo ei = ci.getStaticElementInfo();
165 int ref = ei.getClassObjectRef();
171 public int forName__Ljava_lang_String_2__Ljava_lang_Class_2 (MJIEnv env,
174 if (clsNameRef == MJIEnv.NULL){
175 env.throwException("java.lang.NullPointerException", "no class name provided");
179 String clsName = env.getStringObject(clsNameRef);
181 if (clsName.isEmpty()){
182 env.throwException("java.lang.ClassNotFoundException", "empty class name");
186 ThreadInfo ti = env.getThreadInfo();
187 MethodInfo mi = ti.getTopFrame().getPrevious().getMethodInfo();
188 // class of the method that includes the invocation of Class.forName()
189 ClassInfo cls = mi.getClassInfo();
192 // for array type, the component terminal must be resolved
193 if(clsName.charAt(0)=='[') {
194 name = Types.getComponentTerminal(clsName);
199 // make the classloader of the class including the invocation of
200 // Class.forName() resolve the class with the given name
202 cls.resolveReferencedClass(name);
203 } catch(LoadOnJPFRequired lre) {
204 env.repeatInvocation();
208 // The class obtained here is the same as the resolved one, except
209 // if it represents an array type
210 ClassInfo ci = cls.getClassLoaderInfo().getResolvedClassInfo(clsName);
212 return getClassObject(env, ci);
216 * this is an example of a native method issuing direct calls - otherwise known
218 * We don't have to deal with class init here anymore, since this is called
219 * via the class object of the class to instantiate
222 public int newInstance____Ljava_lang_Object_2 (MJIEnv env, int robj) {
223 ThreadInfo ti = env.getThreadInfo();
224 DirectCallStackFrame frame = ti.getReturnedDirectCall();
226 ClassInfo ci = env.getReferredClassInfo(robj); // what are we
227 MethodInfo miCtor = ci.getMethod("<init>()V", true); // note there always is one since something needs to call Object()
229 if (frame == null){ // first time around
230 if(ci.isAbstract()){ // not allowed to instantiate
231 env.throwException("java.lang.InstantiationException");
235 // <2do> - still need to handle protected
236 if (miCtor.isPrivate()) {
237 env.throwException("java.lang.IllegalAccessException", "cannot access non-public member of class " + ci.getName());
241 int objRef = env.newObjectOfUncheckedClass(ci); // create the thing
243 frame = miCtor.createDirectCallStackFrame(ti, 1);
244 // note that we don't set this as a reflection call since it is supposed to propagate exceptions
245 frame.setReferenceArgument(0, objRef, null);
246 frame.setLocalReferenceVariable(0, objRef); // (1) store ref for retrieval during re-exec
249 // check if we have to push clinits
250 ci.initializeClass(ti);
252 env.repeatInvocation();
255 } else { // re-execution
256 int objRef = frame.getLocalVariable(0); // that's the object ref we set in (1)
262 public int getSuperclass____Ljava_lang_Class_2 (MJIEnv env, int robj) {
263 ClassInfo ci = env.getReferredClassInfo( robj);
264 ClassInfo sci = ci.getSuperClass();
266 return sci.getClassObjectRef();
272 int getMethod (MJIEnv env, int clsRef, ClassInfo ciMethod, String mname, int argTypesRef,
273 boolean isRecursiveLookup, boolean publicOnly) {
275 ClassInfo ci = env.getReferredClassInfo( clsRef);
277 StringBuilder sb = new StringBuilder(mname);
279 int nParams = argTypesRef != MJIEnv.NULL ? env.getArrayLength(argTypesRef) : 0;
280 for (int i=0; i<nParams; i++) {
281 int cRef = env.getReferenceArrayElement(argTypesRef, i);
282 ClassInfo cit = env.getReferredClassInfo( cRef);
283 String tname = cit.getName();
284 String tcode = tname;
285 tcode = Types.getTypeSignature(tcode, false);
289 String fullMthName = sb.toString();
291 MethodInfo mi = ci.getReflectionMethod(fullMthName, isRecursiveLookup);
292 if (mi == null || (publicOnly && !mi.isPublic())) {
293 env.throwException("java.lang.NoSuchMethodException", ci.getName() + '.' + fullMthName);
297 return createMethodObject(env, ciMethod, mi);
301 int createMethodObject (MJIEnv env, ClassInfo objectCi, MethodInfo mi) {
302 // NOTE - we rely on Constructor and Method peers being initialized
304 return JPF_java_lang_reflect_Constructor.createConstructorObject(env, objectCi, mi);
306 return JPF_java_lang_reflect_Method.createMethodObject(env, objectCi, mi);
311 public int getDeclaredMethod__Ljava_lang_String_2_3Ljava_lang_Class_2__Ljava_lang_reflect_Method_2 (MJIEnv env, int clsRef,
312 int nameRef, int argTypesRef) {
313 ClassInfo mci = getInitializedClassInfo(env, METHOD_CLASSNAME);
315 env.repeatInvocation();
319 String mname = env.getStringObject(nameRef);
320 return getMethod(env, clsRef, mci, mname, argTypesRef, false, false);
324 public int getDeclaredConstructor___3Ljava_lang_Class_2__Ljava_lang_reflect_Constructor_2 (MJIEnv env,
327 ClassInfo mci = getInitializedClassInfo(env, CONSTRUCTOR_CLASSNAME);
329 env.repeatInvocation();
333 int ctorRef = getMethod(env,clsRef, mci, "<init>",argTypesRef,false, false);
338 public int getMethod__Ljava_lang_String_2_3Ljava_lang_Class_2__Ljava_lang_reflect_Method_2 (MJIEnv env, int clsRef,
339 int nameRef, int argTypesRef) {
340 ClassInfo mci = getInitializedClassInfo(env, METHOD_CLASSNAME);
342 env.repeatInvocation();
346 String mname = env.getStringObject(nameRef);
347 return getMethod( env, clsRef, mci, mname, argTypesRef, true, true);
350 private void addDeclaredMethodsRec (boolean includeSuperClasses, HashMap<String,MethodInfo>methods, ClassInfo ci){
352 if (includeSuperClasses){ // do NOT include Object methods for interfaces
353 ClassInfo sci = ci.getSuperClass();
355 addDeclaredMethodsRec( includeSuperClasses, methods,sci);
359 ClassLoaderInfo cl = ci.getClassLoaderInfo();
360 for (String ifcName : ci.getDirectInterfaceNames()){
361 ClassInfo ici = cl.getResolvedClassInfo(ifcName); // has to be already defined, so no exception
362 addDeclaredMethodsRec( includeSuperClasses, methods,ici);
365 for (MethodInfo mi : ci.getDeclaredMethodInfos()) {
366 // filter out non-public, <clinit> and <init>
367 if (mi.isPublic() && (mi.getName().charAt(0) != '<')) {
368 String mname = mi.getUniqueName();
370 if (!(ci.isInterface() && methods.containsKey(mname))){
371 methods.put(mname, mi);
378 public int getMethods_____3Ljava_lang_reflect_Method_2 (MJIEnv env, int objref) {
379 ClassInfo mci = getInitializedClassInfo(env, METHOD_CLASSNAME);
381 env.repeatInvocation();
385 ClassInfo ci = env.getReferredClassInfo(objref);
387 // collect all the public, non-ctor instance methods
388 if (!ci.isPrimitive()) {
389 HashMap<String,MethodInfo> methods = new HashMap<String,MethodInfo>();
390 addDeclaredMethodsRec( !ci.isInterface(), methods,ci);
392 int n = methods.size();
393 int aref = env.newObjectArray("Ljava/lang/reflect/Method;", n);
396 for (MethodInfo mi : methods.values()){
397 int mref = createMethodObject(env, mci, mi);
398 env.setReferenceArrayElement(aref,i++,mref);
404 return env.newObjectArray("Ljava/lang/reflect/Method;", 0);
409 public int getDeclaredMethods_____3Ljava_lang_reflect_Method_2 (MJIEnv env, int objref) {
410 ClassInfo mci = getInitializedClassInfo(env, METHOD_CLASSNAME);
412 env.repeatInvocation();
416 ClassInfo ci = env.getReferredClassInfo(objref);
417 MethodInfo[] methodInfos = ci.getDeclaredMethodInfos();
419 // we have to filter out the ctors and the static init
420 int nMth = methodInfos.length;
421 for (int i=0; i<methodInfos.length; i++){
422 if (methodInfos[i].getName().charAt(0) == '<'){
423 methodInfos[i] = null;
428 int aref = env.newObjectArray("Ljava/lang/reflect/Method;", nMth);
430 for (int i=0, j=0; i<methodInfos.length; i++) {
431 if (methodInfos[i] != null){
432 int mref = createMethodObject(env, mci, methodInfos[i]);
433 env.setReferenceArrayElement(aref,j++,mref);
440 int getConstructors (MJIEnv env, int objref, boolean publicOnly){
441 ClassInfo mci = getInitializedClassInfo(env, CONSTRUCTOR_CLASSNAME);
443 env.repeatInvocation();
447 ClassInfo ci = env.getReferredClassInfo(objref);
448 ArrayList<MethodInfo> ctors = new ArrayList<MethodInfo>();
450 // we have to filter out the ctors and the static init
451 for (MethodInfo mi : ci.getDeclaredMethodInfos()){
452 if (mi.getName().equals("<init>")){
453 if (!publicOnly || mi.isPublic()) {
459 int nCtors = ctors.size();
460 int aref = env.newObjectArray("Ljava/lang/reflect/Constructor;", nCtors);
462 for (int i=0; i<nCtors; i++){
463 env.setReferenceArrayElement(aref, i, createMethodObject(env, mci, ctors.get(i)));
470 public int getConstructors_____3Ljava_lang_reflect_Constructor_2 (MJIEnv env, int objref){
471 return getConstructors(env, objref, true);
475 public int getDeclaredConstructors_____3Ljava_lang_reflect_Constructor_2 (MJIEnv env, int objref){
476 return getConstructors(env, objref, false);
480 public int getConstructor___3Ljava_lang_Class_2__Ljava_lang_reflect_Constructor_2 (MJIEnv env, int clsRef,
482 ClassInfo mci = getInitializedClassInfo(env, CONSTRUCTOR_CLASSNAME);
484 env.repeatInvocation();
488 // <2do> should only return a public ctor
489 return getMethod(env,clsRef, mci, "<init>",argTypesRef,false,true);
492 // this is only used for system classes such as java.lang.reflect.Method
493 ClassInfo getInitializedClassInfo (MJIEnv env, String clsName){
494 ThreadInfo ti = env.getThreadInfo();
495 Instruction insn = ti.getPC();
496 ClassInfo ci = ClassLoaderInfo.getSystemResolvedClassInfo( clsName);
498 if (ci.initializeClass(ti)){
506 public void initialize0____V (MJIEnv env, int clsObjRef){
507 ClassInfo ci = env.getReferredClassInfo( clsObjRef);
508 ci.initializeClass(ThreadInfo.currentThread);
511 Set<ClassInfo> getInitializedInterfaces (MJIEnv env, ClassInfo ci){
512 ThreadInfo ti = env.getThreadInfo();
513 Instruction insn = ti.getPC();
515 Set<ClassInfo> ifcs = ci.getAllInterfaceClassInfos();
516 for (ClassInfo ciIfc : ifcs){
517 if (ciIfc.initializeClass(ti)){
525 static int createFieldObject (MJIEnv env, FieldInfo fi, ClassInfo fci){
526 int regIdx = JPF_java_lang_reflect_Field.registerFieldInfo(fi);
528 int eidx = env.newObject(fci);
529 ElementInfo ei = env.getModifiableElementInfo(eidx);
530 ei.setIntField("regIdx", regIdx);
536 public int getDeclaredFields_____3Ljava_lang_reflect_Field_2 (MJIEnv env, int objRef) {
537 ClassInfo fci = getInitializedClassInfo(env, FIELD_CLASSNAME);
539 env.repeatInvocation();
543 ClassInfo ci = env.getReferredClassInfo(objRef);
544 int nInstance = ci.getNumberOfDeclaredInstanceFields();
545 int nStatic = ci.getNumberOfStaticFields();
546 int aref = env.newObjectArray("Ljava/lang/reflect/Field;", nInstance + nStatic);
549 for (i=0; i<nStatic; i++) {
550 FieldInfo fi = ci.getStaticField(i);
551 env.setReferenceArrayElement(aref, j++, createFieldObject(env, fi, fci));
554 for (i=0; i<nInstance; i++) {
555 FieldInfo fi = ci.getDeclaredInstanceField(i);
556 env.setReferenceArrayElement(aref, j++, createFieldObject(env, fi, fci));
563 public int getFields_____3Ljava_lang_reflect_Field_2 (MJIEnv env, int clsRef){
564 ClassInfo fci = getInitializedClassInfo(env, FIELD_CLASSNAME);
566 env.repeatInvocation();
570 ClassInfo ci = env.getReferredClassInfo(clsRef);
571 // interfaces might not be initialized yet, so we have to check first
572 Set<ClassInfo> ifcs = getInitializedInterfaces( env, ci);
574 env.repeatInvocation();
578 ArrayList<FieldInfo> fiList = new ArrayList<FieldInfo>();
579 for (; ci != null; ci = ci.getSuperClass()){
580 // the host VM returns them in order of declaration, but the spec says there is no guaranteed order so we keep it simple
581 for (FieldInfo fi : ci.getDeclaredInstanceFields()){
586 for (FieldInfo fi : ci.getDeclaredStaticFields()){
593 for (ClassInfo ciIfc : ifcs){
594 for (FieldInfo fi : ciIfc.getDeclaredStaticFields()){
595 fiList.add(fi); // there are no non-public fields in interfaces
599 int aref = env.newObjectArray("Ljava/lang/reflect/Field;", fiList.size());
601 for (FieldInfo fi : fiList){
602 env.setReferenceArrayElement(aref, j++, createFieldObject(env, fi, fci));
608 int getField (MJIEnv env, int clsRef, int nameRef, boolean isRecursiveLookup) {
609 ClassInfo ci = env.getReferredClassInfo( clsRef);
610 String fname = env.getStringObject(nameRef);
613 if (isRecursiveLookup) {
614 fi = ci.getInstanceField(fname);
616 fi = ci.getStaticField(fname);
619 fi = ci.getDeclaredInstanceField(fname);
621 fi = ci.getDeclaredStaticField(fname);
626 env.throwException("java.lang.NoSuchFieldException", fname);
630 // don't do a Field clinit before we know there is such a field
631 ClassInfo fci = getInitializedClassInfo( env, FIELD_CLASSNAME);
633 env.repeatInvocation();
637 return createFieldObject( env, fi, fci);
642 public int getDeclaredField__Ljava_lang_String_2__Ljava_lang_reflect_Field_2 (MJIEnv env, int clsRef, int nameRef) {
643 return getField(env,clsRef,nameRef, false);
647 public int getField__Ljava_lang_String_2__Ljava_lang_reflect_Field_2 (MJIEnv env, int clsRef, int nameRef) {
648 return getField(env,clsRef,nameRef, true);
652 public int getModifiers____I (MJIEnv env, int clsRef){
653 ClassInfo ci = env.getReferredClassInfo(clsRef);
654 return ci.getModifiers();
658 public int getEnumConstants_____3Ljava_lang_Object_2 (MJIEnv env, int clsRef){
659 ClassInfo ci = env.getReferredClassInfo(clsRef);
661 if (env.requiresClinitExecution(ci)){
662 env.repeatInvocation();
666 if (ci.getSuperClass().getName().equals("java.lang.Enum")) {
667 ArrayList<FieldInfo> list = new ArrayList<FieldInfo>();
668 String cName = ci.getName();
670 for (FieldInfo fi : ci.getDeclaredStaticFields()) {
671 if (fi.isFinal() && cName.equals(fi.getType())){
676 int aRef = env.newObjectArray(cName, list.size());
677 StaticElementInfo sei = ci.getStaticElementInfo();
679 for (FieldInfo fi : list){
680 env.setReferenceArrayElement( aRef, i++, sei.getReferenceField(fi));
689 public int getInterfaces_____3Ljava_lang_Class_2 (MJIEnv env, int clsRef){
690 ClassInfo ci = env.getReferredClassInfo(clsRef);
691 int aref = MJIEnv.NULL;
692 ThreadInfo ti = env.getThreadInfo();
694 // contrary to the API doc, this only returns the interfaces directly
695 // implemented by this class, not it's bases
696 // <2do> this is not exactly correct, since the interfaces should be ordered
697 Set<ClassInfo> interfaces = ci.getInterfaceClassInfos();
698 aref = env.newObjectArray("Ljava/lang/Class;", interfaces.size());
701 for (ClassInfo ifc: interfaces){
702 env.setReferenceArrayElement(aref, i++, ifc.getClassObjectRef());
710 * <2do> needs to load from the classfile location, NOT the MJIEnv (native) class
712 * @author Sebastian Gfeller (sebastian.gfeller@gmail.com)
713 * @author Tihomir Gvero (tihomir.gvero@gmail.com)
716 public int getByteArrayFromResourceStream__Ljava_lang_String_2___3B(MJIEnv env, int clsRef, int nameRef) {
717 String name = env.getStringObject(nameRef);
719 // <2do> this is not loading from the classfile location! fix it
720 InputStream is = env.getClass().getResourceAsStream(name);
724 // We assume that the entire input stream can be read at the moment,
725 // although this could break.
726 byte[] content = null;
728 content = new byte[is.available()];
730 } catch (IOException e) {
731 throw new RuntimeException(e);
733 // Now if everything worked, the content should be in the byte buffer.
734 // We put this buffer into the JPF VM.
735 return env.newByteArray(content);
739 public int getEnclosingClass____Ljava_lang_Class_2 (MJIEnv env, int clsRef) {
740 ClassInfo ciEncl = env.getReferredClassInfo( clsRef).getEnclosingClassInfo();
746 if (ciEncl.initializeClass(env.getThreadInfo())) {
747 env.repeatInvocation();
751 return ciEncl.getClassObjectRef();
755 public int getDeclaredClasses_____3Ljava_lang_Class_2 (MJIEnv env, int clsRef){
756 ClassInfo ci = env.getReferredClassInfo(clsRef);
757 String[] innerClassNames = ci.getInnerClasses();
758 int aref = MJIEnv.NULL;
759 ThreadInfo ti = env.getThreadInfo();
761 MethodInfo mi = ti.getTopFrame().getPrevious().getMethodInfo();
762 // class of the method that includes the invocation of Class.getDeclaredClasses
763 ClassInfo cls = mi.getClassInfo();
765 // first resolve all the inner classes
766 int length = innerClassNames.length;
767 ClassInfo[] resolvedInnerClass = new ClassInfo[length];
768 for(int i=0; i<length; i++) {
770 resolvedInnerClass[i] = cls.resolveReferencedClass(innerClassNames[i]);
771 } catch(LoadOnJPFRequired lre) {
772 env.repeatInvocation();
777 aref = env.newObjectArray("Ljava/lang/Class;", innerClassNames.length);
778 for (int i=0; i<length; i++){
779 ClassInfo ici = resolvedInnerClass[i];
780 if (!ici.isRegistered()) {
781 ici.registerClass(ti);
783 env.setReferenceArrayElement(aref, i, ici.getClassObjectRef());
789 private String getCanonicalName (ClassInfo ci){
791 String canonicalName = getCanonicalName(ci.getComponentClassInfo());
792 if (canonicalName != null){
793 return canonicalName + "[]";
798 if (isLocalOrAnonymousClass(ci)) {
801 if (ci.getEnclosingClassInfo() == null){
804 String enclosingName = getCanonicalName(ci.getEnclosingClassInfo());
805 if (enclosingName == null){ return null; }
806 return enclosingName + "." + ci.getSimpleName();
811 public int getCanonicalName____Ljava_lang_String_2 (MJIEnv env, int clsRef){
812 ClassInfo ci = env.getReferredClassInfo(clsRef);
813 return env.newString(getCanonicalName(ci));
817 public boolean isAnnotation____Z (MJIEnv env, int clsObjRef){
818 ClassInfo ci = env.getReferredClassInfo(clsObjRef);
819 return (ci.getModifiers() & 0x2000) != 0;
823 public boolean isAnnotationPresent__Ljava_lang_Class_2__Z (MJIEnv env, int clsObjRef, int annoClsObjRef){
824 ClassInfo ci = env.getReferredClassInfo(clsObjRef);
825 ClassInfo ciAnno = env.getReferredClassInfo(annoClsObjRef);
827 return ci.getAnnotation( ciAnno.getName()) != null;
831 public int getDeclaredAnnotations_____3Ljava_lang_annotation_Annotation_2 (MJIEnv env, int robj){
832 ClassInfo ci = env.getReferredClassInfo(robj);
835 return env.newAnnotationProxies(ci.getDeclaredAnnotations());
836 } catch (ClinitRequired x){
837 env.handleClinitRequest(x.getRequiredClassInfo());
843 public int getEnclosingConstructor____Ljava_lang_reflect_Constructor_2 (MJIEnv env, int robj){
844 ClassInfo mci = getInitializedClassInfo(env, CONSTRUCTOR_CLASSNAME);
846 env.repeatInvocation();
849 ClassInfo ci = env.getReferredClassInfo(robj);
850 MethodInfo enclosingMethod = ci.getEnclosingMethodInfo();
852 if ((enclosingMethod != null) && enclosingMethod.isCtor()){
853 return createMethodObject(env, mci, enclosingMethod);
859 public int getEnclosingMethod____Ljava_lang_reflect_Method_2 (MJIEnv env, int robj){
860 ClassInfo mci = getInitializedClassInfo(env, METHOD_CLASSNAME);
862 env.repeatInvocation();
865 ClassInfo ci = env.getReferredClassInfo(robj);
866 MethodInfo enclosingMethod = ci.getEnclosingMethodInfo();
868 if ((enclosingMethod != null) && !enclosingMethod.isCtor()){
869 return createMethodObject(env, mci, enclosingMethod);
875 public boolean isAnonymousClass____Z (MJIEnv env, int robj){
876 ClassInfo ci = env.getReferredClassInfo(robj);
878 if (ci.getName().contains("$")){
879 cname = ci.getName().substring(ci.getName().lastIndexOf('$') + 1);
881 return (cname == null) ? false : cname.matches("\\d+?");
885 public boolean isEnum____Z (MJIEnv env, int robj){
886 ClassInfo ci = env.getReferredClassInfo(robj);
890 // Similar to getEnclosingClass() except it returns null for the case of
893 public int getDeclaringClass____Ljava_lang_Class_2 (MJIEnv env, int clsRef){
894 ClassInfo ci = env.getReferredClassInfo(clsRef);
895 if (isLocalOrAnonymousClass(ci)){
898 return getEnclosingClass____Ljava_lang_Class_2(env, clsRef);
903 public boolean isLocalClass____Z (MJIEnv env, int robj){
904 ClassInfo ci = env.getReferredClassInfo(robj);
905 return isLocalOrAnonymousClass(ci) && !isAnonymousClass____Z(env, robj);
908 private boolean isLocalOrAnonymousClass (ClassInfo ci){
909 return (ci.getEnclosingMethodInfo() != null);
913 public boolean isMemberClass____Z (MJIEnv env, int robj){
914 ClassInfo ci = env.getReferredClassInfo(robj);
915 return (ci.getEnclosingClassInfo() != null) && !isLocalOrAnonymousClass(ci);
919 * Append the package name prefix of the class represented by robj, if the name is not
920 * absolute. OW, remove leading "/".
923 public int getResolvedName__Ljava_lang_String_2__Ljava_lang_String_2 (MJIEnv env, int robj, int resRef){
924 String rname = env.getStringObject(resRef);
925 ClassInfo ci = env.getReferredClassInfo(robj);
929 if (!rname.startsWith("/")) {
931 while (c.isArray()) {
932 c = c.getComponentClassInfo();
934 String baseName = c.getName();
935 int index = baseName.lastIndexOf('.');
937 rname = baseName.substring(0, index).replace('.', '/')
941 rname = rname.substring(1);
944 return env.newString(rname);