| 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/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/scopes.h" | 7 #include "src/scopes.h" |
| 8 | 8 |
| 9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
| 10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| 11 #include "src/compiler.h" | 11 #include "src/compiler.h" |
| 12 #include "src/messages.h" | 12 #include "src/messages.h" |
| 13 #include "src/scopeinfo.h" | 13 #include "src/scopeinfo.h" |
| 14 | 14 |
| 15 namespace v8 { | 15 namespace v8 { |
| 16 namespace internal { | 16 namespace internal { |
| 17 | 17 |
| 18 // ---------------------------------------------------------------------------- | 18 // ---------------------------------------------------------------------------- |
| 19 // Implementation of LocalsMap | 19 // Implementation of LocalsMap |
| 20 // | 20 // |
| 21 // Note: We are storing the handle locations as key values in the hash map. | 21 // Note: We are storing the handle locations as key values in the hash map. |
| 22 // When inserting a new variable via Declare(), we rely on the fact that | 22 // When inserting a new variable via Declare(), we rely on the fact that |
| 23 // the handle location remains alive for the duration of that variable | 23 // the handle location remains alive for the duration of that variable |
| 24 // use. Because a Variable holding a handle with the same location exists | 24 // use. Because a Variable holding a handle with the same location exists |
| 25 // this is ensured. | 25 // this is ensured. |
| 26 | 26 |
| 27 static bool Match(void* key1, void* key2) { | |
| 28 String* name1 = *reinterpret_cast<String**>(key1); | |
| 29 String* name2 = *reinterpret_cast<String**>(key2); | |
| 30 ASSERT(name1->IsInternalizedString()); | |
| 31 ASSERT(name2->IsInternalizedString()); | |
| 32 return name1 == name2; | |
| 33 } | |
| 34 | |
| 35 | |
| 36 VariableMap::VariableMap(Zone* zone) | 27 VariableMap::VariableMap(Zone* zone) |
| 37 : ZoneHashMap(Match, 8, ZoneAllocationPolicy(zone)), | 28 : ZoneHashMap(ZoneHashMap::PointersMatch, 8, ZoneAllocationPolicy(zone)), |
| 38 zone_(zone) {} | 29 zone_(zone) {} |
| 39 VariableMap::~VariableMap() {} | 30 VariableMap::~VariableMap() {} |
| 40 | 31 |
| 41 | 32 |
| 42 Variable* VariableMap::Declare( | 33 Variable* VariableMap::Declare( |
| 43 Scope* scope, | 34 Scope* scope, |
| 44 Handle<String> name, | 35 const AstString* name, |
| 45 VariableMode mode, | 36 VariableMode mode, |
| 46 bool is_valid_lhs, | 37 bool is_valid_lhs, |
| 47 Variable::Kind kind, | 38 Variable::Kind kind, |
| 48 InitializationFlag initialization_flag, | 39 InitializationFlag initialization_flag, |
| 49 Interface* interface) { | 40 Interface* interface) { |
| 50 Entry* p = ZoneHashMap::Lookup(name.location(), name->Hash(), true, | 41 // AstStrings are unambiguous, i.e., the same string is always represented by |
| 51 ZoneAllocationPolicy(zone())); | 42 // the same AstString*. |
| 43 // FIXME(marja): fix the type of Lookup. |
| 44 Entry* p = ZoneHashMap::Lookup(const_cast<AstString*>(name), name->hash(), |
| 45 true, ZoneAllocationPolicy(zone())); |
| 52 if (p->value == NULL) { | 46 if (p->value == NULL) { |
| 53 // The variable has not been declared yet -> insert it. | 47 // The variable has not been declared yet -> insert it. |
| 54 ASSERT(p->key == name.location()); | 48 ASSERT(p->key == name); |
| 55 p->value = new(zone()) Variable(scope, | 49 p->value = new(zone()) Variable(scope, |
| 56 name, | 50 name, |
| 57 mode, | 51 mode, |
| 58 is_valid_lhs, | 52 is_valid_lhs, |
| 59 kind, | 53 kind, |
| 60 initialization_flag, | 54 initialization_flag, |
| 61 interface); | 55 interface); |
| 62 } | 56 } |
| 63 return reinterpret_cast<Variable*>(p->value); | 57 return reinterpret_cast<Variable*>(p->value); |
| 64 } | 58 } |
| 65 | 59 |
| 66 | 60 |
| 67 Variable* VariableMap::Lookup(Handle<String> name) { | 61 Variable* VariableMap::Lookup(const AstString* name) { |
| 68 Entry* p = ZoneHashMap::Lookup(name.location(), name->Hash(), false, | 62 Entry* p = ZoneHashMap::Lookup(const_cast<AstString*>(name), name->hash(), |
| 69 ZoneAllocationPolicy(NULL)); | 63 false, ZoneAllocationPolicy(NULL)); |
| 70 if (p != NULL) { | 64 if (p != NULL) { |
| 71 ASSERT(*reinterpret_cast<String**>(p->key) == *name); | 65 ASSERT(reinterpret_cast<const AstString*>(p->key) == name); |
| 72 ASSERT(p->value != NULL); | 66 ASSERT(p->value != NULL); |
| 73 return reinterpret_cast<Variable*>(p->value); | 67 return reinterpret_cast<Variable*>(p->value); |
| 74 } | 68 } |
| 75 return NULL; | 69 return NULL; |
| 76 } | 70 } |
| 77 | 71 |
| 78 | 72 |
| 79 // ---------------------------------------------------------------------------- | 73 // ---------------------------------------------------------------------------- |
| 80 // Implementation of Scope | 74 // Implementation of Scope |
| 81 | 75 |
| 82 Scope::Scope(Scope* outer_scope, ScopeType scope_type, Zone* zone) | 76 Scope::Scope(Scope* outer_scope, ScopeType scope_type, |
| 77 AstValueFactory* ast_value_factory, Zone* zone) |
| 83 : isolate_(zone->isolate()), | 78 : isolate_(zone->isolate()), |
| 84 inner_scopes_(4, zone), | 79 inner_scopes_(4, zone), |
| 85 variables_(zone), | 80 variables_(zone), |
| 86 internals_(4, zone), | 81 internals_(4, zone), |
| 87 temps_(4, zone), | 82 temps_(4, zone), |
| 88 params_(4, zone), | 83 params_(4, zone), |
| 89 unresolved_(16, zone), | 84 unresolved_(16, zone), |
| 90 decls_(4, zone), | 85 decls_(4, zone), |
| 91 interface_(FLAG_harmony_modules && | 86 interface_(FLAG_harmony_modules && |
| 92 (scope_type == MODULE_SCOPE || scope_type == GLOBAL_SCOPE) | 87 (scope_type == MODULE_SCOPE || scope_type == GLOBAL_SCOPE) |
| 93 ? Interface::NewModule(zone) : NULL), | 88 ? Interface::NewModule(zone) : NULL), |
| 94 already_resolved_(false), | 89 already_resolved_(false), |
| 90 ast_value_factory_(ast_value_factory), |
| 95 zone_(zone) { | 91 zone_(zone) { |
| 96 SetDefaults(scope_type, outer_scope, Handle<ScopeInfo>::null()); | 92 SetDefaults(scope_type, outer_scope, Handle<ScopeInfo>::null()); |
| 97 // The outermost scope must be a global scope. | 93 // The outermost scope must be a global scope. |
| 98 ASSERT(scope_type == GLOBAL_SCOPE || outer_scope != NULL); | 94 ASSERT(scope_type == GLOBAL_SCOPE || outer_scope != NULL); |
| 99 ASSERT(!HasIllegalRedeclaration()); | 95 ASSERT(!HasIllegalRedeclaration()); |
| 100 } | 96 } |
| 101 | 97 |
| 102 | 98 |
| 103 Scope::Scope(Scope* inner_scope, | 99 Scope::Scope(Scope* inner_scope, |
| 104 ScopeType scope_type, | 100 ScopeType scope_type, |
| 105 Handle<ScopeInfo> scope_info, | 101 Handle<ScopeInfo> scope_info, |
| 102 AstValueFactory* value_factory, |
| 106 Zone* zone) | 103 Zone* zone) |
| 107 : isolate_(zone->isolate()), | 104 : isolate_(zone->isolate()), |
| 108 inner_scopes_(4, zone), | 105 inner_scopes_(4, zone), |
| 109 variables_(zone), | 106 variables_(zone), |
| 110 internals_(4, zone), | 107 internals_(4, zone), |
| 111 temps_(4, zone), | 108 temps_(4, zone), |
| 112 params_(4, zone), | 109 params_(4, zone), |
| 113 unresolved_(16, zone), | 110 unresolved_(16, zone), |
| 114 decls_(4, zone), | 111 decls_(4, zone), |
| 115 interface_(NULL), | 112 interface_(NULL), |
| 116 already_resolved_(true), | 113 already_resolved_(true), |
| 114 ast_value_factory_(value_factory), |
| 117 zone_(zone) { | 115 zone_(zone) { |
| 118 SetDefaults(scope_type, NULL, scope_info); | 116 SetDefaults(scope_type, NULL, scope_info); |
| 119 if (!scope_info.is_null()) { | 117 if (!scope_info.is_null()) { |
| 120 num_heap_slots_ = scope_info_->ContextLength(); | 118 num_heap_slots_ = scope_info_->ContextLength(); |
| 121 } | 119 } |
| 122 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context. | 120 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context. |
| 123 num_heap_slots_ = Max(num_heap_slots_, | 121 num_heap_slots_ = Max(num_heap_slots_, |
| 124 static_cast<int>(Context::MIN_CONTEXT_SLOTS)); | 122 static_cast<int>(Context::MIN_CONTEXT_SLOTS)); |
| 125 AddInnerScope(inner_scope); | 123 AddInnerScope(inner_scope); |
| 126 } | 124 } |
| 127 | 125 |
| 128 | 126 |
| 129 Scope::Scope(Scope* inner_scope, Handle<String> catch_variable_name, Zone* zone) | 127 Scope::Scope(Scope* inner_scope, const AstString* catch_variable_name, |
| 128 AstValueFactory* value_factory, Zone* zone) |
| 130 : isolate_(zone->isolate()), | 129 : isolate_(zone->isolate()), |
| 131 inner_scopes_(1, zone), | 130 inner_scopes_(1, zone), |
| 132 variables_(zone), | 131 variables_(zone), |
| 133 internals_(0, zone), | 132 internals_(0, zone), |
| 134 temps_(0, zone), | 133 temps_(0, zone), |
| 135 params_(0, zone), | 134 params_(0, zone), |
| 136 unresolved_(0, zone), | 135 unresolved_(0, zone), |
| 137 decls_(0, zone), | 136 decls_(0, zone), |
| 138 interface_(NULL), | 137 interface_(NULL), |
| 139 already_resolved_(true), | 138 already_resolved_(true), |
| 139 ast_value_factory_(value_factory), |
| 140 zone_(zone) { | 140 zone_(zone) { |
| 141 SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null()); | 141 SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null()); |
| 142 AddInnerScope(inner_scope); | 142 AddInnerScope(inner_scope); |
| 143 ++num_var_or_const_; | 143 ++num_var_or_const_; |
| 144 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; | 144 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; |
| 145 Variable* variable = variables_.Declare(this, | 145 Variable* variable = variables_.Declare(this, |
| 146 catch_variable_name, | 146 catch_variable_name, |
| 147 VAR, | 147 VAR, |
| 148 true, // Valid left-hand side. | 148 true, // Valid left-hand side. |
| 149 Variable::NORMAL, | 149 Variable::NORMAL, |
| 150 kCreatedInitialized); | 150 kCreatedInitialized); |
| 151 AllocateHeapSlot(variable); | 151 AllocateHeapSlot(variable); |
| 152 } | 152 } |
| 153 | 153 |
| 154 | 154 |
| 155 void Scope::SetDefaults(ScopeType scope_type, | 155 void Scope::SetDefaults(ScopeType scope_type, |
| 156 Scope* outer_scope, | 156 Scope* outer_scope, |
| 157 Handle<ScopeInfo> scope_info) { | 157 Handle<ScopeInfo> scope_info) { |
| 158 outer_scope_ = outer_scope; | 158 outer_scope_ = outer_scope; |
| 159 scope_type_ = scope_type; | 159 scope_type_ = scope_type; |
| 160 scope_name_ = isolate_->factory()->empty_string(); | 160 scope_name_ = ast_value_factory_->empty_string(); |
| 161 dynamics_ = NULL; | 161 dynamics_ = NULL; |
| 162 receiver_ = NULL; | 162 receiver_ = NULL; |
| 163 function_ = NULL; | 163 function_ = NULL; |
| 164 arguments_ = NULL; | 164 arguments_ = NULL; |
| 165 illegal_redecl_ = NULL; | 165 illegal_redecl_ = NULL; |
| 166 scope_inside_with_ = false; | 166 scope_inside_with_ = false; |
| 167 scope_contains_with_ = false; | 167 scope_contains_with_ = false; |
| 168 scope_calls_eval_ = false; | 168 scope_calls_eval_ = false; |
| 169 // Inherit the strict mode from the parent scope. | 169 // Inherit the strict mode from the parent scope. |
| 170 strict_mode_ = outer_scope != NULL ? outer_scope->strict_mode_ : SLOPPY; | 170 strict_mode_ = outer_scope != NULL ? outer_scope->strict_mode_ : SLOPPY; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 192 Zone* zone) { | 192 Zone* zone) { |
| 193 // Reconstruct the outer scope chain from a closure's context chain. | 193 // Reconstruct the outer scope chain from a closure's context chain. |
| 194 Scope* current_scope = NULL; | 194 Scope* current_scope = NULL; |
| 195 Scope* innermost_scope = NULL; | 195 Scope* innermost_scope = NULL; |
| 196 bool contains_with = false; | 196 bool contains_with = false; |
| 197 while (!context->IsNativeContext()) { | 197 while (!context->IsNativeContext()) { |
| 198 if (context->IsWithContext()) { | 198 if (context->IsWithContext()) { |
| 199 Scope* with_scope = new(zone) Scope(current_scope, | 199 Scope* with_scope = new(zone) Scope(current_scope, |
| 200 WITH_SCOPE, | 200 WITH_SCOPE, |
| 201 Handle<ScopeInfo>::null(), | 201 Handle<ScopeInfo>::null(), |
| 202 global_scope->ast_value_factory_, |
| 202 zone); | 203 zone); |
| 203 current_scope = with_scope; | 204 current_scope = with_scope; |
| 204 // All the inner scopes are inside a with. | 205 // All the inner scopes are inside a with. |
| 205 contains_with = true; | 206 contains_with = true; |
| 206 for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) { | 207 for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) { |
| 207 s->scope_inside_with_ = true; | 208 s->scope_inside_with_ = true; |
| 208 } | 209 } |
| 209 } else if (context->IsGlobalContext()) { | 210 } else if (context->IsGlobalContext()) { |
| 210 ScopeInfo* scope_info = ScopeInfo::cast(context->extension()); | 211 ScopeInfo* scope_info = ScopeInfo::cast(context->extension()); |
| 211 current_scope = new(zone) Scope(current_scope, | 212 current_scope = new(zone) Scope(current_scope, |
| 212 GLOBAL_SCOPE, | 213 GLOBAL_SCOPE, |
| 213 Handle<ScopeInfo>(scope_info), | 214 Handle<ScopeInfo>(scope_info), |
| 215 global_scope->ast_value_factory_, |
| 214 zone); | 216 zone); |
| 215 } else if (context->IsModuleContext()) { | 217 } else if (context->IsModuleContext()) { |
| 216 ScopeInfo* scope_info = ScopeInfo::cast(context->module()->scope_info()); | 218 ScopeInfo* scope_info = ScopeInfo::cast(context->module()->scope_info()); |
| 217 current_scope = new(zone) Scope(current_scope, | 219 current_scope = new(zone) Scope(current_scope, |
| 218 MODULE_SCOPE, | 220 MODULE_SCOPE, |
| 219 Handle<ScopeInfo>(scope_info), | 221 Handle<ScopeInfo>(scope_info), |
| 222 global_scope->ast_value_factory_, |
| 220 zone); | 223 zone); |
| 221 } else if (context->IsFunctionContext()) { | 224 } else if (context->IsFunctionContext()) { |
| 222 ScopeInfo* scope_info = context->closure()->shared()->scope_info(); | 225 ScopeInfo* scope_info = context->closure()->shared()->scope_info(); |
| 223 current_scope = new(zone) Scope(current_scope, | 226 current_scope = new(zone) Scope(current_scope, |
| 224 FUNCTION_SCOPE, | 227 FUNCTION_SCOPE, |
| 225 Handle<ScopeInfo>(scope_info), | 228 Handle<ScopeInfo>(scope_info), |
| 229 global_scope->ast_value_factory_, |
| 226 zone); | 230 zone); |
| 227 } else if (context->IsBlockContext()) { | 231 } else if (context->IsBlockContext()) { |
| 228 ScopeInfo* scope_info = ScopeInfo::cast(context->extension()); | 232 ScopeInfo* scope_info = ScopeInfo::cast(context->extension()); |
| 229 current_scope = new(zone) Scope(current_scope, | 233 current_scope = new(zone) Scope(current_scope, |
| 230 BLOCK_SCOPE, | 234 BLOCK_SCOPE, |
| 231 Handle<ScopeInfo>(scope_info), | 235 Handle<ScopeInfo>(scope_info), |
| 236 global_scope->ast_value_factory_, |
| 232 zone); | 237 zone); |
| 233 } else { | 238 } else { |
| 234 ASSERT(context->IsCatchContext()); | 239 ASSERT(context->IsCatchContext()); |
| 235 String* name = String::cast(context->extension()); | 240 String* name = String::cast(context->extension()); |
| 236 current_scope = new(zone) Scope( | 241 current_scope = new (zone) Scope( |
| 237 current_scope, Handle<String>(name), zone); | 242 current_scope, |
| 243 global_scope->ast_value_factory_->GetString(Handle<String>(name)), |
| 244 global_scope->ast_value_factory_, zone); |
| 238 } | 245 } |
| 239 if (contains_with) current_scope->RecordWithStatement(); | 246 if (contains_with) current_scope->RecordWithStatement(); |
| 240 if (innermost_scope == NULL) innermost_scope = current_scope; | 247 if (innermost_scope == NULL) innermost_scope = current_scope; |
| 241 | 248 |
| 242 // Forget about a with when we move to a context for a different function. | 249 // Forget about a with when we move to a context for a different function. |
| 243 if (context->previous()->closure() != context->closure()) { | 250 if (context->previous()->closure() != context->closure()) { |
| 244 contains_with = false; | 251 contains_with = false; |
| 245 } | 252 } |
| 246 context = context->previous(); | 253 context = context->previous(); |
| 247 } | 254 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 259 | 266 |
| 260 // Traverse the scope tree up to the first unresolved scope or the global | 267 // Traverse the scope tree up to the first unresolved scope or the global |
| 261 // scope and start scope resolution and variable allocation from that scope. | 268 // scope and start scope resolution and variable allocation from that scope. |
| 262 while (!top->is_global_scope() && | 269 while (!top->is_global_scope() && |
| 263 !top->outer_scope()->already_resolved()) { | 270 !top->outer_scope()->already_resolved()) { |
| 264 top = top->outer_scope(); | 271 top = top->outer_scope(); |
| 265 } | 272 } |
| 266 | 273 |
| 267 // Allocate the variables. | 274 // Allocate the variables. |
| 268 { | 275 { |
| 269 AstNodeFactory<AstNullVisitor> ast_node_factory(info->zone()); | 276 // Passing NULL as AstValueFactory is ok, because AllocateVariables doesn't |
| 277 // need to create new strings or values. |
| 278 AstNodeFactory<AstNullVisitor> ast_node_factory(info->zone(), NULL); |
| 270 if (!top->AllocateVariables(info, &ast_node_factory)) return false; | 279 if (!top->AllocateVariables(info, &ast_node_factory)) return false; |
| 271 } | 280 } |
| 272 | 281 |
| 273 #ifdef DEBUG | 282 #ifdef DEBUG |
| 274 if (info->isolate()->bootstrapper()->IsActive() | 283 if (info->isolate()->bootstrapper()->IsActive() |
| 275 ? FLAG_print_builtin_scopes | 284 ? FLAG_print_builtin_scopes |
| 276 : FLAG_print_scopes) { | 285 : FLAG_print_scopes) { |
| 277 scope->Print(); | 286 scope->Print(); |
| 278 } | 287 } |
| 279 | 288 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 303 // Declare and allocate receiver (even for the global scope, and even | 312 // Declare and allocate receiver (even for the global scope, and even |
| 304 // if naccesses_ == 0). | 313 // if naccesses_ == 0). |
| 305 // NOTE: When loading parameters in the global scope, we must take | 314 // NOTE: When loading parameters in the global scope, we must take |
| 306 // care not to access them as properties of the global object, but | 315 // care not to access them as properties of the global object, but |
| 307 // instead load them directly from the stack. Currently, the only | 316 // instead load them directly from the stack. Currently, the only |
| 308 // such parameter is 'this' which is passed on the stack when | 317 // such parameter is 'this' which is passed on the stack when |
| 309 // invoking scripts | 318 // invoking scripts |
| 310 if (is_declaration_scope()) { | 319 if (is_declaration_scope()) { |
| 311 Variable* var = | 320 Variable* var = |
| 312 variables_.Declare(this, | 321 variables_.Declare(this, |
| 313 isolate_->factory()->this_string(), | 322 ast_value_factory_->this_string(), |
| 314 VAR, | 323 VAR, |
| 315 false, | 324 false, |
| 316 Variable::THIS, | 325 Variable::THIS, |
| 317 kCreatedInitialized); | 326 kCreatedInitialized); |
| 318 var->AllocateTo(Variable::PARAMETER, -1); | 327 var->AllocateTo(Variable::PARAMETER, -1); |
| 319 receiver_ = var; | 328 receiver_ = var; |
| 320 } else { | 329 } else { |
| 321 ASSERT(outer_scope() != NULL); | 330 ASSERT(outer_scope() != NULL); |
| 322 receiver_ = outer_scope()->receiver(); | 331 receiver_ = outer_scope()->receiver(); |
| 323 } | 332 } |
| 324 | 333 |
| 325 if (is_function_scope()) { | 334 if (is_function_scope()) { |
| 326 // Declare 'arguments' variable which exists in all functions. | 335 // Declare 'arguments' variable which exists in all functions. |
| 327 // Note that it might never be accessed, in which case it won't be | 336 // Note that it might never be accessed, in which case it won't be |
| 328 // allocated during variable allocation. | 337 // allocated during variable allocation. |
| 329 variables_.Declare(this, | 338 variables_.Declare(this, |
| 330 isolate_->factory()->arguments_string(), | 339 ast_value_factory_->arguments_string(), |
| 331 VAR, | 340 VAR, |
| 332 true, | 341 true, |
| 333 Variable::ARGUMENTS, | 342 Variable::ARGUMENTS, |
| 334 kCreatedInitialized); | 343 kCreatedInitialized); |
| 335 } | 344 } |
| 336 } | 345 } |
| 337 | 346 |
| 338 | 347 |
| 339 Scope* Scope::FinalizeBlockScope() { | 348 Scope* Scope::FinalizeBlockScope() { |
| 340 ASSERT(is_block_scope()); | 349 ASSERT(is_block_scope()); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 359 | 368 |
| 360 // Move unresolved variables | 369 // Move unresolved variables |
| 361 for (int i = 0; i < unresolved_.length(); i++) { | 370 for (int i = 0; i < unresolved_.length(); i++) { |
| 362 outer_scope()->unresolved_.Add(unresolved_[i], zone()); | 371 outer_scope()->unresolved_.Add(unresolved_[i], zone()); |
| 363 } | 372 } |
| 364 | 373 |
| 365 return NULL; | 374 return NULL; |
| 366 } | 375 } |
| 367 | 376 |
| 368 | 377 |
| 369 Variable* Scope::LookupLocal(Handle<String> name) { | 378 Variable* Scope::LookupLocal(const AstString* name) { |
| 370 Variable* result = variables_.Lookup(name); | 379 Variable* result = variables_.Lookup(name); |
| 371 if (result != NULL || scope_info_.is_null()) { | 380 if (result != NULL || scope_info_.is_null()) { |
| 372 return result; | 381 return result; |
| 373 } | 382 } |
| 383 // The Scope is backed up by ScopeInfo. This means it cannot operate in a |
| 384 // heap-independent mode, and all strings must be internalized immediately. So |
| 385 // it's ok to get the Handle<String> here. |
| 386 Handle<String> name_handle = name->string(); |
| 374 // If we have a serialized scope info, we might find the variable there. | 387 // If we have a serialized scope info, we might find the variable there. |
| 375 // There should be no local slot with the given name. | 388 // There should be no local slot with the given name. |
| 376 ASSERT(scope_info_->StackSlotIndex(*name) < 0); | 389 ASSERT(scope_info_->StackSlotIndex(*name_handle) < 0); |
| 377 | 390 |
| 378 // Check context slot lookup. | 391 // Check context slot lookup. |
| 379 VariableMode mode; | 392 VariableMode mode; |
| 380 Variable::Location location = Variable::CONTEXT; | 393 Variable::Location location = Variable::CONTEXT; |
| 381 InitializationFlag init_flag; | 394 InitializationFlag init_flag; |
| 382 int index = ScopeInfo::ContextSlotIndex(scope_info_, name, &mode, &init_flag); | 395 int index = |
| 396 ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode, &init_flag); |
| 383 if (index < 0) { | 397 if (index < 0) { |
| 384 // Check parameters. | 398 // Check parameters. |
| 385 index = scope_info_->ParameterIndex(*name); | 399 index = scope_info_->ParameterIndex(*name_handle); |
| 386 if (index < 0) return NULL; | 400 if (index < 0) return NULL; |
| 387 | 401 |
| 388 mode = DYNAMIC; | 402 mode = DYNAMIC; |
| 389 location = Variable::LOOKUP; | 403 location = Variable::LOOKUP; |
| 390 init_flag = kCreatedInitialized; | 404 init_flag = kCreatedInitialized; |
| 391 } | 405 } |
| 392 | 406 |
| 393 Variable* var = variables_.Declare(this, name, mode, true, Variable::NORMAL, | 407 Variable* var = variables_.Declare(this, name, mode, true, Variable::NORMAL, |
| 394 init_flag); | 408 init_flag); |
| 395 var->AllocateTo(location, index); | 409 var->AllocateTo(location, index); |
| 396 return var; | 410 return var; |
| 397 } | 411 } |
| 398 | 412 |
| 399 | 413 |
| 400 Variable* Scope::LookupFunctionVar(Handle<String> name, | 414 Variable* Scope::LookupFunctionVar(const AstString* name, |
| 401 AstNodeFactory<AstNullVisitor>* factory) { | 415 AstNodeFactory<AstNullVisitor>* factory) { |
| 402 if (function_ != NULL && function_->proxy()->name().is_identical_to(name)) { | 416 if (function_ != NULL && function_->proxy()->raw_name() == name) { |
| 403 return function_->proxy()->var(); | 417 return function_->proxy()->var(); |
| 404 } else if (!scope_info_.is_null()) { | 418 } else if (!scope_info_.is_null()) { |
| 405 // If we are backed by a scope info, try to lookup the variable there. | 419 // If we are backed by a scope info, try to lookup the variable there. |
| 406 VariableMode mode; | 420 VariableMode mode; |
| 407 int index = scope_info_->FunctionContextSlotIndex(*name, &mode); | 421 int index = scope_info_->FunctionContextSlotIndex(*(name->string()), &mode); |
| 408 if (index < 0) return NULL; | 422 if (index < 0) return NULL; |
| 409 Variable* var = new(zone()) Variable( | 423 Variable* var = new(zone()) Variable( |
| 410 this, name, mode, true /* is valid LHS */, | 424 this, name, mode, true /* is valid LHS */, |
| 411 Variable::NORMAL, kCreatedInitialized); | 425 Variable::NORMAL, kCreatedInitialized); |
| 412 VariableProxy* proxy = factory->NewVariableProxy(var); | 426 VariableProxy* proxy = factory->NewVariableProxy(var); |
| 413 VariableDeclaration* declaration = factory->NewVariableDeclaration( | 427 VariableDeclaration* declaration = factory->NewVariableDeclaration( |
| 414 proxy, mode, this, RelocInfo::kNoPosition); | 428 proxy, mode, this, RelocInfo::kNoPosition); |
| 415 DeclareFunctionVar(declaration); | 429 DeclareFunctionVar(declaration); |
| 416 var->AllocateTo(Variable::CONTEXT, index); | 430 var->AllocateTo(Variable::CONTEXT, index); |
| 417 return var; | 431 return var; |
| 418 } else { | 432 } else { |
| 419 return NULL; | 433 return NULL; |
| 420 } | 434 } |
| 421 } | 435 } |
| 422 | 436 |
| 423 | 437 |
| 424 Variable* Scope::Lookup(Handle<String> name) { | 438 Variable* Scope::Lookup(const AstString* name) { |
| 425 for (Scope* scope = this; | 439 for (Scope* scope = this; |
| 426 scope != NULL; | 440 scope != NULL; |
| 427 scope = scope->outer_scope()) { | 441 scope = scope->outer_scope()) { |
| 428 Variable* var = scope->LookupLocal(name); | 442 Variable* var = scope->LookupLocal(name); |
| 429 if (var != NULL) return var; | 443 if (var != NULL) return var; |
| 430 } | 444 } |
| 431 return NULL; | 445 return NULL; |
| 432 } | 446 } |
| 433 | 447 |
| 434 | 448 |
| 435 void Scope::DeclareParameter(Handle<String> name, VariableMode mode) { | 449 void Scope::DeclareParameter(const AstString* name, VariableMode mode) { |
| 436 ASSERT(!already_resolved()); | 450 ASSERT(!already_resolved()); |
| 437 ASSERT(is_function_scope()); | 451 ASSERT(is_function_scope()); |
| 438 Variable* var = variables_.Declare(this, name, mode, true, Variable::NORMAL, | 452 Variable* var = variables_.Declare(this, name, mode, true, Variable::NORMAL, |
| 439 kCreatedInitialized); | 453 kCreatedInitialized); |
| 440 params_.Add(var, zone()); | 454 params_.Add(var, zone()); |
| 441 } | 455 } |
| 442 | 456 |
| 443 | 457 |
| 444 Variable* Scope::DeclareLocal(Handle<String> name, | 458 Variable* Scope::DeclareLocal(const AstString* name, |
| 445 VariableMode mode, | 459 VariableMode mode, |
| 446 InitializationFlag init_flag, | 460 InitializationFlag init_flag, |
| 447 Interface* interface) { | 461 Interface* interface) { |
| 448 ASSERT(!already_resolved()); | 462 ASSERT(!already_resolved()); |
| 449 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are | 463 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are |
| 450 // introduces during variable allocation, INTERNAL variables are allocated | 464 // introduces during variable allocation, INTERNAL variables are allocated |
| 451 // explicitly, and TEMPORARY variables are allocated via NewTemporary(). | 465 // explicitly, and TEMPORARY variables are allocated via NewTemporary(). |
| 452 ASSERT(IsDeclaredVariableMode(mode)); | 466 ASSERT(IsDeclaredVariableMode(mode)); |
| 453 ++num_var_or_const_; | 467 ++num_var_or_const_; |
| 454 return variables_.Declare( | 468 return variables_.Declare( |
| 455 this, name, mode, true, Variable::NORMAL, init_flag, interface); | 469 this, name, mode, true, Variable::NORMAL, init_flag, interface); |
| 456 } | 470 } |
| 457 | 471 |
| 458 | 472 |
| 459 Variable* Scope::DeclareDynamicGlobal(Handle<String> name) { | 473 Variable* Scope::DeclareDynamicGlobal(const AstString* name) { |
| 460 ASSERT(is_global_scope()); | 474 ASSERT(is_global_scope()); |
| 461 return variables_.Declare(this, | 475 return variables_.Declare(this, |
| 462 name, | 476 name, |
| 463 DYNAMIC_GLOBAL, | 477 DYNAMIC_GLOBAL, |
| 464 true, | 478 true, |
| 465 Variable::NORMAL, | 479 Variable::NORMAL, |
| 466 kCreatedInitialized); | 480 kCreatedInitialized); |
| 467 } | 481 } |
| 468 | 482 |
| 469 | 483 |
| 470 void Scope::RemoveUnresolved(VariableProxy* var) { | 484 void Scope::RemoveUnresolved(VariableProxy* var) { |
| 471 // Most likely (always?) any variable we want to remove | 485 // Most likely (always?) any variable we want to remove |
| 472 // was just added before, so we search backwards. | 486 // was just added before, so we search backwards. |
| 473 for (int i = unresolved_.length(); i-- > 0;) { | 487 for (int i = unresolved_.length(); i-- > 0;) { |
| 474 if (unresolved_[i] == var) { | 488 if (unresolved_[i] == var) { |
| 475 unresolved_.Remove(i); | 489 unresolved_.Remove(i); |
| 476 return; | 490 return; |
| 477 } | 491 } |
| 478 } | 492 } |
| 479 } | 493 } |
| 480 | 494 |
| 481 | 495 |
| 482 Variable* Scope::NewInternal(Handle<String> name) { | 496 Variable* Scope::NewInternal(const AstString* name) { |
| 483 ASSERT(!already_resolved()); | 497 ASSERT(!already_resolved()); |
| 484 Variable* var = new(zone()) Variable(this, | 498 Variable* var = new(zone()) Variable(this, |
| 485 name, | 499 name, |
| 486 INTERNAL, | 500 INTERNAL, |
| 487 false, | 501 false, |
| 488 Variable::NORMAL, | 502 Variable::NORMAL, |
| 489 kCreatedInitialized); | 503 kCreatedInitialized); |
| 490 internals_.Add(var, zone()); | 504 internals_.Add(var, zone()); |
| 491 return var; | 505 return var; |
| 492 } | 506 } |
| 493 | 507 |
| 494 | 508 |
| 495 Variable* Scope::NewTemporary(Handle<String> name) { | 509 Variable* Scope::NewTemporary(const AstString* name) { |
| 496 ASSERT(!already_resolved()); | 510 ASSERT(!already_resolved()); |
| 497 Variable* var = new(zone()) Variable(this, | 511 Variable* var = new(zone()) Variable(this, |
| 498 name, | 512 name, |
| 499 TEMPORARY, | 513 TEMPORARY, |
| 500 true, | 514 true, |
| 501 Variable::NORMAL, | 515 Variable::NORMAL, |
| 502 kCreatedInitialized); | 516 kCreatedInitialized); |
| 503 temps_.Add(var, zone()); | 517 temps_.Add(var, zone()); |
| 504 return var; | 518 return var; |
| 505 } | 519 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 523 ASSERT(HasIllegalRedeclaration()); | 537 ASSERT(HasIllegalRedeclaration()); |
| 524 illegal_redecl_->Accept(visitor); | 538 illegal_redecl_->Accept(visitor); |
| 525 } | 539 } |
| 526 | 540 |
| 527 | 541 |
| 528 Declaration* Scope::CheckConflictingVarDeclarations() { | 542 Declaration* Scope::CheckConflictingVarDeclarations() { |
| 529 int length = decls_.length(); | 543 int length = decls_.length(); |
| 530 for (int i = 0; i < length; i++) { | 544 for (int i = 0; i < length; i++) { |
| 531 Declaration* decl = decls_[i]; | 545 Declaration* decl = decls_[i]; |
| 532 if (decl->mode() != VAR) continue; | 546 if (decl->mode() != VAR) continue; |
| 533 Handle<String> name = decl->proxy()->name(); | 547 const AstString* name = decl->proxy()->raw_name(); |
| 534 | 548 |
| 535 // Iterate through all scopes until and including the declaration scope. | 549 // Iterate through all scopes until and including the declaration scope. |
| 536 Scope* previous = NULL; | 550 Scope* previous = NULL; |
| 537 Scope* current = decl->scope(); | 551 Scope* current = decl->scope(); |
| 538 do { | 552 do { |
| 539 // There is a conflict if there exists a non-VAR binding. | 553 // There is a conflict if there exists a non-VAR binding. |
| 540 Variable* other_var = current->variables_.Lookup(name); | 554 Variable* other_var = current->variables_.Lookup(name); |
| 541 if (other_var != NULL && other_var->mode() != VAR) { | 555 if (other_var != NULL && other_var->mode() != VAR) { |
| 542 return decl; | 556 return decl; |
| 543 } | 557 } |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 766 UNREACHABLE(); | 780 UNREACHABLE(); |
| 767 return NULL; | 781 return NULL; |
| 768 } | 782 } |
| 769 | 783 |
| 770 | 784 |
| 771 static void Indent(int n, const char* str) { | 785 static void Indent(int n, const char* str) { |
| 772 PrintF("%*s%s", n, "", str); | 786 PrintF("%*s%s", n, "", str); |
| 773 } | 787 } |
| 774 | 788 |
| 775 | 789 |
| 776 static void PrintName(Handle<String> name) { | 790 static void PrintName(const AstString* name) { |
| 777 SmartArrayPointer<char> s = name->ToCString(DISALLOW_NULLS); | 791 PrintF("%.*s", name->length(), name->raw_data()); |
| 778 PrintF("%s", s.get()); | |
| 779 } | 792 } |
| 780 | 793 |
| 781 | 794 |
| 782 static void PrintLocation(Variable* var) { | 795 static void PrintLocation(Variable* var) { |
| 783 switch (var->location()) { | 796 switch (var->location()) { |
| 784 case Variable::UNALLOCATED: | 797 case Variable::UNALLOCATED: |
| 785 break; | 798 break; |
| 786 case Variable::PARAMETER: | 799 case Variable::PARAMETER: |
| 787 PrintF("parameter[%d]", var->index()); | 800 PrintF("parameter[%d]", var->index()); |
| 788 break; | 801 break; |
| 789 case Variable::LOCAL: | 802 case Variable::LOCAL: |
| 790 PrintF("local[%d]", var->index()); | 803 PrintF("local[%d]", var->index()); |
| 791 break; | 804 break; |
| 792 case Variable::CONTEXT: | 805 case Variable::CONTEXT: |
| 793 PrintF("context[%d]", var->index()); | 806 PrintF("context[%d]", var->index()); |
| 794 break; | 807 break; |
| 795 case Variable::LOOKUP: | 808 case Variable::LOOKUP: |
| 796 PrintF("lookup"); | 809 PrintF("lookup"); |
| 797 break; | 810 break; |
| 798 } | 811 } |
| 799 } | 812 } |
| 800 | 813 |
| 801 | 814 |
| 802 static void PrintVar(int indent, Variable* var) { | 815 static void PrintVar(int indent, Variable* var) { |
| 803 if (var->is_used() || !var->IsUnallocated()) { | 816 if (var->is_used() || !var->IsUnallocated()) { |
| 804 Indent(indent, Variable::Mode2String(var->mode())); | 817 Indent(indent, Variable::Mode2String(var->mode())); |
| 805 PrintF(" "); | 818 PrintF(" "); |
| 806 PrintName(var->name()); | 819 PrintName(var->raw_name()); |
| 807 PrintF("; // "); | 820 PrintF("; // "); |
| 808 PrintLocation(var); | 821 PrintLocation(var); |
| 809 if (var->has_forced_context_allocation()) { | 822 if (var->has_forced_context_allocation()) { |
| 810 if (!var->IsUnallocated()) PrintF(", "); | 823 if (!var->IsUnallocated()) PrintF(", "); |
| 811 PrintF("forced context allocation"); | 824 PrintF("forced context allocation"); |
| 812 } | 825 } |
| 813 PrintF("\n"); | 826 PrintF("\n"); |
| 814 } | 827 } |
| 815 } | 828 } |
| 816 | 829 |
| 817 | 830 |
| 818 static void PrintMap(int indent, VariableMap* map) { | 831 static void PrintMap(int indent, VariableMap* map) { |
| 819 for (VariableMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) { | 832 for (VariableMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) { |
| 820 Variable* var = reinterpret_cast<Variable*>(p->value); | 833 Variable* var = reinterpret_cast<Variable*>(p->value); |
| 821 PrintVar(indent, var); | 834 PrintVar(indent, var); |
| 822 } | 835 } |
| 823 } | 836 } |
| 824 | 837 |
| 825 | 838 |
| 826 void Scope::Print(int n) { | 839 void Scope::Print(int n) { |
| 827 int n0 = (n > 0 ? n : 0); | 840 int n0 = (n > 0 ? n : 0); |
| 828 int n1 = n0 + 2; // indentation | 841 int n1 = n0 + 2; // indentation |
| 829 | 842 |
| 830 // Print header. | 843 // Print header. |
| 831 Indent(n0, Header(scope_type_)); | 844 Indent(n0, Header(scope_type_)); |
| 832 if (scope_name_->length() > 0) { | 845 if (!scope_name_->IsEmpty()) { |
| 833 PrintF(" "); | 846 PrintF(" "); |
| 834 PrintName(scope_name_); | 847 PrintName(scope_name_); |
| 835 } | 848 } |
| 836 | 849 |
| 837 // Print parameters, if any. | 850 // Print parameters, if any. |
| 838 if (is_function_scope()) { | 851 if (is_function_scope()) { |
| 839 PrintF(" ("); | 852 PrintF(" ("); |
| 840 for (int i = 0; i < params_.length(); i++) { | 853 for (int i = 0; i < params_.length(); i++) { |
| 841 if (i > 0) PrintF(", "); | 854 if (i > 0) PrintF(", "); |
| 842 PrintName(params_[i]->name()); | 855 PrintName(params_[i]->raw_name()); |
| 843 } | 856 } |
| 844 PrintF(")"); | 857 PrintF(")"); |
| 845 } | 858 } |
| 846 | 859 |
| 847 PrintF(" { // (%d, %d)\n", start_position(), end_position()); | 860 PrintF(" { // (%d, %d)\n", start_position(), end_position()); |
| 848 | 861 |
| 849 // Function name, if any (named function literals, only). | 862 // Function name, if any (named function literals, only). |
| 850 if (function_ != NULL) { | 863 if (function_ != NULL) { |
| 851 Indent(n1, "// (local) function name: "); | 864 Indent(n1, "// (local) function name: "); |
| 852 PrintName(function_->proxy()->name()); | 865 PrintName(function_->proxy()->raw_name()); |
| 853 PrintF("\n"); | 866 PrintF("\n"); |
| 854 } | 867 } |
| 855 | 868 |
| 856 // Scope info. | 869 // Scope info. |
| 857 if (HasTrivialOuterContext()) { | 870 if (HasTrivialOuterContext()) { |
| 858 Indent(n1, "// scope has trivial outer context\n"); | 871 Indent(n1, "// scope has trivial outer context\n"); |
| 859 } | 872 } |
| 860 if (strict_mode() == STRICT) { | 873 if (strict_mode() == STRICT) { |
| 861 Indent(n1, "// strict mode scope\n"); | 874 Indent(n1, "// strict mode scope\n"); |
| 862 } | 875 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 910 PrintF("\n"); | 923 PrintF("\n"); |
| 911 inner_scopes_[i]->Print(n1); | 924 inner_scopes_[i]->Print(n1); |
| 912 } | 925 } |
| 913 } | 926 } |
| 914 | 927 |
| 915 Indent(n0, "}\n"); | 928 Indent(n0, "}\n"); |
| 916 } | 929 } |
| 917 #endif // DEBUG | 930 #endif // DEBUG |
| 918 | 931 |
| 919 | 932 |
| 920 Variable* Scope::NonLocal(Handle<String> name, VariableMode mode) { | 933 Variable* Scope::NonLocal(const AstString* name, VariableMode mode) { |
| 921 if (dynamics_ == NULL) dynamics_ = new(zone()) DynamicScopePart(zone()); | 934 if (dynamics_ == NULL) dynamics_ = new (zone()) DynamicScopePart(zone()); |
| 922 VariableMap* map = dynamics_->GetMap(mode); | 935 VariableMap* map = dynamics_->GetMap(mode); |
| 923 Variable* var = map->Lookup(name); | 936 Variable* var = map->Lookup(name); |
| 924 if (var == NULL) { | 937 if (var == NULL) { |
| 925 // Declare a new non-local. | 938 // Declare a new non-local. |
| 926 InitializationFlag init_flag = (mode == VAR) | 939 InitializationFlag init_flag = (mode == VAR) |
| 927 ? kCreatedInitialized : kNeedsInitialization; | 940 ? kCreatedInitialized : kNeedsInitialization; |
| 928 var = map->Declare(NULL, | 941 var = map->Declare(NULL, |
| 929 name, | 942 name, |
| 930 mode, | 943 mode, |
| 931 true, | 944 true, |
| 932 Variable::NORMAL, | 945 Variable::NORMAL, |
| 933 init_flag); | 946 init_flag); |
| 934 // Allocate it by giving it a dynamic lookup. | 947 // Allocate it by giving it a dynamic lookup. |
| 935 var->AllocateTo(Variable::LOOKUP, -1); | 948 var->AllocateTo(Variable::LOOKUP, -1); |
| 936 } | 949 } |
| 937 return var; | 950 return var; |
| 938 } | 951 } |
| 939 | 952 |
| 940 | 953 |
| 941 Variable* Scope::LookupRecursive(Handle<String> name, | 954 Variable* Scope::LookupRecursive(const AstString* name, |
| 942 BindingKind* binding_kind, | 955 BindingKind* binding_kind, |
| 943 AstNodeFactory<AstNullVisitor>* factory) { | 956 AstNodeFactory<AstNullVisitor>* factory) { |
| 944 ASSERT(binding_kind != NULL); | 957 ASSERT(binding_kind != NULL); |
| 945 if (already_resolved() && is_with_scope()) { | 958 if (already_resolved() && is_with_scope()) { |
| 946 // Short-cut: if the scope is deserialized from a scope info, variable | 959 // Short-cut: if the scope is deserialized from a scope info, variable |
| 947 // allocation is already fixed. We can simply return with dynamic lookup. | 960 // allocation is already fixed. We can simply return with dynamic lookup. |
| 948 *binding_kind = DYNAMIC_LOOKUP; | 961 *binding_kind = DYNAMIC_LOOKUP; |
| 949 return NULL; | 962 return NULL; |
| 950 } | 963 } |
| 951 | 964 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1005 VariableProxy* proxy, | 1018 VariableProxy* proxy, |
| 1006 AstNodeFactory<AstNullVisitor>* factory) { | 1019 AstNodeFactory<AstNullVisitor>* factory) { |
| 1007 ASSERT(info->global_scope()->is_global_scope()); | 1020 ASSERT(info->global_scope()->is_global_scope()); |
| 1008 | 1021 |
| 1009 // If the proxy is already resolved there's nothing to do | 1022 // If the proxy is already resolved there's nothing to do |
| 1010 // (functions and consts may be resolved by the parser). | 1023 // (functions and consts may be resolved by the parser). |
| 1011 if (proxy->var() != NULL) return true; | 1024 if (proxy->var() != NULL) return true; |
| 1012 | 1025 |
| 1013 // Otherwise, try to resolve the variable. | 1026 // Otherwise, try to resolve the variable. |
| 1014 BindingKind binding_kind; | 1027 BindingKind binding_kind; |
| 1015 Variable* var = LookupRecursive(proxy->name(), &binding_kind, factory); | 1028 Variable* var = LookupRecursive(proxy->raw_name(), &binding_kind, factory); |
| 1016 switch (binding_kind) { | 1029 switch (binding_kind) { |
| 1017 case BOUND: | 1030 case BOUND: |
| 1018 // We found a variable binding. | 1031 // We found a variable binding. |
| 1019 break; | 1032 break; |
| 1020 | 1033 |
| 1021 case BOUND_EVAL_SHADOWED: | 1034 case BOUND_EVAL_SHADOWED: |
| 1022 // We either found a variable binding that might be shadowed by eval or | 1035 // We either found a variable binding that might be shadowed by eval or |
| 1023 // gave up on it (e.g. by encountering a local with the same in the outer | 1036 // gave up on it (e.g. by encountering a local with the same in the outer |
| 1024 // scope which was not promoted to a context, this can happen if we use | 1037 // scope which was not promoted to a context, this can happen if we use |
| 1025 // debugger to evaluate arbitrary expressions at a break point). | 1038 // debugger to evaluate arbitrary expressions at a break point). |
| 1026 if (var->IsGlobalObjectProperty()) { | 1039 if (var->IsGlobalObjectProperty()) { |
| 1027 var = NonLocal(proxy->name(), DYNAMIC_GLOBAL); | 1040 var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL); |
| 1028 } else if (var->is_dynamic()) { | 1041 } else if (var->is_dynamic()) { |
| 1029 var = NonLocal(proxy->name(), DYNAMIC); | 1042 var = NonLocal(proxy->raw_name(), DYNAMIC); |
| 1030 } else { | 1043 } else { |
| 1031 Variable* invalidated = var; | 1044 Variable* invalidated = var; |
| 1032 var = NonLocal(proxy->name(), DYNAMIC_LOCAL); | 1045 var = NonLocal(proxy->raw_name(), DYNAMIC_LOCAL); |
| 1033 var->set_local_if_not_shadowed(invalidated); | 1046 var->set_local_if_not_shadowed(invalidated); |
| 1034 } | 1047 } |
| 1035 break; | 1048 break; |
| 1036 | 1049 |
| 1037 case UNBOUND: | 1050 case UNBOUND: |
| 1038 // No binding has been found. Declare a variable on the global object. | 1051 // No binding has been found. Declare a variable on the global object. |
| 1039 var = info->global_scope()->DeclareDynamicGlobal(proxy->name()); | 1052 var = info->global_scope()->DeclareDynamicGlobal(proxy->raw_name()); |
| 1040 break; | 1053 break; |
| 1041 | 1054 |
| 1042 case UNBOUND_EVAL_SHADOWED: | 1055 case UNBOUND_EVAL_SHADOWED: |
| 1043 // No binding has been found. But some scope makes a sloppy 'eval' call. | 1056 // No binding has been found. But some scope makes a sloppy 'eval' call. |
| 1044 var = NonLocal(proxy->name(), DYNAMIC_GLOBAL); | 1057 var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL); |
| 1045 break; | 1058 break; |
| 1046 | 1059 |
| 1047 case DYNAMIC_LOOKUP: | 1060 case DYNAMIC_LOOKUP: |
| 1048 // The variable could not be resolved statically. | 1061 // The variable could not be resolved statically. |
| 1049 var = NonLocal(proxy->name(), DYNAMIC); | 1062 var = NonLocal(proxy->raw_name(), DYNAMIC); |
| 1050 break; | 1063 break; |
| 1051 } | 1064 } |
| 1052 | 1065 |
| 1053 ASSERT(var != NULL); | 1066 ASSERT(var != NULL); |
| 1054 | 1067 |
| 1055 if (FLAG_harmony_scoping && strict_mode() == STRICT && | 1068 if (FLAG_harmony_scoping && strict_mode() == STRICT && |
| 1056 var->is_const_mode() && proxy->IsLValue()) { | 1069 var->is_const_mode() && proxy->IsLValue()) { |
| 1057 // Assignment to const. Throw a syntax error. | 1070 // Assignment to const. Throw a syntax error. |
| 1058 MessageLocation location( | 1071 MessageLocation location( |
| 1059 info->script(), proxy->position(), proxy->position()); | 1072 info->script(), proxy->position(), proxy->position()); |
| 1060 Isolate* isolate = info->isolate(); | 1073 Isolate* isolate = info->isolate(); |
| 1061 Factory* factory = isolate->factory(); | 1074 Factory* factory = isolate->factory(); |
| 1062 Handle<JSArray> array = factory->NewJSArray(0); | 1075 Handle<JSArray> array = factory->NewJSArray(0); |
| 1063 Handle<Object> result = | 1076 Handle<Object> result = |
| 1064 factory->NewSyntaxError("harmony_const_assign", array); | 1077 factory->NewSyntaxError("harmony_const_assign", array); |
| 1065 isolate->Throw(*result, &location); | 1078 isolate->Throw(*result, &location); |
| 1066 return false; | 1079 return false; |
| 1067 } | 1080 } |
| 1068 | 1081 |
| 1069 if (FLAG_harmony_modules) { | 1082 if (FLAG_harmony_modules) { |
| 1070 bool ok; | 1083 bool ok; |
| 1071 #ifdef DEBUG | 1084 #ifdef DEBUG |
| 1072 if (FLAG_print_interface_details) | 1085 if (FLAG_print_interface_details) { |
| 1073 PrintF("# Resolve %s:\n", var->name()->ToAsciiArray()); | 1086 PrintF("# Resolve %.*s:\n", var->raw_name()->length(), |
| 1087 var->raw_name()->raw_data()); |
| 1088 } |
| 1074 #endif | 1089 #endif |
| 1075 proxy->interface()->Unify(var->interface(), zone(), &ok); | 1090 proxy->interface()->Unify(var->interface(), zone(), &ok); |
| 1076 if (!ok) { | 1091 if (!ok) { |
| 1077 #ifdef DEBUG | 1092 #ifdef DEBUG |
| 1078 if (FLAG_print_interfaces) { | 1093 if (FLAG_print_interfaces) { |
| 1079 PrintF("SCOPES TYPE ERROR\n"); | 1094 PrintF("SCOPES TYPE ERROR\n"); |
| 1080 PrintF("proxy: "); | 1095 PrintF("proxy: "); |
| 1081 proxy->interface()->Print(); | 1096 proxy->interface()->Print(); |
| 1082 PrintF("var: "); | 1097 PrintF("var: "); |
| 1083 var->interface()->Print(); | 1098 var->interface()->Print(); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1143 } | 1158 } |
| 1144 | 1159 |
| 1145 return scope_calls_eval_ || inner_scope_calls_eval_; | 1160 return scope_calls_eval_ || inner_scope_calls_eval_; |
| 1146 } | 1161 } |
| 1147 | 1162 |
| 1148 | 1163 |
| 1149 bool Scope::MustAllocate(Variable* var) { | 1164 bool Scope::MustAllocate(Variable* var) { |
| 1150 // Give var a read/write use if there is a chance it might be accessed | 1165 // Give var a read/write use if there is a chance it might be accessed |
| 1151 // via an eval() call. This is only possible if the variable has a | 1166 // via an eval() call. This is only possible if the variable has a |
| 1152 // visible name. | 1167 // visible name. |
| 1153 if ((var->is_this() || var->name()->length() > 0) && | 1168 if ((var->is_this() || !var->raw_name()->IsEmpty()) && |
| 1154 (var->has_forced_context_allocation() || | 1169 (var->has_forced_context_allocation() || |
| 1155 scope_calls_eval_ || | 1170 scope_calls_eval_ || |
| 1156 inner_scope_calls_eval_ || | 1171 inner_scope_calls_eval_ || |
| 1157 scope_contains_with_ || | 1172 scope_contains_with_ || |
| 1158 is_catch_scope() || | 1173 is_catch_scope() || |
| 1159 is_block_scope() || | 1174 is_block_scope() || |
| 1160 is_module_scope() || | 1175 is_module_scope() || |
| 1161 is_global_scope())) { | 1176 is_global_scope())) { |
| 1162 var->set_is_used(true); | 1177 var->set_is_used(true); |
| 1163 } | 1178 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1204 } | 1219 } |
| 1205 | 1220 |
| 1206 | 1221 |
| 1207 void Scope::AllocateHeapSlot(Variable* var) { | 1222 void Scope::AllocateHeapSlot(Variable* var) { |
| 1208 var->AllocateTo(Variable::CONTEXT, num_heap_slots_++); | 1223 var->AllocateTo(Variable::CONTEXT, num_heap_slots_++); |
| 1209 } | 1224 } |
| 1210 | 1225 |
| 1211 | 1226 |
| 1212 void Scope::AllocateParameterLocals() { | 1227 void Scope::AllocateParameterLocals() { |
| 1213 ASSERT(is_function_scope()); | 1228 ASSERT(is_function_scope()); |
| 1214 Variable* arguments = LookupLocal(isolate_->factory()->arguments_string()); | 1229 Variable* arguments = LookupLocal(ast_value_factory_->arguments_string()); |
| 1215 ASSERT(arguments != NULL); // functions have 'arguments' declared implicitly | 1230 ASSERT(arguments != NULL); // functions have 'arguments' declared implicitly |
| 1216 | 1231 |
| 1217 bool uses_sloppy_arguments = false; | 1232 bool uses_sloppy_arguments = false; |
| 1218 | 1233 |
| 1219 if (MustAllocate(arguments) && !HasArgumentsParameter()) { | 1234 if (MustAllocate(arguments) && !HasArgumentsParameter()) { |
| 1220 // 'arguments' is used. Unless there is also a parameter called | 1235 // 'arguments' is used. Unless there is also a parameter called |
| 1221 // 'arguments', we must be conservative and allocate all parameters to | 1236 // 'arguments', we must be conservative and allocate all parameters to |
| 1222 // the context assuming they will be captured by the arguments object. | 1237 // the context assuming they will be captured by the arguments object. |
| 1223 // If we have a parameter named 'arguments', a (new) value is always | 1238 // If we have a parameter named 'arguments', a (new) value is always |
| 1224 // assigned to it via the function invocation. Then 'arguments' denotes | 1239 // assigned to it via the function invocation. Then 'arguments' denotes |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1345 | 1360 |
| 1346 // Allocation done. | 1361 // Allocation done. |
| 1347 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); | 1362 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); |
| 1348 } | 1363 } |
| 1349 | 1364 |
| 1350 | 1365 |
| 1351 void Scope::AllocateModulesRecursively(Scope* host_scope) { | 1366 void Scope::AllocateModulesRecursively(Scope* host_scope) { |
| 1352 if (already_resolved()) return; | 1367 if (already_resolved()) return; |
| 1353 if (is_module_scope()) { | 1368 if (is_module_scope()) { |
| 1354 ASSERT(interface_->IsFrozen()); | 1369 ASSERT(interface_->IsFrozen()); |
| 1355 Handle<String> name = isolate_->factory()->InternalizeOneByteString( | |
| 1356 STATIC_ASCII_VECTOR(".module")); | |
| 1357 ASSERT(module_var_ == NULL); | 1370 ASSERT(module_var_ == NULL); |
| 1358 module_var_ = host_scope->NewInternal(name); | 1371 module_var_ = |
| 1372 host_scope->NewInternal(ast_value_factory_->dot_module_string()); |
| 1359 ++host_scope->num_modules_; | 1373 ++host_scope->num_modules_; |
| 1360 } | 1374 } |
| 1361 | 1375 |
| 1362 for (int i = 0; i < inner_scopes_.length(); i++) { | 1376 for (int i = 0; i < inner_scopes_.length(); i++) { |
| 1363 Scope* inner_scope = inner_scopes_.at(i); | 1377 Scope* inner_scope = inner_scopes_.at(i); |
| 1364 inner_scope->AllocateModulesRecursively(host_scope); | 1378 inner_scope->AllocateModulesRecursively(host_scope); |
| 1365 } | 1379 } |
| 1366 } | 1380 } |
| 1367 | 1381 |
| 1368 | 1382 |
| 1369 int Scope::StackLocalCount() const { | 1383 int Scope::StackLocalCount() const { |
| 1370 return num_stack_slots() - | 1384 return num_stack_slots() - |
| 1371 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); | 1385 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); |
| 1372 } | 1386 } |
| 1373 | 1387 |
| 1374 | 1388 |
| 1375 int Scope::ContextLocalCount() const { | 1389 int Scope::ContextLocalCount() const { |
| 1376 if (num_heap_slots() == 0) return 0; | 1390 if (num_heap_slots() == 0) return 0; |
| 1377 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 1391 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
| 1378 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); | 1392 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); |
| 1379 } | 1393 } |
| 1380 | 1394 |
| 1381 } } // namespace v8::internal | 1395 } } // namespace v8::internal |
| OLD | NEW |