[ffigen] Initialize the Block isa field (#378)

diff --git a/pkgs/ffigen/lib/src/code_generator/objc_block.dart b/pkgs/ffigen/lib/src/code_generator/objc_block.dart
index 04f4c0b..63ce7fd 100644
--- a/pkgs/ffigen/lib/src/code_generator/objc_block.dart
+++ b/pkgs/ffigen/lib/src/code_generator/objc_block.dart
@@ -97,6 +97,7 @@
     builtInFunctions.newBlockDesc.addDependencies(dependencies);
     builtInFunctions.blockDescSingleton.addDependencies(dependencies);
     builtInFunctions.blockStruct.addDependencies(dependencies);
+    builtInFunctions.concreteGlobalBlock.addDependencies(dependencies);
     builtInFunctions.newBlock.addDependencies(dependencies);
   }
 
diff --git a/pkgs/ffigen/lib/src/code_generator/objc_built_in_functions.dart b/pkgs/ffigen/lib/src/code_generator/objc_built_in_functions.dart
index 2c2644e..a92dbcb 100644
--- a/pkgs/ffigen/lib/src/code_generator/objc_built_in_functions.dart
+++ b/pkgs/ffigen/lib/src/code_generator/objc_built_in_functions.dart
@@ -142,6 +142,11 @@
     (Writer w) => '${newBlockDesc.name}()',
     blockDescStruct,
   );
+  late final concreteGlobalBlock = ObjCInternalGlobal(
+    '_objc_concrete_global_block',
+    (Writer w) => '${w.lookupFuncIdentifier}<${voidType.getCType(w)}>('
+        "'_NSConcreteGlobalBlock')",
+  );
   late final newBlock =
       ObjCInternalFunction('_newBlock', null, (Writer w, String name) {
     final s = StringBuffer();
@@ -151,6 +156,7 @@
     s.write('\n$blockPtr $name($voidPtr invoke, $voidPtr target) {\n');
     s.write('  final b = ${w.ffiPkgLibraryPrefix}.calloc.allocate<$blockType>('
         '${w.ffiLibraryPrefix}.sizeOf<$blockType>());\n');
+    s.write('  b.ref.isa = ${concreteGlobalBlock.name};\n');
     s.write('  b.ref.invoke = invoke;\n');
     s.write('  b.ref.target = target;\n');
     s.write('  b.ref.descriptor = ${blockDescSingleton.name};\n');
diff --git a/pkgs/ffigen/test/native_objc_test/block_test.dart b/pkgs/ffigen/test/native_objc_test/block_test.dart
index 188da1d..32ac72d 100644
--- a/pkgs/ffigen/test/native_objc_test/block_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/block_test.dart
@@ -32,6 +32,7 @@
       expect(blockTester.call_(123), 1230);
       final intBlock = blockTester.getBlock();
       final blockTester2 = BlockTester.makeFromBlock_(lib, intBlock);
+      blockTester2.pokeBlock();
       expect(blockTester2.call_(456), 4560);
     });
 
@@ -39,6 +40,7 @@
       final block = ObjCBlock.fromFunctionPointer(
           lib, Pointer.fromFunction(_add100, 999));
       final blockTester = BlockTester.makeFromBlock_(lib, block.pointer);
+      blockTester.pokeBlock();
       expect(blockTester.call_(123), 223);
     });
   });
diff --git a/pkgs/ffigen/test/native_objc_test/block_test.m b/pkgs/ffigen/test/native_objc_test/block_test.m
index 43d6a2c..7d17080 100644
--- a/pkgs/ffigen/test/native_objc_test/block_test.m
+++ b/pkgs/ffigen/test/native_objc_test/block_test.m
@@ -15,6 +15,7 @@
 + (BlockTester*)makeFromMultiplier:(int32_t)mult;
 - (int32_t)call:(int32_t)x;
 - (IntBlock)getBlock;
+- (void)pokeBlock;
 @end
 
 @implementation BlockTester
@@ -33,10 +34,15 @@
 }
 
 - (int32_t)call:(int32_t)x {
-  return self->myBlock(x);
+  return myBlock(x);
 }
 
 - (IntBlock)getBlock {
-  return self->myBlock;
+  return myBlock;
+}
+
+- (void)pokeBlock {
+  // Used to repro https://github.com/dart-lang/ffigen/issues/376
+  [[myBlock retain] release];
 }
 @end