Python虛擬機設計方案


一、虛擬機設計方案

1.  架構風格

Python虛擬機實際上是一個解釋器,對編譯后的字節碼進行解釋、執行。因此解釋器風格顯然是最適合本項目的。

2.  分解視圖

 

虛擬機輸入為字節碼.pyc文件,由字節碼文件加載器將二進制的.pyc文件加載到內存,由執行引擎解釋執行,輸出為字節碼文件的執行結果。虛擬機總共分為以下四個模塊:

  • 字節碼加載器:python字節碼是按固定格式存放的二進制文件,而在虛擬機進程中,字節碼對象是codeobject類型,加載器的作用就是在類型體系模塊的支持下,將固定格式的二進制文件解析成內存中的codeobject類型對象,然后將codeobject交由執行引擎運行。
  • 執行引擎:本質是虛擬機的解釋器部分,本次虛擬機設計為棧式執行,所以解釋器維護一個操作棧,字節碼所有的操作都在棧上執行。解釋器主要運行在一個很大switch分支循環中,每個分支分別為對應字節碼的解釋,直到字節碼執行結束跳出循環結束虛擬機。解釋器還維護一個個虛擬機操作數棧幀frame,每個frame對應一個函數或方法的調用,且第一個frame為第一個codeobject。每個frame中有一個指向調用者frame的指針、當前frame字節碼位置的pc、對應的codeobjcet等。在解釋器中,在要操作棧上產生的類型對象都在堆中產生,依賴於堆區的內存管理,虛擬機可以不用管理對象的析構,而交由堆區自動垃圾回收。
  • 類型體系:在python中,一切都是對象,虛擬機有着一個龐大的類型體系。這個模塊也是最基本最重要的模塊,大致上有Integer、Float、String、List、Set、Dict、Tuple這7個基本類型,還有運行時的codeobject、frame,其他的內建類型type、function、method、slice、iterator、module等。還有一個特殊的類型object,它是虛擬機中大部分類型的父類。
  • 堆區內存管理:管理類型對象的關鍵,對象的分配權力交給了堆,在堆中使用自動內存管理算法,如標記-清除、標記-復制等算法。

3.  依賴視圖

依賴視圖展現了軟件模塊之間的依賴關系。

各個模塊之間的依賴關系如下所示:

 

 

 字節碼加載器部分分為兩個類,他們之間不存在依賴關系:

 

Type類存放了對象的類型信息和對應的方法,Object類依賴於Type類,其他的基本類型都繼承自Object類:

4.  執行視圖

執行視圖展示了系統運行時的時序結構特點。

 

5.  實現視圖

實現視圖是描述軟件架構與源文件之間的映射關系。

虛擬機源代碼目錄的結構如下所示:

pvm/
├── bin
├── include
│   ├── Code.h
│   ├── Dict.h
│   ├── Float.h
│   ├── GlobalVar.h
│   ├── Integer.h
│   ├── List.h
│   ├── Object.h
│   ├── OpCode.h
│   ├── Str.h
│   ├── Type.h
│   └── global.h
├── main.c
├── objects
│   ├── Code.c
│   ├── Dict.c
│   ├── Float.c
│   ├── Integer.c
│   ├── List.c
│   ├── Object.c
│   └── Str.c
├── runtime
└── utils
    ├── FileLoader.c
    ├── FileLoader.h
    ├── FileReader.c
    ├── FileReader.h
    ├── Log.c
    └── Log.h

二、核心數據結構

Python2字節碼文件結構

 

 

Magic number

 (4B)

Modified date

 (4B)

‘c‘

(1B,表示接下來是CodeObject)

 

Argcount

(4B)

Nlocals

(4B)

Stacksize

(4B)

Flags

(4B)

字節碼

‘s‘

(1B)

字節碼長度

(4B)

字節碼1,字節碼2 …

常量表

‘(‘

(1B)

常量個數

(4B)

常量1,常量2 …

變量表

‘(‘

(1B)

變量個數

(4B)

變量1,變量2 …

參數列表

‘(‘

(1B)

 

 

Cell var

‘(‘

(1B)

 

 

Free var

‘(‘

(1B)

 

 

文件名

‘s‘

(1B)

名字長度

(4B)

 

模塊名

‘t‘

(1B)

模塊名長度

(4B)

 

行號表(調試)

‘s‘

(1B)

 

 

 

三、運行環境和技術選型

Python是跨平台語言,其生成的字節碼文件在不同平台上具有相同的結構,因此虛擬機的運行環境可以是Windows,Linux,macOS。虛擬機的開發語言定為C語言。

四、核心工作機制

以運行一個內容為 “print(1 + 2 * 3)” 的python源文件為例,假設源文件經過編譯生成的字節碼是a.pyc,要執行這個文件,需要先讀取a.pyc中的字節碼列表和常量表。a.pyc的字節碼列表中有LOAD_CONST、BINARY_ADD、PRINT_ITEM、PRINT_NEWLINE等指令,常量表中有常量1和6,我們根據字節碼列表中的指令,在操作數棧上進行對應操作:指令為LOAD_CONST時從常量表取出數字放進棧里面,指令為BINARY_ADD時就從棧中取出數字相加,指令為PRINT_ITEM就打印計算結果,這樣就完成了對a.pyc的運行。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM