OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stdlib.h> | 5 #include <stdlib.h> |
6 | 6 |
7 #include "src/ast/context-slot-cache.h" | 7 #include "src/ast/context-slot-cache.h" |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 | 10 |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |