mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 12:24:24 +00:00
Migrate pkg/vm to null safety, part 2
TEST=ci Issue: https://github.com/dart-lang/sdk/issues/46620 Change-Id: I18bab8755bfa937b6de07a738e3f22309240da22 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/207365 Commit-Queue: Alexander Markov <alexmarkov@google.com> Reviewed-by: Daco Harkes <dacoharkes@google.com> Reviewed-by: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
parent
b89c35472f
commit
3a96674d3d
13 changed files with 177 additions and 208 deletions
|
@ -1403,7 +1403,7 @@ class KernelDiagnosticReporter
|
|||
|
||||
KernelDiagnosticReporter(this.loader);
|
||||
|
||||
void report(Message message, int charOffset, int length, Uri fileUri,
|
||||
void report(Message message, int charOffset, int length, Uri? fileUri,
|
||||
{List<LocatedMessage>? context}) {
|
||||
loader.addProblem(message, charOffset, noLength, fileUri, context: context);
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ Target? getTarget(String name, TargetFlags flags) {
|
|||
}
|
||||
|
||||
abstract class DiagnosticReporter<M, C> {
|
||||
void report(M message, int charOffset, int length, Uri fileUri,
|
||||
void report(M message, int charOffset, int length, Uri? fileUri,
|
||||
{List<C> context});
|
||||
}
|
||||
|
||||
|
|
|
@ -2,18 +2,16 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart=2.9
|
||||
|
||||
class Vertex<T extends Vertex<T>> {
|
||||
// Input: vertices directly reachable from this vertex.
|
||||
final List<T> successors = <T>[];
|
||||
|
||||
// Output: the nearest vertex that all paths from the root must go through to
|
||||
// reach this vertex.
|
||||
T dominator;
|
||||
T? dominator;
|
||||
|
||||
bool isDominatedBy(T other) {
|
||||
var d = this;
|
||||
Vertex<T>? d = this;
|
||||
while (d != null) {
|
||||
if (d == other) {
|
||||
return true;
|
||||
|
@ -26,17 +24,17 @@ class Vertex<T extends Vertex<T>> {
|
|||
// Temporaries. See Lengauer and Tarjan.
|
||||
final List<T> _predecessors = <T>[];
|
||||
int _semi = 0;
|
||||
T _label;
|
||||
T _ancestor;
|
||||
T _parent;
|
||||
List<T> _bucket;
|
||||
T? _label;
|
||||
T? _ancestor;
|
||||
T? _parent;
|
||||
List<T>? _bucket;
|
||||
}
|
||||
|
||||
// T. Lengauer and R. E. Tarjan. "A Fast Algorithm for Finding Dominators
|
||||
// in a Flowgraph."
|
||||
computeDominators<T extends Vertex<T>>(T root) {
|
||||
// Lengauer and Tarjan Step 1.
|
||||
final vertex = <T>[];
|
||||
final vertex = <T?>[];
|
||||
vertex.add(null);
|
||||
|
||||
var n = 0;
|
||||
|
@ -60,33 +58,35 @@ computeDominators<T extends Vertex<T>>(T root) {
|
|||
dfs(root);
|
||||
|
||||
forestCompress(T v) {
|
||||
if (v._ancestor._ancestor != null) {
|
||||
forestCompress(v._ancestor);
|
||||
if (v._ancestor._label._semi < v._label._semi) {
|
||||
v._label = v._ancestor._label;
|
||||
T ancestor = v._ancestor!;
|
||||
if (ancestor._ancestor != null) {
|
||||
forestCompress(ancestor);
|
||||
ancestor = v._ancestor!;
|
||||
if (ancestor._label!._semi < v._label!._semi) {
|
||||
v._label = ancestor._label;
|
||||
}
|
||||
v._ancestor = v._ancestor._ancestor;
|
||||
v._ancestor = ancestor._ancestor;
|
||||
}
|
||||
}
|
||||
|
||||
forestEval(T v) {
|
||||
T forestEval(T v) {
|
||||
if (v._ancestor == null) {
|
||||
return v;
|
||||
} else {
|
||||
forestCompress(v);
|
||||
return v._label;
|
||||
return v._label!;
|
||||
}
|
||||
}
|
||||
|
||||
forestLink(T v, T w) {
|
||||
forestLink(T? v, T w) {
|
||||
w._ancestor = v;
|
||||
}
|
||||
|
||||
for (var i = vertex.length - 1; i > 1; i--) {
|
||||
Vertex<T> w = vertex[i];
|
||||
final T w = vertex[i]!;
|
||||
|
||||
// Lengauer and Tarjan Step 2.
|
||||
for (Vertex<T> v in w._predecessors) {
|
||||
for (T v in w._predecessors) {
|
||||
if (v._semi == 0) continue; // Unreachable
|
||||
|
||||
final u = forestEval(v);
|
||||
|
@ -95,7 +95,7 @@ computeDominators<T extends Vertex<T>>(T root) {
|
|||
}
|
||||
}
|
||||
|
||||
Vertex<T> z = vertex[w._semi];
|
||||
Vertex<T> z = vertex[w._semi]!;
|
||||
var b = z._bucket;
|
||||
if (b == null) {
|
||||
z._bucket = b = <T>[];
|
||||
|
@ -104,8 +104,7 @@ computeDominators<T extends Vertex<T>>(T root) {
|
|||
forestLink(w._parent, w);
|
||||
|
||||
// Lengauer and Tarjan Step 3.
|
||||
z = w._parent;
|
||||
assert(z != null);
|
||||
z = w._parent!;
|
||||
b = z._bucket;
|
||||
z._bucket = null;
|
||||
if (b != null) {
|
||||
|
@ -118,9 +117,9 @@ computeDominators<T extends Vertex<T>>(T root) {
|
|||
|
||||
// Lengauer and Tarjan Step 4.
|
||||
for (var i = 2; i < vertex.length; i++) {
|
||||
final w = vertex[i];
|
||||
final T w = vertex[i]!;
|
||||
if (w.dominator != vertex[w._semi]) {
|
||||
w.dominator = w.dominator.dominator;
|
||||
w.dominator = w.dominator!.dominator;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart=2.9
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:io' as io;
|
||||
|
||||
|
@ -66,7 +64,7 @@ class HttpFileSystemEntity implements FileSystemEntity {
|
|||
}
|
||||
|
||||
Future<T> connectAndRun<T>(Future<T> body(io.HttpClient httpClient)) async {
|
||||
io.HttpClient httpClient;
|
||||
io.HttpClient? httpClient;
|
||||
try {
|
||||
httpClient = new io.HttpClient();
|
||||
// Set timeout to be shorter than anticipated OS default
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart=2.9
|
||||
|
||||
library vm.transformations.deferred_loading;
|
||||
|
||||
import 'package:kernel/ast.dart';
|
||||
|
@ -11,15 +9,15 @@ import '../dominators.dart';
|
|||
import '../metadata/loading_units.dart';
|
||||
|
||||
class _LoadingUnitBuilder {
|
||||
int id;
|
||||
late int id;
|
||||
final _LibraryVertex root;
|
||||
final List<Library> members = <Library>[];
|
||||
final List<_LoadingUnitBuilder> children = <_LoadingUnitBuilder>[];
|
||||
|
||||
_LoadingUnitBuilder(this.root);
|
||||
|
||||
_LoadingUnitBuilder get parent => root.dominator?.loadingUnit;
|
||||
int get parentId => parent == null ? 0 : parent.id;
|
||||
_LoadingUnitBuilder? get parent => root.dominator?.loadingUnit;
|
||||
int get parentId => parent == null ? 0 : parent!.id;
|
||||
|
||||
LoadingUnit asLoadingUnit() {
|
||||
return new LoadingUnit(
|
||||
|
@ -33,7 +31,7 @@ class _LoadingUnitBuilder {
|
|||
class _LibraryVertex extends Vertex<_LibraryVertex> {
|
||||
final Library library;
|
||||
bool isLoadingRoot = true;
|
||||
_LoadingUnitBuilder loadingUnit;
|
||||
_LoadingUnitBuilder? loadingUnit;
|
||||
_LibraryVertex(this.library);
|
||||
|
||||
String toString() => "_LibraryVertex(${library.importUri})";
|
||||
|
@ -47,11 +45,11 @@ List<LoadingUnit> computeLoadingUnits(Component component) {
|
|||
}
|
||||
for (final vertex in map.values) {
|
||||
for (final dep in vertex.library.dependencies) {
|
||||
final target = map[dep.targetLibrary];
|
||||
final target = map[dep.targetLibrary]!;
|
||||
vertex.successors.add(target);
|
||||
}
|
||||
}
|
||||
final root = map[component.mainMethod.parent as Library];
|
||||
final root = map[component.mainMethod!.enclosingLibrary]!;
|
||||
|
||||
// Fake imports from root library to every core library so they end up in
|
||||
// the same loading unit attributed to the user's root library.
|
||||
|
@ -73,7 +71,7 @@ List<LoadingUnit> computeLoadingUnits(Component component) {
|
|||
if (dep.isDeferred) {
|
||||
continue;
|
||||
}
|
||||
var importee = map[dep.targetLibrary];
|
||||
var importee = map[dep.targetLibrary]!;
|
||||
if (importer.isDominatedBy(importee)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -82,7 +80,7 @@ List<LoadingUnit> computeLoadingUnits(Component component) {
|
|||
}
|
||||
assert(root.isLoadingRoot);
|
||||
|
||||
var loadingUnits = <_LoadingUnitBuilder>[];
|
||||
final List<_LoadingUnitBuilder> loadingUnits = <_LoadingUnitBuilder>[];
|
||||
for (var vertex in map.values) {
|
||||
if (vertex.isLoadingRoot) {
|
||||
var unit = new _LoadingUnitBuilder(vertex);
|
||||
|
@ -101,11 +99,11 @@ List<LoadingUnit> computeLoadingUnits(Component component) {
|
|||
if (dom == null) {
|
||||
continue; // Unreachable library.
|
||||
}
|
||||
while (dom.loadingUnit == null) {
|
||||
while (dom!.loadingUnit == null) {
|
||||
dom = dom.dominator;
|
||||
}
|
||||
vertex.loadingUnit = dom.loadingUnit;
|
||||
vertex.loadingUnit.members.add(vertex.library);
|
||||
vertex.loadingUnit!.members.add(vertex.library);
|
||||
}
|
||||
|
||||
// 4. Sort loading units so parents are before children. Normally this order
|
||||
|
@ -119,7 +117,7 @@ List<LoadingUnit> computeLoadingUnits(Component component) {
|
|||
}
|
||||
var index = 0;
|
||||
loadingUnits.clear();
|
||||
loadingUnits.add(root.loadingUnit);
|
||||
loadingUnits.add(root.loadingUnit!);
|
||||
while (index < loadingUnits.length) {
|
||||
var unit = loadingUnits[index];
|
||||
unit.id = ++index;
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart=2.9
|
||||
|
||||
library vm.transformations.cha_devirtualization;
|
||||
|
||||
import 'package:kernel/ast.dart';
|
||||
|
@ -18,7 +16,8 @@ import '../metadata/direct_call.dart';
|
|||
Component transformComponent(CoreTypes coreTypes, Component component) {
|
||||
void ignoreAmbiguousSupertypes(Class cls, Supertype a, Supertype b) {}
|
||||
ClosedWorldClassHierarchy hierarchy = new ClassHierarchy(component, coreTypes,
|
||||
onAmbiguousSupertypes: ignoreAmbiguousSupertypes);
|
||||
onAmbiguousSupertypes: ignoreAmbiguousSupertypes)
|
||||
as ClosedWorldClassHierarchy;
|
||||
final hierarchySubtypes = hierarchy.computeSubtypesInformation();
|
||||
new CHADevirtualization(coreTypes, component, hierarchy, hierarchySubtypes)
|
||||
.visitComponent(component);
|
||||
|
@ -34,14 +33,14 @@ abstract class Devirtualization extends RecursiveVisitor {
|
|||
static const _trace = const bool.fromEnvironment('trace.devirtualization');
|
||||
|
||||
final DirectCallMetadataRepository _metadata;
|
||||
Set<Name> _objectMemberNames;
|
||||
final Set<Name> _objectMemberNames;
|
||||
|
||||
Devirtualization(
|
||||
CoreTypes coreTypes, Component component, ClassHierarchy hierarchy)
|
||||
: _metadata = new DirectCallMetadataRepository() {
|
||||
_objectMemberNames = new Set<Name>.from(hierarchy
|
||||
.getInterfaceMembers(coreTypes.objectClass)
|
||||
.map((Member m) => m.name));
|
||||
: _metadata = new DirectCallMetadataRepository(),
|
||||
_objectMemberNames = new Set<Name>.from(hierarchy
|
||||
.getInterfaceMembers(coreTypes.objectClass)
|
||||
.map((Member m) => m.name)) {
|
||||
component.addMetadataRepository(_metadata);
|
||||
}
|
||||
|
||||
|
@ -51,7 +50,7 @@ abstract class Devirtualization extends RecursiveVisitor {
|
|||
(member is Field) || ((member is Procedure) && member.isGetter);
|
||||
|
||||
bool isLegalTargetForMethodInvocation(Member target, Arguments arguments) {
|
||||
final FunctionNode func = target.function;
|
||||
final FunctionNode func = target.function!;
|
||||
|
||||
final positionalArgs = arguments.positional.length;
|
||||
if ((positionalArgs < func.requiredParameterCount) ||
|
||||
|
@ -84,10 +83,10 @@ abstract class Devirtualization extends RecursiveVisitor {
|
|||
directCall.checkReceiverForNull &&
|
||||
_objectMemberNames.contains(directCall.target.name);
|
||||
|
||||
DirectCallMetadata getDirectCall(TreeNode node, Member interfaceTarget,
|
||||
DirectCallMetadata? getDirectCall(TreeNode node, Member? interfaceTarget,
|
||||
{bool setter = false});
|
||||
|
||||
makeDirectCall(TreeNode node, Member target, DirectCallMetadata directCall) {
|
||||
makeDirectCall(TreeNode node, Member? target, DirectCallMetadata directCall) {
|
||||
if (_trace) {
|
||||
print("[devirt] Resolving ${target} to ${directCall.target}"
|
||||
" at ${node.location}");
|
||||
|
@ -104,12 +103,12 @@ abstract class Devirtualization extends RecursiveVisitor {
|
|||
}
|
||||
|
||||
void _handleMethodInvocation(
|
||||
TreeNode node, Member target, Arguments arguments) {
|
||||
TreeNode node, Member? target, Arguments arguments) {
|
||||
if (target != null && !isMethod(target)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final DirectCallMetadata directCall = getDirectCall(node, target);
|
||||
final DirectCallMetadata? directCall = getDirectCall(node, target);
|
||||
|
||||
// TODO(alexmarkov): Convert _isLegalTargetForMethodInvocation()
|
||||
// check into an assertion once front-end implements all override checks.
|
||||
|
@ -138,18 +137,18 @@ abstract class Devirtualization extends RecursiveVisitor {
|
|||
super.visitEqualsCall(node);
|
||||
|
||||
final target = node.interfaceTarget;
|
||||
final DirectCallMetadata directCall = getDirectCall(node, target);
|
||||
final DirectCallMetadata? directCall = getDirectCall(node, target);
|
||||
if (directCall != null && !directCall.checkReceiverForNull) {
|
||||
makeDirectCall(node, target, directCall);
|
||||
}
|
||||
}
|
||||
|
||||
void _handlePropertyGet(TreeNode node, Member target) {
|
||||
void _handlePropertyGet(TreeNode node, Member? target) {
|
||||
if (target != null && !isFieldOrGetter(target)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final DirectCallMetadata directCall = getDirectCall(node, target);
|
||||
final DirectCallMetadata? directCall = getDirectCall(node, target);
|
||||
|
||||
if ((directCall != null) &&
|
||||
isFieldOrGetter(directCall.target) &&
|
||||
|
@ -170,8 +169,8 @@ abstract class Devirtualization extends RecursiveVisitor {
|
|||
_handlePropertyGet(node, null);
|
||||
}
|
||||
|
||||
void _handlePropertySet(TreeNode node, Member target) {
|
||||
final DirectCallMetadata directCall =
|
||||
void _handlePropertySet(TreeNode node, Member? target) {
|
||||
final DirectCallMetadata? directCall =
|
||||
getDirectCall(node, target, setter: true);
|
||||
if (directCall != null) {
|
||||
makeDirectCall(node, target, directCall);
|
||||
|
@ -200,12 +199,12 @@ class CHADevirtualization extends Devirtualization {
|
|||
: super(coreTypes, component, hierarchy);
|
||||
|
||||
@override
|
||||
DirectCallMetadata getDirectCall(TreeNode node, Member interfaceTarget,
|
||||
DirectCallMetadata? getDirectCall(TreeNode node, Member? interfaceTarget,
|
||||
{bool setter = false}) {
|
||||
if (interfaceTarget == null) {
|
||||
return null;
|
||||
}
|
||||
Member singleTarget = _hierarchySubtype
|
||||
Member? singleTarget = _hierarchySubtype
|
||||
.getSingleTargetForInterfaceInvocation(interfaceTarget, setter: setter);
|
||||
if (singleTarget == null) {
|
||||
return null;
|
||||
|
|
|
@ -292,7 +292,9 @@ class FfiTransformer extends Transformer {
|
|||
/// Classes corresponding to [NativeType], indexed by [NativeType].
|
||||
final List<Class> nativeTypesClasses;
|
||||
|
||||
Library? currentLibrary;
|
||||
Library? _currentLibrary;
|
||||
Library get currentLibrary => _currentLibrary!;
|
||||
|
||||
IndexedLibrary? currentLibraryIndex;
|
||||
|
||||
FfiTransformer(this.index, this.coreTypes, this.hierarchy,
|
||||
|
@ -459,11 +461,11 @@ class FfiTransformer extends Transformer {
|
|||
|
||||
@override
|
||||
TreeNode visitLibrary(Library node) {
|
||||
assert(currentLibrary == null);
|
||||
currentLibrary = node;
|
||||
assert(_currentLibrary == null);
|
||||
_currentLibrary = node;
|
||||
currentLibraryIndex = referenceFromIndex?.lookupLibrary(node);
|
||||
final result = super.visitLibrary(node);
|
||||
currentLibrary = null;
|
||||
_currentLibrary = null;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart=2.9
|
||||
|
||||
library vm.transformations.ffi_definitions;
|
||||
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:front_end/src/api_unstable/vm.dart'
|
||||
|
@ -71,8 +67,8 @@ void transformLibraries(
|
|||
ClassHierarchy hierarchy,
|
||||
List<Library> libraries,
|
||||
DiagnosticReporter diagnosticReporter,
|
||||
ReferenceFromIndex referenceFromIndex,
|
||||
ChangedStructureNotifier changedStructureNotifier) {
|
||||
ReferenceFromIndex? referenceFromIndex,
|
||||
ChangedStructureNotifier? changedStructureNotifier) {
|
||||
final LibraryIndex index = LibraryIndex(component,
|
||||
const ["dart:core", "dart:ffi", "dart:_internal", "dart:typed_data"]);
|
||||
if (!index.containsLibrary("dart:ffi")) {
|
||||
|
@ -96,7 +92,7 @@ class CompoundDependencyGraph<T> implements Graph<T> {
|
|||
CompoundDependencyGraph(this.map);
|
||||
|
||||
Iterable<T> get vertices => map.keys;
|
||||
Iterable<T> neighborsOf(T vertex) => map[vertex];
|
||||
Iterable<T> neighborsOf(T vertex) => map[vertex]!;
|
||||
}
|
||||
|
||||
/// Checks and elaborates the dart:ffi compounds and their fields.
|
||||
|
@ -109,16 +105,14 @@ class _FfiDefinitionTransformer extends FfiTransformer {
|
|||
Set<Class> transformCompoundsInvalid = {};
|
||||
Map<Class, NativeTypeCfe> compoundCache = {};
|
||||
|
||||
ChangedStructureNotifier changedStructureNotifier;
|
||||
|
||||
IndexedLibrary currentLibraryIndex;
|
||||
ChangedStructureNotifier? changedStructureNotifier;
|
||||
|
||||
_FfiDefinitionTransformer(
|
||||
this.index,
|
||||
CoreTypes coreTypes,
|
||||
ClassHierarchy hierarchy,
|
||||
DiagnosticReporter diagnosticReporter,
|
||||
ReferenceFromIndex referenceFromIndex,
|
||||
ReferenceFromIndex? referenceFromIndex,
|
||||
this.changedStructureNotifier)
|
||||
: super(index, coreTypes, hierarchy, diagnosticReporter,
|
||||
referenceFromIndex) {}
|
||||
|
@ -185,7 +179,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
|
|||
report = true;
|
||||
}
|
||||
if (component.length == 1) {
|
||||
if (dependencyGraph.map[component.single].contains(component.single)) {
|
||||
if (dependencyGraph.map[component.single]!.contains(component.single)) {
|
||||
// Direct cycle.
|
||||
report = true;
|
||||
}
|
||||
|
@ -193,7 +187,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
|
|||
if (report) {
|
||||
component.forEach((Class e) {
|
||||
diagnosticReporter.report(
|
||||
templateFfiFieldCyclic.withArguments(e.superclass.name, e.name,
|
||||
templateFfiFieldCyclic.withArguments(e.superclass!.name, e.name,
|
||||
component.map((e) => e.name).toList()),
|
||||
e.fileOffset,
|
||||
e.name.length,
|
||||
|
@ -232,12 +226,6 @@ class _FfiDefinitionTransformer extends FfiTransformer {
|
|||
});
|
||||
}
|
||||
|
||||
@override
|
||||
visitLibrary(Library node) {
|
||||
currentLibraryIndex = referenceFromIndex?.lookupLibrary(node);
|
||||
return super.visitLibrary(node);
|
||||
}
|
||||
|
||||
@override
|
||||
visitExtension(Extension node) {
|
||||
// The extension and it's members are only metadata.
|
||||
|
@ -262,9 +250,12 @@ class _FfiDefinitionTransformer extends FfiTransformer {
|
|||
|
||||
final packing = _checkCompoundClass(node);
|
||||
|
||||
final indexedClass = currentLibraryIndex?.lookupIndexedClass(node.name);
|
||||
final IndexedClass? indexedClass =
|
||||
currentLibraryIndex?.lookupIndexedClass(node.name);
|
||||
_checkConstructors(node, indexedClass);
|
||||
indexedCompoundClasses[node] = indexedClass;
|
||||
if (indexedClass != null) {
|
||||
indexedCompoundClasses[node] = indexedClass;
|
||||
}
|
||||
|
||||
final fieldsValid = _checkFieldAnnotations(node, packing);
|
||||
if (fieldsValid) {
|
||||
|
@ -278,14 +269,14 @@ class _FfiDefinitionTransformer extends FfiTransformer {
|
|||
}
|
||||
|
||||
/// Returns packing if any.
|
||||
int _checkCompoundClass(Class node) {
|
||||
int? _checkCompoundClass(Class node) {
|
||||
if (node.typeParameters.length > 0) {
|
||||
diagnosticReporter.report(
|
||||
templateFfiStructGeneric.withArguments(
|
||||
node.superclass.name, node.name),
|
||||
node.superclass!.name, node.name),
|
||||
node.fileOffset,
|
||||
1,
|
||||
node.location.file);
|
||||
node.location!.file);
|
||||
}
|
||||
|
||||
if (node.superclass != structClass && node.superclass != unionClass) {
|
||||
|
@ -301,7 +292,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
|
|||
templateFfiPackedAnnotation.withArguments(node.name),
|
||||
node.fileOffset,
|
||||
node.name.length,
|
||||
node.location.file);
|
||||
node.location!.file);
|
||||
}
|
||||
if (packingAnnotations.isNotEmpty) {
|
||||
final packing = packingAnnotations.first;
|
||||
|
@ -311,7 +302,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
|
|||
packing == 8 ||
|
||||
packing == 16)) {
|
||||
diagnosticReporter.report(messageFfiPackedAnnotationAlignment,
|
||||
node.fileOffset, node.name.length, node.location.file);
|
||||
node.fileOffset, node.name.length, node.location!.file);
|
||||
}
|
||||
return packing;
|
||||
}
|
||||
|
@ -354,14 +345,14 @@ class _FfiDefinitionTransformer extends FfiTransformer {
|
|||
if (member is Field) {
|
||||
return member.type;
|
||||
}
|
||||
final Procedure p = member;
|
||||
final p = member as Procedure;
|
||||
if (p.isGetter) {
|
||||
return p.function.returnType;
|
||||
}
|
||||
return p.function.positionalParameters.single.type;
|
||||
}
|
||||
|
||||
bool _checkFieldAnnotations(Class node, int packing) {
|
||||
bool _checkFieldAnnotations(Class node, int? packing) {
|
||||
bool success = true;
|
||||
final membersWithAnnotations =
|
||||
_compoundFieldMembers(node, includeSetters: false);
|
||||
|
@ -445,9 +436,9 @@ class _FfiDefinitionTransformer extends FfiTransformer {
|
|||
success = false;
|
||||
} else {
|
||||
final DartType nativeType = InterfaceType(
|
||||
nativeTypesClasses[_getFieldType(nativeTypeAnnos.first).index],
|
||||
nativeTypesClasses[_getFieldType(nativeTypeAnnos.first)!.index],
|
||||
Nullability.legacy);
|
||||
final DartType shouldBeDartType = convertNativeTypeToDartType(
|
||||
final DartType? shouldBeDartType = convertNativeTypeToDartType(
|
||||
nativeType,
|
||||
allowCompounds: true,
|
||||
allowHandle: false);
|
||||
|
@ -455,11 +446,11 @@ class _FfiDefinitionTransformer extends FfiTransformer {
|
|||
!env.isSubtypeOf(type, shouldBeDartType,
|
||||
SubtypeCheckMode.ignoringNullabilities)) {
|
||||
diagnosticReporter.report(
|
||||
templateFfiTypeMismatch.withArguments(type, shouldBeDartType,
|
||||
templateFfiTypeMismatch.withArguments(type, shouldBeDartType!,
|
||||
nativeType, node.enclosingLibrary.isNonNullableByDefault),
|
||||
f.fileOffset,
|
||||
1,
|
||||
f.location.file);
|
||||
f.location!.file);
|
||||
// This class is invalid, but continue reporting other errors on it.
|
||||
success = false;
|
||||
}
|
||||
|
@ -468,7 +459,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
|
|||
return success;
|
||||
}
|
||||
|
||||
void _checkPacking(Class outerClass, int outerClassPacking, Class fieldClass,
|
||||
void _checkPacking(Class outerClass, int? outerClassPacking, Class fieldClass,
|
||||
Member errorNode) {
|
||||
if (outerClassPacking == null) {
|
||||
// Outer struct has no packing, nesting anything is fine.
|
||||
|
@ -497,7 +488,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
|
|||
}
|
||||
}
|
||||
|
||||
void _checkConstructors(Class node, IndexedClass indexedClass) {
|
||||
void _checkConstructors(Class node, IndexedClass? indexedClass) {
|
||||
final toRemove = <Initializer>[];
|
||||
|
||||
// Constructors cannot have initializers because initializers refer to
|
||||
|
@ -510,13 +501,13 @@ class _FfiDefinitionTransformer extends FfiTransformer {
|
|||
templateFfiFieldInitializer.withArguments(i.field.name.text),
|
||||
i.fileOffset,
|
||||
1,
|
||||
i.location.file);
|
||||
i.location!.file);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Remove initializers referring to fields to prevent cascading errors.
|
||||
for (final Initializer i in toRemove) {
|
||||
final Constructor c = i.parent;
|
||||
final c = i.parent as Constructor;
|
||||
c.initializers.remove(i);
|
||||
}
|
||||
|
||||
|
@ -565,7 +556,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
|
|||
final dartType = _compoundMemberType(m);
|
||||
|
||||
// Nullable.
|
||||
NativeTypeCfe type;
|
||||
NativeTypeCfe? type;
|
||||
if (isArrayType(dartType)) {
|
||||
final sizeAnnotations = _getArraySizeAnnotations(m).toList();
|
||||
if (sizeAnnotations.length == 1) {
|
||||
|
@ -584,7 +575,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
|
|||
final nativeTypeAnnos = _getNativeTypeAnnotations(m).toList();
|
||||
if (nativeTypeAnnos.length == 1) {
|
||||
final clazz = nativeTypeAnnos.first;
|
||||
final nativeType = _getFieldType(clazz);
|
||||
final nativeType = _getFieldType(clazz)!;
|
||||
type = PrimitiveNativeTypeCfe(nativeType, clazz);
|
||||
}
|
||||
}
|
||||
|
@ -635,17 +626,18 @@ class _FfiDefinitionTransformer extends FfiTransformer {
|
|||
///
|
||||
/// Returns the total size of the compound (for all ABIs).
|
||||
void _replaceFields(
|
||||
Class node, IndexedClass indexedClass, CompoundData compoundData) {
|
||||
Class node, IndexedClass? indexedClass, CompoundData compoundData) {
|
||||
final compoundType = compoundData.compoundType as CompoundNativeTypeCfe;
|
||||
final compoundLayout = compoundType.layout;
|
||||
|
||||
_annoteCompoundWithFields(node, compoundType.members, compoundData.packing);
|
||||
if (compoundType.members.isEmpty) {
|
||||
diagnosticReporter.report(
|
||||
templateFfiEmptyStruct.withArguments(node.superclass.name, node.name),
|
||||
templateFfiEmptyStruct.withArguments(
|
||||
node.superclass!.name, node.name),
|
||||
node.fileOffset,
|
||||
node.name.length,
|
||||
node.location.file);
|
||||
node.location!.file);
|
||||
}
|
||||
|
||||
final unalignedAccess = compoundData.packing != null;
|
||||
|
@ -653,9 +645,9 @@ class _FfiDefinitionTransformer extends FfiTransformer {
|
|||
int i = 0;
|
||||
for (final compoundField in compoundData.compoundFields) {
|
||||
NativeTypeCfe type = compoundField.type;
|
||||
Field field = compoundField.field;
|
||||
Procedure getter = compoundField.getter;
|
||||
Procedure setter = compoundField.setter;
|
||||
Field? field = compoundField.field;
|
||||
Procedure? getter = compoundField.getter;
|
||||
Procedure? setter = compoundField.setter;
|
||||
|
||||
final fieldOffsets = compoundLayout
|
||||
.map((Abi abi, CompoundLayout v) => MapEntry(abi, v.offsets[i]));
|
||||
|
@ -693,7 +685,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
|
|||
static const vmFfiStructFields = "vm:ffi:struct-fields";
|
||||
|
||||
// return value is nullable.
|
||||
InstanceConstant _compoundAnnotatedFields(Class node) {
|
||||
InstanceConstant? _compoundAnnotatedFields(Class node) {
|
||||
for (final annotation in node.annotations) {
|
||||
if (annotation is ConstantExpression) {
|
||||
final constant = annotation.constant;
|
||||
|
@ -701,7 +693,8 @@ class _FfiDefinitionTransformer extends FfiTransformer {
|
|||
constant.classNode == pragmaClass &&
|
||||
constant.fieldValues[pragmaName.getterReference] ==
|
||||
StringConstant(vmFfiStructFields)) {
|
||||
return constant.fieldValues[pragmaOptions.getterReference];
|
||||
return constant.fieldValues[pragmaOptions.getterReference]
|
||||
as InstanceConstant?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -726,7 +719,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
|
|||
|
||||
/// Must only be called if all the depencies are already in the cache.
|
||||
CompoundNativeTypeCfe _compoundAnnotatedNativeTypeCfe(Class compoundClass) {
|
||||
final layoutConstant = _compoundAnnotatedFields(compoundClass);
|
||||
final layoutConstant = _compoundAnnotatedFields(compoundClass)!;
|
||||
final fieldTypes = layoutConstant
|
||||
.fieldValues[ffiStructLayoutTypesField.getterReference] as ListConstant;
|
||||
final members = <NativeTypeCfe>[];
|
||||
|
@ -763,7 +756,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
|
|||
|
||||
// packing is `int?`.
|
||||
void _annoteCompoundWithFields(
|
||||
Class node, List<NativeTypeCfe> types, int packing) {
|
||||
Class node, List<NativeTypeCfe> types, int? packing) {
|
||||
List<Constant> constants =
|
||||
types.map((t) => t.generateConstant(this)).toList();
|
||||
|
||||
|
@ -782,7 +775,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
|
|||
}
|
||||
|
||||
void _generateMethodsForField(Class node, Field field, NativeTypeCfe type,
|
||||
Map<Abi, int> offsets, bool unalignedAccess, IndexedClass indexedClass) {
|
||||
Map<Abi, int> offsets, bool unalignedAccess, IndexedClass? indexedClass) {
|
||||
// TODO(johnniwinther): Avoid passing [indexedClass]. When compiling
|
||||
// incrementally, [field] should already carry the references from
|
||||
// [indexedClass].
|
||||
|
@ -802,7 +795,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
|
|||
node.addProcedure(getter);
|
||||
|
||||
if (!field.isFinal) {
|
||||
Reference setterReference =
|
||||
Reference? setterReference =
|
||||
indexedClass?.lookupSetterReference(field.name) ??
|
||||
field.setterReference;
|
||||
assert(setterReference == field.setterReference,
|
||||
|
@ -832,8 +825,8 @@ class _FfiDefinitionTransformer extends FfiTransformer {
|
|||
///
|
||||
/// If sizes are not supplied still emits a field so that the use site
|
||||
/// transformer can still rewrite to it.
|
||||
void _addSizeOfField(Class compound, IndexedClass indexedClass,
|
||||
[Map<Abi, int> sizes = null]) {
|
||||
void _addSizeOfField(Class compound, IndexedClass? indexedClass,
|
||||
[Map<Abi, int>? sizes = null]) {
|
||||
if (sizes == null) {
|
||||
sizes = Map.fromEntries(Abi.values.map((abi) => MapEntry(abi, 0)));
|
||||
}
|
||||
|
@ -859,7 +852,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
|
|||
compound.addProcedure(getter);
|
||||
}
|
||||
|
||||
NativeType _getFieldType(Class c) {
|
||||
NativeType? _getFieldType(Class c) {
|
||||
final fieldType = getType(c);
|
||||
|
||||
if (fieldType == NativeType.kVoid) {
|
||||
|
@ -928,10 +921,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
|
|||
|
||||
class CompoundData {
|
||||
final List<CompoundField> compoundFields;
|
||||
|
||||
// Nullable.
|
||||
final int packing;
|
||||
|
||||
final int? packing;
|
||||
final NativeTypeCfe compoundType;
|
||||
|
||||
CompoundData(this.compoundFields, this.packing, this.compoundType);
|
||||
|
@ -939,15 +929,9 @@ class CompoundData {
|
|||
|
||||
class CompoundField {
|
||||
final NativeTypeCfe type;
|
||||
|
||||
// Nullable.
|
||||
final Field field;
|
||||
|
||||
// Nullable.
|
||||
final Procedure getter;
|
||||
|
||||
// Nullable.
|
||||
final Procedure setter;
|
||||
final Field? field;
|
||||
final Procedure? getter;
|
||||
final Procedure? setter;
|
||||
|
||||
CompoundField(this.type, this.field, this.getter, this.setter);
|
||||
}
|
||||
|
@ -974,11 +958,11 @@ class CompoundLayout {
|
|||
/// intimately to AST nodes such as [Class].
|
||||
abstract class NativeTypeCfe {
|
||||
factory NativeTypeCfe(FfiTransformer transformer, DartType dartType,
|
||||
{List<int> arrayDimensions,
|
||||
{List<int>? arrayDimensions,
|
||||
Map<Class, NativeTypeCfe> compoundCache = const {}}) {
|
||||
if (transformer.isPrimitiveType(dartType)) {
|
||||
final clazz = (dartType as InterfaceType).classNode;
|
||||
final nativeType = transformer.getType(clazz);
|
||||
final nativeType = transformer.getType(clazz)!;
|
||||
return PrimitiveNativeTypeCfe(nativeType, clazz);
|
||||
}
|
||||
if (transformer.isPointerType(dartType)) {
|
||||
|
@ -987,7 +971,7 @@ abstract class NativeTypeCfe {
|
|||
if (transformer.isCompoundSubtype(dartType)) {
|
||||
final clazz = (dartType as InterfaceType).classNode;
|
||||
if (compoundCache.containsKey(clazz)) {
|
||||
return compoundCache[clazz];
|
||||
return compoundCache[clazz]!;
|
||||
} else {
|
||||
throw "Class '$clazz' not found in compoundCache.";
|
||||
}
|
||||
|
@ -1094,8 +1078,8 @@ class PrimitiveNativeTypeCfe implements NativeTypeCfe {
|
|||
}
|
||||
|
||||
@override
|
||||
Map<Abi, int> get alignment => Map.fromEntries(Abi.values.map(
|
||||
(abi) => MapEntry(abi, nonSizeAlignment[abi][nativeType] ?? size[abi])));
|
||||
Map<Abi, int> get alignment => Map.fromEntries(Abi.values.map((abi) =>
|
||||
MapEntry(abi, nonSizeAlignment[abi]![nativeType] ?? size[abi]!)));
|
||||
|
||||
@override
|
||||
Constant generateConstant(FfiTransformer transformer) =>
|
||||
|
@ -1107,8 +1091,8 @@ class PrimitiveNativeTypeCfe implements NativeTypeCfe {
|
|||
bool isUnaligned(Map<Abi, int> offsets) {
|
||||
final alignments = alignment;
|
||||
for (final abi in offsets.keys) {
|
||||
final offset = offsets[abi];
|
||||
final alignment = alignments[abi];
|
||||
final offset = offsets[abi]!;
|
||||
final alignment = alignments[abi]!;
|
||||
if (offset % alignment != 0) {
|
||||
return true;
|
||||
}
|
||||
|
@ -1131,7 +1115,7 @@ class PrimitiveNativeTypeCfe implements NativeTypeCfe {
|
|||
ReturnStatement(StaticInvocation(
|
||||
(unalignedAccess && isFloat
|
||||
? transformer.loadUnalignedMethods
|
||||
: transformer.loadMethods)[nativeType],
|
||||
: transformer.loadMethods)[nativeType]!,
|
||||
Arguments([
|
||||
transformer.getCompoundTypedDataBaseField(
|
||||
ThisExpression(), fileOffset),
|
||||
|
@ -1155,7 +1139,7 @@ class PrimitiveNativeTypeCfe implements NativeTypeCfe {
|
|||
ReturnStatement(StaticInvocation(
|
||||
(unalignedAccess && isFloat
|
||||
? transformer.storeUnalignedMethods
|
||||
: transformer.storeMethods)[nativeType],
|
||||
: transformer.storeMethods)[nativeType]!,
|
||||
Arguments([
|
||||
transformer.getCompoundTypedDataBaseField(
|
||||
ThisExpression(), fileOffset),
|
||||
|
@ -1176,7 +1160,7 @@ class PointerNativeTypeCfe implements NativeTypeCfe {
|
|||
Constant generateConstant(FfiTransformer transformer) => TypeLiteralConstant(
|
||||
InterfaceType(transformer.pointerClass, Nullability.nonNullable, [
|
||||
InterfaceType(
|
||||
transformer.pointerClass.superclass, Nullability.nonNullable)
|
||||
transformer.pointerClass.superclass!, Nullability.nonNullable)
|
||||
]));
|
||||
|
||||
/// Sample output for `Pointer<Int8> get x =>`:
|
||||
|
@ -1195,7 +1179,7 @@ class PointerNativeTypeCfe implements NativeTypeCfe {
|
|||
transformer.fromAddressInternal,
|
||||
Arguments([
|
||||
StaticInvocation(
|
||||
transformer.loadMethods[NativeType.kIntptr],
|
||||
transformer.loadMethods[NativeType.kIntptr]!,
|
||||
Arguments([
|
||||
transformer.getCompoundTypedDataBaseField(
|
||||
ThisExpression(), fileOffset),
|
||||
|
@ -1221,7 +1205,7 @@ class PointerNativeTypeCfe implements NativeTypeCfe {
|
|||
VariableDeclaration argument,
|
||||
FfiTransformer transformer) =>
|
||||
ReturnStatement(StaticInvocation(
|
||||
transformer.storeMethods[NativeType.kIntptr],
|
||||
transformer.storeMethods[NativeType.kIntptr]!,
|
||||
Arguments([
|
||||
transformer.getCompoundTypedDataBaseField(
|
||||
ThisExpression(), fileOffset),
|
||||
|
@ -1312,10 +1296,10 @@ abstract class CompoundNativeTypeCfe implements NativeTypeCfe {
|
|||
|
||||
class StructNativeTypeCfe extends CompoundNativeTypeCfe {
|
||||
// Nullable int.
|
||||
final int packing;
|
||||
final int? packing;
|
||||
|
||||
factory StructNativeTypeCfe(Class clazz, List<NativeTypeCfe> members,
|
||||
{int packing}) {
|
||||
{int? packing}) {
|
||||
final layout = Map.fromEntries(Abi.values
|
||||
.map((abi) => MapEntry(abi, _calculateLayout(members, packing, abi))));
|
||||
return StructNativeTypeCfe._(clazz, members, packing, layout);
|
||||
|
@ -1328,13 +1312,13 @@ class StructNativeTypeCfe extends CompoundNativeTypeCfe {
|
|||
// Keep consistent with runtime/vm/compiler/ffi/native_type.cc
|
||||
// NativeStructType::FromNativeTypes.
|
||||
static CompoundLayout _calculateLayout(
|
||||
List<NativeTypeCfe> types, int packing, Abi abi) {
|
||||
List<NativeTypeCfe> types, int? packing, Abi abi) {
|
||||
int offset = 0;
|
||||
final offsets = <int>[];
|
||||
int structAlignment = 1;
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
final int size = types[i].size[abi];
|
||||
int alignment = types[i].alignment[abi];
|
||||
final int size = types[i].size[abi]!;
|
||||
int alignment = types[i].alignment[abi]!;
|
||||
if (packing != null && packing < alignment) {
|
||||
alignment = packing;
|
||||
}
|
||||
|
@ -1367,8 +1351,8 @@ class UnionNativeTypeCfe extends CompoundNativeTypeCfe {
|
|||
int unionSize = 1;
|
||||
int unionAlignment = 1;
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
final int size = types[i].size[abi];
|
||||
int alignment = types[i].alignment[abi];
|
||||
final int size = types[i].size[abi]!;
|
||||
int alignment = types[i].alignment[abi]!;
|
||||
unionSize = math.max(unionSize, size);
|
||||
unionAlignment = math.max(unionAlignment, alignment);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,9 @@ import 'package:front_end/src/api_unstable/vm.dart'
|
|||
|
||||
/// Transform @FfiNative annotated functions into FFI native function pointer
|
||||
/// functions.
|
||||
void transformLibraries(Component component, List<Library> libraries,
|
||||
void transformLibraries(
|
||||
Component component,
|
||||
List<Library> libraries,
|
||||
DiagnosticReporter diagnosticReporter,
|
||||
ReferenceFromIndex? referenceFromIndex) {
|
||||
final index = LibraryIndex(component, ['dart:ffi']);
|
||||
|
@ -22,8 +24,8 @@ void transformLibraries(Component component, List<Library> libraries,
|
|||
if (index.tryGetClass('dart:ffi', 'FfiNative') == null) {
|
||||
return;
|
||||
}
|
||||
final transformer = FfiNativeTransformer(index, diagnosticReporter,
|
||||
referenceFromIndex);
|
||||
final transformer =
|
||||
FfiNativeTransformer(index, diagnosticReporter, referenceFromIndex);
|
||||
libraries.forEach(transformer.visitLibrary);
|
||||
}
|
||||
|
||||
|
@ -41,8 +43,8 @@ class FfiNativeTransformer extends Transformer {
|
|||
final Procedure asFunctionProcedure;
|
||||
final Procedure fromAddressInternal;
|
||||
|
||||
FfiNativeTransformer(LibraryIndex index, this.diagnosticReporter,
|
||||
this.referenceFromIndex)
|
||||
FfiNativeTransformer(
|
||||
LibraryIndex index, this.diagnosticReporter, this.referenceFromIndex)
|
||||
: ffiNativeClass = index.getClass('dart:ffi', 'FfiNative'),
|
||||
nativeFunctionClass = index.getClass('dart:ffi', 'NativeFunction'),
|
||||
ffiNativeNameField =
|
||||
|
@ -169,11 +171,8 @@ class FfiNativeTransformer extends Transformer {
|
|||
}
|
||||
|
||||
if (!node.isStatic) {
|
||||
diagnosticReporter.report(
|
||||
messageFfiNativeAnnotationMustAnnotateStatic,
|
||||
node.fileOffset,
|
||||
1,
|
||||
node.location!.file);
|
||||
diagnosticReporter.report(messageFfiNativeAnnotationMustAnnotateStatic,
|
||||
node.fileOffset, 1, node.location!.file);
|
||||
}
|
||||
|
||||
node.isExternal = false;
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart=2.9
|
||||
|
||||
library vm.transformations.ffi_use_sites;
|
||||
|
||||
import 'package:front_end/src/api_unstable/vm.dart'
|
||||
show
|
||||
messageFfiExceptionalReturnNull,
|
||||
|
@ -46,7 +42,7 @@ void transformLibraries(
|
|||
ClassHierarchy hierarchy,
|
||||
List<Library> libraries,
|
||||
DiagnosticReporter diagnosticReporter,
|
||||
ReferenceFromIndex referenceFromIndex) {
|
||||
ReferenceFromIndex? referenceFromIndex) {
|
||||
final index = new LibraryIndex(
|
||||
component, ["dart:ffi", "dart:_internal", "dart:typed_data"]);
|
||||
if (!index.containsLibrary("dart:ffi")) {
|
||||
|
@ -66,7 +62,7 @@ void transformLibraries(
|
|||
|
||||
/// Checks and replaces calls to dart:ffi compound fields and methods.
|
||||
class _FfiUseSiteTransformer extends FfiTransformer {
|
||||
StaticTypeContext _staticTypeContext;
|
||||
StaticTypeContext? _staticTypeContext;
|
||||
|
||||
bool get isFfiLibrary => currentLibrary == ffiLibrary;
|
||||
|
||||
|
@ -79,7 +75,7 @@ class _FfiUseSiteTransformer extends FfiTransformer {
|
|||
CoreTypes coreTypes,
|
||||
ClassHierarchy hierarchy,
|
||||
DiagnosticReporter diagnosticReporter,
|
||||
ReferenceFromIndex referenceFromIndex)
|
||||
ReferenceFromIndex? referenceFromIndex)
|
||||
: super(index, coreTypes, hierarchy, diagnosticReporter,
|
||||
referenceFromIndex) {}
|
||||
|
||||
|
@ -176,7 +172,7 @@ class _FfiUseSiteTransformer extends FfiTransformer {
|
|||
_ensureNativeTypeValid(nativeType, node, allowCompounds: true);
|
||||
|
||||
if (nativeType is InterfaceType) {
|
||||
Expression inlineSizeOf = _inlineSizeOf(nativeType);
|
||||
Expression? inlineSizeOf = _inlineSizeOf(nativeType);
|
||||
if (inlineSizeOf != null) {
|
||||
return inlineSizeOf;
|
||||
}
|
||||
|
@ -206,7 +202,7 @@ class _FfiUseSiteTransformer extends FfiTransformer {
|
|||
return replacement;
|
||||
} else if (target == asFunctionMethod) {
|
||||
final dartType = node.arguments.types[1];
|
||||
final DartType nativeType = InterfaceType(
|
||||
final InterfaceType nativeType = InterfaceType(
|
||||
nativeFunctionClass, Nullability.legacy, [node.arguments.types[0]]);
|
||||
|
||||
_ensureNativeTypeValid(nativeType, node);
|
||||
|
@ -214,10 +210,9 @@ class _FfiUseSiteTransformer extends FfiTransformer {
|
|||
_ensureIsLeafIsConst(node);
|
||||
_ensureLeafCallDoesNotUseHandles(nativeType, node);
|
||||
|
||||
final DartType nativeSignature =
|
||||
(nativeType as InterfaceType).typeArguments[0];
|
||||
final DartType nativeSignature = nativeType.typeArguments[0];
|
||||
|
||||
bool isLeaf = _getIsLeafBoolean(node);
|
||||
bool? isLeaf = _getIsLeafBoolean(node);
|
||||
if (isLeaf == null) {
|
||||
isLeaf = false;
|
||||
}
|
||||
|
@ -243,7 +238,7 @@ class _FfiUseSiteTransformer extends FfiTransformer {
|
|||
final DartType nativeType = InterfaceType(
|
||||
nativeFunctionClass, Nullability.legacy, [node.arguments.types[0]]);
|
||||
final Expression func = node.arguments.positional[0];
|
||||
final DartType dartType = func.getStaticType(_staticTypeContext);
|
||||
final DartType dartType = func.getStaticType(_staticTypeContext!);
|
||||
|
||||
_ensureIsStaticFunction(func);
|
||||
|
||||
|
@ -257,7 +252,7 @@ class _FfiUseSiteTransformer extends FfiTransformer {
|
|||
((node.arguments.types[0] as FunctionType).returnType
|
||||
as InterfaceType)
|
||||
.classNode;
|
||||
final NativeType expectedReturn = getType(expectedReturnClass);
|
||||
final NativeType? expectedReturn = getType(expectedReturnClass);
|
||||
|
||||
if (expectedReturn == NativeType.kVoid ||
|
||||
expectedReturn == NativeType.kPointer ||
|
||||
|
@ -309,7 +304,7 @@ class _FfiUseSiteTransformer extends FfiTransformer {
|
|||
}
|
||||
|
||||
final DartType returnType =
|
||||
exceptionalReturn.getStaticType(_staticTypeContext);
|
||||
exceptionalReturn.getStaticType(_staticTypeContext!);
|
||||
|
||||
if (!env.isSubtypeOf(returnType, funcType.returnType,
|
||||
SubtypeCheckMode.ignoringNullabilities)) {
|
||||
|
@ -339,7 +334,7 @@ class _FfiUseSiteTransformer extends FfiTransformer {
|
|||
|
||||
// Inline the body to get rid of a generic invocation of sizeOf.
|
||||
// TODO(http://dartbug.com/39964): Add `allignmentOf<T>()` call.
|
||||
Expression sizeInBytes = _inlineSizeOf(nativeType);
|
||||
Expression? sizeInBytes = _inlineSizeOf(nativeType as InterfaceType);
|
||||
if (sizeInBytes != null) {
|
||||
if (node.arguments.positional.length == 2) {
|
||||
sizeInBytes = multiply(node.arguments.positional[1], sizeInBytes);
|
||||
|
@ -401,9 +396,9 @@ class _FfiUseSiteTransformer extends FfiTransformer {
|
|||
.distinct()
|
||||
.fold(nestedExpression, _invokeCompoundConstructor);
|
||||
|
||||
Expression _inlineSizeOf(InterfaceType nativeType) {
|
||||
Expression? _inlineSizeOf(InterfaceType nativeType) {
|
||||
final Class nativeClass = nativeType.classNode;
|
||||
final NativeType nt = getType(nativeClass);
|
||||
final NativeType? nt = getType(nativeClass);
|
||||
if (nt == null) {
|
||||
// User-defined compounds.
|
||||
final Procedure sizeOfGetter = nativeClass.procedures
|
||||
|
@ -457,7 +452,7 @@ class _FfiUseSiteTransformer extends FfiTransformer {
|
|||
.substituteType(lookupFunctionType.withoutTypeParameters)
|
||||
as FunctionType);
|
||||
|
||||
bool isLeaf = _getIsLeafBoolean(node);
|
||||
bool? isLeaf = _getIsLeafBoolean(node);
|
||||
if (isLeaf == null) {
|
||||
isLeaf = false;
|
||||
}
|
||||
|
@ -518,7 +513,7 @@ class _FfiUseSiteTransformer extends FfiTransformer {
|
|||
pointer,
|
||||
offsetByMethod.name,
|
||||
Arguments([
|
||||
multiply(node.arguments.positional[1], _inlineSizeOf(dartType))
|
||||
multiply(node.arguments.positional[1], _inlineSizeOf(dartType)!)
|
||||
]),
|
||||
interfaceTarget: offsetByMethod,
|
||||
functionType:
|
||||
|
@ -536,8 +531,8 @@ class _FfiUseSiteTransformer extends FfiTransformer {
|
|||
|
||||
final typedDataBasePrime = typedDataBaseOffset(
|
||||
getArrayTypedDataBaseField(NullCheck(node.arguments.positional[0])),
|
||||
multiply(node.arguments.positional[1], _inlineSizeOf(dartType)),
|
||||
_inlineSizeOf(dartType),
|
||||
multiply(node.arguments.positional[1], _inlineSizeOf(dartType)!),
|
||||
_inlineSizeOf(dartType)!,
|
||||
dartType,
|
||||
node.fileOffset);
|
||||
|
||||
|
@ -600,7 +595,7 @@ class _FfiUseSiteTransformer extends FfiTransformer {
|
|||
type: coreTypes.intNonNullableRawType)
|
||||
..fileOffset = node.fileOffset;
|
||||
final singleElementSizeVar = VariableDeclaration("#singleElementSize",
|
||||
initializer: _inlineSizeOf(elementType),
|
||||
initializer: _inlineSizeOf(elementType as InterfaceType),
|
||||
type: coreTypes.intNonNullableRawType)
|
||||
..fileOffset = node.fileOffset;
|
||||
final elementSizeVar = VariableDeclaration("#elementSize",
|
||||
|
@ -684,12 +679,12 @@ class _FfiUseSiteTransformer extends FfiTransformer {
|
|||
try {
|
||||
if (target == elementAtMethod) {
|
||||
final DartType pointerType =
|
||||
node.receiver.getStaticType(_staticTypeContext);
|
||||
final DartType nativeType = _pointerTypeGetTypeArg(pointerType);
|
||||
node.receiver.getStaticType(_staticTypeContext!);
|
||||
final DartType nativeType = _pointerTypeGetTypeArg(pointerType)!;
|
||||
|
||||
_ensureNativeTypeValid(nativeType, node, allowCompounds: true);
|
||||
|
||||
Expression inlineSizeOf = _inlineSizeOf(nativeType);
|
||||
Expression? inlineSizeOf = _inlineSizeOf(nativeType as InterfaceType);
|
||||
if (inlineSizeOf != null) {
|
||||
// Generates `receiver.offsetBy(inlineSizeOfExpression)`.
|
||||
return InstanceInvocation(
|
||||
|
@ -714,7 +709,7 @@ class _FfiUseSiteTransformer extends FfiTransformer {
|
|||
return node;
|
||||
}
|
||||
|
||||
DartType _pointerTypeGetTypeArg(DartType pointerType) {
|
||||
DartType? _pointerTypeGetTypeArg(DartType pointerType) {
|
||||
return pointerType is InterfaceType ? pointerType.typeArguments[0] : null;
|
||||
}
|
||||
|
||||
|
@ -724,7 +719,7 @@ class _FfiUseSiteTransformer extends FfiTransformer {
|
|||
final DartType correspondingDartType = convertNativeTypeToDartType(
|
||||
nativeType,
|
||||
allowCompounds: true,
|
||||
allowHandle: allowHandle);
|
||||
allowHandle: allowHandle)!;
|
||||
if (dartType == correspondingDartType) return;
|
||||
if (env.isSubtypeOf(correspondingDartType, dartType,
|
||||
SubtypeCheckMode.ignoringNullabilities)) {
|
||||
|
@ -787,7 +782,7 @@ class _FfiUseSiteTransformer extends FfiTransformer {
|
|||
/// Returns the class that should not be implemented or extended.
|
||||
///
|
||||
/// If the superclass is not sealed, returns `null`.
|
||||
Class _extendsOrImplementsSealedClass(Class klass) {
|
||||
Class? _extendsOrImplementsSealedClass(Class klass) {
|
||||
// Classes in dart:ffi themselves can extend FFI classes.
|
||||
if (klass == arrayClass ||
|
||||
klass == arraySizeClass ||
|
||||
|
@ -824,7 +819,7 @@ class _FfiUseSiteTransformer extends FfiTransformer {
|
|||
}
|
||||
|
||||
void _ensureNotExtendsOrImplementsSealedClass(Class klass) {
|
||||
final Class extended = _extendsOrImplementsSealedClass(klass);
|
||||
final Class? extended = _extendsOrImplementsSealedClass(klass);
|
||||
if (extended != null) {
|
||||
diagnosticReporter.report(
|
||||
templateFfiExtendsOrImplementsSealedClass
|
||||
|
@ -840,7 +835,7 @@ class _FfiUseSiteTransformer extends FfiTransformer {
|
|||
// - `true` if leaf
|
||||
// - `false` if not leaf
|
||||
// - `null` if the expression is not valid (e.g. non-const bool, null)
|
||||
bool _getIsLeafBoolean(StaticInvocation node) {
|
||||
bool? _getIsLeafBoolean(StaticInvocation node) {
|
||||
for (final named in node.arguments.named) {
|
||||
if (named.name == 'isLeaf') {
|
||||
final expr = named.value;
|
||||
|
@ -893,8 +888,8 @@ class _FfiUseSiteTransformer extends FfiTransformer {
|
|||
}
|
||||
}
|
||||
// Check if any of the argument types are Handle.
|
||||
for (InterfaceType param in functionType.positionalParameters) {
|
||||
if (param.classNode == handleClass) {
|
||||
for (DartType param in functionType.positionalParameters) {
|
||||
if ((param as InterfaceType).classNode == handleClass) {
|
||||
diagnosticReporter.report(messageFfiLeafCallMustNotTakeHandle,
|
||||
node.fileOffset, 1, node.location?.file);
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart=2.9
|
||||
|
||||
import 'package:front_end/src/api_unstable/vm.dart'
|
||||
show isRedirectingFactoryField;
|
||||
import 'package:kernel/ast.dart';
|
||||
|
@ -24,23 +22,24 @@ class ListLiteralsLowering {
|
|||
final Procedure _defaultFactory;
|
||||
|
||||
// Specialized _GrowableList._literalN(e1, ..., eN) factories.
|
||||
final List<Procedure> _specializedFactories =
|
||||
List<Procedure>.filled(numSpecializedFactories, null);
|
||||
final List<Procedure?> _specializedFactories =
|
||||
List<Procedure?>.filled(numSpecializedFactories, null);
|
||||
|
||||
ListLiteralsLowering(this.coreTypes)
|
||||
: _defaultFactory =
|
||||
coreTypes.index.getMember('dart:core', '_GrowableList', '');
|
||||
coreTypes.index.getProcedure('dart:core', '_GrowableList', '');
|
||||
|
||||
Procedure getSpecializedFactory(int length) =>
|
||||
(_specializedFactories[length - 1] ??= coreTypes.index
|
||||
.getMember('dart:core', '_GrowableList', '_literal$length'));
|
||||
.getProcedure('dart:core', '_GrowableList', '_literal$length'));
|
||||
|
||||
Expression transformListLiteral(ListLiteral node) {
|
||||
if (node.isConst) {
|
||||
throw 'Unexpected constant ListLiteral node'
|
||||
' (such nodes should be converted to ConstantExpression): $node';
|
||||
}
|
||||
if (node.parent is Field && isRedirectingFactoryField(node.parent)) {
|
||||
final parent = node.parent;
|
||||
if (parent is Field && isRedirectingFactoryField(parent)) {
|
||||
// Do not transform list literals which are used to represent
|
||||
// redirecting factories.
|
||||
return node;
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart=2.9
|
||||
|
||||
import 'package:kernel/ast.dart';
|
||||
import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
|
||||
import 'package:kernel/core_types.dart' show CoreTypes;
|
||||
|
@ -39,8 +37,8 @@ class _Lowering extends Transformer {
|
|||
final FactorySpecializer factorySpecializer;
|
||||
final ListLiteralsLowering listLiteralsLowering;
|
||||
|
||||
Member _currentMember;
|
||||
StaticTypeContext _cachedStaticTypeContext;
|
||||
Member? _currentMember;
|
||||
StaticTypeContext? _cachedStaticTypeContext;
|
||||
|
||||
_Lowering(CoreTypes coreTypes, ClassHierarchy hierarchy, this.nullSafety)
|
||||
: env = TypeEnvironment(coreTypes, hierarchy),
|
||||
|
@ -49,7 +47,7 @@ class _Lowering extends Transformer {
|
|||
listLiteralsLowering = ListLiteralsLowering(coreTypes);
|
||||
|
||||
StaticTypeContext get _staticTypeContext =>
|
||||
_cachedStaticTypeContext ??= StaticTypeContext(_currentMember, env);
|
||||
_cachedStaticTypeContext ??= StaticTypeContext(_currentMember!, env);
|
||||
|
||||
@override
|
||||
defaultMember(Member node) {
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart=2.9
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:vm/dominators.dart';
|
||||
|
||||
|
|
Loading…
Reference in a new issue