1 /* 2 * Copyright (c) 2021 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_TOOLING_TEST_UTILS_TEST_HOOKS_H 17 #define ECMASCRIPT_TOOLING_TEST_UTILS_TEST_HOOKS_H 18 19 #include "agent/debugger_impl.h" 20 #include "backend/js_pt_hooks.h" 21 #include "test/utils/test_util.h" 22 23 namespace panda::ecmascript::tooling::test { 24 class TestHooks : public PtHooks { 25 public: TestHooks(const std::string & testName,const EcmaVM * vm)26 TestHooks(const std::string &testName, const EcmaVM *vm) : vm_(vm) 27 { 28 testName_ = testName; 29 test_ = TestUtil::GetTest(testName); 30 runtime_ = std::make_unique<RuntimeImpl>(vm, test_->channel_); 31 debugger_ = std::make_unique<DebuggerImpl>(vm, test_->channel_, runtime_.get()); 32 test_->vm_ = vm; 33 test_->debugger_ = debugger_.get(); 34 test_->runtime_ = runtime_.get(); 35 test_->debugInterface_ = debugger_->jsDebugger_; 36 debugInterface_ = debugger_->jsDebugger_; 37 TestUtil::Reset(); 38 debugInterface_->RegisterHooks(this); 39 } 40 Run()41 void Run() 42 { 43 if (test_->scenario) { 44 test_->scenario(); 45 } 46 } 47 DebuggerStmt(const JSPtLocation & location)48 void DebuggerStmt(const JSPtLocation &location) override 49 { 50 if (test_->debugger_) { 51 test_->debuggerStmt(location); 52 } 53 } 54 Breakpoint(const JSPtLocation & location)55 void Breakpoint(const JSPtLocation &location) override 56 { 57 if (test_->breakpoint) { 58 test_->breakpoint(location); 59 } 60 } 61 LoadModule(std::string_view panda_file_name,std::string_view entryPoint)62 void LoadModule(std::string_view panda_file_name, [[maybe_unused]] std::string_view entryPoint) override 63 { 64 if (test_->loadModule) { 65 test_->loadModule(panda_file_name); 66 } 67 } 68 Exception(const JSPtLocation & location)69 void Exception(const JSPtLocation &location) override 70 { 71 if (test_->exception) { 72 Local<JSValueRef> exception = DebuggerApi::GetAndClearException(vm_); 73 74 test_->exception(location); 75 76 if (!exception->IsHole()) { 77 DebuggerApi::SetException(vm_, exception); 78 } 79 } 80 } 81 SingleStep(const JSPtLocation & location)82 bool SingleStep(const JSPtLocation &location) override 83 { 84 if (test_->singleStep) { 85 return test_->singleStep(location); 86 } 87 return false; 88 } 89 NativeOut()90 bool NativeOut() override 91 { 92 if (test_->nativeOut) { 93 return test_->nativeOut(); 94 } 95 96 return false; 97 } 98 VmDeath()99 void VmDeath() override 100 { 101 if (test_->vmDeath) { 102 test_->vmDeath(); 103 } 104 TestUtil::Event(DebugEvent::VM_DEATH); 105 } 106 VmStart()107 void VmStart() override 108 { 109 if (test_->vmStart) { 110 test_->vmStart(); 111 } 112 TestUtil::Event(DebugEvent::VM_START); 113 } 114 NativeCalling(const void * nativeAddress)115 void NativeCalling([[maybe_unused]] const void *nativeAddress) override {} 116 NativeReturn(const void * nativeAddress)117 void NativeReturn([[maybe_unused]] const void *nativeAddress) override {} 118 TerminateTest()119 void TerminateTest() 120 { 121 debugInterface_->UnregisterHooks(); 122 if (TestUtil::IsTestFinished()) { 123 return; 124 } 125 LOG_DEBUGGER(FATAL) << "Test " << testName_ << " failed"; 126 } 127 128 ~TestHooks() = default; 129 130 private: 131 const EcmaVM *vm_ {nullptr}; 132 std::unique_ptr<RuntimeImpl> runtime_ {nullptr}; 133 std::unique_ptr<DebuggerImpl> debugger_ {nullptr}; 134 JSDebugger *debugInterface_; 135 std::string testName_; 136 TestEvents *test_; 137 }; 138 } // namespace panda::ecmascript::tooling::test 139 140 #endif // ECMASCRIPT_TOOLING_TEST_UTILS_TEST_HOOKS_H 141