blob: 5a1f8e97781039b3021cdd59fce74d4463f6807b [file] [log] [blame]
Igor Murashkina1969c42018-02-16 13:30:57 -08001/*
2 * Copyright (C) 2018 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#pragma clang diagnostic push
18#pragma clang diagnostic ignored "-Wused-but-marked-unused"
19#pragma clang diagnostic ignored "-Wdeprecated-dynamic-exception-spec"
20#pragma clang diagnostic ignored "-Wdeprecated"
21#include <gtest/gtest.h>
22#pragma clang diagnostic pop
23#include <sstream>
24
25#define PARSE_FAILURES_NONFATAL // return empty optionals wherever possible instead of asserting.
26#include "nativehelper/jni_macros.h"
27
28// Provide static storage to these values so they can be used in a runtime context.
29// This has to be defined local to the test translation unit to avoid ODR violations prior to C++17.
30#define STORAGE_FN_FOR_JNI_TRAITS(jtype, ...) \
31constexpr char nativehelper::detail::jni_type_trait<jtype>::type_descriptor[]; \
32constexpr char nativehelper::detail::jni_type_trait<jtype>::type_name[];
33
34DEFINE_JNI_TYPE_TRAIT(STORAGE_FN_FOR_JNI_TRAITS)
35
36template <typename T>
37auto stringify_helper(const T& val) -> decltype(std::stringstream().str()) { // suppress incorrect warnings about compiler not support 'auto'
38 std::stringstream ss;
39 ss << val;
40 return ss.str();
41}
42
43#define EXPECT_STRINGIFY_EQ(x, y) EXPECT_EQ(stringify_helper(x), stringify_helper(y))
44
45TEST(JniSafeRegisterNativeMethods, StringParsing) {
46 using namespace nativehelper::detail; \
47
48 // Super basic bring-up tests for core functionality.
49
50 {
51 constexpr ConstexprStringView v_str = "V";
52 EXPECT_EQ(1u, v_str.size());
53 EXPECT_EQ(false, v_str.empty());
54
55 std::stringstream ss;
56 ss << v_str;
57 EXPECT_EQ("V", ss.str());
58 }
59
60 {
61 auto parse = ParseSingleTypeDescriptor("", /*allow_void*/true);
62 EXPECT_EQ("", parse->token);
63 EXPECT_EQ("", parse->remainder);
64 }
65
66 {
67 auto parse = ParseSingleTypeDescriptor("V", /*allow_void*/true);
68 EXPECT_EQ("V", parse->token);
69 EXPECT_EQ("", parse->remainder);
70 }
71
72 {
73 auto parse = ParseSingleTypeDescriptor("[I");
74 EXPECT_EQ("[I", parse->token);
75 EXPECT_EQ("", parse->remainder);
76 }
77
78 // Stringify is used for convenience to make writing out tests easier.
79 // Transforms as "(XYZ)W" -> "args={X,Y,Z}, ret=W"
80
81#define PARSE_SIGNATURE_AS_LIST(str) (ParseSignatureAsList<sizeof(str)>(str))
82
83 {
84 constexpr auto jni_descriptor = PARSE_SIGNATURE_AS_LIST("()V");
85 EXPECT_STRINGIFY_EQ("args={}, ret=V", jni_descriptor);
86 }
87
88 {
89 constexpr auto
90 jni_descriptor = PARSE_SIGNATURE_AS_LIST("()Ljava/lang/Object;");
91 EXPECT_STRINGIFY_EQ("args={}, ret=Ljava/lang/Object;", jni_descriptor);
92 }
93
94 {
95 constexpr auto jni_descriptor = PARSE_SIGNATURE_AS_LIST("()[I");
96 EXPECT_STRINGIFY_EQ("args={}, ret=[I", jni_descriptor);
97 }
98
99#define EXPECT_OK_SIGNATURE_PARSE(signature, args, ret) \
100 do { \
101 constexpr auto jni_descriptor = PARSE_SIGNATURE_AS_LIST(signature); \
102 EXPECT_EQ(true, jni_descriptor.has_value()); \
103 EXPECT_STRINGIFY_EQ("args={" args "}, ret=" ret, jni_descriptor); \
104 } while (0)
105
106 // Exhaustive tests for successful parsing.
107
108 EXPECT_OK_SIGNATURE_PARSE("()V", /*args*/"", /*ret*/"V");
109 EXPECT_OK_SIGNATURE_PARSE("()Z", /*args*/"", /*ret*/"Z");
110 EXPECT_OK_SIGNATURE_PARSE("()B", /*args*/"", /*ret*/"B");
111 EXPECT_OK_SIGNATURE_PARSE("()C", /*args*/"", /*ret*/"C");
112 EXPECT_OK_SIGNATURE_PARSE("()S", /*args*/"", /*ret*/"S");
113 EXPECT_OK_SIGNATURE_PARSE("()I", /*args*/"", /*ret*/"I");
114 EXPECT_OK_SIGNATURE_PARSE("()F", /*args*/"", /*ret*/"F");
115 EXPECT_OK_SIGNATURE_PARSE("()J", /*args*/"", /*ret*/"J");
116 EXPECT_OK_SIGNATURE_PARSE("()D", /*args*/"", /*ret*/"D");
117 EXPECT_OK_SIGNATURE_PARSE("()Ljava/lang/Object;", /*args*/
118 "", /*ret*/
119 "Ljava/lang/Object;");
120 EXPECT_OK_SIGNATURE_PARSE("()[Ljava/lang/Object;", /*args*/
121 "", /*ret*/
122 "[Ljava/lang/Object;");
123 EXPECT_OK_SIGNATURE_PARSE("()[I", /*args*/"", /*ret*/"[I");
124 EXPECT_OK_SIGNATURE_PARSE("()[[I", /*args*/"", /*ret*/"[[I");
125 EXPECT_OK_SIGNATURE_PARSE("()[[[I", /*args*/"", /*ret*/"[[[I");
126
127
128 EXPECT_OK_SIGNATURE_PARSE("(Z)V", /*args*/"Z", /*ret*/"V");
129 EXPECT_OK_SIGNATURE_PARSE("(B)V", /*args*/"B", /*ret*/"V");
130 EXPECT_OK_SIGNATURE_PARSE("(C)D", /*args*/"C", /*ret*/"D");
131 EXPECT_OK_SIGNATURE_PARSE("(S)V", /*args*/"S", /*ret*/"V");
132 EXPECT_OK_SIGNATURE_PARSE("(I)V", /*args*/"I", /*ret*/"V");
133 EXPECT_OK_SIGNATURE_PARSE("(F)V", /*args*/"F", /*ret*/"V");
134 EXPECT_OK_SIGNATURE_PARSE("(J)F", /*args*/"J", /*ret*/"F");
135 EXPECT_OK_SIGNATURE_PARSE("(D)V", /*args*/"D", /*ret*/"V");
136 EXPECT_OK_SIGNATURE_PARSE("(Ljava/lang/Object;)V", "Ljava/lang/Object;", "V");
137 EXPECT_OK_SIGNATURE_PARSE("([Ljava/lang/Object;)V",
138 "[Ljava/lang/Object;",
139 "V");
140 EXPECT_OK_SIGNATURE_PARSE("([I)V", /*ret*/"[I", "V");
141 EXPECT_OK_SIGNATURE_PARSE("([[I)V", /*ret*/"[[I", "V");
142 EXPECT_OK_SIGNATURE_PARSE("([[[I)V", /*ret*/"[[[I", "V");
143
144 EXPECT_OK_SIGNATURE_PARSE("(ZIJ)V", /*args*/"Z,I,J", /*ret*/"V");
145 EXPECT_OK_SIGNATURE_PARSE("(B[IJ)V", /*args*/"B,[I,J", /*ret*/"V");
146 EXPECT_OK_SIGNATURE_PARSE("(Ljava/lang/Object;B)D", /*args*/
147 "Ljava/lang/Object;,B", /*ret*/
148 "D");
149 EXPECT_OK_SIGNATURE_PARSE("(Ljava/lang/Object;Ljava/lang/String;IF)D", /*args*/
150 "Ljava/lang/Object;,Ljava/lang/String;,I,F", /*ret*/
151 "D");
152 EXPECT_OK_SIGNATURE_PARSE("([[[Ljava/lang/Object;Ljava/lang/String;IF)D", /*args*/
153 "[[[Ljava/lang/Object;,Ljava/lang/String;,I,F", /*ret*/
154 "D");
155
156 /*
157 * Test Failures in Parsing
158 */
159
160#define EXPECT_FAILED_SIGNATURE_PARSE(jni_descriptor) \
161 EXPECT_STRINGIFY_EQ(ConstexprOptional<JniSignatureDescriptor<sizeof(jni_descriptor)>>{},\
162 ParseSignatureAsList<sizeof(jni_descriptor)>(jni_descriptor))
163
164 // For the failures to work we must turn off 'PARSE_FAILURES_FATAL'.
165 // Otherwise they immediately cause a crash, which is actually the desired behavior
166 // when this is used by the end-user in REGISTER_NATIVE_METHOD.
167 {
168 EXPECT_FAILED_SIGNATURE_PARSE("");
169 EXPECT_FAILED_SIGNATURE_PARSE("A");
170 EXPECT_FAILED_SIGNATURE_PARSE(")");
171 EXPECT_FAILED_SIGNATURE_PARSE("V");
172 EXPECT_FAILED_SIGNATURE_PARSE("(");
173 EXPECT_FAILED_SIGNATURE_PARSE("(A");
174 EXPECT_FAILED_SIGNATURE_PARSE("()");
175 EXPECT_FAILED_SIGNATURE_PARSE("()A");
176 EXPECT_FAILED_SIGNATURE_PARSE("()VV");
177 EXPECT_FAILED_SIGNATURE_PARSE("()L");
178 EXPECT_FAILED_SIGNATURE_PARSE("()L;");
179 EXPECT_FAILED_SIGNATURE_PARSE("()BAD;");
180 EXPECT_FAILED_SIGNATURE_PARSE("()Ljava/lang/Object");
181 EXPECT_FAILED_SIGNATURE_PARSE("()Ljava/lang/Object;X");
182
183 EXPECT_FAILED_SIGNATURE_PARSE("(V)V");
184 EXPECT_FAILED_SIGNATURE_PARSE("(ILcat)V");
185 EXPECT_FAILED_SIGNATURE_PARSE("([dog)V");
186 EXPECT_FAILED_SIGNATURE_PARSE("(IV)V");
187 EXPECT_FAILED_SIGNATURE_PARSE("([V)V");
188 EXPECT_FAILED_SIGNATURE_PARSE("([[V)V");
189 EXPECT_FAILED_SIGNATURE_PARSE("()v");
190 EXPECT_FAILED_SIGNATURE_PARSE("()i");
191 EXPECT_FAILED_SIGNATURE_PARSE("()f");
192 }
193
194}
195
196#define EXPECT_IS_VALID_JNI_ARGUMENT_TYPE(expected, expr) \
197 { constexpr bool is_valid = (expr); \
198 EXPECT_EQ(expected, is_valid) << #expr; \
199 }
200
201// Basic smoke tests for parameter validity.
202// See below for more exhaustive tests.
203TEST(JniSafeRegisterNativeMethods, ParameterTypes) {
204 using namespace nativehelper::detail;
205 EXPECT_TRUE(IsJniParameterCountValid(kCriticalNative, 0u));
206 EXPECT_TRUE(IsJniParameterCountValid(kCriticalNative, 1u));
207 EXPECT_TRUE(IsJniParameterCountValid(kCriticalNative, 2u));
208 EXPECT_TRUE(IsJniParameterCountValid(kCriticalNative, 3u));
209 EXPECT_TRUE(IsJniParameterCountValid(kCriticalNative, 4u));
210
211 EXPECT_FALSE(IsJniParameterCountValid(kNormalNative, 0u));
212 EXPECT_FALSE(IsJniParameterCountValid(kNormalNative, 1u));
213 EXPECT_TRUE(IsJniParameterCountValid(kNormalNative, 2u));
214 EXPECT_TRUE(IsJniParameterCountValid(kNormalNative, 3u));
215 EXPECT_TRUE(IsJniParameterCountValid(kNormalNative, 4u));
216
217 EXPECT_TRUE((IsValidJniParameter<void>(kNormalNative, kReturnPosition)));
218 EXPECT_IS_VALID_JNI_ARGUMENT_TYPE(true,(is_valid_jni_argument_type<kNormalNative, /*pos*/0u, JNIEnv*>::value));
219 EXPECT_IS_VALID_JNI_ARGUMENT_TYPE(true,(is_valid_jni_argument_type<kNormalNative, /*pos*/1u, jobject>::value));
220 EXPECT_IS_VALID_JNI_ARGUMENT_TYPE(true,(is_valid_jni_argument_type<kNormalNative, /*pos*/1u, jclass>::value));
221 EXPECT_IS_VALID_JNI_ARGUMENT_TYPE(false,(is_valid_jni_argument_type<kNormalNative, /*pos*/1u, jstring>::value));
222}
223
224struct TestReturnAnything {
225 template <typename T>
226 operator T() const {
227 return T{};
228 }
229};
230
231namespace test_jni {
232 void empty_fn() {}
233}
234struct TestJni {
235
236#pragma clang diagnostic push
237#pragma clang diagnostic ignored "-Wunused-parameter"
238
239 // Always bad.
240 static void bad_cptr(const char* ptr) {}
241 static void* bad_ret_ptr() { return nullptr; }
242 static JNIEnv* bad_ret_env() { return nullptr; }
243 static void bad_wrongplace_env(jobject, JNIEnv*) {}
244 static void bad_wrongplace_env2(jobject, jobject, JNIEnv*) {}
245 static void v_e(JNIEnv*) {}
246 static void v_ei(JNIEnv*, jint l) {}
247 static void v_el(JNIEnv*, jlong l) {}
248 static void v_et(JNIEnv*, jstring) {}
249 static jobject o_none() { return nullptr; }
250 static void bad_noref_jint_norm(JNIEnv*, jclass, jint&) {}
251 static void bad_noref_jint_crit(jint&) {}
252
253 // Good depending on the context:
254
255 // CriticalNative
256 static void empty_fn() {}
257 static jint int_fn() { return 0; }
258
259 static void v_() {}
260 static void v_vol_i(volatile jint) {}
261 static void v_const_i(const jint) {}
262 static void v_i(jint) {}
263 static void v_l(jlong) {}
264 static void v_lib(jlong, jint, jboolean) {}
265 static jshort s_lib(jlong, jint, jboolean) { return 0; }
266
267 // Normal or FastNative.
268 static void v_eo(JNIEnv*, jobject) {}
269 static void v_eoo(JNIEnv*, jobject, jobject) {}
270 static void v_ek(JNIEnv*, jclass) {}
271 static void v_eolib(JNIEnv*, jobject, jlong, jint, jboolean) {}
272 static jshort s_eolAibA(JNIEnv*, jobject, jlongArray, jint, jbooleanArray) { return 0; }
273
274#define DEC_TEST_FN_IMPL(name, ret_t, ...) \
275 static ret_t name (__VA_ARGS__) { return TestReturnAnything{}; }
276
277#define DEC_TEST_FN(name, correct, ret_t, ...) \
278 DEC_TEST_FN_IMPL(normal_ ## name, ret_t, JNIEnv*, jobject, __VA_ARGS__) \
279 DEC_TEST_FN_IMPL(normal2_ ## name, ret_t, JNIEnv*, jclass, __VA_ARGS__) \
280 DEC_TEST_FN_IMPL(critical_ ## name, ret_t, __VA_ARGS__)
281
282#define DEC_TEST_FN0(name, correct, ret_t) \
283 DEC_TEST_FN_IMPL(normal_ ## name, ret_t, JNIEnv*, jobject) \
284 DEC_TEST_FN_IMPL(normal2_ ## name, ret_t, JNIEnv*, jclass) \
285 DEC_TEST_FN_IMPL(critical_ ## name, ret_t)
286
287#define JNI_TEST_FN(FN, FN0) \
288 FN0(a0,CRITICAL,void) \
289 FN0(a ,CRITICAL,jboolean) \
290 FN0(a1,CRITICAL,jbyte) \
291 FN0(g, CRITICAL,jchar) \
292 FN0(c, CRITICAL,jshort) \
293 FN0(b, CRITICAL,jint) \
294 FN0(f, CRITICAL,jlong) \
295 FN0(d, CRITICAL,jfloat) \
296 FN0(e, CRITICAL,jdouble) \
297 FN0(f2,NORMAL ,jobject) \
298 FN0(f3,NORMAL ,jclass) \
299 FN0(fr,NORMAL ,jstring) \
300 FN0(fa,NORMAL ,jarray) \
301 FN0(fb,NORMAL ,jobjectArray) \
302 FN0(fc,NORMAL ,jbooleanArray) \
303 FN0(fd,NORMAL ,jcharArray) \
304 FN0(fe,NORMAL ,jshortArray) \
305 FN0(ff,NORMAL ,jintArray) \
306 FN0(fg,NORMAL ,jlongArray) \
307 FN0(fk,NORMAL ,jfloatArray) \
308 FN0(fi,NORMAL ,jdoubleArray) \
309 FN0(fl,NORMAL ,jthrowable) \
310 FN(aa, CRITICAL,jboolean,jboolean) \
311 FN(ax, CRITICAL,jbyte,jbyte) \
312 FN(ag, CRITICAL,jchar,jchar) \
313 FN(ac, CRITICAL,jshort,jshort) \
314 FN(ac2,CRITICAL,jshort,jshort,jchar) \
315 FN(ab, CRITICAL,jint,jint) \
316 FN(af, CRITICAL,jlong,jlong) \
317 FN(ad, CRITICAL,jfloat,jfloat) \
318 FN(ae, CRITICAL,jdouble,jdouble) \
319 FN(af2,NORMAL ,jobject,jobject) \
320 FN(af3,NORMAL ,jclass,jclass) \
321 FN(afr,NORMAL ,jstring,jstring) \
322 FN(afa,NORMAL ,jarray,jarray) \
323 FN(afb,NORMAL ,jobjectArray,jobjectArray) \
324 FN(afc,NORMAL ,jbooleanArray,jbooleanArray) \
325 FN(afd,NORMAL ,jcharArray,jcharArray) \
326 FN(afe,NORMAL ,jshortArray,jshortArray) \
327 FN(aff,NORMAL ,jintArray,jintArray) \
328 FN(afg,NORMAL ,jlongArray,jlongArray) \
329 FN(afk,NORMAL ,jfloatArray,jfloatArray) \
330 FN(afi,NORMAL ,jdoubleArray,jdoubleArray) \
331 FN(agi,NORMAL ,jdoubleArray,jdoubleArray,jobject) \
332 FN(afl,NORMAL ,jthrowable,jthrowable) \
333 \
334 FN0(z0,ILLEGAL ,JNIEnv*) \
335 FN(z1, ILLEGAL ,void, JNIEnv*) \
336 FN(z2, ILLEGAL ,JNIEnv*, JNIEnv*) \
337 FN(z3, ILLEGAL ,void, void*) \
338 FN0(z4,ILLEGAL ,void*) \
339
340#define JNI_TEST_FN_BOTH(x) JNI_TEST_FN(x,x)
341
342// we generate a return statement because some functions are non-void.
343// disable the useless warning about returning from a non-void function.
344#pragma clang diagnostic push
345#pragma clang diagnostic ignored "-Wreturn-type"
346 JNI_TEST_FN(DEC_TEST_FN, DEC_TEST_FN0);
347#pragma clang diagnostic pop
348
349 // TODO: probably should be an x-macro table
350 // and that way we can add critical/normal to it as well
351 // and also the type descriptor, and reuse this for multiple tests.
352
353#pragma clang diagnostic pop
354};
355// Note: Using function-local structs does not work.
356// Template parameters must have linkage, which function-local structs lack.
357
358TEST(JniSafeRegisterNativeMethods, FunctionTypes) {
359 using namespace nativehelper::detail;
360 // The exact error messages are not tested but they would be seen in the compiler
361 // stack trace when used from a constexpr context.
362
363#define IS_VALID_JNI_FUNCTION_TYPE(native_kind, func) (IsValidJniFunctionType<native_kind, decltype(func), (func)>())
364#define IS_VALID_NORMAL_JNI_FUNCTION_TYPE(func) IS_VALID_JNI_FUNCTION_TYPE(kNormalNative, func)
365#define IS_VALID_CRITICAL_JNI_FUNCTION_TYPE(func) IS_VALID_JNI_FUNCTION_TYPE(kCriticalNative, func)
366
367#define EXPECT_ILLEGAL_JNI_FUNCTION_TYPE(func) \
368 do { \
369 EXPECT_FALSE(IS_VALID_CRITICAL_JNI_FUNCTION_TYPE(func)); \
370 EXPECT_FALSE(IS_VALID_NORMAL_JNI_FUNCTION_TYPE(func)); \
371 } while (false)
372
373#define EXPECT_EITHER_JNI_FUNCTION_TYPE(func) \
374 do { \
375 EXPECT_TRUE(IS_VALID_CRITICAL_JNI_FUNCTION_TYPE(func)); \
376 EXPECT_TRUE(IS_VALID_NORMAL_JNI_FUNCTION_TYPE(func)); \
377 } while (false)
378
379#define EXPECT_NORMAL_JNI_FUNCTION_TYPE(func) \
380 do { \
381 EXPECT_FALSE(IS_VALID_CRITICAL_JNI_FUNCTION_TYPE(func)); \
382 EXPECT_TRUE(IS_VALID_NORMAL_JNI_FUNCTION_TYPE(func)); \
383 } while (false)
384
385#define EXPECT_CRITICAL_JNI_FUNCTION_TYPE(func) \
386 do { \
387 EXPECT_TRUE(IS_VALID_CRITICAL_JNI_FUNCTION_TYPE(func)); \
388 EXPECT_FALSE(IS_VALID_NORMAL_JNI_FUNCTION_TYPE(func)); \
389 } while (false)
390
391 {
392 EXPECT_ILLEGAL_JNI_FUNCTION_TYPE(TestJni::bad_cptr);
393 EXPECT_ILLEGAL_JNI_FUNCTION_TYPE(TestJni::bad_ret_ptr);
394 EXPECT_ILLEGAL_JNI_FUNCTION_TYPE(TestJni::bad_ret_env);
395 EXPECT_ILLEGAL_JNI_FUNCTION_TYPE(TestJni::bad_wrongplace_env);
396 EXPECT_ILLEGAL_JNI_FUNCTION_TYPE(TestJni::bad_wrongplace_env2);
397
398 EXPECT_CRITICAL_JNI_FUNCTION_TYPE(TestJni::empty_fn);
399 EXPECT_CRITICAL_JNI_FUNCTION_TYPE(test_jni::empty_fn);
400 EXPECT_CRITICAL_JNI_FUNCTION_TYPE(TestJni::int_fn);
401
402 EXPECT_CRITICAL_JNI_FUNCTION_TYPE(TestJni::v_);
403 EXPECT_CRITICAL_JNI_FUNCTION_TYPE(TestJni::v_vol_i);
404 EXPECT_CRITICAL_JNI_FUNCTION_TYPE(TestJni::v_const_i);
405 EXPECT_CRITICAL_JNI_FUNCTION_TYPE(TestJni::v_i);
406 EXPECT_CRITICAL_JNI_FUNCTION_TYPE(TestJni::v_l);
407
408 EXPECT_ILLEGAL_JNI_FUNCTION_TYPE(TestJni::v_e);
409 EXPECT_ILLEGAL_JNI_FUNCTION_TYPE(TestJni::v_ei);
410 EXPECT_ILLEGAL_JNI_FUNCTION_TYPE(TestJni::v_el);
411 EXPECT_ILLEGAL_JNI_FUNCTION_TYPE(TestJni::v_et);
412
413 EXPECT_NORMAL_JNI_FUNCTION_TYPE(TestJni::v_eo);
414 EXPECT_NORMAL_JNI_FUNCTION_TYPE(TestJni::v_ek);
415
416 EXPECT_ILLEGAL_JNI_FUNCTION_TYPE(TestJni::o_none);
417 EXPECT_ILLEGAL_JNI_FUNCTION_TYPE(TestJni::bad_noref_jint_norm);
418 EXPECT_ILLEGAL_JNI_FUNCTION_TYPE(TestJni::bad_noref_jint_crit);
419 }
420
421 enum class TestJniKind {
422 ILLEGAL,
423 NORMAL,
424 CRITICAL
425 };
426
427 // ILLEGAL signatures are always illegal.
428 bool kExpected_ILLEGAL_against_NORMAL = false;
429 bool kExpected_ILLEGAL_against_CRITICAL = false;
430 // NORMAL signatures are only legal for Normal JNI.
431 bool kExpected_NORMAL_against_NORMAL = true;
432 bool kExpected_NORMAL_against_CRITICAL = false;
433 // CRITICAL signatures are legal for both Normal+Critical JNI.
434 bool kExpected_CRITICAL_against_CRITICAL = true;
435 bool kExpected_CRITICAL_against_NORMAL = true;
436 // Note that we munge normal and critical type signatures separately
437 // and that a normal_ prefixed is always a bad critical signature,
438 // and a critical_ prefixed signature is always a bad normal signature.
439 // See JNI_TEST_FN_MAKE_TEST for the implementation of this logic.
440
441#undef EXPECTED_FOR
442#define EXPECTED_FOR(jni_kind, context) \
443 (kExpected_ ## jni_kind ## _against_ ## context)
444
445 {
446#define JNI_TEST_FN_MAKE_TEST(name, jni_kind, ...) \
447 do { \
448 EXPECT_EQ(EXPECTED_FOR(jni_kind, NORMAL), \
449 IS_VALID_NORMAL_JNI_FUNCTION_TYPE(TestJni::normal_ ## name)); \
450 EXPECT_FALSE(IS_VALID_CRITICAL_JNI_FUNCTION_TYPE(TestJni::normal_ ## name)); \
451 EXPECT_EQ(EXPECTED_FOR(jni_kind, NORMAL), \
452 IS_VALID_NORMAL_JNI_FUNCTION_TYPE(TestJni::normal2_ ## name)); \
453 EXPECT_FALSE(IS_VALID_CRITICAL_JNI_FUNCTION_TYPE(TestJni::normal2_ ## name)); \
454 EXPECT_EQ(EXPECTED_FOR(jni_kind, CRITICAL), \
455 IS_VALID_CRITICAL_JNI_FUNCTION_TYPE(TestJni::critical_ ## name)); \
456 EXPECT_FALSE(IS_VALID_NORMAL_JNI_FUNCTION_TYPE(TestJni::critical_ ## name)); \
457 } while (false);
458
459 JNI_TEST_FN_BOTH(JNI_TEST_FN_MAKE_TEST);
460 }
461}
462
463#define EXPECT_CONSTEXPR_EQ(lhs, rhs) \
464 { constexpr auto lhs_val = (lhs); \
465 constexpr auto rhs_val = (rhs); \
466 EXPECT_EQ(lhs_val, rhs_val) << "LHS: " << #lhs << ", RHS: " << #rhs; \
467 }
468
469TEST(JniSafeRegisterNativeMethods, FunctionTypeDescriptorConversion) {
470 using namespace nativehelper::detail;
471 {
472 constexpr auto cvrt = MaybeMakeReifiedJniSignature<kCriticalNative,
473 decltype(TestJni::v_i),
474 TestJni::v_i>();
475 EXPECT_TRUE(cvrt.has_value());
476 EXPECT_CONSTEXPR_EQ(2u, cvrt->max_size);
477 EXPECT_CONSTEXPR_EQ(1u, cvrt->args.size());
478 EXPECT_STRINGIFY_EQ("args={jint}, ret=void", cvrt.value());
479 }
480
481 {
482 constexpr auto cvrt = MaybeMakeReifiedJniSignature<kNormalNative,
483 decltype(TestJni::v_i),
484 TestJni::v_i>();
485 EXPECT_FALSE(cvrt.has_value());
486 }
487
488 {
489 constexpr auto cvrt = MaybeMakeReifiedJniSignature<kNormalNative,
490 decltype(TestJni::normal_agi),
491 TestJni::normal_agi>();
492 EXPECT_TRUE(cvrt.has_value());
493 EXPECT_EQ(2u, cvrt->args.size());
494 EXPECT_STRINGIFY_EQ("args={jdoubleArray,jobject}, ret=jdoubleArray", cvrt.value());
495 }
496
497 {
498 constexpr auto cvrt = MaybeMakeReifiedJniSignature<kCriticalNative,
499 decltype(TestJni::critical_ac2),
500 TestJni::critical_ac2>();
501 EXPECT_TRUE(cvrt.has_value());
502 EXPECT_EQ(2u, cvrt->args.size());
503 EXPECT_STRINGIFY_EQ("args={jshort,jchar}, ret=jshort", cvrt.value());
504 }
505
506 // TODO: use JNI_TEST_FN to generate these tests automatically.
507}
508
509struct test_function_traits {
510 static int int_returning_function() { return 0; }
511};
512
513template <typename T>
514struct apply_return_type {
515 constexpr int operator()() const {
516 return sizeof(T) == sizeof(int);
517 }
518};
519
520#define FN_ARGS_PAIR(fn) decltype(fn), (fn)
521
522TEST(JniSafeRegisterNativeMethods, FunctionTraits) {
523 using namespace nativehelper::detail;
524 using traits_for_int_ret = FunctionTypeMetafunction<FN_ARGS_PAIR(test_function_traits::int_returning_function)>;
525 int applied = traits_for_int_ret::map_return<apply_return_type>();
526 EXPECT_EQ(1, applied);
527
528 auto arr = traits_for_int_ret::map_args<apply_return_type>();
529 EXPECT_EQ(0u, arr.size());
530}
531
532struct IntHolder {
533 int value;
534};
535
536constexpr int GetTestValue(const IntHolder& i) {
537 return i.value;
538}
539
540constexpr int GetTestValue(int i) {
541 return i;
542}
543
544template <typename T, size_t kMaxSize>
545constexpr size_t SumUpVector(const nativehelper::detail::ConstexprVector<T, kMaxSize>& vec) {
546 size_t s = 0;
547 for (const T& elem : vec) {
548 s += static_cast<size_t>(GetTestValue(elem));
549 }
550 return s;
551}
552
553template <typename T>
554constexpr auto make_test_int_vector() {
555 using namespace nativehelper::detail;
556 ConstexprVector<T, 5> vec_int;
557 vec_int.push_back(T{1});
558 vec_int.push_back(T{2});
559 vec_int.push_back(T{3});
560 vec_int.push_back(T{4});
561 vec_int.push_back(T{5});
562 return vec_int;
563}
564
565TEST(JniSafeRegisterNativeMethods, ConstexprVector) {
566 using namespace nativehelper::detail;
567 {
568 constexpr ConstexprVector<IntHolder, 5> vec_int = make_test_int_vector<IntHolder>();
569 constexpr size_t the_sum = SumUpVector(vec_int);
570 EXPECT_EQ(15u, the_sum);
571 }
572
573 {
574 constexpr ConstexprVector<int, 5> vec_int = make_test_int_vector<int>();
575 constexpr size_t the_sum = SumUpVector(vec_int);
576 EXPECT_EQ(15u, the_sum);
577 }
578}
579
580// Need this intermediate function to make a JniDescriptorNode from a string literal.
581// C++ doesn't do implicit conversion through two+ type constructors.
582constexpr nativehelper::detail::JniDescriptorNode MakeNode(
583 nativehelper::detail::ConstexprStringView str) {
584 return nativehelper::detail::JniDescriptorNode{str};
585}
586
587#define EXPECT_EQUALISH_JNI_DESCRIPTORS_IMPL(user_desc, derived, cond) \
588 do { \
589 constexpr bool res = CompareJniDescriptorNodeErased(MakeNode(user_desc), ReifiedJniTypeTrait::Reify<derived>()); \
590 (void)res; \
591 EXPECT_ ## cond(CompareJniDescriptorNodeErased(MakeNode(user_desc), ReifiedJniTypeTrait::Reify<derived>())); \
592 } while (0);
593
594#define EXPECT_EQUALISH_JNI_DESCRIPTORS(user_desc, derived_desc) \
595 EXPECT_EQUALISH_JNI_DESCRIPTORS_IMPL(user_desc, derived_desc, TRUE)
596
597#define EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS(user_desc, derived_desc) \
598 EXPECT_EQUALISH_JNI_DESCRIPTORS_IMPL(user_desc, derived_desc, FALSE)
599
600TEST(JniSafeRegisterNativeMethods, CompareJniDescriptorNodeErased) {
601 using namespace nativehelper::detail;
602 EXPECT_EQUALISH_JNI_DESCRIPTORS("V", void);
603 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("V", jint);
604 EXPECT_EQUALISH_JNI_DESCRIPTORS("Z", jboolean);
605 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("Z", void);
606 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("Z", jobject);
607 EXPECT_EQUALISH_JNI_DESCRIPTORS("J", jlong);
608 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("J", jobject);
609 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("J", jthrowable);
610 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("J", jint);
611 EXPECT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/String;", jstring);
612 EXPECT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/Class;", jclass);
613 EXPECT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/Object;", jobject);
614 EXPECT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/Integer;", jobject);
615 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("[Z", jthrowable);
616 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("[Z", jobjectArray);
617 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/Integer;", jintArray);
618 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/Integer;", jarray);
619 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/Integer;", jarray);
620
621 // Stricter checks.
622 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/Object;", jobjectArray);
623 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/String;", jobject);
624 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/Class;", jobject);
625 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("[Z", jobject);
626 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("[Ljava/lang/Object;", jobject);
627 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/Object;", jarray);
628
629 // Permissive checks that are weaker than normal.
630 EXPECT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/Exception;", jobject);
631 EXPECT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/Error;", jobject);
632 EXPECT_EQUALISH_JNI_DESCRIPTORS("[Z", jarray);
633 EXPECT_EQUALISH_JNI_DESCRIPTORS("[I", jarray);
634 EXPECT_EQUALISH_JNI_DESCRIPTORS("[[Z", jarray);
635 EXPECT_EQUALISH_JNI_DESCRIPTORS("[[Ljava/lang/Object;", jarray);
636
637 // jthrowable-related checks.
638 EXPECT_NOT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/Throwable;", jobject);
639 EXPECT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/Throwable;", jthrowable);
640 EXPECT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/Exception;", jthrowable);
641 EXPECT_EQUALISH_JNI_DESCRIPTORS("Ljava/lang/Error;", jthrowable);
642}
643
644#define EXPECT_SIMILAR_TYPE_DESCRIPTOR_MATCH(type_desc, type) \
645 do { \
646 constexpr auto res = ReifiedJniTypeTrait::MostSimilarTypeDescriptor(type_desc); \
647 EXPECT_TRUE((ReifiedJniTypeTrait::MostSimilarTypeDescriptor(type_desc)).has_value());\
648 if (res.has_value()) EXPECT_EQ(ReifiedJniTypeTrait::Reify<type>(), res.value()); \
649 } while (false)
650
651#define EXPECT_SIMILAR_TYPE_DESCRIPTOR_NO_MATCH(type_desc) \
652 do { \
653 auto res = ReifiedJniTypeTrait::MostSimilarTypeDescriptor(type_desc); \
654 EXPECT_FALSE(res.has_value()); \
655 } while (false)
656
657#define JNI_TYPE_TRAIT_MUST_BE_SAME_FN(type_name, type_desc, ...) \
658 /* skip jarray because it aliases Ljava/lang/Object; */ \
659 do { \
660 constexpr auto str_type_name = ConstexprStringView(#type_name); \
661 if (str_type_name != "jarray" && str_type_name != "JNIEnv*") { \
662 EXPECT_SIMILAR_TYPE_DESCRIPTOR_MATCH(type_desc, type_name); \
663 } \
664 } while(false);
665
666TEST(JniSafeRegisterNativeMethods, MostSimilarTypeDescriptor) {
667 using namespace nativehelper::detail;
668 EXPECT_SIMILAR_TYPE_DESCRIPTOR_MATCH("Z", jboolean);
669 EXPECT_SIMILAR_TYPE_DESCRIPTOR_MATCH("[[I", jobjectArray);
670 EXPECT_SIMILAR_TYPE_DESCRIPTOR_MATCH("[[Z", jobjectArray);
671 EXPECT_SIMILAR_TYPE_DESCRIPTOR_MATCH("[Ljava/lang/String;", jobjectArray);
672 EXPECT_SIMILAR_TYPE_DESCRIPTOR_MATCH("[Ljava/lang/Integer;", jobjectArray);
673 EXPECT_SIMILAR_TYPE_DESCRIPTOR_NO_MATCH("illegal");
674 EXPECT_SIMILAR_TYPE_DESCRIPTOR_NO_MATCH("?");
675 EXPECT_SIMILAR_TYPE_DESCRIPTOR_NO_MATCH("");
676
677 DEFINE_JNI_TYPE_TRAIT(JNI_TYPE_TRAIT_MUST_BE_SAME_FN);
678}
679
680#define ENFORCE_CONSTEXPR(expr) \
681 static_assert(__builtin_constant_p(expr), "Expression must be constexpr")
682
683#define EXPECT_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION_IMPL(cond, native_kind, func, desc) \
684 do { \
685 ENFORCE_CONSTEXPR((MatchJniDescriptorWithFunctionType< \
686 native_kind, \
687 decltype(func), \
688 func, \
689 sizeof(desc)>(desc))); \
690 EXPECT_ ## cond((MatchJniDescriptorWithFunctionType< \
691 native_kind, \
692 decltype(func), \
693 func, \
694 sizeof(desc)>(desc))); \
695 } while(0)
696
697#define EXPECT_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(native_kind, func, desc) \
698 EXPECT_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION_IMPL(TRUE, native_kind, func, desc)
699
700#define EXPECT_NO_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(native_kind, func, desc) \
701 EXPECT_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION_IMPL(FALSE, native_kind, func, desc)
702
703TEST(JniSafeRegisterNativeMethods, MatchJniDescriptorWithFunctionType) {
704 using namespace nativehelper::detail;
705 // Bad C++ signature.
706 EXPECT_NO_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kCriticalNative, TestJni::bad_cptr, "()V");
707 EXPECT_NO_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kNormalNative, TestJni::bad_cptr, "()V");
708
709 // JNI type descriptor is not legal (by itself).
710 EXPECT_NO_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kCriticalNative, TestJni::v_, "BAD");
711 EXPECT_NO_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kNormalNative, TestJni::v_eo, "BAD");
712
713 // Number of parameters in signature vs C++ function does not match.
714 EXPECT_NO_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kCriticalNative, TestJni::v_i, "()V");
715 EXPECT_NO_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kNormalNative, TestJni::v_eoo, "()V");
716
717 // Return types don't match.
718 EXPECT_NO_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kCriticalNative, TestJni::v_, "()Z");
719 EXPECT_NO_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kFastNative, TestJni::v_eo, "()Z");
720
721 // Argument types don't match.
722 EXPECT_NO_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kCriticalNative, TestJni::v_i, "(Z)V");
723 EXPECT_NO_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kNormalNative, TestJni::v_eoo, "(Ljava/lang/Class;)V");
724
725 // OK.
726 EXPECT_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kCriticalNative, TestJni::v_i, "(I)V");
727 EXPECT_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kNormalNative, TestJni::v_eoo, "(Ljava/lang/Object;)V");
728
729 EXPECT_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kCriticalNative, TestJni::v_lib, "(JIZ)V");
730 EXPECT_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kNormalNative, TestJni::v_eolib, "(JIZ)V");
731 EXPECT_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kCriticalNative, TestJni::s_lib, "(JIZ)S");
732 EXPECT_MATCH_JNI_DESCRIPTOR_AGAINST_FUNCTION(kNormalNative, TestJni::s_eolAibA, "([JI[Z)S");
733}
734
735TEST(JniSafeRegisterNativeMethods, Infer) {
736 using namespace nativehelper::detail;
737 {
738 using Infer_v_eolib_t = InferJniDescriptor<kNormalNative,
739 decltype(TestJni::v_eolib),
740 TestJni::v_eolib>;
741 EXPECT_CONSTEXPR_EQ(6u, Infer_v_eolib_t::kMaxStringSize);
742 std::string x = Infer_v_eolib_t::GetStringAtRuntime();
743 EXPECT_STRINGIFY_EQ("(JIZ)V", x.c_str());
744 }
745
746 {
747 using Infer_v_eolib_t = InferJniDescriptor<kNormalNative,
748 decltype(TestJni::s_eolAibA),
749 TestJni::s_eolAibA>;
750 EXPECT_STRINGIFY_EQ("args={[J,I,[Z}, ret=S", Infer_v_eolib_t::FromFunctionType().value());
751 EXPECT_CONSTEXPR_EQ(8u, Infer_v_eolib_t::kMaxStringSize);
752 std::string x = Infer_v_eolib_t::GetStringAtRuntime();
753 EXPECT_STRINGIFY_EQ("([JI[Z)S", x.c_str());
754 }
755}
756
757// Test the macro definition only. See other tests above for signature-match testing.
758TEST(JniSafeRegisterNativeMethods, MakeCheckedJniNativeMethod) {
759 // Ensure the temporary variables don't conflict with other local vars of same name.
760 JNINativeMethod tmp_native_method; // shadow test.
761 (void) tmp_native_method;
762 bool is_signature_valid = true; // shadow test.
763 (void) is_signature_valid;
764
765 // Ensure it works with critical.
766 {
767 JNINativeMethod m =
768 MAKE_CHECKED_JNI_NATIVE_METHOD(kCriticalNative,
769 "v_lib",
770 "(JIZ)V",
771 TestJni::v_lib);
772 (void)m;
773 }
774
775 // Ensure it works with normal.
776 {
777 JNINativeMethod m =
778 MAKE_CHECKED_JNI_NATIVE_METHOD(kNormalNative,
779 "v_eolib",
780 "(JIZ)V",
781 TestJni::v_eolib);
782 (void)m;
783 }
784
785 // Make sure macros properly expand inside of an array.
786 {
787 JNINativeMethod m_array[] = {
788 MAKE_CHECKED_JNI_NATIVE_METHOD(kCriticalNative,
789 "v_lib",
790 "(JIZ)V",
791 TestJni::v_lib),
792 MAKE_CHECKED_JNI_NATIVE_METHOD(kNormalNative,
793 "v_eolib",
794 "(JIZ)V",
795 TestJni::v_eolib),
796 };
797 (void)m_array;
798 }
799 {
800 JNINativeMethod m_array_direct[] {
801 MAKE_CHECKED_JNI_NATIVE_METHOD(kCriticalNative,
802 "v_lib",
803 "(JIZ)V",
804 TestJni::v_lib),
805 MAKE_CHECKED_JNI_NATIVE_METHOD(kNormalNative,
806 "v_eolib",
807 "(JIZ)V",
808 TestJni::v_eolib),
809 };
810 (void)m_array_direct;
811 }
812
813}
814
815static auto sTestCheckedAtFileScope =
816 MAKE_CHECKED_JNI_NATIVE_METHOD(kCriticalNative,
817 "v_lib",
818 "(JIZ)V",
819 TestJni::v_lib);
820
821static auto sTestInferredAtFileScope =
822 MAKE_INFERRED_JNI_NATIVE_METHOD(kCriticalNative,
823 "v_lib",
824 TestJni::v_lib);
825
826TEST(JniSafeRegisterNativeMethods, TestInferredJniNativeMethod) {
827 (void) sTestCheckedAtFileScope;
828 (void) sTestInferredAtFileScope;
829
830 // Ensure it works with critical.
831 {
832 JNINativeMethod m =
833 MAKE_INFERRED_JNI_NATIVE_METHOD(kCriticalNative,
834 "v_lib",
835 TestJni::v_lib);
836 (void)m;
837 }
838
839 // Ensure it works with normal.
840 {
841 JNINativeMethod m =
842 MAKE_INFERRED_JNI_NATIVE_METHOD(kNormalNative,
843 "v_eolib",
844 TestJni::v_eolib);
845 (void)m;
846 }
847}
848
849static void TestJniMacros_v_lib(jlong, jint, jboolean) {}
850static void TestJniMacros_v_lib_od(jlong, jint, jboolean) {}
851static void TestJniMacros_v_eolib(JNIEnv*, jobject, jlong, jint, jboolean) {}
852static void TestJniMacros_v_eolib_od(JNIEnv*, jobject, jlong, jint, jboolean) {}
853
854TEST(JniSafeRegisterNativeMethods, JniMacros) {
855 JNINativeMethod tmp_native_method; // shadow variable check.
856 (void)tmp_native_method;
857 using Infer_t = int; // shadow using check.
858 Infer_t unused;
859 (void)unused;
860
861 MAKE_JNI_CRITICAL_NATIVE_METHOD("v_lib", "(JIZ)V", TestJniMacros_v_lib);
862 MAKE_JNI_CRITICAL_NATIVE_METHOD_AUTOSIG("v_lib", TestJniMacros_v_lib);
863 CRITICAL_NATIVE_METHOD(TestJniMacros, v_lib, "(JIZ)V");
864 OVERLOADED_CRITICAL_NATIVE_METHOD(TestJniMacros, v_lib, "(JIZ)V", v_lib_od);
865 CRITICAL_NATIVE_METHOD_AUTOSIG(TestJniMacros, v_lib);
866
867 MAKE_JNI_FAST_NATIVE_METHOD("v_eolib", "(JIZ)V", TestJniMacros_v_eolib);
868 MAKE_JNI_FAST_NATIVE_METHOD_AUTOSIG("v_eolib", TestJniMacros_v_eolib);
869 FAST_NATIVE_METHOD(TestJniMacros, v_eolib, "(JIZ)V");
870 OVERLOADED_FAST_NATIVE_METHOD(TestJniMacros, v_eolib, "(JIZ)V", v_eolib_od);
871 FAST_NATIVE_METHOD_AUTOSIG(TestJniMacros, v_eolib);
872
873 MAKE_JNI_NATIVE_METHOD("v_eolib", "(JIZ)V", TestJniMacros_v_eolib);
874 MAKE_JNI_NATIVE_METHOD_AUTOSIG("v_eolib", TestJniMacros_v_eolib);
875 NATIVE_METHOD(TestJniMacros, v_eolib, "(JIZ)V");
876 OVERLOADED_NATIVE_METHOD(TestJniMacros, v_eolib, "(JIZ)V", v_eolib_od);
877 NATIVE_METHOD_AUTOSIG(TestJniMacros, v_eolib);
878
879 _NATIVEHELPER_JNI_MAKE_METHOD_OLD(kNormalNative, "v_eolib", "(JIZ)V", TestJniMacros_v_eolib);
880 tmp_native_method =
881 _NATIVEHELPER_JNI_MAKE_METHOD_OLD(kNormalNative, "v_eolib", "(JIZ)V", TestJniMacros_v_eolib);
882}