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

Side by Side Diff: src/scopes.cc

Issue 943543002: [strong] Declaration-after-use errors. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: computed prop names comment fix Created 5 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
« no previous file with comments | « src/scopes.h ('k') | src/variables.h » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/scopes.h" 7 #include "src/scopes.h"
8 8
9 #include "src/accessors.h" 9 #include "src/accessors.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 // Traverse the scope tree up to the first unresolved scope or the global 256 // Traverse the scope tree up to the first unresolved scope or the global
257 // scope and start scope resolution and variable allocation from that scope. 257 // scope and start scope resolution and variable allocation from that scope.
258 while (!top->is_script_scope() && 258 while (!top->is_script_scope() &&
259 !top->outer_scope()->already_resolved()) { 259 !top->outer_scope()->already_resolved()) {
260 top = top->outer_scope(); 260 top = top->outer_scope();
261 } 261 }
262 262
263 // Allocate the variables. 263 // Allocate the variables.
264 { 264 {
265 AstNodeFactory ast_node_factory(info->ast_value_factory()); 265 AstNodeFactory ast_node_factory(info->ast_value_factory());
266 if (!top->AllocateVariables(info, &ast_node_factory)) return false; 266 if (!top->AllocateVariables(info, &ast_node_factory)) {
267 DCHECK(top->pending_error_handler_.has_pending_error());
268 top->pending_error_handler_.ThrowPendingError(info->isolate(),
269 info->script());
270 return false;
271 }
267 } 272 }
268 273
269 #ifdef DEBUG 274 #ifdef DEBUG
270 if (info->isolate()->bootstrapper()->IsActive() 275 if (info->isolate()->bootstrapper()->IsActive()
271 ? FLAG_print_builtin_scopes 276 ? FLAG_print_builtin_scopes
272 : FLAG_print_scopes) { 277 : FLAG_print_scopes) {
273 scope->Print(); 278 scope->Print();
274 } 279 }
275 #endif 280 #endif
276 281
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 DCHECK_NULL(rest_parameter_); 459 DCHECK_NULL(rest_parameter_);
455 rest_parameter_ = var; 460 rest_parameter_ = var;
456 rest_index_ = num_parameters(); 461 rest_index_ = num_parameters();
457 } 462 }
458 params_.Add(var, zone()); 463 params_.Add(var, zone());
459 return var; 464 return var;
460 } 465 }
461 466
462 467
463 Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode, 468 Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode,
464 InitializationFlag init_flag, 469 InitializationFlag init_flag, Variable::Kind kind,
465 MaybeAssignedFlag maybe_assigned_flag) { 470 MaybeAssignedFlag maybe_assigned_flag) {
466 DCHECK(!already_resolved()); 471 DCHECK(!already_resolved());
467 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are 472 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are
468 // introduces during variable allocation, INTERNAL variables are allocated 473 // introduces during variable allocation, INTERNAL variables are allocated
469 // explicitly, and TEMPORARY variables are allocated via NewTemporary(). 474 // explicitly, and TEMPORARY variables are allocated via NewTemporary().
470 DCHECK(IsDeclaredVariableMode(mode)); 475 DCHECK(IsDeclaredVariableMode(mode));
471 ++num_var_or_const_; 476 ++num_var_or_const_;
472 return variables_.Declare(this, name, mode, true, Variable::NORMAL, init_flag, 477 return variables_.Declare(this, name, mode, true, kind, init_flag,
473 maybe_assigned_flag); 478 maybe_assigned_flag);
474 } 479 }
475 480
476 481
477 Variable* Scope::DeclareDynamicGlobal(const AstRawString* name) { 482 Variable* Scope::DeclareDynamicGlobal(const AstRawString* name) {
478 DCHECK(is_script_scope()); 483 DCHECK(is_script_scope());
479 return variables_.Declare(this, 484 return variables_.Declare(this,
480 name, 485 name,
481 DYNAMIC_GLOBAL, 486 DYNAMIC_GLOBAL,
482 true, 487 true,
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
761 int end_pos = scope->end_position(); 766 int end_pos = scope->end_position();
762 DCHECK(beg_pos >= 0 && end_pos >= 0); 767 DCHECK(beg_pos >= 0 && end_pos >= 0);
763 if (beg_pos <= position && position < end_pos) { 768 if (beg_pos <= position && position < end_pos) {
764 scope->GetNestedScopeChain(isolate, chain, position); 769 scope->GetNestedScopeChain(isolate, chain, position);
765 return; 770 return;
766 } 771 }
767 } 772 }
768 } 773 }
769 774
770 775
776 void Scope::ReportMessage(int start_position, int end_position,
777 const char* message, const AstRawString* arg) {
778 // Propagate the error to the topmost scope targeted by this scope analysis
779 // phase.
780 Scope* top = this;
781 while (!top->is_script_scope() && !top->outer_scope()->already_resolved()) {
782 top = top->outer_scope();
783 }
784
785 top->pending_error_handler_.ReportMessageAt(start_position, end_position,
786 message, arg, kReferenceError);
787 }
788
789
771 #ifdef DEBUG 790 #ifdef DEBUG
772 static const char* Header(ScopeType scope_type) { 791 static const char* Header(ScopeType scope_type) {
773 switch (scope_type) { 792 switch (scope_type) {
774 case EVAL_SCOPE: return "eval"; 793 case EVAL_SCOPE: return "eval";
775 case FUNCTION_SCOPE: return "function"; 794 case FUNCTION_SCOPE: return "function";
776 case MODULE_SCOPE: return "module"; 795 case MODULE_SCOPE: return "module";
777 case SCRIPT_SCOPE: return "global"; 796 case SCRIPT_SCOPE: return "global";
778 case CATCH_SCOPE: return "catch"; 797 case CATCH_SCOPE: return "catch";
779 case BLOCK_SCOPE: return "block"; 798 case BLOCK_SCOPE: return "block";
780 case WITH_SCOPE: return "with"; 799 case WITH_SCOPE: return "with";
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
1043 // If the proxy is already resolved there's nothing to do 1062 // If the proxy is already resolved there's nothing to do
1044 // (functions and consts may be resolved by the parser). 1063 // (functions and consts may be resolved by the parser).
1045 if (proxy->is_resolved()) return true; 1064 if (proxy->is_resolved()) return true;
1046 1065
1047 // Otherwise, try to resolve the variable. 1066 // Otherwise, try to resolve the variable.
1048 BindingKind binding_kind; 1067 BindingKind binding_kind;
1049 Variable* var = LookupRecursive(proxy, &binding_kind, factory); 1068 Variable* var = LookupRecursive(proxy, &binding_kind, factory);
1050 switch (binding_kind) { 1069 switch (binding_kind) {
1051 case BOUND: 1070 case BOUND:
1052 // We found a variable binding. 1071 // We found a variable binding.
1072 if (is_strong(language_mode())) {
1073 // Check for declaration-after use (for variables) in strong mode. Note
1074 // that we can only do this in the case where we have seen the
1075 // declaration. And we always allow referencing functions (for now).
1076
1077 // If both the use and the declaration are inside an eval scope
1078 // (possibly indirectly), or one of them is, we need to check whether
1079 // they are inside the same eval scope or different
1080 // ones.
1081
1082 // TODO(marja,rossberg): Detect errors across different evals (depends
1083 // on the future of eval in strong mode).
1084 const Scope* eval_for_use = NearestOuterEvalScope();
1085 const Scope* eval_for_declaration =
1086 var->scope()->NearestOuterEvalScope();
1087
1088 if (proxy->position() != RelocInfo::kNoPosition &&
1089 proxy->position() < var->initializer_position() &&
1090 !var->is_function() && eval_for_use == eval_for_declaration) {
1091 DCHECK(proxy->end_position() != RelocInfo::kNoPosition);
1092 ReportMessage(proxy->position(), proxy->end_position(),
1093 "strong_use_before_declaration", proxy->raw_name());
1094 return false;
1095 }
1096 }
1053 break; 1097 break;
1054 1098
1055 case BOUND_EVAL_SHADOWED: 1099 case BOUND_EVAL_SHADOWED:
1056 // We either found a variable binding that might be shadowed by eval or 1100 // We either found a variable binding that might be shadowed by eval or
1057 // gave up on it (e.g. by encountering a local with the same in the outer 1101 // gave up on it (e.g. by encountering a local with the same in the outer
1058 // scope which was not promoted to a context, this can happen if we use 1102 // scope which was not promoted to a context, this can happen if we use
1059 // debugger to evaluate arbitrary expressions at a break point). 1103 // debugger to evaluate arbitrary expressions at a break point).
1060 if (var->IsGlobalObjectProperty()) { 1104 if (var->IsGlobalObjectProperty()) {
1061 var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL); 1105 var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL);
1062 } else if (var->is_dynamic()) { 1106 } else if (var->is_dynamic()) {
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
1381 } 1425 }
1382 1426
1383 1427
1384 int Scope::ContextLocalCount() const { 1428 int Scope::ContextLocalCount() const {
1385 if (num_heap_slots() == 0) return 0; 1429 if (num_heap_slots() == 0) return 0;
1386 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - 1430 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
1387 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); 1431 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0);
1388 } 1432 }
1389 1433
1390 } } // namespace v8::internal 1434 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/scopes.h ('k') | src/variables.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698