From f28d1108b2d9dd9e14187fd5729b004c679303a3 Mon Sep 17 00:00:00 2001 From: "rogerl%netscape.com" Date: Wed, 9 Jul 2003 22:56:56 +0000 Subject: [PATCH] Fixed 54/53 bit bug in random() Added start of runtimestrings... --- js2/src/js2math.cpp | 10 ++-- js2/src/js2runtimestring.h | 99 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 5 deletions(-) create mode 100644 js2/src/js2runtimestring.h diff --git a/js2/src/js2math.cpp b/js2/src/js2math.cpp index 46862e5f7c1..91a7b5a6fa2 100644 --- a/js2/src/js2math.cpp +++ b/js2/src/js2math.cpp @@ -218,8 +218,8 @@ static void random_init(JS2Metadata *meta) meta->rngInitialized = true; /* meta->rngMultiplier = 0x5DEECE66DL */ - JSLL_ISHL(tmp, 0x5D, 32); - JSLL_UI2L(tmp2, 0xEECE66DL); + JSLL_ISHL(tmp, 0x5, 32); + JSLL_UI2L(tmp2, 0xDEECE66DL); JSLL_OR(meta->rngMultiplier, tmp, tmp2); /* meta->rngAddend = 0xBL */ @@ -230,8 +230,8 @@ static void random_init(JS2Metadata *meta) JSLL_SHL(tmp2, tmp, 48); JSLL_SUB(meta->rngMask, tmp2, tmp); - /* meta->rngDscale = (jsdouble)(1L << 54) */ - JSLL_SHL(tmp2, tmp, 54); + /* meta->rngDscale = (jsdouble)(1L << 53) */ + JSLL_SHL(tmp2, tmp, 53); JSLL_L2D(meta->rngDscale, tmp2); /* Finally, set the seed from current time. */ @@ -257,7 +257,7 @@ static float64 random_nextDouble(JS2Metadata *meta) int64 tmp, tmp2; float64 d; - JSLL_ISHL(tmp, random_next(meta, 27), 27); + JSLL_ISHL(tmp, random_next(meta, 26), 27); JSLL_UI2L(tmp2, random_next(meta, 27)); JSLL_ADD(tmp, tmp, tmp2); JSLL_L2D(d, tmp); diff --git a/js2/src/js2runtimestring.h b/js2/src/js2runtimestring.h new file mode 100644 index 00000000000..d002ba0597c --- /dev/null +++ b/js2/src/js2runtimestring.h @@ -0,0 +1,99 @@ +class JS2StringElement { +public: + + JS2StringElement(uint16 length) : length(length), chars(new jschar[length]) { } + + JS2StringElement(uint16 length, jschar *source) : length(length), chars(new jschar[length]) { for (uint16 i = 0; i < length; i++) chars[i] = source[i]; } + + uint16 getLength() const { return length; } + jschar *getChars() const { return chars; } + + + void insert(uint16 index, uint16 length, jschar *text) + { + for (uint16 i = 0; i < length; i++, index++) + chars[index] = text[i]; + } + +private: + uint16 length; + jschar *chars; + +}; + + +class JS2String { +public: + + JS2String(uint16 length, jschar *text) : count(1), contents[0] = new JS2StringElement(length, text) { } + + + JS2String(const JS2String &a, const JS2String &b) + { + count = a.getCount() + b.getCount(); + if (count <= 4) { + uint16 i; + for (i = 0; i < a.getCount(); i++) + contents[i] = a.contents[i]; + for (uint16 j = 0; j < b.getCount(); j++, i++) + contents[i] = b.contents[j]; + } + else { + count = 1; + contents[0] = new JS2StringElement(a.getLength() + b.getLength()); + uint16 i; + uint16 index = 0; + for (i = 0; i < a.getCount(); i++) { + contents[0]->insert(index, a.contents[i]->getLength(), a.contents[i]->getChars()); + index += a.contents[i]->getLength(); + } + for (i = 0; i < b.getCount(); i++) { + contents[0]->insert(index, b.contents[i]->getLength(), b.contents[i]->getChars()); + index += b.contents[i]->getLength() + } + } + } + + void add(const JS2String &a) + { + ASSERT((count + a.count) <= 4); + for (uint16 i = 0; i < a.count; i++, count++) + contents[count] = a.contents[i]; + } + + uint16 getCount() const { return count; } + + uint16 getLength() const { uint16 t = 0; for (uint16 i = 0; i < count; i++) t += contents[i]->getLength(); return t; } + + void collapse() + { + if (count > 1) { + JS2StringElement *t = new JS2StringElement(getLength()); + for (uint16 i = 0; i < count; i++) { + t->insert(index, contents[i]->getLength(), contents[i]->getChars()); + index += contents[i]->getLength(); + } + count = 1; + contents[0] = t; + } + } + + jschar *getChars() { collapse(); return contents[0]->getChars(); } + +private: + uint16 count; + JS2StringElement *contents[4]; + +}; + + +JS2String &operator +(const JS2String &a, const JS2String &b) { return JS2String(a, b); } +JS2String &operator +=(const JS2String &a, const JS2String &b) +{ + if ((a.getCount() + b.getCount) <= 4) { + a.add(b); + return a; + } + else + return JS2String(a, b); +}