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 #ifndef PANDA_RUNTIME_HANDLE_SCOPE_H 17 #define PANDA_RUNTIME_HANDLE_SCOPE_H 18 19 #include "runtime/handle_base.h" 20 #include "runtime/include/coretypes/tagged_value.h" 21 22 namespace panda { 23 /* 24 * Handles are only valid within a HandleScope. When a handle is created for an object a cell is allocated in the 25 * current HandleScope. 26 */ 27 template <typename T> 28 class HandleScope { 29 public: 30 inline explicit HandleScope(ManagedThread *thread); 31 32 virtual inline ~HandleScope(); 33 GetBeginIndex()34 inline uint32_t GetBeginIndex() const 35 { 36 return beginIndex_; 37 } 38 GetHandleCount()39 inline uint32_t GetHandleCount() const 40 { 41 return handleCount_; 42 } 43 44 uintptr_t NewHandle(T value); 45 46 protected: 47 inline HandleScope(ManagedThread *thread, T value); 48 49 inline ManagedThread *GetThread() const; 50 51 uint32_t beginIndex_ {0}; // NOLINT(misc-non-private-member-variables-in-classes) 52 53 private: 54 uint32_t handleCount_ {0}; 55 ManagedThread *thread_ {nullptr}; 56 57 NO_COPY_SEMANTIC(HandleScope); 58 NO_MOVE_SEMANTIC(HandleScope); 59 }; 60 61 /* 62 * EscapeHandleScope: Support the user to return a handle to prev handlescope. 63 */ 64 template <typename T> 65 class EscapeHandleScope final : public HandleScope<T> { 66 public: 67 inline explicit EscapeHandleScope(ManagedThread *thread); 68 ~EscapeHandleScope()69 inline ~EscapeHandleScope() override 70 { 71 ASSERT(alreadyEscape_); 72 } 73 74 NO_COPY_SEMANTIC(EscapeHandleScope); 75 NO_MOVE_SEMANTIC(EscapeHandleScope); 76 Escape(HandleBase handle)77 inline HandleBase Escape(HandleBase handle) 78 { 79 ASSERT(!alreadyEscape_); 80 alreadyEscape_ = true; 81 *(reinterpret_cast<T *>(escapeHandle_.GetAddress())) = *(reinterpret_cast<T *>(handle.GetAddress())); 82 return escapeHandle_; 83 } 84 85 private: 86 bool alreadyEscape_ = false; 87 HandleBase escapeHandle_; 88 }; 89 } // namespace panda 90 #endif // PANDA_RUNTIME_HANDLE_SCOPE_H 91