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

Side by Side Diff: runtime/vm/scopes.cc

Issue 2974233002: VM: Re-format to use at most one newline between functions (Closed)
Patch Set: Rebase and merge Created 3 years, 5 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 unified diff | Download patch
« no previous file with comments | « runtime/vm/scopes.h ('k') | runtime/vm/scopes_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/scopes.h" 5 #include "vm/scopes.h"
6 6
7 #include "vm/object.h" 7 #include "vm/object.h"
8 #include "vm/stack_frame.h" 8 #include "vm/stack_frame.h"
9 #include "vm/symbols.h" 9 #include "vm/symbols.h"
10 10
11 namespace dart { 11 namespace dart {
12 12
13 DEFINE_FLAG(bool, 13 DEFINE_FLAG(bool,
14 share_enclosing_context, 14 share_enclosing_context,
15 true, 15 true,
16 "Allocate captured variables in the existing context of an " 16 "Allocate captured variables in the existing context of an "
17 "enclosing scope (up to innermost loop) and spare the allocation " 17 "enclosing scope (up to innermost loop) and spare the allocation "
18 "of a local context."); 18 "of a local context.");
19 19
20 int SourceLabel::FunctionLevel() const { 20 int SourceLabel::FunctionLevel() const {
21 ASSERT(owner() != NULL); 21 ASSERT(owner() != NULL);
22 return owner()->function_level(); 22 return owner()->function_level();
23 } 23 }
24 24
25
26 LocalScope::LocalScope(LocalScope* parent, int function_level, int loop_level) 25 LocalScope::LocalScope(LocalScope* parent, int function_level, int loop_level)
27 : parent_(parent), 26 : parent_(parent),
28 child_(NULL), 27 child_(NULL),
29 sibling_(NULL), 28 sibling_(NULL),
30 function_level_(function_level), 29 function_level_(function_level),
31 loop_level_(loop_level), 30 loop_level_(loop_level),
32 context_level_(LocalScope::kUnitializedContextLevel), 31 context_level_(LocalScope::kUnitializedContextLevel),
33 num_context_variables_(0), 32 num_context_variables_(0),
34 begin_token_pos_(TokenPosition::kNoSourcePos), 33 begin_token_pos_(TokenPosition::kNoSourcePos),
35 end_token_pos_(TokenPosition::kNoSourcePos), 34 end_token_pos_(TokenPosition::kNoSourcePos),
36 variables_(), 35 variables_(),
37 labels_(), 36 labels_(),
38 referenced_() { 37 referenced_() {
39 // Hook this node into the children of the parent, unless the parent has a 38 // Hook this node into the children of the parent, unless the parent has a
40 // different function_level, since the local scope of a nested function can 39 // different function_level, since the local scope of a nested function can
41 // be discarded after it has been parsed. 40 // be discarded after it has been parsed.
42 if ((parent != NULL) && (parent->function_level() == function_level)) { 41 if ((parent != NULL) && (parent->function_level() == function_level)) {
43 sibling_ = parent->child_; 42 sibling_ = parent->child_;
44 parent->child_ = this; 43 parent->child_ = this;
45 } 44 }
46 } 45 }
47 46
48
49 bool LocalScope::IsNestedWithin(LocalScope* scope) const { 47 bool LocalScope::IsNestedWithin(LocalScope* scope) const {
50 const LocalScope* current_scope = this; 48 const LocalScope* current_scope = this;
51 while (current_scope != NULL) { 49 while (current_scope != NULL) {
52 if (current_scope == scope) { 50 if (current_scope == scope) {
53 return true; 51 return true;
54 } 52 }
55 current_scope = current_scope->parent(); 53 current_scope = current_scope->parent();
56 } 54 }
57 return false; 55 return false;
58 } 56 }
59 57
60
61 bool LocalScope::AddVariable(LocalVariable* variable) { 58 bool LocalScope::AddVariable(LocalVariable* variable) {
62 ASSERT(variable != NULL); 59 ASSERT(variable != NULL);
63 if (LocalLookupVariable(variable->name()) != NULL) { 60 if (LocalLookupVariable(variable->name()) != NULL) {
64 return false; 61 return false;
65 } 62 }
66 variables_.Add(variable); 63 variables_.Add(variable);
67 if (variable->owner() == NULL) { 64 if (variable->owner() == NULL) {
68 // Variables must be added to their owner scope first. Subsequent calls 65 // Variables must be added to their owner scope first. Subsequent calls
69 // to 'add' treat the variable as an alias. 66 // to 'add' treat the variable as an alias.
70 variable->set_owner(this); 67 variable->set_owner(this);
71 } 68 }
72 return true; 69 return true;
73 } 70 }
74 71
75
76 bool LocalScope::InsertParameterAt(intptr_t pos, LocalVariable* parameter) { 72 bool LocalScope::InsertParameterAt(intptr_t pos, LocalVariable* parameter) {
77 ASSERT(parameter != NULL); 73 ASSERT(parameter != NULL);
78 if (LocalLookupVariable(parameter->name()) != NULL) { 74 if (LocalLookupVariable(parameter->name()) != NULL) {
79 return false; 75 return false;
80 } 76 }
81 variables_.InsertAt(pos, parameter); 77 variables_.InsertAt(pos, parameter);
82 // InsertParameterAt is not used to add aliases of parameters. 78 // InsertParameterAt is not used to add aliases of parameters.
83 ASSERT(parameter->owner() == NULL); 79 ASSERT(parameter->owner() == NULL);
84 parameter->set_owner(this); 80 parameter->set_owner(this);
85 return true; 81 return true;
86 } 82 }
87 83
88
89 bool LocalScope::AddLabel(SourceLabel* label) { 84 bool LocalScope::AddLabel(SourceLabel* label) {
90 if (LocalLookupLabel(label->name()) != NULL) { 85 if (LocalLookupLabel(label->name()) != NULL) {
91 return false; 86 return false;
92 } 87 }
93 labels_.Add(label); 88 labels_.Add(label);
94 if (label->owner() == NULL) { 89 if (label->owner() == NULL) {
95 // Labels must be added to their owner scope first. Subsequent calls 90 // Labels must be added to their owner scope first. Subsequent calls
96 // to 'add' treat the label as an alias. 91 // to 'add' treat the label as an alias.
97 label->set_owner(this); 92 label->set_owner(this);
98 } 93 }
99 return true; 94 return true;
100 } 95 }
101 96
102
103 void LocalScope::MoveLabel(SourceLabel* label) { 97 void LocalScope::MoveLabel(SourceLabel* label) {
104 ASSERT(LocalLookupLabel(label->name()) == NULL); 98 ASSERT(LocalLookupLabel(label->name()) == NULL);
105 ASSERT(label->kind() == SourceLabel::kForward); 99 ASSERT(label->kind() == SourceLabel::kForward);
106 labels_.Add(label); 100 labels_.Add(label);
107 label->set_owner(this); 101 label->set_owner(this);
108 } 102 }
109 103
110
111 NameReference* LocalScope::FindReference(const String& name) const { 104 NameReference* LocalScope::FindReference(const String& name) const {
112 ASSERT(name.IsSymbol()); 105 ASSERT(name.IsSymbol());
113 intptr_t num_references = referenced_.length(); 106 intptr_t num_references = referenced_.length();
114 for (intptr_t i = 0; i < num_references; i++) { 107 for (intptr_t i = 0; i < num_references; i++) {
115 if (name.raw() == referenced_[i]->name().raw()) { 108 if (name.raw() == referenced_[i]->name().raw()) {
116 return referenced_[i]; 109 return referenced_[i];
117 } 110 }
118 } 111 }
119 return NULL; 112 return NULL;
120 } 113 }
121 114
122
123 void LocalScope::AddReferencedName(TokenPosition token_pos, 115 void LocalScope::AddReferencedName(TokenPosition token_pos,
124 const String& name) { 116 const String& name) {
125 if (LocalLookupVariable(name) != NULL) { 117 if (LocalLookupVariable(name) != NULL) {
126 return; 118 return;
127 } 119 }
128 NameReference* ref = FindReference(name); 120 NameReference* ref = FindReference(name);
129 if (ref != NULL) { 121 if (ref != NULL) {
130 ref->set_token_pos(token_pos); 122 ref->set_token_pos(token_pos);
131 return; 123 return;
132 } 124 }
133 ref = new NameReference(token_pos, name); 125 ref = new NameReference(token_pos, name);
134 referenced_.Add(ref); 126 referenced_.Add(ref);
135 // Add name reference in innermost enclosing scopes that do not 127 // Add name reference in innermost enclosing scopes that do not
136 // define a local variable with this name. 128 // define a local variable with this name.
137 LocalScope* scope = this->parent(); 129 LocalScope* scope = this->parent();
138 while (scope != NULL && (scope->LocalLookupVariable(name) == NULL)) { 130 while (scope != NULL && (scope->LocalLookupVariable(name) == NULL)) {
139 scope->referenced_.Add(ref); 131 scope->referenced_.Add(ref);
140 scope = scope->parent(); 132 scope = scope->parent();
141 } 133 }
142 } 134 }
143 135
144
145 TokenPosition LocalScope::PreviousReferencePos(const String& name) const { 136 TokenPosition LocalScope::PreviousReferencePos(const String& name) const {
146 NameReference* ref = FindReference(name); 137 NameReference* ref = FindReference(name);
147 if (ref != NULL) { 138 if (ref != NULL) {
148 return ref->token_pos(); 139 return ref->token_pos();
149 } 140 }
150 return TokenPosition::kNoSource; 141 return TokenPosition::kNoSource;
151 } 142 }
152 143
153
154 void LocalScope::AllocateContextVariable(LocalVariable* variable, 144 void LocalScope::AllocateContextVariable(LocalVariable* variable,
155 LocalScope** context_owner) { 145 LocalScope** context_owner) {
156 ASSERT(variable->is_captured()); 146 ASSERT(variable->is_captured());
157 ASSERT(variable->owner() == this); 147 ASSERT(variable->owner() == this);
158 // The context level in the owner scope of a captured variable indicates at 148 // The context level in the owner scope of a captured variable indicates at
159 // code generation time how far to walk up the context chain in order to 149 // code generation time how far to walk up the context chain in order to
160 // access the variable from the current context level. 150 // access the variable from the current context level.
161 if ((*context_owner) == NULL) { 151 if ((*context_owner) == NULL) {
162 ASSERT(num_context_variables_ == 0); 152 ASSERT(num_context_variables_ == 0);
163 // This scope becomes the current context owner. 153 // This scope becomes the current context owner.
(...skipping 20 matching lines...) Expand all
184 if (!HasContextLevel()) { 174 if (!HasContextLevel()) {
185 ASSERT(variable->owner() != *context_owner); 175 ASSERT(variable->owner() != *context_owner);
186 set_context_level((*context_owner)->context_level()); 176 set_context_level((*context_owner)->context_level());
187 } else { 177 } else {
188 ASSERT(context_level() == (*context_owner)->context_level()); 178 ASSERT(context_level() == (*context_owner)->context_level());
189 } 179 }
190 } 180 }
191 variable->set_index((*context_owner)->num_context_variables_++); 181 variable->set_index((*context_owner)->num_context_variables_++);
192 } 182 }
193 183
194
195 int LocalScope::AllocateVariables(int first_parameter_index, 184 int LocalScope::AllocateVariables(int first_parameter_index,
196 int num_parameters, 185 int num_parameters,
197 int first_frame_index, 186 int first_frame_index,
198 LocalScope* context_owner, 187 LocalScope* context_owner,
199 bool* found_captured_variables) { 188 bool* found_captured_variables) {
200 // We should not allocate variables of nested functions while compiling an 189 // We should not allocate variables of nested functions while compiling an
201 // enclosing function. 190 // enclosing function.
202 ASSERT(function_level() == 0); 191 ASSERT(function_level() == 0);
203 ASSERT(num_parameters >= 0); 192 ASSERT(num_parameters >= 0);
204 // Parameters must be listed first and must all appear in the top scope. 193 // Parameters must be listed first and must all appear in the top scope.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 dummy_parameter_index, num_parameters_in_child, frame_index, 248 dummy_parameter_index, num_parameters_in_child, frame_index,
260 context_owner, found_captured_variables); 249 context_owner, found_captured_variables);
261 if (child_frame_index < min_frame_index) { 250 if (child_frame_index < min_frame_index) {
262 min_frame_index = child_frame_index; 251 min_frame_index = child_frame_index;
263 } 252 }
264 child = child->sibling(); 253 child = child->sibling();
265 } 254 }
266 return min_frame_index; 255 return min_frame_index;
267 } 256 }
268 257
269
270 // The parser creates internal variables that start with ":" 258 // The parser creates internal variables that start with ":"
271 static bool IsFilteredIdentifier(const String& str) { 259 static bool IsFilteredIdentifier(const String& str) {
272 ASSERT(str.Length() > 0); 260 ASSERT(str.Length() > 0);
273 if (str.raw() == Symbols::AsyncOperation().raw()) { 261 if (str.raw() == Symbols::AsyncOperation().raw()) {
274 // Keep :async_op for asynchronous debugging. 262 // Keep :async_op for asynchronous debugging.
275 return false; 263 return false;
276 } 264 }
277 if (str.raw() == Symbols::AsyncCompleter().raw()) { 265 if (str.raw() == Symbols::AsyncCompleter().raw()) {
278 // Keep :async_completer for asynchronous debugging. 266 // Keep :async_completer for asynchronous debugging.
279 return false; 267 return false;
280 } 268 }
281 if (str.raw() == Symbols::ControllerStream().raw()) { 269 if (str.raw() == Symbols::ControllerStream().raw()) {
282 // Keep :controller_stream for asynchronous debugging. 270 // Keep :controller_stream for asynchronous debugging.
283 return false; 271 return false;
284 } 272 }
285 if (str.raw() == Symbols::AwaitJumpVar().raw()) { 273 if (str.raw() == Symbols::AwaitJumpVar().raw()) {
286 // Keep :await_jump_var for asynchronous debugging. 274 // Keep :await_jump_var for asynchronous debugging.
287 return false; 275 return false;
288 } 276 }
289 if (str.raw() == Symbols::AsyncStackTraceVar().raw()) { 277 if (str.raw() == Symbols::AsyncStackTraceVar().raw()) {
290 // Keep :async_stack_trace for asynchronous debugging. 278 // Keep :async_stack_trace for asynchronous debugging.
291 return false; 279 return false;
292 } 280 }
293 return str.CharAt(0) == ':'; 281 return str.CharAt(0) == ':';
294 } 282 }
295 283
296
297 RawLocalVarDescriptors* LocalScope::GetVarDescriptors( 284 RawLocalVarDescriptors* LocalScope::GetVarDescriptors(
298 const Function& func, 285 const Function& func,
299 ZoneGrowableArray<intptr_t>* context_level_array) { 286 ZoneGrowableArray<intptr_t>* context_level_array) {
300 GrowableArray<VarDesc> vars(8); 287 GrowableArray<VarDesc> vars(8);
301 288
302 // Record deopt-id -> context-level mappings, using ranges of deopt-ids with 289 // Record deopt-id -> context-level mappings, using ranges of deopt-ids with
303 // the same context-level. [context_level_array] contains (deopt_id, 290 // the same context-level. [context_level_array] contains (deopt_id,
304 // context_level) tuples. 291 // context_level) tuples.
305 for (intptr_t start = 0; start < context_level_array->length();) { 292 for (intptr_t start = 0; start < context_level_array->length();) {
306 intptr_t start_deopt_id = (*context_level_array)[start]; 293 intptr_t start_deopt_id = (*context_level_array)[start];
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 return Object::empty_var_descriptors().raw(); 351 return Object::empty_var_descriptors().raw();
365 } 352 }
366 const LocalVarDescriptors& var_desc = 353 const LocalVarDescriptors& var_desc =
367 LocalVarDescriptors::Handle(LocalVarDescriptors::New(vars.length())); 354 LocalVarDescriptors::Handle(LocalVarDescriptors::New(vars.length()));
368 for (int i = 0; i < vars.length(); i++) { 355 for (int i = 0; i < vars.length(); i++) {
369 var_desc.SetVar(i, *(vars[i].name), &vars[i].info); 356 var_desc.SetVar(i, *(vars[i].name), &vars[i].info);
370 } 357 }
371 return var_desc.raw(); 358 return var_desc.raw();
372 } 359 }
373 360
374
375 // Add visible variables that are declared in this scope to vars, then 361 // Add visible variables that are declared in this scope to vars, then
376 // collect visible variables of children, followed by siblings. 362 // collect visible variables of children, followed by siblings.
377 void LocalScope::CollectLocalVariables(GrowableArray<VarDesc>* vars, 363 void LocalScope::CollectLocalVariables(GrowableArray<VarDesc>* vars,
378 int16_t* scope_id) { 364 int16_t* scope_id) {
379 (*scope_id)++; 365 (*scope_id)++;
380 for (int i = 0; i < this->variables_.length(); i++) { 366 for (int i = 0; i < this->variables_.length(); i++) {
381 LocalVariable* var = variables_[i]; 367 LocalVariable* var = variables_[i];
382 if ((var->owner() == this) && !var->is_invisible()) { 368 if ((var->owner() == this) && !var->is_invisible()) {
383 if (var->name().raw() == Symbols::CurrentContextVar().raw()) { 369 if (var->name().raw() == Symbols::CurrentContextVar().raw()) {
384 // This is the local variable in which the function saves its 370 // This is the local variable in which the function saves its
(...skipping 28 matching lines...) Expand all
413 } 399 }
414 } 400 }
415 } 401 }
416 LocalScope* child = this->child(); 402 LocalScope* child = this->child();
417 while (child != NULL) { 403 while (child != NULL) {
418 child->CollectLocalVariables(vars, scope_id); 404 child->CollectLocalVariables(vars, scope_id);
419 child = child->sibling(); 405 child = child->sibling();
420 } 406 }
421 } 407 }
422 408
423
424 SourceLabel* LocalScope::LocalLookupLabel(const String& name) const { 409 SourceLabel* LocalScope::LocalLookupLabel(const String& name) const {
425 ASSERT(name.IsSymbol()); 410 ASSERT(name.IsSymbol());
426 for (intptr_t i = 0; i < labels_.length(); i++) { 411 for (intptr_t i = 0; i < labels_.length(); i++) {
427 SourceLabel* label = labels_[i]; 412 SourceLabel* label = labels_[i];
428 if (label->name().raw() == name.raw()) { 413 if (label->name().raw() == name.raw()) {
429 return label; 414 return label;
430 } 415 }
431 } 416 }
432 return NULL; 417 return NULL;
433 } 418 }
434 419
435
436 LocalVariable* LocalScope::LocalLookupVariable(const String& name) const { 420 LocalVariable* LocalScope::LocalLookupVariable(const String& name) const {
437 ASSERT(name.IsSymbol()); 421 ASSERT(name.IsSymbol());
438 for (intptr_t i = 0; i < variables_.length(); i++) { 422 for (intptr_t i = 0; i < variables_.length(); i++) {
439 LocalVariable* var = variables_[i]; 423 LocalVariable* var = variables_[i];
440 ASSERT(var->name().IsSymbol()); 424 ASSERT(var->name().IsSymbol());
441 if (var->name().raw() == name.raw()) { 425 if (var->name().raw() == name.raw()) {
442 return var; 426 return var;
443 } 427 }
444 } 428 }
445 return NULL; 429 return NULL;
446 } 430 }
447 431
448
449 LocalVariable* LocalScope::LookupVariable(const String& name, bool test_only) { 432 LocalVariable* LocalScope::LookupVariable(const String& name, bool test_only) {
450 LocalScope* current_scope = this; 433 LocalScope* current_scope = this;
451 while (current_scope != NULL) { 434 while (current_scope != NULL) {
452 LocalVariable* var = current_scope->LocalLookupVariable(name); 435 LocalVariable* var = current_scope->LocalLookupVariable(name);
453 // If testing only, return the variable even if invisible. 436 // If testing only, return the variable even if invisible.
454 if ((var != NULL) && (!var->is_invisible_ || test_only)) { 437 if ((var != NULL) && (!var->is_invisible_ || test_only)) {
455 if (!test_only && (var->owner()->function_level() != function_level())) { 438 if (!test_only && (var->owner()->function_level() != function_level())) {
456 CaptureVariable(var); 439 CaptureVariable(var);
457 } 440 }
458 return var; 441 return var;
459 } 442 }
460 current_scope = current_scope->parent(); 443 current_scope = current_scope->parent();
461 } 444 }
462 return NULL; 445 return NULL;
463 } 446 }
464 447
465
466 void LocalScope::CaptureVariable(LocalVariable* variable) { 448 void LocalScope::CaptureVariable(LocalVariable* variable) {
467 ASSERT(variable != NULL); 449 ASSERT(variable != NULL);
468 // The variable must exist in an enclosing scope, not necessarily in this one. 450 // The variable must exist in an enclosing scope, not necessarily in this one.
469 variable->set_is_captured(); 451 variable->set_is_captured();
470 const int variable_function_level = variable->owner()->function_level(); 452 const int variable_function_level = variable->owner()->function_level();
471 LocalScope* scope = this; 453 LocalScope* scope = this;
472 while (scope->function_level() != variable_function_level) { 454 while (scope->function_level() != variable_function_level) {
473 // Insert an alias of the variable in the top scope of each function 455 // Insert an alias of the variable in the top scope of each function
474 // level so that the variable is found in the context. 456 // level so that the variable is found in the context.
475 LocalScope* parent_scope = scope->parent(); 457 LocalScope* parent_scope = scope->parent();
476 while ((parent_scope != NULL) && 458 while ((parent_scope != NULL) &&
477 (parent_scope->function_level() == scope->function_level())) { 459 (parent_scope->function_level() == scope->function_level())) {
478 scope = parent_scope; 460 scope = parent_scope;
479 parent_scope = scope->parent(); 461 parent_scope = scope->parent();
480 } 462 }
481 // An alias may already have been added in this scope, and in that case, 463 // An alias may already have been added in this scope, and in that case,
482 // in parent scopes as needed. If so, we are done. 464 // in parent scopes as needed. If so, we are done.
483 if (!scope->AddVariable(variable)) { 465 if (!scope->AddVariable(variable)) {
484 return; 466 return;
485 } 467 }
486 ASSERT(variable->owner() != scope); // Item is an alias. 468 ASSERT(variable->owner() != scope); // Item is an alias.
487 scope = parent_scope; 469 scope = parent_scope;
488 } 470 }
489 } 471 }
490 472
491
492 SourceLabel* LocalScope::LookupLabel(const String& name) { 473 SourceLabel* LocalScope::LookupLabel(const String& name) {
493 LocalScope* current_scope = this; 474 LocalScope* current_scope = this;
494 while (current_scope != NULL) { 475 while (current_scope != NULL) {
495 SourceLabel* label = current_scope->LocalLookupLabel(name); 476 SourceLabel* label = current_scope->LocalLookupLabel(name);
496 if (label != NULL) { 477 if (label != NULL) {
497 return label; 478 return label;
498 } 479 }
499 current_scope = current_scope->parent(); 480 current_scope = current_scope->parent();
500 } 481 }
501 return NULL; 482 return NULL;
502 } 483 }
503 484
504
505 SourceLabel* LocalScope::LookupInnermostLabel(Token::Kind jump_kind) { 485 SourceLabel* LocalScope::LookupInnermostLabel(Token::Kind jump_kind) {
506 ASSERT((jump_kind == Token::kCONTINUE) || (jump_kind == Token::kBREAK)); 486 ASSERT((jump_kind == Token::kCONTINUE) || (jump_kind == Token::kBREAK));
507 LocalScope* current_scope = this; 487 LocalScope* current_scope = this;
508 while (current_scope != NULL) { 488 while (current_scope != NULL) {
509 for (intptr_t i = 0; i < current_scope->labels_.length(); i++) { 489 for (intptr_t i = 0; i < current_scope->labels_.length(); i++) {
510 SourceLabel* label = current_scope->labels_[i]; 490 SourceLabel* label = current_scope->labels_[i];
511 if ((label->kind() == SourceLabel::kWhile) || 491 if ((label->kind() == SourceLabel::kWhile) ||
512 (label->kind() == SourceLabel::kFor) || 492 (label->kind() == SourceLabel::kFor) ||
513 (label->kind() == SourceLabel::kDoWhile) || 493 (label->kind() == SourceLabel::kDoWhile) ||
514 ((jump_kind == Token::kBREAK) && 494 ((jump_kind == Token::kBREAK) &&
515 (label->kind() == SourceLabel::kSwitch))) { 495 (label->kind() == SourceLabel::kSwitch))) {
516 return label; 496 return label;
517 } 497 }
518 } 498 }
519 current_scope = current_scope->parent(); 499 current_scope = current_scope->parent();
520 } 500 }
521 return NULL; 501 return NULL;
522 } 502 }
523 503
524
525 LocalScope* LocalScope::LookupSwitchScope() { 504 LocalScope* LocalScope::LookupSwitchScope() {
526 LocalScope* current_scope = this->parent(); 505 LocalScope* current_scope = this->parent();
527 int this_level = this->function_level(); 506 int this_level = this->function_level();
528 while (current_scope != NULL && 507 while (current_scope != NULL &&
529 current_scope->function_level() == this_level) { 508 current_scope->function_level() == this_level) {
530 for (int i = 0; i < current_scope->labels_.length(); i++) { 509 for (int i = 0; i < current_scope->labels_.length(); i++) {
531 SourceLabel* label = current_scope->labels_[i]; 510 SourceLabel* label = current_scope->labels_[i];
532 if (label->kind() == SourceLabel::kSwitch) { 511 if (label->kind() == SourceLabel::kSwitch) {
533 // This scope contains a label that is bound to a switch statement, 512 // This scope contains a label that is bound to a switch statement,
534 // so it is the scope of the a statement body. 513 // so it is the scope of the a statement body.
535 return current_scope; 514 return current_scope;
536 } 515 }
537 } 516 }
538 current_scope = current_scope->parent(); 517 current_scope = current_scope->parent();
539 } 518 }
540 // We did not find a switch statement scope at the same function level. 519 // We did not find a switch statement scope at the same function level.
541 return NULL; 520 return NULL;
542 } 521 }
543 522
544
545 SourceLabel* LocalScope::CheckUnresolvedLabels() { 523 SourceLabel* LocalScope::CheckUnresolvedLabels() {
546 for (int i = 0; i < this->labels_.length(); i++) { 524 for (int i = 0; i < this->labels_.length(); i++) {
547 SourceLabel* label = this->labels_[i]; 525 SourceLabel* label = this->labels_[i];
548 if (label->kind() == SourceLabel::kForward) { 526 if (label->kind() == SourceLabel::kForward) {
549 LocalScope* outer_switch = LookupSwitchScope(); 527 LocalScope* outer_switch = LookupSwitchScope();
550 if (outer_switch == NULL) { 528 if (outer_switch == NULL) {
551 return label; 529 return label;
552 } else { 530 } else {
553 outer_switch->MoveLabel(label); 531 outer_switch->MoveLabel(label);
554 } 532 }
555 } 533 }
556 } 534 }
557 return NULL; 535 return NULL;
558 } 536 }
559 537
560
561 int LocalScope::NumCapturedVariables() const { 538 int LocalScope::NumCapturedVariables() const {
562 // It is not necessary to traverse parent scopes, since we are only interested 539 // It is not necessary to traverse parent scopes, since we are only interested
563 // in the captured variables referenced in this scope. If this scope is the 540 // in the captured variables referenced in this scope. If this scope is the
564 // top scope at function level 1 and it (or its children scopes) references a 541 // top scope at function level 1 and it (or its children scopes) references a
565 // captured variable declared in a parent scope at function level 0, it will 542 // captured variable declared in a parent scope at function level 0, it will
566 // contain an alias for that variable. 543 // contain an alias for that variable.
567 544
568 // Since code generation for nested functions is postponed until first 545 // Since code generation for nested functions is postponed until first
569 // invocation, the function level of the closure scope can only be 1. 546 // invocation, the function level of the closure scope can only be 1.
570 ASSERT(function_level() == 1); 547 ASSERT(function_level() == 1);
571 548
572 int num_captured = 0; 549 int num_captured = 0;
573 for (int i = 0; i < num_variables(); i++) { 550 for (int i = 0; i < num_variables(); i++) {
574 LocalVariable* variable = VariableAt(i); 551 LocalVariable* variable = VariableAt(i);
575 // Count the aliases of captured variables belonging to outer scopes. 552 // Count the aliases of captured variables belonging to outer scopes.
576 if (variable->owner()->function_level() != 1) { 553 if (variable->owner()->function_level() != 1) {
577 ASSERT(variable->is_captured()); 554 ASSERT(variable->is_captured());
578 ASSERT(variable->owner()->function_level() == 0); 555 ASSERT(variable->owner()->function_level() == 0);
579 num_captured++; 556 num_captured++;
580 } 557 }
581 } 558 }
582 return num_captured; 559 return num_captured;
583 } 560 }
584 561
585
586 RawContextScope* LocalScope::PreserveOuterScope( 562 RawContextScope* LocalScope::PreserveOuterScope(
587 int current_context_level) const { 563 int current_context_level) const {
588 // Since code generation for nested functions is postponed until first 564 // Since code generation for nested functions is postponed until first
589 // invocation, the function level of the closure scope can only be 1. 565 // invocation, the function level of the closure scope can only be 1.
590 ASSERT(function_level() == 1); 566 ASSERT(function_level() == 1);
591 567
592 // Count the number of referenced captured variables. 568 // Count the number of referenced captured variables.
593 intptr_t num_captured_vars = NumCapturedVariables(); 569 intptr_t num_captured_vars = NumCapturedVariables();
594 570
595 // Create a ContextScope with space for num_captured_vars descriptors. 571 // Create a ContextScope with space for num_captured_vars descriptors.
(...skipping 25 matching lines...) Expand all
621 int adjusted_context_level = 597 int adjusted_context_level =
622 variable->owner()->context_level() - current_context_level; 598 variable->owner()->context_level() - current_context_level;
623 context_scope.SetContextLevelAt(captured_idx, adjusted_context_level); 599 context_scope.SetContextLevelAt(captured_idx, adjusted_context_level);
624 captured_idx++; 600 captured_idx++;
625 } 601 }
626 } 602 }
627 ASSERT(context_scope.num_variables() == captured_idx); // Verify count. 603 ASSERT(context_scope.num_variables() == captured_idx); // Verify count.
628 return context_scope.raw(); 604 return context_scope.raw();
629 } 605 }
630 606
631
632 LocalScope* LocalScope::RestoreOuterScope(const ContextScope& context_scope) { 607 LocalScope* LocalScope::RestoreOuterScope(const ContextScope& context_scope) {
633 // The function level of the outer scope is one less than the function level 608 // The function level of the outer scope is one less than the function level
634 // of the current function, which is 0. 609 // of the current function, which is 0.
635 LocalScope* outer_scope = new LocalScope(NULL, -1, 0); 610 LocalScope* outer_scope = new LocalScope(NULL, -1, 0);
636 // Add all variables as aliases to the outer scope. 611 // Add all variables as aliases to the outer scope.
637 for (int i = 0; i < context_scope.num_variables(); i++) { 612 for (int i = 0; i < context_scope.num_variables(); i++) {
638 LocalVariable* variable; 613 LocalVariable* variable;
639 if (context_scope.IsConstAt(i)) { 614 if (context_scope.IsConstAt(i)) {
640 variable = new LocalVariable(context_scope.DeclarationTokenIndexAt(i), 615 variable = new LocalVariable(context_scope.DeclarationTokenIndexAt(i),
641 context_scope.TokenIndexAt(i), 616 context_scope.TokenIndexAt(i),
(...skipping 18 matching lines...) Expand all
660 // context level has already been assigned. 635 // context level has already been assigned.
661 LocalScope* owner_scope = new LocalScope(NULL, 0, 0); 636 LocalScope* owner_scope = new LocalScope(NULL, 0, 0);
662 owner_scope->set_context_level(context_scope.ContextLevelAt(i)); 637 owner_scope->set_context_level(context_scope.ContextLevelAt(i));
663 owner_scope->AddVariable(variable); 638 owner_scope->AddVariable(variable);
664 outer_scope->AddVariable(variable); // As alias. 639 outer_scope->AddVariable(variable); // As alias.
665 ASSERT(variable->owner() == owner_scope); 640 ASSERT(variable->owner() == owner_scope);
666 } 641 }
667 return outer_scope; 642 return outer_scope;
668 } 643 }
669 644
670
671 void LocalScope::CaptureLocalVariables(LocalScope* top_scope) { 645 void LocalScope::CaptureLocalVariables(LocalScope* top_scope) {
672 ASSERT(top_scope->function_level() == function_level()); 646 ASSERT(top_scope->function_level() == function_level());
673 LocalScope* scope = this; 647 LocalScope* scope = this;
674 while (scope != top_scope->parent()) { 648 while (scope != top_scope->parent()) {
675 for (intptr_t i = 0; i < scope->num_variables(); i++) { 649 for (intptr_t i = 0; i < scope->num_variables(); i++) {
676 LocalVariable* variable = scope->VariableAt(i); 650 LocalVariable* variable = scope->VariableAt(i);
677 if (variable->is_forced_stack() || 651 if (variable->is_forced_stack() ||
678 (variable->name().raw() == Symbols::StackTraceVar().raw()) || 652 (variable->name().raw() == Symbols::StackTraceVar().raw()) ||
679 (variable->name().raw() == Symbols::ExceptionVar().raw()) || 653 (variable->name().raw() == Symbols::ExceptionVar().raw()) ||
680 (variable->name().raw() == Symbols::SavedTryContextVar().raw())) { 654 (variable->name().raw() == Symbols::SavedTryContextVar().raw())) {
681 // Don't capture those variables because the VM expects them to be on 655 // Don't capture those variables because the VM expects them to be on
682 // the stack. 656 // the stack.
683 continue; 657 continue;
684 } 658 }
685 scope->CaptureVariable(variable); 659 scope->CaptureVariable(variable);
686 } 660 }
687 scope = scope->parent(); 661 scope = scope->parent();
688 } 662 }
689 } 663 }
690 664
691
692 RawContextScope* LocalScope::CreateImplicitClosureScope(const Function& func) { 665 RawContextScope* LocalScope::CreateImplicitClosureScope(const Function& func) {
693 static const intptr_t kNumCapturedVars = 1; 666 static const intptr_t kNumCapturedVars = 1;
694 667
695 // Create a ContextScope with space for kNumCapturedVars descriptors. 668 // Create a ContextScope with space for kNumCapturedVars descriptors.
696 const ContextScope& context_scope = 669 const ContextScope& context_scope =
697 ContextScope::Handle(ContextScope::New(kNumCapturedVars, true)); 670 ContextScope::Handle(ContextScope::New(kNumCapturedVars, true));
698 671
699 // Create a descriptor for 'this' variable. 672 // Create a descriptor for 'this' variable.
700 context_scope.SetTokenIndexAt(0, func.token_pos()); 673 context_scope.SetTokenIndexAt(0, func.token_pos());
701 context_scope.SetDeclarationTokenIndexAt(0, func.token_pos()); 674 context_scope.SetDeclarationTokenIndexAt(0, func.token_pos());
702 context_scope.SetNameAt(0, Symbols::This()); 675 context_scope.SetNameAt(0, Symbols::This());
703 context_scope.SetIsFinalAt(0, true); 676 context_scope.SetIsFinalAt(0, true);
704 context_scope.SetIsConstAt(0, false); 677 context_scope.SetIsConstAt(0, false);
705 const AbstractType& type = AbstractType::Handle(func.ParameterTypeAt(0)); 678 const AbstractType& type = AbstractType::Handle(func.ParameterTypeAt(0));
706 context_scope.SetTypeAt(0, type); 679 context_scope.SetTypeAt(0, type);
707 context_scope.SetContextIndexAt(0, 0); 680 context_scope.SetContextIndexAt(0, 0);
708 context_scope.SetContextLevelAt(0, 0); 681 context_scope.SetContextLevelAt(0, 0);
709 ASSERT(context_scope.num_variables() == kNumCapturedVars); // Verify count. 682 ASSERT(context_scope.num_variables() == kNumCapturedVars); // Verify count.
710 return context_scope.raw(); 683 return context_scope.raw();
711 } 684 }
712 685
713
714 bool LocalVariable::Equals(const LocalVariable& other) const { 686 bool LocalVariable::Equals(const LocalVariable& other) const {
715 if (HasIndex() && other.HasIndex() && (index() == other.index())) { 687 if (HasIndex() && other.HasIndex() && (index() == other.index())) {
716 if (is_captured() == other.is_captured()) { 688 if (is_captured() == other.is_captured()) {
717 if (!is_captured()) { 689 if (!is_captured()) {
718 return true; 690 return true;
719 } 691 }
720 if (owner()->context_level() == other.owner()->context_level()) { 692 if (owner()->context_level() == other.owner()->context_level()) {
721 return true; 693 return true;
722 } 694 }
723 } 695 }
724 } 696 }
725 return false; 697 return false;
726 } 698 }
727 699
728
729 int LocalVariable::BitIndexIn(intptr_t fixed_parameter_count) const { 700 int LocalVariable::BitIndexIn(intptr_t fixed_parameter_count) const {
730 ASSERT(!is_captured()); 701 ASSERT(!is_captured());
731 // Parameters have positive indexes with the lowest index being 702 // Parameters have positive indexes with the lowest index being
732 // kParamEndSlotFromFp + 1. Locals and copied parameters have negative 703 // kParamEndSlotFromFp + 1. Locals and copied parameters have negative
733 // indexes with the lowest (closest to 0) index being kFirstLocalSlotFromFp. 704 // indexes with the lowest (closest to 0) index being kFirstLocalSlotFromFp.
734 if (index() > 0) { 705 if (index() > 0) {
735 // Shift non-negative indexes so that the lowest one is 0. 706 // Shift non-negative indexes so that the lowest one is 0.
736 return fixed_parameter_count - (index() - kParamEndSlotFromFp); 707 return fixed_parameter_count - (index() - kParamEndSlotFromFp);
737 } else { 708 } else {
738 // Shift negative indexes so that the lowest one is 0 (they are still 709 // Shift negative indexes so that the lowest one is 0 (they are still
739 // non-positive). 710 // non-positive).
740 return fixed_parameter_count - (index() - kFirstLocalSlotFromFp); 711 return fixed_parameter_count - (index() - kFirstLocalSlotFromFp);
741 } 712 }
742 } 713 }
743 714
744
745 } // namespace dart 715 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/scopes.h ('k') | runtime/vm/scopes_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698