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