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 2007/08/12 22:46:13 UTC

svn commit: r565142 - /harmony/enhanced/sandbox/bootjvm/bootJVM/jvm/src/class.c

Author: dlydick
Date: Sun Aug 12 13:46:12 2007
New Revision: 565142

URL: http://svn.apache.org/viewvc?view=rev&rev=565142
Log:
Disallow in class_find_by_cp_entry() all constant_pool
entries except UTF8.

Added support for reading class info from Java
archives as well as explicit class files.

Added test for an abstract method in class_load_resolve_clinit()
with same arbitrary decision as for when non 'clinit' method
was available, and marked as a to-do item.

Mark JVM for shutdown if no previous thread to revive.

Modified:
    harmony/enhanced/sandbox/bootjvm/bootJVM/jvm/src/class.c

Modified: harmony/enhanced/sandbox/bootjvm/bootJVM/jvm/src/class.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/sandbox/bootjvm/bootJVM/jvm/src/class.c?view=diff&rev=565142&r1=565141&r2=565142
==============================================================================
--- harmony/enhanced/sandbox/bootjvm/bootJVM/jvm/src/class.c (original)
+++ harmony/enhanced/sandbox/bootjvm/bootJVM/jvm/src/class.c Sun Aug 12 13:46:12 2007
@@ -53,6 +53,7 @@
 #include "exit.h"
 #include "field.h"
 #include "gc.h"
+#include "jar.h"
 #include "jvm.h"
 #include "jvmclass.h"
 #include "linkage.h"
@@ -276,7 +277,7 @@
 
 
 /*!
- * @brief Load a class into ad class table slot and load up its
+ * @brief Load a class into a class table slot and load up its
  * associated class definition object.
  *
  * Create a Java class itself (and NOT a @c @b new instance
@@ -895,6 +896,15 @@
 
     jvm_class_index clsidx;
 
+    /* Disallow all but UTF8 @c @b constant_pool entries */
+    if (CONSTANT_Utf8 != PTR_THIS_CP_Utf8(clsname)->tag)
+    {
+        /* Somebody goofed */
+        exit_throw_exception(EXIT_JVM_INTERNAL,
+                             JVMCLASS_JAVA_LANG_INTERNALERROR);
+/*NOTREACHED*/
+    }
+
     jvm_array_dim arraydims =
         utf_get_utf_arraydims(PTR_THIS_CP_Utf8(clsname));
 
@@ -1035,7 +1045,7 @@
  *
  *   where @b name is a null-terminated string passed as the only parm,
  *   and @b b is the byte array read in by classfile_read_classfile()
- *   or classfile_read_jarfile(), and @b off is zero, and @b len being
+ *   or jarutil_read_member(), and @b off is zero, and @b len being
  *   discovered by classfile_read_XXXfile().
  *
  * @todo  HARMONY-6-jvm-class.c-7 Spec section 5.3.4
@@ -1197,10 +1207,10 @@
          * the class.  All array class file pointers will point
          * to this class file structure.
          */
-        u1              *pcfd;
-        ClassFile       *pcfs;
-        rchar           *pcname;
-        jvm_class_index  clsidx;
+        u1               *pcfd;
+        ClassFile        *pcfs;
+        classpath_search *pcname;
+        jvm_class_index   clsidx;
 
         if (LOCAL_CONSTANT_NO_ARRAY_DIMS < arraydims)
         {
@@ -1237,40 +1247,33 @@
 
             pcname = classpath_get_from_cp_entry_utf(pnofmt);
 
-            HEAP_FREE_DATA(pnofmt);
-
-            GENERIC_FAILURE1_THROWERROR((rnull == pcname),
-                                        DMLNORM,
-                                        arch_function_name,
-                                        "Cannot locate class %s",
-                                        clsname,
-                                        EXIT_JVM_CLASS,
+            GENERIC_FAILURECP1_THROWERROR((rnull == pcname),
+                                          DMLNORM,
+                                          arch_function_name,
+                                          "Cannot locate class %*.*s",
+                                          pnofmt,
+                                          EXIT_JVM_CLASS,
                                JVMCLASS_JAVA_LANG_NOCLASSDEFFOUNDERROR,
-                                        pcname,
-                                        rnull);
+                                          rnull,
+                                          pnofmt);
 
             /*
-             * Check if JAR file or class file and read in the class
-             * file data stream as a simple binary image.
+             * Read in the class from wherever it was found, either
+             * in a Java archive or a class file.  Return a simple
+             * binary image of that data
              */
-            if (rtrue == classpath_isjar(pcname))
-            {
-                pcfd = classfile_read_jarfile(pcname);
-            }
-            else
-            {
-                pcfd = classfile_read_classfile(pcname);
-            }
+            pcfd = classfile_read(pcname, rtrue);
 
-            GENERIC_FAILURE1_THROWERROR((rnull == pcfd),
-                                        DMLNORM,
-                                        arch_function_name,
-                                        "Cannot read file %s",
-                                        pcname,
-                                        EXIT_JVM_CLASS,
+            GENERIC_FAILURECP1_THROWERROR((rnull == pcfd),
+                                          DMLNORM,
+                                          arch_function_name,
+                                          "Cannot read file %*.*s",
+                                          pnofmt,
+                                          EXIT_JVM_CLASS,
                                    JVMCLASS_JAVA_LANG_CLASSFORMATERROR,
-                                        pcfd,
-                                        pcname);
+                                          rnull,
+                                          pnofmt);
+
 
             /*! 
              * @todo  HARMONY-6-jvm-class.c-9 Throw
@@ -1290,18 +1293,18 @@
             /* Don't need file image any more */
             HEAP_FREE_DATA(pcfd);
 
-            GENERIC_FAILURE1_THROWERROR((rnull == pcfs),
-                                        DMLNORM,
-                                        arch_function_name,
-                                        "Invalid class file %s",
-                                        pcname,
-                                        EXIT_JVM_CLASS,
+            GENERIC_FAILURECP1_THROWERROR((rnull == pcfs),
+                                          DMLNORM,
+                                          arch_function_name,
+                                          "Invalid class file %*.*s",
+                                          pnofmt,
+                                          EXIT_JVM_CLASS,
                                    JVMCLASS_JAVA_LANG_CLASSFORMATERROR,
-                                        pcname,
-                                        rnull);
+                                          rnull,
+                                          pnofmt);
 
-            /* Don't need absolute path name any more, either */
-            HEAP_FREE_DATA(pcname);
+            /* Don't need unformatted class name any more, either */
+            HEAP_FREE_DATA(pnofmt);
 
             /*!
              * @internal Load superclass
@@ -1311,7 +1314,7 @@
              *        execution engine moves a new class from the
              *        START state into the RUNNABLE state.)
              */
-            if (jvm_class_index_null != pcfs->super_class)
+            if (jvm_constant_pool_index_null != pcfs->super_class)
             {
                 CONSTANT_Utf8_info *name = PTR_CP1_CLASS_NAME(pcfs,
                                                      pcfs->super_class);
@@ -1348,7 +1351,7 @@
                  */
                 (rvoid) class_load_resolve_clinit(super_name,
                                                   jvm_thread_index_null,
-                                                  rfalse,
+                 (rtrue == jvm_completely_initialized) ? rfalse : rtrue,
                                                   find_registerNatives);
 
                 /*
@@ -1438,7 +1441,7 @@
 
 
 /*!
- * @brief All-purpose class loading, load, resolve, @c @b \<clinit\> ,
+ * @brief All-purpose class linking, load, resolve, @c @b \<clinit\> ,
  * each step only run if needed.
  *
  * Load a class into the JVM, resolve its linkages, and run its
@@ -1529,6 +1532,8 @@
 {
     ARCH_FUNCTION_NAME(class_load_resolve_clinit);
 
+    rboolean shutdown_jvm = rfalse;
+
     jvm_class_index clsidx = class_load_from_prchar(clsname,
                                                    find_registerNatives,
                                                     (jint *) rnull);
@@ -1558,122 +1563,141 @@
                            LOCAL_CONSTANT_UTF8_CLASS_CONSTRUCTOR_PARMS);
     if (jvm_method_index_bad == mthidx)
     {
-        /*
-         * Return valid class index even if no @c @b \<clinit\>
-         * was available
+        /*!
+         * @todo HARMONY-6-jvm-class.c-21 Currently, return
+         * valid class index even if no @c @b \<clinit\>
+         * was available.  Is this the proper thing to do?
+         *
          */
         return(clsidx);
     }
-    else
-    {
-        jvm_thread_index thridxLOAD;
 
-        if (jvm_thread_index_null != thridx)
-        {
-            thridxLOAD = thridx;
+    jvm_thread_index thridxLOAD;
 
-            /*!
-             * @internal see similar logic for loading a new stack
-             *           frame and PC in thread_new_common()
-             *
-             */
+    if (jvm_thread_index_null != thridx)
+    {
+        thridxLOAD = thridx;
 
-            ClassFile *pcfs = CLASS_OBJECT_LINKAGE(clsidx)->pcfs;
+        /*!
+         * @internal see similar logic for loading a new stack
+         *           frame and PC in thread_new_common()
+         *
+         */
 
-            jvm_attribute_index codeatridx =
-                pcfs
-                  ->methods[mthidx]
-                    ->LOCAL_method_binding
-                      .codeatridxJVM;
+        ClassFile *pcfs = CLASS_OBJECT_LINKAGE(clsidx)->pcfs;
 
-            if (jvm_attribute_index_bad == codeatridx)
-            {
-                /*!
-                 * @todo HARMONY-6-jvm-class.c-13 Currently, return
-                 *       valid class index even if no @c @b \<clinit\>
-                 *       was available.  Is this correct?  Or should it
-                 *       throw a @b VerifyError since a method was
-                 *       declared, yet had no code area?  Take the
-                 *       easy way out for now, evaluate and maybe fix
-                 *       later.
-                 */
-                return(clsidx);
-            }
+        jvm_attribute_index codeatridx =
+            pcfs
+              ->methods[mthidx]
+                ->LOCAL_method_binding
+                  .codeatridxJVM;
 
-            jvm_attribute_index excpatridx =
-                pcfs
-                  ->methods[mthidx]
-                    ->LOCAL_method_binding
-                      .excpatridxJVM;
-
-            Code_attribute *pca =
-                (Code_attribute *)
-                &pcfs->methods[mthidx]->attributes[codeatridx]->ai;
-
-            /* Check for stack overflow if this frame is loaded */
-            if (JVMCFG_MAX_SP <= GET_SP(thridx) +
-                                 JVMREG_STACK_MIN_FRAME_HEIGHT +
-                                 JVMREG_STACK_PC_HEIGHT +
-                                 pca->max_stack +
-                                 pca->max_locals)
-            {
-                exit_throw_exception(EXIT_JVM_CLASS,
-                                   JVMCLASS_JAVA_LANG_OUTOFMEMORYERROR);
-/*NOTLOADED*/
-            }
-
-            /*
-             * Save old stack frame for @b RETURN from @c b \<clinit\>
+        if (jvm_attribute_index_bad == codeatridx)
+        {
+            /*!
+             * @todo HARMONY-6-jvm-class.c-13 Currently, return
+             *       valid class index even if no @c @b \<clinit\>
+             *       was available.  Is this correct?  Or should it
+             *       throw a @b VerifyError since a method was
+             *       declared, yet had no code area?  Take the
+             *       easy way out for now, evaluate and maybe fix
+             *       later.
              */
-            PUSH_FRAME(thridx, pca->max_locals);
-
-            /* Load PC of @c @b \<clinit\> method */
-            PUT_PC_IMMEDIATE(thridx,
-                             clsidx,
-                             mthidx,
-                             codeatridx,
-                             excpatridx,
-                             CODE_CONSTRAINT_START_PC);
+            return(clsidx);
         }
-        else
+
+        if (jvm_attribute_index_abstract == codeatridx)
         {
-            /*
-             * Class is now known to be available,
-             * so start it on the system thread.
-             *
-             * There is no old stack frame to save for @b RETURN
-             * from @c @b \<clinit\> because this a new thread.  The
-             * starting stack frame is set up by thread_class_load()
-             * and returning to it will @b COMPLETE the thread.
+            /*!
+             * @todo HARMONY-6-jvm-class.c-21 Same issue as with
+             *       test for @link #jvm_attribute_index_bad
+             *       jvm_attribute_index_bad@endlink above.
              */
-            thridxLOAD =
-                thread_class_load(clsname,
-                                  LOCAL_CONSTANT_UTF8_CLASS_CONSTRUCTOR,
-                            LOCAL_CONSTANT_UTF8_CLASS_CONSTRUCTOR_PARMS,
-                                  THREAD_PRIORITY_MAX,
-                                  rfalse,
-                                  usesystemthread,
-                                  find_registerNatives);
+            return(clsidx);
         }
 
-        jvm_manual_thread_run(thridxLOAD,
-                              ((rtrue == usesystemthread) ||
-                               (jvm_thread_index_null == thridx))
-                                ? rtrue /* Die if not prev @b RUN */
-                                : rfalse,
-                              clsname,
-                              LOCAL_CONSTANT_UTF8_CLASS_CONSTRUCTOR,
-                           LOCAL_CONSTANT_UTF8_CLASS_CONSTRUCTOR_PARMS);
+        jvm_attribute_index excpatridx =
+            pcfs
+              ->methods[mthidx]
+                ->LOCAL_method_binding
+                  .excpatridxJVM;
+
+        Code_attribute *pca =
+            (Code_attribute *)
+            &pcfs->methods[mthidx]->attributes[codeatridx]->ai;
+
+        /* Check for stack overflow if this frame is loaded */
+        if (JVMCFG_MAX_SP <= GET_SP(thridx) +
+                             JVMREG_STACK_MIN_FRAME_HEIGHT +
+                             JVMREG_STACK_PC_HEIGHT +
+                             pca->max_stack +
+                             pca->max_locals)
+        {
+            exit_throw_exception(EXIT_JVM_CLASS,
+                               JVMCLASS_JAVA_LANG_OUTOFMEMORYERROR);
+/*NOTREACHED*/
+        }
 
-        /* Class @c @b \<clinit\> has been completed (manually) */
-        CLASS(clsidx).status &= ~CLASS_STATUS_DOCLINIT;
-        CLASS(clsidx).status |= CLASS_STATUS_CLINIT;
+        /*
+         * Save old stack frame for @b RETURN from @c b \<clinit\>
+         */
+        PUSH_FRAME(thridx, pca->max_locals);
 
+        /* Load PC of @c @b \<clinit\> method */
+        PUT_PC_IMMEDIATE(thridx,
+                         clsidx,
+                         mthidx,
+                         codeatridx,
+                         excpatridx,
+                         CODE_CONSTRAINT_START_PC);
+    }
+    else
+    {
+        /*
+         * Class is now known to be available,
+         * so start it on the system thread.
+         *
+         * There is no old stack frame to save for @b RETURN
+         * from @c @b \<clinit\> because this a new thread.  The
+         * starting stack frame is set up by thread_class_load()
+         * and returning to it will @b COMPLETE the thread.
+         */
+        thridxLOAD =
+            thread_class_load(clsname,
+                              LOCAL_CONSTANT_UTF8_CLASS_CONSTRUCTOR,
+                        LOCAL_CONSTANT_UTF8_CLASS_CONSTRUCTOR_PARMS,
+                              THREAD_PRIORITY_MAX,
+                              rfalse,
+                              usesystemthread,
+                              find_registerNatives);
 
-        /*Return class index of class loaded,resolved,and ready to use*/
-        return(clsidx);
+        /*
+         * Die if not previous thread in @b RUN state
+         * or if requesting system thread, but that
+         * thread is already in use.
+         */
+        if ((rfalse == usesystemthread) ||
+            (!(THREAD(JVMCFG_SYSTEM_THREAD).status &
+               THREAD_STATUS_INUSE)))
+        {
+            shutdown_jvm = rtrue;
+        }
     }
 
+    jvm_manual_thread_run(thridxLOAD,
+                          shutdown_jvm,
+                          clsname,
+                          LOCAL_CONSTANT_UTF8_CLASS_CONSTRUCTOR,
+                       LOCAL_CONSTANT_UTF8_CLASS_CONSTRUCTOR_PARMS);
+
+    /* Class @c @b \<clinit\> has been completed (manually) */
+    CLASS(clsidx).status &= ~CLASS_STATUS_DOCLINIT;
+    CLASS(clsidx).status |= CLASS_STATUS_CLINIT;
+
+
+    /*Return class index of class loaded,resolved,and ready to use*/
+    return(clsidx);
+
 } /* END of class_load_resolve_clinit() */
 
 
@@ -1971,7 +1995,7 @@
 
 
 /*!
- * @brief Report number of class static fields are in a class file.
+ * @brief Report number of class static fields in a class file.
  *
  *
  * @param    pcfs  Pointer to ClassFile area
@@ -2110,7 +2134,7 @@
 
 
 /*!
- * @brief Report number of object instance fields are in a class file.
+ * @brief Report number of object instance fields in a class file.
  *
  *
  * @param    pcfs       Pointer to ClassFile area