summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@complang.org>2014-01-21 21:28:27 -0500
committerAdrian Thurston <thurston@complang.org>2014-01-21 21:28:27 -0500
commitfee5f32f5818a2fd075aa6035de2fa980d2b8a58 (patch)
tree3bd3d66fb840361879f5ff20d2404627780341cd
parent9ea5133db407277e819a097727c676ef77c5c558 (diff)
downloadcolm-fee5f32f5818a2fd075aa6035de2fa980d2b8a58.tar.gz
the contiguous instruction also pushes a null value
An initial push prevents a push-pop-push from clearing the contiguous block. This can happen easily when evaluating args (quals, expresssions, etc).
-rw-r--r--src/bytecode.c2
-rw-r--r--src/iter.c1
-rw-r--r--src/parsedata.h1
-rw-r--r--src/synthesis.cc24
4 files changed, 25 insertions, 3 deletions
diff --git a/src/bytecode.c b/src/bytecode.c
index 1065d923..d69cf902 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -3343,6 +3343,7 @@ again:
read_half( size );
debug( prg, REALM_BYTECODE, "IN_CONTIGUOUS %hd\n", size );
vm_contiguous( size );
+ vm_push( 0 );
break;
}
case IN_INIT_LOCALS: {
@@ -3644,6 +3645,7 @@ again:
instr = (Code*) vm_pop();
Tree *retVal = vm_pop();
vm_popn( fi->argSize );
+ vm_pop();
treeDownref( prg, sp, retVal );
}
diff --git a/src/iter.c b/src/iter.c
index 3d38fa3a..9e60a2df 100644
--- a/src/iter.c
+++ b/src/iter.c
@@ -165,6 +165,7 @@ void userIterDestroy2( Program *prg, Tree ***psp, UserIter *uiter )
vm_popn( uiter->yieldSize );
vm_popn( sizeof(UserIter) / sizeof(Word) );
vm_popn( argSize );
+ vm_pop();
uiter->type = 0;
diff --git a/src/parsedata.h b/src/parsedata.h
index 85b70b8c..f9f7df2e 100644
--- a/src/parsedata.h
+++ b/src/parsedata.h
@@ -979,6 +979,7 @@ struct Compiler
bool beginContiguous( CodeVect &code, int stretch );
void endContiguous( CodeVect &code, bool resetContiguous );
+ void clearContiguous( CodeVect &code, bool resetContiguous );
void declareReVars();
};
diff --git a/src/synthesis.cc b/src/synthesis.cc
index 4286320b..ac77b4b0 100644
--- a/src/synthesis.cc
+++ b/src/synthesis.cc
@@ -899,7 +899,9 @@ bool Compiler::beginContiguous( CodeVect &code, int stretch )
if ( inContiguous )
contiguousStretch += stretch;
else {
- contiguousStretch = stretch;
+ /* We add one for the push that always comes with the contiguous
+ * statement. */
+ contiguousStretch = stretch + 1;
code.append( IN_CONTIGUOUS );
contiguousOffset = code.length();
@@ -920,6 +922,14 @@ void Compiler::endContiguous( CodeVect &code, bool resetContiguous )
}
}
+void Compiler::clearContiguous( CodeVect &code, bool resetContiguous )
+{
+ if ( resetContiguous ) {
+ code.append( IN_TOP_SWAP );
+ code.append( IN_POP );
+ }
+}
+
UniqueType *LangVarRef::evaluateCall( Compiler *pd, CodeVect &code, CallArgVect *args )
{
/* Evaluate the object. */
@@ -944,6 +954,7 @@ UniqueType *LangVarRef::evaluateCall( Compiler *pd, CodeVect &code, CallArgVect
delete[] paramRefs;
pd->endContiguous( code, resetContiguous );
+ pd->clearContiguous( code, resetContiguous );
/* Return the type to the expression. */
return lookup.uniqueType;
@@ -1354,6 +1365,7 @@ void LangTerm::evaluateSendStream( Compiler *pd, CodeVect &code ) const
* leave the varref on the stack. */
pd->endContiguous( code, resetContiguous );
+ pd->clearContiguous( code, resetContiguous );
}
void LangTerm::evaluateSendParser( Compiler *pd, CodeVect &code ) const
@@ -1873,6 +1885,7 @@ UniqueType *LangTerm::evaluateMakeToken( Compiler *pd, CodeVect &code ) const
code.append( args->length() );
pd->endContiguous( code, resetContiguous );
+ pd->clearContiguous( code, resetContiguous );
return pd->uniqueTypeAny;
}
@@ -1903,6 +1916,7 @@ UniqueType *LangTerm::evaluateMakeTree( Compiler *pd, CodeVect &code ) const
code.append( args->length() );
pd->endContiguous( code, resetContiguous );
+ pd->clearContiguous( code, resetContiguous );
return pd->uniqueTypeAny;
}
@@ -2002,6 +2016,8 @@ void LangStmt::compileForIter( Compiler *pd, CodeVect &code ) const
ObjectField **paramRefs = iterCall->langTerm->varRef->evaluateArgs(
pd, code, lookup, iterCall->langTerm->args );
+ pd->endContiguous( code, resetContiguous );
+
if ( pd->revertOn )
code.append( iterUT->iterDef->inCreateWV );
else
@@ -2018,14 +2034,16 @@ void LangStmt::compileForIter( Compiler *pd, CodeVect &code ) const
code.appendHalf( searchUT->langEl->id );
}
- pd->endContiguous( code, resetContiguous );
-
compileForIterBody( pd, code, iterUT );
+
iterCall->langTerm->varRef->popRefQuals( pd, code, lookup, iterCall->langTerm->args );
iterCall->langTerm->varRef->resetActiveRefs( pd, lookup, paramRefs );
delete[] paramRefs;
+
+ if ( resetContiguous )
+ code.append( IN_POP );
}
void LangStmt::compileWhile( Compiler *pd, CodeVect &code ) const