Browse Source

Made the original virtual tables static too

Virtual tables are the same object per class in C++.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/1366/head
Dimitar Dobrev 5 years ago committed by João Matos
parent
commit
09222174c1
  1. 134
      src/Generator/Generators/CSharp/CSharpSources.cs

134
src/Generator/Generators/CSharp/CSharpSources.cs

@ -438,7 +438,6 @@ namespace CppSharp.Generators.CSharp @@ -438,7 +438,6 @@ namespace CppSharp.Generators.CSharp
var dict = $@"global::System.Collections.Concurrent.ConcurrentDictionary<IntPtr, {
printedClass}>";
WriteLine("internal static readonly {0} NativeToManagedMap = new {0}();", dict);
WriteLine("protected internal void*[] __OriginalVTables;");
}
PopBlock(NewLineKind.BeforeNextBlock);
}
@ -1521,6 +1520,11 @@ namespace CppSharp.Generators.CSharp @@ -1521,6 +1520,11 @@ namespace CppSharp.Generators.CSharp
if (wrappedEntries.Any(e => e.Method.IsDestructor))
WriteLine("private static void*[] __ManagedVTablesDtorOnly;");
WriteLine("private static void*[] _Thunks;");
WriteLine("private static void*[] __originalVTables;");
bool hasDynamicBase = @class.NeedsBase && @class.BaseClass.IsDynamic;
Write($@"protected internal {(hasDynamicBase ? "override" : "virtual"
)} void*[] __OriginalVTables => __originalVTables ?? ");
SaveOriginalVTablePointers(@class);
NewLine();
GenerateVTableClassSetup(@class, wrappedEntries);
@ -1535,13 +1539,6 @@ namespace CppSharp.Generators.CSharp @@ -1535,13 +1539,6 @@ namespace CppSharp.Generators.CSharp
WriteLine("private void SetupVTables(bool {0} = false)", destructorOnly);
WriteOpenBraceAndIndent();
WriteLine("if (__OriginalVTables != null)");
WriteLineIndent("return;");
SaveOriginalVTablePointers(@class);
NewLine();
var hasVirtualDtor = wrappedEntries.Any(e => e.Method.IsDestructor);
if (!hasVirtualDtor)
{
@ -1549,7 +1546,6 @@ namespace CppSharp.Generators.CSharp @@ -1549,7 +1546,6 @@ namespace CppSharp.Generators.CSharp
WriteLineIndent("return;");
}
// Get the _Thunks
WriteLine("if (_Thunks == null)");
WriteOpenBraceAndIndent();
WriteLine("_Thunks = new void*[{0}];", wrappedEntries.Count);
@ -1567,30 +1563,34 @@ namespace CppSharp.Generators.CSharp @@ -1567,30 +1563,34 @@ namespace CppSharp.Generators.CSharp
WriteLine("_Thunks[{0}] = Marshal.GetFunctionPointerForDelegate({1}).ToPointer();",
i, instance);
}
UnindentAndWriteCloseBrace();
NewLine();
if (hasVirtualDtor)
{
WriteLine("if ({0})", destructorOnly);
WriteOpenBraceAndIndent();
WriteLine("if (__ManagedVTablesDtorOnly == null)");
WriteOpenBraceAndIndent();
AllocateNewVTables(@class, wrappedEntries, destructorOnly: true);
AllocateNewVTables(@class, wrappedEntries, true);
AllocateNewVTables(@class, wrappedEntries, destructorOnly: false);
Write("__originalVTables = ");
SaveOriginalVTablePointers(@class);
UnindentAndWriteCloseBrace();
NewLine();
if (hasVirtualDtor)
{
WriteLine($"if ({destructorOnly})");
WriteOpenBraceAndIndent();
AssignNewVTableEntries(@class, "__ManagedVTablesDtorOnly");
UnindentAndWriteCloseBrace();
WriteLine("else");
WriteOpenBraceAndIndent();
}
WriteLine("if (__ManagedVTables == null)");
WriteOpenBraceAndIndent();
AllocateNewVTables(@class, wrappedEntries, false);
if (hasVirtualDtor)
AssignNewVTableEntries(@class, "__ManagedVTables");
UnindentAndWriteCloseBrace();
}
else
{
AssignNewVTableEntries(@class, "__ManagedVTables");
}
UnindentAndWriteCloseBrace();
NewLine();
@ -1603,6 +1603,20 @@ namespace CppSharp.Generators.CSharp @@ -1603,6 +1603,20 @@ namespace CppSharp.Generators.CSharp
AllocateNewVTablesMS(@class, wrappedEntries, destructorOnly);
else
AllocateNewVTablesItanium(@class, wrappedEntries, destructorOnly);
NewLine();
}
private void AssignNewVTableEntries(Class @class, string table)
{
int size = Context.ParserOptions.IsMicrosoftAbi ?
@class.Layout.VTablePointers.Count : 1;
for (int i = 0; i < size; i++)
{
var offset = @class.Layout.VTablePointers[i].Offset;
WriteLine($"*(void**) ({Helpers.InstanceIdentifier} + {offset}) = {table}[{i}];");
}
}
private void SaveOriginalVTablePointers(Class @class)
@ -1610,66 +1624,55 @@ namespace CppSharp.Generators.CSharp @@ -1610,66 +1624,55 @@ namespace CppSharp.Generators.CSharp
if (@class.IsDependent)
@class = @class.Specializations[0];
Write("new void*[] { ");
if (Context.ParserOptions.IsMicrosoftAbi)
WriteLine("__OriginalVTables = new void*[] {{ {0} }};",
string.Join(", ",
@class.Layout.VTablePointers.Select(v =>
$"*(void**) ({Helpers.InstanceIdentifier} + {v.Offset})")));
Write(string.Join(", ", @class.Layout.VTablePointers.Select(
v => $"*(void**) ({Helpers.InstanceIdentifier} + {v.Offset})")));
else
WriteLine(
$@"__OriginalVTables = new void*[] {{ *(void**) ({
Helpers.InstanceIdentifier} + {@class.Layout.VTablePointers[0].Offset}) }};");
Write($@"*(void**) ({Helpers.InstanceIdentifier} + {
@class.Layout.VTablePointers[0].Offset})");
WriteLine(" };");
}
private void AllocateNewVTablesMS(Class @class, IList<VTableComponent> wrappedEntries,
bool destructorOnly)
{
var managedVTables = destructorOnly ? "__ManagedVTablesDtorOnly" : "__ManagedVTables";
WriteLine("{0} = new void*[{1}];", managedVTables, @class.Layout.VFTables.Count);
WriteLine($"{managedVTables} = new void*[{@class.Layout.VFTables.Count}];");
for (int i = 0; i < @class.Layout.VFTables.Count; i++)
{
var vfptr = @class.Layout.VFTables[i];
var size = vfptr.Layout.Components.Count;
WriteLine("var vfptr{0} = Marshal.AllocHGlobal({1} * {2});",
i, size, Context.TargetInfo.PointerWidth / 8);
WriteLine("{0}[{1}] = vfptr{1}.ToPointer();", managedVTables, i);
VFTableInfo vftable = @class.Layout.VFTables[i];
int size = vftable.Layout.Components.Count;
string vfptr = $"vfptr{(destructorOnly ? "_dtor" : string.Empty)}{i}";
WriteLine($@"var {vfptr} = Marshal.AllocHGlobal({size} * {
Context.TargetInfo.PointerWidth / 8});");
WriteLine($"{managedVTables}[{i}] = {vfptr}.ToPointer();");
AllocateNewVTableEntries(vfptr.Layout.Components, wrappedEntries,
AllocateNewVTableEntries(vftable.Layout.Components, wrappedEntries,
@class.Layout.VTablePointers[i].Offset, i, destructorOnly);
}
UnindentAndWriteCloseBrace();
NewLine();
for (int i = 0; i < @class.Layout.VTablePointers.Count; i++)
{
var offset = @class.Layout.VTablePointers[i].Offset;
WriteLine($"*(void**) ({Helpers.InstanceIdentifier} + {offset}) = {managedVTables}[{i}];");
}
}
private void AllocateNewVTablesItanium(Class @class, IList<VTableComponent> wrappedEntries,
bool destructorOnly)
{
var managedVTables = destructorOnly ? "__ManagedVTablesDtorOnly" : "__ManagedVTables";
WriteLine("{0} = new void*[1];", managedVTables);
WriteLine($"{managedVTables} = new void*[1];");
var size = @class.Layout.Layout.Components.Count;
var pointerSize = Context.TargetInfo.PointerWidth / 8;
WriteLine("var vtptr = Marshal.AllocHGlobal({0} * {1});", size, pointerSize);
string suffix = destructorOnly ? "_dtor" : string.Empty;
int size = @class.Layout.Layout.Components.Count;
uint pointerSize = Context.TargetInfo.PointerWidth / 8;
WriteLine($"var vtptr{suffix} = Marshal.AllocHGlobal({size} * {pointerSize});");
WriteLine("var vfptr0 = vtptr + {0} * {1};", VTables.ItaniumOffsetToTopAndRTTI, pointerSize);
WriteLine("{0}[0] = vfptr0.ToPointer();", managedVTables);
WriteLine($@"var vfptr{suffix}0 = vtptr{suffix} + {
VTables.ItaniumOffsetToTopAndRTTI} * {pointerSize};");
WriteLine($"{managedVTables}[0] = vfptr{suffix}0.ToPointer();");
AllocateNewVTableEntries(@class.Layout.Layout.Components,
wrappedEntries, @class.Layout.VTablePointers[0].Offset, 0, destructorOnly);
UnindentAndWriteCloseBrace();
NewLine();
var offset = @class.Layout.VTablePointers[0].Offset;
WriteLine($"*(void**) ({Helpers.InstanceIdentifier} + {offset}) = {managedVTables}[0];");
}
private void AllocateNewVTableEntries(IList<VTableComponent> entries,
@ -1684,7 +1687,8 @@ namespace CppSharp.Generators.CSharp @@ -1684,7 +1687,8 @@ namespace CppSharp.Generators.CSharp
var nativeVftableEntry = $@"*(void**) (new IntPtr(*(void**) {
Helpers.InstanceIdentifier}) + {vptrOffset} + {offset})";
var managedVftableEntry = $"*(void**) (vfptr{tableIndex} + {offset})";
string vfptr = $"vfptr{(destructorOnly ? "_dtor" : string.Empty)}{tableIndex}";
var managedVftableEntry = $"*(void**) ({vfptr} + {offset})";
if ((entry.Kind == VTableComponentKind.FunctionPointer ||
entry.Kind == VTableComponentKind.DeletingDtorPointer) &&
@ -2207,17 +2211,7 @@ namespace CppSharp.Generators.CSharp @@ -2207,17 +2211,7 @@ namespace CppSharp.Generators.CSharp
var setupVTables = !@class.IsAbstractImpl && hasVTables && dtor?.IsVirtual == true;
if (setupVTables)
{
WriteLine("if (skipVTables)");
Indent();
}
if (@class.IsAbstractImpl || hasVTables)
SaveOriginalVTablePointers(@class);
if (setupVTables)
{
Unindent();
WriteLine("else");
WriteLine("if (!skipVTables)");
Indent();
GenerateVTableClassSetupCall(@class, destructorOnly: true);
Unindent();

Loading…
Cancel
Save