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 (c) 2012 The Chromium Authors. All rights reserved. | 734 // Copyright 2014 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(g_${JAVA_CLASS}_clazz, | 950 if (env->RegisterNatives(${JAVA_CLASS}_clazz(env), |
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, g_${JAVA_CLASS}_clazz, __FILE__); | 954 env, ${JAVA_CLASS}_clazz(env), __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 |
1125 if called_by_native.static or called_by_native.is_constructor: | 1126 if called_by_native.static or called_by_native.is_constructor: |
1126 first_param_in_declaration = '' | 1127 first_param_in_declaration = '' |
1127 first_param_in_call = ('g_%s_clazz' % | 1128 first_param_in_call = ('%s_clazz(env)' % java_class) |
1128 (called_by_native.java_class_name or | |
1129 self.class_name)) | |
1130 else: | 1129 else: |
1131 first_param_in_declaration = ', jobject obj' | 1130 first_param_in_declaration = ', jobject obj' |
1132 first_param_in_call = 'obj' | 1131 first_param_in_call = 'obj' |
1133 params_in_declaration = self.GetCalledByNativeParamsInDeclaration( | 1132 params_in_declaration = self.GetCalledByNativeParamsInDeclaration( |
1134 called_by_native) | 1133 called_by_native) |
1135 if params_in_declaration: | 1134 if params_in_declaration: |
1136 params_in_declaration = ', ' + params_in_declaration | 1135 params_in_declaration = ', ' + params_in_declaration |
1137 params_in_call = ', '.join(self.GetArgumentsInCall(called_by_native.params)) | 1136 params_in_call = ', '.join(self.GetArgumentsInCall(called_by_native.params)) |
1138 if params_in_call: | 1137 if params_in_call: |
1139 params_in_call = ', ' + params_in_call | 1138 params_in_call = ', ' + params_in_call |
(...skipping 13 matching lines...) Expand all Loading... |
1153 return_clause = '' | 1152 return_clause = '' |
1154 if return_type != 'void': | 1153 if return_type != 'void': |
1155 pre_call = ' ' + pre_call | 1154 pre_call = ' ' + pre_call |
1156 return_declaration = return_type + ' ret =' | 1155 return_declaration = return_type + ' ret =' |
1157 if re.match(RE_SCOPED_JNI_RETURN_TYPES, return_type): | 1156 if re.match(RE_SCOPED_JNI_RETURN_TYPES, return_type): |
1158 return_type = 'base::android::ScopedJavaLocalRef<' + return_type + '>' | 1157 return_type = 'base::android::ScopedJavaLocalRef<' + return_type + '>' |
1159 return_clause = 'return ' + return_type + '(env, ret);' | 1158 return_clause = 'return ' + return_type + '(env, ret);' |
1160 else: | 1159 else: |
1161 return_clause = 'return ret;' | 1160 return_clause = 'return ret;' |
1162 return { | 1161 return { |
1163 'JAVA_CLASS': called_by_native.java_class_name or self.class_name, | 1162 'JAVA_CLASS': java_class, |
1164 'RETURN_TYPE': return_type, | 1163 'RETURN_TYPE': return_type, |
1165 'OPTIONAL_ERROR_RETURN': optional_error_return, | 1164 'OPTIONAL_ERROR_RETURN': optional_error_return, |
1166 'RETURN_DECLARATION': return_declaration, | 1165 'RETURN_DECLARATION': return_declaration, |
1167 'RETURN_CLAUSE': return_clause, | 1166 'RETURN_CLAUSE': return_clause, |
1168 'FIRST_PARAM_IN_DECLARATION': first_param_in_declaration, | 1167 'FIRST_PARAM_IN_DECLARATION': first_param_in_declaration, |
1169 'PARAMS_IN_DECLARATION': params_in_declaration, | 1168 'PARAMS_IN_DECLARATION': params_in_declaration, |
1170 'PRE_CALL': pre_call, | 1169 'PRE_CALL': pre_call, |
1171 'POST_CALL': post_call, | 1170 'POST_CALL': post_call, |
1172 'ENV_CALL': called_by_native.env_call, | 1171 'ENV_CALL': called_by_native.env_call, |
1173 'FIRST_PARAM_IN_CALL': first_param_in_call, | 1172 'FIRST_PARAM_IN_CALL': first_param_in_call, |
(...skipping 23 matching lines...) Expand all Loading... |
1197 function_header_template = Template("""\ | 1196 function_header_template = Template("""\ |
1198 ${FUNCTION_SIGNATURE} {""") | 1197 ${FUNCTION_SIGNATURE} {""") |
1199 function_header_with_unused_template = Template("""\ | 1198 function_header_with_unused_template = Template("""\ |
1200 ${FUNCTION_SIGNATURE} __attribute__ ((unused)); | 1199 ${FUNCTION_SIGNATURE} __attribute__ ((unused)); |
1201 ${FUNCTION_SIGNATURE} {""") | 1200 ${FUNCTION_SIGNATURE} {""") |
1202 template = Template(""" | 1201 template = Template(""" |
1203 static base::subtle::AtomicWord g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = 0; | 1202 static base::subtle::AtomicWord g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = 0; |
1204 ${FUNCTION_HEADER} | 1203 ${FUNCTION_HEADER} |
1205 /* Must call RegisterNativesImpl() */ | 1204 /* Must call RegisterNativesImpl() */ |
1206 CHECK_CLAZZ(env, ${FIRST_PARAM_IN_CALL}, | 1205 CHECK_CLAZZ(env, ${FIRST_PARAM_IN_CALL}, |
1207 g_${JAVA_CLASS}_clazz${OPTIONAL_ERROR_RETURN}); | 1206 ${JAVA_CLASS}_clazz(env)${OPTIONAL_ERROR_RETURN}); |
1208 jmethodID method_id = | 1207 jmethodID method_id = |
1209 ${GET_METHOD_ID_IMPL} | 1208 ${GET_METHOD_ID_IMPL} |
1210 ${RETURN_DECLARATION} | 1209 ${RETURN_DECLARATION} |
1211 ${PRE_CALL}env->${ENV_CALL}(${FIRST_PARAM_IN_CALL}, | 1210 ${PRE_CALL}env->${ENV_CALL}(${FIRST_PARAM_IN_CALL}, |
1212 method_id${PARAMS_IN_CALL})${POST_CALL}; | 1211 method_id${PARAMS_IN_CALL})${POST_CALL}; |
1213 ${CHECK_EXCEPTION} | 1212 ${CHECK_EXCEPTION} |
1214 ${RETURN_CLAUSE} | 1213 ${RETURN_CLAUSE} |
1215 }""") | 1214 }""") |
1216 values = self.GetCalledByNativeValues(called_by_native) | 1215 values = self.GetCalledByNativeValues(called_by_native) |
1217 values['FUNCTION_SIGNATURE'] = ( | 1216 values['FUNCTION_SIGNATURE'] = ( |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1256 all_classes = native_classes | 1255 all_classes = native_classes |
1257 all_classes.update(called_by_native_classes) | 1256 all_classes.update(called_by_native_classes) |
1258 | 1257 |
1259 for clazz in all_classes: | 1258 for clazz in all_classes: |
1260 values = { | 1259 values = { |
1261 'JAVA_CLASS': clazz, | 1260 'JAVA_CLASS': clazz, |
1262 'JNI_CLASS_PATH': JniParams.RemapClassName(all_classes[clazz]), | 1261 'JNI_CLASS_PATH': JniParams.RemapClassName(all_classes[clazz]), |
1263 } | 1262 } |
1264 ret += [template.substitute(values)] | 1263 ret += [template.substitute(values)] |
1265 ret += '' | 1264 ret += '' |
1266 for clazz in called_by_native_classes: | 1265 |
| 1266 class_getter_methods = [] |
| 1267 if self.options.native_exports: |
1267 template = Template("""\ | 1268 template = Template("""\ |
1268 // Leaking this jclass as we cannot use LazyInstance from some threads. | 1269 // Leaking this jclass as we cannot use LazyInstance from some threads. |
1269 jclass g_${JAVA_CLASS}_clazz = NULL;""") | 1270 base::subtle::AtomicWord g_${JAVA_CLASS}_clazz = 0; |
| 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: |
1270 values = { | 1282 values = { |
1271 'JAVA_CLASS': clazz, | 1283 'JAVA_CLASS': clazz, |
1272 } | 1284 } |
1273 ret += [template.substitute(values)] | 1285 class_getter_methods += [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)] |
1274 return '\n'.join(ret) | 1300 return '\n'.join(ret) |
1275 | 1301 |
1276 def GetFindClasses(self): | 1302 def GetFindClasses(self): |
1277 """Returns the imlementation of FindClass for all known classes.""" | 1303 """Returns the imlementation of FindClass for all known classes.""" |
1278 if self.init_native: | 1304 if self.init_native: |
1279 template = Template("""\ | 1305 if self.options.native_exports: |
| 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("""\ |
1280 g_${JAVA_CLASS}_clazz = static_cast<jclass>(env->NewWeakGlobalRef(clazz));""") | 1311 g_${JAVA_CLASS}_clazz = static_cast<jclass>(env->NewWeakGlobalRef(clazz));""") |
1281 else: | 1312 else: |
| 1313 if self.options.native_exports: |
| 1314 return '\n' |
1282 template = Template("""\ | 1315 template = Template("""\ |
1283 g_${JAVA_CLASS}_clazz = reinterpret_cast<jclass>(env->NewGlobalRef( | 1316 g_${JAVA_CLASS}_clazz = reinterpret_cast<jclass>(env->NewGlobalRef( |
1284 base::android::GetClass(env, k${JAVA_CLASS}ClassPath).obj()));""") | 1317 base::android::GetClass(env, k${JAVA_CLASS}ClassPath).obj()));""") |
1285 ret = [] | 1318 ret = [] |
1286 for clazz in self.GetUniqueClasses(self.called_by_natives): | 1319 for clazz in self.GetUniqueClasses(self.called_by_natives): |
1287 values = {'JAVA_CLASS': clazz} | 1320 values = {'JAVA_CLASS': clazz} |
1288 ret += [template.substitute(values)] | 1321 ret += [template.substitute(values)] |
1289 return '\n'.join(ret) | 1322 return '\n'.join(ret) |
1290 | 1323 |
1291 def GetMethodIDImpl(self, called_by_native): | 1324 def GetMethodIDImpl(self, called_by_native): |
1292 """Returns the implementation of GetMethodID.""" | 1325 """Returns the implementation of GetMethodID.""" |
1293 if self.options.eager_called_by_natives: | 1326 if self.options.eager_called_by_natives: |
1294 template = Template("""\ | 1327 template = Template("""\ |
1295 env->Get${STATIC_METHOD_PART}MethodID( | 1328 env->Get${STATIC_METHOD_PART}MethodID( |
1296 g_${JAVA_CLASS}_clazz, | 1329 ${JAVA_CLASS}_clazz(env), |
1297 "${JNI_NAME}", ${JNI_SIGNATURE});""") | 1330 "${JNI_NAME}", ${JNI_SIGNATURE});""") |
1298 else: | 1331 else: |
1299 template = Template("""\ | 1332 template = Template("""\ |
1300 base::android::MethodID::LazyGet< | 1333 base::android::MethodID::LazyGet< |
1301 base::android::MethodID::TYPE_${STATIC}>( | 1334 base::android::MethodID::TYPE_${STATIC}>( |
1302 env, g_${JAVA_CLASS}_clazz, | 1335 env, ${JAVA_CLASS}_clazz(env), |
1303 "${JNI_NAME}", | 1336 "${JNI_NAME}", |
1304 ${JNI_SIGNATURE}, | 1337 ${JNI_SIGNATURE}, |
1305 &g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME}); | 1338 &g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME}); |
1306 """) | 1339 """) |
1307 jni_name = called_by_native.name | 1340 jni_name = called_by_native.name |
1308 jni_return_type = called_by_native.return_type | 1341 jni_return_type = called_by_native.return_type |
1309 if called_by_native.is_constructor: | 1342 if called_by_native.is_constructor: |
1310 jni_name = '<init>' | 1343 jni_name = '<init>' |
1311 jni_return_type = 'void' | 1344 jni_return_type = 'void' |
1312 if called_by_native.signature: | 1345 if called_by_native.signature: |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1499 GenerateJNIHeader(input_file, output_file, options) | 1532 GenerateJNIHeader(input_file, output_file, options) |
1500 | 1533 |
1501 if options.depfile: | 1534 if options.depfile: |
1502 build_utils.WriteDepfile( | 1535 build_utils.WriteDepfile( |
1503 options.depfile, | 1536 options.depfile, |
1504 build_utils.GetPythonDependencies()) | 1537 build_utils.GetPythonDependencies()) |
1505 | 1538 |
1506 | 1539 |
1507 if __name__ == '__main__': | 1540 if __name__ == '__main__': |
1508 sys.exit(main(sys.argv)) | 1541 sys.exit(main(sys.argv)) |
OLD | NEW |