OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 if (!*ok) return -1; \ | 58 if (!*ok) return -1; \ |
59 ((void)0 | 59 ((void)0 |
60 #define DUMMY ) // to make indentation work | 60 #define DUMMY ) // to make indentation work |
61 #undef DUMMY | 61 #undef DUMMY |
62 | 62 |
63 | 63 |
64 void PreParser::ReportUnexpectedToken(i::Token::Value token) { | 64 void PreParser::ReportUnexpectedToken(i::Token::Value token) { |
65 // We don't report stack overflows here, to avoid increasing the | 65 // We don't report stack overflows here, to avoid increasing the |
66 // stack depth even further. Instead we report it after parsing is | 66 // stack depth even further. Instead we report it after parsing is |
67 // over, in ParseProgram. | 67 // over, in ParseProgram. |
68 if (token == i::Token::ILLEGAL && scanner_->stack_overflow()) { | 68 if (token == i::Token::ILLEGAL && stack_overflow_) { |
69 return; | 69 return; |
70 } | 70 } |
71 i::JavaScriptScanner::Location source_location = scanner_->location(); | 71 i::JavaScriptScanner::Location source_location = scanner_->location(); |
72 | 72 |
73 // Four of the tokens are treated specially | 73 // Four of the tokens are treated specially |
74 switch (token) { | 74 switch (token) { |
75 case i::Token::EOS: | 75 case i::Token::EOS: |
76 return ReportMessageAt(source_location.beg_pos, source_location.end_pos, | 76 return ReportMessageAt(source_location.beg_pos, source_location.end_pos, |
77 "unexpected_eos", NULL); | 77 "unexpected_eos", NULL); |
78 case i::Token::NUMBER: | 78 case i::Token::NUMBER: |
79 return ReportMessageAt(source_location.beg_pos, source_location.end_pos, | 79 return ReportMessageAt(source_location.beg_pos, source_location.end_pos, |
80 "unexpected_token_number", NULL); | 80 "unexpected_token_number", NULL); |
81 case i::Token::STRING: | 81 case i::Token::STRING: |
82 return ReportMessageAt(source_location.beg_pos, source_location.end_pos, | 82 return ReportMessageAt(source_location.beg_pos, source_location.end_pos, |
83 "unexpected_token_string", NULL); | 83 "unexpected_token_string", NULL); |
84 case i::Token::IDENTIFIER: | 84 case i::Token::IDENTIFIER: |
85 return ReportMessageAt(source_location.beg_pos, source_location.end_pos, | 85 return ReportMessageAt(source_location.beg_pos, source_location.end_pos, |
86 "unexpected_token_identifier", NULL); | 86 "unexpected_token_identifier", NULL); |
87 default: | 87 default: |
88 const char* name = i::Token::String(token); | 88 const char* name = i::Token::String(token); |
89 ReportMessageAt(source_location.beg_pos, source_location.end_pos, | 89 ReportMessageAt(source_location.beg_pos, source_location.end_pos, |
90 "unexpected_token", name); | 90 "unexpected_token", name); |
91 } | 91 } |
92 } | 92 } |
93 | 93 |
94 | 94 |
95 SourceElements PreParser::ParseSourceElements(int end_token, | 95 PreParser::SourceElements PreParser::ParseSourceElements(int end_token, |
96 bool* ok) { | 96 bool* ok) { |
97 // SourceElements :: | 97 // SourceElements :: |
98 // (Statement)* <end_token> | 98 // (Statement)* <end_token> |
99 | 99 |
100 while (peek() != end_token) { | 100 while (peek() != end_token) { |
101 ParseStatement(CHECK_OK); | 101 ParseStatement(CHECK_OK); |
102 } | 102 } |
103 return kUnknownSourceElements; | 103 return kUnknownSourceElements; |
104 } | 104 } |
105 | 105 |
106 | 106 |
107 Statement PreParser::ParseStatement(bool* ok) { | 107 PreParser::PreParser::Statement PreParser::ParseStatement(bool* ok) { |
108 // Statement :: | 108 // Statement :: |
109 // Block | 109 // Block |
110 // VariableStatement | 110 // VariableStatement |
111 // EmptyStatement | 111 // EmptyStatement |
112 // ExpressionStatement | 112 // ExpressionStatement |
113 // IfStatement | 113 // IfStatement |
114 // IterationStatement | 114 // IterationStatement |
115 // ContinueStatement | 115 // ContinueStatement |
116 // BreakStatement | 116 // BreakStatement |
117 // ReturnStatement | 117 // ReturnStatement |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 | 183 |
184 case i::Token::DEBUGGER: | 184 case i::Token::DEBUGGER: |
185 return ParseDebuggerStatement(ok); | 185 return ParseDebuggerStatement(ok); |
186 | 186 |
187 default: | 187 default: |
188 return ParseExpressionOrLabelledStatement(ok); | 188 return ParseExpressionOrLabelledStatement(ok); |
189 } | 189 } |
190 } | 190 } |
191 | 191 |
192 | 192 |
193 Statement PreParser::ParseFunctionDeclaration(bool* ok) { | 193 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { |
194 // FunctionDeclaration :: | 194 // FunctionDeclaration :: |
195 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' | 195 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
196 Expect(i::Token::FUNCTION, CHECK_OK); | 196 Expect(i::Token::FUNCTION, CHECK_OK); |
197 ParseIdentifier(CHECK_OK); | 197 ParseIdentifier(CHECK_OK); |
198 ParseFunctionLiteral(CHECK_OK); | 198 ParseFunctionLiteral(CHECK_OK); |
199 return kUnknownStatement; | 199 return kUnknownStatement; |
200 } | 200 } |
201 | 201 |
202 | 202 |
203 // Language extension which is only enabled for source files loaded | 203 // Language extension which is only enabled for source files loaded |
204 // through the API's extension mechanism. A native function | 204 // through the API's extension mechanism. A native function |
205 // declaration is resolved by looking up the function through a | 205 // declaration is resolved by looking up the function through a |
206 // callback provided by the extension. | 206 // callback provided by the extension. |
207 Statement PreParser::ParseNativeDeclaration(bool* ok) { | 207 PreParser::Statement PreParser::ParseNativeDeclaration(bool* ok) { |
208 Expect(i::Token::NATIVE, CHECK_OK); | 208 Expect(i::Token::NATIVE, CHECK_OK); |
209 Expect(i::Token::FUNCTION, CHECK_OK); | 209 Expect(i::Token::FUNCTION, CHECK_OK); |
210 ParseIdentifier(CHECK_OK); | 210 ParseIdentifier(CHECK_OK); |
211 Expect(i::Token::LPAREN, CHECK_OK); | 211 Expect(i::Token::LPAREN, CHECK_OK); |
212 bool done = (peek() == i::Token::RPAREN); | 212 bool done = (peek() == i::Token::RPAREN); |
213 while (!done) { | 213 while (!done) { |
214 ParseIdentifier(CHECK_OK); | 214 ParseIdentifier(CHECK_OK); |
215 done = (peek() == i::Token::RPAREN); | 215 done = (peek() == i::Token::RPAREN); |
216 if (!done) { | 216 if (!done) { |
217 Expect(i::Token::COMMA, CHECK_OK); | 217 Expect(i::Token::COMMA, CHECK_OK); |
218 } | 218 } |
219 } | 219 } |
220 Expect(i::Token::RPAREN, CHECK_OK); | 220 Expect(i::Token::RPAREN, CHECK_OK); |
221 Expect(i::Token::SEMICOLON, CHECK_OK); | 221 Expect(i::Token::SEMICOLON, CHECK_OK); |
222 return kUnknownStatement; | 222 return kUnknownStatement; |
223 } | 223 } |
224 | 224 |
225 | 225 |
226 Statement PreParser::ParseBlock(bool* ok) { | 226 PreParser::Statement PreParser::ParseBlock(bool* ok) { |
227 // Block :: | 227 // Block :: |
228 // '{' Statement* '}' | 228 // '{' Statement* '}' |
229 | 229 |
230 // Note that a Block does not introduce a new execution scope! | 230 // Note that a Block does not introduce a new execution scope! |
231 // (ECMA-262, 3rd, 12.2) | 231 // (ECMA-262, 3rd, 12.2) |
232 // | 232 // |
233 Expect(i::Token::LBRACE, CHECK_OK); | 233 Expect(i::Token::LBRACE, CHECK_OK); |
234 while (peek() != i::Token::RBRACE) { | 234 while (peek() != i::Token::RBRACE) { |
235 ParseStatement(CHECK_OK); | 235 ParseStatement(CHECK_OK); |
236 } | 236 } |
237 Expect(i::Token::RBRACE, CHECK_OK); | 237 Expect(i::Token::RBRACE, CHECK_OK); |
238 return kUnknownStatement; | 238 return kUnknownStatement; |
239 } | 239 } |
240 | 240 |
241 | 241 |
242 Statement PreParser::ParseVariableStatement(bool* ok) { | 242 PreParser::Statement PreParser::ParseVariableStatement(bool* ok) { |
243 // VariableStatement :: | 243 // VariableStatement :: |
244 // VariableDeclarations ';' | 244 // VariableDeclarations ';' |
245 | 245 |
246 Statement result = ParseVariableDeclarations(true, NULL, CHECK_OK); | 246 Statement result = ParseVariableDeclarations(true, NULL, CHECK_OK); |
247 ExpectSemicolon(CHECK_OK); | 247 ExpectSemicolon(CHECK_OK); |
248 return result; | 248 return result; |
249 } | 249 } |
250 | 250 |
251 | 251 |
252 // If the variable declaration declares exactly one non-const | 252 // If the variable declaration declares exactly one non-const |
253 // variable, then *var is set to that variable. In all other cases, | 253 // variable, then *var is set to that variable. In all other cases, |
254 // *var is untouched; in particular, it is the caller's responsibility | 254 // *var is untouched; in particular, it is the caller's responsibility |
255 // to initialize it properly. This mechanism is also used for the parsing | 255 // to initialize it properly. This mechanism is also used for the parsing |
256 // of 'for-in' loops. | 256 // of 'for-in' loops. |
257 Statement PreParser::ParseVariableDeclarations(bool accept_IN, | 257 PreParser::Statement PreParser::ParseVariableDeclarations(bool accept_IN, |
258 int* num_decl, | 258 int* num_decl, |
259 bool* ok) { | 259 bool* ok) { |
260 // VariableDeclarations :: | 260 // VariableDeclarations :: |
261 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] | 261 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] |
262 | 262 |
263 if (peek() == i::Token::VAR) { | 263 if (peek() == i::Token::VAR) { |
264 Consume(i::Token::VAR); | 264 Consume(i::Token::VAR); |
265 } else if (peek() == i::Token::CONST) { | 265 } else if (peek() == i::Token::CONST) { |
266 Consume(i::Token::CONST); | 266 Consume(i::Token::CONST); |
267 } else { | 267 } else { |
268 *ok = false; | 268 *ok = false; |
269 return 0; | 269 return 0; |
(...skipping 11 matching lines...) Expand all Loading... |
281 Expect(i::Token::ASSIGN, CHECK_OK); | 281 Expect(i::Token::ASSIGN, CHECK_OK); |
282 ParseAssignmentExpression(accept_IN, CHECK_OK); | 282 ParseAssignmentExpression(accept_IN, CHECK_OK); |
283 } | 283 } |
284 } while (peek() == i::Token::COMMA); | 284 } while (peek() == i::Token::COMMA); |
285 | 285 |
286 if (num_decl != NULL) *num_decl = nvars; | 286 if (num_decl != NULL) *num_decl = nvars; |
287 return kUnknownStatement; | 287 return kUnknownStatement; |
288 } | 288 } |
289 | 289 |
290 | 290 |
291 Statement PreParser::ParseExpressionOrLabelledStatement( | 291 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement( |
292 bool* ok) { | 292 bool* ok) { |
293 // ExpressionStatement | LabelledStatement :: | 293 // ExpressionStatement | LabelledStatement :: |
294 // Expression ';' | 294 // Expression ';' |
295 // Identifier ':' Statement | 295 // Identifier ':' Statement |
296 | 296 |
297 Expression expr = ParseExpression(true, CHECK_OK); | 297 Expression expr = ParseExpression(true, CHECK_OK); |
298 if (peek() == i::Token::COLON && expr == kIdentifierExpression) { | 298 if (peek() == i::Token::COLON && expr == kIdentifierExpression) { |
299 Consume(i::Token::COLON); | 299 Consume(i::Token::COLON); |
300 return ParseStatement(ok); | 300 return ParseStatement(ok); |
301 } | 301 } |
302 // Parsed expression statement. | 302 // Parsed expression statement. |
303 ExpectSemicolon(CHECK_OK); | 303 ExpectSemicolon(CHECK_OK); |
304 return kUnknownStatement; | 304 return kUnknownStatement; |
305 } | 305 } |
306 | 306 |
307 | 307 |
308 Statement PreParser::ParseIfStatement(bool* ok) { | 308 PreParser::Statement PreParser::ParseIfStatement(bool* ok) { |
309 // IfStatement :: | 309 // IfStatement :: |
310 // 'if' '(' Expression ')' Statement ('else' Statement)? | 310 // 'if' '(' Expression ')' Statement ('else' Statement)? |
311 | 311 |
312 Expect(i::Token::IF, CHECK_OK); | 312 Expect(i::Token::IF, CHECK_OK); |
313 Expect(i::Token::LPAREN, CHECK_OK); | 313 Expect(i::Token::LPAREN, CHECK_OK); |
314 ParseExpression(true, CHECK_OK); | 314 ParseExpression(true, CHECK_OK); |
315 Expect(i::Token::RPAREN, CHECK_OK); | 315 Expect(i::Token::RPAREN, CHECK_OK); |
316 ParseStatement(CHECK_OK); | 316 ParseStatement(CHECK_OK); |
317 if (peek() == i::Token::ELSE) { | 317 if (peek() == i::Token::ELSE) { |
318 Next(); | 318 Next(); |
319 ParseStatement(CHECK_OK); | 319 ParseStatement(CHECK_OK); |
320 } | 320 } |
321 return kUnknownStatement; | 321 return kUnknownStatement; |
322 } | 322 } |
323 | 323 |
324 | 324 |
325 Statement PreParser::ParseContinueStatement(bool* ok) { | 325 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) { |
326 // ContinueStatement :: | 326 // ContinueStatement :: |
327 // 'continue' [no line terminator] Identifier? ';' | 327 // 'continue' [no line terminator] Identifier? ';' |
328 | 328 |
329 Expect(i::Token::CONTINUE, CHECK_OK); | 329 Expect(i::Token::CONTINUE, CHECK_OK); |
330 i::Token::Value tok = peek(); | 330 i::Token::Value tok = peek(); |
331 if (!scanner_->has_line_terminator_before_next() && | 331 if (!scanner_->has_line_terminator_before_next() && |
332 tok != i::Token::SEMICOLON && | 332 tok != i::Token::SEMICOLON && |
333 tok != i::Token::RBRACE && | 333 tok != i::Token::RBRACE && |
334 tok != i::Token::EOS) { | 334 tok != i::Token::EOS) { |
335 ParseIdentifier(CHECK_OK); | 335 ParseIdentifier(CHECK_OK); |
336 } | 336 } |
337 ExpectSemicolon(CHECK_OK); | 337 ExpectSemicolon(CHECK_OK); |
338 return kUnknownStatement; | 338 return kUnknownStatement; |
339 } | 339 } |
340 | 340 |
341 | 341 |
342 Statement PreParser::ParseBreakStatement(bool* ok) { | 342 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) { |
343 // BreakStatement :: | 343 // BreakStatement :: |
344 // 'break' [no line terminator] Identifier? ';' | 344 // 'break' [no line terminator] Identifier? ';' |
345 | 345 |
346 Expect(i::Token::BREAK, CHECK_OK); | 346 Expect(i::Token::BREAK, CHECK_OK); |
347 i::Token::Value tok = peek(); | 347 i::Token::Value tok = peek(); |
348 if (!scanner_->has_line_terminator_before_next() && | 348 if (!scanner_->has_line_terminator_before_next() && |
349 tok != i::Token::SEMICOLON && | 349 tok != i::Token::SEMICOLON && |
350 tok != i::Token::RBRACE && | 350 tok != i::Token::RBRACE && |
351 tok != i::Token::EOS) { | 351 tok != i::Token::EOS) { |
352 ParseIdentifier(CHECK_OK); | 352 ParseIdentifier(CHECK_OK); |
353 } | 353 } |
354 ExpectSemicolon(CHECK_OK); | 354 ExpectSemicolon(CHECK_OK); |
355 return kUnknownStatement; | 355 return kUnknownStatement; |
356 } | 356 } |
357 | 357 |
358 | 358 |
359 Statement PreParser::ParseReturnStatement(bool* ok) { | 359 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) { |
360 // ReturnStatement :: | 360 // ReturnStatement :: |
361 // 'return' [no line terminator] Expression? ';' | 361 // 'return' [no line terminator] Expression? ';' |
362 | 362 |
363 // Consume the return token. It is necessary to do the before | 363 // Consume the return token. It is necessary to do the before |
364 // reporting any errors on it, because of the way errors are | 364 // reporting any errors on it, because of the way errors are |
365 // reported (underlining). | 365 // reported (underlining). |
366 Expect(i::Token::RETURN, CHECK_OK); | 366 Expect(i::Token::RETURN, CHECK_OK); |
367 | 367 |
368 // An ECMAScript program is considered syntactically incorrect if it | 368 // An ECMAScript program is considered syntactically incorrect if it |
369 // contains a return statement that is not within the body of a | 369 // contains a return statement that is not within the body of a |
370 // function. See ECMA-262, section 12.9, page 67. | 370 // function. See ECMA-262, section 12.9, page 67. |
371 // This is not handled during preparsing. | 371 // This is not handled during preparsing. |
372 | 372 |
373 i::Token::Value tok = peek(); | 373 i::Token::Value tok = peek(); |
374 if (!scanner_->has_line_terminator_before_next() && | 374 if (!scanner_->has_line_terminator_before_next() && |
375 tok != i::Token::SEMICOLON && | 375 tok != i::Token::SEMICOLON && |
376 tok != i::Token::RBRACE && | 376 tok != i::Token::RBRACE && |
377 tok != i::Token::EOS) { | 377 tok != i::Token::EOS) { |
378 ParseExpression(true, CHECK_OK); | 378 ParseExpression(true, CHECK_OK); |
379 } | 379 } |
380 ExpectSemicolon(CHECK_OK); | 380 ExpectSemicolon(CHECK_OK); |
381 return kUnknownStatement; | 381 return kUnknownStatement; |
382 } | 382 } |
383 | 383 |
384 | 384 |
385 Statement PreParser::ParseWithStatement(bool* ok) { | 385 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { |
386 // WithStatement :: | 386 // WithStatement :: |
387 // 'with' '(' Expression ')' Statement | 387 // 'with' '(' Expression ')' Statement |
388 Expect(i::Token::WITH, CHECK_OK); | 388 Expect(i::Token::WITH, CHECK_OK); |
389 Expect(i::Token::LPAREN, CHECK_OK); | 389 Expect(i::Token::LPAREN, CHECK_OK); |
390 ParseExpression(true, CHECK_OK); | 390 ParseExpression(true, CHECK_OK); |
391 Expect(i::Token::RPAREN, CHECK_OK); | 391 Expect(i::Token::RPAREN, CHECK_OK); |
392 | 392 |
393 scope_->EnterWith(); | 393 scope_->EnterWith(); |
394 ParseStatement(CHECK_OK); | 394 ParseStatement(CHECK_OK); |
395 scope_->LeaveWith(); | 395 scope_->LeaveWith(); |
396 return kUnknownStatement; | 396 return kUnknownStatement; |
397 } | 397 } |
398 | 398 |
399 | 399 |
400 Statement PreParser::ParseSwitchStatement(bool* ok) { | 400 PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) { |
401 // SwitchStatement :: | 401 // SwitchStatement :: |
402 // 'switch' '(' Expression ')' '{' CaseClause* '}' | 402 // 'switch' '(' Expression ')' '{' CaseClause* '}' |
403 | 403 |
404 Expect(i::Token::SWITCH, CHECK_OK); | 404 Expect(i::Token::SWITCH, CHECK_OK); |
405 Expect(i::Token::LPAREN, CHECK_OK); | 405 Expect(i::Token::LPAREN, CHECK_OK); |
406 ParseExpression(true, CHECK_OK); | 406 ParseExpression(true, CHECK_OK); |
407 Expect(i::Token::RPAREN, CHECK_OK); | 407 Expect(i::Token::RPAREN, CHECK_OK); |
408 | 408 |
409 Expect(i::Token::LBRACE, CHECK_OK); | 409 Expect(i::Token::LBRACE, CHECK_OK); |
410 i::Token::Value token = peek(); | 410 i::Token::Value token = peek(); |
411 while (token != i::Token::RBRACE) { | 411 while (token != i::Token::RBRACE) { |
412 if (token == i::Token::CASE) { | 412 if (token == i::Token::CASE) { |
413 Expect(i::Token::CASE, CHECK_OK); | 413 Expect(i::Token::CASE, CHECK_OK); |
414 ParseExpression(true, CHECK_OK); | 414 ParseExpression(true, CHECK_OK); |
415 Expect(i::Token::COLON, CHECK_OK); | 415 Expect(i::Token::COLON, CHECK_OK); |
416 } else if (token == i::Token::DEFAULT) { | 416 } else if (token == i::Token::DEFAULT) { |
417 Expect(i::Token::DEFAULT, CHECK_OK); | 417 Expect(i::Token::DEFAULT, CHECK_OK); |
418 Expect(i::Token::COLON, CHECK_OK); | 418 Expect(i::Token::COLON, CHECK_OK); |
419 } else { | 419 } else { |
420 ParseStatement(CHECK_OK); | 420 ParseStatement(CHECK_OK); |
421 } | 421 } |
422 token = peek(); | 422 token = peek(); |
423 } | 423 } |
424 Expect(i::Token::RBRACE, CHECK_OK); | 424 Expect(i::Token::RBRACE, CHECK_OK); |
425 | 425 |
426 return kUnknownStatement; | 426 return kUnknownStatement; |
427 } | 427 } |
428 | 428 |
429 | 429 |
430 Statement PreParser::ParseDoWhileStatement(bool* ok) { | 430 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) { |
431 // DoStatement :: | 431 // DoStatement :: |
432 // 'do' Statement 'while' '(' Expression ')' ';' | 432 // 'do' Statement 'while' '(' Expression ')' ';' |
433 | 433 |
434 Expect(i::Token::DO, CHECK_OK); | 434 Expect(i::Token::DO, CHECK_OK); |
435 ParseStatement(CHECK_OK); | 435 ParseStatement(CHECK_OK); |
436 Expect(i::Token::WHILE, CHECK_OK); | 436 Expect(i::Token::WHILE, CHECK_OK); |
437 Expect(i::Token::LPAREN, CHECK_OK); | 437 Expect(i::Token::LPAREN, CHECK_OK); |
438 ParseExpression(true, CHECK_OK); | 438 ParseExpression(true, CHECK_OK); |
439 Expect(i::Token::RPAREN, CHECK_OK); | 439 Expect(i::Token::RPAREN, CHECK_OK); |
440 return kUnknownStatement; | 440 return kUnknownStatement; |
441 } | 441 } |
442 | 442 |
443 | 443 |
444 Statement PreParser::ParseWhileStatement(bool* ok) { | 444 PreParser::Statement PreParser::ParseWhileStatement(bool* ok) { |
445 // WhileStatement :: | 445 // WhileStatement :: |
446 // 'while' '(' Expression ')' Statement | 446 // 'while' '(' Expression ')' Statement |
447 | 447 |
448 Expect(i::Token::WHILE, CHECK_OK); | 448 Expect(i::Token::WHILE, CHECK_OK); |
449 Expect(i::Token::LPAREN, CHECK_OK); | 449 Expect(i::Token::LPAREN, CHECK_OK); |
450 ParseExpression(true, CHECK_OK); | 450 ParseExpression(true, CHECK_OK); |
451 Expect(i::Token::RPAREN, CHECK_OK); | 451 Expect(i::Token::RPAREN, CHECK_OK); |
452 ParseStatement(CHECK_OK); | 452 ParseStatement(CHECK_OK); |
453 return kUnknownStatement; | 453 return kUnknownStatement; |
454 } | 454 } |
455 | 455 |
456 | 456 |
457 Statement PreParser::ParseForStatement(bool* ok) { | 457 PreParser::Statement PreParser::ParseForStatement(bool* ok) { |
458 // ForStatement :: | 458 // ForStatement :: |
459 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 459 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
460 | 460 |
461 Expect(i::Token::FOR, CHECK_OK); | 461 Expect(i::Token::FOR, CHECK_OK); |
462 Expect(i::Token::LPAREN, CHECK_OK); | 462 Expect(i::Token::LPAREN, CHECK_OK); |
463 if (peek() != i::Token::SEMICOLON) { | 463 if (peek() != i::Token::SEMICOLON) { |
464 if (peek() == i::Token::VAR || peek() == i::Token::CONST) { | 464 if (peek() == i::Token::VAR || peek() == i::Token::CONST) { |
465 int decl_count; | 465 int decl_count; |
466 ParseVariableDeclarations(false, &decl_count, CHECK_OK); | 466 ParseVariableDeclarations(false, &decl_count, CHECK_OK); |
467 if (peek() == i::Token::IN && decl_count == 1) { | 467 if (peek() == i::Token::IN && decl_count == 1) { |
(...skipping 28 matching lines...) Expand all Loading... |
496 if (peek() != i::Token::RPAREN) { | 496 if (peek() != i::Token::RPAREN) { |
497 ParseExpression(true, CHECK_OK); | 497 ParseExpression(true, CHECK_OK); |
498 } | 498 } |
499 Expect(i::Token::RPAREN, CHECK_OK); | 499 Expect(i::Token::RPAREN, CHECK_OK); |
500 | 500 |
501 ParseStatement(CHECK_OK); | 501 ParseStatement(CHECK_OK); |
502 return kUnknownStatement; | 502 return kUnknownStatement; |
503 } | 503 } |
504 | 504 |
505 | 505 |
506 Statement PreParser::ParseThrowStatement(bool* ok) { | 506 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) { |
507 // ThrowStatement :: | 507 // ThrowStatement :: |
508 // 'throw' [no line terminator] Expression ';' | 508 // 'throw' [no line terminator] Expression ';' |
509 | 509 |
510 Expect(i::Token::THROW, CHECK_OK); | 510 Expect(i::Token::THROW, CHECK_OK); |
511 if (scanner_->has_line_terminator_before_next()) { | 511 if (scanner_->has_line_terminator_before_next()) { |
512 i::JavaScriptScanner::Location pos = scanner_->location(); | 512 i::JavaScriptScanner::Location pos = scanner_->location(); |
513 ReportMessageAt(pos.beg_pos, pos.end_pos, | 513 ReportMessageAt(pos.beg_pos, pos.end_pos, |
514 "newline_after_throw", NULL); | 514 "newline_after_throw", NULL); |
515 *ok = false; | 515 *ok = false; |
516 return kUnknownStatement; | 516 return kUnknownStatement; |
517 } | 517 } |
518 ParseExpression(true, CHECK_OK); | 518 ParseExpression(true, CHECK_OK); |
519 ExpectSemicolon(CHECK_OK); | 519 ExpectSemicolon(CHECK_OK); |
520 | 520 |
521 return kUnknownStatement; | 521 return kUnknownStatement; |
522 } | 522 } |
523 | 523 |
524 | 524 |
525 Statement PreParser::ParseTryStatement(bool* ok) { | 525 PreParser::Statement PreParser::ParseTryStatement(bool* ok) { |
526 // TryStatement :: | 526 // TryStatement :: |
527 // 'try' Block Catch | 527 // 'try' Block Catch |
528 // 'try' Block Finally | 528 // 'try' Block Finally |
529 // 'try' Block Catch Finally | 529 // 'try' Block Catch Finally |
530 // | 530 // |
531 // Catch :: | 531 // Catch :: |
532 // 'catch' '(' Identifier ')' Block | 532 // 'catch' '(' Identifier ')' Block |
533 // | 533 // |
534 // Finally :: | 534 // Finally :: |
535 // 'finally' Block | 535 // 'finally' Block |
(...skipping 22 matching lines...) Expand all Loading... |
558 ParseBlock(CHECK_OK); | 558 ParseBlock(CHECK_OK); |
559 catch_or_finally_seen = true; | 559 catch_or_finally_seen = true; |
560 } | 560 } |
561 if (!catch_or_finally_seen) { | 561 if (!catch_or_finally_seen) { |
562 *ok = false; | 562 *ok = false; |
563 } | 563 } |
564 return kUnknownStatement; | 564 return kUnknownStatement; |
565 } | 565 } |
566 | 566 |
567 | 567 |
568 Statement PreParser::ParseDebuggerStatement(bool* ok) { | 568 PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) { |
569 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser | 569 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser |
570 // contexts this is used as a statement which invokes the debugger as if a | 570 // contexts this is used as a statement which invokes the debugger as if a |
571 // break point is present. | 571 // break point is present. |
572 // DebuggerStatement :: | 572 // DebuggerStatement :: |
573 // 'debugger' ';' | 573 // 'debugger' ';' |
574 | 574 |
575 Expect(i::Token::DEBUGGER, CHECK_OK); | 575 Expect(i::Token::DEBUGGER, CHECK_OK); |
576 ExpectSemicolon(CHECK_OK); | 576 ExpectSemicolon(CHECK_OK); |
577 return kUnknownStatement; | 577 return kUnknownStatement; |
578 } | 578 } |
579 | 579 |
580 | 580 |
581 // Precedence = 1 | 581 // Precedence = 1 |
582 Expression PreParser::ParseExpression(bool accept_IN, bool* ok) { | 582 PreParser::Expression PreParser::ParseExpression(bool accept_IN, bool* ok) { |
583 // Expression :: | 583 // Expression :: |
584 // AssignmentExpression | 584 // AssignmentExpression |
585 // Expression ',' AssignmentExpression | 585 // Expression ',' AssignmentExpression |
586 | 586 |
587 Expression result = ParseAssignmentExpression(accept_IN, CHECK_OK); | 587 Expression result = ParseAssignmentExpression(accept_IN, CHECK_OK); |
588 while (peek() == i::Token::COMMA) { | 588 while (peek() == i::Token::COMMA) { |
589 Expect(i::Token::COMMA, CHECK_OK); | 589 Expect(i::Token::COMMA, CHECK_OK); |
590 ParseAssignmentExpression(accept_IN, CHECK_OK); | 590 ParseAssignmentExpression(accept_IN, CHECK_OK); |
591 result = kUnknownExpression; | 591 result = kUnknownExpression; |
592 } | 592 } |
593 return result; | 593 return result; |
594 } | 594 } |
595 | 595 |
596 | 596 |
597 // Precedence = 2 | 597 // Precedence = 2 |
598 Expression PreParser::ParseAssignmentExpression(bool accept_IN, | 598 PreParser::Expression PreParser::ParseAssignmentExpression(bool accept_IN, |
599 bool* ok) { | 599 bool* ok) { |
600 // AssignmentExpression :: | 600 // AssignmentExpression :: |
601 // ConditionalExpression | 601 // ConditionalExpression |
602 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 602 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
603 | 603 |
604 Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK); | 604 Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK); |
605 | 605 |
606 if (!i::Token::IsAssignmentOp(peek())) { | 606 if (!i::Token::IsAssignmentOp(peek())) { |
607 // Parsed conditional expression only (no assignment). | 607 // Parsed conditional expression only (no assignment). |
608 return expression; | 608 return expression; |
609 } | 609 } |
610 | 610 |
611 i::Token::Value op = Next(); // Get assignment operator. | 611 i::Token::Value op = Next(); // Get assignment operator. |
612 ParseAssignmentExpression(accept_IN, CHECK_OK); | 612 ParseAssignmentExpression(accept_IN, CHECK_OK); |
613 | 613 |
614 if ((op == i::Token::ASSIGN) && (expression == kThisPropertyExpression)) { | 614 if ((op == i::Token::ASSIGN) && (expression == kThisPropertyExpression)) { |
615 scope_->AddProperty(); | 615 scope_->AddProperty(); |
616 } | 616 } |
617 | 617 |
618 return kUnknownExpression; | 618 return kUnknownExpression; |
619 } | 619 } |
620 | 620 |
621 | 621 |
622 // Precedence = 3 | 622 // Precedence = 3 |
623 Expression PreParser::ParseConditionalExpression(bool accept_IN, | 623 PreParser::Expression PreParser::ParseConditionalExpression(bool accept_IN, |
624 bool* ok) { | 624 bool* ok) { |
625 // ConditionalExpression :: | 625 // ConditionalExpression :: |
626 // LogicalOrExpression | 626 // LogicalOrExpression |
627 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression | 627 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
628 | 628 |
629 // We start using the binary expression parser for prec >= 4 only! | 629 // We start using the binary expression parser for prec >= 4 only! |
630 Expression expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); | 630 Expression expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); |
631 if (peek() != i::Token::CONDITIONAL) return expression; | 631 if (peek() != i::Token::CONDITIONAL) return expression; |
632 Consume(i::Token::CONDITIONAL); | 632 Consume(i::Token::CONDITIONAL); |
633 // In parsing the first assignment expression in conditional | 633 // In parsing the first assignment expression in conditional |
634 // expressions we always accept the 'in' keyword; see ECMA-262, | 634 // expressions we always accept the 'in' keyword; see ECMA-262, |
635 // section 11.12, page 58. | 635 // section 11.12, page 58. |
636 ParseAssignmentExpression(true, CHECK_OK); | 636 ParseAssignmentExpression(true, CHECK_OK); |
637 Expect(i::Token::COLON, CHECK_OK); | 637 Expect(i::Token::COLON, CHECK_OK); |
638 ParseAssignmentExpression(accept_IN, CHECK_OK); | 638 ParseAssignmentExpression(accept_IN, CHECK_OK); |
639 return kUnknownExpression; | 639 return kUnknownExpression; |
640 } | 640 } |
641 | 641 |
642 | 642 |
643 int PreParser::Precedence(i::Token::Value tok, bool accept_IN) { | 643 int PreParser::Precedence(i::Token::Value tok, bool accept_IN) { |
644 if (tok == i::Token::IN && !accept_IN) | 644 if (tok == i::Token::IN && !accept_IN) |
645 return 0; // 0 precedence will terminate binary expression parsing | 645 return 0; // 0 precedence will terminate binary expression parsing |
646 | 646 |
647 return i::Token::Precedence(tok); | 647 return i::Token::Precedence(tok); |
648 } | 648 } |
649 | 649 |
650 | 650 |
651 // Precedence >= 4 | 651 // Precedence >= 4 |
652 Expression PreParser::ParseBinaryExpression(int prec, | 652 PreParser::Expression PreParser::ParseBinaryExpression(int prec, |
653 bool accept_IN, | 653 bool accept_IN, |
654 bool* ok) { | 654 bool* ok) { |
655 Expression result = ParseUnaryExpression(CHECK_OK); | 655 Expression result = ParseUnaryExpression(CHECK_OK); |
656 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | 656 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
657 // prec1 >= 4 | 657 // prec1 >= 4 |
658 while (Precedence(peek(), accept_IN) == prec1) { | 658 while (Precedence(peek(), accept_IN) == prec1) { |
659 Next(); | 659 Next(); |
660 ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); | 660 ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); |
661 result = kUnknownExpression; | 661 result = kUnknownExpression; |
662 } | 662 } |
663 } | 663 } |
664 return result; | 664 return result; |
665 } | 665 } |
666 | 666 |
667 | 667 |
668 Expression PreParser::ParseUnaryExpression(bool* ok) { | 668 PreParser::Expression PreParser::ParseUnaryExpression(bool* ok) { |
669 // UnaryExpression :: | 669 // UnaryExpression :: |
670 // PostfixExpression | 670 // PostfixExpression |
671 // 'delete' UnaryExpression | 671 // 'delete' UnaryExpression |
672 // 'void' UnaryExpression | 672 // 'void' UnaryExpression |
673 // 'typeof' UnaryExpression | 673 // 'typeof' UnaryExpression |
674 // '++' UnaryExpression | 674 // '++' UnaryExpression |
675 // '--' UnaryExpression | 675 // '--' UnaryExpression |
676 // '+' UnaryExpression | 676 // '+' UnaryExpression |
677 // '-' UnaryExpression | 677 // '-' UnaryExpression |
678 // '~' UnaryExpression | 678 // '~' UnaryExpression |
679 // '!' UnaryExpression | 679 // '!' UnaryExpression |
680 | 680 |
681 i::Token::Value op = peek(); | 681 i::Token::Value op = peek(); |
682 if (i::Token::IsUnaryOp(op) || i::Token::IsCountOp(op)) { | 682 if (i::Token::IsUnaryOp(op) || i::Token::IsCountOp(op)) { |
683 op = Next(); | 683 op = Next(); |
684 ParseUnaryExpression(ok); | 684 ParseUnaryExpression(ok); |
685 return kUnknownExpression; | 685 return kUnknownExpression; |
686 } else { | 686 } else { |
687 return ParsePostfixExpression(ok); | 687 return ParsePostfixExpression(ok); |
688 } | 688 } |
689 } | 689 } |
690 | 690 |
691 | 691 |
692 Expression PreParser::ParsePostfixExpression(bool* ok) { | 692 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) { |
693 // PostfixExpression :: | 693 // PostfixExpression :: |
694 // LeftHandSideExpression ('++' | '--')? | 694 // LeftHandSideExpression ('++' | '--')? |
695 | 695 |
696 Expression expression = ParseLeftHandSideExpression(CHECK_OK); | 696 Expression expression = ParseLeftHandSideExpression(CHECK_OK); |
697 if (!scanner_->has_line_terminator_before_next() && | 697 if (!scanner_->has_line_terminator_before_next() && |
698 i::Token::IsCountOp(peek())) { | 698 i::Token::IsCountOp(peek())) { |
699 Next(); | 699 Next(); |
700 return kUnknownExpression; | 700 return kUnknownExpression; |
701 } | 701 } |
702 return expression; | 702 return expression; |
703 } | 703 } |
704 | 704 |
705 | 705 |
706 Expression PreParser::ParseLeftHandSideExpression(bool* ok) { | 706 PreParser::Expression PreParser::ParseLeftHandSideExpression(bool* ok) { |
707 // LeftHandSideExpression :: | 707 // LeftHandSideExpression :: |
708 // (NewExpression | MemberExpression) ... | 708 // (NewExpression | MemberExpression) ... |
709 | 709 |
710 Expression result; | 710 Expression result; |
711 if (peek() == i::Token::NEW) { | 711 if (peek() == i::Token::NEW) { |
712 result = ParseNewExpression(CHECK_OK); | 712 result = ParseNewExpression(CHECK_OK); |
713 } else { | 713 } else { |
714 result = ParseMemberExpression(CHECK_OK); | 714 result = ParseMemberExpression(CHECK_OK); |
715 } | 715 } |
716 | 716 |
(...skipping 28 matching lines...) Expand all Loading... |
745 break; | 745 break; |
746 } | 746 } |
747 | 747 |
748 default: | 748 default: |
749 return result; | 749 return result; |
750 } | 750 } |
751 } | 751 } |
752 } | 752 } |
753 | 753 |
754 | 754 |
755 Expression PreParser::ParseNewExpression(bool* ok) { | 755 PreParser::Expression PreParser::ParseNewExpression(bool* ok) { |
756 // NewExpression :: | 756 // NewExpression :: |
757 // ('new')+ MemberExpression | 757 // ('new')+ MemberExpression |
758 | 758 |
759 // The grammar for new expressions is pretty warped. The keyword | 759 // The grammar for new expressions is pretty warped. The keyword |
760 // 'new' can either be a part of the new expression (where it isn't | 760 // 'new' can either be a part of the new expression (where it isn't |
761 // followed by an argument list) or a part of the member expression, | 761 // followed by an argument list) or a part of the member expression, |
762 // where it must be followed by an argument list. To accommodate | 762 // where it must be followed by an argument list. To accommodate |
763 // this, we parse the 'new' keywords greedily and keep track of how | 763 // this, we parse the 'new' keywords greedily and keep track of how |
764 // many we have parsed. This information is then passed on to the | 764 // many we have parsed. This information is then passed on to the |
765 // member expression parser, which is only allowed to match argument | 765 // member expression parser, which is only allowed to match argument |
766 // lists as long as it has 'new' prefixes left | 766 // lists as long as it has 'new' prefixes left |
767 unsigned new_count = 0; | 767 unsigned new_count = 0; |
768 do { | 768 do { |
769 Consume(i::Token::NEW); | 769 Consume(i::Token::NEW); |
770 new_count++; | 770 new_count++; |
771 } while (peek() == i::Token::NEW); | 771 } while (peek() == i::Token::NEW); |
772 | 772 |
773 return ParseMemberWithNewPrefixesExpression(new_count, ok); | 773 return ParseMemberWithNewPrefixesExpression(new_count, ok); |
774 } | 774 } |
775 | 775 |
776 | 776 |
777 Expression PreParser::ParseMemberExpression(bool* ok) { | 777 PreParser::Expression PreParser::ParseMemberExpression(bool* ok) { |
778 return ParseMemberWithNewPrefixesExpression(0, ok); | 778 return ParseMemberWithNewPrefixesExpression(0, ok); |
779 } | 779 } |
780 | 780 |
781 | 781 |
782 Expression PreParser::ParseMemberWithNewPrefixesExpression( | 782 PreParser::Expression PreParser::ParseMemberWithNewPrefixesExpression( |
783 unsigned new_count, bool* ok) { | 783 unsigned new_count, bool* ok) { |
784 // MemberExpression :: | 784 // MemberExpression :: |
785 // (PrimaryExpression | FunctionLiteral) | 785 // (PrimaryExpression | FunctionLiteral) |
786 // ('[' Expression ']' | '.' Identifier | Arguments)* | 786 // ('[' Expression ']' | '.' Identifier | Arguments)* |
787 | 787 |
788 // Parse the initial primary or function expression. | 788 // Parse the initial primary or function expression. |
789 Expression result = kUnknownExpression; | 789 Expression result = kUnknownExpression; |
790 if (peek() == i::Token::FUNCTION) { | 790 if (peek() == i::Token::FUNCTION) { |
791 Consume(i::Token::FUNCTION); | 791 Consume(i::Token::FUNCTION); |
792 if (peek() == i::Token::IDENTIFIER) { | 792 if (peek() == i::Token::IDENTIFIER) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
828 result = kUnknownExpression; | 828 result = kUnknownExpression; |
829 break; | 829 break; |
830 } | 830 } |
831 default: | 831 default: |
832 return result; | 832 return result; |
833 } | 833 } |
834 } | 834 } |
835 } | 835 } |
836 | 836 |
837 | 837 |
838 Expression PreParser::ParsePrimaryExpression(bool* ok) { | 838 PreParser::Expression PreParser::ParsePrimaryExpression(bool* ok) { |
839 // PrimaryExpression :: | 839 // PrimaryExpression :: |
840 // 'this' | 840 // 'this' |
841 // 'null' | 841 // 'null' |
842 // 'true' | 842 // 'true' |
843 // 'false' | 843 // 'false' |
844 // Identifier | 844 // Identifier |
845 // Number | 845 // Number |
846 // String | 846 // String |
847 // ArrayLiteral | 847 // ArrayLiteral |
848 // ObjectLiteral | 848 // ObjectLiteral |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
907 Next(); | 907 Next(); |
908 *ok = false; | 908 *ok = false; |
909 return kUnknownExpression; | 909 return kUnknownExpression; |
910 } | 910 } |
911 } | 911 } |
912 | 912 |
913 return result; | 913 return result; |
914 } | 914 } |
915 | 915 |
916 | 916 |
917 Expression PreParser::ParseArrayLiteral(bool* ok) { | 917 PreParser::Expression PreParser::ParseArrayLiteral(bool* ok) { |
918 // ArrayLiteral :: | 918 // ArrayLiteral :: |
919 // '[' Expression? (',' Expression?)* ']' | 919 // '[' Expression? (',' Expression?)* ']' |
920 Expect(i::Token::LBRACK, CHECK_OK); | 920 Expect(i::Token::LBRACK, CHECK_OK); |
921 while (peek() != i::Token::RBRACK) { | 921 while (peek() != i::Token::RBRACK) { |
922 if (peek() != i::Token::COMMA) { | 922 if (peek() != i::Token::COMMA) { |
923 ParseAssignmentExpression(true, CHECK_OK); | 923 ParseAssignmentExpression(true, CHECK_OK); |
924 } | 924 } |
925 if (peek() != i::Token::RBRACK) { | 925 if (peek() != i::Token::RBRACK) { |
926 Expect(i::Token::COMMA, CHECK_OK); | 926 Expect(i::Token::COMMA, CHECK_OK); |
927 } | 927 } |
928 } | 928 } |
929 Expect(i::Token::RBRACK, CHECK_OK); | 929 Expect(i::Token::RBRACK, CHECK_OK); |
930 | 930 |
931 scope_->NextMaterializedLiteralIndex(); | 931 scope_->NextMaterializedLiteralIndex(); |
932 return kUnknownExpression; | 932 return kUnknownExpression; |
933 } | 933 } |
934 | 934 |
935 | 935 |
936 Expression PreParser::ParseObjectLiteral(bool* ok) { | 936 PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) { |
937 // ObjectLiteral :: | 937 // ObjectLiteral :: |
938 // '{' ( | 938 // '{' ( |
939 // ((IdentifierName | String | Number) ':' AssignmentExpression) | 939 // ((IdentifierName | String | Number) ':' AssignmentExpression) |
940 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) | 940 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) |
941 // )*[','] '}' | 941 // )*[','] '}' |
942 | 942 |
943 Expect(i::Token::LBRACE, CHECK_OK); | 943 Expect(i::Token::LBRACE, CHECK_OK); |
944 while (peek() != i::Token::RBRACE) { | 944 while (peek() != i::Token::RBRACE) { |
945 i::Token::Value next = peek(); | 945 i::Token::Value next = peek(); |
946 switch (next) { | 946 switch (next) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
988 // TODO(1240767): Consider allowing trailing comma. | 988 // TODO(1240767): Consider allowing trailing comma. |
989 if (peek() != i::Token::RBRACE) Expect(i::Token::COMMA, CHECK_OK); | 989 if (peek() != i::Token::RBRACE) Expect(i::Token::COMMA, CHECK_OK); |
990 } | 990 } |
991 Expect(i::Token::RBRACE, CHECK_OK); | 991 Expect(i::Token::RBRACE, CHECK_OK); |
992 | 992 |
993 scope_->NextMaterializedLiteralIndex(); | 993 scope_->NextMaterializedLiteralIndex(); |
994 return kUnknownExpression; | 994 return kUnknownExpression; |
995 } | 995 } |
996 | 996 |
997 | 997 |
998 Expression PreParser::ParseRegExpLiteral(bool seen_equal, | 998 PreParser::Expression PreParser::ParseRegExpLiteral(bool seen_equal, |
999 bool* ok) { | 999 bool* ok) { |
1000 if (!scanner_->ScanRegExpPattern(seen_equal)) { | 1000 if (!scanner_->ScanRegExpPattern(seen_equal)) { |
1001 Next(); | 1001 Next(); |
1002 i::JavaScriptScanner::Location location = scanner_->location(); | 1002 i::JavaScriptScanner::Location location = scanner_->location(); |
1003 ReportMessageAt(location.beg_pos, location.end_pos, | 1003 ReportMessageAt(location.beg_pos, location.end_pos, |
1004 "unterminated_regexp", NULL); | 1004 "unterminated_regexp", NULL); |
1005 *ok = false; | 1005 *ok = false; |
1006 return kUnknownExpression; | 1006 return kUnknownExpression; |
1007 } | 1007 } |
1008 | 1008 |
1009 scope_->NextMaterializedLiteralIndex(); | 1009 scope_->NextMaterializedLiteralIndex(); |
1010 | 1010 |
1011 if (!scanner_->ScanRegExpFlags()) { | 1011 if (!scanner_->ScanRegExpFlags()) { |
1012 Next(); | 1012 Next(); |
1013 i::JavaScriptScanner::Location location = scanner_->location(); | 1013 i::JavaScriptScanner::Location location = scanner_->location(); |
1014 ReportMessageAt(location.beg_pos, location.end_pos, | 1014 ReportMessageAt(location.beg_pos, location.end_pos, |
1015 "invalid_regexp_flags", NULL); | 1015 "invalid_regexp_flags", NULL); |
1016 *ok = false; | 1016 *ok = false; |
1017 return kUnknownExpression; | 1017 return kUnknownExpression; |
1018 } | 1018 } |
1019 Next(); | 1019 Next(); |
1020 return kUnknownExpression; | 1020 return kUnknownExpression; |
1021 } | 1021 } |
1022 | 1022 |
1023 | 1023 |
1024 Arguments PreParser::ParseArguments(bool* ok) { | 1024 PreParser::Arguments PreParser::ParseArguments(bool* ok) { |
1025 // Arguments :: | 1025 // Arguments :: |
1026 // '(' (AssignmentExpression)*[','] ')' | 1026 // '(' (AssignmentExpression)*[','] ')' |
1027 | 1027 |
1028 Expect(i::Token::LPAREN, CHECK_OK); | 1028 Expect(i::Token::LPAREN, CHECK_OK); |
1029 bool done = (peek() == i::Token::RPAREN); | 1029 bool done = (peek() == i::Token::RPAREN); |
1030 int argc = 0; | 1030 int argc = 0; |
1031 while (!done) { | 1031 while (!done) { |
1032 ParseAssignmentExpression(true, CHECK_OK); | 1032 ParseAssignmentExpression(true, CHECK_OK); |
1033 argc++; | 1033 argc++; |
1034 done = (peek() == i::Token::RPAREN); | 1034 done = (peek() == i::Token::RPAREN); |
1035 if (!done) Expect(i::Token::COMMA, CHECK_OK); | 1035 if (!done) Expect(i::Token::COMMA, CHECK_OK); |
1036 } | 1036 } |
1037 Expect(i::Token::RPAREN, CHECK_OK); | 1037 Expect(i::Token::RPAREN, CHECK_OK); |
1038 return argc; | 1038 return argc; |
1039 } | 1039 } |
1040 | 1040 |
1041 | 1041 |
1042 Expression PreParser::ParseFunctionLiteral(bool* ok) { | 1042 PreParser::Expression PreParser::ParseFunctionLiteral(bool* ok) { |
1043 // Function :: | 1043 // Function :: |
1044 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 1044 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
1045 | 1045 |
1046 // Parse function body. | 1046 // Parse function body. |
1047 ScopeType outer_scope_type = scope_->type(); | 1047 ScopeType outer_scope_type = scope_->type(); |
1048 bool inside_with = scope_->IsInsideWith(); | 1048 bool inside_with = scope_->IsInsideWith(); |
1049 Scope function_scope(&scope_, kFunctionScope); | 1049 Scope function_scope(&scope_, kFunctionScope); |
1050 | 1050 |
1051 // FormalParameterList :: | 1051 // FormalParameterList :: |
1052 // '(' (Identifier)*[','] ')' | 1052 // '(' (Identifier)*[','] ')' |
(...skipping 30 matching lines...) Expand all Loading... |
1083 function_scope.materialized_literal_count(), | 1083 function_scope.materialized_literal_count(), |
1084 function_scope.expected_properties()); | 1084 function_scope.expected_properties()); |
1085 } else { | 1085 } else { |
1086 ParseSourceElements(i::Token::RBRACE, CHECK_OK); | 1086 ParseSourceElements(i::Token::RBRACE, CHECK_OK); |
1087 Expect(i::Token::RBRACE, CHECK_OK); | 1087 Expect(i::Token::RBRACE, CHECK_OK); |
1088 } | 1088 } |
1089 return kUnknownExpression; | 1089 return kUnknownExpression; |
1090 } | 1090 } |
1091 | 1091 |
1092 | 1092 |
1093 Expression PreParser::ParseV8Intrinsic(bool* ok) { | 1093 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { |
1094 // CallRuntime :: | 1094 // CallRuntime :: |
1095 // '%' Identifier Arguments | 1095 // '%' Identifier Arguments |
1096 | 1096 |
1097 Expect(i::Token::MOD, CHECK_OK); | 1097 Expect(i::Token::MOD, CHECK_OK); |
1098 ParseIdentifier(CHECK_OK); | 1098 ParseIdentifier(CHECK_OK); |
1099 ParseArguments(CHECK_OK); | 1099 ParseArguments(CHECK_OK); |
1100 | 1100 |
1101 return kUnknownExpression; | 1101 return kUnknownExpression; |
1102 } | 1102 } |
1103 | 1103 |
1104 | 1104 |
1105 void PreParser::ExpectSemicolon(bool* ok) { | 1105 void PreParser::ExpectSemicolon(bool* ok) { |
1106 // Check for automatic semicolon insertion according to | 1106 // Check for automatic semicolon insertion according to |
1107 // the rules given in ECMA-262, section 7.9, page 21. | 1107 // the rules given in ECMA-262, section 7.9, page 21. |
1108 i::Token::Value tok = peek(); | 1108 i::Token::Value tok = peek(); |
1109 if (tok == i::Token::SEMICOLON) { | 1109 if (tok == i::Token::SEMICOLON) { |
1110 Next(); | 1110 Next(); |
1111 return; | 1111 return; |
1112 } | 1112 } |
1113 if (scanner_->has_line_terminator_before_next() || | 1113 if (scanner_->has_line_terminator_before_next() || |
1114 tok == i::Token::RBRACE || | 1114 tok == i::Token::RBRACE || |
1115 tok == i::Token::EOS) { | 1115 tok == i::Token::EOS) { |
1116 return; | 1116 return; |
1117 } | 1117 } |
1118 Expect(i::Token::SEMICOLON, ok); | 1118 Expect(i::Token::SEMICOLON, ok); |
1119 } | 1119 } |
1120 | 1120 |
1121 | 1121 |
1122 Identifier PreParser::GetIdentifierSymbol() { | 1122 PreParser::Identifier PreParser::GetIdentifierSymbol() { |
1123 const char* literal_chars = scanner_->literal_string(); | 1123 const char* literal_chars = scanner_->literal_string(); |
1124 int literal_length = scanner_->literal_length(); | 1124 int literal_length = scanner_->literal_length(); |
1125 int identifier_pos = scanner_->location().beg_pos; | 1125 int identifier_pos = scanner_->location().beg_pos; |
1126 | 1126 |
1127 log_->LogSymbol(identifier_pos, literal_chars, literal_length); | 1127 log_->LogSymbol(identifier_pos, literal_chars, literal_length); |
1128 | 1128 |
1129 return kUnknownExpression; | 1129 return kUnknownExpression; |
1130 } | 1130 } |
1131 | 1131 |
1132 | 1132 |
1133 Expression PreParser::GetStringSymbol() { | 1133 PreParser::Expression PreParser::GetStringSymbol() { |
1134 const char* literal_chars = scanner_->literal_string(); | 1134 const char* literal_chars = scanner_->literal_string(); |
1135 int literal_length = scanner_->literal_length(); | 1135 int literal_length = scanner_->literal_length(); |
1136 | 1136 |
1137 int literal_position = scanner_->location().beg_pos; | 1137 int literal_position = scanner_->location().beg_pos; |
1138 log_->LogSymbol(literal_position, literal_chars, literal_length); | 1138 log_->LogSymbol(literal_position, literal_chars, literal_length); |
1139 | 1139 |
1140 return kUnknownExpression; | 1140 return kUnknownExpression; |
1141 } | 1141 } |
1142 | 1142 |
1143 | 1143 |
1144 Identifier PreParser::ParseIdentifier(bool* ok) { | 1144 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) { |
1145 Expect(i::Token::IDENTIFIER, ok); | 1145 Expect(i::Token::IDENTIFIER, ok); |
1146 if (!*ok) return kUnknownIdentifier; | 1146 if (!*ok) return kUnknownIdentifier; |
1147 return GetIdentifierSymbol(); | 1147 return GetIdentifierSymbol(); |
1148 } | 1148 } |
1149 | 1149 |
1150 | 1150 |
1151 Identifier PreParser::ParseIdentifierName(bool* ok) { | 1151 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) { |
1152 i::Token::Value next = Next(); | 1152 i::Token::Value next = Next(); |
1153 if (i::Token::IsKeyword(next)) { | 1153 if (i::Token::IsKeyword(next)) { |
1154 int pos = scanner_->location().beg_pos; | 1154 int pos = scanner_->location().beg_pos; |
1155 const char* keyword = i::Token::String(next); | 1155 const char* keyword = i::Token::String(next); |
1156 log_->LogSymbol(pos, keyword, i::StrLength(keyword)); | 1156 log_->LogSymbol(pos, keyword, i::StrLength(keyword)); |
1157 return kUnknownExpression; | 1157 return kUnknownExpression; |
1158 } | 1158 } |
1159 if (next == i::Token::IDENTIFIER) { | 1159 if (next == i::Token::IDENTIFIER) { |
1160 return GetIdentifierSymbol(); | 1160 return GetIdentifierSymbol(); |
1161 } | 1161 } |
1162 *ok = false; | 1162 *ok = false; |
1163 return kUnknownIdentifier; | 1163 return kUnknownIdentifier; |
1164 } | 1164 } |
1165 | 1165 |
1166 | 1166 |
1167 // This function reads an identifier and determines whether or not it | 1167 // This function reads an identifier and determines whether or not it |
1168 // is 'get' or 'set'. The reason for not using ParseIdentifier and | 1168 // is 'get' or 'set'. The reason for not using ParseIdentifier and |
1169 // checking on the output is that this involves heap allocation which | 1169 // checking on the output is that this involves heap allocation which |
1170 // we can't do during preparsing. | 1170 // we can't do during preparsing. |
1171 Identifier PreParser::ParseIdentifierOrGetOrSet(bool* is_get, | 1171 PreParser::Identifier PreParser::ParseIdentifierOrGetOrSet(bool* is_get, |
1172 bool* is_set, | 1172 bool* is_set, |
1173 bool* ok) { | 1173 bool* ok) { |
1174 Expect(i::Token::IDENTIFIER, CHECK_OK); | 1174 Expect(i::Token::IDENTIFIER, CHECK_OK); |
1175 if (scanner_->literal_length() == 3) { | 1175 if (scanner_->literal_length() == 3) { |
1176 const char* token = scanner_->literal_string(); | 1176 const char* token = scanner_->literal_string(); |
1177 *is_get = strncmp(token, "get", 3) == 0; | 1177 *is_get = strncmp(token, "get", 3) == 0; |
1178 *is_set = !*is_get && strncmp(token, "set", 3) == 0; | 1178 *is_set = !*is_get && strncmp(token, "set", 3) == 0; |
1179 } | 1179 } |
1180 return GetIdentifierSymbol(); | 1180 return GetIdentifierSymbol(); |
1181 } | 1181 } |
1182 | 1182 |
1183 #undef CHECK_OK | 1183 #undef CHECK_OK |
1184 } } // v8::preparser | 1184 } } // v8::preparser |
OLD | NEW |