You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by dl...@apache.org on 2006/04/05 07:11:14 UTC

svn commit: r391498 - /incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/classutil.c

Author: dlydick
Date: Tue Apr  4 22:11:13 2006
New Revision: 391498

URL: http://svn.apache.org/viewcvs?rev=391498&view=rev
Log:
Restructured class hierarchy function names and local variables.

Added classutil_class_is_accessible_to() function.

Modified:
    incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/classutil.c

Modified: incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/classutil.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/classutil.c?rev=391498&r1=391497&r2=391498&view=diff
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/classutil.c (original)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/classutil.c Tue Apr  4 22:11:13 2006
@@ -58,10 +58,13 @@
 
 
 #include "jvmcfg.h"
+#include "cfmacros.h"
 #include "classfile.h"
 #include "jvm.h"
 #include "jvmclass.h"
 #include "linkage.h"
+#include "nts.h"
+#include "utf.h"
 
 
 /*!
@@ -91,9 +94,11 @@
 /*!
  * @brief Examine whether or not one class is a subclass of another
  *
- * For an @link #rtrue rtrue@endlink comparison, class @c @b clsidx1
- * must be either the same class as class @c @b clsidx2 or a subclass
- * of it.
+ * This effectively asks the OO hierarchy question, "Is @c @b clsidx1
+ * a @c @b clsidx2 ?" For an @link #rtrue rtrue@endlink comparison,
+ * class @c @b clsidx1 must be either the same class as class
+ * @c @b clsidx2 or a subclass of it.  In other words, the true
+ * comparison affirms "@c @b clsidx1 is a @c @b clsidx2 ."
  *
  *
  * @returns @link #rtrue rtrue@endlink if @c @b clsidx1 is the same
@@ -105,8 +110,8 @@
  *          is @link #rtrue rtrue@endlink.
  *
  */
-rboolean classutil_subclass_of(jvm_class_index clsidx1,
-                               jvm_class_index clsidx2)
+rboolean classutil_class_is_a(jvm_class_index clsidx1,
+                              jvm_class_index clsidx2)
 {
     /* Disallow comparison with null class */
     if ((jvm_class_index_null == clsidx1) ||
@@ -138,7 +143,7 @@
          * If found top of hierarchy, namely java.lang.Object, then
          * search failed.
          */
-        if (jvm_class_index_null == pcfs->super_class)
+        if (CONSTANT_CP_DEFAULT_INDEX == pcfs->super_class)
         {
             break;
         }
@@ -167,7 +172,7 @@
     /* Superclass of @c @b clsidx1 not found to be @c @b clsidx2 */
     return(rfalse);
 
-} /* END of classutil_subclass_of() */
+} /* END of classutil_class_is_a() */
 
 
 /*!
@@ -186,10 +191,10 @@
  *          is @link #rtrue rtrue@endlink.
  *
  */
-rboolean classutil_implements_interface(jvm_class_index clsidx1,
-                                        jvm_class_index clsidx2)
+rboolean classutil_class_implements_interface(jvm_class_index clsidx1,
+                                              jvm_class_index clsidx2)
 {
-    ClassFile *pcfs, *pcfs1;
+    ClassFile *pcfs1, *pcfs2, *pcfs3;
     u2         ifidx;
 
     /* Disallow comparison with null class */
@@ -204,10 +209,10 @@
      * and if comparend class index is NOT an interface.
      */
     pcfs1 = CLASS_OBJECT_LINKAGE(clsidx1)->pcfs;
-    pcfs  = CLASS_OBJECT_LINKAGE(clsidx2)->pcfs;
+    pcfs2 = CLASS_OBJECT_LINKAGE(clsidx2)->pcfs;
 
     if ( (pcfs1->access_flags & ACC_INTERFACE) ||
-        (!(pcfs->access_flags & ACC_INTERFACE)))
+        (!(pcfs2->access_flags & ACC_INTERFACE)))
     {
         return(rfalse);
     }
@@ -239,13 +244,13 @@
             return(rtrue);
         }
 
-        pcfs = CLASS_OBJECT_LINKAGE(clsidxINTFC)->pcfs;
+        pcfs3 = CLASS_OBJECT_LINKAGE(clsidxINTFC)->pcfs;
 
         /*
          * If found top of hierarchy, namely java.lang.Object class
          * or highest-level interface, then search cannot succeed.
          */
-        if (jvm_class_index_null == pcfs->super_class)
+        if (CONSTANT_CP_DEFAULT_INDEX == pcfs3->super_class)
         {
             break;
         }
@@ -253,8 +258,8 @@
         /* Look at superclass of this one */
         clsidxINTFC =
             class_load_from_cp_entry_utf(
-                                         pcfs->constant_pool
-                                           [pcfs->super_class],
+                                         pcfs3->constant_pool
+                                           [pcfs3->super_class],
                                          rfalse,
                                          (jint *) rnull);
 
@@ -263,8 +268,8 @@
          *
          * WARNING:  RECURSIVE CALL!!! Will go as deep as hierarchy.
          */
-        if (rtrue == classutil_superinterface_of(clsidx2,
-                                                 clsidxINTFC))
+        if (rtrue == classutil_class_is_superinterface_of(clsidx2,
+                                                          clsidxINTFC))
         {
             return(rtrue);
         }
@@ -273,7 +278,7 @@
     /* Class of @c @b clsidx1 not found to implement @c @b clsidx2 */
     return(rfalse);
 
-} /* END of classutil_implements_interface() */
+} /* END of classutil_class_implements_interface() */
 
 
 /*!
@@ -294,10 +299,10 @@
  *          is @link #rtrue rtrue@endlink.
  *
  */
-rboolean classutil_superinterface_of(jvm_class_index clsidx1,
-                                     jvm_class_index clsidx2)
+rboolean classutil_class_is_superinterface_of(jvm_class_index clsidx1,
+                                              jvm_class_index clsidx2)
 {
-    ClassFile *pcfs, *pcfs2;
+    ClassFile *pcfs1, *pcfs2, *pcfs3;
     u2         ifidx;
 
     /* Disallow comparison with null class */
@@ -308,8 +313,8 @@
     }
 
     /* Can only be true if comparator class index is an interface */
-    pcfs = CLASS_OBJECT_LINKAGE(clsidx1)->pcfs;
-    if (!(pcfs->access_flags & ACC_INTERFACE))
+    pcfs1 = CLASS_OBJECT_LINKAGE(clsidx1)->pcfs;
+    if (!(pcfs1->access_flags & ACC_INTERFACE))
     {
         return(rfalse);
     }
@@ -326,20 +331,20 @@
      * If starting at top of hierarchy, namely java.lang.Object class
      * or highest-level interface, then search cannot succeed.
      */
-    pcfs = CLASS_OBJECT_LINKAGE(clsidx2)->pcfs;
+    pcfs2 = CLASS_OBJECT_LINKAGE(clsidx2)->pcfs;
 
-    if (jvm_class_index_null == pcfs->super_class)
+    if (CONSTANT_CP_DEFAULT_INDEX == pcfs2->super_class)
     {
         return(rfalse);
     }
 
     /* If no interfaces, then this loop is skipped */
-    for (ifidx = 0; ifidx < pcfs->interfaces_count; ifidx++)
+    for (ifidx = 0; ifidx < pcfs2->interfaces_count; ifidx++)
     {
         jvm_class_index clsidxINTFC =
-                class_load_from_cp_entry_utf(pcfs->constant_pool[ifidx],
-                                             rfalse,
-                                             (jint *) rnull);
+            class_load_from_cp_entry_utf(pcfs2->constant_pool[ifidx],
+                                         rfalse,
+                                         (jint *) rnull);
 
         /* Check if this class index matches requested interface */
         if (clsidx1 == clsidxINTFC)
@@ -347,13 +352,13 @@
             return(rtrue);
         }
 
-        pcfs2 = CLASS_OBJECT_LINKAGE(clsidxINTFC)->pcfs;
+        pcfs3 = CLASS_OBJECT_LINKAGE(clsidxINTFC)->pcfs;
 
         /*
          * If found top of hierarchy, namely java.lang.Object class
          * or highest-level interface, then search cannot succeed.
          */
-        if (jvm_class_index_null == pcfs2->super_class)
+        if (CONSTANT_CP_DEFAULT_INDEX == pcfs3->super_class)
         {
             break;
         }
@@ -361,7 +366,7 @@
         /* Look at superclass of this one */
         clsidxINTFC =
             class_load_from_cp_entry_utf(
-                           pcfs2->constant_pool[pcfs2->super_class],
+                           pcfs3->constant_pool[pcfs3->super_class],
                                          rfalse,
                                          (jint *) rnull);
 
@@ -370,8 +375,8 @@
          *
          * WARNING:  RECURSIVE CALL!!! Will go as deep as hierarchy.
          */
-        if (rtrue == classutil_superinterface_of(clsidx1,
-                                                 clsidxINTFC))
+        if (rtrue == classutil_class_is_superinterface_of(clsidx1,
+                                                          clsidxINTFC))
         {
             return(rtrue);
         }
@@ -380,7 +385,106 @@
     /* Superclass of @c @b clsidx2 not found to be @c @b clsidx1 */
     return(rfalse);
 
-} /* END of classutil_superinterface_of() */
+} /* END of classutil_class_is_superinterface_of() */
+
+
+/*!
+ * @brief Examine whether or not a class may be accessed by another
+ *
+ * For an @link #rtrue rtrue@endlink comparison, the class @c @b clsidx1
+ * must either be public or must be in the same runtime package
+ * as @c @b clsidx2, as defined in the JVM spec section 5.4.4.
+ *
+ *
+ * @returns @link #rtrue rtrue@endlink if @c @b clsidx1 is either
+ *          @link #ACC_PUBLIC ACC_PUBLIC@endlink or must be
+ *          in the same runtime package as @c @b cldidx2 or is
+ *          actually the same class index as @c @b clsidx2 .
+ *
+ */
+rboolean classutil_class_is_accessible_to(jvm_class_index clsidx1,
+                                          jvm_class_index clsidx2)
+{
+    ClassFile *pcfs1 = CLASS_OBJECT_LINKAGE(clsidx1)->pcfs;
+
+    /* Class is accessible if it is public or the same class */
+    if ((clsidx1 ==  clsidx2) || (ACC_PUBLIC & pcfs1->access_flags))
+    {
+        return(rtrue);
+    }
+
+    /*
+     * Class is accessible if it is in the same runtime package.
+     * This may be discovered by comparing the first part of the
+     * path names (before final path delimiter) for equality.
+     */
+
+    CONSTANT_Utf8_info *putfname1 = PTR_CP1_CLASS_NAME(pcfs1,
+                                                     pcfs1->this_class);
+
+    ClassFile *pcfs2 = CLASS_OBJECT_LINKAGE(clsidx2)->pcfs;
+
+    CONSTANT_Utf8_info *putfname2 = PTR_CP1_CLASS_NAME(pcfs2,
+                                                     pcfs2->this_class);
+
+    /* Truncate class names from both strings, compare remainder */
+    rchar *prcharclsfmt1 = utf_utf2prchar(putfname1);
+    rchar *prcharclsfmt2 = utf_utf2prchar(putfname2);
+
+    /* Strip class formatting, if any, before comparison */
+    /*!
+     * @todo   HARMONY-6-jvm-classutil.c-2 Is this stripping really
+     *         necessary?  Or are the input parameters going to always
+     *         be guaranteed to be @e only class names without
+     *         any formatting?
+     */
+    rchar *prcharname1 =
+        nts_prchar2prchar_unformatted_classname(prcharclsfmt1);
+    rchar *prcharname2 =
+        nts_prchar2prchar_unformatted_classname(prcharclsfmt2);
+
+    HEAP_FREE_DATA(prcharclsfmt1);
+    HEAP_FREE_DATA(prcharclsfmt2);
+
+    /* Locate end of path component, if any */
+    rchar *pnameonly1 = portable_strrchr(prcharname1,
+                                     CLASSNAME_INTERNAL_DELIMITER_CHAR);
+    rchar *pnameonly2 = portable_strrchr(prcharname2,
+                                     CLASSNAME_INTERNAL_DELIMITER_CHAR);
+
+    /* Check for two unpackaged classes, accessible if so */
+    if ((rnull == pnameonly1) && (rnull == pnameonly2))
+    {
+        HEAP_FREE_DATA(prcharname1);
+        HEAP_FREE_DATA(prcharname2);
+        return(rtrue);
+    }
+
+    /* Not accessible if only one is unpackaged */
+    if (((rnull == pnameonly1) && (rnull != pnameonly2)) ||
+        ((rnull != pnameonly1) && (rnull == pnameonly2)))
+    {
+        HEAP_FREE_DATA(prcharname1);
+        HEAP_FREE_DATA(prcharname2);
+        return(rfalse);
+    }
+
+    /*
+     * Both classes area packaged, so compare null-terminated
+     * package name strings
+     */
+    *pnameonly1 = '\0';
+    *pnameonly2 = '\0';
+
+    rboolean rc = (0 == portable_strcmp(prcharname1, prcharname2))
+                  ? rtrue
+                  : rfalse;
+
+    HEAP_FREE_DATA(prcharname1);
+    HEAP_FREE_DATA(prcharname2);
+    return(rc);
+
+} /* END of classutil_class_is_accessible_to() */
 
 
 /*!