Skip to content

Commit

Permalink
[vm/debugger] Pick the correct context async variable in bytecode fra…
Browse files Browse the repository at this point in the history
…mes.

Variable descriptors constructed from bytecode have all variables of
enclosing functions, even shadowed by the current function.
Pick the variable with the highest context level.

This fixes service/regress_28443_test.dart failure in bytecode mode.

Change-Id: Ifd0db566b5e74d29075ed17e91810ffe6953af77
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/116140
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Régis Crelier <regis@google.com>
  • Loading branch information
crelier authored and commit-bot@chromium.org committed Sep 7, 2019
1 parent 68dede0 commit c0f49b0
Showing 1 changed file with 32 additions and 18 deletions.
50 changes: 32 additions & 18 deletions runtime/vm/debugger.cc
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,8 @@ RawObject* ActivationFrame::GetAsyncContextVariable(const String& name) {
return Object::null();
}
GetVarDescriptors();
intptr_t var_ctxt_level = -1;
intptr_t ctxt_slot = -1;
intptr_t var_desc_len = var_descriptors_.Length();
for (intptr_t i = 0; i < var_desc_len; i++) {
RawLocalVarDescriptors::VarInfo var_info;
Expand All @@ -855,21 +857,29 @@ RawObject* ActivationFrame::GetAsyncContextVariable(const String& name) {
return GetStackVar(variable_index);
} else {
ASSERT(kind == RawLocalVarDescriptors::kContextVar);
if (!live_frame_) {
ASSERT(!ctx_.IsNull());
// Compiled code uses relative context levels, i.e. the frame context
// level is always 0 on entry.
// Bytecode uses absolute context levels, i.e. the frame context level
// on entry must be calculated.
const intptr_t frame_ctx_level =
function().is_declared_in_bytecode() ? ctx_.GetLevel() : 0;
return GetRelativeContextVar(var_info.scope_id,
variable_index.value(), frame_ctx_level);
// Variable descriptors constructed from bytecode have all variables of
// enclosing functions, even shadowed by the current function.
// Pick the variable with the highest context level.
if (var_info.scope_id > var_ctxt_level) {
var_ctxt_level = var_info.scope_id;
ctxt_slot = variable_index.value();
}
return GetContextVar(var_info.scope_id, variable_index.value());
}
}
}
if (var_ctxt_level >= 0) {
if (!live_frame_) {
ASSERT(!ctx_.IsNull());
// Compiled code uses relative context levels, i.e. the frame context
// level is always 0 on entry.
// Bytecode uses absolute context levels, i.e. the frame context level
// on entry must be calculated.
const intptr_t frame_ctx_level =
function().is_declared_in_bytecode() ? ctx_.GetLevel() : 0;
return GetRelativeContextVar(var_ctxt_level, ctxt_slot, frame_ctx_level);
}
return GetContextVar(var_ctxt_level, ctxt_slot);
}
return Object::null();
}

Expand Down Expand Up @@ -987,6 +997,8 @@ bool ActivationFrame::HandlesException(const Instance& exc_obj) {

intptr_t ActivationFrame::GetAwaitJumpVariable() {
GetVarDescriptors();
intptr_t var_ctxt_level = -1;
intptr_t ctxt_slot = -1;
intptr_t var_desc_len = var_descriptors_.Length();
intptr_t await_jump_var = -1;
for (intptr_t i = 0; i < var_desc_len; i++) {
Expand All @@ -998,16 +1010,18 @@ intptr_t ActivationFrame::GetAwaitJumpVariable() {
ASSERT(!ctx_.IsNull());
// Variable descriptors constructed from bytecode have all variables of
// enclosing functions, even shadowed by the current function.
// Check context level in order to pick correct :await_jump_var variable.
if (function().is_declared_in_bytecode() &&
(ctx_.GetLevel() != var_info.scope_id)) {
continue;
// Pick the :await_jump_var variable with the highest context level.
if (var_info.scope_id > var_ctxt_level) {
var_ctxt_level = var_info.scope_id;
ctxt_slot = var_info.index();
}
Object& await_jump_index = Object::Handle(ctx_.At(var_info.index()));
ASSERT(await_jump_index.IsSmi());
await_jump_var = Smi::Cast(await_jump_index).Value();
}
}
if (var_ctxt_level >= 0) {
Object& await_jump_index = Object::Handle(ctx_.At(ctxt_slot));
ASSERT(await_jump_index.IsSmi());
await_jump_var = Smi::Cast(await_jump_index).Value();
}
return await_jump_var;
}

Expand Down

0 comments on commit c0f49b0

Please sign in to comment.