Chromium Code Reviews| 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 581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 592 #include "base/logging.h" | 592 #include "base/logging.h" |
| 593 | 593 |
| 594 using base::android::ScopedJavaLocalRef; | 594 using base::android::ScopedJavaLocalRef; |
| 595 | 595 |
| 596 // Step 1: forward declarations. | 596 // Step 1: forward declarations. |
| 597 namespace { | 597 namespace { |
| 598 $CLASS_PATH_DEFINITIONS | 598 $CLASS_PATH_DEFINITIONS |
| 599 } // namespace | 599 } // namespace |
| 600 | 600 |
| 601 $OPEN_NAMESPACE | 601 $OPEN_NAMESPACE |
| 602 extern "C"{ | |
| 602 $FORWARD_DECLARATIONS | 603 $FORWARD_DECLARATIONS |
| 603 | 604 |
| 604 // Step 2: method stubs. | 605 // Step 2: method stubs. |
| 605 $METHOD_STUBS | 606 $METHOD_STUBS |
| 607 }; | |
| 606 | 608 |
| 607 // Step 3: RegisterNatives. | 609 // Step 3: RegisterNatives. |
| 608 | 610 |
| 609 static bool RegisterNativesImpl(JNIEnv* env) { | 611 static bool RegisterNativesImpl(JNIEnv* env) { |
| 610 $REGISTER_NATIVES_IMPL | 612 $REGISTER_NATIVES_IMPL |
| 611 return true; | 613 return true; |
| 612 } | 614 } |
| 613 $CLOSE_NAMESPACE | 615 $CLOSE_NAMESPACE |
| 614 #endif // ${HEADER_GUARD} | 616 #endif // ${HEADER_GUARD} |
| 615 """) | 617 """) |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 653 def GetKMethodsString(self, clazz): | 655 def GetKMethodsString(self, clazz): |
| 654 ret = [] | 656 ret = [] |
| 655 for native in self.natives: | 657 for native in self.natives: |
| 656 if (native.java_class_name == clazz or | 658 if (native.java_class_name == clazz or |
| 657 (not native.java_class_name and clazz == self.class_name)): | 659 (not native.java_class_name and clazz == self.class_name)): |
| 658 ret += [self.GetKMethodArrayEntry(native)] | 660 ret += [self.GetKMethodArrayEntry(native)] |
| 659 return '\n'.join(ret) | 661 return '\n'.join(ret) |
| 660 | 662 |
| 661 def GetRegisterNativesImplString(self): | 663 def GetRegisterNativesImplString(self): |
| 662 """Returns the implementation for RegisterNatives.""" | 664 """Returns the implementation for RegisterNatives.""" |
| 665 if not self.called_by_natives: | |
| 666 return '' | |
| 663 template = Template("""\ | 667 template = Template("""\ |
| 664 static const JNINativeMethod kMethods${JAVA_CLASS}[] = { | 668 static const JNINativeMethod kMethods${JAVA_CLASS}[] = { |
| 665 ${KMETHODS} | 669 ${KMETHODS} |
| 666 }; | 670 }; |
| 667 const int kMethods${JAVA_CLASS}Size = arraysize(kMethods${JAVA_CLASS}); | 671 const int kMethods${JAVA_CLASS}Size = arraysize(kMethods${JAVA_CLASS}); |
| 668 | 672 |
| 669 if (env->RegisterNatives(g_${JAVA_CLASS}_clazz, | 673 if (env->RegisterNatives(g_${JAVA_CLASS}_clazz, |
| 670 kMethods${JAVA_CLASS}, | 674 kMethods${JAVA_CLASS}, |
| 671 kMethods${JAVA_CLASS}Size) < 0) { | 675 kMethods${JAVA_CLASS}Size) < 0) { |
| 672 LOG(ERROR) << "RegisterNatives failed in " << __FILE__; | 676 LOG(ERROR) << "RegisterNatives failed in " << __FILE__; |
| 673 return false; | 677 return false; |
| 674 } | 678 } |
| 675 """) | 679 """) |
| 676 ret = [self.GetFindClasses()] | 680 ret = [self.GetFindClasses()] |
| 677 all_classes = self.GetUniqueClasses(self.natives) | 681 all_classes = self.GetUniqueClasses(self.natives) |
| 678 all_classes[self.class_name] = self.fully_qualified_class | 682 all_classes[self.class_name] = self.fully_qualified_class |
| 679 for clazz in all_classes: | 683 for clazz in all_classes: |
| 680 kmethods = self.GetKMethodsString(clazz) | 684 kmethods = self.GetKMethodsString(clazz) |
| 681 if kmethods: | 685 if kmethods: |
| 682 values = {'JAVA_CLASS': clazz, | 686 values = {'JAVA_CLASS': clazz, |
| 683 'KMETHODS': kmethods} | 687 'KMETHODS': kmethods} |
| 684 ret += [template.substitute(values)] | 688 # ret += [template.substitute(values)] |
| 685 if not ret: return '' | 689 if not ret: return '' |
| 686 return '\n' + '\n'.join(ret) | 690 return '\n' + '\n'.join(ret) |
| 687 | 691 |
| 688 def GetOpenNamespaceString(self): | 692 def GetOpenNamespaceString(self): |
| 689 if self.namespace: | 693 if self.namespace: |
| 690 all_namespaces = ['namespace %s {' % ns | 694 all_namespaces = ['namespace %s {' % ns |
| 691 for ns in self.namespace.split('::')] | 695 for ns in self.namespace.split('::')] |
| 692 return '\n'.join(all_namespaces) | 696 return '\n'.join(all_namespaces) |
| 693 return '' | 697 return '' |
| 694 | 698 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 726 for param in native.params]) | 730 for param in native.params]) |
| 727 | 731 |
| 728 def GetCalledByNativeParamsInDeclaration(self, called_by_native): | 732 def GetCalledByNativeParamsInDeclaration(self, called_by_native): |
| 729 return ',\n '.join([JavaDataTypeToC(param.datatype) + ' ' + | 733 return ',\n '.join([JavaDataTypeToC(param.datatype) + ' ' + |
| 730 param.name | 734 param.name |
| 731 for param in called_by_native.params]) | 735 for param in called_by_native.params]) |
| 732 | 736 |
| 733 def GetForwardDeclaration(self, native): | 737 def GetForwardDeclaration(self, native): |
| 734 template = Template(""" | 738 template = Template(""" |
| 735 static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS}); | 739 static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS}); |
| 740 __attribute__((visibility("default"))) ${RETURN} | |
| 741 Java_${JAVA_NAME}_native${NAME}(JNIEnv* env, ${PARAMS}) | |
| 742 __attribute__((alias("${NAME}"))); | |
|
bulach
2013/06/28 00:45:54
I think you can combine the attributes:
__attribut
| |
| 736 """) | 743 """) |
| 744 java_name = JniParams.RemapClassName(self.fully_qualified_class).replace('_' , '_1').replace('/', '_') | |
| 745 if native.java_class_name: | |
| 746 java_name += "_00024" + native.java_class_name | |
| 747 | |
| 737 values = {'RETURN': JavaDataTypeToC(native.return_type), | 748 values = {'RETURN': JavaDataTypeToC(native.return_type), |
| 738 'NAME': native.name, | 749 'NAME': native.name, |
| 750 'JAVA_NAME': java_name, | |
| 739 'PARAMS': self.GetParamsInDeclaration(native)} | 751 'PARAMS': self.GetParamsInDeclaration(native)} |
| 740 return template.substitute(values) | 752 return template.substitute(values) |
| 741 | 753 |
| 742 def GetNativeMethodStub(self, native): | 754 def GetNativeMethodStub(self, native): |
| 743 """Returns stubs for native methods.""" | 755 """Returns stubs for native methods.""" |
| 744 template = Template("""\ | 756 template = Template("""\ |
| 745 static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS_IN_DECLARATION}) { | 757 static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS_IN_DECLARATION}) { |
| 746 DCHECK(${PARAM0_NAME}) << "${NAME}"; | 758 DCHECK(${PARAM0_NAME}) << "${NAME}"; |
| 747 ${P0_TYPE}* native = reinterpret_cast<${P0_TYPE}*>(${PARAM0_NAME}); | 759 ${P0_TYPE}* native = reinterpret_cast<${P0_TYPE}*>(${PARAM0_NAME}); |
| 748 return native->${NAME}(env, obj${PARAMS_IN_CALL})${POST_CALL}; | 760 return native->${NAME}(env, obj${PARAMS_IN_CALL})${POST_CALL}; |
| 749 } | 761 } |
| 762 __attribute__((visibility("default"))) ${RETURN} Java_${JAVA_NAME}_native${NAME} (JNIEnv* env, | |
| 763 ${PARAMS_IN_DECLARATION}) __attribute__((alias("${NAME}"))); | |
| 750 """) | 764 """) |
| 751 params_for_call = ', '.join(p.name for p in native.params[1:]) | 765 params_for_call = ', '.join(p.name for p in native.params[1:]) |
| 752 if params_for_call: | 766 if params_for_call: |
| 753 params_for_call = ', ' + params_for_call | 767 params_for_call = ', ' + params_for_call |
| 754 | 768 |
| 755 return_type = JavaDataTypeToC(native.return_type) | 769 return_type = JavaDataTypeToC(native.return_type) |
| 756 if re.match(RE_SCOPED_JNI_RETURN_TYPES, return_type): | 770 if re.match(RE_SCOPED_JNI_RETURN_TYPES, return_type): |
| 757 scoped_return_type = 'ScopedJavaLocalRef<' + return_type + '>' | 771 scoped_return_type = 'ScopedJavaLocalRef<' + return_type + '>' |
| 758 post_call = '.Release()' | 772 post_call = '.Release()' |
| 759 else: | 773 else: |
| 760 scoped_return_type = return_type | 774 scoped_return_type = return_type |
| 761 post_call = '' | 775 post_call = '' |
| 776 java_name = JniParams.RemapClassName(self.fully_qualified_class).replace('_' , '_1').replace('/', '_') | |
| 777 if native.java_class_name: | |
| 778 java_name += "_00024" + native.java_class_name | |
| 779 | |
| 762 values = { | 780 values = { |
| 763 'RETURN': return_type, | 781 'RETURN': return_type, |
| 764 'SCOPED_RETURN': scoped_return_type, | 782 'SCOPED_RETURN': scoped_return_type, |
| 783 'JAVA_NAME': java_name, | |
| 765 'NAME': native.name, | 784 'NAME': native.name, |
| 766 'PARAMS_IN_DECLARATION': self.GetParamsInDeclaration(native), | 785 'PARAMS_IN_DECLARATION': self.GetParamsInDeclaration(native), |
| 767 'PARAM0_NAME': native.params[0].name, | 786 'PARAM0_NAME': native.params[0].name, |
| 768 'P0_TYPE': native.p0_type, | 787 'P0_TYPE': native.p0_type, |
| 769 'PARAMS_IN_CALL': params_for_call, | 788 'PARAMS_IN_CALL': params_for_call, |
| 770 'POST_CALL': post_call | 789 'POST_CALL': post_call |
| 771 } | 790 } |
| 772 return template.substitute(values) | 791 return template.substitute(values) |
| 773 | 792 |
| 774 def GetCalledByNativeMethodStub(self, called_by_native): | 793 def GetCalledByNativeMethodStub(self, called_by_native): |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 872 jni_class_path = self.fully_qualified_class | 891 jni_class_path = self.fully_qualified_class |
| 873 if entry.java_class_name: | 892 if entry.java_class_name: |
| 874 class_name = entry.java_class_name | 893 class_name = entry.java_class_name |
| 875 jni_class_path = self.fully_qualified_class + '$' + class_name | 894 jni_class_path = self.fully_qualified_class + '$' + class_name |
| 876 ret[class_name] = jni_class_path | 895 ret[class_name] = jni_class_path |
| 877 return ret | 896 return ret |
| 878 | 897 |
| 879 def GetClassPathDefinitions(self): | 898 def GetClassPathDefinitions(self): |
| 880 """Returns the ClassPath constants.""" | 899 """Returns the ClassPath constants.""" |
| 881 ret = [] | 900 ret = [] |
| 901 if not self.called_by_natives: | |
| 902 return '' | |
| 882 template = Template("""\ | 903 template = Template("""\ |
| 883 const char k${JAVA_CLASS}ClassPath[] = "${JNI_CLASS_PATH}";""") | 904 const char k${JAVA_CLASS}ClassPath[] = "${JNI_CLASS_PATH}";""") |
| 884 native_classes = self.GetUniqueClasses(self.natives) | 905 all_classes = self.GetUniqueClasses(self.called_by_natives) |
| 885 called_by_native_classes = self.GetUniqueClasses(self.called_by_natives) | |
| 886 all_classes = native_classes | |
| 887 all_classes.update(called_by_native_classes) | |
| 888 for clazz in all_classes: | 906 for clazz in all_classes: |
| 889 values = { | 907 values = { |
| 890 'JAVA_CLASS': clazz, | 908 'JAVA_CLASS': clazz, |
| 891 'JNI_CLASS_PATH': JniParams.RemapClassName(all_classes[clazz]), | 909 'JNI_CLASS_PATH': JniParams.RemapClassName(all_classes[clazz]), |
| 892 } | 910 } |
| 893 ret += [template.substitute(values)] | 911 ret += [template.substitute(values)] |
| 894 ret += '' | 912 ret += '' |
| 895 for clazz in called_by_native_classes: | 913 for clazz in all_classes: |
| 896 template = Template("""\ | 914 template = Template("""\ |
| 897 // Leaking this jclass as we cannot use LazyInstance from some threads. | 915 // Leaking this jclass as we cannot use LazyInstance from some threads. |
| 898 jclass g_${JAVA_CLASS}_clazz = NULL;""") | 916 jclass g_${JAVA_CLASS}_clazz = NULL;""") |
| 899 values = { | 917 values = { |
| 900 'JAVA_CLASS': clazz, | 918 'JAVA_CLASS': clazz, |
| 901 } | 919 } |
| 902 ret += [template.substitute(values)] | 920 ret += [template.substitute(values)] |
| 903 return '\n'.join(ret) | 921 return '\n'.join(ret) |
| 904 | 922 |
| 905 def GetFindClasses(self): | 923 def GetFindClasses(self): |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1056 output_file = os.path.join(options.output_dir, root_name) + '_jni.h' | 1074 output_file = os.path.join(options.output_dir, root_name) + '_jni.h' |
| 1057 if options.jarjar: | 1075 if options.jarjar: |
| 1058 with open(options.jarjar) as f: | 1076 with open(options.jarjar) as f: |
| 1059 JniParams.SetJarJarMappings(f.read()) | 1077 JniParams.SetJarJarMappings(f.read()) |
| 1060 GenerateJNIHeader(input_file, output_file, options.namespace, | 1078 GenerateJNIHeader(input_file, output_file, options.namespace, |
| 1061 options.optimize_generation) | 1079 options.optimize_generation) |
| 1062 | 1080 |
| 1063 | 1081 |
| 1064 if __name__ == '__main__': | 1082 if __name__ == '__main__': |
| 1065 sys.exit(main(sys.argv)) | 1083 sys.exit(main(sys.argv)) |
| OLD | NEW |