aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/ast/scopeinfo.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/ast/scopeinfo.cc')
-rw-r--r--deps/v8/src/ast/scopeinfo.cc666
1 files changed, 435 insertions, 231 deletions
diff --git a/deps/v8/src/ast/scopeinfo.cc b/deps/v8/src/ast/scopeinfo.cc
index 7189de3372..5354b8d737 100644
--- a/deps/v8/src/ast/scopeinfo.cc
+++ b/deps/v8/src/ast/scopeinfo.cc
@@ -2,33 +2,92 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "src/ast/scopeinfo.h"
-
#include <stdlib.h>
#include "src/ast/context-slot-cache.h"
#include "src/ast/scopes.h"
+#include "src/ast/variables.h"
#include "src/bootstrapper.h"
namespace v8 {
namespace internal {
+// An entry in ModuleVariableEntries consists of several slots:
+enum ModuleVariableEntryOffset {
+ kModuleVariableNameOffset,
+ kModuleVariableIndexOffset,
+ kModuleVariablePropertiesOffset,
+ kModuleVariableEntryLength // Sentinel value.
+};
-Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
- Scope* scope) {
- // Collect stack and context locals.
- ZoneList<Variable*> stack_locals(scope->StackLocalCount(), zone);
- ZoneList<Variable*> context_locals(scope->ContextLocalCount(), zone);
- ZoneList<Variable*> context_globals(scope->ContextGlobalCount(), zone);
+#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.
+ ZoneList<Variable*>* locals = scope->locals();
+ 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 (int i = 0; i < locals->length(); i++) {
+ Variable* var = locals->at(i);
+ 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());
- scope->CollectStackAndContextLocals(&stack_locals, &context_locals,
- &context_globals);
- const int stack_local_count = stack_locals.length();
- const int context_local_count = context_locals.length();
- const int context_global_count = context_globals.length();
// Make sure we allocate the correct amount.
DCHECK_EQ(scope->ContextLocalCount(), context_local_count);
- DCHECK_EQ(scope->ContextGlobalCount(), context_global_count);
// Determine use and location of the "this" binding if it is present.
VariableAllocationInfo receiver_info;
@@ -53,7 +112,6 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
// Determine use and location of the function variable if it is present.
VariableAllocationInfo function_name_info;
- VariableMode function_variable_mode;
if (scope->is_function_scope() &&
scope->AsDeclarationScope()->function_var() != nullptr) {
Variable* var = scope->AsDeclarationScope()->function_var();
@@ -65,20 +123,21 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
DCHECK(var->IsStackLocal());
function_name_info = STACK;
}
- function_variable_mode = var->mode();
} else {
function_name_info = NONE;
- function_variable_mode = VAR;
}
- DCHECK(context_global_count == 0 || scope->scope_type() == SCRIPT_SCOPE);
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 +
- 2 * context_global_count +
- (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0);
+ (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);
@@ -96,27 +155,29 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
}
// 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) |
- FunctionVariableMode::encode(function_variable_mode) |
- AsmModuleField::encode(asm_module) |
- AsmFunctionField::encode(asm_function) |
- HasSimpleParametersField::encode(has_simple_parameters) |
- FunctionKindField::encode(function_kind);
+ 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);
- scope_info->SetContextGlobalCount(context_global_count);
int index = kVariablePartIndex;
// Add parameters.
- DCHECK(index == scope_info->ParameterEntriesIndex());
+ DCHECK_EQ(index, scope_info->ParameterNamesIndex());
if (scope->is_declaration_scope()) {
for (int i = 0; i < parameter_count; ++i) {
scope_info->set(index++,
@@ -124,68 +185,66 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
}
}
- // Add stack locals' names. We are assuming that the stack locals'
- // slots are allocated in increasing order, so we can simply add
- // them to the ScopeInfo object.
- int first_slot_index;
- if (stack_local_count > 0) {
- first_slot_index = stack_locals[0]->index();
- } else {
- first_slot_index = 0;
- }
- DCHECK(index == scope_info->StackLocalFirstSlotIndex());
+ // 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(index == scope_info->StackLocalEntriesIndex());
- for (int i = 0; i < stack_local_count; ++i) {
- DCHECK(stack_locals[i]->index() == first_slot_index + i);
- scope_info->set(index++, *stack_locals[i]->name());
- }
-
- // Due to usage analysis, context-allocated locals are not necessarily in
- // increasing order: Some of them may be parameters which are allocated before
- // the non-parameter locals. When the non-parameter locals are sorted
- // according to usage, the allocated slot indices may not be in increasing
- // order with the variable list anymore. Thus, we first need to sort them by
- // context slot index before adding them to the ScopeInfo object.
- context_locals.Sort(&Variable::CompareIndex);
-
- // Add context locals' names.
- DCHECK(index == scope_info->ContextLocalNameEntriesIndex());
- for (int i = 0; i < context_local_count; ++i) {
- scope_info->set(index++, *context_locals[i]->name());
- }
-
- // Add context globals' names.
- DCHECK(index == scope_info->ContextGlobalNameEntriesIndex());
- for (int i = 0; i < context_global_count; ++i) {
- scope_info->set(index++, *context_globals[i]->name());
- }
-
- // Add context locals' info.
- DCHECK(index == scope_info->ContextLocalInfoEntriesIndex());
- for (int i = 0; i < context_local_count; ++i) {
- Variable* var = context_locals[i];
- uint32_t value =
- ContextLocalMode::encode(var->mode()) |
- ContextLocalInitFlag::encode(var->initialization_flag()) |
- ContextLocalMaybeAssignedFlag::encode(var->maybe_assigned());
- scope_info->set(index++, Smi::FromInt(value));
- }
-
- // Add context globals' info.
- DCHECK(index == scope_info->ContextGlobalInfoEntriesIndex());
- for (int i = 0; i < context_global_count; ++i) {
- Variable* var = context_globals[i];
- // TODO(ishell): do we need this kind of info for globals here?
- uint32_t value =
- ContextLocalMode::encode(var->mode()) |
- ContextLocalInitFlag::encode(var->initialization_flag()) |
- ContextLocalMaybeAssignedFlag::encode(var->maybe_assigned());
- scope_info->set(index++, Smi::FromInt(value));
+ 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 (int i = 0; i < locals->length(); ++i) {
+ Variable* var = locals->at(i);
+ 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(index == scope_info->ReceiverEntryIndex());
+ DCHECK_EQ(index, scope_info->ReceiverInfoIndex());
if (has_receiver) {
int var_index = scope->AsDeclarationScope()->receiver()->index();
scope_info->set(index++, Smi::FromInt(var_index));
@@ -194,7 +253,7 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
}
// If present, add the function variable name and its index.
- DCHECK(index == scope_info->FunctionNameEntryIndex());
+ DCHECK_EQ(index, scope_info->FunctionNameInfoIndex());
if (has_function_name) {
int var_index = scope->AsDeclarationScope()->function_var()->index();
scope_info->set(index++,
@@ -204,75 +263,130 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
var_index == scope_info->ContextLength() - 1);
}
- DCHECK(index == scope_info->length());
- DCHECK(scope->num_parameters() == scope_info->ParameterCount());
- DCHECK(scope->num_heap_slots() == scope_info->ContextLength() ||
- (scope->num_heap_slots() == kVariablePartIndex &&
- scope_info->ContextLength() == 0));
+ // 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::FromInt(0));
+ 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 int context_global_count = 0;
const bool has_simple_parameters = true;
const VariableAllocationInfo receiver_info = CONTEXT;
const VariableAllocationInfo function_name_info = NONE;
- const VariableMode function_variable_mode = VAR;
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 +
- 2 * context_global_count +
- (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0);
+ (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) |
- FunctionVariableMode::encode(function_variable_mode) |
- AsmModuleField::encode(false) | AsmFunctionField::encode(false) |
- HasSimpleParametersField::encode(has_simple_parameters) |
- FunctionKindField::encode(FunctionKind::kNormalFunction);
+ 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);
- scope_info->SetContextGlobalCount(context_global_count);
int index = kVariablePartIndex;
const int first_slot_index = 0;
- DCHECK(index == scope_info->StackLocalFirstSlotIndex());
+ DCHECK_EQ(index, scope_info->StackLocalFirstSlotIndex());
scope_info->set(index++, Smi::FromInt(first_slot_index));
- DCHECK(index == scope_info->StackLocalEntriesIndex());
+ DCHECK_EQ(index, scope_info->StackLocalNamesIndex());
// Here we add info for context-allocated "this".
- DCHECK(index == scope_info->ContextLocalNameEntriesIndex());
+ DCHECK_EQ(index, scope_info->ContextLocalNamesIndex());
scope_info->set(index++, *isolate->factory()->this_string());
- DCHECK(index == scope_info->ContextLocalInfoEntriesIndex());
- const uint32_t value = ContextLocalMode::encode(CONST) |
- ContextLocalInitFlag::encode(kCreatedInitialized) |
- ContextLocalMaybeAssignedFlag::encode(kNotAssigned);
+ 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(index == scope_info->ReceiverEntryIndex());
+ DCHECK_EQ(index, scope_info->ReceiverInfoIndex());
const int receiver_index = Context::MIN_CONTEXT_SLOTS + 0;
scope_info->set(index++, Smi::FromInt(receiver_index));
- DCHECK(index == scope_info->FunctionNameEntryIndex());
-
+ 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);
@@ -282,12 +396,12 @@ Handle<ScopeInfo> ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) {
ScopeInfo* ScopeInfo::Empty(Isolate* isolate) {
- return reinterpret_cast<ScopeInfo*>(isolate->heap()->empty_fixed_array());
+ return isolate->heap()->empty_scope_info();
}
ScopeType ScopeInfo::scope_type() {
- DCHECK(length() > 0);
+ DCHECK_LT(0, length());
return ScopeTypeField::decode(Flags());
}
@@ -325,19 +439,17 @@ int ScopeInfo::StackSlotCount() {
int ScopeInfo::ContextLength() {
if (length() > 0) {
int context_locals = ContextLocalCount();
- int context_globals = ContextGlobalCount();
bool function_name_context_slot =
FunctionVariableField::decode(Flags()) == CONTEXT;
- bool has_context = context_locals > 0 || context_globals > 0 ||
- function_name_context_slot ||
+ bool has_context = context_locals > 0 || function_name_context_slot ||
scope_type() == WITH_SCOPE ||
(scope_type() == BLOCK_SCOPE && CallsSloppyEval() &&
- is_declaration_scope()) ||
+ is_declaration_scope()) ||
(scope_type() == FUNCTION_SCOPE && CallsSloppyEval()) ||
scope_type() == MODULE_SCOPE;
if (has_context) {
- return Context::MIN_CONTEXT_SLOTS + context_locals + context_globals +
+ return Context::MIN_CONTEXT_SLOTS + context_locals +
(function_name_context_slot ? 1 : 0);
}
}
@@ -375,6 +487,30 @@ bool ScopeInfo::HasFunctionName() {
}
}
+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) {
@@ -392,68 +528,85 @@ bool ScopeInfo::HasContext() {
String* ScopeInfo::FunctionName() {
DCHECK(HasFunctionName());
- return String::cast(get(FunctionNameEntryIndex()));
+ 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(0 <= var && var < ParameterCount());
- int info_index = ParameterEntriesIndex() + 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(0 <= var && var < LocalCount());
- DCHECK(StackLocalEntriesIndex() + StackLocalCount() ==
- ContextLocalNameEntriesIndex());
- int info_index = StackLocalEntriesIndex() + 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(0 <= var && var < StackLocalCount());
- int info_index = StackLocalEntriesIndex() + 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(0 <= var && var < StackLocalCount());
+ 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(0 <= var && var < ContextLocalCount() + ContextGlobalCount());
- int info_index = ContextLocalNameEntriesIndex() + 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(0 <= var && var < ContextLocalCount() + ContextGlobalCount());
- int info_index = ContextLocalInfoEntriesIndex() + var;
+ DCHECK_LE(0, var);
+ DCHECK_LT(var, ContextLocalCount());
+ int info_index = ContextLocalInfosIndex() + var;
int value = Smi::cast(get(info_index))->value();
- return ContextLocalMode::decode(value);
+ return VariableModeField::decode(value);
}
InitializationFlag ScopeInfo::ContextLocalInitFlag(int var) {
- DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount());
- int info_index = ContextLocalInfoEntriesIndex() + var;
+ DCHECK_LE(0, var);
+ DCHECK_LT(var, ContextLocalCount());
+ int info_index = ContextLocalInfosIndex() + var;
int value = Smi::cast(get(info_index))->value();
- return ContextLocalInitFlag::decode(value);
+ return InitFlagField::decode(value);
}
MaybeAssignedFlag ScopeInfo::ContextLocalMaybeAssignedFlag(int var) {
- DCHECK(0 <= var && var < ContextLocalCount() + ContextGlobalCount());
- int info_index = ContextLocalInfoEntriesIndex() + var;
+ DCHECK_LE(0, var);
+ DCHECK_LT(var, ContextLocalCount());
+ int info_index = ContextLocalInfosIndex() + var;
int value = Smi::cast(get(info_index))->value();
- return ContextLocalMaybeAssignedFlag::decode(value);
+ return MaybeAssignedFlagField::decode(value);
}
bool ScopeInfo::VariableIsSynthetic(String* name) {
@@ -470,8 +623,8 @@ int ScopeInfo::StackSlotIndex(String* name) {
DCHECK(name->IsInternalizedString());
if (length() > 0) {
int first_slot_index = Smi::cast(get(StackLocalFirstSlotIndex()))->value();
- int start = StackLocalEntriesIndex();
- int end = StackLocalEntriesIndex() + StackLocalCount();
+ int start = StackLocalNamesIndex();
+ int end = start + StackLocalCount();
for (int i = start; i < end; ++i) {
if (name == get(i)) {
return i - start + first_slot_index;
@@ -481,27 +634,54 @@ int ScopeInfo::StackSlotIndex(String* name) {
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 = Smi::cast(get(entry + kModuleVariableIndexOffset))->value();
+ int properties =
+ Smi::cast(get(entry + kModuleVariablePropertiesOffset))->value();
+ *mode = VariableModeField::decode(properties);
+ *init_flag = InitFlagField::decode(properties);
+ *maybe_assigned_flag = MaybeAssignedFlagField::decode(properties);
+ return index;
+ }
+ entry += kModuleVariableEntryLength;
+ }
+
+ return -1;
+}
int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info,
Handle<String> name, VariableMode* mode,
InitializationFlag* init_flag,
MaybeAssignedFlag* maybe_assigned_flag) {
DCHECK(name->IsInternalizedString());
- DCHECK(mode != NULL);
- DCHECK(init_flag != NULL);
+ 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(result < scope_info->ContextLength());
+ DCHECK_LT(result, scope_info->ContextLength());
return result;
}
- int start = scope_info->ContextLocalNameEntriesIndex();
- int end = scope_info->ContextLocalNameEntriesIndex() +
- scope_info->ContextLocalCount();
+ 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;
@@ -512,7 +692,7 @@ int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info,
context_slot_cache->Update(scope_info, name, *mode, *init_flag,
*maybe_assigned_flag, result);
- DCHECK(result < scope_info->ContextLength());
+ DCHECK_LT(result, scope_info->ContextLength());
return result;
}
}
@@ -520,46 +700,14 @@ int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info,
context_slot_cache->Update(scope_info, name, TEMPORARY,
kNeedsInitialization, kNotAssigned, -1);
}
- return -1;
-}
-
-int ScopeInfo::ContextGlobalSlotIndex(Handle<ScopeInfo> scope_info,
- Handle<String> name, VariableMode* mode,
- InitializationFlag* init_flag,
- MaybeAssignedFlag* maybe_assigned_flag) {
- DCHECK(name->IsInternalizedString());
- DCHECK(mode != NULL);
- DCHECK(init_flag != NULL);
- if (scope_info->length() > 0) {
- // This is to ensure that ContextLocalMode() and co. queries would work.
- DCHECK_EQ(scope_info->ContextGlobalNameEntriesIndex(),
- scope_info->ContextLocalNameEntriesIndex() +
- scope_info->ContextLocalCount());
- int base = scope_info->ContextLocalNameEntriesIndex();
- int start = scope_info->ContextGlobalNameEntriesIndex();
- int end = scope_info->ContextGlobalNameEntriesIndex() +
- scope_info->ContextGlobalCount();
- for (int i = start; i < end; ++i) {
- if (*name == scope_info->get(i)) {
- int var = i - base;
- *mode = scope_info->ContextLocalMode(var);
- *init_flag = scope_info->ContextLocalInitFlag(var);
- *maybe_assigned_flag = scope_info->ContextLocalMaybeAssignedFlag(var);
- int result = Context::MIN_CONTEXT_SLOTS + var;
- DCHECK(result < scope_info->ContextLength());
- return result;
- }
- }
- }
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() + ContextGlobalCount());
+ DCHECK_LT(var, ContextLocalCount());
return ContextLocalName(var);
}
@@ -572,8 +720,8 @@ int ScopeInfo::ParameterIndex(String* name) {
// 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 = ParameterEntriesIndex();
- int end = ParameterEntriesIndex() + ParameterCount();
+ int start = ParameterNamesIndex();
+ int end = start + ParameterCount();
for (int i = end - 1; i >= start; --i) {
if (name == get(i)) {
return i - start;
@@ -586,19 +734,16 @@ int ScopeInfo::ParameterIndex(String* name) {
int ScopeInfo::ReceiverContextSlotIndex() {
if (length() > 0 && ReceiverVariableField::decode(Flags()) == CONTEXT)
- return Smi::cast(get(ReceiverEntryIndex()))->value();
+ return Smi::cast(get(ReceiverInfoIndex()))->value();
return -1;
}
-
-int ScopeInfo::FunctionContextSlotIndex(String* name, VariableMode* mode) {
+int ScopeInfo::FunctionContextSlotIndex(String* name) {
DCHECK(name->IsInternalizedString());
- DCHECK(mode != NULL);
if (length() > 0) {
if (FunctionVariableField::decode(Flags()) == CONTEXT &&
FunctionName() == name) {
- *mode = FunctionVariableMode::decode(Flags());
- return Smi::cast(get(FunctionNameEntryIndex() + 1))->value();
+ return Smi::cast(get(FunctionNameInfoIndex() + 1))->value();
}
}
return -1;
@@ -609,51 +754,45 @@ FunctionKind ScopeInfo::function_kind() {
return FunctionKindField::decode(Flags());
}
-
-int ScopeInfo::ParameterEntriesIndex() {
- DCHECK(length() > 0);
+int ScopeInfo::ParameterNamesIndex() {
+ DCHECK_LT(0, length());
return kVariablePartIndex;
}
int ScopeInfo::StackLocalFirstSlotIndex() {
- return ParameterEntriesIndex() + ParameterCount();
+ return ParameterNamesIndex() + ParameterCount();
}
+int ScopeInfo::StackLocalNamesIndex() { return StackLocalFirstSlotIndex() + 1; }
-int ScopeInfo::StackLocalEntriesIndex() {
- return StackLocalFirstSlotIndex() + 1;
+int ScopeInfo::ContextLocalNamesIndex() {
+ return StackLocalNamesIndex() + StackLocalCount();
}
-
-int ScopeInfo::ContextLocalNameEntriesIndex() {
- return StackLocalEntriesIndex() + StackLocalCount();
+int ScopeInfo::ContextLocalInfosIndex() {
+ return ContextLocalNamesIndex() + ContextLocalCount();
}
-
-int ScopeInfo::ContextGlobalNameEntriesIndex() {
- return ContextLocalNameEntriesIndex() + ContextLocalCount();
+int ScopeInfo::ReceiverInfoIndex() {
+ return ContextLocalInfosIndex() + ContextLocalCount();
}
-
-int ScopeInfo::ContextLocalInfoEntriesIndex() {
- return ContextGlobalNameEntriesIndex() + ContextGlobalCount();
+int ScopeInfo::FunctionNameInfoIndex() {
+ return ReceiverInfoIndex() + (HasAllocatedReceiver() ? 1 : 0);
}
-
-int ScopeInfo::ContextGlobalInfoEntriesIndex() {
- return ContextLocalInfoEntriesIndex() + ContextLocalCount();
+int ScopeInfo::OuterScopeInfoIndex() {
+ return FunctionNameInfoIndex() + (HasFunctionName() ? 2 : 0);
}
-
-int ScopeInfo::ReceiverEntryIndex() {
- return ContextGlobalInfoEntriesIndex() + ContextGlobalCount();
+int ScopeInfo::ModuleInfoIndex() {
+ return OuterScopeInfoIndex() + (HasOuterScopeInfo() ? 1 : 0);
}
+int ScopeInfo::ModuleVariableCountIndex() { return ModuleInfoIndex() + 1; }
-int ScopeInfo::FunctionNameEntryIndex() {
- return ReceiverEntryIndex() + (HasAllocatedReceiver() ? 1 : 0);
-}
+int ScopeInfo::ModuleVariablesIndex() { return ModuleVariableCountIndex() + 1; }
#ifdef DEBUG
@@ -686,19 +825,84 @@ void ScopeInfo::Print() {
PrintF("{");
if (length() > 0) {
- PrintList("parameters", 0, ParameterEntriesIndex(),
- ParameterEntriesIndex() + ParameterCount(), this);
- PrintList("stack slots", 0, StackLocalEntriesIndex(),
- StackLocalEntriesIndex() + StackLocalCount(), this);
+ PrintList("parameters", 0, ParameterNamesIndex(),
+ ParameterNamesIndex() + ParameterCount(), this);
+ PrintList("stack slots", 0, StackLocalNamesIndex(),
+ StackLocalNamesIndex() + StackLocalCount(), this);
PrintList("context slots", Context::MIN_CONTEXT_SLOTS,
- ContextLocalNameEntriesIndex(),
- ContextLocalNameEntriesIndex() + ContextLocalCount(), this);
+ 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,
+ Handle<Object> module_request) {
+ Handle<ModuleInfoEntry> result = isolate->factory()->NewModuleInfoEntry();
+ result->set(kExportNameIndex, *export_name);
+ result->set(kLocalNameIndex, *local_name);
+ result->set(kImportNameIndex, *import_name);
+ result->set(kModuleRequestIndex, *module_request);
+ 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()) {
+ special_exports->set(i++, *entry->Serialize(isolate));
+ }
+ }
+
+ // Serialize namespace imports.
+ Handle<FixedArray> namespace_imports =
+ isolate->factory()->NewFixedArray(descr->namespace_imports().length());
+ {
+ int i = 0;
+ for (auto entry : descr->namespace_imports()) {
+ namespace_imports->set(i++, *entry->Serialize(isolate));
+ }
+ }
+
+ // 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()) {
+ regular_imports->set(i++, *elem.second->Serialize(isolate));
+ }
+ }
+
+ 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;
+}
} // namespace internal
} // namespace v8