From 8795ba68cd238f4e9a9b80e36788ede597669895 Mon Sep 17 00:00:00 2001 From: Adrian Thurston Date: Wed, 5 Nov 2014 20:58:59 -0500 Subject: allow breaking from for loops where args are non-references The triter destroy will now pop temps created for iterator args that can't be referenced. They are tracked in the compile, specified in the create, and used in the destroy. --- src/iter.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'src/iter.c') diff --git a/src/iter.c b/src/iter.c index 8022d1ff..aded50ad 100644 --- a/src/iter.c +++ b/src/iter.c @@ -10,7 +10,8 @@ #define true 1 #define false 0 -void initTreeIter( TreeIter *treeIter, Tree **stackRoot, long rootSize, +void initTreeIter( TreeIter *treeIter, Tree **stackRoot, + long argSize, long rootSize, const Ref *rootRef, int searchId ) { treeIter->type = IT_Tree; @@ -21,9 +22,11 @@ void initTreeIter( TreeIter *treeIter, Tree **stackRoot, long rootSize, treeIter->rootSize = rootSize; treeIter->ref.kid = 0; treeIter->ref.next = 0; + treeIter->argSize = argSize; } -void initRevTreeIter( RevTreeIter *revTriter, Tree **stackRoot, long rootSize, +void initRevTreeIter( RevTreeIter *revTriter, Tree **stackRoot, + long argSize, long rootSize, const Ref *rootRef, int searchId, int children ) { revTriter->type = IT_RevTree; @@ -36,6 +39,7 @@ void initRevTreeIter( RevTreeIter *revTriter, Tree **stackRoot, long rootSize, revTriter->children = children; revTriter->ref.kid = 0; revTriter->ref.next = 0; + revTriter->argSize = argSize; } void initUserIter( UserIter *userIter, Tree **stackRoot, long rootSize, @@ -90,10 +94,13 @@ void uiterInit( Program *prg, Tree **sp, UserIter *uiter, void treeIterDestroy( Program *prg, Tree ***psp, TreeIter *iter ) { if ( (int)iter->type != 0 ) { + int i; Tree **sp = *psp; long curStackSize = vm_ssize() - iter->rootSize; assert( iter->yieldSize == curStackSize ); vm_popn( iter->yieldSize ); + for ( i = 0; i < iter->argSize; i++ ) + treeDownref( prg, sp, vm_pop() ); iter->type = 0; *psp = sp; } @@ -102,10 +109,13 @@ void treeIterDestroy( Program *prg, Tree ***psp, TreeIter *iter ) void revTreeIterDestroy( struct colm_program *prg, Tree ***psp, RevTreeIter *riter ) { if ( (int)riter->type != 0 ) { + int i; Tree **sp = *psp; long curStackSize = vm_ssize() - riter->rootSize; assert( riter->yieldSize == curStackSize ); vm_popn( riter->yieldSize ); + for ( i = 0; i < riter->argSize; i++ ) + treeDownref( prg, sp, vm_pop() ); riter->type = 0; *psp = sp; } -- cgit v1.2.1