#include #include "AST.h" #include "CodeContext.h" #include "CfHeader.h" #include "CfSource.h" #include "aux-code.h" #include "decls.h" #include "interface.h" #include "lgMacro.h" #include "lower.h" #include "code.h" extern void resetPerFileTempCounters(); extern string stringifyTypeFlags(ClassDecl *cl); void InterfaceDeclNode::codeGen() { resetPerFileTempCounters(); // reset temp counters when starting each source file to // prevent spurious recompilation of unchanged source files ClassDecl &declaration = *decl(); const CtType &descriptorType = declaration.cDescriptorType(); const string descriptorName = declaration.cDescriptorName(); const CtType &longName = decl()->cType(); const string classStaticFieldsStructName = declaration.cStaticFieldsStructName(); const string typeFlags = stringifyTypeFlags(decl()); // Declarations { CfHeader os( declaration.cType() ); os << "\n/* ***** " << decl()->fullName() << " generated header file ***** */\n\n"; declaration.includeSupers( os ); declaration.cType().define( os ); os << "extern " << descriptorType << ' ' << descriptorName << ";\n" << "\nextern void " << MANGLE_CLASS_INIT(<<, longName) << "();\n"; foriter (member, members()->allChildren(), ChildIter) if (isMethodSignatureNode(*member)) { const MethodDecl &decl = static_cast(*(*member)->decl()); os << "#define IFACE_DISPATCH_" << decl.cMethodNameStatic() << "(ci) ((" << cMethodTypeString( decl ) << ") " << lgMacro( "IFACE_DISPATCH", decl.modifiers() & Local ) << "(ci, " << FindIntfMethodId( decl ) << "))\n"; } os << "struct " << descriptorName << "_static_fields_struct {\n"; emitStaticFields(declaration, staticFieldDecl, os); // some linkers choke if we try to declare struct variables with zero size, // so make sure we have at least one byte in here: os << "char _pad; /* padding to prevent zero-size structs */\n"; os << "};\n"; os << "extern struct " << descriptorName << "_static_fields_struct " << "STATIC_DEF(" << classStaticFieldsStructName << ");\n"; } // Definitions { CfSource os( declaration.cType() ); os << "\n/* ***** " << decl()->fullName() << " generated source file ***** */\n\n"; declaration.includeSelf( os ); declaration.includeRequirements( os ); const char *listName = declaration.emitInterfaceList( os ); os << descriptorType << ' ' << descriptorName << " = {\n" << " { &" << JavaLangClassDecl->cDescriptorName() << " },\n" << " NULL,\n" << " Interface,\n" << " " << typeFlags << ",\n" << listName << "\n};\n\n"; os << "struct " << descriptorName << "_static_fields_struct " << "STATIC_DEF(" << classStaticFieldsStructName << ");\n"; // forward declare the string table, currently of unknown size os.declare( os ); os << "static void " << MANGLE_CLASS_BUILDST(<<, longName) << "();\n"; os << "\n/* --- " << decl()->fullName() << " Class Initializer --- */\n\n"; os << "#undef __TI_CURRENT_FUNCTION__\n"; os << "#define __TI_CURRENT_FUNCTION__ \"" << decl()->fullName() << ".\"\n"; os << "void " << MANGLE_CLASS_INIT(<<, longName) << "() {\n"; os << "TI_BEGIN_FUNCTION\n"; { CodeContext subcontext( os ); #if 0 /* PR 809 */ subcontext << "#ifdef HAVE_MONITORS\n" << "if (MYBOXPROC == 0) " << "monitor_init( &" << decl()->cDescriptorName() << ".class_object.monitor);\n" << "#endif /*HAVE_MONITORS*/\n"; #endif subcontext << MANGLE_CLASS_BUILDST(<<, longName) << "();\n"; subcontext << "if (MYBOXPROC == 0) " << decl()->cDescriptorName() << ".class_name = java_string_build_8(\"" << decl()->fullName() << "\");\n"; subcontext << "if (MYBOXPROC == 0) " << "ti_register_class((type_header*)&" << decl()->cDescriptorName() << ");\n"; // Inits have already been encapsulated into child 0 in lowering. (static_cast(members()->child(0)->block()))->emitStatement(subcontext); subcontext << "TO_GLOBALB_STATIC( STATIC_REF(" << classStaticFieldsStructName << "," << MANGLE_FIELD(<<, string("class"), longName) << "), 0, " << "&(" << decl()->cDescriptorName() << ".class_object));" << endCline; } os << "}\n\n"; os << "\n/* --- " << decl()->fullName() << " Class String-table builder --- */\n\n"; os << "#undef __TI_CURRENT_FUNCTION__\n"; os << "#define __TI_CURRENT_FUNCTION__ \"" << decl()->fullName() << ".\"\n"; os << "static void " << MANGLE_CLASS_BUILDST(<<, longName) << "() {\n"; os << "TI_BEGIN_FUNCTION\n"; { CodeContext context( os ); os.internAll( context ); } os << "}\n\n"; } }