diff --git a/src/Amalgam/evaluablenode/EvaluableNodeManagement.h b/src/Amalgam/evaluablenode/EvaluableNodeManagement.h index 34568454..ec8fca61 100644 --- a/src/Amalgam/evaluablenode/EvaluableNodeManagement.h +++ b/src/Amalgam/evaluablenode/EvaluableNodeManagement.h @@ -394,27 +394,24 @@ class EvaluableNodeManager //if candidate is not unique, then it allocates and returns a new node inline EvaluableNodeReference ReuseOrAllocNode(EvaluableNodeReference candidate, EvaluableNodeType type) { - if(candidate.unique && candidate != nullptr) + //if not cyclic, can attempt to free all child nodes + //if cyclic, don't try, in case a child node points back to candidate + if(candidate.unique && candidate != nullptr && !candidate->GetNeedCycleCheck()) { - //if not cyclic, can attempt to free all child nodes - //if cyclic, don't try, in case a child node points back to candidate - if(!candidate->GetNeedCycleCheck()) + if(candidate->IsAssociativeArray()) { - if(candidate->IsAssociativeArray()) + for(auto &[_, e] : candidate->GetMappedChildNodesReference()) { - for(auto &[_, e] : candidate->GetMappedChildNodesReference()) - { - if(e != nullptr) - FreeNodeTreeRecurse(e); - } + if(e != nullptr) + FreeNodeTreeRecurse(e); } - else if(!candidate->IsImmediate()) + } + else if(!candidate->IsImmediate()) + { + for(auto &e : candidate->GetOrderedChildNodesReference()) { - for(auto &e : candidate->GetOrderedChildNodesReference()) - { - if(e != nullptr) - FreeNodeTreeRecurse(e); - } + if(e != nullptr) + FreeNodeTreeRecurse(e); } } @@ -625,7 +622,7 @@ class EvaluableNodeManager //attempts to free the node reference __forceinline void FreeNodeIfPossible(EvaluableNodeReference &enr) { - if(enr.unique && !enr.IsImmediateValue()) + if(enr.unique && !enr.IsImmediateValue() && !enr->GetNeedCycleCheck()) FreeNode(enr); } diff --git a/src/Amalgam/interpreter/InterpreterOpcodesCodeMixing.cpp b/src/Amalgam/interpreter/InterpreterOpcodesCodeMixing.cpp index 60a1b57f..e60f6edc 100644 --- a/src/Amalgam/interpreter/InterpreterOpcodesCodeMixing.cpp +++ b/src/Amalgam/interpreter/InterpreterOpcodesCodeMixing.cpp @@ -156,11 +156,13 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_INTERSECT(EvaluableNode *e auto node_stack = CreateInterpreterNodeStackStateSaver(n1); auto n2 = InterpretNodeForImmediateUse(ocn[1]); - node_stack.PushEvaluableNode(n2); EvaluableNode *result = EvaluableNodeTreeManipulation::IntersectTrees(evaluableNodeManager, n1, n2); - EvaluableNodeManager::UpdateFlagsForNodeTree(result); + + evaluableNodeManager->FreeNodeTreeIfPossible(n1); + evaluableNodeManager->FreeNodeTreeIfPossible(n2); + return EvaluableNodeReference(result, true); } @@ -175,11 +177,13 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_UNION(EvaluableNode *en, b auto node_stack = CreateInterpreterNodeStackStateSaver(n1); auto n2 = InterpretNodeForImmediateUse(ocn[1]); - node_stack.PushEvaluableNode(n2); EvaluableNode *result = EvaluableNodeTreeManipulation::UnionTrees(evaluableNodeManager, n1, n2); - EvaluableNodeManager::UpdateFlagsForNodeTree(result); + + evaluableNodeManager->FreeNodeTreeIfPossible(n1); + evaluableNodeManager->FreeNodeTreeIfPossible(n2); + return EvaluableNodeReference(result, true); } @@ -197,8 +201,8 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_DIFFERENCE(EvaluableNode * node_stack.PushEvaluableNode(n2); EvaluableNode *result = EvaluableNodeTreeDifference::DifferenceTrees(evaluableNodeManager, n1, n2); - EvaluableNodeManager::UpdateFlagsForNodeTree(result); + return EvaluableNodeReference(result, (n1.unique && n2.unique)); } @@ -248,12 +252,14 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_MIX(EvaluableNode *en, boo auto node_stack = CreateInterpreterNodeStackStateSaver(n1); auto n2 = InterpretNodeForImmediateUse(ocn[1]); - node_stack.PushEvaluableNode(n2); EvaluableNode *result = EvaluableNodeTreeManipulation::MixTrees(randomStream.CreateOtherStreamViaRand(), evaluableNodeManager, n1, n2, blend1, blend2, similar_mix_chance); - EvaluableNodeManager::UpdateFlagsForNodeTree(result); + + evaluableNodeManager->FreeNodeTreeIfPossible(n1); + evaluableNodeManager->FreeNodeTreeIfPossible(n2); + return EvaluableNodeReference(result, true); } @@ -298,8 +304,8 @@ EvaluableNodeReference Interpreter::InterpretNode_ENT_MIX_LABELS(EvaluableNode * node_stack.PushEvaluableNode(n2); EvaluableNode *result = EvaluableNodeTreeManipulation::MixTreesByCommonLabels(this, evaluableNodeManager, n1, n2, randomStream, blend1, blend2); - EvaluableNodeManager::UpdateFlagsForNodeTree(result); + return EvaluableNodeReference(result, (n1.unique && n2.unique)); }