/ Check-in [042dcb96]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Replace the NOPUSH_MASKs with a bit-vector mechanism that can contain several different properties about each opcode. (CVS 4677)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 042dcb9621934d0318a7c6e9cd08b20a569db367
User & Date: drh 2008-01-04 16:50:09
Context
2008-01-04
19:10
Some modifications to insert.c to work without using the stack. (CVS 4678) check-in: d9ac6bee user: danielk1977 tags: trunk
16:50
Replace the NOPUSH_MASKs with a bit-vector mechanism that can contain several different properties about each opcode. (CVS 4677) check-in: 042dcb96 user: drh tags: trunk
13:57
Modify FifoRead and FifoWrite to work exclusively with memory cells. (CVS 4676) check-in: 2c913908 user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to mkopcodeh.awk.

46
47
48
49
50
51
52







53
54
55
56
57
58
59
60

61
62














63
64
65
66
67
68
69
..
92
93
94
95
96
97
98
99
100
101

102
103
104
105
106
107
108
109

110
111
112
113
114


115
116
117



118
119
120
121
122
123












124
125


126

127

# Scan for "case OP_aaaa:" lines in the vdbe.c file
/^case OP_/ {
  name = $2
  sub(/:/,"",name)
  sub("\r","",name)
  op[name] = -1







  for(i=3; i<NF; i++){
    if($i=="same" && $(i+1)=="as"){
      sym = $(i+2)
      sub(/,/,"",sym)
      op[name] = tk[sym]
      used[op[name]] = 1
      sameas[op[name]] = sym
    }

    if($i=="no-push"){
      nopush[name] = 1














    }
  }
}

# Assign numbers to all opcodes and output the result.
END {
  cnt = 0
................................................................................
        printf "\n/* The following opcode values are never used */\n"
        seenUnused = 1
      }
      printf "#define %-25s %15d\n", sprintf( "OP_NotUsed_%-3d", i ), i
    }
  }

  # Generate the 10 16-bit bitmasks used by function opcodeUsesStack()
  # in vdbeaux.c. See comments in that function for details.
  # 

  nopush[0] = 0              # 0..15
  nopush[1] = 0              # 16..31
  nopush[2] = 0              # 32..47
  nopush[3] = 0              # 48..63
  nopush[4] = 0              # 64..79
  nopush[5] = 0              # 80..95
  nopush[6] = 0              # 96..111
  nopush[7] = 0              # 112..127

  nopush[8] = 0              # 128..143
  nopush[9] = 0              # 144..159
  for(name in op){
    if( nopush[name] ){
      n = op[name]


      j = n%16
      i = ((n - j)/16)
      nopush[i] = nopush[i] + (2^j)



    }
  }
  printf "\n"
  print "/* Opcodes that are guaranteed to never push a value onto the stack"
  print "** contain a 1 their corresponding position of the following mask"
  print "** set.  See the opcodeNoPush() function in vdbeaux.c  */"












  for(i=0; i<10; i++){
    printf "#define NOPUSH_MASK_%d 0x%04x\n", i, nopush[i]


  }

}







>
>
>
>
>
>
>








>


>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
<
|
>
|
|
|
|
|
|
|
<
>
|
<

<
|
>
>
|
|
|
>
>
>
|
<
|
<
<
|
>
>
>
>
>
>
>
>
>
>
>
>
|
<
>
>

>

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
...
114
115
116
117
118
119
120
121

122
123
124
125
126
127
128
129
130

131
132

133

134
135
136
137
138
139
140
141
142
143

144


145
146
147
148
149
150
151
152
153
154
155
156
157
158

159
160
161
162
163

# Scan for "case OP_aaaa:" lines in the vdbe.c file
/^case OP_/ {
  name = $2
  sub(/:/,"",name)
  sub("\r","",name)
  op[name] = -1
  out1[name] = 0
  out2[name] = 0
  out3[name] = 0
  jump[name] = 0
  in1[name] = 0
  in2[name] = 0
  in3[name] = 0
  for(i=3; i<NF; i++){
    if($i=="same" && $(i+1)=="as"){
      sym = $(i+2)
      sub(/,/,"",sym)
      op[name] = tk[sym]
      used[op[name]] = 1
      sameas[op[name]] = sym
    }
    sub(",","",$i)
    if($i=="no-push"){
      nopush[name] = 1
    }else if($i=="out1"){
      out1[name] = 1
    }else if($i=="out2"){
      out2[name] = 2
    }else if($i=="out3"){
      out3[name] = 3
    }else if($i=="in1"){
      in1[name] = 1
    }else if($i=="in2"){
      in2[name] = 1
    }else if($i=="in3"){
      in3[name] = 1
    }else if($i=="jump"){
      jump[name] = 1
    }
  }
}

# Assign numbers to all opcodes and output the result.
END {
  cnt = 0
................................................................................
        printf "\n/* The following opcode values are never used */\n"
        seenUnused = 1
      }
      printf "#define %-25s %15d\n", sprintf( "OP_NotUsed_%-3d", i ), i
    }
  }

  # Generate the bitvectors:

  #
  #  bit 0:     jump
  #  bit 1:     output on P1
  #  bit 2:     output on P2
  #  bit 3:     output on P3
  #  bit 4:     input on P1
  #  bit 5:     input on P2
  #  bit 6:     input on P3
  #  bit 7:     pushes a result onto stack

  #
  for(i=0; i<=max; i++) bv[i] = 0;

  for(name in op){

    x = op[name]
    if( jump[name] ) bv[x] += 0x01;
    if( out1[name] ) bv[x] += 0x02;
    if( out2[name] ) bv[x] += 0x04;
    if( out3[name] ) bv[x] += 0x08;
    if( in1[name] ) bv[x] += 0x10;
    if( in2[name] ) bv[x] += 0x20;
    if( in3[name] ) bv[x] += 0x40;
    if( !nopush[name] ) bv[x] += 0x80;
  }

  print "\n"


  print "/* Properties such as \"out2\" or \"jump\" that are specified in"
  print "** comments following the "case" for each opcode in the vdbe.c"
  print "** are encoded into bitvectors as follows:"
  print "*/"
  print "#define OPFLG_JUMP     0x01    /* jump:  P2 holds a jump target */"
  print "#define OPFLG_OUT1     0x02    /* out1:  P1 specifies output reg */"
  print "#define OPFLG_OUT2     0x04    /* out2:  P2 specifies output reg */"
  print "#define OPFLG_OUT3     0x08    /* out3:  P3 specifies output reg */"
  print "#define OPFLG_IN1      0x10    /* in1:   P1 is an input reg */"
  print "#define OPFLG_IN2      0x20    /* in2:   P2 is an input reg */"
  print "#define OPFLG_IN3      0x40    /* in3:   P3 is an input reg */"
  print "#define OPFLG_PUSH     0x80    /* omits no-push:  Does not push */"
  print "#define OPFLG_INITIALIZER {\\"
  for(i=0; i<=max; i++){

    printf " 0x%02x,", bv[i]
    if( i%10==9 ) printf("\\\n");
  }
  print "}"
}

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
167
168
169
170
171
172
173

























174
175
176
177
178
179
180
...
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573

574
575
576
577
578
579
580
...
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
...
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
....
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
....
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
....
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
....
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
....
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
....
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
....
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
....
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
....
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
....
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
....
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
....
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
....
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
....
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
....
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
....
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
....
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
....
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
....
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
....
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
....
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
....
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
....
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
....
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.676 2008/01/04 13:57:26 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
................................................................................
  }
  else if( flags & MEM_Str ){
    pMem->type = SQLITE_TEXT;
  }else{
    pMem->type = SQLITE_BLOB;
  }
}


























/*
** Pop the stack N times.
*/
static void popStack(Mem **ppTos, int N){
  Mem *pTos = *ppTos;
  while( N>0 ){
................................................................................
        nProgressOps = 0;
      }
      nProgressOps++;
    }
#endif

#ifndef NDEBUG
    /* This is to check that the return value of static function
    ** opcodeNoPush() (see vdbeaux.c) returns values that match the
    ** implementation of the virtual machine in this file. If
    ** opcodeNoPush() returns non-zero, then the stack is guarenteed
    ** not to grow when the opcode is executed. If it returns zero, then
    ** the stack may grow by at most 1.
    **
    ** The global wrapper function sqlite3VdbeOpcodeUsesStack() is not 
    ** available if NDEBUG is defined at build time.
    */ 
    pStackLimit = pTos;
    if( !sqlite3VdbeOpcodeNoPush(pOp->opcode) ){

      pStackLimit++;
    }
#endif

    switch( pOp->opcode ){

/*****************************************************************************
................................................................................
/* Opcode:  Goto * P2 *
**
** An unconditional jump to address P2.
** The next instruction executed will be 
** the one at index P2 from the beginning of
** the program.
*/
case OP_Goto: {             /* no-push */
  CHECK_FOR_INTERRUPT;
  pc = pOp->p2 - 1;
  break;
}

/* Opcode:  Gosub * P2 *
**
................................................................................
** and then jump to address P2.
**
** The return address stack is of limited depth.  If too many
** OP_Gosub operations occur without intervening OP_Returns, then
** the return address stack will fill up and processing will abort
** with a fatal error.
*/
case OP_Gosub: {            /* no-push */
  assert( p->returnDepth<sizeof(p->returnStack)/sizeof(p->returnStack[0]) );
  p->returnStack[p->returnDepth++] = pc+1;
  pc = pOp->p2 - 1;
  break;
}

/* Opcode:  Return * * *
................................................................................
** the stack is not numeric (meaning that is is a NULL or a string that
** does not look like an integer or floating point number) then pop the
** stack and jump to P2.  If the top of the stack is numeric then
** convert it into the least integer that is greater than or equal to its
** current value if P1==0, or to the least integer that is strictly
** greater than its current value if P1==1.
*/
case OP_ForceInt: {            /* no-push */
  i64 v;
  assert( pTos>=p->aStack );
  applyAffinity(pTos, SQLITE_AFF_NUMERIC, encoding);
  if( (pTos->flags & (MEM_Int|MEM_Real))==0 ){
    Release(pTos);
    pTos--;
    pc = pOp->p2 - 1;
................................................................................
** without data loss, then jump immediately to P2, or if P2==0
** raise an SQLITE_MISMATCH exception.
**
** If the top of the stack is not an integer and P2 is not zero and
** P1 is 1, then the stack is popped.  In all other cases, the depth
** of the stack is unchanged.
*/
case OP_MustBeInt: {            /* no-push */
  assert( pTos>=p->aStack );
  applyAffinity(pTos, SQLITE_AFF_NUMERIC, encoding);
  if( (pTos->flags & MEM_Int)==0 ){
    if( pOp->p2==0 ){
      rc = SQLITE_MISMATCH;
      goto abort_due_to_error;
    }else{
................................................................................
*/
/* Opcode: Ge P1 P2 P4
**
** This works just like the Eq opcode except that the jump is taken if
** the 2nd element down on the stack is greater than or equal to the
** top of the stack.  See the Eq opcode for additional information.
*/
case OP_Eq:               /* same as TK_EQ, no-push */
case OP_Ne:               /* same as TK_NE, no-push */
case OP_Lt:               /* same as TK_LT, no-push */
case OP_Le:               /* same as TK_LE, no-push */
case OP_Gt:               /* same as TK_GT, no-push */
case OP_Ge: {             /* same as TK_GE, no-push */
  Mem *pNos;
  int flags;
  int res;
  char affinity;

  pNos = &pTos[-1];
  flags = pTos->flags|pNos->flags;
................................................................................
** false, then jump to p2.  Otherwise continue to the next instruction.
** An integer is false if zero and true otherwise.  A string is
** false if it has zero length and true otherwise.
**
** If the value popped of the stack is NULL, then take the jump if P1
** is true and fall through if P1 is false.
*/
case OP_If:                 /* no-push */
case OP_IfNot: {            /* no-push */
  int c;
  assert( pTos>=p->aStack );
  if( pTos->flags & MEM_Null ){
    c = pOp->p1;
  }else{
#ifdef SQLITE_OMIT_FLOATING_POINT
    c = sqlite3VdbeIntValue(pTos);
................................................................................
**
** Check the top of the stack and jump to P2 if the top of the stack
** is NULL.  If P1 is positive, then pop P1 elements from the stack
** regardless of whether or not the jump is taken.  If P1 is negative,
** pop -P1 elements from the stack only if the jump is taken and leave
** the stack unchanged if the jump is not taken.
*/
case OP_IsNull: {            /* same as TK_ISNULL, no-push */
  if( pTos->flags & MEM_Null ){
    pc = pOp->p2-1;
    if( pOp->p1<0 ){
      popStack(&pTos, -pOp->p1);
    }
  }
  if( pOp->p1>0 ){
................................................................................
/* Opcode: NotNull P1 P2 *
**
** Jump to P2 if the top abs(P1) values on the stack are all not NULL.  
** Regardless of whether or not the jump is taken, pop the stack
** P1 times if P1 is greater than zero.  But if P1 is negative,
** leave the stack unchanged.
*/
case OP_NotNull: {            /* same as TK_NOTNULL, no-push */
  int i, cnt;
  cnt = pOp->p1;
  if( cnt<0 ) cnt = -cnt;
  assert( &pTos[1-cnt] >= p->aStack );
  for(i=0; i<cnt && (pTos[1+i-cnt].flags & MEM_Null)==0; i++){}
  if( i>=cnt ) pc = pOp->p2-1;
  if( pOp->p1>0 ) popStack(&pTos, cnt);
................................................................................
** Works like OP_MakeIdxRec except data is taken from registers
** rather than from the stack.  The P1 register is an integer which
** is the number of register to use in building the new record.
** Data is taken from P1+1, P1+2, ..., P1+mem[P1].
*/
case OP_RegMakeRec:
case OP_RegMakeIRec:
case OP_MakeIdxRec:
case OP_MakeRecord: {
  /* Assuming the record contains N fields, the record format looks
  ** like this:
  **
  ** ------------------------------------------------------------------------
  ** | hdr-size | type 0 | type 1 | ... | type N-1 | data0 | ... | data N-1 | 
  ** ------------------------------------------------------------------------
  **
................................................................................
** cursor P1 so that it points to the largest entry that is less than
** or equal to the key that was popped from the stack.
** If there are no records less than or eqal to the key and P2 is not zero,
** then jump to P2.
**
** See also: Found, NotFound, Distinct, MoveGt, MoveGe, MoveLt
*/
case OP_MoveLt:         /* no-push */
case OP_MoveLe:         /* no-push */
case OP_MoveGe:         /* no-push */
case OP_MoveGt: {       /* no-push */
  int i = pOp->p1;
  Cursor *pC;

  assert( pTos>=p->aStack );
  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC!=0 );
................................................................................
** pointing to the entry that matches.  The blob is popped from the stack.
**
** The difference between this operation and Distinct is that
** Distinct does not pop the key from the stack.
**
** See also: Distinct, Found, MoveTo, NotExists, IsUnique
*/
case OP_Distinct:       /* no-push */
case OP_NotFound:       /* no-push */
case OP_Found: {        /* no-push */
  int i = pOp->p1;
  int alreadyExists = 0;
  Cursor *pC;
  assert( pTos>=p->aStack );
  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  if( (pC = p->apCsr[i])->pCursor!=0 ){
................................................................................
** jump to P2.  If any entry does exist where the index string
** matches K but the record number is not R, then the record
** number for that entry is pushed onto the stack and control
** falls through to the next instruction.
**
** See also: Distinct, NotFound, NotExists, Found
*/
case OP_IsUnique: {        /* no-push */
  int i = pOp->p1;
  Mem *pNos = &pTos[-1];
  Cursor *pCx;
  BtCursor *pCrsr;
  i64 R;

  /* Pop the value R off the top of the stack
................................................................................
** The difference between this operation and NotFound is that this
** operation assumes the key is an integer and that P1 is a table whereas
** NotFound assumes key is a blob constructed from MakeRecord and
** P1 is an index.
**
** See also: Distinct, Found, MoveTo, NotFound, IsUnique
*/
case OP_NotExists: {        /* no-push */
  int i = pOp->p1;
  Cursor *pC;
  BtCursor *pCrsr;
  Mem *pKey;
  if( pOp->p3 ){
    assert( pOp->p3<=p->nMem );
    pKey = &p->aMem[pOp->p3];
................................................................................
**
** The next use of the Rowid or Column or Next instruction for P1 
** will refer to the last entry in the database table or index.
** If the table or index is empty and P2>0, then jump immediately to P2.
** If P2 is 0 or if the table or index is not empty, fall through
** to the following instruction.
*/
case OP_Last: {        /* no-push */
  int i = pOp->p1;
  Cursor *pC;
  BtCursor *pCrsr;

  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC!=0 );
................................................................................
** Sorting is accomplished by writing records into a sorting index,
** then rewinding that index and playing it back from beginning to
** end.  We use the OP_Sort opcode instead of OP_Rewind to do the
** rewinding so that the global variable will be incremented and
** regression tests can determine whether or not the optimizer is
** correctly optimizing out sorts.
*/
case OP_Sort: {        /* no-push */
#ifdef SQLITE_TEST
  sqlite3_sort_count++;
  sqlite3_search_count--;
#endif
  /* Fall through into OP_Rewind */
}
/* Opcode: Rewind P1 P2 *
................................................................................
**
** The next use of the Rowid or Column or Next instruction for P1 
** will refer to the first entry in the database table or index.
** If the table or index is empty and P2>0, then jump immediately to P2.
** If P2 is 0 or if the table or index is not empty, fall through
** to the following instruction.
*/
case OP_Rewind: {        /* no-push */
  int i = pOp->p1;
  Cursor *pC;
  BtCursor *pCrsr;
  int res;

  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
................................................................................
/* Opcode: Prev P1 P2 *
**
** Back up cursor P1 so that it points to the previous key/data pair in its
** table or index.  If there is no previous key/value pairs then fall through
** to the following instruction.  But if the cursor backup was successful,
** jump immediately to P2.
*/
case OP_Prev:          /* no-push */
case OP_Next: {        /* no-push */
  Cursor *pC;
  BtCursor *pCrsr;

  CHECK_FOR_INTERRUPT;
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  if( pC==0 ){
................................................................................
** In either case, the stack is popped once.
**
** If P4 is the "+" string (or any other non-NULL string) then the
** index taken from the top of the stack is temporarily increased by
** an epsilon prior to the comparison.  This makes the opcode work
** like IdxLE.
*/
case OP_IdxLT:          /* no-push */
case OP_IdxGT:          /* no-push */
case OP_IdxGE: {        /* no-push */
  int i= pOp->p1;
  Cursor *pC;

  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  assert( pTos>=p->aStack );
  if( (pC = p->apCsr[i])->pCursor!=0 ){
................................................................................
** Attempt to read a single integer from the Fifo. If P1 is zero,
** push the result onto the stack. Otherwise, store the read integer 
** in register P1.
** 
** If the Fifo is empty do not push an entry onto the stack or set
** a memory register but instead jump to P2.
*/
case OP_FifoRead: {
  i64 v;
  CHECK_FOR_INTERRUPT;
  if( sqlite3VdbeFifoPop(&p->sFifo, &v)==SQLITE_DONE ){
    pc = pOp->p2 - 1;
  }else{
    Mem *pOut = &p->aMem[pOp->p1];
    assert( pOp->p1>0 && pOp->p1<=p->nMem );
................................................................................
/* Opcode: IfMemPos P1 P2 *
**
** If the value of memory cell P1 is 1 or greater, jump to P2.
**
** It is illegal to use this instruction on a memory cell that does
** not contain an integer.  An assertion fault will result if you try.
*/
case OP_IfMemPos: {        /* no-push */
  int i = pOp->p1;
  Mem *pMem;
  assert( i>0 && i<=p->nMem );
  pMem = &p->aMem[i];
  assert( pMem->flags==MEM_Int );
  if( pMem->u.i>0 ){
     pc = pOp->p2 - 1;
................................................................................
/* Opcode: IfMemNeg P1 P2 *
**
** If the value of memory cell P1 is less than zero, jump to P2. 
**
** It is illegal to use this instruction on a memory cell that does
** not contain an integer.  An assertion fault will result if you try.
*/
case OP_IfMemNeg: {        /* no-push */
  int i = pOp->p1;
  Mem *pMem;
  assert( i>0 && i<=p->nMem );
  pMem = &p->aMem[i];
  assert( pMem->flags==MEM_Int );
  if( pMem->u.i<0 ){
     pc = pOp->p2 - 1;
................................................................................
/* Opcode: IfMemZero P1 P2 *
**
** If the value of memory cell P1 is exactly 0, jump to P2. 
**
** It is illegal to use this instruction on a memory cell that does
** not contain an integer.  An assertion fault will result if you try.
*/
case OP_IfMemZero: {        /* no-push */
  int i = pOp->p1;
  Mem *pMem;
  assert( i>0 && i<=p->nMem );
  pMem = &p->aMem[i];
  assert( pMem->flags==MEM_Int );
  if( pMem->u.i==0 ){
     pc = pOp->p2 - 1;
................................................................................
  break;
}

/* Opcode: IfMemNull P1 P2 *
**
** If the value of memory cell P1 is NULL, jump to P2. 
*/
case OP_IfMemNull: {        /* no-push */
  int i = pOp->p1;
  assert( i>0 && i<=p->nMem );
  if( p->aMem[i].flags & MEM_Null ){
     pc = pOp->p2 - 1;
  }
  break;
}
................................................................................
#if !defined(SQLITE_OMIT_AUTOVACUUM)
/* Opcode: IncrVacuum P1 P2 *
**
** Perform a single step of the incremental vacuum procedure on
** the P1 database. If the vacuum has finished, jump to instruction
** P2. Otherwise, fall through to the next instruction.
*/
case OP_IncrVacuum: {        /* no-push */
  Btree *pBt;

  assert( pOp->p1>=0 && pOp->p1<db->nDb );
  assert( (p->btreeMask & (1<<pOp->p1))!=0 );
  pBt = db->aDb[pOp->p1].pBt;
  rc = sqlite3BtreeIncrVacuum(pBt);
  if( rc==SQLITE_DONE ){
................................................................................
** P3. Register P3+1 stores the argc parameter to be passed to the
** xFilter method. Registers P3+2..P3+1+argc are the argc additional
** parametersneath additional parameters which are passed to
** xFilter as argv. Register P3+2 becomes argv[0] when passed to xFilter.
**
** A jump is made to P2 if the result set after filtering would be empty.
*/
case OP_VFilter: {   /* no-push */
  int nArg;
  int iQuery;
  const sqlite3_module *pModule;
  Mem *pQuery = &p->aMem[pOp->p3];
  Mem *pArgc = &pQuery[1];

  Cursor *pCur = p->apCsr[pOp->p1];
................................................................................
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VNext P1 P2 *
**
** Advance virtual table P1 to the next row in its result set and
** jump to instruction P2.  Or, if the virtual table has reached
** the end of its result set, then fall through to the next instruction.
*/
case OP_VNext: {   /* no-push */
  const sqlite3_module *pModule;
  int res = 0;

  Cursor *pCur = p->apCsr[pOp->p1];
  assert( pCur->pVtabCursor );
  pModule = pCur->pVtabCursor->pVtab->pModule;
  if( pModule->xNext==0 ){







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
|
<
<
<
<
<
<
<


<
>







 







|







 







|







 







|







 







|







 







|
|
|
|
|
|







 







|
|







 







|







 







|







 







|
|







 







|
|
|
|







 







|
|
|







 







|







 







|







 







|







 







|







 







|







 







|
|







 







|
|
|







 







|







 







|







 







|







 







|







 







|







 







|







 







|







 







|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
...
580
581
582
583
584
585
586
587
588







589
590

591
592
593
594
595
596
597
598
...
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
...
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
....
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
....
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
....
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
....
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
....
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
....
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
....
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
....
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
....
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
....
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
....
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
....
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
....
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
....
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
....
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
....
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
....
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
....
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
....
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
....
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
....
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
....
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
....
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
....
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.677 2008/01/04 16:50:09 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
................................................................................
  }
  else if( flags & MEM_Str ){
    pMem->type = SQLITE_TEXT;
  }else{
    pMem->type = SQLITE_BLOB;
  }
}

/*
** Properties of opcodes.  The OPFLG_INITIALIZER macro is
** created by mkopcodeh.awk during compilation.  Data is obtained
** from the comments following the "case OP_xxxx:" statements in
** this file.  
**
**      jump:      OPFLG_JUMP
**      out1:      OPFLG_OUT1
**      out2:      OPFLG_OUT2
**      out3:      OPFLG_OUT3
**      in1:       OPFLG_IN1
**      in2:       OPFLG_IN2
**      in3:       OPFLG_IN3
*/
static unsigned char opcodeProperty[] = OPFLG_INITIALIZER;

/*
** Return true if an opcode has any of the OPFLG_xxx properties
** specified by mask.
*/
int sqlite3VdbeOpcodeHasProperty(int opcode, int mask){
  assert( opcode>0 && opcode<sizeof(opcodeProperty) );
  return (opcodeProperty[opcode]&mask)!=0;
}

/*
** Pop the stack N times.
*/
static void popStack(Mem **ppTos, int N){
  Mem *pTos = *ppTos;
  while( N>0 ){
................................................................................
        nProgressOps = 0;
      }
      nProgressOps++;
    }
#endif

#ifndef NDEBUG
    /* This is to check to make sure that the OPFLG_PUSH property
    ** is set correctly on all opcodes.







    */ 
    pStackLimit = pTos;

    if( sqlite3VdbeOpcodeHasProperty(pOp->opcode, OPFLG_PUSH) ){
      pStackLimit++;
    }
#endif

    switch( pOp->opcode ){

/*****************************************************************************
................................................................................
/* Opcode:  Goto * P2 *
**
** An unconditional jump to address P2.
** The next instruction executed will be 
** the one at index P2 from the beginning of
** the program.
*/
case OP_Goto: {             /* no-push, jump */
  CHECK_FOR_INTERRUPT;
  pc = pOp->p2 - 1;
  break;
}

/* Opcode:  Gosub * P2 *
**
................................................................................
** and then jump to address P2.
**
** The return address stack is of limited depth.  If too many
** OP_Gosub operations occur without intervening OP_Returns, then
** the return address stack will fill up and processing will abort
** with a fatal error.
*/
case OP_Gosub: {            /* no-push, jump */
  assert( p->returnDepth<sizeof(p->returnStack)/sizeof(p->returnStack[0]) );
  p->returnStack[p->returnDepth++] = pc+1;
  pc = pOp->p2 - 1;
  break;
}

/* Opcode:  Return * * *
................................................................................
** the stack is not numeric (meaning that is is a NULL or a string that
** does not look like an integer or floating point number) then pop the
** stack and jump to P2.  If the top of the stack is numeric then
** convert it into the least integer that is greater than or equal to its
** current value if P1==0, or to the least integer that is strictly
** greater than its current value if P1==1.
*/
case OP_ForceInt: {            /* no-push, jump */
  i64 v;
  assert( pTos>=p->aStack );
  applyAffinity(pTos, SQLITE_AFF_NUMERIC, encoding);
  if( (pTos->flags & (MEM_Int|MEM_Real))==0 ){
    Release(pTos);
    pTos--;
    pc = pOp->p2 - 1;
................................................................................
** without data loss, then jump immediately to P2, or if P2==0
** raise an SQLITE_MISMATCH exception.
**
** If the top of the stack is not an integer and P2 is not zero and
** P1 is 1, then the stack is popped.  In all other cases, the depth
** of the stack is unchanged.
*/
case OP_MustBeInt: {            /* no-push, jump */
  assert( pTos>=p->aStack );
  applyAffinity(pTos, SQLITE_AFF_NUMERIC, encoding);
  if( (pTos->flags & MEM_Int)==0 ){
    if( pOp->p2==0 ){
      rc = SQLITE_MISMATCH;
      goto abort_due_to_error;
    }else{
................................................................................
*/
/* Opcode: Ge P1 P2 P4
**
** This works just like the Eq opcode except that the jump is taken if
** the 2nd element down on the stack is greater than or equal to the
** top of the stack.  See the Eq opcode for additional information.
*/
case OP_Eq:               /* same as TK_EQ, no-push, jump */
case OP_Ne:               /* same as TK_NE, no-push, jump */
case OP_Lt:               /* same as TK_LT, no-push, jump */
case OP_Le:               /* same as TK_LE, no-push, jump */
case OP_Gt:               /* same as TK_GT, no-push, jump */
case OP_Ge: {             /* same as TK_GE, no-push, jump */
  Mem *pNos;
  int flags;
  int res;
  char affinity;

  pNos = &pTos[-1];
  flags = pTos->flags|pNos->flags;
................................................................................
** false, then jump to p2.  Otherwise continue to the next instruction.
** An integer is false if zero and true otherwise.  A string is
** false if it has zero length and true otherwise.
**
** If the value popped of the stack is NULL, then take the jump if P1
** is true and fall through if P1 is false.
*/
case OP_If:                 /* no-push, jump */
case OP_IfNot: {            /* no-push, jump */
  int c;
  assert( pTos>=p->aStack );
  if( pTos->flags & MEM_Null ){
    c = pOp->p1;
  }else{
#ifdef SQLITE_OMIT_FLOATING_POINT
    c = sqlite3VdbeIntValue(pTos);
................................................................................
**
** Check the top of the stack and jump to P2 if the top of the stack
** is NULL.  If P1 is positive, then pop P1 elements from the stack
** regardless of whether or not the jump is taken.  If P1 is negative,
** pop -P1 elements from the stack only if the jump is taken and leave
** the stack unchanged if the jump is not taken.
*/
case OP_IsNull: {            /* same as TK_ISNULL, no-push, jump */
  if( pTos->flags & MEM_Null ){
    pc = pOp->p2-1;
    if( pOp->p1<0 ){
      popStack(&pTos, -pOp->p1);
    }
  }
  if( pOp->p1>0 ){
................................................................................
/* Opcode: NotNull P1 P2 *
**
** Jump to P2 if the top abs(P1) values on the stack are all not NULL.  
** Regardless of whether or not the jump is taken, pop the stack
** P1 times if P1 is greater than zero.  But if P1 is negative,
** leave the stack unchanged.
*/
case OP_NotNull: {            /* same as TK_NOTNULL, no-push, jump */
  int i, cnt;
  cnt = pOp->p1;
  if( cnt<0 ) cnt = -cnt;
  assert( &pTos[1-cnt] >= p->aStack );
  for(i=0; i<cnt && (pTos[1+i-cnt].flags & MEM_Null)==0; i++){}
  if( i>=cnt ) pc = pOp->p2-1;
  if( pOp->p1>0 ) popStack(&pTos, cnt);
................................................................................
** Works like OP_MakeIdxRec except data is taken from registers
** rather than from the stack.  The P1 register is an integer which
** is the number of register to use in building the new record.
** Data is taken from P1+1, P1+2, ..., P1+mem[P1].
*/
case OP_RegMakeRec:
case OP_RegMakeIRec:
case OP_MakeIdxRec:          /* jump */
case OP_MakeRecord: {        /* jump */
  /* Assuming the record contains N fields, the record format looks
  ** like this:
  **
  ** ------------------------------------------------------------------------
  ** | hdr-size | type 0 | type 1 | ... | type N-1 | data0 | ... | data N-1 | 
  ** ------------------------------------------------------------------------
  **
................................................................................
** cursor P1 so that it points to the largest entry that is less than
** or equal to the key that was popped from the stack.
** If there are no records less than or eqal to the key and P2 is not zero,
** then jump to P2.
**
** See also: Found, NotFound, Distinct, MoveGt, MoveGe, MoveLt
*/
case OP_MoveLt:         /* no-push, jump */
case OP_MoveLe:         /* no-push, jump */
case OP_MoveGe:         /* no-push, jump */
case OP_MoveGt: {       /* no-push, jump */
  int i = pOp->p1;
  Cursor *pC;

  assert( pTos>=p->aStack );
  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC!=0 );
................................................................................
** pointing to the entry that matches.  The blob is popped from the stack.
**
** The difference between this operation and Distinct is that
** Distinct does not pop the key from the stack.
**
** See also: Distinct, Found, MoveTo, NotExists, IsUnique
*/
case OP_Distinct:       /* no-push, jump */
case OP_NotFound:       /* no-push, jump */
case OP_Found: {        /* no-push, jump */
  int i = pOp->p1;
  int alreadyExists = 0;
  Cursor *pC;
  assert( pTos>=p->aStack );
  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  if( (pC = p->apCsr[i])->pCursor!=0 ){
................................................................................
** jump to P2.  If any entry does exist where the index string
** matches K but the record number is not R, then the record
** number for that entry is pushed onto the stack and control
** falls through to the next instruction.
**
** See also: Distinct, NotFound, NotExists, Found
*/
case OP_IsUnique: {        /* no-push, jump */
  int i = pOp->p1;
  Mem *pNos = &pTos[-1];
  Cursor *pCx;
  BtCursor *pCrsr;
  i64 R;

  /* Pop the value R off the top of the stack
................................................................................
** The difference between this operation and NotFound is that this
** operation assumes the key is an integer and that P1 is a table whereas
** NotFound assumes key is a blob constructed from MakeRecord and
** P1 is an index.
**
** See also: Distinct, Found, MoveTo, NotFound, IsUnique
*/
case OP_NotExists: {        /* no-push, jump */
  int i = pOp->p1;
  Cursor *pC;
  BtCursor *pCrsr;
  Mem *pKey;
  if( pOp->p3 ){
    assert( pOp->p3<=p->nMem );
    pKey = &p->aMem[pOp->p3];
................................................................................
**
** The next use of the Rowid or Column or Next instruction for P1 
** will refer to the last entry in the database table or index.
** If the table or index is empty and P2>0, then jump immediately to P2.
** If P2 is 0 or if the table or index is not empty, fall through
** to the following instruction.
*/
case OP_Last: {        /* no-push, jump */
  int i = pOp->p1;
  Cursor *pC;
  BtCursor *pCrsr;

  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  assert( pC!=0 );
................................................................................
** Sorting is accomplished by writing records into a sorting index,
** then rewinding that index and playing it back from beginning to
** end.  We use the OP_Sort opcode instead of OP_Rewind to do the
** rewinding so that the global variable will be incremented and
** regression tests can determine whether or not the optimizer is
** correctly optimizing out sorts.
*/
case OP_Sort: {        /* no-push, jump */
#ifdef SQLITE_TEST
  sqlite3_sort_count++;
  sqlite3_search_count--;
#endif
  /* Fall through into OP_Rewind */
}
/* Opcode: Rewind P1 P2 *
................................................................................
**
** The next use of the Rowid or Column or Next instruction for P1 
** will refer to the first entry in the database table or index.
** If the table or index is empty and P2>0, then jump immediately to P2.
** If P2 is 0 or if the table or index is not empty, fall through
** to the following instruction.
*/
case OP_Rewind: {        /* no-push, jump */
  int i = pOp->p1;
  Cursor *pC;
  BtCursor *pCrsr;
  int res;

  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
................................................................................
/* Opcode: Prev P1 P2 *
**
** Back up cursor P1 so that it points to the previous key/data pair in its
** table or index.  If there is no previous key/value pairs then fall through
** to the following instruction.  But if the cursor backup was successful,
** jump immediately to P2.
*/
case OP_Prev:          /* no-push, jump */
case OP_Next: {        /* no-push, jump */
  Cursor *pC;
  BtCursor *pCrsr;

  CHECK_FOR_INTERRUPT;
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  if( pC==0 ){
................................................................................
** In either case, the stack is popped once.
**
** If P4 is the "+" string (or any other non-NULL string) then the
** index taken from the top of the stack is temporarily increased by
** an epsilon prior to the comparison.  This makes the opcode work
** like IdxLE.
*/
case OP_IdxLT:          /* no-push, jump */
case OP_IdxGT:          /* no-push, jump */
case OP_IdxGE: {        /* no-push, jump */
  int i= pOp->p1;
  Cursor *pC;

  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  assert( pTos>=p->aStack );
  if( (pC = p->apCsr[i])->pCursor!=0 ){
................................................................................
** Attempt to read a single integer from the Fifo. If P1 is zero,
** push the result onto the stack. Otherwise, store the read integer 
** in register P1.
** 
** If the Fifo is empty do not push an entry onto the stack or set
** a memory register but instead jump to P2.
*/
case OP_FifoRead: {         /* jump */
  i64 v;
  CHECK_FOR_INTERRUPT;
  if( sqlite3VdbeFifoPop(&p->sFifo, &v)==SQLITE_DONE ){
    pc = pOp->p2 - 1;
  }else{
    Mem *pOut = &p->aMem[pOp->p1];
    assert( pOp->p1>0 && pOp->p1<=p->nMem );
................................................................................
/* Opcode: IfMemPos P1 P2 *
**
** If the value of memory cell P1 is 1 or greater, jump to P2.
**
** It is illegal to use this instruction on a memory cell that does
** not contain an integer.  An assertion fault will result if you try.
*/
case OP_IfMemPos: {        /* no-push, jump */
  int i = pOp->p1;
  Mem *pMem;
  assert( i>0 && i<=p->nMem );
  pMem = &p->aMem[i];
  assert( pMem->flags==MEM_Int );
  if( pMem->u.i>0 ){
     pc = pOp->p2 - 1;
................................................................................
/* Opcode: IfMemNeg P1 P2 *
**
** If the value of memory cell P1 is less than zero, jump to P2. 
**
** It is illegal to use this instruction on a memory cell that does
** not contain an integer.  An assertion fault will result if you try.
*/
case OP_IfMemNeg: {        /* no-push, jump */
  int i = pOp->p1;
  Mem *pMem;
  assert( i>0 && i<=p->nMem );
  pMem = &p->aMem[i];
  assert( pMem->flags==MEM_Int );
  if( pMem->u.i<0 ){
     pc = pOp->p2 - 1;
................................................................................
/* Opcode: IfMemZero P1 P2 *
**
** If the value of memory cell P1 is exactly 0, jump to P2. 
**
** It is illegal to use this instruction on a memory cell that does
** not contain an integer.  An assertion fault will result if you try.
*/
case OP_IfMemZero: {        /* no-push, jump */
  int i = pOp->p1;
  Mem *pMem;
  assert( i>0 && i<=p->nMem );
  pMem = &p->aMem[i];
  assert( pMem->flags==MEM_Int );
  if( pMem->u.i==0 ){
     pc = pOp->p2 - 1;
................................................................................
  break;
}

/* Opcode: IfMemNull P1 P2 *
**
** If the value of memory cell P1 is NULL, jump to P2. 
*/
case OP_IfMemNull: {        /* no-push, jump */
  int i = pOp->p1;
  assert( i>0 && i<=p->nMem );
  if( p->aMem[i].flags & MEM_Null ){
     pc = pOp->p2 - 1;
  }
  break;
}
................................................................................
#if !defined(SQLITE_OMIT_AUTOVACUUM)
/* Opcode: IncrVacuum P1 P2 *
**
** Perform a single step of the incremental vacuum procedure on
** the P1 database. If the vacuum has finished, jump to instruction
** P2. Otherwise, fall through to the next instruction.
*/
case OP_IncrVacuum: {        /* no-push, jump */
  Btree *pBt;

  assert( pOp->p1>=0 && pOp->p1<db->nDb );
  assert( (p->btreeMask & (1<<pOp->p1))!=0 );
  pBt = db->aDb[pOp->p1].pBt;
  rc = sqlite3BtreeIncrVacuum(pBt);
  if( rc==SQLITE_DONE ){
................................................................................
** P3. Register P3+1 stores the argc parameter to be passed to the
** xFilter method. Registers P3+2..P3+1+argc are the argc additional
** parametersneath additional parameters which are passed to
** xFilter as argv. Register P3+2 becomes argv[0] when passed to xFilter.
**
** A jump is made to P2 if the result set after filtering would be empty.
*/
case OP_VFilter: {   /* no-push, jump */
  int nArg;
  int iQuery;
  const sqlite3_module *pModule;
  Mem *pQuery = &p->aMem[pOp->p3];
  Mem *pArgc = &pQuery[1];

  Cursor *pCur = p->apCsr[pOp->p1];
................................................................................
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VNext P1 P2 *
**
** Advance virtual table P1 to the next row in its result set and
** jump to instruction P2.  Or, if the virtual table has reached
** the end of its result set, then fall through to the next instruction.
*/
case OP_VNext: {   /* no-push, jump */
  const sqlite3_module *pModule;
  int res = 0;

  Cursor *pCur = p->apCsr[pOp->p1];
  assert( pCur->pVtabCursor );
  pModule = pCur->pVtabCursor->pVtab->pModule;
  if( pModule->xNext==0 ){

Changes to src/vdbeInt.h.

396
397
398
399
400
401
402

403
404
405
406
407
408
409
410
411
412
413
void sqlite3VdbeIntegerAffinity(Mem*);
int sqlite3VdbeMemRealify(Mem*);
int sqlite3VdbeMemNumerify(Mem*);
int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*);
void sqlite3VdbeMemRelease(Mem *p);
int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
const char *sqlite3OpcodeName(int);


#ifndef NDEBUG
  void sqlite3VdbeMemSanity(Mem*);
  int sqlite3VdbeOpcodeNoPush(u8);
#endif
int sqlite3VdbeMemTranslate(Mem*, u8);
#ifdef SQLITE_DEBUG
  void sqlite3VdbePrintSql(Vdbe*);
  void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf);
#endif
int sqlite3VdbeMemHandleBom(Mem *pMem);







>



<







396
397
398
399
400
401
402
403
404
405
406

407
408
409
410
411
412
413
void sqlite3VdbeIntegerAffinity(Mem*);
int sqlite3VdbeMemRealify(Mem*);
int sqlite3VdbeMemNumerify(Mem*);
int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*);
void sqlite3VdbeMemRelease(Mem *p);
int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
const char *sqlite3OpcodeName(int);
int sqlite3VdbeOpcodeHasProperty(int, int);

#ifndef NDEBUG
  void sqlite3VdbeMemSanity(Mem*);

#endif
int sqlite3VdbeMemTranslate(Mem*, u8);
#ifdef SQLITE_DEBUG
  void sqlite3VdbePrintSql(Vdbe*);
  void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf);
#endif
int sqlite3VdbeMemHandleBom(Mem *pMem);

Changes to src/vdbeaux.c.

228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
...
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
  assert( p->magic==VDBE_MAGIC_INIT );
  assert( j>=0 && j<p->nLabel );
  if( p->aLabel ){
    p->aLabel[j] = p->nOp;
  }
}

/*
** Return non-zero if opcode 'op' is guarenteed not to push more values
** onto the VDBE stack than it pops off.
*/
static int opcodeNoPush(u8 op){
  /* The 10 NOPUSH_MASK_n constants are defined in the automatically
  ** generated header file opcodes.h. Each is a 16-bit bitmask, one
  ** bit corresponding to each opcode implemented by the virtual
  ** machine in vdbe.c. The bit is true if the word "no-push" appears
  ** in a comment on the same line as the "case OP_XXX:" in 
  ** sqlite3VdbeExec() in vdbe.c.
  **
  ** If the bit is true, then the corresponding opcode is guarenteed not
  ** to grow the stack when it is executed. Otherwise, it may grow the
  ** stack by at most one entry.
  **
  ** NOPUSH_MASK_0 corresponds to opcodes 0 to 15. NOPUSH_MASK_1 contains
  ** one bit for opcodes 16 to 31, and so on.
  **
  ** 16-bit bitmasks (rather than 32-bit) are specified in opcodes.h 
  ** because the file is generated by an awk program. Awk manipulates
  ** all numbers as floating-point and we don't want to risk a rounding
  ** error if someone builds with an awk that uses (for example) 32-bit 
  ** IEEE floats.
  */ 
  static const u32 masks[5] = {
    NOPUSH_MASK_0 + (((unsigned)NOPUSH_MASK_1)<<16),
    NOPUSH_MASK_2 + (((unsigned)NOPUSH_MASK_3)<<16),
    NOPUSH_MASK_4 + (((unsigned)NOPUSH_MASK_5)<<16),
    NOPUSH_MASK_6 + (((unsigned)NOPUSH_MASK_7)<<16),
    NOPUSH_MASK_8 + (((unsigned)NOPUSH_MASK_9)<<16)
  };
  assert( op<32*5 );
  return (masks[op>>5] & (1<<(op&0x1F)));
}

#ifndef NDEBUG
int sqlite3VdbeOpcodeNoPush(u8 op){
  return opcodeNoPush(op);
}
#endif

/*
** Loop through the program looking for P2 values that are negative.
** Each such value is a label.  Resolve the label by setting the P2
** value to its correct non-zero value.
**
** This routine is called once after all opcodes have been inserted.
**
................................................................................
      int n;
      assert( p->nOp - i >= 3 );
      assert( pOp[-1].opcode==OP_MemInt );
      n = pOp[-1].p1;
      if( n>nMaxArgs ) nMaxArgs = n;
#endif
    }
    if( opcodeNoPush(opcode) ){
      nMaxStack--;
    }

    if( pOp->p2>=0 ) continue;
    assert( -1-pOp->p2<p->nLabel );
    pOp->p2 = aLabel[-1-pOp->p2];
  }







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







|







228
229
230
231
232
233
234










































235
236
237
238
239
240
241
...
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
  assert( p->magic==VDBE_MAGIC_INIT );
  assert( j>=0 && j<p->nLabel );
  if( p->aLabel ){
    p->aLabel[j] = p->nOp;
  }
}











































/*
** Loop through the program looking for P2 values that are negative.
** Each such value is a label.  Resolve the label by setting the P2
** value to its correct non-zero value.
**
** This routine is called once after all opcodes have been inserted.
**
................................................................................
      int n;
      assert( p->nOp - i >= 3 );
      assert( pOp[-1].opcode==OP_MemInt );
      n = pOp[-1].p1;
      if( n>nMaxArgs ) nMaxArgs = n;
#endif
    }
    if( !sqlite3VdbeOpcodeHasProperty(opcode, OPFLG_PUSH) ){
      nMaxStack--;
    }

    if( pOp->p2>=0 ) continue;
    assert( -1-pOp->p2<p->nLabel );
    pOp->p2 = aLabel[-1-pOp->p2];
  }