зеркало из https://github.com/dotnet/llilc.git
Merge pull request #345 from pgavlin/callconv
Support VSD calls and methods with a secret parameter.
This commit is contained in:
Коммит
87ee4e6dce
|
@ -281,6 +281,7 @@ enum ReaderSpecialSymbolType {
|
||||||
Reader_UnmodifiedThisPtr, ///< This pointer param passed to method
|
Reader_UnmodifiedThisPtr, ///< This pointer param passed to method
|
||||||
Reader_VarArgsToken, ///< Special param for varargs support
|
Reader_VarArgsToken, ///< Special param for varargs support
|
||||||
Reader_InstParam, ///< Special param for shared generics
|
Reader_InstParam, ///< Special param for shared generics
|
||||||
|
Reader_SecretParam, ///< Special param for IL stubs
|
||||||
Reader_SecurityObject, ///< Local used for security checking
|
Reader_SecurityObject, ///< Local used for security checking
|
||||||
Reader_GenericsContext ///< Local holding shared generics context
|
Reader_GenericsContext ///< Local holding shared generics context
|
||||||
};
|
};
|
||||||
|
@ -1212,26 +1213,34 @@ public:
|
||||||
/// direct client processing for the method parameters and the local
|
/// direct client processing for the method parameters and the local
|
||||||
/// variables of the method.
|
/// variables of the method.
|
||||||
///
|
///
|
||||||
/// \params NumParams Number of parameters to the method. Note this may
|
/// \param NumParams Number of parameters to the method. Note this
|
||||||
/// include implicit parameters like the this pointer.
|
/// includes implicit parameters like the this
|
||||||
/// \params NumAutos Number of locals described in the local signature.
|
/// pointer.
|
||||||
void initParamsAndAutos(uint32_t NumParam, uint32_t NumAuto);
|
/// \param NumAutos Number of locals described in the local
|
||||||
|
/// signature.
|
||||||
|
/// \param HasSecretParameter Indicates whether or not the terminal parameter
|
||||||
|
/// is the secret parameter of an IL stub.
|
||||||
|
void initParamsAndAutos(uint32_t NumParam, uint32_t NumAuto,
|
||||||
|
bool HasSecretParameter);
|
||||||
|
|
||||||
/// \brief Set up parameters
|
/// \brief Set up parameters
|
||||||
///
|
///
|
||||||
/// Uses the method signature and information from the EE to direct the
|
/// Uses the method signature and information from the EE to direct the
|
||||||
/// client to set up processing for method parameters.
|
/// client to set up processing for method parameters.
|
||||||
///
|
///
|
||||||
/// \params NumParams Number of parameters to the method. Note this may
|
/// \param NumParams Number of parameters to the method. Note this
|
||||||
/// include implicit parameters like the this pointer.
|
/// includes implicit parameters like the this
|
||||||
void buildUpParams(uint32_t NumParams);
|
/// pointer.
|
||||||
|
/// \param HasSecretParameter Indicates whether or not the terminal parameter
|
||||||
|
/// is the secret parameter of an IL stub.
|
||||||
|
void buildUpParams(uint32_t NumParams, bool HasSecretParameter);
|
||||||
|
|
||||||
/// \brief Set up locals (autos)
|
/// \brief Set up locals (autos)
|
||||||
///
|
///
|
||||||
/// Uses the local signature to direct the client to set up processing
|
/// Uses the local signature to direct the client to set up processing
|
||||||
/// for local variables in the method.
|
/// for local variables in the method.
|
||||||
///
|
///
|
||||||
/// \params NumAutos Number of locals described in the signature.
|
/// \param NumAutos Number of locals described in the signature.
|
||||||
void buildUpAutos(uint32_t NumAutos);
|
void buildUpAutos(uint32_t NumAutos);
|
||||||
|
|
||||||
/// \brief Process the next element (argument or local) in a signature
|
/// \brief Process the next element (argument or local) in a signature
|
||||||
|
@ -1240,7 +1249,7 @@ public:
|
||||||
/// through a signature and obtain more detailed information about each
|
/// through a signature and obtain more detailed information about each
|
||||||
/// element.
|
/// element.
|
||||||
///
|
///
|
||||||
/// \params ArgListHandle Handle for the current element of the signature
|
/// \param ArgListHandle Handle for the current element of the signature
|
||||||
/// \param Sig The signature being iterated over.
|
/// \param Sig The signature being iterated over.
|
||||||
/// \param CorType [out] Optional; the CorInfoType of the current element.
|
/// \param CorType [out] Optional; the CorInfoType of the current element.
|
||||||
/// \param Class [out] Optional; the class handle of the current element.
|
/// \param Class [out] Optional; the class handle of the current element.
|
||||||
|
@ -2763,8 +2772,8 @@ public:
|
||||||
ReaderSpecialSymbolType Type = Reader_NotSpecialSymbol) = 0;
|
ReaderSpecialSymbolType Type = Reader_NotSpecialSymbol) = 0;
|
||||||
|
|
||||||
virtual IRNode *derefAddress(IRNode *Address, bool DestIsGCPtr, bool IsConst,
|
virtual IRNode *derefAddress(IRNode *Address, bool DestIsGCPtr, bool IsConst,
|
||||||
|
|
||||||
bool AddressMayBeNull = true) = 0;
|
bool AddressMayBeNull = true) = 0;
|
||||||
|
|
||||||
IRNode *derefAddressNonNull(IRNode *Address, bool DestIsGCPtr, bool IsConst) {
|
IRNode *derefAddressNonNull(IRNode *Address, bool DestIsGCPtr, bool IsConst) {
|
||||||
return derefAddress(Address, DestIsGCPtr, IsConst, false);
|
return derefAddress(Address, DestIsGCPtr, IsConst, false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -279,9 +279,7 @@ public:
|
||||||
IRNode *argList() override;
|
IRNode *argList() override;
|
||||||
IRNode *instParam() override;
|
IRNode *instParam() override;
|
||||||
|
|
||||||
IRNode *secretParam() override {
|
IRNode *secretParam() override;
|
||||||
throw NotYetImplementedException("secretParam");
|
|
||||||
};
|
|
||||||
IRNode *thisObj() override;
|
IRNode *thisObj() override;
|
||||||
|
|
||||||
void boolBranch(ReaderBaseNS::BoolBranchOpcode Opcode, IRNode *Arg1) override;
|
void boolBranch(ReaderBaseNS::BoolBranchOpcode Opcode, IRNode *Arg1) override;
|
||||||
|
@ -805,8 +803,11 @@ public:
|
||||||
// newobj
|
// newobj
|
||||||
bool canonNewObjCall(IRNode *CallNode, ReaderCallTargetData *CallTargetData,
|
bool canonNewObjCall(IRNode *CallNode, ReaderCallTargetData *CallTargetData,
|
||||||
IRNode **OutResult);
|
IRNode **OutResult);
|
||||||
void canonNewArrayCall(IRNode *CallNode, ReaderCallTargetData *CallTargetData,
|
IRNode *canonNewArrayCall(IRNode *CallNode,
|
||||||
IRNode **OutResult);
|
ReaderCallTargetData *CallTargetData);
|
||||||
|
|
||||||
|
// stubs
|
||||||
|
IRNode *canonStubCall(IRNode *CallNode, ReaderCallTargetData *CallTargetData);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Used to expand multidimensional array access intrinsics
|
// Used to expand multidimensional array access intrinsics
|
||||||
|
@ -837,11 +838,14 @@ private:
|
||||||
llvm::Type *getType(CorInfoType Type, CORINFO_CLASS_HANDLE ClassHandle,
|
llvm::Type *getType(CorInfoType Type, CORINFO_CLASS_HANDLE ClassHandle,
|
||||||
bool GetRefClassFields = true);
|
bool GetRefClassFields = true);
|
||||||
|
|
||||||
llvm::Function *getFunction(CORINFO_METHOD_HANDLE Method);
|
llvm::Function *getFunction(CORINFO_METHOD_HANDLE Method,
|
||||||
|
bool HasSecretParameter);
|
||||||
|
|
||||||
llvm::FunctionType *getFunctionType(CORINFO_METHOD_HANDLE Method);
|
llvm::FunctionType *getFunctionType(CORINFO_METHOD_HANDLE Method,
|
||||||
|
bool HasSecretParameter = false);
|
||||||
llvm::FunctionType *getFunctionType(CORINFO_SIG_INFO &Sig,
|
llvm::FunctionType *getFunctionType(CORINFO_SIG_INFO &Sig,
|
||||||
CORINFO_CLASS_HANDLE ThisClass);
|
CORINFO_CLASS_HANDLE ThisClass,
|
||||||
|
bool HasSecretParameter = false);
|
||||||
|
|
||||||
llvm::Type *getClassType(CORINFO_CLASS_HANDLE ClassHandle, bool IsRefClass,
|
llvm::Type *getClassType(CORINFO_CLASS_HANDLE ClassHandle, bool IsRefClass,
|
||||||
bool GetRefClassFields);
|
bool GetRefClassFields);
|
||||||
|
@ -1101,6 +1105,7 @@ private:
|
||||||
bool HasThis;
|
bool HasThis;
|
||||||
bool HasTypeParameter;
|
bool HasTypeParameter;
|
||||||
bool HasVarargsToken;
|
bool HasVarargsToken;
|
||||||
|
bool HasSecretParameter;
|
||||||
bool KeepGenericContextAlive;
|
bool KeepGenericContextAlive;
|
||||||
llvm::BasicBlock *EntryBlock;
|
llvm::BasicBlock *EntryBlock;
|
||||||
llvm::Instruction *TempInsertionPoint;
|
llvm::Instruction *TempInsertionPoint;
|
||||||
|
|
|
@ -5609,7 +5609,8 @@ void ReaderBase::clearStack() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReaderBase::initParamsAndAutos(uint32_t NumParam, uint32_t NumAuto) {
|
void ReaderBase::initParamsAndAutos(uint32_t NumParam, uint32_t NumAuto,
|
||||||
|
bool HasSecretParameter) {
|
||||||
// Init verification maps
|
// Init verification maps
|
||||||
if (VerificationNeeded) {
|
if (VerificationNeeded) {
|
||||||
NumVerifyParams = NumParam;
|
NumVerifyParams = NumParam;
|
||||||
|
@ -5626,7 +5627,7 @@ void ReaderBase::initParamsAndAutos(uint32_t NumParam, uint32_t NumAuto) {
|
||||||
NumVerifyAutos = 0;
|
NumVerifyAutos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
buildUpParams(NumParam);
|
buildUpParams(NumParam, HasSecretParameter);
|
||||||
buildUpAutos(NumAuto);
|
buildUpAutos(NumAuto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5690,7 +5691,7 @@ void ReaderBase::buildUpAutos(uint32_t NumAutos) {
|
||||||
// Note there is parallel logic in GenIR::GetFunctionType.
|
// Note there is parallel logic in GenIR::GetFunctionType.
|
||||||
// It must be kept in sync with the logic in this method.
|
// It must be kept in sync with the logic in this method.
|
||||||
// We possibly should merge these two.
|
// We possibly should merge these two.
|
||||||
void ReaderBase::buildUpParams(uint32_t NumParams) {
|
void ReaderBase::buildUpParams(uint32_t NumParams, bool HasSecretParameter) {
|
||||||
if (NumParams > 0) {
|
if (NumParams > 0) {
|
||||||
CORINFO_ARG_LIST_HANDLE NextLoc, Locs;
|
CORINFO_ARG_LIST_HANDLE NextLoc, Locs;
|
||||||
CORINFO_CLASS_HANDLE Class;
|
CORINFO_CLASS_HANDLE Class;
|
||||||
|
@ -5752,8 +5753,10 @@ void ReaderBase::buildUpParams(uint32_t NumParams) {
|
||||||
ParamIndex++;
|
ParamIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t NumRealParams = HasSecretParameter ? NumParams - 1 : NumParams;
|
||||||
|
|
||||||
// Get the types of all of the parameters.
|
// Get the types of all of the parameters.
|
||||||
for (; ParamIndex < NumParams; ParamIndex++) {
|
for (; ParamIndex < NumRealParams; ParamIndex++) {
|
||||||
|
|
||||||
if (VerificationNeeded) {
|
if (VerificationNeeded) {
|
||||||
verifyRecordParamType(ParamIndex - (IsVarArg ? 1 : 0) -
|
verifyRecordParamType(ParamIndex - (IsVarArg ? 1 : 0) -
|
||||||
|
@ -5765,6 +5768,14 @@ void ReaderBase::buildUpParams(uint32_t NumParams) {
|
||||||
createSym(ParamIndex, false, CorType, Class, false);
|
createSym(ParamIndex, false, CorType, Class, false);
|
||||||
Locs = NextLoc;
|
Locs = NextLoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (HasSecretParameter) {
|
||||||
|
ASSERT(ParamIndex == NumParams - 1);
|
||||||
|
|
||||||
|
CORINFO_CLASS_HANDLE Class = 0;
|
||||||
|
createSym(ParamIndex, false, CORINFO_TYPE_NATIVEINT, Class, false,
|
||||||
|
ReaderSpecialSymbolType::Reader_SecretParam);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -269,8 +269,12 @@ void GenIR::readerPrePass(uint8_t *Buffer, uint32_t NumBytes) {
|
||||||
ASSERTNR(UNREACHED);
|
ASSERTNR(UNREACHED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uint32_t JitFlags = JitContext->Flags;
|
||||||
|
|
||||||
|
HasSecretParameter = (JitFlags & CORJIT_FLG_PUBLISH_SECRET_PARAM) != 0;
|
||||||
|
|
||||||
CORINFO_METHOD_HANDLE MethodHandle = JitContext->MethodInfo->ftn;
|
CORINFO_METHOD_HANDLE MethodHandle = JitContext->MethodInfo->ftn;
|
||||||
Function = getFunction(MethodHandle);
|
Function = getFunction(MethodHandle, HasSecretParameter);
|
||||||
|
|
||||||
// Capture low-level info about the return type for use in Return.
|
// Capture low-level info about the return type for use in Return.
|
||||||
CORINFO_SIG_INFO Sig;
|
CORINFO_SIG_INFO Sig;
|
||||||
|
@ -300,7 +304,7 @@ void GenIR::readerPrePass(uint8_t *Buffer, uint32_t NumBytes) {
|
||||||
KeepGenericContextAlive = false;
|
KeepGenericContextAlive = false;
|
||||||
UnreachableContinuationBlock = nullptr;
|
UnreachableContinuationBlock = nullptr;
|
||||||
|
|
||||||
initParamsAndAutos(NumArgs, NumLocals);
|
initParamsAndAutos(NumArgs, NumLocals, HasSecretParameter);
|
||||||
|
|
||||||
// Take note of the current insertion point in case we need
|
// Take note of the current insertion point in case we need
|
||||||
// to add more allocas later.
|
// to add more allocas later.
|
||||||
|
@ -326,7 +330,6 @@ void GenIR::readerPrePass(uint8_t *Buffer, uint32_t NumBytes) {
|
||||||
|
|
||||||
// Check for special cases where the Jit needs to do extra work.
|
// Check for special cases where the Jit needs to do extra work.
|
||||||
const uint32_t MethodFlags = getCurrentMethodAttribs();
|
const uint32_t MethodFlags = getCurrentMethodAttribs();
|
||||||
const uint32_t JitFlags = JitContext->Flags;
|
|
||||||
|
|
||||||
// TODO: support for synchronized methods
|
// TODO: support for synchronized methods
|
||||||
if (MethodFlags & CORINFO_FLG_SYNCH) {
|
if (MethodFlags & CORINFO_FLG_SYNCH) {
|
||||||
|
@ -345,12 +348,6 @@ void GenIR::readerPrePass(uint8_t *Buffer, uint32_t NumBytes) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: support for secret parameter for shared IL stubs
|
|
||||||
if ((JitFlags & CORJIT_FLG_IL_STUB) &&
|
|
||||||
(JitFlags & CORJIT_FLG_PUBLISH_SECRET_PARAM)) {
|
|
||||||
throw NotYetImplementedException("publish secret param");
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Insert class initialization check if necessary
|
// TODO: Insert class initialization check if necessary
|
||||||
CorInfoInitClassResult InitResult =
|
CorInfoInitClassResult InitResult =
|
||||||
initClass(nullptr, getCurrentMethodHandle(), getCurrentContext());
|
initClass(nullptr, getCurrentMethodHandle(), getCurrentContext());
|
||||||
|
@ -495,9 +492,10 @@ void GenIR::createSym(uint32_t Num, bool IsAuto, CorInfoType CorType,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Function *GenIR::getFunction(CORINFO_METHOD_HANDLE MethodHandle) {
|
Function *GenIR::getFunction(CORINFO_METHOD_HANDLE MethodHandle,
|
||||||
|
bool HasSecretParameter) {
|
||||||
Module *M = JitContext->CurrentModule;
|
Module *M = JitContext->CurrentModule;
|
||||||
FunctionType *Ty = getFunctionType(MethodHandle);
|
FunctionType *Ty = getFunctionType(MethodHandle, HasSecretParameter);
|
||||||
llvm::Function *F = Function::Create(Ty, Function::ExternalLinkage,
|
llvm::Function *F = Function::Create(Ty, Function::ExternalLinkage,
|
||||||
M->getModuleIdentifier(), M);
|
M->getModuleIdentifier(), M);
|
||||||
|
|
||||||
|
@ -511,6 +509,17 @@ Function *GenIR::getFunction(CORINFO_METHOD_HANDLE MethodHandle) {
|
||||||
Args->setName(Twine("param") + Twine(N++));
|
Args->setName(Twine("param") + Twine(N++));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (HasSecretParameter) {
|
||||||
|
ASSERT((--F->arg_end())->getType() ==
|
||||||
|
getType(CORINFO_TYPE_NATIVEINT, nullptr));
|
||||||
|
|
||||||
|
LLVMContext &Context = *JitContext->LLVMContext;
|
||||||
|
AttributeSet Attrs = F->getAttributes();
|
||||||
|
F->setAttributes(
|
||||||
|
Attrs.addAttribute(Context, F->arg_size(), "CLR_SecretParameter"));
|
||||||
|
F->setCallingConv(CallingConv::CLR_SecretParameter);
|
||||||
|
}
|
||||||
|
|
||||||
return F;
|
return F;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -552,6 +561,14 @@ IRNode *GenIR::thisObj() {
|
||||||
return (IRNode *)UnmodifiedThis;
|
return (IRNode *)UnmodifiedThis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the value of the secret parameter to an IL stub.
|
||||||
|
IRNode *GenIR::secretParam() {
|
||||||
|
ASSERT(HasSecretParameter);
|
||||||
|
Function::arg_iterator Args = Function->arg_end();
|
||||||
|
Value *SecretParameter = --Args;
|
||||||
|
return (IRNode *)SecretParameter;
|
||||||
|
}
|
||||||
|
|
||||||
// Get the value of the varargs token (aka argList).
|
// Get the value of the varargs token (aka argList).
|
||||||
IRNode *GenIR::argList() {
|
IRNode *GenIR::argList() {
|
||||||
ASSERT(HasVarargsToken);
|
ASSERT(HasVarargsToken);
|
||||||
|
@ -1305,11 +1322,12 @@ Type *GenIR::getClassType(CORINFO_CLASS_HANDLE ClassHandle, bool IsRefClass,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtain an LLVM function type from a method handle.
|
// Obtain an LLVM function type from a method handle.
|
||||||
FunctionType *GenIR::getFunctionType(CORINFO_METHOD_HANDLE Method) {
|
FunctionType *GenIR::getFunctionType(CORINFO_METHOD_HANDLE Method,
|
||||||
|
bool HasSecretParameter) {
|
||||||
CORINFO_SIG_INFO Sig;
|
CORINFO_SIG_INFO Sig;
|
||||||
getMethodSig(Method, &Sig);
|
getMethodSig(Method, &Sig);
|
||||||
CORINFO_CLASS_HANDLE Class = getMethodClass(Method);
|
CORINFO_CLASS_HANDLE Class = getMethodClass(Method);
|
||||||
FunctionType *Result = getFunctionType(Sig, Class);
|
FunctionType *Result = getFunctionType(Sig, Class, HasSecretParameter);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1318,7 +1336,8 @@ FunctionType *GenIR::getFunctionType(CORINFO_METHOD_HANDLE Method) {
|
||||||
// If the signature has an implicit 'this' parameter,
|
// If the signature has an implicit 'this' parameter,
|
||||||
// ThisClass must be passed in as the appropriate class handle.
|
// ThisClass must be passed in as the appropriate class handle.
|
||||||
FunctionType *GenIR::getFunctionType(CORINFO_SIG_INFO &Sig,
|
FunctionType *GenIR::getFunctionType(CORINFO_SIG_INFO &Sig,
|
||||||
CORINFO_CLASS_HANDLE ThisClass) {
|
CORINFO_CLASS_HANDLE ThisClass,
|
||||||
|
bool HasSecretParameter) {
|
||||||
CorInfoType ReturnType = Sig.retType;
|
CorInfoType ReturnType = Sig.retType;
|
||||||
CORINFO_CLASS_HANDLE ReturnClass = Sig.retTypeClass;
|
CORINFO_CLASS_HANDLE ReturnClass = Sig.retTypeClass;
|
||||||
Type *LLVMReturnType = this->getType(ReturnType, ReturnClass);
|
Type *LLVMReturnType = this->getType(ReturnType, ReturnClass);
|
||||||
|
@ -1355,9 +1374,8 @@ FunctionType *GenIR::getFunctionType(CORINFO_SIG_INFO &Sig,
|
||||||
bool HasTypeArg = Sig.hasTypeArg();
|
bool HasTypeArg = Sig.hasTypeArg();
|
||||||
|
|
||||||
if (HasTypeArg) {
|
if (HasTypeArg) {
|
||||||
CORINFO_CLASS_HANDLE Class = 0;
|
CORINFO_CLASS_HANDLE Class = nullptr;
|
||||||
Type *TypeArgType = getType(CORINFO_TYPE_NATIVEINT, Class);
|
Type *TypeArgType = getType(CORINFO_TYPE_NATIVEINT, Class);
|
||||||
|
|
||||||
Arguments.push_back(TypeArgType);
|
Arguments.push_back(TypeArgType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1371,6 +1389,12 @@ FunctionType *GenIR::getFunctionType(CORINFO_SIG_INFO &Sig,
|
||||||
Arguments.push_back(LLVMArgType);
|
Arguments.push_back(LLVMArgType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (HasSecretParameter) {
|
||||||
|
CORINFO_CLASS_HANDLE Class = nullptr;
|
||||||
|
Type *SecretParameterType = getType(CORINFO_TYPE_NATIVEINT, Class);
|
||||||
|
Arguments.push_back(SecretParameterType);
|
||||||
|
}
|
||||||
|
|
||||||
FunctionType *FunctionType =
|
FunctionType *FunctionType =
|
||||||
FunctionType::get(LLVMReturnType, Arguments, IsVarArg);
|
FunctionType::get(LLVMReturnType, Arguments, IsVarArg);
|
||||||
|
|
||||||
|
@ -3259,6 +3283,8 @@ IRNode *GenIR::genCall(ReaderCallTargetData *CallTargetInfo,
|
||||||
IRNode *TargetNode = CallTargetInfo->getCallTargetNode();
|
IRNode *TargetNode = CallTargetInfo->getCallTargetNode();
|
||||||
CORINFO_SIG_INFO *SigInfo = CallTargetInfo->getSigInfo();
|
CORINFO_SIG_INFO *SigInfo = CallTargetInfo->getSigInfo();
|
||||||
CORINFO_CALL_INFO *CallInfo = CallTargetInfo->getCallInfo();
|
CORINFO_CALL_INFO *CallInfo = CallTargetInfo->getCallInfo();
|
||||||
|
bool IsStubCall =
|
||||||
|
(CallInfo != nullptr) && (CallInfo->kind == CORINFO_VIRTUALCALL_STUB);
|
||||||
|
|
||||||
unsigned HiddenMBParamSize = 0;
|
unsigned HiddenMBParamSize = 0;
|
||||||
GCLayout *GCInfo = nullptr;
|
GCLayout *GCInfo = nullptr;
|
||||||
|
@ -3271,12 +3297,6 @@ IRNode *GenIR::genCall(ReaderCallTargetData *CallTargetInfo,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((CallInfo != nullptr) && (CallInfo->kind == CORINFO_VIRTUALCALL_STUB)) {
|
|
||||||
// VSD calls have a special calling convention that requires the pointer
|
|
||||||
// to the stub in a target-specific register.
|
|
||||||
throw NotYetImplementedException("virtual stub dispatch");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ask GenIR to create return value.
|
// Ask GenIR to create return value.
|
||||||
if (!CallTargetInfo->isNewObj()) {
|
if (!CallTargetInfo->isNewObj()) {
|
||||||
ReturnNode = makeCallReturnNode(SigInfo, &HiddenMBParamSize, &GCInfo);
|
ReturnNode = makeCallReturnNode(SigInfo, &HiddenMBParamSize, &GCInfo);
|
||||||
|
@ -3338,8 +3358,8 @@ IRNode *GenIR::genCall(ReaderCallTargetData *CallTargetInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
CallInst *CallInst = LLVMBuilder->CreateCall(TargetNode, Arguments);
|
CallInst *CallInst = LLVMBuilder->CreateCall(TargetNode, Arguments);
|
||||||
CorInfoIntrinsics IntrinsicID = CallTargetInfo->getCorInstrinsic();
|
|
||||||
|
|
||||||
|
CorInfoIntrinsics IntrinsicID = CallTargetInfo->getCorInstrinsic();
|
||||||
if ((0 <= IntrinsicID) && (IntrinsicID < CORINFO_INTRINSIC_Count)) {
|
if ((0 <= IntrinsicID) && (IntrinsicID < CORINFO_INTRINSIC_Count)) {
|
||||||
throw NotYetImplementedException("Call intrinsic");
|
throw NotYetImplementedException("Call intrinsic");
|
||||||
}
|
}
|
||||||
|
@ -3363,6 +3383,10 @@ IRNode *GenIR::genCall(ReaderCallTargetData *CallTargetInfo,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsStubCall) {
|
||||||
|
Call = canonStubCall(Call, CallTargetInfo);
|
||||||
|
}
|
||||||
|
|
||||||
if (ReturnNode != nullptr) {
|
if (ReturnNode != nullptr) {
|
||||||
return ReturnNode;
|
return ReturnNode;
|
||||||
}
|
}
|
||||||
|
@ -3401,7 +3425,7 @@ bool GenIR::canonNewObjCall(IRNode *CallNode,
|
||||||
if (IsArray) {
|
if (IsArray) {
|
||||||
// Zero-based, one-dimensional arrays are allocated via newarr;
|
// Zero-based, one-dimensional arrays are allocated via newarr;
|
||||||
// all other arrays are allocated via newobj
|
// all other arrays are allocated via newobj
|
||||||
canonNewArrayCall(CallNode, CallTargetData, OutResult);
|
*OutResult = canonNewArrayCall(CallNode, CallTargetData);
|
||||||
LLVMBuilder->SetInsertPoint(CurrentBlock, SavedInsertPoint);
|
LLVMBuilder->SetInsertPoint(CurrentBlock, SavedInsertPoint);
|
||||||
DoneBeingProcessed = true;
|
DoneBeingProcessed = true;
|
||||||
} else if (IsVarObjSize) {
|
} else if (IsVarObjSize) {
|
||||||
|
@ -3415,12 +3439,11 @@ bool GenIR::canonNewObjCall(IRNode *CallNode,
|
||||||
|
|
||||||
// Change the type of the called function and
|
// Change the type of the called function and
|
||||||
// the type of the CallInstruction.
|
// the type of the CallInstruction.
|
||||||
CallInst *CallInstruction = dyn_cast<CallInst>(CallNode);
|
CallInst *CallInstruction = cast<CallInst>(CallNode);
|
||||||
Value *CalledValue = CallInstruction->getCalledValue();
|
Value *CalledValue = CallInstruction->getCalledValue();
|
||||||
PointerType *CalledValueType =
|
PointerType *CalledValueType = cast<PointerType>(CalledValue->getType());
|
||||||
dyn_cast<PointerType>(CalledValue->getType());
|
|
||||||
FunctionType *FuncType =
|
FunctionType *FuncType =
|
||||||
dyn_cast<FunctionType>(CalledValueType->getElementType());
|
cast<FunctionType>(CalledValueType->getElementType());
|
||||||
|
|
||||||
// Construct the new function type.
|
// Construct the new function type.
|
||||||
std::vector<Type *> Arguments;
|
std::vector<Type *> Arguments;
|
||||||
|
@ -3488,9 +3511,8 @@ bool GenIR::canonNewObjCall(IRNode *CallNode,
|
||||||
return DoneBeingProcessed;
|
return DoneBeingProcessed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenIR::canonNewArrayCall(IRNode *Call,
|
IRNode *GenIR::canonNewArrayCall(IRNode *Call,
|
||||||
ReaderCallTargetData *CallTargetData,
|
ReaderCallTargetData *CallTargetData) {
|
||||||
IRNode **OutResult) {
|
|
||||||
CallInst *CallInstruction = dyn_cast<CallInst>(Call);
|
CallInst *CallInstruction = dyn_cast<CallInst>(Call);
|
||||||
Value *CalledValue = CallInstruction->getCalledValue();
|
Value *CalledValue = CallInstruction->getCalledValue();
|
||||||
PointerType *CalledValueType = dyn_cast<PointerType>(CalledValue->getType());
|
PointerType *CalledValueType = dyn_cast<PointerType>(CalledValue->getType());
|
||||||
|
@ -3543,18 +3565,63 @@ void GenIR::canonNewArrayCall(IRNode *Call,
|
||||||
LLVMBuilder->CreateCall(NewCalledValue, NewArguments);
|
LLVMBuilder->CreateCall(NewCalledValue, NewArguments);
|
||||||
CallInstruction->eraseFromParent();
|
CallInstruction->eraseFromParent();
|
||||||
|
|
||||||
*OutResult = (IRNode *)NewCallInstruction;
|
return (IRNode *)NewCallInstruction;
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GenIR::callIsCorVarArgs(IRNode *CallNode) {
|
bool GenIR::callIsCorVarArgs(IRNode *CallNode) {
|
||||||
CallInst *CallInstruction = dyn_cast<CallInst>(CallNode);
|
CallInst *CallInstruction = cast<CallInst>(CallNode);
|
||||||
Value *CalledValue = CallInstruction->getCalledValue();
|
Value *CalledValue = CallInstruction->getCalledValue();
|
||||||
PointerType *CalledValueType = dyn_cast<PointerType>(CalledValue->getType());
|
PointerType *CalledValueType = dyn_cast<PointerType>(CalledValue->getType());
|
||||||
return dyn_cast<FunctionType>(CalledValueType->getElementType())->isVarArg();
|
return dyn_cast<FunctionType>(CalledValueType->getElementType())->isVarArg();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IRNode *GenIR::canonStubCall(IRNode *CallNode,
|
||||||
|
ReaderCallTargetData *CallTargetData) {
|
||||||
|
assert(CallTargetData != nullptr);
|
||||||
|
assert(CallTargetData->getCallInfo() != nullptr &&
|
||||||
|
CallTargetData->getCallInfo()->kind == CORINFO_VIRTUALCALL_STUB);
|
||||||
|
|
||||||
|
CallInst *Call = cast<CallInst>(CallNode);
|
||||||
|
BasicBlock *CurrentBlock = Call->getParent();
|
||||||
|
|
||||||
|
BasicBlock::iterator SavedInsertPoint = LLVMBuilder->GetInsertPoint();
|
||||||
|
LLVMBuilder->SetInsertPoint(Call);
|
||||||
|
|
||||||
|
Value *Target = Call->getCalledValue();
|
||||||
|
PointerType *TargetType = cast<PointerType>(Target->getType());
|
||||||
|
FunctionType *TargetFuncType =
|
||||||
|
cast<FunctionType>(TargetType->getElementType());
|
||||||
|
|
||||||
|
// Construct the new function type.
|
||||||
|
std::vector<Type *> ArgumentTypes;
|
||||||
|
std::vector<Value *> Arguments;
|
||||||
|
|
||||||
|
Value *IndirectionCell = (Value *)CallTargetData->getIndirectionCellNode();
|
||||||
|
assert(IndirectionCell != nullptr);
|
||||||
|
|
||||||
|
ArgumentTypes.push_back(IndirectionCell->getType());
|
||||||
|
Arguments.push_back(IndirectionCell);
|
||||||
|
|
||||||
|
for (unsigned I = 0; I < TargetFuncType->getNumParams(); ++I) {
|
||||||
|
ArgumentTypes.push_back(TargetFuncType->getParamType(I));
|
||||||
|
Arguments.push_back(Call->getArgOperand(I));
|
||||||
|
}
|
||||||
|
|
||||||
|
FunctionType *FuncType =
|
||||||
|
FunctionType::get(TargetFuncType->getReturnType(), ArgumentTypes,
|
||||||
|
TargetFuncType->isVarArg());
|
||||||
|
|
||||||
|
Value *NewTarget =
|
||||||
|
LLVMBuilder->CreatePointerCast(Target, getUnmanagedPointerType(FuncType));
|
||||||
|
|
||||||
|
CallInst *NewCall = LLVMBuilder->CreateCall(NewTarget, Arguments);
|
||||||
|
NewCall->setCallingConv(CallingConv::CLR_VirtualDispatchStub);
|
||||||
|
Call->eraseFromParent();
|
||||||
|
|
||||||
|
LLVMBuilder->SetInsertPoint(CurrentBlock, SavedInsertPoint);
|
||||||
|
return (IRNode *)NewCall;
|
||||||
|
}
|
||||||
|
|
||||||
IRNode *GenIR::conv(ReaderBaseNS::ConvOpcode Opcode, IRNode *Arg1) {
|
IRNode *GenIR::conv(ReaderBaseNS::ConvOpcode Opcode, IRNode *Arg1) {
|
||||||
|
|
||||||
struct ConvertInfo {
|
struct ConvertInfo {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче