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

Side by Side Diff: src/compiler.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
« no previous file with comments | « src/ast.h ('k') | src/fast-codegen.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 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 28 matching lines...) Expand all
39 #include "usage-analyzer.h" 39 #include "usage-analyzer.h"
40 40
41 namespace v8 { 41 namespace v8 {
42 namespace internal { 42 namespace internal {
43 43
44 44
45 class CodeGenSelector: public AstVisitor { 45 class CodeGenSelector: public AstVisitor {
46 public: 46 public:
47 enum CodeGenTag { NORMAL, FAST }; 47 enum CodeGenTag { NORMAL, FAST };
48 48
49 CodeGenSelector() 49 CodeGenSelector() : has_supported_syntax_(true) {}
50 : has_supported_syntax_(true),
51 context_(Expression::kUninitialized) {
52 }
53 50
54 CodeGenTag Select(FunctionLiteral* fun); 51 CodeGenTag Select(FunctionLiteral* fun);
55 52
56 private: 53 private:
57 // Visit an expression in a given expression context.
58 void ProcessExpression(Expression* expr, Expression::Context context) {
59 ASSERT(expr->context() == Expression::kUninitialized ||
60 expr->context() == context);
61 Expression::Context saved = context_;
62 context_ = context;
63 Visit(expr);
64 expr->set_context(context);
65 context_ = saved;
66 }
67
68 void VisitDeclarations(ZoneList<Declaration*>* decls); 54 void VisitDeclarations(ZoneList<Declaration*>* decls);
69 void VisitStatements(ZoneList<Statement*>* stmts); 55 void VisitStatements(ZoneList<Statement*>* stmts);
70 56
71 // AST node visit functions. 57 // AST node visit functions.
72 #define DECLARE_VISIT(type) virtual void Visit##type(type* node); 58 #define DECLARE_VISIT(type) virtual void Visit##type(type* node);
73 AST_NODE_LIST(DECLARE_VISIT) 59 AST_NODE_LIST(DECLARE_VISIT)
74 #undef DECLARE_VISIT 60 #undef DECLARE_VISIT
75 61
76 bool has_supported_syntax_; 62 bool has_supported_syntax_;
77 63
78 // The desired expression context of the currently visited expression.
79 Expression::Context context_;
80
81 DISALLOW_COPY_AND_ASSIGN(CodeGenSelector); 64 DISALLOW_COPY_AND_ASSIGN(CodeGenSelector);
82 }; 65 };
83 66
84 67
85 static Handle<Code> MakeCode(FunctionLiteral* literal, 68 static Handle<Code> MakeCode(FunctionLiteral* literal,
86 Handle<Script> script, 69 Handle<Script> script,
87 Handle<Context> context, 70 Handle<Context> context,
88 bool is_eval, 71 bool is_eval,
89 Handle<SharedFunctionInfo> shared) { 72 Handle<SharedFunctionInfo> shared) {
90 ASSERT(literal != NULL); 73 ASSERT(literal != NULL);
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 for (int i = 0, len = stmts->length(); i < len; i++) { 625 for (int i = 0, len = stmts->length(); i < len; i++) {
643 Visit(stmts->at(i)); 626 Visit(stmts->at(i));
644 CHECK_BAILOUT; 627 CHECK_BAILOUT;
645 } 628 }
646 } 629 }
647 630
648 631
649 void CodeGenSelector::VisitDeclaration(Declaration* decl) { 632 void CodeGenSelector::VisitDeclaration(Declaration* decl) {
650 Property* prop = decl->proxy()->AsProperty(); 633 Property* prop = decl->proxy()->AsProperty();
651 if (prop != NULL) { 634 if (prop != NULL) {
652 ProcessExpression(prop->obj(), Expression::kValue); 635 Visit(prop->obj());
653 ProcessExpression(prop->key(), Expression::kValue); 636 Visit(prop->key());
654 } 637 }
655 638
656 if (decl->fun() != NULL) { 639 if (decl->fun() != NULL) {
657 ProcessExpression(decl->fun(), Expression::kValue); 640 Visit(decl->fun());
658 } 641 }
659 } 642 }
660 643
661 644
662 void CodeGenSelector::VisitBlock(Block* stmt) { 645 void CodeGenSelector::VisitBlock(Block* stmt) {
663 VisitStatements(stmt->statements()); 646 VisitStatements(stmt->statements());
664 } 647 }
665 648
666 649
667 void CodeGenSelector::VisitExpressionStatement(ExpressionStatement* stmt) { 650 void CodeGenSelector::VisitExpressionStatement(ExpressionStatement* stmt) {
668 ProcessExpression(stmt->expression(), Expression::kEffect); 651 Visit(stmt->expression());
669 } 652 }
670 653
671 654
672 void CodeGenSelector::VisitEmptyStatement(EmptyStatement* stmt) { 655 void CodeGenSelector::VisitEmptyStatement(EmptyStatement* stmt) {}
673 // EmptyStatement is supported.
674 }
675 656
676 657
677 void CodeGenSelector::VisitIfStatement(IfStatement* stmt) { 658 void CodeGenSelector::VisitIfStatement(IfStatement* stmt) {
678 ProcessExpression(stmt->condition(), Expression::kTest); 659 Visit(stmt->condition());
679 CHECK_BAILOUT; 660 CHECK_BAILOUT;
680 Visit(stmt->then_statement()); 661 Visit(stmt->then_statement());
681 CHECK_BAILOUT; 662 CHECK_BAILOUT;
682 Visit(stmt->else_statement()); 663 Visit(stmt->else_statement());
683 } 664 }
684 665
685 666
686 void CodeGenSelector::VisitContinueStatement(ContinueStatement* stmt) { 667 void CodeGenSelector::VisitContinueStatement(ContinueStatement* stmt) {}
687 }
688 668
689 669
690 void CodeGenSelector::VisitBreakStatement(BreakStatement* stmt) { 670 void CodeGenSelector::VisitBreakStatement(BreakStatement* stmt) {}
691 }
692 671
693 672
694 void CodeGenSelector::VisitReturnStatement(ReturnStatement* stmt) { 673 void CodeGenSelector::VisitReturnStatement(ReturnStatement* stmt) {
695 ProcessExpression(stmt->expression(), Expression::kValue); 674 Visit(stmt->expression());
696 } 675 }
697 676
698 677
699 void CodeGenSelector::VisitWithEnterStatement(WithEnterStatement* stmt) { 678 void CodeGenSelector::VisitWithEnterStatement(WithEnterStatement* stmt) {
700 ProcessExpression(stmt->expression(), Expression::kValue); 679 Visit(stmt->expression());
701 } 680 }
702 681
703 682
704 void CodeGenSelector::VisitWithExitStatement(WithExitStatement* stmt) { 683 void CodeGenSelector::VisitWithExitStatement(WithExitStatement* stmt) {}
705 // Supported.
706 }
707 684
708 685
709 void CodeGenSelector::VisitSwitchStatement(SwitchStatement* stmt) { 686 void CodeGenSelector::VisitSwitchStatement(SwitchStatement* stmt) {
710 BAILOUT("SwitchStatement"); 687 BAILOUT("SwitchStatement");
711 } 688 }
712 689
713 690
714 void CodeGenSelector::VisitDoWhileStatement(DoWhileStatement* stmt) { 691 void CodeGenSelector::VisitDoWhileStatement(DoWhileStatement* stmt) {
715 // We do not handle loops with breaks or continue statements in their 692 Visit(stmt->cond());
716 // body. We will bailout when we hit those statements in the body.
717 ProcessExpression(stmt->cond(), Expression::kTest);
718 CHECK_BAILOUT; 693 CHECK_BAILOUT;
719 Visit(stmt->body()); 694 Visit(stmt->body());
720 } 695 }
721 696
722 697
723 void CodeGenSelector::VisitWhileStatement(WhileStatement* stmt) { 698 void CodeGenSelector::VisitWhileStatement(WhileStatement* stmt) {
724 // We do not handle loops with breaks or continue statements in their 699 Visit(stmt->cond());
725 // body. We will bailout when we hit those statements in the body.
726 ProcessExpression(stmt->cond(), Expression::kTest);
727 CHECK_BAILOUT; 700 CHECK_BAILOUT;
728 Visit(stmt->body()); 701 Visit(stmt->body());
729 } 702 }
730 703
731 704
732 void CodeGenSelector::VisitForStatement(ForStatement* stmt) { 705 void CodeGenSelector::VisitForStatement(ForStatement* stmt) {
733 BAILOUT("ForStatement"); 706 BAILOUT("ForStatement");
734 } 707 }
735 708
736 709
737 void CodeGenSelector::VisitForInStatement(ForInStatement* stmt) { 710 void CodeGenSelector::VisitForInStatement(ForInStatement* stmt) {
738 BAILOUT("ForInStatement"); 711 BAILOUT("ForInStatement");
739 } 712 }
740 713
741 714
742 void CodeGenSelector::VisitTryCatchStatement(TryCatchStatement* stmt) { 715 void CodeGenSelector::VisitTryCatchStatement(TryCatchStatement* stmt) {
743 Visit(stmt->try_block()); 716 Visit(stmt->try_block());
744 CHECK_BAILOUT; 717 CHECK_BAILOUT;
745 Visit(stmt->catch_block()); 718 Visit(stmt->catch_block());
746 } 719 }
747 720
748 721
749 void CodeGenSelector::VisitTryFinallyStatement(TryFinallyStatement* stmt) { 722 void CodeGenSelector::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
750 Visit(stmt->try_block()); 723 Visit(stmt->try_block());
751 CHECK_BAILOUT; 724 CHECK_BAILOUT;
752 Visit(stmt->finally_block()); 725 Visit(stmt->finally_block());
753 } 726 }
754 727
755 728
756 void CodeGenSelector::VisitDebuggerStatement(DebuggerStatement* stmt) { 729 void CodeGenSelector::VisitDebuggerStatement(DebuggerStatement* stmt) {}
757 // Debugger statement is supported.
758 }
759 730
760 731
761 void CodeGenSelector::VisitFunctionLiteral(FunctionLiteral* expr) { 732 void CodeGenSelector::VisitFunctionLiteral(FunctionLiteral* expr) {}
762 // Function literal is supported.
763 }
764 733
765 734
766 void CodeGenSelector::VisitFunctionBoilerplateLiteral( 735 void CodeGenSelector::VisitFunctionBoilerplateLiteral(
767 FunctionBoilerplateLiteral* expr) { 736 FunctionBoilerplateLiteral* expr) {
768 BAILOUT("FunctionBoilerplateLiteral"); 737 BAILOUT("FunctionBoilerplateLiteral");
769 } 738 }
770 739
771 740
772 void CodeGenSelector::VisitConditional(Conditional* expr) { 741 void CodeGenSelector::VisitConditional(Conditional* expr) {
773 ProcessExpression(expr->condition(), Expression::kTest); 742 Visit(expr->condition());
774 CHECK_BAILOUT; 743 CHECK_BAILOUT;
775 ProcessExpression(expr->then_expression(), context_); 744 Visit(expr->then_expression());
776 CHECK_BAILOUT; 745 CHECK_BAILOUT;
777 ProcessExpression(expr->else_expression(), context_); 746 Visit(expr->else_expression());
778 } 747 }
779 748
780 749
781 void CodeGenSelector::VisitSlot(Slot* expr) { 750 void CodeGenSelector::VisitSlot(Slot* expr) {
782 UNREACHABLE(); 751 UNREACHABLE();
783 } 752 }
784 753
785 754
786 void CodeGenSelector::VisitVariableProxy(VariableProxy* expr) { 755 void CodeGenSelector::VisitVariableProxy(VariableProxy* expr) {
787 Expression* rewrite = expr->var()->rewrite(); 756 Variable* var = expr->var();
788 // A rewrite of NULL indicates a global variable. 757 if (!var->is_global()) {
fschneider 2010/01/19 12:36:10 This is clearer than before and should be fine. I
789 if (rewrite != NULL) { 758 Slot* slot = var->slot();
790 // Non-global.
791 Slot* slot = rewrite->AsSlot();
792 if (slot != NULL) { 759 if (slot != NULL) {
793 Slot::Type type = slot->type(); 760 Slot::Type type = slot->type();
794 // When LOOKUP slots are enabled, some currently dead code 761 // When LOOKUP slots are enabled, some currently dead code
795 // implementing unary typeof will become live. 762 // implementing unary typeof will become live.
796 if (type == Slot::LOOKUP) { 763 if (type == Slot::LOOKUP) {
797 BAILOUT("Lookup slot"); 764 BAILOUT("Lookup slot");
798 } 765 }
799 } else { 766 } else {
767 // If not global or a slot, it is a parameter rewritten to an explicit
768 // property reference on the (shadow) arguments object.
800 #ifdef DEBUG 769 #ifdef DEBUG
801 // Only remaining possibility is a property where the object is 770 Property* property = var->AsProperty();
802 // a slotted variable and the key is a smi.
803 Property* property = rewrite->AsProperty();
804 ASSERT_NOT_NULL(property); 771 ASSERT_NOT_NULL(property);
805 Variable* object = property->obj()->AsVariableProxy()->AsVariable(); 772 Variable* object = property->obj()->AsVariableProxy()->AsVariable();
806 ASSERT_NOT_NULL(object); 773 ASSERT_NOT_NULL(object);
807 ASSERT_NOT_NULL(object->slot()); 774 ASSERT_NOT_NULL(object->slot());
808 ASSERT_NOT_NULL(property->key()->AsLiteral()); 775 ASSERT_NOT_NULL(property->key()->AsLiteral());
809 ASSERT(property->key()->AsLiteral()->handle()->IsSmi()); 776 ASSERT(property->key()->AsLiteral()->handle()->IsSmi());
810 #endif 777 #endif
811 } 778 }
812 } 779 }
813 } 780 }
814 781
815 782
816 void CodeGenSelector::VisitLiteral(Literal* expr) { 783 void CodeGenSelector::VisitLiteral(Literal* expr) {}
817 /* Nothing to do. */
818 }
819 784
820 785
821 void CodeGenSelector::VisitRegExpLiteral(RegExpLiteral* expr) { 786 void CodeGenSelector::VisitRegExpLiteral(RegExpLiteral* expr) {}
822 /* Nothing to do. */
823 }
824 787
825 788
826 void CodeGenSelector::VisitObjectLiteral(ObjectLiteral* expr) { 789 void CodeGenSelector::VisitObjectLiteral(ObjectLiteral* expr) {
827 ZoneList<ObjectLiteral::Property*>* properties = expr->properties(); 790 ZoneList<ObjectLiteral::Property*>* properties = expr->properties();
828 791
829 for (int i = 0, len = properties->length(); i < len; i++) { 792 for (int i = 0, len = properties->length(); i < len; i++) {
830 ObjectLiteral::Property* property = properties->at(i); 793 ObjectLiteral::Property* property = properties->at(i);
831 if (property->IsCompileTimeValue()) continue; 794 if (property->IsCompileTimeValue()) continue;
832 795 Visit(property->key());
833 switch (property->kind()) { 796 CHECK_BAILOUT;
834 case ObjectLiteral::Property::CONSTANT: 797 Visit(property->value());
835 UNREACHABLE();
836
837 // For (non-compile-time) materialized literals and computed
838 // properties with symbolic keys we will use an IC and therefore not
839 // generate code for the key.
840 case ObjectLiteral::Property::COMPUTED: // Fall through.
841 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
842 if (property->key()->handle()->IsSymbol()) {
843 break;
844 }
845 // Fall through.
846
847 // In all other cases we need the key's value on the stack
848 // for a runtime call. (Relies on TEMP meaning STACK.)
849 case ObjectLiteral::Property::GETTER: // Fall through.
850 case ObjectLiteral::Property::SETTER: // Fall through.
851 case ObjectLiteral::Property::PROTOTYPE:
852 ProcessExpression(property->key(), Expression::kValue);
853 CHECK_BAILOUT;
854 break;
855 }
856 ProcessExpression(property->value(), Expression::kValue);
857 CHECK_BAILOUT; 798 CHECK_BAILOUT;
858 } 799 }
859 } 800 }
860 801
861 802
862 void CodeGenSelector::VisitArrayLiteral(ArrayLiteral* expr) { 803 void CodeGenSelector::VisitArrayLiteral(ArrayLiteral* expr) {
863 ZoneList<Expression*>* subexprs = expr->values(); 804 ZoneList<Expression*>* subexprs = expr->values();
864 for (int i = 0, len = subexprs->length(); i < len; i++) { 805 for (int i = 0, len = subexprs->length(); i < len; i++) {
865 Expression* subexpr = subexprs->at(i); 806 Expression* subexpr = subexprs->at(i);
866 if (subexpr->AsLiteral() != NULL) continue; 807 if (subexpr->AsLiteral() != NULL) continue;
867 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 808 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
868 ProcessExpression(subexpr, Expression::kValue); 809 Visit(subexpr);
869 CHECK_BAILOUT; 810 CHECK_BAILOUT;
870 } 811 }
871 } 812 }
872 813
873 814
874 void CodeGenSelector::VisitCatchExtensionObject(CatchExtensionObject* expr) { 815 void CodeGenSelector::VisitCatchExtensionObject(CatchExtensionObject* expr) {
875 ProcessExpression(expr->key(), Expression::kValue); 816 Visit(expr->key());
876 CHECK_BAILOUT; 817 CHECK_BAILOUT;
877 ProcessExpression(expr->value(), Expression::kValue); 818 Visit(expr->value());
878 } 819 }
879 820
880 821
881 void CodeGenSelector::VisitAssignment(Assignment* expr) { 822 void CodeGenSelector::VisitAssignment(Assignment* expr) {
882 // We support plain non-compound assignments to properties, parameters and 823 // We support plain non-compound assignments to properties, parameters and
883 // non-context (stack-allocated) locals, and global variables. 824 // non-context (stack-allocated) locals, and global variables.
884 Token::Value op = expr->op(); 825 Token::Value op = expr->op();
885 if (op == Token::INIT_CONST) BAILOUT("initialize constant"); 826 if (op == Token::INIT_CONST) BAILOUT("initialize constant");
886 827
887 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); 828 Variable* var = expr->target()->AsVariableProxy()->AsVariable();
888 Property* prop = expr->target()->AsProperty(); 829 Property* prop = expr->target()->AsProperty();
889 ASSERT(var == NULL || prop == NULL); 830 ASSERT(var == NULL || prop == NULL);
890 if (var != NULL) { 831 if (var != NULL) {
891 if (var->mode() == Variable::CONST) { 832 if (var->mode() == Variable::CONST) {
892 BAILOUT("Assignment to const"); 833 BAILOUT("Assignment to const");
893 } 834 }
894 // All global variables are supported. 835 // All global variables are supported.
895 if (!var->is_global()) { 836 if (!var->is_global()) {
896 ASSERT(var->slot() != NULL); 837 ASSERT(var->slot() != NULL);
897 Slot::Type type = var->slot()->type(); 838 Slot::Type type = var->slot()->type();
898 if (type == Slot::LOOKUP) { 839 if (type == Slot::LOOKUP) {
899 BAILOUT("Lookup slot"); 840 BAILOUT("Lookup slot");
900 } 841 }
901 } 842 }
902 } else if (prop != NULL) { 843 } else if (prop != NULL) {
903 ProcessExpression(prop->obj(), Expression::kValue); 844 Visit(prop->obj());
904 CHECK_BAILOUT; 845 CHECK_BAILOUT;
905 // We will only visit the key during code generation for keyed property 846 Visit(prop->key());
906 // stores. Leave its expression context uninitialized for named 847 CHECK_BAILOUT;
907 // property stores.
908 if (!prop->key()->IsPropertyName()) {
909 ProcessExpression(prop->key(), Expression::kValue);
910 CHECK_BAILOUT;
911 }
912 } else { 848 } else {
913 // This is a throw reference error. 849 // This is a throw reference error.
914 BAILOUT("non-variable/non-property assignment"); 850 BAILOUT("non-variable/non-property assignment");
915 } 851 }
916 852
917 ProcessExpression(expr->value(), Expression::kValue); 853 Visit(expr->value());
918 } 854 }
919 855
920 856
921 void CodeGenSelector::VisitThrow(Throw* expr) { 857 void CodeGenSelector::VisitThrow(Throw* expr) {
922 ProcessExpression(expr->exception(), Expression::kValue); 858 Visit(expr->exception());
923 } 859 }
924 860
925 861
926 void CodeGenSelector::VisitProperty(Property* expr) { 862 void CodeGenSelector::VisitProperty(Property* expr) {
927 ProcessExpression(expr->obj(), Expression::kValue); 863 Visit(expr->obj());
928 CHECK_BAILOUT; 864 CHECK_BAILOUT;
929 ProcessExpression(expr->key(), Expression::kValue); 865 Visit(expr->key());
930 } 866 }
931 867
932 868
933 void CodeGenSelector::VisitCall(Call* expr) { 869 void CodeGenSelector::VisitCall(Call* expr) {
934 Expression* fun = expr->expression(); 870 Expression* fun = expr->expression();
935 ZoneList<Expression*>* args = expr->arguments(); 871 ZoneList<Expression*>* args = expr->arguments();
936 Variable* var = fun->AsVariableProxy()->AsVariable(); 872 Variable* var = fun->AsVariableProxy()->AsVariable();
937 873
938 // Check for supported calls 874 // Check for supported calls
939 if (var != NULL && var->is_possibly_eval()) { 875 if (var != NULL && var->is_possibly_eval()) {
940 BAILOUT("call to the identifier 'eval'"); 876 BAILOUT("call to the identifier 'eval'");
941 } else if (var != NULL && !var->is_this() && var->is_global()) { 877 } else if (var != NULL && !var->is_this() && var->is_global()) {
942 // Calls to global variables are supported. 878 // Calls to global variables are supported.
943 } else if (var != NULL && var->slot() != NULL && 879 } else if (var != NULL && var->slot() != NULL &&
944 var->slot()->type() == Slot::LOOKUP) { 880 var->slot()->type() == Slot::LOOKUP) {
945 BAILOUT("call to a lookup slot"); 881 BAILOUT("call to a lookup slot");
946 } else if (fun->AsProperty() != NULL) { 882 } else if (fun->AsProperty() != NULL) {
947 Property* prop = fun->AsProperty(); 883 Property* prop = fun->AsProperty();
948 Literal* literal_key = prop->key()->AsLiteral(); 884 Literal* literal_key = prop->key()->AsLiteral();
949 if (literal_key != NULL && literal_key->handle()->IsSymbol()) { 885 Visit(prop->obj());
950 ProcessExpression(prop->obj(), Expression::kValue); 886 CHECK_BAILOUT;
951 CHECK_BAILOUT; 887 Visit(prop->key());
952 } else { 888 CHECK_BAILOUT;
953 ProcessExpression(prop->obj(), Expression::kValue);
954 CHECK_BAILOUT;
955 ProcessExpression(prop->key(), Expression::kValue);
956 CHECK_BAILOUT;
957 }
958 } else { 889 } else {
959 // Otherwise the call is supported if the function expression is. 890 // Otherwise the call is supported if the function expression is.
960 ProcessExpression(fun, Expression::kValue); 891 Visit(fun);
961 } 892 }
962 // Check all arguments to the call. 893 // Check all arguments to the call.
963 for (int i = 0; i < args->length(); i++) { 894 for (int i = 0; i < args->length(); i++) {
964 ProcessExpression(args->at(i), Expression::kValue); 895 Visit(args->at(i));
965 CHECK_BAILOUT; 896 CHECK_BAILOUT;
966 } 897 }
967 } 898 }
968 899
969 900
970 void CodeGenSelector::VisitCallNew(CallNew* expr) { 901 void CodeGenSelector::VisitCallNew(CallNew* expr) {
971 ProcessExpression(expr->expression(), Expression::kValue); 902 Visit(expr->expression());
972 CHECK_BAILOUT; 903 CHECK_BAILOUT;
973 ZoneList<Expression*>* args = expr->arguments(); 904 ZoneList<Expression*>* args = expr->arguments();
974 // Check all arguments to the call 905 // Check all arguments to the call
975 for (int i = 0; i < args->length(); i++) { 906 for (int i = 0; i < args->length(); i++) {
976 ProcessExpression(args->at(i), Expression::kValue); 907 Visit(args->at(i));
977 CHECK_BAILOUT; 908 CHECK_BAILOUT;
978 } 909 }
979 } 910 }
980 911
981 912
982 void CodeGenSelector::VisitCallRuntime(CallRuntime* expr) { 913 void CodeGenSelector::VisitCallRuntime(CallRuntime* expr) {
983 // Check for inline runtime call 914 // Check for inline runtime call
984 if (expr->name()->Get(0) == '_' && 915 if (expr->name()->Get(0) == '_' &&
985 CodeGenerator::FindInlineRuntimeLUT(expr->name()) != NULL) { 916 CodeGenerator::FindInlineRuntimeLUT(expr->name()) != NULL) {
986 BAILOUT("inlined runtime call"); 917 BAILOUT("inlined runtime call");
987 } 918 }
988 // Check all arguments to the call. (Relies on TEMP meaning STACK.) 919 // Check all arguments to the call. (Relies on TEMP meaning STACK.)
989 for (int i = 0; i < expr->arguments()->length(); i++) { 920 for (int i = 0; i < expr->arguments()->length(); i++) {
990 ProcessExpression(expr->arguments()->at(i), Expression::kValue); 921 Visit(expr->arguments()->at(i));
991 CHECK_BAILOUT; 922 CHECK_BAILOUT;
992 } 923 }
993 } 924 }
994 925
995 926
996 void CodeGenSelector::VisitUnaryOperation(UnaryOperation* expr) { 927 void CodeGenSelector::VisitUnaryOperation(UnaryOperation* expr) {
997 switch (expr->op()) { 928 switch (expr->op()) {
998 case Token::VOID: 929 case Token::VOID:
999 ProcessExpression(expr->expression(), Expression::kEffect); 930 case Token::NOT:
931 case Token::TYPEOF:
932 Visit(expr->expression());
1000 break; 933 break;
1001 case Token::NOT: 934 case BIT_NOT:
1002 ProcessExpression(expr->expression(), Expression::kTest); 935 BAILOUT("UnaryOperataion: BIT_NOT");
1003 break; 936 case DELETE:
1004 case Token::TYPEOF: 937 BAILOUT("UnaryOperataion: DELETE");
1005 ProcessExpression(expr->expression(), Expression::kValue);
1006 break;
1007 default: 938 default:
1008 BAILOUT("UnaryOperation"); 939 UNREACHABLE();
1009 } 940 }
1010 } 941 }
1011 942
1012 943
1013 void CodeGenSelector::VisitCountOperation(CountOperation* expr) { 944 void CodeGenSelector::VisitCountOperation(CountOperation* expr) {
1014 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); 945 Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
1015 Property* prop = expr->expression()->AsProperty(); 946 Property* prop = expr->expression()->AsProperty();
1016 ASSERT(var == NULL || prop == NULL); 947 ASSERT(var == NULL || prop == NULL);
1017 if (var != NULL) { 948 if (var != NULL) {
1018 // All global variables are supported. 949 // All global variables are supported.
1019 if (!var->is_global()) { 950 if (!var->is_global()) {
1020 ASSERT(var->slot() != NULL); 951 ASSERT(var->slot() != NULL);
1021 Slot::Type type = var->slot()->type(); 952 Slot::Type type = var->slot()->type();
1022 if (type == Slot::LOOKUP) { 953 if (type == Slot::LOOKUP) {
1023 BAILOUT("CountOperation with lookup slot"); 954 BAILOUT("CountOperation with lookup slot");
1024 } 955 }
1025 } 956 }
1026 } else if (prop != NULL) { 957 } else if (prop != NULL) {
1027 ProcessExpression(prop->obj(), Expression::kValue); 958 Visit(prop->obj());
1028 CHECK_BAILOUT; 959 CHECK_BAILOUT;
1029 // We will only visit the key during code generation for keyed property 960 Visit(prop->key());
1030 // stores. Leave its expression context uninitialized for named 961 CHECK_BAILOUT;
1031 // property stores.
1032 if (!prop->key()->IsPropertyName()) {
1033 ProcessExpression(prop->key(), Expression::kValue);
1034 CHECK_BAILOUT;
1035 }
1036 } else { 962 } else {
1037 // This is a throw reference error. 963 // This is a throw reference error.
1038 BAILOUT("CountOperation non-variable/non-property expression"); 964 BAILOUT("CountOperation non-variable/non-property expression");
1039 } 965 }
1040 } 966 }
1041 967
1042 968
1043 void CodeGenSelector::VisitBinaryOperation(BinaryOperation* expr) { 969 void CodeGenSelector::VisitBinaryOperation(BinaryOperation* expr) {
1044 switch (expr->op()) { 970 Visit(expr->left());
1045 case Token::COMMA: 971 CHECK_BAILOUT;
1046 ProcessExpression(expr->left(), Expression::kEffect); 972 Visit(expr->right());
1047 CHECK_BAILOUT;
1048 ProcessExpression(expr->right(), context_);
1049 break;
1050
1051 case Token::OR:
1052 switch (context_) {
1053 case Expression::kUninitialized:
1054 UNREACHABLE();
1055 case Expression::kEffect: // Fall through.
1056 case Expression::kTest: // Fall through.
1057 case Expression::kTestValue:
1058 // The left subexpression's value is not needed, it is in a pure
1059 // test context.
1060 ProcessExpression(expr->left(), Expression::kTest);
1061 break;
1062 case Expression::kValue: // Fall through.
1063 case Expression::kValueTest:
1064 // The left subexpression's value is needed, it is in a hybrid
1065 // value/test context.
1066 ProcessExpression(expr->left(), Expression::kValueTest);
1067 break;
1068 }
1069 CHECK_BAILOUT;
1070 ProcessExpression(expr->right(), context_);
1071 break;
1072
1073 case Token::AND:
1074 switch (context_) {
1075 case Expression::kUninitialized:
1076 UNREACHABLE();
1077 case Expression::kEffect: // Fall through.
1078 case Expression::kTest: // Fall through.
1079 case Expression::kValueTest:
1080 // The left subexpression's value is not needed, it is in a pure
1081 // test context.
1082 ProcessExpression(expr->left(), Expression::kTest);
1083 break;
1084 case Expression::kValue: // Fall through.
1085 case Expression::kTestValue:
1086 // The left subexpression's value is needed, it is in a hybrid
1087 // test/value context.
1088 ProcessExpression(expr->left(), Expression::kTestValue);
1089 break;
1090 }
1091 CHECK_BAILOUT;
1092 ProcessExpression(expr->right(), context_);
1093 break;
1094
1095 case Token::ADD:
1096 case Token::SUB:
1097 case Token::DIV:
1098 case Token::MOD:
1099 case Token::MUL:
1100 case Token::BIT_OR:
1101 case Token::BIT_AND:
1102 case Token::BIT_XOR:
1103 case Token::SHL:
1104 case Token::SHR:
1105 case Token::SAR:
1106 ProcessExpression(expr->left(), Expression::kValue);
1107 CHECK_BAILOUT;
1108 ProcessExpression(expr->right(), Expression::kValue);
1109 break;
1110
1111 default:
1112 BAILOUT("Unsupported binary operation");
1113 }
1114 } 973 }
1115 974
1116 975
1117 void CodeGenSelector::VisitCompareOperation(CompareOperation* expr) { 976 void CodeGenSelector::VisitCompareOperation(CompareOperation* expr) {
1118 ProcessExpression(expr->left(), Expression::kValue); 977 Visit(expr->left());
1119 CHECK_BAILOUT; 978 CHECK_BAILOUT;
1120 ProcessExpression(expr->right(), Expression::kValue); 979 Visit(expr->right());
1121 } 980 }
1122 981
1123 982
1124 void CodeGenSelector::VisitThisFunction(ThisFunction* expr) { 983 void CodeGenSelector::VisitThisFunction(ThisFunction* expr) {}
1125 // ThisFunction is supported.
1126 }
1127 984
1128 #undef BAILOUT 985 #undef BAILOUT
1129 #undef CHECK_BAILOUT 986 #undef CHECK_BAILOUT
1130 987
1131 988
1132 } } // namespace v8::internal 989 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ast.h ('k') | src/fast-codegen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698