/* * Copyright (c) 2021-2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "pt_types.h" namespace panda::ecmascript::tooling { using ObjectType = RemoteObject::TypeName; using ObjectSubType = RemoteObject::SubTypeName; using ObjectClassName = RemoteObject::ClassName; const std::string ObjectType::Object = "object"; // NOLINT (readability-identifier-naming) const std::string ObjectType::Function = "function"; // NOLINT (readability-identifier-naming) const std::string ObjectType::Undefined = "undefined"; // NOLINT (readability-identifier-naming) const std::string ObjectType::String = "string"; // NOLINT (readability-identifier-naming) const std::string ObjectType::Number = "number"; // NOLINT (readability-identifier-naming) const std::string ObjectType::Boolean = "boolean"; // NOLINT (readability-identifier-naming) const std::string ObjectType::Symbol = "symbol"; // NOLINT (readability-identifier-naming) const std::string ObjectType::Bigint = "bigint"; // NOLINT (readability-identifier-naming) const std::string ObjectType::Wasm = "wasm"; // NOLINT (readability-identifier-naming) const std::string ObjectSubType::Array = "array"; // NOLINT (readability-identifier-naming) const std::string ObjectSubType::Null = "null"; // NOLINT (readability-identifier-naming) const std::string ObjectSubType::Node = "node"; // NOLINT (readability-identifier-naming) const std::string ObjectSubType::Regexp = "regexp"; // NOLINT (readability-identifier-naming) const std::string ObjectSubType::Date = "date"; // NOLINT (readability-identifier-naming) const std::string ObjectSubType::Map = "map"; // NOLINT (readability-identifier-naming) const std::string ObjectSubType::Set = "set"; // NOLINT (readability-identifier-naming) const std::string ObjectSubType::Weakmap = "weakmap"; // NOLINT (readability-identifier-naming) const std::string ObjectSubType::Weakset = "weakset"; // NOLINT (readability-identifier-naming) const std::string ObjectSubType::Iterator = "iterator"; // NOLINT (readability-identifier-naming) const std::string ObjectSubType::Generator = "generator"; // NOLINT (readability-identifier-naming) const std::string ObjectSubType::Error = "error"; // NOLINT (readability-identifier-naming) const std::string ObjectSubType::Proxy = "proxy"; // NOLINT (readability-identifier-naming) const std::string ObjectSubType::Promise = "promise"; // NOLINT (readability-identifier-naming) const std::string ObjectSubType::Typedarray = "typedarray"; // NOLINT (readability-identifier-naming) const std::string ObjectSubType::Arraybuffer = "arraybuffer"; // NOLINT (readability-identifier-naming) const std::string ObjectSubType::Dataview = "dataview"; // NOLINT (readability-identifier-naming) const std::string ObjectSubType::I32 = "i32"; // NOLINT (readability-identifier-naming) const std::string ObjectSubType::I64 = "i64"; // NOLINT (readability-identifier-naming) const std::string ObjectSubType::F32 = "f32"; // NOLINT (readability-identifier-naming) const std::string ObjectSubType::F64 = "f64"; // NOLINT (readability-identifier-naming) const std::string ObjectSubType::V128 = "v128"; // NOLINT (readability-identifier-naming) const std::string ObjectSubType::Externref = "externref"; // NOLINT (readability-identifier-naming) const std::string ObjectClassName::Object = "Object"; // NOLINT (readability-identifier-naming) const std::string ObjectClassName::Function = "Function"; // NOLINT (readability-identifier-naming) const std::string ObjectClassName::Array = "Array"; // NOLINT (readability-identifier-naming) const std::string ObjectClassName::Regexp = "RegExp"; // NOLINT (readability-identifier-naming) const std::string ObjectClassName::Date = "Date"; // NOLINT (readability-identifier-naming) const std::string ObjectClassName::Map = "Map"; // NOLINT (readability-identifier-naming) const std::string ObjectClassName::Set = "Set"; // NOLINT (readability-identifier-naming) const std::string ObjectClassName::Weakmap = "Weakmap"; // NOLINT (readability-identifier-naming) const std::string ObjectClassName::Weakset = "Weakset"; // NOLINT (readability-identifier-naming) const std::string ObjectClassName::ArrayIterator = "ArrayIterator"; // NOLINT (readability-identifier-naming) const std::string ObjectClassName::StringIterator = "StringIterator"; // NOLINT (readability-identifier-naming) const std::string ObjectClassName::SetIterator = "SetIterator"; // NOLINT (readability-identifier-naming) const std::string ObjectClassName::MapIterator = "MapIterator"; // NOLINT (readability-identifier-naming) const std::string ObjectClassName::Iterator = "Iterator"; // NOLINT (readability-identifier-naming) const std::string ObjectClassName::Error = "Error"; // NOLINT (readability-identifier-naming) const std::string ObjectClassName::Proxy = "Object"; // NOLINT (readability-identifier-naming) const std::string ObjectClassName::Promise = "Promise"; // NOLINT (readability-identifier-naming) const std::string ObjectClassName::Typedarray = "Typedarray"; // NOLINT (readability-identifier-naming) const std::string ObjectClassName::Arraybuffer = "Arraybuffer"; // NOLINT (readability-identifier-naming) const std::string ObjectClassName::Global = "global"; // NOLINT (readability-identifier-naming) const std::string ObjectClassName::Generator = "Generator"; // NOLINT (readability-identifier-naming) const std::string RemoteObject::ObjectDescription = "Object"; // NOLINT (readability-identifier-naming) const std::string RemoteObject::GlobalDescription = "global"; // NOLINT (readability-identifier-naming) const std::string RemoteObject::ProxyDescription = "Proxy"; // NOLINT (readability-identifier-naming) const std::string RemoteObject::PromiseDescription = "Promise"; // NOLINT (readability-identifier-naming) const std::string RemoteObject::ArrayIteratorDescription = // NOLINT (readability-identifier-naming) "ArrayIterator"; const std::string RemoteObject::StringIteratorDescription = // NOLINT (readability-identifier-naming) "StringIterator"; const std::string RemoteObject::SetIteratorDescription = "SetIterator"; // NOLINT (readability-identifier-naming) const std::string RemoteObject::MapIteratorDescription = "MapIterator"; // NOLINT (readability-identifier-naming) const std::string RemoteObject::WeakRefDescription = "WeakRef"; // NOLINT (readability-identifier-naming) const std::string RemoteObject::WeakMapDescription = "WeakMap"; // NOLINT (readability-identifier-naming) const std::string RemoteObject::WeakSetDescription = "WeakSet"; // NOLINT (readability-identifier-naming) const std::string RemoteObject::JSPrimitiveNumberDescription = // NOLINT (readability-identifier-naming) "Number"; const std::string RemoteObject::JSPrimitiveBooleanDescription = // NOLINT (readability-identifier-naming) "Boolean"; const std::string RemoteObject::JSPrimitiveStringDescription = // NOLINT (readability-identifier-naming) "String"; const std::string RemoteObject::JSPrimitiveSymbolDescription = // NOLINT (readability-identifier-naming) "Symbol"; const std::string RemoteObject::DateTimeFormatDescription = // NOLINT (readability-identifier-naming) "DateTimeFormat"; const std::string RemoteObject::JSIntlDescription = "Intl"; // NOLINT (readability-identifier-naming) const std::string RemoteObject::NumberFormatDescription = "NumberFormat"; // NOLINT (readability-identifier-naming) const std::string RemoteObject::CollatorDescription = "Collator"; // NOLINT (readability-identifier-naming) const std::string RemoteObject::PluralRulesDescription = "PluralRules"; // NOLINT (readability-identifier-naming) const std::string RemoteObject::JSLocaleDescription = "Locale"; // NOLINT (readability-identifier-naming) const std::string RemoteObject::JSListFormatDescription = "ListFormat"; // NOLINT (readability-identifier-naming) const std::string RemoteObject::JSRelativeTimeFormatDescription = // NOLINT (readability-identifier-naming) "RelativeTimeFormat"; std::unique_ptr RemoteObject::FromTagged(const EcmaVM *ecmaVm, Local tagged) { if (tagged->IsNull() || tagged->IsUndefined() || tagged->IsBoolean() || tagged->IsNumber() || tagged->IsBigInt()) { return std::make_unique(ecmaVm, tagged); } if (tagged->IsString()) { return std::make_unique(ecmaVm, Local(tagged)); } if (tagged->IsSymbol()) { return std::make_unique(ecmaVm, Local(tagged)); } // proxy must be placed in front of all object types if (tagged->IsProxy()) { return std::make_unique(ecmaVm, tagged, ObjectClassName::Proxy, ObjectSubType::Proxy); } if (tagged->IsGeneratorFunction()) { return std::make_unique(ecmaVm, Local(tagged)); } if (tagged->IsFunction()) { return std::make_unique(ecmaVm, tagged); } if (tagged->IsArray(ecmaVm)) { return std::make_unique(ecmaVm, tagged, ObjectClassName::Array, ObjectSubType::Array); } if (tagged->IsRegExp()) { return std::make_unique(ecmaVm, tagged, ObjectClassName::Regexp, ObjectSubType::Regexp); } if (tagged->IsDate()) { return std::make_unique(ecmaVm, tagged, ObjectClassName::Date, ObjectSubType::Date); } if (tagged->IsMap()) { return std::make_unique(ecmaVm, tagged, ObjectClassName::Map, ObjectSubType::Map); } if (tagged->IsWeakMap()) { return std::make_unique(ecmaVm, tagged, ObjectClassName::Weakmap, ObjectSubType::Weakmap); } if (tagged->IsSet()) { return std::make_unique(ecmaVm, tagged, ObjectClassName::Set, ObjectSubType::Set); } if (tagged->IsWeakSet()) { return std::make_unique(ecmaVm, tagged, ObjectClassName::Weakset, ObjectSubType::Weakset); } if (tagged->IsError()) { return std::make_unique(ecmaVm, tagged, ObjectClassName::Error, ObjectSubType::Error); } if (tagged->IsPromise()) { return std::make_unique(ecmaVm, tagged, ObjectClassName::Promise, ObjectSubType::Promise); } if (tagged->IsArrayBuffer()) { return std::make_unique(ecmaVm, tagged, ObjectClassName::Arraybuffer, ObjectSubType::Arraybuffer); } if (tagged->IsArrayIterator()) { return std::make_unique(ecmaVm, tagged, ObjectClassName::ArrayIterator); } if (tagged->IsStringIterator()) { return std::make_unique(ecmaVm, tagged, ObjectClassName::StringIterator); } if (tagged->IsSetIterator()) { return std::make_unique(ecmaVm, tagged, ObjectClassName::SetIterator, ObjectSubType::Iterator); } if (tagged->IsMapIterator()) { return std::make_unique(ecmaVm, tagged, ObjectClassName::MapIterator, ObjectSubType::Iterator); } if (tagged->IsObject()) { return std::make_unique(ecmaVm, tagged, ObjectClassName::Object); } std::unique_ptr object = std::make_unique(); object->SetType(ObjectType::Undefined); return object; } PrimitiveRemoteObject::PrimitiveRemoteObject(const EcmaVM *ecmaVm, Local tagged) { if (tagged->IsNull()) { SetType(ObjectType::Object).SetSubType(ObjectSubType::Null); } else if (tagged->IsBoolean()) { std::string description = tagged->IsTrue() ? "true" : "false"; SetType(ObjectType::Boolean) .SetValue(tagged) .SetUnserializableValue(description) .SetDescription(description); } else if (tagged->IsUndefined()) { SetType(ObjectType::Undefined); } else if (tagged->IsNumber()) { std::string description = tagged->ToString(ecmaVm)->ToString(); SetType(ObjectType::Number) .SetValue(tagged) .SetUnserializableValue(description) .SetDescription(description); } else if (tagged->IsBigInt()) { std::string description = tagged->ToString(ecmaVm)->ToString() + "n"; // n : BigInt literal postfix SetType(ObjectType::Bigint) .SetValue(tagged) .SetUnserializableValue(description) .SetDescription(description); } } StringRemoteObject::StringRemoteObject([[maybe_unused]] const EcmaVM *ecmaVm, Local tagged) { std::string description = tagged->ToString(); SetType(RemoteObject::TypeName::String) .SetValue(tagged) .SetUnserializableValue(description) .SetDescription(description); } SymbolRemoteObject::SymbolRemoteObject(const EcmaVM *ecmaVm, Local tagged) { std::string description = DescriptionForSymbol(ecmaVm, tagged); SetType(RemoteObject::TypeName::Symbol) .SetValue(tagged) .SetUnserializableValue(description) .SetDescription(description); } FunctionRemoteObject::FunctionRemoteObject(const EcmaVM *ecmaVm, Local tagged) { std::string description = DescriptionForFunction(ecmaVm, tagged); SetType(RemoteObject::TypeName::Function) .SetClassName(RemoteObject::ClassName::Function) .SetValue(tagged) .SetUnserializableValue(description) .SetDescription(description); } GeneratorFunctionRemoteObject::GeneratorFunctionRemoteObject(const EcmaVM *ecmaVm, Local tagged) { std::string description = DescriptionForGeneratorFunction(ecmaVm, tagged); SetType(RemoteObject::TypeName::Function) .SetClassName(RemoteObject::ClassName::Generator) .SetValue(tagged) .SetUnserializableValue(description) .SetDescription(description); } ObjectRemoteObject::ObjectRemoteObject(const EcmaVM *ecmaVm, Local tagged, const std::string &classname) { std::string description = DescriptionForObject(ecmaVm, tagged); SetType(RemoteObject::TypeName::Object) .SetClassName(classname) .SetValue(tagged) .SetUnserializableValue(description) .SetDescription(description); } ObjectRemoteObject::ObjectRemoteObject(const EcmaVM *ecmaVm, Local tagged, const std::string &classname, const std::string &subtype) { std::string description = DescriptionForObject(ecmaVm, tagged); SetType(RemoteObject::TypeName::Object) .SetSubType(subtype) .SetClassName(classname) .SetValue(tagged) .SetUnserializableValue(description) .SetDescription(description); } std::string ObjectRemoteObject::DescriptionForObject(const EcmaVM *ecmaVm, Local tagged) { // proxy must be placed in front of all object types if (tagged->IsProxy()) { return RemoteObject::ProxyDescription; } if (tagged->IsArray(ecmaVm)) { return DescriptionForArray(ecmaVm, Local(tagged)); } if (tagged->IsRegExp()) { return DescriptionForRegexp(ecmaVm, Local(tagged)); } if (tagged->IsDate()) { return DescriptionForDate(ecmaVm, Local(tagged)); } if (tagged->IsMap()) { return DescriptionForMap(ecmaVm, Local(tagged)); } if (tagged->IsWeakMap()) { return RemoteObject::WeakMapDescription; } if (tagged->IsSet()) { return DescriptionForSet(ecmaVm, Local(tagged)); } if (tagged->IsWeakSet()) { return RemoteObject::WeakSetDescription; } if (tagged->IsError()) { return DescriptionForError(ecmaVm, tagged); } if (tagged->IsPromise()) { return RemoteObject::PromiseDescription; } if (tagged->IsArrayIterator()) { return DescriptionForArrayIterator(); } if (tagged->IsStringIterator()) { return RemoteObject::StringIteratorDescription; } if (tagged->IsSetIterator()) { return DescriptionForSetIterator(); } if (tagged->IsMapIterator()) { return DescriptionForMapIterator(); } if (tagged->IsArrayBuffer()) { return DescriptionForArrayBuffer(ecmaVm, Local(tagged)); } if (tagged->IsSharedArrayBuffer()) { return DescriptionForSharedArrayBuffer(ecmaVm, Local(tagged)); } if (tagged->IsUint8Array()) { return DescriptionForUint8Array(ecmaVm, Local(tagged)); } if (tagged->IsInt8Array()) { return DescriptionForInt8Array(ecmaVm, Local(tagged)); } if (tagged->IsInt16Array()) { return DescriptionForInt16Array(ecmaVm, Local(tagged)); } if (tagged->IsInt32Array()) { return DescriptionForInt32Array(ecmaVm, Local(tagged)); } if (tagged->IsJSPrimitiveRef() && tagged->IsJSPrimitiveNumber()) { return DescriptionForPrimitiveNumber(ecmaVm, tagged); } if (tagged->IsJSPrimitiveRef() && tagged->IsJSPrimitiveString()) { return DescriptionForPrimitiveString(ecmaVm, tagged); } if (tagged->IsJSPrimitiveRef() && tagged->IsJSPrimitiveBoolean()) { return DescriptionForPrimitiveBoolean(ecmaVm, tagged); } if (tagged->IsGeneratorObject()) { return DescriptionForGeneratorObject(ecmaVm, tagged); } if (tagged->IsWeakRef()) { return DescriptionForWeakRef(); } if (tagged->IsJSLocale()) { return DescriptionForJSLocale(); } if (tagged->IsJSDateTimeFormat()) { return DescriptionForDateTimeFormat(); } if (tagged->IsJSRelativeTimeFormat()) { return DescriptionForJSRelativeTimeFormat(); } if (tagged->IsJSIntl()) { return RemoteObject::JSIntlDescription; } if (tagged->IsJSNumberFormat()) { return DescriptionForNumberFormat(); } if (tagged->IsJSCollator()) { return DescriptionForCollator(); } if (tagged->IsJSPluralRules()) { return DescriptionForPluralRules(); } if (tagged->IsJSListFormat()) { return DescriptionForJSListFormat(); } return RemoteObject::ObjectDescription; } std::string ObjectRemoteObject::DescriptionForArray(const EcmaVM *ecmaVm, Local tagged) { std::string description = "Array(" + std::to_string(tagged->Length(ecmaVm)) + ")"; return description; } std::string ObjectRemoteObject::DescriptionForRegexp(const EcmaVM *ecmaVm, Local tagged) { std::string regExpSource = tagged->GetOriginalSource(ecmaVm)->ToString(); std::string regExpFlags = tagged->GetOriginalFlags(); return "/" + regExpSource + "/" + regExpFlags; } std::string ObjectRemoteObject::DescriptionForDate(const EcmaVM *ecmaVm, Local tagged) { std::string description = tagged->ToString(ecmaVm)->ToString(); return description; } std::string ObjectRemoteObject::DescriptionForMap(const EcmaVM *ecmaVm, Local tagged) { int32_t len = tagged->GetTotalElements(); int32_t index = 0; std::string description = "Map(" + std::to_string(len) + ")"; if (!len) { return description; } description += " {"; char cPre = '\''; for (int32_t i = 0; i < len; ++i) { // add Key Local jsVKey = tagged->GetKey(ecmaVm, i); if (jsVKey->IsHole()) { continue; } Local jsVValue = tagged->GetValue(ecmaVm, i); if (jsVKey->IsObject()) { description += "Object"; } else if (jsVKey->IsString()) { description += cPre + jsVKey->ToString(ecmaVm)->ToString() + cPre; } else { description += jsVKey->ToString(ecmaVm)->ToString(); } description += " => "; // add Value if (jsVValue->IsObject()) { description += "Object"; } else if (jsVValue->IsString()) { description += cPre + jsVValue->ToString(ecmaVm)->ToString() + cPre; } else { description += jsVValue->ToString(ecmaVm)->ToString(); } if (index == tagged->GetSize() - 1 || index >= 4) { // 4:The count of elements description += tagged->GetSize() > 5 ? ", ..." : ""; // 5:The count of elements break; } description += ", "; index++; } description += "}"; return description; } std::string ObjectRemoteObject::DescriptionForSet(const EcmaVM *ecmaVm, Local tagged) { int32_t len = tagged->GetTotalElements(); int32_t index = 0; std::string description = ("Set(" + std::to_string(tagged->GetSize()) + ")"); if (!len) { return description; } description += " {"; char cPre = '\''; for (int32_t i = 0; i < len; ++i) { // add Key Local jsValue = tagged->GetValue(ecmaVm, i); if (jsValue->IsHole()) { continue; } // add Value if (jsValue->IsObject()) { description += "Object"; } else if (jsValue->IsString()) { description += cPre + jsValue->ToString(ecmaVm)->ToString() + cPre; } else { description += jsValue->ToString(ecmaVm)->ToString(); } if (index == tagged->GetSize() - 1 || index >= 4) { // 4:The count of elements description += tagged->GetSize() > 5 ? ", ..." : ""; // 5:The count of elements break; } description += ", "; index++; } description += "}"; return description; } std::string ObjectRemoteObject::DescriptionForError(const EcmaVM *ecmaVm, Local tagged) { // add name Local name = StringRef::NewFromUtf8(ecmaVm, "name"); std::string strName = Local(tagged)->Get(ecmaVm, name)->ToString(ecmaVm)->ToString(); // add message Local message = StringRef::NewFromUtf8(ecmaVm, "message"); std::string strMessage = Local(tagged)->Get(ecmaVm, message)->ToString(ecmaVm)->ToString(); if (strMessage.empty()) { return strName; } else { return strName + ": " + strMessage; } } std::string ObjectRemoteObject::DescriptionForArrayIterator() { std::string description = RemoteObject::ArrayIteratorDescription + "{}"; return description; } std::string ObjectRemoteObject::DescriptionForSetIterator() { std::string description = RemoteObject::SetIteratorDescription + "{}"; return description; } std::string ObjectRemoteObject::DescriptionForMapIterator() { std::string description = RemoteObject::MapIteratorDescription + "{}"; return description; } std::string ObjectRemoteObject::DescriptionForArrayBuffer(const EcmaVM *ecmaVm, Local tagged) { int32_t len = tagged->ByteLength(ecmaVm); std::string description = ("ArrayBuffer(" + std::to_string(len) + ")"); return description; } std::string ObjectRemoteObject::DescriptionForSharedArrayBuffer(const EcmaVM *ecmaVm, Local tagged) { int32_t len = tagged->ByteLength(ecmaVm); std::string description = ("SharedArrayBuffer(" + std::to_string(len) + ")"); return description; } std::string ObjectRemoteObject::DescriptionForUint8Array(const EcmaVM *ecmaVm, Local tagged) { int32_t len = static_cast(tagged->ByteLength(ecmaVm)); std::string description = ("Uint8Array(" + std::to_string(len) + ")"); return description; } std::string ObjectRemoteObject::DescriptionForInt8Array(const EcmaVM *ecmaVm, Local tagged) { int32_t len = static_cast(tagged->ByteLength(ecmaVm)); std::string description = ("Int8Array(" + std::to_string(len) + ")"); return description; } std::string ObjectRemoteObject::DescriptionForInt16Array(const EcmaVM *ecmaVm, Local tagged) { int32_t len = tagged->ByteLength(ecmaVm) / static_cast(NumberSize::BYTES_OF_16BITS); std::string description = ("Int16Array(" + std::to_string(len) + ")"); return description; } std::string ObjectRemoteObject::DescriptionForInt32Array(const EcmaVM *ecmaVm, Local tagged) { int32_t len = tagged->ByteLength(ecmaVm) / static_cast(NumberSize::BYTES_OF_32BITS); std::string description = ("Int32Array(" + std::to_string(len) + ")"); return description; } std::string ObjectRemoteObject::DescriptionForPrimitiveNumber(const EcmaVM *ecmaVm, const Local &tagged) { std::string strValue = tagged->ToString(ecmaVm)->ToString(); std::string description = RemoteObject::JSPrimitiveNumberDescription + "{[[PrimitiveValue]]: " + strValue + "}"; return description; } std::string ObjectRemoteObject::DescriptionForPrimitiveString(const EcmaVM *ecmaVm, const Local &tagged) { std::string strValue = tagged->ToString(ecmaVm)->ToString(); std::string description = RemoteObject::JSPrimitiveStringDescription + "{[[PrimitiveValue]]: " + strValue + "}"; return description; } std::string ObjectRemoteObject::DescriptionForPrimitiveBoolean(const EcmaVM *ecmaVm, const Local &tagged) { std::string strValue = tagged->ToString(ecmaVm)->ToString(); std::string description = RemoteObject::JSPrimitiveBooleanDescription + "{[[PrimitiveValue]]: " + strValue + "}"; return description; } std::string ObjectRemoteObject::DescriptionForGeneratorObject(const EcmaVM *ecmaVm, const Local &tagged) { Local genObjectRef = tagged->ToObject(ecmaVm); // add Status Local jsValueRef = genObjectRef->GetGeneratorState(ecmaVm); std::string strState = genObjectRef->GetGeneratorState(ecmaVm)->ToString(ecmaVm)->ToString(); // add FuncName jsValueRef = genObjectRef->GetGeneratorFunction(ecmaVm); Local name = StringRef::NewFromUtf8(ecmaVm, "name"); std::string strFuncName = Local(jsValueRef)->Get(ecmaVm, name)->ToString(ecmaVm)->ToString(); std::string description = strFuncName + " {<" + strState + ">}"; return description; } std::string ObjectRemoteObject::DescriptionForWeakRef() { std::string description = RemoteObject::WeakRefDescription + " {}"; return description; } std::string ObjectRemoteObject::DescriptionForDateTimeFormat() { std::string description = RemoteObject::DateTimeFormatDescription + " {}"; return description; } std::string ObjectRemoteObject::DescriptionForNumberFormat() { std::string description = RemoteObject::NumberFormatDescription + " {}"; return description; } std::string ObjectRemoteObject::DescriptionForCollator() { std::string description = RemoteObject::CollatorDescription + " {}"; return description; } std::string ObjectRemoteObject::DescriptionForPluralRules() { std::string description = RemoteObject::PluralRulesDescription + " {}"; return description; } std::string ObjectRemoteObject::DescriptionForJSLocale() { std::string description = RemoteObject::JSLocaleDescription + " {}"; return description; } std::string ObjectRemoteObject::DescriptionForJSRelativeTimeFormat() { std::string description = RemoteObject::JSRelativeTimeFormatDescription + " {}"; return description; } std::string ObjectRemoteObject::DescriptionForJSListFormat() { std::string description = RemoteObject::JSListFormatDescription + " {}"; return description; } std::string SymbolRemoteObject::DescriptionForSymbol(const EcmaVM *ecmaVm, Local tagged) const { std::string description = "Symbol(" + tagged->GetDescription(ecmaVm)->ToString() + ")"; return description; } std::string FunctionRemoteObject::DescriptionForFunction(const EcmaVM *ecmaVm, Local tagged) const { std::string sourceCode; if (tagged->IsNative(ecmaVm)) { sourceCode = "[native code]"; } else { sourceCode = "[js code]"; } Local name = tagged->GetName(ecmaVm); std::string description = "function " + name->ToString() + "( { " + sourceCode + " }"; return description; } std::string GeneratorFunctionRemoteObject::DescriptionForGeneratorFunction(const EcmaVM *ecmaVm, Local tagged) const { std::string sourceCode; if (tagged->IsNative(ecmaVm)) { sourceCode = "[native code]"; } else { sourceCode = "[js code]"; } Local name = tagged->GetName(ecmaVm); std::string description = "function* " + name->ToString() + "( { " + sourceCode + " }"; return description; } std::unique_ptr RemoteObject::Create(const PtJson ¶ms) { std::string error; auto remoteObject = std::make_unique(); Result ret; std::string type; ret = params.GetString("type", &type); if (ret == Result::SUCCESS) { if (ObjectType::Valid(type)) { remoteObject->type_ = std::move(type); } else { error += "'type' is invalid;"; } } else { error += "Unknown 'type';"; } std::string subType; ret = params.GetString("subtype", &subType); if (ret == Result::SUCCESS) { if (ObjectSubType::Valid(subType)) { remoteObject->subType_ = std::move(subType); } else { error += "'subtype' is invalid;"; } } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'subtype';"; } std::string className; ret = params.GetString("className", &className); if (ret == Result::SUCCESS) { remoteObject->className_ = std::move(className); } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'className';"; } std::string unserializableValue; ret = params.GetString("unserializableValue", &unserializableValue); if (ret == Result::SUCCESS) { remoteObject->unserializableValue_ = std::move(unserializableValue); } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'unserializableValue';"; } std::string description; ret = params.GetString("description", &description); if (ret == Result::SUCCESS) { remoteObject->description_ = std::move(description); } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'description';"; } std::string objectId; ret = params.GetString("objectId", &objectId); if (ret == Result::SUCCESS) { remoteObject->objectId_ = std::stoi(objectId); } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'objectId';"; } if (!error.empty()) { LOG_DEBUGGER(ERROR) << "RemoteObject::Create " << error; return nullptr; } return remoteObject; } std::unique_ptr RemoteObject::ToJson() const { std::unique_ptr result = PtJson::CreateObject(); result->Add("type", type_.c_str()); if (subType_) { result->Add("subtype", subType_->c_str()); } if (className_) { result->Add("className", className_->c_str()); } if (unserializableValue_) { result->Add("unserializableValue", unserializableValue_->c_str()); } if (description_) { result->Add("description", description_->c_str()); } if (objectId_) { result->Add("objectId", std::to_string(objectId_.value()).c_str()); } return result; } std::unique_ptr ExceptionDetails::Create(const PtJson ¶ms) { std::string error; auto exceptionDetails = std::make_unique(); Result ret; int32_t exceptionId; ret = params.GetInt("exceptionId", &exceptionId); if (ret == Result::SUCCESS) { exceptionDetails->exceptionId_ = exceptionId; } else { error += "Unknown 'exceptionId';"; } std::string text; ret = params.GetString("text", &text); if (ret == Result::SUCCESS) { exceptionDetails->text_ = std::move(text); } else { error += "Unknown 'text';"; } int32_t lineNumber; ret = params.GetInt("lineNumber", &lineNumber); if (ret == Result::SUCCESS) { exceptionDetails->lineNumber_ = lineNumber; } else { error += "Unknown 'lineNumber';"; } int32_t columnNumber; ret = params.GetInt("columnNumber", &columnNumber); if (ret == Result::SUCCESS) { exceptionDetails->columnNumber_ = columnNumber; } else { error += "Unknown 'columnNumber';"; } std::string scriptId; ret = params.GetString("scriptId", &scriptId); if (ret == Result::SUCCESS) { exceptionDetails->scriptId_ = std::stoi(scriptId); } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'scriptId';"; } std::string url; ret = params.GetString("url", &url); if (ret == Result::SUCCESS) { exceptionDetails->url_ = std::move(url); } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'url';"; } std::unique_ptr exception; ret = params.GetObject("exception", &exception); if (ret == Result::SUCCESS) { std::unique_ptr obj = RemoteObject::Create(*exception); if (obj == nullptr) { error += "'exception' format error;"; } else { exceptionDetails->exception_ = std::move(obj); } } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'exception';"; } int32_t executionContextId; ret = params.GetInt("executionContextId", &executionContextId); if (ret == Result::SUCCESS) { exceptionDetails->executionContextId_ = executionContextId; } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'executionContextId';"; } if (!error.empty()) { LOG_DEBUGGER(ERROR) << "ExceptionDetails::Create " << error; return nullptr; } return exceptionDetails; } std::unique_ptr ExceptionDetails::ToJson() const { std::unique_ptr result = PtJson::CreateObject(); result->Add("exceptionId", exceptionId_); result->Add("text", text_.c_str()); result->Add("lineNumber", lineNumber_); result->Add("columnNumber", columnNumber_); if (scriptId_) { result->Add("scriptId", std::to_string(scriptId_.value()).c_str()); } if (url_) { result->Add("url", url_->c_str()); } if (exception_) { ASSERT(exception_.value() != nullptr); result->Add("exception", exception_.value()->ToJson()); } if (executionContextId_) { result->Add("executionContextId", executionContextId_.value()); } return result; } std::unique_ptr InternalPropertyDescriptor::Create(const PtJson ¶ms) { std::string error; auto internalPropertyDescriptor = std::make_unique(); Result ret; std::string name; ret = params.GetString("name", &name); if (ret == Result::SUCCESS) { internalPropertyDescriptor->name_ = std::move(name); } else { error += "Unknown 'name';"; } std::unique_ptr value; ret = params.GetObject("value", &value); if (ret == Result::SUCCESS) { std::unique_ptr obj = RemoteObject::Create(*value); if (obj == nullptr) { error += "'value' format error;"; } else { internalPropertyDescriptor->value_ = std::move(obj); } } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'value';"; } if (!error.empty()) { LOG_DEBUGGER(ERROR) << "InternalPropertyDescriptor::Create " << error; return nullptr; } return internalPropertyDescriptor; } std::unique_ptr InternalPropertyDescriptor::ToJson() const { std::unique_ptr result = PtJson::CreateObject(); result->Add("name", name_.c_str()); if (value_) { ASSERT(value_.value() != nullptr); result->Add("value", value_.value()->ToJson()); } return result; } std::unique_ptr PrivatePropertyDescriptor::Create(const PtJson ¶ms) { std::string error; auto privatePropertyDescriptor = std::make_unique(); Result ret; std::string name; ret = params.GetString("name", &name); if (ret == Result::SUCCESS) { privatePropertyDescriptor->name_ = std::move(name); } else { error += "Unknown 'name';"; } std::unique_ptr value; ret = params.GetObject("value", &value); std::unique_ptr obj; if (ret == Result::SUCCESS) { obj = RemoteObject::Create(*value); if (obj == nullptr) { error += "'value' format error;"; } else { privatePropertyDescriptor->value_ = std::move(obj); } } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'value';"; } std::unique_ptr get; ret = params.GetObject("get", &get); if (ret == Result::SUCCESS) { obj = RemoteObject::Create(*get); if (obj == nullptr) { error += "'get' format error;"; } else { privatePropertyDescriptor->get_ = std::move(obj); } } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'get';"; } std::unique_ptr set; ret = params.GetObject("set", &set); if (ret == Result::SUCCESS) { obj = RemoteObject::Create(*set); if (obj == nullptr) { error += "'set' format error;"; } else { privatePropertyDescriptor->set_ = std::move(obj); } } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'set';"; } if (!error.empty()) { LOG_DEBUGGER(ERROR) << "PrivatePropertyDescriptor::Create " << error; return nullptr; } return privatePropertyDescriptor; } std::unique_ptr PrivatePropertyDescriptor::ToJson() const { std::unique_ptr result = PtJson::CreateObject(); result->Add("name", name_.c_str()); if (value_) { ASSERT(value_.value() != nullptr); result->Add("value", value_.value()->ToJson()); } if (get_) { ASSERT(get_.value() != nullptr); result->Add("get", get_.value()->ToJson()); } if (set_) { ASSERT(set_.value() != nullptr); result->Add("set", set_.value()->ToJson()); } return result; } std::unique_ptr PropertyDescriptor::FromProperty(const EcmaVM *ecmaVm, Local name, const PropertyAttribute &property) { std::unique_ptr debuggerProperty = std::make_unique(); std::string nameStr; if (name->IsSymbol()) { Local symbol(name); nameStr = "Symbol(" + Local(name)->GetDescription(ecmaVm)->ToString() + ")"; debuggerProperty->symbol_ = RemoteObject::FromTagged(ecmaVm, name); } else { nameStr = name->ToString(ecmaVm)->ToString(); } debuggerProperty->name_ = nameStr; if (property.HasValue()) { debuggerProperty->value_ = RemoteObject::FromTagged(ecmaVm, property.GetValue(ecmaVm)); } if (property.HasWritable()) { debuggerProperty->writable_ = property.IsWritable(); } if (property.HasGetter()) { debuggerProperty->get_ = RemoteObject::FromTagged(ecmaVm, property.GetGetter(ecmaVm)); } if (property.HasSetter()) { debuggerProperty->set_ = RemoteObject::FromTagged(ecmaVm, property.GetSetter(ecmaVm)); } debuggerProperty->configurable_ = property.IsConfigurable(); debuggerProperty->enumerable_ = property.IsEnumerable(); debuggerProperty->isOwn_ = true; return debuggerProperty; } std::unique_ptr PropertyDescriptor::Create(const PtJson ¶ms) { std::string error; auto propertyDescriptor = std::make_unique(); Result ret; std::string name; ret = params.GetString("name", &name); if (ret == Result::SUCCESS) { propertyDescriptor->name_ = std::move(name); } else { error += "Unknown 'name';"; } std::unique_ptr value; std::unique_ptr obj; ret = params.GetObject("value", &value); if (ret == Result::SUCCESS) { obj = RemoteObject::Create(*value); if (obj == nullptr) { error += "'value' format error;"; } else { propertyDescriptor->value_ = std::move(obj); } } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'value';"; } bool writable = false; ret = params.GetBool("writable", &writable); if (ret == Result::SUCCESS) { propertyDescriptor->writable_ = writable; } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'writable';"; } std::unique_ptr get; ret = params.GetObject("get", &get); if (ret == Result::SUCCESS) { obj = RemoteObject::Create(*get); if (obj == nullptr) { error += "'get' format error;"; } else { propertyDescriptor->get_ = std::move(obj); } } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'get';"; } std::unique_ptr set; ret = params.GetObject("set", &set); if (ret == Result::SUCCESS) { obj = RemoteObject::Create(*set); if (obj == nullptr) { error += "'set' format error;"; } else { propertyDescriptor->set_ = std::move(obj); } } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'set';"; } bool configurable = false; ret = params.GetBool("configurable", &configurable); if (ret == Result::SUCCESS) { propertyDescriptor->configurable_ = configurable; } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'configurable';"; } bool enumerable = false; ret = params.GetBool("enumerable", &enumerable); if (ret == Result::SUCCESS) { propertyDescriptor->enumerable_ = enumerable; } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'enumerable';"; } bool wasThrown = false; ret = params.GetBool("wasThrown", &wasThrown); if (ret == Result::SUCCESS) { propertyDescriptor->wasThrown_ = wasThrown; } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'wasThrown';"; } bool isOwn = false; ret = params.GetBool("isOwn", &isOwn); if (ret == Result::SUCCESS) { propertyDescriptor->isOwn_ = isOwn; } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'isOwn';"; } std::unique_ptr symbol; ret = params.GetObject("symbol", &symbol); if (ret == Result::SUCCESS) { obj = RemoteObject::Create(*symbol); if (obj == nullptr) { error += "'symbol' format error;"; } else { propertyDescriptor->symbol_ = std::move(obj); } } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'symbol';"; } if (!error.empty()) { LOG_DEBUGGER(ERROR) << "PropertyDescriptor::Create " << error; return nullptr; } return propertyDescriptor; } std::unique_ptr PropertyDescriptor::ToJson() const { std::unique_ptr result = PtJson::CreateObject(); result->Add("name", name_.c_str()); if (value_) { ASSERT(value_.value() != nullptr); result->Add("value", value_.value()->ToJson()); } if (writable_) { result->Add("writable", writable_.value()); } if (get_) { ASSERT(get_.value() != nullptr); result->Add("get", get_.value()->ToJson()); } if (set_) { ASSERT(set_.value() != nullptr); result->Add("set", set_.value()->ToJson()); } result->Add("configurable", configurable_); result->Add("enumerable", enumerable_); if (wasThrown_) { result->Add("wasThrown", wasThrown_.value()); } if (isOwn_) { result->Add("isOwn", isOwn_.value()); } if (symbol_) { ASSERT(symbol_.value() != nullptr); result->Add("symbol", symbol_.value()->ToJson()); } return result; } std::unique_ptr CallArgument::Create(const PtJson ¶ms) { auto callArgument = std::make_unique(); std::string error; Result ret; std::string unserializableValue; ret = params.GetString("unserializableValue", &unserializableValue); if (ret == Result::SUCCESS) { callArgument->unserializableValue_ = std::move(unserializableValue); } else if (ret == Result::TYPE_ERROR) { // optional value error += "Unknown 'unserializableValue';"; } std::string objectId; ret = params.GetString("objectId", &objectId); if (ret == Result::SUCCESS) { callArgument->objectId_ = std::stoi(objectId); } else if (ret == Result::TYPE_ERROR) { // optional value error += "Unknown 'objectId';"; } if (!error.empty()) { LOG_DEBUGGER(ERROR) << "CallArgument::Create " << error; return nullptr; } return callArgument; } std::unique_ptr CallArgument::ToJson() const { std::unique_ptr result = PtJson::CreateObject(); if (unserializableValue_) { result->Add("unserializableValue", unserializableValue_->c_str()); } if (objectId_) { result->Add("objectId", std::to_string(objectId_.value()).c_str()); } return result; } std::unique_ptr Location::Create(const PtJson ¶ms) { auto location = std::make_unique(); std::string error; Result ret; std::string scriptId; ret = params.GetString("scriptId", &scriptId); if (ret == Result::SUCCESS) { location->scriptId_ = std::stoi(scriptId); } else { error += "Unknown 'scriptId';"; } int32_t lineNumber; ret = params.GetInt("lineNumber", &lineNumber); if (ret == Result::SUCCESS) { location->lineNumber_ = lineNumber; } else { error += "Unknown 'lineNumber';"; } int32_t columnNumber; ret = params.GetInt("columnNumber", &columnNumber); if (ret == Result::SUCCESS) { location->columnNumber_ = columnNumber; } else if (ret == Result::TYPE_ERROR) { // optional value error += "Unknown 'columnNumber';"; } if (!error.empty()) { LOG_DEBUGGER(ERROR) << "Location::Create " << error; return nullptr; } return location; } std::unique_ptr Location::ToJson() const { std::unique_ptr result = PtJson::CreateObject(); result->Add("scriptId", std::to_string(scriptId_).c_str()); result->Add("lineNumber", lineNumber_); if (columnNumber_) { result->Add("columnNumber", columnNumber_.value()); } return result; } std::unique_ptr ScriptPosition::Create(const PtJson ¶ms) { auto scriptPosition = std::make_unique(); std::string error; Result ret; int32_t lineNumber; ret = params.GetInt("lineNumber", &lineNumber); if (ret == Result::SUCCESS) { scriptPosition->lineNumber_ = lineNumber; } else { error += "Unknown 'lineNumber';"; } int32_t columnNumber; ret = params.GetInt("columnNumber", &columnNumber); if (ret == Result::SUCCESS) { scriptPosition->columnNumber_ = columnNumber; } else { error += "Unknown 'columnNumber';"; } if (!error.empty()) { LOG_DEBUGGER(ERROR) << "ScriptPosition::Create " << error; return nullptr; } return scriptPosition; } std::unique_ptr ScriptPosition::ToJson() const { std::unique_ptr result = PtJson::CreateObject(); result->Add("lineNumber", lineNumber_); result->Add("columnNumber", columnNumber_); return result; } std::unique_ptr SearchMatch::Create(const PtJson ¶ms) { std::string error; auto locationSearch = std::make_unique(); Result ret; int32_t lineNumber; ret = params.GetInt("lineNumber", &lineNumber); if (ret == Result::SUCCESS) { locationSearch->lineNumber_ = lineNumber; } else { error += "Unknown 'lineNumber';"; } std::string lineContent; ret = params.GetString("lineContent", &lineContent); if (ret == Result::SUCCESS) { locationSearch->lineContent_ = std::move(lineContent); } else { error += "Unknown 'lineContent';"; } if (!error.empty()) { LOG_DEBUGGER(ERROR) << "SearchMatch::Create " << error; return nullptr; } return locationSearch; } std::unique_ptr SearchMatch::ToJson() const { std::unique_ptr result = PtJson::CreateObject(); result->Add("lineNumber", lineNumber_); result->Add("lineContent", lineContent_.c_str()); return result; } std::unique_ptr LocationRange::Create(const PtJson ¶ms) { std::string error; auto locationRange = std::make_unique(); Result ret; std::string scriptId; ret = params.GetString("scriptId", &scriptId); if (ret == Result::SUCCESS) { locationRange->scriptId_ = std::stoi(scriptId); } else { error += "Unknown 'scriptId';"; } std::unique_ptr start; std::unique_ptr obj; ret = params.GetObject("start", &start); if (ret == Result::SUCCESS) { obj = ScriptPosition::Create(*start); if (obj == nullptr) { error += "'start' format error;"; } else { locationRange->start_ = std::move(obj); } } else { error += "Unknown 'start';"; } std::unique_ptr end; ret = params.GetObject("end", &end); if (ret == Result::SUCCESS) { obj = ScriptPosition::Create(*end); if (obj == nullptr) { error += "'end' format error;"; } else { locationRange->end_ = std::move(obj); } } else { error += "Unknown 'end';"; } if (!error.empty()) { LOG_DEBUGGER(ERROR) << "LocationRange::Create " << error; return nullptr; } return locationRange; } std::unique_ptr LocationRange::ToJson() const { std::unique_ptr result = PtJson::CreateObject(); result->Add("scriptId", std::to_string(scriptId_).c_str()); ASSERT(start_ != nullptr); result->Add("start", start_->ToJson()); ASSERT(end_ != nullptr); result->Add("end", end_->ToJson()); return result; } std::unique_ptr BreakLocation::Create(const PtJson ¶ms) { std::string error; auto breakLocation = std::make_unique(); Result ret; std::string scriptId; ret = params.GetString("scriptId", &scriptId); if (ret == Result::SUCCESS) { breakLocation->scriptId_ = std::stoi(scriptId); } else { error += "Unknown 'scriptId';"; } int32_t lineNumber; ret = params.GetInt("lineNumber", &lineNumber); if (ret == Result::SUCCESS) { breakLocation->lineNumber_ = lineNumber; } else { error += "Unknown 'lineNumber';"; } int32_t columnNumber; ret = params.GetInt("columnNumber", &columnNumber); if (ret == Result::SUCCESS) { breakLocation->columnNumber_ = columnNumber; } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'columnNumber';"; } std::string type; ret = params.GetString("type", &type); if (ret == Result::SUCCESS) { if (BreakType::Valid(type)) { breakLocation->type_ = std::move(type); } else { error += "'type' is invalid;"; } } else if (ret == Result::TYPE_ERROR) { error += "type 'scriptId';"; } if (!error.empty()) { LOG_DEBUGGER(ERROR) << "Location::Create " << error; return nullptr; } return breakLocation; } std::unique_ptr BreakLocation::ToJson() const { std::unique_ptr result = PtJson::CreateObject(); result->Add("scriptId", std::to_string(scriptId_).c_str()); result->Add("lineNumber", lineNumber_); if (columnNumber_) { result->Add("columnNumber", columnNumber_.value()); } if (type_) { result->Add("type", type_->c_str()); } return result; } std::unique_ptr Scope::Create(const PtJson ¶ms) { std::string error; auto scope = std::make_unique(); Result ret; std::string type; ret = params.GetString("type", &type); if (ret == Result::SUCCESS) { if (Scope::Type::Valid(type)) { scope->type_ = std::move(type); } else { error += "'type' is invalid;"; } } else { error += "Unknown 'type';"; } std::unique_ptr object; std::unique_ptr remoteObject; ret = params.GetObject("object", &object); if (ret == Result::SUCCESS) { remoteObject = RemoteObject::Create(*object); if (remoteObject == nullptr) { error += "'object' format error;"; } else { scope->object_ = std::move(remoteObject); } } else { error += "Unknown 'object';"; } std::string name; ret = params.GetString("name", &name); if (ret == Result::SUCCESS) { scope->name_ = std::move(name); } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'name';"; } std::unique_ptr startLocation; std::unique_ptr obj; ret = params.GetObject("startLocation", &startLocation); if (ret == Result::SUCCESS) { obj = Location::Create(*startLocation); if (obj == nullptr) { error += "'startLocation' format error;"; } else { scope->startLocation_ = std::move(obj); } } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'startLocation';"; } std::unique_ptr endLocation; ret = params.GetObject("endLocation", &endLocation); if (ret == Result::SUCCESS) { obj = Location::Create(*endLocation); if (obj == nullptr) { error += "'endLocation' format error;"; } else { scope->endLocation_ = std::move(obj); } } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'endLocation';"; } if (!error.empty()) { LOG_DEBUGGER(ERROR) << "Location::Create " << error; return nullptr; } return scope; } std::unique_ptr Scope::ToJson() const { std::unique_ptr result = PtJson::CreateObject(); result->Add("type", type_.c_str()); ASSERT(object_ != nullptr); result->Add("object", object_->ToJson()); if (name_) { result->Add("name", name_->c_str()); } if (startLocation_) { ASSERT(startLocation_.value() != nullptr); result->Add("startLocation", startLocation_.value()->ToJson()); } if (endLocation_) { ASSERT(endLocation_.value() != nullptr); result->Add("endLocation", endLocation_.value()->ToJson()); } return result; } std::unique_ptr CallFrame::Create(const PtJson ¶ms) { std::string error; auto callFrame = std::make_unique(); Result ret; std::string callFrameId; ret = params.GetString("callFrameId", &callFrameId); if (ret == Result::SUCCESS) { callFrame->callFrameId_ = std::stoi(callFrameId); } else { error += "Unknown 'callFrameId';"; } std::string functionName; ret = params.GetString("functionName", &functionName); if (ret == Result::SUCCESS) { callFrame->functionName_ = std::move(functionName); } else { error += "Unknown 'functionName';"; } std::unique_ptr functionLocation; std::unique_ptr obj; ret = params.GetObject("functionLocation", &functionLocation); if (ret == Result::SUCCESS) { obj = Location::Create(*functionLocation); if (obj == nullptr) { error += "'functionLocation' format error;"; } else { callFrame->functionLocation_ = std::move(obj); } } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'functionLocation';"; } std::unique_ptr location; ret = params.GetObject("location", &location); if (ret == Result::SUCCESS) { obj = Location::Create(*location); if (obj == nullptr) { error += "'location' format error;"; } else { callFrame->location_ = std::move(obj); } } else { error += "Unknown 'location';"; } std::string url; ret = params.GetString("url", &url); if (ret == Result::SUCCESS) { callFrame->url_ = std::move(url); } else { error += "Unknown 'url';"; } std::unique_ptr scopeChain; ret = params.GetArray("scopeChain", &scopeChain); if (ret == Result::SUCCESS) { int32_t len = scopeChain->GetSize(); for (int32_t i = 0; i < len; ++i) { std::unique_ptr arrayEle = scopeChain->Get(i); ASSERT(arrayEle != nullptr); std::unique_ptr scope = Scope::Create(*arrayEle); if (scope == nullptr) { error += "'scopeChain' format error;"; } else { callFrame->scopeChain_.emplace_back(std::move(scope)); } } } else { error += "Unknown 'scopeChain';"; } std::unique_ptr thisObj; std::unique_ptr remoteObject; ret = params.GetObject("this", &thisObj); if (ret == Result::SUCCESS) { remoteObject = RemoteObject::Create(*thisObj); if (remoteObject == nullptr) { error += "'this' format error;"; } else { callFrame->this_ = std::move(remoteObject); } } else { error += "Unknown 'this';"; } std::unique_ptr returnValue; ret = params.GetObject("returnValue", &returnValue); if (ret == Result::SUCCESS) { remoteObject = RemoteObject::Create(*returnValue); if (remoteObject == nullptr) { error += "'returnValue' format error;"; } else { callFrame->returnValue_ = std::move(remoteObject); } } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'returnValue';"; } if (!error.empty()) { LOG_DEBUGGER(ERROR) << "CallFrame::Create " << error; return nullptr; } return callFrame; } std::unique_ptr CallFrame::ToJson() const { std::unique_ptr result = PtJson::CreateObject(); result->Add("callFrameId", std::to_string(callFrameId_).c_str()); result->Add("functionName", functionName_.c_str()); if (functionLocation_) { ASSERT(functionLocation_.value() != nullptr); result->Add("functionLocation", functionLocation_.value()->ToJson()); } ASSERT(location_ != nullptr); result->Add("location", location_->ToJson()); result->Add("url", url_.c_str()); size_t len = scopeChain_.size(); std::unique_ptr values = PtJson::CreateArray(); for (size_t i = 0; i < len; i++) { ASSERT(scopeChain_[i] != nullptr); std::unique_ptr scope = scopeChain_[i]->ToJson(); values->Push(scope); } result->Add("scopeChain", values); ASSERT(this_ != nullptr); result->Add("this", this_->ToJson()); if (returnValue_) { ASSERT(returnValue_.value() != nullptr); result->Add("returnValue", returnValue_.value()->ToJson()); } return result; } std::unique_ptr SamplingHeapProfileSample::Create(const PtJson ¶ms) { std::string error; auto samplingHeapProfileSample = std::make_unique(); Result ret; int32_t size; ret = params.GetInt("size", &size); if (ret == Result::SUCCESS) { samplingHeapProfileSample->size_ = size; } else { error += "Unknown 'size';"; } int32_t nodeId; ret = params.GetInt("nodeId", &nodeId); if (ret == Result::SUCCESS) { samplingHeapProfileSample->nodeId_ = nodeId; } else { error += "Unknown 'nodeId';"; } int32_t ordinal; ret = params.GetInt("ordinal", &ordinal); if (ret == Result::SUCCESS) { samplingHeapProfileSample->ordinal_ = ordinal; } else { error += "Unknown 'ordinal';"; } if (!error.empty()) { LOG_DEBUGGER(ERROR) << "SamplingHeapProfileSample::Create " << error; return nullptr; } return samplingHeapProfileSample; } std::unique_ptr SamplingHeapProfileSample::ToJson() const { std::unique_ptr result = PtJson::CreateObject(); result->Add("size", size_); result->Add("nodeId", nodeId_); result->Add("ordinal", ordinal_); return result; } std::unique_ptr RuntimeCallFrame::Create(const PtJson ¶ms) { std::string error; auto runtimeCallFrame = std::make_unique(); Result ret; std::string functionName; ret = params.GetString("functionName", &functionName); if (ret == Result::SUCCESS) { runtimeCallFrame->functionName_ = std::move(functionName); } else { error += "Unknown 'functionName';"; } std::string scriptId; ret = params.GetString("scriptId", &scriptId); if (ret == Result::SUCCESS) { runtimeCallFrame->scriptId_ = std::move(scriptId); } else { error += "Unknown 'scriptId';"; } std::string url; ret = params.GetString("url", &url); if (ret == Result::SUCCESS) { runtimeCallFrame->url_ = std::move(url); } else { error += "Unknown 'url';"; } int32_t lineNumber; ret = params.GetInt("lineNumber", &lineNumber); if (ret == Result::SUCCESS) { runtimeCallFrame->lineNumber_ = lineNumber; } else { error += "Unknown 'lineNumber';"; } int32_t columnNumber; ret = params.GetInt("columnNumber", &columnNumber); if (ret == Result::SUCCESS) { runtimeCallFrame->columnNumber_ = columnNumber; } else { error += "Unknown 'columnNumber';"; } if (!error.empty()) { LOG_DEBUGGER(ERROR) << "RuntimeCallFrame::Create " << error; return nullptr; } return runtimeCallFrame; } std::unique_ptr RuntimeCallFrame::FromFrameInfo(const FrameInfo &cpuFrameInfo) { auto runtimeCallFrame = std::make_unique(); runtimeCallFrame->SetFunctionName(cpuFrameInfo.functionName); runtimeCallFrame->SetScriptId(std::to_string(cpuFrameInfo.scriptId)); runtimeCallFrame->SetColumnNumber(cpuFrameInfo.columnNumber); runtimeCallFrame->SetLineNumber(cpuFrameInfo.lineNumber); runtimeCallFrame->SetUrl(cpuFrameInfo.url); return runtimeCallFrame; } std::unique_ptr RuntimeCallFrame::ToJson() const { std::unique_ptr result = PtJson::CreateObject(); result->Add("functionName", functionName_.c_str()); result->Add("scriptId", scriptId_.c_str()); result->Add("url", url_.c_str()); result->Add("lineNumber", lineNumber_); result->Add("columnNumber", columnNumber_); return result; } std::unique_ptr SamplingHeapProfileNode::Create(const PtJson ¶ms) { std::string error; auto samplingHeapProfileNode = std::make_unique(); Result ret; std::unique_ptr callFrame; ret = params.GetObject("callFrame", &callFrame); if (ret == Result::SUCCESS) { std::unique_ptr runtimeCallFrame = RuntimeCallFrame::Create(*callFrame); if (runtimeCallFrame == nullptr) { error += "'callFrame' format invalid;"; } else { samplingHeapProfileNode->callFrame_ = std::move(runtimeCallFrame); } } else { error += "Unknown 'callFrame';"; } int32_t selfSize; ret = params.GetInt("selfSize", &selfSize); if (ret == Result::SUCCESS) { samplingHeapProfileNode->selfSize_ = selfSize; } else { error += "Unknown 'selfSize';"; } int32_t id; ret = params.GetInt("id", &id); if (ret == Result::SUCCESS) { samplingHeapProfileNode->id_ = id; } else { error += "Unknown 'id';"; } std::unique_ptr children; ret = params.GetArray("children", &children); if (ret == Result::SUCCESS) { int32_t len = children->GetSize(); for (int32_t i = 0; i < len; ++i) { std::unique_ptr arrayEle = children->Get(i); ASSERT(arrayEle != nullptr); std::unique_ptr node = SamplingHeapProfileNode::Create(*arrayEle); if (node == nullptr) { error += "'children' format invalid;"; } else { samplingHeapProfileNode->children_.emplace_back(std::move(node)); } } } else { error += "Unknown 'children';"; } if (!error.empty()) { LOG_DEBUGGER(ERROR) << "SamplingHeapProfileNode::Create " << error; return nullptr; } return samplingHeapProfileNode; } std::unique_ptr SamplingHeapProfileNode::ToJson() const { std::unique_ptr result = PtJson::CreateObject(); ASSERT(callFrame_ != nullptr); result->Add("callFrame", callFrame_->ToJson()); result->Add("selfSize", selfSize_); result->Add("id", id_); std::unique_ptr childrens = PtJson::CreateArray(); size_t len = children_.size(); for (size_t i = 0; i < len; i++) { ASSERT(children_[i] != nullptr); childrens->Push(children_[i]->ToJson()); } result->Add("children", childrens); return result; } std::unique_ptr SamplingHeapProfile::Create(const PtJson ¶ms) { std::string error; auto samplingHeapProfile = std::make_unique(); Result ret; std::unique_ptr head; ret = params.GetObject("head", &head); if (ret == Result::SUCCESS) { std::unique_ptr pHead = SamplingHeapProfileNode::Create(*head); if (pHead == nullptr) { error += "'sample' format invalid;"; } else { samplingHeapProfile->head_ = std::move(pHead); } } else { error += "Unknown 'head';"; } std::unique_ptr samples; ret = params.GetArray("samples", &samples); if (ret == Result::SUCCESS) { int32_t len = samples->GetSize(); for (int32_t i = 0; i < len; ++i) { std::unique_ptr arrayEle = samples->Get(i); ASSERT(arrayEle != nullptr); std::unique_ptr pSample = SamplingHeapProfileSample::Create(*arrayEle); if (pSample == nullptr) { error += "'sample' format invalid;"; } else { samplingHeapProfile->samples_.emplace_back(std::move(pSample)); } } } else { error += "Unknown 'samples';"; } if (!error.empty()) { LOG_DEBUGGER(ERROR) << "SamplingHeapProfile::Create " << error; return nullptr; } return samplingHeapProfile; } std::unique_ptr SamplingHeapProfile::ToJson() const { std::unique_ptr result = PtJson::CreateObject(); ASSERT(head_ != nullptr); result->Add("head", head_->ToJson()); std::unique_ptr samples = PtJson::CreateArray(); size_t len = samples_.size(); for (size_t i = 0; i < len; i++) { ASSERT(samples_[i] != nullptr); samples->Push(samples_[i]->ToJson()); } result->Add("samples", samples); return result; } std::unique_ptr PositionTickInfo::Create(const PtJson ¶ms) { std::string error; auto positionTickInfo = std::make_unique(); Result ret; int32_t line; ret = params.GetInt("line", &line); if (ret == Result::SUCCESS) { positionTickInfo->line_ = line; } else { error += "Unknown 'line';"; } int32_t ticks; ret = params.GetInt("ticks", &ticks); if (ret == Result::SUCCESS) { positionTickInfo->ticks_ = ticks; } else { error += "Unknown 'ticks';"; } if (!error.empty()) { LOG_DEBUGGER(ERROR) << "PositionTickInfo::Create " << error; return nullptr; } return positionTickInfo; } std::unique_ptr PositionTickInfo::ToJson() const { std::unique_ptr result = PtJson::CreateObject(); result->Add("line", line_); result->Add("ticks", ticks_); return result; } std::unique_ptr ProfileNode::Create(const PtJson ¶ms) { std::string error; auto profileNode = std::make_unique(); Result ret; int32_t id; ret = params.GetInt("id", &id); if (ret == Result::SUCCESS) { profileNode->id_ = id; } else { error += "Unknown 'id';"; } std::unique_ptr callFrame; ret = params.GetObject("callFrame", &callFrame); if (ret == Result::SUCCESS) { std::unique_ptr runtimeCallFrame = RuntimeCallFrame::Create(*callFrame); if (runtimeCallFrame == nullptr) { error += "'callFrame' format invalid;"; } else { profileNode->callFrame_ = std::move(runtimeCallFrame); } } else { error += "Unknown 'callFrame';"; } int32_t hitCount; ret = params.GetInt("hitCount", &hitCount); if (ret == Result::SUCCESS) { profileNode->hitCount_ = hitCount; } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'hitCount';"; } std::unique_ptr children; ret = params.GetArray("children", &children); if (ret == Result::SUCCESS) { int32_t childrenLen = children->GetSize(); for (int32_t i = 0; i < childrenLen; ++i) { int32_t pChildren = children->Get(i)->GetInt(); profileNode->children_.value().emplace_back(pChildren); } } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'children';"; } std::unique_ptr positionTicks; ret = params.GetArray("positionTicks", &positionTicks); if (ret == Result::SUCCESS) { int32_t positionTicksLen = positionTicks->GetSize(); for (int32_t i = 0; i < positionTicksLen; ++i) { std::unique_ptr arrayEle = positionTicks->Get(i); ASSERT(arrayEle != nullptr); std::unique_ptr tmpPositionTicks = PositionTickInfo::Create(*arrayEle); if (tmpPositionTicks == nullptr) { error += "'positionTicks' format invalid;"; } else { profileNode->positionTicks_.value().emplace_back(std::move(tmpPositionTicks)); } } } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'positionTicks';"; } std::string deoptReason; ret = params.GetString("deoptReason", &deoptReason); if (ret == Result::SUCCESS) { profileNode->deoptReason_ = std::move(deoptReason); } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'deoptReason';"; } if (!error.empty()) { LOG_DEBUGGER(ERROR) << "ProfileNode::Create " << error; return nullptr; } return profileNode; } std::unique_ptr ProfileNode::FromCpuProfileNode(const CpuProfileNode &cpuProfileNode) { auto profileNode = std::make_unique(); profileNode->SetId(cpuProfileNode.id); profileNode->SetHitCount(cpuProfileNode.hitCount); size_t childrenLen = cpuProfileNode.children.size(); std::vector tmpChildren; tmpChildren.reserve(childrenLen); for (size_t i = 0; i < childrenLen; ++i) { tmpChildren.push_back(cpuProfileNode.children[i]); } profileNode->SetChildren(tmpChildren); profileNode->SetCallFrame(RuntimeCallFrame::FromFrameInfo(cpuProfileNode.codeEntry)); return profileNode; } std::unique_ptr ProfileNode::ToJson() const { std::unique_ptr result = PtJson::CreateObject(); result->Add("id", id_); ASSERT(callFrame_ != nullptr); result->Add("callFrame", callFrame_->ToJson()); if (hitCount_) { result->Add("hitCount", hitCount_.value()); } if (children_) { std::unique_ptr childrens = PtJson::CreateArray(); size_t len = children_->size(); for (size_t i = 0; i < len; i++) { childrens->Push(children_.value()[i]); } result->Add("children", childrens); } if (positionTicks_) { std::unique_ptr positionTicks = PtJson::CreateArray(); size_t len = positionTicks_->size(); for (size_t i = 0; i < len; i++) { ASSERT(positionTicks_.value()[i] != nullptr); positionTicks->Push(positionTicks_.value()[i]->ToJson()); } result->Add("positionTicks", positionTicks); } if (deoptReason_) { result->Add("deoptReason", deoptReason_.value().c_str()); } return result; } std::unique_ptr Profile::Create(const PtJson ¶ms) { std::string error; auto profile = std::make_unique(); Result ret; std::unique_ptr nodes; ret = params.GetArray("nodes", &nodes); if (ret == Result::SUCCESS) { int32_t nodesLen = nodes->GetSize(); for (int32_t i = 0; i < nodesLen; ++i) { std::unique_ptr arrayEle = nodes->Get(i); ASSERT(arrayEle != nullptr); std::unique_ptr profileNode = ProfileNode::Create(*arrayEle); if (profileNode == nullptr) { error += "'nodes' format invalid;"; } else { profile->nodes_.emplace_back(std::move(profileNode)); } } } else { error += "Unknown 'nodes';"; } int64_t tid; ret = params.GetInt64("tid", &tid); if (ret == Result::SUCCESS) { profile->tid_ = tid; } else { error += "Unknown 'tid';"; } int64_t startTime; ret = params.GetInt64("startTime", &startTime); if (ret == Result::SUCCESS) { profile->startTime_ = startTime; } else { error += "Unknown 'startTime';"; } int64_t endTime; ret = params.GetInt64("endTime", &endTime); if (ret == Result::SUCCESS) { profile->endTime_ = endTime; } else { error += "Unknown 'endTime';"; } int64_t gcTime; ret = params.GetInt64("gcTime", &gcTime); if (ret == Result::SUCCESS) { profile->gcTime_ = gcTime; } else { error += "Unknown 'gcTime';"; } int64_t cInterpreterTime; ret = params.GetInt64("cInterpreterTime", &cInterpreterTime); if (ret == Result::SUCCESS) { profile->cInterpreterTime_ = cInterpreterTime; } else { error += "Unknown 'cInterpreterTime';"; } int64_t asmInterpreterTime; ret = params.GetInt64("asmInterpreterTime", &asmInterpreterTime); if (ret == Result::SUCCESS) { profile->asmInterpreterTime_ = asmInterpreterTime; } else { error += "Unknown 'asmInterpreterTime';"; } int64_t aotTime; ret = params.GetInt64("aotTime", &aotTime); if (ret == Result::SUCCESS) { profile->aotTime_ = aotTime; } else { error += "Unknown 'aotTime';"; } int64_t builtinTime; ret = params.GetInt64("builtinTime", &builtinTime); if (ret == Result::SUCCESS) { profile->builtinTime_ = builtinTime; } else { error += "Unknown 'builtinTime';"; } int64_t napiTime; ret = params.GetInt64("napiTime", &napiTime); if (ret == Result::SUCCESS) { profile->napiTime_ = napiTime; } else { error += "Unknown 'napiTime';"; } int64_t arkuiEngineTime; ret = params.GetInt64("arkuiEngineTime", &arkuiEngineTime); if (ret == Result::SUCCESS) { profile->arkuiEngineTime_ = arkuiEngineTime; } else { error += "Unknown 'arkuiEngineTime';"; } int64_t runtimeTime; ret = params.GetInt64("runtimeTime", &runtimeTime); if (ret == Result::SUCCESS) { profile->runtimeTime_ = runtimeTime; } else { error += "Unknown 'runtimeTime';"; } int64_t otherTime; ret = params.GetInt64("otherTime", &otherTime); if (ret == Result::SUCCESS) { profile->otherTime_ = otherTime; } else { error += "Unknown 'otherTime';"; } std::unique_ptr samples; ret = params.GetArray("samples", &samples); if (ret == Result::SUCCESS) { int32_t samplesLen = samples->GetSize(); for (int32_t i = 0; i < samplesLen; ++i) { int32_t pSamples = samples->Get(i)->GetInt(); profile->samples_.value().emplace_back(pSamples); } } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'samples';"; } std::unique_ptr timeDeltas; ret = params.GetArray("timeDeltas", &timeDeltas); if (ret == Result::SUCCESS) { int32_t timeDeltasLen = timeDeltas->GetSize(); for (int32_t i = 0; i < timeDeltasLen; ++i) { int32_t pTimeDeltas = timeDeltas->Get(i)->GetInt(); profile->timeDeltas_.value().emplace_back(pTimeDeltas); } } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'timeDeltas';"; } if (!error.empty()) { LOG_DEBUGGER(ERROR) << "Profile::Create " << error; return nullptr; } return profile; } std::unique_ptr Profile::FromProfileInfo(const ProfileInfo &profileInfo) { auto profile = std::make_unique(); profile->SetTid(static_cast(profileInfo.tid)); profile->SetStartTime(static_cast(profileInfo.startTime)); profile->SetEndTime(static_cast(profileInfo.stopTime)); profile->SetGcTime(static_cast(profileInfo.gcTime)); profile->SetCInterpreterTime(static_cast(profileInfo.cInterpreterTime)); profile->SetAsmInterpreterTime(static_cast(profileInfo.asmInterpreterTime)); profile->SetAotTime(static_cast(profileInfo.aotTime)); profile->SetBuiltinTime(static_cast(profileInfo.builtinTime)); profile->SetNapiTime(static_cast(profileInfo.napiTime)); profile->SetArkuiEngineTime(static_cast(profileInfo.arkuiEngineTime)); profile->SetRuntimeTime(static_cast(profileInfo.runtimeTime)); profile->SetOtherTime(static_cast(profileInfo.otherTime)); size_t samplesLen = profileInfo.samples.size(); std::vector tmpSamples; tmpSamples.reserve(samplesLen); for (size_t i = 0; i < samplesLen; ++i) { tmpSamples.push_back(profileInfo.samples[i]); } profile->SetSamples(tmpSamples); size_t timeDeltasLen = profileInfo.timeDeltas.size(); std::vector tmpTimeDeltas; tmpTimeDeltas.reserve(timeDeltasLen); for (size_t i = 0; i < timeDeltasLen; ++i) { tmpTimeDeltas.push_back(profileInfo.timeDeltas[i]); } profile->SetTimeDeltas(tmpTimeDeltas); std::vector> profileNode; size_t nodesLen = profileInfo.nodeCount; for (size_t i = 0; i < nodesLen; ++i) { const auto &cpuProfileNode = profileInfo.nodes[i]; profileNode.push_back(ProfileNode::FromCpuProfileNode(cpuProfileNode)); } profile->SetNodes(std::move(profileNode)); return profile; } std::unique_ptr Profile::ToJson() const { std::unique_ptr result = PtJson::CreateObject(); result->Add("tid", tid_); result->Add("startTime", startTime_); result->Add("endTime", endTime_); result->Add("gcTime", gcTime_); result->Add("cInterpreterTime", cInterpreterTime_); result->Add("asmInterpreterTime", asmInterpreterTime_); result->Add("aotTime", aotTime_); result->Add("builtinTime", builtinTime_); result->Add("napiTime", napiTime_); result->Add("arkuiEngineTime", arkuiEngineTime_); result->Add("runtimeTime", runtimeTime_); result->Add("otherTime", otherTime_); std::unique_ptr nodes = PtJson::CreateArray(); size_t nodesLen = nodes_.size(); for (size_t i = 0; i < nodesLen; i++) { ASSERT(nodes_[i] != nullptr); nodes->Push(nodes_[i]->ToJson()); } result->Add("nodes", nodes); if (samples_) { std::unique_ptr samples = PtJson::CreateArray(); size_t samplesLen = samples_->size(); for (size_t i = 0; i < samplesLen; i++) { samples->Push(samples_.value()[i]); } result->Add("samples", samples); } if (timeDeltas_) { std::unique_ptr timeDeltas = PtJson::CreateArray(); size_t timeDeltasLen = timeDeltas_->size(); for (size_t i = 0; i < timeDeltasLen; i++) { timeDeltas->Push(timeDeltas_.value()[i]); } result->Add("timeDeltas", timeDeltas); } return result; } std::unique_ptr Coverage::Create(const PtJson ¶ms) { std::string error; auto coverage = std::make_unique(); Result ret; int32_t startOffset; ret = params.GetInt("startOffset", &startOffset); if (ret == Result::SUCCESS) { coverage->startOffset_ = startOffset; } else { error += "Unknown 'startOffset';"; } int32_t endOffset; ret = params.GetInt("endOffset", &endOffset); if (ret == Result::SUCCESS) { coverage->endOffset_ = endOffset; } else { error += "Unknown 'endOffset';"; } int32_t count; ret = params.GetInt("count", &count); if (ret == Result::SUCCESS) { coverage->count_ = count; } else { error += "Unknown 'count';"; } if (!error.empty()) { LOG_DEBUGGER(ERROR) << "Coverage::Create " << error; return nullptr; } return coverage; } std::unique_ptr Coverage::ToJson() const { std::unique_ptr result = PtJson::CreateObject(); result->Add("startOffset", startOffset_); result->Add("endOffset", endOffset_); result->Add("count", count_); return result; } std::unique_ptr FunctionCoverage::Create(const PtJson ¶ms) { std::string error; auto functionCoverage = std::make_unique(); Result ret; std::string functionName; ret = params.GetString("functionName", &functionName); if (ret == Result::SUCCESS) { functionCoverage->functionName_ = std::move(functionName); } else { error += "Unknown 'functionName';"; } std::unique_ptr ranges; ret = params.GetArray("ranges", &ranges); if (ret == Result::SUCCESS) { int32_t len = ranges->GetSize(); for (int32_t i = 0; i < len; ++i) { std::unique_ptr arrayEle = ranges->Get(i); ASSERT(arrayEle != nullptr); std::unique_ptr pRanges = Coverage::Create(*arrayEle); if (pRanges == nullptr) { error += "'ranges' format invalid;"; } else { functionCoverage->ranges_.emplace_back(std::move(pRanges)); } } } else { error += "Unknown 'ranges';"; } bool isBlockCoverage = false; ret = params.GetBool("isBlockCoverage", &isBlockCoverage); if (ret == Result::SUCCESS) { functionCoverage->isBlockCoverage_ = isBlockCoverage; } else { error += "Unknown 'isBlockCoverage';"; } if (!error.empty()) { LOG_DEBUGGER(ERROR) << "FunctionCoverage::Create " << error; return nullptr; } return functionCoverage; } std::unique_ptr FunctionCoverage::ToJson() const { std::unique_ptr result = PtJson::CreateObject(); result->Add("functionName", functionName_.c_str()); std::unique_ptr ranges = PtJson::CreateArray(); size_t len = ranges_.size(); for (size_t i = 0; i < len; i++) { ASSERT(ranges_[i] != nullptr); ranges->Push(ranges_[i]->ToJson()); } result->Add("ranges", ranges); result->Add("isBlockCoverage", isBlockCoverage_); return result; } std::unique_ptr ScriptCoverage::Create(const PtJson ¶ms) { std::string error; auto scriptCoverage = std::make_unique(); Result ret; std::string scriptId; ret = params.GetString("scriptId", &scriptId); if (ret == Result::SUCCESS) { scriptCoverage->scriptId_ = std::move(scriptId); } else { error += "Unknown 'scriptId';"; } std::string url; ret = params.GetString("url", &url); if (ret == Result::SUCCESS) { scriptCoverage->url_ = std::move(url); } else { error += "Unknown 'url';"; } std::unique_ptr functions; ret = params.GetArray("functions", &functions); if (ret == Result::SUCCESS) { int32_t len = functions->GetSize(); for (int32_t i = 0; i < len; ++i) { std::unique_ptr arrayEle = functions->Get(i); ASSERT(arrayEle != nullptr); std::unique_ptr pFunctions = FunctionCoverage::Create(*arrayEle); if (pFunctions == nullptr) { error += "'functions' format invalid;"; } else { scriptCoverage->functions_.emplace_back(std::move(pFunctions)); } } } else { error += "Unknown 'functions';"; } if (!error.empty()) { LOG_DEBUGGER(ERROR) << "ScriptCoverage::Create " << error; return nullptr; } return scriptCoverage; } std::unique_ptr ScriptCoverage::ToJson() const { std::unique_ptr result = PtJson::CreateObject(); result->Add("scriptId", scriptId_.c_str()); result->Add("url", url_.c_str()); std::unique_ptr functions = PtJson::CreateArray(); size_t len = functions_.size(); for (size_t i = 0; i < len; i++) { ASSERT(functions_[i] != nullptr); functions->Push(functions_[i]->ToJson()); } result->Add("functions", functions); return result; } std::unique_ptr TypeObject::Create(const PtJson ¶ms) { std::string error; auto typeObject = std::make_unique(); Result ret; std::string name; ret = params.GetString("name", &name); if (ret == Result::SUCCESS) { typeObject->name_ = std::move(name); } else { error += "Unknown 'name';"; } if (!error.empty()) { LOG_DEBUGGER(ERROR) << "TypeObject::Create " << error; return nullptr; } return typeObject; } std::unique_ptr TypeObject::ToJson() const { std::unique_ptr result = PtJson::CreateObject(); result->Add("name", name_.c_str()); return result; } std::unique_ptr TypeProfileEntry::Create(const PtJson ¶ms) { std::string error; auto typeProfileEntry = std::make_unique(); Result ret; int32_t offset; ret = params.GetInt("offset", &offset); if (ret == Result::SUCCESS) { typeProfileEntry->offset_ = offset; } else { error += "Unknown 'offset';"; } std::unique_ptr types; ret = params.GetArray("types", &types); if (ret == Result::SUCCESS) { int32_t len = types->GetSize(); for (int32_t i = 0; i < len; ++i) { std::unique_ptr arrayEle = types->Get(i); ASSERT(arrayEle != nullptr); std::unique_ptr pTypes = TypeObject::Create(*arrayEle); if (pTypes == nullptr) { error += "'types' format invalid;"; } else { typeProfileEntry->types_.emplace_back(std::move(pTypes)); } } } else { error += "Unknown 'types';"; } if (!error.empty()) { LOG_DEBUGGER(ERROR) << "TypeProfileEntry::Create " << error; return nullptr; } return typeProfileEntry; } std::unique_ptr TypeProfileEntry::ToJson() const { std::unique_ptr result = PtJson::CreateObject(); result->Add("offset", offset_); std::unique_ptr types = PtJson::CreateArray(); size_t len = types_.size(); for (size_t i = 0; i < len; i++) { ASSERT(types_[i] != nullptr); types->Push(types_[i]->ToJson()); } result->Add("types", types); return result; } std::unique_ptr ScriptTypeProfile::Create(const PtJson ¶ms) { std::string error; auto scriptTypeProfile = std::make_unique(); Result ret; std::string scriptId; ret = params.GetString("scriptId", &scriptId); if (ret == Result::SUCCESS) { scriptTypeProfile->scriptId_ = std::move(scriptId); } else { error += "Unknown 'scriptId';"; } std::string url; ret = params.GetString("url", &url); if (ret == Result::SUCCESS) { scriptTypeProfile->url_ = std::move(url); } else { error += "Unknown 'url';"; } std::unique_ptr entries; ret = params.GetArray("entries", &entries); if (ret == Result::SUCCESS) { int32_t len = entries->GetSize(); for (int32_t i = 0; i < len; ++i) { std::unique_ptr arrayEle = entries->Get(i); ASSERT(arrayEle != nullptr); std::unique_ptr pEntries = TypeProfileEntry::Create(*arrayEle); if (pEntries == nullptr) { error += "'entries' format invalid;"; } else { scriptTypeProfile->entries_.emplace_back(std::move(pEntries)); } } } else { error += "Unknown 'entries';"; } if (!error.empty()) { LOG_DEBUGGER(ERROR) << "ScriptTypeProfile::Create " << error; return nullptr; } return scriptTypeProfile; } std::unique_ptr ScriptTypeProfile::ToJson() const { std::unique_ptr result = PtJson::CreateObject(); result->Add("scriptId", scriptId_.c_str()); result->Add("url", url_.c_str()); std::unique_ptr entries = PtJson::CreateArray(); size_t len = entries_.size(); for (size_t i = 0; i < len; i++) { ASSERT(entries_[i] != nullptr); entries->Push(entries_[i]->ToJson()); } result->Add("entries", entries); return result; } std::unique_ptr TraceConfig::Create(const PtJson ¶ms) { std::string error; auto traceConfig = std::make_unique(); Result ret; std::string recordMode; ret = params.GetString("recordMode", &recordMode); if (ret == Result::SUCCESS) { if (TraceConfig::RecordModeValues::Valid(recordMode)) { traceConfig->recordMode_ = std::move(recordMode); } else { error += "'recordMode' is invalid;"; } } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'recordMode';"; } bool enableSampling = false; ret = params.GetBool("enableSampling", &enableSampling); if (ret == Result::SUCCESS) { traceConfig->enableSampling_ = enableSampling; } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'enableSampling';"; } bool enableSystrace = false; ret = params.GetBool("enableSystrace", &enableSystrace); if (ret == Result::SUCCESS) { traceConfig->enableSystrace_ = enableSystrace; } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'enableSystrace';"; } bool enableArgumentFilter = false; ret = params.GetBool("enableArgumentFilter", &enableArgumentFilter); if (ret == Result::SUCCESS) { traceConfig->enableArgumentFilter_ = enableArgumentFilter; } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'enableArgumentFilter';"; } std::unique_ptr includedCategories; ret = params.GetArray("includedCategories", &includedCategories); if (ret == Result::SUCCESS) { int32_t includedCategoriesLen = includedCategories->GetSize(); for (int32_t i = 0; i < includedCategoriesLen; ++i) { std::string pIncludedCategories = includedCategories->Get(i)->GetString(); traceConfig->includedCategories_.value().emplace_back(pIncludedCategories); } } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'includedCategories';"; } std::unique_ptr excludedCategories; ret = params.GetArray("excludedCategories", &excludedCategories); if (ret == Result::SUCCESS) { int32_t excludedCategoriesLen = excludedCategories->GetSize(); for (int32_t i = 0; i < excludedCategoriesLen; ++i) { std::string pExcludedCategories = excludedCategories->Get(i)->GetString(); traceConfig->excludedCategories_.value().emplace_back(pExcludedCategories); } } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'excludedCategories';"; } std::unique_ptr syntheticDelays; ret = params.GetArray("syntheticDelays", &syntheticDelays); if (ret == Result::SUCCESS) { int32_t syntheticDelaysLen = includedCategories->GetSize(); for (int32_t i = 0; i < syntheticDelaysLen; ++i) { std::string pSyntheticDelays = syntheticDelays->Get(i)->GetString(); traceConfig->syntheticDelays_.value().emplace_back(pSyntheticDelays); } } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'syntheticDelays';"; } std::unique_ptr memoryDumpConfig; ret = params.GetObject("memoryDumpConfig", &memoryDumpConfig); if (ret == Result::SUCCESS) { std::unique_ptr tmpMemory = std::move(memoryDumpConfig); if (tmpMemory == nullptr) { error += "'memoryDumpConfig' format error;"; } else { traceConfig->memoryDumpConfig_ = std::move(tmpMemory); } } else if (ret == Result::TYPE_ERROR) { error += "Unknown 'memoryDumpConfig';"; } if (!error.empty()) { LOG_DEBUGGER(ERROR) << "TraceConfig::Create " << error; return nullptr; } return traceConfig; } std::unique_ptr TraceConfig::ToJson() const { std::unique_ptr result = PtJson::CreateObject(); if (recordMode_) { result->Add("recordMode", recordMode_.value().c_str()); } if (enableSampling_) { result->Add("enableSampling", enableSampling_.value()); } if (enableSystrace_) { result->Add("enableSystrace", enableSystrace_.value()); } if (enableArgumentFilter_) { result->Add("enableArgumentFilter", enableArgumentFilter_.value()); } if (includedCategories_) { std::unique_ptr includedCategories = PtJson::CreateArray(); size_t includedCategoriesLen = includedCategories_->size(); for (size_t i = 0; i < includedCategoriesLen; i++) { includedCategories->Push(includedCategories_.value()[i].c_str()); } result->Add("includedCategories", includedCategories); } if (excludedCategories_) { std::unique_ptr excludedCategories = PtJson::CreateArray(); size_t excludedCategoriesLen = excludedCategories_->size(); for (size_t i = 0; i < excludedCategoriesLen; i++) { excludedCategories->Push(excludedCategories_.value()[i].c_str()); } result->Add("excludedCategories", excludedCategories); } if (syntheticDelays_) { std::unique_ptr syntheticDelays = PtJson::CreateArray(); size_t syntheticDelaysLen = syntheticDelays_->size(); for (size_t i = 0; i < syntheticDelaysLen; i++) { syntheticDelays->Push(syntheticDelays_.value()[i].c_str()); } result->Add("syntheticDelays", syntheticDelays); } if (memoryDumpConfig_) { result->Add("functionLocation", memoryDumpConfig_.value()); } return result; } } // namespace panda::ecmascript::tooling