lua_getallocf
lua_Alloc lua_getallocf (lua_State *L, void **ud);
返回給定狀態機的內存分配器函數。如果 ud
不是 NULL
,Lua 把調用lua_newstate
時傳入的那個指針放入*ud
。
lua_getfenv
void lua_getfenv (lua_State *L, int index);
把索引處值的環境表壓入堆棧。
lua_getfield
void lua_getfield (lua_State *L, int index, const char *k);
把 t[k]
值壓入堆棧,這裏的 t
是指有效索引
index
指向的值。在 Lua 中,這個函數可能觸發對應 "index" 事件的元方法(參見
§2.8)。
lua_getglobal
void lua_getglobal (lua_State *L, const char *name);
把全局變量 name
裏的值壓入堆棧。這個是用一個宏定義出來的:
#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, s)
lua_getmetatable
int lua_getmetatable (lua_State *L, int index);
把給定索引指向的值的元表壓入堆棧。如果索引無效,或是這個值沒有元表,函數將返回 0 並且不會向棧上壓任何東西。
lua_gettable
void lua_gettable (lua_State *L, int index);
把 t[k]
值壓入堆棧,這裏的 t
是指有效索引
index
指向的值,而 k
則是棧頂放的值。
這個函數會彈出堆棧上的 key (把結果放在棧上相同位置)。在 Lua 中,這個函數可能觸發對應 "index" 事件的元方法(參見§2.8)。
lua_gettop
int lua_gettop (lua_State *L);
返回棧頂元素的索引。因爲索引是從 1 開始編號的,所以這個結果等於堆棧上的元素個數(因此返回 0 表示堆棧爲空)。
lua_insert
void lua_insert (lua_State *L, int index);
把棧頂元素插入指定的有效索引處,並依次移動這個索引之上的元素。不要用僞索引來調用這個函數,因爲僞索引不是真正指向堆棧上的位置。
lua_Integer
typedef ptrdiff_t lua_Integer;
這個類型被用於 Lua API 接收整數值。
缺省時這個被定義爲 ptrdiff_t
,這個東西通常是機器能處理的最大整數類型。
lua_isboolean
int lua_isboolean (lua_State *L, int index);
當給定索引的值類型爲 boolean 時,返回 1 ,否則返回 0 。
lua_iscfunction
int lua_iscfunction (lua_State *L, int index);
當給定索引的值是一個 C 函數時,返回 1 ,否則返回 0 。
lua_isfunction
int lua_isfunction (lua_State *L, int index);
當給定索引的值是一個函數( C 或 Lua 函數均可)時,返回 1 ,否則返回 0 。
lua_islightuserdata
int lua_islightuserdata (lua_State *L, int index);
當給定索引的值是一個 light userdata 時,返回 1 ,否則返回 0 。
lua_isnil
int lua_isnil (lua_State *L, int index);
當給定索引的值是 nil 時,返回 1 ,否則返回 0 。
lua_isnumber
int lua_isnumber (lua_State *L, int index);
當給定索引的值是一個數字,或是一個可轉換爲數字的字符串時,返回 1 ,否則返回 0 。
lua_isstring
int lua_isstring (lua_State *L, int index);
當給定索引的值是一個字符串或是一個數字(數字總能轉換成字符串)時,返回 1 ,否則返回 0 。
lua_istable
int lua_istable (lua_State *L, int index);
當給定索引的值是一個 table 時,返回 1 ,否則返回 0 。
lua_isthread
int lua_isthread (lua_State *L, int index);
當給定索引的值是一個 thread 時,返回 1 ,否則返回 0 。
lua_isuserdata
int lua_isuserdata (lua_State *L, int index);
當給定索引的值是一個 userdata (無論是完整的 userdata 還是 light userdata )時,返回 1 ,否則返回 0 。
lua_lessthan
int lua_lessthan (lua_State *L, int index1, int index2);
如果索引 index1
處的值小於索引 index2
處的值時,返回 1 ;否則返回 0 。其語義遵循 Lua 中的<
操作符(就是說,有可能調用元方法)。如果任何一個索引無效,也會返回 0 。
lua_load
int lua_load (lua_State *L, lua_Reader reader, void *data, const char *chunkname);
加載一個 Lua chunk 。如果沒有錯誤,
lua_load
把一個編譯好的 chunk 作爲一個 Lua 函數壓入堆棧。否則,壓入出錯信息。
lua_load
的返回值可以是:
- 0: 沒有錯誤;
LUA_ERRSYNTAX
: 在預編譯時碰到語法錯誤;LUA_ERRMEM
: 內存分配錯誤。
這個函數僅僅加栽 chunk ;而不會去運行它。
lua_load
會自動檢測 chunk 是文本的還是二進制的,然後做對應的加載操作(參見程序luac
)。
lua_load
函數使用一個用戶提供的reader
函數來讀取 chunk (參見lua_Reader
)。data
參數會被傳入讀取器函數。
chunkname
這個參數可以賦予 chunk 一個名字,這個名字被用於出錯信息和調試信息(參見§3.8)。
lua_newstate
lua_State *lua_newstate (lua_Alloc f, void *ud);
創建的一個新的獨立的狀態機。如果創建不了(因爲內存問題)返回 NULL
。參數
f
是一個分配器函數; Lua 將通過這個函數做狀態機內所有的內存分配操作。第二個參數 ud
,這個指針將在每次調用分配器時被直接傳入。
lua_newtable
void lua_newtable (lua_State *L);
創建一個空 table ,並將之壓入堆棧。它等價於 lua_createtable(L, 0, 0)
。
lua_newthread
lua_State *lua_newthread (lua_State *L);
創建一個新線程,並將其壓入堆棧,並返回維護這個線程的
lua_State
指針。這個函數返回的新狀態機共享原有狀態機中的所有對象(比如一些 table),但是它有獨立的執行堆棧。
沒有顯式的函數可以用來關閉或銷燬掉一個線程。線程跟其它 Lua 對象一樣是垃圾收集的條目之一。
lua_newuserdata
void *lua_newuserdata (lua_State *L, size_t size);
這個函數分配分配一塊指定大小的內存塊,把內存塊地址作爲一個完整的 userdata 壓入堆棧,並返回這個地址。
userdata 代表 Lua 中的 C 值。完整的 userdata 代表一塊內存。它是一個對象(就像 table 那樣的對象):你必須創建它,它有着自己的元表,而且它在被回收時,可以被監測到。一個完整的 userdata 只和它自己相等(在等於的原生作用下)。
當 Lua 通過 gc
元方法回收一個完整的 userdata 時, Lua 調用這個元方法並把 userdata 標記爲已終止。等到這個 userdata 再次被收集的時候,Lua 會釋放掉相關的內存。
lua_next
int lua_next (lua_State *L, int index);
從棧上彈出一個 key(鍵),然後把索引指定的表中 key-value(健值)對壓入堆棧(指定 key 後面的下一 (next) 對)。如果表中以無更多元素,那麼lua_next
將返回 0 (什麼也不壓入堆棧)。
典型的遍歷方法是這樣的:
/* table 放在索引 't' 處 */ lua_pushnil(L); /* 第一個 key */ while (lua_next(L, t) != 0) { /* 用一下 'key' (在索引 -2 處) 和 'value' (在索引 -1 處) */ printf("%s - %s\n", lua_typename(L, lua_type(L, -2)), lua_typename(L, lua_type(L, -1))); /* 移除 'value' ;保留 'key' 做下一次迭代 */ lua_pop(L, 1); }
在遍歷一張表的時候,不要直接對 key 調用
lua_tolstring
,除非你知道這個 key 一定是一個字符串。調用
lua_tolstring
有可能改變給定索引位置的值;這會對下一次調用
lua_next
造成影響。
lua_Number
typedef double lua_Number;
Lua 中數字的類型。確省是 double ,但是你可以在 luaconf.h
中修改它。
通過修改配置文件你可以改變 Lua 讓它操作其它數字類型(例如:float 或是 long )。
lua_objlen
size_t lua_objlen (lua_State *L, int index);
返回指定的索引處的值的長度。對於 string ,那就是字符串的長度;對於 table ,是取長度操作符 ('#
') 的結果;對於 userdata ,就是爲其分配的內存塊的尺寸;對於其它值,爲 0 。
lua_pcall
lua_pcall (lua_State *L, int nargs, int nresults, int errfunc);
以保護模式調用一個函數。
nargs
和 nresults
的含義與
lua_call
中的相同。如果在調用過程中沒有發生錯誤,
lua_pcall
的行爲和
lua_call
完全一致。但是,如果有錯誤發生的話,
lua_pcall
會捕獲它,然後把單一的值(錯誤信息)壓入堆棧,然後返回錯誤碼。同
lua_call
一樣,
lua_pcall
總是把函數本身和它的參數從棧上移除。
如果 errfunc
是 0 ,返回在棧頂的錯誤信息就和原始錯誤信息完全一致。否則,errfunc
就被當成是錯誤處理函數在棧上的索引。(在當前的實現裏,這個索引不能是僞索引。)在發生運行時錯誤時,這個函數會被調用而參數就是錯誤信息。錯誤處理函數的返回值將被lua_pcall
作爲出錯信息返回在堆棧上。
典型的用法中,錯誤處理函數被用來在出錯信息上加上更多的調試信息,比如棧跟蹤信息 (stack traceback) 。這些信息在lua_pcall
返回後,因爲棧已經展開 (unwound) ,所以收集不到了。
lua_pcall
函數在調用成功時返回 0 ,否則返回以下(定義在lua.h
中的)錯誤代碼中的一個:
LUA_ERRRUN
: 運行時錯誤。LUA_ERRMEM
: 內存分配錯誤。 對於這種錯,Lua 調用不了錯誤處理函數。LUA_ERRERR
: 在運行錯誤處理函數時發生的錯誤。
lua_pop
void lua_pop (lua_State *L, int n);
從堆棧中彈出 n
個元素。
lua_pushboolean
void lua_pushboolean (lua_State *L, int b);
把 b
作爲一個 boolean 值壓入堆棧。
lua_pushcclosure
void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
把一個新的 C closure 壓入堆棧。
當創建了一個 C 函數後,你可以給它關聯一些值,這樣就是在創建一個 C closure (參見
§3.4);接下來無論函數何時被調用,這些值都可以被這個函數訪問到。爲了將一些值關聯到一個 C 函數上,首先這些值需要先被壓入堆棧(如果有多個值,第一個先壓)。接下來調用lua_pushcclosure
來創建出 closure 並把這個 C 函數壓到堆棧上。參數n
告之函數有多少個值需要關聯到函數上。lua_pushcclosure
也會把這些值從棧上彈出。
lua_pushcfunction
void lua_pushcfunction (lua_State *L, lua_CFunction f);
將一個 C 函數壓入堆棧。這個函數接收一個 C 函數指針,並將一個類型爲 function
的 Lua 值壓入堆棧。當這個棧頂的值被調用時,將觸發對應的 C 函數。
註冊到 Lua 中的任何函數都必須遵循正確的協議來接收參數和返回值(參見
lua_CFunction
)。
lua_pushcfunction
是作爲一個宏定義出現的:
#define lua_pushcfunction(L,f) lua_pushcclosure(L,f,0)
lua_pushfstring
const char *lua_pushfstring (lua_State *L, const char *fmt, ...);
把一個格式化過的字符串壓入堆棧,然後返回這個字符串的指針。它和 C 函數 sprintf
比較像,不過有一些重要的區別:
- 摸你需要爲結果分配空間: 其結果是一個 Lua 字符串,由 Lua 來關心其內存分配 (同時通過垃圾收集來釋放內存)。
- 這個轉換非常的受限。 不支持 flag ,寬度,或是指定精度。 它只支持下面這些: '
%%
' (插入一個 '%
'), '%s
' (插入一個帶零終止符的字符串,沒有長度限制), '%f
' (插入一個lua_Number
), '%p
' (插入一個指針或是一個十六進制數), '%d
' (插入一個int
), '%c
' (把一個int
作爲一個字符插入)。
lua_pushinteger
void lua_pushinteger (lua_State *L, lua_Integer n);
把 n
作爲一個數字壓棧。
lua_pushlightuserdata
void lua_pushlightuserdata (lua_State *L, void *p);
把一個 light userdata 壓棧。
userdata 在 Lua 中表示一個 C 值。 light userdata 表示一個指針。它是一個像數字一樣的值:你不需要專門創建它,它也沒有獨立的 metatable ,而且也不會被收集(因爲從來不需要創建)。只要表示的 C 地址相同,兩個 light userdata 就相等。
lua_pushlstring
void lua_pushlstring (lua_State *L, const char *s, size_t len);
把指針 s
指向的長度爲 len
的字符串壓棧。 Lua 對這個字符串做一次內存拷貝(或是複用一個拷貝),因此s
處的內存在函數返回後,可以釋放掉或是重用於其它用途。字符串內可以保存有零字符。
lua_pushnil
void lua_pushnil (lua_State *L);
把一個 nil 壓棧。
lua_pushnumber
void lua_pushnumber (lua_State *L, lua_Number n);
把一個數字 n
壓棧。
lua_pushstring
void lua_pushstring (lua_State *L, const char *s);
把指針 s
指向的以零結尾的字符串壓棧。 Lua 對這個字符串做一次內存拷貝(或是複用一個拷貝),因此s
處的內存在函數返回後,可以釋放掉或是重用於其它用途。字符串中不能包含有零字符;第一個碰到的零字符會認爲是字符串的結束。
lua_pushthread
int lua_pushthread (lua_State *L);
把 L
中提供的線程壓棧。如果這個線程是當前狀態機的主線程的話,返回 1 。
lua_pushvalue
void lua_pushvalue (lua_State *L, int index);
把堆棧上給定有效處索引處的元素作一個拷貝壓棧。
lua_pushvfstring
const char *lua_pushvfstring (lua_State *L, const char *fmt, va_list argp);
等價於
lua_pushfstring
,不過是用 va_list
接收參數,而不是用可變數量的實際參數。
lua_rawequal
int lua_rawequal (lua_State *L, int index1, int index2);
如果兩個索引 index1
和 index2
處的值簡單地相等(不調用元方法)則返回 1 。否則返回 0 。如果任何一個索引無效也返回 0 。
lua_rawget
void lua_rawget (lua_State *L, int index);
類似於
lua_gettable
,但是作一次直接訪問(不觸發元方法)。
lua_rawgeti
void lua_rawgeti (lua_State *L, int index, int n);
把 t[n]
的值壓棧,這裏的 t
是指給定索引
index
處的一個值。這是一個直接訪問;就是說,它不會觸發元方法。
lua_rawset
void lua_rawset (lua_State *L, int index);
類似於
lua_settable
,但是是作一個直接賦值(不觸發元方法)。
lua_rawseti
void lua_rawseti (lua_State *L, int index, int n);
等價於 t[n] = v
,這裏的 t
是指給定索引
index
處的一個值,而 v
是棧頂的值。
函數將把這個值彈出棧。賦值操作是直接的;就是說,不會觸發元方法。
lua_Reader
typedef const char * (*lua_Reader) (lua_State *L, void *data, size_t *size);
lua_load
用到的讀取器函數,每次它需要一塊新的 chunk 的時候,lua_load
就調用讀取器,每次都會傳入一個參數data
。讀取器需要返回含有新的 chunk 的一塊內存的指針,並把 size
設爲這塊內存的大小。內存塊必須在下一次函數被調用之前一直存在。讀取器可以通過返回一個NULL
來指示 chunk 結束。讀取器可能返回多個塊,每個塊可以有任意的大於零的尺寸。
lua_register
void lua_register (lua_State *L, const char *name, lua_CFunction f);
把 C 函數 f
設到全局變量 name
中。它通過一個宏定義:
#define lua_register(L,n,f) \ (lua_pushcfunction(L, f), lua_setglobal(L, n))
lua_remove
void lua_remove (lua_State *L, int index);
從給定有效索引處移除一個元素,把這個索引之上的所有元素移下來填補上這個空隙。不能用僞索引來調用這個函數,因爲僞索引並不指向真實的棧上的位置。
lua_replace
void lua_replace (lua_State *L, int index);
把棧頂元素移動到給定位置(並且把這個棧頂元素彈出),不移動任何元素(因此在那個位置處的值被覆蓋掉)。
lua_resume
int lua_resume (lua_State *L, int narg);
在給定線程中啓動或繼續一個 coroutine 。
要啓動一個 coroutine 的話,首先你要創建一個新線程(參見
lua_newthread
);然後把主函數和若干參數壓到新線程的堆棧上;最後調用
lua_resume
,把 narg
設爲參數的個數。這次調用會在 coroutine 掛起時或是結束運行後返回。當函數返回時,堆棧中會有傳給lua_yield
的所有值,或是主函數的所有返回值。如果 coroutine 切換時,lua_resume
返回LUA_YIELD
,而當 coroutine 結束運行且沒有任何錯誤時,返回 0 。如果有錯則返回錯誤代碼(參見lua_pcall
)。在發生錯誤的情況下,堆棧沒有展開,因此你可以使用
debug API 來處理它。出錯信息放在棧頂。要繼續運行一個 coroutine 的話,你把需要傳給yield
作結果的返回值壓入堆棧,然後調用lua_resume
。
lua_setallocf
void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
把指定狀態機的分配器函數換成帶上指針 ud
的 f
。
lua_setfenv
int lua_setfenv (lua_State *L, int index);
從堆棧上彈出一個 table 並把它設爲指定索引處值的新環境。如果指定索引處的值即不是函數又不是線程或是 userdata ,lua_setfenv
會返回 0 ,否則返回 1 。
lua_setfield
void lua_setfield (lua_State *L, int index, const char *k);
做一個等價於 t[k] = v
的操作,這裏 t
是給出的有效索引index
處的值,而v
是棧頂的那個值。
這個函數將把這個值彈出堆棧。跟在 Lua 中一樣,這個函數可能觸發一個 "newindex" 事件的元方法(參見§2.8)。
lua_setglobal
void lua_setglobal (lua_State *L, const char *name);
從堆棧上彈出一個值,並將其設到全局變量 name
中。它由一個宏定義出來:
#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, s)
lua_setmetatable
int lua_setmetatable (lua_State *L, int index);
把一個 table 彈出堆棧,並將其設爲給定索引處的值的 metatable 。
lua_settable
void lua_settable (lua_State *L, int index);
作一個等價於 t[k] = v
的操作,這裏 t
是一個給定有效索引index
處的值,v
指棧頂的值,而
k
是棧頂之下的那個值。
這個函數會把鍵和值都從堆棧中彈出。和在 Lua 中一樣,這個函數可能觸發 "newindex" 事件的元方法(參見§2.8)。
lua_settop
void lua_settop (lua_State *L, int index);
參數允許傳入任何可接受的索引以及 0 。它將把堆棧的棧頂設爲這個索引。如果新的棧頂比原來的大,超出部分的新元素將被填爲nil 。如果index
爲 0 ,把棧上所有元素移除。
lua_State
typedef struct lua_State lua_State;
一個不透明的結構,它保存了整個 Lua 解釋器的狀態。 Lua 庫是完全可重入的:它沒有任何全局變量。(譯註:從 C 語法上來說,也不盡然。例如,在 table 的實現中用了一個靜態全局變量 dummynode_ ,但這在正確使用時並不影響可重入性。只是萬一你錯誤鏈接了 lua 庫,不小心在同一進程空間中存在兩份 lua 庫實現的代碼的話,多份 dummynode_ 不同的地址會導致一些問題。)所有的信息都保存在這個結構中。
這個狀態機的指針必須作爲第一個參數傳遞給每一個庫函數。
lua_newstate
是一個例外,這個函數會從頭創建一個 Lua 狀態機。
lua_status
int lua_status (lua_State *L);
返回線程 L
的狀態。
正常的線程狀態是 0 。當線程執行完畢或發生一個錯誤時,狀態值是錯誤碼。如果線程被掛起,狀態爲
LUA_YIELD
。
lua_toboolean
int lua_toboolean (lua_State *L, int index);
把指定的索引處的的 Lua 值轉換爲一個 C 中的 boolean 值( 0 或是 1 )。和 Lua 中做的所有測試一樣,lua_toboolean
會把任何不同於false 和nil 的值當作 1
返回;否則就返回 0 。如果用一個無效索引去調用也會返回 0 。(如果你想只接收真正的 boolean 值,就需要使用lua_isboolean
來測試值的類型。)
lua_tocfunction
lua_CFunction lua_tocfunction (lua_State *L, int index);
把給定索引處的 Lua 值轉換爲一個 C 函數。這個值必須是一個 C 函數;如果不是就返回 NULL
。
lua_tointeger
lua_Integer lua_tointeger (lua_State *L, int idx);
把給定索引處的 Lua 值轉換爲
lua_Integer
這樣一個有符號整數類型。這個 Lua 值必須是一個數字或是一個可以轉換爲數字的字符串(參見
§2.2.1);否則,lua_tointeger
返回 0 。
如果數字不是一個整數,截斷小數部分的方式沒有被明確定義。
lua_tolstring
const char *lua_tolstring (lua_State *L, int index, size_t *len);
把給定索引處的 Lua 值轉換爲一個 C 字符串。如果 len
不爲 NULL
,它還把字符串長度設到*len
中。這個 Lua 值必須是一個字符串或是一個數字;否則返回返回NULL
。如果值是一個數字,lua_tolstring
還會把堆棧中的那個值的實際類型轉換爲一個字符串。(當遍歷一個表的時候,把lua_tolstring
作用在鍵上,這個轉換有可能導致lua_next
弄錯。)
lua_tolstring
返回 Lua 狀態機中字符串的以對齊指針。這個字符串總能保證 ( C 要求的)最後一個字符爲零 ('\0
') ,而且它允許在字符串內包含多個這樣的零。因爲 Lua 中可能發生垃圾收集,所以不保證lua_tolstring
返回的指針,在對應的值從堆棧中移除後依然有效。
lua_tonumber
lua_Number lua_tonumber (lua_State *L, int index);
把給定索引處的 Lua 值轉換爲
lua_Number
這樣一個 C 類型(參見
lua_Number
)。這個 Lua 值必須是一個數字或是一個可轉換爲數字的字符串(參見
§2.2.1 );否則,lua_tonumber
返回 0 。
lua_topointer
const void *lua_topointer (lua_State *L, int index);
把給定索引處的值轉換爲一般的 C 指針 (void*
) 。這個值可以是一個 userdata ,table ,thread 或是一個 function ;否則,lua_topointer
返回NULL
。不同的對象有不同的指針。不存在把指針再轉回原有類型的方法。
這個函數通常只爲產生 debug 信息用。
lua_tostring
const char *lua_tostring (lua_State *L, int index);
等價於
lua_tolstring
,而參數 len
設爲 NULL
。
lua_tothread
lua_State *lua_tothread (lua_State *L, int index);
把給定索引處的值轉換爲一個 Lua 線程(由 lua_State*
代表)。這個值必須是一個線程;否則函數返回NULL
。
lua_touserdata
void *lua_touserdata (lua_State *L, int index);
如果給定索引處的值是一個完整的 userdata ,函數返回內存塊的地址。如果值是一個 light userdata ,那麼就返回它表示的指針。否則,返回NULL
。
lua_type
int lua_type (lua_State *L, int index);
返回給定索引處的值的類型,當索引無效時則返回 LUA_TNONE
(那是指一個指向堆棧上的空位置的索引)。lua_type
返回的類型是一些個在lua.h
中定義的常量:LUA_TNIL
,
LUA_TNUMBER
, LUA_TBOOLEAN
, LUA_TSTRING
,
LUA_TTABLE
, LUA_TFUNCTION
, LUA_TUSERDATA
,
LUA_TTHREAD
, LUA_TLIGHTUSERDATA
。
lua_typename
const char *lua_typename (lua_State *L, int tp);
返回 tp
表示的類型名,這個 tp
必須是
lua_type
可能返回的值中之一。
lua_Writer
typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud);
由
lua_dump
用到的寫入器函數。每次
lua_dump
產生了一塊新的 chunk ,它都會調用寫入器。傳入要寫入的緩存 (p
) 和它的尺寸 (sz
) ,還有lua_dump
的參數data
。
寫入器會返回一個錯誤碼: 0 表示沒有錯誤;別的值均表示一個錯誤,並且會讓
lua_dump
停止再次調用寫入器。
lua_xmove
void lua_xmove (lua_State *from, lua_State *to, int n);
傳遞 同一個 全局狀態機下不同線程中的值。
這個函數會從 from
的堆棧中彈出 n
個值,然後把它們壓入to
的堆棧中。
lua_yield
int lua_yield (lua_State *L, int nresults);
切出一個 coroutine 。
這個函數只能在一個 C 函數的返回表達式中調用。如下:
return lua_yield (L, nresults);
當一個 C 函數這樣調用
lua_yield
,正在運行中的 coroutine 將從運行中掛起,然後啓動這個 coroutine 用的那次對
lua_resume
的調用就返回了。參數 nresults
指的是堆棧中需要返回的結果個數,這些返回值將被傳遞給lua_resume
。
3.8 - 調試接口
Lua 沒有內建的調試設施。取而代之的是提供了一些函數接口和鉤子。利用這些接口,可以做出一些不同類型的調試器,性能分析器,或是其它一些需要從解釋器中取到“內部信息”的工具。
lua_Debug
typedef struct lua_Debug { int event; const char *name; /* (n) */ const char *namewhat; /* (n) */ const char *what; /* (S) */ const char *source; /* (S) */ int currentline; /* (l) */ int nups; /* (u) upvalue 個數 */ int linedefined; /* (S) */ int lastlinedefined; /* (S) */ char short_src[LUA_IDSIZE]; /* (S) */ /* 私有部分 */ 其它域 } lua_Debug;
一個用來攜帶活動中函數的各種信息的結構。
lua_getstack
僅填寫這個結構中的私有部分,這些部分以後會用到。調用
lua_getinfo
則可以填上
lua_Debug
中有用信息的那些域。
lua_Debug
中的各個域有下列含義:
source
: 如果函數是定義在一個字符串中,source
就是這個字符串。 如果函數定義在一個文件中,source
是一個以 '@
' 開頭的文件名。short_src
: 一個“可打印版本”的source
,用於出錯信息。linedefined
: 函數定義開始處的行號。lastlinedefined
: 函數定義結束處的行號。what
: 如果函數是一個 Lua 函數,則爲一個字符串"Lua"
; 如果是一個 C 函數,則爲"C"
; 如果它是一個 chunk 的主體部分,則爲"main"
; 如果是一個作了尾調用的函數,則爲"tail"
。 別的情況下,Lua 沒有關於函數的別的信息。currentline
: 給定函數正在執行的那一行。 當提供不了行號信息的時候,currentline
被設爲 -1 。name
: 給定函數的一個合理的名字。 因爲 Lua 中的函數也是一個值, 所以它們沒有固定的名字: 一些函數可能是全局複合變量的值, 另一些可能僅僅只是被保存在一個 table 中。lua_getinfo
函數會檢查函數是這樣被調用的,以此來找到一個適合的名字。 如果它找不到名字,name
就被設置爲NULL
。namewhat
: 結實name
域。namewhat
的值可以是"global"
,"local"
,"method"
,"field"
,"upvalue"
, 或是""
(空串)。 這取決於函數怎樣被調用。 (Lua 用空串表示其它選項都不符合)nups
: 函數的 upvalue 的個數。
lua_gethook
lua_Hook lua_gethook (lua_State *L);
返回當前的鉤子函數。
lua_gethookcount
int lua_gethookcount (lua_State *L);
返回當前鉤子記數。
lua_gethookmask
int lua_gethookmask (lua_State *L);
返回當前的鉤子掩碼 (mask) 。
lua_getinfo
int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
返回一個指定的函數或函數調用的信息。
當用於取得一次函數調用的信息時,參數 ar
必須是一個有效的活動的記錄。這條記錄可以是前一次調用lua_getstack
得到的,或是一個鉤子 (參見lua_Hook
)得到的參數。
用於獲取一個函數的信息時,可以把這個函數壓入堆棧,然後把 what
字符串以字符 '>
' 起頭。(這個情況下,lua_getinfo
從棧頂上彈出函數。)例如,想知道函數f
在哪一行定義的,你可以下下列代碼:
lua_Debug ar; lua_getfield(L, LUA_GLOBALSINDEX, "f"); /* 取到全局變量 'f' */ lua_getinfo(L, ">S", &ar); printf("%d\n", ar.linedefined);
what
字符串中的每個字符都篩選出結構 ar
結構中一些域用於填充,或是把一個值壓入堆棧:
- '
n
': 填充name
及namewhat
域; - '
S
': 填充source
,short_src
,linedefined
,lastlinedefined
,以及what
域; - '
l
': 填充currentline
域; - '
u
': 填充nups
域; - '
f
': 把正在運行中指定級別處函數壓入堆棧; (譯註:一般用於獲取函數調用中的信息, 級別是由 ar 中的私有部分來提供。 如果用於獲取靜態函數,那麼就直接把指定函數重新壓回堆棧, 但這樣做通常無甚意義。) - '
L
': 壓一個 table 入棧,這個 table 中的整數索引用於描述函數中哪些行是有效行。 (有效行指有實際代碼的行, 即你可以置入斷點的行。 無效行包括空行和只有註釋的行。)
這個函數出錯會返回 0 (例如,what
中有一個無效選項)。
lua_getlocal
const char *lua_getlocal (lua_State *L, lua_Debug *ar, int n);
從給定活動記錄中獲取一個局部變量的信息。參數 ar
必須是一個有效的活動的記錄。這條記錄可以是前一次調用lua_getstack
得到的,或是一個鉤子 (參見lua_Hook
)得到的參數。索引n
用於選擇要檢閱哪個局部變量( 1 表示第一個參數或是激活的第一個局部變量,以此類推,直到最後一個局部變量)。
lua_getlocal
把變量的值壓入堆棧並返回它的名字。
以 '(' (正小括號)開始的變量指內部變量(循環控制變量,臨時變量,C 函數局部變量)。
當索引大於局部變量的個數時,返回 NULL
(什麼也不壓入)。
lua_getstack
int lua_getstack (lua_State *L, int level, lua_Debug *ar);
獲取解釋器的運行時棧的信息。
這個函數用正在運行中的給定級別處的函數的活動記錄來填寫
lua_Debug
結構的一部分。 0 級表示當前運行的函數,而 n+1 級處的函數就是調用第 n 級函數的那一個。如果沒有錯誤,lua_getstack
返回 1 ;當調用傳入的級別大於堆棧深度的時候,返回 0 。
lua_getupvalue
const char *lua_getupvalue (lua_State *L, int funcindex, int n);
獲取一個 closure 的 upvalue 信息。(對於 Lua 函數,upvalue 是函數需要使用的外部局部變量,因此這些變量被包含在 closure 中。)lua_getupvalue
獲取第n
個 upvalue ,把這個 upvalue
的值壓入堆棧,並且返回它的名字。 funcindex
指向堆棧上 closure 的位置。( 因爲 upvalue 在整個函數中都有效,所以它們沒有特別的次序。因此,它們以字母次序來編號。)
當索引號比 upvalue 數量大的時候,返回 NULL
(而且不會壓入任何東西)對於 C 函數,這個函數用空串""
表示所有 upvalue 的名字。
lua_Hook
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
用於調試的鉤子函數類型。
無論何時鉤子被調用,它的參數 ar
中的 event
域都被設爲觸發鉤子的事件。 Lua 把這些事件定義爲以下常量:LUA_HOOKCALL
,LUA_HOOKRET
,
LUA_HOOKTAILRET
,LUA_HOOKLINE
, andLUA_HOOKCOUNT
。除此之外,對於 line 事件,currentline
域也被設置。要想獲得ar
中的其他域,鉤子必須調用lua_getinfo
。對於返回事件,event
的正常值可能是LUA_HOOKRET
,或者是LUA_HOOKTAILRET
。對於後一種情況,Lua 會對一個函數做的尾調用也模擬出一個返回事件出來;對於這個模擬的返回事件,調用lua_getinfo
沒有什麼作用。
當 Lua 運行在一個鉤子內部時,它將屏蔽掉其它對鉤子的調用。也就是說,如果一個鉤子函數內再調回 Lua 來執行一個函數或是一個 chunk ,這個執行操作不會觸發任何的鉤子。
lua_sethook
int lua_sethook (lua_State *L, lua_Hook f, int mask, int count);
設置一個調試用鉤子函數。
參數 f
是鉤子函數。 mask
指定在哪些事件時會調用:它由下列一組位常量構成LUA_MASKCALL
,LUA_MASKRET
,
LUA_MASKLINE
,以及LUA_MASKCOUNT
。參數count
只在 mask 中包含有LUA_MASKCOUNT
纔有意義。對於每個事件,鉤子被調用的情況解釋如下:
- call hook: 在解釋器調用一個函數時被調用。 鉤子將於 Lua 進入一個新函數後,函數獲取參數前被調用。
- return hook: 在解釋器從一個函數中返回時調用。 鉤子將於 Lua 離開函數之前的那一刻被調用。 你無權訪問被函數返回出去的那些值。(譯註:原文 (You have no access to the values to be returned by the function) 如此。 但“無權訪問”一詞值得商榷。 某些情況下你可以訪問到一些被命名爲 (*temporary) 的局部變量, 那些索引被排在最後的 (*temporary) 變量指的就是返回值。 但是由於 Lua 對特殊情況做了一些優化,比如直接返回一個被命名的局部變量, 那麼就找不到對應的 (*temporary) 變量了。本質上,返回值一定存在於此刻的局部變量中, 並且可以訪問它,只是無法確定是哪些罷了。至於這個時候函數體內的其它局部變量, 是不保證有效的。進入 return hook 的那一刻起,實際已經退出函數內部的運行環節, 返回值佔用的局部變量空間以後的部分,都有可能因 hook 本身複用它們而改變。)
- line hook: 在解釋器準備開始執行新的一行代碼時, 或是跳轉到這行代碼中時(即使在同一行內跳轉)被調用。 (這個事件僅僅在 Lua 執行一個 Lua 函數時發生。)
- count hook: 在解釋器每執行
count
條指令後被調用。 (這個事件僅僅在 Lua 執行一個 Lua 函數時發生。)
鉤子可以通過設置 mask
爲零屏蔽。
lua_setlocal
const char *lua_setlocal (lua_State *L, lua_Debug *ar, int n);
設置給定活動記錄中的局部變量的值。參數 ar
與 n
和
lua_getlocal
中的一樣(參見
lua_getlocal
)。
lua_setlocal
把棧頂的值賦給變量然後返回變量的名字。它會將值從棧頂彈出。
當索引大於局部變量的個數時,返回 NULL
(什麼也不彈出)。
lua_setupvalue
const char *lua_setupvalue (lua_State *L, int funcindex, int n);
設置 closure 的 upvalue 的值。它把棧頂的值彈出並賦於 upvalue 並返回 upvalue 的名字。參數funcindex
與
n
和
lua_getupvalue
中的一樣(參見
lua_getupvalue
)。
當索引大於 upvalue 的個數時,返回 NULL
(什麼也不彈出)。