OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 <stdlib.h> | 5 #include <stdlib.h> |
6 | 6 |
7 #include "src/v8.h" | 7 #include "src/v8.h" |
8 | 8 |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/scopeinfo.h" | 10 #include "src/scopeinfo.h" |
11 #include "src/scopes.h" | 11 #include "src/scopes.h" |
12 | 12 |
13 namespace v8 { | 13 namespace v8 { |
14 namespace internal { | 14 namespace internal { |
15 | 15 |
16 | 16 |
17 Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, | 17 Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, |
18 Scope* scope) { | 18 Scope* scope) { |
19 // Collect stack and context locals. | 19 // Collect stack and context locals. |
20 ZoneList<Variable*> stack_locals(scope->StackLocalCount(), zone); | 20 ZoneList<Variable*> stack_locals(scope->StackLocalCount(), zone); |
21 ZoneList<Variable*> context_locals(scope->ContextLocalCount(), zone); | 21 ZoneList<Variable*> context_locals(scope->ContextLocalCount(), zone); |
| 22 ZoneList<Variable*> context_globals(scope->ContextGlobalCount(), zone); |
22 ZoneList<Variable*> strong_mode_free_variables(0, zone); | 23 ZoneList<Variable*> strong_mode_free_variables(0, zone); |
23 | 24 |
24 scope->CollectStackAndContextLocals(&stack_locals, &context_locals, | 25 scope->CollectStackAndContextLocals(&stack_locals, &context_locals, |
| 26 &context_globals, |
25 &strong_mode_free_variables); | 27 &strong_mode_free_variables); |
26 const int stack_local_count = stack_locals.length(); | 28 const int stack_local_count = stack_locals.length(); |
27 const int context_local_count = context_locals.length(); | 29 const int context_local_count = context_locals.length(); |
| 30 const int context_global_count = context_globals.length(); |
28 const int strong_mode_free_variable_count = | 31 const int strong_mode_free_variable_count = |
29 strong_mode_free_variables.length(); | 32 strong_mode_free_variables.length(); |
30 // Make sure we allocate the correct amount. | 33 // Make sure we allocate the correct amount. |
31 DCHECK(scope->ContextLocalCount() == context_local_count); | 34 DCHECK_EQ(scope->ContextLocalCount(), context_local_count); |
| 35 DCHECK_EQ(scope->ContextGlobalCount(), context_global_count); |
32 | 36 |
33 bool simple_parameter_list = | 37 bool simple_parameter_list = |
34 scope->is_function_scope() ? scope->is_simple_parameter_list() : true; | 38 scope->is_function_scope() ? scope->is_simple_parameter_list() : true; |
35 | 39 |
36 // Determine use and location of the "this" binding if it is present. | 40 // Determine use and location of the "this" binding if it is present. |
37 VariableAllocationInfo receiver_info; | 41 VariableAllocationInfo receiver_info; |
38 if (scope->has_this_declaration()) { | 42 if (scope->has_this_declaration()) { |
39 Variable* var = scope->receiver(); | 43 Variable* var = scope->receiver(); |
40 if (!var->is_used()) { | 44 if (!var->is_used()) { |
41 receiver_info = UNUSED; | 45 receiver_info = UNUSED; |
(...skipping 18 matching lines...) Expand all Loading... |
60 function_name_info = CONTEXT; | 64 function_name_info = CONTEXT; |
61 } else { | 65 } else { |
62 DCHECK(var->IsStackLocal()); | 66 DCHECK(var->IsStackLocal()); |
63 function_name_info = STACK; | 67 function_name_info = STACK; |
64 } | 68 } |
65 function_variable_mode = var->mode(); | 69 function_variable_mode = var->mode(); |
66 } else { | 70 } else { |
67 function_name_info = NONE; | 71 function_name_info = NONE; |
68 function_variable_mode = VAR; | 72 function_variable_mode = VAR; |
69 } | 73 } |
| 74 DCHECK(context_global_count == 0 || scope->scope_type() == SCRIPT_SCOPE); |
70 | 75 |
71 const bool has_function_name = function_name_info != NONE; | 76 const bool has_function_name = function_name_info != NONE; |
72 const bool has_receiver = receiver_info == STACK || receiver_info == CONTEXT; | 77 const bool has_receiver = receiver_info == STACK || receiver_info == CONTEXT; |
73 const int parameter_count = scope->num_parameters(); | 78 const int parameter_count = scope->num_parameters(); |
74 const int length = kVariablePartIndex + parameter_count + | 79 const int length = kVariablePartIndex + parameter_count + |
75 (1 + stack_local_count) + 2 * context_local_count + | 80 (1 + stack_local_count) + 2 * context_local_count + |
| 81 2 * context_global_count + |
76 3 * strong_mode_free_variable_count + | 82 3 * strong_mode_free_variable_count + |
77 (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0); | 83 (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0); |
78 | 84 |
79 Factory* factory = isolate->factory(); | 85 Factory* factory = isolate->factory(); |
80 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); | 86 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); |
81 | 87 |
82 // Encode the flags. | 88 // Encode the flags. |
83 int flags = ScopeTypeField::encode(scope->scope_type()) | | 89 int flags = ScopeTypeField::encode(scope->scope_type()) | |
84 CallsEvalField::encode(scope->calls_eval()) | | 90 CallsEvalField::encode(scope->calls_eval()) | |
85 LanguageModeField::encode(scope->language_mode()) | | 91 LanguageModeField::encode(scope->language_mode()) | |
86 ReceiverVariableField::encode(receiver_info) | | 92 ReceiverVariableField::encode(receiver_info) | |
87 FunctionVariableField::encode(function_name_info) | | 93 FunctionVariableField::encode(function_name_info) | |
88 FunctionVariableMode::encode(function_variable_mode) | | 94 FunctionVariableMode::encode(function_variable_mode) | |
89 AsmModuleField::encode(scope->asm_module()) | | 95 AsmModuleField::encode(scope->asm_module()) | |
90 AsmFunctionField::encode(scope->asm_function()) | | 96 AsmFunctionField::encode(scope->asm_function()) | |
91 IsSimpleParameterListField::encode(simple_parameter_list) | | 97 IsSimpleParameterListField::encode(simple_parameter_list) | |
92 FunctionKindField::encode(scope->function_kind()); | 98 FunctionKindField::encode(scope->function_kind()); |
93 scope_info->SetFlags(flags); | 99 scope_info->SetFlags(flags); |
94 scope_info->SetParameterCount(parameter_count); | 100 scope_info->SetParameterCount(parameter_count); |
95 scope_info->SetStackLocalCount(stack_local_count); | 101 scope_info->SetStackLocalCount(stack_local_count); |
96 scope_info->SetContextLocalCount(context_local_count); | 102 scope_info->SetContextLocalCount(context_local_count); |
| 103 scope_info->SetContextGlobalCount(context_global_count); |
97 scope_info->SetStrongModeFreeVariableCount(strong_mode_free_variable_count); | 104 scope_info->SetStrongModeFreeVariableCount(strong_mode_free_variable_count); |
98 | 105 |
99 int index = kVariablePartIndex; | 106 int index = kVariablePartIndex; |
100 // Add parameters. | 107 // Add parameters. |
101 DCHECK(index == scope_info->ParameterEntriesIndex()); | 108 DCHECK(index == scope_info->ParameterEntriesIndex()); |
102 for (int i = 0; i < parameter_count; ++i) { | 109 for (int i = 0; i < parameter_count; ++i) { |
103 scope_info->set(index++, *scope->parameter(i)->name()); | 110 scope_info->set(index++, *scope->parameter(i)->name()); |
104 } | 111 } |
105 | 112 |
106 // Add stack locals' names. We are assuming that the stack locals' | 113 // Add stack locals' names. We are assuming that the stack locals' |
(...skipping 20 matching lines...) Expand all Loading... |
127 // order with the variable list anymore. Thus, we first need to sort them by | 134 // order with the variable list anymore. Thus, we first need to sort them by |
128 // context slot index before adding them to the ScopeInfo object. | 135 // context slot index before adding them to the ScopeInfo object. |
129 context_locals.Sort(&Variable::CompareIndex); | 136 context_locals.Sort(&Variable::CompareIndex); |
130 | 137 |
131 // Add context locals' names. | 138 // Add context locals' names. |
132 DCHECK(index == scope_info->ContextLocalNameEntriesIndex()); | 139 DCHECK(index == scope_info->ContextLocalNameEntriesIndex()); |
133 for (int i = 0; i < context_local_count; ++i) { | 140 for (int i = 0; i < context_local_count; ++i) { |
134 scope_info->set(index++, *context_locals[i]->name()); | 141 scope_info->set(index++, *context_locals[i]->name()); |
135 } | 142 } |
136 | 143 |
| 144 // Add context globals' names. |
| 145 DCHECK(index == scope_info->ContextGlobalNameEntriesIndex()); |
| 146 for (int i = 0; i < context_global_count; ++i) { |
| 147 scope_info->set(index++, *context_globals[i]->name()); |
| 148 } |
| 149 |
137 // Add context locals' info. | 150 // Add context locals' info. |
138 DCHECK(index == scope_info->ContextLocalInfoEntriesIndex()); | 151 DCHECK(index == scope_info->ContextLocalInfoEntriesIndex()); |
139 for (int i = 0; i < context_local_count; ++i) { | 152 for (int i = 0; i < context_local_count; ++i) { |
140 Variable* var = context_locals[i]; | 153 Variable* var = context_locals[i]; |
141 uint32_t value = | 154 uint32_t value = |
142 ContextLocalMode::encode(var->mode()) | | 155 ContextLocalMode::encode(var->mode()) | |
143 ContextLocalInitFlag::encode(var->initialization_flag()) | | 156 ContextLocalInitFlag::encode(var->initialization_flag()) | |
144 ContextLocalMaybeAssignedFlag::encode(var->maybe_assigned()); | 157 ContextLocalMaybeAssignedFlag::encode(var->maybe_assigned()); |
145 scope_info->set(index++, Smi::FromInt(value)); | 158 scope_info->set(index++, Smi::FromInt(value)); |
146 } | 159 } |
147 | 160 |
| 161 // Add context globals' info. |
| 162 DCHECK(index == scope_info->ContextGlobalInfoEntriesIndex()); |
| 163 for (int i = 0; i < context_global_count; ++i) { |
| 164 Variable* var = context_globals[i]; |
| 165 // TODO(ishell): do we need this kind of info for globals here? |
| 166 uint32_t value = |
| 167 ContextLocalMode::encode(var->mode()) | |
| 168 ContextLocalInitFlag::encode(var->initialization_flag()) | |
| 169 ContextLocalMaybeAssignedFlag::encode(var->maybe_assigned()); |
| 170 scope_info->set(index++, Smi::FromInt(value)); |
| 171 } |
| 172 |
148 DCHECK(index == scope_info->StrongModeFreeVariableNameEntriesIndex()); | 173 DCHECK(index == scope_info->StrongModeFreeVariableNameEntriesIndex()); |
149 for (int i = 0; i < strong_mode_free_variable_count; ++i) { | 174 for (int i = 0; i < strong_mode_free_variable_count; ++i) { |
150 scope_info->set(index++, *strong_mode_free_variables[i]->name()); | 175 scope_info->set(index++, *strong_mode_free_variables[i]->name()); |
151 } | 176 } |
152 | 177 |
153 DCHECK(index == scope_info->StrongModeFreeVariablePositionEntriesIndex()); | 178 DCHECK(index == scope_info->StrongModeFreeVariablePositionEntriesIndex()); |
154 for (int i = 0; i < strong_mode_free_variable_count; ++i) { | 179 for (int i = 0; i < strong_mode_free_variable_count; ++i) { |
155 // Unfortunately, the source code positions are stored as int even though | 180 // Unfortunately, the source code positions are stored as int even though |
156 // int32_t would be enough (given the maximum source code length). | 181 // int32_t would be enough (given the maximum source code length). |
157 Handle<Object> start_position = factory->NewNumberFromInt( | 182 Handle<Object> start_position = factory->NewNumberFromInt( |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 scope_info->ContextLength() == 0)); | 215 scope_info->ContextLength() == 0)); |
191 return scope_info; | 216 return scope_info; |
192 } | 217 } |
193 | 218 |
194 | 219 |
195 Handle<ScopeInfo> ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) { | 220 Handle<ScopeInfo> ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) { |
196 DCHECK(isolate->bootstrapper()->IsActive()); | 221 DCHECK(isolate->bootstrapper()->IsActive()); |
197 | 222 |
198 const int stack_local_count = 0; | 223 const int stack_local_count = 0; |
199 const int context_local_count = 1; | 224 const int context_local_count = 1; |
| 225 const int context_global_count = 0; |
200 const int strong_mode_free_variable_count = 0; | 226 const int strong_mode_free_variable_count = 0; |
201 const bool simple_parameter_list = true; | 227 const bool simple_parameter_list = true; |
202 const VariableAllocationInfo receiver_info = CONTEXT; | 228 const VariableAllocationInfo receiver_info = CONTEXT; |
203 const VariableAllocationInfo function_name_info = NONE; | 229 const VariableAllocationInfo function_name_info = NONE; |
204 const VariableMode function_variable_mode = VAR; | 230 const VariableMode function_variable_mode = VAR; |
205 const bool has_function_name = false; | 231 const bool has_function_name = false; |
206 const bool has_receiver = true; | 232 const bool has_receiver = true; |
207 const int parameter_count = 0; | 233 const int parameter_count = 0; |
208 const int length = kVariablePartIndex + parameter_count + | 234 const int length = kVariablePartIndex + parameter_count + |
209 (1 + stack_local_count) + 2 * context_local_count + | 235 (1 + stack_local_count) + 2 * context_local_count + |
| 236 2 * context_global_count + |
210 3 * strong_mode_free_variable_count + | 237 3 * strong_mode_free_variable_count + |
211 (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0); | 238 (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0); |
212 | 239 |
213 Factory* factory = isolate->factory(); | 240 Factory* factory = isolate->factory(); |
214 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); | 241 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); |
215 | 242 |
216 // Encode the flags. | 243 // Encode the flags. |
217 int flags = ScopeTypeField::encode(SCRIPT_SCOPE) | | 244 int flags = ScopeTypeField::encode(SCRIPT_SCOPE) | |
218 CallsEvalField::encode(false) | | 245 CallsEvalField::encode(false) | |
219 LanguageModeField::encode(SLOPPY) | | 246 LanguageModeField::encode(SLOPPY) | |
220 ReceiverVariableField::encode(receiver_info) | | 247 ReceiverVariableField::encode(receiver_info) | |
221 FunctionVariableField::encode(function_name_info) | | 248 FunctionVariableField::encode(function_name_info) | |
222 FunctionVariableMode::encode(function_variable_mode) | | 249 FunctionVariableMode::encode(function_variable_mode) | |
223 AsmModuleField::encode(false) | AsmFunctionField::encode(false) | | 250 AsmModuleField::encode(false) | AsmFunctionField::encode(false) | |
224 IsSimpleParameterListField::encode(simple_parameter_list) | | 251 IsSimpleParameterListField::encode(simple_parameter_list) | |
225 FunctionKindField::encode(FunctionKind::kNormalFunction); | 252 FunctionKindField::encode(FunctionKind::kNormalFunction); |
226 scope_info->SetFlags(flags); | 253 scope_info->SetFlags(flags); |
227 scope_info->SetParameterCount(parameter_count); | 254 scope_info->SetParameterCount(parameter_count); |
228 scope_info->SetStackLocalCount(stack_local_count); | 255 scope_info->SetStackLocalCount(stack_local_count); |
229 scope_info->SetContextLocalCount(context_local_count); | 256 scope_info->SetContextLocalCount(context_local_count); |
| 257 scope_info->SetContextGlobalCount(context_global_count); |
230 scope_info->SetStrongModeFreeVariableCount(strong_mode_free_variable_count); | 258 scope_info->SetStrongModeFreeVariableCount(strong_mode_free_variable_count); |
231 | 259 |
232 int index = kVariablePartIndex; | 260 int index = kVariablePartIndex; |
233 const int first_slot_index = 0; | 261 const int first_slot_index = 0; |
234 DCHECK(index == scope_info->StackLocalFirstSlotIndex()); | 262 DCHECK(index == scope_info->StackLocalFirstSlotIndex()); |
235 scope_info->set(index++, Smi::FromInt(first_slot_index)); | 263 scope_info->set(index++, Smi::FromInt(first_slot_index)); |
236 DCHECK(index == scope_info->StackLocalEntriesIndex()); | 264 DCHECK(index == scope_info->StackLocalEntriesIndex()); |
237 | 265 |
238 // Here we add info for context-allocated "this". | 266 // Here we add info for context-allocated "this". |
239 DCHECK(index == scope_info->ContextLocalNameEntriesIndex()); | 267 DCHECK(index == scope_info->ContextLocalNameEntriesIndex()); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 FunctionVariableField::decode(Flags()) == STACK; | 322 FunctionVariableField::decode(Flags()) == STACK; |
295 return StackLocalCount() + (function_name_stack_slot ? 1 : 0); | 323 return StackLocalCount() + (function_name_stack_slot ? 1 : 0); |
296 } | 324 } |
297 return 0; | 325 return 0; |
298 } | 326 } |
299 | 327 |
300 | 328 |
301 int ScopeInfo::ContextLength() { | 329 int ScopeInfo::ContextLength() { |
302 if (length() > 0) { | 330 if (length() > 0) { |
303 int context_locals = ContextLocalCount(); | 331 int context_locals = ContextLocalCount(); |
| 332 int context_globals = ContextGlobalCount(); |
304 bool function_name_context_slot = | 333 bool function_name_context_slot = |
305 FunctionVariableField::decode(Flags()) == CONTEXT; | 334 FunctionVariableField::decode(Flags()) == CONTEXT; |
306 bool has_context = context_locals > 0 || function_name_context_slot || | 335 bool has_context = context_locals > 0 || context_globals > 0 || |
| 336 function_name_context_slot || |
307 scope_type() == WITH_SCOPE || | 337 scope_type() == WITH_SCOPE || |
308 (scope_type() == ARROW_SCOPE && CallsSloppyEval()) || | 338 (scope_type() == ARROW_SCOPE && CallsSloppyEval()) || |
309 (scope_type() == FUNCTION_SCOPE && CallsSloppyEval()) || | 339 (scope_type() == FUNCTION_SCOPE && CallsSloppyEval()) || |
310 scope_type() == MODULE_SCOPE; | 340 scope_type() == MODULE_SCOPE; |
| 341 |
311 if (has_context) { | 342 if (has_context) { |
312 return Context::MIN_CONTEXT_SLOTS + context_locals + | 343 return Context::MIN_CONTEXT_SLOTS + context_locals + 2 * context_globals + |
313 (function_name_context_slot ? 1 : 0); | 344 (function_name_context_slot ? 1 : 0); |
314 } | 345 } |
315 } | 346 } |
316 return 0; | 347 return 0; |
317 } | 348 } |
318 | 349 |
319 | 350 |
320 bool ScopeInfo::HasReceiver() { | 351 bool ScopeInfo::HasReceiver() { |
321 if (length() > 0) { | 352 if (length() > 0) { |
322 return NONE != ReceiverVariableField::decode(Flags()); | 353 return NONE != ReceiverVariableField::decode(Flags()); |
323 } else { | 354 } else { |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 | 420 |
390 | 421 |
391 int ScopeInfo::StackLocalIndex(int var) { | 422 int ScopeInfo::StackLocalIndex(int var) { |
392 DCHECK(0 <= var && var < StackLocalCount()); | 423 DCHECK(0 <= var && var < StackLocalCount()); |
393 int first_slot_index = Smi::cast(get(StackLocalFirstSlotIndex()))->value(); | 424 int first_slot_index = Smi::cast(get(StackLocalFirstSlotIndex()))->value(); |
394 return first_slot_index + var; | 425 return first_slot_index + var; |
395 } | 426 } |
396 | 427 |
397 | 428 |
398 String* ScopeInfo::ContextLocalName(int var) { | 429 String* ScopeInfo::ContextLocalName(int var) { |
399 DCHECK(0 <= var && var < ContextLocalCount()); | 430 DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount()); |
400 int info_index = ContextLocalNameEntriesIndex() + var; | 431 int info_index = ContextLocalNameEntriesIndex() + var; |
401 return String::cast(get(info_index)); | 432 return String::cast(get(info_index)); |
402 } | 433 } |
403 | 434 |
404 | 435 |
405 VariableMode ScopeInfo::ContextLocalMode(int var) { | 436 VariableMode ScopeInfo::ContextLocalMode(int var) { |
406 DCHECK(0 <= var && var < ContextLocalCount()); | 437 DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount()); |
407 int info_index = ContextLocalInfoEntriesIndex() + var; | 438 int info_index = ContextLocalInfoEntriesIndex() + var; |
408 int value = Smi::cast(get(info_index))->value(); | 439 int value = Smi::cast(get(info_index))->value(); |
409 return ContextLocalMode::decode(value); | 440 return ContextLocalMode::decode(value); |
410 } | 441 } |
411 | 442 |
412 | 443 |
413 InitializationFlag ScopeInfo::ContextLocalInitFlag(int var) { | 444 InitializationFlag ScopeInfo::ContextLocalInitFlag(int var) { |
414 DCHECK(0 <= var && var < ContextLocalCount()); | 445 DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount()); |
415 int info_index = ContextLocalInfoEntriesIndex() + var; | 446 int info_index = ContextLocalInfoEntriesIndex() + var; |
416 int value = Smi::cast(get(info_index))->value(); | 447 int value = Smi::cast(get(info_index))->value(); |
417 return ContextLocalInitFlag::decode(value); | 448 return ContextLocalInitFlag::decode(value); |
418 } | 449 } |
419 | 450 |
420 | 451 |
421 MaybeAssignedFlag ScopeInfo::ContextLocalMaybeAssignedFlag(int var) { | 452 MaybeAssignedFlag ScopeInfo::ContextLocalMaybeAssignedFlag(int var) { |
422 DCHECK(0 <= var && var < ContextLocalCount()); | 453 DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount()); |
423 int info_index = ContextLocalInfoEntriesIndex() + var; | 454 int info_index = ContextLocalInfoEntriesIndex() + var; |
424 int value = Smi::cast(get(info_index))->value(); | 455 int value = Smi::cast(get(info_index))->value(); |
425 return ContextLocalMaybeAssignedFlag::decode(value); | 456 return ContextLocalMaybeAssignedFlag::decode(value); |
426 } | 457 } |
427 | 458 |
428 | 459 |
429 bool ScopeInfo::LocalIsSynthetic(int var) { | 460 bool ScopeInfo::LocalIsSynthetic(int var) { |
430 DCHECK(0 <= var && var < LocalCount()); | 461 DCHECK(0 <= var && var < LocalCount()); |
431 // There's currently no flag stored on the ScopeInfo to indicate that a | 462 // There's currently no flag stored on the ScopeInfo to indicate that a |
432 // variable is a compiler-introduced temporary. However, to avoid conflict | 463 // variable is a compiler-introduced temporary. However, to avoid conflict |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
478 return i - start + first_slot_index; | 509 return i - start + first_slot_index; |
479 } | 510 } |
480 } | 511 } |
481 } | 512 } |
482 return -1; | 513 return -1; |
483 } | 514 } |
484 | 515 |
485 | 516 |
486 int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info, | 517 int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info, |
487 Handle<String> name, VariableMode* mode, | 518 Handle<String> name, VariableMode* mode, |
| 519 VariableLocation* location, |
488 InitializationFlag* init_flag, | 520 InitializationFlag* init_flag, |
489 MaybeAssignedFlag* maybe_assigned_flag) { | 521 MaybeAssignedFlag* maybe_assigned_flag) { |
490 DCHECK(name->IsInternalizedString()); | 522 DCHECK(name->IsInternalizedString()); |
491 DCHECK(mode != NULL); | 523 DCHECK(mode != NULL); |
| 524 DCHECK(location != NULL); |
492 DCHECK(init_flag != NULL); | 525 DCHECK(init_flag != NULL); |
493 if (scope_info->length() > 0) { | 526 if (scope_info->length() > 0) { |
494 ContextSlotCache* context_slot_cache = | 527 ContextSlotCache* context_slot_cache = |
495 scope_info->GetIsolate()->context_slot_cache(); | 528 scope_info->GetIsolate()->context_slot_cache(); |
496 int result = context_slot_cache->Lookup(*scope_info, *name, mode, init_flag, | 529 int result = context_slot_cache->Lookup(*scope_info, *name, mode, location, |
497 maybe_assigned_flag); | 530 init_flag, maybe_assigned_flag); |
498 if (result != ContextSlotCache::kNotFound) { | 531 if (result != ContextSlotCache::kNotFound) { |
499 DCHECK(result < scope_info->ContextLength()); | 532 DCHECK(result < scope_info->ContextLength()); |
500 return result; | 533 return result; |
501 } | 534 } |
502 | 535 |
| 536 DCHECK_EQ(scope_info->ContextGlobalNameEntriesIndex(), |
| 537 scope_info->ContextLocalNameEntriesIndex() + |
| 538 scope_info->ContextLocalCount()); |
503 int start = scope_info->ContextLocalNameEntriesIndex(); | 539 int start = scope_info->ContextLocalNameEntriesIndex(); |
504 int end = scope_info->ContextLocalNameEntriesIndex() + | 540 int end = scope_info->ContextGlobalNameEntriesIndex() + |
505 scope_info->ContextLocalCount(); | 541 scope_info->ContextGlobalCount(); |
506 for (int i = start; i < end; ++i) { | 542 for (int i = start; i < end; ++i) { |
507 if (*name == scope_info->get(i)) { | 543 if (*name == scope_info->get(i)) { |
508 int var = i - start; | 544 int var = i - start; |
509 *mode = scope_info->ContextLocalMode(var); | 545 *mode = scope_info->ContextLocalMode(var); |
510 *init_flag = scope_info->ContextLocalInitFlag(var); | 546 *init_flag = scope_info->ContextLocalInitFlag(var); |
511 *maybe_assigned_flag = scope_info->ContextLocalMaybeAssignedFlag(var); | 547 *maybe_assigned_flag = scope_info->ContextLocalMaybeAssignedFlag(var); |
512 result = Context::MIN_CONTEXT_SLOTS + var; | 548 |
513 context_slot_cache->Update(scope_info, name, *mode, *init_flag, | 549 if (var < scope_info->ContextLocalCount()) { |
514 *maybe_assigned_flag, result); | 550 *location = VariableLocation::CONTEXT; |
| 551 result = Context::MIN_CONTEXT_SLOTS + var; |
| 552 } else { |
| 553 var -= scope_info->ContextLocalCount(); |
| 554 *location = VariableLocation::GLOBAL; |
| 555 result = Context::MIN_CONTEXT_SLOTS + |
| 556 scope_info->ContextLocalCount() + 2 * var; |
| 557 } |
| 558 |
| 559 context_slot_cache->Update(scope_info, name, *mode, *location, |
| 560 *init_flag, *maybe_assigned_flag, result); |
515 DCHECK(result < scope_info->ContextLength()); | 561 DCHECK(result < scope_info->ContextLength()); |
516 return result; | 562 return result; |
517 } | 563 } |
518 } | 564 } |
519 // Cache as not found. Mode, init flag and maybe assigned flag don't matter. | 565 // Cache as not found. Mode, location, init flag and maybe assigned flag |
520 context_slot_cache->Update(scope_info, name, INTERNAL, kNeedsInitialization, | 566 // don't matter. |
| 567 context_slot_cache->Update(scope_info, name, INTERNAL, |
| 568 VariableLocation::CONTEXT, kNeedsInitialization, |
521 kNotAssigned, -1); | 569 kNotAssigned, -1); |
522 } | 570 } |
523 return -1; | 571 return -1; |
524 } | 572 } |
525 | 573 |
526 | 574 |
527 int ScopeInfo::ParameterIndex(String* name) { | 575 int ScopeInfo::ParameterIndex(String* name) { |
528 DCHECK(name->IsInternalizedString()); | 576 DCHECK(name->IsInternalizedString()); |
529 if (length() > 0) { | 577 if (length() > 0) { |
530 // We must read parameters from the end since for | 578 // We must read parameters from the end since for |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
608 int ScopeInfo::StackLocalEntriesIndex() { | 656 int ScopeInfo::StackLocalEntriesIndex() { |
609 return StackLocalFirstSlotIndex() + 1; | 657 return StackLocalFirstSlotIndex() + 1; |
610 } | 658 } |
611 | 659 |
612 | 660 |
613 int ScopeInfo::ContextLocalNameEntriesIndex() { | 661 int ScopeInfo::ContextLocalNameEntriesIndex() { |
614 return StackLocalEntriesIndex() + StackLocalCount(); | 662 return StackLocalEntriesIndex() + StackLocalCount(); |
615 } | 663 } |
616 | 664 |
617 | 665 |
| 666 int ScopeInfo::ContextGlobalNameEntriesIndex() { |
| 667 return ContextLocalNameEntriesIndex() + ContextLocalCount(); |
| 668 } |
| 669 |
| 670 |
618 int ScopeInfo::ContextLocalInfoEntriesIndex() { | 671 int ScopeInfo::ContextLocalInfoEntriesIndex() { |
619 return ContextLocalNameEntriesIndex() + ContextLocalCount(); | 672 return ContextGlobalNameEntriesIndex() + ContextGlobalCount(); |
| 673 } |
| 674 |
| 675 |
| 676 int ScopeInfo::ContextGlobalInfoEntriesIndex() { |
| 677 return ContextLocalInfoEntriesIndex() + ContextLocalCount(); |
620 } | 678 } |
621 | 679 |
622 | 680 |
623 int ScopeInfo::StrongModeFreeVariableNameEntriesIndex() { | 681 int ScopeInfo::StrongModeFreeVariableNameEntriesIndex() { |
624 return ContextLocalInfoEntriesIndex() + ContextLocalCount(); | 682 return ContextGlobalInfoEntriesIndex() + ContextGlobalCount(); |
625 } | 683 } |
626 | 684 |
627 | 685 |
628 int ScopeInfo::StrongModeFreeVariablePositionEntriesIndex() { | 686 int ScopeInfo::StrongModeFreeVariablePositionEntriesIndex() { |
629 return StrongModeFreeVariableNameEntriesIndex() + | 687 return StrongModeFreeVariableNameEntriesIndex() + |
630 StrongModeFreeVariableCount(); | 688 StrongModeFreeVariableCount(); |
631 } | 689 } |
632 | 690 |
633 | 691 |
634 int ScopeInfo::ReceiverEntryIndex() { | 692 int ScopeInfo::ReceiverEntryIndex() { |
635 return StrongModeFreeVariablePositionEntriesIndex() + | 693 return StrongModeFreeVariablePositionEntriesIndex() + |
636 2 * StrongModeFreeVariableCount(); | 694 2 * StrongModeFreeVariableCount(); |
637 } | 695 } |
638 | 696 |
639 | 697 |
640 int ScopeInfo::FunctionNameEntryIndex() { | 698 int ScopeInfo::FunctionNameEntryIndex() { |
641 return ReceiverEntryIndex() + (HasAllocatedReceiver() ? 1 : 0); | 699 return ReceiverEntryIndex() + (HasAllocatedReceiver() ? 1 : 0); |
642 } | 700 } |
643 | 701 |
644 | 702 |
645 int ContextSlotCache::Hash(Object* data, String* name) { | 703 int ContextSlotCache::Hash(Object* data, String* name) { |
646 // Uses only lower 32 bits if pointers are larger. | 704 // Uses only lower 32 bits if pointers are larger. |
647 uintptr_t addr_hash = | 705 uintptr_t addr_hash = |
648 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2; | 706 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2; |
649 return static_cast<int>((addr_hash ^ name->Hash()) % kLength); | 707 return static_cast<int>((addr_hash ^ name->Hash()) % kLength); |
650 } | 708 } |
651 | 709 |
652 | 710 |
653 int ContextSlotCache::Lookup(Object* data, String* name, VariableMode* mode, | 711 int ContextSlotCache::Lookup(Object* data, String* name, VariableMode* mode, |
| 712 VariableLocation* location, |
654 InitializationFlag* init_flag, | 713 InitializationFlag* init_flag, |
655 MaybeAssignedFlag* maybe_assigned_flag) { | 714 MaybeAssignedFlag* maybe_assigned_flag) { |
656 int index = Hash(data, name); | 715 int index = Hash(data, name); |
657 Key& key = keys_[index]; | 716 Key& key = keys_[index]; |
658 if ((key.data == data) && key.name->Equals(name)) { | 717 if ((key.data == data) && key.name->Equals(name)) { |
659 Value result(values_[index]); | 718 Value result(values_[index]); |
660 if (mode != NULL) *mode = result.mode(); | 719 if (mode != NULL) *mode = result.mode(); |
| 720 if (location != NULL) *location = result.location(); |
661 if (init_flag != NULL) *init_flag = result.initialization_flag(); | 721 if (init_flag != NULL) *init_flag = result.initialization_flag(); |
662 if (maybe_assigned_flag != NULL) | 722 if (maybe_assigned_flag != NULL) |
663 *maybe_assigned_flag = result.maybe_assigned_flag(); | 723 *maybe_assigned_flag = result.maybe_assigned_flag(); |
664 return result.index() + kNotFound; | 724 return result.index() + kNotFound; |
665 } | 725 } |
666 return kNotFound; | 726 return kNotFound; |
667 } | 727 } |
668 | 728 |
669 | 729 |
670 void ContextSlotCache::Update(Handle<Object> data, Handle<String> name, | 730 void ContextSlotCache::Update(Handle<Object> data, Handle<String> name, |
671 VariableMode mode, InitializationFlag init_flag, | 731 VariableMode mode, VariableLocation location, |
| 732 InitializationFlag init_flag, |
672 MaybeAssignedFlag maybe_assigned_flag, | 733 MaybeAssignedFlag maybe_assigned_flag, |
673 int slot_index) { | 734 int slot_index) { |
674 DisallowHeapAllocation no_gc; | 735 DisallowHeapAllocation no_gc; |
675 Handle<String> internalized_name; | 736 Handle<String> internalized_name; |
676 DCHECK(slot_index > kNotFound); | 737 DCHECK(slot_index > kNotFound); |
677 if (StringTable::InternalizeStringIfExists(name->GetIsolate(), name). | 738 if (StringTable::InternalizeStringIfExists(name->GetIsolate(), name). |
678 ToHandle(&internalized_name)) { | 739 ToHandle(&internalized_name)) { |
679 int index = Hash(*data, *internalized_name); | 740 int index = Hash(*data, *internalized_name); |
680 Key& key = keys_[index]; | 741 Key& key = keys_[index]; |
681 key.data = *data; | 742 key.data = *data; |
682 key.name = *internalized_name; | 743 key.name = *internalized_name; |
683 // Please note value only takes a uint as index. | 744 // Please note value only takes a uint as index. |
684 values_[index] = Value(mode, init_flag, maybe_assigned_flag, | 745 values_[index] = Value(mode, location, init_flag, maybe_assigned_flag, |
685 slot_index - kNotFound).raw(); | 746 slot_index - kNotFound).raw(); |
686 #ifdef DEBUG | 747 #ifdef DEBUG |
687 ValidateEntry(data, name, mode, init_flag, maybe_assigned_flag, slot_index); | 748 ValidateEntry(data, name, mode, location, init_flag, maybe_assigned_flag, |
| 749 slot_index); |
688 #endif | 750 #endif |
689 } | 751 } |
690 } | 752 } |
691 | 753 |
692 | 754 |
693 void ContextSlotCache::Clear() { | 755 void ContextSlotCache::Clear() { |
694 for (int index = 0; index < kLength; index++) keys_[index].data = NULL; | 756 for (int index = 0; index < kLength; index++) keys_[index].data = NULL; |
695 } | 757 } |
696 | 758 |
697 | 759 |
698 #ifdef DEBUG | 760 #ifdef DEBUG |
699 | 761 |
700 void ContextSlotCache::ValidateEntry(Handle<Object> data, Handle<String> name, | 762 void ContextSlotCache::ValidateEntry(Handle<Object> data, Handle<String> name, |
701 VariableMode mode, | 763 VariableMode mode, |
| 764 VariableLocation location, |
702 InitializationFlag init_flag, | 765 InitializationFlag init_flag, |
703 MaybeAssignedFlag maybe_assigned_flag, | 766 MaybeAssignedFlag maybe_assigned_flag, |
704 int slot_index) { | 767 int slot_index) { |
705 DisallowHeapAllocation no_gc; | 768 DisallowHeapAllocation no_gc; |
706 Handle<String> internalized_name; | 769 Handle<String> internalized_name; |
707 if (StringTable::InternalizeStringIfExists(name->GetIsolate(), name). | 770 if (StringTable::InternalizeStringIfExists(name->GetIsolate(), name). |
708 ToHandle(&internalized_name)) { | 771 ToHandle(&internalized_name)) { |
709 int index = Hash(*data, *name); | 772 int index = Hash(*data, *name); |
710 Key& key = keys_[index]; | 773 Key& key = keys_[index]; |
711 DCHECK(key.data == *data); | 774 DCHECK(key.data == *data); |
712 DCHECK(key.name->Equals(*name)); | 775 DCHECK(key.name->Equals(*name)); |
713 Value result(values_[index]); | 776 Value result(values_[index]); |
714 DCHECK(result.mode() == mode); | 777 DCHECK(result.mode() == mode); |
| 778 DCHECK(result.location() == location); |
715 DCHECK(result.initialization_flag() == init_flag); | 779 DCHECK(result.initialization_flag() == init_flag); |
716 DCHECK(result.maybe_assigned_flag() == maybe_assigned_flag); | 780 DCHECK(result.maybe_assigned_flag() == maybe_assigned_flag); |
717 DCHECK(result.index() + kNotFound == slot_index); | 781 DCHECK(result.index() + kNotFound == slot_index); |
718 } | 782 } |
719 } | 783 } |
720 | 784 |
721 | 785 |
722 static void PrintList(const char* list_name, | 786 static void PrintList(const char* list_name, |
723 int nof_internal_slots, | 787 int nof_internal_slots, |
724 int start, | 788 int start, |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
782 info->set_mode(i, var->mode()); | 846 info->set_mode(i, var->mode()); |
783 DCHECK(var->index() >= 0); | 847 DCHECK(var->index() >= 0); |
784 info->set_index(i, var->index()); | 848 info->set_index(i, var->index()); |
785 } | 849 } |
786 DCHECK(i == info->length()); | 850 DCHECK(i == info->length()); |
787 return info; | 851 return info; |
788 } | 852 } |
789 | 853 |
790 } // namespace internal | 854 } // namespace internal |
791 } // namespace v8 | 855 } // namespace v8 |
OLD | NEW |