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 VmDeath()90 void VmDeath() override 91 { 92 if (test_->vmDeath) { 93 test_->vmDeath(); 94 } 95 TestUtil::Event(DebugEvent::VM_DEATH); 96 } 97 VmStart()98 void VmStart() override 99 { 100 if (test_->vmStart) { 101 test_->vmStart(); 102 } 103 TestUtil::Event(DebugEvent::VM_START); 104 } 105 NativeCalling(const void * nativeAddress)106 void NativeCalling([[maybe_unused]] const void *nativeAddress) override {} 107 TerminateTest()108 void TerminateTest() 109 { 110 debugInterface_->UnregisterHooks(); 111 if (TestUtil::IsTestFinished()) { 112 return; 113 } 114 LOG_DEBUGGER(FATAL) << "Test " << testName_ << " failed"; 115 } 116 117 ~TestHooks() = default; 118 119 private: 120 const EcmaVM *vm_ {nullptr}; 121 std::unique_ptr<RuntimeImpl> runtime_ {nullptr}; 122 std::unique_ptr<DebuggerImpl> debugger_ {nullptr}; 123 JSDebugger *debugInterface_; 124 std::string testName_; 125 TestEvents *test_; 126 }; 127 } // namespace panda::ecmascript::tooling::test 128 129 #endif // ECMASCRIPT_TOOLING_TEST_UTILS_TEST_HOOKS_H 130