首先 lua是一門動態型別的指令碼語言,這就意味著同乙個變數在不同的時刻可以指向不同的資料型別,例如宣告乙個變數t 既可以指向字串,也可以指向表,這就需要乙個通用的資料結構來表示lua裡的所有資料型別包括數字、字串、表、指標、函式、lua虛擬機器等型別。用來表示不同的資料型別的通用資料結構需要滿足兩個條件,1.結構中需要包含乙個表示資料型別的字段 2.包含乙個儲存實際資料的字段 ,常見的做法有兩種:
1. 一般的物件導向思路,定義乙個公共資料結構,儲存所有資料型別的公共資訊,其他具體資料在派生結構中定義 。
2. 使用c語言的union
在lua中,兩種方法都有使用,接下來看一下lua的通用資料結構是如何定義的,首先需要確定資料型別type,在lua中基礎資料型別對應的type在lua.h 中定義 。如下圖
其中 lua_tuserdata 和 lua_tlightuserdata 兩種 對應的都是void* 。區別在於lua_tlightuserdata的分配釋放由lua外部的使用者來完成,不需要lua關心其生命週期 ,後者是通過lua內部完成的。
上述資料型別大體可以分為兩類,需要gc的和 不需要gc的,需要gc的有lua_tstring(字串)、lua_ttable(表)』lua_tfunction(函式)、lua_tuserdata(指標)lua_tthread(執行緒),對於需要gc的資料型別,他們的公共資訊是乙個簡單的巨集定義commonheader,定義在lobject.h中,並定義了乙個只包含commonheader的結構體gcobject。
lua內部通過乙個這個巨集來標識需要gc的資料,此處使用巨集定義是為了使用上的方便 。 next :下乙個gc鍊錶的成員 tt:表示上述的資料型別,lua_byte 是unsigned char 型別的別名 marked:gc相關標記位
接下來,lua使用了乙個聯合體gcunion來表示所有需要gc的資料型別(定義在lstate.h中)
再將需要所有需要gc的資料型別看作一種型別和 其他不需要gc的資料型別放在一起形成新的聯合體value (lobject.h)
需要注意的是:value中儲存的是乙個gcobject的指標,實際指向的是乙個gcunion型別的值,這裡的value已經可以表示lua中所有資料型別的值。但還有乙個問題,對於gc資料型別,在gcobject中有乙個tt標識具體資料型別,而非gc資料型別卻無法區分出來,所以還需要新增乙個標識資料型別的字段 。也就是下面的tvalue,其中的tt_標識了資料型別
這個結構就跟最開始我們自己定義的tvalue十分類似了。到這裡我們已經可以使用tvalue來表示lua的所有資料型別,緊接著就需要實現各種具體型別和tvalue之間進行轉換 ,lobject.h中定義了大量的tvalue和具體型別相互轉換的巨集定義
首先進行型別判斷,然後根據型別取值,對於非gc資料,直接取vlaue中對應型別的值 ,對於gc資料需要先將vlaue中的gc轉為gcunion* 再去取值 ,例如tstring型別,通過(gcunion*)(t.value_.gc)->ts 取值
對於非gc資料,直接將值賦給對應字段,設定tt_為對應型別 ,對於gc資料型別,需要使用obj2gco將資料轉換為gcobject,位址賦值給tvlaue中的gc欄位,再設定tt_為對應型別 。lobject.h中主要是各種型別的資料結構定義 、型別判斷函式 和 型別轉換函式 。
需要知道的是 ,程式 = 資料結構 + 演算法,而tvalue就是為了實現lua動態語言特性所定義的一種資料結構。
lua5 3資料結構
由於lua版本迭代之間,資料結構和函式都會部分變化 以下是我分析的lua.h中的資訊,以便確定版本 define lua version major 5 define lua version minor 3 define lua version num 503 define lua version ...
lua 原始碼閱讀 1 1 2 1
lua 1.1 閱讀 1.hash.c 中 a 對建立的 hash array 用 listhead 鏈式結構來管理,新增lua hashcollector,用來做 hash 的 處理。ps 1.0 用的是個 512 的陣列,用乙個少乙個 b hash lua createarray int nha...
LUA 原始碼閱讀筆記(一)
背景介紹 因為工作的需要,後台svr要能夠動態修改更新,使用c當然沒有問題,問題就在於修改原始碼後,需要重啟服務。所以就想到在c裡能夠嵌入一種指令碼,最好是和c無縫結合的。因此就想到使用到lua,lua的大名圈內人士應該早有耳聞,只不過一直沒有機會接觸。機緣巧合,有幸一見。俗話說得好,耳聞不如一見。...