| Index: src/ast/scopeinfo.cc
|
| diff --git a/src/ast/scopeinfo.cc b/src/ast/scopeinfo.cc
|
| deleted file mode 100644
|
| index 9c7fedbdaa342b308c7e91ec9e1a6c17b7456027..0000000000000000000000000000000000000000
|
| --- a/src/ast/scopeinfo.cc
|
| +++ /dev/null
|
| @@ -1,981 +0,0 @@
|
| -// Copyright 2011 the V8 project authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include <stdlib.h>
|
| -
|
| -#include "src/objects/scope-info.h"
|
| -
|
| -#include "src/ast/context-slot-cache.h"
|
| -#include "src/ast/scopes.h"
|
| -#include "src/ast/variables.h"
|
| -#include "src/bootstrapper.h"
|
| -#include "src/objects-inl.h"
|
| -
|
| -namespace v8 {
|
| -namespace internal {
|
| -
|
| -// An entry in ModuleVariableEntries consists of several slots:
|
| -enum ModuleVariableEntryOffset {
|
| - kModuleVariableNameOffset,
|
| - kModuleVariableIndexOffset,
|
| - kModuleVariablePropertiesOffset,
|
| - kModuleVariableEntryLength // Sentinel value.
|
| -};
|
| -
|
| -#ifdef DEBUG
|
| -bool ScopeInfo::Equals(ScopeInfo* other) const {
|
| - if (length() != other->length()) return false;
|
| - for (int index = 0; index < length(); ++index) {
|
| - Object* entry = get(index);
|
| - Object* other_entry = other->get(index);
|
| - if (entry->IsSmi()) {
|
| - if (entry != other_entry) return false;
|
| - } else {
|
| - if (HeapObject::cast(entry)->map()->instance_type() !=
|
| - HeapObject::cast(other_entry)->map()->instance_type()) {
|
| - return false;
|
| - }
|
| - if (entry->IsString()) {
|
| - if (!String::cast(entry)->Equals(String::cast(other_entry))) {
|
| - return false;
|
| - }
|
| - } else if (entry->IsScopeInfo()) {
|
| - if (!ScopeInfo::cast(entry)->Equals(ScopeInfo::cast(other_entry))) {
|
| - return false;
|
| - }
|
| - } else if (entry->IsModuleInfo()) {
|
| - if (!ModuleInfo::cast(entry)->Equals(ModuleInfo::cast(other_entry))) {
|
| - return false;
|
| - }
|
| - } else {
|
| - UNREACHABLE();
|
| - return false;
|
| - }
|
| - }
|
| - }
|
| - return true;
|
| -}
|
| -#endif
|
| -
|
| -Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, Scope* scope,
|
| - MaybeHandle<ScopeInfo> outer_scope) {
|
| - // Collect variables.
|
| - int stack_local_count = 0;
|
| - int context_local_count = 0;
|
| - int module_vars_count = 0;
|
| - // Stack allocated block scope variables are allocated in the parent
|
| - // declaration scope, but are recorded in the block scope's scope info. First
|
| - // slot index indicates at which offset a particular scope starts in the
|
| - // parent declaration scope.
|
| - int first_slot_index = 0;
|
| - for (Variable* var : *scope->locals()) {
|
| - switch (var->location()) {
|
| - case VariableLocation::LOCAL:
|
| - if (stack_local_count == 0) first_slot_index = var->index();
|
| - stack_local_count++;
|
| - break;
|
| - case VariableLocation::CONTEXT:
|
| - context_local_count++;
|
| - break;
|
| - case VariableLocation::MODULE:
|
| - module_vars_count++;
|
| - break;
|
| - default:
|
| - break;
|
| - }
|
| - }
|
| - DCHECK(module_vars_count == 0 || scope->is_module_scope());
|
| -
|
| - // Make sure we allocate the correct amount.
|
| - DCHECK_EQ(scope->ContextLocalCount(), context_local_count);
|
| -
|
| - // Determine use and location of the "this" binding if it is present.
|
| - VariableAllocationInfo receiver_info;
|
| - if (scope->is_declaration_scope() &&
|
| - scope->AsDeclarationScope()->has_this_declaration()) {
|
| - Variable* var = scope->AsDeclarationScope()->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;
|
| - }
|
| -
|
| - bool has_new_target =
|
| - scope->is_declaration_scope() &&
|
| - scope->AsDeclarationScope()->new_target_var() != nullptr;
|
| -
|
| - // Determine use and location of the function variable if it is present.
|
| - VariableAllocationInfo function_name_info;
|
| - if (scope->is_function_scope() &&
|
| - scope->AsDeclarationScope()->function_var() != nullptr) {
|
| - Variable* var = scope->AsDeclarationScope()->function_var();
|
| - if (!var->is_used()) {
|
| - function_name_info = UNUSED;
|
| - } else if (var->IsContextSlot()) {
|
| - function_name_info = CONTEXT;
|
| - } else {
|
| - DCHECK(var->IsStackLocal());
|
| - function_name_info = STACK;
|
| - }
|
| - } else {
|
| - function_name_info = NONE;
|
| - }
|
| -
|
| - 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 bool has_outer_scope_info = !outer_scope.is_null();
|
| - const int length = kVariablePartIndex + parameter_count +
|
| - (1 + stack_local_count) + 2 * context_local_count +
|
| - (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0) +
|
| - (has_outer_scope_info ? 1 : 0) +
|
| - (scope->is_module_scope()
|
| - ? 2 + kModuleVariableEntryLength * module_vars_count
|
| - : 0);
|
| -
|
| - Factory* factory = isolate->factory();
|
| - Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
|
| -
|
| - bool has_simple_parameters = false;
|
| - bool asm_module = false;
|
| - bool asm_function = false;
|
| - if (scope->is_function_scope()) {
|
| - DeclarationScope* function_scope = scope->AsDeclarationScope();
|
| - has_simple_parameters = function_scope->has_simple_parameters();
|
| - asm_module = function_scope->asm_module();
|
| - asm_function = function_scope->asm_function();
|
| - }
|
| - FunctionKind function_kind = kNormalFunction;
|
| - if (scope->is_declaration_scope()) {
|
| - function_kind = scope->AsDeclarationScope()->function_kind();
|
| - }
|
| -
|
| - // Encode the flags.
|
| - int flags =
|
| - ScopeTypeField::encode(scope->scope_type()) |
|
| - CallsEvalField::encode(scope->calls_eval()) |
|
| - LanguageModeField::encode(scope->language_mode()) |
|
| - DeclarationScopeField::encode(scope->is_declaration_scope()) |
|
| - ReceiverVariableField::encode(receiver_info) |
|
| - HasNewTargetField::encode(has_new_target) |
|
| - FunctionVariableField::encode(function_name_info) |
|
| - AsmModuleField::encode(asm_module) |
|
| - AsmFunctionField::encode(asm_function) |
|
| - HasSimpleParametersField::encode(has_simple_parameters) |
|
| - FunctionKindField::encode(function_kind) |
|
| - HasOuterScopeInfoField::encode(has_outer_scope_info) |
|
| - IsDebugEvaluateScopeField::encode(scope->is_debug_evaluate_scope());
|
| - scope_info->SetFlags(flags);
|
| -
|
| - scope_info->SetParameterCount(parameter_count);
|
| - scope_info->SetStackLocalCount(stack_local_count);
|
| - scope_info->SetContextLocalCount(context_local_count);
|
| -
|
| - int index = kVariablePartIndex;
|
| - // Add parameters.
|
| - DCHECK_EQ(index, scope_info->ParameterNamesIndex());
|
| - if (scope->is_declaration_scope()) {
|
| - for (int i = 0; i < parameter_count; ++i) {
|
| - scope_info->set(index++,
|
| - *scope->AsDeclarationScope()->parameter(i)->name());
|
| - }
|
| - }
|
| -
|
| - // Add stack locals' names, context locals' names and info, module variables'
|
| - // names and info. We are assuming that the stack locals' slots are allocated
|
| - // in increasing order, so we can simply add them to the ScopeInfo object.
|
| - // Context locals are added using their index.
|
| - DCHECK_EQ(index, scope_info->StackLocalFirstSlotIndex());
|
| - scope_info->set(index++, Smi::FromInt(first_slot_index));
|
| - DCHECK_EQ(index, scope_info->StackLocalNamesIndex());
|
| -
|
| - int stack_local_base = index;
|
| - int context_local_base = stack_local_base + stack_local_count;
|
| - int context_local_info_base = context_local_base + context_local_count;
|
| - int module_var_entry = scope_info->ModuleVariablesIndex();
|
| -
|
| - for (Variable* var : *scope->locals()) {
|
| - switch (var->location()) {
|
| - case VariableLocation::LOCAL: {
|
| - int local_index = var->index() - first_slot_index;
|
| - DCHECK_LE(0, local_index);
|
| - DCHECK_LT(local_index, stack_local_count);
|
| - scope_info->set(stack_local_base + local_index, *var->name());
|
| - break;
|
| - }
|
| - case VariableLocation::CONTEXT: {
|
| - // Due to duplicate parameters, context locals aren't guaranteed to come
|
| - // in order.
|
| - int local_index = var->index() - Context::MIN_CONTEXT_SLOTS;
|
| - DCHECK_LE(0, local_index);
|
| - DCHECK_LT(local_index, context_local_count);
|
| - uint32_t info = VariableModeField::encode(var->mode()) |
|
| - InitFlagField::encode(var->initialization_flag()) |
|
| - MaybeAssignedFlagField::encode(var->maybe_assigned());
|
| - scope_info->set(context_local_base + local_index, *var->name());
|
| - scope_info->set(context_local_info_base + local_index,
|
| - Smi::FromInt(info));
|
| - break;
|
| - }
|
| - case VariableLocation::MODULE: {
|
| - scope_info->set(module_var_entry + kModuleVariableNameOffset,
|
| - *var->name());
|
| - scope_info->set(module_var_entry + kModuleVariableIndexOffset,
|
| - Smi::FromInt(var->index()));
|
| - uint32_t properties =
|
| - VariableModeField::encode(var->mode()) |
|
| - InitFlagField::encode(var->initialization_flag()) |
|
| - MaybeAssignedFlagField::encode(var->maybe_assigned());
|
| - scope_info->set(module_var_entry + kModuleVariablePropertiesOffset,
|
| - Smi::FromInt(properties));
|
| - module_var_entry += kModuleVariableEntryLength;
|
| - break;
|
| - }
|
| - default:
|
| - break;
|
| - }
|
| - }
|
| -
|
| - index += stack_local_count + 2 * context_local_count;
|
| -
|
| - // If the receiver is allocated, add its index.
|
| - DCHECK_EQ(index, scope_info->ReceiverInfoIndex());
|
| - if (has_receiver) {
|
| - int var_index = scope->AsDeclarationScope()->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_EQ(index, scope_info->FunctionNameInfoIndex());
|
| - if (has_function_name) {
|
| - int var_index = scope->AsDeclarationScope()->function_var()->index();
|
| - scope_info->set(index++,
|
| - *scope->AsDeclarationScope()->function_var()->name());
|
| - scope_info->set(index++, Smi::FromInt(var_index));
|
| - DCHECK(function_name_info != CONTEXT ||
|
| - var_index == scope_info->ContextLength() - 1);
|
| - }
|
| -
|
| - // If present, add the outer scope info.
|
| - DCHECK(index == scope_info->OuterScopeInfoIndex());
|
| - if (has_outer_scope_info) {
|
| - scope_info->set(index++, *outer_scope.ToHandleChecked());
|
| - }
|
| -
|
| - // Module-specific information (only for module scopes).
|
| - if (scope->is_module_scope()) {
|
| - Handle<ModuleInfo> module_info =
|
| - ModuleInfo::New(isolate, zone, scope->AsModuleScope()->module());
|
| - DCHECK_EQ(index, scope_info->ModuleInfoIndex());
|
| - scope_info->set(index++, *module_info);
|
| - DCHECK_EQ(index, scope_info->ModuleVariableCountIndex());
|
| - scope_info->set(index++, Smi::FromInt(module_vars_count));
|
| - DCHECK_EQ(index, scope_info->ModuleVariablesIndex());
|
| - // The variable entries themselves have already been written above.
|
| - index += kModuleVariableEntryLength * module_vars_count;
|
| - }
|
| -
|
| - DCHECK_EQ(index, scope_info->length());
|
| - DCHECK_EQ(scope->num_parameters(), scope_info->ParameterCount());
|
| - DCHECK_EQ(scope->num_heap_slots(), scope_info->ContextLength());
|
| - return scope_info;
|
| -}
|
| -
|
| -Handle<ScopeInfo> ScopeInfo::CreateForWithScope(
|
| - Isolate* isolate, MaybeHandle<ScopeInfo> outer_scope) {
|
| - const bool has_outer_scope_info = !outer_scope.is_null();
|
| - const int length = kVariablePartIndex + 1 + (has_outer_scope_info ? 1 : 0);
|
| -
|
| - Factory* factory = isolate->factory();
|
| - Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
|
| -
|
| - // Encode the flags.
|
| - int flags =
|
| - ScopeTypeField::encode(WITH_SCOPE) | CallsEvalField::encode(false) |
|
| - LanguageModeField::encode(SLOPPY) | DeclarationScopeField::encode(false) |
|
| - ReceiverVariableField::encode(NONE) | HasNewTargetField::encode(false) |
|
| - FunctionVariableField::encode(NONE) | AsmModuleField::encode(false) |
|
| - AsmFunctionField::encode(false) | HasSimpleParametersField::encode(true) |
|
| - FunctionKindField::encode(kNormalFunction) |
|
| - HasOuterScopeInfoField::encode(has_outer_scope_info) |
|
| - IsDebugEvaluateScopeField::encode(false);
|
| - scope_info->SetFlags(flags);
|
| -
|
| - scope_info->SetParameterCount(0);
|
| - scope_info->SetStackLocalCount(0);
|
| - scope_info->SetContextLocalCount(0);
|
| -
|
| - int index = kVariablePartIndex;
|
| - DCHECK_EQ(index, scope_info->ParameterNamesIndex());
|
| - DCHECK_EQ(index, scope_info->StackLocalFirstSlotIndex());
|
| - scope_info->set(index++, Smi::kZero);
|
| - DCHECK_EQ(index, scope_info->StackLocalNamesIndex());
|
| - DCHECK_EQ(index, scope_info->ReceiverInfoIndex());
|
| - DCHECK_EQ(index, scope_info->FunctionNameInfoIndex());
|
| - DCHECK(index == scope_info->OuterScopeInfoIndex());
|
| - if (has_outer_scope_info) {
|
| - scope_info->set(index++, *outer_scope.ToHandleChecked());
|
| - }
|
| - DCHECK_EQ(index, scope_info->length());
|
| - DCHECK_EQ(0, scope_info->ParameterCount());
|
| - DCHECK_EQ(Context::MIN_CONTEXT_SLOTS, scope_info->ContextLength());
|
| - return scope_info;
|
| -}
|
| -
|
| -Handle<ScopeInfo> ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) {
|
| - DCHECK(isolate->bootstrapper()->IsActive());
|
| -
|
| - const int stack_local_count = 0;
|
| - const int context_local_count = 1;
|
| - const bool has_simple_parameters = true;
|
| - const VariableAllocationInfo receiver_info = CONTEXT;
|
| - const VariableAllocationInfo function_name_info = NONE;
|
| - const bool has_function_name = false;
|
| - const bool has_receiver = true;
|
| - const bool has_outer_scope_info = false;
|
| - const int parameter_count = 0;
|
| - const int length = kVariablePartIndex + parameter_count +
|
| - (1 + stack_local_count) + 2 * context_local_count +
|
| - (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0) +
|
| - (has_outer_scope_info ? 1 : 0);
|
| -
|
| - Factory* factory = isolate->factory();
|
| - Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
|
| -
|
| - // Encode the flags.
|
| - int flags =
|
| - ScopeTypeField::encode(SCRIPT_SCOPE) | CallsEvalField::encode(false) |
|
| - LanguageModeField::encode(SLOPPY) | DeclarationScopeField::encode(true) |
|
| - ReceiverVariableField::encode(receiver_info) |
|
| - FunctionVariableField::encode(function_name_info) |
|
| - AsmModuleField::encode(false) | AsmFunctionField::encode(false) |
|
| - HasSimpleParametersField::encode(has_simple_parameters) |
|
| - FunctionKindField::encode(FunctionKind::kNormalFunction) |
|
| - HasOuterScopeInfoField::encode(has_outer_scope_info) |
|
| - IsDebugEvaluateScopeField::encode(false);
|
| - scope_info->SetFlags(flags);
|
| - scope_info->SetParameterCount(parameter_count);
|
| - scope_info->SetStackLocalCount(stack_local_count);
|
| - scope_info->SetContextLocalCount(context_local_count);
|
| -
|
| - int index = kVariablePartIndex;
|
| - const int first_slot_index = 0;
|
| - DCHECK_EQ(index, scope_info->StackLocalFirstSlotIndex());
|
| - scope_info->set(index++, Smi::FromInt(first_slot_index));
|
| - DCHECK_EQ(index, scope_info->StackLocalNamesIndex());
|
| -
|
| - // Here we add info for context-allocated "this".
|
| - DCHECK_EQ(index, scope_info->ContextLocalNamesIndex());
|
| - scope_info->set(index++, isolate->heap()->this_string());
|
| - DCHECK_EQ(index, scope_info->ContextLocalInfosIndex());
|
| - const uint32_t value = VariableModeField::encode(CONST) |
|
| - InitFlagField::encode(kCreatedInitialized) |
|
| - MaybeAssignedFlagField::encode(kNotAssigned);
|
| - scope_info->set(index++, Smi::FromInt(value));
|
| -
|
| - // And here we record that this scopeinfo binds a receiver.
|
| - DCHECK_EQ(index, scope_info->ReceiverInfoIndex());
|
| - const int receiver_index = Context::MIN_CONTEXT_SLOTS + 0;
|
| - scope_info->set(index++, Smi::FromInt(receiver_index));
|
| -
|
| - DCHECK_EQ(index, scope_info->FunctionNameInfoIndex());
|
| - DCHECK_EQ(index, scope_info->OuterScopeInfoIndex());
|
| - DCHECK_EQ(index, scope_info->length());
|
| - DCHECK_EQ(scope_info->ParameterCount(), 0);
|
| - DCHECK_EQ(scope_info->ContextLength(), Context::MIN_CONTEXT_SLOTS + 1);
|
| -
|
| - return scope_info;
|
| -}
|
| -
|
| -
|
| -ScopeInfo* ScopeInfo::Empty(Isolate* isolate) {
|
| - return isolate->heap()->empty_scope_info();
|
| -}
|
| -
|
| -
|
| -ScopeType ScopeInfo::scope_type() {
|
| - DCHECK_LT(0, length());
|
| - return ScopeTypeField::decode(Flags());
|
| -}
|
| -
|
| -
|
| -bool ScopeInfo::CallsEval() {
|
| - return length() > 0 && CallsEvalField::decode(Flags());
|
| -}
|
| -
|
| -
|
| -LanguageMode ScopeInfo::language_mode() {
|
| - return length() > 0 ? LanguageModeField::decode(Flags()) : SLOPPY;
|
| -}
|
| -
|
| -
|
| -bool ScopeInfo::is_declaration_scope() {
|
| - return DeclarationScopeField::decode(Flags());
|
| -}
|
| -
|
| -
|
| -int ScopeInfo::LocalCount() {
|
| - return StackLocalCount() + ContextLocalCount();
|
| -}
|
| -
|
| -
|
| -int ScopeInfo::StackSlotCount() {
|
| - if (length() > 0) {
|
| - bool function_name_stack_slot =
|
| - FunctionVariableField::decode(Flags()) == STACK;
|
| - return StackLocalCount() + (function_name_stack_slot ? 1 : 0);
|
| - }
|
| - return 0;
|
| -}
|
| -
|
| -
|
| -int ScopeInfo::ContextLength() {
|
| - if (length() > 0) {
|
| - int context_locals = ContextLocalCount();
|
| - bool function_name_context_slot =
|
| - FunctionVariableField::decode(Flags()) == CONTEXT;
|
| - bool has_context = context_locals > 0 || function_name_context_slot ||
|
| - scope_type() == WITH_SCOPE ||
|
| - (scope_type() == BLOCK_SCOPE && CallsSloppyEval() &&
|
| - is_declaration_scope()) ||
|
| - (scope_type() == FUNCTION_SCOPE && CallsSloppyEval()) ||
|
| - (scope_type() == FUNCTION_SCOPE && IsAsmModule()) ||
|
| - scope_type() == MODULE_SCOPE;
|
| -
|
| - if (has_context) {
|
| - return Context::MIN_CONTEXT_SLOTS + context_locals +
|
| - (function_name_context_slot ? 1 : 0);
|
| - }
|
| - }
|
| - return 0;
|
| -}
|
| -
|
| -
|
| -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::HasNewTarget() { return HasNewTargetField::decode(Flags()); }
|
| -
|
| -
|
| -bool ScopeInfo::HasFunctionName() {
|
| - if (length() > 0) {
|
| - return NONE != FunctionVariableField::decode(Flags());
|
| - } else {
|
| - return false;
|
| - }
|
| -}
|
| -
|
| -bool ScopeInfo::HasOuterScopeInfo() {
|
| - if (length() > 0) {
|
| - return HasOuterScopeInfoField::decode(Flags());
|
| - } else {
|
| - return false;
|
| - }
|
| -}
|
| -
|
| -bool ScopeInfo::IsDebugEvaluateScope() {
|
| - if (length() > 0) {
|
| - return IsDebugEvaluateScopeField::decode(Flags());
|
| - } else {
|
| - return false;
|
| - }
|
| -}
|
| -
|
| -void ScopeInfo::SetIsDebugEvaluateScope() {
|
| - if (length() > 0) {
|
| - DCHECK_EQ(scope_type(), WITH_SCOPE);
|
| - SetFlags(Flags() | IsDebugEvaluateScopeField::encode(true));
|
| - } else {
|
| - UNREACHABLE();
|
| - }
|
| -}
|
| -
|
| -bool ScopeInfo::HasHeapAllocatedLocals() {
|
| - if (length() > 0) {
|
| - return ContextLocalCount() > 0;
|
| - } else {
|
| - return false;
|
| - }
|
| -}
|
| -
|
| -
|
| -bool ScopeInfo::HasContext() {
|
| - return ContextLength() > 0;
|
| -}
|
| -
|
| -
|
| -String* ScopeInfo::FunctionName() {
|
| - DCHECK(HasFunctionName());
|
| - return String::cast(get(FunctionNameInfoIndex()));
|
| -}
|
| -
|
| -ScopeInfo* ScopeInfo::OuterScopeInfo() {
|
| - DCHECK(HasOuterScopeInfo());
|
| - return ScopeInfo::cast(get(OuterScopeInfoIndex()));
|
| -}
|
| -
|
| -ModuleInfo* ScopeInfo::ModuleDescriptorInfo() {
|
| - DCHECK(scope_type() == MODULE_SCOPE);
|
| - return ModuleInfo::cast(get(ModuleInfoIndex()));
|
| -}
|
| -
|
| -String* ScopeInfo::ParameterName(int var) {
|
| - DCHECK_LE(0, var);
|
| - DCHECK_LT(var, ParameterCount());
|
| - int info_index = ParameterNamesIndex() + var;
|
| - return String::cast(get(info_index));
|
| -}
|
| -
|
| -
|
| -String* ScopeInfo::LocalName(int var) {
|
| - DCHECK_LE(0, var);
|
| - DCHECK_LT(var, LocalCount());
|
| - DCHECK(StackLocalNamesIndex() + StackLocalCount() ==
|
| - ContextLocalNamesIndex());
|
| - int info_index = StackLocalNamesIndex() + var;
|
| - return String::cast(get(info_index));
|
| -}
|
| -
|
| -
|
| -String* ScopeInfo::StackLocalName(int var) {
|
| - DCHECK_LE(0, var);
|
| - DCHECK_LT(var, StackLocalCount());
|
| - int info_index = StackLocalNamesIndex() + var;
|
| - return String::cast(get(info_index));
|
| -}
|
| -
|
| -
|
| -int ScopeInfo::StackLocalIndex(int var) {
|
| - DCHECK_LE(0, var);
|
| - DCHECK_LT(var, StackLocalCount());
|
| - int first_slot_index = Smi::cast(get(StackLocalFirstSlotIndex()))->value();
|
| - return first_slot_index + var;
|
| -}
|
| -
|
| -
|
| -String* ScopeInfo::ContextLocalName(int var) {
|
| - DCHECK_LE(0, var);
|
| - DCHECK_LT(var, ContextLocalCount());
|
| - int info_index = ContextLocalNamesIndex() + var;
|
| - return String::cast(get(info_index));
|
| -}
|
| -
|
| -
|
| -VariableMode ScopeInfo::ContextLocalMode(int var) {
|
| - DCHECK_LE(0, var);
|
| - DCHECK_LT(var, ContextLocalCount());
|
| - int info_index = ContextLocalInfosIndex() + var;
|
| - int value = Smi::cast(get(info_index))->value();
|
| - return VariableModeField::decode(value);
|
| -}
|
| -
|
| -
|
| -InitializationFlag ScopeInfo::ContextLocalInitFlag(int var) {
|
| - DCHECK_LE(0, var);
|
| - DCHECK_LT(var, ContextLocalCount());
|
| - int info_index = ContextLocalInfosIndex() + var;
|
| - int value = Smi::cast(get(info_index))->value();
|
| - return InitFlagField::decode(value);
|
| -}
|
| -
|
| -
|
| -MaybeAssignedFlag ScopeInfo::ContextLocalMaybeAssignedFlag(int var) {
|
| - DCHECK_LE(0, var);
|
| - DCHECK_LT(var, ContextLocalCount());
|
| - int info_index = ContextLocalInfosIndex() + var;
|
| - int value = Smi::cast(get(info_index))->value();
|
| - return MaybeAssignedFlagField::decode(value);
|
| -}
|
| -
|
| -bool ScopeInfo::VariableIsSynthetic(String* name) {
|
| - // There's currently no flag stored on the ScopeInfo to indicate that a
|
| - // variable is a compiler-introduced temporary. However, to avoid conflict
|
| - // 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!
|
| - return name->length() == 0 || name->Get(0) == '.' ||
|
| - name->Equals(name->GetHeap()->this_string());
|
| -}
|
| -
|
| -
|
| -int ScopeInfo::StackSlotIndex(String* name) {
|
| - DCHECK(name->IsInternalizedString());
|
| - if (length() > 0) {
|
| - int first_slot_index = Smi::cast(get(StackLocalFirstSlotIndex()))->value();
|
| - int start = StackLocalNamesIndex();
|
| - int end = start + StackLocalCount();
|
| - for (int i = start; i < end; ++i) {
|
| - if (name == get(i)) {
|
| - return i - start + first_slot_index;
|
| - }
|
| - }
|
| - }
|
| - return -1;
|
| -}
|
| -
|
| -int ScopeInfo::ModuleIndex(Handle<String> name, VariableMode* mode,
|
| - InitializationFlag* init_flag,
|
| - MaybeAssignedFlag* maybe_assigned_flag) {
|
| - DCHECK_EQ(scope_type(), MODULE_SCOPE);
|
| - DCHECK(name->IsInternalizedString());
|
| - DCHECK_NOT_NULL(mode);
|
| - DCHECK_NOT_NULL(init_flag);
|
| - DCHECK_NOT_NULL(maybe_assigned_flag);
|
| -
|
| - int module_vars_count = Smi::cast(get(ModuleVariableCountIndex()))->value();
|
| - int entry = ModuleVariablesIndex();
|
| - for (int i = 0; i < module_vars_count; ++i) {
|
| - if (*name == get(entry + kModuleVariableNameOffset)) {
|
| - int index;
|
| - ModuleVariable(i, nullptr, &index, mode, init_flag, maybe_assigned_flag);
|
| - return index;
|
| - }
|
| - entry += kModuleVariableEntryLength;
|
| - }
|
| -
|
| - return 0;
|
| -}
|
| -
|
| -int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info,
|
| - Handle<String> name, VariableMode* mode,
|
| - InitializationFlag* init_flag,
|
| - MaybeAssignedFlag* maybe_assigned_flag) {
|
| - DCHECK(name->IsInternalizedString());
|
| - DCHECK_NOT_NULL(mode);
|
| - DCHECK_NOT_NULL(init_flag);
|
| - DCHECK_NOT_NULL(maybe_assigned_flag);
|
| -
|
| - if (scope_info->length() > 0) {
|
| - ContextSlotCache* context_slot_cache =
|
| - scope_info->GetIsolate()->context_slot_cache();
|
| - int result = context_slot_cache->Lookup(*scope_info, *name, mode, init_flag,
|
| - maybe_assigned_flag);
|
| - if (result != ContextSlotCache::kNotFound) {
|
| - DCHECK_LT(result, scope_info->ContextLength());
|
| - return result;
|
| - }
|
| -
|
| - int start = scope_info->ContextLocalNamesIndex();
|
| - int end = start + scope_info->ContextLocalCount();
|
| - for (int i = start; i < end; ++i) {
|
| - if (*name == scope_info->get(i)) {
|
| - int var = i - start;
|
| - *mode = scope_info->ContextLocalMode(var);
|
| - *init_flag = scope_info->ContextLocalInitFlag(var);
|
| - *maybe_assigned_flag = scope_info->ContextLocalMaybeAssignedFlag(var);
|
| - result = Context::MIN_CONTEXT_SLOTS + var;
|
| -
|
| - context_slot_cache->Update(scope_info, name, *mode, *init_flag,
|
| - *maybe_assigned_flag, result);
|
| - DCHECK_LT(result, scope_info->ContextLength());
|
| - return result;
|
| - }
|
| - }
|
| - // Cache as not found. Mode, init flag and maybe assigned flag don't matter.
|
| - context_slot_cache->Update(scope_info, name, TEMPORARY,
|
| - kNeedsInitialization, kNotAssigned, -1);
|
| - }
|
| -
|
| - return -1;
|
| -}
|
| -
|
| -String* ScopeInfo::ContextSlotName(int slot_index) {
|
| - int const var = slot_index - Context::MIN_CONTEXT_SLOTS;
|
| - DCHECK_LE(0, var);
|
| - DCHECK_LT(var, ContextLocalCount());
|
| - return ContextLocalName(var);
|
| -}
|
| -
|
| -
|
| -int ScopeInfo::ParameterIndex(String* name) {
|
| - DCHECK(name->IsInternalizedString());
|
| - if (length() > 0) {
|
| - // We must read parameters from the end since for
|
| - // multiply declared parameters the value of the
|
| - // last declaration of that parameter is used
|
| - // inside a function (and thus we need to look
|
| - // at the last index). Was bug# 1110337.
|
| - int start = ParameterNamesIndex();
|
| - int end = start + ParameterCount();
|
| - for (int i = end - 1; i >= start; --i) {
|
| - if (name == get(i)) {
|
| - return i - start;
|
| - }
|
| - }
|
| - }
|
| - return -1;
|
| -}
|
| -
|
| -
|
| -int ScopeInfo::ReceiverContextSlotIndex() {
|
| - if (length() > 0 && ReceiverVariableField::decode(Flags()) == CONTEXT)
|
| - return Smi::cast(get(ReceiverInfoIndex()))->value();
|
| - return -1;
|
| -}
|
| -
|
| -int ScopeInfo::FunctionContextSlotIndex(String* name) {
|
| - DCHECK(name->IsInternalizedString());
|
| - if (length() > 0) {
|
| - if (FunctionVariableField::decode(Flags()) == CONTEXT &&
|
| - FunctionName() == name) {
|
| - return Smi::cast(get(FunctionNameInfoIndex() + 1))->value();
|
| - }
|
| - }
|
| - return -1;
|
| -}
|
| -
|
| -
|
| -FunctionKind ScopeInfo::function_kind() {
|
| - return FunctionKindField::decode(Flags());
|
| -}
|
| -
|
| -int ScopeInfo::ParameterNamesIndex() {
|
| - DCHECK_LT(0, length());
|
| - return kVariablePartIndex;
|
| -}
|
| -
|
| -
|
| -int ScopeInfo::StackLocalFirstSlotIndex() {
|
| - return ParameterNamesIndex() + ParameterCount();
|
| -}
|
| -
|
| -int ScopeInfo::StackLocalNamesIndex() { return StackLocalFirstSlotIndex() + 1; }
|
| -
|
| -int ScopeInfo::ContextLocalNamesIndex() {
|
| - return StackLocalNamesIndex() + StackLocalCount();
|
| -}
|
| -
|
| -int ScopeInfo::ContextLocalInfosIndex() {
|
| - return ContextLocalNamesIndex() + ContextLocalCount();
|
| -}
|
| -
|
| -int ScopeInfo::ReceiverInfoIndex() {
|
| - return ContextLocalInfosIndex() + ContextLocalCount();
|
| -}
|
| -
|
| -int ScopeInfo::FunctionNameInfoIndex() {
|
| - return ReceiverInfoIndex() + (HasAllocatedReceiver() ? 1 : 0);
|
| -}
|
| -
|
| -int ScopeInfo::OuterScopeInfoIndex() {
|
| - return FunctionNameInfoIndex() + (HasFunctionName() ? 2 : 0);
|
| -}
|
| -
|
| -int ScopeInfo::ModuleInfoIndex() {
|
| - return OuterScopeInfoIndex() + (HasOuterScopeInfo() ? 1 : 0);
|
| -}
|
| -
|
| -int ScopeInfo::ModuleVariableCountIndex() { return ModuleInfoIndex() + 1; }
|
| -
|
| -int ScopeInfo::ModuleVariablesIndex() { return ModuleVariableCountIndex() + 1; }
|
| -
|
| -void ScopeInfo::ModuleVariable(int i, String** name, int* index,
|
| - VariableMode* mode,
|
| - InitializationFlag* init_flag,
|
| - MaybeAssignedFlag* maybe_assigned_flag) {
|
| - DCHECK_LE(0, i);
|
| - DCHECK_LT(i, Smi::cast(get(ModuleVariableCountIndex()))->value());
|
| -
|
| - int entry = ModuleVariablesIndex() + i * kModuleVariableEntryLength;
|
| - int properties =
|
| - Smi::cast(get(entry + kModuleVariablePropertiesOffset))->value();
|
| -
|
| - if (name != nullptr) {
|
| - *name = String::cast(get(entry + kModuleVariableNameOffset));
|
| - }
|
| - if (index != nullptr) {
|
| - *index = Smi::cast(get(entry + kModuleVariableIndexOffset))->value();
|
| - DCHECK_NE(*index, 0);
|
| - }
|
| - if (mode != nullptr) {
|
| - *mode = VariableModeField::decode(properties);
|
| - }
|
| - if (init_flag != nullptr) {
|
| - *init_flag = InitFlagField::decode(properties);
|
| - }
|
| - if (maybe_assigned_flag != nullptr) {
|
| - *maybe_assigned_flag = MaybeAssignedFlagField::decode(properties);
|
| - }
|
| -}
|
| -
|
| -#ifdef DEBUG
|
| -
|
| -static void PrintList(const char* list_name,
|
| - int nof_internal_slots,
|
| - int start,
|
| - int end,
|
| - ScopeInfo* scope_info) {
|
| - if (start < end) {
|
| - PrintF("\n // %s\n", list_name);
|
| - if (nof_internal_slots > 0) {
|
| - PrintF(" %2d - %2d [internal slots]\n", 0 , nof_internal_slots - 1);
|
| - }
|
| - for (int i = nof_internal_slots; start < end; ++i, ++start) {
|
| - PrintF(" %2d ", i);
|
| - String::cast(scope_info->get(start))->ShortPrint();
|
| - PrintF("\n");
|
| - }
|
| - }
|
| -}
|
| -
|
| -
|
| -void ScopeInfo::Print() {
|
| - PrintF("ScopeInfo ");
|
| - if (HasFunctionName()) {
|
| - FunctionName()->ShortPrint();
|
| - } else {
|
| - PrintF("/* no function name */");
|
| - }
|
| - PrintF("{");
|
| -
|
| - if (length() > 0) {
|
| - PrintList("parameters", 0, ParameterNamesIndex(),
|
| - ParameterNamesIndex() + ParameterCount(), this);
|
| - PrintList("stack slots", 0, StackLocalNamesIndex(),
|
| - StackLocalNamesIndex() + StackLocalCount(), this);
|
| - PrintList("context slots", Context::MIN_CONTEXT_SLOTS,
|
| - ContextLocalNamesIndex(),
|
| - ContextLocalNamesIndex() + ContextLocalCount(), this);
|
| - // TODO(neis): Print module stuff if present.
|
| - }
|
| -
|
| - PrintF("}\n");
|
| -}
|
| -#endif // DEBUG
|
| -
|
| -Handle<ModuleInfoEntry> ModuleInfoEntry::New(Isolate* isolate,
|
| - Handle<Object> export_name,
|
| - Handle<Object> local_name,
|
| - Handle<Object> import_name,
|
| - int module_request, int cell_index,
|
| - int beg_pos, int end_pos) {
|
| - Handle<ModuleInfoEntry> result = Handle<ModuleInfoEntry>::cast(
|
| - isolate->factory()->NewStruct(MODULE_INFO_ENTRY_TYPE));
|
| - result->set_export_name(*export_name);
|
| - result->set_local_name(*local_name);
|
| - result->set_import_name(*import_name);
|
| - result->set_module_request(module_request);
|
| - result->set_cell_index(cell_index);
|
| - result->set_beg_pos(beg_pos);
|
| - result->set_end_pos(end_pos);
|
| - return result;
|
| -}
|
| -
|
| -Handle<ModuleInfo> ModuleInfo::New(Isolate* isolate, Zone* zone,
|
| - ModuleDescriptor* descr) {
|
| - // Serialize module requests.
|
| - Handle<FixedArray> module_requests = isolate->factory()->NewFixedArray(
|
| - static_cast<int>(descr->module_requests().size()));
|
| - for (const auto& elem : descr->module_requests()) {
|
| - module_requests->set(elem.second, *elem.first->string());
|
| - }
|
| -
|
| - // Serialize special exports.
|
| - Handle<FixedArray> special_exports =
|
| - isolate->factory()->NewFixedArray(descr->special_exports().length());
|
| - {
|
| - int i = 0;
|
| - for (auto entry : descr->special_exports()) {
|
| - Handle<ModuleInfoEntry> serialized_entry = entry->Serialize(isolate);
|
| - special_exports->set(i++, *serialized_entry);
|
| - }
|
| - }
|
| -
|
| - // Serialize namespace imports.
|
| - Handle<FixedArray> namespace_imports =
|
| - isolate->factory()->NewFixedArray(descr->namespace_imports().length());
|
| - {
|
| - int i = 0;
|
| - for (auto entry : descr->namespace_imports()) {
|
| - Handle<ModuleInfoEntry> serialized_entry = entry->Serialize(isolate);
|
| - namespace_imports->set(i++, *serialized_entry);
|
| - }
|
| - }
|
| -
|
| - // Serialize regular exports.
|
| - Handle<FixedArray> regular_exports =
|
| - descr->SerializeRegularExports(isolate, zone);
|
| -
|
| - // Serialize regular imports.
|
| - Handle<FixedArray> regular_imports = isolate->factory()->NewFixedArray(
|
| - static_cast<int>(descr->regular_imports().size()));
|
| - {
|
| - int i = 0;
|
| - for (const auto& elem : descr->regular_imports()) {
|
| - Handle<ModuleInfoEntry> serialized_entry =
|
| - elem.second->Serialize(isolate);
|
| - regular_imports->set(i++, *serialized_entry);
|
| - }
|
| - }
|
| -
|
| - Handle<ModuleInfo> result = isolate->factory()->NewModuleInfo();
|
| - result->set(kModuleRequestsIndex, *module_requests);
|
| - result->set(kSpecialExportsIndex, *special_exports);
|
| - result->set(kRegularExportsIndex, *regular_exports);
|
| - result->set(kNamespaceImportsIndex, *namespace_imports);
|
| - result->set(kRegularImportsIndex, *regular_imports);
|
| - return result;
|
| -}
|
| -
|
| -int ModuleInfo::RegularExportCount() const {
|
| - DCHECK_EQ(regular_exports()->length() % kRegularExportLength, 0);
|
| - return regular_exports()->length() / kRegularExportLength;
|
| -}
|
| -
|
| -String* ModuleInfo::RegularExportLocalName(int i) const {
|
| - return String::cast(regular_exports()->get(i * kRegularExportLength +
|
| - kRegularExportLocalNameOffset));
|
| -}
|
| -
|
| -int ModuleInfo::RegularExportCellIndex(int i) const {
|
| - return Smi::cast(regular_exports()->get(i * kRegularExportLength +
|
| - kRegularExportCellIndexOffset))
|
| - ->value();
|
| -}
|
| -
|
| -FixedArray* ModuleInfo::RegularExportExportNames(int i) const {
|
| - return FixedArray::cast(regular_exports()->get(
|
| - i * kRegularExportLength + kRegularExportExportNamesOffset));
|
| -}
|
| -
|
| -Handle<ModuleInfoEntry> ModuleInfo::LookupRegularImport(
|
| - Handle<ModuleInfo> info, Handle<String> local_name) {
|
| - Isolate* isolate = info->GetIsolate();
|
| - Handle<FixedArray> regular_imports(info->regular_imports(), isolate);
|
| - for (int i = 0, n = regular_imports->length(); i < n; ++i) {
|
| - Handle<ModuleInfoEntry> entry(
|
| - ModuleInfoEntry::cast(regular_imports->get(i)), isolate);
|
| - if (String::cast(entry->local_name())->Equals(*local_name)) {
|
| - return entry;
|
| - }
|
| - }
|
| - UNREACHABLE();
|
| - return Handle<ModuleInfoEntry>();
|
| -}
|
| -
|
| -} // namespace internal
|
| -} // namespace v8
|
|
|