Add two argument Math.min and Math.max support to v4.
authorMichael Brasser <michael.brasser@nokia.com>
Thu, 8 Mar 2012 00:36:51 +0000 (10:36 +1000)
committerQt by Nokia <qt-info@nokia.com>
Mon, 12 Mar 2012 22:28:23 +0000 (23:28 +0100)
Change-Id: I26a4812b76571bf0ae6a0b4bd5d1e2afd64051df
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
src/qml/qml/v4/qv4bindings.cpp
src/qml/qml/v4/qv4compiler.cpp
src/qml/qml/v4/qv4instruction.cpp
src/qml/qml/v4/qv4instruction_p.h
src/qml/qml/v4/qv4ir.cpp
src/qml/qml/v4/qv4ir_p.h

index 3f3b666..93c7820 100644 (file)
@@ -1498,6 +1498,26 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
     }
     QML_V4_END_INSTR(StrictNotEqualString, binaryop)
 
+    QML_V4_BEGIN_INSTR(MathMaxReal, binaryop)
+    {
+        const Register &left = registers[instr->binaryop.left];
+        const Register &right = registers[instr->binaryop.right];
+        Register &output = registers[instr->binaryop.output];
+        if (left.isUndefined() || right.isUndefined()) output.setUndefined();
+        else output.setqreal(qMax(left.getqreal(), right.getqreal()));
+    }
+    QML_V4_END_INSTR(MathMaxReal, binaryop)
+
+    QML_V4_BEGIN_INSTR(MathMinReal, binaryop)
+    {
+        const Register &left = registers[instr->binaryop.left];
+        const Register &right = registers[instr->binaryop.right];
+        Register &output = registers[instr->binaryop.output];
+        if (left.isUndefined() || right.isUndefined()) output.setUndefined();
+        else output.setqreal(qMin(left.getqreal(), right.getqreal()));
+    }
+    QML_V4_END_INSTR(MathMinReal, binaryop)
+
     QML_V4_BEGIN_INSTR(NewString, construct)
     {
         Register &output = registers[instr->construct.reg];
index ce83c2d..620d260 100644 (file)
@@ -828,8 +828,42 @@ void QV4CompilerPrivate::visitCall(IR::Call *call)
                 } return;
 
             case IR::MathPIBuiltinConstant:
+            default:
                 break;
             } // switch
+        } else {
+            if (name->builtin == IR::MathMaxBuiltinFunction ||
+                name->builtin == IR::MathMinBuiltinFunction) {
+
+                //only handles the most common case of exactly two arguments
+                if (call->args && call->args->next && !call->args->next->next) {
+                    IR::Expr *arg1 = call->args->expr;
+                    IR::Expr *arg2 = call->args->next->expr;
+
+                    if (arg1 != 0 && arg1->type == IR::RealType &&
+                        arg2 != 0 && arg2->type == IR::RealType) {
+
+                        traceExpression(arg1, currentReg);
+                        traceExpression(arg2, currentReg + 1);
+
+                        if (name->builtin == IR::MathMaxBuiltinFunction) {
+                            Instr::MathMaxReal i;
+                            i.left = currentReg;
+                            i.right = currentReg + 1;
+                            i.output = currentReg;
+                            gen(i);
+                            return;
+                        } else if (name->builtin == IR::MathMinBuiltinFunction) {
+                            Instr::MathMinReal i;
+                            i.left = currentReg;
+                            i.right = currentReg + 1;
+                            i.output = currentReg;
+                            gen(i);
+                            return;
+                        }
+                    }
+                }
+            }
         }
     }
 
index 309ae90..a392c93 100644 (file)
@@ -312,6 +312,12 @@ void Bytecode::dump(const V4Instr *i, int address) const
     case V4Instr::StrictNotEqualString:
         INSTR_DUMP << "\t" << "StrictNotEqualString" << "\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
         break;
+    case V4Instr::MathMaxReal:
+        INSTR_DUMP << "\t" << "MathMaxReal" << "\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+        break;
+    case V4Instr::MathMinReal:
+        INSTR_DUMP << "\t" << "MathMinReal" << "\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+        break;
     case V4Instr::NewString:
         INSTR_DUMP << "\t" << "NewString" << "\t\t" << "Register(" << i->construct.reg << ")";
         break;
index fef8565..9727c23 100644 (file)
@@ -139,6 +139,8 @@ QT_BEGIN_NAMESPACE
     F(NotEqualString, binaryop) \
     F(StrictEqualString, binaryop) \
     F(StrictNotEqualString, binaryop) \
+    F(MathMaxReal, binaryop) \
+    F(MathMinReal, binaryop) \
     F(NewString, construct) \
     F(NewUrl, construct) \
     F(CleanupRegister, cleanup) \
index 051df56..54679c3 100644 (file)
@@ -227,6 +227,10 @@ void Name::init(Name *base, Type type, const QString *id, Symbol symbol, quint32
         builtin = MathFloorBultinFunction;
     } else if (id->length() == 9 && *id == QLatin1String("Math.ceil")) {
         builtin = MathCeilBuiltinFunction;
+    } else if (id->length() == 8 && *id == QLatin1String("Math.max")) {
+        builtin = MathMaxBuiltinFunction;
+    } else if (id->length() == 8 && *id == QLatin1String("Math.min")) {
+        builtin = MathMinBuiltinFunction;
     } else if (id->length() == 7 && *id == QLatin1String("Math.PI")) {
         builtin = MathPIBuiltinConstant;
         this->type = RealType;
@@ -358,6 +362,8 @@ Type Call::typeForFunction(Expr *base)
         case MathSinBultinFunction:
         case MathCosBultinFunction:
         case MathAbsBuiltinFunction:    //### type could also be Int if input was Int
+        case MathMaxBuiltinFunction:
+        case MathMinBuiltinFunction:
             return RealType;
 
         case MathRoundBultinFunction:
index 6520131..79f50cd 100644 (file)
@@ -241,6 +241,8 @@ enum BuiltinSymbol {
     MathFloorBultinFunction,
     MathCeilBuiltinFunction,
     MathAbsBuiltinFunction,
+    MathMaxBuiltinFunction,
+    MathMinBuiltinFunction,
 
     MathPIBuiltinConstant
 };