Files
sdk/pkg/vm/lib/metadata/closure_id.dart
T
Johnni Winther 6e4674d445 [kerne] Remove type parameter from RecursiveVisitor
The type parameter was a left-over from a pre-nnbd encoding of the visitors, but Flutter dependency on the code prevented its removal.

TEST=existing

Change-Id: I02657a469290f169077faa1167cf59b75de13c9c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/350840
Reviewed-by: Mayank Patke <fishythefish@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
2024-02-19 07:51:43 +00:00

73 lines
2.1 KiB
Dart

// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
// 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.
import 'package:kernel/ast.dart';
/// Repository for persistent closure IDs.
class ClosureIdMetadataRepository extends MetadataRepository<int> {
static const String repositoryTag = 'vm.closure-id';
@override
String get tag => repositoryTag;
// For a LocalFunction: id within an enclosing Member,
// with 0 reserved for the tear-off of the Member.
//
// For a Member: number of nested closures.
@override
final Map<TreeNode, int> mapping = {};
@override
void writeToBinary(int metadata, Node node, BinarySink sink) {
sink.writeUInt30(metadata);
}
@override
int readFromBinary(Node node, BinarySource source) {
return source.readUInt30();
}
/// Return closure ID within the enclosing [Member], or -1
/// if closure was not indexed.
///
/// Closures should be indexed within enclosing [Member]
/// using [indexClosures].
int getClosureId(LocalFunction closure) => mapping[closure] ?? -1;
/// Assign IDs for all closures within [member].
void indexClosures(Member member) {
if (mapping.containsKey(member)) {
return;
}
_ClosureIndexer indexer = _ClosureIndexer(this, member);
member.accept(indexer);
mapping[member] = indexer.index - _ClosureIndexer.firstClosureIndex;
}
}
class _ClosureIndexer extends RecursiveVisitor {
// Zero is reserved for tear-offs.
static int firstClosureIndex = 1;
final ClosureIdMetadataRepository _repository;
final Member member;
int index = firstClosureIndex;
_ClosureIndexer(this._repository, this.member);
@override
void visitFunctionDeclaration(FunctionDeclaration node) =>
_visitLocalFunction(node);
@override
void visitFunctionExpression(FunctionExpression node) =>
_visitLocalFunction(node);
void _visitLocalFunction(LocalFunction node) {
assert(index > 0);
_repository.mapping[node] = index++;
node.visitChildren(this);
}
}