summaryrefslogtreecommitdiff
path: root/chromium/v8/src/debug/debug-scopes.cc
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-12 14:27:29 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-13 09:35:20 +0000
commitc30a6232df03e1efbd9f3b226777b07e087a1122 (patch)
treee992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/v8/src/debug/debug-scopes.cc
parent7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff)
downloadqtwebengine-chromium-85-based.tar.gz
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/v8/src/debug/debug-scopes.cc')
-rw-r--r--chromium/v8/src/debug/debug-scopes.cc96
1 files changed, 51 insertions, 45 deletions
diff --git a/chromium/v8/src/debug/debug-scopes.cc b/chromium/v8/src/debug/debug-scopes.cc
index 6b838a69af0..3afbcfd309e 100644
--- a/chromium/v8/src/debug/debug-scopes.cc
+++ b/chromium/v8/src/debug/debug-scopes.cc
@@ -269,8 +269,9 @@ void ScopeIterator::TryParseAndRetrieveScopes(ReparseStrategy strategy) {
const bool parse_result =
flags.is_toplevel()
? parsing::ParseProgram(info_.get(), script, maybe_outer_scope,
- isolate_)
- : parsing::ParseFunction(info_.get(), shared_info, isolate_);
+ isolate_, parsing::ReportStatisticsMode::kNo)
+ : parsing::ParseFunction(info_.get(), shared_info, isolate_,
+ parsing::ReportStatisticsMode::kNo);
if (parse_result) {
DeclarationScope* literal_scope = info_->literal()->scope();
@@ -300,14 +301,13 @@ void ScopeIterator::TryParseAndRetrieveScopes(ReparseStrategy strategy) {
UnwrapEvaluationContext();
} else {
// A failed reparse indicates that the preparser has diverged from the
- // parser or that the preparse data given to the initial parse has been
- // faulty. We fail in debug mode but in release mode we only provide the
- // information we get from the context chain but nothing about
- // completely stack allocated scopes or stack allocated locals.
- // Or it could be due to stack overflow.
+ // parser, that the preparse data given to the initial parse was faulty, or
+ // a stack overflow.
+ // TODO(leszeks): This error is pretty unexpected, so we could report the
+ // error in debug mode. Better to not fail in release though, in case it's
+ // just a stack overflow.
+
// Silently fail by presenting an empty context chain.
- CHECK(isolate_->has_pending_exception());
- isolate_->clear_pending_exception();
context_ = Handle<Context>();
}
}
@@ -373,7 +373,8 @@ bool ScopeIterator::DeclaresLocals(Mode mode) const {
if (type == ScopeTypeGlobal) return mode == Mode::ALL;
bool declares_local = false;
- auto visitor = [&](Handle<String> name, Handle<Object> value) {
+ auto visitor = [&](Handle<String> name, Handle<Object> value,
+ ScopeType scope_type) {
declares_local = true;
return true;
};
@@ -421,7 +422,7 @@ void ScopeIterator::AdvanceContext() {
// While advancing one context, we need to advance at least one
// scope, but until we hit the next scope that actually requires
// a context. All the locals collected along the way build the
- // blacklist for debug-evaluate for this context.
+ // blocklist for debug-evaluate for this context.
locals_ = StringSet::New(isolate_);
do {
if (!current_scope_ || !current_scope_->outer_scope()) break;
@@ -462,7 +463,7 @@ void ScopeIterator::Next() {
if (leaving_closure) {
DCHECK(current_scope_ != closure_scope_);
// Edge case when we just go past {closure_scope_}. This case
- // already needs to start collecting locals for the blacklist.
+ // already needs to start collecting locals for the blocklist.
locals_ = StringSet::New(isolate_);
CollectLocalsFromCurrentScope();
}
@@ -546,7 +547,18 @@ Handle<JSObject> ScopeIterator::ScopeObject(Mode mode) {
}
Handle<JSObject> scope = isolate_->factory()->NewJSObjectWithNullProto();
- auto visitor = [=](Handle<String> name, Handle<Object> value) {
+ auto visitor = [=](Handle<String> name, Handle<Object> value,
+ ScopeType scope_type) {
+ if (value->IsTheHole(isolate_)) {
+ // Reflect variables under TDZ as undefined in scope object.
+ if (scope_type == ScopeTypeScript &&
+ JSReceiver::HasOwnProperty(scope, name).FromMaybe(true)) {
+ // We also use the hole to represent overridden let-declarations via
+ // REPL mode in a script context. Catch this case.
+ return false;
+ }
+ value = isolate_->factory()->undefined_value();
+ }
JSObject::AddProperty(isolate_, scope, name, value, NONE);
return false;
};
@@ -562,10 +574,10 @@ void ScopeIterator::VisitScope(const Visitor& visitor, Mode mode) const {
case ScopeTypeCatch:
case ScopeTypeBlock:
case ScopeTypeEval:
- return VisitLocalScope(visitor, mode);
+ return VisitLocalScope(visitor, mode, Type());
case ScopeTypeModule:
if (InInnerScope()) {
- return VisitLocalScope(visitor, mode);
+ return VisitLocalScope(visitor, mode, Type());
}
DCHECK_EQ(Mode::ALL, mode);
return VisitModuleScope(visitor);
@@ -714,7 +726,8 @@ void ScopeIterator::VisitScriptScope(const Visitor& visitor) const {
Handle<Context> context = ScriptContextTable::GetContext(
isolate_, script_contexts, context_index);
Handle<ScopeInfo> scope_info(context->scope_info(), isolate_);
- if (VisitContextLocals(visitor, scope_info, context)) return;
+ if (VisitContextLocals(visitor, scope_info, context, ScopeTypeScript))
+ return;
}
}
@@ -722,7 +735,8 @@ void ScopeIterator::VisitModuleScope(const Visitor& visitor) const {
DCHECK(context_->IsModuleContext());
Handle<ScopeInfo> scope_info(context_->scope_info(), isolate_);
- if (VisitContextLocals(visitor, scope_info, context_)) return;
+ if (VisitContextLocals(visitor, scope_info, context_, ScopeTypeModule))
+ return;
int count_index = scope_info->ModuleVariableCountIndex();
int module_variable_count = Smi::cast(scope_info->get(count_index)).value();
@@ -741,29 +755,27 @@ void ScopeIterator::VisitModuleScope(const Visitor& visitor) const {
Handle<Object> value =
SourceTextModule::LoadVariable(isolate_, module, index);
- // Reflect variables under TDZ as undeclared in scope object.
- if (value->IsTheHole(isolate_)) continue;
- if (visitor(name, value)) return;
+ if (visitor(name, value, ScopeTypeModule)) return;
}
}
bool ScopeIterator::VisitContextLocals(const Visitor& visitor,
Handle<ScopeInfo> scope_info,
- Handle<Context> context) const {
+ Handle<Context> context,
+ ScopeType scope_type) const {
// Fill all context locals to the context extension.
for (int i = 0; i < scope_info->ContextLocalCount(); ++i) {
Handle<String> name(scope_info->ContextLocalName(i), isolate_);
if (ScopeInfo::VariableIsSynthetic(*name)) continue;
int context_index = scope_info->ContextHeaderLength() + i;
Handle<Object> value(context->get(context_index), isolate_);
- // Reflect variables under TDZ as undefined in scope object.
- if (value->IsTheHole(isolate_)) continue;
- if (visitor(name, value)) return true;
+ if (visitor(name, value, scope_type)) return true;
}
return false;
}
-bool ScopeIterator::VisitLocals(const Visitor& visitor, Mode mode) const {
+bool ScopeIterator::VisitLocals(const Visitor& visitor, Mode mode,
+ ScopeType scope_type) const {
if (mode == Mode::STACK && current_scope_->is_declaration_scope() &&
current_scope_->AsDeclarationScope()->has_this_declaration()) {
// TODO(bmeurer): We should refactor the general variable lookup
@@ -776,10 +788,11 @@ bool ScopeIterator::VisitLocals(const Visitor& visitor, Mode mode) const {
: frame_inspector_ == nullptr
? handle(generator_->receiver(), isolate_)
: frame_inspector_->GetReceiver();
- if (receiver->IsOptimizedOut(isolate_) || receiver->IsTheHole(isolate_)) {
+ if (receiver->IsOptimizedOut(isolate_)) {
receiver = isolate_->factory()->undefined_value();
}
- if (visitor(isolate_->factory()->this_string(), receiver)) return true;
+ if (visitor(isolate_->factory()->this_string(), receiver, scope_type))
+ return true;
}
if (current_scope_->is_function_scope()) {
@@ -790,7 +803,7 @@ bool ScopeIterator::VisitLocals(const Visitor& visitor, Mode mode) const {
? function_
: frame_inspector_->GetFunction();
Handle<String> name = function_var->name();
- if (visitor(name, function)) return true;
+ if (visitor(name, function, scope_type)) return true;
}
}
@@ -839,9 +852,6 @@ bool ScopeIterator::VisitLocals(const Visitor& visitor, Mode mode) const {
index += parameter_count;
DCHECK_LT(index, parameters_and_registers.length());
value = handle(parameters_and_registers.get(index), isolate_);
- if (value->IsTheHole(isolate_)) {
- value = isolate_->factory()->undefined_value();
- }
} else {
value = frame_inspector_->GetExpression(index);
if (value->IsOptimizedOut(isolate_)) {
@@ -851,9 +861,6 @@ bool ScopeIterator::VisitLocals(const Visitor& visitor, Mode mode) const {
continue;
}
value = isolate_->factory()->undefined_value();
- } else if (value->IsTheHole(isolate_)) {
- // Reflect variables under TDZ as undeclared in scope object.
- continue;
}
}
break;
@@ -862,8 +869,6 @@ bool ScopeIterator::VisitLocals(const Visitor& visitor, Mode mode) const {
if (mode == Mode::STACK) continue;
DCHECK(var->IsContextSlot());
value = handle(context_->get(index), isolate_);
- // Reflect variables under TDZ as undeclared in scope object.
- if (value->IsTheHole(isolate_)) continue;
break;
case VariableLocation::MODULE: {
@@ -871,13 +876,11 @@ bool ScopeIterator::VisitLocals(const Visitor& visitor, Mode mode) const {
// if (var->IsExport()) continue;
Handle<SourceTextModule> module(context_->module(), isolate_);
value = SourceTextModule::LoadVariable(isolate_, module, var->index());
- // Reflect variables under TDZ as undeclared in scope object.
- if (value->IsTheHole(isolate_)) continue;
break;
}
}
- if (visitor(var->name(), value)) return true;
+ if (visitor(var->name(), value, scope_type)) return true;
}
return false;
}
@@ -894,9 +897,10 @@ Handle<JSObject> ScopeIterator::WithContextExtension() {
// Create a plain JSObject which materializes the block scope for the specified
// block context.
-void ScopeIterator::VisitLocalScope(const Visitor& visitor, Mode mode) const {
+void ScopeIterator::VisitLocalScope(const Visitor& visitor, Mode mode,
+ ScopeType scope_type) const {
if (InInnerScope()) {
- if (VisitLocals(visitor, mode)) return;
+ if (VisitLocals(visitor, mode, scope_type)) return;
if (mode == Mode::STACK && Type() == ScopeTypeLocal) {
// Hide |this| in arrow functions that may be embedded in other functions
// but don't force |this| to be context-allocated. Otherwise we'd find the
@@ -904,7 +908,7 @@ void ScopeIterator::VisitLocalScope(const Visitor& visitor, Mode mode) const {
if (!closure_scope_->has_this_declaration() &&
!closure_scope_->HasThisReference()) {
if (visitor(isolate_->factory()->this_string(),
- isolate_->factory()->undefined_value()))
+ isolate_->factory()->undefined_value(), scope_type))
return;
}
// Add |arguments| to the function scope even if it wasn't used.
@@ -919,13 +923,15 @@ void ScopeIterator::VisitLocalScope(const Visitor& visitor, Mode mode) const {
JavaScriptFrame* frame = GetFrame();
Handle<JSObject> arguments = Accessors::FunctionGetArguments(
frame, frame_inspector_->inlined_frame_index());
- if (visitor(isolate_->factory()->arguments_string(), arguments)) return;
+ if (visitor(isolate_->factory()->arguments_string(), arguments,
+ scope_type))
+ return;
}
}
} else {
DCHECK_EQ(Mode::ALL, mode);
Handle<ScopeInfo> scope_info(context_->scope_info(), isolate_);
- if (VisitContextLocals(visitor, scope_info, context_)) return;
+ if (VisitContextLocals(visitor, scope_info, context_, scope_type)) return;
}
if (mode == Mode::ALL && HasContext()) {
@@ -945,7 +951,7 @@ void ScopeIterator::VisitLocalScope(const Visitor& visitor, Mode mode) const {
DCHECK(keys->get(i).IsString());
Handle<String> key(String::cast(keys->get(i)), isolate_);
Handle<Object> value = JSReceiver::GetDataProperty(extension, key);
- if (visitor(key, value)) return;
+ if (visitor(key, value, scope_type)) return;
}
}
}