11cb0ef41Sopenharmony_ci// Copyright 2018 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#include "src/inspector/value-mirror.h" 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ci#include <algorithm> 81cb0ef41Sopenharmony_ci#include <cmath> 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci#include "include/v8-container.h" 111cb0ef41Sopenharmony_ci#include "include/v8-date.h" 121cb0ef41Sopenharmony_ci#include "include/v8-function.h" 131cb0ef41Sopenharmony_ci#include "include/v8-microtask-queue.h" 141cb0ef41Sopenharmony_ci#include "include/v8-primitive-object.h" 151cb0ef41Sopenharmony_ci#include "include/v8-proxy.h" 161cb0ef41Sopenharmony_ci#include "include/v8-regexp.h" 171cb0ef41Sopenharmony_ci#include "include/v8-typed-array.h" 181cb0ef41Sopenharmony_ci#include "include/v8-wasm.h" 191cb0ef41Sopenharmony_ci#include "src/base/optional.h" 201cb0ef41Sopenharmony_ci#include "src/debug/debug-interface.h" 211cb0ef41Sopenharmony_ci#include "src/inspector/v8-debugger.h" 221cb0ef41Sopenharmony_ci#include "src/inspector/v8-inspector-impl.h" 231cb0ef41Sopenharmony_ci#include "src/inspector/v8-value-utils.h" 241cb0ef41Sopenharmony_ci#include "src/inspector/v8-webdriver-serializer.h" 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_cinamespace v8_inspector { 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ciusing protocol::Response; 291cb0ef41Sopenharmony_ciusing protocol::Runtime::EntryPreview; 301cb0ef41Sopenharmony_ciusing protocol::Runtime::ObjectPreview; 311cb0ef41Sopenharmony_ciusing protocol::Runtime::PropertyPreview; 321cb0ef41Sopenharmony_ciusing protocol::Runtime::RemoteObject; 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ciResponse toProtocolValue(v8::Local<v8::Context> context, 351cb0ef41Sopenharmony_ci v8::Local<v8::Value> value, int maxDepth, 361cb0ef41Sopenharmony_ci std::unique_ptr<protocol::Value>* result); 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ciResponse arrayToProtocolValue(v8::Local<v8::Context> context, 391cb0ef41Sopenharmony_ci v8::Local<v8::Array> array, int maxDepth, 401cb0ef41Sopenharmony_ci std::unique_ptr<protocol::ListValue>* result) { 411cb0ef41Sopenharmony_ci std::unique_ptr<protocol::ListValue> inspectorArray = 421cb0ef41Sopenharmony_ci protocol::ListValue::create(); 431cb0ef41Sopenharmony_ci uint32_t length = array->Length(); 441cb0ef41Sopenharmony_ci for (uint32_t i = 0; i < length; i++) { 451cb0ef41Sopenharmony_ci v8::Local<v8::Value> value; 461cb0ef41Sopenharmony_ci if (!array->Get(context, i).ToLocal(&value)) 471cb0ef41Sopenharmony_ci return Response::InternalError(); 481cb0ef41Sopenharmony_ci std::unique_ptr<protocol::Value> element; 491cb0ef41Sopenharmony_ci Response response = toProtocolValue(context, value, maxDepth - 1, &element); 501cb0ef41Sopenharmony_ci if (!response.IsSuccess()) return response; 511cb0ef41Sopenharmony_ci inspectorArray->pushValue(std::move(element)); 521cb0ef41Sopenharmony_ci } 531cb0ef41Sopenharmony_ci *result = std::move(inspectorArray); 541cb0ef41Sopenharmony_ci return Response::Success(); 551cb0ef41Sopenharmony_ci} 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_ciResponse objectToProtocolValue( 581cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, v8::Local<v8::Object> object, int maxDepth, 591cb0ef41Sopenharmony_ci std::unique_ptr<protocol::DictionaryValue>* result) { 601cb0ef41Sopenharmony_ci std::unique_ptr<protocol::DictionaryValue> jsonObject = 611cb0ef41Sopenharmony_ci protocol::DictionaryValue::create(); 621cb0ef41Sopenharmony_ci v8::Local<v8::Array> propertyNames; 631cb0ef41Sopenharmony_ci if (!object->GetOwnPropertyNames(context).ToLocal(&propertyNames)) 641cb0ef41Sopenharmony_ci return Response::InternalError(); 651cb0ef41Sopenharmony_ci uint32_t length = propertyNames->Length(); 661cb0ef41Sopenharmony_ci for (uint32_t i = 0; i < length; i++) { 671cb0ef41Sopenharmony_ci v8::Local<v8::Value> name; 681cb0ef41Sopenharmony_ci if (!propertyNames->Get(context, i).ToLocal(&name)) 691cb0ef41Sopenharmony_ci return Response::InternalError(); 701cb0ef41Sopenharmony_ci if (name->IsString()) { 711cb0ef41Sopenharmony_ci v8::Maybe<bool> hasRealNamedProperty = 721cb0ef41Sopenharmony_ci object->HasRealNamedProperty(context, name.As<v8::String>()); 731cb0ef41Sopenharmony_ci // Don't access properties with interceptors. 741cb0ef41Sopenharmony_ci if (hasRealNamedProperty.IsNothing() || !hasRealNamedProperty.FromJust()) 751cb0ef41Sopenharmony_ci continue; 761cb0ef41Sopenharmony_ci } 771cb0ef41Sopenharmony_ci v8::Local<v8::String> propertyName; 781cb0ef41Sopenharmony_ci if (!name->ToString(context).ToLocal(&propertyName)) continue; 791cb0ef41Sopenharmony_ci v8::Local<v8::Value> property; 801cb0ef41Sopenharmony_ci if (!object->Get(context, name).ToLocal(&property)) 811cb0ef41Sopenharmony_ci return Response::InternalError(); 821cb0ef41Sopenharmony_ci if (property->IsUndefined()) continue; 831cb0ef41Sopenharmony_ci std::unique_ptr<protocol::Value> propertyValue; 841cb0ef41Sopenharmony_ci Response response = 851cb0ef41Sopenharmony_ci toProtocolValue(context, property, maxDepth - 1, &propertyValue); 861cb0ef41Sopenharmony_ci if (!response.IsSuccess()) return response; 871cb0ef41Sopenharmony_ci jsonObject->setValue(toProtocolString(context->GetIsolate(), propertyName), 881cb0ef41Sopenharmony_ci std::move(propertyValue)); 891cb0ef41Sopenharmony_ci } 901cb0ef41Sopenharmony_ci *result = std::move(jsonObject); 911cb0ef41Sopenharmony_ci return Response::Success(); 921cb0ef41Sopenharmony_ci} 931cb0ef41Sopenharmony_ci 941cb0ef41Sopenharmony_cistd::unique_ptr<protocol::FundamentalValue> toProtocolValue( 951cb0ef41Sopenharmony_ci double doubleValue) { 961cb0ef41Sopenharmony_ci if (doubleValue >= std::numeric_limits<int>::min() && 971cb0ef41Sopenharmony_ci doubleValue <= std::numeric_limits<int>::max() && 981cb0ef41Sopenharmony_ci bit_cast<int64_t>(doubleValue) != bit_cast<int64_t>(-0.0)) { 991cb0ef41Sopenharmony_ci int intValue = static_cast<int>(doubleValue); 1001cb0ef41Sopenharmony_ci if (intValue == doubleValue) { 1011cb0ef41Sopenharmony_ci return protocol::FundamentalValue::create(intValue); 1021cb0ef41Sopenharmony_ci } 1031cb0ef41Sopenharmony_ci } 1041cb0ef41Sopenharmony_ci return protocol::FundamentalValue::create(doubleValue); 1051cb0ef41Sopenharmony_ci} 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_ciResponse toProtocolValue(v8::Local<v8::Context> context, 1081cb0ef41Sopenharmony_ci v8::Local<v8::Value> value, int maxDepth, 1091cb0ef41Sopenharmony_ci std::unique_ptr<protocol::Value>* result) { 1101cb0ef41Sopenharmony_ci if (maxDepth <= 0) 1111cb0ef41Sopenharmony_ci return Response::ServerError("Object reference chain is too long"); 1121cb0ef41Sopenharmony_ci 1131cb0ef41Sopenharmony_ci if (value->IsNull() || value->IsUndefined()) { 1141cb0ef41Sopenharmony_ci *result = protocol::Value::null(); 1151cb0ef41Sopenharmony_ci return Response::Success(); 1161cb0ef41Sopenharmony_ci } 1171cb0ef41Sopenharmony_ci if (value->IsBoolean()) { 1181cb0ef41Sopenharmony_ci *result = 1191cb0ef41Sopenharmony_ci protocol::FundamentalValue::create(value.As<v8::Boolean>()->Value()); 1201cb0ef41Sopenharmony_ci return Response::Success(); 1211cb0ef41Sopenharmony_ci } 1221cb0ef41Sopenharmony_ci if (value->IsNumber()) { 1231cb0ef41Sopenharmony_ci double doubleValue = value.As<v8::Number>()->Value(); 1241cb0ef41Sopenharmony_ci *result = toProtocolValue(doubleValue); 1251cb0ef41Sopenharmony_ci return Response::Success(); 1261cb0ef41Sopenharmony_ci } 1271cb0ef41Sopenharmony_ci if (value->IsString()) { 1281cb0ef41Sopenharmony_ci *result = protocol::StringValue::create( 1291cb0ef41Sopenharmony_ci toProtocolString(context->GetIsolate(), value.As<v8::String>())); 1301cb0ef41Sopenharmony_ci return Response::Success(); 1311cb0ef41Sopenharmony_ci } 1321cb0ef41Sopenharmony_ci if (value->IsArray()) { 1331cb0ef41Sopenharmony_ci v8::Local<v8::Array> array = value.As<v8::Array>(); 1341cb0ef41Sopenharmony_ci std::unique_ptr<protocol::ListValue> list_result; 1351cb0ef41Sopenharmony_ci auto response = 1361cb0ef41Sopenharmony_ci arrayToProtocolValue(context, array, maxDepth, &list_result); 1371cb0ef41Sopenharmony_ci *result = std::move(list_result); 1381cb0ef41Sopenharmony_ci return response; 1391cb0ef41Sopenharmony_ci } 1401cb0ef41Sopenharmony_ci if (value->IsObject()) { 1411cb0ef41Sopenharmony_ci v8::Local<v8::Object> object = value.As<v8::Object>(); 1421cb0ef41Sopenharmony_ci std::unique_ptr<protocol::DictionaryValue> dict_result; 1431cb0ef41Sopenharmony_ci auto response = 1441cb0ef41Sopenharmony_ci objectToProtocolValue(context, object, maxDepth, &dict_result); 1451cb0ef41Sopenharmony_ci *result = std::move(dict_result); 1461cb0ef41Sopenharmony_ci return response; 1471cb0ef41Sopenharmony_ci } 1481cb0ef41Sopenharmony_ci 1491cb0ef41Sopenharmony_ci return Response::ServerError("Object couldn't be returned by value"); 1501cb0ef41Sopenharmony_ci} 1511cb0ef41Sopenharmony_ci 1521cb0ef41Sopenharmony_ciResponse toProtocolValue(v8::Local<v8::Context> context, 1531cb0ef41Sopenharmony_ci v8::Local<v8::Value> value, 1541cb0ef41Sopenharmony_ci std::unique_ptr<protocol::Value>* result) { 1551cb0ef41Sopenharmony_ci if (value->IsUndefined()) return Response::Success(); 1561cb0ef41Sopenharmony_ci#if defined(V8_USE_ADDRESS_SANITIZER) && V8_OS_DARWIN 1571cb0ef41Sopenharmony_ci // For whatever reason, ASan on MacOS has bigger stack frames. 1581cb0ef41Sopenharmony_ci static const int kMaxDepth = 900; 1591cb0ef41Sopenharmony_ci#else 1601cb0ef41Sopenharmony_ci static const int kMaxDepth = 1000; 1611cb0ef41Sopenharmony_ci#endif 1621cb0ef41Sopenharmony_ci return toProtocolValue(context, value, kMaxDepth, result); 1631cb0ef41Sopenharmony_ci} 1641cb0ef41Sopenharmony_ci 1651cb0ef41Sopenharmony_cinamespace { 1661cb0ef41Sopenharmony_ci 1671cb0ef41Sopenharmony_ci// WebAssembly memory is organized in pages of size 64KiB. 1681cb0ef41Sopenharmony_ciconst size_t kWasmPageSize = 64 * 1024; 1691cb0ef41Sopenharmony_ci 1701cb0ef41Sopenharmony_ciV8InspectorClient* clientFor(v8::Local<v8::Context> context) { 1711cb0ef41Sopenharmony_ci return static_cast<V8InspectorImpl*>( 1721cb0ef41Sopenharmony_ci v8::debug::GetInspector(context->GetIsolate())) 1731cb0ef41Sopenharmony_ci ->client(); 1741cb0ef41Sopenharmony_ci} 1751cb0ef41Sopenharmony_ci 1761cb0ef41Sopenharmony_ciV8InternalValueType v8InternalValueTypeFrom(v8::Local<v8::Context> context, 1771cb0ef41Sopenharmony_ci v8::Local<v8::Value> value) { 1781cb0ef41Sopenharmony_ci if (!value->IsObject()) return V8InternalValueType::kNone; 1791cb0ef41Sopenharmony_ci V8InspectorImpl* inspector = static_cast<V8InspectorImpl*>( 1801cb0ef41Sopenharmony_ci v8::debug::GetInspector(context->GetIsolate())); 1811cb0ef41Sopenharmony_ci int contextId = InspectedContext::contextId(context); 1821cb0ef41Sopenharmony_ci InspectedContext* inspectedContext = inspector->getContext(contextId); 1831cb0ef41Sopenharmony_ci if (!inspectedContext) return V8InternalValueType::kNone; 1841cb0ef41Sopenharmony_ci return inspectedContext->getInternalType(value.As<v8::Object>()); 1851cb0ef41Sopenharmony_ci} 1861cb0ef41Sopenharmony_ci 1871cb0ef41Sopenharmony_cienum AbbreviateMode { kMiddle, kEnd }; 1881cb0ef41Sopenharmony_ci 1891cb0ef41Sopenharmony_ciString16 abbreviateString(const String16& value, AbbreviateMode mode) { 1901cb0ef41Sopenharmony_ci const size_t maxLength = 100; 1911cb0ef41Sopenharmony_ci if (value.length() <= maxLength) return value; 1921cb0ef41Sopenharmony_ci UChar ellipsis = static_cast<UChar>(0x2026); 1931cb0ef41Sopenharmony_ci if (mode == kMiddle) { 1941cb0ef41Sopenharmony_ci return String16::concat( 1951cb0ef41Sopenharmony_ci value.substring(0, maxLength / 2), String16(&ellipsis, 1), 1961cb0ef41Sopenharmony_ci value.substring(value.length() - maxLength / 2 + 1)); 1971cb0ef41Sopenharmony_ci } 1981cb0ef41Sopenharmony_ci return String16::concat(value.substring(0, maxLength - 1), ellipsis); 1991cb0ef41Sopenharmony_ci} 2001cb0ef41Sopenharmony_ci 2011cb0ef41Sopenharmony_ciString16 descriptionForSymbol(v8::Local<v8::Context> context, 2021cb0ef41Sopenharmony_ci v8::Local<v8::Symbol> symbol) { 2031cb0ef41Sopenharmony_ci v8::Isolate* isolate = context->GetIsolate(); 2041cb0ef41Sopenharmony_ci return String16::concat( 2051cb0ef41Sopenharmony_ci "Symbol(", 2061cb0ef41Sopenharmony_ci toProtocolStringWithTypeCheck(isolate, symbol->Description(isolate)), 2071cb0ef41Sopenharmony_ci ")"); 2081cb0ef41Sopenharmony_ci} 2091cb0ef41Sopenharmony_ci 2101cb0ef41Sopenharmony_ciString16 descriptionForBigInt(v8::Local<v8::Context> context, 2111cb0ef41Sopenharmony_ci v8::Local<v8::BigInt> value) { 2121cb0ef41Sopenharmony_ci v8::Isolate* isolate = context->GetIsolate(); 2131cb0ef41Sopenharmony_ci v8::Local<v8::String> description = 2141cb0ef41Sopenharmony_ci v8::debug::GetBigIntDescription(isolate, value); 2151cb0ef41Sopenharmony_ci return toProtocolString(isolate, description); 2161cb0ef41Sopenharmony_ci} 2171cb0ef41Sopenharmony_ci 2181cb0ef41Sopenharmony_ciString16 descriptionForPrimitiveType(v8::Local<v8::Context> context, 2191cb0ef41Sopenharmony_ci v8::Local<v8::Value> value) { 2201cb0ef41Sopenharmony_ci if (value->IsUndefined()) return RemoteObject::TypeEnum::Undefined; 2211cb0ef41Sopenharmony_ci if (value->IsNull()) return RemoteObject::SubtypeEnum::Null; 2221cb0ef41Sopenharmony_ci if (value->IsBoolean()) { 2231cb0ef41Sopenharmony_ci return value.As<v8::Boolean>()->Value() ? "true" : "false"; 2241cb0ef41Sopenharmony_ci } 2251cb0ef41Sopenharmony_ci if (value->IsString()) { 2261cb0ef41Sopenharmony_ci return toProtocolString(context->GetIsolate(), value.As<v8::String>()); 2271cb0ef41Sopenharmony_ci } 2281cb0ef41Sopenharmony_ci UNREACHABLE(); 2291cb0ef41Sopenharmony_ci} 2301cb0ef41Sopenharmony_ci 2311cb0ef41Sopenharmony_ciString16 descriptionForRegExp(v8::Isolate* isolate, 2321cb0ef41Sopenharmony_ci v8::Local<v8::RegExp> value) { 2331cb0ef41Sopenharmony_ci String16Builder description; 2341cb0ef41Sopenharmony_ci description.append('/'); 2351cb0ef41Sopenharmony_ci description.append(toProtocolString(isolate, value->GetSource())); 2361cb0ef41Sopenharmony_ci description.append('/'); 2371cb0ef41Sopenharmony_ci v8::RegExp::Flags flags = value->GetFlags(); 2381cb0ef41Sopenharmony_ci if (flags & v8::RegExp::Flags::kHasIndices) description.append('d'); 2391cb0ef41Sopenharmony_ci if (flags & v8::RegExp::Flags::kGlobal) description.append('g'); 2401cb0ef41Sopenharmony_ci if (flags & v8::RegExp::Flags::kIgnoreCase) description.append('i'); 2411cb0ef41Sopenharmony_ci if (flags & v8::RegExp::Flags::kLinear) description.append('l'); 2421cb0ef41Sopenharmony_ci if (flags & v8::RegExp::Flags::kMultiline) description.append('m'); 2431cb0ef41Sopenharmony_ci if (flags & v8::RegExp::Flags::kDotAll) description.append('s'); 2441cb0ef41Sopenharmony_ci if (flags & v8::RegExp::Flags::kUnicode) description.append('u'); 2451cb0ef41Sopenharmony_ci if (flags & v8::RegExp::Flags::kSticky) description.append('y'); 2461cb0ef41Sopenharmony_ci return description.toString(); 2471cb0ef41Sopenharmony_ci} 2481cb0ef41Sopenharmony_ci 2491cb0ef41Sopenharmony_cienum class ErrorType { kNative, kClient }; 2501cb0ef41Sopenharmony_ci 2511cb0ef41Sopenharmony_ci// Build a description from an exception using the following rules: 2521cb0ef41Sopenharmony_ci// * Usually return the stack trace found in the {stack} property. 2531cb0ef41Sopenharmony_ci// * If the stack trace does not start with the class name of the passed 2541cb0ef41Sopenharmony_ci// exception, try to build a description from the class name, the 2551cb0ef41Sopenharmony_ci// {message} property and the rest of the stack trace. 2561cb0ef41Sopenharmony_ci// (The stack trace is only used if {message} was also found in 2571cb0ef41Sopenharmony_ci// said stack trace). 2581cb0ef41Sopenharmony_ciString16 descriptionForError(v8::Local<v8::Context> context, 2591cb0ef41Sopenharmony_ci v8::Local<v8::Object> object, ErrorType type) { 2601cb0ef41Sopenharmony_ci v8::Isolate* isolate = context->GetIsolate(); 2611cb0ef41Sopenharmony_ci v8::TryCatch tryCatch(isolate); 2621cb0ef41Sopenharmony_ci String16 className = toProtocolString(isolate, object->GetConstructorName()); 2631cb0ef41Sopenharmony_ci 2641cb0ef41Sopenharmony_ci v8::base::Optional<String16> stack; 2651cb0ef41Sopenharmony_ci { 2661cb0ef41Sopenharmony_ci v8::Local<v8::Value> stackValue; 2671cb0ef41Sopenharmony_ci if (object->Get(context, toV8String(isolate, "stack")) 2681cb0ef41Sopenharmony_ci .ToLocal(&stackValue) && 2691cb0ef41Sopenharmony_ci stackValue->IsString()) { 2701cb0ef41Sopenharmony_ci stack = toProtocolString(isolate, stackValue.As<v8::String>()); 2711cb0ef41Sopenharmony_ci } 2721cb0ef41Sopenharmony_ci } 2731cb0ef41Sopenharmony_ci 2741cb0ef41Sopenharmony_ci if (type == ErrorType::kNative && stack) return *stack; 2751cb0ef41Sopenharmony_ci 2761cb0ef41Sopenharmony_ci if (stack && stack->substring(0, className.length()) == className) { 2771cb0ef41Sopenharmony_ci return *stack; 2781cb0ef41Sopenharmony_ci } 2791cb0ef41Sopenharmony_ci 2801cb0ef41Sopenharmony_ci v8::base::Optional<String16> message; 2811cb0ef41Sopenharmony_ci { 2821cb0ef41Sopenharmony_ci v8::Local<v8::Value> messageValue; 2831cb0ef41Sopenharmony_ci if (object->Get(context, toV8String(isolate, "message")) 2841cb0ef41Sopenharmony_ci .ToLocal(&messageValue) && 2851cb0ef41Sopenharmony_ci messageValue->IsString()) { 2861cb0ef41Sopenharmony_ci String16 msg = toProtocolStringWithTypeCheck(isolate, messageValue); 2871cb0ef41Sopenharmony_ci if (!msg.isEmpty()) message = msg; 2881cb0ef41Sopenharmony_ci } 2891cb0ef41Sopenharmony_ci } 2901cb0ef41Sopenharmony_ci 2911cb0ef41Sopenharmony_ci if (!message) return stack ? *stack : className; 2921cb0ef41Sopenharmony_ci 2931cb0ef41Sopenharmony_ci String16 description = className + ": " + *message; 2941cb0ef41Sopenharmony_ci if (!stack) return description; 2951cb0ef41Sopenharmony_ci 2961cb0ef41Sopenharmony_ci DCHECK(stack && message); 2971cb0ef41Sopenharmony_ci size_t index = stack->find(*message); 2981cb0ef41Sopenharmony_ci String16 stackWithoutMessage = 2991cb0ef41Sopenharmony_ci index != String16::kNotFound ? stack->substring(index + message->length()) 3001cb0ef41Sopenharmony_ci : String16(); 3011cb0ef41Sopenharmony_ci return description + stackWithoutMessage; 3021cb0ef41Sopenharmony_ci} 3031cb0ef41Sopenharmony_ci 3041cb0ef41Sopenharmony_ciString16 descriptionForObject(v8::Isolate* isolate, 3051cb0ef41Sopenharmony_ci v8::Local<v8::Object> object) { 3061cb0ef41Sopenharmony_ci return toProtocolString(isolate, object->GetConstructorName()); 3071cb0ef41Sopenharmony_ci} 3081cb0ef41Sopenharmony_ci 3091cb0ef41Sopenharmony_ciString16 descriptionForDate(v8::Local<v8::Context> context, 3101cb0ef41Sopenharmony_ci v8::Local<v8::Date> date) { 3111cb0ef41Sopenharmony_ci v8::Isolate* isolate = context->GetIsolate(); 3121cb0ef41Sopenharmony_ci v8::Local<v8::String> description = v8::debug::GetDateDescription(date); 3131cb0ef41Sopenharmony_ci return toProtocolString(isolate, description); 3141cb0ef41Sopenharmony_ci} 3151cb0ef41Sopenharmony_ci 3161cb0ef41Sopenharmony_ciString16 descriptionForScopeList(v8::Local<v8::Array> list) { 3171cb0ef41Sopenharmony_ci return String16::concat( 3181cb0ef41Sopenharmony_ci "Scopes[", String16::fromInteger(static_cast<size_t>(list->Length())), 3191cb0ef41Sopenharmony_ci ']'); 3201cb0ef41Sopenharmony_ci} 3211cb0ef41Sopenharmony_ci 3221cb0ef41Sopenharmony_ciString16 descriptionForScope(v8::Local<v8::Context> context, 3231cb0ef41Sopenharmony_ci v8::Local<v8::Object> object) { 3241cb0ef41Sopenharmony_ci v8::Isolate* isolate = context->GetIsolate(); 3251cb0ef41Sopenharmony_ci v8::Local<v8::Value> value; 3261cb0ef41Sopenharmony_ci if (!object->GetRealNamedProperty(context, toV8String(isolate, "description")) 3271cb0ef41Sopenharmony_ci .ToLocal(&value)) { 3281cb0ef41Sopenharmony_ci return String16(); 3291cb0ef41Sopenharmony_ci } 3301cb0ef41Sopenharmony_ci return toProtocolStringWithTypeCheck(isolate, value); 3311cb0ef41Sopenharmony_ci} 3321cb0ef41Sopenharmony_ci 3331cb0ef41Sopenharmony_ciString16 descriptionForCollection(v8::Isolate* isolate, 3341cb0ef41Sopenharmony_ci v8::Local<v8::Object> object, size_t length) { 3351cb0ef41Sopenharmony_ci String16 className = toProtocolString(isolate, object->GetConstructorName()); 3361cb0ef41Sopenharmony_ci return String16::concat(className, '(', String16::fromInteger(length), ')'); 3371cb0ef41Sopenharmony_ci} 3381cb0ef41Sopenharmony_ci 3391cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY 3401cb0ef41Sopenharmony_ciString16 descriptionForWasmValueObject( 3411cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, 3421cb0ef41Sopenharmony_ci v8::Local<v8::debug::WasmValueObject> object) { 3431cb0ef41Sopenharmony_ci v8::Isolate* isolate = context->GetIsolate(); 3441cb0ef41Sopenharmony_ci return toProtocolString(isolate, object->type()); 3451cb0ef41Sopenharmony_ci} 3461cb0ef41Sopenharmony_ci#endif // V8_ENABLE_WEBASSEMBLY 3471cb0ef41Sopenharmony_ci 3481cb0ef41Sopenharmony_ciString16 descriptionForEntry(v8::Local<v8::Context> context, 3491cb0ef41Sopenharmony_ci v8::Local<v8::Object> object) { 3501cb0ef41Sopenharmony_ci v8::Isolate* isolate = context->GetIsolate(); 3511cb0ef41Sopenharmony_ci String16 key; 3521cb0ef41Sopenharmony_ci v8::Local<v8::Value> tmp; 3531cb0ef41Sopenharmony_ci if (object->GetRealNamedProperty(context, toV8String(isolate, "key")) 3541cb0ef41Sopenharmony_ci .ToLocal(&tmp)) { 3551cb0ef41Sopenharmony_ci auto wrapper = ValueMirror::create(context, tmp); 3561cb0ef41Sopenharmony_ci if (wrapper) { 3571cb0ef41Sopenharmony_ci std::unique_ptr<ObjectPreview> preview; 3581cb0ef41Sopenharmony_ci int limit = 5; 3591cb0ef41Sopenharmony_ci wrapper->buildEntryPreview(context, &limit, &limit, &preview); 3601cb0ef41Sopenharmony_ci if (preview) { 3611cb0ef41Sopenharmony_ci key = preview->getDescription(String16()); 3621cb0ef41Sopenharmony_ci if (preview->getType() == RemoteObject::TypeEnum::String) { 3631cb0ef41Sopenharmony_ci key = String16::concat('\"', key, '\"'); 3641cb0ef41Sopenharmony_ci } 3651cb0ef41Sopenharmony_ci } 3661cb0ef41Sopenharmony_ci } 3671cb0ef41Sopenharmony_ci } 3681cb0ef41Sopenharmony_ci 3691cb0ef41Sopenharmony_ci String16 value; 3701cb0ef41Sopenharmony_ci if (object->GetRealNamedProperty(context, toV8String(isolate, "value")) 3711cb0ef41Sopenharmony_ci .ToLocal(&tmp)) { 3721cb0ef41Sopenharmony_ci auto wrapper = ValueMirror::create(context, tmp); 3731cb0ef41Sopenharmony_ci if (wrapper) { 3741cb0ef41Sopenharmony_ci std::unique_ptr<ObjectPreview> preview; 3751cb0ef41Sopenharmony_ci int limit = 5; 3761cb0ef41Sopenharmony_ci wrapper->buildEntryPreview(context, &limit, &limit, &preview); 3771cb0ef41Sopenharmony_ci if (preview) { 3781cb0ef41Sopenharmony_ci value = preview->getDescription(String16()); 3791cb0ef41Sopenharmony_ci if (preview->getType() == RemoteObject::TypeEnum::String) { 3801cb0ef41Sopenharmony_ci value = String16::concat('\"', value, '\"'); 3811cb0ef41Sopenharmony_ci } 3821cb0ef41Sopenharmony_ci } 3831cb0ef41Sopenharmony_ci } 3841cb0ef41Sopenharmony_ci } 3851cb0ef41Sopenharmony_ci 3861cb0ef41Sopenharmony_ci return key.length() ? ("{" + key + " => " + value + "}") : value; 3871cb0ef41Sopenharmony_ci} 3881cb0ef41Sopenharmony_ci 3891cb0ef41Sopenharmony_ciString16 descriptionForFunction(v8::Local<v8::Function> value) { 3901cb0ef41Sopenharmony_ci v8::Isolate* isolate = value->GetIsolate(); 3911cb0ef41Sopenharmony_ci v8::Local<v8::String> description = v8::debug::GetFunctionDescription(value); 3921cb0ef41Sopenharmony_ci return toProtocolString(isolate, description); 3931cb0ef41Sopenharmony_ci} 3941cb0ef41Sopenharmony_ci 3951cb0ef41Sopenharmony_ciclass PrimitiveValueMirror final : public ValueMirror { 3961cb0ef41Sopenharmony_ci public: 3971cb0ef41Sopenharmony_ci PrimitiveValueMirror(v8::Local<v8::Value> value, const String16& type) 3981cb0ef41Sopenharmony_ci : m_value(value), m_type(type) {} 3991cb0ef41Sopenharmony_ci 4001cb0ef41Sopenharmony_ci v8::Local<v8::Value> v8Value() const override { return m_value; } 4011cb0ef41Sopenharmony_ci Response buildRemoteObject( 4021cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, WrapMode mode, 4031cb0ef41Sopenharmony_ci std::unique_ptr<RemoteObject>* result) const override { 4041cb0ef41Sopenharmony_ci std::unique_ptr<protocol::Value> protocolValue; 4051cb0ef41Sopenharmony_ci toProtocolValue(context, m_value, &protocolValue); 4061cb0ef41Sopenharmony_ci *result = RemoteObject::create() 4071cb0ef41Sopenharmony_ci .setType(m_type) 4081cb0ef41Sopenharmony_ci .setValue(std::move(protocolValue)) 4091cb0ef41Sopenharmony_ci .build(); 4101cb0ef41Sopenharmony_ci if (m_value->IsNull()) 4111cb0ef41Sopenharmony_ci (*result)->setSubtype(RemoteObject::SubtypeEnum::Null); 4121cb0ef41Sopenharmony_ci return Response::Success(); 4131cb0ef41Sopenharmony_ci } 4141cb0ef41Sopenharmony_ci 4151cb0ef41Sopenharmony_ci void buildEntryPreview( 4161cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, int* nameLimit, int* indexLimit, 4171cb0ef41Sopenharmony_ci std::unique_ptr<ObjectPreview>* preview) const override { 4181cb0ef41Sopenharmony_ci *preview = 4191cb0ef41Sopenharmony_ci ObjectPreview::create() 4201cb0ef41Sopenharmony_ci .setType(m_type) 4211cb0ef41Sopenharmony_ci .setDescription(descriptionForPrimitiveType(context, m_value)) 4221cb0ef41Sopenharmony_ci .setOverflow(false) 4231cb0ef41Sopenharmony_ci .setProperties(std::make_unique<protocol::Array<PropertyPreview>>()) 4241cb0ef41Sopenharmony_ci .build(); 4251cb0ef41Sopenharmony_ci if (m_value->IsNull()) 4261cb0ef41Sopenharmony_ci (*preview)->setSubtype(RemoteObject::SubtypeEnum::Null); 4271cb0ef41Sopenharmony_ci } 4281cb0ef41Sopenharmony_ci 4291cb0ef41Sopenharmony_ci void buildPropertyPreview( 4301cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, const String16& name, 4311cb0ef41Sopenharmony_ci std::unique_ptr<PropertyPreview>* preview) const override { 4321cb0ef41Sopenharmony_ci *preview = PropertyPreview::create() 4331cb0ef41Sopenharmony_ci .setName(name) 4341cb0ef41Sopenharmony_ci .setValue(abbreviateString( 4351cb0ef41Sopenharmony_ci descriptionForPrimitiveType(context, m_value), kMiddle)) 4361cb0ef41Sopenharmony_ci .setType(m_type) 4371cb0ef41Sopenharmony_ci .build(); 4381cb0ef41Sopenharmony_ci if (m_value->IsNull()) 4391cb0ef41Sopenharmony_ci (*preview)->setSubtype(RemoteObject::SubtypeEnum::Null); 4401cb0ef41Sopenharmony_ci } 4411cb0ef41Sopenharmony_ci 4421cb0ef41Sopenharmony_ci protocol::Response buildWebDriverValue( 4431cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, int max_depth, 4441cb0ef41Sopenharmony_ci std::unique_ptr<protocol::Runtime::WebDriverValue>* result) 4451cb0ef41Sopenharmony_ci const override { 4461cb0ef41Sopenharmony_ci // https://w3c.github.io/webdriver-bidi/#data-types-protocolValue-primitiveProtocolValue-serialization 4471cb0ef41Sopenharmony_ci 4481cb0ef41Sopenharmony_ci if (m_value->IsUndefined()) { 4491cb0ef41Sopenharmony_ci *result = 4501cb0ef41Sopenharmony_ci protocol::Runtime::WebDriverValue::create() 4511cb0ef41Sopenharmony_ci .setType(protocol::Runtime::WebDriverValue::TypeEnum::Undefined) 4521cb0ef41Sopenharmony_ci .build(); 4531cb0ef41Sopenharmony_ci return Response::Success(); 4541cb0ef41Sopenharmony_ci } 4551cb0ef41Sopenharmony_ci if (m_value->IsNull()) { 4561cb0ef41Sopenharmony_ci *result = protocol::Runtime::WebDriverValue::create() 4571cb0ef41Sopenharmony_ci .setType(protocol::Runtime::WebDriverValue::TypeEnum::Null) 4581cb0ef41Sopenharmony_ci .build(); 4591cb0ef41Sopenharmony_ci return Response::Success(); 4601cb0ef41Sopenharmony_ci } 4611cb0ef41Sopenharmony_ci if (m_value->IsString()) { 4621cb0ef41Sopenharmony_ci *result = 4631cb0ef41Sopenharmony_ci protocol::Runtime::WebDriverValue::create() 4641cb0ef41Sopenharmony_ci .setType(protocol::Runtime::WebDriverValue::TypeEnum::String) 4651cb0ef41Sopenharmony_ci .setValue(protocol::StringValue::create(toProtocolString( 4661cb0ef41Sopenharmony_ci context->GetIsolate(), m_value.As<v8::String>()))) 4671cb0ef41Sopenharmony_ci .build(); 4681cb0ef41Sopenharmony_ci return Response::Success(); 4691cb0ef41Sopenharmony_ci } 4701cb0ef41Sopenharmony_ci if (m_value->IsBoolean()) { 4711cb0ef41Sopenharmony_ci *result = 4721cb0ef41Sopenharmony_ci protocol::Runtime::WebDriverValue::create() 4731cb0ef41Sopenharmony_ci .setType(protocol::Runtime::WebDriverValue::TypeEnum::Boolean) 4741cb0ef41Sopenharmony_ci .setValue(protocol::FundamentalValue::create( 4751cb0ef41Sopenharmony_ci m_value.As<v8::Boolean>()->Value())) 4761cb0ef41Sopenharmony_ci .build(); 4771cb0ef41Sopenharmony_ci return Response::Success(); 4781cb0ef41Sopenharmony_ci } 4791cb0ef41Sopenharmony_ci return Response::ServerError("unexpected primitive type"); 4801cb0ef41Sopenharmony_ci } 4811cb0ef41Sopenharmony_ci 4821cb0ef41Sopenharmony_ci private: 4831cb0ef41Sopenharmony_ci v8::Local<v8::Value> m_value; 4841cb0ef41Sopenharmony_ci String16 m_type; 4851cb0ef41Sopenharmony_ci String16 m_subtype; 4861cb0ef41Sopenharmony_ci}; 4871cb0ef41Sopenharmony_ci 4881cb0ef41Sopenharmony_ciclass NumberMirror final : public ValueMirror { 4891cb0ef41Sopenharmony_ci public: 4901cb0ef41Sopenharmony_ci explicit NumberMirror(v8::Local<v8::Number> value) : m_value(value) {} 4911cb0ef41Sopenharmony_ci v8::Local<v8::Value> v8Value() const override { return m_value; } 4921cb0ef41Sopenharmony_ci 4931cb0ef41Sopenharmony_ci Response buildRemoteObject( 4941cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, WrapMode mode, 4951cb0ef41Sopenharmony_ci std::unique_ptr<RemoteObject>* result) const override { 4961cb0ef41Sopenharmony_ci bool unserializable = false; 4971cb0ef41Sopenharmony_ci String16 descriptionValue = description(&unserializable); 4981cb0ef41Sopenharmony_ci *result = RemoteObject::create() 4991cb0ef41Sopenharmony_ci .setType(RemoteObject::TypeEnum::Number) 5001cb0ef41Sopenharmony_ci .setDescription(descriptionValue) 5011cb0ef41Sopenharmony_ci .build(); 5021cb0ef41Sopenharmony_ci if (unserializable) { 5031cb0ef41Sopenharmony_ci (*result)->setUnserializableValue(descriptionValue); 5041cb0ef41Sopenharmony_ci } else { 5051cb0ef41Sopenharmony_ci (*result)->setValue(protocol::FundamentalValue::create(m_value->Value())); 5061cb0ef41Sopenharmony_ci } 5071cb0ef41Sopenharmony_ci return Response::Success(); 5081cb0ef41Sopenharmony_ci } 5091cb0ef41Sopenharmony_ci void buildPropertyPreview( 5101cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, const String16& name, 5111cb0ef41Sopenharmony_ci std::unique_ptr<PropertyPreview>* result) const override { 5121cb0ef41Sopenharmony_ci bool unserializable = false; 5131cb0ef41Sopenharmony_ci *result = PropertyPreview::create() 5141cb0ef41Sopenharmony_ci .setName(name) 5151cb0ef41Sopenharmony_ci .setType(RemoteObject::TypeEnum::Number) 5161cb0ef41Sopenharmony_ci .setValue(description(&unserializable)) 5171cb0ef41Sopenharmony_ci .build(); 5181cb0ef41Sopenharmony_ci } 5191cb0ef41Sopenharmony_ci void buildEntryPreview( 5201cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, int* nameLimit, int* indexLimit, 5211cb0ef41Sopenharmony_ci std::unique_ptr<ObjectPreview>* preview) const override { 5221cb0ef41Sopenharmony_ci bool unserializable = false; 5231cb0ef41Sopenharmony_ci *preview = 5241cb0ef41Sopenharmony_ci ObjectPreview::create() 5251cb0ef41Sopenharmony_ci .setType(RemoteObject::TypeEnum::Number) 5261cb0ef41Sopenharmony_ci .setDescription(description(&unserializable)) 5271cb0ef41Sopenharmony_ci .setOverflow(false) 5281cb0ef41Sopenharmony_ci .setProperties(std::make_unique<protocol::Array<PropertyPreview>>()) 5291cb0ef41Sopenharmony_ci .build(); 5301cb0ef41Sopenharmony_ci } 5311cb0ef41Sopenharmony_ci 5321cb0ef41Sopenharmony_ci protocol::Response buildWebDriverValue( 5331cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, int max_depth, 5341cb0ef41Sopenharmony_ci std::unique_ptr<protocol::Runtime::WebDriverValue>* result) 5351cb0ef41Sopenharmony_ci const override { 5361cb0ef41Sopenharmony_ci // https://w3c.github.io/webdriver-bidi/#data-types-protocolValue-primitiveProtocolValue-serialization 5371cb0ef41Sopenharmony_ci *result = protocol::Runtime::WebDriverValue::create() 5381cb0ef41Sopenharmony_ci .setType(protocol::Runtime::WebDriverValue::TypeEnum::Number) 5391cb0ef41Sopenharmony_ci .build(); 5401cb0ef41Sopenharmony_ci 5411cb0ef41Sopenharmony_ci bool unserializable = false; 5421cb0ef41Sopenharmony_ci String16 descriptionValue = description(&unserializable); 5431cb0ef41Sopenharmony_ci if (unserializable) { 5441cb0ef41Sopenharmony_ci (*result)->setValue(protocol::StringValue::create(descriptionValue)); 5451cb0ef41Sopenharmony_ci } else { 5461cb0ef41Sopenharmony_ci (*result)->setValue(toProtocolValue(m_value.As<v8::Number>()->Value())); 5471cb0ef41Sopenharmony_ci } 5481cb0ef41Sopenharmony_ci return Response::Success(); 5491cb0ef41Sopenharmony_ci } 5501cb0ef41Sopenharmony_ci 5511cb0ef41Sopenharmony_ci private: 5521cb0ef41Sopenharmony_ci String16 description(bool* unserializable) const { 5531cb0ef41Sopenharmony_ci *unserializable = true; 5541cb0ef41Sopenharmony_ci double rawValue = m_value->Value(); 5551cb0ef41Sopenharmony_ci if (std::isnan(rawValue)) return "NaN"; 5561cb0ef41Sopenharmony_ci if (rawValue == 0.0 && std::signbit(rawValue)) return "-0"; 5571cb0ef41Sopenharmony_ci if (std::isinf(rawValue)) { 5581cb0ef41Sopenharmony_ci return std::signbit(rawValue) ? "-Infinity" : "Infinity"; 5591cb0ef41Sopenharmony_ci } 5601cb0ef41Sopenharmony_ci *unserializable = false; 5611cb0ef41Sopenharmony_ci return String16::fromDouble(rawValue); 5621cb0ef41Sopenharmony_ci } 5631cb0ef41Sopenharmony_ci 5641cb0ef41Sopenharmony_ci v8::Local<v8::Number> m_value; 5651cb0ef41Sopenharmony_ci}; 5661cb0ef41Sopenharmony_ci 5671cb0ef41Sopenharmony_ciclass BigIntMirror final : public ValueMirror { 5681cb0ef41Sopenharmony_ci public: 5691cb0ef41Sopenharmony_ci explicit BigIntMirror(v8::Local<v8::BigInt> value) : m_value(value) {} 5701cb0ef41Sopenharmony_ci 5711cb0ef41Sopenharmony_ci Response buildRemoteObject( 5721cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, WrapMode mode, 5731cb0ef41Sopenharmony_ci std::unique_ptr<RemoteObject>* result) const override { 5741cb0ef41Sopenharmony_ci String16 description = descriptionForBigInt(context, m_value); 5751cb0ef41Sopenharmony_ci *result = RemoteObject::create() 5761cb0ef41Sopenharmony_ci .setType(RemoteObject::TypeEnum::Bigint) 5771cb0ef41Sopenharmony_ci .setUnserializableValue(description) 5781cb0ef41Sopenharmony_ci .setDescription(abbreviateString(description, kMiddle)) 5791cb0ef41Sopenharmony_ci .build(); 5801cb0ef41Sopenharmony_ci return Response::Success(); 5811cb0ef41Sopenharmony_ci } 5821cb0ef41Sopenharmony_ci 5831cb0ef41Sopenharmony_ci void buildPropertyPreview(v8::Local<v8::Context> context, 5841cb0ef41Sopenharmony_ci const String16& name, 5851cb0ef41Sopenharmony_ci std::unique_ptr<protocol::Runtime::PropertyPreview>* 5861cb0ef41Sopenharmony_ci preview) const override { 5871cb0ef41Sopenharmony_ci *preview = PropertyPreview::create() 5881cb0ef41Sopenharmony_ci .setName(name) 5891cb0ef41Sopenharmony_ci .setType(RemoteObject::TypeEnum::Bigint) 5901cb0ef41Sopenharmony_ci .setValue(abbreviateString( 5911cb0ef41Sopenharmony_ci descriptionForBigInt(context, m_value), kMiddle)) 5921cb0ef41Sopenharmony_ci .build(); 5931cb0ef41Sopenharmony_ci } 5941cb0ef41Sopenharmony_ci 5951cb0ef41Sopenharmony_ci void buildEntryPreview(v8::Local<v8::Context> context, int* nameLimit, 5961cb0ef41Sopenharmony_ci int* indexLimit, 5971cb0ef41Sopenharmony_ci std::unique_ptr<protocol::Runtime::ObjectPreview>* 5981cb0ef41Sopenharmony_ci preview) const override { 5991cb0ef41Sopenharmony_ci *preview = 6001cb0ef41Sopenharmony_ci ObjectPreview::create() 6011cb0ef41Sopenharmony_ci .setType(RemoteObject::TypeEnum::Bigint) 6021cb0ef41Sopenharmony_ci .setDescription(abbreviateString( 6031cb0ef41Sopenharmony_ci descriptionForBigInt(context, m_value), kMiddle)) 6041cb0ef41Sopenharmony_ci .setOverflow(false) 6051cb0ef41Sopenharmony_ci .setProperties(std::make_unique<protocol::Array<PropertyPreview>>()) 6061cb0ef41Sopenharmony_ci .build(); 6071cb0ef41Sopenharmony_ci } 6081cb0ef41Sopenharmony_ci 6091cb0ef41Sopenharmony_ci v8::Local<v8::Value> v8Value() const override { return m_value; } 6101cb0ef41Sopenharmony_ci 6111cb0ef41Sopenharmony_ci protocol::Response buildWebDriverValue( 6121cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, int max_depth, 6131cb0ef41Sopenharmony_ci std::unique_ptr<protocol::Runtime::WebDriverValue>* result) 6141cb0ef41Sopenharmony_ci const override { 6151cb0ef41Sopenharmony_ci // https://w3c.github.io/webdriver-bidi/#data-types-protocolValue-primitiveProtocolValue-serialization 6161cb0ef41Sopenharmony_ci 6171cb0ef41Sopenharmony_ci *result = protocol::Runtime::WebDriverValue::create() 6181cb0ef41Sopenharmony_ci .setType(protocol::Runtime::WebDriverValue::TypeEnum::Bigint) 6191cb0ef41Sopenharmony_ci .setValue(protocol::StringValue::create( 6201cb0ef41Sopenharmony_ci descriptionForBigInt(context, m_value))) 6211cb0ef41Sopenharmony_ci .build(); 6221cb0ef41Sopenharmony_ci return Response::Success(); 6231cb0ef41Sopenharmony_ci } 6241cb0ef41Sopenharmony_ci 6251cb0ef41Sopenharmony_ci private: 6261cb0ef41Sopenharmony_ci v8::Local<v8::BigInt> m_value; 6271cb0ef41Sopenharmony_ci}; 6281cb0ef41Sopenharmony_ci 6291cb0ef41Sopenharmony_ciclass SymbolMirror final : public ValueMirror { 6301cb0ef41Sopenharmony_ci public: 6311cb0ef41Sopenharmony_ci explicit SymbolMirror(v8::Local<v8::Value> value) 6321cb0ef41Sopenharmony_ci : m_symbol(value.As<v8::Symbol>()) {} 6331cb0ef41Sopenharmony_ci 6341cb0ef41Sopenharmony_ci Response buildRemoteObject( 6351cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, WrapMode mode, 6361cb0ef41Sopenharmony_ci std::unique_ptr<RemoteObject>* result) const override { 6371cb0ef41Sopenharmony_ci if (mode == WrapMode::kForceValue) { 6381cb0ef41Sopenharmony_ci return Response::ServerError("Object couldn't be returned by value"); 6391cb0ef41Sopenharmony_ci } 6401cb0ef41Sopenharmony_ci *result = RemoteObject::create() 6411cb0ef41Sopenharmony_ci .setType(RemoteObject::TypeEnum::Symbol) 6421cb0ef41Sopenharmony_ci .setDescription(descriptionForSymbol(context, m_symbol)) 6431cb0ef41Sopenharmony_ci .build(); 6441cb0ef41Sopenharmony_ci return Response::Success(); 6451cb0ef41Sopenharmony_ci } 6461cb0ef41Sopenharmony_ci 6471cb0ef41Sopenharmony_ci void buildPropertyPreview(v8::Local<v8::Context> context, 6481cb0ef41Sopenharmony_ci const String16& name, 6491cb0ef41Sopenharmony_ci std::unique_ptr<protocol::Runtime::PropertyPreview>* 6501cb0ef41Sopenharmony_ci preview) const override { 6511cb0ef41Sopenharmony_ci *preview = PropertyPreview::create() 6521cb0ef41Sopenharmony_ci .setName(name) 6531cb0ef41Sopenharmony_ci .setType(RemoteObject::TypeEnum::Symbol) 6541cb0ef41Sopenharmony_ci .setValue(abbreviateString( 6551cb0ef41Sopenharmony_ci descriptionForSymbol(context, m_symbol), kEnd)) 6561cb0ef41Sopenharmony_ci .build(); 6571cb0ef41Sopenharmony_ci } 6581cb0ef41Sopenharmony_ci 6591cb0ef41Sopenharmony_ci void buildEntryPreview( 6601cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, int* nameLimit, int* indexLimit, 6611cb0ef41Sopenharmony_ci std::unique_ptr<ObjectPreview>* preview) const override { 6621cb0ef41Sopenharmony_ci *preview = 6631cb0ef41Sopenharmony_ci ObjectPreview::create() 6641cb0ef41Sopenharmony_ci .setType(RemoteObject::TypeEnum::Symbol) 6651cb0ef41Sopenharmony_ci .setDescription(descriptionForSymbol(context, m_symbol)) 6661cb0ef41Sopenharmony_ci .setOverflow(false) 6671cb0ef41Sopenharmony_ci .setProperties(std::make_unique<protocol::Array<PropertyPreview>>()) 6681cb0ef41Sopenharmony_ci .build(); 6691cb0ef41Sopenharmony_ci } 6701cb0ef41Sopenharmony_ci 6711cb0ef41Sopenharmony_ci v8::Local<v8::Value> v8Value() const override { return m_symbol; } 6721cb0ef41Sopenharmony_ci 6731cb0ef41Sopenharmony_ci protocol::Response buildWebDriverValue( 6741cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, int max_depth, 6751cb0ef41Sopenharmony_ci std::unique_ptr<protocol::Runtime::WebDriverValue>* result) 6761cb0ef41Sopenharmony_ci const override { 6771cb0ef41Sopenharmony_ci // https://w3c.github.io/webdriver-bidi/#data-types-protocolValue-RemoteValue-serialization 6781cb0ef41Sopenharmony_ci *result = protocol::Runtime::WebDriverValue::create() 6791cb0ef41Sopenharmony_ci .setType(protocol::Runtime::WebDriverValue::TypeEnum::Symbol) 6801cb0ef41Sopenharmony_ci .build(); 6811cb0ef41Sopenharmony_ci return Response::Success(); 6821cb0ef41Sopenharmony_ci } 6831cb0ef41Sopenharmony_ci 6841cb0ef41Sopenharmony_ci private: 6851cb0ef41Sopenharmony_ci v8::Local<v8::Symbol> m_symbol; 6861cb0ef41Sopenharmony_ci}; 6871cb0ef41Sopenharmony_ci 6881cb0ef41Sopenharmony_ciclass LocationMirror final : public ValueMirror { 6891cb0ef41Sopenharmony_ci public: 6901cb0ef41Sopenharmony_ci static std::unique_ptr<LocationMirror> create( 6911cb0ef41Sopenharmony_ci v8::Local<v8::Function> function) { 6921cb0ef41Sopenharmony_ci return create(function, function->ScriptId(), 6931cb0ef41Sopenharmony_ci function->GetScriptLineNumber(), 6941cb0ef41Sopenharmony_ci function->GetScriptColumnNumber()); 6951cb0ef41Sopenharmony_ci } 6961cb0ef41Sopenharmony_ci static std::unique_ptr<LocationMirror> createForGenerator( 6971cb0ef41Sopenharmony_ci v8::Local<v8::Value> value) { 6981cb0ef41Sopenharmony_ci v8::Local<v8::debug::GeneratorObject> generatorObject = 6991cb0ef41Sopenharmony_ci v8::debug::GeneratorObject::Cast(value); 7001cb0ef41Sopenharmony_ci if (!generatorObject->IsSuspended()) { 7011cb0ef41Sopenharmony_ci return create(generatorObject->Function()); 7021cb0ef41Sopenharmony_ci } 7031cb0ef41Sopenharmony_ci v8::Local<v8::debug::Script> script; 7041cb0ef41Sopenharmony_ci if (!generatorObject->Script().ToLocal(&script)) return nullptr; 7051cb0ef41Sopenharmony_ci v8::debug::Location suspendedLocation = 7061cb0ef41Sopenharmony_ci generatorObject->SuspendedLocation(); 7071cb0ef41Sopenharmony_ci return create(value, script->Id(), suspendedLocation.GetLineNumber(), 7081cb0ef41Sopenharmony_ci suspendedLocation.GetColumnNumber()); 7091cb0ef41Sopenharmony_ci } 7101cb0ef41Sopenharmony_ci 7111cb0ef41Sopenharmony_ci Response buildRemoteObject( 7121cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, WrapMode mode, 7131cb0ef41Sopenharmony_ci std::unique_ptr<RemoteObject>* result) const override { 7141cb0ef41Sopenharmony_ci auto location = protocol::DictionaryValue::create(); 7151cb0ef41Sopenharmony_ci location->setString("scriptId", String16::fromInteger(m_scriptId)); 7161cb0ef41Sopenharmony_ci location->setInteger("lineNumber", m_lineNumber); 7171cb0ef41Sopenharmony_ci location->setInteger("columnNumber", m_columnNumber); 7181cb0ef41Sopenharmony_ci *result = RemoteObject::create() 7191cb0ef41Sopenharmony_ci .setType(RemoteObject::TypeEnum::Object) 7201cb0ef41Sopenharmony_ci .setSubtype("internal#location") 7211cb0ef41Sopenharmony_ci .setDescription("Object") 7221cb0ef41Sopenharmony_ci .setValue(std::move(location)) 7231cb0ef41Sopenharmony_ci .build(); 7241cb0ef41Sopenharmony_ci return Response::Success(); 7251cb0ef41Sopenharmony_ci } 7261cb0ef41Sopenharmony_ci v8::Local<v8::Value> v8Value() const override { return m_value; } 7271cb0ef41Sopenharmony_ci 7281cb0ef41Sopenharmony_ci protocol::Response buildWebDriverValue( 7291cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, int max_depth, 7301cb0ef41Sopenharmony_ci std::unique_ptr<protocol::Runtime::WebDriverValue>* result) 7311cb0ef41Sopenharmony_ci const override { 7321cb0ef41Sopenharmony_ci *result = protocol::Runtime::WebDriverValue::create() 7331cb0ef41Sopenharmony_ci .setType(protocol::Runtime::WebDriverValue::TypeEnum::Object) 7341cb0ef41Sopenharmony_ci .build(); 7351cb0ef41Sopenharmony_ci return Response::Success(); 7361cb0ef41Sopenharmony_ci } 7371cb0ef41Sopenharmony_ci 7381cb0ef41Sopenharmony_ci private: 7391cb0ef41Sopenharmony_ci static std::unique_ptr<LocationMirror> create(v8::Local<v8::Value> value, 7401cb0ef41Sopenharmony_ci int scriptId, int lineNumber, 7411cb0ef41Sopenharmony_ci int columnNumber) { 7421cb0ef41Sopenharmony_ci if (scriptId == v8::UnboundScript::kNoScriptId) return nullptr; 7431cb0ef41Sopenharmony_ci if (lineNumber == v8::Function::kLineOffsetNotFound || 7441cb0ef41Sopenharmony_ci columnNumber == v8::Function::kLineOffsetNotFound) { 7451cb0ef41Sopenharmony_ci return nullptr; 7461cb0ef41Sopenharmony_ci } 7471cb0ef41Sopenharmony_ci return std::unique_ptr<LocationMirror>( 7481cb0ef41Sopenharmony_ci new LocationMirror(value, scriptId, lineNumber, columnNumber)); 7491cb0ef41Sopenharmony_ci } 7501cb0ef41Sopenharmony_ci 7511cb0ef41Sopenharmony_ci LocationMirror(v8::Local<v8::Value> value, int scriptId, int lineNumber, 7521cb0ef41Sopenharmony_ci int columnNumber) 7531cb0ef41Sopenharmony_ci : m_value(value), 7541cb0ef41Sopenharmony_ci m_scriptId(scriptId), 7551cb0ef41Sopenharmony_ci m_lineNumber(lineNumber), 7561cb0ef41Sopenharmony_ci m_columnNumber(columnNumber) {} 7571cb0ef41Sopenharmony_ci 7581cb0ef41Sopenharmony_ci v8::Local<v8::Value> m_value; 7591cb0ef41Sopenharmony_ci int m_scriptId; 7601cb0ef41Sopenharmony_ci int m_lineNumber; 7611cb0ef41Sopenharmony_ci int m_columnNumber; 7621cb0ef41Sopenharmony_ci}; 7631cb0ef41Sopenharmony_ci 7641cb0ef41Sopenharmony_ciclass FunctionMirror final : public ValueMirror { 7651cb0ef41Sopenharmony_ci public: 7661cb0ef41Sopenharmony_ci explicit FunctionMirror(v8::Local<v8::Value> value) 7671cb0ef41Sopenharmony_ci : m_value(value.As<v8::Function>()) {} 7681cb0ef41Sopenharmony_ci 7691cb0ef41Sopenharmony_ci v8::Local<v8::Value> v8Value() const override { return m_value; } 7701cb0ef41Sopenharmony_ci 7711cb0ef41Sopenharmony_ci Response buildRemoteObject( 7721cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, WrapMode mode, 7731cb0ef41Sopenharmony_ci std::unique_ptr<RemoteObject>* result) const override { 7741cb0ef41Sopenharmony_ci // TODO(alph): drop this functionality. 7751cb0ef41Sopenharmony_ci if (mode == WrapMode::kForceValue) { 7761cb0ef41Sopenharmony_ci std::unique_ptr<protocol::Value> protocolValue; 7771cb0ef41Sopenharmony_ci Response response = toProtocolValue(context, m_value, &protocolValue); 7781cb0ef41Sopenharmony_ci if (!response.IsSuccess()) return response; 7791cb0ef41Sopenharmony_ci *result = RemoteObject::create() 7801cb0ef41Sopenharmony_ci .setType(RemoteObject::TypeEnum::Function) 7811cb0ef41Sopenharmony_ci .setValue(std::move(protocolValue)) 7821cb0ef41Sopenharmony_ci .build(); 7831cb0ef41Sopenharmony_ci } else { 7841cb0ef41Sopenharmony_ci *result = RemoteObject::create() 7851cb0ef41Sopenharmony_ci .setType(RemoteObject::TypeEnum::Function) 7861cb0ef41Sopenharmony_ci .setClassName(toProtocolStringWithTypeCheck( 7871cb0ef41Sopenharmony_ci context->GetIsolate(), m_value->GetConstructorName())) 7881cb0ef41Sopenharmony_ci .setDescription(descriptionForFunction(m_value)) 7891cb0ef41Sopenharmony_ci .build(); 7901cb0ef41Sopenharmony_ci } 7911cb0ef41Sopenharmony_ci return Response::Success(); 7921cb0ef41Sopenharmony_ci } 7931cb0ef41Sopenharmony_ci 7941cb0ef41Sopenharmony_ci void buildPropertyPreview( 7951cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, const String16& name, 7961cb0ef41Sopenharmony_ci std::unique_ptr<PropertyPreview>* result) const override { 7971cb0ef41Sopenharmony_ci *result = PropertyPreview::create() 7981cb0ef41Sopenharmony_ci .setName(name) 7991cb0ef41Sopenharmony_ci .setType(RemoteObject::TypeEnum::Function) 8001cb0ef41Sopenharmony_ci .setValue(String16()) 8011cb0ef41Sopenharmony_ci .build(); 8021cb0ef41Sopenharmony_ci } 8031cb0ef41Sopenharmony_ci void buildEntryPreview( 8041cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, int* nameLimit, int* indexLimit, 8051cb0ef41Sopenharmony_ci std::unique_ptr<ObjectPreview>* preview) const override { 8061cb0ef41Sopenharmony_ci *preview = 8071cb0ef41Sopenharmony_ci ObjectPreview::create() 8081cb0ef41Sopenharmony_ci .setType(RemoteObject::TypeEnum::Function) 8091cb0ef41Sopenharmony_ci .setDescription(descriptionForFunction(m_value)) 8101cb0ef41Sopenharmony_ci .setOverflow(false) 8111cb0ef41Sopenharmony_ci .setProperties(std::make_unique<protocol::Array<PropertyPreview>>()) 8121cb0ef41Sopenharmony_ci .build(); 8131cb0ef41Sopenharmony_ci } 8141cb0ef41Sopenharmony_ci 8151cb0ef41Sopenharmony_ci protocol::Response buildWebDriverValue( 8161cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, int max_depth, 8171cb0ef41Sopenharmony_ci std::unique_ptr<protocol::Runtime::WebDriverValue>* result) 8181cb0ef41Sopenharmony_ci const override { 8191cb0ef41Sopenharmony_ci // https://w3c.github.io/webdriver-bidi/#data-types-protocolValue-RemoteValue-serialization 8201cb0ef41Sopenharmony_ci *result = 8211cb0ef41Sopenharmony_ci protocol::Runtime::WebDriverValue::create() 8221cb0ef41Sopenharmony_ci .setType(protocol::Runtime::WebDriverValue::TypeEnum::Function) 8231cb0ef41Sopenharmony_ci .build(); 8241cb0ef41Sopenharmony_ci return Response::Success(); 8251cb0ef41Sopenharmony_ci } 8261cb0ef41Sopenharmony_ci 8271cb0ef41Sopenharmony_ci private: 8281cb0ef41Sopenharmony_ci v8::Local<v8::Function> m_value; 8291cb0ef41Sopenharmony_ci}; 8301cb0ef41Sopenharmony_ci 8311cb0ef41Sopenharmony_cibool isArrayLike(v8::Local<v8::Context> context, v8::Local<v8::Value> value, 8321cb0ef41Sopenharmony_ci size_t* length) { 8331cb0ef41Sopenharmony_ci if (!value->IsObject()) return false; 8341cb0ef41Sopenharmony_ci v8::Isolate* isolate = context->GetIsolate(); 8351cb0ef41Sopenharmony_ci v8::TryCatch tryCatch(isolate); 8361cb0ef41Sopenharmony_ci v8::MicrotasksScope microtasksScope(isolate, 8371cb0ef41Sopenharmony_ci v8::MicrotasksScope::kDoNotRunMicrotasks); 8381cb0ef41Sopenharmony_ci v8::Local<v8::Object> object = value.As<v8::Object>(); 8391cb0ef41Sopenharmony_ci v8::Local<v8::Value> spliceValue; 8401cb0ef41Sopenharmony_ci if (!object->IsArgumentsObject() && 8411cb0ef41Sopenharmony_ci (!object->GetRealNamedProperty(context, toV8String(isolate, "splice")) 8421cb0ef41Sopenharmony_ci .ToLocal(&spliceValue) || 8431cb0ef41Sopenharmony_ci !spliceValue->IsFunction())) { 8441cb0ef41Sopenharmony_ci return false; 8451cb0ef41Sopenharmony_ci } 8461cb0ef41Sopenharmony_ci v8::Local<v8::Value> lengthValue; 8471cb0ef41Sopenharmony_ci v8::Maybe<bool> result = 8481cb0ef41Sopenharmony_ci object->HasOwnProperty(context, toV8String(isolate, "length")); 8491cb0ef41Sopenharmony_ci if (result.IsNothing()) return false; 8501cb0ef41Sopenharmony_ci if (!result.FromJust() || 8511cb0ef41Sopenharmony_ci !object->Get(context, toV8String(isolate, "length")) 8521cb0ef41Sopenharmony_ci .ToLocal(&lengthValue) || 8531cb0ef41Sopenharmony_ci !lengthValue->IsUint32()) { 8541cb0ef41Sopenharmony_ci return false; 8551cb0ef41Sopenharmony_ci } 8561cb0ef41Sopenharmony_ci *length = lengthValue.As<v8::Uint32>()->Value(); 8571cb0ef41Sopenharmony_ci return true; 8581cb0ef41Sopenharmony_ci} 8591cb0ef41Sopenharmony_ci 8601cb0ef41Sopenharmony_cistruct EntryMirror { 8611cb0ef41Sopenharmony_ci std::unique_ptr<ValueMirror> key; 8621cb0ef41Sopenharmony_ci std::unique_ptr<ValueMirror> value; 8631cb0ef41Sopenharmony_ci 8641cb0ef41Sopenharmony_ci static bool getEntries(v8::Local<v8::Context> context, 8651cb0ef41Sopenharmony_ci v8::Local<v8::Object> object, size_t limit, 8661cb0ef41Sopenharmony_ci bool* overflow, std::vector<EntryMirror>* mirrors) { 8671cb0ef41Sopenharmony_ci bool isKeyValue = false; 8681cb0ef41Sopenharmony_ci v8::Local<v8::Array> entries; 8691cb0ef41Sopenharmony_ci if (!object->PreviewEntries(&isKeyValue).ToLocal(&entries)) return false; 8701cb0ef41Sopenharmony_ci for (uint32_t i = 0; i < entries->Length(); i += isKeyValue ? 2 : 1) { 8711cb0ef41Sopenharmony_ci v8::Local<v8::Value> tmp; 8721cb0ef41Sopenharmony_ci 8731cb0ef41Sopenharmony_ci std::unique_ptr<ValueMirror> keyMirror; 8741cb0ef41Sopenharmony_ci if (isKeyValue && entries->Get(context, i).ToLocal(&tmp)) { 8751cb0ef41Sopenharmony_ci keyMirror = ValueMirror::create(context, tmp); 8761cb0ef41Sopenharmony_ci } 8771cb0ef41Sopenharmony_ci std::unique_ptr<ValueMirror> valueMirror; 8781cb0ef41Sopenharmony_ci if (entries->Get(context, isKeyValue ? i + 1 : i).ToLocal(&tmp)) { 8791cb0ef41Sopenharmony_ci valueMirror = ValueMirror::create(context, tmp); 8801cb0ef41Sopenharmony_ci } else { 8811cb0ef41Sopenharmony_ci continue; 8821cb0ef41Sopenharmony_ci } 8831cb0ef41Sopenharmony_ci if (mirrors->size() == limit) { 8841cb0ef41Sopenharmony_ci *overflow = true; 8851cb0ef41Sopenharmony_ci return true; 8861cb0ef41Sopenharmony_ci } 8871cb0ef41Sopenharmony_ci mirrors->emplace_back( 8881cb0ef41Sopenharmony_ci EntryMirror{std::move(keyMirror), std::move(valueMirror)}); 8891cb0ef41Sopenharmony_ci } 8901cb0ef41Sopenharmony_ci return mirrors->size() > 0; 8911cb0ef41Sopenharmony_ci } 8921cb0ef41Sopenharmony_ci}; 8931cb0ef41Sopenharmony_ci 8941cb0ef41Sopenharmony_ciclass PreviewPropertyAccumulator : public ValueMirror::PropertyAccumulator { 8951cb0ef41Sopenharmony_ci public: 8961cb0ef41Sopenharmony_ci PreviewPropertyAccumulator(const std::vector<String16>& blocklist, 8971cb0ef41Sopenharmony_ci int skipIndex, int* nameLimit, int* indexLimit, 8981cb0ef41Sopenharmony_ci bool* overflow, 8991cb0ef41Sopenharmony_ci std::vector<PropertyMirror>* mirrors) 9001cb0ef41Sopenharmony_ci : m_blocklist(blocklist), 9011cb0ef41Sopenharmony_ci m_skipIndex(skipIndex), 9021cb0ef41Sopenharmony_ci m_nameLimit(nameLimit), 9031cb0ef41Sopenharmony_ci m_indexLimit(indexLimit), 9041cb0ef41Sopenharmony_ci m_overflow(overflow), 9051cb0ef41Sopenharmony_ci m_mirrors(mirrors) {} 9061cb0ef41Sopenharmony_ci 9071cb0ef41Sopenharmony_ci bool Add(PropertyMirror mirror) override { 9081cb0ef41Sopenharmony_ci if (mirror.exception) return true; 9091cb0ef41Sopenharmony_ci if ((!mirror.getter || !mirror.getter->v8Value()->IsFunction()) && 9101cb0ef41Sopenharmony_ci !mirror.value) { 9111cb0ef41Sopenharmony_ci return true; 9121cb0ef41Sopenharmony_ci } 9131cb0ef41Sopenharmony_ci if (!mirror.isOwn && !mirror.isSynthetic) return true; 9141cb0ef41Sopenharmony_ci if (std::find(m_blocklist.begin(), m_blocklist.end(), mirror.name) != 9151cb0ef41Sopenharmony_ci m_blocklist.end()) { 9161cb0ef41Sopenharmony_ci return true; 9171cb0ef41Sopenharmony_ci } 9181cb0ef41Sopenharmony_ci if (mirror.isIndex && m_skipIndex > 0) { 9191cb0ef41Sopenharmony_ci --m_skipIndex; 9201cb0ef41Sopenharmony_ci if (m_skipIndex > 0) return true; 9211cb0ef41Sopenharmony_ci } 9221cb0ef41Sopenharmony_ci int* limit = mirror.isIndex ? m_indexLimit : m_nameLimit; 9231cb0ef41Sopenharmony_ci if (!*limit) { 9241cb0ef41Sopenharmony_ci *m_overflow = true; 9251cb0ef41Sopenharmony_ci return false; 9261cb0ef41Sopenharmony_ci } 9271cb0ef41Sopenharmony_ci --*limit; 9281cb0ef41Sopenharmony_ci m_mirrors->push_back(std::move(mirror)); 9291cb0ef41Sopenharmony_ci return true; 9301cb0ef41Sopenharmony_ci } 9311cb0ef41Sopenharmony_ci 9321cb0ef41Sopenharmony_ci private: 9331cb0ef41Sopenharmony_ci std::vector<String16> m_blocklist; 9341cb0ef41Sopenharmony_ci int m_skipIndex; 9351cb0ef41Sopenharmony_ci int* m_nameLimit; 9361cb0ef41Sopenharmony_ci int* m_indexLimit; 9371cb0ef41Sopenharmony_ci bool* m_overflow; 9381cb0ef41Sopenharmony_ci std::vector<PropertyMirror>* m_mirrors; 9391cb0ef41Sopenharmony_ci}; 9401cb0ef41Sopenharmony_ci 9411cb0ef41Sopenharmony_cibool getPropertiesForPreview(v8::Local<v8::Context> context, 9421cb0ef41Sopenharmony_ci v8::Local<v8::Object> object, int* nameLimit, 9431cb0ef41Sopenharmony_ci int* indexLimit, bool* overflow, 9441cb0ef41Sopenharmony_ci std::vector<PropertyMirror>* properties) { 9451cb0ef41Sopenharmony_ci std::vector<String16> blocklist; 9461cb0ef41Sopenharmony_ci size_t length = 0; 9471cb0ef41Sopenharmony_ci if (object->IsArray() || isArrayLike(context, object, &length) || 9481cb0ef41Sopenharmony_ci object->IsStringObject()) { 9491cb0ef41Sopenharmony_ci blocklist.push_back("length"); 9501cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY 9511cb0ef41Sopenharmony_ci } else if (v8::debug::WasmValueObject::IsWasmValueObject(object)) { 9521cb0ef41Sopenharmony_ci blocklist.push_back("type"); 9531cb0ef41Sopenharmony_ci#endif // V8_ENABLE_WEBASSEMBLY 9541cb0ef41Sopenharmony_ci } else { 9551cb0ef41Sopenharmony_ci auto clientSubtype = clientFor(context)->valueSubtype(object); 9561cb0ef41Sopenharmony_ci if (clientSubtype && toString16(clientSubtype->string()) == "array") { 9571cb0ef41Sopenharmony_ci blocklist.push_back("length"); 9581cb0ef41Sopenharmony_ci } 9591cb0ef41Sopenharmony_ci } 9601cb0ef41Sopenharmony_ci if (object->IsArrayBuffer() || object->IsSharedArrayBuffer()) { 9611cb0ef41Sopenharmony_ci blocklist.push_back("[[Int8Array]]"); 9621cb0ef41Sopenharmony_ci blocklist.push_back("[[Uint8Array]]"); 9631cb0ef41Sopenharmony_ci blocklist.push_back("[[Int16Array]]"); 9641cb0ef41Sopenharmony_ci blocklist.push_back("[[Int32Array]]"); 9651cb0ef41Sopenharmony_ci } 9661cb0ef41Sopenharmony_ci int skipIndex = object->IsStringObject() 9671cb0ef41Sopenharmony_ci ? object.As<v8::StringObject>()->ValueOf()->Length() + 1 9681cb0ef41Sopenharmony_ci : -1; 9691cb0ef41Sopenharmony_ci PreviewPropertyAccumulator accumulator(blocklist, skipIndex, nameLimit, 9701cb0ef41Sopenharmony_ci indexLimit, overflow, properties); 9711cb0ef41Sopenharmony_ci return ValueMirror::getProperties(context, object, false, false, false, 9721cb0ef41Sopenharmony_ci &accumulator); 9731cb0ef41Sopenharmony_ci} 9741cb0ef41Sopenharmony_ci 9751cb0ef41Sopenharmony_civoid getInternalPropertiesForPreview( 9761cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, v8::Local<v8::Object> object, 9771cb0ef41Sopenharmony_ci int* nameLimit, bool* overflow, 9781cb0ef41Sopenharmony_ci std::vector<InternalPropertyMirror>* properties) { 9791cb0ef41Sopenharmony_ci std::vector<InternalPropertyMirror> mirrors; 9801cb0ef41Sopenharmony_ci ValueMirror::getInternalProperties(context, object, &mirrors); 9811cb0ef41Sopenharmony_ci std::vector<String16> allowlist; 9821cb0ef41Sopenharmony_ci if (object->IsBooleanObject() || object->IsNumberObject() || 9831cb0ef41Sopenharmony_ci object->IsStringObject() || object->IsSymbolObject() || 9841cb0ef41Sopenharmony_ci object->IsBigIntObject()) { 9851cb0ef41Sopenharmony_ci allowlist.emplace_back("[[PrimitiveValue]]"); 9861cb0ef41Sopenharmony_ci } else if (object->IsPromise()) { 9871cb0ef41Sopenharmony_ci allowlist.emplace_back("[[PromiseState]]"); 9881cb0ef41Sopenharmony_ci allowlist.emplace_back("[[PromiseResult]]"); 9891cb0ef41Sopenharmony_ci } else if (object->IsGeneratorObject()) { 9901cb0ef41Sopenharmony_ci allowlist.emplace_back("[[GeneratorState]]"); 9911cb0ef41Sopenharmony_ci } 9921cb0ef41Sopenharmony_ci for (auto& mirror : mirrors) { 9931cb0ef41Sopenharmony_ci if (std::find(allowlist.begin(), allowlist.end(), mirror.name) == 9941cb0ef41Sopenharmony_ci allowlist.end()) { 9951cb0ef41Sopenharmony_ci continue; 9961cb0ef41Sopenharmony_ci } 9971cb0ef41Sopenharmony_ci if (!*nameLimit) { 9981cb0ef41Sopenharmony_ci *overflow = true; 9991cb0ef41Sopenharmony_ci return; 10001cb0ef41Sopenharmony_ci } 10011cb0ef41Sopenharmony_ci --*nameLimit; 10021cb0ef41Sopenharmony_ci properties->push_back(std::move(mirror)); 10031cb0ef41Sopenharmony_ci } 10041cb0ef41Sopenharmony_ci} 10051cb0ef41Sopenharmony_ci 10061cb0ef41Sopenharmony_civoid getPrivatePropertiesForPreview( 10071cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, v8::Local<v8::Object> object, 10081cb0ef41Sopenharmony_ci int* nameLimit, bool* overflow, 10091cb0ef41Sopenharmony_ci protocol::Array<PropertyPreview>* privateProperties) { 10101cb0ef41Sopenharmony_ci std::vector<PrivatePropertyMirror> mirrors = 10111cb0ef41Sopenharmony_ci ValueMirror::getPrivateProperties(context, object, 10121cb0ef41Sopenharmony_ci /* accessPropertiesOnly */ false); 10131cb0ef41Sopenharmony_ci for (auto& mirror : mirrors) { 10141cb0ef41Sopenharmony_ci std::unique_ptr<PropertyPreview> propertyPreview; 10151cb0ef41Sopenharmony_ci if (mirror.value) { 10161cb0ef41Sopenharmony_ci mirror.value->buildPropertyPreview(context, mirror.name, 10171cb0ef41Sopenharmony_ci &propertyPreview); 10181cb0ef41Sopenharmony_ci } else { 10191cb0ef41Sopenharmony_ci propertyPreview = PropertyPreview::create() 10201cb0ef41Sopenharmony_ci .setName(mirror.name) 10211cb0ef41Sopenharmony_ci .setType(PropertyPreview::TypeEnum::Accessor) 10221cb0ef41Sopenharmony_ci .build(); 10231cb0ef41Sopenharmony_ci } 10241cb0ef41Sopenharmony_ci if (!propertyPreview) continue; 10251cb0ef41Sopenharmony_ci if (!*nameLimit) { 10261cb0ef41Sopenharmony_ci *overflow = true; 10271cb0ef41Sopenharmony_ci return; 10281cb0ef41Sopenharmony_ci } 10291cb0ef41Sopenharmony_ci --*nameLimit; 10301cb0ef41Sopenharmony_ci privateProperties->emplace_back(std::move(propertyPreview)); 10311cb0ef41Sopenharmony_ci } 10321cb0ef41Sopenharmony_ci} 10331cb0ef41Sopenharmony_ci 10341cb0ef41Sopenharmony_ciclass ObjectMirror final : public ValueMirror { 10351cb0ef41Sopenharmony_ci public: 10361cb0ef41Sopenharmony_ci ObjectMirror(v8::Local<v8::Value> value, const String16& description) 10371cb0ef41Sopenharmony_ci : m_value(value.As<v8::Object>()), 10381cb0ef41Sopenharmony_ci m_description(description), 10391cb0ef41Sopenharmony_ci m_hasSubtype(false) {} 10401cb0ef41Sopenharmony_ci ObjectMirror(v8::Local<v8::Value> value, const String16& subtype, 10411cb0ef41Sopenharmony_ci const String16& description) 10421cb0ef41Sopenharmony_ci : m_value(value.As<v8::Object>()), 10431cb0ef41Sopenharmony_ci m_description(description), 10441cb0ef41Sopenharmony_ci m_hasSubtype(true), 10451cb0ef41Sopenharmony_ci m_subtype(subtype) {} 10461cb0ef41Sopenharmony_ci 10471cb0ef41Sopenharmony_ci v8::Local<v8::Value> v8Value() const override { return m_value; } 10481cb0ef41Sopenharmony_ci 10491cb0ef41Sopenharmony_ci Response buildRemoteObject( 10501cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, WrapMode mode, 10511cb0ef41Sopenharmony_ci std::unique_ptr<RemoteObject>* result) const override { 10521cb0ef41Sopenharmony_ci if (mode == WrapMode::kForceValue) { 10531cb0ef41Sopenharmony_ci std::unique_ptr<protocol::Value> protocolValue; 10541cb0ef41Sopenharmony_ci Response response = toProtocolValue(context, m_value, &protocolValue); 10551cb0ef41Sopenharmony_ci if (!response.IsSuccess()) return response; 10561cb0ef41Sopenharmony_ci *result = RemoteObject::create() 10571cb0ef41Sopenharmony_ci .setType(RemoteObject::TypeEnum::Object) 10581cb0ef41Sopenharmony_ci .setValue(std::move(protocolValue)) 10591cb0ef41Sopenharmony_ci .build(); 10601cb0ef41Sopenharmony_ci } else { 10611cb0ef41Sopenharmony_ci v8::Isolate* isolate = context->GetIsolate(); 10621cb0ef41Sopenharmony_ci *result = RemoteObject::create() 10631cb0ef41Sopenharmony_ci .setType(RemoteObject::TypeEnum::Object) 10641cb0ef41Sopenharmony_ci .setClassName(toProtocolString( 10651cb0ef41Sopenharmony_ci isolate, m_value->GetConstructorName())) 10661cb0ef41Sopenharmony_ci .setDescription(m_description) 10671cb0ef41Sopenharmony_ci .build(); 10681cb0ef41Sopenharmony_ci if (m_hasSubtype) (*result)->setSubtype(m_subtype); 10691cb0ef41Sopenharmony_ci if (mode == WrapMode::kWithPreview) { 10701cb0ef41Sopenharmony_ci std::unique_ptr<ObjectPreview> previewValue; 10711cb0ef41Sopenharmony_ci int nameLimit = 5; 10721cb0ef41Sopenharmony_ci int indexLimit = 100; 10731cb0ef41Sopenharmony_ci buildObjectPreview(context, false, &nameLimit, &indexLimit, 10741cb0ef41Sopenharmony_ci &previewValue); 10751cb0ef41Sopenharmony_ci (*result)->setPreview(std::move(previewValue)); 10761cb0ef41Sopenharmony_ci } 10771cb0ef41Sopenharmony_ci } 10781cb0ef41Sopenharmony_ci return Response::Success(); 10791cb0ef41Sopenharmony_ci } 10801cb0ef41Sopenharmony_ci 10811cb0ef41Sopenharmony_ci void buildObjectPreview( 10821cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, bool generatePreviewForTable, 10831cb0ef41Sopenharmony_ci int* nameLimit, int* indexLimit, 10841cb0ef41Sopenharmony_ci std::unique_ptr<ObjectPreview>* result) const override { 10851cb0ef41Sopenharmony_ci buildObjectPreviewInternal(context, false /* forEntry */, 10861cb0ef41Sopenharmony_ci generatePreviewForTable, nameLimit, indexLimit, 10871cb0ef41Sopenharmony_ci result); 10881cb0ef41Sopenharmony_ci } 10891cb0ef41Sopenharmony_ci 10901cb0ef41Sopenharmony_ci void buildEntryPreview( 10911cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, int* nameLimit, int* indexLimit, 10921cb0ef41Sopenharmony_ci std::unique_ptr<ObjectPreview>* result) const override { 10931cb0ef41Sopenharmony_ci buildObjectPreviewInternal(context, true /* forEntry */, 10941cb0ef41Sopenharmony_ci false /* generatePreviewForTable */, nameLimit, 10951cb0ef41Sopenharmony_ci indexLimit, result); 10961cb0ef41Sopenharmony_ci } 10971cb0ef41Sopenharmony_ci 10981cb0ef41Sopenharmony_ci void buildPropertyPreview( 10991cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, const String16& name, 11001cb0ef41Sopenharmony_ci std::unique_ptr<PropertyPreview>* result) const override { 11011cb0ef41Sopenharmony_ci *result = PropertyPreview::create() 11021cb0ef41Sopenharmony_ci .setName(name) 11031cb0ef41Sopenharmony_ci .setType(RemoteObject::TypeEnum::Object) 11041cb0ef41Sopenharmony_ci .setValue(abbreviateString( 11051cb0ef41Sopenharmony_ci m_description, 11061cb0ef41Sopenharmony_ci m_subtype == RemoteObject::SubtypeEnum::Regexp ? kMiddle 11071cb0ef41Sopenharmony_ci : kEnd)) 11081cb0ef41Sopenharmony_ci .build(); 11091cb0ef41Sopenharmony_ci if (m_hasSubtype) (*result)->setSubtype(m_subtype); 11101cb0ef41Sopenharmony_ci } 11111cb0ef41Sopenharmony_ci 11121cb0ef41Sopenharmony_ci protocol::Response buildWebDriverValue( 11131cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, int max_depth, 11141cb0ef41Sopenharmony_ci std::unique_ptr<protocol::Runtime::WebDriverValue>* result) 11151cb0ef41Sopenharmony_ci const override { 11161cb0ef41Sopenharmony_ci // https://w3c.github.io/webdriver-bidi/#data-types-protocolValue-RemoteValue-serialization 11171cb0ef41Sopenharmony_ci 11181cb0ef41Sopenharmony_ci // Check if embedder implemented custom serialization. 11191cb0ef41Sopenharmony_ci std::unique_ptr<v8_inspector::WebDriverValue> embedder_serialized_result = 11201cb0ef41Sopenharmony_ci clientFor(context)->serializeToWebDriverValue(m_value, max_depth); 11211cb0ef41Sopenharmony_ci 11221cb0ef41Sopenharmony_ci if (embedder_serialized_result) { 11231cb0ef41Sopenharmony_ci // Embedder-implemented serialization. 11241cb0ef41Sopenharmony_ci *result = protocol::Runtime::WebDriverValue::create() 11251cb0ef41Sopenharmony_ci .setType(toString16(embedder_serialized_result->type)) 11261cb0ef41Sopenharmony_ci .build(); 11271cb0ef41Sopenharmony_ci 11281cb0ef41Sopenharmony_ci if (!embedder_serialized_result->value.IsEmpty()) { 11291cb0ef41Sopenharmony_ci // Embedder-implemented serialization has value. 11301cb0ef41Sopenharmony_ci std::unique_ptr<protocol::Value> protocol_value; 11311cb0ef41Sopenharmony_ci Response response = toProtocolValue( 11321cb0ef41Sopenharmony_ci context, embedder_serialized_result->value.ToLocalChecked(), 11331cb0ef41Sopenharmony_ci &protocol_value); 11341cb0ef41Sopenharmony_ci if (!response.IsSuccess()) return response; 11351cb0ef41Sopenharmony_ci 11361cb0ef41Sopenharmony_ci (*result)->setValue(std::move(protocol_value)); 11371cb0ef41Sopenharmony_ci } 11381cb0ef41Sopenharmony_ci return Response::Success(); 11391cb0ef41Sopenharmony_ci } 11401cb0ef41Sopenharmony_ci 11411cb0ef41Sopenharmony_ci // No embedder-implemented serialization. Serialize as V8 Object. 11421cb0ef41Sopenharmony_ci Response response = V8WebDriverSerializer::serializeV8Value( 11431cb0ef41Sopenharmony_ci m_value, context, max_depth, result); 11441cb0ef41Sopenharmony_ci return response; 11451cb0ef41Sopenharmony_ci } 11461cb0ef41Sopenharmony_ci 11471cb0ef41Sopenharmony_ci private: 11481cb0ef41Sopenharmony_ci void buildObjectPreviewInternal( 11491cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, bool forEntry, 11501cb0ef41Sopenharmony_ci bool generatePreviewForTable, int* nameLimit, int* indexLimit, 11511cb0ef41Sopenharmony_ci std::unique_ptr<ObjectPreview>* result) const { 11521cb0ef41Sopenharmony_ci auto properties = std::make_unique<protocol::Array<PropertyPreview>>(); 11531cb0ef41Sopenharmony_ci std::unique_ptr<protocol::Array<EntryPreview>> entriesPreview; 11541cb0ef41Sopenharmony_ci bool overflow = false; 11551cb0ef41Sopenharmony_ci 11561cb0ef41Sopenharmony_ci v8::Local<v8::Value> value = m_value; 11571cb0ef41Sopenharmony_ci while (value->IsProxy()) value = value.As<v8::Proxy>()->GetTarget(); 11581cb0ef41Sopenharmony_ci 11591cb0ef41Sopenharmony_ci if (value->IsObject() && !value->IsProxy()) { 11601cb0ef41Sopenharmony_ci v8::Local<v8::Object> objectForPreview = value.As<v8::Object>(); 11611cb0ef41Sopenharmony_ci std::vector<InternalPropertyMirror> internalProperties; 11621cb0ef41Sopenharmony_ci getInternalPropertiesForPreview(context, objectForPreview, nameLimit, 11631cb0ef41Sopenharmony_ci &overflow, &internalProperties); 11641cb0ef41Sopenharmony_ci for (size_t i = 0; i < internalProperties.size(); ++i) { 11651cb0ef41Sopenharmony_ci std::unique_ptr<PropertyPreview> propertyPreview; 11661cb0ef41Sopenharmony_ci internalProperties[i].value->buildPropertyPreview( 11671cb0ef41Sopenharmony_ci context, internalProperties[i].name, &propertyPreview); 11681cb0ef41Sopenharmony_ci if (propertyPreview) { 11691cb0ef41Sopenharmony_ci properties->emplace_back(std::move(propertyPreview)); 11701cb0ef41Sopenharmony_ci } 11711cb0ef41Sopenharmony_ci } 11721cb0ef41Sopenharmony_ci 11731cb0ef41Sopenharmony_ci getPrivatePropertiesForPreview(context, objectForPreview, nameLimit, 11741cb0ef41Sopenharmony_ci &overflow, properties.get()); 11751cb0ef41Sopenharmony_ci 11761cb0ef41Sopenharmony_ci std::vector<PropertyMirror> mirrors; 11771cb0ef41Sopenharmony_ci if (getPropertiesForPreview(context, objectForPreview, nameLimit, 11781cb0ef41Sopenharmony_ci indexLimit, &overflow, &mirrors)) { 11791cb0ef41Sopenharmony_ci for (size_t i = 0; i < mirrors.size(); ++i) { 11801cb0ef41Sopenharmony_ci std::unique_ptr<PropertyPreview> preview; 11811cb0ef41Sopenharmony_ci std::unique_ptr<ObjectPreview> valuePreview; 11821cb0ef41Sopenharmony_ci if (mirrors[i].value) { 11831cb0ef41Sopenharmony_ci mirrors[i].value->buildPropertyPreview(context, mirrors[i].name, 11841cb0ef41Sopenharmony_ci &preview); 11851cb0ef41Sopenharmony_ci if (generatePreviewForTable) { 11861cb0ef41Sopenharmony_ci int tableLimit = 1000; 11871cb0ef41Sopenharmony_ci mirrors[i].value->buildObjectPreview(context, false, &tableLimit, 11881cb0ef41Sopenharmony_ci &tableLimit, &valuePreview); 11891cb0ef41Sopenharmony_ci } 11901cb0ef41Sopenharmony_ci } else { 11911cb0ef41Sopenharmony_ci preview = PropertyPreview::create() 11921cb0ef41Sopenharmony_ci .setName(mirrors[i].name) 11931cb0ef41Sopenharmony_ci .setType(PropertyPreview::TypeEnum::Accessor) 11941cb0ef41Sopenharmony_ci .build(); 11951cb0ef41Sopenharmony_ci } 11961cb0ef41Sopenharmony_ci if (valuePreview) { 11971cb0ef41Sopenharmony_ci preview->setValuePreview(std::move(valuePreview)); 11981cb0ef41Sopenharmony_ci } 11991cb0ef41Sopenharmony_ci properties->emplace_back(std::move(preview)); 12001cb0ef41Sopenharmony_ci } 12011cb0ef41Sopenharmony_ci } 12021cb0ef41Sopenharmony_ci 12031cb0ef41Sopenharmony_ci std::vector<EntryMirror> entries; 12041cb0ef41Sopenharmony_ci if (EntryMirror::getEntries(context, objectForPreview, 5, &overflow, 12051cb0ef41Sopenharmony_ci &entries)) { 12061cb0ef41Sopenharmony_ci if (forEntry) { 12071cb0ef41Sopenharmony_ci overflow = true; 12081cb0ef41Sopenharmony_ci } else { 12091cb0ef41Sopenharmony_ci entriesPreview = std::make_unique<protocol::Array<EntryPreview>>(); 12101cb0ef41Sopenharmony_ci for (const auto& entry : entries) { 12111cb0ef41Sopenharmony_ci std::unique_ptr<ObjectPreview> valuePreview; 12121cb0ef41Sopenharmony_ci entry.value->buildEntryPreview(context, nameLimit, indexLimit, 12131cb0ef41Sopenharmony_ci &valuePreview); 12141cb0ef41Sopenharmony_ci if (!valuePreview) continue; 12151cb0ef41Sopenharmony_ci std::unique_ptr<ObjectPreview> keyPreview; 12161cb0ef41Sopenharmony_ci if (entry.key) { 12171cb0ef41Sopenharmony_ci entry.key->buildEntryPreview(context, nameLimit, indexLimit, 12181cb0ef41Sopenharmony_ci &keyPreview); 12191cb0ef41Sopenharmony_ci if (!keyPreview) continue; 12201cb0ef41Sopenharmony_ci } 12211cb0ef41Sopenharmony_ci std::unique_ptr<EntryPreview> entryPreview = 12221cb0ef41Sopenharmony_ci EntryPreview::create() 12231cb0ef41Sopenharmony_ci .setValue(std::move(valuePreview)) 12241cb0ef41Sopenharmony_ci .build(); 12251cb0ef41Sopenharmony_ci if (keyPreview) entryPreview->setKey(std::move(keyPreview)); 12261cb0ef41Sopenharmony_ci entriesPreview->emplace_back(std::move(entryPreview)); 12271cb0ef41Sopenharmony_ci } 12281cb0ef41Sopenharmony_ci } 12291cb0ef41Sopenharmony_ci } 12301cb0ef41Sopenharmony_ci } 12311cb0ef41Sopenharmony_ci *result = ObjectPreview::create() 12321cb0ef41Sopenharmony_ci .setType(RemoteObject::TypeEnum::Object) 12331cb0ef41Sopenharmony_ci .setDescription(m_description) 12341cb0ef41Sopenharmony_ci .setOverflow(overflow) 12351cb0ef41Sopenharmony_ci .setProperties(std::move(properties)) 12361cb0ef41Sopenharmony_ci .build(); 12371cb0ef41Sopenharmony_ci if (m_hasSubtype) (*result)->setSubtype(m_subtype); 12381cb0ef41Sopenharmony_ci if (entriesPreview) (*result)->setEntries(std::move(entriesPreview)); 12391cb0ef41Sopenharmony_ci } 12401cb0ef41Sopenharmony_ci 12411cb0ef41Sopenharmony_ci v8::Local<v8::Object> m_value; 12421cb0ef41Sopenharmony_ci String16 m_description; 12431cb0ef41Sopenharmony_ci bool m_hasSubtype; 12441cb0ef41Sopenharmony_ci String16 m_subtype; 12451cb0ef41Sopenharmony_ci}; 12461cb0ef41Sopenharmony_ci 12471cb0ef41Sopenharmony_civoid nativeGetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info) { 12481cb0ef41Sopenharmony_ci v8::Local<v8::Object> data = info.Data().As<v8::Object>(); 12491cb0ef41Sopenharmony_ci v8::Isolate* isolate = info.GetIsolate(); 12501cb0ef41Sopenharmony_ci v8::Local<v8::Context> context = isolate->GetCurrentContext(); 12511cb0ef41Sopenharmony_ci v8::Local<v8::Value> name; 12521cb0ef41Sopenharmony_ci if (!data->GetRealNamedProperty(context, toV8String(isolate, "name")) 12531cb0ef41Sopenharmony_ci .ToLocal(&name)) { 12541cb0ef41Sopenharmony_ci return; 12551cb0ef41Sopenharmony_ci } 12561cb0ef41Sopenharmony_ci v8::Local<v8::Value> object; 12571cb0ef41Sopenharmony_ci if (!data->GetRealNamedProperty(context, toV8String(isolate, "object")) 12581cb0ef41Sopenharmony_ci .ToLocal(&object) || 12591cb0ef41Sopenharmony_ci !object->IsObject()) { 12601cb0ef41Sopenharmony_ci return; 12611cb0ef41Sopenharmony_ci } 12621cb0ef41Sopenharmony_ci v8::Local<v8::Value> value; 12631cb0ef41Sopenharmony_ci if (!object.As<v8::Object>()->Get(context, name).ToLocal(&value)) return; 12641cb0ef41Sopenharmony_ci info.GetReturnValue().Set(value); 12651cb0ef41Sopenharmony_ci} 12661cb0ef41Sopenharmony_ci 12671cb0ef41Sopenharmony_cistd::unique_ptr<ValueMirror> createNativeGetter(v8::Local<v8::Context> context, 12681cb0ef41Sopenharmony_ci v8::Local<v8::Value> object, 12691cb0ef41Sopenharmony_ci v8::Local<v8::Name> name) { 12701cb0ef41Sopenharmony_ci v8::Isolate* isolate = context->GetIsolate(); 12711cb0ef41Sopenharmony_ci v8::TryCatch tryCatch(isolate); 12721cb0ef41Sopenharmony_ci 12731cb0ef41Sopenharmony_ci v8::Local<v8::Object> data = v8::Object::New(isolate); 12741cb0ef41Sopenharmony_ci if (data->Set(context, toV8String(isolate, "name"), name).IsNothing()) { 12751cb0ef41Sopenharmony_ci return nullptr; 12761cb0ef41Sopenharmony_ci } 12771cb0ef41Sopenharmony_ci if (data->Set(context, toV8String(isolate, "object"), object).IsNothing()) { 12781cb0ef41Sopenharmony_ci return nullptr; 12791cb0ef41Sopenharmony_ci } 12801cb0ef41Sopenharmony_ci 12811cb0ef41Sopenharmony_ci v8::Local<v8::Function> function; 12821cb0ef41Sopenharmony_ci if (!v8::Function::New(context, nativeGetterCallback, data, 0, 12831cb0ef41Sopenharmony_ci v8::ConstructorBehavior::kThrow) 12841cb0ef41Sopenharmony_ci .ToLocal(&function)) { 12851cb0ef41Sopenharmony_ci return nullptr; 12861cb0ef41Sopenharmony_ci } 12871cb0ef41Sopenharmony_ci return ValueMirror::create(context, function); 12881cb0ef41Sopenharmony_ci} 12891cb0ef41Sopenharmony_ci 12901cb0ef41Sopenharmony_civoid nativeSetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info) { 12911cb0ef41Sopenharmony_ci if (info.Length() < 1) return; 12921cb0ef41Sopenharmony_ci v8::Local<v8::Object> data = info.Data().As<v8::Object>(); 12931cb0ef41Sopenharmony_ci v8::Isolate* isolate = info.GetIsolate(); 12941cb0ef41Sopenharmony_ci v8::Local<v8::Context> context = isolate->GetCurrentContext(); 12951cb0ef41Sopenharmony_ci v8::Local<v8::Value> name; 12961cb0ef41Sopenharmony_ci if (!data->GetRealNamedProperty(context, toV8String(isolate, "name")) 12971cb0ef41Sopenharmony_ci .ToLocal(&name)) { 12981cb0ef41Sopenharmony_ci return; 12991cb0ef41Sopenharmony_ci } 13001cb0ef41Sopenharmony_ci v8::Local<v8::Value> object; 13011cb0ef41Sopenharmony_ci if (!data->GetRealNamedProperty(context, toV8String(isolate, "object")) 13021cb0ef41Sopenharmony_ci .ToLocal(&object) || 13031cb0ef41Sopenharmony_ci !object->IsObject()) { 13041cb0ef41Sopenharmony_ci return; 13051cb0ef41Sopenharmony_ci } 13061cb0ef41Sopenharmony_ci v8::Local<v8::Value> value; 13071cb0ef41Sopenharmony_ci if (!object.As<v8::Object>()->Set(context, name, info[0]).IsNothing()) return; 13081cb0ef41Sopenharmony_ci} 13091cb0ef41Sopenharmony_ci 13101cb0ef41Sopenharmony_cistd::unique_ptr<ValueMirror> createNativeSetter(v8::Local<v8::Context> context, 13111cb0ef41Sopenharmony_ci v8::Local<v8::Value> object, 13121cb0ef41Sopenharmony_ci v8::Local<v8::Name> name) { 13131cb0ef41Sopenharmony_ci v8::Isolate* isolate = context->GetIsolate(); 13141cb0ef41Sopenharmony_ci v8::TryCatch tryCatch(isolate); 13151cb0ef41Sopenharmony_ci 13161cb0ef41Sopenharmony_ci v8::Local<v8::Object> data = v8::Object::New(isolate); 13171cb0ef41Sopenharmony_ci if (data->Set(context, toV8String(isolate, "name"), name).IsNothing()) { 13181cb0ef41Sopenharmony_ci return nullptr; 13191cb0ef41Sopenharmony_ci } 13201cb0ef41Sopenharmony_ci if (data->Set(context, toV8String(isolate, "object"), object).IsNothing()) { 13211cb0ef41Sopenharmony_ci return nullptr; 13221cb0ef41Sopenharmony_ci } 13231cb0ef41Sopenharmony_ci 13241cb0ef41Sopenharmony_ci v8::Local<v8::Function> function; 13251cb0ef41Sopenharmony_ci if (!v8::Function::New(context, nativeSetterCallback, data, 1, 13261cb0ef41Sopenharmony_ci v8::ConstructorBehavior::kThrow) 13271cb0ef41Sopenharmony_ci .ToLocal(&function)) { 13281cb0ef41Sopenharmony_ci return nullptr; 13291cb0ef41Sopenharmony_ci } 13301cb0ef41Sopenharmony_ci return ValueMirror::create(context, function); 13311cb0ef41Sopenharmony_ci} 13321cb0ef41Sopenharmony_ci 13331cb0ef41Sopenharmony_cibool doesAttributeHaveObservableSideEffectOnGet(v8::Local<v8::Context> context, 13341cb0ef41Sopenharmony_ci v8::Local<v8::Object> object, 13351cb0ef41Sopenharmony_ci v8::Local<v8::Name> name) { 13361cb0ef41Sopenharmony_ci // TODO(dgozman): we should remove this, annotate more embedder properties as 13371cb0ef41Sopenharmony_ci // side-effect free, and call all getters which do not produce side effects. 13381cb0ef41Sopenharmony_ci if (!name->IsString()) return false; 13391cb0ef41Sopenharmony_ci v8::Isolate* isolate = context->GetIsolate(); 13401cb0ef41Sopenharmony_ci if (!name.As<v8::String>()->StringEquals(toV8String(isolate, "body"))) { 13411cb0ef41Sopenharmony_ci return false; 13421cb0ef41Sopenharmony_ci } 13431cb0ef41Sopenharmony_ci 13441cb0ef41Sopenharmony_ci v8::TryCatch tryCatch(isolate); 13451cb0ef41Sopenharmony_ci v8::Local<v8::Value> request; 13461cb0ef41Sopenharmony_ci if (context->Global() 13471cb0ef41Sopenharmony_ci ->GetRealNamedProperty(context, toV8String(isolate, "Request")) 13481cb0ef41Sopenharmony_ci .ToLocal(&request)) { 13491cb0ef41Sopenharmony_ci if (request->IsObject() && 13501cb0ef41Sopenharmony_ci object->InstanceOf(context, request.As<v8::Object>()) 13511cb0ef41Sopenharmony_ci .FromMaybe(false)) { 13521cb0ef41Sopenharmony_ci return true; 13531cb0ef41Sopenharmony_ci } 13541cb0ef41Sopenharmony_ci } 13551cb0ef41Sopenharmony_ci if (tryCatch.HasCaught()) tryCatch.Reset(); 13561cb0ef41Sopenharmony_ci 13571cb0ef41Sopenharmony_ci v8::Local<v8::Value> response; 13581cb0ef41Sopenharmony_ci if (context->Global() 13591cb0ef41Sopenharmony_ci ->GetRealNamedProperty(context, toV8String(isolate, "Response")) 13601cb0ef41Sopenharmony_ci .ToLocal(&response)) { 13611cb0ef41Sopenharmony_ci if (response->IsObject() && 13621cb0ef41Sopenharmony_ci object->InstanceOf(context, response.As<v8::Object>()) 13631cb0ef41Sopenharmony_ci .FromMaybe(false)) { 13641cb0ef41Sopenharmony_ci return true; 13651cb0ef41Sopenharmony_ci } 13661cb0ef41Sopenharmony_ci } 13671cb0ef41Sopenharmony_ci return false; 13681cb0ef41Sopenharmony_ci} 13691cb0ef41Sopenharmony_ci 13701cb0ef41Sopenharmony_ci} // anonymous namespace 13711cb0ef41Sopenharmony_ci 13721cb0ef41Sopenharmony_ciValueMirror::~ValueMirror() = default; 13731cb0ef41Sopenharmony_ci 13741cb0ef41Sopenharmony_ci// static 13751cb0ef41Sopenharmony_cibool ValueMirror::getProperties(v8::Local<v8::Context> context, 13761cb0ef41Sopenharmony_ci v8::Local<v8::Object> object, 13771cb0ef41Sopenharmony_ci bool ownProperties, bool accessorPropertiesOnly, 13781cb0ef41Sopenharmony_ci bool nonIndexedPropertiesOnly, 13791cb0ef41Sopenharmony_ci PropertyAccumulator* accumulator) { 13801cb0ef41Sopenharmony_ci v8::Isolate* isolate = context->GetIsolate(); 13811cb0ef41Sopenharmony_ci v8::TryCatch tryCatch(isolate); 13821cb0ef41Sopenharmony_ci v8::Local<v8::Set> set = v8::Set::New(isolate); 13831cb0ef41Sopenharmony_ci 13841cb0ef41Sopenharmony_ci v8::MicrotasksScope microtasksScope(isolate, 13851cb0ef41Sopenharmony_ci v8::MicrotasksScope::kDoNotRunMicrotasks); 13861cb0ef41Sopenharmony_ci V8InternalValueType internalType = v8InternalValueTypeFrom(context, object); 13871cb0ef41Sopenharmony_ci if (internalType == V8InternalValueType::kScope) { 13881cb0ef41Sopenharmony_ci v8::Local<v8::Value> value; 13891cb0ef41Sopenharmony_ci if (!object->Get(context, toV8String(isolate, "object")).ToLocal(&value) || 13901cb0ef41Sopenharmony_ci !value->IsObject()) { 13911cb0ef41Sopenharmony_ci return false; 13921cb0ef41Sopenharmony_ci } else { 13931cb0ef41Sopenharmony_ci object = value.As<v8::Object>(); 13941cb0ef41Sopenharmony_ci } 13951cb0ef41Sopenharmony_ci } 13961cb0ef41Sopenharmony_ci if (internalType == V8InternalValueType::kScopeList) { 13971cb0ef41Sopenharmony_ci if (!set->Add(context, toV8String(isolate, "length")).ToLocal(&set)) { 13981cb0ef41Sopenharmony_ci return false; 13991cb0ef41Sopenharmony_ci } 14001cb0ef41Sopenharmony_ci } 14011cb0ef41Sopenharmony_ci 14021cb0ef41Sopenharmony_ci auto iterator = v8::debug::PropertyIterator::Create(context, object, 14031cb0ef41Sopenharmony_ci nonIndexedPropertiesOnly); 14041cb0ef41Sopenharmony_ci if (!iterator) { 14051cb0ef41Sopenharmony_ci CHECK(tryCatch.HasCaught()); 14061cb0ef41Sopenharmony_ci return false; 14071cb0ef41Sopenharmony_ci } 14081cb0ef41Sopenharmony_ci while (!iterator->Done()) { 14091cb0ef41Sopenharmony_ci bool isOwn = iterator->is_own(); 14101cb0ef41Sopenharmony_ci if (!isOwn && ownProperties) break; 14111cb0ef41Sopenharmony_ci v8::Local<v8::Name> v8Name = iterator->name(); 14121cb0ef41Sopenharmony_ci v8::Maybe<bool> result = set->Has(context, v8Name); 14131cb0ef41Sopenharmony_ci if (result.IsNothing()) return false; 14141cb0ef41Sopenharmony_ci if (result.FromJust()) { 14151cb0ef41Sopenharmony_ci if (!iterator->Advance().FromMaybe(false)) { 14161cb0ef41Sopenharmony_ci CHECK(tryCatch.HasCaught()); 14171cb0ef41Sopenharmony_ci return false; 14181cb0ef41Sopenharmony_ci } 14191cb0ef41Sopenharmony_ci continue; 14201cb0ef41Sopenharmony_ci } 14211cb0ef41Sopenharmony_ci if (!set->Add(context, v8Name).ToLocal(&set)) return false; 14221cb0ef41Sopenharmony_ci 14231cb0ef41Sopenharmony_ci String16 name; 14241cb0ef41Sopenharmony_ci std::unique_ptr<ValueMirror> symbolMirror; 14251cb0ef41Sopenharmony_ci if (v8Name->IsString()) { 14261cb0ef41Sopenharmony_ci name = toProtocolString(isolate, v8Name.As<v8::String>()); 14271cb0ef41Sopenharmony_ci } else { 14281cb0ef41Sopenharmony_ci v8::Local<v8::Symbol> symbol = v8Name.As<v8::Symbol>(); 14291cb0ef41Sopenharmony_ci name = descriptionForSymbol(context, symbol); 14301cb0ef41Sopenharmony_ci symbolMirror = ValueMirror::create(context, symbol); 14311cb0ef41Sopenharmony_ci } 14321cb0ef41Sopenharmony_ci 14331cb0ef41Sopenharmony_ci v8::PropertyAttribute attributes; 14341cb0ef41Sopenharmony_ci std::unique_ptr<ValueMirror> valueMirror; 14351cb0ef41Sopenharmony_ci std::unique_ptr<ValueMirror> getterMirror; 14361cb0ef41Sopenharmony_ci std::unique_ptr<ValueMirror> setterMirror; 14371cb0ef41Sopenharmony_ci std::unique_ptr<ValueMirror> exceptionMirror; 14381cb0ef41Sopenharmony_ci bool writable = false; 14391cb0ef41Sopenharmony_ci bool enumerable = false; 14401cb0ef41Sopenharmony_ci bool configurable = false; 14411cb0ef41Sopenharmony_ci 14421cb0ef41Sopenharmony_ci bool isAccessorProperty = false; 14431cb0ef41Sopenharmony_ci v8::TryCatch tryCatchAttributes(isolate); 14441cb0ef41Sopenharmony_ci if (!iterator->attributes().To(&attributes)) { 14451cb0ef41Sopenharmony_ci exceptionMirror = 14461cb0ef41Sopenharmony_ci ValueMirror::create(context, tryCatchAttributes.Exception()); 14471cb0ef41Sopenharmony_ci } else { 14481cb0ef41Sopenharmony_ci if (iterator->is_native_accessor()) { 14491cb0ef41Sopenharmony_ci if (iterator->has_native_getter()) { 14501cb0ef41Sopenharmony_ci getterMirror = createNativeGetter(context, object, v8Name); 14511cb0ef41Sopenharmony_ci } 14521cb0ef41Sopenharmony_ci if (iterator->has_native_setter()) { 14531cb0ef41Sopenharmony_ci setterMirror = createNativeSetter(context, object, v8Name); 14541cb0ef41Sopenharmony_ci } 14551cb0ef41Sopenharmony_ci writable = !(attributes & v8::PropertyAttribute::ReadOnly); 14561cb0ef41Sopenharmony_ci enumerable = !(attributes & v8::PropertyAttribute::DontEnum); 14571cb0ef41Sopenharmony_ci configurable = !(attributes & v8::PropertyAttribute::DontDelete); 14581cb0ef41Sopenharmony_ci isAccessorProperty = getterMirror || setterMirror; 14591cb0ef41Sopenharmony_ci } else { 14601cb0ef41Sopenharmony_ci v8::TryCatch tryCatchDescriptor(isolate); 14611cb0ef41Sopenharmony_ci v8::debug::PropertyDescriptor descriptor; 14621cb0ef41Sopenharmony_ci if (!iterator->descriptor().To(&descriptor)) { 14631cb0ef41Sopenharmony_ci exceptionMirror = 14641cb0ef41Sopenharmony_ci ValueMirror::create(context, tryCatchDescriptor.Exception()); 14651cb0ef41Sopenharmony_ci } else { 14661cb0ef41Sopenharmony_ci writable = descriptor.has_writable ? descriptor.writable : false; 14671cb0ef41Sopenharmony_ci enumerable = 14681cb0ef41Sopenharmony_ci descriptor.has_enumerable ? descriptor.enumerable : false; 14691cb0ef41Sopenharmony_ci configurable = 14701cb0ef41Sopenharmony_ci descriptor.has_configurable ? descriptor.configurable : false; 14711cb0ef41Sopenharmony_ci if (!descriptor.value.IsEmpty()) { 14721cb0ef41Sopenharmony_ci valueMirror = ValueMirror::create(context, descriptor.value); 14731cb0ef41Sopenharmony_ci } 14741cb0ef41Sopenharmony_ci v8::Local<v8::Function> getterFunction; 14751cb0ef41Sopenharmony_ci if (!descriptor.get.IsEmpty()) { 14761cb0ef41Sopenharmony_ci v8::Local<v8::Value> get = descriptor.get; 14771cb0ef41Sopenharmony_ci getterMirror = ValueMirror::create(context, get); 14781cb0ef41Sopenharmony_ci if (get->IsFunction()) getterFunction = get.As<v8::Function>(); 14791cb0ef41Sopenharmony_ci } 14801cb0ef41Sopenharmony_ci if (!descriptor.set.IsEmpty()) { 14811cb0ef41Sopenharmony_ci setterMirror = ValueMirror::create(context, descriptor.set); 14821cb0ef41Sopenharmony_ci } 14831cb0ef41Sopenharmony_ci isAccessorProperty = getterMirror || setterMirror; 14841cb0ef41Sopenharmony_ci if (name != "__proto__" && !getterFunction.IsEmpty() && 14851cb0ef41Sopenharmony_ci getterFunction->ScriptId() == v8::UnboundScript::kNoScriptId && 14861cb0ef41Sopenharmony_ci !doesAttributeHaveObservableSideEffectOnGet(context, object, 14871cb0ef41Sopenharmony_ci v8Name)) { 14881cb0ef41Sopenharmony_ci v8::TryCatch tryCatchFunction(isolate); 14891cb0ef41Sopenharmony_ci v8::Local<v8::Value> value; 14901cb0ef41Sopenharmony_ci if (object->Get(context, v8Name).ToLocal(&value)) { 14911cb0ef41Sopenharmony_ci if (value->IsPromise() && 14921cb0ef41Sopenharmony_ci value.As<v8::Promise>()->State() == v8::Promise::kRejected) { 14931cb0ef41Sopenharmony_ci value.As<v8::Promise>()->MarkAsHandled(); 14941cb0ef41Sopenharmony_ci } else { 14951cb0ef41Sopenharmony_ci valueMirror = ValueMirror::create(context, value); 14961cb0ef41Sopenharmony_ci setterMirror = nullptr; 14971cb0ef41Sopenharmony_ci getterMirror = nullptr; 14981cb0ef41Sopenharmony_ci } 14991cb0ef41Sopenharmony_ci } 15001cb0ef41Sopenharmony_ci } 15011cb0ef41Sopenharmony_ci } 15021cb0ef41Sopenharmony_ci } 15031cb0ef41Sopenharmony_ci } 15041cb0ef41Sopenharmony_ci if (accessorPropertiesOnly && !isAccessorProperty) continue; 15051cb0ef41Sopenharmony_ci auto mirror = PropertyMirror{name, 15061cb0ef41Sopenharmony_ci writable, 15071cb0ef41Sopenharmony_ci configurable, 15081cb0ef41Sopenharmony_ci enumerable, 15091cb0ef41Sopenharmony_ci isOwn, 15101cb0ef41Sopenharmony_ci iterator->is_array_index(), 15111cb0ef41Sopenharmony_ci isAccessorProperty && valueMirror, 15121cb0ef41Sopenharmony_ci std::move(valueMirror), 15131cb0ef41Sopenharmony_ci std::move(getterMirror), 15141cb0ef41Sopenharmony_ci std::move(setterMirror), 15151cb0ef41Sopenharmony_ci std::move(symbolMirror), 15161cb0ef41Sopenharmony_ci std::move(exceptionMirror)}; 15171cb0ef41Sopenharmony_ci if (!accumulator->Add(std::move(mirror))) return true; 15181cb0ef41Sopenharmony_ci 15191cb0ef41Sopenharmony_ci if (!iterator->Advance().FromMaybe(false)) { 15201cb0ef41Sopenharmony_ci CHECK(tryCatch.HasCaught()); 15211cb0ef41Sopenharmony_ci return false; 15221cb0ef41Sopenharmony_ci } 15231cb0ef41Sopenharmony_ci } 15241cb0ef41Sopenharmony_ci return true; 15251cb0ef41Sopenharmony_ci} 15261cb0ef41Sopenharmony_ci 15271cb0ef41Sopenharmony_ci// static 15281cb0ef41Sopenharmony_civoid ValueMirror::getInternalProperties( 15291cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, v8::Local<v8::Object> object, 15301cb0ef41Sopenharmony_ci std::vector<InternalPropertyMirror>* mirrors) { 15311cb0ef41Sopenharmony_ci v8::Isolate* isolate = context->GetIsolate(); 15321cb0ef41Sopenharmony_ci v8::MicrotasksScope microtasksScope(isolate, 15331cb0ef41Sopenharmony_ci v8::MicrotasksScope::kDoNotRunMicrotasks); 15341cb0ef41Sopenharmony_ci v8::TryCatch tryCatch(isolate); 15351cb0ef41Sopenharmony_ci if (object->IsFunction()) { 15361cb0ef41Sopenharmony_ci v8::Local<v8::Function> function = object.As<v8::Function>(); 15371cb0ef41Sopenharmony_ci auto location = LocationMirror::create(function); 15381cb0ef41Sopenharmony_ci if (location) { 15391cb0ef41Sopenharmony_ci mirrors->emplace_back(InternalPropertyMirror{ 15401cb0ef41Sopenharmony_ci String16("[[FunctionLocation]]"), std::move(location)}); 15411cb0ef41Sopenharmony_ci } 15421cb0ef41Sopenharmony_ci if (function->IsGeneratorFunction()) { 15431cb0ef41Sopenharmony_ci mirrors->emplace_back(InternalPropertyMirror{ 15441cb0ef41Sopenharmony_ci String16("[[IsGenerator]]"), 15451cb0ef41Sopenharmony_ci ValueMirror::create(context, v8::True(context->GetIsolate()))}); 15461cb0ef41Sopenharmony_ci } 15471cb0ef41Sopenharmony_ci } 15481cb0ef41Sopenharmony_ci if (object->IsGeneratorObject()) { 15491cb0ef41Sopenharmony_ci auto location = LocationMirror::createForGenerator(object); 15501cb0ef41Sopenharmony_ci if (location) { 15511cb0ef41Sopenharmony_ci mirrors->emplace_back(InternalPropertyMirror{ 15521cb0ef41Sopenharmony_ci String16("[[GeneratorLocation]]"), std::move(location)}); 15531cb0ef41Sopenharmony_ci } 15541cb0ef41Sopenharmony_ci } 15551cb0ef41Sopenharmony_ci V8Debugger* debugger = 15561cb0ef41Sopenharmony_ci static_cast<V8InspectorImpl*>(v8::debug::GetInspector(isolate)) 15571cb0ef41Sopenharmony_ci ->debugger(); 15581cb0ef41Sopenharmony_ci v8::Local<v8::Array> properties; 15591cb0ef41Sopenharmony_ci if (debugger->internalProperties(context, object).ToLocal(&properties)) { 15601cb0ef41Sopenharmony_ci for (uint32_t i = 0; i < properties->Length(); i += 2) { 15611cb0ef41Sopenharmony_ci v8::Local<v8::Value> name; 15621cb0ef41Sopenharmony_ci if (!properties->Get(context, i).ToLocal(&name) || !name->IsString()) { 15631cb0ef41Sopenharmony_ci tryCatch.Reset(); 15641cb0ef41Sopenharmony_ci continue; 15651cb0ef41Sopenharmony_ci } 15661cb0ef41Sopenharmony_ci v8::Local<v8::Value> value; 15671cb0ef41Sopenharmony_ci if (!properties->Get(context, i + 1).ToLocal(&value)) { 15681cb0ef41Sopenharmony_ci tryCatch.Reset(); 15691cb0ef41Sopenharmony_ci continue; 15701cb0ef41Sopenharmony_ci } 15711cb0ef41Sopenharmony_ci auto wrapper = ValueMirror::create(context, value); 15721cb0ef41Sopenharmony_ci if (wrapper) { 15731cb0ef41Sopenharmony_ci mirrors->emplace_back(InternalPropertyMirror{ 15741cb0ef41Sopenharmony_ci toProtocolStringWithTypeCheck(context->GetIsolate(), name), 15751cb0ef41Sopenharmony_ci std::move(wrapper)}); 15761cb0ef41Sopenharmony_ci } 15771cb0ef41Sopenharmony_ci } 15781cb0ef41Sopenharmony_ci } 15791cb0ef41Sopenharmony_ci} 15801cb0ef41Sopenharmony_ci 15811cb0ef41Sopenharmony_ci// static 15821cb0ef41Sopenharmony_cistd::vector<PrivatePropertyMirror> ValueMirror::getPrivateProperties( 15831cb0ef41Sopenharmony_ci v8::Local<v8::Context> context, v8::Local<v8::Object> object, 15841cb0ef41Sopenharmony_ci bool accessorPropertiesOnly) { 15851cb0ef41Sopenharmony_ci std::vector<PrivatePropertyMirror> mirrors; 15861cb0ef41Sopenharmony_ci v8::Isolate* isolate = context->GetIsolate(); 15871cb0ef41Sopenharmony_ci v8::MicrotasksScope microtasksScope(isolate, 15881cb0ef41Sopenharmony_ci v8::MicrotasksScope::kDoNotRunMicrotasks); 15891cb0ef41Sopenharmony_ci v8::TryCatch tryCatch(isolate); 15901cb0ef41Sopenharmony_ci v8::Local<v8::Array> privateProperties; 15911cb0ef41Sopenharmony_ci 15921cb0ef41Sopenharmony_ci std::vector<v8::Local<v8::Value>> names; 15931cb0ef41Sopenharmony_ci std::vector<v8::Local<v8::Value>> values; 15941cb0ef41Sopenharmony_ci if (!v8::debug::GetPrivateMembers(context, object, &names, &values)) 15951cb0ef41Sopenharmony_ci return mirrors; 15961cb0ef41Sopenharmony_ci 15971cb0ef41Sopenharmony_ci size_t len = values.size(); 15981cb0ef41Sopenharmony_ci for (size_t i = 0; i < len; i++) { 15991cb0ef41Sopenharmony_ci v8::Local<v8::Value> name = names[i]; 16001cb0ef41Sopenharmony_ci DCHECK(name->IsString()); 16011cb0ef41Sopenharmony_ci v8::Local<v8::Value> value = values[i]; 16021cb0ef41Sopenharmony_ci 16031cb0ef41Sopenharmony_ci std::unique_ptr<ValueMirror> valueMirror; 16041cb0ef41Sopenharmony_ci std::unique_ptr<ValueMirror> getterMirror; 16051cb0ef41Sopenharmony_ci std::unique_ptr<ValueMirror> setterMirror; 16061cb0ef41Sopenharmony_ci if (v8::debug::AccessorPair::IsAccessorPair(value)) { 16071cb0ef41Sopenharmony_ci v8::Local<v8::debug::AccessorPair> accessors = 16081cb0ef41Sopenharmony_ci value.As<v8::debug::AccessorPair>(); 16091cb0ef41Sopenharmony_ci v8::Local<v8::Value> getter = accessors->getter(); 16101cb0ef41Sopenharmony_ci v8::Local<v8::Value> setter = accessors->setter(); 16111cb0ef41Sopenharmony_ci if (!getter->IsNull()) { 16121cb0ef41Sopenharmony_ci getterMirror = ValueMirror::create(context, getter); 16131cb0ef41Sopenharmony_ci } 16141cb0ef41Sopenharmony_ci if (!setter->IsNull()) { 16151cb0ef41Sopenharmony_ci setterMirror = ValueMirror::create(context, setter); 16161cb0ef41Sopenharmony_ci } 16171cb0ef41Sopenharmony_ci } else if (accessorPropertiesOnly) { 16181cb0ef41Sopenharmony_ci continue; 16191cb0ef41Sopenharmony_ci } else { 16201cb0ef41Sopenharmony_ci valueMirror = ValueMirror::create(context, value); 16211cb0ef41Sopenharmony_ci } 16221cb0ef41Sopenharmony_ci 16231cb0ef41Sopenharmony_ci mirrors.emplace_back(PrivatePropertyMirror{ 16241cb0ef41Sopenharmony_ci toProtocolStringWithTypeCheck(context->GetIsolate(), name), 16251cb0ef41Sopenharmony_ci std::move(valueMirror), std::move(getterMirror), 16261cb0ef41Sopenharmony_ci std::move(setterMirror)}); 16271cb0ef41Sopenharmony_ci } 16281cb0ef41Sopenharmony_ci return mirrors; 16291cb0ef41Sopenharmony_ci} 16301cb0ef41Sopenharmony_ci 16311cb0ef41Sopenharmony_cistd::unique_ptr<ValueMirror> clientMirror(v8::Local<v8::Context> context, 16321cb0ef41Sopenharmony_ci v8::Local<v8::Value> value, 16331cb0ef41Sopenharmony_ci const String16& subtype) { 16341cb0ef41Sopenharmony_ci auto descriptionForValueSubtype = 16351cb0ef41Sopenharmony_ci clientFor(context)->descriptionForValueSubtype(context, value); 16361cb0ef41Sopenharmony_ci if (descriptionForValueSubtype) { 16371cb0ef41Sopenharmony_ci return std::make_unique<ObjectMirror>( 16381cb0ef41Sopenharmony_ci value, subtype, toString16(descriptionForValueSubtype->string())); 16391cb0ef41Sopenharmony_ci } 16401cb0ef41Sopenharmony_ci if (subtype == "error") { 16411cb0ef41Sopenharmony_ci return std::make_unique<ObjectMirror>( 16421cb0ef41Sopenharmony_ci value, RemoteObject::SubtypeEnum::Error, 16431cb0ef41Sopenharmony_ci descriptionForError(context, value.As<v8::Object>(), 16441cb0ef41Sopenharmony_ci ErrorType::kClient)); 16451cb0ef41Sopenharmony_ci } 16461cb0ef41Sopenharmony_ci if (subtype == "array" && value->IsObject()) { 16471cb0ef41Sopenharmony_ci v8::Isolate* isolate = context->GetIsolate(); 16481cb0ef41Sopenharmony_ci v8::TryCatch tryCatch(isolate); 16491cb0ef41Sopenharmony_ci v8::Local<v8::Object> object = value.As<v8::Object>(); 16501cb0ef41Sopenharmony_ci v8::Local<v8::Value> lengthValue; 16511cb0ef41Sopenharmony_ci if (object->Get(context, toV8String(isolate, "length")) 16521cb0ef41Sopenharmony_ci .ToLocal(&lengthValue)) { 16531cb0ef41Sopenharmony_ci if (lengthValue->IsInt32()) { 16541cb0ef41Sopenharmony_ci return std::make_unique<ObjectMirror>( 16551cb0ef41Sopenharmony_ci value, RemoteObject::SubtypeEnum::Array, 16561cb0ef41Sopenharmony_ci descriptionForCollection(isolate, object, 16571cb0ef41Sopenharmony_ci lengthValue.As<v8::Int32>()->Value())); 16581cb0ef41Sopenharmony_ci } 16591cb0ef41Sopenharmony_ci } 16601cb0ef41Sopenharmony_ci } 16611cb0ef41Sopenharmony_ci return std::make_unique<ObjectMirror>( 16621cb0ef41Sopenharmony_ci value, 16631cb0ef41Sopenharmony_ci descriptionForObject(context->GetIsolate(), value.As<v8::Object>())); 16641cb0ef41Sopenharmony_ci} 16651cb0ef41Sopenharmony_ci 16661cb0ef41Sopenharmony_cistd::unique_ptr<ValueMirror> ValueMirror::create(v8::Local<v8::Context> context, 16671cb0ef41Sopenharmony_ci v8::Local<v8::Value> value) { 16681cb0ef41Sopenharmony_ci if (value->IsNull()) { 16691cb0ef41Sopenharmony_ci return std::make_unique<PrimitiveValueMirror>( 16701cb0ef41Sopenharmony_ci value, RemoteObject::TypeEnum::Object); 16711cb0ef41Sopenharmony_ci } 16721cb0ef41Sopenharmony_ci if (value->IsBoolean()) { 16731cb0ef41Sopenharmony_ci return std::make_unique<PrimitiveValueMirror>( 16741cb0ef41Sopenharmony_ci value, RemoteObject::TypeEnum::Boolean); 16751cb0ef41Sopenharmony_ci } 16761cb0ef41Sopenharmony_ci if (value->IsNumber()) { 16771cb0ef41Sopenharmony_ci return std::make_unique<NumberMirror>(value.As<v8::Number>()); 16781cb0ef41Sopenharmony_ci } 16791cb0ef41Sopenharmony_ci v8::Isolate* isolate = context->GetIsolate(); 16801cb0ef41Sopenharmony_ci if (value->IsString()) { 16811cb0ef41Sopenharmony_ci return std::make_unique<PrimitiveValueMirror>( 16821cb0ef41Sopenharmony_ci value, RemoteObject::TypeEnum::String); 16831cb0ef41Sopenharmony_ci } 16841cb0ef41Sopenharmony_ci if (value->IsBigInt()) { 16851cb0ef41Sopenharmony_ci return std::make_unique<BigIntMirror>(value.As<v8::BigInt>()); 16861cb0ef41Sopenharmony_ci } 16871cb0ef41Sopenharmony_ci if (value->IsSymbol()) { 16881cb0ef41Sopenharmony_ci return std::make_unique<SymbolMirror>(value.As<v8::Symbol>()); 16891cb0ef41Sopenharmony_ci } 16901cb0ef41Sopenharmony_ci auto clientSubtype = (value->IsUndefined() || value->IsObject()) 16911cb0ef41Sopenharmony_ci ? clientFor(context)->valueSubtype(value) 16921cb0ef41Sopenharmony_ci : nullptr; 16931cb0ef41Sopenharmony_ci if (clientSubtype) { 16941cb0ef41Sopenharmony_ci String16 subtype = toString16(clientSubtype->string()); 16951cb0ef41Sopenharmony_ci return clientMirror(context, value, subtype); 16961cb0ef41Sopenharmony_ci } 16971cb0ef41Sopenharmony_ci if (value->IsUndefined()) { 16981cb0ef41Sopenharmony_ci return std::make_unique<PrimitiveValueMirror>( 16991cb0ef41Sopenharmony_ci value, RemoteObject::TypeEnum::Undefined); 17001cb0ef41Sopenharmony_ci } 17011cb0ef41Sopenharmony_ci if (value->IsRegExp()) { 17021cb0ef41Sopenharmony_ci return std::make_unique<ObjectMirror>( 17031cb0ef41Sopenharmony_ci value, RemoteObject::SubtypeEnum::Regexp, 17041cb0ef41Sopenharmony_ci descriptionForRegExp(isolate, value.As<v8::RegExp>())); 17051cb0ef41Sopenharmony_ci } 17061cb0ef41Sopenharmony_ci if (value->IsProxy()) { 17071cb0ef41Sopenharmony_ci return std::make_unique<ObjectMirror>( 17081cb0ef41Sopenharmony_ci value, RemoteObject::SubtypeEnum::Proxy, "Proxy"); 17091cb0ef41Sopenharmony_ci } 17101cb0ef41Sopenharmony_ci if (value->IsFunction()) { 17111cb0ef41Sopenharmony_ci return std::make_unique<FunctionMirror>(value); 17121cb0ef41Sopenharmony_ci } 17131cb0ef41Sopenharmony_ci if (value->IsDate()) { 17141cb0ef41Sopenharmony_ci return std::make_unique<ObjectMirror>( 17151cb0ef41Sopenharmony_ci value, RemoteObject::SubtypeEnum::Date, 17161cb0ef41Sopenharmony_ci descriptionForDate(context, value.As<v8::Date>())); 17171cb0ef41Sopenharmony_ci } 17181cb0ef41Sopenharmony_ci if (value->IsPromise()) { 17191cb0ef41Sopenharmony_ci v8::Local<v8::Promise> promise = value.As<v8::Promise>(); 17201cb0ef41Sopenharmony_ci return std::make_unique<ObjectMirror>( 17211cb0ef41Sopenharmony_ci promise, RemoteObject::SubtypeEnum::Promise, 17221cb0ef41Sopenharmony_ci descriptionForObject(isolate, promise)); 17231cb0ef41Sopenharmony_ci } 17241cb0ef41Sopenharmony_ci if (value->IsNativeError()) { 17251cb0ef41Sopenharmony_ci return std::make_unique<ObjectMirror>( 17261cb0ef41Sopenharmony_ci value, RemoteObject::SubtypeEnum::Error, 17271cb0ef41Sopenharmony_ci descriptionForError(context, value.As<v8::Object>(), 17281cb0ef41Sopenharmony_ci ErrorType::kNative)); 17291cb0ef41Sopenharmony_ci } 17301cb0ef41Sopenharmony_ci if (value->IsMap()) { 17311cb0ef41Sopenharmony_ci v8::Local<v8::Map> map = value.As<v8::Map>(); 17321cb0ef41Sopenharmony_ci return std::make_unique<ObjectMirror>( 17331cb0ef41Sopenharmony_ci value, RemoteObject::SubtypeEnum::Map, 17341cb0ef41Sopenharmony_ci descriptionForCollection(isolate, map, map->Size())); 17351cb0ef41Sopenharmony_ci } 17361cb0ef41Sopenharmony_ci if (value->IsSet()) { 17371cb0ef41Sopenharmony_ci v8::Local<v8::Set> set = value.As<v8::Set>(); 17381cb0ef41Sopenharmony_ci return std::make_unique<ObjectMirror>( 17391cb0ef41Sopenharmony_ci value, RemoteObject::SubtypeEnum::Set, 17401cb0ef41Sopenharmony_ci descriptionForCollection(isolate, set, set->Size())); 17411cb0ef41Sopenharmony_ci } 17421cb0ef41Sopenharmony_ci if (value->IsWeakMap()) { 17431cb0ef41Sopenharmony_ci return std::make_unique<ObjectMirror>( 17441cb0ef41Sopenharmony_ci value, RemoteObject::SubtypeEnum::Weakmap, 17451cb0ef41Sopenharmony_ci descriptionForObject(isolate, value.As<v8::Object>())); 17461cb0ef41Sopenharmony_ci } 17471cb0ef41Sopenharmony_ci if (value->IsWeakSet()) { 17481cb0ef41Sopenharmony_ci return std::make_unique<ObjectMirror>( 17491cb0ef41Sopenharmony_ci value, RemoteObject::SubtypeEnum::Weakset, 17501cb0ef41Sopenharmony_ci descriptionForObject(isolate, value.As<v8::Object>())); 17511cb0ef41Sopenharmony_ci } 17521cb0ef41Sopenharmony_ci if (value->IsMapIterator() || value->IsSetIterator()) { 17531cb0ef41Sopenharmony_ci return std::make_unique<ObjectMirror>( 17541cb0ef41Sopenharmony_ci value, RemoteObject::SubtypeEnum::Iterator, 17551cb0ef41Sopenharmony_ci descriptionForObject(isolate, value.As<v8::Object>())); 17561cb0ef41Sopenharmony_ci } 17571cb0ef41Sopenharmony_ci if (value->IsGeneratorObject()) { 17581cb0ef41Sopenharmony_ci v8::Local<v8::Object> object = value.As<v8::Object>(); 17591cb0ef41Sopenharmony_ci return std::make_unique<ObjectMirror>( 17601cb0ef41Sopenharmony_ci object, RemoteObject::SubtypeEnum::Generator, 17611cb0ef41Sopenharmony_ci descriptionForObject(isolate, object)); 17621cb0ef41Sopenharmony_ci } 17631cb0ef41Sopenharmony_ci if (value->IsTypedArray()) { 17641cb0ef41Sopenharmony_ci v8::Local<v8::TypedArray> array = value.As<v8::TypedArray>(); 17651cb0ef41Sopenharmony_ci return std::make_unique<ObjectMirror>( 17661cb0ef41Sopenharmony_ci value, RemoteObject::SubtypeEnum::Typedarray, 17671cb0ef41Sopenharmony_ci descriptionForCollection(isolate, array, array->Length())); 17681cb0ef41Sopenharmony_ci } 17691cb0ef41Sopenharmony_ci if (value->IsArrayBuffer()) { 17701cb0ef41Sopenharmony_ci v8::Local<v8::ArrayBuffer> buffer = value.As<v8::ArrayBuffer>(); 17711cb0ef41Sopenharmony_ci return std::make_unique<ObjectMirror>( 17721cb0ef41Sopenharmony_ci value, RemoteObject::SubtypeEnum::Arraybuffer, 17731cb0ef41Sopenharmony_ci descriptionForCollection(isolate, buffer, buffer->ByteLength())); 17741cb0ef41Sopenharmony_ci } 17751cb0ef41Sopenharmony_ci if (value->IsSharedArrayBuffer()) { 17761cb0ef41Sopenharmony_ci v8::Local<v8::SharedArrayBuffer> buffer = value.As<v8::SharedArrayBuffer>(); 17771cb0ef41Sopenharmony_ci return std::make_unique<ObjectMirror>( 17781cb0ef41Sopenharmony_ci value, RemoteObject::SubtypeEnum::Arraybuffer, 17791cb0ef41Sopenharmony_ci descriptionForCollection(isolate, buffer, buffer->ByteLength())); 17801cb0ef41Sopenharmony_ci } 17811cb0ef41Sopenharmony_ci if (value->IsDataView()) { 17821cb0ef41Sopenharmony_ci v8::Local<v8::DataView> view = value.As<v8::DataView>(); 17831cb0ef41Sopenharmony_ci return std::make_unique<ObjectMirror>( 17841cb0ef41Sopenharmony_ci value, RemoteObject::SubtypeEnum::Dataview, 17851cb0ef41Sopenharmony_ci descriptionForCollection(isolate, view, view->ByteLength())); 17861cb0ef41Sopenharmony_ci } 17871cb0ef41Sopenharmony_ci if (value->IsWasmMemoryObject()) { 17881cb0ef41Sopenharmony_ci v8::Local<v8::WasmMemoryObject> memory = value.As<v8::WasmMemoryObject>(); 17891cb0ef41Sopenharmony_ci return std::make_unique<ObjectMirror>( 17901cb0ef41Sopenharmony_ci value, RemoteObject::SubtypeEnum::Webassemblymemory, 17911cb0ef41Sopenharmony_ci descriptionForCollection( 17921cb0ef41Sopenharmony_ci isolate, memory, memory->Buffer()->ByteLength() / kWasmPageSize)); 17931cb0ef41Sopenharmony_ci } 17941cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY 17951cb0ef41Sopenharmony_ci if (v8::debug::WasmValueObject::IsWasmValueObject(value)) { 17961cb0ef41Sopenharmony_ci v8::Local<v8::debug::WasmValueObject> object = 17971cb0ef41Sopenharmony_ci value.As<v8::debug::WasmValueObject>(); 17981cb0ef41Sopenharmony_ci return std::make_unique<ObjectMirror>( 17991cb0ef41Sopenharmony_ci value, RemoteObject::SubtypeEnum::Wasmvalue, 18001cb0ef41Sopenharmony_ci descriptionForWasmValueObject(context, object)); 18011cb0ef41Sopenharmony_ci } 18021cb0ef41Sopenharmony_ci#endif // V8_ENABLE_WEBASSEMBLY 18031cb0ef41Sopenharmony_ci V8InternalValueType internalType = 18041cb0ef41Sopenharmony_ci v8InternalValueTypeFrom(context, value.As<v8::Object>()); 18051cb0ef41Sopenharmony_ci if (value->IsArray() && internalType == V8InternalValueType::kScopeList) { 18061cb0ef41Sopenharmony_ci return std::make_unique<ObjectMirror>( 18071cb0ef41Sopenharmony_ci value, "internal#scopeList", 18081cb0ef41Sopenharmony_ci descriptionForScopeList(value.As<v8::Array>())); 18091cb0ef41Sopenharmony_ci } 18101cb0ef41Sopenharmony_ci if (value->IsObject() && internalType == V8InternalValueType::kEntry) { 18111cb0ef41Sopenharmony_ci return std::make_unique<ObjectMirror>( 18121cb0ef41Sopenharmony_ci value, "internal#entry", 18131cb0ef41Sopenharmony_ci descriptionForEntry(context, value.As<v8::Object>())); 18141cb0ef41Sopenharmony_ci } 18151cb0ef41Sopenharmony_ci if (value->IsObject() && internalType == V8InternalValueType::kScope) { 18161cb0ef41Sopenharmony_ci return std::make_unique<ObjectMirror>( 18171cb0ef41Sopenharmony_ci value, "internal#scope", 18181cb0ef41Sopenharmony_ci descriptionForScope(context, value.As<v8::Object>())); 18191cb0ef41Sopenharmony_ci } 18201cb0ef41Sopenharmony_ci size_t length = 0; 18211cb0ef41Sopenharmony_ci if (value->IsArray() || isArrayLike(context, value, &length)) { 18221cb0ef41Sopenharmony_ci length = value->IsArray() ? value.As<v8::Array>()->Length() : length; 18231cb0ef41Sopenharmony_ci return std::make_unique<ObjectMirror>( 18241cb0ef41Sopenharmony_ci value, RemoteObject::SubtypeEnum::Array, 18251cb0ef41Sopenharmony_ci descriptionForCollection(isolate, value.As<v8::Object>(), length)); 18261cb0ef41Sopenharmony_ci } 18271cb0ef41Sopenharmony_ci if (value->IsObject()) { 18281cb0ef41Sopenharmony_ci return std::make_unique<ObjectMirror>( 18291cb0ef41Sopenharmony_ci value, descriptionForObject(isolate, value.As<v8::Object>())); 18301cb0ef41Sopenharmony_ci } 18311cb0ef41Sopenharmony_ci return nullptr; 18321cb0ef41Sopenharmony_ci} 18331cb0ef41Sopenharmony_ci} // namespace v8_inspector 1834