[bigint,compiler] Adapt typer and verifier.

This updates various typing and verification rules to take bigints into
account.

R=jarin@chromium.org

Bug: v8:6791
Change-Id: I38fc4c6551bba878623373c69013da8ce2b50c7d
Reviewed-on: https://chromium-review.googlesource.com/788910
Commit-Queue: Georg Neis <neis@chromium.org>
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49701}
This commit is contained in:
Georg Neis 2017-11-24 12:28:30 +01:00 committed by Commit Bot
parent af01d9e09d
commit 8eac5a7cc9
3 changed files with 77 additions and 28 deletions

View File

@ -986,12 +986,22 @@ Typer::Visitor::ComparisonOutcome Typer::Visitor::JSCompareTyper(Type* lhs,
return ComparisonOutcome(kComparisonTrue) |
ComparisonOutcome(kComparisonFalse);
}
return NumberCompareTyper(ToNumber(lhs, t), ToNumber(rhs, t), t);
lhs = ToNumeric(lhs, t);
rhs = ToNumeric(rhs, t);
if (lhs->Is(Type::Number()) && rhs->Is(Type::Number())) {
return NumberCompareTyper(lhs, rhs, t);
}
return ComparisonOutcome(kComparisonTrue) |
ComparisonOutcome(kComparisonFalse) |
ComparisonOutcome(kComparisonUndefined);
}
Typer::Visitor::ComparisonOutcome Typer::Visitor::NumberCompareTyper(Type* lhs,
Type* rhs,
Typer* t) {
DCHECK(lhs->Is(Type::Number()));
DCHECK(rhs->Is(Type::Number()));
// Shortcut for NaNs.
if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return kComparisonUndefined;
@ -1042,27 +1052,53 @@ Type* Typer::Visitor::JSGreaterThanOrEqualTyper(
Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) {
return NumberBitwiseOr(ToNumber(lhs, t), ToNumber(rhs, t), t);
lhs = ToNumeric(lhs, t);
rhs = ToNumeric(rhs, t);
if (lhs->Is(Type::Number()) && rhs->Is(Type::Number())) {
return NumberBitwiseOr(lhs, rhs, t);
}
return Type::Numeric();
}
Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) {
return NumberBitwiseAnd(ToNumber(lhs, t), ToNumber(rhs, t), t);
lhs = ToNumeric(lhs, t);
rhs = ToNumeric(rhs, t);
if (lhs->Is(Type::Number()) && rhs->Is(Type::Number())) {
return NumberBitwiseAnd(lhs, rhs, t);
}
return Type::Numeric();
}
Type* Typer::Visitor::JSBitwiseXorTyper(Type* lhs, Type* rhs, Typer* t) {
return NumberBitwiseXor(ToNumber(lhs, t), ToNumber(rhs, t), t);
lhs = ToNumeric(lhs, t);
rhs = ToNumeric(rhs, t);
if (lhs->Is(Type::Number()) && rhs->Is(Type::Number())) {
return NumberBitwiseXor(lhs, rhs, t);
}
return Type::Numeric();
}
Type* Typer::Visitor::JSShiftLeftTyper(Type* lhs, Type* rhs, Typer* t) {
return NumberShiftLeft(ToNumber(lhs, t), ToNumber(rhs, t), t);
lhs = ToNumeric(lhs, t);
rhs = ToNumeric(rhs, t);
if (lhs->Is(Type::Number()) && rhs->Is(Type::Number())) {
return NumberShiftLeft(lhs, rhs, t);
}
return Type::Numeric();
}
Type* Typer::Visitor::JSShiftRightTyper(Type* lhs, Type* rhs, Typer* t) {
return NumberShiftRight(ToNumber(lhs, t), ToNumber(rhs, t), t);
lhs = ToNumeric(lhs, t);
rhs = ToNumeric(rhs, t);
if (lhs->Is(Type::Number()) && rhs->Is(Type::Number())) {
return NumberShiftRight(lhs, rhs, t);
}
return Type::Numeric();
}
@ -1080,34 +1116,56 @@ Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) {
if (lhs->Is(Type::String()) || rhs->Is(Type::String())) {
return Type::String();
} else {
return Type::NumberOrString();
return Type::NumericOrString();
}
}
// The addition must be numeric.
return NumberAdd(ToNumber(lhs, t), ToNumber(rhs, t), t);
lhs = ToNumeric(lhs, t);
rhs = ToNumeric(rhs, t);
if (lhs->Is(Type::Number()) && rhs->Is(Type::Number())) {
return NumberAdd(lhs, rhs, t);
}
return Type::Numeric();
}
Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* t) {
return NumberSubtract(ToNumber(lhs, t), ToNumber(rhs, t), t);
lhs = ToNumeric(lhs, t);
rhs = ToNumeric(rhs, t);
if (lhs->Is(Type::Number()) && rhs->Is(Type::Number())) {
return NumberSubtract(lhs, rhs, t);
}
return Type::Numeric();
}
Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) {
return NumberMultiply(ToNumber(lhs, t), ToNumber(rhs, t), t);
lhs = ToNumeric(lhs, t);
rhs = ToNumeric(rhs, t);
if (lhs->Is(Type::Number()) && rhs->Is(Type::Number())) {
return NumberMultiply(lhs, rhs, t);
}
return Type::Numeric();
}
Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) {
return NumberDivide(ToNumber(lhs, t), ToNumber(rhs, t), t);
lhs = ToNumeric(lhs, t);
rhs = ToNumeric(rhs, t);
if (lhs->Is(Type::Number()) && rhs->Is(Type::Number())) {
return NumberDivide(lhs, rhs, t);
}
return Type::Numeric();
}
Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) {
return NumberModulus(ToNumber(lhs, t), ToNumber(rhs, t), t);
lhs = ToNumeric(lhs, t);
rhs = ToNumeric(rhs, t);
if (lhs->Is(Type::Number()) && rhs->Is(Type::Number())) {
return NumberModulus(lhs, rhs, t);
}
return Type::Numeric();
}
// TODO(neis): Adapt all these for bigints. Why does this even work in the
// bigint tests?
Type* Typer::Visitor::JSExponentiateTyper(Type* lhs, Type* rhs, Typer* t) {
return Type::Number();
return Type::Numeric();
}
// JS unary operators.

View File

@ -171,6 +171,7 @@ namespace compiler {
V(NumberOrOddball, kNumber | kNullOrUndefined | kBoolean | \
kHole) \
V(NumberOrString, kNumber | kString) \
V(NumericOrString, kNumeric | kString) \
V(NumberOrUndefined, kNumber | kUndefined) \
V(NumberOrUndefinedOrNullOrBoolean, \
kNumber | kNullOrUndefined | kBoolean) \

View File

@ -591,34 +591,24 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) {
CheckTypeIs(node, Type::Boolean());
break;
case IrOpcode::kJSAdd:
CheckTypeIs(node, Type::NumericOrString());
break;
case IrOpcode::kJSBitwiseOr:
case IrOpcode::kJSBitwiseXor:
case IrOpcode::kJSBitwiseAnd:
case IrOpcode::kJSShiftLeft:
case IrOpcode::kJSShiftRight:
case IrOpcode::kJSShiftRightLogical:
// Type is 32 bit integral.
CheckTypeIs(node, Type::Integral32());
break;
case IrOpcode::kJSAdd:
// Type is Number or String.
CheckTypeIs(node, Type::NumberOrString());
break;
case IrOpcode::kJSSubtract:
case IrOpcode::kJSMultiply:
case IrOpcode::kJSDivide:
case IrOpcode::kJSModulus:
case IrOpcode::kJSExponentiate:
// Type is Number.
// TODO(neis): Adapt for bigints.
CheckTypeIs(node, Type::Number());
break;
case IrOpcode::kJSBitwiseNot:
case IrOpcode::kJSDecrement:
case IrOpcode::kJSIncrement:
case IrOpcode::kJSNegate:
// Type is Numeric.
CheckTypeIs(node, Type::Numeric());
break;