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