diff --git a/src/mplfe/common/include/fe_configs.h b/src/mplfe/common/include/fe_configs.h index efcd2a4662c9cff8f99410aca998ae390ad00c54..44612e4eb83874f636b03f066ed104240562565a 100644 --- a/src/mplfe/common/include/fe_configs.h +++ b/src/mplfe/common/include/fe_configs.h @@ -14,6 +14,7 @@ */ #ifndef MPLFE_INCLUDE_COMMON_FE_CONFIGS_H #define MPLFE_INCLUDE_COMMON_FE_CONFIGS_H +#include "types_def.h" #if ENABLE_COV_CHECK == 1 #define LLT_MOCK_TARGET virtual @@ -29,5 +30,14 @@ #define LLT_PRIVATE private #endif +namespace maple { +using TypeDim = uint8; + +class FEConstants { + public: + const static uint8 kDimMax = UINT8_MAX; +}; // class FEContants +} // namespace maple + #include "fe_config_parallel.h" #endif // MPLFE_INCLUDE_COMMON_FE_CONFIGS_H \ No newline at end of file diff --git a/src/mplfe/common/include/fe_struct_elem_info.h b/src/mplfe/common/include/fe_struct_elem_info.h index 53956c5e0047fbf9c271838ebb0530877efa55a2..0da49057bbfe91baa6d31c1962112e510b0c5fc0 100644 --- a/src/mplfe/common/include/fe_struct_elem_info.h +++ b/src/mplfe/common/include/fe_struct_elem_info.h @@ -15,6 +15,7 @@ #ifndef MPLFE_INCLUDE_COMMON_FE_STRUCT_ELEM_INFO_H #define MPLFE_INCLUDE_COMMON_FE_STRUCT_ELEM_INFO_H #include +#include #include "global_tables.h" #include "fe_configs.h" #include "feir_type.h" @@ -143,6 +144,22 @@ class FEStructMethodInfo : public FEStructElemInfo { return isReturnVoid; } + bool IsJavaPolymorphicCall() const { + return isJavaPolymorphicCall; + } + + bool IsJavaDynamicCall() const { + return isJavaDynamicCall; + } + + void SetJavaDyamicCall() { + isJavaDynamicCall = true; + } + + void UnsetJavaDynamicCall() { + isJavaDynamicCall = false; + } + const UniqueFEIRType &GetReturnType() const { return retType; } @@ -155,6 +172,8 @@ class FEStructMethodInfo : public FEStructElemInfo { return argTypes; } + static std::map> InitJavaPolymorphicWhiteList(); + LLT_PROTECTED: void PrepareImpl(MIRBuilder &mirBuilder, bool argIsStatic) override; @@ -165,7 +184,9 @@ class FEStructMethodInfo : public FEStructElemInfo { void PrepareImplJava(MIRBuilder &mirBuilder, bool argIsStatic); bool SearchStructMethodJava(MIRStructType &structType, MIRBuilder &mirBuilder, bool argIsStatic, bool allowPrivate = true); + bool SearchStructMethodJavaInParent(MIRStructType &structType, MIRBuilder &mirBuilder, bool argIsStatic); bool SearchStructMethodJava(const TyIdx &tyIdx, MIRBuilder &mirBuilder, bool argIsStatic, bool allowPrivate = true); + bool CheckJavaPolymorphicCall() const; std::vector argTypes; UniqueFEIRType retType; UniqueFEIRType ownerType; @@ -173,6 +194,9 @@ class FEStructMethodInfo : public FEStructElemInfo { MIRFunction *mirFunc; bool isReturnVoid; bool isConstructor; + bool isJavaPolymorphicCall; + bool isJavaDynamicCall; + static std::map> javaPolymorphicWhiteList; }; } // namespace maple #endif // MPLFE_INCLUDE_COMMON_FE_STRUCT_ELEM_INFO_H diff --git a/src/mplfe/common/include/fe_type_manager.h b/src/mplfe/common/include/fe_type_manager.h index ae6973b621520e963c5c41fc3c35a72cc255afc0..49dc0dc856bf50551de1df364d1f879a80d999aa 100644 --- a/src/mplfe/common/include/fe_type_manager.h +++ b/src/mplfe/common/include/fe_type_manager.h @@ -127,9 +127,9 @@ class FETypeManager { MIRStructType *GetStructTypeFromName(const std::string &name); MIRStructType *GetStructTypeFromName(const GStrIdx &nameIdx); MIRType *GetOrCreateTypeFromName(const std::string &name, FETypeFlag typeFlag, bool usePtr); - MIRType *GetOrCreatePointerType(const MIRType &type); - MIRType *GetOrCreateArrayType(MIRType &elemType, uint8 dim); - MIRType *GetOrCreateJArrayType(MIRType &elemType, uint8 dim); + MIRType *GetOrCreatePointerType(const MIRType &type, PrimType ptyPtr = PTY_ref); + MIRType *GetOrCreateArrayType(MIRType &elemType, uint8 dim, PrimType ptyPtr = PTY_ref); + MIRType *GetOrCreateJArrayType(MIRType &elemType, uint8 dim, PrimType ptyPtr = PTY_ref); void AddClassToModule(const MIRStructType &structType); // ---------- methods for StructElemInfo ---------- diff --git a/src/mplfe/common/include/feir_stmt.h b/src/mplfe/common/include/feir_stmt.h index 534ea763fa4704465ed4e71b743d091435f1f9c7..7bf0f6bb05cffd4898ab2995e2364cff68d16860 100644 --- a/src/mplfe/common/include/feir_stmt.h +++ b/src/mplfe/common/include/feir_stmt.h @@ -46,7 +46,7 @@ enum FEIRNodeKind : uint8 { kStmtJavaConstString, kStmtJavaMultiANewArray, kStmtCallAssign, - kStmtIntrinsicCallAssign, + kStmtJavaDynamicCallAssign, kStmtIAssign, kStmtUseOnly, kStmtReturn, @@ -934,13 +934,13 @@ class FEIRStmtCallAssign : public FEIRStmtAssign { protected: std::list GenMIRStmtsImpl(MIRBuilder &mirBuilder) const override; + std::list GenMIRStmtsUseZeroReturn(MIRBuilder &mirBuilder) const; private: Opcode AdjustMIROp() const; FEStructMethodInfo &methodInfo; Opcode mirOp; - UniqueFEIRVar varRet; bool isStatic; std::list exprArgs; static std::map mapOpAssignToOp; diff --git a/src/mplfe/common/include/feir_type.h b/src/mplfe/common/include/feir_type.h index f8f1ef39c36dc0e17594aa721c3a10bed41f3162..612e960ec0a689f16c6951381ae2e58203fa0085 100644 --- a/src/mplfe/common/include/feir_type.h +++ b/src/mplfe/common/include/feir_type.h @@ -14,12 +14,14 @@ */ #ifndef MPLFE_INCLUDE_FEIR_TYPE_H #define MPLFE_INCLUDE_FEIR_TYPE_H -#include #include +#include +#include #include "prim_types.h" #include "types_def.h" #include "mir_type.h" #include "global_tables.h" +#include "fe_configs.h" namespace maple { enum FEIRTypeKind { @@ -30,11 +32,10 @@ enum FEIRTypeKind { class FEIRType { public: - const static uint8 kDimMax = 255; explicit FEIRType(FEIRTypeKind argKind); - FEIRType(FEIRTypeKind argKind, PrimType argPrimType); virtual ~FEIRType() = default; static std::unique_ptr NewType(FEIRTypeKind argKind = kFEIRTypeDefault); + static std::map> InitLangConfig(); MIRType *GenerateMIRTypeAuto(MIRSrcLang srcLang) const; bool IsSameKind(const FEIRType &type) const { return kind == type.kind; @@ -45,15 +46,11 @@ class FEIRType { } PrimType GetPrimType() const { - return primType; - } - - PrimType GetRealPrimType() const { - return IsScalar() ? primType : PTY_ref; + return GetPrimTypeImpl(); } - void SetPrimType(PrimType argPrimType) { - primType = argPrimType; + void SetPrimType(PrimType pt) { + SetPrimTypeImpl(pt); } bool IsZero() const { @@ -73,34 +70,46 @@ class FEIRType { } MIRType *GenerateMIRType(MIRSrcLang srcLang, bool usePtr) const { - return GenerateMIRTypeImpl(srcLang, usePtr); - } - - MIRType *GenerateMIRType(bool usePtr) const { - return GenerateMIRTypeImpl(usePtr); + return GenerateMIRType(usePtr); } MIRType *GenerateMIRType() const { - return GenerateMIRTypeImpl(); + return GenerateMIRType(false); } bool IsPreciseRefType() const { - return IsPreciseRefTypeImpl(); - } - - bool IsPreciseType() const { - return IsPreciseTypeImpl(); + return IsPrecise() && IsRef(); } bool IsScalar() const { return IsScalarImpl(); } - uint8 ArrayIncrDim(uint8 delta = 1) { + bool IsRef() const { + return IsRefImpl(); + } + + bool IsArray() const { + return IsArrayImpl(); + } + + bool IsPrecise() const { + return IsPreciseImpl(); + } + + bool IsValid() const { + return IsValidImpl(); + } + + MIRType *GenerateMIRType(bool usePtr, PrimType ptyPtr = PTY_ref) const { + return GenerateMIRTypeImpl(usePtr, ptyPtr); + } + + TypeDim ArrayIncrDim(TypeDim delta = 1) { return ArrayIncrDimImpl(delta); } - uint8 ArrayDecrDim(uint8 delta = 1) { + TypeDim ArrayDecrDim(TypeDim delta = 1) { return ArrayDecrDimImpl(delta); } @@ -116,24 +125,27 @@ class FEIRType { return HashImpl(); } + static std::map> langConfig; + protected: virtual void CopyFromImpl(const FEIRType &type); virtual std::unique_ptr CloneImpl() const = 0; - virtual MIRType *GenerateMIRTypeImpl(MIRSrcLang srcLang, bool usePtr) const = 0; - virtual MIRType *GenerateMIRTypeImpl(bool usePtr) const = 0; - virtual MIRType *GenerateMIRTypeImpl() const = 0; - virtual bool IsPreciseRefTypeImpl() const = 0; - virtual bool IsPreciseTypeImpl() const = 0; + virtual MIRType *GenerateMIRTypeImpl(bool usePtr, PrimType ptyPtr) const = 0; virtual bool IsScalarImpl() const = 0; - virtual uint8 ArrayIncrDimImpl(uint8 delta) = 0; - virtual uint8 ArrayDecrDimImpl(uint8 delta) = 0; + virtual TypeDim ArrayIncrDimImpl(TypeDim delta) = 0; + virtual TypeDim ArrayDecrDimImpl(TypeDim delta) = 0; virtual bool IsEqualToImpl(const std::unique_ptr &argType) const; virtual bool IsEqualToImpl(const FEIRType &argType) const; virtual size_t HashImpl() const = 0; + virtual PrimType GetPrimTypeImpl() const = 0; + virtual void SetPrimTypeImpl(PrimType pt) = 0; + virtual bool IsRefImpl() const = 0; + virtual bool IsArrayImpl() const = 0; + virtual bool IsPreciseImpl() const = 0; + virtual bool IsValidImpl() const = 0; FEIRTypeKind kind : 7; bool isZero : 1; - PrimType primType; }; // class FEIRType using UniqueFEIRType = std::unique_ptr; @@ -143,7 +155,7 @@ class FEIRTypeDefault : public FEIRType { FEIRTypeDefault(); explicit FEIRTypeDefault(PrimType argPrimType); FEIRTypeDefault(PrimType argPrimType, const GStrIdx &argTypeNameIdx); - FEIRTypeDefault(PrimType argPrimType, const GStrIdx &argTypeNameIdx, uint8 argDim); + FEIRTypeDefault(PrimType argPrimType, const GStrIdx &argTypeNameIdx, TypeDim argDim); ~FEIRTypeDefault() = default; FEIRTypeDefault(const FEIRTypeDefault&) = delete; FEIRTypeDefault &operator=(const FEIRTypeDefault&) = delete; @@ -169,52 +181,76 @@ class FEIRTypeDefault : public FEIRType { return typeNameIdx; } - uint8 GetDim() const { + TypeDim GetDim() const { return dim; } - FEIRTypeDefault &SetDim(uint8 argDim) { + FEIRTypeDefault &SetDim(TypeDim argDim) { dim = argDim; return *this; } - protected: + LLT_PROTECTED: void CopyFromImpl(const FEIRType &type) override; std::unique_ptr CloneImpl() const override; - MIRType *GenerateMIRTypeImpl(MIRSrcLang srcLang, bool usePtr) const override; - MIRType *GenerateMIRTypeImpl(bool usePtr) const override; - MIRType *GenerateMIRTypeImpl() const override; - uint8 ArrayIncrDimImpl(uint8 delta) override; - uint8 ArrayDecrDimImpl(uint8 delta) override; + MIRType *GenerateMIRTypeImpl(bool usePtr, PrimType ptyPtr) const override; + TypeDim ArrayIncrDimImpl(TypeDim delta) override; + TypeDim ArrayDecrDimImpl(TypeDim delta) override; bool IsEqualToImpl(const FEIRType &argType) const override; + bool IsEqualToImpl(const std::unique_ptr &argType) const override; size_t HashImpl() const override; - bool IsPreciseRefTypeImpl() const override; - bool IsPreciseTypeImpl() const override; bool IsScalarImpl() const override; + PrimType GetPrimTypeImpl() const override; + void SetPrimTypeImpl(PrimType pt) override; MIRType *GenerateMIRTypeInternal(const GStrIdx &argTypeNameIdx, bool usePtr) const; + MIRType *GenerateMIRTypeInternal(const GStrIdx &argTypeNameIdx, bool usePtr, PrimType ptyPtr) const; + bool IsRefImpl() const override { + return dim > 0 || !IsScalarPrimType(primType); + } + + bool IsArrayImpl() const override { + return dim > 0; + } + + bool IsPreciseImpl() const override { + return IsScalarPrimType(primType) || typeNameIdx != 0; + } + + bool IsValidImpl() const override { + return !IsScalarPrimType(primType) || typeNameIdx == 0; + } + + static bool IsScalarPrimType(PrimType pty) { + return pty != PTY_ref && (IsPrimitiveInteger(pty) || IsPrimitiveFloat(pty) || IsAddress(pty) || pty == PTY_void); + } + + PrimType primType; GStrIdx typeNameIdx; - uint8 dim; + TypeDim dim; }; // ---------- FEIRTypeByName ---------- class FEIRTypeByName : public FEIRTypeDefault { public: - FEIRTypeByName(PrimType argPrimType, const std::string &argTypeName, uint8 argDim = 0); + FEIRTypeByName(PrimType argPrimType, const std::string &argTypeName, TypeDim argDim = 0); ~FEIRTypeByName() = default; FEIRTypeByName(const FEIRTypeByName&) = delete; FEIRTypeByName &operator=(const FEIRTypeByName&) = delete; protected: std::unique_ptr CloneImpl() const override; - MIRType *GenerateMIRTypeImpl(MIRSrcLang srcLang, bool usePtr) const override; - MIRType *GenerateMIRTypeImpl(bool usePtr) const override; - MIRType *GenerateMIRTypeImpl() const override; + MIRType *GenerateMIRTypeImpl(bool usePtr, PrimType ptyPtr) const override; bool IsEqualToImpl(const FEIRType &argType) const override; size_t HashImpl() const override; - bool IsPreciseRefTypeImpl() const override; - bool IsPreciseTypeImpl() const override; bool IsScalarImpl() const override; + bool IsPreciseImpl() const override { + return IsScalarPrimType(primType) || !typeName.empty(); + } + + bool IsValidImpl() const override { + return !IsScalarPrimType(primType) || typeName.empty(); + } private: std::string typeName; @@ -223,7 +259,7 @@ class FEIRTypeByName : public FEIRTypeDefault { // ---------- FEIRTypePointer ---------- class FEIRTypePointer : public FEIRType { public: - explicit FEIRTypePointer(std::unique_ptr argBaseType, PrimType argPrimType = PTY_ptr); + explicit FEIRTypePointer(std::unique_ptr argBaseType, PrimType argPrimType = PTY_ref); ~FEIRTypePointer() = default; FEIRTypePointer(const FEIRTypePointer&) = delete; FEIRTypePointer &operator=(const FEIRTypePointer&) = delete; @@ -238,18 +274,32 @@ class FEIRTypePointer : public FEIRType { protected: std::unique_ptr CloneImpl() const override; - MIRType *GenerateMIRTypeImpl(MIRSrcLang srcLang, bool usePtr) const override; - MIRType *GenerateMIRTypeImpl(bool usePtr) const override; - MIRType *GenerateMIRTypeImpl() const override; + MIRType *GenerateMIRTypeImpl(bool usePtr, PrimType ptyPtr) const override; bool IsEqualToImpl(const FEIRType &argType) const override; size_t HashImpl() const override; - bool IsPreciseRefTypeImpl() const override; - bool IsPreciseTypeImpl() const override; bool IsScalarImpl() const override; - uint8 ArrayIncrDimImpl(uint8 delta) override; - uint8 ArrayDecrDimImpl(uint8 delta) override; + TypeDim ArrayIncrDimImpl(TypeDim delta) override; + TypeDim ArrayDecrDimImpl(TypeDim delta) override; + virtual PrimType GetPrimTypeImpl() const override; + virtual void SetPrimTypeImpl(PrimType pt) override; + virtual bool IsRefImpl() const override { + return baseType->IsRef(); + } + + virtual bool IsArrayImpl() const override { + return baseType->IsArray(); + } + + virtual bool IsPreciseImpl() const override { + return baseType->IsPrecise(); + } + + virtual bool IsValidImpl() const override { + return baseType->IsValid(); + } private: + PrimType primType; std::unique_ptr baseType; }; diff --git a/src/mplfe/common/include/feir_type_helper.h b/src/mplfe/common/include/feir_type_helper.h index ffd6fccdd1257e7867813d6142b6f9a9870b4fc2..bf16af267dec986e48cb06f957e48c5dd1974562 100644 --- a/src/mplfe/common/include/feir_type_helper.h +++ b/src/mplfe/common/include/feir_type_helper.h @@ -16,12 +16,13 @@ #define MPLFE_INCLUDE_FEIR_TYPE_HELPER_H #include #include +#include "fe_configs.h" #include "feir_type.h" namespace maple { class FEIRTypeHelper { public: - static UniqueFEIRType CreateTypeByPrimType(PrimType primType, uint8 dim = 0, bool usePtr = false); + static UniqueFEIRType CreateTypeByPrimType(PrimType primType, TypeDim dim = 0, bool usePtr = false); static UniqueFEIRType CreateTypeByJavaName(const std::string typeName, bool inMpl, bool usePtr); static UniqueFEIRType CreatePointerType(UniqueFEIRType baseType, PrimType primType = PTY_ptr); static UniqueFEIRType CreateTypeByDimIncr(const UniqueFEIRType &srcType, uint8 delta, bool usePtr = false, @@ -29,6 +30,7 @@ class FEIRTypeHelper { static UniqueFEIRType CreateTypeByDimDecr(const UniqueFEIRType &srcType, uint8 delta); static UniqueFEIRType CreateTypeByGetAddress(const UniqueFEIRType &srcType, PrimType primType = PTY_ptr); static UniqueFEIRType CreateTypeByDereferrence(const UniqueFEIRType &srcType); + static UniqueFEIRType CreateTypeDefault(PrimType primType, const GStrIdx &typeNameIdx, TypeDim dim); private: FEIRTypeHelper() = default; diff --git a/src/mplfe/common/src/fe_struct_elem_info.cpp b/src/mplfe/common/src/fe_struct_elem_info.cpp index 453770a20f2a982f741ce6d0a3757e91fdd7a9b3..a2b77240af378344a8c1546bf5e0845fcebf14e6 100644 --- a/src/mplfe/common/src/fe_struct_elem_info.cpp +++ b/src/mplfe/common/src/fe_struct_elem_info.cpp @@ -214,15 +214,33 @@ bool FEStructFieldInfo::CompareFieldType(const FieldPair &fieldPair) const { } // ---------- FEStructMethodInfo ---------- +std::map> FEStructMethodInfo::javaPolymorphicWhiteList = + FEStructMethodInfo::InitJavaPolymorphicWhiteList(); + FEStructMethodInfo::FEStructMethodInfo(const GStrIdx &argFullNameIdx, MIRSrcLang argSrcLang, bool argIsStatic) : FEStructElemInfo(argFullNameIdx, argSrcLang, argIsStatic), methodNameIdx(fullNameIdx), mirFunc(nullptr), - isReturnVoid(false) { + isReturnVoid(false), + isJavaPolymorphicCall(false), + isJavaDynamicCall(false) { isMethod = true; LoadMethodType(); } +std::map> FEStructMethodInfo::InitJavaPolymorphicWhiteList() { + MPLFE_PARALLEL_FORBIDDEN(); + std::map> ans; + StringTable &strTable = GlobalTables::GetStrTable(); + GStrIdx idxMethodHandle = + strTable.GetOrCreateStrIdxFromName(NameMangler::EncodeName("Ljava/lang/invoke/MethodHandle;")); + bool success = true; + success = success && ans[idxMethodHandle].insert(strTable.GetOrCreateStrIdxFromName("invoke")).second; + success = success && ans[idxMethodHandle].insert(strTable.GetOrCreateStrIdxFromName("invokeBasic")).second; + success = success && ans[idxMethodHandle].insert(strTable.GetOrCreateStrIdxFromName("invokeExact")).second; + return ans; +} + PUIdx FEStructMethodInfo::GetPuIdx() const { CHECK_NULL_FATAL(mirFunc); return mirFunc->GetPuidx(); @@ -258,6 +276,11 @@ void FEStructMethodInfo::PrepareImplJava(MIRBuilder &mirBuilder, bool argIsStati if (isDefined) { return; } + } else if (isJavaDynamicCall) { + methodNameIdx = fullNameIdx; + isDefined = true; + PrepareMethod(); + return; } std::string methodName = GlobalTables::GetStrTable().GetStringFromStrIdx(fullNameIdx); WARN(kLncWarn, "undefined %s method: %s", isStatic ? "static" : "", methodName.c_str()); @@ -324,6 +347,13 @@ bool FEStructMethodInfo::SearchStructMethodJava(MIRStructType &structType, MIRBu std::string fullName = structType.GetCompactMplTypeName() + NameMangler::kNameSplitterStr + GetElemName() + NameMangler::kNameSplitterStr + GetSignatureName(); GStrIdx nameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fullName); + // PolymorphicCall Check + if (CheckJavaPolymorphicCall()) { + isJavaPolymorphicCall = true; + methodNameIdx = nameIdx; + PrepareMethod(); + return true; + } for (const MethodPair &methodPair : structType.GetMethods()) { const MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(methodPair.first.Idx(), true); CHECK_NULL_FATAL(sym); @@ -343,6 +373,11 @@ bool FEStructMethodInfo::SearchStructMethodJava(MIRStructType &structType, MIRBu } } // search parent + return SearchStructMethodJavaInParent(structType, mirBuilder, argIsStatic); +} + +bool FEStructMethodInfo::SearchStructMethodJavaInParent(MIRStructType &structType, MIRBuilder &mirBuilder, + bool argIsStatic) { bool found = false; if (structType.GetKind() == kTypeClass) { // parent @@ -381,4 +416,12 @@ bool FEStructMethodInfo::SearchStructMethodJava(const TyIdx &tyIdx, MIRBuilder & return false; } } + +bool FEStructMethodInfo::CheckJavaPolymorphicCall() const { + auto it = javaPolymorphicWhiteList.find(structNameIdx); + if (it == javaPolymorphicWhiteList.end()) { + return false; + } + return it->second.find(elemNameIdx) != it->second.end(); +} } // namespace maple diff --git a/src/mplfe/common/src/fe_type_manager.cpp b/src/mplfe/common/src/fe_type_manager.cpp index 412f003caf464c23dce07e30799bb844fb523905..a0dfaae74a2a54b30b50981ee31a94c8c1428a8b 100644 --- a/src/mplfe/common/src/fe_type_manager.cpp +++ b/src/mplfe/common/src/fe_type_manager.cpp @@ -269,29 +269,29 @@ MIRType *FETypeManager::GetOrCreateTypeFromName(const std::string &name, FETypeF } } -MIRType *FETypeManager::GetOrCreatePointerType(const MIRType &type) { - MIRType *retType = GlobalTables::GetTypeTable().GetOrCreatePointerType(type, PTY_ref); +MIRType *FETypeManager::GetOrCreatePointerType(const MIRType &type, PrimType ptyPtr) { + MIRType *retType = GlobalTables::GetTypeTable().GetOrCreatePointerType(type, ptyPtr); CHECK_NULL_FATAL(retType); return retType; } -MIRType *FETypeManager::GetOrCreateArrayType(MIRType &elemType, uint8 dim) { +MIRType *FETypeManager::GetOrCreateArrayType(MIRType &elemType, uint8 dim, PrimType ptyPtr) { switch (srcLang) { case kSrcLangJava: - return GetOrCreateJArrayType(elemType, dim); + return GetOrCreateJArrayType(elemType, dim, ptyPtr); default: CHECK_FATAL(false, "unsupported src lang: %d", srcLang); return nullptr; } } -MIRType *FETypeManager::GetOrCreateJArrayType(MIRType &elem, uint8 dim) { +MIRType *FETypeManager::GetOrCreateJArrayType(MIRType &elem, uint8 dim, PrimType ptyPtr) { MIRType *type = &elem; for (uint8 i = 0; i < dim; i++) { type = GlobalTables::GetTypeTable().GetOrCreateJarrayType(*type); CHECK_NULL_FATAL(type); if (i != dim - 1) { - type = GetOrCreatePointerType(*type); + type = GetOrCreatePointerType(*type, ptyPtr); CHECK_NULL_FATAL(type); } } diff --git a/src/mplfe/common/src/feir_stmt.cpp b/src/mplfe/common/src/feir_stmt.cpp index 11040270b46140b9468fc4de5e18bdc6bced539f..d9b89bae0017a15ddab9af11246ff94ed6f35be8 100644 --- a/src/mplfe/common/src/feir_stmt.cpp +++ b/src/mplfe/common/src/feir_stmt.cpp @@ -545,7 +545,6 @@ FEIRStmtCallAssign::FEIRStmtCallAssign(FEStructMethodInfo &argMethodInfo, Opcode : FEIRStmtAssign(FEIRNodeKind::kStmtCallAssign, std::move(argVarRet)), methodInfo(argMethodInfo), mirOp(argMIROp), - varRet(std::move(argVarRet)), isStatic(argIsStatic) {} std::map FEIRStmtCallAssign::InitMapOpAssignToOp() { @@ -571,6 +570,9 @@ std::list FEIRStmtCallAssign::GenMIRStmtsImpl(MIRBuilder &mirBuilder) StmtNode *stmtCall = nullptr; // prepare and find root methodInfo.Prepare(mirBuilder, isStatic); + if (methodInfo.IsJavaPolymorphicCall() || methodInfo.IsJavaDynamicCall()) { + return GenMIRStmtsUseZeroReturn(mirBuilder); + } Opcode op = AdjustMIROp(); MapleVector args(mirBuilder.GetCurrentFuncCodeMpAllocator()->Adapter()); for (const UniqueFEIRExpr &exprArg : exprArgs) { @@ -588,6 +590,45 @@ std::list FEIRStmtCallAssign::GenMIRStmtsImpl(MIRBuilder &mirBuilder) return ans; } +std::list FEIRStmtCallAssign::GenMIRStmtsUseZeroReturn(MIRBuilder &mirBuilder) const { + std::list ans; + if (methodInfo.IsReturnVoid()) { + return ans; + } + const UniqueFEIRType &retType = methodInfo.GetReturnType(); + MIRType *mirRetType = retType->GenerateMIRTypeAuto(kSrcLangJava); + MIRSymbol *mirRetSym = var->GenerateLocalMIRSymbol(mirBuilder); + BaseNode *nodeZero; + if (mirRetType->IsScalarType()) { + switch (mirRetType->GetPrimType()) { + case PTY_u1: + case PTY_i8: + case PTY_i16: + case PTY_u16: + case PTY_i32: + nodeZero = mirBuilder.CreateIntConst(0, PTY_i32); + break; + case PTY_i64: + nodeZero = mirBuilder.CreateIntConst(0, PTY_i64); + break; + case PTY_f32: + nodeZero = mirBuilder.CreateFloatConst(0.0f); + break; + case PTY_f64: + nodeZero = mirBuilder.CreateDoubleConst(0.0); + break; + default: + nodeZero = mirBuilder.CreateIntConst(0, PTY_i32); + break; + } + } else { + nodeZero = mirBuilder.CreateIntConst(0, PTY_ref); + } + StmtNode *stmt = mirBuilder.CreateStmtDassign(mirRetSym->GetStIdx(), 0, nodeZero); + ans.push_back(stmt); + return ans; +} + Opcode FEIRStmtCallAssign::AdjustMIROp() const { if (methodInfo.IsReturnVoid()) { auto it = mapOpAssignToOp.find(mirOp); diff --git a/src/mplfe/common/src/feir_type.cpp b/src/mplfe/common/src/feir_type.cpp index 36d10447825f4f0ddd189d3d69035f87e0f55548..0b6261352b9c359a2109826d0f27bcd3a4bbfc17 100644 --- a/src/mplfe/common/src/feir_type.cpp +++ b/src/mplfe/common/src/feir_type.cpp @@ -21,27 +21,25 @@ namespace maple { // ---------- FEIRType ---------- -FEIRType::FEIRType(FEIRTypeKind argKind) - : kind(argKind), isZero(false), primType(PTY_void) {} +std::map> FEIRType::langConfig = FEIRType::InitLangConfig(); -FEIRType::FEIRType(FEIRTypeKind argKind, PrimType argPrimType) - : kind(argKind), isZero(false), primType(argPrimType) {} +FEIRType::FEIRType(FEIRTypeKind argKind) + : kind(argKind), isZero(false) {} void FEIRType::CopyFromImpl(const FEIRType &type) { kind = type.kind; - primType = type.primType; } bool FEIRType::IsEqualToImpl(const std::unique_ptr &argType) const { - ASSERT(argType != nullptr, "nullptr check"); - if (kind != argType->kind) { + CHECK_NULL_FATAL(argType.get()); + if (kind != argType.get()->kind) { return false; } return IsEqualTo(*(argType.get())); } bool FEIRType::IsEqualToImpl(const FEIRType &argType) const { - if (kind == argType.kind && isZero == argType.isZero && primType == argType.primType) { + if (kind == argType.kind && isZero == argType.isZero) { return true; } else { return false; @@ -58,15 +56,20 @@ std::unique_ptr FEIRType::NewType(FEIRTypeKind argKind) { } } +std::map> FEIRType::InitLangConfig() { + std::map> ans; + ans[kSrcLangJava] = std::make_tuple(true, PTY_ref); + return ans; +} + MIRType *FEIRType::GenerateMIRTypeAuto(MIRSrcLang srcLang) const { MPLFE_PARALLEL_FORBIDDEN(); - switch (srcLang) { - case kSrcLangJava: - return GenerateMIRType(!IsScalar()); - default: - CHECK_FATAL(kLncErr, "unsupported language"); - return nullptr; + auto it = langConfig.find(srcLang); + if (it == langConfig.end()) { + CHECK_FATAL(kLncErr, "unsupported language"); + return nullptr; } + return GenerateMIRType(std::get<0>(it->second), std::get<1>(it->second)); } // ---------- FEIRTypeDefault ---------- @@ -79,8 +82,9 @@ FEIRTypeDefault::FEIRTypeDefault(PrimType argPrimType) FEIRTypeDefault::FEIRTypeDefault(PrimType argPrimType, const GStrIdx &argTypeNameIdx) : FEIRTypeDefault(argPrimType, argTypeNameIdx, 0) {} -FEIRTypeDefault::FEIRTypeDefault(PrimType argPrimType, const GStrIdx &argTypeNameIdx, uint8 argDim) - : FEIRType(kFEIRTypeDefault, argPrimType), +FEIRTypeDefault::FEIRTypeDefault(PrimType argPrimType, const GStrIdx &argTypeNameIdx, TypeDim argDim) + : FEIRType(kFEIRTypeDefault), + primType(argPrimType), typeNameIdx(argTypeNameIdx), dim(argDim) {} @@ -97,28 +101,18 @@ std::unique_ptr FEIRTypeDefault::CloneImpl() const { return type; } -MIRType *FEIRTypeDefault::GenerateMIRTypeImpl(MIRSrcLang srcLang, bool usePtr) const { - MPLFE_PARALLEL_FORBIDDEN(); - return GenerateMIRType(usePtr); -} - -MIRType *FEIRTypeDefault::GenerateMIRTypeImpl(bool usePtr) const { +MIRType *FEIRTypeDefault::GenerateMIRTypeImpl(bool usePtr, PrimType ptyPtr) const { MPLFE_PARALLEL_FORBIDDEN(); - return GenerateMIRTypeInternal(typeNameIdx, usePtr); + return GenerateMIRTypeInternal(typeNameIdx, usePtr, ptyPtr); } -MIRType *FEIRTypeDefault::GenerateMIRTypeImpl() const { - MPLFE_PARALLEL_FORBIDDEN(); - return GenerateMIRType(false); -} - -uint8 FEIRTypeDefault::ArrayIncrDimImpl(uint8 delta) { - CHECK_FATAL(kDimMax - dim >= delta, "dim delta is too large"); +TypeDim FEIRTypeDefault::ArrayIncrDimImpl(TypeDim delta) { + CHECK_FATAL(FEConstants::kDimMax - dim >= delta, "dim delta is too large"); dim += delta; return dim; } -uint8 FEIRTypeDefault::ArrayDecrDimImpl(uint8 delta) { +TypeDim FEIRTypeDefault::ArrayDecrDimImpl(TypeDim delta) { CHECK_FATAL(dim >= delta, "dim delta is too large"); dim -= delta; return dim; @@ -129,38 +123,53 @@ bool FEIRTypeDefault::IsEqualToImpl(const FEIRType &argType) const { return false; } const FEIRTypeDefault &argTypeDefault = static_cast(argType); - if (typeNameIdx == argTypeDefault.typeNameIdx && dim == argTypeDefault.dim) { + if (typeNameIdx == argTypeDefault.typeNameIdx && dim == argTypeDefault.dim && primType == argTypeDefault.primType) { return true; } else { return false; } } +bool FEIRTypeDefault::IsEqualToImpl(const std::unique_ptr &argType) const { + CHECK_NULL_FATAL(argType.get()); + return IsEqualToImpl(*(argType.get())); +} + size_t FEIRTypeDefault::HashImpl() const { return std::hash{}(typeNameIdx); } -bool FEIRTypeDefault::IsPreciseRefTypeImpl() const { - return primType == PTY_ref && typeNameIdx.GetIdx() != 0; +bool FEIRTypeDefault::IsScalarImpl() const { + return (primType != PTY_ref && IsPrimitiveScalar(primType) && dim == 0); } -bool FEIRTypeDefault::IsPreciseTypeImpl() const { - return (primType != PTY_ref && IsPrimitiveInteger(primType)) || - IsPrimitiveFloat(primType) || - (primType == PTY_ref && typeNameIdx != 0) || - isZero; +PrimType FEIRTypeDefault::GetPrimTypeImpl() const { + if (dim == 0) { + return primType; + } else { + return PTY_ref; + } } -bool FEIRTypeDefault::IsScalarImpl() const { - return (primType != PTY_ref && IsPrimitiveScalar(primType) && dim == 0); +void FEIRTypeDefault::SetPrimTypeImpl(PrimType pt) { + if (dim == 0) { + primType = pt; + } else { + if (pt == PTY_ref) { + primType = pt; + } else { + WARN(kLncWarn, "dim is set to zero"); + dim = 0; + } + } } void FEIRTypeDefault::LoadFromJavaTypeName(const std::string &typeName, bool inMpl) { MPLFE_PARALLEL_FORBIDDEN(); uint32 dimLocal = 0; std::string baseName = FETypeManager::GetBaseTypeName(typeName, dimLocal, inMpl); - CHECK_FATAL(dimLocal <= kDimMax, "invalid array type %s (dim is too big)", typeName.c_str()); - dim = static_cast(dimLocal); + CHECK_FATAL(dimLocal <= FEConstants::kDimMax, "invalid array type %s (dim is too big)", typeName.c_str()); + dim = static_cast(dimLocal); if (baseName.length() == 1) { typeNameIdx = GStrIdx(0); switch (baseName[0]) { @@ -223,6 +232,8 @@ MIRType *FEIRTypeDefault::GenerateMIRTypeForPrim() const { return GlobalTables::GetTypeTable().GetVoid(); case PTY_a32: return GlobalTables::GetTypeTable().GetAddr32(); + case PTY_ref: + return GlobalTables::GetTypeTable().GetRef(); default: CHECK_FATAL(false, "unsupported prim type"); } @@ -248,14 +259,37 @@ MIRType *FEIRTypeDefault::GenerateMIRTypeInternal(const GStrIdx &argTypeNameIdx, baseType = GenerateMIRTypeForPrim(); type = FEManager::GetTypeManager().GetOrCreateArrayType(*baseType, dim); } - if (IsScalar()) { + if (IsScalar() || !IsPreciseRefType()) { return type; } return usePtr ? FEManager::GetTypeManager().GetOrCreatePointerType(*type) : type; } +MIRType *FEIRTypeDefault::GenerateMIRTypeInternal(const GStrIdx &argTypeNameIdx, bool usePtr, PrimType ptyPtr) const { + MIRType *baseType = nullptr; + MIRType *type = nullptr; + bool baseTypeUseNoPtr = (IsScalarPrimType(primType) || argTypeNameIdx == 0); + bool typeUseNoPtr = !IsRef() || (!IsArray() && !IsPrecise()); + if (baseTypeUseNoPtr) { + baseType = GenerateMIRTypeForPrim(); + type = FEManager::GetTypeManager().GetOrCreateArrayType(*baseType, dim, ptyPtr); + } else { + bool isCreate = false; + baseType = FEManager::GetTypeManager().GetOrCreateClassOrInterfaceType(argTypeNameIdx, false, + FETypeFlag::kSrcUnknown, isCreate); + if (dim > 0) { + baseType = FEManager::GetTypeManager().GetOrCreatePointerType(*baseType, ptyPtr); + } + type = FEManager::GetTypeManager().GetOrCreateArrayType(*baseType, dim, ptyPtr); + } + if (typeUseNoPtr) { + return type; + } + return usePtr ? FEManager::GetTypeManager().GetOrCreatePointerType(*type, ptyPtr) : type; +} + // ---------- FEIRTypeByName ---------- -FEIRTypeByName::FEIRTypeByName(PrimType argPrimType, const std::string &argTypeName, uint8 argDim) +FEIRTypeByName::FEIRTypeByName(PrimType argPrimType, const std::string &argTypeName, TypeDim argDim) : FEIRTypeDefault(argPrimType, GStrIdx(0), argDim), typeName(argTypeName) { kind = kFEIRTypeByName; @@ -266,22 +300,10 @@ std::unique_ptr FEIRTypeByName::CloneImpl() const { return newType; } -MIRType *FEIRTypeByName::GenerateMIRTypeImpl(MIRSrcLang srcLang, bool usePtr) const { - MPLFE_PARALLEL_FORBIDDEN(); - GStrIdx argTypeNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(typeName.c_str()); - return GenerateMIRTypeInternal(argTypeNameIdx, usePtr); -} - -MIRType *FEIRTypeByName::GenerateMIRTypeImpl(bool usePtr) const { +MIRType *FEIRTypeByName::GenerateMIRTypeImpl(bool usePtr, PrimType ptyPtr) const { MPLFE_PARALLEL_FORBIDDEN(); - GStrIdx argTypeNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(typeName.c_str()); - return GenerateMIRTypeInternal(argTypeNameIdx, usePtr); -} - -MIRType *FEIRTypeByName::GenerateMIRTypeImpl() const { - MPLFE_PARALLEL_FORBIDDEN(); - GStrIdx argTypeNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(typeName.c_str()); - return GenerateMIRTypeInternal(argTypeNameIdx, false); + GStrIdx nameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(typeName); + return GenerateMIRTypeInternal(nameIdx, usePtr, ptyPtr); } bool FEIRTypeByName::IsEqualToImpl(const FEIRType &argType) const { @@ -300,22 +322,14 @@ size_t FEIRTypeByName::HashImpl() const { return std::hash{}(typeName); } -bool FEIRTypeByName::IsPreciseRefTypeImpl() const { - return primType == PTY_ref && (!typeName.empty()); -} - -bool FEIRTypeByName::IsPreciseTypeImpl() const { - return IsPrimitiveInteger(primType) || IsPrimitiveFloat(primType) || - (primType == PTY_ref && (!typeName.empty())); -} - bool FEIRTypeByName::IsScalarImpl() const { return false; } // ---------- FEIRTypePointer ---------- FEIRTypePointer::FEIRTypePointer(std::unique_ptr argBaseType, PrimType argPrimType) - : FEIRType(kFEIRTypePointer, argPrimType) { + : FEIRType(kFEIRTypePointer), + primType(argPrimType) { CHECK_FATAL(argBaseType != nullptr, "input type is nullptr"); baseType = std::move(argBaseType); } @@ -325,25 +339,9 @@ std::unique_ptr FEIRTypePointer::CloneImpl() const { return newType; } -MIRType *FEIRTypePointer::GenerateMIRTypeImpl(MIRSrcLang srcLang, bool usePtr) const { - ASSERT(baseType != nullptr, "base type is nullptr"); - MIRType *mirBaseType = baseType->GenerateMIRType(srcLang, usePtr); - ASSERT(mirBaseType != nullptr, "base mir type is nullptr"); - return GlobalTables::GetTypeTable().GetOrCreatePointerType(*mirBaseType, primType); -} - -MIRType *FEIRTypePointer::GenerateMIRTypeImpl(bool usePtr) const { - ASSERT(baseType != nullptr, "base type is nullptr"); - MIRType *mirBaseType = baseType->GenerateMIRType(usePtr); - ASSERT(mirBaseType != nullptr, "base mir type is nullptr"); - return GlobalTables::GetTypeTable().GetOrCreatePointerType(*mirBaseType, primType); -} - -MIRType *FEIRTypePointer::GenerateMIRTypeImpl() const { - ASSERT(baseType != nullptr, "base type is nullptr"); - MIRType *mirBaseType = baseType->GenerateMIRType(); - ASSERT(mirBaseType != nullptr, "base mir type is nullptr"); - return GlobalTables::GetTypeTable().GetOrCreatePointerType(*mirBaseType, primType); +MIRType *FEIRTypePointer::GenerateMIRTypeImpl(bool usePtr, PrimType ptyPtr) const { + MIRType *mirBaseType = baseType->GenerateMIRType(usePtr, ptyPtr); + return FEManager::GetTypeManager().GetOrCreatePointerType(*mirBaseType, ptyPtr); } bool FEIRTypePointer::IsEqualToImpl(const FEIRType &argType) const { @@ -356,27 +354,25 @@ size_t FEIRTypePointer::HashImpl() const { return baseType->Hash(); } -bool FEIRTypePointer::IsPreciseRefTypeImpl() const { - ASSERT(baseType != nullptr, "base type is nullptr"); - return baseType->IsPreciseRefType(); -} - -bool FEIRTypePointer::IsPreciseTypeImpl() const { - ASSERT(baseType != nullptr, "base type is nullptr"); - return baseType->IsPreciseType(); -} - bool FEIRTypePointer::IsScalarImpl() const { return false; } -uint8 FEIRTypePointer::ArrayIncrDimImpl(uint8 delta) { +TypeDim FEIRTypePointer::ArrayIncrDimImpl(TypeDim delta) { ASSERT(baseType != nullptr, "base type is nullptr"); return baseType->ArrayIncrDim(delta); } -uint8 FEIRTypePointer::ArrayDecrDimImpl(uint8 delta) { +TypeDim FEIRTypePointer::ArrayDecrDimImpl(TypeDim delta) { ASSERT(baseType != nullptr, "base type is nullptr"); return baseType->ArrayDecrDim(delta); } + +PrimType FEIRTypePointer::GetPrimTypeImpl() const { + return primType; +} + +void FEIRTypePointer::SetPrimTypeImpl(PrimType pt) { + CHECK_FATAL(false, "should not run here"); +} } // namespace maple diff --git a/src/mplfe/common/src/feir_type_helper.cpp b/src/mplfe/common/src/feir_type_helper.cpp index f0b635d1289f87ec512e58e30916f176054a9ab2..2cf06bfffc87bfc8f95ee3cd64fd27afe6274ec7 100644 --- a/src/mplfe/common/src/feir_type_helper.cpp +++ b/src/mplfe/common/src/feir_type_helper.cpp @@ -16,7 +16,7 @@ #include "fe_type_manager.h" namespace maple { -UniqueFEIRType FEIRTypeHelper::CreateTypeByPrimType(PrimType primType, uint8 dim, bool usePtr) { +UniqueFEIRType FEIRTypeHelper::CreateTypeByPrimType(PrimType primType, TypeDim dim, bool usePtr) { UniqueFEIRType type = std::make_unique(primType, GStrIdx(0), dim); if (usePtr) { return FEIRTypeHelper::CreatePointerType(std::move(type)); @@ -28,7 +28,7 @@ UniqueFEIRType FEIRTypeHelper::CreateTypeByPrimType(PrimType primType, uint8 dim UniqueFEIRType FEIRTypeHelper::CreateTypeByJavaName(const std::string typeName, bool inMpl, bool usePtr) { uint32 dim = 0; std::string baseName = FETypeManager::GetBaseTypeName(typeName, dim, inMpl); - CHECK_FATAL(dim <= FEIRType::kDimMax, "invalid array type %s (dim is too big)", typeName.c_str()); + CHECK_FATAL(dim <= FEConstants::kDimMax, "invalid array type %s (dim is too big)", typeName.c_str()); uint8 dim8 = static_cast(dim); UniqueFEIRType newType; if (baseName.length() == 1) { @@ -128,4 +128,10 @@ UniqueFEIRType FEIRTypeHelper::CreateTypeByDereferrence(const UniqueFEIRType &sr ASSERT(ptrSrcType != nullptr, "nullptr check"); return ptrSrcType->GetBaseType()->Clone(); } + +UniqueFEIRType FEIRTypeHelper::CreateTypeDefault(PrimType primType, const GStrIdx &typeNameIdx, TypeDim dim) { + UniqueFEIRType type = std::make_unique(primType, typeNameIdx, dim); + CHECK_FATAL(type->IsValid(), "invalid type"); + return type; +} } // namespace maple \ No newline at end of file diff --git a/src/mplfe/common/src/feir_type_infer.cpp b/src/mplfe/common/src/feir_type_infer.cpp index b6ccc355f03fc3a8ec2a8d1c36a10efc9d4c99a6..08ab91d64b575c2af43d78fc424c64311ccfc4ff 100644 --- a/src/mplfe/common/src/feir_type_infer.cpp +++ b/src/mplfe/common/src/feir_type_infer.cpp @@ -249,7 +249,7 @@ void FEIRTypeInfer::ProcessVarDef(UniqueFEIRVar &varDef) { } } } - if (useTypes.size() == 1 && !(varDef->GetType()->IsPreciseType())) { + if (useTypes.size() == 1 && !(varDef->GetType()->IsPrecise())) { varDef->SetType((*(useTypes.begin())).GetType()->Clone()); return; } diff --git a/src/mplfe/jbc_input/include/jbc_class.h b/src/mplfe/jbc_input/include/jbc_class.h index 1c89ab63f87e87a7e64e34003977aeaf6651da0b..cbd55a62e25d3788e92b2be5b2f2d0041a5ba68f 100644 --- a/src/mplfe/jbc_input/include/jbc_class.h +++ b/src/mplfe/jbc_input/include/jbc_class.h @@ -116,7 +116,7 @@ class JBCClassMethod : public JBCClassElem { class JBCClass { public: JBCClass(MapleAllocator &allocatorIn); - ~JBCClass() = default; + LLT_MOCK_TARGET ~JBCClass() = default; bool ParseFile(BasicIORead &io); bool PreProcess(); diff --git a/src/mplfe/jbc_input/include/jbc_class_const.h b/src/mplfe/jbc_input/include/jbc_class_const.h index 02aa4ada22d965ae4e78b70d71b1e4dc8a0338cf..0e385be7a14e0a7768d04c0010e47e4a3db2df6a 100644 --- a/src/mplfe/jbc_input/include/jbc_class_const.h +++ b/src/mplfe/jbc_input/include/jbc_class_const.h @@ -392,11 +392,20 @@ class JBCConstInvokeDynamic : public JBCConst { public: JBCConstInvokeDynamic(MapleAllocator &alloc, JBCConstTag t); ~JBCConstInvokeDynamic(); + bool PrepareFEStructElemInfo(const std::string &ownerClassName); + JBCConstPoolIdx GetBSMAttrIdx() const { + return rawData.bsmAttrIdx; + } const JBCConstNameAndType *GetConstNameAndType() const { return constNameAndType; } + FEStructElemInfo *GetFEStructElemInfo() const { + CHECK_NULL_FATAL(feStructElemInfo); + return feStructElemInfo; + } + protected: bool ParseFileImpl(BasicIORead &io) override; bool PreProcessImpl(const JBCConstPool &constPool) override; @@ -408,6 +417,7 @@ class JBCConstInvokeDynamic : public JBCConst { JBCConstPoolIdx nameAndTypeIdx; } rawData; const JBCConstNameAndType *constNameAndType; + FEStructElemInfo *feStructElemInfo; }; } // namespace jbc } // namespace maple diff --git a/src/mplfe/jbc_input/include/jbc_class_const_pool.h b/src/mplfe/jbc_input/include/jbc_class_const_pool.h index 090be59cd3ae04999064dbdefc234bacdc9eb312..327415013b8cc62086eb718da9239c725b4bc218 100644 --- a/src/mplfe/jbc_input/include/jbc_class_const_pool.h +++ b/src/mplfe/jbc_input/include/jbc_class_const_pool.h @@ -38,7 +38,7 @@ class JBCConstPool { const JBCConst *GetConstValue8ByteByIdx(uint16 idx, bool safe = false) const; std::string GetNameByClassInfoIdx(uint16 idx, bool safe = false) const; bool PreProcess(uint16 argMajorVersion); - bool PrepareFEStructElemInfo(); + bool PrepareFEStructElemInfo(const std::string &ownerClassName); JBCConstUTF8 *NewConstUTF8(uint16 &idx, const std::string &str); JBCConst4Byte *NewConst4Byte(uint16 &idx, int32 value); JBCConst4Byte *NewConst4Byte(uint16 &idx, float value); diff --git a/src/mplfe/jbc_input/include/jbc_stmt.h b/src/mplfe/jbc_input/include/jbc_stmt.h index 3bd9648dc8f98820d53df57a87566ee50e666cb7..8891034395283754084780ebc6f3d6a4138bb1b1 100644 --- a/src/mplfe/jbc_input/include/jbc_stmt.h +++ b/src/mplfe/jbc_input/include/jbc_stmt.h @@ -200,6 +200,9 @@ class JBCStmtInst : public JBCStmt { std::list EmitToFEIRForOpInvokeSpecial(JBCStack2FEHelper &stack2feHelper, const jbc::JBCConstPool &constPool, bool &success) const; + std::list EmitToFEIRForOpInvokeDynamic(JBCStack2FEHelper &stack2feHelper, + const jbc::JBCConstPool &constPool, + bool &success) const; std::list EmitToFEIRForOpNew(JBCStack2FEHelper &stack2feHelper, const jbc::JBCConstPool &constPool, bool &success) const; diff --git a/src/mplfe/jbc_input/src/jbc_class.cpp b/src/mplfe/jbc_input/src/jbc_class.cpp index 70e4abe43ea094bdba486afbff10e0e83285bb58..29a35b9d042c55833f888fafee17cb2aa69918be 100644 --- a/src/mplfe/jbc_input/src/jbc_class.cpp +++ b/src/mplfe/jbc_input/src/jbc_class.cpp @@ -208,7 +208,7 @@ bool JBCClass::ParseFileForAttrs(BasicIORead &io) { bool JBCClass::PreProcess() { bool success = true; success = success && constPool.PreProcess(header.majorVersion); - success = success && constPool.PrepareFEStructElemInfo(); + success = success && constPool.PrepareFEStructElemInfo(GetClassNameOrin()); for (JBCClassMethod *method : tbMethods) { success = success && method->PreProcess(); } diff --git a/src/mplfe/jbc_input/src/jbc_class_const.cpp b/src/mplfe/jbc_input/src/jbc_class_const.cpp index 70ce76a2f2eafc867df59258fdf58deb5ca3e23a..505e476f20332861a39b46476615419cab40b3e5 100644 --- a/src/mplfe/jbc_input/src/jbc_class_const.cpp +++ b/src/mplfe/jbc_input/src/jbc_class_const.cpp @@ -449,7 +449,7 @@ SimpleXMLElem *JBCConstMethodType::GenXMLElemImpl(MapleAllocator &alloc, uint32 // ---------- JBCConstInvokeDynamic ---------- JBCConstInvokeDynamic::JBCConstInvokeDynamic(MapleAllocator &alloc, JBCConstTag t) - : JBCConst(alloc, t), constNameAndType(nullptr) { + : JBCConst(alloc, t), constNameAndType(nullptr), feStructElemInfo(nullptr) { rawData.bsmAttrIdx = 0; rawData.nameAndTypeIdx = 0; } @@ -458,6 +458,18 @@ JBCConstInvokeDynamic::~JBCConstInvokeDynamic() { constNameAndType = nullptr; } +bool JBCConstInvokeDynamic::PrepareFEStructElemInfo(const std::string &ownerClassName) { + CHECK_NULL_FATAL(constNameAndType); + const std::string &className = ownerClassName + "$DynamicCall$"; + const std::string &elemName = constNameAndType->GetName(); + const std::string &descName = constNameAndType->GetDesc(); + std::string fullName = NameMangler::EncodeName(className + "|" + elemName + "|" + descName); + GStrIdx fullNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(fullName); + feStructElemInfo = FEManager::GetTypeManager().RegisterStructMethodInfo(fullNameIdx, kSrcLangJava, false); + static_cast(feStructElemInfo)->SetJavaDyamicCall(); + return feStructElemInfo != nullptr; +} + bool JBCConstInvokeDynamic::ParseFileImpl(BasicIORead &io) { bool success = false; rawData.bsmAttrIdx = io.ReadUInt16(success); diff --git a/src/mplfe/jbc_input/src/jbc_class_const_pool.cpp b/src/mplfe/jbc_input/src/jbc_class_const_pool.cpp index 7c88bcd0de69ee541c0cff8a3ce128334b6f0c11..df53651ccac7ac9b90293cfdfe93aa57a7385846 100644 --- a/src/mplfe/jbc_input/src/jbc_class_const_pool.cpp +++ b/src/mplfe/jbc_input/src/jbc_class_const_pool.cpp @@ -118,7 +118,7 @@ bool JBCConstPool::PreProcess(uint16 argMajorVersion) { return true; } -bool JBCConstPool::PrepareFEStructElemInfo() { +bool JBCConstPool::PrepareFEStructElemInfo(const std::string &ownerClassName) { bool success = true; for (JBCConst *c : pool) { if (c == nullptr) { @@ -130,6 +130,10 @@ bool JBCConstPool::PrepareFEStructElemInfo() { JBCConstRef *constRef = static_cast(c); success = success && constRef->PrepareFEStructElemInfo(); } + if (tag == JBCConstTag::kConstInvokeDynamic) { + JBCConstInvokeDynamic *constRef = static_cast(c); + success = success && constRef->PrepareFEStructElemInfo(ownerClassName); + } } return success; } diff --git a/src/mplfe/jbc_input/src/jbc_opcode.cpp b/src/mplfe/jbc_input/src/jbc_opcode.cpp index 9e0654d7cc819c64fcfe40ce70600393fdbaf4d5..b913ad2dc0985ef213053ec6b13c6269a6045113 100644 --- a/src/mplfe/jbc_input/src/jbc_opcode.cpp +++ b/src/mplfe/jbc_input/src/jbc_opcode.cpp @@ -1175,7 +1175,8 @@ std::string JBCOpInvoke::DumpImpl(const JBCConstPool &constPool) const { if (tag == kConstInvokeDynamic) { const JBCConstInvokeDynamic *constInvokdDynamic = static_cast(constRaw); CHECK_NULL_FATAL(constInvokdDynamic->GetConstNameAndType()); - ss << constInvokdDynamic->GetConstNameAndType()->GetName() << ":" << + ss << constInvokdDynamic->GetBSMAttrIdx() << ":" << + constInvokdDynamic->GetConstNameAndType()->GetName() << ":" << constInvokdDynamic->GetConstNameAndType()->GetDesc(); } else { ss << "invalid const tag"; diff --git a/src/mplfe/jbc_input/src/jbc_stmt.cpp b/src/mplfe/jbc_input/src/jbc_stmt.cpp index e9145b8917ee62d8282efb944cc6004b17672495..2d944f31f314b33192068ada370aa9143e22e437 100644 --- a/src/mplfe/jbc_input/src/jbc_stmt.cpp +++ b/src/mplfe/jbc_input/src/jbc_stmt.cpp @@ -719,8 +719,7 @@ std::list JBCStmtInst::EmitToFEIRForOpInvoke(JBCStack2FEHelper & case jbc::kOpInvokeInterface: return EmitToFEIRForOpInvokeInterface(stack2feHelper, constPool, success); case jbc::kOpInvokeDynamic: - // WARN(kLncWarn, "unsupported op: invokedynamic"); - break; + return EmitToFEIRForOpInvokeDynamic(stack2feHelper, constPool, success); default: CHECK_FATAL(false, "unsupported op: %s", op.GetOpcodeName().c_str()); break; @@ -735,7 +734,7 @@ void JBCStmtInst::PrepareInvokeParametersAndReturn(JBCStack2FEHelper &stack2feHe const std::vector &argTypes = info.GetArgTypes(); for (int i = argTypes.size() - 1; i >= 0; --i) { const UniqueFEIRType &argType = argTypes[static_cast(i)]; - PrimType pty = argType->GetRealPrimType(); + PrimType pty = argType->GetPrimType(); UniqueFEIRVar var = stack2feHelper.PopItem(JBCStack2FEHelper::SimplifyPrimType(pty)); UniqueFEIRExpr expr = FEIRBuilder::CreateExprDRead(std::move(var)); callStmt.AddExprArgReverse(std::move(expr)); @@ -743,14 +742,14 @@ void JBCStmtInst::PrepareInvokeParametersAndReturn(JBCStack2FEHelper &stack2feHe if (!isStatic) { // push this const UniqueFEIRType &thisType = info.GetOwnerType(); - PrimType pty = thisType->GetRealPrimType(); + PrimType pty = thisType->GetPrimType(); UniqueFEIRVar var = stack2feHelper.PopItem(JBCStack2FEHelper::SimplifyPrimType(pty)); UniqueFEIRExpr expr = FEIRBuilder::CreateExprDRead(std::move(var)); callStmt.AddExprArgReverse(std::move(expr)); } if (!info.IsReturnVoid()) { const UniqueFEIRType &retType = info.GetReturnType(); - PrimType pty = retType->GetRealPrimType(); + PrimType pty = retType->GetPrimType(); UniqueFEIRVar var = stack2feHelper.PushItem(JBCStack2FEHelper::SimplifyPrimType(pty)); callStmt.SetVar(std::move(var)); } @@ -841,6 +840,25 @@ std::list JBCStmtInst::EmitToFEIRForOpInvokeSpecial(JBCStack2FEH return ans; } +std::list JBCStmtInst::EmitToFEIRForOpInvokeDynamic(JBCStack2FEHelper &stack2feHelper, + const jbc::JBCConstPool &constPool, + bool &success) const { + std::list ans; + const jbc::JBCOpInvoke &opInvoke = static_cast(op); + const jbc::JBCConst *constRaw = constPool.GetConstByIdx(opInvoke.GetMethodIdx()); + if (constRaw == nullptr || constRaw->GetTag() != jbc::JBCConstTag::kConstInvokeDynamic) { + success = false; + return ans; + } + const jbc::JBCConstInvokeDynamic *constDynamic = static_cast(constRaw); + FEStructMethodInfo *methodInfo = static_cast(constDynamic->GetFEStructElemInfo()); + UniqueFEIRStmt stmt = std::make_unique(*methodInfo, OP_call, nullptr, true); + FEIRStmtCallAssign *ptrStmt = static_cast(stmt.get()); + PrepareInvokeParametersAndReturn(stack2feHelper, *methodInfo, *ptrStmt, true); + ans.push_back(std::move(stmt)); + return ans; +} + std::list JBCStmtInst::EmitToFEIRForOpNew(JBCStack2FEHelper &stack2feHelper, const jbc::JBCConstPool &constPool, bool &success) const {