[Mono-bugs] [Bug 73349][Cri] New - Enumerations and ValueTypes built with Emit makes assembly crash when loading (invalid assembly!)
bugzilla-daemon@bugzilla.ximian.com
bugzilla-daemon@bugzilla.ximian.com
Fri, 4 Mar 2005 11:11:46 -0500 (EST)
Please do not reply to this email- if you want to comment on the bug, go to the
URL shown below and enter your comments there.
Changed by martin.tapp@cae.com.
http://bugzilla.ximian.com/show_bug.cgi?id=73349
--- shadow/73349 2005-03-04 11:11:46.000000000 -0500
+++ shadow/73349.tmp.11324 2005-03-04 11:11:46.000000000 -0500
@@ -0,0 +1,155 @@
+Bug#: 73349
+Product: Mono: Class Libraries
+Version: 1.1
+OS: Red Hat 9.0
+OS Details:
+Status: NEW
+Resolution:
+Severity:
+Priority: Critical
+Component: CORLIB
+AssignedTo: mono-bugs@ximian.com
+ReportedBy: martin.tapp@cae.com
+QAContact: mono-bugs@ximian.com
+TargetMilestone: ---
+URL:
+Cc:
+Summary: Enumerations and ValueTypes built with Emit makes assembly crash when loading (invalid assembly!)
+
+Description of Problem:
+When using reflection to create enumerations and value types, assembly
+fails to be a valid assembly when saved! Enumerations make this happen,
+but not the value types.
+
+
+Steps to reproduce the problem:
+Using System.Collections:
+Using Reflection:
+Using Reflection.Emit:
+
+public interface IMyValueType {}
+
+AssemblyName wAsmName = new AssemblyName();
+wAsmName.Name = "MyAssembly";
+
+string wPath = "/Some Path(1)";
+string wAssemblyDll = wPath + "/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
+/*
+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;
+//*/
+
+
+// Create complex data type - comment out to test
+/*
+Type[] wInterfaces = { typeof(IMyValueType) };
+TypeBuilder wValueType1 = wModuleBuilder.DefineType
+("MyNamespace1.MyNamespace2.MyValueType1",TypeAttributes.Public|TypeAttribu
+tes.Class|TypeAttributes.SequentialLayout|TypeAttributes.Serializable,typeo
+f(ValueType),wInterfaces);
+
+DefineField(wValueType1,"MyField1",typeof(int));
+DefineField(wValueType1,"MyField2",typeof(float));
+
+wValueType1.CreateType();
+
+
+TypeBuilder wValueType2 = wModuleBuilder.DefineType
+("MyNamespace1.MyNamespace2.MyValueType2",TypeAttributes.Public|TypeAttribu
+tes.Class|TypeAttributes.SequentialLayout|TypeAttributes.Serializable,typeo
+f(ValueType),wInterfaces);
+
+DefineField(wValueType2,"MyField1",wValueType1);
+DefineField(wValueType1,"MyField2",typeof(float));
+
+wValueType2.CreateType();
+//*/
+
+wAsmBuilder.Save(wAssemblyDll);
+
+Assembly wAssembly = AppDomain.CurrentDomain.Load
+(AssemblyName.GetAssemblyName(wAssemblyDll));
+
+public void DefinedField(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,iAttrTy
+pe,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,wA
+rgs);
+ 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);
+}
+
+Actual Results:
+If only value types are defined, assembly is valid but throws when loading
+the value type (Cannot load type exception). On Windows, the same
+assembly works fine (compiled with mono).
+
+If only enumerations are defined, assembly is invalid and cannot be read
+at all (** ERROR **: file class.c: line 1742 (mono_class_setup_parent):
+should not be reached aborting... Aborted). Even opening the assembly with
+ILDASM or .NET Reflector makes these tools crash!
+
+
+Expected Results:
+Works fine on Windows.
+
+How often does this happen?
+Always
+
+Additional Information:
+The Value type problem might be related to the fact that once CreateType()
+is called, the builder cannot be accessed on mono RH9, but on Windows it
+can.