From 5acd2ebc452f0583a60d04228336d62f07e8e604 Mon Sep 17 00:00:00 2001 From: "waldemar%netscape.com" Date: Thu, 3 Feb 2000 08:25:01 +0000 Subject: [PATCH] Updated for VC6 --- js/js2/hash.cpp | 2 +- js/js2/hash.h | 82 ++++++++++++++++++++++++++++--------- js/js2/js2.cpp | 13 ++++-- js/js2/numerics.cpp | 17 ++++---- js/js2/numerics.h | 4 +- js/js2/parser.cpp | 4 +- js/js2/parser.h | 2 +- js/js2/systemtypes.h | 69 +++++++++++++++---------------- js/js2/utilities.cpp | 39 +++++++++++++++++- js/js2/utilities.h | 16 +++++++- js2/src/hash.cpp | 2 +- js2/src/hash.h | 82 ++++++++++++++++++++++++++++--------- js2/src/numerics.cpp | 17 ++++---- js2/src/numerics.h | 4 +- js2/src/parser.cpp | 4 +- js2/src/parser.h | 2 +- js2/src/systemtypes.h | 69 +++++++++++++++---------------- js2/src/utilities.cpp | 39 +++++++++++++++++- js2/src/utilities.h | 16 +++++++- js2/tests/cpp/js2_shell.cpp | 13 ++++-- 20 files changed, 346 insertions(+), 150 deletions(-) diff --git a/js/js2/hash.cpp b/js/js2/hash.cpp index c9c362ecc49..6badca8c1e6 100644 --- a/js/js2/hash.cpp +++ b/js/js2/hash.cpp @@ -17,8 +17,8 @@ // Copyright (C) 1998 Netscape Communications Corporation. All // Rights Reserved. -#include #include "hash.h" +#include namespace JS = JavaScript; diff --git a/js/js2/hash.h b/js/js2/hash.h index 6ee031324d8..ca5cbda5ba7 100644 --- a/js/js2/hash.h +++ b/js/js2/hash.h @@ -47,6 +47,9 @@ namespace JavaScript { } + const HashNumber goldenRatio = 0x9E3779B9U; + + // // Private // @@ -66,6 +69,7 @@ namespace JavaScript { // private + class GenericHashTableIterator; class GenericHashTable { protected: GenericHashEntry **buckets; // Vector of hash buckets @@ -89,21 +93,25 @@ namespace JavaScript { void maybeGrow() {if (nEntries > maxNEntries) rehash();} void maybeShrink() {if (nEntries < minNEntries) rehash();} - class Iterator { - protected: - GenericHashTable &ht; // Hash table being iterated - GenericHashEntry *entry; // Current entry; nil if done - GenericHashEntry **backpointer; // Pointer to pointer to current entry - GenericHashEntry **nextBucket; // Next bucket; pointer past end of vector of hash buckets if done - public: - explicit Iterator(GenericHashTable &ht); - ~Iterator() {ht.maybeShrink(); DEBUG_ONLY(--ht.nReferences);} + friend class GenericHashTableIterator; - operator bool() const {return entry;} // Return true if there are entries left. - Iterator &operator++(); - }; + typedef GenericHashTableIterator Iterator; + }; - friend class Iterator; + // This ought to be GenericHashTable::Iterator, but this doesn't work due to a + // Microsoft VC6 bug. + class GenericHashTableIterator { + protected: + GenericHashTable &ht; // Hash table being iterated + GenericHashEntry *entry; // Current entry; nil if done + GenericHashEntry **backpointer; // Pointer to pointer to current entry + GenericHashEntry **nextBucket; // Next bucket; pointer past end of vector of hash buckets if done + public: + explicit GenericHashTableIterator(GenericHashTable &ht); + ~GenericHashTableIterator() {ht.maybeShrink(); DEBUG_ONLY(--ht.nReferences);} + + operator bool() const {return entry != 0;} // Return true if there are entries left. + GenericHashTableIterator &operator++(); }; @@ -125,6 +133,9 @@ namespace JavaScript { public: class Reference { +#ifdef _WIN32 // Microsoft VC6 bug: friend declarations to inner classes don't work + public: +#endif Entry *entry; // Current entry; nil if done GenericHashEntry **backpointer; // Pointer to pointer to current entry const HashNumber keyHash; // This entry's key's hash value @@ -133,7 +144,25 @@ namespace JavaScript { #endif public: +#ifndef _WIN32 Reference(HashTable &ht, Key key); // Search for an entry with the given key. +#else // Microsoft VC6 bug: VC6 doesn't allow this to be defined outside the class + Reference(HashTable &ht, Key key): keyHash(ht.hasher(key)) { + #ifdef DEBUG + Reference::ht = &ht; + ++ht.nReferences; + #endif + HashNumber kh = keyHash; + HashNumber h = kh*goldenRatio >> ht.shift; + GenericHashEntry **bp = ht.buckets + h; + Entry *e; + + while ((e = static_cast(*bp)) != 0 && !(e->keyHash == kh && e->data == key)) + bp = &e->next; + entry = e; + backpointer = bp; + } +#endif private: Reference(const Reference&); // No copy constructor void operator=(const Reference&); // No assignment operator @@ -142,22 +171,22 @@ namespace JavaScript { ~Reference() {if (ht) --ht->nReferences;} #endif - operator bool() const {return entry;} // Return true if an entry was found. + operator bool() const {return entry != 0;} // Return true if an entry was found. Data &operator*() const {ASSERT(entry); return entry->data;} // Return the data of the entry that was found. friend class HashTable; }; - class Iterator: public GenericHashTable::Iterator { + class Iterator: public GenericHashTableIterator { public: - explicit Iterator(HashTable &ht): GenericHashTable::Iterator(ht) {} + explicit Iterator(HashTable &ht): GenericHashTableIterator(ht) {} private: Iterator(const Iterator&); // No copy constructor void operator=(const Iterator&); // No assignment operator public: // Go to next entry. - Iterator &operator++() {return *static_cast(&GenericHashTable::Iterator::operator++());} + Iterator &operator++() {return *static_cast(&GenericHashTableIterator::operator++());} Data &operator*() const {ASSERT(entry); return static_cast(entry)->data;} // Return current entry's data. void erase(); }; @@ -167,7 +196,6 @@ namespace JavaScript { template Data &insert(Reference &r, Key key, Value value); Data &insert(Reference &r, Key key); - template Data &insert(Key key, Value value); Data &insert(Key key); void erase(Reference &r); void erase(Key key); @@ -175,6 +203,18 @@ namespace JavaScript { friend class Reference; friend class Iterator; + +#ifndef _WIN32 + template Data &insert(Key key, Value value); +#else // Microsoft VC6 bug: VC6 doesn't allow this to be defined outside the class + template Data &insert(Key key, Value value) { + Reference r(*this, key); + if (r) + return *r = value; + else + return insert(r, key, value); + } +#endif }; @@ -197,8 +237,7 @@ namespace JavaScript { } - const HashNumber goldenRatio = 0x9E3779B9U; - +#ifndef _WIN32 template HashTable::Reference::Reference(HashTable &ht, Key key): keyHash(ht.hasher(key)) @@ -237,6 +276,7 @@ namespace JavaScript { #endif return e->data; } +#endif // Same as above but without a Value argument. template @@ -259,6 +299,7 @@ namespace JavaScript { // Insert the given key/value pair into the hash table. If an entry with a // matching key already exists, replace that entry's value. // Return a reference to the new entry's value. +#ifndef _WIN32 // Microsoft VC6 bug: VC6 doesn't allow this to be defined outside the class template template Data &HashTable::insert(Key key, Value value) { @@ -268,6 +309,7 @@ namespace JavaScript { else return insert(r, key, value); } +#endif // Same as above but without a Value argument. template diff --git a/js/js2/js2.cpp b/js/js2/js2.cpp index 984d4002b2f..09abdfe1d37 100644 --- a/js/js2/js2.cpp +++ b/js/js2/js2.cpp @@ -126,7 +126,7 @@ static void initConsole(StringPtr consoleName, const char* startupMessage, int & #endif /* XP_MAC */ -// Interactively read a line from inFile and put it into s. +// Interactively read a line from the input stream in and put it into s. static bool promptLine(istream &in, string &s, const char *prompt) { std::cout << prompt; @@ -134,7 +134,14 @@ static bool promptLine(istream &in, string &s, const char *prompt) /* Print a CR after the prompt because MPW grabs the entire line when entering an interactive command */ std::cout << std::endl; #endif - return getline(in, s); +#ifndef _WIN32 + return std::getline(in, s) != 0; +#else + char buffer[256]; + bool result = fgets(buffer, sizeof(buffer), stdin) != 0; + s = buffer; + return result; +#endif } @@ -166,7 +173,7 @@ static void readEvalPrint(istream &in, World &world) showString(std::cout, e.fullMessage()); } std::cout << std::endl; - buffer.clear(); + clear(buffer); } } std::cout << std::endl; diff --git a/js/js2/numerics.cpp b/js/js2/numerics.cpp index b433e01e998..58d4101334a 100644 --- a/js/js2/numerics.cpp +++ b/js/js2/numerics.cpp @@ -360,7 +360,7 @@ void JS::BigInt::allocate(uint lgGrossSize) FREE_DTOA_LOCK(0); } else { FREE_DTOA_LOCK(0); - w = static_cast(std::malloc(min(grossSize*sizeof(uint32), sizeof(uint32 *)))); + w = static_cast(STD::malloc(max(grossSize*sizeof(uint32), uint32(sizeof(uint32 *))))); if (!w) { std::bad_alloc outOfMemory; throw outOfMemory; @@ -1123,14 +1123,14 @@ double JS::strToDouble(const char *str, const char *&numEnd) goto ret; break; case 'I': - if (!std::strncmp(s+1, "nfinity", 7)) { + if (!STD::strncmp(s+1, "nfinity", 7)) { rv = positiveInfinity; s += 8; goto ret; } break; case 'N': - if (!haveSign && !std::strncmp(s+1, "aN", 2)) { + if (!haveSign && !STD::strncmp(s+1, "aN", 2)) { rv = nan; s += 3; goto ret; @@ -1768,6 +1768,7 @@ double JS::stringToInteger(const char16 *str, const char16 *strEnd, const char16 if (bit == 1) { // Gather the 53 significant bits (including the leading 1) + int bit2; value = 1.0; for (int j = 52; j; --j) { bit = bdr.next(); @@ -1776,7 +1777,7 @@ double JS::stringToInteger(const char16 *str, const char16 *strEnd, const char16 value = value*2 + bit; } // bit2 is the 54th bit (the first dropped from the mantissa) - int bit2 = bdr.next(); + bit2 = bdr.next(); if (bit2 >= 0) { double factor = 2.0; int sticky = 0; // sticky is 1 if any bit beyond the 54th is 1 @@ -1912,7 +1913,7 @@ static char *doubleToAscii(double d, int mode, bool biasUp, int ndigits, // Infinity or NaN *decpt = 9999; s = !word1(d) && !(word0(d) & Frac_mask) ? "Infinity" : "NaN"; - std::strcpy(buf, s); + strcpy(buf, s); return buf[3] ? buf + 8 : buf + 3; } if (!d) { @@ -2515,7 +2516,7 @@ char *JS::doubleToStr(char *buffer, size_t bufferSize, double value, DToStrMode numBegin[0] = numBegin[1]; numBegin[1] = '.'; } - std::sprintf(numEnd, "e%+d", decPt-1); + STD::sprintf(numEnd, "e%+d", decPt-1); } else if (decPt != nDigits) { // Some kind of a fraction in fixed notation ASSERT(decPt <= nDigits); @@ -2590,8 +2591,8 @@ size_t JS::doubleToBaseStr(char *buffer, double value, uint base) // Check for Infinity and NaN if ((word0(value) & Exp_mask) == Exp_mask) { - std::strcpy(p, !word1(value) && !(word0(value) & Frac_mask) ? "Infinity" : "NaN"); - return std::strlen(buffer); + strcpy(p, !word1(value) && !(word0(value) & Frac_mask) ? "Infinity" : "NaN"); + return strlen(buffer); } // Output the integer part of value with the digits in reverse order. diff --git a/js/js2/numerics.h b/js/js2/numerics.h index c8fd6c31157..b8709e9c0d8 100644 --- a/js/js2/numerics.h +++ b/js/js2/numerics.h @@ -24,6 +24,7 @@ #include // Use platform-defined floating-point routines. On platforms with faulty floating-point code // ifdef these out and replace by custom implementations. +#ifndef _WIN32 // Microsoft VC6 bug: standard identifiers should be in std namespace using std::abs; using std::floor; using std::ceil; @@ -34,6 +35,7 @@ using std::tan; using std::asin; using std::acos; using std::atan; +#endif namespace JavaScript { @@ -53,7 +55,7 @@ namespace JavaScript { int hi0bits(uint32 x); class BigInt { - static const int maxLgGrossSize = 15; // Maximum value of lg2(grossSize) + enum {maxLgGrossSize = 15}; // Maximum value of lg2(grossSize) static uint32 *freeLists[maxLgGrossSize+1]; uint lgGrossSize; // lg2(grossSize) diff --git a/js/js2/parser.cpp b/js/js2/parser.cpp index a74aa74dd7a..e72415fbb23 100644 --- a/js/js2/parser.cpp +++ b/js/js2/parser.cpp @@ -151,7 +151,7 @@ JS::String JS::StringReader::sourceFile() const // -static const char *const JS::Token::kindNames[] = { +const char *const JS::Token::kindNames[] = { // Special "[End]", // Token::End "[Identifier]", // Token::Id @@ -676,7 +676,7 @@ void JS::Lexer::lexRegExp() syntaxError("Unterminated regular expression literal"); if (prevCh == '\\') { reader.recordChar(char16orEOFToChar16(ch)); - prevCh = 0; // Ignore slashes and backslashes immediately after a \ + prevCh = 0; // Ignore slashes and backslashes immediately after a backslash } else if (ch != '/') { reader.recordChar(char16orEOFToChar16(ch)); prevCh = ch; diff --git a/js/js2/parser.h b/js/js2/parser.h index c3fb9c08846..a078af9143d 100644 --- a/js/js2/parser.h +++ b/js/js2/parser.h @@ -313,7 +313,7 @@ namespace JavaScript { class Lexer { - static const int tokenBufferSize = 3; // Token lookahead buffer size + enum {tokenBufferSize = 3}; // Token lookahead buffer size public: Reader &reader; World &world; diff --git a/js/js2/systemtypes.h b/js/js2/systemtypes.h index 5772851aadd..bbe7ef75710 100644 --- a/js/js2/systemtypes.h +++ b/js/js2/systemtypes.h @@ -22,43 +22,33 @@ #include +#ifdef _WIN32 + // Turn off warnings about identifiers too long in browser information + #pragma warning(disable: 4786) +#endif + // Define int8, int16, int32, int64, uint8, uint16, uint32, uint64, and uint. -#ifdef XP_BEOS - #include +typedef unsigned int uint; +typedef unsigned char uchar; + +typedef signed char int8; +typedef unsigned char uint8; +typedef short int16; +typedef unsigned short uint16; +#if !defined(XP_MAC) && !defined(_WIN32) + typedef int int32; + typedef unsigned int uint32; #else - #ifdef XP_UNIX - #include - #else - typedef unsigned int uint; - typedef unsigned char uchar; - #endif + typedef long int32; + typedef unsigned long uint32; +#endif +#ifdef _WIN32 + typedef __int64 int64; + typedef unsigned __int64 uint64; +#else + typedef long long int64; typedef unsigned long long uint64; - #if !defined(XP_MAC) && !defined(_WIN32) && !defined(XP_OS2) - typedef unsigned int uint32; - #else - typedef unsigned long uint32; - #endif - typedef unsigned short uint16; - typedef unsigned char uint8; - #ifdef AIX4_3 - #include - #else - typedef long long int64; - #ifdef HPUX - #include - #else - #if !defined(WIN32) || !defined(_WINSOCK2API_) /* defines its own "int32" */ - #if !defined(XP_MAC) && !defined(_WIN32) && !defined(XP_OS2) - typedef int int32; - #else - typedef long int32; - #endif - #endif - typedef short int16; - typedef signed char int8; - #endif /* HPUX */ - #endif /* AIX4_3 */ -#endif /* XP_BEOS */ +#endif // Define this if the machine natively supports 64-bit integers #define NATIVE_INT64 @@ -72,6 +62,13 @@ typedef float float32; // Note that in C++ wchar_t is a distinct type rather than a typedef for some integral type. // Like char, a char16 can be either signed or unsigned at the implementation's discretion. typedef wchar_t char16; -typedef unsigned wchar_t uchar16; - +#ifndef _WIN32 // Microsoft VC6 bug: wchar_t should be a built-in type, not a typedef + typedef unsigned wchar_t uchar16; +#else + typedef wchar_t uchar16; +#endif + +#ifdef _WIN32 + #define IS_LITTLE_ENDIAN +#endif #endif diff --git a/js/js2/utilities.cpp b/js/js2/utilities.cpp index 45d32802571..62889511047 100644 --- a/js/js2/utilities.cpp +++ b/js/js2/utilities.cpp @@ -161,11 +161,33 @@ uint JS::floorLog2(uint32 n) // +#ifdef _WIN32 // Microsoft VC6 bug: String constructor and append limited to char16 iterators +// Return a String containing the characters of the null-terminated C string cstr +// (without the trailing null). +JS::String JS::widenCString(const char *cstr) +{ + size_t len = strlen(cstr); + String s(len, uni::null); + std::transform(cstr, cstr+len, s.begin(), widen); + return s; +} + + +// Widen and append length characters starting at chars to the end of str. +void JS::appendChars(String &str, const char *chars, size_t length) +{ + String::size_type strLen = str.size(); + str.append(length, uni::null); + std::transform(chars, chars+length, str.begin()+strLen, widen); +} +#endif + + // Widen and append the null-terminated string cstr to the end of str. // Return str. JS::String &JS::operator+=(String &str, const char *cstr) { - appendChars(str, cstr, std::strlen(cstr)); + appendChars(str, cstr, strlen(cstr)); return str; } @@ -1581,6 +1603,7 @@ JS::String JS::Exception::fullMessage() const // +#ifndef _WIN32 static void jsNewHandler() { std::bad_alloc outOfMemory; @@ -1592,4 +1615,18 @@ struct InitUtilities { InitUtilities() {std::set_new_handler(&jsNewHandler);} }; +#else +#include +static int jsNewHandler(size_t) +{ + std::bad_alloc outOfMemory; + throw outOfMemory; +} + + +struct InitUtilities +{ + InitUtilities() {_set_new_handler(&jsNewHandler);} +}; +#endif InitUtilities initUtilities; diff --git a/js/js2/utilities.h b/js/js2/utilities.h index d86031302a3..d5d5e2bc08e 100644 --- a/js/js2/utilities.h +++ b/js/js2/utilities.h @@ -20,13 +20,20 @@ #ifndef utilities_h #define utilities_h +#include "systemtypes.h" #include #include #include -#include "systemtypes.h" +#ifndef _WIN32 // Microsoft VC6 bug: standard identifiers should be in std namespace using std::size_t; using std::ptrdiff_t; +using std::strlen; +using std::strcpy; +#define STD std +#else +#define STD +#endif using std::string; using std::istream; using std::ostream; @@ -102,11 +109,12 @@ namespace JavaScript { inline char16 widen(char ch) {return static_cast(static_cast(ch));} +#ifndef _WIN32 // Return a String containing the characters of the null-terminated C string cstr // (without the trailing null). inline String widenCString(const char *cstr) { - size_t len = std::strlen(cstr); + size_t len = strlen(cstr); const uchar *ucstr = reinterpret_cast(cstr); return String(ucstr, ucstr+len); } @@ -118,6 +126,10 @@ namespace JavaScript { const uchar *uchars = reinterpret_cast(chars); str.append(uchars, uchars + length); } +#else // Microsoft VC6 bug: String constructor and append limited to char16 iterators + String widenCString(const char *cstr); + void appendChars(String &str, const char *chars, size_t length); +#endif String &operator+=(String &str, const char *cstr); diff --git a/js2/src/hash.cpp b/js2/src/hash.cpp index c9c362ecc49..6badca8c1e6 100644 --- a/js2/src/hash.cpp +++ b/js2/src/hash.cpp @@ -17,8 +17,8 @@ // Copyright (C) 1998 Netscape Communications Corporation. All // Rights Reserved. -#include #include "hash.h" +#include namespace JS = JavaScript; diff --git a/js2/src/hash.h b/js2/src/hash.h index 6ee031324d8..ca5cbda5ba7 100644 --- a/js2/src/hash.h +++ b/js2/src/hash.h @@ -47,6 +47,9 @@ namespace JavaScript { } + const HashNumber goldenRatio = 0x9E3779B9U; + + // // Private // @@ -66,6 +69,7 @@ namespace JavaScript { // private + class GenericHashTableIterator; class GenericHashTable { protected: GenericHashEntry **buckets; // Vector of hash buckets @@ -89,21 +93,25 @@ namespace JavaScript { void maybeGrow() {if (nEntries > maxNEntries) rehash();} void maybeShrink() {if (nEntries < minNEntries) rehash();} - class Iterator { - protected: - GenericHashTable &ht; // Hash table being iterated - GenericHashEntry *entry; // Current entry; nil if done - GenericHashEntry **backpointer; // Pointer to pointer to current entry - GenericHashEntry **nextBucket; // Next bucket; pointer past end of vector of hash buckets if done - public: - explicit Iterator(GenericHashTable &ht); - ~Iterator() {ht.maybeShrink(); DEBUG_ONLY(--ht.nReferences);} + friend class GenericHashTableIterator; - operator bool() const {return entry;} // Return true if there are entries left. - Iterator &operator++(); - }; + typedef GenericHashTableIterator Iterator; + }; - friend class Iterator; + // This ought to be GenericHashTable::Iterator, but this doesn't work due to a + // Microsoft VC6 bug. + class GenericHashTableIterator { + protected: + GenericHashTable &ht; // Hash table being iterated + GenericHashEntry *entry; // Current entry; nil if done + GenericHashEntry **backpointer; // Pointer to pointer to current entry + GenericHashEntry **nextBucket; // Next bucket; pointer past end of vector of hash buckets if done + public: + explicit GenericHashTableIterator(GenericHashTable &ht); + ~GenericHashTableIterator() {ht.maybeShrink(); DEBUG_ONLY(--ht.nReferences);} + + operator bool() const {return entry != 0;} // Return true if there are entries left. + GenericHashTableIterator &operator++(); }; @@ -125,6 +133,9 @@ namespace JavaScript { public: class Reference { +#ifdef _WIN32 // Microsoft VC6 bug: friend declarations to inner classes don't work + public: +#endif Entry *entry; // Current entry; nil if done GenericHashEntry **backpointer; // Pointer to pointer to current entry const HashNumber keyHash; // This entry's key's hash value @@ -133,7 +144,25 @@ namespace JavaScript { #endif public: +#ifndef _WIN32 Reference(HashTable &ht, Key key); // Search for an entry with the given key. +#else // Microsoft VC6 bug: VC6 doesn't allow this to be defined outside the class + Reference(HashTable &ht, Key key): keyHash(ht.hasher(key)) { + #ifdef DEBUG + Reference::ht = &ht; + ++ht.nReferences; + #endif + HashNumber kh = keyHash; + HashNumber h = kh*goldenRatio >> ht.shift; + GenericHashEntry **bp = ht.buckets + h; + Entry *e; + + while ((e = static_cast(*bp)) != 0 && !(e->keyHash == kh && e->data == key)) + bp = &e->next; + entry = e; + backpointer = bp; + } +#endif private: Reference(const Reference&); // No copy constructor void operator=(const Reference&); // No assignment operator @@ -142,22 +171,22 @@ namespace JavaScript { ~Reference() {if (ht) --ht->nReferences;} #endif - operator bool() const {return entry;} // Return true if an entry was found. + operator bool() const {return entry != 0;} // Return true if an entry was found. Data &operator*() const {ASSERT(entry); return entry->data;} // Return the data of the entry that was found. friend class HashTable; }; - class Iterator: public GenericHashTable::Iterator { + class Iterator: public GenericHashTableIterator { public: - explicit Iterator(HashTable &ht): GenericHashTable::Iterator(ht) {} + explicit Iterator(HashTable &ht): GenericHashTableIterator(ht) {} private: Iterator(const Iterator&); // No copy constructor void operator=(const Iterator&); // No assignment operator public: // Go to next entry. - Iterator &operator++() {return *static_cast(&GenericHashTable::Iterator::operator++());} + Iterator &operator++() {return *static_cast(&GenericHashTableIterator::operator++());} Data &operator*() const {ASSERT(entry); return static_cast(entry)->data;} // Return current entry's data. void erase(); }; @@ -167,7 +196,6 @@ namespace JavaScript { template Data &insert(Reference &r, Key key, Value value); Data &insert(Reference &r, Key key); - template Data &insert(Key key, Value value); Data &insert(Key key); void erase(Reference &r); void erase(Key key); @@ -175,6 +203,18 @@ namespace JavaScript { friend class Reference; friend class Iterator; + +#ifndef _WIN32 + template Data &insert(Key key, Value value); +#else // Microsoft VC6 bug: VC6 doesn't allow this to be defined outside the class + template Data &insert(Key key, Value value) { + Reference r(*this, key); + if (r) + return *r = value; + else + return insert(r, key, value); + } +#endif }; @@ -197,8 +237,7 @@ namespace JavaScript { } - const HashNumber goldenRatio = 0x9E3779B9U; - +#ifndef _WIN32 template HashTable::Reference::Reference(HashTable &ht, Key key): keyHash(ht.hasher(key)) @@ -237,6 +276,7 @@ namespace JavaScript { #endif return e->data; } +#endif // Same as above but without a Value argument. template @@ -259,6 +299,7 @@ namespace JavaScript { // Insert the given key/value pair into the hash table. If an entry with a // matching key already exists, replace that entry's value. // Return a reference to the new entry's value. +#ifndef _WIN32 // Microsoft VC6 bug: VC6 doesn't allow this to be defined outside the class template template Data &HashTable::insert(Key key, Value value) { @@ -268,6 +309,7 @@ namespace JavaScript { else return insert(r, key, value); } +#endif // Same as above but without a Value argument. template diff --git a/js2/src/numerics.cpp b/js2/src/numerics.cpp index b433e01e998..58d4101334a 100644 --- a/js2/src/numerics.cpp +++ b/js2/src/numerics.cpp @@ -360,7 +360,7 @@ void JS::BigInt::allocate(uint lgGrossSize) FREE_DTOA_LOCK(0); } else { FREE_DTOA_LOCK(0); - w = static_cast(std::malloc(min(grossSize*sizeof(uint32), sizeof(uint32 *)))); + w = static_cast(STD::malloc(max(grossSize*sizeof(uint32), uint32(sizeof(uint32 *))))); if (!w) { std::bad_alloc outOfMemory; throw outOfMemory; @@ -1123,14 +1123,14 @@ double JS::strToDouble(const char *str, const char *&numEnd) goto ret; break; case 'I': - if (!std::strncmp(s+1, "nfinity", 7)) { + if (!STD::strncmp(s+1, "nfinity", 7)) { rv = positiveInfinity; s += 8; goto ret; } break; case 'N': - if (!haveSign && !std::strncmp(s+1, "aN", 2)) { + if (!haveSign && !STD::strncmp(s+1, "aN", 2)) { rv = nan; s += 3; goto ret; @@ -1768,6 +1768,7 @@ double JS::stringToInteger(const char16 *str, const char16 *strEnd, const char16 if (bit == 1) { // Gather the 53 significant bits (including the leading 1) + int bit2; value = 1.0; for (int j = 52; j; --j) { bit = bdr.next(); @@ -1776,7 +1777,7 @@ double JS::stringToInteger(const char16 *str, const char16 *strEnd, const char16 value = value*2 + bit; } // bit2 is the 54th bit (the first dropped from the mantissa) - int bit2 = bdr.next(); + bit2 = bdr.next(); if (bit2 >= 0) { double factor = 2.0; int sticky = 0; // sticky is 1 if any bit beyond the 54th is 1 @@ -1912,7 +1913,7 @@ static char *doubleToAscii(double d, int mode, bool biasUp, int ndigits, // Infinity or NaN *decpt = 9999; s = !word1(d) && !(word0(d) & Frac_mask) ? "Infinity" : "NaN"; - std::strcpy(buf, s); + strcpy(buf, s); return buf[3] ? buf + 8 : buf + 3; } if (!d) { @@ -2515,7 +2516,7 @@ char *JS::doubleToStr(char *buffer, size_t bufferSize, double value, DToStrMode numBegin[0] = numBegin[1]; numBegin[1] = '.'; } - std::sprintf(numEnd, "e%+d", decPt-1); + STD::sprintf(numEnd, "e%+d", decPt-1); } else if (decPt != nDigits) { // Some kind of a fraction in fixed notation ASSERT(decPt <= nDigits); @@ -2590,8 +2591,8 @@ size_t JS::doubleToBaseStr(char *buffer, double value, uint base) // Check for Infinity and NaN if ((word0(value) & Exp_mask) == Exp_mask) { - std::strcpy(p, !word1(value) && !(word0(value) & Frac_mask) ? "Infinity" : "NaN"); - return std::strlen(buffer); + strcpy(p, !word1(value) && !(word0(value) & Frac_mask) ? "Infinity" : "NaN"); + return strlen(buffer); } // Output the integer part of value with the digits in reverse order. diff --git a/js2/src/numerics.h b/js2/src/numerics.h index c8fd6c31157..b8709e9c0d8 100644 --- a/js2/src/numerics.h +++ b/js2/src/numerics.h @@ -24,6 +24,7 @@ #include // Use platform-defined floating-point routines. On platforms with faulty floating-point code // ifdef these out and replace by custom implementations. +#ifndef _WIN32 // Microsoft VC6 bug: standard identifiers should be in std namespace using std::abs; using std::floor; using std::ceil; @@ -34,6 +35,7 @@ using std::tan; using std::asin; using std::acos; using std::atan; +#endif namespace JavaScript { @@ -53,7 +55,7 @@ namespace JavaScript { int hi0bits(uint32 x); class BigInt { - static const int maxLgGrossSize = 15; // Maximum value of lg2(grossSize) + enum {maxLgGrossSize = 15}; // Maximum value of lg2(grossSize) static uint32 *freeLists[maxLgGrossSize+1]; uint lgGrossSize; // lg2(grossSize) diff --git a/js2/src/parser.cpp b/js2/src/parser.cpp index a74aa74dd7a..e72415fbb23 100644 --- a/js2/src/parser.cpp +++ b/js2/src/parser.cpp @@ -151,7 +151,7 @@ JS::String JS::StringReader::sourceFile() const // -static const char *const JS::Token::kindNames[] = { +const char *const JS::Token::kindNames[] = { // Special "[End]", // Token::End "[Identifier]", // Token::Id @@ -676,7 +676,7 @@ void JS::Lexer::lexRegExp() syntaxError("Unterminated regular expression literal"); if (prevCh == '\\') { reader.recordChar(char16orEOFToChar16(ch)); - prevCh = 0; // Ignore slashes and backslashes immediately after a \ + prevCh = 0; // Ignore slashes and backslashes immediately after a backslash } else if (ch != '/') { reader.recordChar(char16orEOFToChar16(ch)); prevCh = ch; diff --git a/js2/src/parser.h b/js2/src/parser.h index c3fb9c08846..a078af9143d 100644 --- a/js2/src/parser.h +++ b/js2/src/parser.h @@ -313,7 +313,7 @@ namespace JavaScript { class Lexer { - static const int tokenBufferSize = 3; // Token lookahead buffer size + enum {tokenBufferSize = 3}; // Token lookahead buffer size public: Reader &reader; World &world; diff --git a/js2/src/systemtypes.h b/js2/src/systemtypes.h index 5772851aadd..bbe7ef75710 100644 --- a/js2/src/systemtypes.h +++ b/js2/src/systemtypes.h @@ -22,43 +22,33 @@ #include +#ifdef _WIN32 + // Turn off warnings about identifiers too long in browser information + #pragma warning(disable: 4786) +#endif + // Define int8, int16, int32, int64, uint8, uint16, uint32, uint64, and uint. -#ifdef XP_BEOS - #include +typedef unsigned int uint; +typedef unsigned char uchar; + +typedef signed char int8; +typedef unsigned char uint8; +typedef short int16; +typedef unsigned short uint16; +#if !defined(XP_MAC) && !defined(_WIN32) + typedef int int32; + typedef unsigned int uint32; #else - #ifdef XP_UNIX - #include - #else - typedef unsigned int uint; - typedef unsigned char uchar; - #endif + typedef long int32; + typedef unsigned long uint32; +#endif +#ifdef _WIN32 + typedef __int64 int64; + typedef unsigned __int64 uint64; +#else + typedef long long int64; typedef unsigned long long uint64; - #if !defined(XP_MAC) && !defined(_WIN32) && !defined(XP_OS2) - typedef unsigned int uint32; - #else - typedef unsigned long uint32; - #endif - typedef unsigned short uint16; - typedef unsigned char uint8; - #ifdef AIX4_3 - #include - #else - typedef long long int64; - #ifdef HPUX - #include - #else - #if !defined(WIN32) || !defined(_WINSOCK2API_) /* defines its own "int32" */ - #if !defined(XP_MAC) && !defined(_WIN32) && !defined(XP_OS2) - typedef int int32; - #else - typedef long int32; - #endif - #endif - typedef short int16; - typedef signed char int8; - #endif /* HPUX */ - #endif /* AIX4_3 */ -#endif /* XP_BEOS */ +#endif // Define this if the machine natively supports 64-bit integers #define NATIVE_INT64 @@ -72,6 +62,13 @@ typedef float float32; // Note that in C++ wchar_t is a distinct type rather than a typedef for some integral type. // Like char, a char16 can be either signed or unsigned at the implementation's discretion. typedef wchar_t char16; -typedef unsigned wchar_t uchar16; - +#ifndef _WIN32 // Microsoft VC6 bug: wchar_t should be a built-in type, not a typedef + typedef unsigned wchar_t uchar16; +#else + typedef wchar_t uchar16; +#endif + +#ifdef _WIN32 + #define IS_LITTLE_ENDIAN +#endif #endif diff --git a/js2/src/utilities.cpp b/js2/src/utilities.cpp index 45d32802571..62889511047 100644 --- a/js2/src/utilities.cpp +++ b/js2/src/utilities.cpp @@ -161,11 +161,33 @@ uint JS::floorLog2(uint32 n) // +#ifdef _WIN32 // Microsoft VC6 bug: String constructor and append limited to char16 iterators +// Return a String containing the characters of the null-terminated C string cstr +// (without the trailing null). +JS::String JS::widenCString(const char *cstr) +{ + size_t len = strlen(cstr); + String s(len, uni::null); + std::transform(cstr, cstr+len, s.begin(), widen); + return s; +} + + +// Widen and append length characters starting at chars to the end of str. +void JS::appendChars(String &str, const char *chars, size_t length) +{ + String::size_type strLen = str.size(); + str.append(length, uni::null); + std::transform(chars, chars+length, str.begin()+strLen, widen); +} +#endif + + // Widen and append the null-terminated string cstr to the end of str. // Return str. JS::String &JS::operator+=(String &str, const char *cstr) { - appendChars(str, cstr, std::strlen(cstr)); + appendChars(str, cstr, strlen(cstr)); return str; } @@ -1581,6 +1603,7 @@ JS::String JS::Exception::fullMessage() const // +#ifndef _WIN32 static void jsNewHandler() { std::bad_alloc outOfMemory; @@ -1592,4 +1615,18 @@ struct InitUtilities { InitUtilities() {std::set_new_handler(&jsNewHandler);} }; +#else +#include +static int jsNewHandler(size_t) +{ + std::bad_alloc outOfMemory; + throw outOfMemory; +} + + +struct InitUtilities +{ + InitUtilities() {_set_new_handler(&jsNewHandler);} +}; +#endif InitUtilities initUtilities; diff --git a/js2/src/utilities.h b/js2/src/utilities.h index d86031302a3..d5d5e2bc08e 100644 --- a/js2/src/utilities.h +++ b/js2/src/utilities.h @@ -20,13 +20,20 @@ #ifndef utilities_h #define utilities_h +#include "systemtypes.h" #include #include #include -#include "systemtypes.h" +#ifndef _WIN32 // Microsoft VC6 bug: standard identifiers should be in std namespace using std::size_t; using std::ptrdiff_t; +using std::strlen; +using std::strcpy; +#define STD std +#else +#define STD +#endif using std::string; using std::istream; using std::ostream; @@ -102,11 +109,12 @@ namespace JavaScript { inline char16 widen(char ch) {return static_cast(static_cast(ch));} +#ifndef _WIN32 // Return a String containing the characters of the null-terminated C string cstr // (without the trailing null). inline String widenCString(const char *cstr) { - size_t len = std::strlen(cstr); + size_t len = strlen(cstr); const uchar *ucstr = reinterpret_cast(cstr); return String(ucstr, ucstr+len); } @@ -118,6 +126,10 @@ namespace JavaScript { const uchar *uchars = reinterpret_cast(chars); str.append(uchars, uchars + length); } +#else // Microsoft VC6 bug: String constructor and append limited to char16 iterators + String widenCString(const char *cstr); + void appendChars(String &str, const char *chars, size_t length); +#endif String &operator+=(String &str, const char *cstr); diff --git a/js2/tests/cpp/js2_shell.cpp b/js2/tests/cpp/js2_shell.cpp index 984d4002b2f..09abdfe1d37 100644 --- a/js2/tests/cpp/js2_shell.cpp +++ b/js2/tests/cpp/js2_shell.cpp @@ -126,7 +126,7 @@ static void initConsole(StringPtr consoleName, const char* startupMessage, int & #endif /* XP_MAC */ -// Interactively read a line from inFile and put it into s. +// Interactively read a line from the input stream in and put it into s. static bool promptLine(istream &in, string &s, const char *prompt) { std::cout << prompt; @@ -134,7 +134,14 @@ static bool promptLine(istream &in, string &s, const char *prompt) /* Print a CR after the prompt because MPW grabs the entire line when entering an interactive command */ std::cout << std::endl; #endif - return getline(in, s); +#ifndef _WIN32 + return std::getline(in, s) != 0; +#else + char buffer[256]; + bool result = fgets(buffer, sizeof(buffer), stdin) != 0; + s = buffer; + return result; +#endif } @@ -166,7 +173,7 @@ static void readEvalPrint(istream &in, World &world) showString(std::cout, e.fullMessage()); } std::cout << std::endl; - buffer.clear(); + clear(buffer); } } std::cout << std::endl;