1 /*
2 * Copyright (c) 2021-2022 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 "ecmascript/debugger/debugger_api.h"
17
18 #include "ecmascript/debugger/js_debugger.h"
19 #include "ecmascript/interpreter/slow_runtime_stub.h"
20 #include "ecmascript/interpreter/fast_runtime_stub-inl.h"
21 #include "ecmascript/tagged_hash_array.h"
22 #include "ecmascript/tagged_tree.h"
23 #include "ecmascript/js_api/js_api_hashset.h"
24 #include "ecmascript/js_api/js_api_tree_map.h"
25 #include "ecmascript/js_api/js_api_tree_set.h"
26 #include "ecmascript/js_api/js_api_lightweightmap.h"
27 #include "ecmascript/js_api/js_api_lightweightset.h"
28 #include "ecmascript/jobs/micro_job_queue.h"
29 #include "ecmascript/module/module_resolver.h"
30
31 namespace panda::ecmascript::tooling {
32 using panda::ecmascript::base::ALLOW_BINARY;
33 using panda::ecmascript::base::ALLOW_HEX;
34 using panda::ecmascript::base::ALLOW_OCTAL;
35 using panda::ecmascript::base::NumberHelper;
36 using ecmascript::JSAPIArrayList;
37 using ecmascript::JSAPIDeque;
38 using ecmascript::JSAPIHashMap;
39 using ecmascript::JSAPIHashSet;
40 using ecmascript::JSAPILightWeightMap;
41 using ecmascript::JSAPILightWeightSet;
42 using ecmascript::JSAPIList;
43 using ecmascript::JSAPILinkedList;
44 using ecmascript::JSAPIPlainArray;
45 using ecmascript::JSAPIStack;
46 using ecmascript::JSAPIQueue;
47 using ecmascript::JSAPITreeSet;
48 using ecmascript::JSAPITreeMap;
49 using ecmascript::JSAPIVector;
50 using ecmascript::LinkedNode;
51 using ecmascript::TaggedHashArray;
52 using ecmascript::TaggedNode;
53 using ecmascript::RBTreeNode;
54 using ecmascript::TaggedTreeSet;
55 using ecmascript::TaggedTreeMap;
56 using ecmascript::TaggedQueue;
57
58 // FrameHandler
GetStackDepth(const EcmaVM * ecmaVm)59 uint32_t DebuggerApi::GetStackDepth(const EcmaVM *ecmaVm)
60 {
61 uint32_t count = 0;
62 FrameHandler frameHandler(ecmaVm->GetJSThread());
63 for (; frameHandler.HasFrame(); frameHandler.PrevJSFrame()) {
64 if (frameHandler.IsEntryFrame() || frameHandler.IsBuiltinFrame()) {
65 continue;
66 }
67 ++count;
68 }
69 return count;
70 }
71
NewFrameHandler(const EcmaVM * ecmaVm)72 std::shared_ptr<FrameHandler> DebuggerApi::NewFrameHandler(const EcmaVM *ecmaVm)
73 {
74 return std::make_shared<FrameHandler>(ecmaVm->GetJSThread());
75 }
76
StackWalker(const EcmaVM * ecmaVm,std::function<StackState (const FrameHandler *)> func)77 bool DebuggerApi::StackWalker(const EcmaVM *ecmaVm, std::function<StackState(const FrameHandler *)> func)
78 {
79 FrameHandler frameHandler(ecmaVm->GetJSThread());
80 for (; frameHandler.HasFrame(); frameHandler.PrevJSFrame()) {
81 if (frameHandler.IsEntryFrame() || frameHandler.IsBuiltinFrame()) {
82 continue;
83 }
84 StackState state = func(&frameHandler);
85 if (state == StackState::CONTINUE) {
86 continue;
87 }
88 if (state == StackState::FAILED) {
89 return false;
90 }
91 return true;
92 }
93 return true;
94 }
95
GetStackDepthOverBuiltin(const EcmaVM * ecmaVm)96 uint32_t DebuggerApi::GetStackDepthOverBuiltin(const EcmaVM *ecmaVm)
97 {
98 uint32_t count = 0;
99 FrameHandler frameHandler(ecmaVm->GetJSThread());
100 for (; frameHandler.HasFrame(); frameHandler.PrevJSFrame()) {
101 if (frameHandler.IsEntryFrame()) {
102 if (frameHandler.IsInterpreterBuiltinFrame()) {
103 break;
104 }
105 continue;
106 }
107 if (frameHandler.IsBuiltinFrame()) {
108 break;
109 }
110 ++count;
111 }
112 return count;
113 }
114
GetBytecodeOffset(const EcmaVM * ecmaVm)115 uint32_t DebuggerApi::GetBytecodeOffset(const EcmaVM *ecmaVm)
116 {
117 return FrameHandler(ecmaVm->GetJSThread()).GetBytecodeOffset();
118 }
119
GetMethod(const EcmaVM * ecmaVm)120 std::unique_ptr<PtMethod> DebuggerApi::GetMethod(const EcmaVM *ecmaVm)
121 {
122 FrameHandler frameHandler(ecmaVm->GetJSThread());
123 Method* method = frameHandler.GetMethod();
124 std::unique_ptr<PtMethod> ptMethod = std::make_unique<PtMethod>(
125 method->GetJSPandaFile(), method->GetMethodId(), method->IsNativeWithCallField());
126 return ptMethod;
127 }
128
SetVRegValue(FrameHandler * frameHandler,size_t index,Local<JSValueRef> value)129 void DebuggerApi::SetVRegValue(FrameHandler *frameHandler, size_t index, Local<JSValueRef> value)
130 {
131 return frameHandler->SetVRegValue(index, JSNApiHelper::ToJSTaggedValue(*value));
132 }
133
GetBytecodeOffset(const FrameHandler * frameHandler)134 uint32_t DebuggerApi::GetBytecodeOffset(const FrameHandler *frameHandler)
135 {
136 return frameHandler->GetBytecodeOffset();
137 }
138
GetMethod(const FrameHandler * frameHandler)139 Method *DebuggerApi::GetMethod(const FrameHandler *frameHandler)
140 {
141 return frameHandler->GetMethod();
142 }
143
IsNativeMethod(const EcmaVM * ecmaVm)144 bool DebuggerApi::IsNativeMethod(const EcmaVM *ecmaVm)
145 {
146 FrameHandler frameHandler(ecmaVm->GetJSThread());
147 return DebuggerApi::IsNativeMethod(&frameHandler);
148 }
149
IsNativeMethod(const FrameHandler * frameHandler)150 bool DebuggerApi::IsNativeMethod(const FrameHandler *frameHandler)
151 {
152 if (!frameHandler->HasFrame()) {
153 return false;
154 }
155 Method* method = frameHandler->GetMethod();
156 return method->IsNativeWithCallField();
157 }
158
GetJSPandaFile(const EcmaVM * ecmaVm)159 JSPandaFile *DebuggerApi::GetJSPandaFile(const EcmaVM *ecmaVm)
160 {
161 Method *method = FrameHandler(ecmaVm->GetJSThread()).GetMethod();
162 return const_cast<JSPandaFile *>(method->GetJSPandaFile());
163 }
164
GetEnv(const FrameHandler * frameHandler)165 JSTaggedValue DebuggerApi::GetEnv(const FrameHandler *frameHandler)
166 {
167 return frameHandler->GetEnv();
168 }
169
GetSp(const FrameHandler * frameHandler)170 JSTaggedType *DebuggerApi::GetSp(const FrameHandler *frameHandler)
171 {
172 return frameHandler->GetSp();
173 }
174
GetVregIndex(const FrameHandler * frameHandler,std::string_view name)175 int32_t DebuggerApi::GetVregIndex(const FrameHandler *frameHandler, std::string_view name)
176 {
177 Method *method = DebuggerApi::GetMethod(frameHandler);
178 if (method->IsNativeWithCallField()) {
179 LOG_DEBUGGER(ERROR) << "GetVregIndex: native frame not support";
180 return -1;
181 }
182 DebugInfoExtractor *extractor = JSPandaFileManager::GetInstance()->GetJSPtExtractor(method->GetJSPandaFile());
183 if (extractor == nullptr) {
184 LOG_DEBUGGER(ERROR) << "GetVregIndex: extractor is null";
185 return -1;
186 }
187
188 uint32_t currentOffset = frameHandler->GetBytecodeOffset();
189 int32_t regNumber = -1;
190 uint32_t startOffset = 0;
191 uint32_t endOffset = UINT32_MAX;
192 auto table = extractor->GetLocalVariableTable(method->GetMethodId());
193 for (auto iter = table.begin(); iter != table.end(); iter++) {
194 // if currentOffset not in variable's scope, skip it
195 if (iter->name == name.data() && currentOffset >= iter->startOffset && currentOffset < iter->endOffset) {
196 // if there are multiple variables with the same name, get regNumber with the smallest scope
197 if (iter->startOffset >= startOffset && iter->endOffset <= endOffset) {
198 regNumber = iter->regNumber;
199 startOffset = iter->startOffset;
200 endOffset = iter->endOffset;
201 }
202 }
203 }
204 if (regNumber != -1) {
205 return regNumber;
206 }
207 return -1;
208 }
209
GetVRegValue(const EcmaVM * ecmaVm,const FrameHandler * frameHandler,size_t index)210 Local<JSValueRef> DebuggerApi::GetVRegValue(const EcmaVM *ecmaVm,
211 const FrameHandler *frameHandler, size_t index)
212 {
213 auto value = frameHandler->GetVRegValue(index);
214 JSHandle<JSTaggedValue> handledValue(ecmaVm->GetJSThread(), value);
215 return JSNApiHelper::ToLocal<JSValueRef>(handledValue);
216 }
217
218 // JSThread
GetAndClearException(const EcmaVM * ecmaVm)219 Local<JSValueRef> DebuggerApi::GetAndClearException(const EcmaVM *ecmaVm)
220 {
221 auto exception = ecmaVm->GetJSThread()->GetException();
222 JSHandle<JSTaggedValue> handledException(ecmaVm->GetJSThread(), exception);
223 ecmaVm->GetJSThread()->ClearException();
224 return JSNApiHelper::ToLocal<JSValueRef>(handledException);
225 }
226
SetException(const EcmaVM * ecmaVm,Local<JSValueRef> exception)227 void DebuggerApi::SetException(const EcmaVM *ecmaVm, Local<JSValueRef> exception)
228 {
229 ecmaVm->GetJSThread()->SetException(JSNApiHelper::ToJSTaggedValue(*exception));
230 }
231
ClearException(const EcmaVM * ecmaVm)232 void DebuggerApi::ClearException(const EcmaVM *ecmaVm)
233 {
234 return ecmaVm->GetJSThread()->ClearException();
235 }
236
237 // NumberHelper
StringToDouble(const uint8_t * start,const uint8_t * end,uint8_t radix)238 double DebuggerApi::StringToDouble(const uint8_t *start, const uint8_t *end, uint8_t radix)
239 {
240 return NumberHelper::StringToDouble(start, end, radix, ALLOW_BINARY | ALLOW_HEX | ALLOW_OCTAL);
241 }
242
243 // JSDebugger
CreateJSDebugger(const EcmaVM * ecmaVm)244 JSDebugger *DebuggerApi::CreateJSDebugger(const EcmaVM *ecmaVm)
245 {
246 return new JSDebugger(ecmaVm);
247 }
248
DestroyJSDebugger(JSDebugger * debugger)249 void DebuggerApi::DestroyJSDebugger(JSDebugger *debugger)
250 {
251 delete debugger;
252 }
253
RegisterHooks(JSDebugger * debugger,PtHooks * hooks)254 void DebuggerApi::RegisterHooks(JSDebugger *debugger, PtHooks *hooks)
255 {
256 debugger->RegisterHooks(hooks);
257 }
258
SetBreakpoint(JSDebugger * debugger,const JSPtLocation & location,Local<FunctionRef> condFuncRef,bool isSmartBreakpoint)259 bool DebuggerApi::SetBreakpoint(JSDebugger *debugger, const JSPtLocation &location,
260 Local<FunctionRef> condFuncRef, bool isSmartBreakpoint)
261 {
262 if (isSmartBreakpoint) {
263 return debugger->SetSmartBreakpoint(location);
264 }
265 return debugger->SetBreakpoint(location, condFuncRef);
266 }
267
RemoveBreakpoint(JSDebugger * debugger,const JSPtLocation & location)268 bool DebuggerApi::RemoveBreakpoint(JSDebugger *debugger, const JSPtLocation &location)
269 {
270 return debugger->RemoveBreakpoint(location);
271 }
272
RemoveAllBreakpoints(JSDebugger * debugger)273 void DebuggerApi::RemoveAllBreakpoints(JSDebugger *debugger)
274 {
275 return debugger->RemoveAllBreakpoints();
276 }
277
SetSingleStepStatus(JSDebugger * debugger,bool status)278 void DebuggerApi::SetSingleStepStatus(JSDebugger *debugger, bool status)
279 {
280 return debugger->SetSingleStepStatus(status);
281 }
282
GetSingleStepStatus(JSDebugger * debugger)283 bool DebuggerApi::GetSingleStepStatus(JSDebugger *debugger)
284 {
285 return debugger->GetSingleStepStatus();
286 }
287
GetObjectHash(const EcmaVM * ecmaVM,const JSHandle<JSTaggedValue> & tagged)288 int32_t DebuggerApi::GetObjectHash(const EcmaVM *ecmaVM, const JSHandle<JSTaggedValue> &tagged)
289 {
290 if (!tagged->IsECMAObject()) {
291 return 0;
292 }
293 bool hasHash = ECMAObject::Cast(tagged->GetTaggedObject())->HasHash();
294 if (!hasHash) {
295 int32_t hash = base::RandomGenerator::GenerateIdentityHash();
296 auto ecmaObj = ECMAObject::Cast(tagged->GetTaggedObject());
297 JSHandle<ECMAObject> ecmaObjHandle(ecmaVM->GetJSThread(), ecmaObj);
298 ECMAObject::SetHash(ecmaVM->GetJSThread(), hash, ecmaObjHandle);
299 return hash;
300 } else {
301 return ECMAObject::Cast(tagged->GetTaggedObject())->GetHash();
302 }
303 }
304
GetObjectHashCode(const EcmaVM * ecmaVM,const JSHandle<JSTaggedValue> & tagged)305 int32_t DebuggerApi::GetObjectHashCode(const EcmaVM *ecmaVM, const JSHandle<JSTaggedValue> &tagged)
306 {
307 if (!tagged->IsECMAObject()) {
308 return 0;
309 }
310 int32_t hash = ECMAObject::Cast(tagged->GetTaggedObject())->GetHash();
311 if (hash == 0) {
312 hash = base::RandomGenerator::GenerateIdentityHash();
313 auto ecmaObjHandle = JSHandle<ECMAObject>::Cast(tagged);
314 ECMAObject::SetHash(ecmaVM->GetJSThread(), hash, ecmaObjHandle);
315 }
316 return hash;
317 }
318
GetObjectClassName(const EcmaVM * ecmaVM,Local<JSValueRef> & tagged,std::string & className)319 void DebuggerApi::GetObjectClassName(const EcmaVM *ecmaVM, Local<JSValueRef> &tagged, std::string &className)
320 {
321 if (!tagged->IsObject(ecmaVM)) {
322 return;
323 }
324 Local<JSValueRef> prototype = Local<ObjectRef>(tagged)->GetPrototype(ecmaVM);
325 Local<StringRef> key = StringRef::NewFromUtf8(ecmaVM, "constructor");
326 PropertyAttribute protoProperty = PropertyAttribute::Default();
327 if (!Local<ObjectRef>(prototype)->GetOwnProperty(ecmaVM, key, protoProperty)) {
328 LOG_DEBUGGER(DEBUG) << "DebuggerApi::GetObjectClassName get property [constructor] failed";
329 return;
330 }
331 Local<JSValueRef> constructor = protoProperty.GetValue(ecmaVM);
332 if (!constructor->IsNull()) {
333 Local<StringRef> constructorFuncName = Local<FunctionRef>(constructor)->GetName(ecmaVM);
334 className = constructorFuncName->ToString(ecmaVM);
335 }
336 }
337
RemoveBreakpointsByUrl(JSDebugger * debugger,const std::string & url)338 bool DebuggerApi::RemoveBreakpointsByUrl(JSDebugger *debugger, const std::string &url)
339 {
340 return debugger->RemoveBreakpointsByUrl(url);
341 }
342
DisableFirstTimeFlag(JSDebugger * debugger)343 void DebuggerApi::DisableFirstTimeFlag(JSDebugger *debugger)
344 {
345 return debugger->DisableFirstTimeFlag();
346 }
347
348 // ScopeInfo
GetProperties(const EcmaVM * ecmaVm,const FrameHandler * frameHandler,int32_t level,uint32_t slot)349 Local<JSValueRef> DebuggerApi::GetProperties(const EcmaVM *ecmaVm, const FrameHandler *frameHandler,
350 int32_t level, uint32_t slot)
351 {
352 JSTaggedValue env = frameHandler->GetEnv();
353 for (int i = 0; i < level; i++) {
354 JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv();
355 ASSERT(!taggedParentEnv.IsUndefined());
356 env = taggedParentEnv;
357 }
358 JSTaggedValue value = LexicalEnv::Cast(env.GetTaggedObject())->GetProperties(slot);
359 JSHandle<JSTaggedValue> handledValue(ecmaVm->GetJSThread(), value);
360 return JSNApiHelper::ToLocal<JSValueRef>(handledValue);
361 }
362
SetProperties(const EcmaVM * ecmaVm,const FrameHandler * frameHandler,int32_t level,uint32_t slot,Local<JSValueRef> value)363 void DebuggerApi::SetProperties(const EcmaVM *ecmaVm, const FrameHandler *frameHandler,
364 int32_t level, uint32_t slot, Local<JSValueRef> value)
365 {
366 JSTaggedValue env = frameHandler->GetEnv();
367 for (int i = 0; i < level; i++) {
368 JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv();
369 ASSERT(!taggedParentEnv.IsUndefined());
370 env = taggedParentEnv;
371 }
372 JSTaggedValue target = JSNApiHelper::ToJSHandle(value).GetTaggedValue();
373 LexicalEnv::Cast(env.GetTaggedObject())->SetProperties(ecmaVm->GetJSThread(), slot, target);
374 }
375
GetLevelSlot(const FrameHandler * frameHandler,std::string_view name)376 std::pair<int32_t, uint32_t> DebuggerApi::GetLevelSlot(const FrameHandler *frameHandler, std::string_view name)
377 {
378 int32_t level = 0;
379 uint32_t slot = 0;
380 JSTaggedValue curEnv = frameHandler->GetEnv();
381 for (; curEnv.IsTaggedArray(); curEnv = LexicalEnv::Cast(curEnv.GetTaggedObject())->GetParentEnv(), level++) {
382 LexicalEnv *lexicalEnv = LexicalEnv::Cast(curEnv.GetTaggedObject());
383 if (lexicalEnv->GetScopeInfo().IsHole()) {
384 continue;
385 }
386 auto result = JSNativePointer::Cast(lexicalEnv->GetScopeInfo().GetTaggedObject())->GetExternalPointer();
387 ScopeDebugInfo *scopeDebugInfo = reinterpret_cast<ScopeDebugInfo *>(result);
388 auto iter = scopeDebugInfo->scopeInfo.find(name.data());
389 if (iter == scopeDebugInfo->scopeInfo.end()) {
390 continue;
391 }
392 slot = iter->second;
393 return std::make_pair(level, slot);
394 }
395 return std::make_pair(-1, 0);
396 }
397
GetGlobalValue(const EcmaVM * ecmaVm,Local<StringRef> name)398 Local<JSValueRef> DebuggerApi::GetGlobalValue(const EcmaVM *ecmaVm, Local<StringRef> name)
399 {
400 JSTaggedValue result;
401 JSTaggedValue globalObj = ecmaVm->GetGlobalEnv()->GetGlobalObject();
402 JSThread *thread = ecmaVm->GetJSThread();
403
404 JSTaggedValue key = JSNApiHelper::ToJSTaggedValue(*name);
405 JSTaggedValue globalRec = SlowRuntimeStub::LdGlobalRecord(thread, key);
406 if (!globalRec.IsUndefined()) {
407 ASSERT(globalRec.IsPropertyBox());
408 result = PropertyBox::Cast(globalRec.GetTaggedObject())->GetValue();
409 return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, result));
410 }
411
412 JSTaggedValue globalVar = FastRuntimeStub::GetGlobalOwnProperty(thread, globalObj, key);
413 if (!globalVar.IsHole()) {
414 return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, globalVar));
415 } else {
416 result = SlowRuntimeStub::TryLdGlobalByNameFromGlobalProto(thread, globalObj, key);
417 return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, result));
418 }
419
420 return Local<JSValueRef>();
421 }
422
SetGlobalValue(const EcmaVM * ecmaVm,Local<StringRef> name,Local<JSValueRef> value)423 bool DebuggerApi::SetGlobalValue(const EcmaVM *ecmaVm, Local<StringRef> name, Local<JSValueRef> value)
424 {
425 JSTaggedValue result;
426 JSTaggedValue globalObj = ecmaVm->GetGlobalEnv()->GetGlobalObject();
427 JSThread *thread = ecmaVm->GetJSThread();
428
429 JSTaggedValue key = JSNApiHelper::ToJSTaggedValue(*name);
430 JSTaggedValue newVal = JSNApiHelper::ToJSTaggedValue(*value);
431 JSTaggedValue globalRec = SlowRuntimeStub::LdGlobalRecord(thread, key);
432 if (!globalRec.IsUndefined()) {
433 result = SlowRuntimeStub::TryUpdateGlobalRecord(thread, key, newVal);
434 return !result.IsException();
435 }
436
437 JSTaggedValue globalVar = FastRuntimeStub::GetGlobalOwnProperty(thread, globalObj, key);
438 if (!globalVar.IsHole()) {
439 result = SlowRuntimeStub::StGlobalVar(thread, key, newVal);
440 return !result.IsException();
441 }
442
443 return false;
444 }
445
GetCurrentModule(const EcmaVM * ecmaVm)446 JSTaggedValue DebuggerApi::GetCurrentModule(const EcmaVM *ecmaVm)
447 {
448 JSThread *thread = ecmaVm->GetJSThread();
449 FrameHandler frameHandler(thread);
450 for (; frameHandler.HasFrame(); frameHandler.PrevJSFrame()) {
451 if (frameHandler.IsEntryFrame()) {
452 continue;
453 }
454 Method *method = frameHandler.GetMethod();
455 // Skip builtins method
456 if (method->IsNativeWithCallField()) {
457 continue;
458 }
459 JSTaggedValue func = frameHandler.GetFunction();
460 JSTaggedValue module = JSFunction::Cast(func.GetTaggedObject())->GetModule();
461 if (module.IsUndefined()) {
462 continue;
463 }
464 return module;
465 }
466 UNREACHABLE();
467 }
468
GetImportModule(const EcmaVM * ecmaVm,const JSHandle<JSTaggedValue> & currentModule,std::string & name)469 JSHandle<JSTaggedValue> DebuggerApi::GetImportModule(const EcmaVM *ecmaVm,
470 const JSHandle<JSTaggedValue> ¤tModule, std::string &name)
471 {
472 JSThread *thread = ecmaVm->GetJSThread();
473 JSMutableHandle<JSTaggedValue> importModule(thread, thread->GlobalConstants()->GetUndefined());
474 if (!currentModule->IsSourceTextModule()) {
475 return importModule;
476 }
477
478 JSTaggedValue importEntries = SourceTextModule::Cast(currentModule->GetTaggedObject())->GetImportEntries();
479 if (importEntries.IsUndefined()) {
480 return importModule;
481 }
482
483 JSHandle<TaggedArray> importArray(thread, TaggedArray::Cast(importEntries.GetTaggedObject()));
484 size_t importEntriesLen = importArray->GetLength();
485 JSHandle<JSTaggedValue> starString = thread->GlobalConstants()->GetHandledStarString();
486 JSMutableHandle<ImportEntry> ee(thread, thread->GlobalConstants()->GetUndefined());
487 JSMutableHandle<TaggedArray> environment(thread, thread->GlobalConstants()->GetUndefined());
488 for (size_t idx = 0; idx < importEntriesLen; idx++) {
489 ee.Update(importArray->Get(idx));
490 JSTaggedValue localName = ee->GetLocalName();
491 JSTaggedValue importName = ee->GetImportName();
492 // Skip 'import * as name from xxx'
493 if (localName.IsString() && !JSTaggedValue::SameValue(importName, starString.GetTaggedValue())) {
494 std::string varName = EcmaStringAccessor(localName).ToStdString();
495 if (varName != name) {
496 continue;
497 }
498 JSTaggedValue moduleEnvironment = SourceTextModule::Cast(
499 currentModule->GetTaggedObject())->GetEnvironment();
500 environment.Update(moduleEnvironment);
501 JSTaggedValue resolvedBinding = environment->Get(idx);
502 ResolvedIndexBinding *binding = ResolvedIndexBinding::Cast(resolvedBinding.GetTaggedObject());
503 importModule.Update(binding->GetModule());
504 name = EcmaStringAccessor(importName).ToStdString();
505 return importModule;
506 }
507 }
508 return importModule;
509 }
510
GetModuleVariableIndex(const EcmaVM * ecmaVm,const JSHandle<JSTaggedValue> & currentModule,std::string & name)511 int32_t DebuggerApi::GetModuleVariableIndex(const EcmaVM *ecmaVm, const JSHandle<JSTaggedValue> ¤tModule,
512 std::string &name)
513 {
514 if (!currentModule->IsSourceTextModule()) {
515 return -1;
516 }
517 JSTaggedValue dictionary = SourceTextModule::Cast(currentModule->GetTaggedObject())->GetNameDictionary();
518 if (dictionary.IsUndefined()) {
519 return -1;
520 }
521
522 JSThread *thread = ecmaVm->GetJSThread();
523 if (dictionary.IsTaggedArray()) {
524 JSTaggedValue localExportEntries = SourceTextModule::Cast(
525 currentModule->GetTaggedObject())->GetLocalExportEntries();
526 ASSERT(localExportEntries.IsTaggedArray());
527 JSHandle<TaggedArray> localExportArray(thread, TaggedArray::Cast(localExportEntries.GetTaggedObject()));
528 uint32_t exportEntriesLen = localExportArray->GetLength();
529 JSMutableHandle<LocalExportEntry> ee(thread, thread->GlobalConstants()->GetUndefined());
530 for (uint32_t idx = 0; idx < exportEntriesLen; idx++) {
531 ee.Update(localExportArray->Get(idx));
532 JSTaggedValue localKey = ee->GetLocalName();
533 JSTaggedValue exportKey = ee->GetExportName();
534 if (localKey.IsString() && exportKey.IsString()) {
535 std::string localName = EcmaStringAccessor(localKey).ToStdString();
536 std::string exportName = EcmaStringAccessor(exportKey).ToStdString();
537 if (localName == name || exportName == name) {
538 return idx;
539 }
540 }
541 }
542 }
543 return -1;
544 }
545
GetExportVariableValue(const EcmaVM * ecmaVm,const JSHandle<JSTaggedValue> & currentModule,std::string & name)546 Local<JSValueRef> DebuggerApi::GetExportVariableValue(const EcmaVM *ecmaVm,
547 const JSHandle<JSTaggedValue> ¤tModule, std::string &name)
548 {
549 Local<JSValueRef> result;
550 if (!currentModule->IsSourceTextModule()) {
551 return result;
552 }
553 int32_t index = GetModuleVariableIndex(ecmaVm, currentModule, name);
554 if (index == -1) {
555 return result;
556 }
557
558 JSTaggedValue dictionary = SourceTextModule::Cast(currentModule->GetTaggedObject())->GetNameDictionary();
559 if (dictionary.IsUndefined()) {
560 return result;
561 }
562
563 JSThread *thread = ecmaVm->GetJSThread();
564 if (dictionary.IsTaggedArray()) {
565 TaggedArray *array = TaggedArray::Cast(dictionary.GetTaggedObject());
566 JSTaggedValue moduleValue = array->Get(index);
567 result = JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, moduleValue));
568 return result;
569 }
570 return result;
571 }
572
SetExportVariableValue(const EcmaVM * ecmaVm,const JSHandle<JSTaggedValue> & currentModule,std::string & name,Local<JSValueRef> value)573 bool DebuggerApi::SetExportVariableValue(const EcmaVM *ecmaVm, const JSHandle<JSTaggedValue> ¤tModule,
574 std::string &name, Local<JSValueRef> value)
575 {
576 if (!currentModule->IsSourceTextModule()) {
577 return false;
578 }
579 int32_t index = GetModuleVariableIndex(ecmaVm, currentModule, name);
580 if (index == -1) {
581 return false;
582 }
583
584 JSTaggedValue dictionary = SourceTextModule::Cast(currentModule->GetTaggedObject())->GetNameDictionary();
585 if (dictionary.IsUndefined()) {
586 return false;
587 }
588
589 JSThread *thread = ecmaVm->GetJSThread();
590 JSTaggedValue curValue = JSNApiHelper::ToJSTaggedValue(*value);
591 if (dictionary.IsTaggedArray()) {
592 TaggedArray *array = TaggedArray::Cast(dictionary.GetTaggedObject());
593 array->Set(thread, index, curValue);
594 return true;
595 }
596 return false;
597 }
598
GetModuleValue(const EcmaVM * ecmaVm,const JSHandle<JSTaggedValue> & currentModule,std::string & name)599 Local<JSValueRef> DebuggerApi::GetModuleValue(const EcmaVM *ecmaVm, const JSHandle<JSTaggedValue> ¤tModule,
600 std::string &name)
601 {
602 Local<JSValueRef> result;
603 if (!currentModule->IsSourceTextModule()) {
604 return result;
605 }
606 // Get variable from local export
607 result = GetExportVariableValue(ecmaVm, currentModule, name);
608 if (!result.IsEmpty()) {
609 return result;
610 }
611 // Get variable from import module
612 JSHandle<JSTaggedValue> importModule = GetImportModule(ecmaVm, currentModule, name);
613 result = GetExportVariableValue(ecmaVm, importModule, name);
614 return result;
615 }
616
SetModuleValue(const EcmaVM * ecmaVm,const JSHandle<JSTaggedValue> & currentModule,std::string & name,Local<JSValueRef> value)617 bool DebuggerApi::SetModuleValue(const EcmaVM *ecmaVm, const JSHandle<JSTaggedValue> ¤tModule,
618 std::string &name, Local<JSValueRef> value)
619 {
620 bool result;
621 if (!currentModule->IsSourceTextModule()) {
622 return false;
623 }
624 // Set local export variable
625 result = SetExportVariableValue(ecmaVm, currentModule, name, value);
626 if (result == true) {
627 return result;
628 }
629 // Set import module variable
630 JSHandle<JSTaggedValue> importModule = GetImportModule(ecmaVm, currentModule, name);
631 result = SetExportVariableValue(ecmaVm, importModule, name, value);
632 if (result == true) {
633 return result;
634 }
635 return false;
636 }
637
InitializeExportVariables(const EcmaVM * ecmaVm,Local<ObjectRef> & moduleObj,const JSHandle<JSTaggedValue> & currentModule)638 void DebuggerApi::InitializeExportVariables(const EcmaVM *ecmaVm, Local<ObjectRef> &moduleObj,
639 const JSHandle<JSTaggedValue> ¤tModule)
640 {
641 if (!currentModule->IsSourceTextModule()) {
642 return;
643 }
644 JSTaggedValue localExportEntries = SourceTextModule::Cast(
645 currentModule->GetTaggedObject())->GetLocalExportEntries();
646 if (localExportEntries.IsUndefined()) {
647 return;
648 }
649
650 JSThread *thread = ecmaVm->GetJSThread();
651 JSHandle<TaggedArray> localExportArray(thread, TaggedArray::Cast(localExportEntries.GetTaggedObject()));
652 uint32_t exportEntriesLen = localExportArray->GetLength();
653 JSMutableHandle<LocalExportEntry> ee(thread, thread->GlobalConstants()->GetUndefined());
654 JSMutableHandle<JSTaggedValue> name(thread, thread->GlobalConstants()->GetUndefined());
655 JSMutableHandle<JSTaggedValue> value(thread, thread->GlobalConstants()->GetUndefined());
656 JSTaggedValue moduleValue = JSTaggedValue::Undefined();
657 for (uint32_t idx = 0; idx < exportEntriesLen; idx++) {
658 ee.Update(localExportArray->Get(idx));
659 JSTaggedValue key = ee->GetLocalName();
660 name.Update(key);
661 value.Update(moduleValue);
662 if (key.IsString()) {
663 Local<JSValueRef> variableName = JSNApiHelper::ToLocal<JSValueRef>(name);
664 Local<JSValueRef> variableValue = JSNApiHelper::ToLocal<JSValueRef>(value);
665 PropertyAttribute descriptor(variableValue, true, true, true);
666 moduleObj->DefineProperty(ecmaVm, variableName, descriptor);
667 }
668 }
669 }
670
GetLocalExportVariables(const EcmaVM * ecmaVm,Local<ObjectRef> & moduleObj,const JSHandle<JSTaggedValue> & currentModule,bool isImportStar)671 void DebuggerApi::GetLocalExportVariables(const EcmaVM *ecmaVm, Local<ObjectRef> &moduleObj,
672 const JSHandle<JSTaggedValue> ¤tModule, bool isImportStar)
673 {
674 if (!currentModule->IsSourceTextModule()) {
675 return;
676 }
677 JSTaggedValue dictionary = SourceTextModule::Cast(currentModule->GetTaggedObject())->GetNameDictionary();
678 if (dictionary.IsUndefined()) {
679 InitializeExportVariables(ecmaVm, moduleObj, currentModule);
680 return;
681 }
682
683 JSThread *thread = ecmaVm->GetJSThread();
684 JSMutableHandle<JSTaggedValue> name(thread, thread->GlobalConstants()->GetUndefined());
685 JSMutableHandle<JSTaggedValue> value(thread, thread->GlobalConstants()->GetUndefined());
686 if (dictionary.IsTaggedArray()) {
687 JSTaggedValue localExportEntries = SourceTextModule::Cast(
688 currentModule->GetTaggedObject())->GetLocalExportEntries();
689 ASSERT(localExportEntries.IsTaggedArray());
690 JSHandle<TaggedArray> localExportArray(thread, TaggedArray::Cast(localExportEntries.GetTaggedObject()));
691 uint32_t exportEntriesLen = localExportArray->GetLength();
692 JSHandle<TaggedArray> dict(thread, TaggedArray::Cast(dictionary.GetTaggedObject()));
693 uint32_t valueLen = dict->GetLength();
694 if (exportEntriesLen != valueLen) {
695 LOG_FULL(FATAL) << "Key does not match value";
696 }
697
698 JSMutableHandle<LocalExportEntry> ee(thread, thread->GlobalConstants()->GetUndefined());
699 for (uint32_t idx = 0; idx < exportEntriesLen; idx++) {
700 ee.Update(localExportArray->Get(idx));
701 JSTaggedValue key;
702 if (isImportStar) {
703 key = ee->GetExportName();
704 } else {
705 key = ee->GetLocalName();
706 }
707 name.Update(key);
708 JSTaggedValue moduleValue = dict->Get(idx);
709 if (moduleValue.IsHole()) {
710 moduleValue = JSTaggedValue::Undefined();
711 }
712 value.Update(moduleValue);
713 if (key.IsString()) {
714 Local<JSValueRef> variableName = JSNApiHelper::ToLocal<JSValueRef>(name);
715 Local<JSValueRef> variableValue = JSNApiHelper::ToLocal<JSValueRef>(value);
716 PropertyAttribute descriptor(variableValue, true, true, true);
717 moduleObj->DefineProperty(ecmaVm, variableName, descriptor);
718 }
719 }
720 }
721 }
722
GetIndirectExportVariables(const EcmaVM * ecmaVm,Local<ObjectRef> & moduleObj,const JSHandle<JSTaggedValue> & currentModule)723 void DebuggerApi::GetIndirectExportVariables(const EcmaVM *ecmaVm, Local<ObjectRef> &moduleObj,
724 const JSHandle<JSTaggedValue> ¤tModule)
725 {
726 if (!currentModule->IsSourceTextModule()) {
727 return;
728 }
729 JSHandle<SourceTextModule> module = JSHandle<SourceTextModule>::Cast(currentModule);
730 JSTaggedValue indirectExportEntries = module->GetIndirectExportEntries();
731 if (indirectExportEntries.IsUndefined()) {
732 return;
733 }
734 ASSERT(indirectExportEntries.IsTaggedArray());
735 JSThread *thread = ecmaVm->GetJSThread();
736 JSHandle<TaggedArray> indirectExportArray(thread, TaggedArray::Cast(indirectExportEntries.GetTaggedObject()));
737 JSHandle<TaggedArray> requestedModules(thread, module->GetRequestedModules());
738 uint32_t indirectExportEntriesLen = indirectExportArray->GetLength();
739 JSMutableHandle<IndirectExportEntry> ee(thread, thread->GlobalConstants()->GetUndefined());
740 JSMutableHandle<JSTaggedValue> name(thread, thread->GlobalConstants()->GetUndefined());
741 for (uint32_t idx = 0; idx < indirectExportEntriesLen; idx++) {
742 ee.Update(indirectExportArray->Get(idx));
743 JSTaggedValue key = ee->GetImportName();
744 name.Update(key);
745 if (key.IsString()) {
746 JSHandle<JSTaggedValue> importModule =
747 SourceTextModule::GetRequestedModule(thread, module, requestedModules, ee->GetModuleRequestIndex());
748 RETURN_IF_ABRUPT_COMPLETION(thread);
749 std::string importName = EcmaStringAccessor(ee->GetImportName()).ToStdString();
750 Local<JSValueRef> value = GetModuleValue(ecmaVm, importModule, importName);
751 PropertyAttribute descriptor(value, true, true, true);
752 Local<JSValueRef> variableName = JSNApiHelper::ToLocal<JSValueRef>(name);
753 moduleObj->DefineProperty(ecmaVm, variableName, descriptor);
754 }
755 }
756 }
757
GetImportVariables(const EcmaVM * ecmaVm,Local<ObjectRef> & moduleObj,const JSHandle<JSTaggedValue> & currentModule)758 void DebuggerApi::GetImportVariables(const EcmaVM *ecmaVm, Local<ObjectRef> &moduleObj,
759 const JSHandle<JSTaggedValue> ¤tModule)
760 {
761 if (!currentModule->IsSourceTextModule()) {
762 return;
763 }
764 JSHandle<SourceTextModule> module = JSHandle<SourceTextModule>::Cast(currentModule);
765 JSTaggedValue importEntries = module->GetImportEntries();
766 if (importEntries.IsUndefined()) {
767 return;
768 }
769
770 JSThread *thread = ecmaVm->GetJSThread();
771 JSHandle<TaggedArray> importArray(thread, TaggedArray::Cast(importEntries.GetTaggedObject()));
772 JSHandle<TaggedArray> requestedModules(thread, module->GetRequestedModules());
773 uint32_t importEntriesLen = importArray->GetLength();
774 JSHandle<JSTaggedValue> starString = thread->GlobalConstants()->GetHandledStarString();
775 JSMutableHandle<ImportEntry> ee(thread, thread->GlobalConstants()->GetUndefined());
776 JSMutableHandle<JSTaggedValue> name(thread, thread->GlobalConstants()->GetUndefined());
777 for (uint32_t idx = 0; idx < importEntriesLen; idx++) {
778 ee.Update(importArray->Get(idx));
779 JSTaggedValue key = ee->GetImportName();
780 JSTaggedValue localName = ee->GetLocalName();
781 name.Update(localName);
782 if (JSTaggedValue::SameValue(key, starString.GetTaggedValue())) {
783 JSHandle<JSTaggedValue> importModule =
784 SourceTextModule::GetRequestedModule(thread, module, requestedModules, ee->GetModuleRequestIndex());
785 RETURN_IF_ABRUPT_COMPLETION(thread);
786 Local<ObjectRef> importModuleObj = ObjectRef::New(ecmaVm);
787 GetLocalExportVariables(ecmaVm, importModuleObj, importModule, true);
788 Local<JSValueRef> variableName = JSNApiHelper::ToLocal<JSValueRef>(name);
789 PropertyAttribute descriptor(static_cast<Local<JSValueRef>>(importModuleObj), true, true, true);
790 moduleObj->DefineProperty(ecmaVm, variableName, descriptor);
791 continue;
792 }
793 JSTaggedValue moduleValue =
794 thread->GetCurrentEcmaContext()->GetModuleManager()->GetModuleValueOutter(idx, currentModule);
795 Local<JSValueRef> value = JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, moduleValue));
796 Local<JSValueRef> variableName = JSNApiHelper::ToLocal<JSValueRef>(name);
797 PropertyAttribute descriptor(value, true, true, true);
798 moduleObj->DefineProperty(ecmaVm, variableName, descriptor);
799 }
800 }
801
HandleUncaughtException(const EcmaVM * ecmaVm,std::string & message)802 void DebuggerApi::HandleUncaughtException(const EcmaVM *ecmaVm, std::string &message)
803 {
804 JSThread *thread = ecmaVm->GetJSThread();
805 [[maybe_unused]] EcmaHandleScope handleScope(thread);
806 const GlobalEnvConstants *globalConst = thread->GlobalConstants();
807
808 JSHandle<JSTaggedValue> exHandle(thread, thread->GetException());
809 thread->ClearException();
810 if (exHandle->IsJSError()) {
811 JSHandle<JSTaggedValue> nameKey = globalConst->GetHandledNameString();
812 JSHandle<EcmaString> name(JSObject::GetProperty(thread, exHandle, nameKey).GetValue());
813 JSHandle<JSTaggedValue> msgKey = globalConst->GetHandledMessageString();
814 JSHandle<EcmaString> msg(JSObject::GetProperty(thread, exHandle, msgKey).GetValue());
815 message = ConvertToString(*name) + ": " + ConvertToString(*msg);
816 } else {
817 JSHandle<EcmaString> ecmaStr = JSTaggedValue::ToString(thread, exHandle);
818 message = ConvertToString(*ecmaStr);
819 }
820 }
821
GenerateFuncFromBuffer(const EcmaVM * ecmaVm,const void * buffer,size_t size,std::string_view entryPoint)822 Local<FunctionRef> DebuggerApi::GenerateFuncFromBuffer(const EcmaVM *ecmaVm, const void *buffer,
823 size_t size, std::string_view entryPoint)
824 {
825 JSPandaFileManager *mgr = JSPandaFileManager::GetInstance();
826 std::shared_ptr<JSPandaFile> jsPandaFile =
827 mgr->LoadJSPandaFile(ecmaVm->GetJSThread(), "", entryPoint, buffer, size);
828 if (jsPandaFile == nullptr) {
829 return JSValueRef::Undefined(ecmaVm);
830 }
831
832 JSHandle<Program> program = mgr->GenerateProgram(const_cast<EcmaVM *>(ecmaVm), jsPandaFile.get(), entryPoint);
833 JSTaggedValue func = program->GetMainFunction();
834 return JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(ecmaVm->GetJSThread(), func));
835 }
836
EvaluateViaFuncCall(EcmaVM * ecmaVm,Local<FunctionRef> funcRef,std::shared_ptr<FrameHandler> & frameHandler)837 Local<JSValueRef> DebuggerApi::EvaluateViaFuncCall(EcmaVM *ecmaVm, Local<FunctionRef> funcRef,
838 std::shared_ptr<FrameHandler> &frameHandler)
839 {
840 JSNApi::EnableUserUncaughtErrorHandler(ecmaVm);
841
842 JsDebuggerManager *mgr = ecmaVm->GetJsDebuggerManager();
843 bool prevDebugMode = mgr->IsDebugMode();
844 mgr->SetEvalFrameHandler(frameHandler);
845 mgr->SetDebugMode(false); // in order to catch exception
846 ecmaVm->GetJSThread()->CheckSwitchDebuggerBCStub();
847 std::vector<Local<JSValueRef>> args;
848 auto result = funcRef->Call(ecmaVm, JSValueRef::Undefined(ecmaVm), args.data(), args.size());
849 mgr->SetDebugMode(prevDebugMode);
850 ecmaVm->GetJSThread()->CheckSwitchDebuggerBCStub();
851 mgr->SetEvalFrameHandler(nullptr);
852
853 return result;
854 }
855
CallFunctionOnCall(EcmaVM * ecmaVm,Local<FunctionRef> funcRef,std::shared_ptr<FrameHandler> & frameHandler)856 Local<JSValueRef> DebuggerApi::CallFunctionOnCall(EcmaVM *ecmaVm, Local<FunctionRef> funcRef,
857 std::shared_ptr<FrameHandler> &frameHandler)
858 {
859 JSNApi::EnableUserUncaughtErrorHandler(ecmaVm);
860
861 JsDebuggerManager *mgr = ecmaVm->GetJsDebuggerManager();
862 bool prevDebugMode = mgr->IsDebugMode();
863 mgr->SetEvalFrameHandler(frameHandler);
864 mgr->SetDebugMode(false);
865 ecmaVm->GetJSThread()->CheckSwitchDebuggerBCStub();
866 std::vector<Local<JSValueRef>> args;
867 auto result = funcRef->Call(ecmaVm, JSValueRef::Undefined(ecmaVm), args.data(), args.size());
868 mgr->SetDebugMode(prevDebugMode);
869 ecmaVm->GetJSThread()->CheckSwitchDebuggerBCStub();
870 mgr->SetEvalFrameHandler(nullptr);
871
872 return result;
873 }
874
IsExceptionCaught(const EcmaVM * ecmaVm)875 bool DebuggerApi::IsExceptionCaught(const EcmaVM *ecmaVm)
876 {
877 FrameHandler frameHandler(ecmaVm->GetJSThread());
878 for (; frameHandler.HasFrame(); frameHandler.PrevJSFrame()) {
879 if (frameHandler.IsEntryFrame()) {
880 return false;
881 }
882 auto method = frameHandler.GetMethod();
883 if (method->FindCatchBlock(frameHandler.GetBytecodeOffset()) != INVALID_INDEX) {
884 return true;
885 }
886 }
887 return false;
888 }
889
GetPatchExtractors(const EcmaVM * ecmaVm,const std::string & url)890 std::vector<DebugInfoExtractor *> DebuggerApi::GetPatchExtractors(const EcmaVM *ecmaVm, const std::string &url)
891 {
892 const auto *hotReloadManager = ecmaVm->GetJsDebuggerManager()->GetHotReloadManager();
893 return hotReloadManager->GetPatchExtractors(url);
894 }
895
GetBaseJSPandaFile(const EcmaVM * ecmaVm,const JSPandaFile * jsPandaFile)896 const JSPandaFile *DebuggerApi::GetBaseJSPandaFile(const EcmaVM *ecmaVm, const JSPandaFile *jsPandaFile)
897 {
898 const auto *hotReloadManager = ecmaVm->GetJsDebuggerManager()->GetHotReloadManager();
899 return hotReloadManager->GetBaseJSPandaFile(jsPandaFile);
900 }
901
GetNativePointer(const EcmaVM * ecmaVm)902 std::vector<void *> DebuggerApi::GetNativePointer(const EcmaVM *ecmaVm)
903 {
904 void *native = nullptr;
905 std::vector<void *> nativePointer;
906 JSThread *thread = ecmaVm->GetJSThread();
907 JSTaggedType *current = const_cast<JSTaggedType *>(thread->GetCurrentFrame());
908 FrameIterator it(current, thread);
909 for (; !it.Done(); it.Advance<GCVisitedFlag::HYBRID_STACK>()) {
910 if (!it.IsJSFrame()) {
911 continue;
912 }
913 auto method = it.CheckAndGetMethod();
914 if (method == nullptr) {
915 continue;
916 }
917
918 if (method->IsNativeWithCallField()) {
919 JSTaggedValue function = it.GetFunction();
920 JSHandle<JSTaggedValue> extraInfoValue(
921 thread, JSFunctionBase::Cast(function.GetTaggedObject())->GetFunctionExtraInfo());
922 auto cb = ecmaVm->GetNativePtrGetter();
923 if (extraInfoValue->IsJSNativePointer() && cb != nullptr) {
924 JSHandle<JSNativePointer> extraInfo(extraInfoValue);
925 native = cb(reinterpret_cast<void *>(extraInfo->GetData()));
926 nativePointer.push_back(native);
927 }
928 } else {
929 nativePointer.push_back(nullptr); // to tell IDE this frame don't hava nativePointer
930 }
931 }
932 return nativePointer;
933 }
934
GetContainerLength(const EcmaVM * ecmaVm,Local<JSValueRef> value)935 uint32_t DebuggerApi::GetContainerLength(const EcmaVM *ecmaVm, Local<JSValueRef> value)
936 {
937 uint32_t length = Local<ArrayRef>(value)->Length(ecmaVm);
938 return length;
939 }
940
AddInternalProperties(const EcmaVM * ecmaVm,Local<ObjectRef> object,ArkInternalValueType type,Global<MapRef> internalObjects)941 void DebuggerApi::AddInternalProperties(const EcmaVM *ecmaVm, Local<ObjectRef> object,
942 ArkInternalValueType type, Global<MapRef> internalObjects)
943 {
944 if (internalObjects.IsEmpty()) {
945 return;
946 }
947 internalObjects->Set(ecmaVm, object, NumberRef::New(ecmaVm, static_cast<int32_t>(type)));
948 }
949
GetArrayListValue(const EcmaVM * ecmaVm,Local<JSValueRef> value,Global<MapRef> internalObjects)950 Local<JSValueRef> DebuggerApi::GetArrayListValue(const EcmaVM *ecmaVm, Local<JSValueRef> value,
951 Global<MapRef> internalObjects)
952 {
953 JSHandle<JSAPIArrayList> arrayList(JSNApiHelper::ToJSHandle(value));
954 uint32_t size = static_cast<uint32_t>(arrayList->GetSize());
955 Local<JSValueRef> jsValueRef = ArrayRef::New(ecmaVm, size);
956 JSThread *thread = ecmaVm->GetJSThread();
957 JSMutableHandle<JSTaggedValue> currentValue(thread, JSTaggedValue::Undefined());
958 uint32_t index = 0;
959 while (index < size) {
960 currentValue.Update(arrayList->Get(thread, index));
961 ArrayRef::SetValueAt(ecmaVm, jsValueRef, index++, JSNApiHelper::ToLocal<JSValueRef>(currentValue));
962 }
963 AddInternalProperties(ecmaVm, jsValueRef, ArkInternalValueType::Entry, internalObjects);
964 return jsValueRef;
965 }
966
GetDequeValue(const EcmaVM * ecmaVm,Local<JSValueRef> value,Global<MapRef> internalObjects)967 Local<JSValueRef> DebuggerApi::GetDequeValue(const EcmaVM *ecmaVm, Local<JSValueRef> value,
968 Global<MapRef> internalObjects)
969 {
970 JSHandle<JSAPIDeque> deque(JSNApiHelper::ToJSHandle(value));
971 uint32_t size = static_cast<uint32_t>(deque->GetSize());
972 Local<JSValueRef> jsValueRef = ArrayRef::New(ecmaVm, size);
973 JSThread *thread = ecmaVm->GetJSThread();
974 JSMutableHandle<JSTaggedValue> currentValue(thread, JSTaggedValue::Undefined());
975 uint32_t index = 0;
976 while (index < size) {
977 currentValue.Update(deque->Get(index));
978 ArrayRef::SetValueAt(ecmaVm, jsValueRef, index++, JSNApiHelper::ToLocal<JSValueRef>(currentValue));
979 }
980 AddInternalProperties(ecmaVm, jsValueRef, ArkInternalValueType::Entry, internalObjects);
981 return jsValueRef;
982 }
983
GetHashMapValue(const EcmaVM * ecmaVm,Local<JSValueRef> value,Global<MapRef> internalObjects)984 Local<JSValueRef> DebuggerApi::GetHashMapValue(const EcmaVM *ecmaVm, Local<JSValueRef> value,
985 Global<MapRef> internalObjects)
986 {
987 JSHandle<JSAPIHashMap> hashMap(JSNApiHelper::ToJSHandle(value));
988 JSThread *thread = ecmaVm->GetJSThread();
989 JSHandle<TaggedHashArray> table(thread, hashMap->GetTable());
990 uint32_t length = table->GetLength();
991 uint32_t size = static_cast<uint32_t>(hashMap->GetSize());
992 Local<JSValueRef> jsValueRef = ArrayRef::New(ecmaVm, size);
993 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
994 JSMutableHandle<TaggedQueue> queue(thread, factory->NewTaggedQueue(0));
995 JSMutableHandle<TaggedNode> node(thread, JSTaggedValue::Undefined());
996 JSMutableHandle<JSTaggedValue> currentKey(thread, JSTaggedValue::Undefined());
997 JSMutableHandle<JSTaggedValue> currentValue(thread, JSTaggedValue::Undefined());
998 Local<JSValueRef> jsKey = StringRef::NewFromUtf8(ecmaVm, "key");
999 Local<JSValueRef> jsValue = StringRef::NewFromUtf8(ecmaVm, "value");
1000 uint32_t pos = 0;
1001 uint32_t index = 0;
1002 while (index < length) {
1003 node.Update(TaggedHashArray::GetCurrentNode(thread, queue, table, index));
1004 if (!node.GetTaggedValue().IsHole()) {
1005 currentKey.Update(node->GetKey());
1006 currentValue.Update(node->GetValue());
1007 Local<ObjectRef> objRef = ObjectRef::New(ecmaVm);
1008 objRef->Set(ecmaVm, jsKey, JSNApiHelper::ToLocal<JSValueRef>(currentKey));
1009 objRef->Set(ecmaVm, jsValue, JSNApiHelper::ToLocal<JSValueRef>(currentValue));
1010 AddInternalProperties(ecmaVm, objRef, ArkInternalValueType::Entry, internalObjects);
1011 ArrayRef::SetValueAt(ecmaVm, jsValueRef, pos++, objRef);
1012 }
1013 }
1014 AddInternalProperties(ecmaVm, jsValueRef, ArkInternalValueType::Entry, internalObjects);
1015 return jsValueRef;
1016 }
1017
GetHashSetValue(const EcmaVM * ecmaVm,Local<JSValueRef> value,Global<MapRef> internalObjects)1018 Local<JSValueRef> DebuggerApi::GetHashSetValue(const EcmaVM *ecmaVm, Local<JSValueRef> value,
1019 Global<MapRef> internalObjects)
1020 {
1021 JSHandle<JSAPIHashSet> hashSet(JSNApiHelper::ToJSHandle(value));
1022 JSThread *thread = ecmaVm->GetJSThread();
1023 JSHandle<TaggedHashArray> table(thread, hashSet->GetTable());
1024 uint32_t length = table->GetLength();
1025 uint32_t size = static_cast<uint32_t>(hashSet->GetSize());
1026 Local<JSValueRef> jsValueRef = ArrayRef::New(ecmaVm, size);
1027 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1028 JSMutableHandle<TaggedQueue> queue(thread, factory->NewTaggedQueue(0));
1029 JSMutableHandle<TaggedNode> node(thread, JSTaggedValue::Undefined());
1030 JSMutableHandle<JSTaggedValue> currentKey(thread, JSTaggedValue::Undefined());
1031 Local<JSValueRef> jsValue = StringRef::NewFromUtf8(ecmaVm, "value");
1032 uint32_t pos = 0;
1033 uint32_t index = 0;
1034 while (index < length) {
1035 node.Update(TaggedHashArray::GetCurrentNode(thread, queue, table, index));
1036 if (!node.GetTaggedValue().IsHole()) {
1037 currentKey.Update(node->GetKey());
1038 if (currentKey->IsECMAObject()) {
1039 Local<ObjectRef> objRef = ObjectRef::New(ecmaVm);
1040 objRef->Set(ecmaVm, jsValue, JSNApiHelper::ToLocal<JSValueRef>(currentKey));
1041 AddInternalProperties(ecmaVm, objRef, ArkInternalValueType::Entry, internalObjects);
1042 ArrayRef::SetValueAt(ecmaVm, jsValueRef, pos++, objRef);
1043 } else {
1044 ArrayRef::SetValueAt(ecmaVm, jsValueRef, pos++, JSNApiHelper::ToLocal<JSValueRef>(currentKey));
1045 }
1046 }
1047 }
1048 AddInternalProperties(ecmaVm, jsValueRef, ArkInternalValueType::Entry, internalObjects);
1049 return jsValueRef;
1050 }
1051
GetLightWeightMapValue(const EcmaVM * ecmaVm,Local<JSValueRef> value,Global<MapRef> internalObjects)1052 Local<JSValueRef> DebuggerApi::GetLightWeightMapValue(const EcmaVM *ecmaVm, Local<JSValueRef> value,
1053 Global<MapRef> internalObjects)
1054 {
1055 JSHandle<JSAPILightWeightMap> lightweightMap(JSNApiHelper::ToJSHandle(value));
1056 uint32_t size = static_cast<uint32_t>(lightweightMap->GetSize());
1057 Local<JSValueRef> jsValueRef = ArrayRef::New(ecmaVm, size);
1058 JSThread *thread = ecmaVm->GetJSThread();
1059 JSMutableHandle<TaggedArray> keys(thread, lightweightMap->GetKeys());
1060 JSMutableHandle<TaggedArray> values(thread, lightweightMap->GetValues());
1061 JSMutableHandle<JSTaggedValue> currentKey(thread, JSTaggedValue::Undefined());
1062 JSMutableHandle<JSTaggedValue> currentValue(thread, JSTaggedValue::Undefined());
1063 Local<JSValueRef> jsKey = StringRef::NewFromUtf8(ecmaVm, "key");
1064 Local<JSValueRef> jsValue = StringRef::NewFromUtf8(ecmaVm, "value");
1065 uint32_t index = 0;
1066 while (index < size) {
1067 currentKey.Update(keys->Get(index));
1068 currentValue.Update(values->Get(index));
1069 Local<ObjectRef> objRef = ObjectRef::New(ecmaVm);
1070 objRef->Set(ecmaVm, jsKey, JSNApiHelper::ToLocal<JSValueRef>(currentKey));
1071 objRef->Set(ecmaVm, jsValue, JSNApiHelper::ToLocal<JSValueRef>(currentValue));
1072 AddInternalProperties(ecmaVm, objRef, ArkInternalValueType::Entry, internalObjects);
1073 ArrayRef::SetValueAt(ecmaVm, jsValueRef, index++, objRef);
1074 }
1075 AddInternalProperties(ecmaVm, jsValueRef, ArkInternalValueType::Entry, internalObjects);
1076 return jsValueRef;
1077 }
1078
GetLightWeightSetValue(const EcmaVM * ecmaVm,Local<JSValueRef> value,Global<MapRef> internalObjects)1079 Local<JSValueRef> DebuggerApi::GetLightWeightSetValue(const EcmaVM *ecmaVm, Local<JSValueRef> value,
1080 Global<MapRef> internalObjects)
1081 {
1082 JSHandle<JSAPILightWeightSet> lightWeightSet(JSNApiHelper::ToJSHandle(value));
1083 uint32_t size = static_cast<uint32_t>(lightWeightSet->GetSize());
1084 Local<JSValueRef> jsValueRef = ArrayRef::New(ecmaVm, size);
1085 JSThread *thread = ecmaVm->GetJSThread();
1086 JSMutableHandle<JSTaggedValue> currentValue(thread, JSTaggedValue::Undefined());
1087 Local<JSValueRef> jsValue = StringRef::NewFromUtf8(ecmaVm, "value");
1088 uint32_t index = 0;
1089 while (index < size) {
1090 currentValue.Update(lightWeightSet->GetValueAt(index));
1091 if (currentValue->IsECMAObject()) {
1092 Local<ObjectRef> objRef = ObjectRef::New(ecmaVm);
1093 objRef->Set(ecmaVm, jsValue, JSNApiHelper::ToLocal<JSValueRef>(currentValue));
1094 AddInternalProperties(ecmaVm, objRef, ArkInternalValueType::Entry, internalObjects);
1095 ArrayRef::SetValueAt(ecmaVm, jsValueRef, index++, objRef);
1096 } else {
1097 ArrayRef::SetValueAt(ecmaVm, jsValueRef, index++, JSNApiHelper::ToLocal<JSValueRef>(currentValue));
1098 }
1099 }
1100 AddInternalProperties(ecmaVm, jsValueRef, ArkInternalValueType::Entry, internalObjects);
1101 return jsValueRef;
1102 }
1103
GetLinkedListValue(const EcmaVM * ecmaVm,Local<JSValueRef> value,Global<MapRef> internalObjects)1104 Local<JSValueRef> DebuggerApi::GetLinkedListValue(const EcmaVM *ecmaVm, Local<JSValueRef> value,
1105 Global<MapRef> internalObjects)
1106 {
1107 JSHandle<JSAPILinkedList> linkedList(JSNApiHelper::ToJSHandle(value));
1108 JSThread *thread = ecmaVm->GetJSThread();
1109 JSHandle<TaggedDoubleList> doubleList(thread, linkedList->GetDoubleList());
1110 uint32_t size = static_cast<uint32_t>(linkedList->Length());
1111 Local<JSValueRef> jsValueRef = ArrayRef::New(ecmaVm, size);
1112 JSMutableHandle<JSTaggedValue> currentValue(thread, JSTaggedValue::Undefined());
1113 int valueNode = TaggedDoubleList::ELEMENTS_START_INDEX;
1114 uint32_t index = 0;
1115 while (index < size) {
1116 valueNode = doubleList->GetNextDataIndex(valueNode);
1117 currentValue.Update(doubleList->GetElement(valueNode));
1118 ArrayRef::SetValueAt(ecmaVm, jsValueRef, index++, JSNApiHelper::ToLocal<JSValueRef>(currentValue));
1119 }
1120 AddInternalProperties(ecmaVm, jsValueRef, ArkInternalValueType::Entry, internalObjects);
1121 return jsValueRef;
1122 }
1123
GetListValue(const EcmaVM * ecmaVm,Local<JSValueRef> value,Global<MapRef> internalObjects)1124 Local<JSValueRef> DebuggerApi::GetListValue(const EcmaVM *ecmaVm, Local<JSValueRef> value,
1125 Global<MapRef> internalObjects)
1126 {
1127 JSHandle<JSAPIList> list(JSNApiHelper::ToJSHandle(value));
1128 JSThread *thread = ecmaVm->GetJSThread();
1129 JSHandle<TaggedSingleList> singleList(thread, list->GetSingleList());
1130 uint32_t size = static_cast<uint32_t>(list->Length());
1131 Local<JSValueRef> jsValueRef = ArrayRef::New(ecmaVm, size);
1132 JSMutableHandle<JSTaggedValue> currentValue(thread, JSTaggedValue::Undefined());
1133 int valueNode = TaggedDoubleList::ELEMENTS_START_INDEX;
1134 uint32_t index = 0;
1135 while (index < size) {
1136 valueNode = singleList->GetNextDataIndex(valueNode);
1137 currentValue.Update(singleList->GetElement(valueNode));
1138 ArrayRef::SetValueAt(ecmaVm, jsValueRef, index++, JSNApiHelper::ToLocal<JSValueRef>(currentValue));
1139 }
1140 AddInternalProperties(ecmaVm, jsValueRef, ArkInternalValueType::Entry, internalObjects);
1141 return jsValueRef;
1142 }
1143
GetPlainArrayValue(const EcmaVM * ecmaVm,Local<JSValueRef> value,Global<MapRef> internalObjects)1144 Local<JSValueRef> DebuggerApi::GetPlainArrayValue(const EcmaVM *ecmaVm, Local<JSValueRef> value,
1145 Global<MapRef> internalObjects)
1146 {
1147 JSHandle<JSAPIPlainArray> plainarray(JSNApiHelper::ToJSHandle(value));
1148 uint32_t size = static_cast<uint32_t>(plainarray->GetSize());
1149 Local<JSValueRef> jsValueRef = ArrayRef::New(ecmaVm, size);
1150 JSThread *thread = ecmaVm->GetJSThread();
1151 JSHandle<TaggedArray> keyArray(thread, plainarray->GetKeys());
1152 JSHandle<TaggedArray> valueArray(thread, plainarray->GetValues());
1153 JSMutableHandle<JSTaggedValue> currentKey(thread, JSTaggedValue::Undefined());
1154 JSMutableHandle<JSTaggedValue> currentValue(thread, JSTaggedValue::Undefined());
1155 Local<JSValueRef> jsKey = StringRef::NewFromUtf8(ecmaVm, "key");
1156 Local<JSValueRef> jsValue = StringRef::NewFromUtf8(ecmaVm, "value");
1157 uint32_t index = 0;
1158 while (index < size) {
1159 currentKey.Update(keyArray->Get(index));
1160 currentValue.Update(valueArray->Get(index));
1161 Local<ObjectRef> objRef = ObjectRef::New(ecmaVm);
1162 objRef->Set(ecmaVm, jsKey, JSNApiHelper::ToLocal<JSValueRef>(currentKey));
1163 objRef->Set(ecmaVm, jsValue, JSNApiHelper::ToLocal<JSValueRef>(currentValue));
1164 AddInternalProperties(ecmaVm, objRef, ArkInternalValueType::Entry, internalObjects);
1165 ArrayRef::SetValueAt(ecmaVm, jsValueRef, index++, objRef);
1166 }
1167 AddInternalProperties(ecmaVm, jsValueRef, ArkInternalValueType::Entry, internalObjects);
1168 return jsValueRef;
1169 }
1170
GetQueueValue(const EcmaVM * ecmaVm,Local<JSValueRef> value,Global<MapRef> internalObjects)1171 Local<JSValueRef> DebuggerApi::GetQueueValue(const EcmaVM *ecmaVm, Local<JSValueRef> value,
1172 Global<MapRef> internalObjects)
1173 {
1174 JSHandle<JSAPIQueue> queue(JSNApiHelper::ToJSHandle(value));
1175 uint32_t size = static_cast<uint32_t>(queue->GetSize());
1176 Local<JSValueRef> jsValueRef = ArrayRef::New(ecmaVm, size);
1177 JSThread *thread = ecmaVm->GetJSThread();
1178 JSMutableHandle<JSTaggedValue> currentValue(thread, JSTaggedValue::Undefined());
1179 uint32_t pos = 0;
1180 uint32_t index = 0;
1181 while (index < size) {
1182 currentValue.Update(queue->Get(thread, pos));
1183 pos = queue->GetNextPosition(pos);
1184 ArrayRef::SetValueAt(ecmaVm, jsValueRef, index++, JSNApiHelper::ToLocal<JSValueRef>(currentValue));
1185 }
1186 AddInternalProperties(ecmaVm, jsValueRef, ArkInternalValueType::Entry, internalObjects);
1187 return jsValueRef;
1188 }
1189
GetStackValue(const EcmaVM * ecmaVm,Local<JSValueRef> value,Global<MapRef> internalObjects)1190 Local<JSValueRef> DebuggerApi::GetStackValue(const EcmaVM *ecmaVm, Local<JSValueRef> value,
1191 Global<MapRef> internalObjects)
1192 {
1193 JSHandle<JSAPIStack> stack(JSNApiHelper::ToJSHandle(value));
1194 uint32_t size = static_cast<uint32_t>(stack->GetSize() + 1);
1195 Local<JSValueRef> jsValueRef = ArrayRef::New(ecmaVm, size);
1196 JSThread *thread = ecmaVm->GetJSThread();
1197 JSMutableHandle<JSTaggedValue> currentValue(thread, JSTaggedValue::Undefined());
1198 uint32_t index = 0;
1199 while (index < size) {
1200 currentValue.Update(stack->Get(index));
1201 ArrayRef::SetValueAt(ecmaVm, jsValueRef, index++, JSNApiHelper::ToLocal<JSValueRef>(currentValue));
1202 }
1203 AddInternalProperties(ecmaVm, jsValueRef, ArkInternalValueType::Entry, internalObjects);
1204 return jsValueRef;
1205 }
1206
GetTreeMapValue(const EcmaVM * ecmaVm,Local<JSValueRef> value,Global<MapRef> internalObjects)1207 Local<JSValueRef> DebuggerApi::GetTreeMapValue(const EcmaVM *ecmaVm, Local<JSValueRef> value,
1208 Global<MapRef> internalObjects)
1209 {
1210 JSHandle<JSAPITreeMap> treeMap(JSNApiHelper::ToJSHandle(value));
1211 uint32_t size = static_cast<uint32_t>(treeMap->GetSize());
1212 Local<JSValueRef> jsValueRef = ArrayRef::New(ecmaVm, size);
1213 JSThread *thread = ecmaVm->GetJSThread();
1214 JSMutableHandle<TaggedTreeMap> iteratedMap(thread, treeMap->GetTreeMap());
1215 uint32_t elements = static_cast<uint32_t>(iteratedMap->NumberOfElements());
1216 JSHandle<TaggedArray> entries = TaggedTreeMap::GetArrayFromMap(thread, iteratedMap);
1217 JSMutableHandle<JSTaggedValue> currentKey(thread, JSTaggedValue::Undefined());
1218 JSMutableHandle<JSTaggedValue> currentValue(thread, JSTaggedValue::Undefined());
1219 Local<JSValueRef> jsKey = StringRef::NewFromUtf8(ecmaVm, "key");
1220 Local<JSValueRef> jsValue = StringRef::NewFromUtf8(ecmaVm, "value");
1221 uint32_t index = 0;
1222 while (index < elements) {
1223 int entriesIndex = entries->Get(index).GetInt();
1224 currentKey.Update(iteratedMap->GetKey(entriesIndex));
1225 currentValue.Update(iteratedMap->GetValue(entriesIndex));
1226 Local<ObjectRef> objRef = ObjectRef::New(ecmaVm);
1227 objRef->Set(ecmaVm, jsKey, JSNApiHelper::ToLocal<JSValueRef>(currentKey));
1228 objRef->Set(ecmaVm, jsValue, JSNApiHelper::ToLocal<JSValueRef>(currentValue));
1229 AddInternalProperties(ecmaVm, objRef, ArkInternalValueType::Entry, internalObjects);
1230 ArrayRef::SetValueAt(ecmaVm, jsValueRef, index++, objRef);
1231 }
1232 AddInternalProperties(ecmaVm, jsValueRef, ArkInternalValueType::Entry, internalObjects);
1233 return jsValueRef;
1234 }
1235
GetTreeSetValue(const EcmaVM * ecmaVm,Local<JSValueRef> value,Global<MapRef> internalObjects)1236 Local<JSValueRef> DebuggerApi::GetTreeSetValue(const EcmaVM *ecmaVm, Local<JSValueRef> value,
1237 Global<MapRef> internalObjects)
1238 {
1239 JSHandle<JSAPITreeSet> treeSet(JSNApiHelper::ToJSHandle(value));
1240 JSThread *thread = ecmaVm->GetJSThread();
1241 JSMutableHandle<TaggedTreeSet> iteratedSet(thread, treeSet->GetTreeSet());
1242 uint32_t elements = static_cast<uint32_t>(iteratedSet->NumberOfElements());
1243 Local<JSValueRef> jsValueRef = ArrayRef::New(ecmaVm, elements);
1244 JSHandle<TaggedArray> entries = TaggedTreeSet::GetArrayFromSet(thread, iteratedSet);
1245 JSMutableHandle<JSTaggedValue> currentValue(thread, JSTaggedValue::Undefined());
1246 Local<JSValueRef> jsValue = StringRef::NewFromUtf8(ecmaVm, "value");
1247 uint32_t index = 0;
1248 while (index < elements) {
1249 int entriesIndex = entries->Get(index).GetInt();
1250 currentValue.Update(iteratedSet->GetKey(entriesIndex));
1251 if (currentValue->IsECMAObject()) {
1252 Local<ObjectRef> objRef = ObjectRef::New(ecmaVm);
1253 objRef->Set(ecmaVm, jsValue, JSNApiHelper::ToLocal<JSValueRef>(currentValue));
1254 AddInternalProperties(ecmaVm, objRef, ArkInternalValueType::Entry, internalObjects);
1255 ArrayRef::SetValueAt(ecmaVm, jsValueRef, index++, objRef);
1256 } else {
1257 ArrayRef::SetValueAt(ecmaVm, jsValueRef, index++, JSNApiHelper::ToLocal<JSValueRef>(currentValue));
1258 }
1259 }
1260 AddInternalProperties(ecmaVm, jsValueRef, ArkInternalValueType::Entry, internalObjects);
1261 return jsValueRef;
1262 }
1263
GetVectorValue(const EcmaVM * ecmaVm,Local<JSValueRef> value,Global<MapRef> internalObjects)1264 Local<JSValueRef> DebuggerApi::GetVectorValue(const EcmaVM *ecmaVm, Local<JSValueRef> value,
1265 Global<MapRef> internalObjects)
1266 {
1267 JSHandle<JSAPIVector> vector(JSNApiHelper::ToJSHandle(value));
1268 uint32_t size = static_cast<uint32_t>(vector->GetSize());
1269 Local<JSValueRef> jsValueRef = ArrayRef::New(ecmaVm, size);
1270 JSThread *thread = ecmaVm->GetJSThread();
1271 JSMutableHandle<JSTaggedValue> currentValue(thread, JSTaggedValue::Undefined());
1272 uint32_t index = 0;
1273 while (index < size) {
1274 currentValue.Update(vector->Get(thread, vector, index));
1275 ArrayRef::SetValueAt(ecmaVm, jsValueRef, index++, JSNApiHelper::ToLocal<JSValueRef>(currentValue));
1276 }
1277 AddInternalProperties(ecmaVm, jsValueRef, ArkInternalValueType::Entry, internalObjects);
1278 return jsValueRef;
1279 }
1280
CheckPromiseQueueSize(const EcmaVM * ecmaVm)1281 bool DebuggerApi::CheckPromiseQueueSize(const EcmaVM *ecmaVm)
1282 {
1283 auto *debuggerMgr = ecmaVm->GetJsDebuggerManager();
1284 uint32_t queueSizeEntry = debuggerMgr->GetPromiseQueueSizeRecordOfTopFrame();
1285 JSThread *thread = ecmaVm->GetJSThread();
1286 EcmaContext *context = thread->GetCurrentEcmaContext();
1287 uint32_t queueSizeCurrent = job::MicroJobQueue::GetPromiseQueueSize(thread, context->GetMicroJobQueue());
1288 return queueSizeEntry == queueSizeCurrent;
1289 }
1290
CheckIsSendableMethod(const EcmaVM * ecmaVm)1291 bool DebuggerApi::CheckIsSendableMethod(const EcmaVM *ecmaVm)
1292 {
1293 auto *debuggerMgr = ecmaVm->GetJsDebuggerManager();
1294 return debuggerMgr->CheckIsSendableMethod();
1295 }
IsMainThread()1296 bool DebuggerApi::IsMainThread()
1297 {
1298 return JSThread::IsMainThread();
1299 }
1300
DropLastFrame(const EcmaVM * ecmaVm)1301 void DebuggerApi::DropLastFrame(const EcmaVM *ecmaVm)
1302 {
1303 auto *debuggerMgr = ecmaVm->GetJsDebuggerManager();
1304 debuggerMgr->DropLastFrame();
1305 }
1306
DebuggerNativeScope(const EcmaVM * vm)1307 DebuggerApi::DebuggerNativeScope::DebuggerNativeScope(const EcmaVM *vm)
1308 {
1309 thread_ = vm->GetAssociatedJSThread();
1310 ecmascript::ThreadState oldState = thread_->GetState();
1311 if (oldState != ecmascript::ThreadState::RUNNING) {
1312 return;
1313 }
1314 oldThreadState_ = static_cast<uint16_t>(oldState);
1315 hasSwitchState_ = true;
1316 thread_->UpdateState(ecmascript::ThreadState::NATIVE);
1317 }
1318
~DebuggerNativeScope()1319 DebuggerApi::DebuggerNativeScope::~DebuggerNativeScope()
1320 {
1321 if (hasSwitchState_) {
1322 thread_->UpdateState(static_cast<ecmascript::ThreadState>(oldThreadState_));
1323 }
1324 }
1325
DebuggerManagedScope(const EcmaVM * vm)1326 DebuggerApi::DebuggerManagedScope::DebuggerManagedScope(const EcmaVM *vm)
1327 {
1328 thread_ = vm->GetAssociatedJSThread();
1329 ecmascript::ThreadState oldState = thread_->GetState();
1330 if (oldState == ecmascript::ThreadState::RUNNING) {
1331 return;
1332 }
1333 oldThreadState_ = static_cast<uint16_t>(oldState);
1334 hasSwitchState_ = true;
1335 thread_->UpdateState(ecmascript::ThreadState::RUNNING);
1336 }
1337
~DebuggerManagedScope()1338 DebuggerApi::DebuggerManagedScope::~DebuggerManagedScope()
1339 {
1340 if (hasSwitchState_) {
1341 thread_->UpdateState(static_cast<ecmascript::ThreadState>(oldThreadState_));
1342 }
1343 }
1344 } // namespace panda::ecmascript::tooling
1345