Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

/ray/src/vm/input/asmfile.cc

Go to the documentation of this file.
00001 /*
00002  * vm/input/asmfile.cc
00003  * 
00004  * VM assembler input file. 
00005  * 
00006  * Copyright (c) 2004 by Wolfgang Wieser ] wwieser (a) gmx <*> de [ 
00007  * 
00008  * This file may be distributed and/or modified under the terms of the 
00009  * GNU General Public License version 2 as published by the Free Software 
00010  * Foundation. (See COPYING.GPL for details.)
00011  * 
00012  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00013  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00014  * 
00015  */
00016 
00017 #include "asmfile.h"
00018 #include "classinfo.h"
00019 #include <lib/message/message.h>
00020 
00021 
00022 namespace VM
00023 {
00024 
00025 AssemblerFile::Config::Config()
00026 {
00027     // For now, we read (by default) all we can :)
00028     read_non_pointer_members=1;
00029     read_member_var_names=1;
00030     
00031     emit_all_namespaces=0;  // should be 0
00032     emit_all_classinfo=0;   // should be 0
00033 }
00034 
00035 //------------------------------------------------------------------------------
00036 
00037 NamespaceInfo::SymbolEntryB *AssemblerFile::InternalSymbolList::LookupStore(
00038     SymRef symref)
00039 {
00040     // Only for internal symrefs. 
00041     if(symref>=0)  return(NULL);
00042     
00043     // First see if we already have it. 
00044     NamespaceInfo::SymbolEntryB *seb=sym_map.lookup(symref);
00045     if(!seb)
00046     {
00047         // Allocate a new one. 
00048         sym_stor.PushHead(NamespaceInfo::SymbolEntryB());
00049         seb=sym_stor.head();
00050         
00051         seb->symref=symref;
00052         
00053         // Put into map: 
00054         NamespaceInfo::SymbolEntryB _unused_ *known=sym_map.AddNode(seb);
00055         Assert(!known);
00056     }
00057     
00058     return(seb);
00059 }
00060 
00061 AssemblerFile::InternalSymbolList::InternalSymbolList() : 
00062     sym_stor(/*chunk_size=*/32,/*keep_old=*/0),
00063     sym_map()
00064 {
00065     // nothing to do
00066 }
00067 
00068 //------------------------------------------------------------------------------
00069 
00070 ClassInfoIE *AssemblerFile::InternalClassList::LookupStore(TypeID tid)
00071 {
00072     // Only for internal TypeIDs. 
00073     if(tid>=0)  return(NULL);
00074     
00075     // First see if we already have it. 
00076     ClassInfoIE *cie=class_map.lookup(tid);
00077     if(!cie)
00078     {
00079         // Allocate a new one. 
00080         class_stor.PushHead(ClassInfoIE(tid));
00081         cie=class_stor.head();
00082         
00083         // Put into map: 
00084         ClassInfoIE _unused_ *known=class_map.AddNode(cie);
00085         Assert(!known);
00086     }
00087     
00088     return(cie);
00089 }
00090 
00091 AssemblerFile::InternalClassList::InternalClassList() : 
00092     class_stor(/*chunk_size=*/32,/*keep_old=*/0),
00093     class_map()
00094 {
00095     // nothing to do
00096 }
00097 
00098 //------------------------------------------------------------------------------
00099 
00100 int AssemblerFile::_ResolveIDsNamespaceLocal_Recursive(NamespaceInfo *root)
00101 {
00102     int errcnt=0;
00103     
00104     // Process this node. 
00105     switch(root->nstype)
00106     {
00107         case NamespaceInfo::NSClass:
00108         {
00109             ClassInfo *croot=static_cast<ClassInfo*>(root);
00110             
00111             // Look up base entries. 
00112             for(uint32 i=0,iend=croot->base.n(); i<iend; i++)
00113             {
00114                 ClassInfo::BaseEntry *be=&croot->base[i];
00115                 if(be->tid<0)
00116                 {
00117                     be->ci=internal_classes.LookupStore(be->tid);
00118                 }
00119                 else
00120                 {
00121                     ClassInfo *ci=tid2classinfo.lookup(be->tid);
00122                     if(!ci)
00123                     {
00124                         Error(croot->asm_loc,
00125                             "undeclared typeid %d in base spec of \"%s\"",
00126                             (int)be->tid,croot->CompleteName().str());
00127                         ++errcnt;
00128                     }
00129                     be->ci=ci;
00130                 }
00131             }
00132             
00133             // Look up vtable entries: 
00134             for(uint32 i=0,iend=croot->vtable.n(); i<iend; i++)
00135             {
00136                 if(croot->vtable[i].symref<0)
00137                 {
00138                     // "Lookup" of internal symref in vtable. 
00139                     // (Just allocate one if not yet allocated.)
00140                     croot->vtable[i].se=internal_symbols.LookupStore(
00141                         croot->vtable[i].symref);
00142                 }
00143                 else
00144                 {
00145                     NamespaceInfo::SymbolEntryE *se=symref2symbol.lookup(
00146                         croot->vtable[i].symref);
00147                     if(!se)
00148                     {
00149                         Error(filename,
00150                             "undefined symref $%d in vtable of %s",
00151                             (int)croot->vtable[i].symref,
00152                             croot->CompleteName().str());
00153                         ++errcnt;
00154                     }
00155                     croot->vtable[i].se=se;
00156                 }
00157             }
00158             
00159         }   // NO BREAK; fall through. 
00160         case NamespaceInfo::NSNamespace:
00161             // For the plain namespace info, there is nothing to do. 
00162             break;
00163         default:  Assert(0);
00164     }
00165     
00166     // Recurse: 
00167     for(NamespaceInfo *i=root->down.first(); i; i=i->next)
00168     {  errcnt+=_ResolveIDsNamespaceLocal_Recursive(i);  }
00169     
00170     return(errcnt);
00171 }
00172 
00173 
00174 int AssemblerFile::_ResolveSymrefsInGlobal(_GlobVars *gvar)
00175 {
00176     int errcnt=0;
00177     for(GlobalVarList::Iterator i(gvar->globvarq); i; i++)
00178     {
00179         // Global storage may not contain internal symbols. 
00180         Assert((*i)->symref>=0);
00181         
00182         NamespaceInfo::SymbolEntryE *se=symref2symbol.lookup((*i)->symref);
00183         if(!se)
00184         {
00185             Error(filename,
00186                 "undefined symref $%d in global",
00187                 (int)(*i)->symref);
00188             ++errcnt;
00189         }
00190         (*i)->se=se;
00191     }
00192     
00193     return(errcnt);
00194 }
00195 
00196 
00197 int AssemblerFile::ResolveIDsNamespaceLocal()
00198 {
00199     int errcnt=0;
00200     
00201     // TypeIDs in base entries and SymRefs in vtables: 
00202     if(nspc_root)
00203     {  errcnt+=_ResolveIDsNamespaceLocal_Recursive(nspc_root);  }
00204     
00205     // SymRefs in global vars. 
00206     errcnt+=_ResolveSymrefsInGlobal(&gvar_v);
00207     errcnt+=_ResolveSymrefsInGlobal(&gvar_p);
00208     
00209     // SymRefs to functions in function program storage (one per function). 
00210     for(ProgramStorage::Function *pfunc=program.FirstFunction(); 
00211         pfunc; pfunc=pfunc->next)
00212     {
00213         // .init and .start may have phantasy symrefs...
00214         // (Actually, these do not have SymRefs but initially get the 
00215         // *se pointer set, so there is nothing to look up anyways.) 
00216         if(pfunc==slabel_init.pfunc || pfunc==slabel_start.pfunc) continue;
00217         
00218         Assert(pfunc->symref>=0);
00219         NamespaceInfo::SymbolEntryE *sent=symref2symbol.lookup(
00220             pfunc->symref);
00221         if(!sent)
00222         {
00223             Error(pfunc->loc,
00224                 "undefined function symref $%d in program section",
00225                 (int)pfunc->symref);
00226             ++errcnt;
00227         }
00228         pfunc->se=sent;
00229     }
00230     
00231     return(errcnt);
00232 }
00233 
00234 
00235 int AssemblerFile::ParseFile(const TLString &/*fname*/,SError &/*error*/,
00236     uint32 /*file_num*/)
00237 {
00238     CritAssert(0);  // must be overridden
00239     return(-1);
00240 }
00241 
00242 
00243 int AssemblerFile::WriteFile(const TLString &/*fname*/,SError &/*error*/)
00244 {
00245     CritAssert(0);  // must be overridden
00246     return(-1);
00247 }
00248 
00249 
00250 AssemblerFile::AssemblerFile() : 
00251     cfg(),
00252     filename(),
00253     file_num(0),
00254     gvar_v(),
00255     gvar_p(),
00256     program(),
00257     tid2classinfo(),
00258     symref2symbol(),
00259     internal_symbols(),
00260     internal_classes(),
00261     symref2function(),
00262     symref2globvar()
00263 {
00264     nspc_root=NULL;
00265     
00266     slabel_start.pfunc=NULL;
00267     slabel_init.pfunc=NULL;
00268 }
00269 
00270 AssemblerFile::~AssemblerFile()
00271 {
00272     // Recursively delete tree: 
00273     DELETE(nspc_root);
00274     
00275     // gvar_{v,p}.globvar tidy up themselves. 
00276     // program storage cleans up itself. 
00277     // tid2classinfo, symref2symbol, internal_symbols, internal_classes, 
00278     //    symref2function, symref2globvar tidy up themselves. 
00279     
00280     // The program storage takes care to free these: 
00281     slabel_start.pfunc=NULL;
00282     slabel_init.pfunc=NULL;
00283 }
00284 
00285 }  // end of namespace VM

Generated on Sat Feb 19 22:33:46 2005 for Ray by doxygen 1.3.5