From 2f7032741ece427594ddbf9127b43cde3ed22152 Mon Sep 17 00:00:00 2001 From: Gymee Date: Wed, 14 Dec 2022 15:15:52 +0800 Subject: [PATCH] Fix this value when getting local scope chain Issue: #I665YR Signed-off-by: Gymee Change-Id: I16fc9a562c70bc815307cd4fdb0dd6bd8cd22b76 --- tooling/agent/debugger_impl.cpp | 32 ++++++++++++++++++++++++-------- tooling/agent/debugger_impl.h | 2 ++ 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/tooling/agent/debugger_impl.cpp b/tooling/agent/debugger_impl.cpp index 547d5915..e61c2816 100644 --- a/tooling/agent/debugger_impl.cpp +++ b/tooling/agent/debugger_impl.cpp @@ -995,8 +995,10 @@ std::unique_ptr DebuggerImpl::GetLocalScopeChain(const FrameHandler *fram scopeObjects_[sp] = runtime_->curObjectId_; runtime_->properties_[runtime_->curObjectId_++] = Global(vm_, localObj); - Local thisVal = JSValueRef::Undefined(vm_); + Local thisVal = JSNApiHelper::ToLocal( + JSHandle(vm_->GetJSThread(), JSTaggedValue::Hole())); GetLocalVariables(frameHandler, methodId, jsPandaFile, thisVal, localObj); + GetClosureVariables(frameHandler, thisVal, localObj); *thisObj = RemoteObject::FromTagged(vm_, thisVal); runtime_->CacheObjectIfNeeded(thisVal, (*thisObj).get()); @@ -1045,7 +1047,6 @@ void DebuggerImpl::GetLocalVariables(const FrameHandler *frameHandler, panda_fil auto *extractor = GetExtractor(jsPandaFile); Local value = JSValueRef::Undefined(vm_); // in case of arrow function, which doesn't have this in local variable table - bool hasThis = false; for (const auto &[varName, regIndex] : extractor->GetLocalVariableTable(methodId)) { value = DebuggerApi::GetVRegValue(vm_, frameHandler, regIndex); if (varName == "4newTarget") { @@ -1053,8 +1054,8 @@ void DebuggerImpl::GetLocalVariables(const FrameHandler *frameHandler, panda_fil } if (varName == "this") { + LOG_DEBUGGER(INFO) << "find 'this' in local variable table"; thisVal = value; - hasThis = true; continue; } Local name = JSValueRef::Undefined(vm_); @@ -1071,26 +1072,30 @@ void DebuggerImpl::GetLocalVariables(const FrameHandler *frameHandler, panda_fil PropertyAttribute descriptor(value, true, true, true); localObj->DefineProperty(vm_, name, descriptor); } +} - // closure variables are stored in env +void DebuggerImpl::GetClosureVariables(const FrameHandler *frameHandler, Local &thisVal, + Local &localObj) +{ JSTaggedValue env = DebuggerApi::GetEnv(frameHandler); if (env.IsTaggedArray() && DebuggerApi::GetBytecodeOffset(frameHandler) != 0) { LexicalEnv *lexEnv = LexicalEnv::Cast(env.GetTaggedObject()); if (lexEnv->GetScopeInfo().IsHole()) { return; } - auto ptr = JSNativePointer::Cast(lexEnv->GetScopeInfo().GetTaggedObject())->GetExternalPointer(); - auto *scopeDebugInfo = reinterpret_cast(ptr); + auto *scopeDebugInfo = reinterpret_cast(JSNativePointer::Cast( + lexEnv->GetScopeInfo().GetTaggedObject())->GetExternalPointer()); JSThread *thread = vm_->GetJSThread(); for (const auto &[varName, slot] : scopeDebugInfo->scopeInfo) { // skip possible duplicate variables both in local variable table and env if (varName == "4newTarget") { continue; } - value = JSNApiHelper::ToLocal( + Local value = JSNApiHelper::ToLocal( JSHandle(thread, lexEnv->GetProperties(slot))); if (varName == "this") { - if (!hasThis) { + if (thisVal->IsHole()) { + LOG_DEBUGGER(INFO) << "find 'this' in current lexical env"; thisVal = value; } continue; @@ -1100,6 +1105,17 @@ void DebuggerImpl::GetLocalVariables(const FrameHandler *frameHandler, panda_fil localObj->DefineProperty(vm_, name, descriptor); } } + + // if 'this' is not in current lexical env, we should try to find from it's parent env + if (thisVal->IsHole()) { + auto [level, slot] = DebuggerApi::GetLevelSlot(frameHandler, "this"); + if (LIKELY(level != -1)) { + LOG_DEBUGGER(INFO) << "find 'this' in parent lexical env"; + thisVal = DebuggerApi::GetProperties(vm_, frameHandler, level, slot); + } else { + thisVal = JSValueRef::Undefined(vm_); + } + } } std::unique_ptr DebuggerImpl::GetGlobalScopeChain() diff --git a/tooling/agent/debugger_impl.h b/tooling/agent/debugger_impl.h index 87b66c54..cae0a29d 100644 --- a/tooling/agent/debugger_impl.h +++ b/tooling/agent/debugger_impl.h @@ -150,6 +150,8 @@ private: std::unique_ptr GetGlobalScopeChain(); void GetLocalVariables(const FrameHandler *frameHandler, panda_file::File::EntityId methodId, const JSPandaFile *jsPandaFile, Local &thisVal, Local &localObj); + void GetClosureVariables(const FrameHandler *frameHandler, Local &thisVal, + Local &localObj); void CleanUpOnPaused(); void UpdateScopeObject(const FrameHandler *frameHandler, std::string_view varName, Local newVal); void ClearSingleStepper(); -- Gitee