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