From a04691a8a80c1299410e2306092f4a2cc8bb3940 Mon Sep 17 00:00:00 2001 From: Johnni Winther Date: Wed, 27 May 2026 00:41:34 -0700 Subject: [PATCH] [kernel][Contexts] Serialize new local variables This adds serialization of the new local variables, VariableStatement and VariableDeclaration. This prepares for replacing LegacyVariable with the new variables in all backends. TEST=existing Change-Id: I9bbebfbfd372042d6b7027f0fabd24c165699832 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/506240 Reviewed-by: Martin Kustermann Reviewed-by: Jens Johansen Commit-Queue: Johnni Winther --- pkg/front_end/test/binary_md_dill_reader.dart | 10 ++ pkg/front_end/testcases/modular.status | 2 +- pkg/front_end/testcases/outline.status | 15 -- pkg/front_end/testcases/strong.status | 2 +- pkg/kernel/bin/switch_order.dart | 14 +- pkg/kernel/binary.md | 83 ++++++++-- pkg/kernel/lib/binary/ast_from_binary.dart | 148 ++++++++++++++---- pkg/kernel/lib/binary/ast_to_binary.dart | 71 ++++++++- pkg/kernel/lib/binary/tag.dart | 14 +- pkg/kernel/lib/src/ast/components.dart | 2 - pkg/kernel/lib/src/ast/dummies.dart | 10 +- .../frontend/kernel_binary_flowgraph.cc | 63 +++++--- .../frontend/kernel_binary_flowgraph.h | 2 + .../compiler/frontend/kernel_fingerprints.cc | 57 ++++--- .../frontend/kernel_translation_helper.cc | 62 +++++--- .../frontend/kernel_translation_helper.h | 15 +- runtime/vm/compiler/frontend/scope_builder.cc | 52 +++--- runtime/vm/compiler/frontend/scope_builder.h | 10 +- runtime/vm/kernel.cc | 21 ++- runtime/vm/kernel_binary.h | 13 +- runtime/vm/kernel_loader.cc | 8 +- 21 files changed, 479 insertions(+), 195 deletions(-) diff --git a/pkg/front_end/test/binary_md_dill_reader.dart b/pkg/front_end/test/binary_md_dill_reader.dart index 961d0e64a9f..9a6db8ffb89 100644 --- a/pkg/front_end/test/binary_md_dill_reader.dart +++ b/pkg/front_end/test/binary_md_dill_reader.dart @@ -809,6 +809,16 @@ class BinaryMdDillReader { throw "Unknown Constant"; } } + if (what == "Variable") { + if (tagMap[_dillContent[_binaryOffset]] != null) { + what = tagMap[_dillContent[_binaryOffset]]!; + if (!isA(what, "Variable")) { + throw "Expected Variable but found $what"; + } + } else { + throw "Unknown Variable"; + } + } return what; } diff --git a/pkg/front_end/testcases/modular.status b/pkg/front_end/testcases/modular.status index 48ecef18bca..abf5e8b52d5 100644 --- a/pkg/front_end/testcases/modular.status +++ b/pkg/front_end/testcases/modular.status @@ -35,5 +35,5 @@ closure_context_lowering/loop_depth_strategy: ExpectationFileMismatchSerialized closure_context_lowering/parameters: Crash closure_context_lowering/redirecting_factories: ExpectationFileMismatchSerialized closure_context_lowering/super_initializing_formal: ExpectationFileMismatchSerialized -closure_context_lowering/synthetic_variables: Crash +closure_context_lowering/synthetic_variables: ExpectationFileMismatchSerialized closure_context_lowering/this_variable: Crash diff --git a/pkg/front_end/testcases/outline.status b/pkg/front_end/testcases/outline.status index 81a8072afa1..feb43ae7752 100644 --- a/pkg/front_end/testcases/outline.status +++ b/pkg/front_end/testcases/outline.status @@ -16,18 +16,3 @@ inference/mixin_inference_outwards_4: TypeCheckError inference/mixin_inference_unification_1: TypeCheckError inference/mixin_inference_unification_2: TypeCheckError rasta/native_is_illegal: Pass # Issue 29763 - -# Temporarily unimplemented binary serialization, see https://github.com/dart-lang/sdk/issues/61765 -closure_context_lowering/local_variables: ExpectationFileMismatchSerialized -closure_context_lowering/parameters: ExpectationFileMismatchSerialized -closure_context_lowering/this_variable: ExpectationFileMismatchSerialized -closure_context_lowering/loop_depth_strategy: ExpectationFileMismatchSerialized -closure_context_lowering/foo42: ExpectationFileMismatchSerialized -closure_context_lowering/foo45: ExpectationFileMismatchSerialized -closure_context_lowering/foo48: ExpectationFileMismatchSerialized -closure_context_lowering/assert_captured_variables: ExpectationFileMismatchSerialized -closure_context_lowering/late_variable_initializers: ExpectationFileMismatchSerialized -closure_context_lowering/synthetic_variables: ExpectationFileMismatchSerialized -closure_context_lowering/constructor_initializers: ExpectationFileMismatchSerialized -closure_context_lowering/super_initializing_formal: ExpectationFileMismatchSerialized -closure_context_lowering/redirecting_factories: ExpectationFileMismatchSerialized \ No newline at end of file diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status index f8c9e221a1b..f1377469307 100644 --- a/pkg/front_end/testcases/strong.status +++ b/pkg/front_end/testcases/strong.status @@ -274,5 +274,5 @@ closure_context_lowering/loop_depth_strategy: ExpectationFileMismatchSerialized closure_context_lowering/parameters: Crash closure_context_lowering/redirecting_factories: ExpectationFileMismatchSerialized closure_context_lowering/super_initializing_formal: ExpectationFileMismatchSerialized -closure_context_lowering/synthetic_variables: Crash +closure_context_lowering/synthetic_variables: ExpectationFileMismatchSerialized closure_context_lowering/this_variable: Crash diff --git a/pkg/kernel/bin/switch_order.dart b/pkg/kernel/bin/switch_order.dart index 57b0809c9ec..77461df1da8 100755 --- a/pkg/kernel/bin/switch_order.dart +++ b/pkg/kernel/bin/switch_order.dart @@ -1,4 +1,5 @@ #!/usr/bin/env dart + // Copyright (c) 2022, 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. @@ -305,7 +306,7 @@ String? getNameOfTag(int tag) { if (tag == Tag.TryCatch) return "TryCatch"; if (tag == Tag.TryFinally) return "TryFinally"; if (tag == Tag.YieldStatement) return "YieldStatement"; - if (tag == Tag.VariableDeclaration) return "VariableDeclaration"; + if (tag == Tag.VariableStatement) return "VariableStatement"; if (tag == Tag.FunctionDeclaration) return "FunctionDeclaration"; if (tag == Tag.AsyncForInStatement) return "AsyncForInStatement"; if (tag == Tag.AssertBlock) return "AssertBlock"; @@ -324,5 +325,16 @@ String? getNameOfTag(int tag) { if (tag == Tag.RecordType) return "RecordType"; if (tag == Tag.ExtensionType) return "ExtensionType"; + if (tag == Tag.VariableDeclaration) return "VariableDeclaration"; + + if (tag == Tag.LocalVariable) return "LocalVariable"; + if (tag == Tag.LateVariable) return "LateVariable"; + if (tag == Tag.SyntheticVariable) return "SyntheticVariable"; + if (tag == Tag.CatchVariable) return "CatchVariable"; + if (tag == Tag.PositionalParameter) return "PositionalParameter"; + if (tag == Tag.NamedParameter) return "NamedParameter"; + if (tag == Tag.ThisVariable) return "ThisVariable"; + if (tag == Tag.LegacyVariable) return "LegacyVariable"; + return null; } diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md index 41a934e8273..7787fb722e1 100644 --- a/pkg/kernel/binary.md +++ b/pkg/kernel/binary.md @@ -147,7 +147,7 @@ type CanonicalName { type ComponentFile { UInt32 magic = 0x90ABCDEF; - UInt32 formatVersion = 130; + UInt32 formatVersion = 131; Byte[10] shortSdkHash; List problemsAsJson; // Described in problems.md. Library[] libraries; @@ -500,7 +500,7 @@ type RedirectingInitializer extends Initializer { type LocalInitializer extends Initializer { Byte tag = 11; FileOffset fileOffset; - VariableDeclarationPlain variable; + Variable variable; } type AssertInitializer extends Initializer { @@ -527,8 +527,8 @@ type FunctionNode { List typeParameters; UInt parameterCount; // positionalParameters.length + namedParameters.length. UInt requiredParameterCount; - List positionalParameters; - List namedParameters; + List positionalParameters; + List namedParameters; DartType returnType; Option emittedValueType; Option redirectingFactoryTarget; @@ -1181,7 +1181,7 @@ type FunctionExpression extends Expression { type Let extends Expression { Byte tag = 53; FileOffset fileOffset; - VariableDeclarationPlain variable; + Variable variable; Expression body; } @@ -1396,7 +1396,7 @@ type DoStatement extends Statement { type ForStatement extends Statement { Byte tag = 69; FileOffset fileOffset; - List variables; + List variables; Option condition; List updates; Statement body; @@ -1406,7 +1406,7 @@ type ForInStatement extends Statement { Byte tag = 70; FileOffset fileOffset; FileOffset bodyOffset; - VariableDeclarationPlain variable; + Variable variable; Expression iterable; Statement body; } @@ -1415,7 +1415,7 @@ type AsyncForInStatement extends Statement { Byte tag = 80; // Note: tag is out of order. FileOffset fileOffset; FileOffset bodyOffset; - VariableDeclarationPlain variable; + Variable variable; Expression iterable; Statement body; } @@ -1481,8 +1481,8 @@ type TryCatch extends Statement { type Catch { FileOffset fileOffset; DartType guard; - Option exception; - Option stackTrace; + Option exception; + Option stackTrace; Statement body; } @@ -1500,12 +1500,61 @@ type YieldStatement extends Statement { Expression expression; } -type VariableDeclaration extends Statement { +type VariableStatement extends Statement { Byte tag = 78; - VariableDeclarationPlain variable; + FileOffset fileOffset; + VariableDeclaration declaration; } -type VariableDeclarationPlain { +type VariableDeclaration extends Node { + Byte tag = 154; + FileOffset fileOffset; + Variable variable; +} + +abstract type Variable extends Node {} + +type LegacyVariable extends Variable { + Byte tag = 162; + VariableInternal variable; +} + +type LocalVariable extends Variable { + Byte tag = 155; + VariableInternal variable; +} + +type LateVariable extends Variable { + Byte tag = 156; + VariableInternal variable; +} + +type SyntheticVariable extends Variable { + Byte tag = 157; + VariableInternal variable; +} + +type CatchVariable extends Variable { + Byte tag = 158; + VariableInternal variable; +} + +type PositionalParameter extends Variable { + Byte tag = 159; + VariableInternal variable; +} + +type NamedParameter extends Variable { + Byte tag = 160; + VariableInternal variable; +} + +type ThisVariable extends Variable { + Byte tag = 161; + VariableInternal variable; +} + +type VariableInternal { // The offset for the variable declaration, i.e. the offset of the start of // the declaration. FileOffset fileOffset; @@ -1539,7 +1588,7 @@ type FunctionDeclaration extends Statement { // within the function for use as a self-reference. // Some of the fields in the variable are redundant, but its presence here // simplifies the rule for variable indexing. - VariableDeclarationPlain variable; + Variable variable; // Identifier of the local function within an enclosing member. UInt id; FunctionNode function; @@ -1718,7 +1767,7 @@ type InvalidPattern extends Pattern { Byte tag = 132; FileOffset fileOffset; Expression invalidExpression; - List declaredVariables; + List declaredVariables; } type ListPattern extends Pattern { @@ -1884,7 +1933,7 @@ type VariablePattern extends Pattern { Byte tag = 143; FileOffset fileOffset; Option type; - VariableDeclaration variable; + Variable variable; Option matchedType; } @@ -1952,7 +2001,7 @@ type PatternSwitchStatement extends Statement { type PatternSwitchCase extends TreeNode { // Note: there is no tag on PatternSwitchCase - List jointVariables; + List jointVariables; List> patternGuards; Byte flags; // {isDefault, hasLabel} Statement body; diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart index 5c92f36a175..8342eae5cc9 100644 --- a/pkg/kernel/lib/binary/ast_from_binary.dart +++ b/pkg/kernel/lib/binary/ast_from_binary.dart @@ -3145,7 +3145,7 @@ class BinaryBuilder { Expression _readLet() { int offset = readOffset(); - Variable variable = readVariableDeclaration(); + Variable variable = readVariable(); int stackHeight = variableStack.length; pushVariableDeclaration(variable); Expression body = readExpression(); @@ -3283,7 +3283,7 @@ class BinaryBuilder { if (!useGrowableLists && length == 0) { // When lists don't have to be growable anyway, we might as well use an // almost constant one for the empty list. - return emptyListOfVariableDeclaration; + return emptyListOfVariable; } return new List.generate( length, @@ -3527,7 +3527,7 @@ class BinaryBuilder { VariablePattern _readVariablePattern() { int fileOffset = readOffset(); DartType? type = readDartTypeOption(); - Variable variable = readVariableDeclaration(); + Variable variable = readVariable(); DartType? matchedType = readDartTypeOption(); return new VariablePattern(type, variable) ..matchedValueType = matchedType @@ -3671,7 +3671,7 @@ class BinaryBuilder { void _readPatternSwitchCaseInto(PatternSwitchCase caseNode) { int variableCount = readUInt30(); for (int i = 0; i < variableCount; ++i) { - caseNode.jointVariables.add(readVariableDeclaration()..parent = caseNode); + caseNode.jointVariables.add(readVariable()..parent = caseNode); } int caseCount = readUInt30(); for (int i = 0; i < caseCount; ++i) { @@ -3722,7 +3722,7 @@ class BinaryBuilder { return _readBlock(); // 9.62% (6.92% - 12.64%). - case Tag.VariableDeclaration: + case Tag.VariableStatement: return _readVariableStatement(); // 9.28% (6.69% - 11.18%). @@ -3929,21 +3929,23 @@ class BinaryBuilder { } VariableStatement _readVariableStatement() { - Variable variable = _readVariableDeclaration(); - return new VariableStatement( - VariableDeclaration(variable)..fileOffset = variable.fileOffset, - )..fileOffset = variable.fileOffset; + int offset = readOffset(); + VariableDeclaration declaration = readVariableDeclaration(); + return new VariableStatement(declaration)..fileOffset = offset; } - Variable _readVariableDeclaration() { - Variable variable = readVariableDeclaration(); + VariableDeclaration readVariableDeclaration() { + int tag = readByte(); + assert(tag == Tag.VariableDeclaration); + int offset = readOffset(); + Variable variable = readVariable(); variableStack.add(variable); // Will be popped by the enclosing scope. - return variable; + return new VariableDeclaration(variable)..fileOffset = offset; } Statement _readFunctionDeclaration() { int offset = readOffset(); - Variable variable = readVariableDeclaration(); + Variable variable = readVariable(); variableStack.add(variable); // Will be popped by the enclosing scope. final LocalFunctionId id = LocalFunctionId(readUInt30()); return new FunctionDeclaration(variable, readFunctionNode()) @@ -4432,12 +4434,16 @@ class BinaryBuilder { } List readAndPushVariableDeclarationList() { - List list = readAndPushVariableList(); + int length = readUInt30(); + if (!useGrowableLists && length == 0) { + // When lists don't have to be growable anyway, we might as well use an + // almost constant one for the empty list. + return emptyListOfVariableDeclaration; + } return new List.generate( - list.length, - (int index) => - new VariableDeclaration(list[index]) - ..fileOffset = list[index].fileOffset, + length, + (int index) => readVariableDeclaration(), + growable: useGrowableLists, ); } @@ -4446,7 +4452,7 @@ class BinaryBuilder { if (!useGrowableLists && length == 0) { // When lists don't have to be growable anyway, we might as well use an // almost constant one for the empty list. - return emptyListOfVariableDeclaration; + return emptyListOfVariable; } return new List.generate( length, @@ -4460,27 +4466,101 @@ class BinaryBuilder { } Variable readAndPushVariable() { - Variable variable = readVariableDeclaration(); + Variable variable = readVariable(); variableStack.add(variable); return variable; } - Variable readVariableDeclaration() { + Variable readVariable() { + int tag = readByte(); int offset = readOffset(); int fileEqualsOffset = readOffset(); // The [VariableDeclaration] instance is not created at this point yet, // so `null` is temporarily set as the parent of the annotation nodes. List annotations = readAnnotationList(null); int flags = readUInt30(); - Variable node = - new Variable( - readStringOrNullIfEmpty(), - type: readDartType(), - initializer: readExpressionOption(), - flags: flags, - ) + String? name = readStringOrNullIfEmpty(); + DartType type = readDartType(); + Expression? initializer = readExpressionOption(); + Variable node; + switch (tag) { + case Tag.LegacyVariable: + node = + new LegacyVariable( + name, + type: type, + initializer: initializer, + flags: flags, + ) + ..fileOffset = offset + ..fileEqualsOffset = fileEqualsOffset; + case Tag.LocalVariable: + node = + new LocalVariable( + cosmeticName: name, + type: type, + initializer: initializer, + ) + ..flags = flags + ..fileOffset = offset + ..fileEqualsOffset = fileEqualsOffset; + case Tag.LateVariable: + node = + new LateVariable( + cosmeticName: name, + type: type, + initializer: initializer, + ) + ..flags = flags + ..fileOffset = offset + ..fileEqualsOffset = fileEqualsOffset; + case Tag.SyntheticVariable: + node = + new SyntheticVariable( + cosmeticName: name, + type: type, + initializer: initializer, + ) + ..flags = flags + ..fileOffset = offset + ..fileEqualsOffset = fileEqualsOffset; + case Tag.CatchVariable: + assert(initializer == null, "Unexpected initializer on CatchVariable"); + node = new CatchVariable(name: name!, type: type) + ..flags = flags ..fileOffset = offset ..fileEqualsOffset = fileEqualsOffset; + case Tag.PositionalParameter: + node = + new PositionalParameter( + cosmeticName: name, + type: type, + defaultValue: initializer, + ) + ..flags = flags + ..fileOffset = offset + ..fileEqualsOffset = fileEqualsOffset; + case Tag.NamedParameter: + node = + new NamedParameter( + parameterName: name!, + type: type, + defaultValue: initializer, + ) + ..flags = flags + ..fileOffset = offset + ..fileEqualsOffset = fileEqualsOffset; + case Tag.ThisVariable: + assert(name == null, "Unexpected name on ThisVariable."); + assert(initializer == null, "Unexpected initializer on ThisVariable."); + node = new ThisVariable(type: type) + ..flags = flags + ..fileOffset = offset + ..fileEqualsOffset = fileEqualsOffset; + default: + throw new UnsupportedError("Unexpected variable tag $tag"); + } + if (annotations.isNotEmpty) { for (int i = 0; i < annotations.length; ++i) { Expression annotation = annotations[i]; @@ -4758,10 +4838,10 @@ class BinaryBuilderWithMetadata extends BinaryBuilder implements BinarySource { } @override - Variable readVariableDeclaration() { + Variable readVariable() { final int nodeOffset = _byteOffset; final bool hasMetadata = _hasMetadata(_byteOffset); - final Variable result = super.readVariableDeclaration(); + final Variable result = super.readVariable(); return hasMetadata ? _associateMetadata(result, nodeOffset) : result; } @@ -4773,6 +4853,14 @@ class BinaryBuilderWithMetadata extends BinaryBuilder implements BinarySource { return hasMetadata ? _associateMetadata(result, nodeOffset) : result; } + @override + VariableDeclaration readVariableDeclaration() { + final int nodeOffset = _byteOffset; + final bool hasMetadata = _hasMetadata(_byteOffset); + final VariableDeclaration result = super.readVariableDeclaration(); + return hasMetadata ? _associateMetadata(result, nodeOffset) : result; + } + @override Combinator readCombinator() { final int nodeOffset = _byteOffset; diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart index 0f330a753ed..fc56a75fb93 100644 --- a/pkg/kernel/lib/binary/ast_to_binary.dart +++ b/pkg/kernel/lib/binary/ast_to_binary.dart @@ -19,8 +19,6 @@ class BinaryPrinter with TreeVisitorExperimentExclusionMixin, DartTypeVisitorExperimentExclusionMixin, - StatementVisitorExperimentExclusionMixin, - VariableVisitorExperimentExclusionMixin, ExpressionVisitorExperimentExclusionMixin implements Visitor, BinarySink { final VariableIndexer Function() _newVariableIndexer; @@ -2476,21 +2474,60 @@ class BinaryPrinter } @override - void visitVariable(Variable node) { - writeByte(Tag.VariableDeclaration); + void visitCatchVariable(CatchVariable node) { writeVariable(node); } + @override + void visitLateVariable(LateVariable node) { + writeVariable(node); + } + + @override + void visitLocalVariable(LocalVariable node) { + writeVariable(node); + } + + @override + void visitLegacyVariable(LegacyVariable node) { + writeVariable(node); + } + + @override + void visitNamedParameter(NamedParameter node) { + writeVariable(node); + } + + @override + void visitPositionalParameter(PositionalParameter node) { + writeVariable(node); + } + + @override + void visitThisVariable(ThisVariable node) { + writeVariable(node); + } + + @override + void visitSyntheticVariable(SyntheticVariable node) { + writeVariable(node); + } + + @override + void visitVariableStatement(VariableStatement node) { + writeByte(Tag.VariableStatement); + writeOffset(node.fileOffset); + writeNode(node.declaration); + } + @override void visitVariableDeclaration(VariableDeclaration node) { writeVariableDeclaration(node); } - void writeVariableStatement(VariableStatement node) { - writeVariableDeclaration(node.declaration); - } - void writeVariableDeclaration(VariableDeclaration node) { + writeByte(Tag.VariableDeclaration); + writeOffset(node.fileOffset); writeVariable(node.variable); } @@ -2499,6 +2536,24 @@ class BinaryPrinter _writeNodeMetadata(node); } node.binaryOffsetNoTag = getBufferOffset(); + switch (node) { + case LegacyVariable(): + writeByte(Tag.LegacyVariable); + case LocalVariable(): + writeByte(Tag.LocalVariable); + case LateVariable(): + writeByte(Tag.LateVariable); + case CatchVariable(): + writeByte(Tag.CatchVariable); + case ThisVariable(): + writeByte(Tag.ThisVariable); + case SyntheticVariable(): + writeByte(Tag.SyntheticVariable); + case PositionalParameter(): + writeByte(Tag.PositionalParameter); + case NamedParameter(): + writeByte(Tag.NamedParameter); + } writeOffset(node.fileOffset); writeOffset(node.fileEqualsOffset); writeAnnotationList(node.annotations); diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart index 3d6bfd798e3..0d6fb1b1c4d 100644 --- a/pkg/kernel/lib/binary/tag.dart +++ b/pkg/kernel/lib/binary/tag.dart @@ -130,7 +130,7 @@ class Tag { static const int TryCatch = 75; static const int TryFinally = 76; static const int YieldStatement = 77; - static const int VariableDeclaration = 78; + static const int VariableStatement = 78; static const int FunctionDeclaration = 79; static const int AsyncForInStatement = 80; static const int AssertBlock = 81; @@ -210,6 +210,16 @@ class Tag { static const int PatternVariableDeclaration = 151; static const int NullType = 152; + // 153 is occupied by [RedirectingFactoryInvocation] (expression). + static const int VariableDeclaration = 154; + static const int LocalVariable = 155; + static const int LateVariable = 156; + static const int SyntheticVariable = 157; + static const int CatchVariable = 158; + static const int PositionalParameter = 159; + static const int NamedParameter = 160; + static const int ThisVariable = 161; + static const int LegacyVariable = 162; static const int SpecializedTagHighBits = 0xE0; // 0b11100000 static const int SpecializedTagMask = 0xF8; // 0b11111000 @@ -227,7 +237,7 @@ class Tag { /// Internal version of kernel binary format. /// Bump it when making incompatible changes in kernel binaries. /// Keep in sync with runtime/vm/kernel_binary.h, pkg/kernel/binary.md. - static const int BinaryFormatVersion = 130; + static const int BinaryFormatVersion = 131; } abstract class ConstantTag { diff --git a/pkg/kernel/lib/src/ast/components.dart b/pkg/kernel/lib/src/ast/components.dart index 854186dd56b..cd6cd5281f4 100644 --- a/pkg/kernel/lib/src/ast/components.dart +++ b/pkg/kernel/lib/src/ast/components.dart @@ -369,8 +369,6 @@ abstract class MetadataRepository { return !(node is MapLiteralEntry || node is Catch || (node is Block && node.parent is BlockExpression) || - // TODO(johnniwinther): Support [VariableStatement]. - node is VariableStatement || // TODO(johnniwinther): Support [VariableDeclaration]. node is VariableDeclaration); } diff --git a/pkg/kernel/lib/src/ast/dummies.dart b/pkg/kernel/lib/src/ast/dummies.dart index f8cc28f84ff..bd56ea7b247 100644 --- a/pkg/kernel/lib/src/ast/dummies.dart +++ b/pkg/kernel/lib/src/ast/dummies.dart @@ -14,7 +14,15 @@ final List emptyListOfNamedExpression = List.filled( /// Almost const [], but not const in an attempt to avoid /// polymorphism. See https://dart-review.googlesource.com/c/sdk/+/185828. -final List emptyListOfVariableDeclaration = List.filled( +final List emptyListOfVariableDeclaration = List.filled( + 0, + dummyVariableDeclaration, + growable: false, +); + +/// Almost const [], but not const in an attempt to avoid +/// polymorphism. See https://dart-review.googlesource.com/c/sdk/+/185828. +final List emptyListOfVariable = List.filled( 0, dummyVariable, growable: false, diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc index d38e5578ec2..56b4705a76a 100644 --- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc +++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc @@ -92,7 +92,7 @@ void StreamingFlowGraphBuilder::SetupDefaultParameterValues() { // List of positional. intptr_t list_length = ReadListLength(); // read list length. for (intptr_t i = 0; i < list_length; ++i) { - SkipVariableDeclaration(); // read ith variable declaration. + SkipVariable(); // read ith variable. } // List of named. @@ -102,9 +102,9 @@ void StreamingFlowGraphBuilder::SetupDefaultParameterValues() { for (intptr_t i = 0; i < list_length; ++i) { Instance* default_value; - // Read ith variable declaration - VariableDeclarationHelper helper(this); - helper.ReadUntilExcluding(VariableDeclarationHelper::kInitializer); + // Read ith variable + VariableHelper helper(this); + helper.ReadUntilExcluding(VariableHelper::kInitializer); Tag tag = ReadTag(); // read (first part of) initializer. if (tag == kSomething) { // This will read the initializer. @@ -123,14 +123,14 @@ void StreamingFlowGraphBuilder::SetupDefaultParameterValues() { ASSERT(parsed_function()->function().HasOptionalPositionalParameters()); for (intptr_t i = 0; i < function_node_helper.required_parameter_count_; ++i) { - SkipVariableDeclaration(); // read ith variable declaration. + SkipVariable(); // read ith variable. } for (intptr_t i = 0; i < optional_parameter_count; ++i) { Instance* default_value; - // Read ith variable declaration - VariableDeclarationHelper helper(this); - helper.ReadUntilExcluding(VariableDeclarationHelper::kInitializer); + // Read ith variable + VariableHelper helper(this); + helper.ReadUntilExcluding(VariableHelper::kInitializer); Tag tag = ReadTag(); // read (first part of) initializer. if (tag == kSomething) { // This will read the initializer. @@ -445,9 +445,9 @@ Fragment StreamingFlowGraphBuilder::BuildInitializers( LocalVariable* variable = LookupVariable(ReaderOffset() + data_program_offset_); - // Variable declaration - VariableDeclarationHelper helper(this); - helper.ReadUntilExcluding(VariableDeclarationHelper::kInitializer); + // Variable + VariableHelper helper(this); + helper.ReadUntilExcluding(VariableHelper::kInitializer); ASSERT(!helper.IsConst()); Tag tag = ReadTag(); // read (first part of) initializer. if (tag != kSomething) { @@ -686,9 +686,9 @@ Fragment StreamingFlowGraphBuilder::BuildFunctionBody( bool constructor) { Fragment body; - // TODO(27590): Currently the [VariableDeclaration]s from the - // initializers will be visible inside the entire body of the constructor. - // We should make a separate scope for them. + // TODO(27590): Currently the [Variable]s from the initializers will be + // visible inside the entire body of the constructor. We should make a + // separate scope for them. if (constructor) { body += BuildInitializers(Class::Handle(Z, dart_function.Owner())); } @@ -1293,8 +1293,8 @@ Fragment StreamingFlowGraphBuilder::BuildStatement(TokenPosition* position) { return BuildTryFinally(position); case kYieldStatement: return BuildYieldStatement(position); - case kVariableDeclaration: - return BuildVariableDeclaration(position); + case kVariableStatement: + return BuildVariableStatement(position); case kFunctionDeclaration: return BuildFunctionDeclaration(position); case kForInStatement: @@ -3059,7 +3059,7 @@ Fragment StreamingFlowGraphBuilder::BuildLocalFunctionInvocation( { AlternativeReadingScope alt( &reader_, variable_kernel_position - data_program_offset_); - SkipVariableDeclaration(); + SkipVariable(); const intptr_t local_function_id = ReadUInt(); // read id. ASSERT(local_function_id > 0); @@ -4314,8 +4314,8 @@ Fragment StreamingFlowGraphBuilder::BuildLet(TokenPosition* p) { if (p != nullptr) *p = position; Fragment instructions; instructions += EnterScope(offset); - instructions += BuildVariableDeclaration(nullptr); // read variable. - instructions += BuildExpression(); // read body. + instructions += BuildVariable(nullptr); // read variable. + instructions += BuildExpression(); // read body. instructions += ExitScope(offset); return instructions; } @@ -5552,7 +5552,7 @@ Fragment StreamingFlowGraphBuilder::BuildTryCatch(TokenPosition* position) { StoreLocal(TokenPosition::kNoSource, LookupVariable(ReaderOffset() + data_program_offset_)); catch_handler_body += Drop(); - SkipVariableDeclaration(); // read exception. + SkipVariable(); // read exception. } tag = ReadTag(); // read first part of stack trace. @@ -5562,7 +5562,7 @@ Fragment StreamingFlowGraphBuilder::BuildTryCatch(TokenPosition* position) { StoreLocal(TokenPosition::kNoSource, LookupVariable(ReaderOffset() + data_program_offset_)); catch_handler_body += Drop(); - SkipVariableDeclaration(); // read stack trace. + SkipVariable(); // read stack trace. } { @@ -5834,13 +5834,28 @@ Fragment StreamingFlowGraphBuilder::BuildYieldStatement( return instructions; } +Fragment StreamingFlowGraphBuilder::BuildVariableStatement( + TokenPosition* position) { + const TokenPosition pos = ReadPosition(); // read position. + if (position != nullptr) *position = pos; + return BuildVariableDeclaration(position); +} + Fragment StreamingFlowGraphBuilder::BuildVariableDeclaration( TokenPosition* position) { + const Tag tag = ReadTag(); // read tag. + ASSERT(tag == kVariableDeclaration); + const TokenPosition pos = ReadPosition(); // read position. + if (position != nullptr) *position = pos; + return BuildVariable(position); +} + +Fragment StreamingFlowGraphBuilder::BuildVariable(TokenPosition* position) { intptr_t kernel_position_no_tag = ReaderOffset() + data_program_offset_; LocalVariable* variable = LookupVariable(kernel_position_no_tag); - VariableDeclarationHelper helper(this); - helper.ReadUntilExcluding(VariableDeclarationHelper::kType); + VariableHelper helper(this); + helper.ReadUntilExcluding(VariableHelper::kType); T.BuildType(); // read type. bool has_initializer = (ReadTag() != kNothing); @@ -5883,7 +5898,7 @@ Fragment StreamingFlowGraphBuilder::BuildFunctionDeclaration( if (position != nullptr) *position = pos; const intptr_t variable_offset = ReaderOffset() + data_program_offset_; - SkipVariableDeclaration(); + SkipVariable(); const intptr_t local_function_id = ReadUInt(); // read id. ASSERT(local_function_id > 0); diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h index 871563e2d3f..40661227ca1 100644 --- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h +++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h @@ -370,7 +370,9 @@ class StreamingFlowGraphBuilder : public KernelReaderHelper { Fragment BuildTryCatch(TokenPosition* position); Fragment BuildTryFinally(TokenPosition* position); Fragment BuildYieldStatement(TokenPosition* position); + Fragment BuildVariableStatement(TokenPosition* position); Fragment BuildVariableDeclaration(TokenPosition* position); + Fragment BuildVariable(TokenPosition* position); Fragment BuildFunctionDeclaration(TokenPosition* position); Fragment BuildFunctionNode(intptr_t local_function_id, intptr_t func_decl_offset); diff --git a/runtime/vm/compiler/frontend/kernel_fingerprints.cc b/runtime/vm/compiler/frontend/kernel_fingerprints.cc index 4a6d44ae671..eab111eaea2 100644 --- a/runtime/vm/compiler/frontend/kernel_fingerprints.cc +++ b/runtime/vm/compiler/frontend/kernel_fingerprints.cc @@ -32,11 +32,13 @@ class KernelFingerprintHelper : public KernelReaderHelper { void BuildHash(uint32_t val); void CalculateConstructorFingerprint(); void CalculateArgumentsFingerprint(); + void CalculateVariableFingerprint(); void CalculateVariableDeclarationFingerprint(); void CalculateStatementListFingerprint(); void CalculateListOfExpressionsFingerprint(); void CalculateListOfNamedExpressionsFingerprint(); void CalculateListOfDartTypesFingerprint(); + void CalculateListOfVariablesFingerprint(); void CalculateListOfVariableDeclarationsFingerprint(); void CalculateStringReferenceFingerprint(); void CalculateTypeParameterFingerprint(); @@ -87,13 +89,19 @@ void KernelFingerprintHelper::CalculateArgumentsFingerprint() { } void KernelFingerprintHelper::CalculateVariableDeclarationFingerprint() { - VariableDeclarationHelper helper(this); + ReadTag(); // read tag. + ReadPosition(); // read position. + CalculateVariableFingerprint(); +} - helper.ReadUntilExcluding(VariableDeclarationHelper::kAnnotations); +void KernelFingerprintHelper::CalculateVariableFingerprint() { + VariableHelper helper(this); + + helper.ReadUntilExcluding(VariableHelper::kAnnotations); CalculateListOfExpressionsFingerprint(); - helper.SetJustRead(VariableDeclarationHelper::kAnnotations); + helper.SetJustRead(VariableHelper::kAnnotations); - helper.ReadUntilExcluding(VariableDeclarationHelper::kType); + helper.ReadUntilExcluding(VariableHelper::kType); // We don't need to use the helper after this point. CalculateDartTypeFingerprint(); if (ReadTag() == kSomething) { @@ -137,6 +145,14 @@ void KernelFingerprintHelper::CalculateStringReferenceFingerprint() { H.DartString(ReadStringReference()).Hash()); // read ith string index. } +void KernelFingerprintHelper::CalculateListOfVariablesFingerprint() { + intptr_t list_length = ReadListLength(); // read list length. + for (intptr_t i = 0; i < list_length; ++i) { + // read ith variable. + CalculateVariableFingerprint(); + } +} + void KernelFingerprintHelper::CalculateListOfVariableDeclarationsFingerprint() { intptr_t list_length = ReadListLength(); // read list length. for (intptr_t i = 0; i < list_length; ++i) { @@ -207,8 +223,8 @@ void KernelFingerprintHelper::CalculateInitializerFingerprint() { CalculateArgumentsFingerprint(); // read arguments. return; case kLocalInitializer: - ReadPosition(); // read position. - CalculateVariableDeclarationFingerprint(); // read variable. + ReadPosition(); // read position. + CalculateVariableFingerprint(); // read variable. return; case kAssertInitializer: ReadPosition(); // read position. @@ -630,9 +646,9 @@ void KernelFingerprintHelper::CalculateExpressionFingerprint() { CalculateFunctionNodeFingerprint(); // read function node. return; case kLet: - ReadPosition(); // read position. - CalculateVariableDeclarationFingerprint(); // read variable declaration. - CalculateExpressionFingerprint(); // read expression. + ReadPosition(); // read position. + CalculateVariableFingerprint(); // read variable declaration. + CalculateExpressionFingerprint(); // read expression. return; case kBlockExpression: ReadPosition(); // read position. @@ -832,12 +848,12 @@ void KernelFingerprintHelper::CalculateStatementFingerprint() { tag = ReadTag(); // read first part of exception. BuildHash(tag); if (tag == kSomething) { - CalculateVariableDeclarationFingerprint(); // read exception. + CalculateVariableFingerprint(); // read exception. } tag = ReadTag(); // read first part of stack trace. BuildHash(tag); if (tag == kSomething) { - CalculateVariableDeclarationFingerprint(); // read stack trace. + CalculateVariableFingerprint(); // read stack trace. } CalculateStatementFingerprint(); // read body. } @@ -854,14 +870,15 @@ void KernelFingerprintHelper::CalculateStatementFingerprint() { CalculateExpressionFingerprint(); // read expression. return; } - case kVariableDeclaration: + case kVariableStatement: + ReadPosition(); // read position CalculateVariableDeclarationFingerprint(); // read variable declaration. return; case kFunctionDeclaration: - ReadPosition(); // read position. - CalculateVariableDeclarationFingerprint(); // read variable. - ReadUInt(); // read id. - CalculateFunctionNodeFingerprint(); // read function node. + ReadPosition(); // read position. + CalculateVariableFingerprint(); // read variable. + ReadUInt(); // read id. + CalculateFunctionNodeFingerprint(); // read function node. return; case kForInStatement: case kAsyncForInStatement: @@ -911,10 +928,10 @@ void KernelFingerprintHelper::CalculateFunctionNodeFingerprint() { function_node_helper.ReadUntilExcluding( FunctionNodeHelper::kPositionalParameters); - CalculateListOfVariableDeclarationsFingerprint(); // read positionals - CalculateListOfVariableDeclarationsFingerprint(); // read named - CalculateDartTypeFingerprint(); // read return type. - CalculateOptionalDartTypeFingerprint(); // read emitted value type. + CalculateListOfVariablesFingerprint(); // read positionals + CalculateListOfVariablesFingerprint(); // read named + CalculateDartTypeFingerprint(); // read return type. + CalculateOptionalDartTypeFingerprint(); // read emitted value type. if (ReadTag() == kSomething) { // read redirecting factory target ReadCanonicalNameReference(); // read member reference diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc index c902d0cc0fd..3c66b606fae 100644 --- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc +++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc @@ -956,11 +956,11 @@ void FunctionNodeHelper::ReadUntilExcluding(Field field) { if (++next_read_ == field) return; FALL_THROUGH; case kPositionalParameters: - helper_->SkipListOfVariableDeclarations(); // read positionals. + helper_->SkipListOfVariables(); // read positionals. if (++next_read_ == field) return; FALL_THROUGH; case kNamedParameters: - helper_->SkipListOfVariableDeclarations(); // read named. + helper_->SkipListOfVariables(); // read named. if (++next_read_ == field) return; FALL_THROUGH; case kReturnType: @@ -1030,11 +1030,15 @@ void TypeParameterHelper::ReadUntilExcluding(Field field) { } } -void VariableDeclarationHelper::ReadUntilExcluding(Field field) { +void VariableHelper::ReadUntilExcluding(Field field) { if (field <= next_read_) return; // Ordered with fall-through. switch (next_read_) { + case kTag: + helper_->ReadTag(); // read tag. + if (++next_read_ == field) return; + FALL_THROUGH; case kPosition: position_ = helper_->ReadPosition(); // read position. if (++next_read_ == field) return; @@ -2325,7 +2329,7 @@ void KernelReaderHelper::ReadUntilFunctionNode() { case kFunctionDeclaration: ReadTag(); ReadPosition(); - SkipVariableDeclaration(); + SkipVariable(); ReadUInt(); break; case kFunctionExpression: @@ -2496,6 +2500,13 @@ void KernelReaderHelper::SkipListOfVariableDeclarations() { } } +void KernelReaderHelper::SkipListOfVariables() { + intptr_t list_length = ReadListLength(); // read list length. + for (intptr_t i = 0; i < list_length; ++i) { + SkipVariable(); // read ith variable. + } +} + void KernelReaderHelper::SkipListOfCanonicalNameReferences() { intptr_t list_length = ReadListLength(); // read list length. for (intptr_t i = 0; i < list_length; ++i) { @@ -2537,8 +2548,8 @@ void KernelReaderHelper::SkipInitializer() { SkipArguments(); // read arguments. return; case kLocalInitializer: - ReadPosition(); // read position. - SkipVariableDeclaration(); // read variable. + ReadPosition(); // read position. + SkipVariable(); // read variable. return; case kAssertInitializer: ReadPosition(); // read position. @@ -2816,9 +2827,9 @@ void KernelReaderHelper::SkipExpression() { SkipFunctionNode(); // read function node. return; case kLet: - ReadPosition(); // read position. - SkipVariableDeclaration(); // read variable declaration. - SkipExpression(); // read expression. + ReadPosition(); // read position. + SkipVariable(); // read variable declaration. + SkipExpression(); // read expression. return; case kBlockExpression: ReadPosition(); // read position. @@ -3011,11 +3022,11 @@ void KernelReaderHelper::SkipStatement() { SkipDartType(); // read guard. tag = ReadTag(); // read first part of exception. if (tag == kSomething) { - SkipVariableDeclaration(); // read exception. + SkipVariable(); // read exception. } tag = ReadTag(); // read first part of stack trace. if (tag == kSomething) { - SkipVariableDeclaration(); // read stack trace. + SkipVariable(); // read stack trace. } SkipStatement(); // read body. } @@ -3032,14 +3043,15 @@ void KernelReaderHelper::SkipStatement() { SkipExpression(); // read expression. return; } - case kVariableDeclaration: + case kVariableStatement: + ReadPosition(); // read position. SkipVariableDeclaration(); // read variable declaration. return; case kFunctionDeclaration: - ReadPosition(); // read position. - SkipVariableDeclaration(); // read variable. - ReadUInt(); // read id. - SkipFunctionNode(); // read function node. + ReadPosition(); // read position. + SkipVariable(); // read variable. + ReadUInt(); // read id. + SkipFunctionNode(); // read function node. return; case kForInStatement: case kAsyncForInStatement: @@ -3075,8 +3087,14 @@ void KernelReaderHelper::SkipArguments() { } void KernelReaderHelper::SkipVariableDeclaration() { - VariableDeclarationHelper helper(this); - helper.ReadUntilExcluding(VariableDeclarationHelper::kEnd); + ReadTag(); // read tag. + ReadPosition(); // read position. + SkipVariable(); // read variable. +} + +void KernelReaderHelper::SkipVariable() { + VariableHelper helper(this); + helper.ReadUntilExcluding(VariableHelper::kEnd); } void KernelReaderHelper::SkipLibraryCombinator() { @@ -3969,8 +3987,8 @@ void TypeTranslator::SetupFunctionParameters( const Library& lib = Library::Handle(Z, active_class_->klass->library()); for (intptr_t i = 0; i < positional_parameter_count; ++i, ++pos) { // Read ith variable declaration. - VariableDeclarationHelper helper(helper_); - helper.ReadUntilExcluding(VariableDeclarationHelper::kType); + VariableHelper helper(helper_); + helper.ReadUntilExcluding(VariableHelper::kType); // The required flag should only be set on named parameters. ASSERT(!helper.IsRequired()); const AbstractType& type = BuildTypeWithoutFinalization(); // read type. @@ -3988,8 +4006,8 @@ void TypeTranslator::SetupFunctionParameters( ASSERT(named_parameter_count_check == named_parameter_count); for (intptr_t i = 0; i < named_parameter_count; ++i, ++pos) { // Read ith variable declaration. - VariableDeclarationHelper helper(helper_); - helper.ReadUntilExcluding(VariableDeclarationHelper::kType); + VariableHelper helper(helper_); + helper.ReadUntilExcluding(VariableHelper::kType); const AbstractType& type = BuildTypeWithoutFinalization(); // read type. Tag tag = helper_->ReadTag(); // read (first part of) initializer. if (tag == kSomething) { diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h index 4ee60a264f4..b043c7b82d1 100644 --- a/runtime/vm/compiler/frontend/kernel_translation_helper.h +++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h @@ -389,16 +389,17 @@ class TypeParameterHelper { DISALLOW_COPY_AND_ASSIGN(TypeParameterHelper); }; -// Helper class that reads a kernel VariableDeclaration from binary. +// Helper class that reads a kernel Variable from binary. // // Use ReadUntilExcluding to read up to but not including a field. // One can then for instance read the field from the call-site (and remember to // call SetAt to inform this helper class), and then use this to read more. // Simple fields are stored (e.g. integers) and can be fetched from this class. // If asked to read a compound field (e.g. an expression) it will be skipped. -class VariableDeclarationHelper { +class VariableHelper { public: enum Field { + kTag, kPosition, kEqualPosition, kAnnotations, @@ -425,8 +426,8 @@ class VariableDeclarationHelper { kIsSuperInitializingFormal = 1 << 12, }; - explicit VariableDeclarationHelper(KernelReaderHelper* helper) - : annotation_count_(0), helper_(helper), next_read_(kPosition) {} + explicit VariableHelper(KernelReaderHelper* helper) + : annotation_count_(0), helper_(helper), next_read_(kTag) {} void ReadUntilIncluding(Field field) { ReadUntilExcluding(static_cast(static_cast(field) + 1)); @@ -469,7 +470,7 @@ class VariableDeclarationHelper { KernelReaderHelper* helper_; intptr_t next_read_; - DISALLOW_COPY_AND_ASSIGN(VariableDeclarationHelper); + DISALLOW_COPY_AND_ASSIGN(VariableHelper); }; // Helper class that reads a kernel Field from binary. @@ -1340,6 +1341,7 @@ class KernelReaderHelper { void SkipListOfNamedExpressions(); void SkipListOfDartTypes(); void SkipListOfStrings(); + void SkipListOfVariables(); void SkipListOfVariableDeclarations(); void SkipListOfCanonicalNameReferences(); void SkipTypeParametersList(); @@ -1350,6 +1352,7 @@ class KernelReaderHelper { void SkipName(); void SkipArguments(); void SkipVariableDeclaration(); + void SkipVariable(); void SkipLibraryCombinator(); void SkipLibraryDependency(); TokenPosition ReadPosition(); @@ -1398,7 +1401,7 @@ class KernelReaderHelper { friend class TypeParameterHelper; friend class TypeTranslator; friend class UnboxingInfoMetadataHelper; - friend class VariableDeclarationHelper; + friend class VariableHelper; friend class ObfuscationProhibitionsMetadataHelper; friend class LoadingUnitsMetadataHelper; friend ArrayPtr CollectConstConstructorCoverageFrom( diff --git a/runtime/vm/compiler/frontend/scope_builder.cc b/runtime/vm/compiler/frontend/scope_builder.cc index ab7f04e0817..862d927c49d 100644 --- a/runtime/vm/compiler/frontend/scope_builder.cc +++ b/runtime/vm/compiler/frontend/scope_builder.cc @@ -670,8 +670,8 @@ void ScopeBuilder::VisitInitializer() { VisitArguments(); // read arguments. return; case kLocalInitializer: - helper_.ReadPosition(); // read position. - VisitVariableDeclaration(); // read variable. + helper_.ReadPosition(); // read position. + VisitVariable(); // read variable. return; case kAssertInitializer: helper_.ReadPosition(); // read position. @@ -985,9 +985,9 @@ void ScopeBuilder::VisitExpression() { EnterScope(offset); - helper_.ReadPosition(); // read position. - VisitVariableDeclaration(); // read variable declaration. - VisitExpression(); // read expression. + helper_.ReadPosition(); // read position. + VisitVariable(); // read variable declaration. + VisitExpression(); // read expression. ExitScope(helper_.reader_.min_position(), helper_.reader_.max_position()); return; @@ -1283,11 +1283,11 @@ void ScopeBuilder::VisitStatement() { VisitDartType(); // Read the guard. tag = helper_.ReadTag(); // read first part of exception. if (tag == kSomething) { - VisitVariableDeclaration(); // read exception. + VisitVariable(); // read exception. } tag = helper_.ReadTag(); // read first part of stack trace. if (tag == kSomething) { - VisitVariableDeclaration(); // read stack trace. + VisitVariable(); // read stack trace. } VisitStatement(); // read body. @@ -1326,13 +1326,14 @@ void ScopeBuilder::VisitStatement() { VisitExpression(); // read expression. return; } - case kVariableDeclaration: + case kVariableStatement: + helper_.ReadPosition(); // read position. VisitVariableDeclaration(); // read variable declaration. return; case kFunctionDeclaration: { intptr_t offset = helper_.ReaderOffset() - 1; // -1 to include tag byte. helper_.ReadPosition(); // read position. - VisitVariableDeclaration(); // read variable declaration. + VisitVariable(); // read variable declaration. helper_.ReadUInt(); // read id. HandleLocalFunction(offset); // read function node. return; @@ -1379,6 +1380,12 @@ void ScopeBuilder::VisitArguments() { } void ScopeBuilder::VisitVariableDeclaration() { + helper_.ReadTag(); // read tag. + helper_.ReadPosition(); // read position. + VisitVariable(); // read variable. +} + +void ScopeBuilder::VisitVariable() { PositionScope scope(&helper_.reader_); const intptr_t kernel_offset = @@ -1386,10 +1393,10 @@ void ScopeBuilder::VisitVariableDeclaration() { // MetadataHelper expects relative offsets and adjusts them internally const InferredTypeMetadata inferred_type = inferred_type_metadata_helper_.GetInferredType(helper_.ReaderOffset()); - VariableDeclarationHelper helper(&helper_); - helper.ReadUntilExcluding(VariableDeclarationHelper::kAnnotations); + VariableHelper helper(&helper_); + helper.ReadUntilExcluding(VariableHelper::kAnnotations); const intptr_t annotations_offset = helper_.ReaderOffset(); - helper.ReadUntilExcluding(VariableDeclarationHelper::kType); + helper.ReadUntilExcluding(VariableHelper::kType); AbstractType& type = BuildAndVisitVariableType(); const String& name = H.DartSymbolObfuscate(helper.name_index_); @@ -1674,20 +1681,19 @@ void ScopeBuilder::AddPositionalAndNamedParameters( // List of positional. intptr_t list_length = helper_.ReadListLength(); // read list length. for (intptr_t i = 0; i < list_length; ++i) { - AddVariableDeclarationParameter(pos++, type_check_mode, attrs); + AddParameter(pos++, type_check_mode, attrs); } // List of named. list_length = helper_.ReadListLength(); // read list length. for (intptr_t i = 0; i < list_length; ++i) { - AddVariableDeclarationParameter(pos++, type_check_mode, attrs); + AddParameter(pos++, type_check_mode, attrs); } } -void ScopeBuilder::AddVariableDeclarationParameter( - intptr_t pos, - ParameterTypeCheckMode type_check_mode, - const ProcedureAttributesMetadata& attrs) { +void ScopeBuilder::AddParameter(intptr_t pos, + ParameterTypeCheckMode type_check_mode, + const ProcedureAttributesMetadata& attrs) { // Convert kernel offset of variable declaration to absolute. const intptr_t kernel_offset = helper_.data_program_offset_ + helper_.ReaderOffset(); @@ -1697,15 +1703,15 @@ void ScopeBuilder::AddVariableDeclarationParameter( const InferredTypeMetadata inferred_arg_type = inferred_arg_type_metadata_helper_.GetInferredType( helper_.ReaderOffset()); - VariableDeclarationHelper helper(&helper_); - helper.ReadUntilExcluding(VariableDeclarationHelper::kAnnotations); + VariableHelper helper(&helper_); + helper.ReadUntilExcluding(VariableHelper::kAnnotations); const intptr_t annotations_offset = helper_.ReaderOffset(); - helper.ReadUntilExcluding(VariableDeclarationHelper::kType); + helper.ReadUntilExcluding(VariableHelper::kType); String& name = H.DartSymbolObfuscate(helper.name_index_); ASSERT(name.Length() > 0); AbstractType& type = BuildAndVisitVariableType(); // read type. - helper.SetJustRead(VariableDeclarationHelper::kType); - helper.ReadUntilExcluding(VariableDeclarationHelper::kInitializer); + helper.SetJustRead(VariableHelper::kType); + helper.ReadUntilExcluding(VariableHelper::kInitializer); LocalVariable* variable = MakeVariable( helper.position_, helper.position_, name, type, kernel_offset, diff --git a/runtime/vm/compiler/frontend/scope_builder.h b/runtime/vm/compiler/frontend/scope_builder.h index 4052e90d9e4..2523b880f41 100644 --- a/runtime/vm/compiler/frontend/scope_builder.h +++ b/runtime/vm/compiler/frontend/scope_builder.h @@ -44,6 +44,7 @@ class ScopeBuilder { void VisitListOfNamedExpressions(); void VisitArguments(); void VisitVariableDeclaration(); + void VisitVariable(); void VisitVariableGet(intptr_t declaration_binary_offset); void VisitDartType(); void VisitInterfaceType(bool simple); @@ -93,11 +94,10 @@ class ScopeBuilder { const ProcedureAttributesMetadata& attrs); // This assumes that the reader is at a FunctionNode, - // about to read a parameter (i.e. VariableDeclaration). - void AddVariableDeclarationParameter( - intptr_t pos, - ParameterTypeCheckMode type_check_mode, - const ProcedureAttributesMetadata& attrs); + // about to read a parameter (i.e. Variable). + void AddParameter(intptr_t pos, + ParameterTypeCheckMode type_check_mode, + const ProcedureAttributesMetadata& attrs); LocalVariable* MakeVariable( TokenPosition declaration_pos, diff --git a/runtime/vm/kernel.cc b/runtime/vm/kernel.cc index dd88f9bf8a9..82492700568 100644 --- a/runtime/vm/kernel.cc +++ b/runtime/vm/kernel.cc @@ -322,9 +322,8 @@ class MetadataEvaluator : public KernelReaderHelper { } else if (tag == kFunctionDeclaration) { ReadTag(); ReadPosition(); // fileOffset - VariableDeclarationHelper variable_declaration_helper(this); - variable_declaration_helper.ReadUntilExcluding( - VariableDeclarationHelper::kAnnotations); + VariableHelper variable_helper(this); + variable_helper.ReadUntilExcluding(VariableHelper::kAnnotations); } else { FATAL("No support for metadata on this type of kernel node: %" Pd32 "\n", @@ -411,8 +410,8 @@ ObjectPtr ParameterDescriptorBuilder::BuildParameterDescriptor( // Read ith variable declaration. intptr_t param_kernel_offset = reader_.offset(); - VariableDeclarationHelper helper(this); - helper.ReadUntilExcluding(VariableDeclarationHelper::kInitializer); + VariableHelper helper(this); + helper.ReadUntilExcluding(VariableHelper::kInitializer); param_descriptor.SetAt(entry_start + Parser::kParameterIsFinalOffset, helper.IsFinal() ? Bool::True() : Bool::False()); @@ -433,8 +432,8 @@ ObjectPtr ParameterDescriptorBuilder::BuildParameterDescriptor( if (FLAG_enable_mirrors && (helper.annotation_count_ > 0)) { AlternativeReadingScope alt(&reader_, param_kernel_offset); - VariableDeclarationHelper helper(this); - helper.ReadUntilExcluding(VariableDeclarationHelper::kAnnotations); + VariableHelper helper(this); + helper.ReadUntilExcluding(VariableHelper::kAnnotations); Object& metadata = Object::ZoneHandle(zone_, constant_reader_.ReadAnnotations()); param_descriptor.SetAt(entry_start + Parser::kParameterMetadataOffset, @@ -505,8 +504,8 @@ void ReadParameterCovariance(const Function& function, const intptr_t num_positional_params = reader_helper.ReadListLength(); intptr_t param_index = function.NumImplicitParameters(); for (intptr_t i = 0; i < num_positional_params; ++i, ++param_index) { - VariableDeclarationHelper helper(&reader_helper); - helper.ReadUntilExcluding(VariableDeclarationHelper::kEnd); + VariableHelper helper(&reader_helper); + helper.ReadUntilExcluding(VariableHelper::kEnd); if (helper.IsCovariant()) { is_covariant->Add(param_index); @@ -519,8 +518,8 @@ void ReadParameterCovariance(const Function& function, // Named. const intptr_t num_named_params = reader_helper.ReadListLength(); for (intptr_t i = 0; i < num_named_params; ++i, ++param_index) { - VariableDeclarationHelper helper(&reader_helper); - helper.ReadUntilExcluding(VariableDeclarationHelper::kEnd); + VariableHelper helper(&reader_helper); + helper.ReadUntilExcluding(VariableHelper::kEnd); if (helper.IsCovariant()) { is_covariant->Add(param_index); diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h index cd82a7a2ff1..ec7276c0466 100644 --- a/runtime/vm/kernel_binary.h +++ b/runtime/vm/kernel_binary.h @@ -18,7 +18,7 @@ namespace kernel { // package:kernel/binary.md. static const uint32_t kMagicProgramFile = 0x90ABCDEFu; -static const uint32_t kSupportedKernelFormatVersion = 130; +static const uint32_t kSupportedKernelFormatVersion = 131; // Keep in sync with package:kernel/lib/binary/tag.dart #define KERNEL_TAG_LIST(V) \ @@ -117,7 +117,7 @@ static const uint32_t kSupportedKernelFormatVersion = 130; V(TryCatch, 75) \ V(TryFinally, 76) \ V(YieldStatement, 77) \ - V(VariableDeclaration, 78) \ + V(VariableStatement, 78) \ V(FunctionDeclaration, 79) \ V(AsyncForInStatement, 80) \ V(AssertBlock, 81) \ @@ -174,6 +174,15 @@ static const uint32_t kSupportedKernelFormatVersion = 130; V(PatternVariableDeclaration, 151) \ V(NullType, 152) \ V(RedirectingFactoryInvocation, 153) \ + V(VariableDeclaration, 154) \ + V(LocalVariable, 155) \ + V(LateVariable, 156) \ + V(SyntheticVariable, 157) \ + V(CatchVariable, 158) \ + V(PositionalParameter, 159) \ + V(NamedParameter, 160) \ + V(ThisVariable, 161) \ + V(LegacyVariable, 162) \ V(SpecializedVariableGet, 224) \ V(SpecializedVariableSet, 232) \ V(SpecializedIntLiteral, 240) diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc index a5a800e3f47..76e17780a7b 100644 --- a/runtime/vm/kernel_loader.cc +++ b/runtime/vm/kernel_loader.cc @@ -2245,16 +2245,16 @@ FunctionPtr KernelLoader::LoadClosureFunction(const Function& parent_function, const String* name; if (is_declaration) { // Read variable declaration. - VariableDeclarationHelper variable_helper(&helper_); + VariableHelper variable_helper(&helper_); - variable_helper.ReadUntilExcluding(VariableDeclarationHelper::kAnnotations); + variable_helper.ReadUntilExcluding(VariableHelper::kAnnotations); const intptr_t annotation_count = helper_.ReadListLength(); const auto& library = Library::Handle(Z, Class::Handle(Z, parent_function.Owner()).library()); ReadVMAnnotations(library, annotation_count, &pragma_bits); - variable_helper.SetJustRead(VariableDeclarationHelper::kAnnotations); + variable_helper.SetJustRead(VariableHelper::kAnnotations); - variable_helper.ReadUntilExcluding(VariableDeclarationHelper::kEnd); + variable_helper.ReadUntilExcluding(VariableHelper::kEnd); name = &H.DartSymbolObfuscate(variable_helper.name_index_); } else { name = &Symbols::AnonymousClosure();