Commit e093ad73 authored by Marja Hölttä's avatar Marja Hölttä Committed by Commit Bot

[parser] Skipping inner functions: fix recording eval calls.

(The test that catches the bug was test-bytecode-generator/LookupSlot)

BUG=v8:5516

Change-Id: I00a02c5326b2a132383a9d72b5b894fade53bbf2
Reviewed-on: https://chromium-review.googlesource.com/558864
Commit-Queue: Marja Hölttä <marja@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46374}
parent d92628de
......@@ -264,9 +264,16 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
// eval call.
void RecordEvalCall() {
scope_calls_eval_ = true;
RecordInnerScopeEvalCall();
}
void RecordInnerScopeEvalCall() {
inner_scope_calls_eval_ = true;
for (Scope* scope = outer_scope(); scope != nullptr;
scope = scope->outer_scope()) {
if (scope->inner_scope_calls_eval_) {
return;
}
scope->inner_scope_calls_eval_ = true;
}
}
......
......@@ -16,6 +16,10 @@ namespace internal {
namespace {
class ScopeCallsEvalField : public BitField<bool, 0, 1> {};
class InnerScopeCallsEvalField
: public BitField<bool, ScopeCallsEvalField::kNext, 1> {};
class VariableIsUsedField : public BitField16<bool, 0, 1> {};
class VariableMaybeAssignedField
: public BitField16<bool, VariableIsUsedField::kNext, 1> {};
......@@ -58,7 +62,7 @@ class UsesSuperField : public BitField<bool, LanguageField::kNext, 1> {};
scope positions
------------------------------------
| scope type << only in debug |
| inner_scope_calls_eval_ |
| eval |
| ---------------------- |
| | data for variables | |
| | ... | |
......@@ -289,7 +293,11 @@ void ProducedPreParsedScopeData::SaveDataForScope(Scope* scope) {
#ifdef DEBUG
backing_store_.push_back(scope->scope_type());
#endif
backing_store_.push_back(scope->inner_scope_calls_eval());
uint32_t eval =
ScopeCallsEvalField::encode(scope->calls_eval()) |
InnerScopeCallsEvalField::encode(scope->inner_scope_calls_eval());
backing_store_.push_back(eval);
if (scope->scope_type() == ScopeType::FUNCTION_SCOPE) {
Variable* function = scope->AsDeclarationScope()->function_var();
......@@ -369,7 +377,7 @@ ConsumedPreParsedScopeData::GetDataForSkippableFunction(
// The skippable function *must* be the next function in the data. Use the
// start position as a sanity check.
CHECK_GE(scope_data->length(), index_ + 5);
CHECK_GE(scope_data->length(), index_ + SkippableFunctionDataOffsets::kSize);
int start_position_from_data =
scope_data->get(index_ + SkippableFunctionDataOffsets::kStartPosition);
CHECK_EQ(start_position, start_position_from_data);
......@@ -454,9 +462,13 @@ void ConsumedPreParsedScopeData::RestoreData(Scope* scope,
DCHECK_GE(scope_data->length(), index_ + 2);
DCHECK_EQ(scope_data->get(index_++), scope->scope_type());
if (scope_data->get(index_++)) {
uint32_t eval = scope_data->get(index_++);
if (ScopeCallsEvalField::decode(eval)) {
scope->RecordEvalCall();
}
if (InnerScopeCallsEvalField::decode(eval)) {
scope->RecordInnerScopeEvalCall();
}
if (scope->scope_type() == ScopeType::FUNCTION_SCOPE) {
Variable* function = scope->AsDeclarationScope()->function_var();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment