diff options
-rw-r--r-- | colm/bytecode.h | 17 | ||||
-rw-r--r-- | colm/program.c | 39 |
2 files changed, 36 insertions, 20 deletions
diff --git a/colm/bytecode.h b/colm/bytecode.h index d07dfb2e..f3661230 100644 --- a/colm/bytecode.h +++ b/colm/bytecode.h @@ -414,13 +414,14 @@ typedef unsigned char uchar; #define IFR_RFR 0 /* return frame pointer */ /* Exported to modules other than bytecode.c */ -#define vm_push(i) ( ( sp == prg->sb_beg ? (sp = vm_grow(prg, sp, 1)) : 0 ), (*(--sp) = (i)) ) -#define vm_pop() ({ SW r = *sp++; if ( sp == prg->sb_end ) { sp = vm_shrink(prg); }; r; }) -#define vm_pop_ignore() ({ sp++; if ( sp == prg->sb_end ) { sp = vm_shrink(prg); }; }) -#define vm_pushn(n) ( ( (sp-(n)) < prg->sb_beg ? (sp = vm_grow(prg, sp, n)) : 0 ),(sp -= (n)) ) -#define vm_popn(n) ( ( (sp+(n)) > prg->sb_end ? (sp = vm_shrink(prg)) : 0 ), (sp += (n)) ) +#define vm_push(i) ( ( sp == prg->sb_beg ? (sp = vm_bs_add(prg, sp, 1)) : 0 ), (*(--sp) = (i)) ) +#define vm_pushn(n) ( ( (sp-(n)) < prg->sb_beg ? (sp = vm_bs_add(prg, sp, n)) : 0 ), (sp -= (n)) ) -#define vm_contiguous(n) ( ( (sp-(n)) < prg->sb_beg ? (sp = vm_grow(prg, sp, n)) : 0 ) ) +#define vm_pop() ({ SW r = *sp; (sp+1) >= prg->sb_end ? (sp = vm_bs_pop(prg, sp, 1)) : (sp += 1); r; }) +#define vm_pop_ignore() ({ (sp+1) >= prg->sb_end ? (sp = vm_bs_pop(prg, sp, 1)) : (sp += 1); }) +#define vm_popn(n) ({ (sp+(n)) >= prg->sb_end ? (sp = vm_bs_pop(prg, sp, n)) : (sp += (n)); }) + +#define vm_contiguous(n) ( ( (sp-(n)) < prg->sb_beg ? (sp = vm_bs_add(prg, sp, n)) : 0 ) ) #define vm_top() (*sp) #define vm_ptop() (sp) @@ -433,8 +434,8 @@ typedef unsigned char uchar; #define vm_plocal_iframe(o) (&exec->iframePtr[o]) void vm_init( struct ColmProgram * ); -Tree** vm_grow( struct ColmProgram *, Tree **, int ); -Tree** vm_shrink( struct ColmProgram * ); +Tree** vm_bs_add( struct ColmProgram *, Tree **, int ); +Tree** vm_bs_pop( struct ColmProgram *, Tree **, int ); void vm_clear( struct ColmProgram * ); typedef Tree *SW; diff --git a/colm/program.c b/colm/program.c index ed983c46..5e1a6a9a 100644 --- a/colm/program.c +++ b/colm/program.c @@ -92,7 +92,7 @@ void vm_init( Program *prg ) prg->stackRoot = prg->sb_end; } -Tree **vm_grow( Program *prg, Tree **sp, int n ) +Tree **vm_bs_add( Program *prg, Tree **sp, int n ) { /* Close off the current block. */ if ( prg->stackBlock != 0 ) { @@ -127,32 +127,47 @@ Tree **vm_grow( Program *prg, Tree **sp, int n ) return prg->sb_end; } -Tree **vm_shrink( Program *prg ) +Tree **vm_bs_pop( Program *prg, Tree **sp, int n ) { - if ( prg->stackBlock->next == 0 ) { - /* Don't delete the sentinal stack block. Returns the end as in the - * creation of the first stack block. */ - return prg->sb_end; - } - else { + while ( 1 ) { + Tree **end = prg->stackBlock->data + prg->stackBlock->len; + int remaining = end - sp; + + /* Don't have to free this block. Remaining values to pop leave us + * inside it. */ + if ( n < remaining ) { + sp += n; + return sp; + } + + if ( prg->stackBlock->next == 0 ) { + /* Don't delete the sentinal stack block. Returns the end as in the + * creation of the first stack block. */ + return prg->sb_end; + } + + /* Clear any previous reserve. We are going to save this block as the + * reserve. */ if ( prg->reserve != 0 ) { free( prg->reserve->data ); free( prg->reserve ); } + /* Pop the stack block. */ StackBlock *b = prg->stackBlock; prg->stackBlock = prg->stackBlock->next; - prg->reserve = b; - /* FIXME: need to use offset here? Maybe we can grant more space in - * case any push that follows has fewer requirements. */ + /* Setup the bounds. Need to use offset here? Maybe we can grant more + * space in case any push that follows has fewer requirements. */ prg->sb_beg = prg->stackBlock->data + prg->stackBlock->offset; prg->sb_end = prg->stackBlock->data + prg->stackBlock->len; + /* Update the total stack usage. */ prg->sb_total -= prg->stackBlock->len - prg->stackBlock->offset; - return prg->sb_beg; + n -= remaining; + sp = prg->sb_beg; } } |