Files
ace_napi/scope_manager/native_scope_manager.cpp
T
zhongjianfei a99921b5ca zhongjianfei@huawei.com
Signed-off-by: zhongjianfei <zhongjianfei@huawei.com>
Change-Id: Ic43ae2175fca333394f68d670ee60343cf63c278
2021-09-14 15:48:11 +08:00

173 lines
4.4 KiB
C++

/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "native_scope_manager.h"
#include "native_engine/native_value.h"
#include "utils/log.h"
struct NativeHandle {
NativeValue* value = nullptr;
NativeHandle* sibling = nullptr;
};
struct NativeScope {
static NativeScope* CreateNewInstance() { return new NativeScope(); }
NativeHandle* handlePtr = nullptr;
size_t handleCount = 0;
bool escaped = false;
NativeScope* child = nullptr;
NativeScope* parent = nullptr;
};
NativeScopeManager::NativeScopeManager()
{
root_ = NativeScope::CreateNewInstance();
current_ = root_;
}
NativeScopeManager::~NativeScopeManager()
{
NativeScope* scope = root_;
while (scope != nullptr) {
NativeScope* tempScope = scope->child;
NativeHandle* handle = scope->handlePtr;
while (handle != nullptr) {
NativeHandle* tempHandle = handle->sibling;
delete handle->value;
delete handle;
handle = tempHandle;
}
delete scope;
scope = tempScope;
}
root_ = nullptr;
current_ = nullptr;
}
NativeScope* NativeScopeManager::Open()
{
if (current_ == nullptr) {
HILOG_ERROR("current scope is null when open scope");
return nullptr;
}
auto scope = new NativeScope();
if (scope != nullptr) {
current_->child = scope;
scope->parent = current_;
current_ = scope;
}
return scope;
}
void NativeScopeManager::Close(NativeScope* scope)
{
if ((scope == nullptr) || (scope == root_)) {
return;
}
if (scope == current_) {
current_ = scope->parent;
}
scope->parent->child = scope->child;
NativeHandle* handle = scope->handlePtr;
while (handle != nullptr) {
scope->handlePtr = handle->sibling;
delete handle->value;
delete handle;
handle = scope->handlePtr;
}
delete scope;
}
NativeScope* NativeScopeManager::OpenEscape()
{
NativeScope* scope = Open();
if (scope != nullptr) {
scope->escaped = true;
}
return scope;
}
void NativeScopeManager::CloseEscape(NativeScope* scope)
{
if (scope == nullptr) {
return;
}
Close(scope);
}
NativeValue* NativeScopeManager::Escape(NativeScope* scope, NativeValue* value)
{
NativeValue* result = nullptr;
if ((scope == nullptr) || (value == nullptr)) {
return result;
}
NativeHandle* handle = scope->handlePtr;
NativeHandle* temp = nullptr;
while (handle != nullptr && scope->escaped) {
if (handle->value == value) {
if (temp == nullptr) {
scope->handlePtr = handle->sibling;
} else {
temp->sibling = handle->sibling;
}
if (scope->parent->handlePtr == nullptr) {
scope->parent->handlePtr = handle;
handle->sibling = nullptr;
} else {
handle->sibling = scope->parent->handlePtr;
scope->parent->handlePtr = handle;
}
scope->handleCount--;
scope->parent->handleCount++;
result = scope->parent->handlePtr->value;
break;
}
temp = handle;
handle = handle->sibling;
}
return result;
}
void NativeScopeManager::CreateHandle(NativeValue* value)
{
if (current_ == nullptr) {
HILOG_ERROR("current scope is null when create handle");
return;
}
auto handlePtr = new NativeHandle();
if (handlePtr == nullptr) {
HILOG_ERROR("create handle ptr failed");
return;
}
if (current_->handlePtr == nullptr) {
current_->handlePtr = handlePtr;
current_->handlePtr->value = value;
current_->handlePtr->sibling = nullptr;
} else {
handlePtr->sibling = current_->handlePtr;
handlePtr->value = value;
current_->handlePtr = handlePtr;
}
current_->handleCount++;
}