Lua5.2.3源码阅读(1)-TValue,TString

来源:互联网 发布:信佑linux无盘 编辑:程序博客网 时间:2024/06/01 07:15

转载:http://blog.csdn.net/murisly/article/details/46848897

Lua是一个弱类型语言,类型可以在使用的时候变化。对应在源码中,TVable就充当了这个角色,lua中的所有数据类型都可以放在这个结构中。TValue是实现Lua数据类型的主要结构,不仅在脚本中使用了TValue,其他的一些数据结构也依赖于它。首先看看Lua的整个数据类型(lua.h)

#define LUA_TNONE (-1)#define LUA_TNIL 0#define LUA_TBOOLEAN 1#define LUA_TLIGHTUSERDATA 2#define LUA_TNUMBER 3#define LUA_TSTRING 4#define LUA_TTABLE 5#define LUA_TFUNCTION 6#define LUA_TUSERDATA 7 //(自定义的用户数据结构,有Light和Heavy两种,后者由Lua来分配管理,用GC)#define LUA_TTHREAD 8 //(线程,CoRoutine)#define LUA_NUMTAGS 9

从这里可以看出lua中有9中数据类型,其中有8种是和脚本中对应的,现在来看看TValue这个结构。

<code class="hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#define TValuefields    Value value_; int tt_  ①</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#undef TValuefields</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>/* little endian */<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#define TValuefields  \</span>    union { struct { Value v__; int tt__; } i; double d__; } u ②<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>/* big endian */<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#define TValuefields  \</span>    union { struct { int tt__; Value v__; } i; double d__; } u ③<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>struct lua_TValue {  TValuefields;};<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>typedef struct lua_TValue TValue;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li></ul>

在使用的这台x86机器上,使用的是定义②。因为#undef TValuefields,定义①在后面失效。定义②中用到了 Value,在来看看Value这个结构。

<code class="hljs d has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">typedef</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">union</span> Value Value;...<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">union</span> Value {  GCObject *gc;    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* collectable objects 可以gc的数据类型,*/</span>  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> *p;         <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* light userdata 轻量用户数据*/</span>  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> b;           <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* booleans */</span>  lua_CFunction f; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* light C functions */</span>  numfield         <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* numbers暂时无用 */</span>};</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>

Value中包含了数据结构GCObject和三种数据类型,先看看这里GCObject这个结构

<code class="hljs d has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">union</span> GCObject {  GCheader gch;       <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* common header */</span>  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">union</span> TString ts;  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//string类型</span>  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">union</span> Udata u;         <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//用户数据</span>  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">union</span> Closure cl;  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//闭包</span>  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> Table h;    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//表</span>  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> Proto p;    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//函数字节码结构</span>  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> UpVal uv;   <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//闭包数据</span>  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> lua_State th;  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* thread 线程(协同)*/</span>};</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul>

其中GCheader如下

typedef struct GCheader { 
CommonHeader; 
} GCheader;

monHeader是一个宏,定义如下。

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#<span class="hljs-keyword" style="box-sizing: border-box;">define</span> CommonHeader    GCObject *next; lu_byte tt; lu_byte marked </span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

*next将所有回收的对象连成一个链表,tt表示了对象的类型,marked表示当前的回收状态。通过tt可以确定当前需要访问那个类型的值,通过marked可以确定该对象是否可以被回收。

<code class="hljs d has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> lua_TValue {  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">union</span>   {    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span>     {        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">union</span> Value        {         <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">union</span> GCObject {           GCObject *next;            lu_byte tt;            lu_byte marked            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">union</span> TString ts;  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//string类型</span>           <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">union</span> Udata u;       <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//用户数据</span>           <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">union</span> Closure cl;    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//闭包</span>           <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> Table h;     <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//表</span>           <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> Proto p;     <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//函数字节码结构</span>           <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> UpVal uv;  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//闭包数据</span>           <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> lua_State th;  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* thread 线程(协同)*/</span>         } *gc;         <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> *p;         <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* light userdata 轻量用户数据*/</span>         <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> b;           <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* booleans */</span>         lua_CFunction f;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* light C functions */</span>         numfield         <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* numbers暂时无用 */</span>       } v__;       <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> tt__;   <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*数据类型*/</span>     } i;      <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">double</span> d__;   } u};</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li></ul>

其中tt__是数据类型,如果数据类型是NUM,那么值直接存在d__中,如果是其他类型,就放在value中。Value中有GCObject,这是一个可回收的结构。CommonHeader头中包含了回收对象链,数据类型tt,和标记状态marked。GCObject 采用了union的结构,可以表示不同的值,而这些值,都有CommonHeader作为头部。这样的处理方式,使得在访问GCObject头部时,设定头部值后,里面的所有联合体访问的都是这个头部。 
Lua语句

下面来看看TString这个结构,其定义如下

<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">typedef</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">union</span> TString {  L_Umaxalign dummy;  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* ensures maximum alignment for strings 用于最大字节对齐,这里起占位作用*/</span>  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> {    CommonHeader;  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//用于gc处理的头</span>    lu_byte extra;  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* reserved words for short strings; "has hash" for longs 字符串是不是保留字符串*/</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> hash; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//记录字符串对应的hash值</span>    size_t len;  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* number of characters in string 字符串长度*/</span>  } tsv;} TString;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>

可以看出STring是个union,第一个成员主要是占用,用于字节对其。第二个成员是string主体,前面依然是CommonHeader,即STring也是可以gc的对象。在lua中,分为长字符串和段字符串。长度小于40的是短字符串,大于40的是长字符串(在luaconf.h中的LUAI_MAXSHORTLEN中定义)。短字符串存放在global_State->strt中,长字符串放在gc链上。下面是创建字符串用到的函数

<code class="hljs rust has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">TString *luaS_newlstr (lua_State *L, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> *<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span>, size_t l) {  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (l <= LUAI_MAXSHORTLEN)  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* short string? */</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> internshrstr(L, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span>, l);  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (l + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> > (MAX_SIZET - sizeof(TString))/sizeof(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span>))      luaM_toobig(L);    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> createstrobj(L, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span>, l, LUA_TLNGSTR, G(L)->seed, NULL);  }}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>

对于短字符串,在创建的时候,首先计算str的hash值。计算时会获得一个随机种子,这个种子就是global_State->seed。然后通过LUAI_HASHLIMIT控制步长,每一个步长范围内取字符串中的一个字符,和上次hash的结果相加,得到新的hash结果。计算出hash后就开始找是否存在这个字符串,方法是遍历global_State->strt->hash,global_State->strt结构定义如下。短字符串表申请内存的大小和实际使用大小由后两个字段表示。

<code class="hljs d has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">typedef</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> stringtable {  GCObject **hash;  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//保存所有的字符串</span>  lu_int32 nuse;  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* number of elements 已装元素的个数*/</span>  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> size;  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//当前hash桶的大小</span>} stringtable;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>

这里写图片描述
GCObject是一个数组,数组中每个元素是一个STring同义词链,每新建的一个元素其hash值通过lmod方法得在数组中的位置,然后挂在在位置的list链上。这种方类似于用链地址表法解决同义词冲突,方便查找和删除。 
遍历global_State->strt->hash数组时,首先是比较hash,相同再比较len(字符串长度),相同在判断原始str是否相同。通过两个&&关系起到了过滤的作用,可以加快判断的速度。如果找到有相同的字符串,那就直接返回找到的STting,没有找到,就需要创建新的段字符串,通过函数newshrstr实现。先创建一个LUA_TSHRSTR结构,然后存放到global_State->strt->hash中。

对于长字符串,创建的是LUA_TLNGSTR类型结构。会直接createstrobj创建一个gc对象,挂到gc链上。长字符串一般是使用的文本,在新建的时候不计算hash值,也不保证唯一性,使用extra字段来表示是否计算hash。

版权声明:本文为博主原创文章,未经博主允许不得转载。


0 0