OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/typing-asm.h" | 7 #include "src/typing-asm.h" |
8 | 8 |
9 #include "src/ast.h" | 9 #include "src/ast.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 RECURSE(VisitWithExpectation(expr->condition(), cache_.kInt32, | 439 RECURSE(VisitWithExpectation(expr->condition(), cache_.kInt32, |
440 "condition expected to be integer")); | 440 "condition expected to be integer")); |
441 RECURSE(VisitWithExpectation( | 441 RECURSE(VisitWithExpectation( |
442 expr->then_expression(), expected_type_, | 442 expr->then_expression(), expected_type_, |
443 "conditional then branch type mismatch with enclosing expression")); | 443 "conditional then branch type mismatch with enclosing expression")); |
444 Type* then_type = computed_type_; | 444 Type* then_type = computed_type_; |
445 RECURSE(VisitWithExpectation( | 445 RECURSE(VisitWithExpectation( |
446 expr->else_expression(), expected_type_, | 446 expr->else_expression(), expected_type_, |
447 "conditional else branch type mismatch with enclosing expression")); | 447 "conditional else branch type mismatch with enclosing expression")); |
448 Type* else_type = computed_type_; | 448 Type* else_type = computed_type_; |
449 Type* type = Type::Intersect(then_type, else_type, zone()); | 449 Type* type = Type::Union(then_type, else_type, zone()); |
450 if (!(type->Is(cache_.kInt32) || type->Is(cache_.kFloat64))) { | 450 if (!(type->Is(cache_.kInt32) || type->Is(cache_.kUint32) || |
| 451 type->Is(cache_.kFloat32) || type->Is(cache_.kFloat64))) { |
451 FAIL(expr, "ill-typed conditional"); | 452 FAIL(expr, "ill-typed conditional"); |
452 } | 453 } |
453 IntersectResult(expr, type); | 454 IntersectResult(expr, type); |
454 } | 455 } |
455 | 456 |
456 | 457 |
457 void AsmTyper::VisitVariableProxy(VariableProxy* expr) { | 458 void AsmTyper::VisitVariableProxy(VariableProxy* expr) { |
458 Variable* var = expr->var(); | 459 Variable* var = expr->var(); |
459 if (GetType(var) == NULL) { | 460 if (GetType(var) == NULL) { |
460 FAIL(expr, "unbound variable"); | 461 FAIL(expr, "unbound variable"); |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
788 } | 789 } |
789 } | 790 } |
790 | 791 |
791 | 792 |
792 void AsmTyper::VisitCountOperation(CountOperation* expr) { | 793 void AsmTyper::VisitCountOperation(CountOperation* expr) { |
793 FAIL(expr, "increment or decrement operator encountered"); | 794 FAIL(expr, "increment or decrement operator encountered"); |
794 } | 795 } |
795 | 796 |
796 | 797 |
797 void AsmTyper::VisitIntegerBinaryOperation(BinaryOperation* expr, | 798 void AsmTyper::VisitIntegerBinaryOperation(BinaryOperation* expr, |
798 Type* expected_type, | 799 Type* left_expected, |
799 Type* result_type) { | 800 Type* right_expected, |
800 RECURSE(VisitWithExpectation(expr->left(), expected_type, | 801 Type* result_type, bool conversion) { |
| 802 RECURSE(VisitWithExpectation(expr->left(), left_expected, |
801 "left bit operand expected to be integer")); | 803 "left bit operand expected to be integer")); |
802 int left_intish = intish_; | 804 int left_intish = intish_; |
803 RECURSE(VisitWithExpectation(expr->right(), expected_type, | 805 Type* left_type = computed_type_; |
| 806 RECURSE(VisitWithExpectation(expr->right(), right_expected, |
804 "right bit operand expected to be integer")); | 807 "right bit operand expected to be integer")); |
805 int right_intish = intish_; | 808 int right_intish = intish_; |
| 809 Type* right_type = computed_type_; |
806 if (left_intish > kMaxUncombinedAdditiveSteps) { | 810 if (left_intish > kMaxUncombinedAdditiveSteps) { |
807 FAIL(expr, "too many consecutive additive ops"); | 811 FAIL(expr, "too many consecutive additive ops"); |
808 } | 812 } |
809 if (right_intish > kMaxUncombinedAdditiveSteps) { | 813 if (right_intish > kMaxUncombinedAdditiveSteps) { |
810 FAIL(expr, "too many consecutive additive ops"); | 814 FAIL(expr, "too many consecutive additive ops"); |
811 } | 815 } |
812 intish_ = 0; | 816 intish_ = 0; |
| 817 if (!conversion) { |
| 818 if (!left_type->Is(right_type) || !right_type->Is(left_type)) { |
| 819 FAIL(expr, "ill typed bitwise operation"); |
| 820 } |
| 821 } |
813 IntersectResult(expr, result_type); | 822 IntersectResult(expr, result_type); |
814 } | 823 } |
815 | 824 |
816 | 825 |
817 void AsmTyper::VisitBinaryOperation(BinaryOperation* expr) { | 826 void AsmTyper::VisitBinaryOperation(BinaryOperation* expr) { |
818 switch (expr->op()) { | 827 switch (expr->op()) { |
819 case Token::COMMA: { | 828 case Token::COMMA: { |
820 RECURSE(VisitWithExpectation(expr->left(), Type::Any(), | 829 RECURSE(VisitWithExpectation(expr->left(), Type::Any(), |
821 "left comma operand expected to be any")); | 830 "left comma operand expected to be any")); |
822 RECURSE(VisitWithExpectation(expr->right(), Type::Any(), | 831 RECURSE(VisitWithExpectation(expr->right(), Type::Any(), |
823 "right comma operand expected to be any")); | 832 "right comma operand expected to be any")); |
824 IntersectResult(expr, computed_type_); | 833 IntersectResult(expr, computed_type_); |
825 return; | 834 return; |
826 } | 835 } |
827 case Token::OR: | 836 case Token::OR: |
828 case Token::AND: | 837 case Token::AND: |
829 FAIL(expr, "logical operator encountered"); | 838 FAIL(expr, "logical operator encountered"); |
830 case Token::BIT_OR: { | 839 case Token::BIT_OR: { |
831 // BIT_OR allows Any since it is used as a type coercion. | 840 // BIT_OR allows Any since it is used as a type coercion. |
832 VisitIntegerBinaryOperation(expr, Type::Any(), cache_.kInt32); | 841 VisitIntegerBinaryOperation(expr, Type::Any(), cache_.kIntegral32, |
| 842 cache_.kInt32, true); |
833 return; | 843 return; |
834 } | 844 } |
835 case Token::BIT_XOR: { | 845 case Token::BIT_XOR: { |
836 // BIT_XOR allows Number since it is used as a type coercion (encoding ~). | 846 // BIT_XOR allows Number since it is used as a type coercion (via ~~). |
837 VisitIntegerBinaryOperation(expr, Type::Number(), cache_.kInt32); | 847 VisitIntegerBinaryOperation(expr, Type::Number(), cache_.kIntegral32, |
| 848 cache_.kInt32, true); |
838 return; | 849 return; |
839 } | 850 } |
840 case Token::SHR: { | 851 case Token::SHR: { |
841 VisitIntegerBinaryOperation(expr, Type::Number(), cache_.kUint32); | 852 VisitIntegerBinaryOperation(expr, cache_.kIntegral32, cache_.kIntegral32, |
| 853 cache_.kUint32, false); |
842 return; | 854 return; |
843 } | 855 } |
844 case Token::SHL: | 856 case Token::SHL: |
845 case Token::SAR: | 857 case Token::SAR: |
846 case Token::BIT_AND: { | 858 case Token::BIT_AND: { |
847 VisitIntegerBinaryOperation(expr, cache_.kInt32, cache_.kInt32); | 859 VisitIntegerBinaryOperation(expr, cache_.kIntegral32, cache_.kIntegral32, |
| 860 cache_.kInt32, false); |
848 return; | 861 return; |
849 } | 862 } |
850 case Token::ADD: | 863 case Token::ADD: |
851 case Token::SUB: | 864 case Token::SUB: |
852 case Token::MUL: | 865 case Token::MUL: |
853 case Token::DIV: | 866 case Token::DIV: |
854 case Token::MOD: { | 867 case Token::MOD: { |
855 RECURSE(VisitWithExpectation( | 868 RECURSE(VisitWithExpectation( |
856 expr->left(), Type::Number(), | 869 expr->left(), Type::Number(), |
857 "left arithmetic operand expected to be number")); | 870 "left arithmetic operand expected to be number")); |
858 Type* left_type = computed_type_; | 871 Type* left_type = computed_type_; |
859 int left_intish = intish_; | 872 int left_intish = intish_; |
860 RECURSE(VisitWithExpectation( | 873 RECURSE(VisitWithExpectation( |
861 expr->right(), Type::Number(), | 874 expr->right(), Type::Number(), |
862 "right arithmetic operand expected to be number")); | 875 "right arithmetic operand expected to be number")); |
863 Type* right_type = computed_type_; | 876 Type* right_type = computed_type_; |
864 int right_intish = intish_; | 877 int right_intish = intish_; |
865 Type* type = Type::Union(left_type, right_type, zone()); | 878 Type* type = Type::Union(left_type, right_type, zone()); |
866 if (type->Is(cache_.kInt32)) { | 879 if (type->Is(cache_.kInt32) || type->Is(cache_.kUint32)) { |
867 if (expr->op() == Token::MUL) { | 880 if (expr->op() == Token::MUL) { |
868 if (!expr->left()->IsLiteral() && !expr->right()->IsLiteral()) { | 881 if (!expr->left()->IsLiteral() && !expr->right()->IsLiteral()) { |
869 FAIL(expr, "direct integer multiply forbidden"); | 882 FAIL(expr, "direct integer multiply forbidden"); |
870 } | 883 } |
871 intish_ = 0; | 884 intish_ = 0; |
872 IntersectResult(expr, cache_.kInt32); | 885 IntersectResult(expr, cache_.kInt32); |
873 return; | 886 return; |
874 } else { | 887 } else { |
875 intish_ = left_intish + right_intish + 1; | 888 intish_ = left_intish + right_intish + 1; |
876 if (expr->op() == Token::ADD || expr->op() == Token::SUB) { | 889 if (expr->op() == Token::ADD || expr->op() == Token::SUB) { |
877 if (intish_ > kMaxUncombinedAdditiveSteps) { | 890 if (intish_ > kMaxUncombinedAdditiveSteps) { |
878 FAIL(expr, "too many consecutive additive ops"); | 891 FAIL(expr, "too many consecutive additive ops"); |
879 } | 892 } |
880 } else { | 893 } else { |
881 if (intish_ > kMaxUncombinedMultiplicativeSteps) { | 894 if (intish_ > kMaxUncombinedMultiplicativeSteps) { |
882 FAIL(expr, "too many consecutive multiplicative ops"); | 895 FAIL(expr, "too many consecutive multiplicative ops"); |
883 } | 896 } |
884 } | 897 } |
885 IntersectResult(expr, cache_.kInt32); | 898 IntersectResult(expr, cache_.kInt32); |
886 return; | 899 return; |
887 } | 900 } |
888 } else if (type->Is(Type::Number())) { | 901 } else if (expr->op() == Token::MUL && |
| 902 left_type->Is(cache_.kIntegral32) && |
| 903 right_type->Is(cache_.kFloat64)) { |
| 904 // For unary +, expressed as x * 1.0 |
| 905 IntersectResult(expr, cache_.kFloat64); |
| 906 return; |
| 907 } else if (type->Is(cache_.kFloat32) && expr->op() != Token::MOD) { |
| 908 IntersectResult(expr, cache_.kFloat32); |
| 909 return; |
| 910 } else if (type->Is(cache_.kFloat64)) { |
889 IntersectResult(expr, cache_.kFloat64); | 911 IntersectResult(expr, cache_.kFloat64); |
890 return; | 912 return; |
891 } else { | 913 } else { |
892 FAIL(expr, "ill-typed arithmetic operation"); | 914 FAIL(expr, "ill-typed arithmetic operation"); |
893 } | 915 } |
894 } | 916 } |
895 default: | 917 default: |
896 UNREACHABLE(); | 918 UNREACHABLE(); |
897 } | 919 } |
898 } | 920 } |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1078 computed_type_->Print(); | 1100 computed_type_->Print(); |
1079 PrintF("Expected type: "); | 1101 PrintF("Expected type: "); |
1080 expected_type_->Print(); | 1102 expected_type_->Print(); |
1081 #endif | 1103 #endif |
1082 FAIL(expr, msg); | 1104 FAIL(expr, msg); |
1083 } | 1105 } |
1084 expected_type_ = save; | 1106 expected_type_ = save; |
1085 } | 1107 } |
1086 } // namespace internal | 1108 } // namespace internal |
1087 } // namespace v8 | 1109 } // namespace v8 |
OLD | NEW |