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

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: Rebaes, added native_exports switch, don't remove empty RegisterNatives. Created 6 years, 8 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
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 712 matching lines...) Expand 10 before | Expand all | Expand 10 after
723 'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name, 723 'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name,
724 } 724 }
725 ret += [template.substitute(values)] 725 ret += [template.substitute(values)]
726 return '\n'.join(ret) 726 return '\n'.join(ret)
727 727
728 def GetForwardDeclarationsString(self): 728 def GetForwardDeclarationsString(self):
729 ret = [] 729 ret = []
730 for native in self.natives: 730 for native in self.natives:
731 if native.type != 'method': 731 if native.type != 'method':
732 ret += [self.GetForwardDeclaration(native)] 732 ret += [self.GetForwardDeclaration(native)]
733 if self.options.native_exports and ret != []:
734 return '\nextern "C" {\n' + "\n".join(ret) + "\n};"
bulach 2014/04/14 13:16:02 nit: use '\n' instead of "\n" in the second string
ostap 2014/04/15 23:30:20 Done.
733 return '\n'.join(ret) 735 return '\n'.join(ret)
734 736
735 def GetConstantFieldsString(self): 737 def GetConstantFieldsString(self):
736 if not self.constant_fields: 738 if not self.constant_fields:
737 return '' 739 return ''
738 ret = ['enum Java_%s_constant_fields {' % self.class_name] 740 ret = ['enum Java_%s_constant_fields {' % self.class_name]
739 for c in self.constant_fields: 741 for c in self.constant_fields:
740 ret += [' %s = %s,' % (c.name, c.value)] 742 ret += [' %s = %s,' % (c.name, c.value)]
741 ret += ['};'] 743 ret += ['};']
742 return '\n'.join(ret) 744 return '\n'.join(ret)
743 745
744 def GetMethodStubsString(self): 746 def GetMethodStubsString(self):
745 """Returns the code corresponding to method stubs.""" 747 """Returns the code corresponding to method stubs."""
746 ret = [] 748 ret = []
747 for native in self.natives: 749 for native in self.natives:
748 if native.type == 'method': 750 if native.type == 'method':
749 ret += [self.GetNativeMethodStubString(native)] 751 ret += [self.GetNativeMethodStubString(native)]
750 if self.options.eager_called_by_natives: 752 if self.options.eager_called_by_natives:
751 ret += self.GetEagerCalledByNativeMethodStubs() 753 ret += self.GetEagerCalledByNativeMethodStubs()
752 else: 754 else:
753 ret += self.GetLazyCalledByNativeMethodStubs() 755 ret += self.GetLazyCalledByNativeMethodStubs()
756
757 if self.options.native_exports and ret != []:
758 return '\nextern "C" {\n' + "\n".join(ret) + "\n};"
754 return '\n'.join(ret) 759 return '\n'.join(ret)
755 760
756 def GetLazyCalledByNativeMethodStubs(self): 761 def GetLazyCalledByNativeMethodStubs(self):
757 return [self.GetLazyCalledByNativeMethodStub(called_by_native) 762 return [self.GetLazyCalledByNativeMethodStub(called_by_native)
758 for called_by_native in self.called_by_natives] 763 for called_by_native in self.called_by_natives]
759 764
760 def GetEagerCalledByNativeMethodStubs(self): 765 def GetEagerCalledByNativeMethodStubs(self):
761 ret = [] 766 ret = []
762 if self.called_by_natives: 767 if self.called_by_natives:
763 ret += ['namespace {'] 768 ret += ['namespace {']
(...skipping 25 matching lines...) Expand all
789 kmethods = self.GetKMethodsString(clazz) 794 kmethods = self.GetKMethodsString(clazz)
790 if kmethods: 795 if kmethods:
791 values = {'JAVA_CLASS': clazz, 796 values = {'JAVA_CLASS': clazz,
792 'KMETHODS': kmethods} 797 'KMETHODS': kmethods}
793 ret += [template.substitute(values)] 798 ret += [template.substitute(values)]
794 if not ret: return '' 799 if not ret: return ''
795 return '\n' + '\n'.join(ret) 800 return '\n' + '\n'.join(ret)
796 801
797 def GetJNINativeMethodsString(self): 802 def GetJNINativeMethodsString(self):
798 """Returns the implementation of the array of native methods.""" 803 """Returns the implementation of the array of native methods."""
804 if self.options.native_exports:
805 return ''
799 template = Template("""\ 806 template = Template("""\
800 static const JNINativeMethod kMethods${JAVA_CLASS}[] = { 807 static const JNINativeMethod kMethods${JAVA_CLASS}[] = {
801 ${KMETHODS} 808 ${KMETHODS}
802 }; 809 };
803 """) 810 """)
804 return self.SubstituteNativeMethods(template) 811 return self.SubstituteNativeMethods(template)
805 812
806 def GetRegisterCalledByNativesImplString(self): 813 def GetRegisterCalledByNativesImplString(self):
807 """Returns the code for registering the called by native methods.""" 814 """Returns the code for registering the called by native methods."""
808 if not self.options.eager_called_by_natives: 815 if not self.options.eager_called_by_natives:
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
843 called_by_natives = self.GetRegisterCalledByNativesImplString() 850 called_by_natives = self.GetRegisterCalledByNativesImplString()
844 values = {'REGISTER_NATIVES_SIGNATURE': signature, 851 values = {'REGISTER_NATIVES_SIGNATURE': signature,
845 'CLASSES': self.GetFindClasses(), 852 'CLASSES': self.GetFindClasses(),
846 'NATIVES': natives, 853 'NATIVES': natives,
847 'CALLED_BY_NATIVES': called_by_natives, 854 'CALLED_BY_NATIVES': called_by_natives,
848 } 855 }
849 return template.substitute(values) 856 return template.substitute(values)
850 857
851 def GetRegisterNativesImplString(self): 858 def GetRegisterNativesImplString(self):
852 """Returns the shared implementation for RegisterNatives.""" 859 """Returns the shared implementation for RegisterNatives."""
860 if self.options.native_exports:
861 return ''
862
853 template = Template("""\ 863 template = Template("""\
854 const int kMethods${JAVA_CLASS}Size = arraysize(kMethods${JAVA_CLASS}); 864 const int kMethods${JAVA_CLASS}Size = arraysize(kMethods${JAVA_CLASS});
855 865
856 if (env->RegisterNatives(g_${JAVA_CLASS}_clazz, 866 if (env->RegisterNatives(g_${JAVA_CLASS}_clazz,
857 kMethods${JAVA_CLASS}, 867 kMethods${JAVA_CLASS},
858 kMethods${JAVA_CLASS}Size) < 0) { 868 kMethods${JAVA_CLASS}Size) < 0) {
859 jni_generator::HandleRegistrationError( 869 jni_generator::HandleRegistrationError(
860 env, g_${JAVA_CLASS}_clazz, __FILE__); 870 env, g_${JAVA_CLASS}_clazz, __FILE__);
861 return false; 871 return false;
862 } 872 }
863 """) 873 """)
864 return self.SubstituteNativeMethods(template) 874 return self.SubstituteNativeMethods(template)
865 875
866 def GetJNIRegisterNativesString(self): 876 def GetJNIRegisterNativesString(self):
867 """Returns the implementation for the JNI registration of native methods.""" 877 """Returns the implementation for the JNI registration of native methods."""
868 if not self.init_native: 878 if self.options.native_exports or not self.init_native:
869 return '' 879 return ''
870 880
871 template = Template("""\ 881 template = Template("""\
872 extern "C" JNIEXPORT bool JNICALL 882 extern "C" JNIEXPORT bool JNICALL
873 Java_${FULLY_QUALIFIED_CLASS}_${INIT_NATIVE_NAME}(JNIEnv* env, jclass clazz) { 883 Java_${FULLY_QUALIFIED_CLASS}_${INIT_NATIVE_NAME}(JNIEnv* env, jclass clazz) {
874 return ${NAMESPACE}RegisterNativesImpl(env, clazz); 884 return ${NAMESPACE}RegisterNativesImpl(env, clazz);
875 } 885 }
876 """) 886 """)
877 fully_qualified_class = self.fully_qualified_class.replace('/', '_') 887 fully_qualified_class = self.fully_qualified_class.replace('/', '_')
878 namespace = '' 888 namespace = ''
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
924 [JavaDataTypeToC(param.datatype) + ' ' + 934 [JavaDataTypeToC(param.datatype) + ' ' +
925 param.name 935 param.name
926 for param in native.params]) 936 for param in native.params])
927 937
928 def GetCalledByNativeParamsInDeclaration(self, called_by_native): 938 def GetCalledByNativeParamsInDeclaration(self, called_by_native):
929 return ',\n '.join([JavaDataTypeToC(param.datatype) + ' ' + 939 return ',\n '.join([JavaDataTypeToC(param.datatype) + ' ' +
930 param.name 940 param.name
931 for param in called_by_native.params]) 941 for param in called_by_native.params])
932 942
933 def GetForwardDeclaration(self, native): 943 def GetForwardDeclaration(self, native):
934 template = Template(""" 944 template_str = """
935 static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS}); 945 static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS});
936 """) 946 """
947 if self.options.native_exports:
948 template_str += """
949 __attribute__((alias("${NAME}"), visibility("default"))) ${RETURN}
bulach 2014/04/14 13:16:02 nit: move the ${RETURN} to the next line and put i
ostap 2014/04/15 23:30:20 Done.
950 Java_${JAVA_NAME}_native${NAME}(JNIEnv* env, ${PARAMS});
951 """
952 template = Template(template_str)
953
954 java_name = JniParams.RemapClassName(self.fully_qualified_class).replace('_' , '_1').replace('/', '_')
bulach 2014/04/14 13:16:02 nit: >80cols, suggest: java_name = java_name = Jni
ostap 2014/04/15 23:30:20 Done.
955 if native.java_class_name:
956 java_name += "_00024" + native.java_class_name
bulach 2014/04/14 13:16:02 nit: s/"/'/
ostap 2014/04/15 23:30:20 Done.
957
937 values = {'RETURN': JavaDataTypeToC(native.return_type), 958 values = {'RETURN': JavaDataTypeToC(native.return_type),
938 'NAME': native.name, 959 'NAME': native.name,
960 'JAVA_NAME': java_name,
939 'PARAMS': self.GetParamsInDeclaration(native)} 961 'PARAMS': self.GetParamsInDeclaration(native)}
940 return template.substitute(values) 962 return template.substitute(values)
941 963
942 def GetNativeMethodStubString(self, native): 964 def GetNativeMethodStubString(self, native):
943 """Returns stubs for native methods.""" 965 """Returns stubs for native methods."""
944 template = Template("""\ 966 template_str = """\
945 static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS_IN_DECLARATION}) { 967 static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS_IN_DECLARATION}) {
946 ${P0_TYPE}* native = reinterpret_cast<${P0_TYPE}*>(${PARAM0_NAME}); 968 ${P0_TYPE}* native = reinterpret_cast<${P0_TYPE}*>(${PARAM0_NAME});
947 CHECK_NATIVE_PTR(env, jcaller, native, "${NAME}"${OPTIONAL_ERROR_RETURN}); 969 CHECK_NATIVE_PTR(env, jcaller, native, "${NAME}"${OPTIONAL_ERROR_RETURN});
948 return native->${NAME}(${PARAMS_IN_CALL})${POST_CALL}; 970 return native->${NAME}(${PARAMS_IN_CALL})${POST_CALL};
949 } 971 }
950 """) 972 """
973 if self.options.native_exports:
974 template_str += """
975 __attribute__((alias("${NAME}"), visibility("default")))
976 ${RETURN} Java_${JAVA_NAME}_native${NAME}(JNIEnv* env,
bulach 2014/04/14 13:16:02 nit: unindent this line
ostap 2014/04/15 23:30:20 Done.
977 ${PARAMS_IN_DECLARATION});
978 """
979 template = Template(template_str)
951 params = [] 980 params = []
952 if not self.options.pure_native_methods: 981 if not self.options.pure_native_methods:
953 params = ['env', 'jcaller'] 982 params = ['env', 'jcaller']
954 params_in_call = ', '.join(params + [p.name for p in native.params[1:]]) 983 params_in_call = ', '.join(params + [p.name for p in native.params[1:]])
955 984
956 return_type = JavaDataTypeToC(native.return_type) 985 return_type = JavaDataTypeToC(native.return_type)
957 optional_error_return = JavaReturnValueToC(native.return_type) 986 optional_error_return = JavaReturnValueToC(native.return_type)
958 if optional_error_return: 987 if optional_error_return:
959 optional_error_return = ', ' + optional_error_return 988 optional_error_return = ', ' + optional_error_return
960 post_call = '' 989 post_call = ''
961 if re.match(RE_SCOPED_JNI_RETURN_TYPES, return_type): 990 if re.match(RE_SCOPED_JNI_RETURN_TYPES, return_type):
962 post_call = '.Release()' 991 post_call = '.Release()'
992
993 if self.options.native_exports:
994 java_name = JniParams.RemapClassName(self.fully_qualified_class).replace(' _', '_1').replace('/', '_')
bulach 2014/04/14 13:16:02 nit: as above, >80 cols
ostap 2014/04/15 23:30:20 Done.
995 if native.java_class_name:
996 java_name += "_00024" + native.java_class_name
bulach 2014/04/14 13:16:02 nit: s/"/'/ and below in 998
ostap 2014/04/15 23:30:20 Done.
997 else:
998 java_name = ""
999
963 values = { 1000 values = {
964 'RETURN': return_type, 1001 'RETURN': return_type,
965 'OPTIONAL_ERROR_RETURN': optional_error_return, 1002 'OPTIONAL_ERROR_RETURN': optional_error_return,
1003 'JAVA_NAME': java_name,
966 'NAME': native.name, 1004 'NAME': native.name,
967 'PARAMS_IN_DECLARATION': self.GetParamsInDeclaration(native), 1005 'PARAMS_IN_DECLARATION': self.GetParamsInDeclaration(native),
968 'PARAM0_NAME': native.params[0].name, 1006 'PARAM0_NAME': native.params[0].name,
969 'P0_TYPE': native.p0_type, 1007 'P0_TYPE': native.p0_type,
970 'PARAMS_IN_CALL': params_in_call, 1008 'PARAMS_IN_CALL': params_in_call,
971 'POST_CALL': post_call 1009 'POST_CALL': post_call
972 } 1010 }
973 return template.substitute(values) 1011 return template.substitute(values)
974 1012
975 def GetCalledByNativeValues(self, called_by_native): 1013 def GetCalledByNativeValues(self, called_by_native):
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1095 ret[class_name] = jni_class_path 1133 ret[class_name] = jni_class_path
1096 return ret 1134 return ret
1097 1135
1098 def GetClassPathDefinitions(self): 1136 def GetClassPathDefinitions(self):
1099 """Returns the ClassPath constants.""" 1137 """Returns the ClassPath constants."""
1100 ret = [] 1138 ret = []
1101 template = Template("""\ 1139 template = Template("""\
1102 const char k${JAVA_CLASS}ClassPath[] = "${JNI_CLASS_PATH}";""") 1140 const char k${JAVA_CLASS}ClassPath[] = "${JNI_CLASS_PATH}";""")
1103 native_classes = self.GetUniqueClasses(self.natives) 1141 native_classes = self.GetUniqueClasses(self.natives)
1104 called_by_native_classes = self.GetUniqueClasses(self.called_by_natives) 1142 called_by_native_classes = self.GetUniqueClasses(self.called_by_natives)
1105 all_classes = native_classes 1143 if self.options.native_exports:
1106 all_classes.update(called_by_native_classes) 1144 all_classes = called_by_native_classes
1145 loop_classes = all_classes
1146 else:
1147 all_classes = native_classes
1148 all_classes.update(called_by_native_classes)
1149 loop_classes = called_by_native_classes
1150
1107 for clazz in all_classes: 1151 for clazz in all_classes:
1108 values = { 1152 values = {
1109 'JAVA_CLASS': clazz, 1153 'JAVA_CLASS': clazz,
1110 'JNI_CLASS_PATH': JniParams.RemapClassName(all_classes[clazz]), 1154 'JNI_CLASS_PATH': JniParams.RemapClassName(all_classes[clazz]),
1111 } 1155 }
1112 ret += [template.substitute(values)] 1156 ret += [template.substitute(values)]
1113 ret += '' 1157 ret += ''
1114 for clazz in called_by_native_classes: 1158 for clazz in loop_classes:
1115 template = Template("""\ 1159 template = Template("""\
1116 // Leaking this jclass as we cannot use LazyInstance from some threads. 1160 // Leaking this jclass as we cannot use LazyInstance from some threads.
1117 jclass g_${JAVA_CLASS}_clazz = NULL;""") 1161 jclass g_${JAVA_CLASS}_clazz = NULL;""")
1118 values = { 1162 values = {
1119 'JAVA_CLASS': clazz, 1163 'JAVA_CLASS': clazz,
1120 } 1164 }
1121 ret += [template.substitute(values)] 1165 ret += [template.substitute(values)]
1122 return '\n'.join(ret) 1166 return '\n'.join(ret)
1123 1167
1124 def GetFindClasses(self): 1168 def GetFindClasses(self):
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
1315 'will limit the initialization to only the ' 1359 'will limit the initialization to only the '
1316 'top-level class.') 1360 'top-level class.')
1317 option_parser.add_option('--eager_called_by_natives', 1361 option_parser.add_option('--eager_called_by_natives',
1318 action='store_true', dest='eager_called_by_natives', 1362 action='store_true', dest='eager_called_by_natives',
1319 help='When true, the called-by-native methods will ' 1363 help='When true, the called-by-native methods will '
1320 'be initialized in a non-atomic way.') 1364 'be initialized in a non-atomic way.')
1321 option_parser.add_option('--cpp', default='cpp', 1365 option_parser.add_option('--cpp', default='cpp',
1322 help='The path to cpp command.') 1366 help='The path to cpp command.')
1323 option_parser.add_option('--javap', default='javap', 1367 option_parser.add_option('--javap', default='javap',
1324 help='The path to javap command.') 1368 help='The path to javap command.')
1369 option_parser.add_option('--native_exports',
1370 action='store_true', dest='native_exports',
bulach 2014/04/14 13:16:02 nit: no need for dest
ostap 2014/04/15 23:30:20 Done.
1371 help='Native method registration through .so '
1372 'exports.')
1325 options, args = option_parser.parse_args(argv) 1373 options, args = option_parser.parse_args(argv)
1326 if options.jar_file: 1374 if options.jar_file:
1327 input_file = ExtractJarInputFile(options.jar_file, options.input_file, 1375 input_file = ExtractJarInputFile(options.jar_file, options.input_file,
1328 options.output_dir) 1376 options.output_dir)
1329 elif options.input_file: 1377 elif options.input_file:
1330 input_file = options.input_file 1378 input_file = options.input_file
1331 else: 1379 else:
1332 option_parser.print_help() 1380 option_parser.print_help()
1333 print '\nError: Must specify --jar_file or --input_file.' 1381 print '\nError: Must specify --jar_file or --input_file.'
1334 return 1 1382 return 1
1335 output_file = None 1383 output_file = None
1336 if options.output_dir: 1384 if options.output_dir:
1337 root_name = os.path.splitext(os.path.basename(input_file))[0] 1385 root_name = os.path.splitext(os.path.basename(input_file))[0]
1338 output_file = os.path.join(options.output_dir, root_name) + '_jni.h' 1386 output_file = os.path.join(options.output_dir, root_name) + '_jni.h'
1339 if options.jarjar: 1387 if options.jarjar:
1340 with open(options.jarjar) as f: 1388 with open(options.jarjar) as f:
1341 JniParams.SetJarJarMappings(f.read()) 1389 JniParams.SetJarJarMappings(f.read())
1342 GenerateJNIHeader(input_file, output_file, options) 1390 GenerateJNIHeader(input_file, output_file, options)
1343 1391
1344 1392
1345 if __name__ == '__main__': 1393 if __name__ == '__main__':
1346 sys.exit(main(sys.argv)) 1394 sys.exit(main(sys.argv))
OLDNEW
« no previous file with comments | « no previous file | base/android/jni_generator/jni_generator_tests.py » ('j') | base/android/jni_generator/jni_generator_tests.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698