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/ast/context-slot-cache.h" | 7 #include "src/ast/context-slot-cache.h" |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 | 10 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 function_variable_mode = var->mode(); | 64 function_variable_mode = var->mode(); |
65 } else { | 65 } else { |
66 function_name_info = NONE; | 66 function_name_info = NONE; |
67 function_variable_mode = VAR; | 67 function_variable_mode = VAR; |
68 } | 68 } |
69 DCHECK(context_global_count == 0 || scope->scope_type() == SCRIPT_SCOPE); | 69 DCHECK(context_global_count == 0 || scope->scope_type() == SCRIPT_SCOPE); |
70 | 70 |
71 const bool has_function_name = function_name_info != NONE; | 71 const bool has_function_name = function_name_info != NONE; |
72 const bool has_receiver = receiver_info == STACK || receiver_info == CONTEXT; | 72 const bool has_receiver = receiver_info == STACK || receiver_info == CONTEXT; |
73 const int parameter_count = scope->num_parameters(); | 73 const int parameter_count = scope->num_parameters(); |
| 74 const bool has_outer_scope_info = |
| 75 scope->GetOuterScopeWithContext() != nullptr; |
74 const int length = kVariablePartIndex + parameter_count + | 76 const int length = kVariablePartIndex + parameter_count + |
75 (1 + stack_local_count) + 2 * context_local_count + | 77 (1 + stack_local_count) + 2 * context_local_count + |
76 2 * context_global_count + | 78 2 * context_global_count + (has_receiver ? 1 : 0) + |
77 (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0); | 79 (has_function_name ? 2 : 0) + |
| 80 (has_outer_scope_info ? 1 : 0); |
78 | 81 |
79 Factory* factory = isolate->factory(); | 82 Factory* factory = isolate->factory(); |
80 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); | 83 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); |
81 | 84 |
82 bool has_simple_parameters = false; | 85 bool has_simple_parameters = false; |
83 bool asm_module = false; | 86 bool asm_module = false; |
84 bool asm_function = false; | 87 bool asm_function = false; |
85 FunctionKind function_kind = kNormalFunction; | 88 FunctionKind function_kind = kNormalFunction; |
86 if (scope->is_function_scope()) { | 89 if (scope->is_function_scope()) { |
87 DeclarationScope* function_scope = scope->AsDeclarationScope(); | 90 DeclarationScope* function_scope = scope->AsDeclarationScope(); |
88 has_simple_parameters = function_scope->has_simple_parameters(); | 91 has_simple_parameters = function_scope->has_simple_parameters(); |
89 asm_module = function_scope->asm_module(); | 92 asm_module = function_scope->asm_module(); |
90 asm_function = function_scope->asm_function(); | 93 asm_function = function_scope->asm_function(); |
91 function_kind = function_scope->function_kind(); | 94 function_kind = function_scope->function_kind(); |
92 } | 95 } |
93 | 96 |
94 // Encode the flags. | 97 // Encode the flags. |
95 int flags = ScopeTypeField::encode(scope->scope_type()) | | 98 int flags = ScopeTypeField::encode(scope->scope_type()) | |
96 CallsEvalField::encode(scope->calls_eval()) | | 99 CallsEvalField::encode(scope->calls_eval()) | |
97 LanguageModeField::encode(scope->language_mode()) | | 100 LanguageModeField::encode(scope->language_mode()) | |
98 DeclarationScopeField::encode(scope->is_declaration_scope()) | | 101 DeclarationScopeField::encode(scope->is_declaration_scope()) | |
99 ReceiverVariableField::encode(receiver_info) | | 102 ReceiverVariableField::encode(receiver_info) | |
100 HasNewTargetField::encode(has_new_target) | | 103 HasNewTargetField::encode(has_new_target) | |
101 FunctionVariableField::encode(function_name_info) | | 104 FunctionVariableField::encode(function_name_info) | |
102 FunctionVariableMode::encode(function_variable_mode) | | 105 FunctionVariableMode::encode(function_variable_mode) | |
103 AsmModuleField::encode(asm_module) | | 106 AsmModuleField::encode(asm_module) | |
104 AsmFunctionField::encode(asm_function) | | 107 AsmFunctionField::encode(asm_function) | |
105 HasSimpleParametersField::encode(has_simple_parameters) | | 108 HasSimpleParametersField::encode(has_simple_parameters) | |
106 FunctionKindField::encode(function_kind); | 109 FunctionKindField::encode(function_kind) | |
| 110 HasOuterScopeInfoField::encode(has_outer_scope_info); |
107 scope_info->SetFlags(flags); | 111 scope_info->SetFlags(flags); |
108 scope_info->SetParameterCount(parameter_count); | 112 scope_info->SetParameterCount(parameter_count); |
109 scope_info->SetStackLocalCount(stack_local_count); | 113 scope_info->SetStackLocalCount(stack_local_count); |
110 scope_info->SetContextLocalCount(context_local_count); | 114 scope_info->SetContextLocalCount(context_local_count); |
111 scope_info->SetContextGlobalCount(context_global_count); | 115 scope_info->SetContextGlobalCount(context_global_count); |
112 | 116 |
113 int index = kVariablePartIndex; | 117 int index = kVariablePartIndex; |
114 // Add parameters. | 118 // Add parameters. |
115 DCHECK_EQ(index, scope_info->ParameterEntriesIndex()); | 119 DCHECK_EQ(index, scope_info->ParameterEntriesIndex()); |
116 if (scope->is_declaration_scope()) { | 120 if (scope->is_declaration_scope()) { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 DCHECK(index == scope_info->FunctionNameEntryIndex()); | 188 DCHECK(index == scope_info->FunctionNameEntryIndex()); |
185 if (has_function_name) { | 189 if (has_function_name) { |
186 int var_index = scope->AsDeclarationScope()->function_var()->index(); | 190 int var_index = scope->AsDeclarationScope()->function_var()->index(); |
187 scope_info->set(index++, | 191 scope_info->set(index++, |
188 *scope->AsDeclarationScope()->function_var()->name()); | 192 *scope->AsDeclarationScope()->function_var()->name()); |
189 scope_info->set(index++, Smi::FromInt(var_index)); | 193 scope_info->set(index++, Smi::FromInt(var_index)); |
190 DCHECK(function_name_info != CONTEXT || | 194 DCHECK(function_name_info != CONTEXT || |
191 var_index == scope_info->ContextLength() - 1); | 195 var_index == scope_info->ContextLength() - 1); |
192 } | 196 } |
193 | 197 |
| 198 // If present, add the outer scope info. |
| 199 DCHECK(index == scope_info->OuterScopeInfoEntryIndex()); |
| 200 if (has_outer_scope_info) { |
| 201 Handle<ScopeInfo> outer_scope_info = |
| 202 scope->GetOuterScopeWithContext()->GetScopeInfo(isolate); |
| 203 scope_info->set(index++, *outer_scope_info); |
| 204 } |
| 205 |
194 DCHECK(index == scope_info->length()); | 206 DCHECK(index == scope_info->length()); |
195 DCHECK(scope->num_parameters() == scope_info->ParameterCount()); | 207 DCHECK(scope->num_parameters() == scope_info->ParameterCount()); |
196 DCHECK(scope->num_heap_slots() == scope_info->ContextLength() || | 208 DCHECK(scope->num_heap_slots() == scope_info->ContextLength() || |
197 (scope->num_heap_slots() == kVariablePartIndex && | 209 (scope->num_heap_slots() == kVariablePartIndex && |
198 scope_info->ContextLength() == 0)); | 210 scope_info->ContextLength() == 0)); |
199 return scope_info; | 211 return scope_info; |
200 } | 212 } |
201 | 213 |
202 | 214 |
203 Handle<ScopeInfo> ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) { | 215 Handle<ScopeInfo> ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) { |
204 DCHECK(isolate->bootstrapper()->IsActive()); | 216 DCHECK(isolate->bootstrapper()->IsActive()); |
205 | 217 |
206 const int stack_local_count = 0; | 218 const int stack_local_count = 0; |
207 const int context_local_count = 1; | 219 const int context_local_count = 1; |
208 const int context_global_count = 0; | 220 const int context_global_count = 0; |
209 const bool has_simple_parameters = true; | 221 const bool has_simple_parameters = true; |
210 const VariableAllocationInfo receiver_info = CONTEXT; | 222 const VariableAllocationInfo receiver_info = CONTEXT; |
211 const VariableAllocationInfo function_name_info = NONE; | 223 const VariableAllocationInfo function_name_info = NONE; |
212 const VariableMode function_variable_mode = VAR; | 224 const VariableMode function_variable_mode = VAR; |
213 const bool has_function_name = false; | 225 const bool has_function_name = false; |
214 const bool has_receiver = true; | 226 const bool has_receiver = true; |
| 227 const bool has_outer_scope_info = false; |
215 const int parameter_count = 0; | 228 const int parameter_count = 0; |
216 const int length = kVariablePartIndex + parameter_count + | 229 const int length = kVariablePartIndex + parameter_count + |
217 (1 + stack_local_count) + 2 * context_local_count + | 230 (1 + stack_local_count) + 2 * context_local_count + |
218 2 * context_global_count + | 231 2 * context_global_count + (has_receiver ? 1 : 0) + |
219 (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0); | 232 (has_function_name ? 2 : 0) + |
| 233 (has_outer_scope_info ? 1 : 0); |
220 | 234 |
221 Factory* factory = isolate->factory(); | 235 Factory* factory = isolate->factory(); |
222 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); | 236 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); |
223 | 237 |
224 // Encode the flags. | 238 // Encode the flags. |
225 int flags = ScopeTypeField::encode(SCRIPT_SCOPE) | | 239 int flags = |
226 CallsEvalField::encode(false) | | 240 ScopeTypeField::encode(SCRIPT_SCOPE) | CallsEvalField::encode(false) | |
227 LanguageModeField::encode(SLOPPY) | | 241 LanguageModeField::encode(SLOPPY) | DeclarationScopeField::encode(true) | |
228 DeclarationScopeField::encode(true) | | 242 ReceiverVariableField::encode(receiver_info) | |
229 ReceiverVariableField::encode(receiver_info) | | 243 FunctionVariableField::encode(function_name_info) | |
230 FunctionVariableField::encode(function_name_info) | | 244 FunctionVariableMode::encode(function_variable_mode) | |
231 FunctionVariableMode::encode(function_variable_mode) | | 245 AsmModuleField::encode(false) | AsmFunctionField::encode(false) | |
232 AsmModuleField::encode(false) | AsmFunctionField::encode(false) | | 246 HasSimpleParametersField::encode(has_simple_parameters) | |
233 HasSimpleParametersField::encode(has_simple_parameters) | | 247 FunctionKindField::encode(FunctionKind::kNormalFunction) | |
234 FunctionKindField::encode(FunctionKind::kNormalFunction); | 248 HasOuterScopeInfoField::encode(has_outer_scope_info); |
235 scope_info->SetFlags(flags); | 249 scope_info->SetFlags(flags); |
236 scope_info->SetParameterCount(parameter_count); | 250 scope_info->SetParameterCount(parameter_count); |
237 scope_info->SetStackLocalCount(stack_local_count); | 251 scope_info->SetStackLocalCount(stack_local_count); |
238 scope_info->SetContextLocalCount(context_local_count); | 252 scope_info->SetContextLocalCount(context_local_count); |
239 scope_info->SetContextGlobalCount(context_global_count); | 253 scope_info->SetContextGlobalCount(context_global_count); |
240 | 254 |
241 int index = kVariablePartIndex; | 255 int index = kVariablePartIndex; |
242 const int first_slot_index = 0; | 256 const int first_slot_index = 0; |
243 DCHECK(index == scope_info->StackLocalFirstSlotIndex()); | 257 DCHECK(index == scope_info->StackLocalFirstSlotIndex()); |
244 scope_info->set(index++, Smi::FromInt(first_slot_index)); | 258 scope_info->set(index++, Smi::FromInt(first_slot_index)); |
245 DCHECK(index == scope_info->StackLocalEntriesIndex()); | 259 DCHECK(index == scope_info->StackLocalEntriesIndex()); |
246 | 260 |
247 // Here we add info for context-allocated "this". | 261 // Here we add info for context-allocated "this". |
248 DCHECK(index == scope_info->ContextLocalNameEntriesIndex()); | 262 DCHECK(index == scope_info->ContextLocalNameEntriesIndex()); |
249 scope_info->set(index++, *isolate->factory()->this_string()); | 263 scope_info->set(index++, *isolate->factory()->this_string()); |
250 DCHECK(index == scope_info->ContextLocalInfoEntriesIndex()); | 264 DCHECK(index == scope_info->ContextLocalInfoEntriesIndex()); |
251 const uint32_t value = VariableModeField::encode(CONST) | | 265 const uint32_t value = VariableModeField::encode(CONST) | |
252 InitFlagField::encode(kCreatedInitialized) | | 266 InitFlagField::encode(kCreatedInitialized) | |
253 MaybeAssignedFlagField::encode(kNotAssigned); | 267 MaybeAssignedFlagField::encode(kNotAssigned); |
254 scope_info->set(index++, Smi::FromInt(value)); | 268 scope_info->set(index++, Smi::FromInt(value)); |
255 | 269 |
256 // And here we record that this scopeinfo binds a receiver. | 270 // And here we record that this scopeinfo binds a receiver. |
257 DCHECK(index == scope_info->ReceiverEntryIndex()); | 271 DCHECK(index == scope_info->ReceiverEntryIndex()); |
258 const int receiver_index = Context::MIN_CONTEXT_SLOTS + 0; | 272 const int receiver_index = Context::MIN_CONTEXT_SLOTS + 0; |
259 scope_info->set(index++, Smi::FromInt(receiver_index)); | 273 scope_info->set(index++, Smi::FromInt(receiver_index)); |
260 | 274 |
261 DCHECK(index == scope_info->FunctionNameEntryIndex()); | 275 DCHECK(index == scope_info->FunctionNameEntryIndex()); |
| 276 DCHECK(index == scope_info->OuterScopeInfoEntryIndex()); |
262 | 277 |
263 DCHECK_EQ(index, scope_info->length()); | 278 DCHECK_EQ(index, scope_info->length()); |
264 DCHECK_EQ(scope_info->ParameterCount(), 0); | 279 DCHECK_EQ(scope_info->ParameterCount(), 0); |
265 DCHECK_EQ(scope_info->ContextLength(), Context::MIN_CONTEXT_SLOTS + 1); | 280 DCHECK_EQ(scope_info->ContextLength(), Context::MIN_CONTEXT_SLOTS + 1); |
266 | 281 |
267 return scope_info; | 282 return scope_info; |
268 } | 283 } |
269 | 284 |
270 | 285 |
271 ScopeInfo* ScopeInfo::Empty(Isolate* isolate) { | 286 ScopeInfo* ScopeInfo::Empty(Isolate* isolate) { |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 | 370 |
356 | 371 |
357 bool ScopeInfo::HasFunctionName() { | 372 bool ScopeInfo::HasFunctionName() { |
358 if (length() > 0) { | 373 if (length() > 0) { |
359 return NONE != FunctionVariableField::decode(Flags()); | 374 return NONE != FunctionVariableField::decode(Flags()); |
360 } else { | 375 } else { |
361 return false; | 376 return false; |
362 } | 377 } |
363 } | 378 } |
364 | 379 |
| 380 bool ScopeInfo::HasOuterScopeInfo() { |
| 381 if (length() > 0) { |
| 382 return HasOuterScopeInfoField::decode(Flags()); |
| 383 } else { |
| 384 return false; |
| 385 } |
| 386 } |
365 | 387 |
366 bool ScopeInfo::HasHeapAllocatedLocals() { | 388 bool ScopeInfo::HasHeapAllocatedLocals() { |
367 if (length() > 0) { | 389 if (length() > 0) { |
368 return ContextLocalCount() > 0; | 390 return ContextLocalCount() > 0; |
369 } else { | 391 } else { |
370 return false; | 392 return false; |
371 } | 393 } |
372 } | 394 } |
373 | 395 |
374 | 396 |
375 bool ScopeInfo::HasContext() { | 397 bool ScopeInfo::HasContext() { |
376 return ContextLength() > 0; | 398 return ContextLength() > 0; |
377 } | 399 } |
378 | 400 |
379 | 401 |
380 String* ScopeInfo::FunctionName() { | 402 String* ScopeInfo::FunctionName() { |
381 DCHECK(HasFunctionName()); | 403 DCHECK(HasFunctionName()); |
382 return String::cast(get(FunctionNameEntryIndex())); | 404 return String::cast(get(FunctionNameEntryIndex())); |
383 } | 405 } |
384 | 406 |
| 407 ScopeInfo* ScopeInfo::OuterScopeInfo() { |
| 408 DCHECK(HasOuterScopeInfo()); |
| 409 return ScopeInfo::cast(get(OuterScopeInfoEntryIndex())); |
| 410 } |
385 | 411 |
386 String* ScopeInfo::ParameterName(int var) { | 412 String* ScopeInfo::ParameterName(int var) { |
387 DCHECK(0 <= var && var < ParameterCount()); | 413 DCHECK(0 <= var && var < ParameterCount()); |
388 int info_index = ParameterEntriesIndex() + var; | 414 int info_index = ParameterEntriesIndex() + var; |
389 return String::cast(get(info_index)); | 415 return String::cast(get(info_index)); |
390 } | 416 } |
391 | 417 |
392 | 418 |
393 String* ScopeInfo::LocalName(int var) { | 419 String* ScopeInfo::LocalName(int var) { |
394 DCHECK(0 <= var && var < LocalCount()); | 420 DCHECK(0 <= var && var < LocalCount()); |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
636 | 662 |
637 int ScopeInfo::ReceiverEntryIndex() { | 663 int ScopeInfo::ReceiverEntryIndex() { |
638 return ContextGlobalInfoEntriesIndex() + ContextGlobalCount(); | 664 return ContextGlobalInfoEntriesIndex() + ContextGlobalCount(); |
639 } | 665 } |
640 | 666 |
641 | 667 |
642 int ScopeInfo::FunctionNameEntryIndex() { | 668 int ScopeInfo::FunctionNameEntryIndex() { |
643 return ReceiverEntryIndex() + (HasAllocatedReceiver() ? 1 : 0); | 669 return ReceiverEntryIndex() + (HasAllocatedReceiver() ? 1 : 0); |
644 } | 670 } |
645 | 671 |
| 672 int ScopeInfo::OuterScopeInfoEntryIndex() { |
| 673 return FunctionNameEntryIndex() + (HasFunctionName() ? 2 : 0); |
| 674 } |
| 675 |
646 #ifdef DEBUG | 676 #ifdef DEBUG |
647 | 677 |
648 static void PrintList(const char* list_name, | 678 static void PrintList(const char* list_name, |
649 int nof_internal_slots, | 679 int nof_internal_slots, |
650 int start, | 680 int start, |
651 int end, | 681 int end, |
652 ScopeInfo* scope_info) { | 682 ScopeInfo* scope_info) { |
653 if (start < end) { | 683 if (start < end) { |
654 PrintF("\n // %s\n", list_name); | 684 PrintF("\n // %s\n", list_name); |
655 if (nof_internal_slots > 0) { | 685 if (nof_internal_slots > 0) { |
(...skipping 27 matching lines...) Expand all Loading... |
683 ContextLocalNameEntriesIndex() + ContextLocalCount(), this); | 713 ContextLocalNameEntriesIndex() + ContextLocalCount(), this); |
684 } | 714 } |
685 | 715 |
686 PrintF("}\n"); | 716 PrintF("}\n"); |
687 } | 717 } |
688 #endif // DEBUG | 718 #endif // DEBUG |
689 | 719 |
690 | 720 |
691 } // namespace internal | 721 } // namespace internal |
692 } // namespace v8 | 722 } // namespace v8 |
OLD | NEW |