• 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 "backend/debugger_executor.h"
17 
18 #include "ecmascript/debugger/debugger_api.h"
19 #include "ecmascript/debugger/js_debugger_manager.h"
20 
21 namespace panda::ecmascript::tooling {
Initialize(const EcmaVM * vm)22 void DebuggerExecutor::Initialize(const EcmaVM *vm)
23 {
24     [[maybe_unused]] EcmaHandleScope handleScope(vm->GetJSThread());
25     Local<ObjectRef> globalObj = JSNApi::GetGlobalObject(vm);
26     globalObj->Set(vm, StringRef::NewFromUtf8(vm, "debuggerSetValue"), FunctionRef::New(
27         const_cast<panda::EcmaVM*>(vm), DebuggerExecutor::DebuggerSetValue));
28     globalObj->Set(vm, StringRef::NewFromUtf8(vm, "debuggerGetValue"), FunctionRef::New(
29         const_cast<panda::EcmaVM*>(vm), DebuggerExecutor::DebuggerGetValue));
30 }
31 
DebuggerGetValue(JsiRuntimeCallInfo * runtimeCallInfo)32 Local<JSValueRef> DebuggerExecutor::DebuggerGetValue(JsiRuntimeCallInfo *runtimeCallInfo)
33 {
34     EcmaVM *vm = runtimeCallInfo->GetVM();
35     uint32_t argc = runtimeCallInfo->GetArgsNumber();
36     if (argc != NUM_ARGS) {
37         return JSValueRef::Undefined(vm);
38     }
39     Local<JSValueRef> name = runtimeCallInfo->GetCallArgRef(0);
40     if (!name->IsString()) {
41         return JSValueRef::Undefined(vm);
42     }
43     Local<JSValueRef> isThrow = runtimeCallInfo->GetCallArgRef(1);
44 
45     auto &frameHandler = vm->GetJsDebuggerManager()->GetEvalFrameHandler();
46     ASSERT(frameHandler);
47 
48     Local<JSValueRef> value = GetValue(vm, frameHandler.get(), Local<StringRef>(name));
49     if (!value.IsEmpty()) {
50         return value;
51     }
52 
53     if (!isThrow->ToBoolean(vm)->Value()) {
54         DebuggerApi::ClearException(vm);
55         return JSValueRef::Undefined(vm);
56     }
57 
58     std::string varName = Local<StringRef>(name)->ToString();
59     ThrowException(vm, varName + " is not defined");
60     return Local<JSValueRef>();
61 }
62 
DebuggerSetValue(JsiRuntimeCallInfo * runtimeCallInfo)63 Local<JSValueRef> DebuggerExecutor::DebuggerSetValue(JsiRuntimeCallInfo *runtimeCallInfo)
64 {
65     EcmaVM *vm = runtimeCallInfo->GetVM();
66     uint32_t argc = runtimeCallInfo->GetArgsNumber();
67     if (argc != NUM_ARGS) {
68         return JSValueRef::Undefined(vm);
69     }
70     Local<JSValueRef> name = runtimeCallInfo->GetCallArgRef(0);
71     if (!name->IsString()) {
72         return JSValueRef::Undefined(vm);
73     }
74     Local<JSValueRef> value = runtimeCallInfo->GetCallArgRef(1);
75 
76     auto &frameHandler = vm->GetJsDebuggerManager()->GetEvalFrameHandler();
77     ASSERT(frameHandler);
78 
79     if (SetValue(vm, frameHandler.get(), Local<StringRef>(name), value)) {
80         return value;
81     }
82 
83     std::string varName = StringRef::Cast(*name)->ToString();
84     ThrowException(vm, varName + " is not defined");
85     return Local<JSValueRef>();
86 }
87 
GetValue(const EcmaVM * vm,const FrameHandler * frameHandler,Local<StringRef> name)88 Local<JSValueRef> DebuggerExecutor::GetValue(const EcmaVM *vm, const FrameHandler *frameHandler, Local<StringRef> name)
89 {
90     Local<JSValueRef> value;
91     value = GetLocalValue(vm, frameHandler, name);
92     if (!value.IsEmpty()) {
93         return value;
94     }
95     value = GetLexicalValue(vm, frameHandler, name);
96     if (!value.IsEmpty()) {
97         return value;
98     }
99     value = GetGlobalValue(vm, name);
100     if (!value.IsEmpty()) {
101         return value;
102     }
103 
104     return Local<JSValueRef>();
105 }
106 
SetValue(const EcmaVM * vm,FrameHandler * frameHandler,Local<StringRef> name,Local<JSValueRef> value)107 bool DebuggerExecutor::SetValue(const EcmaVM *vm, FrameHandler *frameHandler,
108                                 Local<StringRef> name, Local<JSValueRef> value)
109 {
110     if (SetLocalValue(vm, frameHandler, name, value)) {
111         return true;
112     }
113     if (SetLexicalValue(vm, frameHandler, name, value)) {
114         return true;
115     }
116     if (SetGlobalValue(vm, name, value)) {
117         return true;
118     }
119 
120     return false;
121 }
122 
ThrowException(const EcmaVM * vm,const std::string & error)123 void DebuggerExecutor::ThrowException(const EcmaVM *vm, const std::string &error)
124 {
125     Local<StringRef> msg = StringRef::NewFromUtf8(vm, error.c_str());
126     Local<JSValueRef> exception = Exception::ReferenceError(vm, msg);
127     JSNApi::ThrowException(vm, exception);
128 }
129 
GetLocalValue(const EcmaVM * vm,const FrameHandler * frameHandler,Local<StringRef> name)130 Local<JSValueRef> DebuggerExecutor::GetLocalValue(const EcmaVM *vm, const FrameHandler *frameHandler,
131                                                   Local<StringRef> name)
132 {
133     Local<JSValueRef> result;
134 
135     int32_t index = DebuggerApi::GetVregIndex(frameHandler, name->ToString());
136     if (index == -1) {
137         return result;
138     }
139 
140     result = DebuggerApi::GetVRegValue(vm, frameHandler, index);
141     return result;
142 }
143 
SetLocalValue(const EcmaVM * vm,FrameHandler * frameHandler,Local<StringRef> name,Local<JSValueRef> value)144 bool DebuggerExecutor::SetLocalValue(const EcmaVM *vm, FrameHandler *frameHandler,
145                                      Local<StringRef> name, Local<JSValueRef> value)
146 {
147     std::string varName = name->ToString();
148     int32_t index = DebuggerApi::GetVregIndex(frameHandler, varName);
149     if (index == -1) {
150         return false;
151     }
152 
153     DebuggerApi::SetVRegValue(frameHandler, index, value);
154     vm->GetJsDebuggerManager()->NotifyLocalScopeUpdated(varName, value);
155     return true;
156 }
157 
GetLexicalValue(const EcmaVM * vm,const FrameHandler * frameHandler,Local<StringRef> name)158 Local<JSValueRef> DebuggerExecutor::GetLexicalValue(const EcmaVM *vm, const FrameHandler *frameHandler,
159                                                     Local<StringRef> name)
160 {
161     Local<JSValueRef> result;
162 
163     auto [level, slot] = DebuggerApi::GetLevelSlot(frameHandler, name->ToString());
164     if (level == -1) {
165         return result;
166     }
167 
168     result = DebuggerApi::GetProperties(vm, frameHandler, level, slot);
169     return result;
170 }
171 
SetLexicalValue(const EcmaVM * vm,const FrameHandler * frameHandler,Local<StringRef> name,Local<JSValueRef> value)172 bool DebuggerExecutor::SetLexicalValue(const EcmaVM *vm, const FrameHandler *frameHandler,
173                                        Local<StringRef> name, Local<JSValueRef> value)
174 {
175     std::string varName = name->ToString();
176     auto [level, slot] = DebuggerApi::GetLevelSlot(frameHandler, varName);
177     if (level == -1) {
178         return false;
179     }
180 
181     DebuggerApi::SetProperties(vm, frameHandler, level, slot, value);
182     vm->GetJsDebuggerManager()->NotifyLocalScopeUpdated(varName, value);
183     return true;
184 }
185 
GetGlobalValue(const EcmaVM * vm,Local<StringRef> name)186 Local<JSValueRef> DebuggerExecutor::GetGlobalValue(const EcmaVM *vm, Local<StringRef> name)
187 {
188     return DebuggerApi::GetGlobalValue(vm, name);
189 }
190 
SetGlobalValue(const EcmaVM * vm,Local<StringRef> name,Local<JSValueRef> value)191 bool DebuggerExecutor::SetGlobalValue(const EcmaVM *vm, Local<StringRef> name, Local<JSValueRef> value)
192 {
193     return DebuggerApi::SetGlobalValue(vm, name, value);
194 }
195 }  // namespace panda::ecmascript::tooling
196