Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/ikvm-fork.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjfrijters <jfrijters>2011-12-01 11:37:48 +0400
committerjfrijters <jfrijters>2011-12-01 11:37:48 +0400
commitb1d03c25d3dc212e64e855214d1ebe98b5b1259c (patch)
tree7636ee293228040bad214d8f8ab33cdb34db50c7
parent3c49c20346609d4c397dff93d25bb68297301516 (diff)
Added support for function pointer types.
-rw-r--r--reflect/Module.cs11
-rw-r--r--reflect/Reader/GenericTypeParameter.cs2
-rw-r--r--reflect/Signature.cs27
-rw-r--r--reflect/StandAloneMethodSig.cs22
-rw-r--r--reflect/Type.cs107
-rw-r--r--reflect/Universe.cs41
6 files changed, 187 insertions, 23 deletions
diff --git a/reflect/Module.cs b/reflect/Module.cs
index 3530e5af..429fc39b 100644
--- a/reflect/Module.cs
+++ b/reflect/Module.cs
@@ -451,17 +451,6 @@ namespace IKVM.Reflection
return GetCustomAttributes(token, null);
}
- internal Type CanonicalizeType(Type type)
- {
- Type canon;
- if (!universe.canonicalizedTypes.TryGetValue(type, out canon))
- {
- canon = type;
- universe.canonicalizedTypes.Add(canon, canon);
- }
- return canon;
- }
-
internal abstract Type GetModuleType();
internal abstract ByteReader GetBlob(int blobIndex);
diff --git a/reflect/Reader/GenericTypeParameter.cs b/reflect/Reader/GenericTypeParameter.cs
index d99e1af8..3b7fbd3e 100644
--- a/reflect/Reader/GenericTypeParameter.cs
+++ b/reflect/Reader/GenericTypeParameter.cs
@@ -169,7 +169,7 @@ namespace IKVM.Reflection.Reader
internal static Type Make(int position)
{
- return module.CanonicalizeType(new UnboundGenericMethodParameter(position));
+ return module.universe.CanonicalizeType(new UnboundGenericMethodParameter(position));
}
private UnboundGenericMethodParameter(int position)
diff --git a/reflect/Signature.cs b/reflect/Signature.cs
index 787de5f7..ff6031e8 100644
--- a/reflect/Signature.cs
+++ b/reflect/Signature.cs
@@ -129,10 +129,16 @@ namespace IKVM.Reflection
private static Type ReadFunctionPointer(ModuleReader module, ByteReader br, IGenericContext context)
{
- // TODO like .NET we return System.IntPtr here, but ideally we should fire an event in Universe that
- // the user can hook to provide a custom type (or we simply should build in full support for function pointer types)
- MethodSignature.ReadStandAloneMethodSig(module, br, context);
- return module.universe.System_IntPtr;
+ __StandAloneMethodSig sig = MethodSignature.ReadStandAloneMethodSig(module, br, context);
+ if (module.universe.EnableFunctionPointers)
+ {
+ return FunctionPointerType.Make(module.universe, sig);
+ }
+ else
+ {
+ // by default, like .NET we return System.IntPtr here
+ return module.universe.System_IntPtr;
+ }
}
internal static Type[] ReadMethodSpec(ModuleReader module, ByteReader br, IGenericContext context)
@@ -445,6 +451,19 @@ namespace IKVM.Reflection
{
WriteGenericSignature(module, bb, type);
}
+ else if (type.__IsFunctionPointer)
+ {
+ bb.Write(ELEMENT_TYPE_FNPTR);
+ __StandAloneMethodSig sig = type.__MethodSignature;
+ if (sig.IsUnmanaged)
+ {
+ WriteStandAloneMethodSig(module, bb, sig.UnmanagedCallingConvention, sig.ReturnType, sig.ParameterTypes);
+ }
+ else
+ {
+ WriteStandAloneMethodSig(module, bb, sig.CallingConvention, sig.ReturnType, sig.ParameterTypes, sig.OptionalParameterTypes);
+ }
+ }
else
{
if (type.IsValueType)
diff --git a/reflect/StandAloneMethodSig.cs b/reflect/StandAloneMethodSig.cs
index 007e5757..74d58d15 100644
--- a/reflect/StandAloneMethodSig.cs
+++ b/reflect/StandAloneMethodSig.cs
@@ -46,6 +46,28 @@ namespace IKVM.Reflection
this.optionalParameterTypes = optionalParameterTypes;
}
+ public bool Equals(__StandAloneMethodSig other)
+ {
+ return other != null
+ && other.unmanaged == unmanaged
+ && other.unmanagedCallingConvention == unmanagedCallingConvention
+ && other.callingConvention == callingConvention
+ && other.returnType == returnType
+ && Util.ArrayEquals(other.parameterTypes, parameterTypes)
+ && Util.ArrayEquals(other.optionalParameterTypes, optionalParameterTypes);
+ }
+
+ public override bool Equals(object obj)
+ {
+ return Equals(obj as __StandAloneMethodSig);
+ }
+
+ public override int GetHashCode()
+ {
+ return returnType.GetHashCode()
+ ^ Util.GetHashCode(parameterTypes);
+ }
+
public bool IsUnmanaged
{
get { return unmanaged; }
diff --git a/reflect/Type.cs b/reflect/Type.cs
index 43e84d50..6c0badaf 100644
--- a/reflect/Type.cs
+++ b/reflect/Type.cs
@@ -163,6 +163,11 @@ namespace IKVM.Reflection
return __GetCustomModifiers().GetOptional();
}
+ public virtual __StandAloneMethodSig __MethodSignature
+ {
+ get { throw new InvalidOperationException(); }
+ }
+
public virtual bool HasElementType
{
get { return false; }
@@ -188,6 +193,11 @@ namespace IKVM.Reflection
get { return false; }
}
+ public virtual bool __IsFunctionPointer
+ {
+ get { return false; }
+ }
+
public virtual bool IsValueType
{
get
@@ -1064,7 +1074,7 @@ namespace IKVM.Reflection
{
get
{
- Universe u = this.Module.universe;
+ Universe u = this.Universe;
return this == u.System_Boolean
|| this == u.System_Byte
|| this == u.System_SByte
@@ -1819,6 +1829,11 @@ namespace IKVM.Reflection
{
throw new NotSupportedException();
}
+
+ internal virtual Universe Universe
+ {
+ get { return Module.universe; }
+ }
}
abstract class ElementHolderType : Type
@@ -1937,6 +1952,11 @@ namespace IKVM.Reflection
return CustomAttributeData.EmptyList;
}
+ internal sealed override Universe Universe
+ {
+ get { return elementType.Universe; }
+ }
+
internal abstract string GetSuffix();
protected abstract Type Wrap(Type type, CustomModifiers mods);
@@ -1946,7 +1966,7 @@ namespace IKVM.Reflection
{
internal static Type Make(Type type, CustomModifiers mods)
{
- return type.Module.CanonicalizeType(new ArrayType(type, mods));
+ return type.Universe.CanonicalizeType(new ArrayType(type, mods));
}
private ArrayType(Type type, CustomModifiers mods)
@@ -2034,7 +2054,7 @@ namespace IKVM.Reflection
internal static Type Make(Type type, int rank, int[] sizes, int[] lobounds, CustomModifiers mods)
{
- return type.Module.CanonicalizeType(new MultiArrayType(type, rank, sizes, lobounds, mods));
+ return type.Universe.CanonicalizeType(new MultiArrayType(type, rank, sizes, lobounds, mods));
}
private MultiArrayType(Type type, int rank, int[] sizes, int[] lobounds, CustomModifiers mods)
@@ -2252,7 +2272,7 @@ namespace IKVM.Reflection
{
internal static Type Make(Type type, CustomModifiers mods)
{
- return type.Module.CanonicalizeType(new ByRefType(type, mods));
+ return type.Universe.CanonicalizeType(new ByRefType(type, mods));
}
private ByRefType(Type type, CustomModifiers mods)
@@ -2300,7 +2320,7 @@ namespace IKVM.Reflection
{
internal static Type Make(Type type, CustomModifiers mods)
{
- return type.Module.CanonicalizeType(new PointerType(type, mods));
+ return type.Universe.CanonicalizeType(new PointerType(type, mods));
}
private PointerType(Type type, CustomModifiers mods)
@@ -2379,7 +2399,7 @@ namespace IKVM.Reflection
}
else
{
- return type.Module.CanonicalizeType(new GenericTypeInstance(type, typeArguments, mods));
+ return type.Universe.CanonicalizeType(new GenericTypeInstance(type, typeArguments, mods));
}
}
@@ -2701,4 +2721,79 @@ namespace IKVM.Reflection
return type.GetCustomAttributesData(attributeType);
}
}
+
+ sealed class FunctionPointerType : Type
+ {
+ private readonly Universe universe;
+ private readonly __StandAloneMethodSig sig;
+
+ internal static Type Make(Universe universe, __StandAloneMethodSig sig)
+ {
+ return universe.CanonicalizeType(new FunctionPointerType(universe, sig));
+ }
+
+ private FunctionPointerType(Universe universe, __StandAloneMethodSig sig)
+ {
+ this.universe = universe;
+ this.sig = sig;
+ }
+
+ public override bool Equals(object obj)
+ {
+ FunctionPointerType other = obj as FunctionPointerType;
+ return other != null
+ && other.universe == universe
+ && other.sig.Equals(sig);
+ }
+
+ public override int GetHashCode()
+ {
+ return sig.GetHashCode();
+ }
+
+ public override bool __IsFunctionPointer
+ {
+ get { return true; }
+ }
+
+ public override __StandAloneMethodSig __MethodSignature
+ {
+ get { return sig; }
+ }
+
+ public override Type BaseType
+ {
+ get { return null; }
+ }
+
+ public override TypeAttributes Attributes
+ {
+ get { return 0; }
+ }
+
+ public override string Name
+ {
+ get { throw new InvalidOperationException(); }
+ }
+
+ public override string FullName
+ {
+ get { throw new InvalidOperationException(); }
+ }
+
+ public override Module Module
+ {
+ get { throw new InvalidOperationException(); }
+ }
+
+ internal override Universe Universe
+ {
+ get { return universe; }
+ }
+
+ public override string ToString()
+ {
+ return "<FunctionPtr>";
+ }
+ }
}
diff --git a/reflect/Universe.cs b/reflect/Universe.cs
index 4ad9e465..d2f7e926 100644
--- a/reflect/Universe.cs
+++ b/reflect/Universe.cs
@@ -77,15 +77,23 @@ namespace IKVM.Reflection
public delegate Assembly ResolveEventHandler(object sender, ResolveEventArgs args);
+ [Flags]
+ public enum UniverseOptions
+ {
+ None = 0,
+ EnableFunctionPointers = 1,
+ }
+
public sealed class Universe : IDisposable
{
- internal readonly Dictionary<Type, Type> canonicalizedTypes = new Dictionary<Type, Type>();
+ private readonly Dictionary<Type, Type> canonicalizedTypes = new Dictionary<Type, Type>();
private readonly List<Assembly> assemblies = new List<Assembly>();
private readonly List<AssemblyBuilder> dynamicAssemblies = new List<AssemblyBuilder>();
private readonly Dictionary<string, Assembly> assembliesByName = new Dictionary<string, Assembly>();
private readonly Dictionary<System.Type, Type> importedTypes = new Dictionary<System.Type, Type>();
private Dictionary<ScopedTypeName, Type> missingTypes;
private bool resolveMissingMembers;
+ private readonly bool enableFunctionPointers;
private Type typeof_System_Object;
private Type typeof_System_ValueType;
private Type typeof_System_Enum;
@@ -146,6 +154,16 @@ namespace IKVM.Reflection
private Type typeof_System_Security_Permissions_SecurityAction;
private List<ResolveEventHandler> resolvers = new List<ResolveEventHandler>();
+ public Universe()
+ : this(UniverseOptions.None)
+ {
+ }
+
+ public Universe(UniverseOptions options)
+ {
+ enableFunctionPointers = (options & UniverseOptions.EnableFunctionPointers) != 0;
+ }
+
internal Assembly Mscorlib
{
get { return Load("mscorlib"); }
@@ -856,6 +874,11 @@ namespace IKVM.Reflection
get { return resolveMissingMembers; }
}
+ internal bool EnableFunctionPointers
+ {
+ get { return enableFunctionPointers; }
+ }
+
private struct ScopedTypeName : IEquatable<ScopedTypeName>
{
private readonly object scope;
@@ -942,5 +965,21 @@ namespace IKVM.Reflection
}
throw new System.MissingMemberException(declaringType.ToString(), name);
}
+
+ internal Type CanonicalizeType(Type type)
+ {
+ Type canon;
+ if (!canonicalizedTypes.TryGetValue(type, out canon))
+ {
+ canon = type;
+ canonicalizedTypes.Add(canon, canon);
+ }
+ return canon;
+ }
+
+ public Type MakeFunctionPointer(__StandAloneMethodSig sig)
+ {
+ return FunctionPointerType.Make(this, sig);
+ }
}
}