51 |
/* |
/* |
52 |
* Forward declaration. |
* Forward declaration. |
53 |
*/ |
*/ |
54 |
static int LayoutClass(ILClass *info, LayoutInfo *layout); |
static int LayoutClass(ILExecProcess *process, ILClass *info, LayoutInfo *layout); |
55 |
|
|
56 |
/* |
/* |
57 |
* Get the layout information for a type. Returns zero |
* Get the layout information for a type. Returns zero |
58 |
* if there is something wrong with the type. |
* if there is something wrong with the type. |
59 |
*/ |
*/ |
60 |
static int LayoutType(ILType *type, LayoutInfo *layout) |
static int LayoutType(ILExecProcess *process, ILType *type, LayoutInfo *layout) |
61 |
{ |
{ |
62 |
type = ILTypeStripPrefixes(type); |
type = ILTypeStripPrefixes(type); |
63 |
if(ILType_IsPrimitive(type)) |
if(ILType_IsPrimitive(type)) |
186 |
ILType *synType = ILClassGetSynType(classInfo); |
ILType *synType = ILClassGetSynType(classInfo); |
187 |
if(synType == 0) |
if(synType == 0) |
188 |
{ |
{ |
189 |
return LayoutClass(classInfo, layout); |
return LayoutClass(process, classInfo, layout); |
190 |
} |
} |
191 |
else |
else |
192 |
{ |
{ |
193 |
return LayoutType(ILTypeStripPrefixes(synType), layout); |
return LayoutType(process, ILTypeStripPrefixes(synType), layout); |
194 |
} |
} |
195 |
} |
} |
196 |
else |
else |
452 |
* This is necessary because we convert methods one at a time, instead of |
* This is necessary because we convert methods one at a time, instead of |
453 |
* class at a time like RVM does. |
* class at a time like RVM does. |
454 |
*/ |
*/ |
455 |
static void BuildIMT(ILClass *info, ILClassPrivate *classPrivate) |
static void BuildIMT(ILExecProcess *process, ILClass *info, |
456 |
|
ILClassPrivate *classPrivate) |
457 |
{ |
{ |
|
ILExecThread *thread; |
|
|
ILExecProcess *process; |
|
458 |
ILImplPrivate *impl; |
ILImplPrivate *impl; |
459 |
ILClassPrivate *implPrivate; |
ILClassPrivate *implPrivate; |
460 |
ILUInt32 posn, size; |
ILUInt32 posn, size; |
461 |
ILUInt32 vtableIndex; |
ILUInt32 vtableIndex; |
462 |
ILUInt32 imtIndex; |
ILUInt32 imtIndex; |
463 |
|
|
|
/* Find the process that owns the class */ |
|
|
thread = ILExecThreadCurrent(); |
|
|
if(!thread) |
|
|
{ |
|
|
return; |
|
|
} |
|
|
process = thread->process; |
|
|
|
|
464 |
/* Is this class itself an interface? */ |
/* Is this class itself an interface? */ |
465 |
if(ILClass_IsInterface(info)) |
if(ILClass_IsInterface(info)) |
466 |
{ |
{ |
537 |
* Lay out a particular class. Returns zero if there |
* Lay out a particular class. Returns zero if there |
538 |
* is something wrong with the class definition. |
* is something wrong with the class definition. |
539 |
*/ |
*/ |
540 |
static int LayoutClass(ILClass *info, LayoutInfo *layout) |
static int LayoutClass(ILExecProcess *process, ILClass *info, LayoutInfo *layout) |
541 |
{ |
{ |
542 |
ILClassLayout *classLayout; |
ILClassLayout *classLayout; |
543 |
ILFieldLayout *fieldLayout; |
ILFieldLayout *fieldLayout; |
591 |
garbage collector so that the object pointers that |
garbage collector so that the object pointers that |
592 |
it contains will be visible to the collector */ |
it contains will be visible to the collector */ |
593 |
classPrivate = (ILClassPrivate *) |
classPrivate = (ILClassPrivate *) |
594 |
(ILGCAllocPersistent(sizeof(ILClassPrivate))); |
(ILGCAlloc(sizeof(ILClassPrivate))); |
595 |
if(!classPrivate) |
if(!classPrivate) |
596 |
{ |
{ |
597 |
return 0; |
return 0; |
600 |
info->userData = (void *)classPrivate; |
info->userData = (void *)classPrivate; |
601 |
classPrivate->inLayout = 1; |
classPrivate->inLayout = 1; |
602 |
classPrivate->gcTypeDescriptor = IL_MAX_NATIVE_UINT; |
classPrivate->gcTypeDescriptor = IL_MAX_NATIVE_UINT; |
603 |
|
classPrivate->process = process; |
604 |
|
classPrivate->nextClassPrivate = process->firstClassPrivate; |
605 |
|
process->firstClassPrivate = classPrivate; |
606 |
|
|
607 |
} |
} |
608 |
|
|
609 |
/* Lay out the parent class first */ |
/* Lay out the parent class first */ |
611 |
{ |
{ |
612 |
/* Use "ILClassGetParent" to resolve cross-image links */ |
/* Use "ILClassGetParent" to resolve cross-image links */ |
613 |
parent = ILClassGetParent(info); |
parent = ILClassGetParent(info); |
614 |
if(!LayoutClass(parent, layout)) |
if(!LayoutClass(process, parent, layout)) |
615 |
{ |
{ |
616 |
info->userData = 0; |
info->userData = 0; |
617 |
return 0; |
return 0; |
638 |
implements = info->implements; |
implements = info->implements; |
639 |
while(implements != 0) |
while(implements != 0) |
640 |
{ |
{ |
641 |
if(!LayoutClass(ILClassResolve(implements->interface), &typeLayout)) |
if(!LayoutClass(process, ILClassResolve(implements->interface), &typeLayout)) |
642 |
{ |
{ |
643 |
info->userData = 0; |
info->userData = 0; |
644 |
return 0; |
return 0; |
693 |
if((field->member.attributes & IL_META_FIELDDEF_STATIC) == 0) |
if((field->member.attributes & IL_META_FIELDDEF_STATIC) == 0) |
694 |
{ |
{ |
695 |
/* Get the layout information for this field's type */ |
/* Get the layout information for this field's type */ |
696 |
if(!LayoutType(field->member.signature, &typeLayout)) |
if(!LayoutType(process, field->member.signature, &typeLayout)) |
697 |
{ |
{ |
698 |
info->userData = 0; |
info->userData = 0; |
699 |
return 0; |
return 0; |
822 |
if(!fieldRVA || !allowRVALayout) |
if(!fieldRVA || !allowRVALayout) |
823 |
{ |
{ |
824 |
/* Get the layout information for this field's type */ |
/* Get the layout information for this field's type */ |
825 |
if(!LayoutType(field->member.signature, &typeLayout)) |
if(!LayoutType(process, field->member.signature, &typeLayout)) |
826 |
{ |
{ |
827 |
info->userData = 0; |
info->userData = 0; |
828 |
return 0; |
return 0; |
833 |
function has acquired the metadata lock on the process */ |
function has acquired the metadata lock on the process */ |
834 |
if(ILFieldIsThreadStatic(field)) |
if(ILFieldIsThreadStatic(field)) |
835 |
{ |
{ |
|
ILExecThread *thread = ILExecThreadCurrent(); |
|
|
if(!thread) |
|
|
{ |
|
|
/* This shouldn't happen if the engine has |
|
|
been initialized correctly */ |
|
|
continue; |
|
|
} |
|
836 |
/* Store the slot number in the "offset" field and |
/* Store the slot number in the "offset" field and |
837 |
the field size in the "nativeOffset" field */ |
the field size in the "nativeOffset" field */ |
838 |
field->offset = (thread->process->numThreadStaticSlots)++; |
field->offset = (process->numThreadStaticSlots)++; |
839 |
field->nativeOffset = typeLayout.size; |
field->nativeOffset = typeLayout.size; |
840 |
continue; |
continue; |
841 |
} |
} |
980 |
|
|
981 |
#ifdef IL_USE_IMTS |
#ifdef IL_USE_IMTS |
982 |
/* Build the interface method table for this class */ |
/* Build the interface method table for this class */ |
983 |
BuildIMT(info, classPrivate); |
BuildIMT(process, info, classPrivate); |
984 |
#endif |
#endif |
985 |
|
|
986 |
/* Done */ |
/* Done */ |
987 |
return 1; |
return 1; |
988 |
} |
} |
989 |
|
|
990 |
int _ILLayoutClass(ILClass *info) |
int _ILLayoutClass(ILExecProcess *process, ILClass *info) |
991 |
{ |
{ |
992 |
LayoutInfo layout; |
LayoutInfo layout; |
993 |
return LayoutClass(info, &layout); |
return LayoutClass(process, info, &layout); |
994 |
} |
} |
995 |
|
|
996 |
ILUInt32 _ILLayoutClassReturn(ILClass *info, ILUInt32 *alignment) |
ILUInt32 _ILLayoutClassReturn(ILExecProcess *process, ILClass *info, ILUInt32 *alignment) |
997 |
{ |
{ |
998 |
LayoutInfo layout; |
LayoutInfo layout; |
999 |
if(LayoutClass(info, &layout)) |
if(LayoutClass(process, info, &layout)) |
1000 |
{ |
{ |
1001 |
*alignment = layout.alignment; |
*alignment = layout.alignment; |
1002 |
return layout.size; |
return layout.size; |
1021 |
} |
} |
1022 |
} |
} |
1023 |
|
|
1024 |
ILUInt32 _ILSizeOfTypeLocked(ILType *type) |
ILUInt32 _ILSizeOfTypeLocked(ILExecProcess *process, ILType *type) |
1025 |
{ |
{ |
1026 |
LayoutInfo layout; |
LayoutInfo layout; |
1027 |
if(!LayoutType(type, &layout)) |
if(!LayoutType(process, type, &layout)) |
1028 |
{ |
{ |
1029 |
return 0; |
return 0; |
1030 |
} |
} |
1039 |
if(!ILType_IsValueType(type)) |
if(!ILType_IsValueType(type)) |
1040 |
{ |
{ |
1041 |
/* We can take a shortcut because the type is not a value type */ |
/* We can take a shortcut because the type is not a value type */ |
1042 |
return _ILSizeOfTypeLocked(type); |
return _ILSizeOfTypeLocked(_ILExecThreadProcess(thread), type); |
1043 |
} |
} |
1044 |
else |
else |
1045 |
{ |
{ |
1046 |
/* We have to lock down the metadata first */ |
/* We have to lock down the metadata first */ |
1047 |
ILUInt32 size; |
ILUInt32 size; |
1048 |
IL_METADATA_WRLOCK(thread); |
IL_METADATA_WRLOCK(_ILExecThreadProcess(thread)); |
1049 |
size = _ILSizeOfTypeLocked(type); |
size = _ILSizeOfTypeLocked(_ILExecThreadProcess(thread), type); |
1050 |
IL_METADATA_UNLOCK(thread); |
IL_METADATA_UNLOCK(_ILExecThreadProcess(thread)); |
1051 |
return size; |
return size; |
1052 |
} |
} |
1053 |
} |
} |