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 { @@ -339,7 +339,7 @@ namespace Mono.VisualC.Interop.ABI {
*/
internal virtual Delegate GetManagedOverrideTrampoline (CppTypeInfo typeInfo, int vtableIndex)
{
if (wrapper_type == null)
if (typeInfo.WrapperType == null)
return null;
var sig = typeInfo.VirtualMethods [vtableIndex];
@ -347,7 +347,7 @@ namespace Mono.VisualC.Interop.ABI { @@ -347,7 +347,7 @@ namespace Mono.VisualC.Interop.ABI {
return null;
var interfaceMethod = sig.OrigMethod;
var targetMethod = FindManagedOverrideTarget (interfaceMethod);
var targetMethod = FindManagedOverrideTarget (typeInfo.WrapperType, interfaceMethod);
if (targetMethod == null)
return null;
@ -357,7 +357,7 @@ namespace Mono.VisualC.Interop.ABI { @@ -357,7 +357,7 @@ namespace Mono.VisualC.Interop.ABI {
// 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.
// 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);
ReflectionHelper.ApplyMethodParameterAttributes (interfaceMethod, trampolineIn, true);
@ -375,7 +375,7 @@ namespace Mono.VisualC.Interop.ABI { @@ -375,7 +375,7 @@ namespace Mono.VisualC.Interop.ABI {
il.Emit (OpCodes.Ldarg_0);
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);
}
@ -391,14 +391,13 @@ namespace Mono.VisualC.Interop.ABI { @@ -391,14 +391,13 @@ namespace Mono.VisualC.Interop.ABI {
return trampolineIn.CreateDelegate (typeInfo.VTableDelegateTypes [vtableIndex]);
}
protected virtual MethodInfo FindManagedOverrideTarget (MethodInfo interfaceMethod)
protected virtual MethodInfo FindManagedOverrideTarget (Type wrapper, MethodInfo interfaceMethod)
{
if (interfaceMethod == null)
return null;
// FIXME: Does/should this look in superclasses?
MemberInfo [] possibleMembers = wrapper_type.FindMembers (MemberTypes.Method, BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.Static, vtable_override_filter, interfaceMethod);
var possibleMembers = wrapper.FindMembers (MemberTypes.Method, BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.Static, vtable_override_filter, interfaceMethod);
if (possibleMembers.Length > 1)
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 { @@ -79,7 +79,7 @@ namespace Mono.VisualC.Interop {
byte[] zeroArray = new byte [allocSize];
Marshal.Copy (zeroArray, 0, ptr, allocSize);
IntPtr handlePtr = GetGCHandle (managedWrapper);
IntPtr handlePtr = MakeGCHandle (managedWrapper);
Marshal.WriteIntPtr (ptr, nativeSize, handlePtr);
manage_memory = true;
@ -131,7 +131,7 @@ namespace Mono.VisualC.Interop { @@ -131,7 +131,7 @@ namespace Mono.VisualC.Interop {
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.
GCHandle handle = GCHandle.Alloc (managedWrapper, GCHandleType.Normal);

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

@ -121,13 +121,14 @@ namespace Mono.VisualC.Interop { @@ -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
// Skew the offsets of this subclass's vmethods to account for the new base vmethods.
int newVirtualMethodCount = baseType.virtual_methods.Count;
for (int i = 0; i < newVirtualMethodCount; i++)
int baseVMethodCount = baseType.virtual_methods.Count;
for (int i = 0; i < baseVMethodCount; i++)
virtual_methods.Insert (BaseVTableSlots + i, baseType.virtual_methods [i]);
BaseVTableSlots += newVirtualMethodCount;
BaseVTableSlots += baseVMethodCount;
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 {
// 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 { @@ -195,6 +195,11 @@ namespace Mono.VisualC.Interop.Util {
removed.Add (index);
content--;
}
public void Add (int count)
{
content += count;
Array.Resize (ref cache, content);
}
public void Add (TItem item)
{
throw new NotImplementedException ();

Loading…
Cancel
Save