Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: base/android/jni_generator/jni_generator.py

Issue 147533004: Remove unneeded JNI registrations. (Closed) Base URL: https://git.chromium.org/chromium/src.git@master
Patch Set: Fix exports in non-JNI shared libs. Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | base/android/jni_generator/jni_generator_tests.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 775 matching lines...) Expand 10 before | Expand all | Expand 10 after
786 'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name, 786 'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name,
787 } 787 }
788 ret += [template.substitute(values)] 788 ret += [template.substitute(values)]
789 return '\n'.join(ret) 789 return '\n'.join(ret)
790 790
791 def GetForwardDeclarationsString(self): 791 def GetForwardDeclarationsString(self):
792 ret = [] 792 ret = []
793 for native in self.natives: 793 for native in self.natives:
794 if native.type != 'method': 794 if native.type != 'method':
795 ret += [self.GetForwardDeclaration(native)] 795 ret += [self.GetForwardDeclaration(native)]
796 if self.options.native_exports and ret:
797 return '\nextern "C" {\n' + "\n".join(ret) + '\n}; // extern "C"'
796 return '\n'.join(ret) 798 return '\n'.join(ret)
797 799
798 def GetConstantFieldsString(self): 800 def GetConstantFieldsString(self):
799 if not self.constant_fields: 801 if not self.constant_fields:
800 return '' 802 return ''
801 ret = ['enum Java_%s_constant_fields {' % self.class_name] 803 ret = ['enum Java_%s_constant_fields {' % self.class_name]
802 for c in self.constant_fields: 804 for c in self.constant_fields:
803 ret += [' %s = %s,' % (c.name, c.value)] 805 ret += [' %s = %s,' % (c.name, c.value)]
804 ret += ['};'] 806 ret += ['};']
805 return '\n'.join(ret) 807 return '\n'.join(ret)
806 808
807 def GetMethodStubsString(self): 809 def GetMethodStubsString(self):
808 """Returns the code corresponding to method stubs.""" 810 """Returns the code corresponding to method stubs."""
809 ret = [] 811 ret = []
810 for native in self.natives: 812 for native in self.natives:
811 if native.type == 'method': 813 if native.type == 'method':
812 ret += [self.GetNativeMethodStubString(native)] 814 ret += [self.GetNativeMethodStubString(native)]
813 if self.options.eager_called_by_natives: 815 if self.options.eager_called_by_natives:
814 ret += self.GetEagerCalledByNativeMethodStubs() 816 ret += self.GetEagerCalledByNativeMethodStubs()
815 else: 817 else:
816 ret += self.GetLazyCalledByNativeMethodStubs() 818 ret += self.GetLazyCalledByNativeMethodStubs()
819
820 if self.options.native_exports and ret:
821 return '\nextern "C" {\n' + "\n".join(ret) + '\n}; // extern "C"'
817 return '\n'.join(ret) 822 return '\n'.join(ret)
818 823
819 def GetLazyCalledByNativeMethodStubs(self): 824 def GetLazyCalledByNativeMethodStubs(self):
820 return [self.GetLazyCalledByNativeMethodStub(called_by_native) 825 return [self.GetLazyCalledByNativeMethodStub(called_by_native)
821 for called_by_native in self.called_by_natives] 826 for called_by_native in self.called_by_natives]
822 827
823 def GetEagerCalledByNativeMethodStubs(self): 828 def GetEagerCalledByNativeMethodStubs(self):
824 ret = [] 829 ret = []
825 if self.called_by_natives: 830 if self.called_by_natives:
826 ret += ['namespace {'] 831 ret += ['namespace {']
(...skipping 25 matching lines...) Expand all
852 kmethods = self.GetKMethodsString(clazz) 857 kmethods = self.GetKMethodsString(clazz)
853 if kmethods: 858 if kmethods:
854 values = {'JAVA_CLASS': clazz, 859 values = {'JAVA_CLASS': clazz,
855 'KMETHODS': kmethods} 860 'KMETHODS': kmethods}
856 ret += [template.substitute(values)] 861 ret += [template.substitute(values)]
857 if not ret: return '' 862 if not ret: return ''
858 return '\n' + '\n'.join(ret) 863 return '\n' + '\n'.join(ret)
859 864
860 def GetJNINativeMethodsString(self): 865 def GetJNINativeMethodsString(self):
861 """Returns the implementation of the array of native methods.""" 866 """Returns the implementation of the array of native methods."""
867 if self.options.native_exports:
868 return ''
862 template = Template("""\ 869 template = Template("""\
863 static const JNINativeMethod kMethods${JAVA_CLASS}[] = { 870 static const JNINativeMethod kMethods${JAVA_CLASS}[] = {
864 ${KMETHODS} 871 ${KMETHODS}
865 }; 872 };
866 """) 873 """)
867 return self.SubstituteNativeMethods(template) 874 return self.SubstituteNativeMethods(template)
868 875
869 def GetRegisterCalledByNativesImplString(self): 876 def GetRegisterCalledByNativesImplString(self):
870 """Returns the code for registering the called by native methods.""" 877 """Returns the code for registering the called by native methods."""
871 if not self.options.eager_called_by_natives: 878 if not self.options.eager_called_by_natives:
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
906 called_by_natives = self.GetRegisterCalledByNativesImplString() 913 called_by_natives = self.GetRegisterCalledByNativesImplString()
907 values = {'REGISTER_NATIVES_SIGNATURE': signature, 914 values = {'REGISTER_NATIVES_SIGNATURE': signature,
908 'CLASSES': self.GetFindClasses(), 915 'CLASSES': self.GetFindClasses(),
909 'NATIVES': natives, 916 'NATIVES': natives,
910 'CALLED_BY_NATIVES': called_by_natives, 917 'CALLED_BY_NATIVES': called_by_natives,
911 } 918 }
912 return template.substitute(values) 919 return template.substitute(values)
913 920
914 def GetRegisterNativesImplString(self): 921 def GetRegisterNativesImplString(self):
915 """Returns the shared implementation for RegisterNatives.""" 922 """Returns the shared implementation for RegisterNatives."""
923 if self.options.native_exports:
924 return ''
925
916 template = Template("""\ 926 template = Template("""\
917 const int kMethods${JAVA_CLASS}Size = arraysize(kMethods${JAVA_CLASS}); 927 const int kMethods${JAVA_CLASS}Size = arraysize(kMethods${JAVA_CLASS});
918 928
919 if (env->RegisterNatives(g_${JAVA_CLASS}_clazz, 929 if (env->RegisterNatives(g_${JAVA_CLASS}_clazz,
920 kMethods${JAVA_CLASS}, 930 kMethods${JAVA_CLASS},
921 kMethods${JAVA_CLASS}Size) < 0) { 931 kMethods${JAVA_CLASS}Size) < 0) {
922 jni_generator::HandleRegistrationError( 932 jni_generator::HandleRegistrationError(
923 env, g_${JAVA_CLASS}_clazz, __FILE__); 933 env, g_${JAVA_CLASS}_clazz, __FILE__);
924 return false; 934 return false;
925 } 935 }
926 """) 936 """)
927 return self.SubstituteNativeMethods(template) 937 return self.SubstituteNativeMethods(template)
928 938
929 def GetJNIRegisterNativesString(self): 939 def GetJNIRegisterNativesString(self):
930 """Returns the implementation for the JNI registration of native methods.""" 940 """Returns the implementation for the JNI registration of native methods."""
931 if not self.init_native: 941 if not self.init_native:
932 return '' 942 return ''
933 943
934 template = Template("""\ 944 template = Template("""\
935 extern "C" JNIEXPORT bool JNICALL 945 extern "C" JNIEXPORT bool JNICALL
936 Java_${FULLY_QUALIFIED_CLASS}_${INIT_NATIVE_NAME}(JNIEnv* env, jclass clazz) { 946 Java_${FULLY_QUALIFIED_CLASS}_${INIT_NATIVE_NAME}(JNIEnv* env, jclass clazz) {
937 return ${NAMESPACE}RegisterNativesImpl(env, clazz); 947 return ${NAMESPACE}RegisterNativesImpl(env, clazz);
938 } 948 }
939 """) 949 """)
940 fully_qualified_class = self.fully_qualified_class.replace('/', '_') 950
951 if self.options.native_exports:
952 java_name = JniParams.RemapClassName(self.fully_qualified_class)
953 java_name = java_name.replace('_', '_1').replace('/', '_')
954 else:
955 java_name = self.fully_qualified_class.replace('/', '_')
956
941 namespace = '' 957 namespace = ''
942 if self.namespace: 958 if self.namespace:
943 namespace = self.namespace + '::' 959 namespace = self.namespace + '::'
944 values = {'FULLY_QUALIFIED_CLASS': fully_qualified_class, 960 values = {'FULLY_QUALIFIED_CLASS': java_name,
945 'INIT_NATIVE_NAME': 'native' + self.init_native.name, 961 'INIT_NATIVE_NAME': 'native' + self.init_native.name,
946 'NAMESPACE': namespace, 962 'NAMESPACE': namespace,
947 'REGISTER_NATIVES_IMPL': self.GetRegisterNativesImplString() 963 'REGISTER_NATIVES_IMPL': self.GetRegisterNativesImplString()
948 } 964 }
949 return template.substitute(values) 965 return template.substitute(values)
950 966
951 def GetOpenNamespaceString(self): 967 def GetOpenNamespaceString(self):
952 if self.namespace: 968 if self.namespace:
953 all_namespaces = ['namespace %s {' % ns 969 all_namespaces = ['namespace %s {' % ns
954 for ns in self.namespace.split('::')] 970 for ns in self.namespace.split('::')]
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
988 param.name 1004 param.name
989 for param in native.params]) 1005 for param in native.params])
990 1006
991 def GetCalledByNativeParamsInDeclaration(self, called_by_native): 1007 def GetCalledByNativeParamsInDeclaration(self, called_by_native):
992 return ',\n '.join([ 1008 return ',\n '.join([
993 JavaDataTypeToCForCalledByNativeParam(param.datatype) + ' ' + 1009 JavaDataTypeToCForCalledByNativeParam(param.datatype) + ' ' +
994 param.name 1010 param.name
995 for param in called_by_native.params]) 1011 for param in called_by_native.params])
996 1012
997 def GetForwardDeclaration(self, native): 1013 def GetForwardDeclaration(self, native):
998 template = Template(""" 1014 template_str = """
999 static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS}); 1015 static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS});
1000 """) 1016 """
1017 if self.options.native_exports:
1018 template_str += """
1019 __attribute__((visibility("default")))
1020 ${RETURN} Java_${JAVA_NAME}_native${NAME}(JNIEnv* env, ${PARAMS}) {
1021 return ${NAME}(${PARAMS_IN_CALL});
1022 }
1023 """
1024 template = Template(template_str)
1025 params_in_call = []
1026 if not self.options.pure_native_methods:
1027 params_in_call = ['env', 'jcaller']
1028 params_in_call = ', '.join(params_in_call + [p.name for p in native.params])
1029
1030 java_name = JniParams.RemapClassName(self.fully_qualified_class)
1031 java_name = java_name.replace('_', '_1').replace('/', '_')
1032 if native.java_class_name:
1033 java_name += '_00024' + native.java_class_name
1034
1001 values = {'RETURN': JavaDataTypeToC(native.return_type), 1035 values = {'RETURN': JavaDataTypeToC(native.return_type),
1002 'NAME': native.name, 1036 'NAME': native.name,
1003 'PARAMS': self.GetParamsInDeclaration(native)} 1037 'JAVA_NAME': java_name,
1038 'PARAMS': self.GetParamsInDeclaration(native),
1039 'PARAMS_IN_CALL': params_in_call}
1004 return template.substitute(values) 1040 return template.substitute(values)
1005 1041
1006 def GetNativeMethodStubString(self, native): 1042 def GetNativeMethodStubString(self, native):
1007 """Returns stubs for native methods.""" 1043 """Returns stubs for native methods."""
1008 template = Template("""\ 1044 if self.options.native_exports:
1009 static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS_IN_DECLARATION}) { 1045 template_str = """\
1046 __attribute__((visibility("default")))
1047 ${RETURN} Java_${JAVA_NAME}_native${NAME}(JNIEnv* env,
1048 ${PARAMS_IN_DECLARATION}) {"""
1049 else:
1050 template_str = """\
1051 static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS_IN_DECLARATION}) {"""
1052 template_str += """
1010 ${P0_TYPE}* native = reinterpret_cast<${P0_TYPE}*>(${PARAM0_NAME}); 1053 ${P0_TYPE}* native = reinterpret_cast<${P0_TYPE}*>(${PARAM0_NAME});
1011 CHECK_NATIVE_PTR(env, jcaller, native, "${NAME}"${OPTIONAL_ERROR_RETURN}); 1054 CHECK_NATIVE_PTR(env, jcaller, native, "${NAME}"${OPTIONAL_ERROR_RETURN});
1012 return native->${NAME}(${PARAMS_IN_CALL})${POST_CALL}; 1055 return native->${NAME}(${PARAMS_IN_CALL})${POST_CALL};
1013 } 1056 }
1014 """) 1057 """
1058
1059 template = Template(template_str)
1015 params = [] 1060 params = []
1016 if not self.options.pure_native_methods: 1061 if not self.options.pure_native_methods:
1017 params = ['env', 'jcaller'] 1062 params = ['env', 'jcaller']
1018 params_in_call = ', '.join(params + [p.name for p in native.params[1:]]) 1063 params_in_call = ', '.join(params + [p.name for p in native.params[1:]])
1019 1064
1020 return_type = JavaDataTypeToC(native.return_type) 1065 return_type = JavaDataTypeToC(native.return_type)
1021 optional_error_return = JavaReturnValueToC(native.return_type) 1066 optional_error_return = JavaReturnValueToC(native.return_type)
1022 if optional_error_return: 1067 if optional_error_return:
1023 optional_error_return = ', ' + optional_error_return 1068 optional_error_return = ', ' + optional_error_return
1024 post_call = '' 1069 post_call = ''
1025 if re.match(RE_SCOPED_JNI_RETURN_TYPES, return_type): 1070 if re.match(RE_SCOPED_JNI_RETURN_TYPES, return_type):
1026 post_call = '.Release()' 1071 post_call = '.Release()'
1072
1073 if self.options.native_exports:
1074 java_name = JniParams.RemapClassName(self.fully_qualified_class)
1075 java_name = java_name.replace('_', '_1').replace('/', '_')
1076 if native.java_class_name:
1077 java_name += '_00024' + native.java_class_name
1078 else:
1079 java_name = ''
1080
1027 values = { 1081 values = {
1028 'RETURN': return_type, 1082 'RETURN': return_type,
1029 'OPTIONAL_ERROR_RETURN': optional_error_return, 1083 'OPTIONAL_ERROR_RETURN': optional_error_return,
1084 'JAVA_NAME': java_name,
1030 'NAME': native.name, 1085 'NAME': native.name,
1031 'PARAMS_IN_DECLARATION': self.GetParamsInDeclaration(native), 1086 'PARAMS_IN_DECLARATION': self.GetParamsInDeclaration(native),
1032 'PARAM0_NAME': native.params[0].name, 1087 'PARAM0_NAME': native.params[0].name,
1033 'P0_TYPE': native.p0_type, 1088 'P0_TYPE': native.p0_type,
1034 'PARAMS_IN_CALL': params_in_call, 1089 'PARAMS_IN_CALL': params_in_call,
1035 'POST_CALL': post_call 1090 'POST_CALL': post_call
1036 } 1091 }
1037 return template.substitute(values) 1092 return template.substitute(values)
1038 1093
1039 def GetArgument(self, param): 1094 def GetArgument(self, param):
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
1167 ret[class_name] = jni_class_path 1222 ret[class_name] = jni_class_path
1168 return ret 1223 return ret
1169 1224
1170 def GetClassPathDefinitions(self): 1225 def GetClassPathDefinitions(self):
1171 """Returns the ClassPath constants.""" 1226 """Returns the ClassPath constants."""
1172 ret = [] 1227 ret = []
1173 template = Template("""\ 1228 template = Template("""\
1174 const char k${JAVA_CLASS}ClassPath[] = "${JNI_CLASS_PATH}";""") 1229 const char k${JAVA_CLASS}ClassPath[] = "${JNI_CLASS_PATH}";""")
1175 native_classes = self.GetUniqueClasses(self.natives) 1230 native_classes = self.GetUniqueClasses(self.natives)
1176 called_by_native_classes = self.GetUniqueClasses(self.called_by_natives) 1231 called_by_native_classes = self.GetUniqueClasses(self.called_by_natives)
1177 all_classes = native_classes 1232 if self.options.native_exports:
1178 all_classes.update(called_by_native_classes) 1233 all_classes = called_by_native_classes
1234 else:
1235 all_classes = native_classes
1236 all_classes.update(called_by_native_classes)
1237
1179 for clazz in all_classes: 1238 for clazz in all_classes:
1180 values = { 1239 values = {
1181 'JAVA_CLASS': clazz, 1240 'JAVA_CLASS': clazz,
1182 'JNI_CLASS_PATH': JniParams.RemapClassName(all_classes[clazz]), 1241 'JNI_CLASS_PATH': JniParams.RemapClassName(all_classes[clazz]),
1183 } 1242 }
1184 ret += [template.substitute(values)] 1243 ret += [template.substitute(values)]
1185 ret += '' 1244 ret += ''
1186 for clazz in called_by_native_classes: 1245 for clazz in called_by_native_classes:
1187 template = Template("""\ 1246 template = Template("""\
1188 // Leaking this jclass as we cannot use LazyInstance from some threads. 1247 // Leaking this jclass as we cannot use LazyInstance from some threads.
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
1387 'will limit the initialization to only the ' 1446 'will limit the initialization to only the '
1388 'top-level class.') 1447 'top-level class.')
1389 option_parser.add_option('--eager_called_by_natives', 1448 option_parser.add_option('--eager_called_by_natives',
1390 action='store_true', dest='eager_called_by_natives', 1449 action='store_true', dest='eager_called_by_natives',
1391 help='When true, the called-by-native methods will ' 1450 help='When true, the called-by-native methods will '
1392 'be initialized in a non-atomic way.') 1451 'be initialized in a non-atomic way.')
1393 option_parser.add_option('--cpp', default='cpp', 1452 option_parser.add_option('--cpp', default='cpp',
1394 help='The path to cpp command.') 1453 help='The path to cpp command.')
1395 option_parser.add_option('--javap', default='javap', 1454 option_parser.add_option('--javap', default='javap',
1396 help='The path to javap command.') 1455 help='The path to javap command.')
1456 option_parser.add_option('--native_exports', action='store_true',
1457 help='Native method registration through .so '
1458 'exports.')
1397 options, args = option_parser.parse_args(argv) 1459 options, args = option_parser.parse_args(argv)
1398 if options.jar_file: 1460 if options.jar_file:
1399 input_file = ExtractJarInputFile(options.jar_file, options.input_file, 1461 input_file = ExtractJarInputFile(options.jar_file, options.input_file,
1400 options.output_dir) 1462 options.output_dir)
1401 elif options.input_file: 1463 elif options.input_file:
1402 input_file = options.input_file 1464 input_file = options.input_file
1403 else: 1465 else:
1404 option_parser.print_help() 1466 option_parser.print_help()
1405 print '\nError: Must specify --jar_file or --input_file.' 1467 print '\nError: Must specify --jar_file or --input_file.'
1406 return 1 1468 return 1
1407 output_file = None 1469 output_file = None
1408 if options.output_dir: 1470 if options.output_dir:
1409 root_name = os.path.splitext(os.path.basename(input_file))[0] 1471 root_name = os.path.splitext(os.path.basename(input_file))[0]
1410 output_file = os.path.join(options.output_dir, root_name) + '_jni.h' 1472 output_file = os.path.join(options.output_dir, root_name) + '_jni.h'
1411 if options.jarjar: 1473 if options.jarjar:
1412 with open(options.jarjar) as f: 1474 with open(options.jarjar) as f:
1413 JniParams.SetJarJarMappings(f.read()) 1475 JniParams.SetJarJarMappings(f.read())
1414 GenerateJNIHeader(input_file, output_file, options) 1476 GenerateJNIHeader(input_file, output_file, options)
1415 1477
1416 1478
1417 if __name__ == '__main__': 1479 if __name__ == '__main__':
1418 sys.exit(main(sys.argv)) 1480 sys.exit(main(sys.argv))
OLDNEW
« no previous file with comments | « no previous file | base/android/jni_generator/jni_generator_tests.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698