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