Browse Source

Fix issues when base class virtual methods are prepended into primary vtable.

pull/1/head
Alexander Corrado 15 years ago committed by Alex Corrado
parent
commit
65edb53892
  1. 4
      src/Mono.VisualC.Interop/CppTypeInfo.cs
  2. 68
      src/Mono.VisualC.Interop/Util/LazyGeneratedList.cs

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

@ -103,8 +103,8 @@ namespace Mono.VisualC.Interop {
VirtualMethods.Insert (BaseVTableSlots + i, baseType.VirtualMethods [i]); VirtualMethods.Insert (BaseVTableSlots + i, baseType.VirtualMethods [i]);
BaseVTableSlots += newVirtualMethodCount; BaseVTableSlots += newVirtualMethodCount;
VTableDelegateTypes.Skew (newVirtualMethodCount); VTableDelegateTypes.PrependLast (baseType.VTableDelegateTypes);
VTableOverrides.Skew (newVirtualMethodCount); VTableOverrides.PrependLast (baseType.VTableOverrides);
} }
field_offset_padding += baseType.native_size + field_offset_padding += baseType.native_size +

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

@ -37,13 +37,16 @@ namespace Mono.VisualC.Interop.Util {
private TItem [] cache; private TItem [] cache;
private Func<int, TItem> generator; private Func<int, TItem> generator;
private int skew; private LazyGeneratedList<TItem> previous;
private LazyGeneratedList<TItem> next;
private int lead, follow;
public LazyGeneratedList (int count, Func<int, TItem> generator) public LazyGeneratedList (int count, Func<int, TItem> generator)
{ {
this.cache = new TItem [count]; this.cache = new TItem [count];
this.generator = generator; this.generator = generator;
this.skew = 0; this.lead = 0;
this.follow = 0;
} }
public IEnumerator<TItem> GetEnumerator () public IEnumerator<TItem> GetEnumerator ()
@ -57,7 +60,7 @@ namespace Mono.VisualC.Interop.Util {
} }
public int Count { public int Count {
get { return cache.Length + skew; } get { return lead + cache.Length + follow; }
} }
public bool IsReadOnly { public bool IsReadOnly {
@ -66,8 +69,19 @@ namespace Mono.VisualC.Interop.Util {
public TItem this [int index] { public TItem this [int index] {
get { get {
int realIndex = index - skew; if (index < lead) {
if (realIndex < 0) return null; if (previous != null && index > 0)
return previous [index];
throw new IndexOutOfRangeException (index.ToString ());
}
int realIndex = index - lead;
if (realIndex > cache.Length) {
int followIndex = realIndex - cache.Length;
if (next != null && followIndex < follow)
return next [followIndex];
throw new IndexOutOfRangeException (index.ToString ());
}
if (cache [realIndex] == null) if (cache [realIndex] == null)
cache [realIndex] = generator (realIndex); cache [realIndex] = generator (realIndex);
@ -79,9 +93,49 @@ namespace Mono.VisualC.Interop.Util {
} }
} }
public void Skew (int skew) /* Visual aid for the behavior of the following methods:
|<Prepended Range><Generated Range><Appended Range>|
^ ^ ^ ^
PrependFirst PrependLast AppendFirst AppendLast
*/
public void AppendFirst (LazyGeneratedList<TItem> list)
{
follow += list.Count;
if (next != null)
list.AppendLast (next);
next = list;
}
public void AppendLast (LazyGeneratedList<TItem> list)
{ {
this.skew += skew; if (next == null)
next = list;
else
next.AppendLast (list);
follow += list.Count;
}
public void PrependFirst (LazyGeneratedList<TItem> list)
{
if (previous == null)
previous = list;
else
previous.PrependFirst (list);
lead += list.Count;
}
public void PrependLast (LazyGeneratedList<TItem> list)
{
lead += list.Count;
if (previous != null)
list.PrependFirst (previous);
previous = list;
} }
// FIXME: Should probably implement these 3 at some point // FIXME: Should probably implement these 3 at some point

Loading…
Cancel
Save