Skip to content

Commit

Permalink
[vm] Fix late final local variables in AST mode
Browse files Browse the repository at this point in the history
- Modify setter logic for late final local variables.
- Remove extra visitVariableDeclaration in late_var_init_transformer
  that was causing nodes to be visited multiple times.

Bug: #38841
Change-Id: Id39925e4b9560a1da1b01e1cf14ef20c515f3928
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/127720
Commit-Queue: Liam Appelbe <liama@google.com>
Reviewed-by: Régis Crelier <regis@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
  • Loading branch information
liamappelbe authored and commit-bot@chromium.org committed Dec 9, 2019
1 parent 991e55f commit a17884a
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 14 deletions.
2 changes: 0 additions & 2 deletions pkg/vm/lib/transformations/late_var_init_transformer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ class _LateVarInitTransformer extends Transformer {
}

List<Statement> _transformVariableDeclaration(VariableDeclaration node) {
super.visitVariableDeclaration(node);

final fnNode =
FunctionNode(ReturnStatement(node.initializer), returnType: node.type);
final fn = FunctionDeclaration(
Expand Down
53 changes: 41 additions & 12 deletions runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2194,15 +2194,8 @@ Fragment StreamingFlowGraphBuilder::BuildVariableSet(TokenPosition* p) {
if (p != NULL) *p = position;

intptr_t variable_kernel_position = ReadUInt(); // read kernel position.
ReadUInt(); // read relative variable index.
Fragment instructions = BuildExpression(); // read expression.

if (NeedsDebugStepCheck(stack(), position)) {
instructions = DebugStepCheck(position) + instructions;
}
instructions +=
StoreLocal(position, LookupVariable(variable_kernel_position));
return instructions;
ReadUInt(); // read relative variable index.
return BuildVariableSetImpl(position, variable_kernel_position);
}

Fragment StreamingFlowGraphBuilder::BuildVariableSet(uint8_t payload,
Expand All @@ -2211,13 +2204,49 @@ Fragment StreamingFlowGraphBuilder::BuildVariableSet(uint8_t payload,
if (p != NULL) *p = position;

intptr_t variable_kernel_position = ReadUInt(); // read kernel position.
Fragment instructions = BuildExpression(); // read expression.
return BuildVariableSetImpl(position, variable_kernel_position);
}

Fragment StreamingFlowGraphBuilder::BuildVariableSetImpl(
TokenPosition position,
intptr_t variable_kernel_position) {
Fragment instructions = BuildExpression(); // read expression.
if (NeedsDebugStepCheck(stack(), position)) {
instructions = DebugStepCheck(position) + instructions;
}
instructions +=
StoreLocal(position, LookupVariable(variable_kernel_position));

LocalVariable* variable = LookupVariable(variable_kernel_position);
if (variable->is_late() && variable->is_final()) {
// Late final variable, so check whether it has been initialized.
LocalVariable* expr_temp = MakeTemporary();
instructions += LoadLocal(variable);
TargetEntryInstr *is_uninitialized, *is_initialized;
instructions += Constant(Object::sentinel());
instructions += flow_graph_builder_->BranchIfStrictEqual(&is_uninitialized,
&is_initialized);
JoinEntryInstr* join = BuildJoinEntry();

{
// The variable is uninitialized, so store the expression value.
Fragment initialize(is_uninitialized);
initialize += LoadLocal(expr_temp);
initialize += StoreLocal(position, variable);
initialize += Drop();
initialize += Goto(join);
}

{
// Already initialized, so throw a LateInitializationError.
Fragment already_initialized(is_initialized);
already_initialized += flow_graph_builder_->ThrowLateInitializationError(
position, variable->name());
already_initialized += Goto(join);
}

instructions = Fragment(instructions.entry, join);
} else {
instructions += StoreLocal(position, variable);
}

return instructions;
}
Expand Down
2 changes: 2 additions & 0 deletions runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,8 @@ class StreamingFlowGraphBuilder : public KernelReaderHelper {
TokenPosition position);
Fragment BuildVariableSet(TokenPosition* position);
Fragment BuildVariableSet(uint8_t payload, TokenPosition* position);
Fragment BuildVariableSetImpl(TokenPosition position,
intptr_t variable_kernel_position);
Fragment BuildPropertyGet(TokenPosition* position);
Fragment BuildPropertySet(TokenPosition* position);
Fragment BuildAllocateInvocationMirrorCall(TokenPosition position,
Expand Down

0 comments on commit a17884a

Please sign in to comment.