v8  3.14.5(node0.10.28)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
scopes.cc
Go to the documentation of this file.
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 "accessors.h"
33 #include "bootstrapper.h"
34 #include "compiler.h"
35 #include "messages.h"
36 #include "scopeinfo.h"
37 
38 #include "allocation-inl.h"
39 
40 namespace v8 {
41 namespace internal {
42 
43 // ----------------------------------------------------------------------------
44 // Implementation of LocalsMap
45 //
46 // Note: We are storing the handle locations as key values in the hash map.
47 // When inserting a new variable via Declare(), we rely on the fact that
48 // the handle location remains alive for the duration of that variable
49 // use. Because a Variable holding a handle with the same location exists
50 // this is ensured.
51 
52 static bool Match(void* key1, void* key2) {
53  String* name1 = *reinterpret_cast<String**>(key1);
54  String* name2 = *reinterpret_cast<String**>(key2);
55  ASSERT(name1->IsSymbol());
56  ASSERT(name2->IsSymbol());
57  return name1 == name2;
58 }
59 
60 
62  : ZoneHashMap(Match, 8, ZoneAllocationPolicy(zone)),
63  zone_(zone) {}
65 
66 
68  Scope* scope,
69  Handle<String> name,
70  VariableMode mode,
71  bool is_valid_lhs,
72  Variable::Kind kind,
73  InitializationFlag initialization_flag,
75  Entry* p = ZoneHashMap::Lookup(name.location(), name->Hash(), true,
77  if (p->value == NULL) {
78  // The variable has not been declared yet -> insert it.
79  ASSERT(p->key == name.location());
80  p->value = new(zone()) Variable(scope,
81  name,
82  mode,
83  is_valid_lhs,
84  kind,
85  initialization_flag,
86  interface);
87  }
88  return reinterpret_cast<Variable*>(p->value);
89 }
90 
91 
93  Entry* p = ZoneHashMap::Lookup(name.location(), name->Hash(), false,
95  if (p != NULL) {
96  ASSERT(*reinterpret_cast<String**>(p->key) == *name);
97  ASSERT(p->value != NULL);
98  return reinterpret_cast<Variable*>(p->value);
99  }
100  return NULL;
101 }
102 
103 
104 // ----------------------------------------------------------------------------
105 // Implementation of Scope
106 
107 Scope::Scope(Scope* outer_scope, ScopeType type, Zone* zone)
108  : isolate_(Isolate::Current()),
109  inner_scopes_(4, zone),
110  variables_(zone),
111  temps_(4, zone),
112  params_(4, zone),
113  unresolved_(16, zone),
114  decls_(4, zone),
115  interface_(FLAG_harmony_modules &&
116  (type == MODULE_SCOPE || type == GLOBAL_SCOPE)
117  ? Interface::NewModule(zone) : NULL),
118  already_resolved_(false),
119  zone_(zone) {
120  SetDefaults(type, outer_scope, Handle<ScopeInfo>::null());
121  // The outermost scope must be a global scope.
122  ASSERT(type == GLOBAL_SCOPE || outer_scope != NULL);
124 }
125 
126 
127 Scope::Scope(Scope* inner_scope,
128  ScopeType type,
129  Handle<ScopeInfo> scope_info,
130  Zone* zone)
131  : isolate_(Isolate::Current()),
132  inner_scopes_(4, zone),
133  variables_(zone),
134  temps_(4, zone),
135  params_(4, zone),
136  unresolved_(16, zone),
137  decls_(4, zone),
138  interface_(NULL),
139  already_resolved_(true),
140  zone_(zone) {
141  SetDefaults(type, NULL, scope_info);
142  if (!scope_info.is_null()) {
143  num_heap_slots_ = scope_info_->ContextLength();
144  }
145  // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context.
147  static_cast<int>(Context::MIN_CONTEXT_SLOTS));
148  AddInnerScope(inner_scope);
149 }
150 
151 
152 Scope::Scope(Scope* inner_scope, Handle<String> catch_variable_name, Zone* zone)
153  : isolate_(Isolate::Current()),
154  inner_scopes_(1, zone),
155  variables_(zone),
156  temps_(0, zone),
157  params_(0, zone),
158  unresolved_(0, zone),
159  decls_(0, zone),
160  interface_(NULL),
161  already_resolved_(true),
162  zone_(zone) {
163  SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null());
164  AddInnerScope(inner_scope);
167  Variable* variable = variables_.Declare(this,
168  catch_variable_name,
169  VAR,
170  true, // Valid left-hand side.
173  AllocateHeapSlot(variable);
174 }
175 
176 
177 void Scope::SetDefaults(ScopeType type,
178  Scope* outer_scope,
179  Handle<ScopeInfo> scope_info) {
181  type_ = type;
182  scope_name_ = isolate_->factory()->empty_symbol();
183  dynamics_ = NULL;
184  receiver_ = NULL;
185  function_ = NULL;
186  arguments_ = NULL;
188  scope_inside_with_ = false;
189  scope_contains_with_ = false;
190  scope_calls_eval_ = false;
191  // Inherit the strict mode from the parent scope.
192  language_mode_ = (outer_scope != NULL)
193  ? outer_scope->language_mode_ : CLASSIC_MODE;
195  inner_scope_calls_eval_ = false;
196  force_eager_compilation_ = false;
197  num_var_or_const_ = 0;
198  num_stack_slots_ = 0;
199  num_heap_slots_ = 0;
200  scope_info_ = scope_info;
201  start_position_ = RelocInfo::kNoPosition;
202  end_position_ = RelocInfo::kNoPosition;
203  if (!scope_info.is_null()) {
204  scope_calls_eval_ = scope_info->CallsEval();
205  language_mode_ = scope_info->language_mode();
206  }
207 }
208 
209 
211  Zone* zone) {
212  // Reconstruct the outer scope chain from a closure's context chain.
213  Scope* current_scope = NULL;
214  Scope* innermost_scope = NULL;
215  bool contains_with = false;
216  while (!context->IsNativeContext()) {
217  if (context->IsWithContext()) {
218  Scope* with_scope = new(zone) Scope(current_scope,
219  WITH_SCOPE,
221  zone);
222  current_scope = with_scope;
223  // All the inner scopes are inside a with.
224  contains_with = true;
225  for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) {
226  s->scope_inside_with_ = true;
227  }
228  } else if (context->IsGlobalContext()) {
229  ScopeInfo* scope_info = ScopeInfo::cast(context->extension());
230  current_scope = new(zone) Scope(current_scope,
231  GLOBAL_SCOPE,
232  Handle<ScopeInfo>(scope_info),
233  zone);
234  } else if (context->IsModuleContext()) {
235  ScopeInfo* scope_info = ScopeInfo::cast(context->module()->scope_info());
236  current_scope = new(zone) Scope(current_scope,
237  MODULE_SCOPE,
238  Handle<ScopeInfo>(scope_info),
239  zone);
240  } else if (context->IsFunctionContext()) {
241  ScopeInfo* scope_info = context->closure()->shared()->scope_info();
242  current_scope = new(zone) Scope(current_scope,
244  Handle<ScopeInfo>(scope_info),
245  zone);
246  } else if (context->IsBlockContext()) {
247  ScopeInfo* scope_info = ScopeInfo::cast(context->extension());
248  current_scope = new(zone) Scope(current_scope,
249  BLOCK_SCOPE,
250  Handle<ScopeInfo>(scope_info),
251  zone);
252  } else {
253  ASSERT(context->IsCatchContext());
254  String* name = String::cast(context->extension());
255  current_scope = new(zone) Scope(
256  current_scope, Handle<String>(name), zone);
257  }
258  if (contains_with) current_scope->RecordWithStatement();
259  if (innermost_scope == NULL) innermost_scope = current_scope;
260 
261  // Forget about a with when we move to a context for a different function.
262  if (context->previous()->closure() != context->closure()) {
263  contains_with = false;
264  }
265  context = context->previous();
266  }
267 
268  global_scope->AddInnerScope(current_scope);
269  global_scope->PropagateScopeInfo(false);
270  return (innermost_scope == NULL) ? global_scope : innermost_scope;
271 }
272 
273 
275  ASSERT(info->function() != NULL);
276  Scope* scope = info->function()->scope();
277  Scope* top = scope;
278 
279  // Traverse the scope tree up to the first unresolved scope or the global
280  // scope and start scope resolution and variable allocation from that scope.
281  while (!top->is_global_scope() &&
282  !top->outer_scope()->already_resolved()) {
283  top = top->outer_scope();
284  }
285 
286  // Allocate the variables.
287  {
288  AstNodeFactory<AstNullVisitor> ast_node_factory(info->isolate(),
289  info->zone());
290  if (!top->AllocateVariables(info, &ast_node_factory)) return false;
291  }
292 
293 #ifdef DEBUG
294  if (info->isolate()->bootstrapper()->IsActive()
295  ? FLAG_print_builtin_scopes
296  : FLAG_print_scopes) {
297  scope->Print();
298  }
299 
300  if (FLAG_harmony_modules && FLAG_print_interfaces && top->is_global_scope()) {
301  PrintF("global : ");
302  top->interface()->Print();
303  }
304 #endif
305 
306  if (FLAG_harmony_scoping) {
307  VariableProxy* proxy = scope->CheckAssignmentToConst();
308  if (proxy != NULL) {
309  // Found an assignment to const. Throw a syntax error.
310  MessageLocation location(info->script(),
311  proxy->position(),
312  proxy->position());
313  Isolate* isolate = info->isolate();
314  Factory* factory = isolate->factory();
315  Handle<JSArray> array = factory->NewJSArray(0);
316  Handle<Object> result =
317  factory->NewSyntaxError("harmony_const_assign", array);
318  isolate->Throw(*result, &location);
319  return false;
320  }
321  }
322 
323  info->SetScope(scope);
324  return true;
325 }
326 
327 
330 
331  // Add this scope as a new inner scope of the outer scope.
332  if (outer_scope_ != NULL) {
333  outer_scope_->inner_scopes_.Add(this, zone());
335  } else {
337  }
338 
339  // Declare convenience variables.
340  // Declare and allocate receiver (even for the global scope, and even
341  // if naccesses_ == 0).
342  // NOTE: When loading parameters in the global scope, we must take
343  // care not to access them as properties of the global object, but
344  // instead load them directly from the stack. Currently, the only
345  // such parameter is 'this' which is passed on the stack when
346  // invoking scripts
347  if (is_declaration_scope()) {
348  Variable* var =
349  variables_.Declare(this,
350  isolate_->factory()->this_symbol(),
351  VAR,
352  false,
356  receiver_ = var;
357  } else {
358  ASSERT(outer_scope() != NULL);
360  }
361 
362  if (is_function_scope()) {
363  // Declare 'arguments' variable which exists in all functions.
364  // Note that it might never be accessed, in which case it won't be
365  // allocated during variable allocation.
366  variables_.Declare(this,
367  isolate_->factory()->arguments_symbol(),
368  VAR,
369  true,
372  }
373 }
374 
375 
378  ASSERT(temps_.is_empty());
379  ASSERT(params_.is_empty());
380 
381  if (num_var_or_const() > 0) return this;
382 
383  // Remove this scope from outer scope.
384  for (int i = 0; i < outer_scope_->inner_scopes_.length(); i++) {
385  if (outer_scope_->inner_scopes_[i] == this) {
386  outer_scope_->inner_scopes_.Remove(i);
387  break;
388  }
389  }
390 
391  // Reparent inner scopes.
392  for (int i = 0; i < inner_scopes_.length(); i++) {
393  outer_scope()->AddInnerScope(inner_scopes_[i]);
394  }
395 
396  // Move unresolved variables
397  for (int i = 0; i < unresolved_.length(); i++) {
398  outer_scope()->unresolved_.Add(unresolved_[i], zone());
399  }
400 
401  return NULL;
402 }
403 
404 
406  Variable* result = variables_.Lookup(name);
407  if (result != NULL || scope_info_.is_null()) {
408  return result;
409  }
410  // If we have a serialized scope info, we might find the variable there.
411  // There should be no local slot with the given name.
412  ASSERT(scope_info_->StackSlotIndex(*name) < 0);
413 
414  // Check context slot lookup.
415  VariableMode mode;
417  InitializationFlag init_flag;
418  int index = scope_info_->ContextSlotIndex(*name, &mode, &init_flag);
419  if (index < 0) {
420  // Check parameters.
421  index = scope_info_->ParameterIndex(*name);
422  if (index < 0) return NULL;
423 
424  mode = DYNAMIC;
425  location = Variable::LOOKUP;
426  init_flag = kCreatedInitialized;
427  }
428 
429  Variable* var = variables_.Declare(this, name, mode, true, Variable::NORMAL,
430  init_flag);
431  var->AllocateTo(location, index);
432  return var;
433 }
434 
435 
438  if (function_ != NULL && function_->proxy()->name().is_identical_to(name)) {
439  return function_->proxy()->var();
440  } else if (!scope_info_.is_null()) {
441  // If we are backed by a scope info, try to lookup the variable there.
442  VariableMode mode;
443  int index = scope_info_->FunctionContextSlotIndex(*name, &mode);
444  if (index < 0) return NULL;
445  Variable* var = new(zone()) Variable(
446  this, name, mode, true /* is valid LHS */,
448  VariableProxy* proxy = factory->NewVariableProxy(var);
449  VariableDeclaration* declaration =
450  factory->NewVariableDeclaration(proxy, mode, this);
451  DeclareFunctionVar(declaration);
452  var->AllocateTo(Variable::CONTEXT, index);
453  return var;
454  } else {
455  return NULL;
456  }
457 }
458 
459 
461  for (Scope* scope = this;
462  scope != NULL;
463  scope = scope->outer_scope()) {
464  Variable* var = scope->LocalLookup(name);
465  if (var != NULL) return var;
466  }
467  return NULL;
468 }
469 
470 
474  Variable* var = variables_.Declare(this, name, mode, true, Variable::NORMAL,
476  params_.Add(var, zone());
477 }
478 
479 
481  VariableMode mode,
482  InitializationFlag init_flag,
483  Interface* interface) {
485  // This function handles VAR and CONST modes. DYNAMIC variables are
486  // introduces during variable allocation, INTERNAL variables are allocated
487  // explicitly, and TEMPORARY variables are allocated via NewTemporary().
490  return variables_.Declare(
491  this, name, mode, true, Variable::NORMAL, init_flag, interface);
492 }
493 
494 
497  return variables_.Declare(this,
498  name,
500  true,
503 }
504 
505 
507  // Most likely (always?) any variable we want to remove
508  // was just added before, so we search backwards.
509  for (int i = unresolved_.length(); i-- > 0;) {
510  if (unresolved_[i] == var) {
511  unresolved_.Remove(i);
512  return;
513  }
514  }
515 }
516 
517 
520  Variable* var = new(zone()) Variable(this,
521  name,
522  TEMPORARY,
523  true,
526  temps_.Add(var, zone());
527  return var;
528 }
529 
530 
531 void Scope::AddDeclaration(Declaration* declaration) {
532  decls_.Add(declaration, zone());
533 }
534 
535 
537  // Record only the first illegal redeclaration.
538  if (!HasIllegalRedeclaration()) {
539  illegal_redecl_ = expression;
540  }
542 }
543 
544 
545 void Scope::VisitIllegalRedeclaration(AstVisitor* visitor) {
547  illegal_redecl_->Accept(visitor);
548 }
549 
550 
552  int length = decls_.length();
553  for (int i = 0; i < length; i++) {
554  Declaration* decl = decls_[i];
555  if (decl->mode() != VAR) continue;
556  Handle<String> name = decl->proxy()->name();
557 
558  // Iterate through all scopes until and including the declaration scope.
559  Scope* previous = NULL;
560  Scope* current = decl->scope();
561  do {
562  // There is a conflict if there exists a non-VAR binding.
563  Variable* other_var = current->variables_.Lookup(name);
564  if (other_var != NULL && other_var->mode() != VAR) {
565  return decl;
566  }
567  previous = current;
568  current = current->outer_scope_;
569  } while (!previous->is_declaration_scope());
570  }
571  return NULL;
572 }
573 
574 
576  // Check this scope.
577  if (is_extended_mode()) {
578  for (int i = 0; i < unresolved_.length(); i++) {
579  ASSERT(unresolved_[i]->var() != NULL);
580  if (unresolved_[i]->var()->is_const_mode() &&
581  unresolved_[i]->IsLValue()) {
582  return unresolved_[i];
583  }
584  }
585  }
586 
587  // Check inner scopes.
588  for (int i = 0; i < inner_scopes_.length(); i++) {
589  VariableProxy* proxy = inner_scopes_[i]->CheckAssignmentToConst();
590  if (proxy != NULL) return proxy;
591  }
592 
593  // No assignments to const found.
594  return NULL;
595 }
596 
597 
598 class VarAndOrder {
599  public:
600  VarAndOrder(Variable* var, int order) : var_(var), order_(order) { }
601  Variable* var() const { return var_; }
602  int order() const { return order_; }
603  static int Compare(const VarAndOrder* a, const VarAndOrder* b) {
604  return a->order_ - b->order_;
605  }
606 
607  private:
608  Variable* var_;
609  int order_;
610 };
611 
612 
614  ZoneList<Variable*>* context_locals) {
615  ASSERT(stack_locals != NULL);
616  ASSERT(context_locals != NULL);
617 
618  // Collect temporaries which are always allocated on the stack.
619  for (int i = 0; i < temps_.length(); i++) {
620  Variable* var = temps_[i];
621  if (var->is_used()) {
622  ASSERT(var->IsStackLocal());
623  stack_locals->Add(var, zone());
624  }
625  }
626 
628 
629  // Collect declared local variables.
630  for (VariableMap::Entry* p = variables_.Start();
631  p != NULL;
632  p = variables_.Next(p)) {
633  Variable* var = reinterpret_cast<Variable*>(p->value);
634  if (var->is_used()) {
635  vars.Add(VarAndOrder(var, p->order), zone());
636  }
637  }
638  vars.Sort(VarAndOrder::Compare);
639  int var_count = vars.length();
640  for (int i = 0; i < var_count; i++) {
641  Variable* var = vars[i].var();
642  if (var->IsStackLocal()) {
643  stack_locals->Add(var, zone());
644  } else if (var->IsContextSlot()) {
645  context_locals->Add(var, zone());
646  }
647  }
648 }
649 
650 
653  // 1) Propagate scope information.
655  if (outer_scope_ != NULL) {
656  outer_scope_calls_non_strict_eval =
659  }
660  PropagateScopeInfo(outer_scope_calls_non_strict_eval);
661 
662  // 2) Resolve variables.
663  if (!ResolveVariablesRecursively(info, factory)) return false;
664 
665  // 3) Allocate variables.
667 
668  // 4) Allocate and link module instance objects.
669  if (FLAG_harmony_modules && (is_global_scope() || is_module_scope())) {
670  AllocateModules(info);
671  LinkModules(info);
672  }
673 
674  return true;
675 }
676 
677 
679  // A function scope has a trivial context if it always is the global
680  // context. We iteratively scan out the context chain to see if
681  // there is anything that makes this scope non-trivial; otherwise we
682  // return true.
683  for (const Scope* scope = this; scope != NULL; scope = scope->outer_scope_) {
684  if (scope->is_eval_scope()) return false;
685  if (scope->scope_inside_with_) return false;
686  if (scope->num_heap_slots_ > 0) return false;
687  }
688  return true;
689 }
690 
691 
693  Scope* outer = outer_scope_;
694  if (outer == NULL) return true;
695  // Note that the outer context may be trivial in general, but the current
696  // scope may be inside a 'with' statement in which case the outer context
697  // for this scope is not trivial.
698  return !scope_inside_with_ && outer->HasTrivialContext();
699 }
700 
701 
703  Scope* outer = outer_scope_;
704  if (outer == NULL) return true;
705  // There are several reasons that prevent lazy compilation:
706  // - This scope is inside a with scope and all declaration scopes between
707  // them have empty contexts. Such declaration scopes become invisible
708  // during scope info deserialization.
709  // - This scope is inside a strict eval scope with variables that are
710  // potentially context allocated in an artificial function scope that
711  // is not deserialized correctly.
712  outer = outer->DeclarationScope();
713  bool found_non_trivial_declarations = false;
714  for (const Scope* scope = outer; scope != NULL; scope = scope->outer_scope_) {
715  if (scope->is_eval_scope()) return false;
716  if (scope->is_with_scope() && !found_non_trivial_declarations) return false;
717  if (scope->is_declaration_scope() && scope->num_heap_slots() > 0) {
718  found_non_trivial_declarations = true;
719  }
720  }
721  return true;
722 }
723 
724 
727 }
728 
729 
732 }
733 
734 
736  int n = 0;
737  for (Scope* s = this; s != scope; s = s->outer_scope_) {
738  ASSERT(s != NULL); // scope must be in the scope chain
739  if (s->num_heap_slots() > 0) n++;
740  }
741  return n;
742 }
743 
744 
746  Scope* scope = this;
747  while (!scope->is_declaration_scope()) {
748  scope = scope->outer_scope();
749  }
750  return scope;
751 }
752 
753 
755  if (scope_info_.is_null()) {
757  }
758  return scope_info_;
759 }
760 
761 
763  List<Handle<ScopeInfo> >* chain,
764  int position) {
765  if (!is_eval_scope()) chain->Add(Handle<ScopeInfo>(GetScopeInfo()));
766 
767  for (int i = 0; i < inner_scopes_.length(); i++) {
768  Scope* scope = inner_scopes_[i];
769  int beg_pos = scope->start_position();
770  int end_pos = scope->end_position();
771  ASSERT(beg_pos >= 0 && end_pos >= 0);
772  if (beg_pos <= position && position < end_pos) {
773  scope->GetNestedScopeChain(chain, position);
774  return;
775  }
776  }
777 }
778 
779 
780 #ifdef DEBUG
781 static const char* Header(ScopeType type) {
782  switch (type) {
783  case EVAL_SCOPE: return "eval";
784  case FUNCTION_SCOPE: return "function";
785  case MODULE_SCOPE: return "module";
786  case GLOBAL_SCOPE: return "global";
787  case CATCH_SCOPE: return "catch";
788  case BLOCK_SCOPE: return "block";
789  case WITH_SCOPE: return "with";
790  }
791  UNREACHABLE();
792  return NULL;
793 }
794 
795 
796 static void Indent(int n, const char* str) {
797  PrintF("%*s%s", n, "", str);
798 }
799 
800 
801 static void PrintName(Handle<String> name) {
802  SmartArrayPointer<char> s = name->ToCString(DISALLOW_NULLS);
803  PrintF("%s", *s);
804 }
805 
806 
807 static void PrintLocation(Variable* var) {
808  switch (var->location()) {
810  break;
811  case Variable::PARAMETER:
812  PrintF("parameter[%d]", var->index());
813  break;
814  case Variable::LOCAL:
815  PrintF("local[%d]", var->index());
816  break;
817  case Variable::CONTEXT:
818  PrintF("context[%d]", var->index());
819  break;
820  case Variable::LOOKUP:
821  PrintF("lookup");
822  break;
823  }
824 }
825 
826 
827 static void PrintVar(int indent, Variable* var) {
828  if (var->is_used() || !var->IsUnallocated()) {
829  Indent(indent, Variable::Mode2String(var->mode()));
830  PrintF(" ");
831  PrintName(var->name());
832  PrintF("; // ");
833  PrintLocation(var);
834  if (var->has_forced_context_allocation()) {
835  if (!var->IsUnallocated()) PrintF(", ");
836  PrintF("forced context allocation");
837  }
838  PrintF("\n");
839  }
840 }
841 
842 
843 static void PrintMap(int indent, VariableMap* map) {
844  for (VariableMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) {
845  Variable* var = reinterpret_cast<Variable*>(p->value);
846  PrintVar(indent, var);
847  }
848 }
849 
850 
851 void Scope::Print(int n) {
852  int n0 = (n > 0 ? n : 0);
853  int n1 = n0 + 2; // indentation
854 
855  // Print header.
856  Indent(n0, Header(type_));
857  if (scope_name_->length() > 0) {
858  PrintF(" ");
859  PrintName(scope_name_);
860  }
861 
862  // Print parameters, if any.
863  if (is_function_scope()) {
864  PrintF(" (");
865  for (int i = 0; i < params_.length(); i++) {
866  if (i > 0) PrintF(", ");
867  PrintName(params_[i]->name());
868  }
869  PrintF(")");
870  }
871 
872  PrintF(" { // (%d, %d)\n", start_position(), end_position());
873 
874  // Function name, if any (named function literals, only).
875  if (function_ != NULL) {
876  Indent(n1, "// (local) function name: ");
877  PrintName(function_->proxy()->name());
878  PrintF("\n");
879  }
880 
881  // Scope info.
882  if (HasTrivialOuterContext()) {
883  Indent(n1, "// scope has trivial outer context\n");
884  }
885  switch (language_mode()) {
886  case CLASSIC_MODE:
887  break;
888  case STRICT_MODE:
889  Indent(n1, "// strict mode scope\n");
890  break;
891  case EXTENDED_MODE:
892  Indent(n1, "// extended mode scope\n");
893  break;
894  }
895  if (scope_inside_with_) Indent(n1, "// scope inside 'with'\n");
896  if (scope_contains_with_) Indent(n1, "// scope contains 'with'\n");
897  if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n");
899  Indent(n1, "// outer scope calls 'eval' in non-strict context\n");
900  }
901  if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n");
902  if (num_stack_slots_ > 0) { Indent(n1, "// ");
903  PrintF("%d stack slots\n", num_stack_slots_); }
904  if (num_heap_slots_ > 0) { Indent(n1, "// ");
905  PrintF("%d heap slots\n", num_heap_slots_); }
906 
907  // Print locals.
908  Indent(n1, "// function var\n");
909  if (function_ != NULL) {
910  PrintVar(n1, function_->proxy()->var());
911  }
912 
913  Indent(n1, "// temporary vars\n");
914  for (int i = 0; i < temps_.length(); i++) {
915  PrintVar(n1, temps_[i]);
916  }
917 
918  Indent(n1, "// local vars\n");
919  PrintMap(n1, &variables_);
920 
921  Indent(n1, "// dynamic vars\n");
922  if (dynamics_ != NULL) {
926  }
927 
928  // Print inner scopes (disable by providing negative n).
929  if (n >= 0) {
930  for (int i = 0; i < inner_scopes_.length(); i++) {
931  PrintF("\n");
932  inner_scopes_[i]->Print(n1);
933  }
934  }
935 
936  Indent(n0, "}\n");
937 }
938 #endif // DEBUG
939 
940 
942  if (dynamics_ == NULL) dynamics_ = new(zone()) DynamicScopePart(zone());
943  VariableMap* map = dynamics_->GetMap(mode);
944  Variable* var = map->Lookup(name);
945  if (var == NULL) {
946  // Declare a new non-local.
947  InitializationFlag init_flag = (mode == VAR)
949  var = map->Declare(NULL,
950  name,
951  mode,
952  true,
954  init_flag);
955  // Allocate it by giving it a dynamic lookup.
956  var->AllocateTo(Variable::LOOKUP, -1);
957  }
958  return var;
959 }
960 
961 
963  BindingKind* binding_kind,
965  ASSERT(binding_kind != NULL);
966  // Try to find the variable in this scope.
967  Variable* var = LocalLookup(name);
968 
969  // We found a variable and we are done. (Even if there is an 'eval' in
970  // this scope which introduces the same variable again, the resulting
971  // variable remains the same.)
972  if (var != NULL) {
973  *binding_kind = BOUND;
974  return var;
975  }
976 
977  // We did not find a variable locally. Check against the function variable,
978  // if any. We can do this for all scopes, since the function variable is
979  // only present - if at all - for function scopes.
980  *binding_kind = UNBOUND;
981  var = LookupFunctionVar(name, factory);
982  if (var != NULL) {
983  *binding_kind = BOUND;
984  } else if (outer_scope_ != NULL) {
985  var = outer_scope_->LookupRecursive(name, binding_kind, factory);
986  if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) {
987  var->ForceContextAllocation();
988  }
989  } else {
991  }
992 
993  if (is_with_scope()) {
994  // The current scope is a with scope, so the variable binding can not be
995  // statically resolved. However, note that it was necessary to do a lookup
996  // in the outer scope anyway, because if a binding exists in an outer scope,
997  // the associated variable has to be marked as potentially being accessed
998  // from inside of an inner with scope (the property may not be in the 'with'
999  // object).
1000  *binding_kind = DYNAMIC_LOOKUP;
1001  return NULL;
1002  } else if (calls_non_strict_eval()) {
1003  // A variable binding may have been found in an outer scope, but the current
1004  // scope makes a non-strict 'eval' call, so the found variable may not be
1005  // the correct one (the 'eval' may introduce a binding with the same name).
1006  // In that case, change the lookup result to reflect this situation.
1007  if (*binding_kind == BOUND) {
1008  *binding_kind = BOUND_EVAL_SHADOWED;
1009  } else if (*binding_kind == UNBOUND) {
1010  *binding_kind = UNBOUND_EVAL_SHADOWED;
1011  }
1012  }
1013  return var;
1014 }
1015 
1016 
1018  VariableProxy* proxy,
1019  AstNodeFactory<AstNullVisitor>* factory) {
1020  ASSERT(info->global_scope()->is_global_scope());
1021 
1022  // If the proxy is already resolved there's nothing to do
1023  // (functions and consts may be resolved by the parser).
1024  if (proxy->var() != NULL) return true;
1025 
1026  // Otherwise, try to resolve the variable.
1027  BindingKind binding_kind;
1028  Variable* var = LookupRecursive(proxy->name(), &binding_kind, factory);
1029  switch (binding_kind) {
1030  case BOUND:
1031  // We found a variable binding.
1032  break;
1033 
1034  case BOUND_EVAL_SHADOWED:
1035  // We either found a variable binding that might be shadowed by eval or
1036  // gave up on it (e.g. by encountering a local with the same in the outer
1037  // scope which was not promoted to a context, this can happen if we use
1038  // debugger to evaluate arbitrary expressions at a break point).
1039  if (var->IsGlobalObjectProperty()) {
1040  var = NonLocal(proxy->name(), DYNAMIC_GLOBAL);
1041  } else if (var->is_dynamic()) {
1042  var = NonLocal(proxy->name(), DYNAMIC);
1043  } else {
1044  Variable* invalidated = var;
1045  var = NonLocal(proxy->name(), DYNAMIC_LOCAL);
1046  var->set_local_if_not_shadowed(invalidated);
1047  }
1048  break;
1049 
1050  case UNBOUND:
1051  // No binding has been found. Declare a variable on the global object.
1052  var = info->global_scope()->DeclareDynamicGlobal(proxy->name());
1053  break;
1054 
1055  case UNBOUND_EVAL_SHADOWED:
1056  // No binding has been found. But some scope makes a
1057  // non-strict 'eval' call.
1058  var = NonLocal(proxy->name(), DYNAMIC_GLOBAL);
1059  break;
1060 
1061  case DYNAMIC_LOOKUP:
1062  // The variable could not be resolved statically.
1063  var = NonLocal(proxy->name(), DYNAMIC);
1064  break;
1065  }
1066 
1067  ASSERT(var != NULL);
1068  proxy->BindTo(var);
1069 
1070  if (FLAG_harmony_modules) {
1071  bool ok;
1072 #ifdef DEBUG
1073  if (FLAG_print_interface_details)
1074  PrintF("# Resolve %s:\n", var->name()->ToAsciiArray());
1075 #endif
1076  proxy->interface()->Unify(var->interface(), zone(), &ok);
1077  if (!ok) {
1078 #ifdef DEBUG
1079  if (FLAG_print_interfaces) {
1080  PrintF("SCOPES TYPE ERROR\n");
1081  PrintF("proxy: ");
1082  proxy->interface()->Print();
1083  PrintF("var: ");
1084  var->interface()->Print();
1085  }
1086 #endif
1087 
1088  // Inconsistent use of module. Throw a syntax error.
1089  // TODO(rossberg): generate more helpful error message.
1090  MessageLocation location(info->script(),
1091  proxy->position(),
1092  proxy->position());
1093  Isolate* isolate = Isolate::Current();
1094  Factory* factory = isolate->factory();
1095  Handle<JSArray> array = factory->NewJSArray(1);
1096  USE(JSObject::SetElement(array, 0, var->name(), NONE, kStrictMode));
1097  Handle<Object> result =
1098  factory->NewSyntaxError("module_type_error", array);
1099  isolate->Throw(*result, &location);
1100  return false;
1101  }
1102  }
1103 
1104  return true;
1105 }
1106 
1107 
1109  CompilationInfo* info,
1110  AstNodeFactory<AstNullVisitor>* factory) {
1111  ASSERT(info->global_scope()->is_global_scope());
1112 
1113  // Resolve unresolved variables for this scope.
1114  for (int i = 0; i < unresolved_.length(); i++) {
1115  if (!ResolveVariable(info, unresolved_[i], factory)) return false;
1116  }
1117 
1118  // Resolve unresolved variables for inner scopes.
1119  for (int i = 0; i < inner_scopes_.length(); i++) {
1120  if (!inner_scopes_[i]->ResolveVariablesRecursively(info, factory))
1121  return false;
1122  }
1123 
1124  return true;
1125 }
1126 
1127 
1128 bool Scope::PropagateScopeInfo(bool outer_scope_calls_non_strict_eval ) {
1129  if (outer_scope_calls_non_strict_eval) {
1131  }
1132 
1133  bool calls_non_strict_eval =
1135  for (int i = 0; i < inner_scopes_.length(); i++) {
1136  Scope* inner_scope = inner_scopes_[i];
1137  if (inner_scope->PropagateScopeInfo(calls_non_strict_eval)) {
1138  inner_scope_calls_eval_ = true;
1139  }
1140  if (inner_scope->force_eager_compilation_) {
1141  force_eager_compilation_ = true;
1142  }
1143  }
1144 
1146 }
1147 
1148 
1150  // Give var a read/write use if there is a chance it might be accessed
1151  // via an eval() call. This is only possible if the variable has a
1152  // visible name.
1153  if ((var->is_this() || var->name()->length() > 0) &&
1158  is_catch_scope() ||
1159  is_block_scope() ||
1160  is_module_scope() ||
1161  is_global_scope())) {
1162  var->set_is_used(true);
1163  }
1164  // Global variables do not need to be allocated.
1165  return !var->IsGlobalObjectProperty() && var->is_used();
1166 }
1167 
1168 
1170  // If var is accessed from an inner scope, or if there is a possibility
1171  // that it might be accessed from the current or an inner scope (through
1172  // an eval() call or a runtime with lookup), it must be allocated in the
1173  // context.
1174  //
1175  // Exceptions: temporary variables are never allocated in a context;
1176  // catch-bound variables are always allocated in a context.
1177  if (var->mode() == TEMPORARY) return false;
1178  if (is_catch_scope() || is_block_scope() || is_module_scope()) return true;
1179  if (is_global_scope() && IsLexicalVariableMode(var->mode())) return true;
1180  return var->has_forced_context_allocation() ||
1184 }
1185 
1186 
1188  for (int i = 0; i < params_.length(); i++) {
1189  if (params_[i]->name().is_identical_to(
1190  isolate_->factory()->arguments_symbol())) {
1191  return true;
1192  }
1193  }
1194  return false;
1195 }
1196 
1197 
1200 }
1201 
1202 
1205 }
1206 
1207 
1210  Variable* arguments = LocalLookup(isolate_->factory()->arguments_symbol());
1211  ASSERT(arguments != NULL); // functions have 'arguments' declared implicitly
1212 
1213  bool uses_nonstrict_arguments = false;
1214 
1215  if (MustAllocate(arguments) && !HasArgumentsParameter()) {
1216  // 'arguments' is used. Unless there is also a parameter called
1217  // 'arguments', we must be conservative and allocate all parameters to
1218  // the context assuming they will be captured by the arguments object.
1219  // If we have a parameter named 'arguments', a (new) value is always
1220  // assigned to it via the function invocation. Then 'arguments' denotes
1221  // that specific parameter value and cannot be used to access the
1222  // parameters, which is why we don't need to allocate an arguments
1223  // object in that case.
1224 
1225  // We are using 'arguments'. Tell the code generator that is needs to
1226  // allocate the arguments object by setting 'arguments_'.
1228 
1229  // In strict mode 'arguments' does not alias formal parameters.
1230  // Therefore in strict mode we allocate parameters as if 'arguments'
1231  // were not used.
1232  uses_nonstrict_arguments = is_classic_mode();
1233  }
1234 
1235  // The same parameter may occur multiple times in the parameters_ list.
1236  // If it does, and if it is not copied into the context object, it must
1237  // receive the highest parameter index for that parameter; thus iteration
1238  // order is relevant!
1239  for (int i = params_.length() - 1; i >= 0; --i) {
1240  Variable* var = params_[i];
1241  ASSERT(var->scope() == this);
1242  if (uses_nonstrict_arguments) {
1243  // Force context allocation of the parameter.
1244  var->ForceContextAllocation();
1245  }
1246 
1247  if (MustAllocate(var)) {
1248  if (MustAllocateInContext(var)) {
1249  ASSERT(var->IsUnallocated() || var->IsContextSlot());
1250  if (var->IsUnallocated()) {
1251  AllocateHeapSlot(var);
1252  }
1253  } else {
1254  ASSERT(var->IsUnallocated() || var->IsParameter());
1255  if (var->IsUnallocated()) {
1257  }
1258  }
1259  }
1260  }
1261 }
1262 
1263 
1265  ASSERT(var->scope() == this);
1266  ASSERT(!var->IsVariable(isolate_->factory()->result_symbol()) ||
1267  !var->IsStackLocal());
1268  if (var->IsUnallocated() && MustAllocate(var)) {
1269  if (MustAllocateInContext(var)) {
1270  AllocateHeapSlot(var);
1271  } else {
1272  AllocateStackSlot(var);
1273  }
1274  }
1275 }
1276 
1277 
1279  // All variables that have no rewrite yet are non-parameter locals.
1280  for (int i = 0; i < temps_.length(); i++) {
1282  }
1283 
1285 
1286  for (VariableMap::Entry* p = variables_.Start();
1287  p != NULL;
1288  p = variables_.Next(p)) {
1289  Variable* var = reinterpret_cast<Variable*>(p->value);
1290  vars.Add(VarAndOrder(var, p->order), zone());
1291  }
1292 
1293  vars.Sort(VarAndOrder::Compare);
1294  int var_count = vars.length();
1295  for (int i = 0; i < var_count; i++) {
1296  AllocateNonParameterLocal(vars[i].var());
1297  }
1298 
1299  // For now, function_ must be allocated at the very end. If it gets
1300  // allocated in the context, it must be the last slot in the context,
1301  // because of the current ScopeInfo implementation (see
1302  // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor).
1303  if (function_ != NULL) {
1305  }
1306 }
1307 
1308 
1310  // Allocate variables for inner scopes.
1311  for (int i = 0; i < inner_scopes_.length(); i++) {
1312  inner_scopes_[i]->AllocateVariablesRecursively();
1313  }
1314 
1315  // If scope is already resolved, we still need to allocate
1316  // variables in inner scopes which might not had been resolved yet.
1317  if (already_resolved()) return;
1318  // The number of slots required for variables.
1319  num_stack_slots_ = 0;
1321 
1322  // Allocate variables for this scope.
1323  // Parameters must be allocated first, if any.
1326 
1327  // Force allocation of a context for this scope if necessary. For a 'with'
1328  // scope and for a function scope that makes an 'eval' call we need a context,
1329  // even if no local variables were statically allocated in the scope.
1330  // Likewise for modules.
1331  bool must_have_context = is_with_scope() || is_module_scope() ||
1332  (is_function_scope() && calls_eval());
1333 
1334  // If we didn't allocate any locals in the local context, then we only
1335  // need the minimal number of slots if we must have a context.
1336  if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) {
1337  num_heap_slots_ = 0;
1338  }
1339 
1340  // Allocation done.
1342 }
1343 
1344 
1346  return num_stack_slots() -
1347  (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0);
1348 }
1349 
1350 
1352  if (num_heap_slots() == 0) return 0;
1354  (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0);
1355 }
1356 
1357 
1360 
1361  if (is_module_scope()) {
1363  ASSERT(scope_info_.is_null());
1364 
1365  // TODO(rossberg): This has to be the initial compilation of this code.
1366  // We currently do not allow recompiling any module definitions.
1367  Handle<ScopeInfo> scope_info = GetScopeInfo();
1368  Factory* factory = info->isolate()->factory();
1369  Handle<Context> context = factory->NewModuleContext(scope_info);
1370  Handle<JSModule> instance = factory->NewJSModule(context, scope_info);
1371  context->set_module(*instance);
1372 
1373  bool ok;
1374  interface_->MakeSingleton(instance, &ok);
1375  ASSERT(ok);
1376  }
1377 
1378  // Allocate nested modules.
1379  for (int i = 0; i < inner_scopes_.length(); i++) {
1380  Scope* inner_scope = inner_scopes_.at(i);
1381  if (inner_scope->is_module_scope()) {
1382  inner_scope->AllocateModules(info);
1383  }
1384  }
1385 }
1386 
1387 
1390 
1391  if (is_module_scope()) {
1392  Handle<JSModule> instance = interface_->Instance();
1393 
1394  // Populate the module instance object.
1395  const PropertyAttributes ro_attr =
1397  const PropertyAttributes rw_attr =
1398  static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM);
1400  !it.done(); it.Advance()) {
1401  if (it.interface()->IsModule()) {
1402  Handle<Object> value = it.interface()->Instance();
1403  ASSERT(!value.is_null());
1405  instance, it.name(), value, ro_attr, kStrictMode);
1406  } else {
1407  Variable* var = LocalLookup(it.name());
1408  ASSERT(var != NULL && var->IsContextSlot());
1409  PropertyAttributes attr = var->is_const_mode() ? ro_attr : rw_attr;
1410  Handle<AccessorInfo> info =
1411  Accessors::MakeModuleExport(it.name(), var->index(), attr);
1412  Handle<Object> result = SetAccessor(instance, info);
1413  ASSERT(!(result.is_null() || result->IsUndefined()));
1414  USE(result);
1415  }
1416  }
1417  USE(JSObject::PreventExtensions(instance));
1418  }
1419 
1420  // Link nested modules.
1421  for (int i = 0; i < inner_scopes_.length(); i++) {
1422  Scope* inner_scope = inner_scopes_.at(i);
1423  if (inner_scope->is_module_scope()) {
1424  inner_scope->LinkModules(info);
1425  }
1426  }
1427 }
1428 
1429 
1430 } } // namespace v8::internal
bool is_global_scope() const
Definition: scopes.h:278
void AllocateTo(Location location, int index)
Definition: variables.h:153
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if expose natives in global object expose gc extension number of stack frames to capture disable builtin natives files print a stack trace if an assertion failure occurs use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations prepare for turning on always opt minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions automatically set the debug break flag when debugger commands are in the queue always cause a debug break before aborting maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print more details following each garbage collection print amount of external allocated memory after each time it is adjusted flush code that we expect not to use again before full gc do incremental marking steps track object counts and memory usage use caching Perform compaction on every full GC Never perform compaction on full GC testing only Compact code space on full incremental collections Default seed for initializing random allows verbose printing trace parsing and preparsing Check icache flushes in ARM and MIPS simulator Stack alingment in bytes in print stack trace when throwing exceptions randomize hashes to avoid predictable hash Fixed seed to use to hash property activate a timer that switches between V8 threads testing_bool_flag float flag Seed used for threading test randomness A filename with extra code to be included in the Print usage including on console Map counters to a file Enable debugger compile events enable GDBJIT interface(disables compacting GC)") DEFINE_bool(gdbjit_full
Scope * DeclarationScope()
Definition: scopes.cc:745
bool scope_contains_with_
Definition: scopes.h:471
static Handle< Object > SetProperty(Handle< JSReceiver > object, Handle< String > key, Handle< Object > value, PropertyAttributes attributes, StrictModeFlag strict_mode)
Definition: objects.cc:1893
Declaration * CheckConflictingVarDeclarations()
Definition: scopes.cc:551
Handle< Context > NewModuleContext(Handle< ScopeInfo > scope_info)
Definition: factory.cc:305
bool scope_calls_eval_
Definition: scopes.h:474
virtual ~VariableMap()
Definition: scopes.cc:64
bool calls_eval() const
Definition: scopes.h:297
JSModule * module()
Definition: contexts.h:321
void PrintF(const char *format,...)
Definition: v8utils.cc:40
void ForceContextAllocation()
Definition: variables.h:101
static String * cast(Object *obj)
Context * previous()
Definition: contexts.h:310
Handle< ScopeInfo > GetScopeInfo()
Definition: scopes.cc:754
void SetScope(Scope *scope)
Definition: compiler.h:106
ZoneList< Scope * > inner_scopes_
Definition: scopes.h:430
Variable * receiver()
Definition: scopes.h:320
bool already_resolved()
Definition: scopes.h:499
bool force_eager_compilation_
Definition: scopes.h:484
VarAndOrder(Variable *var, int order)
Definition: scopes.cc:600
void CollectStackAndContextLocals(ZoneList< Variable * > *stack_locals, ZoneList< Variable * > *context_locals)
Definition: scopes.cc:613
bool outer_scope_calls_non_strict_eval() const
Definition: scopes.h:301
Scope * FinalizeBlockScope()
Definition: scopes.cc:376
Handle< JSArray > NewJSArray(int capacity, ElementsKind elements_kind=TERMINAL_FAST_ELEMENTS_KIND, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:937
Handle< Script > script() const
Definition: compiler.h:72
Variable * arguments_
Definition: scopes.h:459
static bool Analyze(CompilationInfo *info)
Definition: scopes.cc:274
Scope * outer_scope() const
Definition: scopes.h:348
ScopeType type_
Definition: scopes.h:433
bool HasIllegalRedeclaration() const
Definition: scopes.h:214
bool is_identical_to(const Handle< T > other) const
Definition: handles.h:67
ZoneList< VariableProxy * > unresolved_
Definition: scopes.h:451
Expression * illegal_redecl_
Definition: scopes.h:464
void set_local_if_not_shadowed(Variable *local)
Definition: variables.h:142
bool is_classic_mode() const
Definition: scopes.h:286
Bootstrapper * bootstrapper()
Definition: isolate.h:818
Handle< String > scope_name_
Definition: scopes.h:436
Zone * zone() const
Definition: scopes.h:57
void DeclareParameter(Handle< String > name, VariableMode mode)
Definition: scopes.cc:471
Handle< Object > SetAccessor(Handle< JSObject > obj, Handle< AccessorInfo > info)
Definition: handles.cc:342
VariableProxy * CheckAssignmentToConst()
Definition: scopes.cc:575
bool HasTrivialContext() const
Definition: scopes.cc:678
#define ASSERT(condition)
Definition: checks.h:270
v8::Handle< v8::Value > Print(const v8::Arguments &args)
Variable * NewTemporary(Handle< String > name)
Definition: scopes.cc:518
MUST_USE_RESULT MaybeObject * PreventExtensions()
Definition: objects.cc:4143
bool is_const_mode() const
Definition: variables.h:124
Interface * interface() const
Definition: variables.h:151
bool is_this() const
Definition: variables.h:129
VariableMap * GetMap(VariableMode mode)
Definition: scopes.h:75
VariableDeclaration * function_
Definition: scopes.h:457
Variable * LookupRecursive(Handle< String > name, BindingKind *binding_kind, AstNodeFactory< AstNullVisitor > *factory)
Definition: scopes.cc:962
LanguageMode language_mode_
Definition: scopes.h:476
Variable * var() const
Definition: scopes.cc:601
Factory * factory()
Definition: isolate.h:992
PropertyAttributes
Handle< String > name() const
Definition: ast.h:1410
bool outer_scope_calls_non_strict_eval_
Definition: scopes.h:482
void Unify(Interface *that, Zone *zone, bool *ok)
Definition: interface.cc:119
bool is_block_scope() const
Definition: scopes.h:280
Handle< Object > NewSyntaxError(const char *type, Handle< JSArray > args)
Definition: factory.cc:652
Handle< String > name() const
Definition: variables.h:96
static Handle< ScopeInfo > Create(Scope *scope, Zone *zone)
Definition: scopeinfo.cc:41
bool MustAllocateInContext(Variable *var)
Definition: scopes.cc:1169
ZoneList< Declaration * > decls_
Definition: scopes.h:453
Handle< ScopeInfo > scope_info_
Definition: scopes.h:498
void MakeSingleton(Handle< JSModule > instance, bool *ok)
Definition: interface.h:112
int ContextChainLength(Scope *scope)
Definition: scopes.cc:735
static ScopeInfo * cast(Object *object)
bool HasTrivialOuterContext() const
Definition: scopes.cc:692
bool is_dynamic() const
Definition: variables.h:123
Iterator iterator() const
Definition: interface.h:175
bool AllowsLazyCompilation() const
Definition: scopes.cc:725
void DeclareFunctionVar(VariableDeclaration *declaration)
Definition: scopes.h:142
void AllocateNonParameterLocal(Variable *var)
Definition: scopes.cc:1264
static int Compare(const VarAndOrder *a, const VarAndOrder *b)
Definition: scopes.cc:603
T ** location() const
Definition: handles.h:75
void AllocateModules(CompilationInfo *info)
Definition: scopes.cc:1358
int start_position() const
Definition: scopes.h:262
Variable * DeclareLocal(Handle< String > name, VariableMode mode, InitializationFlag init_flag, Interface *interface=Interface::NewValue())
Definition: scopes.cc:480
Variable * var() const
Definition: ast.h:1411
#define UNREACHABLE()
Definition: checks.h:50
VariableProxy * proxy() const
Definition: ast.h:443
void AllocateVariablesRecursively()
Definition: scopes.cc:1309
VariableMode mode() const
Definition: variables.h:97
bool is_eval_scope() const
Definition: scopes.h:275
bool HasArgumentsParameter()
Definition: scopes.cc:1187
Variable * arguments() const
Definition: scopes.h:339
int num_stack_slots() const
Definition: scopes.h:366
Isolate *const isolate_
Definition: scopes.h:426
bool has_forced_context_allocation() const
Definition: variables.h:98
void GetNestedScopeChain(List< Handle< ScopeInfo > > *chain, int statement_position)
Definition: scopes.cc:762
void AllocateHeapSlot(Variable *var)
Definition: scopes.cc:1203
ScopeType type() const
Definition: scopes.h:314
uint32_t occupancy() const
Definition: hashmap.h:83
bool PropagateScopeInfo(bool outer_scope_calls_non_strict_eval)
Definition: scopes.cc:1128
bool calls_non_strict_eval()
Definition: scopes.h:298
Scope * scope() const
Definition: variables.h:94
FunctionLiteral * function() const
Definition: compiler.h:66
void PrintMap(map< string, string > *m)
Definition: process.cc:591
bool is_declaration_scope() const
Definition: scopes.h:282
bool HasLazyCompilableOuterContext() const
Definition: scopes.cc:702
bool inner_scope_calls_eval_
Definition: scopes.h:483
Interface * interface_
Definition: scopes.h:461
Entry * Lookup(void *key, uint32_t hash, bool insert, ZoneAllocationPolicyallocator=ZoneAllocationPolicy())
void AllocateStackSlot(Variable *var)
Definition: scopes.cc:1198
int index() const
Definition: variables.h:147
bool IsLexicalVariableMode(VariableMode mode)
Definition: v8globals.h:521
Variable * receiver_
Definition: scopes.h:455
Scope * global_scope() const
Definition: compiler.h:68
bool IsContextSlot() const
Definition: variables.h:119
static MUST_USE_RESULT Handle< Object > SetElement(Handle< JSObject > object, uint32_t index, Handle< Object > value, PropertyAttributes attr, StrictModeFlag strict_mode, SetPropertyMode set_mode=SET_PROPERTY)
Definition: objects.cc:9886
static const char * Mode2String(VariableMode mode)
Definition: variables.cc:40
bool MustAllocate(Variable *var)
Definition: scopes.cc:1149
Variable * LocalLookup(Handle< String > name)
Definition: scopes.cc:405
bool IsVariable(Handle< String > n) const
Definition: variables.h:111
int end_position() const
Definition: scopes.h:266
bool IsDeclaredVariableMode(VariableMode mode)
Definition: v8globals.h:516
activate correct semantics for inheriting readonliness false
Definition: flags.cc:141
bool IsStackLocal() const
Definition: variables.h:117
ZoneList< Variable * > params_
Definition: scopes.h:447
static Handle< AccessorInfo > MakeModuleExport(Handle< String > name, int index, PropertyAttributes attributes)
Definition: accessors.cc:838
Scope * scope() const
Definition: ast.h:1953
Interface * interface() const
Definition: scopes.h:351
void AllocateParameterLocals()
Definition: scopes.cc:1208
int StackLocalCount() const
Definition: scopes.cc:1345
VariableMap variables_
Definition: scopes.h:443
void AddDeclaration(Declaration *declaration)
Definition: scopes.cc:531
int num_heap_slots() const
Definition: scopes.h:367
void VisitIllegalRedeclaration(AstVisitor *visitor)
Definition: scopes.cc:545
Scope * scope() const
Definition: ast.h:445
bool is_null() const
Definition: handles.h:87
int position() const
Definition: ast.h:1413
int order() const
Definition: scopes.cc:602
bool IsParameter() const
Definition: variables.h:116
bool is_with_scope() const
Definition: scopes.h:281
void AllocateNonParameterLocals()
Definition: scopes.cc:1278
ZoneList< Variable * > temps_
Definition: scopes.h:445
int num_var_or_const()
Definition: scopes.h:363
bool contains_with() const
Definition: scopes.h:308
bool AllowsLazyCompilationWithoutContext() const
Definition: scopes.cc:730
bool IsFunctionContext()
Definition: contexts.h:350
Handle< JSModule > NewJSModule(Handle< Context > context, Handle< ScopeInfo > scope_info)
Definition: factory.cc:912
Zone * zone() const
Definition: scopes.h:120
void LinkModules(CompilationInfo *info)
Definition: scopes.cc:1388
bool IsUnallocated() const
Definition: variables.h:115
Variable * DeclareDynamicGlobal(Handle< String > name)
Definition: scopes.cc:495
Handle< JSModule > Instance()
Definition: interface.h:141
int ContextLocalCount() const
Definition: scopes.cc:1351
Variable * Lookup(Handle< String > name)
Definition: scopes.cc:92
Object * extension()
Definition: contexts.h:318
void BindTo(Variable *var)
Definition: ast.cc:103
void USE(T)
Definition: globals.h:289
void set_is_used(bool flag)
Definition: variables.h:106
MUST_USE_RESULT bool AllocateVariables(CompilationInfo *info, AstNodeFactory< AstNullVisitor > *factory)
Definition: scopes.cc:651
Variable * NonLocal(Handle< String > name, VariableMode mode)
Definition: scopes.cc:941
bool IsGlobalObjectProperty() const
Definition: variables.cc:84
Interface * interface() const
Definition: ast.h:1414
void Add(const T &element, AllocationPolicy allocator=AllocationPolicy())
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
Definition: flags.cc:301
MUST_USE_RESULT bool ResolveVariable(CompilationInfo *info, VariableProxy *proxy, AstNodeFactory< AstNullVisitor > *factory)
Definition: scopes.cc:1017
LanguageMode language_mode() const
Definition: scopes.h:317
DynamicScopePart * dynamics_
Definition: scopes.h:449
JSFunction * closure()
Definition: contexts.h:307
bool is_function_scope() const
Definition: scopes.h:276
Variable * Lookup(Handle< String > name)
Definition: scopes.cc:460
virtual void Accept(AstVisitor *v)=0
VariableMode mode() const
Definition: ast.h:444
VariableMap(Zone *zone)
Definition: scopes.cc:61
Variable * Declare(Scope *scope, Handle< String > name, VariableMode mode, bool is_valid_lhs, Variable::Kind kind, InitializationFlag initialization_flag, Interface *interface=Interface::NewValue())
Definition: scopes.cc:67
void RecordWithStatement()
Definition: scopes.h:230
bool is_module_scope() const
Definition: scopes.h:277
bool is_catch_scope() const
Definition: scopes.h:279
bool is_extended_mode() const
Definition: scopes.h:289
static Scope * DeserializeScopeChain(Context *context, Scope *global_scope, Zone *zone)
Definition: scopes.cc:210
Scope(Scope *outer_scope, ScopeType type, Zone *zone)
Definition: scopes.cc:107
Scope * outer_scope_
Definition: scopes.h:429
void RemoveUnresolved(VariableProxy *var)
Definition: scopes.cc:506
Entry * Next(Entry *p) const
Definition: hashmap.h:243
Variable * LookupFunctionVar(Handle< String > name, AstNodeFactory< AstNullVisitor > *factory)
Definition: scopes.cc:436
bool scope_inside_with_
Definition: scopes.h:469
MUST_USE_RESULT bool ResolveVariablesRecursively(CompilationInfo *info, AstNodeFactory< AstNullVisitor > *factory)
Definition: scopes.cc:1108
void SetIllegalRedeclaration(Expression *expression)
Definition: scopes.cc:536