/*
 * Make a value type.
 */
static void MakeValueType(ILGenInfo *info, ILImage *image,
						  const char *name, ILClass *parent,
						  ILClass *stringClass)
{
	ILClass *newClass;
	ABORT_IF(newClass, ILClassCreate(ILClassGlobalScope(image),
									 0, name, "System", parent));
	ILClassSetAttrs(newClass, ~0,
					IL_META_TYPEDEF_PUBLIC |
				    IL_META_TYPEDEF_VALUE_TYPE |
				    IL_META_TYPEDEF_LAYOUT_SEQUENTIAL |
				    IL_META_TYPEDEF_SERIALIZABLE |
				    IL_META_TYPEDEF_BEFORE_FIELD_INIT |
				    IL_META_TYPEDEF_SEALED);
	if(!AddMethod(newClass, "ToString",
				  ILType_FromClass(stringClass), ILType_Void, ILType_Void,
				  IL_META_METHODDEF_VIRTUAL))
	{
		ILGenOutOfMemory(info);
	}
}
Example #2
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;
}
void ILGenMakeLibrary(ILGenInfo *info)
{
	ILImage *image = info->libImage;
	ILProgramItem *scope = ILClassGlobalScope(image);
	ILClass *objectClass;
	ILClass *stringClass;
	ILClass *typeClass;
	ILClass *valueTypeClass;
	ILClass *enumClass;
	ILClass *voidClass;
	ILClass *intPtrClass;
	ILClass *uintPtrClass;
	ILClass *typedRefClass;
	ILClass *argIterClass;
	ILClass *argHandleClass;
	ILClass *attributeClass;
	ILClass *paramAttributeClass;
	ILClass *defMemberAttributeClass;
	ILClass *decimalConstantClass;
	ILClass *exceptionClass;
	ILClass *disposableInterface;
	ILClass *asyncResultInterface;
	ILClass *collectionInterface;
	ILClass *enumeratorInterface;
	ILClass *isVolatileClass;
	ILClass *delegateClass;
	ILClass *multicastDelegateClass;
	ILClass *asyncCallbackClass;
	int constructorOK;
	ILMethod *method;
	ILProperty *property;
	ILType *signature;

	/* Create the "System.Object" class */
	ABORT_IF(objectClass, ILClassCreate(scope, 0, "Object", "System", 0));
	ILClassSetAttrs(objectClass, ~0,
				    IL_META_TYPEDEF_PUBLIC |
				    IL_META_TYPEDEF_BEFORE_FIELD_INIT |
					IL_META_TYPEDEF_SERIALIZABLE);
	ABORT_IF(constructorOK, AddDefaultConstructor(objectClass));

	/* Create the "System.String" class */
	ABORT_IF(stringClass,
			 ILClassCreate(scope, 0, "String", "System", objectClass));
	ILClassSetAttrs(stringClass, ~0,
					IL_META_TYPEDEF_PUBLIC |
				    IL_META_TYPEDEF_SERIALIZABLE |
					IL_META_TYPEDEF_BEFORE_FIELD_INIT |
				    IL_META_TYPEDEF_SEALED);

	/* Create the "System.Type" class */
	ABORT_IF(typeClass,
			 ILClassCreate(scope, 0, "Type", "System", objectClass));
	ILClassSetAttrs(typeClass, ~0,
					IL_META_TYPEDEF_PUBLIC |
				    IL_META_TYPEDEF_SERIALIZABLE |
					IL_META_TYPEDEF_BEFORE_FIELD_INIT |
				    IL_META_TYPEDEF_ABSTRACT);
	ABORT_IF(constructorOK, AddDefaultConstructor(typeClass));

	/* Add the "ToString" and "GetType" methods to the "System.Object" class */
	if(!AddMethod(objectClass, "ToString",
				  ILType_FromClass(stringClass), ILType_Void, ILType_Void,
				  IL_META_METHODDEF_VIRTUAL | IL_META_METHODDEF_NEW_SLOT))
	{
		ILGenOutOfMemory(info);
	}
	if(!AddMethod(objectClass, "GetType",
				  ILType_FromClass(typeClass),
				  ILType_Void, ILType_Void, 0))
	{
		ILGenOutOfMemory(info);
	}

	/* Add the "==" and "!=" operators to the "System.String" class */
	if(!AddMethod(stringClass, "op_Equality",
				  ILType_Boolean, ILType_FromClass(stringClass),
				  ILType_FromClass(stringClass),
				  IL_META_METHODDEF_STATIC | IL_META_METHODDEF_SPECIAL_NAME))
	{
		ILGenOutOfMemory(info);
	}
	if(!AddMethod(stringClass, "op_Inequality",
				  ILType_Boolean, ILType_FromClass(stringClass),
				  ILType_FromClass(stringClass),
				  IL_META_METHODDEF_STATIC | IL_META_METHODDEF_SPECIAL_NAME))
	{
		ILGenOutOfMemory(info);
	}

	/* Create the "System.ValueType" class */
	ABORT_IF(valueTypeClass,
			 ILClassCreate(scope, 0, "ValueType", "System", objectClass));
	ILClassSetAttrs(valueTypeClass, ~0,
					IL_META_TYPEDEF_PUBLIC |
					IL_META_TYPEDEF_BEFORE_FIELD_INIT |
				    IL_META_TYPEDEF_SERIALIZABLE);
	ABORT_IF(constructorOK, AddDefaultConstructor(valueTypeClass));

	/* Create the "System.Enum" class */
	ABORT_IF(enumClass,
			 ILClassCreate(scope, 0, "Enum", "System", valueTypeClass));
	ILClassSetAttrs(enumClass, ~0,
					IL_META_TYPEDEF_PUBLIC |
					IL_META_TYPEDEF_ABSTRACT |
					IL_META_TYPEDEF_BEFORE_FIELD_INIT |
				    IL_META_TYPEDEF_SERIALIZABLE);
	ABORT_IF(constructorOK, AddDefaultConstructor(enumClass));

	/* Create the "System.Void" class */
	ABORT_IF(voidClass,
			 ILClassCreate(scope, 0, "Void", "System", valueTypeClass));
	ILClassSetAttrs(voidClass, ~0,
					IL_META_TYPEDEF_PUBLIC |
				    IL_META_TYPEDEF_VALUE_TYPE |
					IL_META_TYPEDEF_BEFORE_FIELD_INIT |
					IL_META_TYPEDEF_SEALED);

	/* Create the numeric value types */
	MakeValueType(info, image, "SByte", valueTypeClass, stringClass);
	MakeValueType(info, image, "Byte", valueTypeClass, stringClass);
	MakeValueType(info, image, "Int16", valueTypeClass, stringClass);
	MakeValueType(info, image, "UInt16", valueTypeClass, stringClass);
	MakeValueType(info, image, "Int32", valueTypeClass, stringClass);
	MakeValueType(info, image, "UInt32", valueTypeClass, stringClass);
	MakeValueType(info, image, "Int64", valueTypeClass, stringClass);
	MakeValueType(info, image, "UInt64", valueTypeClass, stringClass);
	MakeValueType(info, image, "Single", valueTypeClass, stringClass);
	MakeValueType(info, image, "Double", valueTypeClass, stringClass);
	MakeValueType(info, image, "Decimal", valueTypeClass, stringClass);

	/* Create the "System.IntPtr" class */
	ABORT_IF(intPtrClass,
			 ILClassCreate(scope, 0, "IntPtr", "System", valueTypeClass));
	ILClassSetAttrs(intPtrClass, ~0,
					IL_META_TYPEDEF_PUBLIC |
				    IL_META_TYPEDEF_VALUE_TYPE |
				    IL_META_TYPEDEF_SERIALIZABLE |
					IL_META_TYPEDEF_BEFORE_FIELD_INIT |
				    IL_META_TYPEDEF_SEALED);

	/* Create the "System.UIntPtr" class */
	ABORT_IF(uintPtrClass,
			 ILClassCreate(scope, 0, "UIntPtr", "System", valueTypeClass));
	ILClassSetAttrs(uintPtrClass, ~0,
					IL_META_TYPEDEF_PUBLIC |
				    IL_META_TYPEDEF_VALUE_TYPE |
				    IL_META_TYPEDEF_SERIALIZABLE |
					IL_META_TYPEDEF_BEFORE_FIELD_INIT |
				    IL_META_TYPEDEF_SEALED);

	/* Create the "System.TypedReference" class */
	ABORT_IF(typedRefClass,
			 ILClassCreate(scope, 0, "TypedReference", "System",
			 			   valueTypeClass));
	ILClassSetAttrs(typedRefClass, ~0,
					IL_META_TYPEDEF_PUBLIC |
				    IL_META_TYPEDEF_VALUE_TYPE |
				    IL_META_TYPEDEF_SERIALIZABLE |
					IL_META_TYPEDEF_BEFORE_FIELD_INIT |
				    IL_META_TYPEDEF_SEALED);

	/* Create the "System.ArgIterator" class */
	ABORT_IF(argIterClass,
			 ILClassCreate(scope, 0, "ArgIterator", "System",
			 			   valueTypeClass));
	ILClassSetAttrs(argIterClass, ~0,
					IL_META_TYPEDEF_PUBLIC |
				    IL_META_TYPEDEF_VALUE_TYPE |
				    IL_META_TYPEDEF_SERIALIZABLE |
					IL_META_TYPEDEF_BEFORE_FIELD_INIT |
				    IL_META_TYPEDEF_SEALED);

	/* Create the "System.RuntimeArgumentHandle" class */
	ABORT_IF(argHandleClass,
			 ILClassCreate(scope, 0, "RuntimeArgumentHandle", "System",
			 			   valueTypeClass));
	ILClassSetAttrs(argHandleClass, ~0,
					IL_META_TYPEDEF_PUBLIC |
				    IL_META_TYPEDEF_VALUE_TYPE |
				    IL_META_TYPEDEF_SERIALIZABLE |
					IL_META_TYPEDEF_BEFORE_FIELD_INIT |
				    IL_META_TYPEDEF_SEALED);

	/* Create the "System.Attribute" class */
	ABORT_IF(attributeClass,
			 ILClassCreate(scope, 0, "Attribute", "System",
			 			   objectClass));
	ILClassSetAttrs(attributeClass, ~0,
					IL_META_TYPEDEF_PUBLIC |
				    IL_META_TYPEDEF_SERIALIZABLE |
					IL_META_TYPEDEF_BEFORE_FIELD_INIT |
				    IL_META_TYPEDEF_ABSTRACT);

	/* Create the "System.ParamArrayAttribute" class */
	ABORT_IF(paramAttributeClass,
			 ILClassCreate(scope, 0, "ParamArrayAttribute", "System",
			 			   attributeClass));
	ILClassSetAttrs(paramAttributeClass, ~0,
					IL_META_TYPEDEF_PUBLIC |
				    IL_META_TYPEDEF_SERIALIZABLE |
					IL_META_TYPEDEF_BEFORE_FIELD_INIT |
				    IL_META_TYPEDEF_SEALED);
	ABORT_IF(constructorOK, AddDefaultConstructor(paramAttributeClass));

	/* Create the "System.Reflection.DefaultMemberAttribute" class */
	ABORT_IF(defMemberAttributeClass,
			 ILClassCreate(scope, 0, "DefaultMemberAttribute",
			 			   "System.Reflection", attributeClass));
	ILClassSetAttrs(defMemberAttributeClass, ~0,
					IL_META_TYPEDEF_PUBLIC |
				    IL_META_TYPEDEF_SERIALIZABLE |
					IL_META_TYPEDEF_BEFORE_FIELD_INIT |
				    IL_META_TYPEDEF_SEALED);
	ABORT_IF(constructorOK,
			 AddParamConstructor(defMemberAttributeClass,
			 					 ILType_FromClass(stringClass), ILType_Void));

	/* Create "System.Runtime.CompilerServices.DecimalConstantAttribute" */
	ABORT_IF(decimalConstantClass,
			 ILClassCreate(scope, 0, "DecimalConstantAttribute",
			 			   "System.Runtime.CompilerServices",
			 			   attributeClass));
	ILClassSetAttrs(decimalConstantClass, ~0,
					IL_META_TYPEDEF_PUBLIC |
				    IL_META_TYPEDEF_SERIALIZABLE |
					IL_META_TYPEDEF_BEFORE_FIELD_INIT |
				    IL_META_TYPEDEF_SEALED);
	ABORT_IF(constructorOK, AddDecimalConstructor(decimalConstantClass));

	/* Create the "System.Exception" class */
	ABORT_IF(exceptionClass,
			 ILClassCreate(scope, 0, "Exception", "System",
			 			   objectClass));
	ILClassSetAttrs(exceptionClass, ~0,
					IL_META_TYPEDEF_PUBLIC |
				    IL_META_TYPEDEF_SERIALIZABLE |
					IL_META_TYPEDEF_BEFORE_FIELD_INIT);
	ABORT_IF(constructorOK, AddDefaultConstructor(exceptionClass));

	/* Create the "System.IDisposable" interface */
	ABORT_IF(disposableInterface,
			 ILClassCreate(scope, 0, "IDisposable", "System", 0));
	ILClassSetAttrs(disposableInterface, ~0,
					IL_META_TYPEDEF_PUBLIC |
				    IL_META_TYPEDEF_INTERFACE |
					IL_META_TYPEDEF_ABSTRACT);

	/* Create the "System.IAsyncResult" interface */
	ABORT_IF(asyncResultInterface,
			 ILClassCreate(scope, 0, "IAsyncResult", "System", 0));
	ILClassSetAttrs(asyncResultInterface, ~0,
					IL_META_TYPEDEF_PUBLIC |
				    IL_META_TYPEDEF_INTERFACE |
					IL_META_TYPEDEF_ABSTRACT);

	/* Create the "System.Collections.ICollection" interface */
	ABORT_IF(collectionInterface,
			 ILClassCreate(scope, 0, "ICollection", "System.Collections", 0));
	ILClassSetAttrs(collectionInterface, ~0,
					IL_META_TYPEDEF_PUBLIC |
				    IL_META_TYPEDEF_INTERFACE |
					IL_META_TYPEDEF_ABSTRACT);

	/* Create the "System.Collections.IEnumerator" interface */
	ABORT_IF(enumeratorInterface,
			 ILClassCreate(scope, 0, "IEnumerator", "System.Collections", 0));
	ILClassSetAttrs(enumeratorInterface, ~0,
					IL_META_TYPEDEF_PUBLIC |
				    IL_META_TYPEDEF_INTERFACE |
					IL_META_TYPEDEF_ABSTRACT);

	/* Add the "GetEnumerator" method to the "ICollection" interface */
	ABORT_IF(method, AddAbstractMethod(collectionInterface, "GetEnumerator",
									   ILType_FromClass(enumeratorInterface),
									   ILType_Void));

	/* Add the "MoveNext" and "Reset" methods to "IEnumerator" */
	ABORT_IF(method, AddAbstractMethod(enumeratorInterface, "MoveNext",
									   ILType_Boolean, ILType_Void));
	ABORT_IF(method, AddAbstractMethod(enumeratorInterface, "Reset",
									   ILType_Void, ILType_Void));

	/* Add the "Current" property to "IEnumerator" */
	ABORT_IF(method, AddAbstractMethod(enumeratorInterface, "get_Current",
									   ILType_FromClass(objectClass),
									   ILType_Void));
	ABORT_IF(signature, ILTypeCreateProperty(info->context,
									 		 ILType_FromClass(objectClass)));
	ILTypeSetCallConv(signature, IL_META_CALLCONV_HASTHIS);
	ABORT_IF(property, ILPropertyCreate(enumeratorInterface, 0, "Current",
										0, signature));
	if(!ILMethodSemCreate((ILProgramItem *)property, 0,
				  		  IL_META_METHODSEM_GETTER, method))
	{
		ILGenOutOfMemory(info);
	}

	/* Create the "System.Runtime.CompilerServices.IsVolatile" class */
	ABORT_IF(isVolatileClass,
			 ILClassCreate(scope, 0, "IsVolatile",
			 			   "System.Runtime.CompilerServices",
			 			   objectClass));
	ILClassSetAttrs(isVolatileClass, ~0,
					IL_META_TYPEDEF_PUBLIC |
					IL_META_TYPEDEF_SEALED |
				    IL_META_TYPEDEF_SERIALIZABLE |
					IL_META_TYPEDEF_BEFORE_FIELD_INIT);
	ABORT_IF(constructorOK, AddDefaultConstructor(isVolatileClass));

	/* Create the "System.Delegate" class */
	ABORT_IF(delegateClass,
			 ILClassCreate(scope, 0, "Delegate", "System", objectClass));
	ILClassSetAttrs(delegateClass, ~0,
					IL_META_TYPEDEF_PUBLIC |
				    IL_META_TYPEDEF_SERIALIZABLE |
					IL_META_TYPEDEF_BEFORE_FIELD_INIT |
				    IL_META_TYPEDEF_ABSTRACT);
	if(!AddMethod(delegateClass, "op_Equality", ILType_Boolean,
				  ILType_FromClass(delegateClass),
				  ILType_FromClass(delegateClass),
				  IL_META_METHODDEF_SPECIAL_NAME | IL_META_METHODDEF_STATIC))
	{
		ILGenOutOfMemory(info);
	}
	if(!AddMethod(delegateClass, "op_Inequality", ILType_Boolean,
				  ILType_FromClass(delegateClass),
				  ILType_FromClass(delegateClass),
				  IL_META_METHODDEF_SPECIAL_NAME | IL_META_METHODDEF_STATIC))
	{
		ILGenOutOfMemory(info);
	}

	/* Create the "System.MulticastDelegate" class */
	ABORT_IF(multicastDelegateClass,
			 ILClassCreate(scope, 0, "MulticastDelegate", "System",
			 			   delegateClass));
	ILClassSetAttrs(multicastDelegateClass, ~0,
					IL_META_TYPEDEF_PUBLIC |
				    IL_META_TYPEDEF_SERIALIZABLE |
					IL_META_TYPEDEF_BEFORE_FIELD_INIT |
				    IL_META_TYPEDEF_ABSTRACT);
	if(!AddMethod(multicastDelegateClass, "op_Equality", ILType_Boolean,
				  ILType_FromClass(multicastDelegateClass),
				  ILType_FromClass(multicastDelegateClass),
				  IL_META_METHODDEF_SPECIAL_NAME | IL_META_METHODDEF_STATIC))
	{
		ILGenOutOfMemory(info);
	}
	if(!AddMethod(multicastDelegateClass, "op_Inequality", ILType_Boolean,
				  ILType_FromClass(multicastDelegateClass),
				  ILType_FromClass(multicastDelegateClass),
				  IL_META_METHODDEF_SPECIAL_NAME | IL_META_METHODDEF_STATIC))
	{
		ILGenOutOfMemory(info);
	}

	/* Create the "AsyncCallback" delegate class */
	ABORT_IF(asyncCallbackClass,
			 ILClassCreate(scope, 0, "AsyncCallback", "System",
			 			   multicastDelegateClass));
	ILClassSetAttrs(asyncCallbackClass, ~0,
					IL_META_TYPEDEF_PUBLIC |
				    IL_META_TYPEDEF_SERIALIZABLE |
					IL_META_TYPEDEF_BEFORE_FIELD_INIT |
				    IL_META_TYPEDEF_ABSTRACT);
}