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

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: 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 803 matching lines...) Expand 10 before | Expand all | Expand 10 after
814 'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name, 814 'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name,
815 } 815 }
816 ret += [template.substitute(values)] 816 ret += [template.substitute(values)]
817 return '\n'.join(ret) 817 return '\n'.join(ret)
818 818
819 def GetForwardDeclarationsString(self): 819 def GetForwardDeclarationsString(self):
820 ret = [] 820 ret = []
821 for native in self.natives: 821 for native in self.natives:
822 if native.type != 'method': 822 if native.type != 'method':
823 ret += [self.GetForwardDeclaration(native)] 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) 824 return '\n'.join(ret)
827 825
828 def GetConstantFieldsString(self): 826 def GetConstantFieldsString(self):
829 if not self.constant_fields: 827 if not self.constant_fields:
830 return '' 828 return ''
831 ret = ['enum Java_%s_constant_fields {' % self.class_name] 829 ret = ['enum Java_%s_constant_fields {' % self.class_name]
832 for c in self.constant_fields: 830 for c in self.constant_fields:
833 ret += [' %s = %s,' % (c.name, c.value)] 831 ret += [' %s = %s,' % (c.name, c.value)]
834 ret += ['};'] 832 ret += ['};']
835 return '\n'.join(ret) 833 return '\n'.join(ret)
836 834
837 def GetMethodStubsString(self): 835 def GetMethodStubsString(self):
838 """Returns the code corresponding to method stubs.""" 836 """Returns the code corresponding to method stubs."""
839 ret = [] 837 ret = []
840 for native in self.natives: 838 for native in self.natives:
841 if native.type == 'method': 839 if native.type == 'method':
842 ret += [self.GetNativeMethodStubString(native)] 840 ret += [self.GetNativeMethodStubString(native)]
843 if self.options.eager_called_by_natives: 841 if self.options.eager_called_by_natives:
844 ret += self.GetEagerCalledByNativeMethodStubs() 842 ret += self.GetEagerCalledByNativeMethodStubs()
845 else: 843 else:
846 ret += self.GetLazyCalledByNativeMethodStubs() 844 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) 845 return '\n'.join(ret)
851 846
852 def GetLazyCalledByNativeMethodStubs(self): 847 def GetLazyCalledByNativeMethodStubs(self):
853 return [self.GetLazyCalledByNativeMethodStub(called_by_native) 848 return [self.GetLazyCalledByNativeMethodStub(called_by_native)
854 for called_by_native in self.called_by_natives] 849 for called_by_native in self.called_by_natives]
855 850
856 def GetEagerCalledByNativeMethodStubs(self): 851 def GetEagerCalledByNativeMethodStubs(self):
857 ret = [] 852 ret = []
858 if self.called_by_natives: 853 if self.called_by_natives:
859 ret += ['namespace {'] 854 ret += ['namespace {']
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
1046 param.name 1041 param.name
1047 for param in called_by_native.params]) 1042 for param in called_by_native.params])
1048 1043
1049 def GetStubName(self, native): 1044 def GetStubName(self, native):
1050 """Return the name of the stub function for this native method. 1045 """Return the name of the stub function for this native method.
1051 1046
1052 Args: 1047 Args:
1053 native: the native dictionary describing the method. 1048 native: the native dictionary describing the method.
1054 1049
1055 Returns: 1050 Returns:
1056 A string with the stub function name. For native exports mode this is the 1051 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 """ 1052 """
1060 if self.options.native_exports: 1053 template = Template("Java_${JAVA_NAME}_native${NAME}")
1061 template = Template("Java_${JAVA_NAME}_native${NAME}")
1062 1054
1063 java_name = JniParams.RemapClassName(self.fully_qualified_class) 1055 java_name = JniParams.RemapClassName(self.fully_qualified_class)
1064 java_name = java_name.replace('_', '_1').replace('/', '_') 1056 java_name = java_name.replace('_', '_1').replace('/', '_')
1065 if native.java_class_name: 1057 if native.java_class_name:
1066 java_name += '_00024' + native.java_class_name 1058 java_name += '_00024' + native.java_class_name
1067 1059
1068 values = {'NAME': native.name, 1060 values = {'NAME': native.name,
1069 'JAVA_NAME': java_name} 1061 'JAVA_NAME': java_name}
1070 return template.substitute(values) 1062 return template.substitute(values)
1071 else:
1072 return native.name
1073 1063
1074 def GetForwardDeclaration(self, native): 1064 def GetForwardDeclaration(self, native):
1075 template_str = """ 1065 template_str = """
1076 static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS}); 1066 static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS});
1077 """ 1067
1078 if self.options.native_exports: 1068 ${STUB_VISIBILITY}${RETURN} ${STUB_NAME}(JNIEnv* env, ${PARAMS}) {
1079 template_str += """
1080 __attribute__((visibility("default")))
1081 ${RETURN} ${STUB_NAME}(JNIEnv* env, ${PARAMS}) {
1082 return ${NAME}(${PARAMS_IN_CALL}); 1069 return ${NAME}(${PARAMS_IN_CALL});
1083 } 1070 }
1084 """ 1071 """
1085 template = Template(template_str) 1072 template = Template(template_str)
1086 params_in_call = [] 1073 params_in_call = []
1087 if not self.options.pure_native_methods: 1074 if not self.options.pure_native_methods:
1088 params_in_call = ['env', 'jcaller'] 1075 params_in_call = ['env', 'jcaller']
1089 params_in_call = ', '.join(params_in_call + [p.name for p in native.params]) 1076 params_in_call = ', '.join(params_in_call + [p.name for p in native.params])
1077 if self.options.native_exports:
1078 stub_visibility = 'extern "C" __attribute__((visibility("default")))\n'
1079 else:
1080 stub_visibility = 'static '
1090 1081
1091 values = {'RETURN': JavaDataTypeToC(native.return_type), 1082 values = {'RETURN': JavaDataTypeToC(native.return_type),
1092 'NAME': native.name, 1083 'NAME': native.name,
1093 'PARAMS': self.GetParamsInDeclaration(native), 1084 'PARAMS': self.GetParamsInDeclaration(native),
1094 'PARAMS_IN_CALL': params_in_call, 1085 'PARAMS_IN_CALL': params_in_call,
1095 'STUB_NAME': self.GetStubName(native)} 1086 'STUB_NAME': self.GetStubName(native),
1087 'STUB_VISIBILITY': stub_visibility}
1096 return template.substitute(values) 1088 return template.substitute(values)
1097 1089
1098 def GetNativeMethodStubString(self, native): 1090 def GetNativeMethodStubString(self, native):
1099 """Returns stubs for native methods.""" 1091 """Returns stubs for native methods."""
1100 if self.options.native_exports: 1092 template_str = """\
1101 template_str = """\ 1093 ${STUB_VISIBILITY}${RETURN} ${STUB_NAME}(JNIEnv* env,
1102 __attribute__((visibility("default"))) 1094 ${PARAMS_IN_DECLARATION}) {
1103 ${RETURN} ${STUB_NAME}(JNIEnv* env,
1104 ${PARAMS_IN_DECLARATION}) {"""
1105 else:
1106 template_str = """\
1107 static ${RETURN} ${STUB_NAME}(JNIEnv* env, ${PARAMS_IN_DECLARATION}) {"""
1108 template_str += """
1109 ${P0_TYPE}* native = reinterpret_cast<${P0_TYPE}*>(${PARAM0_NAME}); 1095 ${P0_TYPE}* native = reinterpret_cast<${P0_TYPE}*>(${PARAM0_NAME});
1110 CHECK_NATIVE_PTR(env, jcaller, native, "${NAME}"${OPTIONAL_ERROR_RETURN}); 1096 CHECK_NATIVE_PTR(env, jcaller, native, "${NAME}"${OPTIONAL_ERROR_RETURN});
1111 return native->${NAME}(${PARAMS_IN_CALL})${POST_CALL}; 1097 return native->${NAME}(${PARAMS_IN_CALL})${POST_CALL};
1112 } 1098 }
1113 """ 1099 """
1114
1115 template = Template(template_str) 1100 template = Template(template_str)
1116 params = [] 1101 params = []
1117 if not self.options.pure_native_methods: 1102 if not self.options.pure_native_methods:
1118 params = ['env', 'jcaller'] 1103 params = ['env', 'jcaller']
1119 params_in_call = ', '.join(params + [p.name for p in native.params[1:]]) 1104 params_in_call = ', '.join(params + [p.name for p in native.params[1:]])
1120 1105
1121 return_type = JavaDataTypeToC(native.return_type) 1106 return_type = JavaDataTypeToC(native.return_type)
1122 optional_error_return = JavaReturnValueToC(native.return_type) 1107 optional_error_return = JavaReturnValueToC(native.return_type)
1123 if optional_error_return: 1108 if optional_error_return:
1124 optional_error_return = ', ' + optional_error_return 1109 optional_error_return = ', ' + optional_error_return
1125 post_call = '' 1110 post_call = ''
1126 if re.match(RE_SCOPED_JNI_RETURN_TYPES, return_type): 1111 if re.match(RE_SCOPED_JNI_RETURN_TYPES, return_type):
1127 post_call = '.Release()' 1112 post_call = '.Release()'
1113 if self.options.native_exports:
1114 stub_visibility = 'extern "C" __attribute__((visibility("default")))\n'
1115 else:
1116 stub_visibility = 'static '
rmcilroy 2015/08/12 10:35:35 nit - pull this out to a helper function to avoid
Torne 2015/08/12 10:37:56 Actually, I could probably just merge these two fu
1128 1117
1129 values = { 1118 values = {
1130 'RETURN': return_type, 1119 'RETURN': return_type,
1131 'OPTIONAL_ERROR_RETURN': optional_error_return, 1120 'OPTIONAL_ERROR_RETURN': optional_error_return,
1132 'NAME': native.name, 1121 'NAME': native.name,
1133 'PARAMS_IN_DECLARATION': self.GetParamsInDeclaration(native), 1122 'PARAMS_IN_DECLARATION': self.GetParamsInDeclaration(native),
1134 'PARAM0_NAME': native.params[0].name, 1123 'PARAM0_NAME': native.params[0].name,
1135 'P0_TYPE': native.p0_type, 1124 'P0_TYPE': native.p0_type,
1136 'PARAMS_IN_CALL': params_in_call, 1125 'PARAMS_IN_CALL': params_in_call,
1137 'POST_CALL': post_call, 1126 'POST_CALL': post_call,
1138 'STUB_NAME': self.GetStubName(native), 1127 'STUB_NAME': self.GetStubName(native),
1128 'STUB_VISIBILITY': stub_visibility,
1139 } 1129 }
1140 return template.substitute(values) 1130 return template.substitute(values)
1141 1131
1142 def GetArgument(self, param): 1132 def GetArgument(self, param):
1143 return ('as_jint(' + param.name + ')' 1133 return ('as_jint(' + param.name + ')'
1144 if param.datatype == 'int' else param.name) 1134 if param.datatype == 'int' else param.name)
1145 1135
1146 def GetArgumentsInCall(self, params): 1136 def GetArgumentsInCall(self, params):
1147 """Return a string of arguments to call from native into Java""" 1137 """Return a string of arguments to call from native into Java"""
1148 return [self.GetArgument(p) for p in params] 1138 return [self.GetArgument(p) for p in params]
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after
1551 GenerateJNIHeader(input_file, output_file, options) 1541 GenerateJNIHeader(input_file, output_file, options)
1552 1542
1553 if options.depfile: 1543 if options.depfile:
1554 build_utils.WriteDepfile( 1544 build_utils.WriteDepfile(
1555 options.depfile, 1545 options.depfile,
1556 build_utils.GetPythonDependencies()) 1546 build_utils.GetPythonDependencies())
1557 1547
1558 1548
1559 if __name__ == '__main__': 1549 if __name__ == '__main__':
1560 sys.exit(main(sys.argv)) 1550 sys.exit(main(sys.argv))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698