From 4269003d1ac4575dacd53675aaec87ba283c1f2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Fri, 17 Aug 2018 10:34:42 +0200 Subject: [PATCH] [poincare] Copy static nodes in the pool before add/replaceChild --- poincare/src/tree_by_reference.cpp | 31 ++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/poincare/src/tree_by_reference.cpp b/poincare/src/tree_by_reference.cpp index 8c55266c0..45a3ad043 100644 --- a/poincare/src/tree_by_reference.cpp +++ b/poincare/src/tree_by_reference.cpp @@ -46,6 +46,9 @@ void TreeByReference::replaceWithInPlace(TreeByReference t) { } void TreeByReference::replaceChildInPlace(TreeByReference oldChild, TreeByReference newChild) { + assert(!oldChild.isUninitialized()); + assert(!newChild.isUninitialized()); + if (oldChild == newChild) { return; } @@ -59,6 +62,17 @@ void TreeByReference::replaceChildInPlace(TreeByReference oldChild, TreeByRefere return; } + // If the new node is static, copy it in the pool and add the copy + if (newChild.isStatic()) { + TreeByReference newT = TreeByReference(TreePool::sharedPool()->deepCopy(newChild.node())); + if (newT.isAllocationFailure()) { + replaceWithAllocationFailureInPlace(numberOfChildren()); + return; + } + replaceChildInPlace(oldChild, newT); + return; + } + // Move the new child assert(newChild.parent().isUninitialized()); TreePool::sharedPool()->move(oldChild.node(), newChild.node(), newChild.numberOfChildren()); @@ -166,7 +180,9 @@ void TreeByReference::log() const { // Add void TreeByReference::addChildAtIndexInPlace(TreeByReference t, int index, int currentNumberOfChildren) { assert(!isUninitialized()); - if (node()->isAllocationFailure()) { + assert(!t.isUninitialized()); + + if (isAllocationFailure()) { return; } if (t.isAllocationFailure()) { @@ -174,8 +190,19 @@ void TreeByReference::addChildAtIndexInPlace(TreeByReference t, int index, int c return; } assert(index >= 0 && index <= currentNumberOfChildren); - assert(t.parent().isUninitialized()); + + // If the new node is static, copy it in the pool and add the copy + if (t.isStatic()) { + TreeByReference newT = TreeByReference(TreePool::sharedPool()->deepCopy(t.node())); + if (newT.isAllocationFailure()) { + replaceWithAllocationFailureInPlace(currentNumberOfChildren); + return; + } + addChildAtIndexInPlace(newT, index, currentNumberOfChildren); + return; + } + // Move t TreeNode * newChildPosition = node()->next(); for (int i = 0; i < index; i++) {