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 803 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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)) |
OLD | NEW |