From ef1e2ab328087c61a6878c1e84f4fc5d710aebce Mon Sep 17 00:00:00 2001 From: dotnet-bot Date: Fri, 30 Jan 2015 14:14:42 -0800 Subject: Initial commit to populate CoreCLR repo [tfs-changeset: 1407945] --- src/vm/clrvarargs.cpp | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 src/vm/clrvarargs.cpp (limited to 'src/vm/clrvarargs.cpp') diff --git a/src/vm/clrvarargs.cpp b/src/vm/clrvarargs.cpp new file mode 100644 index 0000000000..8411f6be1b --- /dev/null +++ b/src/vm/clrvarargs.cpp @@ -0,0 +1,115 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// +// +// File: CLRVarArgs.cpp +// + +// +// Variant-specific marshalling. + + +#include "common.h" +#include "clrvarargs.h" + +DWORD VARARGS::CalcVaListSize(VARARGS *data) +{ + LIMITED_METHOD_CONTRACT; + + // Calculate how much space we need for the marshaled stack. + // This assumes that the vararg managed and unmanaged calling conventions are similar-enough, + // so we can simply use the size stored in the VASigCookie. This actually overestimates + // the value since it counts the fixed args as well as the varargs. But that's harmless. + + DWORD dwVaListSize = data->ArgCookie->sizeOfArgs; +#ifndef _TARGET_X86_ + dwVaListSize += ARGUMENTREGISTERS_SIZE; +#endif + return dwVaListSize; +} + +void VARARGS::MarshalToManagedVaList(va_list va, VARARGS *dataout) +{ + WRAPPER_NO_CONTRACT + + _ASSERTE(dataout != NULL); + dataout->SigPtr = SigPointer(NULL, 0); + dataout->ArgCookie = NULL; + dataout->ArgPtr = (BYTE*)va; +} + +//////////////////////////////////////////////////////////////////////////////// +// Marshal a ArgIterator to a pre-allocated va_list +//////////////////////////////////////////////////////////////////////////////// +void +VARARGS::MarshalToUnmanagedVaList( + va_list va, DWORD cbVaListSize, const VARARGS * data) +{ + BYTE * pdstbuffer = (BYTE *)va; + + int remainingArgs = data->RemainingArgs; + BYTE * psrc = (BYTE *)(data->ArgPtr); + BYTE * pdst = pdstbuffer; + + SigPointer sp = data->SigPtr; + SigTypeContext typeContext; // This is an empty type context. This is OK because the vararg methods may not be generic + while (remainingArgs--) + { + CorElementType elemType = sp.PeekElemTypeClosed(data->ArgCookie->pModule, &typeContext); + switch (elemType) + { + case ELEMENT_TYPE_I1: + case ELEMENT_TYPE_U1: + case ELEMENT_TYPE_I2: + case ELEMENT_TYPE_U2: + case ELEMENT_TYPE_I4: + case ELEMENT_TYPE_U4: + case ELEMENT_TYPE_I8: + case ELEMENT_TYPE_U8: + case ELEMENT_TYPE_R4: + case ELEMENT_TYPE_R8: + case ELEMENT_TYPE_I: + case ELEMENT_TYPE_U: + case ELEMENT_TYPE_PTR: + { + DWORD cbSize = StackElemSize(CorTypeInfo::Size(elemType)); + + #ifdef ENREGISTERED_PARAMTYPE_MAXSIZE + if (cbSize > ENREGISTERED_PARAMTYPE_MAXSIZE) + cbSize = sizeof(void*); + #endif + +#ifdef _TARGET_ARM_ + if (cbSize == 8) + { + // 64-bit primitives come from and must be copied to 64-bit aligned locations. + psrc = (BYTE*)ALIGN_UP(psrc, 8); + pdst = (BYTE*)ALIGN_UP(pdst, 8); + } +#endif // _TARGET_ARM_ + + #ifdef STACK_GROWS_DOWN_ON_ARGS_WALK + psrc -= cbSize; + #endif // STACK_GROWS_DOWN_ON_ARGS_WALK + + if (pdst + cbSize > pdstbuffer + cbVaListSize) + COMPlusThrow(kArgumentException); + + CopyMemory(pdst, psrc, cbSize); + + #ifdef STACK_GROWS_UP_ON_ARGS_WALK + psrc += cbSize; + #endif // STACK_GROWS_UP_ON_ARGS_WALK + + pdst += cbSize; + IfFailThrow(sp.SkipExactlyOne()); + } + break; + + default: + // non-IJW data type - we don't support marshaling these inside a va_list. + COMPlusThrow(kNotSupportedException); + } + } +} // VARARGS::MarshalToUnmanagedVaList -- cgit v1.2.3