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

Side by Side Diff: src/scopeinfo.cc

Issue 1005063002: Strawman: check strong mode free variables against the global object. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: . Created 5 years, 9 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
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"
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
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
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
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
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
OLDNEW
« src/api.cc ('K') | « src/pending-compilation-error-handler.cc ('k') | src/scopes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698