Lua數據結構 — lua_State(六)

作者:羅日健

前面各種Lua的數據類型基本都說得差不多了,剩下最後一個數據類型:lua_State,我們可以認爲是”腳本上下文”,主要是包括當前腳本環境的運行狀態信息,還會有gc相關的信息。

Lua這門語言考慮了多線程的情況,在腳本空間中能夠開多個線程相關腳本上下文,而大家會共用一個全局腳本狀態數據,如下:

{07047585-760C-4695-95BA-841AC89FDCDA}

全局數據global_state的數據結構如下:

global_state主要是用於GC的數據鏈表,下面簡要說明幾個:

  1. stringtable strt:這個是在TString那章說到的全局字符串哈希表
  2. TValue lregistry:對應LUAREGISTRYINDEX的全局table.
  3. TString *tmname[TM_N]:元方法的名稱字符串。
  4. Table *mt[NUM_TAGS]:基本類型的元表,這是Lua5.0的特性。

mt成員在作者介紹文章中說到:

在上面代碼中,我們看到a支持一個tostring的方法,a是數值類型,我們可以爲數值類型添加任意的方法。Lua文章中說到一個用途,就是對於unicode和gbk的字符串的len方法能自己實現。

其它成員就不一一介紹了,下面來介紹與線程相關的腳本上下文lua_State:

我們看到,luaState也帶有CommonHeader頭,在第一章中也提到了GCObject中有luaState th這個成員,由此可見lua_State也會是被回收的對象之一。

考慮回一個線程中的腳本上下文,我們再來逐個分析每個成員:

  • lu_byte status:線程腳本的狀態,線程可選狀態如下:

  • StkId top:指向當前線程棧的棧頂指針,typedef TValue *StkId
  • StkId base:指向當前函數運行的相對基位置,具體可參考第四章的閉包
  • globalState *lG:指向全局狀態的指針
  • CallInfo *ci:當前線程運行的函數調用信息
  • const Instruction *savedpc:函數調用前,記錄上一個函數的pc位置
  • StkId stack_last:棧的實際最後一個位置(棧的長度是動態增長的)
  • StkId stack:棧底
  • CallInfo *end_ci:指向函數調用棧的棧頂
  • CallInfo *base_ci:指向函數調用棧的棧底
  • int stacksize:棧的大小
  • int size_ci:函數調用棧的大小
  • unsigned short nCcalls:當前C函數的調用的深度
  • unsigned short baseCcalls:用於記錄每個線程狀態的C函數調用深度的輔助成員
  • lu_byte hookmask:支持哪些hook能力,有下列可選的

  • lu_byte allowhook:是否允許hook
  • int basehookcount:用戶設置的執行指令數(LUA_MASKCOUNT下有效)
  • int hookcount:運行時,跑了多少條指令(LUA_MASKCOUNT下有效)
  • lua_Hook:用戶註冊的hook回調函數
  • TValue l_gt:當前線程的全局的環境表
  • TValue env:當前運行的環境表
  • GCObject *openupval、gclist:用於gc,詳細將會在GC一章細說
  • struct lua_longjmp *errorJmp:發生錯誤的長跳轉位置,用於記錄當函數發生錯誤時跳轉出去的位置。

 

本系列總結:

整個系列文章回答了我們對Lua中最基本的一個問題:“一個Lua變量究竟是什麼?”。由此我們深入並引申出各種知識,在腳本中我們覺得弱類型變量用起來很痛快,而其實它的內部實現其實是如此的複雜。

對於實現一門腳本語言,必須實現的是解釋器、虛擬機、上下文數據3大部分:

{2CC92087-0020-40B4-9403-7DB0D5F97BCC}

上下文數據這一層是腳本最基礎,最底層的東西,它決定了這門腳本究竟能做什麼。拋開解釋器和虛擬機,我們依然可以單純地通過C接口,在C++這一層就能操作腳本的上下文數據。

有空再研究一下Lua的GC,解釋器等等。

來自: http://blog.aliyun.com/795?spm=0.0.0.0.JJQP5w

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章