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 int start_position = | |
131 strong_mode_free_variables[i]->strong_mode_reference_start_position(); | |
132 if (Smi::IsValid(start_position)) { | |
Dmitry Lomov (no reviews)
2015/03/24 14:51:46
Factory::NewNumberFromInt does this.
marja
2015/03/24 16:46:14
Done.
| |
133 scope_info->set(index++, Smi::FromInt(start_position)); | |
134 } else { | |
135 Handle<HeapNumber> number = factory->NewHeapNumber(start_position); | |
136 scope_info->set(index++, *number); | |
137 } | |
138 int end_position = | |
139 strong_mode_free_variables[i]->strong_mode_reference_end_position(); | |
140 if (Smi::IsValid(end_position)) { | |
141 scope_info->set(index++, Smi::FromInt(end_position)); | |
142 } else { | |
143 Handle<HeapNumber> number = factory->NewHeapNumber(end_position); | |
144 scope_info->set(index++, *number); | |
145 } | |
146 } | |
147 | |
116 // If present, add the function variable name and its index. | 148 // If present, add the function variable name and its index. |
117 DCHECK(index == scope_info->FunctionNameEntryIndex()); | 149 DCHECK(index == scope_info->FunctionNameEntryIndex()); |
118 if (has_function_name) { | 150 if (has_function_name) { |
119 int var_index = scope->function()->proxy()->var()->index(); | 151 int var_index = scope->function()->proxy()->var()->index(); |
120 scope_info->set(index++, *scope->function()->proxy()->name()); | 152 scope_info->set(index++, *scope->function()->proxy()->name()); |
121 scope_info->set(index++, Smi::FromInt(var_index)); | 153 scope_info->set(index++, Smi::FromInt(var_index)); |
122 DCHECK(function_name_info != STACK || | 154 DCHECK(function_name_info != STACK || |
123 (var_index == scope_info->StackLocalCount() && | 155 (var_index == scope_info->StackLocalCount() && |
124 var_index == scope_info->StackSlotCount() - 1)); | 156 var_index == scope_info->StackSlotCount() - 1)); |
125 DCHECK(function_name_info != CONTEXT || | 157 DCHECK(function_name_info != CONTEXT || |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
278 DCHECK(0 <= var && var < LocalCount()); | 310 DCHECK(0 <= var && var < LocalCount()); |
279 // There's currently no flag stored on the ScopeInfo to indicate that a | 311 // There's currently no flag stored on the ScopeInfo to indicate that a |
280 // variable is a compiler-introduced temporary. However, to avoid conflict | 312 // variable is a compiler-introduced temporary. However, to avoid conflict |
281 // with user declarations, the current temporaries like .generator_object and | 313 // 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! | 314 // .result start with a dot, so we can use that as a flag. It's a hack! |
283 Handle<String> name(LocalName(var)); | 315 Handle<String> name(LocalName(var)); |
284 return name->length() > 0 && name->Get(0) == '.'; | 316 return name->length() > 0 && name->Get(0) == '.'; |
285 } | 317 } |
286 | 318 |
287 | 319 |
320 String* ScopeInfo::StrongModeFreeVariableName(int var) { | |
321 DCHECK(0 <= var && var < StrongModeFreeVariableCount()); | |
322 int info_index = StrongModeFreeVariableNameEntriesIndex() + var; | |
323 return String::cast(get(info_index)); | |
324 } | |
325 | |
326 | |
327 namespace { | |
328 | |
329 int IntFromSmiOrHeapNumber(Object* value) { | |
330 if (value->IsSmi()) return Smi::cast(value)->value(); | |
331 DCHECK(value->IsHeapNumber()); | |
332 return static_cast<int>(HeapNumber::cast(value)->value()); | |
333 } | |
334 | |
335 } // namespace | |
336 | |
337 | |
338 int ScopeInfo::StrongModeFreeVariableStartPosition(int var) { | |
339 DCHECK(0 <= var && var < StrongModeFreeVariableCount()); | |
340 int info_index = StrongModeFreeVariablePositionEntriesIndex() + var * 2; | |
341 return IntFromSmiOrHeapNumber(get(info_index)); | |
342 } | |
343 | |
344 | |
345 int ScopeInfo::StrongModeFreeVariableEndPosition(int var) { | |
346 DCHECK(0 <= var && var < StrongModeFreeVariableCount()); | |
347 int info_index = StrongModeFreeVariablePositionEntriesIndex() + var * 2 + 1; | |
348 return IntFromSmiOrHeapNumber(get(info_index)); | |
349 } | |
350 | |
351 | |
288 int ScopeInfo::StackSlotIndex(String* name) { | 352 int ScopeInfo::StackSlotIndex(String* name) { |
289 DCHECK(name->IsInternalizedString()); | 353 DCHECK(name->IsInternalizedString()); |
290 if (length() > 0) { | 354 if (length() > 0) { |
291 int start = StackLocalEntriesIndex(); | 355 int start = StackLocalEntriesIndex(); |
292 int end = StackLocalEntriesIndex() + StackLocalCount(); | 356 int end = StackLocalEntriesIndex() + StackLocalCount(); |
293 for (int i = start; i < end; ++i) { | 357 for (int i = start; i < end; ++i) { |
294 if (name == get(i)) { | 358 if (name == get(i)) { |
295 return i - start; | 359 return i - start; |
296 } | 360 } |
297 } | 361 } |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
425 int ScopeInfo::ContextLocalNameEntriesIndex() { | 489 int ScopeInfo::ContextLocalNameEntriesIndex() { |
426 return StackLocalEntriesIndex() + StackLocalCount(); | 490 return StackLocalEntriesIndex() + StackLocalCount(); |
427 } | 491 } |
428 | 492 |
429 | 493 |
430 int ScopeInfo::ContextLocalInfoEntriesIndex() { | 494 int ScopeInfo::ContextLocalInfoEntriesIndex() { |
431 return ContextLocalNameEntriesIndex() + ContextLocalCount(); | 495 return ContextLocalNameEntriesIndex() + ContextLocalCount(); |
432 } | 496 } |
433 | 497 |
434 | 498 |
499 int ScopeInfo::StrongModeFreeVariableNameEntriesIndex() { | |
500 return ContextLocalInfoEntriesIndex() + ContextLocalCount(); | |
501 } | |
502 | |
503 | |
504 int ScopeInfo::StrongModeFreeVariablePositionEntriesIndex() { | |
505 return StrongModeFreeVariableNameEntriesIndex() + | |
506 StrongModeFreeVariableCount(); | |
507 } | |
508 | |
509 | |
435 int ScopeInfo::FunctionNameEntryIndex() { | 510 int ScopeInfo::FunctionNameEntryIndex() { |
436 return ContextLocalInfoEntriesIndex() + ContextLocalCount(); | 511 return StrongModeFreeVariablePositionEntriesIndex() + |
512 2 * StrongModeFreeVariableCount(); | |
437 } | 513 } |
438 | 514 |
439 | 515 |
440 int ContextSlotCache::Hash(Object* data, String* name) { | 516 int ContextSlotCache::Hash(Object* data, String* name) { |
441 // Uses only lower 32 bits if pointers are larger. | 517 // Uses only lower 32 bits if pointers are larger. |
442 uintptr_t addr_hash = | 518 uintptr_t addr_hash = |
443 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2; | 519 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2; |
444 return static_cast<int>((addr_hash ^ name->Hash()) % kLength); | 520 return static_cast<int>((addr_hash ^ name->Hash()) % kLength); |
445 } | 521 } |
446 | 522 |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
576 info->set_name(i, *(it.export_name()->string())); | 652 info->set_name(i, *(it.export_name()->string())); |
577 info->set_mode(i, var->mode()); | 653 info->set_mode(i, var->mode()); |
578 DCHECK(var->index() >= 0); | 654 DCHECK(var->index() >= 0); |
579 info->set_index(i, var->index()); | 655 info->set_index(i, var->index()); |
580 } | 656 } |
581 DCHECK(i == info->length()); | 657 DCHECK(i == info->length()); |
582 return info; | 658 return info; |
583 } | 659 } |
584 | 660 |
585 } } // namespace v8::internal | 661 } } // namespace v8::internal |
OLD | NEW |