Browse Source

Fixed a memory leak by removing from static members typedefs used for delegates.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/593/head
Dimitar Dobrev 10 years ago
parent
commit
057e025ee3
  1. 6
      src/Generator/Driver.cs
  2. 16
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  3. 72
      src/Generator/Passes/DelegatesPass.cs

6
src/Generator/Driver.cs

@ -14,6 +14,7 @@ using CppSharp.Types; @@ -14,6 +14,7 @@ using CppSharp.Types;
using Microsoft.CSharp;
using CppSharp.Parser;
using System.CodeDom;
using System;
namespace CppSharp
{
@ -32,6 +33,8 @@ namespace CppSharp @@ -32,6 +33,8 @@ namespace CppSharp
public ASTContext ASTContext { get; private set; }
public SymbolContext Symbols { get; private set; }
public Dictionary<Function, DelegatesPass.DelegateDefinition> Delegates { get; private set; }
public bool HasCompilationErrors { get; set; }
private static readonly Dictionary<string, string> libraryMappings = new Dictionary<string, string>();
@ -43,6 +46,7 @@ namespace CppSharp @@ -43,6 +46,7 @@ namespace CppSharp
Project = new Project();
ASTContext = new ASTContext();
Symbols = new SymbolContext();
Delegates = new Dictionary<Function, DelegatesPass.DelegateDefinition>();
TypeDatabase = new TypeMapDatabase();
TranslationUnitPasses = new PassBuilder<TranslationUnitPass>(this);
GeneratorOutputPasses = new PassBuilder<GeneratorOutputPass>(this);
@ -429,7 +433,7 @@ namespace CppSharp @@ -429,7 +433,7 @@ namespace CppSharp
GeneratorOutputPasses.AddPass(pass);
}
private List<CodeSnippetCompileUnit> compileUnits = new List<CodeSnippetCompileUnit>();
private readonly List<CodeSnippetCompileUnit> compileUnits = new List<CodeSnippetCompileUnit>();
}
public static class ConsoleDriver

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

@ -1573,7 +1573,7 @@ namespace CppSharp.Generators.CSharp @@ -1573,7 +1573,7 @@ namespace CppSharp.Generators.CSharp
var vTableMethodDelegateName = GetVTableMethodDelegateName(method);
WriteLine("private static {0} {1}Instance;", DelegatesPass.Delegates[method].Visit(TypePrinter),
WriteLine("private static {0} {1}Instance;", GetDelegateName(Driver.Delegates[method]),
vTableMethodDelegateName);
NewLine();
@ -2355,7 +2355,7 @@ namespace CppSharp.Generators.CSharp @@ -2355,7 +2355,7 @@ namespace CppSharp.Generators.CSharp
}
}
public void GetVirtualCallDelegate(Method method, Class @class,
private void GetVirtualCallDelegate(Method method, Class @class,
out string delegateId)
{
var i = VTables.GetVTableIndex(method.OriginalFunction ?? method, @class);
@ -2371,7 +2371,17 @@ namespace CppSharp.Generators.CSharp @@ -2371,7 +2371,17 @@ namespace CppSharp.Generators.CSharp
delegateId = Generator.GeneratedIdentifier(@delegate);
WriteLine("var {0} = ({1}) Marshal.GetDelegateForFunctionPointer(new IntPtr({2}), typeof({1}));",
delegateId, DelegatesPass.Delegates[method].Visit(TypePrinter), Helpers.SlotIdentifier);
delegateId, GetDelegateName(Driver.Delegates[method]), Helpers.SlotIdentifier);
}
private string GetDelegateName(DelegatesPass.DelegateDefinition @delegate)
{
if (string.IsNullOrWhiteSpace(@delegate.Namespace) ||
Driver.Options.OutputNamespace == @delegate.Namespace)
{
return @delegate.Signature;
}
return string.Format("{0}.{1}", @delegate.Namespace, @delegate.Signature);
}
private void GenerateOperator(Method method)

72
src/Generator/Passes/DelegatesPass.cs

@ -4,6 +4,7 @@ using System.Text; @@ -4,6 +4,7 @@ using System.Text;
using CppSharp.AST;
using CppSharp.AST.Extensions;
using CppSharp.Generators.CSharp;
using System;
namespace CppSharp.Passes
{
@ -11,6 +12,19 @@ namespace CppSharp.Passes @@ -11,6 +12,19 @@ namespace CppSharp.Passes
{
public const string DelegatesNamespace = "Delegates";
public class DelegateDefinition
{
public DelegateDefinition(string @namespace, string signature)
{
Namespace = @namespace;
Signature = signature;
}
public string Namespace { get; private set; }
public string Signature { get; private set; }
}
public DelegatesPass()
{
Options.VisitClassBases = false;
@ -21,15 +35,10 @@ namespace CppSharp.Passes @@ -21,15 +35,10 @@ namespace CppSharp.Passes
Options.VisitTemplateArguments = false;
}
public static Dictionary<Function, TypedefDecl> Delegates
{
get { return delegates; }
}
public override bool VisitLibrary(ASTContext context)
{
foreach (var library in Driver.Options.Libraries.Where(l => !libsDelegates.ContainsKey(l)))
libsDelegates.Add(library, new Dictionary<string, TypedefDecl>());
libsDelegates.Add(library, new Dictionary<string, DelegateDefinition>());
var unit = context.TranslationUnits.Last(u => u.IsValid && u.IsGenerated &&
!u.IsSystemHeader && u.HasDeclarations);
@ -50,12 +59,6 @@ namespace CppSharp.Passes @@ -50,12 +59,6 @@ namespace CppSharp.Passes
var @params = method.GatherInternalParams(Driver.Options.IsItaniumLikeAbi, true).ToList();
var delegateName = GenerateDelegateSignature(@params, method.ReturnType);
var existingDelegate = GetExistingDelegate(delegateName);
if (existingDelegate != null)
{
delegates.Add(method, existingDelegate);
return true;
}
var @delegate = new TypedefDecl
{
@ -72,24 +75,35 @@ namespace CppSharp.Passes @@ -72,24 +75,35 @@ namespace CppSharp.Passes
}))),
Namespace = namespaceDelegates
};
delegates.Add(method, @delegate);
var delegateString = @delegate.Visit(TypePrinter).Type;
var existingDelegate = GetExistingDelegate(delegateString);
if (existingDelegate != null)
{
Driver.Delegates.Add(method, existingDelegate);
return true;
}
existingDelegate = new DelegateDefinition(Driver.Options.OutputNamespace, delegateString);
Driver.Delegates.Add(method, existingDelegate);
foreach (var library in Driver.Options.Libraries)
libsDelegates[library].Add(delegateName, @delegate);
libsDelegates[library].Add(delegateString, existingDelegate);
namespaceDelegates.Declarations.Add(@delegate);
return true;
}
private TypedefDecl GetExistingDelegate(string delegateName)
private DelegateDefinition GetExistingDelegate(string delegateString)
{
TypedefDecl @delegate = null;
if (Driver.Options.Libraries.Count == 0)
return @delegates.Values.FirstOrDefault(v => v.Name == delegateName);
return Driver.Delegates.Values.FirstOrDefault(t => t.Signature == delegateString);
if (Driver.Options.Libraries.Union(Driver.Symbols.Libraries.SelectMany(l => l.Dependencies)).Any(
l => libsDelegates.ContainsKey(l) && libsDelegates[l].TryGetValue(delegateName, out @delegate)))
DelegateDefinition @delegate = null;
if (Driver.Options.Libraries.Union(
Driver.Symbols.Libraries.SelectMany(l => l.Dependencies)).Any(
l => libsDelegates.ContainsKey(l) &&
libsDelegates[l].TryGetValue(delegateString, out @delegate)))
return @delegate;
return null;
@ -124,8 +138,22 @@ namespace CppSharp.Passes @@ -124,8 +138,22 @@ namespace CppSharp.Passes
return delegateName;
}
private CSharpTypePrinter TypePrinter
{
get
{
if (typePrinter == null)
{
typePrinter = new CSharpTypePrinter(Driver);
typePrinter.PushContext(CSharpTypePrinterContextKind.Native);
}
return typePrinter;
}
}
private Namespace namespaceDelegates;
private static readonly Dictionary<string, Dictionary<string, TypedefDecl>> libsDelegates = new Dictionary<string, Dictionary<string, TypedefDecl>>();
private static readonly Dictionary<Function, TypedefDecl> delegates = new Dictionary<Function, TypedefDecl>();
private CSharpTypePrinter typePrinter;
private static readonly Dictionary<string, Dictionary<string, DelegateDefinition>> libsDelegates =
new Dictionary<string, Dictionary<string, DelegateDefinition>>();
}
}

Loading…
Cancel
Save