[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