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

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

@ -37,13 +37,16 @@ namespace Mono.VisualC.Interop.Util { @@ -37,13 +37,16 @@ namespace Mono.VisualC.Interop.Util {
private TItem [] cache;
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)
{
this.cache = new TItem [count];
this.generator = generator;
this.skew = 0;
this.lead = 0;
this.follow = 0;
}
public IEnumerator<TItem> GetEnumerator ()
@ -57,7 +60,7 @@ namespace Mono.VisualC.Interop.Util { @@ -57,7 +60,7 @@ namespace Mono.VisualC.Interop.Util {
}
public int Count {
get { return cache.Length + skew; }
get { return lead + cache.Length + follow; }
}
public bool IsReadOnly {
@ -66,8 +69,19 @@ namespace Mono.VisualC.Interop.Util { @@ -66,8 +69,19 @@ namespace Mono.VisualC.Interop.Util {
public TItem this [int index] {
get {
int realIndex = index - skew;
if (realIndex < 0) return null;
if (index < lead) {
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)
cache [realIndex] = generator (realIndex);
@ -79,9 +93,49 @@ namespace Mono.VisualC.Interop.Util { @@ -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

Loading…
Cancel
Save