test/hotspot/jtreg/runtime/Nestmates/libNestmatesJNI.c
changeset 50735 2f2af62dfac7
equal deleted inserted replaced
50734:0828a0f6676b 50735:2f2af62dfac7
       
     1 /*
       
     2  * Copyright (c) 2018, Oracle and/or its affiliates. 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.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 #include <jni.h>
       
    25 
       
    26 // boolean flag for static versus non-static
       
    27 #define STATIC 1
       
    28 #define NON_STATIC 0
       
    29 
       
    30 // Helper methods to get class/method/field IDs
       
    31 
       
    32 static void getClassID(JNIEnv *env,
       
    33                        jstring defining_class_name,
       
    34                        jclass* clazz) {
       
    35   const char* name = (*env)->GetStringUTFChars(env, defining_class_name, NULL);
       
    36   if (name != NULL) {
       
    37     *clazz = (*env)->FindClass(env, name);
       
    38     (*env)->ReleaseStringUTFChars(env, defining_class_name, name);
       
    39   }
       
    40 }
       
    41 
       
    42 static void getClassAndMethodID(JNIEnv *env,
       
    43                                 int is_static,
       
    44                                 jstring defining_class_name,
       
    45                                 jstring method_name,
       
    46                                 const char* sig,
       
    47                                 jmethodID* m_id, jclass* clazz) {
       
    48   getClassID(env, defining_class_name, clazz);
       
    49   if (*clazz != NULL) {
       
    50     const char* name = (*env)->GetStringUTFChars(env, method_name, NULL);
       
    51     if (name != NULL) {
       
    52       if (is_static) {
       
    53         *m_id = (*env)->GetStaticMethodID(env, *clazz, name, sig);
       
    54       } else {
       
    55         *m_id = (*env)->GetMethodID(env, *clazz, name, sig);
       
    56       }
       
    57       (*env)->ReleaseStringUTFChars(env, method_name, name);
       
    58     }
       
    59   }
       
    60 }
       
    61 
       
    62 static void getClassAndFieldID(JNIEnv *env,
       
    63                                 int is_static,
       
    64                                 jstring defining_class_name,
       
    65                                 jstring field_name,
       
    66                                 const char* sig,
       
    67                                 jfieldID* m_id, jclass* clazz) {
       
    68   getClassID(env, defining_class_name, clazz);
       
    69   if (*clazz != NULL) {
       
    70     const char* name = (*env)->GetStringUTFChars(env, field_name, NULL);
       
    71     if (name != NULL) {
       
    72       if (is_static) {
       
    73         *m_id = (*env)->GetStaticFieldID(env, *clazz, name, sig);
       
    74       } else {
       
    75         *m_id = (*env)->GetFieldID(env, *clazz, name, sig);
       
    76       }
       
    77       (*env)->ReleaseStringUTFChars(env, field_name, name);
       
    78     }
       
    79   }
       
    80 }
       
    81 
       
    82 JNIEXPORT void JNICALL
       
    83 Java_NestmatesJNI_callVoidVoid(JNIEnv *env, jclass unused,
       
    84                                jobject target,
       
    85                                jstring defining_class_name,
       
    86                                jstring method_name,
       
    87                                jboolean virtual) {
       
    88 
       
    89   // Lookup "void method_name()" in defining_class_name, and if it exists
       
    90   // call target.method_name() using a virtual or non-virtual invocation
       
    91 
       
    92   jmethodID m_id = NULL;
       
    93   jclass clazz = NULL;
       
    94   getClassAndMethodID(env, NON_STATIC, defining_class_name, method_name,
       
    95                       "()V", &m_id, &clazz);
       
    96   if (m_id != NULL && clazz != NULL) {
       
    97     if (!virtual) {
       
    98       (*env)->CallNonvirtualVoidMethod(env, target, clazz, m_id);
       
    99     } else {
       
   100       (*env)->CallVoidMethod(env, target, m_id);
       
   101     }
       
   102   }
       
   103 }
       
   104 
       
   105 JNIEXPORT jobject JNICALL
       
   106 Java_NestmatesJNI_callStringVoid(JNIEnv *env, jclass unused,
       
   107                                  jobject target,
       
   108                                  jstring defining_class_name,
       
   109                                  jstring method_name,
       
   110                                  jboolean virtual) {
       
   111 
       
   112   // Lookup "String method_name()" in defining_class_name, and if it exists
       
   113   // call target.method_name() using a virtual or non-virtual invocation
       
   114 
       
   115   jmethodID m_id = NULL;
       
   116   jclass clazz = NULL;
       
   117   getClassAndMethodID(env, NON_STATIC, defining_class_name, method_name,
       
   118                       "()Ljava/lang/String;", &m_id, &clazz);
       
   119   if (m_id != NULL && clazz != NULL) {
       
   120     if (!virtual) {
       
   121       return (*env)->CallNonvirtualObjectMethod(env, target, clazz, m_id);
       
   122     } else {
       
   123       return (*env)->CallObjectMethod(env, target, m_id);
       
   124     }
       
   125   }
       
   126   return NULL;
       
   127 }
       
   128 
       
   129 JNIEXPORT jobject JNICALL
       
   130 Java_NestmatesJNI_newInstance0(JNIEnv *env, jclass unused,
       
   131                               jstring defining_class_name,
       
   132                               jstring method_name,
       
   133                               jstring sig,
       
   134                               jobject outerThis) {
       
   135 
       
   136   // Lookup the no-user-arg constructor in defining_class_name using sig,
       
   137   // and use it to create an instance of the class, and return it. For
       
   138   // inner classes we need an outerThis reference to pass to the constructor.
       
   139 
       
   140   jmethodID m_id = NULL;
       
   141   jclass clazz = NULL;
       
   142   const char* _sig = (*env)->GetStringUTFChars(env, sig, NULL);
       
   143   getClassAndMethodID(env, NON_STATIC, defining_class_name, method_name,
       
   144                       _sig, &m_id, &clazz);
       
   145   (*env)->ReleaseStringUTFChars(env, sig, _sig);
       
   146   if (m_id != NULL && clazz != NULL) {
       
   147     return (*env)->NewObject(env, clazz, m_id, outerThis);
       
   148   }
       
   149   return NULL;
       
   150 }
       
   151 
       
   152 JNIEXPORT void JNICALL
       
   153 Java_NestmatesJNI_callStaticVoidVoid(JNIEnv *env, jclass unused,
       
   154                                      jstring defining_class_name,
       
   155                                      jstring method_name) {
       
   156 
       
   157   // Lookup "static void method_name()" in defining_class_name, and if it exists
       
   158   // invoke it.
       
   159 
       
   160   jmethodID m_id = NULL;
       
   161   jclass clazz = NULL;
       
   162   getClassAndMethodID(env, STATIC, defining_class_name, method_name,
       
   163                         "()V", &m_id, &clazz);
       
   164   if (m_id != NULL && clazz != NULL) {
       
   165     (*env)->CallStaticVoidMethod(env, clazz, m_id);
       
   166   }
       
   167 }
       
   168 
       
   169 JNIEXPORT jint JNICALL
       
   170 Java_NestmatesJNI_getIntField(JNIEnv *env, jclass unused,
       
   171                               jobject target,
       
   172                               jstring defining_class_name,
       
   173                               jstring field_name) {
       
   174 
       
   175   // Lookup field field_name in defining_class_name, and if it exists
       
   176   // return its value.
       
   177 
       
   178   jfieldID f_id = NULL;
       
   179   jclass clazz = NULL;
       
   180   getClassAndFieldID(env, NON_STATIC, defining_class_name, field_name,
       
   181                      "I", &f_id, &clazz);
       
   182   if (f_id != NULL && clazz != NULL) {
       
   183     return (*env)->GetIntField(env, target, f_id);
       
   184   }
       
   185   return -1;
       
   186 }
       
   187 
       
   188 JNIEXPORT void JNICALL
       
   189 Java_NestmatesJNI_setIntField(JNIEnv *env, jclass unused,
       
   190                               jobject target,
       
   191                               jstring defining_class_name,
       
   192                               jstring field_name,
       
   193                               jint newVal) {
       
   194 
       
   195   // Lookup field field_name in defining_class_name, and if it exists
       
   196   // set it to newVal.
       
   197 
       
   198   jfieldID f_id = NULL;
       
   199   jclass clazz = NULL;
       
   200   getClassAndFieldID(env, NON_STATIC, defining_class_name, field_name,
       
   201                      "I", &f_id, &clazz);
       
   202   if (f_id != NULL && clazz != NULL) {
       
   203     (*env)->SetIntField(env, target, f_id, newVal);
       
   204   }
       
   205 }
       
   206 
       
   207 JNIEXPORT jint JNICALL
       
   208 Java_NestmatesJNI_getStaticIntField(JNIEnv *env, jclass unused,
       
   209                                     jstring defining_class_name,
       
   210                                     jstring field_name) {
       
   211 
       
   212   // Lookup field field_name in defining_class_name, and if it exists
       
   213   // return its value.
       
   214 
       
   215   jfieldID f_id = NULL;
       
   216   jclass clazz = NULL;
       
   217   getClassAndFieldID(env, STATIC, defining_class_name, field_name,
       
   218                      "I", &f_id, &clazz);
       
   219   if (f_id != NULL && clazz != NULL) {
       
   220     return (*env)->GetStaticIntField(env, clazz, f_id);
       
   221   }
       
   222   return -1;
       
   223 }
       
   224 
       
   225 JNIEXPORT void JNICALL
       
   226 Java_NestmatesJNI_setStaticIntField(JNIEnv *env, jclass unused,
       
   227                                     jstring defining_class_name,
       
   228                                     jstring field_name,
       
   229                                     jint newVal) {
       
   230 
       
   231   // Lookup field field_name in defining_class_name, and if it exists
       
   232   // set it to newVal.
       
   233 
       
   234   jfieldID f_id = NULL;
       
   235   jclass clazz = NULL;
       
   236   getClassAndFieldID(env, STATIC, defining_class_name, field_name,
       
   237                        "I", &f_id, &clazz);
       
   238   if (f_id != NULL && clazz != NULL) {
       
   239     (*env)->SetStaticIntField(env, clazz, f_id, newVal);
       
   240   }
       
   241 }