/ Check-in [8273c74b]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Rework internal data structures to make the VDBE about 15% smaller. (CVS 1203)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:8273c74bd09d1a044cb5154498b0a39939f6e3ed
User & Date: drh 2004-01-31 19:22:56
Context
2004-01-31
20:20
A few more optimizations to the VDBE. (CVS 1204) check-in: 06e7ff4c user: drh tags: trunk
19:22
Rework internal data structures to make the VDBE about 15% smaller. (CVS 1203) check-in: 8273c74b user: drh tags: trunk
2004-01-30
14:49
Rework the VDBE data structures to combine string representations into the same structure with integer and floating point. This opens the door to significant optimizations. (CVS 1202) check-in: c0faa1c6 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbe.c.

    39     39   **
    40     40   ** Various scripts scan this source file in order to generate HTML
    41     41   ** documentation, headers files, or other derived files.  The formatting
    42     42   ** of the code in this file is, therefore, important.  See other comments
    43     43   ** in this file for details.  If in doubt, do not deviate from existing
    44     44   ** commenting and indentation practices when changing or adding code.
    45     45   **
    46         -** $Id: vdbe.c,v 1.252 2004/01/30 14:49:17 drh Exp $
           46  +** $Id: vdbe.c,v 1.253 2004/01/31 19:22:56 drh Exp $
    47     47   */
    48     48   #include "sqliteInt.h"
    49     49   #include "os.h"
    50     50   #include <ctype.h>
    51     51   #include "vdbeInt.h"
    52     52   
    53     53   /*
................................................................................
   178    178     return pElem ? sqliteHashData(pElem) : 0;
   179    179   }
   180    180   
   181    181   /*
   182    182   ** Convert the given stack entity into a string if it isn't one
   183    183   ** already.
   184    184   */
   185         -#define Stringify(P,I) if((aStack[I].flags & MEM_Str)==0){hardStringify(P,I);}
   186         -static int hardStringify(Vdbe *p, int i){
   187         -  Mem *pStack = &p->aStack[i];
          185  +#define Stringify(P) if(((P)->flags & MEM_Str)==0){hardStringify(P);}
          186  +static int hardStringify(Mem *pStack){
   188    187     int fg = pStack->flags;
   189    188     if( fg & MEM_Real ){
   190    189       sqlite_snprintf(sizeof(pStack->zShort),pStack->zShort,"%.15g",pStack->r);
   191    190     }else if( fg & MEM_Int ){
   192    191       sqlite_snprintf(sizeof(pStack->zShort),pStack->zShort,"%d",pStack->i);
   193    192     }else{
   194    193       pStack->zShort[0] = 0;
   195    194     }
   196         -  p->aStack[i].z = pStack->zShort;
          195  +  pStack->z = pStack->zShort;
   197    196     pStack->n = strlen(pStack->zShort)+1;
   198         -  pStack->flags = MEM_Str;
          197  +  pStack->flags = MEM_Str | MEM_Short;
   199    198     return 0;
   200    199   }
   201    200   
   202    201   /*
   203    202   ** Convert the given stack entity into a string that has been obtained
   204    203   ** from sqliteMalloc().  This is different from Stringify() above in that
   205    204   ** Stringify() will use the NBFS bytes of static string space if the string
   206    205   ** will fit but this routine always mallocs for space.
   207    206   ** Return non-zero if we run out of memory.
   208    207   */
   209         -#define Dynamicify(P,I) ((aStack[I].flags & MEM_Dyn)==0 ? hardDynamicify(P,I):0)
   210         -static int hardDynamicify(Vdbe *p, int i){
   211         -  Mem *pStack = &p->aStack[i];
          208  +#define Dynamicify(P) (((P)->flags & MEM_Dyn)==0 ? hardDynamicify(P):0)
          209  +static int hardDynamicify(Mem *pStack){
   212    210     int fg = pStack->flags;
   213    211     char *z;
   214    212     if( (fg & MEM_Str)==0 ){
   215         -    hardStringify(p, i);
          213  +    hardStringify(pStack);
   216    214     }
   217    215     assert( (fg & MEM_Dyn)==0 );
   218    216     z = sqliteMallocRaw( pStack->n );
   219    217     if( z==0 ) return 1;
   220         -  memcpy(z, p->aStack[i].z, pStack->n);
   221         -  p->aStack[i].z = z;
          218  +  memcpy(z, pStack->z, pStack->n);
          219  +  pStack->z = z;
   222    220     pStack->flags |= MEM_Dyn;
   223    221     return 0;
   224    222   }
   225    223   
   226    224   /*
   227    225   ** An ephemeral string value (signified by the MEM_Ephem flag) contains
   228    226   ** a pointer to a dynamically allocated string where some other entity
................................................................................
   230    228   ** does not control the string, it might be deleted without the stack
   231    229   ** entry knowing it.
   232    230   **
   233    231   ** This routine converts an ephemeral string into a dynamically allocated
   234    232   ** string that the stack entry itself controls.  In other words, it
   235    233   ** converts an MEM_Ephem string into an MEM_Dyn string.
   236    234   */
   237         -#define Deephemeralize(P,I) \
   238         -   if( ((P)->aStack[I].flags&MEM_Ephem)!=0 && hardDeephem(P,I) ){ goto no_mem;}
   239         -static int hardDeephem(Vdbe *p, int i){
   240         -  Mem *pStack = &p->aStack[i];
          235  +#define Deephemeralize(P) \
          236  +   if( ((P)->flags&MEM_Ephem)!=0 && hardDeephem(P) ){ goto no_mem;}
          237  +static int hardDeephem(Mem *pStack){
   241    238     char *z;
   242    239     assert( (pStack->flags & MEM_Ephem)!=0 );
   243    240     z = sqliteMallocRaw( pStack->n );
   244    241     if( z==0 ) return 1;
   245    242     memcpy(z, pStack->z, pStack->n);
   246    243     pStack->z = z;
   247    244     pStack->flags &= ~MEM_Ephem;
   248    245     pStack->flags |= MEM_Dyn;
   249    246     return 0;
   250    247   }
   251    248   
   252    249   /*
   253         -** Release the memory associated with the given stack level
          250  +** Release the memory associated with the given stack level.  This
          251  +** leaves the Mem.flags field in an inconsistent state.
   254    252   */
   255         -#define Release(P,I)  if((P)->aStack[I].flags&MEM_Dyn){ hardRelease(P,I); }
   256         -static void hardRelease(Vdbe *p, int i){
   257         -  sqliteFree(p->aStack[i].z);
   258         -  p->aStack[i].z = 0;
   259         -  p->aStack[i].flags &= ~(MEM_Str|MEM_Dyn|MEM_Static|MEM_Ephem);
          253  +#define Release(P) if((P)->flags&MEM_Dyn){ sqliteFree((P)->z); }
          254  +
          255  +/*
          256  +** Pop the stack N times.
          257  +*/
          258  +static void popStack(Mem **ppTos, int N){
          259  +  Mem *pTos = *ppTos;
          260  +  while( N>0 ){
          261  +    N--;
          262  +    Release(pTos);
          263  +    pTos--;
          264  +  }
          265  +  *ppTos = pTos;
   260    266   }
   261    267   
   262    268   /*
   263    269   ** Return TRUE if zNum is a 32-bit signed integer and write
   264    270   ** the value of the integer into *pNum.  If zNum is not an integer
   265    271   ** or is an integer that is too large to be expressed with just 32
   266    272   ** bits, then return false.
................................................................................
   291    297   /*
   292    298   ** Convert the given stack entity into a integer if it isn't one
   293    299   ** already.
   294    300   **
   295    301   ** Any prior string or real representation is invalidated.  
   296    302   ** NULLs are converted into 0.
   297    303   */
   298         -#define Integerify(P,I) \
   299         -    if(((P)->aStack[(I)].flags&MEM_Int)==0){ hardIntegerify(P,I); }
   300         -static void hardIntegerify(Vdbe *p, int i){
   301         -  if( p->aStack[i].flags & MEM_Real ){
   302         -    p->aStack[i].i = (int)p->aStack[i].r;
   303         -    Release(p, i);
   304         -  }else if( p->aStack[i].flags & MEM_Str ){
   305         -    toInt(p->aStack[i].z, &p->aStack[i].i);
   306         -    Release(p, i);
          304  +#define Integerify(P) if(((P)->flags&MEM_Int)==0){ hardIntegerify(P); }
          305  +static void hardIntegerify(Mem *pStack){
          306  +  if( pStack->flags & MEM_Real ){
          307  +    pStack->i = (int)pStack->r;
          308  +    Release(pStack);
          309  +  }else if( pStack->flags & MEM_Str ){
          310  +    toInt(pStack->z, &pStack->i);
          311  +    Release(pStack);
   307    312     }else{
   308         -    p->aStack[i].i = 0;
          313  +    pStack->i = 0;
   309    314     }
   310         -  p->aStack[i].flags = MEM_Int;
          315  +  pStack->flags = MEM_Int;
   311    316   }
   312    317   
   313    318   /*
   314    319   ** Get a valid Real representation for the given stack element.
   315    320   **
   316    321   ** Any prior string or integer representation is retained.
   317    322   ** NULLs are converted into 0.0.
   318    323   */
   319         -#define Realify(P,I) \
   320         -    if(((P)->aStack[(I)].flags&MEM_Real)==0){ hardRealify(P,I); }
   321         -static void hardRealify(Vdbe *p, int i){
   322         -  if( p->aStack[i].flags & MEM_Str ){
   323         -    p->aStack[i].r = sqliteAtoF(p->aStack[i].z);
   324         -  }else if( p->aStack[i].flags & MEM_Int ){
   325         -    p->aStack[i].r = p->aStack[i].i;
          324  +#define Realify(P) if(((P)->flags&MEM_Real)==0){ hardRealify(P); }
          325  +static void hardRealify(Mem *pStack){
          326  +  if( pStack->flags & MEM_Str ){
          327  +    pStack->r = sqliteAtoF(pStack->z);
          328  +  }else if( pStack->flags & MEM_Int ){
          329  +    pStack->r = pStack->i;
   326    330     }else{
   327         -    p->aStack[i].r = 0.0;
          331  +    pStack->r = 0.0;
   328    332     }
   329         -  p->aStack[i].flags |= MEM_Real;
          333  +  pStack->flags |= MEM_Real;
   330    334   }
   331    335   
   332    336   /*
   333    337   ** The parameters are pointers to the head of two sorted lists
   334    338   ** of Sorter structures.  Merge these two lists together and return
   335    339   ** a single sorted list.  This routine forms the core of the merge-sort
   336    340   ** algorithm.
................................................................................
   357    361       pTail->pNext = pLeft;
   358    362     }else if( pRight ){
   359    363       pTail->pNext = pRight;
   360    364     }
   361    365     return sHead.pNext;
   362    366   }
   363    367   
   364         -/*
   365         -** Code contained within the VERIFY() macro is not needed for correct
   366         -** execution.  It is there only to catch errors.  So when we compile
   367         -** with NDEBUG=1, the VERIFY() code is omitted.
   368         -*/
   369         -#ifdef NDEBUG
   370         -# define VERIFY(X)
   371         -#else
   372         -# define VERIFY(X) X
   373         -#endif
   374         -
   375    368   /*
   376    369   ** The following routine works like a replacement for the standard
   377    370   ** library routine fgets().  The difference is in how end-of-line (EOL)
   378    371   ** is handled.  Standard fgets() uses LF for EOL under unix, CRLF
   379    372   ** under windows, and CR under mac.  This routine accepts any of these
   380    373   ** character sequences as an EOL mark.  The EOL mark is replaced by
   381    374   ** a single LF character in zBuf.
................................................................................
   481    474   int sqliteVdbeExec(
   482    475     Vdbe *p                    /* The VDBE */
   483    476   ){
   484    477     int pc;                    /* The program counter */
   485    478     Op *pOp;                   /* Current operation */
   486    479     int rc = SQLITE_OK;        /* Value to return */
   487    480     sqlite *db = p->db;        /* The database */
   488         -  Mem *aStack = p->aStack;   /* The operand stack */
          481  +  Mem *pTos;                 /* Top entry in the operand stack */
   489    482     char zBuf[100];            /* Space to sprintf() an integer */
   490    483   #ifdef VDBE_PROFILE
   491    484     unsigned long long start;  /* CPU clock count at start of opcode */
   492    485     int origPc;                /* Program counter at start of opcode */
   493    486   #endif
   494    487   #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
   495    488     int nProgressOps = 0;      /* Opcodes executed since progress callback. */
................................................................................
   497    490   
   498    491     if( p->magic!=VDBE_MAGIC_RUN ) return SQLITE_MISUSE;
   499    492     assert( db->magic==SQLITE_MAGIC_BUSY );
   500    493     assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );
   501    494     p->rc = SQLITE_OK;
   502    495     assert( p->explain==0 );
   503    496     if( sqlite_malloc_failed ) goto no_mem;
          497  +  pTos = p->pTos;
   504    498     if( p->popStack ){
   505         -    sqliteVdbePopStack(p, p->popStack);
          499  +    popStack(&pTos, p->popStack);
   506    500       p->popStack = 0;
   507    501     }
   508    502     for(pc=p->pc; rc==SQLITE_OK; pc++){
   509    503       assert( pc>=0 && pc<p->nOp );
   510         -    assert( p->tos<=pc );
          504  +    assert( pTos<=&p->aStack[pc] );
   511    505   #ifdef VDBE_PROFILE
   512    506       origPc = pc;
   513    507       start = hwtime();
   514    508   #endif
   515    509       pOp = &p->aOp[pc];
   516    510   
   517    511       /* Only allow tracing if NDEBUG is not defined.
................................................................................
   635    629   **
   636    630   ** There is an implied "Halt 0 0 0" instruction inserted at the very end of
   637    631   ** every program.  So a jump past the last instruction of the program
   638    632   ** is the same as executing Halt.
   639    633   */
   640    634   case OP_Halt: {
   641    635     p->magic = VDBE_MAGIC_HALT;
          636  +  p->pTos = pTos;
   642    637     if( pOp->p1!=SQLITE_OK ){
   643    638       p->rc = pOp->p1;
   644    639       p->errorAction = pOp->p2;
   645    640       if( pOp->p3 ){
   646    641         sqliteSetString(&p->zErrMsg, pOp->p3, (char*)0);
   647    642       }
   648    643       return SQLITE_ERROR;
................................................................................
   654    649   
   655    650   /* Opcode: Integer P1 * P3
   656    651   **
   657    652   ** The integer value P1 is pushed onto the stack.  If P3 is not zero
   658    653   ** then it is assumed to be a string representation of the same integer.
   659    654   */
   660    655   case OP_Integer: {
   661         -  int i = ++p->tos;
   662         -  aStack[i].i = pOp->p1;
   663         -  aStack[i].flags = MEM_Int;
          656  +  pTos++;
          657  +  pTos->i = pOp->p1;
          658  +  pTos->flags = MEM_Int;
   664    659     if( pOp->p3 ){
   665         -    aStack[i].z = pOp->p3;
   666         -    aStack[i].flags |= MEM_Str | MEM_Static;
   667         -    aStack[i].n = strlen(pOp->p3)+1;
          660  +    pTos->z = pOp->p3;
          661  +    pTos->flags |= MEM_Str | MEM_Static;
          662  +    pTos->n = strlen(pOp->p3)+1;
   668    663     }
   669    664     break;
   670    665   }
   671    666   
   672    667   /* Opcode: String * * P3
   673    668   **
   674    669   ** The string value P3 is pushed onto the stack.  If P3==0 then a
   675    670   ** NULL is pushed onto the stack.
   676    671   */
   677    672   case OP_String: {
   678         -  int i = ++p->tos;
   679         -  char *z;
   680         -  z = pOp->p3;
          673  +  char *z = pOp->p3;
          674  +  pTos++;
   681    675     if( z==0 ){
   682         -    aStack[i].z = 0;
   683         -    aStack[i].n = 0;
   684         -    aStack[i].flags = MEM_Null;
          676  +    pTos->flags = MEM_Null;
   685    677     }else{
   686         -    aStack[i].z = z;
   687         -    aStack[i].n = strlen(z) + 1;
   688         -    aStack[i].flags = MEM_Str | MEM_Static;
          678  +    pTos->z = z;
          679  +    pTos->n = strlen(z) + 1;
          680  +    pTos->flags = MEM_Str | MEM_Static;
   689    681     }
   690    682     break;
   691    683   }
   692    684   
   693    685   /* Opcode: Variable P1 * *
   694    686   **
   695    687   ** Push the value of variable P1 onto the stack.  A variable is
................................................................................
   696    688   ** an unknown in the original SQL string as handed to sqlite_compile().
   697    689   ** Any occurance of the '?' character in the original SQL is considered
   698    690   ** a variable.  Variables in the SQL string are number from left to
   699    691   ** right beginning with 1.  The values of variables are set using the
   700    692   ** sqlite_bind() API.
   701    693   */
   702    694   case OP_Variable: {
   703         -  int i = ++p->tos;
   704    695     int j = pOp->p1 - 1;
          696  +  pTos++;
   705    697     if( j>=0 && j<p->nVar && p->azVar[j]!=0 ){
   706         -    aStack[i].z = p->azVar[j];
   707         -    aStack[i].n = p->anVar[j];
   708         -    aStack[i].flags = MEM_Str | MEM_Static;
          698  +    pTos->z = p->azVar[j];
          699  +    pTos->n = p->anVar[j];
          700  +    pTos->flags = MEM_Str | MEM_Static;
   709    701     }else{
   710         -    aStack[i].z = 0;
   711         -    aStack[i].n = 0;
   712         -    aStack[i].flags = MEM_Null;
          702  +    pTos->flags = MEM_Null;
   713    703     }
   714    704     break;
   715    705   }
   716    706   
   717    707   /* Opcode: Pop P1 * *
   718    708   **
   719    709   ** P1 elements are popped off of the top of stack and discarded.
   720    710   */
   721    711   case OP_Pop: {
   722         -  assert( p->tos+1>=pOp->p1 );
   723         -  sqliteVdbePopStack(p, pOp->p1);
          712  +  assert( pOp->p1>=0 );
          713  +  popStack(&pTos, pOp->p1);
          714  +  assert( pTos>=&p->aStack[-1] );
   724    715     break;
   725    716   }
   726    717   
   727    718   /* Opcode: Dup P1 P2 *
   728    719   **
   729    720   ** A copy of the P1-th element of the stack 
   730    721   ** is made and pushed onto the top of the stack.
................................................................................
   736    727   ** allocated string, then a new copy of that string
   737    728   ** is made if P2==0.  If P2!=0, then just a pointer
   738    729   ** to the string is copied.
   739    730   **
   740    731   ** Also see the Pull instruction.
   741    732   */
   742    733   case OP_Dup: {
   743         -  int i = p->tos - pOp->p1;
   744         -  int j = ++p->tos;
   745         -  VERIFY( if( i<0 ) goto not_enough_stack; )
   746         -  memcpy(&aStack[j], &aStack[i], sizeof(aStack[i])-NBFS);
   747         -  if( aStack[j].flags & MEM_Str ){
   748         -    int isStatic = (aStack[j].flags & MEM_Static)!=0;
   749         -    if( pOp->p2 || isStatic ){
   750         -      aStack[j].z = aStack[i].z;
   751         -      aStack[j].flags &= ~MEM_Dyn;
   752         -      if( !isStatic ) aStack[j].flags |= MEM_Ephem;
   753         -    }else if( aStack[i].n<=NBFS ){
   754         -      memcpy(aStack[j].zShort, aStack[i].z, aStack[j].n);
   755         -      aStack[j].z = aStack[j].zShort;
   756         -      aStack[j].flags &= ~(MEM_Static|MEM_Dyn|MEM_Ephem);
   757         -    }else{
   758         -      aStack[j].z = sqliteMallocRaw( aStack[j].n );
   759         -      if( aStack[j].z==0 ) goto no_mem;
   760         -      memcpy(aStack[j].z, aStack[i].z, aStack[j].n);
   761         -      aStack[j].flags &= ~(MEM_Static|MEM_Ephem);
   762         -      aStack[j].flags |= MEM_Dyn;
          734  +  Mem *pFrom = &pTos[-pOp->p1];
          735  +  assert( pFrom<=pTos && pFrom>=p->aStack );
          736  +  pTos++;
          737  +  memcpy(pTos, pFrom, sizeof(*pFrom)-NBFS);
          738  +  if( pTos->flags & MEM_Str ){
          739  +    if( pOp->p2 && (pTos->flags & (MEM_Dyn|MEM_Ephem)) ){
          740  +      pTos->flags &= ~MEM_Dyn;
          741  +      pTos->flags |= MEM_Ephem;
          742  +    }else if( pTos->flags & MEM_Short ){
          743  +      memcpy(pTos->zShort, pFrom->zShort, pTos->n);
          744  +      pTos->z = pTos->zShort;
          745  +    }else if( (pTos->flags & MEM_Static)==0 ){
          746  +      pTos->z = sqliteMallocRaw(pFrom->n);
          747  +      if( sqlite_malloc_failed ) goto no_mem;
          748  +      memcpy(pTos->z, pFrom->z, pFrom->n);
          749  +      pTos->flags &= ~(MEM_Static|MEM_Ephem|MEM_Short);
          750  +      pTos->flags |= MEM_Dyn;
   763    751       }
   764    752     }
   765    753     break;
   766    754   }
   767    755   
   768    756   /* Opcode: Pull P1 * *
   769    757   **
................................................................................
   772    760   ** top of the stack is element 0, so "Pull 0 0 0" is
   773    761   ** a no-op.  "Pull 1 0 0" swaps the top two elements of
   774    762   ** the stack.
   775    763   **
   776    764   ** See also the Dup instruction.
   777    765   */
   778    766   case OP_Pull: {
   779         -  int from = p->tos - pOp->p1;
   780         -  int to = p->tos;
          767  +  Mem *pFrom = &pTos[-pOp->p1];
   781    768     int i;
   782    769     Mem ts;
   783         -  VERIFY( if( from<0 ) goto not_enough_stack; )
   784         -  Deephemeralize(p, from);
   785         -  ts = aStack[from];
   786         -  Deephemeralize(p, to);
   787         -  for(i=from; i<to; i++){
   788         -    Deephemeralize(p, i+1);
   789         -    aStack[i] = aStack[i+1];
   790         -    assert( (aStack[i].flags & MEM_Ephem)==0 );
   791         -    if( aStack[i].flags & (MEM_Dyn|MEM_Static) ){
   792         -      aStack[i].z = aStack[i+1].z;
   793         -    }else{
   794         -      aStack[i].z = aStack[i].zShort;
          770  +
          771  +  /* Deephemeralize(pFrom); *** not needed */
          772  +  ts = *pFrom;
          773  +  Deephemeralize(pTos);
          774  +  for(i=0; i<pOp->p1; i++, pFrom++){
          775  +    Deephemeralize(&pFrom[1]);
          776  +    *pFrom = pFrom[1];
          777  +    assert( (pFrom->flags & MEM_Ephem)==0 );
          778  +    if( pFrom->flags & MEM_Short ){
          779  +      assert( pFrom->flags & MEM_Str );
          780  +      assert( pFrom->z==pFrom[1].zShort );
          781  +      assert( (pTos->flags & (MEM_Dyn|MEM_Static|MEM_Ephem))==0 );
          782  +      pFrom->z = pFrom->zShort;
   795    783       }
   796    784     }
   797         -  aStack[to] = ts;
   798         -  assert( (aStack[to].flags & MEM_Ephem)==0 );
   799         -  if( (aStack[to].flags & (MEM_Dyn|MEM_Static))==0 ){
   800         -    aStack[to].z = aStack[to].zShort;
          785  +  *pTos = ts;
          786  +  /* assert( (pTos->flags & MEM_Ephem)==0 ); *** not needed */
          787  +  if( pTos->flags & MEM_Short ){
          788  +    assert( pTos->flags & MEM_Str );
          789  +    assert( pTos->z==pTos[-pOp->p1].zShort );
          790  +    assert( (pTos->flags & (MEM_Dyn|MEM_Static|MEM_Ephem))==0 );
          791  +    pTos->z = pTos->zShort;
   801    792     }
   802    793     break;
   803    794   }
   804    795   
   805    796   /* Opcode: Push P1 * *
   806    797   **
   807    798   ** Overwrite the value of the P1-th element down on the
   808    799   ** stack (P1==0 is the top of the stack) with the value
   809    800   ** of the top of the stack.  Then pop the top of the stack.
   810    801   */
   811    802   case OP_Push: {
   812         -  int from = p->tos;
   813         -  int to = p->tos - pOp->p1;
          803  +  Mem *pTo = &pTos[-pOp->p1];
   814    804   
   815         -  VERIFY( if( to<0 ) goto not_enough_stack; )
   816         -  if( aStack[to].flags & MEM_Dyn ){
   817         -    sqliteFree(aStack[to].z);
          805  +  assert( pTo>=p->aStack );
          806  +  Deephemeralize(pTos);
          807  +  Release(pTo);
          808  +  *pTo = *pTos;
          809  +  if( pTo->flags & MEM_Short ){
          810  +    assert( pTo->z==pTos->zShort );
          811  +    pTo->z = pTo->zShort;
   818    812     }
   819         -  Deephemeralize(p, from);
   820         -  aStack[to] = aStack[from];
   821         -  if( aStack[to].flags & (MEM_Dyn|MEM_Static|MEM_Ephem) ){
   822         -    aStack[to].z = aStack[from].z;
   823         -  }else{
   824         -    aStack[to].z = aStack[to].zShort;
   825         -  }
   826         -  aStack[from].flags = 0;
   827         -  p->tos--;
          813  +  pTos--;
   828    814     break;
   829    815   }
          816  +
   830    817   
   831    818   /* Opcode: ColumnName P1 * P3
   832    819   **
   833    820   ** P3 becomes the P1-th column name (first is 0).  An array of pointers
   834    821   ** to all column names is passed as the 4th parameter to the callback.
   835    822   */
   836    823   case OP_ColumnName: {
................................................................................
   843    830   /* Opcode: Callback P1 * *
   844    831   **
   845    832   ** Pop P1 values off the stack and form them into an array.  Then
   846    833   ** invoke the callback function using the newly formed array as the
   847    834   ** 3rd parameter.
   848    835   */
   849    836   case OP_Callback: {
   850         -  int i = p->tos - pOp->p1 + 1;
   851         -  int j;
   852         -  VERIFY( if( i<0 ) goto not_enough_stack; )
   853         -  for(j=i; j<=p->tos; j++){
   854         -    if( aStack[j].flags & MEM_Null ){
   855         -      aStack[j].z = 0;
          837  +  int i;
          838  +  char **azArgv = p->zArgv;
          839  +  Mem *pCol;
          840  +
          841  +  pCol = &pTos[1-pOp->p1];
          842  +  assert( pCol>=p->aStack );
          843  +  for(i=0; i<pOp->p1; i++, pCol++){
          844  +    if( pCol->flags & MEM_Null ){
          845  +      azArgv[i] = 0;
   856    846       }else{
   857         -      Stringify(p, j);
          847  +      Stringify(pCol);
          848  +      azArgv[i] = pCol->z;
   858    849       }
   859         -    p->zArgv[j] = aStack[j].z;
   860    850     }
   861         -  p->zArgv[p->tos+1] = 0;
          851  +  azArgv[i] = 0;
   862    852     if( p->xCallback==0 ){
   863         -    p->azResColumn = &p->zArgv[i];
          853  +    p->azResColumn = azArgv;
   864    854       p->nResColumn = pOp->p1;
   865    855       p->popStack = pOp->p1;
   866    856       p->pc = pc + 1;
          857  +    p->pTos = pTos;
   867    858       return SQLITE_ROW;
   868    859     }
   869    860     if( sqliteSafetyOff(db) ) goto abort_due_to_misuse; 
   870         -  if( p->xCallback(p->pCbArg, pOp->p1, &p->zArgv[i], p->azColName)!=0 ){
          861  +  if( p->xCallback(p->pCbArg, pOp->p1, azArgv, p->azColName)!=0 ){
   871    862       rc = SQLITE_ABORT;
   872    863     }
   873    864     if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;
   874    865     p->nCallback++;
   875         -  sqliteVdbePopStack(p, pOp->p1);
          866  +  popStack(&pTos, pOp->p1);
          867  +  assert( pTos>=&p->aStack[-1] );
   876    868     if( sqlite_malloc_failed ) goto no_mem;
   877    869     break;
   878    870   }
   879    871   
   880    872   /* Opcode: NullCallback P1 * *
   881    873   **
   882    874   ** Invoke the callback function once with the 2nd argument (the
................................................................................
   922    914   case OP_Concat: {
   923    915     char *zNew;
   924    916     int nByte;
   925    917     int nField;
   926    918     int i, j;
   927    919     char *zSep;
   928    920     int nSep;
          921  +  Mem *pTerm;
   929    922   
   930    923     nField = pOp->p1;
   931    924     zSep = pOp->p3;
   932    925     if( zSep==0 ) zSep = "";
   933    926     nSep = strlen(zSep);
   934         -  VERIFY( if( p->tos+1<nField ) goto not_enough_stack; )
          927  +  assert( &pTos[1-nField] >= p->aStack );
   935    928     nByte = 1 - nSep;
   936         -  for(i=p->tos-nField+1; i<=p->tos; i++){
   937         -    if( aStack[i].flags & MEM_Null ){
          929  +  pTerm = &pTos[1-nField];
          930  +  for(i=0; i<nField; i++, pTerm++){
          931  +    if( pTerm->flags & MEM_Null ){
   938    932         nByte = -1;
   939    933         break;
   940    934       }else{
   941         -      Stringify(p, i);
   942         -      nByte += aStack[i].n - 1 + nSep;
          935  +      Stringify(pTerm);
          936  +      nByte += pTerm->n - 1 + nSep;
   943    937       }
   944    938     }
   945    939     if( nByte<0 ){
   946         -    if( pOp->p2==0 ) sqliteVdbePopStack(p, nField);
   947         -    p->tos++;
   948         -    aStack[p->tos].flags = MEM_Null;
   949         -    aStack[p->tos].z = 0;
          940  +    if( pOp->p2==0 ){
          941  +      popStack(&pTos, nField);
          942  +    }
          943  +    pTos++;
          944  +    pTos->flags = MEM_Null;
   950    945       break;
   951    946     }
   952    947     zNew = sqliteMallocRaw( nByte );
   953    948     if( zNew==0 ) goto no_mem;
   954    949     j = 0;
   955         -  for(i=p->tos-nField+1; i<=p->tos; i++){
   956         -    if( (aStack[i].flags & MEM_Null)==0 ){
   957         -      memcpy(&zNew[j], aStack[i].z, aStack[i].n-1);
   958         -      j += aStack[i].n-1;
   959         -    }
   960         -    if( nSep>0 && i<p->tos ){
          950  +  pTerm = &pTos[1-nField];
          951  +  for(i=j=0; i<nField; i++, pTerm++){
          952  +    assert( pTerm->flags & MEM_Str );
          953  +    memcpy(&zNew[j], pTerm->z, pTerm->n-1);
          954  +    j += pTerm->n-1;
          955  +    if( nSep>0 && i<nField-1 ){
   961    956         memcpy(&zNew[j], zSep, nSep);
   962    957         j += nSep;
   963    958       }
   964    959     }
   965    960     zNew[j] = 0;
   966         -  if( pOp->p2==0 ) sqliteVdbePopStack(p, nField);
   967         -  p->tos++;
   968         -  aStack[p->tos].n = nByte;
   969         -  aStack[p->tos].flags = MEM_Str|MEM_Dyn;
   970         -  aStack[p->tos].z = zNew;
          961  +  if( pOp->p2==0 ){
          962  +    popStack(&pTos, nField);
          963  +  }
          964  +  pTos++;
          965  +  pTos->n = nByte;
          966  +  pTos->flags = MEM_Str|MEM_Dyn;
          967  +  pTos->z = zNew;
   971    968     break;
   972    969   }
   973    970   
   974    971   /* Opcode: Add * * *
   975    972   **
   976    973   ** Pop the top two elements from the stack, add them together,
   977    974   ** and push the result back onto the stack.  If either element
................................................................................
  1018   1015   ** If either operand is NULL, the result is NULL.
  1019   1016   */
  1020   1017   case OP_Add:
  1021   1018   case OP_Subtract:
  1022   1019   case OP_Multiply:
  1023   1020   case OP_Divide:
  1024   1021   case OP_Remainder: {
  1025         -  int tos = p->tos;
  1026         -  int nos = tos - 1;
  1027         -  VERIFY( if( nos<0 ) goto not_enough_stack; )
  1028         -  if( ((aStack[tos].flags | aStack[nos].flags) & MEM_Null)!=0 ){
  1029         -    POPSTACK;
  1030         -    Release(p, nos);
  1031         -    aStack[nos].flags = MEM_Null;
  1032         -  }else if( (aStack[tos].flags & aStack[nos].flags & MEM_Int)==MEM_Int ){
         1022  +  Mem *pNos = &pTos[-1];
         1023  +  assert( pNos>=p->aStack );
         1024  +  if( ((pTos->flags | pNos->flags) & MEM_Null)!=0 ){
         1025  +    Release(pTos);
         1026  +    pTos--;
         1027  +    Release(pTos);
         1028  +    pTos->flags = MEM_Null;
         1029  +  }else if( (pTos->flags & pNos->flags & MEM_Int)==MEM_Int ){
  1033   1030       int a, b;
  1034         -    a = aStack[tos].i;
  1035         -    b = aStack[nos].i;
         1031  +    a = pTos->i;
         1032  +    b = pNos->i;
  1036   1033       switch( pOp->opcode ){
  1037   1034         case OP_Add:         b += a;       break;
  1038   1035         case OP_Subtract:    b -= a;       break;
  1039   1036         case OP_Multiply:    b *= a;       break;
  1040   1037         case OP_Divide: {
  1041   1038           if( a==0 ) goto divide_by_zero;
  1042   1039           b /= a;
................................................................................
  1044   1041         }
  1045   1042         default: {
  1046   1043           if( a==0 ) goto divide_by_zero;
  1047   1044           b %= a;
  1048   1045           break;
  1049   1046         }
  1050   1047       }
  1051         -    POPSTACK;
  1052         -    Release(p, nos);
  1053         -    aStack[nos].i = b;
  1054         -    aStack[nos].flags = MEM_Int;
         1048  +    Release(pTos);
         1049  +    pTos--;
         1050  +    Release(pTos);
         1051  +    pTos->i = b;
         1052  +    pTos->flags = MEM_Int;
  1055   1053     }else{
  1056   1054       double a, b;
  1057         -    Realify(p, tos);
  1058         -    Realify(p, nos);
  1059         -    a = aStack[tos].r;
  1060         -    b = aStack[nos].r;
         1055  +    Realify(pTos);
         1056  +    Realify(pNos);
         1057  +    a = pTos->r;
         1058  +    b = pNos->r;
  1061   1059       switch( pOp->opcode ){
  1062   1060         case OP_Add:         b += a;       break;
  1063   1061         case OP_Subtract:    b -= a;       break;
  1064   1062         case OP_Multiply:    b *= a;       break;
  1065   1063         case OP_Divide: {
  1066   1064           if( a==0.0 ) goto divide_by_zero;
  1067   1065           b /= a;
................................................................................
  1071   1069           int ia = (int)a;
  1072   1070           int ib = (int)b;
  1073   1071           if( ia==0.0 ) goto divide_by_zero;
  1074   1072           b = ib % ia;
  1075   1073           break;
  1076   1074         }
  1077   1075       }
  1078         -    POPSTACK;
  1079         -    Release(p, nos);
  1080         -    aStack[nos].r = b;
  1081         -    aStack[nos].flags = MEM_Real;
         1076  +    Release(pTos);
         1077  +    pTos--;
         1078  +    Release(pTos);
         1079  +    pTos->r = b;
         1080  +    pTos->flags = MEM_Real;
  1082   1081     }
  1083   1082     break;
  1084   1083   
  1085   1084   divide_by_zero:
  1086         -  sqliteVdbePopStack(p, 2);
  1087         -  p->tos = nos;
  1088         -  aStack[nos].flags = MEM_Null;
         1085  +  Release(pTos);
         1086  +  pTos--;
         1087  +  Release(pTos);
         1088  +  pTos->flags = MEM_Null;
  1089   1089     break;
  1090   1090   }
  1091   1091   
  1092   1092   /* Opcode: Function P1 * P3
  1093   1093   **
  1094   1094   ** Invoke a user function (P3 is a pointer to a Function structure that
  1095   1095   ** defines the function) with P1 string arguments taken from the stack.
  1096   1096   ** Pop all arguments from the stack and push back the result.
  1097   1097   **
  1098   1098   ** See also: AggFunc
  1099   1099   */
  1100   1100   case OP_Function: {
  1101   1101     int n, i;
         1102  +  Mem *pArg;
         1103  +  char **azArgv;
  1102   1104     sqlite_func ctx;
  1103   1105   
  1104   1106     n = pOp->p1;
  1105         -  VERIFY( if( n<0 ) goto bad_instruction; )
  1106         -  VERIFY( if( p->tos+1<n ) goto not_enough_stack; )
  1107         -  for(i=p->tos-n+1; i<=p->tos; i++){
  1108         -    if( aStack[i].flags & MEM_Null ){
  1109         -      aStack[i].z = 0;
         1107  +  pArg = &pTos[1-n];
         1108  +  azArgv = p->zArgv;
         1109  +  for(i=0; i<n; i++, pArg++){
         1110  +    if( pArg->flags & MEM_Null ){
         1111  +      azArgv[i] = 0;
  1110   1112       }else{
  1111         -      Stringify(p, i);
         1113  +      Stringify(pArg);
         1114  +      azArgv[i] = pArg->z;
  1112   1115       }
  1113         -    p->zArgv[i] = aStack[i].z;
  1114   1116     }
  1115   1117     ctx.pFunc = (FuncDef*)pOp->p3;
  1116   1118     ctx.s.flags = MEM_Null;
  1117   1119     ctx.s.z = 0;
  1118   1120     ctx.isError = 0;
  1119   1121     ctx.isStep = 0;
  1120   1122     if( sqliteSafetyOff(db) ) goto abort_due_to_misuse;
  1121         -  (*ctx.pFunc->xFunc)(&ctx, n, (const char**)&p->zArgv[p->tos-n+1]);
         1123  +  (*ctx.pFunc->xFunc)(&ctx, n, (const char**)azArgv);
  1122   1124     if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;
  1123         -  sqliteVdbePopStack(p, n);
  1124         -  p->tos++;
  1125         -  aStack[p->tos] = ctx.s;
  1126         -  if( ctx.s.flags & MEM_Dyn ){
  1127         -    aStack[p->tos].z = ctx.s.z;
  1128         -  }else if( ctx.s.flags & MEM_Str ){
  1129         -    aStack[p->tos].z = aStack[p->tos].zShort;
  1130         -  }else{
  1131         -    aStack[p->tos].z = 0;
         1125  +  popStack(&pTos, n);
         1126  +  pTos++;
         1127  +  *pTos = ctx.s;
         1128  +  if( pTos->flags & MEM_Short ){
         1129  +    pTos->z = pTos->zShort;
  1132   1130     }
  1133   1131     if( ctx.isError ){
  1134   1132       sqliteSetString(&p->zErrMsg, 
  1135         -       aStack[p->tos].z ? aStack[p->tos].z : "user function error", (char*)0);
         1133  +       (pTos->flags & MEM_Str)!=0 ? pTos->z : "user function error", (char*)0);
  1136   1134       rc = SQLITE_ERROR;
  1137   1135     }
  1138   1136     break;
  1139   1137   }
  1140   1138   
  1141   1139   /* Opcode: BitAnd * * *
  1142   1140   **
................................................................................
  1166   1164   ** right by N bits where N is the second element on the stack.
  1167   1165   ** If either operand is NULL, the result is NULL.
  1168   1166   */
  1169   1167   case OP_BitAnd:
  1170   1168   case OP_BitOr:
  1171   1169   case OP_ShiftLeft:
  1172   1170   case OP_ShiftRight: {
  1173         -  int tos = p->tos;
  1174         -  int nos = tos - 1;
         1171  +  Mem *pNos = &pTos[-1];
  1175   1172     int a, b;
  1176         -  VERIFY( if( nos<0 ) goto not_enough_stack; )
  1177         -  if( (aStack[tos].flags | aStack[nos].flags) & MEM_Null ){
  1178         -    POPSTACK;
  1179         -    Release(p,nos);
  1180         -    aStack[nos].flags = MEM_Null;
         1173  +
         1174  +  assert( pNos>=p->aStack );
         1175  +  if( (pTos->flags | pNos->flags) & MEM_Null ){
         1176  +    popStack(&pTos, 2);
         1177  +    pTos++;
         1178  +    pTos->flags = MEM_Null;
  1181   1179       break;
  1182   1180     }
  1183         -  Integerify(p, tos);
  1184         -  Integerify(p, nos);
  1185         -  a = aStack[tos].i;
  1186         -  b = aStack[nos].i;
         1181  +  Integerify(pTos);
         1182  +  Integerify(pNos);
         1183  +  a = pTos->i;
         1184  +  b = pNos->i;
  1187   1185     switch( pOp->opcode ){
  1188   1186       case OP_BitAnd:      a &= b;     break;
  1189   1187       case OP_BitOr:       a |= b;     break;
  1190   1188       case OP_ShiftLeft:   a <<= b;    break;
  1191   1189       case OP_ShiftRight:  a >>= b;    break;
  1192   1190       default:   /* CANT HAPPEN */     break;
  1193   1191     }
  1194         -  POPSTACK;
  1195         -  Release(p, nos);
  1196         -  aStack[nos].i = a;
  1197         -  aStack[nos].flags = MEM_Int;
         1192  +  assert( (pTos->flags & MEM_Dyn)==0 );
         1193  +  assert( (pNos->flags & MEM_Dyn)==0 );
         1194  +  pTos--;
         1195  +  pTos->i = a;
         1196  +  assert( pTos->flags==MEM_Int );
  1198   1197     break;
  1199   1198   }
  1200   1199   
  1201   1200   /* Opcode: AddImm  P1 * *
  1202   1201   ** 
  1203   1202   ** Add the value P1 to whatever is on top of the stack.  The result
  1204   1203   ** is always an integer.
  1205   1204   **
  1206   1205   ** To force the top of the stack to be an integer, just add 0.
  1207   1206   */
  1208   1207   case OP_AddImm: {
  1209         -  int tos = p->tos;
  1210         -  VERIFY( if( tos<0 ) goto not_enough_stack; )
  1211         -  Integerify(p, tos);
  1212         -  aStack[tos].i += pOp->p1;
         1208  +  assert( pTos>=p->aStack );
         1209  +  Integerify(pTos);
         1210  +  pTos->i += pOp->p1;
  1213   1211     break;
  1214   1212   }
  1215   1213   
  1216   1214   /* Opcode: ForceInt P1 P2 *
  1217   1215   **
  1218   1216   ** Convert the top of the stack into an integer.  If the current top of
  1219   1217   ** the stack is not numeric (meaning that is is a NULL or a string that
................................................................................
  1220   1218   ** does not look like an integer or floating point number) then pop the
  1221   1219   ** stack and jump to P2.  If the top of the stack is numeric then
  1222   1220   ** convert it into the least integer that is greater than or equal to its
  1223   1221   ** current value if P1==0, or to the least integer that is strictly
  1224   1222   ** greater than its current value if P1==1.
  1225   1223   */
  1226   1224   case OP_ForceInt: {
  1227         -  int tos = p->tos;
  1228   1225     int v;
  1229         -  VERIFY( if( tos<0 ) goto not_enough_stack; )
  1230         -  if( (aStack[tos].flags & (MEM_Int|MEM_Real))==0
  1231         -         && (aStack[tos].z==0 || sqliteIsNumber(aStack[tos].z)==0) ){
  1232         -    POPSTACK;
         1226  +  assert( pTos>=p->aStack );
         1227  +  if( (pTos->flags & (MEM_Int|MEM_Real))==0
         1228  +         && ((pTos->flags & MEM_Str)==0 || sqliteIsNumber(pTos->z)==0) ){
         1229  +    Release(pTos);
         1230  +    pTos--;
  1233   1231       pc = pOp->p2 - 1;
  1234   1232       break;
  1235   1233     }
  1236         -  if( aStack[tos].flags & MEM_Int ){
  1237         -    v = aStack[tos].i + (pOp->p1!=0);
         1234  +  if( pTos->flags & MEM_Int ){
         1235  +    v = pTos->i + (pOp->p1!=0);
  1238   1236     }else{
  1239         -    Realify(p, tos);
  1240         -    v = (int)aStack[tos].r;
  1241         -    if( aStack[tos].r>(double)v ) v++;
  1242         -    if( pOp->p1 && aStack[tos].r==(double)v ) v++;
         1237  +    Realify(pTos);
         1238  +    v = (int)pTos->r;
         1239  +    if( pTos->r>(double)v ) v++;
         1240  +    if( pOp->p1 && pTos->r==(double)v ) v++;
  1243   1241     }
  1244         -  if( aStack[tos].flags & MEM_Dyn ) sqliteFree(aStack[tos].z);
  1245         -  aStack[tos].z = 0;
  1246         -  aStack[tos].i = v;
  1247         -  aStack[tos].flags = MEM_Int;
         1242  +  Release(pTos);
         1243  +  pTos->i = v;
         1244  +  pTos->flags = MEM_Int;
  1248   1245     break;
  1249   1246   }
  1250   1247   
  1251   1248   /* Opcode: MustBeInt P1 P2 *
  1252   1249   ** 
  1253   1250   ** Force the top of the stack to be an integer.  If the top of the
  1254   1251   ** stack is not an integer and cannot be converted into an integer
................................................................................
  1256   1253   ** raise an SQLITE_MISMATCH exception.
  1257   1254   **
  1258   1255   ** If the top of the stack is not an integer and P2 is not zero and
  1259   1256   ** P1 is 1, then the stack is popped.  In all other cases, the depth
  1260   1257   ** of the stack is unchanged.
  1261   1258   */
  1262   1259   case OP_MustBeInt: {
  1263         -  int tos = p->tos;
  1264         -  VERIFY( if( tos<0 ) goto not_enough_stack; )
  1265         -  if( aStack[tos].flags & MEM_Int ){
         1260  +  assert( pTos>=p->aStack );
         1261  +  if( pTos->flags & MEM_Int ){
  1266   1262       /* Do nothing */
  1267         -  }else if( aStack[tos].flags & MEM_Real ){
  1268         -    int i = aStack[tos].r;
         1263  +  }else if( pTos->flags & MEM_Real ){
         1264  +    int i = (int)pTos->r;
  1269   1265       double r = (double)i;
  1270         -    if( r!=aStack[tos].r ){
         1266  +    if( r!=pTos->r ){
  1271   1267         goto mismatch;
  1272   1268       }
  1273         -    aStack[tos].i = i;
  1274         -  }else if( aStack[tos].flags & MEM_Str ){
         1269  +    pTos->i = i;
         1270  +  }else if( pTos->flags & MEM_Str ){
  1275   1271       int v;
  1276         -    if( !toInt(aStack[tos].z, &v) ){
         1272  +    if( !toInt(pTos->z, &v) ){
  1277   1273         double r;
  1278         -      if( !sqliteIsNumber(aStack[tos].z) ){
         1274  +      if( !sqliteIsNumber(pTos->z) ){
  1279   1275           goto mismatch;
  1280   1276         }
  1281         -      Realify(p, tos);
  1282         -      assert( (aStack[tos].flags & MEM_Real)!=0 );
  1283         -      v = aStack[tos].r;
         1277  +      Realify(pTos);
         1278  +      v = (int)pTos->r;
  1284   1279         r = (double)v;
  1285         -      if( r!=aStack[tos].r ){
         1280  +      if( r!=pTos->r ){
  1286   1281           goto mismatch;
  1287   1282         }
  1288   1283       }
  1289         -    aStack[tos].i = v;
         1284  +    pTos->i = v;
  1290   1285     }else{
  1291   1286       goto mismatch;
  1292   1287     }
  1293         -  Release(p, tos);
  1294         -  aStack[tos].flags = MEM_Int;
         1288  +  Release(pTos);
         1289  +  pTos->flags = MEM_Int;
  1295   1290     break;
  1296   1291   
  1297   1292   mismatch:
  1298   1293     if( pOp->p2==0 ){
  1299   1294       rc = SQLITE_MISMATCH;
  1300   1295       goto abort_due_to_error;
  1301   1296     }else{
  1302         -    if( pOp->p1 ) POPSTACK;
         1297  +    if( pOp->p1 ) popStack(&pTos, 1);
  1303   1298       pc = pOp->p2 - 1;
  1304   1299     }
  1305   1300     break;
  1306   1301   }
  1307   1302   
  1308   1303   /* Opcode: Eq P1 P2 *
  1309   1304   **
................................................................................
  1418   1413   */
  1419   1414   case OP_Eq:
  1420   1415   case OP_Ne:
  1421   1416   case OP_Lt:
  1422   1417   case OP_Le:
  1423   1418   case OP_Gt:
  1424   1419   case OP_Ge: {
  1425         -  int tos = p->tos;
  1426         -  int nos = tos - 1;
         1420  +  Mem *pNos = &pTos[-1];
  1427   1421     int c, v;
  1428   1422     int ft, fn;
  1429         -  VERIFY( if( nos<0 ) goto not_enough_stack; )
  1430         -  ft = aStack[tos].flags;
  1431         -  fn = aStack[nos].flags;
         1423  +  assert( pNos>=p->aStack );
         1424  +  ft = pTos->flags;
         1425  +  fn = pNos->flags;
  1432   1426     if( (ft | fn) & MEM_Null ){
  1433         -    POPSTACK;
  1434         -    POPSTACK;
         1427  +    popStack(&pTos, 2);
  1435   1428       if( pOp->p2 ){
  1436   1429         if( pOp->p1 ) pc = pOp->p2-1;
  1437   1430       }else{
  1438         -      p->tos++;
  1439         -      aStack[nos].flags = MEM_Null;
         1431  +      pTos++;
         1432  +      pTos->flags = MEM_Null;
  1440   1433       }
  1441   1434       break;
  1442   1435     }else if( (ft & fn & MEM_Int)==MEM_Int ){
  1443         -    c = aStack[nos].i - aStack[tos].i;
  1444         -  }else if( (ft & MEM_Int)!=0 && (fn & MEM_Str)!=0 && toInt(aStack[nos].z,&v) ){
  1445         -    Release(p, nos);
  1446         -    aStack[nos].i = v;
  1447         -    aStack[nos].flags = MEM_Int;
  1448         -    c = aStack[nos].i - aStack[tos].i;
  1449         -  }else if( (fn & MEM_Int)!=0 && (ft & MEM_Str)!=0 && toInt(aStack[tos].z,&v) ){
  1450         -    Release(p, tos);
  1451         -    aStack[tos].i = v;
  1452         -    aStack[tos].flags = MEM_Int;
  1453         -    c = aStack[nos].i - aStack[tos].i;
         1436  +    c = pNos->i - pTos->i;
         1437  +  }else if( (ft & MEM_Int)!=0 && (fn & MEM_Str)!=0 && toInt(pNos->z,&v) ){
         1438  +    c = v - pTos->i;
         1439  +  }else if( (fn & MEM_Int)!=0 && (ft & MEM_Str)!=0 && toInt(pTos->z,&v) ){
         1440  +    c = pNos->i - v;
  1454   1441     }else{
  1455         -    Stringify(p, tos);
  1456         -    Stringify(p, nos);
  1457         -    c = sqliteCompare(aStack[nos].z, aStack[tos].z);
         1442  +    Stringify(pTos);
         1443  +    Stringify(pNos);
         1444  +    c = sqliteCompare(pNos->z, pTos->z);
  1458   1445     }
  1459   1446     switch( pOp->opcode ){
  1460   1447       case OP_Eq:    c = c==0;     break;
  1461   1448       case OP_Ne:    c = c!=0;     break;
  1462   1449       case OP_Lt:    c = c<0;      break;
  1463   1450       case OP_Le:    c = c<=0;     break;
  1464   1451       case OP_Gt:    c = c>0;      break;
  1465   1452       default:       c = c>=0;     break;
  1466   1453     }
  1467         -  POPSTACK;
  1468         -  POPSTACK;
         1454  +  popStack(&pTos, 2);
  1469   1455     if( pOp->p2 ){
  1470   1456       if( c ) pc = pOp->p2-1;
  1471   1457     }else{
  1472         -    p->tos++;
  1473         -    aStack[nos].flags = MEM_Int;
  1474         -    aStack[nos].i = c;
         1458  +    pTos++;
         1459  +    pTos->i = c;
         1460  +    pTos->flags = MEM_Int;
  1475   1461     }
  1476   1462     break;
  1477   1463   }
  1478   1464   /* INSERT NO CODE HERE!
  1479   1465   **
  1480   1466   ** The opcode numbers are extracted from this source file by doing
  1481   1467   **
................................................................................
  1584   1570   */
  1585   1571   case OP_StrEq:
  1586   1572   case OP_StrNe:
  1587   1573   case OP_StrLt:
  1588   1574   case OP_StrLe:
  1589   1575   case OP_StrGt:
  1590   1576   case OP_StrGe: {
  1591         -  int tos = p->tos;
  1592         -  int nos = tos - 1;
         1577  +  Mem *pNos = &pTos[-1];
  1593   1578     int c;
  1594         -  VERIFY( if( nos<0 ) goto not_enough_stack; )
  1595         -  if( (aStack[nos].flags | aStack[tos].flags) & MEM_Null ){
  1596         -    POPSTACK;
  1597         -    POPSTACK;
         1579  +  assert( pNos>=p->aStack );
         1580  +  if( (pNos->flags | pTos->flags) & MEM_Null ){
         1581  +    popStack(&pTos, 2);
  1598   1582       if( pOp->p2 ){
  1599   1583         if( pOp->p1 ) pc = pOp->p2-1;
  1600   1584       }else{
  1601         -      p->tos++;
  1602         -      aStack[nos].flags = MEM_Null;
         1585  +      pTos++;
         1586  +      pTos->flags = MEM_Null;
  1603   1587       }
  1604   1588       break;
  1605   1589     }else{
  1606         -    Stringify(p, tos);
  1607         -    Stringify(p, nos);
  1608         -    c = strcmp(aStack[nos].z, aStack[tos].z);
         1590  +    Stringify(pTos);
         1591  +    Stringify(pNos);
         1592  +    c = strcmp(pNos->z, pTos->z);
  1609   1593     }
  1610   1594     /* The asserts on each case of the following switch are there to verify
  1611   1595     ** that string comparison opcodes are always exactly 6 greater than the
  1612   1596     ** corresponding numeric comparison opcodes.  The code generator depends
  1613   1597     ** on this fact.
  1614   1598     */
  1615   1599     switch( pOp->opcode ){
................................................................................
  1616   1600       case OP_StrEq:    c = c==0;    assert( pOp->opcode-6==OP_Eq );   break;
  1617   1601       case OP_StrNe:    c = c!=0;    assert( pOp->opcode-6==OP_Ne );   break;
  1618   1602       case OP_StrLt:    c = c<0;     assert( pOp->opcode-6==OP_Lt );   break;
  1619   1603       case OP_StrLe:    c = c<=0;    assert( pOp->opcode-6==OP_Le );   break;
  1620   1604       case OP_StrGt:    c = c>0;     assert( pOp->opcode-6==OP_Gt );   break;
  1621   1605       default:          c = c>=0;    assert( pOp->opcode-6==OP_Ge );   break;
  1622   1606     }
  1623         -  POPSTACK;
  1624         -  POPSTACK;
         1607  +  popStack(&pTos, 2);
  1625   1608     if( pOp->p2 ){
  1626   1609       if( c ) pc = pOp->p2-1;
  1627   1610     }else{
  1628         -    p->tos++;
  1629         -    aStack[nos].flags = MEM_Int;
  1630         -    aStack[nos].i = c;
         1611  +    pTos++;
         1612  +    pTos->flags = MEM_Int;
         1613  +    pTos->i = c;
  1631   1614     }
  1632   1615     break;
  1633   1616   }
  1634   1617   
  1635   1618   /* Opcode: And * * *
  1636   1619   **
  1637   1620   ** Pop two values off the stack.  Take the logical AND of the
................................................................................
  1642   1625   **
  1643   1626   ** Pop two values off the stack.  Take the logical OR of the
  1644   1627   ** two values and push the resulting boolean value back onto the
  1645   1628   ** stack. 
  1646   1629   */
  1647   1630   case OP_And:
  1648   1631   case OP_Or: {
  1649         -  int tos = p->tos;
  1650         -  int nos = tos - 1;
         1632  +  Mem *pNos = &pTos[-1];
  1651   1633     int v1, v2;    /* 0==TRUE, 1==FALSE, 2==UNKNOWN or NULL */
  1652   1634   
  1653         -  VERIFY( if( nos<0 ) goto not_enough_stack; )
  1654         -  if( aStack[tos].flags & MEM_Null ){
         1635  +  assert( pNos>=p->aStack );
         1636  +  if( pTos->flags & MEM_Null ){
  1655   1637       v1 = 2;
  1656   1638     }else{
  1657         -    Integerify(p, tos);
  1658         -    v1 = aStack[tos].i==0;
         1639  +    Integerify(pTos);
         1640  +    v1 = pTos->i==0;
  1659   1641     }
  1660         -  if( aStack[nos].flags & MEM_Null ){
         1642  +  if( pNos->flags & MEM_Null ){
  1661   1643       v2 = 2;
  1662   1644     }else{
  1663         -    Integerify(p, nos);
  1664         -    v2 = aStack[nos].i==0;
         1645  +    Integerify(pNos);
         1646  +    v2 = pNos->i==0;
  1665   1647     }
  1666   1648     if( pOp->opcode==OP_And ){
  1667   1649       static const unsigned char and_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 };
  1668   1650       v1 = and_logic[v1*3+v2];
  1669   1651     }else{
  1670   1652       static const unsigned char or_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 };
  1671   1653       v1 = or_logic[v1*3+v2];
  1672   1654     }
  1673         -  POPSTACK;
  1674         -  Release(p, nos);
         1655  +  popStack(&pTos, 2);
         1656  +  pTos++;
  1675   1657     if( v1==2 ){
  1676         -    aStack[nos].flags = MEM_Null;
         1658  +    pTos->flags = MEM_Null;
  1677   1659     }else{
  1678         -    aStack[nos].i = v1==0;
  1679         -    aStack[nos].flags = MEM_Int;
         1660  +    pTos->i = v1==0;
         1661  +    pTos->flags = MEM_Int;
  1680   1662     }
  1681   1663     break;
  1682   1664   }
  1683   1665   
  1684   1666   /* Opcode: Negative * * *
  1685   1667   **
  1686   1668   ** Treat the top of the stack as a numeric quantity.  Replace it
................................................................................
  1691   1673   **
  1692   1674   ** Treat the top of the stack as a numeric quantity.  Replace it
  1693   1675   ** with its absolute value. If the top of the stack is NULL
  1694   1676   ** its value is unchanged.
  1695   1677   */
  1696   1678   case OP_Negative:
  1697   1679   case OP_AbsValue: {
  1698         -  int tos = p->tos;
  1699         -  VERIFY( if( tos<0 ) goto not_enough_stack; )
  1700         -  if( aStack[tos].flags & MEM_Real ){
  1701         -    Release(p, tos);
  1702         -    if( pOp->opcode==OP_Negative || aStack[tos].r<0.0 ){
  1703         -      aStack[tos].r = -aStack[tos].r;
         1680  +  assert( pTos>=p->aStack );
         1681  +  if( pTos->flags & MEM_Real ){
         1682  +    Release(pTos);
         1683  +    if( pOp->opcode==OP_Negative || pTos->r<0.0 ){
         1684  +      pTos->r = -pTos->r;
  1704   1685       }
  1705         -    aStack[tos].flags = MEM_Real;
  1706         -  }else if( aStack[tos].flags & MEM_Int ){
  1707         -    Release(p, tos);
  1708         -    if( pOp->opcode==OP_Negative ||  aStack[tos].i<0 ){
  1709         -      aStack[tos].i = -aStack[tos].i;
         1686  +    pTos->flags = MEM_Real;
         1687  +  }else if( pTos->flags & MEM_Int ){
         1688  +    Release(pTos);
         1689  +    if( pOp->opcode==OP_Negative || pTos->i<0 ){
         1690  +      pTos->i = -pTos->i;
  1710   1691       }
  1711         -    aStack[tos].flags = MEM_Int;
  1712         -  }else if( aStack[tos].flags & MEM_Null ){
         1692  +    pTos->flags = MEM_Int;
         1693  +  }else if( pTos->flags & MEM_Null ){
  1713   1694       /* Do nothing */
  1714   1695     }else{
  1715         -    Realify(p, tos);
  1716         -    Release(p, tos);
  1717         -    if( pOp->opcode==OP_Negative ||  aStack[tos].r<0.0 ){
  1718         -      aStack[tos].r = -aStack[tos].r;
         1696  +    Realify(pTos);
         1697  +    Release(pTos);
         1698  +    if( pOp->opcode==OP_Negative || pTos->r<0.0 ){
         1699  +      pTos->r = -pTos->r;
  1719   1700       }
  1720         -    aStack[tos].flags = MEM_Real;
         1701  +    pTos->flags = MEM_Real;
  1721   1702     }
  1722   1703     break;
  1723   1704   }
  1724   1705   
  1725   1706   /* Opcode: Not * * *
  1726   1707   **
  1727   1708   ** Interpret the top of the stack as a boolean value.  Replace it
  1728   1709   ** with its complement.  If the top of the stack is NULL its value
  1729   1710   ** is unchanged.
  1730   1711   */
  1731   1712   case OP_Not: {
  1732         -  int tos = p->tos;
  1733         -  VERIFY( if( p->tos<0 ) goto not_enough_stack; )
  1734         -  if( aStack[tos].flags & MEM_Null ) break;  /* Do nothing to NULLs */
  1735         -  Integerify(p, tos);
  1736         -  Release(p, tos);
  1737         -  aStack[tos].i = !aStack[tos].i;
  1738         -  aStack[tos].flags = MEM_Int;
         1713  +  assert( pTos>=p->aStack );
         1714  +  if( pTos->flags & MEM_Null ) break;  /* Do nothing to NULLs */
         1715  +  Integerify(pTos);
         1716  +  assert( pTos->flags==MEM_Int );
         1717  +  pTos->i = !pTos->i;
  1739   1718     break;
  1740   1719   }
  1741   1720   
  1742   1721   /* Opcode: BitNot * * *
  1743   1722   **
  1744   1723   ** Interpret the top of the stack as an value.  Replace it
  1745   1724   ** with its ones-complement.  If the top of the stack is NULL its
  1746   1725   ** value is unchanged.
  1747   1726   */
  1748   1727   case OP_BitNot: {
  1749         -  int tos = p->tos;
  1750         -  VERIFY( if( p->tos<0 ) goto not_enough_stack; )
  1751         -  if( aStack[tos].flags & MEM_Null ) break;  /* Do nothing to NULLs */
  1752         -  Integerify(p, tos);
  1753         -  Release(p, tos);
  1754         -  aStack[tos].i = ~aStack[tos].i;
  1755         -  aStack[tos].flags = MEM_Int;
         1728  +  assert( pTos>=p->aStack );
         1729  +  if( pTos->flags & MEM_Null ) break;  /* Do nothing to NULLs */
         1730  +  Integerify(pTos);
         1731  +  assert( pTos->flags==MEM_Int );
         1732  +  pTos->i = ~pTos->i;
  1756   1733     break;
  1757   1734   }
  1758   1735   
  1759   1736   /* Opcode: Noop * * *
  1760   1737   **
  1761   1738   ** Do nothing.  This instruction is often useful as a jump
  1762   1739   ** destination.
................................................................................
  1784   1761   **
  1785   1762   ** If the value popped of the stack is NULL, then take the jump if P1
  1786   1763   ** is true and fall through if P1 is false.
  1787   1764   */
  1788   1765   case OP_If:
  1789   1766   case OP_IfNot: {
  1790   1767     int c;
  1791         -  VERIFY( if( p->tos<0 ) goto not_enough_stack; )
  1792         -  if( aStack[p->tos].flags & MEM_Null ){
         1768  +  assert( pTos>=p->aStack );
         1769  +  if( pTos->flags & MEM_Null ){
  1793   1770       c = pOp->p1;
  1794   1771     }else{
  1795         -    Integerify(p, p->tos);
  1796         -    c = aStack[p->tos].i;
         1772  +    Integerify(pTos);
         1773  +    c = pTos->i;
  1797   1774       if( pOp->opcode==OP_IfNot ) c = !c;
  1798   1775     }
  1799         -  POPSTACK;
         1776  +  assert( (pTos->flags & MEM_Dyn)==0 );
         1777  +  pTos--;
  1800   1778     if( c ) pc = pOp->p2-1;
  1801   1779     break;
  1802   1780   }
  1803   1781   
  1804   1782   /* Opcode: IsNull P1 P2 *
  1805   1783   **
  1806   1784   ** If any of the top abs(P1) values on the stack are NULL, then jump
  1807   1785   ** to P2.  Pop the stack P1 times if P1>0.   If P1<0 leave the stack
  1808   1786   ** unchanged.
  1809   1787   */
  1810   1788   case OP_IsNull: {
  1811   1789     int i, cnt;
         1790  +  Mem *pTerm;
  1812   1791     cnt = pOp->p1;
  1813   1792     if( cnt<0 ) cnt = -cnt;
  1814         -  VERIFY( if( p->tos+1-cnt<0 ) goto not_enough_stack; )
  1815         -  for(i=0; i<cnt; i++){
  1816         -    if( aStack[p->tos-i].flags & MEM_Null ){
         1793  +  pTerm = &pTos[1-cnt];
         1794  +  assert( pTerm>=p->aStack );
         1795  +  for(i=0; i<cnt; i++, pTerm++){
         1796  +    if( pTerm->flags & MEM_Null ){
  1817   1797         pc = pOp->p2-1;
  1818   1798         break;
  1819   1799       }
  1820   1800     }
  1821         -  if( pOp->p1>0 ) sqliteVdbePopStack(p, cnt);
         1801  +  if( pOp->p1>0 ) popStack(&pTos, cnt);
  1822   1802     break;
  1823   1803   }
  1824   1804   
  1825   1805   /* Opcode: NotNull P1 P2 *
  1826   1806   **
  1827   1807   ** Jump to P2 if the top P1 values on the stack are all not NULL.  Pop the
  1828   1808   ** stack if P1 times if P1 is greater than zero.  If P1 is less than
  1829   1809   ** zero then leave the stack unchanged.
  1830   1810   */
  1831   1811   case OP_NotNull: {
  1832   1812     int i, cnt;
  1833   1813     cnt = pOp->p1;
  1834   1814     if( cnt<0 ) cnt = -cnt;
  1835         -  VERIFY( if( p->tos+1-cnt<0 ) goto not_enough_stack; )
  1836         -  for(i=0; i<cnt && (aStack[p->tos-i].flags & MEM_Null)==0; i++){}
         1815  +  assert( &pTos[1-cnt] >= p->aStack );
         1816  +  for(i=0; i<cnt && (pTos[1+i-cnt].flags & MEM_Null)==0; i++){}
  1837   1817     if( i>=cnt ) pc = pOp->p2-1;
  1838         -  if( pOp->p1>0 ) sqliteVdbePopStack(p, cnt);
         1818  +  if( pOp->p1>0 ) popStack(&pTos, cnt);
  1839   1819     break;
  1840   1820   }
  1841   1821   
  1842   1822   /* Opcode: MakeRecord P1 P2 *
  1843   1823   **
  1844   1824   ** Convert the top P1 entries of the stack into a single entry
  1845   1825   ** suitable for use as a data record in a database table.  The
................................................................................
  1863   1843   case OP_MakeRecord: {
  1864   1844     char *zNewRecord;
  1865   1845     int nByte;
  1866   1846     int nField;
  1867   1847     int i, j;
  1868   1848     int idxWidth;
  1869   1849     u32 addr;
         1850  +  Mem *pRec;
  1870   1851     int addUnique = 0;   /* True to cause bytes to be added to make the
  1871   1852                          ** generated record distinct */
  1872   1853     char zTemp[NBFS];    /* Temp space for small records */
  1873   1854   
  1874   1855     /* Assuming the record contains N fields, the record format looks
  1875   1856     ** like this:
  1876   1857     **
................................................................................
  1886   1867     **
  1887   1868     ** Each of the idx() entries is either 1, 2, or 3 bytes depending on
  1888   1869     ** how big the total record is.  Idx(0) contains the offset to the start
  1889   1870     ** of data(0).  Idx(k) contains the offset to the start of data(k).
  1890   1871     ** Idx(N) contains the total number of bytes in the record.
  1891   1872     */
  1892   1873     nField = pOp->p1;
  1893         -  VERIFY( if( p->tos+1<nField ) goto not_enough_stack; )
         1874  +  pRec = &pTos[1-nField];
         1875  +  assert( pRec>=p->aStack );
  1894   1876     nByte = 0;
  1895         -  for(i=p->tos-nField+1; i<=p->tos; i++){
  1896         -    if( (aStack[i].flags & MEM_Null) ){
         1877  +  for(i=0; i<nField; i++, pRec++){
         1878  +    if( pRec->flags & MEM_Null ){
  1897   1879         addUnique = pOp->p2;
  1898   1880       }else{
  1899         -      Stringify(p, i);
  1900         -      nByte += aStack[i].n;
         1881  +      Stringify(pRec);
         1882  +      nByte += pRec->n;
  1901   1883       }
  1902   1884     }
  1903   1885     if( addUnique ) nByte += sizeof(p->uniqueCnt);
  1904   1886     if( nByte + nField + 1 < 256 ){
  1905   1887       idxWidth = 1;
  1906   1888     }else if( nByte + 2*nField + 2 < 65536 ){
  1907   1889       idxWidth = 2;
................................................................................
  1917   1899       zNewRecord = zTemp;
  1918   1900     }else{
  1919   1901       zNewRecord = sqliteMallocRaw( nByte );
  1920   1902       if( zNewRecord==0 ) goto no_mem;
  1921   1903     }
  1922   1904     j = 0;
  1923   1905     addr = idxWidth*(nField+1) + addUnique*sizeof(p->uniqueCnt);
  1924         -  for(i=p->tos-nField+1; i<=p->tos; i++){
         1906  +  for(i=0, pRec=&pTos[1-nField]; i<nField; i++, pRec++){
  1925   1907       zNewRecord[j++] = addr & 0xff;
  1926   1908       if( idxWidth>1 ){
  1927   1909         zNewRecord[j++] = (addr>>8)&0xff;
  1928   1910         if( idxWidth>2 ){
  1929   1911           zNewRecord[j++] = (addr>>16)&0xff;
  1930   1912         }
  1931   1913       }
  1932         -    if( (aStack[i].flags & MEM_Null)==0 ){
  1933         -      addr += aStack[i].n;
         1914  +    if( (pRec->flags & MEM_Null)==0 ){
         1915  +      addr += pRec->n;
  1934   1916       }
  1935   1917     }
  1936   1918     zNewRecord[j++] = addr & 0xff;
  1937   1919     if( idxWidth>1 ){
  1938   1920       zNewRecord[j++] = (addr>>8)&0xff;
  1939   1921       if( idxWidth>2 ){
  1940   1922         zNewRecord[j++] = (addr>>16)&0xff;
................................................................................
  1941   1923       }
  1942   1924     }
  1943   1925     if( addUnique ){
  1944   1926       memcpy(&zNewRecord[j], &p->uniqueCnt, sizeof(p->uniqueCnt));
  1945   1927       p->uniqueCnt++;
  1946   1928       j += sizeof(p->uniqueCnt);
  1947   1929     }
  1948         -  for(i=p->tos-nField+1; i<=p->tos; i++){
  1949         -    if( (aStack[i].flags & MEM_Null)==0 ){
  1950         -      memcpy(&zNewRecord[j], aStack[i].z, aStack[i].n);
  1951         -      j += aStack[i].n;
         1930  +  for(i=0, pRec=&pTos[1-nField]; i<nField; i++, pRec++){
         1931  +    if( (pRec->flags & MEM_Null)==0 ){
         1932  +      memcpy(&zNewRecord[j], pRec->z, pRec->n);
         1933  +      j += pRec->n;
  1952   1934       }
  1953   1935     }
  1954         -  sqliteVdbePopStack(p, nField);
  1955         -  p->tos++;
  1956         -  aStack[p->tos].n = nByte;
         1936  +  popStack(&pTos, nField);
         1937  +  pTos++;
         1938  +  pTos->n = nByte;
  1957   1939     if( nByte<=NBFS ){
  1958   1940       assert( zNewRecord==zTemp );
  1959         -    memcpy(aStack[p->tos].zShort, zTemp, nByte);
  1960         -    aStack[p->tos].z = aStack[p->tos].zShort;
  1961         -    aStack[p->tos].flags = MEM_Str;
         1941  +    memcpy(pTos->zShort, zTemp, nByte);
         1942  +    pTos->z = pTos->zShort;
         1943  +    pTos->flags = MEM_Str | MEM_Short;
  1962   1944     }else{
  1963   1945       assert( zNewRecord!=zTemp );
  1964         -    aStack[p->tos].flags = MEM_Str | MEM_Dyn;
  1965         -    aStack[p->tos].z = zNewRecord;
         1946  +    pTos->z = zNewRecord;
         1947  +    pTos->flags = MEM_Str | MEM_Dyn;
  1966   1948     }
  1967   1949     break;
  1968   1950   }
  1969   1951   
  1970   1952   /* Opcode: MakeKey P1 P2 P3
  1971   1953   **
  1972   1954   ** Convert the top P1 entries of the stack into a single entry suitable
................................................................................
  2043   2025   case OP_MakeKey: {
  2044   2026     char *zNewKey;
  2045   2027     int nByte;
  2046   2028     int nField;
  2047   2029     int addRowid;
  2048   2030     int i, j;
  2049   2031     int containsNull = 0;
         2032  +  Mem *pRec;
  2050   2033     char zTemp[NBFS];
  2051   2034   
  2052   2035     addRowid = pOp->opcode==OP_MakeIdxKey;
  2053   2036     nField = pOp->p1;
  2054         -  VERIFY( if( p->tos+1+addRowid<nField ) goto not_enough_stack; )
         2037  +  pRec = &pTos[1-nField];
         2038  +  assert( pRec>=p->aStack );
  2055   2039     nByte = 0;
  2056         -  for(j=0, i=p->tos-nField+1; i<=p->tos; i++, j++){
  2057         -    int flags = aStack[i].flags;
         2040  +  for(j=0, i=0; i<nField; i++, j++, pRec++){
         2041  +    int flags = pRec->flags;
  2058   2042       int len;
  2059   2043       char *z;
  2060   2044       if( flags & MEM_Null ){
  2061   2045         nByte += 2;
  2062   2046         containsNull = 1;
  2063   2047       }else if( pOp->p3 && pOp->p3[j]=='t' ){
  2064         -      Stringify(p, i);
  2065         -      aStack[i].flags &= ~(MEM_Int|MEM_Real);
  2066         -      nByte += aStack[i].n+1;
  2067         -    }else if( (flags & (MEM_Real|MEM_Int))!=0 || sqliteIsNumber(aStack[i].z) ){
         2048  +      Stringify(pRec);
         2049  +      pRec->flags &= ~(MEM_Int|MEM_Real);
         2050  +      nByte += pRec->n+1;
         2051  +    }else if( (flags & (MEM_Real|MEM_Int))!=0 || sqliteIsNumber(pRec->z) ){
  2068   2052         if( (flags & (MEM_Real|MEM_Int))==MEM_Int ){
  2069         -        aStack[i].r = aStack[i].i;
         2053  +        pRec->r = pRec->i;
  2070   2054         }else if( (flags & (MEM_Real|MEM_Int))==0 ){
  2071         -        aStack[i].r = sqliteAtoF(aStack[i].z);
         2055  +        pRec->r = sqliteAtoF(pRec->z);
  2072   2056         }
  2073         -      Release(p, i);
  2074         -      z = aStack[i].zShort;
  2075         -      sqliteRealToSortable(aStack[i].r, z);
         2057  +      Release(pRec);
         2058  +      z = pRec->zShort;
         2059  +      sqliteRealToSortable(pRec->r, z);
  2076   2060         len = strlen(z);
  2077         -      aStack[i].z = 0;
  2078         -      aStack[i].flags = MEM_Real;
  2079         -      aStack[i].n = len+1;
  2080         -      nByte += aStack[i].n+1;
         2061  +      pRec->z = 0;
         2062  +      pRec->flags = MEM_Real;
         2063  +      pRec->n = len+1;
         2064  +      nByte += pRec->n+1;
  2081   2065       }else{
  2082         -      nByte += aStack[i].n+1;
         2066  +      nByte += pRec->n+1;
  2083   2067       }
  2084   2068     }
  2085   2069     if( nByte+sizeof(u32)>MAX_BYTES_PER_ROW ){
  2086   2070       rc = SQLITE_TOOBIG;
  2087   2071       goto abort_due_to_error;
  2088   2072     }
  2089   2073     if( addRowid ) nByte += sizeof(u32);
................................................................................
  2090   2074     if( nByte<=NBFS ){
  2091   2075       zNewKey = zTemp;
  2092   2076     }else{
  2093   2077       zNewKey = sqliteMallocRaw( nByte );
  2094   2078       if( zNewKey==0 ) goto no_mem;
  2095   2079     }
  2096   2080     j = 0;
  2097         -  for(i=p->tos-nField+1; i<=p->tos; i++){
  2098         -    if( aStack[i].flags & MEM_Null ){
         2081  +  pRec = &pTos[1-nField];
         2082  +  for(i=0; i<nField; i++, pRec++){
         2083  +    if( pRec->flags & MEM_Null ){
  2099   2084         zNewKey[j++] = 'a';
  2100   2085         zNewKey[j++] = 0;
         2086  +    }else if( pRec->flags==MEM_Real ){
         2087  +      zNewKey[j++] = 'b';
         2088  +      memcpy(&zNewKey[j], pRec->zShort, pRec->n);
         2089  +      j += pRec->n;
  2101   2090       }else{
  2102         -      if( aStack[i].flags & (MEM_Int|MEM_Real) ){
  2103         -        zNewKey[j++] = 'b';
  2104         -      }else{
  2105         -        zNewKey[j++] = 'c';
  2106         -      }
  2107         -      /*** Is this right? ****/
  2108         -      memcpy(&zNewKey[j],aStack[i].z?aStack[i].z:aStack[i].zShort,aStack[i].n);
  2109         -      j += aStack[i].n;
         2091  +      assert( pRec->flags & MEM_Str );
         2092  +      zNewKey[j++] = 'c';
         2093  +      memcpy(&zNewKey[j], pRec->z, pRec->n);
         2094  +      j += pRec->n;
  2110   2095       }
  2111   2096     }
  2112   2097     if( addRowid ){
  2113   2098       u32 iKey;
  2114         -    Integerify(p, p->tos-nField);
  2115         -    iKey = intToKey(aStack[p->tos-nField].i);
         2099  +    pRec = &pTos[-nField];
         2100  +    assert( pRec>=p->aStack );
         2101  +    Integerify(pRec);
         2102  +    iKey = intToKey(pRec->i);
  2116   2103       memcpy(&zNewKey[j], &iKey, sizeof(u32));
  2117         -    sqliteVdbePopStack(p, nField+1);
         2104  +    popStack(&pTos, nField+1);
  2118   2105       if( pOp->p2 && containsNull ) pc = pOp->p2 - 1;
  2119   2106     }else{
  2120         -    if( pOp->p2==0 ) sqliteVdbePopStack(p, nField+addRowid);
         2107  +    if( pOp->p2==0 ) popStack(&pTos, nField);
  2121   2108     }
  2122         -  p->tos++;
  2123         -  aStack[p->tos].n = nByte;
         2109  +  pTos++;
         2110  +  pTos->n = nByte;
  2124   2111     if( nByte<=NBFS ){
  2125   2112       assert( zNewKey==zTemp );
  2126         -    aStack[p->tos].z = aStack[p->tos].zShort;
  2127         -    memcpy(aStack[p->tos].z, zTemp, nByte);
  2128         -    aStack[p->tos].flags = MEM_Str;
         2113  +    pTos->z = pTos->zShort;
         2114  +    memcpy(pTos->zShort, zTemp, nByte);
         2115  +    pTos->flags = MEM_Str | MEM_Short;
  2129   2116     }else{
  2130         -    aStack[p->tos].flags = MEM_Str|MEM_Dyn;
  2131         -    aStack[p->tos].z = zNewKey;
         2117  +    pTos->z = zNewKey;
         2118  +    pTos->flags = MEM_Str | MEM_Dyn;
  2132   2119     }
  2133   2120     break;
  2134   2121   }
  2135   2122   
  2136   2123   /* Opcode: IncrKey * * *
  2137   2124   **
  2138   2125   ** The top of the stack should contain an index key generated by
  2139   2126   ** The MakeKey opcode.  This routine increases the least significant
  2140   2127   ** byte of that key by one.  This is used so that the MoveTo opcode
  2141   2128   ** will move to the first entry greater than the key rather than to
  2142   2129   ** the key itself.
  2143   2130   */
  2144   2131   case OP_IncrKey: {
  2145         -  int tos = p->tos;
  2146         -
  2147         -  VERIFY( if( tos<0 ) goto bad_instruction );
  2148         -  Stringify(p, tos);
  2149         -  if( aStack[tos].flags & (MEM_Static|MEM_Ephem) ){
  2150         -    /* CANT HAPPEN.  The IncrKey opcode is only applied to keys
  2151         -    ** generated by MakeKey or MakeIdxKey and the results of those
  2152         -    ** operands are always dynamic strings.
  2153         -    */
  2154         -    goto abort_due_to_error;
  2155         -  }
  2156         -  aStack[tos].z[aStack[tos].n-1]++;
         2132  +  assert( pTos>=p->aStack );
         2133  +  /* The IncrKey opcode is only applied to keys generated by
         2134  +  ** MakeKey or MakeIdxKey and the results of those operands
         2135  +  ** are always dynamic strings or zShort[] strings.  So we
         2136  +  ** are always free to modify the string in place.
         2137  +  */
         2138  +  assert( pTos->flags & (MEM_Dyn|MEM_Short) );
         2139  +  pTos->z[pTos->n-1]++;
  2157   2140     break;
  2158   2141   }
  2159   2142   
  2160   2143   /* Opcode: Checkpoint P1 * *
  2161   2144   **
  2162   2145   ** Begin a checkpoint.  A checkpoint is the beginning of a operation that
  2163   2146   ** is part of a larger transaction but which might need to be rolled back
................................................................................
  2202   2185       rc = sqliteBtreeBeginTrans(db->aDb[i].pBt);
  2203   2186       switch( rc ){
  2204   2187         case SQLITE_BUSY: {
  2205   2188           if( db->xBusyCallback==0 ){
  2206   2189             p->pc = pc;
  2207   2190             p->undoTransOnError = 1;
  2208   2191             p->rc = SQLITE_BUSY;
         2192  +          p->pTos = pTos;
  2209   2193             return SQLITE_BUSY;
  2210   2194           }else if( (*db->xBusyCallback)(db->pBusyArg, "", busy++)==0 ){
  2211   2195             sqliteSetString(&p->zErrMsg, sqlite_error_string(rc), (char*)0);
  2212   2196             busy = 0;
  2213   2197           }
  2214   2198           break;
  2215   2199         }
................................................................................
  2291   2275   ** temporary tables.
  2292   2276   **
  2293   2277   ** There must be a read-lock on the database (either a transaction
  2294   2278   ** must be started or there must be an open cursor) before
  2295   2279   ** executing this instruction.
  2296   2280   */
  2297   2281   case OP_ReadCookie: {
  2298         -  int i = ++p->tos;
  2299   2282     int aMeta[SQLITE_N_BTREE_META];
  2300   2283     assert( pOp->p2<SQLITE_N_BTREE_META );
  2301   2284     assert( pOp->p1>=0 && pOp->p1<db->nDb );
  2302   2285     assert( db->aDb[pOp->p1].pBt!=0 );
  2303   2286     rc = sqliteBtreeGetMeta(db->aDb[pOp->p1].pBt, aMeta);
  2304         -  aStack[i].i = aMeta[1+pOp->p2];
  2305         -  aStack[i].flags = MEM_Int;
         2287  +  pTos++;
         2288  +  pTos->i = aMeta[1+pOp->p2];
         2289  +  pTos->flags = MEM_Int;
  2306   2290     break;
  2307   2291   }
  2308   2292   
  2309   2293   /* Opcode: SetCookie P1 P2 *
  2310   2294   **
  2311   2295   ** Write the top of the stack into cookie number P2 of database P1.
  2312   2296   ** P2==0 is the schema version.  P2==1 is the database format.
................................................................................
  2317   2301   ** A transaction must be started before executing this opcode.
  2318   2302   */
  2319   2303   case OP_SetCookie: {
  2320   2304     int aMeta[SQLITE_N_BTREE_META];
  2321   2305     assert( pOp->p2<SQLITE_N_BTREE_META );
  2322   2306     assert( pOp->p1>=0 && pOp->p1<db->nDb );
  2323   2307     assert( db->aDb[pOp->p1].pBt!=0 );
  2324         -  VERIFY( if( p->tos<0 ) goto not_enough_stack; )
  2325         -  Integerify(p, p->tos)
         2308  +  assert( pTos>=p->aStack );
         2309  +  Integerify(pTos)
  2326   2310     rc = sqliteBtreeGetMeta(db->aDb[pOp->p1].pBt, aMeta);
  2327   2311     if( rc==SQLITE_OK ){
  2328         -    aMeta[1+pOp->p2] = aStack[p->tos].i;
         2312  +    aMeta[1+pOp->p2] = pTos->i;
  2329   2313       rc = sqliteBtreeUpdateMeta(db->aDb[pOp->p1].pBt, aMeta);
  2330   2314     }
  2331         -  POPSTACK;
         2315  +  assert( pTos->flags==MEM_Int );
         2316  +  pTos--;
  2332   2317     break;
  2333   2318   }
  2334   2319   
  2335   2320   /* Opcode: VerifyCookie P1 P2 *
  2336   2321   **
  2337   2322   ** Check the value of global database parameter number 0 (the
  2338   2323   ** schema version) and make sure it is equal to P2.  
................................................................................
  2403   2388   **
  2404   2389   ** See also OpenRead.
  2405   2390   */
  2406   2391   case OP_OpenRead:
  2407   2392   case OP_OpenWrite: {
  2408   2393     int busy = 0;
  2409   2394     int i = pOp->p1;
  2410         -  int tos = p->tos;
  2411   2395     int p2 = pOp->p2;
  2412   2396     int wrFlag;
  2413   2397     Btree *pX;
  2414   2398     int iDb;
  2415   2399     
  2416         -  VERIFY( if( tos<0 ) goto not_enough_stack; );
  2417         -  Integerify(p, tos);
  2418         -  iDb = p->aStack[tos].i;
  2419         -  tos--;
  2420         -  VERIFY( if( iDb<0 || iDb>=db->nDb ) goto bad_instruction; );
  2421         -  VERIFY( if( db->aDb[iDb].pBt==0 ) goto bad_instruction; );
         2400  +  assert( pTos>=p->aStack );
         2401  +  Integerify(pTos);
         2402  +  iDb = pTos->i;
         2403  +  pTos--;
         2404  +  assert( iDb>=0 && iDb<db->nDb );
  2422   2405     pX = db->aDb[iDb].pBt;
         2406  +  assert( pX!=0 );
  2423   2407     wrFlag = pOp->opcode==OP_OpenWrite;
  2424   2408     if( p2<=0 ){
  2425         -    VERIFY( if( tos<0 ) goto not_enough_stack; );
  2426         -    Integerify(p, tos);
  2427         -    p2 = p->aStack[tos].i;
  2428         -    POPSTACK;
         2409  +    assert( pTos>=p->aStack );
         2410  +    Integerify(pTos);
         2411  +    p2 = pTos->i;
         2412  +    pTos--;
  2429   2413       if( p2<2 ){
  2430   2414         sqliteSetString(&p->zErrMsg, "root page number less than 2", (char*)0);
  2431   2415         rc = SQLITE_INTERNAL;
  2432   2416         break;
  2433   2417       }
  2434   2418     }
  2435         -  VERIFY( if( i<0 ) goto bad_instruction; )
         2419  +  assert( i>=0 );
  2436   2420     if( expandCursorArraySize(p, i) ) goto no_mem;
  2437   2421     sqliteVdbeCleanupCursor(&p->aCsr[i]);
  2438   2422     memset(&p->aCsr[i], 0, sizeof(Cursor));
  2439   2423     p->aCsr[i].nullRow = 1;
  2440   2424     if( pX==0 ) break;
  2441   2425     do{
  2442   2426       rc = sqliteBtreeCursor(pX, p2, wrFlag, &p->aCsr[i].pCursor);
  2443   2427       switch( rc ){
  2444   2428         case SQLITE_BUSY: {
  2445   2429           if( db->xBusyCallback==0 ){
  2446   2430             p->pc = pc;
  2447   2431             p->rc = SQLITE_BUSY;
         2432  +          p->pTos = &pTos[1 + (pOp->p2<=0)]; /* Operands must remain on stack */
  2448   2433             return SQLITE_BUSY;
  2449   2434           }else if( (*db->xBusyCallback)(db->pBusyArg, pOp->p3, ++busy)==0 ){
  2450   2435             sqliteSetString(&p->zErrMsg, sqlite_error_string(rc), (char*)0);
  2451   2436             busy = 0;
  2452   2437           }
  2453   2438           break;
  2454   2439         }
................................................................................
  2457   2442           break;
  2458   2443         }
  2459   2444         default: {
  2460   2445           goto abort_due_to_error;
  2461   2446         }
  2462   2447       }
  2463   2448     }while( busy );
  2464         -  if( p2<=0 ){
  2465         -    POPSTACK;
  2466         -  }
  2467         -  POPSTACK;
  2468   2449     break;
  2469   2450   }
  2470   2451   
  2471   2452   /* Opcode: OpenTemp P1 P2 *
  2472   2453   **
  2473   2454   ** Open a new cursor to a transient table.
  2474   2455   ** The transient cursor is always opened read/write even if 
................................................................................
  2485   2466   ** context of this opcode means for the duration of a single SQL statement
  2486   2467   ** whereas "Temporary" in the context of CREATE TABLE means for the duration
  2487   2468   ** of the connection to the database.  Same word; different meanings.
  2488   2469   */
  2489   2470   case OP_OpenTemp: {
  2490   2471     int i = pOp->p1;
  2491   2472     Cursor *pCx;
  2492         -  VERIFY( if( i<0 ) goto bad_instruction; )
         2473  +  assert( i>=0 );
  2493   2474     if( expandCursorArraySize(p, i) ) goto no_mem;
  2494   2475     pCx = &p->aCsr[i];
  2495   2476     sqliteVdbeCleanupCursor(pCx);
  2496   2477     memset(pCx, 0, sizeof(*pCx));
  2497   2478     pCx->nullRow = 1;
  2498   2479     rc = sqliteBtreeFactory(db, 0, 1, TEMP_PAGES, &pCx->pBt);
  2499   2480   
................................................................................
  2523   2504   **
  2524   2505   ** A pseudo-table created by this opcode is useful for holding the
  2525   2506   ** NEW or OLD tables in a trigger.
  2526   2507   */
  2527   2508   case OP_OpenPseudo: {
  2528   2509     int i = pOp->p1;
  2529   2510     Cursor *pCx;
  2530         -  VERIFY( if( i<0 ) goto bad_instruction; )
         2511  +  assert( i>=0 );
  2531   2512     if( expandCursorArraySize(p, i) ) goto no_mem;
  2532   2513     pCx = &p->aCsr[i];
  2533   2514     sqliteVdbeCleanupCursor(pCx);
  2534   2515     memset(pCx, 0, sizeof(*pCx));
  2535   2516     pCx->nullRow = 1;
  2536   2517     pCx->pseudoTable = 1;
  2537   2518     break;
................................................................................
  2570   2551   ** is not zero then an immediate jump to P2 is made.
  2571   2552   **
  2572   2553   ** See also: MoveTo
  2573   2554   */
  2574   2555   case OP_MoveLt:
  2575   2556   case OP_MoveTo: {
  2576   2557     int i = pOp->p1;
  2577         -  int tos = p->tos;
  2578   2558     Cursor *pC;
  2579   2559   
  2580         -  VERIFY( if( tos<0 ) goto not_enough_stack; )
         2560  +  assert( pTos>=p->aStack );
  2581   2561     assert( i>=0 && i<p->nCursor );
  2582   2562     pC = &p->aCsr[i];
  2583   2563     if( pC->pCursor!=0 ){
  2584   2564       int res, oc;
  2585   2565       pC->nullRow = 0;
  2586         -    if( aStack[tos].flags & MEM_Int ){
  2587         -      int iKey = intToKey(aStack[tos].i);
         2566  +    if( pTos->flags & MEM_Int ){
         2567  +      int iKey = intToKey(pTos->i);
  2588   2568         if( pOp->p2==0 && pOp->opcode==OP_MoveTo ){
  2589   2569           pC->movetoTarget = iKey;
  2590   2570           pC->deferredMoveto = 1;
  2591         -        POPSTACK;
         2571  +        Release(pTos);
         2572  +        pTos--;
  2592   2573           break;
  2593   2574         }
  2594   2575         sqliteBtreeMoveto(pC->pCursor, (char*)&iKey, sizeof(int), &res);
  2595         -      pC->lastRecno = aStack[tos].i;
         2576  +      pC->lastRecno = pTos->i;
  2596   2577         pC->recnoIsValid = res==0;
  2597   2578       }else{
  2598         -      Stringify(p, tos);
  2599         -      sqliteBtreeMoveto(pC->pCursor, aStack[tos].z, aStack[tos].n, &res);
         2579  +      Stringify(pTos);
         2580  +      sqliteBtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
  2600   2581         pC->recnoIsValid = 0;
  2601   2582       }
  2602   2583       pC->deferredMoveto = 0;
  2603   2584       sqlite_search_count++;
  2604   2585       oc = pOp->opcode;
  2605   2586       if( oc==OP_MoveTo && res<0 ){
  2606   2587         sqliteBtreeNext(pC->pCursor, &res);
................................................................................
  2620   2601           res = sqliteBtreeKeySize(pC->pCursor,&keysize)!=0 || keysize==0;
  2621   2602         }
  2622   2603         if( res && pOp->p2>0 ){
  2623   2604           pc = pOp->p2 - 1;
  2624   2605         }
  2625   2606       }
  2626   2607     }
  2627         -  POPSTACK;
         2608  +  Release(pTos);
         2609  +  pTos--;
  2628   2610     break;
  2629   2611   }
  2630   2612   
  2631   2613   /* Opcode: Distinct P1 P2 *
  2632   2614   **
  2633   2615   ** Use the top of the stack as a string key.  If a record with that key does
  2634   2616   ** not exist in the table of cursor P1, then jump to P2.  If the record
................................................................................
  2661   2643   **
  2662   2644   ** See also: Distinct, Found, MoveTo, NotExists, IsUnique
  2663   2645   */
  2664   2646   case OP_Distinct:
  2665   2647   case OP_NotFound:
  2666   2648   case OP_Found: {
  2667   2649     int i = pOp->p1;
  2668         -  int tos = p->tos;
  2669   2650     int alreadyExists = 0;
  2670   2651     Cursor *pC;
  2671         -  VERIFY( if( tos<0 ) goto not_enough_stack; )
  2672         -  if( VERIFY( i>=0 && i<p->nCursor && ) (pC = &p->aCsr[i])->pCursor!=0 ){
         2652  +  assert( pTos>=p->aStack );
         2653  +  assert( i>=0 && i<p->nCursor );
         2654  +  if( (pC = &p->aCsr[i])->pCursor!=0 ){
  2673   2655       int res, rx;
  2674         -    Stringify(p, tos);
  2675         -    rx = sqliteBtreeMoveto(pC->pCursor, aStack[tos].z, aStack[tos].n, &res);
         2656  +    Stringify(pTos);
         2657  +    rx = sqliteBtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
  2676   2658       alreadyExists = rx==SQLITE_OK && res==0;
  2677   2659       pC->deferredMoveto = 0;
  2678   2660     }
  2679   2661     if( pOp->opcode==OP_Found ){
  2680   2662       if( alreadyExists ) pc = pOp->p2 - 1;
  2681   2663     }else{
  2682   2664       if( !alreadyExists ) pc = pOp->p2 - 1;
  2683   2665     }
  2684   2666     if( pOp->opcode!=OP_Distinct ){
  2685         -    POPSTACK;
         2667  +    Release(pTos);
         2668  +    pTos--;
  2686   2669     }
  2687   2670     break;
  2688   2671   }
  2689   2672   
  2690   2673   /* Opcode: IsUnique P1 P2 *
  2691   2674   **
  2692   2675   ** The top of the stack is an integer record number.  Call this
................................................................................
  2705   2688   ** number for that entry is pushed onto the stack and control
  2706   2689   ** falls through to the next instruction.
  2707   2690   **
  2708   2691   ** See also: Distinct, NotFound, NotExists, Found
  2709   2692   */
  2710   2693   case OP_IsUnique: {
  2711   2694     int i = pOp->p1;
  2712         -  int tos = p->tos;
  2713         -  int nos = tos-1;
         2695  +  Mem *pNos = &pTos[-1];
  2714   2696     BtCursor *pCrsr;
  2715   2697     int R;
  2716   2698   
  2717   2699     /* Pop the value R off the top of the stack
  2718   2700     */
  2719         -  VERIFY( if( nos<0 ) goto not_enough_stack; )
  2720         -  Integerify(p, tos);
  2721         -  R = aStack[tos].i;   
  2722         -  POPSTACK;
  2723         -  if( VERIFY( i>=0 && i<p->nCursor && ) (pCrsr = p->aCsr[i].pCursor)!=0 ){
         2701  +  assert( pNos>=p->aStack );
         2702  +  Integerify(pTos);
         2703  +  R = pTos->i;
         2704  +  pTos--;
         2705  +  assert( i>=0 && i<=p->nCursor );
         2706  +  if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
  2724   2707       int res, rc;
  2725   2708       int v;         /* The record number on the P1 entry that matches K */
  2726   2709       char *zKey;    /* The value of K */
  2727   2710       int nKey;      /* Number of bytes in K */
  2728   2711   
  2729   2712       /* Make sure K is a string and make zKey point to K
  2730   2713       */
  2731         -    Stringify(p, nos);
  2732         -    zKey = aStack[nos].z;
  2733         -    nKey = aStack[nos].n;
         2714  +    Stringify(pNos);
         2715  +    zKey = pNos->z;
         2716  +    nKey = pNos->n;
  2734   2717       assert( nKey >= 4 );
  2735   2718   
  2736   2719       /* Search for an entry in P1 where all but the last four bytes match K.
  2737   2720       ** If there is no such entry, jump immediately to P2.
  2738   2721       */
  2739   2722       assert( p->aCsr[i].deferredMoveto==0 );
  2740   2723       rc = sqliteBtreeMoveto(pCrsr, zKey, nKey-4, &res);
................................................................................
  2766   2749       }
  2767   2750   
  2768   2751       /* The last four bytes of the key are different from R.  Convert the
  2769   2752       ** last four bytes of the key into an integer and push it onto the
  2770   2753       ** stack.  (These bytes are the record number of an entry that
  2771   2754       ** violates a UNIQUE constraint.)
  2772   2755       */
  2773         -    p->tos++;
  2774         -    aStack[tos].i = v;
  2775         -    aStack[tos].flags = MEM_Int;
         2756  +    pTos++;
         2757  +    pTos->i = v;
         2758  +    pTos->flags = MEM_Int;
  2776   2759     }
  2777   2760     break;
  2778   2761   }
  2779   2762   
  2780   2763   /* Opcode: NotExists P1 P2 *
  2781   2764   **
  2782   2765   ** Use the top of the stack as a integer key.  If a record with that key
................................................................................
  2788   2771   ** operation assumes the key is an integer and NotFound assumes it
  2789   2772   ** is a string.
  2790   2773   **
  2791   2774   ** See also: Distinct, Found, MoveTo, NotFound, IsUnique
  2792   2775   */
  2793   2776   case OP_NotExists: {
  2794   2777     int i = pOp->p1;
  2795         -  int tos = p->tos;
  2796   2778     BtCursor *pCrsr;
  2797         -  VERIFY( if( tos<0 ) goto not_enough_stack; )
  2798         -  if( VERIFY( i>=0 && i<p->nCursor && ) (pCrsr = p->aCsr[i].pCursor)!=0 ){
         2779  +  assert( pTos>=p->aStack );
         2780  +  assert( i>=0 && i<p->nCursor );
         2781  +  if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
  2799   2782       int res, rx, iKey;
  2800         -    assert( aStack[tos].flags & MEM_Int );
  2801         -    iKey = intToKey(aStack[tos].i);
         2783  +    assert( pTos->flags & MEM_Int );
         2784  +    iKey = intToKey(pTos->i);
  2802   2785       rx = sqliteBtreeMoveto(pCrsr, (char*)&iKey, sizeof(int), &res);
  2803         -    p->aCsr[i].lastRecno = aStack[tos].i;
         2786  +    p->aCsr[i].lastRecno = pTos->i;
  2804   2787       p->aCsr[i].recnoIsValid = res==0;
  2805   2788       p->aCsr[i].nullRow = 0;
  2806   2789       if( rx!=SQLITE_OK || res!=0 ){
  2807   2790         pc = pOp->p2 - 1;
  2808   2791         p->aCsr[i].recnoIsValid = 0;
  2809   2792       }
  2810   2793     }
  2811         -  POPSTACK;
         2794  +  Release(pTos);
         2795  +  pTos--;
  2812   2796     break;
  2813   2797   }
  2814   2798   
  2815   2799   /* Opcode: NewRecno P1 * *
  2816   2800   **
  2817   2801   ** Get a new integer record number used as the key to a table.
  2818   2802   ** The record number is not previously used as a key in the database
................................................................................
  2819   2803   ** table that cursor P1 points to.  The new record number is pushed 
  2820   2804   ** onto the stack.
  2821   2805   */
  2822   2806   case OP_NewRecno: {
  2823   2807     int i = pOp->p1;
  2824   2808     int v = 0;
  2825   2809     Cursor *pC;
  2826         -  if( VERIFY( i<0 || i>=p->nCursor || ) (pC = &p->aCsr[i])->pCursor==0 ){
         2810  +  assert( i>=0 && i<p->nCursor );
         2811  +  if( (pC = &p->aCsr[i])->pCursor==0 ){
  2827   2812       v = 0;
  2828   2813     }else{
  2829   2814       /* The next rowid or record number (different terms for the same
  2830   2815       ** thing) is obtained in a two-step algorithm.
  2831   2816       **
  2832   2817       ** First we attempt to find the largest existing rowid and add one
  2833   2818       ** to that.  But if the largest existing rowid is already the maximum
................................................................................
  2903   2888           rc = SQLITE_FULL;
  2904   2889           goto abort_due_to_error;
  2905   2890         }
  2906   2891       }
  2907   2892       pC->recnoIsValid = 0;
  2908   2893       pC->deferredMoveto = 0;
  2909   2894     }
  2910         -  p->tos++;
  2911         -  aStack[p->tos].i = v;
  2912         -  aStack[p->tos].flags = MEM_Int;
         2895  +  pTos++;
         2896  +  pTos->i = v;
         2897  +  pTos->flags = MEM_Int;
  2913   2898     break;
  2914   2899   }
  2915   2900   
  2916   2901   /* Opcode: PutIntKey P1 P2 *
  2917   2902   **
  2918   2903   ** Write an entry into the table of cursor P1.  A new entry is
  2919   2904   ** created if it doesn't already exist or the data for an existing
................................................................................
  2933   2918   ** stack.  The key is the next value down on the stack.  The key must
  2934   2919   ** be a string.  The stack is popped twice by this instruction.
  2935   2920   **
  2936   2921   ** P1 may not be a pseudo-table opened using the OpenPseudo opcode.
  2937   2922   */
  2938   2923   case OP_PutIntKey:
  2939   2924   case OP_PutStrKey: {
  2940         -  int tos = p->tos;
  2941         -  int nos = p->tos-1;
         2925  +  Mem *pNos = &pTos[-1];
  2942   2926     int i = pOp->p1;
  2943   2927     Cursor *pC;
  2944         -  VERIFY( if( nos<0 ) goto not_enough_stack; )
  2945         -  if( VERIFY( i>=0 && i<p->nCursor && )
  2946         -      ((pC = &p->aCsr[i])->pCursor!=0 || pC->pseudoTable) ){
         2928  +  assert( pNos>=p->aStack );
         2929  +  assert( i>=0 && i<p->nCursor );
         2930  +  if( ((pC = &p->aCsr[i])->pCursor!=0 || pC->pseudoTable) ){
  2947   2931       char *zKey;
  2948   2932       int nKey, iKey;
  2949   2933       if( pOp->opcode==OP_PutStrKey ){
  2950         -      Stringify(p, nos);
  2951         -      nKey = aStack[nos].n;
  2952         -      zKey = aStack[nos].z;
         2934  +      Stringify(pNos);
         2935  +      nKey = pNos->n;
         2936  +      zKey = pNos->z;
  2953   2937       }else{
  2954         -      assert( aStack[nos].flags & MEM_Int );
         2938  +      assert( pNos->flags & MEM_Int );
  2955   2939         nKey = sizeof(int);
  2956         -      iKey = intToKey(aStack[nos].i);
         2940  +      iKey = intToKey(pNos->i);
  2957   2941         zKey = (char*)&iKey;
  2958   2942         if( pOp->p2 ){
  2959   2943           db->nChange++;
  2960         -        db->lastRowid = aStack[nos].i;
         2944  +        db->lastRowid = pNos->i;
  2961   2945         }
  2962         -      if( pC->nextRowidValid && aStack[nos].i>=pC->nextRowid ){
         2946  +      if( pC->nextRowidValid && pTos->i>=pC->nextRowid ){
  2963   2947           pC->nextRowidValid = 0;
  2964   2948         }
  2965   2949       }
  2966   2950       if( pC->pseudoTable ){
  2967   2951         /* PutStrKey does not work for pseudo-tables.
  2968   2952         ** The following assert makes sure we are not trying to use
  2969   2953         ** PutStrKey on a pseudo-table
  2970   2954         */
  2971   2955         assert( pOp->opcode==OP_PutIntKey );
  2972   2956         sqliteFree(pC->pData);
  2973   2957         pC->iKey = iKey;
  2974         -      pC->nData = aStack[tos].n;
  2975         -      if( aStack[tos].flags & MEM_Dyn ){
  2976         -        pC->pData = aStack[tos].z;
  2977         -        aStack[tos].z = 0;
  2978         -        aStack[tos].flags = MEM_Null;
         2958  +      pC->nData = pTos->n;
         2959  +      if( pTos->flags & MEM_Dyn ){
         2960  +        pC->pData = pTos->z;
         2961  +        pTos->flags = MEM_Null;
  2979   2962         }else{
  2980   2963           pC->pData = sqliteMallocRaw( pC->nData );
  2981   2964           if( pC->pData ){
  2982         -          memcpy(pC->pData, aStack[tos].z, pC->nData);
         2965  +          memcpy(pC->pData, pTos->z, pC->nData);
  2983   2966           }
  2984   2967         }
  2985   2968         pC->nullRow = 0;
  2986   2969       }else{
  2987         -      rc = sqliteBtreeInsert(pC->pCursor, zKey, nKey,
  2988         -                          aStack[tos].z, aStack[tos].n);
         2970  +      rc = sqliteBtreeInsert(pC->pCursor, zKey, nKey, pTos->z, pTos->n);
  2989   2971       }
  2990   2972       pC->recnoIsValid = 0;
  2991   2973       pC->deferredMoveto = 0;
  2992   2974     }
  2993         -  POPSTACK;
  2994         -  POPSTACK;
         2975  +  popStack(&pTos, 2);
  2995   2976     break;
  2996   2977   }
  2997   2978   
  2998   2979   /* Opcode: Delete P1 P2 *
  2999   2980   **
  3000   2981   ** Delete the record at which the P1 cursor is currently pointing.
  3001   2982   **
................................................................................
  3054   3035   **
  3055   3036   ** If the cursor is not pointing to a valid row, a NULL is pushed
  3056   3037   ** onto the stack.
  3057   3038   */
  3058   3039   case OP_RowKey:
  3059   3040   case OP_RowData: {
  3060   3041     int i = pOp->p1;
  3061         -  int tos = ++p->tos;
  3062   3042     Cursor *pC;
  3063   3043     int n;
  3064   3044   
         3045  +  pTos++;
  3065   3046     assert( i>=0 && i<p->nCursor );
  3066   3047     pC = &p->aCsr[i];
  3067   3048     if( pC->nullRow ){
  3068         -    aStack[tos].flags = MEM_Null;
         3049  +    pTos->flags = MEM_Null;
  3069   3050     }else if( pC->pCursor!=0 ){
  3070   3051       BtCursor *pCrsr = pC->pCursor;
  3071   3052       sqliteVdbeCursorMoveto(pC);
  3072   3053       if( pC->nullRow ){
  3073         -      aStack[tos].flags = MEM_Null;
         3054  +      pTos->flags = MEM_Null;
  3074   3055         break;
  3075   3056       }else if( pC->keyAsData || pOp->opcode==OP_RowKey ){
  3076   3057         sqliteBtreeKeySize(pCrsr, &n);
  3077   3058       }else{
  3078   3059         sqliteBtreeDataSize(pCrsr, &n);
  3079   3060       }
  3080         -    aStack[tos].n = n;
         3061  +    pTos->n = n;
  3081   3062       if( n<=NBFS ){
  3082         -      aStack[tos].flags = MEM_Str;
  3083         -      aStack[tos].z = aStack[tos].zShort;
         3063  +      pTos->flags = MEM_Str | MEM_Short;
         3064  +      pTos->z = pTos->zShort;
  3084   3065       }else{
  3085   3066         char *z = sqliteMallocRaw( n );
  3086   3067         if( z==0 ) goto no_mem;
  3087         -      aStack[tos].flags = MEM_Str | MEM_Dyn;
  3088         -      aStack[tos].z = z;
         3068  +      pTos->flags = MEM_Str | MEM_Dyn;
         3069  +      pTos->z = z;
  3089   3070       }
  3090   3071       if( pC->keyAsData || pOp->opcode==OP_RowKey ){
  3091         -      sqliteBtreeKey(pCrsr, 0, n, aStack[tos].z);
         3072  +      sqliteBtreeKey(pCrsr, 0, n, pTos->z);
  3092   3073       }else{
  3093         -      sqliteBtreeData(pCrsr, 0, n, aStack[tos].z);
         3074  +      sqliteBtreeData(pCrsr, 0, n, pTos->z);
  3094   3075       }
  3095   3076     }else if( pC->pseudoTable ){
  3096         -    aStack[tos].n = pC->nData;
  3097         -    aStack[tos].z = pC->pData;
  3098         -    aStack[tos].flags = MEM_Str|MEM_Ephem;
         3077  +    pTos->n = pC->nData;
         3078  +    pTos->z = pC->pData;
         3079  +    pTos->flags = MEM_Str|MEM_Ephem;
  3099   3080     }else{
  3100         -    aStack[tos].flags = MEM_Null;
         3081  +    pTos->flags = MEM_Null;
  3101   3082     }
  3102   3083     break;
  3103   3084   }
  3104   3085   
  3105   3086   /* Opcode: Column P1 P2 *
  3106   3087   **
  3107   3088   ** Interpret the data that cursor P1 points to as
................................................................................
  3121   3102   ** value pushed is always just a pointer into the record which is
  3122   3103   ** stored further down on the stack.  The column value is not copied.
  3123   3104   */
  3124   3105   case OP_Column: {
  3125   3106     int amt, offset, end, payloadSize;
  3126   3107     int i = pOp->p1;
  3127   3108     int p2 = pOp->p2;
  3128         -  int tos = p->tos+1;
  3129   3109     Cursor *pC;
  3130   3110     char *zRec;
  3131   3111     BtCursor *pCrsr;
  3132   3112     int idxWidth;
  3133   3113     unsigned char aHdr[10];
  3134   3114   
  3135   3115     assert( i<p->nCursor );
         3116  +  pTos++;
  3136   3117     if( i<0 ){
  3137         -    VERIFY( if( tos+i<0 ) goto bad_instruction; )
  3138         -    VERIFY( if( (aStack[tos+i].flags & MEM_Str)==0 ) goto bad_instruction; )
  3139         -    zRec = aStack[tos+i].z;
  3140         -    payloadSize = aStack[tos+i].n;
         3118  +    assert( &pTos[i]>=p->aStack );
         3119  +    assert( pTos[i].flags & MEM_Str );
         3120  +    zRec = pTos[i].z;
         3121  +    payloadSize = pTos[i].n;
  3141   3122     }else if( (pC = &p->aCsr[i])->pCursor!=0 ){
  3142   3123       sqliteVdbeCursorMoveto(pC);
  3143   3124       zRec = 0;
  3144   3125       pCrsr = pC->pCursor;
  3145   3126       if( pC->nullRow ){
  3146   3127         payloadSize = 0;
  3147   3128       }else if( pC->keyAsData ){
................................................................................
  3157   3138       payloadSize = 0;
  3158   3139     }
  3159   3140   
  3160   3141     /* Figure out how many bytes in the column data and where the column
  3161   3142     ** data begins.
  3162   3143     */
  3163   3144     if( payloadSize==0 ){
  3164         -    aStack[tos].flags = MEM_Null;
  3165         -    p->tos = tos;
         3145  +    pTos->flags = MEM_Null;
  3166   3146       break;
  3167   3147     }else if( payloadSize<256 ){
  3168   3148       idxWidth = 1;
  3169   3149     }else if( payloadSize<65536 ){
  3170   3150       idxWidth = 2;
  3171   3151     }else{
  3172   3152       idxWidth = 3;
................................................................................
  3200   3180       rc = SQLITE_CORRUPT;
  3201   3181       goto abort_due_to_error;
  3202   3182     }
  3203   3183   
  3204   3184     /* amt and offset now hold the offset to the start of data and the
  3205   3185     ** amount of data.  Go get the data and put it on the stack.
  3206   3186     */
         3187  +  pTos->n = amt;
  3207   3188     if( amt==0 ){
  3208         -    aStack[tos].flags = MEM_Null;
         3189  +    pTos->flags = MEM_Null;
  3209   3190     }else if( zRec ){
  3210         -    aStack[tos].flags = MEM_Str | MEM_Ephem;
  3211         -    aStack[tos].n = amt;
  3212         -    aStack[tos].z = &zRec[offset];
         3191  +    pTos->flags = MEM_Str | MEM_Ephem;
         3192  +    pTos->z = &zRec[offset];
  3213   3193     }else{
  3214   3194       if( amt<=NBFS ){
  3215         -      aStack[tos].flags = MEM_Str;
  3216         -      aStack[tos].z = aStack[tos].zShort;
  3217         -      aStack[tos].n = amt;
         3195  +      pTos->flags = MEM_Str | MEM_Short;
         3196  +      pTos->z = pTos->zShort;
  3218   3197       }else{
  3219   3198         char *z = sqliteMallocRaw( amt );
  3220   3199         if( z==0 ) goto no_mem;
  3221         -      aStack[tos].flags = MEM_Str | MEM_Dyn;
  3222         -      aStack[tos].z = z;
  3223         -      aStack[tos].n = amt;
         3200  +      pTos->flags = MEM_Str | MEM_Dyn;
         3201  +      pTos->z = z;
  3224   3202       }
  3225   3203       if( pC->keyAsData ){
  3226         -      sqliteBtreeKey(pCrsr, offset, amt, aStack[tos].z);
         3204  +      sqliteBtreeKey(pCrsr, offset, amt, pTos->z);
  3227   3205       }else{
  3228         -      sqliteBtreeData(pCrsr, offset, amt, aStack[tos].z);
         3206  +      sqliteBtreeData(pCrsr, offset, amt, pTos->z);
  3229   3207       }
  3230   3208     }
  3231         -  p->tos = tos;
  3232   3209     break;
  3233   3210   }
  3234   3211   
  3235   3212   /* Opcode: Recno P1 * *
  3236   3213   **
  3237   3214   ** Push onto the stack an integer which is the first 4 bytes of the
  3238   3215   ** the key to the current entry in a sequential scan of the database
  3239   3216   ** file P1.  The sequential scan should have been started using the 
  3240   3217   ** Next opcode.
  3241   3218   */
  3242   3219   case OP_Recno: {
  3243   3220     int i = pOp->p1;
  3244         -  int tos = ++p->tos;
  3245   3221     Cursor *pC;
  3246   3222     int v;
  3247   3223   
  3248   3224     assert( i>=0 && i<p->nCursor );
  3249   3225     pC = &p->aCsr[i];
  3250   3226     sqliteVdbeCursorMoveto(pC);
         3227  +  pTos++;
  3251   3228     if( pC->recnoIsValid ){
  3252   3229       v = pC->lastRecno;
  3253   3230     }else if( pC->pseudoTable ){
  3254   3231       v = keyToInt(pC->iKey);
  3255   3232     }else if( pC->nullRow || pC->pCursor==0 ){
  3256         -    aStack[tos].flags = MEM_Null;
         3233  +    pTos->flags = MEM_Null;
  3257   3234       break;
  3258   3235     }else{
  3259   3236       assert( pC->pCursor!=0 );
  3260   3237       sqliteBtreeKey(pC->pCursor, 0, sizeof(u32), (char*)&v);
  3261   3238       v = keyToInt(v);
  3262   3239     }
  3263         -  aStack[tos].i = v;
  3264         -  aStack[tos].flags = MEM_Int;
         3240  +  pTos->i = v;
         3241  +  pTos->flags = MEM_Int;
  3265   3242     break;
  3266   3243   }
  3267   3244   
  3268   3245   /* Opcode: FullKey P1 * *
  3269   3246   **
  3270   3247   ** Extract the complete key from the record that cursor P1 is currently
  3271   3248   ** pointing to and push the key onto the stack as a string.
................................................................................
  3274   3251   ** 4 bytes of the key and pushes those bytes onto the stack as an
  3275   3252   ** integer.  This instruction pushes the entire key as a string.
  3276   3253   **
  3277   3254   ** This opcode may not be used on a pseudo-table.
  3278   3255   */
  3279   3256   case OP_FullKey: {
  3280   3257     int i = pOp->p1;
  3281         -  int tos = ++p->tos;
  3282   3258     BtCursor *pCrsr;
  3283   3259   
  3284         -  VERIFY( if( !p->aCsr[i].keyAsData ) goto bad_instruction; )
  3285         -  VERIFY( if( p->aCsr[i].pseudoTable ) goto bad_instruction; )
  3286         -  if( VERIFY( i>=0 && i<p->nCursor && ) (pCrsr = p->aCsr[i].pCursor)!=0 ){
         3260  +  assert( p->aCsr[i].keyAsData );
         3261  +  assert( !p->aCsr[i].pseudoTable );
         3262  +  assert( i>=0 && i<p->nCursor );
         3263  +  pTos++;
         3264  +  if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
  3287   3265       int amt;
  3288   3266       char *z;
  3289   3267   
  3290   3268       sqliteVdbeCursorMoveto(&p->aCsr[i]);
  3291   3269       sqliteBtreeKeySize(pCrsr, &amt);
  3292   3270       if( amt<=0 ){
  3293   3271         rc = SQLITE_CORRUPT;
  3294   3272         goto abort_due_to_error;
  3295   3273       }
  3296   3274       if( amt>NBFS ){
  3297   3275         z = sqliteMallocRaw( amt );
  3298   3276         if( z==0 ) goto no_mem;
  3299         -      aStack[tos].flags = MEM_Str | MEM_Dyn;
         3277  +      pTos->flags = MEM_Str | MEM_Dyn;
  3300   3278       }else{
  3301         -      z = aStack[tos].zShort;
  3302         -      aStack[tos].flags = MEM_Str;
         3279  +      z = pTos->zShort;
         3280  +      pTos->flags = MEM_Str | MEM_Short;
  3303   3281       }
  3304   3282       sqliteBtreeKey(pCrsr, 0, amt, z);
  3305         -    aStack[tos].z = z;
  3306         -    aStack[tos].n = amt;
         3283  +    pTos->z = z;
         3284  +    pTos->n = amt;
  3307   3285     }
  3308   3286     break;
  3309   3287   }
  3310   3288   
  3311   3289   /* Opcode: NullRow P1 * *
  3312   3290   **
  3313   3291   ** Move the cursor P1 to a null row.  Any OP_Column operations
................................................................................
  3436   3414   ** If P2==1, then the key must be unique.  If the key is not unique,
  3437   3415   ** the program aborts with a SQLITE_CONSTRAINT error and the database
  3438   3416   ** is rolled back.  If P3 is not null, then it becomes part of the
  3439   3417   ** error message returned with the SQLITE_CONSTRAINT.
  3440   3418   */
  3441   3419   case OP_IdxPut: {
  3442   3420     int i = pOp->p1;
  3443         -  int tos = p->tos;
  3444   3421     BtCursor *pCrsr;
  3445         -  VERIFY( if( tos<0 ) goto not_enough_stack; )
  3446         -  if( VERIFY( i>=0 && i<p->nCursor && ) (pCrsr = p->aCsr[i].pCursor)!=0 ){
  3447         -    int nKey = aStack[tos].n;
  3448         -    const char *zKey = aStack[tos].z;
         3422  +  assert( pTos>=p->aStack );
         3423  +  assert( i>=0 && i<p->nCursor );
         3424  +  assert( pTos->flags & MEM_Str );
         3425  +  if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
         3426  +    int nKey = pTos->n;
         3427  +    const char *zKey = pTos->z;
  3449   3428       if( pOp->p2 ){
  3450   3429         int res, n;
  3451         -      assert( aStack[tos].n >= 4 );
         3430  +      assert( nKey >= 4 );
  3452   3431         rc = sqliteBtreeMoveto(pCrsr, zKey, nKey-4, &res);
  3453   3432         if( rc!=SQLITE_OK ) goto abort_due_to_error;
  3454   3433         while( res!=0 ){
  3455   3434           int c;
  3456   3435           sqliteBtreeKeySize(pCrsr, &n);
  3457   3436           if( n==nKey
  3458   3437              && sqliteBtreeKeyCompare(pCrsr, zKey, nKey-4, 4, &c)==SQLITE_OK
................................................................................
  3471   3450             break;
  3472   3451           }
  3473   3452         }
  3474   3453       }
  3475   3454       rc = sqliteBtreeInsert(pCrsr, zKey, nKey, "", 0);
  3476   3455       assert( p->aCsr[i].deferredMoveto==0 );
  3477   3456     }
  3478         -  POPSTACK;
         3457  +  Release(pTos);
         3458  +  pTos--;
  3479   3459     break;
  3480   3460   }
  3481   3461   
  3482   3462   /* Opcode: IdxDelete P1 * *
  3483   3463   **
  3484   3464   ** The top of the stack is an index key built using the MakeIdxKey opcode.
  3485   3465   ** This opcode removes that entry from the index.
  3486   3466   */
  3487   3467   case OP_IdxDelete: {
  3488   3468     int i = pOp->p1;
  3489         -  int tos = p->tos;
  3490   3469     BtCursor *pCrsr;
  3491         -  VERIFY( if( tos<0 ) goto not_enough_stack; )
  3492         -  if( VERIFY( i>=0 && i<p->nCursor && ) (pCrsr = p->aCsr[i].pCursor)!=0 ){
         3470  +  assert( pTos>=p->aStack );
         3471  +  assert( pTos->flags & MEM_Str );
         3472  +  assert( i>=0 && i<p->nCursor );
         3473  +  if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
  3493   3474       int rx, res;
  3494         -    rx = sqliteBtreeMoveto(pCrsr, aStack[tos].z, aStack[tos].n, &res);
         3475  +    rx = sqliteBtreeMoveto(pCrsr, pTos->z, pTos->n, &res);
  3495   3476       if( rx==SQLITE_OK && res==0 ){
  3496   3477         rc = sqliteBtreeDelete(pCrsr);
  3497   3478       }
  3498   3479       assert( p->aCsr[i].deferredMoveto==0 );
  3499   3480     }
  3500         -  POPSTACK;
         3481  +  Release(pTos);
         3482  +  pTos--;
  3501   3483     break;
  3502   3484   }
  3503   3485   
  3504   3486   /* Opcode: IdxRecno P1 * *
  3505   3487   **
  3506   3488   ** Push onto the stack an integer which is the last 4 bytes of the
  3507   3489   ** the key to the current entry in index P1.  These 4 bytes should
................................................................................
  3508   3490   ** be the record number of the table entry to which this index entry
  3509   3491   ** points.
  3510   3492   **
  3511   3493   ** See also: Recno, MakeIdxKey.
  3512   3494   */
  3513   3495   case OP_IdxRecno: {
  3514   3496     int i = pOp->p1;
  3515         -  int tos = ++p->tos;
  3516   3497     BtCursor *pCrsr;
  3517   3498   
  3518         -  if( VERIFY( i>=0 && i<p->nCursor && ) (pCrsr = p->aCsr[i].pCursor)!=0 ){
         3499  +  assert( i>=0 && i<p->nCursor );
         3500  +  pTos++;
         3501  +  if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
  3519   3502       int v;
  3520   3503       int sz;
  3521   3504       assert( p->aCsr[i].deferredMoveto==0 );
  3522   3505       sqliteBtreeKeySize(pCrsr, &sz);
  3523   3506       if( sz<sizeof(u32) ){
  3524         -      aStack[tos].flags = MEM_Null;
         3507  +      pTos->flags = MEM_Null;
  3525   3508       }else{
  3526   3509         sqliteBtreeKey(pCrsr, sz - sizeof(u32), sizeof(u32), (char*)&v);
  3527   3510         v = keyToInt(v);
  3528         -      aStack[tos].i = v;
  3529         -      aStack[tos].flags = MEM_Int;
         3511  +      pTos->i = v;
         3512  +      pTos->flags = MEM_Int;
  3530   3513       }
         3514  +  }else{
         3515  +    pTos->flags = MEM_Null;
  3531   3516     }
  3532   3517     break;
  3533   3518   }
  3534   3519   
  3535   3520   /* Opcode: IdxGT P1 P2 *
  3536   3521   **
  3537   3522   ** Compare the top of the stack against the key on the index entry that
................................................................................
  3557   3542   ** then jump to P2.  Otherwise fall through to the next instruction.
  3558   3543   ** In either case, the stack is popped once.
  3559   3544   */
  3560   3545   case OP_IdxLT:
  3561   3546   case OP_IdxGT:
  3562   3547   case OP_IdxGE: {
  3563   3548     int i= pOp->p1;
  3564         -  int tos = p->tos;
  3565   3549     BtCursor *pCrsr;
  3566   3550   
  3567         -  if( VERIFY( i>=0 && i<p->nCursor && ) (pCrsr = p->aCsr[i].pCursor)!=0 ){
         3551  +  assert( i>=0 && i<p->nCursor );
         3552  +  assert( pTos>=p->aStack );
         3553  +  if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
  3568   3554       int res, rc;
  3569   3555    
  3570         -    Stringify(p, tos);
         3556  +    Stringify(pTos);
  3571   3557       assert( p->aCsr[i].deferredMoveto==0 );
  3572         -    rc = sqliteBtreeKeyCompare(pCrsr, aStack[tos].z, aStack[tos].n, 4, &res);
         3558  +    rc = sqliteBtreeKeyCompare(pCrsr, pTos->z, pTos->n, 4, &res);
  3573   3559       if( rc!=SQLITE_OK ){
  3574   3560         break;
  3575   3561       }
  3576   3562       if( pOp->opcode==OP_IdxLT ){
  3577   3563         res = -res;
  3578   3564       }else if( pOp->opcode==OP_IdxGE ){
  3579   3565         res++;
  3580   3566       }
  3581   3567       if( res>0 ){
  3582   3568         pc = pOp->p2 - 1 ;
  3583   3569       }
  3584   3570     }
  3585         -  POPSTACK;
         3571  +  Release(pTos);
         3572  +  pTos--;
  3586   3573     break;
  3587   3574   }
  3588   3575   
  3589   3576   /* Opcode: IdxIsNull P1 P2 *
  3590   3577   **
  3591   3578   ** The top of the stack contains an index entry such as might be generated
  3592   3579   ** by the MakeIdxKey opcode.  This routine looks at the first P1 fields of
................................................................................
  3593   3580   ** that key.  If any of the first P1 fields are NULL, then a jump is made
  3594   3581   ** to address P2.  Otherwise we fall straight through.
  3595   3582   **
  3596   3583   ** The index entry is always popped from the stack.
  3597   3584   */
  3598   3585   case OP_IdxIsNull: {
  3599   3586     int i = pOp->p1;
  3600         -  int tos = p->tos;
  3601   3587     int k, n;
  3602   3588     const char *z;
  3603   3589   
  3604         -  assert( tos>=0 );
  3605         -  assert( aStack[tos].flags & MEM_Str );
  3606         -  z = aStack[tos].z;
  3607         -  n = aStack[tos].n;
         3590  +  assert( pTos>=p->aStack );
         3591  +  assert( pTos->flags & MEM_Str );
         3592  +  z = pTos->z;
         3593  +  n = pTos->n;
  3608   3594     for(k=0; k<n && i>0; i--){
  3609   3595       if( z[k]=='a' ){
  3610   3596         pc = pOp->p2-1;
  3611   3597         break;
  3612   3598       }
  3613   3599       while( k<n && z[k] ){ k++; }
  3614   3600       k++;
  3615   3601     }
  3616         -  POPSTACK;
         3602  +  Release(pTos);
         3603  +  pTos--;
  3617   3604     break;
  3618   3605   }
  3619   3606   
  3620   3607   /* Opcode: Destroy P1 P2 *
  3621   3608   **
  3622   3609   ** Delete an entire database table or index whose root page in the database
  3623   3610   ** file is given by P1.
................................................................................
  3673   3660   ** auxiliary database file if P2==1.  Push the page number of the
  3674   3661   ** root page of the new index onto the stack.
  3675   3662   **
  3676   3663   ** See documentation on OP_CreateTable for additional information.
  3677   3664   */
  3678   3665   case OP_CreateIndex:
  3679   3666   case OP_CreateTable: {
  3680         -  int i = ++p->tos;
  3681   3667     int pgno;
  3682   3668     assert( pOp->p3!=0 && pOp->p3type==P3_POINTER );
  3683   3669     assert( pOp->p2>=0 && pOp->p2<db->nDb );
  3684   3670     assert( db->aDb[pOp->p2].pBt!=0 );
  3685   3671     if( pOp->opcode==OP_CreateTable ){
  3686   3672       rc = sqliteBtreeCreateTable(db->aDb[pOp->p2].pBt, &pgno);
  3687   3673     }else{
  3688   3674       rc = sqliteBtreeCreateIndex(db->aDb[pOp->p2].pBt, &pgno);
  3689   3675     }
         3676  +  pTos++;
  3690   3677     if( rc==SQLITE_OK ){
  3691         -    aStack[i].i = pgno;
  3692         -    aStack[i].flags = MEM_Int;
         3678  +    pTos->i = pgno;
         3679  +    pTos->flags = MEM_Int;
  3693   3680       *(u32*)pOp->p3 = pgno;
  3694   3681       pOp->p3 = 0;
  3695   3682     }
  3696   3683     break;
  3697   3684   }
  3698   3685   
  3699   3686   /* Opcode: IntegrityCk P1 P2 *
................................................................................
  3711   3698   ** file, not the main database file.
  3712   3699   **
  3713   3700   ** This opcode is used for testing purposes only.
  3714   3701   */
  3715   3702   case OP_IntegrityCk: {
  3716   3703     int nRoot;
  3717   3704     int *aRoot;
  3718         -  int tos = ++p->tos;
  3719   3705     int iSet = pOp->p1;
  3720   3706     Set *pSet;
  3721   3707     int j;
  3722   3708     HashElem *i;
  3723   3709     char *z;
  3724   3710   
  3725         -  VERIFY( if( iSet<0 || iSet>=p->nSet ) goto bad_instruction; )
         3711  +  assert( iSet>=0 && iSet<p->nSet );
         3712  +  pTos++;
  3726   3713     pSet = &p->aSet[iSet];
  3727   3714     nRoot = sqliteHashCount(&pSet->hash);
  3728   3715     aRoot = sqliteMallocRaw( sizeof(int)*(nRoot+1) );
  3729   3716     if( aRoot==0 ) goto no_mem;
  3730   3717     for(j=0, i=sqliteHashFirst(&pSet->hash); i; i=sqliteHashNext(i), j++){
  3731   3718       toInt((char*)sqliteHashKey(i), &aRoot[j]);
  3732   3719     }
  3733   3720     aRoot[j] = 0;
  3734   3721     sqliteHashClear(&pSet->hash);
  3735   3722     pSet->prev = 0;
  3736   3723     z = sqliteBtreeIntegrityCheck(db->aDb[pOp->p2].pBt, aRoot, nRoot);
  3737   3724     if( z==0 || z[0]==0 ){
  3738   3725       if( z ) sqliteFree(z);
  3739         -    aStack[tos].z = "ok";
  3740         -    aStack[tos].n = 3;
  3741         -    aStack[tos].flags = MEM_Str | MEM_Static;
         3726  +    pTos->z = "ok";
         3727  +    pTos->n = 3;
         3728  +    pTos->flags = MEM_Str | MEM_Static;
  3742   3729     }else{
  3743         -    aStack[tos].z = z;
  3744         -    aStack[tos].n = strlen(z) + 1;
  3745         -    aStack[tos].flags = MEM_Str | MEM_Dyn;
         3730  +    pTos->z = z;
         3731  +    pTos->n = strlen(z) + 1;
         3732  +    pTos->flags = MEM_Str | MEM_Dyn;
  3746   3733     }
  3747   3734     sqliteFree(aRoot);
  3748   3735     break;
  3749   3736   }
  3750   3737   
  3751   3738   /* Opcode: ListWrite * * *
  3752   3739   **
  3753   3740   ** Write the integer on the top of the stack
  3754   3741   ** into the temporary storage list.
  3755   3742   */
  3756   3743   case OP_ListWrite: {
  3757   3744     Keylist *pKeylist;
  3758         -  VERIFY( if( p->tos<0 ) goto not_enough_stack; )
         3745  +  assert( pTos>=p->aStack );
  3759   3746     pKeylist = p->pList;
  3760   3747     if( pKeylist==0 || pKeylist->nUsed>=pKeylist->nKey ){
  3761   3748       pKeylist = sqliteMallocRaw( sizeof(Keylist)+999*sizeof(pKeylist->aKey[0]) );
  3762   3749       if( pKeylist==0 ) goto no_mem;
  3763   3750       pKeylist->nKey = 1000;
  3764   3751       pKeylist->nRead = 0;
  3765   3752       pKeylist->nUsed = 0;
  3766   3753       pKeylist->pNext = p->pList;
  3767   3754       p->pList = pKeylist;
  3768   3755     }
  3769         -  Integerify(p, p->tos);
  3770         -  pKeylist->aKey[pKeylist->nUsed++] = aStack[p->tos].i;
  3771         -  POPSTACK;
         3756  +  Integerify(pTos);
         3757  +  pKeylist->aKey[pKeylist->nUsed++] = pTos->i;
         3758  +  assert( pTos->flags==MEM_Int );
         3759  +  pTos--;
  3772   3760     break;
  3773   3761   }
  3774   3762   
  3775   3763   /* Opcode: ListRewind * * *
  3776   3764   **
  3777   3765   ** Rewind the temporary buffer back to the beginning.  This is 
  3778   3766   ** now a no-op.
................................................................................
  3789   3777   ** push nothing but instead jump to P2.
  3790   3778   */
  3791   3779   case OP_ListRead: {
  3792   3780     Keylist *pKeylist;
  3793   3781     CHECK_FOR_INTERRUPT;
  3794   3782     pKeylist = p->pList;
  3795   3783     if( pKeylist!=0 ){
  3796         -    VERIFY(
  3797         -      if( pKeylist->nRead<0 
  3798         -        || pKeylist->nRead>=pKeylist->nUsed
  3799         -        || pKeylist->nRead>=pKeylist->nKey ) goto bad_instruction;
  3800         -    )
  3801         -    p->tos++;
  3802         -    aStack[p->tos].i = pKeylist->aKey[pKeylist->nRead++];
  3803         -    aStack[p->tos].flags = MEM_Int;
  3804         -    aStack[p->tos].z = 0;
         3784  +    assert( pKeylist->nRead>=0 );
         3785  +    assert( pKeylist->nRead<pKeylist->nUsed );
         3786  +    assert( pKeylist->nRead<pKeylist->nKey );
         3787  +    pTos++;
         3788  +    pTos->i = pKeylist->aKey[pKeylist->nRead++];
         3789  +    pTos->flags = MEM_Int;
  3805   3790       if( pKeylist->nRead>=pKeylist->nUsed ){
  3806   3791         p->pList = pKeylist->pNext;
  3807   3792         sqliteFree(pKeylist);
  3808   3793       }
  3809   3794     }else{
  3810   3795       pc = pOp->p2 - 1;
  3811   3796     }
................................................................................
  3861   3846   /* Opcode: SortPut * * *
  3862   3847   **
  3863   3848   ** The TOS is the key and the NOS is the data.  Pop both from the stack
  3864   3849   ** and put them on the sorter.  The key and data should have been
  3865   3850   ** made using SortMakeKey and SortMakeRec, respectively.
  3866   3851   */
  3867   3852   case OP_SortPut: {
  3868         -  int tos = p->tos;
  3869         -  int nos = tos - 1;
         3853  +  Mem *pNos = &pTos[-1];
  3870   3854     Sorter *pSorter;
  3871         -  VERIFY( if( tos<1 ) goto not_enough_stack; )
  3872         -  if( Dynamicify(p, tos) || Dynamicify(p, nos) ) goto no_mem;
         3855  +  assert( pNos>=p->aStack );
         3856  +  if( Dynamicify(pTos) || Dynamicify(pNos) ) goto no_mem;
  3873   3857     pSorter = sqliteMallocRaw( sizeof(Sorter) );
  3874   3858     if( pSorter==0 ) goto no_mem;
  3875   3859     pSorter->pNext = p->pSort;
  3876   3860     p->pSort = pSorter;
  3877         -  assert( aStack[tos].flags & MEM_Dyn );
  3878         -  pSorter->nKey = aStack[tos].n;
  3879         -  pSorter->zKey = aStack[tos].z;
  3880         -  pSorter->nData = aStack[nos].n;
  3881         -  if( aStack[nos].flags & MEM_Dyn ){
  3882         -    pSorter->pData = aStack[nos].z;
  3883         -  }else{
  3884         -    pSorter->pData = sqliteStrDup(aStack[nos].z);
  3885         -  }
  3886         -  aStack[tos].flags = 0;
  3887         -  aStack[nos].flags = 0;
  3888         -  aStack[tos].z = 0;
  3889         -  aStack[nos].z = 0;
  3890         -  p->tos -= 2;
         3861  +  assert( pTos->flags & MEM_Dyn );
         3862  +  pSorter->nKey = pTos->n;
         3863  +  pSorter->zKey = pTos->z;
         3864  +  assert( pNos->flags & MEM_Dyn );
         3865  +  pSorter->nData = pNos->n;
         3866  +  pSorter->pData = pNos->z;
         3867  +  pTos -= 2;
  3891   3868     break;
  3892   3869   }
  3893   3870   
  3894   3871   /* Opcode: SortMakeRec P1 * *
  3895   3872   **
  3896   3873   ** The top P1 elements are the arguments to a callback.  Form these
  3897   3874   ** elements into a single data entry that can be stored on a sorter
................................................................................
  3898   3875   ** using SortPut and later fed to a callback using SortCallback.
  3899   3876   */
  3900   3877   case OP_SortMakeRec: {
  3901   3878     char *z;
  3902   3879     char **azArg;
  3903   3880     int nByte;
  3904   3881     int nField;
  3905         -  int i, j;
         3882  +  int i;
         3883  +  Mem *pRec;
  3906   3884   
  3907   3885     nField = pOp->p1;
  3908         -  VERIFY( if( p->tos+1<nField ) goto not_enough_stack; )
         3886  +  pRec = &pTos[1-nField];
         3887  +  assert( pRec>=p->aStack );
  3909   3888     nByte = 0;
  3910         -  for(i=p->tos-nField+1; i<=p->tos; i++){
  3911         -    if( (aStack[i].flags & MEM_Null)==0 ){
  3912         -      Stringify(p, i);
  3913         -      nByte += aStack[i].n;
         3889  +  for(i=0; i<nField; i++, pRec++){
         3890  +    if( (pRec->flags & MEM_Null)==0 ){
         3891  +      Stringify(pRec);
         3892  +      nByte += pRec->n;
  3914   3893       }
  3915   3894     }
  3916   3895     nByte += sizeof(char*)*(nField+1);
  3917   3896     azArg = sqliteMallocRaw( nByte );
  3918   3897     if( azArg==0 ) goto no_mem;
  3919   3898     z = (char*)&azArg[nField+1];
  3920         -  for(j=0, i=p->tos-nField+1; i<=p->tos; i++, j++){
  3921         -    if( aStack[i].flags & MEM_Null ){
  3922         -      azArg[j] = 0;
         3899  +  for(pRec=&pTos[1-nField], i=0; i<nField; i++, pRec++){
         3900  +    if( pRec->flags & MEM_Null ){
         3901  +      azArg[i] = 0;
  3923   3902       }else{
  3924         -      azArg[j] = z;
  3925         -      strcpy(z, aStack[i].z);
  3926         -      z += aStack[i].n;
         3903  +      azArg[i] = z;
         3904  +      memcpy(z, pRec->z, pRec->n);
         3905  +      z += pRec->n;
  3927   3906       }
  3928   3907     }
  3929         -  sqliteVdbePopStack(p, nField);
  3930         -  p->tos++;
  3931         -  aStack[p->tos].n = nByte;
  3932         -  aStack[p->tos].z = (char*)azArg;
  3933         -  aStack[p->tos].flags = MEM_Str|MEM_Dyn;
         3908  +  popStack(&pTos, nField);
         3909  +  pTos++;
         3910  +  pTos->n = nByte;
         3911  +  pTos->z = (char*)azArg;
         3912  +  pTos->flags = MEM_Str | MEM_Dyn;
  3934   3913     break;
  3935   3914   }
  3936   3915   
  3937   3916   /* Opcode: SortMakeKey * * P3
  3938   3917   **
  3939   3918   ** Convert the top few entries of the stack into a sort key.  The
  3940   3919   ** number of stack entries consumed is the number of characters in 
................................................................................
  3950   3929   ** See also the MakeKey and MakeIdxKey opcodes.
  3951   3930   */
  3952   3931   case OP_SortMakeKey: {
  3953   3932     char *zNewKey;
  3954   3933     int nByte;
  3955   3934     int nField;
  3956   3935     int i, j, k;
         3936  +  Mem *pRec;
  3957   3937   
  3958   3938     nField = strlen(pOp->p3);
  3959         -  VERIFY( if( p->tos+1<nField ) goto not_enough_stack; )
         3939  +  pRec = &pTos[1-nField];
  3960   3940     nByte = 1;
  3961         -  for(i=p->tos-nField+1; i<=p->tos; i++){
  3962         -    if( (aStack[i].flags & MEM_Null)!=0 ){
         3941  +  for(i=0; i<nField; i++, pRec++){
         3942  +    if( pRec->flags & MEM_Null ){
  3963   3943         nByte += 2;
  3964   3944       }else{
  3965         -      Stringify(p, i);
  3966         -      nByte += aStack[i].n+2;
         3945  +      Stringify(pRec);
         3946  +      nByte += pRec->n+2;
  3967   3947       }
  3968   3948     }
  3969   3949     zNewKey = sqliteMallocRaw( nByte );
  3970   3950     if( zNewKey==0 ) goto no_mem;
  3971   3951     j = 0;
  3972   3952     k = 0;
  3973         -  for(i=p->tos-nField+1; i<=p->tos; i++){
  3974         -    if( (aStack[i].flags & MEM_Null)!=0 ){
         3953  +  for(pRec=&pTos[1-nField], i=0; i<nField; i++, pRec++){
         3954  +    if( pRec->flags & MEM_Null ){
  3975   3955         zNewKey[j++] = 'N';
  3976   3956         zNewKey[j++] = 0;
  3977   3957         k++;
  3978   3958       }else{
  3979   3959         zNewKey[j++] = pOp->p3[k++];
  3980         -      memcpy(&zNewKey[j], aStack[i].z, aStack[i].n-1);
  3981         -      j += aStack[i].n-1;
         3960  +      memcpy(&zNewKey[j], pRec->z, pRec->n-1);
         3961  +      j += pRec->n-1;
  3982   3962         zNewKey[j++] = 0;
  3983   3963       }
  3984   3964     }
  3985   3965     zNewKey[j] = 0;
  3986   3966     assert( j<nByte );
  3987         -  sqliteVdbePopStack(p, nField);
  3988         -  p->tos++;
  3989         -  aStack[p->tos].n = nByte;
  3990         -  aStack[p->tos].flags = MEM_Str|MEM_Dyn;
  3991         -  aStack[p->tos].z = zNewKey;
         3967  +  popStack(&pTos, nField);
         3968  +  pTos++;
         3969  +  pTos->n = nByte;
         3970  +  pTos->flags = MEM_Str|MEM_Dyn;
         3971  +  pTos->z = zNewKey;
  3992   3972     break;
  3993   3973   }
  3994   3974   
  3995   3975   /* Opcode: Sort * * *
  3996   3976   **
  3997   3977   ** Sort all elements on the sorter.  The algorithm is a
  3998   3978   ** mergesort.
................................................................................
  4037   4017   ** to instruction P2.
  4038   4018   */
  4039   4019   case OP_SortNext: {
  4040   4020     Sorter *pSorter = p->pSort;
  4041   4021     CHECK_FOR_INTERRUPT;
  4042   4022     if( pSorter!=0 ){
  4043   4023       p->pSort = pSorter->pNext;
  4044         -    p->tos++;
  4045         -    aStack[p->tos].z = pSorter->pData;
  4046         -    aStack[p->tos].n = pSorter->nData;
  4047         -    aStack[p->tos].flags = MEM_Str|MEM_Dyn;
         4024  +    pTos++;
         4025  +    pTos->z = pSorter->pData;
         4026  +    pTos->n = pSorter->nData;
         4027  +    pTos->flags = MEM_Str|MEM_Dyn;
  4048   4028       sqliteFree(pSorter->zKey);
  4049   4029       sqliteFree(pSorter);
  4050   4030     }else{
  4051   4031       pc = pOp->p2 - 1;
  4052   4032     }
  4053   4033     break;
  4054   4034   }
................................................................................
  4057   4037   **
  4058   4038   ** The top of the stack contains a callback record built using
  4059   4039   ** the SortMakeRec operation with the same P1 value as this
  4060   4040   ** instruction.  Pop this record from the stack and invoke the
  4061   4041   ** callback on it.
  4062   4042   */
  4063   4043   case OP_SortCallback: {
  4064         -  int i = p->tos;
  4065         -  VERIFY( if( i<0 ) goto not_enough_stack; )
         4044  +  assert( pTos>=p->aStack );
         4045  +  assert( pTos->flags & MEM_Str );
  4066   4046     if( p->xCallback==0 ){
  4067   4047       p->pc = pc+1;
  4068         -    p->azResColumn = (char**)aStack[i].z;
         4048  +    p->azResColumn = (char**)pTos->z;
  4069   4049       p->nResColumn = pOp->p1;
  4070   4050       p->popStack = 1;
         4051  +    p->pTos = pTos;
  4071   4052       return SQLITE_ROW;
  4072   4053     }else{
  4073   4054       if( sqliteSafetyOff(db) ) goto abort_due_to_misuse;
  4074         -    if( p->xCallback(p->pCbArg, pOp->p1, (char**)aStack[i].z, p->azColName)!=0){
         4055  +    if( p->xCallback(p->pCbArg, pOp->p1, (char**)pTos->z, p->azColName)!=0){
  4075   4056         rc = SQLITE_ABORT;
  4076   4057       }
  4077   4058       if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;
  4078   4059       p->nCallback++;
  4079   4060     }
  4080         -  POPSTACK;
         4061  +  Release(pTos);
         4062  +  pTos--;
  4081   4063     if( sqlite_malloc_failed ) goto no_mem;
  4082   4064     break;
  4083   4065   }
  4084   4066   
  4085   4067   /* Opcode: SortReset * * *
  4086   4068   **
  4087   4069   ** Remove any elements that remain on the sorter.
................................................................................
  4093   4075   
  4094   4076   /* Opcode: FileOpen * * P3
  4095   4077   **
  4096   4078   ** Open the file named by P3 for reading using the FileRead opcode.
  4097   4079   ** If P3 is "stdin" then open standard input for reading.
  4098   4080   */
  4099   4081   case OP_FileOpen: {
  4100         -  VERIFY( if( pOp->p3==0 ) goto bad_instruction; )
         4082  +  assert( pOp->p3!=0 );
  4101   4083     if( p->pFile ){
  4102   4084       if( p->pFile!=stdin ) fclose(p->pFile);
  4103   4085       p->pFile = 0;
  4104   4086     }
  4105   4087     if( sqliteStrICmp(pOp->p3,"stdin")==0 ){
  4106   4088       p->pFile = stdin;
  4107   4089     }else{
................................................................................
  4238   4220   **
  4239   4221   ** Push onto the stack the P1-th column of the most recently read line
  4240   4222   ** from the input file.
  4241   4223   */
  4242   4224   case OP_FileColumn: {
  4243   4225     int i = pOp->p1;
  4244   4226     char *z;
  4245         -  if( VERIFY( i>=0 && i<p->nField && ) p->azField ){
         4227  +  assert( i>=0 && i<p->nField );
         4228  +  if( p->azField ){
  4246   4229       z = p->azField[i];
  4247   4230     }else{
  4248   4231       z = 0;
  4249   4232     }
  4250         -  p->tos++;
         4233  +  pTos++;
  4251   4234     if( z ){
  4252         -    aStack[p->tos].n = strlen(z) + 1;
  4253         -    aStack[p->tos].z = z;
  4254         -    aStack[p->tos].flags = MEM_Str;
         4235  +    pTos->n = strlen(z) + 1;
         4236  +    pTos->z = z;
         4237  +    pTos->flags = MEM_Str | MEM_Ephem;
  4255   4238     }else{
  4256         -    aStack[p->tos].n = 0;
  4257         -    aStack[p->tos].z = 0;
  4258         -    aStack[p->tos].flags = MEM_Null;
         4239  +    pTos->flags = MEM_Null;
  4259   4240     }
  4260   4241     break;
  4261   4242   }
  4262   4243   
  4263   4244   /* Opcode: MemStore P1 P2 *
  4264   4245   **
  4265   4246   ** Write the top of the stack into memory location P1.
................................................................................
  4268   4249   **
  4269   4250   ** After the data is stored in the memory location, the
  4270   4251   ** stack is popped once if P2 is 1.  If P2 is zero, then
  4271   4252   ** the original data remains on the stack.
  4272   4253   */
  4273   4254   case OP_MemStore: {
  4274   4255     int i = pOp->p1;
  4275         -  int tos = p->tos;
  4276   4256     char *zOld;
  4277   4257     Mem *pMem;
  4278   4258     int flags;
  4279         -  VERIFY( if( tos<0 ) goto not_enough_stack; )
         4259  +  assert( pTos>=p->aStack );
  4280   4260     if( i>=p->nMem ){
  4281   4261       int nOld = p->nMem;
  4282   4262       Mem *aMem;
  4283   4263       p->nMem = i + 5;
  4284   4264       aMem = sqliteRealloc(p->aMem, p->nMem*sizeof(p->aMem[0]));
  4285   4265       if( aMem==0 ) goto no_mem;
  4286   4266       if( aMem!=p->aMem ){
  4287   4267         int j;
  4288   4268         for(j=0; j<nOld; j++){
  4289         -        if( aMem[j].z==p->aMem[j].zShort ){
         4269  +        if( aMem[j].flags & MEM_Short ){
  4290   4270             aMem[j].z = aMem[j].zShort;
  4291   4271           }
  4292   4272         }
  4293   4273       }
  4294   4274       p->aMem = aMem;
  4295   4275       if( nOld<p->nMem ){
  4296   4276         memset(&p->aMem[nOld], 0, sizeof(p->aMem[0])*(p->nMem-nOld));
................................................................................
  4299   4279     pMem = &p->aMem[i];
  4300   4280     flags = pMem->flags;
  4301   4281     if( flags & MEM_Dyn ){
  4302   4282       zOld = pMem->z;
  4303   4283     }else{
  4304   4284       zOld = 0;
  4305   4285     }
  4306         -  *pMem = aStack[tos];
         4286  +  *pMem = *pTos;
  4307   4287     flags = pMem->flags;
  4308         -  if( flags & (MEM_Static|MEM_Dyn|MEM_Ephem) ){
  4309         -    if( (flags & MEM_Static)!=0 || (pOp->p2 && (flags & MEM_Dyn)!=0) ){
  4310         -      /* pMem->z = zStack[tos]; *** do nothing */
  4311         -    }else if( flags & MEM_Str ){
         4288  +  if( flags & MEM_Dyn ){
         4289  +    if( pOp->p2 ){
         4290  +      pTos->flags = MEM_Null;
         4291  +    }else{
         4292  +      /* OR: perhaps just make the stack ephermeral */
  4312   4293         pMem->z = sqliteMallocRaw( pMem->n );
  4313   4294         if( pMem->z==0 ) goto no_mem;
  4314         -      memcpy(pMem->z, aStack[tos].z, pMem->n);
  4315         -      pMem->flags |= MEM_Dyn;
  4316         -      pMem->flags &= ~(MEM_Static|MEM_Ephem);
         4295  +      memcpy(pMem->z, pTos->z, pMem->n);
  4317   4296       }
  4318         -  }else{
         4297  +  }else if( flags & MEM_Short ){
  4319   4298       pMem->z = pMem->zShort;
  4320   4299     }
  4321   4300     if( zOld ) sqliteFree(zOld);
  4322   4301     if( pOp->p2 ){
  4323         -    aStack[tos].z = 0;
  4324         -    aStack[tos].flags = 0;
  4325         -    POPSTACK;
         4302  +    Release(pTos);
         4303  +    pTos--;
  4326   4304     }
  4327   4305     break;
  4328   4306   }
  4329   4307   
  4330   4308   /* Opcode: MemLoad P1 * *
  4331   4309   **
  4332   4310   ** Push a copy of the value in memory location P1 onto the stack.
................................................................................
  4333   4311   **
  4334   4312   ** If the value is a string, then the value pushed is a pointer to
  4335   4313   ** the string that is stored in the memory location.  If the memory
  4336   4314   ** location is subsequently changed (using OP_MemStore) then the
  4337   4315   ** value pushed onto the stack will change too.
  4338   4316   */
  4339   4317   case OP_MemLoad: {
  4340         -  int tos = ++p->tos;
  4341   4318     int i = pOp->p1;
  4342         -  VERIFY( if( i<0 || i>=p->nMem ) goto bad_instruction; )
  4343         -  memcpy(&aStack[tos], &p->aMem[i], sizeof(aStack[tos])-NBFS);;
  4344         -  if( aStack[tos].flags & MEM_Str ){
  4345         -    /* aStack[tos].z = p->aMem[i].z; */
  4346         -    aStack[tos].flags |= MEM_Ephem;
  4347         -    aStack[tos].flags &= ~(MEM_Dyn|MEM_Static);
         4319  +  assert( i>=0 && i<p->nMem );
         4320  +  pTos++;
         4321  +  memcpy(pTos, &p->aMem[i], sizeof(pTos[0])-NBFS);;
         4322  +  if( pTos->flags & MEM_Str ){
         4323  +    pTos->flags |= MEM_Ephem;
         4324  +    pTos->flags &= ~(MEM_Dyn|MEM_Static|MEM_Short);
  4348   4325     }
  4349   4326     break;
  4350   4327   }
  4351   4328   
  4352   4329   /* Opcode: MemIncr P1 P2 *
  4353   4330   **
  4354   4331   ** Increment the integer valued memory cell P1 by 1.  If P2 is not zero
................................................................................
  4357   4334   **
  4358   4335   ** This instruction throws an error if the memory cell is not initially
  4359   4336   ** an integer.
  4360   4337   */
  4361   4338   case OP_MemIncr: {
  4362   4339     int i = pOp->p1;
  4363   4340     Mem *pMem;
  4364         -  VERIFY( if( i<0 || i>=p->nMem ) goto bad_instruction; )
         4341  +  assert( i>=0 && i<p->nMem );
  4365   4342     pMem = &p->aMem[i];
  4366         -  VERIFY( if( pMem->flags != MEM_Int ) goto bad_instruction; )
         4343  +  assert( pMem->flags==MEM_Int );
  4367   4344     pMem->i++;
  4368   4345     if( pOp->p2>0 && pMem->i>0 ){
  4369   4346        pc = pOp->p2 - 1;
  4370   4347     }
  4371   4348     break;
  4372   4349   }
  4373   4350   
................................................................................
  4388   4365   **
  4389   4366   ** Initialize the function parameters for an aggregate function.
  4390   4367   ** The aggregate will operate out of aggregate column P2.
  4391   4368   ** P3 is a pointer to the FuncDef structure for the function.
  4392   4369   */
  4393   4370   case OP_AggInit: {
  4394   4371     int i = pOp->p2;
  4395         -  VERIFY( if( i<0 || i>=p->agg.nMem ) goto bad_instruction; )
         4372  +  assert( i>=0 && i<p->agg.nMem );
  4396   4373     p->agg.apFunc[i] = (FuncDef*)pOp->p3;
  4397   4374     break;
  4398   4375   }
  4399   4376   
  4400   4377   /* Opcode: AggFunc * P2 P3
  4401   4378   **
  4402   4379   ** Execute the step function for an aggregate.  The
................................................................................
  4407   4384   ** the aggregate column that corresponds to this aggregate function.
  4408   4385   ** Ideally, this index would be another parameter, but there are
  4409   4386   ** no free parameters left.  The integer is popped from the stack.
  4410   4387   */
  4411   4388   case OP_AggFunc: {
  4412   4389     int n = pOp->p2;
  4413   4390     int i;
  4414         -  Mem *pMem;
         4391  +  Mem *pMem, *pRec;
         4392  +  char **azArgv = p->zArgv;
  4415   4393     sqlite_func ctx;
  4416   4394   
  4417         -  VERIFY( if( n<0 ) goto bad_instruction; )
  4418         -  VERIFY( if( p->tos+1<n ) goto not_enough_stack; )
  4419         -  VERIFY( if( aStack[p->tos].flags!=MEM_Int ) goto bad_instruction; )
  4420         -  for(i=p->tos-n; i<p->tos; i++){
  4421         -    if( aStack[i].flags & MEM_Null ){
  4422         -      aStack[i].z = 0;
         4395  +  assert( n>=0 );
         4396  +  assert( pTos->flags==MEM_Int );
         4397  +  pRec = &pTos[-n];
         4398  +  assert( pRec>=p->aStack );
         4399  +  for(i=0; i<n; i++, pRec++){
         4400  +    if( pRec->flags & MEM_Null ){
         4401  +      azArgv[i] = 0;
  4423   4402       }else{
  4424         -      Stringify(p, i);
         4403  +      Stringify(pRec);
         4404  +      azArgv[i] = pRec->z;
  4425   4405       }
  4426         -    p->zArgv[i] = aStack[i].z;
  4427   4406     }
  4428         -  i = aStack[p->tos].i;
  4429         -  VERIFY( if( i<0 || i>=p->agg.nMem ) goto bad_instruction; )
         4407  +  i = pTos->i;
         4408  +  assert( i>=0 && i<p->agg.nMem );
  4430   4409     ctx.pFunc = (FuncDef*)pOp->p3;
  4431   4410     pMem = &p->agg.pCurrent->aMem[i];
  4432   4411     ctx.s.z = pMem->zShort;  /* Space used for small aggregate contexts */
  4433   4412     ctx.pAgg = pMem->z;
  4434   4413     ctx.cnt = ++pMem->i;
  4435   4414     ctx.isError = 0;
  4436   4415     ctx.isStep = 1;
  4437         -  (ctx.pFunc->xStep)(&ctx, n, (const char**)&p->zArgv[p->tos-n]);
         4416  +  (ctx.pFunc->xStep)(&ctx, n, (const char**)azArgv);
  4438   4417     pMem->z = ctx.pAgg;
  4439   4418     pMem->flags = MEM_AggCtx;
  4440         -  sqliteVdbePopStack(p, n+1);
         4419  +  popStack(&pTos, n+1);
  4441   4420     if( ctx.isError ){
  4442   4421       rc = SQLITE_ERROR;
  4443   4422     }
  4444   4423     break;
  4445   4424   }
  4446   4425   
  4447   4426   /* Opcode: AggFocus * P2 *
................................................................................
  4455   4434   ** The order of aggregator opcodes is important.  The order is:
  4456   4435   ** AggReset AggFocus AggNext.  In other words, you must execute
  4457   4436   ** AggReset first, then zero or more AggFocus operations, then
  4458   4437   ** zero or more AggNext operations.  You must not execute an AggFocus
  4459   4438   ** in between an AggNext and an AggReset.
  4460   4439   */
  4461   4440   case OP_AggFocus: {
  4462         -  int tos = p->tos;
  4463   4441     AggElem *pElem;
  4464   4442     char *zKey;
  4465   4443     int nKey;
  4466   4444   
  4467         -  VERIFY( if( tos<0 ) goto not_enough_stack; )
  4468         -  Stringify(p, tos);
  4469         -  zKey = aStack[tos].z; 
  4470         -  nKey = aStack[tos].n;
         4445  +  assert( pTos>=p->aStack );
         4446  +  Stringify(pTos);
         4447  +  zKey = pTos->z;
         4448  +  nKey = pTos->n;
  4471   4449     pElem = sqliteHashFind(&p->agg.hash, zKey, nKey);
  4472   4450     if( pElem ){
  4473   4451       p->agg.pCurrent = pElem;
  4474   4452       pc = pOp->p2 - 1;
  4475   4453     }else{
  4476   4454       AggInsert(&p->agg, zKey, nKey);
  4477   4455       if( sqlite_malloc_failed ) goto no_mem;
  4478   4456     }
  4479         -  POPSTACK;
         4457  +  Release(pTos);
         4458  +  pTos--;
  4480   4459     break; 
  4481   4460   }
  4482   4461   
  4483   4462   /* Opcode: AggSet * P2 *
  4484   4463   **
  4485   4464   ** Move the top of the stack into the P2-th field of the current
  4486   4465   ** aggregate.  String values are duplicated into new memory.
  4487   4466   */
  4488   4467   case OP_AggSet: {
  4489   4468     AggElem *pFocus = AggInFocus(p->agg);
  4490   4469     int i = pOp->p2;
  4491         -  int tos = p->tos;
  4492         -  VERIFY( if( tos<0 ) goto not_enough_stack; )
         4470  +  assert( pTos>=p->aStack );
  4493   4471     if( pFocus==0 ) goto no_mem;
  4494         -  if( VERIFY( i>=0 && ) i<p->agg.nMem ){
         4472  +  assert( i>=0 );
         4473  +  assert( i<p->agg.nMem );
         4474  +  if( i<p->agg.nMem ){
  4495   4475       Mem *pMem = &pFocus->aMem[i];
  4496   4476       char *zOld;
  4497   4477       if( pMem->flags & MEM_Dyn ){
  4498   4478         zOld = pMem->z;
  4499   4479       }else{
  4500   4480         zOld = 0;
  4501   4481       }
  4502         -    Deephemeralize(p, tos);
  4503         -    *pMem = aStack[tos];
         4482  +    Deephemeralize(pTos);
         4483  +    *pMem = *pTos;
  4504   4484       if( pMem->flags & MEM_Dyn ){
  4505         -      aStack[tos].z = 0;
  4506         -      aStack[tos].flags = 0;
  4507         -    }else if( pMem->flags & (MEM_Static|MEM_AggCtx) ){
  4508         -      /* pMem->z = zStack[tos]; *** do nothing */
  4509         -    }else if( pMem->flags & MEM_Str ){
         4485  +      pTos->flags = MEM_Null;
         4486  +    }else if( pMem->flags & MEM_Short ){
  4510   4487         pMem->z = pMem->zShort;
  4511   4488       }
  4512   4489       if( zOld ) sqliteFree(zOld);
  4513   4490     }
  4514         -  POPSTACK;
         4491  +  Release(pTos);
         4492  +  pTos--;
  4515   4493     break;
  4516   4494   }
  4517   4495   
  4518   4496   /* Opcode: AggGet * P2 *
  4519   4497   **
  4520   4498   ** Push a new entry onto the stack which is a copy of the P2-th field
  4521   4499   ** of the current aggregate.  Strings are not duplicated so
  4522   4500   ** string values will be ephemeral.
  4523   4501   */
  4524   4502   case OP_AggGet: {
  4525   4503     AggElem *pFocus = AggInFocus(p->agg);
  4526   4504     int i = pOp->p2;
  4527         -  int tos = ++p->tos;
  4528   4505     if( pFocus==0 ) goto no_mem;
  4529         -  if( VERIFY( i>=0 && ) i<p->agg.nMem ){
         4506  +  assert( i>=0 );
         4507  +  pTos++;
         4508  +  assert( i<p->agg.nMem );
         4509  +  if( i<p->agg.nMem ){
  4530   4510       Mem *pMem = &pFocus->aMem[i];
  4531         -    aStack[tos] = *pMem;
  4532         -    aStack[tos].flags &= ~MEM_Dyn;
  4533         -    aStack[tos].flags |= MEM_Ephem;
         4511  +    *pTos = *pMem;
         4512  +    pTos->flags &= ~(MEM_Dyn|MEM_Static|MEM_Short);
         4513  +    pTos->flags |= MEM_Ephem;
  4534   4514     }
  4535   4515     break;
  4536   4516   }
  4537   4517   
  4538   4518   /* Opcode: AggNext * P2 *
  4539   4519   **
  4540   4520   ** Make the next aggregate value the current aggregate.  The prior
................................................................................
  4574   4554         ctx.isStep = 0;
  4575   4555         ctx.pFunc = p->agg.apFunc[i];
  4576   4556         (*p->agg.apFunc[i]->xFinalize)(&ctx);
  4577   4557         if( freeCtx ){
  4578   4558           sqliteFree( aMem[i].z );
  4579   4559         }
  4580   4560         aMem[i] = ctx.s;
  4581         -      if( (aMem[i].flags & MEM_Str) &&
  4582         -              (aMem[i].flags & (MEM_Dyn|MEM_Static|MEM_Ephem))==0 ){
         4561  +      if( aMem[i].flags & MEM_Short ){
  4583   4562           aMem[i].z = aMem[i].zShort;
  4584   4563         }
  4585   4564       }
  4586   4565     }
  4587   4566     break;
  4588   4567   }
  4589   4568   
................................................................................
  4604   4583         sqliteHashInit(&p->aSet[k].hash, SQLITE_HASH_BINARY, 1);
  4605   4584       }
  4606   4585       p->nSet = i+1;
  4607   4586     }
  4608   4587     if( pOp->p3 ){
  4609   4588       sqliteHashInsert(&p->aSet[i].hash, pOp->p3, strlen(pOp->p3)+1, p);
  4610   4589     }else{
  4611         -    int tos = p->tos;
  4612         -    if( tos<0 ) goto not_enough_stack;
  4613         -    Stringify(p, tos);
  4614         -    sqliteHashInsert(&p->aSet[i].hash, aStack[tos].z, aStack[tos].n, p);
  4615         -    POPSTACK;
         4590  +    assert( pTos>=p->aStack );
         4591  +    Stringify(pTos);
         4592  +    sqliteHashInsert(&p->aSet[i].hash, pTos->z, pTos->n, p);
         4593  +    Release(pTos);
         4594  +    pTos--;
  4616   4595     }
  4617   4596     if( sqlite_malloc_failed ) goto no_mem;
  4618   4597     break;
  4619   4598   }
  4620   4599   
  4621   4600   /* Opcode: SetFound P1 P2 *
  4622   4601   **
  4623   4602   ** Pop the stack once and compare the value popped off with the
  4624   4603   ** contents of set P1.  If the element popped exists in set P1,
  4625   4604   ** then jump to P2.  Otherwise fall through.
  4626   4605   */
  4627   4606   case OP_SetFound: {
  4628   4607     int i = pOp->p1;
  4629         -  int tos = p->tos;
  4630         -  VERIFY( if( tos<0 ) goto not_enough_stack; )
  4631         -  Stringify(p, tos);
  4632         -  if( i>=0 && i<p->nSet &&
  4633         -       sqliteHashFind(&p->aSet[i].hash, aStack[tos].z, aStack[tos].n)){
         4608  +  assert( pTos>=p->aStack );
         4609  +  Stringify(pTos);
         4610  +  if( i>=0 && i<p->nSet && sqliteHashFind(&p->aSet[i].hash, pTos->z, pTos->n)){
  4634   4611       pc = pOp->p2 - 1;
  4635   4612     }
  4636         -  POPSTACK;
         4613  +  Release(pTos);
         4614  +  pTos--;
  4637   4615     break;
  4638   4616   }
  4639   4617   
  4640   4618   /* Opcode: SetNotFound P1 P2 *
  4641   4619   **
  4642   4620   ** Pop the stack once and compare the value popped off with the
  4643   4621   ** contents of set P1.  If the element popped does not exists in 
  4644   4622   ** set P1, then jump to P2.  Otherwise fall through.
  4645   4623   */
  4646   4624   case OP_SetNotFound: {
  4647   4625     int i = pOp->p1;
  4648         -  int tos = p->tos;
  4649         -  VERIFY( if( tos<0 ) goto not_enough_stack; )
  4650         -  Stringify(p, tos);
         4626  +  assert( pTos>=p->aStack );
         4627  +  Stringify(pTos);
  4651   4628     if( i<0 || i>=p->nSet ||
  4652         -       sqliteHashFind(&p->aSet[i].hash, aStack[tos].z, aStack[tos].n)==0 ){
         4629  +       sqliteHashFind(&p->aSet[i].hash, pTos->z, pTos->n)==0 ){
  4653   4630       pc = pOp->p2 - 1;
  4654   4631     }
  4655         -  POPSTACK;
         4632  +  Release(pTos);
         4633  +  pTos--;
  4656   4634     break;
  4657   4635   }
  4658   4636   
  4659   4637   /* Opcode: SetFirst P1 P2 *
  4660   4638   **
  4661   4639   ** Read the first element from set P1 and push it onto the stack.  If the
  4662   4640   ** set is empty, push nothing and jump immediately to P2.  This opcode is
................................................................................
  4667   4645   ** Read the next element from set P1 and push it onto the stack.  If there
  4668   4646   ** are no more elements in the set, do not do the push and fall through.
  4669   4647   ** Otherwise, jump to P2 after pushing the next set element.
  4670   4648   */
  4671   4649   case OP_SetFirst: 
  4672   4650   case OP_SetNext: {
  4673   4651     Set *pSet;
  4674         -  int tos;
  4675   4652     CHECK_FOR_INTERRUPT;
  4676   4653     if( pOp->p1<0 || pOp->p1>=p->nSet ){
  4677   4654       if( pOp->opcode==OP_SetFirst ) pc = pOp->p2 - 1;
  4678   4655       break;
  4679   4656     }
  4680   4657     pSet = &p->aSet[pOp->p1];
  4681   4658     if( pOp->opcode==OP_SetFirst ){
  4682   4659       pSet->prev = sqliteHashFirst(&pSet->hash);
  4683   4660       if( pSet->prev==0 ){
  4684   4661         pc = pOp->p2 - 1;
  4685   4662         break;
  4686   4663       }
  4687   4664     }else{
  4688         -    VERIFY( if( pSet->prev==0 ) goto bad_instruction; )
         4665  +    assert( pSet->prev );
  4689   4666       pSet->prev = sqliteHashNext(pSet->prev);
  4690   4667       if( pSet->prev==0 ){
  4691   4668         break;
  4692   4669       }else{
  4693   4670         pc = pOp->p2 - 1;
  4694   4671       }
  4695   4672     }
  4696         -  tos = ++p->tos;
  4697         -  aStack[tos].z = sqliteHashKey(pSet->prev);
  4698         -  aStack[tos].n = sqliteHashKeysize(pSet->prev);
  4699         -  aStack[tos].flags = MEM_Str | MEM_Ephem;
         4673  +  pTos++;
         4674  +  pTos->z = sqliteHashKey(pSet->prev);
         4675  +  pTos->n = sqliteHashKeysize(pSet->prev);
         4676  +  pTos->flags = MEM_Str | MEM_Ephem;
  4700   4677     break;
  4701   4678   }
  4702   4679   
  4703   4680   /* Opcode: Vacuum * * *
  4704   4681   **
  4705   4682   ** Vacuum the entire database.  This opcode will cause other virtual
  4706   4683   ** machines to be created and run.  It may not be called from within
................................................................................
  4748   4725       ** the evaluator loop.  So we can leave it out when NDEBUG is defined.
  4749   4726       */
  4750   4727   #ifndef NDEBUG
  4751   4728       if( pc<-1 || pc>=p->nOp ){
  4752   4729         sqliteSetString(&p->zErrMsg, "jump destination out of range", (char*)0);
  4753   4730         rc = SQLITE_INTERNAL;
  4754   4731       }
  4755         -    if( p->trace && p->tos>=0 ){
         4732  +    if( p->trace && pTos>=p->aStack ){
  4756   4733         int i;
  4757   4734         fprintf(p->trace, "Stack:");
  4758         -      for(i=p->tos; i>=0 && i>p->tos-5; i--){
  4759         -        if( aStack[i].flags & MEM_Null ){
         4735  +      for(i=0; i>-5 && &pTos[i]>=p->aStack; i--){
         4736  +        if( pTos[i].flags & MEM_Null ){
  4760   4737             fprintf(p->trace, " NULL");
  4761         -        }else if( (aStack[i].flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
  4762         -          fprintf(p->trace, " si:%d", aStack[i].i);
  4763         -        }else if( aStack[i].flags & MEM_Int ){
  4764         -          fprintf(p->trace, " i:%d", aStack[i].i);
  4765         -        }else if( aStack[i].flags & MEM_Real ){
  4766         -          fprintf(p->trace, " r:%g", aStack[i].r);
  4767         -        }else if( aStack[i].flags & MEM_Str ){
         4738  +        }else if( (pTos[i].flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
         4739  +          fprintf(p->trace, " si:%d", pTos[i].i);
         4740  +        }else if( pTos[i].flags & MEM_Int ){
         4741  +          fprintf(p->trace, " i:%d", pTos[i].i);
         4742  +        }else if( pTos[i].flags & MEM_Real ){
         4743  +          fprintf(p->trace, " r:%g", pTos[i].r);
         4744  +        }else if( pTos[i].flags & MEM_Str ){
  4768   4745             int j, k;
  4769   4746             char zBuf[100];
  4770   4747             zBuf[0] = ' ';
  4771         -          if( aStack[i].flags & MEM_Dyn ){
         4748  +          if( pTos[i].flags & MEM_Dyn ){
  4772   4749               zBuf[1] = 'z';
  4773         -            assert( (aStack[i].flags & (MEM_Static|MEM_Ephem))==0 );
  4774         -          }else if( aStack[i].flags & MEM_Static ){
         4750  +            assert( (pTos[i].flags & (MEM_Static|MEM_Ephem))==0 );
         4751  +          }else if( pTos[i].flags & MEM_Static ){
  4775   4752               zBuf[1] = 't';
  4776         -            assert( (aStack[i].flags & (MEM_Dyn|MEM_Ephem))==0 );
  4777         -          }else if( aStack[i].flags & MEM_Ephem ){
         4753  +            assert( (pTos[i].flags & (MEM_Dyn|MEM_Ephem))==0 );
         4754  +          }else if( pTos[i].flags & MEM_Ephem ){
  4778   4755               zBuf[1] = 'e';
  4779         -            assert( (aStack[i].flags & (MEM_Static|MEM_Dyn))==0 );
         4756  +            assert( (pTos[i].flags & (MEM_Static|MEM_Dyn))==0 );
  4780   4757             }else{
  4781   4758               zBuf[1] = 's';
  4782   4759             }
  4783   4760             zBuf[2] = '[';
  4784   4761             k = 3;
  4785         -          for(j=0; j<20 && j<aStack[i].n; j++){
  4786         -            int c = aStack[i].z[j];
  4787         -            if( c==0 && j==aStack[i].n-1 ) break;
         4762  +          for(j=0; j<20 && j<pTos[i].n; j++){
         4763  +            int c = pTos[i].z[j];
         4764  +            if( c==0 && j==pTos[i].n-1 ) break;
  4788   4765               if( isprint(c) && !isspace(c) ){
  4789   4766                 zBuf[k++] = c;
  4790   4767               }else{
  4791   4768                 zBuf[k++] = '.';
  4792   4769               }
  4793   4770             }
  4794   4771             zBuf[k++] = ']';
................................................................................
  4810   4787     if( rc ){
  4811   4788       p->rc = rc;
  4812   4789       rc = SQLITE_ERROR;
  4813   4790     }else{
  4814   4791       rc = SQLITE_DONE;
  4815   4792     }
  4816   4793     p->magic = VDBE_MAGIC_HALT;
         4794  +  p->pTos = pTos;
  4817   4795     return rc;
  4818   4796   
  4819   4797     /* Jump to here if a malloc() fails.  It's hard to get a malloc()
  4820   4798     ** to fail on a modern VM computer, so this code is untested.
  4821   4799     */
  4822   4800   no_mem:
  4823   4801     sqliteSetString(&p->zErrMsg, "out of memory", (char*)0);
................................................................................
  4848   4826     if( db->magic!=SQLITE_MAGIC_BUSY ){
  4849   4827       rc = SQLITE_MISUSE;
  4850   4828     }else{
  4851   4829       rc = SQLITE_INTERRUPT;
  4852   4830     }
  4853   4831     sqliteSetString(&p->zErrMsg, sqlite_error_string(rc), (char*)0);
  4854   4832     goto vdbe_halt;
  4855         -
  4856         -  /* Jump to here if a operator is encountered that requires more stack
  4857         -  ** operands than are currently available on the stack.
  4858         -  */
  4859         -not_enough_stack:
  4860         -  sqlite_snprintf(sizeof(zBuf),zBuf,"%d",pc);
  4861         -  sqliteSetString(&p->zErrMsg, "too few operands on stack at ", zBuf, (char*)0);
  4862         -  rc = SQLITE_INTERNAL;
  4863         -  goto vdbe_halt;
  4864         -
  4865         -  /* Jump here if an illegal or illformed instruction is executed.
  4866         -  */
  4867         -VERIFY(
  4868         -bad_instruction:
  4869         -  sqlite_snprintf(sizeof(zBuf),zBuf,"%d",pc);
  4870         -  sqliteSetString(&p->zErrMsg, "illegal operation at ", zBuf, (char*)0);
  4871         -  rc = SQLITE_INTERNAL;
  4872         -  goto vdbe_halt;
  4873         -)
  4874   4833   }

Changes to src/vdbeInt.h.

   125    125   #define MEM_Null      0x0001   /* Value is NULL */
   126    126   #define MEM_Str       0x0002   /* Value is a string */
   127    127   #define MEM_Int       0x0004   /* Value is an integer */
   128    128   #define MEM_Real      0x0008   /* Value is a real number */
   129    129   #define MEM_Dyn       0x0010   /* Need to call sqliteFree() on Mem.z */
   130    130   #define MEM_Static    0x0020   /* Mem.z points to a static string */
   131    131   #define MEM_Ephem     0x0040   /* Mem.z points to an ephemeral string */
          132  +#define MEM_Short     0x0080   /* Mem.z points to Mem.zShort */
   132    133   
   133    134   /* The following MEM_ value appears only in AggElem.aMem.s.flag fields.
   134    135   ** It indicates that the corresponding AggElem.aMem.z points to a
   135    136   ** aggregate function context that needs to be finalized.
   136    137   */
   137         -#define MEM_AggCtx    0x0040   /* Mem.z points to an agg function context */
          138  +#define MEM_AggCtx    0x0100   /* Mem.z points to an agg function context */
   138    139   
   139    140   /*
   140    141   ** The "context" argument for a installable function.  A pointer to an
   141    142   ** instance of this structure is the first argument to the routines used
   142    143   ** implement the SQL functions.
   143    144   **
   144    145   ** There is a typedef for this structure in sqlite.h.  So all routines,
................................................................................
   219    220     FILE *trace;        /* Write an execution trace here, if not NULL */
   220    221     int nOp;            /* Number of instructions in the program */
   221    222     int nOpAlloc;       /* Number of slots allocated for aOp[] */
   222    223     Op *aOp;            /* Space to hold the virtual machine's program */
   223    224     int nLabel;         /* Number of labels used */
   224    225     int nLabelAlloc;    /* Number of slots allocated in aLabel[] */
   225    226     int *aLabel;        /* Space to hold the labels */
   226         -  int tos;            /* Index of top of stack */
   227    227     Mem *aStack;        /* The operand stack, except string values */
          228  +  Mem *pTos;          /* Top entry in the operand stack */
   228    229     char **zArgv;       /* Text values used by the callback */
   229    230     char **azColName;   /* Becomes the 4th parameter to callbacks */
   230    231     int nCursor;        /* Number of slots in aCsr[] */
   231    232     Cursor *aCsr;       /* One element of this array for each open cursor */
   232    233     Sorter *pSort;      /* A linked list of objects to be sorted */
   233    234     FILE *pFile;        /* At most one open file handler */
   234    235     int nField;         /* Number of file fields */
................................................................................
   270    271   ** The following are allowed values for Vdbe.magic
   271    272   */
   272    273   #define VDBE_MAGIC_INIT     0x26bceaa5    /* Building a VDBE program */
   273    274   #define VDBE_MAGIC_RUN      0xbdf20da3    /* VDBE is ready to execute */
   274    275   #define VDBE_MAGIC_HALT     0x519c2973    /* VDBE has completed execution */
   275    276   #define VDBE_MAGIC_DEAD     0xb606c3c8    /* The VDBE has been deallocated */
   276    277   
   277         -/*
   278         -** Here is a macro to handle the common case of popping the stack
   279         -** once.  This macro only works from within the sqliteVdbeExec()
   280         -** function.
   281         -*/
   282         -#define POPSTACK \
   283         -  assert(p->tos>=0); \
   284         -  if( aStack[p->tos].flags & MEM_Dyn ) sqliteFree(aStack[p->tos].z); \
   285         -  p->tos--;
   286         -
   287    278   /*
   288    279   ** Function prototypes
   289    280   */
   290    281   void sqliteVdbeCleanupCursor(Cursor*);
   291    282   void sqliteVdbeSorterReset(Vdbe*);
   292    283   void sqliteVdbeAggReset(Agg*);
   293    284   void sqliteVdbeKeylistFree(Keylist*);
   294    285   void sqliteVdbePopStack(Vdbe*,int);
   295    286   int sqliteVdbeCursorMoveto(Cursor*);
   296    287   int sqliteVdbeByteSwap(int);
   297    288   #if !defined(NDEBUG) || defined(VDBE_PROFILE)
   298    289   void sqliteVdbePrintOp(FILE*, int, Op*);
   299    290   #endif

Changes to src/vdbeaux.c.

   384    384       p->s.z = 0;
   385    385       p->s.n = 0;
   386    386     }else{
   387    387       if( n<0 ) n = strlen(zResult);
   388    388       if( n<NBFS-1 ){
   389    389         memcpy(p->s.zShort, zResult, n);
   390    390         p->s.zShort[n] = 0;
   391         -      p->s.flags = MEM_Str;
          391  +      p->s.flags = MEM_Str | MEM_Short;
   392    392         p->s.z = p->s.zShort;
   393    393       }else{
   394    394         p->s.z = sqliteMallocRaw( n+1 );
   395    395         if( p->s.z ){
   396    396           memcpy(p->s.z, zResult, n);
   397    397           p->s.z[n] = 0;
   398    398         }
................................................................................
   593    593     ** Allocation all the stack space we will ever need.
   594    594     */
   595    595     if( p->aStack==0 ){
   596    596       p->nVar = nVar;
   597    597       assert( nVar>=0 );
   598    598       n = isExplain ? 10 : p->nOp;
   599    599       p->aStack = sqliteMalloc(
   600         -    n*(sizeof(p->aStack[0]) + 2*sizeof(char*))     /* aStack and zArgv */
   601         -      + p->nVar*(sizeof(char*)+sizeof(int)+1)      /* azVar, anVar, abVar */
          600  +      n*(sizeof(p->aStack[0]) + 2*sizeof(char*))     /* aStack and zArgv */
          601  +        + p->nVar*(sizeof(char*)+sizeof(int)+1)    /* azVar, anVar, abVar */
   602    602       );
   603    603       p->zArgv = (char**)&p->aStack[n];
   604    604       p->azColName = (char**)&p->zArgv[n];
   605    605       p->azVar = (char**)&p->azColName[n];
   606    606       p->anVar = (int*)&p->azVar[p->nVar];
   607    607       p->abVar = (u8*)&p->anVar[p->nVar];
   608    608     }
................................................................................
   610    610     sqliteHashInit(&p->agg.hash, SQLITE_HASH_BINARY, 0);
   611    611     p->agg.pSearch = 0;
   612    612   #ifdef MEMORY_DEBUG
   613    613     if( sqliteOsFileExists("vdbe_trace") ){
   614    614       p->trace = stdout;
   615    615     }
   616    616   #endif
   617         -  p->tos = -1;
          617  +  p->pTos = &p->aStack[-1];
   618    618     p->pc = 0;
   619    619     p->rc = SQLITE_OK;
   620    620     p->uniqueCnt = 0;
   621    621     p->returnDepth = 0;
   622    622     p->errorAction = OE_Abort;
   623    623     p->undoTransOnError = 0;
   624    624     p->xCallback = xCallback;
................................................................................
   647    647       p->pSort = pSorter->pNext;
   648    648       sqliteFree(pSorter->zKey);
   649    649       sqliteFree(pSorter->pData);
   650    650       sqliteFree(pSorter);
   651    651     }
   652    652   }
   653    653   
   654         -/*
   655         -** Pop the stack N times.  Free any memory associated with the
   656         -** popped stack elements.
   657         -*/
   658         -void sqliteVdbePopStack(Vdbe *p, int N){
   659         -  assert( N>=0 );
   660         -  if( p->aStack==0 ) return;
   661         -  while( N-- > 0 ){
   662         -    if( p->aStack[p->tos].flags & MEM_Dyn ){
   663         -      sqliteFree(p->aStack[p->tos].z);
   664         -    }
   665         -    p->aStack[p->tos].flags = 0;
   666         -    p->tos--;
   667         -  }
   668         -}
   669         -
   670    654   /*
   671    655   ** Reset an Agg structure.  Delete all its contents. 
   672    656   **
   673    657   ** For installable aggregate functions, if the step function has been
   674    658   ** called, make sure the finalizer function has also been called.  The
   675    659   ** finalizer might need to free memory that was allocated as part of its
   676    660   ** private context.  If the finalizer has not been called yet, call it
................................................................................
   754    738   **
   755    739   ** This routine will automatically close any cursors, lists, and/or
   756    740   ** sorters that were left open.  It also deletes the values of
   757    741   ** variables in the azVariable[] array.
   758    742   */
   759    743   static void Cleanup(Vdbe *p){
   760    744     int i;
   761         -  sqliteVdbePopStack(p, p->tos+1);
          745  +  if( p->aStack ){
          746  +    Mem *pTos = p->pTos;
          747  +    while( pTos>=p->aStack ){
          748  +      if( pTos->flags & MEM_Dyn ){
          749  +        sqliteFree(pTos->z);
          750  +      }
          751  +      pTos--;
          752  +    }
          753  +    p->pTos = pTos;
          754  +  }
   762    755     closeAllCursors(p);
   763    756     if( p->aMem ){
   764    757       for(i=0; i<p->nMem; i++){
   765    758         if( p->aMem[i].flags & MEM_Dyn ){
   766    759           sqliteFree(p->aMem[i].z);
   767    760         }
   768    761       }
................................................................................
   867    860     }
   868    861     for(i=0; i<db->nDb; i++){
   869    862       if( db->aDb[i].pBt && db->aDb[i].inTrans==2 ){
   870    863         sqliteBtreeCommitCkpt(db->aDb[i].pBt);
   871    864         db->aDb[i].inTrans = 1;
   872    865       }
   873    866     }
   874         -  assert( p->tos<p->pc || sqlite_malloc_failed==1 );
          867  +  assert( p->pTos<&p->aStack[p->pc] || sqlite_malloc_failed==1 );
   875    868   #ifdef VDBE_PROFILE
   876    869     {
   877    870       FILE *out = fopen("vdbe_profile.out", "a");
   878    871       if( out ){
   879    872         int i;
   880    873         fprintf(out, "---- ");
   881    874         for(i=0; i<p->nOp; i++){

Changes to tool/memleak.awk.

     6      6     mem[$6] = $0
     7      7   }
     8      8   /[0-9]+ realloc / {
     9      9     mem[$8] = "";
    10     10     mem[$10] = $0
    11     11   }
    12     12   /[0-9]+ free / {
           13  +  if (mem[$6]=="") {
           14  +    print "*** free without a malloc at",$6
           15  +  }
    13     16     mem[$6] = "";
    14     17     str[$6] = ""
    15     18   }
    16     19   /^string at / {
    17     20     addr = $4
    18     21     sub("string at " addr " is ","")
    19     22     str[addr] = $0