aboutsummaryrefslogtreecommitdiff
path: root/src/vdbe.c
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2011-09-16 01:34:43 +0000
committerdrh <drh@noemail.net>2011-09-16 01:34:43 +0000
commit48f2d3b10a5ac48ae2a1a24f77c7cb1aab6ea978 (patch)
tree0b02d36b1ecb60c458133c090c14df3c131b6151 /src/vdbe.c
parent5b6a9ed49556deac6d48be80b6ef2816102f1951 (diff)
downloadsqlite-48f2d3b10a5ac48ae2a1a24f77c7cb1aab6ea978.tar.gz
sqlite-48f2d3b10a5ac48ae2a1a24f77c7cb1aab6ea978.zip
Add the new OP_Once opcode. Use it to clean up and simplify various
one-time initialization sections in the code, including the fix for ticket [002caede898ae]. FossilOrigin-Name: 7f00552b739fad79517b042a6ed61abe743a917b
Diffstat (limited to 'src/vdbe.c')
-rw-r--r--src/vdbe.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/src/vdbe.c b/src/vdbe.c
index 906058c1f..4f7fd6bbe 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -2021,6 +2021,16 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */
break;
}
+/* Opcode: Once P1 P2 * * *
+**
+** Jump to P2 if the value in register P1 is a not null or zero. If
+** the value is NULL or zero, fall through and change the P1 register
+** to an integer 1.
+**
+** When P1 is not used otherwise in a program, this opcode falls through
+** once and jumps on all subsequent invocations. It is the equivalent
+** of "OP_If P1 P2", followed by "OP_Integer 1 P1".
+*/
/* Opcode: If P1 P2 P3 * *
**
** Jump to P2 if the value in register P1 is true. The value
@@ -2033,6 +2043,7 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */
** is considered true if it has a numeric value of zero. If the value
** in P1 is NULL then take the jump if P3 is true.
*/
+case OP_Once: /* jump, in1 */
case OP_If: /* jump, in1 */
case OP_IfNot: { /* jump, in1 */
int c;
@@ -2049,6 +2060,12 @@ case OP_IfNot: { /* jump, in1 */
}
if( c ){
pc = pOp->p2-1;
+ }else if( pOp->opcode==OP_Once ){
+ assert( (pIn1->flags & (MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))==0 );
+ memAboutToChange(p, pIn1);
+ pIn1->flags = MEM_Int;
+ pIn1->u.i = 1;
+ REGISTER_TRACE(pOp->p1, pIn1);
}
break;
}