comparison generator/dgenerator.cpp @ 355:08c1ca7975ab

obviated redundant virtual dispatch callbacks
author Max Samukha <maxter@spambox.com>
date Tue, 25 May 2010 17:23:11 +0300
parents 18bd68f586c6
children 9784459f0750
comparison
equal deleted inserted replaced
354:18bd68f586c6 355:08c1ca7975ab
776 s << "super."; 776 s << "super.";
777 }*/ 777 }*/
778 s << d_function->marshalledName() << "("; 778 s << d_function->marshalledName() << "(";
779 } 779 }
780 780
781 bool arg_written = false;
782
781 if (!d_function->isConstructor() && !d_function->isStatic()) { 783 if (!d_function->isConstructor() && !d_function->isStatic()) {
782 if(dVersion == 2 && d_function->isConstant()) 784 s << "(cast(" << d_function->ownerClass()->name() << ")this).__nativeId";
783 s << "(cast(" << d_function->ownerClass()->name() << ")this).__nativeId"; 785 arg_written = true;
784 else
785 s << "__nativeId";
786 } 786 }
787 787
788 if (d_function->isConstructor() && 788 if (d_function->isConstructor() &&
789 ( d_function->implementingClass()->hasVirtualFunctions() 789 ( d_function->ownerClass()->isPolymorphic()
790 || d_function->implementingClass()->typeEntry()->isObject() ) ) { // qtd 790 || d_function->implementingClass()->typeEntry()->isObject() ) ) { // qtd
791 if (arg_written)
792 s << ", ";
791 s << "cast(void*) this"; 793 s << "cast(void*) this";
792 if (arguments.count() > 0) 794 arg_written = true;
793 s << ", "; 795 }
794 } 796
795 797 if(return_in_arg) {
796 if(return_in_arg) { // qtd 798 if (arg_written)
797 if (!d_function->isStatic() && !d_function->isConstructor()) // qtd
798 s << ", "; 799 s << ", ";
799 s << "&res"; 800 s << "&res";
801 arg_written = true;
800 } 802 }
801 803
802 for (int i=0; i<arguments.count(); ++i) { 804 for (int i=0; i<arguments.count(); ++i) {
803 const AbstractMetaArgument *arg = arguments.at(i); 805 const AbstractMetaArgument *arg = arguments.at(i);
804 const AbstractMetaType *type = arg->type(); 806 const AbstractMetaType *type = arg->type();
805 const TypeEntry *te = type->typeEntry(); 807 const TypeEntry *te = type->typeEntry();
806 808
807 if (!d_function->argumentRemoved(i+1)) { 809 if (!d_function->argumentRemoved(i+1)) {
808 if (i > 0 || (!d_function->isStatic() && !d_function->isConstructor()) || return_in_arg) // qtd 810 if (arg_written)
809 s << ", "; 811 s << ", ";
812 arg_written = true;
810 813
811 // qtd 814 // qtd
812 QString modified_type = d_function->typeReplaced(arg->argumentIndex() + 1); 815 QString modified_type = d_function->typeReplaced(arg->argumentIndex() + 1);
813 if (!modified_type.isEmpty()) 816 if (!modified_type.isEmpty())
814 modified_type = modified_type.replace('$', '.'); 817 modified_type = modified_type.replace('$', '.');
852 } 855 }
853 } 856 }
854 } 857 }
855 858
856 if (useJumpTable) { 859 if (useJumpTable) {
857 if ((!d_function->isConstructor() && !d_function->isStatic()) || arguments.size() > 0) 860 if (arg_written)
858 s << ", "; 861 s << ", ";
859 862
860 if (d_function->isStatic()) 863 if (d_function->isStatic())
861 s << "null"; 864 s << "null";
862 else 865 else
863 s << "this"; 866 s << "this";
867 arg_written = true;
864 } 868 }
865 869
866 s << ")"; 870 s << ")";
867 871
868 if ( !d_function->argumentReplaced(0).isEmpty() ) { 872 if ( !d_function->argumentReplaced(0).isEmpty() ) {
1752 } 1756 }
1753 } 1757 }
1754 */ 1758 */
1755 AbstractMetaArgumentList arguments = signal->arguments(); 1759 AbstractMetaArgumentList arguments = signal->arguments();
1756 1760
1757 s << "/*private extern(C) void " << sigExternName << "_handle(void* d_entity, void** args) {" << endl; 1761 s << "/*private extern(C) void " << sigExternName << "_handle(void* dId, void** args) {" << endl;
1758 { 1762 {
1759 Indentation indent(INDENT); 1763 Indentation indent(INDENT);
1760 s << INDENT << "auto d_object = cast(" << d_class->name() << ") d_entity;" << endl; 1764 s << INDENT << "auto d_object = cast(" << d_class->name() << ") dId;" << endl;
1761 int sz = arguments.count(); 1765 int sz = arguments.count();
1762 1766
1763 for (int j=0; j<sz; ++j) { 1767 for (int j=0; j<sz; ++j) {
1764 AbstractMetaArgument *argument = arguments.at(j); 1768 AbstractMetaArgument *argument = arguments.at(j);
1765 QString arg_name = argument->indexedName(); 1769 QString arg_name = argument->indexedName();
2040 s << templateArgument->name(); 2044 s << templateArgument->name();
2041 } 2045 }
2042 s << ">"; 2046 s << ">";
2043 } 2047 }
2044 2048
2049 AbstractMetaClassList interfaces = d_class->interfaces();
2050 bool implements = false;
2045 if (!d_class->isNamespace() && !d_class->isInterface()) { 2051 if (!d_class->isNamespace() && !d_class->isInterface()) {
2046 if (!d_class->baseClassName().isEmpty()) { 2052 if (!d_class->baseClassName().isEmpty()) {
2047 s << " : " << d_class->baseClass()->name(); 2053 s << " : " << d_class->baseClass()->name();
2054 implements = true;
2048 } else { 2055 } else {
2056
2057 /*
2049 QString sc = type->defaultSuperclass(); 2058 QString sc = type->defaultSuperclass();
2050 if ((sc != d_class->name()) && !sc.isEmpty()) 2059 if ((sc != d_class->name()) && !sc.isEmpty()) {
2051 s << " : " << sc; 2060 s << " : " << sc;
2061 implements = true;
2062 }
2063 */
2064 if (d_class->isQObject())
2065 s << " : QtdObject";
2066 else
2067 s << " : QtdObject";
2068 implements = true;
2052 } 2069 }
2053 }/* qtd else if (d_class->isInterface()) { 2070 }/* qtd else if (d_class->isInterface()) {
2054 s << " extends QtJambiInterface"; 2071 s << " extends QtJambiInterface";
2055 }*/ 2072 }*/
2056 2073
2057 // implementing interfaces... 2074 // implementing interfaces...
2058 bool implements = false; 2075 for (int i=0; i<interfaces.size(); ++i) {
2059 AbstractMetaClassList interfaces = d_class->interfaces(); 2076 if (implements)
2060 if (!interfaces.isEmpty()) {
2061 if (!d_class->isInterface())
2062 s << ", "; 2077 s << ", ";
2063 else { 2078 else {
2079 s << " : ";
2064 implements = true; 2080 implements = true;
2065 s << ": "; 2081 }
2066 } 2082 AbstractMetaClass *iface = interfaces.at(i);
2067 for (int i=0; i<interfaces.size(); ++i) { 2083 s << iface->name();
2068 AbstractMetaClass *iface = interfaces.at(i); 2084 }
2069 if (i) s << ", "; 2085
2070 s << iface->name();
2071 }
2072 }
2073 /* qtd 2086 /* qtd
2074 if (isComparable(d_class)) { 2087 if (isComparable(d_class)) {
2075 if (!implements) { 2088 if (!implements) {
2076 implements = true; 2089 implements = true;
2077 s << endl << " implements "; 2090 s << endl << " implements ";
2452 } 2465 }
2453 s << INDENT << "}" << endl << endl; 2466 s << INDENT << "}" << endl << endl;
2454 } 2467 }
2455 2468
2456 if (d_class->generateShellClass()) { // qtd2 2469 if (d_class->generateShellClass()) { // qtd2
2457 if (d_class->hasVirtualFunctions() 2470 if (d_class->isPolymorphic()
2458 && (d_class->typeEntry()->isObject() && !d_class->typeEntry()->isQObject()) ) 2471 && (d_class->typeEntry()->isObject() && !d_class->typeEntry()->isQObject()) )
2459 s << endl << "extern (C) void *__" << d_class->name() << "_entity(void *q_ptr);" << endl << endl; 2472 s << endl << "extern (C) void *__" << d_class->name() << "_entity(void *q_ptr);" << endl << endl;
2460 } 2473 }
2461 2474
2462 if (d_class->typeEntry()->isValue()) 2475 if (d_class->typeEntry()->isValue())
2555 if (cpp_shared && d_class->generateShellClass()) { 2568 if (cpp_shared && d_class->generateShellClass()) {
2556 // virtual functions 2569 // virtual functions
2557 s << INDENT << "void*[" << virtualFunctions.size() << "] virt_arr;" << endl; 2570 s << INDENT << "void*[" << virtualFunctions.size() << "] virt_arr;" << endl;
2558 for (int pos = 0; pos<virtualFunctions.size(); ++pos) { 2571 for (int pos = 0; pos<virtualFunctions.size(); ++pos) {
2559 const AbstractMetaFunction *function = virtualFunctions.at(pos); 2572 const AbstractMetaFunction *function = virtualFunctions.at(pos);
2560 if (!notWrappedYet(function)) // qtd2 2573 if (!notWrappedYet(function) && d_class == function->declaringClass()) // qtd2
2561 s << INDENT << "virt_arr[" << pos << "] = &" << function->marshalledName() << "_dispatch;" <<endl; 2574 s << INDENT << "virt_arr[" << pos << "] = &" << function->marshalledName(false) << "_dispatch;" <<endl;
2562 } 2575 }
2563 if (virtualFunctions.size() == 0) 2576 if (virtualFunctions.size() == 0)
2564 initArgs = "null"; 2577 initArgs = "null";
2565 else 2578 else
2566 initArgs = "virt_arr.ptr"; 2579 initArgs = "virt_arr.ptr";
2567 2580
2568 if (d_class->isQObject()) { 2581 if (d_class->name() == "QObject") {
2569 // qt_metacall, metaObject 2582 // qt_metacall, metaObject
2570 s << endl << INDENT << "void*[2] sign_arr;" << endl; 2583 s << endl << INDENT << "void*[2] sign_arr;" << endl;
2571 s << INDENT << "sign_arr[0] = &qtd_" << d_class->name() << "_qt_metacall_dispatch;" << endl; 2584 s << INDENT << "sign_arr[0] = &qtd_QObject_qt_metacall_dispatch;" << endl;
2572 s << INDENT << "sign_arr[1] = &qtd_" << d_class->name() << "_metaObject_dispatch;" << endl; 2585 s << INDENT << "sign_arr[1] = &qtd_QObject_metaObject_dispatch;" << endl;
2573 initArgs += ", sign_arr.ptr"; 2586 initArgs += ", sign_arr.ptr";
2574 } 2587 }
2575 2588
2576 s << INDENT << "qtd_" << d_class->name() << QString("_initCallBacks(%1);").arg(initArgs) << endl; 2589 s << INDENT << "qtd_" << d_class->name() << QString("_initCallBacks(%1);").arg(initArgs) << endl;
2577 } 2590 }
2805 s << " }" << endl << endl; 2818 s << " }" << endl << endl;
2806 2819
2807 s << INDENT << "mixin Q_OBJECT_BIND;" << endl << endl; 2820 s << INDENT << "mixin Q_OBJECT_BIND;" << endl << endl;
2808 } 2821 }
2809 2822
2810 /* 2823 void DGenerator::marshalFromCppToD(QTextStream &s, const ComplexTypeEntry* ctype)
2811 void DGenerator::writeMarshallFunction(QTextStream &s, const AbstractMetaClass *d_class)
2812 {
2813
2814 }
2815 */
2816 void DGenerator::marshallFromCppToD(QTextStream &s, const ComplexTypeEntry* ctype)
2817 { 2824 {
2818 if(ctype->isQObject()) { 2825 if(ctype->isQObject()) {
2819 QString type_name = ctype->name(); 2826 QString type_name = ctype->name();
2820 if (ctype->isAbstract()) 2827 if (ctype->isAbstract())
2821 type_name += "_ConcreteWrapper"; 2828 type_name += "_ConcreteWrapper";
2936 const AbstractMetaClass *implementor, int id) 2943 const AbstractMetaClass *implementor, int id)
2937 { 2944 {
2938 Q_UNUSED(id); 2945 Q_UNUSED(id);
2939 Q_UNUSED(implementor); 2946 Q_UNUSED(implementor);
2940 2947
2948 if (implementor != d_function->declaringClass())
2949 return;
2950
2941 s << "private extern(C) "; 2951 s << "private extern(C) ";
2942 CppImplGenerator::writeVirtualDispatchFunction(s, d_function, true); 2952 CppImplGenerator::writeVirtualDispatchFunction(s, d_function, implementor, true);
2943 s << "{" << endl; 2953 s << "{" << endl;
2944 2954
2945 const AbstractMetaClass *own_class = d_function->ownerClass(); 2955 const AbstractMetaClass *own_class = d_function->ownerClass();
2946 2956
2947 s << INDENT << "auto d_object = cast(" << own_class->name() << ") d_entity;" << endl; 2957 InterfaceTypeEntry *ite = own_class->typeEntry()->designatedInterface();
2958 if (ite)
2959 s << INDENT << "auto d_object = cast(" << ite->name() << ")cast(Object) dId;" << endl;
2960 else
2961 s << INDENT << "auto d_object = cast(" << own_class->name() << ") dId;" << endl;
2948 2962
2949 // the function arguments 2963 // the function arguments
2950 AbstractMetaArgumentList arguments = d_function->arguments(); 2964 AbstractMetaArgumentList arguments = d_function->arguments();
2951 foreach (const AbstractMetaArgument *argument, arguments) 2965 foreach (const AbstractMetaArgument *argument, arguments)
2952 if (!d_function->argumentRemoved(argument->argumentIndex() + 1)) { 2966 if (!d_function->argumentRemoved(argument->argumentIndex() + 1)) {