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

📄 vdbe.c

📁 sqlite 嵌入式数据库的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
  }  a = sqlite3VdbeIntValue(pNos);  b = sqlite3VdbeIntValue(pTos);  switch( pOp->opcode ){    case OP_BitAnd:      a &= b;     break;    case OP_BitOr:       a |= b;     break;    case OP_ShiftLeft:   a <<= b;    break;    case OP_ShiftRight:  a >>= b;    break;    default:   /* CANT HAPPEN */     break;  }  Release(pTos);  pTos--;  Release(pTos);  pTos->i = a;  pTos->flags = MEM_Int;  break;}/* Opcode: AddImm  P1 * *** ** Add the value P1 to whatever is on top of the stack.  The result** is always an integer.**** To force the top of the stack to be an integer, just add 0.*/case OP_AddImm: {            /* no-push */  assert( pTos>=p->aStack );  Integerify(pTos);  pTos->i += pOp->p1;  break;}/* Opcode: ForceInt P1 P2 ***** Convert the top of the stack into an integer.  If the current top of** the stack is not numeric (meaning that is is a NULL or a string that** does not look like an integer or floating point number) then pop the** stack and jump to P2.  If the top of the stack is numeric then** convert it into the least integer that is greater than or equal to its** current value if P1==0, or to the least integer that is strictly** greater than its current value if P1==1.*/case OP_ForceInt: {            /* no-push */  i64 v;  assert( pTos>=p->aStack );  applyAffinity(pTos, SQLITE_AFF_INTEGER, db->enc);  if( (pTos->flags & (MEM_Int|MEM_Real))==0 ){    Release(pTos);    pTos--;    pc = pOp->p2 - 1;    break;  }  if( pTos->flags & MEM_Int ){    v = pTos->i + (pOp->p1!=0);  }else{    Realify(pTos);    v = (int)pTos->r;    if( pTos->r>(double)v ) v++;    if( pOp->p1 && pTos->r==(double)v ) v++;  }  Release(pTos);  pTos->i = v;  pTos->flags = MEM_Int;  break;}/* Opcode: MustBeInt P1 P2 *** ** Force the top of the stack to be an integer.  If the top of the** stack is not an integer and cannot be converted into an integer** with out data loss, then jump immediately to P2, or if P2==0** raise an SQLITE_MISMATCH exception.**** If the top of the stack is not an integer and P2 is not zero and** P1 is 1, then the stack is popped.  In all other cases, the depth** of the stack is unchanged.*/case OP_MustBeInt: {            /* no-push */  assert( pTos>=p->aStack );  applyAffinity(pTos, SQLITE_AFF_INTEGER, db->enc);  if( (pTos->flags & MEM_Int)==0 ){    if( pOp->p2==0 ){      rc = SQLITE_MISMATCH;      goto abort_due_to_error;    }else{      if( pOp->p1 ) popStack(&pTos, 1);      pc = pOp->p2 - 1;    }  }else{    Release(pTos);    pTos->flags = MEM_Int;  }  break;}/* Opcode: Eq P1 P2 P3**** Pop the top two elements from the stack.  If they are equal, then** jump to instruction P2.  Otherwise, continue to the next instruction.**** If the 0x100 bit of P1 is true and either operand is NULL then take the** jump.  If the 0x100 bit of P1 is false then fall thru if either operand** is NULL.**** The least significant byte of P1 (mask 0xff) must be an affinity character -** 'n', 't', 'i' or 'o' - or 0x00. An attempt is made to coerce both values** according to the affinity before the comparison is made. If the byte is** 0x00, then numeric affinity is used.**** Once any conversions have taken place, and neither value is NULL, ** the values are compared. If both values are blobs, or both are text,** then memcmp() is used to determine the results of the comparison. If** both values are numeric, then a numeric comparison is used. If the** two values are of different types, then they are inequal.**** 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.**** If P3 is not NULL it is a pointer to a collating sequence (a CollSeq** structure) that defines how to compare text.*//* Opcode: Ne P1 P2 P3**** This works just like the Eq opcode except that the jump is taken if** the operands from the stack are not equal.  See the Eq opcode for** additional information.*//* Opcode: Lt P1 P2 P3**** This works just like the Eq opcode except that the jump is taken if** the 2nd element down on the stack is less than the top of the stack.** See the Eq opcode for additional information.*//* Opcode: Le P1 P2 P3**** This works just like the Eq opcode except that the jump is taken if** the 2nd element down on the stack is less than or equal to the** top of the stack.  See the Eq opcode for additional information.*//* Opcode: Gt P1 P2 P3**** This works just like the Eq opcode except that the jump is taken if** the 2nd element down on the stack is greater than the top of the stack.** See the Eq opcode for additional information.*//* Opcode: Ge P1 P2 P3**** This works just like the Eq opcode except that the jump is taken if** the 2nd element down on the stack is greater than or equal to the** top of the stack.  See the Eq opcode for additional information.*/case OP_Eq:               /* same as TK_EQ, no-push */case OP_Ne:               /* same as TK_NE, no-push */case OP_Lt:               /* same as TK_LT, no-push */case OP_Le:               /* same as TK_LE, no-push */case OP_Gt:               /* same as TK_GT, no-push */case OP_Ge: {             /* same as TK_GE, no-push */  Mem *pNos;  int flags;  int res;  char affinity;  pNos = &pTos[-1];  flags = pTos->flags|pNos->flags;  /* If either value is a NULL P2 is not zero, take the jump if the least  ** significant byte of P1 is true. If P2 is zero, then push a NULL onto  ** the stack.  */  if( flags&MEM_Null ){    popStack(&pTos, 2);    if( pOp->p2 ){      if( pOp->p1 & 0x100 ) pc = pOp->p2-1;    }else{      pTos++;      pTos->flags = MEM_Null;    }    break;  }  affinity = pOp->p1 & 0xFF;  if( affinity ){    applyAffinity(pNos, affinity, db->enc);    applyAffinity(pTos, affinity, db->enc);  }  assert( pOp->p3type==P3_COLLSEQ || pOp->p3==0 );  res = sqlite3MemCompare(pNos, pTos, (CollSeq*)pOp->p3);  switch( pOp->opcode ){    case OP_Eq:    res = res==0;     break;    case OP_Ne:    res = res!=0;     break;    case OP_Lt:    res = res<0;      break;    case OP_Le:    res = res<=0;     break;    case OP_Gt:    res = res>0;      break;    default:       res = res>=0;     break;  }  popStack(&pTos, 2);  if( pOp->p2 ){    if( res ){      pc = pOp->p2-1;    }  }else{    pTos++;    pTos->flags = MEM_Int;    pTos->i = res;  }  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:              /* same as TK_AND, no-push */case OP_Or: {             /* same as TK_OR, no-push */  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:              /* same as TK_UMINUS, no-push */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);    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: {                /* same as TK_NOT, no-push */  assert( pTos>=p->aStack );  if( pTos->flags & MEM_Null ) break;  /* Do nothing to NULLs */  Integerify(pTos);  assert( (pTos->flags & MEM_Dyn)==0 );  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: {             /* same as TK_BITNOT, no-push */  assert( pTos>=p->aStack );  if( pTos->flags & MEM_Null ) break;  /* Do nothing to NULLs */  Integerify(pTos);  assert( (pTos->flags & MEM_Dyn)==0 );  pTos->i = ~pTos->i;  pTos->flags = MEM_Int;  break;}/* Opcode: Noop * * ***** Do nothing.  This instruction is often useful as a jump** destination.*/case OP_Noop: {            /* no-push */  break;}/* Opcode: If P1 P2 ***** Pop a single boolean from the stack.  If the boolean popped is** true, then jump to p2.  Otherwise continue to the next instruction.** An integer is false if zero and true otherwise.  A string is** false if it has zero length and true otherwise.**** If the value popped of the stack is NULL, then take the jump if P1** is true and fall through if P1 is false.*//* Opcode: IfNot P1 P2 ***** Pop a single boolean from the stack.  If the boolean popped is** false, then jump to p2.  Otherwise continue to the next instruction.** An integer is false if zero and true otherwise.  A string is** false if it has zero length and true otherwise.**** If the value popped of the stack is NULL, then take the jump if P1** is true and fall through if P1 is false.*/case OP_If:                 /* no-push */case OP_IfNot: {            /* no-push */  int c;  assert( pTos>=p->aStack );  if( pTos->flags & MEM_Null ){    c = pOp->p1;  }else{#ifdef SQLITE_OMIT_FLOATING_POINT    c = sqlite3VdbeIntValue(pTos);#else    c = sqlite3VdbeRealValue(pTos)!=0.0;#endif    if( pOp->opcode==OP_IfNot ) c = !c;  }  Release(pTos);  pTos--;  if( c ) pc = pOp->p2-1;  break;}/* Opcode: IsNull P1 P2 ***** If any of the top abs(P1) values on the stack are NULL, then jump** to P2.  Pop the stack P1 times if P1>0.   If P1<0 leave the stack** unchanged.*/case OP_IsNull: {            /* same as TK_ISNULL, no-push */  int i, cnt;  Mem *pTerm;  cnt = pOp->p1;  if( cnt<0 ) cnt = -cnt;  pTerm = &pTos[1-cnt];  assert( pTerm>=p->aStack );  for(i=0; i<cnt; i++, pTerm++){    if( pTerm->flags & MEM_Null ){      pc = pOp->p2-1;      break;    }  }  if( pOp->p1>0 ) popStack(&pTos, cnt);  break;}/* Opcode: NotNull P1 P2 ***** Jump to P2 if the top P1 values on the stack are all not NULL.  Pop the** stack if P1 times if P1 is greater than zero.  If P1 is less than** zero then leave the stack unchanged.*/case OP_NotNull: {            /* same as TK_NOTNULL, no-push */  int i, cnt;  cnt = pOp->p1;  if( cnt<0 ) cnt = -cnt;  assert( &pTos[1-cnt] >= p->aStack );  for(i=0; i<cnt && (pTos[1+i-cnt].flags & MEM_Null)==0; i++){}  if( i>=cnt ) pc = pOp->p2-1;  if( pOp->p1>0 ) popStack(&pTos, cnt);  break;}/* Opcode: SetNumColumns P1 P2 ***** Before the OP_Column opcode can be executed on a cursor, this** opcode must be called to set the number of fields in the table.**** This opcode sets the number of columns for cursor P1 to P2.**** If OP_KeyAsData is to be applied to cursor P1, it must be executed** before this op-code.

⌨️ 快捷键说明

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