dotgnu-pnet-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Dotgnu-pnet-commits] pnet/image context.c, 1.14, 1.15 image.h, 1.33, 1


From: Rhys Weatherley <address@hidden>
Subject: [Dotgnu-pnet-commits] pnet/image context.c, 1.14, 1.15 image.h, 1.33, 1.34 link.c, 1.30, 1.31 meta_build.c, 1.33, 1.34 pecoff_loader.c, 1.20, 1.21
Date: Sun, 23 Nov 2003 02:30:09 +0000

Update of /cvsroot/dotgnu-pnet/pnet/image
In directory subversions:/tmp/cvs-serv10629/image

Modified Files:
        context.c image.h link.c meta_build.c pecoff_loader.c 
Log Message:


Add a "redo" list to the program loading process, to allow recursive
TypeRef's and MemberRef's to be resolved in a final pass after all
recursive images have been loaded.


Index: meta_build.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/image/meta_build.c,v
retrieving revision 1.33
retrieving revision 1.34
diff -C2 -d -r1.33 -r1.34
*** meta_build.c        14 Oct 2003 04:12:21 -0000      1.33
--- meta_build.c        23 Nov 2003 02:30:07 -0000      1.34
***************
*** 385,388 ****
--- 385,426 ----
  
  /*
+  * Add a program item to the redo list.  Returns zero if out of memory.
+  */
+ static int AddToRedoList(ILContext *context, ILProgramItem *item)
+ {
+       ILProgramItem **items;
+       if(context->numRedoItems >= context->maxRedoItems)
+       {
+               items = (ILProgramItem **)ILRealloc
+                       (context->redoItems,
+                        sizeof(ILProgramItem *) * (context->maxRedoItems + 
64));
+               if(!items)
+               {
+                       return 0;
+               }
+               context->redoItems = items;
+               context->maxRedoItems += 64;
+       }
+       context->redoItems[(context->numRedoItems)++] = item;
+       return 1;
+ }
+ 
+ /*
+  * Determine if a program item is currently on the redo list.
+  */
+ static int IsOnRedoList(ILContext *context, ILProgramItem *item)
+ {
+       ILUInt32 posn;
+       for(posn = 0; posn < context->numRedoItems; ++posn)
+       {
+               if(context->redoItems[posn] == item)
+               {
+                       return 1;
+               }
+       }
+       return 0;
+ }
+ 
+ /*
   * Resolve the TypeRef's.  Returns zero if OK, -1 if a
   * second-phase scan is needed for TypeRef's to this module.
***************
*** 501,504 ****
--- 539,552 ----
                                                (importScope, name, namespace);
                                }
+                               else if(IsOnRedoList(image->context, scope))
+                               {
+                                       /* The nesting parent is marked for 
redo,
+                                          so mark the child for redo also */
+                                       if(!AddToRedoList(image->context, 
scope))
+                                       {
+                                               return IL_LOADERR_MEMORY;
+                                       }
+                                       continue;
+                               }
                        }
                        break;
***************
*** 519,527 ****
                                if(importImage)
                                {
!                                       importScope = 
ILClassGlobalScope(importImage);
!                                       if(importScope)
                                        {
!                                               importInfo = ILClassLookup
!                                                       (importScope, name, 
namespace);
                                        }
                                }
--- 567,588 ----
                                if(importImage)
                                {
!                                       if(importImage == image || 
!(importImage->loading))
                                        {
!                                               importScope = 
ILClassGlobalScope(importImage);
!                                               if(importScope)
!                                               {
!                                                       importInfo = 
ILClassLookup
!                                                               (importScope, 
name, namespace);
!                                               }
!                                       }
!                                       else
!                                       {
!                                               /* We cannot resolve this 
TypeRef yet.  We queue it
!                                                  on the "redo" list to be 
redone later */
!                                               
if(!AddToRedoList(image->context, &(info->programItem)))
!                                               {
!                                                       return 
IL_LOADERR_MEMORY;
!                                               }
!                                               continue;
                                        }
                                }
***************
*** 2456,2461 ****
                                {
                                        /* Failed to resolve the class */
!                                       member = 0;
!                                       break;
                                }
                                resolvedMember = 0;
--- 2517,2538 ----
                                {
                                        /* Failed to resolve the class */
!                                       if(resolvedClass &&
!                                          IsOnRedoList(image->context,
!                                                                   
&(resolvedClass->programItem)))
!                                       {
!                                               /* The TypeRef is on the redo 
list, so add
!                                                  the MemberRef to the redo 
list also */
!                                               
if(!AddToRedoList(image->context,
!                                                                               
  &(member->programItem)))
!                                               {
!                                                       return 
IL_LOADERR_MEMORY;
!                                               }
!                                               break;
!                                       }
!                                       else
!                                       {
!                                               member = 0;
!                                               break;
!                                       }
                                }
                                resolvedMember = 0;
***************
*** 3535,3538 ****
--- 3612,3844 ----
        }
        return 0;
+ }
+ 
+ /*
+  * Redo a "TypeRef" token that was left dangling because of
+  * recursive assembly references.
+  */
+ static int RedoTypeRef(ILImage *image, ILClass *classInfo)
+ {
+       ILProgramItem *scope = ILClassGetScope(classInfo);
+       ILProgramItem *importScope;
+       ILImage *importImage;
+       ILClass *importInfo = 0;
+       switch(ILProgramItem_Token(scope) & IL_META_TOKEN_MASK)
+       {
+               case IL_META_TOKEN_TYPE_REF:
+               {
+                       /* Nested type within a foreign assembly */
+                       importScope = _ILProgramItemLinkedTo(scope);
+                       if(importScope)
+                       {
+                               importInfo = ILClassLookup
+                                       (importScope, ILClass_Name(classInfo),
+                                        ILClass_Namespace(classInfo));
+                       }
+               }
+               break;
+ 
+               case IL_META_TOKEN_ASSEMBLY_REF:
+               {
+                       /* Type is imported from a foreign assembly */
+                       importImage = ILAssemblyToImage((ILAssembly *)scope);
+                       if(importImage)
+                       {
+                               importScope = ILClassGlobalScope(importImage);
+                               if(importScope)
+                               {
+                                       importInfo = ILClassLookup
+                                               (importScope, 
ILClass_Name(classInfo),
+                                                ILClass_Namespace(classInfo));
+                               }
+                       }
+               }
+               break;
+       }
+       if(importInfo)
+       {
+               /* Link "info" to "importInfo" */
+               if(!_ILProgramItemLink(&(classInfo->programItem),
+                                                          
&(importInfo->programItem)))
+               {
+                       return IL_LOADERR_MEMORY;
+               }
+               else
+               {
+                       return 0;
+               }
+       }
+       else
+       {
+               /* Could not resolve the type */
+       #if IL_DEBUG_META
+               ReportResolveError(image, scope->token,
+                                                  ILClass_Name(classInfo),
+                                                  
ILClass_Namespace(classInfo));
+       #endif
+               return IL_LOADERR_UNRESOLVED;
+       }
+ }
+ 
+ /*
+  * Redo a "MemberRef" token that was left dangling because of
+  * recursive assembly references.
+  */
+ static int RedoMemberRef(ILImage *image, ILMember *member)
+ {
+       ILToken token = ILMember_Token(member);
+       ILClass *classInfo = ILMember_Owner(member);
+       const char *name = ILMember_Name(member);
+       ILClass *resolvedClass;
+       ILMember *resolvedMember;
+       int isMethod = ILMember_IsMethod(member);
+       ILType *type = ILMember_Signature(member);
+       ILMethod *method;
+ 
+       /* Resolve the class the contains the member */
+       resolvedClass = ILClassResolve(classInfo);
+       if(!resolvedClass || ILClassIsRef(resolvedClass))
+       {
+               goto reportError;
+       }
+ 
+       /* Walk the class hierarchy looking for the member */
+       resolvedMember = 0;
+       while(resolvedClass != 0)
+       {
+               resolvedMember = 0;
+               while((resolvedMember = ILClassNextMember
+                                       (resolvedClass, resolvedMember)) != 0)
+               {
+                       if(!strcmp(ILMember_Name(resolvedMember), name))
+                       {
+                               if(isMethod && 
ILMember_IsMethod(resolvedMember))
+                               {
+                                       if(ILTypeIdentical
+                                               
(ILMember_Signature(resolvedMember), type))
+                                       {
+                                               break;
+                                       }
+                               }
+                               else if(!isMethod && 
ILMember_IsField(resolvedMember))
+                               {
+                                       if(ILTypeIdentical
+                                               
(ILMember_Signature(resolvedMember), type))
+                                       {
+                                               break;
+                                       }
+                               }
+                       }
+               }
+               if(resolvedMember != 0)
+               {
+                       break;
+               }
+               resolvedClass = ILClass_Parent(resolvedClass);
+       }
+       if(!resolvedMember)
+       {
+               /* Failed to resolve the member */
+               if(ILType_IsComplex(type) &&
+                  ILType_Kind(type) == (IL_TYPE_COMPLEX_METHOD |
+                                                                
IL_TYPE_COMPLEX_METHOD_SENTINEL))
+               {
+                       /* Create a local reference to a vararg call site */
+                       method = ILMethodCreate(classInfo, token, name, 0);
+                       if(!method)
+                       {
+                               return IL_LOADERR_MEMORY;
+                       }
+                       ILMethodSetCallConv(method, ILType_CallConv(type));
+                       ILMemberSetSignature((ILMember *)method, type);
+                       return 0;
+               }
+               goto reportError;
+       }
+       if(!_ILProgramItemLink(&(member->programItem),
+                                                  
&(resolvedMember->programItem)))
+       {
+               return IL_LOADERR_MEMORY;
+       }
+       return 0;
+ 
+       /* Report an error in the member resolution process */
+ reportError:
+ #if IL_DEBUG_META
+       if(classInfo)
+       {
+               if(classInfo->className->namespace &&
+                  !strcmp(classInfo->className->namespace, "$Synthetic"))
+               {
+                       fprintf(stderr,
+                                       "token 0x%08lX: member `%s.%s' not 
found\n",
+                                       (unsigned long)token, 
classInfo->className->name, name);
+               }
+               else
+               {
+                       fprintf(stderr,
+                                       "token 0x%08lX: member `%s%s%s.%s' not 
found\n",
+                                       (unsigned long)token,
+                                       (classInfo->className->namespace
+                                                       ? 
classInfo->className->namespace : ""),
+                                       (classInfo->className->namespace ? "." 
: ""),
+                                       classInfo->className->name, name);
+               }
+       }
+       else
+       {
+               fprintf(stderr,
+                               "token 0x%08lX: member %s not found\n",
+                               (unsigned long)token, name);
+       }
+ #endif
+       return IL_LOADERR_UNRESOLVED;
+ }
+ 
+ int _ILImageRedoReferences(ILContext *context)
+ {
+       ILUInt32 posn;
+       ILProgramItem *item;
+       int error = 0;
+       int error2;
+ 
+       /* Process the TypeRef's that are registered to be redone */
+       for(posn = 0; posn < context->numRedoItems; ++posn)
+       {
+               item = context->redoItems[posn];
+               switch(item->token & IL_META_TOKEN_MASK)
+               {
+                       case IL_META_TOKEN_TYPE_REF:
+                       {
+                               error2 = RedoTypeRef(item->image, (ILClass 
*)item);
+                               if(!error)
+                               {
+                                       error = error2;
+                               }
+                       }
+                       break;
+               }
+       }
+ 
+       /* Process the MemberRef's that are registered to be redone.
+          Must be done after all TypeRef's because a member's signature
+          may refer to a TypeRef that appears later in the redo list */
+       for(posn = 0; posn < context->numRedoItems; ++posn)
+       {
+               item = context->redoItems[posn];
+               switch(item->token & IL_META_TOKEN_MASK)
+               {
+                       case IL_META_TOKEN_MEMBER_REF:
+                       {
+                               error2 = RedoMemberRef(item->image, (ILMember 
*)item);
+                               if(!error)
+                               {
+                                       error = error2;
+                               }
+                       }
+                       break;
+               }
+       }
+       return error;
  }
  

Index: image.h
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/image/image.h,v
retrieving revision 1.33
retrieving revision 1.34
diff -C2 -d -r1.33 -r1.34
*** image.h     14 Oct 2003 04:12:21 -0000      1.33
--- image.h     23 Nov 2003 02:30:07 -0000      1.34
***************
*** 92,95 ****
--- 92,103 ----
        /* User data for the runtime engine */
        void *userData;
+ 
+       /* Reference "redo" table.  This is the list of references that
+          must be redone to fix up recursive TypeRef's and MemberRef's */
+       ILProgramItem **redoItems;
+       ILUInt32                numRedoItems;
+       ILUInt32                maxRedoItems;
+       ILUInt32                redoLevel;
+ 
  };
  
***************
*** 170,173 ****
--- 178,182 ----
        int                             blobRefBig : 1; /* Non-zero if 
BLOBREF's are 32-bit */
        int                             guidRefBig : 1; /* Non-zero if 
GUIDREF's are 32-bit */
+       int                             loading : 1;    /* Non-zero if still 
loading metadata */
        ILSectionMap   *map;                    /* Maps virtual to real 
addresses */
        char               *data;                       /* Data that makes up 
the IL image */
***************
*** 472,475 ****
--- 481,490 ----
  int _ILImageBuildMetaStructures(ILImage *image, const char *filename,
                                                                int loadFlags);
+ 
+ /*
+  * Redo TypeRef and MemberRef references that resulted from recursive
+  * assembly references.
+  */
+ int _ILImageRedoReferences(ILContext *context);
  
  /*

Index: pecoff_loader.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/image/pecoff_loader.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -C2 -d -r1.20 -r1.21
*** pecoff_loader.c     17 Nov 2003 09:00:18 -0000      1.20
--- pecoff_loader.c     23 Nov 2003 02:30:07 -0000      1.21
***************
*** 938,953 ****
        (*image)->rsrcSize = rsrcSize;
  
        /* Load the meta information from the image */
        if((flags & IL_LOADFLAG_NO_METADATA) == 0)
        {
!               if((error = _ILImageParseMeta(*image, filename, flags)) != 0)
                {
!                       ILImageDestroy(*image);
!                       return error;
                }
        }
  
        /* The image is loaded and ready to go */
!       return 0;
  }
  
--- 938,978 ----
        (*image)->rsrcSize = rsrcSize;
  
+       /* Mark the metadata as loading so that we can detect TypeRef recursion 
*/
+       (*image)->loading = 1;
+       ++(context->redoLevel);
+ 
        /* Load the meta information from the image */
        if((flags & IL_LOADFLAG_NO_METADATA) == 0)
        {
!               error = _ILImageParseMeta(*image, filename, flags);
!       }
!       else
!       {
!               error = 0;
!       }
! 
!       /* The metadata is now fully loaded for this image */
!       (*image)->loading = 0;
!       if(--(context->redoLevel) == 0 && context->numRedoItems > 0)
!       {
!               /* We've exited all recursive loading levels, so redo queued 
items */
!               if(!error)
                {
!                       error = _ILImageRedoReferences(context);
                }
+ 
+               /* Free the "redo" table, which we no longer need */
+               ILFree(context->redoItems);
+               context->redoItems = 0;
+               context->numRedoItems = 0;
+               context->maxRedoItems = 0;
        }
  
        /* The image is loaded and ready to go */
!       if(error)
!       {
!               ILImageDestroy(*image);
!       }
!       return error;
  }
  

Index: context.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/image/context.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -C2 -d -r1.14 -r1.15
*** context.c   15 Jul 2003 22:17:33 -0000      1.14
--- context.c   23 Nov 2003 02:30:07 -0000      1.15
***************
*** 266,269 ****
--- 266,275 ----
        ILMemPoolDestroy(&(context->typePool));
  
+       /* Destory the redo table */
+       if(context->redoItems)
+       {
+               ILFree(context->redoItems);
+       }
+ 
        /* Destroy the context itself */
        ILFree(context);

Index: link.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/image/link.c,v
retrieving revision 1.30
retrieving revision 1.31
diff -C2 -d -r1.30 -r1.31
*** link.c      10 Nov 2003 06:34:23 -0000      1.30
--- link.c      23 Nov 2003 02:30:07 -0000      1.31
***************
*** 563,566 ****
--- 563,567 ----
        int loadFlags;
        int len, retryLower;
+       ILImage *linkImage;
  
        /* Scan the AssemblyRef table for the assemblies that we require */
***************
*** 569,574 ****
                                (image, IL_META_TOKEN_ASSEMBLY_REF, assem)) != 
0)
        {
!               /* Ignore this assembly reference if we already have it */
!               if(ILContextGetAssembly(image->context, assem->name) != 0)
                {
                        continue;
--- 570,577 ----
                                (image, IL_META_TOKEN_ASSEMBLY_REF, assem)) != 
0)
        {
!               /* Ignore this assembly reference if we already have it and
!                  it isn't marked as "building" */
!               linkImage = ILContextGetAssembly(image->context, assem->name);
!               if(linkImage && linkImage->type != IL_IMAGETYPE_BUILDING)
                {
                        continue;





reply via email to

[Prev in Thread] Current Thread [Next in Thread]