diff --git a/src/bin/jbc2mpl b/src/bin/jbc2mpl index 66946f71fc674d93d5aea6d113b8ca6b66f860f1..3309209e0f66140a039bcca46b74e428b0973ad7 100755 Binary files a/src/bin/jbc2mpl and b/src/bin/jbc2mpl differ diff --git a/src/bin/maple b/src/bin/maple index 0196f1d4a9ea18cbbdfff01f862e4eb81e74c280..fe0b7350167db25ab374b7c642bb2ef021c2528d 100755 Binary files a/src/bin/maple and b/src/bin/maple differ diff --git a/src/bin/mplcg b/src/bin/mplcg index 7b8e15ecf34e23a4ede07285b934a84e8deda4fe..6eeb609cfd05874c67e43881fb41a24f27cb67b1 100755 Binary files a/src/bin/mplcg and b/src/bin/mplcg differ diff --git a/src/deplibs/libmplphase.a b/src/deplibs/libmplphase.a index f5f8dfae5c742484feb36f112ef19111e4d4d3f0..525212e9ac40830f0b684b514a6befc18befafb3 100644 Binary files a/src/deplibs/libmplphase.a and b/src/deplibs/libmplphase.a differ diff --git a/src/maple_ir/include/ir_safe_cast_traits.def b/src/maple_ir/include/ir_safe_cast_traits.def index 1360c6f1311d2002b2955ff74abd875e2d18f88d..44819a552801cb887e18df5c6bc1d28a178ddb08 100644 --- a/src/maple_ir/include/ir_safe_cast_traits.def +++ b/src/maple_ir/include/ir_safe_cast_traits.def @@ -17,52 +17,228 @@ namespace maple { #ifdef LOAD_SAFE_CAST_FOR_MIR_CONST #undef LOAD_SAFE_CAST_FOR_MIR_CONST -inline MIRConstKind safe_cast_traits(const MIRConst &mirConst) { - return mirConst.GetKind(); -}; - -template <> struct ExtractCode { - enum {value = kConstInt}; -}; - -template <> struct ExtractCode { - enum {value = kConstAddrof}; -}; - -template <> struct ExtractCode { - enum {value = kConstAddrofFunc}; -}; - -template <> struct ExtractCode { - enum {value = kConstLblConst}; -}; - -template <> struct ExtractCode { - enum {value = kConstStrConst}; -}; - -template <> struct ExtractCode { - enum {value = kConstStr16Const}; -}; - -template <> struct ExtractCode { - enum {value = kConstFloatConst}; -}; - -template <> struct ExtractCode { - enum {value = kConstDoubleConst}; -}; - -template <> struct ExtractCode { - enum {value = kConstFloat128Const}; -}; +REGISTER_SAFE_CAST(MIRIntConst, from.GetKind() == kConstInt); +REGISTER_SAFE_CAST(MIRAddrofConst, from.GetKind() == kConstAddrof); +REGISTER_SAFE_CAST(MIRAddroffuncConst, from.GetKind() == kConstAddrofFunc); +REGISTER_SAFE_CAST(MIRLblConst, from.GetKind() == kConstLblConst); +REGISTER_SAFE_CAST(MIRStrConst, from.GetKind() == kConstStrConst); +REGISTER_SAFE_CAST(MIRStr16Const, from.GetKind() == kConstStr16Const); +REGISTER_SAFE_CAST(MIRFloatConst, from.GetKind() == kConstFloatConst); +REGISTER_SAFE_CAST(MIRDoubleConst, from.GetKind() == kConstDoubleConst); +REGISTER_SAFE_CAST(MIRFloat128Const, from.GetKind() == kConstFloat128Const); +REGISTER_SAFE_CAST(MIRAggConst, from.GetKind() == kConstAggConst); +REGISTER_SAFE_CAST(MIRStConst, from.GetKind() == kConstStConst); +#endif -template <> struct ExtractCode { - enum {value = kConstAggConst}; -}; +#ifdef LOAD_SAFE_CAST_FOR_MIR_TYPE +#undef LOAD_SAFE_CAST_FOR_MIR_TYPE +REGISTER_SAFE_CAST(MIRPtrType, from.GetKind() == kTypePointer); +REGISTER_SAFE_CAST(MIRArrayType, from.GetKind() == kTypeArray); +REGISTER_SAFE_CAST(MIRFarrayType, from.GetKind() == kTypeFArray || + instance_of(from)); +REGISTER_SAFE_CAST(MIRStructType, from.GetKind() == kTypeStruct || + from.GetKind() == kTypeStructIncomplete || + from.GetKind() == kTypeUnion || + instance_of(from) || + instance_of(from)); +REGISTER_SAFE_CAST(MIRJarrayType, from.GetKind() == kTypeJArray); +REGISTER_SAFE_CAST(MIRClassType, from.GetKind() == kTypeClass || + from.GetKind() == kTypeClassIncomplete); +REGISTER_SAFE_CAST(MIRInterfaceType, from.GetKind() == kTypeInterface || + from.GetKind() == kTypeInterfaceIncomplete); +REGISTER_SAFE_CAST(MIRBitFieldType, from.GetKind() == kTypeBitField); +REGISTER_SAFE_CAST(MIRFuncType, from.GetKind() == kTypeFunction); +REGISTER_SAFE_CAST(MIRTypeByName, from.GetKind() == kTypeByName); +REGISTER_SAFE_CAST(MIRTypeParam, from.GetKind() == kTypeParam); +REGISTER_SAFE_CAST(MIRInstantVectorType, from.GetKind() == kTypeInstantVector); +REGISTER_SAFE_CAST(MIRGenericInstantType, from.GetKind() == kTypeGenericInstant); +#endif -template <> struct ExtractCode { - enum {value = kConstStConst}; -}; +#ifdef LOAD_SAFE_CAST_FOR_MIR_NODE +#undef LOAD_SAFE_CAST_FOR_MIR_NODE +REGISTER_SAFE_CAST(UnaryNode, from.GetOpCode() == OP_abs || + from.GetOpCode() == OP_bnot || + from.GetOpCode() == OP_lnot || + from.GetOpCode() == OP_neg || + from.GetOpCode() == OP_recip || + from.GetOpCode() == OP_sqrt || + from.GetOpCode() == OP_alloca || + from.GetOpCode() == OP_malloc || + instance_of(from) || + instance_of(from) || + instance_of(from) || + instance_of(from) || + instance_of(from)); +REGISTER_SAFE_CAST(TypeCvtNode, from.GetOpCode() == OP_ceil || + from.GetOpCode() == OP_cvt || + from.GetOpCode() == OP_floor || + from.GetOpCode() == OP_round || + from.GetOpCode() == OP_trunc || + instance_of(from)); +REGISTER_SAFE_CAST(RetypeNode, from.GetOpCode() == OP_retype); +REGISTER_SAFE_CAST(ExtractbitsNode, from.GetOpCode() == OP_extractbits || + from.GetOpCode() == OP_sext || + from.GetOpCode() == OP_zext); +REGISTER_SAFE_CAST(GCMallocNode, from.GetOpCode() == OP_gcmalloc || + from.GetOpCode() = OP_gcpermalloc); +REGISTER_SAFE_CAST(JarrayMallocNode, from.GetOpCode() == OP_gcmallocjarray || + from.GetOpCode() = OP_gcpermallocjarray); +REGISTER_SAFE_CAST(IreadNode, from.GetOpCode() == OP_iread || + from.GetOpCode() = OP_iaddrof); +REGISTER_SAFE_CAST(IreadoffNode, from.GetOpCode() == OP_ireadoff); +REGISTER_SAFE_CAST(IreadFPoffNode, from.GetOpCode() == OP_ireadfpoff); +REGISTER_SAFE_CAST(BinaryNode, from.GetOpCode() == OP_add || + from.GetOpCode() == OP_sub || + from.GetOpCode() == OP_mul || + from.GetOpCode() == OP_div || + from.GetOpCode() == OP_rem || + from.GetOpCode() == OP_ashr || + from.GetOpCode() == OP_lshr || + from.GetOpCode() == OP_shl || + from.GetOpCode() == OP_max || + from.GetOpCode() == OP_min || + from.GetOpCode() == OP_band || + from.GetOpCode() == OP_bior || + from.GetOpCode() == OP_bxor || + from.GetOpCode() == OP_CG_array_elem_add || + from.GetOpCode() == OP_land || + from.GetOpCode() == OP_lior || + from.GetOpCode() == OP_cand || + from.GetOpCode() == OP_cior || + instance_of(from) || + instance_of(from) || + instance_of(from)); +REGISTER_SAFE_CAST(CompareNode, from.GetOpCode() == OP_eq || + from.GetOpCode() = OP_ge || + from.GetOpCode() = OP_gt || + from.GetOpCode() = OP_le || + from.GetOpCode() = OP_lt || + from.GetOpCode() = OP_ne || + from.GetOpCode() = OP_cmp || + from.GetOpCode() = OP_cmpl || + from.GetOpCode() = OP_cmpg); +REGISTER_SAFE_CAST(DepositbitsNode, from.GetOpCode() == OP_depositbits); +REGISTER_SAFE_CAST(ResolveFuncNode, from.GetOpCode() == OP_resolveinterfacefunc || + from.GetOpCode() == OP_resolvevirtualfunc); +REGISTER_SAFE_CAST(TernaryNode, from.GetOpCode() == OP_select); +REGISTER_SAFE_CAST(NaryNode, instance_of(from) || + instance_of(from)); +REGISTER_SAFE_CAST(IntrinsicopNode, from.GetOpCode() == OP_intrinsicop || + from.GetOpCode() == OP_intrinsicopwithtype); +REGISTER_SAFE_CAST(ConstvalNode, from.GetOpCode() == OP_constval); +REGISTER_SAFE_CAST(ConststrNode, from.GetOpCode() == OP_conststr); +REGISTER_SAFE_CAST(Conststr16Node, from.GetOpCode() == OP_conststr16); +REGISTER_SAFE_CAST(SizeoftypeNode, from.GetOpCode() == OP_sizeoftype); +REGISTER_SAFE_CAST(FieldsDistNode, from.GetOpCode() == OP_fieldsdist); +REGISTER_SAFE_CAST(ArrayNode, from.GetOpCode() == OP_array); +REGISTER_SAFE_CAST(AddrofNode, from.GetOpCode() == OP_dread || + from.GetOpCode() == OP_addrof); +REGISTER_SAFE_CAST(RegreadNode, from.GetOpCode() == OP_regread); +REGISTER_SAFE_CAST(AddroffuncNode, from.GetOpCode() == OP_addroffunc); +REGISTER_SAFE_CAST(AddroflabelNode, from.GetOpCode() == OP_addroflabel); +REGISTER_SAFE_CAST(StmtNode, from.GetOpCode() == OP_finally || + from.GetOpCode() == OP_cleanuptry || + from.GetOpCode() == OP_endtry || + from.GetOpCode() == OP_retsub || + from.GetOpCode() == OP_membaracquire || + from.GetOpCode() == OP_membarrelease || + from.GetOpCode() == OP_membarstoreload || + from.GetOpCode() == OP_membarstorestore || + instance_of(from) || + instance_of(from) || + instance_of(from) || + instance_of(from) || + instance_of(from) || + instance_of(from) || + instance_of(from) || + instance_of(from) || + instance_of(from) || + instance_of(from) || + instance_of(from) || + instance_of(from) || + instance_of(from) || + instance_of(from)); +REGISTER_SAFE_CAST(IassignNode, from.GetOpCode() == OP_iassign); +REGISTER_SAFE_CAST(GotoNode, from.GetOpCode() == OP_goto || + from.GetOpCode() == OP_gosub); +REGISTER_SAFE_CAST(JsTryNode, from.GetOpCode() == OP_jstry); +REGISTER_SAFE_CAST(TryNode, from.GetOpCode() == OP_try); +REGISTER_SAFE_CAST(CatchNode, from.GetOpCode() == OP_catch); +REGISTER_SAFE_CAST(SwitchNode, from.GetOpCode() == OP_switch); +REGISTER_SAFE_CAST(MultiwayNode, from.GetOpCode() == OP_multiway); +REGISTER_SAFE_CAST(UnaryStmtNode, from.GetOpCode() == OP_eval || + from.GetOpCode() == OP_throw || + from.GetOpCode() == OP_free || + from.GetOpCode() == OP_decref || + from.GetOpCode() == OP_incref || + from.GetOpCode() == OP_decrefreset || + from.GetOpCode() == OP_assertnonnull || + instance_of(from) || + instance_of(from) || + instance_of(from) || + instance_of(from) || + instance_of(from) || + instance_of(from) || + instance_of(from)); +REGISTER_SAFE_CAST(DassignNode, from.GetOpCode() == OP_dassign || + from.GetOpCode() == OP_maydassign); +REGISTER_SAFE_CAST(RegassignNode, from.GetOpCode() == OP_regassign); +REGISTER_SAFE_CAST(CondGotoNode, from.GetOpCode() == OP_brtrue || + from.GetOpCode() == OP_brfalse); +REGISTER_SAFE_CAST(RangeGotoNode, from.GetOpCode() == OP_rangegoto); +REGISTER_SAFE_CAST(BlockNode, from.GetOpCode() == OP_block); +REGISTER_SAFE_CAST(IfStmtNode, from.GetOpCode() == OP_if); +REGISTER_SAFE_CAST(WhileStmtNode, from.GetOpCode() == OP_while || + from.GetOpCode() == OP_dowhile); +REGISTER_SAFE_CAST(DoloopNode, from.GetOpCode() == OP_doloop); +REGISTER_SAFE_CAST(ForeachelemNode, from.GetOpCode() == OP_foreachelem); +REGISTER_SAFE_CAST(BinaryStmtNode, from.GetOpCode() == OP_assertge || + from.GetOpCode() == OP_assertlt || + instance_of(from) || + instance_of(from)); +REGISTER_SAFE_CAST(IassignoffNode, from.GetOpCode() == OP_iassignoff); +REGISTER_SAFE_CAST(IassignFPoffNode, from.GetOpCode() == OP_iassignfpoff); +REGISTER_SAFE_CAST(NaryStmtNode, from.GetOpCode() == OP_return || + from.GetOpCode() == OP_syncenter || + from.GetOpCode() == OP_syncexit || + instance_of(from) || + instance_of(from) || + instance_of(from)); +REGISTER_SAFE_CAST(CallNode, from.GetOpCode() == OP_call || + from.GetOpCode() == OP_virtualcall || + from.GetOpCode() == OP_superclasscall || + from.GetOpCode() == OP_interfacecall || + from.GetOpCode() == OP_customcall || + from.GetOpCode() == OP_polymorphiccall || + from.GetOpCode() == OP_interfaceicall || + from.GetOpCode() == OP_virtualicall || + from.GetOpCode() == OP_callassigned || + from.GetOpCode() == OP_virtualcallassigned || + from.GetOpCode() == OP_superclasscallassigned || + from.GetOpCode() == OP_interfacecallassigned || + from.GetOpCode() == OP_customcallassigned || + from.GetOpCode() == OP_polymorphiccallassigned || + from.GetOpCode() == OP_interfaceicallassigned || + from.GetOpCode() == OP_virtualicallassigned || + instance_of(from)); +REGISTER_SAFE_CAST(IcallNode, from.GetOpCode() == OP_icall || + from.GetOpCode() == OP_icallassigned); +REGISTER_SAFE_CAST(IntrinsiccallNode, from.GetOpCode() == OP_intrinsiccall || + from.GetOpCode() == OP_intrinsiccallwithtype || + from.GetOpCode() == OP_xintrinsiccall || + from.GetOpCode() == OP_intrinsiccallassigned || + from.GetOpCode() == OP_intrinsiccallwithtypeassigned || + from.GetOpCode() == OP_xintrinsiccallassigned); +REGISTER_SAFE_CAST(CallinstantNode, from.GetOpCode() == OP_callinstant || + from.GetOpCode() == OP_virtualcallinstant || + from.GetOpCode() == OP_superclasscallinstant || + from.GetOpCode() == OP_interfacecallinstant || + from.GetOpCode() == OP_callinstantassigned || + from.GetOpCode() == OP_virtualcallinstantassigned || + from.GetOpCode() == OP_superclasscallinstantassigned || + from.GetOpCode() == OP_interfacecallinstantassigned); +REGISTER_SAFE_CAST(AssertStmtNode, false); +REGISTER_SAFE_CAST(LabelNode, from.GetOpCode() == OP_label); +REGISTER_SAFE_CAST(CommentNode, from.GetOpCode() == OP_comment); #endif } diff --git a/src/maple_ir/include/mir_config.h b/src/maple_ir/include/mir_config.h index 2c3a2e7cd2c251448edb2350d2b64e7ff5b0089b..d3d1463af41f91bf3336f39b66f7a949c4606fbf 100644 --- a/src/maple_ir/include/mir_config.h +++ b/src/maple_ir/include/mir_config.h @@ -39,7 +39,6 @@ do { \ } while (0) #define MIR_CAST_TO(var, totype) ((totype)(var)) -#define MIR_DYN_CAST(var, totype) ((totype)(var)) #include #if DEBUG #include @@ -81,7 +80,6 @@ namespace maple { #define MIR_PRINTF(...) printf(__VA_ARGS__) #define MIR_INFO(...) printf(__VA_ARGS__) #define MIR_CAST_TO(var, totype) static_cast(var) -#define MIR_DYN_CAST(var, totype) dynamic_cast(var) #endif // !MIR_FEATURE_FULL // MIR specific configurations. diff --git a/src/maple_ir/include/mir_const.h b/src/maple_ir/include/mir_const.h index 5edc57b15da5ebfa0050c60e27b24e5913160034..c56fbc2f5b148c6117d542e128ac2b317d1ec987 100644 --- a/src/maple_ir/include/mir_const.h +++ b/src/maple_ir/include/mir_const.h @@ -531,6 +531,8 @@ class MIRStConst : public MIRConst { }; #endif // MIR_FEATURE_FULL } // namespace maple + #define LOAD_SAFE_CAST_FOR_MIR_CONST #include "ir_safe_cast_traits.def" + #endif // MAPLE_IR_INCLUDE_MIR_CONST_H diff --git a/src/maple_ir/include/mir_nodes.h b/src/maple_ir/include/mir_nodes.h index 02d7a07f090246e9020b8fe1dccf06dfd1e9be1c..4e0d7aa7fbbb4650df3efaa6d272835b28d7abfc 100644 --- a/src/maple_ir/include/mir_nodes.h +++ b/src/maple_ir/include/mir_nodes.h @@ -3116,4 +3116,8 @@ class CommentNode : public StmtNode { void DumpCallReturns(const MIRModule &mod, CallReturnVector nrets, int32 indent); } // namespace maple + +#define LOAD_SAFE_CAST_FOR_MIR_NODE +#include "ir_safe_cast_traits.def" + #endif // MAPLE_IR_INCLUDE_MIR_NODES_H diff --git a/src/maple_ir/include/mir_type.h b/src/maple_ir/include/mir_type.h index a9d25a783ffa51a42d9c937fdfcdd6c567ef8862..de990fa021940a092b3b4f91fba77f55e166555f 100644 --- a/src/maple_ir/include/mir_type.h +++ b/src/maple_ir/include/mir_type.h @@ -19,6 +19,7 @@ #include "prim_types.h" #include "mir_pragma.h" #include "mpl_logging.h" +#include "safe_cast.h" #if MIR_FEATURE_FULL #include "mempool.h" #include "mempool_allocator.h" @@ -1579,4 +1580,8 @@ class MIRGenericInstantType : public MIRInstantVectorType { }; #endif // MIR_FEATURE_FULL } // namespace maple + +#define LOAD_SAFE_CAST_FOR_MIR_TYPE +#include "ir_safe_cast_traits.def" + #endif // MAPLE_IR_INCLUDE_MIR_TYPE_H diff --git a/src/maple_ir/src/mir_type.cpp b/src/maple_ir/src/mir_type.cpp index c05e070f03fa1d4a5ff8dd3b27c5f39e7af58810..168a6a26586b9700f1d8d0834a432cc82fcc3ab8 100644 --- a/src/maple_ir/src/mir_type.cpp +++ b/src/maple_ir/src/mir_type.cpp @@ -631,8 +631,7 @@ FieldID MIRClassType::GetFirstLocalFieldID() const { constexpr uint8 lastFieldIDOffset = 2; constexpr uint8 firstLocalFieldIDOffset = 1; const auto *parentClassType = - MIR_DYN_CAST(GlobalTables::GetTypeTable().GetTypeFromTyIdx(parentTyIdx), const MIRClassType*); - CHECK_FATAL(parentClassType != nullptr, "null pointer check"); + static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(parentTyIdx)); return !parentClassType->IsLocal() ? parentClassType->GetLastFieldID() + lastFieldIDOffset : parentClassType->GetFirstLocalFieldID() + firstLocalFieldIDOffset; } @@ -665,7 +664,7 @@ FieldID MIRClassType::GetLastFieldID() const { FieldID fieldID = fields.size(); if (parentTyIdx != 0) { const auto *parentClassType = - MIR_DYN_CAST(GlobalTables::GetTypeTable().GetTypeFromTyIdx(parentTyIdx), const MIRClassType*); + static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(parentTyIdx)); if (parentClassType != nullptr) { fieldID += parentClassType->GetLastFieldID() + 1; } @@ -1369,7 +1368,8 @@ bool MIRInterfaceType::HasTypeParam() const { FieldPair MIRClassType::TraverseToFieldRef(FieldID &fieldID) const { if (parentTyIdx != 0) { - auto *parentClassType = MIR_DYN_CAST(GlobalTables::GetTypeTable().GetTypeFromTyIdx(parentTyIdx), MIRClassType*); + auto *parentClassType = + static_cast(GlobalTables::GetTypeTable().GetTypeFromTyIdx(parentTyIdx)); if (parentClassType != nullptr) { --fieldID; const FieldPair &curPair = parentClassType->TraverseToFieldRef(fieldID); diff --git a/src/maple_me/include/me_safe_cast_traits.def b/src/maple_me/include/me_safe_cast_traits.def index 06a84154cb1f2ccde62f99760a6c354df43d505e..c58785dedc8b7cc351f26008b370984e0cf6e950 100644 --- a/src/maple_me/include/me_safe_cast_traits.def +++ b/src/maple_me/include/me_safe_cast_traits.def @@ -17,43 +17,83 @@ namespace maple { #ifdef LOAD_SAFE_CAST_FOR_ME_EXPR #undef LOAD_SAFE_CAST_FOR_ME_EXPR -inline MeExprOp safe_cast_traits(const MeExpr &expr) { - return expr.GetMeOp(); -}; - -template <> struct ExtractCode { - enum {value = kMeOpVar}; -}; - -template <> struct ExtractCode { - enum {value = kMeOpOp}; -}; - -template <> struct ExtractCode { - enum {value = kMeOpNary}; -}; - -template <> struct ExtractCode { - enum {value = kMeOpIvar}; -}; +REGISTER_SAFE_CAST(VarMeExpr, from.GetMeOp() == kMeOpVar); +REGISTER_SAFE_CAST(RegMeExpr, from.GetMeOp() == kMeOpReg); +REGISTER_SAFE_CAST(ConstMeExpr, from.GetMeOp() == kMeOpConst); +REGISTER_SAFE_CAST(ConststrMeExpr, from.GetMeOp() == kMeOpConststr); +REGISTER_SAFE_CAST(Conststr16MeExpr, from.GetMeOp() == kMeOpConststr16); +REGISTER_SAFE_CAST(SizeoftypeMeExpr, from.GetMeOp() == kMeOpSizeoftype); +REGISTER_SAFE_CAST(FieldsDistMeExpr, from.GetMeOp() == kMeOpFieldsDist); +REGISTER_SAFE_CAST(AddrofMeExpr, from.GetMeOp() == kMeOpAddrof); +REGISTER_SAFE_CAST(AddroffuncMeExpr, from.GetMeOp() == kMeOpAddroffunc); +REGISTER_SAFE_CAST(GcmallocMeExpr, from.GetMeOp() == kMeOpGcmalloc); +REGISTER_SAFE_CAST(OpMeExpr, from.GetMeOp() == kMeOpOp); +REGISTER_SAFE_CAST(IvarMeExpr, from.GetMeOp() == kMeOpIvar); +REGISTER_SAFE_CAST(NaryMeExpr, from.GetMeOp() == kMeOpNary); #endif #ifdef LOAD_SAFE_CAST_FOR_ME_STMT #undef LOAD_SAFE_CAST_FOR_ME_STMT -inline Opcode safe_cast_traits(const MeStmt &stmt) { - return stmt.GetOp(); -} - -template <> struct ExtractCode { - enum {value = OP_dassign}; -}; - -template <> struct ExtractCode { - enum {value = OP_maydassign}; -}; - -template <> struct ExtractCode { - enum {value = OP_iassign}; -}; +REGISTER_SAFE_CAST(PaiassignMeStmt, from.GetOp() == OP_paiassign); +REGISTER_SAFE_CAST(DassignMeStmt, from.GetOp() == OP_dassign); +REGISTER_SAFE_CAST(RegassignMeStmt, from.GetOp() == OP_regassign); +REGISTER_SAFE_CAST(MaydassignMeStmt, from.GetOp() == OP_maydassign); +REGISTER_SAFE_CAST(IassignMeStmt, from.GetOp() == OP_iassign); +REGISTER_SAFE_CAST(NaryMeStmt, instance_of(from) || + instance_of(from) || + instance_of(from) || + instance_of(from) || + instance_of(from)); +REGISTER_SAFE_CAST(CallMeStmt, from.GetOp() == OP_call || + from.GetOp() == OP_virtualcall || + from.GetOp() == OP_superclasscall || + from.GetOp() == OP_interfacecall || + from.GetOp() == OP_customcall || + from.GetOp() == OP_polymorphiccall || + from.GetOp() == OP_interfaceicall || + from.GetOp() == OP_virtualicall || + from.GetOp() == OP_callassigned || + from.GetOp() == OP_virtualcallassigned || + from.GetOp() == OP_superclasscallassigned || + from.GetOp() == OP_interfacecallassigned || + from.GetOp() == OP_customcallassigned || + from.GetOp() == OP_polymorphiccallassigned || + from.GetOp() == OP_interfaceicallassigned || + from.GetOp() == OP_virtualicallassigned); +REGISTER_SAFE_CAST(IcallMeStmt, from.GetOp() == OP_icall || + from.GetOp() == OP_icallassigned); +REGISTER_SAFE_CAST(IntrinsiccallMeStmt, from.GetOp() == OP_intrinsiccall || + from.GetOp() == OP_intrinsiccallwithtype || + from.GetOp() == OP_xintrinsiccall || + from.GetOp() == OP_intrinsiccallassigned || + from.GetOp() == OP_intrinsiccallwithtypeassigned || + from.GetOp() == OP_xintrinsiccallassigned); +REGISTER_SAFE_CAST(RetMeStmt, from.GetOp() == OP_return); +REGISTER_SAFE_CAST(UnaryMeStmt, instance_of(from) || + instance_of(from) || + instance_of(from) || + from.GetOp() == OP_eval || + from.GetOp() == OP_free || + from.GetOp() == OP_assertnonnull || + from.GetOp() == OP_incref || + from.GetOp() == OP_decref || + from.GetOp() == OP_decrefreset); +REGISTER_SAFE_CAST(GotoMeStmt, from.GetOp() == OP_goto); +REGISTER_SAFE_CAST(CondGotoMeStmt, from.GetOp() == OP_brtrue || + from.GetOp() == OP_brfalse); +REGISTER_SAFE_CAST(JsTryMeStmt, from.GetOp() == OP_jstry); +REGISTER_SAFE_CAST(TryMeStmt, from.GetOp() == OP_try); +REGISTER_SAFE_CAST(CatchMeStmt, from.GetOp() == OP_catch); +REGISTER_SAFE_CAST(SwitchMeStmt, from.GetOp() == OP_switch); +REGISTER_SAFE_CAST(CommentMeStmt, from.GetOp() == OP_comment); +REGISTER_SAFE_CAST(WithMuMeStmt, instance_of(from) || + instance_of(from) || + from.GetOp() == OP_retsub); +REGISTER_SAFE_CAST(GosubMeStmt, from.GetOp() == OP_gosub); +REGISTER_SAFE_CAST(ThrowMeStmt, from.GetOp() == OP_throw); +REGISTER_SAFE_CAST(SyncMeStmt, from.GetOp() == OP_syncenter || + from.GetOp() == OP_syncexit); +REGISTER_SAFE_CAST(AssertMeStmt, from.GetOp() == OP_assertge || + from.GetOp() == OP_assertlt); #endif } diff --git a/src/maple_me/src/me_rc_lowering.cpp b/src/maple_me/src/me_rc_lowering.cpp index ff94ccb0042945501d6ccf997b06777b13113cc5..8437b1aeb547f4d61ea18083d204513fbb3eb9f0 100644 --- a/src/maple_me/src/me_rc_lowering.cpp +++ b/src/maple_me/src/me_rc_lowering.cpp @@ -250,7 +250,7 @@ void RCLowering::HandleRetOfCallAssignedMeStmt(MeStmt &stmt, MeExpr &pendingDec) RegassignMeStmt *backup = irMap.CreateRegassignMeStmt(*irMap.CreateRegMeExpr(PTY_ref), pendingDec, *bb); std::vector opnds = { backup->GetRegLHS() }; IntrinsiccallMeStmt *decRefCall = CreateRCIntrinsic(INTRN_MCCDecRef, stmt, opnds); - if (!dynamic_cast(&stmt)) { + if (!instance_of(stmt)) { bb->InsertMeStmtBefore(&stmt, backup); bb->InsertMeStmtAfter(&stmt, decRefCall); } else { @@ -395,9 +395,8 @@ bool RCLowering::IsInitialized(IvarMeExpr &ivar) { return true; } MIRType *baseType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ivar.GetTyIdx()); - ASSERT(baseType->IsMIRPtrType(), "unexpect type"); - auto *ptype = static_cast(baseType)->GetPointedType(); - auto *classType = dynamic_cast(ptype); + auto *ptype = utils::ToRef(safe_cast(baseType)).GetPointedType(); + auto *classType = safe_cast(ptype); return classType == nullptr || !classType->IsOwnField(fieldID); } @@ -406,9 +405,8 @@ void RCLowering::HandleAssignMeStmtIvarLHS(MeStmt &stmt) { IvarMeExpr *lhsInner = iassign.GetLHSVal(); FieldID fieldID = lhsInner->GetFieldID(); MIRType *baseType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(lhsInner->GetTyIdx()); - ASSERT(baseType->IsMIRPtrType(), "unexpect type"); - auto *ptype = static_cast(baseType)->GetPointedType(); - auto *classType = dynamic_cast(ptype); + auto *ptype = utils::ToRef(safe_cast(baseType)).GetPointedType(); + auto *classType = safe_cast(ptype); // skip RC operation if the field is unowned if (classType != nullptr && classType->IsFieldRCUnownedRef(fieldID)) { return; diff --git a/src/maple_util/include/safe_cast.h b/src/maple_util/include/safe_cast.h index c17bfd4fabc8025501a3826ce8ed6b71274c4d28..ff13ff68bd74ed3f40e7902347549157a4c311e3 100644 --- a/src/maple_util/include/safe_cast.h +++ b/src/maple_util/include/safe_cast.h @@ -14,46 +14,76 @@ */ #ifndef MAPLE_UTIL_INCLUDE_SAFE_CAST_H #define MAPLE_UTIL_INCLUDE_SAFE_CAST_H +#include "utils/meta.h" namespace maple { -template -struct ExtractCode { +template +struct safe_cast_condition : std::false_type {}; + +#define REGISTER_SAFE_CAST(type, condition) \ +template <> \ +struct safe_cast_condition : std::true_type { \ + template \ + static inline bool DoIt(FromT &from) { \ + return (condition); \ + } \ +} + +namespace __impl { +template ::value>> +struct instance_of_impl { + static inline bool DoIt(FromT &from) { + return (safe_cast_condition::DoIt(from)); + } +}; + +template +struct instance_of_impl::value>> { + static inline bool DoIt(FromT&) { + return true; + } }; -template::value>> -inline bool instance_of(T &base) { - return safe_cast_traits(base) == ExtractCode::value; +template +struct enabled_safe_cast : + std::conditional_t, safe_cast_condition>::value, + std::true_type, + std::false_type> {}; } -template::value>> -inline bool instance_of(T *base) { - return (base != nullptr && instance_of(*base)); +template ::value>> +inline bool instance_of(FromT &from) { + return __impl::instance_of_impl::DoIt(from); } -template::value || std::is_const>::value, - std::add_pointer_t>>, - std::add_pointer_t>>, - typename = std::enable_if_t::value>> -inline RetT safe_cast(T &base) { - return (safe_cast_traits(base) == ExtractCode::value ? static_cast(&base) : nullptr); +template ::value>> +inline bool instance_of(FromT *from) { + return (from != nullptr && instance_of(*from)); } -template::value || std::is_const>::value, - std::add_pointer_t>>, - std::add_pointer_t>>, - typename = std::enable_if_t::value>> -inline RetT safe_cast(T *base) { - return ((base != nullptr && safe_cast_traits(*base) == ExtractCode::value) ? - static_cast(base) : nullptr); + std::is_const::value || std::is_const>::value, + std::add_pointer_t>>, + std::add_pointer_t>>, + typename = std::enable_if_t<__impl::enabled_safe_cast::value>> +inline RetT safe_cast(FromT &from) { + return (instance_of(from) ? static_cast(&from) : nullptr); } +template ::value || std::is_const>::value, + std::add_pointer_t>>, + std::add_pointer_t>>, + typename = std::enable_if_t<__impl::enabled_safe_cast::value>> +inline RetT safe_cast(FromT *from) { + return (instance_of(from) ? static_cast(from) : nullptr); } +} #endif //MAPLE_UTIL_INCLUDE_SAFE_CAST_H diff --git a/src/mpl2mpl/src/gen_check_cast.cpp b/src/mpl2mpl/src/gen_check_cast.cpp index 96acefa6d072ac4e6f9683e292e9870fe975d738..215264a85866c493bb93462b9012c8eb1e29195b 100644 --- a/src/mpl2mpl/src/gen_check_cast.cpp +++ b/src/mpl2mpl/src/gen_check_cast.cpp @@ -42,7 +42,9 @@ CheckCastGenerator::CheckCastGenerator(MIRModule *mod, KlassHierarchy *kh, bool void CheckCastGenerator::InitTypes() { - pointerObjType = GlobalTables::GetTypeTable().GetOrCreatePointerType(*WKTypes::Util::GetJavaLangObjectType()); + const MIRType *javaLangObjectType = WKTypes::Util::GetJavaLangObjectType(); + CHECK_FATAL(javaLangObjectType != nullptr, "The pointerObjType in InitTypes is null!"); + pointerObjType = GlobalTables::GetTypeTable().GetOrCreatePointerType(*javaLangObjectType); classinfoType = GlobalTables::GetTypeTable().GetOrCreateClassType(NameMangler::kClassMetadataTypeName, GetMIRModule()); pointerClassMetaType = GlobalTables::GetTypeTable().GetOrCreatePointerType(*classinfoType);