diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bytecode.c | 34 | ||||
-rw-r--r-- | src/iter.c | 14 | ||||
-rw-r--r-- | src/parsetree.h | 5 | ||||
-rw-r--r-- | src/synthesis.cc | 45 | ||||
-rw-r--r-- | src/tree.h | 6 |
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: { @@ -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 ); @@ -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 ); |