@@ -948,6 +948,25 @@ bool ActivationFrame::HandlesException(const Instance& exc_obj) {
948948 return false ;
949949}
950950
951+ intptr_t ActivationFrame::GetAwaitJumpVariable () {
952+ GetVarDescriptors ();
953+ intptr_t var_desc_len = var_descriptors_.Length ();
954+ intptr_t await_jump_var = -1 ;
955+ for (intptr_t i = 0 ; i < var_desc_len; i++) {
956+ RawLocalVarDescriptors::VarInfo var_info;
957+ var_descriptors_.GetInfo (i, &var_info);
958+ const int8_t kind = var_info.kind ();
959+ if (var_descriptors_.GetName (i) == Symbols::AwaitJumpVar ().raw ()) {
960+ ASSERT (kind == RawLocalVarDescriptors::kContextVar );
961+ ASSERT (!ctx_.IsNull ());
962+ Object& await_jump_index = Object::Handle (ctx_.At (var_info.index ()));
963+ ASSERT (await_jump_index.IsSmi ());
964+ await_jump_var = Smi::Cast (await_jump_index).Value ();
965+ }
966+ }
967+ return await_jump_var;
968+ }
969+
951970void ActivationFrame::ExtractTokenPositionFromAsyncClosure () {
952971 // Attempt to determine the token pos and try index from the async closure.
953972 Thread* thread = Thread::Current ();
@@ -958,28 +977,46 @@ void ActivationFrame::ExtractTokenPositionFromAsyncClosure() {
958977 // This should only be called on frames that aren't active on the stack.
959978 ASSERT (fp () == 0 );
960979
980+ if (function_.is_declared_in_bytecode ()) {
981+ #if !defined(DART_PRECOMPILED_RUNTIME)
982+ const auto & bytecode = Bytecode::Handle (zone, function_.bytecode ());
983+ if (!bytecode.HasSourcePositions ()) {
984+ return ;
985+ }
986+ const intptr_t await_jump_var = GetAwaitJumpVariable ();
987+ if (await_jump_var < 0 ) {
988+ return ;
989+ }
990+ // Yield points are counted from 1 (0 is reserved for normal entry).
991+ intptr_t yield_point_index = 1 ;
992+ kernel::BytecodeSourcePositionsIterator iter (zone, bytecode);
993+ while (iter.MoveNext ()) {
994+ if (iter.IsYieldPoint ()) {
995+ if (yield_point_index == await_jump_var) {
996+ token_pos_ = iter.TokenPos ();
997+ token_pos_initialized_ = true ;
998+ try_index_ = bytecode.GetTryIndexAtPc (bytecode.PayloadStart () +
999+ iter.PcOffset ());
1000+ return ;
1001+ }
1002+ ++yield_point_index;
1003+ }
1004+ }
1005+ return ;
1006+ #else
1007+ UNREACHABLE ();
1008+ #endif // !defined(DART_PRECOMPILED_RUNTIME)
1009+ }
1010+
1011+ ASSERT (!IsInterpreted ());
9611012 ASSERT (script.kind () == RawScript::kKernelTag );
9621013 const Array& await_to_token_map =
9631014 Array::Handle (zone, script.yield_positions ());
9641015 if (await_to_token_map.IsNull ()) {
9651016 // No mapping.
9661017 return ;
9671018 }
968- GetVarDescriptors ();
969- intptr_t var_desc_len = var_descriptors_.Length ();
970- intptr_t await_jump_var = -1 ;
971- for (intptr_t i = 0 ; i < var_desc_len; i++) {
972- RawLocalVarDescriptors::VarInfo var_info;
973- var_descriptors_.GetInfo (i, &var_info);
974- const int8_t kind = var_info.kind ();
975- if (var_descriptors_.GetName (i) == Symbols::AwaitJumpVar ().raw ()) {
976- ASSERT (kind == RawLocalVarDescriptors::kContextVar );
977- ASSERT (!ctx_.IsNull ());
978- Object& await_jump_index = Object::Handle (ctx_.At (var_info.index ()));
979- ASSERT (await_jump_index.IsSmi ());
980- await_jump_var = Smi::Cast (await_jump_index).Value ();
981- }
982- }
1019+ const intptr_t await_jump_var = GetAwaitJumpVariable ();
9831020 if (await_jump_var < 0 ) {
9841021 return ;
9851022 }
@@ -1011,29 +1048,6 @@ void ActivationFrame::ExtractTokenPositionFromAsyncClosure() {
10111048 ASSERT (token_pos.IsSmi ());
10121049 token_pos_ = TokenPosition (Smi::Cast (token_pos).Value ());
10131050 token_pos_initialized_ = true ;
1014- if (IsInterpreted ()) {
1015- #if !defined(DART_PRECOMPILED_RUNTIME)
1016- // In order to determine the try index, we need to map the token position
1017- // to a pc offset, and then a pc offset to the try index.
1018- // TODO(regis): Should we set the token position fields in pc descriptors?
1019- uword pc_offset = kUwordMax ;
1020- kernel::BytecodeSourcePositionsIterator iter (zone, bytecode ());
1021- while (iter.MoveNext ()) {
1022- // PcOffsets are monotonic in source positions, so we get the lowest one.
1023- if (iter.TokenPos () == token_pos_) {
1024- pc_offset = iter.PcOffset ();
1025- break ;
1026- }
1027- }
1028- if (pc_offset < kUwordMax ) {
1029- try_index_ =
1030- bytecode ().GetTryIndexAtPc (bytecode ().PayloadStart () + pc_offset);
1031- }
1032- #else
1033- UNREACHABLE ();
1034- #endif // !defined(DART_PRECOMPILED_RUNTIME)
1035- return ;
1036- }
10371051 GetPcDescriptors ();
10381052 PcDescriptors::Iterator iter (pc_desc_, RawPcDescriptors::kAnyKind );
10391053 while (iter.MoveNext ()) {
@@ -4170,6 +4184,23 @@ bool Debugger::IsAtAsyncJump(ActivationFrame* top_frame) {
41704184 if (!closure_or_null.IsNull ()) {
41714185 ASSERT (closure_or_null.IsInstance ());
41724186 ASSERT (Instance::Cast (closure_or_null).IsClosure ());
4187+ if (top_frame->function ().is_declared_in_bytecode ()) {
4188+ #if !defined(DART_PRECOMPILED_RUNTIME)
4189+ const auto & bytecode =
4190+ Bytecode::Handle (zone, top_frame->function ().bytecode ());
4191+ const TokenPosition token_pos = top_frame->TokenPos ();
4192+ kernel::BytecodeSourcePositionsIterator iter (zone, bytecode);
4193+ while (iter.MoveNext ()) {
4194+ if (iter.IsYieldPoint () && (iter.TokenPos () == token_pos)) {
4195+ return true ;
4196+ }
4197+ }
4198+ return false ;
4199+ #else
4200+ UNREACHABLE ();
4201+ #endif // !defined(DART_PRECOMPILED_RUNTIME)
4202+ }
4203+ ASSERT (!top_frame->IsInterpreted ());
41734204 const Script& script = Script::Handle (zone, top_frame->SourceScript ());
41744205 ASSERT (script.kind () == RawScript::kKernelTag );
41754206 // Are we at a yield point (previous await)?
0 commit comments