OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 22 matching lines...) Expand all Loading... | |
33 | 33 |
34 namespace v8 { | 34 namespace v8 { |
35 namespace internal { | 35 namespace internal { |
36 | 36 |
37 class CompilationInfo; | 37 class CompilationInfo; |
38 | 38 |
39 | 39 |
40 // A hash map to support fast variable declaration and lookup. | 40 // A hash map to support fast variable declaration and lookup. |
41 class VariableMap: public ZoneHashMap { | 41 class VariableMap: public ZoneHashMap { |
42 public: | 42 public: |
43 VariableMap(); | 43 explicit VariableMap(Zone* zone); |
danno
2012/06/05 13:42:35
Seems weird that you have to pass this into the co
sanjoy
2012/06/05 14:21:39
I figured not adding a member will save some space
danno
2012/06/06 10:59:53
This is probably cleaner still if the zone is stor
| |
44 | 44 |
45 virtual ~VariableMap(); | 45 virtual ~VariableMap(); |
46 | 46 |
47 Variable* Declare(Scope* scope, | 47 Variable* Declare(Scope* scope, |
48 Handle<String> name, | 48 Handle<String> name, |
49 VariableMode mode, | 49 VariableMode mode, |
50 bool is_valid_lhs, | 50 bool is_valid_lhs, |
51 Variable::Kind kind, | 51 Variable::Kind kind, |
52 InitializationFlag initialization_flag, | 52 InitializationFlag initialization_flag, |
53 Zone* zone, | |
53 Interface* interface = Interface::NewValue()); | 54 Interface* interface = Interface::NewValue()); |
54 | 55 |
55 Variable* Lookup(Handle<String> name); | 56 Variable* Lookup(Handle<String> name); |
56 }; | 57 }; |
57 | 58 |
58 | 59 |
59 // The dynamic scope part holds hash maps for the variables that will | 60 // The dynamic scope part holds hash maps for the variables that will |
60 // be looked up dynamically from within eval and with scopes. The objects | 61 // be looked up dynamically from within eval and with scopes. The objects |
61 // are allocated on-demand from Scope::NonLocal to avoid wasting memory | 62 // are allocated on-demand from Scope::NonLocal to avoid wasting memory |
62 // and setup time for scopes that don't need them. | 63 // and setup time for scopes that don't need them. |
63 class DynamicScopePart : public ZoneObject { | 64 class DynamicScopePart : public ZoneObject { |
64 public: | 65 public: |
66 explicit DynamicScopePart(Zone* zone) { | |
67 for (int i = 0; i < 3; i++) | |
68 maps_[i] = new VariableMap(zone); | |
69 } | |
70 | |
65 VariableMap* GetMap(VariableMode mode) { | 71 VariableMap* GetMap(VariableMode mode) { |
66 int index = mode - DYNAMIC; | 72 int index = mode - DYNAMIC; |
67 ASSERT(index >= 0 && index < 3); | 73 ASSERT(index >= 0 && index < 3); |
68 return &maps_[index]; | 74 return maps_[index]; |
75 } | |
76 | |
77 ~DynamicScopePart() { | |
78 for (int i = 0; i < 3; i++) | |
79 delete maps_[i]; | |
69 } | 80 } |
70 | 81 |
71 private: | 82 private: |
72 VariableMap maps_[3]; | 83 VariableMap *maps_[3]; |
73 }; | 84 }; |
74 | 85 |
75 | 86 |
76 // Global invariants after AST construction: Each reference (i.e. identifier) | 87 // Global invariants after AST construction: Each reference (i.e. identifier) |
77 // to a JavaScript variable (including global properties) is represented by a | 88 // to a JavaScript variable (including global properties) is represented by a |
78 // VariableProxy node. Immediately after AST construction and before variable | 89 // VariableProxy node. Immediately after AST construction and before variable |
79 // allocation, most VariableProxy nodes are "unresolved", i.e. not bound to a | 90 // allocation, most VariableProxy nodes are "unresolved", i.e. not bound to a |
80 // corresponding variable (though some are bound during parse time). Variable | 91 // corresponding variable (though some are bound during parse time). Variable |
81 // allocation binds each unresolved VariableProxy to one Variable and assigns | 92 // allocation binds each unresolved VariableProxy to one Variable and assigns |
82 // a location. Note that many VariableProxy nodes may refer to the same Java- | 93 // a location. Note that many VariableProxy nodes may refer to the same Java- |
83 // Script variable. | 94 // Script variable. |
84 | 95 |
85 class Scope: public ZoneObject { | 96 class Scope: public ZoneObject { |
86 public: | 97 public: |
87 // --------------------------------------------------------------------------- | 98 // --------------------------------------------------------------------------- |
88 // Construction | 99 // Construction |
89 | 100 |
90 Scope(Scope* outer_scope, ScopeType type); | 101 Scope(Scope* outer_scope, ScopeType type, Zone* zone); |
91 | 102 |
92 // Compute top scope and allocate variables. For lazy compilation the top | 103 // Compute top scope and allocate variables. For lazy compilation the top |
93 // scope only contains the single lazily compiled function, so this | 104 // scope only contains the single lazily compiled function, so this |
94 // doesn't re-allocate variables repeatedly. | 105 // doesn't re-allocate variables repeatedly. |
95 static bool Analyze(CompilationInfo* info); | 106 static bool Analyze(CompilationInfo* info); |
96 | 107 |
97 static Scope* DeserializeScopeChain(Context* context, Scope* global_scope); | 108 static Scope* DeserializeScopeChain(Context* context, Scope* global_scope, |
109 Zone* zone); | |
98 | 110 |
99 // The scope name is only used for printing/debugging. | 111 // The scope name is only used for printing/debugging. |
100 void SetScopeName(Handle<String> scope_name) { scope_name_ = scope_name; } | 112 void SetScopeName(Handle<String> scope_name) { scope_name_ = scope_name; } |
101 | 113 |
102 void Initialize(); | 114 void Initialize(); |
103 | 115 |
104 // Checks if the block scope is redundant, i.e. it does not contain any | 116 // Checks if the block scope is redundant, i.e. it does not contain any |
105 // block scoped declarations. In that case it is removed from the scope | 117 // block scoped declarations. In that case it is removed from the scope |
106 // tree and its children are reparented. | 118 // tree and its children are reparented. |
107 Scope* FinalizeBlockScope(); | 119 Scope* FinalizeBlockScope(); |
108 | 120 |
121 Zone* zone() const { return zone_; } | |
122 | |
109 // --------------------------------------------------------------------------- | 123 // --------------------------------------------------------------------------- |
110 // Declarations | 124 // Declarations |
111 | 125 |
112 // Lookup a variable in this scope. Returns the variable or NULL if not found. | 126 // Lookup a variable in this scope. Returns the variable or NULL if not found. |
113 Variable* LocalLookup(Handle<String> name); | 127 Variable* LocalLookup(Handle<String> name); |
114 | 128 |
115 // This lookup corresponds to a lookup in the "intermediate" scope sitting | 129 // This lookup corresponds to a lookup in the "intermediate" scope sitting |
116 // between this scope and the outer scope. (ECMA-262, 3rd., requires that | 130 // between this scope and the outer scope. (ECMA-262, 3rd., requires that |
117 // the name of named function literal is kept in an intermediate scope | 131 // the name of named function literal is kept in an intermediate scope |
118 // in between this scope and the next outer scope.) | 132 // in between this scope and the next outer scope.) |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
154 VariableProxy* NewUnresolved(AstNodeFactory<Visitor>* factory, | 168 VariableProxy* NewUnresolved(AstNodeFactory<Visitor>* factory, |
155 Handle<String> name, | 169 Handle<String> name, |
156 int position = RelocInfo::kNoPosition, | 170 int position = RelocInfo::kNoPosition, |
157 Interface* interface = Interface::NewValue()) { | 171 Interface* interface = Interface::NewValue()) { |
158 // Note that we must not share the unresolved variables with | 172 // Note that we must not share the unresolved variables with |
159 // the same name because they may be removed selectively via | 173 // the same name because they may be removed selectively via |
160 // RemoveUnresolved(). | 174 // RemoveUnresolved(). |
161 ASSERT(!already_resolved()); | 175 ASSERT(!already_resolved()); |
162 VariableProxy* proxy = | 176 VariableProxy* proxy = |
163 factory->NewVariableProxy(name, false, position, interface); | 177 factory->NewVariableProxy(name, false, position, interface); |
164 unresolved_.Add(proxy); | 178 unresolved_.Add(proxy, zone_); |
165 return proxy; | 179 return proxy; |
166 } | 180 } |
167 | 181 |
168 // Remove a unresolved variable. During parsing, an unresolved variable | 182 // Remove a unresolved variable. During parsing, an unresolved variable |
169 // may have been added optimistically, but then only the variable name | 183 // may have been added optimistically, but then only the variable name |
170 // was used (typically for labels). If the variable was not declared, the | 184 // was used (typically for labels). If the variable was not declared, the |
171 // addition introduced a new unresolved variable which may end up being | 185 // addition introduced a new unresolved variable which may end up being |
172 // allocated globally as a "ghost" variable. RemoveUnresolved removes | 186 // allocated globally as a "ghost" variable. RemoveUnresolved removes |
173 // such a variable again if it was added; otherwise this is a no-op. | 187 // such a variable again if it was added; otherwise this is a no-op. |
174 void RemoveUnresolved(VariableProxy* var); | 188 void RemoveUnresolved(VariableProxy* var); |
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
574 // | 588 // |
575 // In the case of code compiled and run using 'eval', the context | 589 // In the case of code compiled and run using 'eval', the context |
576 // parameter is the context in which eval was called. In all other | 590 // parameter is the context in which eval was called. In all other |
577 // cases the context parameter is an empty handle. | 591 // cases the context parameter is an empty handle. |
578 MUST_USE_RESULT | 592 MUST_USE_RESULT |
579 bool AllocateVariables(CompilationInfo* info, | 593 bool AllocateVariables(CompilationInfo* info, |
580 AstNodeFactory<AstNullVisitor>* factory); | 594 AstNodeFactory<AstNullVisitor>* factory); |
581 | 595 |
582 private: | 596 private: |
583 // Construct a scope based on the scope info. | 597 // Construct a scope based on the scope info. |
584 Scope(Scope* inner_scope, ScopeType type, Handle<ScopeInfo> scope_info); | 598 Scope(Scope* inner_scope, ScopeType type, Handle<ScopeInfo> scope_info, |
599 Zone* zone); | |
585 | 600 |
586 // Construct a catch scope with a binding for the name. | 601 // Construct a catch scope with a binding for the name. |
587 Scope(Scope* inner_scope, Handle<String> catch_variable_name); | 602 Scope(Scope* inner_scope, Handle<String> catch_variable_name, Zone* zone); |
588 | 603 |
589 void AddInnerScope(Scope* inner_scope) { | 604 void AddInnerScope(Scope* inner_scope) { |
590 if (inner_scope != NULL) { | 605 if (inner_scope != NULL) { |
591 inner_scopes_.Add(inner_scope); | 606 inner_scopes_.Add(inner_scope, zone_); |
592 inner_scope->outer_scope_ = this; | 607 inner_scope->outer_scope_ = this; |
593 } | 608 } |
594 } | 609 } |
595 | 610 |
596 void SetDefaults(ScopeType type, | 611 void SetDefaults(ScopeType type, |
597 Scope* outer_scope, | 612 Scope* outer_scope, |
598 Handle<ScopeInfo> scope_info); | 613 Handle<ScopeInfo> scope_info); |
614 | |
615 Zone* zone_; | |
599 }; | 616 }; |
600 | 617 |
601 } } // namespace v8::internal | 618 } } // namespace v8::internal |
602 | 619 |
603 #endif // V8_SCOPES_H_ | 620 #endif // V8_SCOPES_H_ |
OLD | NEW |