Changeset 164 for trunk/thune/context.c

Show
Ignore:
Timestamp:
06/03/06 19:42:11 (3 years ago)
Author:
krobillard
Message:

Thune -

Added ur_setDatatypeBit() and ur_clrDatatypeBit().
Added 'lift-local and _scanControlStack().
'copy now handles context!.
Renamed ur_copy() as ur_clone().
ur_clone() now holds root block when deep copying.
Removed unused context code.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/thune/context.c

    r157 r164  
    217217    return -1; 
    218218} 
    219  
    220  
    221 #if 0 
    222 /** 
    223 */ 
    224 void orMakeContext( OContext* ctx, int size ) 
    225 { 
    226     ctx->wblkN = orBlockN( orMakeBlock( size ) ); 
    227     orRefPush( OT_BLOCK, ctx->wblkN ); 
    228     ctx->vblkN = orBlockN( orMakeBlock( size ) ); 
    229     orRefPop( 1 ); 
    230 } 
    231  
    232  
    233 static void internSetWords( OContext* ctx, UCell* it, UCell* end ) 
    234 { 
    235     int wrdN; 
    236     OBlock* wordBlk = orBlockPtr( ctx->wblkN ); 
    237  
    238     while( it != end ) 
    239     { 
    240         if( it->type == OT_SETWORD ) 
    241         { 
    242             // Word might be redefined mulitple times so we have to 
    243             // orLookup() first. 
    244             wrdN = orLookup( ctx, it->word.atom ); 
    245             if( wrdN < 0 ) 
    246                 wrdN = orInternA( wordBlk, it->word.atom ); 
    247         } 
    248         ++it; 
    249     } 
    250 } 
    251  
    252  
    253 static void unsetValues( UCell* it, UCell* end ) 
    254 { 
    255     while( it != end ) 
    256     { 
    257         orSetTF( it, OT_UNSET ); 
    258         ++it; 
    259     } 
    260 } 
    261  
    262  
    263 /** 
    264   Returns 0 if fails. 
    265 */ 
    266 int orMakeObject( OBlock* pblk, int blkI, OContext* ctx ) 
    267 { 
    268     OBlock* wblk; 
    269     OBlock* vblk; 
    270     UCell* it; 
    271     UCell* end; 
    272     OIndex blkN; 
    273     int wcount; 
    274  
    275  
    276     wcount = 0; 
    277     it  = pblk->values + blkI; 
    278     end = pblk->values + pblk->used; 
    279     while( it != end ) 
    280     { 
    281         // This could be optimized to not count duplicate words. 
    282         if( it->type == OT_SETWORD ) 
    283             ++wcount; 
    284         ++it; 
    285     } 
    286  
    287     blkN = orBlockN( pblk ); 
    288     orRefPush( OT_BLOCK, blkN ); 
    289     orMakeContext( ctx, wcount + 1 ); 
    290  
    291     // re-acquire 
    292     wblk = orBlockPtr( ctx->wblkN ); 
    293     vblk = orBlockPtr( ctx->vblkN ); 
    294     pblk = orBlockPtr( blkN ); 
    295  
    296     // Intern words. 
    297     it = pblk->values + blkI; 
    298     orInternA( wblk, orEnv->atom_self ); 
    299     internSetWords( ctx, it, end ); 
    300  
    301     vblk->used = wblk->used; 
    302     it = vblk->values; 
    303     orSetTF( it, OT_OBJECT ); 
    304     it->ctx = *ctx; 
    305     unsetValues( it + 1, it + vblk->used ); 
    306  
    307     orRefPush( OT_BLOCK, ctx->wblkN ); 
    308     orRefPush( OT_BLOCK, ctx->vblkN ); 
    309  
    310     // Bind prototype block. 
    311     orBind( pblk, ctx ); 
    312  
    313     pblk = orBlockPtr( blkN );  // re-acquire 
    314     orEvalBlock( pblk, blkI ); 
    315  
    316     orRefPop( 3 ); 
    317  
    318     if( orErrorThrown ) 
    319         return 0; 
    320     return 1; 
    321 } 
    322  
    323  
    324 /* 
    325    Similar to deep orCopyBlock() but OT_FUNCTION bodies are also copied. 
    326 */ 
    327 static void copyObjectValues( UCell* copy, UCell* it, int n ) 
    328 { 
    329     UCell* end = it + n; 
    330     while( it != end ) 
    331     { 
    332         orCopyV( copy, *it ); 
    333  
    334         if( (it->type == OT_BLOCK) || (it->type == OT_PAREN) ) 
    335         { 
    336             OBlock* blk = orCopyBlock( it->index, it->series.index, 1 ); 
    337             orSetSeries( copy, orBlockN(blk), 0 );  
    338         } 
    339         else if( it->type == OT_FUNCTION ) 
    340         { 
    341             OBlock* blk = orCopyBlock( it->func.bodyBlk, 0, 1 ); 
    342             copy->func.bodyBlk = orBlockN(blk); 
    343         } 
    344  
    345         ++copy; 
    346         ++it; 
    347     } 
    348 } 
    349  
    350  
    351 /** 
    352   Orig & clone must not point to the same OContext. 
    353 */ 
    354 void orCloneObject( const OContext* orig, OContext* clone ) 
    355 { 
    356     int size; 
    357     OBlock* cblk; 
    358     OBlock* vblk; 
    359     UCell* val; 
    360  
    361  
    362     vblk = orBlockPtr( orig->vblkN ); 
    363     size = vblk->used; 
    364     cblk = orMakeBlock( size ); 
    365     cblk->used = size; 
    366  
    367     clone->wblkN = orig->wblkN; 
    368     clone->vblkN = orBlockN( cblk ); 
    369  
    370     // Point self to the new object. 
    371     assert( cblk->avail ); 
    372     val = cblk->values; 
    373     orSetTF( val, OT_OBJECT ); 
    374     val->ctx = *clone; 
    375  
    376     // Must set cblk->used and clear values in case GC called in 
    377     // copyObjectValues(). 
    378     unsetValues( val + 1, val + size ); 
    379  
    380     orRefPush( OT_BLOCK, clone->vblkN ); 
    381     vblk = orBlockPtr( orig->vblkN );   // re-acquire 
    382     copyObjectValues( cblk->values + 1, vblk->values + 1, size - 1 ); 
    383     orRefPop( 1 ); 
    384  
    385     cblk = orBlockPtr( clone->vblkN );  // re-acquire 
    386     orBind( cblk, clone ); 
    387 } 
    388  
    389  
    390 /** 
    391   Clones the orig context if no new members are added in the block. 
    392   Returns new context number or -1 if fails. 
    393 */ 
    394 int orMakeClone( const OContext* orig, OContext* clone, 
    395                  OIndex blkN, OIndex blkI ) 
    396 { 
    397     OBlock* pblk; 
    398     OBlock* vblk; 
    399     OBlock* cblk; 
    400     UCell* it; 
    401     UCell* end; 
    402     int wcount; 
    403     int origUsed; 
    404  
    405  
    406     orRefPush( OT_BLOCK, blkN ); 
    407  
    408     vblk = orBlockPtr( orig->vblkN ); 
    409     wcount = origUsed = vblk->used; 
    410  
    411     pblk = orBlockPtr( blkN ); 
    412     it  = pblk->values + blkI; 
    413     end = pblk->values + pblk->used; 
    414     while( it != end ) 
    415     { 
    416         if( it->type == OT_SETWORD ) 
    417         { 
    418             if( orLookup( orig, it->word.atom ) < 0 ) 
    419                 ++wcount; 
    420         } 
    421         ++it; 
    422     } 
    423  
    424     if( wcount == origUsed ) 
    425     { 
    426         orCloneObject( orig, clone ); 
    427     } 
    428     else 
    429     { 
    430         orMakeContext( clone, wcount ); 
    431  
    432         // Re-acquire. 
    433         pblk = orBlockPtr( blkN ); 
    434         cblk = orBlockPtr( clone->wblkN ); 
    435         vblk = orBlockPtr( orig->wblkN ); 
    436  
    437         assert( cblk->avail ); 
    438         memCpy( cblk->values, vblk->values, sizeof(UCell) * origUsed ); 
    439         cblk->used = origUsed; 
    440         internSetWords( clone, pblk->values + blkI, end ); 
    441         wcount = cblk->used; 
    442  
    443  
    444         vblk = orBlockPtr( orig->vblkN ); 
    445         cblk = orBlockPtr( clone->vblkN ); 
    446         cblk->used = wcount; 
    447  
    448         // Point self to the new object. 
    449         it = cblk->values; 
    450         orSetTF( it, OT_OBJECT ); 
    451         it->ctx = *clone; 
    452  
    453         unsetValues( it + 1, it + wcount ); 
    454  
    455         orRefPush( OT_BLOCK, clone->wblkN ); 
    456         orRefPush( OT_BLOCK, clone->vblkN ); 
    457         copyObjectValues( it + 1, vblk->values + 1, origUsed - 1 ); 
    458         orRefPop( 2 ); 
    459     } 
    460  
    461     orBind( orBlockPtr( blkN ), clone ); 
    462  
    463     orRefPop( 1 ); 
    464  
    465     orRefPush( OT_BLOCK, clone->wblkN ); 
    466     orRefPush( OT_BLOCK, clone->vblkN ); 
    467     orEvalBlock( orBlockPtr( blkN ), blkI ); 
    468     orRefPop( 2 ); 
    469  
    470     if( orErrorThrown ) 
    471         return 0; 
    472  
    473     return 1; 
    474 } 
    475 #endif 
    476219 
    477220