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