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