コード例 #1
0
ファイル: generic_class.c プロジェクト: bencz/DotGnu
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;
}
コード例 #2
0
ファイル: verify.c プロジェクト: bencz/DotGnu
/*
 * Determine if a type is a sub-class of a specific class.
 */
static int IsSubClass(ILType *type, ILClass *classInfo)
{
	ILClass *typeClass;
	if(type == 0)
	{
		/* The type is "null", which is always a sub-class */
		return 1;
	}
	else if(ILType_IsClass(type) || ILType_IsValueType(type))
	{
		typeClass = ILType_ToClass(type);
		if(ILClassInheritsFrom(typeClass, classInfo) ||
		   ILClassImplements(typeClass, classInfo))
		{
			return 1;
		}
		return 0;
	}
	else if((typeClass = ILClassFromType(ILClassToImage(classInfo),
										 0, type, 0)) != 0)
	{
		if(ILClassInheritsFrom(typeClass, classInfo) ||
		   ILClassImplements(typeClass, classInfo))
		{
			return 1;
		}
		return 0;
	}
	else
	{
		return 0;
	}
}
コード例 #3
0
ファイル: generic_class.c プロジェクト: bencz/DotGnu
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;
	}
}
コード例 #4
0
/*
 * private static TypedReference ClrMakeTypedReference(Object target,
 *													   FieldInfo[] flds);
 */
ILTypedRef _IL_TypedReference_ClrMakeTypedReference(ILExecThread *_thread,
													ILObject *target,
													System_Array *flds)
{
	ILClass *classInfo;
	ILInt32 index;
	ILUInt32 offset;
	ILTypedRef ref;
	ILField *field;

	/* Get the initial class and offset */
	classInfo = GetObjectClass(target);
	offset = 0;

	/* Resolve the fields within the object, level by level */
	for(index = 0; index < ArrayLength(flds); ++index)
	{
		field = *((ILField **)(((ILObject **)(ArrayToBuffer(flds)))[index]));
		if(!field)
		{
			ILExecThreadThrowSystem
				(_thread, "System.ArgumentException",
				 "Arg_MakeTypedRefFields");
			ref.type = 0;
			ref.value = 0;
			return ref;
		}
		offset += field->offset;
		classInfo = ILClassFromType
			(ILContextNextImage(_thread->process->context, 0),
			 0, ILField_Type(field), 0);
		classInfo = ILClassResolve(classInfo);
		if(!classInfo ||
		   (index < (ArrayLength(flds) - 1) && !ILClassIsValueType(classInfo)))
		{
			ILExecThreadThrowSystem
				(_thread, "System.ArgumentException",
				 "Arg_MakeTypedRefFields");
			ref.type = 0;
			ref.value = 0;
			return ref;
		}
	}

	/* Populate the typed reference */
	ref.type = (void *)classInfo;
	ref.value = (void *)(((unsigned char *)target) + offset);
	return ref;
}
コード例 #5
0
ファイル: item.c プロジェクト: bencz/DotGnu
ILProgramItem *ILProgramItemFromType(ILImage *image, ILType *type)
{
	if(!type)
	{
		return 0;
	}
	if(ILType_IsComplex(type))
	{
		switch(ILType_Kind(type))
		{
			case IL_TYPE_COMPLEX_WITH:
			case IL_TYPE_COMPLEX_ARRAY:
			case IL_TYPE_COMPLEX_ARRAY_CONTINUE:
			case IL_TYPE_COMPLEX_PTR:
			case IL_TYPE_COMPLEX_METHOD:
			case (IL_TYPE_COMPLEX_METHOD | IL_TYPE_COMPLEX_METHOD_SENTINEL):
			{
				ILTypeSpec *spec;

				spec = ILTypeSpecCreate(image, 0, type);
				return ILToProgramItem(spec);
			}
		}
	}
	else
	{
		ILClass *info;

		info = ILClassFromType(image, 0, type, 0);
		if(info)
		{
			info = ILClassImport(image, info);
		}
		return ILToProgramItem(info);
	}
	return 0;
}
コード例 #6
0
ファイル: verify_branch.c プロジェクト: bencz/DotGnu
/* 
 * Find the nearest type in the type2 heirarchy that is assign 
 * compatible to type1.
 */
static ILType* TryCommonType(ILImage* image, ILType * type1, ILType *type2)
{
	ILClass *classInfo;

	if(type1==NULL) return type2;
	if(type2==NULL) return type1;

	/* Note: boxing conversions are not allowed because both
	 * types have to be reference types.
	 */ 
	if(ILTypeAssignCompatibleNonBoxing(image, type1,type2))
	{
		return type2;
	}

	classInfo=ILClassFromType(image, 0, type2, 0);
	
	if((classInfo = ILClass_ParentClass(classInfo)) != NULL)
	{
		return TryCommonType(image, type1, ILClassToType(classInfo));
	}
	
	return type2;
}
コード例 #7
0
ファイル: verify.c プロジェクト: bencz/DotGnu
/*
 * Determine if a stack item is assignment-compatible with
 * a particular memory slot (argument, local, field, etc).
 */
static int AssignCompatible(ILMethod *method, ILEngineStackItem *item,
							ILType *type, int unsafeAllowed)
{
	ILImage *image;
	ILClass *classInfo;
	ILClass *classInfo2;
	ILMethod *methodRef;
	ILType *objType;

	/* Check for safe and unsafe pointer assignments */
	if(item->engineType == ILEngineType_I)
	{
		methodRef = MethodRefToMethod(item->typeInfo);
		if(methodRef)
		{
			/* Assigning a method reference, obtained via "ldftn"
			   or "ldvirtftn", to a method pointer destination */
			if(ILTypeIdentical(ILMethod_Signature(methodRef), type))
			{
				return 1;
			}
		}
		else if(item->typeInfo != 0 && ILType_IsComplex(item->typeInfo))
		{
			/* May be trying to assign a method pointer to a method type */
			if(ILType_IsMethod(item->typeInfo))
			{
				if(ILTypeIdentical(item->typeInfo, type))
				{
					return 1;
				}
			}
		}
		if(unsafeAllowed)
		{
			if(type != 0 && ILType_IsComplex(type))
			{
				if((ILType_Kind(type) & IL_TYPE_COMPLEX_METHOD) != 0 ||
				   ILType_Kind(type) == IL_TYPE_COMPLEX_PTR)
				{
					return 1;
				}
			}
		}
	}

	/* Check for regular assignments */
	if(item->engineType == ILEngineType_I4 ||
	   item->engineType == ILEngineType_I)
	{
		type = ILTypeGetEnumType(type);
		switch((unsigned long)type)
		{
			case (unsigned long)ILType_Boolean:
			case (unsigned long)ILType_Int8:
			case (unsigned long)ILType_UInt8:
			case (unsigned long)ILType_Int16:
			case (unsigned long)ILType_UInt16:
			case (unsigned long)ILType_Char:
			case (unsigned long)ILType_Int32:
			case (unsigned long)ILType_UInt32:
			case (unsigned long)ILType_Int:
			case (unsigned long)ILType_UInt:	return 1;
			default: break;
		}

		if(!unsafeAllowed)
		{
			return 0;
		}

		/* Allow a native int to be assigned to a complex type */
		if(type != 0 && ILType_IsComplex(type) && 
						item->engineType == ILEngineType_I)
		{
			if(ILType_Kind(type) == IL_TYPE_COMPLEX_PTR ||
			  ILType_Kind(type) == IL_TYPE_COMPLEX_BYREF) 
			{
				return 1;
			}
		}
		return 0;
	}
	else if(item->engineType == ILEngineType_I8)
	{
		type = ILTypeGetEnumType(type);
		return (type == ILType_Int64 || type == ILType_UInt64);
	}
	else if(item->engineType == ILEngineType_F)
	{
		return (type == ILType_Float32 ||
		        type == ILType_Float64 ||
		        type == ILType_Float);
	}
	else if(item->engineType == ILEngineType_O)
	{
		if(!(item->typeInfo))
		{
			/* A "null" constant was pushed, which is
			   compatible with any object reference type */
			return IsObjectRef(type);
		}
		if(!IsObjectRef(type) || !IsObjectRef(item->typeInfo))
		{
			/* Both types must be object references */
			return 0;
		}
		/* make a copy to avoid unecessary complications */
		objType=item->typeInfo;
		if(ILType_IsArray(type) && ILType_IsArray(objType) &&
			(ILTypeGetRank(type) == ILTypeGetRank(objType)))
		{
			objType=ILTypeGetElemType(objType);
			type=ILTypeGetElemType(type);
		}
		image = ILProgramItem_Image(method);
		classInfo = ILClassResolve(ILClassFromType(image, 0, type, 0));
		classInfo2 = ILClassResolve
			(ILClassFromType(image, 0, objType, 0));
		if(classInfo && classInfo2)
		{
			/* Is the type a regular class or an interface? */
			if(!ILClass_IsInterface(classInfo))
			{
				/* Regular class: the value must inherit from the type */
				if(ILClassInheritsFrom(classInfo2, classInfo))
				{
					return 1;
				}

				/* If "classInfo2" is an interface, then the conversion
				   is OK if "type" is "System.Object", because all
				   interfaces inherit from "System.Object", even though
				   the metadata doesn't explicitly say so */
				if(ILClass_IsInterface(classInfo2))
				{
					return ILTypeIsObjectClass(type);
				}

				/* The conversion is not OK */
				return 0;
			}
			else
			{
				/* Interface which the value must implement or inherit from */
				return ILClassImplements(classInfo2, classInfo) ||
				       ILClassInheritsFrom(classInfo2, classInfo);
			}
		}
		else
		{
			return 0;
		}
	}
	else if(item->engineType == ILEngineType_MV)
	{
		/* Can only assign managed values to an exact type destination */
		return ILTypeIdentical(item->typeInfo, type);
	}
	else if(item->engineType == ILEngineType_TypedRef)
	{
		/* The type must be "typedref" */
		return (type == ILType_TypedRef);
	}
	else if(item->engineType == ILEngineType_M ||
	        item->engineType == ILEngineType_T)
	{
		/* Cannot assign managed pointers to variables or fields,
		   unless we are in "unsafe" mode */
		if(!unsafeAllowed)
		{
			return 0;
		}

		/* Allow an assignment to any pointer, reference, or native
		   destination, regardless of type.  This allows C/C++ code
		   to arbitrarily cast pointers via assignment */
		if(type != 0 && ILType_IsComplex(type))
		{
			if(ILType_Kind(type) == IL_TYPE_COMPLEX_PTR ||
			   ILType_Kind(type) == IL_TYPE_COMPLEX_BYREF ||
			   (ILType_Kind(type) & IL_TYPE_COMPLEX_METHOD) != 0)
			{
				return 1;
			}
		}
		else if(type == ILType_Int || type == ILType_UInt)
		{
			return 1;
		}
		return 0;
	}
	else
	{
		/* Invalid type: never assignment-compatible with anything */
		return 0;
	}
}
コード例 #8
0
ファイル: generic_class.c プロジェクト: bencz/DotGnu
/*
 * 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)
	{
		ILClass *parentClass;

		parentClass = ILClassExpand
			(image, ILClass_ParentClass(origClass), classParams, 0);
		if(!parentClass)
		{
			classInfo->parent = 0;
			return 0;
		}
		classInfo->parent = ILToProgramItem(parentClass);
	}
	impl = _ILClass_Implements(origClass);
	while(impl)
	{
		tempInfo = ILImplements_InterfaceClass(impl);
		tempInfo = ILClassExpand(image, tempInfo, classParams, 0);
		if(!tempInfo)
		{
			return 0;
		}
		if(!ILClassAddImplements(classInfo, ILToProgramItem(tempInfo), 0))
		{
			return 0;
		}
		impl = _ILImplements_NextImplements(impl);
	}

	/* 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 = (ILEvent *)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;
}