Skip to content

Commit

Permalink
Merge branch 'main' into in-hook-caching
Browse files Browse the repository at this point in the history
  • Loading branch information
dcharkes committed Sep 13, 2024
2 parents 8281a87 + 4af11a0 commit d407f6c
Show file tree
Hide file tree
Showing 126 changed files with 2,023 additions and 930 deletions.
22 changes: 11 additions & 11 deletions .github/workflows/jnigen.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ jobs:
- uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
with:
distribution: 'zulu'
java-version: '11'
java-version: '17'
cache: maven
## Committed bindings are formatted with clang-format.
## So this is required to format generated bindings identically
Expand Down Expand Up @@ -135,7 +135,7 @@ jobs:
- uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
with:
distribution: 'zulu'
java-version: '11'
java-version: '17'
- uses: axel-op/googlejavaformat-action@fe78db8a90171b6a836449f8d0e982d5d71e5c5a
name: 'Check Java formatting with google-java-format'
with:
Expand Down Expand Up @@ -173,7 +173,7 @@ jobs:
- uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
with:
distribution: 'zulu'
java-version: '11'
java-version: '17'
- run: |
sudo apt-get update -y
sudo apt-get install -y ninja-build libgtk-3-dev libclang-dev
Expand Down Expand Up @@ -222,7 +222,7 @@ jobs:
- uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
with:
distribution: 'zulu'
java-version: '11'
java-version: '17'
- run: Add-Content $env:GITHUB_PATH "$env:JAVA_HOME\bin\server"
- run: dart pub get
- run: dart run jni:setup
Expand All @@ -249,7 +249,7 @@ jobs:
- uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
with:
distribution: 'zulu'
java-version: '11'
java-version: '17'
- run: git config --global core.autocrlf true
- run: Add-Content $env:GITHUB_PATH "$env:JAVA_HOME\bin\server"
- run: dart pub get
Expand All @@ -275,7 +275,7 @@ jobs:
- uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
with:
distribution: 'temurin'
java-version: '11'
java-version: '17'
- run: dart pub get
- run: dart run jni:setup
- run: dart test --test-randomize-ordering-seed random
Expand All @@ -300,7 +300,7 @@ jobs:
- uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
with:
distribution: 'temurin'
java-version: '11'
java-version: '17'
- run: git config --global core.autocrlf true
- run: dart pub get
- name: Build summarizer
Expand All @@ -323,7 +323,7 @@ jobs:
- uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
with:
distribution: 'zulu'
java-version: '11'
java-version: '17'
- run: |
sudo apt-get update -y
sudo apt-get install -y ninja-build libgtk-3-dev
Expand All @@ -347,7 +347,7 @@ jobs:
- uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
with:
distribution: 'zulu'
java-version: '11'
java-version: '17'
- run: flutter config --enable-windows-desktop
- run: flutter pub get
- run: flutter build windows
Expand All @@ -362,7 +362,7 @@ jobs:
- uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
with:
distribution: 'zulu'
java-version: '11'
java-version: '17'
- uses: subosito/flutter-action@44ac965b96f18d999802d4b807e3256d5a3f9fa1
with:
channel: 'stable'
Expand All @@ -386,7 +386,7 @@ jobs:
- uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
with:
distribution: 'zulu'
java-version: '11'
java-version: '17'
- run: |
sudo apt-get update -y
sudo apt-get install -y ninja-build libgtk-3-dev clang-format
Expand Down
10 changes: 10 additions & 0 deletions pkgs/ffigen/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
## 14.1.0-wip

- Dedupe `ObjCBlock` trampolines to reduce generated ObjC code.

## 14.0.1

- Fix bug with nullable types in `ObjCBlock`'s type arguments:
https://github.com/dart-lang/native/issues/1537
- Fix a path normalization bug: https://github.com/dart-lang/native/issues/1543

## 14.0.0

- Create a public facing API for ffigen that can be invoked as a library:
Expand Down
4 changes: 4 additions & 0 deletions pkgs/ffigen/lib/src/code_generator/library.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class Library {
/// List of bindings in this library.
late List<Binding> bindings;

final ObjCBuiltInFunctions? objCBuiltInFunctions;

late Writer _writer;
Writer get writer => _writer;

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

Expand Down Expand Up @@ -103,6 +106,7 @@ class Library {
for (final b in original) {
b.addDependencies(dependencies);
}
objCBuiltInFunctions?.addDependencies(dependencies);

/// Save bindings.
bindings = dependencies.toList();
Expand Down
42 changes: 18 additions & 24 deletions pkgs/ffigen/lib/src/code_generator/objc_block.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,23 @@
// BSD-style license that can be found in the LICENSE file.

import '../code_generator.dart';
import '../config_provider/config_types.dart';
import '../header_parser/data.dart' show bindingsIndex;

import 'binding_string.dart';
import 'writer.dart';

class ObjCBlock extends BindingType {
final ObjCBuiltInFunctions builtInFunctions;
final Type returnType;
final List<Parameter> params;
final bool returnsRetained;
Func? _wrapListenerBlock;
ObjCListenerBlockTrampoline? _wrapListenerBlock;

factory ObjCBlock({
required Type returnType,
required List<Parameter> params,
required bool returnsRetained,
required ObjCBuiltInFunctions builtInFunctions,
}) {
final usr = _getBlockUsr(returnType, params, returnsRetained);

Expand All @@ -33,6 +34,7 @@ class ObjCBlock extends BindingType {
returnType: returnType,
params: params,
returnsRetained: returnsRetained,
builtInFunctions: builtInFunctions,
);
bindingsIndex.addObjCBlockToSeen(usr, block);

Expand All @@ -45,6 +47,7 @@ class ObjCBlock extends BindingType {
required this.returnType,
required this.params,
required this.returnsRetained,
required this.builtInFunctions,
}) : super(originalName: name);

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

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

@override
BindingString? toObjCBindingString(Writer w) {
if (_wrapListenerBlock == null) return null;
if (_wrapListenerBlock?.objCBindingsGenerated ?? true) return null;
_wrapListenerBlock!.objCBindingsGenerated = true;

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

final s = StringBuffer();
s.write('''
typedef ${getNativeType(varName: blockTypedef)};
$blockTypedef $fnName($blockTypedef block) NS_RETURNS_RETAINED {
return ^void(${argsReceived.join(', ')}) {
typedef $blockTypedef;
$blockName $fnName($blockName block) NS_RETURNS_RETAINED {
return ^void($argStr) {
block(${retains.join(', ')});
};
}
Expand All @@ -315,17 +321,8 @@ $blockTypedef $fnName($blockTypedef block) NS_RETURNS_RETAINED {
p.type.addDependencies(dependencies);
}

if (hasListener && params.any((p) => p.type.generateRetain('') != null)) {
_wrapListenerBlock = Func(
name: 'wrapListenerBlock_$name',
returnType: this,
parameters: [Parameter(name: 'block', type: this, objCConsumed: false)],
objCReturnsRetained: true,
isLeaf: true,
isInternal: true,
useNameForLookup: true,
ffiNativeConfig: const FfiNativeConfig(enabled: true),
)..addDependencies(dependencies);
if (hasListener) {
_wrapListenerBlock = builtInFunctions.getListenerBlockTrampoline(this);
}
}

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

@override
String getNativeType({String varName = ''}) {
final paramStrs = params.map<String>((p) => p.getNativeType());
return '${returnType.getNativeType()} (^$varName)(${paramStrs.join(', ')})';
}
String getNativeType({String varName = ''}) => 'id $varName';

@override
bool get sameFfiDartAndCType => true;
Expand Down
54 changes: 54 additions & 0 deletions pkgs/ffigen/lib/src/code_generator/objc_built_in_functions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.

import '../code_generator.dart';
import '../config_provider/config_types.dart';

import 'binding_string.dart';
import 'writer.dart';
Expand All @@ -12,6 +13,7 @@ class ObjCBuiltInFunctions {
ObjCBuiltInFunctions(this.generateForPackageObjectiveC);

final bool generateForPackageObjectiveC;
var _depsAdded = false;

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

final _selObjects = <String, ObjCInternalGlobal>{};
ObjCInternalGlobal getSelObject(String methodName) {
assert(!_depsAdded);
return _selObjects[methodName] ??= ObjCInternalGlobal(
'_sel_${methodName.replaceAll(":", "_")}',
(Writer w) => '${registerName.gen(w)}("$methodName")',
);
}

final _blockTrampolines = <String, ObjCListenerBlockTrampoline>{};
ObjCListenerBlockTrampoline? getListenerBlockTrampoline(ObjCBlock block) {
assert(!_depsAdded);

var needsTrampoline = false;
final paramIds = <String>[];
for (final param in block.params) {
final retainFunc = param.type.generateRetain('');
if (retainFunc != null) {
needsTrampoline = true;
}

// The trampoline ID is based on the getNativeType of the param. Objects
// and blocks both have `id` as their native type, but need separate
// trampolines since they have different retain functions. So add the
// retainFunc (if any) to all the param IDs.
paramIds.add('${param.getNativeType()}-${retainFunc ?? ''}');
}
if (!needsTrampoline) return null;
final id = paramIds.join(',');

return _blockTrampolines[id] ??= ObjCListenerBlockTrampoline(Func(
name: '_wrapListenerBlock_${id.hashCode.toRadixString(16)}',
returnType: PointerType(objCBlockType),
parameters: [
Parameter(
name: 'block',
type: PointerType(objCBlockType),
objCConsumed: false)
],
objCReturnsRetained: true,
isLeaf: true,
isInternal: true,
useNameForLookup: true,
ffiNativeConfig: const FfiNativeConfig(enabled: true),
));
}

void addDependencies(Set<Binding> dependencies) {
if (_depsAdded) return;
_depsAdded = true;
for (final msgSendFunc in _msgSendFuncs.values) {
msgSendFunc.addDependencies(dependencies);
}
for (final sel in _selObjects.values) {
sel.addDependencies(dependencies);
}
for (final tramp in _blockTrampolines.values) {
tramp.func.addDependencies(dependencies);
}
}

static bool isInstanceType(Type type) {
Expand All @@ -151,6 +198,13 @@ class ObjCBuiltInFunctions {
}
}

/// A native trampoline function for a listener block.
class ObjCListenerBlockTrampoline {
final Func func;
bool objCBindingsGenerated = false;
ObjCListenerBlockTrampoline(this.func);
}

/// A function, global variable, or helper type defined in package:objective_c.
class ObjCImport {
final String name;
Expand Down
4 changes: 1 addition & 3 deletions pkgs/ffigen/lib/src/code_generator/objc_interface.dart
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,6 @@ class ObjCInterface extends BindingType with ObjCMethods {
// Add dependencies for any methods that were added.
addMethodDependencies(dependencies, needMsgSend: true);
}

builtInFunctions.addDependencies(dependencies);
}

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

@override
String getNativeType({String varName = ''}) => '$originalName* $varName';
String getNativeType({String varName = ''}) => 'id $varName';

@override
String getObjCBlockSignatureType(Writer w) => getDartType(w);
Expand Down
1 change: 1 addition & 0 deletions pkgs/ffigen/lib/src/code_generator/objc_methods.dart
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ class ObjCMethod {
...params,
],
returnsRetained: returnsRetained,
builtInFunctions: builtInFunctions,
)..addDependencies(dependencies);
}
}
Expand Down
4 changes: 4 additions & 0 deletions pkgs/ffigen/lib/src/code_generator/objc_nullable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ class ObjCNullable extends Type {
String getNativeType({String varName = ''}) =>
child.getNativeType(varName: varName);

@override
String getObjCBlockSignatureType(Writer w) =>
'${child.getObjCBlockSignatureType(w)}?';

@override
bool get sameFfiDartAndCType => child.sameFfiDartAndCType;

Expand Down
Loading

0 comments on commit d407f6c

Please sign in to comment.