| OLD | NEW |
| 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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 'char': 'jchar', | 106 'char': 'jchar', |
| 107 'short': 'jshort', | 107 'short': 'jshort', |
| 108 'boolean': 'jboolean', | 108 'boolean': 'jboolean', |
| 109 'long': 'jlong', | 109 'long': 'jlong', |
| 110 'double': 'jdouble', | 110 'double': 'jdouble', |
| 111 'float': 'jfloat', | 111 'float': 'jfloat', |
| 112 } | 112 } |
| 113 java_type_map = { | 113 java_type_map = { |
| 114 'void': 'void', | 114 'void': 'void', |
| 115 'String': 'jstring', | 115 'String': 'jstring', |
| 116 'Throwable': 'jthrowable', |
| 116 'java/lang/String': 'jstring', | 117 'java/lang/String': 'jstring', |
| 117 'java/lang/Class': 'jclass', | 118 'java/lang/Class': 'jclass', |
| 119 'java/lang/Throwable': 'jthrowable', |
| 118 } | 120 } |
| 119 | 121 |
| 120 if java_type in java_pod_type_map: | 122 if java_type in java_pod_type_map: |
| 121 return java_pod_type_map[java_type] | 123 return java_pod_type_map[java_type] |
| 122 elif java_type in java_type_map: | 124 elif java_type in java_type_map: |
| 123 return java_type_map[java_type] | 125 return java_type_map[java_type] |
| 124 elif java_type.endswith('[]'): | 126 elif java_type.endswith('[]'): |
| 125 if java_type[:-2] in java_pod_type_map: | 127 if java_type[:-2] in java_pod_type_map: |
| 126 return java_pod_type_map[java_type[:-2]] + 'Array' | 128 return java_pod_type_map[java_type[:-2]] + 'Array' |
| 127 return 'jobjectArray' | 129 return 'jobjectArray' |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 name=match.group('name').replace('native', ''), | 425 name=match.group('name').replace('native', ''), |
| 424 params=JniParams.Parse(match.group('params')), | 426 params=JniParams.Parse(match.group('params')), |
| 425 ptr_type=ptr_type) | 427 ptr_type=ptr_type) |
| 426 natives += [native] | 428 natives += [native] |
| 427 return natives | 429 return natives |
| 428 | 430 |
| 429 | 431 |
| 430 def GetStaticCastForReturnType(return_type): | 432 def GetStaticCastForReturnType(return_type): |
| 431 type_map = { 'String' : 'jstring', | 433 type_map = { 'String' : 'jstring', |
| 432 'java/lang/String' : 'jstring', | 434 'java/lang/String' : 'jstring', |
| 435 'Throwable': 'jthrowable', |
| 436 'java/lang/Throwable': 'jthrowable', |
| 433 'boolean[]': 'jbooleanArray', | 437 'boolean[]': 'jbooleanArray', |
| 434 'byte[]': 'jbyteArray', | 438 'byte[]': 'jbyteArray', |
| 435 'char[]': 'jcharArray', | 439 'char[]': 'jcharArray', |
| 436 'short[]': 'jshortArray', | 440 'short[]': 'jshortArray', |
| 437 'int[]': 'jintArray', | 441 'int[]': 'jintArray', |
| 438 'long[]': 'jlongArray', | 442 'long[]': 'jlongArray', |
| 439 'float[]': 'jfloatArray', | 443 'float[]': 'jfloatArray', |
| 440 'double[]': 'jdoubleArray' } | 444 'double[]': 'jdoubleArray' } |
| 441 ret = type_map.get(return_type, None) | 445 ret = type_map.get(return_type, None) |
| 442 if ret: | 446 if ret: |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 if method_counts[java_class_name][method_name] > 1: | 522 if method_counts[java_class_name][method_name] > 1: |
| 519 method_id_var_name = GetMangledMethodName(method_name, | 523 method_id_var_name = GetMangledMethodName(method_name, |
| 520 called_by_native.params, | 524 called_by_native.params, |
| 521 called_by_native.return_type) | 525 called_by_native.return_type) |
| 522 called_by_native.method_id_var_name = method_id_var_name | 526 called_by_native.method_id_var_name = method_id_var_name |
| 523 return called_by_natives | 527 return called_by_natives |
| 524 | 528 |
| 525 | 529 |
| 526 # Regex to match the JNI return types that should be included in a | 530 # Regex to match the JNI return types that should be included in a |
| 527 # ScopedJavaLocalRef. | 531 # ScopedJavaLocalRef. |
| 528 RE_SCOPED_JNI_RETURN_TYPES = re.compile('jobject|jclass|jstring|.*Array') | 532 RE_SCOPED_JNI_RETURN_TYPES = re.compile( |
| 533 'jobject|jclass|jstring|jthrowable|.*Array') |
| 529 | 534 |
| 530 # Regex to match a string like "@CalledByNative public void foo(int bar)". | 535 # Regex to match a string like "@CalledByNative public void foo(int bar)". |
| 531 RE_CALLED_BY_NATIVE = re.compile( | 536 RE_CALLED_BY_NATIVE = re.compile( |
| 532 '@CalledByNative(?P<Unchecked>(Unchecked)*?)(?:\("(?P<annotation>.*)"\))?' | 537 '@CalledByNative(?P<Unchecked>(Unchecked)*?)(?:\("(?P<annotation>.*)"\))?' |
| 533 '\s+(?P<prefix>[\w ]*?)' | 538 '\s+(?P<prefix>[\w ]*?)' |
| 534 '\s*(?P<return_type>\S+?)' | 539 '\s*(?P<return_type>\S+?)' |
| 535 '\s+(?P<name>\w+)' | 540 '\s+(?P<name>\w+)' |
| 536 '\s*\((?P<params>[^\)]*)\)') | 541 '\s*\((?P<params>[^\)]*)\)') |
| 537 | 542 |
| 538 | 543 |
| (...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1060 params = native.params | 1065 params = native.params |
| 1061 params_in_call = [] | 1066 params_in_call = [] |
| 1062 if not self.options.pure_native_methods: | 1067 if not self.options.pure_native_methods: |
| 1063 params_in_call = ['env', 'jcaller'] | 1068 params_in_call = ['env', 'jcaller'] |
| 1064 params_in_call = ', '.join(params_in_call + [p.name for p in params]) | 1069 params_in_call = ', '.join(params_in_call + [p.name for p in params]) |
| 1065 | 1070 |
| 1066 if self.options.native_exports: | 1071 if self.options.native_exports: |
| 1067 stub_visibility = 'extern "C" __attribute__((visibility("default")))\n' | 1072 stub_visibility = 'extern "C" __attribute__((visibility("default")))\n' |
| 1068 else: | 1073 else: |
| 1069 stub_visibility = 'static ' | 1074 stub_visibility = 'static ' |
| 1070 return_type = JavaDataTypeToC(native.return_type) | 1075 return_type = return_declaration = JavaDataTypeToC(native.return_type) |
| 1076 post_call = '' |
| 1077 if re.match(RE_SCOPED_JNI_RETURN_TYPES, return_type): |
| 1078 post_call = '.Release()' |
| 1079 return_declaration = 'ScopedJavaLocalRef<' + return_type + '>' |
| 1071 values = { | 1080 values = { |
| 1072 'RETURN': return_type, | 1081 'RETURN': return_type, |
| 1082 'RETURN_DECLARATION': return_declaration, |
| 1073 'NAME': native.name, | 1083 'NAME': native.name, |
| 1074 'PARAMS': self.GetParamsInDeclaration(native), | 1084 'PARAMS': self.GetParamsInDeclaration(native), |
| 1075 'PARAMS_IN_CALL': params_in_call, | 1085 'PARAMS_IN_CALL': params_in_call, |
| 1086 'POST_CALL': post_call, |
| 1076 'STUB_NAME': self.GetStubName(native), | 1087 'STUB_NAME': self.GetStubName(native), |
| 1077 'STUB_VISIBILITY': stub_visibility, | 1088 'STUB_VISIBILITY': stub_visibility, |
| 1078 } | 1089 } |
| 1079 | 1090 |
| 1080 if is_method: | 1091 if is_method: |
| 1081 optional_error_return = JavaReturnValueToC(native.return_type) | 1092 optional_error_return = JavaReturnValueToC(native.return_type) |
| 1082 if optional_error_return: | 1093 if optional_error_return: |
| 1083 optional_error_return = ', ' + optional_error_return | 1094 optional_error_return = ', ' + optional_error_return |
| 1084 post_call = '' | |
| 1085 if re.match(RE_SCOPED_JNI_RETURN_TYPES, return_type): | |
| 1086 post_call = '.Release()' | |
| 1087 values.update({ | 1095 values.update({ |
| 1088 'OPTIONAL_ERROR_RETURN': optional_error_return, | 1096 'OPTIONAL_ERROR_RETURN': optional_error_return, |
| 1089 'PARAM0_NAME': native.params[0].name, | 1097 'PARAM0_NAME': native.params[0].name, |
| 1090 'P0_TYPE': native.p0_type, | 1098 'P0_TYPE': native.p0_type, |
| 1091 'POST_CALL': post_call, | |
| 1092 }) | 1099 }) |
| 1093 template = Template("""\ | 1100 template = Template("""\ |
| 1094 ${STUB_VISIBILITY}${RETURN} ${STUB_NAME}(JNIEnv* env, | 1101 ${STUB_VISIBILITY}${RETURN} ${STUB_NAME}(JNIEnv* env, |
| 1095 ${PARAMS}) { | 1102 ${PARAMS}) { |
| 1096 ${P0_TYPE}* native = reinterpret_cast<${P0_TYPE}*>(${PARAM0_NAME}); | 1103 ${P0_TYPE}* native = reinterpret_cast<${P0_TYPE}*>(${PARAM0_NAME}); |
| 1097 CHECK_NATIVE_PTR(env, jcaller, native, "${NAME}"${OPTIONAL_ERROR_RETURN}); | 1104 CHECK_NATIVE_PTR(env, jcaller, native, "${NAME}"${OPTIONAL_ERROR_RETURN}); |
| 1098 return native->${NAME}(${PARAMS_IN_CALL})${POST_CALL}; | 1105 return native->${NAME}(${PARAMS_IN_CALL})${POST_CALL}; |
| 1099 } | 1106 } |
| 1100 """) | 1107 """) |
| 1101 else: | 1108 else: |
| 1102 template = Template(""" | 1109 template = Template(""" |
| 1103 static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS}); | 1110 static ${RETURN_DECLARATION} ${NAME}(JNIEnv* env, ${PARAMS}); |
| 1104 | 1111 |
| 1105 ${STUB_VISIBILITY}${RETURN} ${STUB_NAME}(JNIEnv* env, ${PARAMS}) { | 1112 ${STUB_VISIBILITY}${RETURN} ${STUB_NAME}(JNIEnv* env, ${PARAMS}) { |
| 1106 return ${NAME}(${PARAMS_IN_CALL}); | 1113 return ${NAME}(${PARAMS_IN_CALL})${POST_CALL}; |
| 1107 } | 1114 } |
| 1108 """) | 1115 """) |
| 1109 | 1116 |
| 1110 return template.substitute(values) | 1117 return template.substitute(values) |
| 1111 | 1118 |
| 1112 def GetArgument(self, param): | 1119 def GetArgument(self, param): |
| 1113 return ('as_jint(' + param.name + ')' | 1120 return ('as_jint(' + param.name + ')' |
| 1114 if param.datatype == 'int' else param.name) | 1121 if param.datatype == 'int' else param.name) |
| 1115 | 1122 |
| 1116 def GetArgumentsInCall(self, params): | 1123 def GetArgumentsInCall(self, params): |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1144 return_type = JavaDataTypeToC(called_by_native.return_type) | 1151 return_type = JavaDataTypeToC(called_by_native.return_type) |
| 1145 optional_error_return = JavaReturnValueToC(called_by_native.return_type) | 1152 optional_error_return = JavaReturnValueToC(called_by_native.return_type) |
| 1146 if optional_error_return: | 1153 if optional_error_return: |
| 1147 optional_error_return = ', ' + optional_error_return | 1154 optional_error_return = ', ' + optional_error_return |
| 1148 return_declaration = '' | 1155 return_declaration = '' |
| 1149 return_clause = '' | 1156 return_clause = '' |
| 1150 if return_type != 'void': | 1157 if return_type != 'void': |
| 1151 pre_call = ' ' + pre_call | 1158 pre_call = ' ' + pre_call |
| 1152 return_declaration = return_type + ' ret =' | 1159 return_declaration = return_type + ' ret =' |
| 1153 if re.match(RE_SCOPED_JNI_RETURN_TYPES, return_type): | 1160 if re.match(RE_SCOPED_JNI_RETURN_TYPES, return_type): |
| 1154 return_type = 'base::android::ScopedJavaLocalRef<' + return_type + '>' | 1161 return_type = 'ScopedJavaLocalRef<' + return_type + '>' |
| 1155 return_clause = 'return ' + return_type + '(env, ret);' | 1162 return_clause = 'return ' + return_type + '(env, ret);' |
| 1156 else: | 1163 else: |
| 1157 return_clause = 'return ret;' | 1164 return_clause = 'return ret;' |
| 1158 return { | 1165 return { |
| 1159 'JAVA_CLASS': java_class, | 1166 'JAVA_CLASS': java_class, |
| 1160 'RETURN_TYPE': return_type, | 1167 'RETURN_TYPE': return_type, |
| 1161 'OPTIONAL_ERROR_RETURN': optional_error_return, | 1168 'OPTIONAL_ERROR_RETURN': optional_error_return, |
| 1162 'RETURN_DECLARATION': return_declaration, | 1169 'RETURN_DECLARATION': return_declaration, |
| 1163 'RETURN_CLAUSE': return_clause, | 1170 'RETURN_CLAUSE': return_clause, |
| 1164 'FIRST_PARAM_IN_DECLARATION': first_param_in_declaration, | 1171 'FIRST_PARAM_IN_DECLARATION': first_param_in_declaration, |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1521 GenerateJNIHeader(input_file, output_file, options) | 1528 GenerateJNIHeader(input_file, output_file, options) |
| 1522 | 1529 |
| 1523 if options.depfile: | 1530 if options.depfile: |
| 1524 build_utils.WriteDepfile( | 1531 build_utils.WriteDepfile( |
| 1525 options.depfile, | 1532 options.depfile, |
| 1526 build_utils.GetPythonDependencies()) | 1533 build_utils.GetPythonDependencies()) |
| 1527 | 1534 |
| 1528 | 1535 |
| 1529 if __name__ == '__main__': | 1536 if __name__ == '__main__': |
| 1530 sys.exit(main(sys.argv)) | 1537 sys.exit(main(sys.argv)) |
| OLD | NEW |