1e509ee18Sopenharmony_ci/* 2e509ee18Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 3e509ee18Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4e509ee18Sopenharmony_ci * you may not use this file except in compliance with the License. 5e509ee18Sopenharmony_ci * You may obtain a copy of the License at 6e509ee18Sopenharmony_ci * 7e509ee18Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8e509ee18Sopenharmony_ci * 9e509ee18Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10e509ee18Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11e509ee18Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12e509ee18Sopenharmony_ci * See the License for the specific language governing permissions and 13e509ee18Sopenharmony_ci * limitations under the License. 14e509ee18Sopenharmony_ci */ 15e509ee18Sopenharmony_ci 16e509ee18Sopenharmony_ci#include "tooling/client/domain/runtime_client.h" 17e509ee18Sopenharmony_ci 18e509ee18Sopenharmony_ci#include "common/log_wrapper.h" 19e509ee18Sopenharmony_ci#include "tooling/client/manager/variable_manager.h" 20e509ee18Sopenharmony_ci#include "tooling/client/manager/watch_manager.h" 21e509ee18Sopenharmony_ci#include "tooling/base/pt_json.h" 22e509ee18Sopenharmony_ci#include "tooling/client/session/session.h" 23e509ee18Sopenharmony_ci#include "tooling/utils/utils.h" 24e509ee18Sopenharmony_ci 25e509ee18Sopenharmony_ciusing PtJson = panda::ecmascript::tooling::PtJson; 26e509ee18Sopenharmony_cinamespace OHOS::ArkCompiler::Toolchain { 27e509ee18Sopenharmony_cibool RuntimeClient::DispatcherCmd(const std::string &cmd) 28e509ee18Sopenharmony_ci{ 29e509ee18Sopenharmony_ci std::map<std::string, std::function<int()>> dispatcherTable { 30e509ee18Sopenharmony_ci { "heapusage", std::bind(&RuntimeClient::HeapusageCommand, this)}, 31e509ee18Sopenharmony_ci { "runtime-enable", std::bind(&RuntimeClient::RuntimeEnableCommand, this)}, 32e509ee18Sopenharmony_ci { "runtime-disable", std::bind(&RuntimeClient::RuntimeDisableCommand, this)}, 33e509ee18Sopenharmony_ci { "print", std::bind(&RuntimeClient::GetPropertiesCommand, this)}, 34e509ee18Sopenharmony_ci { "run", std::bind(&RuntimeClient::RunIfWaitingForDebuggerCommand, this)}, 35e509ee18Sopenharmony_ci }; 36e509ee18Sopenharmony_ci 37e509ee18Sopenharmony_ci auto entry = dispatcherTable.find(cmd); 38e509ee18Sopenharmony_ci if (entry != dispatcherTable.end()) { 39e509ee18Sopenharmony_ci entry->second(); 40e509ee18Sopenharmony_ci LOGI("RuntimeClient DispatcherCmd reqStr1: %{public}s", cmd.c_str()); 41e509ee18Sopenharmony_ci return true; 42e509ee18Sopenharmony_ci } else { 43e509ee18Sopenharmony_ci LOGI("Unknown commond: %{public}s", cmd.c_str()); 44e509ee18Sopenharmony_ci return false; 45e509ee18Sopenharmony_ci } 46e509ee18Sopenharmony_ci} 47e509ee18Sopenharmony_ci 48e509ee18Sopenharmony_ciint RuntimeClient::HeapusageCommand() 49e509ee18Sopenharmony_ci{ 50e509ee18Sopenharmony_ci Session *session = SessionManager::getInstance().GetSessionById(sessionId_); 51e509ee18Sopenharmony_ci uint32_t id = session->GetMessageId(); 52e509ee18Sopenharmony_ci 53e509ee18Sopenharmony_ci idMethodMap_[id] = std::make_tuple("getHeapUsage", ""); 54e509ee18Sopenharmony_ci std::unique_ptr<PtJson> request = PtJson::CreateObject(); 55e509ee18Sopenharmony_ci request->Add("id", id); 56e509ee18Sopenharmony_ci request->Add("method", "Runtime.getHeapUsage"); 57e509ee18Sopenharmony_ci 58e509ee18Sopenharmony_ci std::unique_ptr<PtJson> params = PtJson::CreateObject(); 59e509ee18Sopenharmony_ci request->Add("params", params); 60e509ee18Sopenharmony_ci 61e509ee18Sopenharmony_ci std::string message = request->Stringify(); 62e509ee18Sopenharmony_ci if (session->ClientSendReq(message)) { 63e509ee18Sopenharmony_ci session->GetDomainManager().SetDomainById(id, "Runtime"); 64e509ee18Sopenharmony_ci } 65e509ee18Sopenharmony_ci return 0; 66e509ee18Sopenharmony_ci} 67e509ee18Sopenharmony_ci 68e509ee18Sopenharmony_ciint RuntimeClient::RuntimeEnableCommand() 69e509ee18Sopenharmony_ci{ 70e509ee18Sopenharmony_ci Session *session = SessionManager::getInstance().GetSessionById(sessionId_); 71e509ee18Sopenharmony_ci uint32_t id = session->GetMessageId(); 72e509ee18Sopenharmony_ci 73e509ee18Sopenharmony_ci idMethodMap_[id] = std::make_tuple("enable", ""); 74e509ee18Sopenharmony_ci std::unique_ptr<PtJson> request = PtJson::CreateObject(); 75e509ee18Sopenharmony_ci request->Add("id", id); 76e509ee18Sopenharmony_ci request->Add("method", "Runtime.enable"); 77e509ee18Sopenharmony_ci 78e509ee18Sopenharmony_ci std::unique_ptr<PtJson> params = PtJson::CreateObject(); 79e509ee18Sopenharmony_ci request->Add("params", params); 80e509ee18Sopenharmony_ci 81e509ee18Sopenharmony_ci std::string message = request->Stringify(); 82e509ee18Sopenharmony_ci if (session->ClientSendReq(message)) { 83e509ee18Sopenharmony_ci session->GetDomainManager().SetDomainById(id, "Runtime"); 84e509ee18Sopenharmony_ci } 85e509ee18Sopenharmony_ci return 0; 86e509ee18Sopenharmony_ci} 87e509ee18Sopenharmony_ci 88e509ee18Sopenharmony_ciint RuntimeClient::RuntimeDisableCommand() 89e509ee18Sopenharmony_ci{ 90e509ee18Sopenharmony_ci Session *session = SessionManager::getInstance().GetSessionById(sessionId_); 91e509ee18Sopenharmony_ci uint32_t id = session->GetMessageId(); 92e509ee18Sopenharmony_ci 93e509ee18Sopenharmony_ci idMethodMap_[id] = std::make_tuple("disable", ""); 94e509ee18Sopenharmony_ci std::unique_ptr<PtJson> request = PtJson::CreateObject(); 95e509ee18Sopenharmony_ci request->Add("id", id); 96e509ee18Sopenharmony_ci request->Add("method", "Runtime.disable"); 97e509ee18Sopenharmony_ci 98e509ee18Sopenharmony_ci std::unique_ptr<PtJson> params = PtJson::CreateObject(); 99e509ee18Sopenharmony_ci request->Add("params", params); 100e509ee18Sopenharmony_ci 101e509ee18Sopenharmony_ci std::string message = request->Stringify(); 102e509ee18Sopenharmony_ci if (session->ClientSendReq(message)) { 103e509ee18Sopenharmony_ci session->GetDomainManager().SetDomainById(id, "Runtime"); 104e509ee18Sopenharmony_ci } 105e509ee18Sopenharmony_ci return 0; 106e509ee18Sopenharmony_ci} 107e509ee18Sopenharmony_ci 108e509ee18Sopenharmony_ciint RuntimeClient::RunIfWaitingForDebuggerCommand() 109e509ee18Sopenharmony_ci{ 110e509ee18Sopenharmony_ci Session *session = SessionManager::getInstance().GetSessionById(sessionId_); 111e509ee18Sopenharmony_ci uint32_t id = session->GetMessageId(); 112e509ee18Sopenharmony_ci 113e509ee18Sopenharmony_ci idMethodMap_[id] = std::make_tuple("runIfWaitingForDebugger", ""); 114e509ee18Sopenharmony_ci std::unique_ptr<PtJson> request = PtJson::CreateObject(); 115e509ee18Sopenharmony_ci request->Add("id", id); 116e509ee18Sopenharmony_ci request->Add("method", "Runtime.runIfWaitingForDebugger"); 117e509ee18Sopenharmony_ci 118e509ee18Sopenharmony_ci std::unique_ptr<PtJson> params = PtJson::CreateObject(); 119e509ee18Sopenharmony_ci request->Add("params", params); 120e509ee18Sopenharmony_ci 121e509ee18Sopenharmony_ci std::string message = request->Stringify(); 122e509ee18Sopenharmony_ci if (session->ClientSendReq(message)) { 123e509ee18Sopenharmony_ci session->GetDomainManager().SetDomainById(id, "Runtime"); 124e509ee18Sopenharmony_ci } 125e509ee18Sopenharmony_ci WatchManager &watchManager = session->GetWatchManager(); 126e509ee18Sopenharmony_ci watchManager.DebugFalseState(); 127e509ee18Sopenharmony_ci return 0; 128e509ee18Sopenharmony_ci} 129e509ee18Sopenharmony_ci 130e509ee18Sopenharmony_ciint RuntimeClient::GetPropertiesCommand() 131e509ee18Sopenharmony_ci{ 132e509ee18Sopenharmony_ci Session *session = SessionManager::getInstance().GetSessionById(sessionId_); 133e509ee18Sopenharmony_ci uint32_t id = session->GetMessageId(); 134e509ee18Sopenharmony_ci 135e509ee18Sopenharmony_ci idMethodMap_[id] = std::make_tuple("getProperties", objectId_); 136e509ee18Sopenharmony_ci std::unique_ptr<PtJson> request = PtJson::CreateObject(); 137e509ee18Sopenharmony_ci request->Add("id", id); 138e509ee18Sopenharmony_ci request->Add("method", "Runtime.getProperties"); 139e509ee18Sopenharmony_ci 140e509ee18Sopenharmony_ci std::unique_ptr<PtJson> params = PtJson::CreateObject(); 141e509ee18Sopenharmony_ci params->Add("accessorPropertiesOnly", false); 142e509ee18Sopenharmony_ci params->Add("generatePreview", true); 143e509ee18Sopenharmony_ci params->Add("objectId", objectId_.c_str()); 144e509ee18Sopenharmony_ci params->Add("ownProperties", true); 145e509ee18Sopenharmony_ci request->Add("params", params); 146e509ee18Sopenharmony_ci 147e509ee18Sopenharmony_ci std::string message = request->Stringify(); 148e509ee18Sopenharmony_ci if (session->ClientSendReq(message)) { 149e509ee18Sopenharmony_ci session->GetDomainManager().SetDomainById(id, "Runtime"); 150e509ee18Sopenharmony_ci } 151e509ee18Sopenharmony_ci return 0; 152e509ee18Sopenharmony_ci} 153e509ee18Sopenharmony_ci 154e509ee18Sopenharmony_ciint RuntimeClient::GetPropertiesCommand2() 155e509ee18Sopenharmony_ci{ 156e509ee18Sopenharmony_ci Session *session = SessionManager::getInstance().GetSessionById(sessionId_); 157e509ee18Sopenharmony_ci uint32_t id = session->GetMessageId(); 158e509ee18Sopenharmony_ci 159e509ee18Sopenharmony_ci idMethodMap_[id] = std::make_tuple("getProperties", objectId_); 160e509ee18Sopenharmony_ci std::unique_ptr<PtJson> request = PtJson::CreateObject(); 161e509ee18Sopenharmony_ci request->Add("id", id); 162e509ee18Sopenharmony_ci request->Add("method", "Runtime.getProperties"); 163e509ee18Sopenharmony_ci 164e509ee18Sopenharmony_ci std::unique_ptr<PtJson> params = PtJson::CreateObject(); 165e509ee18Sopenharmony_ci params->Add("accessorPropertiesOnly", true); 166e509ee18Sopenharmony_ci params->Add("generatePreview", true); 167e509ee18Sopenharmony_ci params->Add("objectId", "0"); 168e509ee18Sopenharmony_ci params->Add("ownProperties", false); 169e509ee18Sopenharmony_ci request->Add("params", params); 170e509ee18Sopenharmony_ci 171e509ee18Sopenharmony_ci std::string message = request->Stringify(); 172e509ee18Sopenharmony_ci if (session->ClientSendReq(message)) { 173e509ee18Sopenharmony_ci session->GetDomainManager().SetDomainById(id, "Runtime"); 174e509ee18Sopenharmony_ci } 175e509ee18Sopenharmony_ci return 0; 176e509ee18Sopenharmony_ci} 177e509ee18Sopenharmony_ci 178e509ee18Sopenharmony_civoid RuntimeClient::RecvReply(std::unique_ptr<PtJson> json) 179e509ee18Sopenharmony_ci{ 180e509ee18Sopenharmony_ci if (json == nullptr) { 181e509ee18Sopenharmony_ci LOGE("arkdb: json parse error"); 182e509ee18Sopenharmony_ci return; 183e509ee18Sopenharmony_ci } 184e509ee18Sopenharmony_ci 185e509ee18Sopenharmony_ci if (!json->IsObject()) { 186e509ee18Sopenharmony_ci LOGE("arkdb: json parse format error"); 187e509ee18Sopenharmony_ci json->ReleaseRoot(); 188e509ee18Sopenharmony_ci return; 189e509ee18Sopenharmony_ci } 190e509ee18Sopenharmony_ci 191e509ee18Sopenharmony_ci int replyId; 192e509ee18Sopenharmony_ci Result ret = json->GetInt("id", &replyId); 193e509ee18Sopenharmony_ci if (ret != Result::SUCCESS) { 194e509ee18Sopenharmony_ci LOGE("arkdb: find id error"); 195e509ee18Sopenharmony_ci return; 196e509ee18Sopenharmony_ci } 197e509ee18Sopenharmony_ci 198e509ee18Sopenharmony_ci if (GetMethodById(replyId) == "getHeapUsage") { 199e509ee18Sopenharmony_ci HandleHeapUsage(std::move(json)); 200e509ee18Sopenharmony_ci } else if (GetMethodById(replyId) == "getProperties") { 201e509ee18Sopenharmony_ci HandleGetProperties(std::move(json), replyId); 202e509ee18Sopenharmony_ci } else { 203e509ee18Sopenharmony_ci LOGI("arkdb: Runtime replay message is %{public}s", json->Stringify().c_str()); 204e509ee18Sopenharmony_ci } 205e509ee18Sopenharmony_ci} 206e509ee18Sopenharmony_ci 207e509ee18Sopenharmony_cistd::string RuntimeClient::GetMethodById(const int &id) 208e509ee18Sopenharmony_ci{ 209e509ee18Sopenharmony_ci auto it = idMethodMap_.find(id); 210e509ee18Sopenharmony_ci if (it != idMethodMap_.end()) { 211e509ee18Sopenharmony_ci return std::get<0>(it->second); 212e509ee18Sopenharmony_ci } 213e509ee18Sopenharmony_ci return ""; 214e509ee18Sopenharmony_ci} 215e509ee18Sopenharmony_ci 216e509ee18Sopenharmony_cistd::string RuntimeClient::GetRequestObjectIdById(const int &id) 217e509ee18Sopenharmony_ci{ 218e509ee18Sopenharmony_ci auto it = idMethodMap_.find(id); 219e509ee18Sopenharmony_ci if (it != idMethodMap_.end()) { 220e509ee18Sopenharmony_ci return std::get<1>(it->second); 221e509ee18Sopenharmony_ci } 222e509ee18Sopenharmony_ci return ""; 223e509ee18Sopenharmony_ci} 224e509ee18Sopenharmony_ci 225e509ee18Sopenharmony_civoid RuntimeClient::HandleGetProperties(std::unique_ptr<PtJson> json, const int &id) 226e509ee18Sopenharmony_ci{ 227e509ee18Sopenharmony_ci if (json == nullptr) { 228e509ee18Sopenharmony_ci LOGE("arkdb: json parse error"); 229e509ee18Sopenharmony_ci return; 230e509ee18Sopenharmony_ci } 231e509ee18Sopenharmony_ci 232e509ee18Sopenharmony_ci if (!json->IsObject()) { 233e509ee18Sopenharmony_ci LOGE("arkdb: json parse format error"); 234e509ee18Sopenharmony_ci json->ReleaseRoot(); 235e509ee18Sopenharmony_ci return; 236e509ee18Sopenharmony_ci } 237e509ee18Sopenharmony_ci 238e509ee18Sopenharmony_ci std::unique_ptr<PtJson> result; 239e509ee18Sopenharmony_ci Result ret = json->GetObject("result", &result); 240e509ee18Sopenharmony_ci if (ret != Result::SUCCESS) { 241e509ee18Sopenharmony_ci LOGE("arkdb: find result error"); 242e509ee18Sopenharmony_ci return; 243e509ee18Sopenharmony_ci } 244e509ee18Sopenharmony_ci 245e509ee18Sopenharmony_ci std::unique_ptr<PtJson> innerResult; 246e509ee18Sopenharmony_ci ret = result->GetArray("result", &innerResult); 247e509ee18Sopenharmony_ci if (ret != Result::SUCCESS) { 248e509ee18Sopenharmony_ci LOGE("arkdb: find innerResult error"); 249e509ee18Sopenharmony_ci return; 250e509ee18Sopenharmony_ci } 251e509ee18Sopenharmony_ci 252e509ee18Sopenharmony_ci Session *session = SessionManager::getInstance().GetSessionById(sessionId_); 253e509ee18Sopenharmony_ci StackManager &stackManager = session->GetStackManager(); 254e509ee18Sopenharmony_ci VariableManager &variableManager = session->GetVariableManager(); 255e509ee18Sopenharmony_ci std::map<int32_t, std::map<int32_t, std::string>> treeInfo = stackManager.GetScopeChainInfo(); 256e509ee18Sopenharmony_ci if (isInitializeTree_) { 257e509ee18Sopenharmony_ci variableManager.ClearVariableInfo(); 258e509ee18Sopenharmony_ci variableManager.InitializeTree(treeInfo); 259e509ee18Sopenharmony_ci } 260e509ee18Sopenharmony_ci std::string requestObjectIdStr = GetRequestObjectIdById(id); 261e509ee18Sopenharmony_ci TreeNode *node = nullptr; 262e509ee18Sopenharmony_ci if (!isInitializeTree_) { 263e509ee18Sopenharmony_ci int32_t requestObjectId; 264e509ee18Sopenharmony_ci if (!Utils::StrToInt32(requestObjectIdStr, requestObjectId)) { 265e509ee18Sopenharmony_ci LOGE("arkdb: convert 'requestObjectId' from string to int error"); 266e509ee18Sopenharmony_ci return; 267e509ee18Sopenharmony_ci } 268e509ee18Sopenharmony_ci node = variableManager.FindNodeWithObjectId(requestObjectId); 269e509ee18Sopenharmony_ci } else { 270e509ee18Sopenharmony_ci node = variableManager.FindNodeObjectZero(); 271e509ee18Sopenharmony_ci } 272e509ee18Sopenharmony_ci 273e509ee18Sopenharmony_ci for (int32_t i = 0; i < innerResult->GetSize(); i++) { 274e509ee18Sopenharmony_ci std::unique_ptr<PropertyDescriptor> variableInfo = PropertyDescriptor::Create(*(innerResult->Get(i))); 275e509ee18Sopenharmony_ci variableManager.AddVariableInfo(node, std::move(variableInfo)); 276e509ee18Sopenharmony_ci } 277e509ee18Sopenharmony_ci 278e509ee18Sopenharmony_ci std::cout << std::endl; 279e509ee18Sopenharmony_ci variableManager.PrintVariableInfo(); 280e509ee18Sopenharmony_ci} 281e509ee18Sopenharmony_ci 282e509ee18Sopenharmony_civoid RuntimeClient::HandleHeapUsage(std::unique_ptr<PtJson> json) 283e509ee18Sopenharmony_ci{ 284e509ee18Sopenharmony_ci if (json == nullptr) { 285e509ee18Sopenharmony_ci LOGE("arkdb: json parse error"); 286e509ee18Sopenharmony_ci return; 287e509ee18Sopenharmony_ci } 288e509ee18Sopenharmony_ci 289e509ee18Sopenharmony_ci if (!json->IsObject()) { 290e509ee18Sopenharmony_ci LOGE("arkdb: json parse format error"); 291e509ee18Sopenharmony_ci json->ReleaseRoot(); 292e509ee18Sopenharmony_ci return; 293e509ee18Sopenharmony_ci } 294e509ee18Sopenharmony_ci 295e509ee18Sopenharmony_ci std::unique_ptr<PtJson> result; 296e509ee18Sopenharmony_ci Result ret = json->GetObject("result", &result); 297e509ee18Sopenharmony_ci if (ret != Result::SUCCESS) { 298e509ee18Sopenharmony_ci LOGE("arkdb: find result error"); 299e509ee18Sopenharmony_ci return; 300e509ee18Sopenharmony_ci } 301e509ee18Sopenharmony_ci 302e509ee18Sopenharmony_ci Session *session = SessionManager::getInstance().GetSessionById(sessionId_); 303e509ee18Sopenharmony_ci VariableManager &variableManager = session->GetVariableManager(); 304e509ee18Sopenharmony_ci std::unique_ptr<GetHeapUsageReturns> heapUsageReturns = GetHeapUsageReturns::Create(*result); 305e509ee18Sopenharmony_ci variableManager.SetHeapUsageInfo(std::move(heapUsageReturns)); 306e509ee18Sopenharmony_ci variableManager.ShowHeapUsageInfo(); 307e509ee18Sopenharmony_ci} 308e509ee18Sopenharmony_ci} // OHOS::ArkCompiler::Toolchain