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