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

Side by Side Diff: src/fast-codegen.cc

Issue 546075: First step of refactoring expression contexts in the toplevel code... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 11 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
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 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 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 158
159 159
160 void FastCodeGenerator::SetSourcePosition(int pos) { 160 void FastCodeGenerator::SetSourcePosition(int pos) {
161 if (FLAG_debug_info && pos != RelocInfo::kNoPosition) { 161 if (FLAG_debug_info && pos != RelocInfo::kNoPosition) {
162 masm_->RecordPosition(pos); 162 masm_->RecordPosition(pos);
163 } 163 }
164 } 164 }
165 165
166 166
167 void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) { 167 void FastCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) {
168 #ifdef DEBUG
169 Expression::Context expected = Expression::kUninitialized;
170 switch (expr->context()) {
171 case Expression::kUninitialized:
172 UNREACHABLE();
173 case Expression::kEffect:
174 case Expression::kTest:
175 // The value of the left subexpression is not needed.
176 expected = Expression::kTest;
177 break;
178 case Expression::kValue:
179 // The value of the left subexpression is needed and its specific
180 // context depends on the operator.
181 expected = (expr->op() == Token::OR)
182 ? Expression::kValueTest
183 : Expression::kTestValue;
184 break;
185 case Expression::kValueTest:
186 // The value of the left subexpression is needed for OR.
187 expected = (expr->op() == Token::OR)
188 ? Expression::kValueTest
189 : Expression::kTest;
190 break;
191 case Expression::kTestValue:
192 // The value of the left subexpression is needed for AND.
193 expected = (expr->op() == Token::OR)
194 ? Expression::kTest
195 : Expression::kTestValue;
196 break;
197 }
198 ASSERT_EQ(expected, expr->left()->context());
199 ASSERT_EQ(expr->context(), expr->right()->context());
200 #endif
201
202 Label eval_right, done; 168 Label eval_right, done;
203 169
204 // Set up the appropriate context for the left subexpression based 170 // Set up the appropriate context for the left subexpression based
205 // on the operation and our own context. Initially assume we can 171 // on the operation and our own context. Initially assume we can
206 // inherit both true and false labels from our context. 172 // inherit both true and false labels from our context.
207 Label* if_true = true_label_;
208 Label* if_false = false_label_;
209 if (expr->op() == Token::OR) { 173 if (expr->op() == Token::OR) {
210 // If we are not in some kind of a test context, we did not inherit a 174 switch (context_) {
211 // true label from our context. Use the end of the expression. 175 case Expression::kUninitialized:
212 if (expr->context() == Expression::kEffect || 176 UNREACHABLE();
213 expr->context() == Expression::kValue) { 177 case Expression::kEffect:
214 if_true = &done; 178 VisitForControl(expr->left(), &done, &eval_right);
179 break;
180 case Expression::kValue:
181 VisitForValueControl(expr->left(),
182 location_,
183 &done,
184 &eval_right);
185 break;
186 case Expression::kTest:
187 VisitForControl(expr->left(), true_label_, &eval_right);
188 break;
189 case Expression::kValueTest:
190 VisitForValueControl(expr->left(),
191 location_,
192 true_label_,
193 &eval_right);
194 break;
195 case Expression::kTestValue:
196 VisitForControl(expr->left(), true_label_, &eval_right);
197 break;
215 } 198 }
216 // The false label is the label of the right subexpression.
217 if_false = &eval_right;
218 } else { 199 } else {
219 ASSERT_EQ(Token::AND, expr->op()); 200 ASSERT_EQ(Token::AND, expr->op());
220 // The true label is the label of the right subexpression. 201 switch (context_) {
221 if_true = &eval_right; 202 case Expression::kUninitialized:
222 // If we are not in some kind of a test context, we did not inherit a 203 UNREACHABLE();
223 // false label from our context. Use the end of the expression. 204 case Expression::kEffect:
224 if (expr->context() == Expression::kEffect || 205 VisitForControl(expr->left(), &eval_right, &done);
225 expr->context() == Expression::kValue) { 206 break;
226 if_false = &done; 207 case Expression::kValue:
208 VisitForControlValue(expr->left(),
209 location_,
210 &eval_right,
211 &done);
212 break;
213 case Expression::kTest:
214 VisitForControl(expr->left(), &eval_right, false_label_);
215 break;
216 case Expression::kValueTest:
217 VisitForControl(expr->left(), &eval_right, false_label_);
218 break;
219 case Expression::kTestValue:
220 VisitForControlValue(expr->left(),
221 location_,
222 &eval_right,
223 false_label_);
224 break;
227 } 225 }
228 } 226 }
229 VisitForControl(expr->left(), if_true, if_false);
230 227
231 __ bind(&eval_right); 228 __ bind(&eval_right);
232 Visit(expr->right()); 229 Visit(expr->right());
233 230
234 __ bind(&done); 231 __ bind(&done);
235 } 232 }
236 233
237 234
238 void FastCodeGenerator::VisitBlock(Block* stmt) { 235 void FastCodeGenerator::VisitBlock(Block* stmt) {
239 Comment cmnt(masm_, "[ Block"); 236 Comment cmnt(masm_, "[ Block");
240 Breakable nested_statement(this, stmt); 237 Breakable nested_statement(this, stmt);
241 SetStatementPosition(stmt); 238 SetStatementPosition(stmt);
242 VisitStatements(stmt->statements()); 239 VisitStatements(stmt->statements());
243 __ bind(nested_statement.break_target()); 240 __ bind(nested_statement.break_target());
244 } 241 }
245 242
246 243
247 void FastCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { 244 void FastCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
248 Comment cmnt(masm_, "[ ExpressionStatement"); 245 Comment cmnt(masm_, "[ ExpressionStatement");
249 SetStatementPosition(stmt); 246 SetStatementPosition(stmt);
250 Visit(stmt->expression()); 247 VisitForEffect(stmt->expression());
251 } 248 }
252 249
253 250
254 void FastCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { 251 void FastCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
255 Comment cmnt(masm_, "[ EmptyStatement"); 252 Comment cmnt(masm_, "[ EmptyStatement");
256 SetStatementPosition(stmt); 253 SetStatementPosition(stmt);
257 } 254 }
258 255
259 256
260 void FastCodeGenerator::VisitIfStatement(IfStatement* stmt) { 257 void FastCodeGenerator::VisitIfStatement(IfStatement* stmt) {
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 // before entering, and removes it again when exiting normally. 436 // before entering, and removes it again when exiting normally.
440 // If an exception is thrown during execution of the try block, 437 // If an exception is thrown during execution of the try block,
441 // control is passed to the handler, which also consumes the handler. 438 // control is passed to the handler, which also consumes the handler.
442 // At this point, the exception is in a register, and store it in 439 // At this point, the exception is in a register, and store it in
443 // the temporary local variable (prints as ".catch-var") before 440 // the temporary local variable (prints as ".catch-var") before
444 // executing the catch block. The catch block has been rewritten 441 // executing the catch block. The catch block has been rewritten
445 // to introduce a new scope to bind the catch variable and to remove 442 // to introduce a new scope to bind the catch variable and to remove
446 // that scope again afterwards. 443 // that scope again afterwards.
447 444
448 Label try_handler_setup, catch_entry, done; 445 Label try_handler_setup, catch_entry, done;
449
450 __ Call(&try_handler_setup); 446 __ Call(&try_handler_setup);
451 // Try handler code, exception in result register. 447 // Try handler code, exception in result register.
452 448
453 // Store exception in local .catch variable before executing catch block. 449 // Store exception in local .catch variable before executing catch block.
454 { 450 {
455 // The catch variable is *always* a variable proxy for a local variable. 451 // The catch variable is *always* a variable proxy for a local variable.
456 Variable* catch_var = stmt->catch_var()->AsVariableProxy()->AsVariable(); 452 Variable* catch_var = stmt->catch_var()->AsVariableProxy()->AsVariable();
457 ASSERT_NOT_NULL(catch_var); 453 ASSERT_NOT_NULL(catch_var);
458 Slot* variable_slot = catch_var->slot(); 454 Slot* variable_slot = catch_var->slot();
459 ASSERT_NOT_NULL(variable_slot); 455 ASSERT_NOT_NULL(variable_slot);
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 547
552 548
553 void FastCodeGenerator::VisitFunctionBoilerplateLiteral( 549 void FastCodeGenerator::VisitFunctionBoilerplateLiteral(
554 FunctionBoilerplateLiteral* expr) { 550 FunctionBoilerplateLiteral* expr) {
555 UNREACHABLE(); 551 UNREACHABLE();
556 } 552 }
557 553
558 554
559 void FastCodeGenerator::VisitConditional(Conditional* expr) { 555 void FastCodeGenerator::VisitConditional(Conditional* expr) {
560 Comment cmnt(masm_, "[ Conditional"); 556 Comment cmnt(masm_, "[ Conditional");
561 ASSERT_EQ(Expression::kTest, expr->condition()->context());
562 ASSERT_EQ(expr->context(), expr->then_expression()->context());
563 ASSERT_EQ(expr->context(), expr->else_expression()->context());
564
565
566 Label true_case, false_case, done; 557 Label true_case, false_case, done;
567 VisitForControl(expr->condition(), &true_case, &false_case); 558 VisitForControl(expr->condition(), &true_case, &false_case);
568 559
569 __ bind(&true_case); 560 __ bind(&true_case);
570 Visit(expr->then_expression()); 561 Visit(expr->then_expression());
571 // If control flow falls through Visit, jump to done. 562 // If control flow falls through Visit, jump to done.
572 if (expr->context() == Expression::kEffect || 563 if (context_ == Expression::kEffect || context_ == Expression::kValue) {
573 expr->context() == Expression::kValue) {
574 __ jmp(&done); 564 __ jmp(&done);
575 } 565 }
576 566
577 __ bind(&false_case); 567 __ bind(&false_case);
578 Visit(expr->else_expression()); 568 Visit(expr->else_expression());
579 // If control flow falls through Visit, merge it with true case here. 569 // If control flow falls through Visit, merge it with true case here.
580 if (expr->context() == Expression::kEffect || 570 if (context_ == Expression::kEffect || context_ == Expression::kValue) {
581 expr->context() == Expression::kValue) {
582 __ bind(&done); 571 __ bind(&done);
583 } 572 }
584 } 573 }
585 574
586 575
587 void FastCodeGenerator::VisitSlot(Slot* expr) { 576 void FastCodeGenerator::VisitSlot(Slot* expr) {
588 // Slots do not appear directly in the AST. 577 // Slots do not appear directly in the AST.
589 UNREACHABLE(); 578 UNREACHABLE();
590 } 579 }
591 580
592 581
593 void FastCodeGenerator::VisitLiteral(Literal* expr) { 582 void FastCodeGenerator::VisitLiteral(Literal* expr) {
594 Comment cmnt(masm_, "[ Literal"); 583 Comment cmnt(masm_, "[ Literal");
595 Apply(expr->context(), expr); 584 Apply(context_, expr);
596 } 585 }
597 586
598 587
599 void FastCodeGenerator::VisitAssignment(Assignment* expr) { 588 void FastCodeGenerator::VisitAssignment(Assignment* expr) {
600 Comment cmnt(masm_, "[ Assignment"); 589 Comment cmnt(masm_, "[ Assignment");
601
602 // Left-hand side can only be a property, a global or a (parameter or local) 590 // Left-hand side can only be a property, a global or a (parameter or local)
603 // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY. 591 // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
604 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 592 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
605 LhsKind assign_type = VARIABLE; 593 LhsKind assign_type = VARIABLE;
606 Property* prop = expr->target()->AsProperty(); 594 Property* prop = expr->target()->AsProperty();
607 // In case of a property we use the uninitialized expression context
608 // of the key to detect a named property.
609 if (prop != NULL) { 595 if (prop != NULL) {
610 assign_type = (prop->key()->context() == Expression::kUninitialized) 596 assign_type =
611 ? NAMED_PROPERTY 597 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
612 : KEYED_PROPERTY;
613 } 598 }
614 599
615 // Evaluate LHS expression. 600 // Evaluate LHS expression.
616 switch (assign_type) { 601 switch (assign_type) {
617 case VARIABLE: 602 case VARIABLE:
618 // Nothing to do here. 603 // Nothing to do here.
619 break; 604 break;
620 case NAMED_PROPERTY: 605 case NAMED_PROPERTY:
621 VisitForValue(prop->obj(), kStack); 606 VisitForValue(prop->obj(), kStack);
622 break; 607 break;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 location_ = saved_location; 645 location_ = saved_location;
661 } 646 }
662 647
663 // Record source position before possible IC call. 648 // Record source position before possible IC call.
664 SetSourcePosition(expr->position()); 649 SetSourcePosition(expr->position());
665 650
666 // Store the value. 651 // Store the value.
667 switch (assign_type) { 652 switch (assign_type) {
668 case VARIABLE: 653 case VARIABLE:
669 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), 654 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
670 expr->context()); 655 context_);
671 break; 656 break;
672 case NAMED_PROPERTY: 657 case NAMED_PROPERTY:
673 EmitNamedPropertyAssignment(expr); 658 EmitNamedPropertyAssignment(expr);
674 break; 659 break;
675 case KEYED_PROPERTY: 660 case KEYED_PROPERTY:
676 EmitKeyedPropertyAssignment(expr); 661 EmitKeyedPropertyAssignment(expr);
677 break; 662 break;
678 } 663 }
679 } 664 }
680 665
681 666
682 void FastCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) { 667 void FastCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) {
683 // Call runtime routine to allocate the catch extension object and 668 // Call runtime routine to allocate the catch extension object and
684 // assign the exception value to the catch variable. 669 // assign the exception value to the catch variable.
685 Comment cmnt(masm_, "[ CatchExtensionObject"); 670 Comment cmnt(masm_, "[ CatchExtensionObject");
686
687 VisitForValue(expr->key(), kStack); 671 VisitForValue(expr->key(), kStack);
688 VisitForValue(expr->value(), kStack); 672 VisitForValue(expr->value(), kStack);
689
690 // Create catch extension object. 673 // Create catch extension object.
691 __ CallRuntime(Runtime::kCreateCatchExtensionObject, 2); 674 __ CallRuntime(Runtime::kCreateCatchExtensionObject, 2);
692 675 Apply(context_, result_register());
693 __ push(result_register());
694 } 676 }
695 677
696 678
697 void FastCodeGenerator::VisitThrow(Throw* expr) { 679 void FastCodeGenerator::VisitThrow(Throw* expr) {
698 Comment cmnt(masm_, "[ Throw"); 680 Comment cmnt(masm_, "[ Throw");
699 VisitForValue(expr->exception(), kStack); 681 VisitForValue(expr->exception(), kStack);
700 __ CallRuntime(Runtime::kThrow, 1); 682 __ CallRuntime(Runtime::kThrow, 1);
701 // Never returns here. 683 // Never returns here.
702 } 684 }
703 685
(...skipping 12 matching lines...) Expand all
716 __ Drop(stack_depth); 698 __ Drop(stack_depth);
717 __ PopTryHandler(); 699 __ PopTryHandler();
718 return 0; 700 return 0;
719 } 701 }
720 702
721 703
722 #undef __ 704 #undef __
723 705
724 706
725 } } // namespace v8::internal 707 } } // namespace v8::internal
OLDNEW
« src/compiler.cc ('K') | « src/fast-codegen.h ('k') | src/ia32/fast-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698