From 60d09a712cf2253f243683dae32fe0958d6c87fc Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 30 Aug 2007 15:05:08 +0000 Subject: [PATCH] Fix the SQLITE_MIXED_ENDIAN_64BIT_FLOAT option so that it works on goofy linux kernels that employ CONFIG_FPE_FASTFPE. Patch from Frank van Vugt. (CVS 4339) FossilOrigin-Name: 71ab92e900512ad01047b46f734bd5f65998ecf9 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 27 ++++++++++++++++++++------- 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 7760fe718a..344a2fdb01 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sref-count\sproblem\sin\sthe\sTCL\sbindings.\s\sTicket\s#2597.\s(CVS\s4338) -D 2007-08-30T14:58:20 +C Fix\sthe\sSQLITE_MIXED_ENDIAN_64BIT_FLOAT\soption\sso\sthat\sit\sworks\son\ngoofy\slinux\skernels\sthat\semploy\sCONFIG_FPE_FASTFPE.\s\sPatch\sfrom\nFrank\svan\sVugt.\s(CVS\s4339) +D 2007-08-30T15:05:08 F Makefile.in bfcc303429a5d9dcd552d807ee016c77427418c3 F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -166,7 +166,7 @@ F src/vdbe.c d2f156bbb6b636e9b4a3648c38454bf472668a86 F src/vdbe.h 03a0fa17f6753a24d6cb585d7a362944a2c115aa F src/vdbeInt.h 630145b9bfaa19190ab491f52658a7db550f2247 F src/vdbeapi.c 9c2d681b75e4b90c28b9dd01a3f2e5905267f884 -F src/vdbeaux.c 0e92ed38fe905131f1a95011d67cea67cd973ff2 +F src/vdbeaux.c e35c851e3c1d18a7b90dbe35ae5e0fc9419a4ed4 F src/vdbeblob.c 82f51cdf9b0c0af729732fde48c824e498c0a1ca F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6 F src/vdbemem.c 246d434fa60bde6553490eb686adfd86adcd6712 @@ -568,7 +568,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P 5a22d8695b49cf7bc2eee382b66a98d29adb9e6e -R e8bf3e9d6844747dd965b50d2cb26b45 +P 18a5babb72102f9a82cb24757612a8b683a3f995 +R 8fce7bfd868038e0cdf6352f204f8e03 U drh -Z 936d6ea52e3c08696df033234951ad71 +Z a486c2c7c2c9dc221c09c07a8a467098 diff --git a/manifest.uuid b/manifest.uuid index c635013750..4af2d4186d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -18a5babb72102f9a82cb24757612a8b683a3f995 \ No newline at end of file +71ab92e900512ad01047b46f734bd5f65998ecf9 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 4af63d2fc6..ac347c50a5 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1852,11 +1852,24 @@ int sqlite3VdbeSerialTypeLen(u32 serial_type){ ** application using -DSQLITE_DEBUG=1 at least once. With DEBUG ** enabled, some asserts below will ensure that the byte order of ** floating point values is correct. +** +** (2007-08-30) Frank van Vugt has studied this problem closely +** and has send his findings to the SQLite developers. Frank +** writes that some Linux kernels offer floating point hardware +** emulation that uses only 32-bit mantissas instead of a full +** 48-bits as required by the IEEE standard. (This is the +** CONFIG_FPE_FASTFPE option.) On such systems, floating point +** byte swapping becomes very complicated. To avoid problems, +** the necessary byte swapping is carried out using a 64-bit integer +** rather than a 64-bit float. Frank assures us that the code here +** works for him. We, the developers, have no way to independently +** verify this, but Frank seems to know what he is talking about +** so we trust him. */ #ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT -static double floatSwap(double in){ +static u64 floatSwap(u64 in){ union { - double r; + u64 r; u32 i[2]; } u; u32 t; @@ -1900,8 +1913,8 @@ int sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_format){ int i; if( serial_type==7 ){ assert( sizeof(v)==sizeof(pMem->r) ); - swapMixedEndianFloat(pMem->r); memcpy(&v, &pMem->r, sizeof(v)); + swapMixedEndianFloat(v); }else{ v = pMem->u.i; } @@ -1991,9 +2004,9 @@ int sqlite3VdbeSerialGet( */ static const u64 t1 = ((u64)0x3ff00000)<<32; static const double r1 = 1.0; - double r2 = r1; - swapMixedEndianFloat(r2); - assert( sizeof(r2)==sizeof(t1) && memcmp(&r2, &t1, sizeof(r1))==0 ); + u64 t2 = t1; + swapMixedEndianFloat(t2); + assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 ); #endif x = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3]; @@ -2004,8 +2017,8 @@ int sqlite3VdbeSerialGet( pMem->flags = MEM_Int; }else{ assert( sizeof(x)==8 && sizeof(pMem->r)==8 ); + swapMixedEndianFloat(x); memcpy(&pMem->r, &x, sizeof(x)); - swapMixedEndianFloat(pMem->r); pMem->flags = MEM_Real; } return 8; -- 2.47.3