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