@@ -126,9 +126,12 @@ Instruction* FlowGraphDeserializer::FirstUnhandledInstruction(
126126 return nullptr ;
127127}
128128
129- // Keep in sync with work in ParseDartValue.
129+ // Keep in sync with work in ParseDartValue. Right now, this is just a shallow
130+ // check, not a deep one.
130131bool FlowGraphDeserializer::IsHandledConstant (const Object& obj) {
131- return obj.IsNull () || obj.IsBool () || obj.IsString ();
132+ return obj.IsNull () || obj.IsBool () || obj.IsString () || obj.IsInteger () ||
133+ obj.IsDouble () || obj.IsClass () || obj.IsType () ||
134+ obj.IsTypeArguments ();
132135}
133136
134137SExpression* FlowGraphDeserializer::Retrieve (SExpList* list, intptr_t index) {
@@ -222,6 +225,16 @@ FlowGraph* FlowGraphDeserializer::ParseFlowGraph() {
222225 }
223226 }
224227
228+ // Before we return the new graph, make sure all definitions were found for
229+ // all pending values.
230+ if (values_map_.Length () > 0 ) {
231+ auto it = values_map_.GetIterator ();
232+ auto const kv = it.Next ();
233+ StoreError (new (zone ()) SExpInteger (kv->key ),
234+ " no definition found for variable index in flow graph" );
235+ return nullptr ;
236+ }
237+
225238 flow_graph_->set_max_block_id (max_block_id_);
226239 flow_graph_->set_current_ssa_temp_index (max_ssa_index_ + 1 );
227240 // Now that the deserializer has finished re-creating all the blocks in the
@@ -406,6 +419,7 @@ bool FlowGraphDeserializer::ParseDefinitionWithParsedBody(SExpList* list,
406419 }
407420
408421 definition_map_.Insert (index, def);
422+ FixPendingValues (index, def);
409423 return true ;
410424}
411425
@@ -460,13 +474,63 @@ Instruction* FlowGraphDeserializer::ParseInstruction(SExpList* list) {
460474 return inst;
461475}
462476
477+ CheckStackOverflowInstr* FlowGraphDeserializer::HandleCheckStackOverflow (
478+ SExpList* sexp,
479+ const CommonInstrInfo& info) {
480+ intptr_t stack_depth = 0 ;
481+ if (auto const stack_sexp =
482+ CheckInteger (sexp->ExtraLookupValue (" stack_depth" ))) {
483+ stack_depth = stack_sexp->value ();
484+ }
485+
486+ intptr_t loop_depth = 0 ;
487+ if (auto const loop_sexp =
488+ CheckInteger (sexp->ExtraLookupValue (" loop_depth" ))) {
489+ loop_depth = loop_sexp->value ();
490+ }
491+
492+ auto kind = CheckStackOverflowInstr::kOsrAndPreemption ;
493+ if (auto const kind_sexp = CheckSymbol (sexp->ExtraLookupValue (" kind" ))) {
494+ ASSERT (strcmp (kind_sexp->value (), " OsrOnly" ) == 0 );
495+ kind = CheckStackOverflowInstr::kOsrOnly ;
496+ }
497+
498+ return new (zone ()) CheckStackOverflowInstr (info.token_pos , stack_depth,
499+ loop_depth, info.deopt_id , kind);
500+ }
501+
502+ ParameterInstr* FlowGraphDeserializer::HandleParameter (
503+ SExpList* sexp,
504+ const CommonInstrInfo& info) {
505+ ASSERT (current_block_ != nullptr );
506+ if (auto const index_sexp = CheckInteger (Retrieve (sexp, 1 ))) {
507+ return new (zone ()) ParameterInstr (index_sexp->value (), current_block_);
508+ }
509+ return nullptr ;
510+ }
511+
463512ReturnInstr* FlowGraphDeserializer::HandleReturn (SExpList* list,
464513 const CommonInstrInfo& info) {
465514 Value* val = ParseValue (Retrieve (list, 1 ));
466515 if (val == nullptr ) return nullptr ;
467516 return new (zone ()) ReturnInstr (info.token_pos , val, info.deopt_id );
468517}
469518
519+ SpecialParameterInstr* FlowGraphDeserializer::HandleSpecialParameter (
520+ SExpList* sexp,
521+ const CommonInstrInfo& info) {
522+ ASSERT (current_block_ != nullptr );
523+ auto const kind_sexp = CheckSymbol (Retrieve (sexp, 1 ));
524+ if (kind_sexp == nullptr ) return nullptr ;
525+ SpecialParameterInstr::SpecialParameterKind kind;
526+ if (!SpecialParameterInstr::KindFromCString (kind_sexp->value (), &kind)) {
527+ StoreError (kind_sexp, " unknown special parameter kind" );
528+ return nullptr ;
529+ }
530+ return new (zone ())
531+ SpecialParameterInstr (kind, info.deopt_id , current_block_);
532+ }
533+
470534Value* FlowGraphDeserializer::ParseValue (SExpression* sexp) {
471535 auto name = sexp->AsSymbol ();
472536 CompileType* type = nullptr ;
@@ -485,9 +549,7 @@ Value* FlowGraphDeserializer::ParseValue(SExpression* sexp) {
485549 auto const def = definition_map_.LookupValue (index);
486550 Value* val;
487551 if (def == nullptr ) {
488- // TODO(sstrickl): Handle uses that come before parsed definitions.
489- StoreError (name, " use found before definition" );
490- return nullptr ;
552+ val = AddPendingValue (index);
491553 } else {
492554 val = new (zone ()) Value (def);
493555 }
@@ -581,10 +643,47 @@ bool FlowGraphDeserializer::ParseDartValue(SExpression* sexp, Object* out) {
581643
582644 // Other instance values may need to be canonicalized, so do that before
583645 // returning.
584- if (auto const b = sexp->AsBool ()) {
646+ if (auto const list = CheckTaggedList (sexp)) {
647+ auto const tag = list->At (0 )->AsSymbol ();
648+ if (strcmp (tag->value (), " Class" ) == 0 ) {
649+ auto const cid_sexp = CheckInteger (Retrieve (list, 1 ));
650+ if (cid_sexp == nullptr ) return false ;
651+ ClassTable* table = thread ()->isolate ()->class_table ();
652+ if (!table->IsValidIndex (cid_sexp->value ())) {
653+ StoreError (cid_sexp, " no class found for cid" );
654+ return false ;
655+ }
656+ *out = table->At (cid_sexp->value ());
657+ } else if (strcmp (tag->value (), " Type" ) == 0 ) {
658+ if (const auto cls_sexp = CheckTaggedList (Retrieve (list, 1 ), " Class" )) {
659+ auto & cls = Class::ZoneHandle (zone ());
660+ if (!ParseDartValue (cls_sexp, &cls)) return false ;
661+ auto & type_args = TypeArguments::ZoneHandle (zone ());
662+ if (const auto ta_sexp = CheckTaggedList (
663+ list->ExtraLookupValue (" type_args" ), " TypeArguments" )) {
664+ if (!ParseDartValue (ta_sexp, &type_args)) return false ;
665+ }
666+ *out = Type::New (cls, type_args, TokenPosition::kNoSource , Heap::kOld );
667+ // Need to set this for canonicalization.
668+ Type::Cast (*out).SetIsFinalized ();
669+ }
670+ // TODO(sstrickl): Handle types not derived from classes.
671+ } else if (strcmp (tag->value (), " TypeArguments" ) == 0 ) {
672+ *out = TypeArguments::New (list->Length () - 1 , Heap::kOld );
673+ auto & typ = AbstractType::Handle (zone ());
674+ for (intptr_t i = 1 ; i < list->Length (); i++) {
675+ if (!ParseDartValue (Retrieve (list, i), &typ)) return false ;
676+ TypeArguments::Cast (*out).SetTypeAt (i - 1 , typ);
677+ }
678+ }
679+ } else if (auto const b = sexp->AsBool ()) {
585680 *out = Bool::Get (b->value ()).raw ();
586681 } else if (auto const str = sexp->AsString ()) {
587682 *out = String::New (str->value (), Heap::kOld );
683+ } else if (auto const i = sexp->AsInteger ()) {
684+ *out = Integer::New (i->value (), Heap::kOld );
685+ } else if (auto const d = sexp->AsDouble ()) {
686+ *out = Double::New (d->value (), Heap::kOld );
588687 }
589688
590689 // If we're here and still haven't gotten a non-null value, then something
@@ -645,6 +744,29 @@ bool FlowGraphDeserializer::ParseSymbolAsPrefixedInt(SExpSymbol* sym,
645744 return true ;
646745}
647746
747+ Value* FlowGraphDeserializer::AddPendingValue (intptr_t index) {
748+ ASSERT (flow_graph_ != nullptr );
749+ ASSERT (!definition_map_.HasKey (index));
750+ auto value_list = values_map_.LookupValue (index);
751+ if (value_list == nullptr ) {
752+ value_list = new (zone ()) ZoneGrowableArray<Value*>(zone (), 2 );
753+ values_map_.Insert (index, value_list);
754+ }
755+ auto const val = new (zone ()) Value (flow_graph_->constant_null ());
756+ value_list->Add (val);
757+ return val;
758+ }
759+
760+ void FlowGraphDeserializer::FixPendingValues (intptr_t index, Definition* def) {
761+ if (auto value_list = values_map_.LookupValue (index)) {
762+ for (intptr_t i = 0 ; i < value_list->length (); i++) {
763+ auto const val = value_list->At (i);
764+ val->BindTo (def);
765+ }
766+ values_map_.Remove (index);
767+ }
768+ }
769+
648770#define BASE_CHECK_DEF (name, type ) \
649771 SExp##name* FlowGraphDeserializer::Check##name(SExpression* sexp) { \
650772 if (sexp == nullptr ) return nullptr ; \
@@ -657,6 +779,8 @@ bool FlowGraphDeserializer::ParseSymbolAsPrefixedInt(SExpSymbol* sym,
657779
658780FOR_EACH_S_EXPRESSION (BASE_CHECK_DEF)
659781
782+ #undef BASE_CHECK_DEF
783+
660784bool FlowGraphDeserializer::IsTag (SExpression* sexp, const char * label) {
661785 auto const sym = CheckSymbol (sexp);
662786 if (sym == nullptr ) return false ;
0 commit comments