对于使用C#实现的.Net Framework部分,最容易使用
http://referencesource.microsoft.com/进行审查。 对于其他部分,您需要下载SSCLI的副本或在GitHub上
浏览coreclr存储库。
曾经出版了一本
免费电子书,试图解释SSCLI2的许多内部工作原理,它是.Net 2的精简版本。
InternalCall
由运行时使用在coreclr中定义的映射处理{{link4:文件
ecalllist.h
},或者在sscli中的
ecall.cpp
中。例如,Math.Round被映射为:
// snip
FCFuncStart(gMathFuncs)
FCIntrinsic("Sin", COMDouble::Sin, CORINFO_INTRINSIC_Sin)
FCIntrinsic("Cos", COMDouble::Cos, CORINFO_INTRINSIC_Cos)
FCIntrinsic("Sqrt", COMDouble::Sqrt, CORINFO_INTRINSIC_Sqrt)
FCIntrinsic("Round", COMDouble::Round, CORINFO_INTRINSIC_Round)
// snip
如果我们查看类
COMDouble
,其实现可以在
comfloat.cpp
中找到
(链接),我们将看到
Math.Round
背后的代码:
/*====================================Round=====================================
**
==============================================================================*/
FCIMPL1_V(double, COMDouble::Round, double x)
FCALL_CONTRACT;
// If the number has no fractional part do nothing
// This shortcut is necessary to workaround precision loss in borderline cases on some platforms
if (x == (double)((INT64)x)) {
return x;
}
// We had a number that was equally close to 2 integers.
// We need to return the even one.
double tempVal = (x + 0.5);
double flrTempVal = floor(tempVal);
if ((flrTempVal == tempVal) && (fmod(tempVal, 2.0)
flrTempVal -= 1.0;
}
return _copysign(flrTempVal, x);
FCIMPLEND
Math.Round
调用了不在参考源代码中的“内部”实现。 - D Stanleyecalllist.h
中(https://github.com/dotnet/coreclr/blob/master/src/vm/ecalllist.h#L1241),而Math.Round是在[`COMDouble :: Round`](https://github.com/dotnet/coreclr/blob/32f0f9721afb584b4a14d69135bea7ddc129f755/src/classlibnative/float/floatdouble.cpp#L201) 中实现的。 - Mitch