| Index: src/compiler/typer.cc
|
| diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc
|
| index 9af65597bf5527e9d60ca3c67b38300726cfe1bb..288fedce8ec09cd47a8fa7c12783a3ad2557cced 100644
|
| --- a/src/compiler/typer.cc
|
| +++ b/src/compiler/typer.cc
|
| @@ -350,6 +350,7 @@ class Typer::Visitor : public Reducer {
|
| static Type* JSMultiplyRanger(Type::RangeType*, Type::RangeType*, Typer*);
|
| static Type* JSDivideRanger(Type::RangeType*, Type::RangeType*, Typer*);
|
| static Type* JSModulusRanger(Type::RangeType*, Type::RangeType*, Typer*);
|
| + static Type* JSExponentiateRanger(Type::RangeType*, Type::RangeType*, Typer*);
|
|
|
| static ComparisonOutcome JSCompareTyper(Type*, Type*, Typer*);
|
|
|
| @@ -1223,6 +1224,54 @@ Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) {
|
| }
|
|
|
|
|
| +Type* Typer::Visitor::JSExponentiateRanger(Type::RangeType* lhs,
|
| + Type::RangeType* rhs, Typer* t) {
|
| + double lmin = lhs->Min();
|
| + double lmax = lhs->Max();
|
| + double rmin = rhs->Min();
|
| + double rmax = rhs->Max();
|
| +
|
| + if (lmin > 0.0) {
|
| + // +x ** -y : epsilon...1
|
| + if (rmax < 0.0) return Type::Range(0.0, 1.0, t->zone());
|
| +
|
| + // +x ** +y : epsilon...infinity
|
| + if (rmin > 0.0) return Type::Range(0.0, +V8_INFINITY, t->zone());
|
| + } else if (lmax < 0.0) {
|
| + // -x ** -y : -1.0...1.0
|
| + if (rmax < 0.0) return Type::Range(-1.0, 1.0, t->zone());
|
| + }
|
| +
|
| + // pow(lmin, rmax) does not limit range by much.
|
| + return Type::Number();
|
| +}
|
| +
|
| +
|
| +Type* Typer::Visitor::JSExponentiateTyper(Type* lhs, Type* rhs, Typer* t) {
|
| + lhs = ToNumber(lhs, t);
|
| + rhs = ToNumber(rhs, t);
|
| +
|
| + // x ** NaN|undefined : NaN
|
| + if (rhs->Is(Type::NaN())) return Type::NaN();
|
| +
|
| + // x ** 0|false|null : 1
|
| + if (rhs->Is(t->singleton_zero)) return t->singleton_one;
|
| +
|
| + // NaN ** x [~0] : NaN
|
| + if (lhs->Is(Type::NaN())) return Type::NaN();
|
| +
|
| + // 0|false|null ** x [~0] : 0
|
| + if (lhs->Is(t->singleton_zero)) return t->singleton_zero;
|
| +
|
| + lhs = Rangify(lhs, t);
|
| + rhs = Rangify(rhs, t);
|
| + if (lhs->IsRange() && rhs->IsRange()) {
|
| + return JSExponentiateRanger(lhs->AsRange(), rhs->AsRange(), t);
|
| + }
|
| + return Type::Number();
|
| +}
|
| +
|
| +
|
| // JS unary operators.
|
|
|
|
|
|
|