• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &params)
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 &params)
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 &params)
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 &params)
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 &params)
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 &params)
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 &params)
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 &params)
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 &params)
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 &params)
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 &params)
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 &params)
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 &params)
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 &params)
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 &params)
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 &params)
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 &params)
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 &params)
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 &params)
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 &params)
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 &params)
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 &params)
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 &params)
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 &params)
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 &params)
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 &params)
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