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/scopeinfo.h" | 9 #include "src/scopeinfo.h" |
10 #include "src/scopes.h" | 10 #include "src/scopes.h" |
11 | 11 |
12 namespace v8 { | 12 namespace v8 { |
13 namespace internal { | 13 namespace internal { |
14 | 14 |
15 | 15 |
16 Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, | 16 Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, |
17 Scope* scope) { | 17 Scope* scope) { |
18 // Collect stack and context locals. | 18 // Collect stack and context locals. |
19 ZoneList<Variable*> stack_locals(scope->StackLocalCount(), zone); | 19 ZoneList<Variable*> stack_locals(scope->StackLocalCount(), zone); |
20 ZoneList<Variable*> context_locals(scope->ContextLocalCount(), zone); | 20 ZoneList<Variable*> context_locals(scope->ContextLocalCount(), zone); |
21 scope->CollectStackAndContextLocals(&stack_locals, &context_locals); | 21 ZoneList<Variable*> strong_mode_free_variables(0, zone); |
| 22 |
| 23 scope->CollectStackAndContextLocals(&stack_locals, &context_locals, |
| 24 &strong_mode_free_variables); |
22 const int stack_local_count = stack_locals.length(); | 25 const int stack_local_count = stack_locals.length(); |
23 const int context_local_count = context_locals.length(); | 26 const int context_local_count = context_locals.length(); |
| 27 const int strong_mode_free_variable_count = |
| 28 strong_mode_free_variables.length(); |
24 // Make sure we allocate the correct amount. | 29 // Make sure we allocate the correct amount. |
25 DCHECK(scope->StackLocalCount() == stack_local_count); | 30 DCHECK(scope->StackLocalCount() == stack_local_count); |
26 DCHECK(scope->ContextLocalCount() == context_local_count); | 31 DCHECK(scope->ContextLocalCount() == context_local_count); |
27 | 32 |
28 bool simple_parameter_list = | 33 bool simple_parameter_list = |
29 scope->is_function_scope() ? scope->is_simple_parameter_list() : true; | 34 scope->is_function_scope() ? scope->is_simple_parameter_list() : true; |
30 | 35 |
31 // Determine use and location of the function variable if it is present. | 36 // Determine use and location of the function variable if it is present. |
32 FunctionVariableInfo function_name_info; | 37 FunctionVariableInfo function_name_info; |
33 VariableMode function_variable_mode; | 38 VariableMode function_variable_mode; |
34 if (scope->is_function_scope() && scope->function() != NULL) { | 39 if (scope->is_function_scope() && scope->function() != NULL) { |
35 Variable* var = scope->function()->proxy()->var(); | 40 Variable* var = scope->function()->proxy()->var(); |
36 if (!var->is_used()) { | 41 if (!var->is_used()) { |
37 function_name_info = UNUSED; | 42 function_name_info = UNUSED; |
38 } else if (var->IsContextSlot()) { | 43 } else if (var->IsContextSlot()) { |
39 function_name_info = CONTEXT; | 44 function_name_info = CONTEXT; |
40 } else { | 45 } else { |
41 DCHECK(var->IsStackLocal()); | 46 DCHECK(var->IsStackLocal()); |
42 function_name_info = STACK; | 47 function_name_info = STACK; |
43 } | 48 } |
44 function_variable_mode = var->mode(); | 49 function_variable_mode = var->mode(); |
45 } else { | 50 } else { |
46 function_name_info = NONE; | 51 function_name_info = NONE; |
47 function_variable_mode = VAR; | 52 function_variable_mode = VAR; |
48 } | 53 } |
49 | 54 |
50 const bool has_function_name = function_name_info != NONE; | 55 const bool has_function_name = function_name_info != NONE; |
51 const int parameter_count = scope->num_parameters(); | 56 const int parameter_count = scope->num_parameters(); |
52 const int length = kVariablePartIndex | 57 const int length = kVariablePartIndex + parameter_count + stack_local_count + |
53 + parameter_count + stack_local_count + 2 * context_local_count | 58 2 * context_local_count + (has_function_name ? 2 : 0) + |
54 + (has_function_name ? 2 : 0); | 59 strong_mode_free_variable_count; |
55 | 60 |
56 Factory* factory = isolate->factory(); | 61 Factory* factory = isolate->factory(); |
57 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); | 62 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); |
58 | 63 |
59 // Encode the flags. | 64 // Encode the flags. |
60 int flags = ScopeTypeField::encode(scope->scope_type()) | | 65 int flags = ScopeTypeField::encode(scope->scope_type()) | |
61 CallsEvalField::encode(scope->calls_eval()) | | 66 CallsEvalField::encode(scope->calls_eval()) | |
62 LanguageModeField::encode(scope->language_mode()) | | 67 LanguageModeField::encode(scope->language_mode()) | |
63 FunctionVariableField::encode(function_name_info) | | 68 FunctionVariableField::encode(function_name_info) | |
64 FunctionVariableMode::encode(function_variable_mode) | | 69 FunctionVariableMode::encode(function_variable_mode) | |
65 AsmModuleField::encode(scope->asm_module()) | | 70 AsmModuleField::encode(scope->asm_module()) | |
66 AsmFunctionField::encode(scope->asm_function()) | | 71 AsmFunctionField::encode(scope->asm_function()) | |
67 IsSimpleParameterListField::encode(simple_parameter_list) | | 72 IsSimpleParameterListField::encode(simple_parameter_list) | |
68 BlockScopeIsClassScopeField::encode(scope->is_class_scope()) | | 73 BlockScopeIsClassScopeField::encode(scope->is_class_scope()) | |
69 FunctionKindField::encode(scope->function_kind()); | 74 FunctionKindField::encode(scope->function_kind()); |
70 scope_info->SetFlags(flags); | 75 scope_info->SetFlags(flags); |
71 scope_info->SetParameterCount(parameter_count); | 76 scope_info->SetParameterCount(parameter_count); |
72 scope_info->SetStackLocalCount(stack_local_count); | 77 scope_info->SetStackLocalCount(stack_local_count); |
73 scope_info->SetContextLocalCount(context_local_count); | 78 scope_info->SetContextLocalCount(context_local_count); |
| 79 scope_info->SetStrongModeFreeVariableCount(strong_mode_free_variable_count); |
74 | 80 |
75 int index = kVariablePartIndex; | 81 int index = kVariablePartIndex; |
76 // Add parameters. | 82 // Add parameters. |
77 DCHECK(index == scope_info->ParameterEntriesIndex()); | 83 DCHECK(index == scope_info->ParameterEntriesIndex()); |
78 for (int i = 0; i < parameter_count; ++i) { | 84 for (int i = 0; i < parameter_count; ++i) { |
79 scope_info->set(index++, *scope->parameter(i)->name()); | 85 scope_info->set(index++, *scope->parameter(i)->name()); |
80 } | 86 } |
81 | 87 |
82 // Add stack locals' names. We are assuming that the stack locals' | 88 // Add stack locals' names. We are assuming that the stack locals' |
83 // slots are allocated in increasing order, so we can simply add | 89 // slots are allocated in increasing order, so we can simply add |
(...skipping 22 matching lines...) Expand all Loading... |
106 DCHECK(index == scope_info->ContextLocalInfoEntriesIndex()); | 112 DCHECK(index == scope_info->ContextLocalInfoEntriesIndex()); |
107 for (int i = 0; i < context_local_count; ++i) { | 113 for (int i = 0; i < context_local_count; ++i) { |
108 Variable* var = context_locals[i]; | 114 Variable* var = context_locals[i]; |
109 uint32_t value = | 115 uint32_t value = |
110 ContextLocalMode::encode(var->mode()) | | 116 ContextLocalMode::encode(var->mode()) | |
111 ContextLocalInitFlag::encode(var->initialization_flag()) | | 117 ContextLocalInitFlag::encode(var->initialization_flag()) | |
112 ContextLocalMaybeAssignedFlag::encode(var->maybe_assigned()); | 118 ContextLocalMaybeAssignedFlag::encode(var->maybe_assigned()); |
113 scope_info->set(index++, Smi::FromInt(value)); | 119 scope_info->set(index++, Smi::FromInt(value)); |
114 } | 120 } |
115 | 121 |
| 122 DCHECK(index == scope_info->StrongModeFreeVariableEntriesIndex()); |
| 123 for (int i = 0; i < strong_mode_free_variable_count; ++i) { |
| 124 scope_info->set(index++, *strong_mode_free_variables[i]->name()); |
| 125 } |
| 126 |
116 // If present, add the function variable name and its index. | 127 // If present, add the function variable name and its index. |
117 DCHECK(index == scope_info->FunctionNameEntryIndex()); | 128 DCHECK(index == scope_info->FunctionNameEntryIndex()); |
118 if (has_function_name) { | 129 if (has_function_name) { |
119 int var_index = scope->function()->proxy()->var()->index(); | 130 int var_index = scope->function()->proxy()->var()->index(); |
120 scope_info->set(index++, *scope->function()->proxy()->name()); | 131 scope_info->set(index++, *scope->function()->proxy()->name()); |
121 scope_info->set(index++, Smi::FromInt(var_index)); | 132 scope_info->set(index++, Smi::FromInt(var_index)); |
122 DCHECK(function_name_info != STACK || | 133 DCHECK(function_name_info != STACK || |
123 (var_index == scope_info->StackLocalCount() && | 134 (var_index == scope_info->StackLocalCount() && |
124 var_index == scope_info->StackSlotCount() - 1)); | 135 var_index == scope_info->StackSlotCount() - 1)); |
125 DCHECK(function_name_info != CONTEXT || | 136 DCHECK(function_name_info != CONTEXT || |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 DCHECK(0 <= var && var < LocalCount()); | 289 DCHECK(0 <= var && var < LocalCount()); |
279 // There's currently no flag stored on the ScopeInfo to indicate that a | 290 // There's currently no flag stored on the ScopeInfo to indicate that a |
280 // variable is a compiler-introduced temporary. However, to avoid conflict | 291 // variable is a compiler-introduced temporary. However, to avoid conflict |
281 // with user declarations, the current temporaries like .generator_object and | 292 // with user declarations, the current temporaries like .generator_object and |
282 // .result start with a dot, so we can use that as a flag. It's a hack! | 293 // .result start with a dot, so we can use that as a flag. It's a hack! |
283 Handle<String> name(LocalName(var)); | 294 Handle<String> name(LocalName(var)); |
284 return name->length() > 0 && name->Get(0) == '.'; | 295 return name->length() > 0 && name->Get(0) == '.'; |
285 } | 296 } |
286 | 297 |
287 | 298 |
| 299 String* ScopeInfo::StrongModeFreeVariableName(int var) { |
| 300 DCHECK(0 <= var && var < StrongModeFreeVariableCount()); |
| 301 int info_index = StrongModeFreeVariableEntriesIndex() + var; |
| 302 return String::cast(get(info_index)); |
| 303 } |
| 304 |
| 305 |
288 int ScopeInfo::StackSlotIndex(String* name) { | 306 int ScopeInfo::StackSlotIndex(String* name) { |
289 DCHECK(name->IsInternalizedString()); | 307 DCHECK(name->IsInternalizedString()); |
290 if (length() > 0) { | 308 if (length() > 0) { |
291 int start = StackLocalEntriesIndex(); | 309 int start = StackLocalEntriesIndex(); |
292 int end = StackLocalEntriesIndex() + StackLocalCount(); | 310 int end = StackLocalEntriesIndex() + StackLocalCount(); |
293 for (int i = start; i < end; ++i) { | 311 for (int i = start; i < end; ++i) { |
294 if (name == get(i)) { | 312 if (name == get(i)) { |
295 return i - start; | 313 return i - start; |
296 } | 314 } |
297 } | 315 } |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 int ScopeInfo::ContextLocalNameEntriesIndex() { | 443 int ScopeInfo::ContextLocalNameEntriesIndex() { |
426 return StackLocalEntriesIndex() + StackLocalCount(); | 444 return StackLocalEntriesIndex() + StackLocalCount(); |
427 } | 445 } |
428 | 446 |
429 | 447 |
430 int ScopeInfo::ContextLocalInfoEntriesIndex() { | 448 int ScopeInfo::ContextLocalInfoEntriesIndex() { |
431 return ContextLocalNameEntriesIndex() + ContextLocalCount(); | 449 return ContextLocalNameEntriesIndex() + ContextLocalCount(); |
432 } | 450 } |
433 | 451 |
434 | 452 |
| 453 int ScopeInfo::StrongModeFreeVariableEntriesIndex() { |
| 454 return ContextLocalInfoEntriesIndex() + ContextLocalCount(); |
| 455 } |
| 456 |
| 457 |
435 int ScopeInfo::FunctionNameEntryIndex() { | 458 int ScopeInfo::FunctionNameEntryIndex() { |
436 return ContextLocalInfoEntriesIndex() + ContextLocalCount(); | 459 return StrongModeFreeVariableEntriesIndex() + StrongModeFreeVariableCount(); |
437 } | 460 } |
438 | 461 |
439 | 462 |
440 int ContextSlotCache::Hash(Object* data, String* name) { | 463 int ContextSlotCache::Hash(Object* data, String* name) { |
441 // Uses only lower 32 bits if pointers are larger. | 464 // Uses only lower 32 bits if pointers are larger. |
442 uintptr_t addr_hash = | 465 uintptr_t addr_hash = |
443 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2; | 466 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2; |
444 return static_cast<int>((addr_hash ^ name->Hash()) % kLength); | 467 return static_cast<int>((addr_hash ^ name->Hash()) % kLength); |
445 } | 468 } |
446 | 469 |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
576 info->set_name(i, *(it.export_name()->string())); | 599 info->set_name(i, *(it.export_name()->string())); |
577 info->set_mode(i, var->mode()); | 600 info->set_mode(i, var->mode()); |
578 DCHECK(var->index() >= 0); | 601 DCHECK(var->index() >= 0); |
579 info->set_index(i, var->index()); | 602 info->set_index(i, var->index()); |
580 } | 603 } |
581 DCHECK(i == info->length()); | 604 DCHECK(i == info->length()); |
582 return info; | 605 return info; |
583 } | 606 } |
584 | 607 |
585 } } // namespace v8::internal | 608 } } // namespace v8::internal |
OLD | NEW |