mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Simplify the bytecode generation for SQL function calls such that the
OP_Function or OP_PureFunc opcodes are coded directly, rather than using the intermediate OP_Function0 or OP_PureFunc0 - opcodes that are now removed. FossilOrigin-Name: 84e02d773d60cffe619104991d21d7f0c68616c0f6bb99686bf54f5306c756d0
This commit is contained in:
88
src/vdbe.c
88
src/vdbe.c
@@ -7442,29 +7442,14 @@ case OP_MaxPgcnt: { /* out2 */
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Opcode: Function0 P1 P2 P3 P4 P5
|
||||
** Synopsis: r[P3]=func(r[P2@P5])
|
||||
**
|
||||
** Invoke a user function (P4 is a pointer to a FuncDef object that
|
||||
** defines the function) with P5 arguments taken from register P2 and
|
||||
** successors. The result of the function is stored in register P3.
|
||||
** Register P3 must not be one of the function inputs.
|
||||
**
|
||||
** P1 is a 32-bit bitmask indicating whether or not each argument to the
|
||||
** function was determined to be constant at compile time. If the first
|
||||
** argument was constant then bit 0 of P1 is set. This is used to determine
|
||||
** whether meta data associated with a user function argument using the
|
||||
** sqlite3_set_auxdata() API may be safely retained until the next
|
||||
** invocation of this opcode.
|
||||
**
|
||||
** See also: Function, AggStep, AggFinal
|
||||
*/
|
||||
/* Opcode: Function P1 P2 P3 P4 P5
|
||||
/* Opcode: Function P1 P2 P3 P4 *
|
||||
** Synopsis: r[P3]=func(r[P2@P5])
|
||||
**
|
||||
** Invoke a user function (P4 is a pointer to an sqlite3_context object that
|
||||
** contains a pointer to the function to be run) with P5 arguments taken
|
||||
** from register P2 and successors. The result of the function is stored
|
||||
** contains a pointer to the function to be run) with arguments taken
|
||||
** from register P2 and successors. The number of arguments is in
|
||||
** the sqlite3_context object that P4 points to.
|
||||
** The result of the function is stored
|
||||
** in register P3. Register P3 must not be one of the function inputs.
|
||||
**
|
||||
** P1 is a 32-bit bitmask indicating whether or not each argument to the
|
||||
@@ -7474,40 +7459,35 @@ case OP_MaxPgcnt: { /* out2 */
|
||||
** sqlite3_set_auxdata() API may be safely retained until the next
|
||||
** invocation of this opcode.
|
||||
**
|
||||
** SQL functions are initially coded as OP_Function0 with P4 pointing
|
||||
** to a FuncDef object. But on first evaluation, the P4 operand is
|
||||
** automatically converted into an sqlite3_context object and the operation
|
||||
** changed to this OP_Function opcode. In this way, the initialization of
|
||||
** the sqlite3_context object occurs only once, rather than once for each
|
||||
** evaluation of the function.
|
||||
**
|
||||
** See also: Function0, AggStep, AggFinal
|
||||
** See also: AggStep, AggFinal, PureFunc
|
||||
*/
|
||||
/* Opcode: PureFunc P1 P2 P3 P4 *
|
||||
** Synopsis: r[P3]=func(r[P2@P5])
|
||||
**
|
||||
** Invoke a user function (P4 is a pointer to an sqlite3_context object that
|
||||
** contains a pointer to the function to be run) with arguments taken
|
||||
** from register P2 and successors. The number of arguments is in
|
||||
** the sqlite3_context object that P4 points to.
|
||||
** The result of the function is stored
|
||||
** in register P3. Register P3 must not be one of the function inputs.
|
||||
**
|
||||
** P1 is a 32-bit bitmask indicating whether or not each argument to the
|
||||
** function was determined to be constant at compile time. If the first
|
||||
** argument was constant then bit 0 of P1 is set. This is used to determine
|
||||
** whether meta data associated with a user function argument using the
|
||||
** sqlite3_set_auxdata() API may be safely retained until the next
|
||||
** invocation of this opcode.
|
||||
**
|
||||
** This opcode works exactly like OP_Function. The only difference is in
|
||||
** its name. This opcode is used in places where the function must be
|
||||
** purely non-deterministic. Some built-in date/time functions can be
|
||||
** either determinitic of non-deterministic, depending on their arguments.
|
||||
** When those function are used in a non-deterministic way, they will check
|
||||
** to see if they were called using OP_PureFunc instead of OP_Function, and
|
||||
** if they were, they throw an error.
|
||||
**
|
||||
** See also: AggStep, AggFinal, Function
|
||||
*/
|
||||
case OP_PureFunc0: /* group */
|
||||
case OP_Function0: { /* group */
|
||||
int n;
|
||||
sqlite3_context *pCtx;
|
||||
|
||||
assert( pOp->p4type==P4_FUNCDEF );
|
||||
n = pOp->p5;
|
||||
assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
|
||||
assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) );
|
||||
assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
|
||||
pCtx = sqlite3DbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*));
|
||||
if( pCtx==0 ) goto no_mem;
|
||||
pCtx->pOut = 0;
|
||||
pCtx->pFunc = pOp->p4.pFunc;
|
||||
pCtx->iOp = (int)(pOp - aOp);
|
||||
pCtx->pVdbe = p;
|
||||
pCtx->isError = 0;
|
||||
pCtx->argc = n;
|
||||
pOp->p4type = P4_FUNCCTX;
|
||||
pOp->p4.pCtx = pCtx;
|
||||
assert( OP_PureFunc == OP_PureFunc0+2 );
|
||||
assert( OP_Function == OP_Function0+2 );
|
||||
pOp->opcode += 2;
|
||||
/* Fall through into OP_Function */
|
||||
}
|
||||
case OP_PureFunc: /* group */
|
||||
case OP_Function: { /* group */
|
||||
int i;
|
||||
@@ -7522,9 +7502,11 @@ case OP_Function: { /* group */
|
||||
** reinitializes the relavant parts of the sqlite3_context object */
|
||||
pOut = &aMem[pOp->p3];
|
||||
if( pCtx->pOut != pOut ){
|
||||
pCtx->pVdbe = p;
|
||||
pCtx->pOut = pOut;
|
||||
for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i];
|
||||
}
|
||||
assert( pCtx->pVdbe==p );
|
||||
|
||||
memAboutToChange(p, pOut);
|
||||
#ifdef SQLITE_DEBUG
|
||||
|
Reference in New Issue
Block a user