Improved implementation of the destructor on pointer-passing interfaces.
FossilOrigin-Name: 601ad6795927fff8c3cc1711a2fd90912499573e94aa5bc8f18cbd4b89778f58
This commit is contained in:
parent
22930062d5
commit
a0024e6c99
23
manifest
23
manifest
@ -1,5 +1,5 @@
|
|||||||
C Add\sa\sdestructor\sargument\sto\ssqlite3_bind_pointer()\s\nand\ssqlite3_result_pointer().
|
C Improved\simplementation\sof\sthe\sdestructor\son\spointer-passing\sinterfaces.
|
||||||
D 2017-07-27T03:48:02.500
|
D 2017-07-27T15:53:24.187
|
||||||
F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8
|
F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8
|
||||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||||
F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016
|
F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016
|
||||||
@ -520,13 +520,13 @@ F src/update.c c443935c652af9365e033f756550b5032d02e1b06eb2cb890ed7511ae0c051dc
|
|||||||
F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5
|
F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5
|
||||||
F src/util.c fc081ec6f63448dcd80d3dfad35baecfa104823254a815b081a4d9fe76e1db23
|
F src/util.c fc081ec6f63448dcd80d3dfad35baecfa104823254a815b081a4d9fe76e1db23
|
||||||
F src/vacuum.c 874c0f2f15ab2908748297d587d22d485ea96d55aaec91d4775dddb2e24d2ecf
|
F src/vacuum.c 874c0f2f15ab2908748297d587d22d485ea96d55aaec91d4775dddb2e24d2ecf
|
||||||
F src/vdbe.c d8437d81958fb9d1f3382586e5a2736258e72dc981631853ecfb66f5091ad90c
|
F src/vdbe.c 1e541ec7ff409bbabcc6b4f154957296fff5827c16c2ab0056348acae75685bf
|
||||||
F src/vdbe.h d50cadf12bcf9fb99117ef392ce1ea283aa429270481426b6e8b0280c101fd97
|
F src/vdbe.h d50cadf12bcf9fb99117ef392ce1ea283aa429270481426b6e8b0280c101fd97
|
||||||
F src/vdbeInt.h 4f7034052871f5b358b8c733163505c2820868112494c73294084b20876591cd
|
F src/vdbeInt.h ff2b7db0968d20e6184aee256d2e535d565f5a172e3588a78adb166a41fc4911
|
||||||
F src/vdbeapi.c 7fd45f2470bfc3b02313b4500c965b1848b827b736e3ff754b14861c9c13417f
|
F src/vdbeapi.c 5857a84fcba6005963716c973fabb1fe1bf06b680d202f8548c97861c89f93eb
|
||||||
F src/vdbeaux.c 986c5cae1dcfda124e871a016274589f6b87ddfe4625f60ddf6a5cdb94f64517
|
F src/vdbeaux.c 3fe68bad02b33b09e08bdc0ad90d6b92b3d571f7864c3d047abca1bde050751c
|
||||||
F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9
|
F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9
|
||||||
F src/vdbemem.c 9d1dde677986b68a25b0f30190325ae173fa51d2991ccc7cffda984407cfc5d7
|
F src/vdbemem.c 9ca2854976f35db40341977e688a08204c96427505f5b90215dc7970f6ea42c4
|
||||||
F src/vdbesort.c f512c68d0bf7e0105316a5594c4329358c8ee9cae3b25138df041d97516c0372
|
F src/vdbesort.c f512c68d0bf7e0105316a5594c4329358c8ee9cae3b25138df041d97516c0372
|
||||||
F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834
|
F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834
|
||||||
F src/vtab.c 35b9bdc2b41de32a417141d12097bcc4e29a77ed7cdb8f836d1d2305d946b61b
|
F src/vtab.c 35b9bdc2b41de32a417141d12097bcc4e29a77ed7cdb8f836d1d2305d946b61b
|
||||||
@ -1637,10 +1637,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P f39cb76b3347baba22f2c329e74036710b64620414433a952de8d44da79ba8d9
|
P 3d9e841f6011480ebb8a6d860da72af7fa545983e08835ddef2cac96e5f5cd4b
|
||||||
R f73e68c37e03cf44fd4c91b4fa2d5350
|
R db911569e272fbc630cc582a997f40e2
|
||||||
T *branch * pointer-with-destructor
|
|
||||||
T *sym-pointer-with-destructor *
|
|
||||||
T -sym-branch-3.20 *
|
|
||||||
U drh
|
U drh
|
||||||
Z d38f5fd0f536ce6fac398141bc9e08dd
|
Z c71a43c2a0910e645f13d11d84d63db1
|
||||||
|
@ -1 +1 @@
|
|||||||
3d9e841f6011480ebb8a6d860da72af7fa545983e08835ddef2cac96e5f5cd4b
|
601ad6795927fff8c3cc1711a2fd90912499573e94aa5bc8f18cbd4b89778f58
|
@ -416,7 +416,7 @@ void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){
|
|||||||
else *zCsr++ = z;
|
else *zCsr++ = z;
|
||||||
}
|
}
|
||||||
*(zCsr++) = ']';
|
*(zCsr++) = ']';
|
||||||
if( (f & (MEM_Zero|MEM_Blob))==(MEM_Zero|MEM_Blob) ){
|
if( f & MEM_Zero ){
|
||||||
sqlite3_snprintf(100, zCsr,"+%dz",pMem->u.nZero);
|
sqlite3_snprintf(100, zCsr,"+%dz",pMem->u.nZero);
|
||||||
zCsr += sqlite3Strlen30(zCsr);
|
zCsr += sqlite3Strlen30(zCsr);
|
||||||
}
|
}
|
||||||
@ -2735,7 +2735,7 @@ case OP_MakeRecord: {
|
|||||||
do{
|
do{
|
||||||
assert( memIsValid(pRec) );
|
assert( memIsValid(pRec) );
|
||||||
pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format, &len);
|
pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format, &len);
|
||||||
if( (pRec->flags & MEM_Zero)!=0 && (pRec->flags & MEM_Blob)!=0 ){
|
if( pRec->flags & MEM_Zero ){
|
||||||
if( nData ){
|
if( nData ){
|
||||||
if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem;
|
if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem;
|
||||||
}else{
|
}else{
|
||||||
@ -4411,7 +4411,7 @@ case OP_InsertInt: {
|
|||||||
x.nData = pData->n;
|
x.nData = pData->n;
|
||||||
}
|
}
|
||||||
seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0);
|
seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0);
|
||||||
if( (pData->flags & MEM_Zero)!=0 && (pData->flags & MEM_Blob)!=0 ){
|
if( pData->flags & MEM_Zero ){
|
||||||
x.nZero = pData->u.nZero;
|
x.nZero = pData->u.nZero;
|
||||||
}else{
|
}else{
|
||||||
x.nZero = 0;
|
x.nZero = 0;
|
||||||
|
@ -190,7 +190,7 @@ struct sqlite3_value {
|
|||||||
double r; /* Real value used when MEM_Real is set in flags */
|
double r; /* Real value used when MEM_Real is set in flags */
|
||||||
i64 i; /* Integer value used when MEM_Int is set in flags */
|
i64 i; /* Integer value used when MEM_Int is set in flags */
|
||||||
int nZero; /* Extra zero bytes when MEM_Zero and MEM_Blob set */
|
int nZero; /* Extra zero bytes when MEM_Zero and MEM_Blob set */
|
||||||
const char *zPType; /* Pointer type when MEM_Pointer and MEM_Null set */
|
const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */
|
||||||
FuncDef *pDef; /* Used only when flags==MEM_Agg */
|
FuncDef *pDef; /* Used only when flags==MEM_Agg */
|
||||||
RowSet *pRowSet; /* Used only when flags==MEM_RowSet */
|
RowSet *pRowSet; /* Used only when flags==MEM_RowSet */
|
||||||
VdbeFrame *pFrame; /* Used when flags==MEM_Frame */
|
VdbeFrame *pFrame; /* Used when flags==MEM_Frame */
|
||||||
@ -222,7 +222,8 @@ struct sqlite3_value {
|
|||||||
** representations of the value stored in the Mem struct.
|
** representations of the value stored in the Mem struct.
|
||||||
**
|
**
|
||||||
** If the MEM_Null flag is set, then the value is an SQL NULL value.
|
** If the MEM_Null flag is set, then the value is an SQL NULL value.
|
||||||
** No other flags may be set in this case.
|
** For a pointer type created using sqlite3_bind_pointer() or
|
||||||
|
** sqlite3_result_pointer() the MEM_Term and MEM_Subtype flags are also set.
|
||||||
**
|
**
|
||||||
** If the MEM_Str flag is set then Mem.z points at a string representation.
|
** If the MEM_Str flag is set then Mem.z points at a string representation.
|
||||||
** Usually this is encoded in the same unicode encoding as the main
|
** Usually this is encoded in the same unicode encoding as the main
|
||||||
@ -230,7 +231,7 @@ struct sqlite3_value {
|
|||||||
** set, then the string is nul terminated. The MEM_Int and MEM_Real
|
** set, then the string is nul terminated. The MEM_Int and MEM_Real
|
||||||
** flags may coexist with the MEM_Str flag.
|
** flags may coexist with the MEM_Str flag.
|
||||||
*/
|
*/
|
||||||
#define MEM_Null 0x0001 /* Value is NULL */
|
#define MEM_Null 0x0001 /* Value is NULL (or a pointer) */
|
||||||
#define MEM_Str 0x0002 /* Value is a string */
|
#define MEM_Str 0x0002 /* Value is a string */
|
||||||
#define MEM_Int 0x0004 /* Value is an integer */
|
#define MEM_Int 0x0004 /* Value is an integer */
|
||||||
#define MEM_Real 0x0008 /* Value is a real number */
|
#define MEM_Real 0x0008 /* Value is a real number */
|
||||||
@ -247,18 +248,13 @@ struct sqlite3_value {
|
|||||||
** the following flags must be set to determine the memory management
|
** the following flags must be set to determine the memory management
|
||||||
** policy for Mem.z. The MEM_Term flag tells us whether or not the
|
** policy for Mem.z. The MEM_Term flag tells us whether or not the
|
||||||
** string is \000 or \u0000 terminated
|
** string is \000 or \u0000 terminated
|
||||||
**
|
|
||||||
** NB: MEM_Zero and MEM_Pointer are the same value. But MEM_Zero is
|
|
||||||
** only value if MEM_Blob is also set, and MEM_Pointer is only valid
|
|
||||||
** if MEM_Null is also set.
|
|
||||||
*/
|
*/
|
||||||
#define MEM_Term 0x0200 /* String rep is nul terminated */
|
#define MEM_Term 0x0200 /* String in Mem.z is zero terminated */
|
||||||
#define MEM_Dyn 0x0400 /* Need to call Mem.xDel() on Mem.z */
|
#define MEM_Dyn 0x0400 /* Need to call Mem.xDel() on Mem.z */
|
||||||
#define MEM_Static 0x0800 /* Mem.z points to a static string */
|
#define MEM_Static 0x0800 /* Mem.z points to a static string */
|
||||||
#define MEM_Ephem 0x1000 /* Mem.z points to an ephemeral string */
|
#define MEM_Ephem 0x1000 /* Mem.z points to an ephemeral string */
|
||||||
#define MEM_Agg 0x2000 /* Mem.z points to an agg function context */
|
#define MEM_Agg 0x2000 /* Mem.z points to an agg function context */
|
||||||
#define MEM_Zero 0x4000 /* Mem.i contains count of 0s appended to blob */
|
#define MEM_Zero 0x4000 /* Mem.i contains count of 0s appended to blob */
|
||||||
#define MEM_Pointer 0x4000 /* Mem.z is an extension pointer */
|
|
||||||
#define MEM_Subtype 0x8000 /* Mem.eSubtype is valid */
|
#define MEM_Subtype 0x8000 /* Mem.eSubtype is valid */
|
||||||
#ifdef SQLITE_OMIT_INCRBLOB
|
#ifdef SQLITE_OMIT_INCRBLOB
|
||||||
#undef MEM_Zero
|
#undef MEM_Zero
|
||||||
|
@ -201,8 +201,10 @@ unsigned int sqlite3_value_subtype(sqlite3_value *pVal){
|
|||||||
}
|
}
|
||||||
void *sqlite3_value_pointer(sqlite3_value *pVal, const char *zPType){
|
void *sqlite3_value_pointer(sqlite3_value *pVal, const char *zPType){
|
||||||
Mem *p = (Mem*)pVal;
|
Mem *p = (Mem*)pVal;
|
||||||
if( (p->flags&(MEM_AffMask|MEM_Pointer))==(MEM_Null|MEM_Pointer)
|
if( (p->flags&(MEM_TypeMask|MEM_Term|MEM_Subtype)) ==
|
||||||
|
(MEM_Null|MEM_Term|MEM_Subtype)
|
||||||
&& zPType!=0
|
&& zPType!=0
|
||||||
|
&& p->eSubtype=='p'
|
||||||
&& strcmp(p->u.zPType, zPType)==0
|
&& strcmp(p->u.zPType, zPType)==0
|
||||||
){
|
){
|
||||||
return (void*)p->z;
|
return (void*)p->z;
|
||||||
|
@ -3224,7 +3224,7 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
|
|||||||
assert( pMem->db->mallocFailed || flags&(MEM_Str|MEM_Blob) );
|
assert( pMem->db->mallocFailed || flags&(MEM_Str|MEM_Blob) );
|
||||||
assert( pMem->n>=0 );
|
assert( pMem->n>=0 );
|
||||||
n = (u32)pMem->n;
|
n = (u32)pMem->n;
|
||||||
if( (flags & MEM_Zero)!=0 && (flags & MEM_Blob)!=0 ){
|
if( flags & MEM_Zero ){
|
||||||
n += pMem->u.nZero;
|
n += pMem->u.nZero;
|
||||||
}
|
}
|
||||||
*pLen = n;
|
*pLen = n;
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
*/
|
*/
|
||||||
int sqlite3VdbeCheckMemInvariants(Mem *p){
|
int sqlite3VdbeCheckMemInvariants(Mem *p){
|
||||||
/* If MEM_Dyn is set then Mem.xDel!=0.
|
/* If MEM_Dyn is set then Mem.xDel!=0.
|
||||||
** Mem.xDel is might not be initialized if MEM_Dyn is clear.
|
** Mem.xDel might not be initialized if MEM_Dyn is clear.
|
||||||
*/
|
*/
|
||||||
assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 );
|
assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 );
|
||||||
|
|
||||||
@ -40,9 +40,34 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){
|
|||||||
/* Cannot be both MEM_Int and MEM_Real at the same time */
|
/* Cannot be both MEM_Int and MEM_Real at the same time */
|
||||||
assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) );
|
assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) );
|
||||||
|
|
||||||
/* Cannot be both MEM_Null and some other type */
|
if( p->flags & MEM_Null ){
|
||||||
assert( (p->flags & MEM_Null)==0 ||
|
/* Cannot be both MEM_Null and some other type */
|
||||||
(p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob))==0 );
|
assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob
|
||||||
|
|MEM_RowSet|MEM_Frame|MEM_Agg|MEM_Zero))==0 );
|
||||||
|
|
||||||
|
/* If MEM_Null is set, then either the value is a pure NULL (the usual
|
||||||
|
** case) or it is a pointer set using sqlite3_bind_pointer() or
|
||||||
|
** sqlite3_result_pointer(). If a pointer, then MEM_Term must also be
|
||||||
|
** set.
|
||||||
|
*/
|
||||||
|
if( (p->flags & (MEM_Term|MEM_Subtype))==(MEM_Term|MEM_Subtype) ){
|
||||||
|
/* This is a pointer type. There may be a flag to indicate what to
|
||||||
|
** do with the pointer. */
|
||||||
|
assert( ((p->flags&MEM_Dyn)!=0 ? 1 : 0) +
|
||||||
|
((p->flags&MEM_Ephem)!=0 ? 1 : 0) +
|
||||||
|
((p->flags&MEM_Static)!=0 ? 1 : 0) <= 1 );
|
||||||
|
|
||||||
|
/* No other bits set */
|
||||||
|
assert( (p->flags & ~(MEM_Null|MEM_Term|MEM_Subtype
|
||||||
|
|MEM_Dyn|MEM_Ephem|MEM_Static))==0 );
|
||||||
|
}else{
|
||||||
|
/* A pure NULL might have other flags, such as MEM_Static, MEM_Dyn,
|
||||||
|
** MEM_Ephem, MEM_Cleared, or MEM_Subtype */
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
/* The MEM_Cleared bit is only allowed on NULLs */
|
||||||
|
assert( (p->flags & MEM_Cleared)==0 );
|
||||||
|
}
|
||||||
|
|
||||||
/* The szMalloc field holds the correct memory allocation size */
|
/* The szMalloc field holds the correct memory allocation size */
|
||||||
assert( p->szMalloc==0
|
assert( p->szMalloc==0
|
||||||
@ -220,9 +245,9 @@ int sqlite3VdbeMemMakeWriteable(Mem *pMem){
|
|||||||
int sqlite3VdbeMemExpandBlob(Mem *pMem){
|
int sqlite3VdbeMemExpandBlob(Mem *pMem){
|
||||||
int nByte;
|
int nByte;
|
||||||
assert( pMem->flags & MEM_Zero );
|
assert( pMem->flags & MEM_Zero );
|
||||||
|
assert( pMem->flags&MEM_Blob );
|
||||||
assert( (pMem->flags&MEM_RowSet)==0 );
|
assert( (pMem->flags&MEM_RowSet)==0 );
|
||||||
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
|
||||||
if( (pMem->flags & MEM_Blob)==0 ) return SQLITE_OK;
|
|
||||||
|
|
||||||
/* Set nByte to the number of bytes required to store the expanded blob. */
|
/* Set nByte to the number of bytes required to store the expanded blob. */
|
||||||
nByte = pMem->n + pMem->u.nZero;
|
nByte = pMem->n + pMem->u.nZero;
|
||||||
@ -705,6 +730,9 @@ void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* A no-op destructor */
|
||||||
|
static void sqlite3NoopDestructor(void *p){ UNUSED_PARAMETER(p); }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Set the value stored in *pMem should already be a NULL.
|
** Set the value stored in *pMem should already be a NULL.
|
||||||
** Also store a pointer to go with it.
|
** Also store a pointer to go with it.
|
||||||
@ -716,15 +744,11 @@ void sqlite3VdbeMemSetPointer(
|
|||||||
void (*xDestructor)(void*)
|
void (*xDestructor)(void*)
|
||||||
){
|
){
|
||||||
assert( pMem->flags==MEM_Null );
|
assert( pMem->flags==MEM_Null );
|
||||||
pMem->u.zPType = zPType;
|
pMem->u.zPType = zPType ? zPType : "";
|
||||||
pMem->z = pPtr;
|
pMem->z = pPtr;
|
||||||
if( zPType ){
|
pMem->flags = MEM_Null|MEM_Dyn|MEM_Subtype|MEM_Term;
|
||||||
pMem->flags = MEM_Null|MEM_Pointer;
|
pMem->eSubtype = 'p';
|
||||||
}
|
pMem->xDel = xDestructor ? xDestructor : sqlite3NoopDestructor;
|
||||||
if( xDestructor ){
|
|
||||||
pMem->xDel = xDestructor;
|
|
||||||
pMem->flags |= MEM_Dyn;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SQLITE_OMIT_FLOATING_POINT
|
#ifndef SQLITE_OMIT_FLOATING_POINT
|
||||||
|
Loading…
Reference in New Issue
Block a user