繁体   English   中英

如何生成C#中的多维数组的源代码

[英]How is the source code for multidimensional array in C# generated

例如,我们有一个double[,] d = new double[1,2];维数组double[,] d = new double[1,2];

d.GetType()返回{Name = "Double[,]" FullName = "System.Double[,]"}

d[0,0]被编译为call instance float64 float64[0..., 0...]::Get(int32, int32) IL

如何生成System.Double[,]类型的源代码? 它是在CLR中烘焙还是Roslyn负责它的产生?

您正在寻找的是arraynative.cpparraynative.h

Array.cs开始:

public unsafe Object GetValue(params int[] indices)

使用

fixed(int* pIndices = indices)
    InternalGetReference(&elemref, indices.Length, pIndices);

InternalGetReference()位置(同一文件):

[MethodImplAttribute(MethodImplOptions.InternalCall)]
// reference to TypedReference is banned, so have to pass result as pointer
private unsafe extern void InternalGetReference(void * elemRef, int rank, int * pIndices);

MethodImplOptions.InternalCallecalllist.h中定义(记住这个文件......它包含所有的MethodImplOptions.InternalCall ,所以它非常有用)(如果你不记得文件名,你可以简单地搜索InternalGetReference在github中...包含该单词的文件不多:):

FCFuncElement("InternalGetReference", ArrayNative::GetReference)

所以你必须寻找ArrayNative ,这是我链接的两个文件。

CLR以特殊方式处理数组类型(包括一维和多维数组,每种都以不同的特殊方式)。 对于多维数组,所有Roslyn都会call Get()方法,CLR会处理其余的数组。

CLR究竟做了什么是非常复杂的(至少对我来说似乎是这样),但我相信最相关的部分始于Lowering::LowerArrElem

最终的结果是像这样的方法:

[MethodImpl(MethodImplOptions.NoInlining)]
private static double Get(double[,] d)
{
    return d[0, 0];
}

编译到这个x64代码(评论我的):

// stack pointer adjustment, not interesting
sub         rsp,28h  

// eax = 0
xor         eax,eax  

// range check first dimension against eax
sub         eax,dword ptr [rcx+18h]  
cmp         eax,dword ptr [rcx+10h]  
jae         00007FFD0A554521  

// edx = 0
xor         edx,edx  

// range check second dimension against edx
sub         edx,dword ptr [rcx+1Ch]  
cmp         edx,dword ptr [rcx+14h]  
jae         00007FFD0A554521  

// compute item offset
mov         r8d,dword ptr [rcx+14h]  
imul        r8,rax  
mov         rax,rdx  
add         rax,r8  

// load result into xmm0
movsd       xmm0,mmword ptr [rcx+rax*8+20h]  

// stack pointer adjustment, not interesting
add         rsp,28h  

// return
ret

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM