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

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: Updated by review comments. 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
« no previous file with comments | « no previous file | base/android/jni_generator/jni_generator_tests.py » ('j') | build/common.gypi » ('J')
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 718 matching lines...) Expand 10 before | Expand all | Expand 10 after
729 'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name, 729 'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name,
730 } 730 }
731 ret += [template.substitute(values)] 731 ret += [template.substitute(values)]
732 return '\n'.join(ret) 732 return '\n'.join(ret)
733 733
734 def GetForwardDeclarationsString(self): 734 def GetForwardDeclarationsString(self):
735 ret = [] 735 ret = []
736 for native in self.natives: 736 for native in self.natives:
737 if native.type != 'method': 737 if native.type != 'method':
738 ret += [self.GetForwardDeclaration(native)] 738 ret += [self.GetForwardDeclaration(native)]
739 if self.options.native_exports and ret:
740 return '\nextern "C" {\n' + "\n".join(ret) + '\n}; // extern "C"'
739 return '\n'.join(ret) 741 return '\n'.join(ret)
740 742
741 def GetConstantFieldsString(self): 743 def GetConstantFieldsString(self):
742 if not self.constant_fields: 744 if not self.constant_fields:
743 return '' 745 return ''
744 ret = ['enum Java_%s_constant_fields {' % self.class_name] 746 ret = ['enum Java_%s_constant_fields {' % self.class_name]
745 for c in self.constant_fields: 747 for c in self.constant_fields:
746 ret += [' %s = %s,' % (c.name, c.value)] 748 ret += [' %s = %s,' % (c.name, c.value)]
747 ret += ['};'] 749 ret += ['};']
748 return '\n'.join(ret) 750 return '\n'.join(ret)
749 751
750 def GetMethodStubsString(self): 752 def GetMethodStubsString(self):
751 """Returns the code corresponding to method stubs.""" 753 """Returns the code corresponding to method stubs."""
752 ret = [] 754 ret = []
753 for native in self.natives: 755 for native in self.natives:
754 if native.type == 'method': 756 if native.type == 'method':
755 ret += [self.GetNativeMethodStubString(native)] 757 ret += [self.GetNativeMethodStubString(native)]
756 if self.options.eager_called_by_natives: 758 if self.options.eager_called_by_natives:
757 ret += self.GetEagerCalledByNativeMethodStubs() 759 ret += self.GetEagerCalledByNativeMethodStubs()
758 else: 760 else:
759 ret += self.GetLazyCalledByNativeMethodStubs() 761 ret += self.GetLazyCalledByNativeMethodStubs()
762
763 if self.options.native_exports and ret:
764 return '\nextern "C" {\n' + "\n".join(ret) + '\n}; // extern "C"'
760 return '\n'.join(ret) 765 return '\n'.join(ret)
761 766
762 def GetLazyCalledByNativeMethodStubs(self): 767 def GetLazyCalledByNativeMethodStubs(self):
763 return [self.GetLazyCalledByNativeMethodStub(called_by_native) 768 return [self.GetLazyCalledByNativeMethodStub(called_by_native)
764 for called_by_native in self.called_by_natives] 769 for called_by_native in self.called_by_natives]
765 770
766 def GetEagerCalledByNativeMethodStubs(self): 771 def GetEagerCalledByNativeMethodStubs(self):
767 ret = [] 772 ret = []
768 if self.called_by_natives: 773 if self.called_by_natives:
769 ret += ['namespace {'] 774 ret += ['namespace {']
(...skipping 25 matching lines...) Expand all
795 kmethods = self.GetKMethodsString(clazz) 800 kmethods = self.GetKMethodsString(clazz)
796 if kmethods: 801 if kmethods:
797 values = {'JAVA_CLASS': clazz, 802 values = {'JAVA_CLASS': clazz,
798 'KMETHODS': kmethods} 803 'KMETHODS': kmethods}
799 ret += [template.substitute(values)] 804 ret += [template.substitute(values)]
800 if not ret: return '' 805 if not ret: return ''
801 return '\n' + '\n'.join(ret) 806 return '\n' + '\n'.join(ret)
802 807
803 def GetJNINativeMethodsString(self): 808 def GetJNINativeMethodsString(self):
804 """Returns the implementation of the array of native methods.""" 809 """Returns the implementation of the array of native methods."""
810 if self.options.native_exports:
811 return ''
805 template = Template("""\ 812 template = Template("""\
806 static const JNINativeMethod kMethods${JAVA_CLASS}[] = { 813 static const JNINativeMethod kMethods${JAVA_CLASS}[] = {
807 ${KMETHODS} 814 ${KMETHODS}
808 }; 815 };
809 """) 816 """)
810 return self.SubstituteNativeMethods(template) 817 return self.SubstituteNativeMethods(template)
811 818
812 def GetRegisterCalledByNativesImplString(self): 819 def GetRegisterCalledByNativesImplString(self):
813 """Returns the code for registering the called by native methods.""" 820 """Returns the code for registering the called by native methods."""
814 if not self.options.eager_called_by_natives: 821 if not self.options.eager_called_by_natives:
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
849 called_by_natives = self.GetRegisterCalledByNativesImplString() 856 called_by_natives = self.GetRegisterCalledByNativesImplString()
850 values = {'REGISTER_NATIVES_SIGNATURE': signature, 857 values = {'REGISTER_NATIVES_SIGNATURE': signature,
851 'CLASSES': self.GetFindClasses(), 858 'CLASSES': self.GetFindClasses(),
852 'NATIVES': natives, 859 'NATIVES': natives,
853 'CALLED_BY_NATIVES': called_by_natives, 860 'CALLED_BY_NATIVES': called_by_natives,
854 } 861 }
855 return template.substitute(values) 862 return template.substitute(values)
856 863
857 def GetRegisterNativesImplString(self): 864 def GetRegisterNativesImplString(self):
858 """Returns the shared implementation for RegisterNatives.""" 865 """Returns the shared implementation for RegisterNatives."""
866 if self.options.native_exports:
867 return ''
868
859 template = Template("""\ 869 template = Template("""\
860 const int kMethods${JAVA_CLASS}Size = arraysize(kMethods${JAVA_CLASS}); 870 const int kMethods${JAVA_CLASS}Size = arraysize(kMethods${JAVA_CLASS});
861 871
862 if (env->RegisterNatives(g_${JAVA_CLASS}_clazz, 872 if (env->RegisterNatives(g_${JAVA_CLASS}_clazz,
863 kMethods${JAVA_CLASS}, 873 kMethods${JAVA_CLASS},
864 kMethods${JAVA_CLASS}Size) < 0) { 874 kMethods${JAVA_CLASS}Size) < 0) {
865 jni_generator::HandleRegistrationError( 875 jni_generator::HandleRegistrationError(
866 env, g_${JAVA_CLASS}_clazz, __FILE__); 876 env, g_${JAVA_CLASS}_clazz, __FILE__);
867 return false; 877 return false;
868 } 878 }
869 """) 879 """)
870 return self.SubstituteNativeMethods(template) 880 return self.SubstituteNativeMethods(template)
871 881
872 def GetJNIRegisterNativesString(self): 882 def GetJNIRegisterNativesString(self):
873 """Returns the implementation for the JNI registration of native methods.""" 883 """Returns the implementation for the JNI registration of native methods."""
874 if not self.init_native: 884 if not self.init_native:
875 return '' 885 return ''
876 886
877 template = Template("""\ 887 template = Template("""\
878 extern "C" JNIEXPORT bool JNICALL 888 extern "C" JNIEXPORT bool JNICALL
879 Java_${FULLY_QUALIFIED_CLASS}_${INIT_NATIVE_NAME}(JNIEnv* env, jclass clazz) { 889 Java_${FULLY_QUALIFIED_CLASS}_${INIT_NATIVE_NAME}(JNIEnv* env, jclass clazz) {
880 return ${NAMESPACE}RegisterNativesImpl(env, clazz); 890 return ${NAMESPACE}RegisterNativesImpl(env, clazz);
881 } 891 }
882 """) 892 """)
883 fully_qualified_class = self.fully_qualified_class.replace('/', '_') 893
894 if self.options.native_exports:
895 java_name = JniParams.RemapClassName(self.fully_qualified_class)
896 java_name = java_name.replace('_', '_1').replace('/', '_')
897 else:
898 java_name = self.fully_qualified_class.replace('/', '_')
899
884 namespace = '' 900 namespace = ''
885 if self.namespace: 901 if self.namespace:
886 namespace = self.namespace + '::' 902 namespace = self.namespace + '::'
887 values = {'FULLY_QUALIFIED_CLASS': fully_qualified_class, 903 values = {'FULLY_QUALIFIED_CLASS': java_name,
888 'INIT_NATIVE_NAME': 'native' + self.init_native.name, 904 'INIT_NATIVE_NAME': 'native' + self.init_native.name,
889 'NAMESPACE': namespace, 905 'NAMESPACE': namespace,
890 'REGISTER_NATIVES_IMPL': self.GetRegisterNativesImplString() 906 'REGISTER_NATIVES_IMPL': self.GetRegisterNativesImplString()
891 } 907 }
892 return template.substitute(values) 908 return template.substitute(values)
893 909
894 def GetOpenNamespaceString(self): 910 def GetOpenNamespaceString(self):
895 if self.namespace: 911 if self.namespace:
896 all_namespaces = ['namespace %s {' % ns 912 all_namespaces = ['namespace %s {' % ns
897 for ns in self.namespace.split('::')] 913 for ns in self.namespace.split('::')]
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
930 [JavaDataTypeToC(param.datatype) + ' ' + 946 [JavaDataTypeToC(param.datatype) + ' ' +
931 param.name 947 param.name
932 for param in native.params]) 948 for param in native.params])
933 949
934 def GetCalledByNativeParamsInDeclaration(self, called_by_native): 950 def GetCalledByNativeParamsInDeclaration(self, called_by_native):
935 return ',\n '.join([JavaDataTypeToC(param.datatype) + ' ' + 951 return ',\n '.join([JavaDataTypeToC(param.datatype) + ' ' +
936 param.name 952 param.name
937 for param in called_by_native.params]) 953 for param in called_by_native.params])
938 954
939 def GetForwardDeclaration(self, native): 955 def GetForwardDeclaration(self, native):
940 template = Template(""" 956 template_str = """
941 static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS}); 957 static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS});
942 """) 958 """
959 if self.options.native_exports:
960 template_str += """
961 __attribute__((visibility("default")))
962 ${RETURN} Java_${JAVA_NAME}_native${NAME}(JNIEnv* env, ${PARAMS}) {
963 return ${NAME}(${PARAMS_IN_CALL});
964 }
965 """
966 template = Template(template_str)
967 params_in_call = []
968 if not self.options.pure_native_methods:
969 params_in_call = ['env', 'jcaller']
970 params_in_call = ', '.join(params_in_call + [p.name for p in native.params])
971
972 java_name = JniParams.RemapClassName(self.fully_qualified_class)
973 java_name = java_name.replace('_', '_1').replace('/', '_')
974 if native.java_class_name:
975 java_name += '_00024' + native.java_class_name
Yaron 2014/04/22 02:43:08 Why is this logic not needed in GetJNIRegisterNati
ostap 2014/04/24 03:58:43 SoOn 2014/04/22 02:43:08, Yaron wrote:
ostap 2014/04/24 14:10:00 Actually, RegisterNatives will never be in inner c
976
943 values = {'RETURN': JavaDataTypeToC(native.return_type), 977 values = {'RETURN': JavaDataTypeToC(native.return_type),
944 'NAME': native.name, 978 'NAME': native.name,
945 'PARAMS': self.GetParamsInDeclaration(native)} 979 'JAVA_NAME': java_name,
980 'PARAMS': self.GetParamsInDeclaration(native),
981 'PARAMS_IN_CALL': params_in_call}
946 return template.substitute(values) 982 return template.substitute(values)
947 983
948 def GetNativeMethodStubString(self, native): 984 def GetNativeMethodStubString(self, native):
949 """Returns stubs for native methods.""" 985 """Returns stubs for native methods."""
950 template = Template("""\ 986 if self.options.native_exports:
951 static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS_IN_DECLARATION}) { 987 template_str = """\
988 __attribute__((visibility("default")))
989 ${RETURN} Java_${JAVA_NAME}_native${NAME}(JNIEnv* env,
990 ${PARAMS_IN_DECLARATION}) {"""
991 else:
992 template_str = """\
993 static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS_IN_DECLARATION}) {"""
994 template_str += """
952 ${P0_TYPE}* native = reinterpret_cast<${P0_TYPE}*>(${PARAM0_NAME}); 995 ${P0_TYPE}* native = reinterpret_cast<${P0_TYPE}*>(${PARAM0_NAME});
953 CHECK_NATIVE_PTR(env, jcaller, native, "${NAME}"${OPTIONAL_ERROR_RETURN}); 996 CHECK_NATIVE_PTR(env, jcaller, native, "${NAME}"${OPTIONAL_ERROR_RETURN});
954 return native->${NAME}(${PARAMS_IN_CALL})${POST_CALL}; 997 return native->${NAME}(${PARAMS_IN_CALL})${POST_CALL};
955 } 998 }
956 """) 999 """
1000
1001 template = Template(template_str)
957 params = [] 1002 params = []
958 if not self.options.pure_native_methods: 1003 if not self.options.pure_native_methods:
959 params = ['env', 'jcaller'] 1004 params = ['env', 'jcaller']
960 params_in_call = ', '.join(params + [p.name for p in native.params[1:]]) 1005 params_in_call = ', '.join(params + [p.name for p in native.params[1:]])
961 1006
962 return_type = JavaDataTypeToC(native.return_type) 1007 return_type = JavaDataTypeToC(native.return_type)
963 optional_error_return = JavaReturnValueToC(native.return_type) 1008 optional_error_return = JavaReturnValueToC(native.return_type)
964 if optional_error_return: 1009 if optional_error_return:
965 optional_error_return = ', ' + optional_error_return 1010 optional_error_return = ', ' + optional_error_return
966 post_call = '' 1011 post_call = ''
967 if re.match(RE_SCOPED_JNI_RETURN_TYPES, return_type): 1012 if re.match(RE_SCOPED_JNI_RETURN_TYPES, return_type):
968 post_call = '.Release()' 1013 post_call = '.Release()'
1014
1015 if self.options.native_exports:
1016 java_name = JniParams.RemapClassName(self.fully_qualified_class)
1017 java_name = java_name.replace('_', '_1').replace('/', '_')
1018 if native.java_class_name:
1019 java_name += '_00024' + native.java_class_name
1020 else:
1021 java_name = ''
1022
969 values = { 1023 values = {
970 'RETURN': return_type, 1024 'RETURN': return_type,
971 'OPTIONAL_ERROR_RETURN': optional_error_return, 1025 'OPTIONAL_ERROR_RETURN': optional_error_return,
1026 'JAVA_NAME': java_name,
972 'NAME': native.name, 1027 'NAME': native.name,
973 'PARAMS_IN_DECLARATION': self.GetParamsInDeclaration(native), 1028 'PARAMS_IN_DECLARATION': self.GetParamsInDeclaration(native),
974 'PARAM0_NAME': native.params[0].name, 1029 'PARAM0_NAME': native.params[0].name,
975 'P0_TYPE': native.p0_type, 1030 'P0_TYPE': native.p0_type,
976 'PARAMS_IN_CALL': params_in_call, 1031 'PARAMS_IN_CALL': params_in_call,
977 'POST_CALL': post_call 1032 'POST_CALL': post_call
978 } 1033 }
979 return template.substitute(values) 1034 return template.substitute(values)
980 1035
981 def GetCalledByNativeValues(self, called_by_native): 1036 def GetCalledByNativeValues(self, called_by_native):
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1101 ret[class_name] = jni_class_path 1156 ret[class_name] = jni_class_path
1102 return ret 1157 return ret
1103 1158
1104 def GetClassPathDefinitions(self): 1159 def GetClassPathDefinitions(self):
1105 """Returns the ClassPath constants.""" 1160 """Returns the ClassPath constants."""
1106 ret = [] 1161 ret = []
1107 template = Template("""\ 1162 template = Template("""\
1108 const char k${JAVA_CLASS}ClassPath[] = "${JNI_CLASS_PATH}";""") 1163 const char k${JAVA_CLASS}ClassPath[] = "${JNI_CLASS_PATH}";""")
1109 native_classes = self.GetUniqueClasses(self.natives) 1164 native_classes = self.GetUniqueClasses(self.natives)
1110 called_by_native_classes = self.GetUniqueClasses(self.called_by_natives) 1165 called_by_native_classes = self.GetUniqueClasses(self.called_by_natives)
1111 all_classes = native_classes 1166 if self.options.native_exports:
1112 all_classes.update(called_by_native_classes) 1167 all_classes = called_by_native_classes
1168 else:
1169 all_classes = native_classes
1170 all_classes.update(called_by_native_classes)
1171
1113 for clazz in all_classes: 1172 for clazz in all_classes:
1114 values = { 1173 values = {
1115 'JAVA_CLASS': clazz, 1174 'JAVA_CLASS': clazz,
1116 'JNI_CLASS_PATH': JniParams.RemapClassName(all_classes[clazz]), 1175 'JNI_CLASS_PATH': JniParams.RemapClassName(all_classes[clazz]),
1117 } 1176 }
1118 ret += [template.substitute(values)] 1177 ret += [template.substitute(values)]
1119 ret += '' 1178 ret += ''
1120 for clazz in called_by_native_classes: 1179 for clazz in called_by_native_classes:
1121 template = Template("""\ 1180 template = Template("""\
1122 // Leaking this jclass as we cannot use LazyInstance from some threads. 1181 // Leaking this jclass as we cannot use LazyInstance from some threads.
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
1321 'will limit the initialization to only the ' 1380 'will limit the initialization to only the '
1322 'top-level class.') 1381 'top-level class.')
1323 option_parser.add_option('--eager_called_by_natives', 1382 option_parser.add_option('--eager_called_by_natives',
1324 action='store_true', dest='eager_called_by_natives', 1383 action='store_true', dest='eager_called_by_natives',
1325 help='When true, the called-by-native methods will ' 1384 help='When true, the called-by-native methods will '
1326 'be initialized in a non-atomic way.') 1385 'be initialized in a non-atomic way.')
1327 option_parser.add_option('--cpp', default='cpp', 1386 option_parser.add_option('--cpp', default='cpp',
1328 help='The path to cpp command.') 1387 help='The path to cpp command.')
1329 option_parser.add_option('--javap', default='javap', 1388 option_parser.add_option('--javap', default='javap',
1330 help='The path to javap command.') 1389 help='The path to javap command.')
1390 option_parser.add_option('--native_exports', action='store_true',
1391 help='Native method registration through .so '
1392 'exports.')
1331 options, args = option_parser.parse_args(argv) 1393 options, args = option_parser.parse_args(argv)
1332 if options.jar_file: 1394 if options.jar_file:
1333 input_file = ExtractJarInputFile(options.jar_file, options.input_file, 1395 input_file = ExtractJarInputFile(options.jar_file, options.input_file,
1334 options.output_dir) 1396 options.output_dir)
1335 elif options.input_file: 1397 elif options.input_file:
1336 input_file = options.input_file 1398 input_file = options.input_file
1337 else: 1399 else:
1338 option_parser.print_help() 1400 option_parser.print_help()
1339 print '\nError: Must specify --jar_file or --input_file.' 1401 print '\nError: Must specify --jar_file or --input_file.'
1340 return 1 1402 return 1
1341 output_file = None 1403 output_file = None
1342 if options.output_dir: 1404 if options.output_dir:
1343 root_name = os.path.splitext(os.path.basename(input_file))[0] 1405 root_name = os.path.splitext(os.path.basename(input_file))[0]
1344 output_file = os.path.join(options.output_dir, root_name) + '_jni.h' 1406 output_file = os.path.join(options.output_dir, root_name) + '_jni.h'
1345 if options.jarjar: 1407 if options.jarjar:
1346 with open(options.jarjar) as f: 1408 with open(options.jarjar) as f:
1347 JniParams.SetJarJarMappings(f.read()) 1409 JniParams.SetJarJarMappings(f.read())
1348 GenerateJNIHeader(input_file, output_file, options) 1410 GenerateJNIHeader(input_file, output_file, options)
1349 1411
1350 1412
1351 if __name__ == '__main__': 1413 if __name__ == '__main__':
1352 sys.exit(main(sys.argv)) 1414 sys.exit(main(sys.argv))
OLDNEW
« no previous file with comments | « no previous file | base/android/jni_generator/jni_generator_tests.py » ('j') | build/common.gypi » ('J')

Powered by Google App Engine
This is Rietveld 408576698