comparison generator/cppimplgenerator.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
498 498
499 // virtual functions handlers 499 // virtual functions handlers
500 AbstractMetaFunctionList virtualFunctions = java_class->virtualFunctions(); 500 AbstractMetaFunctionList virtualFunctions = java_class->virtualFunctions();
501 for (int pos = 0; pos<virtualFunctions.size(); ++pos) { 501 for (int pos = 0; pos<virtualFunctions.size(); ++pos) {
502 const AbstractMetaFunction *function = virtualFunctions.at(pos); 502 const AbstractMetaFunction *function = virtualFunctions.at(pos);
503 if (!notWrappedYet(function)) { // qtd2 503 if (!notWrappedYet(function) && java_class == function->declaringClass()) { // qtd2
504 s << " " << function->marshalledName() << "_dispatch = " 504 s << " " << function->marshalledName(false) << "_dispatch = "
505 "(pf" << function->marshalledName() << "_dispatch) virts[" << pos << "];" << endl; 505 "(pf" << function->marshalledName(false) << "_dispatch) virts[" << pos << "];" << endl;
506 } 506 }
507 } 507 }
508 // D-side signal callbacks 508 // D-side signal callbacks
509 if (java_class->isQObject()) { 509 if (java_class->name() == "QObject") {
510 s << " qtd_" << java_class->name() << "_qt_metacall_dispatch = (QtMetacallCallback)sigs[0];" << endl 510 s << " qtd_QObject_qt_metacall_dispatch = (QtMetacallCallback)sigs[0];" << endl
511 << " qtd_" << java_class->name() << "_metaObject_dispatch = (MetaObjectCallback)sigs[1];" << endl; 511 << " qtd_QObject_metaObject_dispatch = (MetaObjectCallback)sigs[1];" << endl;
512 } 512 }
513 s << "}" << endl; 513 s << "}" << endl;
514 } 514 }
515 515
516 516
542 s << "#include \"" << java_class->name() << "_shell" << ".h\"" << endl; 542 s << "#include \"" << java_class->name() << "_shell" << ".h\"" << endl;
543 /* qtd 543 /* qtd
544 if (java_class->isQObject()) 544 if (java_class->isQObject())
545 s << "#include <qtdynamicmetaobject.h>" << endl; 545 s << "#include <qtdynamicmetaobject.h>" << endl;
546 */ 546 */
547 if (java_class->isQObject())
548 s << "#include <QObjectEntity.h>" << endl;
549 547
550 s << "#include <iostream>" << endl; 548 s << "#include <iostream>" << endl;
551 549
552 550 writeInclude(s, java_class->typeEntry()->include());
553 551
554 Include inc = java_class->typeEntry()->include();
555 if (!inc.name.isEmpty()) {
556 s << "#include ";
557 if (inc.type == Include::IncludePath)
558 s << "<";
559 else
560 s << "\"";
561 s << inc.name;
562 if (inc.type == Include::IncludePath)
563 s << ">";
564 else
565 s << "\"";
566 s << endl;
567 }
568 s << endl; // qtd 552 s << endl; // qtd
569 s << "#include \"qtd_core.h\"" << endl 553 s << "#include \"qtd_core.h\"" << endl
570 << "#include \"ArrayOpsPrimitive.h\"" << endl 554 << "#include \"ArrayOpsPrimitive.h\"" << endl
571 << "#include \"ArrayOps_qt_core.h\"" << endl; 555 << "#include \"ArrayOps_qt_core.h\"" << endl;
572 556
597 if (shellClass) { 581 if (shellClass) {
598 foreach (AbstractMetaFunction *function, java_class->functions()) { 582 foreach (AbstractMetaFunction *function, java_class->functions()) {
599 if (function->isConstructor() && !function->isPrivate()) 583 if (function->isConstructor() && !function->isPrivate())
600 writeShellConstructor(s, function); 584 writeShellConstructor(s, function);
601 } 585 }
586
602 writeShellDestructor(s, java_class); 587 writeShellDestructor(s, java_class);
603 588
604 if (!java_class->isQObject() && java_class->hasVirtualFunctions()) 589 if (!java_class->isQObject() && java_class->hasVirtualFunctions())
605 writeQtdEntityFunction(s, java_class); 590 writeQtdEntityFunction(s, java_class);
606 591
753 s << QString("extern \"C\" DLL_PUBLIC bool qtd_%1_QTypeInfo_isLarge() { return (bool) QTypeInfo<%2>::isLarge; }\n").arg(java_class->name()).arg(java_class->qualifiedCppName()); 738 s << QString("extern \"C\" DLL_PUBLIC bool qtd_%1_QTypeInfo_isLarge() { return (bool) QTypeInfo<%2>::isLarge; }\n").arg(java_class->name()).arg(java_class->qualifiedCppName());
754 s << QString("extern \"C\" DLL_PUBLIC bool qtd_%1_QTypeInfo_isPointer() { return (bool) QTypeInfo<%2>::isPointer; }\n").arg(java_class->name()).arg(java_class->qualifiedCppName()); 739 s << QString("extern \"C\" DLL_PUBLIC bool qtd_%1_QTypeInfo_isPointer() { return (bool) QTypeInfo<%2>::isPointer; }\n").arg(java_class->name()).arg(java_class->qualifiedCppName());
755 s << QString("extern \"C\" DLL_PUBLIC bool qtd_%1_QTypeInfo_isDummy() { return (bool) QTypeInfo<%2>::isDummy; }\n").arg(java_class->name()).arg(java_class->qualifiedCppName()); 740 s << QString("extern \"C\" DLL_PUBLIC bool qtd_%1_QTypeInfo_isDummy() { return (bool) QTypeInfo<%2>::isDummy; }\n").arg(java_class->name()).arg(java_class->qualifiedCppName());
756 } 741 }
757 742
758 void CppImplGenerator::writeVirtualDispatchFunction(QTextStream &s, const AbstractMetaFunction *function, bool d_export) 743 void CppImplGenerator::writeVirtualDispatchFunction(QTextStream &s, const AbstractMetaFunction *function, const AbstractMetaClass *java_class, bool d_export)
759 { 744 {
760 uint options2 = ReturnType | ExternC; 745 uint options2 = ReturnType | ExternC;
761 QString return_type = jniReturnName(function, options2); 746 QString return_type = jniReturnName(function, options2);
762 QString f_name = function->marshalledName() + "_dispatch"; 747 QString f_name = function->marshalledName(false) + "_dispatch";
763 748
764 if(!d_export) 749 if(!d_export)
765 s << "extern \"C\" "; 750 s << "extern \"C\" ";
766 751
767 if (!cpp_shared || d_export) { 752 if (!cpp_shared || d_export) {
768 s << return_type << " " << f_name; 753 s << return_type << " " << f_name;
769 writeVirtualDispatchArguments(s, function, d_export); 754 writeVirtualDispatchArguments(s, function, d_export);
770 if(!d_export) 755 if(!d_export)
771 s << ";"; 756 s << ";";
772 } else if (cpp_shared) { 757 } else if (cpp_shared) {
773 s << "typedef " << return_type << " " << "(*pf" << f_name << ")"; 758 if (function->declaringClass() == java_class) {
774 writeVirtualDispatchArguments(s, function, false); 759 s << "typedef " << return_type << " " << "(*pf" << f_name << ")";
775 s << ";" << endl 760 writeVirtualDispatchArguments(s, function, false);
776 << "pf" << f_name << " " << f_name << ";"; 761 s << ";" << endl
762 << "pf" << f_name << " " << f_name << ";";
763 } else {
764 s << "extern pf" << f_name << " " << f_name << ";";
765 }
777 } 766 }
778 767
779 s << endl; 768 s << endl;
780 } 769 }
781 770
790 QString new_return_type = function->typeReplaced(0); 779 QString new_return_type = function->typeReplaced(0);
791 bool has_function_type = ((f_type != 0 780 bool has_function_type = ((f_type != 0
792 || !new_return_type.isEmpty()) 781 || !new_return_type.isEmpty())
793 && new_return_type != "void"); 782 && new_return_type != "void");
794 783
795 writeVirtualDispatchFunction(s, function); 784 writeVirtualDispatchFunction(s, function, implementor);
796 785
797 writeFunctionSignature(s, function, implementor, QString(), OriginalName); 786 writeFunctionSignature(s, function, implementor, QString(), OriginalName);
798 787
799 s << endl 788 s << endl
800 << "{" << endl; 789 << "{" << endl;
870 859
871 if (f_type->isEnum() || f_type->isFlags()) 860 if (f_type->isEnum() || f_type->isFlags())
872 s << "(" << f_type->typeEntry()->qualifiedCppName() <<") "; 861 s << "(" << f_type->typeEntry()->qualifiedCppName() <<") ";
873 } 862 }
874 863
875 s << function->marshalledName() << "_dispatch(" 864 s << function->marshalledName(false) << "_dispatch(";
876 << "this->dId"; 865 if (implementor->isQObject())
866 s << "QObjectLink::getLink(this)->dId";
867 else
868 s << "this->dId";
877 869
878 if (f_type) { 870 if (f_type) {
879 if (f_type->isTargetLangString()) 871 if (f_type->isTargetLangString())
880 s << ", &ret_str"; 872 s << ", &ret_str";
881 if (f_type->name() == "QModelIndex" || f_type->typeEntry()->isStructInD()) 873 if (f_type->name() == "QModelIndex" || f_type->typeEntry()->isStructInD())
932 void CppImplGenerator::writeVirtualDispatchArguments(QTextStream &s, const AbstractMetaFunction *d_function, bool d_export) 924 void CppImplGenerator::writeVirtualDispatchArguments(QTextStream &s, const AbstractMetaFunction *d_function, bool d_export)
933 { 925 {
934 uint nativeArgCount = 0; 926 uint nativeArgCount = 0;
935 AbstractMetaType *ret_type = d_function->type(); 927 AbstractMetaType *ret_type = d_function->type();
936 928
937 s << "(void *d_entity"; 929 s << "(void *dId";
938 930
939 if (ret_type) { 931 if (ret_type) {
940 if (ret_type->isTargetLangString()) { 932 if (ret_type->isTargetLangString()) {
941 if (d_export) 933 if (d_export)
942 s << ", string* ret_str"; 934 s << ", string* ret_str";
1271 void CppImplGenerator::writeQObjectEntity(QTextStream &s, const AbstractMetaClass *java_class) 1263 void CppImplGenerator::writeQObjectEntity(QTextStream &s, const AbstractMetaClass *java_class)
1272 { 1264 {
1273 QString entityName = java_class->name() + "Entity"; 1265 QString entityName = java_class->name() + "Entity";
1274 QString className = java_class->name(); 1266 QString className = java_class->name();
1275 1267
1276 s << "class " << entityName << " : public QObject, public QtD_QObjectEntity" << endl 1268 s << "class " << entityName << " : public QObject, public QObjectLink" << endl
1277 << "{" << endl 1269 << "{" << endl
1278 << "public:" << endl 1270 << "public:" << endl
1279 << " Q_OBJECT_CHECK" << endl 1271 << " Q_OBJECT_CHECK" << endl
1280 << "// virtual int qt_metacall(QMetaObject::Call, int, void **);" << endl << endl 1272 << "// virtual int qt_metacall(QMetaObject::Call, int, void **);" << endl << endl
1281 1273
1282 << " " << entityName << "(QObject *qObject, void *dId) : QObject(), QtD_QObjectEntity(qObject, dId) {}" << endl 1274 << " " << entityName << "(QObject *qObject, void *dId) : QObject(), QObjectLink(qObject, dId) {}" << endl
1283 << "};" << endl << endl; 1275 << "};" << endl << endl;
1284 1276
1285 /* // QObject_Link::qt_metacall() 1277 /* // QObject_Link::qt_metacall()
1286 s << "int " << entityName << "::qt_metacall(QMetaObject::Call _c, int _id, void **_a)" << endl 1278 s << "int " << entityName << "::qt_metacall(QMetaObject::Call _c, int _id, void **_a)" << endl
1287 << "{" << endl 1279 << "{" << endl
1350 << " emit_callbacks_" << java_class->name() << "[_id](this->dId, _a);" << endl 1342 << " emit_callbacks_" << java_class->name() << "[_id](this->dId, _a);" << endl
1351 << " return -1;" << endl 1343 << " return -1;" << endl
1352 << "}" << endl << endl; 1344 << "}" << endl << endl;
1353 */ 1345 */
1354 1346
1355 if(cpp_shared) 1347 if(cpp_shared) {
1356 s << "MetaObjectCallback qtd_" << java_class->name() << "_metaObject_dispatch;" << endl 1348 QString attr;
1357 << "QtMetacallCallback qtd_" << java_class->name() << "_qt_metacall_dispatch;" << endl; 1349 if (java_class->name() == "QObject")
1358 else 1350 attr = "extern ";
1359 s << "extern \"C\" const QMetaObject* qtd_" << java_class->name() << "_metaObject_dispatch(void *d_entity);" << endl 1351
1360 << "extern \"C\" int qtd_" << java_class->name() << "_qt_metacall_dispatch(void *d_entity, QMetaObject::Call _c, int _id, void **_a);" << endl; 1352 s << attr << "MetaObjectCallback qtd_QObject_metaObject_dispatch;" << endl
1361 1353 << attr << "QtMetacallCallback qtd_QObject_qt_metacall_dispatch;" << endl;
1354 } else {
1355 s << "extern \"C\" const QMetaObject* qtd_QObject_metaObject_dispatch(void *dId);" << endl
1356 << "extern \"C\" int qtd_QObject_qt_metacall_dispatch(void *dId, QMetaObject::Call _c, int _id, void **_a);" << endl;
1357 }
1358
1359 // TODO: QMetaObject should be included in the typesystem
1362 s << endl 1360 s << endl
1363 << "const QMetaObject * " << shellClassName(java_class) << "::metaObject() const" << endl 1361 << "const QMetaObject * " << shellClassName(java_class) << "::metaObject() const" << endl
1364 << "{" << endl 1362 << "{" << endl
1365 << " return qtd_" << java_class->name() << "_metaObject_dispatch(this->dId);" << endl 1363 << " void* dId = QObjectLink::getDId(this);" << endl
1364 << " if (dId)" << endl
1365 << " return qtd_QObject_metaObject_dispatch(dId);" << endl
1366 << " else" << endl
1367 << " return " << java_class->qualifiedCppName() << "::metaObject();" << endl
1366 << "}" << endl << endl 1368 << "}" << endl << endl
1367 << "int " << shellClassName(java_class) << "::qt_metacall(QMetaObject::Call _c, int _id, void **_a)" << endl 1369 << "int " << shellClassName(java_class) << "::qt_metacall(QMetaObject::Call _c, int _id, void **_a)" << endl
1368 << "{" << endl 1370 << "{" << endl
1369 << " return qtd_" << java_class->name() << "_qt_metacall_dispatch(this->dId, _c, _id, _a);" << endl 1371 << " void* dId = QObjectLink::getDId(this);" << endl
1372 << " if (dId)" << endl
1373 << " return qtd_QObject_qt_metacall_dispatch(dId, _c, _id, _a);" << endl
1374 << " else" << endl
1375 << " return " << java_class->qualifiedCppName() << "::qt_metacall(_c, _id, _a);" << endl
1370 << "}" << endl << endl 1376 << "}" << endl << endl
1371 1377
1372 << "int " << shellClassName(java_class) << "::__override_qt_metacall(QMetaObject::Call _c, int _id, void **_a)" << endl 1378 << "int " << shellClassName(java_class) << "::__override_qt_metacall(QMetaObject::Call _c, int _id, void **_a)" << endl
1373 << "{" << endl 1379 << "{" << endl
1374 << " return " << java_class->qualifiedCppName() << "::qt_metacall(_c, _id, _a);" 1380 << " return " << java_class->qualifiedCppName() << "::qt_metacall(_c, _id, _a);"
1440 s << "EmitCallback emit_callbacks_" << java_class->name() << "[1];" << endl; // Hack for msvc. 1446 s << "EmitCallback emit_callbacks_" << java_class->name() << "[1];" << endl; // Hack for msvc.
1441 else { 1447 else {
1442 // D-side signal callbacks 1448 // D-side signal callbacks
1443 for(int i = 0; i < signal_funcs.size(); i++) { 1449 for(int i = 0; i < signal_funcs.size(); i++) {
1444 AbstractMetaFunction *signal = signal_funcs.at(i); 1450 AbstractMetaFunction *signal = signal_funcs.at(i);
1445 s << "extern \"C\" DLL_PUBLIC void " << signalExternName(java_class, signal) << "_handle(void* d_entity, void** args);" << endl; 1451 s << "extern \"C\" DLL_PUBLIC void " << signalExternName(java_class, signal) << "_handle(void* dId, void** args);" << endl;
1446 } 1452 }
1447 1453
1448 if(signal_funcs.size() > 0) 1454 if(signal_funcs.size() > 0)
1449 s << "EmitCallback emit_callbacks_" << java_class->name() << "[" << signal_funcs.size() << "] = {" << endl; 1455 s << "EmitCallback emit_callbacks_" << java_class->name() << "[" << signal_funcs.size() << "] = {" << endl;
1450 else 1456 else
1477 s << arguments.at(i)->indexedName(); 1483 s << arguments.at(i)->indexedName();
1478 if (i != arguments.size() - 1) 1484 if (i != arguments.size() - 1)
1479 s << ", "; 1485 s << ", ";
1480 } 1486 }
1481 s << ")"; 1487 s << ")";
1482 if (cls->isQObject()) 1488 if (cls->isQObject()) {
1483 s << "," << endl << " QtD_QObjectEntity(this, d_ptr)"; 1489 s << "," << endl << " QObjectLink(this, d_ptr)";
1484 else if (cls->hasVirtualFunctions()) 1490 }
1485 s << "," << endl << " QtD_Entity(d_ptr)"; 1491 else if (cls->isPolymorphic())
1492 s << "," << endl << " QtdObjectLink(d_ptr)";
1486 /* qtd s << " m_meta_object(0)," << endl; 1493 /* qtd s << " m_meta_object(0)," << endl;
1487 s << " m_vtable(0)," << endl 1494 s << " m_vtable(0)," << endl
1488 << " m_link(0)" << endl; 1495 << " m_link(0)" << endl;
1489 */ 1496 */
1490 s << endl; 1497 s << endl;
1501 void CppImplGenerator::writeShellDestructor(QTextStream &s, const AbstractMetaClass *java_class) 1508 void CppImplGenerator::writeShellDestructor(QTextStream &s, const AbstractMetaClass *java_class)
1502 { 1509 {
1503 QString className = shellClassName(java_class); 1510 QString className = shellClassName(java_class);
1504 s << className << "::~" << className << "() {" << endl; 1511 s << className << "::~" << className << "() {" << endl;
1505 1512
1506 if (java_class->isQObject()) 1513 if (java_class->isQObject()) {
1507 s << " destroyEntity(this);"; 1514 s << " destroyLink(this);" << endl;
1508 //else if (java_class->isPolymorphic()) 1515 }
1509 // s << " qtd_QtdObject_delete(dId);" << endl; 1516 /*
1517 else if (java_class->isPolymorphic())
1518 s << " qtd_delete_d_object(dId);" << endl;
1519 */
1510 1520
1511 s << "}" << endl << endl; 1521 s << "}" << endl << endl;
1512 } 1522 }
1513 1523
1514 void CppImplGenerator::writeCodeInjections(QTextStream &s, const AbstractMetaFunction *java_function, 1524 void CppImplGenerator::writeCodeInjections(QTextStream &s, const AbstractMetaFunction *java_function,
1826 { 1836 {
1827 s << "extern \"C\" DLL_PUBLIC void *__" << java_class->name() << "_entity(void *q_ptr)" << endl; 1837 s << "extern \"C\" DLL_PUBLIC void *__" << java_class->name() << "_entity(void *q_ptr)" << endl;
1828 s << "{" << endl; 1838 s << "{" << endl;
1829 { 1839 {
1830 Indentation indent(INDENT); 1840 Indentation indent(INDENT);
1831 s << INDENT << "QtD_Entity* a = dynamic_cast<QtD_Entity*>((" << java_class->qualifiedCppName() << "*)q_ptr);" << endl 1841 s << INDENT << "QtdObjectLink* a = dynamic_cast<QtdObjectLink*>((" << java_class->qualifiedCppName() << "*)q_ptr);" << endl
1832 << INDENT << "if (a != NULL)" << endl 1842 << INDENT << "if (a != NULL)" << endl
1833 << INDENT << " return a->dId;" << endl 1843 << INDENT << " return a->dId;" << endl
1834 << INDENT << "else" << endl 1844 << INDENT << "else" << endl
1835 << INDENT << " return NULL;" << endl; 1845 << INDENT << " return NULL;" << endl;
1836 } 1846 }
1955 s << " jobject " << java_object_name; 1965 s << " jobject " << java_object_name;
1956 */ 1966 */
1957 uint nativeArgCount = 0; 1967 uint nativeArgCount = 0;
1958 const AbstractMetaClass *cls = java_function->ownerClass(); 1968 const AbstractMetaClass *cls = java_function->ownerClass();
1959 if (java_function->isConstructor() && 1969 if (java_function->isConstructor() &&
1960 ( cls->hasVirtualFunctions() 1970 ( cls->isPolymorphic()
1961 || cls->typeEntry()->isObject() ) ) 1971 || cls->typeEntry()->isObject() ) )
1962 { 1972 {
1963 s << "void *d_ptr"; 1973 s << "void *d_ptr";
1964 nativeArgCount++; 1974 nativeArgCount++;
1965 } 1975 }
1966 1976
1967 // passing pointer to C++ object 1977 // passing pointer to C++ object
1968 bool hasNativeId = (callThrough && !java_function->isStatic() && !java_function->isConstructor()); 1978 bool hasNativeId = callThrough && !java_function->isStatic() && !java_function->isConstructor();
1969 if (hasNativeId) { 1979 if (hasNativeId) {
1970 if (nativeArgCount > 0) 1980 if (nativeArgCount > 0)
1971 s << "," << endl << " "; 1981 s << "," << endl << " ";
1972 /* qtd << "," << endl */ s << "void* __this_nativeId"; 1982 /* qtd << "," << endl */ s << "void* __this_nativeId";
1973 nativeArgCount++; 1983 nativeArgCount++;
2174 function_prefix = "__public_"; 2184 function_prefix = "__public_";
2175 } else if (!java_function->isFinalInCpp() && !java_function->isStatic() && hasShell) { 2185 } else if (!java_function->isFinalInCpp() && !java_function->isStatic() && hasShell) {
2176 function_prefix = "__override_"; 2186 function_prefix = "__override_";
2177 extra_param.append("__do_static_call"); 2187 extra_param.append("__do_static_call");
2178 s << INDENT 2188 s << INDENT
2179 << "bool __do_static_call = __this_nativeId ? "; 2189 << "bool __do_static_call = "
2180 if (java_class->isQObject()) 2190 << "dynamic_cast<QtdObjectLink*>((" << java_class->polymorphicBase()->qualifiedCppName() << "*)__this_nativeId) != NULL;" << endl;
2181 s << "dynamic_cast<QtD_QObjectEntity*>((QObject*)__this_nativeId) : false;" << endl;
2182 else
2183 s << "__" << java_class->name() << "_entity(__this_nativeId) : false;" << endl;
2184 } else { 2191 } else {
2185 option = OriginalName; 2192 option = OriginalName;
2186 } 2193 }
2187 2194
2188 // Call the Qt function on the java object 2195 // Call the Qt function on the java object
3605 { 3612 {
3606 AbstractMetaArgumentList arguments = java_function->arguments(); 3613 AbstractMetaArgumentList arguments = java_function->arguments();
3607 3614
3608 int written_arguments = 0; 3615 int written_arguments = 0;
3609 const AbstractMetaClass *cls = java_function->ownerClass(); 3616 const AbstractMetaClass *cls = java_function->ownerClass();
3610 if (java_function->isConstructor() && cls->hasVirtualFunctions()) { 3617 if (java_function->isConstructor() && cls->isPolymorphic()) {
3611 s << "d_ptr"; 3618 s << "d_ptr";
3612 written_arguments++; 3619 written_arguments++;
3613 } 3620 }
3614 for (int i=0; i<arguments.size(); ++i) { 3621 for (int i=0; i<arguments.size(); ++i) {
3615 const AbstractMetaArgument *argument = arguments.at(i); 3622 const AbstractMetaArgument *argument = arguments.at(i);