Changeset 89192 in webkit for trunk/Source/JavaScriptCore/runtime/LiteralParser.cpp
- Timestamp:
- Jun 18, 2011, 1:47:10 AM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/runtime/LiteralParser.cpp
r89184 r89192 43 43 } 44 44 45 bool LiteralParser::tryJSONPParse(Vector<JSONPData>& results) 46 { 47 if (m_lexer.next() != TokIdentifier) 48 return false; 49 do { 50 Vector<JSONPPathEntry> path; 51 // Unguarded next to start off the lexer 52 Identifier name = Identifier(m_exec, m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start); 53 JSONPPathEntry entry; 54 if (name == m_exec->globalData().propertyNames->varKeyword) { 55 if (m_lexer.next() != TokIdentifier) 56 return false; 57 entry.m_type = JSONPPathEntryTypeDeclare; 58 entry.m_pathEntryName = Identifier(m_exec, m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start); 59 path.append(entry); 60 } else { 61 entry.m_type = JSONPPathEntryTypeDot; 62 entry.m_pathEntryName = Identifier(m_exec, m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start); 63 path.append(entry); 64 } 65 if (m_exec->globalData().lexer->isKeyword(entry.m_pathEntryName)) 66 return false; 67 TokenType tokenType = m_lexer.next(); 68 while (tokenType != TokAssign) { 69 switch (tokenType) { 70 case TokLBracket: { 71 entry.m_type = JSONPPathEntryTypeLookup; 72 if (m_lexer.next() != TokNumber) 73 return false; 74 double doubleIndex = m_lexer.currentToken().numberToken; 75 int index = (int)doubleIndex; 76 if (index != doubleIndex || index < 0) 77 return false; 78 entry.m_pathIndex = index; 79 if (m_lexer.next() != TokRBracket) 80 return false; 81 break; 82 } 83 case TokDot: { 84 entry.m_type = JSONPPathEntryTypeDot; 85 if (m_lexer.next() != TokIdentifier) 86 return false; 87 entry.m_pathEntryName = Identifier(m_exec, m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start); 88 break; 89 } 90 default: 91 return false; 92 } 93 path.append(entry); 94 tokenType = m_lexer.next(); 95 } 96 m_lexer.next(); 97 results.append(JSONPData()); 98 results.last().m_value.set(m_exec->globalData(), parse(StartParseExpression)); 99 if (!results.last().m_value) 100 return false; 101 results.last().m_path.swap(path); 102 if (m_lexer.currentToken().type != TokSemi) 103 break; 104 m_lexer.next(); 105 } while (m_lexer.currentToken().type == TokIdentifier); 106 return m_lexer.currentToken().type == TokEnd; 107 } 108 109 ALWAYS_INLINE const Identifier LiteralParser::makeIdentifier(const UChar* characters, size_t length) 110 { 111 if (!length) 112 return m_exec->globalData().propertyNames->emptyIdentifier; 113 if (characters[0] >= MaximumCachableCharacter) 114 return Identifier(&m_exec->globalData(), characters, length); 115 116 if (length == 1) { 117 if (!m_shortIdentifiers[characters[0]].isNull()) 118 return m_shortIdentifiers[characters[0]]; 119 m_shortIdentifiers[characters[0]] = Identifier(&m_exec->globalData(), characters, length); 120 return m_shortIdentifiers[characters[0]]; 121 } 122 if (!m_recentIdentifiers[characters[0]].isNull() && Identifier::equal(m_recentIdentifiers[characters[0]].impl(), characters, length)) 123 return m_recentIdentifiers[characters[0]]; 124 m_recentIdentifiers[characters[0]] = Identifier(&m_exec->globalData(), characters, length); 125 return m_recentIdentifiers[characters[0]]; 126 } 127 128 template <LiteralParser::ParserMode mode> LiteralParser::TokenType LiteralParser::Lexer::lex(LiteralParserToken& token) 45 LiteralParser::TokenType LiteralParser::Lexer::lex(LiteralParserToken& token) 129 46 { 130 47 while (m_ptr < m_end && isJSONWhiteSpace(*m_ptr)) … … 173 90 return TokColon; 174 91 case '"': 175 return lexString<mode, '"'>(token); 92 if (m_mode == StrictJSON) 93 return lexString<StrictJSON>(token); 94 return lexString<NonStrictJSON>(token); 176 95 case 't': 177 96 if (m_end - m_ptr >= 4 && m_ptr[1] == 'r' && m_ptr[2] == 'u' && m_ptr[3] == 'e') { … … 197 116 return TokNull; 198 117 } 199 break; 118 break; 200 119 case '-': 201 120 case '0': … … 211 130 return lexNumber(token); 212 131 } 213 if (m_ptr < m_end) {214 if (*m_ptr == '.') {215 token.type = TokDot;216 token.end = ++m_ptr;217 return TokDot;218 }219 if (*m_ptr == '=') {220 token.type = TokAssign;221 token.end = ++m_ptr;222 return TokAssign;223 }224 if (*m_ptr == ';') {225 token.type = TokSemi;226 token.end = ++m_ptr;227 return TokAssign;228 }229 if (isASCIIAlpha(*m_ptr) || *m_ptr == '_' || *m_ptr == '$') {230 while (m_ptr < m_end && (isASCIIAlphanumeric(*m_ptr) || *m_ptr == '_' || *m_ptr == '$'))231 m_ptr++;232 token.stringToken = token.start;233 token.stringLength = m_ptr - token.start;234 token.type = TokIdentifier;235 token.end = m_ptr;236 return TokIdentifier;237 }238 if (*m_ptr == '\'') {239 if (mode == StrictJSON)240 return TokError;241 return lexString<mode, '\''>(token);242 }243 }244 132 return TokError; 245 133 } 246 134 247 LiteralParser::TokenType LiteralParser::Lexer::next() 248 { 249 if (m_mode == NonStrictJSON) 250 return lex<NonStrictJSON>(m_currentToken); 251 if (m_mode == JSONP) 252 return lex<JSONP>(m_currentToken); 253 return lex<StrictJSON>(m_currentToken); 254 } 255 256 template <LiteralParser::ParserMode mode, UChar terminator> static inline bool isSafeStringCharacter(UChar c) 257 { 258 return (c >= ' ' && (mode == LiteralParser::StrictJSON || c <= 0xff) && c != '\\' && c != terminator) || c == '\t'; 135 template <LiteralParser::ParserMode mode> static inline bool isSafeStringCharacter(UChar c) 136 { 137 return (c >= ' ' && (mode == LiteralParser::StrictJSON || c <= 0xff) && c != '\\' && c != '"') || c == '\t'; 259 138 } 260 139 261 140 // "inline" is required here to help WINSCW compiler resolve specialized argument in templated functions. 262 template <LiteralParser::ParserMode mode , UChar terminator> inline LiteralParser::TokenType LiteralParser::Lexer::lexString(LiteralParserToken& token)141 template <LiteralParser::ParserMode mode> inline LiteralParser::TokenType LiteralParser::Lexer::lexString(LiteralParserToken& token) 263 142 { 264 143 ++m_ptr; 265 const UChar* runStart = m_ptr;144 const UChar* runStart; 266 145 UStringBuilder builder; 267 146 do { 268 147 runStart = m_ptr; 269 while (m_ptr < m_end && isSafeStringCharacter<mode , terminator>(*m_ptr))270 ++m_ptr; 271 if ( builder.length())148 while (m_ptr < m_end && isSafeStringCharacter<mode>(*m_ptr)) 149 ++m_ptr; 150 if (runStart < m_ptr) 272 151 builder.append(runStart, m_ptr - runStart); 273 if ((mode != NonStrictJSON) && m_ptr < m_end && *m_ptr == '\\') { 274 if (builder.isEmpty() && runStart < m_ptr) 275 builder.append(runStart, m_ptr - runStart); 152 if ((mode == StrictJSON) && m_ptr < m_end && *m_ptr == '\\') { 276 153 ++m_ptr; 277 154 if (m_ptr >= m_end) … … 323 200 324 201 default: 325 if (*m_ptr == '\'' && mode != StrictJSON) {326 builder.append('\'');327 m_ptr++;328 break;329 }330 202 return TokError; 331 203 } 332 204 } 333 } while ((mode != NonStrictJSON) && m_ptr != runStart && (m_ptr < m_end) && *m_ptr != terminator);334 335 if (m_ptr >= m_end || *m_ptr != terminator)205 } while ((mode == StrictJSON) && m_ptr != runStart && (m_ptr < m_end) && *m_ptr != '"'); 206 207 if (m_ptr >= m_end || *m_ptr != '"') 336 208 return TokError; 337 209 338 if (builder.isEmpty()) { 339 token.stringBuffer = UString(); 340 token.stringToken = runStart; 341 token.stringLength = m_ptr - runStart; 342 } else { 343 token.stringBuffer = builder.toUString(); 344 token.stringToken = token.stringBuffer.characters(); 345 token.stringLength = token.stringBuffer.length(); 346 } 210 token.stringToken = builder.toUString(); 347 211 token.type = TokString; 348 212 token.end = ++m_ptr; … … 390 254 while (m_ptr < m_end && isASCIIDigit(*m_ptr)) 391 255 ++m_ptr; 392 } else if (m_ptr < m_end && (*m_ptr != 'e' && *m_ptr != 'E') && (m_ptr - token.start) < 10) {393 int result = 0;394 token.type = TokNumber;395 token.end = m_ptr;396 const UChar* digit = token.start;397 int negative = 1;398 if (*digit == '-') {399 negative = -1;400 digit++;401 }402 403 while (digit < m_ptr)404 result = result * 10 + (*digit++) - '0';405 result *= negative;406 token.numberToken = result;407 return TokNumber;408 256 } 409 257 … … 490 338 491 339 TokenType type = m_lexer.next(); 492 if (type == TokString || (m_mode != StrictJSON && type == TokIdentifier)) {340 if (type == TokString) { 493 341 Lexer::LiteralParserToken identifierToken = m_lexer.currentToken(); 494 342 … … 498 346 499 347 m_lexer.next(); 500 identifierStack.append( makeIdentifier(identifierToken.stringToken, identifierToken.stringLength));348 identifierStack.append(Identifier(m_exec, identifierToken.stringToken)); 501 349 stateStack.append(DoParseObjectEndExpression); 502 350 goto startParseExpression; 503 } 504 if (type != TokRBrace) 351 } else if (type != TokRBrace) 505 352 return JSValue(); 506 353 m_lexer.next(); … … 512 359 case DoParseObjectStartExpression: { 513 360 TokenType type = m_lexer.next(); 514 if (type != TokString && (m_mode == StrictJSON || type != TokIdentifier))361 if (type != TokString) 515 362 return JSValue(); 516 363 Lexer::LiteralParserToken identifierToken = m_lexer.currentToken(); … … 521 368 522 369 m_lexer.next(); 523 identifierStack.append( makeIdentifier(identifierToken.stringToken, identifierToken.stringLength));370 identifierStack.append(Identifier(m_exec, identifierToken.stringToken)); 524 371 stateStack.append(DoParseObjectEndExpression); 525 372 goto startParseExpression; … … 548 395 Lexer::LiteralParserToken stringToken = m_lexer.currentToken(); 549 396 m_lexer.next(); 550 lastValue = jsString(m_exec, makeIdentifier(stringToken.stringToken, stringToken.stringLength).ustring());397 lastValue = jsString(m_exec, stringToken.stringToken); 551 398 break; 552 399 }
Note:
See TracChangeset
for help on using the changeset viewer.