Skip to content

Commit d407f6c

Browse files
committed
Merge branch 'main' into in-hook-caching
2 parents 8281a87 + 4af11a0 commit d407f6c

File tree

126 files changed

+2023
-930
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

126 files changed

+2023
-930
lines changed

.github/workflows/jnigen.yaml

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ jobs:
8484
- uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
8585
with:
8686
distribution: 'zulu'
87-
java-version: '11'
87+
java-version: '17'
8888
cache: maven
8989
## Committed bindings are formatted with clang-format.
9090
## So this is required to format generated bindings identically
@@ -135,7 +135,7 @@ jobs:
135135
- uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
136136
with:
137137
distribution: 'zulu'
138-
java-version: '11'
138+
java-version: '17'
139139
- uses: axel-op/googlejavaformat-action@fe78db8a90171b6a836449f8d0e982d5d71e5c5a
140140
name: 'Check Java formatting with google-java-format'
141141
with:
@@ -173,7 +173,7 @@ jobs:
173173
- uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
174174
with:
175175
distribution: 'zulu'
176-
java-version: '11'
176+
java-version: '17'
177177
- run: |
178178
sudo apt-get update -y
179179
sudo apt-get install -y ninja-build libgtk-3-dev libclang-dev
@@ -222,7 +222,7 @@ jobs:
222222
- uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
223223
with:
224224
distribution: 'zulu'
225-
java-version: '11'
225+
java-version: '17'
226226
- run: Add-Content $env:GITHUB_PATH "$env:JAVA_HOME\bin\server"
227227
- run: dart pub get
228228
- run: dart run jni:setup
@@ -249,7 +249,7 @@ jobs:
249249
- uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
250250
with:
251251
distribution: 'zulu'
252-
java-version: '11'
252+
java-version: '17'
253253
- run: git config --global core.autocrlf true
254254
- run: Add-Content $env:GITHUB_PATH "$env:JAVA_HOME\bin\server"
255255
- run: dart pub get
@@ -275,7 +275,7 @@ jobs:
275275
- uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
276276
with:
277277
distribution: 'temurin'
278-
java-version: '11'
278+
java-version: '17'
279279
- run: dart pub get
280280
- run: dart run jni:setup
281281
- run: dart test --test-randomize-ordering-seed random
@@ -300,7 +300,7 @@ jobs:
300300
- uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
301301
with:
302302
distribution: 'temurin'
303-
java-version: '11'
303+
java-version: '17'
304304
- run: git config --global core.autocrlf true
305305
- run: dart pub get
306306
- name: Build summarizer
@@ -323,7 +323,7 @@ jobs:
323323
- uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
324324
with:
325325
distribution: 'zulu'
326-
java-version: '11'
326+
java-version: '17'
327327
- run: |
328328
sudo apt-get update -y
329329
sudo apt-get install -y ninja-build libgtk-3-dev
@@ -347,7 +347,7 @@ jobs:
347347
- uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
348348
with:
349349
distribution: 'zulu'
350-
java-version: '11'
350+
java-version: '17'
351351
- run: flutter config --enable-windows-desktop
352352
- run: flutter pub get
353353
- run: flutter build windows
@@ -362,7 +362,7 @@ jobs:
362362
- uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
363363
with:
364364
distribution: 'zulu'
365-
java-version: '11'
365+
java-version: '17'
366366
- uses: subosito/flutter-action@44ac965b96f18d999802d4b807e3256d5a3f9fa1
367367
with:
368368
channel: 'stable'
@@ -386,7 +386,7 @@ jobs:
386386
- uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
387387
with:
388388
distribution: 'zulu'
389-
java-version: '11'
389+
java-version: '17'
390390
- run: |
391391
sudo apt-get update -y
392392
sudo apt-get install -y ninja-build libgtk-3-dev clang-format

pkgs/ffigen/CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
## 14.1.0-wip
2+
3+
- Dedupe `ObjCBlock` trampolines to reduce generated ObjC code.
4+
5+
## 14.0.1
6+
7+
- Fix bug with nullable types in `ObjCBlock`'s type arguments:
8+
https://github.com/dart-lang/native/issues/1537
9+
- Fix a path normalization bug: https://github.com/dart-lang/native/issues/1543
10+
111
## 14.0.0
212

313
- Create a public facing API for ffigen that can be invoked as a library:

pkgs/ffigen/lib/src/code_generator/library.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ class Library {
2020
/// List of bindings in this library.
2121
late List<Binding> bindings;
2222

23+
final ObjCBuiltInFunctions? objCBuiltInFunctions;
24+
2325
late Writer _writer;
2426
Writer get writer => _writer;
2527

@@ -34,6 +36,7 @@ class Library {
3436
List<LibraryImport>? libraryImports,
3537
bool silenceEnumWarning = false,
3638
List<String> nativeEntryPoints = const <String>[],
39+
this.objCBuiltInFunctions,
3740
}) {
3841
_findBindings(bindings, sort);
3942

@@ -103,6 +106,7 @@ class Library {
103106
for (final b in original) {
104107
b.addDependencies(dependencies);
105108
}
109+
objCBuiltInFunctions?.addDependencies(dependencies);
106110

107111
/// Save bindings.
108112
bindings = dependencies.toList();

pkgs/ffigen/lib/src/code_generator/objc_block.dart

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,23 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import '../code_generator.dart';
6-
import '../config_provider/config_types.dart';
76
import '../header_parser/data.dart' show bindingsIndex;
87

98
import 'binding_string.dart';
109
import 'writer.dart';
1110

1211
class ObjCBlock extends BindingType {
12+
final ObjCBuiltInFunctions builtInFunctions;
1313
final Type returnType;
1414
final List<Parameter> params;
1515
final bool returnsRetained;
16-
Func? _wrapListenerBlock;
16+
ObjCListenerBlockTrampoline? _wrapListenerBlock;
1717

1818
factory ObjCBlock({
1919
required Type returnType,
2020
required List<Parameter> params,
2121
required bool returnsRetained,
22+
required ObjCBuiltInFunctions builtInFunctions,
2223
}) {
2324
final usr = _getBlockUsr(returnType, params, returnsRetained);
2425

@@ -33,6 +34,7 @@ class ObjCBlock extends BindingType {
3334
returnType: returnType,
3435
params: params,
3536
returnsRetained: returnsRetained,
37+
builtInFunctions: builtInFunctions,
3638
);
3739
bindingsIndex.addObjCBlockToSeen(usr, block);
3840

@@ -45,6 +47,7 @@ class ObjCBlock extends BindingType {
4547
required this.returnType,
4648
required this.params,
4749
required this.returnsRetained,
50+
required this.builtInFunctions,
4851
}) : super(originalName: name);
4952

5053
// Generates a human readable name for the block based on the args and return
@@ -213,7 +216,7 @@ abstract final class $name {
213216
);
214217
final listenerConvFn =
215218
'($paramsFfiDartType) => $listenerConvFnInvocation';
216-
final wrapFn = _wrapListenerBlock?.name;
219+
final wrapFn = _wrapListenerBlock?.func.name;
217220
final releaseFn = ObjCBuiltInFunctions.objectRelease.gen(w);
218221

219222
s.write('''
@@ -278,7 +281,8 @@ ref.pointer.ref.invoke.cast<$natTrampFnType>().asFunction<$trampFuncFfiDartType>
278281

279282
@override
280283
BindingString? toObjCBindingString(Writer w) {
281-
if (_wrapListenerBlock == null) return null;
284+
if (_wrapListenerBlock?.objCBindingsGenerated ?? true) return null;
285+
_wrapListenerBlock!.objCBindingsGenerated = true;
282286

283287
final argsReceived = <String>[];
284288
final retains = <String>[];
@@ -288,15 +292,17 @@ ref.pointer.ref.invoke.cast<$natTrampFnType>().asFunction<$trampFuncFfiDartType>
288292
argsReceived.add(param.getNativeType(varName: argName));
289293
retains.add(param.type.generateRetain(argName) ?? argName);
290294
}
291-
final fnName = _wrapListenerBlock!.name;
292-
final blockTypedef = w.objCLevelUniqueNamer.makeUnique('ListenerBlock');
295+
final argStr = argsReceived.join(', ');
296+
final fnName = _wrapListenerBlock!.func.name;
297+
final blockName = w.objCLevelUniqueNamer.makeUnique('_ListenerTrampoline');
298+
final blockTypedef = '${returnType.getNativeType()} (^$blockName)($argStr)';
293299

294300
final s = StringBuffer();
295301
s.write('''
296302
297-
typedef ${getNativeType(varName: blockTypedef)};
298-
$blockTypedef $fnName($blockTypedef block) NS_RETURNS_RETAINED {
299-
return ^void(${argsReceived.join(', ')}) {
303+
typedef $blockTypedef;
304+
$blockName $fnName($blockName block) NS_RETURNS_RETAINED {
305+
return ^void($argStr) {
300306
block(${retains.join(', ')});
301307
};
302308
}
@@ -315,17 +321,8 @@ $blockTypedef $fnName($blockTypedef block) NS_RETURNS_RETAINED {
315321
p.type.addDependencies(dependencies);
316322
}
317323

318-
if (hasListener && params.any((p) => p.type.generateRetain('') != null)) {
319-
_wrapListenerBlock = Func(
320-
name: 'wrapListenerBlock_$name',
321-
returnType: this,
322-
parameters: [Parameter(name: 'block', type: this, objCConsumed: false)],
323-
objCReturnsRetained: true,
324-
isLeaf: true,
325-
isInternal: true,
326-
useNameForLookup: true,
327-
ffiNativeConfig: const FfiNativeConfig(enabled: true),
328-
)..addDependencies(dependencies);
324+
if (hasListener) {
325+
_wrapListenerBlock = builtInFunctions.getListenerBlockTrampoline(this);
329326
}
330327
}
331328

@@ -342,10 +339,7 @@ $blockTypedef $fnName($blockTypedef block) NS_RETURNS_RETAINED {
342339
String getObjCBlockSignatureType(Writer w) => getDartType(w);
343340

344341
@override
345-
String getNativeType({String varName = ''}) {
346-
final paramStrs = params.map<String>((p) => p.getNativeType());
347-
return '${returnType.getNativeType()} (^$varName)(${paramStrs.join(', ')})';
348-
}
342+
String getNativeType({String varName = ''}) => 'id $varName';
349343

350344
@override
351345
bool get sameFfiDartAndCType => true;

pkgs/ffigen/lib/src/code_generator/objc_built_in_functions.dart

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import '../code_generator.dart';
6+
import '../config_provider/config_types.dart';
67

78
import 'binding_string.dart';
89
import 'writer.dart';
@@ -12,6 +13,7 @@ class ObjCBuiltInFunctions {
1213
ObjCBuiltInFunctions(this.generateForPackageObjectiveC);
1314

1415
final bool generateForPackageObjectiveC;
16+
var _depsAdded = false;
1517

1618
static const registerName = ObjCImport('registerName');
1719
static const getClass = ObjCImport('getClass');
@@ -116,6 +118,7 @@ class ObjCBuiltInFunctions {
116118
// for float return types we need objc_msgSend_fpret.
117119
final _msgSendFuncs = <String, ObjCMsgSendFunc>{};
118120
ObjCMsgSendFunc getMsgSendFunc(Type returnType, List<Parameter> params) {
121+
assert(!_depsAdded);
119122
var key = returnType.cacheKey();
120123
for (final p in params) {
121124
key += ' ${p.type.cacheKey()}';
@@ -129,19 +132,63 @@ class ObjCBuiltInFunctions {
129132

130133
final _selObjects = <String, ObjCInternalGlobal>{};
131134
ObjCInternalGlobal getSelObject(String methodName) {
135+
assert(!_depsAdded);
132136
return _selObjects[methodName] ??= ObjCInternalGlobal(
133137
'_sel_${methodName.replaceAll(":", "_")}',
134138
(Writer w) => '${registerName.gen(w)}("$methodName")',
135139
);
136140
}
137141

142+
final _blockTrampolines = <String, ObjCListenerBlockTrampoline>{};
143+
ObjCListenerBlockTrampoline? getListenerBlockTrampoline(ObjCBlock block) {
144+
assert(!_depsAdded);
145+
146+
var needsTrampoline = false;
147+
final paramIds = <String>[];
148+
for (final param in block.params) {
149+
final retainFunc = param.type.generateRetain('');
150+
if (retainFunc != null) {
151+
needsTrampoline = true;
152+
}
153+
154+
// The trampoline ID is based on the getNativeType of the param. Objects
155+
// and blocks both have `id` as their native type, but need separate
156+
// trampolines since they have different retain functions. So add the
157+
// retainFunc (if any) to all the param IDs.
158+
paramIds.add('${param.getNativeType()}-${retainFunc ?? ''}');
159+
}
160+
if (!needsTrampoline) return null;
161+
final id = paramIds.join(',');
162+
163+
return _blockTrampolines[id] ??= ObjCListenerBlockTrampoline(Func(
164+
name: '_wrapListenerBlock_${id.hashCode.toRadixString(16)}',
165+
returnType: PointerType(objCBlockType),
166+
parameters: [
167+
Parameter(
168+
name: 'block',
169+
type: PointerType(objCBlockType),
170+
objCConsumed: false)
171+
],
172+
objCReturnsRetained: true,
173+
isLeaf: true,
174+
isInternal: true,
175+
useNameForLookup: true,
176+
ffiNativeConfig: const FfiNativeConfig(enabled: true),
177+
));
178+
}
179+
138180
void addDependencies(Set<Binding> dependencies) {
181+
if (_depsAdded) return;
182+
_depsAdded = true;
139183
for (final msgSendFunc in _msgSendFuncs.values) {
140184
msgSendFunc.addDependencies(dependencies);
141185
}
142186
for (final sel in _selObjects.values) {
143187
sel.addDependencies(dependencies);
144188
}
189+
for (final tramp in _blockTrampolines.values) {
190+
tramp.func.addDependencies(dependencies);
191+
}
145192
}
146193

147194
static bool isInstanceType(Type type) {
@@ -151,6 +198,13 @@ class ObjCBuiltInFunctions {
151198
}
152199
}
153200

201+
/// A native trampoline function for a listener block.
202+
class ObjCListenerBlockTrampoline {
203+
final Func func;
204+
bool objCBindingsGenerated = false;
205+
ObjCListenerBlockTrampoline(this.func);
206+
}
207+
154208
/// A function, global variable, or helper type defined in package:objective_c.
155209
class ObjCImport {
156210
final String name;

pkgs/ffigen/lib/src/code_generator/objc_interface.dart

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -256,8 +256,6 @@ class ObjCInterface extends BindingType with ObjCMethods {
256256
// Add dependencies for any methods that were added.
257257
addMethodDependencies(dependencies, needMsgSend: true);
258258
}
259-
260-
builtInFunctions.addDependencies(dependencies);
261259
}
262260

263261
void _copyMethodsFromSuperType() {
@@ -318,7 +316,7 @@ class ObjCInterface extends BindingType with ObjCMethods {
318316
_isBuiltIn ? '${w.objcPkgPrefix}.$name' : name;
319317

320318
@override
321-
String getNativeType({String varName = ''}) => '$originalName* $varName';
319+
String getNativeType({String varName = ''}) => 'id $varName';
322320

323321
@override
324322
String getObjCBlockSignatureType(Writer w) => getDartType(w);

pkgs/ffigen/lib/src/code_generator/objc_methods.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ class ObjCMethod {
225225
...params,
226226
],
227227
returnsRetained: returnsRetained,
228+
builtInFunctions: builtInFunctions,
228229
)..addDependencies(dependencies);
229230
}
230231
}

pkgs/ffigen/lib/src/code_generator/objc_nullable.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ class ObjCNullable extends Type {
4040
String getNativeType({String varName = ''}) =>
4141
child.getNativeType(varName: varName);
4242

43+
@override
44+
String getObjCBlockSignatureType(Writer w) =>
45+
'${child.getObjCBlockSignatureType(w)}?';
46+
4347
@override
4448
bool get sameFfiDartAndCType => child.sameFfiDartAndCType;
4549

0 commit comments

Comments
 (0)