Exemplo n.º 1
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;
}
Exemplo n.º 2
0
/*
 * Get the total spanning size of an interface inheritance tree.
 */
static int GetSpanningSize(ILClass *interface)
{
    int size = 1;
    ILImplements *impl = 0;
    while((impl = ILClassNextImplements(interface, impl)) != 0)
    {
        size += GetSpanningSize(ILClassResolve(ILImplementsGetInterface(impl)));
    }
    return size;
}
Exemplo n.º 3
0
ILObject *_ILGetClrType(ILExecThread *thread, ILClass *classInfo)
{
	ILObject *obj;

	classInfo = ILClassResolve(classInfo);

	if(!classInfo)
	{
		thread->thrownException = _ILSystemException
			(thread, "System.TypeInitializationException");
		return 0;
	}

	/* Make sure that the class has been laid out */
	IL_METADATA_WRLOCK(_ILExecThreadProcess(thread));
	if(!_ILLayoutClass(_ILExecThreadProcess(thread), classInfo))
	{
		IL_METADATA_UNLOCK(_ILExecThreadProcess(thread));
		thread->thrownException = _ILSystemException
			(thread, "System.TypeInitializationException");
		return 0;
	}
	IL_METADATA_UNLOCK(_ILExecThreadProcess(thread));

	/* Does the class already have a "ClrType" instance? */
	if(((ILClassPrivate *)(classInfo->userData))->clrType)
	{
		return ((ILClassPrivate *)(classInfo->userData))->clrType;
	}

	/* Create a new "ClrType" instance */
	if(!(thread->process->clrTypeClass))
	{
		thread->thrownException = _ILSystemException
			(thread, "System.TypeInitializationException");
		return 0;
	}
	obj = _ILEngineAllocObject(thread, thread->process->clrTypeClass);
	if(!obj)
	{
		return 0;
	}

	/* Fill in the object with the class information */
	((System_Reflection *)obj)->privateData = classInfo;

	/* Attach the object to the class so that it will be returned
	   for future calls to this function */
	((ILClassPrivate *)(classInfo->userData))->clrType = obj;

	/* Return the object to the caller */
	return obj;
}
Exemplo n.º 4
0
/*
 * Convert an IL type into an "ffi" type descriptor.
 */
static ffi_type *TypeToFFI(ILExecProcess *process, ILType *type, int isInternal)
{
	if(ILType_IsPrimitive(type))
	{
		/* Determine how to marshal a primitive type */
		switch(ILType_ToElement(type))
		{
			case IL_META_ELEMTYPE_VOID:		return &ffi_type_void;
			case IL_META_ELEMTYPE_BOOLEAN:	return &ffi_type_sint8;
			case IL_META_ELEMTYPE_I1:		return &ffi_type_sint8;
			case IL_META_ELEMTYPE_U1:		return &ffi_type_uint8;
			case IL_META_ELEMTYPE_I2:		return &ffi_type_sint16;
			case IL_META_ELEMTYPE_U2:		return &ffi_type_uint16;
			case IL_META_ELEMTYPE_CHAR:		return &ffi_type_uint16;
			case IL_META_ELEMTYPE_I4:		return &ffi_type_sint32;
			case IL_META_ELEMTYPE_U4:		return &ffi_type_uint32;
		#ifdef IL_NATIVE_INT32
			case IL_META_ELEMTYPE_I:		return &ffi_type_sint32;
			case IL_META_ELEMTYPE_U:		return &ffi_type_uint32;
		#else
			case IL_META_ELEMTYPE_I:		return &ffi_type_sint64;
			case IL_META_ELEMTYPE_U:		return &ffi_type_uint64;
		#endif
			case IL_META_ELEMTYPE_I8:		return &ffi_type_sint64;
			case IL_META_ELEMTYPE_U8:		return &ffi_type_uint64;
			case IL_META_ELEMTYPE_R4:		return &ffi_type_float;
			case IL_META_ELEMTYPE_R8:		return &ffi_type_double;
		#ifdef IL_NATIVE_FLOAT
			case IL_META_ELEMTYPE_R:		return &ffi_type_longdouble;
		#else
			case IL_META_ELEMTYPE_R:		return &ffi_type_double;
		#endif
			case IL_META_ELEMTYPE_TYPEDBYREF: return &ffi_type_typedref;
		}
		return &ffi_type_pointer;
	}
#ifdef IL_CONFIG_PINVOKE
	else if(!isInternal && ILType_IsValueType(type))
	{
		/* Structure that is passed by value to a PInvoke method */
		ffi_type *ffi = StructToFFI(process, ILClassResolve(ILType_ToValueType(type)));
		return (ffi ? ffi : &ffi_type_pointer);
	}
#endif
	else
	{
		/* Everything else is passed as a pointer */
		return &ffi_type_pointer;
	}
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
0
/*
 * Determine if "classInfo" fully implements all parent interfaces
 * of "refClass".  Note: Returns non-zero on error.
 */
static int ImplementsAllInterfaces(ILNode *node, ILClass *classInfo,
                                   ILClass *refClass,
                                   ILGenInterfaceErrorFunc error,
                                   ILGenInterfaceProxyFunc proxy,
                                   ILClass **visited, int *visitedSize)
{
    ILImplements *impl = 0;
    int sawErrors = 0;
    while((impl = ILClassNextImplements(refClass, impl)) != 0)
    {
        sawErrors |= ImplementsInterface
                     (node, classInfo,
                      ILClassResolve(ILImplementsGetInterface(impl)),
                      error, proxy, visited, visitedSize);
    }
    return sawErrors;
}
Exemplo n.º 7
0
/*
 * 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;
	}
}
Exemplo n.º 8
0
/*
 * 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;
}