2c61a7523a6dc33402a346681dc5775eb86c2a41
[profile/ivi/qtjsbackend.git] / src / 3rdparty / v8 / src / scopes.cc
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #include "v8.h"
29
30 #include "scopes.h"
31
32 #include "bootstrapper.h"
33 #include "compiler.h"
34 #include "messages.h"
35 #include "scopeinfo.h"
36
37 #include "allocation-inl.h"
38
39 namespace v8 {
40 namespace internal {
41
42 // ----------------------------------------------------------------------------
43 // Implementation of LocalsMap
44 //
45 // Note: We are storing the handle locations as key values in the hash map.
46 //       When inserting a new variable via Declare(), we rely on the fact that
47 //       the handle location remains alive for the duration of that variable
48 //       use. Because a Variable holding a handle with the same location exists
49 //       this is ensured.
50
51 static bool Match(void* key1, void* key2) {
52   String* name1 = *reinterpret_cast<String**>(key1);
53   String* name2 = *reinterpret_cast<String**>(key2);
54   ASSERT(name1->IsSymbol());
55   ASSERT(name2->IsSymbol());
56   return name1 == name2;
57 }
58
59
60 VariableMap::VariableMap() : ZoneHashMap(Match, 8) {}
61 VariableMap::~VariableMap() {}
62
63
64 Variable* VariableMap::Declare(
65     Scope* scope,
66     Handle<String> name,
67     VariableMode mode,
68     bool is_valid_lhs,
69     Variable::Kind kind,
70     InitializationFlag initialization_flag,
71     Interface* interface) {
72   Entry* p = ZoneHashMap::Lookup(name.location(), name->Hash(), true);
73   if (p->value == NULL) {
74     // The variable has not been declared yet -> insert it.
75     ASSERT(p->key == name.location());
76     p->value = new Variable(scope,
77                             name,
78                             mode,
79                             is_valid_lhs,
80                             kind,
81                             initialization_flag,
82                             interface);
83   }
84   return reinterpret_cast<Variable*>(p->value);
85 }
86
87
88 Variable* VariableMap::Lookup(Handle<String> name) {
89   Entry* p = ZoneHashMap::Lookup(name.location(), name->Hash(), false);
90   if (p != NULL) {
91     ASSERT(*reinterpret_cast<String**>(p->key) == *name);
92     ASSERT(p->value != NULL);
93     return reinterpret_cast<Variable*>(p->value);
94   }
95   return NULL;
96 }
97
98
99 // ----------------------------------------------------------------------------
100 // Implementation of Scope
101
102 Scope::Scope(Scope* outer_scope, ScopeType type)
103     : isolate_(Isolate::Current()),
104       inner_scopes_(4),
105       variables_(),
106       temps_(4),
107       params_(4),
108       unresolved_(16),
109       decls_(4),
110       interface_(FLAG_harmony_modules &&
111                  (type == MODULE_SCOPE || type == GLOBAL_SCOPE)
112                      ? Interface::NewModule() : NULL),
113       already_resolved_(false) {
114   SetDefaults(type, outer_scope, Handle<ScopeInfo>::null());
115   // At some point we might want to provide outer scopes to
116   // eval scopes (by walking the stack and reading the scope info).
117   // In that case, the ASSERT below needs to be adjusted.
118   ASSERT_EQ(type == GLOBAL_SCOPE, outer_scope == NULL);
119   ASSERT(!HasIllegalRedeclaration());
120 }
121
122
123 Scope::Scope(Scope* inner_scope,
124              ScopeType type,
125              Handle<ScopeInfo> scope_info)
126     : isolate_(Isolate::Current()),
127       inner_scopes_(4),
128       variables_(),
129       temps_(4),
130       params_(4),
131       unresolved_(16),
132       decls_(4),
133       interface_(NULL),
134       already_resolved_(true) {
135   SetDefaults(type, NULL, scope_info);
136   if (!scope_info.is_null()) {
137     num_heap_slots_ = scope_info_->ContextLength();
138   }
139   // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context.
140   num_heap_slots_ = Max(num_heap_slots_,
141                         static_cast<int>(Context::MIN_CONTEXT_SLOTS));
142   AddInnerScope(inner_scope);
143 }
144
145
146 Scope::Scope(Scope* inner_scope, Handle<String> catch_variable_name)
147     : isolate_(Isolate::Current()),
148       inner_scopes_(1),
149       variables_(),
150       temps_(0),
151       params_(0),
152       unresolved_(0),
153       decls_(0),
154       interface_(NULL),
155       already_resolved_(true) {
156   SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null());
157   AddInnerScope(inner_scope);
158   ++num_var_or_const_;
159   num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
160   Variable* variable = variables_.Declare(this,
161                                           catch_variable_name,
162                                           VAR,
163                                           true,  // Valid left-hand side.
164                                           Variable::NORMAL,
165                                           kCreatedInitialized);
166   AllocateHeapSlot(variable);
167 }
168
169
170 void Scope::SetDefaults(ScopeType type,
171                         Scope* outer_scope,
172                         Handle<ScopeInfo> scope_info) {
173   outer_scope_ = outer_scope;
174   type_ = type;
175   scope_name_ = isolate_->factory()->empty_symbol();
176   dynamics_ = NULL;
177   receiver_ = NULL;
178   function_ = NULL;
179   arguments_ = NULL;
180   illegal_redecl_ = NULL;
181   scope_inside_with_ = false;
182   scope_contains_with_ = false;
183   scope_calls_eval_ = false;
184   // Inherit the strict mode from the parent scope.
185   language_mode_ = (outer_scope != NULL)
186       ? outer_scope->language_mode_ : CLASSIC_MODE;
187   outer_scope_calls_non_strict_eval_ = false;
188   inner_scope_calls_eval_ = false;
189   force_eager_compilation_ = false;
190   num_var_or_const_ = 0;
191   num_stack_slots_ = 0;
192   num_heap_slots_ = 0;
193   scope_info_ = scope_info;
194   start_position_ = RelocInfo::kNoPosition;
195   end_position_ = RelocInfo::kNoPosition;
196   if (!scope_info.is_null()) {
197     scope_calls_eval_ = scope_info->CallsEval();
198     language_mode_ = scope_info->language_mode();
199   }
200 }
201
202
203 Scope* Scope::DeserializeScopeChain(Context* context, Scope* global_scope) {
204   // Reconstruct the outer scope chain from a closure's context chain.
205   Scope* current_scope = NULL;
206   Scope* innermost_scope = NULL;
207   bool contains_with = false;
208   while (!context->IsGlobalContext()) {
209     if (context->IsWithContext()) {
210       Scope* with_scope = new Scope(current_scope,
211                                     WITH_SCOPE,
212                                     Handle<ScopeInfo>::null());
213       current_scope = with_scope;
214       // All the inner scopes are inside a with.
215       contains_with = true;
216       for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) {
217         s->scope_inside_with_ = true;
218       }
219     } else if (context->IsFunctionContext()) {
220       ScopeInfo* scope_info = context->closure()->shared()->scope_info();
221       current_scope = new Scope(current_scope,
222                                 FUNCTION_SCOPE,
223                                 Handle<ScopeInfo>(scope_info));
224     } else if (context->IsBlockContext()) {
225       ScopeInfo* scope_info = ScopeInfo::cast(context->extension());
226       current_scope = new Scope(current_scope,
227                                 BLOCK_SCOPE,
228                                 Handle<ScopeInfo>(scope_info));
229     } else {
230       ASSERT(context->IsCatchContext());
231       String* name = String::cast(context->extension());
232       current_scope = new Scope(current_scope, Handle<String>(name));
233     }
234     if (contains_with) current_scope->RecordWithStatement();
235     if (innermost_scope == NULL) innermost_scope = current_scope;
236
237     // Forget about a with when we move to a context for a different function.
238     if (context->previous()->closure() != context->closure()) {
239       contains_with = false;
240     }
241     context = context->previous();
242   }
243
244   global_scope->AddInnerScope(current_scope);
245   global_scope->PropagateScopeInfo(false);
246   return (innermost_scope == NULL) ? global_scope : innermost_scope;
247 }
248
249
250 bool Scope::Analyze(CompilationInfo* info) {
251   ASSERT(info->function() != NULL);
252   Scope* scope = info->function()->scope();
253   Scope* top = scope;
254
255   // Traverse the scope tree up to the first unresolved scope or the global
256   // scope and start scope resolution and variable allocation from that scope.
257   while (!top->is_global_scope() &&
258          !top->outer_scope()->already_resolved()) {
259     top = top->outer_scope();
260   }
261
262   // Allocate the variables.
263   {
264     AstNodeFactory<AstNullVisitor> ast_node_factory(info->isolate());
265     if (!top->AllocateVariables(info, &ast_node_factory)) return false;
266   }
267
268 #ifdef DEBUG
269   if (info->isolate()->bootstrapper()->IsActive()
270           ? FLAG_print_builtin_scopes
271           : FLAG_print_scopes) {
272     scope->Print();
273   }
274
275   if (FLAG_harmony_modules && FLAG_print_interfaces && top->is_global_scope()) {
276     PrintF("global : ");
277     top->interface()->Print();
278   }
279 #endif
280
281   if (FLAG_harmony_scoping) {
282     VariableProxy* proxy = scope->CheckAssignmentToConst();
283     if (proxy != NULL) {
284       // Found an assignment to const. Throw a syntax error.
285       MessageLocation location(info->script(),
286                                proxy->position(),
287                                proxy->position());
288       Isolate* isolate = info->isolate();
289       Factory* factory = isolate->factory();
290       Handle<JSArray> array = factory->NewJSArray(0);
291       Handle<Object> result =
292           factory->NewSyntaxError("harmony_const_assign", array);
293       isolate->Throw(*result, &location);
294       return false;
295     }
296   }
297
298   info->SetScope(scope);
299   return true;
300 }
301
302
303 void Scope::Initialize() {
304   ASSERT(!already_resolved());
305
306   // Add this scope as a new inner scope of the outer scope.
307   if (outer_scope_ != NULL) {
308     outer_scope_->inner_scopes_.Add(this);
309     scope_inside_with_ = outer_scope_->scope_inside_with_ || is_with_scope();
310   } else {
311     scope_inside_with_ = is_with_scope();
312   }
313
314   // Declare convenience variables.
315   // Declare and allocate receiver (even for the global scope, and even
316   // if naccesses_ == 0).
317   // NOTE: When loading parameters in the global scope, we must take
318   // care not to access them as properties of the global object, but
319   // instead load them directly from the stack. Currently, the only
320   // such parameter is 'this' which is passed on the stack when
321   // invoking scripts
322   if (is_declaration_scope()) {
323     Variable* var =
324         variables_.Declare(this,
325                            isolate_->factory()->this_symbol(),
326                            VAR,
327                            false,
328                            Variable::THIS,
329                            kCreatedInitialized);
330     var->AllocateTo(Variable::PARAMETER, -1);
331     receiver_ = var;
332   } else {
333     ASSERT(outer_scope() != NULL);
334     receiver_ = outer_scope()->receiver();
335   }
336
337   if (is_function_scope()) {
338     // Declare 'arguments' variable which exists in all functions.
339     // Note that it might never be accessed, in which case it won't be
340     // allocated during variable allocation.
341     variables_.Declare(this,
342                        isolate_->factory()->arguments_symbol(),
343                        VAR,
344                        true,
345                        Variable::ARGUMENTS,
346                        kCreatedInitialized);
347   }
348 }
349
350
351 Scope* Scope::FinalizeBlockScope() {
352   ASSERT(is_block_scope());
353   ASSERT(temps_.is_empty());
354   ASSERT(params_.is_empty());
355
356   if (num_var_or_const() > 0) return this;
357
358   // Remove this scope from outer scope.
359   for (int i = 0; i < outer_scope_->inner_scopes_.length(); i++) {
360     if (outer_scope_->inner_scopes_[i] == this) {
361       outer_scope_->inner_scopes_.Remove(i);
362       break;
363     }
364   }
365
366   // Reparent inner scopes.
367   for (int i = 0; i < inner_scopes_.length(); i++) {
368     outer_scope()->AddInnerScope(inner_scopes_[i]);
369   }
370
371   // Move unresolved variables
372   for (int i = 0; i < unresolved_.length(); i++) {
373     outer_scope()->unresolved_.Add(unresolved_[i]);
374   }
375
376   return NULL;
377 }
378
379
380 Variable* Scope::LocalLookup(Handle<String> name) {
381   Variable* result = variables_.Lookup(name);
382   if (result != NULL || scope_info_.is_null()) {
383     return result;
384   }
385   // If we have a serialized scope info, we might find the variable there.
386   // There should be no local slot with the given name.
387   ASSERT(scope_info_->StackSlotIndex(*name) < 0);
388
389   // Check context slot lookup.
390   VariableMode mode;
391   Variable::Location location = Variable::CONTEXT;
392   InitializationFlag init_flag;
393   int index = scope_info_->ContextSlotIndex(*name, &mode, &init_flag);
394   if (index < 0) {
395     // Check parameters.
396     index = scope_info_->ParameterIndex(*name);
397     if (index < 0) return NULL;
398
399     mode = DYNAMIC;
400     location = Variable::LOOKUP;
401     init_flag = kCreatedInitialized;
402   }
403
404   Variable* var =
405       variables_.Declare(this,
406                          name,
407                          mode,
408                          true,
409                          Variable::NORMAL,
410                          init_flag);
411   var->AllocateTo(location, index);
412   return var;
413 }
414
415
416 Variable* Scope::LookupFunctionVar(Handle<String> name,
417                                    AstNodeFactory<AstNullVisitor>* factory) {
418   if (function_ != NULL && function_->proxy()->name().is_identical_to(name)) {
419     return function_->proxy()->var();
420   } else if (!scope_info_.is_null()) {
421     // If we are backed by a scope info, try to lookup the variable there.
422     VariableMode mode;
423     int index = scope_info_->FunctionContextSlotIndex(*name, &mode);
424     if (index < 0) return NULL;
425     Variable* var = new Variable(
426         this, name, mode, true /* is valid LHS */,
427         Variable::NORMAL, kCreatedInitialized);
428     VariableProxy* proxy = factory->NewVariableProxy(var);
429     VariableDeclaration* declaration =
430         factory->NewVariableDeclaration(proxy, mode, this);
431     DeclareFunctionVar(declaration);
432     var->AllocateTo(Variable::CONTEXT, index);
433     return var;
434   } else {
435     return NULL;
436   }
437 }
438
439
440 Variable* Scope::Lookup(Handle<String> name) {
441   for (Scope* scope = this;
442        scope != NULL;
443        scope = scope->outer_scope()) {
444     Variable* var = scope->LocalLookup(name);
445     if (var != NULL) return var;
446   }
447   return NULL;
448 }
449
450
451 void Scope::DeclareParameter(Handle<String> name, VariableMode mode) {
452   ASSERT(!already_resolved());
453   ASSERT(is_function_scope());
454   Variable* var = variables_.Declare(
455       this, name, mode, true, Variable::NORMAL, kCreatedInitialized);
456   params_.Add(var);
457 }
458
459
460 Variable* Scope::DeclareLocal(Handle<String> name,
461                               VariableMode mode,
462                               InitializationFlag init_flag,
463                               Interface* interface) {
464   ASSERT(!already_resolved());
465   // This function handles VAR and CONST modes.  DYNAMIC variables are
466   // introduces during variable allocation, INTERNAL variables are allocated
467   // explicitly, and TEMPORARY variables are allocated via NewTemporary().
468   ASSERT(mode == VAR ||
469          mode == CONST ||
470          mode == CONST_HARMONY ||
471          mode == LET);
472   ++num_var_or_const_;
473   return variables_.Declare(
474       this, name, mode, true, Variable::NORMAL, init_flag, interface);
475 }
476
477
478 Variable* Scope::DeclareGlobal(Handle<String> name) {
479   ASSERT(is_global_scope());
480   return variables_.Declare(this,
481                             name,
482                             DYNAMIC_GLOBAL,
483                             true,
484                             Variable::NORMAL,
485                             kCreatedInitialized);
486 }
487
488
489 void Scope::RemoveUnresolved(VariableProxy* var) {
490   // Most likely (always?) any variable we want to remove
491   // was just added before, so we search backwards.
492   for (int i = unresolved_.length(); i-- > 0;) {
493     if (unresolved_[i] == var) {
494       unresolved_.Remove(i);
495       return;
496     }
497   }
498 }
499
500
501 Variable* Scope::NewTemporary(Handle<String> name) {
502   ASSERT(!already_resolved());
503   Variable* var = new Variable(this,
504                                name,
505                                TEMPORARY,
506                                true,
507                                Variable::NORMAL,
508                                kCreatedInitialized);
509   temps_.Add(var);
510   return var;
511 }
512
513
514 void Scope::AddDeclaration(Declaration* declaration) {
515   decls_.Add(declaration);
516 }
517
518
519 void Scope::SetIllegalRedeclaration(Expression* expression) {
520   // Record only the first illegal redeclaration.
521   if (!HasIllegalRedeclaration()) {
522     illegal_redecl_ = expression;
523   }
524   ASSERT(HasIllegalRedeclaration());
525 }
526
527
528 void Scope::VisitIllegalRedeclaration(AstVisitor* visitor) {
529   ASSERT(HasIllegalRedeclaration());
530   illegal_redecl_->Accept(visitor);
531 }
532
533
534 Declaration* Scope::CheckConflictingVarDeclarations() {
535   int length = decls_.length();
536   for (int i = 0; i < length; i++) {
537     Declaration* decl = decls_[i];
538     if (decl->mode() != VAR) continue;
539     Handle<String> name = decl->proxy()->name();
540
541     // Iterate through all scopes until and including the declaration scope.
542     Scope* previous = NULL;
543     Scope* current = decl->scope();
544     do {
545       // There is a conflict if there exists a non-VAR binding.
546       Variable* other_var = current->variables_.Lookup(name);
547       if (other_var != NULL && other_var->mode() != VAR) {
548         return decl;
549       }
550       previous = current;
551       current = current->outer_scope_;
552     } while (!previous->is_declaration_scope());
553   }
554   return NULL;
555 }
556
557
558 VariableProxy* Scope::CheckAssignmentToConst() {
559   // Check this scope.
560   if (is_extended_mode()) {
561     for (int i = 0; i < unresolved_.length(); i++) {
562       ASSERT(unresolved_[i]->var() != NULL);
563       if (unresolved_[i]->var()->is_const_mode() &&
564           unresolved_[i]->IsLValue()) {
565         return unresolved_[i];
566       }
567     }
568   }
569
570   // Check inner scopes.
571   for (int i = 0; i < inner_scopes_.length(); i++) {
572     VariableProxy* proxy = inner_scopes_[i]->CheckAssignmentToConst();
573     if (proxy != NULL) return proxy;
574   }
575
576   // No assignments to const found.
577   return NULL;
578 }
579
580
581 void Scope::CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals,
582                                          ZoneList<Variable*>* context_locals) {
583   ASSERT(stack_locals != NULL);
584   ASSERT(context_locals != NULL);
585
586   // Collect temporaries which are always allocated on the stack.
587   for (int i = 0; i < temps_.length(); i++) {
588     Variable* var = temps_[i];
589     if (var->is_used()) {
590       ASSERT(var->IsStackLocal());
591       stack_locals->Add(var);
592     }
593   }
594
595   // Collect declared local variables.
596   for (VariableMap::Entry* p = variables_.Start();
597        p != NULL;
598        p = variables_.Next(p)) {
599     Variable* var = reinterpret_cast<Variable*>(p->value);
600     if (var->is_used()) {
601       if (var->IsStackLocal()) {
602         stack_locals->Add(var);
603       } else if (var->IsContextSlot()) {
604         context_locals->Add(var);
605       }
606     }
607   }
608 }
609
610
611 bool Scope::AllocateVariables(CompilationInfo* info,
612                               AstNodeFactory<AstNullVisitor>* factory) {
613   // 1) Propagate scope information.
614   bool outer_scope_calls_non_strict_eval = false;
615   if (outer_scope_ != NULL) {
616     outer_scope_calls_non_strict_eval =
617         outer_scope_->outer_scope_calls_non_strict_eval() |
618         outer_scope_->calls_non_strict_eval();
619   }
620   PropagateScopeInfo(outer_scope_calls_non_strict_eval);
621
622   // 2) Resolve variables.
623   if (!ResolveVariablesRecursively(info, factory)) return false;
624
625   // 3) Allocate variables.
626   AllocateVariablesRecursively();
627
628   return true;
629 }
630
631
632 bool Scope::AllowsLazyCompilation() const {
633   return !force_eager_compilation_ && HasTrivialOuterContext();
634 }
635
636
637 bool Scope::HasTrivialContext() const {
638   // A function scope has a trivial context if it always is the global
639   // context. We iteratively scan out the context chain to see if
640   // there is anything that makes this scope non-trivial; otherwise we
641   // return true.
642   for (const Scope* scope = this; scope != NULL; scope = scope->outer_scope_) {
643     if (scope->is_eval_scope()) return false;
644     if (scope->scope_inside_with_) return false;
645     if (scope->num_heap_slots_ > 0) return false;
646   }
647   return true;
648 }
649
650
651 bool Scope::HasTrivialOuterContext() const {
652   Scope* outer = outer_scope_;
653   if (outer == NULL) return true;
654   // Note that the outer context may be trivial in general, but the current
655   // scope may be inside a 'with' statement in which case the outer context
656   // for this scope is not trivial.
657   return !scope_inside_with_ && outer->HasTrivialContext();
658 }
659
660
661 bool Scope::AllowsLazyRecompilation() const {
662   return !force_eager_compilation_ &&
663          !TrivialDeclarationScopesBeforeWithScope();
664 }
665
666
667 bool Scope::TrivialDeclarationScopesBeforeWithScope() const {
668   Scope* outer = outer_scope_;
669   if (outer == NULL) return false;
670   outer = outer->DeclarationScope();
671   while (outer != NULL) {
672     if (outer->is_with_scope()) return true;
673     if (outer->is_declaration_scope() && outer->num_heap_slots() > 0)
674       return false;
675     outer = outer->outer_scope_;
676   }
677   return false;
678 }
679
680
681 int Scope::ContextChainLength(Scope* scope) {
682   int n = 0;
683   for (Scope* s = this; s != scope; s = s->outer_scope_) {
684     ASSERT(s != NULL);  // scope must be in the scope chain
685     if (s->num_heap_slots() > 0) n++;
686   }
687   return n;
688 }
689
690
691 Scope* Scope::DeclarationScope() {
692   Scope* scope = this;
693   while (!scope->is_declaration_scope()) {
694     scope = scope->outer_scope();
695   }
696   return scope;
697 }
698
699
700 Handle<ScopeInfo> Scope::GetScopeInfo() {
701   if (scope_info_.is_null()) {
702     scope_info_ = ScopeInfo::Create(this);
703   }
704   return scope_info_;
705 }
706
707
708 void Scope::GetNestedScopeChain(
709     List<Handle<ScopeInfo> >* chain,
710     int position) {
711   if (!is_eval_scope()) chain->Add(Handle<ScopeInfo>(GetScopeInfo()));
712
713   for (int i = 0; i < inner_scopes_.length(); i++) {
714     Scope* scope = inner_scopes_[i];
715     int beg_pos = scope->start_position();
716     int end_pos = scope->end_position();
717     ASSERT(beg_pos >= 0 && end_pos >= 0);
718     if (beg_pos <= position && position < end_pos) {
719       scope->GetNestedScopeChain(chain, position);
720       return;
721     }
722   }
723 }
724
725
726 #ifdef DEBUG
727 static const char* Header(ScopeType type) {
728   switch (type) {
729     case EVAL_SCOPE: return "eval";
730     case FUNCTION_SCOPE: return "function";
731     case MODULE_SCOPE: return "module";
732     case GLOBAL_SCOPE: return "global";
733     case CATCH_SCOPE: return "catch";
734     case BLOCK_SCOPE: return "block";
735     case WITH_SCOPE: return "with";
736   }
737   UNREACHABLE();
738   return NULL;
739 }
740
741
742 static void Indent(int n, const char* str) {
743   PrintF("%*s%s", n, "", str);
744 }
745
746
747 static void PrintName(Handle<String> name) {
748   SmartArrayPointer<char> s = name->ToCString(DISALLOW_NULLS);
749   PrintF("%s", *s);
750 }
751
752
753 static void PrintLocation(Variable* var) {
754   switch (var->location()) {
755     case Variable::UNALLOCATED:
756       break;
757     case Variable::PARAMETER:
758       PrintF("parameter[%d]", var->index());
759       break;
760     case Variable::LOCAL:
761       PrintF("local[%d]", var->index());
762       break;
763     case Variable::CONTEXT:
764       PrintF("context[%d]", var->index());
765       break;
766     case Variable::LOOKUP:
767       PrintF("lookup");
768       break;
769   }
770 }
771
772
773 static void PrintVar(int indent, Variable* var) {
774   if (var->is_used() || !var->IsUnallocated()) {
775     Indent(indent, Variable::Mode2String(var->mode()));
776     PrintF(" ");
777     PrintName(var->name());
778     PrintF(";  // ");
779     PrintLocation(var);
780     if (var->has_forced_context_allocation()) {
781       if (!var->IsUnallocated()) PrintF(", ");
782       PrintF("forced context allocation");
783     }
784     PrintF("\n");
785   }
786 }
787
788
789 static void PrintMap(int indent, VariableMap* map) {
790   for (VariableMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) {
791     Variable* var = reinterpret_cast<Variable*>(p->value);
792     PrintVar(indent, var);
793   }
794 }
795
796
797 void Scope::Print(int n) {
798   int n0 = (n > 0 ? n : 0);
799   int n1 = n0 + 2;  // indentation
800
801   // Print header.
802   Indent(n0, Header(type_));
803   if (scope_name_->length() > 0) {
804     PrintF(" ");
805     PrintName(scope_name_);
806   }
807
808   // Print parameters, if any.
809   if (is_function_scope()) {
810     PrintF(" (");
811     for (int i = 0; i < params_.length(); i++) {
812       if (i > 0) PrintF(", ");
813       PrintName(params_[i]->name());
814     }
815     PrintF(")");
816   }
817
818   PrintF(" { // (%d, %d)\n", start_position(), end_position());
819
820   // Function name, if any (named function literals, only).
821   if (function_ != NULL) {
822     Indent(n1, "// (local) function name: ");
823     PrintName(function_->proxy()->name());
824     PrintF("\n");
825   }
826
827   // Scope info.
828   if (HasTrivialOuterContext()) {
829     Indent(n1, "// scope has trivial outer context\n");
830   }
831   switch (language_mode()) {
832     case CLASSIC_MODE:
833       break;
834     case STRICT_MODE:
835       Indent(n1, "// strict mode scope\n");
836       break;
837     case EXTENDED_MODE:
838       Indent(n1, "// extended mode scope\n");
839       break;
840   }
841   if (scope_inside_with_) Indent(n1, "// scope inside 'with'\n");
842   if (scope_contains_with_) Indent(n1, "// scope contains 'with'\n");
843   if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n");
844   if (outer_scope_calls_non_strict_eval_) {
845     Indent(n1, "// outer scope calls 'eval' in non-strict context\n");
846   }
847   if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n");
848   if (num_stack_slots_ > 0) { Indent(n1, "// ");
849   PrintF("%d stack slots\n", num_stack_slots_); }
850   if (num_heap_slots_ > 0) { Indent(n1, "// ");
851   PrintF("%d heap slots\n", num_heap_slots_); }
852
853   // Print locals.
854   Indent(n1, "// function var\n");
855   if (function_ != NULL) {
856     PrintVar(n1, function_->proxy()->var());
857   }
858
859   Indent(n1, "// temporary vars\n");
860   for (int i = 0; i < temps_.length(); i++) {
861     PrintVar(n1, temps_[i]);
862   }
863
864   Indent(n1, "// local vars\n");
865   PrintMap(n1, &variables_);
866
867   Indent(n1, "// dynamic vars\n");
868   if (dynamics_ != NULL) {
869     PrintMap(n1, dynamics_->GetMap(DYNAMIC));
870     PrintMap(n1, dynamics_->GetMap(DYNAMIC_LOCAL));
871     PrintMap(n1, dynamics_->GetMap(DYNAMIC_GLOBAL));
872   }
873
874   // Print inner scopes (disable by providing negative n).
875   if (n >= 0) {
876     for (int i = 0; i < inner_scopes_.length(); i++) {
877       PrintF("\n");
878       inner_scopes_[i]->Print(n1);
879     }
880   }
881
882   Indent(n0, "}\n");
883 }
884 #endif  // DEBUG
885
886
887 Variable* Scope::NonLocal(Handle<String> name, VariableMode mode) {
888   if (dynamics_ == NULL) dynamics_ = new DynamicScopePart();
889   VariableMap* map = dynamics_->GetMap(mode);
890   Variable* var = map->Lookup(name);
891   if (var == NULL) {
892     // Declare a new non-local.
893     InitializationFlag init_flag = (mode == VAR)
894         ? kCreatedInitialized : kNeedsInitialization;
895     var = map->Declare(NULL,
896                        name,
897                        mode,
898                        true,
899                        Variable::NORMAL,
900                        init_flag);
901     // Allocate it by giving it a dynamic lookup.
902     var->AllocateTo(Variable::LOOKUP, -1);
903   }
904   return var;
905 }
906
907
908 Variable* Scope::LookupRecursive(Handle<String> name,
909                                  BindingKind* binding_kind,
910                                  AstNodeFactory<AstNullVisitor>* factory) {
911   ASSERT(binding_kind != NULL);
912   // Try to find the variable in this scope.
913   Variable* var = LocalLookup(name);
914
915   // We found a variable and we are done. (Even if there is an 'eval' in
916   // this scope which introduces the same variable again, the resulting
917   // variable remains the same.)
918   if (var != NULL) {
919     *binding_kind = BOUND;
920     return var;
921   }
922
923   // We did not find a variable locally. Check against the function variable,
924   // if any. We can do this for all scopes, since the function variable is
925   // only present - if at all - for function scopes.
926   *binding_kind = UNBOUND;
927   var = LookupFunctionVar(name, factory);
928   if (var != NULL) {
929     *binding_kind = BOUND;
930   } else if (outer_scope_ != NULL) {
931     var = outer_scope_->LookupRecursive(name, binding_kind, factory);
932     if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) {
933       var->ForceContextAllocation();
934     }
935   } else {
936     ASSERT(is_global_scope());
937   }
938
939   if (is_with_scope()) {
940     // The current scope is a with scope, so the variable binding can not be
941     // statically resolved. However, note that it was necessary to do a lookup
942     // in the outer scope anyway, because if a binding exists in an outer scope,
943     // the associated variable has to be marked as potentially being accessed
944     // from inside of an inner with scope (the property may not be in the 'with'
945     // object).
946     *binding_kind = DYNAMIC_LOOKUP;
947     return NULL;
948   } else if (calls_non_strict_eval()) {
949     // A variable binding may have been found in an outer scope, but the current
950     // scope makes a non-strict 'eval' call, so the found variable may not be
951     // the correct one (the 'eval' may introduce a binding with the same name).
952     // In that case, change the lookup result to reflect this situation.
953     if (*binding_kind == BOUND) {
954       *binding_kind = BOUND_EVAL_SHADOWED;
955     } else if (*binding_kind == UNBOUND) {
956       *binding_kind = UNBOUND_EVAL_SHADOWED;
957     }
958   }
959   return var;
960 }
961
962
963 bool Scope::ResolveVariable(CompilationInfo* info,
964                             VariableProxy* proxy,
965                             AstNodeFactory<AstNullVisitor>* factory) {
966   ASSERT(info->global_scope()->is_global_scope());
967
968   // If the proxy is already resolved there's nothing to do
969   // (functions and consts may be resolved by the parser).
970   if (proxy->var() != NULL) return true;
971
972   // Otherwise, try to resolve the variable.
973   BindingKind binding_kind;
974   Variable* var = LookupRecursive(proxy->name(), &binding_kind, factory);
975   switch (binding_kind) {
976     case BOUND:
977       // We found a variable binding.
978       break;
979
980     case BOUND_EVAL_SHADOWED:
981       // We either found a variable binding that might be shadowed by eval  or
982       // gave up on it (e.g. by encountering a local with the same in the outer
983       // scope which was not promoted to a context, this can happen if we use
984       // debugger to evaluate arbitrary expressions at a break point).
985       if (var->is_global()) {
986         var = NonLocal(proxy->name(), DYNAMIC_GLOBAL);
987       } else if (var->is_dynamic()) {
988         var = NonLocal(proxy->name(), DYNAMIC);
989       } else {
990         Variable* invalidated = var;
991         var = NonLocal(proxy->name(), DYNAMIC_LOCAL);
992         var->set_local_if_not_shadowed(invalidated);
993       }
994       break;
995
996     case UNBOUND:
997       // No binding has been found. Declare a variable in global scope.
998       var = info->global_scope()->DeclareGlobal(proxy->name());
999       break;
1000
1001     case UNBOUND_EVAL_SHADOWED:
1002       // No binding has been found. But some scope makes a
1003       // non-strict 'eval' call.
1004       var = NonLocal(proxy->name(), DYNAMIC_GLOBAL);
1005       break;
1006
1007     case DYNAMIC_LOOKUP:
1008       // The variable could not be resolved statically.
1009       var = NonLocal(proxy->name(), DYNAMIC);
1010       break;
1011   }
1012
1013   ASSERT(var != NULL);
1014   proxy->BindTo(var);
1015
1016   if (FLAG_harmony_modules) {
1017     bool ok;
1018 #ifdef DEBUG
1019     if (FLAG_print_interface_details)
1020       PrintF("# Resolve %s:\n", var->name()->ToAsciiArray());
1021 #endif
1022     proxy->interface()->Unify(var->interface(), &ok);
1023     if (!ok) {
1024 #ifdef DEBUG
1025       if (FLAG_print_interfaces) {
1026         PrintF("SCOPES TYPE ERROR\n");
1027         PrintF("proxy: ");
1028         proxy->interface()->Print();
1029         PrintF("var: ");
1030         var->interface()->Print();
1031       }
1032 #endif
1033
1034       // Inconsistent use of module. Throw a syntax error.
1035       // TODO(rossberg): generate more helpful error message.
1036       MessageLocation location(info->script(),
1037                                proxy->position(),
1038                                proxy->position());
1039       Isolate* isolate = Isolate::Current();
1040       Factory* factory = isolate->factory();
1041       Handle<JSArray> array = factory->NewJSArray(1);
1042       USE(JSObject::SetElement(array, 0, var->name(), NONE, kStrictMode));
1043       Handle<Object> result =
1044           factory->NewSyntaxError("module_type_error", array);
1045       isolate->Throw(*result, &location);
1046       return false;
1047     }
1048   }
1049
1050   return true;
1051 }
1052
1053
1054 bool Scope::ResolveVariablesRecursively(
1055     CompilationInfo* info,
1056     AstNodeFactory<AstNullVisitor>* factory) {
1057   ASSERT(info->global_scope()->is_global_scope());
1058
1059   // Resolve unresolved variables for this scope.
1060   for (int i = 0; i < unresolved_.length(); i++) {
1061     if (!ResolveVariable(info, unresolved_[i], factory)) return false;
1062   }
1063
1064   // Resolve unresolved variables for inner scopes.
1065   for (int i = 0; i < inner_scopes_.length(); i++) {
1066     if (!inner_scopes_[i]->ResolveVariablesRecursively(info, factory))
1067       return false;
1068   }
1069
1070   return true;
1071 }
1072
1073
1074 bool Scope::PropagateScopeInfo(bool outer_scope_calls_non_strict_eval ) {
1075   if (outer_scope_calls_non_strict_eval) {
1076     outer_scope_calls_non_strict_eval_ = true;
1077   }
1078
1079   bool calls_non_strict_eval =
1080       this->calls_non_strict_eval() || outer_scope_calls_non_strict_eval_;
1081   for (int i = 0; i < inner_scopes_.length(); i++) {
1082     Scope* inner_scope = inner_scopes_[i];
1083     if (inner_scope->PropagateScopeInfo(calls_non_strict_eval)) {
1084       inner_scope_calls_eval_ = true;
1085     }
1086     if (inner_scope->force_eager_compilation_) {
1087       force_eager_compilation_ = true;
1088     }
1089   }
1090
1091   return scope_calls_eval_ || inner_scope_calls_eval_;
1092 }
1093
1094
1095 bool Scope::MustAllocate(Variable* var) {
1096   // Give var a read/write use if there is a chance it might be accessed
1097   // via an eval() call.  This is only possible if the variable has a
1098   // visible name.
1099   if ((var->is_this() || var->name()->length() > 0) &&
1100       (var->has_forced_context_allocation() ||
1101        scope_calls_eval_ ||
1102        inner_scope_calls_eval_ ||
1103        scope_contains_with_ ||
1104        is_catch_scope() ||
1105        is_block_scope())) {
1106     var->set_is_used(true);
1107   }
1108   // Global variables do not need to be allocated.
1109   return !var->is_global() && var->is_used();
1110 }
1111
1112
1113 bool Scope::MustAllocateInContext(Variable* var) {
1114   // If var is accessed from an inner scope, or if there is a possibility
1115   // that it might be accessed from the current or an inner scope (through
1116   // an eval() call or a runtime with lookup), it must be allocated in the
1117   // context.
1118   //
1119   // Exceptions: temporary variables are never allocated in a context;
1120   // catch-bound variables are always allocated in a context.
1121   if (var->mode() == TEMPORARY) return false;
1122   if (is_catch_scope() || is_block_scope() || is_module_scope()) return true;
1123   return var->has_forced_context_allocation() ||
1124       scope_calls_eval_ ||
1125       inner_scope_calls_eval_ ||
1126       scope_contains_with_ ||
1127       var->is_global();
1128 }
1129
1130
1131 bool Scope::HasArgumentsParameter() {
1132   for (int i = 0; i < params_.length(); i++) {
1133     if (params_[i]->name().is_identical_to(
1134             isolate_->factory()->arguments_symbol())) {
1135       return true;
1136     }
1137   }
1138   return false;
1139 }
1140
1141
1142 void Scope::AllocateStackSlot(Variable* var) {
1143   var->AllocateTo(Variable::LOCAL, num_stack_slots_++);
1144 }
1145
1146
1147 void Scope::AllocateHeapSlot(Variable* var) {
1148   var->AllocateTo(Variable::CONTEXT, num_heap_slots_++);
1149 }
1150
1151
1152 void Scope::AllocateParameterLocals() {
1153   ASSERT(is_function_scope());
1154   Variable* arguments = LocalLookup(isolate_->factory()->arguments_symbol());
1155   ASSERT(arguments != NULL);  // functions have 'arguments' declared implicitly
1156
1157   bool uses_nonstrict_arguments = false;
1158
1159   if (MustAllocate(arguments) && !HasArgumentsParameter()) {
1160     // 'arguments' is used. Unless there is also a parameter called
1161     // 'arguments', we must be conservative and allocate all parameters to
1162     // the context assuming they will be captured by the arguments object.
1163     // If we have a parameter named 'arguments', a (new) value is always
1164     // assigned to it via the function invocation. Then 'arguments' denotes
1165     // that specific parameter value and cannot be used to access the
1166     // parameters, which is why we don't need to allocate an arguments
1167     // object in that case.
1168
1169     // We are using 'arguments'. Tell the code generator that is needs to
1170     // allocate the arguments object by setting 'arguments_'.
1171     arguments_ = arguments;
1172
1173     // In strict mode 'arguments' does not alias formal parameters.
1174     // Therefore in strict mode we allocate parameters as if 'arguments'
1175     // were not used.
1176     uses_nonstrict_arguments = is_classic_mode();
1177   }
1178
1179   // The same parameter may occur multiple times in the parameters_ list.
1180   // If it does, and if it is not copied into the context object, it must
1181   // receive the highest parameter index for that parameter; thus iteration
1182   // order is relevant!
1183   for (int i = params_.length() - 1; i >= 0; --i) {
1184     Variable* var = params_[i];
1185     ASSERT(var->scope() == this);
1186     if (uses_nonstrict_arguments) {
1187       // Force context allocation of the parameter.
1188       var->ForceContextAllocation();
1189     }
1190
1191     if (MustAllocate(var)) {
1192       if (MustAllocateInContext(var)) {
1193         ASSERT(var->IsUnallocated() || var->IsContextSlot());
1194         if (var->IsUnallocated()) {
1195           AllocateHeapSlot(var);
1196         }
1197       } else {
1198         ASSERT(var->IsUnallocated() || var->IsParameter());
1199         if (var->IsUnallocated()) {
1200           var->AllocateTo(Variable::PARAMETER, i);
1201         }
1202       }
1203     }
1204   }
1205 }
1206
1207
1208 void Scope::AllocateNonParameterLocal(Variable* var) {
1209   ASSERT(var->scope() == this);
1210   ASSERT(!var->IsVariable(isolate_->factory()->result_symbol()) ||
1211          !var->IsStackLocal());
1212   if (var->IsUnallocated() && MustAllocate(var)) {
1213     if (MustAllocateInContext(var)) {
1214       AllocateHeapSlot(var);
1215     } else {
1216       AllocateStackSlot(var);
1217     }
1218   }
1219 }
1220
1221
1222 void Scope::AllocateNonParameterLocals() {
1223   // All variables that have no rewrite yet are non-parameter locals.
1224   for (int i = 0; i < temps_.length(); i++) {
1225     AllocateNonParameterLocal(temps_[i]);
1226   }
1227
1228   for (VariableMap::Entry* p = variables_.Start();
1229        p != NULL;
1230        p = variables_.Next(p)) {
1231     Variable* var = reinterpret_cast<Variable*>(p->value);
1232     AllocateNonParameterLocal(var);
1233   }
1234
1235   // For now, function_ must be allocated at the very end.  If it gets
1236   // allocated in the context, it must be the last slot in the context,
1237   // because of the current ScopeInfo implementation (see
1238   // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor).
1239   if (function_ != NULL) {
1240     AllocateNonParameterLocal(function_->proxy()->var());
1241   }
1242 }
1243
1244
1245 void Scope::AllocateVariablesRecursively() {
1246   // Allocate variables for inner scopes.
1247   for (int i = 0; i < inner_scopes_.length(); i++) {
1248     inner_scopes_[i]->AllocateVariablesRecursively();
1249   }
1250
1251   // If scope is already resolved, we still need to allocate
1252   // variables in inner scopes which might not had been resolved yet.
1253   if (already_resolved()) return;
1254   // The number of slots required for variables.
1255   num_stack_slots_ = 0;
1256   num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
1257
1258   // Allocate variables for this scope.
1259   // Parameters must be allocated first, if any.
1260   if (is_function_scope()) AllocateParameterLocals();
1261   AllocateNonParameterLocals();
1262
1263   // Force allocation of a context for this scope if necessary. For a 'with'
1264   // scope and for a function scope that makes an 'eval' call we need a context,
1265   // even if no local variables were statically allocated in the scope.
1266   // Likewise for modules.
1267   bool must_have_context = is_with_scope() || is_module_scope() ||
1268       (is_function_scope() && calls_eval());
1269
1270   // If we didn't allocate any locals in the local context, then we only
1271   // need the minimal number of slots if we must have a context.
1272   if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) {
1273     num_heap_slots_ = 0;
1274   }
1275
1276   // Allocation done.
1277   ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS);
1278 }
1279
1280
1281 int Scope::StackLocalCount() const {
1282   return num_stack_slots() -
1283       (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0);
1284 }
1285
1286
1287 int Scope::ContextLocalCount() const {
1288   if (num_heap_slots() == 0) return 0;
1289   return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
1290       (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0);
1291 }
1292
1293 } }  // namespace v8::internal