public void SetUp()
 {
     grinderContextMock = TestHelpers.TestUtils.CreateContextMock();
     loggerMock = TestHelpers.TestUtils.CreateLoggerMock();
     grinderContextMock.Setup(c => c.ScriptFile).Returns(TestHelpers.TestUtils.TestsAsScriptFile);
     grinderContextMock.Setup(c => c.GetLogger(typeof(AbstractGrinderElementTests.TestElement))).Returns(loggerMock.Object);
     typeHelper = new TypeHelper(grinderContextMock.Object);
 }
        public void Initialize()
        {
            if (GrinderContext == null)
            {
                throw new AwarenessException("GrinderContext == null");
            }

            Logger = new LoggerFacade(GrinderContext.GetLogger(GetType()), GrinderContext);
            Logger.Trace("Initialize: Enter");
            TypeHelper = new TypeHelper(GrinderContext);
            OnInitialize();
            Logger.Trace("Initialize: Exit");
        }
示例#3
0
		private void CreateInitContextLazyInstance(
			FieldBuilder field,
			TypeHelper   fieldType,
			TypeHelper   objectType,
			EmitHelper   emit,
			object[]     parameters)
		{
			if (!CheckObjectHolderCtor(fieldType, objectType))
				return;

			LocalBuilder initField = emit.DeclareLocal(InitContextType);

			emit
				.newobj   (InitContextType.GetPublicDefaultConstructor())

				.dup
				.ldarg_0
				.callvirt (InitContextType.GetProperty("Parent").GetSetMethod())

				.dup
				.ldc_i4_1
				.callvirt (InitContextType.GetProperty("IsInternal").GetSetMethod())

				.dup
				.ldc_i4_1
				.callvirt (InitContextType.GetProperty("IsLazyInstance").GetSetMethod())

				;

			if (parameters != null)
			{
				emit
					.dup
					.ldsfld   (GetParameterField())
					.callvirt (InitContextType.GetProperty("MemberParameters").GetSetMethod())
					;
			}

			emit
				.stloc    (initField);

			if (objectType.IsAbstract)
			{
				emit
					.ldarg_0
					.ldsfld             (GetTypeAccessorField())
					.ldloc              (initField)
					.callvirtNoGenerics (typeof(TypeAccessor), "CreateInstanceEx", _initContextType)
					.isinst             (objectType)
					;
			}
			else
			{
				emit
					.ldarg_0
					.ldloc   (initField)
					.newobj  (objectType.GetPublicConstructor(typeof(InitContext)))
					;
			}

			if (IsObjectHolder)
			{
				emit
					.newobj (fieldType, objectType)
					;
			}

			emit
				.stfld (field)
				;
		}
示例#4
0
		private void BuildLazyInstanceEnsurer()
		{
			string              fieldName  = GetFieldName();
			FieldBuilder        field      = Context.GetField(fieldName);
			TypeHelper          fieldType  = new TypeHelper(field.FieldType);
			TypeHelper          objectType = new TypeHelper(GetObjectType());
			MethodBuilderHelper ensurer    = Context.TypeBuilder.DefineMethod(
				string.Format("$EnsureInstance{0}", fieldName),
				MethodAttributes.Private | MethodAttributes.HideBySig);

			EmitHelper emit = ensurer.Emitter;
			Label      end  = emit.DefineLabel();

			emit
				.ldarg_0
				.ldfld    (field)
				.brtrue_s (end)
				;

			object[] parameters = TypeHelper.GetPropertyParameters(Context.CurrentProperty);
			ConstructorInfo  ci = objectType.GetPublicConstructor(typeof(InitContext));

			if (ci != null || objectType.IsAbstract)
				CreateInitContextLazyInstance(field, fieldType, objectType, emit, parameters);
			else if (parameters == null)
				CreateDefaultInstance(field, fieldType, objectType, emit);
			else
				CreateParametrizedInstance(field, fieldType, objectType, emit, parameters);

			emit
				.MarkLabel(end)
				.ret()
				;

			Context.Items.Add("$BLToolkit.FieldInstanceEnsurer." + fieldName, ensurer);
		}
示例#5
0
		private void CreateInitContextDefaultInstance(
			string       initContextName,
			FieldBuilder field,
			TypeHelper   fieldType,
			TypeHelper   objectType,
			EmitHelper   emit,
			object[]     parameters)
		{
			if (!CheckObjectHolderCtor(fieldType, objectType))
				return;

			LocalBuilder initField    = GetInitContextBuilder(initContextName, emit);
			MethodInfo   memberParams = InitContextType.GetProperty("MemberParameters").GetSetMethod();

			if (parameters != null)
			{
				emit
					.ldloc    (initField)
					.ldsfld   (GetParameterField())
					.callvirt (memberParams)
					;
			}
			else if ((bool)Context.Items["$BLToolkit.Default.DirtyParameters"])
			{
				emit
					.ldloc    (initField)
					.ldnull
					.callvirt (memberParams)
					;
			}

			Context.Items["$BLToolkit.Default.DirtyParameters"] = parameters != null;

			if (objectType.IsAbstract)
			{
				emit
					.ldarg_0
					.ldsfld             (GetTypeAccessorField())
					.ldloc              (initField)
					.callvirtNoGenerics (typeof(TypeAccessor), "CreateInstanceEx", _initContextType)
					.isinst             (objectType)
					;
			}
			else
			{
				emit
					.ldarg_0
					.ldloc   (initField)
					.newobj  (objectType.GetPublicConstructor(typeof(InitContext)))
					;
			}

			if (IsObjectHolder)
			{
				emit
					.newobj (fieldType, objectType)
					;
			}

			emit
				.stfld (field)
				;
		}
示例#6
0
		private bool CheckObjectHolderCtor(TypeHelper fieldType, TypeHelper objectType)
		{
			if (IsObjectHolder)
			{
				ConstructorInfo holderCi = fieldType.GetPublicConstructor(objectType);

				if (holderCi == null)
				{
					string message = string.Format(
						Resources.TypeBuilder_PropertyTypeHasNoCtorWithParamType,
						Context.CurrentProperty.Name,
						Context.Type.FullName,
						fieldType.FullName,
						objectType.FullName);

					Context.TypeBuilder.DefaultConstructor.Emitter
						.ldstr  (message)
						.newobj (typeof(TypeBuilderException), typeof(string))
						.@throw
						.end()
						;

					return false;
				}
			}

			return true;
		}
示例#7
0
		private void BuildDefaultInstance()
		{
			string       fieldName  = GetFieldName();
			FieldBuilder field      = Context.GetField(fieldName);
			TypeHelper   fieldType  = new TypeHelper(field.FieldType);
			TypeHelper   objectType = new TypeHelper(GetObjectType());

			EmitHelper       emit = Context.TypeBuilder.DefaultConstructor.Emitter;
			object[]         ps   = TypeHelper.GetPropertyParameters(Context.CurrentProperty);
			ConstructorInfo  ci   = objectType.GetPublicConstructor(typeof(InitContext));

			if (ci != null && ci.GetParameters()[0].ParameterType != typeof(InitContext))
				ci = null;

			if (ci != null || objectType.IsAbstract)
				CreateInitContextDefaultInstance(
					"$BLToolkit.DefaultInitContext.", field, fieldType, objectType, emit, ps);
			else if (ps == null)
				CreateDefaultInstance(field, fieldType, objectType, emit);
			else
				CreateParametrizedInstance(field, fieldType, objectType, emit, ps);
		}
		private Stack<ConstructorInfo> GetGenericNestedConstructors(TypeHelper objectType, 
			Predicate<TypeHelper> isActionable, 
			Action<TypeHelper> action, 
			Func<bool> isBreakCondition)
		{
			Stack<ConstructorInfo> genericNestedConstructors = null;

			if (isActionable(objectType))
				action(objectType);

			while (objectType.Type.IsGenericType && !isBreakCondition())
			{
				var typeArgs = objectType.Type.GetGenericArguments();

				if (typeArgs.Length == 1)
				{
					var genericCtor = objectType.GetPublicConstructor(typeArgs[0]);

					if (genericCtor != null)
					{
						if (genericNestedConstructors == null)
							genericNestedConstructors = new Stack<ConstructorInfo>();

						genericNestedConstructors.Push(genericCtor);
						objectType = typeArgs[0];

						if (isActionable(objectType))
							action(objectType);
					}
				}
				else
				{
					throw new TypeBuilderException(
						string.Format(Resources.TypeBuilder_GenericShouldBeSingleTyped,
							Context.CurrentProperty.Name,
							Context.Type.FullName,
							objectType.FullName));
				}
			}

			return genericNestedConstructors;
		}
示例#9
0
		private void CreateParametrizedInstance(
			FieldBuilder field, TypeHelper fieldType, TypeHelper objectType, EmitHelper emit, object[] parameters)
		{
			if (!CheckObjectHolderCtor(fieldType, objectType))
				return;

			if (parameters.Length == 1)
			{
				object o = parameters[0];

				if (o == null)
				{
					if (objectType.IsValueType == false)
						emit
							.ldarg_0
							.ldnull
							.end()
							;

					if (IsObjectHolder)
					{
						emit
							.newobj (fieldType, objectType)
							;
					}

					emit
						.stfld (field)
						;

					return;
				}
				else
				{
					if (objectType.Type == o.GetType())
					{
						if (objectType.Type == typeof(string))
						{
							emit
								.ldarg_0
								.ldstr   ((string)o)
								.stfld   (field)
								;

							return;
						}

						if (objectType.IsValueType)
						{
							emit.ldarg_0.end();

							if (emit.LoadWellKnownValue(o) == false)
							{
								emit
									.ldsfld     (GetParameterField())
									.ldc_i4_0
									.ldelem_ref
									.end()
									;
							}

							emit.stfld(field);

							return;
						}
					}
				}
			}

			Type[] types = new Type[parameters.Length];

			for (int i = 0; i < parameters.Length; i++)
			{
				if (parameters[i] != null)
				{
					Type t = parameters[i].GetType();

					types[i] = (t.IsEnum) ? Enum.GetUnderlyingType(t) : t;
				}
				else
					types[i] = typeof(object);
			}

			ConstructorInfo ci = objectType.GetPublicConstructor(types);

			if (ci == null)
			{
				if (objectType.IsValueType)
					return;

				throw new TypeBuilderException(
					string.Format(types.Length == 0?
							Resources.TypeBuilder_PropertyTypeHasNoPublicDefaultCtor:
							Resources.TypeBuilder_PropertyTypeHasNoPublicCtor,
						Context.CurrentProperty.Name,
						Context.Type.FullName,
						objectType.FullName));
			}

			ParameterInfo[] pi = ci.GetParameters();

			emit.ldarg_0.end();

			for (int i = 0; i < parameters.Length; i++)
			{
				object o     = parameters[i];
				Type   oType = o.GetType();

				if (emit.LoadWellKnownValue(o))
				{
					if (oType.IsValueType)
					{
						if (!pi[i].ParameterType.IsValueType)
							emit.box(oType);
						else if (Type.GetTypeCode(oType) != Type.GetTypeCode(pi[i].ParameterType))
							emit.conv(pi[i].ParameterType);
					}
				}
				else
				{
					emit
						.ldsfld         (GetParameterField())
						.ldc_i4         (i)
						.ldelem_ref
						.CastFromObject (types[i])
						;

					if (oType.IsValueType && !pi[i].ParameterType.IsValueType)
						emit.box(oType);
				}
			}

			emit
				.newobj (ci)
				;

			if (IsObjectHolder)
			{
				emit
					.newobj (fieldType, objectType)
					;
			}

			emit
				.stfld  (field)
				;
		}
示例#10
0
		private void CreateDefaultInstance(
			FieldBuilder field, TypeHelper fieldType, TypeHelper objectType, EmitHelper emit)
		{
			if (!CheckObjectHolderCtor(fieldType, objectType))
				return;

			if (objectType.Type == typeof(string))
			{
				emit
					.ldarg_0
					.LoadInitValue (objectType)
					;
			}
			else if (objectType.IsArray)
			{
				FieldBuilder initializer = GetArrayInitializer(objectType);

				emit
					.ldarg_0
					.ldsfld  (initializer)
					;
			}
			else
			{
				ConstructorInfo ci = objectType.GetPublicDefaultConstructor();

				if (ci == null)
				{
					if (objectType.Type.IsValueType)
						return;

					string message = string.Format(
						Resources.TypeBuilder_PropertyTypeHasNoPublicDefaultCtor,
						Context.CurrentProperty.Name,
						Context.Type.FullName,
						objectType.FullName);

					emit
						.ldstr  (message)
						.newobj (typeof(TypeBuilderException), typeof(string))
						.@throw
						.end()
						;

					return;
				}
				else
				{
					emit
						.ldarg_0
						.newobj  (ci)
						;
				}
			}

			if (IsObjectHolder)
			{
				emit
					.newobj (fieldType, objectType)
					;
			}

			emit
				.stfld (field)
				;
		}
示例#11
0
		private void BuildHolderInstance(EmitHelper emit)
		{
			string       fieldName  = GetFieldName();
			FieldBuilder field      = Context.GetField(fieldName);
			TypeHelper   fieldType  = new TypeHelper(field.FieldType);
			TypeHelper   objectType = new TypeHelper(GetObjectType());

			ConstructorInfo ci = fieldType.GetPublicDefaultConstructor();

			if (ci != null)
			{
				emit
					.ldarg_0
					.newobj (ci)
					.stfld  (field)
					;
			}
			else
			{
				if (!CheckObjectHolderCtor(fieldType, objectType))
					return;

				emit
					.ldarg_0
					.ldnull
					.newobj (fieldType, objectType)
					.stfld  (field)
					;
			}
		}
示例#12
0
		private void LoadParameterOrNull(ParameterInfo pi, Type type)
		{
			EmitHelper emit  = Context.MethodBuilder.Emitter;
			object[]   attrs = pi.GetCustomAttributes(typeof(ParamNullValueAttribute), true);

			object nullValue = attrs.Length == 0?
				null: ((ParamNullValueAttribute)attrs[0]).Value;

			Label labelNull  = emit.DefineLabel();
			Label labelEndIf = emit.DefineLabel();

			if (pi.Attributes == ParameterAttributes.Out)
			{
				emit
					.ldnull
					.end()
					;

				return;
			}

			if (nullValue != null)
			{
				Type nullValueType = type;
				bool isNullable    = TypeHelper.IsNullable(type);

				if (type.IsEnum)
				{
					nullValueType = Enum.GetUnderlyingType(type);
					nullValue     = System.Convert.ChangeType(nullValue, nullValueType);
				}
				else if (isNullable)
				{
					nullValueType = type.GetGenericArguments()[0];

					emit
						.ldarga   (pi)
						.call     (type, "get_HasValue")
						.brfalse  (labelNull)
						;
				}

				if (nullValueType == nullValue.GetType() && emit.LoadWellKnownValue(nullValue))
				{
					if (nullValueType == typeof(string))
						emit
							.ldargEx (pi, false)
							.call    (nullValueType, "Equals", nullValueType)
							.brtrue  (labelNull)
							;
					else if (isNullable)
						emit
							.ldarga  (pi)
							.call    (type, "get_Value")
							.beq     (labelNull)
							;
					else
						emit
							.ldargEx (pi, false)
							.beq     (labelNull)
						;
				}
				else
				{
					string       nullString  = TypeDescriptor.GetConverter(nullValue).ConvertToInvariantString(nullValue);
					FieldBuilder staticField = CreateNullValueField(nullValueType, nullString);
					MethodInfo   miEquals    = new TypeHelper(nullValueType).GetPublicMethod("Equals", nullValueType);

					if (miEquals == null)
					{
						// Is it possible?
						//
						throw new TypeBuilderException(string.Format(
							Resources.DataAccessorBuilder_EqualsMethodIsNotPublic, type.FullName));
					}

					if (isNullable)
						emit
							.ldsflda (staticField)
							.ldarga  (pi)
							.call    (pi.ParameterType, "get_Value")
							;
					else
						emit
							.ldsflda (staticField)
							.ldarg   (pi)
						;

					if (miEquals.GetParameters()[0].ParameterType.IsClass)
						emit
							.boxIfValueType(nullValueType)
							;

					emit
						.call   (miEquals)
						.brtrue (labelNull)
						;
				}
			}

			if (type.IsEnum)
				emit
					.ldloc     (_locManager)
					.callvirt  (typeof (DbManager).GetProperty("MappingSchema").GetGetMethod())
					;

			emit
				.ldargEx(pi, true)
				;

			if (type.IsEnum)
				emit
					.ldc_i4_1
					.callvirt  (typeof (MappingSchema), "MapEnumToValue", typeof (object), typeof (bool))
					;

			if (nullValue != null)
			{
				emit
					.br        (labelEndIf)
					.MarkLabel (labelNull)
					.ldnull
					.MarkLabel (labelEndIf)
					;
			}
		}
示例#13
0
		public void NumericTest()
		{
			TypeHelper helper = new TypeHelper(typeof(Convert));
			IConvertible src  = 123;

			// All types from SByte to Decimal can convert to each other
			//
			for (int from = 0; from < NumericTypes.Length; ++from)
			{
				Type typeFrom = NumericTypes[from];
				object   test = src.ToType(typeFrom, null);

				for (int to = 0; to < NumericTypes.Length; ++to)
				{
					if (from == to)
						continue;

					Type   typeTo = NumericTypes[to];
					MethodInfo mi = helper.GetMethod("To" + typeTo.Name, bindingFlags, typeFrom);

					Assert.IsNotNull(mi, string.Format("Missed To{0}({1})", typeTo.Name, typeFrom.Name));
					Assert.AreEqual(123, mi.Invoke(null, new object[] { test }));
				}
			}
		}
示例#14
0
		private void BuildInitContextInstance()
		{
			var fieldName  = GetFieldName();
			var field      = Context.GetField(fieldName);
			var fieldType  = new TypeHelper(field.FieldType);
			var objectType = new TypeHelper(GetObjectType());

			var emit = Context.TypeBuilder.InitConstructor.Emitter;

			var parameters = TypeHelper.GetPropertyParameters(Context.CurrentProperty);
			var ci = objectType.GetPublicConstructor(typeof(InitContext));

			if (ci != null && ci.GetParameters()[0].ParameterType != typeof(InitContext))
				ci = null;

			if (ci != null || objectType.IsAbstract)
				CreateAbstractInitContextInstance(field, fieldType, objectType, emit, parameters);
			else if (parameters == null)
				CreateDefaultInstance(field, fieldType, objectType, emit);
			else
				CreateParametrizedInstance(field, fieldType, objectType, emit, parameters);
		}
示例#15
0
		private void CreateAbstractInitContextInstance(
			FieldBuilder field, TypeHelper fieldType, TypeHelper objectType, EmitHelper emit, object[] parameters)
		{
			if (!CheckObjectHolderCtor(fieldType, objectType))
				return;

			MethodInfo memberParams = InitContextType.GetProperty("MemberParameters").GetSetMethod();

			LocalBuilder parentField = (LocalBuilder)Context.Items["$BLToolkit.InitContext.Parent"];

			if (parentField == null)
			{
				Context.Items["$BLToolkit.InitContext.Parent"] = parentField = emit.DeclareLocal(typeof(object));

				Label label = emit.DefineLabel();

				emit
					.ldarg_1
					.brtrue_s  (label)

					.newobj    (InitContextType.GetPublicDefaultConstructor())
					.starg     (1)

					.ldarg_1
					.ldc_i4_1
					.callvirt  (InitContextType.GetProperty("IsInternal").GetSetMethod())

					.MarkLabel (label)

					.ldarg_1
					.callvirt  (InitContextType.GetProperty("Parent").GetGetMethod())
					.stloc     (parentField)
					;
			}

			emit
				.ldarg_1
				.ldarg_0
				.callvirt (InitContextType.GetProperty("Parent").GetSetMethod())
				;

			object isDirty = Context.Items["$BLToolkit.InitContext.DirtyParameters"];

			if (parameters != null)
			{
				emit
					.ldarg_1
					.ldsfld   (GetParameterField())
					.callvirt (memberParams)
					;
			}
			else if (isDirty != null && (bool)isDirty)
			{
				emit
					.ldarg_1
					.ldnull
					.callvirt (memberParams)
					;
			}

			Context.Items["$BLToolkit.InitContext.DirtyParameters"] = parameters != null;

			if (objectType.IsAbstract)
			{
				emit
					.ldarg_0
					.ldsfld             (GetTypeAccessorField())
					.ldarg_1
					.callvirtNoGenerics (typeof(TypeAccessor), "CreateInstanceEx", _initContextType)
					.isinst             (objectType)
					;
			}
			else
			{
				emit
					.ldarg_0
					.ldarg_1
					.newobj  (objectType.GetPublicConstructor(typeof(InitContext)))
					;
			}

			if (IsObjectHolder)
			{
				emit
					.newobj (fieldType, objectType)
					;
			}

			emit
				.stfld (field)
				;
		}
示例#16
0
 public bool IsBasicType()
 {
     var typeHelper = new TypeHelper();
     return typeHelper.IsBasicType(FieldType);
 }
示例#17
0
		private void CreateParametrizedInstance(
			FieldBuilder field, TypeHelper fieldType, TypeHelper objectType, EmitHelper emit, object[] parameters)
		{
			if (!CheckObjectHolderCtor(fieldType, objectType))
				return;

			Stack<ConstructorInfo> genericNestedConstructors;
			if (parameters.Length == 1)
			{
				var o = parameters[0];

				if (o == null)
				{
					if (objectType.IsValueType == false)
						emit
							.ldarg_0
							.ldnull
							.end()
							;

					if (IsObjectHolder)
					{
						emit
							.newobj (fieldType, objectType)
							;
					}
					else
					{
						if (objectType.Type.IsGenericType)
						{
							Type nullableType = null;
							genericNestedConstructors = GetGenericNestedConstructors(
								objectType,
								typeHelper =>
									typeHelper.IsValueType == false ||
									(typeHelper.Type.IsGenericType && typeHelper.Type.GetGenericTypeDefinition() == typeof (Nullable<>)),
								typeHelper => { nullableType = typeHelper.Type; },
								() => nullableType != null);

							if (nullableType == null)
								throw new Exception("Cannot find nullable type in generic types chain");

							if (nullableType.IsValueType == false)
							{
								emit
									.ldarg_0
									.ldnull
									.end()
									;
							}
							else
							{
								var nullable = emit.DeclareLocal(nullableType);

								emit
									.ldloca(nullable)
									.initobj(nullableType)
									.ldarg_0
									.ldloc(nullable)
									;

								if (genericNestedConstructors != null)
								{
									while (genericNestedConstructors.Count != 0)
									{
										emit
											.newobj(genericNestedConstructors.Pop())
											;
									}
								}
							}
						}
					}

					emit
						.stfld (field)
						;

					return;
				}
				
				if (objectType.Type == o.GetType())
				{
					if (objectType.Type == typeof(string))
					{
						emit
							.ldarg_0
							.ldstr   ((string)o)
							.stfld   (field)
							;

						return;
					}

					if (objectType.IsValueType)
					{
						emit.ldarg_0.end();

						if (emit.LoadWellKnownValue(o) == false)
						{
							emit
								.ldsfld     (GetParameterField())
								.ldc_i4_0
								.ldelem_ref
								.end()
								;
						}

						emit.stfld(field);

						return;
					}
				}
			}

			var types = new Type[parameters.Length];

			for (var i = 0; i < parameters.Length; i++)
			{
				if (parameters[i] != null)
				{
					var t = parameters[i].GetType();

					types[i] = (t.IsEnum) ? Enum.GetUnderlyingType(t) : t;
				}
				else
					types[i] = typeof(object);
			}

			// Do some heuristics for Nullable<DateTime> and EditableValue<Decimal>
			//
			ConstructorInfo objectCtor = null;
			genericNestedConstructors = GetGenericNestedConstructors(
				objectType,
				typeHelper => true,
				typeHelper => { objectCtor = typeHelper.GetPublicConstructor(types); },
				() => objectCtor != null);

			if (objectCtor == null)
			{
				if (objectType.IsValueType)
					return;

				throw new TypeBuilderException(
					string.Format(types.Length == 0?
							Resources.TypeBuilder_PropertyTypeHasNoPublicDefaultCtor:
							Resources.TypeBuilder_PropertyTypeHasNoPublicCtor,
						Context.CurrentProperty.Name,
						Context.Type.FullName,
						objectType.FullName));
			}

			var pi = objectCtor.GetParameters();

			emit.ldarg_0.end();

			for (var i = 0; i < parameters.Length; i++)
			{
				var o     = parameters[i];
				var oType = o.GetType();

				if (emit.LoadWellKnownValue(o))
				{
					if (oType.IsValueType)
					{
						if (!pi[i].ParameterType.IsValueType)
							emit.box(oType);
						else if (Type.GetTypeCode(oType) != Type.GetTypeCode(pi[i].ParameterType))
							emit.conv(pi[i].ParameterType);
					}
				}
				else
				{
					emit
						.ldsfld         (GetParameterField())
						.ldc_i4         (i)
						.ldelem_ref
						.CastFromObject (types[i])
						;

					if (oType.IsValueType && !pi[i].ParameterType.IsValueType)
						emit.box(oType);
				}
			}

			emit
				.newobj (objectCtor)
				;

			if (genericNestedConstructors != null)
			{
				while (genericNestedConstructors.Count != 0)
				{
					emit
						.newobj(genericNestedConstructors.Pop())
						;
				}
			}

			if (IsObjectHolder)
			{
				emit
					.newobj (fieldType, objectType)
					;
			}

			emit
				.stfld  (field)
				;
		}