[ffigen] Merge pull request #610 from dart-lang/roll-stable-to-9.0.1

Roll stable to 9.0.1
diff --git a/pkgs/ffigen/.github/workflows/test-package.yml b/pkgs/ffigen/.github/workflows/test-package.yml
index 9ee11ac..75f4585 100644
--- a/pkgs/ffigen/.github/workflows/test-package.yml
+++ b/pkgs/ffigen/.github/workflows/test-package.yml
@@ -19,9 +19,10 @@
     strategy:
       fail-fast: false
       matrix:
-        sdk: [3.0.0]
+        # TODO: Change to 3.2.0 stable once it's released.
+        sdk: [3.2.0-114.0.dev]
     steps:
-      - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
+      - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744
       - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
         with:
           sdk: ${{ matrix.sdk }}
@@ -41,10 +42,10 @@
     needs: analyze
     runs-on: ubuntu-22.04
     steps:
-      - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
+      - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744
       - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
         with:
-          sdk: 3.0.0
+          sdk: 3.2.0-114.0.dev
       - name: Install dependencies
         run: dart pub get
       - name: Install libclang-14-dev
@@ -58,10 +59,10 @@
     needs: analyze
     runs-on: macos-latest
     steps:
-      - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
+      - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744
       - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
         with:
-          sdk: 3.0.0
+          sdk: 3.2.0-114.0.dev
       - name: Install dependencies
         run: dart pub get
       - name: Build test dylib and bindings
@@ -71,7 +72,7 @@
       - name: Collect coverage
         run: ./tool/coverage.sh
       - name: Upload coverage
-        uses: coverallsapp/github-action@c7885c00cb7ec0b8f9f5ff3f53cddb980f7a4412
+        uses: coverallsapp/github-action@95b1a2355bd0e526ad2fd62da9fd386ad4c98474
         with:
           github-token: ${{ secrets.GITHUB_TOKEN }}
           path-to-lcov: lcov.info
@@ -80,10 +81,10 @@
     needs: analyze
     runs-on: windows-latest
     steps:
-      - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
+      - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744
       - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
         with:
-          sdk: 3.0.0
+          sdk: 3.2.0-114.0.dev
       - name: Install dependencies
         run: dart pub get
       - name: Build test dylib and bindings
@@ -105,7 +106,7 @@
     needs: analyze
     runs-on: windows-latest
     steps:
-      - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
+      - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744
       - uses: subosito/flutter-action@48cafc24713cca54bbe03cdc3a423187d413aafa
         with:
           channel: "master"
diff --git a/pkgs/ffigen/CHANGELOG.md b/pkgs/ffigen/CHANGELOG.md
index b4bdf28..7036a8c 100644
--- a/pkgs/ffigen/CHANGELOG.md
+++ b/pkgs/ffigen/CHANGELOG.md
@@ -1,3 +1,9 @@
+# 10.0.0-dev.0
+
+- Add support for ObjC Blocks that can be invoked from any thread, using
+  NativeCallable.listener.
+- Bump min SDK version to 3.2.0-114.0.dev.
+
 # 9.0.1
 
 - Fix doc comment missing on struct/union array fields.
diff --git a/pkgs/ffigen/README.md b/pkgs/ffigen/README.md
index 38c66e5..61464fd 100644
--- a/pkgs/ffigen/README.md
+++ b/pkgs/ffigen/README.md
@@ -76,7 +76,8 @@
 
 #### MacOS
 1. Install Xcode.
-2. Install LLVM - `brew install llvm`.
+2. Install Xcode command line tools - `xcode-select --install`.
+3. Install LLVM - `brew install llvm`.
 
 ## Configurations
 Configurations can be provided in 2 ways-
diff --git a/pkgs/ffigen/example/c_json/cjson_generated_bindings.dart b/pkgs/ffigen/example/c_json/cjson_generated_bindings.dart
index 0fb9e1a..fa9e56e 100644
--- a/pkgs/ffigen/example/c_json/cjson_generated_bindings.dart
+++ b/pkgs/ffigen/example/c_json/cjson_generated_bindings.dart
@@ -73,8 +73,9 @@
   }
 
   late final _cJSON_ParsePtr = _lookup<
-      ffi.NativeFunction<
-          ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>>('cJSON_Parse');
+          ffi
+          .NativeFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>>(
+      'cJSON_Parse');
   late final _cJSON_Parse = _cJSON_ParsePtr
       .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>();
 
@@ -109,8 +110,9 @@
   }
 
   late final _cJSON_PrintPtr = _lookup<
-      ffi.NativeFunction<
-          ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>)>>('cJSON_Print');
+          ffi
+          .NativeFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>)>>(
+      'cJSON_Print');
   late final _cJSON_Print = _cJSON_PrintPtr
       .asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>)>();
 
@@ -123,9 +125,9 @@
   }
 
   late final _cJSON_PrintUnformattedPtr = _lookup<
-      ffi.NativeFunction<
-          ffi.Pointer<ffi.Char> Function(
-              ffi.Pointer<cJSON>)>>('cJSON_PrintUnformatted');
+          ffi
+          .NativeFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>)>>(
+      'cJSON_PrintUnformatted');
   late final _cJSON_PrintUnformatted = _cJSON_PrintUnformattedPtr
       .asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>)>();
 
@@ -286,9 +288,9 @@
   }
 
   late final _cJSON_GetStringValuePtr = _lookup<
-      ffi.NativeFunction<
-          ffi.Pointer<ffi.Char> Function(
-              ffi.Pointer<cJSON>)>>('cJSON_GetStringValue');
+          ffi
+          .NativeFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>)>>(
+      'cJSON_GetStringValue');
   late final _cJSON_GetStringValue = _cJSON_GetStringValuePtr
       .asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>)>();
 
@@ -499,9 +501,9 @@
   }
 
   late final _cJSON_CreateStringPtr = _lookup<
-      ffi.NativeFunction<
-          ffi.Pointer<cJSON> Function(
-              ffi.Pointer<ffi.Char>)>>('cJSON_CreateString');
+          ffi
+          .NativeFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>>(
+      'cJSON_CreateString');
   late final _cJSON_CreateString = _cJSON_CreateStringPtr
       .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>();
 
@@ -514,9 +516,9 @@
   }
 
   late final _cJSON_CreateRawPtr = _lookup<
-      ffi.NativeFunction<
-          ffi.Pointer<cJSON> Function(
-              ffi.Pointer<ffi.Char>)>>('cJSON_CreateRaw');
+          ffi
+          .NativeFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>>(
+      'cJSON_CreateRaw');
   late final _cJSON_CreateRaw = _cJSON_CreateRawPtr
       .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>();
 
@@ -549,9 +551,9 @@
   }
 
   late final _cJSON_CreateStringReferencePtr = _lookup<
-      ffi.NativeFunction<
-          ffi.Pointer<cJSON> Function(
-              ffi.Pointer<ffi.Char>)>>('cJSON_CreateStringReference');
+          ffi
+          .NativeFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>>(
+      'cJSON_CreateStringReference');
   late final _cJSON_CreateStringReference = _cJSON_CreateStringReferencePtr
       .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>();
 
@@ -1199,9 +1201,9 @@
   }
 
   late final _cJSON_SetNumberHelperPtr = _lookup<
-      ffi.NativeFunction<
-          ffi.Double Function(
-              ffi.Pointer<cJSON>, ffi.Double)>>('cJSON_SetNumberHelper');
+          ffi
+          .NativeFunction<ffi.Double Function(ffi.Pointer<cJSON>, ffi.Double)>>(
+      'cJSON_SetNumberHelper');
   late final _cJSON_SetNumberHelper = _cJSON_SetNumberHelperPtr
       .asFunction<double Function(ffi.Pointer<cJSON>, double)>();
 
@@ -1256,12 +1258,13 @@
 }
 
 final class cJSON_Hooks extends ffi.Struct {
-  external ffi.Pointer<
-          ffi.NativeFunction<ffi.Pointer<ffi.Void> Function(ffi.Size sz)>>
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function(ffi.Size sz)>>
       malloc_fn;
 
-  external ffi.Pointer<
-      ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void> ptr)>> free_fn;
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void> ptr)>>
+      free_fn;
 }
 
 typedef cJSON_bool = ffi.Int;
diff --git a/pkgs/ffigen/example/c_json/pubspec.yaml b/pkgs/ffigen/example/c_json/pubspec.yaml
index 3301013..c1277a8 100644
--- a/pkgs/ffigen/example/c_json/pubspec.yaml
+++ b/pkgs/ffigen/example/c_json/pubspec.yaml
@@ -5,7 +5,7 @@
 name: c_json_example
 
 environment:
-  sdk: ">=3.0.0 <4.0.0"
+  sdk: ">=3.2.0-114.0.dev <4.0.0"
 
 dependencies:
   ffi: ^2.0.1
diff --git a/pkgs/ffigen/example/ffinative/pubspec.yaml b/pkgs/ffigen/example/ffinative/pubspec.yaml
index ef452f8..7be76fc 100644
--- a/pkgs/ffigen/example/ffinative/pubspec.yaml
+++ b/pkgs/ffigen/example/ffinative/pubspec.yaml
@@ -5,7 +5,7 @@
 name: ffinative_example
 
 environment:
-  sdk: ">=3.0.0 <4.0.0"
+  sdk: ">=3.2.0-114.0.dev <4.0.0"
 
 dependencies:
   ffi: ^2.0.1
diff --git a/pkgs/ffigen/example/libclang-example/generated_bindings.dart b/pkgs/ffigen/example/libclang-example/generated_bindings.dart
index 64de33c..fe7f3c4 100644
--- a/pkgs/ffigen/example/libclang-example/generated_bindings.dart
+++ b/pkgs/ffigen/example/libclang-example/generated_bindings.dart
@@ -205,8 +205,8 @@
   }
 
   late final _clang_CXIndex_setInvocationEmissionPathOptionPtr = _lookup<
-          ffi.NativeFunction<
-              NativeClang_CXIndex_setInvocationEmissionPathOption>>(
+          ffi
+          .NativeFunction<NativeClang_CXIndex_setInvocationEmissionPathOption>>(
       'clang_CXIndex_setInvocationEmissionPathOption');
   late final _clang_CXIndex_setInvocationEmissionPathOption =
       _clang_CXIndex_setInvocationEmissionPathOptionPtr
@@ -2938,8 +2938,8 @@
   }
 
   late final _clang_Cursor_getTemplateArgumentUnsignedValuePtr = _lookup<
-          ffi.NativeFunction<
-              NativeClang_Cursor_getTemplateArgumentUnsignedValue>>(
+          ffi
+          .NativeFunction<NativeClang_Cursor_getTemplateArgumentUnsignedValue>>(
       'clang_Cursor_getTemplateArgumentUnsignedValue');
   late final _clang_Cursor_getTemplateArgumentUnsignedValue =
       _clang_Cursor_getTemplateArgumentUnsignedValuePtr
@@ -4849,8 +4849,8 @@
   }
 
   late final _clang_CXXConstructor_isConvertingConstructorPtr = _lookup<
-          ffi.NativeFunction<
-              NativeClang_CXXConstructor_isConvertingConstructor>>(
+          ffi
+          .NativeFunction<NativeClang_CXXConstructor_isConvertingConstructor>>(
       'clang_CXXConstructor_isConvertingConstructor');
   late final _clang_CXXConstructor_isConvertingConstructor =
       _clang_CXXConstructor_isConvertingConstructorPtr
@@ -6850,8 +6850,8 @@
       get clang_CXIndex_getGlobalOptions =>
           _library._clang_CXIndex_getGlobalOptionsPtr;
   ffi.Pointer<
-          ffi.NativeFunction<
-              NativeClang_CXIndex_setInvocationEmissionPathOption>>
+          ffi
+          .NativeFunction<NativeClang_CXIndex_setInvocationEmissionPathOption>>
       get clang_CXIndex_setInvocationEmissionPathOption =>
           _library._clang_CXIndex_setInvocationEmissionPathOptionPtr;
   ffi.Pointer<ffi.NativeFunction<NativeClang_getFileName>>
@@ -7148,8 +7148,8 @@
       get clang_Cursor_getTemplateArgumentValue =>
           _library._clang_Cursor_getTemplateArgumentValuePtr;
   ffi.Pointer<
-          ffi.NativeFunction<
-              NativeClang_Cursor_getTemplateArgumentUnsignedValue>>
+          ffi
+          .NativeFunction<NativeClang_Cursor_getTemplateArgumentUnsignedValue>>
       get clang_Cursor_getTemplateArgumentUnsignedValue =>
           _library._clang_Cursor_getTemplateArgumentUnsignedValuePtr;
   ffi.Pointer<ffi.NativeFunction<NativeClang_equalTypes>>
@@ -7406,8 +7406,8 @@
       get clang_Module_getTopLevelHeader =>
           _library._clang_Module_getTopLevelHeaderPtr;
   ffi.Pointer<
-          ffi.NativeFunction<
-              NativeClang_CXXConstructor_isConvertingConstructor>>
+          ffi
+          .NativeFunction<NativeClang_CXXConstructor_isConvertingConstructor>>
       get clang_CXXConstructor_isConvertingConstructor =>
           _library._clang_CXXConstructor_isConvertingConstructorPtr;
   ffi.Pointer<ffi.NativeFunction<NativeClang_CXXConstructor_isCopyConstructor>>
@@ -11104,8 +11104,8 @@
 /// The visitor should return one of the \c CXVisitorResult values
 /// to direct \c clang_Type_visitFields.
 typedef CXFieldVisitor = ffi.Pointer<
-    ffi.NativeFunction<
-        ffi.Int32 Function(CXCursor C, CXClientData client_data)>>;
+    ffi
+    .NativeFunction<ffi.Int32 Function(CXCursor C, CXClientData client_data)>>;
 typedef NativeClang_Type_visitFields = ffi.UnsignedInt Function(
     CXType T, CXFieldVisitor visitor, CXClientData client_data);
 typedef DartClang_Type_visitFields = int Function(
diff --git a/pkgs/ffigen/example/libclang-example/pubspec.yaml b/pkgs/ffigen/example/libclang-example/pubspec.yaml
index 9d7e8ab..a8ecc54 100644
--- a/pkgs/ffigen/example/libclang-example/pubspec.yaml
+++ b/pkgs/ffigen/example/libclang-example/pubspec.yaml
@@ -5,7 +5,7 @@
 name: libclang_example
 
 environment:
-  sdk: ">=3.0.0 <4.0.0"
+  sdk: ">=3.2.0-114.0.dev <4.0.0"
 
 dependencies:
   ffi: ^2.0.1
diff --git a/pkgs/ffigen/example/objective_c/avf_audio_bindings.dart b/pkgs/ffigen/example/objective_c/avf_audio_bindings.dart
index ae0d3fd..eaa669d 100644
--- a/pkgs/ffigen/example/objective_c/avf_audio_bindings.dart
+++ b/pkgs/ffigen/example/objective_c/avf_audio_bindings.dart
@@ -22381,8 +22381,8 @@
           ffi.Pointer<ObjCObject>,
           ffi.Pointer<ObjCSel>,
           ffi.Pointer<
-              ffi.NativeFunction<
-                  NSUInteger Function(ffi.Pointer<ffi.Void>)>>)>();
+              ffi
+              .NativeFunction<NSUInteger Function(ffi.Pointer<ffi.Void>)>>)>();
 
   late final _sel_descriptionFunction1 = _registerName1("descriptionFunction");
   ffi.Pointer<
@@ -22541,8 +22541,8 @@
           ffi.Pointer<ffi.Void> Function(
               ffi.Pointer<ffi.Void>,
               ffi.Pointer<
-                  ffi.NativeFunction<
-                      NSUInteger Function(ffi.Pointer<ffi.Void>)>>,
+                  ffi
+                  .NativeFunction<NSUInteger Function(ffi.Pointer<ffi.Void>)>>,
               ffi.Bool)>> _objc_msgSend_803(
     ffi.Pointer<ObjCObject> obj,
     ffi.Pointer<ObjCSel> sel,
@@ -22553,20 +22553,20 @@
     );
   }
 
-  late final __objc_msgSend_803Ptr =
-      _lookup<
-              ffi.NativeFunction<
-                  ffi.Pointer<
-                          ffi.NativeFunction<
-                              ffi.Pointer<ffi.Void> Function(
-                                  ffi.Pointer<ffi.Void>,
-                                  ffi.Pointer<
+  late final __objc_msgSend_803Ptr = _lookup<
+          ffi.NativeFunction<
+              ffi.Pointer<
+                      ffi.NativeFunction<
+                          ffi.Pointer<ffi.Void> Function(
+                              ffi.Pointer<ffi.Void>,
+                              ffi
+                                  .Pointer<
                                       ffi.NativeFunction<
                                           NSUInteger Function(
                                               ffi.Pointer<ffi.Void>)>>,
-                                  ffi.Bool)>>
-                      Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>(
-          'objc_msgSend');
+                              ffi.Bool)>>
+                  Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>(
+      'objc_msgSend');
   late final __objc_msgSend_803 = __objc_msgSend_803Ptr.asFunction<
       ffi.Pointer<
               ffi.NativeFunction<
@@ -36092,16 +36092,17 @@
                       NSUInteger arg1, ffi.Pointer<ffi.Bool> arg2)>>
           ptr)
       : this._(
-            lib._newBlock1(
-                ffi.Pointer.fromFunction<
-                            ffi.Bool Function(
-                                ffi.Pointer<_ObjCBlock> block,
-                                ffi.Pointer<ObjCObject> arg0,
-                                NSUInteger arg1,
-                                ffi.Pointer<ffi.Bool> arg2)>(
-                        _ObjCBlock4_fnPtrTrampoline, false)
-                    .cast(),
-                ptr.cast()),
+            lib
+                ._newBlock1(
+                    ffi.Pointer.fromFunction<
+                                ffi.Bool Function(
+                                    ffi.Pointer<_ObjCBlock> block,
+                                    ffi.Pointer<ObjCObject> arg0,
+                                    NSUInteger arg1,
+                                    ffi.Pointer<ffi.Bool> arg2)>(
+                            _ObjCBlock4_fnPtrTrampoline, false)
+                        .cast(),
+                    ptr.cast()),
             lib);
 
   /// Creates a block from a Dart function.
@@ -40641,8 +40642,8 @@
   ObjCBlock15.fromFunctionPointer(
       AVFAudio lib,
       ffi.Pointer<
-              ffi.NativeFunction<
-                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
+              ffi
+              .NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
           ptr)
       : this._(
             lib._newBlock1(
@@ -43044,8 +43045,8 @@
   void call() {
     return _id.ref.invoke
         .cast<
-            ffi.NativeFunction<
-                ffi.Void Function(ffi.Pointer<_ObjCBlock> block)>>()
+            ffi
+            .NativeFunction<ffi.Void Function(ffi.Pointer<_ObjCBlock> block)>>()
         .asFunction<void Function(ffi.Pointer<_ObjCBlock> block)>()(_id);
   }
 
@@ -44324,8 +44325,8 @@
   ObjCBlock17.fromFunctionPointer(
       AVFAudio lib,
       ffi.Pointer<
-              ffi.NativeFunction<
-                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
+              ffi
+              .NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
           ptr)
       : this._(
             lib._newBlock1(
@@ -47403,15 +47404,16 @@
                       ffi.Pointer<ObjCObject> arg1)>>
           ptr)
       : this._(
-            lib._newBlock1(
-                ffi.Pointer.fromFunction<
-                            ffi.Void Function(
-                                ffi.Pointer<_ObjCBlock> block,
-                                ffi.Pointer<ObjCObject> arg0,
-                                ffi.Pointer<ObjCObject> arg1)>(
-                        _ObjCBlock19_fnPtrTrampoline)
-                    .cast(),
-                ptr.cast()),
+            lib
+                ._newBlock1(
+                    ffi.Pointer.fromFunction<
+                                ffi.Void Function(
+                                    ffi.Pointer<_ObjCBlock> block,
+                                    ffi.Pointer<ObjCObject> arg0,
+                                    ffi.Pointer<ObjCObject> arg1)>(
+                            _ObjCBlock19_fnPtrTrampoline)
+                        .cast(),
+                    ptr.cast()),
             lib);
 
   /// Creates a block from a Dart function.
@@ -47560,7 +47562,8 @@
   ObjCBlock21.fromFunctionPointer(
       AVFAudio lib,
       ffi.Pointer<
-              ffi.NativeFunction<
+              ffi
+              .NativeFunction<
                   ffi.Void Function(ffi.Pointer<ObjCObject> arg0, ffi.Bool arg1,
                       ffi.Pointer<ObjCObject> arg2)>>
           ptr)
@@ -47654,15 +47657,16 @@
                       ffi.Pointer<ObjCObject> arg1)>>
           ptr)
       : this._(
-            lib._newBlock1(
-                ffi.Pointer.fromFunction<
-                            ffi.Void Function(
-                                ffi.Pointer<_ObjCBlock> block,
-                                ffi.Pointer<ObjCObject> arg0,
-                                ffi.Pointer<ObjCObject> arg1)>(
-                        _ObjCBlock22_fnPtrTrampoline)
-                    .cast(),
-                ptr.cast()),
+            lib
+                ._newBlock1(
+                    ffi.Pointer.fromFunction<
+                                ffi.Void Function(
+                                    ffi.Pointer<_ObjCBlock> block,
+                                    ffi.Pointer<ObjCObject> arg0,
+                                    ffi.Pointer<ObjCObject> arg1)>(
+                            _ObjCBlock22_fnPtrTrampoline)
+                        .cast(),
+                    ptr.cast()),
             lib);
 
   /// Creates a block from a Dart function.
@@ -47811,15 +47815,16 @@
                       ffi.Pointer<ObjCObject> arg1)>>
           ptr)
       : this._(
-            lib._newBlock1(
-                ffi.Pointer.fromFunction<
-                            ffi.Void Function(
-                                ffi.Pointer<_ObjCBlock> block,
-                                ffi.Pointer<ObjCObject> arg0,
-                                ffi.Pointer<ObjCObject> arg1)>(
-                        _ObjCBlock24_fnPtrTrampoline)
-                    .cast(),
-                ptr.cast()),
+            lib
+                ._newBlock1(
+                    ffi.Pointer.fromFunction<
+                                ffi.Void Function(
+                                    ffi.Pointer<_ObjCBlock> block,
+                                    ffi.Pointer<ObjCObject> arg0,
+                                    ffi.Pointer<ObjCObject> arg1)>(
+                            _ObjCBlock24_fnPtrTrampoline)
+                        .cast(),
+                    ptr.cast()),
             lib);
 
   /// Creates a block from a Dart function.
@@ -53644,8 +53649,8 @@
   ObjCBlock29.fromFunctionPointer(
       AVFAudio lib,
       ffi.Pointer<
-              ffi.NativeFunction<
-                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
+              ffi
+              .NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
           ptr)
       : this._(
             lib._newBlock1(
@@ -55582,8 +55587,8 @@
   ObjCBlock30.fromFunctionPointer(
       AVFAudio lib,
       ffi.Pointer<
-              ffi.NativeFunction<
-                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
+              ffi
+              .NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
           ptr)
       : this._(
             lib._newBlock1(
@@ -57065,8 +57070,8 @@
           ffi.Pointer<ffi.Void> Function(
               ffi.Pointer<ffi.Void>,
               ffi.Pointer<
-                  ffi.NativeFunction<
-                      NSUInteger Function(ffi.Pointer<ffi.Void>)>>,
+                  ffi
+                  .NativeFunction<NSUInteger Function(ffi.Pointer<ffi.Void>)>>,
               ffi.Bool)>> get acquireFunction {
     return _lib._objc_msgSend_803(_id, _lib._sel_acquireFunction1);
   }
@@ -58822,8 +58827,8 @@
   ObjCBlock33.fromFunctionPointer(
       AVFAudio lib,
       ffi.Pointer<
-              ffi.NativeFunction<
-                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
+              ffi
+              .NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
           ptr)
       : this._(
             lib._newBlock1(
@@ -59834,8 +59839,8 @@
   ObjCBlock35.fromFunctionPointer(
       AVFAudio lib,
       ffi.Pointer<
-              ffi.NativeFunction<
-                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
+              ffi
+              .NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
           ptr)
       : this._(
             lib._newBlock1(
@@ -59902,8 +59907,8 @@
   ObjCBlock36.fromFunctionPointer(
       AVFAudio lib,
       ffi.Pointer<
-              ffi.NativeFunction<
-                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
+              ffi
+              .NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
           ptr)
       : this._(
             lib._newBlock1(
@@ -62217,8 +62222,8 @@
   ObjCBlock38.fromFunctionPointer(
       AVFAudio lib,
       ffi.Pointer<
-              ffi.NativeFunction<
-                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
+              ffi
+              .NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
           ptr)
       : this._(
             lib._newBlock1(
@@ -62442,7 +62447,8 @@
   ObjCBlock39.fromFunctionPointer(
       AVFAudio lib,
       ffi.Pointer<
-              ffi.NativeFunction<
+              ffi
+              .NativeFunction<
                   ffi.Void Function(ffi.Pointer<ObjCObject> arg0, ffi.Bool arg1,
                       ffi.Pointer<ObjCObject> arg2)>>
           ptr)
@@ -63106,15 +63112,16 @@
                       ffi.Pointer<ObjCObject> arg1)>>
           ptr)
       : this._(
-            lib._newBlock1(
-                ffi.Pointer.fromFunction<
-                            ffi.Void Function(
-                                ffi.Pointer<_ObjCBlock> block,
-                                ffi.Pointer<ObjCObject> arg0,
-                                ffi.Pointer<ObjCObject> arg1)>(
-                        _ObjCBlock40_fnPtrTrampoline)
-                    .cast(),
-                ptr.cast()),
+            lib
+                ._newBlock1(
+                    ffi.Pointer.fromFunction<
+                                ffi.Void Function(
+                                    ffi.Pointer<_ObjCBlock> block,
+                                    ffi.Pointer<ObjCObject> arg0,
+                                    ffi.Pointer<ObjCObject> arg1)>(
+                            _ObjCBlock40_fnPtrTrampoline)
+                        .cast(),
+                    ptr.cast()),
             lib);
 
   /// Creates a block from a Dart function.
@@ -63770,8 +63777,8 @@
   ObjCBlock43.fromFunctionPointer(
       AVFAudio lib,
       ffi.Pointer<
-              ffi.NativeFunction<
-                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
+              ffi
+              .NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
           ptr)
       : this._(
             lib._newBlock1(
diff --git a/pkgs/ffigen/example/objective_c/config.yaml b/pkgs/ffigen/example/objective_c/config.yaml
index b44cc69..3a76517 100644
--- a/pkgs/ffigen/example/objective_c/config.yaml
+++ b/pkgs/ffigen/example/objective_c/config.yaml
@@ -12,4 +12,4 @@
   entry-points:
     - '/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/AVFAudio.framework/Headers/AVAudioPlayer.h'
 preamble: |
-  // ignore_for_file: camel_case_types, non_constant_identifier_names, unused_element, unused_field, return_of_invalid_type, void_checks, annotate_overrides, no_leading_underscores_for_local_identifiers, library_private_types_in_public_api
+  // ignore_for_file: camel_case_types, non_constant_identifier_names, unused_element, unused_field, void_checks, annotate_overrides, no_leading_underscores_for_local_identifiers, library_private_types_in_public_api
diff --git a/pkgs/ffigen/example/objective_c/pubspec.yaml b/pkgs/ffigen/example/objective_c/pubspec.yaml
index 4cedaa3..c06b7a0 100644
--- a/pkgs/ffigen/example/objective_c/pubspec.yaml
+++ b/pkgs/ffigen/example/objective_c/pubspec.yaml
@@ -5,7 +5,7 @@
 name: objective_c_example
 
 environment:
-  sdk: ">=3.0.0 <4.0.0"
+  sdk: ">=3.2.0-114.0.dev <4.0.0"
 
 dependencies:
   ffi: ^2.0.1
diff --git a/pkgs/ffigen/example/shared_bindings/pubspec.yaml b/pkgs/ffigen/example/shared_bindings/pubspec.yaml
index 2f270f1..23008d2 100644
--- a/pkgs/ffigen/example/shared_bindings/pubspec.yaml
+++ b/pkgs/ffigen/example/shared_bindings/pubspec.yaml
@@ -5,7 +5,7 @@
 name: shared_bindings
 
 environment:
-  sdk: ">=3.0.0 <4.0.0"
+  sdk: ">=3.2.0-114.0.dev <4.0.0"
 
 dependencies:
   cli_util: ^0.4.0
diff --git a/pkgs/ffigen/example/simple/generated_bindings.dart b/pkgs/ffigen/example/simple/generated_bindings.dart
index 71f0414..b26a8ac 100644
--- a/pkgs/ffigen/example/simple/generated_bindings.dart
+++ b/pkgs/ffigen/example/simple/generated_bindings.dart
@@ -81,8 +81,9 @@
   }
 
   late final _dividePtr = _lookup<
-      ffi.NativeFunction<
-          ffi.Pointer<ffi.Float> Function(ffi.Int, ffi.Int)>>('divide');
+          ffi
+          .NativeFunction<ffi.Pointer<ffi.Float> Function(ffi.Int, ffi.Int)>>(
+      'divide');
   late final _divide =
       _dividePtr.asFunction<ffi.Pointer<ffi.Float> Function(int, int)>();
 
diff --git a/pkgs/ffigen/example/simple/pubspec.yaml b/pkgs/ffigen/example/simple/pubspec.yaml
index ea43572..bef3790 100644
--- a/pkgs/ffigen/example/simple/pubspec.yaml
+++ b/pkgs/ffigen/example/simple/pubspec.yaml
@@ -5,7 +5,7 @@
 name: simple_example
 
 environment:
-  sdk: ">=3.0.0 <4.0.0"
+  sdk: ">=3.2.0-114.0.dev <4.0.0"
 
 dependencies:
   ffi: ^2.0.1
diff --git a/pkgs/ffigen/example/swift/pubspec.yaml b/pkgs/ffigen/example/swift/pubspec.yaml
index 07d93eb..de19bf2 100644
--- a/pkgs/ffigen/example/swift/pubspec.yaml
+++ b/pkgs/ffigen/example/swift/pubspec.yaml
@@ -5,7 +5,7 @@
 name: swift_example
 
 environment:
-  sdk: ">=3.0.0 <4.0.0"
+  sdk: ">=3.2.0-42.1.beta <4.0.0"
 
 dependencies:
   ffi: ^2.0.1
diff --git a/pkgs/ffigen/example/swift/swift_api_bindings.dart b/pkgs/ffigen/example/swift/swift_api_bindings.dart
index f741f7f..2a8783a 100644
--- a/pkgs/ffigen/example/swift/swift_api_bindings.dart
+++ b/pkgs/ffigen/example/swift/swift_api_bindings.dart
@@ -22386,8 +22386,8 @@
           ffi.Pointer<ObjCObject>,
           ffi.Pointer<ObjCSel>,
           ffi.Pointer<
-              ffi.NativeFunction<
-                  NSUInteger Function(ffi.Pointer<ffi.Void>)>>)>();
+              ffi
+              .NativeFunction<NSUInteger Function(ffi.Pointer<ffi.Void>)>>)>();
 
   late final _sel_descriptionFunction1 = _registerName1("descriptionFunction");
   ffi.Pointer<
@@ -22546,8 +22546,8 @@
           ffi.Pointer<ffi.Void> Function(
               ffi.Pointer<ffi.Void>,
               ffi.Pointer<
-                  ffi.NativeFunction<
-                      NSUInteger Function(ffi.Pointer<ffi.Void>)>>,
+                  ffi
+                  .NativeFunction<NSUInteger Function(ffi.Pointer<ffi.Void>)>>,
               ffi.Bool)>> _objc_msgSend_803(
     ffi.Pointer<ObjCObject> obj,
     ffi.Pointer<ObjCSel> sel,
@@ -22558,20 +22558,20 @@
     );
   }
 
-  late final __objc_msgSend_803Ptr =
-      _lookup<
-              ffi.NativeFunction<
-                  ffi.Pointer<
-                          ffi.NativeFunction<
-                              ffi.Pointer<ffi.Void> Function(
-                                  ffi.Pointer<ffi.Void>,
-                                  ffi.Pointer<
+  late final __objc_msgSend_803Ptr = _lookup<
+          ffi.NativeFunction<
+              ffi.Pointer<
+                      ffi.NativeFunction<
+                          ffi.Pointer<ffi.Void> Function(
+                              ffi.Pointer<ffi.Void>,
+                              ffi
+                                  .Pointer<
                                       ffi.NativeFunction<
                                           NSUInteger Function(
                                               ffi.Pointer<ffi.Void>)>>,
-                                  ffi.Bool)>>
-                      Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>(
-          'objc_msgSend');
+                              ffi.Bool)>>
+                  Function(ffi.Pointer<ObjCObject>, ffi.Pointer<ObjCSel>)>>(
+      'objc_msgSend');
   late final __objc_msgSend_803 = __objc_msgSend_803Ptr.asFunction<
       ffi.Pointer<
               ffi.NativeFunction<
@@ -34838,7 +34838,11 @@
   /// Creates a block from a C function pointer.
   ObjCBlock4.fromFunctionPointer(
       SwiftLibrary lib,
-      ffi.Pointer<ffi.NativeFunction<ffi.Bool Function(ffi.Pointer<ObjCObject> arg0, NSUInteger arg1, ffi.Pointer<ffi.Bool> arg2)>>
+      ffi.Pointer<
+              ffi
+              .NativeFunction<
+                  ffi.Bool Function(ffi.Pointer<ObjCObject> arg0,
+                      NSUInteger arg1, ffi.Pointer<ffi.Bool> arg2)>>
           ptr)
       : this._(
             lib._newBlock1(
@@ -39398,8 +39402,8 @@
   ObjCBlock15.fromFunctionPointer(
       SwiftLibrary lib,
       ffi.Pointer<
-              ffi.NativeFunction<
-                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
+              ffi
+              .NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
           ptr)
       : this._(
             lib._newBlock1(
@@ -41807,8 +41811,8 @@
   void call() {
     return _id.ref.invoke
         .cast<
-            ffi.NativeFunction<
-                ffi.Void Function(ffi.Pointer<_ObjCBlock> block)>>()
+            ffi
+            .NativeFunction<ffi.Void Function(ffi.Pointer<_ObjCBlock> block)>>()
         .asFunction<void Function(ffi.Pointer<_ObjCBlock> block)>()(_id);
   }
 
@@ -43090,8 +43094,8 @@
   ObjCBlock17.fromFunctionPointer(
       SwiftLibrary lib,
       ffi.Pointer<
-              ffi.NativeFunction<
-                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
+              ffi
+              .NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
           ptr)
       : this._(
             lib._newBlock1(
@@ -46332,7 +46336,8 @@
   ObjCBlock21.fromFunctionPointer(
       SwiftLibrary lib,
       ffi.Pointer<
-              ffi.NativeFunction<
+              ffi
+              .NativeFunction<
                   ffi.Void Function(ffi.Pointer<ObjCObject> arg0, ffi.Bool arg1,
                       ffi.Pointer<ObjCObject> arg2)>>
           ptr)
@@ -52432,8 +52437,8 @@
   ObjCBlock29.fromFunctionPointer(
       SwiftLibrary lib,
       ffi.Pointer<
-              ffi.NativeFunction<
-                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
+              ffi
+              .NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
           ptr)
       : this._(
             lib._newBlock1(
@@ -54371,8 +54376,8 @@
   ObjCBlock30.fromFunctionPointer(
       SwiftLibrary lib,
       ffi.Pointer<
-              ffi.NativeFunction<
-                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
+              ffi
+              .NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
           ptr)
       : this._(
             lib._newBlock1(
@@ -55856,8 +55861,8 @@
           ffi.Pointer<ffi.Void> Function(
               ffi.Pointer<ffi.Void>,
               ffi.Pointer<
-                  ffi.NativeFunction<
-                      NSUInteger Function(ffi.Pointer<ffi.Void>)>>,
+                  ffi
+                  .NativeFunction<NSUInteger Function(ffi.Pointer<ffi.Void>)>>,
               ffi.Bool)>> get acquireFunction {
     return _lib._objc_msgSend_803(_id, _lib._sel_acquireFunction1);
   }
@@ -57616,8 +57621,8 @@
   ObjCBlock33.fromFunctionPointer(
       SwiftLibrary lib,
       ffi.Pointer<
-              ffi.NativeFunction<
-                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
+              ffi
+              .NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
           ptr)
       : this._(
             lib._newBlock1(
@@ -58632,8 +58637,8 @@
   ObjCBlock35.fromFunctionPointer(
       SwiftLibrary lib,
       ffi.Pointer<
-              ffi.NativeFunction<
-                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
+              ffi
+              .NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
           ptr)
       : this._(
             lib._newBlock1(
@@ -58700,8 +58705,8 @@
   ObjCBlock36.fromFunctionPointer(
       SwiftLibrary lib,
       ffi.Pointer<
-              ffi.NativeFunction<
-                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
+              ffi
+              .NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
           ptr)
       : this._(
             lib._newBlock1(
@@ -61015,8 +61020,8 @@
   ObjCBlock38.fromFunctionPointer(
       SwiftLibrary lib,
       ffi.Pointer<
-              ffi.NativeFunction<
-                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
+              ffi
+              .NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
           ptr)
       : this._(
             lib._newBlock1(
@@ -61240,7 +61245,8 @@
   ObjCBlock39.fromFunctionPointer(
       SwiftLibrary lib,
       ffi.Pointer<
-              ffi.NativeFunction<
+              ffi
+              .NativeFunction<
                   ffi.Void Function(ffi.Pointer<ObjCObject> arg0, ffi.Bool arg1,
                       ffi.Pointer<ObjCObject> arg2)>>
           ptr)
@@ -62568,8 +62574,8 @@
   ObjCBlock43.fromFunctionPointer(
       SwiftLibrary lib,
       ffi.Pointer<
-              ffi.NativeFunction<
-                  ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
+              ffi
+              .NativeFunction<ffi.Void Function(ffi.Pointer<ObjCObject> arg0)>>
           ptr)
       : this._(
             lib._newBlock1(
diff --git a/pkgs/ffigen/lib/src/code_generator/imports.dart b/pkgs/ffigen/lib/src/code_generator/imports.dart
index d6dcd06..93af5ad 100644
--- a/pkgs/ffigen/lib/src/code_generator/imports.dart
+++ b/pkgs/ffigen/lib/src/code_generator/imports.dart
@@ -86,8 +86,8 @@
     ImportedType(ffiImport, 'UnsignedLongLong', 'int', '0');
 final longLongType = ImportedType(ffiImport, 'LongLong', 'int', '0');
 
-final floatType = ImportedType(ffiImport, 'Float', 'double', '0');
-final doubleType = ImportedType(ffiImport, 'Double', 'double', '0');
+final floatType = ImportedType(ffiImport, 'Float', 'double', '0.0');
+final doubleType = ImportedType(ffiImport, 'Double', 'double', '0.0');
 
 final sizeType = ImportedType(ffiImport, 'Size', 'int', '0');
 final wCharType = ImportedType(ffiImport, 'WChar', 'int', '0');
diff --git a/pkgs/ffigen/lib/src/code_generator/native_type.dart b/pkgs/ffigen/lib/src/code_generator/native_type.dart
index d76e7e7..dfb43a5 100644
--- a/pkgs/ffigen/lib/src/code_generator/native_type.dart
+++ b/pkgs/ffigen/lib/src/code_generator/native_type.dart
@@ -36,8 +36,8 @@
     SupportedNativeType.Uint16: NativeType._('Uint16', 'int', '0'),
     SupportedNativeType.Uint32: NativeType._('Uint32', 'int', '0'),
     SupportedNativeType.Uint64: NativeType._('Uint64', 'int', '0'),
-    SupportedNativeType.Float: NativeType._('Float', 'double', '0'),
-    SupportedNativeType.Double: NativeType._('Double', 'double', '0'),
+    SupportedNativeType.Float: NativeType._('Float', 'double', '0.0'),
+    SupportedNativeType.Double: NativeType._('Double', 'double', '0.0'),
     SupportedNativeType.IntPtr: NativeType._('IntPtr', 'int', '0'),
     SupportedNativeType.UintPtr: NativeType._('UintPtr', 'int', '0'),
   };
diff --git a/pkgs/ffigen/lib/src/code_generator/objc_block.dart b/pkgs/ffigen/lib/src/code_generator/objc_block.dart
index 1599748..ba028d6 100644
--- a/pkgs/ffigen/lib/src/code_generator/objc_block.dart
+++ b/pkgs/ffigen/lib/src/code_generator/objc_block.dart
@@ -35,7 +35,7 @@
       params.add(Parameter(name: 'arg$i', type: argTypes[i]));
     }
 
-    final isVoid = returnType == NativeType(SupportedNativeType.Void);
+    final isVoid = returnType == voidType;
     final voidPtr = PointerType(voidType).getCType(w);
     final blockPtr = PointerType(builtInFunctions.blockStruct);
     final funcType = FunctionType(returnType: returnType, parameters: params);
@@ -55,6 +55,8 @@
         returnType: returnType,
         parameters: [Parameter(type: blockPtr, name: 'block'), ...params]);
     final natTrampFnType = NativeFunc(trampFuncType);
+    final nativeCallableType =
+        '${w.ffiLibraryPrefix}.NativeCallable<${trampFuncType.getCType(w)}>';
 
     // Write the function pointer based trampoline function.
     s.write(returnType.getDartType(w));
@@ -90,8 +92,14 @@
       s.write(', ${params[i].type.getDartType(w)} ${params[i].name}');
     }
     s.write(') {\n');
-    s.write('  ${isVoid ? '' : 'return '}$closureRegistry['
-        'block.ref.target.address]!(');
+    s.write('  ${isVoid ? '' : 'return '}');
+    s.write('($closureRegistry[block.ref.target.address]');
+    s.write(' as ${returnType.getDartType(w)} Function(');
+    for (int i = 0; i < params.length; ++i) {
+      s.write('${i == 0 ? '' : ', '}${params[i].type.getDartType(w)}');
+    }
+    s.write('))');
+    s.write('(');
     for (int i = 0; i < params.length; ++i) {
       s.write('${i == 0 ? '' : ', '}${params[i].name}');
     }
@@ -107,6 +115,10 @@
       super._(id, lib, retain: false, release: true);
 
   /// Creates a block from a C function pointer.
+  ///
+  /// This block must be invoked by native code running on the same thread as
+  /// the isolate that registered it. Invoking the block on the wrong thread
+  /// will result in a crash.
   $name.fromFunctionPointer(${w.className} lib, $natFnPtr ptr) :
       this._(lib.${builtInFunctions.newBlock.name}(
           _cFuncTrampoline ??= ${w.ffiLibraryPrefix}.Pointer.fromFunction<
@@ -115,14 +127,41 @@
   static $voidPtr? _cFuncTrampoline;
 
   /// Creates a block from a Dart function.
+  ///
+  /// This block must be invoked by native code running on the same thread as
+  /// the isolate that registered it. Invoking the block on the wrong thread
+  /// will result in a crash.
   $name.fromFunction(${w.className} lib, ${funcType.getDartType(w)} fn) :
       this._(lib.${builtInFunctions.newBlock.name}(
           _dartFuncTrampoline ??= ${w.ffiLibraryPrefix}.Pointer.fromFunction<
               ${trampFuncType.getCType(w)}>($closureTrampoline
                   $exceptionalReturn).cast(), $registerClosure(fn)), lib);
   static $voidPtr? _dartFuncTrampoline;
+
 ''');
 
+    // Listener block constructor is only available for void blocks.
+    if (isVoid) {
+      s.write('''
+  /// Creates a listener block from a Dart function.
+  ///
+  /// This is based on FFI's NativeCallable.listener, and has the same
+  /// capabilities and limitations. This block can be invoked from any thread,
+  /// but only supports void functions, and is not run synchronously. See
+  /// NativeCallable.listener for more details.
+  ///
+  /// Note that unlike the default behavior of NativeCallable.listener, listener
+  /// blocks do not keep the isolate alive.
+  $name.listener(${w.className} lib, ${funcType.getDartType(w)} fn) :
+      this._(lib.${builtInFunctions.newBlock.name}(
+          (_dartFuncListenerTrampoline ??= $nativeCallableType.listener($closureTrampoline
+                  $exceptionalReturn)..keepIsolateAlive = false).nativeFunction.cast(),
+          $registerClosure(fn)), lib);
+  static $nativeCallableType? _dartFuncListenerTrampoline;
+
+''');
+    }
+
     // Call method.
     s.write('  ${returnType.getDartType(w)} call(');
     for (int i = 0; i < params.length; ++i) {
diff --git a/pkgs/ffigen/lib/src/config_provider/config_spec.dart b/pkgs/ffigen/lib/src/config_provider/config_spec.dart
index 3ad3249..3d67be9 100644
--- a/pkgs/ffigen/lib/src/config_provider/config_spec.dart
+++ b/pkgs/ffigen/lib/src/config_provider/config_spec.dart
@@ -591,7 +591,7 @@
     if (!o.checkType<String>(log: log)) {
       return false;
     }
-    if (_regexp != null && !_regexp!.hasMatch(o.value as String)) {
+    if (!(_regexp?.hasMatch(o.value as String) ?? true)) {
       if (log) {
         _logger.severe(
             "Expected value of key '${o.pathString}' to match pattern $pattern (Input - ${o.value}).");
diff --git a/pkgs/ffigen/lib/src/header_parser/clang_bindings/clang_bindings.dart b/pkgs/ffigen/lib/src/header_parser/clang_bindings/clang_bindings.dart
index 4c5fba2..fc5ca17 100644
--- a/pkgs/ffigen/lib/src/header_parser/clang_bindings/clang_bindings.dart
+++ b/pkgs/ffigen/lib/src/header_parser/clang_bindings/clang_bindings.dart
@@ -1097,9 +1097,9 @@
   }
 
   late final _clang_Cursor_getObjCPropertyAttributesPtr = _lookup<
-      ffi.NativeFunction<
-          ffi.UnsignedInt Function(CXCursor,
-              ffi.UnsignedInt)>>('clang_Cursor_getObjCPropertyAttributes');
+          ffi
+          .NativeFunction<ffi.UnsignedInt Function(CXCursor, ffi.UnsignedInt)>>(
+      'clang_Cursor_getObjCPropertyAttributes');
   late final _clang_Cursor_getObjCPropertyAttributes =
       _clang_Cursor_getObjCPropertyAttributesPtr
           .asFunction<int Function(CXCursor, int)>();
diff --git a/pkgs/ffigen/pubspec.yaml b/pkgs/ffigen/pubspec.yaml
index 3a8e0c1..ae45a10 100644
--- a/pkgs/ffigen/pubspec.yaml
+++ b/pkgs/ffigen/pubspec.yaml
@@ -3,8 +3,10 @@
 # BSD-style license that can be found in the LICENSE file.
 
 name: ffigen
-version: 9.0.1
-description: Generator for FFI bindings, using LibClang to parse C header files.
+version: 10.0.0-dev.0
+description: >
+  Generator for FFI bindings, using LibClang to parse C, Objective-C, and Swift
+  files.
 repository: https://github.com/dart-lang/ffigen
 
 topics:
@@ -13,7 +15,7 @@
  - codegen
 
 environment:
-  sdk: ">=3.0.0 <4.0.0"
+  sdk: ">=3.2.0-114.0.dev <4.0.0"
 
 dependencies:
   ffi: ^2.0.1
diff --git a/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_boolean_dartbool_bindings.dart b/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_boolean_dartbool_bindings.dart
index 015821e..ff7dc12 100644
--- a/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_boolean_dartbool_bindings.dart
+++ b/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_boolean_dartbool_bindings.dart
@@ -29,8 +29,9 @@
   }
 
   late final _test1Ptr = _lookup<
-      ffi.NativeFunction<
-          ffi.Bool Function(ffi.Bool, ffi.Pointer<ffi.Bool>)>>('test1');
+          ffi
+          .NativeFunction<ffi.Bool Function(ffi.Bool, ffi.Pointer<ffi.Bool>)>>(
+      'test1');
   late final _test1 =
       _test1Ptr.asFunction<bool Function(bool, ffi.Pointer<ffi.Bool>)>();
 }
diff --git a/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_functions_bindings.dart b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_functions_bindings.dart
index 7475b09..7b6682c 100644
--- a/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_functions_bindings.dart
+++ b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_functions_bindings.dart
@@ -128,8 +128,9 @@
   }
 
   late final _diffCharsPtr = _lookup<
-      ffi.NativeFunction<
-          ffi.Char Function(ffi.UnsignedChar, ffi.SignedChar)>>('diffChars');
+          ffi
+          .NativeFunction<ffi.Char Function(ffi.UnsignedChar, ffi.SignedChar)>>(
+      'diffChars');
   late final _diffChars = _diffCharsPtr.asFunction<int Function(int, int)>();
 
   late final addresses = _SymbolAddresses(this);
diff --git a/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_struct_fptr_fields_bindings.dart b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_struct_fptr_fields_bindings.dart
index 2b2fe8a..2a769db 100644
--- a/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_struct_fptr_fields_bindings.dart
+++ b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_struct_fptr_fields_bindings.dart
@@ -8,7 +8,7 @@
   external ffi.Pointer<ffi.NativeFunction<ffi.Int Function()>> func1;
 
   external ffi
-          .Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Int a, ffi.Int b)>>
+      .Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Int a, ffi.Int b)>>
       comparator;
 
   external ffi.Pointer<
@@ -53,8 +53,8 @@
 
   @ffi.Array.multi([2])
   external ffi.Array<
-          ffi.Pointer<
-              ffi.NativeFunction<ffi.Void Function(ffi.Char, ffi.Char)>>>
+          ffi
+          .Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Char, ffi.Char)>>>
       manyFunctions;
 
   external ffi.Pointer<
diff --git a/pkgs/ffigen/test/large_integration_tests/_expected_cjson_bindings.dart b/pkgs/ffigen/test/large_integration_tests/_expected_cjson_bindings.dart
index b93c74f..f4edb59 100644
--- a/pkgs/ffigen/test/large_integration_tests/_expected_cjson_bindings.dart
+++ b/pkgs/ffigen/test/large_integration_tests/_expected_cjson_bindings.dart
@@ -54,8 +54,9 @@
   }
 
   late final _cJSON_ParsePtr = _lookup<
-      ffi.NativeFunction<
-          ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>>('cJSON_Parse');
+          ffi
+          .NativeFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>>(
+      'cJSON_Parse');
   late final _cJSON_Parse = _cJSON_ParsePtr
       .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>();
 
@@ -90,8 +91,9 @@
   }
 
   late final _cJSON_PrintPtr = _lookup<
-      ffi.NativeFunction<
-          ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>)>>('cJSON_Print');
+          ffi
+          .NativeFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>)>>(
+      'cJSON_Print');
   late final _cJSON_Print = _cJSON_PrintPtr
       .asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>)>();
 
@@ -104,9 +106,9 @@
   }
 
   late final _cJSON_PrintUnformattedPtr = _lookup<
-      ffi.NativeFunction<
-          ffi.Pointer<ffi.Char> Function(
-              ffi.Pointer<cJSON>)>>('cJSON_PrintUnformatted');
+          ffi
+          .NativeFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>)>>(
+      'cJSON_PrintUnformatted');
   late final _cJSON_PrintUnformatted = _cJSON_PrintUnformattedPtr
       .asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>)>();
 
@@ -267,9 +269,9 @@
   }
 
   late final _cJSON_GetStringValuePtr = _lookup<
-      ffi.NativeFunction<
-          ffi.Pointer<ffi.Char> Function(
-              ffi.Pointer<cJSON>)>>('cJSON_GetStringValue');
+          ffi
+          .NativeFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>)>>(
+      'cJSON_GetStringValue');
   late final _cJSON_GetStringValue = _cJSON_GetStringValuePtr
       .asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>)>();
 
@@ -480,9 +482,9 @@
   }
 
   late final _cJSON_CreateStringPtr = _lookup<
-      ffi.NativeFunction<
-          ffi.Pointer<cJSON> Function(
-              ffi.Pointer<ffi.Char>)>>('cJSON_CreateString');
+          ffi
+          .NativeFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>>(
+      'cJSON_CreateString');
   late final _cJSON_CreateString = _cJSON_CreateStringPtr
       .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>();
 
@@ -495,9 +497,9 @@
   }
 
   late final _cJSON_CreateRawPtr = _lookup<
-      ffi.NativeFunction<
-          ffi.Pointer<cJSON> Function(
-              ffi.Pointer<ffi.Char>)>>('cJSON_CreateRaw');
+          ffi
+          .NativeFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>>(
+      'cJSON_CreateRaw');
   late final _cJSON_CreateRaw = _cJSON_CreateRawPtr
       .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>();
 
@@ -530,9 +532,9 @@
   }
 
   late final _cJSON_CreateStringReferencePtr = _lookup<
-      ffi.NativeFunction<
-          ffi.Pointer<cJSON> Function(
-              ffi.Pointer<ffi.Char>)>>('cJSON_CreateStringReference');
+          ffi
+          .NativeFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>>(
+      'cJSON_CreateStringReference');
   late final _cJSON_CreateStringReference = _cJSON_CreateStringReferencePtr
       .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>();
 
@@ -1180,9 +1182,9 @@
   }
 
   late final _cJSON_SetNumberHelperPtr = _lookup<
-      ffi.NativeFunction<
-          ffi.Double Function(
-              ffi.Pointer<cJSON>, ffi.Double)>>('cJSON_SetNumberHelper');
+          ffi
+          .NativeFunction<ffi.Double Function(ffi.Pointer<cJSON>, ffi.Double)>>(
+      'cJSON_SetNumberHelper');
   late final _cJSON_SetNumberHelper = _cJSON_SetNumberHelperPtr
       .asFunction<double Function(ffi.Pointer<cJSON>, double)>();
 
@@ -1237,12 +1239,13 @@
 }
 
 final class cJSON_Hooks extends ffi.Struct {
-  external ffi.Pointer<
-          ffi.NativeFunction<ffi.Pointer<ffi.Void> Function(ffi.Size sz)>>
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function(ffi.Size sz)>>
       malloc_fn;
 
-  external ffi.Pointer<
-      ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void> ptr)>> free_fn;
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void> ptr)>>
+      free_fn;
 }
 
 typedef cJSON_bool = ffi.Int;
diff --git a/pkgs/ffigen/test/large_integration_tests/_expected_libclang_bindings.dart b/pkgs/ffigen/test/large_integration_tests/_expected_libclang_bindings.dart
index 22c6f266..2bc7688 100644
--- a/pkgs/ffigen/test/large_integration_tests/_expected_libclang_bindings.dart
+++ b/pkgs/ffigen/test/large_integration_tests/_expected_libclang_bindings.dart
@@ -133,9 +133,9 @@
   }
 
   late final _clang_VirtualFileOverlay_setCaseSensitivityPtr = _lookup<
-      ffi.NativeFunction<
-          ffi.Int32 Function(CXVirtualFileOverlay,
-              ffi.Int)>>('clang_VirtualFileOverlay_setCaseSensitivity');
+          ffi
+          .NativeFunction<ffi.Int32 Function(CXVirtualFileOverlay, ffi.Int)>>(
+      'clang_VirtualFileOverlay_setCaseSensitivity');
   late final _clang_VirtualFileOverlay_setCaseSensitivity =
       _clang_VirtualFileOverlay_setCaseSensitivityPtr
           .asFunction<int Function(CXVirtualFileOverlay, int)>();
@@ -384,8 +384,8 @@
   }
 
   late final _clang_CXIndex_setInvocationEmissionPathOptionPtr = _lookup<
-          ffi.NativeFunction<
-              ffi.Void Function(CXIndex, ffi.Pointer<ffi.Char>)>>(
+          ffi
+          .NativeFunction<ffi.Void Function(CXIndex, ffi.Pointer<ffi.Char>)>>(
       'clang_CXIndex_setInvocationEmissionPathOption');
   late final _clang_CXIndex_setInvocationEmissionPathOption =
       _clang_CXIndex_setInvocationEmissionPathOptionPtr
@@ -453,9 +453,9 @@
   }
 
   late final _clang_isFileMultipleIncludeGuardedPtr = _lookup<
-      ffi.NativeFunction<
-          ffi.UnsignedInt Function(CXTranslationUnit,
-              CXFile)>>('clang_isFileMultipleIncludeGuarded');
+          ffi
+          .NativeFunction<ffi.UnsignedInt Function(CXTranslationUnit, CXFile)>>(
+      'clang_isFileMultipleIncludeGuarded');
   late final _clang_isFileMultipleIncludeGuarded =
       _clang_isFileMultipleIncludeGuardedPtr
           .asFunction<int Function(CXTranslationUnit, CXFile)>();
@@ -943,9 +943,9 @@
   }
 
   late final _clang_disposeSourceRangeListPtr = _lookup<
-      ffi.NativeFunction<
-          ffi.Void Function(
-              ffi.Pointer<CXSourceRangeList>)>>('clang_disposeSourceRangeList');
+          ffi
+          .NativeFunction<ffi.Void Function(ffi.Pointer<CXSourceRangeList>)>>(
+      'clang_disposeSourceRangeList');
   late final _clang_disposeSourceRangeList = _clang_disposeSourceRangeListPtr
       .asFunction<void Function(ffi.Pointer<CXSourceRangeList>)>();
 
@@ -3586,9 +3586,9 @@
   }
 
   late final _clang_constructUSR_ObjCIvarPtr = _lookup<
-      ffi.NativeFunction<
-          CXString Function(
-              ffi.Pointer<ffi.Char>, CXString)>>('clang_constructUSR_ObjCIvar');
+          ffi
+          .NativeFunction<CXString Function(ffi.Pointer<ffi.Char>, CXString)>>(
+      'clang_constructUSR_ObjCIvar');
   late final _clang_constructUSR_ObjCIvar = _clang_constructUSR_ObjCIvarPtr
       .asFunction<CXString Function(ffi.Pointer<ffi.Char>, CXString)>();
 
@@ -3626,9 +3626,9 @@
   }
 
   late final _clang_constructUSR_ObjCPropertyPtr = _lookup<
-      ffi.NativeFunction<
-          CXString Function(ffi.Pointer<ffi.Char>,
-              CXString)>>('clang_constructUSR_ObjCProperty');
+          ffi
+          .NativeFunction<CXString Function(ffi.Pointer<ffi.Char>, CXString)>>(
+      'clang_constructUSR_ObjCProperty');
   late final _clang_constructUSR_ObjCProperty =
       _clang_constructUSR_ObjCPropertyPtr
           .asFunction<CXString Function(ffi.Pointer<ffi.Char>, CXString)>();
@@ -3900,9 +3900,9 @@
   }
 
   late final _clang_Cursor_getObjCPropertyAttributesPtr = _lookup<
-      ffi.NativeFunction<
-          ffi.UnsignedInt Function(CXCursor,
-              ffi.UnsignedInt)>>('clang_Cursor_getObjCPropertyAttributes');
+          ffi
+          .NativeFunction<ffi.UnsignedInt Function(CXCursor, ffi.UnsignedInt)>>(
+      'clang_Cursor_getObjCPropertyAttributes');
   late final _clang_Cursor_getObjCPropertyAttributes =
       _clang_Cursor_getObjCPropertyAttributesPtr
           .asFunction<int Function(CXCursor, int)>();
@@ -4595,9 +4595,9 @@
   }
 
   late final _clang_getTokenExtentPtr = _lookup<
-      ffi.NativeFunction<
-          CXSourceRange Function(
-              CXTranslationUnit, CXToken)>>('clang_getTokenExtent');
+          ffi
+          .NativeFunction<CXSourceRange Function(CXTranslationUnit, CXToken)>>(
+      'clang_getTokenExtent');
   late final _clang_getTokenExtent = _clang_getTokenExtentPtr
       .asFunction<CXSourceRange Function(CXTranslationUnit, CXToken)>();
 
@@ -8225,8 +8225,8 @@
 
 /// Visitor invoked for each field found by a traversal.
 typedef CXFieldVisitor = ffi.Pointer<
-    ffi.NativeFunction<
-        ffi.Int32 Function(CXCursor C, CXClientData client_data)>>;
+    ffi
+    .NativeFunction<ffi.Int32 Function(CXCursor C, CXClientData client_data)>>;
 
 const int CINDEX_VERSION_MAJOR = 0;
 
diff --git a/pkgs/ffigen/test/large_integration_tests/_expected_sqlite_bindings.dart b/pkgs/ffigen/test/large_integration_tests/_expected_sqlite_bindings.dart
index af6cccf..984fad3 100644
--- a/pkgs/ffigen/test/large_integration_tests/_expected_sqlite_bindings.dart
+++ b/pkgs/ffigen/test/large_integration_tests/_expected_sqlite_bindings.dart
@@ -914,8 +914,8 @@
   int sqlite3_busy_handler(
     ffi.Pointer<sqlite3> arg0,
     ffi.Pointer<
-            ffi.NativeFunction<
-                ffi.Int Function(ffi.Pointer<ffi.Void>, ffi.Int)>>
+            ffi
+            .NativeFunction<ffi.Int Function(ffi.Pointer<ffi.Void>, ffi.Int)>>
         arg1,
     ffi.Pointer<ffi.Void> arg2,
   ) {
@@ -1410,9 +1410,9 @@
   }
 
   late final _sqlite3_randomnessPtr = _lookup<
-      ffi.NativeFunction<
-          ffi.Void Function(
-              ffi.Int, ffi.Pointer<ffi.Void>)>>('sqlite3_randomness');
+          ffi
+          .NativeFunction<ffi.Void Function(ffi.Int, ffi.Pointer<ffi.Void>)>>(
+      'sqlite3_randomness');
   late final _sqlite3_randomness = _sqlite3_randomnessPtr
       .asFunction<void Function(int, ffi.Pointer<ffi.Void>)>();
 
@@ -4733,10 +4733,11 @@
                                   ffi.Pointer<sqlite3_context>,
                                   ffi.Int,
                                   ffi.Pointer<ffi.Pointer<sqlite3_value>>)>>,
-                      ffi.Pointer<
-                          ffi.NativeFunction<
-                              ffi.Void Function(
-                                  ffi.Pointer<sqlite3_context>)>>)>>(
+                      ffi
+                          .Pointer<
+                              ffi.NativeFunction<
+                                  ffi.Void Function(
+                                      ffi.Pointer<sqlite3_context>)>>)>>(
           'sqlite3_create_function');
   late final _sqlite3_create_function = _sqlite3_create_functionPtr.asFunction<
       int Function(
@@ -4810,10 +4811,11 @@
                                   ffi.Pointer<sqlite3_context>,
                                   ffi.Int,
                                   ffi.Pointer<ffi.Pointer<sqlite3_value>>)>>,
-                      ffi.Pointer<
-                          ffi.NativeFunction<
-                              ffi.Void Function(
-                                  ffi.Pointer<sqlite3_context>)>>)>>(
+                      ffi
+                          .Pointer<
+                              ffi.NativeFunction<
+                                  ffi.Void Function(
+                                      ffi.Pointer<sqlite3_context>)>>)>>(
           'sqlite3_create_function16');
   late final _sqlite3_create_function16 =
       _sqlite3_create_function16Ptr.asFunction<
@@ -4894,9 +4896,10 @@
                       ffi.Pointer<
                           ffi.NativeFunction<
                               ffi.Void Function(ffi.Pointer<sqlite3_context>)>>,
-                      ffi.Pointer<
-                          ffi.NativeFunction<
-                              ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>>(
+                      ffi
+                          .Pointer<
+                              ffi.NativeFunction<
+                                  ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>>(
           'sqlite3_create_function_v2');
   late final _sqlite3_create_function_v2 =
       _sqlite3_create_function_v2Ptr.asFunction<
@@ -4987,9 +4990,10 @@
                                   ffi.Pointer<sqlite3_context>,
                                   ffi.Int,
                                   ffi.Pointer<ffi.Pointer<sqlite3_value>>)>>,
-                      ffi.Pointer<
-                          ffi.NativeFunction<
-                              ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>>(
+                      ffi
+                          .Pointer<
+                              ffi.NativeFunction<
+                                  ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>>(
           'sqlite3_create_window_function');
   late final _sqlite3_create_window_function =
       _sqlite3_create_window_functionPtr.asFunction<
@@ -5294,9 +5298,9 @@
   }
 
   late final _sqlite3_value_int64Ptr = _lookup<
-      ffi.NativeFunction<
-          sqlite3_int64 Function(
-              ffi.Pointer<sqlite3_value>)>>('sqlite3_value_int64');
+          ffi
+          .NativeFunction<sqlite3_int64 Function(ffi.Pointer<sqlite3_value>)>>(
+      'sqlite3_value_int64');
   late final _sqlite3_value_int64 = _sqlite3_value_int64Ptr
       .asFunction<int Function(ffi.Pointer<sqlite3_value>)>();
 
@@ -8361,9 +8365,9 @@
   }
 
   late final _sqlite3_vfs_registerPtr = _lookup<
-      ffi.NativeFunction<
-          ffi.Int Function(
-              ffi.Pointer<sqlite3_vfs>, ffi.Int)>>('sqlite3_vfs_register');
+          ffi
+          .NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_vfs>, ffi.Int)>>(
+      'sqlite3_vfs_register');
   late final _sqlite3_vfs_register = _sqlite3_vfs_registerPtr
       .asFunction<int Function(ffi.Pointer<sqlite3_vfs>, int)>();
 
@@ -9756,8 +9760,9 @@
   }
 
   late final _sqlite3_logPtr = _lookup<
-      ffi.NativeFunction<
-          ffi.Void Function(ffi.Int, ffi.Pointer<ffi.Char>)>>('sqlite3_log');
+          ffi
+          .NativeFunction<ffi.Void Function(ffi.Int, ffi.Pointer<ffi.Char>)>>(
+      'sqlite3_log');
   late final _sqlite3_log =
       _sqlite3_logPtr.asFunction<void Function(int, ffi.Pointer<ffi.Char>)>();
 
@@ -10689,21 +10694,22 @@
     );
   }
 
-  late final _sqlite3_rtree_query_callbackPtr =
-      _lookup<
-              ffi.NativeFunction<
-                  ffi.Int Function(
-                      ffi.Pointer<sqlite3>,
-                      ffi.Pointer<ffi.Char>,
-                      ffi.Pointer<
+  late final _sqlite3_rtree_query_callbackPtr = _lookup<
+          ffi.NativeFunction<
+              ffi.Int Function(
+                  ffi.Pointer<sqlite3>,
+                  ffi.Pointer<ffi.Char>,
+                  ffi
+                      .Pointer<
                           ffi.NativeFunction<
                               ffi.Int Function(
                                   ffi.Pointer<sqlite3_rtree_query_info>)>>,
-                      ffi.Pointer<ffi.Void>,
-                      ffi.Pointer<
-                          ffi.NativeFunction<
-                              ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>>(
-          'sqlite3_rtree_query_callback');
+                  ffi.Pointer<ffi.Void>,
+                  ffi.Pointer<
+                      ffi
+                      .NativeFunction<
+                          ffi.Void Function(ffi.Pointer<ffi.Void>)>>)>>(
+      'sqlite3_rtree_query_callback');
   late final _sqlite3_rtree_query_callback =
       _sqlite3_rtree_query_callbackPtr.asFunction<
           int Function(
@@ -10804,8 +10810,9 @@
       xRandomness;
 
   external ffi.Pointer<
-      ffi.NativeFunction<
-          ffi.Int Function(ffi.Pointer<sqlite3_vfs>, ffi.Int)>> xSleep;
+          ffi
+          .NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_vfs>, ffi.Int)>>
+      xSleep;
 
   external ffi.Pointer<
       ffi.NativeFunction<
@@ -10853,12 +10860,12 @@
 final class sqlite3_mem_methods extends ffi.Struct {
   /// Memory allocation function
   external ffi
-          .Pointer<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function(ffi.Int)>>
+      .Pointer<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function(ffi.Int)>>
       xMalloc;
 
   /// Free a prior allocation
   external ffi
-          .Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+      .Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
       xFree;
 
   /// Resize an allocation
@@ -10869,7 +10876,7 @@
 
   /// Return the size of an allocation
   external ffi
-          .Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<ffi.Void>)>>
+      .Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<ffi.Void>)>>
       xSize;
 
   /// Round up request size to allocation size
@@ -10877,12 +10884,12 @@
 
   /// Initialize the memory allocator
   external ffi
-          .Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<ffi.Void>)>>
+      .Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<ffi.Void>)>>
       xInit;
 
   /// Deinitialize the memory allocator
   external ffi
-          .Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+      .Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
       xShutdown;
 
   /// Argument to xInit() and xShutdown()
@@ -10984,8 +10991,9 @@
               ffi.Pointer<ffi.Pointer<sqlite3_vtab_cursor>> ppCursor)>> xOpen;
 
   external ffi.Pointer<
-      ffi.NativeFunction<
-          ffi.Int Function(ffi.Pointer<sqlite3_vtab_cursor>)>> xClose;
+          ffi
+          .NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_vtab_cursor>)>>
+      xClose;
 
   external ffi.Pointer<
       ffi.NativeFunction<
@@ -10997,12 +11005,13 @@
               ffi.Pointer<ffi.Pointer<sqlite3_value>>)>> xFilter;
 
   external ffi.Pointer<
-      ffi.NativeFunction<
-          ffi.Int Function(ffi.Pointer<sqlite3_vtab_cursor>)>> xNext;
+          ffi
+          .NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_vtab_cursor>)>>
+      xNext;
 
   external ffi.Pointer<
-      ffi.NativeFunction<
-          ffi.Int Function(ffi.Pointer<sqlite3_vtab_cursor>)>> xEof;
+      ffi
+      .NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_vtab_cursor>)>> xEof;
 
   external ffi.Pointer<
       ffi.NativeFunction<
@@ -11063,21 +11072,24 @@
   /// The methods above are in version 1 of the sqlite_module object. Those
   /// below are for version 2 and greater.
   external ffi.Pointer<
-      ffi.NativeFunction<
-          ffi.Int Function(ffi.Pointer<sqlite3_vtab>, ffi.Int)>> xSavepoint;
+          ffi
+          .NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_vtab>, ffi.Int)>>
+      xSavepoint;
 
   external ffi.Pointer<
-      ffi.NativeFunction<
-          ffi.Int Function(ffi.Pointer<sqlite3_vtab>, ffi.Int)>> xRelease;
+          ffi
+          .NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_vtab>, ffi.Int)>>
+      xRelease;
 
   external ffi.Pointer<
-      ffi.NativeFunction<
-          ffi.Int Function(ffi.Pointer<sqlite3_vtab>, ffi.Int)>> xRollbackTo;
+          ffi
+          .NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_vtab>, ffi.Int)>>
+      xRollbackTo;
 
   /// The methods above are in versions 1 and 2 of the sqlite_module object.
   /// Those below are for version 3 and greater.
   external ffi
-          .Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<ffi.Char>)>>
+      .Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<ffi.Char>)>>
       xShadowName;
 }
 
@@ -11296,8 +11308,8 @@
 
   external ffi.Pointer<ffi.NativeFunction<ffi.Int Function()>> xMutexEnd;
 
-  external ffi.Pointer<
-          ffi.NativeFunction<ffi.Pointer<sqlite3_mutex> Function(ffi.Int)>>
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Pointer<sqlite3_mutex> Function(ffi.Int)>>
       xMutexAlloc;
 
   external ffi.Pointer<
@@ -11308,20 +11320,20 @@
           ffi.NativeFunction<ffi.Void Function(ffi.Pointer<sqlite3_mutex>)>>
       xMutexEnter;
 
-  external ffi.Pointer<
-          ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_mutex>)>>
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_mutex>)>>
       xMutexTry;
 
   external ffi.Pointer<
           ffi.NativeFunction<ffi.Void Function(ffi.Pointer<sqlite3_mutex>)>>
       xMutexLeave;
 
-  external ffi.Pointer<
-          ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_mutex>)>>
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_mutex>)>>
       xMutexHeld;
 
-  external ffi.Pointer<
-          ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_mutex>)>>
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<sqlite3_mutex>)>>
       xMutexNotheld;
 }
 
@@ -11344,11 +11356,11 @@
   external ffi.Pointer<ffi.Void> pArg;
 
   external ffi
-          .Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<ffi.Void>)>>
+      .Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<ffi.Void>)>>
       xInit;
 
   external ffi
-          .Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+      .Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
       xShutdown;
 
   external ffi.Pointer<
@@ -11400,11 +11412,11 @@
   external ffi.Pointer<ffi.Void> pArg;
 
   external ffi
-          .Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<ffi.Void>)>>
+      .Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<ffi.Void>)>>
       xInit;
 
   external ffi
-          .Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+      .Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
       xShutdown;
 
   external ffi.Pointer<
@@ -11489,7 +11501,7 @@
 
   /// Called by SQLite to clean up pUser
   external ffi
-          .Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+      .Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
       xDelUser;
 }
 
@@ -11518,7 +11530,7 @@
 
   /// function to free pUser
   external ffi
-          .Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+      .Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
       xDelUser;
 
   /// Coordinates of node or entry to check
@@ -11781,8 +11793,8 @@
       ffi.NativeFunction<
           ffi.Pointer<ffi.Void> Function(ffi.Pointer<Fts5Context>)>> xUserData;
 
-  external ffi.Pointer<
-          ffi.NativeFunction<ffi.Int Function(ffi.Pointer<Fts5Context>)>>
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<Fts5Context>)>>
       xColumnCount;
 
   external ffi.Pointer<
@@ -11812,13 +11824,14 @@
                           ffi.Int,
                           ffi.Int)>>)>> xTokenize;
 
-  external ffi.Pointer<
-          ffi.NativeFunction<ffi.Int Function(ffi.Pointer<Fts5Context>)>>
+  external ffi
+      .Pointer<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<Fts5Context>)>>
       xPhraseCount;
 
   external ffi.Pointer<
-      ffi.NativeFunction<
-          ffi.Int Function(ffi.Pointer<Fts5Context>, ffi.Int)>> xPhraseSize;
+          ffi
+          .NativeFunction<ffi.Int Function(ffi.Pointer<Fts5Context>, ffi.Int)>>
+      xPhraseSize;
 
   external ffi.Pointer<
           ffi.NativeFunction<
@@ -11968,8 +11981,8 @@
               ffi.Pointer<ffi.Void> pContext,
               ffi.Pointer<fts5_tokenizer> pTokenizer,
               ffi.Pointer<
-                      ffi.NativeFunction<
-                          ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+                      ffi
+                      .NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
                   xDestroy)>> xCreateTokenizer;
 
   /// Find an existing tokenizer
@@ -11990,8 +12003,8 @@
               ffi.Pointer<ffi.Void> pContext,
               fts5_extension_function xFunction,
               ffi.Pointer<
-                      ffi.NativeFunction<
-                          ffi.Void Function(ffi.Pointer<ffi.Void>)>>
+                      ffi
+                      .NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
                   xDestroy)>> xCreateFunction;
 }
 
diff --git a/pkgs/ffigen/test/native_objc_test/block_test.dart b/pkgs/ffigen/test/native_objc_test/block_test.dart
index 76f7a93..87a735a 100644
--- a/pkgs/ffigen/test/native_objc_test/block_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/block_test.dart
@@ -5,6 +5,7 @@
 // Objective C support is only available on mac.
 @TestOn('mac-os')
 
+import 'dart:async';
 import 'dart:ffi';
 import 'dart:io';
 
@@ -51,7 +52,7 @@
     });
 
     test('Block from function pointer', () {
-      final block = ObjCBlock.fromFunctionPointer(
+      final block = ObjCBlock1.fromFunctionPointer(
           lib, Pointer.fromFunction(_add100, 999));
       final blockTester = BlockTester.makeFromBlock_(lib, block);
       blockTester.pokeBlock();
@@ -64,15 +65,52 @@
     }
 
     test('Block from function', () {
-      final block = ObjCBlock.fromFunction(lib, makeAdder(4000));
+      final block = ObjCBlock1.fromFunction(lib, makeAdder(4000));
       final blockTester = BlockTester.makeFromBlock_(lib, block);
       blockTester.pokeBlock();
       expect(blockTester.call_(123), 4123);
       expect(block(123), 4123);
     });
 
+    test('Listener block same thread', () async {
+      final hasRun = Completer();
+      int value = 0;
+      final block = ObjCBlock.listener(lib, () {
+        value = 123;
+        hasRun.complete();
+      });
+
+      BlockTester.callOnSameThread_(lib, block);
+
+      await hasRun.future;
+      expect(value, 123);
+    });
+
+    test('Listener block new thread', () async {
+      final hasRun = Completer();
+      int value = 0;
+      final block = ObjCBlock.listener(lib, () {
+        value = 123;
+        hasRun.complete();
+      });
+
+      final thread = BlockTester.callOnNewThread_(lib, block);
+      thread.start();
+
+      await hasRun.future;
+      expect(value, 123);
+    });
+
+    test('Float block', () {
+      final block = ObjCBlock2.fromFunction(lib, (double x) {
+        return x + 4.56;
+      });
+      expect(block(1.23), closeTo(5.79, 1e-6));
+      expect(BlockTester.callFloatBlock_(lib, block), closeTo(5.79, 1e-6));
+    });
+
     Pointer<Void> funcPointerBlockRefCountTest() {
-      final block = ObjCBlock.fromFunctionPointer(
+      final block = ObjCBlock1.fromFunctionPointer(
           lib, Pointer.fromFunction(_add100, 999));
       expect(BlockTester.getBlockRetainCount_(lib, block.pointer.cast()), 1);
       return block.pointer.cast();
@@ -85,7 +123,7 @@
     });
 
     Pointer<Void> funcBlockRefCountTest() {
-      final block = ObjCBlock.fromFunction(lib, makeAdder(4000));
+      final block = ObjCBlock1.fromFunction(lib, makeAdder(4000));
       expect(BlockTester.getBlockRetainCount_(lib, block.pointer.cast()), 1);
       return block.pointer.cast();
     }
@@ -97,7 +135,7 @@
     });
 
     test('Block fields have sensible values', () {
-      final block = ObjCBlock.fromFunction(lib, makeAdder(4000));
+      final block = ObjCBlock1.fromFunction(lib, makeAdder(4000));
       final blockPtr = block.pointer;
       expect(blockPtr.ref.isa, isNot(0));
       expect(blockPtr.ref.flags, isNot(0)); // Set by Block_copy.
diff --git a/pkgs/ffigen/test/native_objc_test/block_test.m b/pkgs/ffigen/test/native_objc_test/block_test.m
index bdd37a7..9e619b6 100644
--- a/pkgs/ffigen/test/native_objc_test/block_test.m
+++ b/pkgs/ffigen/test/native_objc_test/block_test.m
@@ -3,8 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #import <Foundation/NSObject.h>
+#import <Foundation/NSThread.h>
 
 typedef int32_t (^IntBlock)(int32_t);
+typedef float (^FloatBlock)(float);
+typedef void (^VoidBlock)();
 
 // Wrapper around a block, so that our Dart code can test creating and invoking
 // blocks in Objective C code.
@@ -17,6 +20,9 @@
 - (int32_t)call:(int32_t)x;
 - (IntBlock)getBlock;
 - (void)pokeBlock;
++ (void)callOnSameThread:(VoidBlock)block;
++ (NSThread*)callOnNewThread:(VoidBlock)block;
++ (float)callFloatBlock:(FloatBlock)block;
 @end
 
 @implementation BlockTester
@@ -73,4 +79,17 @@
   // Used to repro https://github.com/dart-lang/ffigen/issues/376
   [[myBlock retain] release];
 }
+
++ (void)callOnSameThread:(VoidBlock)block {
+  block();
+}
+
++ (NSThread*)callOnNewThread:(VoidBlock)block {
+  return [[NSThread alloc] initWithBlock: block];
+}
+
++ (float)callFloatBlock:(FloatBlock)block {
+  return block(1.23);
+}
+
 @end
diff --git a/pkgs/ffigen/test/native_objc_test/setup.dart b/pkgs/ffigen/test/native_objc_test/setup.dart
index 5eff12c..8e74d87 100644
--- a/pkgs/ffigen/test/native_objc_test/setup.dart
+++ b/pkgs/ffigen/test/native_objc_test/setup.dart
@@ -119,6 +119,8 @@
 }
 
 Future<void> main(List<String> arguments) async {
+  // Allow running this script directly from any path (or an IDE).
+  Directory.current = Platform.script.resolve('.').toFilePath();
   if (!Platform.isMacOS) {
     throw OSError('Objective C tests are only supported on MacOS');
   }