1/*
2 * Copyright (c) 2021-2024 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#ifndef ECMASCRIPT_DEBUGGER_DEBUGGER_API_H
17#define ECMASCRIPT_DEBUGGER_DEBUGGER_API_H
18
19#include <functional>
20
21#include "ecmascript/common.h"
22#include "ecmascript/debugger/js_debugger_interface.h"
23#include "ecmascript/debugger/js_pt_method.h"
24#include "ecmascript/jspandafile/scope_info_extractor.h"
25#include "ecmascript/napi/include/jsnapi.h"
26
27namespace panda {
28namespace ecmascript {
29class EcmaVM;
30class FrameHandler;
31class JSThread;
32class Method;
33class ModuleManager;
34class NameDictionary;
35class SourceTextModule;
36class DebugInfoExtractor;
37namespace tooling {
38class JSDebugger;
39}
40}  // ecmascript
41}  // panda
42
43namespace panda::ecmascript::tooling {
44enum StackState {
45    CONTINUE,
46    FAILED,
47    SUCCESS,
48};
49
50enum class ArkInternalValueType {None, Entry, Scope, ScopeList};
51class PUBLIC_API DebuggerApi {
52public:
53    class PUBLIC_API DebuggerNativeScope {
54    public:
55        explicit DebuggerNativeScope(const EcmaVM *vm);
56        ~DebuggerNativeScope();
57        ECMA_DISALLOW_COPY(DebuggerNativeScope);
58        ECMA_DISALLOW_MOVE(DebuggerNativeScope);
59
60    private:
61        JSThread *thread_ {nullptr};
62        uint16_t oldThreadState_ {0};
63        bool hasSwitchState_ {false};
64    };
65    class PUBLIC_API DebuggerManagedScope {
66    public:
67        explicit DebuggerManagedScope(const EcmaVM *vm);
68        ~DebuggerManagedScope();
69        ECMA_DISALLOW_COPY(DebuggerManagedScope);
70        ECMA_DISALLOW_MOVE(DebuggerManagedScope);
71
72    private:
73        JSThread *thread_ {nullptr};
74        uint16_t oldThreadState_ {0};
75        bool hasSwitchState_ {false};
76    };
77
78    // FrameHandler
79    static uint32_t GetStackDepth(const EcmaVM *ecmaVm);
80    static std::shared_ptr<FrameHandler> NewFrameHandler(const EcmaVM *ecmaVm);
81    static bool StackWalker(const EcmaVM *ecmaVm, std::function<StackState(const FrameHandler *)> func);
82    static uint32_t GetStackDepthOverBuiltin(const EcmaVM *ecmaVm);
83
84    static uint32_t GetBytecodeOffset(const EcmaVM *ecmaVm);
85    static uint32_t GetBytecodeOffset(const FrameHandler *frameHandler);
86    static std::unique_ptr<PtMethod> GetMethod(const EcmaVM *ecmaVm);
87    static Method *GetMethod(const FrameHandler *frameHandler);
88    static bool IsNativeMethod(const EcmaVM *ecmaVm);
89    static bool IsNativeMethod(const FrameHandler *frameHandler);
90    static JSPandaFile *GetJSPandaFile(const EcmaVM *ecmaVm);
91
92    static JSTaggedValue GetEnv(const FrameHandler *frameHandler);
93    static JSTaggedType *GetSp(const FrameHandler *frameHandler);
94    static int32_t GetVregIndex(const FrameHandler *frameHandler, std::string_view name);
95    static Local<JSValueRef> GetVRegValue(const EcmaVM *ecmaVm,
96                                          const FrameHandler *frameHandler, size_t index);
97    static void SetVRegValue(FrameHandler *frameHandler, size_t index, Local<JSValueRef> value);
98
99    static Local<JSValueRef> GetProperties(const EcmaVM *ecmaVm, const FrameHandler *frameHandler,
100                                           int32_t level, uint32_t slot);
101    static void SetProperties(const EcmaVM *ecmaVm, const FrameHandler *frameHandler, int32_t level,
102                              uint32_t slot, Local<JSValueRef> value);
103    static std::pair<int32_t, uint32_t> GetLevelSlot(const FrameHandler *frameHandler, std::string_view name);
104    static Local<JSValueRef> GetGlobalValue(const EcmaVM *ecmaVm, Local<StringRef> name);
105    static bool SetGlobalValue(const EcmaVM *ecmaVm, Local<StringRef> name, Local<JSValueRef> value);
106
107    // JSThread
108    static Local<JSValueRef> GetAndClearException(const EcmaVM *ecmaVm);
109    static JSTaggedValue GetCurrentModule(const EcmaVM *ecmaVm);
110    static JSHandle<JSTaggedValue> GetImportModule(const EcmaVM *ecmaVm, const JSHandle<JSTaggedValue> &currentModule,
111                                                   std::string &name);
112    static int32_t GetModuleVariableIndex(const EcmaVM *ecmaVm, const JSHandle<JSTaggedValue> &currentModule,
113                                          std::string &name);
114    static int32_t GetRequestModuleIndex(const EcmaVM *ecmaVm, const JSTaggedValue moduleRequest,
115                                         const JSHandle<JSTaggedValue> &currentModule);
116    static Local<JSValueRef> GetExportVariableValue(const EcmaVM *ecmaVm, const JSHandle<JSTaggedValue> &currentModule,
117                                                    std::string &name);
118    static bool SetExportVariableValue(const EcmaVM *ecmaVm, const JSHandle<JSTaggedValue> &currentModule,
119                                       std::string &name, Local<JSValueRef> value);
120    static Local<JSValueRef> GetModuleValue(const EcmaVM *ecmaVm, const JSHandle<JSTaggedValue> &currentModule,
121                                            std::string &name);
122    static bool SetModuleValue(const EcmaVM *ecmaVm, const JSHandle<JSTaggedValue> &currentModule,
123                               std::string &name, Local<JSValueRef> value);
124    static void InitializeExportVariables(const EcmaVM *ecmaVm, Local<ObjectRef> &moduleObj,
125                                          const JSHandle<JSTaggedValue> &currentModule);
126    static void GetLocalExportVariables(const EcmaVM *ecmaVm, Local<ObjectRef> &moduleObj,
127                                        const JSHandle<JSTaggedValue> &currentModule, bool isImportStar);
128    static void GetIndirectExportVariables(const EcmaVM *ecmaVm, Local<ObjectRef> &moduleObj,
129                                           const JSHandle<JSTaggedValue> &currentModule);
130    static void GetImportVariables(const EcmaVM *ecmaVm, Local<ObjectRef> &moduleObj,
131                                   const JSHandle<JSTaggedValue> &currentModule);
132    static void SetException(const EcmaVM *ecmaVm, Local<JSValueRef> exception);
133    static void ClearException(const EcmaVM *ecmaVm);
134    static bool IsExceptionCaught(const EcmaVM *ecmaVm);
135
136    // NumberHelper
137    static double StringToDouble(const uint8_t *start, const uint8_t *end, uint8_t radix);
138
139    // JSDebugger
140    static JSDebugger *CreateJSDebugger(const EcmaVM *ecmaVm);
141    static void DestroyJSDebugger(JSDebugger *debugger);
142    static void RegisterHooks(JSDebugger *debugger, PtHooks *hooks);
143    static bool SetBreakpoint(JSDebugger *debugger, const JSPtLocation &location,
144                              Local<FunctionRef> condFuncRef, bool isSmartBreakPoint = false);
145    static bool RemoveBreakpoint(JSDebugger *debugger, const JSPtLocation &location);
146    static void RemoveAllBreakpoints(JSDebugger *debugger);
147    static void HandleUncaughtException(const EcmaVM *ecmaVm, std::string &message);
148    static Local<JSValueRef> EvaluateViaFuncCall(EcmaVM *ecmaVm, Local<FunctionRef> funcRef,
149                                                 std::shared_ptr<FrameHandler> &frameHandler);
150    static Local<JSValueRef> CallFunctionOnCall(EcmaVM *ecmaVm, Local<FunctionRef> funcRef,
151                                                std::shared_ptr<FrameHandler> &frameHandler);
152    static Local<FunctionRef> GenerateFuncFromBuffer(const EcmaVM *ecmaVm, const void *buffer, size_t size,
153                                                     std::string_view entryPoint);
154    static void SetSingleStepStatus(JSDebugger *debugger, bool status);
155    static bool GetSingleStepStatus(JSDebugger *debugger);
156
157    static int32_t GetObjectHash(const EcmaVM *ecmaVM, const JSHandle<JSTaggedValue> &tagged);
158    static void GetObjectClassName(const EcmaVM *ecmaVM, Local<JSValueRef> &tagged, std::string &className);
159    static bool RemoveBreakpointsByUrl(JSDebugger *debugger, const std::string &url);
160
161    // HotReload
162    static std::vector<DebugInfoExtractor *> GetPatchExtractors(const EcmaVM *ecmaVm, const std::string &url);
163    static const JSPandaFile *GetBaseJSPandaFile(const EcmaVM *ecmaVm, const JSPandaFile *jsPandaFile);
164    static std::vector<void *> GetNativePointer(const EcmaVM *ecmaVm);
165
166    // Container
167    static uint32_t GetContainerLength(const EcmaVM *ecmaVm, Local<JSValueRef> value);
168    static void AddInternalProperties(const EcmaVM *ecmaVm, Local<ObjectRef> object,
169                                      ArkInternalValueType type, Global<MapRef> internalObjects);
170    static Local<JSValueRef> GetArrayListValue(const EcmaVM *ecmaVm, Local<JSValueRef> value,
171                                               Global<MapRef> internalObjects);
172    static Local<JSValueRef> GetDequeValue(const EcmaVM *ecmaVm, Local<JSValueRef> value,
173                                           Global<MapRef> internalObjects);
174    static Local<JSValueRef> GetHashMapValue(const EcmaVM *ecmaVm, Local<JSValueRef> value,
175                                             Global<MapRef> internalObjects);
176    static Local<JSValueRef> GetHashSetValue(const EcmaVM *ecmaVm, Local<JSValueRef> value,
177                                             Global<MapRef> internalObjects);
178    static Local<JSValueRef> GetLightWeightMapValue(const EcmaVM *ecmaVm, Local<JSValueRef> value,
179                                                    Global<MapRef> internalObjects);
180    static Local<JSValueRef> GetLightWeightSetValue(const EcmaVM *ecmaVm, Local<JSValueRef> value,
181                                                    Global<MapRef> internalObjects);
182    static Local<JSValueRef> GetLinkedListValue(const EcmaVM *ecmaVm, Local<JSValueRef> value,
183                                                Global<MapRef> internalObjects);
184    static Local<JSValueRef> GetListValue(const EcmaVM *ecmaVm, Local<JSValueRef> value,
185                                          Global<MapRef> internalObjects);
186    static Local<JSValueRef> GetPlainArrayValue(const EcmaVM *ecmaVm, Local<JSValueRef> value,
187                                                Global<MapRef> internalObjects);
188    static Local<JSValueRef> GetQueueValue(const EcmaVM *ecmaVm, Local<JSValueRef> value,
189                                           Global<MapRef> internalObjects);
190    static Local<JSValueRef> GetStackValue(const EcmaVM *ecmaVm, Local<JSValueRef> value,
191                                           Global<MapRef> internalObjects);
192    static Local<JSValueRef> GetTreeMapValue(const EcmaVM *ecmaVm, Local<JSValueRef> value,
193                                             Global<MapRef> internalObjects);
194    static Local<JSValueRef> GetTreeSetValue(const EcmaVM *ecmaVm, Local<JSValueRef> value,
195                                             Global<MapRef> internalObjects);
196    static Local<JSValueRef> GetVectorValue(const EcmaVM *ecmaVm, Local<JSValueRef> value,
197                                            Global<MapRef> internalObjects);
198
199    static bool CheckPromiseQueueSize(const EcmaVM *ecmaVm);
200    static bool CheckIsSendableMethod(const EcmaVM *ecmaVm);
201    static bool IsMainThread();
202    static void DropLastFrame(const EcmaVM *ecmaVm);
203};
204}  // namespace panda::ecmascript::tooling
205
206#endif  // ECMASCRIPT_DEBUGGER_DEBUGGER_API_H
207