DCHECK(context->IsScriptContext());
Handle<ScopeInfo> scope_info(context->scope_info());
int slot_index = ScopeInfo::ContextSlotIndex(
- scope_info, name, &result->mode, &result->location, &result->init_flag,
+ scope_info, name, &result->mode, &result->init_flag,
&result->maybe_assigned_flag);
- if (slot_index >= 0 && result->location == VariableLocation::CONTEXT) {
+ if (slot_index >= 0) {
result->context_index = i;
result->slot_index = slot_index;
return true;
? context->closure()->shared()->scope_info()
: context->scope_info());
VariableMode mode;
- VariableLocation location;
InitializationFlag init_flag;
// TODO(sigurds) Figure out whether maybe_assigned_flag should
// be used to compute binding_flags.
MaybeAssignedFlag maybe_assigned_flag;
int slot_index = ScopeInfo::ContextSlotIndex(
- scope_info, name, &mode, &location, &init_flag, &maybe_assigned_flag);
+ scope_info, name, &mode, &init_flag, &maybe_assigned_flag);
DCHECK(slot_index < 0 || slot_index >= MIN_CONTEXT_SLOTS);
- if (slot_index >= 0 && location == VariableLocation::CONTEXT) {
+ if (slot_index >= 0) {
if (FLAG_trace_contexts) {
PrintF("=> found local in context slot %d (mode = %d)\n",
slot_index, mode);
int context_index;
int slot_index;
VariableMode mode;
- VariableLocation location;
InitializationFlag init_flag;
MaybeAssignedFlag maybe_assigned_flag;
};
switch (scope_info->scope_type()) {
case FUNCTION_SCOPE: {
VariableMode mode;
- VariableLocation location;
InitializationFlag init_flag;
MaybeAssignedFlag maybe_assigned_flag;
// Don't bother creating a fake context node if "this" is in the context
// already.
- if (ScopeInfo::ContextSlotIndex(
- scope_info, isolate_->factory()->this_string(), &mode, &location,
- &init_flag, &maybe_assigned_flag) >= 0) {
+ if (ScopeInfo::ContextSlotIndex(scope_info,
+ isolate_->factory()->this_string(), &mode,
+ &init_flag, &maybe_assigned_flag) >= 0) {
return target;
}
receiver = handle(frame_->receiver(), isolate_);
bool FrameInspector::ParameterIsShadowedByContextLocal(
Handle<ScopeInfo> info, Handle<String> parameter_name) {
VariableMode mode;
- VariableLocation location;
InitializationFlag init_flag;
MaybeAssignedFlag maybe_assigned_flag;
- return ScopeInfo::ContextSlotIndex(info, parameter_name, &mode, &location,
- &init_flag, &maybe_assigned_flag) != -1;
+ return ScopeInfo::ContextSlotIndex(info, parameter_name, &mode, &init_flag,
+ &maybe_assigned_flag) != -1;
}
Handle<String> next_name(scope_info->ContextLocalName(i));
if (String::Equals(variable_name, next_name)) {
VariableMode mode;
- VariableLocation location;
InitializationFlag init_flag;
MaybeAssignedFlag maybe_assigned_flag;
- int context_index =
- ScopeInfo::ContextSlotIndex(scope_info, next_name, &mode, &location,
- &init_flag, &maybe_assigned_flag);
+ int context_index = ScopeInfo::ContextSlotIndex(
+ scope_info, next_name, &mode, &init_flag, &maybe_assigned_flag);
context->set(context_index, *new_value);
return true;
}
// string.
int StackSlotIndex(String* name);
- // Lookup support for serialized scope info. Returns the
- // context slot index for a given slot name if the slot is present; otherwise
+ // Lookup support for serialized scope info. Returns the local context slot
+ // index for a given slot name if the slot is present; otherwise
// returns a value < 0. The name must be an internalized string.
// If the slot is present and mode != NULL, sets *mode to the corresponding
// mode for that variable.
static int ContextSlotIndex(Handle<ScopeInfo> scope_info, Handle<String> name,
- VariableMode* mode, VariableLocation* location,
- InitializationFlag* init_flag,
+ VariableMode* mode, InitializationFlag* init_flag,
MaybeAssignedFlag* maybe_assigned_flag);
+ // Similar to ContextSlotIndex() but this method searches only among
+ // global slots of the serialized scope info. Returns the context slot index
+ // for a given slot name if the slot is present; otherwise returns a
+ // value < 0. The name must be an internalized string. If the slot is present
+ // and mode != NULL, sets *mode to the corresponding mode for that variable.
+ static int ContextGlobalSlotIndex(Handle<ScopeInfo> scope_info,
+ Handle<String> name, VariableMode* mode,
+ InitializationFlag* init_flag,
+ MaybeAssignedFlag* maybe_assigned_flag);
+
// Lookup the name of a certain context slot by its index.
String* ContextSlotName(int slot_index);
if (scope_info->LocalIsSynthetic(i)) continue;
Handle<String> name(scope_info->LocalName(i));
VariableMode mode;
- VariableLocation location;
InitializationFlag init_flag;
MaybeAssignedFlag maybe_assigned_flag;
locals->set(local * 2, *name);
int context_slot_index = ScopeInfo::ContextSlotIndex(
- scope_info, name, &mode, &location, &init_flag, &maybe_assigned_flag);
- DCHECK(VariableLocation::CONTEXT == location);
+ scope_info, name, &mode, &init_flag, &maybe_assigned_flag);
Object* value = context->get(context_slot_index);
locals->set(local * 2 + 1, value);
local++;
int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info,
Handle<String> name, VariableMode* mode,
- VariableLocation* location,
InitializationFlag* init_flag,
MaybeAssignedFlag* maybe_assigned_flag) {
DCHECK(name->IsInternalizedString());
DCHECK(mode != NULL);
- DCHECK(location != NULL);
DCHECK(init_flag != NULL);
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, location,
- init_flag, maybe_assigned_flag);
+ int result = context_slot_cache->Lookup(*scope_info, *name, mode, init_flag,
+ maybe_assigned_flag);
if (result != ContextSlotCache::kNotFound) {
DCHECK(result < scope_info->ContextLength());
return result;
}
+ int start = scope_info->ContextLocalNameEntriesIndex();
+ int end = scope_info->ContextLocalNameEntriesIndex() +
+ 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(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;
+}
+
+
+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 start = scope_info->ContextLocalNameEntriesIndex();
+ 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 - start;
+ int var = i - base;
*mode = scope_info->ContextLocalMode(var);
*init_flag = scope_info->ContextLocalInitFlag(var);
*maybe_assigned_flag = scope_info->ContextLocalMaybeAssignedFlag(var);
-
- if (var < scope_info->ContextLocalCount()) {
- *location = VariableLocation::CONTEXT;
- result = Context::MIN_CONTEXT_SLOTS + var;
- } else {
- var -= scope_info->ContextLocalCount();
- *location = VariableLocation::GLOBAL;
- result = Context::MIN_CONTEXT_SLOTS +
- scope_info->ContextLocalCount() + var;
- }
-
- context_slot_cache->Update(scope_info, name, *mode, *location,
- *init_flag, *maybe_assigned_flag, result);
+ int result = Context::MIN_CONTEXT_SLOTS + var;
DCHECK(result < scope_info->ContextLength());
return result;
}
}
- // Cache as not found. Mode, location, init flag and maybe assigned flag
- // don't matter.
- context_slot_cache->Update(scope_info, name, TEMPORARY,
- VariableLocation::CONTEXT, kNeedsInitialization,
- kNotAssigned, -1);
}
return -1;
}
int ContextSlotCache::Lookup(Object* data, String* name, VariableMode* mode,
- VariableLocation* location,
InitializationFlag* init_flag,
MaybeAssignedFlag* maybe_assigned_flag) {
int index = Hash(data, name);
if ((key.data == data) && key.name->Equals(name)) {
Value result(values_[index]);
if (mode != NULL) *mode = result.mode();
- if (location != NULL) *location = result.location();
if (init_flag != NULL) *init_flag = result.initialization_flag();
if (maybe_assigned_flag != NULL)
*maybe_assigned_flag = result.maybe_assigned_flag();
void ContextSlotCache::Update(Handle<Object> data, Handle<String> name,
- VariableMode mode, VariableLocation location,
- InitializationFlag init_flag,
+ VariableMode mode, InitializationFlag init_flag,
MaybeAssignedFlag maybe_assigned_flag,
int slot_index) {
DisallowHeapAllocation no_gc;
key.data = *data;
key.name = *internalized_name;
// Please note value only takes a uint as index.
- values_[index] = Value(mode, location, init_flag, maybe_assigned_flag,
+ values_[index] = Value(mode, init_flag, maybe_assigned_flag,
slot_index - kNotFound).raw();
#ifdef DEBUG
- ValidateEntry(data, name, mode, location, init_flag, maybe_assigned_flag,
- slot_index);
+ ValidateEntry(data, name, mode, init_flag, maybe_assigned_flag, slot_index);
#endif
}
}
void ContextSlotCache::ValidateEntry(Handle<Object> data, Handle<String> name,
VariableMode mode,
- VariableLocation location,
InitializationFlag init_flag,
MaybeAssignedFlag maybe_assigned_flag,
int slot_index) {
DCHECK(key.name->Equals(*name));
Value result(values_[index]);
DCHECK(result.mode() == mode);
- DCHECK(result.location() == location);
DCHECK(result.initialization_flag() == init_flag);
DCHECK(result.maybe_assigned_flag() == maybe_assigned_flag);
DCHECK(result.index() + kNotFound == slot_index);
// Lookup context slot index for (data, name).
// If absent, kNotFound is returned.
int Lookup(Object* data, String* name, VariableMode* mode,
- VariableLocation* location, InitializationFlag* init_flag,
+ InitializationFlag* init_flag,
MaybeAssignedFlag* maybe_assigned_flag);
// Update an element in the cache.
void Update(Handle<Object> data, Handle<String> name, VariableMode mode,
- VariableLocation location, InitializationFlag init_flag,
+ InitializationFlag init_flag,
MaybeAssignedFlag maybe_assigned_flag, int slot_index);
// Clear the cache.
#ifdef DEBUG
void ValidateEntry(Handle<Object> data, Handle<String> name,
- VariableMode mode, VariableLocation location,
- InitializationFlag init_flag,
+ VariableMode mode, InitializationFlag init_flag,
MaybeAssignedFlag maybe_assigned_flag, int slot_index);
#endif
};
struct Value {
- enum VariableLocationFlag { kContext, kGlobal };
-
- Value(VariableMode mode, VariableLocation location,
- InitializationFlag init_flag, MaybeAssignedFlag maybe_assigned_flag,
- int index) {
- DCHECK(location == VariableLocation::CONTEXT ||
- location == VariableLocation::GLOBAL);
- VariableLocationFlag location_flag =
- location == VariableLocation::CONTEXT ? kContext : kGlobal;
+ Value(VariableMode mode, InitializationFlag init_flag,
+ MaybeAssignedFlag maybe_assigned_flag, int index) {
DCHECK(ModeField::is_valid(mode));
- DCHECK(VariableLocationField::is_valid(location_flag));
DCHECK(InitField::is_valid(init_flag));
DCHECK(MaybeAssignedField::is_valid(maybe_assigned_flag));
DCHECK(IndexField::is_valid(index));
value_ = ModeField::encode(mode) | IndexField::encode(index) |
- VariableLocationField::encode(location_flag) |
InitField::encode(init_flag) |
MaybeAssignedField::encode(maybe_assigned_flag);
DCHECK(mode == this->mode());
- DCHECK(location == this->location());
DCHECK(init_flag == this->initialization_flag());
DCHECK(maybe_assigned_flag == this->maybe_assigned_flag());
DCHECK(index == this->index());
VariableMode mode() { return ModeField::decode(value_); }
- VariableLocation location() {
- switch (VariableLocationField::decode(value_)) {
- case kContext:
- return VariableLocation::CONTEXT;
- case kGlobal:
- return VariableLocation::GLOBAL;
- }
- UNREACHABLE();
- return VariableLocation::CONTEXT;
- }
-
InitializationFlag initialization_flag() {
return InitField::decode(value_);
}
class ModeField : public BitField<VariableMode, 0, 4> {};
class InitField : public BitField<InitializationFlag, 4, 1> {};
class MaybeAssignedField : public BitField<MaybeAssignedFlag, 5, 1> {};
- class VariableLocationField : public BitField<VariableLocationFlag, 6, 1> {
- };
- class IndexField : public BitField<int, 7, 32 - 7> {};
+ class IndexField : public BitField<int, 6, 32 - 6> {};
private:
uint32_t value_;
// Check context slot lookup.
VariableMode mode;
- VariableLocation location;
+ VariableLocation location = VariableLocation::CONTEXT;
InitializationFlag init_flag;
MaybeAssignedFlag maybe_assigned_flag;
- int index =
- ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode, &location,
- &init_flag, &maybe_assigned_flag);
+ int index = ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode,
+ &init_flag, &maybe_assigned_flag);
+ if (index < 0) {
+ location = VariableLocation::GLOBAL;
+ index = ScopeInfo::ContextGlobalSlotIndex(scope_info_, name_handle, &mode,
+ &init_flag, &maybe_assigned_flag);
+ }
if (index < 0) {
// Check parameters.
index = scope_info_->ParameterIndex(*name_handle);