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 ¶ms,
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