Beispiel #1
0
/*
 * Convert a method reference type into a method block.
 * Returns NULL if not a method reference type.
 */
static ILMethod *MethodRefToMethod(ILType *type)
{
	if(type != 0 && ILType_IsComplex(type) &&
	   ILType_Kind(type) == IL_TYPE_COMPLEX_METHOD_REF)
	{
		return (ILMethod *)(ILType_Ref(type));
	}
	else
	{
		return 0;
	}
}
Beispiel #2
0
/*
 * Get type size information.
 */
static void GetTypeSize(ILSizeInfo *info, ILType *type)
{
	unsigned long num;
	unsigned long posn;

	/* Only complex types have a non-zero memory size */
	if(type == 0 || !ILType_IsComplex(type))
	{
		return;
	}

	/* Account for the size of the complex type header */
	info->loadedMeta += sizeof(ILType);

	/* Account for element information */
	switch(ILType_Kind(type))
	{
		case IL_TYPE_COMPLEX_BYREF:
		case IL_TYPE_COMPLEX_PTR:
		case IL_TYPE_COMPLEX_PINNED:
		{
			GetTypeSize(info, ILType_Ref(type));
		}
		break;

		case IL_TYPE_COMPLEX_ARRAY:
		case IL_TYPE_COMPLEX_ARRAY_CONTINUE:
		{
			GetTypeSize(info, ILType_ElemType(type));
		}
		break;

		case IL_TYPE_COMPLEX_CMOD_REQD:
		case IL_TYPE_COMPLEX_CMOD_OPT:
		{
			GetTypeSize(info, type->un.modifier__.type__);
		}
		break;

		case IL_TYPE_COMPLEX_LOCALS:
		{
			num = ILTypeNumLocals(type);
			for(posn = 0; posn < num; ++posn)
			{
				GetTypeSize(info, ILTypeGetLocalWithPrefixes(type, posn));
			}
		}
		break;

		case IL_TYPE_COMPLEX_WITH:
		{
			num = ILTypeNumWithParams(type);
			GetTypeSize(info, ILTypeGetWithMainWithPrefixes(type));
			for(posn = 1; posn <= num; ++posn)
			{
				GetTypeSize(info, ILTypeGetWithParamWithPrefixes(type, posn));
			}
		}
		break;

		case IL_TYPE_COMPLEX_PROPERTY:
		case IL_TYPE_COMPLEX_METHOD:
		case IL_TYPE_COMPLEX_METHOD | IL_TYPE_COMPLEX_METHOD_SENTINEL:
		{
			num = ILTypeNumParams(type);
			GetTypeSize(info, ILTypeGetReturnWithPrefixes(type));
			for(posn = 1; posn <= num; ++posn)
			{
				GetTypeSize(info, ILTypeGetParamWithPrefixes(type, posn));
			}
		}
		break;
	}
}
Beispiel #3
0
/*
 * Convert a type into an engine type.
 */
static ILEngineType TypeToEngineType(ILType *type)
{
	type = ILTypeGetEnumType(type);
	if(ILType_IsPrimitive(type))
	{
		switch(ILType_ToElement(type))
		{
			case IL_META_ELEMTYPE_BOOLEAN:
			case IL_META_ELEMTYPE_I1:
			case IL_META_ELEMTYPE_U1:
			case IL_META_ELEMTYPE_I2:
			case IL_META_ELEMTYPE_U2:
			case IL_META_ELEMTYPE_CHAR:
			case IL_META_ELEMTYPE_I4:
			case IL_META_ELEMTYPE_U4:		return ILEngineType_I4;

			case IL_META_ELEMTYPE_I8:
			case IL_META_ELEMTYPE_U8:		return ILEngineType_I8;

			case IL_META_ELEMTYPE_I:
			case IL_META_ELEMTYPE_U:		return ILEngineType_I;

			case IL_META_ELEMTYPE_R4:
			case IL_META_ELEMTYPE_R8:
			case IL_META_ELEMTYPE_R:		return ILEngineType_F;

			case IL_META_ELEMTYPE_TYPEDBYREF: return ILEngineType_TypedRef;
		}
		return ILEngineType_I4;
	}
	else if(ILType_IsValueType(type))
	{
		return ILEngineType_MV;
	}
	else if(ILType_IsComplex(type) && type != 0)
	{
		switch(ILType_Kind(type))
		{
			case IL_TYPE_COMPLEX_PTR:
			{
				/* Unsafe pointers are represented as native integers */
				return ILEngineType_I;
			}
			/* Not reached */

			case IL_TYPE_COMPLEX_BYREF:
			{
				/* Reference values are managed pointers */
				return ILEngineType_M;
			}
			/* Not reached */

			case IL_TYPE_COMPLEX_PINNED:
			{
				/* Pinned types are the same as their underlying type */
				return TypeToEngineType(ILType_Ref(type));
			}
			/* Not reached */

			case IL_TYPE_COMPLEX_CMOD_REQD:
			case IL_TYPE_COMPLEX_CMOD_OPT:
			{
				/* Strip the modifier and inspect the underlying type */
				return TypeToEngineType(type->un.modifier__.type__);
			}
			/* Not reached */

			case IL_TYPE_COMPLEX_METHOD:
			case IL_TYPE_COMPLEX_METHOD | IL_TYPE_COMPLEX_METHOD_SENTINEL:
			{
				/* Pass method pointers around the system as "I".  Higher
				   level code will also set the "typeInfo" field to reflect
				   the signature so that method pointers become verifiable */
				return ILEngineType_I;
			}
			/* Not reached */
		}
	}
	return ILEngineType_O;
}
ILUInt32 ILPInvokeGetMarshalType(ILPInvoke *pinvoke, ILMethod *method,
								 unsigned long param, char **customName,
								 int *customNameLen, char **customCookie,
								 int *customCookieLen, ILType *type)
{
	ILParameter *parameter;
	ILFieldMarshal *marshal;
	const unsigned char *nativeType;
	unsigned long nativeTypeLen;
	int nativeTypeCode;

	/* Find the parameter information block */
	if(method)
	{
		if(!(method->parameters))
		{
			_ILMethodLoadParams(method);
		}
		parameter = method->parameters;
		while(parameter != 0 && parameter->paramNum != param)
		{
			parameter = parameter->next;
		}
	}
	else
	{
		parameter = 0;
	}

	/* See if we have native type information for the parameter */
	nativeType = 0;
	nativeTypeLen = 0;
	nativeTypeCode = IL_META_NATIVETYPE_END;
	if(parameter != 0)
	{
		marshal = ILFieldMarshalGetFromOwner(&(parameter->programItem));
		if(marshal != 0)
		{
			nativeType = (const unsigned char *)
				ILFieldMarshalGetType(marshal, &nativeTypeLen);
			if(nativeTypeLen > 0)
			{
				nativeTypeCode = (int)(nativeType[0]);
			}
		}
	}

	/* Initialize the custom name return information to nothing */
	*customName = 0;
	*customNameLen = 0;
	*customCookie = 0;
	*customCookieLen = 0;

	/* If the native type is "interface", then always marshal directly.
	   This is normally used to force strings, delegates, and arrays
	   to be passed as objects */
	if(nativeTypeCode == IL_META_NATIVETYPE_INTF)
	{
		return IL_META_MARSHAL_DIRECT;
	}

	/* Check for custom marshalling */
	if(nativeTypeCode == IL_META_NATIVETYPE_CUSTOMMARSHALER &&
	   ILTypeIsReference(type))
	{
		ILMetaDataRead reader;
		reader.data = nativeType + 1;
		reader.len = nativeTypeLen - 1;
		reader.error = 0;
		ExtractCustomString(customName, customNameLen);	/* Unused GUID */
		ExtractCustomString(customName, customNameLen);	/* Unused native name */
		ExtractCustomString(customName, customNameLen);
		ExtractCustomString(customCookie, customCookieLen);
		if(*customNameLen > 0)
		{
			return IL_META_MARSHAL_CUSTOM;
		}
		else
		{
			return IL_META_MARSHAL_DIRECT;
		}
	}

	/* Determine what to do based on the parameter type */
	if(ILTypeIsStringClass(type))
	{
		/* Value string type */
		if(nativeTypeCode == IL_META_NATIVETYPE_LPWSTR)
		{
		#ifdef IL_WIN32_PLATFORM
			return IL_META_MARSHAL_UTF16_STRING;
		#else
			return IL_META_MARSHAL_UTF8_STRING;
		#endif
		}
		else if(nativeTypeCode == IL_META_NATIVETYPE_LPSTR)
		{
			return IL_META_MARSHAL_ANSI_STRING;
		}
		else
		{
			return ILPInvokeGetCharSet(pinvoke, method);
		}
	}
	else if(ILTypeIsDelegateSubClass(type))
	{
		/* Delegate type */
		return IL_META_MARSHAL_FNPTR;
	}
	else if(ILType_IsSimpleArray(type))
	{
		if(ILTypeIsStringClass(ILTypeGetElemType(type)))
		{
			/* Array of strings, passed as "char **" */
			switch(ILPInvokeGetCharSet(pinvoke, method))
			{
				case IL_META_MARSHAL_UTF8_STRING:
				{
					return IL_META_MARSHAL_UTF8_ARRAY;
				}
				/* not reached */
	
				case IL_META_MARSHAL_UTF16_STRING:
				{
					return IL_META_MARSHAL_UTF16_ARRAY;
				}
				/* not reached */

				default:
				{
					return IL_META_MARSHAL_ANSI_ARRAY;
				}
				/* not reached */
			}
		}
		else
		{
			/* Array type, passed in by pointer to the first element */
			return IL_META_MARSHAL_ARRAY;
		}
	}
	else if(type != 0 && ILType_IsComplex(type) &&
			ILType_Kind(type) == IL_TYPE_COMPLEX_BYREF)
	{
		/* Check for "ref String[]", which is used by Gtk# when
		   calling the "gtk_init" function */
		if(ILType_IsSimpleArray(ILType_Ref(type)) &&
		   ILTypeIsStringClass(ILTypeGetElemType(ILType_Ref(type))))
		{
			switch(ILPInvokeGetCharSet(pinvoke, method))
			{
				case IL_META_MARSHAL_UTF8_STRING:
				{
					return IL_META_MARSHAL_REF_UTF8_ARRAY;
				}
				/* not reached */
	
				case IL_META_MARSHAL_UTF16_STRING:
				{
					return IL_META_MARSHAL_REF_UTF16_ARRAY;
				}
				/* not reached */

				default:
				{
					return IL_META_MARSHAL_REF_ANSI_ARRAY;
				}
				/* not reached */
			}
			return IL_META_MARSHAL_REF_ANSI_ARRAY;
		}
	}

	/* Marshal the parameter directly */
	return IL_META_MARSHAL_DIRECT;
}