mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Modify the build process so that the VDBE opcode numbers and the table
that contains the opcode names are both automatically generated. This makes it much easier to create new VDBE opcodes. (CVS 746) FossilOrigin-Name: eb54d455b0325d3be96daf6c220c4ee3e0da1a85
This commit is contained in:
106
src/vdbe.c
106
src/vdbe.c
@@ -30,11 +30,19 @@
|
||||
** But other routines are also provided to help in building up
|
||||
** a program instruction by instruction.
|
||||
**
|
||||
** $Id: vdbe.c,v 1.175 2002/09/03 19:43:24 drh Exp $
|
||||
** $Id: vdbe.c,v 1.176 2002/09/08 00:04:52 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
|
||||
/*
|
||||
** The makefile scans this source file and creates the following
|
||||
** array of string constants which are the names of all VDBE opcodes.
|
||||
** This array is defined in a separate source code file named opcode.c
|
||||
** which is automatically generated by the makefile.
|
||||
*/
|
||||
extern char *sqliteOpcodeNames[];
|
||||
|
||||
/*
|
||||
** The following global variable is incremented every time a cursor
|
||||
** moves, either by the OP_MoveTo or the OP_Next opcode. The test
|
||||
@@ -1066,65 +1074,6 @@ void sqliteVdbeDelete(Vdbe *p){
|
||||
sqliteFree(p);
|
||||
}
|
||||
|
||||
/*
|
||||
** A translation from opcode numbers to opcode names. Used for testing
|
||||
** and debugging only.
|
||||
**
|
||||
** If any of the numeric OP_ values for opcodes defined in sqliteVdbe.h
|
||||
** change, be sure to change this array to match. You can use the
|
||||
** "opNames.awk" awk script which is part of the source tree to regenerate
|
||||
** this array, then copy and paste it into this file, if you want.
|
||||
*/
|
||||
static char *zOpName[] = { 0,
|
||||
"Transaction", "Checkpoint", "Commit", "Rollback",
|
||||
"ReadCookie", "SetCookie", "VerifyCookie", "Open",
|
||||
"OpenTemp", "OpenWrite", "OpenAux", "OpenWrAux",
|
||||
"RenameCursor", "Close", "MoveTo", "NewRecno",
|
||||
"PutIntKey", "PutStrKey", "Distinct", "Found",
|
||||
"NotFound", "IsUnique", "NotExists", "Delete",
|
||||
"Column", "KeyAsData", "Recno", "FullKey",
|
||||
"NullRow", "Last", "Rewind", "Next",
|
||||
"Destroy", "Clear", "CreateIndex", "CreateTable",
|
||||
"IntegrityCk", "IdxPut", "IdxDelete", "IdxRecno",
|
||||
"IdxGT", "IdxGE", "MemLoad", "MemStore",
|
||||
"MemIncr", "ListWrite", "ListRewind", "ListRead",
|
||||
"ListReset", "ListPush", "ListPop", "SortPut",
|
||||
"SortMakeRec", "SortMakeKey", "Sort", "SortNext",
|
||||
"SortCallback", "SortReset", "FileOpen", "FileRead",
|
||||
"FileColumn", "AggReset", "AggFocus", "AggNext",
|
||||
"AggSet", "AggGet", "AggFunc", "AggInit",
|
||||
"AggPush", "AggPop", "SetInsert", "SetFound",
|
||||
"SetNotFound", "SetFirst", "SetNext", "MakeRecord",
|
||||
"MakeKey", "MakeIdxKey", "IncrKey", "Goto",
|
||||
"If", "IfNot", "Halt", "Gosub",
|
||||
"Return", "ColumnCount", "ColumnName", "Callback",
|
||||
"NullCallback", "Integer", "String", "Pop",
|
||||
"Dup", "Pull", "Push", "MustBeInt",
|
||||
"Add", "AddImm", "Subtract", "Multiply",
|
||||
"Divide", "Remainder", "BitAnd", "BitOr",
|
||||
"BitNot", "ShiftLeft", "ShiftRight", "AbsValue",
|
||||
"Eq", "Ne", "Lt", "Le",
|
||||
"Gt", "Ge", "StrEq", "StrNe",
|
||||
"StrLt", "StrLe", "StrGt", "StrGe",
|
||||
"IsNull", "NotNull", "Negative", "And",
|
||||
"Or", "Not", "Concat", "Noop",
|
||||
"Function",
|
||||
};
|
||||
|
||||
/*
|
||||
** Given the name of an opcode, return its number. Return 0 if
|
||||
** there is no match.
|
||||
**
|
||||
** This routine is used for testing and debugging.
|
||||
*/
|
||||
int sqliteVdbeOpcode(const char *zName){
|
||||
int i;
|
||||
for(i=1; i<=OP_MAX; i++){
|
||||
if( sqliteStrICmp(zName, zOpName[i])==0 ) return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Give a listing of the program in the virtual machine.
|
||||
**
|
||||
@@ -1175,7 +1124,7 @@ int sqliteVdbeList(
|
||||
}else{
|
||||
azValue[4] = p->aOp[i].p3;
|
||||
}
|
||||
azValue[1] = zOpName[p->aOp[i].opcode];
|
||||
azValue[1] = sqliteOpcodeNames[p->aOp[i].opcode];
|
||||
if( sqliteSafetyOff(db) ){
|
||||
rc = SQLITE_MISUSE;
|
||||
break;
|
||||
@@ -1310,7 +1259,7 @@ static void vdbePrintOp(FILE *pOut, int pc, Op *pOp){
|
||||
}
|
||||
if( pOut==0 ) pOut = stdout;
|
||||
fprintf(pOut,"%4d %-12s %4d %4d %s\n",
|
||||
pc, zOpName[pOp->opcode], pOp->p1, pOp->p2, zP3 ? zP3 : "");
|
||||
pc, sqliteOpcodeNames[pOp->opcode], pOp->p1, pOp->p2, zP3 ? zP3 : "");
|
||||
fflush(pOut);
|
||||
}
|
||||
#endif
|
||||
@@ -2283,7 +2232,18 @@ case OP_Ge: {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* INSERT NO CODE HERE!
|
||||
**
|
||||
** The opcode numbers are extracted from this source file by doing
|
||||
**
|
||||
** grep '^case OP_' vdbe.c | ... >opcodes.h
|
||||
**
|
||||
** The opcodes are numbered in the order that they appear in this file.
|
||||
** But in order for the expression generating code to work right, the
|
||||
** string comparison operators that follow must be numbered exactly 6
|
||||
** greater than the numeric comparison opcodes above. So no other
|
||||
** cases can appear between the two.
|
||||
*/
|
||||
/* Opcode: StrEq P1 P2 *
|
||||
**
|
||||
** Pop the top two elements from the stack. If they are equal, then
|
||||
@@ -2403,13 +2363,18 @@ case OP_StrGe: {
|
||||
if( Stringify(p, tos) || Stringify(p, nos) ) goto no_mem;
|
||||
c = strcmp(zStack[nos], zStack[tos]);
|
||||
}
|
||||
/* The asserts on each case of the following switch are there to verify
|
||||
** that string comparison opcodes are always exactly 6 greater than the
|
||||
** corresponding numeric comparison opcodes. The code generator depends
|
||||
** on this fact.
|
||||
*/
|
||||
switch( pOp->opcode ){
|
||||
case OP_StrEq: c = c==0; break;
|
||||
case OP_StrNe: c = c!=0; break;
|
||||
case OP_StrLt: c = c<0; break;
|
||||
case OP_StrLe: c = c<=0; break;
|
||||
case OP_StrGt: c = c>0; break;
|
||||
default: c = c>=0; break;
|
||||
case OP_StrEq: c = c==0; assert( pOp->opcode-6==OP_Eq ); break;
|
||||
case OP_StrNe: c = c!=0; assert( pOp->opcode-6==OP_Ne ); break;
|
||||
case OP_StrLt: c = c<0; assert( pOp->opcode-6==OP_Lt ); break;
|
||||
case OP_StrLe: c = c<=0; assert( pOp->opcode-6==OP_Le ); break;
|
||||
case OP_StrGt: c = c>0; assert( pOp->opcode-6==OP_Gt ); break;
|
||||
default: c = c>=0; assert( pOp->opcode-6==OP_Ge ); break;
|
||||
}
|
||||
POPSTACK;
|
||||
POPSTACK;
|
||||
@@ -3789,6 +3754,9 @@ case OP_Column: {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: Extract * * *
|
||||
*/
|
||||
|
||||
/* Opcode: Recno P1 * *
|
||||
**
|
||||
** Push onto the stack an integer which is the first 4 bytes of the
|
||||
|
Reference in New Issue
Block a user