[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[dotgnu-pnet-commits] pnet/image generic_class.c generic_member.c
From: |
Ivan de Jesus Deras Tabora |
Subject: |
[dotgnu-pnet-commits] pnet/image generic_class.c generic_member.c |
Date: |
Fri, 14 Sep 2007 12:09:12 +0000 |
CVSROOT: /sources/dotgnu-pnet
Module name: pnet
Changes by: Ivan de Jesus Deras Tabora <iderashn> 07/09/14 12:09:12
Added files:
image : generic_class.c generic_member.c
Log message:
Added missing generic_class.c and generic_member.c
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/pnet/image/generic_class.c?cvsroot=dotgnu-pnet&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pnet/image/generic_member.c?cvsroot=dotgnu-pnet&rev=1.1
Patches:
Index: generic_class.c
===================================================================
RCS file: generic_class.c
diff -N generic_class.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ generic_class.c 14 Sep 2007 12:09:12 -0000 1.1
@@ -0,0 +1,391 @@
+/*
+ * generic_class.c - Functions related to generic class instances.
+ *
+ * Copyright (C) 2007 Southern Storm Software, Pty Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "program.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ILMethod *ILMethodCreateInstance(ILImage *image,
+ ILMethod
*method,
+ ILClass
*classInfo,
+ ILType
*classTypeArgs,
+ ILType
*methodTypeArgs);
+
+ILParameter *ILParameterCreateInstance(ILParameter *paramDef, ILMethod
*method);
+ILMember *ILMemberCreateInstance(ILMember *memberDef, ILClass *info);
+
+ILClass *ILClassGetUnderlying(ILClass *info)
+{
+ ILType *synType = info->synthetic;
+ if(ILType_IsWith(synType) &&
+ !ILClassIsExpanded(info))
+ {
+ synType = ILTypeGetWithMain(synType);
+ return ILClassFromType(info->programItem.image, 0, synType, 0);
+ }
+ else
+ {
+ return info;
+ }
+}
+
+ILClass *ILClassGetGenericDef(ILClass *info)
+{
+ ILType *type = info->synthetic;
+ if(ILType_IsWith(type))
+ {
+ return ILType_ToClass(ILTypeGetWithMain(type));
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+/*
+ * Expand a class instance.
+ */
+ILClass *ILClassExpand(ILImage *image, ILClass *classInfo,
+ ILType *classArgs, ILType
*methodArgs)
+{
+ ILType *type = ILClassToType(classInfo);
+ return ILClassInstantiate(image, type, classArgs, methodArgs);
+}
+
+/*
+ * Expand the instantiations in a class. Returns zero if out of memory.
+ */
+static int ExpandInstantiations(ILImage *image, ILClass *classInfo,
+ ILType
*classType, ILType *classParams)
+{
+ ILClass *origClass;
+ ILMember *member;
+ ILMethod *newMethod;
+ ILField *newField;
+ ILEvent *newEvent;
+ ILType *signature;
+ ILImplements *impl;
+ ILClass *tempInfo;
+
+ /* Bail out if not a "with" type, since the instantiation would
+ have already been taken care of by "ILClassFromType" */
+ if(!ILType_IsWith(classType))
+ {
+ return 1;
+ }
+
+ /* Find the original class underlying the type */
+ origClass = ILClassFromType(image, 0, ILTypeGetWithMain(classType), 0);
+ if(!origClass)
+ {
+ return 0;
+ }
+ origClass = ILClassResolve(origClass);
+
+ /* Copy across the class attributes */
+ ILClassSetAttrs(classInfo, ~((ILUInt32)0), ILClass_Attrs(origClass));
+
+ /* Mark this class as being expanded, to deal with circularities */
+ classInfo->attributes |= IL_META_TYPEDEF_CLASS_EXPANDED;
+
+ /* Expand the parent class and interfaces */
+ if(origClass->parent)
+ {
+ classInfo->parent = ILClassExpand
+ (image, ILClass_Parent(origClass), classParams, 0);
+ if(!(classInfo->parent))
+ {
+ return 0;
+ }
+ }
+ impl = 0;
+ while((impl = ILClassNextImplements(origClass, impl)) != 0)
+ {
+ tempInfo = ILImplementsGetInterface(impl);
+ tempInfo = ILClassExpand(image, tempInfo, classParams, 0);
+ if(!tempInfo)
+ {
+ return 0;
+ }
+ if(!ILClassAddImplements(classInfo, tempInfo, 0))
+ {
+ return 0;
+ }
+ }
+
+ /* Expand the methods and fields */
+ member = 0;
+ while((member = ILClassNextMember(origClass, member)) != 0)
+ {
+ switch(ILMemberGetKind(member))
+ {
+ case IL_META_MEMBERKIND_METHOD:
+ {
+ newMethod = ILMethodCreateInstance(image,
(ILMethod *)member,
+
classInfo, classParams, 0);
+
+ if(!newMethod)
+ {
+ return 0;
+ }
+ }
+ break;
+
+ case IL_META_MEMBERKIND_FIELD:
+ {
+ /* Create a new field */
+ newField = (ILField
*)ILMemberCreateInstance(member, classInfo);
+
+ if(!newField)
+ {
+ return 0;
+ }
+
+ /* Copy the original field's properties */
+ signature = ILTypeInstantiate(image->context,
+
ILMember_Signature(member),
+
classParams, 0);
+ if(!signature)
+ {
+ return 0;
+ }
+ else
+ {
+ ILMemberSetSignature((ILMember
*)newField, signature);
+ }
+ }
+ break;
+
+ case IL_META_MEMBERKIND_EVENT:
+ {
+ /* Create a new event */
+ newEvent = (ILField
*)ILMemberCreateInstance(member, classInfo);
+
+ if(!newEvent)
+ {
+ return 0;
+ }
+
+ /* Copy the original field's properties */
+ signature = ILTypeInstantiate(image->context,
+
ILMember_Signature(member),
+
classParams, 0);
+ if(!signature)
+ {
+ return 0;
+ }
+ else
+ {
+ ILMemberSetSignature((ILMember
*)newEvent, signature);
+ }
+ }
+ break;
+
+ case IL_META_MEMBERKIND_PROPERTY:
+ {
+ /* TODO */
+ }
+ break;
+
+ case IL_META_MEMBERKIND_OVERRIDE:
+ {
+ /* TODO */
+ }
+ break;
+
+ case IL_META_MEMBERKIND_PINVOKE:
+ {
+ /* TODO */
+ }
+ break;
+ }
+ }
+
+ /* Done */
+ return 1;
+}
+
+ILClass *ILClassInstantiate(ILImage *image, ILType *classType,
+ ILType *classArgs,
ILType *methodArgs)
+{
+ ILClass *classInfo;
+ ILType *type;
+
+ /* Bail out early if the type does not need instantiation */
+ if(!ILType_IsWith(classType) && !ILTypeNeedsInstantiation(classType))
+ {
+ return ILClassFromType(image, 0, classType, 0);
+ }
+
+ /* Search for a synthetic type that matches the expanded
+ form of the class type, in case we already instantiated
+ this class previously. We do this in such a way that we
+ won't need to call "ILTypeInstantiate" unless necessary */
+ classInfo = _ILTypeToSyntheticInstantiation(image, classType,
classArgs, methodArgs);
+ if(classInfo)
+ {
+ if((classInfo->attributes & IL_META_TYPEDEF_CLASS_EXPANDED) ==
0)
+ {
+ classArgs = ILClassToType(classInfo);
+ if(!ExpandInstantiations(image, classInfo, classType,
classArgs))
+ {
+ return 0;
+ }
+ }
+ return classInfo;
+ }
+
+ /* Instantiate the class type */
+ type = ILTypeInstantiate(image->context, classType, classArgs,
methodArgs);
+ if(!type)
+ {
+ return 0;
+ }
+
+ /* Create a synthetic type for the expanded form */
+ classInfo = ILClassFromType(image, 0, type, 0);
+ if(!classInfo)
+ {
+ return 0;
+ }
+ if(!ExpandInstantiations(image, classInfo, type, type))
+ {
+ return 0;
+ }
+ return classInfo;
+}
+
+ILType *ILClassGetTypeArguments(ILClass *info)
+{
+ if((info->attributes & IL_META_TYPEDEF_CLASS_EXPANDED) != 0)
+ {
+ return info->synthetic;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+int ILClassNeedsExpansion(ILClass *info)
+{
+ ILType *type = info->synthetic;
+ if(ILType_IsWith(type) &&
+ (info->attributes & IL_META_TYPEDEF_CLASS_EXPANDED) == 0)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+int ILClassIsExpanded(ILClass *info)
+{
+ return ((info->attributes & IL_META_TYPEDEF_CLASS_EXPANDED) != 0);
+}
+
+/* FIXME: Make this function more efficient. */
+ILMember *ILClassGetMemberInstance(ILClass *owner, ILMember *member)
+{
+ ILMember *memberInst = owner->firstMember;
+
+ if(!ILClass_IsGenericInstance(owner))
+ {
+ return 0;
+ }
+
+ while(memberInst != 0)
+ {
+ if(ILProgramItem_Token(memberInst) ==
ILProgramItem_Token(member))
+ {
+ return memberInst;
+ }
+ memberInst = memberInst->nextMember;
+ }
+
+ return 0;
+}
+
+/* FIXME: Make this function more efficient. */
+ILMethod *ILClassLookupMethodInstance(ILClass *owner, const char *name,
+
ILType *signature, ILType *methodArgs)
+{
+ ILMember *member = 0;
+
+ while((member = ILClassNextMemberByKind(owner,
+
member,
+
IL_META_MEMBERKIND_METHOD)) != 0)
+ {
+ if(strcmp(member->name, name) != 0)
+ {
+ continue;
+ }
+ if(!ILTypeIdentical(member->signature, signature))
+ {
+ continue;
+ }
+ if(ILMember_IsGenericInstance(member))
+ {
+ ILMethodInstance *methodInstance = (ILMethodInstance
*)member;
+
+ if
(ILTypeIdentical(methodInstance->methodTypeArguments, methodArgs))
+ {
+ return (ILMethod *)member;
+ }
+ }
+ }
+
+ return 0;
+}
+
+ILClass *ILClassResolveToInstance(ILClass *classInfo, ILMethod *methodCaller)
+{
+ ILType *classTypeArgs = 0;
+ ILType *methodTypeArgs = 0;
+ ILType *classType;
+
+ classInfo = ILClassResolve(classInfo);
+ classType = ILClass_SynType(classInfo);
+ if(!classType ||
+ (!ILTypeNeedsInstantiation(classType) &&
+ !ILClassNeedsExpansion(classInfo)))
+ {
+ return classInfo;
+ }
+ if(ILMember_IsGenericInstance(methodCaller))
+ {
+ ILMethodInstance *methodInstance = (ILMethodInstance
*)methodCaller;
+
+ classTypeArgs = methodInstance->classTypeArguments;
+ methodTypeArgs = methodInstance->methodTypeArguments;
+ }
+ classInfo = ILClassExpand(ILClassToImage(classInfo), classInfo,
+ classTypeArgs,
methodTypeArgs);
+
+ return classInfo;
+}
+
+#ifdef __cplusplus
+};
+#endif
Index: generic_member.c
===================================================================
RCS file: generic_member.c
diff -N generic_member.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ generic_member.c 14 Sep 2007 12:09:12 -0000 1.1
@@ -0,0 +1,493 @@
+/*
+ * generic_member.c - Functions related to generic class members.
+ *
+ * Copyright (C) 2007 Southern Storm Software, Pty Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "program.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ILMember *ILClassGetMemberInstance(ILClass *owner, ILMember *member);
+
+/*
+ * Function for creating members instances and attaching them to a class.
+ */
+ILMember *ILMemberCreateInstance(ILMember *memberDef,
+ ILClass *info)
+{
+ ILImage *image = memberDef->programItem.image;
+ ILMember *member;
+ unsigned size;
+
+ if(ILMember_IsMethod(memberDef))
+ {
+ size = sizeof(ILMethodInstance);
+ }
+ else if(ILMember_IsField(memberDef))
+ {
+ size = sizeof(ILField);
+ }
+ else if(ILMember_IsProperty(memberDef))
+ {
+ size = sizeof(ILProperty);
+ }
+ else if(ILMember_IsEvent(memberDef))
+ {
+ size = sizeof(ILEvent);
+ }
+ else if(ILMember_IsOverride(memberDef))
+ {
+ size = sizeof(ILOverride);
+ }
+ else if(ILMember_IsPInvoke(memberDef))
+ {
+ size = sizeof(ILPInvoke);
+ }
+ else
+ {
+ /* Unknown */
+ return 0;
+ }
+
+ /* Allocate space for the member from the memory stack */
+ member = (ILMember *)ILMemStackAllocItem(&(image->memStack), size);
+ if(!member)
+ {
+ return 0;
+ }
+
+ /* Attach the member to its owning class */
+ member->owner = info;
+ member->nextMember = 0;
+ if(info->lastMember)
+ info->lastMember->nextMember = member;
+ else
+ info->firstMember = member;
+ info->lastMember = member;
+
+ /* Copy the other member fields from the member definition */
+ member->name = memberDef->name;
+ member->programItem.image = image;
+ member->programItem.token = memberDef->programItem.token;
+ member->kind = memberDef->kind;
+ member->attributes = memberDef->attributes;
+ member->signature = 0;
+ member->signatureBlob = 0;
+
+ return member;
+}
+
+
+/*
+ * Function for creating parameter instances and attaching them to a method.
+ */
+ILParameter *ILParameterCreateInstance(ILParameter *paramDef,
+
ILMethod *method)
+{
+ ILImage *image = paramDef->programItem.image;
+ ILParameter *param;
+ ILParameter *current;
+ ILParameter *prev;
+
+ /* Allocate space for the parameter from the memory stack */
+ param = ILMemStackAlloc(&(image->memStack), ILParameter);
+ if(!param)
+ {
+ return 0;
+ }
+
+ /* Set the parameter fields */
+ param->name = paramDef->name;
+ param->programItem.image = image;
+ param->attributes = paramDef->attributes;
+ param->paramNum = paramDef->paramNum;
+
+ /* Attach the parameter to the method */
+ current = method->parameters;
+ prev = 0;
+ while(current != 0 && current->paramNum < param->paramNum)
+ {
+ prev = current;
+ current = current->next;
+ }
+ param->next = current;
+ if(prev)
+ {
+ prev->next = param;
+ }
+ else
+ {
+ method->parameters = param;
+ }
+
+ /* Return the parameter to the caller */
+ return param;
+}
+
+/*
+ * Create a method instance and attach it to a class.
+ */
+ILMethod *ILMethodCreateInstance(ILImage *image,
+ ILMethod
*method,
+ ILClass
*classInfo,
+ ILType
*classTypeArgs,
+ ILType
*methodTypeArgs)
+{
+ ILParameter *origParam;
+ ILMethod *newMethod;
+ ILType *signature;
+ ILMethodInstance *methodInstance;
+
+ signature = ILTypeInstantiate(image->context,
+
ILMethod_Signature(method),
+ classTypeArgs,
+
methodTypeArgs);
+ if(!signature)
+ {
+ return 0;
+ }
+ newMethod = 0;
+ if(ILClassIsExpanded(classInfo))
+ {
+ newMethod = ILClassLookupMethodInstance(classInfo,
ILMethod_Name(method),
+
signature, methodTypeArgs);
+ }
+ if(!newMethod)
+ {
+ /* Create a new method */
+ newMethod = (ILMethod *)ILMemberCreateInstance((ILMember
*)method, classInfo);
+
+ if(!newMethod)
+ {
+ return 0;
+ }
+
+ /* Copy the original method's properties */
+ ILMemberSetSignature((ILMember *)newMethod, signature);
+ ILMethodSetImplAttrs(newMethod, ~((ILUInt32)0),
+
ILMethod_ImplAttrs(method));
+ ILMethodSetCallConv(newMethod, ILMethod_CallConv(method));
+ ILMethodSetRVA(newMethod, ILMethod_RVA(method));
+ newMethod->callingConventions |= IL_META_CALLCONV_INSTANTIATION;
+ newMethod->userData = 0;
+ methodInstance = (ILMethodInstance *)newMethod;
+ methodInstance->genMethod = method;
+ methodInstance->classTypeArguments = classTypeArgs;
+ methodInstance->methodTypeArguments = methodTypeArgs;
+
+ /* Copy the original method's parameter blocks */
+ origParam = 0;
+ while((origParam = ILMethodNextParam(method, origParam)) != 0)
+ {
+ if(!ILParameterCreateInstance(origParam, newMethod))
+ {
+ return 0;
+ }
+ }
+ }
+
+ return newMethod;
+}
+
+static int UpdateMethodVTable(ILMethod *method, ILMethod *virtualAncestor)
+{
+ ILClass *owner = ILMethod_Owner(method);
+ ILImage *image;
+ ILMethodVTable *parentVTable;
+ ILMethodVTable *vtable;
+
+ if(method->vtable == 0)
+ {
+ return 0;
+ }
+ parentVTable = virtualAncestor->vtable;
+ if(!parentVTable)
+ {
+ return 0;
+ }
+ image = ILProgramItem_Image(method);
+ vtable = method->vtable;
+ while(vtable->numSlots < parentVTable->numSlots)
+ {
+ ILMethodInstance *methodInstance = (ILMethodInstance
*)ILMethodGetInstance(virtualAncestor, vtable->numSlots);
+ ILMethod *newMethod = ILMethodCreateInstance(image,
+
method,
+
owner,
+
ILClassGetTypeArguments(owner),
+
methodInstance->methodTypeArguments);
+ if(!newMethod)
+ {
+ return 0;
+ }
+ if(!ILMethodAddInstance(method, newMethod))
+ {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static int InitVTable(ILMethod *method)
+{
+ ILImage *image = ILProgramItem_Image(method);
+
+ method->vtable = ILMemStackAlloc(&(image->memStack), ILMethodVTable);
+ if(!method->vtable)
+ {
+ return 0;
+ }
+ method->vtable->numSlots = 0;
+ method->vtable->numItems = 1;
+ method->vtable->lastItem = &method->vtable->firstItem;
+
+ return 1;
+}
+
+/*
+ * Set the method ancestor and initialize the vtable.
+ */
+int ILMethodSetVirtualAncestor(ILMethod *method, ILMethod *virtualAncestor)
+{
+ if(!ILMethod_IsVirtualGeneric(method))
+ {
+ return 1;
+ }
+ if(method->vtable == 0)
+ {
+ if(!InitVTable(method))
+ {
+ return 0;
+ }
+ }
+ method->vtable->virtualAncestor = virtualAncestor;
+
+ return 1;
+}
+
+ILMethod *ILMethodGetInstance(ILMethod *method, int index)
+{
+ ILMethodVTableItem *item;
+ ILMethodVTable *vtable;
+ ILMethod *ancestor;
+ int itemIndex;
+ int indexInItem;
+
+ if(method->vtable == 0)
+ {
+ return 0;
+ }
+ /* Let's find the top virtual ancestor. */
+ ancestor = method->vtable->virtualAncestor;
+ if(ancestor != 0)
+ {
+ while(ancestor->vtable->virtualAncestor != 0)
+ {
+ ancestor = ancestor->vtable->virtualAncestor;
+ }
+
+ /* Ensure that the vtable is up-to-date. */
+ if(!UpdateMethodVTable(method, ancestor))
+ {
+ return 0;
+ }
+ }
+ vtable = method->vtable;
+ if(index >= vtable->numSlots)
+ {
+ return 0;
+ }
+ item = &(vtable->firstItem);
+ itemIndex = index / METHOD_VTABLE_ITEM_COUNT;
+ indexInItem = index % METHOD_VTABLE_ITEM_COUNT;
+ while(itemIndex-- > 0)
+ {
+ item = item->nextItem;
+ }
+
+ return item->data[indexInItem];
+}
+
+int ILMethodAddInstance(ILMethod *method, ILMethod *methodInstance)
+{
+ ILImage *image = ILProgramItem_Image(method);
+ ILMethodVTableItem *item;
+ int indexInItem;
+ int lastItemCount;
+
+ /* The method vtable should have been initialized when laying out the
class */
+ if(method->vtable == 0)
+ {
+ return 0;
+ }
+ lastItemCount = (method->vtable->numItems * METHOD_VTABLE_ITEM_COUNT) -
method->vtable->numSlots;
+ if(lastItemCount == 0)
+ {
+ item = ILMemStackAlloc(&(image->memStack), ILMethodVTableItem);
+ if(!item)
+ {
+ return 0;
+ }
+ method->vtable->numItems++;
+ method->vtable->lastItem->nextItem = item;
+ method->vtable->lastItem = item;
+ }
+ else
+ {
+ item = method->vtable->lastItem;
+ }
+ methodInstance->index = method->vtable->numSlots;
+ method->vtable->numSlots++;
+ indexInItem = methodInstance->index % METHOD_VTABLE_ITEM_COUNT;
+ item->data[indexInItem] = methodInstance;
+
+ return 1;
+}
+
+ILMember *ILMemberResolveToInstance(ILMember *member, ILMethod *methodCaller)
+{
+ ILClass *owner;
+
+ owner = ILClassResolveToInstance(member->owner, methodCaller);
+ if(owner == 0)
+ {
+ return 0;
+ }
+ member = ILMemberResolve(member);
+ if(member->owner != owner)
+ {
+ member = ILClassGetMemberInstance(owner, member);
+ }
+
+ return member;
+}
+
+int ILMemberIsGenericInstance(ILMember *member)
+{
+ if(!member->owner)
+ {
+ return 0;
+ }
+ if(ILClass_IsGenericInstance(member->owner))
+ {
+ return 1;
+ }
+
+ if(ILMember_IsMethod(member))
+ {
+ return ((ILMethod_CallConv((ILMethod *)member) &
IL_META_CALLCONV_INSTANTIATION) != 0);
+ }
+
+ return 0;
+}
+
+ILMethod *ILMethodSpecToMethod(ILMethodSpec *mspec, ILMethod *methodCaller)
+{
+ ILType *classTypeArgs = 0;
+ ILType *methodTypeArgs = 0;
+ ILMethod *newMethod;
+ ILMethod *genMethod;
+ ILMethod *virtAncestor;
+ ILType *mspecTypeArgs;
+ ILClass *owner;
+ ILImage *image;
+
+ if(ILMember_IsGenericInstance((ILMember *)methodCaller))
+ {
+ ILMethodInstance *methodInstance = (ILMethodInstance
*)methodCaller;
+
+ classTypeArgs = methodInstance->classTypeArguments;
+ methodTypeArgs = methodInstance->methodTypeArguments;
+ }
+
+ image = ILProgramItem_Image(mspec);
+ mspecTypeArgs = ILTypeInstantiate(ILImageToContext(image),
+
ILMethodSpec_Type(mspec),
+
classTypeArgs,
+
methodTypeArgs);
+ if(!mspecTypeArgs)
+ {
+ return 0;
+ }
+ genMethod = (ILMethod *)ILMemberResolveToInstance(mspec->method,
methodCaller);
+ if(!genMethod)
+ {
+ return 0;
+ }
+ virtAncestor = genMethod;
+ if(ILMethod_IsVirtualGeneric(genMethod))
+ {
+ while(virtAncestor->vtable->virtualAncestor != 0)
+ {
+ virtAncestor = virtAncestor->vtable->virtualAncestor;
+ }
+ }
+ newMethod = ILMethodCreateInstance(image,
+
virtAncestor,
+
ILMethod_Owner(virtAncestor),
+
classTypeArgs,
+
mspecTypeArgs);
+ if(!newMethod)
+ {
+ return 0;
+ }
+ if(ILMethod_IsVirtualGeneric(virtAncestor))
+ {
+ if(!ILMethodAddInstance(virtAncestor, newMethod))
+ {
+ return 0;
+ }
+ newMethod = ILMethodGetInstance(genMethod, newMethod->index);
+ if(!newMethod)
+ {
+ return 0;
+ }
+ }
+
+ return newMethod;
+}
+
+ILType *ILMethodGetClassTypeArguments(ILMethod *method)
+{
+ if(ILMember_IsGenericInstance(method))
+ {
+ return ((ILMethodInstance*)method)->classTypeArguments;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+ILType *ILMethodGetMethodTypeArguments(ILMethod *method)
+{
+ if(ILMember_IsGenericInstance(method))
+ {
+ return ((ILMethodInstance*)method)->methodTypeArguments;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+#ifdef __cplusplus
+};
+#endif
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [dotgnu-pnet-commits] pnet/image generic_class.c generic_member.c,
Ivan de Jesus Deras Tabora <=