[Top][All Lists]
[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;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [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,
Rhys Weatherley <address@hidden> <=