Changeset 44644 in webkit for trunk/JavaScriptCore/runtime/LiteralParser.cpp
- Timestamp:
- Jun 12, 2009, 6:18:57 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/runtime/LiteralParser.cpp
r44343 r44644 33 33 namespace JSC { 34 34 35 class LiteralParser::StackGuard {36 public:37 StackGuard(LiteralParser* parser)38 : m_parser(parser)39 {40 m_parser->m_depth++;41 }42 ~StackGuard()43 {44 m_parser->m_depth--;45 }46 bool isSafe() { return m_parser->m_depth < 10; }47 private:48 LiteralParser* m_parser;49 };50 51 35 static bool isSafeStringCharacter(UChar c) 52 36 { … … 198 182 } 199 183 200 JSValue LiteralParser::parseStatement() 201 { 202 StackGuard guard(this); 203 if (!guard.isSafe()) 204 return abortParse(); 205 206 switch (m_lexer.currentToken().type) { 207 case TokLBracket: 208 case TokNumber: 209 case TokString: 210 return parseExpression(); 211 case TokLParen: { 212 m_lexer.next(); 213 JSValue result = parseExpression(); 214 if (m_aborted || m_lexer.currentToken().type != TokRParen) 215 return abortParse(); 216 m_lexer.next(); 217 return result; 184 JSValue LiteralParser::parse(ParserState initialState) 185 { 186 ParserState state = initialState; 187 MarkedArgumentBuffer objectStack; 188 JSValue lastValue; 189 Vector<ParserState, 16> stateStack; 190 Vector<Identifier, 16> identifierStack; 191 while (1) { 192 switch(state) { 193 startParseArray: 194 case StartParseArray: { 195 JSArray* array = constructEmptyArray(m_exec); 196 objectStack.append(array); 197 // fallthrough 198 } 199 doParseArrayStartExpression: 200 case DoParseArrayStartExpression: { 201 if (m_lexer.next() == TokRBracket) { 202 m_lexer.next(); 203 lastValue = objectStack.last(); 204 objectStack.removeLast(); 205 break; 206 } 207 208 stateStack.append(DoParseArrayEndExpression); 209 goto startParseExpression; 210 } 211 case DoParseArrayEndExpression: { 212 asArray(objectStack.last())->push(m_exec, lastValue); 213 214 if (m_lexer.currentToken().type == TokComma) 215 goto doParseArrayStartExpression; 216 217 if (m_lexer.currentToken().type != TokRBracket) 218 return JSValue(); 219 220 m_lexer.next(); 221 lastValue = objectStack.last(); 222 objectStack.removeLast(); 223 break; 224 } 225 startParseObject: 226 case StartParseObject: { 227 JSObject* object = constructEmptyObject(m_exec); 228 objectStack.append(object); 229 // fallthrough 230 } 231 doParseObjectStartExpression: 232 case DoParseObjectStartExpression: { 233 TokenType type = m_lexer.next(); 234 if (type == TokString) { 235 Lexer::LiteralParserToken identifierToken = m_lexer.currentToken(); 236 237 // Check for colon 238 if (m_lexer.next() != TokColon) 239 return JSValue(); 240 241 m_lexer.next(); 242 identifierStack.append(Identifier(m_exec, identifierToken.start + 1, identifierToken.end - identifierToken.start - 2)); 243 stateStack.append(DoParseObjectEndExpression); 244 goto startParseExpression; 245 } else if (type != TokRBrace) 246 return JSValue(); 247 m_lexer.next(); 248 lastValue = objectStack.last(); 249 objectStack.removeLast(); 250 break; 251 } 252 case DoParseObjectEndExpression: 253 { 254 asObject(objectStack.last())->putDirect(identifierStack.last(), lastValue); 255 identifierStack.removeLast(); 256 if (m_lexer.currentToken().type == TokComma) 257 goto doParseObjectStartExpression; 258 if (m_lexer.currentToken().type != TokRBrace) 259 return JSValue(); 260 m_lexer.next(); 261 lastValue = objectStack.last(); 262 objectStack.removeLast(); 263 break; 264 } 265 startParseExpression: 266 case StartParseExpression: { 267 switch (m_lexer.currentToken().type) { 268 case TokLBracket: 269 goto startParseArray; 270 case TokLBrace: 271 goto startParseObject; 272 case TokString: { 273 Lexer::LiteralParserToken stringToken = m_lexer.currentToken(); 274 m_lexer.next(); 275 lastValue = jsString(m_exec, UString(stringToken.start + 1, stringToken.end - stringToken.start - 2)); 276 break; 277 } 278 case TokNumber: { 279 Lexer::LiteralParserToken numberToken = m_lexer.currentToken(); 280 m_lexer.next(); 281 lastValue = jsNumber(m_exec, UString(numberToken.start, numberToken.end - numberToken.start).toDouble()); 282 break; 283 } 284 default: 285 // Error 286 return JSValue(); 287 } 288 break; 289 } 290 case StartParseStatement: { 291 switch (m_lexer.currentToken().type) { 292 case TokLBracket: 293 case TokNumber: 294 case TokString: 295 goto startParseExpression; 296 297 case TokLParen: { 298 m_lexer.next(); 299 stateStack.append(StartParseStatementEndStatement); 300 goto startParseExpression; 301 } 302 default: 303 return JSValue(); 304 } 305 } 306 case StartParseStatementEndStatement: { 307 ASSERT(stateStack.isEmpty()); 308 if (m_lexer.currentToken().type != TokRParen) 309 return JSValue(); 310 if (m_lexer.next() == TokEnd) 311 return lastValue; 312 return JSValue(); 313 } 314 default: 315 ASSERT_NOT_REACHED(); 218 316 } 219 default: 220 return abortParse(); 221 } 222 } 223 224 JSValue LiteralParser::parseExpression() 225 { 226 StackGuard guard(this); 227 if (!guard.isSafe()) 228 return abortParse(); 229 switch (m_lexer.currentToken().type) { 230 case TokLBracket: 231 return parseArray(); 232 case TokLBrace: 233 return parseObject(); 234 case TokString: { 235 Lexer::LiteralParserToken stringToken = m_lexer.currentToken(); 236 m_lexer.next(); 237 return jsString(m_exec, UString(stringToken.start + 1, stringToken.end - stringToken.start - 2)); 238 } 239 case TokNumber: { 240 Lexer::LiteralParserToken numberToken = m_lexer.currentToken(); 241 m_lexer.next(); 242 return jsNumber(m_exec, UString(numberToken.start, numberToken.end - numberToken.start).toDouble()); 243 } 244 default: 245 return JSValue(); 246 } 247 } 248 249 JSValue LiteralParser::parseArray() 250 { 251 StackGuard guard(this); 252 if (!guard.isSafe()) 253 return abortParse(); 254 JSArray* array = constructEmptyArray(m_exec); 255 while (true) { 256 m_lexer.next(); 257 JSValue value = parseExpression(); 258 if (m_aborted) 259 return JSValue(); 260 if (!value) 261 break; 262 array->push(m_exec, value); 263 264 if (m_lexer.currentToken().type != TokComma) 265 break; 266 } 267 if (m_lexer.currentToken().type != TokRBracket) 268 return abortParse(); 269 270 m_lexer.next(); 271 return array; 272 } 273 274 JSValue LiteralParser::parseObject() 275 { 276 StackGuard guard(this); 277 if (!guard.isSafe()) 278 return abortParse(); 279 JSObject* object = constructEmptyObject(m_exec); 280 281 while (m_lexer.next() == TokString) { 282 Lexer::LiteralParserToken identifierToken = m_lexer.currentToken(); 283 284 // Check for colon 285 if (m_lexer.next() != TokColon) 286 return abortParse(); 287 m_lexer.next(); 288 289 JSValue value = parseExpression(); 290 if (!value || m_aborted) 291 return abortParse(); 292 293 Identifier ident(m_exec, identifierToken.start + 1, identifierToken.end - identifierToken.start - 2); 294 object->putDirect(ident, value); 295 296 if (m_lexer.currentToken().type != TokComma) 297 break; 298 } 299 300 if (m_lexer.currentToken().type != TokRBrace) 301 return abortParse(); 302 m_lexer.next(); 303 return object; 304 } 305 306 } 317 if (stateStack.isEmpty()) 318 return lastValue; 319 state = stateStack.last(); 320 stateStack.removeLast(); 321 continue; 322 } 323 } 324 325 }
Note:
See TracChangeset
for help on using the changeset viewer.