/ Check-in [f10130ed]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix more instances of assuming 'char' is signed. And, make sure to never shift a signed integer.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | broken-on-arm
Files: files | file ages | folders
SHA1: f10130ede433a19b3945753f23962871c8d2dcf3
User & Date: drh 2014-03-04 04:04:33
Context
2014-03-04
04:12
Refactor the sqlite3VdbeRecordCompare() routine used to compare btree records. Create fast-track special case routines to handle the common cases more quickly. This gives a significant performance boost. check-in: 3325ad5b user: drh tags: trunk
04:04
Fix more instances of assuming 'char' is signed. And, make sure to never shift a signed integer. Closed-Leaf check-in: f10130ed user: drh tags: broken-on-arm
00:15
Do not assume that 'char' is signed. Make it explicit. check-in: 979da752 user: drh tags: broken-on-arm
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbeaux.c.

  2938   2938       return len;
  2939   2939     }
  2940   2940   
  2941   2941     /* NULL or constants 0 or 1 */
  2942   2942     return 0;
  2943   2943   }
  2944   2944   
         2945  +/* Input "x" is a sequence of unsigned characters that represent a
         2946  +** big-endian integer.  Return the equivalent native integer
         2947  +*/
         2948  +#define ONE_BYTE_INT(x)    ((i8)(x)[0])
         2949  +#define TWO_BYTE_INT(x)    (256*(i8)((x)[0])|(x)[1])
         2950  +#define THREE_BYTE_INT(x)  (65536*(i8)((x)[0])|((x)[1]<<8)|(x)[2])
         2951  +#define FOUR_BYTE_UINT(x)  (((u32)(x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
         2952  +
  2945   2953   /*
  2946   2954   ** Deserialize the data blob pointed to by buf as serial type serial_type
  2947   2955   ** and store the result in pMem.  Return the number of bytes read.
  2948   2956   */ 
  2949   2957   u32 sqlite3VdbeSerialGet(
  2950   2958     const unsigned char *buf,     /* Buffer to deserialize from */
  2951   2959     u32 serial_type,              /* Serial type to deserialize */
  2952   2960     Mem *pMem                     /* Memory cell to write value into */
  2953   2961   ){
  2954   2962     u64 x;
  2955   2963     u32 y;
  2956         -  int i;
  2957   2964     switch( serial_type ){
  2958   2965       case 10:   /* Reserved for future use */
  2959   2966       case 11:   /* Reserved for future use */
  2960   2967       case 0: {  /* NULL */
  2961   2968         pMem->flags = MEM_Null;
  2962   2969         break;
  2963   2970       }
  2964   2971       case 1: { /* 1-byte signed integer */
  2965         -      pMem->u.i = (signed char)buf[0];
         2972  +      pMem->u.i = ONE_BYTE_INT(buf);
  2966   2973         pMem->flags = MEM_Int;
  2967   2974         return 1;
  2968   2975       }
  2969   2976       case 2: { /* 2-byte signed integer */
  2970         -      i = 256*(signed char)buf[0] | buf[1];
  2971         -      pMem->u.i = (i64)i;
         2977  +      pMem->u.i = TWO_BYTE_INT(buf);
  2972   2978         pMem->flags = MEM_Int;
  2973   2979         return 2;
  2974   2980       }
  2975   2981       case 3: { /* 3-byte signed integer */
  2976         -      i = 65536*(signed char)buf[0] | (buf[1]<<8) | buf[2];
  2977         -      pMem->u.i = (i64)i;
         2982  +      pMem->u.i = THREE_BYTE_INT(buf);
  2978   2983         pMem->flags = MEM_Int;
  2979   2984         return 3;
  2980   2985       }
  2981   2986       case 4: { /* 4-byte signed integer */
  2982         -      y = ((unsigned)buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
         2987  +      y = FOUR_BYTE_UINT(buf);
  2983   2988         pMem->u.i = (i64)*(int*)&y;
  2984   2989         pMem->flags = MEM_Int;
  2985   2990         return 4;
  2986   2991       }
  2987   2992       case 5: { /* 6-byte signed integer */
  2988         -      x = 256*(signed char)buf[0] + buf[1];
  2989         -      y = ((unsigned)buf[2]<<24) | (buf[3]<<16) | (buf[4]<<8) | buf[5];
  2990         -      x = (x<<32) | y;
  2991         -      pMem->u.i = *(i64*)&x;
         2993  +      pMem->u.i = FOUR_BYTE_UINT(buf+2) + (((i64)1)<<32)*TWO_BYTE_INT(buf);
  2992   2994         pMem->flags = MEM_Int;
  2993   2995         return 6;
  2994   2996       }
  2995   2997       case 6:   /* 8-byte signed integer */
  2996   2998       case 7: { /* IEEE floating point */
  2997   2999   #if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT)
  2998   3000         /* Verify that integers and floating point values use the same
................................................................................
  3002   3004         */
  3003   3005         static const u64 t1 = ((u64)0x3ff00000)<<32;
  3004   3006         static const double r1 = 1.0;
  3005   3007         u64 t2 = t1;
  3006   3008         swapMixedEndianFloat(t2);
  3007   3009         assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 );
  3008   3010   #endif
  3009         -      x = ((unsigned)buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
  3010         -      y = ((unsigned)buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7];
         3011  +      x = FOUR_BYTE_UINT(buf);
         3012  +      y = FOUR_BYTE_UINT(buf+4);
  3011   3013         x = (x<<32) | y;
  3012   3014         if( serial_type==6 ){
  3013   3015           pMem->u.i = *(i64*)&x;
  3014   3016           pMem->flags = MEM_Int;
  3015   3017         }else{
  3016   3018           assert( sizeof(x)==8 && sizeof(pMem->r)==8 );
  3017   3019           swapMixedEndianFloat(x);
................................................................................
  3348   3350   ** The first argument passed to this function is a serial-type that
  3349   3351   ** corresponds to an integer - all values between 1 and 9 inclusive 
  3350   3352   ** except 7. The second points to a buffer containing an integer value
  3351   3353   ** serialized according to serial_type. This function deserializes
  3352   3354   ** and returns the value.
  3353   3355   */
  3354   3356   static i64 vdbeRecordDecodeInt(u32 serial_type, const u8 *aKey){
         3357  +  u32 y;
  3355   3358     assert( CORRUPT_DB || (serial_type>=1 && serial_type<=9 && serial_type!=7) );
  3356   3359     switch( serial_type ){
  3357   3360       case 0:
  3358   3361       case 1:
  3359         -      return (char)aKey[0];
         3362  +      return ONE_BYTE_INT(aKey);
  3360   3363       case 2:
  3361         -      return ((char)aKey[0] << 8) | aKey[1];
         3364  +      return TWO_BYTE_INT(aKey);
  3362   3365       case 3:
  3363         -      return ((char)aKey[0] << 16) | (aKey[1] << 8) | aKey[2];
  3364         -    case 4:
  3365         -      return ((char)aKey[0]<<24) | (aKey[1]<<16) | (aKey[2]<<8)| aKey[3];
         3366  +      return THREE_BYTE_INT(aKey);
         3367  +    case 4: {
         3368  +      y = FOUR_BYTE_UINT(aKey);
         3369  +      return (i64)*(int*)&y;
         3370  +    }
  3366   3371       case 5: {
  3367         -      i64 msw = ((char)aKey[0]<<24)|(aKey[1]<<16)|(aKey[2]<<8)|aKey[3];
  3368         -      u32 lsw = (aKey[4] << 8) | aKey[5];
  3369         -      return (i64)( msw << 16 | (u64)lsw );
         3372  +      return FOUR_BYTE_UINT(aKey+2) + (((i64)1)<<32)*TWO_BYTE_INT(aKey);
  3370   3373       }
  3371   3374       case 6: {
  3372         -      i64 msw = ((char)aKey[0]<<24)|(aKey[1]<<16)|(aKey[2]<<8)|aKey[3];
  3373         -      u32 lsw = ((unsigned)aKey[4]<<24)|(aKey[5]<<16)|(aKey[6]<<8)|aKey[7];
  3374         -      return (i64)( msw << 32 | (u64)lsw );
         3375  +      u64 x = FOUR_BYTE_UINT(aKey);
         3376  +      x = (x<<32) | FOUR_BYTE_UINT(aKey+4);
         3377  +      return (i64)*(i64*)&x;
  3375   3378       }
  3376   3379     }
  3377   3380   
  3378   3381     return (serial_type - 8);
  3379   3382   }
  3380   3383   
  3381   3384   /*
................................................................................
  3574   3577     int nKey1, const void *pKey1, /* Left key */
  3575   3578     const UnpackedRecord *pPKey2, /* Right key */
  3576   3579     int bSkip                     /* Ignored */
  3577   3580   ){
  3578   3581     const u8 *aKey = &((const u8*)pKey1)[*(const u8*)pKey1 & 0x3F];
  3579   3582     int serial_type = ((const u8*)pKey1)[1];
  3580   3583     int res;
         3584  +  u32 y;
         3585  +  u64 x;
  3581   3586     i64 v = pPKey2->aMem[0].u.i;
  3582   3587     i64 lhs;
  3583   3588     UNUSED_PARAMETER(bSkip);
  3584   3589   
  3585   3590     assert( bSkip==0 );
  3586   3591     switch( serial_type ){
  3587         -    case 1:
  3588         -      lhs = (char)(aKey[0]);
         3592  +    case 1: { /* 1-byte signed integer */
         3593  +      lhs = ONE_BYTE_INT(aKey);
         3594  +      break;
         3595  +    }
         3596  +    case 2: { /* 2-byte signed integer */
         3597  +      lhs = TWO_BYTE_INT(aKey);
  3589   3598         break;
  3590         -    case 2:
  3591         -      lhs = 256*(signed char)aKey[0] + aKey[1];
         3599  +    }
         3600  +    case 3: { /* 3-byte signed integer */
         3601  +      lhs = THREE_BYTE_INT(aKey);
  3592   3602         break;
  3593         -    case 3:
  3594         -      lhs = 65536*(char)aKey[0] | (aKey[1]<<8) | aKey[2];
         3603  +    }
         3604  +    case 4: { /* 4-byte signed integer */
         3605  +      y = FOUR_BYTE_UINT(aKey);
         3606  +      lhs = (i64)*(int*)&y;
  3595   3607         break;
  3596         -    case 4:
  3597         -      lhs = (int)(((u32)aKey[0]<<24) | (aKey[1]<<16) | (aKey[2]<<8)| aKey[3]);
  3598         -      break;
  3599         -    case 5: {
  3600         -      i64 msw = ((char)aKey[0]<<24)|(aKey[1]<<16)|(aKey[2]<<8)|aKey[3];
  3601         -      u32 lsw = (aKey[4] << 8) | aKey[5];
  3602         -      lhs = (i64)( msw << 16 | (u64)lsw );
         3608  +    }
         3609  +    case 5: { /* 6-byte signed integer */
         3610  +      lhs = FOUR_BYTE_UINT(aKey+2) + (((i64)1)<<32)*TWO_BYTE_INT(aKey);
  3603   3611         break;
  3604   3612       }
  3605         -    case 6: {
  3606         -      i64 msw = ((char)aKey[0]<<24)|(aKey[1]<<16)|(aKey[2]<<8)|aKey[3];
  3607         -      u32 lsw = ((unsigned)aKey[4]<<24)|(aKey[5]<<16)|(aKey[6]<<8)|aKey[7];
  3608         -      lhs = (i64)( msw << 32 | (u64)lsw );
         3613  +    case 6: { /* 8-byte signed integer */
         3614  +      x = FOUR_BYTE_UINT(aKey);
         3615  +      x = (x<<32) | FOUR_BYTE_UINT(aKey+4);
         3616  +      lhs = *(i64*)&x;
  3609   3617         break;
  3610   3618       }
  3611   3619       case 8: 
  3612   3620         lhs = 0;
  3613   3621         break;
  3614   3622       case 9:
  3615   3623         lhs = 1;