• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
25 namespace panda::ecmascript::tooling {
26 // Whenever adding a new protocol which is not a standard CDP protocol,
27 // must add its methodName to the runtimeProtocolsList
InitializeExtendedProtocolsList()28 void RuntimeImpl::InitializeExtendedProtocolsList()
29 {
30     std::vector<std::string> runtimeProtocolList {};
31     runtimeExtendedProtocols_ = std::move(runtimeProtocolList);
32 }
33 
Dispatch(const DispatchRequest & request)34 void 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 
GetMethodEnum(const std::string & method)60 RuntimeImpl::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 
Enable(const DispatchRequest & request)77 void 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 
Disable(const DispatchRequest & request)85 void RuntimeImpl::DispatcherImpl::Disable(const DispatchRequest &request)
86 {
87     DispatchResponse response = runtime_->Disable();
88     SendResponse(request, response);
89 }
90 
RunIfWaitingForDebugger(const DispatchRequest & request)91 void RuntimeImpl::DispatcherImpl::RunIfWaitingForDebugger(const DispatchRequest &request)
92 {
93     DispatchResponse response = runtime_->RunIfWaitingForDebugger();
94     SendResponse(request, response);
95 }
96 
GetProperties(const DispatchRequest & request)97 void 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 
GetHeapUsage(const DispatchRequest & request)122 void 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 
AllowNotify() const131 bool RuntimeImpl::Frontend::AllowNotify() const
132 {
133     return channel_ != nullptr;
134 }
135 
RunIfWaitingForDebugger()136 void RuntimeImpl::Frontend::RunIfWaitingForDebugger()
137 {
138     if (!AllowNotify()) {
139         return;
140     }
141 
142     channel_->RunIfWaitingForDebugger();
143 }
144 
Enable()145 DispatchResponse RuntimeImpl::Enable()
146 {
147     internalObjects_ = Global<MapRef>(vm_, MapRef::New(vm_));
148     return DispatchResponse::Ok();
149 }
150 
Disable()151 DispatchResponse RuntimeImpl::Disable()
152 {
153     internalObjects_.FreeGlobalHandleAddr();
154     return DispatchResponse::Ok();
155 }
156 
RunIfWaitingForDebugger()157 DispatchResponse RuntimeImpl::RunIfWaitingForDebugger()
158 {
159     frontend_.RunIfWaitingForDebugger();
160     return DispatchResponse::Ok();
161 }
162 
GetHeapUsage(double * usedSize,double * totalSize)163 DispatchResponse 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 
GetProperties(const GetPropertiesParams & params,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc,std::optional<std::vector<std::unique_ptr<InternalPropertyDescriptor>>> * outInternalDescs,std::optional<std::vector<std::unique_ptr<PrivatePropertyDescriptor>>> * outPrivateProps,std::optional<std::unique_ptr<ExceptionDetails>> * outExceptionDetails)175 DispatchResponse 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 
AddTypedArrayRefs(Local<ArrayBufferRef> arrayBufferRef,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)332 void 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 
AddSharedArrayBufferRefs(Local<ArrayBufferRef> arrayBufferRef,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)362 void 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 
385 template <typename TypedArrayRef>
AddTypedArrayRef(Local<ArrayBufferRef> arrayBufferRef,int32_t length,const char * name,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)386 void 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 
CacheObjectIfNeeded(Local<JSValueRef> valRef,RemoteObject * remoteObj)403 void 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 
GetProtoOrProtoType(Local<JSValueRef> value,bool isOwn,bool isAccessorOnly,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)411 void 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 
GetAdditionalProperties(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)445 void 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 
SetKeyValue(Local<JSValueRef> & jsValueRef,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc,const std::string & strProName)484 void 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 
GetPrimitiveNumberValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)500 void 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 
GetPrimitiveStringValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)508 void 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 
GetPrimitiveBooleanValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)516 void 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 
GetMapIteratorValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)525 void 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 
GetSetIteratorValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)538 void 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 
GetGeneratorFunctionValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)551 void 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 
GetGeneratorObjectValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)562 void 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 
GetNumberFormatValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)577 void 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 
GetCollatorValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)585 void 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 
GetDateTimeFormatValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)593 void 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 
GetSharedMapValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)601 void 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 }
GetMapValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)626 void 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 
GetWeakMapValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)652 void 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 
GetSendableSetValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)676 void 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 
GetSetValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)703 void 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 
GetWeakSetValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)730 void 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 
GetDataViewValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)752 void 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 
GetRegExpValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)766 void 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 
GetArrayListValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)791 void 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 
GetDequeValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)800 void 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 
GetHashMapValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)809 void 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 
GetHashSetValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)818 void 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 
GetLightWeightMapValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)827 void 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 
GetLightWeightSetValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)836 void 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 
GetLinkedListValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)845 void 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 
GetListValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)854 void 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 
GetPlainArrayValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)863 void 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 
GetQueueValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)872 void 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 
GetStackValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)881 void 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 
GetTreeMapValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)890 void 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 
GetTreeSetValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)899 void 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 
GetVectorValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)908 void 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 
GetProxyValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)917 void 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 
GetPromiseValue(Local<JSValueRef> value,std::vector<std::unique_ptr<PropertyDescriptor>> * outPropertyDesc)932 void 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