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