void IRTranslator::translateBoxR(const NormalizedInstruction& i) { if (i.noOp) { // statically proved to be unboxed -- just pass that info to the IR TRACE(1, "HHIR: translateBoxR: output inferred to be Box\n"); m_hhbcTrans.assertTypeStack(0, JIT::Type::BoxedCell); } else { HHIR_UNIMPLEMENTED(BoxR); } }
void IRTranslator::translateFPassCOp(const NormalizedInstruction& i) { auto const op = i.op(); if (i.noOp) return; if (i.preppedByRef && (op == OpFPassCW || op == OpFPassCE)) { // These cases might have to raise a warning or an error HHIR_UNIMPLEMENTED(FPassCW_FPassCE_byref); } else { HHIR_EMIT(FPassCOp); } }
void IRTranslator::translateLtGtOp(const NormalizedInstruction& i) { auto const op = i.op(); assert(op == Op::Lt || op == Op::Lte || op == Op::Gt || op == Op::Gte); auto leftType = m_hhbcTrans.topType(1, DataTypeGeneric); auto rightType = m_hhbcTrans.topType(0, DataTypeGeneric); if (!leftType.isKnownDataType() || !rightType.isKnownDataType()) { HHIR_UNIMPLEMENTED(LtGtOp-UnknownInput); } bool ok = leftType.subtypeOfAny (Type::Null, Type::Bool, Type::Int, Type::Dbl) && rightType.subtypeOfAny(Type::Null, Type::Bool, Type::Int, Type::Dbl); HHIR_UNIMPLEMENTED_WHEN(!ok, LtGtOp); switch (op) { case Op::Lt : HHIR_EMIT(Lt); case Op::Lte : HHIR_EMIT(Lte); case Op::Gt : HHIR_EMIT(Gt); case Op::Gte : HHIR_EMIT(Gte); default : HHIR_UNIMPLEMENTED(LtGtOp); } }
void IRTranslator::translateSetOpL(const NormalizedInstruction& i) { auto const opc = [&] { switch (static_cast<SetOpOp>(i.imm[1].u_OA)) { case SetOpOp::PlusEqual: return Op::Add; case SetOpOp::MinusEqual: return Op::Sub; case SetOpOp::MulEqual: return Op::Mul; case SetOpOp::PlusEqualO: return Op::AddO; case SetOpOp::MinusEqualO: return Op::SubO; case SetOpOp::MulEqualO: return Op::MulO; case SetOpOp::DivEqual: HHIR_UNIMPLEMENTED(SetOpL_Div); case SetOpOp::ConcatEqual: return Op::Concat; case SetOpOp::ModEqual: HHIR_UNIMPLEMENTED(SetOpL_Mod); case SetOpOp::AndEqual: return Op::BitAnd; case SetOpOp::OrEqual: return Op::BitOr; case SetOpOp::XorEqual: return Op::BitXor; case SetOpOp::SlEqual: HHIR_UNIMPLEMENTED(SetOpL_Shl); case SetOpOp::SrEqual: HHIR_UNIMPLEMENTED(SetOpL_Shr); } not_reached(); }(); HHIR_EMIT(SetOpL, opc, i.imm[0].u_LA); }
void IRTranslator::translateFPassR(const NormalizedInstruction& i) { /* * Like FPassC, FPassR is able to cheat on boxing if the current * parameter is pass by reference but we have a cell: the box would refer * to exactly one datum (the value currently on the stack). * * However, if the callee wants a cell and we have a variant we must * unbox; otherwise we might accidentally make callee changes to its * parameter globally visible. */ if (!i.preppedByRef) { HHIR_EMIT(FPassR); } else { HHIR_UNIMPLEMENTED(FPassR); } }
void IRTranslator::translateLtGtOp(const NormalizedInstruction& i) { auto const op = i.op(); assert(op == Op::Lt || op == Op::Lte || op == Op::Gt || op == Op::Gte); auto leftType = m_hhbcTrans.topType(1, DataTypeGeneric); auto rightType = m_hhbcTrans.topType(0, DataTypeGeneric); bool ok = equivDataTypes(leftType.toDataType(), rightType.toDataType()) && leftType.subtypeOfAny(Type::Null, Type::Bool, Type::Int); HHIR_UNIMPLEMENTED_WHEN(!ok, LtGtOp); switch (op) { case Op::Lt : HHIR_EMIT(Lt); case Op::Lte : HHIR_EMIT(Lte); case Op::Gt : HHIR_EMIT(Gt); case Op::Gte : HHIR_EMIT(Gte); default : HHIR_UNIMPLEMENTED(LtGtOp); } }
void IRTranslator::translateContRaise(const NormalizedInstruction& i) { HHIR_UNIMPLEMENTED(ContRaise); }