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