-
Notifications
You must be signed in to change notification settings - Fork 53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ffigen] Migrate to ARC #1441
[ffigen] Migrate to ARC #1441
Conversation
PR HealthChangelog Entry ✔️
Changes to files need to be accounted for in their respective changelogs.
Coverage
|
File | Coverage |
---|---|
pkgs/ffigen/lib/src/code_generator/objc_block.dart | 💔 Not covered |
pkgs/ffigen/lib/src/code_generator/objc_built_in_functions.dart | 💔 Not covered |
pkgs/ffigen/lib/src/code_generator/objc_interface.dart | 💔 Not covered |
pkgs/ffigen/lib/src/code_generator/pointer.dart | 💔 Not covered |
pkgs/ffigen/lib/src/code_generator/writer.dart | 💔 Not covered |
pkgs/objective_c/lib/objective_c.dart | 💔 Not covered |
pkgs/objective_c/lib/src/c_bindings_generated.dart | 💔 Not covered |
pkgs/objective_c/lib/src/internal.dart | 💔 Not covered |
pkgs/objective_c/lib/src/objective_c_bindings_generated.dart | 💔 Not covered |
This check for test coverage is informational (issues shown here will not fail the PR).
This check can be disabled by tagging the PR with skip-coverage-check
.
License Headers ✔️
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
Files |
---|
no missing headers |
All source files should start with a license header.
Unrelated files missing license headers
Files |
---|
pkgs/ffigen/example/libclang-example/generated_bindings.dart |
pkgs/ffigen/example/shared_bindings/generate.dart |
pkgs/ffigen/example/shared_bindings/lib/generated/a_gen.dart |
pkgs/ffigen/example/shared_bindings/lib/generated/a_shared_b_gen.dart |
pkgs/ffigen/example/shared_bindings/lib/generated/base_gen.dart |
pkgs/ffigen/example/simple/generated_bindings.dart |
pkgs/ffigen/lib/src/header_parser/clang_bindings/clang_bindings.dart |
pkgs/ffigen/test/collision_tests/expected_bindings/_expected_decl_decl_collision_bindings.dart |
pkgs/ffigen/test/collision_tests/expected_bindings/_expected_decl_symbol_address_collision_bindings.dart |
pkgs/ffigen/test/collision_tests/expected_bindings/_expected_decl_type_name_collision_bindings.dart |
pkgs/ffigen/test/collision_tests/expected_bindings/_expected_reserved_keyword_collision_bindings.dart |
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_comment_markup_bindings.dart |
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_dart_handle_bindings.dart |
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_enum_int_mimic_bindings.dart |
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_forward_decl_bindings.dart |
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_functions_bindings.dart |
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_imported_types_bindings.dart |
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_native_func_typedef_bindings.dart |
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_opaque_dependencies_bindings.dart |
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_packed_structs_bindings.dart |
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_regress_384_bindings.dart |
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_struct_fptr_fields_bindings.dart |
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_typedef_bindings.dart |
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_unions_bindings.dart |
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_varargs_bindings.dart |
pkgs/ffigen/test/large_integration_tests/_expected_cjson_bindings.dart |
pkgs/ffigen/test/large_integration_tests/_expected_libclang_bindings.dart |
pkgs/ffigen/test/large_integration_tests/_expected_sqlite_bindings.dart |
pkgs/ffigen/test/native_test/_expected_native_test_bindings.dart |
pkgs/jni/lib/src/lang/jcharacter.dart |
pkgs/jni/lib/src/third_party/generated_bindings.dart |
pkgs/jni/lib/src/third_party/global_env_extensions.dart |
pkgs/jni/lib/src/third_party/jni_bindings_generated.dart |
pkgs/jnigen/android_test_runner/lib/main.dart |
pkgs/jnigen/example/in_app_java/lib/android_utils.dart |
pkgs/jnigen/example/kotlin_plugin/example/lib/main.dart |
pkgs/jnigen/example/kotlin_plugin/lib/kotlin_bindings.dart |
pkgs/jnigen/example/kotlin_plugin/lib/kotlin_plugin.dart |
pkgs/jnigen/example/pdfbox_plugin/lib/pdfbox_plugin.dart |
pkgs/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/pdmodel/PDDocument.dart |
pkgs/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/pdmodel/PDDocumentInformation.dart |
pkgs/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/pdmodel/_package.dart |
pkgs/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/text/PDFTextStripper.dart |
pkgs/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/text/_package.dart |
pkgs/jnigen/lib/src/bindings/descriptor.dart |
pkgs/jnigen/lib/src/elements/elements.g.dart |
pkgs/jnigen/test/jackson_core_test/third_party/bindings/com/fasterxml/jackson/core/_package.dart |
pkgs/jnigen/tool/command_runner.dart |
pkgs/swift2objc/lib/src/config.dart |
pkgs/swift2objc/lib/src/generate_wrapper.dart |
pkgs/swift2objc/lib/src/generator/_core/utils.dart |
pkgs/swift2objc/lib/src/generator/generator.dart |
pkgs/swift2objc/lib/src/generator/generators/class_generator.dart |
pkgs/swift2objc/lib/src/parser/parsers/declaration_parsers/parse_property_declaration.dart |
pkgs/swift2objc/lib/src/transformer/_core/unique_namer.dart |
pkgs/swift2objc/lib/src/transformer/_core/utils.dart |
pkgs/swift2objc/lib/src/transformer/transformers/transform_property.dart |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, instead of releasing the reference to the incoming block in here, we're doing it in Dart land instead.
What is the effect of this?
- Added a github workflow that verifies that the package:objective_c example builds, to make sure the podspecs are correct (the tests build the package test/setup.dart, so the flutter build path was untested).
Probably leave a TODO there for switching to native assets, as then we don't use podspecs anymore.
Do we end up in kind of a half-state here? E.g. we don't support non ARC anymore, but for ARC we ignore a bunch of things which would lead to memory errors. Should #1446 be folded in to this PR? Or is the current PR usable? If so in what cases? And how do users know?
(Side note: Should we have some way of specifying in our workflow that something should be addressed before the next version is released? Maybe we need a release-blocker issue label? Or, is the tracker of when we want to release the next version enough? As long as you're the person mostly working on FFIgen, I guess it's fine to leave FFIgen in a unpublishable state on the main branch, but it does prevent us from addressing other bugs and doing a release in the meantime.)
The code changes in this PR, LGTM.
So, LGTM once above question is answered.
pkgs/objective_c/CHANGELOG.md
Outdated
@@ -3,6 +3,7 @@ | |||
- Drop API methods that are deprecated in the oldest versions of iOS and macOS | |||
that flutter supports. | |||
- Added `ObjCBlock`, which is the new user-facing representation of ObjC blocks. | |||
- Migrate to ARC. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe spell out the acronym in case a layman comes along.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -0,0 +1,22 @@ | |||
PODS: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is committing this intentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed
Somehow after generating code I got one wrapper function that was still using the #include <stdint.h>
#import <CoreMIDI/CoreMIDI.h>
#import <CloudKit/CloudKit.h>
#import <CoreFoundation/CoreFoundation.h>
#import <AVFoundation/AVFoundation.h>
#import <AVFoundation/AVAssetExportSession.h>
#import <AVFoundation/AVAssetTrackSegment.h>
#import <AVFoundation/AVAssetImageGenerator.h>
#import <AVFoundation/AVMediaFormat.h>
#import <AVFoundation/AVVideoComposition.h>
#import <CoreGraphics/CGBase.h>
#import <CoreGraphics/CGGeometry.h>
#import <CoreGraphics/CGImage.h>
#import <CoreMedia/CMBase.h>
#import <CoreMedia/CMTime.h>
#import <CoreMedia/CMTimeRange.h>
#import <QuartzCore/CADisplayLink.h>
#if !__has_feature(objc_arc)
#error "This file must be compiled with ARC enabled"
#endif
id objc_retain(id);
id objc_retainBlock(id);
typedef void (^ListenerBlock)(NSDictionary* , struct _NSRange , BOOL * );
ListenerBlock wrapListenerBlock_ObjCBlock_ffiVoid_NSDictionary_NSRange_bool(ListenerBlock block) NS_RETURNS_RETAINED {
return ^void(NSDictionary* arg0, struct _NSRange arg1, BOOL * arg2) {
block(objc_retain(arg0), arg1, arg2);
};
}
//
// The block below has the issue
//
typedef void (^ListenerBlock1)(id , struct _NSRange , BOOL * );
ListenerBlock1 wrapListenerBlock_ObjCBlock_ffiVoid_objcObjCObject_NSRange_bool(ListenerBlock1 block) NS_RETURNS_RETAINED {
return ^void(id arg0, struct _NSRange arg1, BOOL * arg2) {
block([arg0 retain], arg1, arg2); // <--- here
};
}
typedef void (^ListenerBlock2)(NSDate* , BOOL , BOOL * );
ListenerBlock2 wrapListenerBlock_ObjCBlock_ffiVoid_NSDate_bool_bool(ListenerBlock2 block) NS_RETURNS_RETAINED {
return ^void(NSDate* arg0, BOOL arg1, BOOL * arg2) {
block(objc_retain(arg0), arg1, arg2);
};
}
// bunch more below, but everything is fine there Not sure which interface led to the generation of this. If needed, I can share |
Oops. Good catch. Forgot about |
It doesn't make a functional difference, but it means one less ARC hack in the ObjC bindings.
Done.
This isn't a regression. The migration to ARC just made some existing bugs more obvious. The way we're not quite handling method families correctly is a very obscure issue that users will probably never actually hit. The bigger issue is the way we are assuming all blocks that return ref countable objects are
I've been using milestones. Eg, #1446 is in the ffigen 14.0.0 milestone. |
Migrate package:objective_c, ffigen's generated block trampolines, and all the objective_c tests to ARC.
The generated block trampolines have changed from
to
We have to retain the args using
objc_retain
/objc_retainBlock
instead of sending a retain message. Also, instead of explicitly copying the wrapper block, we can just add aNS_RETURNS_RETAINED
annotation and rely on ARC to copy it for us. Also, instead of releasing the reference to the incoming block in here, we're doing it in Dart land instead.Other changes:
_Block_copy
toobjc_retainBlock
, which is more stable. Also switched from releasing blocks using_Block_release
to the ordinaryobjc_release
used for all objects.Fixes #1421
Follow up work: #1446