From ce2fe515e3cf2b054d9f68bdf976a86282dcea7f Mon Sep 17 00:00:00 2001 From: jashook Date: Fri, 8 Jun 2018 10:57:33 -0700 Subject: [PATCH] Enable NativeVarargs for CoreCLR This will allow coreclr run programs which have native varargs. It also re-enables the ArgIterator type for managed to managed native vararg calls. This will allow the use of the __arglist keyword. Limitations: NYI statements have been added for all Unix Targets. With this change __arglist (native varargs) will be supported, but not yet tested on: Amd64 Windows x86 Windows Arm32 Windows Arm64 Windows This change does not re-enable native vararg tests. This will be done in a seperate change. --- .../src/System/ArgIterator.cs | 50 ------------------- src/jit/lclvars.cpp | 12 +++++ src/jit/morph.cpp | 12 +++++ src/vm/callingconvention.h | 5 +- src/vm/jitinterface.cpp | 7 --- 5 files changed, 26 insertions(+), 60 deletions(-) diff --git a/src/System.Private.CoreLib/src/System/ArgIterator.cs b/src/System.Private.CoreLib/src/System/ArgIterator.cs index 67e549c9dc67..72108db0622c 100644 --- a/src/System.Private.CoreLib/src/System/ArgIterator.cs +++ b/src/System.Private.CoreLib/src/System/ArgIterator.cs @@ -27,7 +27,6 @@ public ref struct ArgIterator private IntPtr ArgPtr; // Pointer to remaining args. private int RemainingArgs; // # of remaining args. -#if VARARGS_ENABLED //The JIT doesn't support Varargs calling convention. [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern ArgIterator(IntPtr arglist); @@ -132,54 +131,5 @@ public override bool Equals(Object o) { throw new NotSupportedException(SR.NotSupported_NYI); } -#else - public ArgIterator(RuntimeArgumentHandle arglist) - { - throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/coreclr/issues/9204 - } - - [CLSCompliant(false)] - public unsafe ArgIterator(RuntimeArgumentHandle arglist, void* ptr) - { - throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/coreclr/issues/9204 - } - - public void End() - { - throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/coreclr/issues/9204 - } - - public override bool Equals(Object o) - { - throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/coreclr/issues/9204 - } - - public override int GetHashCode() - { - throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/coreclr/issues/9204 - } - - [System.CLSCompliantAttribute(false)] - public System.TypedReference GetNextArg() - { - throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/coreclr/issues/9204 - } - - [System.CLSCompliantAttribute(false)] - public System.TypedReference GetNextArg(System.RuntimeTypeHandle rth) - { - throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/coreclr/issues/9204 - } - - public unsafe System.RuntimeTypeHandle GetNextArgType() - { - throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/coreclr/issues/9204 - } - - public int GetRemainingCount() - { - throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/coreclr/issues/9204 - } -#endif //VARARGS_ENABLED } } diff --git a/src/jit/lclvars.cpp b/src/jit/lclvars.cpp index 19dadfca0947..6bb7ff5009b3 100644 --- a/src/jit/lclvars.cpp +++ b/src/jit/lclvars.cpp @@ -598,6 +598,18 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo) isHfaArg = varTypeIsFloating(hfaType); } } + else if (info.compIsVarArgs) + { +#ifdef _TARGET_UNIX_ + // Currently native varargs is not implemented on non windows targets. + // + // Note that some targets like Arm64 Unix should not need much work as + // the ABI is the same. While other targets may only need small changes + // such as amd64 Unix, which just expects RAX to pass numFPArguments. + NYI("InitUserArgs for Vararg callee is not yet implemented on non Windows targets."); +#endif + } + if (isHfaArg) { // We have an HFA argument, so from here on out treat the type as a float or double. diff --git a/src/jit/morph.cpp b/src/jit/morph.cpp index 37bc2f3751ca..e02585d07d8a 100644 --- a/src/jit/morph.cpp +++ b/src/jit/morph.cpp @@ -2742,6 +2742,18 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* call) bool callIsVararg = call->IsVarargs(); #endif +#ifdef _TARGET_UNIX_ + if (callIsVararg) + { + // Currently native varargs is not implemented on non windows targets. + // + // Note that some targets like Arm64 Unix should not need much work as + // the ABI is the same. While other targets may only need small changes + // such as amd64 Unix, which just expects RAX to pass numFPArguments. + NYI("Morhing Vararg call not yet implemented on non Windows targets."); + } +#endif + #ifdef UNIX_AMD64_ABI // If fgMakeOutgoingStructArgCopy is called and copies are generated, hasStackArgCopy is set // to make sure to call EvalArgsToTemp. fgMakeOutgoingStructArgCopy just marks the argument diff --git a/src/vm/callingconvention.h b/src/vm/callingconvention.h index a0d7bd4fa02c..8a33b4a67c41 100644 --- a/src/vm/callingconvention.h +++ b/src/vm/callingconvention.h @@ -417,11 +417,10 @@ class ArgIteratorTemplate : public ARGITERATOR_BASE #ifdef _TARGET_AMD64_ #ifdef UNIX_AMD64_ABI - PORTABILITY_ASSERT("ArgIteratorTemplate::IsVarArgPassedByRef"); return FALSE; -#else // UNIX_AMD64_ABI +#else // !UNIX_AMD64_ABI return IsArgPassedByRef(size); -#endif // UNIX_AMD64_ABI +#endif // !UNIX_AMD64_ABI #else return (size > ENREGISTERED_PARAMTYPE_MAXSIZE); diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp index ff8a89d26fc6..0024590fc501 100644 --- a/src/vm/jitinterface.cpp +++ b/src/vm/jitinterface.cpp @@ -489,13 +489,6 @@ CEEInfo::ConvToJitSig( IfFailThrow(sig.GetCallingConvInfo(&data)); sigRet->callConv = (CorInfoCallConv) data; - if ((isCallConv(sigRet->callConv, IMAGE_CEE_CS_CALLCONV_VARARG)) || - (isCallConv(sigRet->callConv, IMAGE_CEE_CS_CALLCONV_NATIVEVARARG))) - { - // This signature corresponds to a method that uses varargs, which are not supported. - COMPlusThrow(kInvalidProgramException, IDS_EE_VARARG_NOT_SUPPORTED); - } - // Skip number of type arguments if (sigRet->callConv & IMAGE_CEE_CS_CALLCONV_GENERIC) IfFailThrow(sig.GetData(NULL));