jdk/src/share/back/ArrayTypeImpl.c
changeset 2 90ce3da70b43
child 5506 202f599c92aa
equal deleted inserted replaced
0:fd16c54261b3 2:90ce3da70b43
       
     1 /*
       
     2  * Copyright 1998-2005 Sun Microsystems, Inc.  All Rights Reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Sun designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Sun in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    23  * have any questions.
       
    24  */
       
    25 
       
    26 #include "ArrayTypeImpl.h"
       
    27 #include "util.h"
       
    28 #include "inStream.h"
       
    29 #include "outStream.h"
       
    30 
       
    31 /*
       
    32  * Determine the component class by looking thru all classes for
       
    33  * one that has the signature of the component and the same class loadeer
       
    34  * as the array.  See JVM spec 5.3.3:
       
    35  *     If the component type is a reference type, C is marked as having
       
    36  *     been defined by the defining class loader of the component type.
       
    37  */
       
    38 static jdwpError
       
    39 getComponentClass(JNIEnv *env, jclass arrayClass, char *componentSignature,
       
    40                 jclass *componentClassPtr)
       
    41 {
       
    42     jobject arrayClassLoader;
       
    43     jclass *classes;
       
    44     jint count;
       
    45     jclass componentClass = NULL;
       
    46     jdwpError serror;
       
    47     jvmtiError error;
       
    48 
       
    49     serror = JDWP_ERROR(NONE);
       
    50 
       
    51     error = classLoader(arrayClass, &arrayClassLoader);
       
    52     if (error != JVMTI_ERROR_NONE) {
       
    53         return map2jdwpError(error);
       
    54     }
       
    55 
       
    56     error = allLoadedClasses(&classes, &count);
       
    57     if (error != JVMTI_ERROR_NONE) {
       
    58         serror = map2jdwpError(error);
       
    59     } else {
       
    60         int i;
       
    61         for (i = 0; (i < count) && (componentClass == NULL); i++) {
       
    62             char *signature = NULL;
       
    63             jclass clazz = classes[i];
       
    64             jboolean match;
       
    65             jvmtiError error;
       
    66 
       
    67             /* signature must match */
       
    68             error = classSignature(clazz, &signature, NULL);
       
    69             if (error != JVMTI_ERROR_NONE) {
       
    70                 serror = map2jdwpError(error);
       
    71                 break;
       
    72             }
       
    73             match = strcmp(signature, componentSignature) == 0;
       
    74             jvmtiDeallocate(signature);
       
    75 
       
    76             /* if signature matches, get class loader to check if
       
    77              * it matches
       
    78              */
       
    79             if (match) {
       
    80                 jobject loader;
       
    81                 error = classLoader(clazz, &loader);
       
    82                 if (error != JVMTI_ERROR_NONE) {
       
    83                     return map2jdwpError(error);
       
    84                 }
       
    85                 match = isSameObject(env, loader, arrayClassLoader);
       
    86             }
       
    87 
       
    88             if (match) {
       
    89                 componentClass = clazz;
       
    90             }
       
    91         }
       
    92         jvmtiDeallocate(classes);
       
    93 
       
    94         *componentClassPtr = componentClass;
       
    95     }
       
    96 
       
    97     if (serror == JDWP_ERROR(NONE) && componentClass == NULL) {
       
    98         /* per JVM spec, component class is always loaded
       
    99          * before array class, so this should never occur.
       
   100          */
       
   101         serror = JDWP_ERROR(NOT_FOUND);
       
   102     }
       
   103 
       
   104     return serror;
       
   105 }
       
   106 
       
   107 static void
       
   108 writeNewObjectArray(JNIEnv *env, PacketOutputStream *out,
       
   109                  jclass arrayClass, jint size, char *componentSignature)
       
   110 {
       
   111 
       
   112     WITH_LOCAL_REFS(env, 1) {
       
   113 
       
   114         jarray array;
       
   115         jclass componentClass;
       
   116         jdwpError serror;
       
   117 
       
   118         serror = getComponentClass(env, arrayClass,
       
   119                                        componentSignature, &componentClass);
       
   120         if (serror != JDWP_ERROR(NONE)) {
       
   121             outStream_setError(out, serror);
       
   122         } else {
       
   123 
       
   124             array = JNI_FUNC_PTR(env,NewObjectArray)(env, size, componentClass, 0);
       
   125             if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
       
   126                 JNI_FUNC_PTR(env,ExceptionClear)(env);
       
   127                 array = NULL;
       
   128             }
       
   129 
       
   130             if (array == NULL) {
       
   131                 outStream_setError(out, JDWP_ERROR(OUT_OF_MEMORY));
       
   132             } else {
       
   133                 (void)outStream_writeByte(out, specificTypeKey(env, array));
       
   134                 (void)outStream_writeObjectRef(env, out, array);
       
   135             }
       
   136 
       
   137         }
       
   138 
       
   139     } END_WITH_LOCAL_REFS(env);
       
   140 }
       
   141 
       
   142 static void
       
   143 writeNewPrimitiveArray(JNIEnv *env, PacketOutputStream *out,
       
   144                        jclass arrayClass, jint size, char *componentSignature)
       
   145 {
       
   146 
       
   147     WITH_LOCAL_REFS(env, 1) {
       
   148 
       
   149         jarray array = NULL;
       
   150 
       
   151         switch (componentSignature[0]) {
       
   152             case JDWP_TAG(BYTE):
       
   153                 array = JNI_FUNC_PTR(env,NewByteArray)(env, size);
       
   154                 break;
       
   155 
       
   156             case JDWP_TAG(CHAR):
       
   157                 array = JNI_FUNC_PTR(env,NewCharArray)(env, size);
       
   158                 break;
       
   159 
       
   160             case JDWP_TAG(FLOAT):
       
   161                 array = JNI_FUNC_PTR(env,NewFloatArray)(env, size);
       
   162                 break;
       
   163 
       
   164             case JDWP_TAG(DOUBLE):
       
   165                 array = JNI_FUNC_PTR(env,NewDoubleArray)(env, size);
       
   166                 break;
       
   167 
       
   168             case JDWP_TAG(INT):
       
   169                 array = JNI_FUNC_PTR(env,NewIntArray)(env, size);
       
   170                 break;
       
   171 
       
   172             case JDWP_TAG(LONG):
       
   173                 array = JNI_FUNC_PTR(env,NewLongArray)(env, size);
       
   174                 break;
       
   175 
       
   176             case JDWP_TAG(SHORT):
       
   177                 array = JNI_FUNC_PTR(env,NewShortArray)(env, size);
       
   178                 break;
       
   179 
       
   180             case JDWP_TAG(BOOLEAN):
       
   181                 array = JNI_FUNC_PTR(env,NewBooleanArray)(env, size);
       
   182                 break;
       
   183 
       
   184             default:
       
   185                 outStream_setError(out, JDWP_ERROR(TYPE_MISMATCH));
       
   186                 break;
       
   187         }
       
   188 
       
   189         if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
       
   190             JNI_FUNC_PTR(env,ExceptionClear)(env);
       
   191             array = NULL;
       
   192         }
       
   193 
       
   194         if (array == NULL) {
       
   195             outStream_setError(out, JDWP_ERROR(OUT_OF_MEMORY));
       
   196         } else {
       
   197             (void)outStream_writeByte(out, specificTypeKey(env, array));
       
   198             (void)outStream_writeObjectRef(env, out, array);
       
   199         }
       
   200 
       
   201     } END_WITH_LOCAL_REFS(env);
       
   202 }
       
   203 
       
   204 static jboolean
       
   205 newInstance(PacketInputStream *in, PacketOutputStream *out)
       
   206 {
       
   207     JNIEnv *env;
       
   208     char *signature = NULL;
       
   209     char *componentSignature;
       
   210     jclass arrayClass;
       
   211     jint size;
       
   212     jvmtiError error;
       
   213 
       
   214     env = getEnv();
       
   215 
       
   216     arrayClass = inStream_readClassRef(env, in);
       
   217     if (inStream_error(in)) {
       
   218         return JNI_TRUE;
       
   219     }
       
   220     size = inStream_readInt(in);
       
   221     if (inStream_error(in)) {
       
   222         return JNI_TRUE;
       
   223     }
       
   224 
       
   225     error = classSignature(arrayClass, &signature, NULL);
       
   226     if ( error != JVMTI_ERROR_NONE ) {
       
   227         outStream_setError(out, map2jdwpError(error));
       
   228         return JNI_FALSE;
       
   229     }
       
   230     componentSignature = &signature[1];
       
   231 
       
   232     if ((componentSignature[0] == JDWP_TAG(OBJECT)) ||
       
   233         (componentSignature[0] == JDWP_TAG(ARRAY))) {
       
   234         writeNewObjectArray(env, out, arrayClass, size, componentSignature);
       
   235     } else {
       
   236         writeNewPrimitiveArray(env, out, arrayClass, size, componentSignature);
       
   237     }
       
   238 
       
   239     jvmtiDeallocate(signature);
       
   240     return JNI_TRUE;
       
   241 }
       
   242 
       
   243 void *ArrayType_Cmds[] = { (void *)0x1
       
   244                           ,(void *)newInstance};