From a69511b6e6355584aaa11262d7355b52251d4502 Mon Sep 17 00:00:00 2001 From: Alex Corrado Date: Tue, 16 Aug 2011 00:46:01 -0400 Subject: [PATCH] Account for alignment when calculating NativeSize, and fix bug with cloning base CppTypeInfos. --- src/Mono.Cxxi/Abi/VTable.cs | 2 +- src/Mono.Cxxi/CppTypeInfo.cs | 18 ++++++++++++++---- src/Mono.Cxxi/Util/LazyGeneratedList.cs | 5 ----- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/Mono.Cxxi/Abi/VTable.cs b/src/Mono.Cxxi/Abi/VTable.cs index af61e230..2d17a5c9 100644 --- a/src/Mono.Cxxi/Abi/VTable.cs +++ b/src/Mono.Cxxi/Abi/VTable.cs @@ -48,7 +48,7 @@ namespace Mono.Cxxi.Abi { get { return type_info.VirtualMethods.Count; } } public virtual int EntrySize { - get { return Marshal.SizeOf (typeof (IntPtr)); } + get { return IntPtr.Size; } } // Subclasses should allocate vtPtr and then call WriteOverrides diff --git a/src/Mono.Cxxi/CppTypeInfo.cs b/src/Mono.Cxxi/CppTypeInfo.cs index b7d8941a..10206f66 100644 --- a/src/Mono.Cxxi/CppTypeInfo.cs +++ b/src/Mono.Cxxi/CppTypeInfo.cs @@ -142,6 +142,10 @@ namespace Mono.Cxxi { #region Type Layout + public virtual int Alignment { + get { return IntPtr.Size; } + } + // the extra padding to allocate at the top of the class before the fields begin // (by default, just the vtable pointer) public virtual int FieldOffsetPadding { @@ -149,7 +153,10 @@ namespace Mono.Cxxi { } public virtual int NativeSize { - get { return native_size_without_padding + FieldOffsetPadding; } + get { + var basesize = native_size_without_padding + FieldOffsetPadding; + return basesize + (basesize % Alignment); + } } public virtual int GCHandleOffset { @@ -169,6 +176,7 @@ namespace Mono.Cxxi { return; var baseVMethodCount = baseType.virtual_methods.Count; + baseType = baseType.Clone (); switch (location) { @@ -197,7 +205,6 @@ namespace Mono.Cxxi { case BaseVirtualMethods.NewVTable: - baseType = baseType.Clone (); baseType.IsPrimaryBase = (base_classes.Count == 0); // offset all previously added bases @@ -208,8 +215,11 @@ namespace Mono.Cxxi { gchandle_offset_delta += baseType.GCHandleOffset; baseType.gchandle_offset_delta += native_size_without_padding + CountBases (b => !b.IsPrimaryBase) * IntPtr.Size; - baseType.vt_overrides = baseType.vt_overrides.Clone (); // managed override tramps will be regenerated with correct gchandle offset - baseType.lazy_vtable = new VTable (baseType); + + // ensure managed override tramps will be regenerated with correct gchandle offset + baseType.vt_overrides = new LazyGeneratedList (baseType.virtual_methods.Count, i => Library.Abi.GetManagedOverrideTrampoline (baseType, i)); + baseType.VTableOverrides = new ReadOnlyCollection (baseType.vt_overrides); + baseType.lazy_vtable = null; break; } diff --git a/src/Mono.Cxxi/Util/LazyGeneratedList.cs b/src/Mono.Cxxi/Util/LazyGeneratedList.cs index 9d9ffb0d..45d4be90 100644 --- a/src/Mono.Cxxi/Util/LazyGeneratedList.cs +++ b/src/Mono.Cxxi/Util/LazyGeneratedList.cs @@ -47,11 +47,6 @@ namespace Mono.Cxxi.Util { this.count = count; } - public virtual LazyGeneratedList Clone () - { - return new LazyGeneratedList (count, generator); - } - public IEnumerator GetEnumerator () { for (int i = 0; i < Count; i++)