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