[poincare] Fix TreeRef deletion: releaseNode shouldn't create a TreeRef

This commit is contained in:
Léa Saviot
2018-08-14 17:31:47 +02:00
parent 220e2285b1
commit cd43d84b1e
6 changed files with 23 additions and 16 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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 */

View File

@@ -18,7 +18,7 @@ void TreeNode::release(int currentNumberOfChildren) {
}
m_referenceCounter--;
if (m_referenceCounter == 0) {
TreeByReference(this).removeChildrenAndDestroyInPlace(currentNumberOfChildren);
TreePool::sharedPool()->removeChildrenAndDestroy(this, currentNumberOfChildren);
}
}

View File

@@ -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;