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