From 591e9575a639dfbfba3571e13879ea7b3b2bae27 Mon Sep 17 00:00:00 2001 From: Michael Holman Date: Wed, 7 Mar 2018 03:02:00 -0800 Subject: [PATCH] deps: update ChakraCore to Microsoft/ChakraCore@7cb85ae5e4 [1.8>1.9] [MERGE #4785 @MikeHolman] Different CRTs declare ceil/floor with different calling conventions, so use our own Merge pull request #4785 from MikeHolman:crtcdecl Previously we were assuming cdecl. And while this was true for floor, it was not true for floorf in the CRT version that ChakraFull uses. However, on the version of CRT I'm using with ChakraCore, floorf is cdecl. Because the calling convention is not reliable, I added methods in chakra for the JIT to call to ensure the calling convention is what we expect (at least for MSVC builds). Also, since it's our function now, we can use callee cleanup. Reviewed-By: chakrabot --- .../core/lib/Backend/JnHelperMethod.cpp | 120 +++++++----------- .../core/lib/Backend/LowerMDShared.cpp | 10 +- .../core/lib/Runtime/Base/ThreadContextInfo.h | 20 +++ .../core/lib/Runtime/Math/JavascriptMath.h | 5 + 4 files changed, 72 insertions(+), 83 deletions(-) diff --git a/deps/chakrashim/core/lib/Backend/JnHelperMethod.cpp b/deps/chakrashim/core/lib/Backend/JnHelperMethod.cpp index 23ceefc0a39..d6edf097f45 100644 --- a/deps/chakrashim/core/lib/Backend/JnHelperMethod.cpp +++ b/deps/chakrashim/core/lib/Backend/JnHelperMethod.cpp @@ -149,116 +149,88 @@ DECLSPEC_GUARDIGNORE _NOINLINE intptr_t GetNonTableMethodAddress(ThreadContextI // DllImport methods // #if defined(_M_IX86) - // TODO: OOP JIT, have some way to validate that these are all loaded from CRT + // These are internal CRT functions which don't use a standard calling convention case HelperDirectMath_Acos: - return ShiftAddr(context, (double(*)(double))__libm_sse2_acos); + return ShiftAddr(context, __libm_sse2_acos); case HelperDirectMath_Asin: - return ShiftAddr(context, (double(*)(double))__libm_sse2_asin); + return ShiftAddr(context, __libm_sse2_asin); case HelperDirectMath_Atan: - return ShiftAddr(context, (double(*)(double))__libm_sse2_atan); + return ShiftAddr(context, __libm_sse2_atan); case HelperDirectMath_Atan2: - return ShiftAddr(context, (double(*)(double, double))__libm_sse2_atan2); + return ShiftAddr(context, __libm_sse2_atan2); case HelperDirectMath_Cos: - return ShiftAddr(context, (double(*)(double))__libm_sse2_cos); + return ShiftAddr(context, __libm_sse2_cos); case HelperDirectMath_Exp: - return ShiftAddr(context, (double(*)(double))__libm_sse2_exp); + return ShiftAddr(context, __libm_sse2_exp); case HelperDirectMath_Log: - return ShiftAddr(context, (double(*)(double))__libm_sse2_log); + return ShiftAddr(context, __libm_sse2_log); case HelperDirectMath_Sin: - return ShiftAddr(context, (double(*)(double))__libm_sse2_sin); + return ShiftAddr(context, __libm_sse2_sin); case HelperDirectMath_Tan: - return ShiftAddr(context, (double(*)(double))__libm_sse2_tan); + return ShiftAddr(context, __libm_sse2_tan); #endif case HelperDirectMath_FloorDb: - return ShiftAddr(context, (double(*)(double))floor); + return ShiftStdcallAddr(context, Js::JavascriptMath::Floor); case HelperDirectMath_CeilDb: - return ShiftAddr(context, (double(*)(double))ceil); - - // - // These are statically initialized to an import thunk, but let's keep them out of the table in case a new CRT changes this - // - case HelperWMemCmp: - return ShiftAddr(context, (int(*)(const char16 *, const char16 *, size_t))wmemcmp); - - case HelperMemCpy: - return ShiftAddr(context, (void*(*)(void *, void const*, size_t))memcpy); + return ShiftStdcallAddr(context, Js::JavascriptMath::Ceil); case HelperDirectMath_FloorFlt: - return ShiftAddr(context, (float(*)(float))floorf); + return ShiftStdcallAddr(context, Js::JavascriptMath::FloorF); case HelperDirectMath_CeilFlt: - return ShiftAddr(context, (float(*)(float))ceilf); - -#if defined(_M_X64) - case HelperDirectMath_Acos: - return ShiftAddr(context, (double(*)(double))acos); + return ShiftStdcallAddr(context, Js::JavascriptMath::CeilF); - case HelperDirectMath_Asin: - return ShiftAddr(context, (double(*)(double))asin); - - case HelperDirectMath_Atan: - return ShiftAddr(context, (double(*)(double))atan); - - case HelperDirectMath_Atan2: - return ShiftAddr(context, (double(*)(double, double))atan2); - - case HelperDirectMath_Cos: - return ShiftAddr(context, (double(*)(double))cos); - - case HelperDirectMath_Exp: - return ShiftAddr(context, (double(*)(double))exp); - - case HelperDirectMath_Log: - return ShiftAddr(context, (double(*)(double))log); - - case HelperDirectMath_Sin: - return ShiftAddr(context, (double(*)(double))sin); + // + // These are statically initialized to an import thunk, but let's keep them out of the table in case a new CRT changes this + // + case HelperWMemCmp: + return ShiftCdeclAddr(context, wmemcmp); - case HelperDirectMath_Tan: - return ShiftAddr(context, (double(*)(double))tan); + case HelperMemCpy: + return ShiftCdeclAddr(context, (void *(__cdecl *)(void *, void const*, size_t))memcpy); -#elif defined(_M_ARM32_OR_ARM64) +#if defined(_M_X64) || defined(_M_ARM32_OR_ARM64) case HelperDirectMath_Acos: - return ShiftAddr(context, (double(*)(double))acos); + return ShiftCdeclAddr(context, (double(__cdecl *)(double))acos); case HelperDirectMath_Asin: - return ShiftAddr(context, (double(*)(double))asin); + return ShiftCdeclAddr(context, (double(__cdecl *)(double))asin); case HelperDirectMath_Atan: - return ShiftAddr(context, (double(*)(double))atan); + return ShiftCdeclAddr(context, (double(__cdecl *)(double))atan); case HelperDirectMath_Atan2: - return ShiftAddr(context, (double(*)(double, double))atan2); + return ShiftCdeclAddr(context, (double(__cdecl *)(double, double))atan2); case HelperDirectMath_Cos: - return ShiftAddr(context, (double(*)(double))cos); + return ShiftCdeclAddr(context, (double(__cdecl *)(double))cos); case HelperDirectMath_Exp: - return ShiftAddr(context, (double(*)(double))exp); + return ShiftCdeclAddr(context, (double(__cdecl *)(double))exp); case HelperDirectMath_Log: - return ShiftAddr(context, (double(*)(double))log); + return ShiftCdeclAddr(context, (double(__cdecl *)(double))log); case HelperDirectMath_Sin: - return ShiftAddr(context, (double(*)(double))sin); + return ShiftCdeclAddr(context, (double(__cdecl *)(double))sin); case HelperDirectMath_Tan: - return ShiftAddr(context, (double(*)(double))tan); + return ShiftCdeclAddr(context, (double(__cdecl *)(double))tan); #endif - // - // Methods that we don't want to get marked as CFG targets as they make unprotected calls - // + // + // Methods that we don't want to get marked as CFG targets as they make unprotected calls + // #ifdef _CONTROL_FLOW_GUARD case HelperGuardCheckCall: @@ -266,29 +238,29 @@ DECLSPEC_GUARDIGNORE _NOINLINE intptr_t GetNonTableMethodAddress(ThreadContextI #endif case HelperOp_TryCatch: - return ShiftAddr(context, Js::JavascriptExceptionOperators::OP_TryCatch); + return ShiftStdcallAddr(context, Js::JavascriptExceptionOperators::OP_TryCatch); case HelperOp_TryFinally: - return ShiftAddr(context, Js::JavascriptExceptionOperators::OP_TryFinally); + return ShiftStdcallAddr(context, Js::JavascriptExceptionOperators::OP_TryFinally); case HelperOp_TryFinallySimpleJit: - return ShiftAddr(context, Js::JavascriptExceptionOperators::OP_TryFinallySimpleJit); + return ShiftStdcallAddr(context, Js::JavascriptExceptionOperators::OP_TryFinallySimpleJit); - // - // Methods that we don't want to get marked as CFG targets as they dump all registers to a controlled address - // + // + // Methods that we don't want to get marked as CFG targets as they dump all registers to a controlled address + // case HelperSaveAllRegistersAndBailOut: - return ShiftAddr(context, LinearScanMD::SaveAllRegistersAndBailOut); + return ShiftStdcallAddr(context, LinearScanMD::SaveAllRegistersAndBailOut); case HelperSaveAllRegistersAndBranchBailOut: - return ShiftAddr(context, LinearScanMD::SaveAllRegistersAndBranchBailOut); + return ShiftStdcallAddr(context, LinearScanMD::SaveAllRegistersAndBranchBailOut); - #ifdef _M_IX86 +#ifdef _M_IX86 case HelperSaveAllRegistersNoSse2AndBailOut: - return ShiftAddr(context, LinearScanMD::SaveAllRegistersNoSse2AndBailOut); + return ShiftStdcallAddr(context, LinearScanMD::SaveAllRegistersNoSse2AndBailOut); case HelperSaveAllRegistersNoSse2AndBranchBailOut: - return ShiftAddr(context, LinearScanMD::SaveAllRegistersNoSse2AndBranchBailOut); - #endif + return ShiftStdcallAddr(context, LinearScanMD::SaveAllRegistersNoSse2AndBranchBailOut); +#endif } diff --git a/deps/chakrashim/core/lib/Backend/LowerMDShared.cpp b/deps/chakrashim/core/lib/Backend/LowerMDShared.cpp index e1b94f0ffa9..f937c27db38 100644 --- a/deps/chakrashim/core/lib/Backend/LowerMDShared.cpp +++ b/deps/chakrashim/core/lib/Backend/LowerMDShared.cpp @@ -7778,26 +7778,18 @@ void LowererMD::HelperCallForAsmMathBuiltin(IR::Instr* instr, IR::JnHelperMethod IR::Opnd * argOpnd = instr->UnlinkSrc1(); IR::JnHelperMethod helperMethod; - uint dwordCount; if (argOpnd->IsFloat32()) { helperMethod = helperMethodFloat; LoadFloatHelperArgument(instr, argOpnd); - dwordCount = 1; } else { helperMethod = helperMethodDouble; LoadDoubleHelperArgument(instr, argOpnd); - dwordCount = 2; } - instr->m_opcode = Js::OpCode::CALL; - - IR::HelperCallOpnd *helperCallOpnd = Lowerer::CreateHelperCallOpnd(helperMethod, this->lowererMDArch.GetHelperArgsCount(), m_func); - instr->SetSrc1(helperCallOpnd); - - this->lowererMDArch.LowerCall(instr, dwordCount); + ChangeToHelperCall(instr, helperMethod); } void LowererMD::GenerateFastInlineBuiltInCall(IR::Instr* instr, IR::JnHelperMethod helperMethod) { diff --git a/deps/chakrashim/core/lib/Runtime/Base/ThreadContextInfo.h b/deps/chakrashim/core/lib/Runtime/Base/ThreadContextInfo.h index 2412491090b..fd36f6d3eb8 100644 --- a/deps/chakrashim/core/lib/Runtime/Base/ThreadContextInfo.h +++ b/deps/chakrashim/core/lib/Runtime/Base/ThreadContextInfo.h @@ -142,6 +142,26 @@ class ThreadContextInfo }; +#pragma warning(push) +#pragma warning(error: 4440) +// MSVC will give warning C4440 in case of calling convention redefinition +template void EnsureStdcall(F*) { typedef F __stdcall* T; } +template void EnsureCdecl(F*) { typedef F __cdecl* T; } +#pragma warning(pop) +template +uintptr_t ShiftCdeclAddr(const ThreadContextInfo*const context, T* address) +{ + EnsureCdecl(address); + return ShiftAddr(context, (uintptr_t)address); +} + +template +uintptr_t ShiftStdcallAddr(const ThreadContextInfo*const context, T* address) +{ + EnsureStdcall(address); + return ShiftAddr(context, (uintptr_t)address); +} + template uintptr_t ShiftAddr(const ThreadContextInfo*const context, T* address) { diff --git a/deps/chakrashim/core/lib/Runtime/Math/JavascriptMath.h b/deps/chakrashim/core/lib/Runtime/Math/JavascriptMath.h index d57a33d3ab3..74727035d37 100644 --- a/deps/chakrashim/core/lib/Runtime/Math/JavascriptMath.h +++ b/deps/chakrashim/core/lib/Runtime/Math/JavascriptMath.h @@ -97,6 +97,11 @@ namespace Js static int32 ToInt32(double value); static int32 ToInt32_Full(Var aValue, ScriptContext* scriptContext); + // different CRT versions define these with different calling conventions, so use our own method to prevent these inconsistencies + static float FloorF(float val) { return floorf(val); } + static double Floor(double val) { return floor(val); } + static float CeilF(float val) { return ceilf(val); } + static double Ceil(double val) { return ceil(val); } private: static Var Add_FullHelper(Var aLeft, Var aRight, ScriptContext* scriptContext, JavascriptNumber* result, bool leftIsDead); static Var Add_FullHelper_Wrapper(Var aLeft, Var aRight, ScriptContext* scriptContext, JavascriptNumber* result, bool leftIsDead);