Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(491)

Side by Side Diff: src/scopeinfo.cc

Issue 1140633003: Reapply "Resolve references to "this" the same way as normal variables"" (Closed) Base URL: https://chromium.googlesource.com/v8/v8@master
Patch Set: ScopeInfo records slot of "this" binding; formatting Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/runtime/runtime-scopes.cc ('k') | src/scopes.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
(...skipping 14 matching lines...) Expand all
25 const int stack_local_count = stack_locals.length(); 25 const int stack_local_count = stack_locals.length();
26 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 = 27 const int strong_mode_free_variable_count =
28 strong_mode_free_variables.length(); 28 strong_mode_free_variables.length();
29 // Make sure we allocate the correct amount. 29 // Make sure we allocate the correct amount.
30 DCHECK(scope->ContextLocalCount() == context_local_count); 30 DCHECK(scope->ContextLocalCount() == context_local_count);
31 31
32 bool simple_parameter_list = 32 bool simple_parameter_list =
33 scope->is_function_scope() ? scope->is_simple_parameter_list() : true; 33 scope->is_function_scope() ? scope->is_simple_parameter_list() : true;
34 34
35 // Determine use and location of the "this" binding if it is present.
36 VariableAllocationInfo receiver_info;
37 if (scope->has_this_declaration()) {
38 Variable* var = scope->receiver();
39 if (!var->is_used()) {
40 receiver_info = UNUSED;
41 } else if (var->IsContextSlot()) {
42 receiver_info = CONTEXT;
43 } else {
44 DCHECK(var->IsParameter());
45 receiver_info = STACK;
46 }
47 } else {
48 receiver_info = NONE;
49 }
50
35 // Determine use and location of the function variable if it is present. 51 // Determine use and location of the function variable if it is present.
36 FunctionVariableInfo function_name_info; 52 VariableAllocationInfo function_name_info;
37 VariableMode function_variable_mode; 53 VariableMode function_variable_mode;
38 if (scope->is_function_scope() && scope->function() != NULL) { 54 if (scope->is_function_scope() && scope->function() != NULL) {
39 Variable* var = scope->function()->proxy()->var(); 55 Variable* var = scope->function()->proxy()->var();
40 if (!var->is_used()) { 56 if (!var->is_used()) {
41 function_name_info = UNUSED; 57 function_name_info = UNUSED;
42 } else if (var->IsContextSlot()) { 58 } else if (var->IsContextSlot()) {
43 function_name_info = CONTEXT; 59 function_name_info = CONTEXT;
44 } else { 60 } else {
45 DCHECK(var->IsStackLocal()); 61 DCHECK(var->IsStackLocal());
46 function_name_info = STACK; 62 function_name_info = STACK;
47 } 63 }
48 function_variable_mode = var->mode(); 64 function_variable_mode = var->mode();
49 } else { 65 } else {
50 function_name_info = NONE; 66 function_name_info = NONE;
51 function_variable_mode = VAR; 67 function_variable_mode = VAR;
52 } 68 }
53 69
54 const bool has_function_name = function_name_info != NONE; 70 const bool has_function_name = function_name_info != NONE;
71 const bool has_receiver = receiver_info == STACK || receiver_info == CONTEXT;
55 const int parameter_count = scope->num_parameters(); 72 const int parameter_count = scope->num_parameters();
56 const int length = kVariablePartIndex + parameter_count + 73 const int length = kVariablePartIndex + parameter_count +
57 (1 + stack_local_count) + 2 * context_local_count + 74 (1 + stack_local_count) + 2 * context_local_count +
58 3 * strong_mode_free_variable_count + 75 3 * strong_mode_free_variable_count +
59 (has_function_name ? 2 : 0); 76 (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0);
60 77
61 Factory* factory = isolate->factory(); 78 Factory* factory = isolate->factory();
62 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); 79 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
63 80
64 // Encode the flags. 81 // Encode the flags.
65 int flags = ScopeTypeField::encode(scope->scope_type()) | 82 int flags = ScopeTypeField::encode(scope->scope_type()) |
66 CallsEvalField::encode(scope->calls_eval()) | 83 CallsEvalField::encode(scope->calls_eval()) |
67 LanguageModeField::encode(scope->language_mode()) | 84 LanguageModeField::encode(scope->language_mode()) |
85 ReceiverVariableField::encode(receiver_info) |
68 FunctionVariableField::encode(function_name_info) | 86 FunctionVariableField::encode(function_name_info) |
69 FunctionVariableMode::encode(function_variable_mode) | 87 FunctionVariableMode::encode(function_variable_mode) |
70 AsmModuleField::encode(scope->asm_module()) | 88 AsmModuleField::encode(scope->asm_module()) |
71 AsmFunctionField::encode(scope->asm_function()) | 89 AsmFunctionField::encode(scope->asm_function()) |
72 IsSimpleParameterListField::encode(simple_parameter_list) | 90 IsSimpleParameterListField::encode(simple_parameter_list) |
73 BlockScopeIsClassScopeField::encode(scope->is_class_scope()) | 91 BlockScopeIsClassScopeField::encode(scope->is_class_scope()) |
74 FunctionKindField::encode(scope->function_kind()); 92 FunctionKindField::encode(scope->function_kind());
75 scope_info->SetFlags(flags); 93 scope_info->SetFlags(flags);
76 scope_info->SetParameterCount(parameter_count); 94 scope_info->SetParameterCount(parameter_count);
77 scope_info->SetStackLocalCount(stack_local_count); 95 scope_info->SetStackLocalCount(stack_local_count);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 Handle<Object> start_position = factory->NewNumberFromInt( 157 Handle<Object> start_position = factory->NewNumberFromInt(
140 static_cast<int32_t>(strong_mode_free_variables[i] 158 static_cast<int32_t>(strong_mode_free_variables[i]
141 ->strong_mode_reference_start_position())); 159 ->strong_mode_reference_start_position()));
142 scope_info->set(index++, *start_position); 160 scope_info->set(index++, *start_position);
143 Handle<Object> end_position = factory->NewNumberFromInt( 161 Handle<Object> end_position = factory->NewNumberFromInt(
144 static_cast<int32_t>(strong_mode_free_variables[i] 162 static_cast<int32_t>(strong_mode_free_variables[i]
145 ->strong_mode_reference_end_position())); 163 ->strong_mode_reference_end_position()));
146 scope_info->set(index++, *end_position); 164 scope_info->set(index++, *end_position);
147 } 165 }
148 166
167 // If the receiver is allocated, add its index.
168 DCHECK(index == scope_info->ReceiverEntryIndex());
169 if (has_receiver) {
170 int var_index = scope->receiver()->index();
171 scope_info->set(index++, Smi::FromInt(var_index));
172 // ?? DCHECK(receiver_info != CONTEXT || var_index ==
173 // scope_info->ContextLength() - 1);
174 }
175
149 // If present, add the function variable name and its index. 176 // If present, add the function variable name and its index.
150 DCHECK(index == scope_info->FunctionNameEntryIndex()); 177 DCHECK(index == scope_info->FunctionNameEntryIndex());
151 if (has_function_name) { 178 if (has_function_name) {
152 int var_index = scope->function()->proxy()->var()->index(); 179 int var_index = scope->function()->proxy()->var()->index();
153 scope_info->set(index++, *scope->function()->proxy()->name()); 180 scope_info->set(index++, *scope->function()->proxy()->name());
154 scope_info->set(index++, Smi::FromInt(var_index)); 181 scope_info->set(index++, Smi::FromInt(var_index));
155 DCHECK(function_name_info != CONTEXT || 182 DCHECK(function_name_info != CONTEXT ||
156 var_index == scope_info->ContextLength() - 1); 183 var_index == scope_info->ContextLength() - 1);
157 } 184 }
158 185
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 scope_type() == MODULE_SCOPE; 240 scope_type() == MODULE_SCOPE;
214 if (has_context) { 241 if (has_context) {
215 return Context::MIN_CONTEXT_SLOTS + context_locals + 242 return Context::MIN_CONTEXT_SLOTS + context_locals +
216 (function_name_context_slot ? 1 : 0); 243 (function_name_context_slot ? 1 : 0);
217 } 244 }
218 } 245 }
219 return 0; 246 return 0;
220 } 247 }
221 248
222 249
250 bool ScopeInfo::HasReceiver() {
251 if (length() > 0) {
252 return NONE != ReceiverVariableField::decode(Flags());
253 } else {
254 return false;
255 }
256 }
257
258
259 bool ScopeInfo::HasAllocatedReceiver() {
260 if (length() > 0) {
261 VariableAllocationInfo allocation = ReceiverVariableField::decode(Flags());
262 return allocation == STACK || allocation == CONTEXT;
263 } else {
264 return false;
265 }
266 }
267
268
223 bool ScopeInfo::HasFunctionName() { 269 bool ScopeInfo::HasFunctionName() {
224 if (length() > 0) { 270 if (length() > 0) {
225 return NONE != FunctionVariableField::decode(Flags()); 271 return NONE != FunctionVariableField::decode(Flags());
226 } else { 272 } else {
227 return false; 273 return false;
228 } 274 }
229 } 275 }
230 276
231 277
232 bool ScopeInfo::HasHeapAllocatedLocals() { 278 bool ScopeInfo::HasHeapAllocatedLocals() {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 } 356 }
311 357
312 358
313 bool ScopeInfo::LocalIsSynthetic(int var) { 359 bool ScopeInfo::LocalIsSynthetic(int var) {
314 DCHECK(0 <= var && var < LocalCount()); 360 DCHECK(0 <= var && var < LocalCount());
315 // There's currently no flag stored on the ScopeInfo to indicate that a 361 // There's currently no flag stored on the ScopeInfo to indicate that a
316 // variable is a compiler-introduced temporary. However, to avoid conflict 362 // variable is a compiler-introduced temporary. However, to avoid conflict
317 // with user declarations, the current temporaries like .generator_object and 363 // with user declarations, the current temporaries like .generator_object and
318 // .result start with a dot, so we can use that as a flag. It's a hack! 364 // .result start with a dot, so we can use that as a flag. It's a hack!
319 Handle<String> name(LocalName(var)); 365 Handle<String> name(LocalName(var));
320 return name->length() > 0 && name->Get(0) == '.'; 366 return (name->length() > 0 && name->Get(0) == '.') ||
367 name->Equals(*GetIsolate()->factory()->this_string());
321 } 368 }
322 369
323 370
324 String* ScopeInfo::StrongModeFreeVariableName(int var) { 371 String* ScopeInfo::StrongModeFreeVariableName(int var) {
325 DCHECK(0 <= var && var < StrongModeFreeVariableCount()); 372 DCHECK(0 <= var && var < StrongModeFreeVariableCount());
326 int info_index = StrongModeFreeVariableNameEntriesIndex() + var; 373 int info_index = StrongModeFreeVariableNameEntriesIndex() + var;
327 return String::cast(get(info_index)); 374 return String::cast(get(info_index));
328 } 375 }
329 376
330 377
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 for (int i = end - 1; i >= start; --i) { 467 for (int i = end - 1; i >= start; --i) {
421 if (name == get(i)) { 468 if (name == get(i)) {
422 return i - start; 469 return i - start;
423 } 470 }
424 } 471 }
425 } 472 }
426 return -1; 473 return -1;
427 } 474 }
428 475
429 476
477 int ScopeInfo::ReceiverContextSlotIndex() {
478 if (length() > 0 && ReceiverVariableField::decode(Flags()) == CONTEXT)
479 return Smi::cast(get(ReceiverEntryIndex()))->value();
480 return -1;
481 }
482
483
430 int ScopeInfo::FunctionContextSlotIndex(String* name, VariableMode* mode) { 484 int ScopeInfo::FunctionContextSlotIndex(String* name, VariableMode* mode) {
431 DCHECK(name->IsInternalizedString()); 485 DCHECK(name->IsInternalizedString());
432 DCHECK(mode != NULL); 486 DCHECK(mode != NULL);
433 if (length() > 0) { 487 if (length() > 0) {
434 if (FunctionVariableField::decode(Flags()) == CONTEXT && 488 if (FunctionVariableField::decode(Flags()) == CONTEXT &&
435 FunctionName() == name) { 489 FunctionName() == name) {
436 *mode = FunctionVariableMode::decode(Flags()); 490 *mode = FunctionVariableMode::decode(Flags());
437 return Smi::cast(get(FunctionNameEntryIndex() + 1))->value(); 491 return Smi::cast(get(FunctionNameEntryIndex() + 1))->value();
438 } 492 }
439 } 493 }
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 return ContextLocalInfoEntriesIndex() + ContextLocalCount(); 561 return ContextLocalInfoEntriesIndex() + ContextLocalCount();
508 } 562 }
509 563
510 564
511 int ScopeInfo::StrongModeFreeVariablePositionEntriesIndex() { 565 int ScopeInfo::StrongModeFreeVariablePositionEntriesIndex() {
512 return StrongModeFreeVariableNameEntriesIndex() + 566 return StrongModeFreeVariableNameEntriesIndex() +
513 StrongModeFreeVariableCount(); 567 StrongModeFreeVariableCount();
514 } 568 }
515 569
516 570
571 int ScopeInfo::ReceiverEntryIndex() {
572 return StrongModeFreeVariablePositionEntriesIndex() +
573 2 * StrongModeFreeVariableCount();
574 }
575
576
517 int ScopeInfo::FunctionNameEntryIndex() { 577 int ScopeInfo::FunctionNameEntryIndex() {
518 return StrongModeFreeVariablePositionEntriesIndex() + 578 return ReceiverEntryIndex() + (HasAllocatedReceiver() ? 1 : 0);
519 2 * StrongModeFreeVariableCount();
520 } 579 }
521 580
522 581
523 int ContextSlotCache::Hash(Object* data, String* name) { 582 int ContextSlotCache::Hash(Object* data, String* name) {
524 // Uses only lower 32 bits if pointers are larger. 583 // Uses only lower 32 bits if pointers are larger.
525 uintptr_t addr_hash = 584 uintptr_t addr_hash =
526 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2; 585 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2;
527 return static_cast<int>((addr_hash ^ name->Hash()) % kLength); 586 return static_cast<int>((addr_hash ^ name->Hash()) % kLength);
528 } 587 }
529 588
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 info->set_name(i, *(it.export_name()->string())); 718 info->set_name(i, *(it.export_name()->string()));
660 info->set_mode(i, var->mode()); 719 info->set_mode(i, var->mode());
661 DCHECK(var->index() >= 0); 720 DCHECK(var->index() >= 0);
662 info->set_index(i, var->index()); 721 info->set_index(i, var->index());
663 } 722 }
664 DCHECK(i == info->length()); 723 DCHECK(i == info->length());
665 return info; 724 return info;
666 } 725 }
667 726
668 } } // namespace v8::internal 727 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime/runtime-scopes.cc ('k') | src/scopes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698