Index: src/typing-asm.cc |
diff --git a/src/typing-asm.cc b/src/typing-asm.cc |
index 986926f5a794c7c2d8bd245402529e24db88636e..75057b93ffb57d238f19172474274d623d01da70 100644 |
--- a/src/typing-asm.cc |
+++ b/src/typing-asm.cc |
@@ -934,6 +934,54 @@ void AsmTyper::VisitProperty(Property* expr) { |
FAIL(expr, "invalid property access"); |
} |
+void AsmTyper::CheckPolymorphicStdlibArguments( |
+ enum StandardMember standard_member, ZoneList<Expression*>* args) { |
+ if (args->length() == 0) { |
+ return; |
+ } |
+ // Handle polymorphic stdlib functions specially. |
+ Expression* arg0 = args->at(0); |
+ Type* arg0_type = arg0->bounds().upper; |
+ switch (standard_member) { |
+ case kMathFround: { |
+ if (!arg0_type->Is(cache_.kAsmFloat) && |
+ !arg0_type->Is(cache_.kAsmDouble) && |
+ !arg0_type->Is(cache_.kAsmSigned) && |
+ !arg0_type->Is(cache_.kAsmUnsigned)) { |
+ FAIL(arg0, "illegal function argument type"); |
+ } |
+ break; |
+ } |
+ case kMathCeil: |
+ case kMathFloor: |
+ case kMathSqrt: { |
+ if (!arg0_type->Is(cache_.kAsmFloat) && |
+ !arg0_type->Is(cache_.kAsmDouble)) { |
+ FAIL(arg0, "illegal function argument type"); |
+ } |
+ break; |
+ } |
+ case kMathAbs: |
+ case kMathMin: |
+ case kMathMax: { |
+ if (!arg0_type->Is(cache_.kAsmFloat) && |
+ !arg0_type->Is(cache_.kAsmDouble) && |
+ !arg0_type->Is(cache_.kAsmSigned)) { |
+ FAIL(arg0, "illegal function argument type"); |
+ } |
+ if (args->length() > 1) { |
+ Type* other = Type::Intersect(args->at(0)->bounds().upper, |
+ args->at(1)->bounds().upper, zone()); |
+ if (!other->Is(cache_.kAsmFloat) && !other->Is(cache_.kAsmDouble) && |
+ !other->Is(cache_.kAsmSigned)) { |
+ FAIL(arg0, "function arguments types don't match"); |
+ } |
+ } |
+ break; |
+ } |
+ default: { break; } |
+ } |
+} |
void AsmTyper::VisitCall(Call* expr) { |
Type* expected_type = expected_type_; |
@@ -987,29 +1035,7 @@ void AsmTyper::VisitCall(Call* expr) { |
result_type = computed_type_; |
} |
} |
- // Handle polymorphic stdlib functions specially. |
- if (standard_member == kMathCeil || standard_member == kMathFloor || |
- standard_member == kMathSqrt) { |
- if (!args->at(0)->bounds().upper->Is(cache_.kAsmFloat) && |
- !args->at(0)->bounds().upper->Is(cache_.kAsmDouble)) { |
- FAIL(expr, "illegal function argument type"); |
- } |
- } else if (standard_member == kMathAbs || standard_member == kMathMin || |
- standard_member == kMathMax) { |
- if (!args->at(0)->bounds().upper->Is(cache_.kAsmFloat) && |
- !args->at(0)->bounds().upper->Is(cache_.kAsmDouble) && |
- !args->at(0)->bounds().upper->Is(cache_.kAsmSigned)) { |
- FAIL(expr, "illegal function argument type"); |
- } |
- if (args->length() > 1) { |
- Type* other = Type::Intersect(args->at(0)->bounds().upper, |
- args->at(1)->bounds().upper, zone()); |
- if (!other->Is(cache_.kAsmFloat) && !other->Is(cache_.kAsmDouble) && |
- !other->Is(cache_.kAsmSigned)) { |
- FAIL(expr, "function arguments types don't match"); |
- } |
- } |
- } |
+ RECURSE(CheckPolymorphicStdlibArguments(standard_member, args)); |
intish_ = 0; |
IntersectResult(expr, result_type); |
} |
@@ -1156,13 +1182,16 @@ void AsmTyper::VisitBinaryOperation(BinaryOperation* expr) { |
FAIL(expr, "illegal logical operator"); |
case Token::BIT_OR: { |
// BIT_OR allows Any since it is used as a type coercion. |
- VisitIntegerBitwiseOperator(expr, Type::Any(), cache_.kAsmIntQ, |
- cache_.kAsmSigned, true); |
+ RECURSE(VisitIntegerBitwiseOperator(expr, Type::Any(), cache_.kAsmIntQ, |
+ cache_.kAsmSigned, true)); |
if (expr->left()->IsCall() && expr->op() == Token::BIT_OR && |
Type::Number()->Is(expr->left()->bounds().upper)) { |
// Force the return types of foreign functions. |
expr->left()->set_bounds(Bounds(cache_.kAsmSigned)); |
} |
+ if (in_function_ && !expr->left()->bounds().upper->Is(cache_.kAsmIntQ)) { |
+ FAIL(expr->left(), "intish required"); |
+ } |
return; |
} |
case Token::BIT_XOR: { |
@@ -1180,20 +1209,20 @@ void AsmTyper::VisitBinaryOperation(BinaryOperation* expr) { |
} |
} |
// BIT_XOR allows Any since it is used as a type coercion (via ~~). |
- VisitIntegerBitwiseOperator(expr, Type::Any(), cache_.kAsmIntQ, |
- cache_.kAsmSigned, true); |
+ RECURSE(VisitIntegerBitwiseOperator(expr, Type::Any(), cache_.kAsmIntQ, |
+ cache_.kAsmSigned, true)); |
return; |
} |
case Token::SHR: { |
- VisitIntegerBitwiseOperator(expr, cache_.kAsmIntQ, cache_.kAsmIntQ, |
- cache_.kAsmUnsigned, false); |
+ RECURSE(VisitIntegerBitwiseOperator( |
+ expr, cache_.kAsmIntQ, cache_.kAsmIntQ, cache_.kAsmUnsigned, false)); |
return; |
} |
case Token::SHL: |
case Token::SAR: |
case Token::BIT_AND: { |
- VisitIntegerBitwiseOperator(expr, cache_.kAsmIntQ, cache_.kAsmIntQ, |
- cache_.kAsmSigned, false); |
+ RECURSE(VisitIntegerBitwiseOperator( |
+ expr, cache_.kAsmIntQ, cache_.kAsmIntQ, cache_.kAsmSigned, false)); |
return; |
} |
case Token::ADD: |