1/*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "agent/runtime_impl.h"
17
18#include <iomanip>
19
20#include "tooling/base/pt_returns.h"
21#include "protocol_channel.h"
22
23#include "ecmascript/napi/include/dfx_jsnapi.h"
24
25namespace panda::ecmascript::tooling {
26// Whenever adding a new protocol which is not a standard CDP protocol,
27// must add its methodName to the runtimeProtocolsList
28void RuntimeImpl::InitializeExtendedProtocolsList()
29{
30    std::vector<std::string> runtimeProtocolList {};
31    runtimeExtendedProtocols_ = std::move(runtimeProtocolList);
32}
33
34void RuntimeImpl::DispatcherImpl::Dispatch(const DispatchRequest &request)
35{
36    Method method = GetMethodEnum(request.GetMethod());
37    LOG_DEBUGGER(DEBUG) << "dispatch [" << request.GetMethod() << "] to RuntimeImpl";
38    switch (method) {
39        case Method::ENABLE:
40            Enable(request);
41            break;
42        case Method::DISABLE:
43            Disable(request);
44            break;
45        case Method::GET_PROPERTIES:
46            GetProperties(request);
47            break;
48        case Method::RUN_IF_WAITING_FOR_DEBUGGER:
49            RunIfWaitingForDebugger(request);
50            break;
51        case Method::GET_HEAP_USAGE:
52            GetHeapUsage(request);
53            break;
54        default:
55            SendResponse(request, DispatchResponse::Fail("unknown method: " + request.GetMethod()));
56            break;
57    }
58}
59
60RuntimeImpl::DispatcherImpl::Method RuntimeImpl::DispatcherImpl::GetMethodEnum(const std::string& method)
61{
62    if (method == "enable") {
63        return Method::ENABLE;
64    } else if (method == "disable") {
65        return Method::DISABLE;
66    } else if (method == "getProperties") {
67        return Method::GET_PROPERTIES;
68    } else if (method == "runIfWaitingForDebugger") {
69        return Method::RUN_IF_WAITING_FOR_DEBUGGER;
70    } else if (method == "getHeapUsage") {
71        return Method::GET_HEAP_USAGE;
72    } else {
73        return Method::UNKNOWN;
74    }
75}
76
77void RuntimeImpl::DispatcherImpl::Enable(const DispatchRequest &request)
78{
79    DispatchResponse response = runtime_->Enable();
80    runtime_->InitializeExtendedProtocolsList();
81    EnableReturns result(runtime_->runtimeExtendedProtocols_);
82    SendResponse(request, response, result);
83}
84
85void RuntimeImpl::DispatcherImpl::Disable(const DispatchRequest &request)
86{
87    DispatchResponse response = runtime_->Disable();
88    SendResponse(request, response);
89}
90
91void RuntimeImpl::DispatcherImpl::RunIfWaitingForDebugger(const DispatchRequest &request)
92{
93    DispatchResponse response = runtime_->RunIfWaitingForDebugger();
94    SendResponse(request, response);
95}
96
97void RuntimeImpl::DispatcherImpl::GetProperties(const DispatchRequest &request)
98{
99    std::unique_ptr<GetPropertiesParams> params = GetPropertiesParams::Create(request.GetParams());
100    if (params == nullptr) {
101        SendResponse(request, DispatchResponse::Fail("wrong params"));
102        return;
103    }
104
105    std::vector<std::unique_ptr<PropertyDescriptor>> outPropertyDesc;
106    std::optional<std::vector<std::unique_ptr<InternalPropertyDescriptor>>> outInternalDescs;
107    std::optional<std::vector<std::unique_ptr<PrivatePropertyDescriptor>>> outPrivateProperties;
108    std::optional<std::unique_ptr<ExceptionDetails>> outExceptionDetails;
109    DispatchResponse response = runtime_->GetProperties(*params, &outPropertyDesc, &outInternalDescs,
110        &outPrivateProperties, &outExceptionDetails);
111    if (outExceptionDetails) {
112        ASSERT(outExceptionDetails.value() != nullptr);
113        LOG_DEBUGGER(WARN) << "GetProperties thrown an exception";
114    }
115    GetPropertiesReturns result(std::move(outPropertyDesc),
116        std::move(outInternalDescs),
117        std::move(outPrivateProperties),
118        std::move(outExceptionDetails));
119    SendResponse(request, response, result);
120}
121
122void RuntimeImpl::DispatcherImpl::GetHeapUsage(const DispatchRequest &request)
123{
124    double usedSize = 0;
125    double totalSize = 0;
126    DispatchResponse response = runtime_->GetHeapUsage(&usedSize, &totalSize);
127    GetHeapUsageReturns result(usedSize, totalSize);
128    SendResponse(request, response, result);
129}
130
131bool RuntimeImpl::Frontend::AllowNotify() const
132{
133    return channel_ != nullptr;
134}
135
136void RuntimeImpl::Frontend::RunIfWaitingForDebugger()
137{
138    if (!AllowNotify()) {
139        return;
140    }
141
142    channel_->RunIfWaitingForDebugger();
143}
144
145DispatchResponse RuntimeImpl::Enable()
146{
147    internalObjects_ = Global<MapRef>(vm_, MapRef::New(vm_));
148    return DispatchResponse::Ok();
149}
150
151DispatchResponse RuntimeImpl::Disable()
152{
153    internalObjects_.FreeGlobalHandleAddr();
154    return DispatchResponse::Ok();
155}
156
157DispatchResponse RuntimeImpl::RunIfWaitingForDebugger()
158{
159    frontend_.RunIfWaitingForDebugger();
160    return DispatchResponse::Ok();
161}
162
163DispatchResponse RuntimeImpl::GetHeapUsage(double *usedSize, double *totalSize)
164{
165#ifdef ECMASCRIPT_SUPPORT_HEAPPROFILER
166    *totalSize = static_cast<double>(DFXJSNApi::GetHeapTotalSize(vm_));
167    *usedSize = static_cast<double>(DFXJSNApi::GetHeapUsedSize(vm_));
168#else
169    *totalSize = 0;
170    *usedSize = 0;
171#endif
172    return DispatchResponse::Ok();
173}
174
175DispatchResponse RuntimeImpl::GetProperties(const GetPropertiesParams &params,
176    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc,
177    [[maybe_unused]] std::optional<std::vector<std::unique_ptr<InternalPropertyDescriptor>>> *outInternalDescs,
178    [[maybe_unused]] std::optional<std::vector<std::unique_ptr<PrivatePropertyDescriptor>>> *outPrivateProps,
179    [[maybe_unused]] std::optional<std::unique_ptr<ExceptionDetails>> *outExceptionDetails)
180{
181    RemoteObjectId objectId = params.GetObjectId();
182    bool isOwn = params.GetOwnProperties();
183    bool isAccessorOnly = params.GetAccessPropertiesOnly();
184    auto iter = properties_.find(objectId);
185    if (iter == properties_.end()) {
186        LOG_DEBUGGER(ERROR) << "RuntimeImpl::GetProperties Unknown object id: " << objectId;
187        return DispatchResponse::Fail("Unknown object id");
188    }
189    Local<JSValueRef> value = Local<JSValueRef>(vm_, iter->second);
190    if (value.IsEmpty() || !value->IsObject(vm_)) {
191        LOG_DEBUGGER(ERROR) << "RuntimeImpl::GetProperties should a js object";
192        return DispatchResponse::Fail("Not a object");
193    }
194    bool skipProto = false;
195    if (!internalObjects_.IsEmpty() && internalObjects_->Get(vm_, value)->IsNumber()) {
196        if (static_cast<ArkInternalValueType>(internalObjects_->Get(vm_, value)->ToNumber(vm_)->Value()) ==
197            ArkInternalValueType::Entry || static_cast<ArkInternalValueType>(internalObjects_->Get(vm_, value)->
198            ToNumber(vm_)->Value()) == ArkInternalValueType::Scope) {
199            skipProto = true;
200        }
201    }
202    if (value->IsArrayBuffer(vm_)) {
203        Local<ArrayBufferRef> arrayBufferRef(value);
204        AddTypedArrayRefs(arrayBufferRef, outPropertyDesc);
205    } else if (value->IsSharedArrayBuffer(vm_)) {
206        Local<ArrayBufferRef> arrayBufferRef(value);
207        AddSharedArrayBufferRefs(arrayBufferRef, outPropertyDesc);
208    } else if (value->IsProxy(vm_)) {
209        GetProxyValue(value, outPropertyDesc);
210        return DispatchResponse::Ok();
211    } else if (value->IsMapIterator(vm_)) {
212        GetMapIteratorValue(value, outPropertyDesc);
213    } else if (value->IsSetIterator(vm_)) {
214        GetSetIteratorValue(value, outPropertyDesc);
215    } else if (value->IsJSPrimitiveRef(vm_) && value->IsJSPrimitiveNumber(vm_)) {
216        GetPrimitiveNumberValue(value, outPropertyDesc);
217    } else if (value->IsJSPrimitiveRef(vm_) && value->IsJSPrimitiveString(vm_)) {
218        GetPrimitiveStringValue(value, outPropertyDesc);
219    } else if (value->IsJSPrimitiveRef(vm_) && value->IsJSPrimitiveBoolean(vm_)) {
220        GetPrimitiveBooleanValue(value, outPropertyDesc);
221    } else if (value->IsGeneratorFunction(vm_)) {
222        GetGeneratorFunctionValue(value, outPropertyDesc);
223    } else if (value->IsGeneratorObject(vm_)) {
224        GetGeneratorObjectValue(value, outPropertyDesc);
225    } else if (value->IsJSNumberFormat(vm_)) {
226        GetNumberFormatValue(value, outPropertyDesc);
227    } else if (value->IsJSCollator(vm_)) {
228        GetCollatorValue(value, outPropertyDesc);
229    } else if (value->IsJSDateTimeFormat(vm_)) {
230        GetDateTimeFormatValue(value, outPropertyDesc);
231    } else if (value->IsSharedMap(vm_)) {
232        GetSharedMapValue(value, outPropertyDesc);
233    } else if (value->IsMap(vm_)) {
234        GetMapValue(value, outPropertyDesc);
235    } else if (value->IsWeakMap(vm_)) {
236        GetWeakMapValue(value, outPropertyDesc);
237    } else if (value->IsRegExp(vm_)) {
238        GetRegExpValue(value, outPropertyDesc);
239    } else if (value->IsSharedSet(vm_)) {
240        GetSendableSetValue(value, outPropertyDesc);
241    } else if (value->IsSet(vm_)) {
242        GetSetValue(value, outPropertyDesc);
243    } else if (value->IsWeakSet(vm_)) {
244        GetWeakSetValue(value, outPropertyDesc);
245    } else if (value->IsDataView(vm_)) {
246        GetDataViewValue(value, outPropertyDesc);
247    } else if (value->IsHashMap(vm_)) {
248        GetHashMapValue(value, outPropertyDesc);
249    } else if (value->IsHashSet(vm_)) {
250        GetHashSetValue(value, outPropertyDesc);
251    } else if (value->IsLightWeightMap(vm_)) {
252        GetLightWeightMapValue(value, outPropertyDesc);
253    } else if (value->IsLightWeightSet(vm_)) {
254        GetLightWeightSetValue(value, outPropertyDesc);
255    } else if (value->IsLinkedList(vm_)) {
256        GetLinkedListValue(value, outPropertyDesc);
257    } else if (value->IsList(vm_)) {
258        GetListValue(value, outPropertyDesc);
259    } else if (value->IsPlainArray(vm_)) {
260        GetPlainArrayValue(value, outPropertyDesc);
261    } else if (value->IsTreeMap(vm_)) {
262        GetTreeMapValue(value, outPropertyDesc);
263    } else if (value->IsTreeSet(vm_)) {
264        GetTreeSetValue(value, outPropertyDesc);
265    } else if (value->IsArrayList(vm_)) {
266        GetArrayListValue(value, outPropertyDesc);
267        GetProtoOrProtoType(value, isOwn, isAccessorOnly, outPropertyDesc);
268        return DispatchResponse::Ok();
269    } else if (value->IsDeque(vm_)) {
270        GetDequeValue(value, outPropertyDesc);
271        GetProtoOrProtoType(value, isOwn, isAccessorOnly, outPropertyDesc);
272        return DispatchResponse::Ok();
273    } else if (value->IsQueue(vm_)) {
274        GetQueueValue(value, outPropertyDesc);
275        GetProtoOrProtoType(value, isOwn, isAccessorOnly, outPropertyDesc);
276        return DispatchResponse::Ok();
277    } else if (value->IsStack(vm_)) {
278        GetStackValue(value, outPropertyDesc);
279        GetProtoOrProtoType(value, isOwn, isAccessorOnly, outPropertyDesc);
280        return DispatchResponse::Ok();
281    } else if (value->IsVector(vm_)) {
282        GetVectorValue(value, outPropertyDesc);
283        GetProtoOrProtoType(value, isOwn, isAccessorOnly, outPropertyDesc);
284        return DispatchResponse::Ok();
285    } else if (value->IsPromise(vm_)) {
286        GetPromiseValue(value, outPropertyDesc);
287        GetProtoOrProtoType(value, isOwn, isAccessorOnly, outPropertyDesc);
288        return DispatchResponse::Ok();
289    }
290    Local<ArrayRef> keys = Local<ObjectRef>(value)->GetOwnPropertyNames(vm_);
291    int32_t length = static_cast<int32_t>(keys->Length(vm_));
292    Local<JSValueRef> name = JSValueRef::Undefined(vm_);
293    for (int32_t i = 0; i < length; ++i) {
294        name = keys->Get(vm_, i);
295        PropertyAttribute jsProperty = PropertyAttribute::Default();
296        if (!Local<ObjectRef>(value)->GetOwnProperty(vm_, name, jsProperty)) {
297            continue;
298        }
299        std::unique_ptr<PropertyDescriptor> debuggerProperty =
300            PropertyDescriptor::FromProperty(vm_, name, jsProperty);
301        if (isAccessorOnly && !jsProperty.HasGetter() && !jsProperty.HasSetter()) {
302            continue;
303        }
304        if (debuggerProperty->HasGet()) {
305            debuggerProperty->GetGet()->SetObjectId(curObjectId_);
306            properties_[curObjectId_++] = Global<JSValueRef>(vm_, jsProperty.GetGetter(vm_));
307        }
308        if (debuggerProperty->HasSet()) {
309            debuggerProperty->GetSet()->SetObjectId(curObjectId_);
310            properties_[curObjectId_++] = Global<JSValueRef>(vm_, jsProperty.GetSetter(vm_));
311        }
312        if (debuggerProperty->HasValue()) {
313            Local<JSValueRef> vValue = jsProperty.GetValue(vm_);
314            if (vValue->IsObject(vm_)) {
315                debuggerProperty->GetValue()->SetObjectId(curObjectId_);
316                properties_[curObjectId_++] = Global<JSValueRef>(vm_, vValue);
317            }
318        }
319        if (debuggerProperty->HasSymbol()) {
320            debuggerProperty->GetSymbol()->SetObjectId(curObjectId_);
321            properties_[curObjectId_++] = Global<JSValueRef>(vm_, name);
322        }
323        outPropertyDesc->emplace_back(std::move(debuggerProperty));
324    }
325    if (!skipProto) {
326        GetProtoOrProtoType(value, isOwn, isAccessorOnly, outPropertyDesc);
327    }
328
329    return DispatchResponse::Ok();
330}
331
332void RuntimeImpl::AddTypedArrayRefs(Local<ArrayBufferRef> arrayBufferRef,
333    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
334{
335    int32_t arrayBufferByteLength = arrayBufferRef->ByteLength(vm_);
336    int32_t typedArrayLength = arrayBufferByteLength;
337    AddTypedArrayRef<Int8ArrayRef>(arrayBufferRef, typedArrayLength, "[[Int8Array]]", outPropertyDesc);
338    AddTypedArrayRef<Uint8ArrayRef>(arrayBufferRef, typedArrayLength, "[[Uint8Array]]", outPropertyDesc);
339    AddTypedArrayRef<Uint8ClampedArrayRef>(arrayBufferRef, typedArrayLength, "[[Uint8ClampedArray]]", outPropertyDesc);
340
341    if ((arrayBufferByteLength % NumberSize::BYTES_OF_16BITS) == 0) {
342        typedArrayLength = arrayBufferByteLength / NumberSize::BYTES_OF_16BITS;
343        AddTypedArrayRef<Int16ArrayRef>(arrayBufferRef, typedArrayLength, "[[Int16Array]]", outPropertyDesc);
344        AddTypedArrayRef<Uint16ArrayRef>(arrayBufferRef, typedArrayLength, "[[Uint16Array]]", outPropertyDesc);
345    }
346
347    if ((arrayBufferByteLength % NumberSize::BYTES_OF_32BITS) == 0) {
348        typedArrayLength = arrayBufferByteLength / NumberSize::BYTES_OF_32BITS;
349        AddTypedArrayRef<Int32ArrayRef>(arrayBufferRef, typedArrayLength, "[[Int32Array]]", outPropertyDesc);
350        AddTypedArrayRef<Uint32ArrayRef>(arrayBufferRef, typedArrayLength, "[[Uint32Array]]", outPropertyDesc);
351        AddTypedArrayRef<Float32ArrayRef>(arrayBufferRef, typedArrayLength, "[[Float32Array]]", outPropertyDesc);
352    }
353
354    if ((arrayBufferByteLength % NumberSize::BYTES_OF_64BITS) == 0) {
355        typedArrayLength = arrayBufferByteLength / NumberSize::BYTES_OF_64BITS;
356        AddTypedArrayRef<Float64ArrayRef>(arrayBufferRef, typedArrayLength, "[[Float64Array]]", outPropertyDesc);
357        AddTypedArrayRef<BigInt64ArrayRef>(arrayBufferRef, typedArrayLength, "[[BigInt64Array]]", outPropertyDesc);
358        AddTypedArrayRef<BigUint64ArrayRef>(arrayBufferRef, typedArrayLength, "[[BigUint64Array]]", outPropertyDesc);
359    }
360}
361
362void RuntimeImpl::AddSharedArrayBufferRefs(Local<ArrayBufferRef> arrayBufferRef,
363    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
364{
365    int32_t arrayBufferByteLength = arrayBufferRef->ByteLength(vm_);
366    int32_t typedArrayLength = arrayBufferByteLength;
367    AddTypedArrayRef<Int8ArrayRef>(arrayBufferRef, typedArrayLength, "[[Int8Array]]", outPropertyDesc);
368    AddTypedArrayRef<Uint8ArrayRef>(arrayBufferRef, typedArrayLength, "[[Uint8Array]]", outPropertyDesc);
369
370    if ((arrayBufferByteLength % NumberSize::BYTES_OF_16BITS) == 0) {
371        typedArrayLength = arrayBufferByteLength / NumberSize::BYTES_OF_16BITS;
372        AddTypedArrayRef<Int16ArrayRef>(arrayBufferRef, typedArrayLength, "[[Int16Array]]", outPropertyDesc);
373    }
374
375    if ((arrayBufferByteLength % NumberSize::BYTES_OF_32BITS) == 0) {
376        typedArrayLength = arrayBufferByteLength / NumberSize::BYTES_OF_32BITS;
377        AddTypedArrayRef<Int32ArrayRef>(arrayBufferRef, typedArrayLength, "[[Int32Array]]", outPropertyDesc);
378    }
379    Local<JSValueRef> jsValueRef;
380    jsValueRef = NumberRef::New(vm_, arrayBufferByteLength);
381    SetKeyValue(jsValueRef, outPropertyDesc, "[[ArrayBufferByteLength]]");
382    SetKeyValue(jsValueRef, outPropertyDesc, "byteLength");
383}
384
385template <typename TypedArrayRef>
386void RuntimeImpl::AddTypedArrayRef(Local<ArrayBufferRef> arrayBufferRef, int32_t length, const char* name,
387    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
388{
389    Local<JSValueRef> jsValueRefTypedArray(TypedArrayRef::New(vm_, arrayBufferRef, 0, length));
390    std::unique_ptr<RemoteObject> remoteObjectTypedArray = RemoteObject::FromTagged(vm_, jsValueRefTypedArray);
391    remoteObjectTypedArray->SetObjectId(curObjectId_);
392    properties_[curObjectId_++] = Global<JSValueRef>(vm_, jsValueRefTypedArray);
393    std::unique_ptr<PropertyDescriptor> debuggerProperty = std::make_unique<PropertyDescriptor>();
394    debuggerProperty->SetName(name)
395        .SetWritable(true)
396        .SetConfigurable(true)
397        .SetEnumerable(false)
398        .SetIsOwn(true)
399        .SetValue(std::move(remoteObjectTypedArray));
400    outPropertyDesc->emplace_back(std::move(debuggerProperty));
401}
402
403void RuntimeImpl::CacheObjectIfNeeded(Local<JSValueRef> valRef, RemoteObject *remoteObj)
404{
405    if (valRef->IsObject(vm_)) {
406        remoteObj->SetObjectId(curObjectId_);
407        properties_[curObjectId_++] = Global<JSValueRef>(vm_, valRef);
408    }
409}
410
411void RuntimeImpl::GetProtoOrProtoType(Local<JSValueRef> value, bool isOwn, bool isAccessorOnly,
412    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
413{
414    if (!isAccessorOnly && isOwn) {
415        return;
416    }
417    // Get Function ProtoOrHClass
418    if (value->IsConstructor(vm_)) {
419        Local<JSValueRef> prototype = Local<FunctionRef>(value)->GetFunctionPrototype(vm_);
420        std::unique_ptr<RemoteObject> protoObj = RemoteObject::FromTagged(vm_, prototype);
421        CacheObjectIfNeeded(prototype, protoObj.get());
422        std::unique_ptr<PropertyDescriptor> debuggerProperty = std::make_unique<PropertyDescriptor>();
423        debuggerProperty->SetName("prototype")
424            .SetWritable(false)
425            .SetConfigurable(false)
426            .SetEnumerable(false)
427            .SetIsOwn(true)
428            .SetValue(std::move(protoObj));
429        outPropertyDesc->emplace_back(std::move(debuggerProperty));
430    }
431    // Get __proto__
432    Local<JSValueRef> proto = Local<ObjectRef>(value)->GetPrototype(vm_);
433    std::unique_ptr<RemoteObject> protoObj = RemoteObject::FromTagged(vm_, proto);
434    CacheObjectIfNeeded(proto, protoObj.get());
435    std::unique_ptr<PropertyDescriptor> debuggerProperty = std::make_unique<PropertyDescriptor>();
436    debuggerProperty->SetName("__proto__")
437        .SetWritable(true)
438        .SetConfigurable(true)
439        .SetEnumerable(false)
440        .SetIsOwn(true)
441        .SetValue(std::move(protoObj));
442    outPropertyDesc->emplace_back(std::move(debuggerProperty));
443}
444
445void RuntimeImpl::GetAdditionalProperties(Local<JSValueRef> value,
446    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
447{
448    // The length of the TypedArray have to be limited(less than or equal to lengthTypedArrayLimit) until we construct
449    // the PropertyPreview class. Let lengthTypedArrayLimit be 10000 temporarily.
450    static const uint32_t lengthTypedArrayLimit = 10000;
451
452    // The width of the string-expression for JSTypedArray::MAX_TYPED_ARRAY_INDEX which is euqal to
453    // JSObject::MAX_ELEMENT_INDEX which is equal to std::numeric_limits<uint32_t>::max(). (42,9496,7295)
454    static const int32_t widthStrExprMaxElementIndex = 10;
455
456    if (value->IsTypedArray(vm_)) {
457        Local<TypedArrayRef> localTypedArrayRef(value);
458        uint32_t lengthTypedArray = localTypedArrayRef->ArrayLength(vm_);
459        if (lengthTypedArray > lengthTypedArrayLimit) {
460            LOG_DEBUGGER(ERROR) << "The length of the TypedArray is non-compliant or unsupported.";
461            return;
462        }
463        for (uint32_t i = 0; i < lengthTypedArray; ++i) {
464            Local<JSValueRef> localValRefElement = localTypedArrayRef->Get(vm_, i);
465            std::unique_ptr<RemoteObject> remoteObjElement = RemoteObject::FromTagged(vm_, localValRefElement);
466            remoteObjElement->SetObjectId(curObjectId_);
467            properties_[curObjectId_++] = Global<JSValueRef>(vm_, localValRefElement);
468            std::unique_ptr<PropertyDescriptor> debuggerProperty = std::make_unique<PropertyDescriptor>();
469
470            std::ostringstream osNameElement;
471            osNameElement << std::right << std::setw(widthStrExprMaxElementIndex) << i;
472            std::string cStrNameElement = osNameElement.str();
473            debuggerProperty->SetName(cStrNameElement)
474                .SetWritable(true)
475                .SetConfigurable(true)
476                .SetEnumerable(false)
477                .SetIsOwn(true)
478                .SetValue(std::move(remoteObjElement));
479            outPropertyDesc->emplace_back(std::move(debuggerProperty));
480        }
481    }
482}
483
484void RuntimeImpl::SetKeyValue(Local<JSValueRef> &jsValueRef,
485    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc, const std::string &strProName)
486{
487    std::unique_ptr<RemoteObject> remoteObj = RemoteObject::FromTagged(vm_, jsValueRef);
488    remoteObj->SetObjectId(curObjectId_);
489    properties_[curObjectId_++] = Global<JSValueRef>(vm_, jsValueRef);
490    std::unique_ptr<PropertyDescriptor> debuggerProperty = std::make_unique<PropertyDescriptor>();
491    debuggerProperty->SetName(strProName)
492        .SetWritable(false)
493        .SetConfigurable(false)
494        .SetEnumerable(false)
495        .SetIsOwn(false)
496        .SetValue(std::move(remoteObj));
497    outPropertyDesc->emplace_back(std::move(debuggerProperty));
498}
499
500void RuntimeImpl::GetPrimitiveNumberValue(Local<JSValueRef> value,
501    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
502{
503    Local<JSValueRef> jsValueRef;
504    jsValueRef = value->ToNumber(vm_);
505    SetKeyValue(jsValueRef, outPropertyDesc, "[[PrimitiveValue]]");
506}
507
508void RuntimeImpl::GetPrimitiveStringValue(Local<JSValueRef> value,
509    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
510{
511    Local<JSValueRef> jsValueRef;
512    jsValueRef = value->ToString(vm_);
513    SetKeyValue(jsValueRef, outPropertyDesc, "[[PrimitiveValue]]");
514}
515
516void RuntimeImpl::GetPrimitiveBooleanValue(Local<JSValueRef> value,
517    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
518{
519    Local<JSValueRef> jsValueRef;
520    Local<PrimitiveRef> primitiveRef(value);
521    jsValueRef = primitiveRef->GetValue(vm_);
522    SetKeyValue(jsValueRef, outPropertyDesc, "[[PrimitiveValue]]");
523}
524
525void RuntimeImpl::GetMapIteratorValue(Local<JSValueRef> value,
526    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
527{
528    Local<JSValueRef> jsValueRef;
529    Local<MapIteratorRef> iterRef = value->ToObject(vm_);
530    if (!iterRef.IsEmpty()) {
531        jsValueRef = NumberRef::New(vm_, iterRef->GetIndex());
532        SetKeyValue(jsValueRef, outPropertyDesc, "[[IteratorIndex]]");
533        jsValueRef = iterRef->GetKind(vm_);
534        SetKeyValue(jsValueRef, outPropertyDesc, "[[IteratorKind]]");
535    }
536}
537
538void RuntimeImpl::GetSetIteratorValue(Local<JSValueRef> value,
539    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
540{
541    Local<JSValueRef> jsValueRef;
542    Local<SetIteratorRef> iterRef = value->ToObject(vm_);
543    if (!iterRef.IsEmpty()) {
544        jsValueRef = NumberRef::New(vm_, iterRef->GetIndex());
545        SetKeyValue(jsValueRef, outPropertyDesc, "[[IteratorIndex]]");
546        jsValueRef = iterRef->GetKind(vm_);
547        SetKeyValue(jsValueRef, outPropertyDesc, "[[IteratorKind]]");
548    }
549}
550
551void RuntimeImpl::GetGeneratorFunctionValue(Local<JSValueRef> value,
552    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
553{
554    Local<JSValueRef> jsValueRef;
555    Local<GeneratorFunctionRef> genFuncRef = value->ToObject(vm_);
556    if (!genFuncRef.IsEmpty()) {
557        jsValueRef = BooleanRef::New(vm_, genFuncRef->IsGenerator(vm_));
558        SetKeyValue(jsValueRef, outPropertyDesc, "[[IsGenerator]]");
559    }
560}
561
562void RuntimeImpl::GetGeneratorObjectValue(Local<JSValueRef> value,
563    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
564{
565    Local<JSValueRef> jsValueRef;
566    Local<GeneratorObjectRef> genObjRef = value->ToObject(vm_);
567    if (!genObjRef.IsEmpty()) {
568        jsValueRef = genObjRef->GetGeneratorState(vm_);
569        SetKeyValue(jsValueRef, outPropertyDesc, "[[GeneratorState]]");
570        jsValueRef = genObjRef->GetGeneratorFunction(vm_);
571        SetKeyValue(jsValueRef, outPropertyDesc, "[[GeneratorFunction]]");
572        jsValueRef = JSNApi::GetGlobalObject(vm_);
573        SetKeyValue(jsValueRef, outPropertyDesc, "[[GeneratorReceiver]]");
574    }
575}
576
577void RuntimeImpl::GetNumberFormatValue(Local<JSValueRef> value,
578    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
579{
580    Local<NumberFormatRef> numberFormatRef = value->ToObject(vm_);
581    Local<JSValueRef> jsValueRef = numberFormatRef->GetFormatFunction(vm_);
582    SetKeyValue(jsValueRef, outPropertyDesc, "format");
583}
584
585void RuntimeImpl::GetCollatorValue(Local<JSValueRef> value,
586    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
587{
588    Local<CollatorRef> collatorRef = value->ToObject(vm_);
589    Local<JSValueRef> jsValueRef = collatorRef->GetCompareFunction(vm_);
590    SetKeyValue(jsValueRef, outPropertyDesc, "compare");
591}
592
593void RuntimeImpl::GetDateTimeFormatValue(Local<JSValueRef> value,
594    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
595{
596    Local<DataTimeFormatRef> dtFormatRef = value->ToObject(vm_);
597    Local<JSValueRef> jsValueRef = dtFormatRef->GetFormatFunction(vm_);
598    SetKeyValue(jsValueRef, outPropertyDesc, "format");
599}
600
601void RuntimeImpl::GetSharedMapValue(Local<JSValueRef> value,
602                                    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
603{
604    Local<SendableMapRef> sendableMapRef(value);
605    uint32_t size = sendableMapRef->GetSize(vm_);
606    uint32_t len = sendableMapRef->GetTotalElements(vm_);
607    uint32_t index = 0;
608    Local<JSValueRef> jsValueRef = NumberRef::New(vm_, size);
609    SetKeyValue(jsValueRef, outPropertyDesc, "size");
610    jsValueRef = ArrayRef::New(vm_, size);
611    for (uint32_t i = 0; i < len; ++i) {
612        Local<JSValueRef> jsKey = sendableMapRef->GetKey(vm_, i);
613        if (jsKey->IsHole()) {
614            continue;
615        }
616        Local<JSValueRef> jsValue = sendableMapRef->GetValue(vm_, i);
617        Local<ObjectRef> objRef = ObjectRef::New(vm_);
618        objRef->Set(vm_, StringRef::NewFromUtf8(vm_, "key"), jsKey);
619        objRef->Set(vm_, StringRef::NewFromUtf8(vm_, "value"), jsValue);
620        DebuggerApi::AddInternalProperties(vm_, objRef, ArkInternalValueType::Entry, internalObjects_);
621        ArrayRef::SetValueAt(vm_, jsValueRef, index++, objRef);
622    }
623    DebuggerApi::AddInternalProperties(vm_, jsValueRef, ArkInternalValueType::Entry, internalObjects_);
624    SetKeyValue(jsValueRef, outPropertyDesc, "[[Entries]]");
625}
626void RuntimeImpl::GetMapValue(Local<JSValueRef> value,
627    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
628{
629    Local<MapRef> mapRef = value->ToObject(vm_);
630    int32_t size = mapRef->GetSize(vm_);
631    int32_t len = mapRef->GetTotalElements(vm_);
632    int32_t index = 0;
633    Local<JSValueRef> jsValueRef = NumberRef::New(vm_, size);
634    SetKeyValue(jsValueRef, outPropertyDesc, "size");
635    jsValueRef = ArrayRef::New(vm_, size);
636    for (int32_t i = 0; i < len; ++i) {
637        Local<JSValueRef> jsKey = mapRef->GetKey(vm_, i);
638        if (jsKey->IsHole()) {
639            continue;
640        }
641        Local<JSValueRef> jsValue = mapRef->GetValue(vm_, i);
642        Local<ObjectRef> objRef = ObjectRef::New(vm_);
643        objRef->Set(vm_, StringRef::NewFromUtf8(vm_, "key"), jsKey);
644        objRef->Set(vm_, StringRef::NewFromUtf8(vm_, "value"), jsValue);
645        DebuggerApi::AddInternalProperties(vm_, objRef, ArkInternalValueType::Entry, internalObjects_);
646        ArrayRef::SetValueAt(vm_, jsValueRef, index++, objRef);
647    }
648    DebuggerApi::AddInternalProperties(vm_, jsValueRef, ArkInternalValueType::Entry, internalObjects_);
649    SetKeyValue(jsValueRef, outPropertyDesc, "[[Entries]]");
650}
651
652void RuntimeImpl::GetWeakMapValue(Local<JSValueRef> value,
653    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
654{
655    Local<WeakMapRef> weakMapRef = value->ToObject(vm_);
656    int32_t size = weakMapRef->GetSize(vm_);
657    int32_t len = weakMapRef->GetTotalElements(vm_);
658    int32_t index = 0;
659    Local<JSValueRef> jsValueRef = ArrayRef::New(vm_, size);
660    for (int32_t i = 0; i < len; i++) {
661        Local<JSValueRef> jsKey = weakMapRef->GetKey(vm_, i);
662        if (jsKey->IsHole() || !jsKey->IsObject(vm_)) {
663            continue;
664        }
665        Local<JSValueRef> jsValue = weakMapRef->GetValue(vm_, i);
666        Local<ObjectRef> objRef = ObjectRef::New(vm_);
667        objRef->Set(vm_, StringRef::NewFromUtf8(vm_, "key"), jsKey);
668        objRef->Set(vm_, StringRef::NewFromUtf8(vm_, "value"), jsValue);
669        DebuggerApi::AddInternalProperties(vm_, objRef, ArkInternalValueType::Entry, internalObjects_);
670        ArrayRef::SetValueAt(vm_, jsValueRef, index++, objRef);
671    }
672    DebuggerApi::AddInternalProperties(vm_, jsValueRef, ArkInternalValueType::Entry, internalObjects_);
673    SetKeyValue(jsValueRef, outPropertyDesc, "[[Entries]]");
674}
675
676void RuntimeImpl::GetSendableSetValue(Local<JSValueRef> value,
677                                      std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
678{
679    Local<SendableSetRef> setRef = value->ToObject(vm_);
680    uint32_t size = setRef->GetSize(vm_);
681    uint32_t len = setRef->GetTotalElements(vm_);
682    int32_t index = 0;
683    Local<JSValueRef> jsValueRef = NumberRef::New(vm_, size);
684    SetKeyValue(jsValueRef, outPropertyDesc, "size");
685    jsValueRef = ArrayRef::New(vm_, size);
686    for (uint32_t i = 0; i < len; ++i) {
687        Local<JSValueRef> elementRef = setRef->GetValue(vm_, i);
688        if (elementRef->IsHole()) {
689            continue;
690        } else if (elementRef->IsObject(vm_)) {
691            Local<ObjectRef> objRef = ObjectRef::New(vm_);
692            objRef->Set(vm_, StringRef::NewFromUtf8(vm_, "value"), elementRef);
693            DebuggerApi::AddInternalProperties(vm_, objRef, ArkInternalValueType::Entry, internalObjects_);
694            ArrayRef::SetValueAt(vm_, jsValueRef, index++, objRef);
695        } else {
696            ArrayRef::SetValueAt(vm_, jsValueRef, index++, elementRef);
697        }
698    }
699    DebuggerApi::AddInternalProperties(vm_, jsValueRef, ArkInternalValueType::Entry, internalObjects_);
700    SetKeyValue(jsValueRef, outPropertyDesc, "[[Entries]]");
701}
702
703void RuntimeImpl::GetSetValue(Local<JSValueRef> value,
704    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
705{
706    Local<SetRef> setRef = value->ToObject(vm_);
707    int32_t size = setRef->GetSize(vm_);
708    int32_t len = setRef->GetTotalElements(vm_);
709    int32_t index = 0;
710    Local<JSValueRef> jsValueRef = NumberRef::New(vm_, size);
711    SetKeyValue(jsValueRef, outPropertyDesc, "size");
712    jsValueRef = ArrayRef::New(vm_, size);
713    for (int32_t i = 0; i < len; ++i) {
714        Local<JSValueRef> elementRef = setRef->GetValue(vm_, i);
715        if (elementRef->IsHole()) {
716            continue;
717        } else if (elementRef->IsObject(vm_)) {
718            Local<ObjectRef> objRef = ObjectRef::New(vm_);
719            objRef->Set(vm_, StringRef::NewFromUtf8(vm_, "value"), elementRef);
720            DebuggerApi::AddInternalProperties(vm_, objRef, ArkInternalValueType::Entry, internalObjects_);
721            ArrayRef::SetValueAt(vm_, jsValueRef, index++, objRef);
722        } else {
723            ArrayRef::SetValueAt(vm_, jsValueRef, index++, elementRef);
724        }
725    }
726    DebuggerApi::AddInternalProperties(vm_, jsValueRef, ArkInternalValueType::Entry, internalObjects_);
727    SetKeyValue(jsValueRef, outPropertyDesc, "[[Entries]]");
728}
729
730void RuntimeImpl::GetWeakSetValue(Local<JSValueRef> value,
731    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
732{
733    Local<WeakSetRef> weakSetRef = value->ToObject(vm_);
734    int32_t size = weakSetRef->GetSize(vm_);
735    int32_t len = weakSetRef->GetTotalElements(vm_);
736    int32_t index = 0;
737    Local<JSValueRef> jsValueRef = ArrayRef::New(vm_, size);
738    for (int32_t i = 0; i < len; ++i) {
739        Local<JSValueRef> elementRef = weakSetRef->GetValue(vm_, i);
740        if (elementRef->IsHole()) {
741            continue;
742        }
743        Local<ObjectRef> objRef = ObjectRef::New(vm_);
744        objRef->Set(vm_, StringRef::NewFromUtf8(vm_, "value"), elementRef);
745        DebuggerApi::AddInternalProperties(vm_, objRef, ArkInternalValueType::Entry, internalObjects_);
746        ArrayRef::SetValueAt(vm_, jsValueRef, index++, objRef);
747    }
748    DebuggerApi::AddInternalProperties(vm_, jsValueRef, ArkInternalValueType::Entry, internalObjects_);
749    SetKeyValue(jsValueRef, outPropertyDesc, "[[Entries]]");
750}
751
752void RuntimeImpl::GetDataViewValue(Local<JSValueRef> value,
753    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
754{
755    Local<DataViewRef> dataViewRef = value->ToObject(vm_);
756    int32_t byteLength = static_cast<int32_t>(dataViewRef->ByteLength());
757    int32_t byteOffset = static_cast<int32_t>(dataViewRef->ByteOffset());
758    Local<JSValueRef> jsValueRef = dataViewRef->GetArrayBuffer(vm_);
759    SetKeyValue(jsValueRef, outPropertyDesc, "buffer");
760    jsValueRef = NumberRef::New(vm_, byteLength);
761    SetKeyValue(jsValueRef, outPropertyDesc, "byteLength");
762    jsValueRef = NumberRef::New(vm_, byteOffset);
763    SetKeyValue(jsValueRef, outPropertyDesc, "byteOffset");
764}
765
766void RuntimeImpl::GetRegExpValue(Local<JSValueRef> value,
767    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
768{
769    Local<RegExpRef> regExpRef = value->ToObject(vm_);
770    Local<JSValueRef> jsValueRef = regExpRef->IsGlobal(vm_);
771    SetKeyValue(jsValueRef, outPropertyDesc, "global");
772    jsValueRef = regExpRef->IsIgnoreCase(vm_);
773    SetKeyValue(jsValueRef, outPropertyDesc, "ignoreCase");
774    jsValueRef = regExpRef->IsMultiline(vm_);
775    SetKeyValue(jsValueRef, outPropertyDesc, "multiline");
776    jsValueRef = regExpRef->IsDotAll(vm_);
777    SetKeyValue(jsValueRef, outPropertyDesc, "dotAll");
778    SetKeyValue(jsValueRef, outPropertyDesc, "hasIndices");
779    jsValueRef = regExpRef->IsUtf16(vm_);
780    SetKeyValue(jsValueRef, outPropertyDesc, "unicode");
781    jsValueRef = regExpRef->IsStick(vm_);
782    SetKeyValue(jsValueRef, outPropertyDesc, "sticky");
783    std::string strFlags = regExpRef->GetOriginalFlags(vm_);
784    jsValueRef = StringRef::NewFromUtf8(vm_, strFlags.c_str());
785    SetKeyValue(jsValueRef, outPropertyDesc, "flags");
786    std::string strSource = regExpRef->GetOriginalSource(vm_)->ToString(vm_);
787    jsValueRef = StringRef::NewFromUtf8(vm_, strSource.c_str());
788    SetKeyValue(jsValueRef, outPropertyDesc, "source");
789}
790
791void RuntimeImpl::GetArrayListValue(Local<JSValueRef> value,
792    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
793{
794    Local<JSValueRef> jsValueRef = DebuggerApi::GetArrayListValue(vm_, value, internalObjects_);
795    Local<JSValueRef> size = NumberRef::New(vm_, DebuggerApi::GetContainerLength(vm_, jsValueRef));
796    SetKeyValue(size, outPropertyDesc, "size");
797    SetKeyValue(jsValueRef, outPropertyDesc, "[[ArrayList]]");
798}
799
800void RuntimeImpl::GetDequeValue(Local<JSValueRef> value,
801    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
802{
803    Local<JSValueRef> jsValueRef = DebuggerApi::GetDequeValue(vm_, value, internalObjects_);
804    Local<JSValueRef> size = NumberRef::New(vm_, DebuggerApi::GetContainerLength(vm_, jsValueRef));
805    SetKeyValue(size, outPropertyDesc, "size");
806    SetKeyValue(jsValueRef, outPropertyDesc, "[[Deque]]");
807}
808
809void RuntimeImpl::GetHashMapValue(Local<JSValueRef> value,
810    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
811{
812    Local<JSValueRef> jsValueRef = DebuggerApi::GetHashMapValue(vm_, value, internalObjects_);
813    Local<JSValueRef> size = NumberRef::New(vm_, DebuggerApi::GetContainerLength(vm_, jsValueRef));
814    SetKeyValue(size, outPropertyDesc, "size");
815    SetKeyValue(jsValueRef, outPropertyDesc, "[[HashMap]]");
816}
817
818void RuntimeImpl::GetHashSetValue(Local<JSValueRef> value,
819    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
820{
821    Local<JSValueRef> jsValueRef = DebuggerApi::GetHashSetValue(vm_, value, internalObjects_);
822    Local<JSValueRef> size = NumberRef::New(vm_, DebuggerApi::GetContainerLength(vm_, jsValueRef));
823    SetKeyValue(size, outPropertyDesc, "size");
824    SetKeyValue(jsValueRef, outPropertyDesc, "[[HashSet]]");
825}
826
827void RuntimeImpl::GetLightWeightMapValue(Local<JSValueRef> value,
828    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
829{
830    Local<JSValueRef> jsValueRef = DebuggerApi::GetLightWeightMapValue(vm_, value, internalObjects_);
831    Local<JSValueRef> size = NumberRef::New(vm_, DebuggerApi::GetContainerLength(vm_, jsValueRef));
832    SetKeyValue(size, outPropertyDesc, "size");
833    SetKeyValue(jsValueRef, outPropertyDesc, "[[LightWeightMap]]");
834}
835
836void RuntimeImpl::GetLightWeightSetValue(Local<JSValueRef> value,
837    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
838{
839    Local<JSValueRef> jsValueRef = DebuggerApi::GetLightWeightSetValue(vm_, value, internalObjects_);
840    Local<JSValueRef> size = NumberRef::New(vm_, DebuggerApi::GetContainerLength(vm_, jsValueRef));
841    SetKeyValue(size, outPropertyDesc, "size");
842    SetKeyValue(jsValueRef, outPropertyDesc, "[[LightWeightSet]]");
843}
844
845void RuntimeImpl::GetLinkedListValue(Local<JSValueRef> value,
846    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
847{
848    Local<JSValueRef> jsValueRef = DebuggerApi::GetLinkedListValue(vm_, value, internalObjects_);
849    Local<JSValueRef> size = NumberRef::New(vm_, DebuggerApi::GetContainerLength(vm_, jsValueRef));
850    SetKeyValue(size, outPropertyDesc, "size");
851    SetKeyValue(jsValueRef, outPropertyDesc, "[[LinkedList]]");
852}
853
854void RuntimeImpl::GetListValue(Local<JSValueRef> value,
855    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
856{
857    Local<JSValueRef> jsValueRef = DebuggerApi::GetListValue(vm_, value, internalObjects_);
858    Local<JSValueRef> size = NumberRef::New(vm_, DebuggerApi::GetContainerLength(vm_, jsValueRef));
859    SetKeyValue(size, outPropertyDesc, "size");
860    SetKeyValue(jsValueRef, outPropertyDesc, "[[List]]");
861}
862
863void RuntimeImpl::GetPlainArrayValue(Local<JSValueRef> value,
864    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
865{
866    Local<JSValueRef> jsValueRef = DebuggerApi::GetPlainArrayValue(vm_, value, internalObjects_);
867    Local<JSValueRef> size = NumberRef::New(vm_, DebuggerApi::GetContainerLength(vm_, jsValueRef));
868    SetKeyValue(size, outPropertyDesc, "size");
869    SetKeyValue(jsValueRef, outPropertyDesc, "[[PlainArray]]");
870}
871
872void RuntimeImpl::GetQueueValue(Local<JSValueRef> value,
873    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
874{
875    Local<JSValueRef> jsValueRef = DebuggerApi::GetQueueValue(vm_, value, internalObjects_);
876    Local<JSValueRef> size = NumberRef::New(vm_, DebuggerApi::GetContainerLength(vm_, jsValueRef));
877    SetKeyValue(size, outPropertyDesc, "size");
878    SetKeyValue(jsValueRef, outPropertyDesc, "[[Queue]]");
879}
880
881void RuntimeImpl::GetStackValue(Local<JSValueRef> value,
882    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
883{
884    Local<JSValueRef> jsValueRef = DebuggerApi::GetStackValue(vm_, value, internalObjects_);
885    Local<JSValueRef> size = NumberRef::New(vm_, DebuggerApi::GetContainerLength(vm_, jsValueRef));
886    SetKeyValue(size, outPropertyDesc, "size");
887    SetKeyValue(jsValueRef, outPropertyDesc, "[[Stack]]");
888}
889
890void RuntimeImpl::GetTreeMapValue(Local<JSValueRef> value,
891    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
892{
893    Local<JSValueRef> jsValueRef = DebuggerApi::GetTreeMapValue(vm_, value, internalObjects_);
894    Local<JSValueRef> size = NumberRef::New(vm_, DebuggerApi::GetContainerLength(vm_, jsValueRef));
895    SetKeyValue(size, outPropertyDesc, "size");
896    SetKeyValue(jsValueRef, outPropertyDesc, "[[TreeMap]]");
897}
898
899void RuntimeImpl::GetTreeSetValue(Local<JSValueRef> value,
900    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
901{
902    Local<JSValueRef> jsValueRef = DebuggerApi::GetTreeSetValue(vm_, value, internalObjects_);
903    Local<JSValueRef> size = NumberRef::New(vm_, DebuggerApi::GetContainerLength(vm_, jsValueRef));
904    SetKeyValue(size, outPropertyDesc, "size");
905    SetKeyValue(jsValueRef, outPropertyDesc, "[[TreeSet]]");
906}
907
908void RuntimeImpl::GetVectorValue(Local<JSValueRef> value,
909    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
910{
911    Local<JSValueRef> jsValueRef = DebuggerApi::GetVectorValue(vm_, value, internalObjects_);
912    Local<JSValueRef> size = NumberRef::New(vm_, DebuggerApi::GetContainerLength(vm_, jsValueRef));
913    SetKeyValue(size, outPropertyDesc, "size");
914    SetKeyValue(jsValueRef, outPropertyDesc, "[[Vector]]");
915}
916
917void RuntimeImpl::GetProxyValue(Local<JSValueRef> value,
918    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
919{
920    Local<ProxyRef> proxyRef = value->ToObject(vm_);
921    if (proxyRef.IsEmpty()) {
922        return;
923    }
924    Local<JSValueRef> target = proxyRef->GetTarget(vm_);
925    SetKeyValue(target, outPropertyDesc, "[[Target]]");
926    Local<JSValueRef> handler = proxyRef->GetHandler(vm_);
927    SetKeyValue(handler, outPropertyDesc, "[[Handler]]");
928    Local<JSValueRef> isRevoked = BooleanRef::New(vm_, proxyRef->IsRevoked());
929    SetKeyValue(isRevoked, outPropertyDesc, "[[IsRevoked]]");
930}
931
932void RuntimeImpl::GetPromiseValue(Local<JSValueRef> value,
933    std::vector<std::unique_ptr<PropertyDescriptor>> *outPropertyDesc)
934{
935    Local<PromiseRef> promiseRef = value->ToObject(vm_);
936    if (promiseRef.IsEmpty()) {
937        return;
938    }
939    Local<JSValueRef> promiseState = promiseRef->GetPromiseState(vm_);
940    SetKeyValue(promiseState, outPropertyDesc, "[[PromiseState]]");
941    Local<JSValueRef> promiseResult = promiseRef->GetPromiseResult(vm_);
942    SetKeyValue(promiseResult, outPropertyDesc, "[[PromiseResult]]");
943}
944}  // namespace panda::ecmascript::tooling
945