[ffigen] Pointer.fromFunction leaks, so store result in static variable (#459)
diff --git a/pkgs/ffigen/lib/src/code_generator/objc_block.dart b/pkgs/ffigen/lib/src/code_generator/objc_block.dart index 73f5a31..310fef1 100644 --- a/pkgs/ffigen/lib/src/code_generator/objc_block.dart +++ b/pkgs/ffigen/lib/src/code_generator/objc_block.dart
@@ -109,16 +109,18 @@ /// Creates a block from a C function pointer. $name.fromFunctionPointer(${w.className} lib, $natFnPtr ptr) : this._(lib.${builtInFunctions.newBlock.name}( - ${w.ffiLibraryPrefix}.Pointer.fromFunction< + _cFuncTrampoline ??= ${w.ffiLibraryPrefix}.Pointer.fromFunction< ${trampFuncType.getCType(w)}>($funcPtrTrampoline $exceptionalReturn).cast(), ptr.cast()), lib); + static $voidPtr? _cFuncTrampoline; /// Creates a block from a Dart function. $name.fromFunction(${w.className} lib, ${funcType.getDartType(w)} fn) : this._(lib.${builtInFunctions.newBlock.name}( - ${w.ffiLibraryPrefix}.Pointer.fromFunction< + _dartFuncTrampoline ??= ${w.ffiLibraryPrefix}.Pointer.fromFunction< ${trampFuncType.getCType(w)}>($closureTrampoline $exceptionalReturn).cast(), $registerClosure(fn)), lib); + static $voidPtr? _dartFuncTrampoline; '''); // Call method.
diff --git a/pkgs/ffigen/lib/src/header_parser/sub_parsers/compounddecl_parser.dart b/pkgs/ffigen/lib/src/header_parser/sub_parsers/compounddecl_parser.dart index 49e2418..9e284b2 100644 --- a/pkgs/ffigen/lib/src/header_parser/sub_parsers/compounddecl_parser.dart +++ b/pkgs/ffigen/lib/src/header_parser/sub_parsers/compounddecl_parser.dart
@@ -16,6 +16,12 @@ final _logger = Logger('ffigen.header_parser.compounddecl_parser'); +Pointer< + NativeFunction< + Int32 Function( + clang_types.CXCursor, clang_types.CXCursor, Pointer<Void>)>>? + _compoundMembersVisitorPtr; + /// Holds temporary information regarding [compound] while parsing. class _ParsedCompound { Compound compound; @@ -179,7 +185,8 @@ _stack.push(parsed); final resultCode = clang.clang_visitChildren( cursor, - Pointer.fromFunction(_compoundMembersVisitor, exceptional_visitor_return), + _compoundMembersVisitorPtr ??= Pointer.fromFunction( + _compoundMembersVisitor, exceptional_visitor_return), nullptr, ); _stack.pop();
diff --git a/pkgs/ffigen/lib/src/header_parser/sub_parsers/enumdecl_parser.dart b/pkgs/ffigen/lib/src/header_parser/sub_parsers/enumdecl_parser.dart index 7eb65a8..1353f2d 100644 --- a/pkgs/ffigen/lib/src/header_parser/sub_parsers/enumdecl_parser.dart +++ b/pkgs/ffigen/lib/src/header_parser/sub_parsers/enumdecl_parser.dart
@@ -15,6 +15,12 @@ final _logger = Logger('ffigen.header_parser.enumdecl_parser'); +Pointer< + NativeFunction< + Int32 Function( + clang_types.CXCursor, clang_types.CXCursor, Pointer<Void>)>>? + _enumCursorVisitorPtr; + /// Holds temporary information regarding [EnumClass] while parsing. class _ParsedEnum { EnumClass? enumClass; @@ -70,7 +76,8 @@ void _addEnumConstant(clang_types.CXCursor cursor) { final resultCode = clang.clang_visitChildren( cursor, - Pointer.fromFunction(_enumCursorVisitor, exceptional_visitor_return), + _enumCursorVisitorPtr ??= + Pointer.fromFunction(_enumCursorVisitor, exceptional_visitor_return), nullptr, );
diff --git a/pkgs/ffigen/lib/src/header_parser/sub_parsers/macro_parser.dart b/pkgs/ffigen/lib/src/header_parser/sub_parsers/macro_parser.dart index 753a4b5..cb5fbdb 100644 --- a/pkgs/ffigen/lib/src/header_parser/sub_parsers/macro_parser.dart +++ b/pkgs/ffigen/lib/src/header_parser/sub_parsers/macro_parser.dart
@@ -19,6 +19,12 @@ final _logger = Logger('ffigen.header_parser.macro_parser'); +Pointer< + NativeFunction< + Int32 Function( + clang_types.CXCursor, clang_types.CXCursor, Pointer<Void>)>>? + _macroVariablevisitorPtr; + /// Adds a macro definition to be parsed later. void saveMacroDefinition(clang_types.CXCursor cursor) { final macroUsr = cursor.usr(); @@ -79,7 +85,8 @@ final resultCode = clang.clang_visitChildren( rootCursor, - Pointer.fromFunction(_macroVariablevisitor, exceptional_visitor_return), + _macroVariablevisitorPtr ??= Pointer.fromFunction( + _macroVariablevisitor, exceptional_visitor_return), nullptr, );
diff --git a/pkgs/ffigen/lib/src/header_parser/sub_parsers/objcinterfacedecl_parser.dart b/pkgs/ffigen/lib/src/header_parser/sub_parsers/objcinterfacedecl_parser.dart index bace1c4..16cec51 100644 --- a/pkgs/ffigen/lib/src/header_parser/sub_parsers/objcinterfacedecl_parser.dart +++ b/pkgs/ffigen/lib/src/header_parser/sub_parsers/objcinterfacedecl_parser.dart
@@ -14,6 +14,27 @@ final _logger = Logger('ffigen.header_parser.objcinterfacedecl_parser'); +Pointer< + NativeFunction< + Int32 Function( + clang_types.CXCursor, clang_types.CXCursor, Pointer<Void>)>>? + _parseInterfaceVisitorPtr; +Pointer< + NativeFunction< + Int32 Function( + clang_types.CXCursor, clang_types.CXCursor, Pointer<Void>)>>? + _isClassDeclarationVisitorPtr; +Pointer< + NativeFunction< + Int32 Function( + clang_types.CXCursor, clang_types.CXCursor, Pointer<Void>)>>? + _parseMethodVisitorPtr; +Pointer< + NativeFunction< + Int32 Function( + clang_types.CXCursor, clang_types.CXCursor, Pointer<Void>)>>? + _findCategoryInterfaceVisitorPtr; + class _ParsedObjCInterface { ObjCInterface interface; _ParsedObjCInterface(this.interface); @@ -75,7 +96,8 @@ _interfaceStack.push(_ParsedObjCInterface(itf)); clang.clang_visitChildren( cursor, - Pointer.fromFunction(_parseInterfaceVisitor, exceptional_visitor_return), + _parseInterfaceVisitorPtr ??= Pointer.fromFunction( + _parseInterfaceVisitor, exceptional_visitor_return), nullptr); _interfaceStack.pop(); @@ -89,7 +111,7 @@ _isClassDeclarationResult = true; clang.clang_visitChildren( cursor, - Pointer.fromFunction( + _isClassDeclarationVisitorPtr ??= Pointer.fromFunction( _isClassDeclarationVisitor, exceptional_visitor_return), nullptr); return _isClassDeclarationResult; @@ -218,7 +240,8 @@ _methodStack.push(parsed); clang.clang_visitChildren( cursor, - Pointer.fromFunction(_parseMethodVisitor, exceptional_visitor_return), + _parseMethodVisitorPtr ??= + Pointer.fromFunction(_parseMethodVisitor, exceptional_visitor_return), nullptr); _methodStack.pop(); if (parsed.hasError) { @@ -292,7 +315,7 @@ _findCategoryInterfaceVisitorResult = null; clang.clang_visitChildren( cursor, - Pointer.fromFunction( + _findCategoryInterfaceVisitorPtr ??= Pointer.fromFunction( _findCategoryInterfaceVisitor, exceptional_visitor_return), nullptr); final itfCursor = _findCategoryInterfaceVisitorResult; @@ -312,7 +335,8 @@ _interfaceStack.push(_ParsedObjCInterface(itf)); clang.clang_visitChildren( cursor, - Pointer.fromFunction(_parseInterfaceVisitor, exceptional_visitor_return), + _parseInterfaceVisitorPtr ??= Pointer.fromFunction( + _parseInterfaceVisitor, exceptional_visitor_return), nullptr); _interfaceStack.pop();
diff --git a/pkgs/ffigen/lib/src/header_parser/sub_parsers/unnamed_enumdecl_parser.dart b/pkgs/ffigen/lib/src/header_parser/sub_parsers/unnamed_enumdecl_parser.dart index 81c0a77..879dfea 100644 --- a/pkgs/ffigen/lib/src/header_parser/sub_parsers/unnamed_enumdecl_parser.dart +++ b/pkgs/ffigen/lib/src/header_parser/sub_parsers/unnamed_enumdecl_parser.dart
@@ -14,11 +14,18 @@ final _logger = Logger('ffigen.header_parser.unnamed_enumdecl_parser'); +Pointer< + NativeFunction< + Int32 Function( + clang_types.CXCursor, clang_types.CXCursor, Pointer<Void>)>>? + _unnamedenumCursorVisitorPtr; + /// Saves unnamed enums. void saveUnNamedEnum(clang_types.CXCursor cursor) { final resultCode = clang.clang_visitChildren( cursor, - Pointer.fromFunction(_unnamedenumCursorVisitor, exceptional_visitor_return), + _unnamedenumCursorVisitorPtr ??= Pointer.fromFunction( + _unnamedenumCursorVisitor, exceptional_visitor_return), nullptr, );
diff --git a/pkgs/ffigen/lib/src/header_parser/translation_unit_parser.dart b/pkgs/ffigen/lib/src/header_parser/translation_unit_parser.dart index 7831ae8..b34b1b1 100644 --- a/pkgs/ffigen/lib/src/header_parser/translation_unit_parser.dart +++ b/pkgs/ffigen/lib/src/header_parser/translation_unit_parser.dart
@@ -21,12 +21,19 @@ late Set<Binding> _bindings; +Pointer< + NativeFunction< + Int32 Function( + clang_types.CXCursor, clang_types.CXCursor, Pointer<Void>)>>? + _rootCursorVisitorPtr; + /// Parses the translation unit and returns the generated bindings. Set<Binding> parseTranslationUnit(clang_types.CXCursor translationUnitCursor) { _bindings = {}; final resultCode = clang.clang_visitChildren( translationUnitCursor, - Pointer.fromFunction(_rootCursorVisitor, exceptional_visitor_return), + _rootCursorVisitorPtr ??= + Pointer.fromFunction(_rootCursorVisitor, exceptional_visitor_return), nullptr, );
diff --git a/pkgs/ffigen/lib/src/header_parser/utils.dart b/pkgs/ffigen/lib/src/header_parser/utils.dart index 7352642..5f9bd33 100644 --- a/pkgs/ffigen/lib/src/header_parser/utils.dart +++ b/pkgs/ffigen/lib/src/header_parser/utils.dart
@@ -127,6 +127,11 @@ } } +Pointer< + NativeFunction< + Int32 Function( + clang_types.CXCursor, clang_types.CXCursor, Pointer<Void>)>>? + _printAstVisitorPtr; int _printAstVisitorMaxDepth = 0; int _printAstVisitor(clang_types.CXCursor cursor, clang_types.CXCursor parent, Pointer<Void> clientData) { @@ -137,7 +142,8 @@ print((' ' * depth) + cursor.completeStringRepr()); clang.clang_visitChildren( cursor, - Pointer.fromFunction(_printAstVisitor, exceptional_visitor_return), + _printAstVisitorPtr ??= + Pointer.fromFunction(_printAstVisitor, exceptional_visitor_return), Pointer<Void>.fromAddress(depth + 1)); return clang_types.CXChildVisitResult.CXChildVisit_Continue; }