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 "tooling/base/pt_types.h"
17 #include "ecmascript/napi/jsnapi_helper.h"
18 #include "ecmascript/debugger/js_debugger.h"
19 #include "ecmascript/property_attributes.h"
20 
21 namespace panda::ecmascript::tooling {
22 using ObjectType = RemoteObject::TypeName;
23 using ObjectSubType = RemoteObject::SubTypeName;
24 using ObjectClassName = RemoteObject::ClassName;
25 
26 const std::string ObjectType::Object = "object";        // NOLINT (readability-identifier-naming)
27 const std::string ObjectType::Function = "function";    // NOLINT (readability-identifier-naming)
28 const std::string ObjectType::Undefined = "undefined";  // NOLINT (readability-identifier-naming)
29 const std::string ObjectType::String = "string";        // NOLINT (readability-identifier-naming)
30 const std::string ObjectType::Number = "number";        // NOLINT (readability-identifier-naming)
31 const std::string ObjectType::Boolean = "boolean";      // NOLINT (readability-identifier-naming)
32 const std::string ObjectType::Symbol = "symbol";        // NOLINT (readability-identifier-naming)
33 const std::string ObjectType::Bigint = "bigint";        // NOLINT (readability-identifier-naming)
34 const std::string ObjectType::Wasm = "wasm";            // NOLINT (readability-identifier-naming)
35 
36 const std::string ObjectSubType::Array = "array";              // NOLINT (readability-identifier-naming)
37 const std::string ObjectSubType::Null = "null";                // NOLINT (readability-identifier-naming)
38 const std::string ObjectSubType::Node = "node";                // NOLINT (readability-identifier-naming)
39 const std::string ObjectSubType::Regexp = "regexp";            // NOLINT (readability-identifier-naming)
40 const std::string ObjectSubType::Date = "date";                // NOLINT (readability-identifier-naming)
41 const std::string ObjectSubType::Map = "map";                  // NOLINT (readability-identifier-naming)
42 const std::string ObjectSubType::Set = "set";                  // NOLINT (readability-identifier-naming)
43 const std::string ObjectSubType::Weakmap = "weakmap";          // NOLINT (readability-identifier-naming)
44 const std::string ObjectSubType::Weakset = "weakset";          // NOLINT (readability-identifier-naming)
45 const std::string ObjectSubType::Iterator = "iterator";        // NOLINT (readability-identifier-naming)
46 const std::string ObjectSubType::Generator = "generator";      // NOLINT (readability-identifier-naming)
47 const std::string ObjectSubType::Error = "error";              // NOLINT (readability-identifier-naming)
48 const std::string ObjectSubType::Proxy = "proxy";              // NOLINT (readability-identifier-naming)
49 const std::string ObjectSubType::Promise = "promise";          // NOLINT (readability-identifier-naming)
50 const std::string ObjectSubType::Typedarray = "typedarray";    // NOLINT (readability-identifier-naming)
51 const std::string ObjectSubType::Arraybuffer = "arraybuffer";  // NOLINT (readability-identifier-naming)
52 const std::string ObjectSubType::Dataview = "dataview";        // NOLINT (readability-identifier-naming)
53 const std::string ObjectSubType::I32 = "i32";                  // NOLINT (readability-identifier-naming)
54 const std::string ObjectSubType::I64 = "i64";                  // NOLINT (readability-identifier-naming)
55 const std::string ObjectSubType::F32 = "f32";                  // NOLINT (readability-identifier-naming)
56 const std::string ObjectSubType::F64 = "f64";                  // NOLINT (readability-identifier-naming)
57 const std::string ObjectSubType::V128 = "v128";                // NOLINT (readability-identifier-naming)
58 const std::string ObjectSubType::Externref = "externref";      // NOLINT (readability-identifier-naming)
59 
60 const std::string ObjectClassName::Object = "Object";                  // NOLINT (readability-identifier-naming)
61 const std::string ObjectClassName::Function = "Function";              // NOLINT (readability-identifier-naming)
62 const std::string ObjectClassName::Array = "Array";                    // NOLINT (readability-identifier-naming)
63 const std::string ObjectClassName::Regexp = "RegExp";                  // NOLINT (readability-identifier-naming)
64 const std::string ObjectClassName::Date = "Date";                      // NOLINT (readability-identifier-naming)
65 const std::string ObjectClassName::Map = "Map";                        // NOLINT (readability-identifier-naming)
66 const std::string ObjectClassName::Set = "Set";                        // NOLINT (readability-identifier-naming)
67 const std::string ObjectClassName::Weakmap = "Weakmap";                // NOLINT (readability-identifier-naming)
68 const std::string ObjectClassName::Weakset = "Weakset";                // NOLINT (readability-identifier-naming)
69 const std::string ObjectClassName::Dataview = "Dataview";                // 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 const std::string ObjectClassName::Generator = "Generator";            // NOLINT (readability-identifier-naming)
82 
83 const std::string RemoteObject::ObjectDescription = "Object";    // NOLINT (readability-identifier-naming)
84 const std::string RemoteObject::GlobalDescription = "global";    // NOLINT (readability-identifier-naming)
85 const std::string RemoteObject::ProxyDescription = "Proxy";      // NOLINT (readability-identifier-naming)
86 const std::string RemoteObject::PromiseDescription = "Promise";  // NOLINT (readability-identifier-naming)
87 const std::string RemoteObject::ArrayIteratorDescription =       // NOLINT (readability-identifier-naming)
88     "ArrayIterator";
89 const std::string RemoteObject::StringIteratorDescription =  // NOLINT (readability-identifier-naming)
90     "StringIterator";
91 const std::string RemoteObject::SetIteratorDescription = "SetIterator";  // NOLINT (readability-identifier-naming)
92 const std::string RemoteObject::MapIteratorDescription = "MapIterator";  // NOLINT (readability-identifier-naming)
93 const std::string RemoteObject::WeakRefDescription = "WeakRef";          // NOLINT (readability-identifier-naming)
94 const std::string RemoteObject::WeakMapDescription = "WeakMap";          // NOLINT (readability-identifier-naming)
95 const std::string RemoteObject::WeakSetDescription = "WeakSet";          // NOLINT (readability-identifier-naming)
96 const std::string RemoteObject::DataViewDescription = "DataView";          // NOLINT (readability-identifier-naming)
97 const std::string RemoteObject::JSPrimitiveNumberDescription =           // NOLINT (readability-identifier-naming)
98     "Number";
99 const std::string RemoteObject::JSPrimitiveBooleanDescription =          // NOLINT (readability-identifier-naming)
100     "Boolean";
101 const std::string RemoteObject::JSPrimitiveStringDescription =           // NOLINT (readability-identifier-naming)
102     "String";
103 const std::string RemoteObject::JSPrimitiveSymbolDescription =           // NOLINT (readability-identifier-naming)
104     "Symbol";
105 const std::string RemoteObject::DateTimeFormatDescription =                // NOLINT (readability-identifier-naming)
106     "DateTimeFormat";
107 const std::string RemoteObject::JSIntlDescription = "Intl";                // NOLINT (readability-identifier-naming)
108 const std::string RemoteObject::NumberFormatDescription = "NumberFormat";  // NOLINT (readability-identifier-naming)
109 const std::string RemoteObject::CollatorDescription = "Collator";          // NOLINT (readability-identifier-naming)
110 const std::string RemoteObject::PluralRulesDescription = "PluralRules";    // NOLINT (readability-identifier-naming)
111 const std::string RemoteObject::JSLocaleDescription = "Locale";            // NOLINT (readability-identifier-naming)
112 const std::string RemoteObject::JSListFormatDescription = "ListFormat";    // NOLINT (readability-identifier-naming)
113 const std::string RemoteObject::JSRelativeTimeFormatDescription =          // NOLINT (readability-identifier-naming)
114     "RelativeTimeFormat";
115 
FromTagged(const EcmaVM *ecmaVm, Local<JSValueRef> tagged)116 std::unique_ptr<RemoteObject> RemoteObject::FromTagged(const EcmaVM *ecmaVm, Local<JSValueRef> tagged)
117 {
118     if (tagged->IsNull() || tagged->IsUndefined() ||
119         tagged->IsBoolean() || tagged->IsNumber() ||
120         tagged->IsBigInt(ecmaVm)) {
121         return std::make_unique<PrimitiveRemoteObject>(ecmaVm, tagged);
122     }
123     if (tagged->IsString(ecmaVm)) {
124         return std::make_unique<StringRemoteObject>(ecmaVm, Local<StringRef>(tagged));
125     }
126     if (tagged->IsSymbol(ecmaVm)) {
127         return std::make_unique<SymbolRemoteObject>(ecmaVm, Local<SymbolRef>(tagged));
128     }
129     // proxy must be placed in front of all object types
130     if (tagged->IsProxy(ecmaVm)) {
131         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Proxy, ObjectSubType::Proxy);
132     }
133     if (tagged->IsGeneratorFunction(ecmaVm)) {
134         return std::make_unique<GeneratorFunctionRemoteObject>(ecmaVm, tagged);
135     }
136     if (tagged->IsFunction(ecmaVm)) {
137         return std::make_unique<FunctionRemoteObject>(ecmaVm, tagged);
138     }
139     if (tagged->IsArray(ecmaVm)) {
140         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Array, ObjectSubType::Array);
141     }
142     if (tagged->IsRegExp(ecmaVm)) {
143         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Regexp, ObjectSubType::Regexp);
144     }
145     if (tagged->IsDate(ecmaVm)) {
146         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Date, ObjectSubType::Date);
147     }
148     if (tagged->IsMap(ecmaVm)) {
149         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Map, ObjectSubType::Map);
150     }
151     if (tagged->IsWeakMap(ecmaVm)) {
152         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Weakmap, ObjectSubType::Weakmap);
153     }
154     if (tagged->IsSet(ecmaVm)) {
155         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Set, ObjectSubType::Set);
156     }
157     if (tagged->IsWeakSet(ecmaVm)) {
158         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Weakset, ObjectSubType::Weakset);
159     }
160     if (tagged->IsDataView(ecmaVm)) {
161         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Dataview, ObjectSubType::Dataview);
162     }
163     if (tagged->IsError(ecmaVm)) {
164         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Error, ObjectSubType::Error);
165     }
166     if (tagged->IsPromise(ecmaVm)) {
167         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Promise, ObjectSubType::Promise);
168     }
169     if (tagged->IsArrayBuffer(ecmaVm)) {
170         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Arraybuffer,
171             ObjectSubType::Arraybuffer);
172     }
173     if (tagged->IsArrayIterator(ecmaVm)) {
174         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::ArrayIterator);
175     }
176     if (tagged->IsStringIterator(ecmaVm)) {
177         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::StringIterator);
178     }
179     if (tagged->IsSetIterator(ecmaVm)) {
180         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::SetIterator,
181             ObjectSubType::Iterator);
182     }
183     if (tagged->IsMapIterator(ecmaVm)) {
184         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::MapIterator,
185             ObjectSubType::Iterator);
186     }
187     if (tagged->IsArrayList(ecmaVm)) {
188         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
189     }
190     if (tagged->IsDeque(ecmaVm)) {
191         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
192     }
193     if (tagged->IsHashMap(ecmaVm)) {
194         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
195     }
196     if (tagged->IsHashSet(ecmaVm)) {
197         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
198     }
199     if (tagged->IsLightWeightMap(ecmaVm)) {
200         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
201     }
202     if (tagged->IsLightWeightSet(ecmaVm)) {
203         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
204     }
205     if (tagged->IsLinkedList(ecmaVm)) {
206         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
207     }
208     if (tagged->IsList(ecmaVm)) {
209         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
210     }
211     if (tagged->IsPlainArray(ecmaVm)) {
212         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
213     }
214     if (tagged->IsQueue(ecmaVm)) {
215         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
216     }
217     if (tagged->IsStack(ecmaVm)) {
218         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
219     }
220     if (tagged->IsTreeMap(ecmaVm)) {
221         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
222     }
223     if (tagged->IsTreeSet(ecmaVm)) {
224         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
225     }
226     if (tagged->IsVector(ecmaVm)) {
227         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
228     }
229     if (tagged->IsObject(ecmaVm)) {
230         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
231     }
232     if (tagged->IsNativePointer(ecmaVm)) {
233         return std::make_unique<ObjectRemoteObject>(ecmaVm, tagged, ObjectClassName::Object);
234     }
235     std::unique_ptr<RemoteObject> object = std::make_unique<RemoteObject>();
236     object->SetType(ObjectType::Undefined);
237     return object;
238 }
239 
AppendingHashToDescription(const EcmaVM *ecmaVm, Local<JSValueRef> tagged, std::string &description)240 void RemoteObject::AppendingHashToDescription(const EcmaVM *ecmaVm, Local<JSValueRef> tagged,
241     std::string &description)
242 {
243     if (ecmaVm->GetJsDebuggerManager() != nullptr && ecmaVm->GetJsDebuggerManager()->IsObjHashDisplayEnabled()) {
244         JSHandle<JSTaggedValue> valueHandle = JSNApiHelper::ToJSHandle(tagged);
245         int32_t hash = DebuggerApi::GetObjectHash(ecmaVm, valueHandle);
246         if (hash != 0) {
247             std::stringstream stringstream;
248             stringstream << std::hex << hash;
249             description += "@" + stringstream.str();
250         }
251     }
252 }
253 
AppendingSendableDescription(Local<JSValueRef> tagged, std::string &description)254 void RemoteObject::AppendingSendableDescription(Local<JSValueRef> tagged, std::string &description)
255 {
256     if (JSNApiHelper::ToJSTaggedValue(*tagged).IsInSharedHeap()) {
257         description += " [Sendable]";
258     }
259 }
260 
ResolveClassNameToDescription(const EcmaVM *ecmaVm, Local<JSValueRef> tagged)261 std::string RemoteObject::ResolveClassNameToDescription(const EcmaVM *ecmaVm, Local<JSValueRef> tagged)
262 {
263     std::string description = RemoteObject::ObjectDescription;
264     if (!tagged->IsObject(ecmaVm)) {
265         return description;
266     }
267     DebuggerApi::GetObjectClassName(ecmaVm, tagged, description);
268     return description.empty() ? RemoteObject::ObjectDescription : description;
269 }
270 
PrimitiveRemoteObject(const EcmaVM *ecmaVm, Local<JSValueRef> tagged)271 PrimitiveRemoteObject::PrimitiveRemoteObject(const EcmaVM *ecmaVm, Local<JSValueRef> tagged)
272 {
273     if (tagged->IsNull()) {
274         SetType(ObjectType::Object)
275             .SetSubType(ObjectSubType::Null)
276             .SetPreviewValue(ObjectSubType::Null);
277     } else if (tagged->IsBoolean()) {
278         std::string description = tagged->IsTrue() ? "true" : "false";
279         SetType(ObjectType::Boolean)
280             .SetValue(tagged)
281             .SetPreviewValue(description)
282             .SetUnserializableValue(description)
283             .SetDescription(description);
284     } else if (tagged->IsUndefined()) {
285         SetType(ObjectType::Undefined).SetPreviewValue(ObjectType::Undefined);
286     } else if (tagged->IsNumber()) {
287         std::string description = tagged->ToString(ecmaVm)->ToString(ecmaVm);
288         SetType(ObjectType::Number)
289             .SetValue(tagged)
290             .SetPreviewValue(description)
291             .SetUnserializableValue(description)
292             .SetDescription(description);
293     } else if (tagged->IsBigInt(ecmaVm)) {
294         std::string description = tagged->ToString(ecmaVm)->ToString(ecmaVm) + "n";  // n : BigInt literal postfix
295         SetType(ObjectType::Bigint)
296             .SetValue(tagged)
297             .SetPreviewValue(description)
298             .SetUnserializableValue(description)
299             .SetDescription(description);
300     }
301 }
302 
StringRemoteObject([[maybe_unused]] const EcmaVM *ecmaVm, Local<StringRef> tagged)303 StringRemoteObject::StringRemoteObject([[maybe_unused]] const EcmaVM *ecmaVm, Local<StringRef> tagged)
304 {
305     std::string description = tagged->DebuggerToString(ecmaVm);
306     SetType(RemoteObject::TypeName::String)
307         .SetValue(tagged)
308         .SetPreviewValue(description)
309         .SetUnserializableValue(description)
310         .SetDescription(description);
311 }
312 
SymbolRemoteObject(const EcmaVM *ecmaVm, Local<SymbolRef> tagged)313 SymbolRemoteObject::SymbolRemoteObject(const EcmaVM *ecmaVm, Local<SymbolRef> tagged)
314 {
315     std::string description = DescriptionForSymbol(ecmaVm, tagged);
316     SetPreviewValue(description);
317     AppendingHashToDescription(ecmaVm, tagged, description);
318     AppendingSendableDescription(tagged, description);
319     SetType(RemoteObject::TypeName::Symbol)
320         .SetValue(tagged)
321         .SetUnserializableValue(description)
322         .SetDescription(description);
323 }
324 
FunctionRemoteObject(const EcmaVM *ecmaVm, Local<JSValueRef> tagged)325 FunctionRemoteObject::FunctionRemoteObject(const EcmaVM *ecmaVm, Local<JSValueRef> tagged)
326 {
327     std::string description = DescriptionForFunction(ecmaVm, tagged);
328     AppendingHashToDescription(ecmaVm, tagged, description);
329     AppendingSendableDescription(tagged, description);
330     SetType(RemoteObject::TypeName::Function)
331         .SetClassName(RemoteObject::ClassName::Function)
332         .SetValue(tagged)
333         .SetPreviewValue(RemoteObject::ClassName::Function)
334         .SetUnserializableValue(description)
335         .SetDescription(description);
336 }
337 
GeneratorFunctionRemoteObject(const EcmaVM *ecmaVm, Local<JSValueRef> tagged)338 GeneratorFunctionRemoteObject::GeneratorFunctionRemoteObject(const EcmaVM *ecmaVm, Local<JSValueRef> tagged)
339 {
340     std::string description = DescriptionForGeneratorFunction(ecmaVm, tagged);
341     AppendingHashToDescription(ecmaVm, tagged, description);
342     AppendingSendableDescription(tagged, description);
343     SetType(RemoteObject::TypeName::Function)
344         .SetClassName(RemoteObject::ClassName::Generator)
345         .SetValue(tagged)
346         .SetPreviewValue(RemoteObject::ClassName::Generator)
347         .SetUnserializableValue(description)
348         .SetDescription(description);
349 }
350 
ObjectRemoteObject(const EcmaVM *ecmaVm, Local<JSValueRef> tagged, const std::string &classname)351 ObjectRemoteObject::ObjectRemoteObject(const EcmaVM *ecmaVm, Local<JSValueRef> tagged,
352                                        const std::string &classname)
353 {
354     std::string description = DescriptionForObject(ecmaVm, tagged);
355     SetPreviewValue(description);
356     AppendingHashToDescription(ecmaVm, tagged, description);
357     AppendingSendableDescription(tagged, description);
358     SetType(RemoteObject::TypeName::Object)
359         .SetClassName(classname)
360         .SetValue(tagged)
361         .SetUnserializableValue(description)
362         .SetDescription(description);
363 }
364 
ObjectRemoteObject(const EcmaVM *ecmaVm, Local<JSValueRef> tagged, const std::string &classname, const std::string &subtype)365 ObjectRemoteObject::ObjectRemoteObject(const EcmaVM *ecmaVm, Local<JSValueRef> tagged,
366                                        const std::string &classname, const std::string &subtype)
367 {
368     std::string description = DescriptionForObject(ecmaVm, tagged);
369     SetPreviewValue(description);
370     AppendingHashToDescription(ecmaVm, tagged, description);
371     AppendingSendableDescription(tagged, description);
372     SetType(RemoteObject::TypeName::Object)
373         .SetSubType(subtype)
374         .SetClassName(classname)
375         .SetValue(tagged)
376         .SetUnserializableValue(description)
377         .SetDescription(description);
378 }
379 
DescriptionForObject(const EcmaVM *ecmaVm, Local<JSValueRef> tagged)380 std::string ObjectRemoteObject::DescriptionForObject(const EcmaVM *ecmaVm, Local<JSValueRef> tagged)
381 {
382     // proxy must be placed in front of all object types
383     if (tagged->IsProxy(ecmaVm)) {
384         return RemoteObject::ProxyDescription;
385     }
386     if (tagged->IsArray(ecmaVm)) {
387         return DescriptionForArray(ecmaVm, Local<ArrayRef>(tagged));
388     }
389     if (tagged->IsRegExp(ecmaVm)) {
390         return DescriptionForRegexp(ecmaVm, Local<RegExpRef>(tagged));
391     }
392     if (tagged->IsDate(ecmaVm)) {
393         return DescriptionForDate(ecmaVm, Local<DateRef>(tagged));
394     }
395     if (tagged->IsMap(ecmaVm)) {
396         return DescriptionForMap(ecmaVm, Local<MapRef>(tagged));
397     }
398     if (tagged->IsWeakMap(ecmaVm)) {
399         return DescriptionForWeakMap(ecmaVm, Local<WeakMapRef>(tagged));
400     }
401     if (tagged->IsSet(ecmaVm)) {
402         return DescriptionForSet(ecmaVm, Local<SetRef>(tagged));
403     }
404     if (tagged->IsWeakSet(ecmaVm)) {
405         return DescriptionForWeakSet(ecmaVm, Local<WeakSetRef>(tagged));
406     }
407     if (tagged->IsDataView(ecmaVm)) {
408         return DescriptionForDataView(Local<DataViewRef>(tagged));
409     }
410     if (tagged->IsError(ecmaVm)) {
411         return DescriptionForError(ecmaVm, tagged);
412     }
413     if (tagged->IsPromise(ecmaVm)) {
414         return RemoteObject::PromiseDescription;
415     }
416     if (tagged->IsArrayIterator(ecmaVm)) {
417         return DescriptionForArrayIterator();
418     }
419     if (tagged->IsStringIterator(ecmaVm)) {
420         return RemoteObject::StringIteratorDescription;
421     }
422     if (tagged->IsSetIterator(ecmaVm)) {
423         return DescriptionForSetIterator();
424     }
425     if (tagged->IsMapIterator(ecmaVm)) {
426         return DescriptionForMapIterator();
427     }
428     if (tagged->IsArrayBuffer(ecmaVm)) {
429         return DescriptionForArrayBuffer(ecmaVm, Local<ArrayBufferRef>(tagged));
430     }
431     if (tagged->IsSharedArrayBuffer(ecmaVm)) {
432         return DescriptionForSharedArrayBuffer(ecmaVm, Local<ArrayBufferRef>(tagged));
433     }
434     if (tagged->IsUint8Array(ecmaVm)) {
435         return DescriptionForUint8Array(ecmaVm, Local<TypedArrayRef>(tagged));
436     }
437     if (tagged->IsInt8Array(ecmaVm)) {
438         return DescriptionForInt8Array(ecmaVm, Local<TypedArrayRef>(tagged));
439     }
440     if (tagged->IsInt16Array(ecmaVm)) {
441         return DescriptionForInt16Array(ecmaVm, Local<TypedArrayRef>(tagged));
442     }
443     if (tagged->IsInt32Array(ecmaVm)) {
444         return DescriptionForInt32Array(ecmaVm, Local<TypedArrayRef>(tagged));
445     }
446     if (tagged->IsJSPrimitiveRef(ecmaVm) && tagged->IsJSPrimitiveNumber(ecmaVm)) {
447         return DescriptionForPrimitiveNumber(ecmaVm, tagged);
448     }
449     if (tagged->IsJSPrimitiveRef(ecmaVm) && tagged->IsJSPrimitiveString(ecmaVm)) {
450         return DescriptionForPrimitiveString(ecmaVm, tagged);
451     }
452     if (tagged->IsJSPrimitiveRef(ecmaVm) && tagged->IsJSPrimitiveBoolean(ecmaVm)) {
453         return DescriptionForPrimitiveBoolean(ecmaVm, tagged);
454     }
455     if (tagged->IsGeneratorObject(ecmaVm)) {
456         return DescriptionForGeneratorObject(ecmaVm, tagged);
457     }
458     if (tagged->IsWeakRef(ecmaVm)) {
459         return DescriptionForWeakRef();
460     }
461     if (tagged->IsJSLocale(ecmaVm)) {
462         return DescriptionForJSLocale();
463     }
464     if (tagged->IsJSDateTimeFormat(ecmaVm)) {
465         return DescriptionForDateTimeFormat();
466     }
467     if (tagged->IsJSRelativeTimeFormat(ecmaVm)) {
468         return DescriptionForJSRelativeTimeFormat();
469     }
470     if (tagged->IsJSIntl(ecmaVm)) {
471         return RemoteObject::JSIntlDescription;
472     }
473     if (tagged->IsJSNumberFormat(ecmaVm)) {
474         return DescriptionForNumberFormat();
475     }
476     if (tagged->IsJSCollator(ecmaVm)) {
477         return DescriptionForCollator();
478     }
479     if (tagged->IsJSPluralRules(ecmaVm)) {
480         return DescriptionForPluralRules();
481     }
482     if (tagged->IsJSListFormat(ecmaVm)) {
483         return DescriptionForJSListFormat();
484     }
485     if (tagged->IsArrayList(ecmaVm)) {
486         return DescriptionForArrayList();
487     }
488     if (tagged->IsDeque(ecmaVm)) {
489         return DescriptionForDeque();
490     }
491     if (tagged->IsHashMap(ecmaVm)) {
492         return DescriptionForHashMap();
493     }
494     if (tagged->IsHashSet(ecmaVm)) {
495         return DescriptionForHashSet();
496     }
497     if (tagged->IsLightWeightMap(ecmaVm)) {
498         return DescriptionForLightWeightMap();
499     }
500     if (tagged->IsLightWeightSet(ecmaVm)) {
501         return DescriptionForLightWeightSet();
502     }
503     if (tagged->IsLinkedList(ecmaVm)) {
504         return DescriptionForLinkedList();
505     }
506     if (tagged->IsList(ecmaVm)) {
507         return DescriptionForList();
508     }
509     if (tagged->IsPlainArray(ecmaVm)) {
510         return DescriptionForPlainArray();
511     }
512     if (tagged->IsQueue(ecmaVm)) {
513         return DescriptionForQueue();
514     }
515     if (tagged->IsStack(ecmaVm)) {
516         return DescriptionForStack();
517     }
518     if (tagged->IsTreeMap(ecmaVm)) {
519         return DescriptionForTreeMap();
520     }
521     if (tagged->IsTreeSet(ecmaVm)) {
522         return DescriptionForTreeSet();
523     }
524     if (tagged->IsVector(ecmaVm)) {
525         return DescriptionForVector();
526     }
527     if (tagged->IsNativePointer(ecmaVm)) {
528         return DescriptionForNativePointer(Local<NativePointerRef>(tagged));
529     }
530     return ResolveClassNameToDescription(ecmaVm, tagged);
531 }
532 
DescriptionForNativePointer(const Local<NativePointerRef> &tagged)533 std::string ObjectRemoteObject::DescriptionForNativePointer(const Local<NativePointerRef> &tagged)
534 {
535     std::stringstream address;
536     address << std::hex << tagged->Value();
537     std::string description = "[External: " + address.str() + "]";
538     return description;
539 }
540 
DescriptionForArray(const EcmaVM *ecmaVm, Local<ArrayRef> tagged)541 std::string ObjectRemoteObject::DescriptionForArray(const EcmaVM *ecmaVm, Local<ArrayRef> tagged)
542 {
543     std::string description = "Array(" + std::to_string(tagged->Length(ecmaVm)) + ")";
544     return description;
545 }
546 
DescriptionForRegexp(const EcmaVM *ecmaVm, Local<RegExpRef> tagged)547 std::string ObjectRemoteObject::DescriptionForRegexp(const EcmaVM *ecmaVm, Local<RegExpRef> tagged)
548 {
549     std::string regExpSource = tagged->GetOriginalSource(ecmaVm)->ToString(ecmaVm);
550     std::string regExpFlags = tagged->GetOriginalFlags(ecmaVm);
551     return "/" + regExpSource + "/" + regExpFlags;
552 }
553 
DescriptionForDate(const EcmaVM *ecmaVm, Local<DateRef> tagged)554 std::string ObjectRemoteObject::DescriptionForDate(const EcmaVM *ecmaVm, Local<DateRef> tagged)
555 {
556     std::string description = tagged->ToString(ecmaVm)->ToString(ecmaVm);
557     return description;
558 }
559 
DescriptionForMap(const EcmaVM *ecmaVm, Local<MapRef> tagged)560 std::string ObjectRemoteObject::DescriptionForMap(const EcmaVM *ecmaVm, Local<MapRef> tagged)
561 {
562     int32_t len = tagged->GetTotalElements(ecmaVm);
563     int32_t index = 0;
564     std::string description = "Map(" + std::to_string(tagged->GetSize(ecmaVm)) + ")";
565     if (!len) {
566         return description;
567     }
568     description += " {";
569     char cPre = '\'';
570     for (int32_t i = 0; i < len; ++i) {
571         // add Key
572         Local<JSValueRef> jsVKey = tagged->GetKey(ecmaVm, i);
573         if (jsVKey->IsHole()) {
574             continue;
575         }
576 
577         Local<JSValueRef> jsVValue = tagged->GetValue(ecmaVm, i);
578         if (jsVKey->IsObject(ecmaVm)) {
579             description += "Object";
580         } else if (jsVKey->IsString(ecmaVm)) {
581             description += cPre + jsVKey->ToString(ecmaVm)->ToString(ecmaVm) + cPre;
582         } else {
583             description += jsVKey->ToString(ecmaVm)->ToString(ecmaVm);
584         }
585 
586         description += " => ";
587         // add Value
588         if (jsVValue->IsObject(ecmaVm)) {
589             description += "Object";
590         } else if (jsVValue->IsString(ecmaVm)) {
591             description += cPre + jsVValue->ToString(ecmaVm)->ToString(ecmaVm) + cPre;
592         } else {
593             description += jsVValue->ToString(ecmaVm)->ToString(ecmaVm);
594         }
595         if (index == tagged->GetSize(ecmaVm) - 1 || index >= 4) { // 4:The count of elements
596             description += tagged->GetSize(ecmaVm) > 5 ? ", ..." : ""; // 5:The count of elements
597             break;
598         }
599         description += ", ";
600         index++;
601     }
602     description += "}";
603     return description;
604 }
605 
DescriptionForWeakMap(const EcmaVM *ecmaVm, Local<WeakMapRef> tagged)606 std::string ObjectRemoteObject::DescriptionForWeakMap(const EcmaVM *ecmaVm, Local<WeakMapRef> tagged)
607 {
608     int32_t len = tagged->GetTotalElements(ecmaVm);
609     int32_t index = 0;
610     std::string description = "WeakMap(" + std::to_string(tagged->GetSize(ecmaVm)) + ")";
611     if (!len) {
612         return description;
613     }
614     description += " {";
615     char cPre = '\'';
616     for (int32_t i = 0; i < len; ++i) {
617         Local<JSValueRef> jsVKey = tagged->GetKey(ecmaVm, i);
618         if (jsVKey->IsHole()) {
619             continue;
620         }
621         Local<JSValueRef> jsVValue = tagged->GetValue(ecmaVm, i);
622         if (jsVKey->IsObject(ecmaVm)) {
623             description += "Object";
624         } else if (jsVKey->IsString(ecmaVm)) {
625             description += cPre + jsVKey->ToString(ecmaVm)->ToString(ecmaVm) + cPre;
626         } else {
627             description += jsVKey->ToString(ecmaVm)->ToString(ecmaVm);
628         }
629 
630         description += " => ";
631 
632         if (jsVValue->IsObject(ecmaVm)) {
633             description += "Object";
634         } else if (jsVValue->IsString(ecmaVm)) {
635             description += cPre + jsVValue->ToString(ecmaVm)->ToString(ecmaVm) + cPre;
636         } else {
637             description += jsVValue->ToString(ecmaVm)->ToString(ecmaVm);
638         }
639         if (index == tagged->GetSize(ecmaVm) - 1 || index >= 4) { // 4:The count of elements
640             description += tagged->GetSize(ecmaVm) > 5 ? ", ..." : ""; // 5:The count of elements
641             break;
642         }
643         description += ", ";
644         index++;
645     }
646     description += "}";
647     return description;
648 }
649 
DescriptionForSet(const EcmaVM *ecmaVm, Local<SetRef> tagged)650 std::string ObjectRemoteObject::DescriptionForSet(const EcmaVM *ecmaVm, Local<SetRef> tagged)
651 {
652     int32_t len = tagged->GetTotalElements(ecmaVm);
653     int32_t index = 0;
654     std::string description = ("Set(" + std::to_string(tagged->GetSize(ecmaVm)) + ")");
655     if (!len) {
656         return description;
657     }
658     description += " {";
659     char cPre = '\'';
660     for (int32_t i = 0; i < len; ++i) {
661         // add Key
662         Local<JSValueRef> jsValue = tagged->GetValue(ecmaVm, i);
663         if (jsValue->IsHole()) {
664             continue;
665         }
666         // add Value
667         if (jsValue->IsObject(ecmaVm)) {
668             description += "Object";
669         } else if (jsValue->IsString(ecmaVm)) {
670             description += cPre + jsValue->ToString(ecmaVm)->ToString(ecmaVm) + cPre;
671         } else {
672             description += jsValue->ToString(ecmaVm)->ToString(ecmaVm);
673         }
674         if (index == tagged->GetSize(ecmaVm) - 1 || index >= 4) { // 4:The count of elements
675             description += tagged->GetSize(ecmaVm) > 5 ? ", ..." : ""; // 5:The count of elements
676             break;
677         }
678         description += ", ";
679         index++;
680     }
681     description += "}";
682     return description;
683 }
684 
DescriptionForWeakSet(const EcmaVM *ecmaVm, Local<WeakSetRef> tagged)685 std::string ObjectRemoteObject::DescriptionForWeakSet(const EcmaVM *ecmaVm, Local<WeakSetRef> tagged)
686 {
687     int32_t len = tagged->GetTotalElements(ecmaVm);
688     int32_t index = 0;
689     std::string description = ("WeakSet(" + std::to_string(tagged->GetSize(ecmaVm)) + ")");
690     if (!len) {
691         return description;
692     }
693     description += " {";
694     char cPre = '\'';
695     for (int32_t i = 0; i < len; ++i) {
696         Local<JSValueRef> jsValue = tagged->GetValue(ecmaVm, i);
697         if (jsValue->IsHole()) {
698             continue;
699         }
700         if (jsValue->IsObject(ecmaVm)) {
701             description += "Object";
702         } else if (jsValue->IsString(ecmaVm)) {
703             description += cPre + jsValue->ToString(ecmaVm)->ToString(ecmaVm) + cPre;
704         } else {
705             description += jsValue->ToString(ecmaVm)->ToString(ecmaVm);
706         }
707         if (index == tagged->GetSize(ecmaVm) - 1 || index >= 4) { // 4:The count of elements
708             description += tagged->GetSize(ecmaVm) > 5 ? ", ..." : ""; // 5:The count of elements
709             break;
710         }
711         description += ", ";
712         index++;
713     }
714     description += "}";
715     return description;
716 }
717 
DescriptionForDataView(Local<DataViewRef> tagged)718 std::string ObjectRemoteObject::DescriptionForDataView(Local<DataViewRef> tagged)
719 {
720     std::string description = ("DataView(" + std::to_string(tagged->ByteLength()) + ")");
721     return description;
722 }
723 
DescriptionForError(const EcmaVM *ecmaVm, Local<JSValueRef> tagged)724 std::string ObjectRemoteObject::DescriptionForError(const EcmaVM *ecmaVm, Local<JSValueRef> tagged)
725 {
726     // add name
727     Local<JSValueRef> name = StringRef::NewFromUtf8(ecmaVm, "name");
728     std::string strName = Local<ObjectRef>(tagged)->Get(ecmaVm, name)->ToString(ecmaVm)->ToString(ecmaVm);
729     // add message
730     Local<JSValueRef> message = StringRef::NewFromUtf8(ecmaVm, "message");
731     std::string strMessage = Local<ObjectRef>(tagged)->Get(ecmaVm, message)->ToString(ecmaVm)->ToString(ecmaVm);
732     if (strMessage.empty()) {
733         return strName;
734     } else {
735         return strName + ": " + strMessage;
736     }
737 }
738 
DescriptionForArrayIterator()739 std::string ObjectRemoteObject::DescriptionForArrayIterator()
740 {
741     std::string description = RemoteObject::ArrayIteratorDescription + "{}";
742     return description;
743 }
744 
DescriptionForSetIterator()745 std::string ObjectRemoteObject::DescriptionForSetIterator()
746 {
747     std::string description = RemoteObject::SetIteratorDescription + "{}";
748     return description;
749 }
750 
DescriptionForMapIterator()751 std::string ObjectRemoteObject::DescriptionForMapIterator()
752 {
753     std::string description = RemoteObject::MapIteratorDescription + "{}";
754     return description;
755 }
756 
DescriptionForArrayBuffer(const EcmaVM *ecmaVm, Local<ArrayBufferRef> tagged)757 std::string ObjectRemoteObject::DescriptionForArrayBuffer(const EcmaVM *ecmaVm, Local<ArrayBufferRef> tagged)
758 {
759     int32_t len = tagged->ByteLength(ecmaVm);
760     std::string description = ObjectClassName::Arraybuffer + "(" + std::to_string(len) + ")";
761     return description;
762 }
763 
DescriptionForSharedArrayBuffer(const EcmaVM *ecmaVm, Local<ArrayBufferRef> tagged)764 std::string ObjectRemoteObject::DescriptionForSharedArrayBuffer(const EcmaVM *ecmaVm, Local<ArrayBufferRef> tagged)
765 {
766     int32_t len = tagged->ByteLength(ecmaVm);
767     std::string description = ("SharedArrayBuffer(" + std::to_string(len) + ")");
768     return description;
769 }
770 
DescriptionForUint8Array(const EcmaVM *ecmaVm, Local<TypedArrayRef> tagged)771 std::string ObjectRemoteObject::DescriptionForUint8Array(const EcmaVM *ecmaVm, Local<TypedArrayRef> tagged)
772 {
773     uint32_t len = tagged->ByteLength(ecmaVm);
774     std::string description = ("Uint8Array(" + std::to_string(len) + ")");
775     return description;
776 }
777 
DescriptionForInt8Array(const EcmaVM *ecmaVm, Local<TypedArrayRef> tagged)778 std::string ObjectRemoteObject::DescriptionForInt8Array(const EcmaVM *ecmaVm, Local<TypedArrayRef> tagged)
779 {
780     uint32_t len = tagged->ByteLength(ecmaVm);
781     std::string description = ("Int8Array(" + std::to_string(len) + ")");
782     return description;
783 }
784 
DescriptionForInt16Array(const EcmaVM *ecmaVm, Local<TypedArrayRef> tagged)785 std::string ObjectRemoteObject::DescriptionForInt16Array(const EcmaVM *ecmaVm, Local<TypedArrayRef> tagged)
786 {
787     uint32_t len = tagged->ByteLength(ecmaVm) / NumberSize::BYTES_OF_16BITS;
788     std::string description = ("Int16Array(" + std::to_string(len) + ")");
789     return description;
790 }
791 
DescriptionForInt32Array(const EcmaVM *ecmaVm, Local<TypedArrayRef> tagged)792 std::string ObjectRemoteObject::DescriptionForInt32Array(const EcmaVM *ecmaVm, Local<TypedArrayRef> tagged)
793 {
794     uint32_t len = tagged->ByteLength(ecmaVm) / NumberSize::BYTES_OF_32BITS;
795     std::string description = ("Int32Array(" + std::to_string(len) + ")");
796     return description;
797 }
798 
DescriptionForPrimitiveNumber(const EcmaVM *ecmaVm, const Local<JSValueRef> &tagged)799 std::string ObjectRemoteObject::DescriptionForPrimitiveNumber(const EcmaVM *ecmaVm, const Local<JSValueRef> &tagged)
800 {
801     std::string strValue = tagged->ToString(ecmaVm)->ToString(ecmaVm);
802     std::string description = RemoteObject::JSPrimitiveNumberDescription + "{[[PrimitiveValue]]: " + strValue + "}";
803     return description;
804 }
805 
DescriptionForPrimitiveString(const EcmaVM *ecmaVm, const Local<JSValueRef> &tagged)806 std::string ObjectRemoteObject::DescriptionForPrimitiveString(const EcmaVM *ecmaVm, const Local<JSValueRef> &tagged)
807 {
808     std::string strValue = tagged->ToString(ecmaVm)->ToString(ecmaVm);
809     std::string description = RemoteObject::JSPrimitiveStringDescription + "{[[PrimitiveValue]]: " + strValue + "}";
810     return description;
811 }
812 
DescriptionForPrimitiveBoolean(const EcmaVM *ecmaVm, const Local<JSValueRef> &tagged)813 std::string ObjectRemoteObject::DescriptionForPrimitiveBoolean(const EcmaVM *ecmaVm, const Local<JSValueRef> &tagged)
814 {
815     std::string strValue = tagged->ToString(ecmaVm)->ToString(ecmaVm);
816     std::string description = RemoteObject::JSPrimitiveBooleanDescription + "{[[PrimitiveValue]]: " + strValue + "}";
817     return description;
818 }
819 
DescriptionForGeneratorObject(const EcmaVM *ecmaVm, const Local<JSValueRef> &tagged)820 std::string ObjectRemoteObject::DescriptionForGeneratorObject(const EcmaVM *ecmaVm, const Local<JSValueRef> &tagged)
821 {
822     Local<GeneratorObjectRef> genObjectRef = tagged->ToObject(ecmaVm);
823     // add Status
824     Local<JSValueRef> jsValueRef = genObjectRef->GetGeneratorState(ecmaVm);
825     std::string strState = genObjectRef->GetGeneratorState(ecmaVm)->ToString(ecmaVm)->ToString(ecmaVm);
826     // add FuncName
827     jsValueRef = genObjectRef->GetGeneratorFunction(ecmaVm);
828     Local<JSValueRef> name = StringRef::NewFromUtf8(ecmaVm, "name");
829     std::string strFuncName = Local<ObjectRef>(jsValueRef)->Get(ecmaVm, name)->ToString(ecmaVm)->ToString(ecmaVm);
830 
831     std::string description = strFuncName + " {<" + strState + ">}";
832     return description;
833 }
834 
DescriptionForWeakRef()835 std::string ObjectRemoteObject::DescriptionForWeakRef()
836 {
837     std::string description = RemoteObject::WeakRefDescription + " {}";
838     return description;
839 }
840 
DescriptionForDateTimeFormat()841 std::string ObjectRemoteObject::DescriptionForDateTimeFormat()
842 {
843     std::string description = RemoteObject::DateTimeFormatDescription + " {}";
844     return description;
845 }
846 
DescriptionForNumberFormat()847 std::string ObjectRemoteObject::DescriptionForNumberFormat()
848 {
849     std::string description = RemoteObject::NumberFormatDescription + " {}";
850     return description;
851 }
852 
DescriptionForCollator()853 std::string ObjectRemoteObject::DescriptionForCollator()
854 {
855     std::string description = RemoteObject::CollatorDescription + " {}";
856     return description;
857 }
858 
DescriptionForPluralRules()859 std::string ObjectRemoteObject::DescriptionForPluralRules()
860 {
861     std::string description = RemoteObject::PluralRulesDescription + " {}";
862     return description;
863 }
864 
DescriptionForJSLocale()865 std::string ObjectRemoteObject::DescriptionForJSLocale()
866 {
867     std::string description = RemoteObject::JSLocaleDescription + " {}";
868     return description;
869 }
870 
DescriptionForJSRelativeTimeFormat()871 std::string ObjectRemoteObject::DescriptionForJSRelativeTimeFormat()
872 {
873     std::string description = RemoteObject::JSRelativeTimeFormatDescription + " {}";
874     return description;
875 }
876 
DescriptionForJSListFormat()877 std::string ObjectRemoteObject::DescriptionForJSListFormat()
878 {
879     std::string description = RemoteObject::JSListFormatDescription + " {}";
880     return description;
881 }
882 
DescriptionForArrayList()883 std::string ObjectRemoteObject::DescriptionForArrayList()
884 {
885     std::string description = "ArrayList";
886     return description;
887 }
888 
DescriptionForDeque()889 std::string ObjectRemoteObject::DescriptionForDeque()
890 {
891     std::string description = "Deque";
892     return description;
893 }
894 
DescriptionForHashMap()895 std::string ObjectRemoteObject::DescriptionForHashMap()
896 {
897     std::string description = "HashMap";
898     return description;
899 }
900 
DescriptionForHashSet()901 std::string ObjectRemoteObject::DescriptionForHashSet()
902 {
903     std::string description = "HashSet";
904     return description;
905 }
906 
DescriptionForLightWeightMap()907 std::string ObjectRemoteObject::DescriptionForLightWeightMap()
908 {
909     std::string description = "LightWeightMap";
910     return description;
911 }
912 
DescriptionForLightWeightSet()913 std::string ObjectRemoteObject::DescriptionForLightWeightSet()
914 {
915     std::string description = "LightWeightSet";
916     return description;
917 }
918 
DescriptionForLinkedList()919 std::string ObjectRemoteObject::DescriptionForLinkedList()
920 {
921     std::string description = "LinkedList";
922     return description;
923 }
924 
DescriptionForList()925 std::string ObjectRemoteObject::DescriptionForList()
926 {
927     std::string description = "List";
928     return description;
929 }
930 
DescriptionForPlainArray()931 std::string ObjectRemoteObject::DescriptionForPlainArray()
932 {
933     std::string description = "PlainArray";
934     return description;
935 }
936 
DescriptionForQueue()937 std::string ObjectRemoteObject::DescriptionForQueue()
938 {
939     std::string description = "Queue";
940     return description;
941 }
942 
DescriptionForStack()943 std::string ObjectRemoteObject::DescriptionForStack()
944 {
945     std::string description = "Stack";
946     return description;
947 }
948 
DescriptionForTreeMap()949 std::string ObjectRemoteObject::DescriptionForTreeMap()
950 {
951     std::string description = "TreeMap";
952     return description;
953 }
954 
DescriptionForTreeSet()955 std::string ObjectRemoteObject::DescriptionForTreeSet()
956 {
957     std::string description = "TreeSet";
958     return description;
959 }
960 
DescriptionForVector()961 std::string ObjectRemoteObject::DescriptionForVector()
962 {
963     std::string description = "Vector";
964     return description;
965 }
966 
DescriptionForSymbol(const EcmaVM *ecmaVm, Local<SymbolRef> tagged) const967 std::string SymbolRemoteObject::DescriptionForSymbol(const EcmaVM *ecmaVm, Local<SymbolRef> tagged) const
968 {
969     std::string description = "Symbol(" + tagged->GetDescription(ecmaVm)->ToString(ecmaVm) + ")";
970     return description;
971 }
972 
DescriptionForFunction(const EcmaVM *ecmaVm, Local<FunctionRef> tagged) const973 std::string FunctionRemoteObject::DescriptionForFunction(const EcmaVM *ecmaVm, Local<FunctionRef> tagged) const
974 {
975     std::string sourceCode;
976     if (tagged->IsNative(ecmaVm)) {
977         sourceCode = "[native code]";
978     } else {
979         sourceCode = "[js code]";
980     }
981     Local<StringRef> name = tagged->GetName(ecmaVm);
982     std::string description = "function " + name->ToString(ecmaVm) + "( { " + sourceCode + " }";
983     return description;
984 }
985 
DescriptionForGeneratorFunction(const EcmaVM *ecmaVm, Local<FunctionRef> tagged) const986 std::string GeneratorFunctionRemoteObject::DescriptionForGeneratorFunction(const EcmaVM *ecmaVm,
987     Local<FunctionRef> tagged) const
988 {
989     std::string sourceCode;
990     if (tagged->IsNative(ecmaVm)) {
991         sourceCode = "[native code]";
992     } else {
993         sourceCode = "[js code]";
994     }
995     Local<StringRef> name = tagged->GetName(ecmaVm);
996     std::string description = "function* " + name->ToString(ecmaVm) + "( { " + sourceCode + " }";
997     return description;
998 }
999 
Create(const PtJson &params)1000 std::unique_ptr<RemoteObject> RemoteObject::Create(const PtJson &params)
1001 {
1002     std::string error;
1003     auto remoteObject = std::make_unique<RemoteObject>();
1004     Result ret;
1005 
1006     std::string type;
1007     ret = params.GetString("type", &type);
1008     if (ret == Result::SUCCESS) {
1009         if (ObjectType::Valid(type)) {
1010             remoteObject->type_ = std::move(type);
1011         } else {
1012             error += "'type' is invalid;";
1013         }
1014     } else {
1015         error += "Unknown or wrong type of 'type';";
1016     }
1017 
1018     std::string subType;
1019     ret = params.GetString("subtype", &subType);
1020     if (ret == Result::SUCCESS) {
1021         if (ObjectSubType::Valid(subType)) {
1022             remoteObject->subType_ = std::move(subType);
1023         } else {
1024             error += "'subtype' is invalid;";
1025         }
1026     } else if (ret == Result::TYPE_ERROR) {
1027         error += "Wrong type of 'subtype';";
1028     }
1029 
1030     std::string className;
1031     ret = params.GetString("className", &className);
1032     if (ret == Result::SUCCESS) {
1033         remoteObject->className_ = std::move(className);
1034     } else if (ret == Result::TYPE_ERROR) {
1035         error += "Wrong type of 'className';";
1036     }
1037 
1038     std::string unserializableValue;
1039     ret = params.GetString("unserializableValue", &unserializableValue);
1040     if (ret == Result::SUCCESS) {
1041         remoteObject->unserializableValue_ = std::move(unserializableValue);
1042     } else if (ret == Result::TYPE_ERROR) {
1043         error += "Wrong type of 'unserializableValue';";
1044     }
1045 
1046     std::string description;
1047     ret = params.GetString("description", &description);
1048     if (ret == Result::SUCCESS) {
1049         remoteObject->description_ = std::move(description);
1050     } else if (ret == Result::TYPE_ERROR) {
1051         error += "Wrong type of 'description';";
1052     }
1053 
1054     std::string objectId;
1055     ret = params.GetString("objectId", &objectId);
1056     if (ret == Result::SUCCESS) {
1057         if (!ToolchainUtils::StrToInt32(objectId, remoteObject->objectId_)) {
1058             error += "Failed to convert 'objectId' from string to int;";
1059         }
1060     } else if (ret == Result::TYPE_ERROR) {
1061         error += "Wrong type of 'objectId';";
1062     }
1063 
1064     if (!error.empty()) {
1065         LOG_DEBUGGER(ERROR) << "RemoteObject::Create " << error;
1066         return nullptr;
1067     }
1068 
1069     return remoteObject;
1070 }
1071 
ToJson() const1072 std::unique_ptr<PtJson> RemoteObject::ToJson() const
1073 {
1074     std::unique_ptr<PtJson> result = PtJson::CreateObject();
1075 
1076     result->Add("type", type_.c_str());
1077     if (subType_) {
1078         result->Add("subtype", subType_->c_str());
1079     }
1080     if (className_) {
1081         result->Add("className", className_->c_str());
1082     }
1083     if (unserializableValue_) {
1084         result->Add("unserializableValue", unserializableValue_->c_str());
1085     }
1086     if (description_) {
1087         result->Add("description", description_->c_str());
1088     }
1089     if (objectId_) {
1090         result->Add("objectId", std::to_string(objectId_.value()).c_str());
1091     }
1092 
1093     return result;
1094 }
1095 
Create(const PtJson &params)1096 std::unique_ptr<ExceptionDetails> ExceptionDetails::Create(const PtJson &params)
1097 {
1098     std::string error;
1099     auto exceptionDetails = std::make_unique<ExceptionDetails>();
1100     Result ret;
1101 
1102     int32_t exceptionId;
1103     ret = params.GetInt("exceptionId", &exceptionId);
1104     if (ret == Result::SUCCESS) {
1105         exceptionDetails->exceptionId_ = exceptionId;
1106     } else {
1107         error += "Unknown or wrong type of 'exceptionId';";
1108     }
1109 
1110     std::string text;
1111     ret = params.GetString("text", &text);
1112     if (ret == Result::SUCCESS) {
1113         exceptionDetails->text_ = std::move(text);
1114     } else {
1115         error += "Unknown or wrong type of 'text';";
1116     }
1117 
1118     int32_t lineNumber;
1119     ret = params.GetInt("lineNumber", &lineNumber);
1120     if (ret == Result::SUCCESS) {
1121         exceptionDetails->lineNumber_ = lineNumber;
1122     } else {
1123         error += "Unknown or wrong type of 'lineNumber';";
1124     }
1125 
1126     int32_t columnNumber;
1127     ret = params.GetInt("columnNumber", &columnNumber);
1128     if (ret == Result::SUCCESS) {
1129         exceptionDetails->columnNumber_ = columnNumber;
1130     } else {
1131         error += "Unknown or wrong type of 'columnNumber';";
1132     }
1133 
1134     std::string scriptId;
1135     ret = params.GetString("scriptId", &scriptId);
1136     if (ret == Result::SUCCESS) {
1137         if (!ToolchainUtils::StrToInt32(scriptId, exceptionDetails->scriptId_)) {
1138             error += "Failed to convert 'scriptId' from string to int;";
1139         }
1140     } else if (ret == Result::TYPE_ERROR) {
1141         error += "Wrong type of 'scriptId';";
1142     }
1143 
1144     std::string url;
1145     ret = params.GetString("url", &url);
1146     if (ret == Result::SUCCESS) {
1147         exceptionDetails->url_ = std::move(url);
1148     } else if (ret == Result::TYPE_ERROR) {
1149         error += "Wrong type of 'url';";
1150     }
1151 
1152     std::unique_ptr<PtJson> exception;
1153     ret = params.GetObject("exception", &exception);
1154     if (ret == Result::SUCCESS) {
1155         std::unique_ptr<RemoteObject> obj = RemoteObject::Create(*exception);
1156         if (obj == nullptr) {
1157             error += "'exception' format error;";
1158         } else {
1159             exceptionDetails->exception_ = std::move(obj);
1160         }
1161     } else if (ret == Result::TYPE_ERROR) {
1162         error += "Wrong type of 'exception';";
1163     }
1164 
1165     int32_t executionContextId;
1166     ret = params.GetInt("executionContextId", &executionContextId);
1167     if (ret == Result::SUCCESS) {
1168         exceptionDetails->executionContextId_ = executionContextId;
1169     } else if (ret == Result::TYPE_ERROR) {
1170         error += "Wrong type of 'executionContextId';";
1171     }
1172 
1173     if (!error.empty()) {
1174         LOG_DEBUGGER(ERROR) << "ExceptionDetails::Create " << error;
1175         return nullptr;
1176     }
1177 
1178     return exceptionDetails;
1179 }
1180 
ToJson() const1181 std::unique_ptr<PtJson> ExceptionDetails::ToJson() const
1182 {
1183     std::unique_ptr<PtJson> result = PtJson::CreateObject();
1184 
1185     result->Add("exceptionId", exceptionId_);
1186     result->Add("text", text_.c_str());
1187     result->Add("lineNumber", lineNumber_);
1188     result->Add("columnNumber", columnNumber_);
1189 
1190     if (scriptId_) {
1191         result->Add("scriptId", std::to_string(scriptId_.value()).c_str());
1192     }
1193     if (url_) {
1194         result->Add("url", url_->c_str());
1195     }
1196     if (exception_) {
1197         ASSERT(exception_.value() != nullptr);
1198         result->Add("exception", exception_.value()->ToJson());
1199     }
1200     if (executionContextId_) {
1201         result->Add("executionContextId", executionContextId_.value());
1202     }
1203 
1204     return result;
1205 }
1206 
Create(const PtJson &params)1207 std::unique_ptr<InternalPropertyDescriptor> InternalPropertyDescriptor::Create(const PtJson &params)
1208 {
1209     std::string error;
1210     auto internalPropertyDescriptor = std::make_unique<InternalPropertyDescriptor>();
1211     Result ret;
1212 
1213     std::string name;
1214     ret = params.GetString("name", &name);
1215     if (ret == Result::SUCCESS) {
1216         internalPropertyDescriptor->name_ = std::move(name);
1217     } else {
1218         error += "Unknown or wrong type of 'name';";
1219     }
1220 
1221     std::unique_ptr<PtJson> value;
1222     ret = params.GetObject("value", &value);
1223     if (ret == Result::SUCCESS) {
1224         std::unique_ptr<RemoteObject> obj = RemoteObject::Create(*value);
1225         if (obj == nullptr) {
1226             error += "'value' format error;";
1227         } else {
1228             internalPropertyDescriptor->value_ = std::move(obj);
1229         }
1230     } else if (ret == Result::TYPE_ERROR) {
1231         error += "Wrong type of 'value';";
1232     }
1233 
1234     if (!error.empty()) {
1235         LOG_DEBUGGER(ERROR) << "InternalPropertyDescriptor::Create " << error;
1236         return nullptr;
1237     }
1238 
1239     return internalPropertyDescriptor;
1240 }
1241 
ToJson() const1242 std::unique_ptr<PtJson> InternalPropertyDescriptor::ToJson() const
1243 {
1244     std::unique_ptr<PtJson> result = PtJson::CreateObject();
1245 
1246     result->Add("name", name_.c_str());
1247     if (value_) {
1248         ASSERT(value_.value() != nullptr);
1249         result->Add("value", value_.value()->ToJson());
1250     }
1251 
1252     return result;
1253 }
1254 
Create(const PtJson &params)1255 std::unique_ptr<PrivatePropertyDescriptor> PrivatePropertyDescriptor::Create(const PtJson &params)
1256 {
1257     std::string error;
1258     auto privatePropertyDescriptor = std::make_unique<PrivatePropertyDescriptor>();
1259     Result ret;
1260 
1261     std::string name;
1262     ret = params.GetString("name", &name);
1263     if (ret == Result::SUCCESS) {
1264         privatePropertyDescriptor->name_ = std::move(name);
1265     } else {
1266         error += "Unknown or wrong type of 'name';";
1267     }
1268 
1269     std::unique_ptr<PtJson> value;
1270     ret = params.GetObject("value", &value);
1271     std::unique_ptr<RemoteObject> obj;
1272     if (ret == Result::SUCCESS) {
1273         obj = RemoteObject::Create(*value);
1274         if (obj == nullptr) {
1275             error += "'value' format error;";
1276         } else {
1277             privatePropertyDescriptor->value_ = std::move(obj);
1278         }
1279     } else if (ret == Result::TYPE_ERROR) {
1280         error += "Wrong type of 'value';";
1281     }
1282 
1283     std::unique_ptr<PtJson> get;
1284     ret = params.GetObject("get", &get);
1285     if (ret == Result::SUCCESS) {
1286         obj = RemoteObject::Create(*get);
1287         if (obj == nullptr) {
1288             error += "'get' format error;";
1289         } else {
1290             privatePropertyDescriptor->get_ = std::move(obj);
1291         }
1292     } else if (ret == Result::TYPE_ERROR) {
1293         error += "Wrong type of 'get';";
1294     }
1295 
1296     std::unique_ptr<PtJson> set;
1297     ret = params.GetObject("set", &set);
1298     if (ret == Result::SUCCESS) {
1299         obj = RemoteObject::Create(*set);
1300         if (obj == nullptr) {
1301             error += "'set' format error;";
1302         } else {
1303             privatePropertyDescriptor->set_ = std::move(obj);
1304         }
1305     } else if (ret == Result::TYPE_ERROR) {
1306         error += "Wrong type of 'set';";
1307     }
1308 
1309     if (!error.empty()) {
1310         LOG_DEBUGGER(ERROR) << "PrivatePropertyDescriptor::Create " << error;
1311         return nullptr;
1312     }
1313 
1314     return privatePropertyDescriptor;
1315 }
1316 
ToJson() const1317 std::unique_ptr<PtJson> PrivatePropertyDescriptor::ToJson() const
1318 {
1319     std::unique_ptr<PtJson> result = PtJson::CreateObject();
1320 
1321     result->Add("name", name_.c_str());
1322     if (value_) {
1323         ASSERT(value_.value() != nullptr);
1324         result->Add("value", value_.value()->ToJson());
1325     }
1326     if (get_) {
1327         ASSERT(get_.value() != nullptr);
1328         result->Add("get", get_.value()->ToJson());
1329     }
1330     if (set_) {
1331         ASSERT(set_.value() != nullptr);
1332         result->Add("set", set_.value()->ToJson());
1333     }
1334 
1335     return result;
1336 }
1337 
FromProperty(const EcmaVM *ecmaVm, Local<JSValueRef> name, const PropertyAttribute &property)1338 std::unique_ptr<PropertyDescriptor> PropertyDescriptor::FromProperty(const EcmaVM *ecmaVm,
1339     Local<JSValueRef> name, const PropertyAttribute &property)
1340 {
1341     std::unique_ptr<PropertyDescriptor> debuggerProperty = std::make_unique<PropertyDescriptor>();
1342 
1343     std::string nameStr;
1344     if (name->IsSymbol(ecmaVm)) {
1345         Local<SymbolRef> symbol(name);
1346         nameStr = "Symbol(" + Local<SymbolRef>(name)->GetDescription(ecmaVm)->ToString(ecmaVm) + ")";
1347         debuggerProperty->symbol_ = RemoteObject::FromTagged(ecmaVm, name);
1348     } else {
1349         nameStr = name->ToString(ecmaVm)->ToString(ecmaVm);
1350     }
1351 
1352     debuggerProperty->name_ = nameStr;
1353     if (property.HasValue()) {
1354         debuggerProperty->value_ = RemoteObject::FromTagged(ecmaVm, property.GetValue(ecmaVm));
1355     }
1356     if (property.HasWritable()) {
1357         debuggerProperty->writable_ = property.IsWritable();
1358     }
1359     if (property.HasGetter()) {
1360         debuggerProperty->get_ = RemoteObject::FromTagged(ecmaVm, property.GetGetter(ecmaVm));
1361     }
1362     if (property.HasSetter()) {
1363         debuggerProperty->set_ = RemoteObject::FromTagged(ecmaVm, property.GetSetter(ecmaVm));
1364     }
1365     debuggerProperty->configurable_ = property.IsConfigurable();
1366     debuggerProperty->enumerable_ = property.IsEnumerable();
1367     debuggerProperty->isOwn_ = true;
1368 
1369     return debuggerProperty;
1370 }
1371 
Create(const PtJson &params)1372 std::unique_ptr<PropertyDescriptor> PropertyDescriptor::Create(const PtJson &params)
1373 {
1374     std::string error;
1375     auto propertyDescriptor = std::make_unique<PropertyDescriptor>();
1376     Result ret;
1377 
1378     std::string name;
1379     ret = params.GetString("name", &name);
1380     if (ret == Result::SUCCESS) {
1381         propertyDescriptor->name_ = std::move(name);
1382     } else {
1383         error += "Unknown or wrong type of 'name';";
1384     }
1385 
1386     std::unique_ptr<PtJson> value;
1387     std::unique_ptr<RemoteObject> obj;
1388     ret = params.GetObject("value", &value);
1389     if (ret == Result::SUCCESS) {
1390         obj = RemoteObject::Create(*value);
1391         if (obj == nullptr) {
1392             error += "'value' format error;";
1393         } else {
1394             propertyDescriptor->value_ = std::move(obj);
1395         }
1396     } else if (ret == Result::TYPE_ERROR) {
1397         error += "Wrong type of 'value';";
1398     }
1399 
1400     bool writable = false;
1401     ret = params.GetBool("writable", &writable);
1402     if (ret == Result::SUCCESS) {
1403         propertyDescriptor->writable_ = writable;
1404     } else if (ret == Result::TYPE_ERROR) {
1405         error += "Wrong type of 'writable';";
1406     }
1407 
1408     std::unique_ptr<PtJson> get;
1409     ret = params.GetObject("get", &get);
1410     if (ret == Result::SUCCESS) {
1411         obj = RemoteObject::Create(*get);
1412         if (obj == nullptr) {
1413             error += "'get' format error;";
1414         } else {
1415             propertyDescriptor->get_ = std::move(obj);
1416         }
1417     } else if (ret == Result::TYPE_ERROR) {
1418         error += "Wrong type of 'get';";
1419     }
1420 
1421     std::unique_ptr<PtJson> set;
1422     ret = params.GetObject("set", &set);
1423     if (ret == Result::SUCCESS) {
1424         obj = RemoteObject::Create(*set);
1425         if (obj == nullptr) {
1426             error += "'set' format error;";
1427         } else {
1428             propertyDescriptor->set_ = std::move(obj);
1429         }
1430     } else if (ret == Result::TYPE_ERROR) {
1431         error += "Wrong type of 'set';";
1432     }
1433 
1434     bool configurable = false;
1435     ret = params.GetBool("configurable", &configurable);
1436     if (ret == Result::SUCCESS) {
1437         propertyDescriptor->configurable_ = configurable;
1438     } else if (ret == Result::TYPE_ERROR) {
1439         error += "Wrong type of 'configurable';";
1440     }
1441 
1442     bool enumerable = false;
1443     ret = params.GetBool("enumerable", &enumerable);
1444     if (ret == Result::SUCCESS) {
1445         propertyDescriptor->enumerable_ = enumerable;
1446     } else if (ret == Result::TYPE_ERROR) {
1447         error += "Wrong type of 'enumerable';";
1448     }
1449 
1450     bool wasThrown = false;
1451     ret = params.GetBool("wasThrown", &wasThrown);
1452     if (ret == Result::SUCCESS) {
1453         propertyDescriptor->wasThrown_ = wasThrown;
1454     } else if (ret == Result::TYPE_ERROR) {
1455         error += "Wrong type of 'wasThrown';";
1456     }
1457 
1458     bool isOwn = false;
1459     ret = params.GetBool("isOwn", &isOwn);
1460     if (ret == Result::SUCCESS) {
1461         propertyDescriptor->isOwn_ = isOwn;
1462     } else if (ret == Result::TYPE_ERROR) {
1463         error += "Wrong type of 'isOwn';";
1464     }
1465 
1466     std::unique_ptr<PtJson> symbol;
1467     ret = params.GetObject("symbol", &symbol);
1468     if (ret == Result::SUCCESS) {
1469         obj = RemoteObject::Create(*symbol);
1470         if (obj == nullptr) {
1471             error += "'symbol' format error;";
1472         } else {
1473             propertyDescriptor->symbol_ = std::move(obj);
1474         }
1475     } else if (ret == Result::TYPE_ERROR) {
1476         error += "Wrong type of 'symbol';";
1477     }
1478 
1479     if (!error.empty()) {
1480         LOG_DEBUGGER(ERROR) << "PropertyDescriptor::Create " << error;
1481         return nullptr;
1482     }
1483 
1484     return propertyDescriptor;
1485 }
1486 
ToJson() const1487 std::unique_ptr<PtJson> PropertyDescriptor::ToJson() const
1488 {
1489     std::unique_ptr<PtJson> result = PtJson::CreateObject();
1490 
1491     result->Add("name", name_.c_str());
1492     if (value_) {
1493         ASSERT(value_.value() != nullptr);
1494         result->Add("value", value_.value()->ToJson());
1495     }
1496     if (writable_) {
1497         result->Add("writable", writable_.value());
1498     }
1499     if (get_) {
1500         ASSERT(get_.value() != nullptr);
1501         result->Add("get", get_.value()->ToJson());
1502     }
1503     if (set_) {
1504         ASSERT(set_.value() != nullptr);
1505         result->Add("set", set_.value()->ToJson());
1506     }
1507     result->Add("configurable", configurable_);
1508     result->Add("enumerable", enumerable_);
1509     if (wasThrown_) {
1510         result->Add("wasThrown", wasThrown_.value());
1511     }
1512     if (isOwn_) {
1513         result->Add("isOwn", isOwn_.value());
1514     }
1515     if (symbol_) {
1516         ASSERT(symbol_.value() != nullptr);
1517         result->Add("symbol", symbol_.value()->ToJson());
1518     }
1519 
1520     return result;
1521 }
1522 
Create(const PtJson &params)1523 std::unique_ptr<CallArgument> CallArgument::Create(const PtJson &params)
1524 {
1525     auto callArgument = std::make_unique<CallArgument>();
1526     std::string error;
1527     Result ret;
1528 
1529     std::string unserializableValue;
1530     ret = params.GetString("unserializableValue", &unserializableValue);
1531     if (ret == Result::SUCCESS) {
1532         callArgument->unserializableValue_ = std::move(unserializableValue);
1533     } else if (ret == Result::TYPE_ERROR) {  // optional value
1534         error += "Wrong type of 'unserializableValue';";
1535     }
1536     std::string objectId;
1537     ret = params.GetString("objectId", &objectId);
1538     if (ret == Result::SUCCESS) {
1539         if (!ToolchainUtils::StrToInt32(objectId, callArgument->objectId_)) {
1540             error += "Failed to convert 'objectId' from string to int;";
1541         }
1542     } else if (ret == Result::TYPE_ERROR) {  // optional value
1543         error += "Wrong type of 'objectId';";
1544     }
1545 
1546     if (!error.empty()) {
1547         LOG_DEBUGGER(ERROR) << "CallArgument::Create " << error;
1548         return nullptr;
1549     }
1550 
1551     return callArgument;
1552 }
1553 
ToJson() const1554 std::unique_ptr<PtJson> CallArgument::ToJson() const
1555 {
1556     std::unique_ptr<PtJson> result = PtJson::CreateObject();
1557 
1558     if (unserializableValue_) {
1559         result->Add("unserializableValue", unserializableValue_->c_str());
1560     }
1561     if (objectId_) {
1562         result->Add("objectId", std::to_string(objectId_.value()).c_str());
1563     }
1564 
1565     return result;
1566 }
1567 
Create(const PtJson &params)1568 std::unique_ptr<Location> Location::Create(const PtJson &params)
1569 {
1570     auto location = std::make_unique<Location>();
1571     std::string error;
1572     Result ret;
1573 
1574     std::string scriptId;
1575     ret = params.GetString("scriptId", &scriptId);
1576     if (ret == Result::SUCCESS) {
1577         if (!ToolchainUtils::StrToInt32(scriptId, location->scriptId_)) {
1578             error += "Failed to convert 'scriptId' from string to int;";
1579         }
1580     } else {
1581         error += "Unknown or wrong type of 'scriptId';";
1582     }
1583     int32_t lineNumber;
1584     ret = params.GetInt("lineNumber", &lineNumber);
1585     if (ret == Result::SUCCESS) {
1586         location->lineNumber_ = lineNumber;
1587     } else {
1588         error += "Unknown or wrong type of 'lineNumber';";
1589     }
1590     int32_t columnNumber;
1591     ret = params.GetInt("columnNumber", &columnNumber);
1592     if (ret == Result::SUCCESS) {
1593         location->columnNumber_ = columnNumber;
1594     } else if (ret == Result::TYPE_ERROR) {  // optional value
1595         error += "Wrong type of 'columnNumber';";
1596     }
1597 
1598     if (!error.empty()) {
1599         LOG_DEBUGGER(ERROR) << "Location::Create " << error;
1600         return nullptr;
1601     }
1602 
1603     return location;
1604 }
1605 
ToJson() const1606 std::unique_ptr<PtJson> Location::ToJson() const
1607 {
1608     std::unique_ptr<PtJson> result = PtJson::CreateObject();
1609 
1610     result->Add("scriptId", std::to_string(scriptId_).c_str());
1611     result->Add("lineNumber", lineNumber_);
1612     if (columnNumber_) {
1613         result->Add("columnNumber", columnNumber_.value());
1614     }
1615 
1616     return result;
1617 }
1618 
Create(const PtJson &params)1619 std::unique_ptr<ScriptPosition> ScriptPosition::Create(const PtJson &params)
1620 {
1621     auto scriptPosition = std::make_unique<ScriptPosition>();
1622     std::string error;
1623     Result ret;
1624 
1625     int32_t lineNumber;
1626     ret = params.GetInt("lineNumber", &lineNumber);
1627     if (ret == Result::SUCCESS) {
1628         scriptPosition->lineNumber_ = lineNumber;
1629     } else {
1630         error += "Unknown or wrong type of 'lineNumber';";
1631     }
1632     int32_t columnNumber;
1633     ret = params.GetInt("columnNumber", &columnNumber);
1634     if (ret == Result::SUCCESS) {
1635         scriptPosition->columnNumber_ = columnNumber;
1636     } else {
1637         error += "Unknown or wrong type of 'columnNumber';";
1638     }
1639 
1640     if (!error.empty()) {
1641         LOG_DEBUGGER(ERROR) << "ScriptPosition::Create " << error;
1642         return nullptr;
1643     }
1644 
1645     return scriptPosition;
1646 }
1647 
ToJson() const1648 std::unique_ptr<PtJson> ScriptPosition::ToJson() const
1649 {
1650     std::unique_ptr<PtJson> result = PtJson::CreateObject();
1651 
1652     result->Add("lineNumber", lineNumber_);
1653     result->Add("columnNumber", columnNumber_);
1654 
1655     return result;
1656 }
1657 
Create(const PtJson &params)1658 std::unique_ptr<SearchMatch> SearchMatch::Create(const PtJson &params)
1659 {
1660     std::string error;
1661     auto locationSearch = std::make_unique<SearchMatch>();
1662     Result ret;
1663 
1664     int32_t lineNumber;
1665     ret = params.GetInt("lineNumber", &lineNumber);
1666     if (ret == Result::SUCCESS) {
1667         locationSearch->lineNumber_ = lineNumber;
1668     } else {
1669         error += "Unknown or wrong type of 'lineNumber';";
1670     }
1671 
1672     std::string lineContent;
1673     ret = params.GetString("lineContent", &lineContent);
1674     if (ret == Result::SUCCESS) {
1675         locationSearch->lineContent_ = std::move(lineContent);
1676     } else {
1677         error += "Unknown or wrong type of 'lineContent';";
1678     }
1679 
1680     if (!error.empty()) {
1681         LOG_DEBUGGER(ERROR) << "SearchMatch::Create " << error;
1682         return nullptr;
1683     }
1684 
1685     return locationSearch;
1686 }
1687 
ToJson() const1688 std::unique_ptr<PtJson> SearchMatch::ToJson() const
1689 {
1690     std::unique_ptr<PtJson> result = PtJson::CreateObject();
1691 
1692     result->Add("lineNumber", lineNumber_);
1693     result->Add("lineContent", lineContent_.c_str());
1694 
1695     return result;
1696 }
1697 
Create(const PtJson &params)1698 std::unique_ptr<LocationRange> LocationRange::Create(const PtJson &params)
1699 {
1700     std::string error;
1701     auto locationRange = std::make_unique<LocationRange>();
1702     Result ret;
1703 
1704     std::string scriptId;
1705     ret = params.GetString("scriptId", &scriptId);
1706     if (ret == Result::SUCCESS) {
1707         if (!ToolchainUtils::StrToInt32(scriptId, locationRange->scriptId_)) {
1708             error += "Failed to convert 'scriptId' from string to int;";
1709         }
1710     } else {
1711         error += "Unknown or wrong type of 'scriptId';";
1712     }
1713 
1714     std::unique_ptr<PtJson> start;
1715     std::unique_ptr<ScriptPosition> obj;
1716     ret = params.GetObject("start", &start);
1717     if (ret == Result::SUCCESS) {
1718         obj = ScriptPosition::Create(*start);
1719         if (obj == nullptr) {
1720             error += "'start' format error;";
1721         } else {
1722             locationRange->start_ = std::move(obj);
1723         }
1724     } else {
1725         error += "Unknown or wrong type of 'start';";
1726     }
1727 
1728     std::unique_ptr<PtJson> end;
1729     ret = params.GetObject("end", &end);
1730     if (ret == Result::SUCCESS) {
1731         obj = ScriptPosition::Create(*end);
1732         if (obj == nullptr) {
1733             error += "'end' format error;";
1734         } else {
1735             locationRange->end_ = std::move(obj);
1736         }
1737     } else {
1738         error += "Unknown or wrong type of 'end';";
1739     }
1740 
1741     if (!error.empty()) {
1742         LOG_DEBUGGER(ERROR) << "LocationRange::Create " << error;
1743         return nullptr;
1744     }
1745 
1746     return locationRange;
1747 }
1748 
ToJson() const1749 std::unique_ptr<PtJson> LocationRange::ToJson() const
1750 {
1751     std::unique_ptr<PtJson> result = PtJson::CreateObject();
1752 
1753     result->Add("scriptId", std::to_string(scriptId_).c_str());
1754     ASSERT(start_ != nullptr);
1755     result->Add("start", start_->ToJson());
1756     ASSERT(end_ != nullptr);
1757     result->Add("end", end_->ToJson());
1758 
1759     return result;
1760 }
1761 
Create(const PtJson &params)1762 std::unique_ptr<NativeRange> NativeRange::Create(const PtJson &params)
1763 {
1764     std::string error;
1765     auto nativeRange = std::make_unique<NativeRange>();
1766     Result ret;
1767 
1768     uint64_t start;
1769     ret = params.GetUInt64("start", &start);
1770     if (ret == Result::SUCCESS) {
1771         nativeRange->start_ = std::move(start);
1772     } else {
1773         error += "Unknown 'start';";
1774     }
1775 
1776     uint64_t end;
1777     ret = params.GetUInt64("end", &end);
1778     if (ret == Result::SUCCESS) {
1779         nativeRange->end_ = std::move(end);
1780     } else {
1781         error += "Unknown 'end';";
1782     }
1783 
1784     if (!error.empty()) {
1785         LOG_DEBUGGER(ERROR) << "NativeRange::Create " << error;
1786         return nullptr;
1787     }
1788 
1789     return nativeRange;
1790 }
1791 
Create(const PtJson &params)1792 std::unique_ptr<BreakLocation> BreakLocation::Create(const PtJson &params)
1793 {
1794     std::string error;
1795     auto breakLocation = std::make_unique<BreakLocation>();
1796     Result ret;
1797 
1798     std::string scriptId;
1799     ret = params.GetString("scriptId", &scriptId);
1800     if (ret == Result::SUCCESS) {
1801         if (!ToolchainUtils::StrToInt32(scriptId, breakLocation->scriptId_)) {
1802             error += "Failed to convert 'scriptId' from string to int;";
1803         }
1804     } else {
1805         error += "Unknown or wrong type of 'scriptId';";
1806     }
1807 
1808     int32_t lineNumber;
1809     ret = params.GetInt("lineNumber", &lineNumber);
1810     if (ret == Result::SUCCESS) {
1811         breakLocation->lineNumber_ = lineNumber;
1812     } else {
1813         error += "Unknown or wrong type of 'lineNumber';";
1814     }
1815 
1816     int32_t columnNumber;
1817     ret = params.GetInt("columnNumber", &columnNumber);
1818     if (ret == Result::SUCCESS) {
1819         breakLocation->columnNumber_ = columnNumber;
1820     } else if (ret == Result::TYPE_ERROR) {
1821         error += "Wrong type of 'columnNumber';";
1822     }
1823 
1824     std::string type;
1825     ret = params.GetString("type", &type);
1826     if (ret == Result::SUCCESS) {
1827         if (BreakType::Valid(type)) {
1828             breakLocation->type_ = std::move(type);
1829         } else {
1830             error += "'type' is invalid;";
1831         }
1832     } else if (ret == Result::TYPE_ERROR) {
1833         error += "type 'scriptId';";
1834     }
1835 
1836     if (!error.empty()) {
1837         LOG_DEBUGGER(ERROR) << "Location::Create " << error;
1838         return nullptr;
1839     }
1840 
1841     return breakLocation;
1842 }
1843 
ToJson() const1844 std::unique_ptr<PtJson> BreakLocation::ToJson() const
1845 {
1846     std::unique_ptr<PtJson> result = PtJson::CreateObject();
1847 
1848     result->Add("scriptId", std::to_string(scriptId_).c_str());
1849     result->Add("lineNumber", lineNumber_);
1850     if (columnNumber_) {
1851         result->Add("columnNumber", columnNumber_.value());
1852     }
1853     if (type_) {
1854         result->Add("type", type_->c_str());
1855     }
1856 
1857     return result;
1858 }
1859 
Create(const PtJson &params)1860 std::unique_ptr<Scope> Scope::Create(const PtJson &params)
1861 {
1862     std::string error;
1863     auto scope = std::make_unique<Scope>();
1864     Result ret;
1865 
1866     std::string type;
1867     ret = params.GetString("type", &type);
1868     if (ret == Result::SUCCESS) {
1869         if (Scope::Type::Valid(type)) {
1870             scope->type_ = std::move(type);
1871         } else {
1872             error += "'type' is invalid;";
1873         }
1874     } else {
1875         error += "Unknown or wrong type of 'type';";
1876     }
1877 
1878     std::unique_ptr<PtJson> object;
1879     std::unique_ptr<RemoteObject> remoteObject;
1880     ret = params.GetObject("object", &object);
1881     if (ret == Result::SUCCESS) {
1882         remoteObject = RemoteObject::Create(*object);
1883         if (remoteObject == nullptr) {
1884             error += "'object' format error;";
1885         } else {
1886             scope->object_ = std::move(remoteObject);
1887         }
1888     } else {
1889         error += "Unknown or wrong type of 'object';";
1890     }
1891 
1892     std::string name;
1893     ret = params.GetString("name", &name);
1894     if (ret == Result::SUCCESS) {
1895         scope->name_ = std::move(name);
1896     } else if (ret == Result::TYPE_ERROR) {
1897         error += "Wrong type of 'name';";
1898     }
1899 
1900     std::unique_ptr<PtJson> startLocation;
1901     std::unique_ptr<Location> obj;
1902     ret = params.GetObject("startLocation", &startLocation);
1903     if (ret == Result::SUCCESS) {
1904         obj = Location::Create(*startLocation);
1905         if (obj == nullptr) {
1906             error += "'startLocation' format error;";
1907         } else {
1908             scope->startLocation_ = std::move(obj);
1909         }
1910     } else if (ret == Result::TYPE_ERROR) {
1911         error += "Wrong type of 'startLocation';";
1912     }
1913 
1914     std::unique_ptr<PtJson> endLocation;
1915     ret = params.GetObject("endLocation", &endLocation);
1916     if (ret == Result::SUCCESS) {
1917         obj = Location::Create(*endLocation);
1918         if (obj == nullptr) {
1919             error += "'endLocation' format error;";
1920         } else {
1921             scope->endLocation_ = std::move(obj);
1922         }
1923     } else if (ret == Result::TYPE_ERROR) {
1924         error += "Wrong type of 'endLocation';";
1925     }
1926 
1927     if (!error.empty()) {
1928         LOG_DEBUGGER(ERROR) << "Location::Create " << error;
1929         return nullptr;
1930     }
1931 
1932     return scope;
1933 }
1934 
ToJson() const1935 std::unique_ptr<PtJson> Scope::ToJson() const
1936 {
1937     std::unique_ptr<PtJson> result = PtJson::CreateObject();
1938 
1939     result->Add("type", type_.c_str());
1940     ASSERT(object_ != nullptr);
1941     result->Add("object", object_->ToJson());
1942     if (name_) {
1943         result->Add("name", name_->c_str());
1944     }
1945     if (startLocation_) {
1946         ASSERT(startLocation_.value() != nullptr);
1947         result->Add("startLocation", startLocation_.value()->ToJson());
1948     }
1949     if (endLocation_) {
1950         ASSERT(endLocation_.value() != nullptr);
1951         result->Add("endLocation", endLocation_.value()->ToJson());
1952     }
1953 
1954     return result;
1955 }
1956 
Create(const PtJson &params)1957 std::unique_ptr<CallFrame> CallFrame::Create(const PtJson &params)
1958 {
1959     std::string error;
1960     auto callFrame = std::make_unique<CallFrame>();
1961     Result ret;
1962 
1963     std::string callFrameId;
1964     ret = params.GetString("callFrameId", &callFrameId);
1965     if (ret == Result::SUCCESS) {
1966         if (!ToolchainUtils::StrToInt32(callFrameId, callFrame->callFrameId_)) {
1967             error += "Failed to convert 'callFrameId' from string to int;";
1968         }
1969     } else {
1970         error += "Unknown or wrong type of 'callFrameId';";
1971     }
1972 
1973     std::string functionName;
1974     ret = params.GetString("functionName", &functionName);
1975     if (ret == Result::SUCCESS) {
1976         callFrame->functionName_ = std::move(functionName);
1977     } else {
1978         error += "Unknown or wrong type of 'functionName';";
1979     }
1980 
1981     std::unique_ptr<PtJson> functionLocation;
1982     std::unique_ptr<Location> obj;
1983     ret = params.GetObject("functionLocation", &functionLocation);
1984     if (ret == Result::SUCCESS) {
1985         obj = Location::Create(*functionLocation);
1986         if (obj == nullptr) {
1987             error += "'functionLocation' format error;";
1988         } else {
1989             callFrame->functionLocation_ = std::move(obj);
1990         }
1991     } else if (ret == Result::TYPE_ERROR) {
1992         error += "Wrong type of 'functionLocation';";
1993     }
1994 
1995     std::unique_ptr<PtJson> location;
1996     ret = params.GetObject("location", &location);
1997     if (ret == Result::SUCCESS) {
1998         obj = Location::Create(*location);
1999         if (obj == nullptr) {
2000             error += "'location' format error;";
2001         } else {
2002             callFrame->location_ = std::move(obj);
2003         }
2004     } else {
2005         error += "Unknown or wrong type of 'location';";
2006     }
2007 
2008     std::string url;
2009     ret = params.GetString("url", &url);
2010     if (ret == Result::SUCCESS) {
2011         callFrame->url_ = std::move(url);
2012     } else {
2013         error += "Unknown or wrong type of 'url';";
2014     }
2015 
2016     std::unique_ptr<PtJson> scopeChain;
2017     ret = params.GetArray("scopeChain", &scopeChain);
2018     if (ret == Result::SUCCESS) {
2019         int32_t len = scopeChain->GetSize();
2020         for (int32_t i = 0; i < len; ++i) {
2021             std::unique_ptr<PtJson> arrayEle = scopeChain->Get(i);
2022             ASSERT(arrayEle != nullptr);
2023             std::unique_ptr<Scope> scope = Scope::Create(*arrayEle);
2024             if (scope == nullptr) {
2025                 error += "'scopeChain' format error;";
2026             } else {
2027                 callFrame->scopeChain_.emplace_back(std::move(scope));
2028             }
2029         }
2030     } else {
2031         error += "Unknown or wrong type of 'scopeChain';";
2032     }
2033 
2034     std::unique_ptr<PtJson> thisObj;
2035     std::unique_ptr<RemoteObject> remoteObject;
2036     ret = params.GetObject("this", &thisObj);
2037     if (ret == Result::SUCCESS) {
2038         remoteObject = RemoteObject::Create(*thisObj);
2039         if (remoteObject == nullptr) {
2040             error += "'this' format error;";
2041         } else {
2042             callFrame->this_ = std::move(remoteObject);
2043         }
2044     } else {
2045         error += "Unknown or wrong type of 'this';";
2046     }
2047 
2048     std::unique_ptr<PtJson> returnValue;
2049     ret = params.GetObject("returnValue", &returnValue);
2050     if (ret == Result::SUCCESS) {
2051         remoteObject = RemoteObject::Create(*returnValue);
2052         if (remoteObject == nullptr) {
2053             error += "'returnValue' format error;";
2054         } else {
2055             callFrame->returnValue_ = std::move(remoteObject);
2056         }
2057     } else if (ret == Result::TYPE_ERROR) {
2058         error += "Wrong type of 'returnValue';";
2059     }
2060 
2061     if (!error.empty()) {
2062         LOG_DEBUGGER(ERROR) << "CallFrame::Create " << error;
2063         return nullptr;
2064     }
2065 
2066     return callFrame;
2067 }
2068 
ToJson() const2069 std::unique_ptr<PtJson> CallFrame::ToJson() const
2070 {
2071     std::unique_ptr<PtJson> result = PtJson::CreateObject();
2072 
2073     result->Add("callFrameId", std::to_string(callFrameId_).c_str());
2074     result->Add("functionName", functionName_.c_str());
2075 
2076     if (functionLocation_) {
2077         ASSERT(functionLocation_.value() != nullptr);
2078         result->Add("functionLocation", functionLocation_.value()->ToJson());
2079     }
2080     ASSERT(location_ != nullptr);
2081     result->Add("location", location_->ToJson());
2082     result->Add("url", url_.c_str());
2083 
2084     size_t len = scopeChain_.size();
2085     std::unique_ptr<PtJson> values = PtJson::CreateArray();
2086     for (size_t i = 0; i < len; i++) {
2087         ASSERT(scopeChain_[i] != nullptr);
2088         std::unique_ptr<PtJson> scope = scopeChain_[i]->ToJson();
2089         values->Push(scope);
2090     }
2091     result->Add("scopeChain", values);
2092 
2093     ASSERT(this_ != nullptr);
2094     result->Add("this", this_->ToJson());
2095     if (returnValue_) {
2096         ASSERT(returnValue_.value() != nullptr);
2097         result->Add("returnValue", returnValue_.value()->ToJson());
2098     }
2099 
2100     return result;
2101 }
2102 
Create(const PtJson &params)2103 std::unique_ptr<SamplingHeapProfileSample> SamplingHeapProfileSample::Create(const PtJson &params)
2104 {
2105     std::string error;
2106     auto samplingHeapProfileSample = std::make_unique<SamplingHeapProfileSample>();
2107     Result ret;
2108 
2109     int32_t size;
2110     ret = params.GetInt("size", &size);
2111     if (ret == Result::SUCCESS) {
2112         samplingHeapProfileSample->size_ = size;
2113     } else {
2114         error += "Unknown or wrong type of 'size';";
2115     }
2116     int32_t nodeId;
2117     ret = params.GetInt("nodeId", &nodeId);
2118     if (ret == Result::SUCCESS) {
2119         samplingHeapProfileSample->nodeId_ = nodeId;
2120     } else {
2121         error += "Unknown or wrong type of 'nodeId';";
2122     }
2123     int32_t ordinal;
2124     ret = params.GetInt("ordinal", &ordinal);
2125     if (ret == Result::SUCCESS) {
2126         samplingHeapProfileSample->ordinal_ = ordinal;
2127     } else {
2128         error += "Unknown or wrong type of 'ordinal';";
2129     }
2130     if (!error.empty()) {
2131         LOG_DEBUGGER(ERROR) << "SamplingHeapProfileSample::Create " << error;
2132         return nullptr;
2133     }
2134 
2135     return samplingHeapProfileSample;
2136 }
2137 
ToJson() const2138 std::unique_ptr<PtJson> SamplingHeapProfileSample::ToJson() const
2139 {
2140     std::unique_ptr<PtJson> result = PtJson::CreateObject();
2141 
2142     result->Add("size", size_);
2143     result->Add("nodeId", nodeId_);
2144     result->Add("ordinal", ordinal_);
2145 
2146     return result;
2147 }
2148 
Create(const PtJson &params)2149 std::unique_ptr<RuntimeCallFrame> RuntimeCallFrame::Create(const PtJson &params)
2150 {
2151     std::string error;
2152     auto runtimeCallFrame = std::make_unique<RuntimeCallFrame>();
2153     Result ret;
2154 
2155     std::string functionName;
2156     ret = params.GetString("functionName", &functionName);
2157     if (ret == Result::SUCCESS) {
2158         runtimeCallFrame->functionName_ = std::move(functionName);
2159     } else {
2160         error += "Unknown or wrong type of 'functionName';";
2161     }
2162 
2163     std::string moduleName;
2164     ret = params.GetString("moduleName", &moduleName);
2165     if (ret == Result::SUCCESS) {
2166         runtimeCallFrame->moduleName_ = std::move(moduleName);
2167     } else {
2168         error += "Unknown or wrong type of 'moduleName';";
2169     }
2170 
2171     std::string scriptId;
2172     ret = params.GetString("scriptId", &scriptId);
2173     if (ret == Result::SUCCESS) {
2174         runtimeCallFrame->scriptId_ = std::move(scriptId);
2175     } else {
2176         error += "Unknown or wrong type of 'scriptId';";
2177     }
2178 
2179     std::string url;
2180     ret = params.GetString("url", &url);
2181     if (ret == Result::SUCCESS) {
2182         runtimeCallFrame->url_ = std::move(url);
2183     } else {
2184         error += "Unknown or wrong type of 'url';";
2185     }
2186 
2187     int32_t lineNumber;
2188     ret = params.GetInt("lineNumber", &lineNumber);
2189     if (ret == Result::SUCCESS) {
2190         runtimeCallFrame->lineNumber_ = lineNumber;
2191     } else {
2192         error += "Unknown or wrong type of 'lineNumber';";
2193     }
2194 
2195     int32_t columnNumber;
2196     ret = params.GetInt("columnNumber", &columnNumber);
2197     if (ret == Result::SUCCESS) {
2198         runtimeCallFrame->columnNumber_ = columnNumber;
2199     } else {
2200         error += "Unknown or wrong type of 'columnNumber';";
2201     }
2202     if (!error.empty()) {
2203         LOG_DEBUGGER(ERROR) << "RuntimeCallFrame::Create " << error;
2204         return nullptr;
2205     }
2206 
2207     return runtimeCallFrame;
2208 }
2209 
FromFrameInfo(const FrameInfo &cpuFrameInfo)2210 std::unique_ptr<RuntimeCallFrame> RuntimeCallFrame::FromFrameInfo(const FrameInfo &cpuFrameInfo)
2211 {
2212     auto runtimeCallFrame = std::make_unique<RuntimeCallFrame>();
2213     runtimeCallFrame->SetFunctionName(cpuFrameInfo.functionName);
2214     runtimeCallFrame->SetModuleName(cpuFrameInfo.moduleName);
2215     runtimeCallFrame->SetScriptId(std::to_string(cpuFrameInfo.scriptId));
2216     runtimeCallFrame->SetColumnNumber(cpuFrameInfo.columnNumber);
2217     runtimeCallFrame->SetLineNumber(cpuFrameInfo.lineNumber);
2218     runtimeCallFrame->SetUrl(cpuFrameInfo.url);
2219     return runtimeCallFrame;
2220 }
2221 
ToJson() const2222 std::unique_ptr<PtJson> RuntimeCallFrame::ToJson() const
2223 {
2224     std::unique_ptr<PtJson> result = PtJson::CreateObject();
2225 
2226     result->Add("functionName", functionName_.c_str());
2227     result->Add("moduleName", moduleName_.c_str());
2228     result->Add("scriptId", scriptId_.c_str());
2229     result->Add("url", url_.c_str());
2230     result->Add("lineNumber", lineNumber_);
2231     result->Add("columnNumber", columnNumber_);
2232 
2233     return result;
2234 }
2235 
Create(const PtJson &params)2236 std::unique_ptr<SamplingHeapProfileNode> SamplingHeapProfileNode::Create(const PtJson &params)
2237 {
2238     std::string error;
2239     auto samplingHeapProfileNode = std::make_unique<SamplingHeapProfileNode>();
2240     Result ret;
2241 
2242     std::unique_ptr<PtJson> callFrame;
2243     ret = params.GetObject("callFrame", &callFrame);
2244     if (ret == Result::SUCCESS) {
2245         std::unique_ptr<RuntimeCallFrame> runtimeCallFrame = RuntimeCallFrame::Create(*callFrame);
2246         if (runtimeCallFrame == nullptr) {
2247             error += "'callFrame' format invalid;";
2248         } else {
2249             samplingHeapProfileNode->callFrame_ = std::move(runtimeCallFrame);
2250         }
2251     } else {
2252         error += "Unknown or wrong type of 'callFrame';";
2253     }
2254 
2255     int32_t selfSize;
2256     ret = params.GetInt("selfSize", &selfSize);
2257     if (ret == Result::SUCCESS) {
2258         samplingHeapProfileNode->selfSize_ = selfSize;
2259     } else {
2260         error += "Unknown or wrong type of 'selfSize';";
2261     }
2262 
2263     int32_t id;
2264     ret = params.GetInt("id", &id);
2265     if (ret == Result::SUCCESS) {
2266         samplingHeapProfileNode->id_ = id;
2267     } else {
2268         error += "Unknown or wrong type of 'id';";
2269     }
2270 
2271     std::unique_ptr<PtJson> children;
2272     ret = params.GetArray("children", &children);
2273     if (ret == Result::SUCCESS) {
2274         int32_t len = children->GetSize();
2275         for (int32_t i = 0; i < len; ++i) {
2276             std::unique_ptr<PtJson> arrayEle = children->Get(i);
2277             ASSERT(arrayEle != nullptr);
2278             std::unique_ptr<SamplingHeapProfileNode> node = SamplingHeapProfileNode::Create(*arrayEle);
2279             if (node == nullptr) {
2280                 error += "'children' format invalid;";
2281             } else {
2282                 samplingHeapProfileNode->children_.emplace_back(std::move(node));
2283             }
2284         }
2285     } else {
2286         error += "Unknown or wrong type of 'children';";
2287     }
2288 
2289     if (!error.empty()) {
2290         LOG_DEBUGGER(ERROR) << "SamplingHeapProfileNode::Create " << error;
2291         return nullptr;
2292     }
2293 
2294     return samplingHeapProfileNode;
2295 }
2296 
ToJson() const2297 std::unique_ptr<PtJson> SamplingHeapProfileNode::ToJson() const
2298 {
2299     std::unique_ptr<PtJson> result = PtJson::CreateObject();
2300     ASSERT(callFrame_ != nullptr);
2301     result->Add("callFrame", callFrame_->ToJson());
2302     result->Add("selfSize", selfSize_);
2303     result->Add("id", id_);
2304 
2305     std::unique_ptr<PtJson> childrens = PtJson::CreateArray();
2306     size_t len = children_.size();
2307     for (size_t i = 0; i < len; i++) {
2308         ASSERT(children_[i] != nullptr);
2309         childrens->Push(children_[i]->ToJson());
2310     }
2311     result->Add("children", childrens);
2312 
2313     return result;
2314 }
2315 
Create(const PtJson &params)2316 std::unique_ptr<SamplingHeapProfile> SamplingHeapProfile::Create(const PtJson &params)
2317 {
2318     std::string error;
2319     auto samplingHeapProfile = std::make_unique<SamplingHeapProfile>();
2320     Result ret;
2321 
2322     std::unique_ptr<PtJson> head;
2323     ret = params.GetObject("head", &head);
2324     if (ret == Result::SUCCESS) {
2325         std::unique_ptr<SamplingHeapProfileNode> pHead = SamplingHeapProfileNode::Create(*head);
2326         if (pHead == nullptr) {
2327             error += "'sample' format invalid;";
2328         } else {
2329             samplingHeapProfile->head_ = std::move(pHead);
2330         }
2331     } else {
2332         error += "Unknown or wrong type of 'head';";
2333     }
2334 
2335     std::unique_ptr<PtJson> samples;
2336     ret = params.GetArray("samples", &samples);
2337     if (ret == Result::SUCCESS) {
2338         int32_t len = samples->GetSize();
2339         for (int32_t i = 0; i < len; ++i) {
2340             std::unique_ptr<PtJson> arrayEle = samples->Get(i);
2341             ASSERT(arrayEle != nullptr);
2342             std::unique_ptr<SamplingHeapProfileSample> pSample = SamplingHeapProfileSample::Create(*arrayEle);
2343             if (pSample == nullptr) {
2344                 error += "'sample' format invalid;";
2345             } else {
2346                 samplingHeapProfile->samples_.emplace_back(std::move(pSample));
2347             }
2348         }
2349     } else {
2350         error += "Unknown or wrong type of 'samples';";
2351     }
2352 
2353     if (!error.empty()) {
2354         LOG_DEBUGGER(ERROR) << "SamplingHeapProfile::Create " << error;
2355         return nullptr;
2356     }
2357 
2358     return samplingHeapProfile;
2359 }
2360 
ToJson() const2361 std::unique_ptr<PtJson> SamplingHeapProfile::ToJson() const
2362 {
2363     std::unique_ptr<PtJson> result = PtJson::CreateObject();
2364 
2365     ASSERT(head_ != nullptr);
2366     result->Add("head", head_->ToJson());
2367 
2368     std::unique_ptr<PtJson> samples = PtJson::CreateArray();
2369     size_t len = samples_.size();
2370     for (size_t i = 0; i < len; i++) {
2371         ASSERT(samples_[i] != nullptr);
2372         samples->Push(samples_[i]->ToJson());
2373     }
2374     result->Add("samples", samples);
2375     return result;
2376 }
2377 
FromSamplingInfo( const SamplingInfo *samplingInfo)2378 std::unique_ptr<SamplingHeapProfile> SamplingHeapProfile::FromSamplingInfo(
2379     const SamplingInfo *samplingInfo)
2380 {
2381     std::unique_ptr<SamplingHeapProfile> profile = std::make_unique<SamplingHeapProfile>();
2382     auto node = TransferHead(&(samplingInfo->head_));
2383     profile->head_ = std::move(node);
2384     const CVector<struct Sample> &samples = samplingInfo->samples_;
2385     for (const auto &sample : samples) {
2386         std::unique_ptr<SamplingHeapProfileSample> sampleTemp = std::make_unique<SamplingHeapProfileSample>();
2387         sampleTemp->SetSize(sample.size_ * sample.count_);
2388         sampleTemp->SetNodeId(sample.nodeId_);
2389         sampleTemp->SetOrdinal(sample.ordinal_);
2390         profile->samples_.emplace_back(std::move(sampleTemp));
2391     }
2392     return profile;
2393 }
2394 
TransferHead(const SamplingNode *samplingNode)2395 std::unique_ptr<SamplingHeapProfileNode> SamplingHeapProfile::TransferHead(const SamplingNode *samplingNode)
2396 {
2397     std::unique_ptr<SamplingHeapProfileNode> node = std::make_unique<SamplingHeapProfileNode>();
2398     node->SetSelfSize(samplingNode->selfSize_);
2399     node->SetId(samplingNode->id_);
2400     std::unique_ptr<RuntimeCallFrame> callFrame = std::make_unique<RuntimeCallFrame>();
2401     callFrame->SetFunctionName(samplingNode->callFrameInfo_.functionName_);
2402     callFrame->SetScriptId(std::to_string(samplingNode->callFrameInfo_.scriptId_));
2403     callFrame->SetUrl(samplingNode->callFrameInfo_.url_);
2404     callFrame->SetLineNumber(samplingNode->callFrameInfo_.lineNumber_);
2405     callFrame->SetColumnNumber(samplingNode->callFrameInfo_.columnNumber_);
2406     node->SetCallFrame(std::move(callFrame));
2407     std::vector<std::unique_ptr<SamplingHeapProfileNode>> profileNode;
2408     for (const auto &it : samplingNode->children_) {
2409         auto proNode = TransferHead(it.second.get());
2410         profileNode.push_back(std::move(proNode));
2411     }
2412     node->SetChildren(std::move(profileNode));
2413     return node;
2414 }
2415 
Create(const PtJson &params)2416 std::unique_ptr<PositionTickInfo> PositionTickInfo::Create(const PtJson &params)
2417 {
2418     std::string error;
2419     auto positionTickInfo = std::make_unique<PositionTickInfo>();
2420     Result ret;
2421 
2422     int32_t line;
2423     ret = params.GetInt("line", &line);
2424     if (ret == Result::SUCCESS) {
2425         positionTickInfo->line_ = line;
2426     } else {
2427         error += "Unknown or wrong type of 'line';";
2428     }
2429 
2430     int32_t ticks;
2431     ret = params.GetInt("ticks", &ticks);
2432     if (ret == Result::SUCCESS) {
2433         positionTickInfo->ticks_ = ticks;
2434     } else {
2435         error += "Unknown or wrong type of 'ticks';";
2436     }
2437 
2438     if (!error.empty()) {
2439         LOG_DEBUGGER(ERROR) << "PositionTickInfo::Create " << error;
2440         return nullptr;
2441     }
2442 
2443     return positionTickInfo;
2444 }
2445 
ToJson() const2446 std::unique_ptr<PtJson> PositionTickInfo::ToJson() const
2447 {
2448     std::unique_ptr<PtJson> result = PtJson::CreateObject();
2449 
2450     result->Add("line", line_);
2451     result->Add("ticks", ticks_);
2452 
2453     return result;
2454 }
2455 
Create(const PtJson &params)2456 std::unique_ptr<ProfileNode> ProfileNode::Create(const PtJson &params)
2457 {
2458     std::string error;
2459     auto profileNode = std::make_unique<ProfileNode>();
2460     Result ret;
2461 
2462     int32_t id;
2463     ret = params.GetInt("id", &id);
2464     if (ret == Result::SUCCESS) {
2465         profileNode->id_ = id;
2466     } else {
2467         error += "Unknown or wrong type of 'id';";
2468     }
2469 
2470     std::unique_ptr<PtJson> callFrame;
2471     ret = params.GetObject("callFrame", &callFrame);
2472     if (ret == Result::SUCCESS) {
2473         std::unique_ptr<RuntimeCallFrame> runtimeCallFrame = RuntimeCallFrame::Create(*callFrame);
2474         if (runtimeCallFrame == nullptr) {
2475             error += "'callFrame' format invalid;";
2476         } else {
2477             profileNode->callFrame_ = std::move(runtimeCallFrame);
2478         }
2479     } else {
2480         error += "Unknown or wrong type of 'callFrame';";
2481     }
2482 
2483     int32_t hitCount;
2484     ret = params.GetInt("hitCount", &hitCount);
2485     if (ret == Result::SUCCESS) {
2486         profileNode->hitCount_ = hitCount;
2487     } else if (ret == Result::TYPE_ERROR) {
2488         error += "Wrong type of 'hitCount';";
2489     }
2490 
2491     std::unique_ptr<PtJson> children;
2492     ret = params.GetArray("children", &children);
2493     if (ret == Result::SUCCESS) {
2494         int32_t childrenLen = children->GetSize();
2495         for (int32_t i = 0; i < childrenLen; ++i) {
2496             int32_t pChildren = children->Get(i)->GetInt();
2497             profileNode->children_.value().emplace_back(pChildren);
2498         }
2499     } else if (ret == Result::TYPE_ERROR) {
2500         error += "Wrong type of 'children';";
2501     }
2502 
2503     std::unique_ptr<PtJson> positionTicks;
2504     ret = params.GetArray("positionTicks", &positionTicks);
2505     if (ret == Result::SUCCESS) {
2506         int32_t positionTicksLen = positionTicks->GetSize();
2507         for (int32_t i = 0; i < positionTicksLen; ++i) {
2508             std::unique_ptr<PtJson> arrayEle = positionTicks->Get(i);
2509             ASSERT(arrayEle != nullptr);
2510             std::unique_ptr<PositionTickInfo> tmpPositionTicks = PositionTickInfo::Create(*arrayEle);
2511             if (tmpPositionTicks == nullptr) {
2512                 error += "'positionTicks' format invalid;";
2513             } else {
2514                 profileNode->positionTicks_.value().emplace_back(std::move(tmpPositionTicks));
2515             }
2516         }
2517     } else if (ret == Result::TYPE_ERROR) {
2518         error += "Wrong type of 'positionTicks';";
2519     }
2520 
2521     std::string deoptReason;
2522     ret = params.GetString("deoptReason", &deoptReason);
2523     if (ret == Result::SUCCESS) {
2524         profileNode->deoptReason_ = std::move(deoptReason);
2525     } else if (ret == Result::TYPE_ERROR) {
2526         error += "Wrong type of 'deoptReason';";
2527     }
2528 
2529     if (!error.empty()) {
2530         LOG_DEBUGGER(ERROR) << "ProfileNode::Create " << error;
2531         return nullptr;
2532     }
2533 
2534     return profileNode;
2535 }
2536 
FromCpuProfileNode(const CpuProfileNode &cpuProfileNode)2537 std::unique_ptr<ProfileNode> ProfileNode::FromCpuProfileNode(const CpuProfileNode &cpuProfileNode)
2538 {
2539     auto profileNode = std::make_unique<ProfileNode>();
2540     profileNode->SetId(cpuProfileNode.id);
2541     profileNode->SetHitCount(cpuProfileNode.hitCount);
2542 
2543     size_t childrenLen = cpuProfileNode.children.size();
2544     std::vector<int32_t> tmpChildren;
2545     tmpChildren.reserve(childrenLen);
2546     for (size_t i = 0; i < childrenLen; ++i) {
2547         tmpChildren.push_back(cpuProfileNode.children[i]);
2548     }
2549     profileNode->SetChildren(tmpChildren);
2550     profileNode->SetCallFrame(RuntimeCallFrame::FromFrameInfo(cpuProfileNode.codeEntry));
2551     return profileNode;
2552 }
2553 
ToJson() const2554 std::unique_ptr<PtJson> ProfileNode::ToJson() const
2555 {
2556     std::unique_ptr<PtJson> result = PtJson::CreateObject();
2557 
2558     result->Add("id", id_);
2559     ASSERT(callFrame_ != nullptr);
2560     result->Add("callFrame", callFrame_->ToJson());
2561     if (hitCount_) {
2562         result->Add("hitCount", hitCount_.value());
2563     }
2564     if (children_) {
2565         std::unique_ptr<PtJson> childrens = PtJson::CreateArray();
2566         size_t len = children_->size();
2567         for (size_t i = 0; i < len; i++) {
2568             childrens->Push(children_.value()[i]);
2569         }
2570         result->Add("children", childrens);
2571     }
2572     if (positionTicks_) {
2573         std::unique_ptr<PtJson> positionTicks = PtJson::CreateArray();
2574         size_t len = positionTicks_->size();
2575         for (size_t i = 0; i < len; i++) {
2576             ASSERT(positionTicks_.value()[i] != nullptr);
2577             positionTicks->Push(positionTicks_.value()[i]->ToJson());
2578         }
2579         result->Add("positionTicks", positionTicks);
2580     }
2581 
2582     if (deoptReason_) {
2583         result->Add("deoptReason", deoptReason_.value().c_str());
2584     }
2585 
2586     return result;
2587 }
2588 
Create(const PtJson &params)2589 std::unique_ptr<Profile> Profile::Create(const PtJson &params)
2590 {
2591     std::string error;
2592     auto profile = std::make_unique<Profile>();
2593     Result ret;
2594 
2595     std::unique_ptr<PtJson> nodes;
2596     ret = params.GetArray("nodes", &nodes);
2597     if (ret == Result::SUCCESS) {
2598         int32_t nodesLen = nodes->GetSize();
2599         for (int32_t i = 0; i < nodesLen; ++i) {
2600             std::unique_ptr<PtJson> arrayEle = nodes->Get(i);
2601             ASSERT(arrayEle != nullptr);
2602             std::unique_ptr<ProfileNode> profileNode = ProfileNode::Create(*arrayEle);
2603             if (profileNode == nullptr) {
2604                 error += "'nodes' format invalid;";
2605             } else {
2606                 profile->nodes_.emplace_back(std::move(profileNode));
2607             }
2608         }
2609     } else {
2610         error += "Unknown or wrong type of 'nodes';";
2611     }
2612 
2613     int64_t tid;
2614     ret = params.GetInt64("tid", &tid);
2615     if (ret == Result::SUCCESS) {
2616         profile->tid_ = tid;
2617     } else {
2618         error += "Unknown or wrong type of 'tid';";
2619     }
2620 
2621     int64_t startTime;
2622     ret = params.GetInt64("startTime", &startTime);
2623     if (ret == Result::SUCCESS) {
2624         profile->startTime_ = startTime;
2625     } else {
2626         error += "Unknown or wrong type of 'startTime';";
2627     }
2628 
2629     int64_t endTime;
2630     ret = params.GetInt64("endTime", &endTime);
2631     if (ret == Result::SUCCESS) {
2632         profile->endTime_ = endTime;
2633     } else {
2634         error += "Unknown or wrong type of 'endTime';";
2635     }
2636 
2637     int64_t gcTime;
2638     ret = params.GetInt64("gcTime", &gcTime);
2639     if (ret == Result::SUCCESS) {
2640         profile->gcTime_ = gcTime;
2641     } else {
2642         error += "Unknown or wrong type of 'gcTime';";
2643     }
2644 
2645     int64_t cInterpreterTime;
2646     ret = params.GetInt64("cInterpreterTime", &cInterpreterTime);
2647     if (ret == Result::SUCCESS) {
2648         profile->cInterpreterTime_ = cInterpreterTime;
2649     } else {
2650         error += "Unknown or wrong type of 'cInterpreterTime';";
2651     }
2652 
2653     int64_t asmInterpreterTime;
2654     ret = params.GetInt64("asmInterpreterTime", &asmInterpreterTime);
2655     if (ret == Result::SUCCESS) {
2656         profile->asmInterpreterTime_ = asmInterpreterTime;
2657     } else {
2658         error += "Unknown or wrong type of 'asmInterpreterTime';";
2659     }
2660 
2661     int64_t aotTime;
2662     ret = params.GetInt64("aotTime", &aotTime);
2663     if (ret == Result::SUCCESS) {
2664         profile->aotTime_ = aotTime;
2665     } else {
2666         error += "Unknown or wrong type of 'aotTime';";
2667     }
2668 
2669     int64_t builtinTime;
2670     ret = params.GetInt64("builtinTime", &builtinTime);
2671     if (ret == Result::SUCCESS) {
2672         profile->builtinTime_ = builtinTime;
2673     } else {
2674         error += "Unknown or wrong type of 'builtinTime';";
2675     }
2676 
2677     int64_t napiTime;
2678     ret = params.GetInt64("napiTime", &napiTime);
2679     if (ret == Result::SUCCESS) {
2680         profile->napiTime_ = napiTime;
2681     } else {
2682         error += "Unknown or wrong type of 'napiTime';";
2683     }
2684 
2685     int64_t arkuiEngineTime;
2686     ret = params.GetInt64("arkuiEngineTime", &arkuiEngineTime);
2687     if (ret == Result::SUCCESS) {
2688         profile->arkuiEngineTime_ = arkuiEngineTime;
2689     } else {
2690         error += "Unknown or wrong type of 'arkuiEngineTime';";
2691     }
2692 
2693     int64_t runtimeTime;
2694     ret = params.GetInt64("runtimeTime", &runtimeTime);
2695     if (ret == Result::SUCCESS) {
2696         profile->runtimeTime_ = runtimeTime;
2697     } else {
2698         error += "Unknown or wrong type of 'runtimeTime';";
2699     }
2700 
2701     int64_t otherTime;
2702     ret = params.GetInt64("otherTime", &otherTime);
2703     if (ret == Result::SUCCESS) {
2704         profile->otherTime_ = otherTime;
2705     } else {
2706         error += "Unknown or wrong type of 'otherTime';";
2707     }
2708 
2709     std::unique_ptr<PtJson> samples;
2710     ret = params.GetArray("samples", &samples);
2711     if (ret == Result::SUCCESS) {
2712         int32_t samplesLen = samples->GetSize();
2713         for (int32_t i = 0; i < samplesLen; ++i) {
2714             int32_t pSamples = samples->Get(i)->GetInt();
2715             profile->samples_.value().emplace_back(pSamples);
2716         }
2717     } else if (ret == Result::TYPE_ERROR) {
2718         error += "Wrong type of 'samples';";
2719     }
2720 
2721     std::unique_ptr<PtJson> timeDeltas;
2722     ret = params.GetArray("timeDeltas", &timeDeltas);
2723     if (ret == Result::SUCCESS) {
2724         int32_t timeDeltasLen = timeDeltas->GetSize();
2725         for (int32_t i = 0; i < timeDeltasLen; ++i) {
2726             int32_t pTimeDeltas = timeDeltas->Get(i)->GetInt();
2727             profile->timeDeltas_.value().emplace_back(pTimeDeltas);
2728         }
2729     } else if (ret == Result::TYPE_ERROR) {
2730         error += "Wrong type of 'timeDeltas';";
2731     }
2732 
2733     if (!error.empty()) {
2734         LOG_DEBUGGER(ERROR) << "Profile::Create " << error;
2735         return nullptr;
2736     }
2737 
2738     return profile;
2739 }
2740 
FromProfileInfo(const ProfileInfo &profileInfo)2741 std::unique_ptr<Profile> Profile::FromProfileInfo(const ProfileInfo &profileInfo)
2742 {
2743     auto profile = std::make_unique<Profile>();
2744     profile->SetTid(static_cast<int64_t>(profileInfo.tid));
2745     profile->SetStartTime(static_cast<int64_t>(profileInfo.startTime));
2746     profile->SetEndTime(static_cast<int64_t>(profileInfo.stopTime));
2747     profile->SetGcTime(static_cast<int64_t>(profileInfo.gcTime));
2748     profile->SetCInterpreterTime(static_cast<int64_t>(profileInfo.cInterpreterTime));
2749     profile->SetAsmInterpreterTime(static_cast<int64_t>(profileInfo.asmInterpreterTime));
2750     profile->SetAotTime(static_cast<int64_t>(profileInfo.aotTime));
2751     profile->SetBuiltinTime(static_cast<int64_t>(profileInfo.builtinTime));
2752     profile->SetNapiTime(static_cast<int64_t>(profileInfo.napiTime));
2753     profile->SetArkuiEngineTime(static_cast<int64_t>(profileInfo.arkuiEngineTime));
2754     profile->SetRuntimeTime(static_cast<int64_t>(profileInfo.runtimeTime));
2755     profile->SetOtherTime(static_cast<int64_t>(profileInfo.otherTime));
2756     size_t samplesLen = profileInfo.samples.size();
2757     std::vector<int32_t> tmpSamples;
2758     tmpSamples.reserve(samplesLen);
2759     for (size_t i = 0; i < samplesLen; ++i) {
2760         tmpSamples.push_back(profileInfo.samples[i]);
2761     }
2762     profile->SetSamples(tmpSamples);
2763 
2764     size_t timeDeltasLen = profileInfo.timeDeltas.size();
2765     std::vector<int32_t> tmpTimeDeltas;
2766     tmpTimeDeltas.reserve(timeDeltasLen);
2767     for (size_t i = 0; i < timeDeltasLen; ++i) {
2768         tmpTimeDeltas.push_back(profileInfo.timeDeltas[i]);
2769     }
2770     profile->SetTimeDeltas(tmpTimeDeltas);
2771 
2772     std::vector<std::unique_ptr<ProfileNode>> profileNode;
2773     size_t nodesLen = profileInfo.nodeCount;
2774     for (size_t i = 0; i < nodesLen; ++i) {
2775         const auto &cpuProfileNode = profileInfo.nodes[i];
2776         profileNode.push_back(ProfileNode::FromCpuProfileNode(cpuProfileNode));
2777     }
2778     profile->SetNodes(std::move(profileNode));
2779     return profile;
2780 }
2781 
ToJson() const2782 std::unique_ptr<PtJson> Profile::ToJson() const
2783 {
2784     std::unique_ptr<PtJson> result = PtJson::CreateObject();
2785 
2786     result->Add("tid", tid_);
2787     result->Add("startTime", startTime_);
2788     result->Add("endTime", endTime_);
2789     result->Add("gcTime", gcTime_);
2790     result->Add("cInterpreterTime", cInterpreterTime_);
2791     result->Add("asmInterpreterTime", asmInterpreterTime_);
2792     result->Add("aotTime", aotTime_);
2793     result->Add("builtinTime", builtinTime_);
2794     result->Add("napiTime", napiTime_);
2795     result->Add("arkuiEngineTime", arkuiEngineTime_);
2796     result->Add("runtimeTime", runtimeTime_);
2797     result->Add("otherTime", otherTime_);
2798 
2799     std::unique_ptr<PtJson> nodes = PtJson::CreateArray();
2800     size_t nodesLen = nodes_.size();
2801     for (size_t i = 0; i < nodesLen; i++) {
2802         ASSERT(nodes_[i] != nullptr);
2803         nodes->Push(nodes_[i]->ToJson());
2804     }
2805     result->Add("nodes", nodes);
2806 
2807     if (samples_) {
2808         std::unique_ptr<PtJson> samples = PtJson::CreateArray();
2809         size_t samplesLen = samples_->size();
2810         for (size_t i = 0; i < samplesLen; i++) {
2811             samples->Push(samples_.value()[i]);
2812         }
2813         result->Add("samples", samples);
2814     }
2815 
2816     if (timeDeltas_) {
2817         std::unique_ptr<PtJson> timeDeltas = PtJson::CreateArray();
2818         size_t timeDeltasLen = timeDeltas_->size();
2819         for (size_t i = 0; i < timeDeltasLen; i++) {
2820             timeDeltas->Push(timeDeltas_.value()[i]);
2821         }
2822         result->Add("timeDeltas", timeDeltas);
2823     }
2824 
2825     return result;
2826 }
2827 
Create(const PtJson &params)2828 std::unique_ptr<Coverage> Coverage::Create(const PtJson &params)
2829 {
2830     std::string error;
2831     auto coverage = std::make_unique<Coverage>();
2832     Result ret;
2833 
2834     int32_t startOffset;
2835     ret = params.GetInt("startOffset", &startOffset);
2836     if (ret == Result::SUCCESS) {
2837         coverage->startOffset_ = startOffset;
2838     } else {
2839         error += "Unknown or wrong type of 'startOffset';";
2840     }
2841 
2842     int32_t endOffset;
2843     ret = params.GetInt("endOffset", &endOffset);
2844     if (ret == Result::SUCCESS) {
2845         coverage->endOffset_ = endOffset;
2846     } else {
2847         error += "Unknown or wrong type of 'endOffset';";
2848     }
2849 
2850     int32_t count;
2851     ret = params.GetInt("count", &count);
2852     if (ret == Result::SUCCESS) {
2853         coverage->count_ = count;
2854     } else {
2855         error += "Unknown or wrong type of 'count';";
2856     }
2857 
2858     if (!error.empty()) {
2859         LOG_DEBUGGER(ERROR) << "Coverage::Create " << error;
2860         return nullptr;
2861     }
2862 
2863     return coverage;
2864 }
2865 
ToJson() const2866 std::unique_ptr<PtJson> Coverage::ToJson() const
2867 {
2868     std::unique_ptr<PtJson> result = PtJson::CreateObject();
2869 
2870     result->Add("startOffset", startOffset_);
2871     result->Add("endOffset", endOffset_);
2872     result->Add("count", count_);
2873 
2874     return result;
2875 }
2876 
Create(const PtJson &params)2877 std::unique_ptr<FunctionCoverage> FunctionCoverage::Create(const PtJson &params)
2878 {
2879     std::string error;
2880     auto functionCoverage = std::make_unique<FunctionCoverage>();
2881     Result ret;
2882 
2883     std::string functionName;
2884     ret = params.GetString("functionName", &functionName);
2885     if (ret == Result::SUCCESS) {
2886         functionCoverage->functionName_ = std::move(functionName);
2887     } else {
2888         error += "Unknown or wrong type of 'functionName';";
2889     }
2890 
2891     std::unique_ptr<PtJson> ranges;
2892     ret = params.GetArray("ranges", &ranges);
2893     if (ret == Result::SUCCESS) {
2894         int32_t len = ranges->GetSize();
2895         for (int32_t i = 0; i < len; ++i) {
2896             std::unique_ptr<PtJson> arrayEle = ranges->Get(i);
2897             ASSERT(arrayEle != nullptr);
2898             std::unique_ptr<Coverage> pRanges = Coverage::Create(*arrayEle);
2899             if (pRanges == nullptr) {
2900                 error += "'ranges' format invalid;";
2901             } else {
2902                 functionCoverage->ranges_.emplace_back(std::move(pRanges));
2903             }
2904         }
2905     } else {
2906         error += "Unknown or wrong type of 'ranges';";
2907     }
2908 
2909     bool isBlockCoverage = false;
2910     ret = params.GetBool("isBlockCoverage", &isBlockCoverage);
2911     if (ret == Result::SUCCESS) {
2912         functionCoverage->isBlockCoverage_ = isBlockCoverage;
2913     } else {
2914         error += "Unknown or wrong type of 'isBlockCoverage';";
2915     }
2916 
2917     if (!error.empty()) {
2918         LOG_DEBUGGER(ERROR) << "FunctionCoverage::Create " << error;
2919         return nullptr;
2920     }
2921 
2922     return functionCoverage;
2923 }
2924 
ToJson() const2925 std::unique_ptr<PtJson> FunctionCoverage::ToJson() const
2926 {
2927     std::unique_ptr<PtJson> result = PtJson::CreateObject();
2928 
2929     result->Add("functionName", functionName_.c_str());
2930 
2931     std::unique_ptr<PtJson> ranges = PtJson::CreateArray();
2932     size_t len = ranges_.size();
2933     for (size_t i = 0; i < len; i++) {
2934         ASSERT(ranges_[i] != nullptr);
2935         ranges->Push(ranges_[i]->ToJson());
2936     }
2937     result->Add("ranges", ranges);
2938 
2939     result->Add("isBlockCoverage", isBlockCoverage_);
2940 
2941     return result;
2942 }
2943 
Create(const PtJson &params)2944 std::unique_ptr<ScriptCoverage> ScriptCoverage::Create(const PtJson &params)
2945 {
2946     std::string error;
2947     auto scriptCoverage = std::make_unique<ScriptCoverage>();
2948     Result ret;
2949 
2950     std::string scriptId;
2951     ret = params.GetString("scriptId", &scriptId);
2952     if (ret == Result::SUCCESS) {
2953         scriptCoverage->scriptId_ = std::move(scriptId);
2954     } else {
2955         error += "Unknown or wrong type of 'scriptId';";
2956     }
2957 
2958     std::string url;
2959     ret = params.GetString("url", &url);
2960     if (ret == Result::SUCCESS) {
2961         scriptCoverage->url_ = std::move(url);
2962     } else {
2963         error += "Unknown or wrong type of 'url';";
2964     }
2965 
2966     std::unique_ptr<PtJson> functions;
2967     ret = params.GetArray("functions", &functions);
2968     if (ret == Result::SUCCESS) {
2969         int32_t len = functions->GetSize();
2970         for (int32_t i = 0; i < len; ++i) {
2971             std::unique_ptr<PtJson> arrayEle = functions->Get(i);
2972             ASSERT(arrayEle != nullptr);
2973             std::unique_ptr<FunctionCoverage> pFunctions = FunctionCoverage::Create(*arrayEle);
2974             if (pFunctions == nullptr) {
2975                 error += "'functions' format invalid;";
2976             } else {
2977                 scriptCoverage->functions_.emplace_back(std::move(pFunctions));
2978             }
2979         }
2980     } else {
2981         error += "Unknown or wrong type of 'functions';";
2982     }
2983 
2984     if (!error.empty()) {
2985         LOG_DEBUGGER(ERROR) << "ScriptCoverage::Create " << error;
2986         return nullptr;
2987     }
2988 
2989     return scriptCoverage;
2990 }
2991 
ToJson() const2992 std::unique_ptr<PtJson> ScriptCoverage::ToJson() const
2993 {
2994     std::unique_ptr<PtJson> result = PtJson::CreateObject();
2995 
2996     result->Add("scriptId", scriptId_.c_str());
2997     result->Add("url", url_.c_str());
2998 
2999     std::unique_ptr<PtJson> functions = PtJson::CreateArray();
3000     size_t len = functions_.size();
3001     for (size_t i = 0; i < len; i++) {
3002         ASSERT(functions_[i] != nullptr);
3003         functions->Push(functions_[i]->ToJson());
3004     }
3005     result->Add("functions", functions);
3006 
3007     return result;
3008 }
3009 
Create(const PtJson &params)3010 std::unique_ptr<TypeObject> TypeObject::Create(const PtJson &params)
3011 {
3012     std::string error;
3013     auto typeObject = std::make_unique<TypeObject>();
3014     Result ret;
3015 
3016     std::string name;
3017     ret = params.GetString("name", &name);
3018     if (ret == Result::SUCCESS) {
3019         typeObject->name_ = std::move(name);
3020     } else {
3021         error += "Unknown or wrong type of 'name';";
3022     }
3023 
3024     if (!error.empty()) {
3025         LOG_DEBUGGER(ERROR) << "TypeObject::Create " << error;
3026         return nullptr;
3027     }
3028 
3029     return typeObject;
3030 }
3031 
ToJson() const3032 std::unique_ptr<PtJson> TypeObject::ToJson() const
3033 {
3034     std::unique_ptr<PtJson> result = PtJson::CreateObject();
3035 
3036     result->Add("name", name_.c_str());
3037 
3038     return result;
3039 }
3040 
Create(const PtJson &params)3041 std::unique_ptr<TypeProfileEntry> TypeProfileEntry::Create(const PtJson &params)
3042 {
3043     std::string error;
3044     auto typeProfileEntry = std::make_unique<TypeProfileEntry>();
3045     Result ret;
3046 
3047     int32_t offset;
3048     ret = params.GetInt("offset", &offset);
3049     if (ret == Result::SUCCESS) {
3050         typeProfileEntry->offset_ = offset;
3051     } else {
3052         error += "Unknown or wrong type of 'offset';";
3053     }
3054 
3055     std::unique_ptr<PtJson> types;
3056     ret = params.GetArray("types", &types);
3057     if (ret == Result::SUCCESS) {
3058         int32_t len = types->GetSize();
3059         for (int32_t i = 0; i < len; ++i) {
3060             std::unique_ptr<PtJson> arrayEle = types->Get(i);
3061             ASSERT(arrayEle != nullptr);
3062             std::unique_ptr<TypeObject> pTypes = TypeObject::Create(*arrayEle);
3063             if (pTypes == nullptr) {
3064                 error += "'types' format invalid;";
3065             } else {
3066                 typeProfileEntry->types_.emplace_back(std::move(pTypes));
3067             }
3068         }
3069     } else {
3070         error += "Unknown or wrong type of 'types';";
3071     }
3072 
3073     if (!error.empty()) {
3074         LOG_DEBUGGER(ERROR) << "TypeProfileEntry::Create " << error;
3075         return nullptr;
3076     }
3077 
3078     return typeProfileEntry;
3079 }
3080 
ToJson() const3081 std::unique_ptr<PtJson> TypeProfileEntry::ToJson() const
3082 {
3083     std::unique_ptr<PtJson> result = PtJson::CreateObject();
3084 
3085     result->Add("offset", offset_);
3086 
3087     std::unique_ptr<PtJson> types = PtJson::CreateArray();
3088     size_t len = types_.size();
3089     for (size_t i = 0; i < len; i++) {
3090         ASSERT(types_[i] != nullptr);
3091         types->Push(types_[i]->ToJson());
3092     }
3093     result->Add("types", types);
3094 
3095     return result;
3096 }
3097 
Create(const PtJson &params)3098 std::unique_ptr<ScriptTypeProfile> ScriptTypeProfile::Create(const PtJson &params)
3099 {
3100     std::string error;
3101     auto scriptTypeProfile = std::make_unique<ScriptTypeProfile>();
3102     Result ret;
3103 
3104     std::string scriptId;
3105     ret = params.GetString("scriptId", &scriptId);
3106     if (ret == Result::SUCCESS) {
3107         scriptTypeProfile->scriptId_ = std::move(scriptId);
3108     } else {
3109         error += "Unknown or wrong type of 'scriptId';";
3110     }
3111 
3112     std::string url;
3113     ret = params.GetString("url", &url);
3114     if (ret == Result::SUCCESS) {
3115         scriptTypeProfile->url_ = std::move(url);
3116     } else {
3117         error += "Unknown or wrong type of 'url';";
3118     }
3119 
3120     std::unique_ptr<PtJson> entries;
3121     ret = params.GetArray("entries", &entries);
3122     if (ret == Result::SUCCESS) {
3123         int32_t len = entries->GetSize();
3124         for (int32_t i = 0; i < len; ++i) {
3125             std::unique_ptr<PtJson> arrayEle = entries->Get(i);
3126             ASSERT(arrayEle != nullptr);
3127             std::unique_ptr<TypeProfileEntry> pEntries = TypeProfileEntry::Create(*arrayEle);
3128             if (pEntries == nullptr) {
3129                 error += "'entries' format invalid;";
3130             } else {
3131                 scriptTypeProfile->entries_.emplace_back(std::move(pEntries));
3132             }
3133         }
3134     } else {
3135         error += "Unknown or wrong type of 'entries';";
3136     }
3137 
3138     if (!error.empty()) {
3139         LOG_DEBUGGER(ERROR) << "ScriptTypeProfile::Create " << error;
3140         return nullptr;
3141     }
3142 
3143     return scriptTypeProfile;
3144 }
3145 
ToJson() const3146 std::unique_ptr<PtJson> ScriptTypeProfile::ToJson() const
3147 {
3148     std::unique_ptr<PtJson> result = PtJson::CreateObject();
3149 
3150     result->Add("scriptId", scriptId_.c_str());
3151     result->Add("url", url_.c_str());
3152 
3153     std::unique_ptr<PtJson> entries = PtJson::CreateArray();
3154     size_t len = entries_.size();
3155     for (size_t i = 0; i < len; i++) {
3156         ASSERT(entries_[i] != nullptr);
3157         entries->Push(entries_[i]->ToJson());
3158     }
3159     result->Add("entries", entries);
3160 
3161     return result;
3162 }
3163 
Create(const PtJson &params)3164 std::unique_ptr<TraceConfig> TraceConfig::Create(const PtJson &params)
3165 {
3166     std::string error;
3167     auto traceConfig = std::make_unique<TraceConfig>();
3168     Result ret;
3169 
3170     std::string recordMode;
3171     ret = params.GetString("recordMode", &recordMode);
3172     if (ret == Result::SUCCESS) {
3173         if (TraceConfig::RecordModeValues::Valid(recordMode)) {
3174             traceConfig->recordMode_ = std::move(recordMode);
3175         } else {
3176             error += "'recordMode' is invalid;";
3177         }
3178     } else if (ret == Result::TYPE_ERROR) {
3179         error += "Wrong type of 'recordMode';";
3180     }
3181 
3182     bool enableSampling = false;
3183     ret = params.GetBool("enableSampling", &enableSampling);
3184     if (ret == Result::SUCCESS) {
3185         traceConfig->enableSampling_ = enableSampling;
3186     } else if (ret == Result::TYPE_ERROR) {
3187         error += "Wrong type of 'enableSampling';";
3188     }
3189 
3190     bool enableSystrace = false;
3191     ret = params.GetBool("enableSystrace", &enableSystrace);
3192     if (ret == Result::SUCCESS) {
3193         traceConfig->enableSystrace_ = enableSystrace;
3194     } else if (ret == Result::TYPE_ERROR) {
3195         error += "Wrong type of 'enableSystrace';";
3196     }
3197 
3198     bool enableArgumentFilter = false;
3199     ret = params.GetBool("enableArgumentFilter", &enableArgumentFilter);
3200     if (ret == Result::SUCCESS) {
3201         traceConfig->enableArgumentFilter_ = enableArgumentFilter;
3202     } else if (ret == Result::TYPE_ERROR) {
3203         error += "Wrong type of 'enableArgumentFilter';";
3204     }
3205 
3206     std::unique_ptr<PtJson> includedCategories;
3207     ret = params.GetArray("includedCategories", &includedCategories);
3208     if (ret == Result::SUCCESS) {
3209         int32_t includedCategoriesLen = includedCategories->GetSize();
3210         traceConfig->includedCategories_= std::vector<std::string>();
3211         for (int32_t i = 0; i < includedCategoriesLen; ++i) {
3212             std::string pIncludedCategories = includedCategories->Get(i)->GetString();
3213             traceConfig->includedCategories_.value().emplace_back(pIncludedCategories);
3214         }
3215     } else if (ret == Result::TYPE_ERROR) {
3216         error += "Wrong type of 'includedCategories';";
3217     }
3218 
3219     std::unique_ptr<PtJson> excludedCategories;
3220     ret = params.GetArray("excludedCategories", &excludedCategories);
3221     if (ret == Result::SUCCESS) {
3222         int32_t excludedCategoriesLen = excludedCategories->GetSize();
3223         traceConfig->excludedCategories_ = std::vector<std::string>();
3224         for (int32_t i = 0; i < excludedCategoriesLen; ++i) {
3225             std::string pExcludedCategories = excludedCategories->Get(i)->GetString();
3226             traceConfig->excludedCategories_.value().emplace_back(pExcludedCategories);
3227         }
3228     } else if (ret == Result::TYPE_ERROR) {
3229         error += "Wrong type of 'excludedCategories';";
3230     }
3231 
3232     std::unique_ptr<PtJson> syntheticDelays;
3233     ret = params.GetArray("syntheticDelays", &syntheticDelays);
3234     if (ret == Result::SUCCESS) {
3235         int32_t syntheticDelaysLen = syntheticDelays->GetSize();
3236         traceConfig->syntheticDelays_ = std::vector<std::string>();
3237         for (int32_t i = 0; i < syntheticDelaysLen; ++i) {
3238             std::string pSyntheticDelays = syntheticDelays->Get(i)->GetString();
3239             traceConfig->syntheticDelays_.value().emplace_back(pSyntheticDelays);
3240         }
3241     } else if (ret == Result::TYPE_ERROR) {
3242         error += "Wrong type of 'syntheticDelays';";
3243     }
3244 
3245     std::unique_ptr<PtJson> memoryDumpConfig;
3246     ret = params.GetObject("memoryDumpConfig", &memoryDumpConfig);
3247     if (ret == Result::SUCCESS) {
3248         std::unique_ptr<MemoryDumpConfig> tmpMemory = std::move(memoryDumpConfig);
3249         if (tmpMemory == nullptr) {
3250             error += "'memoryDumpConfig' format error;";
3251         } else {
3252             traceConfig->memoryDumpConfig_ = std::move(tmpMemory);
3253         }
3254     } else if (ret == Result::TYPE_ERROR) {
3255         error += "Wrong type of 'memoryDumpConfig';";
3256     }
3257 
3258     if (!error.empty()) {
3259         LOG_DEBUGGER(ERROR) << "TraceConfig::Create " << error;
3260         return nullptr;
3261     }
3262 
3263     return traceConfig;
3264 }
3265 
ToJson() const3266 std::unique_ptr<PtJson> TraceConfig::ToJson() const
3267 {
3268     std::unique_ptr<PtJson> result = PtJson::CreateObject();
3269 
3270     if (recordMode_) {
3271         result->Add("recordMode", recordMode_.value().c_str());
3272     }
3273 
3274     if (enableSampling_) {
3275         result->Add("enableSampling", enableSampling_.value());
3276     }
3277 
3278     if (enableSystrace_) {
3279         result->Add("enableSystrace", enableSystrace_.value());
3280     }
3281 
3282     if (enableArgumentFilter_) {
3283         result->Add("enableArgumentFilter", enableArgumentFilter_.value());
3284     }
3285 
3286     if (includedCategories_) {
3287         std::unique_ptr<PtJson> includedCategories = PtJson::CreateArray();
3288         size_t includedCategoriesLen = includedCategories_->size();
3289         for (size_t i = 0; i < includedCategoriesLen; i++) {
3290             includedCategories->Push(includedCategories_.value()[i].c_str());
3291         }
3292         result->Add("includedCategories", includedCategories);
3293     }
3294 
3295     if (excludedCategories_) {
3296         std::unique_ptr<PtJson> excludedCategories = PtJson::CreateArray();
3297         size_t excludedCategoriesLen = excludedCategories_->size();
3298         for (size_t i = 0; i < excludedCategoriesLen; i++) {
3299             excludedCategories->Push(excludedCategories_.value()[i].c_str());
3300         }
3301         result->Add("excludedCategories", excludedCategories);
3302     }
3303 
3304     if (syntheticDelays_) {
3305         std::unique_ptr<PtJson> syntheticDelays = PtJson::CreateArray();
3306         size_t syntheticDelaysLen = syntheticDelays_->size();
3307         for (size_t i = 0; i < syntheticDelaysLen; i++) {
3308             syntheticDelays->Push(syntheticDelays_.value()[i].c_str());
3309         }
3310         result->Add("syntheticDelays", syntheticDelays);
3311     }
3312 
3313     if (memoryDumpConfig_) {
3314         result->Add("functionLocation", memoryDumpConfig_.value());
3315     }
3316 
3317     return result;
3318 }
3319 
Create(const PtJson &params)3320 std::unique_ptr<BreakpointInfo> BreakpointInfo::Create(const PtJson &params)
3321 {
3322     auto paramsObject = std::make_unique<BreakpointInfo>();
3323     std::string error;
3324     Result ret;
3325     // lineNumber
3326     int32_t lineNumber;
3327     ret = params.GetInt("lineNumber", &lineNumber);
3328     if (ret == Result::SUCCESS) {
3329         paramsObject->lineNumber_ = lineNumber;
3330     } else {
3331         error += "Unknown or wrong type of 'lineNumber';";
3332     }
3333     // columnNumber
3334     int32_t columnNumber;
3335     ret = params.GetInt("columnNumber", &columnNumber);
3336     if (ret == Result::SUCCESS) {
3337         paramsObject->columnNumber_ = columnNumber;
3338     } else {
3339         error += "Unknown or wrong type of 'columnNumber';";
3340     }
3341     // url
3342     std::string url;
3343     ret = params.GetString("url", &url);
3344     if (ret == Result::SUCCESS) {
3345         paramsObject->url_ = std::move(url);
3346     } else {
3347         error += "Unknown or wrong type of 'url';";
3348     }
3349     // condition
3350     std::string condition;
3351     ret = params.GetString("condition", &condition);
3352     if (ret == Result::SUCCESS) {
3353         paramsObject->condition_ = std::move(condition);
3354     } else if (ret == Result::TYPE_ERROR) {
3355         error += "Wrong type of 'condition';";
3356     }
3357     // urlRegex
3358     std::string urlRegex;
3359     ret = params.GetString("urlRegex", &urlRegex);
3360     if (ret == Result::SUCCESS) {
3361         paramsObject->urlRegex_ = std::move(urlRegex);
3362     } else if (ret == Result::TYPE_ERROR) {
3363         error += "Wrong type of 'urlRegex';";
3364     }
3365     // scriptHash
3366     std::string scriptHash;
3367     ret = params.GetString("scriptHash", &scriptHash);
3368     if (ret == Result::SUCCESS) {
3369         paramsObject->scriptHash_ = std::move(scriptHash);
3370     } else if (ret == Result::TYPE_ERROR) {
3371         error += "Wrong type of 'scriptHash';";
3372     }
3373     // restrictToFunction
3374     bool restrictToFunction = false;
3375     ret = params.GetBool("restrictToFunction", &restrictToFunction);
3376     if (ret == Result::SUCCESS) {
3377         paramsObject->restrictToFunction_ = restrictToFunction;
3378     } else if (ret == Result::TYPE_ERROR) {  // optional value
3379         error += "Wrong type of 'restrictToFunction';";
3380     }
3381 
3382     if (!error.empty()) {
3383         LOG_DEBUGGER(ERROR) << "BreakpointInfo::Create " << error;
3384         return nullptr;
3385     }
3386     return paramsObject;
3387 }
3388 
ToJson() const3389 std::unique_ptr<PtJson> BreakpointInfo::ToJson() const
3390 {
3391     std::unique_ptr<PtJson> result = PtJson::CreateObject();
3392     result->Add("lineNumber", lineNumber_);
3393     result->Add("columnNumber", columnNumber_);
3394     result->Add("url", url_.c_str());
3395     if (condition_) {
3396         result->Add("condition", condition_.value().c_str());
3397     }
3398     if (urlRegex_) {
3399         result->Add("urlRegex", urlRegex_.value().c_str());
3400     }
3401     if (scriptHash_) {
3402         result->Add("scriptHash", scriptHash_.value().c_str());
3403     }
3404     if (restrictToFunction_) {
3405         result->Add("restrictToFunction", restrictToFunction_.value());
3406     }
3407 
3408     return result;
3409 }
3410 
Create(const PtJson &params)3411 std::unique_ptr<BreakpointReturnInfo> BreakpointReturnInfo::Create(const PtJson &params)
3412 {
3413     auto paramsObject = std::make_unique<BreakpointReturnInfo>();
3414     std::string error;
3415     Result ret;
3416     // lineNumber
3417     int32_t lineNumber;
3418     ret = params.GetInt("lineNumber", &lineNumber);
3419     if (ret == Result::SUCCESS) {
3420         paramsObject->lineNumber_ = lineNumber;
3421     } else {
3422         error += "Wrong type of 'lineNumber';";
3423     }
3424     // columnNumber
3425     int32_t columnNumber;
3426     ret = params.GetInt("columnNumber", &columnNumber);
3427     if (ret == Result::SUCCESS) {
3428         paramsObject->columnNumber_ = columnNumber;
3429     } else if (ret == Result::TYPE_ERROR) {
3430         error += "Wrong type of 'columnNumber';";
3431     }
3432     // id
3433     std::string id;
3434     ret = params.GetString("id", &id);
3435     if (ret == Result::SUCCESS) {
3436         paramsObject->id_ = std::move(id);
3437     } else if (ret == Result::TYPE_ERROR) {
3438         error += "Wrong type of 'id';";
3439     }
3440     // scriptId
3441     int32_t scriptId;
3442     ret = params.GetInt("scriptId", &scriptId);
3443     if (ret == Result::SUCCESS) {
3444         paramsObject->scriptId_ = scriptId;
3445     } else if (ret == Result::TYPE_ERROR) {
3446         error += "Wrong type of 'scriptId';";
3447     }
3448 
3449     if (!error.empty()) {
3450         LOG_DEBUGGER(ERROR) << "BreakpointReturnInfo::Create " << error;
3451         return nullptr;
3452     }
3453 
3454     return paramsObject;
3455 }
3456 
ToJson() const3457 std::unique_ptr<PtJson> BreakpointReturnInfo::ToJson() const
3458 {
3459     std::unique_ptr<PtJson> result = PtJson::CreateObject();
3460     result->Add("lineNumber", lineNumber_);
3461     result->Add("columnNumber", columnNumber_);
3462     result->Add("id", id_.c_str());
3463     result->Add("scriptId", scriptId_);
3464 
3465     return result;
3466 }
3467 }  // namespace panda::ecmascript::tooling
3468