Changeset 181497 in webkit
- Timestamp:
- Mar 14, 2015, 9:29:20 AM (11 years ago)
- Location:
- trunk
- Files:
-
- 6 added
- 8 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/js/binary-literals-expected.txt (added)
-
LayoutTests/js/binary-literals.html (added)
-
LayoutTests/js/octal-literals-expected.txt (added)
-
LayoutTests/js/octal-literals.html (added)
-
LayoutTests/js/script-tests/binary-literals.js (added)
-
LayoutTests/js/script-tests/octal-literals.js (added)
-
Source/JavaScriptCore/ChangeLog (modified) (1 diff)
-
Source/JavaScriptCore/parser/Lexer.cpp (modified) (4 diffs)
-
Source/JavaScriptCore/parser/Lexer.h (modified) (1 diff)
-
Source/JavaScriptCore/parser/ParserTokens.h (modified) (1 diff)
-
Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp (modified) (4 diffs)
-
Source/WTF/ChangeLog (modified) (1 diff)
-
Source/WTF/wtf/ASCIICType.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r181490 r181497 1 2015-03-14 Michael Saboff <msaboff@apple.com> 2 3 ES6: Add binary and octal literal support 4 https://bugs.webkit.org/show_bug.cgi?id=142681 5 6 Reviewed by Ryosuke Niwa. 7 8 New tests. 9 10 * js/binary-literals-expected.txt: Added. 11 * js/binary-literals.html: Added. 12 * js/octal-literals-expected.txt: Added. 13 * js/octal-literals.html: Added. 14 * js/script-tests/binary-literals.js: Added. 15 * js/script-tests/octal-literals.js: Added. 16 1 17 2015-03-13 Ryosuke Niwa <rniwa@webkit.org> 2 18 -
trunk/Source/JavaScriptCore/ChangeLog
r181496 r181497 1 2015-03-14 Michael Saboff <msaboff@apple.com> 2 3 ES6: Add binary and octal literal support 4 https://bugs.webkit.org/show_bug.cgi?id=142681 5 6 Reviewed by Ryosuke Niwa. 7 8 Added a binary literal parser function, parseBinary(), to Lexer patterned after the octal parser. 9 Refactored the parseBinary, parseOctal and parseDecimal to use a constant size for the number of 10 characters to try and handle directly. Factored out the shifting past any prefix to be handled by 11 the caller. Added binary and octal parsing to toDouble() via helper functions. 12 13 * parser/Lexer.cpp: 14 (JSC::Lexer<T>::parseHex): 15 (JSC::Lexer<T>::parseBinary): 16 (JSC::Lexer<T>::parseOctal): 17 (JSC::Lexer<T>::parseDecimal): 18 (JSC::Lexer<T>::lex): 19 * parser/Lexer.h: 20 * parser/ParserTokens.h: 21 * runtime/JSGlobalObjectFunctions.cpp: 22 (JSC::jsBinaryIntegerLiteral): 23 (JSC::jsOctalIntegerLiteral): 24 (JSC::toDouble): 25 1 26 2015-03-13 Alex Christensen <achristensen@webkit.org> 2 27 -
trunk/Source/JavaScriptCore/parser/Lexer.cpp
r180813 r181497 1223 1223 int maximumDigits = 7; 1224 1224 1225 // Shift out the 'x' prefix.1226 shift();1227 1228 1225 do { 1229 1226 hexValue = (hexValue << 4) + toASCIIHexValue(m_current); … … 1257 1254 1258 1255 template <typename T> 1256 ALWAYS_INLINE bool Lexer<T>::parseBinary(double& returnValue) 1257 { 1258 // Optimization: most binary values fit into 4 bytes. 1259 uint32_t binaryValue = 0; 1260 const unsigned maximumDigits = 32; 1261 int digit = maximumDigits - 1; 1262 // Temporary buffer for the digits. Makes easier 1263 // to reconstruct the input characters when needed. 1264 LChar digits[maximumDigits]; 1265 1266 do { 1267 binaryValue = (binaryValue << 1) + (m_current - '0'); 1268 digits[digit] = m_current; 1269 shift(); 1270 --digit; 1271 } while (isASCIIBinaryDigit(m_current) && digit >= 0); 1272 1273 if (!isASCIIDigit(m_current) && digit >= 0) { 1274 returnValue = binaryValue; 1275 return true; 1276 } 1277 1278 for (int i = maximumDigits - 1; i > digit; --i) 1279 record8(digits[i]); 1280 1281 while (isASCIIBinaryDigit(m_current)) { 1282 record8(m_current); 1283 shift(); 1284 } 1285 1286 if (isASCIIDigit(m_current)) 1287 return false; 1288 1289 returnValue = parseIntOverflow(m_buffer8.data(), m_buffer8.size(), 2); 1290 return true; 1291 } 1292 1293 template <typename T> 1259 1294 ALWAYS_INLINE bool Lexer<T>::parseOctal(double& returnValue) 1260 1295 { 1261 1296 // Optimization: most octal values fit into 4 bytes. 1262 1297 uint32_t octalValue = 0; 1263 int maximumDigits = 9; 1298 const unsigned maximumDigits = 10; 1299 int digit = maximumDigits - 1; 1264 1300 // Temporary buffer for the digits. Makes easier 1265 1301 // to reconstruct the input characters when needed. 1266 LChar digits[ 10];1302 LChar digits[maximumDigits]; 1267 1303 1268 1304 do { 1269 1305 octalValue = octalValue * 8 + (m_current - '0'); 1270 digits[ maximumDigits] = m_current;1271 shift(); 1272 -- maximumDigits;1273 } while (isASCIIOctalDigit(m_current) && maximumDigits>= 0);1274 1275 if (!isASCIIDigit(m_current) && maximumDigits>= 0) {1306 digits[digit] = m_current; 1307 shift(); 1308 --digit; 1309 } while (isASCIIOctalDigit(m_current) && digit >= 0); 1310 1311 if (!isASCIIDigit(m_current) && digit >= 0) { 1276 1312 returnValue = octalValue; 1277 1313 return true; 1278 1314 } 1279 1315 1280 for (int i = 9; i > maximumDigits; --i)1316 for (int i = maximumDigits - 1; i > digit; --i) 1281 1317 record8(digits[i]); 1282 1318 … … 1302 1338 // the m_buffer8 may hold ascii digits. 1303 1339 if (!m_buffer8.size()) { 1304 int maximumDigits = 9; 1340 const unsigned maximumDigits = 10; 1341 int digit = maximumDigits - 1; 1305 1342 // Temporary buffer for the digits. Makes easier 1306 1343 // to reconstruct the input characters when needed. 1307 LChar digits[ 10];1344 LChar digits[maximumDigits]; 1308 1345 1309 1346 do { 1310 1347 decimalValue = decimalValue * 10 + (m_current - '0'); 1311 digits[ maximumDigits] = m_current;1312 shift(); 1313 -- maximumDigits;1314 } while (isASCIIDigit(m_current) && maximumDigits>= 0);1315 1316 if ( maximumDigits>= 0 && m_current != '.' && (m_current | 0x20) != 'e') {1348 digits[digit] = m_current; 1349 shift(); 1350 --digit; 1351 } while (isASCIIDigit(m_current) && digit >= 0); 1352 1353 if (digit >= 0 && m_current != '.' && (m_current | 0x20) != 'e') { 1317 1354 returnValue = decimalValue; 1318 1355 return true; 1319 1356 } 1320 1357 1321 for (int i = 9; i > maximumDigits; --i)1358 for (int i = maximumDigits - 1; i > digit; --i) 1322 1359 record8(digits[i]); 1323 1360 } … … 1689 1726 goto returnError; 1690 1727 } 1728 1729 // Shift out the 'x' prefix. 1730 shift(); 1731 1691 1732 parseHex(tokenData->doubleValue); 1692 1733 if (isIdentStart(m_current)) { 1693 1734 m_lexErrorMessage = ASCIILiteral("No space between hexadecimal literal and identifier"); 1694 1735 token = INVALID_HEX_NUMBER_ERRORTOK; 1736 goto returnError; 1737 } 1738 token = tokenTypeForIntegerLikeToken(tokenData->doubleValue); 1739 m_buffer8.resize(0); 1740 break; 1741 } 1742 if ((m_current | 0x20) == 'b') { 1743 if (!isASCIIBinaryDigit(peek(1))) { 1744 m_lexErrorMessage = ASCIILiteral("No binary digits after '0b'"); 1745 token = INVALID_BINARY_NUMBER_ERRORTOK; 1746 goto returnError; 1747 } 1748 1749 // Shift out the 'b' prefix. 1750 shift(); 1751 1752 parseBinary(tokenData->doubleValue); 1753 if (isIdentStart(m_current)) { 1754 m_lexErrorMessage = ASCIILiteral("No space between binary literal and identifier"); 1755 token = INVALID_BINARY_NUMBER_ERRORTOK; 1756 goto returnError; 1757 } 1758 token = tokenTypeForIntegerLikeToken(tokenData->doubleValue); 1759 m_buffer8.resize(0); 1760 break; 1761 } 1762 1763 if ((m_current | 0x20) == 'o') { 1764 if (!isASCIIOctalDigit(peek(1))) { 1765 m_lexErrorMessage = ASCIILiteral("No octal digits after '0o'"); 1766 token = INVALID_OCTAL_NUMBER_ERRORTOK; 1767 goto returnError; 1768 } 1769 1770 // Shift out the 'o' prefix. 1771 shift(); 1772 1773 parseOctal(tokenData->doubleValue); 1774 if (isIdentStart(m_current)) { 1775 m_lexErrorMessage = ASCIILiteral("No space between octal literal and identifier"); 1776 token = INVALID_OCTAL_NUMBER_ERRORTOK; 1695 1777 goto returnError; 1696 1778 } -
trunk/Source/JavaScriptCore/parser/Lexer.h
r177222 r181497 204 204 template <bool shouldBuildStrings> NEVER_INLINE StringParseResult parseStringSlowCase(JSTokenData*, bool strictMode); 205 205 ALWAYS_INLINE void parseHex(double& returnValue); 206 ALWAYS_INLINE bool parseBinary(double& returnValue); 206 207 ALWAYS_INLINE bool parseOctal(double& returnValue); 207 208 ALWAYS_INLINE bool parseDecimal(double& returnValue); -
trunk/Source/JavaScriptCore/parser/ParserTokens.h
r181419 r181497 161 161 INVALID_STRING_LITERAL_ERRORTOK = 9 | ErrorTokenFlag, 162 162 INVALID_PRIVATE_NAME_ERRORTOK = 10 | ErrorTokenFlag, 163 INVALID_HEX_NUMBER_ERRORTOK = 11 | ErrorTokenFlag 163 INVALID_HEX_NUMBER_ERRORTOK = 11 | ErrorTokenFlag, 164 INVALID_BINARY_NUMBER_ERRORTOK = 12 | ErrorTokenFlag 164 165 }; 165 166 -
trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
r180370 r181497 344 344 } 345 345 346 // See ecma-262 9.3.1 346 // See ecma-262 6th 11.8.3 347 template <typename CharType> 348 static double jsBinaryIntegerLiteral(const CharType*& data, const CharType* end) 349 { 350 // Binary number. 351 data += 2; 352 const CharType* firstDigitPosition = data; 353 double number = 0; 354 while (true) { 355 number = number * 2 + (*data - '0'); 356 ++data; 357 if (data == end) 358 break; 359 if (!isASCIIBinaryDigit(*data)) 360 break; 361 } 362 if (number >= mantissaOverflowLowerBound) 363 number = parseIntOverflow(firstDigitPosition, data - firstDigitPosition, 2); 364 365 return number; 366 } 367 368 // See ecma-262 6th 11.8.3 369 template <typename CharType> 370 static double jsOctalIntegerLiteral(const CharType*& data, const CharType* end) 371 { 372 // Octal number. 373 data += 2; 374 const CharType* firstDigitPosition = data; 375 double number = 0; 376 while (true) { 377 number = number * 8 + (*data - '0'); 378 ++data; 379 if (data == end) 380 break; 381 if (!isASCIIOctalDigit(*data)) 382 break; 383 } 384 if (number >= mantissaOverflowLowerBound) 385 number = parseIntOverflow(firstDigitPosition, data - firstDigitPosition, 8); 386 387 return number; 388 } 389 390 // See ecma-262 6th 11.8.3 347 391 template <typename CharType> 348 392 static double jsHexIntegerLiteral(const CharType*& data, const CharType* end) … … 366 410 } 367 411 368 // See ecma-262 9.3.1412 // See ecma-262 6th 11.8.3 369 413 template <typename CharType> 370 414 static double jsStrDecimalLiteral(const CharType*& data, const CharType* end) … … 423 467 424 468 double number; 425 if (characters[0] == '0' && characters + 2 < endCharacters && (characters[1] | 0x20) == 'x' && isASCIIHexDigit(characters[2])) 426 number = jsHexIntegerLiteral(characters, endCharacters); 427 else 469 if (characters[0] == '0' && characters + 2 < endCharacters) { 470 if ((characters[1] | 0x20) == 'x' && isASCIIHexDigit(characters[2])) 471 number = jsHexIntegerLiteral(characters, endCharacters); 472 else if ((characters[1] | 0x20) == 'o' && isASCIIOctalDigit(characters[2])) 473 number = jsOctalIntegerLiteral(characters, endCharacters); 474 else if ((characters[1] | 0x20) == 'b' && isASCIIBinaryDigit(characters[2])) 475 number = jsBinaryIntegerLiteral(characters, endCharacters); 476 else 477 number = jsStrDecimalLiteral(characters, endCharacters); 478 } else 428 479 number = jsStrDecimalLiteral(characters, endCharacters); 429 480 … … 439 490 } 440 491 441 // See ecma-262 9.3.1492 // See ecma-262 6th 11.8.3 442 493 double jsToNumber(const String& s) 443 494 { -
trunk/Source/WTF/ChangeLog
r181485 r181497 1 2015-03-14 Michael Saboff <msaboff@apple.com> 2 3 ES6: Add binary and octal literal support 4 https://bugs.webkit.org/show_bug.cgi?id=142681 5 6 Reviewed by Ryosuke Niwa. 7 8 * wtf/ASCIICType.h: 9 (WTF::isASCIIBinaryDigit): New support function. 10 (WTF::isASCIIOctalDigit): Updated to use logical and (&&) instead of binary and (&). 11 1 12 2015-03-13 Mark Lam <mark.lam@apple.com> 2 13 -
trunk/Source/WTF/wtf/ASCIICType.h
r165676 r181497 74 74 } 75 75 76 template<typename CharType> inline bool isASCIIBinaryDigit(CharType c) 77 { 78 return (c == '0') || (c == '1'); 79 } 80 76 81 template<typename CharType> inline bool isASCIIOctalDigit(CharType c) 77 82 { 78 return (c >= '0') & (c <= '7');83 return (c >= '0') && (c <= '7'); 79 84 } 80 85 … … 167 172 using WTF::isASCIIHexDigit; 168 173 using WTF::isASCIILower; 174 using WTF::isASCIIBinaryDigit; 169 175 using WTF::isASCIIOctalDigit; 170 176 using WTF::isASCIIPrintable;
Note:
See TracChangeset
for help on using the changeset viewer.