OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """Extracts native methods from a Java file and generates the JNI bindings. | 6 """Extracts native methods from a Java file and generates the JNI bindings. |
7 If you change this, please run and update the tests.""" | 7 If you change this, please run and update the tests.""" |
8 | 8 |
9 import collections | 9 import collections |
10 import errno | 10 import errno |
(...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
724 def ExtractInitNative(self, options): | 724 def ExtractInitNative(self, options): |
725 for native in self.natives: | 725 for native in self.natives: |
726 if options.jni_init_native_name == 'native' + native.name: | 726 if options.jni_init_native_name == 'native' + native.name: |
727 self.natives.remove(native) | 727 self.natives.remove(native) |
728 return native | 728 return native |
729 return None | 729 return None |
730 | 730 |
731 def GetContent(self): | 731 def GetContent(self): |
732 """Returns the content of the JNI binding file.""" | 732 """Returns the content of the JNI binding file.""" |
733 template = Template("""\ | 733 template = Template("""\ |
734 // Copyright 2014 The Chromium Authors. All rights reserved. | 734 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
735 // Use of this source code is governed by a BSD-style license that can be | 735 // Use of this source code is governed by a BSD-style license that can be |
736 // found in the LICENSE file. | 736 // found in the LICENSE file. |
737 | 737 |
738 | 738 |
739 // This file is autogenerated by | 739 // This file is autogenerated by |
740 // ${SCRIPT_NAME} | 740 // ${SCRIPT_NAME} |
741 // For | 741 // For |
742 // ${FULLY_QUALIFIED_CLASS} | 742 // ${FULLY_QUALIFIED_CLASS} |
743 | 743 |
744 #ifndef ${HEADER_GUARD} | 744 #ifndef ${HEADER_GUARD} |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
940 return template.substitute(values) | 940 return template.substitute(values) |
941 | 941 |
942 def GetRegisterNativesImplString(self): | 942 def GetRegisterNativesImplString(self): |
943 """Returns the shared implementation for RegisterNatives.""" | 943 """Returns the shared implementation for RegisterNatives.""" |
944 if self.options.native_exports: | 944 if self.options.native_exports: |
945 return '' | 945 return '' |
946 | 946 |
947 template = Template("""\ | 947 template = Template("""\ |
948 const int kMethods${JAVA_CLASS}Size = arraysize(kMethods${JAVA_CLASS}); | 948 const int kMethods${JAVA_CLASS}Size = arraysize(kMethods${JAVA_CLASS}); |
949 | 949 |
950 if (env->RegisterNatives(${JAVA_CLASS}_clazz(env), | 950 if (env->RegisterNatives(g_${JAVA_CLASS}_clazz, |
951 kMethods${JAVA_CLASS}, | 951 kMethods${JAVA_CLASS}, |
952 kMethods${JAVA_CLASS}Size) < 0) { | 952 kMethods${JAVA_CLASS}Size) < 0) { |
953 jni_generator::HandleRegistrationError( | 953 jni_generator::HandleRegistrationError( |
954 env, ${JAVA_CLASS}_clazz(env), __FILE__); | 954 env, g_${JAVA_CLASS}_clazz, __FILE__); |
955 return false; | 955 return false; |
956 } | 956 } |
957 """) | 957 """) |
958 return self.SubstituteNativeMethods(template) | 958 return self.SubstituteNativeMethods(template) |
959 | 959 |
960 def GetJNIRegisterNativesString(self): | 960 def GetJNIRegisterNativesString(self): |
961 """Returns the implementation for the JNI registration of native methods.""" | 961 """Returns the implementation for the JNI registration of native methods.""" |
962 if not self.init_native: | 962 if not self.init_native: |
963 return '' | 963 return '' |
964 | 964 |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1115 def GetArgument(self, param): | 1115 def GetArgument(self, param): |
1116 return ('as_jint(' + param.name + ')' | 1116 return ('as_jint(' + param.name + ')' |
1117 if param.datatype == 'int' else param.name) | 1117 if param.datatype == 'int' else param.name) |
1118 | 1118 |
1119 def GetArgumentsInCall(self, params): | 1119 def GetArgumentsInCall(self, params): |
1120 """Return a string of arguments to call from native into Java""" | 1120 """Return a string of arguments to call from native into Java""" |
1121 return [self.GetArgument(p) for p in params] | 1121 return [self.GetArgument(p) for p in params] |
1122 | 1122 |
1123 def GetCalledByNativeValues(self, called_by_native): | 1123 def GetCalledByNativeValues(self, called_by_native): |
1124 """Fills in necessary values for the CalledByNative methods.""" | 1124 """Fills in necessary values for the CalledByNative methods.""" |
1125 java_class = called_by_native.java_class_name or self.class_name | |
1126 if called_by_native.static or called_by_native.is_constructor: | 1125 if called_by_native.static or called_by_native.is_constructor: |
1127 first_param_in_declaration = '' | 1126 first_param_in_declaration = '' |
1128 first_param_in_call = ('%s_clazz(env)' % java_class) | 1127 first_param_in_call = ('g_%s_clazz' % |
| 1128 (called_by_native.java_class_name or |
| 1129 self.class_name)) |
1129 else: | 1130 else: |
1130 first_param_in_declaration = ', jobject obj' | 1131 first_param_in_declaration = ', jobject obj' |
1131 first_param_in_call = 'obj' | 1132 first_param_in_call = 'obj' |
1132 params_in_declaration = self.GetCalledByNativeParamsInDeclaration( | 1133 params_in_declaration = self.GetCalledByNativeParamsInDeclaration( |
1133 called_by_native) | 1134 called_by_native) |
1134 if params_in_declaration: | 1135 if params_in_declaration: |
1135 params_in_declaration = ', ' + params_in_declaration | 1136 params_in_declaration = ', ' + params_in_declaration |
1136 params_in_call = ', '.join(self.GetArgumentsInCall(called_by_native.params)) | 1137 params_in_call = ', '.join(self.GetArgumentsInCall(called_by_native.params)) |
1137 if params_in_call: | 1138 if params_in_call: |
1138 params_in_call = ', ' + params_in_call | 1139 params_in_call = ', ' + params_in_call |
(...skipping 13 matching lines...) Expand all Loading... |
1152 return_clause = '' | 1153 return_clause = '' |
1153 if return_type != 'void': | 1154 if return_type != 'void': |
1154 pre_call = ' ' + pre_call | 1155 pre_call = ' ' + pre_call |
1155 return_declaration = return_type + ' ret =' | 1156 return_declaration = return_type + ' ret =' |
1156 if re.match(RE_SCOPED_JNI_RETURN_TYPES, return_type): | 1157 if re.match(RE_SCOPED_JNI_RETURN_TYPES, return_type): |
1157 return_type = 'base::android::ScopedJavaLocalRef<' + return_type + '>' | 1158 return_type = 'base::android::ScopedJavaLocalRef<' + return_type + '>' |
1158 return_clause = 'return ' + return_type + '(env, ret);' | 1159 return_clause = 'return ' + return_type + '(env, ret);' |
1159 else: | 1160 else: |
1160 return_clause = 'return ret;' | 1161 return_clause = 'return ret;' |
1161 return { | 1162 return { |
1162 'JAVA_CLASS': java_class, | 1163 'JAVA_CLASS': called_by_native.java_class_name or self.class_name, |
1163 'RETURN_TYPE': return_type, | 1164 'RETURN_TYPE': return_type, |
1164 'OPTIONAL_ERROR_RETURN': optional_error_return, | 1165 'OPTIONAL_ERROR_RETURN': optional_error_return, |
1165 'RETURN_DECLARATION': return_declaration, | 1166 'RETURN_DECLARATION': return_declaration, |
1166 'RETURN_CLAUSE': return_clause, | 1167 'RETURN_CLAUSE': return_clause, |
1167 'FIRST_PARAM_IN_DECLARATION': first_param_in_declaration, | 1168 'FIRST_PARAM_IN_DECLARATION': first_param_in_declaration, |
1168 'PARAMS_IN_DECLARATION': params_in_declaration, | 1169 'PARAMS_IN_DECLARATION': params_in_declaration, |
1169 'PRE_CALL': pre_call, | 1170 'PRE_CALL': pre_call, |
1170 'POST_CALL': post_call, | 1171 'POST_CALL': post_call, |
1171 'ENV_CALL': called_by_native.env_call, | 1172 'ENV_CALL': called_by_native.env_call, |
1172 'FIRST_PARAM_IN_CALL': first_param_in_call, | 1173 'FIRST_PARAM_IN_CALL': first_param_in_call, |
(...skipping 23 matching lines...) Expand all Loading... |
1196 function_header_template = Template("""\ | 1197 function_header_template = Template("""\ |
1197 ${FUNCTION_SIGNATURE} {""") | 1198 ${FUNCTION_SIGNATURE} {""") |
1198 function_header_with_unused_template = Template("""\ | 1199 function_header_with_unused_template = Template("""\ |
1199 ${FUNCTION_SIGNATURE} __attribute__ ((unused)); | 1200 ${FUNCTION_SIGNATURE} __attribute__ ((unused)); |
1200 ${FUNCTION_SIGNATURE} {""") | 1201 ${FUNCTION_SIGNATURE} {""") |
1201 template = Template(""" | 1202 template = Template(""" |
1202 static base::subtle::AtomicWord g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = 0; | 1203 static base::subtle::AtomicWord g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = 0; |
1203 ${FUNCTION_HEADER} | 1204 ${FUNCTION_HEADER} |
1204 /* Must call RegisterNativesImpl() */ | 1205 /* Must call RegisterNativesImpl() */ |
1205 CHECK_CLAZZ(env, ${FIRST_PARAM_IN_CALL}, | 1206 CHECK_CLAZZ(env, ${FIRST_PARAM_IN_CALL}, |
1206 ${JAVA_CLASS}_clazz(env)${OPTIONAL_ERROR_RETURN}); | 1207 g_${JAVA_CLASS}_clazz${OPTIONAL_ERROR_RETURN}); |
1207 jmethodID method_id = | 1208 jmethodID method_id = |
1208 ${GET_METHOD_ID_IMPL} | 1209 ${GET_METHOD_ID_IMPL} |
1209 ${RETURN_DECLARATION} | 1210 ${RETURN_DECLARATION} |
1210 ${PRE_CALL}env->${ENV_CALL}(${FIRST_PARAM_IN_CALL}, | 1211 ${PRE_CALL}env->${ENV_CALL}(${FIRST_PARAM_IN_CALL}, |
1211 method_id${PARAMS_IN_CALL})${POST_CALL}; | 1212 method_id${PARAMS_IN_CALL})${POST_CALL}; |
1212 ${CHECK_EXCEPTION} | 1213 ${CHECK_EXCEPTION} |
1213 ${RETURN_CLAUSE} | 1214 ${RETURN_CLAUSE} |
1214 }""") | 1215 }""") |
1215 values = self.GetCalledByNativeValues(called_by_native) | 1216 values = self.GetCalledByNativeValues(called_by_native) |
1216 values['FUNCTION_SIGNATURE'] = ( | 1217 values['FUNCTION_SIGNATURE'] = ( |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1255 all_classes = native_classes | 1256 all_classes = native_classes |
1256 all_classes.update(called_by_native_classes) | 1257 all_classes.update(called_by_native_classes) |
1257 | 1258 |
1258 for clazz in all_classes: | 1259 for clazz in all_classes: |
1259 values = { | 1260 values = { |
1260 'JAVA_CLASS': clazz, | 1261 'JAVA_CLASS': clazz, |
1261 'JNI_CLASS_PATH': JniParams.RemapClassName(all_classes[clazz]), | 1262 'JNI_CLASS_PATH': JniParams.RemapClassName(all_classes[clazz]), |
1262 } | 1263 } |
1263 ret += [template.substitute(values)] | 1264 ret += [template.substitute(values)] |
1264 ret += '' | 1265 ret += '' |
1265 | 1266 for clazz in called_by_native_classes: |
1266 class_getter_methods = [] | |
1267 if self.options.native_exports: | |
1268 template = Template("""\ | 1267 template = Template("""\ |
1269 // Leaking this jclass as we cannot use LazyInstance from some threads. | 1268 // Leaking this jclass as we cannot use LazyInstance from some threads. |
1270 base::subtle::AtomicWord g_${JAVA_CLASS}_clazz = 0; | 1269 jclass g_${JAVA_CLASS}_clazz = NULL;""") |
1271 jclass ${JAVA_CLASS}_clazz(JNIEnv* env) { | |
1272 return base::android::LazyGetClass(env, k${JAVA_CLASS}ClassPath, \ | |
1273 &g_${JAVA_CLASS}_clazz); | |
1274 }""") | |
1275 else: | |
1276 template = Template("""\ | |
1277 // Leaking this jclass as we cannot use LazyInstance from some threads. | |
1278 jclass g_${JAVA_CLASS}_clazz = NULL; | |
1279 jclass ${JAVA_CLASS}_clazz(JNIEnv*) { return g_${JAVA_CLASS}_clazz; }""") | |
1280 | |
1281 for clazz in called_by_native_classes: | |
1282 values = { | 1270 values = { |
1283 'JAVA_CLASS': clazz, | 1271 'JAVA_CLASS': clazz, |
1284 } | 1272 } |
1285 class_getter_methods += [template.substitute(values)] | 1273 ret += [template.substitute(values)] |
1286 | |
1287 template = Template("""\ | |
1288 #if __clang__ | |
1289 #pragma clang diagnostic push | |
1290 #pragma clang diagnostic ignored "-Wunused-function" | |
1291 #endif | |
1292 ${CLASS_GETER_METHODS} | |
1293 #if __clang__ | |
1294 #pragma clang diagnostic pop | |
1295 #endif""") | |
1296 values = { | |
1297 'CLASS_GETER_METHODS': '\n'.join(class_getter_methods) | |
1298 } | |
1299 ret += [template.substitute(values)] | |
1300 return '\n'.join(ret) | 1274 return '\n'.join(ret) |
1301 | 1275 |
1302 def GetFindClasses(self): | 1276 def GetFindClasses(self): |
1303 """Returns the imlementation of FindClass for all known classes.""" | 1277 """Returns the imlementation of FindClass for all known classes.""" |
1304 if self.init_native: | 1278 if self.init_native: |
1305 if self.options.native_exports: | 1279 template = Template("""\ |
1306 template = Template("""\ | |
1307 base::subtle::Release_Store(&g_${JAVA_CLASS}_clazz, | |
1308 static_cast<base::subtle::AtomicWord>(env->NewWeakGlobalRef(clazz));""") | |
1309 else: | |
1310 template = Template("""\ | |
1311 g_${JAVA_CLASS}_clazz = static_cast<jclass>(env->NewWeakGlobalRef(clazz));""") | 1280 g_${JAVA_CLASS}_clazz = static_cast<jclass>(env->NewWeakGlobalRef(clazz));""") |
1312 else: | 1281 else: |
1313 if self.options.native_exports: | |
1314 return '\n' | |
1315 template = Template("""\ | 1282 template = Template("""\ |
1316 g_${JAVA_CLASS}_clazz = reinterpret_cast<jclass>(env->NewGlobalRef( | 1283 g_${JAVA_CLASS}_clazz = reinterpret_cast<jclass>(env->NewGlobalRef( |
1317 base::android::GetClass(env, k${JAVA_CLASS}ClassPath).obj()));""") | 1284 base::android::GetClass(env, k${JAVA_CLASS}ClassPath).obj()));""") |
1318 ret = [] | 1285 ret = [] |
1319 for clazz in self.GetUniqueClasses(self.called_by_natives): | 1286 for clazz in self.GetUniqueClasses(self.called_by_natives): |
1320 values = {'JAVA_CLASS': clazz} | 1287 values = {'JAVA_CLASS': clazz} |
1321 ret += [template.substitute(values)] | 1288 ret += [template.substitute(values)] |
1322 return '\n'.join(ret) | 1289 return '\n'.join(ret) |
1323 | 1290 |
1324 def GetMethodIDImpl(self, called_by_native): | 1291 def GetMethodIDImpl(self, called_by_native): |
1325 """Returns the implementation of GetMethodID.""" | 1292 """Returns the implementation of GetMethodID.""" |
1326 if self.options.eager_called_by_natives: | 1293 if self.options.eager_called_by_natives: |
1327 template = Template("""\ | 1294 template = Template("""\ |
1328 env->Get${STATIC_METHOD_PART}MethodID( | 1295 env->Get${STATIC_METHOD_PART}MethodID( |
1329 ${JAVA_CLASS}_clazz(env), | 1296 g_${JAVA_CLASS}_clazz, |
1330 "${JNI_NAME}", ${JNI_SIGNATURE});""") | 1297 "${JNI_NAME}", ${JNI_SIGNATURE});""") |
1331 else: | 1298 else: |
1332 template = Template("""\ | 1299 template = Template("""\ |
1333 base::android::MethodID::LazyGet< | 1300 base::android::MethodID::LazyGet< |
1334 base::android::MethodID::TYPE_${STATIC}>( | 1301 base::android::MethodID::TYPE_${STATIC}>( |
1335 env, ${JAVA_CLASS}_clazz(env), | 1302 env, g_${JAVA_CLASS}_clazz, |
1336 "${JNI_NAME}", | 1303 "${JNI_NAME}", |
1337 ${JNI_SIGNATURE}, | 1304 ${JNI_SIGNATURE}, |
1338 &g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME}); | 1305 &g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME}); |
1339 """) | 1306 """) |
1340 jni_name = called_by_native.name | 1307 jni_name = called_by_native.name |
1341 jni_return_type = called_by_native.return_type | 1308 jni_return_type = called_by_native.return_type |
1342 if called_by_native.is_constructor: | 1309 if called_by_native.is_constructor: |
1343 jni_name = '<init>' | 1310 jni_name = '<init>' |
1344 jni_return_type = 'void' | 1311 jni_return_type = 'void' |
1345 if called_by_native.signature: | 1312 if called_by_native.signature: |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1532 GenerateJNIHeader(input_file, output_file, options) | 1499 GenerateJNIHeader(input_file, output_file, options) |
1533 | 1500 |
1534 if options.depfile: | 1501 if options.depfile: |
1535 build_utils.WriteDepfile( | 1502 build_utils.WriteDepfile( |
1536 options.depfile, | 1503 options.depfile, |
1537 build_utils.GetPythonDependencies()) | 1504 build_utils.GetPythonDependencies()) |
1538 | 1505 |
1539 | 1506 |
1540 if __name__ == '__main__': | 1507 if __name__ == '__main__': |
1541 sys.exit(main(sys.argv)) | 1508 sys.exit(main(sys.argv)) |
OLD | NEW |