Exemple #1
0
/*
 * 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;
	}
}
/*
 * public static bool ClrSetTypedReference(TypedReference target,
 *										   Object value);
 */
ILBool _IL_TypedReference_ClrSetTypedReference(ILExecThread *_thread,
										       ILTypedRef target,
										       ILObject *value)
{
	ILType *type;
	if(target.type == 0 || target.value == 0)
	{
		/* This is an invalid typed reference */
		return 0;
	}
	type = ILClassToType(target.type);
	if(ILType_IsPrimitive(type) || ILType_IsValueType(type))
	{
		if(!ILExecThreadUnbox(_thread, type, value, target.value))
		{
			return 0;
		}
		return 1;
	}
	else if(ILTypeAssignCompatible
				(ILProgramItem_Image(_thread->method),
			     (value ? ILClassToType(GetObjectClass(value)) : 0),
			     type))
	{
		*((ILObject **)(target.value)) = value;
		return 1;
	}
	else
	{
		return 0;
	}
}
Exemple #3
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;
	}
}
Exemple #4
0
/*
 * Populate a list of "ffi" type descriptors with information
 * about the non-static fields of a class.  Returns zero if
 * out of memory.
 */
static int PopulateStructFFI(ILExecProcess *process, ILClass *classInfo,
							  ffi_type **fieldTypes, unsigned *posn)
{
	ILClass *parent;
	ILField *field;
	ILType *type;
	ffi_type *ffi;

	/* Process the parent class first */
	parent = ILClass_ParentClass(classInfo);
	if(parent)
	{
		if(!PopulateStructFFI(process, parent, fieldTypes, posn))
		{
			return 0;
		}
	}

	/* Process the non-static fields in this class */
	field = 0;
	while((field = (ILField *)ILClassNextMemberByKind
			(classInfo, (ILMember *)field, IL_META_MEMBERKIND_FIELD)) != 0)
	{
		if(!ILField_IsStatic(field))
		{
			type = ILTypeGetEnumType(ILField_Type(field));
			if(ILType_IsValueType(type))
			{
				/* Process an embedded structure type */
				ffi = StructToFFI(process, ILType_ToValueType(type));
				if(!ffi)
				{
					return 0;
				}
			}
			else
			{
				/* Process a non-structure type */
				ffi = TypeToFFI(process, type, 0);
			}
			fieldTypes[(*posn)++] = ffi;
		}
	}

	/* Done */
	return 1;
}
/*
 * private static Object InternalGetUnitializaedObject(Type type);
 */
ILObject *_IL_FormatterServices_InternalGetUninitializedObject
				(ILExecThread *_thread, ILObject *type)
{
	ILClass *classInfo = _ILGetClrClass(_thread, type);
	ILType *classType;
	if(classInfo)
	{
		classType = ILClassToType(classInfo);
		if(classType && (ILType_IsClass(classType) ||
						 ILType_IsValueType(classType) ||
						 ILType_IsPrimitive(classType)) &&
		   !ILTypeIsStringClass(classType))
		{
			return _ILEngineAllocObject(_thread, classInfo);
		}
	}
	return 0;
}
Exemple #6
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;
}
/*
 * Convert a type into its primitive form, ignoring slight differences
 * in type that don't matter because we can blindly cast between the
 * equivalents without losing type-safety.
 */
static int ArgTypeToPrimitive(ILType *type)
{
	if(ILType_IsPrimitive(type))
	{
		switch(ILType_ToElement(type))
		{
			case IL_META_ELEMTYPE_BOOLEAN:
			case IL_META_ELEMTYPE_I1:
			case IL_META_ELEMTYPE_U1:
				return IL_META_ELEMTYPE_I1;

			case IL_META_ELEMTYPE_I2:
			case IL_META_ELEMTYPE_U2:
			case IL_META_ELEMTYPE_CHAR:
				return IL_META_ELEMTYPE_I2;

			case IL_META_ELEMTYPE_I4:
			case IL_META_ELEMTYPE_U4:
		#ifdef IL_NATIVE_INT32
			case IL_META_ELEMTYPE_I:
			case IL_META_ELEMTYPE_U:
		#endif
				return IL_META_ELEMTYPE_I4;

			case IL_META_ELEMTYPE_I8:
			case IL_META_ELEMTYPE_U8:
		#ifdef IL_NATIVE_INT64
			case IL_META_ELEMTYPE_I:
			case IL_META_ELEMTYPE_U:
		#endif
				return IL_META_ELEMTYPE_I8;

			case IL_META_ELEMTYPE_R4:
				return IL_META_ELEMTYPE_R4;

			case IL_META_ELEMTYPE_R8:
			case IL_META_ELEMTYPE_R:
				return IL_META_ELEMTYPE_R8;

			default: break;
		}
		return IL_META_ELEMTYPE_END;
	}
	else if(ILType_IsValueType(type))
	{
		if(ILTypeIsEnum(type))
		{
			return ArgTypeToPrimitive(ILTypeGetEnumType(type));
		}
		else
		{
			return IL_META_ELEMTYPE_VALUETYPE;
		}
	}
	else if(ILType_IsPointer(type))
	{
	#ifdef IL_NATIVE_INT32
		return IL_META_ELEMTYPE_I4;
	#else
		return IL_META_ELEMTYPE_I8;
	#endif
	}
	else
	{
		return IL_META_ELEMTYPE_END;
	}
}
Exemple #8
0
/*
 * Unpack the result of a delegate closure call.
 */
static void UnpackDelegateResult(ILExecThread *thread, ILMethod *method,
					             int isCtor, void *result, void *userData)
{
	ILMethod *pinvokeInfo = ((PackDelegateUserData *)userData)->pinvokeInfo;
	ILType *signature = ILMethod_Signature(method);
	ILType *paramType;
	ILUInt32 size, sizeInWords;
	ILNativeFloat tempFloat;
	ILUInt32 marshalType;
	char *customName;
	int customNameLen;
	char *customCookie;
	int customCookieLen;

	/* Marshal return types that need special handling */
	marshalType = ILPInvokeGetMarshalType
			(0, pinvokeInfo, 0, &customName, &customNameLen,
			 &customCookie, &customCookieLen, ILTypeGetReturn(signature));
	if(marshalType != IL_META_MARSHAL_DIRECT)
	{
		switch(marshalType)
		{
			case IL_META_MARSHAL_ANSI_STRING:
			{
				/* Marshal an ANSI string back to the native world */
				*((char **)result) = ILStringToAnsi
					(thread, (ILString *)(thread->stackTop[-1].ptrValue));
				--(thread->stackTop);
			}
			return;

			case IL_META_MARSHAL_UTF8_STRING:
			{
				/* Marshal a UTF-8 string back to the native world */
				*((char **)result) = ILStringToUTF8
					(thread, (ILString *)(thread->stackTop[-1].ptrValue));
				--(thread->stackTop);
			}
			return;

			case IL_META_MARSHAL_UTF16_STRING:
			{
				/* Marshal a UTF-16 string back to the native world */
				*((ILUInt16 **)result) = ILStringToUTF16
					(thread, (ILString *)(thread->stackTop[-1].ptrValue));
				--(thread->stackTop);
			}
			return;

			case IL_META_MARSHAL_FNPTR:
			{
				/* Convert a delegate into a function closure pointer */
				*((void **)result) = _ILDelegateGetClosure
					(thread, (ILObject *)(thread->stackTop[-1].ptrValue));
				--(thread->stackTop);
			}
			return;

			case IL_META_MARSHAL_ARRAY:
			{
				/* Convert an array into a pointer to its first member */
				void *array = thread->stackTop[-1].ptrValue;
				--(thread->stackTop);
				if(array)
				{
					*((void **)result) = ArrayToBuffer(array);
				}
				else
				{
					*((void **)result) = 0;
				}
			}
			return;

			case IL_META_MARSHAL_CUSTOM:
			{
				/* Marshal a custom value to the native world */
				*((void **)result) = _ILObjectToCustom
					(thread, (ILObject *)(thread->stackTop[-1].ptrValue),
					 customName, customNameLen, customCookie, customCookieLen);
				--(thread->stackTop);
			}
			return;
		}
	}

	/* Copy the return value into place */
	paramType = ILTypeGetEnumType(ILTypeGetReturn(signature));
	if(ILType_IsPrimitive(paramType))
	{
		/* Process a primitive value */
		switch(ILType_ToElement(paramType))
		{
			case IL_META_ELEMTYPE_VOID:		break;

			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:
		#ifdef IL_NATIVE_INT32
			case IL_META_ELEMTYPE_I:
			case IL_META_ELEMTYPE_U:
		#endif
			{
				*((ILInt32 *)result) = thread->stackTop[-1].intValue;
				--(thread->stackTop);
			}
			break;

			case IL_META_ELEMTYPE_I8:
			case IL_META_ELEMTYPE_U8:
		#ifdef IL_NATIVE_INT64
			case IL_META_ELEMTYPE_I:
			case IL_META_ELEMTYPE_U:
		#endif
			{
				ILMemCpy(result,
						 thread->stackTop - CVM_WORDS_PER_LONG,
						 sizeof(ILInt64));
				thread->stackTop -= CVM_WORDS_PER_LONG;
			}
			break;

			case IL_META_ELEMTYPE_R4:
			{
				ILMemCpy(&tempFloat,
						 thread->stackTop - CVM_WORDS_PER_NATIVE_FLOAT,
						 sizeof(ILNativeFloat));
				*((ILFloat *)result) = (ILFloat)tempFloat;
				thread->stackTop -= CVM_WORDS_PER_NATIVE_FLOAT;
			}
			break;

			case IL_META_ELEMTYPE_R8:
			{
				ILMemCpy(&tempFloat,
						 thread->stackTop - CVM_WORDS_PER_NATIVE_FLOAT,
						 sizeof(ILNativeFloat));
				*((ILDouble *)result) = (ILDouble)tempFloat;
				thread->stackTop -= CVM_WORDS_PER_NATIVE_FLOAT;
			}
			break;

			case IL_META_ELEMTYPE_R:
			{
				ILMemCpy(result,
						 thread->stackTop - CVM_WORDS_PER_NATIVE_FLOAT,
						 sizeof(ILNativeFloat));
				thread->stackTop -= CVM_WORDS_PER_NATIVE_FLOAT;
			}
			break;

			case IL_META_ELEMTYPE_TYPEDBYREF:
			{
				ILMemCpy(result,
						 thread->stackTop - CVM_WORDS_PER_TYPED_REF,
						 sizeof(ILTypedRef));
				thread->stackTop -= CVM_WORDS_PER_TYPED_REF;
			}
			break;
		}
	}
	else if(ILType_IsClass(paramType))
	{
		/* Process an object reference */
		*((void **)result) = thread->stackTop[-1].ptrValue;
		--(thread->stackTop);
	}
	else if(ILType_IsValueType(paramType))
	{
		/* Process a value type */
		size = ILSizeOfType(thread, paramType);
		sizeInWords = ((size + sizeof(CVMWord) - 1) / sizeof(CVMWord));
		ILMemCpy(result, thread->stackTop - sizeInWords, size);
		thread->stackTop -= sizeInWords;
	}
	else
	{
		/* Assume that everything else is an object reference */
		*((void **)result) = thread->stackTop[-1].ptrValue;
		--(thread->stackTop);
	}
}
Exemple #9
0
/*
 * Pack the parameters for a delegate closure call onto the CVM stack.
 */
static int PackDelegateParams(ILExecThread *thread, ILMethod *method,
					          int isCtor, void *_this, void *userData)
{
	void **args = ((PackDelegateUserData *)userData)->args;
	ILMethod *pinvokeInfo = ((PackDelegateUserData *)userData)->pinvokeInfo;
	ILType *signature = ILMethod_Signature(method);
	CVMWord *stacktop, *stacklimit;
	ILUInt32 param, numParams;
	ILType *paramType;
	void *ptr;
	ILUInt32 size, sizeInWords;
	ILNativeFloat tempFloat;
	ILUInt32 marshalType;
	char *customName;
	int customNameLen;
	char *customCookie;
	int customCookieLen;
	char *strValue;

	/* Get the top and extent of the stack */
	stacktop = thread->stackTop;
	stacklimit = thread->stackLimit;

	/* Push the arguments onto the evaluation stack */
	if(ILType_HasThis(signature))
	{
		/* Push the "this" argument */
		CHECK_SPACE(1);
		if(((PackDelegateUserData *)userData)->needThis)
		{
			/* We get the "this" value from the incoming arguments */
			stacktop->ptrValue = *((void **)(*args));
			++args;
		}
		else
		{
			/* We get the "this" value from the delegate object */
			stacktop->ptrValue = _this;
		}
		++stacktop;
	}
	numParams = ILTypeNumParams(signature);
	for(param = 1; param <= numParams; ++param)
	{
		/* Marshal parameters that need special handling */
		marshalType = ILPInvokeGetMarshalType(0, pinvokeInfo, param,
											  &customName, &customNameLen,
											  &customCookie, &customCookieLen,
											  ILTypeGetParam(signature, param));
		if(marshalType != IL_META_MARSHAL_DIRECT)
		{
			switch(marshalType)
			{
				case IL_META_MARSHAL_ANSI_STRING:
				{
					/* Marshal an ANSI string from the native world */
					CHECK_SPACE(1);
					strValue = *((char **)(*args));
					if(strValue)
					{
						stacktop->ptrValue = ILStringCreate(thread, strValue);

						/* Free the native string */
						ILFreeNativeString(strValue);

						if(!(stacktop->ptrValue))
						{
							return 1;
						}
					}
					else
					{
						stacktop->ptrValue = 0;
					}
					++args;
					++stacktop;
				}
				continue;

				case IL_META_MARSHAL_UTF8_STRING:
				{
					/* Marshal a UTF-8 string from the native world */
					CHECK_SPACE(1);
					strValue = *((char **)(*args));
					if(strValue)
					{
						stacktop->ptrValue =
							ILStringCreateUTF8(thread, strValue);

						/* Free the native string */
						ILFreeNativeString(strValue);

						if(!(stacktop->ptrValue))
						{
							return 1;
						}
					}
					else
					{
						stacktop->ptrValue = 0;
					}
					++args;
					++stacktop;
				}
				continue;

				case IL_META_MARSHAL_UTF16_STRING:
				{
					/* Marshal a UTF-16 string from the native world */
					CHECK_SPACE(1);
					strValue = *((char **)(*args));
					if(strValue)
					{
						stacktop->ptrValue =
							ILStringWCreate(thread, (ILUInt16 *)strValue);

						/* Free the native string */
						ILFreeNativeString(strValue);
					
						if(!(stacktop->ptrValue))
						{
							return 1;
						}
					}
					else
					{
						stacktop->ptrValue = 0;
					}
					++args;
					++stacktop;
				}
				continue;

				case IL_META_MARSHAL_CUSTOM:
				{
					/* Marshal a custom value from the native world */
					CHECK_SPACE(1);
					stacktop->ptrValue = _ILCustomToObject
						(thread, *((void **)(*args)),
						 customName, customNameLen,
						 customCookie, customCookieLen);
					if(_ILExecThreadHasException(thread))
					{
						return 1;
					}
					++args;
					++stacktop;
				}
				continue;
			}
		}

		/* Marshal the parameter directly */
		paramType = ILTypeGetEnumType(ILTypeGetParam(signature, param));
		if(ILType_IsPrimitive(paramType))
		{
			/* Process a primitive value */
			switch(ILType_ToElement(paramType))
			{
				case IL_META_ELEMTYPE_VOID:		break;

				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:
			#ifdef IL_NATIVE_INT32
				case IL_META_ELEMTYPE_I:
				case IL_META_ELEMTYPE_U:
			#endif
				{
					CHECK_SPACE(1);
					stacktop->intValue = *((ILInt32 *)(*args));
					++args;
					++stacktop;
				}
				break;

				case IL_META_ELEMTYPE_I8:
				case IL_META_ELEMTYPE_U8:
			#ifdef IL_NATIVE_INT64
				case IL_META_ELEMTYPE_I:
				case IL_META_ELEMTYPE_U:
			#endif
				{
					CHECK_SPACE(CVM_WORDS_PER_LONG);
					ILMemCpy(stacktop, *args, sizeof(ILInt64));
					++args;
					stacktop += CVM_WORDS_PER_LONG;
				}
				break;

				case IL_META_ELEMTYPE_R4:
				{
					CHECK_SPACE(CVM_WORDS_PER_NATIVE_FLOAT);
					tempFloat = (ILNativeFloat)(*((ILFloat *)(*args)));
					ILMemCpy(stacktop, &tempFloat, sizeof(ILNativeFloat));
					++args;
					stacktop += CVM_WORDS_PER_NATIVE_FLOAT;
				}
				break;

				case IL_META_ELEMTYPE_R8:
				{
					CHECK_SPACE(CVM_WORDS_PER_NATIVE_FLOAT);
					tempFloat = (ILNativeFloat)(*((ILDouble *)(*args)));
					ILMemCpy(stacktop, &tempFloat, sizeof(ILNativeFloat));
					++args;
					stacktop += CVM_WORDS_PER_NATIVE_FLOAT;
				}
				break;

				case IL_META_ELEMTYPE_R:
				{
					CHECK_SPACE(CVM_WORDS_PER_NATIVE_FLOAT);
					ILMemCpy(stacktop, *args, sizeof(ILNativeFloat));
					++args;
					stacktop += CVM_WORDS_PER_NATIVE_FLOAT;
				}
				break;

				case IL_META_ELEMTYPE_TYPEDBYREF:
				{
					CHECK_SPACE(CVM_WORDS_PER_TYPED_REF);
					ILMemCpy(stacktop, *args, sizeof(ILTypedRef));
					++args;
					stacktop += CVM_WORDS_PER_TYPED_REF;
				}
				break;
			}
		}
		else if(ILType_IsClass(paramType))
		{
			/* Process an object reference */
			CHECK_SPACE(1);
			stacktop->ptrValue = *((void **)(*args));
			++args;
			++stacktop;
		}
		else if(ILType_IsValueType(paramType))
		{
			/* Process a value type which was passed by value */
			ptr = *args;
			++args;
			size = ILSizeOfType(thread, paramType);
			sizeInWords = ((size + sizeof(CVMWord) - 1) / sizeof(CVMWord));
			CHECK_SPACE(sizeInWords);
			ILMemCpy(stacktop, ptr, size);
			stacktop += sizeInWords;
		}
		else if(paramType != 0 && ILType_IsComplex(paramType) &&
				(ILType_Kind(paramType) == IL_TYPE_COMPLEX_BYREF || 
				 ILType_Kind(paramType) == IL_TYPE_COMPLEX_PTR))
		{
			/* Process a value that is being passed by reference */
			CHECK_SPACE(1);
			stacktop->ptrValue = *((void **)(*args));
			++args;
			++stacktop;
		}
		else
		{
			/* Assume that everything else is an object reference */
			CHECK_SPACE(1);
			stacktop->ptrValue = *args;
			++args;
			++stacktop;
		}
	}

	/* Update the stack top */
	thread->stackTop = stacktop;
	return 0;
}
Exemple #10
0
void *_ILMakeCifForMethod(ILExecProcess *process, ILMethod *method, int isInternal)
{
	ILType *signature = ILMethod_Signature(method);
	ILType *returnType = ILTypeGetEnumType(ILTypeGetReturn(signature));
	ILType *modReturnType = returnType;
	ILUInt32 numArgs;
	ILUInt32 numParams;
	ffi_cif *cif;
	ffi_type **args;
	ffi_type *rtype;
	ILUInt32 arg;
	ILUInt32 param;

	/* Determine the number of argument blocks that we need */
	numArgs = numParams = ILTypeNumParams(signature);
	if(ILType_HasThis(signature))
	{
		++numArgs;
	}
	if(isInternal)
	{
		/* This is an "internalcall" or "runtime" method
		   which needs an extra argument for the thread */
		++numArgs;
		if(ILType_IsValueType(returnType))
		{
			/* We need an extra argument to pass a pointer to
			   the buffer to use to return the result */
			++numArgs;
			modReturnType = ILType_Void;
		}
	}

	/* Allocate space for the cif */
	cif = (ffi_cif *)ILMalloc(sizeof(ffi_cif) +
							  sizeof(ffi_type *) * numArgs);
	if(!cif)
	{
		return 0;
	}
	args = ((ffi_type **)(cif + 1));

	/* Convert the return type */
	rtype = TypeToFFI(process, modReturnType, isInternal);

	/* Convert the argument types */
	arg = 0;
	if(isInternal)
	{
		/* Pointer argument for the thread */
		args[arg++] = &ffi_type_pointer;
		if(ILType_IsValueType(returnType))
		{
			/* Pointer argument for value type returns */
			args[arg++] = &ffi_type_pointer;
		}
	}
	if(ILType_HasThis(signature))
	{
		/* Pointer argument for "this" */
		args[arg++] = &ffi_type_pointer;
	}
	for(param = 1; param <= numParams; ++param)
	{
		args[arg++] = TypeToFFI(process, ILTypeGetEnumType
									(ILTypeGetParam(signature, param)),
							    isInternal);
	}

	/* Limit the number of arguments if we cannot use raw mode */
	if(!_ILCVMCanUseRawCalls(method, isInternal) &&
	   numArgs > (CVM_MAX_NATIVE_ARGS + 1))
	{
		numArgs = CVM_MAX_NATIVE_ARGS + 1;
	}

	/* Prepare the "ffi_cif" structure for the call */
	if(ffi_prep_cif(cif, FFI_DEFAULT_ABI, numArgs, rtype, args) != FFI_OK)
	{
		fprintf(stderr, "Cannot marshal a type in the definition of %s::%s\n",
				ILClass_Name(ILMethod_Owner(method)), ILMethod_Name(method));
		return 0;
	}

	/* Ready to go */
	return (void *)cif;
}