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