Commit d9e1a7ae authored by Georg Neis's avatar Georg Neis Committed by Commit Bot

[turbofan] Improve handling of empty types

- Fix a non-observable bug in the typer.
- Add some CHECKs where we rely on not receiving None types.
- Remove an explicit handling of None types where it's redundant and
  misleading (later ToNumeric conversions can again introduce None).

Bug: chromium:965911
Change-Id: I4bb84422de3f9297131e7304216b86884f04ed49
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1630679
Auto-Submit: Georg Neis <neis@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61880}
parent 8c2c336b
...@@ -1124,7 +1124,7 @@ Type OperationTyper::ToPrimitive(Type type) { ...@@ -1124,7 +1124,7 @@ Type OperationTyper::ToPrimitive(Type type) {
Type OperationTyper::Invert(Type type) { Type OperationTyper::Invert(Type type) {
DCHECK(type.Is(Type::Boolean())); DCHECK(type.Is(Type::Boolean()));
DCHECK(!type.IsNone()); CHECK(!type.IsNone());
if (type.Is(singleton_false())) return singleton_true(); if (type.Is(singleton_false())) return singleton_true();
if (type.Is(singleton_true())) return singleton_false(); if (type.Is(singleton_true())) return singleton_false();
return type; return type;
...@@ -1195,6 +1195,8 @@ Type OperationTyper::SameValueNumbersOnly(Type lhs, Type rhs) { ...@@ -1195,6 +1195,8 @@ Type OperationTyper::SameValueNumbersOnly(Type lhs, Type rhs) {
} }
Type OperationTyper::StrictEqual(Type lhs, Type rhs) { Type OperationTyper::StrictEqual(Type lhs, Type rhs) {
CHECK(!lhs.IsNone());
CHECK(!rhs.IsNone());
if (!JSType(lhs).Maybe(JSType(rhs))) return singleton_false(); if (!JSType(lhs).Maybe(JSType(rhs))) return singleton_false();
if (lhs.Is(Type::NaN()) || rhs.Is(Type::NaN())) return singleton_false(); if (lhs.Is(Type::NaN()) || rhs.Is(Type::NaN())) return singleton_false();
if (lhs.Is(Type::Number()) && rhs.Is(Type::Number()) && if (lhs.Is(Type::Number()) && rhs.Is(Type::Number()) &&
......
...@@ -624,17 +624,20 @@ Type Typer::Visitor::ToString(Type type, Typer* t) { ...@@ -624,17 +624,20 @@ Type Typer::Visitor::ToString(Type type, Typer* t) {
Type Typer::Visitor::ObjectIsArrayBufferView(Type type, Typer* t) { Type Typer::Visitor::ObjectIsArrayBufferView(Type type, Typer* t) {
// TODO(turbofan): Introduce a Type::ArrayBufferView? // TODO(turbofan): Introduce a Type::ArrayBufferView?
CHECK(!type.IsNone());
if (!type.Maybe(Type::OtherObject())) return t->singleton_false_; if (!type.Maybe(Type::OtherObject())) return t->singleton_false_;
return Type::Boolean(); return Type::Boolean();
} }
Type Typer::Visitor::ObjectIsBigInt(Type type, Typer* t) { Type Typer::Visitor::ObjectIsBigInt(Type type, Typer* t) {
CHECK(!type.IsNone());
if (type.Is(Type::BigInt())) return t->singleton_true_; if (type.Is(Type::BigInt())) return t->singleton_true_;
if (!type.Maybe(Type::BigInt())) return t->singleton_false_; if (!type.Maybe(Type::BigInt())) return t->singleton_false_;
return Type::Boolean(); return Type::Boolean();
} }
Type Typer::Visitor::ObjectIsCallable(Type type, Typer* t) { Type Typer::Visitor::ObjectIsCallable(Type type, Typer* t) {
CHECK(!type.IsNone());
if (type.Is(Type::Callable())) return t->singleton_true_; if (type.Is(Type::Callable())) return t->singleton_true_;
if (!type.Maybe(Type::Callable())) return t->singleton_false_; if (!type.Maybe(Type::Callable())) return t->singleton_false_;
return Type::Boolean(); return Type::Boolean();
...@@ -642,53 +645,62 @@ Type Typer::Visitor::ObjectIsCallable(Type type, Typer* t) { ...@@ -642,53 +645,62 @@ Type Typer::Visitor::ObjectIsCallable(Type type, Typer* t) {
Type Typer::Visitor::ObjectIsConstructor(Type type, Typer* t) { Type Typer::Visitor::ObjectIsConstructor(Type type, Typer* t) {
// TODO(turbofan): Introduce a Type::Constructor? // TODO(turbofan): Introduce a Type::Constructor?
CHECK(!type.IsNone());
if (!type.Maybe(Type::Callable())) return t->singleton_false_; if (!type.Maybe(Type::Callable())) return t->singleton_false_;
return Type::Boolean(); return Type::Boolean();
} }
Type Typer::Visitor::ObjectIsDetectableCallable(Type type, Typer* t) { Type Typer::Visitor::ObjectIsDetectableCallable(Type type, Typer* t) {
CHECK(!type.IsNone());
if (type.Is(Type::DetectableCallable())) return t->singleton_true_; if (type.Is(Type::DetectableCallable())) return t->singleton_true_;
if (!type.Maybe(Type::DetectableCallable())) return t->singleton_false_; if (!type.Maybe(Type::DetectableCallable())) return t->singleton_false_;
return Type::Boolean(); return Type::Boolean();
} }
Type Typer::Visitor::ObjectIsMinusZero(Type type, Typer* t) { Type Typer::Visitor::ObjectIsMinusZero(Type type, Typer* t) {
CHECK(!type.IsNone());
if (type.Is(Type::MinusZero())) return t->singleton_true_; if (type.Is(Type::MinusZero())) return t->singleton_true_;
if (!type.Maybe(Type::MinusZero())) return t->singleton_false_; if (!type.Maybe(Type::MinusZero())) return t->singleton_false_;
return Type::Boolean(); return Type::Boolean();
} }
Type Typer::Visitor::NumberIsMinusZero(Type type, Typer* t) { Type Typer::Visitor::NumberIsMinusZero(Type type, Typer* t) {
CHECK(!type.IsNone());
if (type.Is(Type::MinusZero())) return t->singleton_true_; if (type.Is(Type::MinusZero())) return t->singleton_true_;
if (!type.Maybe(Type::MinusZero())) return t->singleton_false_; if (!type.Maybe(Type::MinusZero())) return t->singleton_false_;
return Type::Boolean(); return Type::Boolean();
} }
Type Typer::Visitor::ObjectIsNaN(Type type, Typer* t) { Type Typer::Visitor::ObjectIsNaN(Type type, Typer* t) {
CHECK(!type.IsNone());
if (type.Is(Type::NaN())) return t->singleton_true_; if (type.Is(Type::NaN())) return t->singleton_true_;
if (!type.Maybe(Type::NaN())) return t->singleton_false_; if (!type.Maybe(Type::NaN())) return t->singleton_false_;
return Type::Boolean(); return Type::Boolean();
} }
Type Typer::Visitor::NumberIsNaN(Type type, Typer* t) { Type Typer::Visitor::NumberIsNaN(Type type, Typer* t) {
CHECK(!type.IsNone());
if (type.Is(Type::NaN())) return t->singleton_true_; if (type.Is(Type::NaN())) return t->singleton_true_;
if (!type.Maybe(Type::NaN())) return t->singleton_false_; if (!type.Maybe(Type::NaN())) return t->singleton_false_;
return Type::Boolean(); return Type::Boolean();
} }
Type Typer::Visitor::ObjectIsNonCallable(Type type, Typer* t) { Type Typer::Visitor::ObjectIsNonCallable(Type type, Typer* t) {
CHECK(!type.IsNone());
if (type.Is(Type::NonCallable())) return t->singleton_true_; if (type.Is(Type::NonCallable())) return t->singleton_true_;
if (!type.Maybe(Type::NonCallable())) return t->singleton_false_; if (!type.Maybe(Type::NonCallable())) return t->singleton_false_;
return Type::Boolean(); return Type::Boolean();
} }
Type Typer::Visitor::ObjectIsNumber(Type type, Typer* t) { Type Typer::Visitor::ObjectIsNumber(Type type, Typer* t) {
CHECK(!type.IsNone());
if (type.Is(Type::Number())) return t->singleton_true_; if (type.Is(Type::Number())) return t->singleton_true_;
if (!type.Maybe(Type::Number())) return t->singleton_false_; if (!type.Maybe(Type::Number())) return t->singleton_false_;
return Type::Boolean(); return Type::Boolean();
} }
Type Typer::Visitor::ObjectIsReceiver(Type type, Typer* t) { Type Typer::Visitor::ObjectIsReceiver(Type type, Typer* t) {
CHECK(!type.IsNone());
if (type.Is(Type::Receiver())) return t->singleton_true_; if (type.Is(Type::Receiver())) return t->singleton_true_;
if (!type.Maybe(Type::Receiver())) return t->singleton_false_; if (!type.Maybe(Type::Receiver())) return t->singleton_false_;
return Type::Boolean(); return Type::Boolean();
...@@ -700,18 +712,21 @@ Type Typer::Visitor::ObjectIsSmi(Type type, Typer* t) { ...@@ -700,18 +712,21 @@ Type Typer::Visitor::ObjectIsSmi(Type type, Typer* t) {
} }
Type Typer::Visitor::ObjectIsString(Type type, Typer* t) { Type Typer::Visitor::ObjectIsString(Type type, Typer* t) {
CHECK(!type.IsNone());
if (type.Is(Type::String())) return t->singleton_true_; if (type.Is(Type::String())) return t->singleton_true_;
if (!type.Maybe(Type::String())) return t->singleton_false_; if (!type.Maybe(Type::String())) return t->singleton_false_;
return Type::Boolean(); return Type::Boolean();
} }
Type Typer::Visitor::ObjectIsSymbol(Type type, Typer* t) { Type Typer::Visitor::ObjectIsSymbol(Type type, Typer* t) {
CHECK(!type.IsNone());
if (type.Is(Type::Symbol())) return t->singleton_true_; if (type.Is(Type::Symbol())) return t->singleton_true_;
if (!type.Maybe(Type::Symbol())) return t->singleton_false_; if (!type.Maybe(Type::Symbol())) return t->singleton_false_;
return Type::Boolean(); return Type::Boolean();
} }
Type Typer::Visitor::ObjectIsUndetectable(Type type, Typer* t) { Type Typer::Visitor::ObjectIsUndetectable(Type type, Typer* t) {
CHECK(!type.IsNone());
if (type.Is(Type::Undetectable())) return t->singleton_true_; if (type.Is(Type::Undetectable())) return t->singleton_true_;
if (!type.Maybe(Type::Undetectable())) return t->singleton_false_; if (!type.Maybe(Type::Undetectable())) return t->singleton_false_;
return Type::Boolean(); return Type::Boolean();
...@@ -1000,6 +1015,7 @@ Type Typer::Visitor::TypeStaticAssert(Node* node) { UNREACHABLE(); } ...@@ -1000,6 +1015,7 @@ Type Typer::Visitor::TypeStaticAssert(Node* node) { UNREACHABLE(); }
// JS comparison operators. // JS comparison operators.
Type Typer::Visitor::JSEqualTyper(Type lhs, Type rhs, Typer* t) { Type Typer::Visitor::JSEqualTyper(Type lhs, Type rhs, Typer* t) {
if (lhs.IsNone() || rhs.IsNone()) return Type::None();
if (lhs.Is(Type::NaN()) || rhs.Is(Type::NaN())) return t->singleton_false_; if (lhs.Is(Type::NaN()) || rhs.Is(Type::NaN())) return t->singleton_false_;
if (lhs.Is(Type::NullOrUndefined()) && rhs.Is(Type::NullOrUndefined())) { if (lhs.Is(Type::NullOrUndefined()) && rhs.Is(Type::NullOrUndefined())) {
return t->singleton_true_; return t->singleton_true_;
...@@ -1027,8 +1043,6 @@ Type Typer::Visitor::JSStrictEqualTyper(Type lhs, Type rhs, Typer* t) { ...@@ -1027,8 +1043,6 @@ Type Typer::Visitor::JSStrictEqualTyper(Type lhs, Type rhs, Typer* t) {
Typer::Visitor::ComparisonOutcome Typer::Visitor::JSCompareTyper(Type lhs, Typer::Visitor::ComparisonOutcome Typer::Visitor::JSCompareTyper(Type lhs,
Type rhs, Type rhs,
Typer* t) { Typer* t) {
if (lhs.IsNone() || rhs.IsNone()) return {};
lhs = ToPrimitive(lhs, t); lhs = ToPrimitive(lhs, t);
rhs = ToPrimitive(rhs, t); rhs = ToPrimitive(rhs, t);
if (lhs.Maybe(Type::String()) && rhs.Maybe(Type::String())) { if (lhs.Maybe(Type::String()) && rhs.Maybe(Type::String())) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment