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

Side by Side Diff: src/ast/scopes.cc

Issue 2209573002: Separate Scope into DeclarationScope and Scope (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressed adamks comments Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ast/scopes.h ('k') | src/compiler.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/ast/scopes.h" 5 #include "src/ast/scopes.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/bootstrapper.h" 8 #include "src/bootstrapper.h"
9 #include "src/messages.h" 9 #include "src/messages.h"
10 #include "src/parsing/parser.h" // for ParseInfo 10 #include "src/parsing/parser.h" // for ParseInfo
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 p->value = new (zone_->New(sizeof(Vector))) Vector(zone_); 74 p->value = new (zone_->New(sizeof(Vector))) Vector(zone_);
75 } 75 }
76 Vector* delegates = static_cast<Vector*>(p->value); 76 Vector* delegates = static_cast<Vector*>(p->value);
77 delegates->push_back(stmt); 77 delegates->push_back(stmt);
78 } 78 }
79 79
80 80
81 // ---------------------------------------------------------------------------- 81 // ----------------------------------------------------------------------------
82 // Implementation of Scope 82 // Implementation of Scope
83 83
84 Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type, 84 Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type)
85 FunctionKind function_kind)
86 : outer_scope_(outer_scope), 85 : outer_scope_(outer_scope),
87 variables_(zone), 86 variables_(zone),
88 temps_(4, zone),
89 params_(4, zone),
90 decls_(4, zone), 87 decls_(4, zone),
91 module_descriptor_(scope_type == MODULE_SCOPE ? new (zone)
92 ModuleDescriptor(zone)
93 : NULL),
94 sloppy_block_function_map_(zone),
95 scope_type_(scope_type), 88 scope_type_(scope_type),
96 function_kind_(function_kind),
97 already_resolved_(false) { 89 already_resolved_(false) {
98 SetDefaults(); 90 SetDefaults();
99 if (outer_scope == nullptr) { 91 if (outer_scope == nullptr) {
100 // If the outer scope is null, this cannot be a with scope. The outermost 92 // If the outer scope is null, this cannot be a with scope. The outermost
101 // scope must be a script scope. 93 // scope must be a script scope.
102 DCHECK_EQ(SCRIPT_SCOPE, scope_type); 94 DCHECK_EQ(SCRIPT_SCOPE, scope_type);
103 } else { 95 } else {
104 asm_function_ = outer_scope_->asm_module_; 96 asm_function_ = outer_scope_->asm_module_;
105 // Inherit the language mode from the parent scope unless we're a module 97 // Inherit the language mode from the parent scope unless we're a module
106 // scope. 98 // scope.
107 if (!is_module_scope()) language_mode_ = outer_scope->language_mode_; 99 if (!is_module_scope()) language_mode_ = outer_scope->language_mode_;
108 force_context_allocation_ = 100 force_context_allocation_ =
109 !is_function_scope() && outer_scope->has_forced_context_allocation(); 101 !is_function_scope() && outer_scope->has_forced_context_allocation();
110 outer_scope_->AddInnerScope(this); 102 outer_scope_->AddInnerScope(this);
111 scope_inside_with_ = outer_scope_->scope_inside_with_ || is_with_scope(); 103 scope_inside_with_ = outer_scope_->scope_inside_with_ || is_with_scope();
112 } 104 }
113 } 105 }
114 106
107 Scope::Snapshot::Snapshot(Scope* scope)
108 : outer_scope_(scope),
109 top_inner_scope_(scope->inner_scope_),
110 top_unresolved_(scope->unresolved_),
111 top_temp_(scope->GetClosureScope()->temps()->length()) {}
112
113 DeclarationScope::DeclarationScope(Zone* zone, Scope* outer_scope,
114 ScopeType scope_type,
115 FunctionKind function_kind)
116 : Scope(zone, outer_scope, scope_type),
117 function_kind_(function_kind),
118 temps_(4, zone),
119 params_(4, zone),
120 sloppy_block_function_map_(zone),
121 module_descriptor_(scope_type == MODULE_SCOPE ? new (zone)
122 ModuleDescriptor(zone)
123 : NULL) {
124 SetDefaults();
125 }
126
115 Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type, 127 Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type,
116 Handle<ScopeInfo> scope_info) 128 Handle<ScopeInfo> scope_info)
117 : outer_scope_(nullptr), 129 : outer_scope_(nullptr),
118 variables_(zone), 130 variables_(zone),
119 temps_(4, zone),
120 params_(4, zone),
121 decls_(4, zone), 131 decls_(4, zone),
122 module_descriptor_(nullptr),
123 sloppy_block_function_map_(zone),
124 scope_type_(scope_type), 132 scope_type_(scope_type),
125 function_kind_(scope_info.is_null() ? kNormalFunction
126 : scope_info->function_kind()),
127 already_resolved_(true), 133 already_resolved_(true),
128 scope_info_(scope_info) { 134 scope_info_(scope_info) {
129 SetDefaults(); 135 SetDefaults();
130 if (!scope_info.is_null()) { 136 if (!scope_info.is_null()) {
131 scope_calls_eval_ = scope_info->CallsEval(); 137 scope_calls_eval_ = scope_info->CallsEval();
132 language_mode_ = scope_info->language_mode(); 138 language_mode_ = scope_info->language_mode();
133 is_declaration_scope_ = scope_info->is_declaration_scope();
134 num_heap_slots_ = scope_info_->ContextLength(); 139 num_heap_slots_ = scope_info_->ContextLength();
135 } 140 }
136 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context. 141 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context.
137 num_heap_slots_ = Max(num_heap_slots_, 142 num_heap_slots_ = Max(num_heap_slots_,
138 static_cast<int>(Context::MIN_CONTEXT_SLOTS)); 143 static_cast<int>(Context::MIN_CONTEXT_SLOTS));
139 AddInnerScope(inner_scope); 144 AddInnerScope(inner_scope);
140 } 145 }
141 146
147 DeclarationScope::DeclarationScope(Zone* zone, Scope* inner_scope,
148 ScopeType scope_type,
149 Handle<ScopeInfo> scope_info)
150 : Scope(zone, inner_scope, scope_type, scope_info),
151 function_kind_(scope_info.is_null() ? kNormalFunction
152 : scope_info->function_kind()),
153 temps_(4, zone),
154 params_(4, zone),
155 sloppy_block_function_map_(zone),
156 module_descriptor_(nullptr) {
157 SetDefaults();
158 }
159
142 Scope::Scope(Zone* zone, Scope* inner_scope, 160 Scope::Scope(Zone* zone, Scope* inner_scope,
143 const AstRawString* catch_variable_name) 161 const AstRawString* catch_variable_name)
144 : outer_scope_(nullptr), 162 : outer_scope_(nullptr),
145 variables_(zone), 163 variables_(zone),
146 temps_(0, zone),
147 params_(0, zone),
148 decls_(0, zone), 164 decls_(0, zone),
149 module_descriptor_(nullptr),
150 sloppy_block_function_map_(zone),
151 scope_type_(CATCH_SCOPE), 165 scope_type_(CATCH_SCOPE),
152 function_kind_(kNormalFunction),
153 already_resolved_(true) { 166 already_resolved_(true) {
154 SetDefaults(); 167 SetDefaults();
155 AddInnerScope(inner_scope); 168 AddInnerScope(inner_scope);
156 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; 169 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
157 Variable* variable = variables_.Declare(this, 170 Variable* variable = variables_.Declare(this,
158 catch_variable_name, 171 catch_variable_name,
159 VAR, 172 VAR,
160 Variable::NORMAL, 173 Variable::NORMAL,
161 kCreatedInitialized); 174 kCreatedInitialized);
162 AllocateHeapSlot(variable); 175 AllocateHeapSlot(variable);
163 } 176 }
164 177
165 void Scope::SetDefaults() { 178 void DeclarationScope::SetDefaults() {
166 is_declaration_scope_ = 179 is_declaration_scope_ = true;
167 is_eval_scope() || is_function_scope() ||
168 is_module_scope() || is_script_scope();
169 inner_scope_ = nullptr;
170 sibling_ = nullptr;
171 unresolved_ = nullptr;
172 #ifdef DEBUG
173 scope_name_ = nullptr;
174 #endif
175 dynamics_ = nullptr;
176 receiver_ = nullptr; 180 receiver_ = nullptr;
177 new_target_ = nullptr; 181 new_target_ = nullptr;
178 function_ = nullptr; 182 function_ = nullptr;
179 arguments_ = nullptr; 183 arguments_ = nullptr;
180 this_function_ = nullptr; 184 this_function_ = nullptr;
185 arity_ = 0;
186 has_simple_parameters_ = true;
187 rest_parameter_ = NULL;
188 rest_index_ = -1;
189 }
190
191 void Scope::SetDefaults() {
192 #ifdef DEBUG
193 scope_name_ = nullptr;
194 #endif
195 is_declaration_scope_ = false;
196 inner_scope_ = nullptr;
197 sibling_ = nullptr;
198 unresolved_ = nullptr;
199 dynamics_ = nullptr;
181 scope_inside_with_ = false; 200 scope_inside_with_ = false;
182 scope_calls_eval_ = false; 201 scope_calls_eval_ = false;
183 has_arguments_parameter_ = false; 202 has_arguments_parameter_ = false;
184 scope_uses_super_property_ = false; 203 scope_uses_super_property_ = false;
185 asm_module_ = false; 204 asm_module_ = false;
186 asm_function_ = false; 205 asm_function_ = false;
187 language_mode_ = is_module_scope() ? STRICT : SLOPPY; 206 language_mode_ = is_module_scope() ? STRICT : SLOPPY;
188 outer_scope_calls_sloppy_eval_ = false; 207 outer_scope_calls_sloppy_eval_ = false;
189 inner_scope_calls_eval_ = false; 208 inner_scope_calls_eval_ = false;
190 scope_nonlinear_ = false; 209 scope_nonlinear_ = false;
191 force_eager_compilation_ = false; 210 force_eager_compilation_ = false;
192 force_context_allocation_ = false; 211 force_context_allocation_ = false;
193 num_stack_slots_ = 0; 212 num_stack_slots_ = 0;
194 num_heap_slots_ = 0; 213 num_heap_slots_ = 0;
195 num_global_slots_ = 0; 214 num_global_slots_ = 0;
196 arity_ = 0;
197 has_simple_parameters_ = true;
198 rest_parameter_ = NULL;
199 rest_index_ = -1;
200 start_position_ = kNoSourcePosition; 215 start_position_ = kNoSourcePosition;
201 end_position_ = kNoSourcePosition; 216 end_position_ = kNoSourcePosition;
202 is_hidden_ = false; 217 is_hidden_ = false;
203 } 218 }
204 219
220 bool Scope::HasSimpleParameters() {
221 DeclarationScope* scope = GetClosureScope();
222 return !scope->is_function_scope() || scope->has_simple_parameters();
223 }
224
205 Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, 225 Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone,
206 Context* context, Scope* script_scope, 226 Context* context, Scope* script_scope,
207 AstValueFactory* ast_value_factory) { 227 AstValueFactory* ast_value_factory) {
208 // Reconstruct the outer scope chain from a closure's context chain. 228 // Reconstruct the outer scope chain from a closure's context chain.
209 Scope* current_scope = NULL; 229 Scope* current_scope = NULL;
210 Scope* innermost_scope = NULL; 230 Scope* innermost_scope = NULL;
211 while (!context->IsNativeContext()) { 231 while (!context->IsNativeContext()) {
212 if (context->IsWithContext() || context->IsDebugEvaluateContext()) { 232 if (context->IsWithContext() || context->IsDebugEvaluateContext()) {
213 // For scope analysis, debug-evaluate is equivalent to a with scope. 233 // For scope analysis, debug-evaluate is equivalent to a with scope.
214 Scope* with_scope = new (zone) 234 Scope* with_scope = new (zone)
215 Scope(zone, current_scope, WITH_SCOPE, Handle<ScopeInfo>::null()); 235 Scope(zone, current_scope, WITH_SCOPE, Handle<ScopeInfo>::null());
216 current_scope = with_scope; 236 current_scope = with_scope;
217 // All the inner scopes are inside a with. 237 // All the inner scopes are inside a with.
218 for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) { 238 for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) {
219 s->scope_inside_with_ = true; 239 s->scope_inside_with_ = true;
220 } 240 }
221 } else if (context->IsScriptContext()) { 241 } else if (context->IsScriptContext()) {
222 ScopeInfo* scope_info = context->scope_info(); 242 ScopeInfo* scope_info = context->scope_info();
223 current_scope = new (zone) Scope(zone, current_scope, SCRIPT_SCOPE, 243 current_scope = new (zone) DeclarationScope(
224 Handle<ScopeInfo>(scope_info)); 244 zone, current_scope, SCRIPT_SCOPE, Handle<ScopeInfo>(scope_info));
225 } else if (context->IsFunctionContext()) { 245 } else if (context->IsFunctionContext()) {
226 ScopeInfo* scope_info = context->closure()->shared()->scope_info(); 246 ScopeInfo* scope_info = context->closure()->shared()->scope_info();
227 current_scope = new (zone) Scope(zone, current_scope, FUNCTION_SCOPE, 247 current_scope = new (zone) DeclarationScope(
228 Handle<ScopeInfo>(scope_info)); 248 zone, current_scope, FUNCTION_SCOPE, Handle<ScopeInfo>(scope_info));
229 if (scope_info->IsAsmFunction()) current_scope->asm_function_ = true; 249 if (scope_info->IsAsmFunction()) current_scope->asm_function_ = true;
230 if (scope_info->IsAsmModule()) current_scope->asm_module_ = true; 250 if (scope_info->IsAsmModule()) current_scope->asm_module_ = true;
231 } else if (context->IsBlockContext()) { 251 } else if (context->IsBlockContext()) {
232 ScopeInfo* scope_info = context->scope_info(); 252 ScopeInfo* scope_info = context->scope_info();
233 current_scope = new (zone) Scope(zone, current_scope, BLOCK_SCOPE, 253 if (scope_info->is_declaration_scope()) {
234 Handle<ScopeInfo>(scope_info)); 254 current_scope = new (zone) DeclarationScope(
255 zone, current_scope, BLOCK_SCOPE, Handle<ScopeInfo>(scope_info));
256 } else {
257 current_scope = new (zone) Scope(zone, current_scope, BLOCK_SCOPE,
258 Handle<ScopeInfo>(scope_info));
259 }
235 } else { 260 } else {
236 DCHECK(context->IsCatchContext()); 261 DCHECK(context->IsCatchContext());
237 String* name = context->catch_name(); 262 String* name = context->catch_name();
238 current_scope = 263 current_scope =
239 new (zone) Scope(zone, current_scope, 264 new (zone) Scope(zone, current_scope,
240 ast_value_factory->GetString(handle(name, isolate))); 265 ast_value_factory->GetString(handle(name, isolate)));
241 } 266 }
242 if (innermost_scope == NULL) innermost_scope = current_scope; 267 if (innermost_scope == NULL) innermost_scope = current_scope;
243 context = context->previous(); 268 context = context->previous();
244 } 269 }
245 270
246 script_scope->AddInnerScope(current_scope); 271 script_scope->AddInnerScope(current_scope);
247 script_scope->PropagateScopeInfo(false); 272 script_scope->PropagateScopeInfo(false);
248 return (innermost_scope == NULL) ? script_scope : innermost_scope; 273 return (innermost_scope == NULL) ? script_scope : innermost_scope;
249 } 274 }
250 275
276 DeclarationScope* Scope::AsDeclarationScope() {
277 DCHECK(is_declaration_scope());
278 return static_cast<DeclarationScope*>(this);
279 }
280
281 const DeclarationScope* Scope::AsDeclarationScope() const {
282 DCHECK(is_declaration_scope());
283 return static_cast<const DeclarationScope*>(this);
284 }
285
286 int Scope::num_parameters() const {
287 return is_declaration_scope() ? AsDeclarationScope()->num_parameters() : 0;
288 }
251 289
252 bool Scope::Analyze(ParseInfo* info) { 290 bool Scope::Analyze(ParseInfo* info) {
253 DCHECK(info->literal() != NULL); 291 DCHECK(info->literal() != NULL);
254 DCHECK(info->scope() == NULL); 292 DCHECK(info->scope() == NULL);
255 Scope* scope = info->literal()->scope(); 293 DeclarationScope* scope = info->literal()->scope();
256 Scope* top = scope; 294 DeclarationScope* top = scope;
257 295
258 // Traverse the scope tree up to the first unresolved scope or the global 296 // Traverse the scope tree up to the first unresolved scope or the global
259 // scope and start scope resolution and variable allocation from that scope. 297 // scope and start scope resolution and variable allocation from that scope.
298 // Such a scope is always a closure-scope, so always skip to the next closure
299 // scope.
260 while (!top->is_script_scope() && 300 while (!top->is_script_scope() &&
261 !top->outer_scope()->already_resolved()) { 301 !top->outer_scope()->already_resolved()) {
262 top = top->outer_scope(); 302 top = top->outer_scope()->GetClosureScope();
263 } 303 }
264 304
265 // Allocate the variables. 305 // Allocate the variables.
266 { 306 {
267 AstNodeFactory ast_node_factory(info->ast_value_factory()); 307 AstNodeFactory ast_node_factory(info->ast_value_factory());
268 if (!top->AllocateVariables(info, &ast_node_factory)) { 308 if (!top->AllocateVariables(info, &ast_node_factory)) {
269 DCHECK(top->pending_error_handler_.has_pending_error()); 309 DCHECK(top->pending_error_handler_.has_pending_error());
270 top->pending_error_handler_.ThrowPendingError(info->isolate(), 310 top->pending_error_handler_.ThrowPendingError(info->isolate(),
271 info->script()); 311 info->script());
272 return false; 312 return false;
273 } 313 }
274 } 314 }
275 315
276 #ifdef DEBUG 316 #ifdef DEBUG
277 if (info->script_is_native() ? FLAG_print_builtin_scopes 317 if (info->script_is_native() ? FLAG_print_builtin_scopes
278 : FLAG_print_scopes) { 318 : FLAG_print_scopes) {
279 scope->Print(); 319 scope->Print();
280 } 320 }
281 scope->CheckScopePositions(); 321 scope->CheckScopePositions();
282 scope->CheckZones(); 322 scope->CheckZones();
283 #endif 323 #endif
284 324
285 info->set_scope(scope); 325 info->set_scope(scope);
286 return true; 326 return true;
287 } 327 }
288 328
289 void Scope::DeclareThis(AstValueFactory* ast_value_factory) { 329 void DeclarationScope::DeclareThis(AstValueFactory* ast_value_factory) {
290 DCHECK(!already_resolved()); 330 DCHECK(!already_resolved());
291 DCHECK(is_declaration_scope()); 331 DCHECK(is_declaration_scope());
292 DCHECK(has_this_declaration()); 332 DCHECK(has_this_declaration());
293 333
294 bool subclass_constructor = IsSubclassConstructor(function_kind_); 334 bool subclass_constructor = IsSubclassConstructor(function_kind_);
295 Variable* var = variables_.Declare( 335 Variable* var = variables_.Declare(
296 this, ast_value_factory->this_string(), 336 this, ast_value_factory->this_string(),
297 subclass_constructor ? CONST : VAR, Variable::THIS, 337 subclass_constructor ? CONST : VAR, Variable::THIS,
298 subclass_constructor ? kNeedsInitialization : kCreatedInitialized); 338 subclass_constructor ? kNeedsInitialization : kCreatedInitialized);
299 receiver_ = var; 339 receiver_ = var;
300 } 340 }
301 341
302 void Scope::DeclareDefaultFunctionVariables( 342 void DeclarationScope::DeclareDefaultFunctionVariables(
303 AstValueFactory* ast_value_factory) { 343 AstValueFactory* ast_value_factory) {
304 DCHECK(is_function_scope()); 344 DCHECK(is_function_scope());
305 DCHECK(!is_arrow_scope()); 345 DCHECK(!is_arrow_scope());
306 // Declare 'arguments' variable which exists in all non arrow functions. 346 // Declare 'arguments' variable which exists in all non arrow functions.
307 // Note that it might never be accessed, in which case it won't be 347 // Note that it might never be accessed, in which case it won't be
308 // allocated during variable allocation. 348 // allocated during variable allocation.
309 arguments_ = 349 arguments_ =
310 variables_.Declare(this, ast_value_factory->arguments_string(), VAR, 350 variables_.Declare(this, ast_value_factory->arguments_string(), VAR,
311 Variable::ARGUMENTS, kCreatedInitialized); 351 Variable::ARGUMENTS, kCreatedInitialized);
312 352
313 new_target_ = 353 new_target_ =
314 variables_.Declare(this, ast_value_factory->new_target_string(), CONST, 354 variables_.Declare(this, ast_value_factory->new_target_string(), CONST,
315 Variable::NORMAL, kCreatedInitialized); 355 Variable::NORMAL, kCreatedInitialized);
316 356
317 if (IsConciseMethod(function_kind_) || IsClassConstructor(function_kind_) || 357 if (IsConciseMethod(function_kind_) || IsClassConstructor(function_kind_) ||
318 IsAccessorFunction(function_kind_)) { 358 IsAccessorFunction(function_kind_)) {
319 this_function_ = 359 this_function_ =
320 variables_.Declare(this, ast_value_factory->this_function_string(), 360 variables_.Declare(this, ast_value_factory->this_function_string(),
321 CONST, Variable::NORMAL, kCreatedInitialized); 361 CONST, Variable::NORMAL, kCreatedInitialized);
322 } 362 }
323 } 363 }
324 364
325 365
326 Scope* Scope::FinalizeBlockScope() { 366 Scope* Scope::FinalizeBlockScope() {
327 DCHECK(is_block_scope()); 367 DCHECK(is_block_scope());
328 DCHECK(temps_.is_empty());
329 DCHECK(params_.is_empty());
330 368
331 if (variables_.occupancy() > 0 || 369 if (variables_.occupancy() > 0 ||
332 (is_declaration_scope() && calls_sloppy_eval())) { 370 (is_declaration_scope() && calls_sloppy_eval())) {
333 return this; 371 return this;
334 } 372 }
335 373
336 // Remove this scope from outer scope. 374 // Remove this scope from outer scope.
337 outer_scope()->RemoveInnerScope(this); 375 outer_scope()->RemoveInnerScope(this);
338 376
339 // Reparent inner scopes. 377 // Reparent inner scopes.
(...skipping 20 matching lines...) Expand all
360 } 398 }
361 outer_scope()->unresolved_ = unresolved_; 399 outer_scope()->unresolved_ = unresolved_;
362 unresolved_ = nullptr; 400 unresolved_ = nullptr;
363 } 401 }
364 402
365 PropagateUsageFlagsToScope(outer_scope_); 403 PropagateUsageFlagsToScope(outer_scope_);
366 404
367 return NULL; 405 return NULL;
368 } 406 }
369 407
370 void Scope::Snapshot::Reparent(Scope* new_parent) const { 408 void Scope::Snapshot::Reparent(DeclarationScope* new_parent) const {
371 DCHECK_EQ(new_parent, outer_scope_->inner_scope_); 409 DCHECK_EQ(new_parent, outer_scope_->inner_scope_);
372 DCHECK_EQ(new_parent->outer_scope_, outer_scope_); 410 DCHECK_EQ(new_parent->outer_scope_, outer_scope_);
373 DCHECK_EQ(new_parent, new_parent->ClosureScope()); 411 DCHECK_EQ(new_parent, new_parent->GetClosureScope());
374 DCHECK_NULL(new_parent->inner_scope_); 412 DCHECK_NULL(new_parent->inner_scope_);
375 DCHECK_NULL(new_parent->unresolved_); 413 DCHECK_NULL(new_parent->unresolved_);
376 DCHECK_EQ(0, new_parent->temps_.length()); 414 DCHECK_EQ(0, new_parent->temps()->length());
377 Scope* inner_scope = new_parent->sibling_; 415 Scope* inner_scope = new_parent->sibling_;
378 if (inner_scope != top_inner_scope_) { 416 if (inner_scope != top_inner_scope_) {
379 for (; inner_scope->sibling() != top_inner_scope_; 417 for (; inner_scope->sibling() != top_inner_scope_;
380 inner_scope = inner_scope->sibling()) { 418 inner_scope = inner_scope->sibling()) {
381 inner_scope->outer_scope_ = new_parent; 419 inner_scope->outer_scope_ = new_parent;
382 DCHECK_NE(inner_scope, new_parent); 420 DCHECK_NE(inner_scope, new_parent);
383 } 421 }
384 inner_scope->outer_scope_ = new_parent; 422 inner_scope->outer_scope_ = new_parent;
385 423
386 new_parent->inner_scope_ = new_parent->sibling_; 424 new_parent->inner_scope_ = new_parent->sibling_;
387 inner_scope->sibling_ = nullptr; 425 inner_scope->sibling_ = nullptr;
388 // Reset the sibling rather than the inner_scope_ since we 426 // Reset the sibling rather than the inner_scope_ since we
389 // want to keep new_parent there. 427 // want to keep new_parent there.
390 new_parent->sibling_ = top_inner_scope_; 428 new_parent->sibling_ = top_inner_scope_;
391 } 429 }
392 430
393 if (outer_scope_->unresolved_ != top_unresolved_) { 431 if (outer_scope_->unresolved_ != top_unresolved_) {
394 VariableProxy* last = outer_scope_->unresolved_; 432 VariableProxy* last = outer_scope_->unresolved_;
395 while (last->next_unresolved() != top_unresolved_) { 433 while (last->next_unresolved() != top_unresolved_) {
396 last = last->next_unresolved(); 434 last = last->next_unresolved();
397 } 435 }
398 last->set_next_unresolved(nullptr); 436 last->set_next_unresolved(nullptr);
399 new_parent->unresolved_ = outer_scope_->unresolved_; 437 new_parent->unresolved_ = outer_scope_->unresolved_;
400 outer_scope_->unresolved_ = top_unresolved_; 438 outer_scope_->unresolved_ = top_unresolved_;
401 } 439 }
402 440
403 if (outer_scope_->ClosureScope()->temps_.length() != top_temp_) { 441 if (outer_scope_->GetClosureScope()->temps()->length() != top_temp_) {
404 ZoneList<Variable*>* temps = &outer_scope_->ClosureScope()->temps_; 442 ZoneList<Variable*>* temps = outer_scope_->GetClosureScope()->temps();
405 for (int i = top_temp_; i < temps->length(); i++) { 443 for (int i = top_temp_; i < temps->length(); i++) {
406 Variable* temp = temps->at(i); 444 Variable* temp = temps->at(i);
407 DCHECK_EQ(temp->scope(), temp->scope()->ClosureScope()); 445 DCHECK_EQ(temp->scope(), temp->scope()->GetClosureScope());
408 DCHECK_NE(temp->scope(), new_parent); 446 DCHECK_NE(temp->scope(), new_parent);
409 temp->set_scope(new_parent); 447 temp->set_scope(new_parent);
410 new_parent->AddTemporary(temp); 448 new_parent->AddTemporary(temp);
411 } 449 }
412 temps->Rewind(top_temp_); 450 temps->Rewind(top_temp_);
413 } 451 }
414 } 452 }
415 453
416 void Scope::ReplaceOuterScope(Scope* outer) { 454 void Scope::ReplaceOuterScope(Scope* outer) {
417 DCHECK_NOT_NULL(outer); 455 DCHECK_NOT_NULL(outer);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 } 522 }
485 // TODO(marja, rossberg): Correctly declare FUNCTION, CLASS, NEW_TARGET, and 523 // TODO(marja, rossberg): Correctly declare FUNCTION, CLASS, NEW_TARGET, and
486 // ARGUMENTS bindings as their corresponding Variable::Kind. 524 // ARGUMENTS bindings as their corresponding Variable::Kind.
487 525
488 Variable* var = variables_.Declare(this, name, mode, kind, init_flag, 526 Variable* var = variables_.Declare(this, name, mode, kind, init_flag,
489 maybe_assigned_flag); 527 maybe_assigned_flag);
490 var->AllocateTo(location, index); 528 var->AllocateTo(location, index);
491 return var; 529 return var;
492 } 530 }
493 531
494 532 Variable* DeclarationScope::LookupFunctionVar(const AstRawString* name,
495 Variable* Scope::LookupFunctionVar(const AstRawString* name, 533 AstNodeFactory* factory) {
496 AstNodeFactory* factory) {
497 if (function_ != NULL && function_->proxy()->raw_name() == name) { 534 if (function_ != NULL && function_->proxy()->raw_name() == name) {
498 return function_->proxy()->var(); 535 return function_->proxy()->var();
499 } else if (!scope_info_.is_null()) { 536 } else if (!scope_info_.is_null()) {
500 // If we are backed by a scope info, try to lookup the variable there. 537 // If we are backed by a scope info, try to lookup the variable there.
501 VariableMode mode; 538 VariableMode mode;
502 int index = scope_info_->FunctionContextSlotIndex(*(name->string()), &mode); 539 int index = scope_info_->FunctionContextSlotIndex(*(name->string()), &mode);
503 if (index < 0) return NULL; 540 if (index < 0) return NULL;
504 Variable* var = new (zone()) 541 Variable* var = new (zone())
505 Variable(this, name, mode, Variable::NORMAL, kCreatedInitialized); 542 Variable(this, name, mode, Variable::NORMAL, kCreatedInitialized);
506 DCHECK_NOT_NULL(factory); 543 DCHECK_NOT_NULL(factory);
(...skipping 13 matching lines...) Expand all
520 Variable* Scope::Lookup(const AstRawString* name) { 557 Variable* Scope::Lookup(const AstRawString* name) {
521 for (Scope* scope = this; 558 for (Scope* scope = this;
522 scope != NULL; 559 scope != NULL;
523 scope = scope->outer_scope()) { 560 scope = scope->outer_scope()) {
524 Variable* var = scope->LookupLocal(name); 561 Variable* var = scope->LookupLocal(name);
525 if (var != NULL) return var; 562 if (var != NULL) return var;
526 } 563 }
527 return NULL; 564 return NULL;
528 } 565 }
529 566
530 Variable* Scope::DeclareParameter(const AstRawString* name, VariableMode mode, 567 Variable* DeclarationScope::DeclareParameter(
531 bool is_optional, bool is_rest, 568 const AstRawString* name, VariableMode mode, bool is_optional, bool is_rest,
532 bool* is_duplicate, 569 bool* is_duplicate, AstValueFactory* ast_value_factory) {
533 AstValueFactory* ast_value_factory) {
534 DCHECK(!already_resolved()); 570 DCHECK(!already_resolved());
535 DCHECK(is_function_scope()); 571 DCHECK(is_function_scope());
536 DCHECK(!is_optional || !is_rest); 572 DCHECK(!is_optional || !is_rest);
537 Variable* var; 573 Variable* var;
538 if (mode == TEMPORARY) { 574 if (mode == TEMPORARY) {
539 var = NewTemporary(name); 575 var = NewTemporary(name);
540 } else { 576 } else {
541 var = variables_.Declare(this, name, mode, Variable::NORMAL, 577 var = variables_.Declare(this, name, mode, Variable::NORMAL,
542 kCreatedInitialized); 578 kCreatedInitialized);
543 // TODO(wingo): Avoid O(n^2) check. 579 // TODO(wingo): Avoid O(n^2) check.
(...skipping 19 matching lines...) Expand all
563 MaybeAssignedFlag maybe_assigned_flag) { 599 MaybeAssignedFlag maybe_assigned_flag) {
564 DCHECK(!already_resolved()); 600 DCHECK(!already_resolved());
565 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are 601 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are
566 // introduced during variable allocation, and TEMPORARY variables are 602 // introduced during variable allocation, and TEMPORARY variables are
567 // allocated via NewTemporary(). 603 // allocated via NewTemporary().
568 DCHECK(IsDeclaredVariableMode(mode)); 604 DCHECK(IsDeclaredVariableMode(mode));
569 return variables_.Declare(this, name, mode, kind, init_flag, 605 return variables_.Declare(this, name, mode, kind, init_flag,
570 maybe_assigned_flag); 606 maybe_assigned_flag);
571 } 607 }
572 608
573 609 Variable* DeclarationScope::DeclareDynamicGlobal(const AstRawString* name) {
574 Variable* Scope::DeclareDynamicGlobal(const AstRawString* name) {
575 DCHECK(is_script_scope()); 610 DCHECK(is_script_scope());
576 return variables_.Declare(this, 611 return variables_.Declare(this,
577 name, 612 name,
578 DYNAMIC_GLOBAL, 613 DYNAMIC_GLOBAL,
579 Variable::NORMAL, 614 Variable::NORMAL,
580 kCreatedInitialized); 615 kCreatedInitialized);
581 } 616 }
582 617
583 618
584 bool Scope::RemoveUnresolved(VariableProxy* var) { 619 bool Scope::RemoveUnresolved(VariableProxy* var) {
(...skipping 11 matching lines...) Expand all
596 return true; 631 return true;
597 } 632 }
598 current = next; 633 current = next;
599 } 634 }
600 return false; 635 return false;
601 } 636 }
602 637
603 638
604 Variable* Scope::NewTemporary(const AstRawString* name) { 639 Variable* Scope::NewTemporary(const AstRawString* name) {
605 DCHECK(!already_resolved()); 640 DCHECK(!already_resolved());
606 Scope* scope = this->ClosureScope(); 641 DeclarationScope* scope = GetClosureScope();
607 Variable* var = new(zone()) Variable(scope, 642 Variable* var = new(zone()) Variable(scope,
608 name, 643 name,
609 TEMPORARY, 644 TEMPORARY,
610 Variable::NORMAL, 645 Variable::NORMAL,
611 kCreatedInitialized); 646 kCreatedInitialized);
612 scope->AddTemporary(var); 647 scope->AddTemporary(var);
613 return var; 648 return var;
614 } 649 }
615 650
616 int Scope::RemoveTemporary(Variable* var) { 651 int DeclarationScope::RemoveTemporary(Variable* var) {
617 DCHECK_NOT_NULL(var); 652 DCHECK_NOT_NULL(var);
618 // Temporaries are only placed in ClosureScopes. 653 // Temporaries are only placed in ClosureScopes.
619 DCHECK_EQ(ClosureScope(), this); 654 DCHECK_EQ(GetClosureScope(), this);
620 DCHECK_EQ(var->scope()->ClosureScope(), var->scope()); 655 DCHECK_EQ(var->scope()->GetClosureScope(), var->scope());
621 // If the temporary is not here, return quickly. 656 // If the temporary is not here, return quickly.
622 if (var->scope() != this) return -1; 657 if (var->scope() != this) return -1;
623 // Most likely (always?) any temporary variable we want to remove 658 // Most likely (always?) any temporary variable we want to remove
624 // was just added before, so we search backwards. 659 // was just added before, so we search backwards.
625 for (int i = temps_.length(); i-- > 0;) { 660 for (int i = temps_.length(); i-- > 0;) {
626 if (temps_[i] == var) { 661 if (temps_[i] == var) {
627 // Don't shrink temps_, as callers of this method expect 662 // Don't shrink temps_, as callers of this method expect
628 // the returned indices to be unique per-scope. 663 // the returned indices to be unique per-scope.
629 temps_[i] = nullptr; 664 temps_[i] = nullptr;
630 return i; 665 return i;
631 } 666 }
632 } 667 }
633 return -1; 668 return -1;
634 } 669 }
635 670
636 671
637 void Scope::AddDeclaration(Declaration* declaration) { 672 void Scope::AddDeclaration(Declaration* declaration) {
638 decls_.Add(declaration, zone()); 673 decls_.Add(declaration, zone());
639 } 674 }
640 675
641 676
642 Declaration* Scope::CheckConflictingVarDeclarations() { 677 Declaration* Scope::CheckConflictingVarDeclarations() {
643 int length = decls_.length(); 678 int length = decls_.length();
644 for (int i = 0; i < length; i++) { 679 for (int i = 0; i < length; i++) {
645 Declaration* decl = decls_[i]; 680 Declaration* decl = decls_[i];
646 // We don't create a separate scope to hold the function name of a function 681 // We don't create a separate scope to hold the function name of a function
647 // expression, so we have to make sure not to consider it when checking for 682 // expression, so we have to make sure not to consider it when checking for
648 // conflicts (since it's conceptually "outside" the declaration scope). 683 // conflicts (since it's conceptually "outside" the declaration scope).
649 if (is_function_scope() && decl == function()) continue; 684 if (is_function_scope() && decl == AsDeclarationScope()->function())
685 continue;
650 if (IsLexicalVariableMode(decl->mode()) && !is_block_scope()) continue; 686 if (IsLexicalVariableMode(decl->mode()) && !is_block_scope()) continue;
651 const AstRawString* name = decl->proxy()->raw_name(); 687 const AstRawString* name = decl->proxy()->raw_name();
652 688
653 // Iterate through all scopes until and including the declaration scope. 689 // Iterate through all scopes until and including the declaration scope.
654 Scope* previous = NULL; 690 Scope* previous = NULL;
655 Scope* current = decl->scope(); 691 Scope* current = decl->scope();
656 // Lexical vs lexical conflicts within the same scope have already been 692 // Lexical vs lexical conflicts within the same scope have already been
657 // captured in Parser::Declare. The only conflicts we still need to check 693 // captured in Parser::Declare. The only conflicts we still need to check
658 // are lexical vs VAR, or any declarations within a declaration block scope 694 // are lexical vs VAR, or any declarations within a declaration block scope
659 // vs lexical declarations in its surrounding (function) scope. 695 // vs lexical declarations in its surrounding (function) scope.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
707 743
708 void Scope::CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals, 744 void Scope::CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals,
709 ZoneList<Variable*>* context_locals, 745 ZoneList<Variable*>* context_locals,
710 ZoneList<Variable*>* context_globals) { 746 ZoneList<Variable*>* context_globals) {
711 DCHECK(stack_locals != NULL); 747 DCHECK(stack_locals != NULL);
712 DCHECK(context_locals != NULL); 748 DCHECK(context_locals != NULL);
713 DCHECK(context_globals != NULL); 749 DCHECK(context_globals != NULL);
714 750
715 // Collect temporaries which are always allocated on the stack, unless the 751 // Collect temporaries which are always allocated on the stack, unless the
716 // context as a whole has forced context allocation. 752 // context as a whole has forced context allocation.
717 for (int i = 0; i < temps_.length(); i++) { 753 if (is_declaration_scope()) {
718 Variable* var = temps_[i]; 754 ZoneList<Variable*>* temps = AsDeclarationScope()->temps();
719 if (var == nullptr) continue; 755 for (int i = 0; i < temps->length(); i++) {
720 if (var->is_used()) { 756 Variable* var = (*temps)[i];
721 if (var->IsContextSlot()) { 757 if (var == nullptr) continue;
722 DCHECK(has_forced_context_allocation()); 758 if (var->is_used()) {
723 context_locals->Add(var, zone()); 759 if (var->IsContextSlot()) {
724 } else if (var->IsStackLocal()) { 760 DCHECK(has_forced_context_allocation());
725 stack_locals->Add(var, zone()); 761 context_locals->Add(var, zone());
726 } else { 762 } else if (var->IsStackLocal()) {
727 DCHECK(var->IsParameter()); 763 stack_locals->Add(var, zone());
764 } else {
765 DCHECK(var->IsParameter());
766 }
728 } 767 }
729 } 768 }
730 } 769 }
731 770
732 // Collect declared local variables. 771 // Collect declared local variables.
733 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); 772 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone());
734 for (VariableMap::Entry* p = variables_.Start(); 773 for (VariableMap::Entry* p = variables_.Start();
735 p != NULL; 774 p != NULL;
736 p = variables_.Next(p)) { 775 p = variables_.Next(p)) {
737 Variable* var = reinterpret_cast<Variable*>(p->value); 776 Variable* var = reinterpret_cast<Variable*>(p->value);
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
832 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { 871 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
833 max_context_chain_length = std::max(scope->MaxNestedContextChainLength(), 872 max_context_chain_length = std::max(scope->MaxNestedContextChainLength(),
834 max_context_chain_length); 873 max_context_chain_length);
835 } 874 }
836 if (NeedsContext()) { 875 if (NeedsContext()) {
837 max_context_chain_length += 1; 876 max_context_chain_length += 1;
838 } 877 }
839 return max_context_chain_length; 878 return max_context_chain_length;
840 } 879 }
841 880
842 881 DeclarationScope* Scope::GetDeclarationScope() {
843 Scope* Scope::DeclarationScope() {
844 Scope* scope = this; 882 Scope* scope = this;
845 while (!scope->is_declaration_scope()) { 883 while (!scope->is_declaration_scope()) {
846 scope = scope->outer_scope(); 884 scope = scope->outer_scope();
847 } 885 }
848 return scope; 886 return scope->AsDeclarationScope();
849 } 887 }
850 888
851 889 DeclarationScope* Scope::GetClosureScope() {
852 Scope* Scope::ClosureScope() {
853 Scope* scope = this; 890 Scope* scope = this;
854 while (!scope->is_declaration_scope() || scope->is_block_scope()) { 891 while (!scope->is_declaration_scope() || scope->is_block_scope()) {
855 scope = scope->outer_scope(); 892 scope = scope->outer_scope();
856 } 893 }
857 return scope; 894 return scope->AsDeclarationScope();
895 }
896
897 DeclarationScope* Scope::GetReceiverScope() {
898 Scope* scope = this;
899 while (!scope->is_script_scope() &&
900 (!scope->is_function_scope() ||
901 scope->AsDeclarationScope()->is_arrow_scope())) {
902 scope = scope->outer_scope();
903 }
904 return scope->AsDeclarationScope();
858 } 905 }
859 906
860 907
861 Scope* Scope::ReceiverScope() {
862 Scope* scope = this;
863 while (!scope->is_script_scope() &&
864 (!scope->is_function_scope() || scope->is_arrow_scope())) {
865 scope = scope->outer_scope();
866 }
867 return scope;
868 }
869
870
871 908
872 Handle<ScopeInfo> Scope::GetScopeInfo(Isolate* isolate) { 909 Handle<ScopeInfo> Scope::GetScopeInfo(Isolate* isolate) {
873 if (scope_info_.is_null()) { 910 if (scope_info_.is_null()) {
874 scope_info_ = ScopeInfo::Create(isolate, zone(), this); 911 scope_info_ = ScopeInfo::Create(isolate, zone(), this);
875 } 912 }
876 return scope_info_; 913 return scope_info_;
877 } 914 }
878 915
879 Handle<StringSet> Scope::CollectNonLocals(Handle<StringSet> non_locals) { 916 Handle<StringSet> Scope::CollectNonLocals(Handle<StringSet> non_locals) {
880 // Collect non-local variables referenced in the scope. 917 // Collect non-local variables referenced in the scope.
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
1012 for (VariableMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) { 1049 for (VariableMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) {
1013 Variable* var = reinterpret_cast<Variable*>(p->value); 1050 Variable* var = reinterpret_cast<Variable*>(p->value);
1014 if (var == NULL) { 1051 if (var == NULL) {
1015 Indent(indent, "<?>\n"); 1052 Indent(indent, "<?>\n");
1016 } else { 1053 } else {
1017 PrintVar(indent, var); 1054 PrintVar(indent, var);
1018 } 1055 }
1019 } 1056 }
1020 } 1057 }
1021 1058
1059 void DeclarationScope::PrintParameters() {
1060 PrintF(" (");
1061 for (int i = 0; i < params_.length(); i++) {
1062 if (i > 0) PrintF(", ");
1063 const AstRawString* name = params_[i]->raw_name();
1064 if (name->IsEmpty())
1065 PrintF(".%p", reinterpret_cast<void*>(params_[i]));
1066 else
1067 PrintName(name);
1068 }
1069 PrintF(")");
1070 }
1022 1071
1023 void Scope::Print(int n) { 1072 void Scope::Print(int n) {
1024 int n0 = (n > 0 ? n : 0); 1073 int n0 = (n > 0 ? n : 0);
1025 int n1 = n0 + 2; // indentation 1074 int n1 = n0 + 2; // indentation
1026 1075
1027 // Print header. 1076 // Print header.
1028 Indent(n0, Header(scope_type_, function_kind_, is_declaration_scope())); 1077 FunctionKind function_kind = is_function_scope()
1078 ? AsDeclarationScope()->function_kind()
1079 : kNormalFunction;
marja 2016/08/05 07:00:38 It's slightly weird that we pass kNormalFunction i
1080 Indent(n0, Header(scope_type_, function_kind, is_declaration_scope()));
1029 if (scope_name_ != nullptr && !scope_name_->IsEmpty()) { 1081 if (scope_name_ != nullptr && !scope_name_->IsEmpty()) {
1030 PrintF(" "); 1082 PrintF(" ");
1031 PrintName(scope_name_); 1083 PrintName(scope_name_);
1032 } 1084 }
1033 1085
1034 // Print parameters, if any. 1086 // Print parameters, if any.
1087 VariableDeclaration* function = nullptr;
1035 if (is_function_scope()) { 1088 if (is_function_scope()) {
1036 PrintF(" ("); 1089 AsDeclarationScope()->PrintParameters();
1037 for (int i = 0; i < params_.length(); i++) { 1090 function = AsDeclarationScope()->function();
1038 if (i > 0) PrintF(", ");
1039 const AstRawString* name = params_[i]->raw_name();
1040 if (name->IsEmpty())
1041 PrintF(".%p", reinterpret_cast<void*>(params_[i]));
1042 else
1043 PrintName(name);
1044 }
1045 PrintF(")");
1046 } 1091 }
1047 1092
1048 PrintF(" { // (%d, %d)\n", start_position(), end_position()); 1093 PrintF(" { // (%d, %d)\n", start_position(), end_position());
1049 1094
1050 // Function name, if any (named function literals, only). 1095 // Function name, if any (named function literals, only).
1051 if (function_ != NULL) { 1096 if (function != nullptr) {
1052 Indent(n1, "// (local) function name: "); 1097 Indent(n1, "// (local) function name: ");
1053 PrintName(function_->proxy()->raw_name()); 1098 PrintName(function->proxy()->raw_name());
1054 PrintF("\n"); 1099 PrintF("\n");
1055 } 1100 }
1056 1101
1057 // Scope info. 1102 // Scope info.
1058 if (HasTrivialOuterContext()) { 1103 if (HasTrivialOuterContext()) {
1059 Indent(n1, "// scope has trivial outer context\n"); 1104 Indent(n1, "// scope has trivial outer context\n");
1060 } 1105 }
1061 if (is_strict(language_mode())) { 1106 if (is_strict(language_mode())) {
1062 Indent(n1, "// strict mode scope\n"); 1107 Indent(n1, "// strict mode scope\n");
1063 } 1108 }
(...skipping 11 matching lines...) Expand all
1075 Indent(n1, "// "); 1120 Indent(n1, "// ");
1076 PrintF("%d stack slots\n", num_stack_slots_); 1121 PrintF("%d stack slots\n", num_stack_slots_);
1077 } 1122 }
1078 if (num_heap_slots_ > 0) { 1123 if (num_heap_slots_ > 0) {
1079 Indent(n1, "// "); 1124 Indent(n1, "// ");
1080 PrintF("%d heap slots (including %d global slots)\n", num_heap_slots_, 1125 PrintF("%d heap slots (including %d global slots)\n", num_heap_slots_,
1081 num_global_slots_); 1126 num_global_slots_);
1082 } 1127 }
1083 1128
1084 // Print locals. 1129 // Print locals.
1085 if (function_ != NULL) { 1130 if (function != nullptr) {
1086 Indent(n1, "// function var:\n"); 1131 Indent(n1, "// function var:\n");
1087 PrintVar(n1, function_->proxy()->var()); 1132 PrintVar(n1, function->proxy()->var());
1088 } 1133 }
1089 1134
1090 if (temps_.length() > 0) { 1135 if (is_declaration_scope()) {
1091 bool printed_header = false; 1136 bool printed_header = false;
1092 for (int i = 0; i < temps_.length(); i++) { 1137 ZoneList<Variable*>* temps = AsDeclarationScope()->temps();
1093 if (temps_[i] != nullptr) { 1138 for (int i = 0; i < temps->length(); i++) {
1139 if ((*temps)[i] != nullptr) {
1094 if (!printed_header) { 1140 if (!printed_header) {
1095 printed_header = true; 1141 printed_header = true;
1096 Indent(n1, "// temporary vars:\n"); 1142 Indent(n1, "// temporary vars:\n");
1097 } 1143 }
1098 PrintVar(n1, temps_[i]); 1144 PrintVar(n1, (*temps)[i]);
1099 } 1145 }
1100 } 1146 }
1101 } 1147 }
1102 1148
1103 if (variables_.Start() != NULL) { 1149 if (variables_.Start() != NULL) {
1104 Indent(n1, "// local vars:\n"); 1150 Indent(n1, "// local vars:\n");
1105 PrintMap(n1, &variables_); 1151 PrintMap(n1, &variables_);
1106 } 1152 }
1107 1153
1108 if (dynamics_ != NULL) { 1154 if (dynamics_ != NULL) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1179 Variable* var = LookupLocal(proxy->raw_name()); 1225 Variable* var = LookupLocal(proxy->raw_name());
1180 1226
1181 // We found a variable and we are done. (Even if there is an 'eval' in 1227 // We found a variable and we are done. (Even if there is an 'eval' in
1182 // this scope which introduces the same variable again, the resulting 1228 // this scope which introduces the same variable again, the resulting
1183 // variable remains the same.) 1229 // variable remains the same.)
1184 if (var != NULL) { 1230 if (var != NULL) {
1185 *binding_kind = BOUND; 1231 *binding_kind = BOUND;
1186 return var; 1232 return var;
1187 } 1233 }
1188 1234
1189 // We did not find a variable locally. Check against the function variable, 1235 // We did not find a variable locally. Check against the function variable, if
1190 // if any. We can do this for all scopes, since the function variable is 1236 // any.
1191 // only present - if at all - for function scopes.
1192 *binding_kind = UNBOUND; 1237 *binding_kind = UNBOUND;
1193 var = LookupFunctionVar(proxy->raw_name(), factory); 1238 var =
1239 is_function_scope()
1240 ? AsDeclarationScope()->LookupFunctionVar(proxy->raw_name(), factory)
1241 : nullptr;
1194 if (var != NULL) { 1242 if (var != NULL) {
1195 *binding_kind = BOUND; 1243 *binding_kind = BOUND;
1196 } else if (outer_scope_ != nullptr && this != max_outer_scope) { 1244 } else if (outer_scope_ != nullptr && this != max_outer_scope) {
1197 var = outer_scope_->LookupRecursive(proxy, binding_kind, factory, 1245 var = outer_scope_->LookupRecursive(proxy, binding_kind, factory,
1198 max_outer_scope); 1246 max_outer_scope);
1199 if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) { 1247 if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) {
1200 var->ForceContextAllocation(); 1248 var->ForceContextAllocation();
1201 } 1249 }
1202 } else { 1250 } else {
1203 DCHECK(is_script_scope() || this == max_outer_scope); 1251 DCHECK(is_script_scope() || this == max_outer_scope);
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
1406 if (var->mode() == TEMPORARY) return false; 1454 if (var->mode() == TEMPORARY) return false;
1407 if (is_catch_scope() || is_module_scope()) return true; 1455 if (is_catch_scope() || is_module_scope()) return true;
1408 if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true; 1456 if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true;
1409 return var->has_forced_context_allocation() || scope_calls_eval_ || 1457 return var->has_forced_context_allocation() || scope_calls_eval_ ||
1410 inner_scope_calls_eval_; 1458 inner_scope_calls_eval_;
1411 } 1459 }
1412 1460
1413 1461
1414 void Scope::AllocateStackSlot(Variable* var) { 1462 void Scope::AllocateStackSlot(Variable* var) {
1415 if (is_block_scope()) { 1463 if (is_block_scope()) {
1416 outer_scope()->DeclarationScope()->AllocateStackSlot(var); 1464 outer_scope()->GetDeclarationScope()->AllocateStackSlot(var);
1417 } else { 1465 } else {
1418 var->AllocateTo(VariableLocation::LOCAL, num_stack_slots_++); 1466 var->AllocateTo(VariableLocation::LOCAL, num_stack_slots_++);
1419 } 1467 }
1420 } 1468 }
1421 1469
1422 1470
1423 void Scope::AllocateHeapSlot(Variable* var) { 1471 void Scope::AllocateHeapSlot(Variable* var) {
1424 var->AllocateTo(VariableLocation::CONTEXT, num_heap_slots_++); 1472 var->AllocateTo(VariableLocation::CONTEXT, num_heap_slots_++);
1425 } 1473 }
1426 1474
1427 void Scope::AllocateParameterLocals() { 1475 void DeclarationScope::AllocateParameterLocals() {
1428 DCHECK(is_function_scope()); 1476 DCHECK(is_function_scope());
1429 1477
1430 bool uses_sloppy_arguments = false; 1478 bool uses_sloppy_arguments = false;
1431 1479
1432 // Functions have 'arguments' declared implicitly in all non arrow functions. 1480 // Functions have 'arguments' declared implicitly in all non arrow functions.
1433 if (arguments_ != nullptr) { 1481 if (arguments_ != nullptr) {
1434 // 'arguments' is used. Unless there is also a parameter called 1482 // 'arguments' is used. Unless there is also a parameter called
1435 // 'arguments', we must be conservative and allocate all parameters to 1483 // 'arguments', we must be conservative and allocate all parameters to
1436 // the context assuming they will be captured by the arguments object. 1484 // the context assuming they will be captured by the arguments object.
1437 // If we have a parameter named 'arguments', a (new) value is always 1485 // If we have a parameter named 'arguments', a (new) value is always
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1470 1518
1471 DCHECK(var->scope() == this); 1519 DCHECK(var->scope() == this);
1472 if (uses_sloppy_arguments || has_forced_context_allocation()) { 1520 if (uses_sloppy_arguments || has_forced_context_allocation()) {
1473 // Force context allocation of the parameter. 1521 // Force context allocation of the parameter.
1474 var->ForceContextAllocation(); 1522 var->ForceContextAllocation();
1475 } 1523 }
1476 AllocateParameter(var, i); 1524 AllocateParameter(var, i);
1477 } 1525 }
1478 } 1526 }
1479 1527
1480 1528 void DeclarationScope::AllocateParameter(Variable* var, int index) {
1481 void Scope::AllocateParameter(Variable* var, int index) {
1482 if (MustAllocate(var)) { 1529 if (MustAllocate(var)) {
1483 if (MustAllocateInContext(var)) { 1530 if (MustAllocateInContext(var)) {
1484 DCHECK(var->IsUnallocated() || var->IsContextSlot()); 1531 DCHECK(var->IsUnallocated() || var->IsContextSlot());
1485 if (var->IsUnallocated()) { 1532 if (var->IsUnallocated()) {
1486 AllocateHeapSlot(var); 1533 AllocateHeapSlot(var);
1487 } 1534 }
1488 } else { 1535 } else {
1489 DCHECK(var->IsUnallocated() || var->IsParameter()); 1536 DCHECK(var->IsUnallocated() || var->IsParameter());
1490 if (var->IsUnallocated()) { 1537 if (var->IsUnallocated()) {
1491 var->AllocateTo(VariableLocation::PARAMETER, index); 1538 var->AllocateTo(VariableLocation::PARAMETER, index);
1492 } 1539 }
1493 } 1540 }
1494 } else { 1541 } else {
1495 DCHECK(!var->IsGlobalSlot()); 1542 DCHECK(!var->IsGlobalSlot());
1496 } 1543 }
1497 } 1544 }
1498 1545
1499 1546 void DeclarationScope::AllocateReceiver() {
1500 void Scope::AllocateReceiver() { 1547 if (!has_this_declaration()) return;
1501 DCHECK_NOT_NULL(receiver()); 1548 DCHECK_NOT_NULL(receiver());
1502 DCHECK_EQ(receiver()->scope(), this); 1549 DCHECK_EQ(receiver()->scope(), this);
1503 1550
1504 if (has_forced_context_allocation()) { 1551 if (has_forced_context_allocation()) {
1505 // Force context allocation of the receiver. 1552 // Force context allocation of the receiver.
1506 receiver()->ForceContextAllocation(); 1553 receiver()->ForceContextAllocation();
1507 } 1554 }
1508 AllocateParameter(receiver(), -1); 1555 AllocateParameter(receiver(), -1);
1509 } 1556 }
1510 1557
(...skipping 25 matching lines...) Expand all
1536 } else { 1583 } else {
1537 // There must be only DYNAMIC_GLOBAL in the script scope. 1584 // There must be only DYNAMIC_GLOBAL in the script scope.
1538 DCHECK(!is_script_scope() || DYNAMIC_GLOBAL == var->mode()); 1585 DCHECK(!is_script_scope() || DYNAMIC_GLOBAL == var->mode());
1539 } 1586 }
1540 } 1587 }
1541 } 1588 }
1542 1589
1543 void Scope::AllocateNonParameterLocalsAndDeclaredGlobals( 1590 void Scope::AllocateNonParameterLocalsAndDeclaredGlobals(
1544 AstValueFactory* ast_value_factory) { 1591 AstValueFactory* ast_value_factory) {
1545 // All variables that have no rewrite yet are non-parameter locals. 1592 // All variables that have no rewrite yet are non-parameter locals.
1546 for (int i = 0; i < temps_.length(); i++) { 1593 if (is_declaration_scope()) {
1547 if (temps_[i] == nullptr) continue; 1594 ZoneList<Variable*>* temps = AsDeclarationScope()->temps();
1548 AllocateNonParameterLocal(temps_[i], ast_value_factory); 1595 for (int i = 0; i < temps->length(); i++) {
1596 if ((*temps)[i] == nullptr) continue;
1597 AllocateNonParameterLocal((*temps)[i], ast_value_factory);
1598 }
1549 } 1599 }
1550 1600
1551 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); 1601 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone());
1552 for (VariableMap::Entry* p = variables_.Start(); 1602 for (VariableMap::Entry* p = variables_.Start();
1553 p != NULL; 1603 p != NULL;
1554 p = variables_.Next(p)) { 1604 p = variables_.Next(p)) {
1555 Variable* var = reinterpret_cast<Variable*>(p->value); 1605 Variable* var = reinterpret_cast<Variable*>(p->value);
1556 vars.Add(VarAndOrder(var, p->order), zone()); 1606 vars.Add(VarAndOrder(var, p->order), zone());
1557 } 1607 }
1558 vars.Sort(VarAndOrder::Compare); 1608 vars.Sort(VarAndOrder::Compare);
1559 int var_count = vars.length(); 1609 int var_count = vars.length();
1560 for (int i = 0; i < var_count; i++) { 1610 for (int i = 0; i < var_count; i++) {
1561 AllocateNonParameterLocal(vars[i].var(), ast_value_factory); 1611 AllocateNonParameterLocal(vars[i].var(), ast_value_factory);
1562 } 1612 }
1563 1613
1564 if (FLAG_global_var_shortcuts) { 1614 if (FLAG_global_var_shortcuts) {
1565 for (int i = 0; i < var_count; i++) { 1615 for (int i = 0; i < var_count; i++) {
1566 AllocateDeclaredGlobal(vars[i].var(), ast_value_factory); 1616 AllocateDeclaredGlobal(vars[i].var(), ast_value_factory);
1567 } 1617 }
1568 } 1618 }
1569 1619
1620 if (is_declaration_scope()) {
1621 AsDeclarationScope()->AllocateLocals(ast_value_factory);
1622 }
1623 }
1624
1625 void DeclarationScope::AllocateLocals(AstValueFactory* ast_value_factory) {
1570 // For now, function_ must be allocated at the very end. If it gets 1626 // For now, function_ must be allocated at the very end. If it gets
1571 // allocated in the context, it must be the last slot in the context, 1627 // allocated in the context, it must be the last slot in the context,
1572 // because of the current ScopeInfo implementation (see 1628 // because of the current ScopeInfo implementation (see
1573 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). 1629 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor).
1574 if (function_ != nullptr) { 1630 if (function_ != nullptr) {
1575 AllocateNonParameterLocal(function_->proxy()->var(), ast_value_factory); 1631 AllocateNonParameterLocal(function_->proxy()->var(), ast_value_factory);
1576 } 1632 }
1577 1633
1578 if (rest_parameter_ != nullptr) { 1634 if (rest_parameter_ != nullptr) {
1579 AllocateNonParameterLocal(rest_parameter_, ast_value_factory); 1635 AllocateNonParameterLocal(rest_parameter_, ast_value_factory);
(...skipping 18 matching lines...) Expand all
1598 } 1654 }
1599 1655
1600 // If scope is already resolved, we still need to allocate 1656 // If scope is already resolved, we still need to allocate
1601 // variables in inner scopes which might not have been resolved yet. 1657 // variables in inner scopes which might not have been resolved yet.
1602 if (already_resolved()) return; 1658 if (already_resolved()) return;
1603 // The number of slots required for variables. 1659 // The number of slots required for variables.
1604 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; 1660 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
1605 1661
1606 // Allocate variables for this scope. 1662 // Allocate variables for this scope.
1607 // Parameters must be allocated first, if any. 1663 // Parameters must be allocated first, if any.
1608 if (is_function_scope()) AllocateParameterLocals(); 1664 if (is_declaration_scope()) {
1609 if (has_this_declaration()) AllocateReceiver(); 1665 if (is_function_scope()) AsDeclarationScope()->AllocateParameterLocals();
1666 AsDeclarationScope()->AllocateReceiver();
1667 }
1610 AllocateNonParameterLocalsAndDeclaredGlobals(ast_value_factory); 1668 AllocateNonParameterLocalsAndDeclaredGlobals(ast_value_factory);
1611 1669
1612 // Force allocation of a context for this scope if necessary. For a 'with' 1670 // Force allocation of a context for this scope if necessary. For a 'with'
1613 // scope and for a function scope that makes an 'eval' call we need a context, 1671 // scope and for a function scope that makes an 'eval' call we need a context,
1614 // even if no local variables were statically allocated in the scope. 1672 // even if no local variables were statically allocated in the scope.
1615 // Likewise for modules. 1673 // Likewise for modules.
1616 bool must_have_context = 1674 bool must_have_context =
1617 is_with_scope() || is_module_scope() || 1675 is_with_scope() || is_module_scope() ||
1618 (is_function_scope() && calls_sloppy_eval()) || 1676 (is_function_scope() && calls_sloppy_eval()) ||
1619 (is_block_scope() && is_declaration_scope() && calls_sloppy_eval()); 1677 (is_block_scope() && is_declaration_scope() && calls_sloppy_eval());
1620 1678
1621 // If we didn't allocate any locals in the local context, then we only 1679 // If we didn't allocate any locals in the local context, then we only
1622 // need the minimal number of slots if we must have a context. 1680 // need the minimal number of slots if we must have a context.
1623 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) { 1681 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) {
1624 num_heap_slots_ = 0; 1682 num_heap_slots_ = 0;
1625 } 1683 }
1626 1684
1627 // Allocation done. 1685 // Allocation done.
1628 DCHECK(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); 1686 DCHECK(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS);
1629 } 1687 }
1630 1688
1631 1689
1632 int Scope::StackLocalCount() const { 1690 int Scope::StackLocalCount() const {
1691 VariableDeclaration* function =
1692 is_function_scope() ? AsDeclarationScope()->function() : nullptr;
1633 return num_stack_slots() - 1693 return num_stack_slots() -
1634 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); 1694 (function != NULL && function->proxy()->var()->IsStackLocal() ? 1 : 0);
1635 } 1695 }
1636 1696
1637 1697
1638 int Scope::ContextLocalCount() const { 1698 int Scope::ContextLocalCount() const {
1639 if (num_heap_slots() == 0) return 0; 1699 if (num_heap_slots() == 0) return 0;
1700 VariableDeclaration* function =
1701 is_function_scope() ? AsDeclarationScope()->function() : nullptr;
1640 bool is_function_var_in_context = 1702 bool is_function_var_in_context =
1641 function_ != NULL && function_->proxy()->var()->IsContextSlot(); 1703 function != NULL && function->proxy()->var()->IsContextSlot();
1642 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - 1704 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() -
1643 (is_function_var_in_context ? 1 : 0); 1705 (is_function_var_in_context ? 1 : 0);
1644 } 1706 }
1645 1707
1646 1708
1647 int Scope::ContextGlobalCount() const { return num_global_slots(); } 1709 int Scope::ContextGlobalCount() const { return num_global_slots(); }
1648 1710
1649 } // namespace internal 1711 } // namespace internal
1650 } // namespace v8 1712 } // namespace v8
OLDNEW
« no previous file with comments | « src/ast/scopes.h ('k') | src/compiler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698