• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-341  評(píng)論-2670  文章-0  trackbacks-0
                為了讓編譯成x86后的代碼可以轉(zhuǎn)換成C++的函數(shù)指針,我們也必須處理成員對(duì)齊的事情。如果腳本里的結(jié)構(gòu)成員對(duì)齊跟C++不一致的話,會(huì)造成很多麻煩。下面是成員對(duì)齊的計(jì)算方法:

                一個(gè)類型有兩種屬性,一種是尺寸,另一種是對(duì)齊單位,可以分別用sizeof和__alignof來(lái)表示。

                1:對(duì)于基本類型(char、short、double等)T有__alignof(T) == sizeof(T)
                2:對(duì)于數(shù)組類型T[N]有__alignof(T[N]) == __alignof(T),sizeof(T[N]) == sizeof(T)×N
                3:對(duì)于結(jié)構(gòu)類型T=T1×T2×...×Tn,有__alignof(T) = max(__alignof(Ti)),sizeof(T) = align(offset(Tn)+sizeof(Tn) , __alignof(T))
                4:如果一個(gè)類型結(jié)構(gòu)T為空,那么sizeof(T) == __alignof(T) == 1

                offset(Tn)是第n個(gè)成員相對(duì)于T起始位置的偏移,而align(S,A)可以用如下代碼計(jì)算:
            1 VInt Align(VInt Offset , VInt Alignment)
            2 {
            3     if(Alignment==0)
            4     {
            5         Alignment=1;
            6     }
            7     return (Offset+Alignment-1)/Alignment*Alignment;
            8 }

                于是就剩下offset(Tn)了。有了Align之后就可以遞歸定義offset(Tn):
                offset(T1)=0
                offset(Ti)=align(offset(Ti-1)+sizeof(Ti-1) , __alignof(Ti))

                于是我們可以得到定理:
                1:sizeof(T) == 0 (mod __alignof(T))
                2:當(dāng)T=T1×T2×...×Tn中T1==T2==...==Tn的時(shí)候,T的結(jié)構(gòu)與T1[n]的結(jié)構(gòu)完全一致
                3:對(duì)于任意類型集合{T1 T2 ... Tn}有max(__alignof(Ti)) <= max(__alignof(基本類型集合))

                以上結(jié)論在VC++的缺省設(shè)置中有效,如果為一個(gè)struct強(qiáng)行指定了pack和__alignof,將使用另外的規(guī)則。

                為了證明以上式子,我寫了一段程序,通過(guò)上面的方法計(jì)算成員的sizeof、__alignof以及offset,最后跟C++的編譯結(jié)果互相驗(yàn)證:
             1 #include "..\..\..\..\VL++\Library\Platform\VL_Console.h"
             2 #include "..\..\..\..\VL++\Library\Script\JIT\Assembler\VL_JIT_MemberAlignment.h"
             3 
             4 using namespace vl;
             5 using namespace vl::jit::alignment;
             6 using namespace vl::platform;
             7 
             8 struct SubStructForTest
             9 {
            10     char Char;
            11     double Double;
            12     short Short;
            13     int Int;
            14 };
            15 
            16 struct StructForTest
            17 {
            18     SubStructForTest Sub;
            19     double Double[8];
            20     SubStructForTest Subs[10];
            21     char Char;
            22 };
            23 
            24 #define OFFSET_OF(TYPE,MEMBER) (VInt)(&((TYPE*)0)->MEMBER)
            25 
            26 void Main_Alignment()
            27 {
            28     VL_AutoPtr<VL_AlignStruct> SubStruct=new VL_AlignStruct;
            29     SubStruct->AddMember(new VL_AlignBasic(vabtAsciiChar));
            30     SubStruct->AddMember(new VL_AlignBasic(vabtDouble));
            31     SubStruct->AddMember(new VL_AlignBasic(vabtInt16));
            32     SubStruct->AddMember(new VL_AlignBasic(vabtInt32));
            33 
            34     VL_AutoPtr<VL_AlignStruct> Struct=new VL_AlignStruct;
            35     Struct->AddMember(SubStruct);
            36     Struct->AddMember(new VL_AlignArray(new VL_AlignBasic(vabtDouble),8));
            37     Struct->AddMember(new VL_AlignArray(SubStruct,10));
            38     Struct->AddMember(new VL_AlignBasic(vabtAsciiChar));
            39 
            40     GetConsole()->Write(VUnicodeString(SubStruct->GetMember(0).GetOffset())+L"\t"+VUnicodeString(OFFSET_OF(SubStructForTest,Char))+L"\r\n");
            41     GetConsole()->Write(VUnicodeString(SubStruct->GetMember(1).GetOffset())+L"\t"+VUnicodeString(OFFSET_OF(SubStructForTest,Double))+L"\r\n");
            42     GetConsole()->Write(VUnicodeString(SubStruct->GetMember(2).GetOffset())+L"\t"+VUnicodeString(OFFSET_OF(SubStructForTest,Short))+L"\r\n");
            43     GetConsole()->Write(VUnicodeString(SubStruct->GetMember(3).GetOffset())+L"\t"+VUnicodeString(OFFSET_OF(SubStructForTest,Int))+L"\r\n");
            44     GetConsole()->Write(VUnicodeString(SubStruct->GetSize())+L"\t"+VUnicodeString((VInt)sizeof(SubStructForTest))+L"\r\n");
            45     GetConsole()->Write(L"\t\n");
            46 
            47     GetConsole()->Write(VUnicodeString(Struct->GetMember(0).GetOffset())+L"\t"+VUnicodeString(OFFSET_OF(StructForTest,Sub))+L"\r\n");
            48     GetConsole()->Write(VUnicodeString(Struct->GetMember(1).GetOffset())+L"\t"+VUnicodeString(OFFSET_OF(StructForTest,Double))+L"\r\n");
            49     GetConsole()->Write(VUnicodeString(Struct->GetMember(2).GetOffset())+L"\t"+VUnicodeString(OFFSET_OF(StructForTest,Subs))+L"\r\n");
            50     GetConsole()->Write(VUnicodeString(Struct->GetMember(3).GetOffset())+L"\t"+VUnicodeString(OFFSET_OF(StructForTest,Char))+L"\r\n");
            51     GetConsole()->Write(VUnicodeString(Struct->GetSize())+L"\t"+VUnicodeString((VInt)sizeof(StructForTest))+L"\r\n");
            52 }

                最后是結(jié)果:

                vl::jit::alignment頭文件:
              1 /*******************************************************************************
              2 Vczh Library++ 2.0
              3 JIT::成員對(duì)齊
              4 開(kāi)發(fā)者:陳梓瀚
              5 
              6 接口:
              7 類:
              8 函數(shù):
              9 *******************************************************************************/
             10 
             11 #ifndef VL_JIT_MEMBERALIGNMENT
             12 #define VL_JIT_MEMBERALIGNMENT
             13 
             14 #include "..\..\..\Data\Data\VL_Data_Basic.h"
             15 #include "..\..\..\Data\Data\VL_Data_List.h"
             16 
             17 namespace vl
             18 {
             19     namespace jit
             20     {
             21         namespace alignment
             22         {
             23             using namespace collection;
             24 
             25             class VL_AlignType : public VL_Base
             26             {
             27             public:
             28                 typedef VL_AutoPtr<VL_AlignType>            Ptr;
             29                 typedef VL_AutoPtr<const VL_AlignType>        ConstPtr;
             30 
             31                 virtual VInt                    GetSize()const=0;
             32                 virtual VInt                    GetAlignment()const=0;
             33             };
             34 
             35             class VL_AlignMember : public VL_Base
             36             {
             37             protected:
             38                 VL_AlignType::Ptr                FType;
             39                 VInt                            FMinOffset;
             40             public:
             41                 typedef VL_List<VL_AlignMember , false>        List;
             42 
             43                 VL_AlignMember();
             44 
             45                 VL_AlignType::ConstPtr            GetType()const;
             46                 void                            SetType(VL_AlignType::Ptr Type);
             47                 VInt                            GetOffset()const;
             48                 void                            SetMinOffset(VInt MinOffset);
             49             };
             50 
             51             class VL_AlignArray : public VL_AlignType
             52             {
             53             protected:
             54                 VL_AlignType::Ptr                FType;
             55                 VInt                            FCount;
             56             public:
             57                 VL_AlignArray(VL_AlignType::Ptr Type , VInt Count);
             58 
             59                 VInt                            GetSize()const;
             60                 VInt                            GetAlignment()const;
             61                 VL_AlignType::ConstPtr            GetType()const;
             62                 VInt                            GetCount()const;
             63             };
             64 
             65             class VL_AlignStruct : public VL_AlignType
             66             {
             67             protected:
             68                 mutable VL_AlignMember::List    FMembers;
             69                 mutable VInt                    FSize;
             70                 mutable VInt                    FAlignment;
             71             public:
             72                 VL_AlignStruct();
             73 
             74                 VInt                            GetSize()const;
             75                 VInt                            GetAlignment()const;
             76                 void                            AddMember(VL_AlignType::Ptr Type);
             77                 void                            InsertMember(VInt Index , VL_AlignType::Ptr Type);
             78                 void                            DeleteMember(VInt Index);
             79                 VInt                            GetMemberCount()const;
             80                 const VL_AlignMember&            GetMember(VInt Index)const;
             81                 void                            Refresh()const;
             82             };
             83 
             84             enum VLE_AlignBasicType
             85             {
             86                 vabtInt8,
             87                 vabtInt16,
             88                 vabtInt32,
             89                 vabtAsciiChar,
             90                 vabtWideChar,
             91                 vabtFloat,
             92                 vabtDouble
             93             };
             94             class VL_AlignBasic : public VL_AlignType
             95             {
             96             protected:
             97                 VLE_AlignBasicType                FType;
             98             public:
             99                 VL_AlignBasic(VLE_AlignBasicType Type);
            100 
            101                 VInt                            GetSize()const;
            102                 VInt                            GetAlignment()const;
            103                 VLE_AlignBasicType                GetType()const;
            104             };
            105         }
            106     }
            107 }
            108 
            109 #endif

                實(shí)現(xiàn)文件:
              1 #include "VL_JIT_MemberAlignment.h"
              2 
              3 namespace vl
              4 {
              5     namespace jit
              6     {
              7         namespace alignment
              8         {
              9             VInt Align(VInt Offset , VInt Alignment)
             10             {
             11                 if(Alignment==0)
             12                 {
             13                     Alignment=1;
             14                 }
             15                 return (Offset+Alignment-1)/Alignment*Alignment;
             16             }
             17 
             18 /*********************************************************************************************************
             19 VL_AlignMember
             20 *********************************************************************************************************/
             21 
             22             VL_AlignMember::VL_AlignMember()
             23             {
             24                 FMinOffset=0;
             25             }
             26 
             27             VL_AlignType::ConstPtr VL_AlignMember::GetType()const
             28             {
             29                 return FType;
             30             }
             31 
             32             void VL_AlignMember::SetType(VL_AlignType::Ptr Type)
             33             {
             34                 FType=Type;
             35             }
             36 
             37             VInt VL_AlignMember::GetOffset()const
             38             {
             39                 return Align(FMinOffset,FType->GetAlignment());
             40             }
             41 
             42             void VL_AlignMember::SetMinOffset(VInt MinOffset)
             43             {
             44                 FMinOffset=MinOffset;
             45             }
             46 
             47 /*********************************************************************************************************
             48 VL_AlignArray
             49 *********************************************************************************************************/
             50 
             51             VL_AlignArray::VL_AlignArray(VL_AlignType::Ptr Type , VInt Count)
             52             {
             53                 FType=Type;
             54                 FCount=Count;
             55             }
             56 
             57             VInt VL_AlignArray::GetSize()const
             58             {
             59                 return FType->GetSize()*FCount;
             60             }
             61             
             62             VInt VL_AlignArray::GetAlignment()const
             63             {
             64                 return FType->GetAlignment();
             65             }
             66 
             67             VL_AlignType::ConstPtr VL_AlignArray::GetType()const
             68             {
             69                 return FType;
             70             }
             71 
             72             VInt VL_AlignArray::GetCount()const
             73             {
             74                 return FCount;
             75             }
             76 
             77 /*********************************************************************************************************
             78 VL_AlignStruct
             79 *********************************************************************************************************/
             80 
             81             VL_AlignStruct::VL_AlignStruct()
             82             {
             83                 Refresh();
             84             }
             85 
             86             VInt VL_AlignStruct::GetSize()const
             87             {
             88                 return FSize;
             89             }
             90 
             91             VInt VL_AlignStruct::GetAlignment()const
             92             {
             93                 return FAlignment;
             94             }
             95 
             96             void VL_AlignStruct::AddMember(VL_AlignType::Ptr Type)
             97             {
             98                 VL_AlignMember Member;
             99                 Member.SetType(Type);
            100                 FMembers.Add(Member);
            101                 Refresh();
            102             }
            103 
            104             void VL_AlignStruct::InsertMember(VInt Index , VL_AlignType::Ptr Type)
            105             {
            106                 VL_AlignMember Member;
            107                 Member.SetType(Type);
            108                 FMembers.Insert(Index,Member);
            109                 Refresh();
            110             }
            111 
            112             void VL_AlignStruct::DeleteMember(VInt Index)
            113             {
            114                 FMembers.Delete(Index);
            115                 Refresh();
            116             }
            117 
            118             VInt VL_AlignStruct::GetMemberCount()const
            119             {
            120                 return FMembers.GetCount();
            121             }
            122 
            123             const VL_AlignMember& VL_AlignStruct::GetMember(VInt Index)const
            124             {
            125                 return FMembers[Index];
            126             }
            127 
            128             void VL_AlignStruct::Refresh()const
            129             {
            130                 FSize=0;
            131                 FAlignment=0;
            132                 for(VInt i=0;i<FMembers.GetCount();i++)
            133                 {
            134                     if(FAlignment<FMembers[i].GetType()->GetAlignment())
            135                     {
            136                         FAlignment=FMembers[i].GetType()->GetAlignment();
            137                     }
            138                     FMembers[i].SetMinOffset(FSize);
            139                     FSize=FMembers[i].GetOffset()+FMembers[i].GetType()->GetSize();
            140                 }
            141                 FSize=Align(FSize,FAlignment);
            142                 if(FSize==0)
            143                 {
            144                     FAlignment=1;
            145                     FSize=1;
            146                 }
            147             }
            148 
            149 /*********************************************************************************************************
            150 VL_AlignBasic
            151 *********************************************************************************************************/
            152 
            153             VL_AlignBasic::VL_AlignBasic(VLE_AlignBasicType Type)
            154             {
            155                 FType=Type;
            156             }
            157 
            158             VInt VL_AlignBasic::GetSize()const
            159             {
            160                 switch(FType)
            161                 {
            162                 case vabtInt8:        return sizeof(VInt8s);
            163                 case vabtInt16:        return sizeof(VInt16s);
            164                 case vabtInt32:        return sizeof(VInt32s);
            165                 case vabtAsciiChar:    return sizeof(VChar);
            166                 case vabtWideChar:    return sizeof(VWChar);
            167                 case vabtFloat:        return sizeof(VFloat);
            168                 case vabtDouble:    return sizeof(VDouble);
            169                 default:            return 0;
            170                 }
            171             }
            172 
            173             VInt VL_AlignBasic::GetAlignment()const
            174             {
            175                 return GetSize();
            176             }
            177 
            178             VLE_AlignBasicType VL_AlignBasic::GetType()const
            179             {
            180                 return FType;
            181             }
            182         }
            183     }
            184 }
            posted on 2009-03-09 20:46 陳梓瀚(vczh) 閱讀(3746) 評(píng)論(2)  編輯 收藏 引用 所屬分類: JIT

            評(píng)論:
            # re: JIT腳本引擎:成員對(duì)齊詳解 2009-03-09 21:00 | jiong
            囧o(╯□╰)o  回復(fù)  更多評(píng)論
              
            # re: JIT腳本引擎:成員對(duì)齊詳解 2009-03-10 03:36 | 123
            強(qiáng)啊!  回復(fù)  更多評(píng)論
              
            久久久噜噜噜久久| 91精品国产综合久久精品| 久久伊人精品青青草原高清| 久久综合九色综合网站| 欧美性猛交xxxx免费看久久久 | 久久强奷乱码老熟女网站| 久久久久国产精品| 色综合久久88色综合天天| 久久99国产精一区二区三区| 777久久精品一区二区三区无码| 久久国产精品久久| 久久996热精品xxxx| 亚洲国产成人久久综合区| 人人妻久久人人澡人人爽人人精品| 无码人妻久久一区二区三区蜜桃| 久久国产免费直播| 奇米综合四色77777久久| 国产成人久久精品一区二区三区| 狠狠色丁香久久婷婷综| 久久国产综合精品五月天| 亚洲精品WWW久久久久久| 伊人久久大香线焦AV综合影院| 97精品久久天干天天天按摩| 久久精品一区二区国产| 久久精品国产欧美日韩| 囯产极品美女高潮无套久久久| 久久99精品久久久久久久不卡| 久久国产综合精品五月天| 99久久无色码中文字幕人妻| 久久精品国产亚洲一区二区| 久久性精品| 亚洲国产精品热久久| 亚洲人成无码www久久久| 国产精品久久精品| 久久99国产精品久久99小说 | 国产成人精品久久免费动漫| 精品久久久久久久久久中文字幕 | 精品久久久久中文字幕日本| 国产真实乱对白精彩久久| 久久亚洲精品无码VA大香大香 | 精品国产青草久久久久福利|