1/*
2 * Copyright (c) 2015, 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 <stdio.h>
25
26#include "jni.h"
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32#define METHOD_SIGNATURE "(IJFDLjava/lang/String;)Z"
33#define STATIC_CALLEE_SIGNATURE "(Lcompiler/calls/common/InvokeStatic;IJFDLjava/lang/String;)Z"
34#define BASE_CLASS "compiler/calls/common/CallsBase"
35
36#define CHECK_EXCEPTIONS if ((*env)->ExceptionCheck(env)) return
37#define CHECK_EXCEPTIONS_FALSE if ((*env)->ExceptionCheck(env)) return JNI_FALSE
38
39#define IS_STATIC 1
40#define NOT_STATIC 0
41
42jboolean doCalleeWork(JNIEnv *env, jobject self, jint param1, jlong param2,
43    jfloat param3, jdouble param4, jstring param5) {
44  jclass cls = (*env)->GetObjectClass(env, self);
45  jfieldID calleeVisitedID = (*env)->GetFieldID(env, cls, "calleeVisited", "Z");
46  jclass CheckCallsBaseClass;
47  jmethodID checkValuesID;
48  CHECK_EXCEPTIONS_FALSE;
49  (*env)->SetBooleanField(env, self, calleeVisitedID, JNI_TRUE);
50  CHECK_EXCEPTIONS_FALSE;
51  CheckCallsBaseClass = (*env)->FindClass(env, BASE_CLASS);
52  CHECK_EXCEPTIONS_FALSE;
53  checkValuesID = (*env)->GetStaticMethodID(env, CheckCallsBaseClass,
54      "checkValues", "(IJFDLjava/lang/String;)V");
55  CHECK_EXCEPTIONS_FALSE;
56  (*env)->CallStaticVoidMethod(env, CheckCallsBaseClass, checkValuesID,
57      param1, param2, param3, param4, param5);
58  return JNI_TRUE;
59}
60
61JNIEXPORT jboolean JNICALL Java_compiler_calls_common_InvokeDynamic_calleeNative(JNIEnv *env, jobject obj,
62    jint param1, jlong param2, jfloat param3, jdouble param4, jstring param5) {
63  return doCalleeWork(env, obj, param1, param2, param3, param4, param5);
64}
65
66JNIEXPORT jboolean JNICALL Java_compiler_calls_common_InvokeInterface_calleeNative(JNIEnv *env, jobject obj,
67    jint param1, jlong param2, jfloat param3, jdouble param4, jstring param5) {
68  return doCalleeWork(env, obj, param1, param2, param3, param4, param5);
69}
70
71JNIEXPORT jboolean JNICALL Java_compiler_calls_common_InvokeSpecial_calleeNative(JNIEnv *env, jobject obj,
72    jint param1, jlong param2, jfloat param3, jdouble param4, jstring param5) {
73  return doCalleeWork(env, obj, param1, param2, param3, param4, param5);
74}
75
76JNIEXPORT jboolean JNICALL Java_compiler_calls_common_InvokeVirtual_calleeNative(JNIEnv *env, jobject obj,
77    jint param1, jlong param2, jfloat param3, jdouble param4, jstring param5) {
78  return doCalleeWork(env, obj, param1, param2, param3, param4, param5);
79}
80
81JNIEXPORT jboolean JNICALL Java_compiler_calls_common_InvokeStatic_calleeNative(JNIEnv *env, jclass obj,
82    jobject self, jint param1, jlong param2, jfloat param3, jdouble param4, jstring param5) {
83  return doCalleeWork(env, self, param1, param2, param3, param4, param5);
84}
85
86void doCallerWork(JNIEnv *env, jobject obj, int isStatic) {
87  jclass cls = (*env)->GetObjectClass(env, obj);
88  jmethodID calleeMethodID = 0;
89  jfieldID errorMessageID;
90  jfieldID nativeCalleeID;
91  jobject errorMessage;
92  jmethodID assertTrue;
93  jboolean callNative;
94  jclass assertsClass;
95  jclass baseClass;
96  jboolean result;
97  char* methodName;
98  CHECK_EXCEPTIONS;
99  nativeCalleeID = (*env)->GetFieldID(env, cls, "nativeCallee", "Z");
100  CHECK_EXCEPTIONS;
101  callNative = (*env)->GetBooleanField(env, obj, nativeCalleeID);
102  CHECK_EXCEPTIONS;
103  methodName = (callNative == JNI_TRUE) ? "calleeNative" : "callee";
104  if (isStatic) {
105    calleeMethodID = (*env)->GetStaticMethodID(env, cls, methodName,
106        STATIC_CALLEE_SIGNATURE);
107  } else {
108    calleeMethodID = (*env)->GetMethodID(env, cls, methodName, METHOD_SIGNATURE);
109  }
110  CHECK_EXCEPTIONS;
111  if (isStatic) {
112    result = (*env)->CallStaticBooleanMethod(env, cls, calleeMethodID, obj,
113        (jint) 1, (jlong) 2L, (jfloat) 3.0f, (jdouble) 4.0, (*env)->NewStringUTF(env, "5"));
114  } else {
115    result = (*env)->CallBooleanMethod(env, obj, calleeMethodID,
116        (jint) 1, (jlong) 2L, (jfloat) 3.0f, (jdouble) 4.0, (*env)->NewStringUTF(env, "5"));
117  }
118  CHECK_EXCEPTIONS;
119  baseClass = (*env)->FindClass(env, BASE_CLASS);
120  CHECK_EXCEPTIONS;
121  errorMessageID = (*env)->GetStaticFieldID(env, baseClass,
122      "CALL_ERR_MSG", "Ljava/lang/String;");
123  CHECK_EXCEPTIONS;
124  errorMessage = (*env)->GetStaticObjectField(env, baseClass, errorMessageID);
125  CHECK_EXCEPTIONS;
126  assertsClass = (*env)->FindClass(env, "jdk/test/lib/Asserts");
127  CHECK_EXCEPTIONS;
128  assertTrue = (*env)->GetStaticMethodID(env, assertsClass,
129      "assertTrue", "(ZLjava/lang/String;)V");
130  (*env)->CallStaticVoidMethod(env, assertsClass, assertTrue, result,
131      errorMessage);
132}
133
134JNIEXPORT void JNICALL Java_compiler_calls_common_InvokeSpecial_callerNative(JNIEnv *env, jobject obj) {
135  doCallerWork(env, obj, NOT_STATIC);
136}
137
138JNIEXPORT void JNICALL Java_compiler_calls_common_InvokeVirtual_callerNative(JNIEnv *env, jobject obj) {
139  doCallerWork(env, obj, NOT_STATIC);
140}
141
142JNIEXPORT void JNICALL Java_compiler_calls_common_InvokeStatic_callerNative(JNIEnv *env, jobject obj) {
143  doCallerWork(env, obj, IS_STATIC);
144}
145
146#ifdef __cplusplus
147}
148#endif
149