[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:
parent
af01d9e09d
commit
8eac5a7cc9
@ -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.
|
||||
|
@ -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) \
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user