diff --git a/src/bin/jbc2mpl b/src/bin/jbc2mpl index 2ad498a2eb8478ca053475d708161e35d0d502af..20976bdd9f2c4fb9e9cf1321e419159d9aacdd52 100755 Binary files a/src/bin/jbc2mpl and b/src/bin/jbc2mpl differ diff --git a/src/bin/maple b/src/bin/maple index 0f5b3166f40c48c164e07747271b2b1b99760362..bda49905a33b75a52cd2fabcb0ec48cbfd1065a5 100755 Binary files a/src/bin/maple and b/src/bin/maple differ diff --git a/src/maple_be/src/cg/aarch64/aarch64_insn.cpp b/src/maple_be/src/cg/aarch64/aarch64_insn.cpp index 7c4bae0fa247cf6d0564fe80af5acc08fb59d04e..181b7dba6588ba3dc83db1c0934fe8568f0d95ba 100644 --- a/src/maple_be/src/cg/aarch64/aarch64_insn.cpp +++ b/src/maple_be/src/cg/aarch64/aarch64_insn.cpp @@ -66,6 +66,8 @@ uint32 AArch64Insn::GetOpndNum() const { void AArch64Insn::EmitCompareAndSwapInt(Emitter &emitter) const { /* MOP_compare_and_swapI and MOP_compare_and_swapL have 8 operands */ ASSERT(opnds.size() > kInsnEighthOpnd, "ensure the operands number"); + const MOperator mOp = GetMachineOpcode(); + const AArch64MD *md = &AArch64CG::kMd[mOp]; Operand *temp0 = opnds[kInsnSecondOpnd]; Operand *temp1 = opnds[kInsnThirdOpnd]; Operand *obj = opnds[kInsnFourthOpnd]; @@ -89,11 +91,12 @@ void AArch64Insn::EmitCompareAndSwapInt(Emitter &emitter) const { temp0->Emit(emitter, nullptr); emitter.Emit("]\n"); Operand *expectedValue = opnds[kInsnSixthOpnd]; + OpndProp *expectedValueProp = md->operand[kInsnSixthOpnd]; /* cmp ws, w3 */ emitter.Emit("\tcmp\t"); temp1->Emit(emitter, nullptr); emitter.Emit(", "); - expectedValue->Emit(emitter, nullptr); + expectedValue->Emit(emitter, expectedValueProp); emitter.Emit("\n"); constexpr uint32 kInsnNinethOpnd = 8; Operand *label2 = opnds[kInsnNinethOpnd]; diff --git a/src/maple_be/src/cg/eh_func.cpp b/src/maple_be/src/cg/eh_func.cpp index daa3e0a19101918866e5078435cc2aeb5f7389b0..f05fba58b3c6dda43d73a3745657bb8ff0914252 100644 --- a/src/maple_be/src/cg/eh_func.cpp +++ b/src/maple_be/src/cg/eh_func.cpp @@ -191,6 +191,15 @@ void EHThrow::Lower(CGFunc &cgFunc) { arg = retypeNode->CloneTree(mirModule->GetCurFuncCodeMPAllocator()); break; } + case OP_cvt: { + TypeCvtNode *cvtNode = static_cast(opnd0); + PrimType prmType = cvtNode->GetPrimType(); + // prmType supposed to be Pointer. + if ((prmType == PTY_ptr) || (prmType == PTY_ref) || (prmType == PTY_a32) || (prmType == PTY_a64)) { + ConvertThrowToRethrow(cgFunc); + } + return; + } default: ASSERT(false, " NYI throw something"); } diff --git a/src/mpl2mpl/src/constantfold.cpp b/src/mpl2mpl/src/constantfold.cpp index 35b4a427228df8ccacedc6dc1754073cd6293b53..e0ad8af745f463a763d849816f68fe2b4fcd9eb7 100644 --- a/src/mpl2mpl/src/constantfold.cpp +++ b/src/mpl2mpl/src/constantfold.cpp @@ -1344,11 +1344,10 @@ std::pair ConstantFold::FoldBinary(BinaryNode *node) { } else if (op == OP_sub) { sum = cst - rp.second; result = NegateTree(r); - } else if ((op == OP_mul || op == OP_div || op == OP_rem || op == OP_ashr || op == OP_lshr || op == OP_shl || + } else if ((op == OP_mul || op == OP_rem || op == OP_ashr || op == OP_lshr || op == OP_shl || op == OP_band || op == OP_cand || op == OP_land) && cst == 0) { // 0 * X -> 0 - // 0 / X -> 0 // 0 % X -> 0 // 0 >> X -> 0 // 0 << X -> 0 diff --git a/src/mpl2mpl/src/muid_replacement.cpp b/src/mpl2mpl/src/muid_replacement.cpp index ed7b2ceccf3c0afe0c3a9c6136e6ea69f6bf6c20..fb2f5cf07675f7e043eab946a4fae7c58c3a2251 100644 --- a/src/mpl2mpl/src/muid_replacement.cpp +++ b/src/mpl2mpl/src/muid_replacement.cpp @@ -993,6 +993,7 @@ void MUIDReplacement::ReplaceDirectInvokeOrAddroffunc(MIRFunction ¤tFunc, std::string moduleName = GetMIRModule().GetFileNameAsPostfix(); std::string baseName = calleeFunc->GetBaseClassName(); + ASSERT(funcDefTabSym != nullptr, "null ptr check!"); baseExpr = builder->CreateExprAddrof(0, *funcDefTabSym, GetMIRModule().GetMemPool()); ASSERT(calleeFunc->GetFuncSymbol() != nullptr, "null ptr check!"); index = FindIndexFromDefTable(*(calleeFunc->GetFuncSymbol()), true); @@ -1003,6 +1004,7 @@ void MUIDReplacement::ReplaceDirectInvokeOrAddroffunc(MIRFunction ¤tFunc, std::string commentLabel = NameMangler::kMarkMuidFuncUndefStr + calleeFunc->GetName(); currentFunc.GetBody()->InsertBefore(&stmt, builder->CreateStmtComment(commentLabel)); + ASSERT(funcUndefTabSym != nullptr, "null ptr check!"); baseExpr = builder->CreateExprAddrof(0, *funcUndefTabSym, GetMIRModule().GetMemPool()); ASSERT(calleeFunc->GetFuncSymbol() != nullptr, "null ptr check!"); index = FindIndexFromUndefTable(*(calleeFunc->GetFuncSymbol()), true); diff --git a/src/mpl2mpl/src/reflection_analysis.cpp b/src/mpl2mpl/src/reflection_analysis.cpp index ecb5093098ce3b3ba3dc2b410376b68b642488ed..f597107e293b8047cbeb4ad26f99e9a695ce9c78 100644 --- a/src/mpl2mpl/src/reflection_analysis.cpp +++ b/src/mpl2mpl/src/reflection_analysis.cpp @@ -928,7 +928,6 @@ static void ConvertFieldName(std::string &fieldname, bool staticfield) { std::stringstream ss(decodeFieldName); std::string item; std::vector res; - std::string typeName, fieldName; while (std::getline(ss, item, '|')) { res.push_back(item); } diff --git a/src/mplfe/common/src/feir_type.cpp b/src/mplfe/common/src/feir_type.cpp index 66300fe316144d744e686c23b0dee9699e165bfb..36d10447825f4f0ddd189d3d69035f87e0f55548 100644 --- a/src/mplfe/common/src/feir_type.cpp +++ b/src/mplfe/common/src/feir_type.cpp @@ -221,6 +221,8 @@ MIRType *FEIRTypeDefault::GenerateMIRTypeForPrim() const { return GlobalTables::GetTypeTable().GetUInt16(); case PTY_void: return GlobalTables::GetTypeTable().GetVoid(); + case PTY_a32: + return GlobalTables::GetTypeTable().GetAddr32(); default: CHECK_FATAL(false, "unsupported prim type"); } diff --git a/src/mplfe/jbc_input/include/jbc_function.h b/src/mplfe/jbc_input/include/jbc_function.h index bf53f6787090ea8aa90a3ba85a3e9f5c562e573e..ee16f428d0f8bf7d03ad581315c24710a01ef8d9 100644 --- a/src/mplfe/jbc_input/include/jbc_function.h +++ b/src/mplfe/jbc_input/include/jbc_function.h @@ -102,8 +102,16 @@ class JBCFunction : public FEFunction { std::map mapPCLabelStmt; // key: labelPC, value: stmt std::map mapPCStmtLOC; // key: locPC, value: stmt std::map mapPCCommentStmt; // key: commentPC, value: stmt + std::map> mapJsrSlotRetAddr; // key: slotIdx, value: map GeneralBB *pesudoBBCatchPred; - void BuildStmtFromInstruction(const jbc::JBCAttrCode &code); + + bool PreBuildJsrInfo(const jbc::JBCAttrCode &code); + bool BuildStmtFromInstruction(const jbc::JBCAttrCode &code); + GeneralStmt *BuildStmtFromInstructionForBranch(const jbc::JBCOp &op); + GeneralStmt *BuildStmtFromInstructionForGoto(const jbc::JBCOp &op); + GeneralStmt *BuildStmtFromInstructionForSwitch(const jbc::JBCOp &op); + GeneralStmt *BuildStmtFromInstructionForJsr(const jbc::JBCOp &op); + GeneralStmt *BuildStmtFromInstructionForRet(const jbc::JBCOp &op); void BuildStmtForCatch(const jbc::JBCAttrCode &code); void BuildStmtForTry(const jbc::JBCAttrCode &code); void BuildTryInfo(const std::map, std::vector> &rawInfo, diff --git a/src/mplfe/jbc_input/include/jbc_opcode.def b/src/mplfe/jbc_input/include/jbc_opcode.def index 822641fee69dd4de8e4560c6a9063095aff1eadf..d05768413795a8076583070bfc12da7fb38bef15 100644 --- a/src/mplfe/jbc_input/include/jbc_opcode.def +++ b/src/mplfe/jbc_input/include/jbc_opcode.def @@ -181,8 +181,8 @@ JBC_OP(IfICmple, 0xA4, Branch, "if_icmple", (kOpFlagFallThru | kOpFlagBranch)) JBC_OP(IfACmpeq, 0xA5, Branch, "if_acmpeq", (kOpFlagFallThru | kOpFlagBranch)) JBC_OP(IfACmpne, 0xA6, Branch, "if_acmpne", (kOpFlagFallThru | kOpFlagBranch)) JBC_OP(Goto, 0xA7, Goto, "goto", (kOpFlagBranch)) -JBC_OP(Jsr, 0xA8, Reversed, "jsr", (kOpFlagBranch)) -JBC_OP(Ret, 0xA9, Reversed, "ret", (kOpFlagBranch)) +JBC_OP(Jsr, 0xA8, Jsr, "jsr", (kOpFlagBranch)) +JBC_OP(Ret, 0xA9, Ret, "ret", (kOpFlagBranch)) JBC_OP(TableSwitch, 0xAA, Switch, "tableswitch", (kOpFlagBranch)) JBC_OP(LookupSwitch, 0xAB, Switch, "lookupswitch", (kOpFlagBranch)) JBC_OP(IReturn, 0xAC, Return, "ireturn", (kOpFlagThrowable)) diff --git a/src/mplfe/jbc_input/include/jbc_opcode.h b/src/mplfe/jbc_input/include/jbc_opcode.h index d26a8d0bc4ef907c4134a3fc1e44daf260519aea..2a022159de8987e78fae2565ffd75c5b408e96bc 100644 --- a/src/mplfe/jbc_input/include/jbc_opcode.h +++ b/src/mplfe/jbc_input/include/jbc_opcode.h @@ -300,6 +300,7 @@ class JBCOpSlotOpr : public JBCOp { public: JBCOpSlotOpr(MapleAllocator &allocator, JBCOpcode opIn, JBCOpcodeKind kindIn, bool wideIn); ~JBCOpSlotOpr() = default; + bool IsAStore() const; uint16 GetSlotIdx() const { return slotIdx; } @@ -308,6 +309,18 @@ class JBCOpSlotOpr : public JBCOp { slotIdx = argSlotIdx; } + bool IsAddressOpr() const { + return isAddressOpr; + } + + void SetAddressOpr() { + isAddressOpr = true; + } + + void UnsetAddressOpr() { + isAddressOpr = false; + } + protected: bool ParseFileImpl(BasicIORead &io) override; const std::vector &GetInputTypesFromStackImpl() const override; @@ -320,9 +333,11 @@ class JBCOpSlotOpr : public JBCOp { static std::map InitMapOpOutputType(); uint16 slotIdx; + bool isAddressOpr; static std::map> mapSlotIdxAndType; static std::map> mapOpInputTypes; static std::map mapOpOutputType; + static std::vector inputTypesAddressOpr; }; class JBCOpMathInc : public JBCOp { @@ -513,11 +528,31 @@ class JBCOpJsr : public JBCOp { target = argTarget; } + uint16 GetSlotIdx() const { + return slotIdx; + } + + void SetSlotIdx(uint32 argSlotIdx) { + slotIdx = argSlotIdx; + } + + int32 GetJsrID() const { + return jsrID; + } + + void SetJsrID(int32 argJsrID) { + jsrID = argJsrID; + } + protected: bool ParseFileImpl(BasicIORead &io) override; + JBCPrimType GetOutputTypesToStackImpl() const override; + std::string DumpImpl(const JBCConstPool &constPool) const override; private: uint32 target; + uint16 slotIdx; + int32 jsrID; }; class JBCOpRet : public JBCOp { @@ -534,6 +569,7 @@ class JBCOpRet : public JBCOp { protected: bool ParseFileImpl(BasicIORead &io) override; + std::string DumpImpl(const JBCConstPool &constPool) const override; private: uint16 index; diff --git a/src/mplfe/jbc_input/include/jbc_stack2fe_helper.h b/src/mplfe/jbc_input/include/jbc_stack2fe_helper.h index 0bfd9bbd18a33a7f34c2850b04c58b0e96551192..b69644be22911f9b56f83749028847dc34ff674b 100644 --- a/src/mplfe/jbc_input/include/jbc_stack2fe_helper.h +++ b/src/mplfe/jbc_input/include/jbc_stack2fe_helper.h @@ -126,7 +126,7 @@ class JBCStack2FEHelper { } bool IsPrimTypeNormal(PrimType pty) const { - return pty == PTY_i32 || pty == PTY_f32 || pty == PTY_ref; + return pty == PTY_i32 || pty == PTY_f32 || pty == PTY_ref || pty == PTY_a32; } bool IsPrimTypeWide(PrimType pty) const { diff --git a/src/mplfe/jbc_input/include/jbc_stmt.h b/src/mplfe/jbc_input/include/jbc_stmt.h index b68acf47853132a00c1cced90319d7681f410ce6..3bd9648dc8f98820d53df57a87566ee50e666cb7 100644 --- a/src/mplfe/jbc_input/include/jbc_stmt.h +++ b/src/mplfe/jbc_input/include/jbc_stmt.h @@ -27,6 +27,7 @@ enum JBCStmtKind : uint8 { kJBCStmtFuncEnd, kJBCStmtInst, kJBCStmtInstBranch, + kJBCStmtInstBranchRet, kJBCStmtPesudoComment, kJBCStmtPesudoLOC, kJBCStmtPesudoLabel, @@ -68,6 +69,10 @@ class JBCStmt : public GeneralStmt { kind = argKind; } + bool IsBranch() const { + return kind == JBCStmtKind::kJBCStmtInstBranch || kind == JBCStmtKind::kJBCStmtInstBranchRet; + } + protected: virtual std::list EmitToFEIRImpl(JBCStack2FEHelper &stack2feHelper, const jbc::JBCConstPool &constPool, @@ -248,6 +253,14 @@ class JBCStmtInstBranch : public JBCStmt { std::list EmitToFEIRImpl(JBCStack2FEHelper &stack2feHelper, const jbc::JBCConstPool &constPool, bool &success) const override; + JBCStmtPesudoLabel *GetTarget(const std::map &mapPCStmtLabel, uint32 pc) const; + virtual std::list EmitToFEIRForOpRetImpl(JBCStack2FEHelper &stack2feHelper, + const std::map &mapPCStmtLabel, + bool &success) const { + return std::list(); + } + + const jbc::JBCOp &op; private: // bitwise mode @@ -257,7 +270,6 @@ class JBCStmtInstBranch : public JBCStmt { kModeUseZeroAsSecondOpnd = 0x2 // bit1: 1 for using 0 for 2nd opnd, 0 for using normal opnd }; - const jbc::JBCOp &op; using FuncPtrEmitToFEIR = std::list (JBCStmtInstBranch::*)(JBCStack2FEHelper &stack2feHelper, const std::map &mapPCStmtLabel, @@ -275,11 +287,31 @@ class JBCStmtInstBranch : public JBCStmt { std::list EmitToFEIRForOpSwitch(JBCStack2FEHelper &stack2feHelper, const std::map &mapPCStmtLabel, bool &success) const; + std::list EmitToFEIRForOpJsr(JBCStack2FEHelper &stack2feHelper, + const std::map &mapPCStmtLabel, + bool &success) const; + std::list EmitToFEIRForOpRet(JBCStack2FEHelper &stack2feHelper, + const std::map &mapPCStmtLabel, + bool &success) const; std::list EmitToFEIRCommon(JBCStack2FEHelper &stack2feHelper, const std::map &mapPCStmtLabel, bool &success) const; }; +class JBCStmtInstBranchRet : public JBCStmtInstBranch { + public: + JBCStmtInstBranchRet(const jbc::JBCOp &argOp, const std::map> &argMapJsrSlotRetAddr); + ~JBCStmtInstBranchRet() = default; + + protected: + std::list EmitToFEIRForOpRetImpl(JBCStack2FEHelper &stack2feHelper, + const std::map &mapPCStmtLabel, + bool &success) const override; + + private: + const std::map> &mapJsrSlotRetAddr; +}; + class JBCStmtPesudoLabel : public JBCStmt { public: JBCStmtPesudoLabel() diff --git a/src/mplfe/jbc_input/src/jbc_function.cpp b/src/mplfe/jbc_input/src/jbc_function.cpp index d997eba14d15b997ddd3a8a10c6c9ae9d277630d..28a33357f1082d9c968b8e0826523f1ddb942771 100644 --- a/src/mplfe/jbc_input/src/jbc_function.cpp +++ b/src/mplfe/jbc_input/src/jbc_function.cpp @@ -103,7 +103,12 @@ bool JBCFunction::GenerateGeneralStmt(const std::string &phaseName) { phaseResult.RegisterPhaseNameAndStart(phaseName); const jbc::JBCAttrCode *code = method.GetCode(); if (phaseResult.IsSuccess() && code != nullptr) { - BuildStmtFromInstruction(*code); + if (!PreBuildJsrInfo(*code)) { + return phaseResult.Finish(false); + } + if (!BuildStmtFromInstruction(*code)) { + return phaseResult.Finish(false); + } BuildStmtForCatch(*code); BuildStmtForTry(*code); BuildStmtForLOC(*code); @@ -193,7 +198,7 @@ void JBCFunction::EmitToFEIRStmt(const JBCBB &bb) { const FELinkListNode *stmtNode = bb.GetStmtHead(); while (stmtNode != nullptr && success) { const JBCStmt *stmt = static_cast(stmtNode); - if (stmt->GetKind() == JBCStmtKind::kJBCStmtInstBranch) { + if (stmt->IsBranch()) { const JBCStmtInstBranch *stmtBranch = static_cast(stmt); feirStmts = stmtBranch->EmitToFEIRWithLabel(stack2feHelper, mapPCLabelStmt, success); } else { @@ -298,7 +303,48 @@ bool JBCFunction::CheckJVMStackResult() { return true; } -void JBCFunction::BuildStmtFromInstruction(const jbc::JBCAttrCode &code) { +bool JBCFunction::PreBuildJsrInfo(const jbc::JBCAttrCode &code) { + const MapleMap &instMap = code.GetInstMap(); + for (const std::pair &it : instMap) { + uint32 pc = it.first; + jbc::JBCOp *op = it.second; + ASSERT_NOT_NULL(op); + jbc::JBCOpcode opcode = op->GetOpcode(); + jbc::JBCOpcodeKind kind = op->GetOpcodeKind(); + if (kind != jbc::kOpKindJsr) { + continue;; + } + uint32 width = (opcode == jbc::kOpJsr ? 3 : 5); // instruction width for jsr is 3, and for jsr_w is 5 + uint32 nextPC = pc + width; + jbc::JBCOpJsr *opJsr = static_cast(op); + auto itTarget = instMap.find(opJsr->GetTarget()); + if (itTarget == instMap.end()) { + ERR(kLncErr, "invalid target %u for jsr @pc=%u", opJsr->GetTarget(), pc); + return false; + } + jbc::JBCOp *opTarget = itTarget->second; + if (opTarget->GetOpcodeKind() != jbc::kOpKindStore) { + ERR(kLncErr, "invalid target (without astore) for jsr @pc=%u", pc); + return false; + } + jbc::JBCOpSlotOpr *opSlotOpr = static_cast(opTarget); + uint16 slotIdx = opSlotOpr->GetSlotIdx(); + opSlotOpr->SetAddressOpr(); + opJsr->SetSlotIdx(slotIdx); + auto itInfo = mapJsrSlotRetAddr.find(slotIdx); + int32 jsrID; + if (itInfo == mapJsrSlotRetAddr.end()) { + jsrID = 0; + } else { + jsrID = itInfo->second.size(); + } + opJsr->SetJsrID(jsrID); + mapJsrSlotRetAddr[slotIdx][jsrID] = nextPC; + } + return true; +} + +bool JBCFunction::BuildStmtFromInstruction(const jbc::JBCAttrCode &code) { GeneralStmt *stmt = nullptr; const MapleMap &instMap = code.GetInstMap(); for (const std::pair &it : instMap) { @@ -306,39 +352,24 @@ void JBCFunction::BuildStmtFromInstruction(const jbc::JBCAttrCode &code) { const jbc::JBCOp *op = it.second; ASSERT(op != nullptr, "null ptr check"); switch (op->GetOpcodeKind()) { - case jbc::kOpKindBranch: { - const std::unique_ptr &uniStmt = - RegisterGeneralStmtUniqueReturn(std::make_unique(*op)); - stmt = uniStmt.get(); - const jbc::JBCOpBranch *opBranch = static_cast(op); - GeneralStmt *target = BuildAndUpdateLabel(opBranch->GetTarget(), uniStmt); - static_cast(stmt)->AddSucc(target); + case jbc::kOpKindBranch: + stmt = BuildStmtFromInstructionForBranch(*op); break; - } - case jbc::kOpKindGoto: { - const std::unique_ptr &uniStmt = - RegisterGeneralStmtUniqueReturn(std::make_unique(*op)); - stmt = uniStmt.get(); - stmt->SetFallThru(false); - const jbc::JBCOpGoto *opGoto = static_cast(op); - GeneralStmt *target = BuildAndUpdateLabel(opGoto->GetTarget(), uniStmt); - static_cast(stmt)->AddSucc(target); + case jbc::kOpKindGoto: + stmt = BuildStmtFromInstructionForGoto(*op); break; - } - case jbc::kOpKindSwitch:{ - const std::unique_ptr &uniStmt = - RegisterGeneralStmtUniqueReturn(std::make_unique(*op)); - stmt = uniStmt.get(); - stmt->SetFallThru(false); - const jbc::JBCOpSwitch *opSwitch = static_cast(op); - for (const std::pair &targetInfo : opSwitch->GetTargets()) { - GeneralStmt *target = BuildAndUpdateLabel(targetInfo.second, uniStmt); - static_cast(stmt)->AddSucc(target); + case jbc::kOpKindSwitch: + stmt = BuildStmtFromInstructionForSwitch(*op); + break; + case jbc::kOpKindJsr: + stmt = BuildStmtFromInstructionForJsr(*op); + break; + case jbc::kOpKindRet: + stmt = BuildStmtFromInstructionForRet(*op); + if (stmt == nullptr) { + return false; } - GeneralStmt *target = BuildAndUpdateLabel(opSwitch->GetDefaultTarget(), uniStmt); - static_cast(stmt)->AddSucc(target); break; - } default: stmt = RegisterGeneralStmt(std::make_unique(*op)); break; @@ -347,6 +378,73 @@ void JBCFunction::BuildStmtFromInstruction(const jbc::JBCAttrCode &code) { mapPCStmtInst[pc] = stmt; } mapPCStmtInst[code.GetCodeLength()] = genStmtTail; + return true; +} + +GeneralStmt *JBCFunction::BuildStmtFromInstructionForBranch(const jbc::JBCOp &op) { + const std::unique_ptr &uniStmt = + RegisterGeneralStmtUniqueReturn(std::make_unique(op)); + GeneralStmt *stmt = uniStmt.get(); + const jbc::JBCOpBranch &opBranch = static_cast(op); + GeneralStmt *target = BuildAndUpdateLabel(opBranch.GetTarget(), uniStmt); + static_cast(stmt)->AddSucc(target); + return stmt; +} + +GeneralStmt *JBCFunction::BuildStmtFromInstructionForGoto(const jbc::JBCOp &op) { + const std::unique_ptr &uniStmt = + RegisterGeneralStmtUniqueReturn(std::make_unique(op)); + GeneralStmt *stmt = uniStmt.get(); + stmt->SetFallThru(false); + const jbc::JBCOpGoto &opGoto = static_cast(op); + GeneralStmt *target = BuildAndUpdateLabel(opGoto.GetTarget(), uniStmt); + static_cast(stmt)->AddSucc(target); + return stmt; +} + +GeneralStmt *JBCFunction::BuildStmtFromInstructionForSwitch(const jbc::JBCOp &op) { + const std::unique_ptr &uniStmt = + RegisterGeneralStmtUniqueReturn(std::make_unique(op)); + GeneralStmt *stmt = uniStmt.get(); + stmt->SetFallThru(false); + const jbc::JBCOpSwitch &opSwitch = static_cast(op); + for (const std::pair &targetInfo : opSwitch.GetTargets()) { + GeneralStmt *target = BuildAndUpdateLabel(targetInfo.second, uniStmt); + static_cast(stmt)->AddSucc(target); + } + GeneralStmt *target = BuildAndUpdateLabel(opSwitch.GetDefaultTarget(), uniStmt); + static_cast(stmt)->AddSucc(target); + return stmt; +} + +GeneralStmt *JBCFunction::BuildStmtFromInstructionForJsr(const jbc::JBCOp &op) { + const std::unique_ptr &uniStmt = + RegisterGeneralStmtUniqueReturn(std::make_unique(op)); + GeneralStmt *stmt = uniStmt.get(); + stmt->SetFallThru(false); + const jbc::JBCOpJsr &opJsr = static_cast(op); + GeneralStmt *target = BuildAndUpdateLabel(opJsr.GetTarget(), uniStmt); + static_cast(stmt)->AddSucc(target); + return stmt; +} + +GeneralStmt *JBCFunction::BuildStmtFromInstructionForRet(const jbc::JBCOp &op) { + const std::unique_ptr &uniStmt = + RegisterGeneralStmtUniqueReturn(std::make_unique(op, mapJsrSlotRetAddr)); + GeneralStmt *stmt = uniStmt.get(); + stmt->SetFallThru(false); + const jbc::JBCOpRet &opRet = static_cast(op); + auto itJsrInfo = mapJsrSlotRetAddr.find(opRet.GetIndex()); + if (itJsrInfo == mapJsrSlotRetAddr.end()) { + ERR(kLncWarn, "invalid slotIdx for ret instruction"); + return nullptr; + } + for (auto itTarget : itJsrInfo->second) { + uint32 pc = itTarget.second; + GeneralStmt *target = BuildAndUpdateLabel(pc, uniStmt); + static_cast(stmt)->AddSucc(target); + } + return stmt; } void JBCFunction::BuildStmtForCatch(const jbc::JBCAttrCode &code) { diff --git a/src/mplfe/jbc_input/src/jbc_opcode.cpp b/src/mplfe/jbc_input/src/jbc_opcode.cpp index e9069e92e29d254b18a996479510d02214b652dd..9e0654d7cc819c64fcfe40ce70600393fdbaf4d5 100644 --- a/src/mplfe/jbc_input/src/jbc_opcode.cpp +++ b/src/mplfe/jbc_input/src/jbc_opcode.cpp @@ -612,9 +612,23 @@ std::map> JBCOpSlotOpr::mapSlotIdxAndT JBCOpSlotOpr::InitMapSlotIdxAndType(); std::map> JBCOpSlotOpr::mapOpInputTypes = JBCOpSlotOpr::InitMapOpInputTypes(); std::map JBCOpSlotOpr::mapOpOutputType = JBCOpSlotOpr::InitMapOpOutputType(); +std::vector JBCOpSlotOpr::inputTypesAddressOpr = { JBCPrimType::kTypeAddress }; JBCOpSlotOpr::JBCOpSlotOpr(MapleAllocator &allocator, JBCOpcode opIn, JBCOpcodeKind kindIn, bool wideIn) - : JBCOp(allocator, opIn, kindIn, wideIn), slotIdx(0) {} + : JBCOp(allocator, opIn, kindIn, wideIn), slotIdx(0), isAddressOpr(false) {} + +bool JBCOpSlotOpr::IsAStore() const { + switch (op) { + case jbc::kOpAStore: + case jbc::kOpAStore0: + case jbc::kOpAStore1: + case jbc::kOpAStore2: + case jbc::kOpAStore3: + return true; + default: + return false; + } +} bool JBCOpSlotOpr::ParseFileImpl(BasicIORead &io) { bool success = false; @@ -650,6 +664,9 @@ bool JBCOpSlotOpr::ParseFileImpl(BasicIORead &io) { } const std::vector &JBCOpSlotOpr::GetInputTypesFromStackImpl() const { + if (isAddressOpr) { + return inputTypesAddressOpr; + } auto it = mapOpInputTypes.find(op); CHECK_FATAL(it != mapOpInputTypes.end(), "Unsupported opcode %s", opcodeInfo.GetOpcodeName(op).c_str()); return it->second; @@ -1244,6 +1261,16 @@ bool JBCOpJsr::ParseFileImpl(BasicIORead &io) { return success; } +JBCPrimType JBCOpJsr::GetOutputTypesToStackImpl() const { + return JBCPrimType::kTypeAddress; +} + +std::string JBCOpJsr::DumpImpl(const JBCConstPool &constPool) const { + std::stringstream ss; + ss << GetOpcodeName() << " " << target; + return ss.str(); +} + // ---------- JBCOpRet ---------- JBCOpRet::JBCOpRet(MapleAllocator &allocator, JBCOpcode opIn, JBCOpcodeKind kindIn, bool wideIn) : JBCOp(allocator, opIn, kindIn, wideIn), index(0) {} @@ -1258,6 +1285,12 @@ bool JBCOpRet::ParseFileImpl(BasicIORead &io) { return success; } +std::string JBCOpRet::DumpImpl(const JBCConstPool &constPool) const { + std::stringstream ss; + ss << GetOpcodeName() << " " << index; + return ss.str(); +} + // ---------- JBCOpNew ---------- std::map> JBCOpNew::mapOpInputTypes = JBCOpNew::InitMapOpInputTypes(); diff --git a/src/mplfe/jbc_input/src/jbc_stack2fe_helper.cpp b/src/mplfe/jbc_input/src/jbc_stack2fe_helper.cpp index c0a8d926bb4e37e8713f391283685bf2ffd5de6d..cb2c670793f094c0c2c36ac8cc9f372d7d51ccda 100644 --- a/src/mplfe/jbc_input/src/jbc_stack2fe_helper.cpp +++ b/src/mplfe/jbc_input/src/jbc_stack2fe_helper.cpp @@ -343,7 +343,7 @@ PrimType JBCStack2FEHelper::JBCStackItemTypeToPrimType(jbc::JBCPrimType itemType case jbc::JBCPrimType::kTypeRef: return PTY_ref; case jbc::JBCPrimType::kTypeAddress: - return PTY_i32; + return PTY_a32; case jbc::JBCPrimType::kTypeDefault: return PTY_unknown; default: diff --git a/src/mplfe/jbc_input/src/jbc_stmt.cpp b/src/mplfe/jbc_input/src/jbc_stmt.cpp index 9632067ed95c3061edf10d194778d9a5e552d8ae..e9145b8917ee62d8282efb944cc6004b17672495 100644 --- a/src/mplfe/jbc_input/src/jbc_stmt.cpp +++ b/src/mplfe/jbc_input/src/jbc_stmt.cpp @@ -410,6 +410,13 @@ std::list JBCStmtInst::EmitToFEIRForOpStore(JBCStack2FEHelper &s bool &success) const { std::list ans; const jbc::JBCOpSlotOpr &opStore = static_cast(op); + if (opStore.IsAddressOpr()) { + UniqueFEIRVar varTmp = stack2feHelper.PopItem(PTY_a32); + if (varTmp.get() == nullptr) { + success = false; + } + return ans; + } std::vector stackInTypes = op.GetInputTypesFromStack(); CHECK_FATAL(stackInTypes.size() == 1, "store op need one stack opnd"); PrimType pty = JBCStack2FEHelper::JBCStackItemTypeToPrimType(stackInTypes[0]); @@ -1139,6 +1146,16 @@ std::list JBCStmtInstBranch::EmitToFEIRImpl(JBCStack2FEHelper &s return ans; } +JBCStmtPesudoLabel *JBCStmtInstBranch::GetTarget(const std::map &mapPCStmtLabel, + uint32 pc) const { + auto itTarget = mapPCStmtLabel.find(pc); + if (itTarget == mapPCStmtLabel.end()) { + ERR(kLncErr, "target@pc=%u not found", pc); + return nullptr; + } + return itTarget->second; +} + std::list JBCStmtInstBranch::EmitToFEIRWithLabel( JBCStack2FEHelper &stack2feHelper, const std::map &mapPCStmtLabel, @@ -1156,6 +1173,8 @@ std::map JBCStmtInstBr ans[jbc::JBCOpcodeKind::kOpKindGoto] = &JBCStmtInstBranch::EmitToFEIRForOpGoto; ans[jbc::JBCOpcodeKind::kOpKindBranch] = &JBCStmtInstBranch::EmitToFEIRForOpBranch; ans[jbc::JBCOpcodeKind::kOpKindSwitch] = &JBCStmtInstBranch::EmitToFEIRForOpSwitch; + ans[jbc::JBCOpcodeKind::kOpKindJsr] = &JBCStmtInstBranch::EmitToFEIRForOpJsr; + ans[jbc::JBCOpcodeKind::kOpKindRet] = &JBCStmtInstBranch::EmitToFEIRForOpRet; return ans; } @@ -1266,6 +1285,38 @@ std::list JBCStmtInstBranch::EmitToFEIRForOpSwitch( return ans; } +std::list JBCStmtInstBranch::EmitToFEIRForOpJsr( + JBCStack2FEHelper &stack2feHelper, + const std::map &mapPCStmtLabel, + bool &success) const { + std::list ans; + const jbc::JBCOpJsr &opJsr = static_cast(op); + auto itTarget = mapPCStmtLabel.find(opJsr.GetTarget()); + if (itTarget == mapPCStmtLabel.end()) { + ERR(kLncErr, "target not found for inst jsr"); + success = false; + return ans; + } + JBCStmtPesudoLabel *stmtLabel = itTarget->second; + CHECK_NULL_FATAL(stmtLabel); + uint32 slotRegNum = stack2feHelper.GetRegNumForSlot(opJsr.GetSlotIdx()); + UniqueFEIRVar var = FEIRBuilder::CreateVarReg(slotRegNum, PTY_i32, false); + stack2feHelper.PushItem(var->Clone(), PTY_a32); + UniqueFEIRExpr exprConst = FEIRBuilder::CreateExprConstI32(opJsr.GetJsrID()); + UniqueFEIRStmt stmtJsr = FEIRBuilder::CreateStmtDAssign(std::move(var), std::move(exprConst)); + UniqueFEIRStmt stmtGoto = FEIRBuilder::CreateStmtGoto(stmtLabel->GetLabelIdx()); + ans.push_back(std::move(stmtJsr)); + ans.push_back(std::move(stmtGoto)); + return ans; +} + +std::list JBCStmtInstBranch::EmitToFEIRForOpRet( + JBCStack2FEHelper &stack2feHelper, + const std::map &mapPCStmtLabel, + bool &success) const { + return EmitToFEIRForOpRetImpl(stack2feHelper, mapPCStmtLabel, success); +} + std::list JBCStmtInstBranch::EmitToFEIRCommon( JBCStack2FEHelper &stack2feHelper, const std::map &mapPCStmtLabel, @@ -1313,6 +1364,61 @@ std::map> JBCStmtInstBranch::I return ans; } +// ---------- JBCStmtInstBranchRet ---------- +JBCStmtInstBranchRet::JBCStmtInstBranchRet(const jbc::JBCOp &argOp, + const std::map> &argMapJsrSlotRetAddr) + : JBCStmtInstBranch(argOp), + mapJsrSlotRetAddr(argMapJsrSlotRetAddr) { + kind = kJBCStmtInstBranchRet; +} + +std::list JBCStmtInstBranchRet::EmitToFEIRForOpRetImpl( + JBCStack2FEHelper &stack2feHelper, + const std::map &mapPCStmtLabel, + bool &success) const { + std::list ans; + const jbc::JBCOpRet &opRet = static_cast(op); + uint16 slotIdx = opRet.GetIndex(); + auto itJsrInfo = mapJsrSlotRetAddr.find(slotIdx); + if (itJsrInfo == mapJsrSlotRetAddr.end()) { + WARN(kLncWarn, "jsr info not found"); + success = false; + return ans; + } + const std::map &jsrInfo = itJsrInfo->second; + if (jsrInfo.size() == 1) { + auto itInfo = jsrInfo.begin(); + JBCStmtPesudoLabel *stmtLabel = GetTarget(mapPCStmtLabel, itInfo->second); + if (stmtLabel == nullptr) { + success = false; + return ans; + } + UniqueFEIRStmt stmtGoto = FEIRBuilder::CreateStmtGoto(stmtLabel->GetLabelIdx()); + ans.push_back(std::move(stmtGoto)); + } else { + uint32 idx = 0; + UniqueFEIRVar var = FEIRBuilder::CreateVarReg(slotIdx, PTY_i32); + UniqueFEIRExpr exprValue = FEIRBuilder::CreateExprDRead(std::move(var)); + UniqueFEIRStmt stmtSwitch = FEIRBuilder::CreateStmtSwitch(std::move(exprValue)); + FEIRStmtSwitch *ptrStmtSwitch = static_cast(stmtSwitch.get()); + for (auto itInfo : jsrInfo) { + JBCStmtPesudoLabel *stmtLabel = GetTarget(mapPCStmtLabel, itInfo.second); + if (stmtLabel == nullptr) { + success = false; + return ans; + } + if (idx == jsrInfo.size() - 1) { + ptrStmtSwitch->SetDefaultLabelIdx(stmtLabel->GetLabelIdx()); + } else { + ptrStmtSwitch->AddTarget(itInfo.first, stmtLabel->GetLabelIdx()); + } + ++idx; + } + ans.push_back(std::move(stmtSwitch)); + } + return ans; +} + // ---------- JBCStmtPesudoLabel ---------- void JBCStmtPesudoLabel::DumpImpl(const std::string &prefix) const { std::cout << prefix << "JBCStmtPesudoLabel (id=" << id << "," <<