summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@complang.org>2013-06-01 15:43:23 +0000
committerAdrian Thurston <thurston@complang.org>2013-06-01 15:43:23 +0000
commit8fcb8e61fb6d89c98cee8ff57bd629cf61587f9b (patch)
treef4356138e2d87d7b8e2895a9e458588dd8517284
parent3f5699f5048ec6d9b42b1dc833b2ab42e23705dd (diff)
downloadcolm-8fcb8e61fb6d89c98cee8ff57bd629cf61587f9b.tar.gz
downref exiting tree when setting a reference val
Downref a tree before replacing it in a reference. Also, don't need to walk the list of references to set all kids to handle refs of refs. Normally these will be split and the chain will be zero length. But even if they weren't, the kid is the same and the tree in it needs to be replaced only once.
-rw-r--r--colm/bytecode.c2
-rw-r--r--colm/tree.c9
-rw-r--r--colm/tree.h2
3 files changed, 5 insertions, 8 deletions
diff --git a/colm/bytecode.c b/colm/bytecode.c
index 955aac1d..a58f395f 100644
--- a/colm/bytecode.c
+++ b/colm/bytecode.c
@@ -1341,7 +1341,7 @@ again:
Tree *val = vm_pop();
Ref *ref = (Ref*) vm_plocal(field);
splitRef( prg, &sp, ref );
- refSetValue( ref, val );
+ refSetValue( prg, sp, ref, val );
break;
}
case IN_GET_FIELD_R: {
diff --git a/colm/tree.c b/colm/tree.c
index c5dc548c..515aadef 100644
--- a/colm/tree.c
+++ b/colm/tree.c
@@ -1216,13 +1216,10 @@ Tree *treeIterDerefCur( TreeIter *iter )
return iter->ref.kid == 0 ? 0 : iter->ref.kid->tree;
}
-void refSetValue( Ref *ref, Tree *v )
+void refSetValue( Program *prg, Tree **sp, Ref *ref, Tree *v )
{
- Kid *firstKid = ref->kid;
- while ( ref != 0 && ref->kid == firstKid ) {
- ref->kid->tree = v;
- ref = ref->next;
- }
+ treeDownref( prg, sp, ref->kid->tree );
+ ref->kid->tree = v;
}
Tree *getRhsEl( Program *prg, Tree *lhs, long position )
diff --git a/colm/tree.h b/colm/tree.h
index 80b980de..91051022 100644
--- a/colm/tree.h
+++ b/colm/tree.h
@@ -273,7 +273,7 @@ void setField( struct colm_program *prg, Tree *tree, long field, Tree *value );
void setTriterCur( struct colm_program *prg, TreeIter *iter, Tree *tree );
void setUiterCur( struct colm_program *prg, UserIter *uiter, Tree *tree );
-void refSetValue( Ref *ref, Tree *v );
+void refSetValue( struct colm_program *prg, Tree **sp, Ref *ref, Tree *v );
Tree *treeSearch( struct colm_program *prg, Tree *tree, long id );
Location *locSearch( struct colm_program *prg, Tree *tree );