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> ¤tModule, 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> ¤tModule,
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> ¤tModule)
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> ¤tModule, 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> ¤tModule,
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> ¤tModule,
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> ¤tModule,
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> ¤tModule)
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> ¤tModule, 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> ¤tModule)
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> ¤tModule)
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