| 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:
|
|
|