1 /*
2 * Copyright (c) 2021-2022 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 "pt_types.h"
17
18 #ifdef SUPPORT_PROFILER_CDP
19 #include "ecmascript/dfx/cpu_profiler/samples_record.h"
20 #endif
21
22 namespace panda::ecmascript::tooling {
23 using ObjectType = RemoteObject::TypeName;
24 using ObjectSubType = RemoteObject::SubTypeName;
25 using ObjectClassName = RemoteObject::ClassName;
26
27 const std::string ObjectType::Object = "object"; // NOLINT (readability-identifier-naming)
28 const std::string ObjectType::Function = "function"; // NOLINT (readability-identifier-naming)
29 const std::string ObjectType::Undefined = "undefined"; // NOLINT (readability-identifier-naming)
30 const std::string ObjectType::String = "string"; // NOLINT (readability-identifier-naming)
31 const std::string ObjectType::Number = "number"; // NOLINT (readability-identifier-naming)
32 const std::string ObjectType::Boolean = "boolean"; // NOLINT (readability-identifier-naming)
33 const std::string ObjectType::Symbol = "symbol"; // NOLINT (readability-identifier-naming)
34 const std::string ObjectType::Bigint = "bigint"; // NOLINT (readability-identifier-naming)
35 const std::string ObjectType::Wasm = "wasm"; // NOLINT (readability-identifier-naming)
36
37 const std::string ObjectSubType::Array = "array"; // NOLINT (readability-identifier-naming)
38 const std::string ObjectSubType::Null = "null"; // NOLINT (readability-identifier-naming)
39 const std::string ObjectSubType::Node = "node"; // NOLINT (readability-identifier-naming)
40 const std::string ObjectSubType::Regexp = "regexp"; // NOLINT (readability-identifier-naming)
41 const std::string ObjectSubType::Date = "date"; // NOLINT (readability-identifier-naming)
42 const std::string ObjectSubType::Map = "map"; // NOLINT (readability-identifier-naming)
43 const std::string ObjectSubType::Set = "set"; // NOLINT (readability-identifier-naming)
44 const std::string ObjectSubType::Weakmap = "weakmap"; // NOLINT (readability-identifier-naming)
45 const std::string ObjectSubType::Weakset = "weakset"; // NOLINT (readability-identifier-naming)
46 const std::string ObjectSubType::Iterator = "iterator"; // NOLINT (readability-identifier-naming)
47 const std::string ObjectSubType::Generator = "generator"; // NOLINT (readability-identifier-naming)
48 const std::string ObjectSubType::Error = "error"; // NOLINT (readability-identifier-naming)
49 const std::string ObjectSubType::Proxy = "proxy"; // NOLINT (readability-identifier-naming)
50 const std::string ObjectSubType::Promise = "promise"; // NOLINT (readability-identifier-naming)
51 const std::string ObjectSubType::Typedarray = "typedarray"; // NOLINT (readability-identifier-naming)
52 const std::string ObjectSubType::Arraybuffer = "arraybuffer"; // NOLINT (readability-identifier-naming)
53 const std::string ObjectSubType::Dataview = "dataview"; // NOLINT (readability-identifier-naming)
54 const std::string ObjectSubType::I32 = "i32"; // NOLINT (readability-identifier-naming)
55 const std::string ObjectSubType::I64 = "i64"; // NOLINT (readability-identifier-naming)
56 const std::string ObjectSubType::F32 = "f32"; // NOLINT (readability-identifier-naming)
57 const std::string ObjectSubType::F64 = "f64"; // NOLINT (readability-identifier-naming)
58 const std::string ObjectSubType::V128 = "v128"; // NOLINT (readability-identifier-naming)
59 const std::string ObjectSubType::Externref = "externref"; // NOLINT (readability-identifier-naming)
60
61 const std::string ObjectClassName::Object = "Object"; // NOLINT (readability-identifier-naming)
62 const std::string ObjectClassName::Function = "Function"; // NOLINT (readability-identifier-naming)
63 const std::string ObjectClassName::Array = "Array"; // NOLINT (readability-identifier-naming)
64 const std::string ObjectClassName::Regexp = "RegExp"; // NOLINT (readability-identifier-naming)
65 const std::string ObjectClassName::Date = "Date"; // NOLINT (readability-identifier-naming)
66 const std::string ObjectClassName::Map = "Map"; // NOLINT (readability-identifier-naming)
67 const std::string ObjectClassName::Set = "Set"; // NOLINT (readability-identifier-naming)
68 const std::string ObjectClassName::Weakmap = "Weakmap"; // NOLINT (readability-identifier-naming)
69 const std::string ObjectClassName::Weakset = "Weakset"; // NOLINT (readability-identifier-naming)
70 const std::string ObjectClassName::ArrayIterator = "ArrayIterator"; // NOLINT (readability-identifier-naming)
71 const std::string ObjectClassName::StringIterator = "StringIterator"; // NOLINT (readability-identifier-naming)
72 const std::string ObjectClassName::SetIterator = "SetIterator"; // NOLINT (readability-identifier-naming)
73 const std::string ObjectClassName::MapIterator = "MapIterator"; // NOLINT (readability-identifier-naming)
74 const std::string ObjectClassName::Iterator = "Iterator"; // NOLINT (readability-identifier-naming)
75 const std::string ObjectClassName::Error = "Error"; // NOLINT (readability-identifier-naming)
76 const std::string ObjectClassName::Proxy = "Object"; // NOLINT (readability-identifier-naming)
77 const std::string ObjectClassName::Promise = "Promise"; // NOLINT (readability-identifier-naming)
78 const std::string ObjectClassName::Typedarray = "Typedarray"; // NOLINT (readability-identifier-naming)
79 const std::string ObjectClassName::Arraybuffer = "Arraybuffer"; // NOLINT (readability-identifier-naming)
80 const std::string ObjectClassName::Global = "global"; // NOLINT (readability-identifier-naming)
81
82 const std::string RemoteObject::ObjectDescription = "Object"; // NOLINT (readability-identifier-naming)
83 const std::string RemoteObject::GlobalDescription = "global"; // NOLINT (readability-identifier-naming)
84 const std::string RemoteObject::ProxyDescription = "Proxy"; // NOLINT (readability-identifier-naming)
85 const std::string RemoteObject::PromiseDescription = "Promise"; // NOLINT (readability-identifier-naming)
86 const std::string RemoteObject::ArrayIteratorDescription = // NOLINT (readability-identifier-naming)
87 "ArrayIterator";
88 const std::string RemoteObject::StringIteratorDescription = // NOLINT (readability-identifier-naming)
89 "StringIterator";
90 const std::string RemoteObject::SetIteratorDescription = "SetIterator"; // NOLINT (readability-identifier-naming)
91 const std::string RemoteObject::MapIteratorDescription = "MapIterator"; // NOLINT (readability-identifier-naming)
92 const std::string RemoteObject::WeakMapDescription = "WeakMap"; // NOLINT (readability-identifier-naming)
93 const std::string RemoteObject::WeakSetDescription = "WeakSet"; // NOLINT (readability-identifier-naming)
94
FromTagged(const EcmaVM * ecmaVm,Local<JSValueRef> tagged)95 std::unique_ptr<RemoteObject> RemoteObject::FromTagged(const EcmaVM *ecmaVm, Local<JSValueRef> tagged)
96 {
97 if (tagged->IsNull() || tagged->IsUndefined() ||
98 tagged->IsBoolean() || tagged->IsNumber() ||
99 tagged->IsBigInt()) {
100 return std::make_unique<PrimitiveRemoteObject>(ecmaVm, tagged);
101 }
102 if (tagged->IsString()) {
103 return std::make_unique<StringRemoteObject>(ecmaVm, Local<StringRef>(tagged));
104 }
105 if (tagged->IsSymbol()) {
106 return std::make_unique<SymbolRemoteObject>(ecmaVm, Local<SymbolRef>(tagged));
107 }
108 if (tagged->IsFunction()) {
109 return std::make_unique<FunctionRemoteObject>(ecmaVm, tagged);
110 }
111 if (tagged->IsArray(ecmaVm)) {
112 return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Array, ObjectSubType::Array);
113 }
114 if (tagged->IsRegExp()) {
115 return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Regexp, ObjectSubType::Regexp);
116 }
117 if (tagged->IsDate()) {
118 return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Date, ObjectSubType::Date);
119 }
120 if (tagged->IsMap()) {
121 return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Map, ObjectSubType::Map);
122 }
123 if (tagged->IsWeakMap()) {
124 return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Weakmap, ObjectSubType::Weakmap);
125 }
126 if (tagged->IsSet()) {
127 return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Set, ObjectSubType::Set);
128 }
129 if (tagged->IsWeakSet()) {
130 return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Weakset, ObjectSubType::Weakset);
131 }
132 if (tagged->IsError()) {
133 return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Error, ObjectSubType::Error);
134 }
135 if (tagged->IsProxy()) {
136 return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Proxy, ObjectSubType::Proxy);
137 }
138 if (tagged->IsPromise()) {
139 return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Promise, ObjectSubType::Promise);
140 }
141 if (tagged->IsArrayBuffer()) {
142 return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Arraybuffer,
143 ObjectSubType::Arraybuffer);
144 }
145 if (tagged->IsArrayIterator()) {
146 return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::ArrayIterator);
147 }
148 if (tagged->IsStringIterator()) {
149 return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::StringIterator);
150 }
151 if (tagged->IsSetIterator()) {
152 return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::SetIterator,
153 ObjectSubType::Iterator);
154 }
155 if (tagged->IsMapIterator()) {
156 return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::MapIterator,
157 ObjectSubType::Iterator);
158 }
159 if (tagged->IsObject()) {
160 return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
161 }
162 std::unique_ptr<RemoteObject> object = std::make_unique<RemoteObject>();
163 object->SetType(ObjectType::Undefined);
164 return object;
165 }
166
PrimitiveRemoteObject(const EcmaVM * ecmaVm,Local<JSValueRef> tagged)167 PrimitiveRemoteObject::PrimitiveRemoteObject(const EcmaVM *ecmaVm, Local<JSValueRef> tagged)
168 {
169 if (tagged->IsNull()) {
170 SetType(ObjectType::Object).SetSubType(ObjectSubType::Null);
171 } else if (tagged->IsBoolean()) {
172 std::string description = tagged->IsTrue() ? "true" : "false";
173 SetType(ObjectType::Boolean)
174 .SetValue(tagged)
175 .SetUnserializableValue(description)
176 .SetDescription(description);
177 } else if (tagged->IsUndefined()) {
178 SetType(ObjectType::Undefined);
179 } else if (tagged->IsNumber()) {
180 std::string description = tagged->ToString(ecmaVm)->ToString();
181 SetType(ObjectType::Number)
182 .SetValue(tagged)
183 .SetUnserializableValue(description)
184 .SetDescription(description);
185 } else if (tagged->IsBigInt()) {
186 std::string description = tagged->ToString(ecmaVm)->ToString() + "n"; // n : BigInt literal postfix
187 SetType(ObjectType::Bigint)
188 .SetValue(tagged)
189 .SetUnserializableValue(description)
190 .SetDescription(description);
191 }
192 }
193
StringRemoteObject(const EcmaVM * ecmaVm,Local<StringRef> tagged)194 StringRemoteObject::StringRemoteObject([[maybe_unused]] const EcmaVM *ecmaVm, Local<StringRef> tagged)
195 {
196 std::string description = tagged->ToString();
197 SetType(RemoteObject::TypeName::String)
198 .SetValue(tagged)
199 .SetUnserializableValue(description)
200 .SetDescription(description);
201 }
202
SymbolRemoteObject(const EcmaVM * ecmaVm,Local<SymbolRef> tagged)203 SymbolRemoteObject::SymbolRemoteObject(const EcmaVM *ecmaVm, Local<SymbolRef> tagged)
204 {
205 std::string description = DescriptionForSymbol(ecmaVm, tagged);
206 SetType(RemoteObject::TypeName::Symbol)
207 .SetValue(tagged)
208 .SetUnserializableValue(description)
209 .SetDescription(description);
210 }
211
FunctionRemoteObject(const EcmaVM * ecmaVm,Local<JSValueRef> tagged)212 FunctionRemoteObject::FunctionRemoteObject(const EcmaVM *ecmaVm, Local<JSValueRef> tagged)
213 {
214 std::string description = DescriptionForFunction(ecmaVm, tagged);
215 SetType(RemoteObject::TypeName::Function)
216 .SetClassName(RemoteObject::ClassName::Function)
217 .SetValue(tagged)
218 .SetUnserializableValue(description)
219 .SetDescription(description);
220 }
221
ObjectRemoteObject(const EcmaVM * ecmaVm,Local<JSValueRef> tagged,const std::string & classname)222 ObjectRemoteObject::ObjectRemoteObject(const EcmaVM *ecmaVm, Local<JSValueRef> tagged,
223 const std::string &classname)
224 {
225 std::string description = DescriptionForObject(ecmaVm, tagged);
226 SetType(RemoteObject::TypeName::Object)
227 .SetClassName(classname)
228 .SetValue(tagged)
229 .SetUnserializableValue(description)
230 .SetDescription(description);
231 }
232
ObjectRemoteObject(const EcmaVM * ecmaVm,Local<JSValueRef> tagged,const std::string & classname,const std::string & subtype)233 ObjectRemoteObject::ObjectRemoteObject(const EcmaVM *ecmaVm, Local<JSValueRef> tagged,
234 const std::string &classname, const std::string &subtype)
235 {
236 std::string description = DescriptionForObject(ecmaVm, tagged);
237 SetType(RemoteObject::TypeName::Object)
238 .SetSubType(subtype)
239 .SetClassName(classname)
240 .SetValue(tagged)
241 .SetUnserializableValue(description)
242 .SetDescription(description);
243 }
244
DescriptionForObject(const EcmaVM * ecmaVm,Local<JSValueRef> tagged)245 std::string ObjectRemoteObject::DescriptionForObject(const EcmaVM *ecmaVm, Local<JSValueRef> tagged)
246 {
247 if (tagged->IsArray(ecmaVm)) {
248 return DescriptionForArray(ecmaVm, Local<ArrayRef>(tagged));
249 }
250 if (tagged->IsRegExp()) {
251 return DescriptionForRegexp(ecmaVm, Local<RegExpRef>(tagged));
252 }
253 if (tagged->IsDate()) {
254 return DescriptionForDate(ecmaVm, Local<DateRef>(tagged));
255 }
256 if (tagged->IsMap()) {
257 return DescriptionForMap(Local<MapRef>(tagged));
258 }
259 if (tagged->IsWeakMap()) {
260 return RemoteObject::WeakMapDescription;
261 }
262 if (tagged->IsSet()) {
263 return DescriptionForSet(Local<SetRef>(tagged));
264 }
265 if (tagged->IsWeakSet()) {
266 return RemoteObject::WeakSetDescription;
267 }
268 if (tagged->IsError()) {
269 return DescriptionForError(ecmaVm, tagged);
270 }
271 if (tagged->IsProxy()) {
272 return RemoteObject::ProxyDescription;
273 }
274 if (tagged->IsPromise()) {
275 return RemoteObject::PromiseDescription;
276 }
277 if (tagged->IsArrayIterator()) {
278 return RemoteObject::ArrayIteratorDescription;
279 }
280 if (tagged->IsStringIterator()) {
281 return RemoteObject::StringIteratorDescription;
282 }
283 if (tagged->IsSetIterator()) {
284 return RemoteObject::SetIteratorDescription;
285 }
286 if (tagged->IsMapIterator()) {
287 return RemoteObject::MapIteratorDescription;
288 }
289 if (tagged->IsArrayBuffer()) {
290 return DescriptionForArrayBuffer(ecmaVm, Local<ArrayBufferRef>(tagged));
291 }
292 return RemoteObject::ObjectDescription;
293 }
294
DescriptionForArray(const EcmaVM * ecmaVm,Local<ArrayRef> tagged)295 std::string ObjectRemoteObject::DescriptionForArray(const EcmaVM *ecmaVm, Local<ArrayRef> tagged)
296 {
297 std::string description = "Array(" + std::to_string(tagged->Length(ecmaVm)) + ")";
298 return description;
299 }
300
DescriptionForRegexp(const EcmaVM * ecmaVm,Local<RegExpRef> tagged)301 std::string ObjectRemoteObject::DescriptionForRegexp(const EcmaVM *ecmaVm, Local<RegExpRef> tagged)
302 {
303 std::string regexpSource = tagged->GetOriginalSource(ecmaVm)->ToString();
304 std::string description = "/" + regexpSource + "/";
305 return description;
306 }
307
DescriptionForDate(const EcmaVM * ecmaVm,Local<DateRef> tagged)308 std::string ObjectRemoteObject::DescriptionForDate(const EcmaVM *ecmaVm, Local<DateRef> tagged)
309 {
310 std::string description = tagged->ToString(ecmaVm)->ToString();
311 return description;
312 }
313
DescriptionForMap(Local<MapRef> tagged)314 std::string ObjectRemoteObject::DescriptionForMap(Local<MapRef> tagged)
315 {
316 std::string description = ("Map(" + std::to_string(tagged->GetSize()) + ")");
317 return description;
318 }
319
DescriptionForSet(Local<SetRef> tagged)320 std::string ObjectRemoteObject::DescriptionForSet(Local<SetRef> tagged)
321 {
322 std::string description = ("Set(" + std::to_string(tagged->GetSize()) + ")");
323 return description;
324 }
325
DescriptionForError(const EcmaVM * ecmaVm,Local<JSValueRef> tagged)326 std::string ObjectRemoteObject::DescriptionForError(const EcmaVM *ecmaVm, Local<JSValueRef> tagged)
327 {
328 // add message
329 Local<JSValueRef> stack = StringRef::NewFromUtf8(ecmaVm, "message");
330 Local<JSValueRef> result = Local<ObjectRef>(tagged)->Get(ecmaVm, stack);
331 return result->ToString(ecmaVm)->ToString();
332 }
333
DescriptionForArrayBuffer(const EcmaVM * ecmaVm,Local<ArrayBufferRef> tagged)334 std::string ObjectRemoteObject::DescriptionForArrayBuffer(const EcmaVM *ecmaVm, Local<ArrayBufferRef> tagged)
335 {
336 int32_t len = tagged->ByteLength(ecmaVm);
337 std::string description = ("ArrayBuffer(" + std::to_string(len) + ")");
338 return description;
339 }
340
DescriptionForSymbol(const EcmaVM * ecmaVm,Local<SymbolRef> tagged) const341 std::string SymbolRemoteObject::DescriptionForSymbol(const EcmaVM *ecmaVm, Local<SymbolRef> tagged) const
342 {
343 std::string description = "Symbol(" + tagged->GetDescription(ecmaVm)->ToString() + ")";
344 return description;
345 }
346
DescriptionForFunction(const EcmaVM * ecmaVm,Local<FunctionRef> tagged) const347 std::string FunctionRemoteObject::DescriptionForFunction(const EcmaVM *ecmaVm, Local<FunctionRef> tagged) const
348 {
349 std::string sourceCode;
350 if (tagged->IsNative(ecmaVm)) {
351 sourceCode = "[native code]";
352 } else {
353 sourceCode = "[js code]";
354 }
355 Local<StringRef> name = tagged->GetName(ecmaVm);
356 std::string description = "function " + name->ToString() + "( { " + sourceCode + " }";
357 return description;
358 }
359
Create(const PtJson & params)360 std::unique_ptr<RemoteObject> RemoteObject::Create(const PtJson ¶ms)
361 {
362 std::string error;
363 auto remoteObject = std::make_unique<RemoteObject>();
364 Result ret;
365
366 std::string type;
367 ret = params.GetString("type", &type);
368 if (ret == Result::SUCCESS) {
369 if (ObjectType::Valid(type)) {
370 remoteObject->type_ = std::move(type);
371 } else {
372 error += "'type' is invalid;";
373 }
374 } else {
375 error += "Unknown 'type';";
376 }
377
378 std::string subType;
379 ret = params.GetString("subtype", &subType);
380 if (ret == Result::SUCCESS) {
381 if (ObjectSubType::Valid(subType)) {
382 remoteObject->subType_ = std::move(subType);
383 } else {
384 error += "'subtype' is invalid;";
385 }
386 } else if (ret == Result::TYPE_ERROR) {
387 error += "Unknown 'subtype';";
388 }
389
390 std::string className;
391 ret = params.GetString("className", &className);
392 if (ret == Result::SUCCESS) {
393 remoteObject->className_ = std::move(className);
394 } else if (ret == Result::TYPE_ERROR) {
395 error += "Unknown 'className';";
396 }
397
398 std::string unserializableValue;
399 ret = params.GetString("unserializableValue", &unserializableValue);
400 if (ret == Result::SUCCESS) {
401 remoteObject->unserializableValue_ = std::move(unserializableValue);
402 } else if (ret == Result::TYPE_ERROR) {
403 error += "Unknown 'unserializableValue';";
404 }
405
406 std::string description;
407 ret = params.GetString("description", &description);
408 if (ret == Result::SUCCESS) {
409 remoteObject->description_ = std::move(description);
410 } else if (ret == Result::TYPE_ERROR) {
411 error += "Unknown 'description';";
412 }
413
414 std::string objectId;
415 ret = params.GetString("objectId", &objectId);
416 if (ret == Result::SUCCESS) {
417 remoteObject->objectId_ = std::stoi(objectId);
418 } else if (ret == Result::TYPE_ERROR) {
419 error += "Unknown 'objectId';";
420 }
421
422 if (!error.empty()) {
423 LOG(ERROR, DEBUGGER) << "RemoteObject::Create " << error;
424 return nullptr;
425 }
426
427 return remoteObject;
428 }
429
ToJson() const430 std::unique_ptr<PtJson> RemoteObject::ToJson() const
431 {
432 std::unique_ptr<PtJson> result = PtJson::CreateObject();
433
434 result->Add("type", type_.c_str());
435 if (subType_) {
436 result->Add("subtype", subType_->c_str());
437 }
438 if (className_) {
439 result->Add("className", className_->c_str());
440 }
441 if (unserializableValue_) {
442 result->Add("unserializableValue", unserializableValue_->c_str());
443 }
444 if (description_) {
445 result->Add("description", description_->c_str());
446 }
447 if (objectId_) {
448 result->Add("objectId", std::to_string(objectId_.value()).c_str());
449 }
450
451 return result;
452 }
453
Create(const PtJson & params)454 std::unique_ptr<ExceptionDetails> ExceptionDetails::Create(const PtJson ¶ms)
455 {
456 std::string error;
457 auto exceptionDetails = std::make_unique<ExceptionDetails>();
458 Result ret;
459
460 int32_t exceptionId;
461 ret = params.GetInt("exceptionId", &exceptionId);
462 if (ret == Result::SUCCESS) {
463 exceptionDetails->exceptionId_ = exceptionId;
464 } else {
465 error += "Unknown 'exceptionId';";
466 }
467
468 std::string text;
469 ret = params.GetString("text", &text);
470 if (ret == Result::SUCCESS) {
471 exceptionDetails->text_ = std::move(text);
472 } else {
473 error += "Unknown 'text';";
474 }
475
476 int32_t lineNumber;
477 ret = params.GetInt("lineNumber", &lineNumber);
478 if (ret == Result::SUCCESS) {
479 exceptionDetails->lineNumber_ = lineNumber;
480 } else {
481 error += "Unknown 'lineNumber';";
482 }
483
484 int32_t columnNumber;
485 ret = params.GetInt("columnNumber", &columnNumber);
486 if (ret == Result::SUCCESS) {
487 exceptionDetails->columnNumber_ = columnNumber;
488 } else {
489 error += "Unknown 'columnNumber';";
490 }
491
492 std::string scriptId;
493 ret = params.GetString("scriptId", &scriptId);
494 if (ret == Result::SUCCESS) {
495 exceptionDetails->scriptId_ = std::stoi(scriptId);
496 } else if (ret == Result::TYPE_ERROR) {
497 error += "Unknown 'scriptId';";
498 }
499
500 std::string url;
501 ret = params.GetString("url", &url);
502 if (ret == Result::SUCCESS) {
503 exceptionDetails->url_ = std::move(url);
504 } else if (ret == Result::TYPE_ERROR) {
505 error += "Unknown 'url';";
506 }
507
508 std::unique_ptr<PtJson> exception;
509 ret = params.GetObject("exception", &exception);
510 if (ret == Result::SUCCESS) {
511 std::unique_ptr<RemoteObject> obj = RemoteObject::Create(*exception);
512 if (obj == nullptr) {
513 error += "'exception' format error;";
514 } else {
515 exceptionDetails->exception_ = std::move(obj);
516 }
517 } else if (ret == Result::TYPE_ERROR) {
518 error += "Unknown 'exception';";
519 }
520
521 int32_t executionContextId;
522 ret = params.GetInt("executionContextId", &executionContextId);
523 if (ret == Result::SUCCESS) {
524 exceptionDetails->executionContextId_ = executionContextId;
525 } else if (ret == Result::TYPE_ERROR) {
526 error += "Unknown 'executionContextId';";
527 }
528
529 if (!error.empty()) {
530 LOG(ERROR, DEBUGGER) << "ExceptionDetails::Create " << error;
531 return nullptr;
532 }
533
534 return exceptionDetails;
535 }
536
ToJson() const537 std::unique_ptr<PtJson> ExceptionDetails::ToJson() const
538 {
539 std::unique_ptr<PtJson> result = PtJson::CreateObject();
540
541 result->Add("exceptionId", exceptionId_);
542 result->Add("text", text_.c_str());
543 result->Add("lineNumber", lineNumber_);
544 result->Add("columnNumber", columnNumber_);
545
546 if (scriptId_) {
547 result->Add("scriptId", std::to_string(scriptId_.value()).c_str());
548 }
549 if (url_) {
550 result->Add("url", url_->c_str());
551 }
552 if (exception_) {
553 ASSERT(exception_.value() != nullptr);
554 result->Add("exception", exception_.value()->ToJson());
555 }
556 if (executionContextId_) {
557 result->Add("executionContextId", executionContextId_.value());
558 }
559
560 return result;
561 }
562
Create(const PtJson & params)563 std::unique_ptr<InternalPropertyDescriptor> InternalPropertyDescriptor::Create(const PtJson ¶ms)
564 {
565 std::string error;
566 auto internalPropertyDescriptor = std::make_unique<InternalPropertyDescriptor>();
567 Result ret;
568
569 std::string name;
570 ret = params.GetString("name", &name);
571 if (ret == Result::SUCCESS) {
572 internalPropertyDescriptor->name_ = std::move(name);
573 } else {
574 error += "Unknown 'name';";
575 }
576
577 std::unique_ptr<PtJson> value;
578 ret = params.GetObject("value", &value);
579 if (ret == Result::SUCCESS) {
580 std::unique_ptr<RemoteObject> obj = RemoteObject::Create(*value);
581 if (obj == nullptr) {
582 error += "'value' format error;";
583 } else {
584 internalPropertyDescriptor->value_ = std::move(obj);
585 }
586 } else if (ret == Result::TYPE_ERROR) {
587 error += "Unknown 'value';";
588 }
589
590 if (!error.empty()) {
591 LOG(ERROR, DEBUGGER) << "InternalPropertyDescriptor::Create " << error;
592 return nullptr;
593 }
594
595 return internalPropertyDescriptor;
596 }
597
ToJson() const598 std::unique_ptr<PtJson> InternalPropertyDescriptor::ToJson() const
599 {
600 std::unique_ptr<PtJson> result = PtJson::CreateObject();
601
602 result->Add("name", name_.c_str());
603 if (value_) {
604 ASSERT(value_.value() != nullptr);
605 result->Add("value", value_.value()->ToJson());
606 }
607
608 return result;
609 }
610
Create(const PtJson & params)611 std::unique_ptr<PrivatePropertyDescriptor> PrivatePropertyDescriptor::Create(const PtJson ¶ms)
612 {
613 std::string error;
614 auto privatePropertyDescriptor = std::make_unique<PrivatePropertyDescriptor>();
615 Result ret;
616
617 std::string name;
618 ret = params.GetString("name", &name);
619 if (ret == Result::SUCCESS) {
620 privatePropertyDescriptor->name_ = std::move(name);
621 } else {
622 error += "Unknown 'name';";
623 }
624
625 std::unique_ptr<PtJson> value;
626 ret = params.GetObject("value", &value);
627 std::unique_ptr<RemoteObject> obj;
628 if (ret == Result::SUCCESS) {
629 obj = RemoteObject::Create(*value);
630 if (obj == nullptr) {
631 error += "'value' format error;";
632 } else {
633 privatePropertyDescriptor->value_ = std::move(obj);
634 }
635 } else if (ret == Result::TYPE_ERROR) {
636 error += "Unknown 'value';";
637 }
638
639 std::unique_ptr<PtJson> get;
640 ret = params.GetObject("get", &get);
641 if (ret == Result::SUCCESS) {
642 obj = RemoteObject::Create(*get);
643 if (obj == nullptr) {
644 error += "'get' format error;";
645 } else {
646 privatePropertyDescriptor->get_ = std::move(obj);
647 }
648 } else if (ret == Result::TYPE_ERROR) {
649 error += "Unknown 'get';";
650 }
651
652 std::unique_ptr<PtJson> set;
653 ret = params.GetObject("set", &set);
654 if (ret == Result::SUCCESS) {
655 obj = RemoteObject::Create(*set);
656 if (obj == nullptr) {
657 error += "'set' format error;";
658 } else {
659 privatePropertyDescriptor->set_ = std::move(obj);
660 }
661 } else if (ret == Result::TYPE_ERROR) {
662 error += "Unknown 'set';";
663 }
664
665 if (!error.empty()) {
666 LOG(ERROR, DEBUGGER) << "PrivatePropertyDescriptor::Create " << error;
667 return nullptr;
668 }
669
670 return privatePropertyDescriptor;
671 }
672
ToJson() const673 std::unique_ptr<PtJson> PrivatePropertyDescriptor::ToJson() const
674 {
675 std::unique_ptr<PtJson> result = PtJson::CreateObject();
676
677 result->Add("name", name_.c_str());
678 if (value_) {
679 ASSERT(value_.value() != nullptr);
680 result->Add("value", value_.value()->ToJson());
681 }
682 if (get_) {
683 ASSERT(get_.value() != nullptr);
684 result->Add("get", get_.value()->ToJson());
685 }
686 if (set_) {
687 ASSERT(set_.value() != nullptr);
688 result->Add("set", set_.value()->ToJson());
689 }
690
691 return result;
692 }
693
FromProperty(const EcmaVM * ecmaVm,Local<JSValueRef> name,const PropertyAttribute & property)694 std::unique_ptr<PropertyDescriptor> PropertyDescriptor::FromProperty(const EcmaVM *ecmaVm,
695 Local<JSValueRef> name, const PropertyAttribute &property)
696 {
697 std::unique_ptr<PropertyDescriptor> debuggerProperty = std::make_unique<PropertyDescriptor>();
698
699 std::string nameStr;
700 if (name->IsSymbol()) {
701 Local<SymbolRef> symbol(name);
702 nameStr = "Symbol(" + Local<SymbolRef>(name)->GetDescription(ecmaVm)->ToString() + ")";
703 debuggerProperty->symbol_ = RemoteObject::FromTagged(ecmaVm, name);
704 } else {
705 nameStr = name->ToString(ecmaVm)->ToString();
706 }
707
708 debuggerProperty->name_ = nameStr;
709 if (property.HasValue()) {
710 debuggerProperty->value_ = RemoteObject::FromTagged(ecmaVm, property.GetValue(ecmaVm));
711 }
712 if (property.HasWritable()) {
713 debuggerProperty->writable_ = property.IsWritable();
714 }
715 if (property.HasGetter()) {
716 debuggerProperty->get_ = RemoteObject::FromTagged(ecmaVm, property.GetGetter(ecmaVm));
717 }
718 if (property.HasSetter()) {
719 debuggerProperty->set_ = RemoteObject::FromTagged(ecmaVm, property.GetSetter(ecmaVm));
720 }
721 debuggerProperty->configurable_ = property.IsConfigurable();
722 debuggerProperty->enumerable_ = property.IsEnumerable();
723 debuggerProperty->isOwn_ = true;
724
725 return debuggerProperty;
726 }
727
Create(const PtJson & params)728 std::unique_ptr<PropertyDescriptor> PropertyDescriptor::Create(const PtJson ¶ms)
729 {
730 std::string error;
731 auto propertyDescriptor = std::make_unique<PropertyDescriptor>();
732 Result ret;
733
734 std::string name;
735 ret = params.GetString("name", &name);
736 if (ret == Result::SUCCESS) {
737 propertyDescriptor->name_ = std::move(name);
738 } else {
739 error += "Unknown 'name';";
740 }
741
742 std::unique_ptr<PtJson> value;
743 std::unique_ptr<RemoteObject> obj;
744 ret = params.GetObject("value", &value);
745 if (ret == Result::SUCCESS) {
746 obj = RemoteObject::Create(*value);
747 if (obj == nullptr) {
748 error += "'value' format error;";
749 } else {
750 propertyDescriptor->value_ = std::move(obj);
751 }
752 } else if (ret == Result::TYPE_ERROR) {
753 error += "Unknown 'value';";
754 }
755
756 bool writable;
757 ret = params.GetBool("writable", &writable);
758 if (ret == Result::SUCCESS) {
759 propertyDescriptor->writable_ = writable;
760 } else if (ret == Result::TYPE_ERROR) {
761 error += "Unknown 'writable';";
762 }
763
764 std::unique_ptr<PtJson> get;
765 ret = params.GetObject("get", &get);
766 if (ret == Result::SUCCESS) {
767 obj = RemoteObject::Create(*get);
768 if (obj == nullptr) {
769 error += "'get' format error;";
770 } else {
771 propertyDescriptor->get_ = std::move(obj);
772 }
773 } else if (ret == Result::TYPE_ERROR) {
774 error += "Unknown 'get';";
775 }
776
777 std::unique_ptr<PtJson> set;
778 ret = params.GetObject("set", &set);
779 if (ret == Result::SUCCESS) {
780 obj = RemoteObject::Create(*set);
781 if (obj == nullptr) {
782 error += "'set' format error;";
783 } else {
784 propertyDescriptor->set_ = std::move(obj);
785 }
786 } else if (ret == Result::TYPE_ERROR) {
787 error += "Unknown 'set';";
788 }
789
790 bool configurable;
791 ret = params.GetBool("configurable", &configurable);
792 if (ret == Result::SUCCESS) {
793 propertyDescriptor->configurable_ = configurable;
794 } else if (ret == Result::TYPE_ERROR) {
795 error += "Unknown 'configurable';";
796 }
797
798 bool enumerable;
799 ret = params.GetBool("enumerable", &enumerable);
800 if (ret == Result::SUCCESS) {
801 propertyDescriptor->enumerable_ = enumerable;
802 } else if (ret == Result::TYPE_ERROR) {
803 error += "Unknown 'enumerable';";
804 }
805
806 bool wasThrown;
807 ret = params.GetBool("wasThrown", &wasThrown);
808 if (ret == Result::SUCCESS) {
809 propertyDescriptor->wasThrown_ = wasThrown;
810 } else if (ret == Result::TYPE_ERROR) {
811 error += "Unknown 'wasThrown';";
812 }
813
814 bool isOwn;
815 ret = params.GetBool("isOwn", &isOwn);
816 if (ret == Result::SUCCESS) {
817 propertyDescriptor->isOwn_ = isOwn;
818 } else if (ret == Result::TYPE_ERROR) {
819 error += "Unknown 'isOwn';";
820 }
821
822 std::unique_ptr<PtJson> symbol;
823 ret = params.GetObject("symbol", &symbol);
824 if (ret == Result::SUCCESS) {
825 obj = RemoteObject::Create(*symbol);
826 if (obj == nullptr) {
827 error += "'symbol' format error;";
828 } else {
829 propertyDescriptor->symbol_ = std::move(obj);
830 }
831 } else if (ret == Result::TYPE_ERROR) {
832 error += "Unknown 'symbol';";
833 }
834
835 if (!error.empty()) {
836 LOG(ERROR, DEBUGGER) << "PropertyDescriptor::Create " << error;
837 return nullptr;
838 }
839
840 return propertyDescriptor;
841 }
842
ToJson() const843 std::unique_ptr<PtJson> PropertyDescriptor::ToJson() const
844 {
845 std::unique_ptr<PtJson> result = PtJson::CreateObject();
846
847 result->Add("name", name_.c_str());
848 if (value_) {
849 ASSERT(value_.value() != nullptr);
850 result->Add("value", value_.value()->ToJson());
851 }
852 if (writable_) {
853 result->Add("writable", writable_.value());
854 }
855 if (get_) {
856 ASSERT(get_.value() != nullptr);
857 result->Add("get", get_.value()->ToJson());
858 }
859 if (set_) {
860 ASSERT(set_.value() != nullptr);
861 result->Add("set", set_.value()->ToJson());
862 }
863 result->Add("configurable", configurable_);
864 result->Add("enumerable", enumerable_);
865 if (wasThrown_) {
866 result->Add("wasThrown", wasThrown_.value());
867 }
868 if (isOwn_) {
869 result->Add("isOwn", isOwn_.value());
870 }
871 if (symbol_) {
872 ASSERT(symbol_.value() != nullptr);
873 result->Add("symbol", symbol_.value()->ToJson());
874 }
875
876 return result;
877 }
878
Create(const PtJson & params)879 std::unique_ptr<CallArgument> CallArgument::Create(const PtJson ¶ms)
880 {
881 auto callArgument = std::make_unique<CallArgument>();
882 std::string error;
883 Result ret;
884
885 std::string unserializableValue;
886 ret = params.GetString("unserializableValue", &unserializableValue);
887 if (ret == Result::SUCCESS) {
888 callArgument->unserializableValue_ = std::move(unserializableValue);
889 } else if (ret == Result::TYPE_ERROR) { // optional value
890 error += "Unknown 'unserializableValue';";
891 }
892 std::string objectId;
893 ret = params.GetString("objectId", &objectId);
894 if (ret == Result::SUCCESS) {
895 callArgument->objectId_ = std::stoi(objectId);
896 } else if (ret == Result::TYPE_ERROR) { // optional value
897 error += "Unknown 'objectId';";
898 }
899
900 if (!error.empty()) {
901 LOG(ERROR, DEBUGGER) << "CallArgument::Create " << error;
902 return nullptr;
903 }
904
905 return callArgument;
906 }
907
ToJson() const908 std::unique_ptr<PtJson> CallArgument::ToJson() const
909 {
910 std::unique_ptr<PtJson> result = PtJson::CreateObject();
911
912 if (unserializableValue_) {
913 result->Add("unserializableValue", unserializableValue_->c_str());
914 }
915 if (objectId_) {
916 result->Add("objectId", std::to_string(objectId_.value()).c_str());
917 }
918
919 return result;
920 }
921
Create(const PtJson & params)922 std::unique_ptr<Location> Location::Create(const PtJson ¶ms)
923 {
924 auto location = std::make_unique<Location>();
925 std::string error;
926 Result ret;
927
928 std::string scriptId;
929 ret = params.GetString("scriptId", &scriptId);
930 if (ret == Result::SUCCESS) {
931 location->scriptId_ = std::stoi(scriptId);
932 } else {
933 error += "Unknown 'scriptId';";
934 }
935 int32_t lineNumber;
936 ret = params.GetInt("lineNumber", &lineNumber);
937 if (ret == Result::SUCCESS) {
938 location->lineNumber_ = lineNumber;
939 } else {
940 error += "Unknown 'lineNumber';";
941 }
942 int32_t columnNumber;
943 ret = params.GetInt("columnNumber", &columnNumber);
944 if (ret == Result::SUCCESS) {
945 location->columnNumber_ = columnNumber;
946 } else if (ret == Result::TYPE_ERROR) { // optional value
947 error += "Unknown 'columnNumber';";
948 }
949
950 if (!error.empty()) {
951 LOG(ERROR, DEBUGGER) << "Location::Create " << error;
952 return nullptr;
953 }
954
955 return location;
956 }
957
ToJson() const958 std::unique_ptr<PtJson> Location::ToJson() const
959 {
960 std::unique_ptr<PtJson> result = PtJson::CreateObject();
961
962 result->Add("scriptId", std::to_string(scriptId_).c_str());
963 result->Add("lineNumber", lineNumber_);
964 if (columnNumber_) {
965 result->Add("columnNumber", columnNumber_.value());
966 }
967
968 return result;
969 }
970
Create(const PtJson & params)971 std::unique_ptr<ScriptPosition> ScriptPosition::Create(const PtJson ¶ms)
972 {
973 auto scriptPosition = std::make_unique<ScriptPosition>();
974 std::string error;
975 Result ret;
976
977 int32_t lineNumber;
978 ret = params.GetInt("lineNumber", &lineNumber);
979 if (ret == Result::SUCCESS) {
980 scriptPosition->lineNumber_ = lineNumber;
981 } else {
982 error += "Unknown 'lineNumber';";
983 }
984 int32_t columnNumber;
985 ret = params.GetInt("columnNumber", &columnNumber);
986 if (ret == Result::SUCCESS) {
987 scriptPosition->columnNumber_ = columnNumber;
988 } else {
989 error += "Unknown 'columnNumber';";
990 }
991
992 if (!error.empty()) {
993 LOG(ERROR, DEBUGGER) << "ScriptPosition::Create " << error;
994 return nullptr;
995 }
996
997 return scriptPosition;
998 }
999
ToJson() const1000 std::unique_ptr<PtJson> ScriptPosition::ToJson() const
1001 {
1002 std::unique_ptr<PtJson> result = PtJson::CreateObject();
1003
1004 result->Add("lineNumber", lineNumber_);
1005 result->Add("columnNumber", columnNumber_);
1006
1007 return result;
1008 }
1009
Create(const PtJson & params)1010 std::unique_ptr<SearchMatch> SearchMatch::Create(const PtJson ¶ms)
1011 {
1012 std::string error;
1013 auto locationSearch = std::make_unique<SearchMatch>();
1014 Result ret;
1015
1016 int32_t lineNumber;
1017 ret = params.GetInt("lineNumber", &lineNumber);
1018 if (ret == Result::SUCCESS) {
1019 locationSearch->lineNumber_ = lineNumber;
1020 } else {
1021 error += "Unknown 'lineNumber';";
1022 }
1023
1024 std::string lineContent;
1025 ret = params.GetString("lineContent", &lineContent);
1026 if (ret == Result::SUCCESS) {
1027 locationSearch->lineContent_ = std::move(lineContent);
1028 } else {
1029 error += "Unknown 'lineContent';";
1030 }
1031
1032 if (!error.empty()) {
1033 LOG(ERROR, DEBUGGER) << "SearchMatch::Create " << error;
1034 return nullptr;
1035 }
1036
1037 return locationSearch;
1038 }
1039
ToJson() const1040 std::unique_ptr<PtJson> SearchMatch::ToJson() const
1041 {
1042 std::unique_ptr<PtJson> result = PtJson::CreateObject();
1043
1044 result->Add("lineNumber", lineNumber_);
1045 result->Add("lineContent", lineContent_.c_str());
1046
1047 return result;
1048 }
1049
Create(const PtJson & params)1050 std::unique_ptr<LocationRange> LocationRange::Create(const PtJson ¶ms)
1051 {
1052 std::string error;
1053 auto locationRange = std::make_unique<LocationRange>();
1054 Result ret;
1055
1056 std::string scriptId;
1057 ret = params.GetString("scriptId", &scriptId);
1058 if (ret == Result::SUCCESS) {
1059 locationRange->scriptId_ = std::stoi(scriptId);
1060 } else {
1061 error += "Unknown 'scriptId';";
1062 }
1063
1064 std::unique_ptr<PtJson> start;
1065 std::unique_ptr<ScriptPosition> obj;
1066 ret = params.GetObject("start", &start);
1067 if (ret == Result::SUCCESS) {
1068 obj = ScriptPosition::Create(*start);
1069 if (obj == nullptr) {
1070 error += "'start' format error;";
1071 } else {
1072 locationRange->start_ = std::move(obj);
1073 }
1074 } else {
1075 error += "Unknown 'start';";
1076 }
1077
1078 std::unique_ptr<PtJson> end;
1079 ret = params.GetObject("end", &end);
1080 if (ret == Result::SUCCESS) {
1081 obj = ScriptPosition::Create(*end);
1082 if (obj == nullptr) {
1083 error += "'end' format error;";
1084 } else {
1085 locationRange->end_ = std::move(obj);
1086 }
1087 } else {
1088 error += "Unknown 'end';";
1089 }
1090
1091 if (!error.empty()) {
1092 LOG(ERROR, DEBUGGER) << "LocationRange::Create " << error;
1093 return nullptr;
1094 }
1095
1096 return locationRange;
1097 }
1098
ToJson() const1099 std::unique_ptr<PtJson> LocationRange::ToJson() const
1100 {
1101 std::unique_ptr<PtJson> result = PtJson::CreateObject();
1102
1103 result->Add("scriptId", std::to_string(scriptId_).c_str());
1104 ASSERT(start_ != nullptr);
1105 result->Add("start", start_->ToJson());
1106 ASSERT(end_ != nullptr);
1107 result->Add("end", end_->ToJson());
1108
1109 return result;
1110 }
1111
Create(const PtJson & params)1112 std::unique_ptr<BreakLocation> BreakLocation::Create(const PtJson ¶ms)
1113 {
1114 std::string error;
1115 auto breakLocation = std::make_unique<BreakLocation>();
1116 Result ret;
1117
1118 std::string scriptId;
1119 ret = params.GetString("scriptId", &scriptId);
1120 if (ret == Result::SUCCESS) {
1121 breakLocation->scriptId_ = std::stoi(scriptId);
1122 } else {
1123 error += "Unknown 'scriptId';";
1124 }
1125
1126 int32_t lineNumber;
1127 ret = params.GetInt("lineNumber", &lineNumber);
1128 if (ret == Result::SUCCESS) {
1129 breakLocation->lineNumber_ = lineNumber;
1130 } else {
1131 error += "Unknown 'lineNumber';";
1132 }
1133
1134 int32_t columnNumber;
1135 ret = params.GetInt("columnNumber", &columnNumber);
1136 if (ret == Result::SUCCESS) {
1137 breakLocation->columnNumber_ = columnNumber;
1138 } else if (ret == Result::TYPE_ERROR) {
1139 error += "Unknown 'columnNumber';";
1140 }
1141
1142 std::string type;
1143 ret = params.GetString("type", &type);
1144 if (ret == Result::SUCCESS) {
1145 if (BreakType::Valid(type)) {
1146 breakLocation->type_ = std::move(type);
1147 } else {
1148 error += "'type' is invalid;";
1149 }
1150 } else if (ret == Result::TYPE_ERROR) {
1151 error += "type 'scriptId';";
1152 }
1153
1154 if (!error.empty()) {
1155 LOG(ERROR, DEBUGGER) << "Location::Create " << error;
1156 return nullptr;
1157 }
1158
1159 return breakLocation;
1160 }
1161
ToJson() const1162 std::unique_ptr<PtJson> BreakLocation::ToJson() const
1163 {
1164 std::unique_ptr<PtJson> result = PtJson::CreateObject();
1165
1166 result->Add("scriptId", std::to_string(scriptId_).c_str());
1167 result->Add("lineNumber", lineNumber_);
1168 if (columnNumber_) {
1169 result->Add("columnNumber", columnNumber_.value());
1170 }
1171 if (type_) {
1172 result->Add("type", type_->c_str());
1173 }
1174
1175 return result;
1176 }
1177
Create(const PtJson & params)1178 std::unique_ptr<Scope> Scope::Create(const PtJson ¶ms)
1179 {
1180 std::string error;
1181 auto scope = std::make_unique<Scope>();
1182 Result ret;
1183
1184 std::string type;
1185 ret = params.GetString("type", &type);
1186 if (ret == Result::SUCCESS) {
1187 if (Scope::Type::Valid(type)) {
1188 scope->type_ = std::move(type);
1189 } else {
1190 error += "'type' is invalid;";
1191 }
1192 } else {
1193 error += "Unknown 'type';";
1194 }
1195
1196 std::unique_ptr<PtJson> object;
1197 std::unique_ptr<RemoteObject> remoteObject;
1198 ret = params.GetObject("object", &object);
1199 if (ret == Result::SUCCESS) {
1200 remoteObject = RemoteObject::Create(*object);
1201 if (remoteObject == nullptr) {
1202 error += "'object' format error;";
1203 } else {
1204 scope->object_ = std::move(remoteObject);
1205 }
1206 } else {
1207 error += "Unknown 'object';";
1208 }
1209
1210 std::string name;
1211 ret = params.GetString("name", &name);
1212 if (ret == Result::SUCCESS) {
1213 scope->name_ = std::move(name);
1214 } else if (ret == Result::TYPE_ERROR) {
1215 error += "Unknown 'name';";
1216 }
1217
1218 std::unique_ptr<PtJson> startLocation;
1219 std::unique_ptr<Location> obj;
1220 ret = params.GetObject("startLocation", &startLocation);
1221 if (ret == Result::SUCCESS) {
1222 obj = Location::Create(*startLocation);
1223 if (obj == nullptr) {
1224 error += "'startLocation' format error;";
1225 } else {
1226 scope->startLocation_ = std::move(obj);
1227 }
1228 } else if (ret == Result::TYPE_ERROR) {
1229 error += "Unknown 'startLocation';";
1230 }
1231
1232 std::unique_ptr<PtJson> endLocation;
1233 ret = params.GetObject("endLocation", &endLocation);
1234 if (ret == Result::SUCCESS) {
1235 obj = Location::Create(*endLocation);
1236 if (obj == nullptr) {
1237 error += "'endLocation' format error;";
1238 } else {
1239 scope->endLocation_ = std::move(obj);
1240 }
1241 } else if (ret == Result::TYPE_ERROR) {
1242 error += "Unknown 'endLocation';";
1243 }
1244
1245 if (!error.empty()) {
1246 LOG(ERROR, DEBUGGER) << "Location::Create " << error;
1247 return nullptr;
1248 }
1249
1250 return scope;
1251 }
1252
ToJson() const1253 std::unique_ptr<PtJson> Scope::ToJson() const
1254 {
1255 std::unique_ptr<PtJson> result = PtJson::CreateObject();
1256
1257 result->Add("type", type_.c_str());
1258 ASSERT(object_ != nullptr);
1259 result->Add("object", object_->ToJson());
1260 if (name_) {
1261 result->Add("name", name_->c_str());
1262 }
1263 if (startLocation_) {
1264 ASSERT(startLocation_.value() != nullptr);
1265 result->Add("startLocation", startLocation_.value()->ToJson());
1266 }
1267 if (endLocation_) {
1268 ASSERT(endLocation_.value() != nullptr);
1269 result->Add("endLocation", endLocation_.value()->ToJson());
1270 }
1271
1272 return result;
1273 }
1274
Create(const PtJson & params)1275 std::unique_ptr<CallFrame> CallFrame::Create(const PtJson ¶ms)
1276 {
1277 std::string error;
1278 auto callFrame = std::make_unique<CallFrame>();
1279 Result ret;
1280
1281 std::string callFrameId;
1282 ret = params.GetString("callFrameId", &callFrameId);
1283 if (ret == Result::SUCCESS) {
1284 callFrame->callFrameId_ = std::stoi(callFrameId);
1285 } else {
1286 error += "Unknown 'callFrameId';";
1287 }
1288
1289 std::string functionName;
1290 ret = params.GetString("functionName", &functionName);
1291 if (ret == Result::SUCCESS) {
1292 callFrame->functionName_ = std::move(functionName);
1293 } else {
1294 error += "Unknown 'functionName';";
1295 }
1296
1297 std::unique_ptr<PtJson> functionLocation;
1298 std::unique_ptr<Location> obj;
1299 ret = params.GetObject("functionLocation", &functionLocation);
1300 if (ret == Result::SUCCESS) {
1301 obj = Location::Create(*functionLocation);
1302 if (obj == nullptr) {
1303 error += "'functionLocation' format error;";
1304 } else {
1305 callFrame->functionLocation_ = std::move(obj);
1306 }
1307 } else if (ret == Result::TYPE_ERROR) {
1308 error += "Unknown 'functionLocation';";
1309 }
1310
1311 std::unique_ptr<PtJson> location;
1312 ret = params.GetObject("location", &location);
1313 if (ret == Result::SUCCESS) {
1314 obj = Location::Create(*location);
1315 if (obj == nullptr) {
1316 error += "'location' format error;";
1317 } else {
1318 callFrame->location_ = std::move(obj);
1319 }
1320 } else {
1321 error += "Unknown 'location';";
1322 }
1323
1324 std::string url;
1325 ret = params.GetString("url", &url);
1326 if (ret == Result::SUCCESS) {
1327 callFrame->url_ = std::move(url);
1328 } else {
1329 error += "Unknown 'url';";
1330 }
1331
1332 std::unique_ptr<PtJson> scopeChain;
1333 ret = params.GetArray("scopeChain", &scopeChain);
1334 if (ret == Result::SUCCESS) {
1335 int32_t len = scopeChain->GetSize();
1336 for (int32_t i = 0; i < len; ++i) {
1337 std::unique_ptr<PtJson> arrayEle = scopeChain->Get(i);
1338 ASSERT(arrayEle != nullptr);
1339 std::unique_ptr<Scope> scope = Scope::Create(*arrayEle);
1340 if (scope == nullptr) {
1341 error += "'scopeChain' format error;";
1342 } else {
1343 callFrame->scopeChain_.emplace_back(std::move(scope));
1344 }
1345 }
1346 } else {
1347 error += "Unknown 'scopeChain';";
1348 }
1349
1350 std::unique_ptr<PtJson> thisObj;
1351 std::unique_ptr<RemoteObject> remoteObject;
1352 ret = params.GetObject("this", &thisObj);
1353 if (ret == Result::SUCCESS) {
1354 remoteObject = RemoteObject::Create(*thisObj);
1355 if (remoteObject == nullptr) {
1356 error += "'this' format error;";
1357 } else {
1358 callFrame->this_ = std::move(remoteObject);
1359 }
1360 } else {
1361 error += "Unknown 'this';";
1362 }
1363
1364 std::unique_ptr<PtJson> returnValue;
1365 ret = params.GetObject("returnValue", &returnValue);
1366 if (ret == Result::SUCCESS) {
1367 remoteObject = RemoteObject::Create(*returnValue);
1368 if (remoteObject == nullptr) {
1369 error += "'returnValue' format error;";
1370 } else {
1371 callFrame->returnValue_ = std::move(remoteObject);
1372 }
1373 } else if (ret == Result::TYPE_ERROR) {
1374 error += "Unknown 'returnValue';";
1375 }
1376
1377 if (!error.empty()) {
1378 LOG(ERROR, DEBUGGER) << "CallFrame::Create " << error;
1379 return nullptr;
1380 }
1381
1382 return callFrame;
1383 }
1384
ToJson() const1385 std::unique_ptr<PtJson> CallFrame::ToJson() const
1386 {
1387 std::unique_ptr<PtJson> result = PtJson::CreateObject();
1388
1389 result->Add("callFrameId", std::to_string(callFrameId_).c_str());
1390 result->Add("functionName", functionName_.c_str());
1391
1392 if (functionLocation_) {
1393 ASSERT(functionLocation_.value() != nullptr);
1394 result->Add("functionLocation", functionLocation_.value()->ToJson());
1395 }
1396 ASSERT(location_ != nullptr);
1397 result->Add("location", location_->ToJson());
1398 result->Add("url", url_.c_str());
1399
1400 size_t len = scopeChain_.size();
1401 std::unique_ptr<PtJson> values = PtJson::CreateArray();
1402 for (size_t i = 0; i < len; i++) {
1403 std::unique_ptr<PtJson> scope = scopeChain_[i]->ToJson();
1404 values->Push(scope);
1405 }
1406 result->Add("scopeChain", values);
1407
1408 ASSERT(this_ != nullptr);
1409 result->Add("this", this_->ToJson());
1410 if (returnValue_) {
1411 ASSERT(returnValue_.value() != nullptr);
1412 result->Add("returnValue", returnValue_.value()->ToJson());
1413 }
1414
1415 return result;
1416 }
1417
1418 #ifdef SUPPORT_PROFILER_CDP
Create(const PtJson & params)1419 std::unique_ptr<SamplingHeapProfileSample> SamplingHeapProfileSample::Create(const PtJson ¶ms)
1420 {
1421 std::string error;
1422 auto samplingHeapProfileSample = std::make_unique<SamplingHeapProfileSample>();
1423 Result ret;
1424
1425 int32_t size;
1426 ret = params.GetInt("size", &size);
1427 if (ret == Result::SUCCESS) {
1428 samplingHeapProfileSample->size_ = size;
1429 } else {
1430 error += "Unknown 'size';";
1431 }
1432 int32_t nodeId;
1433 ret = params.GetInt("nodeId", &nodeId);
1434 if (ret == Result::SUCCESS) {
1435 samplingHeapProfileSample->nodeId_ = nodeId;
1436 } else {
1437 error += "Unknown 'nodeId';";
1438 }
1439 int32_t ordinal;
1440 ret = params.GetInt("ordinal", &ordinal);
1441 if (ret == Result::SUCCESS) {
1442 samplingHeapProfileSample->ordinal_ = ordinal;
1443 } else {
1444 error += "Unknown 'ordinal';";
1445 }
1446 if (!error.empty()) {
1447 LOG(ERROR, DEBUGGER) << "SamplingHeapProfileSample::Create " << error;
1448 return nullptr;
1449 }
1450
1451 return samplingHeapProfileSample;
1452 }
1453
ToJson() const1454 std::unique_ptr<PtJson> SamplingHeapProfileSample::ToJson() const
1455 {
1456 std::unique_ptr<PtJson> result = PtJson::CreateObject();
1457
1458 result->Add("size", size_);
1459 result->Add("nodeId", nodeId_);
1460 result->Add("ordinal", ordinal_);
1461
1462 return result;
1463 }
1464
Create(const PtJson & params)1465 std::unique_ptr<RuntimeCallFrame> RuntimeCallFrame::Create(const PtJson ¶ms)
1466 {
1467 std::string error;
1468 auto runtimeCallFrame = std::make_unique<RuntimeCallFrame>();
1469 Result ret;
1470
1471 std::string functionName;
1472 ret = params.GetString("functionName", &functionName);
1473 if (ret == Result::SUCCESS) {
1474 runtimeCallFrame->functionName_ = std::move(functionName);
1475 } else {
1476 error += "Unknown 'functionName';";
1477 }
1478
1479 std::string scriptId;
1480 ret = params.GetString("scriptId", &scriptId);
1481 if (ret == Result::SUCCESS) {
1482 runtimeCallFrame->scriptId_ = std::move(scriptId);
1483 } else {
1484 error += "Unknown 'scriptId';";
1485 }
1486
1487 std::string url;
1488 ret = params.GetString("url", &url);
1489 if (ret == Result::SUCCESS) {
1490 runtimeCallFrame->url_ = std::move(url);
1491 } else {
1492 error += "Unknown 'url';";
1493 }
1494
1495 int32_t lineNumber;
1496 ret = params.GetInt("lineNumber", &lineNumber);
1497 if (ret == Result::SUCCESS) {
1498 runtimeCallFrame->lineNumber_ = lineNumber;
1499 } else {
1500 error += "Unknown 'lineNumber';";
1501 }
1502
1503 int32_t columnNumber;
1504 ret = params.GetInt("columnNumber", &columnNumber);
1505 if (ret == Result::SUCCESS) {
1506 runtimeCallFrame->columnNumber_ = columnNumber;
1507 } else {
1508 error += "Unknown 'columnNumber';";
1509 }
1510 if (!error.empty()) {
1511 LOG(ERROR, DEBUGGER) << "RuntimeCallFrame::Create " << error;
1512 return nullptr;
1513 }
1514
1515 return runtimeCallFrame;
1516 }
1517
FromFrameInfo(const FrameInfo & cpuFrameInfo)1518 std::unique_ptr<RuntimeCallFrame> RuntimeCallFrame::FromFrameInfo(const FrameInfo &cpuFrameInfo)
1519 {
1520 auto runtimeCallFrame = std::make_unique<RuntimeCallFrame>();
1521 runtimeCallFrame->SetFunctionName(cpuFrameInfo.functionName);
1522 runtimeCallFrame->SetScriptId(std::to_string(cpuFrameInfo.scriptId));
1523 runtimeCallFrame->SetColumnNumber(cpuFrameInfo.columnNumber);
1524 runtimeCallFrame->SetLineNumber(cpuFrameInfo.lineNumber);
1525 runtimeCallFrame->SetUrl(cpuFrameInfo.url);
1526 return runtimeCallFrame;
1527 }
1528
ToJson() const1529 std::unique_ptr<PtJson> RuntimeCallFrame::ToJson() const
1530 {
1531 std::unique_ptr<PtJson> result = PtJson::CreateObject();
1532
1533 result->Add("functionName", functionName_.c_str());
1534 result->Add("scriptId", scriptId_.c_str());
1535 result->Add("url", url_.c_str());
1536 result->Add("lineNumber", lineNumber_);
1537 result->Add("columnNumber", columnNumber_);
1538
1539 return result;
1540 }
1541
Create(const PtJson & params)1542 std::unique_ptr<SamplingHeapProfileNode> SamplingHeapProfileNode::Create(const PtJson ¶ms)
1543 {
1544 std::string error;
1545 auto samplingHeapProfileNode = std::make_unique<SamplingHeapProfileNode>();
1546 Result ret;
1547
1548 std::unique_ptr<PtJson> callFrame;
1549 ret = params.GetObject("callFrame", &callFrame);
1550 if (ret == Result::SUCCESS) {
1551 std::unique_ptr<RuntimeCallFrame> runtimeCallFrame = RuntimeCallFrame::Create(*callFrame);
1552 if (runtimeCallFrame == nullptr) {
1553 error += "'callFrame' format invalid;";
1554 } else {
1555 samplingHeapProfileNode->callFrame_ = std::move(runtimeCallFrame);
1556 }
1557 } else {
1558 error += "Unknown 'callFrame';";
1559 }
1560
1561 int32_t selfSize;
1562 ret = params.GetInt("selfSize", &selfSize);
1563 if (ret == Result::SUCCESS) {
1564 samplingHeapProfileNode->selfSize_ = selfSize;
1565 } else {
1566 error += "Unknown 'selfSize';";
1567 }
1568
1569 int32_t id;
1570 ret = params.GetInt("id", &id);
1571 if (ret == Result::SUCCESS) {
1572 samplingHeapProfileNode->id_ = id;
1573 } else {
1574 error += "Unknown 'id';";
1575 }
1576
1577 std::unique_ptr<PtJson> children;
1578 ret = params.GetArray("children", &children);
1579 if (ret == Result::SUCCESS) {
1580 int32_t len = children->GetSize();
1581 for (int32_t i = 0; i < len; ++i) {
1582 std::unique_ptr<PtJson> arrayEle = children->Get(i);
1583 ASSERT(arrayEle != nullptr);
1584 std::unique_ptr<SamplingHeapProfileNode> node = SamplingHeapProfileNode::Create(*arrayEle);
1585 if (node == nullptr) {
1586 error += "'children' format invalid;";
1587 } else {
1588 samplingHeapProfileNode->children_.emplace_back(std::move(node));
1589 }
1590 }
1591 } else {
1592 error += "Unknown 'children';";
1593 }
1594
1595 if (!error.empty()) {
1596 LOG(ERROR, DEBUGGER) << "SamplingHeapProfileNode::Create " << error;
1597 return nullptr;
1598 }
1599
1600 return samplingHeapProfileNode;
1601 }
1602
ToJson() const1603 std::unique_ptr<PtJson> SamplingHeapProfileNode::ToJson() const
1604 {
1605 std::unique_ptr<PtJson> result = PtJson::CreateObject();
1606 ASSERT(callFrame_ != nullptr);
1607 result->Add("callFrame", callFrame_->ToJson());
1608 result->Add("selfSize", selfSize_);
1609 result->Add("id", id_);
1610
1611 std::unique_ptr<PtJson> childrens = PtJson::CreateArray();
1612 size_t len = children_.size();
1613 for (size_t i = 0; i < len; i++) {
1614 childrens->Push(children_[i]->ToJson());
1615 }
1616 result->Add("children", childrens);
1617
1618 return result;
1619 }
1620
Create(const PtJson & params)1621 std::unique_ptr<SamplingHeapProfile> SamplingHeapProfile::Create(const PtJson ¶ms)
1622 {
1623 std::string error;
1624 auto samplingHeapProfile = std::make_unique<SamplingHeapProfile>();
1625 Result ret;
1626
1627 std::unique_ptr<PtJson> head;
1628 ret = params.GetObject("head", &head);
1629 if (ret == Result::SUCCESS) {
1630 std::unique_ptr<SamplingHeapProfileNode> pHead = SamplingHeapProfileNode::Create(*head);
1631 if (pHead == nullptr) {
1632 error += "'sample' format invalid;";
1633 } else {
1634 samplingHeapProfile->head_ = std::move(pHead);
1635 }
1636 } else {
1637 error += "Unknown 'head';";
1638 }
1639
1640 std::unique_ptr<PtJson> samples;
1641 ret = params.GetArray("samples", &samples);
1642 if (ret == Result::SUCCESS) {
1643 int32_t len = samples->GetSize();
1644 for (int32_t i = 0; i < len; ++i) {
1645 std::unique_ptr<PtJson> arrayEle = samples->Get(i);
1646 ASSERT(arrayEle != nullptr);
1647 std::unique_ptr<SamplingHeapProfileSample> pSample = SamplingHeapProfileSample::Create(*arrayEle);
1648 if (pSample == nullptr) {
1649 error += "'sample' format invalid;";
1650 } else {
1651 samplingHeapProfile->samples_.emplace_back(std::move(pSample));
1652 }
1653 }
1654 } else {
1655 error += "Unknown 'samples';";
1656 }
1657
1658 if (!error.empty()) {
1659 LOG(ERROR, DEBUGGER) << "SamplingHeapProfile::Create " << error;
1660 return nullptr;
1661 }
1662
1663 return samplingHeapProfile;
1664 }
1665
ToJson() const1666 std::unique_ptr<PtJson> SamplingHeapProfile::ToJson() const
1667 {
1668 std::unique_ptr<PtJson> result = PtJson::CreateObject();
1669
1670 ASSERT(head_ != nullptr);
1671 result->Add("head", head_->ToJson());
1672
1673 std::unique_ptr<PtJson> samples = PtJson::CreateArray();
1674 size_t len = samples_.size();
1675 for (size_t i = 0; i < len; i++) {
1676 ASSERT(samples_[i] != nullptr);
1677 samples->Push(samples_[i]->ToJson());
1678 }
1679 result->Add("samples", samples);
1680 return result;
1681 }
1682
Create(const PtJson & params)1683 std::unique_ptr<PositionTickInfo> PositionTickInfo::Create(const PtJson ¶ms)
1684 {
1685 std::string error;
1686 auto positionTickInfo = std::make_unique<PositionTickInfo>();
1687 Result ret;
1688
1689 int32_t line;
1690 ret = params.GetInt("line", &line);
1691 if (ret == Result::SUCCESS) {
1692 positionTickInfo->line_ = line;
1693 } else {
1694 error += "Unknown 'line';";
1695 }
1696
1697 int32_t ticks;
1698 ret = params.GetInt("ticks", &ticks);
1699 if (ret == Result::SUCCESS) {
1700 positionTickInfo->ticks_ = ticks;
1701 } else {
1702 error += "Unknown 'ticks';";
1703 }
1704
1705 if (!error.empty()) {
1706 LOG(ERROR, DEBUGGER) << "PositionTickInfo::Create " << error;
1707 return nullptr;
1708 }
1709
1710 return positionTickInfo;
1711 }
1712
ToJson() const1713 std::unique_ptr<PtJson> PositionTickInfo::ToJson() const
1714 {
1715 std::unique_ptr<PtJson> result = PtJson::CreateObject();
1716
1717 result->Add("line", line_);
1718 result->Add("ticks", ticks_);
1719
1720 return result;
1721 }
1722
Create(const PtJson & params)1723 std::unique_ptr<ProfileNode> ProfileNode::Create(const PtJson ¶ms)
1724 {
1725 std::string error;
1726 auto profileNode = std::make_unique<ProfileNode>();
1727 Result ret;
1728
1729 int32_t id;
1730 ret = params.GetInt("id", &id);
1731 if (ret == Result::SUCCESS) {
1732 profileNode->id_ = id;
1733 } else {
1734 error += "Unknown 'id';";
1735 }
1736
1737 std::unique_ptr<PtJson> callFrame;
1738 ret = params.GetObject("callFrame", &callFrame);
1739 if (ret == Result::SUCCESS) {
1740 std::unique_ptr<RuntimeCallFrame> runtimeCallFrame = RuntimeCallFrame::Create(*callFrame);
1741 if (runtimeCallFrame == nullptr) {
1742 error += "'callFrame' format invalid;";
1743 } else {
1744 profileNode->callFrame_ = std::move(runtimeCallFrame);
1745 }
1746 } else {
1747 error += "Unknown 'callFrame';";
1748 }
1749
1750 int32_t hitCount;
1751 ret = params.GetInt("hitCount", &hitCount);
1752 if (ret == Result::SUCCESS) {
1753 profileNode->hitCount_ = hitCount;
1754 } else if (ret == Result::TYPE_ERROR) {
1755 error += "Unknown 'hitCount';";
1756 }
1757
1758 std::unique_ptr<PtJson> children;
1759 ret = params.GetArray("children", &children);
1760 if (ret == Result::SUCCESS) {
1761 int32_t childrenLen = children->GetSize();
1762 for (int32_t i = 0; i < childrenLen; ++i) {
1763 int32_t pChildren = children->Get(i)->GetInt();
1764 profileNode->children_.value().emplace_back(pChildren);
1765 }
1766 } else if (ret == Result::TYPE_ERROR) {
1767 error += "Unknown 'children';";
1768 }
1769
1770 std::unique_ptr<PtJson> positionTicks;
1771 ret = params.GetArray("positionTicks", &positionTicks);
1772 if (ret == Result::SUCCESS) {
1773 int32_t positionTicksLen = positionTicks->GetSize();
1774 for (int32_t i = 0; i < positionTicksLen; ++i) {
1775 std::unique_ptr<PtJson> arrayEle = positionTicks->Get(i);
1776 ASSERT(arrayEle != nullptr);
1777 std::unique_ptr<PositionTickInfo> tmpPositionTicks = PositionTickInfo::Create(*arrayEle);
1778 if (tmpPositionTicks == nullptr) {
1779 error += "'positionTicks' format invalid;";
1780 } else {
1781 profileNode->positionTicks_.value().emplace_back(std::move(tmpPositionTicks));
1782 }
1783 }
1784 } else if (ret == Result::TYPE_ERROR) {
1785 error += "Unknown 'positionTicks';";
1786 }
1787
1788 std::string deoptReason;
1789 ret = params.GetString("deoptReason", &deoptReason);
1790 if (ret == Result::SUCCESS) {
1791 profileNode->deoptReason_ = std::move(deoptReason);
1792 } else if (ret == Result::TYPE_ERROR) {
1793 error += "Unknown 'deoptReason';";
1794 }
1795
1796 if (!error.empty()) {
1797 LOG(ERROR, DEBUGGER) << "ProfileNode::Create " << error;
1798 return nullptr;
1799 }
1800
1801 return profileNode;
1802 }
1803
FromCpuProfileNode(const CpuProfileNode & cpuProfileNode)1804 std::unique_ptr<ProfileNode> ProfileNode::FromCpuProfileNode(const CpuProfileNode &cpuProfileNode)
1805 {
1806 auto profileNode = std::make_unique<ProfileNode>();
1807 profileNode->SetId(cpuProfileNode.id);
1808 profileNode->SetHitCount(cpuProfileNode.hitCount);
1809
1810 size_t childrenLen = cpuProfileNode.children.size();
1811 std::vector<int32_t> tmpChildren;
1812 tmpChildren.reserve(childrenLen);
1813 for (size_t i = 0; i < childrenLen; ++i) {
1814 tmpChildren.push_back(cpuProfileNode.children[i]);
1815 }
1816 profileNode->SetChildren(tmpChildren);
1817 profileNode->SetCallFrame(RuntimeCallFrame::FromFrameInfo(cpuProfileNode.codeEntry));
1818 return profileNode;
1819 }
1820
ToJson() const1821 std::unique_ptr<PtJson> ProfileNode::ToJson() const
1822 {
1823 std::unique_ptr<PtJson> result = PtJson::CreateObject();
1824
1825 result->Add("id", id_);
1826 ASSERT(callFrame_ != nullptr);
1827 result->Add("callFrame", callFrame_->ToJson());
1828 if (hitCount_) {
1829 result->Add("hitCount", hitCount_.value());
1830 }
1831 if (children_) {
1832 std::unique_ptr<PtJson> childrens = PtJson::CreateArray();
1833 size_t len = children_->size();
1834 for (size_t i = 0; i < len; i++) {
1835 childrens->Push(children_.value()[i]);
1836 }
1837 result->Add("children", childrens);
1838 }
1839 if (positionTicks_) {
1840 std::unique_ptr<PtJson> positionTicks = PtJson::CreateArray();
1841 size_t len = positionTicks_->size();
1842 for (size_t i = 0; i < len; i++) {
1843 ASSERT(positionTicks_.value()[i] != nullptr);
1844 positionTicks->Push(positionTicks_.value()[i]->ToJson());
1845 }
1846 result->Add("positionTicks", positionTicks);
1847 }
1848
1849 if (deoptReason_) {
1850 result->Add("deoptReason", deoptReason_.value().c_str());
1851 }
1852
1853 return result;
1854 }
1855
Create(const PtJson & params)1856 std::unique_ptr<Profile> Profile::Create(const PtJson ¶ms)
1857 {
1858 std::string error;
1859 auto profile = std::make_unique<Profile>();
1860 Result ret;
1861
1862 std::unique_ptr<PtJson> nodes;
1863 ret = params.GetArray("nodes", &nodes);
1864 if (ret == Result::SUCCESS) {
1865 int32_t nodesLen = nodes->GetSize();
1866 for (int32_t i = 0; i < nodesLen; ++i) {
1867 std::unique_ptr<PtJson> arrayEle = nodes->Get(i);
1868 ASSERT(arrayEle != nullptr);
1869 std::unique_ptr<ProfileNode> profileNode = ProfileNode::Create(*arrayEle);
1870 if (profileNode == nullptr) {
1871 error += "'nodes' format invalid;";
1872 } else {
1873 profile->nodes_.emplace_back(std::move(profileNode));
1874 }
1875 }
1876 } else {
1877 error += "Unknown 'nodes';";
1878 }
1879
1880 int64_t startTime;
1881 ret = params.GetInt64("startTime", &startTime);
1882 if (ret == Result::SUCCESS) {
1883 profile->startTime_ = startTime;
1884 } else {
1885 error += "Unknown 'startTime';";
1886 }
1887
1888 int64_t endTime;
1889 ret = params.GetInt64("endTime", &endTime);
1890 if (ret == Result::SUCCESS) {
1891 profile->endTime_ = endTime;
1892 } else {
1893 error += "Unknown 'endTime';";
1894 }
1895
1896 std::unique_ptr<PtJson> samples;
1897 ret = params.GetArray("samples", &samples);
1898 if (ret == Result::SUCCESS) {
1899 int32_t samplesLen = samples->GetSize();
1900 for (int32_t i = 0; i < samplesLen; ++i) {
1901 int32_t pSamples = samples->Get(i)->GetInt();
1902 profile->samples_.value().emplace_back(pSamples);
1903 }
1904 } else if (ret == Result::TYPE_ERROR) {
1905 error += "Unknown 'samples';";
1906 }
1907
1908 std::unique_ptr<PtJson> timeDeltas;
1909 ret = params.GetArray("timeDeltas", &timeDeltas);
1910 if (ret == Result::SUCCESS) {
1911 int32_t timeDeltasLen = timeDeltas->GetSize();
1912 for (int32_t i = 0; i < timeDeltasLen; ++i) {
1913 int32_t pTimeDeltas = timeDeltas->Get(i)->GetInt();
1914 profile->timeDeltas_.value().emplace_back(pTimeDeltas);
1915 }
1916 } else if (ret == Result::TYPE_ERROR) {
1917 error += "Unknown 'timeDeltas';";
1918 }
1919
1920 if (!error.empty()) {
1921 LOG(ERROR, DEBUGGER) << "Profile::Create " << error;
1922 return nullptr;
1923 }
1924
1925 return profile;
1926 }
1927
FromProfileInfo(const ProfileInfo & profileInfo)1928 std::unique_ptr<Profile> Profile::FromProfileInfo(const ProfileInfo &profileInfo)
1929 {
1930 auto profile = std::make_unique<Profile>();
1931 profile->SetStartTime(static_cast<int64_t>(profileInfo.startTime));
1932 profile->SetEndTime(static_cast<int64_t>(profileInfo.stopTime));
1933 size_t samplesLen = profileInfo.samples.size();
1934 std::vector<int32_t> tmpSamples;
1935 tmpSamples.reserve(samplesLen);
1936 for (size_t i = 0; i < samplesLen; ++i) {
1937 tmpSamples.push_back(profileInfo.samples[i]);
1938 }
1939 profile->SetSamples(tmpSamples);
1940
1941 size_t timeDeltasLen = profileInfo.timeDeltas.size();
1942 std::vector<int32_t> tmpTimeDeltas;
1943 tmpTimeDeltas.reserve(timeDeltasLen);
1944 for (size_t i = 0; i < timeDeltasLen; ++i) {
1945 tmpTimeDeltas.push_back(profileInfo.timeDeltas[i]);
1946 }
1947 profile->SetTimeDeltas(tmpTimeDeltas);
1948
1949 std::vector<std::unique_ptr<ProfileNode>> profileNode;
1950 size_t nodesLen = profileInfo.nodes.size();
1951 for (size_t i = 0; i < nodesLen; ++i) {
1952 const auto &cpuProfileNode = profileInfo.nodes[i];
1953 profileNode.push_back(ProfileNode::FromCpuProfileNode(cpuProfileNode));
1954 }
1955 profile->SetNodes(std::move(profileNode));
1956 return profile;
1957 }
1958
ToJson() const1959 std::unique_ptr<PtJson> Profile::ToJson() const
1960 {
1961 std::unique_ptr<PtJson> result = PtJson::CreateObject();
1962
1963 result->Add("startTime", startTime_);
1964 result->Add("endTime", endTime_);
1965
1966 std::unique_ptr<PtJson> nodes = PtJson::CreateArray();
1967 size_t nodesLen = nodes_.size();
1968 for (size_t i = 0; i < nodesLen; i++) {
1969 ASSERT(nodes_[i] != nullptr);
1970 nodes->Push(nodes_[i]->ToJson());
1971 }
1972 result->Add("nodes", nodes);
1973
1974 if (samples_) {
1975 std::unique_ptr<PtJson> samples = PtJson::CreateArray();
1976 size_t samplesLen = samples_->size();
1977 for (size_t i = 0; i < samplesLen; i++) {
1978 samples->Push(samples_.value()[i]);
1979 }
1980 result->Add("samples", samples);
1981 }
1982
1983 if (timeDeltas_) {
1984 std::unique_ptr<PtJson> timeDeltas = PtJson::CreateArray();
1985 size_t timeDeltasLen = timeDeltas_->size();
1986 for (size_t i = 0; i < timeDeltasLen; i++) {
1987 timeDeltas->Push(timeDeltas_.value()[i]);
1988 }
1989 result->Add("timeDeltas", timeDeltas);
1990 }
1991
1992 return result;
1993 }
1994
Create(const PtJson & params)1995 std::unique_ptr<Coverage> Coverage::Create(const PtJson ¶ms)
1996 {
1997 std::string error;
1998 auto coverage = std::make_unique<Coverage>();
1999 Result ret;
2000
2001 int32_t startOffset;
2002 ret = params.GetInt("startOffset", &startOffset);
2003 if (ret == Result::SUCCESS) {
2004 coverage->startOffset_ = startOffset;
2005 } else {
2006 error += "Unknown 'startOffset';";
2007 }
2008
2009 int32_t endOffset;
2010 ret = params.GetInt("endOffset", &endOffset);
2011 if (ret == Result::SUCCESS) {
2012 coverage->endOffset_ = endOffset;
2013 } else {
2014 error += "Unknown 'endOffset';";
2015 }
2016
2017 int32_t count;
2018 ret = params.GetInt("count", &count);
2019 if (ret == Result::SUCCESS) {
2020 coverage->count_ = count;
2021 } else {
2022 error += "Unknown 'count';";
2023 }
2024
2025 if (!error.empty()) {
2026 LOG(ERROR, DEBUGGER) << "Coverage::Create " << error;
2027 return nullptr;
2028 }
2029
2030 return coverage;
2031 }
2032
ToJson() const2033 std::unique_ptr<PtJson> Coverage::ToJson() const
2034 {
2035 std::unique_ptr<PtJson> result = PtJson::CreateObject();
2036
2037 result->Add("startOffset", startOffset_);
2038 result->Add("endOffset", endOffset_);
2039 result->Add("count", count_);
2040
2041 return result;
2042 }
2043
Create(const PtJson & params)2044 std::unique_ptr<FunctionCoverage> FunctionCoverage::Create(const PtJson ¶ms)
2045 {
2046 std::string error;
2047 auto functionCoverage = std::make_unique<FunctionCoverage>();
2048 Result ret;
2049
2050 std::string functionName;
2051 ret = params.GetString("functionName", &functionName);
2052 if (ret == Result::SUCCESS) {
2053 functionCoverage->functionName_ = std::move(functionName);
2054 } else {
2055 error += "Unknown 'functionName';";
2056 }
2057
2058 std::unique_ptr<PtJson> ranges;
2059 ret = params.GetArray("ranges", &ranges);
2060 if (ret == Result::SUCCESS) {
2061 int32_t len = ranges->GetSize();
2062 for (int32_t i = 0; i < len; ++i) {
2063 std::unique_ptr<PtJson> arrayEle = ranges->Get(i);
2064 ASSERT(arrayEle != nullptr);
2065 std::unique_ptr<Coverage> pRanges = Coverage::Create(*arrayEle);
2066 if (pRanges == nullptr) {
2067 error += "'ranges' format invalid;";
2068 } else {
2069 functionCoverage->ranges_.emplace_back(std::move(pRanges));
2070 }
2071 }
2072 } else {
2073 error += "Unknown 'ranges';";
2074 }
2075
2076 bool isBlockCoverage;
2077 ret = params.GetBool("isBlockCoverage", &isBlockCoverage);
2078 if (ret == Result::SUCCESS) {
2079 functionCoverage->isBlockCoverage_ = isBlockCoverage;
2080 } else {
2081 error += "Unknown 'isBlockCoverage';";
2082 }
2083
2084 if (!error.empty()) {
2085 LOG(ERROR, DEBUGGER) << "FunctionCoverage::Create " << error;
2086 return nullptr;
2087 }
2088
2089 return functionCoverage;
2090 }
2091
ToJson() const2092 std::unique_ptr<PtJson> FunctionCoverage::ToJson() const
2093 {
2094 std::unique_ptr<PtJson> result = PtJson::CreateObject();
2095
2096 result->Add("functionName", functionName_.c_str());
2097
2098 std::unique_ptr<PtJson> ranges = PtJson::CreateArray();
2099 size_t len = ranges_.size();
2100 for (size_t i = 0; i < len; i++) {
2101 ASSERT(ranges_[i] != nullptr);
2102 ranges->Push(ranges_[i]->ToJson());
2103 }
2104 result->Add("ranges", ranges);
2105
2106 result->Add("isBlockCoverage", isBlockCoverage_);
2107
2108 return result;
2109 }
2110
Create(const PtJson & params)2111 std::unique_ptr<ScriptCoverage> ScriptCoverage::Create(const PtJson ¶ms)
2112 {
2113 std::string error;
2114 auto scriptCoverage = std::make_unique<ScriptCoverage>();
2115 Result ret;
2116
2117 std::string scriptId;
2118 ret = params.GetString("scriptId", &scriptId);
2119 if (ret == Result::SUCCESS) {
2120 scriptCoverage->scriptId_ = std::move(scriptId);
2121 } else {
2122 error += "Unknown 'scriptId';";
2123 }
2124
2125 std::string url;
2126 ret = params.GetString("url", &url);
2127 if (ret == Result::SUCCESS) {
2128 scriptCoverage->url_ = std::move(url);
2129 } else {
2130 error += "Unknown 'url';";
2131 }
2132
2133 std::unique_ptr<PtJson> functions;
2134 ret = params.GetArray("functions", &functions);
2135 if (ret == Result::SUCCESS) {
2136 int32_t len = functions->GetSize();
2137 for (int32_t i = 0; i < len; ++i) {
2138 std::unique_ptr<PtJson> arrayEle = functions->Get(i);
2139 ASSERT(arrayEle != nullptr);
2140 std::unique_ptr<FunctionCoverage> pFunctions = FunctionCoverage::Create(*arrayEle);
2141 if (pFunctions == nullptr) {
2142 error += "'functions' format invalid;";
2143 } else {
2144 scriptCoverage->functions_.emplace_back(std::move(pFunctions));
2145 }
2146 }
2147 } else {
2148 error += "Unknown 'functions';";
2149 }
2150
2151 if (!error.empty()) {
2152 LOG(ERROR, DEBUGGER) << "ScriptCoverage::Create " << error;
2153 return nullptr;
2154 }
2155
2156 return scriptCoverage;
2157 }
2158
ToJson() const2159 std::unique_ptr<PtJson> ScriptCoverage::ToJson() const
2160 {
2161 std::unique_ptr<PtJson> result = PtJson::CreateObject();
2162
2163 result->Add("scriptId", scriptId_.c_str());
2164 result->Add("url", url_.c_str());
2165
2166 std::unique_ptr<PtJson> functions = PtJson::CreateArray();
2167 size_t len = functions_.size();
2168 for (size_t i = 0; i < len; i++) {
2169 ASSERT(functions_[i] != nullptr);
2170 functions->Push(functions_[i]->ToJson());
2171 }
2172 result->Add("functions", functions);
2173
2174 return result;
2175 }
2176
Create(const PtJson & params)2177 std::unique_ptr<TypeObject> TypeObject::Create(const PtJson ¶ms)
2178 {
2179 std::string error;
2180 auto typeObject = std::make_unique<TypeObject>();
2181 Result ret;
2182
2183 std::string name;
2184 ret = params.GetString("name", &name);
2185 if (ret == Result::SUCCESS) {
2186 typeObject->name_ = std::move(name);
2187 } else {
2188 error += "Unknown 'name';";
2189 }
2190
2191 if (!error.empty()) {
2192 LOG(ERROR, DEBUGGER) << "TypeObject::Create " << error;
2193 return nullptr;
2194 }
2195
2196 return typeObject;
2197 }
2198
ToJson() const2199 std::unique_ptr<PtJson> TypeObject::ToJson() const
2200 {
2201 std::unique_ptr<PtJson> result = PtJson::CreateObject();
2202
2203 result->Add("name", name_.c_str());
2204
2205 return result;
2206 }
2207
Create(const PtJson & params)2208 std::unique_ptr<TypeProfileEntry> TypeProfileEntry::Create(const PtJson ¶ms)
2209 {
2210 std::string error;
2211 auto typeProfileEntry = std::make_unique<TypeProfileEntry>();
2212 Result ret;
2213
2214 int32_t offset;
2215 ret = params.GetInt("offset", &offset);
2216 if (ret == Result::SUCCESS) {
2217 typeProfileEntry->offset_ = offset;
2218 } else {
2219 error += "Unknown 'offset';";
2220 }
2221
2222 std::unique_ptr<PtJson> types;
2223 ret = params.GetArray("types", &types);
2224 if (ret == Result::SUCCESS) {
2225 int32_t len = types->GetSize();
2226 for (int32_t i = 0; i < len; ++i) {
2227 std::unique_ptr<PtJson> arrayEle = types->Get(i);
2228 ASSERT(arrayEle != nullptr);
2229 std::unique_ptr<TypeObject> pTypes = TypeObject::Create(*arrayEle);
2230 if (pTypes == nullptr) {
2231 error += "'types' format invalid;";
2232 } else {
2233 typeProfileEntry->types_.emplace_back(std::move(pTypes));
2234 }
2235 }
2236 } else {
2237 error += "Unknown 'types';";
2238 }
2239
2240 if (!error.empty()) {
2241 LOG(ERROR, DEBUGGER) << "TypeProfileEntry::Create " << error;
2242 return nullptr;
2243 }
2244
2245 return typeProfileEntry;
2246 }
2247
ToJson() const2248 std::unique_ptr<PtJson> TypeProfileEntry::ToJson() const
2249 {
2250 std::unique_ptr<PtJson> result = PtJson::CreateObject();
2251
2252 result->Add("offset", offset_);
2253
2254 std::unique_ptr<PtJson> types = PtJson::CreateArray();
2255 size_t len = types_.size();
2256 for (size_t i = 0; i < len; i++) {
2257 types->Push(types_[i]->ToJson());
2258 }
2259 result->Add("types", types);
2260
2261 return result;
2262 }
2263
Create(const PtJson & params)2264 std::unique_ptr<ScriptTypeProfile> ScriptTypeProfile::Create(const PtJson ¶ms)
2265 {
2266 std::string error;
2267 auto scriptTypeProfile = std::make_unique<ScriptTypeProfile>();
2268 Result ret;
2269
2270 std::string scriptId;
2271 ret = params.GetString("scriptId", &scriptId);
2272 if (ret == Result::SUCCESS) {
2273 scriptTypeProfile->scriptId_ = std::move(scriptId);
2274 } else {
2275 error += "Unknown 'scriptId';";
2276 }
2277
2278 std::string url;
2279 ret = params.GetString("url", &url);
2280 if (ret == Result::SUCCESS) {
2281 scriptTypeProfile->url_ = std::move(url);
2282 } else {
2283 error += "Unknown 'url';";
2284 }
2285
2286 std::unique_ptr<PtJson> entries;
2287 ret = params.GetArray("entries", &entries);
2288 if (ret == Result::SUCCESS) {
2289 int32_t len = entries->GetSize();
2290 for (int32_t i = 0; i < len; ++i) {
2291 std::unique_ptr<PtJson> arrayEle = entries->Get(i);
2292 ASSERT(arrayEle != nullptr);
2293 std::unique_ptr<TypeProfileEntry> pEntries = TypeProfileEntry::Create(*arrayEle);
2294 if (pEntries == nullptr) {
2295 error += "'entries' format invalid;";
2296 } else {
2297 scriptTypeProfile->entries_.emplace_back(std::move(pEntries));
2298 }
2299 }
2300 } else {
2301 error += "Unknown 'entries';";
2302 }
2303
2304 if (!error.empty()) {
2305 LOG(ERROR, DEBUGGER) << "ScriptTypeProfile::Create " << error;
2306 return nullptr;
2307 }
2308
2309 return scriptTypeProfile;
2310 }
2311
ToJson() const2312 std::unique_ptr<PtJson> ScriptTypeProfile::ToJson() const
2313 {
2314 std::unique_ptr<PtJson> result = PtJson::CreateObject();
2315
2316 result->Add("scriptId", scriptId_.c_str());
2317 result->Add("url", url_.c_str());
2318
2319 std::unique_ptr<PtJson> entries = PtJson::CreateArray();
2320 size_t len = entries_.size();
2321 for (size_t i = 0; i < len; i++) {
2322 entries->Push(entries_[i]->ToJson());
2323 }
2324 result->Add("entries", entries);
2325
2326 return result;
2327 }
2328 #endif
2329 } // namespace panda::ecmascript::tooling
2330