| 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 <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
| 10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(), | 70 ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(), |
| 71 ZoneAllocationPolicy(zone)); | 71 ZoneAllocationPolicy(zone)); |
| 72 stmt->set_next(static_cast<SloppyBlockFunctionStatement*>(p->value)); | 72 stmt->set_next(static_cast<SloppyBlockFunctionStatement*>(p->value)); |
| 73 p->value = stmt; | 73 p->value = stmt; |
| 74 } | 74 } |
| 75 | 75 |
| 76 | 76 |
| 77 // ---------------------------------------------------------------------------- | 77 // ---------------------------------------------------------------------------- |
| 78 // Implementation of Scope | 78 // Implementation of Scope |
| 79 | 79 |
| 80 Scope::Scope(Zone* zone) | 80 Scope::Scope(Zone* zone, ScopeType scope_type) |
| 81 : zone_(zone), | 81 : zone_(zone), |
| 82 outer_scope_(nullptr), | 82 outer_scope_(nullptr), |
| 83 variables_(zone), | 83 variables_(zone), |
| 84 ordered_variables_(4, zone), | 84 ordered_variables_(4, zone), |
| 85 decls_(4, zone), | 85 decls_(4, zone), |
| 86 scope_type_(SCRIPT_SCOPE) { | 86 scope_type_(scope_type) { |
| 87 DCHECK(scope_type == SCRIPT_SCOPE || scope_type == WITH_SCOPE); |
| 87 SetDefaults(); | 88 SetDefaults(); |
| 89 #ifdef DEBUG |
| 90 if (scope_type == WITH_SCOPE) { |
| 91 already_resolved_ = true; |
| 92 } |
| 93 #endif |
| 88 } | 94 } |
| 89 | 95 |
| 90 Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type) | 96 Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type) |
| 91 : zone_(zone), | 97 : zone_(zone), |
| 92 outer_scope_(outer_scope), | 98 outer_scope_(outer_scope), |
| 93 variables_(zone), | 99 variables_(zone), |
| 94 ordered_variables_(4, zone), | 100 ordered_variables_(4, zone), |
| 95 decls_(4, zone), | 101 decls_(4, zone), |
| 96 scope_type_(scope_type) { | 102 scope_type_(scope_type) { |
| 97 DCHECK_NE(SCRIPT_SCOPE, scope_type); | 103 DCHECK_NE(SCRIPT_SCOPE, scope_type); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 } | 136 } |
| 131 | 137 |
| 132 ModuleScope::ModuleScope(Zone* zone, DeclarationScope* script_scope, | 138 ModuleScope::ModuleScope(Zone* zone, DeclarationScope* script_scope, |
| 133 AstValueFactory* ast_value_factory) | 139 AstValueFactory* ast_value_factory) |
| 134 : DeclarationScope(zone, script_scope, MODULE_SCOPE) { | 140 : DeclarationScope(zone, script_scope, MODULE_SCOPE) { |
| 135 module_descriptor_ = new (zone) ModuleDescriptor(zone); | 141 module_descriptor_ = new (zone) ModuleDescriptor(zone); |
| 136 set_language_mode(STRICT); | 142 set_language_mode(STRICT); |
| 137 DeclareThis(ast_value_factory); | 143 DeclareThis(ast_value_factory); |
| 138 } | 144 } |
| 139 | 145 |
| 140 Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type, | 146 Scope::Scope(Zone* zone, ScopeType scope_type, Handle<ScopeInfo> scope_info) |
| 141 Handle<ScopeInfo> scope_info) | |
| 142 : zone_(zone), | 147 : zone_(zone), |
| 143 outer_scope_(nullptr), | 148 outer_scope_(nullptr), |
| 144 variables_(zone), | 149 variables_(zone), |
| 145 ordered_variables_(0, zone), | 150 ordered_variables_(0, zone), |
| 146 decls_(0, zone), | 151 decls_(0, zone), |
| 147 scope_info_(scope_info), | 152 scope_info_(scope_info), |
| 148 scope_type_(scope_type) { | 153 scope_type_(scope_type) { |
| 154 DCHECK(!scope_info.is_null()); |
| 149 SetDefaults(); | 155 SetDefaults(); |
| 150 #ifdef DEBUG | 156 #ifdef DEBUG |
| 151 already_resolved_ = true; | 157 already_resolved_ = true; |
| 152 #endif | 158 #endif |
| 153 if (scope_type == WITH_SCOPE) { | 159 if (scope_info->CallsEval()) RecordEvalCall(); |
| 154 DCHECK(scope_info.is_null()); | 160 set_language_mode(scope_info->language_mode()); |
| 155 } else { | 161 num_heap_slots_ = scope_info->ContextLength(); |
| 156 if (scope_info->CallsEval()) RecordEvalCall(); | |
| 157 set_language_mode(scope_info->language_mode()); | |
| 158 num_heap_slots_ = scope_info->ContextLength(); | |
| 159 } | |
| 160 DCHECK_LE(Context::MIN_CONTEXT_SLOTS, num_heap_slots_); | 162 DCHECK_LE(Context::MIN_CONTEXT_SLOTS, num_heap_slots_); |
| 161 | |
| 162 if (inner_scope != nullptr) AddInnerScope(inner_scope); | |
| 163 } | 163 } |
| 164 | 164 |
| 165 DeclarationScope::DeclarationScope(Zone* zone, Scope* inner_scope, | 165 DeclarationScope::DeclarationScope(Zone* zone, ScopeType scope_type, |
| 166 ScopeType scope_type, | |
| 167 Handle<ScopeInfo> scope_info) | 166 Handle<ScopeInfo> scope_info) |
| 168 : Scope(zone, inner_scope, scope_type, scope_info), | 167 : Scope(zone, scope_type, scope_info), |
| 169 function_kind_(scope_info->function_kind()), | 168 function_kind_(scope_info->function_kind()), |
| 170 temps_(0, zone), | 169 temps_(0, zone), |
| 171 params_(0, zone), | 170 params_(0, zone), |
| 172 sloppy_block_function_map_(zone) { | 171 sloppy_block_function_map_(zone) { |
| 173 SetDefaults(); | 172 SetDefaults(); |
| 174 } | 173 } |
| 175 | 174 |
| 176 Scope::Scope(Zone* zone, Scope* inner_scope, | 175 Scope::Scope(Zone* zone, const AstRawString* catch_variable_name) |
| 177 const AstRawString* catch_variable_name) | |
| 178 : zone_(zone), | 176 : zone_(zone), |
| 179 outer_scope_(nullptr), | 177 outer_scope_(nullptr), |
| 180 variables_(zone), | 178 variables_(zone), |
| 181 ordered_variables_(0, zone), | 179 ordered_variables_(0, zone), |
| 182 decls_(0, zone), | 180 decls_(0, zone), |
| 183 scope_type_(CATCH_SCOPE) { | 181 scope_type_(CATCH_SCOPE) { |
| 184 SetDefaults(); | 182 SetDefaults(); |
| 185 #ifdef DEBUG | 183 #ifdef DEBUG |
| 186 already_resolved_ = true; | 184 already_resolved_ = true; |
| 187 #endif | 185 #endif |
| 188 if (inner_scope != nullptr) AddInnerScope(inner_scope); | |
| 189 Variable* variable = | 186 Variable* variable = |
| 190 variables_.Declare(zone, this, catch_variable_name, VAR, Variable::NORMAL, | 187 variables_.Declare(zone, this, catch_variable_name, VAR, Variable::NORMAL, |
| 191 kCreatedInitialized); | 188 kCreatedInitialized); |
| 192 AllocateHeapSlot(variable); | 189 AllocateHeapSlot(variable); |
| 193 } | 190 } |
| 194 | 191 |
| 195 void DeclarationScope::SetDefaults() { | 192 void DeclarationScope::SetDefaults() { |
| 196 is_declaration_scope_ = true; | 193 is_declaration_scope_ = true; |
| 197 has_simple_parameters_ = true; | 194 has_simple_parameters_ = true; |
| 198 asm_module_ = false; | 195 asm_module_ = false; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 } | 250 } |
| 254 | 251 |
| 255 Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, | 252 Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, |
| 256 Context* context, | 253 Context* context, |
| 257 DeclarationScope* script_scope, | 254 DeclarationScope* script_scope, |
| 258 AstValueFactory* ast_value_factory, | 255 AstValueFactory* ast_value_factory, |
| 259 DeserializationMode deserialization_mode) { | 256 DeserializationMode deserialization_mode) { |
| 260 // Reconstruct the outer scope chain from a closure's context chain. | 257 // Reconstruct the outer scope chain from a closure's context chain. |
| 261 Scope* current_scope = nullptr; | 258 Scope* current_scope = nullptr; |
| 262 Scope* innermost_scope = nullptr; | 259 Scope* innermost_scope = nullptr; |
| 260 Scope* outer_scope = nullptr; |
| 263 while (!context->IsNativeContext()) { | 261 while (!context->IsNativeContext()) { |
| 264 if (context->IsWithContext() || context->IsDebugEvaluateContext()) { | 262 if (context->IsWithContext() || context->IsDebugEvaluateContext()) { |
| 265 // For scope analysis, debug-evaluate is equivalent to a with scope. | 263 // For scope analysis, debug-evaluate is equivalent to a with scope. |
| 266 Scope* with_scope = new (zone) | 264 outer_scope = new (zone) Scope(zone, WITH_SCOPE); |
| 267 Scope(zone, current_scope, WITH_SCOPE, Handle<ScopeInfo>()); | 265 |
| 268 // TODO(yangguo): Remove once debug-evaluate properly keeps track of the | 266 // TODO(yangguo): Remove once debug-evaluate properly keeps track of the |
| 269 // function scope in which we are evaluating. | 267 // function scope in which we are evaluating. |
| 270 if (context->IsDebugEvaluateContext()) { | 268 if (context->IsDebugEvaluateContext()) { |
| 271 with_scope->set_is_debug_evaluate_scope(); | 269 outer_scope->set_is_debug_evaluate_scope(); |
| 272 } | 270 } |
| 273 current_scope = with_scope; | |
| 274 } else if (context->IsScriptContext()) { | 271 } else if (context->IsScriptContext()) { |
| 275 // If we reach a script context, it's the outermost context with scope | 272 // If we reach a script context, it's the outermost context with scope |
| 276 // info. The next context will be the native context. Install the scope | 273 // info. The next context will be the native context. Install the scope |
| 277 // info of this script context onto the existing script scope to avoid | 274 // info of this script context onto the existing script scope to avoid |
| 278 // nesting script scopes. | 275 // nesting script scopes. |
| 279 Handle<ScopeInfo> scope_info(context->scope_info(), isolate); | 276 Handle<ScopeInfo> scope_info(context->scope_info(), isolate); |
| 280 script_scope->SetScriptScopeInfo(scope_info); | 277 script_scope->SetScriptScopeInfo(scope_info); |
| 281 DCHECK(context->previous()->IsNativeContext()); | 278 DCHECK(context->previous()->IsNativeContext()); |
| 282 break; | 279 break; |
| 283 } else if (context->IsFunctionContext()) { | 280 } else if (context->IsFunctionContext()) { |
| 284 Handle<ScopeInfo> scope_info(context->closure()->shared()->scope_info(), | 281 Handle<ScopeInfo> scope_info(context->closure()->shared()->scope_info(), |
| 285 isolate); | 282 isolate); |
| 286 // TODO(neis): For an eval scope, we currently create an ordinary function | 283 // TODO(neis): For an eval scope, we currently create an ordinary function |
| 287 // context. This is wrong and needs to be fixed. | 284 // context. This is wrong and needs to be fixed. |
| 288 // https://bugs.chromium.org/p/v8/issues/detail?id=5295 | 285 // https://bugs.chromium.org/p/v8/issues/detail?id=5295 |
| 289 DCHECK(scope_info->scope_type() == FUNCTION_SCOPE || | 286 DCHECK(scope_info->scope_type() == FUNCTION_SCOPE || |
| 290 scope_info->scope_type() == EVAL_SCOPE); | 287 scope_info->scope_type() == EVAL_SCOPE); |
| 291 DeclarationScope* function_scope = new (zone) | 288 outer_scope = |
| 292 DeclarationScope(zone, current_scope, FUNCTION_SCOPE, scope_info); | 289 new (zone) DeclarationScope(zone, FUNCTION_SCOPE, scope_info); |
| 293 if (scope_info->IsAsmFunction()) function_scope->set_asm_function(); | 290 if (scope_info->IsAsmFunction()) |
| 294 if (scope_info->IsAsmModule()) function_scope->set_asm_module(); | 291 outer_scope->AsDeclarationScope()->set_asm_function(); |
| 295 current_scope = function_scope; | 292 if (scope_info->IsAsmModule()) |
| 293 outer_scope->AsDeclarationScope()->set_asm_module(); |
| 296 } else if (context->IsBlockContext()) { | 294 } else if (context->IsBlockContext()) { |
| 297 Handle<ScopeInfo> scope_info(context->scope_info(), isolate); | 295 Handle<ScopeInfo> scope_info(context->scope_info(), isolate); |
| 298 DCHECK_EQ(scope_info->scope_type(), BLOCK_SCOPE); | 296 DCHECK_EQ(scope_info->scope_type(), BLOCK_SCOPE); |
| 299 if (scope_info->is_declaration_scope()) { | 297 if (scope_info->is_declaration_scope()) { |
| 300 current_scope = new (zone) | 298 outer_scope = |
| 301 DeclarationScope(zone, current_scope, BLOCK_SCOPE, scope_info); | 299 new (zone) DeclarationScope(zone, BLOCK_SCOPE, scope_info); |
| 302 } else { | 300 } else { |
| 303 current_scope = | 301 outer_scope = new (zone) Scope(zone, BLOCK_SCOPE, scope_info); |
| 304 new (zone) Scope(zone, current_scope, BLOCK_SCOPE, scope_info); | |
| 305 } | 302 } |
| 306 } else { | 303 } else { |
| 307 DCHECK(context->IsCatchContext()); | 304 DCHECK(context->IsCatchContext()); |
| 308 String* name = context->catch_name(); | 305 String* name = context->catch_name(); |
| 309 current_scope = | 306 outer_scope = new (zone) |
| 310 new (zone) Scope(zone, current_scope, | 307 Scope(zone, ast_value_factory->GetString(handle(name, isolate))); |
| 311 ast_value_factory->GetString(handle(name, isolate))); | |
| 312 } | 308 } |
| 309 if (current_scope != nullptr) { |
| 310 outer_scope->AddInnerScope(current_scope); |
| 311 } |
| 312 current_scope = outer_scope; |
| 313 if (deserialization_mode == DeserializationMode::kDeserializeOffHeap) { | 313 if (deserialization_mode == DeserializationMode::kDeserializeOffHeap) { |
| 314 current_scope->DeserializeScopeInfo(isolate, ast_value_factory); | 314 current_scope->DeserializeScopeInfo(isolate, ast_value_factory); |
| 315 } | 315 } |
| 316 if (innermost_scope == nullptr) innermost_scope = current_scope; | 316 if (innermost_scope == nullptr) innermost_scope = current_scope; |
| 317 context = context->previous(); | 317 context = context->previous(); |
| 318 } | 318 } |
| 319 | 319 |
| 320 if (innermost_scope == nullptr) return script_scope; | 320 if (innermost_scope == nullptr) return script_scope; |
| 321 script_scope->AddInnerScope(current_scope); | 321 script_scope->AddInnerScope(current_scope); |
| 322 script_scope->PropagateScopeInfo(); | 322 script_scope->PropagateScopeInfo(); |
| (...skipping 1358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1681 function != nullptr && function->IsContextSlot(); | 1681 function != nullptr && function->IsContextSlot(); |
| 1682 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - | 1682 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - |
| 1683 (is_function_var_in_context ? 1 : 0); | 1683 (is_function_var_in_context ? 1 : 0); |
| 1684 } | 1684 } |
| 1685 | 1685 |
| 1686 | 1686 |
| 1687 int Scope::ContextGlobalCount() const { return num_global_slots(); } | 1687 int Scope::ContextGlobalCount() const { return num_global_slots(); } |
| 1688 | 1688 |
| 1689 } // namespace internal | 1689 } // namespace internal |
| 1690 } // namespace v8 | 1690 } // namespace v8 |
| OLD | NEW |