| Index: src/scopeinfo.cc
|
| diff --git a/src/scopeinfo.cc b/src/scopeinfo.cc
|
| index 012744992fe783fa072249be7f7454de7699e7ca..4a0254bf592319db3c18f46411dd0a652b8f76b8 100644
|
| --- a/src/scopeinfo.cc
|
| +++ b/src/scopeinfo.cc
|
| @@ -32,8 +32,24 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
|
| bool simple_parameter_list =
|
| scope->is_function_scope() ? scope->is_simple_parameter_list() : true;
|
|
|
| + // Determine use and location of the "this" binding if it is present.
|
| + VariableAllocationInfo receiver_info;
|
| + if (scope->has_this_declaration()) {
|
| + Variable* var = scope->receiver();
|
| + if (!var->is_used()) {
|
| + receiver_info = UNUSED;
|
| + } else if (var->IsContextSlot()) {
|
| + receiver_info = CONTEXT;
|
| + } else {
|
| + DCHECK(var->IsParameter());
|
| + receiver_info = STACK;
|
| + }
|
| + } else {
|
| + receiver_info = NONE;
|
| + }
|
| +
|
| // Determine use and location of the function variable if it is present.
|
| - FunctionVariableInfo function_name_info;
|
| + VariableAllocationInfo function_name_info;
|
| VariableMode function_variable_mode;
|
| if (scope->is_function_scope() && scope->function() != NULL) {
|
| Variable* var = scope->function()->proxy()->var();
|
| @@ -52,11 +68,12 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
|
| }
|
|
|
| const bool has_function_name = function_name_info != NONE;
|
| + const bool has_receiver = receiver_info == STACK || receiver_info == CONTEXT;
|
| const int parameter_count = scope->num_parameters();
|
| const int length = kVariablePartIndex + parameter_count +
|
| (1 + stack_local_count) + 2 * context_local_count +
|
| 3 * strong_mode_free_variable_count +
|
| - (has_function_name ? 2 : 0);
|
| + (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0);
|
|
|
| Factory* factory = isolate->factory();
|
| Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
|
| @@ -65,6 +82,7 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
|
| int flags = ScopeTypeField::encode(scope->scope_type()) |
|
| CallsEvalField::encode(scope->calls_eval()) |
|
| LanguageModeField::encode(scope->language_mode()) |
|
| + ReceiverVariableField::encode(receiver_info) |
|
| FunctionVariableField::encode(function_name_info) |
|
| FunctionVariableMode::encode(function_variable_mode) |
|
| AsmModuleField::encode(scope->asm_module()) |
|
| @@ -146,6 +164,15 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
|
| scope_info->set(index++, *end_position);
|
| }
|
|
|
| + // If the receiver is allocated, add its index.
|
| + DCHECK(index == scope_info->ReceiverEntryIndex());
|
| + if (has_receiver) {
|
| + int var_index = scope->receiver()->index();
|
| + scope_info->set(index++, Smi::FromInt(var_index));
|
| + // ?? DCHECK(receiver_info != CONTEXT || var_index ==
|
| + // scope_info->ContextLength() - 1);
|
| + }
|
| +
|
| // If present, add the function variable name and its index.
|
| DCHECK(index == scope_info->FunctionNameEntryIndex());
|
| if (has_function_name) {
|
| @@ -220,6 +247,25 @@ int ScopeInfo::ContextLength() {
|
| }
|
|
|
|
|
| +bool ScopeInfo::HasReceiver() {
|
| + if (length() > 0) {
|
| + return NONE != ReceiverVariableField::decode(Flags());
|
| + } else {
|
| + return false;
|
| + }
|
| +}
|
| +
|
| +
|
| +bool ScopeInfo::HasAllocatedReceiver() {
|
| + if (length() > 0) {
|
| + VariableAllocationInfo allocation = ReceiverVariableField::decode(Flags());
|
| + return allocation == STACK || allocation == CONTEXT;
|
| + } else {
|
| + return false;
|
| + }
|
| +}
|
| +
|
| +
|
| bool ScopeInfo::HasFunctionName() {
|
| if (length() > 0) {
|
| return NONE != FunctionVariableField::decode(Flags());
|
| @@ -317,7 +363,8 @@ bool ScopeInfo::LocalIsSynthetic(int var) {
|
| // with user declarations, the current temporaries like .generator_object and
|
| // .result start with a dot, so we can use that as a flag. It's a hack!
|
| Handle<String> name(LocalName(var));
|
| - return name->length() > 0 && name->Get(0) == '.';
|
| + return (name->length() > 0 && name->Get(0) == '.') ||
|
| + name->Equals(*GetIsolate()->factory()->this_string());
|
| }
|
|
|
|
|
| @@ -427,6 +474,13 @@ int ScopeInfo::ParameterIndex(String* name) {
|
| }
|
|
|
|
|
| +int ScopeInfo::ReceiverContextSlotIndex() {
|
| + if (length() > 0 && ReceiverVariableField::decode(Flags()) == CONTEXT)
|
| + return Smi::cast(get(ReceiverEntryIndex()))->value();
|
| + return -1;
|
| +}
|
| +
|
| +
|
| int ScopeInfo::FunctionContextSlotIndex(String* name, VariableMode* mode) {
|
| DCHECK(name->IsInternalizedString());
|
| DCHECK(mode != NULL);
|
| @@ -514,12 +568,17 @@ int ScopeInfo::StrongModeFreeVariablePositionEntriesIndex() {
|
| }
|
|
|
|
|
| -int ScopeInfo::FunctionNameEntryIndex() {
|
| +int ScopeInfo::ReceiverEntryIndex() {
|
| return StrongModeFreeVariablePositionEntriesIndex() +
|
| 2 * StrongModeFreeVariableCount();
|
| }
|
|
|
|
|
| +int ScopeInfo::FunctionNameEntryIndex() {
|
| + return ReceiverEntryIndex() + (HasAllocatedReceiver() ? 1 : 0);
|
| +}
|
| +
|
| +
|
| int ContextSlotCache::Hash(Object* data, String* name) {
|
| // Uses only lower 32 bits if pointers are larger.
|
| uintptr_t addr_hash =
|
|
|