• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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()36 NativeScopeManager::NativeScopeManager()
37 {
38     root_ = NativeScope::CreateNewInstance();
39     current_ = root_;
40 }
41 
~NativeScopeManager()42 NativeScopeManager::~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()61 NativeScope* 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)78 void 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()99 NativeScope* NativeScopeManager::OpenEscape()
100 {
101     NativeScope* scope = Open();
102     if (scope != nullptr) {
103         scope->escaped = true;
104     }
105     return scope;
106 }
107 
CloseEscape(NativeScope * scope)108 void NativeScopeManager::CloseEscape(NativeScope* scope)
109 {
110     if (scope == nullptr) {
111         return;
112     }
113     Close(scope);
114 }
115 
Escape(NativeScope * scope,NativeValue * value)116 NativeValue* 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)151 void 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