Stop using ConstructorBuilder (always use MethodBuilder).

This commit is contained in:
jfrijters 2012-08-15 08:45:39 +00:00
Родитель 165abbec78
Коммит 15d12a5439
4 изменённых файлов: 32 добавлений и 40 удалений

Просмотреть файл

@ -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)

Просмотреть файл

@ -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 <clinit> 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 <clinit> 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);
}
}
}

Просмотреть файл

@ -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);
}
}
}

Просмотреть файл

@ -315,13 +315,6 @@ namespace IKVM.Internal
}
TypeWrapper t = loader.LoadClassByDottedName(attr.Class);
isDeclarativeSecurity = t.TypeAsBaseType.IsSubclassOf(Types.SecurityAttribute);
MethodWrapper mw = t.GetMethodWrapper("<init>", attr.Sig, false);
mw.Link();
ConstructorInfo ci = (ConstructorInfo)mw.GetMethod();
if(ci == null)
{
throw new InvalidOperationException(string.Format("Constructor missing: {0}::<init>{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("<init>", attr.Sig, false);
if (mw == null)
{
throw new InvalidOperationException(string.Format("Constructor missing: {0}::<init>{1}", attr.Class, attr.Sig));
}
mw.Link();
ConstructorInfo ci = (mw.GetMethod() as ConstructorInfo) ?? ((MethodInfo)mw.GetMethod()).__AsConstructorInfo();
return new CustomAttributeBuilder(ci, args, namedFields, fieldValues);
}
}