Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1856)

Unified Diff: runtime/vm/code_generator_ia32.cc

Issue 9392020: Fix context unchaining (issue 5991015). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/ast_printer.cc ('k') | runtime/vm/code_generator_x64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/code_generator_ia32.cc
===================================================================
--- runtime/vm/code_generator_ia32.cc (revision 4199)
+++ runtime/vm/code_generator_ia32.cc (working copy)
@@ -1,4 +1,4 @@
-// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -987,13 +987,15 @@
state()->set_root_node(child_node);
child_node->Visit(this);
}
- if (node_sequence->label() != NULL) {
- __ Bind(node_sequence->label()->break_label());
- }
if (num_context_variables > 0) {
// Unchain the previously allocated context.
__ movl(CTX, FieldAddress(CTX, Context::parent_offset()));
}
+ // If this node sequence is labeled, a break out of the sequence will have
+ // taken care of unchaining the context.
+ if (node_sequence->label() != NULL) {
+ __ Bind(node_sequence->label()->break_label());
+ }
}
@@ -1993,18 +1995,29 @@
// Unchain the context(s) up to the outer context level of the scope which
// contains the destination label.
ASSERT(label->owner() != NULL);
- LocalScope* outer_context_owner = label->owner()->parent();
- ASSERT(outer_context_owner != NULL);
int target_context_level = 0;
- if (outer_context_owner->HasContextLevel()) {
- target_context_level = outer_context_owner->context_level();
- ASSERT(target_context_level >= 0);
- int context_level = state()->context_level();
- ASSERT(context_level >= target_context_level);
- while (context_level-- > target_context_level) {
- __ movl(CTX, FieldAddress(CTX, Context::parent_offset()));
+ LocalScope* target_scope = label->owner();
+ if (target_scope->num_context_variables() > 0) {
+ // The scope of the target label allocates a context, therefore its outer
+ // scope is at a lower context level.
+ target_context_level = target_scope->context_level() - 1;
+ } else {
+ // The scope of the target label does not allocate a context, so its outer
+ // scope is at the same context level. Find it.
+ while ((target_scope != NULL) &&
+ (target_scope->num_context_variables() == 0)) {
+ target_scope = target_scope->parent();
}
+ if (target_scope != NULL) {
+ target_context_level = target_scope->context_level();
+ }
}
+ ASSERT(target_context_level >= 0);
+ int context_level = state()->context_level();
+ ASSERT(context_level >= target_context_level);
+ while (context_level-- > target_context_level) {
+ __ movl(CTX, FieldAddress(CTX, Context::parent_offset()));
+ }
if (node->kind() == Token::kBREAK) {
__ jmp(label->break_label());
« no previous file with comments | « runtime/vm/ast_printer.cc ('k') | runtime/vm/code_generator_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698