Skip to content

Commit ae56643

Browse files
committed
Different CRTs declare ceil/floor with different calling conventions, so use our own
1 parent e9f645e commit ae56643

File tree

4 files changed

+72
-83
lines changed

4 files changed

+72
-83
lines changed

lib/Backend/JnHelperMethod.cpp

Lines changed: 46 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -149,146 +149,118 @@ DECLSPEC_GUARDIGNORE _NOINLINE intptr_t GetNonTableMethodAddress(ThreadContextI
149149
// DllImport methods
150150
//
151151
#if defined(_M_IX86)
152-
// TODO: OOP JIT, have some way to validate that these are all loaded from CRT
152+
// These are internal CRT functions which don't use a standard calling convention
153153
case HelperDirectMath_Acos:
154-
return ShiftAddr(context, (double(*)(double))__libm_sse2_acos);
154+
return ShiftAddr(context, __libm_sse2_acos);
155155

156156
case HelperDirectMath_Asin:
157-
return ShiftAddr(context, (double(*)(double))__libm_sse2_asin);
157+
return ShiftAddr(context, __libm_sse2_asin);
158158

159159
case HelperDirectMath_Atan:
160-
return ShiftAddr(context, (double(*)(double))__libm_sse2_atan);
160+
return ShiftAddr(context, __libm_sse2_atan);
161161

162162
case HelperDirectMath_Atan2:
163-
return ShiftAddr(context, (double(*)(double, double))__libm_sse2_atan2);
163+
return ShiftAddr(context, __libm_sse2_atan2);
164164

165165
case HelperDirectMath_Cos:
166-
return ShiftAddr(context, (double(*)(double))__libm_sse2_cos);
166+
return ShiftAddr(context, __libm_sse2_cos);
167167

168168
case HelperDirectMath_Exp:
169-
return ShiftAddr(context, (double(*)(double))__libm_sse2_exp);
169+
return ShiftAddr(context, __libm_sse2_exp);
170170

171171
case HelperDirectMath_Log:
172-
return ShiftAddr(context, (double(*)(double))__libm_sse2_log);
172+
return ShiftAddr(context, __libm_sse2_log);
173173

174174
case HelperDirectMath_Sin:
175-
return ShiftAddr(context, (double(*)(double))__libm_sse2_sin);
175+
return ShiftAddr(context, __libm_sse2_sin);
176176

177177
case HelperDirectMath_Tan:
178-
return ShiftAddr(context, (double(*)(double))__libm_sse2_tan);
178+
return ShiftAddr(context, __libm_sse2_tan);
179179
#endif
180180

181181
case HelperDirectMath_FloorDb:
182-
return ShiftAddr(context, (double(*)(double))floor);
182+
return ShiftStdcallAddr(context, Js::JavascriptMath::Floor);
183183

184184
case HelperDirectMath_CeilDb:
185-
return ShiftAddr(context, (double(*)(double))ceil);
186-
187-
//
188-
// These are statically initialized to an import thunk, but let's keep them out of the table in case a new CRT changes this
189-
//
190-
case HelperWMemCmp:
191-
return ShiftAddr(context, (int(*)(const char16 *, const char16 *, size_t))wmemcmp);
192-
193-
case HelperMemCpy:
194-
return ShiftAddr(context, (void*(*)(void *, void const*, size_t))memcpy);
185+
return ShiftStdcallAddr(context, Js::JavascriptMath::Ceil);
195186

196187
case HelperDirectMath_FloorFlt:
197-
return ShiftAddr(context, (float(*)(float))floorf);
188+
return ShiftStdcallAddr(context, Js::JavascriptMath::FloorF);
198189

199190
case HelperDirectMath_CeilFlt:
200-
return ShiftAddr(context, (float(*)(float))ceilf);
201-
202-
#if defined(_M_X64)
203-
case HelperDirectMath_Acos:
204-
return ShiftAddr(context, (double(*)(double))acos);
191+
return ShiftStdcallAddr(context, Js::JavascriptMath::CeilF);
205192

206-
case HelperDirectMath_Asin:
207-
return ShiftAddr(context, (double(*)(double))asin);
208-
209-
case HelperDirectMath_Atan:
210-
return ShiftAddr(context, (double(*)(double))atan);
211-
212-
case HelperDirectMath_Atan2:
213-
return ShiftAddr(context, (double(*)(double, double))atan2);
214-
215-
case HelperDirectMath_Cos:
216-
return ShiftAddr(context, (double(*)(double))cos);
217-
218-
case HelperDirectMath_Exp:
219-
return ShiftAddr(context, (double(*)(double))exp);
220-
221-
case HelperDirectMath_Log:
222-
return ShiftAddr(context, (double(*)(double))log);
223-
224-
case HelperDirectMath_Sin:
225-
return ShiftAddr(context, (double(*)(double))sin);
193+
//
194+
// These are statically initialized to an import thunk, but let's keep them out of the table in case a new CRT changes this
195+
//
196+
case HelperWMemCmp:
197+
return ShiftCdeclAddr(context, wmemcmp);
226198

227-
case HelperDirectMath_Tan:
228-
return ShiftAddr(context, (double(*)(double))tan);
199+
case HelperMemCpy:
200+
return ShiftCdeclAddr(context, (void *(__cdecl *)(void *, void const*, size_t))memcpy);
229201

230-
#elif defined(_M_ARM32_OR_ARM64)
202+
#if defined(_M_X64) || defined(_M_ARM32_OR_ARM64)
231203
case HelperDirectMath_Acos:
232-
return ShiftAddr(context, (double(*)(double))acos);
204+
return ShiftCdeclAddr(context, (double(__cdecl *)(double))acos);
233205

234206
case HelperDirectMath_Asin:
235-
return ShiftAddr(context, (double(*)(double))asin);
207+
return ShiftCdeclAddr(context, (double(__cdecl *)(double))asin);
236208

237209
case HelperDirectMath_Atan:
238-
return ShiftAddr(context, (double(*)(double))atan);
210+
return ShiftCdeclAddr(context, (double(__cdecl *)(double))atan);
239211

240212
case HelperDirectMath_Atan2:
241-
return ShiftAddr(context, (double(*)(double, double))atan2);
213+
return ShiftCdeclAddr(context, (double(__cdecl *)(double, double))atan2);
242214

243215
case HelperDirectMath_Cos:
244-
return ShiftAddr(context, (double(*)(double))cos);
216+
return ShiftCdeclAddr(context, (double(__cdecl *)(double))cos);
245217

246218
case HelperDirectMath_Exp:
247-
return ShiftAddr(context, (double(*)(double))exp);
219+
return ShiftCdeclAddr(context, (double(__cdecl *)(double))exp);
248220

249221
case HelperDirectMath_Log:
250-
return ShiftAddr(context, (double(*)(double))log);
222+
return ShiftCdeclAddr(context, (double(__cdecl *)(double))log);
251223

252224
case HelperDirectMath_Sin:
253-
return ShiftAddr(context, (double(*)(double))sin);
225+
return ShiftCdeclAddr(context, (double(__cdecl *)(double))sin);
254226

255227
case HelperDirectMath_Tan:
256-
return ShiftAddr(context, (double(*)(double))tan);
228+
return ShiftCdeclAddr(context, (double(__cdecl *)(double))tan);
257229
#endif
258230

259-
//
260-
// Methods that we don't want to get marked as CFG targets as they make unprotected calls
261-
//
231+
//
232+
// Methods that we don't want to get marked as CFG targets as they make unprotected calls
233+
//
262234

263235
#ifdef _CONTROL_FLOW_GUARD
264236
case HelperGuardCheckCall:
265237
return (intptr_t)__guard_check_icall_fptr; // OOP JIT: ntdll load at same address across all process
266238
#endif
267239

268240
case HelperOp_TryCatch:
269-
return ShiftAddr(context, Js::JavascriptExceptionOperators::OP_TryCatch);
241+
return ShiftStdcallAddr(context, Js::JavascriptExceptionOperators::OP_TryCatch);
270242

271243
case HelperOp_TryFinally:
272-
return ShiftAddr(context, Js::JavascriptExceptionOperators::OP_TryFinally);
244+
return ShiftStdcallAddr(context, Js::JavascriptExceptionOperators::OP_TryFinally);
273245

274246

275247
case HelperOp_TryFinallySimpleJit:
276-
return ShiftAddr(context, Js::JavascriptExceptionOperators::OP_TryFinallySimpleJit);
248+
return ShiftStdcallAddr(context, Js::JavascriptExceptionOperators::OP_TryFinallySimpleJit);
277249

278-
//
279-
// Methods that we don't want to get marked as CFG targets as they dump all registers to a controlled address
280-
//
250+
//
251+
// Methods that we don't want to get marked as CFG targets as they dump all registers to a controlled address
252+
//
281253
case HelperSaveAllRegistersAndBailOut:
282-
return ShiftAddr(context, LinearScanMD::SaveAllRegistersAndBailOut);
254+
return ShiftStdcallAddr(context, LinearScanMD::SaveAllRegistersAndBailOut);
283255
case HelperSaveAllRegistersAndBranchBailOut:
284-
return ShiftAddr(context, LinearScanMD::SaveAllRegistersAndBranchBailOut);
256+
return ShiftStdcallAddr(context, LinearScanMD::SaveAllRegistersAndBranchBailOut);
285257

286-
#ifdef _M_IX86
258+
#ifdef _M_IX86
287259
case HelperSaveAllRegistersNoSse2AndBailOut:
288-
return ShiftAddr(context, LinearScanMD::SaveAllRegistersNoSse2AndBailOut);
260+
return ShiftStdcallAddr(context, LinearScanMD::SaveAllRegistersNoSse2AndBailOut);
289261
case HelperSaveAllRegistersNoSse2AndBranchBailOut:
290-
return ShiftAddr(context, LinearScanMD::SaveAllRegistersNoSse2AndBranchBailOut);
291-
#endif
262+
return ShiftStdcallAddr(context, LinearScanMD::SaveAllRegistersNoSse2AndBranchBailOut);
263+
#endif
292264

293265
}
294266

lib/Backend/LowerMDShared.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8580,26 +8580,18 @@ void LowererMD::HelperCallForAsmMathBuiltin(IR::Instr* instr, IR::JnHelperMethod
85808580

85818581
IR::Opnd * argOpnd = instr->UnlinkSrc1();
85828582
IR::JnHelperMethod helperMethod;
8583-
uint dwordCount;
85848583
if (argOpnd->IsFloat32())
85858584
{
85868585
helperMethod = helperMethodFloat;
85878586
LoadFloatHelperArgument(instr, argOpnd);
8588-
dwordCount = 1;
85898587
}
85908588
else
85918589
{
85928590
helperMethod = helperMethodDouble;
85938591
LoadDoubleHelperArgument(instr, argOpnd);
8594-
dwordCount = 2;
85958592
}
85968593

8597-
instr->m_opcode = Js::OpCode::CALL;
8598-
8599-
IR::HelperCallOpnd *helperCallOpnd = Lowerer::CreateHelperCallOpnd(helperMethod, this->lowererMDArch.GetHelperArgsCount(), m_func);
8600-
instr->SetSrc1(helperCallOpnd);
8601-
8602-
this->lowererMDArch.LowerCall(instr, dwordCount);
8594+
ChangeToHelperCall(instr, helperMethod);
86038595
}
86048596
void LowererMD::GenerateFastInlineBuiltInCall(IR::Instr* instr, IR::JnHelperMethod helperMethod)
86058597
{

lib/Runtime/Base/ThreadContextInfo.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,26 @@ class ThreadContextInfo
142142

143143
};
144144

145+
#pragma warning(push)
146+
#pragma warning(error: 4440)
147+
// MSVC will give warning C4440 in case of calling convention redefinition
148+
template<typename F> void EnsureStdcall(F*) { typedef F __stdcall* T; }
149+
template<typename F> void EnsureCdecl(F*) { typedef F __cdecl* T; }
150+
#pragma warning(pop)
151+
template<typename T>
152+
uintptr_t ShiftCdeclAddr(const ThreadContextInfo*const context, T* address)
153+
{
154+
EnsureCdecl(address);
155+
return ShiftAddr(context, (uintptr_t)address);
156+
}
157+
158+
template<typename T>
159+
uintptr_t ShiftStdcallAddr(const ThreadContextInfo*const context, T* address)
160+
{
161+
EnsureStdcall(address);
162+
return ShiftAddr(context, (uintptr_t)address);
163+
}
164+
145165
template<typename T>
146166
uintptr_t ShiftAddr(const ThreadContextInfo*const context, T* address)
147167
{

lib/Runtime/Math/JavascriptMath.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@ namespace Js
9797
static int32 ToInt32(double value);
9898
static int32 ToInt32_Full(Var aValue, ScriptContext* scriptContext);
9999

100+
// different CRT versions define these with different calling conventions, so use our own method to prevent these inconsistencies
101+
static float FloorF(float val) { return floorf(val); }
102+
static double Floor(double val) { return floor(val); }
103+
static float CeilF(float val) { return ceilf(val); }
104+
static double Ceil(double val) { return ceil(val); }
100105
private:
101106
static Var Add_FullHelper(Var aLeft, Var aRight, ScriptContext* scriptContext, JavascriptNumber* result, bool leftIsDead);
102107
static Var Add_FullHelper_Wrapper(Var aLeft, Var aRight, ScriptContext* scriptContext, JavascriptNumber* result, bool leftIsDead);

0 commit comments

Comments
 (0)