Browse Source

Decreased the pass for abstract impls in half.

Signed-off-by: Dimitar Dobrev <dpldobrev@yahoo.com>
pull/546/head
Dimitar Dobrev 11 years ago
parent
commit
9377845ba7
  1. 10
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  2. 81
      src/Generator/Passes/GenerateAbstractImplementationsPass.cs

10
src/Generator/Generators/CSharp/CSharpTextTemplate.cs

@ -820,7 +820,7 @@ namespace CppSharp.Generators.CSharp
if (function.SynthKind == FunctionSynthKind.AbstractImplCall) if (function.SynthKind == FunctionSynthKind.AbstractImplCall)
{ {
string delegateId; string delegateId;
Write(GetAbstractCallDelegate(function, @class, out delegateId)); Write(GetAbstractCallDelegate(function, @class.BaseClass, out delegateId));
GenerateFunctionCall(delegateId, new List<Parameter> { param }, function); GenerateFunctionCall(delegateId, new List<Parameter> { param }, function);
} }
else else
@ -955,7 +955,7 @@ namespace CppSharp.Generators.CSharp
WriteStartBraceIndent(); WriteStartBraceIndent();
var method = function as Method; var method = function as Method;
if (method != null && method.SynthKind == FunctionSynthKind.AbstractImplCall) if (method != null && method.SynthKind == FunctionSynthKind.AbstractImplCall)
GenerateAbstractImplCall(method, @class); GenerateAbstractImplCall(method, @class.BaseClass);
else else
GenerateInternalFunctionCall(function, function.Parameters, returnType.Type); GenerateInternalFunctionCall(function, function.Parameters, returnType.Type);
} }
@ -2124,7 +2124,7 @@ namespace CppSharp.Generators.CSharp
} }
else if (method.SynthKind == FunctionSynthKind.AbstractImplCall) else if (method.SynthKind == FunctionSynthKind.AbstractImplCall)
{ {
GenerateAbstractImplCall(method, @class); GenerateAbstractImplCall(method, @class.BaseClass);
} }
else else
{ {
@ -2264,9 +2264,9 @@ namespace CppSharp.Generators.CSharp
out string delegateId) out string delegateId)
{ {
var virtualCallBuilder = new StringBuilder(); var virtualCallBuilder = new StringBuilder();
var i = VTables.GetVTableIndex(function, @class); var i = VTables.GetVTableIndex(function.OriginalFunction, @class);
virtualCallBuilder.AppendFormat("void* slot = *(void**) ((({0}.Internal*) {1})->vfptr0 + {2} * {3});", virtualCallBuilder.AppendFormat("void* slot = *(void**) ((({0}.Internal*) {1})->vfptr0 + {2} * {3});",
@class.BaseClass.Name, Helpers.InstanceIdentifier, i, Driver.TargetInfo.PointerWidth / 8); @class.Name, Helpers.InstanceIdentifier, i, Driver.TargetInfo.PointerWidth / 8);
virtualCallBuilder.AppendLine(); virtualCallBuilder.AppendLine();
string @delegate = GetVTableMethodDelegateName(function.OriginalFunction); string @delegate = GetVTableMethodDelegateName(function.OriginalFunction);

81
src/Generator/Passes/GenerateAbstractImplementationsPass.cs

@ -1,7 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using CppSharp.AST; using CppSharp.AST;
using CppAbi = CppSharp.Parser.AST.CppAbi;
namespace CppSharp.Passes namespace CppSharp.Passes
{ {
@ -53,7 +52,7 @@ namespace CppSharp.Passes
return @class.IsAbstract; return @class.IsAbstract;
} }
private Class AddInternalImplementation(Class @class) private static Class AddInternalImplementation(Class @class)
{ {
var internalImpl = GetInternalImpl(@class); var internalImpl = GetInternalImpl(@class);
@ -70,8 +69,7 @@ namespace CppSharp.Passes
SynthKind = FunctionSynthKind.AbstractImplCall SynthKind = FunctionSynthKind.AbstractImplCall
}); });
internalImpl.Layout = new ClassLayout(@class.Layout); internalImpl.Layout = @class.Layout;
FillVTable(@class, abstractMethods, internalImpl);
return internalImpl; return internalImpl;
} }
@ -128,80 +126,5 @@ namespace CppSharp.Passes
return overriddenMethods; return overriddenMethods;
} }
private void FillVTable(Class @class, IList<Method> abstractMethods, Class internalImplementation)
{
switch (Driver.Options.Abi)
{
case CppAbi.Microsoft:
CreateVTableMS(@class, abstractMethods, internalImplementation);
break;
default:
CreateVTableItanium(@class, abstractMethods, internalImplementation);
break;
}
}
private static void CreateVTableMS(Class @class,
IList<Method> abstractMethods, Class internalImplementation)
{
var vtables = GetVTables(@class);
for (int i = 0; i < abstractMethods.Count; i++)
{
for (int j = 0; j < vtables.Count; j++)
{
var vTable = vtables[j];
var k = vTable.Layout.Components.FindIndex(v => v.Method == abstractMethods[i]);
if (k >= 0)
{
var vTableComponent = vTable.Layout.Components[k];
vTableComponent.Declaration = internalImplementation.Methods[i];
vTable.Layout.Components[k] = vTableComponent;
vtables[j] = vTable;
}
}
}
internalImplementation.Layout.VFTables.Clear();
internalImplementation.Layout.VFTables.AddRange(vtables);
}
private static void CreateVTableItanium(Class @class,
IList<Method> abstractMethods, Class internalImplementation)
{
var vtableComponents = GetVTableComponents(@class);
for (var i = 0; i < abstractMethods.Count; i++)
{
var j = vtableComponents.FindIndex(v => v.Method == abstractMethods[i]);
var vtableComponent = vtableComponents[j];
vtableComponent.Declaration = internalImplementation.Methods[i];
vtableComponents[j] = vtableComponent;
}
internalImplementation.Layout.Layout.Components.Clear();
internalImplementation.Layout.Layout.Components.AddRange(vtableComponents);
}
private static List<VTableComponent> GetVTableComponents(Class @class)
{
var vtableComponents = new List<VTableComponent>(
@class.Layout.Layout.Components);
foreach (var @base in @class.Bases)
vtableComponents.AddRange(GetVTableComponents(@base.Class));
return vtableComponents;
}
private static List<VFTableInfo> GetVTables(Class @class)
{
var vtables = new List<VFTableInfo>(
@class.Layout.VFTables);
foreach (var @base in @class.Bases)
vtables.AddRange(GetVTables(@base.Class));
return vtables;
}
} }
} }

Loading…
Cancel
Save