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

Side by Side Diff: src/parser.cc

Issue 164183006: Revert "(Pre)Parser: Simplify NewExpression handling." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: 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
49 RegExpBuilder::RegExpBuilder(Zone* zone) 92 RegExpBuilder::RegExpBuilder(Zone* zone)
50 : zone_(zone), 93 : zone_(zone),
51 pending_empty_(false), 94 pending_empty_(false),
52 characters_(NULL), 95 characters_(NULL),
53 terms_(), 96 terms_(),
54 alternatives_() 97 alternatives_()
55 #ifdef DEBUG 98 #ifdef DEBUG
56 , last_added_(ADD_NONE) 99 , last_added_(ADD_NONE)
57 #endif 100 #endif
58 {} 101 {}
(...skipping 3183 matching lines...) Expand 10 before | Expand all | Expand 10 after
3242 position()); 3285 position());
3243 } 3286 }
3244 return expression; 3287 return expression;
3245 } 3288 }
3246 3289
3247 3290
3248 Expression* Parser::ParseLeftHandSideExpression(bool* ok) { 3291 Expression* Parser::ParseLeftHandSideExpression(bool* ok) {
3249 // LeftHandSideExpression :: 3292 // LeftHandSideExpression ::
3250 // (NewExpression | MemberExpression) ... 3293 // (NewExpression | MemberExpression) ...
3251 3294
3252 Expression* result = ParseMemberWithNewPrefixesExpression(CHECK_OK); 3295 Expression* result;
3296 if (peek() == Token::NEW) {
3297 result = ParseNewExpression(CHECK_OK);
3298 } else {
3299 result = ParseMemberExpression(CHECK_OK);
3300 }
3253 3301
3254 while (true) { 3302 while (true) {
3255 switch (peek()) { 3303 switch (peek()) {
3256 case Token::LBRACK: { 3304 case Token::LBRACK: {
3257 Consume(Token::LBRACK); 3305 Consume(Token::LBRACK);
3258 int pos = position(); 3306 int pos = position();
3259 Expression* index = ParseExpression(true, CHECK_OK); 3307 Expression* index = ParseExpression(true, CHECK_OK);
3260 result = factory()->NewProperty(result, index, pos); 3308 result = factory()->NewProperty(result, index, pos);
3261 Expect(Token::RBRACK, CHECK_OK); 3309 Expect(Token::RBRACK, CHECK_OK);
3262 break; 3310 break;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
3311 break; 3359 break;
3312 } 3360 }
3313 3361
3314 default: 3362 default:
3315 return result; 3363 return result;
3316 } 3364 }
3317 } 3365 }
3318 } 3366 }
3319 3367
3320 3368
3321 Expression* Parser::ParseMemberWithNewPrefixesExpression(bool* ok) { 3369 Expression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) {
3322 // NewExpression :: 3370 // NewExpression ::
3323 // ('new')+ MemberExpression 3371 // ('new')+ MemberExpression
3324 3372
3325 // The grammar for new expressions is pretty warped. We can have several 'new' 3373 // The grammar for new expressions is pretty warped. The keyword
3326 // keywords following each other, and then a MemberExpression. When we see '(' 3374 // 'new' can either be a part of the new expression (where it isn't
3327 // after the MemberExpression, it's associated with the rightmost unassociated 3375 // followed by an argument list) or a part of the member expression,
3328 // 'new' to create a NewExpression with arguments. However, a NewExpression 3376 // where it must be followed by an argument list. To accommodate
3329 // can also occur without arguments. 3377 // this, we parse the 'new' keywords greedily and keep track of how
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());
3330 3383
3331 // Examples of new expression: 3384 Expression* result;
3332 // new foo.bar().baz means (new (foo.bar)()).baz 3385 if (peek() == Token::NEW) {
3333 // new foo()() means (new foo())() 3386 result = ParseNewPrefix(stack, CHECK_OK);
3334 // new new foo()() means (new (new foo())()) 3387 } else {
3335 // new new foo means new (new foo) 3388 result = ParseMemberWithNewPrefixesExpression(stack, CHECK_OK);
3336 // new new foo() means new (new foo()) 3389 }
3337 3390
3338 if (peek() == Token::NEW) { 3391 if (!stack->is_empty()) {
3339 Consume(Token::NEW); 3392 int last = stack->pop();
3340 int new_pos = position(); 3393 result = factory()->NewCallNew(
3341 Expression* result = ParseMemberWithNewPrefixesExpression(CHECK_OK); 3394 result, new(zone()) ZoneList<Expression*>(0, zone()), last);
3342 if (peek() == Token::LPAREN) {
3343 // NewExpression with arguments.
3344 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
3345 return factory()->NewCallNew(result, args, new_pos);
3346 }
3347 // NewExpression without arguments.
3348 return factory()->NewCallNew(
3349 result, new(zone()) ZoneList<Expression*>(0, zone()), new_pos);
3350 } 3395 }
3351 // No 'new' keyword. 3396 return result;
3352 return ParseMemberExpression(ok); 3397 }
3398
3399
3400 Expression* Parser::ParseNewExpression(bool* ok) {
3401 PositionStack stack(ok);
3402 return ParseNewPrefix(&stack, ok);
3353 } 3403 }
3354 3404
3355 3405
3356 Expression* Parser::ParseMemberExpression(bool* ok) { 3406 Expression* Parser::ParseMemberExpression(bool* ok) {
3407 return ParseMemberWithNewPrefixesExpression(NULL, ok);
3408 }
3409
3410
3411 Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack,
3412 bool* ok) {
3357 // MemberExpression :: 3413 // MemberExpression ::
3358 // (PrimaryExpression | FunctionLiteral) 3414 // (PrimaryExpression | FunctionLiteral)
3359 // ('[' Expression ']' | '.' Identifier | Arguments)* 3415 // ('[' Expression ']' | '.' Identifier | Arguments)*
3360 3416
3361 // Parse the initial primary or function expression. 3417 // Parse the initial primary or function expression.
3362 Expression* result = NULL; 3418 Expression* result = NULL;
3363 if (peek() == Token::FUNCTION) { 3419 if (peek() == Token::FUNCTION) {
3364 Consume(Token::FUNCTION); 3420 Consume(Token::FUNCTION);
3365 int function_token_position = position(); 3421 int function_token_position = position();
3366 bool is_generator = allow_generators() && Check(Token::MUL); 3422 bool is_generator = allow_generators() && Check(Token::MUL);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
3406 } 3462 }
3407 case Token::PERIOD: { 3463 case Token::PERIOD: {
3408 Consume(Token::PERIOD); 3464 Consume(Token::PERIOD);
3409 int pos = position(); 3465 int pos = position();
3410 Handle<String> name = ParseIdentifierName(CHECK_OK); 3466 Handle<String> name = ParseIdentifierName(CHECK_OK);
3411 result = factory()->NewProperty( 3467 result = factory()->NewProperty(
3412 result, factory()->NewLiteral(name, pos), pos); 3468 result, factory()->NewLiteral(name, pos), pos);
3413 if (fni_ != NULL) fni_->PushLiteralName(name); 3469 if (fni_ != NULL) fni_->PushLiteralName(name);
3414 break; 3470 break;
3415 } 3471 }
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 }
3416 default: 3480 default:
3417 return result; 3481 return result;
3418 } 3482 }
3419 } 3483 }
3420 } 3484 }
3421 3485
3422 3486
3423 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) { 3487 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) {
3424 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser 3488 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
3425 // contexts this is used as a statement which invokes the debugger as i a 3489 // contexts this is used as a statement which invokes the debugger as i a
(...skipping 1920 matching lines...) Expand 10 before | Expand all | Expand 10 after
5346 ASSERT(info()->isolate()->has_pending_exception()); 5410 ASSERT(info()->isolate()->has_pending_exception());
5347 } else { 5411 } else {
5348 result = ParseProgram(); 5412 result = ParseProgram();
5349 } 5413 }
5350 } 5414 }
5351 info()->SetFunction(result); 5415 info()->SetFunction(result);
5352 return (result != NULL); 5416 return (result != NULL);
5353 } 5417 }
5354 5418
5355 } } // namespace v8::internal 5419 } } // 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