diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/sqliteInt.h | 2 | ||||
-rw-r--r-- | src/vdbe.h | 9 | ||||
-rw-r--r-- | src/vdbeaux.c | 23 |
3 files changed, 22 insertions, 12 deletions
diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 1db0bc4c8..e056088fc 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3068,7 +3068,7 @@ struct Parse { int szOpAlloc; /* Bytes of memory space allocated for Vdbe.aOp[] */ int iSelfTab; /* Table associated with an index on expr, or negative ** of the base register during check-constraint eval */ - int nLabel; /* Number of labels used */ + int nLabel; /* The *negative* of the number of labels used */ int nLabelAlloc; /* Number of slots in aLabel */ int *aLabel; /* Space to hold the labels */ ExprList *pConstExpr;/* Constant expressions */ diff --git a/src/vdbe.h b/src/vdbe.h index 7a0312a04..8928798f1 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -156,12 +156,11 @@ typedef struct VdbeOpList VdbeOpList; #endif /* -** The following macro converts a relative address in the p2 field -** of a VdbeOp structure into a negative number so that -** sqlite3VdbeAddOpList() knows that the address is relative. Calling -** the macro again restores the address. +** The following macro converts a label returned by sqlite3VdbeMakeLabel() +** into an index into the Parse.aLabel[] array that contains the resolved +** address of that label. */ -#define ADDR(X) (-1-(X)) +#define ADDR(X) (~(X)) /* ** The makefile scans the vdbe.c source file and creates the "opcodes.h" diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 77e72e046..193b24db8 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -445,11 +445,22 @@ void sqlite3VdbeEndCoroutine(Vdbe *v, int regYield){ ** The VDBE knows that a P2 value is a label because labels are ** always negative and P2 values are suppose to be non-negative. ** Hence, a negative P2 value is a label that has yet to be resolved. +** (Later:) This is only true for opcodes that have the OPFLG_JUMP +** property. ** -** Zero is returned if a malloc() fails. +** Variable usage notes: +** +** Parse.aLabel[x] Stores the address that the x-th label resolves +** into. For testing (SQLITE_DEBUG), unresolved +** labels stores -1, but that is not required. +** Parse.nLabelAlloc Number of slots allocated to Parse.aLabel[] +** Parse.nLabel The *negative* of the number of labels that have +** been issued. The negative is stored because +** that gives a performance improvement over storing +** the equivalent positive value. */ int sqlite3VdbeMakeLabel(Parse *pParse){ - return ADDR(pParse->nLabel++); + return --pParse->nLabel; } /* @@ -458,7 +469,7 @@ int sqlite3VdbeMakeLabel(Parse *pParse){ ** a prior call to sqlite3VdbeMakeLabel(). */ static SQLITE_NOINLINE void resizeResolveLabel(Parse *p, Vdbe *v, int j){ - int nNewSize = p->nLabel+10; + int nNewSize = 10 - p->nLabel; p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel, nNewSize*sizeof(p->aLabel[0])); if( p->aLabel==0 ){ @@ -476,14 +487,14 @@ void sqlite3VdbeResolveLabel(Vdbe *v, int x){ Parse *p = v->pParse; int j = ADDR(x); assert( v->magic==VDBE_MAGIC_INIT ); - assert( j<p->nLabel ); + assert( j<-p->nLabel ); assert( j>=0 ); #ifdef SQLITE_DEBUG if( p->db->flags & SQLITE_VdbeAddopTrace ){ printf("RESOLVE LABEL %d to %d\n", x, v->nOp); } #endif - if( p->nLabelAlloc < p->nLabel ){ + if( p->nLabelAlloc + p->nLabel < 0 ){ resizeResolveLabel(p,v,j); }else{ assert( p->aLabel[j]==(-1) ); /* Labels may only be resolved once */ @@ -761,7 +772,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ ** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to ** have non-negative values for P2. */ assert( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 ); - assert( ADDR(pOp->p2)<pParse->nLabel ); + assert( ADDR(pOp->p2)<-pParse->nLabel ); pOp->p2 = aLabel[ADDR(pOp->p2)]; } break; |