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

Unified Diff: runtime/vm/code_generator_x64.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/code_generator_ia32.cc ('k') | runtime/vm/scopes.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/code_generator_x64.cc
===================================================================
--- runtime/vm/code_generator_x64.cc (revision 4199)
+++ runtime/vm/code_generator_x64.cc (working copy)
@@ -984,13 +984,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.
__ movq(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());
+ }
}
@@ -1219,6 +1221,7 @@
}
node->operand()->Visit(this);
if (node->kind() == Token::kADD) {
+ // TODO(srdjan): Remove this as it is not part of Dart language any longer.
// Unary operator '+' does not exist, it's a NOP, skip it.
if (!IsResultNeeded(node)) {
__ popq(RAX);
@@ -1989,18 +1992,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) {
- __ movq(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) {
+ __ movq(CTX, FieldAddress(CTX, Context::parent_offset()));
+ }
if (node->kind() == Token::kBREAK) {
__ jmp(label->break_label());
« no previous file with comments | « runtime/vm/code_generator_ia32.cc ('k') | runtime/vm/scopes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698