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

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

Issue 2050803003: Update to Chromium //base at Chromium commit e3a753f17bac62738b0dbf0b36510f767b081e4b. (Closed) Base URL: https://github.com/domokit/base.git@master
Patch Set: Created 4 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
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 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 return java_pod_type_map[java_type[:-2]] + 'Array' 128 return java_pod_type_map[java_type[:-2]] + 'Array'
129 return 'jobjectArray' 129 return 'jobjectArray'
130 elif java_type.startswith('Class'): 130 elif java_type.startswith('Class'):
131 # Checking just the start of the name, rather than a direct comparison, 131 # Checking just the start of the name, rather than a direct comparison,
132 # in order to handle generics. 132 # in order to handle generics.
133 return 'jclass' 133 return 'jclass'
134 else: 134 else:
135 return 'jobject' 135 return 'jobject'
136 136
137 137
138 def WrapCTypeForDeclaration(c_type):
139 """Wrap the C datatype in a JavaRef if required."""
140 if re.match(RE_SCOPED_JNI_TYPES, c_type):
141 return 'const JavaParamRef<' + c_type + '>&'
142 else:
143 return c_type
144
145
146 def JavaDataTypeToCForDeclaration(java_type):
147 """Returns a JavaRef-wrapped C datatype for the given java type."""
148 return WrapCTypeForDeclaration(JavaDataTypeToC(java_type))
149
150
138 def JavaDataTypeToCForCalledByNativeParam(java_type): 151 def JavaDataTypeToCForCalledByNativeParam(java_type):
139 """Returns a C datatype to be when calling from native.""" 152 """Returns a C datatype to be when calling from native."""
140 if java_type == 'int': 153 if java_type == 'int':
141 return 'JniIntWrapper' 154 return 'JniIntWrapper'
142 else: 155 else:
143 return JavaDataTypeToC(java_type) 156 return JavaDataTypeToC(java_type)
144 157
145 158
146 def JavaReturnValueToC(java_type): 159 def JavaReturnValueToC(java_type):
147 """Returns a valid C return value for the given java type.""" 160 """Returns a valid C return value for the given java type."""
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 method_name = called_by_native.name 533 method_name = called_by_native.name
521 method_id_var_name = method_name 534 method_id_var_name = method_name
522 if method_counts[java_class_name][method_name] > 1: 535 if method_counts[java_class_name][method_name] > 1:
523 method_id_var_name = GetMangledMethodName(method_name, 536 method_id_var_name = GetMangledMethodName(method_name,
524 called_by_native.params, 537 called_by_native.params,
525 called_by_native.return_type) 538 called_by_native.return_type)
526 called_by_native.method_id_var_name = method_id_var_name 539 called_by_native.method_id_var_name = method_id_var_name
527 return called_by_natives 540 return called_by_natives
528 541
529 542
530 # Regex to match the JNI return types that should be included in a 543 # Regex to match the JNI types that should be wrapped in a JavaRef.
531 # ScopedJavaLocalRef. 544 RE_SCOPED_JNI_TYPES = re.compile('jobject|jclass|jstring|jthrowable|.*Array')
532 RE_SCOPED_JNI_RETURN_TYPES = re.compile( 545
533 'jobject|jclass|jstring|jthrowable|.*Array')
534 546
535 # Regex to match a string like "@CalledByNative public void foo(int bar)". 547 # Regex to match a string like "@CalledByNative public void foo(int bar)".
536 RE_CALLED_BY_NATIVE = re.compile( 548 RE_CALLED_BY_NATIVE = re.compile(
537 '@CalledByNative(?P<Unchecked>(Unchecked)*?)(?:\("(?P<annotation>.*)"\))?' 549 '@CalledByNative(?P<Unchecked>(Unchecked)*?)(?:\("(?P<annotation>.*)"\))?'
538 '\s+(?P<prefix>[\w ]*?)' 550 '\s+(?P<prefix>[\w ]*?)'
539 '\s*(?P<return_type>\S+?)' 551 '\s*(?P<return_type>\S+?)'
540 '\s+(?P<name>\w+)' 552 '\s+(?P<name>\w+)'
541 '\s*\((?P<params>[^\)]*)\)') 553 '\s*\((?P<params>[^\)]*)\)')
542 554
543 555
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after
998 return '' 1010 return ''
999 1011
1000 def GetCloseNamespaceString(self): 1012 def GetCloseNamespaceString(self):
1001 if self.namespace: 1013 if self.namespace:
1002 all_namespaces = ['} // namespace %s' % ns 1014 all_namespaces = ['} // namespace %s' % ns
1003 for ns in self.namespace.split('::')] 1015 for ns in self.namespace.split('::')]
1004 all_namespaces.reverse() 1016 all_namespaces.reverse()
1005 return '\n'.join(all_namespaces) + '\n' 1017 return '\n'.join(all_namespaces) + '\n'
1006 return '' 1018 return ''
1007 1019
1008 def GetJNIFirstParam(self, native): 1020 def GetJNIFirstParamType(self, native):
1009 ret = []
1010 if native.type == 'method': 1021 if native.type == 'method':
1011 ret = ['jobject jcaller'] 1022 return 'jobject'
1012 elif native.type == 'function': 1023 elif native.type == 'function':
1013 if native.static: 1024 if native.static:
1014 ret = ['jclass jcaller'] 1025 return 'jclass'
1015 else: 1026 else:
1016 ret = ['jobject jcaller'] 1027 return 'jobject'
1017 return ret 1028
1029 def GetJNIFirstParam(self, native, for_declaration):
1030 c_type = self.GetJNIFirstParamType(native)
1031 if for_declaration:
1032 c_type = WrapCTypeForDeclaration(c_type)
1033 return [c_type + ' jcaller']
1018 1034
1019 def GetParamsInDeclaration(self, native): 1035 def GetParamsInDeclaration(self, native):
1036 """Returns the params for the forward declaration.
1037
1038 Args:
1039 native: the native dictionary describing the method.
1040
1041 Returns:
1042 A string containing the params.
1043 """
1044 return ',\n '.join(self.GetJNIFirstParam(native, True) +
1045 [JavaDataTypeToCForDeclaration(param.datatype) + ' ' +
1046 param.name
1047 for param in native.params])
1048
1049 def GetParamsInStub(self, native):
1020 """Returns the params for the stub declaration. 1050 """Returns the params for the stub declaration.
1021 1051
1022 Args: 1052 Args:
1023 native: the native dictionary describing the method. 1053 native: the native dictionary describing the method.
1024 1054
1025 Returns: 1055 Returns:
1026 A string containing the params. 1056 A string containing the params.
1027 """ 1057 """
1028 return ',\n '.join(self.GetJNIFirstParam(native) + 1058 return ',\n '.join(self.GetJNIFirstParam(native, False) +
1029 [JavaDataTypeToC(param.datatype) + ' ' + 1059 [JavaDataTypeToC(param.datatype) + ' ' +
1030 param.name 1060 param.name
1031 for param in native.params]) 1061 for param in native.params])
1032 1062
1033 def GetCalledByNativeParamsInDeclaration(self, called_by_native): 1063 def GetCalledByNativeParamsInDeclaration(self, called_by_native):
1034 return ',\n '.join([ 1064 return ',\n '.join([
1035 JavaDataTypeToCForCalledByNativeParam(param.datatype) + ' ' + 1065 JavaDataTypeToCForCalledByNativeParam(param.datatype) + ' ' +
1036 param.name 1066 param.name
1037 for param in called_by_native.params]) 1067 for param in called_by_native.params])
1038 1068
(...skipping 10 matching lines...) Expand all
1049 1079
1050 java_name = JniParams.RemapClassName(self.fully_qualified_class) 1080 java_name = JniParams.RemapClassName(self.fully_qualified_class)
1051 java_name = java_name.replace('_', '_1').replace('/', '_') 1081 java_name = java_name.replace('_', '_1').replace('/', '_')
1052 if native.java_class_name: 1082 if native.java_class_name:
1053 java_name += '_00024' + native.java_class_name 1083 java_name += '_00024' + native.java_class_name
1054 1084
1055 values = {'NAME': native.name, 1085 values = {'NAME': native.name,
1056 'JAVA_NAME': java_name} 1086 'JAVA_NAME': java_name}
1057 return template.substitute(values) 1087 return template.substitute(values)
1058 1088
1089 def GetJavaParamRefForCall(self, c_type, name):
1090 return Template('JavaParamRef<${TYPE}>(env, ${NAME})').substitute({
1091 'TYPE': c_type,
1092 'NAME': name,
1093 })
1094
1095 def GetJNIFirstParamForCall(self, native):
1096 c_type = self.GetJNIFirstParamType(native)
1097 return [self.GetJavaParamRefForCall(c_type, 'jcaller')]
1098
1059 def GetNativeStub(self, native): 1099 def GetNativeStub(self, native):
1060 is_method = native.type == 'method' 1100 is_method = native.type == 'method'
1061 1101
1062 if is_method: 1102 if is_method:
1063 params = native.params[1:] 1103 params = native.params[1:]
1064 else: 1104 else:
1065 params = native.params 1105 params = native.params
1066 params_in_call = [] 1106 params_in_call = []
1067 if not self.options.pure_native_methods: 1107 if not self.options.pure_native_methods:
1068 params_in_call = ['env', 'jcaller'] 1108 params_in_call = ['env'] + self.GetJNIFirstParamForCall(native)
1069 params_in_call = ', '.join(params_in_call + [p.name for p in params]) 1109 for p in params:
1110 c_type = JavaDataTypeToC(p.datatype)
1111 if re.match(RE_SCOPED_JNI_TYPES, c_type):
1112 params_in_call.append(self.GetJavaParamRefForCall(c_type, p.name))
1113 else:
1114 params_in_call.append(p.name)
1115 params_in_call = ', '.join(params_in_call)
1070 1116
1071 if self.options.native_exports: 1117 if self.options.native_exports:
1072 stub_visibility = 'extern "C" __attribute__((visibility("default")))\n' 1118 stub_visibility = 'extern "C" __attribute__((visibility("default")))\n'
1073 else: 1119 else:
1074 stub_visibility = 'static ' 1120 stub_visibility = 'static '
1075 return_type = return_declaration = JavaDataTypeToC(native.return_type) 1121 return_type = return_declaration = JavaDataTypeToC(native.return_type)
1076 post_call = '' 1122 post_call = ''
1077 if re.match(RE_SCOPED_JNI_RETURN_TYPES, return_type): 1123 if re.match(RE_SCOPED_JNI_TYPES, return_type):
1078 post_call = '.Release()' 1124 post_call = '.Release()'
1079 return_declaration = 'ScopedJavaLocalRef<' + return_type + '>' 1125 return_declaration = 'ScopedJavaLocalRef<' + return_type + '>'
1080 values = { 1126 values = {
1081 'RETURN': return_type, 1127 'RETURN': return_type,
1082 'RETURN_DECLARATION': return_declaration, 1128 'RETURN_DECLARATION': return_declaration,
1083 'NAME': native.name, 1129 'NAME': native.name,
1084 'PARAMS': self.GetParamsInDeclaration(native), 1130 'PARAMS': self.GetParamsInDeclaration(native),
1131 'PARAMS_IN_STUB': self.GetParamsInStub(native),
1085 'PARAMS_IN_CALL': params_in_call, 1132 'PARAMS_IN_CALL': params_in_call,
1086 'POST_CALL': post_call, 1133 'POST_CALL': post_call,
1087 'STUB_NAME': self.GetStubName(native), 1134 'STUB_NAME': self.GetStubName(native),
1088 'STUB_VISIBILITY': stub_visibility, 1135 'STUB_VISIBILITY': stub_visibility,
1089 } 1136 }
1090 1137
1091 if is_method: 1138 if is_method:
1092 optional_error_return = JavaReturnValueToC(native.return_type) 1139 optional_error_return = JavaReturnValueToC(native.return_type)
1093 if optional_error_return: 1140 if optional_error_return:
1094 optional_error_return = ', ' + optional_error_return 1141 optional_error_return = ', ' + optional_error_return
1095 values.update({ 1142 values.update({
1096 'OPTIONAL_ERROR_RETURN': optional_error_return, 1143 'OPTIONAL_ERROR_RETURN': optional_error_return,
1097 'PARAM0_NAME': native.params[0].name, 1144 'PARAM0_NAME': native.params[0].name,
1098 'P0_TYPE': native.p0_type, 1145 'P0_TYPE': native.p0_type,
1099 }) 1146 })
1100 template = Template("""\ 1147 template = Template("""\
1101 ${STUB_VISIBILITY}${RETURN} ${STUB_NAME}(JNIEnv* env, 1148 ${STUB_VISIBILITY}${RETURN} ${STUB_NAME}(JNIEnv* env,
1102 ${PARAMS}) { 1149 ${PARAMS_IN_STUB}) {
1103 ${P0_TYPE}* native = reinterpret_cast<${P0_TYPE}*>(${PARAM0_NAME}); 1150 ${P0_TYPE}* native = reinterpret_cast<${P0_TYPE}*>(${PARAM0_NAME});
1104 CHECK_NATIVE_PTR(env, jcaller, native, "${NAME}"${OPTIONAL_ERROR_RETURN}); 1151 CHECK_NATIVE_PTR(env, jcaller, native, "${NAME}"${OPTIONAL_ERROR_RETURN});
1105 return native->${NAME}(${PARAMS_IN_CALL})${POST_CALL}; 1152 return native->${NAME}(${PARAMS_IN_CALL})${POST_CALL};
1106 } 1153 }
1107 """) 1154 """)
1108 else: 1155 else:
1109 template = Template(""" 1156 template = Template("""
1110 static ${RETURN_DECLARATION} ${NAME}(JNIEnv* env, ${PARAMS}); 1157 static ${RETURN_DECLARATION} ${NAME}(JNIEnv* env, ${PARAMS});
1111 1158
1112 ${STUB_VISIBILITY}${RETURN} ${STUB_NAME}(JNIEnv* env, ${PARAMS}) { 1159 ${STUB_VISIBILITY}${RETURN} ${STUB_NAME}(JNIEnv* env, ${PARAMS_IN_STUB}) {
1113 return ${NAME}(${PARAMS_IN_CALL})${POST_CALL}; 1160 return ${NAME}(${PARAMS_IN_CALL})${POST_CALL};
1114 } 1161 }
1115 """) 1162 """)
1116 1163
1117 return template.substitute(values) 1164 return template.substitute(values)
1118 1165
1119 def GetArgument(self, param): 1166 def GetArgument(self, param):
1120 return ('as_jint(' + param.name + ')' 1167 return ('as_jint(' + param.name + ')'
1121 if param.datatype == 'int' else param.name) 1168 if param.datatype == 'int' else param.name)
1122 1169
(...skipping 27 matching lines...) Expand all
1150 check_exception = 'jni_generator::CheckException(env);' 1197 check_exception = 'jni_generator::CheckException(env);'
1151 return_type = JavaDataTypeToC(called_by_native.return_type) 1198 return_type = JavaDataTypeToC(called_by_native.return_type)
1152 optional_error_return = JavaReturnValueToC(called_by_native.return_type) 1199 optional_error_return = JavaReturnValueToC(called_by_native.return_type)
1153 if optional_error_return: 1200 if optional_error_return:
1154 optional_error_return = ', ' + optional_error_return 1201 optional_error_return = ', ' + optional_error_return
1155 return_declaration = '' 1202 return_declaration = ''
1156 return_clause = '' 1203 return_clause = ''
1157 if return_type != 'void': 1204 if return_type != 'void':
1158 pre_call = ' ' + pre_call 1205 pre_call = ' ' + pre_call
1159 return_declaration = return_type + ' ret =' 1206 return_declaration = return_type + ' ret ='
1160 if re.match(RE_SCOPED_JNI_RETURN_TYPES, return_type): 1207 if re.match(RE_SCOPED_JNI_TYPES, return_type):
1161 return_type = 'ScopedJavaLocalRef<' + return_type + '>' 1208 return_type = 'ScopedJavaLocalRef<' + return_type + '>'
1162 return_clause = 'return ' + return_type + '(env, ret);' 1209 return_clause = 'return ' + return_type + '(env, ret);'
1163 else: 1210 else:
1164 return_clause = 'return ret;' 1211 return_clause = 'return ret;'
1165 return { 1212 return {
1166 'JAVA_CLASS': java_class, 1213 'JAVA_CLASS': java_class,
1167 'RETURN_TYPE': return_type, 1214 'RETURN_TYPE': return_type,
1168 'OPTIONAL_ERROR_RETURN': optional_error_return, 1215 'OPTIONAL_ERROR_RETURN': optional_error_return,
1169 'RETURN_DECLARATION': return_declaration, 1216 'RETURN_DECLARATION': return_declaration,
1170 'RETURN_CLAUSE': return_clause, 1217 'RETURN_CLAUSE': return_clause,
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
1528 GenerateJNIHeader(input_file, output_file, options) 1575 GenerateJNIHeader(input_file, output_file, options)
1529 1576
1530 if options.depfile: 1577 if options.depfile:
1531 build_utils.WriteDepfile( 1578 build_utils.WriteDepfile(
1532 options.depfile, 1579 options.depfile,
1533 build_utils.GetPythonDependencies()) 1580 build_utils.GetPythonDependencies())
1534 1581
1535 1582
1536 if __name__ == '__main__': 1583 if __name__ == '__main__':
1537 sys.exit(main(sys.argv)) 1584 sys.exit(main(sys.argv))
OLDNEW
« no previous file with comments | « android/jni_generator/golden_sample_for_tests_jni.h ('k') | android/jni_generator/jni_generator_helper.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698