⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vdbe.c

📁 sqlite数据库管理系统开放源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Opcode: Eq P1 P2 ***** Pop the top two elements from the stack.  If they are equal, then** jump to instruction P2.  Otherwise, continue to the next instruction.**** If either operand is NULL (and thus if the result is unknown) then** take the jump if P1 is true.**** If both values are numeric, they are converted to doubles using atof()** and compared for equality that way.  Otherwise the strcmp() library** routine is used for the comparison.  For a pure text comparison** use OP_StrEq.**** If P2 is zero, do not jump.  Instead, push an integer 1 onto the** stack if the jump would have been taken, or a 0 if not.  Push a** NULL if either operand was NULL.*//* Opcode: Ne P1 P2 ***** Pop the top two elements from the stack.  If they are not equal, then** jump to instruction P2.  Otherwise, continue to the next instruction.**** If either operand is NULL (and thus if the result is unknown) then** take the jump if P1 is true.**** If both values are numeric, they are converted to doubles using atof()** and compared in that format.  Otherwise the strcmp() library** routine is used for the comparison.  For a pure text comparison** use OP_StrNe.**** If P2 is zero, do not jump.  Instead, push an integer 1 onto the** stack if the jump would have been taken, or a 0 if not.  Push a** NULL if either operand was NULL.*//* Opcode: Lt P1 P2 ***** Pop the top two elements from the stack.  If second element (the** next on stack) is less than the first (the top of stack), then** jump to instruction P2.  Otherwise, continue to the next instruction.** In other words, jump if NOS<TOS.**** If either operand is NULL (and thus if the result is unknown) then** take the jump if P1 is true.**** If both values are numeric, they are converted to doubles using atof()** and compared in that format.  Numeric values are always less than** non-numeric values.  If both operands are non-numeric, the strcmp() library** routine is used for the comparison.  For a pure text comparison** use OP_StrLt.**** If P2 is zero, do not jump.  Instead, push an integer 1 onto the** stack if the jump would have been taken, or a 0 if not.  Push a** NULL if either operand was NULL.*//* Opcode: Le P1 P2 ***** Pop the top two elements from the stack.  If second element (the** next on stack) is less than or equal to the first (the top of stack),** then jump to instruction P2. In other words, jump if NOS<=TOS.**** If either operand is NULL (and thus if the result is unknown) then** take the jump if P1 is true.**** If both values are numeric, they are converted to doubles using atof()** and compared in that format.  Numeric values are always less than** non-numeric values.  If both operands are non-numeric, the strcmp() library** routine is used for the comparison.  For a pure text comparison** use OP_StrLe.**** If P2 is zero, do not jump.  Instead, push an integer 1 onto the** stack if the jump would have been taken, or a 0 if not.  Push a** NULL if either operand was NULL.*//* Opcode: Gt P1 P2 ***** Pop the top two elements from the stack.  If second element (the** next on stack) is greater than the first (the top of stack),** then jump to instruction P2. In other words, jump if NOS>TOS.**** If either operand is NULL (and thus if the result is unknown) then** take the jump if P1 is true.**** If both values are numeric, they are converted to doubles using atof()** and compared in that format.  Numeric values are always less than** non-numeric values.  If both operands are non-numeric, the strcmp() library** routine is used for the comparison.  For a pure text comparison** use OP_StrGt.**** If P2 is zero, do not jump.  Instead, push an integer 1 onto the** stack if the jump would have been taken, or a 0 if not.  Push a** NULL if either operand was NULL.*//* Opcode: Ge P1 P2 ***** Pop the top two elements from the stack.  If second element (the next** on stack) is greater than or equal to the first (the top of stack),** then jump to instruction P2. In other words, jump if NOS>=TOS.**** If either operand is NULL (and thus if the result is unknown) then** take the jump if P1 is true.**** If both values are numeric, they are converted to doubles using atof()** and compared in that format.  Numeric values are always less than** non-numeric values.  If both operands are non-numeric, the strcmp() library** routine is used for the comparison.  For a pure text comparison** use OP_StrGe.**** If P2 is zero, do not jump.  Instead, push an integer 1 onto the** stack if the jump would have been taken, or a 0 if not.  Push a** NULL if either operand was NULL.*/case OP_Eq:case OP_Ne:case OP_Lt:case OP_Le:case OP_Gt:case OP_Ge: {  Mem *pNos = &pTos[-1];  int c, v;  int ft, fn;  assert( pNos>=p->aStack );  ft = pTos->flags;  fn = pNos->flags;  if( (ft | fn) & MEM_Null ){    popStack(&pTos, 2);    if( pOp->p2 ){      if( pOp->p1 ) pc = pOp->p2-1;    }else{      pTos++;      pTos->flags = MEM_Null;    }    break;  }else if( (ft & fn & MEM_Int)==MEM_Int ){    c = pNos->i - pTos->i;  }else if( (ft & MEM_Int)!=0 && (fn & MEM_Str)!=0 && toInt(pNos->z,&v) ){    c = v - pTos->i;  }else if( (fn & MEM_Int)!=0 && (ft & MEM_Str)!=0 && toInt(pTos->z,&v) ){    c = pNos->i - v;  }else{    Stringify(pTos);    Stringify(pNos);    c = sqliteCompare(pNos->z, pTos->z);  }  switch( pOp->opcode ){    case OP_Eq:    c = c==0;     break;    case OP_Ne:    c = c!=0;     break;    case OP_Lt:    c = c<0;      break;    case OP_Le:    c = c<=0;     break;    case OP_Gt:    c = c>0;      break;    default:       c = c>=0;     break;  }  popStack(&pTos, 2);  if( pOp->p2 ){    if( c ) pc = pOp->p2-1;  }else{    pTos++;    pTos->i = c;    pTos->flags = MEM_Int;  }  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** jump to instruction P2.  Otherwise, continue to the next instruction.**** If either operand is NULL (and thus if the result is unknown) then** take the jump if P1 is true.**** The strcmp() library routine is used for the comparison.  For a** numeric comparison, use OP_Eq.**** If P2 is zero, do not jump.  Instead, push an integer 1 onto the** stack if the jump would have been taken, or a 0 if not.  Push a** NULL if either operand was NULL.*//* Opcode: StrNe P1 P2 ***** Pop the top two elements from the stack.  If they are not equal, then** jump to instruction P2.  Otherwise, continue to the next instruction.**** If either operand is NULL (and thus if the result is unknown) then** take the jump if P1 is true.**** The strcmp() library routine is used for the comparison.  For a** numeric comparison, use OP_Ne.**** If P2 is zero, do not jump.  Instead, push an integer 1 onto the** stack if the jump would have been taken, or a 0 if not.  Push a** NULL if either operand was NULL.*//* Opcode: StrLt P1 P2 ***** Pop the top two elements from the stack.  If second element (the** next on stack) is less than the first (the top of stack), then** jump to instruction P2.  Otherwise, continue to the next instruction.** In other words, jump if NOS<TOS.**** If either operand is NULL (and thus if the result is unknown) then** take the jump if P1 is true.**** The strcmp() library routine is used for the comparison.  For a** numeric comparison, use OP_Lt.**** If P2 is zero, do not jump.  Instead, push an integer 1 onto the** stack if the jump would have been taken, or a 0 if not.  Push a** NULL if either operand was NULL.*//* Opcode: StrLe P1 P2 ***** Pop the top two elements from the stack.  If second element (the** next on stack) is less than or equal to the first (the top of stack),** then jump to instruction P2. In other words, jump if NOS<=TOS.**** If either operand is NULL (and thus if the result is unknown) then** take the jump if P1 is true.**** The strcmp() library routine is used for the comparison.  For a** numeric comparison, use OP_Le.**** If P2 is zero, do not jump.  Instead, push an integer 1 onto the** stack if the jump would have been taken, or a 0 if not.  Push a** NULL if either operand was NULL.*//* Opcode: StrGt P1 P2 ***** Pop the top two elements from the stack.  If second element (the** next on stack) is greater than the first (the top of stack),** then jump to instruction P2. In other words, jump if NOS>TOS.**** If either operand is NULL (and thus if the result is unknown) then** take the jump if P1 is true.**** The strcmp() library routine is used for the comparison.  For a** numeric comparison, use OP_Gt.**** If P2 is zero, do not jump.  Instead, push an integer 1 onto the** stack if the jump would have been taken, or a 0 if not.  Push a** NULL if either operand was NULL.*//* Opcode: StrGe P1 P2 ***** Pop the top two elements from the stack.  If second element (the next** on stack) is greater than or equal to the first (the top of stack),** then jump to instruction P2. In other words, jump if NOS>=TOS.**** If either operand is NULL (and thus if the result is unknown) then** take the jump if P1 is true.**** The strcmp() library routine is used for the comparison.  For a** numeric comparison, use OP_Ge.**** If P2 is zero, do not jump.  Instead, push an integer 1 onto the** stack if the jump would have been taken, or a 0 if not.  Push a** NULL if either operand was NULL.*/case OP_StrEq:case OP_StrNe:case OP_StrLt:case OP_StrLe:case OP_StrGt:case OP_StrGe: {  Mem *pNos = &pTos[-1];  int c;  assert( pNos>=p->aStack );  if( (pNos->flags | pTos->flags) & MEM_Null ){    popStack(&pTos, 2);    if( pOp->p2 ){      if( pOp->p1 ) pc = pOp->p2-1;    }else{      pTos++;      pTos->flags = MEM_Null;    }    break;  }else{    Stringify(pTos);    Stringify(pNos);    c = strcmp(pNos->z, pTos->z);  }  /* 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;    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(&pTos, 2);  if( pOp->p2 ){    if( c ) pc = pOp->p2-1;  }else{    pTos++;    pTos->flags = MEM_Int;    pTos->i = c;  }  break;}/* Opcode: And * * ***** Pop two values off the stack.  Take the logical AND of the** two values and push the resulting boolean value back onto the** stack. *//* Opcode: Or * * ***** Pop two values off the stack.  Take the logical OR of the** two values and push the resulting boolean value back onto the** stack. */case OP_And:case OP_Or: {  Mem *pNos = &pTos[-1];  int v1, v2;    /* 0==TRUE, 1==FALSE, 2==UNKNOWN or NULL */  assert( pNos>=p->aStack );  if( pTos->flags & MEM_Null ){    v1 = 2;  }else{    Integerify(pTos);    v1 = pTos->i==0;  }  if( pNos->flags & MEM_Null ){    v2 = 2;  }else{    Integerify(pNos);    v2 = pNos->i==0;  }  if( pOp->opcode==OP_And ){    static const unsigned char and_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 };    v1 = and_logic[v1*3+v2];  }else{    static const unsigned char or_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 };    v1 = or_logic[v1*3+v2];  }  popStack(&pTos, 2);  pTos++;  if( v1==2 ){    pTos->flags = MEM_Null;  }else{    pTos->i = v1==0;    pTos->flags = MEM_Int;  }  break;}/* Opcode: Negative * * ***** Treat the top of the stack as a numeric quantity.  Replace it** with its additive inverse.  If the top of the stack is NULL** its value is unchanged.*//* Opcode: AbsValue * * ***** Treat the top of the stack as a numeric quantity.  Replace it** with its absolute value. If the top of the stack is NULL** its value is unchanged.*/case OP_Negative:case OP_AbsValue: {  assert( pTos>=p->aStack );  if( pTos->flags & MEM_Real ){    Release(pTos);    if( pOp->opcode==OP_Negative || pTos->r<0.0 ){      pTos->r = -pTos->r;    }    pTos->flags = MEM_Real;  }else if( pTos->flags & MEM_Int ){    Release(pTos);    if( pOp->opcode==OP_Negative || pTos->i<0 ){      pTos->i = -pTos->i;    }    pTos->flags = MEM_Int;  }else if( pTos->flags & MEM_Null ){    /* Do nothing */  }else{    Realify(pTos);    Release(pTos);    if( pOp->opcode==OP_Negative || pTos->r<0.0 ){      pTos->r = -pTos->r;    }    pTos->flags = MEM_Real;  }  break;}/* Opcode: Not * * ***** Interpret the top of the stack as a boolean value.  Replace it** with its complement.  If the top of the stack is NULL its value** is unchanged.*/case OP_Not: {  assert( pTos>=p->aStack );  if( pTos->flags & MEM_Null ) break;  /* Do nothing to NULLs */  Integerify(pTos);  Release(pTos);  pTos->i = !pTos->i;  pTos->flags = MEM_Int;  break;}/* Opcode: BitNot * * ***** Interpret the top of the stack as an value.  Replace it** with its ones-complement.  If the top of the stack is NULL its** value is unchanged.*/case OP_BitNot: {  assert( pTos>=p->aStack );  if( pTos->flags & MEM_Null ) break;  /* Do nothing to NULLs */  Integerify(pTos);  Release(pTos);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -