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 #include "native_scope_manager.h" 17 18 #include "native_engine/native_value.h" 19 #include "utils/log.h" 20 21 struct NativeHandle { 22 NativeValue* value = nullptr; 23 NativeHandle* sibling = nullptr; 24 }; 25 26 struct NativeScope { CreateNewInstanceNativeScope27 static NativeScope* CreateNewInstance() { return new NativeScope(); } 28 NativeHandle* handlePtr = nullptr; 29 size_t handleCount = 0; 30 bool escaped = false; 31 32 NativeScope* child = nullptr; 33 NativeScope* parent = nullptr; 34 }; 35 NativeScopeManager()36NativeScopeManager::NativeScopeManager() 37 { 38 root_ = NativeScope::CreateNewInstance(); 39 current_ = root_; 40 } 41 ~NativeScopeManager()42NativeScopeManager::~NativeScopeManager() 43 { 44 NativeScope* scope = root_; 45 while (scope != nullptr) { 46 NativeScope* tempScope = scope->child; 47 NativeHandle* handle = scope->handlePtr; 48 while (handle != nullptr) { 49 NativeHandle* tempHandle = handle->sibling; 50 delete handle->value; 51 delete handle; 52 handle = tempHandle; 53 } 54 delete scope; 55 scope = tempScope; 56 } 57 root_ = nullptr; 58 current_ = nullptr; 59 } 60 Open()61NativeScope* NativeScopeManager::Open() 62 { 63 if (current_ == nullptr) { 64 HILOG_ERROR("current scope is null when open scope"); 65 return nullptr; 66 } 67 68 auto scope = new NativeScope(); 69 if (scope != nullptr) { 70 current_->child = scope; 71 scope->parent = current_; 72 current_ = scope; 73 } 74 75 return scope; 76 } 77 Close(NativeScope * scope)78void NativeScopeManager::Close(NativeScope* scope) 79 { 80 if ((scope == nullptr) || (scope == root_)) { 81 return; 82 } 83 if (scope == current_) { 84 current_ = scope->parent; 85 } 86 87 scope->parent->child = scope->child; 88 89 NativeHandle* handle = scope->handlePtr; 90 while (handle != nullptr) { 91 scope->handlePtr = handle->sibling; 92 delete handle->value; 93 delete handle; 94 handle = scope->handlePtr; 95 } 96 delete scope; 97 } 98 OpenEscape()99NativeScope* NativeScopeManager::OpenEscape() 100 { 101 NativeScope* scope = Open(); 102 if (scope != nullptr) { 103 scope->escaped = true; 104 } 105 return scope; 106 } 107 CloseEscape(NativeScope * scope)108void NativeScopeManager::CloseEscape(NativeScope* scope) 109 { 110 if (scope == nullptr) { 111 return; 112 } 113 Close(scope); 114 } 115 Escape(NativeScope * scope,NativeValue * value)116NativeValue* NativeScopeManager::Escape(NativeScope* scope, NativeValue* value) 117 { 118 NativeValue* result = nullptr; 119 120 if ((scope == nullptr) || (value == nullptr)) { 121 return result; 122 } 123 124 NativeHandle* handle = scope->handlePtr; 125 NativeHandle* temp = nullptr; 126 while (handle != nullptr && scope->escaped) { 127 if (handle->value == value) { 128 if (temp == nullptr) { 129 scope->handlePtr = handle->sibling; 130 } else { 131 temp->sibling = handle->sibling; 132 } 133 if (scope->parent->handlePtr == nullptr) { 134 scope->parent->handlePtr = handle; 135 handle->sibling = nullptr; 136 } else { 137 handle->sibling = scope->parent->handlePtr; 138 scope->parent->handlePtr = handle; 139 } 140 scope->handleCount--; 141 scope->parent->handleCount++; 142 result = scope->parent->handlePtr->value; 143 break; 144 } 145 temp = handle; 146 handle = handle->sibling; 147 } 148 return result; 149 } 150 CreateHandle(NativeValue * value)151void NativeScopeManager::CreateHandle(NativeValue* value) 152 { 153 if (current_ == nullptr) { 154 HILOG_ERROR("current scope is null when create handle"); 155 return; 156 } 157 auto handlePtr = new NativeHandle(); 158 if (handlePtr == nullptr) { 159 HILOG_ERROR("create handle ptr failed"); 160 return; 161 } 162 if (current_->handlePtr == nullptr) { 163 current_->handlePtr = handlePtr; 164 current_->handlePtr->value = value; 165 current_->handlePtr->sibling = nullptr; 166 } else { 167 handlePtr->sibling = current_->handlePtr; 168 handlePtr->value = value; 169 current_->handlePtr = handlePtr; 170 } 171 current_->handleCount++; 172 } 173