本書按內(nèi)容分為六個部分,*部分介紹語言虛擬機(jī)的基本概念,并實現(xiàn)字節(jié)碼解釋器;第二部分,實現(xiàn)內(nèi)嵌類型,如整數(shù)、字符串、列表和字典等;第三部分,實現(xiàn)了函數(shù);第四部分,實現(xiàn)自定義類、對象和方法;第五部分,實現(xiàn)垃圾回收,也就是自動內(nèi)存管理;第六部分,模塊和迭代。本書的章節(jié)內(nèi)容之間都有很強(qiáng)的依賴性,后面的章節(jié)內(nèi)容都是在前面章節(jié)的基礎(chǔ)上去實現(xiàn)的,所以讀者必須按部就班地從前向后閱讀,才能保證閱讀的流暢。
本書適合的人群包括:在校大學(xué)生(可以通過本書掌握很多計算機(jī)工作運行的核心知識),以及對編譯器,編程語言感興趣的人。
本書內(nèi)容新穎、通俗易懂,讀者只需懂得相關(guān)的類C語言即可閱讀。
編程語言是每個程序員每天都要使用的基本工具,現(xiàn)代的主流編程語言以 Java、javascript 和
Python 為代表,都是運行在語言虛擬機(jī)之上的,很多人都很想知道語言虛擬機(jī)的內(nèi)部構(gòu)造。我從2017年開始在知乎撰寫專欄《進(jìn)擊的Java新人》,專欄中對 Java 語言虛擬機(jī)的字節(jié)碼和垃圾回收做了一些簡單的介紹,很多讀者發(fā)私信給我,表示非常想知道更多的細(xì)節(jié)。在這樣的背景下,我開始了本書的寫作。我希望在這本書中和讀者一起從零開始構(gòu)建一個完整的編程語言虛擬機(jī),它將會涉及到字節(jié)碼的解析執(zhí)行、對象系統(tǒng)、語言內(nèi)置功能和垃圾回收等多個主題。
本書適合的人群包括:
1. 在校大學(xué)生,大一大二的同學(xué)可以通過本書掌握很多計算機(jī)工作運行的核心知識
。
2. 對編譯器和編程語言感興趣的人。相比起直接將一門語言編譯成機(jī)器碼,將其編譯為虛擬機(jī)上的字節(jié)碼文件會簡單很多,所以掌握一門虛擬機(jī)字節(jié)碼,甚至自己實現(xiàn)一個虛擬機(jī)對學(xué)習(xí)編譯器、了解編程語言特性有很大的幫助。
本書的內(nèi)容雖然很新穎,但是對讀者門檻的要求并不高。讀者只要簡單地掌握一些Python或者某一門類C語言(例如Java)即可。在本書中,我選擇了使用C 來實現(xiàn)語言虛擬機(jī)。這主要是由于在內(nèi)存操作方面,C 可以更精準(zhǔn)地表達(dá)作者的意圖。C 是一門很難的語言,相比起 Java、Python和PHP 等語言,流行度也不高,但是讀者不必有畏難情緒,本書在使用 C 的時候是比較克制的。本書并沒有使用很多 C 的高級技巧,最多只涉及到類和一點點的模板編程的知識。C 是一門多范式的編程語言,我們不可能在一個工程中使用所有的編程范式。本書中所涉及的代碼,讀者只需要有任何一門面向?qū)ο蟮恼Z言的編程經(jīng)驗即可順利閱讀。
如何使用本書:
本書共分為六個部分,第一部分介紹語言虛擬機(jī)的基本概念,并實現(xiàn)字節(jié)碼解釋器;第二部分,實現(xiàn)了內(nèi)嵌類型,如整數(shù)、字符串、列表和字典等;第三部分,實現(xiàn)了函數(shù);第四部分,實現(xiàn)自定義類、對象和方法;第五部分,實現(xiàn)垃圾回收,也就是自動內(nèi)存管理;第六部分,模塊和迭代。其中第二、第三和第四部分的實現(xiàn)并不是完全獨立的,而是相互嵌套依賴的。比如完整的對象系統(tǒng)必然依賴函數(shù),而 Python 中的函數(shù)本身也是對象,這就產(chǎn)生了循環(huán)依賴,解決這個問題的辦法是先實現(xiàn)一套相對簡單的對象系統(tǒng),然后基于此也實現(xiàn)一套簡單的函數(shù)系統(tǒng),再回過頭來補充完善對象系統(tǒng)……這樣螺旋式地上升,最終完成整個系統(tǒng)的搭建。
本書章節(jié)的內(nèi)容之間都有很強(qiáng)的依賴,后面章節(jié)的內(nèi)容都是在前面的章節(jié)的基礎(chǔ)上去實現(xiàn)的。所以讀者必須按部就班地從前向后閱讀,才能保證閱讀的流暢。本書為了節(jié)約篇幅,對于一些邏輯比較簡單的代碼,就都省略了。讀者可以在https://gitee.com/hinus/pythonvm 里找到全部的代碼,包括該項目最近的更新以及各種提交記錄。在提交記錄中,讀者可以清晰地看到本項目的進(jìn)化過程。
感謝出版社編輯劇艷婕的耐心審校,尤其還要感謝專欄《進(jìn)擊的Java新人》的讀者,是你們的精彩評論和學(xué)習(xí)反饋引發(fā)了這本書的創(chuàng)作。
實現(xiàn)一個高效的編程語言虛擬機(jī)是一個十分復(fù)雜的問題,從Hotspot虛擬機(jī)的發(fā)展過程中就可以看出來。書中難免有訛錯紕漏之處,歡迎讀者及時指出。書中如果有描述不清的地方,也歡迎讀者來信交流,可發(fā)至郵箱:hinus@163.com。
海納,曾就職于人大金倉、網(wǎng)易游戲,現(xiàn)就職于華為編譯器實驗室。長期從事編譯器和編輯語言虛擬機(jī)的研發(fā)工作,擅長編譯器后端和垃圾回收機(jī)制。
第1章編程語言虛擬機(jī)1
1.1編程語言的發(fā)展1
1.2編程語言虛擬機(jī)2
1.3開發(fā)環(huán)境5
第2章編譯流程6
2.1Python字節(jié)碼6
2.2詞法分析7
2.3文法分析10
2.4抽象語法樹13
2.4.1構(gòu)建AST14
2.4.2遞歸程序的本質(zhì)16
2.4.3訪問者模式21
2.4.4用Visitor重寫AST29
第3章二進(jìn)制文件結(jié)構(gòu)32
3.1pyc文件格式32
3.2加載CodeObject34
3.2.1準(zhǔn)備工具36
3.2.2創(chuàng)建CodeObject41
3.3整理工程結(jié)構(gòu)47
3.4執(zhí)行字節(jié)碼49
第4章實現(xiàn)控制流55
4.1分支結(jié)構(gòu)55
4.1.1條件判斷56
4.1.2跳轉(zhuǎn)59
4.1.3True、False和None60
4.2循環(huán)結(jié)構(gòu)62
4.2.1變量62
4.2.2循環(huán)內(nèi)的跳轉(zhuǎn)67
第5章基本的數(shù)據(jù)類型75
5.1KlassOop二元結(jié)構(gòu)75
5.2整數(shù)78
5.3字符串82
第6章函數(shù)和方法85
6.1函數(shù)85
6.1.1棧幀86
6.1.2創(chuàng)建FunctionObject89
6.1.3調(diào)用方法92
6.2變量和參數(shù)96
6.2.1LEGB規(guī)則96
6.2.2函數(shù)的參數(shù)104
6.2.3參數(shù)默認(rèn)值107
6.3Native函數(shù)111
6.4方法115
第7章列表和字典122
7.1列表122
7.1.1列表的定義122
7.1.2操作列表126
7.2字典154
7.2.1字典的定義154
7.2.2操作字典157
7.3增強(qiáng)函數(shù)功能165
7.3.1靈活多變的函數(shù)參數(shù)165
7.3.2閉包和函數(shù)修飾器172
7.4總結(jié)179
第8章類和對象180
8.1類型對象180
8.1.1TypeObject180
8.1.2object185
8.1.3通過類型創(chuàng)建對象189
8.2自定義類型191
8.3創(chuàng)建對象196
8.4操作符重載206
8.5繼承215
第9章垃圾回收223
9.1自動內(nèi)存管理223
9.1.1概念定義223
9.1.2引用計數(shù)224
9.1.3圖的知識226
9.1.4Tracing
GC231
9.2復(fù)制回收234
9.2.1算法描述234
9.2.2算法實現(xiàn)235
9.2.3建堆237
9.2.4在堆中創(chuàng)建對象243
9.2.5垃圾回收247
第10章模塊和庫261
10.1import語句261
10.1.1ModuleObject262
10.1.2加載模塊264
10.1.3from子句266
10.2builtin模塊268
10.3加載動態(tài)庫271
10.3.1定義接口27
10.3.2實現(xiàn)math module277
第11章迭代281
11.1異常281
11.1.1finally子句281
11.1.2break和continue287
11.1.3Exception291
11.2自定義迭代器類306
11.3Generator309
11.3.1yield語句309
11.3.2Generator對象311
11.4總結(jié)317
附錄APython2字節(jié)碼表318
附錄B高級算法321
B.1字符串查找321
B.2排序算法325
B.2.1快速排序325
B.2.2選擇排序328
B.2.3堆排序329