| 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 |