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

Side by Side Diff: src/ast/scopeinfo.cc

Issue 2287173002: Replace CollectVariables with locals(), update callsites to walk locals instead (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: restore undefined handling Created 4 years, 3 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/ast/ast.cc ('k') | src/ast/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/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
11 namespace v8 { 11 namespace v8 {
12 namespace internal { 12 namespace internal {
13 13
14 14
15 Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, 15 Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
16 Scope* scope) { 16 Scope* scope) {
17 // Collect variables. 17 // Collect variables.
18 ZoneList<Variable*> stack_locals(scope->StackLocalCount(), zone); 18 ZoneList<Variable*>* locals = scope->locals();
19 ZoneList<Variable*> context_locals(scope->ContextLocalCount(), zone); 19 int stack_local_count = 0;
20 ZoneList<Variable*> context_globals(scope->ContextGlobalCount(), zone); 20 int context_local_count = 0;
21 scope->CollectVariables(&stack_locals, &context_locals, &context_globals); 21 // Stack allocated block scope variables are allocated in the parent
22 const int stack_local_count = stack_locals.length(); 22 // declaration scope, but are recorded in the block scope's scope info. First
23 const int context_local_count = context_locals.length(); 23 // slot index indicates at which offset a particular scope starts in the
24 const int context_global_count = context_globals.length(); 24 // parent declaration scope.
25 int first_slot_index = 0;
26 for (int i = 0; i < locals->length(); i++) {
27 Variable* var = locals->at(i);
28 if (var->IsStackLocal()) {
29 if (stack_local_count == 0) first_slot_index = var->index();
30 stack_local_count++;
31 } else if (var->IsContextSlot()) {
32 context_local_count++;
33 }
34 }
35
25 // Make sure we allocate the correct amount. 36 // Make sure we allocate the correct amount.
26 DCHECK_EQ(scope->ContextLocalCount(), context_local_count); 37 DCHECK_EQ(scope->ContextLocalCount(), context_local_count);
27 DCHECK_EQ(scope->ContextGlobalCount(), context_global_count);
28 38
29 // Determine use and location of the "this" binding if it is present. 39 // Determine use and location of the "this" binding if it is present.
30 VariableAllocationInfo receiver_info; 40 VariableAllocationInfo receiver_info;
31 if (scope->is_declaration_scope() && 41 if (scope->is_declaration_scope() &&
32 scope->AsDeclarationScope()->has_this_declaration()) { 42 scope->AsDeclarationScope()->has_this_declaration()) {
33 Variable* var = scope->AsDeclarationScope()->receiver(); 43 Variable* var = scope->AsDeclarationScope()->receiver();
34 if (!var->is_used()) { 44 if (!var->is_used()) {
35 receiver_info = UNUSED; 45 receiver_info = UNUSED;
36 } else if (var->IsContextSlot()) { 46 } else if (var->IsContextSlot()) {
37 receiver_info = CONTEXT; 47 receiver_info = CONTEXT;
(...skipping 21 matching lines...) Expand all
59 function_name_info = CONTEXT; 69 function_name_info = CONTEXT;
60 } else { 70 } else {
61 DCHECK(var->IsStackLocal()); 71 DCHECK(var->IsStackLocal());
62 function_name_info = STACK; 72 function_name_info = STACK;
63 } 73 }
64 function_variable_mode = var->mode(); 74 function_variable_mode = var->mode();
65 } else { 75 } else {
66 function_name_info = NONE; 76 function_name_info = NONE;
67 function_variable_mode = VAR; 77 function_variable_mode = VAR;
68 } 78 }
69 DCHECK(context_global_count == 0 || scope->scope_type() == SCRIPT_SCOPE);
70 79
71 const bool has_function_name = function_name_info != NONE; 80 const bool has_function_name = function_name_info != NONE;
72 const bool has_receiver = receiver_info == STACK || receiver_info == CONTEXT; 81 const bool has_receiver = receiver_info == STACK || receiver_info == CONTEXT;
73 const int parameter_count = scope->num_parameters(); 82 const int parameter_count = scope->num_parameters();
74 const int length = kVariablePartIndex + parameter_count + 83 const int length = kVariablePartIndex + parameter_count +
75 (1 + stack_local_count) + 2 * context_local_count + 84 (1 + stack_local_count) + 2 * context_local_count +
76 2 * context_global_count +
77 (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0); 85 (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0);
78 86
79 Factory* factory = isolate->factory(); 87 Factory* factory = isolate->factory();
80 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); 88 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
81 89
82 bool has_simple_parameters = false; 90 bool has_simple_parameters = false;
83 bool asm_module = false; 91 bool asm_module = false;
84 bool asm_function = false; 92 bool asm_function = false;
85 FunctionKind function_kind = kNormalFunction; 93 FunctionKind function_kind = kNormalFunction;
86 if (scope->is_function_scope()) { 94 if (scope->is_function_scope()) {
(...skipping 14 matching lines...) Expand all
101 FunctionVariableField::encode(function_name_info) | 109 FunctionVariableField::encode(function_name_info) |
102 FunctionVariableMode::encode(function_variable_mode) | 110 FunctionVariableMode::encode(function_variable_mode) |
103 AsmModuleField::encode(asm_module) | 111 AsmModuleField::encode(asm_module) |
104 AsmFunctionField::encode(asm_function) | 112 AsmFunctionField::encode(asm_function) |
105 HasSimpleParametersField::encode(has_simple_parameters) | 113 HasSimpleParametersField::encode(has_simple_parameters) |
106 FunctionKindField::encode(function_kind); 114 FunctionKindField::encode(function_kind);
107 scope_info->SetFlags(flags); 115 scope_info->SetFlags(flags);
108 scope_info->SetParameterCount(parameter_count); 116 scope_info->SetParameterCount(parameter_count);
109 scope_info->SetStackLocalCount(stack_local_count); 117 scope_info->SetStackLocalCount(stack_local_count);
110 scope_info->SetContextLocalCount(context_local_count); 118 scope_info->SetContextLocalCount(context_local_count);
111 scope_info->SetContextGlobalCount(context_global_count);
112 119
113 int index = kVariablePartIndex; 120 int index = kVariablePartIndex;
114 // Add parameters. 121 // Add parameters.
115 DCHECK_EQ(index, scope_info->ParameterEntriesIndex()); 122 DCHECK_EQ(index, scope_info->ParameterEntriesIndex());
116 if (scope->is_declaration_scope()) { 123 if (scope->is_declaration_scope()) {
117 for (int i = 0; i < parameter_count; ++i) { 124 for (int i = 0; i < parameter_count; ++i) {
118 scope_info->set(index++, 125 scope_info->set(index++,
119 *scope->AsDeclarationScope()->parameter(i)->name()); 126 *scope->AsDeclarationScope()->parameter(i)->name());
120 } 127 }
121 } 128 }
122 129
123 // Add stack locals' names. We are assuming that the stack locals' 130 // Add stack locals' names, context locals' names and info. We are assuming
124 // slots are allocated in increasing order, so we can simply add 131 // that the stack locals' slots are allocated in increasing order, so we can
125 // them to the ScopeInfo object. 132 // simply add them to the ScopeInfo object. Context locals are added using
126 int first_slot_index; 133 // their index.
127 if (stack_local_count > 0) {
128 first_slot_index = stack_locals[0]->index();
129 } else {
130 first_slot_index = 0;
131 }
132 DCHECK_EQ(index, scope_info->StackLocalFirstSlotIndex()); 134 DCHECK_EQ(index, scope_info->StackLocalFirstSlotIndex());
133 scope_info->set(index++, Smi::FromInt(first_slot_index)); 135 scope_info->set(index++, Smi::FromInt(first_slot_index));
134 DCHECK_EQ(index, scope_info->StackLocalEntriesIndex()); 136 DCHECK_EQ(index, scope_info->StackLocalEntriesIndex());
135 for (int i = 0; i < stack_local_count; ++i) { 137
136 DCHECK(stack_locals[i]->index() == first_slot_index + i); 138 int stack_local_base = index;
137 scope_info->set(index++, *stack_locals[i]->name()); 139 int context_local_base = stack_local_base + stack_local_count;
140 int context_local_info_base = context_local_base + context_local_count;
141
142 for (int i = 0; i < locals->length(); ++i) {
143 Variable* var = locals->at(i);
144 if (var->IsStackLocal()) {
145 int local_index = var->index() - first_slot_index;
146 DCHECK_LE(0, local_index);
147 DCHECK_LT(local_index, stack_local_count);
148 scope_info->set(stack_local_base + local_index, *var->name());
149 } else if (var->IsContextSlot()) {
150 // Due to duplicate parameters, context locals aren't guaranteed to come
151 // in order.
152 int local_index = var->index() - Context::MIN_CONTEXT_SLOTS;
153 DCHECK_LE(0, local_index);
154 DCHECK_LT(local_index, context_local_count);
155 uint32_t info = VariableModeField::encode(var->mode()) |
156 InitFlagField::encode(var->initialization_flag()) |
157 MaybeAssignedFlagField::encode(var->maybe_assigned());
158 scope_info->set(context_local_base + local_index, *var->name());
159 scope_info->set(context_local_info_base + local_index,
160 Smi::FromInt(info));
161 }
138 } 162 }
139 163
140 // Add context locals' names and info. Info lies beyond context globals' 164 index += stack_local_count + 2 * context_local_count;
141 // names.
142 // Make sure to store them in the order that they appear in the context.
143 DCHECK_EQ(index, scope_info->ContextLocalNameEntriesIndex());
144 int info_index = index + context_local_count + context_global_count;
145 DCHECK_EQ(info_index, scope_info->ContextLocalInfoEntriesIndex());
146 for (int i = 0; i < context_local_count; ++i) {
147 Variable* var = context_locals[i];
148 int context_index = var->index() - Context::MIN_CONTEXT_SLOTS;
149 uint32_t info = VariableModeField::encode(var->mode()) |
150 InitFlagField::encode(var->initialization_flag()) |
151 MaybeAssignedFlagField::encode(var->maybe_assigned());
152 scope_info->set(index + context_index, *var->name());
153 scope_info->set(info_index + context_index, Smi::FromInt(info));
154 }
155
156 index += context_local_count;
157
158 // Add context globals' names and info. Info lies beyond context locals' info.
159 DCHECK_EQ(index, scope_info->ContextGlobalNameEntriesIndex());
160 info_index = index + context_global_count + context_local_count;
161 DCHECK_EQ(info_index, scope_info->ContextGlobalInfoEntriesIndex());
162 for (int i = 0; i < context_global_count; ++i) {
163 Variable* var = context_globals[i];
164 scope_info->set(index + i, *var->name());
165 // TODO(ishell): do we need this kind of info for globals here?
166 uint32_t info = VariableModeField::encode(var->mode()) |
167 InitFlagField::encode(var->initialization_flag()) |
168 MaybeAssignedFlagField::encode(var->maybe_assigned());
169 scope_info->set(info_index + i, Smi::FromInt(info));
170 }
171
172 index += context_local_count + 2 * context_global_count;
173 165
174 // If the receiver is allocated, add its index. 166 // If the receiver is allocated, add its index.
175 DCHECK(index == scope_info->ReceiverEntryIndex()); 167 DCHECK_EQ(index, scope_info->ReceiverEntryIndex());
176 if (has_receiver) { 168 if (has_receiver) {
177 int var_index = scope->AsDeclarationScope()->receiver()->index(); 169 int var_index = scope->AsDeclarationScope()->receiver()->index();
178 scope_info->set(index++, Smi::FromInt(var_index)); 170 scope_info->set(index++, Smi::FromInt(var_index));
179 // ?? DCHECK(receiver_info != CONTEXT || var_index == 171 // ?? DCHECK(receiver_info != CONTEXT || var_index ==
180 // scope_info->ContextLength() - 1); 172 // scope_info->ContextLength() - 1);
181 } 173 }
182 174
183 // If present, add the function variable name and its index. 175 // If present, add the function variable name and its index.
184 DCHECK(index == scope_info->FunctionNameEntryIndex()); 176 DCHECK_EQ(index, scope_info->FunctionNameEntryIndex());
185 if (has_function_name) { 177 if (has_function_name) {
186 int var_index = scope->AsDeclarationScope()->function_var()->index(); 178 int var_index = scope->AsDeclarationScope()->function_var()->index();
187 scope_info->set(index++, 179 scope_info->set(index++,
188 *scope->AsDeclarationScope()->function_var()->name()); 180 *scope->AsDeclarationScope()->function_var()->name());
189 scope_info->set(index++, Smi::FromInt(var_index)); 181 scope_info->set(index++, Smi::FromInt(var_index));
190 DCHECK(function_name_info != CONTEXT || 182 DCHECK(function_name_info != CONTEXT ||
191 var_index == scope_info->ContextLength() - 1); 183 var_index == scope_info->ContextLength() - 1);
192 } 184 }
193 185
194 DCHECK(index == scope_info->length()); 186 DCHECK_EQ(index, scope_info->length());
195 DCHECK(scope->num_parameters() == scope_info->ParameterCount()); 187 DCHECK_EQ(scope->num_parameters(), scope_info->ParameterCount());
196 DCHECK(scope->num_heap_slots() == scope_info->ContextLength()); 188 DCHECK_EQ(scope->num_heap_slots(), scope_info->ContextLength());
197 return scope_info; 189 return scope_info;
198 } 190 }
199 191
200 192
201 Handle<ScopeInfo> ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) { 193 Handle<ScopeInfo> ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) {
202 DCHECK(isolate->bootstrapper()->IsActive()); 194 DCHECK(isolate->bootstrapper()->IsActive());
203 195
204 const int stack_local_count = 0; 196 const int stack_local_count = 0;
205 const int context_local_count = 1; 197 const int context_local_count = 1;
206 const int context_global_count = 0;
207 const bool has_simple_parameters = true; 198 const bool has_simple_parameters = true;
208 const VariableAllocationInfo receiver_info = CONTEXT; 199 const VariableAllocationInfo receiver_info = CONTEXT;
209 const VariableAllocationInfo function_name_info = NONE; 200 const VariableAllocationInfo function_name_info = NONE;
210 const VariableMode function_variable_mode = VAR; 201 const VariableMode function_variable_mode = VAR;
211 const bool has_function_name = false; 202 const bool has_function_name = false;
212 const bool has_receiver = true; 203 const bool has_receiver = true;
213 const int parameter_count = 0; 204 const int parameter_count = 0;
214 const int length = kVariablePartIndex + parameter_count + 205 const int length = kVariablePartIndex + parameter_count +
215 (1 + stack_local_count) + 2 * context_local_count + 206 (1 + stack_local_count) + 2 * context_local_count +
216 2 * context_global_count +
217 (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0); 207 (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0);
218 208
219 Factory* factory = isolate->factory(); 209 Factory* factory = isolate->factory();
220 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); 210 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
221 211
222 // Encode the flags. 212 // Encode the flags.
223 int flags = ScopeTypeField::encode(SCRIPT_SCOPE) | 213 int flags = ScopeTypeField::encode(SCRIPT_SCOPE) |
224 CallsEvalField::encode(false) | 214 CallsEvalField::encode(false) |
225 LanguageModeField::encode(SLOPPY) | 215 LanguageModeField::encode(SLOPPY) |
226 DeclarationScopeField::encode(true) | 216 DeclarationScopeField::encode(true) |
227 ReceiverVariableField::encode(receiver_info) | 217 ReceiverVariableField::encode(receiver_info) |
228 FunctionVariableField::encode(function_name_info) | 218 FunctionVariableField::encode(function_name_info) |
229 FunctionVariableMode::encode(function_variable_mode) | 219 FunctionVariableMode::encode(function_variable_mode) |
230 AsmModuleField::encode(false) | AsmFunctionField::encode(false) | 220 AsmModuleField::encode(false) | AsmFunctionField::encode(false) |
231 HasSimpleParametersField::encode(has_simple_parameters) | 221 HasSimpleParametersField::encode(has_simple_parameters) |
232 FunctionKindField::encode(FunctionKind::kNormalFunction); 222 FunctionKindField::encode(FunctionKind::kNormalFunction);
233 scope_info->SetFlags(flags); 223 scope_info->SetFlags(flags);
234 scope_info->SetParameterCount(parameter_count); 224 scope_info->SetParameterCount(parameter_count);
235 scope_info->SetStackLocalCount(stack_local_count); 225 scope_info->SetStackLocalCount(stack_local_count);
236 scope_info->SetContextLocalCount(context_local_count); 226 scope_info->SetContextLocalCount(context_local_count);
237 scope_info->SetContextGlobalCount(context_global_count);
238 227
239 int index = kVariablePartIndex; 228 int index = kVariablePartIndex;
240 const int first_slot_index = 0; 229 const int first_slot_index = 0;
241 DCHECK(index == scope_info->StackLocalFirstSlotIndex()); 230 DCHECK_EQ(index, scope_info->StackLocalFirstSlotIndex());
242 scope_info->set(index++, Smi::FromInt(first_slot_index)); 231 scope_info->set(index++, Smi::FromInt(first_slot_index));
243 DCHECK(index == scope_info->StackLocalEntriesIndex()); 232 DCHECK_EQ(index, scope_info->StackLocalEntriesIndex());
244 233
245 // Here we add info for context-allocated "this". 234 // Here we add info for context-allocated "this".
246 DCHECK(index == scope_info->ContextLocalNameEntriesIndex()); 235 DCHECK_EQ(index, scope_info->ContextLocalNameEntriesIndex());
247 scope_info->set(index++, *isolate->factory()->this_string()); 236 scope_info->set(index++, *isolate->factory()->this_string());
248 DCHECK(index == scope_info->ContextLocalInfoEntriesIndex()); 237 DCHECK_EQ(index, scope_info->ContextLocalInfoEntriesIndex());
249 const uint32_t value = VariableModeField::encode(CONST) | 238 const uint32_t value = VariableModeField::encode(CONST) |
250 InitFlagField::encode(kCreatedInitialized) | 239 InitFlagField::encode(kCreatedInitialized) |
251 MaybeAssignedFlagField::encode(kNotAssigned); 240 MaybeAssignedFlagField::encode(kNotAssigned);
252 scope_info->set(index++, Smi::FromInt(value)); 241 scope_info->set(index++, Smi::FromInt(value));
253 242
254 // And here we record that this scopeinfo binds a receiver. 243 // And here we record that this scopeinfo binds a receiver.
255 DCHECK(index == scope_info->ReceiverEntryIndex()); 244 DCHECK_EQ(index, scope_info->ReceiverEntryIndex());
256 const int receiver_index = Context::MIN_CONTEXT_SLOTS + 0; 245 const int receiver_index = Context::MIN_CONTEXT_SLOTS + 0;
257 scope_info->set(index++, Smi::FromInt(receiver_index)); 246 scope_info->set(index++, Smi::FromInt(receiver_index));
258 247
259 DCHECK(index == scope_info->FunctionNameEntryIndex()); 248 DCHECK_EQ(index, scope_info->FunctionNameEntryIndex());
260 249
261 DCHECK_EQ(index, scope_info->length()); 250 DCHECK_EQ(index, scope_info->length());
262 DCHECK_EQ(scope_info->ParameterCount(), 0); 251 DCHECK_EQ(scope_info->ParameterCount(), 0);
263 DCHECK_EQ(scope_info->ContextLength(), Context::MIN_CONTEXT_SLOTS + 1); 252 DCHECK_EQ(scope_info->ContextLength(), Context::MIN_CONTEXT_SLOTS + 1);
264 253
265 return scope_info; 254 return scope_info;
266 } 255 }
267 256
268 257
269 ScopeInfo* ScopeInfo::Empty(Isolate* isolate) { 258 ScopeInfo* ScopeInfo::Empty(Isolate* isolate) {
270 return reinterpret_cast<ScopeInfo*>(isolate->heap()->empty_fixed_array()); 259 return reinterpret_cast<ScopeInfo*>(isolate->heap()->empty_fixed_array());
271 } 260 }
272 261
273 262
274 ScopeType ScopeInfo::scope_type() { 263 ScopeType ScopeInfo::scope_type() {
275 DCHECK(length() > 0); 264 DCHECK_LT(0, length());
276 return ScopeTypeField::decode(Flags()); 265 return ScopeTypeField::decode(Flags());
277 } 266 }
278 267
279 268
280 bool ScopeInfo::CallsEval() { 269 bool ScopeInfo::CallsEval() {
281 return length() > 0 && CallsEvalField::decode(Flags()); 270 return length() > 0 && CallsEvalField::decode(Flags());
282 } 271 }
283 272
284 273
285 LanguageMode ScopeInfo::language_mode() { 274 LanguageMode ScopeInfo::language_mode() {
(...skipping 17 matching lines...) Expand all
303 FunctionVariableField::decode(Flags()) == STACK; 292 FunctionVariableField::decode(Flags()) == STACK;
304 return StackLocalCount() + (function_name_stack_slot ? 1 : 0); 293 return StackLocalCount() + (function_name_stack_slot ? 1 : 0);
305 } 294 }
306 return 0; 295 return 0;
307 } 296 }
308 297
309 298
310 int ScopeInfo::ContextLength() { 299 int ScopeInfo::ContextLength() {
311 if (length() > 0) { 300 if (length() > 0) {
312 int context_locals = ContextLocalCount(); 301 int context_locals = ContextLocalCount();
313 int context_globals = ContextGlobalCount();
314 bool function_name_context_slot = 302 bool function_name_context_slot =
315 FunctionVariableField::decode(Flags()) == CONTEXT; 303 FunctionVariableField::decode(Flags()) == CONTEXT;
316 bool has_context = context_locals > 0 || context_globals > 0 || 304 bool has_context = context_locals > 0 || function_name_context_slot ||
317 function_name_context_slot ||
318 scope_type() == WITH_SCOPE || 305 scope_type() == WITH_SCOPE ||
319 (scope_type() == BLOCK_SCOPE && CallsSloppyEval() && 306 (scope_type() == BLOCK_SCOPE && CallsSloppyEval() &&
320 is_declaration_scope()) || 307 is_declaration_scope()) ||
321 (scope_type() == FUNCTION_SCOPE && CallsSloppyEval()) || 308 (scope_type() == FUNCTION_SCOPE && CallsSloppyEval()) ||
322 scope_type() == MODULE_SCOPE; 309 scope_type() == MODULE_SCOPE;
323 310
324 if (has_context) { 311 if (has_context) {
325 return Context::MIN_CONTEXT_SLOTS + context_locals + context_globals + 312 return Context::MIN_CONTEXT_SLOTS + context_locals +
326 (function_name_context_slot ? 1 : 0); 313 (function_name_context_slot ? 1 : 0);
327 } 314 }
328 } 315 }
329 return 0; 316 return 0;
330 } 317 }
331 318
332 319
333 bool ScopeInfo::HasReceiver() { 320 bool ScopeInfo::HasReceiver() {
334 if (length() > 0) { 321 if (length() > 0) {
335 return NONE != ReceiverVariableField::decode(Flags()); 322 return NONE != ReceiverVariableField::decode(Flags());
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 } 362 }
376 363
377 364
378 String* ScopeInfo::FunctionName() { 365 String* ScopeInfo::FunctionName() {
379 DCHECK(HasFunctionName()); 366 DCHECK(HasFunctionName());
380 return String::cast(get(FunctionNameEntryIndex())); 367 return String::cast(get(FunctionNameEntryIndex()));
381 } 368 }
382 369
383 370
384 String* ScopeInfo::ParameterName(int var) { 371 String* ScopeInfo::ParameterName(int var) {
385 DCHECK(0 <= var && var < ParameterCount()); 372 DCHECK_LE(0, var);
373 DCHECK_LT(var, ParameterCount());
386 int info_index = ParameterEntriesIndex() + var; 374 int info_index = ParameterEntriesIndex() + var;
387 return String::cast(get(info_index)); 375 return String::cast(get(info_index));
388 } 376 }
389 377
390 378
391 String* ScopeInfo::LocalName(int var) { 379 String* ScopeInfo::LocalName(int var) {
392 DCHECK(0 <= var && var < LocalCount()); 380 DCHECK_LE(0, var);
381 DCHECK_LT(var, LocalCount());
393 DCHECK(StackLocalEntriesIndex() + StackLocalCount() == 382 DCHECK(StackLocalEntriesIndex() + StackLocalCount() ==
394 ContextLocalNameEntriesIndex()); 383 ContextLocalNameEntriesIndex());
395 int info_index = StackLocalEntriesIndex() + var; 384 int info_index = StackLocalEntriesIndex() + var;
396 return String::cast(get(info_index)); 385 return String::cast(get(info_index));
397 } 386 }
398 387
399 388
400 String* ScopeInfo::StackLocalName(int var) { 389 String* ScopeInfo::StackLocalName(int var) {
401 DCHECK(0 <= var && var < StackLocalCount()); 390 DCHECK_LE(0, var);
391 DCHECK_LT(var, StackLocalCount());
402 int info_index = StackLocalEntriesIndex() + var; 392 int info_index = StackLocalEntriesIndex() + var;
403 return String::cast(get(info_index)); 393 return String::cast(get(info_index));
404 } 394 }
405 395
406 396
407 int ScopeInfo::StackLocalIndex(int var) { 397 int ScopeInfo::StackLocalIndex(int var) {
408 DCHECK(0 <= var && var < StackLocalCount()); 398 DCHECK_LE(0, var);
399 DCHECK_LT(var, StackLocalCount());
409 int first_slot_index = Smi::cast(get(StackLocalFirstSlotIndex()))->value(); 400 int first_slot_index = Smi::cast(get(StackLocalFirstSlotIndex()))->value();
410 return first_slot_index + var; 401 return first_slot_index + var;
411 } 402 }
412 403
413 404
414 String* ScopeInfo::ContextLocalName(int var) { 405 String* ScopeInfo::ContextLocalName(int var) {
415 DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount()); 406 DCHECK_LE(0, var);
407 DCHECK_LT(var, ContextLocalCount());
416 int info_index = ContextLocalNameEntriesIndex() + var; 408 int info_index = ContextLocalNameEntriesIndex() + var;
417 return String::cast(get(info_index)); 409 return String::cast(get(info_index));
418 } 410 }
419 411
420 412
421 VariableMode ScopeInfo::ContextLocalMode(int var) { 413 VariableMode ScopeInfo::ContextLocalMode(int var) {
422 DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount()); 414 DCHECK_LE(0, var);
415 DCHECK_LT(var, ContextLocalCount());
423 int info_index = ContextLocalInfoEntriesIndex() + var; 416 int info_index = ContextLocalInfoEntriesIndex() + var;
424 int value = Smi::cast(get(info_index))->value(); 417 int value = Smi::cast(get(info_index))->value();
425 return VariableModeField::decode(value); 418 return VariableModeField::decode(value);
426 } 419 }
427 420
428 421
429 InitializationFlag ScopeInfo::ContextLocalInitFlag(int var) { 422 InitializationFlag ScopeInfo::ContextLocalInitFlag(int var) {
430 DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount()); 423 DCHECK_LE(0, var);
424 DCHECK_LT(var, ContextLocalCount());
431 int info_index = ContextLocalInfoEntriesIndex() + var; 425 int info_index = ContextLocalInfoEntriesIndex() + var;
432 int value = Smi::cast(get(info_index))->value(); 426 int value = Smi::cast(get(info_index))->value();
433 return InitFlagField::decode(value); 427 return InitFlagField::decode(value);
434 } 428 }
435 429
436 430
437 MaybeAssignedFlag ScopeInfo::ContextLocalMaybeAssignedFlag(int var) { 431 MaybeAssignedFlag ScopeInfo::ContextLocalMaybeAssignedFlag(int var) {
438 DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount()); 432 DCHECK_LE(0, var);
433 DCHECK_LT(var, ContextLocalCount());
439 int info_index = ContextLocalInfoEntriesIndex() + var; 434 int info_index = ContextLocalInfoEntriesIndex() + var;
440 int value = Smi::cast(get(info_index))->value(); 435 int value = Smi::cast(get(info_index))->value();
441 return MaybeAssignedFlagField::decode(value); 436 return MaybeAssignedFlagField::decode(value);
442 } 437 }
443 438
444 bool ScopeInfo::VariableIsSynthetic(String* name) { 439 bool ScopeInfo::VariableIsSynthetic(String* name) {
445 // There's currently no flag stored on the ScopeInfo to indicate that a 440 // There's currently no flag stored on the ScopeInfo to indicate that a
446 // variable is a compiler-introduced temporary. However, to avoid conflict 441 // variable is a compiler-introduced temporary. However, to avoid conflict
447 // with user declarations, the current temporaries like .generator_object and 442 // with user declarations, the current temporaries like .generator_object and
448 // .result start with a dot, so we can use that as a flag. It's a hack! 443 // .result start with a dot, so we can use that as a flag. It's a hack!
(...skipping 26 matching lines...) Expand all
475 DCHECK_NOT_NULL(mode); 470 DCHECK_NOT_NULL(mode);
476 DCHECK_NOT_NULL(init_flag); 471 DCHECK_NOT_NULL(init_flag);
477 DCHECK_NOT_NULL(maybe_assigned_flag); 472 DCHECK_NOT_NULL(maybe_assigned_flag);
478 473
479 if (scope_info->length() > 0) { 474 if (scope_info->length() > 0) {
480 ContextSlotCache* context_slot_cache = 475 ContextSlotCache* context_slot_cache =
481 scope_info->GetIsolate()->context_slot_cache(); 476 scope_info->GetIsolate()->context_slot_cache();
482 int result = context_slot_cache->Lookup(*scope_info, *name, mode, init_flag, 477 int result = context_slot_cache->Lookup(*scope_info, *name, mode, init_flag,
483 maybe_assigned_flag); 478 maybe_assigned_flag);
484 if (result != ContextSlotCache::kNotFound) { 479 if (result != ContextSlotCache::kNotFound) {
485 DCHECK(result < scope_info->ContextLength()); 480 DCHECK_LT(result, scope_info->ContextLength());
486 return result; 481 return result;
487 } 482 }
488 483
489 int start = scope_info->ContextLocalNameEntriesIndex(); 484 int start = scope_info->ContextLocalNameEntriesIndex();
490 int end = start + scope_info->ContextLocalCount(); 485 int end = start + scope_info->ContextLocalCount();
491 for (int i = start; i < end; ++i) { 486 for (int i = start; i < end; ++i) {
492 if (*name == scope_info->get(i)) { 487 if (*name == scope_info->get(i)) {
493 int var = i - start; 488 int var = i - start;
494 *mode = scope_info->ContextLocalMode(var); 489 *mode = scope_info->ContextLocalMode(var);
495 *init_flag = scope_info->ContextLocalInitFlag(var); 490 *init_flag = scope_info->ContextLocalInitFlag(var);
496 *maybe_assigned_flag = scope_info->ContextLocalMaybeAssignedFlag(var); 491 *maybe_assigned_flag = scope_info->ContextLocalMaybeAssignedFlag(var);
497 result = Context::MIN_CONTEXT_SLOTS + var; 492 result = Context::MIN_CONTEXT_SLOTS + var;
498 493
499 context_slot_cache->Update(scope_info, name, *mode, *init_flag, 494 context_slot_cache->Update(scope_info, name, *mode, *init_flag,
500 *maybe_assigned_flag, result); 495 *maybe_assigned_flag, result);
501 DCHECK(result < scope_info->ContextLength()); 496 DCHECK_LT(result, scope_info->ContextLength());
502 return result; 497 return result;
503 } 498 }
504 } 499 }
505 // Cache as not found. Mode, init flag and maybe assigned flag don't matter. 500 // Cache as not found. Mode, init flag and maybe assigned flag don't matter.
506 context_slot_cache->Update(scope_info, name, TEMPORARY, 501 context_slot_cache->Update(scope_info, name, TEMPORARY,
507 kNeedsInitialization, kNotAssigned, -1); 502 kNeedsInitialization, kNotAssigned, -1);
508 } 503 }
509 504
510 return -1; 505 return -1;
511 } 506 }
512 507
513 int ScopeInfo::ContextGlobalSlotIndex(Handle<ScopeInfo> scope_info,
514 Handle<String> name, VariableMode* mode,
515 InitializationFlag* init_flag,
516 MaybeAssignedFlag* maybe_assigned_flag) {
517 DCHECK(name->IsInternalizedString());
518 DCHECK_NOT_NULL(mode);
519 DCHECK_NOT_NULL(init_flag);
520 DCHECK_NOT_NULL(maybe_assigned_flag);
521 if (scope_info->length() > 0) {
522 // This is to ensure that ContextLocalMode() and co. queries would work.
523 DCHECK_EQ(scope_info->ContextGlobalNameEntriesIndex(),
524 scope_info->ContextLocalNameEntriesIndex() +
525 scope_info->ContextLocalCount());
526 int base = scope_info->ContextLocalNameEntriesIndex();
527 int start = scope_info->ContextGlobalNameEntriesIndex();
528 int end = start + scope_info->ContextGlobalCount();
529 for (int i = start; i < end; ++i) {
530 if (*name == scope_info->get(i)) {
531 int var = i - base;
532 *mode = scope_info->ContextLocalMode(var);
533 *init_flag = scope_info->ContextLocalInitFlag(var);
534 *maybe_assigned_flag = scope_info->ContextLocalMaybeAssignedFlag(var);
535 int result = Context::MIN_CONTEXT_SLOTS + var;
536 DCHECK(result < scope_info->ContextLength());
537 return result;
538 }
539 }
540 }
541 return -1;
542 }
543
544
545 String* ScopeInfo::ContextSlotName(int slot_index) { 508 String* ScopeInfo::ContextSlotName(int slot_index) {
546 int const var = slot_index - Context::MIN_CONTEXT_SLOTS; 509 int const var = slot_index - Context::MIN_CONTEXT_SLOTS;
547 DCHECK_LE(0, var); 510 DCHECK_LE(0, var);
548 DCHECK_LT(var, ContextLocalCount() + ContextGlobalCount()); 511 DCHECK_LT(var, ContextLocalCount());
549 return ContextLocalName(var); 512 return ContextLocalName(var);
550 } 513 }
551 514
552 515
553 int ScopeInfo::ParameterIndex(String* name) { 516 int ScopeInfo::ParameterIndex(String* name) {
554 DCHECK(name->IsInternalizedString()); 517 DCHECK(name->IsInternalizedString());
555 if (length() > 0) { 518 if (length() > 0) {
556 // We must read parameters from the end since for 519 // We must read parameters from the end since for
557 // multiply declared parameters the value of the 520 // multiply declared parameters the value of the
558 // last declaration of that parameter is used 521 // last declaration of that parameter is used
(...skipping 13 matching lines...) Expand all
572 535
573 int ScopeInfo::ReceiverContextSlotIndex() { 536 int ScopeInfo::ReceiverContextSlotIndex() {
574 if (length() > 0 && ReceiverVariableField::decode(Flags()) == CONTEXT) 537 if (length() > 0 && ReceiverVariableField::decode(Flags()) == CONTEXT)
575 return Smi::cast(get(ReceiverEntryIndex()))->value(); 538 return Smi::cast(get(ReceiverEntryIndex()))->value();
576 return -1; 539 return -1;
577 } 540 }
578 541
579 542
580 int ScopeInfo::FunctionContextSlotIndex(String* name, VariableMode* mode) { 543 int ScopeInfo::FunctionContextSlotIndex(String* name, VariableMode* mode) {
581 DCHECK(name->IsInternalizedString()); 544 DCHECK(name->IsInternalizedString());
582 DCHECK(mode != NULL); 545 DCHECK_NOT_NULL(mode);
583 if (length() > 0) { 546 if (length() > 0) {
584 if (FunctionVariableField::decode(Flags()) == CONTEXT && 547 if (FunctionVariableField::decode(Flags()) == CONTEXT &&
585 FunctionName() == name) { 548 FunctionName() == name) {
586 *mode = FunctionVariableMode::decode(Flags()); 549 *mode = FunctionVariableMode::decode(Flags());
587 return Smi::cast(get(FunctionNameEntryIndex() + 1))->value(); 550 return Smi::cast(get(FunctionNameEntryIndex() + 1))->value();
588 } 551 }
589 } 552 }
590 return -1; 553 return -1;
591 } 554 }
592 555
593 556
594 FunctionKind ScopeInfo::function_kind() { 557 FunctionKind ScopeInfo::function_kind() {
595 return FunctionKindField::decode(Flags()); 558 return FunctionKindField::decode(Flags());
596 } 559 }
597 560
598 561
599 int ScopeInfo::ParameterEntriesIndex() { 562 int ScopeInfo::ParameterEntriesIndex() {
600 DCHECK(length() > 0); 563 DCHECK_LT(0, length());
601 return kVariablePartIndex; 564 return kVariablePartIndex;
602 } 565 }
603 566
604 567
605 int ScopeInfo::StackLocalFirstSlotIndex() { 568 int ScopeInfo::StackLocalFirstSlotIndex() {
606 return ParameterEntriesIndex() + ParameterCount(); 569 return ParameterEntriesIndex() + ParameterCount();
607 } 570 }
608 571
609 572
610 int ScopeInfo::StackLocalEntriesIndex() { 573 int ScopeInfo::StackLocalEntriesIndex() {
611 return StackLocalFirstSlotIndex() + 1; 574 return StackLocalFirstSlotIndex() + 1;
612 } 575 }
613 576
614 577
615 int ScopeInfo::ContextLocalNameEntriesIndex() { 578 int ScopeInfo::ContextLocalNameEntriesIndex() {
616 return StackLocalEntriesIndex() + StackLocalCount(); 579 return StackLocalEntriesIndex() + StackLocalCount();
617 } 580 }
618 581
619 582
620 int ScopeInfo::ContextGlobalNameEntriesIndex() { 583 int ScopeInfo::ContextLocalInfoEntriesIndex() {
621 return ContextLocalNameEntriesIndex() + ContextLocalCount(); 584 return ContextLocalNameEntriesIndex() + ContextLocalCount();
622 } 585 }
623 586
624 587
625 int ScopeInfo::ContextLocalInfoEntriesIndex() { 588 int ScopeInfo::ReceiverEntryIndex() {
626 return ContextGlobalNameEntriesIndex() + ContextGlobalCount();
627 }
628
629
630 int ScopeInfo::ContextGlobalInfoEntriesIndex() {
631 return ContextLocalInfoEntriesIndex() + ContextLocalCount(); 589 return ContextLocalInfoEntriesIndex() + ContextLocalCount();
632 } 590 }
633 591
634 592
635 int ScopeInfo::ReceiverEntryIndex() {
636 return ContextGlobalInfoEntriesIndex() + ContextGlobalCount();
637 }
638
639
640 int ScopeInfo::FunctionNameEntryIndex() { 593 int ScopeInfo::FunctionNameEntryIndex() {
641 return ReceiverEntryIndex() + (HasAllocatedReceiver() ? 1 : 0); 594 return ReceiverEntryIndex() + (HasAllocatedReceiver() ? 1 : 0);
642 } 595 }
643 596
644 #ifdef DEBUG 597 #ifdef DEBUG
645 598
646 static void PrintList(const char* list_name, 599 static void PrintList(const char* list_name,
647 int nof_internal_slots, 600 int nof_internal_slots,
648 int start, 601 int start,
649 int end, 602 int end,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
681 ContextLocalNameEntriesIndex() + ContextLocalCount(), this); 634 ContextLocalNameEntriesIndex() + ContextLocalCount(), this);
682 } 635 }
683 636
684 PrintF("}\n"); 637 PrintF("}\n");
685 } 638 }
686 #endif // DEBUG 639 #endif // DEBUG
687 640
688 641
689 } // namespace internal 642 } // namespace internal
690 } // namespace v8 643 } // namespace v8
OLDNEW
« no previous file with comments | « src/ast/ast.cc ('k') | src/ast/scopes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698