標籤:os io ar for 檔案 問題 cti 代碼 sp
table.c 程式碼分析
全域符號,常量,字串,關聯陣列,檔案清單的定義。
全域符號:
初始有 5 個基本的符號,Lua 預設的函數和庫函數都註冊在裡面。
常量:
初始的幾個常量是 Lua 中 type 的名字。
字串表,關聯陣列表,檔案清單 所有的這些在 table.c 中定義的這些數組可以認為是 Lua 的全域註冊資料表空間,Lua 的環境。
函數分析
/*** Given a name, search it at symbol table and return its index. If not** found, allocate at end of table, checking oveflow and return its index.** On error, return -1.*/int lua_findsymbol (char *s){ int i; for (i=0; i<lua_ntable; i++) if (streq(s,s_name(i))) return i; if (lua_ntable >= MAXSYMBOL-1) { lua_error ("symbol table overflow"); return -1; } s_name(lua_ntable) = strdup(s); if (s_name(lua_ntable) == NULL) { lua_error ("not enough memory"); return -1; } s_tag(lua_ntable++) = T_NIL; return (lua_ntable-1);}
注釋說得比較清楚了:
給定一個名字,在符號表中尋找,如果找到,返回它的索引。如果沒有找到,在數組尾部添加註意不要越界。
如果出錯, 返回 -1。
/*** Given a constant string, eliminate its delimeters (" or ‘), search it at** constant table and return its index. If not found, allocate at end of** the table, checking oveflow and return its index.**** For each allocation, the function allocate a extra char to be used to** mark used string (it‘s necessary to deal with constant and string** uniformily). The function store at the table the second position allocated,** that represents the beginning of the real string. On error, return -1.***/int lua_findenclosedconstant (char *s){ int i, j, l=strlen(s); char *c = calloc (l, sizeof(char)); /* make a copy */ c++; /* create mark space */ /* introduce scape characters */ for (i=1,j=0; i<l-1; i++) { if (s[i] == ‘\\‘) { switch (s[++i]) { case ‘n‘: c[j++] = ‘\n‘; break; case ‘t‘: c[j++] = ‘\t‘; break; case ‘r‘: c[j++] = ‘\r‘; break; default : c[j++] = ‘\\‘; c[j++] = c[i]; break; } } else c[j++] = s[i]; } c[j++] = 0; for (i=0; i<lua_nconstant; i++) if (streq(c,lua_constant[i])) { free (c-1); return i; } if (lua_nconstant >= MAXCONSTANT-1) { lua_error ("lua: constant string table overflow"); return -1; } lua_constant[lua_nconstant++] = c; return (lua_nconstant-1);}
給定一個常量字串,在常量表中尋找它,如果找到返回它的索引。如果沒有,在結尾分配,返回它的索引。注意溢出。
對於每一個新的分配的常量字串,在它的前面多分配一個字元用來做標記位。真正的字串從第二位開始存放。
/*** Given a constant string, search it at constant table and return its index.** If not found, allocate at end of the table, checking oveflow and return** its index.**** For each allocation, the function allocate a extra char to be used to** mark used string (it‘s necessary to deal with constant and string** uniformily). The function store at the table the second position allocated,** that represents the beginning of the real string. On error, return -1.***/int lua_findconstant (char *s){ int i; for (i=0; i<lua_nconstant; i++) if (streq(s,lua_constant[i])) return i; if (lua_nconstant >= MAXCONSTANT-1) { lua_error ("lua: constant string table overflow"); return -1; } { char *c = calloc(strlen(s)+2,sizeof(char)); c++; /* create mark space */ lua_constant[lua_nconstant++] = strcpy(c,s); } return (lua_nconstant-1);}
和上面的操作差不多,沒有上面的複雜。上面的針對的是長的字串(字串中的特殊符號的,例如字串的有單引號或雙引號的),下面的針對的是短字串。由於 Lua1.0 的詞法分析和文法分析都沒有源檔案,暫時這麼認為。到以後的版本中再看類似的問題。
/*** Mark an object if it is a string or a unmarked array.*/void lua_markobject (Object *o){ if (tag(o) == T_STRING) lua_markstring (svalue(o)) = 1; else if (tag(o) == T_ARRAY && markarray(avalue(o)) == 0) lua_hashmark (avalue(o));}
標記字串或者數組,用以記憶體回收。
/*** Mark all strings and arrays used by any object stored at symbol table.*/static void lua_marktable (void){ int i; for (i=0; i<lua_ntable; i++) lua_markobject (&s_object(i));}
標記字串,數組及在符號數組中的 Object.
/*** Simulate a garbage colection. When string table or array table overflows,** this function check if all allocated strings and arrays are in use. If** there are unused ones, pack (compress) the tables.*/static void lua_pack (void){ lua_markstack (); lua_marktable (); { /* pack string */ int i, j; for (i=j=0; i<lua_nstring; i++) if (lua_markstring(lua_string[i]) == 1) { lua_string[j++] = lua_string[i]; lua_markstring(lua_string[i]) = 0; } else { free (lua_string[i]-1); } lua_nstring = j; }{ /* pack array */ int i, j; for (i=j=0; i<lua_narray; i++) if (markarray(lua_array[i]) == 1) { lua_array[j++] = lua_array[i]; markarray(lua_array[i]) = 0; } else { lua_hashdelete (lua_array[i]); } lua_narray = j; }}
記憶體回收,當建立字串或者數組時,如果記憶體溢出,就會被調到。如果字串或者數組有沒有用到的,釋放它。
標記 stack 上所有的 object
標記 table
壓縮字串數組
壓縮數組。
lua_createstring
lua_createarray
lua_addfile
注釋的比較清楚,不再細說。
/*** Internal function: return next global variable*/void lua_nextvar (void){ int index; Object *o = lua_getparam (1); if (o == NULL) { lua_error ("too few arguments to function `nextvar‘"); return; } if (lua_getparam (2) != NULL) { lua_error ("too many arguments to function `nextvar‘"); return; } if (tag(o) == T_NIL) { index = 0; } else if (tag(o) != T_STRING) { lua_error ("incorrect argument to function `nextvar‘"); return; } else { for (index=0; index<lua_ntable; index++) if (streq(s_name(index),svalue(o))) break; if (index == lua_ntable) { lua_error ("name not found in function `nextvar‘"); return; } index++; while (index < lua_ntable-1 && tag(&s_object(index)) == T_NIL) index++; if (index == lua_ntable-1) { lua_pushnil(); lua_pushnil(); return; } } { Object name; tag(&name) = T_STRING; svalue(&name) = lua_createstring(lua_strdup(s_name(index))); if (lua_pushobject (&name)) return; if (lua_pushobject (&s_object(index))) return; }}
獲得下一個全域變數。
必須傳入一個參數,但參數可以為空白,如果參數為空白,則返回第一個全域變數。
參數的類型必須為字串型。
在全域表中尋找給定的字串,如果沒找到,返回錯誤。如果找到,則在全域變數中找它後面第一個不為空白的全域變數。
Lua1.0 程式碼分析 table.c