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