Browse Source

Correctly generate managed override trampolines for native subclass wrappers

pull/1/head
Alex Corrado 14 years ago
parent
commit
b8bba69a81
  1. 15
      src/Mono.VisualC.Interop/ABI/CppAbi.cs
  2. 4
      src/Mono.VisualC.Interop/CppInstancePtr.cs
  3. 9
      src/Mono.VisualC.Interop/CppTypeInfo.cs
  4. 5
      src/Mono.VisualC.Interop/Util/LazyGeneratedList.cs

15
src/Mono.VisualC.Interop/ABI/CppAbi.cs

@ -339,7 +339,7 @@ namespace Mono.VisualC.Interop.ABI {
*/ */
internal virtual Delegate GetManagedOverrideTrampoline (CppTypeInfo typeInfo, int vtableIndex) internal virtual Delegate GetManagedOverrideTrampoline (CppTypeInfo typeInfo, int vtableIndex)
{ {
if (wrapper_type == null) if (typeInfo.WrapperType == null)
return null; return null;
var sig = typeInfo.VirtualMethods [vtableIndex]; var sig = typeInfo.VirtualMethods [vtableIndex];
@ -347,7 +347,7 @@ namespace Mono.VisualC.Interop.ABI {
return null; return null;
var interfaceMethod = sig.OrigMethod; var interfaceMethod = sig.OrigMethod;
var targetMethod = FindManagedOverrideTarget (interfaceMethod); var targetMethod = FindManagedOverrideTarget (typeInfo.WrapperType, interfaceMethod);
if (targetMethod == null) if (targetMethod == null)
return null; return null;
@ -357,7 +357,7 @@ namespace Mono.VisualC.Interop.ABI {
// TODO: According to http://msdn.microsoft.com/en-us/library/w16z8yc4.aspx // TODO: According to http://msdn.microsoft.com/en-us/library/w16z8yc4.aspx
// The dynamic method created with this constructor has access to public and internal members of all the types contained in module m. // The dynamic method created with this constructor has access to public and internal members of all the types contained in module m.
// This does not appear to hold true, so we also disable JIT visibility checks. // This does not appear to hold true, so we also disable JIT visibility checks.
var trampolineIn = new DynamicMethod (wrapper_type.Name + "_" + interfaceMethod.Name + "_FromNative", sig.ReturnType, var trampolineIn = new DynamicMethod (typeInfo.WrapperType.Name + "_" + interfaceMethod.Name + "_FromNative", sig.ReturnType,
nativeArgs, typeof (CppInstancePtr).Module, true); nativeArgs, typeof (CppInstancePtr).Module, true);
ReflectionHelper.ApplyMethodParameterAttributes (interfaceMethod, trampolineIn, true); ReflectionHelper.ApplyMethodParameterAttributes (interfaceMethod, trampolineIn, true);
@ -375,7 +375,7 @@ namespace Mono.VisualC.Interop.ABI {
il.Emit (OpCodes.Ldarg_0); il.Emit (OpCodes.Ldarg_0);
il.Emit (OpCodes.Ldc_I4, typeInfo.NativeSize); il.Emit (OpCodes.Ldc_I4, typeInfo.NativeSize);
MethodInfo getManagedObj = cppip_getmanaged.MakeGenericMethod (wrapper_type); var getManagedObj = cppip_getmanaged.MakeGenericMethod (typeInfo.WrapperType);
il.Emit (OpCodes.Call, getManagedObj); il.Emit (OpCodes.Call, getManagedObj);
} }
@ -391,14 +391,13 @@ namespace Mono.VisualC.Interop.ABI {
return trampolineIn.CreateDelegate (typeInfo.VTableDelegateTypes [vtableIndex]); return trampolineIn.CreateDelegate (typeInfo.VTableDelegateTypes [vtableIndex]);
} }
protected virtual MethodInfo FindManagedOverrideTarget (MethodInfo interfaceMethod) protected virtual MethodInfo FindManagedOverrideTarget (Type wrapper, MethodInfo interfaceMethod)
{ {
if (interfaceMethod == null) if (interfaceMethod == null)
return null; return null;
// FIXME: Does/should this look in superclasses? var possibleMembers = wrapper.FindMembers (MemberTypes.Method, BindingFlags.Public | BindingFlags.NonPublic |
MemberInfo [] possibleMembers = wrapper_type.FindMembers (MemberTypes.Method, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, vtable_override_filter, interfaceMethod);
BindingFlags.Instance | BindingFlags.Static, vtable_override_filter, interfaceMethod);
if (possibleMembers.Length > 1) if (possibleMembers.Length > 1)
throw new InvalidProgramException ("More than one possible override found when binding virtual method: " + interfaceMethod.Name); throw new InvalidProgramException ("More than one possible override found when binding virtual method: " + interfaceMethod.Name);

4
src/Mono.VisualC.Interop/CppInstancePtr.cs

@ -79,7 +79,7 @@ namespace Mono.VisualC.Interop {
byte[] zeroArray = new byte [allocSize]; byte[] zeroArray = new byte [allocSize];
Marshal.Copy (zeroArray, 0, ptr, allocSize); Marshal.Copy (zeroArray, 0, ptr, allocSize);
IntPtr handlePtr = GetGCHandle (managedWrapper); IntPtr handlePtr = MakeGCHandle (managedWrapper);
Marshal.WriteIntPtr (ptr, nativeSize, handlePtr); Marshal.WriteIntPtr (ptr, nativeSize, handlePtr);
manage_memory = true; manage_memory = true;
@ -131,7 +131,7 @@ namespace Mono.VisualC.Interop {
get { return manage_memory; } get { return manage_memory; }
} }
internal static IntPtr GetGCHandle (object managedWrapper) internal static IntPtr MakeGCHandle (object managedWrapper)
{ {
// TODO: Dispose() should probably be called at some point on this GCHandle. // TODO: Dispose() should probably be called at some point on this GCHandle.
GCHandle handle = GCHandle.Alloc (managedWrapper, GCHandleType.Normal); GCHandle handle = GCHandle.Alloc (managedWrapper, GCHandleType.Normal);

9
src/Mono.VisualC.Interop/CppTypeInfo.cs

@ -121,13 +121,14 @@ namespace Mono.VisualC.Interop {
// If we're not adding a new vtable, then all this base class's virtual methods go in primary vtable // If we're not adding a new vtable, then all this base class's virtual methods go in primary vtable
// Skew the offsets of this subclass's vmethods to account for the new base vmethods. // Skew the offsets of this subclass's vmethods to account for the new base vmethods.
int newVirtualMethodCount = baseType.virtual_methods.Count; int baseVMethodCount = baseType.virtual_methods.Count;
for (int i = 0; i < newVirtualMethodCount; i++) for (int i = 0; i < baseVMethodCount; i++)
virtual_methods.Insert (BaseVTableSlots + i, baseType.virtual_methods [i]); virtual_methods.Insert (BaseVTableSlots + i, baseType.virtual_methods [i]);
BaseVTableSlots += newVirtualMethodCount; BaseVTableSlots += baseVMethodCount;
vt_delegate_types.PrependLast (baseType.vt_delegate_types); vt_delegate_types.PrependLast (baseType.vt_delegate_types);
vt_overrides.PrependLast (baseType.vt_overrides); //vt_overrides.PrependLast (baseType.vt_overrides);
vt_overrides.Add (baseVMethodCount);
} else { } else {
// FIXME: Implement this when we get around to msvc again ? // FIXME: Implement this when we get around to msvc again ?

5
src/Mono.VisualC.Interop/Util/LazyGeneratedList.cs

@ -195,6 +195,11 @@ namespace Mono.VisualC.Interop.Util {
removed.Add (index); removed.Add (index);
content--; content--;
} }
public void Add (int count)
{
content += count;
Array.Resize (ref cache, content);
}
public void Add (TItem item) public void Add (TItem item)
{ {
throw new NotImplementedException (); throw new NotImplementedException ();

Loading…
Cancel
Save