summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bytecode.c34
-rw-r--r--src/iter.c14
-rw-r--r--src/parsetree.h5
-rw-r--r--src/synthesis.cc45
-rw-r--r--src/tree.h6
5 files changed, 71 insertions, 33 deletions
diff --git a/src/bytecode.c b/src/bytecode.c
index 3e66869d..735ff0e2 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -371,7 +371,8 @@ static void downrefLocalTrees( Program *prg, Tree **sp,
long i;
for ( i = localsLen-1; i >= 0; i-- ) {
if ( locals[i].type == LI_Tree ) {
- debug( prg, REALM_BYTECODE, "local tree downref: %ld\n", (long)locals[i].offset );
+ debug( prg, REALM_BYTECODE, "local tree downref: %ld\n",
+ (long)locals[i].offset );
Tree *tree = (Tree*) frame[(long)locals[i].offset];
treeDownref( prg, sp, tree );
@@ -386,25 +387,29 @@ static void downrefLocals( Program *prg, Tree ***psp,
for ( i = localsLen-1; i >= 0; i-- ) {
switch ( locals[i].type ) {
case LI_Tree: {
- debug( prg, REALM_BYTECODE, "local tree downref: %ld\n", (long)locals[i].offset );
+ debug( prg, REALM_BYTECODE, "local tree downref: %ld\n",
+ (long)locals[i].offset );
Tree *tree = (Tree*) frame[(long)locals[i].offset];
treeDownref( prg, *psp, tree );
break;
}
case LI_Iter: {
- debug( prg, REALM_BYTECODE, "local iter downref: %ld\n", (long)locals[i].offset );
+ debug( prg, REALM_BYTECODE, "local iter downref: %ld\n",
+ (long)locals[i].offset );
TreeIter *iter = (TreeIter*) &frame[(long)locals[i].offset];
treeIterDestroy( prg, psp, iter );
break;
}
case LI_RevIter: {
- debug( prg, REALM_BYTECODE, "local rev iter downref: %ld\n", (long)locals[i].offset );
+ debug( prg, REALM_BYTECODE, "local rev iter downref: %ld\n",
+ (long)locals[i].offset );
RevTreeIter *riter = (RevTreeIter*) &frame[(long)locals[i].offset];
revTreeIterDestroy( prg, psp, riter );
break;
}
case LI_UserIter: {
- debug( prg, REALM_BYTECODE, "local user iter downref: %ld\n", (long)locals[i].offset );
+ debug( prg, REALM_BYTECODE, "local user iter downref: %ld\n",
+ (long)locals[i].offset );
UserIter *uiter = (UserIter*) frame[locals[i].offset];
userIterDestroy2( prg, psp, uiter );
break;
@@ -1899,11 +1904,14 @@ again:
}
case IN_TRITER_FROM_REF: {
short field;
+ Half argSize;
Half searchTypeId;
read_half( field );
+ read_half( argSize );
read_half( searchTypeId );
- debug( prg, REALM_BYTECODE, "IN_TRITER_FROM_REF\n" );
+ debug( prg, REALM_BYTECODE, "IN_TRITER_FROM_REF "
+ "%hd %hd %hd\n", field, argSize, searchTypeId );
Ref rootRef;
rootRef.kid = (Kid*)vm_pop();
@@ -1913,26 +1921,29 @@ again:
Tree **stackRoot = vm_ptop();
long rootSize = vm_ssize();
- initTreeIter( (TreeIter*)mem, stackRoot, rootSize, &rootRef, searchTypeId );
+ initTreeIter( (TreeIter*)mem, stackRoot,
+ argSize, rootSize, &rootRef, searchTypeId );
break;
}
case IN_TRITER_DESTROY: {
short field;
read_half( field );
- debug( prg, REALM_BYTECODE, "IN_TRITER_DESTROY\n" );
-
TreeIter *iter = (TreeIter*) vm_plocal(field);
+ debug( prg, REALM_BYTECODE, "IN_TRITER_DESTROY %d\n", iter->yieldSize );
treeIterDestroy( prg, &sp, iter );
break;
}
case IN_REV_TRITER_FROM_REF: {
short field;
+ Half argSize;
Half searchTypeId;
read_half( field );
+ read_half( argSize );
read_half( searchTypeId );
- debug( prg, REALM_BYTECODE, "IN_REV_TRITER_FROM_REF\n" );
+ debug( prg, REALM_BYTECODE, "IN_REV_TRITER_FROM_REF "
+ "%hd %hd %hd\n", field, argSize, searchTypeId );
Ref rootRef;
rootRef.kid = (Kid*)vm_pop();
@@ -1950,7 +1961,8 @@ again:
}
void *mem = vm_plocal(field);
- initRevTreeIter( (RevTreeIter*)mem, stackRoot, rootSize, &rootRef, searchTypeId, children );
+ initRevTreeIter( (RevTreeIter*)mem, stackRoot,
+ argSize, rootSize, &rootRef, searchTypeId, children );
break;
}
case IN_REV_TRITER_DESTROY: {
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;
}
diff --git a/src/parsetree.h b/src/parsetree.h
index c62a9ff5..f32c0d09 100644
--- a/src/parsetree.h
+++ b/src/parsetree.h
@@ -2565,7 +2565,7 @@ struct LangVarRef
void assignValue( Compiler *pd, CodeVect &code, UniqueType *exprUT ) const;
ObjectField **evaluateArgs( Compiler *pd, CodeVect &code,
- VarRefLookup &lookup, CallArgVect *args ) const;
+ VarRefLookup &lookup, CallArgVect *args );
void callOperation( Compiler *pd, CodeVect &code, VarRefLookup &lookup ) const;
UniqueType *evaluateCall( Compiler *pd, CodeVect &code, CallArgVect *args );
UniqueType *evaluate( Compiler *pd, CodeVect &code, bool forWriting = false ) const;
@@ -2574,13 +2574,14 @@ struct LangVarRef
void resetActiveRefs( Compiler *pd, VarRefLookup &lookup, ObjectField **paramRefs ) const;
long loadQualificationRefs( Compiler *pd, CodeVect &code, ObjNameScope *rootScope ) const;
void popRefQuals( Compiler *pd, CodeVect &code,
- VarRefLookup &lookup, CallArgVect *args ) const;
+ VarRefLookup &lookup, CallArgVect *args, bool temps ) const;
InputLoc loc;
Context *context;
ObjNameScope *scope;
QualItemVect *qual;
String name;
+ long argSize;
};
struct LangTerm
diff --git a/src/synthesis.cc b/src/synthesis.cc
index 79e04cee..561f87b8 100644
--- a/src/synthesis.cc
+++ b/src/synthesis.cc
@@ -609,7 +609,8 @@ bool LangVarRef::canTakeRefTest( Compiler *pd, VarRefLookup &lookup ) const
* via a local and attributes. */
if ( lookup.inObject->type == ObjectDef::FrameType )
canTake = true;
- else if ( isLocalRef() && lookup.lastPtrInQual < 0 && lookup.uniqueType->typeId != TYPE_PTR )
+ else if ( isLocalRef() && lookup.lastPtrInQual < 0 &&
+ lookup.uniqueType->typeId != TYPE_PTR )
canTake = true;
return canTake;
@@ -637,6 +638,7 @@ bool LangExpr::canTakeRefTest( Compiler *pd ) const
if ( term->varRef->canTakeRefTest( pd, lookup ) )
canTake = true;
}
+
return canTake;
}
@@ -707,7 +709,7 @@ ObjectField *LangVarRef::evaluateRef( Compiler *pd, CodeVect &code, long pushCou
ObjectField **LangVarRef::evaluateArgs( Compiler *pd, CodeVect &code,
- VarRefLookup &lookup, CallArgVect *args ) const
+ VarRefLookup &lookup, CallArgVect *args )
{
/* Parameter list is given only for user defined methods. Otherwise it
* will be null. */
@@ -727,6 +729,7 @@ ObjectField **LangVarRef::evaluateArgs( Compiler *pd, CodeVect &code,
/* We use this only if there is a paramter list. */
ParameterList::Iter p;
long size = 0;
+ long tempPops = 0;
/* First pass we need to allocate and evaluate temporaries. */
paramList != 0 && ( p = *paramList );
@@ -744,6 +747,7 @@ ObjectField **LangVarRef::evaluateArgs( Compiler *pd, CodeVect &code,
size += 1;
(*pe)->offTmp = size;
+ tempPops += 1;
}
}
@@ -786,7 +790,8 @@ ObjectField **LangVarRef::evaluateArgs( Compiler *pd, CodeVect &code,
/* Lookup the field. */
LangVarRef *varRef = expression->term->varRef;
- ObjectField *refOf = varRef->evaluateRef( pd, code, (size - (*pe)->offQualRef) );
+ ObjectField *refOf = varRef->evaluateRef( pd, code,
+ (size - (*pe)->offQualRef) );
paramRefs[pe.pos()] = refOf;
size += 2;
@@ -810,6 +815,8 @@ ObjectField **LangVarRef::evaluateArgs( Compiler *pd, CodeVect &code,
/* Advance the parameter list iterator if we have it. */
paramList != 0 && p.increment();
}
+
+ argSize = tempPops;
}
return paramRefs;
@@ -871,7 +878,7 @@ void LangVarRef::callOperation( Compiler *pd, CodeVect &code, VarRefLookup &look
}
void LangVarRef::popRefQuals( Compiler *pd, CodeVect &code,
- VarRefLookup &lookup, CallArgVect *args ) const
+ VarRefLookup &lookup, CallArgVect *args, bool temps ) const
{
long popCount = 0;
@@ -895,17 +902,18 @@ void LangVarRef::popRefQuals( Compiler *pd, CodeVect &code,
code.appendHalf( (short)popCount );
}
- for ( CallArgVect::Iter pe = *args; pe.lte(); pe++ ) {
- /* Get the expression and the UT for the arg. */
- LangExpr *expression = (*pe)->expr;
- UniqueType *paramUT = lookup.objMethod->paramUTs[pe.pos()];
+ if ( temps ) {
+ for ( CallArgVect::Iter pe = *args; pe.lte(); pe++ ) {
+ /* Get the expression and the UT for the arg. */
+ LangExpr *expression = (*pe)->expr;
+ UniqueType *paramUT = lookup.objMethod->paramUTs[pe.pos()];
- if ( paramUT->typeId == TYPE_REF ) {
- if ( ! expression->canTakeRefTest( pd ) )
- code.append( IN_POP );
+ if ( paramUT->typeId == TYPE_REF ) {
+ if ( ! expression->canTakeRefTest( pd ) )
+ code.append( IN_POP );
+ }
}
}
-
}
}
@@ -965,7 +973,7 @@ UniqueType *LangVarRef::evaluateCall( Compiler *pd, CodeVect &code, CallArgVect
/* Write the call opcode. */
callOperation( pd, code, lookup );
- popRefQuals( pd, code, lookup, args );
+ popRefQuals( pd, code, lookup, args, true );
resetActiveRefs( pd, lookup, paramRefs);
delete[] paramRefs;
@@ -2074,9 +2082,14 @@ void LangStmt::compileForIter( Compiler *pd, CodeVect &code ) const
code.append( iterUT->iterDef->inCreateWC );
code.appendHalf( objField->offset );
+
+ /* Arg size (or func id for user iters). */
if ( lookup.objMethod->func != 0 )
code.appendHalf( lookup.objMethod->func->funcId );
+ else
+ code.appendHalf( iterCall->langTerm->varRef->argSize );
+ /* Search type. */
if ( iterUT->iterDef->useSearchUT ) {
if ( searchUT->typeId == TYPE_PTR )
code.appendHalf( pd->uniqueTypePtr->langEl->id );
@@ -2086,8 +2099,8 @@ void LangStmt::compileForIter( Compiler *pd, CodeVect &code ) const
compileForIterBody( pd, code, iterUT );
-
- iterCall->langTerm->varRef->popRefQuals( pd, code, lookup, iterCall->langTerm->args );
+ iterCall->langTerm->varRef->popRefQuals( pd, code, lookup,
+ iterCall->langTerm->args, false );
iterCall->langTerm->varRef->resetActiveRefs( pd, lookup, paramRefs );
delete[] paramRefs;
@@ -2262,7 +2275,7 @@ void LangStmt::compile( Compiler *pd, CodeVect &code ) const
if ( pd->loopCleanup != 0 )
code.append( *pd->loopCleanup );
- /* Jump to the return label. The distnacnce will be filled in
+ /* Jump to the return label. The distance will be filled in
* later. */
pd->returnJumps.append( code.length() );
code.append( IN_JMP );
diff --git a/src/tree.h b/src/tree.h
index 5f8cb568..76f6d34b 100644
--- a/src/tree.h
+++ b/src/tree.h
@@ -187,6 +187,7 @@ typedef struct _TreeIter
Ref ref;
long searchId;
Tree **stackRoot;
+ long argSize;
long yieldSize;
long rootSize;
} TreeIter;
@@ -199,6 +200,7 @@ typedef struct _RevTreeIter
Ref ref;
long searchId;
Tree **stackRoot;
+ long argSize;
long yieldSize;
long rootSize;
@@ -336,9 +338,9 @@ UserIter *uiterCreate( struct colm_program *prg, Tree ***psp,
void uiterInit( struct colm_program *prg, Tree **sp, UserIter *uiter,
struct _FunctionInfo *fi, int revertOn );
-void initTreeIter( TreeIter *treeIter, Tree **stackRoot, long rootSize,
+void initTreeIter( TreeIter *treeIter, Tree **stackRoot, long argSize, long rootSize,
const Ref *rootRef, int searchId );
-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 );
void initUserIter( UserIter *userIter, Tree **stackRoot, long rootSize,
long argSize, long searchId );