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

Side by Side Diff: src/scopes.cc

Issue 9221011: Collect AstNode type information (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: review feedback (embedded AstProperties and AstConstructionVisitor) 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution. 11 // with the distribution.
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 Scope* scope = info->function()->scope(); 267 Scope* scope = info->function()->scope();
268 Scope* top = scope; 268 Scope* top = scope;
269 269
270 // Traverse the scope tree up to the first unresolved scope or the global 270 // Traverse the scope tree up to the first unresolved scope or the global
271 // scope and start scope resolution and variable allocation from that scope. 271 // scope and start scope resolution and variable allocation from that scope.
272 while (!top->is_global_scope() && 272 while (!top->is_global_scope() &&
273 !top->outer_scope()->already_resolved()) { 273 !top->outer_scope()->already_resolved()) {
274 top = top->outer_scope(); 274 top = top->outer_scope();
275 } 275 }
276 276
277 // Allocated the variables. 277 // Allocate the variables.
278 top->AllocateVariables(info->global_scope()); 278 {
279 AstNodeFactory<AstNullVisitor> ast_node_factory(info->isolate());
280 top->AllocateVariables(info->global_scope(), &ast_node_factory);
281 }
279 282
280 #ifdef DEBUG 283 #ifdef DEBUG
281 if (info->isolate()->bootstrapper()->IsActive() 284 if (info->isolate()->bootstrapper()->IsActive()
282 ? FLAG_print_builtin_scopes 285 ? FLAG_print_builtin_scopes
283 : FLAG_print_scopes) { 286 : FLAG_print_scopes) {
284 scope->Print(); 287 scope->Print();
285 } 288 }
286 #endif 289 #endif
287 290
288 if (FLAG_harmony_scoping) { 291 if (FLAG_harmony_scoping) {
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 name, 413 name,
411 mode, 414 mode,
412 true, 415 true,
413 Variable::NORMAL, 416 Variable::NORMAL,
414 init_flag); 417 init_flag);
415 var->AllocateTo(Variable::CONTEXT, index); 418 var->AllocateTo(Variable::CONTEXT, index);
416 return var; 419 return var;
417 } 420 }
418 421
419 422
420 Variable* Scope::LookupFunctionVar(Handle<String> name) { 423 Variable* Scope::LookupFunctionVar(Handle<String> name,
424 AstNodeFactory<AstNullVisitor>* factory) {
421 if (function_ != NULL && function_->name().is_identical_to(name)) { 425 if (function_ != NULL && function_->name().is_identical_to(name)) {
422 return function_->var(); 426 return function_->var();
423 } else if (!scope_info_.is_null()) { 427 } else if (!scope_info_.is_null()) {
424 // If we are backed by a scope info, try to lookup the variable there. 428 // If we are backed by a scope info, try to lookup the variable there.
425 VariableMode mode; 429 VariableMode mode;
426 int index = scope_info_->FunctionContextSlotIndex(*name, &mode); 430 int index = scope_info_->FunctionContextSlotIndex(*name, &mode);
427 if (index < 0) return NULL; 431 if (index < 0) return NULL;
428 Variable* var = DeclareFunctionVar(name, mode); 432 Variable* var = DeclareFunctionVar(name, mode, factory);
429 var->AllocateTo(Variable::CONTEXT, index); 433 var->AllocateTo(Variable::CONTEXT, index);
430 return var; 434 return var;
431 } else { 435 } else {
432 return NULL; 436 return NULL;
433 } 437 }
434 } 438 }
435 439
436 440
437 Variable* Scope::Lookup(Handle<String> name) { 441 Variable* Scope::Lookup(Handle<String> name) {
438 for (Scope* scope = this; 442 for (Scope* scope = this;
439 scope != NULL; 443 scope != NULL;
440 scope = scope->outer_scope()) { 444 scope = scope->outer_scope()) {
441 Variable* var = scope->LocalLookup(name); 445 Variable* var = scope->LocalLookup(name);
442 if (var != NULL) return var; 446 if (var != NULL) return var;
443 } 447 }
444 return NULL; 448 return NULL;
445 } 449 }
446 450
447 451
448 Variable* Scope::DeclareFunctionVar(Handle<String> name, VariableMode mode) {
449 ASSERT(is_function_scope() && function_ == NULL);
450 Variable* function_var = new Variable(
451 this, name, mode, true, Variable::NORMAL, kCreatedInitialized);
452 function_ = new(isolate_->zone()) VariableProxy(isolate_, function_var);
453 return function_var;
454 }
455
456
457 void Scope::DeclareParameter(Handle<String> name, VariableMode mode) { 452 void Scope::DeclareParameter(Handle<String> name, VariableMode mode) {
458 ASSERT(!already_resolved()); 453 ASSERT(!already_resolved());
459 ASSERT(is_function_scope()); 454 ASSERT(is_function_scope());
460 Variable* var = variables_.Declare( 455 Variable* var = variables_.Declare(
461 this, name, mode, true, Variable::NORMAL, kCreatedInitialized); 456 this, name, mode, true, Variable::NORMAL, kCreatedInitialized);
462 params_.Add(var); 457 params_.Add(var);
463 } 458 }
464 459
465 460
466 Variable* Scope::DeclareLocal(Handle<String> name, 461 Variable* Scope::DeclareLocal(Handle<String> name,
(...skipping 17 matching lines...) Expand all
484 ASSERT(is_global_scope()); 479 ASSERT(is_global_scope());
485 return variables_.Declare(this, 480 return variables_.Declare(this,
486 name, 481 name,
487 DYNAMIC_GLOBAL, 482 DYNAMIC_GLOBAL,
488 true, 483 true,
489 Variable::NORMAL, 484 Variable::NORMAL,
490 kCreatedInitialized); 485 kCreatedInitialized);
491 } 486 }
492 487
493 488
494 VariableProxy* Scope::NewUnresolved(Handle<String> name, int position) {
495 // Note that we must not share the unresolved variables with
496 // the same name because they may be removed selectively via
497 // RemoveUnresolved().
498 ASSERT(!already_resolved());
499 VariableProxy* proxy = new(isolate_->zone()) VariableProxy(
500 isolate_, name, false, position);
501 unresolved_.Add(proxy);
502 return proxy;
503 }
504
505
506 void Scope::RemoveUnresolved(VariableProxy* var) { 489 void Scope::RemoveUnresolved(VariableProxy* var) {
507 // Most likely (always?) any variable we want to remove 490 // Most likely (always?) any variable we want to remove
508 // was just added before, so we search backwards. 491 // was just added before, so we search backwards.
509 for (int i = unresolved_.length(); i-- > 0;) { 492 for (int i = unresolved_.length(); i-- > 0;) {
510 if (unresolved_[i] == var) { 493 if (unresolved_[i] == var) {
511 unresolved_.Remove(i); 494 unresolved_.Remove(i);
512 return; 495 return;
513 } 496 }
514 } 497 }
515 } 498 }
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 if (var->IsStackLocal()) { 601 if (var->IsStackLocal()) {
619 stack_locals->Add(var); 602 stack_locals->Add(var);
620 } else if (var->IsContextSlot()) { 603 } else if (var->IsContextSlot()) {
621 context_locals->Add(var); 604 context_locals->Add(var);
622 } 605 }
623 } 606 }
624 } 607 }
625 } 608 }
626 609
627 610
628 void Scope::AllocateVariables(Scope* global_scope) { 611 void Scope::AllocateVariables(Scope* global_scope,
612 AstNodeFactory<AstNullVisitor>* factory) {
629 // 1) Propagate scope information. 613 // 1) Propagate scope information.
630 bool outer_scope_calls_non_strict_eval = false; 614 bool outer_scope_calls_non_strict_eval = false;
631 if (outer_scope_ != NULL) { 615 if (outer_scope_ != NULL) {
632 outer_scope_calls_non_strict_eval = 616 outer_scope_calls_non_strict_eval =
633 outer_scope_->outer_scope_calls_non_strict_eval() | 617 outer_scope_->outer_scope_calls_non_strict_eval() |
634 outer_scope_->calls_non_strict_eval(); 618 outer_scope_->calls_non_strict_eval();
635 } 619 }
636 PropagateScopeInfo(outer_scope_calls_non_strict_eval); 620 PropagateScopeInfo(outer_scope_calls_non_strict_eval);
637 621
638 // 2) Resolve variables. 622 // 2) Resolve variables.
639 ResolveVariablesRecursively(global_scope); 623 ResolveVariablesRecursively(global_scope, factory);
640 624
641 // 3) Allocate variables. 625 // 3) Allocate variables.
642 AllocateVariablesRecursively(); 626 AllocateVariablesRecursively();
643 } 627 }
644 628
645 629
646 bool Scope::AllowsLazyCompilation() const { 630 bool Scope::AllowsLazyCompilation() const {
647 return !force_eager_compilation_ && HasTrivialOuterContext(); 631 return !force_eager_compilation_ && HasTrivialOuterContext();
648 } 632 }
649 633
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
892 Variable::NORMAL, 876 Variable::NORMAL,
893 init_flag); 877 init_flag);
894 // Allocate it by giving it a dynamic lookup. 878 // Allocate it by giving it a dynamic lookup.
895 var->AllocateTo(Variable::LOOKUP, -1); 879 var->AllocateTo(Variable::LOOKUP, -1);
896 } 880 }
897 return var; 881 return var;
898 } 882 }
899 883
900 884
901 Variable* Scope::LookupRecursive(Handle<String> name, 885 Variable* Scope::LookupRecursive(Handle<String> name,
902 BindingKind* binding_kind) { 886 BindingKind* binding_kind,
887 AstNodeFactory<AstNullVisitor>* factory) {
903 ASSERT(binding_kind != NULL); 888 ASSERT(binding_kind != NULL);
904 // Try to find the variable in this scope. 889 // Try to find the variable in this scope.
905 Variable* var = LocalLookup(name); 890 Variable* var = LocalLookup(name);
906 891
907 // We found a variable and we are done. (Even if there is an 'eval' in 892 // We found a variable and we are done. (Even if there is an 'eval' in
908 // this scope which introduces the same variable again, the resulting 893 // this scope which introduces the same variable again, the resulting
909 // variable remains the same.) 894 // variable remains the same.)
910 if (var != NULL) { 895 if (var != NULL) {
911 *binding_kind = BOUND; 896 *binding_kind = BOUND;
912 return var; 897 return var;
913 } 898 }
914 899
915 // We did not find a variable locally. Check against the function variable, 900 // We did not find a variable locally. Check against the function variable,
916 // if any. We can do this for all scopes, since the function variable is 901 // if any. We can do this for all scopes, since the function variable is
917 // only present - if at all - for function scopes. 902 // only present - if at all - for function scopes.
918 *binding_kind = UNBOUND; 903 *binding_kind = UNBOUND;
919 var = LookupFunctionVar(name); 904 var = LookupFunctionVar(name, factory);
920 if (var != NULL) { 905 if (var != NULL) {
921 *binding_kind = BOUND; 906 *binding_kind = BOUND;
922 } else if (outer_scope_ != NULL) { 907 } else if (outer_scope_ != NULL) {
923 var = outer_scope_->LookupRecursive(name, binding_kind); 908 var = outer_scope_->LookupRecursive(name, binding_kind, factory);
924 if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) { 909 if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) {
925 var->ForceContextAllocation(); 910 var->ForceContextAllocation();
926 } 911 }
927 } else { 912 } else {
928 ASSERT(is_global_scope()); 913 ASSERT(is_global_scope());
929 } 914 }
930 915
931 if (is_with_scope()) { 916 if (is_with_scope()) {
932 // The current scope is a with scope, so the variable binding can not be 917 // The current scope is a with scope, so the variable binding can not be
933 // statically resolved. However, note that it was necessary to do a lookup 918 // statically resolved. However, note that it was necessary to do a lookup
(...skipping 12 matching lines...) Expand all
946 *binding_kind = BOUND_EVAL_SHADOWED; 931 *binding_kind = BOUND_EVAL_SHADOWED;
947 } else if (*binding_kind == UNBOUND) { 932 } else if (*binding_kind == UNBOUND) {
948 *binding_kind = UNBOUND_EVAL_SHADOWED; 933 *binding_kind = UNBOUND_EVAL_SHADOWED;
949 } 934 }
950 } 935 }
951 return var; 936 return var;
952 } 937 }
953 938
954 939
955 void Scope::ResolveVariable(Scope* global_scope, 940 void Scope::ResolveVariable(Scope* global_scope,
956 VariableProxy* proxy) { 941 VariableProxy* proxy,
942 AstNodeFactory<AstNullVisitor>* factory) {
957 ASSERT(global_scope == NULL || global_scope->is_global_scope()); 943 ASSERT(global_scope == NULL || global_scope->is_global_scope());
958 944
959 // If the proxy is already resolved there's nothing to do 945 // If the proxy is already resolved there's nothing to do
960 // (functions and consts may be resolved by the parser). 946 // (functions and consts may be resolved by the parser).
961 if (proxy->var() != NULL) return; 947 if (proxy->var() != NULL) return;
962 948
963 // Otherwise, try to resolve the variable. 949 // Otherwise, try to resolve the variable.
964 BindingKind binding_kind; 950 BindingKind binding_kind;
965 Variable* var = LookupRecursive(proxy->name(), &binding_kind); 951 Variable* var = LookupRecursive(proxy->name(), &binding_kind, factory);
966 switch (binding_kind) { 952 switch (binding_kind) {
967 case BOUND: 953 case BOUND:
968 // We found a variable binding. 954 // We found a variable binding.
969 break; 955 break;
970 956
971 case BOUND_EVAL_SHADOWED: 957 case BOUND_EVAL_SHADOWED:
972 // We found a variable variable binding that might be shadowed 958 // We found a variable variable binding that might be shadowed
973 // by 'eval' introduced variable bindings. 959 // by 'eval' introduced variable bindings.
974 if (var->is_global()) { 960 if (var->is_global()) {
975 var = NonLocal(proxy->name(), DYNAMIC_GLOBAL); 961 var = NonLocal(proxy->name(), DYNAMIC_GLOBAL);
(...skipping 20 matching lines...) Expand all
996 // The variable could not be resolved statically. 982 // The variable could not be resolved statically.
997 var = NonLocal(proxy->name(), DYNAMIC); 983 var = NonLocal(proxy->name(), DYNAMIC);
998 break; 984 break;
999 } 985 }
1000 986
1001 ASSERT(var != NULL); 987 ASSERT(var != NULL);
1002 proxy->BindTo(var); 988 proxy->BindTo(var);
1003 } 989 }
1004 990
1005 991
1006 void Scope::ResolveVariablesRecursively(Scope* global_scope) { 992 void Scope::ResolveVariablesRecursively(
993 Scope* global_scope,
994 AstNodeFactory<AstNullVisitor>* factory) {
1007 ASSERT(global_scope == NULL || global_scope->is_global_scope()); 995 ASSERT(global_scope == NULL || global_scope->is_global_scope());
1008 996
1009 // Resolve unresolved variables for this scope. 997 // Resolve unresolved variables for this scope.
1010 for (int i = 0; i < unresolved_.length(); i++) { 998 for (int i = 0; i < unresolved_.length(); i++) {
1011 ResolveVariable(global_scope, unresolved_[i]); 999 ResolveVariable(global_scope, unresolved_[i], factory);
1012 } 1000 }
1013 1001
1014 // Resolve unresolved variables for inner scopes. 1002 // Resolve unresolved variables for inner scopes.
1015 for (int i = 0; i < inner_scopes_.length(); i++) { 1003 for (int i = 0; i < inner_scopes_.length(); i++) {
1016 inner_scopes_[i]->ResolveVariablesRecursively(global_scope); 1004 inner_scopes_[i]->ResolveVariablesRecursively(global_scope, factory);
1017 } 1005 }
1018 } 1006 }
1019 1007
1020 1008
1021 bool Scope::PropagateScopeInfo(bool outer_scope_calls_non_strict_eval ) { 1009 bool Scope::PropagateScopeInfo(bool outer_scope_calls_non_strict_eval ) {
1022 if (outer_scope_calls_non_strict_eval) { 1010 if (outer_scope_calls_non_strict_eval) {
1023 outer_scope_calls_non_strict_eval_ = true; 1011 outer_scope_calls_non_strict_eval_ = true;
1024 } 1012 }
1025 1013
1026 bool calls_non_strict_eval = 1014 bool calls_non_strict_eval =
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
1230 } 1218 }
1231 1219
1232 1220
1233 int Scope::ContextLocalCount() const { 1221 int Scope::ContextLocalCount() const {
1234 if (num_heap_slots() == 0) return 0; 1222 if (num_heap_slots() == 0) return 0;
1235 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - 1223 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
1236 (function_ != NULL && function_->var()->IsContextSlot() ? 1 : 0); 1224 (function_ != NULL && function_->var()->IsContextSlot() ? 1 : 0);
1237 } 1225 }
1238 1226
1239 } } // namespace v8::internal 1227 } } // namespace v8::internal
OLDNEW
« src/ast.h ('K') | « src/scopes.h ('k') | test/cctest/test-ast.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698