aboutsummaryrefslogtreecommitdiff
path: root/src/vdbeaux.c
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2018-08-29 18:47:22 +0000
committerdrh <drh@noemail.net>2018-08-29 18:47:22 +0000
commit72f56ef95dbed75685221e0018c63e90798a9fd8 (patch)
treea37414505c1856698150c2c3f93621a7d90f0dd3 /src/vdbeaux.c
parentc0d2117f1ceeb4cfe5e406831722523d696274f5 (diff)
downloadsqlite-72f56ef95dbed75685221e0018c63e90798a9fd8.tar.gz
sqlite-72f56ef95dbed75685221e0018c63e90798a9fd8.zip
Free up the MEM_Frame bit in Mem.flags object. Store VdbeFrame objects
as MEM_Blob with a special Mem.xDel pointer instead. FossilOrigin-Name: 62db5fd47660bbc4fcf2c6d4a6c5a3077f12c6442a128d22b66b789a0409ef32
Diffstat (limited to 'src/vdbeaux.c')
-rw-r--r--src/vdbeaux.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index f4708d6c3..ce763e916 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -1661,9 +1661,9 @@ static void releaseMemArray(Mem *p, int N){
*/
testcase( p->flags & MEM_Agg );
testcase( p->flags & MEM_Dyn );
- testcase( p->flags & MEM_Frame );
+ testcase( p->xDel==sqlite3VdbeFrameMemDel );
testcase( p->flags & MEM_RowSet );
- if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){
+ if( p->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet) ){
sqlite3VdbeMemRelease(p);
}else if( p->szMalloc ){
sqlite3DbFreeNN(db, p->zMalloc);
@@ -1675,6 +1675,35 @@ static void releaseMemArray(Mem *p, int N){
}
}
+#ifdef SQLITE_DEBUG
+/*
+** Verify that pFrame is a valid VdbeFrame pointer. Return true if it is
+** and false if something is wrong.
+**
+** This routine is intended for use inside of assert() statements only.
+*/
+int sqlite3VdbeFrameIsValid(VdbeFrame *pFrame){
+ if( pFrame->iFrameMagic!=SQLITE_FRAME_MAGIC ) return 0;
+ return 1;
+}
+#endif
+
+
+/*
+** This is a destructor on a Mem object (which is really an sqlite3_value)
+** that deletes the Frame object that is attached to it as a blob.
+**
+** This routine does not delete the Frame right away. It merely adds the
+** frame to a list of frames to be deleted when the Vdbe halts.
+*/
+void sqlite3VdbeFrameMemDel(void *pArg){
+ VdbeFrame *pFrame = (VdbeFrame*)pArg;
+ assert( sqlite3VdbeFrameIsValid(pFrame) );
+ pFrame->pParent = pFrame->v->pDelFrame;
+ pFrame->v->pDelFrame = pFrame;
+}
+
+
/*
** Delete a VdbeFrame object and its contents. VdbeFrame objects are
** allocated by the OP_Program opcode in sqlite3VdbeExec().
@@ -1683,6 +1712,7 @@ void sqlite3VdbeFrameDelete(VdbeFrame *p){
int i;
Mem *aMem = VdbeFrameMem(p);
VdbeCursor **apCsr = (VdbeCursor **)&aMem[p->nChildMem];
+ assert( sqlite3VdbeFrameIsValid(p) );
for(i=0; i<p->nChildCsr; i++){
sqlite3VdbeFreeCursor(p->v, apCsr[i]);
}