@@ -2194,15 +2194,8 @@ Fragment StreamingFlowGraphBuilder::BuildVariableSet(TokenPosition* p) {
21942194 if (p != NULL ) *p = position;
21952195
21962196 intptr_t variable_kernel_position = ReadUInt (); // read kernel position.
2197- ReadUInt (); // read relative variable index.
2198- Fragment instructions = BuildExpression (); // read expression.
2199-
2200- if (NeedsDebugStepCheck (stack (), position)) {
2201- instructions = DebugStepCheck (position) + instructions;
2202- }
2203- instructions +=
2204- StoreLocal (position, LookupVariable (variable_kernel_position));
2205- return instructions;
2197+ ReadUInt (); // read relative variable index.
2198+ return BuildVariableSetImpl (position, variable_kernel_position);
22062199}
22072200
22082201Fragment StreamingFlowGraphBuilder::BuildVariableSet (uint8_t payload,
@@ -2211,13 +2204,49 @@ Fragment StreamingFlowGraphBuilder::BuildVariableSet(uint8_t payload,
22112204 if (p != NULL ) *p = position;
22122205
22132206 intptr_t variable_kernel_position = ReadUInt (); // read kernel position.
2214- Fragment instructions = BuildExpression (); // read expression.
2207+ return BuildVariableSetImpl (position, variable_kernel_position);
2208+ }
22152209
2210+ Fragment StreamingFlowGraphBuilder::BuildVariableSetImpl (
2211+ TokenPosition position,
2212+ intptr_t variable_kernel_position) {
2213+ Fragment instructions = BuildExpression (); // read expression.
22162214 if (NeedsDebugStepCheck (stack (), position)) {
22172215 instructions = DebugStepCheck (position) + instructions;
22182216 }
2219- instructions +=
2220- StoreLocal (position, LookupVariable (variable_kernel_position));
2217+
2218+ LocalVariable* variable = LookupVariable (variable_kernel_position);
2219+ if (variable->is_late () && variable->is_final ()) {
2220+ // Late final variable, so check whether it has been initialized.
2221+ LocalVariable* expr_temp = MakeTemporary ();
2222+ instructions += LoadLocal (variable);
2223+ TargetEntryInstr *is_uninitialized, *is_initialized;
2224+ instructions += Constant (Object::sentinel ());
2225+ instructions += flow_graph_builder_->BranchIfStrictEqual (&is_uninitialized,
2226+ &is_initialized);
2227+ JoinEntryInstr* join = BuildJoinEntry ();
2228+
2229+ {
2230+ // The variable is uninitialized, so store the expression value.
2231+ Fragment initialize (is_uninitialized);
2232+ initialize += LoadLocal (expr_temp);
2233+ initialize += StoreLocal (position, variable);
2234+ initialize += Drop ();
2235+ initialize += Goto (join);
2236+ }
2237+
2238+ {
2239+ // Already initialized, so throw a LateInitializationError.
2240+ Fragment already_initialized (is_initialized);
2241+ already_initialized += flow_graph_builder_->ThrowLateInitializationError (
2242+ position, variable->name ());
2243+ already_initialized += Goto (join);
2244+ }
2245+
2246+ instructions = Fragment (instructions.entry , join);
2247+ } else {
2248+ instructions += StoreLocal (position, variable);
2249+ }
22212250
22222251 return instructions;
22232252}
0 commit comments