1 /*
   2  * Copyright (c) 2017, 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 /*
  27  * Class:     CallWithJNIWeak
  28  * Method:    testJNIFieldAccessors
  29  * Signature: (LCallWithJNIWeak;)V
  30  */
  31 JNIEXPORT void JNICALL
  32 Java_CallWithJNIWeak_testJNIFieldAccessors (JNIEnv *env, jclass clazz, jobject this) {
  33   // Make sure that we have a weak reference to the receiver
  34 
  35   jweak self = (*env)->NewWeakGlobalRef(env, this);
  36 
  37   jclass this_class = (*env)->GetObjectClass(env, self);
  38 
  39   jclass exception = (*env)->FindClass(env, "java/lang/RuntimeException");
  40 
  41   jfieldID id_i = (*env)->GetFieldID(env, this_class, "i", "I");
  42   jfieldID id_j = (*env)->GetFieldID(env, this_class, "j", "J");
  43   jfieldID id_z = (*env)->GetFieldID(env, this_class, "z", "Z");
  44   jfieldID id_c = (*env)->GetFieldID(env, this_class, "c", "C");
  45   jfieldID id_s = (*env)->GetFieldID(env, this_class, "s", "S");
  46   jfieldID id_f = (*env)->GetFieldID(env, this_class, "f", "F");
  47   jfieldID id_d = (*env)->GetFieldID(env, this_class, "d", "D");
  48   jfieldID id_l = (*env)->GetFieldID(env, this_class, "l", "Ljava/lang/Object;");
  49   jvalue v;
  50 
  51 #define CHECK(variable, expected)                                   \
  52   do {                                                              \
  53     if ((variable) != (expected)) {                                 \
  54       (*env)->ThrowNew(env, exception,  #variable" != " #expected); \
  55       return;                                                       \
  56     }                                                               \
  57   } while(0)
  58 
  59   v.i = (*env)->GetIntField(env, self, id_i);
  60   CHECK(v.i, 1);
  61 
  62   v.j = (*env)->GetLongField(env, self, id_j);
  63   CHECK(v.j, 2);
  64 
  65   v.z = (*env)->GetBooleanField(env, self, id_z);
  66   CHECK(v.z, JNI_TRUE);
  67 
  68   v.c = (*env)->GetCharField(env, self, id_c);
  69   CHECK(v.c, 'a');
  70 
  71   v.s = (*env)->GetShortField(env, self, id_s);
  72   CHECK(v.s, 3);
  73 
  74   v.f = (*env)->GetFloatField(env, self, id_f);
  75   CHECK(v.f, 1.0f);
  76 
  77   v.d = (*env)->GetDoubleField(env, self, id_d);
  78   CHECK(v.d, 2.0);
  79 
  80 #undef CHECK
  81 
  82   v.l = (*env)->GetObjectField(env, self, id_l);
  83   if (v.l == NULL) {
  84     (*env)->ThrowNew(env, exception, "Object field was null");
  85     return;
  86   }
  87   {
  88     jclass clz = (*env)->GetObjectClass(env, v.l);
  89     if (!(*env)->IsSameObject(env, clazz, clz)) {
  90       (*env)->ThrowNew(env, exception, "Bad object class");
  91     }
  92   }
  93 
  94   (*env)->DeleteWeakGlobalRef(env, self);
  95 }
  96 
  97 /*
  98  * Class:     CallWithJNIWeak
  99  * Method:    runTests
 100  * Signature: (LCallWithJNIWeak;)V
 101  */
 102 JNIEXPORT void JNICALL
 103 Java_CallWithJNIWeak_runTests (JNIEnv *env, jclass clazz, jobject this) {
 104   jweak that = (*env)->NewWeakGlobalRef(env, this);
 105   {
 106     jmethodID method = (*env)->GetStaticMethodID(env,
 107         clazz, "testJNIFieldAccessors", "(LCallWithJNIWeak;)V");
 108     (*env)->CallStaticVoidMethod(env, clazz, method, that);
 109     if ((*env)->ExceptionCheck(env)) {
 110       return;
 111     }
 112   }
 113 
 114   {
 115     jmethodID method = (*env)->GetMethodID(env, clazz, "weakReceiverTest", "()V");
 116     (*env)->CallVoidMethod(env, that, method);
 117     if ((*env)->ExceptionCheck(env)) {
 118       return;
 119     }
 120   }
 121 
 122   {
 123     jmethodID method = (*env)->GetMethodID(env, clazz, "synchonizedWeakReceiverTest", "()V");
 124     (*env)->CallVoidMethod(env, that, method);
 125     if ((*env)->ExceptionCheck(env)) {
 126       return;
 127     }
 128   }
 129   (*env)->DeleteWeakGlobalRef(env, that);
 130 }
 131 
 132 /*
 133  * Class:     CallWithJNIWeak
 134  * Method:    weakReceiverTest0
 135  * Signature: ()V
 136  */
 137 JNIEXPORT void JNICALL
 138 Java_CallWithJNIWeak_weakReceiverTest0 (JNIEnv *env, jobject obj) {
 139   (*env)->GetObjectClass(env, obj);
 140 }