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