From 1902516d16d24506a7ae8ce3ac776bbad78c539e Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 3 Mar 2022 15:00:44 +0000 Subject: [PATCH] Add the new OP_BeginSubrtn opcode (which is really an alias for OP_Integer) and make other changes so that the span of a subroutine that implements a subquery is more readily apparent in bytecode listings. FossilOrigin-Name: b8226748709de37cfc86414714c20567254e5b320b380e767c322dba69a79d49 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 18 +++++++++++------- src/vdbe.c | 17 ++++++++++++++++- 4 files changed, 35 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index d18322769a..9ff7ab746e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Bloom\sfilter\spull-down\soptimization\sis\sincompatible\swith\sSkip-Scan.\nMake\ssure\sthe\squery\splanner\sdoes\snot\stry\sto\sto\sboth.\n[forum:/info/50a1bbe08ce4c29c|Forum\spost\s50a1bbe08ce4c29c]. -D 2022-03-02T21:04:10.291 +C Add\sthe\snew\sOP_BeginSubrtn\sopcode\s(which\sis\sreally\san\salias\sfor\sOP_Integer)\nand\smake\sother\schanges\sso\sthat\sthe\sspan\sof\sa\ssubroutine\sthat\simplements\na\ssubquery\sis\smore\sreadily\sapparent\sin\sbytecode\slistings. +D 2022-03-03T15:00:44.258 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -503,7 +503,7 @@ F src/date.c 1abbd739ae1d3fc8e0aaff995f57332af10d0b332728e4d3f241c494515495f0 F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d F src/delete.c b5f1716b4d723db48254ee0f896e362cd029e865e05414139ea7f539f3884e1d -F src/expr.c b90a029105a93a93a0ed5e5f8c5eaed8f19043a3b62e4c4d235a4611d9ada178 +F src/expr.c 3cdb00b6c15f815c94836e7b4474b675155d1279e64804f6ab5816188a9b05b6 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 06e4ac33031b02dde7130c12e79cddf4dc5cfa72b23d8e63a3c26878fc9c1d3c F src/func.c f801c6bc8b30afea51817d86a6c46259d3cca180c612cfa0a30b18d661e9c8df @@ -624,7 +624,7 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c d2cf2ef62b51aedab4d9df4b9980f70f95c7ab294ff6e56478067630b7c5c5eb +F src/vdbe.c 62282c976aedf02603368d8d20d33cb7c8c214a34538f39da028d3e0c2aa6e16 F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e F src/vdbeInt.h 8dd91427155a38ec06e9ecbde07e33f21bc02e101625191e7613f883e379a363 F src/vdbeapi.c 1c80efbe51118bbecc7279023e75d18edcfa4b3dc441287e1718ee70ad594f58 @@ -1944,8 +1944,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 86c5fa2f301e4bdb538099f654b70b6ba0e214778cba2c53c53844e5d7ca129f -R ce130c74174cec9891d61458e25bf794 +P ad3ffa1a75a5a032ebb64d8e014ee0a85c5e44b732e4b11bd67f31a59e729b94 +R cf617415d744f05eb16874e90dfd5f1d U drh -Z d775ec6037256eae49bb0d3cd795e9f6 +Z c1aa9fa8cb20b2f538a49ebe46b0f2e7 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 570bbc16d5..04cf7d651f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ad3ffa1a75a5a032ebb64d8e014ee0a85c5e44b732e4b11bd67f31a59e729b94 \ No newline at end of file +b8226748709de37cfc86414714c20567254e5b320b380e767c322dba69a79d49 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 271f06bc6a..79889bdd75 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3040,8 +3040,7 @@ void sqlite3CodeRhsOfIN( assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); pExpr->y.sub.regReturn = ++pParse->nMem; pExpr->y.sub.iAddr = - sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1; - VdbeComment((v, "return address")); + sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1; addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); } @@ -3143,6 +3142,7 @@ void sqlite3CodeRhsOfIN( ** expression we need to rerun this code each time. */ if( addrOnce && !sqlite3ExprIsConstant(pE2) ){ + sqlite3VdbeChangeToNoop(v, addrOnce-1); sqlite3VdbeChangeToNoop(v, addrOnce); ExprClearProperty(pExpr, EP_Subrtn); addrOnce = 0; @@ -3163,7 +3163,10 @@ void sqlite3CodeRhsOfIN( sqlite3VdbeJumpHere(v, addrOnce); /* Subroutine return */ assert( ExprUseYSub(pExpr) ); - sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn); + assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn + || pParse->nErr ); + sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, 0, + pExpr->y.sub.iAddr-1); sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1); sqlite3ClearTempRegCache(pParse); } @@ -3218,9 +3221,7 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ ExprSetProperty(pExpr, EP_Subrtn); pExpr->y.sub.regReturn = ++pParse->nMem; pExpr->y.sub.iAddr = - sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1; - VdbeComment((v, "return address")); - + sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1; /* The evaluation of the EXISTS/SELECT must be repeated every time it ** is encountered if any of the following is true: @@ -3293,7 +3294,10 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ /* Subroutine return */ assert( ExprUseYSub(pExpr) ); - sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn); + assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn + || pParse->nErr ); + sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, 0, + pExpr->y.sub.iAddr-1); sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1); sqlite3ClearTempRegCache(pParse); return rReg; diff --git a/src/vdbe.c b/src/vdbe.c index e0668ea9aa..554c9afb54 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -991,10 +991,14 @@ jump_to_p2: break; } -/* Opcode: Return P1 * * * * +/* Opcode: Return P1 * P3 * * ** ** Jump to the next instruction after the address in register P1. After ** the jump, register P1 becomes undefined. +** +** P3 is not used by the byte-code engine. However, the code generator +** sets P3 to address of the associated OP_BeginSubrtn opcode, if there is +** one. */ case OP_Return: { /* in1 */ pIn1 = &aMem[pOp->p1]; @@ -1182,11 +1186,22 @@ case OP_Halt: { goto vdbe_return; } +/* Opcode: BeginSubrtn P1 P2 * * * +** Synopsis: r[P2]=P1 +** +** Mark the beginning of a subroutine by loading the integer value P1 +** into register r[P2]. The P2 register is used to store the return +** address of the subroutine call. +** +** This opcode is identical to OP_Integer. It has a different name +** only to make the byte code easier to read and verify. +*/ /* Opcode: Integer P1 P2 * * * ** Synopsis: r[P2]=P1 ** ** The 32-bit integer value P1 is written into register P2. */ +case OP_BeginSubrtn: case OP_Integer: { /* out2 */ pOut = out2Prerelease(p, pOp); pOut->u.i = pOp->p1; -- 2.47.2