[Mono-bugs] [Bug 317388] Enumerations and ValueTypes built with Emit makes assembly crash when loading (invalid assembly!)

bugzilla_noreply at novell.com bugzilla_noreply at novell.com
Tue Nov 6 01:50:42 EST 2007


https://bugzilla.novell.com/show_bug.cgi?id=317388#c2


Atsushi Enomoto <atsushi at ximian.com> changed:

           What    |Removed                                         |Added
----------------------------------------------------------------------------
                 CC|                                                |atsushi at ximian.com
             Status|NEEDINFO                                        |RESOLVED
      Info Provider|martin.tapp at cae.com                             |
         Resolution|                                                |FIXED




--- Comment #2 from Atsushi Enomoto <atsushi at ximian.com>  2007-11-05 23:50:42 MST ---
>From the imaginary runnable test case above, I've created a runnable test case
that is hopefully equivalent to the test (I fixed lots of mistakes in the
source). And it just worked fine. So I'm closing it as fixed.

--------
using System;
using System.Collections;
using System.Reflection;
using System.Reflection.Emit;

public interface IMyValueType {}

public class Test
{
        public static void Main ()
        {
                AssemblyName wAsmName = new AssemblyName();
                wAsmName.Name = "MyAssembly";

                string wPath = ".";
                string wAssemblyDll = "MyAssembly.dll";

                AssemblyBuilder wAsmBuilder = 
                AppDomain.CurrentDomain.DefineDynamicAssembly
                (wAsmName,AssemblyBuilderAccess.RunAndSave,wPath);

                ModuleBuilder wModuleBuilder = wAsmBuilder.DefineDynamicModule
                (wAssemblyDll,wAssemblyDll,false);

                IDictionary wEnums = new SortedList();
                // Create enumeration - comment out to test
#if true
                Type wEnumType = typeof(uint);
                EnumBuilder wEnumBuilder =
wModuleBuilder.DefineEnum("MyNamespace1.MyNamespace2.MyEnum",TypeAttributes.Public,wEnumType);

               
wEnumBuilder.DefineLiteral("SomeLiteral1",Convert.ChangeType(1234,wEnumType));
               
wEnumBuilder.DefineLiteral("SomeLiteral2",Convert.ChangeType(5678,wEnumType));

                // Note: on Windows, the wEnumBuilder can be used after the
type is created, in mono on Linux RH9 it crashes
                Type wEnumerationType = wEnumBuilder.CreateType();
                wEnums[wEnumBuilder.Name.ToLower()] = wEnumBuilder;
                // Need to to this instead:
                //wEnums[wEnumerationType.Name.ToLower()] = wEnumerationType;
#endif


                // Create complex data type - comment out to test
#if true
                Type[] wInterfaces = { typeof(IMyValueType) };
                TypeBuilder wValueType1 =
wModuleBuilder.DefineType("MyNamespace1.MyNamespace2.MyValueType1",TypeAttributes.Public|TypeAttributes.Class|TypeAttributes.SequentialLayout|TypeAttributes.Serializable,typeof(ValueType),wInterfaces);

                DefineField(wValueType1,"MyField1",typeof(int));
                DefineField(wValueType1,"MyField2",typeof(float));

                wValueType1.CreateType();


                TypeBuilder wValueType2 =
wModuleBuilder.DefineType("MyNamespace1.MyNamespace2.MyValueType2",TypeAttributes.Public|TypeAttributes.Class|TypeAttributes.SequentialLayout|TypeAttributes.Serializable,typeof(ValueType),wInterfaces);

                DefineField(wValueType2,"MyField1",wValueType1);
                DefineField(wValueType2,"MyField2",typeof(float));

                wValueType2.CreateType();
#endif

                wAsmBuilder.Save(wAssemblyDll);

                Assembly wAssembly = AppDomain.CurrentDomain.Load
                (AssemblyName.GetAssemblyName(wAssemblyDll));

                        }

                public static void DefineField(TypeBuilder iTypeBuilder,string
iAttrName,Type 
                iAttrType)
                {
                  string       wFieldName = string.Concat("_",iAttrName);
                  FieldBuilder wField     = iTypeBuilder.DefineField
                (wFieldName,iAttrType,FieldAttributes.Private);

                  Type[]          wArgs     = { iAttrType };
                  PropertyBuilder wProperty = iTypeBuilder.DefineProperty
                (iAttrName,PropertyAttributes.None,iAttrType,Type.EmptyTypes);

                  // "get" property method
                  string        wAttrMethodName =
string.Concat("get_",iAttrName);
                  MethodBuilder wGetMethod      = iTypeBuilder.DefineMethod
               
(wAttrMethodName,MethodAttributes.Public,CallingConventions.HasThis,iAttrType,Type.EmptyTypes);
                  ILGenerator   wGetIL          = wGetMethod.GetILGenerator();
                  // return _mField;
                  wGetIL.Emit(OpCodes.Ldarg_0);
                  wGetIL.Emit(OpCodes.Ldfld,wField);
                  wGetIL.Emit(OpCodes.Ret);

                  // "set" property method
                  wAttrMethodName          = string.Concat("set_",iAttrName);
                  MethodBuilder wSetMethod = iTypeBuilder.DefineMethod
               
(wAttrMethodName,MethodAttributes.Public,CallingConventions.HasThis,null,wArgs);
                  ILGenerator   wSetIL     = wSetMethod.GetILGenerator();
                  // _mField = iField;
                  wSetIL.Emit(OpCodes.Ldarg_0);
                  wSetIL.Emit(OpCodes.Ldarg_1);
                  wSetIL.Emit(OpCodes.Stfld,wField);
                  wSetIL.Emit(OpCodes.Ret);

                  // Map the get and set methods to the property get and set
respectively
                  wProperty.SetGetMethod(wGetMethod);
                  wProperty.SetSetMethod(wSetMethod);
                }
}


-- 
Configure bugmail: https://bugzilla.novell.com/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
You are the assignee for the bug.


More information about the mono-bugs mailing list