1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-02 05:54:29 +03:00

Improvements to the way sqlite3VdbeAddOpList() works, resulting in a slightly

smaller and faster binary.

FossilOrigin-Name: 88ceb588bcdb3ca86d0c58cfdeb61b5fe070872f
This commit is contained in:
drh
2016-01-16 20:50:21 +00:00
parent 8631402e6a
commit 2ce1865dd8
6 changed files with 161 additions and 126 deletions

View File

@@ -250,8 +250,7 @@ void sqlite3VdbeMultiLoad(Vdbe *p, int iDest, const char *zTypes, ...){
for(i=0; (c = zTypes[i])!=0; i++){
if( c=='s' ){
const char *z = va_arg(ap, const char*);
int addr = sqlite3VdbeAddOp2(p, z==0 ? OP_Null : OP_String8, 0, iDest++);
if( z ) sqlite3VdbeChangeP4(p, addr, z, 0);
sqlite3VdbeAddOp4(p, z==0 ? OP_Null : OP_String8, 0, iDest++, 0, z, 0);
}else{
assert( c=='i' );
sqlite3VdbeAddOp2(p, OP_Integer, va_arg(ap, int), iDest++);
@@ -606,6 +605,17 @@ int sqlite3VdbeCurrentAddr(Vdbe *p){
return p->nOp;
}
/*
** Verify that at least N opcode slots are available in p without
** having to malloc for more space. This interface is used for
** testing only.
*/
#ifdef SQLITE_DEBUG
void sqlite3VdbeVerifyAvailableSpace(Vdbe *p, int N){
assert( p->nOp + N <= p->pParse->nOpAlloc );
}
#endif
/*
** This function returns a pointer to the array of opcodes associated with
** the Vdbe passed as the first argument. It is the callers responsibility
@@ -631,19 +641,23 @@ VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){
}
/*
** Add a whole list of operations to the operation stack. Return the
** address of the first operation added.
** Add a whole list of operations to the operation stack. Return a
** pointer to the first operation inserted.
*/
int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp, int iLineno){
int addr, i;
VdbeOp *pOut;
VdbeOp *sqlite3VdbeAddOpList(
Vdbe *p, /* Add opcodes to the prepared statement */
int nOp, /* Number of opcodes to add */
VdbeOpList const *aOp, /* The opcodes to be added */
int iLineno /* Source-file line number of first opcode */
){
int i;
VdbeOp *pOut, *pFirst;
assert( nOp>0 );
assert( p->magic==VDBE_MAGIC_INIT );
if( p->nOp + nOp > p->pParse->nOpAlloc && growOpArray(p, nOp) ){
return 0;
}
addr = p->nOp;
pOut = &p->aOp[addr];
pFirst = pOut = &p->aOp[p->nOp];
for(i=0; i<nOp; i++, aOp++, pOut++){
pOut->opcode = aOp->opcode;
pOut->p1 = aOp->p1;
@@ -663,12 +677,12 @@ int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp, int iLineno){
#endif
#ifdef SQLITE_DEBUG
if( p->db->flags & SQLITE_VdbeAddopTrace ){
sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]);
sqlite3VdbePrintOp(0, i+p->nOp, &p->aOp[i+p->nOp]);
}
#endif
}
p->nOp += nOp;
return addr;
return pFirst;
}
#if defined(SQLITE_ENABLE_STMT_SCANSTATUS)
@@ -826,14 +840,15 @@ void sqlite3VdbeLinkSubProgram(Vdbe *pVdbe, SubProgram *p){
/*
** Change the opcode at addr into OP_Noop
*/
void sqlite3VdbeChangeToNoop(Vdbe *p, int addr){
if( addr<p->nOp ){
VdbeOp *pOp = &p->aOp[addr];
sqlite3 *db = p->db;
freeP4(db, pOp->p4type, pOp->p4.p);
memset(pOp, 0, sizeof(pOp[0]));
pOp->opcode = OP_Noop;
}
int sqlite3VdbeChangeToNoop(Vdbe *p, int addr){
VdbeOp *pOp;
if( p->db->mallocFailed ) return 0;
assert( addr>=0 && addr<p->nOp );
pOp = &p->aOp[addr];
freeP4(p->db, pOp->p4type, pOp->p4.p);
memset(pOp, 0, sizeof(pOp[0]));
pOp->opcode = OP_Noop;
return 1;
}
/*
@@ -842,8 +857,7 @@ void sqlite3VdbeChangeToNoop(Vdbe *p, int addr){
*/
int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){
if( (p->nOp-1)>(p->pParse->iFixedOp) && p->aOp[p->nOp-1].opcode==op ){
sqlite3VdbeChangeToNoop(p, p->nOp-1);
return 1;
return sqlite3VdbeChangeToNoop(p, p->nOp-1);
}else{
return 0;
}