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