// File: /workspace/github_c_makefile_star2_O0/barabo[P]advanced-shell-history/src/sqlite3.c
// Function: sqlite3ExprCodeIN
static void sqlite3ExprCodeIN(
  Parse *pParse,        /* Parsing and code generating context */
  Expr *pExpr,          /* The IN expression */
  int destIfFalse,      /* Jump here if LHS is not contained in the RHS */
  int destIfNull        /* Jump here if the results are unknown due to NULLs */
){
  int rRhsHasNull = 0;  /* Register that is true if RHS contains NULL values */
  char affinity;        /* Comparison affinity to use */
  int eType;            /* Type of the RHS */
  int r1;               /* Temporary use register */
  Vdbe *v;              /* Statement under construction */

  /* Compute the RHS.   After this step, the table with cursor
  ** pExpr->iTable will contains the values that make up the RHS.
  */
  v = pParse->pVdbe;
  assert( v!=0 );       /* OOM detected prior to this routine */
  VdbeNoopComment((v, "begin IN expr"));
  eType = sqlite3FindInIndex(pParse, pExpr, &rRhsHasNull);

  /* Figure out the affinity to use to create a key from the results
  ** of the expression. affinityStr stores a static string suitable for
  ** P4 of OP_MakeRecord.
  */
  affinity = comparisonAffinity(pExpr);

  /* Code the LHS, the <expr> from "<expr> IN (...)".
  */
  sqlite3ExprCachePush(pParse);
  r1 = sqlite3GetTempReg(pParse);
  sqlite3ExprCode(pParse, pExpr->pLeft, r1);

  /* If the LHS is NULL, then the result is either false or NULL depending
  ** on whether the RHS is empty or not, respectively.
  */
  if( destIfNull==destIfFalse ){
    /* Shortcut for the common case where the false and NULL outcomes are
    ** the same. */
    sqlite3VdbeAddOp2(v, OP_IsNull, r1, destIfNull);
  }else{
    int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1);
    sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse);
    sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull);
    sqlite3VdbeJumpHere(v, addr1);
  }

  if( eType==IN_INDEX_ROWID ){
    /* In this case, the RHS is the ROWID of table b-tree
    */
    sqlite3VdbeAddOp2(v, OP_MustBeInt, r1, destIfFalse);
    sqlite3VdbeAddOp3(v, OP_NotExists, pExpr->iTable, destIfFalse, r1);
  }else{
    /* In this case, the RHS is an index b-tree.
    */
    sqlite3VdbeAddOp4(v, OP_Affinity, r1, 1, 0, &affinity, 1);

    /* If the set membership test fails, then the result of the 
    ** "x IN (...)" expression must be either 0 or NULL. If the set
    ** contains no NULL values, then the result is 0. If the set 
    ** contains one or more NULL values, then the result of the
    ** expression is also NULL.
    */
    if( rRhsHasNull==0 || destIfFalse==destIfNull ){
      /* This branch runs if it is known at compile time that the RHS
      ** cannot contain NULL values. This happens as the result
      ** of a "NOT NULL" constraint in the database schema.
      **
      ** Also run this branch if NULL is equivalent to FALSE
      ** for this particular IN operator.
      */
      sqlite3VdbeAddOp4Int(v, OP_NotFound, pExpr->iTable, destIfFalse, r1, 1);

    }else{
      /* In this branch, the RHS of the IN might contain a NULL and
      ** the presence of a NULL on the RHS makes a difference in the
      ** outcome.
      */
      int j1, j2, j3;

      /* First check to see if the LHS is contained in the RHS.  If so,
      ** then the presence of NULLs in the RHS does not matter, so jump
      ** over all of the code that follows.
      */
      j1 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, r1, 1);

      /* Here we begin generating code that runs if the LHS is not
      ** contained within the RHS.  Generate additional code that
      ** tests the RHS for NULLs.  If the RHS contains a NULL then
      ** jump to destIfNull.  If there are no NULLs in the RHS then
      ** jump to destIfFalse.
      */
      j2 = sqlite3VdbeAddOp1(v, OP_NotNull, rRhsHasNull);
      j3 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, rRhsHasNull, 1);
      sqlite3VdbeAddOp2(v, OP_Integer, -1, rRhsHasNull);
      sqlite3VdbeJumpHere(v, j3);
      sqlite3VdbeAddOp2(v, OP_AddImm, rRhsHasNull, 1);
      sqlite3VdbeJumpHere(v, j2);

      /* Jump to the appropriate target depending on whether or not
      ** the RHS contains a NULL
      */
      sqlite3VdbeAddOp2(v, OP_If, rRhsHasNull, destIfNull);
      sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse);

      /* The OP_Found at the top of this branch jumps here when true, 
      ** causing the overall IN expression evaluation to fall through.
      */
      sqlite3VdbeJumpHere(v, j1);
    }
  }
  sqlite3ReleaseTempReg(pParse, r1);
  sqlite3ExprCachePop(pParse, 1);
  VdbeComment((v, "end IN expr"));
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movl %ecx, -0x18(%rbp)
movl $0x0, -0x1c(%rbp)
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
leaq -0x1c(%rbp), %rdx
callq 0x6abf0
movl %eax, -0x24(%rbp)
movq -0x10(%rbp), %rdi
callq 0x6aff0
movb %al, -0x1d(%rbp)
movq -0x8(%rbp), %rdi
callq 0x67ee0
movq -0x8(%rbp), %rdi
callq 0x66a70
movl %eax, -0x28(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rsi
movl -0x28(%rbp), %edx
callq 0x69c70
movl -0x18(%rbp), %eax
cmpl -0x14(%rbp), %eax
jne 0x68580
movq -0x30(%rbp), %rdi
movl -0x28(%rbp), %edx
movl -0x18(%rbp), %ecx
movl $0x49, %esi
callq 0x5e0c0
jmp 0x685cb
movq -0x30(%rbp), %rdi
movl -0x28(%rbp), %edx
movl $0x4a, %esi
callq 0x5ecf0
movl %eax, -0x34(%rbp)
movq -0x30(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x2c(%rax), %edx
movl -0x14(%rbp), %ecx
movl $0x65, %esi
callq 0x5e0c0
movq -0x30(%rbp), %rdi
movl -0x18(%rbp), %ecx
movl $0xe, %esi
xorl %edx, %edx
callq 0x5e0c0
movq -0x30(%rbp), %rdi
movl -0x34(%rbp), %esi
callq 0x5e090
cmpl $0x1, -0x24(%rbp)
jne 0x68606
movq -0x30(%rbp), %rdi
movl -0x28(%rbp), %edx
movl -0x14(%rbp), %ecx
movl $0x21, %esi
callq 0x5e0c0
movq -0x30(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x2c(%rax), %edx
movl -0x14(%rbp), %ecx
movl -0x28(%rbp), %r8d
movl $0x3f, %esi
callq 0x5e0f0
jmp 0x68734
movq -0x30(%rbp), %rdi
movl -0x28(%rbp), %edx
movl $0x2a, %esi
movl $0x1, %ecx
xorl %r8d, %r8d
leaq -0x1d(%rbp), %r9
movl $0x1, (%rsp)
callq 0x5e1b0
cmpl $0x0, -0x1c(%rbp)
je 0x68638
movl -0x14(%rbp), %eax
cmpl -0x18(%rbp), %eax
jne 0x6865f
movq -0x30(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x2c(%rax), %edx
movl -0x14(%rbp), %ecx
movl -0x28(%rbp), %r8d
movl $0x3c, %esi
movl $0x1, %r9d
callq 0x6b080
jmp 0x68732
movq -0x30(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x2c(%rax), %edx
movl -0x28(%rbp), %r8d
movl $0x3d, %esi
xorl %ecx, %ecx
movl $0x1, %r9d
callq 0x6b080
movl %eax, -0x38(%rbp)
movq -0x30(%rbp), %rdi
movl -0x1c(%rbp), %edx
movl $0x4a, %esi
callq 0x5ecf0
movl %eax, -0x3c(%rbp)
movq -0x30(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x2c(%rax), %edx
movl -0x1c(%rbp), %r8d
movl $0x3d, %esi
xorl %ecx, %ecx
movl $0x1, %r9d
callq 0x6b080
movl %eax, -0x40(%rbp)
movq -0x30(%rbp), %rdi
movl -0x1c(%rbp), %ecx
movl $0x15, %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x5e0c0
movq -0x30(%rbp), %rdi
movl -0x40(%rbp), %esi
callq 0x5e090
movq -0x30(%rbp), %rdi
movl -0x1c(%rbp), %edx
movl $0x20, %esi
movl $0x1, %ecx
callq 0x5e0c0
movq -0x30(%rbp), %rdi
movl -0x3c(%rbp), %esi
callq 0x5e090
movq -0x30(%rbp), %rdi
movl -0x1c(%rbp), %edx
movl -0x18(%rbp), %ecx
movl $0x27, %esi
callq 0x5e0c0
movq -0x30(%rbp), %rdi
movl -0x14(%rbp), %ecx
movl $0xe, %esi
xorl %edx, %edx
callq 0x5e0c0
movq -0x30(%rbp), %rdi
movl -0x38(%rbp), %esi
callq 0x5e090
jmp 0x68734
movq -0x8(%rbp), %rdi
movl -0x28(%rbp), %esi
callq 0x66ac0
movq -0x8(%rbp), %rdi
movl $0x1, %esi
callq 0x68220
addq $0x50, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)