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 + |
54 + (has_function_name ? 2 : 0); | 59 3 * strong_mode_free_variable_count + |
| 60 (has_function_name ? 2 : 0); |
55 | 61 |
56 Factory* factory = isolate->factory(); | 62 Factory* factory = isolate->factory(); |
57 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); | 63 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); |
58 | 64 |
59 // Encode the flags. | 65 // Encode the flags. |
60 int flags = ScopeTypeField::encode(scope->scope_type()) | | 66 int flags = ScopeTypeField::encode(scope->scope_type()) | |
61 CallsEvalField::encode(scope->calls_eval()) | | 67 CallsEvalField::encode(scope->calls_eval()) | |
62 LanguageModeField::encode(scope->language_mode()) | | 68 LanguageModeField::encode(scope->language_mode()) | |
63 FunctionVariableField::encode(function_name_info) | | 69 FunctionVariableField::encode(function_name_info) | |
64 FunctionVariableMode::encode(function_variable_mode) | | 70 FunctionVariableMode::encode(function_variable_mode) | |
65 AsmModuleField::encode(scope->asm_module()) | | 71 AsmModuleField::encode(scope->asm_module()) | |
66 AsmFunctionField::encode(scope->asm_function()) | | 72 AsmFunctionField::encode(scope->asm_function()) | |
67 IsSimpleParameterListField::encode(simple_parameter_list) | | 73 IsSimpleParameterListField::encode(simple_parameter_list) | |
68 BlockScopeIsClassScopeField::encode(scope->is_class_scope()) | | 74 BlockScopeIsClassScopeField::encode(scope->is_class_scope()) | |
69 FunctionKindField::encode(scope->function_kind()); | 75 FunctionKindField::encode(scope->function_kind()); |
70 scope_info->SetFlags(flags); | 76 scope_info->SetFlags(flags); |
71 scope_info->SetParameterCount(parameter_count); | 77 scope_info->SetParameterCount(parameter_count); |
72 scope_info->SetStackLocalCount(stack_local_count); | 78 scope_info->SetStackLocalCount(stack_local_count); |
73 scope_info->SetContextLocalCount(context_local_count); | 79 scope_info->SetContextLocalCount(context_local_count); |
| 80 scope_info->SetStrongModeFreeVariableCount(strong_mode_free_variable_count); |
74 | 81 |
75 int index = kVariablePartIndex; | 82 int index = kVariablePartIndex; |
76 // Add parameters. | 83 // Add parameters. |
77 DCHECK(index == scope_info->ParameterEntriesIndex()); | 84 DCHECK(index == scope_info->ParameterEntriesIndex()); |
78 for (int i = 0; i < parameter_count; ++i) { | 85 for (int i = 0; i < parameter_count; ++i) { |
79 scope_info->set(index++, *scope->parameter(i)->name()); | 86 scope_info->set(index++, *scope->parameter(i)->name()); |
80 } | 87 } |
81 | 88 |
82 // Add stack locals' names. We are assuming that the stack locals' | 89 // Add stack locals' names. We are assuming that the stack locals' |
83 // slots are allocated in increasing order, so we can simply add | 90 // slots are allocated in increasing order, so we can simply add |
(...skipping 22 matching lines...) Expand all Loading... |
106 DCHECK(index == scope_info->ContextLocalInfoEntriesIndex()); | 113 DCHECK(index == scope_info->ContextLocalInfoEntriesIndex()); |
107 for (int i = 0; i < context_local_count; ++i) { | 114 for (int i = 0; i < context_local_count; ++i) { |
108 Variable* var = context_locals[i]; | 115 Variable* var = context_locals[i]; |
109 uint32_t value = | 116 uint32_t value = |
110 ContextLocalMode::encode(var->mode()) | | 117 ContextLocalMode::encode(var->mode()) | |
111 ContextLocalInitFlag::encode(var->initialization_flag()) | | 118 ContextLocalInitFlag::encode(var->initialization_flag()) | |
112 ContextLocalMaybeAssignedFlag::encode(var->maybe_assigned()); | 119 ContextLocalMaybeAssignedFlag::encode(var->maybe_assigned()); |
113 scope_info->set(index++, Smi::FromInt(value)); | 120 scope_info->set(index++, Smi::FromInt(value)); |
114 } | 121 } |
115 | 122 |
| 123 DCHECK(index == scope_info->StrongModeFreeVariableNameEntriesIndex()); |
| 124 for (int i = 0; i < strong_mode_free_variable_count; ++i) { |
| 125 scope_info->set(index++, *strong_mode_free_variables[i]->name()); |
| 126 } |
| 127 |
| 128 DCHECK(index == scope_info->StrongModeFreeVariablePositionEntriesIndex()); |
| 129 for (int i = 0; i < strong_mode_free_variable_count; ++i) { |
| 130 // Unfortunately, the source code positions are stored as int even though |
| 131 // int32_t would be enough (given the maximum source code length). |
| 132 Handle<Object> start_position = factory->NewNumberFromInt( |
| 133 static_cast<int32_t>(strong_mode_free_variables[i] |
| 134 ->strong_mode_reference_start_position())); |
| 135 scope_info->set(index++, *start_position); |
| 136 Handle<Object> end_position = factory->NewNumberFromInt( |
| 137 static_cast<int32_t>(strong_mode_free_variables[i] |
| 138 ->strong_mode_reference_end_position())); |
| 139 scope_info->set(index++, *end_position); |
| 140 } |
| 141 |
116 // If present, add the function variable name and its index. | 142 // If present, add the function variable name and its index. |
117 DCHECK(index == scope_info->FunctionNameEntryIndex()); | 143 DCHECK(index == scope_info->FunctionNameEntryIndex()); |
118 if (has_function_name) { | 144 if (has_function_name) { |
119 int var_index = scope->function()->proxy()->var()->index(); | 145 int var_index = scope->function()->proxy()->var()->index(); |
120 scope_info->set(index++, *scope->function()->proxy()->name()); | 146 scope_info->set(index++, *scope->function()->proxy()->name()); |
121 scope_info->set(index++, Smi::FromInt(var_index)); | 147 scope_info->set(index++, Smi::FromInt(var_index)); |
122 DCHECK(function_name_info != STACK || | 148 DCHECK(function_name_info != STACK || |
123 (var_index == scope_info->StackLocalCount() && | 149 (var_index == scope_info->StackLocalCount() && |
124 var_index == scope_info->StackSlotCount() - 1)); | 150 var_index == scope_info->StackSlotCount() - 1)); |
125 DCHECK(function_name_info != CONTEXT || | 151 DCHECK(function_name_info != CONTEXT || |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 DCHECK(0 <= var && var < LocalCount()); | 304 DCHECK(0 <= var && var < LocalCount()); |
279 // There's currently no flag stored on the ScopeInfo to indicate that a | 305 // There's currently no flag stored on the ScopeInfo to indicate that a |
280 // variable is a compiler-introduced temporary. However, to avoid conflict | 306 // variable is a compiler-introduced temporary. However, to avoid conflict |
281 // with user declarations, the current temporaries like .generator_object and | 307 // 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! | 308 // .result start with a dot, so we can use that as a flag. It's a hack! |
283 Handle<String> name(LocalName(var)); | 309 Handle<String> name(LocalName(var)); |
284 return name->length() > 0 && name->Get(0) == '.'; | 310 return name->length() > 0 && name->Get(0) == '.'; |
285 } | 311 } |
286 | 312 |
287 | 313 |
| 314 String* ScopeInfo::StrongModeFreeVariableName(int var) { |
| 315 DCHECK(0 <= var && var < StrongModeFreeVariableCount()); |
| 316 int info_index = StrongModeFreeVariableNameEntriesIndex() + var; |
| 317 return String::cast(get(info_index)); |
| 318 } |
| 319 |
| 320 |
| 321 int ScopeInfo::StrongModeFreeVariableStartPosition(int var) { |
| 322 DCHECK(0 <= var && var < StrongModeFreeVariableCount()); |
| 323 int info_index = StrongModeFreeVariablePositionEntriesIndex() + var * 2; |
| 324 int32_t value = 0; |
| 325 bool ok = get(info_index)->ToInt32(&value); |
| 326 USE(ok); |
| 327 DCHECK(ok); |
| 328 return value; |
| 329 } |
| 330 |
| 331 |
| 332 int ScopeInfo::StrongModeFreeVariableEndPosition(int var) { |
| 333 DCHECK(0 <= var && var < StrongModeFreeVariableCount()); |
| 334 int info_index = StrongModeFreeVariablePositionEntriesIndex() + var * 2 + 1; |
| 335 int32_t value = 0; |
| 336 bool ok = get(info_index)->ToInt32(&value); |
| 337 USE(ok); |
| 338 DCHECK(ok); |
| 339 return value; |
| 340 } |
| 341 |
| 342 |
288 int ScopeInfo::StackSlotIndex(String* name) { | 343 int ScopeInfo::StackSlotIndex(String* name) { |
289 DCHECK(name->IsInternalizedString()); | 344 DCHECK(name->IsInternalizedString()); |
290 if (length() > 0) { | 345 if (length() > 0) { |
291 int start = StackLocalEntriesIndex(); | 346 int start = StackLocalEntriesIndex(); |
292 int end = StackLocalEntriesIndex() + StackLocalCount(); | 347 int end = StackLocalEntriesIndex() + StackLocalCount(); |
293 for (int i = start; i < end; ++i) { | 348 for (int i = start; i < end; ++i) { |
294 if (name == get(i)) { | 349 if (name == get(i)) { |
295 return i - start; | 350 return i - start; |
296 } | 351 } |
297 } | 352 } |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 int ScopeInfo::ContextLocalNameEntriesIndex() { | 480 int ScopeInfo::ContextLocalNameEntriesIndex() { |
426 return StackLocalEntriesIndex() + StackLocalCount(); | 481 return StackLocalEntriesIndex() + StackLocalCount(); |
427 } | 482 } |
428 | 483 |
429 | 484 |
430 int ScopeInfo::ContextLocalInfoEntriesIndex() { | 485 int ScopeInfo::ContextLocalInfoEntriesIndex() { |
431 return ContextLocalNameEntriesIndex() + ContextLocalCount(); | 486 return ContextLocalNameEntriesIndex() + ContextLocalCount(); |
432 } | 487 } |
433 | 488 |
434 | 489 |
| 490 int ScopeInfo::StrongModeFreeVariableNameEntriesIndex() { |
| 491 return ContextLocalInfoEntriesIndex() + ContextLocalCount(); |
| 492 } |
| 493 |
| 494 |
| 495 int ScopeInfo::StrongModeFreeVariablePositionEntriesIndex() { |
| 496 return StrongModeFreeVariableNameEntriesIndex() + |
| 497 StrongModeFreeVariableCount(); |
| 498 } |
| 499 |
| 500 |
435 int ScopeInfo::FunctionNameEntryIndex() { | 501 int ScopeInfo::FunctionNameEntryIndex() { |
436 return ContextLocalInfoEntriesIndex() + ContextLocalCount(); | 502 return StrongModeFreeVariablePositionEntriesIndex() + |
| 503 2 * StrongModeFreeVariableCount(); |
437 } | 504 } |
438 | 505 |
439 | 506 |
440 int ContextSlotCache::Hash(Object* data, String* name) { | 507 int ContextSlotCache::Hash(Object* data, String* name) { |
441 // Uses only lower 32 bits if pointers are larger. | 508 // Uses only lower 32 bits if pointers are larger. |
442 uintptr_t addr_hash = | 509 uintptr_t addr_hash = |
443 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2; | 510 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2; |
444 return static_cast<int>((addr_hash ^ name->Hash()) % kLength); | 511 return static_cast<int>((addr_hash ^ name->Hash()) % kLength); |
445 } | 512 } |
446 | 513 |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
576 info->set_name(i, *(it.export_name()->string())); | 643 info->set_name(i, *(it.export_name()->string())); |
577 info->set_mode(i, var->mode()); | 644 info->set_mode(i, var->mode()); |
578 DCHECK(var->index() >= 0); | 645 DCHECK(var->index() >= 0); |
579 info->set_index(i, var->index()); | 646 info->set_index(i, var->index()); |
580 } | 647 } |
581 DCHECK(i == info->length()); | 648 DCHECK(i == info->length()); |
582 return info; | 649 return info; |
583 } | 650 } |
584 | 651 |
585 } } // namespace v8::internal | 652 } } // namespace v8::internal |
OLD | NEW |