From fc6afa7f7d567f32d167f04b659e7bf4f546f48d Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 9 Aug 2013 10:06:10 +0200 Subject: [PATCH] Fix binop related crashes in the interpreter if (foo instanceof blah) would crash because we generated a BinOp instruction with a null aluop pointer. Instanceof, in and add are binops that now require a context, and thus require a different instruction (BinOpContext). This was already handled by the traditional binop() of the isel, but not by the binop expression that can be in a cjump. Centralize the code by calling a common binop helper from isel binop as well as cjump. Change-Id: I793ee3eebe56db4c86d5399a783a84be3093fd35 Reviewed-by: Lars Knoll --- src/qml/compiler/qv4isel_moth.cpp | 21 +++++++++++---------- src/qml/compiler/qv4isel_moth_p.h | 2 ++ 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp index 53a3983..9313e24 100644 --- a/src/qml/compiler/qv4isel_moth.cpp +++ b/src/qml/compiler/qv4isel_moth.cpp @@ -506,6 +506,11 @@ void InstructionSelection::unop(V4IR::AluOp oper, V4IR::Temp *sourceTemp, V4IR:: void InstructionSelection::binop(V4IR::AluOp oper, V4IR::Expr *leftSource, V4IR::Expr *rightSource, V4IR::Temp *target) { + binopHelper(oper, leftSource, rightSource, target); +} + +Instr::Param InstructionSelection::binopHelper(V4IR::AluOp oper, V4IR::Expr *leftSource, V4IR::Expr *rightSource, V4IR::Temp *target) +{ #ifdef USE_TYPE_INFO if (leftSource->type & V4IR::NumberType && rightSource->type & V4IR::NumberType) { // TODO: add Temp+Const variation on the topic. @@ -516,21 +521,21 @@ void InstructionSelection::binop(V4IR::AluOp oper, V4IR::Expr *leftSource, V4IR: instr.rhs = getParam(rightSource); instr.result = getResultParam(target); addInstruction(instr); - } return; + } return instr.result; case V4IR::OpMul: { Instruction::MulNumberParams instr; instr.lhs = getParam(leftSource); instr.rhs = getParam(rightSource); instr.result = getResultParam(target); addInstruction(instr); - } return; + } return instr.result; case V4IR::OpSub: { Instruction::SubNumberParams instr; instr.lhs = getParam(leftSource); instr.rhs = getParam(rightSource); instr.result = getResultParam(target); addInstruction(instr); - } return; + } return instr.result; default: break; } @@ -551,6 +556,7 @@ void InstructionSelection::binop(V4IR::AluOp oper, V4IR::Expr *leftSource, V4IR: binop.rhs = getParam(rightSource); binop.result = getResultParam(target); addInstruction(binop); + return binop.result; } else { Instruction::Binop binop; binop.alu = aluOpFunction(oper); @@ -558,6 +564,7 @@ void InstructionSelection::binop(V4IR::AluOp oper, V4IR::Expr *leftSource, V4IR: binop.rhs = getParam(rightSource); binop.result = getResultParam(target); addInstruction(binop); + return binop.result; } } @@ -690,13 +697,7 @@ void InstructionSelection::visitCJump(V4IR::CJump *s) if (V4IR::Temp *t = s->cond->asTemp()) { condition = getResultParam(t); } else if (V4IR::Binop *b = s->cond->asBinop()) { - condition = getResultParam(0); - Instruction::Binop binop; - binop.alu = aluOpFunction(b->op); - binop.lhs = getParam(b->left); - binop.rhs = getParam(b->right); - binop.result = condition; - addInstruction(binop); + condition = binopHelper(b->op, b->left, b->right, /*target*/0); } else { Q_UNIMPLEMENTED(); } diff --git a/src/qml/compiler/qv4isel_moth_p.h b/src/qml/compiler/qv4isel_moth_p.h index 315d798..57fc964 100644 --- a/src/qml/compiler/qv4isel_moth_p.h +++ b/src/qml/compiler/qv4isel_moth_p.h @@ -126,6 +126,8 @@ protected: virtual void inplaceMemberOp(V4IR::AluOp oper, V4IR::Temp *source, V4IR::Temp *targetBase, const QString &targetName); private: + Instr::Param binopHelper(V4IR::AluOp oper, V4IR::Expr *leftSource, V4IR::Expr *rightSource, V4IR::Temp *target); + struct Instruction { #define MOTH_INSTR_DATA_TYPEDEF(I, FMT) typedef InstrData I; FOR_EACH_MOTH_INSTR(MOTH_INSTR_DATA_TYPEDEF) -- 2.7.4