Browse Source

Make certain CppTypeInfo properties read-only

pull/1/head
Alex Corrado 14 years ago
parent
commit
4c73c29878
  1. 54
      src/Mono.VisualC.Interop/CppTypeInfo.cs

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

@ -30,6 +30,7 @@ using System;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -45,11 +46,17 @@ namespace Mono.VisualC.Interop {
public CppAbi Abi { get; private set; } public CppAbi Abi { get; private set; }
public Type NativeLayout {get; private set; } public Type NativeLayout {get; private set; }
public IList<PInvokeSignature> VirtualMethods { get; private set; } public IList<PInvokeSignature> VirtualMethods { get; private set; } // read only version
public LazyGeneratedList<Type> VTableDelegateTypes { get; private set; } protected List<PInvokeSignature> virtual_methods;
public LazyGeneratedList<Delegate> VTableOverrides { get; private set; }
public IList<CppTypeInfo> BaseClasses { get; private set; } public IList<Type> VTableDelegateTypes { get; private set; } // read only version
protected LazyGeneratedList<Type> vt_delegate_types;
public IList<Delegate> VTableOverrides { get; private set; } // read only version
protected LazyGeneratedList<Delegate> vt_overrides;
public IList<CppTypeInfo> BaseClasses { get; private set; } // read only version
protected List<CppTypeInfo> base_classes;
// returns the number of vtable slots reserved for the // returns the number of vtable slots reserved for the
// base class(es) // base class(es)
@ -67,11 +74,18 @@ namespace Mono.VisualC.Interop {
Abi = abi; Abi = abi;
NativeLayout = nativeLayout; NativeLayout = nativeLayout;
VirtualMethods = new List<PInvokeSignature> (virtualMethods); virtual_methods = new List<PInvokeSignature> (virtualMethods);
VTableDelegateTypes = new LazyGeneratedList<Type> (VirtualMethods.Count, i => DelegateTypeCache.GetDelegateType (VirtualMethods [i])); VirtualMethods = new ReadOnlyCollection<PInvokeSignature> (virtual_methods);
VTableOverrides = new LazyGeneratedList<Delegate> (VirtualMethods.Count, i => Abi.GetManagedOverrideTrampoline (this, i));
vt_delegate_types = new LazyGeneratedList<Type> (virtual_methods.Count, i => DelegateTypeCache.GetDelegateType (virtual_methods [i]));
VTableDelegateTypes = new ReadOnlyCollection<Type> (vt_delegate_types);
vt_overrides = new LazyGeneratedList<Delegate> (virtual_methods.Count, i => Abi.GetManagedOverrideTrampoline (this, i));
VTableOverrides = new ReadOnlyCollection<Delegate> (vt_overrides);
base_classes = new List<CppTypeInfo> ();
BaseClasses = new ReadOnlyCollection<CppTypeInfo> (base_classes);
BaseClasses = new List<CppTypeInfo> ();
BaseVTableSlots = 0; BaseVTableSlots = 0;
TypeComplete = false; TypeComplete = false;
@ -93,19 +107,19 @@ namespace Mono.VisualC.Interop {
if (TypeComplete) if (TypeComplete)
return; return;
BaseClasses.Add (baseType); base_classes.Add (baseType);
if (!addVTablePointer) { if (!addVTablePointer) {
// If we're not adding a vtptr, then all this base class's virtual methods go in primary vtable // If we're not adding a vtptr, 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.VirtualMethods.Count; int newVirtualMethodCount = baseType.virtual_methods.Count;
for (int i = 0; i < newVirtualMethodCount; i++) for (int i = 0; i < newVirtualMethodCount; i++)
VirtualMethods.Insert (BaseVTableSlots + i, baseType.VirtualMethods [i]); virtual_methods.Insert (BaseVTableSlots + i, baseType.virtual_methods [i]);
BaseVTableSlots += newVirtualMethodCount; BaseVTableSlots += newVirtualMethodCount;
VTableDelegateTypes.PrependLast (baseType.VTableDelegateTypes); vt_delegate_types.PrependLast (baseType.vt_delegate_types);
VTableOverrides.PrependLast (baseType.VTableOverrides); vt_overrides.PrependLast (baseType.vt_overrides);
} }
field_offset_padding_without_vtptr += baseType.native_size + field_offset_padding_without_vtptr += baseType.native_size +
@ -115,7 +129,7 @@ namespace Mono.VisualC.Interop {
public int CountBases (Func<CppTypeInfo, bool> predicate) public int CountBases (Func<CppTypeInfo, bool> predicate)
{ {
int count = 0; int count = 0;
foreach (var baseClass in BaseClasses) { foreach (var baseClass in base_classes) {
count += baseClass.CountBases (predicate); count += baseClass.CountBases (predicate);
count += predicate (baseClass)? 1 : 0; count += predicate (baseClass)? 1 : 0;
} }
@ -127,7 +141,7 @@ namespace Mono.VisualC.Interop {
if (TypeComplete) if (TypeComplete)
return; return;
foreach (var baseClass in BaseClasses) foreach (var baseClass in base_classes)
baseClass.CompleteType (); baseClass.CompleteType ();
TypeComplete = true; TypeComplete = true;
@ -139,14 +153,14 @@ namespace Mono.VisualC.Interop {
// check that any virtual methods overridden in a subclass are only included once // check that any virtual methods overridden in a subclass are only included once
var vsignatures = new HashSet<MethodSignature> (); var vsignatures = new HashSet<MethodSignature> ();
for (int i = 0; i < VirtualMethods.Count; i++) { for (int i = 0; i < virtual_methods.Count; i++) {
var sig = VirtualMethods [i]; var sig = virtual_methods [i];
if (sig == null) if (sig == null)
continue; continue;
if (vsignatures.Contains (sig)) { if (vsignatures.Contains (sig)) {
if (pred (sig)) if (pred (sig))
VirtualMethods.RemoveAt (i--); virtual_methods.RemoveAt (i--);
} else { } else {
vsignatures.Add (sig); vsignatures.Add (sig);
} }
@ -163,7 +177,7 @@ namespace Mono.VisualC.Interop {
public virtual VTable VTable { public virtual VTable VTable {
get { get {
CompleteType (); CompleteType ();
if (!VirtualMethods.Any ()) if (!virtual_methods.Any ())
return null; return null;
if (lazy_vtable == null) if (lazy_vtable == null)
@ -183,7 +197,7 @@ namespace Mono.VisualC.Interop {
// the extra padding to allocate at the top of the class before the fields begin // the extra padding to allocate at the top of the class before the fields begin
// (by default, just the vtable pointer) // (by default, just the vtable pointer)
public virtual int FieldOffsetPadding { public virtual int FieldOffsetPadding {
get { return field_offset_padding_without_vtptr + (VirtualMethods.Any ()? Marshal.SizeOf (typeof (IntPtr)) : 0); } get { return field_offset_padding_without_vtptr + (virtual_methods.Any ()? Marshal.SizeOf (typeof (IntPtr)) : 0); }
} }
// the padding in the data pointed to by the vtable pointer before the list of function pointers starts // the padding in the data pointed to by the vtable pointer before the list of function pointers starts

Loading…
Cancel
Save