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

[bigint,compiler] Improve typing of arithmetic operators.

R=jarin@chromium.org

Bug: v8:6791
Change-Id: Ie030a79accebd7c43f19bcebefa7cd1951d67c2e
Reviewed-on: https://chromium-review.googlesource.com/808937Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49999}
parent a20495f1
......@@ -254,6 +254,9 @@ class Typer::Visitor : public Reducer {
Type* TypeUnaryOp(Node* node, UnaryTyperFun);
Type* TypeBinaryOp(Node* node, BinaryTyperFun);
static Type* BinaryNumberOpTyper(Type* lhs, Type* rhs, Typer* t,
BinaryTyperFun f);
enum ComparisonOutcomeFlags {
kComparisonTrue = 1,
kComparisonFalse = 2,
......@@ -399,7 +402,6 @@ Type* Typer::Visitor::TypeUnaryOp(Node* node, UnaryTyperFun f) {
return input->IsNone() ? Type::None() : f(input, typer_);
}
Type* Typer::Visitor::TypeBinaryOp(Node* node, BinaryTyperFun f) {
Type* left = Operand(node, 0);
Type* right = Operand(node, 1);
......@@ -407,6 +409,21 @@ Type* Typer::Visitor::TypeBinaryOp(Node* node, BinaryTyperFun f) {
: f(left, right, typer_);
}
Type* Typer::Visitor::BinaryNumberOpTyper(Type* lhs, Type* rhs, Typer* t,
BinaryTyperFun f) {
lhs = ToNumeric(lhs, t);
rhs = ToNumeric(rhs, t);
bool lhs_is_number = lhs->Is(Type::Number());
bool rhs_is_number = rhs->Is(Type::Number());
if (lhs_is_number && rhs_is_number) {
return f(lhs, rhs, t);
}
if (lhs_is_number || rhs_is_number) {
return Type::Number();
}
// TODO(neis): Check if one side is BigInt in order to return BigInt?
return Type::Numeric();
}
Typer::Visitor::ComparisonOutcome Typer::Visitor::Invert(
ComparisonOutcome outcome, Typer* t) {
......@@ -417,7 +434,6 @@ Typer::Visitor::ComparisonOutcome Typer::Visitor::Invert(
return result;
}
Type* Typer::Visitor::FalsifyUndefined(ComparisonOutcome outcome, Typer* t) {
if ((outcome & kComparisonFalse) != 0 ||
(outcome & kComparisonUndefined) != 0) {
......@@ -1052,52 +1068,23 @@ Type* Typer::Visitor::JSGreaterThanOrEqualTyper(
Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* 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();
return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseOr);
}
Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* 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();
return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseAnd);
}
Type* Typer::Visitor::JSBitwiseXorTyper(Type* lhs, Type* rhs, Typer* 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();
return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseXor);
}
Type* Typer::Visitor::JSShiftLeftTyper(Type* lhs, Type* rhs, Typer* 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();
return BinaryNumberOpTyper(lhs, rhs, t, NumberShiftLeft);
}
Type* Typer::Visitor::JSShiftRightTyper(Type* lhs, Type* rhs, Typer* 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();
return BinaryNumberOpTyper(lhs, rhs, t, NumberShiftRight);
}
......@@ -1119,51 +1106,27 @@ Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) {
}
}
// The addition must be numeric.
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();
return BinaryNumberOpTyper(lhs, rhs, t, NumberAdd);
}
Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* 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();
return BinaryNumberOpTyper(lhs, rhs, t, NumberSubtract);
}
Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* 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();
return BinaryNumberOpTyper(lhs, rhs, t, NumberMultiply);
}
Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* 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();
return BinaryNumberOpTyper(lhs, rhs, t, NumberDivide);
}
Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* 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();
return BinaryNumberOpTyper(lhs, rhs, t, NumberModulus);
}
Type* Typer::Visitor::JSExponentiateTyper(Type* lhs, Type* rhs, Typer* t) {
// TODO(neis): Refine using BinaryNumberOpTyper?
return Type::Numeric();
}
......
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