Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Side by Side Diff: src/parser.cc

Issue 168583008: (Pre)Parser: Simplify NewExpression handling (fixed). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: one more comment Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 28 matching lines...) Expand all
39 #include "platform.h" 39 #include "platform.h"
40 #include "preparser.h" 40 #include "preparser.h"
41 #include "runtime.h" 41 #include "runtime.h"
42 #include "scanner-character-streams.h" 42 #include "scanner-character-streams.h"
43 #include "scopeinfo.h" 43 #include "scopeinfo.h"
44 #include "string-stream.h" 44 #include "string-stream.h"
45 45
46 namespace v8 { 46 namespace v8 {
47 namespace internal { 47 namespace internal {
48 48
49 // PositionStack is used for on-stack allocation of token positions for
50 // new expressions. Please look at ParseNewExpression.
51
52 class PositionStack {
53 public:
54 explicit PositionStack(bool* ok) : top_(NULL), ok_(ok) {}
55 ~PositionStack() {
56 ASSERT(!*ok_ || is_empty());
57 USE(ok_);
58 }
59
60 class Element {
61 public:
62 Element(PositionStack* stack, int value) {
63 previous_ = stack->top();
64 value_ = value;
65 stack->set_top(this);
66 }
67
68 private:
69 Element* previous() { return previous_; }
70 int value() { return value_; }
71 friend class PositionStack;
72 Element* previous_;
73 int value_;
74 };
75
76 bool is_empty() { return top_ == NULL; }
77 int pop() {
78 ASSERT(!is_empty());
79 int result = top_->value();
80 top_ = top_->previous();
81 return result;
82 }
83
84 private:
85 Element* top() { return top_; }
86 void set_top(Element* value) { top_ = value; }
87 Element* top_;
88 bool* ok_;
89 };
90
91
92 RegExpBuilder::RegExpBuilder(Zone* zone) 49 RegExpBuilder::RegExpBuilder(Zone* zone)
93 : zone_(zone), 50 : zone_(zone),
94 pending_empty_(false), 51 pending_empty_(false),
95 characters_(NULL), 52 characters_(NULL),
96 terms_(), 53 terms_(),
97 alternatives_() 54 alternatives_()
98 #ifdef DEBUG 55 #ifdef DEBUG
99 , last_added_(ADD_NONE) 56 , last_added_(ADD_NONE)
100 #endif 57 #endif
101 {} 58 {}
(...skipping 3183 matching lines...) Expand 10 before | Expand all | Expand 10 after
3285 position()); 3242 position());
3286 } 3243 }
3287 return expression; 3244 return expression;
3288 } 3245 }
3289 3246
3290 3247
3291 Expression* Parser::ParseLeftHandSideExpression(bool* ok) { 3248 Expression* Parser::ParseLeftHandSideExpression(bool* ok) {
3292 // LeftHandSideExpression :: 3249 // LeftHandSideExpression ::
3293 // (NewExpression | MemberExpression) ... 3250 // (NewExpression | MemberExpression) ...
3294 3251
3295 Expression* result; 3252 Expression* result = ParseMemberWithNewPrefixesExpression(CHECK_OK);
3296 if (peek() == Token::NEW) {
3297 result = ParseNewExpression(CHECK_OK);
3298 } else {
3299 result = ParseMemberExpression(CHECK_OK);
3300 }
3301 3253
3302 while (true) { 3254 while (true) {
3303 switch (peek()) { 3255 switch (peek()) {
3304 case Token::LBRACK: { 3256 case Token::LBRACK: {
3305 Consume(Token::LBRACK); 3257 Consume(Token::LBRACK);
3306 int pos = position(); 3258 int pos = position();
3307 Expression* index = ParseExpression(true, CHECK_OK); 3259 Expression* index = ParseExpression(true, CHECK_OK);
3308 result = factory()->NewProperty(result, index, pos); 3260 result = factory()->NewProperty(result, index, pos);
3309 Expect(Token::RBRACK, CHECK_OK); 3261 Expect(Token::RBRACK, CHECK_OK);
3310 break; 3262 break;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
3359 break; 3311 break;
3360 } 3312 }
3361 3313
3362 default: 3314 default:
3363 return result; 3315 return result;
3364 } 3316 }
3365 } 3317 }
3366 } 3318 }
3367 3319
3368 3320
3369 Expression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) { 3321 Expression* Parser::ParseMemberWithNewPrefixesExpression(bool* ok) {
3370 // NewExpression :: 3322 // NewExpression ::
3371 // ('new')+ MemberExpression 3323 // ('new')+ MemberExpression
3372 3324
3373 // The grammar for new expressions is pretty warped. The keyword 3325 // The grammar for new expressions is pretty warped. We can have several 'new'
3374 // 'new' can either be a part of the new expression (where it isn't 3326 // keywords following each other, and then a MemberExpression. When we see '('
3375 // followed by an argument list) or a part of the member expression, 3327 // after the MemberExpression, it's associated with the rightmost unassociated
3376 // where it must be followed by an argument list. To accommodate 3328 // 'new' to create a NewExpression with arguments. However, a NewExpression
3377 // this, we parse the 'new' keywords greedily and keep track of how 3329 // can also occur without arguments.
3378 // many we have parsed. This information is then passed on to the
3379 // member expression parser, which is only allowed to match argument
3380 // lists as long as it has 'new' prefixes left
3381 Expect(Token::NEW, CHECK_OK);
3382 PositionStack::Element pos(stack, position());
3383 3330
3384 Expression* result; 3331 // Examples of new expression:
3332 // new foo.bar().baz means (new (foo.bar)()).baz
3333 // new foo()() means (new foo())()
3334 // new new foo()() means (new (new foo())())
3335 // new new foo means new (new foo)
3336 // new new foo() means new (new foo())
3337 // new new foo().bar().baz means (new (new foo()).bar()).baz
3338
3385 if (peek() == Token::NEW) { 3339 if (peek() == Token::NEW) {
3386 result = ParseNewPrefix(stack, CHECK_OK); 3340 Consume(Token::NEW);
3387 } else { 3341 int new_pos = position();
3388 result = ParseMemberWithNewPrefixesExpression(stack, CHECK_OK); 3342 Expression* result = ParseMemberWithNewPrefixesExpression(CHECK_OK);
3343 if (peek() == Token::LPAREN) {
3344 // NewExpression with arguments.
3345 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
3346 result = factory()->NewCallNew(result, args, new_pos);
3347 // The expression can still continue with . or [ after the arguments.
3348 result = ParseMemberExpressionContinuation(result, CHECK_OK);
3349 return result;
3350 }
3351 // NewExpression without arguments.
3352 return factory()->NewCallNew(
3353 result, new(zone()) ZoneList<Expression*>(0, zone()), new_pos);
3389 } 3354 }
3390 3355 // No 'new' keyword.
3391 if (!stack->is_empty()) { 3356 return ParseMemberExpression(ok);
3392 int last = stack->pop();
3393 result = factory()->NewCallNew(
3394 result, new(zone()) ZoneList<Expression*>(0, zone()), last);
3395 }
3396 return result;
3397 }
3398
3399
3400 Expression* Parser::ParseNewExpression(bool* ok) {
3401 PositionStack stack(ok);
3402 return ParseNewPrefix(&stack, ok);
3403 } 3357 }
3404 3358
3405 3359
3406 Expression* Parser::ParseMemberExpression(bool* ok) { 3360 Expression* Parser::ParseMemberExpression(bool* ok) {
3407 return ParseMemberWithNewPrefixesExpression(NULL, ok);
3408 }
3409
3410
3411 Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack,
3412 bool* ok) {
3413 // MemberExpression :: 3361 // MemberExpression ::
3414 // (PrimaryExpression | FunctionLiteral) 3362 // (PrimaryExpression | FunctionLiteral)
3415 // ('[' Expression ']' | '.' Identifier | Arguments)* 3363 // ('[' Expression ']' | '.' Identifier | Arguments)*
3416 3364
3365 // The '[' Expression ']' and '.' Identifier parts are parsed by
3366 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the
3367 // caller.
3368
3417 // Parse the initial primary or function expression. 3369 // Parse the initial primary or function expression.
3418 Expression* result = NULL; 3370 Expression* result = NULL;
3419 if (peek() == Token::FUNCTION) { 3371 if (peek() == Token::FUNCTION) {
3420 Consume(Token::FUNCTION); 3372 Consume(Token::FUNCTION);
3421 int function_token_position = position(); 3373 int function_token_position = position();
3422 bool is_generator = allow_generators() && Check(Token::MUL); 3374 bool is_generator = allow_generators() && Check(Token::MUL);
3423 Handle<String> name; 3375 Handle<String> name;
3424 bool is_strict_reserved_name = false; 3376 bool is_strict_reserved_name = false;
3425 Scanner::Location function_name_location = Scanner::Location::invalid(); 3377 Scanner::Location function_name_location = Scanner::Location::invalid();
3426 if (peek_any_identifier()) { 3378 if (peek_any_identifier()) {
3427 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, 3379 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
3428 CHECK_OK); 3380 CHECK_OK);
3429 function_name_location = scanner()->location(); 3381 function_name_location = scanner()->location();
3430 } 3382 }
3431 FunctionLiteral::FunctionType function_type = name.is_null() 3383 FunctionLiteral::FunctionType function_type = name.is_null()
3432 ? FunctionLiteral::ANONYMOUS_EXPRESSION 3384 ? FunctionLiteral::ANONYMOUS_EXPRESSION
3433 : FunctionLiteral::NAMED_EXPRESSION; 3385 : FunctionLiteral::NAMED_EXPRESSION;
3434 result = ParseFunctionLiteral(name, 3386 result = ParseFunctionLiteral(name,
3435 function_name_location, 3387 function_name_location,
3436 is_strict_reserved_name, 3388 is_strict_reserved_name,
3437 is_generator, 3389 is_generator,
3438 function_token_position, 3390 function_token_position,
3439 function_type, 3391 function_type,
3440 CHECK_OK); 3392 CHECK_OK);
3441 } else { 3393 } else {
3442 result = ParsePrimaryExpression(CHECK_OK); 3394 result = ParsePrimaryExpression(CHECK_OK);
3443 } 3395 }
3444 3396
3397 result = ParseMemberExpressionContinuation(result, CHECK_OK);
3398 return result;
3399 }
3400
3401
3402 Expression* Parser::ParseMemberExpressionContinuation(Expression* expression,
3403 bool* ok) {
3404 // Parses this part of MemberExpression:
3405 // ('[' Expression ']' | '.' Identifier)*
3445 while (true) { 3406 while (true) {
3446 switch (peek()) { 3407 switch (peek()) {
3447 case Token::LBRACK: { 3408 case Token::LBRACK: {
3448 Consume(Token::LBRACK); 3409 Consume(Token::LBRACK);
3449 int pos = position(); 3410 int pos = position();
3450 Expression* index = ParseExpression(true, CHECK_OK); 3411 Expression* index = ParseExpression(true, CHECK_OK);
3451 result = factory()->NewProperty(result, index, pos); 3412 expression = factory()->NewProperty(expression, index, pos);
3452 if (fni_ != NULL) { 3413 if (fni_ != NULL) {
3453 if (index->IsPropertyName()) { 3414 if (index->IsPropertyName()) {
3454 fni_->PushLiteralName(index->AsLiteral()->AsPropertyName()); 3415 fni_->PushLiteralName(index->AsLiteral()->AsPropertyName());
3455 } else { 3416 } else {
3456 fni_->PushLiteralName( 3417 fni_->PushLiteralName(
3457 isolate()->factory()->anonymous_function_string()); 3418 isolate()->factory()->anonymous_function_string());
3458 } 3419 }
3459 } 3420 }
3460 Expect(Token::RBRACK, CHECK_OK); 3421 Expect(Token::RBRACK, CHECK_OK);
3461 break; 3422 break;
3462 } 3423 }
3463 case Token::PERIOD: { 3424 case Token::PERIOD: {
3464 Consume(Token::PERIOD); 3425 Consume(Token::PERIOD);
3465 int pos = position(); 3426 int pos = position();
3466 Handle<String> name = ParseIdentifierName(CHECK_OK); 3427 Handle<String> name = ParseIdentifierName(CHECK_OK);
3467 result = factory()->NewProperty( 3428 expression = factory()->NewProperty(
3468 result, factory()->NewLiteral(name, pos), pos); 3429 expression, factory()->NewLiteral(name, pos), pos);
3469 if (fni_ != NULL) fni_->PushLiteralName(name); 3430 if (fni_ != NULL) fni_->PushLiteralName(name);
3470 break; 3431 break;
3471 } 3432 }
3472 case Token::LPAREN: {
3473 if ((stack == NULL) || stack->is_empty()) return result;
3474 // Consume one of the new prefixes (already parsed).
3475 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
3476 int pos = stack->pop();
3477 result = factory()->NewCallNew(result, args, pos);
3478 break;
3479 }
3480 default: 3433 default:
3481 return result; 3434 return expression;
3482 } 3435 }
3483 } 3436 }
3437 ASSERT(false);
3438 return NULL;
3484 } 3439 }
3485 3440
3486 3441
3487 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) { 3442 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) {
3488 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser 3443 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
3489 // contexts this is used as a statement which invokes the debugger as i a 3444 // contexts this is used as a statement which invokes the debugger as i a
3490 // break point is present. 3445 // break point is present.
3491 // DebuggerStatement :: 3446 // DebuggerStatement ::
3492 // 'debugger' ';' 3447 // 'debugger' ';'
3493 3448
(...skipping 1916 matching lines...) Expand 10 before | Expand all | Expand 10 after
5410 ASSERT(info()->isolate()->has_pending_exception()); 5365 ASSERT(info()->isolate()->has_pending_exception());
5411 } else { 5366 } else {
5412 result = ParseProgram(); 5367 result = ParseProgram();
5413 } 5368 }
5414 } 5369 }
5415 info()->SetFunction(result); 5370 info()->SetFunction(result);
5416 return (result != NULL); 5371 return (result != NULL);
5417 } 5372 }
5418 5373
5419 } } // namespace v8::internal 5374 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698