mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[poincare] Fix TreeRef deletion: releaseNode shouldn't create a TreeRef
This commit is contained in:
@@ -36,7 +36,6 @@ public:
|
||||
NAryExpression(const NAryExpressionNode * n) : Expression(n) {}
|
||||
using Expression::addChildAtIndexInPlace;
|
||||
using Expression::removeChildrenInPlace;
|
||||
using Expression::removeChildrenAndDestroyInPlace;
|
||||
using Expression::removeChildAtIndexInPlace;
|
||||
using Expression::removeChildInPlace;
|
||||
typedef int (*ExpressionOrder)(const ExpressionNode * e1, const ExpressionNode * e2, bool canBeInterrupted);
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
#ifndef POINCARE_TREE_BY_REFERENCE_H
|
||||
#define POINCARE_TREE_BY_REFERENCE_H
|
||||
|
||||
#include "tree_pool.h"
|
||||
#include <poincare/tree_pool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class TreeByReference {
|
||||
friend class TreeNode;
|
||||
friend class TreePool;
|
||||
public:
|
||||
/* Constructors */
|
||||
TreeByReference(const TreeByReference & tr) : m_identifier(TreePool::NoNodeIdentifier) {
|
||||
@@ -129,7 +130,6 @@ protected:
|
||||
virtual void removeChildAtIndexInPlace(int i);
|
||||
virtual void removeChildInPlace(TreeByReference t, int childNumberOfChildren);
|
||||
virtual void removeChildrenInPlace(int currentNumberOfChildren);
|
||||
virtual void removeChildrenAndDestroyInPlace(int currentNumberOfChildren);
|
||||
|
||||
int m_identifier;
|
||||
|
||||
|
||||
@@ -69,6 +69,8 @@ public:
|
||||
|
||||
void move(TreeNode * destination, TreeNode * source, int realNumberOfSourceChildren);
|
||||
void moveChildren(TreeNode * destination, TreeNode * sourceParent);
|
||||
void removeChildren(TreeNode * node, int nodeNumberOfChildren);
|
||||
void removeChildrenAndDestroy(TreeNode * nodeToDestroy, int nodeNumberOfChildren);
|
||||
|
||||
TreeNode * deepCopy(TreeNode * node) {
|
||||
size_t size = node->deepSize(-1);
|
||||
|
||||
@@ -80,7 +80,7 @@ void TreeByReference::replaceWithAllocationFailureInPlace(int currentNumberOfChi
|
||||
TreeNode * staticAllocFailNode = node()->failedAllocationStaticNode();
|
||||
|
||||
// Release all children and delete the node in the pool
|
||||
removeChildrenAndDestroyInPlace(currentNumberOfChildren);
|
||||
TreePool::sharedPool()->removeChildrenAndDestroy(node(), currentNumberOfChildren);
|
||||
/* WARNING: If we called "p.decrementNumberOfChildren()" here, the number of
|
||||
* children of the parent layout would be:
|
||||
* -> numberOfChildren() for "dynamic trees" that have a m_numberOfChildren
|
||||
@@ -202,17 +202,7 @@ void TreeByReference::removeChildInPlace(TreeByReference t, int childNumberOfChi
|
||||
|
||||
void TreeByReference::removeChildrenInPlace(int currentNumberOfChildren) {
|
||||
assert(!isUninitialized());
|
||||
for (int i = 0; i < currentNumberOfChildren; i++) {
|
||||
TreeByReference childRef = childAtIndex(0);
|
||||
TreePool::sharedPool()->move(TreePool::sharedPool()->last(), childRef.node(), childRef.numberOfChildren());
|
||||
childRef.node()->release(childRef.numberOfChildren());
|
||||
}
|
||||
node()->eraseNumberOfChildren();
|
||||
}
|
||||
|
||||
void TreeByReference::removeChildrenAndDestroyInPlace(int currentNumberOfChildren) {
|
||||
removeChildrenInPlace(currentNumberOfChildren);
|
||||
TreePool::sharedPool()->discardTreeNode(node());
|
||||
TreePool::sharedPool()->removeChildren(node(), currentNumberOfChildren);
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
@@ -18,7 +18,7 @@ void TreeNode::release(int currentNumberOfChildren) {
|
||||
}
|
||||
m_referenceCounter--;
|
||||
if (m_referenceCounter == 0) {
|
||||
TreeByReference(this).removeChildrenAndDestroyInPlace(currentNumberOfChildren);
|
||||
TreePool::sharedPool()->removeChildrenAndDestroy(this, currentNumberOfChildren);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <poincare/tree_pool.h>
|
||||
#include <poincare/tree_by_reference.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -63,6 +64,21 @@ void TreePool::moveChildren(TreeNode * destination, TreeNode * sourceParent) {
|
||||
moveNodes(destination, sourceParent->next(), moveSize);
|
||||
}
|
||||
|
||||
void TreePool::removeChildren(TreeNode * node, int nodeNumberOfChildren) {
|
||||
for (int i = 0; i < nodeNumberOfChildren; i++) {
|
||||
TreeNode * child = node->childAtIndex(0);
|
||||
TreeNode * newAddress = last();
|
||||
move(newAddress, child, child->numberOfChildren());
|
||||
newAddress->release(newAddress->numberOfChildren());
|
||||
}
|
||||
node->eraseNumberOfChildren();
|
||||
}
|
||||
|
||||
void TreePool::removeChildrenAndDestroy(TreeNode * nodeToDestroy, int nodeNumberOfChildren) {
|
||||
removeChildren(nodeToDestroy, nodeNumberOfChildren);
|
||||
discardTreeNode(nodeToDestroy);
|
||||
}
|
||||
|
||||
void TreePool::moveNodes(TreeNode * destination, TreeNode * source, size_t moveSize) {
|
||||
if (source == destination || moveSize == 0) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user