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 890 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
901 // Only recurse at this point so that we avoid needing | 901 // Only recurse at this point so that we avoid needing |
902 // stdlib.Math to have a real type. | 902 // stdlib.Math to have a real type. |
903 RECURSE(VisitWithExpectation(expr->obj(), Type::Any(), "bad propety object")); | 903 RECURSE(VisitWithExpectation(expr->obj(), Type::Any(), "bad propety object")); |
904 | 904 |
905 // For heap view or function table access. | 905 // For heap view or function table access. |
906 if (computed_type_->IsArray()) { | 906 if (computed_type_->IsArray()) { |
907 VisitHeapAccess(expr, false, NULL); | 907 VisitHeapAccess(expr, false, NULL); |
908 return; | 908 return; |
909 } | 909 } |
910 | 910 |
911 // stdlib.x or foreign.x | |
912 VariableProxy* proxy = expr->obj()->AsVariableProxy(); | 911 VariableProxy* proxy = expr->obj()->AsVariableProxy(); |
913 if (proxy != NULL) { | 912 if (proxy != NULL) { |
914 Variable* var = proxy->var(); | 913 Variable* var = proxy->var(); |
915 if (var->location() == VariableLocation::PARAMETER && var->index() == 1) { | 914 if (var->location() == VariableLocation::PARAMETER && var->index() == 1) { |
916 // foreign.x is ok. | 915 // foreign.x - Function represent as () -> Any |
917 SetResult(expr, expected_type_); | 916 if (Type::Any()->Is(expected_type_)) { |
917 SetResult(expr, Type::Function(Type::Any(), zone())); | |
918 } else { | |
919 SetResult(expr, expected_type_); | |
920 } | |
918 return; | 921 return; |
919 } | 922 } |
920 } | 923 } |
921 | 924 |
922 FAIL(expr, "invalid property access"); | 925 FAIL(expr, "invalid property access"); |
923 } | 926 } |
924 | 927 |
925 | 928 |
926 void AsmTyper::VisitCall(Call* expr) { | 929 void AsmTyper::VisitCall(Call* expr) { |
927 Type* expected_type = expected_type_; | 930 Type* expected_type = expected_type_; |
928 RECURSE(VisitWithExpectation(expr->expression(), Type::Any(), | 931 RECURSE(VisitWithExpectation(expr->expression(), Type::Any(), |
929 "callee expected to be any")); | 932 "callee expected to be any")); |
930 StandardMember standard_member = kNone; | 933 StandardMember standard_member = kNone; |
931 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 934 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
932 if (proxy) { | 935 if (proxy) { |
933 standard_member = VariableAsStandardMember(proxy->var()); | 936 standard_member = VariableAsStandardMember(proxy->var()); |
934 } | 937 } |
935 if (!in_function_ && (proxy == NULL || standard_member != kMathFround)) { | 938 if (!in_function_ && (proxy == NULL || standard_member != kMathFround)) { |
936 FAIL(expr, "calls forbidden outside function bodies"); | 939 FAIL(expr, "calls forbidden outside function bodies"); |
937 } | 940 } |
938 if (proxy == NULL && !expr->expression()->IsProperty()) { | 941 if (proxy == NULL && !expr->expression()->IsProperty()) { |
939 FAIL(expr, "calls must be to bound variables or function tables"); | 942 FAIL(expr, "calls must be to bound variables or function tables"); |
940 } | 943 } |
941 if (computed_type_->IsFunction()) { | 944 if (computed_type_->IsFunction()) { |
942 FunctionType* fun_type = computed_type_->AsFunction(); | 945 FunctionType* fun_type = computed_type_->AsFunction(); |
943 Type* result_type = fun_type->Result(); | 946 Type* result_type = fun_type->Result(); |
944 ZoneList<Expression*>* args = expr->arguments(); | 947 ZoneList<Expression*>* args = expr->arguments(); |
945 if (fun_type->Arity() != args->length()) { | 948 if (Type::Any()->Is(result_type)) { |
946 FAIL(expr, "call with wrong arity"); | 949 // For foreign calls. |
947 } | 950 ZoneList<Expression*>* args = expr->arguments(); |
brucedawson
2016/02/05 23:35:50
Not a serious problem, but this line of code is re
bradn
2016/02/06 00:32:54
Ah, bad merge.
Thanks!
| |
948 for (int i = 0; i < args->length(); ++i) { | 951 for (int i = 0; i < args->length(); ++i) { |
949 Expression* arg = args->at(i); | 952 Expression* arg = args->at(i); |
950 RECURSE(VisitWithExpectation( | 953 RECURSE(VisitWithExpectation( |
951 arg, fun_type->Parameter(i), | 954 arg, Type::Any(), "foreign call argument expected to be any")); |
952 "call argument expected to match callee parameter")); | 955 // Checking for asm extern types explicitly, as the type system |
953 if (standard_member != kNone && standard_member != kMathFround && | 956 // doesn't correctly check their inheritance relationship. |
954 i == 0) { | 957 if (!computed_type_->Is(cache_.kAsmSigned) && |
955 result_type = computed_type_; | 958 !computed_type_->Is(cache_.kAsmFixnum) && |
956 } | 959 !computed_type_->Is(cache_.kAsmDouble)) { |
957 } | 960 FAIL(arg, |
958 // Handle polymorphic stdlib functions specially. | 961 "foreign call argument expected to be int, double, or fixnum"); |
959 if (standard_member == kMathCeil || standard_member == kMathFloor || | |
960 standard_member == kMathSqrt) { | |
961 if (!args->at(0)->bounds().upper->Is(cache_.kAsmFloat) && | |
962 !args->at(0)->bounds().upper->Is(cache_.kAsmDouble)) { | |
963 FAIL(expr, "illegal function argument type"); | |
964 } | |
965 } else if (standard_member == kMathAbs || standard_member == kMathMin || | |
966 standard_member == kMathMax) { | |
967 if (!args->at(0)->bounds().upper->Is(cache_.kAsmFloat) && | |
968 !args->at(0)->bounds().upper->Is(cache_.kAsmDouble) && | |
969 !args->at(0)->bounds().upper->Is(cache_.kAsmSigned)) { | |
970 FAIL(expr, "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(expr, "function arguments types don't match"); | |
978 } | 962 } |
979 } | 963 } |
964 intish_ = 0; | |
965 expr->expression()->set_bounds( | |
966 Bounds(Type::Function(Type::Any(), zone()))); | |
967 IntersectResult(expr, expected_type); | |
968 } else { | |
969 if (fun_type->Arity() != args->length()) { | |
970 FAIL(expr, "call with wrong arity"); | |
971 } | |
972 for (int i = 0; i < args->length(); ++i) { | |
973 Expression* arg = args->at(i); | |
974 RECURSE(VisitWithExpectation( | |
975 arg, fun_type->Parameter(i), | |
976 "call argument expected to match callee parameter")); | |
977 if (standard_member != kNone && standard_member != kMathFround && | |
978 i == 0) { | |
979 result_type = computed_type_; | |
980 } | |
981 } | |
982 // Handle polymorphic stdlib functions specially. | |
983 if (standard_member == kMathCeil || standard_member == kMathFloor || | |
984 standard_member == kMathSqrt) { | |
985 if (!args->at(0)->bounds().upper->Is(cache_.kAsmFloat) && | |
986 !args->at(0)->bounds().upper->Is(cache_.kAsmDouble)) { | |
987 FAIL(expr, "illegal function argument type"); | |
988 } | |
989 } else if (standard_member == kMathAbs || standard_member == kMathMin || | |
990 standard_member == kMathMax) { | |
991 if (!args->at(0)->bounds().upper->Is(cache_.kAsmFloat) && | |
992 !args->at(0)->bounds().upper->Is(cache_.kAsmDouble) && | |
993 !args->at(0)->bounds().upper->Is(cache_.kAsmSigned)) { | |
994 FAIL(expr, "illegal function argument type"); | |
995 } | |
996 if (args->length() > 1) { | |
997 Type* other = Type::Intersect(args->at(0)->bounds().upper, | |
998 args->at(1)->bounds().upper, zone()); | |
999 if (!other->Is(cache_.kAsmFloat) && !other->Is(cache_.kAsmDouble) && | |
1000 !other->Is(cache_.kAsmSigned)) { | |
1001 FAIL(expr, "function arguments types don't match"); | |
1002 } | |
1003 } | |
1004 } | |
1005 intish_ = 0; | |
1006 IntersectResult(expr, result_type); | |
980 } | 1007 } |
981 intish_ = 0; | |
982 IntersectResult(expr, result_type); | |
983 } else if (computed_type_->Is(Type::Any())) { | |
984 // For foreign calls. | |
985 ZoneList<Expression*>* args = expr->arguments(); | |
986 for (int i = 0; i < args->length(); ++i) { | |
987 Expression* arg = args->at(i); | |
988 RECURSE(VisitWithExpectation(arg, Type::Any(), | |
989 "foreign call argument expected to be any")); | |
990 // Checking for asm extern types explicitly, as the type system | |
991 // doesn't correctly check their inheritance relationship. | |
992 if (!computed_type_->Is(cache_.kAsmSigned) && | |
993 !computed_type_->Is(cache_.kAsmFixnum) && | |
994 !computed_type_->Is(cache_.kAsmDouble)) { | |
995 FAIL(arg, | |
996 "foreign call argument expected to be int, double, or fixnum"); | |
997 } | |
998 } | |
999 intish_ = kMaxUncombinedAdditiveSteps; | |
1000 expr->expression()->set_bounds(Bounds(Type::Function())); | |
1001 IntersectResult(expr, expected_type); | |
1002 } else { | 1008 } else { |
1003 FAIL(expr, "invalid callee"); | 1009 FAIL(expr, "invalid callee"); |
1004 } | 1010 } |
1005 } | 1011 } |
1006 | 1012 |
1007 | 1013 |
1008 void AsmTyper::VisitCallNew(CallNew* expr) { | 1014 void AsmTyper::VisitCallNew(CallNew* expr) { |
1009 if (in_function_) { | 1015 if (in_function_) { |
1010 FAIL(expr, "new not allowed in module function"); | 1016 FAIL(expr, "new not allowed in module function"); |
1011 } | 1017 } |
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1529 | 1535 |
1530 | 1536 |
1531 void AsmTyper::VisitRewritableAssignmentExpression( | 1537 void AsmTyper::VisitRewritableAssignmentExpression( |
1532 RewritableAssignmentExpression* expr) { | 1538 RewritableAssignmentExpression* expr) { |
1533 RECURSE(Visit(expr->expression())); | 1539 RECURSE(Visit(expr->expression())); |
1534 } | 1540 } |
1535 | 1541 |
1536 | 1542 |
1537 } // namespace internal | 1543 } // namespace internal |
1538 } // namespace v8 | 1544 } // namespace v8 |
OLD | NEW |