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/typing-asm.h" | 5 #include "src/typing-asm.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "src/v8.h" | 9 #include "src/v8.h" |
10 | 10 |
(...skipping 916 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
927 } else { | 927 } else { |
928 SetResult(expr, expected_type_); | 928 SetResult(expr, expected_type_); |
929 } | 929 } |
930 return; | 930 return; |
931 } | 931 } |
932 } | 932 } |
933 | 933 |
934 FAIL(expr, "invalid property access"); | 934 FAIL(expr, "invalid property access"); |
935 } | 935 } |
936 | 936 |
| 937 void AsmTyper::CheckPolymorphicStdlibArguments( |
| 938 enum StandardMember standard_member, ZoneList<Expression*>* args) { |
| 939 if (args->length() == 0) { |
| 940 return; |
| 941 } |
| 942 // Handle polymorphic stdlib functions specially. |
| 943 Expression* arg0 = args->at(0); |
| 944 Type* arg0_type = arg0->bounds().upper; |
| 945 switch (standard_member) { |
| 946 case kMathFround: { |
| 947 if (!arg0_type->Is(cache_.kAsmFloat) && |
| 948 !arg0_type->Is(cache_.kAsmDouble) && |
| 949 !arg0_type->Is(cache_.kAsmSigned) && |
| 950 !arg0_type->Is(cache_.kAsmUnsigned)) { |
| 951 FAIL(arg0, "illegal function argument type"); |
| 952 } |
| 953 break; |
| 954 } |
| 955 case kMathCeil: |
| 956 case kMathFloor: |
| 957 case kMathSqrt: { |
| 958 if (!arg0_type->Is(cache_.kAsmFloat) && |
| 959 !arg0_type->Is(cache_.kAsmDouble)) { |
| 960 FAIL(arg0, "illegal function argument type"); |
| 961 } |
| 962 break; |
| 963 } |
| 964 case kMathAbs: |
| 965 case kMathMin: |
| 966 case kMathMax: { |
| 967 if (!arg0_type->Is(cache_.kAsmFloat) && |
| 968 !arg0_type->Is(cache_.kAsmDouble) && |
| 969 !arg0_type->Is(cache_.kAsmSigned)) { |
| 970 FAIL(arg0, "illegal function argument type"); |
| 971 } |
| 972 if (args->length() > 1) { |
| 973 Type* other = Type::Intersect(args->at(0)->bounds().upper, |
| 974 args->at(1)->bounds().upper, zone()); |
| 975 if (!other->Is(cache_.kAsmFloat) && !other->Is(cache_.kAsmDouble) && |
| 976 !other->Is(cache_.kAsmSigned)) { |
| 977 FAIL(arg0, "function arguments types don't match"); |
| 978 } |
| 979 } |
| 980 break; |
| 981 } |
| 982 default: { break; } |
| 983 } |
| 984 } |
937 | 985 |
938 void AsmTyper::VisitCall(Call* expr) { | 986 void AsmTyper::VisitCall(Call* expr) { |
939 Type* expected_type = expected_type_; | 987 Type* expected_type = expected_type_; |
940 RECURSE(VisitWithExpectation(expr->expression(), Type::Any(), | 988 RECURSE(VisitWithExpectation(expr->expression(), Type::Any(), |
941 "callee expected to be any")); | 989 "callee expected to be any")); |
942 StandardMember standard_member = kNone; | 990 StandardMember standard_member = kNone; |
943 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 991 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
944 if (proxy) { | 992 if (proxy) { |
945 standard_member = VariableAsStandardMember(proxy->var()); | 993 standard_member = VariableAsStandardMember(proxy->var()); |
946 } | 994 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
980 for (int i = 0; i < args->length(); ++i) { | 1028 for (int i = 0; i < args->length(); ++i) { |
981 Expression* arg = args->at(i); | 1029 Expression* arg = args->at(i); |
982 RECURSE(VisitWithExpectation( | 1030 RECURSE(VisitWithExpectation( |
983 arg, fun_type->Parameter(i), | 1031 arg, fun_type->Parameter(i), |
984 "call argument expected to match callee parameter")); | 1032 "call argument expected to match callee parameter")); |
985 if (standard_member != kNone && standard_member != kMathFround && | 1033 if (standard_member != kNone && standard_member != kMathFround && |
986 i == 0) { | 1034 i == 0) { |
987 result_type = computed_type_; | 1035 result_type = computed_type_; |
988 } | 1036 } |
989 } | 1037 } |
990 // Handle polymorphic stdlib functions specially. | 1038 RECURSE(CheckPolymorphicStdlibArguments(standard_member, args)); |
991 if (standard_member == kMathCeil || standard_member == kMathFloor || | |
992 standard_member == kMathSqrt) { | |
993 if (!args->at(0)->bounds().upper->Is(cache_.kAsmFloat) && | |
994 !args->at(0)->bounds().upper->Is(cache_.kAsmDouble)) { | |
995 FAIL(expr, "illegal function argument type"); | |
996 } | |
997 } else if (standard_member == kMathAbs || standard_member == kMathMin || | |
998 standard_member == kMathMax) { | |
999 if (!args->at(0)->bounds().upper->Is(cache_.kAsmFloat) && | |
1000 !args->at(0)->bounds().upper->Is(cache_.kAsmDouble) && | |
1001 !args->at(0)->bounds().upper->Is(cache_.kAsmSigned)) { | |
1002 FAIL(expr, "illegal function argument type"); | |
1003 } | |
1004 if (args->length() > 1) { | |
1005 Type* other = Type::Intersect(args->at(0)->bounds().upper, | |
1006 args->at(1)->bounds().upper, zone()); | |
1007 if (!other->Is(cache_.kAsmFloat) && !other->Is(cache_.kAsmDouble) && | |
1008 !other->Is(cache_.kAsmSigned)) { | |
1009 FAIL(expr, "function arguments types don't match"); | |
1010 } | |
1011 } | |
1012 } | |
1013 intish_ = 0; | 1039 intish_ = 0; |
1014 IntersectResult(expr, result_type); | 1040 IntersectResult(expr, result_type); |
1015 } | 1041 } |
1016 } else { | 1042 } else { |
1017 FAIL(expr, "invalid callee"); | 1043 FAIL(expr, "invalid callee"); |
1018 } | 1044 } |
1019 } | 1045 } |
1020 | 1046 |
1021 | 1047 |
1022 void AsmTyper::VisitCallNew(CallNew* expr) { | 1048 void AsmTyper::VisitCallNew(CallNew* expr) { |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1149 RECURSE(VisitWithExpectation(expr->right(), Type::Any(), | 1175 RECURSE(VisitWithExpectation(expr->right(), Type::Any(), |
1150 "right comma operand expected to be any")); | 1176 "right comma operand expected to be any")); |
1151 IntersectResult(expr, computed_type_); | 1177 IntersectResult(expr, computed_type_); |
1152 return; | 1178 return; |
1153 } | 1179 } |
1154 case Token::OR: | 1180 case Token::OR: |
1155 case Token::AND: | 1181 case Token::AND: |
1156 FAIL(expr, "illegal logical operator"); | 1182 FAIL(expr, "illegal logical operator"); |
1157 case Token::BIT_OR: { | 1183 case Token::BIT_OR: { |
1158 // BIT_OR allows Any since it is used as a type coercion. | 1184 // BIT_OR allows Any since it is used as a type coercion. |
1159 VisitIntegerBitwiseOperator(expr, Type::Any(), cache_.kAsmIntQ, | 1185 RECURSE(VisitIntegerBitwiseOperator(expr, Type::Any(), cache_.kAsmIntQ, |
1160 cache_.kAsmSigned, true); | 1186 cache_.kAsmSigned, true)); |
1161 if (expr->left()->IsCall() && expr->op() == Token::BIT_OR && | 1187 if (expr->left()->IsCall() && expr->op() == Token::BIT_OR && |
1162 Type::Number()->Is(expr->left()->bounds().upper)) { | 1188 Type::Number()->Is(expr->left()->bounds().upper)) { |
1163 // Force the return types of foreign functions. | 1189 // Force the return types of foreign functions. |
1164 expr->left()->set_bounds(Bounds(cache_.kAsmSigned)); | 1190 expr->left()->set_bounds(Bounds(cache_.kAsmSigned)); |
1165 } | 1191 } |
| 1192 if (in_function_ && !expr->left()->bounds().upper->Is(cache_.kAsmIntQ)) { |
| 1193 FAIL(expr->left(), "intish required"); |
| 1194 } |
1166 return; | 1195 return; |
1167 } | 1196 } |
1168 case Token::BIT_XOR: { | 1197 case Token::BIT_XOR: { |
1169 // Handle booleans specially to handle de-sugared ! | 1198 // Handle booleans specially to handle de-sugared ! |
1170 Literal* left = expr->left()->AsLiteral(); | 1199 Literal* left = expr->left()->AsLiteral(); |
1171 if (left && left->value()->IsBoolean()) { | 1200 if (left && left->value()->IsBoolean()) { |
1172 if (left->ToBooleanIsTrue()) { | 1201 if (left->ToBooleanIsTrue()) { |
1173 left->set_bounds(Bounds(cache_.kSingletonOne)); | 1202 left->set_bounds(Bounds(cache_.kSingletonOne)); |
1174 RECURSE(VisitWithExpectation(expr->right(), cache_.kAsmIntQ, | 1203 RECURSE(VisitWithExpectation(expr->right(), cache_.kAsmIntQ, |
1175 "not operator expects an integer")); | 1204 "not operator expects an integer")); |
1176 IntersectResult(expr, cache_.kAsmSigned); | 1205 IntersectResult(expr, cache_.kAsmSigned); |
1177 return; | 1206 return; |
1178 } else { | 1207 } else { |
1179 FAIL(left, "unexpected false"); | 1208 FAIL(left, "unexpected false"); |
1180 } | 1209 } |
1181 } | 1210 } |
1182 // BIT_XOR allows Any since it is used as a type coercion (via ~~). | 1211 // BIT_XOR allows Any since it is used as a type coercion (via ~~). |
1183 VisitIntegerBitwiseOperator(expr, Type::Any(), cache_.kAsmIntQ, | 1212 RECURSE(VisitIntegerBitwiseOperator(expr, Type::Any(), cache_.kAsmIntQ, |
1184 cache_.kAsmSigned, true); | 1213 cache_.kAsmSigned, true)); |
1185 return; | 1214 return; |
1186 } | 1215 } |
1187 case Token::SHR: { | 1216 case Token::SHR: { |
1188 VisitIntegerBitwiseOperator(expr, cache_.kAsmIntQ, cache_.kAsmIntQ, | 1217 RECURSE(VisitIntegerBitwiseOperator( |
1189 cache_.kAsmUnsigned, false); | 1218 expr, cache_.kAsmIntQ, cache_.kAsmIntQ, cache_.kAsmUnsigned, false)); |
1190 return; | 1219 return; |
1191 } | 1220 } |
1192 case Token::SHL: | 1221 case Token::SHL: |
1193 case Token::SAR: | 1222 case Token::SAR: |
1194 case Token::BIT_AND: { | 1223 case Token::BIT_AND: { |
1195 VisitIntegerBitwiseOperator(expr, cache_.kAsmIntQ, cache_.kAsmIntQ, | 1224 RECURSE(VisitIntegerBitwiseOperator( |
1196 cache_.kAsmSigned, false); | 1225 expr, cache_.kAsmIntQ, cache_.kAsmIntQ, cache_.kAsmSigned, false)); |
1197 return; | 1226 return; |
1198 } | 1227 } |
1199 case Token::ADD: | 1228 case Token::ADD: |
1200 case Token::SUB: | 1229 case Token::SUB: |
1201 case Token::MUL: | 1230 case Token::MUL: |
1202 case Token::DIV: | 1231 case Token::DIV: |
1203 case Token::MOD: { | 1232 case Token::MOD: { |
1204 RECURSE(VisitWithExpectation( | 1233 RECURSE(VisitWithExpectation( |
1205 expr->left(), Type::Number(), | 1234 expr->left(), Type::Number(), |
1206 "left arithmetic operand expected to be number")); | 1235 "left arithmetic operand expected to be number")); |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1571 } | 1600 } |
1572 | 1601 |
1573 | 1602 |
1574 void AsmTyper::VisitRewritableExpression(RewritableExpression* expr) { | 1603 void AsmTyper::VisitRewritableExpression(RewritableExpression* expr) { |
1575 RECURSE(Visit(expr->expression())); | 1604 RECURSE(Visit(expr->expression())); |
1576 } | 1605 } |
1577 | 1606 |
1578 | 1607 |
1579 } // namespace internal | 1608 } // namespace internal |
1580 } // namespace v8 | 1609 } // namespace v8 |
OLD | NEW |