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

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

Issue 1279163006: jni_generator: Wrap all native methods in stubs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove separate forward declaration section entirely Created 5 years, 4 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 746 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 757
758 #include "base/android/jni_int_wrapper.h" 758 #include "base/android/jni_int_wrapper.h"
759 759
760 // Step 1: forward declarations. 760 // Step 1: forward declarations.
761 namespace { 761 namespace {
762 $CLASS_PATH_DEFINITIONS 762 $CLASS_PATH_DEFINITIONS
763 $METHOD_ID_DEFINITIONS 763 $METHOD_ID_DEFINITIONS
764 } // namespace 764 } // namespace
765 765
766 $OPEN_NAMESPACE 766 $OPEN_NAMESPACE
767 $FORWARD_DECLARATIONS
768 767
769 $CONSTANT_FIELDS 768 $CONSTANT_FIELDS
770 769
771 // Step 2: method stubs. 770 // Step 2: method stubs.
772 $METHOD_STUBS 771 $METHOD_STUBS
773 772
774 // Step 3: RegisterNatives. 773 // Step 3: RegisterNatives.
775 $JNI_NATIVE_METHODS 774 $JNI_NATIVE_METHODS
776 $REGISTER_NATIVES 775 $REGISTER_NATIVES
777 $CLOSE_NAMESPACE 776 $CLOSE_NAMESPACE
778 $JNI_REGISTER_NATIVES 777 $JNI_REGISTER_NATIVES
779 #endif // ${HEADER_GUARD} 778 #endif // ${HEADER_GUARD}
780 """) 779 """)
781 values = { 780 values = {
782 'SCRIPT_NAME': self.options.script_name, 781 'SCRIPT_NAME': self.options.script_name,
783 'FULLY_QUALIFIED_CLASS': self.fully_qualified_class, 782 'FULLY_QUALIFIED_CLASS': self.fully_qualified_class,
784 'CLASS_PATH_DEFINITIONS': self.GetClassPathDefinitionsString(), 783 'CLASS_PATH_DEFINITIONS': self.GetClassPathDefinitionsString(),
785 'METHOD_ID_DEFINITIONS': self.GetMethodIDDefinitionsString(), 784 'METHOD_ID_DEFINITIONS': self.GetMethodIDDefinitionsString(),
786 'FORWARD_DECLARATIONS': self.GetForwardDeclarationsString(),
787 'CONSTANT_FIELDS': self.GetConstantFieldsString(), 785 'CONSTANT_FIELDS': self.GetConstantFieldsString(),
788 'METHOD_STUBS': self.GetMethodStubsString(), 786 'METHOD_STUBS': self.GetMethodStubsString(),
789 'OPEN_NAMESPACE': self.GetOpenNamespaceString(), 787 'OPEN_NAMESPACE': self.GetOpenNamespaceString(),
790 'JNI_NATIVE_METHODS': self.GetJNINativeMethodsString(), 788 'JNI_NATIVE_METHODS': self.GetJNINativeMethodsString(),
791 'REGISTER_NATIVES': self.GetRegisterNativesString(), 789 'REGISTER_NATIVES': self.GetRegisterNativesString(),
792 'CLOSE_NAMESPACE': self.GetCloseNamespaceString(), 790 'CLOSE_NAMESPACE': self.GetCloseNamespaceString(),
793 'HEADER_GUARD': self.header_guard, 791 'HEADER_GUARD': self.header_guard,
794 'INCLUDES': self.GetIncludesString(), 792 'INCLUDES': self.GetIncludesString(),
795 'JNI_REGISTER_NATIVES': self.GetJNIRegisterNativesString() 793 'JNI_REGISTER_NATIVES': self.GetJNIRegisterNativesString()
796 } 794 }
(...skipping 12 matching lines...) Expand all
809 jmethodID g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = NULL;""") 807 jmethodID g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = NULL;""")
810 ret = [] 808 ret = []
811 for called_by_native in self.called_by_natives: 809 for called_by_native in self.called_by_natives:
812 values = { 810 values = {
813 'JAVA_CLASS': called_by_native.java_class_name or self.class_name, 811 'JAVA_CLASS': called_by_native.java_class_name or self.class_name,
814 'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name, 812 'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name,
815 } 813 }
816 ret += [template.substitute(values)] 814 ret += [template.substitute(values)]
817 return '\n'.join(ret) 815 return '\n'.join(ret)
818 816
819 def GetForwardDeclarationsString(self):
820 ret = []
821 for native in self.natives:
822 if native.type != 'method':
823 ret += [self.GetForwardDeclaration(native)]
824 if self.options.native_exports and ret:
825 return '\nextern "C" {\n' + "\n".join(ret) + '\n}; // extern "C"'
826 return '\n'.join(ret)
827
828 def GetConstantFieldsString(self): 817 def GetConstantFieldsString(self):
829 if not self.constant_fields: 818 if not self.constant_fields:
830 return '' 819 return ''
831 ret = ['enum Java_%s_constant_fields {' % self.class_name] 820 ret = ['enum Java_%s_constant_fields {' % self.class_name]
832 for c in self.constant_fields: 821 for c in self.constant_fields:
833 ret += [' %s = %s,' % (c.name, c.value)] 822 ret += [' %s = %s,' % (c.name, c.value)]
834 ret += ['};'] 823 ret += ['};']
835 return '\n'.join(ret) 824 return '\n'.join(ret)
836 825
837 def GetMethodStubsString(self): 826 def GetMethodStubsString(self):
838 """Returns the code corresponding to method stubs.""" 827 """Returns the code corresponding to method stubs."""
839 ret = [] 828 ret = []
840 for native in self.natives: 829 for native in self.natives:
841 if native.type == 'method': 830 ret += [self.GetNativeStub(native)]
842 ret += [self.GetNativeMethodStubString(native)]
843 if self.options.eager_called_by_natives: 831 if self.options.eager_called_by_natives:
844 ret += self.GetEagerCalledByNativeMethodStubs() 832 ret += self.GetEagerCalledByNativeMethodStubs()
845 else: 833 else:
846 ret += self.GetLazyCalledByNativeMethodStubs() 834 ret += self.GetLazyCalledByNativeMethodStubs()
847
848 if self.options.native_exports and ret:
849 return '\nextern "C" {\n' + "\n".join(ret) + '\n}; // extern "C"'
850 return '\n'.join(ret) 835 return '\n'.join(ret)
851 836
852 def GetLazyCalledByNativeMethodStubs(self): 837 def GetLazyCalledByNativeMethodStubs(self):
853 return [self.GetLazyCalledByNativeMethodStub(called_by_native) 838 return [self.GetLazyCalledByNativeMethodStub(called_by_native)
854 for called_by_native in self.called_by_natives] 839 for called_by_native in self.called_by_natives]
855 840
856 def GetEagerCalledByNativeMethodStubs(self): 841 def GetEagerCalledByNativeMethodStubs(self):
857 ret = [] 842 ret = []
858 if self.called_by_natives: 843 if self.called_by_natives:
859 ret += ['namespace {'] 844 ret += ['namespace {']
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
1046 param.name 1031 param.name
1047 for param in called_by_native.params]) 1032 for param in called_by_native.params])
1048 1033
1049 def GetStubName(self, native): 1034 def GetStubName(self, native):
1050 """Return the name of the stub function for this native method. 1035 """Return the name of the stub function for this native method.
1051 1036
1052 Args: 1037 Args:
1053 native: the native dictionary describing the method. 1038 native: the native dictionary describing the method.
1054 1039
1055 Returns: 1040 Returns:
1056 A string with the stub function name. For native exports mode this is the 1041 A string with the stub function name (used by the JVM).
1057 Java_* symbol name required by the JVM; otherwise it is just the name of
1058 the native method itself.
1059 """ 1042 """
1060 if self.options.native_exports: 1043 template = Template("Java_${JAVA_NAME}_native${NAME}")
1061 template = Template("Java_${JAVA_NAME}_native${NAME}")
1062 1044
1063 java_name = JniParams.RemapClassName(self.fully_qualified_class) 1045 java_name = JniParams.RemapClassName(self.fully_qualified_class)
1064 java_name = java_name.replace('_', '_1').replace('/', '_') 1046 java_name = java_name.replace('_', '_1').replace('/', '_')
1065 if native.java_class_name: 1047 if native.java_class_name:
1066 java_name += '_00024' + native.java_class_name 1048 java_name += '_00024' + native.java_class_name
1067 1049
1068 values = {'NAME': native.name, 1050 values = {'NAME': native.name,
1069 'JAVA_NAME': java_name} 1051 'JAVA_NAME': java_name}
1070 return template.substitute(values) 1052 return template.substitute(values)
1053
1054 def GetNativeStub(self, native):
1055 is_method = native.type == 'method'
1056
1057 if is_method:
1058 params = native.params[1:]
1071 else: 1059 else:
1072 return native.name 1060 params = native.params
1073
1074 def GetForwardDeclaration(self, native):
1075 template_str = """
1076 static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS});
1077 """
1078 if self.options.native_exports:
1079 template_str += """
1080 __attribute__((visibility("default")))
1081 ${RETURN} ${STUB_NAME}(JNIEnv* env, ${PARAMS}) {
1082 return ${NAME}(${PARAMS_IN_CALL});
1083 }
1084 """
1085 template = Template(template_str)
1086 params_in_call = [] 1061 params_in_call = []
1087 if not self.options.pure_native_methods: 1062 if not self.options.pure_native_methods:
1088 params_in_call = ['env', 'jcaller'] 1063 params_in_call = ['env', 'jcaller']
1089 params_in_call = ', '.join(params_in_call + [p.name for p in native.params]) 1064 params_in_call = ', '.join(params_in_call + [p.name for p in params])
1090 1065
1091 values = {'RETURN': JavaDataTypeToC(native.return_type), 1066 if self.options.native_exports:
1092 'NAME': native.name, 1067 stub_visibility = 'extern "C" __attribute__((visibility("default")))\n'
1093 'PARAMS': self.GetParamsInDeclaration(native), 1068 else:
1094 'PARAMS_IN_CALL': params_in_call, 1069 stub_visibility = 'static '
1095 'STUB_NAME': self.GetStubName(native)} 1070 return_type = JavaDataTypeToC(native.return_type)
1096 return template.substitute(values) 1071 values = {
1072 'RETURN': return_type,
1073 'NAME': native.name,
1074 'PARAMS': self.GetParamsInDeclaration(native),
1075 'PARAMS_IN_CALL': params_in_call,
1076 'STUB_NAME': self.GetStubName(native),
1077 'STUB_VISIBILITY': stub_visibility,
1078 }
1097 1079
1098 def GetNativeMethodStubString(self, native): 1080 if is_method:
1099 """Returns stubs for native methods.""" 1081 optional_error_return = JavaReturnValueToC(native.return_type)
1100 if self.options.native_exports: 1082 if optional_error_return:
1101 template_str = """\ 1083 optional_error_return = ', ' + optional_error_return
1102 __attribute__((visibility("default"))) 1084 post_call = ''
1103 ${RETURN} ${STUB_NAME}(JNIEnv* env, 1085 if re.match(RE_SCOPED_JNI_RETURN_TYPES, return_type):
1104 ${PARAMS_IN_DECLARATION}) {""" 1086 post_call = '.Release()'
1105 else: 1087 values.update({
1106 template_str = """\ 1088 'OPTIONAL_ERROR_RETURN': optional_error_return,
1107 static ${RETURN} ${STUB_NAME}(JNIEnv* env, ${PARAMS_IN_DECLARATION}) {""" 1089 'PARAM0_NAME': native.params[0].name,
1108 template_str += """ 1090 'P0_TYPE': native.p0_type,
1091 'POST_CALL': post_call,
1092 })
1093 template = Template("""\
1094 ${STUB_VISIBILITY}${RETURN} ${STUB_NAME}(JNIEnv* env,
1095 ${PARAMS}) {
1109 ${P0_TYPE}* native = reinterpret_cast<${P0_TYPE}*>(${PARAM0_NAME}); 1096 ${P0_TYPE}* native = reinterpret_cast<${P0_TYPE}*>(${PARAM0_NAME});
1110 CHECK_NATIVE_PTR(env, jcaller, native, "${NAME}"${OPTIONAL_ERROR_RETURN}); 1097 CHECK_NATIVE_PTR(env, jcaller, native, "${NAME}"${OPTIONAL_ERROR_RETURN});
1111 return native->${NAME}(${PARAMS_IN_CALL})${POST_CALL}; 1098 return native->${NAME}(${PARAMS_IN_CALL})${POST_CALL};
1112 } 1099 }
1113 """ 1100 """)
1101 else:
1102 template = Template("""
1103 static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS});
1114 1104
1115 template = Template(template_str) 1105 ${STUB_VISIBILITY}${RETURN} ${STUB_NAME}(JNIEnv* env, ${PARAMS}) {
1116 params = [] 1106 return ${NAME}(${PARAMS_IN_CALL});
1117 if not self.options.pure_native_methods: 1107 }
1118 params = ['env', 'jcaller'] 1108 """)
1119 params_in_call = ', '.join(params + [p.name for p in native.params[1:]])
1120 1109
1121 return_type = JavaDataTypeToC(native.return_type)
1122 optional_error_return = JavaReturnValueToC(native.return_type)
1123 if optional_error_return:
1124 optional_error_return = ', ' + optional_error_return
1125 post_call = ''
1126 if re.match(RE_SCOPED_JNI_RETURN_TYPES, return_type):
1127 post_call = '.Release()'
1128
1129 values = {
1130 'RETURN': return_type,
1131 'OPTIONAL_ERROR_RETURN': optional_error_return,
1132 'NAME': native.name,
1133 'PARAMS_IN_DECLARATION': self.GetParamsInDeclaration(native),
1134 'PARAM0_NAME': native.params[0].name,
1135 'P0_TYPE': native.p0_type,
1136 'PARAMS_IN_CALL': params_in_call,
1137 'POST_CALL': post_call,
1138 'STUB_NAME': self.GetStubName(native),
1139 }
1140 return template.substitute(values) 1110 return template.substitute(values)
1141 1111
1142 def GetArgument(self, param): 1112 def GetArgument(self, param):
1143 return ('as_jint(' + param.name + ')' 1113 return ('as_jint(' + param.name + ')'
1144 if param.datatype == 'int' else param.name) 1114 if param.datatype == 'int' else param.name)
1145 1115
1146 def GetArgumentsInCall(self, params): 1116 def GetArgumentsInCall(self, params):
1147 """Return a string of arguments to call from native into Java""" 1117 """Return a string of arguments to call from native into Java"""
1148 return [self.GetArgument(p) for p in params] 1118 return [self.GetArgument(p) for p in params]
1149 1119
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after
1551 GenerateJNIHeader(input_file, output_file, options) 1521 GenerateJNIHeader(input_file, output_file, options)
1552 1522
1553 if options.depfile: 1523 if options.depfile:
1554 build_utils.WriteDepfile( 1524 build_utils.WriteDepfile(
1555 options.depfile, 1525 options.depfile,
1556 build_utils.GetPythonDependencies()) 1526 build_utils.GetPythonDependencies())
1557 1527
1558 1528
1559 if __name__ == '__main__': 1529 if __name__ == '__main__':
1560 sys.exit(main(sys.argv)) 1530 sys.exit(main(sys.argv))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698