我寫了一個TypeScript虛擬機器: Tser。
Github地址:tser-project/tser。
安裝使用
$ brew tap tser-project/tser && brew install tser;
$ tser ./input.ts;
為什麼要創造Tser?
TypeScript(TS)是一個偉大的發明,讓我們在複用JS生態的同時擁有了靜態型別語言的開發體驗。
TS本質是一門預編譯語言,編譯到JS後再使用JS虛擬機器執行,由於強依賴於JS,也因此無法擺脫JS的一些頑疾,比如執行效率。而TS本身是靜態型別語言,擁有確定的資料型別標記,只是在轉義為JS時丟失了型別標記;如果我們能直接執行TS程式,而不是先轉義為JS再執行,這些資料型別標記可以為程式帶來很大的效能提升。
我們來看一組效能對比資料,僅對比fib(42)
在各個虛擬機器或語言中的效能表現(並不能完全依此來作為效能評價標準;測試條件:同一裝置同一狀態,編譯過程均未使用任何優化)。
語言 | 虛擬機器 | 執行耗時(ms) |
---|---|---|
TypeScript | deno | 4150 |
JavaScript | v8 / node | 3859 |
TypeScript | Tser | 2035 |
C++ | -- | 2106 |
TS技術發展很快,業界已經有越來越多的專案使用TS開發和重構;拋開眼下去看TS技術的發展,它的終點會在哪裡?會一直停留在一個預編譯語言上嗎?當TS生態發展越來越健全,是不是還有必要完全依託於JS的生態?業界會不會誕生一個真正的TS虛擬機器(Deno並不是)?如果業界有一個穩定且高效能的TS虛擬機器,對TS生態是不是一件好事,會不會將TS推向一個新的高度?
這些問題思考了很久。
<u>TS應該無法取代JS的生態,但是在某些領域,TS可以脫離JS生態而獨立存在;TS虛擬機器是獨立TS生態的基石,可以讓TS在這些領域有明顯優於JS的執行時表現,併為這些領域帶來實際的業務收益。</u>
Tser能做什麼?
Tser編譯效能相對不高而執行時效能高,更適合獨立後臺服務、Serverless等場景。如果語法支援完善,可以執行絕大部分現有的使用TS編寫的後臺服務時,這些服務可以因此獲得很大的效能提升。
Tser目前能做的事情還非常少,因為語法支援很不完善,僅能支援一些簡單指令碼的執行,比如應該能夠支援一些簡單的雲函式場景。
Tser技術原理
Tser前端依託於Antlr來生成的語法解析器,然後進行語法樹的生成與遍歷;後端依託於LLVM建設,將TS程式碼編譯為LLVM IR,並使用其JIT引擎立即執行IR。
業界雷同產品: AssemblyScript、StaticScript
Tser語法支援
變數
支援var
let
const
, var
與let
相同。
基礎型別
型別 | 位元組 (in 64bit) | 支援 |
---|---|---|
boolean | 1 | ✔️ |
number | 4 | ✔️ 同int32 |
int32 | 4 | ✔️ |
int64 | 8 | ✔️ |
float | 4 | ✔️ |
double | 8 | ✔️ |
string | -- | ✔️ 暫不支援運算 |
運算子
運算子 | 支援 |
---|---|
+ - * / % | ✔️ |
++ -- | ✔️ |
+= -= *= /= %= | ✔️ |
< > <= >= | ✔️ |
== === != !== | ✔️ === 與== 目前沒有區別 |
&& ‖ | ✔️ |
! | ✔️ |
? : | ✔️ |
() | ✔️ |
. | ✔️ |
邏輯控制語句
語句 | 支援 |
---|---|
if else | ✔️ |
while do while | ✔️ |
for | ✔️ |
switch | ✔️ |
continue | ✔️ |
break | ✔️ |
函式
支援絕大部分函式功能,函式巢狀,暫不支援閉包和函式引數。
Class
Class支援繼承、多型,支援Class組合,支援靜態屬性與靜態方法,不支援方法過載;Class繼承和多型使用類似虛擬表的方式來支援,多型支援方法和屬性。
內建物件
目前內建物件支援力度非常低,僅用於測試。
內建物件 | 方法 |
---|---|
console | debug log info warn error |
Date | now |
暫不支援
module
內建物件
、Event Loop
、GC
等等。
貢獻Tser
Tser是一個巨大的工程,很難用一己之力完成。Tser現在還是一個baby,更希望它能起到一個拋磚引玉的作用,能聚集起一些有能力的人來一起建設。