From 15d12a5439d6def83fd23261cd692376de2429be Mon Sep 17 00:00:00 2001 From: jfrijters Date: Wed, 15 Aug 2012 08:45:39 +0000 Subject: [PATCH] Stop using ConstructorBuilder (always use MethodBuilder). --- ikvmc/AotTypeWrapper.cs | 2 +- runtime/DynamicTypeWrapper.cs | 45 +++++++++++++---------------------- runtime/ReflectUtil.cs | 11 ++++++--- runtime/TypeWrapper.cs | 14 +++++------ 4 files changed, 32 insertions(+), 40 deletions(-) diff --git a/ikvmc/AotTypeWrapper.cs b/ikvmc/AotTypeWrapper.cs index 268e0b46..3835c042 100644 --- a/ikvmc/AotTypeWrapper.cs +++ b/ikvmc/AotTypeWrapper.cs @@ -157,7 +157,7 @@ namespace IKVM.Internal private readonly TypeWrapperFactory context; private readonly TypeBuilder typeBuilder; private readonly MethodWrapper ctor; - private ConstructorBuilder constructorBuilder; + private MethodBuilder constructorBuilder; internal ConstructorForwarder(TypeWrapperFactory context, TypeBuilder typeBuilder, MethodWrapper ctor) : base(ctor.DeclaringType, ctor.Name, ctor.Signature, null, null, null, ctor.Modifiers, MemberFlags.None) diff --git a/runtime/DynamicTypeWrapper.cs b/runtime/DynamicTypeWrapper.cs index 17f7a75b..7963ae2d 100644 --- a/runtime/DynamicTypeWrapper.cs +++ b/runtime/DynamicTypeWrapper.cs @@ -2798,7 +2798,7 @@ namespace IKVM.Internal private MethodBase GenerateConstructor(MethodWrapper mw) { - ConstructorBuilder cb = mw.GetDefineMethodHelper().DefineConstructor(wrapper, typeBuilder, GetMethodAccess(mw) | MethodAttributes.HideBySig); + MethodBuilder cb = mw.GetDefineMethodHelper().DefineConstructor(wrapper, typeBuilder, GetMethodAccess(mw) | MethodAttributes.HideBySig); cb.SetImplementationFlags(MethodImplAttributes.NoInlining); return cb; } @@ -3695,20 +3695,17 @@ namespace IKVM.Internal hasConstructor = true; } } - else if (mb is ConstructorBuilder) + else if (m.IsClassInitializer) { - if (m.IsClassInitializer) - { - // we handle the after we've done the other methods, - // to make it easier to inject code needed by the other methods - clinitIndex = i; - continue; - } - else - { - hasConstructor = true; - } - CodeEmitter ilGenerator = CodeEmitter.Create((ConstructorBuilder)mb); + // we handle the after we've done the other methods, + // to make it easier to inject code needed by the other methods + clinitIndex = i; + continue; + } + else if (m.IsConstructor) + { + hasConstructor = true; + CodeEmitter ilGenerator = CodeEmitter.Create((MethodBuilder)mb); CompileConstructorBody(this, ilGenerator, i, invokespecialstubcache); } else @@ -3894,10 +3891,10 @@ namespace IKVM.Internal if (clinitIndex != -1 || (basehasclinit && !classFile.IsInterface) || classFile.HasInitializedFields) { - ConstructorBuilder cb; + MethodBuilder cb; if (clinitIndex != -1) { - cb = (ConstructorBuilder)methods[clinitIndex].GetMethod(); + cb = (MethodBuilder)methods[clinitIndex].GetMethod(); } else { @@ -6037,24 +6034,14 @@ namespace IKVM.Internal return tb.DefineMethod(name, attribs, CallingConventions.Standard, mw.ReturnType.TypeAsSignatureType, null, modoptReturnType, parameterTypes, null, modopt); } - internal ConstructorBuilder DefineConstructor(DynamicTypeWrapper context, TypeBuilder tb, MethodAttributes attribs) + internal MethodBuilder DefineConstructor(DynamicTypeWrapper context, TypeBuilder tb, MethodAttributes attribs) { return DefineConstructor(context.GetClassLoader().GetTypeWrapperFactory(), tb, attribs); } - internal ConstructorBuilder DefineConstructor(TypeWrapperFactory context, TypeBuilder tb, MethodAttributes attribs) + internal MethodBuilder DefineConstructor(TypeWrapperFactory context, TypeBuilder tb, MethodAttributes attribs) { - // we add optional modifiers to make the signature unique - // (note that constructors do not support callerid) - TypeWrapper[] parameters = mw.GetParameters(); - Type[] parameterTypes = new Type[parameters.Length]; - Type[][] modopt = new Type[parameterTypes.Length][]; - for (int i = 0; i < parameters.Length; i++) - { - parameterTypes[i] = parameters[i].TypeAsSignatureType; - modopt[i] = DynamicTypeWrapper.GetModOpt(context, parameters[i], false); - } - return tb.DefineConstructor(attribs, CallingConventions.Standard, parameterTypes, null, modopt); + return DefineMethod(context, tb, ConstructorInfo.ConstructorName, attribs | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName); } } } diff --git a/runtime/ReflectUtil.cs b/runtime/ReflectUtil.cs index 888954c8..26975af7 100644 --- a/runtime/ReflectUtil.cs +++ b/runtime/ReflectUtil.cs @@ -148,8 +148,9 @@ namespace IKVM.Internal } } - internal static ConstructorBuilder DefineTypeInitializer(TypeBuilder typeBuilder) + internal static MethodBuilder DefineTypeInitializer(TypeBuilder typeBuilder) { + MethodAttributes attr = MethodAttributes.Static | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName; if (typeBuilder.IsInterface) { // LAMESPEC the ECMA spec says (part. I, sect. 8.5.3.2) that all interface members must be public, so we make @@ -157,9 +158,13 @@ namespace IKVM.Internal // NOTE it turns out that on .NET 2.0 this isn't necessary anymore (neither Ref.Emit nor the CLR verifier complain about it), // but the C# compiler still considers interfaces with non-public methods to be invalid, so to keep interop with C# we have // to keep making the .cctor method public. - return typeBuilder.DefineConstructor(MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes); + attr |= MethodAttributes.Public; } - return typeBuilder.DefineTypeInitializer(); + else + { + attr |= MethodAttributes.Private; + } + return typeBuilder.DefineMethod(ConstructorInfo.TypeConstructorName, attr, null, Type.EmptyTypes); } } } diff --git a/runtime/TypeWrapper.cs b/runtime/TypeWrapper.cs index ad6334e7..fc7bb7c5 100644 --- a/runtime/TypeWrapper.cs +++ b/runtime/TypeWrapper.cs @@ -315,13 +315,6 @@ namespace IKVM.Internal } TypeWrapper t = loader.LoadClassByDottedName(attr.Class); isDeclarativeSecurity = t.TypeAsBaseType.IsSubclassOf(Types.SecurityAttribute); - MethodWrapper mw = t.GetMethodWrapper("", attr.Sig, false); - mw.Link(); - ConstructorInfo ci = (ConstructorInfo)mw.GetMethod(); - if(ci == null) - { - throw new InvalidOperationException(string.Format("Constructor missing: {0}::{1}", attr.Class, attr.Sig)); - } FieldInfo[] namedFields; object[] fieldValues; if(attr.Fields != null) @@ -341,6 +334,13 @@ namespace IKVM.Internal namedFields = new FieldInfo[0]; fieldValues = new object[0]; } + MethodWrapper mw = t.GetMethodWrapper("", attr.Sig, false); + if (mw == null) + { + throw new InvalidOperationException(string.Format("Constructor missing: {0}::{1}", attr.Class, attr.Sig)); + } + mw.Link(); + ConstructorInfo ci = (mw.GetMethod() as ConstructorInfo) ?? ((MethodInfo)mw.GetMethod()).__AsConstructorInfo(); return new CustomAttributeBuilder(ci, args, namedFields, fieldValues); } }