summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/webkit/JavaScriptCore/wtf/dtoa.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/webkit/JavaScriptCore/wtf/dtoa.cpp')
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/wtf/dtoa.cpp216
1 files changed, 126 insertions, 90 deletions
diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/dtoa.cpp b/src/3rdparty/webkit/JavaScriptCore/wtf/dtoa.cpp
index 9509388f09..d75c17a933 100644
--- a/src/3rdparty/webkit/JavaScriptCore/wtf/dtoa.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/wtf/dtoa.cpp
@@ -148,6 +148,7 @@
#include <wtf/AlwaysInline.h>
#include <wtf/Assertions.h>
#include <wtf/FastMalloc.h>
+#include <wtf/Vector.h>
#include <wtf/Threading.h>
#include <stdio.h>
@@ -255,6 +256,8 @@ typedef union { double d; uint32_t L[2]; } U;
#define Big0 (Frac_mask1 | Exp_msk1 * (DBL_MAX_EXP + Bias - 1))
#define Big1 0xffffffff
+
+// FIXME: we should remove non-Pack_32 mode since it is unused and unmaintained
#ifndef Pack_32
#define Pack_32
#endif
@@ -278,25 +281,41 @@ typedef union { double d; uint32_t L[2]; } U;
#define Kmax 15
struct BigInt {
- BigInt() : sign(0), wds(0) { }
- BigInt(const BigInt& other) : sign(other.sign), wds(other.wds)
+ BigInt() : sign(0) { }
+ int sign;
+
+ void clear()
+ {
+ sign = 0;
+ m_words.clear();
+ }
+
+ size_t size() const
+ {
+ return m_words.size();
+ }
+
+ void resize(size_t s)
{
- for (int i = 0; i < 64; ++i)
- x[i] = other.x[i];
+ m_words.resize(s);
+ }
+
+ uint32_t* words()
+ {
+ return m_words.data();
}
- BigInt& operator=(const BigInt& other)
+ const uint32_t* words() const
{
- sign = other.sign;
- wds = other.wds;
- for (int i = 0; i < 64; ++i)
- x[i] = other.x[i];
- return *this;
+ return m_words.data();
}
- int sign;
- int wds;
- uint32_t x[64];
+ void append(uint32_t w)
+ {
+ m_words.append(w);
+ }
+
+ Vector<uint32_t, 16> m_words;
};
static void multadd(BigInt& b, int m, int a) /* multiply by m and add a */
@@ -307,8 +326,8 @@ static void multadd(BigInt& b, int m, int a) /* multiply by m and add a */
uint32_t carry;
#endif
- int wds = b.wds;
- uint32_t* x = b.x;
+ int wds = b.size();
+ uint32_t* x = b.words();
int i = 0;
carry = a;
do {
@@ -331,10 +350,8 @@ static void multadd(BigInt& b, int m, int a) /* multiply by m and add a */
#endif
} while (++i < wds);
- if (carry) {
- b.x[wds++] = (uint32_t)carry;
- b.wds = wds;
- }
+ if (carry)
+ b.append((uint32_t)carry);
}
static void s2b(BigInt& b, const char* s, int nd0, int nd, uint32_t y9)
@@ -346,12 +363,12 @@ static void s2b(BigInt& b, const char* s, int nd0, int nd, uint32_t y9)
for (k = 0, y = 1; x > y; y <<= 1, k++) { }
#ifdef Pack_32
b.sign = 0;
- b.x[0] = y9;
- b.wds = 1;
+ b.resize(1);
+ b.words()[0] = y9;
#else
b.sign = 0;
- b.x[0] = y9 & 0xffff;
- b.wds = (b->x[1] = y9 >> 16) ? 2 : 1;
+ b.resize((b->x[1] = y9 >> 16) ? 2 : 1);
+ b.words()[0] = y9 & 0xffff;
#endif
int i = 9;
@@ -440,8 +457,8 @@ static int lo0bits (uint32_t* y)
static void i2b(BigInt& b, int i)
{
b.sign = 0;
- b.x[0] = i;
- b.wds = 1;
+ b.resize(1);
+ b.words()[0] = i;
}
static void mult(BigInt& aRef, const BigInt& bRef)
@@ -459,23 +476,24 @@ static void mult(BigInt& aRef, const BigInt& bRef)
uint32_t carry, z;
#endif
- if (a->wds < b->wds) {
+ if (a->size() < b->size()) {
const BigInt* tmp = a;
a = b;
b = tmp;
}
- wa = a->wds;
- wb = b->wds;
+ wa = a->size();
+ wb = b->size();
wc = wa + wb;
+ c.resize(wc);
- for (xc = c.x, xa = xc + wc; xc < xa; xc++)
+ for (xc = c.words(), xa = xc + wc; xc < xa; xc++)
*xc = 0;
- xa = a->x;
+ xa = a->words();
xae = xa + wa;
- xb = b->x;
+ xb = b->words();
xbe = xb + wb;
- xc0 = c.x;
+ xc0 = c.words();
#ifdef USE_LONG_LONG
for (; xb < xbe; xc0++) {
if ((y = *xb++)) {
@@ -537,8 +555,8 @@ static void mult(BigInt& aRef, const BigInt& bRef)
}
#endif
#endif
- for (xc0 = c.x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) { }
- c.wds = wc;
+ for (xc0 = c.words(), xc = xc0 + wc; wc > 0 && !*--xc; --wc) { }
+ c.resize(wc);
aRef = c;
}
@@ -617,14 +635,20 @@ static ALWAYS_INLINE void lshift(BigInt& b, int k)
int n = k >> 4;
#endif
- int n1 = n + b.wds + 1;
+ int origSize = b.size();
+ int n1 = n + origSize + 1;
+
+ if (k &= 0x1f)
+ b.resize(b.size() + n + 1);
+ else
+ b.resize(b.size() + n);
- const uint32_t* srcStart = b.x;
- uint32_t* dstStart = b.x;
- const uint32_t* src = srcStart + b.wds - 1;
+ const uint32_t* srcStart = b.words();
+ uint32_t* dstStart = b.words();
+ const uint32_t* src = srcStart + origSize - 1;
uint32_t* dst = dstStart + n1 - 1;
#ifdef Pack_32
- if (k &= 0x1f) {
+ if (k) {
uint32_t hiSubword = 0;
int s = 32 - k;
for (; src >= srcStart; --src) {
@@ -633,7 +657,8 @@ static ALWAYS_INLINE void lshift(BigInt& b, int k)
}
*dst = hiSubword;
ASSERT(dst == dstStart + n);
- b.wds = b.wds + n + (b.x[n1 - 1] != 0);
+
+ b.resize(origSize + n + (b.words()[n1 - 1] != 0));
}
#else
if (k &= 0xf) {
@@ -652,10 +677,11 @@ static ALWAYS_INLINE void lshift(BigInt& b, int k)
do {
*--dst = *src--;
} while (src >= srcStart);
- b.wds = b.wds + n;
}
for (dst = dstStart + n; dst != dstStart; )
*--dst = 0;
+
+ ASSERT(b.size() <= 1 || b.words()[b.size() - 1]);
}
static int cmp(const BigInt& a, const BigInt& b)
@@ -663,15 +689,15 @@ static int cmp(const BigInt& a, const BigInt& b)
const uint32_t *xa, *xa0, *xb, *xb0;
int i, j;
- i = a.wds;
- j = b.wds;
- ASSERT(i <= 1 || a.x[i - 1]);
- ASSERT(j <= 1 || b.x[j - 1]);
+ i = a.size();
+ j = b.size();
+ ASSERT(i <= 1 || a.words()[i - 1]);
+ ASSERT(j <= 1 || b.words()[j - 1]);
if (i -= j)
return i;
- xa0 = a.x;
+ xa0 = a.words();
xa = xa0 + j;
- xb0 = b.x;
+ xb0 = b.words();
xb = xb0 + j;
for (;;) {
if (*--xa != *--xb)
@@ -692,8 +718,8 @@ static ALWAYS_INLINE void diff(BigInt& c, const BigInt& aRef, const BigInt& bRef
i = cmp(*a, *b);
if (!i) {
c.sign = 0;
- c.wds = 1;
- c.x[0] = 0;
+ c.resize(1);
+ c.words()[0] = 0;
return;
}
if (i < 0) {
@@ -704,15 +730,16 @@ static ALWAYS_INLINE void diff(BigInt& c, const BigInt& aRef, const BigInt& bRef
} else
i = 0;
- c.wds = 0;
- c.sign = i;
- wa = a->wds;
- const uint32_t* xa = a->x;
+ wa = a->size();
+ const uint32_t* xa = a->words();
const uint32_t* xae = xa + wa;
- wb = b->wds;
- const uint32_t* xb = b->x;
+ wb = b->size();
+ const uint32_t* xb = b->words();
const uint32_t* xbe = xb + wb;
- xc = c.x;
+
+ c.resize(wa);
+ c.sign = i;
+ xc = c.words();
#ifdef USE_LONG_LONG
unsigned long long borrow = 0;
do {
@@ -757,7 +784,7 @@ static ALWAYS_INLINE void diff(BigInt& c, const BigInt& aRef, const BigInt& bRef
#endif
while (!*--xc)
wa--;
- c.wds = wa;
+ c.resize(wa);
}
static double ulp(U *x)
@@ -804,8 +831,8 @@ static double b2d(const BigInt& a, int* e)
#define d0 word0(&d)
#define d1 word1(&d)
- xa0 = a.x;
- xa = xa0 + a.wds;
+ xa0 = a.words();
+ xa = xa0 + a.size();
y = *--xa;
ASSERT(y);
k = hi0bits(y);
@@ -860,11 +887,11 @@ static ALWAYS_INLINE void d2b(BigInt& b, U* d, int* e, int* bits)
b.sign = 0;
#ifdef Pack_32
- b.wds = 1;
+ b.resize(1);
#else
- b.wds = 2;
+ b.resize(2);
#endif
- x = b.x;
+ x = b.words();
z = d0 & Frac_mask;
d0 &= 0x7fffffff; /* clear sign bit, which we ignore */
@@ -881,17 +908,21 @@ static ALWAYS_INLINE void d2b(BigInt& b, U* d, int* e, int* bits)
z >>= k;
} else
x[0] = y;
+ if (z) {
+ b.resize(2);
+ x[1] = z;
+ }
+
#ifndef Sudden_Underflow
- i =
+ i = b.size();
#endif
- b.wds = (x[1] = z) ? 2 : 1;
} else {
k = lo0bits(&z);
x[0] = z;
#ifndef Sudden_Underflow
- i =
+ i = 1;
#endif
- b.wds = 1;
+ b.resize(1);
k += 32;
}
#else
@@ -929,7 +960,7 @@ static ALWAYS_INLINE void d2b(BigInt& b, U* d, int* e, int* bits)
k += 32;
} while (!x[i])
--i;
- b->wds = i + 1;
+ b->resize(i + 1);
#endif
#ifndef Sudden_Underflow
if (de) {
@@ -958,9 +989,9 @@ static double ratio(const BigInt& a, const BigInt& b)
dval(&da) = b2d(a, &ka);
dval(&db) = b2d(b, &kb);
#ifdef Pack_32
- k = ka - kb + 32 * (a.wds - b.wds);
+ k = ka - kb + 32 * (a.size() - b.size());
#else
- k = ka - kb + 16 * (a.wds - b.wds);
+ k = ka - kb + 16 * (a.size() - b.size());
#endif
if (k > 0)
word0(&da) += k * Exp_msk1;
@@ -1452,12 +1483,12 @@ undfl:
#endif
) {
#ifdef SET_INEXACT
- if (!delta->x[0] && delta->wds <= 1)
+ if (!delta->words()[0] && delta->size() <= 1)
inexact = 0;
#endif
break;
}
- if (!delta.x[0] && delta.wds <= 1) {
+ if (!delta.words()[0] && delta.size() <= 1) {
/* exact result */
#ifdef SET_INEXACT
inexact = 0;
@@ -1700,7 +1731,7 @@ ret:
static ALWAYS_INLINE int quorem(BigInt& b, BigInt& S)
{
- int n;
+ size_t n;
uint32_t *bx, *bxe, q, *sx, *sxe;
#ifdef USE_LONG_LONG
unsigned long long borrow, carry, y, ys;
@@ -1710,14 +1741,16 @@ static ALWAYS_INLINE int quorem(BigInt& b, BigInt& S)
uint32_t si, z, zs;
#endif
#endif
+ ASSERT(b.size() <= 1 || b.words()[b.size() - 1]);
+ ASSERT(S.size() <= 1 || S.words()[S.size() - 1]);
- n = S.wds;
- ASSERT_WITH_MESSAGE(b.wds <= n, "oversize b in quorem");
- if (b.wds < n)
+ n = S.size();
+ ASSERT_WITH_MESSAGE(b.size() <= n, "oversize b in quorem");
+ if (b.size() < n)
return 0;
- sx = S.x;
+ sx = S.words();
sxe = sx + --n;
- bx = b.x;
+ bx = b.words();
bxe = bx + n;
q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
ASSERT_WITH_MESSAGE(q <= 9, "oversized quotient in quorem");
@@ -1752,18 +1785,18 @@ static ALWAYS_INLINE int quorem(BigInt& b, BigInt& S)
#endif
} while (sx <= sxe);
if (!*bxe) {
- bx = b.x;
+ bx = b.words();
while (--bxe > bx && !*bxe)
--n;
- b.wds = n;
+ b.resize(n);
}
}
if (cmp(b, S) >= 0) {
q++;
borrow = 0;
carry = 0;
- bx = b.x;
- sx = S.x;
+ bx = b.words();
+ sx = S.words();
do {
#ifdef USE_LONG_LONG
ys = *sx++ + carry;
@@ -1791,12 +1824,12 @@ static ALWAYS_INLINE int quorem(BigInt& b, BigInt& S)
#endif
#endif
} while (sx <= sxe);
- bx = b.x;
+ bx = b.words();
bxe = bx + n;
if (!*bxe) {
while (--bxe > bx && !*bxe)
--n;
- b.wds = n;
+ b.resize(n);
}
}
return q;
@@ -2027,7 +2060,8 @@ void dtoa(char* result, double dd, int ndigits, int* decpt, int* sign, char** rv
dval(&eps) = (ieps * dval(&u)) + 7.;
word0(&eps) -= (P - 1) * Exp_msk1;
if (ilim == 0) {
- S = mhi = BigInt();
+ S.clear();
+ mhi.clear();
dval(&u) -= 5.;
if (dval(&u) > dval(&eps))
goto one_digit;
@@ -2090,7 +2124,8 @@ fast_failed:
/* Yes. */
ds = tens[k];
if (ndigits < 0 && ilim <= 0) {
- S = mhi = BigInt();
+ S.clear();
+ mhi.clear();
if (ilim < 0 || dval(&u) <= 5 * ds)
goto no_digits;
goto one_digit;
@@ -2132,7 +2167,8 @@ bump_up:
m2 = b2;
m5 = b5;
- mhi = mlo = BigInt();
+ mhi.clear();
+ mlo.clear();
if (leftright) {
i =
#ifndef Sudden_Underflow
@@ -2186,10 +2222,10 @@ bump_up:
* can do shifts and ors to compute the numerator for q.
*/
#ifdef Pack_32
- if ((i = ((s5 ? 32 - hi0bits(S.x[S.wds - 1]) : 1) + s2) & 0x1f))
+ if ((i = ((s5 ? 32 - hi0bits(S.words()[S.size() - 1]) : 1) + s2) & 0x1f))
i = 32 - i;
#else
- if ((i = ((s5 ? 32 - hi0bits(S.x[S.wds - 1]) : 1) + s2) & 0xf))
+ if ((i = ((s5 ? 32 - hi0bits(S.words()[S.size() - 1]) : 1) + s2) & 0xf))
i = 16 - i;
#endif
if (i > 4) {
@@ -2252,7 +2288,7 @@ bump_up:
goto ret;
}
if (j < 0 || (j == 0 && !(word1(&u) & 1))) {
- if (!b.x[0] && b.wds <= 1) {
+ if (!b.words()[0] && b.size() <= 1) {
#ifdef SET_INEXACT
inexact = 0;
#endif
@@ -2287,7 +2323,7 @@ round_9_up:
} else
for (i = 1;; i++) {
*s++ = dig = quorem(b,S) + '0';
- if (!b.x[0] && b.wds <= 1) {
+ if (!b.words()[0] && b.size() <= 1) {
#ifdef SET_INEXACT
inexact = 0;
#endif