diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-12 14:27:29 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-13 09:35:20 +0000 |
commit | c30a6232df03e1efbd9f3b226777b07e087a1122 (patch) | |
tree | e992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/v8/src/debug/debug-scopes.cc | |
parent | 7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff) | |
download | qtwebengine-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.cc | 96 |
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; } } } |