1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <nativehelper/JNIHelp.h>
18 #include <nativehelper/jni_macros.h>
19 
ThrowUnsupportedOperationForAccessMode(JNIEnv * env,const char * accessMode)20 static void ThrowUnsupportedOperationForAccessMode(JNIEnv* env, const char* accessMode) {
21   // VarHandle access mode methods should be dispatched by the
22   // interpreter or inlined into compiled code. The JNI methods below
23   // are discoverable via reflection, but are not intended to be
24   // invoked this way.
25   jniThrowExceptionFmt(env,
26                        "java/lang/UnsupportedOperationException",
27                        "VarHandle.%s cannot be invoked reflectively.",
28                        accessMode);
29 }
30 
VarHandle_compareAndExchange(JNIEnv * env,jobject,jobjectArray)31 static jobject VarHandle_compareAndExchange(JNIEnv* env, jobject, jobjectArray) {
32   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
33   ThrowUnsupportedOperationForAccessMode(env, "compareAndExchange");
34   return nullptr;
35 }
36 
VarHandle_compareAndExchangeAcquire(JNIEnv * env,jobject,jobjectArray)37 static jobject VarHandle_compareAndExchangeAcquire(JNIEnv* env, jobject, jobjectArray) {
38   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
39   ThrowUnsupportedOperationForAccessMode(env, "compareAndExchangeAcquire");
40   return nullptr;
41 }
42 
VarHandle_compareAndExchangeRelease(JNIEnv * env,jobject,jobjectArray)43 static jobject VarHandle_compareAndExchangeRelease(JNIEnv* env, jobject, jobjectArray) {
44   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
45   ThrowUnsupportedOperationForAccessMode(env, "compareAndExchangeRelease");
46   return nullptr;
47 }
48 
VarHandle_compareAndSet(JNIEnv * env,jobject,jobjectArray)49 static jboolean VarHandle_compareAndSet(JNIEnv* env, jobject, jobjectArray) {
50   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
51   ThrowUnsupportedOperationForAccessMode(env, "compareAndSet");
52   return JNI_FALSE;
53 }
54 
VarHandle_get(JNIEnv * env,jobject,jobjectArray)55 static jobject VarHandle_get(JNIEnv* env, jobject, jobjectArray) {
56   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
57   ThrowUnsupportedOperationForAccessMode(env, "get");
58   return nullptr;
59 }
60 
VarHandle_getAcquire(JNIEnv * env,jobject,jobjectArray)61 static jobject VarHandle_getAcquire(JNIEnv* env, jobject, jobjectArray) {
62   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
63   ThrowUnsupportedOperationForAccessMode(env, "getAcquire");
64   return nullptr;
65 }
66 
VarHandle_getAndAdd(JNIEnv * env,jobject,jobjectArray)67 static jobject VarHandle_getAndAdd(JNIEnv* env, jobject, jobjectArray) {
68   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
69   ThrowUnsupportedOperationForAccessMode(env, "getAndAdd");
70   return nullptr;
71 }
72 
VarHandle_getAndAddAcquire(JNIEnv * env,jobject,jobjectArray)73 static jobject VarHandle_getAndAddAcquire(JNIEnv* env, jobject, jobjectArray) {
74   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
75   ThrowUnsupportedOperationForAccessMode(env, "getAndAddAcquire");
76   return nullptr;
77 }
78 
VarHandle_getAndAddRelease(JNIEnv * env,jobject,jobjectArray)79 static jobject VarHandle_getAndAddRelease(JNIEnv* env, jobject, jobjectArray) {
80   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
81   ThrowUnsupportedOperationForAccessMode(env, "getAndAddRelease");
82   return nullptr;
83 }
84 
VarHandle_getAndBitwiseAnd(JNIEnv * env,jobject,jobjectArray)85 static jobject VarHandle_getAndBitwiseAnd(JNIEnv* env, jobject, jobjectArray) {
86   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
87   ThrowUnsupportedOperationForAccessMode(env, "getAndBitwiseAnd");
88   return nullptr;
89 }
90 
VarHandle_getAndBitwiseAndAcquire(JNIEnv * env,jobject,jobjectArray)91 static jobject VarHandle_getAndBitwiseAndAcquire(JNIEnv* env, jobject, jobjectArray) {
92   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
93   ThrowUnsupportedOperationForAccessMode(env, "getAndBitwiseAndAcquire");
94   return nullptr;
95 }
96 
VarHandle_getAndBitwiseAndRelease(JNIEnv * env,jobject,jobjectArray)97 static jobject VarHandle_getAndBitwiseAndRelease(JNIEnv* env, jobject, jobjectArray) {
98   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
99   ThrowUnsupportedOperationForAccessMode(env, "getAndBitwiseAndRelease");
100   return nullptr;
101 }
102 
VarHandle_getAndBitwiseOr(JNIEnv * env,jobject,jobjectArray)103 static jobject VarHandle_getAndBitwiseOr(JNIEnv* env, jobject, jobjectArray) {
104   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
105   ThrowUnsupportedOperationForAccessMode(env, "getAndBitwiseOr");
106   return nullptr;
107 }
108 
VarHandle_getAndBitwiseOrAcquire(JNIEnv * env,jobject,jobjectArray)109 static jobject VarHandle_getAndBitwiseOrAcquire(JNIEnv* env, jobject, jobjectArray) {
110   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
111   ThrowUnsupportedOperationForAccessMode(env, "getAndBitwiseOrAcquire");
112   return nullptr;
113 }
114 
VarHandle_getAndBitwiseOrRelease(JNIEnv * env,jobject,jobjectArray)115 static jobject VarHandle_getAndBitwiseOrRelease(JNIEnv* env, jobject, jobjectArray) {
116   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
117   ThrowUnsupportedOperationForAccessMode(env, "getAndBitwiseOrRelease");
118   return nullptr;
119 }
120 
VarHandle_getAndBitwiseXor(JNIEnv * env,jobject,jobjectArray)121 static jobject VarHandle_getAndBitwiseXor(JNIEnv* env, jobject, jobjectArray) {
122   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
123   ThrowUnsupportedOperationForAccessMode(env, "getAndBitwiseXor");
124   return nullptr;
125 }
126 
VarHandle_getAndBitwiseXorAcquire(JNIEnv * env,jobject,jobjectArray)127 static jobject VarHandle_getAndBitwiseXorAcquire(JNIEnv* env, jobject, jobjectArray) {
128   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
129   ThrowUnsupportedOperationForAccessMode(env, "getAndBitwiseXorAcquire");
130   return nullptr;
131 }
132 
VarHandle_getAndBitwiseXorRelease(JNIEnv * env,jobject,jobjectArray)133 static jobject VarHandle_getAndBitwiseXorRelease(JNIEnv* env, jobject, jobjectArray) {
134   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
135   ThrowUnsupportedOperationForAccessMode(env, "getAndBitwiseXorRelease");
136   return nullptr;
137 }
138 
VarHandle_getAndSet(JNIEnv * env,jobject,jobjectArray)139 static jobject VarHandle_getAndSet(JNIEnv* env, jobject, jobjectArray) {
140   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
141   ThrowUnsupportedOperationForAccessMode(env, "getAndSet");
142   return nullptr;
143 }
144 
VarHandle_getAndSetAcquire(JNIEnv * env,jobject,jobjectArray)145 static jobject VarHandle_getAndSetAcquire(JNIEnv* env, jobject, jobjectArray) {
146   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
147   ThrowUnsupportedOperationForAccessMode(env, "getAndSetAcquire");
148   return nullptr;
149 }
150 
VarHandle_getAndSetRelease(JNIEnv * env,jobject,jobjectArray)151 static jobject VarHandle_getAndSetRelease(JNIEnv* env, jobject, jobjectArray) {
152   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
153   ThrowUnsupportedOperationForAccessMode(env, "getAndSetRelease");
154   return nullptr;
155 }
156 
VarHandle_getOpaque(JNIEnv * env,jobject,jobjectArray)157 static jobject VarHandle_getOpaque(JNIEnv* env, jobject, jobjectArray) {
158   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
159   ThrowUnsupportedOperationForAccessMode(env, "getOpaque");
160   return nullptr;
161 }
162 
VarHandle_getVolatile(JNIEnv * env,jobject,jobjectArray)163 static jobject VarHandle_getVolatile(JNIEnv* env, jobject, jobjectArray) {
164   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
165   ThrowUnsupportedOperationForAccessMode(env, "getVolatile");
166   return nullptr;
167 }
168 
VarHandle_set(JNIEnv * env,jobject,jobjectArray)169 static void VarHandle_set(JNIEnv* env, jobject, jobjectArray) {
170   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
171   ThrowUnsupportedOperationForAccessMode(env, "set");
172 }
173 
VarHandle_setOpaque(JNIEnv * env,jobject,jobjectArray)174 static void VarHandle_setOpaque(JNIEnv* env, jobject, jobjectArray) {
175   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
176   ThrowUnsupportedOperationForAccessMode(env, "setOpaque");
177 }
178 
VarHandle_setRelease(JNIEnv * env,jobject,jobjectArray)179 static void VarHandle_setRelease(JNIEnv* env, jobject, jobjectArray) {
180   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
181   ThrowUnsupportedOperationForAccessMode(env, "setRelease");
182 }
183 
VarHandle_setVolatile(JNIEnv * env,jobject,jobjectArray)184 static void VarHandle_setVolatile(JNIEnv* env, jobject, jobjectArray) {
185   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
186   ThrowUnsupportedOperationForAccessMode(env, "setVolatile");
187 }
188 
VarHandle_weakCompareAndSet(JNIEnv * env,jobject,jobjectArray)189 static jboolean VarHandle_weakCompareAndSet(JNIEnv* env, jobject, jobjectArray) {
190   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
191   ThrowUnsupportedOperationForAccessMode(env, "weakCompareAndSet");
192   return JNI_FALSE;
193 }
194 
VarHandle_weakCompareAndSetAcquire(JNIEnv * env,jobject,jobjectArray)195 static jboolean VarHandle_weakCompareAndSetAcquire(JNIEnv* env, jobject, jobjectArray) {
196   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
197   ThrowUnsupportedOperationForAccessMode(env, "weakCompareAndSetAcquire");
198   return JNI_FALSE;
199 }
200 
VarHandle_weakCompareAndSetPlain(JNIEnv * env,jobject,jobjectArray)201 static jboolean VarHandle_weakCompareAndSetPlain(JNIEnv* env, jobject, jobjectArray) {
202   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
203   ThrowUnsupportedOperationForAccessMode(env, "weakCompareAndSetPlain");
204   return JNI_FALSE;
205 }
206 
VarHandle_weakCompareAndSetRelease(JNIEnv * env,jobject,jobjectArray)207 static jboolean VarHandle_weakCompareAndSetRelease(JNIEnv* env, jobject, jobjectArray) {
208   // Only reachable with reflection (see comment in ThrowUnsupportedOperationForAccessMode).
209   ThrowUnsupportedOperationForAccessMode(env, "weakCompareAndSetRelease");
210   return JNI_FALSE;
211 }
212 
213 static JNINativeMethod gMethods[] = {
214   NATIVE_METHOD(VarHandle, compareAndExchange, "([Ljava/lang/Object;)Ljava/lang/Object;"),
215   NATIVE_METHOD(VarHandle, compareAndExchangeAcquire, "([Ljava/lang/Object;)Ljava/lang/Object;"),
216   NATIVE_METHOD(VarHandle, compareAndExchangeRelease, "([Ljava/lang/Object;)Ljava/lang/Object;"),
217   NATIVE_METHOD(VarHandle, compareAndSet, "([Ljava/lang/Object;)Z"),
218   NATIVE_METHOD(VarHandle, get, "([Ljava/lang/Object;)Ljava/lang/Object;"),
219   NATIVE_METHOD(VarHandle, getAcquire, "([Ljava/lang/Object;)Ljava/lang/Object;"),
220   NATIVE_METHOD(VarHandle, getAndAdd, "([Ljava/lang/Object;)Ljava/lang/Object;"),
221   NATIVE_METHOD(VarHandle, getAndAddAcquire, "([Ljava/lang/Object;)Ljava/lang/Object;"),
222   NATIVE_METHOD(VarHandle, getAndAddRelease, "([Ljava/lang/Object;)Ljava/lang/Object;"),
223   NATIVE_METHOD(VarHandle, getAndBitwiseAnd, "([Ljava/lang/Object;)Ljava/lang/Object;"),
224   NATIVE_METHOD(VarHandle, getAndBitwiseAndAcquire, "([Ljava/lang/Object;)Ljava/lang/Object;"),
225   NATIVE_METHOD(VarHandle, getAndBitwiseAndRelease, "([Ljava/lang/Object;)Ljava/lang/Object;"),
226   NATIVE_METHOD(VarHandle, getAndBitwiseOr, "([Ljava/lang/Object;)Ljava/lang/Object;"),
227   NATIVE_METHOD(VarHandle, getAndBitwiseOrAcquire, "([Ljava/lang/Object;)Ljava/lang/Object;"),
228   NATIVE_METHOD(VarHandle, getAndBitwiseOrRelease, "([Ljava/lang/Object;)Ljava/lang/Object;"),
229   NATIVE_METHOD(VarHandle, getAndBitwiseXor, "([Ljava/lang/Object;)Ljava/lang/Object;"),
230   NATIVE_METHOD(VarHandle, getAndBitwiseXorAcquire, "([Ljava/lang/Object;)Ljava/lang/Object;"),
231   NATIVE_METHOD(VarHandle, getAndBitwiseXorRelease, "([Ljava/lang/Object;)Ljava/lang/Object;"),
232   NATIVE_METHOD(VarHandle, getAndSet, "([Ljava/lang/Object;)Ljava/lang/Object;"),
233   NATIVE_METHOD(VarHandle, getAndSetAcquire, "([Ljava/lang/Object;)Ljava/lang/Object;"),
234   NATIVE_METHOD(VarHandle, getAndSetRelease, "([Ljava/lang/Object;)Ljava/lang/Object;"),
235   NATIVE_METHOD(VarHandle, getOpaque, "([Ljava/lang/Object;)Ljava/lang/Object;"),
236   NATIVE_METHOD(VarHandle, getVolatile, "([Ljava/lang/Object;)Ljava/lang/Object;"),
237   NATIVE_METHOD(VarHandle, set, "([Ljava/lang/Object;)V"),
238   NATIVE_METHOD(VarHandle, setOpaque, "([Ljava/lang/Object;)V"),
239   NATIVE_METHOD(VarHandle, setRelease, "([Ljava/lang/Object;)V"),
240   NATIVE_METHOD(VarHandle, setVolatile, "([Ljava/lang/Object;)V"),
241   NATIVE_METHOD(VarHandle, weakCompareAndSet, "([Ljava/lang/Object;)Z"),
242   NATIVE_METHOD(VarHandle, weakCompareAndSetAcquire, "([Ljava/lang/Object;)Z"),
243   NATIVE_METHOD(VarHandle, weakCompareAndSetPlain, "([Ljava/lang/Object;)Z"),
244   NATIVE_METHOD(VarHandle, weakCompareAndSetRelease, "([Ljava/lang/Object;)Z"),
245 };
246 
register_java_lang_invoke_VarHandle(JNIEnv * env)247 void register_java_lang_invoke_VarHandle(JNIEnv* env) {
248     jniRegisterNativeMethods(env, "java/lang/invoke/VarHandle", gMethods, NELEM(gMethods));
249 }
250