OLD | NEW |
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/ast/scopeinfo.h" | 8 #include "src/ast/scopeinfo.h" |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/messages.h" | 10 #include "src/messages.h" |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 function_kind_ = function_kind; | 164 function_kind_ = function_kind; |
165 scope_name_ = ast_value_factory_->empty_string(); | 165 scope_name_ = ast_value_factory_->empty_string(); |
166 dynamics_ = nullptr; | 166 dynamics_ = nullptr; |
167 receiver_ = nullptr; | 167 receiver_ = nullptr; |
168 new_target_ = nullptr; | 168 new_target_ = nullptr; |
169 function_ = nullptr; | 169 function_ = nullptr; |
170 arguments_ = nullptr; | 170 arguments_ = nullptr; |
171 this_function_ = nullptr; | 171 this_function_ = nullptr; |
172 illegal_redecl_ = nullptr; | 172 illegal_redecl_ = nullptr; |
173 scope_inside_with_ = false; | 173 scope_inside_with_ = false; |
174 scope_contains_with_ = false; | |
175 scope_calls_eval_ = false; | 174 scope_calls_eval_ = false; |
176 scope_uses_arguments_ = false; | 175 scope_uses_arguments_ = false; |
177 scope_uses_super_property_ = false; | 176 scope_uses_super_property_ = false; |
178 asm_module_ = false; | 177 asm_module_ = false; |
179 asm_function_ = outer_scope != NULL && outer_scope->asm_module_; | 178 asm_function_ = outer_scope != NULL && outer_scope->asm_module_; |
180 // Inherit the language mode from the parent scope. | 179 // Inherit the language mode from the parent scope. |
181 language_mode_ = outer_scope != NULL ? outer_scope->language_mode_ : SLOPPY; | 180 language_mode_ = outer_scope != NULL ? outer_scope->language_mode_ : SLOPPY; |
182 outer_scope_calls_sloppy_eval_ = false; | 181 outer_scope_calls_sloppy_eval_ = false; |
183 inner_scope_calls_eval_ = false; | 182 inner_scope_calls_eval_ = false; |
184 scope_nonlinear_ = false; | 183 scope_nonlinear_ = false; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 Scope(zone, current_scope, BLOCK_SCOPE, Handle<ScopeInfo>(scope_info), | 244 Scope(zone, current_scope, BLOCK_SCOPE, Handle<ScopeInfo>(scope_info), |
246 script_scope->ast_value_factory_); | 245 script_scope->ast_value_factory_); |
247 } else { | 246 } else { |
248 DCHECK(context->IsCatchContext()); | 247 DCHECK(context->IsCatchContext()); |
249 String* name = context->catch_name(); | 248 String* name = context->catch_name(); |
250 current_scope = new (zone) Scope( | 249 current_scope = new (zone) Scope( |
251 zone, current_scope, | 250 zone, current_scope, |
252 script_scope->ast_value_factory_->GetString(Handle<String>(name)), | 251 script_scope->ast_value_factory_->GetString(Handle<String>(name)), |
253 script_scope->ast_value_factory_); | 252 script_scope->ast_value_factory_); |
254 } | 253 } |
255 if (contains_with) current_scope->RecordWithStatement(); | |
256 if (innermost_scope == NULL) innermost_scope = current_scope; | 254 if (innermost_scope == NULL) innermost_scope = current_scope; |
257 | 255 |
258 // Forget about a with when we move to a context for a different function. | 256 // Forget about a with when we move to a context for a different function. |
259 if (context->previous()->closure() != context->closure()) { | 257 if (context->previous()->closure() != context->closure()) { |
260 contains_with = false; | 258 contains_with = false; |
261 } | 259 } |
262 context = context->previous(); | 260 context = context->previous(); |
263 } | 261 } |
264 | 262 |
265 script_scope->AddInnerScope(current_scope); | 263 script_scope->AddInnerScope(current_scope); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
385 } | 383 } |
386 | 384 |
387 | 385 |
388 void Scope::PropagateUsageFlagsToScope(Scope* other) { | 386 void Scope::PropagateUsageFlagsToScope(Scope* other) { |
389 DCHECK_NOT_NULL(other); | 387 DCHECK_NOT_NULL(other); |
390 DCHECK(!already_resolved()); | 388 DCHECK(!already_resolved()); |
391 DCHECK(!other->already_resolved()); | 389 DCHECK(!other->already_resolved()); |
392 if (uses_arguments()) other->RecordArgumentsUsage(); | 390 if (uses_arguments()) other->RecordArgumentsUsage(); |
393 if (uses_super_property()) other->RecordSuperPropertyUsage(); | 391 if (uses_super_property()) other->RecordSuperPropertyUsage(); |
394 if (calls_eval()) other->RecordEvalCall(); | 392 if (calls_eval()) other->RecordEvalCall(); |
395 if (scope_contains_with_) other->RecordWithStatement(); | |
396 } | 393 } |
397 | 394 |
398 | 395 |
399 Variable* Scope::LookupLocal(const AstRawString* name) { | 396 Variable* Scope::LookupLocal(const AstRawString* name) { |
400 Variable* result = variables_.Lookup(name); | 397 Variable* result = variables_.Lookup(name); |
401 if (result != NULL || scope_info_.is_null()) { | 398 if (result != NULL || scope_info_.is_null()) { |
402 return result; | 399 return result; |
403 } | 400 } |
404 Handle<String> name_handle = name->string(); | 401 Handle<String> name_handle = name->string(); |
405 // The Scope is backed up by ScopeInfo. This means it cannot operate in a | 402 // The Scope is backed up by ScopeInfo. This means it cannot operate in a |
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
975 } | 972 } |
976 | 973 |
977 // Scope info. | 974 // Scope info. |
978 if (HasTrivialOuterContext()) { | 975 if (HasTrivialOuterContext()) { |
979 Indent(n1, "// scope has trivial outer context\n"); | 976 Indent(n1, "// scope has trivial outer context\n"); |
980 } | 977 } |
981 if (is_strict(language_mode())) { | 978 if (is_strict(language_mode())) { |
982 Indent(n1, "// strict mode scope\n"); | 979 Indent(n1, "// strict mode scope\n"); |
983 } | 980 } |
984 if (scope_inside_with_) Indent(n1, "// scope inside 'with'\n"); | 981 if (scope_inside_with_) Indent(n1, "// scope inside 'with'\n"); |
985 if (scope_contains_with_) Indent(n1, "// scope contains 'with'\n"); | |
986 if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n"); | 982 if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n"); |
987 if (scope_uses_arguments_) Indent(n1, "// scope uses 'arguments'\n"); | 983 if (scope_uses_arguments_) Indent(n1, "// scope uses 'arguments'\n"); |
988 if (scope_uses_super_property_) | 984 if (scope_uses_super_property_) |
989 Indent(n1, "// scope uses 'super' property\n"); | 985 Indent(n1, "// scope uses 'super' property\n"); |
990 if (outer_scope_calls_sloppy_eval_) { | 986 if (outer_scope_calls_sloppy_eval_) { |
991 Indent(n1, "// outer scope calls 'eval' in sloppy context\n"); | 987 Indent(n1, "// outer scope calls 'eval' in sloppy context\n"); |
992 } | 988 } |
993 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n"); | 989 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n"); |
994 if (num_stack_slots_ > 0) { | 990 if (num_stack_slots_ > 0) { |
995 Indent(n1, "// "); | 991 Indent(n1, "// "); |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1247 } | 1243 } |
1248 } | 1244 } |
1249 | 1245 |
1250 | 1246 |
1251 bool Scope::MustAllocate(Variable* var) { | 1247 bool Scope::MustAllocate(Variable* var) { |
1252 // Give var a read/write use if there is a chance it might be accessed | 1248 // Give var a read/write use if there is a chance it might be accessed |
1253 // via an eval() call. This is only possible if the variable has a | 1249 // via an eval() call. This is only possible if the variable has a |
1254 // visible name. | 1250 // visible name. |
1255 if ((var->is_this() || !var->raw_name()->IsEmpty()) && | 1251 if ((var->is_this() || !var->raw_name()->IsEmpty()) && |
1256 (var->has_forced_context_allocation() || scope_calls_eval_ || | 1252 (var->has_forced_context_allocation() || scope_calls_eval_ || |
1257 inner_scope_calls_eval_ || scope_contains_with_ || is_catch_scope() || | 1253 inner_scope_calls_eval_ || is_catch_scope() || is_block_scope() || |
1258 is_block_scope() || is_module_scope() || is_script_scope())) { | 1254 is_module_scope() || is_script_scope())) { |
1259 var->set_is_used(); | 1255 var->set_is_used(); |
1260 if (scope_calls_eval_ || inner_scope_calls_eval_) var->set_maybe_assigned(); | 1256 if (scope_calls_eval_ || inner_scope_calls_eval_) var->set_maybe_assigned(); |
1261 } | 1257 } |
1262 // Global variables do not need to be allocated. | 1258 // Global variables do not need to be allocated. |
1263 return !var->IsGlobalObjectProperty() && var->is_used(); | 1259 return !var->IsGlobalObjectProperty() && var->is_used(); |
1264 } | 1260 } |
1265 | 1261 |
1266 | 1262 |
1267 bool Scope::MustAllocateInContext(Variable* var) { | 1263 bool Scope::MustAllocateInContext(Variable* var) { |
1268 // If var is accessed from an inner scope, or if there is a possibility | 1264 // If var is accessed from an inner scope, or if there is a possibility |
1269 // that it might be accessed from the current or an inner scope (through | 1265 // that it might be accessed from the current or an inner scope (through |
1270 // an eval() call or a runtime with lookup), it must be allocated in the | 1266 // an eval() call or a runtime with lookup), it must be allocated in the |
1271 // context. | 1267 // context. |
1272 // | 1268 // |
1273 // Exceptions: If the scope as a whole has forced context allocation, all | 1269 // Exceptions: If the scope as a whole has forced context allocation, all |
1274 // variables will have context allocation, even temporaries. Otherwise | 1270 // variables will have context allocation, even temporaries. Otherwise |
1275 // temporary variables are always stack-allocated. Catch-bound variables are | 1271 // temporary variables are always stack-allocated. Catch-bound variables are |
1276 // always context-allocated. | 1272 // always context-allocated. |
1277 if (has_forced_context_allocation()) return true; | 1273 if (has_forced_context_allocation()) return true; |
1278 if (var->mode() == TEMPORARY) return false; | 1274 if (var->mode() == TEMPORARY) return false; |
1279 if (is_catch_scope() || is_module_scope()) return true; | 1275 if (is_catch_scope() || is_module_scope()) return true; |
1280 if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true; | 1276 if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true; |
1281 return var->has_forced_context_allocation() || | 1277 return var->has_forced_context_allocation() || scope_calls_eval_ || |
1282 scope_calls_eval_ || | 1278 inner_scope_calls_eval_; |
1283 inner_scope_calls_eval_ || | |
1284 scope_contains_with_; | |
1285 } | 1279 } |
1286 | 1280 |
1287 | 1281 |
1288 bool Scope::HasArgumentsParameter(Isolate* isolate) { | 1282 bool Scope::HasArgumentsParameter(Isolate* isolate) { |
1289 for (int i = 0; i < params_.length(); i++) { | 1283 for (int i = 0; i < params_.length(); i++) { |
1290 if (params_[i]->name().is_identical_to( | 1284 if (params_[i]->name().is_identical_to( |
1291 isolate->factory()->arguments_string())) { | 1285 isolate->factory()->arguments_string())) { |
1292 return true; | 1286 return true; |
1293 } | 1287 } |
1294 } | 1288 } |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1530 function_ != NULL && function_->proxy()->var()->IsContextSlot(); | 1524 function_ != NULL && function_->proxy()->var()->IsContextSlot(); |
1531 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - | 1525 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - |
1532 (is_function_var_in_context ? 1 : 0); | 1526 (is_function_var_in_context ? 1 : 0); |
1533 } | 1527 } |
1534 | 1528 |
1535 | 1529 |
1536 int Scope::ContextGlobalCount() const { return num_global_slots(); } | 1530 int Scope::ContextGlobalCount() const { return num_global_slots(); } |
1537 | 1531 |
1538 } // namespace internal | 1532 } // namespace internal |
1539 } // namespace v8 | 1533 } // namespace v8 |
OLD | NEW |