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

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

Issue 11038015: Android: lazy initialization for method id. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased Created 8 years, 2 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 | Annotate | Revision Log
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 # TODO (qinmin): Need to refactor this file as base should not know about 6 # TODO (qinmin): Need to refactor this file as base should not know about
7 # higher level concepts. Currently this file has knowledge about higher level 7 # higher level concepts. Currently this file has knowledge about higher level
8 # java classes. 8 # java classes.
9 9
10 """Extracts native methods from a Java file and generates the JNI bindings. 10 """Extracts native methods from a Java file and generates the JNI bindings.
(...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 namespace { 596 namespace {
597 $CLASS_PATH_DEFINITIONS 597 $CLASS_PATH_DEFINITIONS
598 } // namespace 598 } // namespace
599 599
600 $OPEN_NAMESPACE 600 $OPEN_NAMESPACE
601 $FORWARD_DECLARATIONS 601 $FORWARD_DECLARATIONS
602 602
603 // Step 2: method stubs. 603 // Step 2: method stubs.
604 $METHOD_STUBS 604 $METHOD_STUBS
605 605
606 // Step 3: GetMethodIDs and RegisterNatives. 606 // Step 3: RegisterNatives.
607 static void GetMethodIDsImpl(JNIEnv* env) {
608 $GET_METHOD_IDS_IMPL
609 }
610 607
611 static bool RegisterNativesImpl(JNIEnv* env) { 608 static bool RegisterNativesImpl(JNIEnv* env) {
612 GetMethodIDsImpl(env);
613 $REGISTER_NATIVES_IMPL 609 $REGISTER_NATIVES_IMPL
614 return true; 610 return true;
615 } 611 }
616 $CLOSE_NAMESPACE 612 $CLOSE_NAMESPACE
617 #endif // ${HEADER_GUARD} 613 #endif // ${HEADER_GUARD}
618 """) 614 """)
619 script_components = os.path.abspath(sys.argv[0]).split(os.path.sep) 615 script_components = os.path.abspath(sys.argv[0]).split(os.path.sep)
620 base_index = script_components.index('base') 616 base_index = script_components.index('base')
621 script_name = os.sep.join(script_components[base_index:]) 617 script_name = os.sep.join(script_components[base_index:])
622 values = { 618 values = {
623 'SCRIPT_NAME': script_name, 619 'SCRIPT_NAME': script_name,
624 'FULLY_QUALIFIED_CLASS': self.fully_qualified_class, 620 'FULLY_QUALIFIED_CLASS': self.fully_qualified_class,
625 'CLASS_PATH_DEFINITIONS': self.GetClassPathDefinitionsString(), 621 'CLASS_PATH_DEFINITIONS': self.GetClassPathDefinitionsString(),
626 'FORWARD_DECLARATIONS': self.GetForwardDeclarationsString(), 622 'FORWARD_DECLARATIONS': self.GetForwardDeclarationsString(),
627 'METHOD_STUBS': self.GetMethodStubsString(), 623 'METHOD_STUBS': self.GetMethodStubsString(),
628 'OPEN_NAMESPACE': self.GetOpenNamespaceString(), 624 'OPEN_NAMESPACE': self.GetOpenNamespaceString(),
629 'GET_METHOD_IDS_IMPL': self.GetMethodIDsImplString(),
630 'REGISTER_NATIVES_IMPL': self.GetRegisterNativesImplString(), 625 'REGISTER_NATIVES_IMPL': self.GetRegisterNativesImplString(),
631 'CLOSE_NAMESPACE': self.GetCloseNamespaceString(), 626 'CLOSE_NAMESPACE': self.GetCloseNamespaceString(),
632 'HEADER_GUARD': self.header_guard, 627 'HEADER_GUARD': self.header_guard,
633 } 628 }
634 return WrapOutput(template.substitute(values)) 629 return WrapOutput(template.substitute(values))
635 630
636 def GetClassPathDefinitionsString(self): 631 def GetClassPathDefinitionsString(self):
637 ret = [] 632 ret = []
638 ret += [self.GetClassPathDefinitions()] 633 ret += [self.GetClassPathDefinitions()]
639 return '\n'.join(ret) 634 return '\n'.join(ret)
(...skipping 15 matching lines...) Expand all
655 return '\n'.join(ret) 650 return '\n'.join(ret)
656 651
657 def GetKMethodsString(self, clazz): 652 def GetKMethodsString(self, clazz):
658 ret = [] 653 ret = []
659 for native in self.natives: 654 for native in self.natives:
660 if (native.java_class_name == clazz or 655 if (native.java_class_name == clazz or
661 (not native.java_class_name and clazz == self.class_name)): 656 (not native.java_class_name and clazz == self.class_name)):
662 ret += [self.GetKMethodArrayEntry(native)] 657 ret += [self.GetKMethodArrayEntry(native)]
663 return '\n'.join(ret) 658 return '\n'.join(ret)
664 659
665 def GetMethodIDsImplString(self):
666 ret = []
667 ret += [self.GetFindClasses()]
668 for called_by_native in self.called_by_natives:
669 ret += [self.GetMethodIDImpl(called_by_native)]
670 return '\n'.join(ret)
671
672 def GetRegisterNativesImplString(self): 660 def GetRegisterNativesImplString(self):
673 """Returns the implementation for RegisterNatives.""" 661 """Returns the implementation for RegisterNatives."""
674 template = Template("""\ 662 template = Template("""\
675 static const JNINativeMethod kMethods${JAVA_CLASS}[] = { 663 static const JNINativeMethod kMethods${JAVA_CLASS}[] = {
676 ${KMETHODS} 664 ${KMETHODS}
677 }; 665 };
678 const int kMethods${JAVA_CLASS}Size = arraysize(kMethods${JAVA_CLASS}); 666 const int kMethods${JAVA_CLASS}Size = arraysize(kMethods${JAVA_CLASS});
679 667
680 if (env->RegisterNatives(g_${JAVA_CLASS}_clazz, 668 if (env->RegisterNatives(g_${JAVA_CLASS}_clazz,
681 kMethods${JAVA_CLASS}, 669 kMethods${JAVA_CLASS},
682 kMethods${JAVA_CLASS}Size) < 0) { 670 kMethods${JAVA_CLASS}Size) < 0) {
683 LOG(ERROR) << "RegisterNatives failed in " << __FILE__; 671 LOG(ERROR) << "RegisterNatives failed in " << __FILE__;
684 return false; 672 return false;
685 } 673 }
686 """) 674 """)
687 ret = [] 675 ret = [self.GetFindClasses()]
688 all_classes = self.GetUniqueClasses(self.natives) 676 all_classes = self.GetUniqueClasses(self.natives)
689 all_classes[self.class_name] = self.fully_qualified_class 677 all_classes[self.class_name] = self.fully_qualified_class
690 for clazz in all_classes: 678 for clazz in all_classes:
691 kmethods = self.GetKMethodsString(clazz) 679 kmethods = self.GetKMethodsString(clazz)
692 if kmethods: 680 if kmethods:
693 values = {'JAVA_CLASS': clazz, 681 values = {'JAVA_CLASS': clazz,
694 'KMETHODS': kmethods} 682 'KMETHODS': kmethods}
695 ret += [template.substitute(values)] 683 ret += [template.substitute(values)]
696 if not ret: return '' 684 if not ret: return ''
697 return '\n' + '\n'.join(ret) 685 return '\n' + '\n'.join(ret)
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
786 """Returns a string.""" 774 """Returns a string."""
787 function_signature_template = Template("""\ 775 function_signature_template = Template("""\
788 static ${RETURN_TYPE} Java_${JAVA_CLASS}_${METHOD_ID_VAR_NAME}(\ 776 static ${RETURN_TYPE} Java_${JAVA_CLASS}_${METHOD_ID_VAR_NAME}(\
789 JNIEnv* env${FIRST_PARAM_IN_DECLARATION}${PARAMS_IN_DECLARATION})""") 777 JNIEnv* env${FIRST_PARAM_IN_DECLARATION}${PARAMS_IN_DECLARATION})""")
790 function_header_template = Template("""\ 778 function_header_template = Template("""\
791 ${FUNCTION_SIGNATURE} {""") 779 ${FUNCTION_SIGNATURE} {""")
792 function_header_with_unused_template = Template("""\ 780 function_header_with_unused_template = Template("""\
793 ${FUNCTION_SIGNATURE} __attribute__ ((unused)); 781 ${FUNCTION_SIGNATURE} __attribute__ ((unused));
794 ${FUNCTION_SIGNATURE} {""") 782 ${FUNCTION_SIGNATURE} {""")
795 template = Template(""" 783 template = Template("""
796 static jmethodID g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = 0; 784 static base::subtle::AtomicWord g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = 0;
797 ${FUNCTION_HEADER} 785 ${FUNCTION_HEADER}
798 /* Must call RegisterNativesImpl() */ 786 /* Must call RegisterNativesImpl() */
799 DCHECK(g_${JAVA_CLASS}_clazz); 787 DCHECK(g_${JAVA_CLASS}_clazz);
800 DCHECK(g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME}); 788 jmethodID method_id =
789 ${GET_METHOD_ID_IMPL}
801 ${RETURN_DECLARATION} 790 ${RETURN_DECLARATION}
802 ${PRE_CALL}env->${ENV_CALL}(${FIRST_PARAM_IN_CALL}, 791 ${PRE_CALL}env->${ENV_CALL}(${FIRST_PARAM_IN_CALL},
803 g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME}${PARAMS_IN_CALL})${POST_CALL}; 792 method_id${PARAMS_IN_CALL})${POST_CALL};
804 ${CHECK_EXCEPTION} 793 ${CHECK_EXCEPTION}
805 ${RETURN_CLAUSE} 794 ${RETURN_CLAUSE}
806 }""") 795 }""")
807 if called_by_native.static or called_by_native.is_constructor: 796 if called_by_native.static or called_by_native.is_constructor:
808 first_param_in_declaration = '' 797 first_param_in_declaration = ''
809 first_param_in_call = ('g_%s_clazz' % 798 first_param_in_call = ('g_%s_clazz' %
810 (called_by_native.java_class_name or 799 (called_by_native.java_class_name or
811 self.class_name)) 800 self.class_name))
812 else: 801 else:
813 first_param_in_declaration = ', jobject obj' 802 first_param_in_declaration = ', jobject obj'
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
848 'FIRST_PARAM_IN_DECLARATION': first_param_in_declaration, 837 'FIRST_PARAM_IN_DECLARATION': first_param_in_declaration,
849 'PARAMS_IN_DECLARATION': params_in_declaration, 838 'PARAMS_IN_DECLARATION': params_in_declaration,
850 'STATIC': 'Static' if called_by_native.static else '', 839 'STATIC': 'Static' if called_by_native.static else '',
851 'PRE_CALL': pre_call, 840 'PRE_CALL': pre_call,
852 'POST_CALL': post_call, 841 'POST_CALL': post_call,
853 'ENV_CALL': called_by_native.env_call, 842 'ENV_CALL': called_by_native.env_call,
854 'FIRST_PARAM_IN_CALL': first_param_in_call, 843 'FIRST_PARAM_IN_CALL': first_param_in_call,
855 'PARAMS_IN_CALL': params_for_call, 844 'PARAMS_IN_CALL': params_for_call,
856 'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name, 845 'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name,
857 'CHECK_EXCEPTION': check_exception, 846 'CHECK_EXCEPTION': check_exception,
847 'GET_METHOD_ID_IMPL': self.GetMethodIDImpl(called_by_native)
858 } 848 }
859 values['FUNCTION_SIGNATURE'] = ( 849 values['FUNCTION_SIGNATURE'] = (
860 function_signature_template.substitute(values)) 850 function_signature_template.substitute(values))
861 if called_by_native.system_class: 851 if called_by_native.system_class:
862 values['FUNCTION_HEADER'] = ( 852 values['FUNCTION_HEADER'] = (
863 function_header_with_unused_template.substitute(values)) 853 function_header_with_unused_template.substitute(values))
864 else: 854 else:
865 values['FUNCTION_HEADER'] = function_header_template.substitute(values) 855 values['FUNCTION_HEADER'] = function_header_template.substitute(values)
866 return template.substitute(values) 856 return template.substitute(values)
867 857
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
917 base::android::GetUnscopedClass(env, k${JAVA_CLASS}ClassPath)));""") 907 base::android::GetUnscopedClass(env, k${JAVA_CLASS}ClassPath)));""")
918 ret = [] 908 ret = []
919 for clazz in self.GetUniqueClasses(self.called_by_natives): 909 for clazz in self.GetUniqueClasses(self.called_by_natives):
920 values = {'JAVA_CLASS': clazz} 910 values = {'JAVA_CLASS': clazz}
921 ret += [template.substitute(values)] 911 ret += [template.substitute(values)]
922 return '\n'.join(ret) 912 return '\n'.join(ret)
923 913
924 def GetMethodIDImpl(self, called_by_native): 914 def GetMethodIDImpl(self, called_by_native):
925 """Returns the implementation of GetMethodID.""" 915 """Returns the implementation of GetMethodID."""
926 template = Template("""\ 916 template = Template("""\
927 g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = 917 base::android::MethodID::LazyGet<
928 base::android::Get${STATIC}MethodID${SUFFIX}( 918 base::android::MethodID::TYPE_${STATIC}>(
929 env, g_${JAVA_CLASS}_clazz, 919 env, g_${JAVA_CLASS}_clazz,
930 "${JNI_NAME}", 920 "${JNI_NAME}",
931 ${JNI_SIGNATURE}); 921 ${JNI_SIGNATURE},
922 &g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME});
932 """) 923 """)
933 jni_name = called_by_native.name 924 jni_name = called_by_native.name
934 jni_return_type = called_by_native.return_type 925 jni_return_type = called_by_native.return_type
935 if called_by_native.is_constructor: 926 if called_by_native.is_constructor:
936 jni_name = '<init>' 927 jni_name = '<init>'
937 jni_return_type = 'void' 928 jni_return_type = 'void'
938 values = { 929 values = {
939 'JAVA_CLASS': called_by_native.java_class_name or self.class_name, 930 'JAVA_CLASS': called_by_native.java_class_name or self.class_name,
940 'JNI_NAME': jni_name, 931 'JNI_NAME': jni_name,
941 'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name, 932 'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name,
942 'STATIC': 'Static' if called_by_native.static else '', 933 'STATIC': 'STATIC' if called_by_native.static else 'INSTANCE',
943 'SUFFIX': 'OrNull' if called_by_native.system_class else '',
944 'JNI_SIGNATURE': JniSignature(called_by_native.params, 934 'JNI_SIGNATURE': JniSignature(called_by_native.params,
945 jni_return_type, 935 jni_return_type,
946 True) 936 True)
947 } 937 }
948 return template.substitute(values) 938 return template.substitute(values)
949 939
950 940
951 def WrapOutput(output): 941 def WrapOutput(output):
952 ret = [] 942 ret = []
953 for line in output.splitlines(): 943 for line in output.splitlines():
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1046 input_file = options.input_file 1036 input_file = options.input_file
1047 output_file = None 1037 output_file = None
1048 if options.output_dir: 1038 if options.output_dir:
1049 root_name = os.path.splitext(os.path.basename(input_file))[0] 1039 root_name = os.path.splitext(os.path.basename(input_file))[0]
1050 output_file = os.path.join(options.output_dir, root_name) + '_jni.h' 1040 output_file = os.path.join(options.output_dir, root_name) + '_jni.h'
1051 GenerateJNIHeader(input_file, output_file, options.namespace) 1041 GenerateJNIHeader(input_file, output_file, options.namespace)
1052 1042
1053 1043
1054 if __name__ == '__main__': 1044 if __name__ == '__main__':
1055 sys.exit(main(sys.argv)) 1045 sys.exit(main(sys.argv))
OLDNEW
« no previous file with comments | « base/android/jni_generator/golden_sample_for_tests_jni.h ('k') | base/android/jni_generator/jni_generator_tests.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698