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