From 5f1ebe4df09a4899aa32a1c19c368e5260b5b246 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Thu, 8 Mar 2012 10:36:51 +1000 Subject: [PATCH] Add two argument Math.min and Math.max support to v4. Change-Id: I26a4812b76571bf0ae6a0b4bd5d1e2afd64051df Reviewed-by: Roberto Raggi --- src/qml/qml/v4/qv4bindings.cpp | 20 ++++++++++++++++++++ src/qml/qml/v4/qv4compiler.cpp | 34 ++++++++++++++++++++++++++++++++++ src/qml/qml/v4/qv4instruction.cpp | 6 ++++++ src/qml/qml/v4/qv4instruction_p.h | 2 ++ src/qml/qml/v4/qv4ir.cpp | 6 ++++++ src/qml/qml/v4/qv4ir_p.h | 2 ++ 6 files changed, 70 insertions(+), 0 deletions(-) diff --git a/src/qml/qml/v4/qv4bindings.cpp b/src/qml/qml/v4/qv4bindings.cpp index 3f3b666..93c7820 100644 --- a/src/qml/qml/v4/qv4bindings.cpp +++ b/src/qml/qml/v4/qv4bindings.cpp @@ -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]; diff --git a/src/qml/qml/v4/qv4compiler.cpp b/src/qml/qml/v4/qv4compiler.cpp index ce83c2d..620d260 100644 --- a/src/qml/qml/v4/qv4compiler.cpp +++ b/src/qml/qml/v4/qv4compiler.cpp @@ -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; + } + } + } + } } } diff --git a/src/qml/qml/v4/qv4instruction.cpp b/src/qml/qml/v4/qv4instruction.cpp index 309ae90..a392c93 100644 --- a/src/qml/qml/v4/qv4instruction.cpp +++ b/src/qml/qml/v4/qv4instruction.cpp @@ -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; diff --git a/src/qml/qml/v4/qv4instruction_p.h b/src/qml/qml/v4/qv4instruction_p.h index fef8565..9727c23 100644 --- a/src/qml/qml/v4/qv4instruction_p.h +++ b/src/qml/qml/v4/qv4instruction_p.h @@ -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) \ diff --git a/src/qml/qml/v4/qv4ir.cpp b/src/qml/qml/v4/qv4ir.cpp index 051df56..54679c3 100644 --- a/src/qml/qml/v4/qv4ir.cpp +++ b/src/qml/qml/v4/qv4ir.cpp @@ -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: diff --git a/src/qml/qml/v4/qv4ir_p.h b/src/qml/qml/v4/qv4ir_p.h index 6520131..79f50cd 100644 --- a/src/qml/qml/v4/qv4ir_p.h +++ b/src/qml/qml/v4/qv4ir_p.h @@ -241,6 +241,8 @@ enum BuiltinSymbol { MathFloorBultinFunction, MathCeilBuiltinFunction, MathAbsBuiltinFunction, + MathMaxBuiltinFunction, + MathMinBuiltinFunction, MathPIBuiltinConstant }; -- 1.7.2.5