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 runtime_ = std::make_unique<RuntimeImpl>(vm, nullptr); 29 debugger_ = std::make_unique<DebuggerImpl>(vm, nullptr, runtime_.get()); 30 testName_ = testName; 31 test_ = TestUtil::GetTest(testName); 32 test_->vm_ = vm; 33 test_->debugger_ = debugger_.get(); 34 test_->debugInterface_ = debugger_->jsDebugger_; 35 debugInterface_ = debugger_->jsDebugger_; 36 TestUtil::Reset(); 37 debugInterface_->RegisterHooks(this); 38 } 39 Run()40 void Run() 41 { 42 if (test_->scenario) { 43 test_->scenario(); 44 } 45 } 46 Breakpoint(const JSPtLocation & location)47 void Breakpoint(const JSPtLocation &location) override 48 { 49 if (test_->breakpoint) { 50 test_->breakpoint(location); 51 } 52 } 53 LoadModule(std::string_view panda_file_name,std::string_view entryPoint)54 void LoadModule(std::string_view panda_file_name, [[maybe_unused]]std::string_view entryPoint) override 55 { 56 if (test_->loadModule) { 57 test_->loadModule(panda_file_name); 58 } 59 } 60 Exception(const JSPtLocation & location)61 void Exception(const JSPtLocation &location) override 62 { 63 if (test_->exception) { 64 Local<JSValueRef> exception = DebuggerApi::GetAndClearException(vm_); 65 66 test_->exception(location); 67 68 if (!exception->IsHole()) { 69 DebuggerApi::SetException(vm_, exception); 70 } 71 } 72 } 73 SingleStep(const JSPtLocation & location)74 bool SingleStep(const JSPtLocation &location) override 75 { 76 if (test_->singleStep) { 77 return test_->singleStep(location); 78 } 79 return false; 80 } 81 VmDeath()82 void VmDeath() override 83 { 84 if (test_->vmDeath) { 85 test_->vmDeath(); 86 } 87 TestUtil::Event(DebugEvent::VM_DEATH); 88 } 89 VmStart()90 void VmStart() override 91 { 92 if (test_->vmStart) { 93 test_->vmStart(); 94 } 95 TestUtil::Event(DebugEvent::VM_START); 96 } 97 PendingJobEntry()98 void PendingJobEntry() override {} 99 NativeCalling(const void * nativeAddress)100 void NativeCalling([[maybe_unused]] const void *nativeAddress) override {} 101 TerminateTest()102 void TerminateTest() 103 { 104 debugInterface_->UnregisterHooks(); 105 if (TestUtil::IsTestFinished()) { 106 return; 107 } 108 LOG_DEBUGGER(FATAL) << "Test " << testName_ << " failed"; 109 } 110 111 ~TestHooks() = default; 112 113 private: 114 const EcmaVM *vm_ {nullptr}; 115 std::unique_ptr<RuntimeImpl> runtime_ {nullptr}; 116 std::unique_ptr<DebuggerImpl> debugger_ {nullptr}; 117 JSDebugger *debugInterface_; 118 std::string testName_; 119 TestEvents *test_; 120 }; 121 } // namespace panda::ecmascript::tooling::test 122 123 #endif // ECMASCRIPT_TOOLING_TEST_UTILS_TEST_HOOKS_H 124