Changeset 89184 in webkit for trunk/Source/JavaScriptCore/runtime/LiteralParser.cpp
- Timestamp:
- Jun 17, 2011, 9:25:57 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/runtime/LiteralParser.cpp
r77151 r89184 43 43 } 44 44 45 LiteralParser::TokenType LiteralParser::Lexer::lex(LiteralParserToken& token) 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) 46 129 { 47 130 while (m_ptr < m_end && isJSONWhiteSpace(*m_ptr)) … … 90 173 return TokColon; 91 174 case '"': 92 if (m_mode == StrictJSON) 93 return lexString<StrictJSON>(token); 94 return lexString<NonStrictJSON>(token); 175 return lexString<mode, '"'>(token); 95 176 case 't': 96 177 if (m_end - m_ptr >= 4 && m_ptr[1] == 'r' && m_ptr[2] == 'u' && m_ptr[3] == 'e') { … … 116 197 return TokNull; 117 198 } 118 break; 199 break; 119 200 case '-': 120 201 case '0': … … 130 211 return lexNumber(token); 131 212 } 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 } 132 244 return TokError; 133 245 } 134 246 135 template <LiteralParser::ParserMode mode> static inline bool isSafeStringCharacter(UChar c) 136 { 137 return (c >= ' ' && (mode == LiteralParser::StrictJSON || c <= 0xff) && c != '\\' && c != '"') || c == '\t'; 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'; 138 259 } 139 260 140 261 // "inline" is required here to help WINSCW compiler resolve specialized argument in templated functions. 141 template <LiteralParser::ParserMode mode > inline LiteralParser::TokenType LiteralParser::Lexer::lexString(LiteralParserToken& token)262 template <LiteralParser::ParserMode mode, UChar terminator> inline LiteralParser::TokenType LiteralParser::Lexer::lexString(LiteralParserToken& token) 142 263 { 143 264 ++m_ptr; 144 const UChar* runStart ;265 const UChar* runStart = m_ptr; 145 266 UStringBuilder builder; 146 267 do { 147 268 runStart = m_ptr; 148 while (m_ptr < m_end && isSafeStringCharacter<mode >(*m_ptr))269 while (m_ptr < m_end && isSafeStringCharacter<mode, terminator>(*m_ptr)) 149 270 ++m_ptr; 150 if ( runStart < m_ptr)271 if (builder.length()) 151 272 builder.append(runStart, m_ptr - runStart); 152 if ((mode == StrictJSON) && m_ptr < m_end && *m_ptr == '\\') { 273 if ((mode != NonStrictJSON) && m_ptr < m_end && *m_ptr == '\\') { 274 if (builder.isEmpty() && runStart < m_ptr) 275 builder.append(runStart, m_ptr - runStart); 153 276 ++m_ptr; 154 277 if (m_ptr >= m_end) … … 200 323 201 324 default: 325 if (*m_ptr == '\'' && mode != StrictJSON) { 326 builder.append('\''); 327 m_ptr++; 328 break; 329 } 202 330 return TokError; 203 331 } 204 332 } 205 } while ((mode == StrictJSON) && m_ptr != runStart && (m_ptr < m_end) && *m_ptr != '"');206 207 if (m_ptr >= m_end || *m_ptr != '"')333 } while ((mode != NonStrictJSON) && m_ptr != runStart && (m_ptr < m_end) && *m_ptr != terminator); 334 335 if (m_ptr >= m_end || *m_ptr != terminator) 208 336 return TokError; 209 337 210 token.stringToken = builder.toUString(); 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 } 211 347 token.type = TokString; 212 348 token.end = ++m_ptr; … … 254 390 while (m_ptr < m_end && isASCIIDigit(*m_ptr)) 255 391 ++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; 256 408 } 257 409 … … 338 490 339 491 TokenType type = m_lexer.next(); 340 if (type == TokString ) {492 if (type == TokString || (m_mode != StrictJSON && type == TokIdentifier)) { 341 493 Lexer::LiteralParserToken identifierToken = m_lexer.currentToken(); 342 494 … … 346 498 347 499 m_lexer.next(); 348 identifierStack.append( Identifier(m_exec, identifierToken.stringToken));500 identifierStack.append(makeIdentifier(identifierToken.stringToken, identifierToken.stringLength)); 349 501 stateStack.append(DoParseObjectEndExpression); 350 502 goto startParseExpression; 351 } else if (type != TokRBrace) 503 } 504 if (type != TokRBrace) 352 505 return JSValue(); 353 506 m_lexer.next(); … … 359 512 case DoParseObjectStartExpression: { 360 513 TokenType type = m_lexer.next(); 361 if (type != TokString )514 if (type != TokString && (m_mode == StrictJSON || type != TokIdentifier)) 362 515 return JSValue(); 363 516 Lexer::LiteralParserToken identifierToken = m_lexer.currentToken(); … … 368 521 369 522 m_lexer.next(); 370 identifierStack.append( Identifier(m_exec, identifierToken.stringToken));523 identifierStack.append(makeIdentifier(identifierToken.stringToken, identifierToken.stringLength)); 371 524 stateStack.append(DoParseObjectEndExpression); 372 525 goto startParseExpression; … … 395 548 Lexer::LiteralParserToken stringToken = m_lexer.currentToken(); 396 549 m_lexer.next(); 397 lastValue = jsString(m_exec, stringToken.stringToken);550 lastValue = jsString(m_exec, makeIdentifier(stringToken.stringToken, stringToken.stringLength).ustring()); 398 551 break; 399 552 }
Note:
See TracChangeset
for help on using the changeset viewer.