Changeset 44923 in webkit for trunk/JavaScriptCore/runtime/LiteralParser.cpp
- Timestamp:
- Jun 21, 2009, 4:02:13 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/runtime/LiteralParser.cpp
r44644 r44923 29 29 #include "JSArray.h" 30 30 #include "JSString.h" 31 #include "Lexer.h" 31 32 #include <wtf/ASCIICType.h> 32 33 33 34 namespace JSC { 34 35 static bool isSafeStringCharacter(UChar c)36 {37 return (c >= ' ' && c <= 0xff && c != '\\') || c == '\t';38 }39 35 40 36 LiteralParser::TokenType LiteralParser::Lexer::lex(LiteralParserToken& token) … … 85 81 return TokColon; 86 82 case '"': 87 return lexString(token); 88 83 if (m_mode == StrictJSON) 84 return lexString<StrictJSON>(token); 85 return lexString<NonStrictJSON>(token); 86 case 't': 87 if (m_end - m_ptr >= 4 && m_ptr[1] == 'r' && m_ptr[2] == 'u' && m_ptr[3] == 'e') { 88 m_ptr += 4; 89 token.type = TokTrue; 90 token.end = m_ptr; 91 return TokTrue; 92 } 93 break; 94 case 'f': 95 if (m_end - m_ptr >= 5 && m_ptr[1] == 'a' && m_ptr[2] == 'l' && m_ptr[3] == 's' && m_ptr[4] == 'e') { 96 m_ptr += 5; 97 token.type = TokFalse; 98 token.end = m_ptr; 99 return TokFalse; 100 } 101 break; 102 case 'n': 103 if (m_end - m_ptr >= 4 && m_ptr[1] == 'u' && m_ptr[2] == 'l' && m_ptr[3] == 'l') { 104 m_ptr += 4; 105 token.type = TokNull; 106 token.end = m_ptr; 107 return TokNull; 108 } 109 break; 89 110 case '-': 90 111 case '0': … … 103 124 } 104 125 105 LiteralParser::TokenType LiteralParser::Lexer::lexString(LiteralParserToken& token) 126 static inline bool isSafeStringCharacter(UChar c) 127 { 128 return (c >= ' ' && c <= 0xff && c != '\\' && c != '"') || c == '\t'; 129 } 130 131 template <LiteralParser::ParserMode mode> LiteralParser::TokenType LiteralParser::Lexer::lexString(LiteralParserToken& token) 106 132 { 107 133 ++m_ptr; 108 while (m_ptr < m_end && isSafeStringCharacter(*m_ptr) && *m_ptr != '"') 109 ++m_ptr; 110 if (m_ptr >= m_end || *m_ptr != '"') { 111 token.type = TokError; 112 token.end = ++m_ptr; 134 const UChar* runStart; 135 token.stringToken = UString(); 136 do { 137 runStart = m_ptr; 138 while (m_ptr < m_end && isSafeStringCharacter(*m_ptr)) 139 ++m_ptr; 140 if (runStart < m_ptr) 141 token.stringToken.append(runStart, m_ptr - runStart); 142 if ((mode == StrictJSON) && m_ptr < m_end && *m_ptr == '\\') { 143 ++m_ptr; 144 if (m_ptr >= m_end) 145 return TokError; 146 switch (*m_ptr) { 147 case '"': 148 token.stringToken.append('"'); 149 m_ptr++; 150 break; 151 case '\\': 152 token.stringToken.append('\\'); 153 m_ptr++; 154 break; 155 case '/': 156 token.stringToken.append('/'); 157 m_ptr++; 158 break; 159 case 'b': 160 token.stringToken.append('\b'); 161 m_ptr++; 162 break; 163 case 'f': 164 token.stringToken.append('\f'); 165 m_ptr++; 166 break; 167 case 'n': 168 token.stringToken.append('\n'); 169 m_ptr++; 170 break; 171 case 'r': 172 token.stringToken.append('\r'); 173 m_ptr++; 174 break; 175 case 't': 176 token.stringToken.append('\t'); 177 m_ptr++; 178 break; 179 180 case 'u': 181 if ((m_end - m_ptr) < 5) // uNNNN == 5 characters 182 return TokError; 183 for (int i = 1; i < 5; i++) { 184 if (!isASCIIHexDigit(m_ptr[i])) 185 return TokError; 186 } 187 token.stringToken.append(JSC::Lexer::convertUnicode(m_ptr[1], m_ptr[2], m_ptr[3], m_ptr[4])); 188 m_ptr += 5; 189 break; 190 191 default: 192 return TokError; 193 } 194 } 195 } while ((mode == StrictJSON) && m_ptr != runStart && (m_ptr < m_end) && *m_ptr != '"'); 196 197 if (m_ptr >= m_end || *m_ptr != '"') 113 198 return TokError; 114 } 199 115 200 token.type = TokString; 116 201 token.end = ++m_ptr; … … 152 237 ++m_ptr; 153 238 // [0-9]+ 154 if (m_ptr >= m_end &&!isASCIIDigit(*m_ptr))239 if (m_ptr >= m_end || !isASCIIDigit(*m_ptr)) 155 240 return TokError; 156 241 … … 169 254 170 255 // [0-9]+ 171 if (m_ptr >= m_end &&!isASCIIDigit(*m_ptr))256 if (m_ptr >= m_end || !isASCIIDigit(*m_ptr)) 172 257 return TokError; 173 258 … … 227 312 JSObject* object = constructEmptyObject(m_exec); 228 313 objectStack.append(object); 229 // fallthrough 314 315 TokenType type = m_lexer.next(); 316 if (type == TokString) { 317 Lexer::LiteralParserToken identifierToken = m_lexer.currentToken(); 318 319 // Check for colon 320 if (m_lexer.next() != TokColon) 321 return JSValue(); 322 323 m_lexer.next(); 324 identifierStack.append(Identifier(m_exec, identifierToken.stringToken)); 325 stateStack.append(DoParseObjectEndExpression); 326 goto startParseExpression; 327 } else if (type != TokRBrace) 328 return JSValue(); 329 m_lexer.next(); 330 lastValue = objectStack.last(); 331 objectStack.removeLast(); 332 break; 230 333 } 231 334 doParseObjectStartExpression: … … 240 343 241 344 m_lexer.next(); 242 identifierStack.append(Identifier(m_exec, identifierToken.st art + 1, identifierToken.end - identifierToken.start - 2));345 identifierStack.append(Identifier(m_exec, identifierToken.stringToken)); 243 346 stateStack.append(DoParseObjectEndExpression); 244 347 goto startParseExpression; 245 } else if (type != TokRBrace)348 } else 246 349 return JSValue(); 247 350 m_lexer.next(); … … 273 376 Lexer::LiteralParserToken stringToken = m_lexer.currentToken(); 274 377 m_lexer.next(); 275 lastValue = jsString(m_exec, UString(stringToken.start + 1, stringToken.end - stringToken.start - 2));378 lastValue = jsString(m_exec, stringToken.stringToken); 276 379 break; 277 380 } … … 282 385 break; 283 386 } 387 case TokNull: 388 m_lexer.next(); 389 lastValue = jsNull(); 390 break; 391 392 case TokTrue: 393 m_lexer.next(); 394 lastValue = jsBoolean(true); 395 break; 396 397 case TokFalse: 398 m_lexer.next(); 399 lastValue = jsBoolean(false); 400 break; 401 284 402 default: 285 403 // Error
Note:
See TracChangeset
for help on using the changeset viewer.