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

Side by Side Diff: src/scopeinfo.cc

Issue 1218783005: Support for global var shortcuts in script contexts. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fixing builds Created 5 years, 5 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/scopeinfo.h ('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/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/scopeinfo.h" 10 #include "src/scopeinfo.h"
11 #include "src/scopes.h" 11 #include "src/scopes.h"
12 12
13 namespace v8 { 13 namespace v8 {
14 namespace internal { 14 namespace internal {
15 15
16 16
17 Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, 17 Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
18 Scope* scope) { 18 Scope* scope) {
19 // Collect stack and context locals. 19 // Collect stack and context locals.
20 ZoneList<Variable*> stack_locals(scope->StackLocalCount(), zone); 20 ZoneList<Variable*> stack_locals(scope->StackLocalCount(), zone);
21 ZoneList<Variable*> context_locals(scope->ContextLocalCount(), zone); 21 ZoneList<Variable*> context_locals(scope->ContextLocalCount(), zone);
22 ZoneList<Variable*> context_globals(scope->ContextGlobalCount(), zone);
22 ZoneList<Variable*> strong_mode_free_variables(0, zone); 23 ZoneList<Variable*> strong_mode_free_variables(0, zone);
23 24
24 scope->CollectStackAndContextLocals(&stack_locals, &context_locals, 25 scope->CollectStackAndContextLocals(&stack_locals, &context_locals,
26 &context_globals,
25 &strong_mode_free_variables); 27 &strong_mode_free_variables);
26 const int stack_local_count = stack_locals.length(); 28 const int stack_local_count = stack_locals.length();
27 const int context_local_count = context_locals.length(); 29 const int context_local_count = context_locals.length();
30 const int context_global_count = context_globals.length();
28 const int strong_mode_free_variable_count = 31 const int strong_mode_free_variable_count =
29 strong_mode_free_variables.length(); 32 strong_mode_free_variables.length();
30 // Make sure we allocate the correct amount. 33 // Make sure we allocate the correct amount.
31 DCHECK(scope->ContextLocalCount() == context_local_count); 34 DCHECK_EQ(scope->ContextLocalCount(), context_local_count);
35 DCHECK_EQ(scope->ContextGlobalCount(), context_global_count);
32 36
33 bool simple_parameter_list = 37 bool simple_parameter_list =
34 scope->is_function_scope() ? scope->is_simple_parameter_list() : true; 38 scope->is_function_scope() ? scope->is_simple_parameter_list() : true;
35 39
36 // Determine use and location of the "this" binding if it is present. 40 // Determine use and location of the "this" binding if it is present.
37 VariableAllocationInfo receiver_info; 41 VariableAllocationInfo receiver_info;
38 if (scope->has_this_declaration()) { 42 if (scope->has_this_declaration()) {
39 Variable* var = scope->receiver(); 43 Variable* var = scope->receiver();
40 if (!var->is_used()) { 44 if (!var->is_used()) {
41 receiver_info = UNUSED; 45 receiver_info = UNUSED;
(...skipping 18 matching lines...) Expand all
60 function_name_info = CONTEXT; 64 function_name_info = CONTEXT;
61 } else { 65 } else {
62 DCHECK(var->IsStackLocal()); 66 DCHECK(var->IsStackLocal());
63 function_name_info = STACK; 67 function_name_info = STACK;
64 } 68 }
65 function_variable_mode = var->mode(); 69 function_variable_mode = var->mode();
66 } else { 70 } else {
67 function_name_info = NONE; 71 function_name_info = NONE;
68 function_variable_mode = VAR; 72 function_variable_mode = VAR;
69 } 73 }
74 DCHECK(context_global_count == 0 || scope->scope_type() == SCRIPT_SCOPE);
70 75
71 const bool has_function_name = function_name_info != NONE; 76 const bool has_function_name = function_name_info != NONE;
72 const bool has_receiver = receiver_info == STACK || receiver_info == CONTEXT; 77 const bool has_receiver = receiver_info == STACK || receiver_info == CONTEXT;
73 const int parameter_count = scope->num_parameters(); 78 const int parameter_count = scope->num_parameters();
74 const int length = kVariablePartIndex + parameter_count + 79 const int length = kVariablePartIndex + parameter_count +
75 (1 + stack_local_count) + 2 * context_local_count + 80 (1 + stack_local_count) + 2 * context_local_count +
81 2 * context_global_count +
76 3 * strong_mode_free_variable_count + 82 3 * strong_mode_free_variable_count +
77 (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0); 83 (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0);
78 84
79 Factory* factory = isolate->factory(); 85 Factory* factory = isolate->factory();
80 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); 86 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
81 87
82 // Encode the flags. 88 // Encode the flags.
83 int flags = ScopeTypeField::encode(scope->scope_type()) | 89 int flags = ScopeTypeField::encode(scope->scope_type()) |
84 CallsEvalField::encode(scope->calls_eval()) | 90 CallsEvalField::encode(scope->calls_eval()) |
85 LanguageModeField::encode(scope->language_mode()) | 91 LanguageModeField::encode(scope->language_mode()) |
86 ReceiverVariableField::encode(receiver_info) | 92 ReceiverVariableField::encode(receiver_info) |
87 FunctionVariableField::encode(function_name_info) | 93 FunctionVariableField::encode(function_name_info) |
88 FunctionVariableMode::encode(function_variable_mode) | 94 FunctionVariableMode::encode(function_variable_mode) |
89 AsmModuleField::encode(scope->asm_module()) | 95 AsmModuleField::encode(scope->asm_module()) |
90 AsmFunctionField::encode(scope->asm_function()) | 96 AsmFunctionField::encode(scope->asm_function()) |
91 IsSimpleParameterListField::encode(simple_parameter_list) | 97 IsSimpleParameterListField::encode(simple_parameter_list) |
92 FunctionKindField::encode(scope->function_kind()); 98 FunctionKindField::encode(scope->function_kind());
93 scope_info->SetFlags(flags); 99 scope_info->SetFlags(flags);
94 scope_info->SetParameterCount(parameter_count); 100 scope_info->SetParameterCount(parameter_count);
95 scope_info->SetStackLocalCount(stack_local_count); 101 scope_info->SetStackLocalCount(stack_local_count);
96 scope_info->SetContextLocalCount(context_local_count); 102 scope_info->SetContextLocalCount(context_local_count);
103 scope_info->SetContextGlobalCount(context_global_count);
97 scope_info->SetStrongModeFreeVariableCount(strong_mode_free_variable_count); 104 scope_info->SetStrongModeFreeVariableCount(strong_mode_free_variable_count);
98 105
99 int index = kVariablePartIndex; 106 int index = kVariablePartIndex;
100 // Add parameters. 107 // Add parameters.
101 DCHECK(index == scope_info->ParameterEntriesIndex()); 108 DCHECK(index == scope_info->ParameterEntriesIndex());
102 for (int i = 0; i < parameter_count; ++i) { 109 for (int i = 0; i < parameter_count; ++i) {
103 scope_info->set(index++, *scope->parameter(i)->name()); 110 scope_info->set(index++, *scope->parameter(i)->name());
104 } 111 }
105 112
106 // Add stack locals' names. We are assuming that the stack locals' 113 // Add stack locals' names. We are assuming that the stack locals'
(...skipping 20 matching lines...) Expand all
127 // order with the variable list anymore. Thus, we first need to sort them by 134 // order with the variable list anymore. Thus, we first need to sort them by
128 // context slot index before adding them to the ScopeInfo object. 135 // context slot index before adding them to the ScopeInfo object.
129 context_locals.Sort(&Variable::CompareIndex); 136 context_locals.Sort(&Variable::CompareIndex);
130 137
131 // Add context locals' names. 138 // Add context locals' names.
132 DCHECK(index == scope_info->ContextLocalNameEntriesIndex()); 139 DCHECK(index == scope_info->ContextLocalNameEntriesIndex());
133 for (int i = 0; i < context_local_count; ++i) { 140 for (int i = 0; i < context_local_count; ++i) {
134 scope_info->set(index++, *context_locals[i]->name()); 141 scope_info->set(index++, *context_locals[i]->name());
135 } 142 }
136 143
144 // Add context globals' names.
145 DCHECK(index == scope_info->ContextGlobalNameEntriesIndex());
146 for (int i = 0; i < context_global_count; ++i) {
147 scope_info->set(index++, *context_globals[i]->name());
148 }
149
137 // Add context locals' info. 150 // Add context locals' info.
138 DCHECK(index == scope_info->ContextLocalInfoEntriesIndex()); 151 DCHECK(index == scope_info->ContextLocalInfoEntriesIndex());
139 for (int i = 0; i < context_local_count; ++i) { 152 for (int i = 0; i < context_local_count; ++i) {
140 Variable* var = context_locals[i]; 153 Variable* var = context_locals[i];
141 uint32_t value = 154 uint32_t value =
142 ContextLocalMode::encode(var->mode()) | 155 ContextLocalMode::encode(var->mode()) |
143 ContextLocalInitFlag::encode(var->initialization_flag()) | 156 ContextLocalInitFlag::encode(var->initialization_flag()) |
144 ContextLocalMaybeAssignedFlag::encode(var->maybe_assigned()); 157 ContextLocalMaybeAssignedFlag::encode(var->maybe_assigned());
145 scope_info->set(index++, Smi::FromInt(value)); 158 scope_info->set(index++, Smi::FromInt(value));
146 } 159 }
147 160
161 // Add context globals' info.
162 DCHECK(index == scope_info->ContextGlobalInfoEntriesIndex());
163 for (int i = 0; i < context_global_count; ++i) {
164 Variable* var = context_globals[i];
165 // TODO(ishell): do we need this kind of info for globals here?
166 uint32_t value =
167 ContextLocalMode::encode(var->mode()) |
168 ContextLocalInitFlag::encode(var->initialization_flag()) |
169 ContextLocalMaybeAssignedFlag::encode(var->maybe_assigned());
170 scope_info->set(index++, Smi::FromInt(value));
171 }
172
148 DCHECK(index == scope_info->StrongModeFreeVariableNameEntriesIndex()); 173 DCHECK(index == scope_info->StrongModeFreeVariableNameEntriesIndex());
149 for (int i = 0; i < strong_mode_free_variable_count; ++i) { 174 for (int i = 0; i < strong_mode_free_variable_count; ++i) {
150 scope_info->set(index++, *strong_mode_free_variables[i]->name()); 175 scope_info->set(index++, *strong_mode_free_variables[i]->name());
151 } 176 }
152 177
153 DCHECK(index == scope_info->StrongModeFreeVariablePositionEntriesIndex()); 178 DCHECK(index == scope_info->StrongModeFreeVariablePositionEntriesIndex());
154 for (int i = 0; i < strong_mode_free_variable_count; ++i) { 179 for (int i = 0; i < strong_mode_free_variable_count; ++i) {
155 // Unfortunately, the source code positions are stored as int even though 180 // Unfortunately, the source code positions are stored as int even though
156 // int32_t would be enough (given the maximum source code length). 181 // int32_t would be enough (given the maximum source code length).
157 Handle<Object> start_position = factory->NewNumberFromInt( 182 Handle<Object> start_position = factory->NewNumberFromInt(
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 scope_info->ContextLength() == 0)); 215 scope_info->ContextLength() == 0));
191 return scope_info; 216 return scope_info;
192 } 217 }
193 218
194 219
195 Handle<ScopeInfo> ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) { 220 Handle<ScopeInfo> ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) {
196 DCHECK(isolate->bootstrapper()->IsActive()); 221 DCHECK(isolate->bootstrapper()->IsActive());
197 222
198 const int stack_local_count = 0; 223 const int stack_local_count = 0;
199 const int context_local_count = 1; 224 const int context_local_count = 1;
225 const int context_global_count = 0;
200 const int strong_mode_free_variable_count = 0; 226 const int strong_mode_free_variable_count = 0;
201 const bool simple_parameter_list = true; 227 const bool simple_parameter_list = true;
202 const VariableAllocationInfo receiver_info = CONTEXT; 228 const VariableAllocationInfo receiver_info = CONTEXT;
203 const VariableAllocationInfo function_name_info = NONE; 229 const VariableAllocationInfo function_name_info = NONE;
204 const VariableMode function_variable_mode = VAR; 230 const VariableMode function_variable_mode = VAR;
205 const bool has_function_name = false; 231 const bool has_function_name = false;
206 const bool has_receiver = true; 232 const bool has_receiver = true;
207 const int parameter_count = 0; 233 const int parameter_count = 0;
208 const int length = kVariablePartIndex + parameter_count + 234 const int length = kVariablePartIndex + parameter_count +
209 (1 + stack_local_count) + 2 * context_local_count + 235 (1 + stack_local_count) + 2 * context_local_count +
236 2 * context_global_count +
210 3 * strong_mode_free_variable_count + 237 3 * strong_mode_free_variable_count +
211 (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0); 238 (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0);
212 239
213 Factory* factory = isolate->factory(); 240 Factory* factory = isolate->factory();
214 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); 241 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
215 242
216 // Encode the flags. 243 // Encode the flags.
217 int flags = ScopeTypeField::encode(SCRIPT_SCOPE) | 244 int flags = ScopeTypeField::encode(SCRIPT_SCOPE) |
218 CallsEvalField::encode(false) | 245 CallsEvalField::encode(false) |
219 LanguageModeField::encode(SLOPPY) | 246 LanguageModeField::encode(SLOPPY) |
220 ReceiverVariableField::encode(receiver_info) | 247 ReceiverVariableField::encode(receiver_info) |
221 FunctionVariableField::encode(function_name_info) | 248 FunctionVariableField::encode(function_name_info) |
222 FunctionVariableMode::encode(function_variable_mode) | 249 FunctionVariableMode::encode(function_variable_mode) |
223 AsmModuleField::encode(false) | AsmFunctionField::encode(false) | 250 AsmModuleField::encode(false) | AsmFunctionField::encode(false) |
224 IsSimpleParameterListField::encode(simple_parameter_list) | 251 IsSimpleParameterListField::encode(simple_parameter_list) |
225 FunctionKindField::encode(FunctionKind::kNormalFunction); 252 FunctionKindField::encode(FunctionKind::kNormalFunction);
226 scope_info->SetFlags(flags); 253 scope_info->SetFlags(flags);
227 scope_info->SetParameterCount(parameter_count); 254 scope_info->SetParameterCount(parameter_count);
228 scope_info->SetStackLocalCount(stack_local_count); 255 scope_info->SetStackLocalCount(stack_local_count);
229 scope_info->SetContextLocalCount(context_local_count); 256 scope_info->SetContextLocalCount(context_local_count);
257 scope_info->SetContextGlobalCount(context_global_count);
230 scope_info->SetStrongModeFreeVariableCount(strong_mode_free_variable_count); 258 scope_info->SetStrongModeFreeVariableCount(strong_mode_free_variable_count);
231 259
232 int index = kVariablePartIndex; 260 int index = kVariablePartIndex;
233 const int first_slot_index = 0; 261 const int first_slot_index = 0;
234 DCHECK(index == scope_info->StackLocalFirstSlotIndex()); 262 DCHECK(index == scope_info->StackLocalFirstSlotIndex());
235 scope_info->set(index++, Smi::FromInt(first_slot_index)); 263 scope_info->set(index++, Smi::FromInt(first_slot_index));
236 DCHECK(index == scope_info->StackLocalEntriesIndex()); 264 DCHECK(index == scope_info->StackLocalEntriesIndex());
237 265
238 // Here we add info for context-allocated "this". 266 // Here we add info for context-allocated "this".
239 DCHECK(index == scope_info->ContextLocalNameEntriesIndex()); 267 DCHECK(index == scope_info->ContextLocalNameEntriesIndex());
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 FunctionVariableField::decode(Flags()) == STACK; 322 FunctionVariableField::decode(Flags()) == STACK;
295 return StackLocalCount() + (function_name_stack_slot ? 1 : 0); 323 return StackLocalCount() + (function_name_stack_slot ? 1 : 0);
296 } 324 }
297 return 0; 325 return 0;
298 } 326 }
299 327
300 328
301 int ScopeInfo::ContextLength() { 329 int ScopeInfo::ContextLength() {
302 if (length() > 0) { 330 if (length() > 0) {
303 int context_locals = ContextLocalCount(); 331 int context_locals = ContextLocalCount();
332 int context_globals = ContextGlobalCount();
304 bool function_name_context_slot = 333 bool function_name_context_slot =
305 FunctionVariableField::decode(Flags()) == CONTEXT; 334 FunctionVariableField::decode(Flags()) == CONTEXT;
306 bool has_context = context_locals > 0 || function_name_context_slot || 335 bool has_context = context_locals > 0 || context_globals > 0 ||
336 function_name_context_slot ||
307 scope_type() == WITH_SCOPE || 337 scope_type() == WITH_SCOPE ||
308 (scope_type() == ARROW_SCOPE && CallsSloppyEval()) || 338 (scope_type() == ARROW_SCOPE && CallsSloppyEval()) ||
309 (scope_type() == FUNCTION_SCOPE && CallsSloppyEval()) || 339 (scope_type() == FUNCTION_SCOPE && CallsSloppyEval()) ||
310 scope_type() == MODULE_SCOPE; 340 scope_type() == MODULE_SCOPE;
341
311 if (has_context) { 342 if (has_context) {
312 return Context::MIN_CONTEXT_SLOTS + context_locals + 343 return Context::MIN_CONTEXT_SLOTS + context_locals + 2 * context_globals +
313 (function_name_context_slot ? 1 : 0); 344 (function_name_context_slot ? 1 : 0);
314 } 345 }
315 } 346 }
316 return 0; 347 return 0;
317 } 348 }
318 349
319 350
320 bool ScopeInfo::HasReceiver() { 351 bool ScopeInfo::HasReceiver() {
321 if (length() > 0) { 352 if (length() > 0) {
322 return NONE != ReceiverVariableField::decode(Flags()); 353 return NONE != ReceiverVariableField::decode(Flags());
323 } else { 354 } else {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 420
390 421
391 int ScopeInfo::StackLocalIndex(int var) { 422 int ScopeInfo::StackLocalIndex(int var) {
392 DCHECK(0 <= var && var < StackLocalCount()); 423 DCHECK(0 <= var && var < StackLocalCount());
393 int first_slot_index = Smi::cast(get(StackLocalFirstSlotIndex()))->value(); 424 int first_slot_index = Smi::cast(get(StackLocalFirstSlotIndex()))->value();
394 return first_slot_index + var; 425 return first_slot_index + var;
395 } 426 }
396 427
397 428
398 String* ScopeInfo::ContextLocalName(int var) { 429 String* ScopeInfo::ContextLocalName(int var) {
399 DCHECK(0 <= var && var < ContextLocalCount()); 430 DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount());
400 int info_index = ContextLocalNameEntriesIndex() + var; 431 int info_index = ContextLocalNameEntriesIndex() + var;
401 return String::cast(get(info_index)); 432 return String::cast(get(info_index));
402 } 433 }
403 434
404 435
405 VariableMode ScopeInfo::ContextLocalMode(int var) { 436 VariableMode ScopeInfo::ContextLocalMode(int var) {
406 DCHECK(0 <= var && var < ContextLocalCount()); 437 DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount());
407 int info_index = ContextLocalInfoEntriesIndex() + var; 438 int info_index = ContextLocalInfoEntriesIndex() + var;
408 int value = Smi::cast(get(info_index))->value(); 439 int value = Smi::cast(get(info_index))->value();
409 return ContextLocalMode::decode(value); 440 return ContextLocalMode::decode(value);
410 } 441 }
411 442
412 443
413 InitializationFlag ScopeInfo::ContextLocalInitFlag(int var) { 444 InitializationFlag ScopeInfo::ContextLocalInitFlag(int var) {
414 DCHECK(0 <= var && var < ContextLocalCount()); 445 DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount());
415 int info_index = ContextLocalInfoEntriesIndex() + var; 446 int info_index = ContextLocalInfoEntriesIndex() + var;
416 int value = Smi::cast(get(info_index))->value(); 447 int value = Smi::cast(get(info_index))->value();
417 return ContextLocalInitFlag::decode(value); 448 return ContextLocalInitFlag::decode(value);
418 } 449 }
419 450
420 451
421 MaybeAssignedFlag ScopeInfo::ContextLocalMaybeAssignedFlag(int var) { 452 MaybeAssignedFlag ScopeInfo::ContextLocalMaybeAssignedFlag(int var) {
422 DCHECK(0 <= var && var < ContextLocalCount()); 453 DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount());
423 int info_index = ContextLocalInfoEntriesIndex() + var; 454 int info_index = ContextLocalInfoEntriesIndex() + var;
424 int value = Smi::cast(get(info_index))->value(); 455 int value = Smi::cast(get(info_index))->value();
425 return ContextLocalMaybeAssignedFlag::decode(value); 456 return ContextLocalMaybeAssignedFlag::decode(value);
426 } 457 }
427 458
428 459
429 bool ScopeInfo::LocalIsSynthetic(int var) { 460 bool ScopeInfo::LocalIsSynthetic(int var) {
430 DCHECK(0 <= var && var < LocalCount()); 461 DCHECK(0 <= var && var < LocalCount());
431 // There's currently no flag stored on the ScopeInfo to indicate that a 462 // There's currently no flag stored on the ScopeInfo to indicate that a
432 // variable is a compiler-introduced temporary. However, to avoid conflict 463 // variable is a compiler-introduced temporary. However, to avoid conflict
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 return i - start + first_slot_index; 509 return i - start + first_slot_index;
479 } 510 }
480 } 511 }
481 } 512 }
482 return -1; 513 return -1;
483 } 514 }
484 515
485 516
486 int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info, 517 int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info,
487 Handle<String> name, VariableMode* mode, 518 Handle<String> name, VariableMode* mode,
519 VariableLocation* location,
488 InitializationFlag* init_flag, 520 InitializationFlag* init_flag,
489 MaybeAssignedFlag* maybe_assigned_flag) { 521 MaybeAssignedFlag* maybe_assigned_flag) {
490 DCHECK(name->IsInternalizedString()); 522 DCHECK(name->IsInternalizedString());
491 DCHECK(mode != NULL); 523 DCHECK(mode != NULL);
524 DCHECK(location != NULL);
492 DCHECK(init_flag != NULL); 525 DCHECK(init_flag != NULL);
493 if (scope_info->length() > 0) { 526 if (scope_info->length() > 0) {
494 ContextSlotCache* context_slot_cache = 527 ContextSlotCache* context_slot_cache =
495 scope_info->GetIsolate()->context_slot_cache(); 528 scope_info->GetIsolate()->context_slot_cache();
496 int result = context_slot_cache->Lookup(*scope_info, *name, mode, init_flag, 529 int result = context_slot_cache->Lookup(*scope_info, *name, mode, location,
497 maybe_assigned_flag); 530 init_flag, maybe_assigned_flag);
498 if (result != ContextSlotCache::kNotFound) { 531 if (result != ContextSlotCache::kNotFound) {
499 DCHECK(result < scope_info->ContextLength()); 532 DCHECK(result < scope_info->ContextLength());
500 return result; 533 return result;
501 } 534 }
502 535
536 DCHECK_EQ(scope_info->ContextGlobalNameEntriesIndex(),
537 scope_info->ContextLocalNameEntriesIndex() +
538 scope_info->ContextLocalCount());
503 int start = scope_info->ContextLocalNameEntriesIndex(); 539 int start = scope_info->ContextLocalNameEntriesIndex();
504 int end = scope_info->ContextLocalNameEntriesIndex() + 540 int end = scope_info->ContextGlobalNameEntriesIndex() +
505 scope_info->ContextLocalCount(); 541 scope_info->ContextGlobalCount();
506 for (int i = start; i < end; ++i) { 542 for (int i = start; i < end; ++i) {
507 if (*name == scope_info->get(i)) { 543 if (*name == scope_info->get(i)) {
508 int var = i - start; 544 int var = i - start;
509 *mode = scope_info->ContextLocalMode(var); 545 *mode = scope_info->ContextLocalMode(var);
510 *init_flag = scope_info->ContextLocalInitFlag(var); 546 *init_flag = scope_info->ContextLocalInitFlag(var);
511 *maybe_assigned_flag = scope_info->ContextLocalMaybeAssignedFlag(var); 547 *maybe_assigned_flag = scope_info->ContextLocalMaybeAssignedFlag(var);
512 result = Context::MIN_CONTEXT_SLOTS + var; 548
513 context_slot_cache->Update(scope_info, name, *mode, *init_flag, 549 if (var < scope_info->ContextLocalCount()) {
514 *maybe_assigned_flag, result); 550 *location = VariableLocation::CONTEXT;
551 result = Context::MIN_CONTEXT_SLOTS + var;
552 } else {
553 var -= scope_info->ContextLocalCount();
554 *location = VariableLocation::GLOBAL;
555 result = Context::MIN_CONTEXT_SLOTS +
556 scope_info->ContextLocalCount() + 2 * var;
557 }
558
559 context_slot_cache->Update(scope_info, name, *mode, *location,
560 *init_flag, *maybe_assigned_flag, result);
515 DCHECK(result < scope_info->ContextLength()); 561 DCHECK(result < scope_info->ContextLength());
516 return result; 562 return result;
517 } 563 }
518 } 564 }
519 // Cache as not found. Mode, init flag and maybe assigned flag don't matter. 565 // Cache as not found. Mode, location, init flag and maybe assigned flag
520 context_slot_cache->Update(scope_info, name, INTERNAL, kNeedsInitialization, 566 // don't matter.
567 context_slot_cache->Update(scope_info, name, INTERNAL,
568 VariableLocation::CONTEXT, kNeedsInitialization,
521 kNotAssigned, -1); 569 kNotAssigned, -1);
522 } 570 }
523 return -1; 571 return -1;
524 } 572 }
525 573
526 574
527 int ScopeInfo::ParameterIndex(String* name) { 575 int ScopeInfo::ParameterIndex(String* name) {
528 DCHECK(name->IsInternalizedString()); 576 DCHECK(name->IsInternalizedString());
529 if (length() > 0) { 577 if (length() > 0) {
530 // We must read parameters from the end since for 578 // We must read parameters from the end since for
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 int ScopeInfo::StackLocalEntriesIndex() { 656 int ScopeInfo::StackLocalEntriesIndex() {
609 return StackLocalFirstSlotIndex() + 1; 657 return StackLocalFirstSlotIndex() + 1;
610 } 658 }
611 659
612 660
613 int ScopeInfo::ContextLocalNameEntriesIndex() { 661 int ScopeInfo::ContextLocalNameEntriesIndex() {
614 return StackLocalEntriesIndex() + StackLocalCount(); 662 return StackLocalEntriesIndex() + StackLocalCount();
615 } 663 }
616 664
617 665
666 int ScopeInfo::ContextGlobalNameEntriesIndex() {
667 return ContextLocalNameEntriesIndex() + ContextLocalCount();
668 }
669
670
618 int ScopeInfo::ContextLocalInfoEntriesIndex() { 671 int ScopeInfo::ContextLocalInfoEntriesIndex() {
619 return ContextLocalNameEntriesIndex() + ContextLocalCount(); 672 return ContextGlobalNameEntriesIndex() + ContextGlobalCount();
673 }
674
675
676 int ScopeInfo::ContextGlobalInfoEntriesIndex() {
677 return ContextLocalInfoEntriesIndex() + ContextLocalCount();
620 } 678 }
621 679
622 680
623 int ScopeInfo::StrongModeFreeVariableNameEntriesIndex() { 681 int ScopeInfo::StrongModeFreeVariableNameEntriesIndex() {
624 return ContextLocalInfoEntriesIndex() + ContextLocalCount(); 682 return ContextGlobalInfoEntriesIndex() + ContextGlobalCount();
625 } 683 }
626 684
627 685
628 int ScopeInfo::StrongModeFreeVariablePositionEntriesIndex() { 686 int ScopeInfo::StrongModeFreeVariablePositionEntriesIndex() {
629 return StrongModeFreeVariableNameEntriesIndex() + 687 return StrongModeFreeVariableNameEntriesIndex() +
630 StrongModeFreeVariableCount(); 688 StrongModeFreeVariableCount();
631 } 689 }
632 690
633 691
634 int ScopeInfo::ReceiverEntryIndex() { 692 int ScopeInfo::ReceiverEntryIndex() {
635 return StrongModeFreeVariablePositionEntriesIndex() + 693 return StrongModeFreeVariablePositionEntriesIndex() +
636 2 * StrongModeFreeVariableCount(); 694 2 * StrongModeFreeVariableCount();
637 } 695 }
638 696
639 697
640 int ScopeInfo::FunctionNameEntryIndex() { 698 int ScopeInfo::FunctionNameEntryIndex() {
641 return ReceiverEntryIndex() + (HasAllocatedReceiver() ? 1 : 0); 699 return ReceiverEntryIndex() + (HasAllocatedReceiver() ? 1 : 0);
642 } 700 }
643 701
644 702
645 int ContextSlotCache::Hash(Object* data, String* name) { 703 int ContextSlotCache::Hash(Object* data, String* name) {
646 // Uses only lower 32 bits if pointers are larger. 704 // Uses only lower 32 bits if pointers are larger.
647 uintptr_t addr_hash = 705 uintptr_t addr_hash =
648 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2; 706 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2;
649 return static_cast<int>((addr_hash ^ name->Hash()) % kLength); 707 return static_cast<int>((addr_hash ^ name->Hash()) % kLength);
650 } 708 }
651 709
652 710
653 int ContextSlotCache::Lookup(Object* data, String* name, VariableMode* mode, 711 int ContextSlotCache::Lookup(Object* data, String* name, VariableMode* mode,
712 VariableLocation* location,
654 InitializationFlag* init_flag, 713 InitializationFlag* init_flag,
655 MaybeAssignedFlag* maybe_assigned_flag) { 714 MaybeAssignedFlag* maybe_assigned_flag) {
656 int index = Hash(data, name); 715 int index = Hash(data, name);
657 Key& key = keys_[index]; 716 Key& key = keys_[index];
658 if ((key.data == data) && key.name->Equals(name)) { 717 if ((key.data == data) && key.name->Equals(name)) {
659 Value result(values_[index]); 718 Value result(values_[index]);
660 if (mode != NULL) *mode = result.mode(); 719 if (mode != NULL) *mode = result.mode();
720 if (location != NULL) *location = result.location();
661 if (init_flag != NULL) *init_flag = result.initialization_flag(); 721 if (init_flag != NULL) *init_flag = result.initialization_flag();
662 if (maybe_assigned_flag != NULL) 722 if (maybe_assigned_flag != NULL)
663 *maybe_assigned_flag = result.maybe_assigned_flag(); 723 *maybe_assigned_flag = result.maybe_assigned_flag();
664 return result.index() + kNotFound; 724 return result.index() + kNotFound;
665 } 725 }
666 return kNotFound; 726 return kNotFound;
667 } 727 }
668 728
669 729
670 void ContextSlotCache::Update(Handle<Object> data, Handle<String> name, 730 void ContextSlotCache::Update(Handle<Object> data, Handle<String> name,
671 VariableMode mode, InitializationFlag init_flag, 731 VariableMode mode, VariableLocation location,
732 InitializationFlag init_flag,
672 MaybeAssignedFlag maybe_assigned_flag, 733 MaybeAssignedFlag maybe_assigned_flag,
673 int slot_index) { 734 int slot_index) {
674 DisallowHeapAllocation no_gc; 735 DisallowHeapAllocation no_gc;
675 Handle<String> internalized_name; 736 Handle<String> internalized_name;
676 DCHECK(slot_index > kNotFound); 737 DCHECK(slot_index > kNotFound);
677 if (StringTable::InternalizeStringIfExists(name->GetIsolate(), name). 738 if (StringTable::InternalizeStringIfExists(name->GetIsolate(), name).
678 ToHandle(&internalized_name)) { 739 ToHandle(&internalized_name)) {
679 int index = Hash(*data, *internalized_name); 740 int index = Hash(*data, *internalized_name);
680 Key& key = keys_[index]; 741 Key& key = keys_[index];
681 key.data = *data; 742 key.data = *data;
682 key.name = *internalized_name; 743 key.name = *internalized_name;
683 // Please note value only takes a uint as index. 744 // Please note value only takes a uint as index.
684 values_[index] = Value(mode, init_flag, maybe_assigned_flag, 745 values_[index] = Value(mode, location, init_flag, maybe_assigned_flag,
685 slot_index - kNotFound).raw(); 746 slot_index - kNotFound).raw();
686 #ifdef DEBUG 747 #ifdef DEBUG
687 ValidateEntry(data, name, mode, init_flag, maybe_assigned_flag, slot_index); 748 ValidateEntry(data, name, mode, location, init_flag, maybe_assigned_flag,
749 slot_index);
688 #endif 750 #endif
689 } 751 }
690 } 752 }
691 753
692 754
693 void ContextSlotCache::Clear() { 755 void ContextSlotCache::Clear() {
694 for (int index = 0; index < kLength; index++) keys_[index].data = NULL; 756 for (int index = 0; index < kLength; index++) keys_[index].data = NULL;
695 } 757 }
696 758
697 759
698 #ifdef DEBUG 760 #ifdef DEBUG
699 761
700 void ContextSlotCache::ValidateEntry(Handle<Object> data, Handle<String> name, 762 void ContextSlotCache::ValidateEntry(Handle<Object> data, Handle<String> name,
701 VariableMode mode, 763 VariableMode mode,
764 VariableLocation location,
702 InitializationFlag init_flag, 765 InitializationFlag init_flag,
703 MaybeAssignedFlag maybe_assigned_flag, 766 MaybeAssignedFlag maybe_assigned_flag,
704 int slot_index) { 767 int slot_index) {
705 DisallowHeapAllocation no_gc; 768 DisallowHeapAllocation no_gc;
706 Handle<String> internalized_name; 769 Handle<String> internalized_name;
707 if (StringTable::InternalizeStringIfExists(name->GetIsolate(), name). 770 if (StringTable::InternalizeStringIfExists(name->GetIsolate(), name).
708 ToHandle(&internalized_name)) { 771 ToHandle(&internalized_name)) {
709 int index = Hash(*data, *name); 772 int index = Hash(*data, *name);
710 Key& key = keys_[index]; 773 Key& key = keys_[index];
711 DCHECK(key.data == *data); 774 DCHECK(key.data == *data);
712 DCHECK(key.name->Equals(*name)); 775 DCHECK(key.name->Equals(*name));
713 Value result(values_[index]); 776 Value result(values_[index]);
714 DCHECK(result.mode() == mode); 777 DCHECK(result.mode() == mode);
778 DCHECK(result.location() == location);
715 DCHECK(result.initialization_flag() == init_flag); 779 DCHECK(result.initialization_flag() == init_flag);
716 DCHECK(result.maybe_assigned_flag() == maybe_assigned_flag); 780 DCHECK(result.maybe_assigned_flag() == maybe_assigned_flag);
717 DCHECK(result.index() + kNotFound == slot_index); 781 DCHECK(result.index() + kNotFound == slot_index);
718 } 782 }
719 } 783 }
720 784
721 785
722 static void PrintList(const char* list_name, 786 static void PrintList(const char* list_name,
723 int nof_internal_slots, 787 int nof_internal_slots,
724 int start, 788 int start,
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 info->set_mode(i, var->mode()); 846 info->set_mode(i, var->mode());
783 DCHECK(var->index() >= 0); 847 DCHECK(var->index() >= 0);
784 info->set_index(i, var->index()); 848 info->set_index(i, var->index());
785 } 849 }
786 DCHECK(i == info->length()); 850 DCHECK(i == info->length());
787 return info; 851 return info;
788 } 852 }
789 853
790 } // namespace internal 854 } // namespace internal
791 } // namespace v8 855 } // namespace v8
OLDNEW
« no previous file with comments | « src/scopeinfo.h ('k') | src/scopes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698