1. 程式人生 > >Lua虛擬機器的初始化

Lua虛擬機器的初始化

1. 建立Lua虛擬機器

lua_State *lua_newstate(lua_Alloc f, void *ud) API可以為我們建立一個新的獨立的Lua虛擬機器。

引數指定了虛擬機器中的記憶體分配策略,例如我們已經在自己的程式碼中實現了記憶體池,這時候只需要寫一個符合lua_Alloc原型的介面卡,然後指定為Lua的記憶體分配器就可以了,使得記憶體分配更加靈活。當然,如果不想自定義記憶體分配策略,也可以使用luaL_newstate,這樣Lua會幫你定義預設的記憶體分配策略。

我們可以先來看一下luaL_newstate的原始碼:

  1. // luaconf.h
  2. /* 
  3. @@ LUA_EXTRASPACE defines the size of a raw memory area associated with 
  4. ** a Lua state with very fast access. 
  5. ** CHANGE it if you need a different size. 
  6. */
  7. #define LUA_EXTRASPACE        (sizeof(void *))
  8. // lstate.c
  9. /* 
  10. ** thread state + extra space 
  11. */
  12. typedefstruct LX {  
  13.   lu_byte extra_[LUA_EXTRASPACE];  
  14.   lua_State l;  
  15. } LX;  
  16. /* 
  17. ** Main thread combines a thread state and the global state 
  18. */
  19. typedefstruct LG {  
  20.   LX l;  
  21.   global_State g;  
  22. } LG;  
  23. // lstate.c
  24. LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {  
  25.   int i;  
  26.   lua_State *L;  
  27.   global_State *g;  
  28.   LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof
    (LG)));  
  29.   if (l == NULL) return NULL;  
  30.   L = &l->l.l;  
  31.   g = &l->g;  
  32.   ......  
  33.   return L;  
  34. }  

可見,通過luaL_newstate 建立Lua虛擬機器時,第一塊申請的記憶體將用來儲存global_State(全域性狀態機)和lua_State(主執行緒)例項。為了避免記憶體碎片的產生,同時減少記憶體分配和釋放的次數,Lua採用了一個小技巧:利用一個LG結構,把分配lua_State和global_State的行為關聯在一起。這個LG結構是在C檔案內部定義,而不存在公開的H檔案中,僅供該C程式碼檔案使用,因此這種依賴資料結構記憶體佈局的用法負作用不大。


2. 關於global_State和lua_State

在一個獨立的Lua虛擬機器中,global_State是一個全域性的結構, 而lua_State可以有多個


global_State

global_State結構,我們可以稱之為Lua全域性狀態機。從Lua的使用者角度來看,global_State結構是完全感知不到的:我們無法用Lua公開的API獲取到它的指標、控制代碼或引用,而且實際上我們也並不需要引用到它。但是對於Lua的實現來說,global_State是十分重要的部分。

它管理著Lua中全域性唯一的資訊,主要是以下功能:

(1)記憶體分配策略及其引數

在呼叫lua_newstate的時候配置它們. 也可以通過lua_getallocf和lua_setallocf隨時獲取和修改它

(2)字串的hashtable

全域性的字串雜湊表,即儲存那些短字串,使得整個虛擬機器中短字串只有一份例項。具體參見 Lua字串處理

(3)垃圾回收相關的資訊,記憶體使用統計量

(4)panic, 當無保護呼叫發生時, 會呼叫該函式, 預設是null, 可以通過lua_atpanic配置.(用於異常處理)

(5)登錄檔, 登錄檔是一個全域性唯一的table

(6)記錄lua中元方法名稱 和 基本型別的元表

[注意, lua中table和userdata每個例項可以擁有自己的獨特的元表--記錄在table和userdata的mt欄位, 其他型別是每個型別共享一個元表--就是記錄在這裡].

(7)upvalue連結串列

(8)主lua_State, 一個lua虛擬機器中, 可以有多個lua_State, lua_newstate會創建出一個lua_State(稱為主執行緒), 並邦定到global_state的主lua_State上

lua_State

執行緒,這裡執行緒的概念區別於作業系統的執行緒,實際上也是Lua中定義的一種狀態機。lua_State主要是管理一個lua虛擬機器的執行環境, 一個lua虛擬機器可以有多個執行環境。

(1)要注意的是, 和nil, string, table一樣,lua_State也是lua中的一種基本型別, lua中的表示是TValue {value = lua_State, tt = LUA_TTHREAD}

(2)lua_State的成員和功能

a. 棧的管理, 包括管理整個棧和當前函式使用的棧的情況

b. CallInfo的管理, 包括管理整個CallInfo陣列和當前函式的CallInfo

c. hook相關的, 包括hookmask, hookcount, hook函式等

相關推薦

lua API 小記——— lua虛擬機器初始)

1. 建立lua虛擬機器 lua_State *lua_newstate (lua_Alloc f, void *ud) 建立一個新的獨立的lua虛擬機器. 引數指定了記憶體分配策略及其引數, 注意, 讓使用者可以定製記憶體分配策略是十分有用的, 比如在遊戲伺服器端使用lu

Qemu-KVM虛擬機器初始及建立過程原始碼簡要分析(一)

    我們知道,Qemu-KVM實際上包括Qemu和KVM兩部分,那麼在建立以及初始化虛擬機器時,實際上也是在這兩部分進行的。     KVM實際上就是kvm核心模組,包括kvm.ko、kvm-intel.ko、kvm-amd.ko三部分,後兩部分分別對應Intel體系的

Qemu-KVM虛擬機器初始及建立過程原始碼簡要分析(二)

    前面我們講了KVM核心層建立及初始化虛擬機器的一些工作過程,現在講一下Qemu層的流程以及與KVM核心層的配合過程。         Qemu層是從vl.c中的main()函式開始的,這裡通過在程式碼中新增一些註釋的方式來進行講解,中間省略了很多不重要或者我也沒有搞

OpenStack Nova:虛擬機器初始user-data & Cloud-init

    有的時候我們希望在boot虛擬機器的時候能夠對虛擬機器做些配置, 比如配置網路, 寫入檔案, 下載一些包並安裝等等, openstack中提供了實現這些的方法, 就是user-data 和Cloud-init。 user-data     在說user-data之前

Lua虛擬機器初始

1. 建立Lua虛擬機器 lua_State *lua_newstate(lua_Alloc f, void *ud) API可以為我們建立一個新的獨立的Lua虛擬機器。 引數指定了虛擬機器中的記憶體分配策略,例如我們已經在自己的程式碼中實現了記憶體池,這時候只需要寫一個符合lua_A

Lua知識整理】——Lua虛擬機器初始

1. 建立Lua虛擬機器 lua_State *lua_newstate(lua_Alloc f, void *ud) API可以為我們建立一個新的獨立的Lua虛擬機器。 引數指定了虛擬機器中的記憶體分配策略,例如我們已經在自己的程式碼中實現了記憶體池,這時候只需要寫一個符合lua_Alloc原型的介面卡

Lua 虛擬機器初始

轉自 https://blog.csdn.net/suhuaiqiang_janlay/article/details/56702381一、Lua指令碼語言1. 概述Lua是一種指令碼程式語言,與一般指令碼語言不同,被稱為是嵌入式的指令碼語言。Lua最著名的應用是在暴雪公司的

lua虛擬機器概述

何為虛擬機器 用於模擬計算機執行的程式.是個中間層,它處於指令碼語言和硬體之間的一個程式.每一門指令碼語言都會有自己定義的opcode(”操作碼”),可以理解為這門程式自己定義的”組合語言”.一般的編譯型語言,比如C等,經過編譯器編譯之後生成的都是與當前硬體環境相匹配的彙編程式碼;而指令碼型的語言,經過前端

大佬帶你深入淺出Lua虛擬機器

歡迎大家前往騰訊雲+社群,獲取更多騰訊海量技術實踐乾貨哦~ 本文由鵝廠優文發表於雲+社群專欄 作者:鄭小輝 | 騰訊 遊戲客戶端開發高階工程師 寫在前面:本文所有的文字都是我手工一個一個敲的,以及本文後面分享的Demo程式碼都是我一行一行碼的,在我之前已經有

linux下的虛擬機器 圖形安裝,指令碼安裝 及其管理

一.圖形安裝虛擬機器 二.虛擬機器管理命令 virt-manager ##開啟虛擬機器管理器 virsh list ##顯示正在執行的虛擬機器 vir

雲風的 BLOG: Lua 虛擬機器的封裝

我們面臨的需求是:建立一個(或幾個)Lua 虛擬機器,定期驅動它執行。重點在,定期驅動它執行。這可視為向虛擬機發送訊息,虛擬機器本質上是訊息驅動的(其實 Windows 程式也是)。通常,有一個時鐘驅動的行為,或者有一個渲染幀驅動的行為;然後,有外

漫談lua虛擬機器

什麼是虛擬機器? 大部分人都用c語言寫過簡單的小程式吧,寫好後用編譯器,比如turbo c或者visual c++編譯生成exe檔案,然後執行exe程式。exe檔案裡面其實存放著c程式碼對應的機器指令,執行exe就是排程cpu去一句句執行機器指令。 lua與c語言不同的地方在於,lua不需要編譯成e

Lua原始碼閱讀四——lua虛擬機器指令系統

本篇文章,主要探討一下lua中的指令系統(涉及到的檔案 lopcodes.c )。 在lua中,用32位的unsigned int型別來表示一條指令操作碼,32位值包含了6位的操作碼和26位的指令欄位兩部分內容。   All instructions have an opc

Lua虛擬機器之語法分析(二)

      最近實在是忙,專案就快要釋出了,加班加點在所難免。繼上一篇關於lua基本資料型別的簡單分析後,我將繼續寫閱讀lua虛擬機器的原始碼筆記,這是第一次接觸虛擬機器工作原理,lua虛擬機器程式碼量不大,是個很好的學習的例子,應當堅持下去。關於語法分析,我覺得只需要弄清

Java程式設計師從笨鳥到菜鳥之(九十四)深入java虛擬機器(三)——類的生命週期 下)類的初始

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

初始虛擬機器錯誤 - Error occurred during initialization of VM

文章目錄 1 環境配置資訊 1.1 伺服器配置資訊 1.2 Tomcat啟動引數 2 問題描述 3 問題解決 4 關於vm.overcommit_memory引數的說明 4.1 vm.overcommit

虛擬機器類載入機制(七)——類載入的過程(初始

類初始化時類載入過程的最後一步,前面的類載入過程中,除了在載入階段(類載入過程的一個階段)應用程式可以通過自定義類載入器參與之外,其餘動作完全由虛擬機器主導和控制。到了初始化階段,才真正開始執行類中定義的java程式程式碼。 在準備階段,變數已經賦過一次系統要求的初始值,而

阿里P7帶你深入理解Java虛擬機器總結——類初始過程

類的初始化過程 非法向前引用 編譯器手機的順序是由語句在原始檔中出現的順序決定的,靜態語句塊中只能訪問到定義在靜態語句之前的變數,定義它之後的變數,可以賦值,但不能訪問 public class Test{ static{ i=0; system.out.print(

深入理解java虛擬機器(三)(一個類載入器只初始一次類物件,不同類載入器可以對同一類物件進行初始

package com.ygl; class Final{public static final int x=6/3;//此處x在編譯時能計算出值,是編譯時的常量,則System.out.println(Final.x);直接輸出值,不再執行下面static(前提是fina

java 虛擬機器記憶體劃分,類載入過程以及物件的初始

涉及關鍵詞: 虛擬機器執行時記憶體 java記憶體劃分 類載入順序  類載入時機  類載入步驟  物件初始化順序  構造程式碼塊順序 構造方法 順序 記憶體區域   java記憶體圖  堆 方法區 虛擬機器棧 本地方法棧 程式計數器  區域性變量表   棧幀  java堆 執行時常量池   直接記憶體