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