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*); |
235 | 236 |
236 static Type* JSCompareTyper(Type*, Type*, Typer*); | 237 static Type* JSCompareTyper(Type*, Type*, Typer*); |
237 | 238 |
238 #define DECLARE_METHOD(x) static Type* x##Typer(Type*, Type*, Typer*); | 239 #define DECLARE_METHOD(x) static Type* x##Typer(Type*, Type*, Typer*); |
239 JS_SIMPLE_BINOP_LIST(DECLARE_METHOD) | 240 JS_SIMPLE_BINOP_LIST(DECLARE_METHOD) |
240 #undef DECLARE_METHOD | 241 #undef DECLARE_METHOD |
241 | 242 |
242 static Type* JSUnaryNotTyper(Type*, Typer*); | 243 static Type* JSUnaryNotTyper(Type*, Typer*); |
243 static Type* JSLoadPropertyTyper(Type*, Type*, Typer*); | 244 static Type* JSLoadPropertyTyper(Type*, Type*, Typer*); |
244 static Type* JSCallFunctionTyper(Type*, Typer*); | 245 static Type* JSCallFunctionTyper(Type*, Typer*); |
(...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
977 // Division is tricky, so all we do is try ruling out nan. | 978 // Division is tricky, so all we do is try ruling out nan. |
978 // TODO(neis): try ruling out -0 as well? | 979 // TODO(neis): try ruling out -0 as well? |
979 bool maybe_nan = | 980 bool maybe_nan = |
980 lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish) || | 981 lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish) || |
981 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) && | 982 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) && |
982 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY)); | 983 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY)); |
983 return maybe_nan ? Type::Number() : Type::OrderedNumber(); | 984 return maybe_nan ? Type::Number() : Type::OrderedNumber(); |
984 } | 985 } |
985 | 986 |
986 | 987 |
| 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 = true; |
| 1008 } else { |
| 1009 omin = 0 - abs; |
| 1010 omax = abs; |
| 1011 maybe_minus_zero = true; |
| 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 |
987 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) { | 1022 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) { |
988 lhs = ToNumber(lhs, t); | 1023 lhs = ToNumber(lhs, t); |
989 rhs = ToNumber(rhs, t); | 1024 rhs = ToNumber(rhs, t); |
990 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); | 1025 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); |
991 // Division is tricky, so all we do is try ruling out nan. | 1026 |
992 // TODO(neis): try ruling out -0 as well? | 1027 if (lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish) || |
993 bool maybe_nan = | 1028 lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) { |
994 lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish) || | 1029 // Result maybe NaN. |
995 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) && | 1030 return Type::Number(); |
996 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY)); | 1031 } |
997 return maybe_nan ? Type::Number() : Type::OrderedNumber(); | 1032 |
| 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(); |
998 } | 1039 } |
999 | 1040 |
1000 | 1041 |
1001 // JS unary operators. | 1042 // JS unary operators. |
1002 | 1043 |
1003 | 1044 |
1004 Type* Typer::Visitor::JSUnaryNotTyper(Type* type, Typer* t) { | 1045 Type* Typer::Visitor::JSUnaryNotTyper(Type* type, Typer* t) { |
1005 return Invert(ToBoolean(type, t), t); | 1046 return Invert(ToBoolean(type, t), t); |
1006 } | 1047 } |
1007 | 1048 |
(...skipping 883 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1891 return typer_->float64_array_fun_; | 1932 return typer_->float64_array_fun_; |
1892 } | 1933 } |
1893 } | 1934 } |
1894 } | 1935 } |
1895 return Type::Constant(value, zone()); | 1936 return Type::Constant(value, zone()); |
1896 } | 1937 } |
1897 | 1938 |
1898 } | 1939 } |
1899 } | 1940 } |
1900 } // namespace v8::internal::compiler | 1941 } // namespace v8::internal::compiler |
OLD | NEW |