OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/bootstrapper.h" | 5 #include "src/bootstrapper.h" |
6 #include "src/compiler/graph-inl.h" | 6 #include "src/compiler/graph-inl.h" |
7 #include "src/compiler/js-operator.h" | 7 #include "src/compiler/js-operator.h" |
8 #include "src/compiler/node.h" | 8 #include "src/compiler/node.h" |
9 #include "src/compiler/node-properties-inl.h" | 9 #include "src/compiler/node-properties-inl.h" |
10 #include "src/compiler/node-properties.h" | 10 #include "src/compiler/node-properties.h" |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
225 static Type* ToBoolean(Type*, Typer*); | 225 static Type* ToBoolean(Type*, Typer*); |
226 static Type* ToNumber(Type*, Typer*); | 226 static Type* ToNumber(Type*, Typer*); |
227 static Type* ToString(Type*, Typer*); | 227 static Type* ToString(Type*, Typer*); |
228 static Type* NumberToInt32(Type*, Typer*); | 228 static Type* NumberToInt32(Type*, Typer*); |
229 static Type* NumberToUint32(Type*, Typer*); | 229 static Type* NumberToUint32(Type*, Typer*); |
230 | 230 |
231 static Type* JSAddRanger(Type::RangeType*, Type::RangeType*, Typer*); | 231 static Type* JSAddRanger(Type::RangeType*, Type::RangeType*, Typer*); |
232 static Type* JSSubtractRanger(Type::RangeType*, Type::RangeType*, Typer*); | 232 static Type* JSSubtractRanger(Type::RangeType*, Type::RangeType*, Typer*); |
233 static Type* JSMultiplyRanger(Type::RangeType*, Type::RangeType*, Typer*); | 233 static Type* JSMultiplyRanger(Type::RangeType*, Type::RangeType*, Typer*); |
234 static Type* JSDivideRanger(Type::RangeType*, Type::RangeType*, Typer*); | 234 static Type* JSDivideRanger(Type::RangeType*, Type::RangeType*, Typer*); |
235 static Type* JSModulusRanger(Type::RangeType*, Type::RangeType*, Typer*); | |
236 | 235 |
237 static Type* JSCompareTyper(Type*, Type*, Typer*); | 236 static Type* JSCompareTyper(Type*, Type*, Typer*); |
238 | 237 |
239 #define DECLARE_METHOD(x) static Type* x##Typer(Type*, Type*, Typer*); | 238 #define DECLARE_METHOD(x) static Type* x##Typer(Type*, Type*, Typer*); |
240 JS_SIMPLE_BINOP_LIST(DECLARE_METHOD) | 239 JS_SIMPLE_BINOP_LIST(DECLARE_METHOD) |
241 #undef DECLARE_METHOD | 240 #undef DECLARE_METHOD |
242 | 241 |
243 static Type* JSUnaryNotTyper(Type*, Typer*); | 242 static Type* JSUnaryNotTyper(Type*, Typer*); |
244 static Type* JSLoadPropertyTyper(Type*, Type*, Typer*); | 243 static Type* JSLoadPropertyTyper(Type*, Type*, Typer*); |
245 static Type* JSCallFunctionTyper(Type*, Typer*); | 244 static Type* JSCallFunctionTyper(Type*, Typer*); |
(...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
978 // Division is tricky, so all we do is try ruling out nan. | 977 // Division is tricky, so all we do is try ruling out nan. |
979 // TODO(neis): try ruling out -0 as well? | 978 // TODO(neis): try ruling out -0 as well? |
980 bool maybe_nan = | 979 bool maybe_nan = |
981 lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish) || | 980 lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish) || |
982 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) && | 981 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) && |
983 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY)); | 982 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY)); |
984 return maybe_nan ? Type::Number() : Type::OrderedNumber(); | 983 return maybe_nan ? Type::Number() : Type::OrderedNumber(); |
985 } | 984 } |
986 | 985 |
987 | 986 |
988 Type* Typer::Visitor::JSModulusRanger(Type::RangeType* lhs, | |
989 Type::RangeType* rhs, Typer* t) { | |
990 double lmin = lhs->Min()->Number(); | |
991 double lmax = lhs->Max()->Number(); | |
992 double rmin = rhs->Min()->Number(); | |
993 double rmax = rhs->Max()->Number(); | |
994 | |
995 double labs = std::max(std::abs(lmin), std::abs(lmax)); | |
996 double rabs = std::max(std::abs(rmin), std::abs(rmax)) - 1; | |
997 double abs = std::min(labs, rabs); | |
998 bool maybe_minus_zero = false; | |
999 double omin = 0; | |
1000 double omax = 0; | |
1001 if (lmin >= 0) { // {lhs} positive. | |
1002 omin = 0; | |
1003 omax = abs; | |
1004 } else if (lmax <= 0) { // {lhs} negative. | |
1005 omin = 0 - abs; | |
1006 omax = 0; | |
1007 maybe_minus_zero = lmin <= omin; | |
1008 } else { | |
1009 omin = 0 - abs; | |
1010 omax = abs; | |
1011 maybe_minus_zero = lmin <= omin; | |
1012 } | |
1013 | |
1014 Factory* f = t->isolate()->factory(); | |
1015 Type* result = Type::Range(f->NewNumber(omin), f->NewNumber(omax), t->zone()); | |
1016 if (maybe_minus_zero) | |
1017 result = Type::Union(result, Type::MinusZero(), t->zone()); | |
1018 return result; | |
1019 } | |
1020 | |
1021 | |
1022 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) { | 987 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) { |
1023 lhs = ToNumber(lhs, t); | 988 lhs = ToNumber(lhs, t); |
1024 rhs = ToNumber(rhs, t); | 989 rhs = ToNumber(rhs, t); |
1025 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); | 990 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); |
1026 | 991 // Division is tricky, so all we do is try ruling out nan. |
1027 if (lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish) || | 992 // TODO(neis): try ruling out -0 as well? |
1028 lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) { | 993 bool maybe_nan = |
1029 // Result maybe NaN. | 994 lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish) || |
1030 return Type::Number(); | 995 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) && |
1031 } | 996 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY)); |
1032 | 997 return maybe_nan ? Type::Number() : Type::OrderedNumber(); |
1033 lhs = Rangify(lhs, t); | |
1034 rhs = Rangify(rhs, t); | |
1035 if (lhs->IsRange() && rhs->IsRange()) { | |
1036 return JSModulusRanger(lhs->AsRange(), rhs->AsRange(), t); | |
1037 } | |
1038 return Type::OrderedNumber(); | |
1039 } | 998 } |
1040 | 999 |
1041 | 1000 |
1042 // JS unary operators. | 1001 // JS unary operators. |
1043 | 1002 |
1044 | 1003 |
1045 Type* Typer::Visitor::JSUnaryNotTyper(Type* type, Typer* t) { | 1004 Type* Typer::Visitor::JSUnaryNotTyper(Type* type, Typer* t) { |
1046 return Invert(ToBoolean(type, t), t); | 1005 return Invert(ToBoolean(type, t), t); |
1047 } | 1006 } |
1048 | 1007 |
(...skipping 883 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1932 return typer_->float64_array_fun_; | 1891 return typer_->float64_array_fun_; |
1933 } | 1892 } |
1934 } | 1893 } |
1935 } | 1894 } |
1936 return Type::Constant(value, zone()); | 1895 return Type::Constant(value, zone()); |
1937 } | 1896 } |
1938 | 1897 |
1939 } | 1898 } |
1940 } | 1899 } |
1941 } // namespace v8::internal::compiler | 1900 } // namespace v8::internal::compiler |
OLD | NEW |