# A10: rubi
###### tags: `sysprog2016`
:::info
主講人: [jserv](http://wiki.csie.ncku.edu.tw/User/jserv) / 課程討論區: [2016 年系統軟體課程](https://www.facebook.com/groups/system.software2016/)
:mega: 返回「[進階電腦系統理論與實作](http://wiki.csie.ncku.edu.tw/sysprog/schedule)」課程進度表
:::
## 預期目標
* 學習 JIT 編譯器設計,透過輔助開發工具
* 設計 benchmark suite
* 延展程式語言
## [DynASM](http://luajit.org/dynasm.html)
根據[教學](http://corsix.github.io/dynasm-doc/tutorial.html)可以輸出碎形,但是速度非常慢
```shell
$ git clone https://github.com/corsix/dynasm-doc.git
$ cd dynasm-doc
$ git submodule update --init
$ cp bf_c.c tutorial.c
$ gcc -o tutorial tutorial.c
$ ./tutorial mandelbrot.bf
```
現在要用 JIT 版本加速
首先要先在 header 中加上
```C
#include "luajit-2.0/dynasm/dasm_proto.h"
#include "luajit-2.0/dynasm/dasm_x86.h"
```
接著將 interpreter 改為 compiler
```c
- static void bf_interpret(const char* program, bf_state_t* state)
+ static void(* bf_compile(const char* program) )(bf_state_t*)
```
呼叫的部份也要改
```c
- bf_interpret(program, &state);
+ bf_compile(program)(&state);
```
變數部份也要做一些新增和修改
```c
- int nskip = 0;
+ dasm_State* d;
+ unsigned npc = 8;
+ unsigned nextpc = 0
```
接下來要根據不同平台去定義不同的 arch (硬體架構):
```c
|.if X64
|.arch x64
|.else
|.arch x86
|.endif
```
在上面有宣告 dasm_State* d; 可以呼叫 [dasm_init 來初始化](http://corsix.github.io/dynasm-doc/reference.html#dasm_init)
```c
|.section code
dasm_init(&d, DASM_MAXSECTION);
```
第二個參數為在開始 define 的 DASM_MAXSECTION 1
結束以上動作後,還沒完全的初始化必須在 call dasm_setupglobal(&d, labels, lbl__MAX);
```c
|.globals lbl_
void *labels[lbl__MAX];
dasm_setupglobal(&d, labels, lbl__MAX);
```
在 call dasm_setup(&d, bf_actions);
```
|.actionlist bf_actions
dasm_setup(&d, bf_actions);
```
將 actionlist 當作參數傳入
最後 call dasm_growpc(&d, npc); 來完成初始化
```c
dasm_growpc(&d, npc);
```
npc 為目前被分配的 dynamic label
接下來要做一連串的定義,和巨集
![](https://hackpad-attachments.s3.amazonaws.com/embedded2015.hackpad.com_GRZwN80zPkp_p.342028_1445782118406_abstraction.png)
接下來一樣做 Emitting 各 expression ,如 Arithmetic, I/O, Loops, 完成 compile。
用 JIT compiler 來執行之前的程式:
```shell
$ cp bf_dynasm.c tutorial.c
$ gcc -o minilua luajit-2.0/src/host/minilua.c -lm
$ ./minilua luajit-2.0/dynasm/dynasm.lua -o tutorial.posix64.c -D X64 tutorial.c
$ gcc -o tutorial tutorial.posix64.c
$ ./tutorial mandelbrot.bf
```
## rubi
[rubi](https://github.com/sysprog21/rubi) 是成大資訊系師生合作開發、類似 Ruby 語法的程式語言實作,提供 JIT compiler,主體程式碼不到一千行,具體而微。Rubi 使用前述 [DynASM](http://luajit.org/dynasm.html) 打造,請留意看 `Makefile` 得知編譯方式。
## 作業要求
* 作在 github 上 fork [rubi](https://github.com/sysprog21/rubi),注意不要跟 2015 年的作業搞錯了
* 依據 `prog` 的程式,熟悉 Rubi 語法,著手設計類似 [A09: jit-compiler](/s/SJ7AZJv1e) 裡頭整合性的 benchmark suite,提出改善內建 benchmark suite 效能的機制,並且要能夠充分解釋行為,需要一併透過 gnuplot 自動產生效能分析圖表
* 對 Rubi 程式語言進行擴充,使其能夠支援 concurrency / parallelism。需要有程式語言的規格描述並且驗證。
* 學習 [Ruby Concurrency and Parallelism: A Practical Tutorial](https://www.toptal.com/ruby/ruby-concurrency-and-parallelism-a-practical-primer) 的語法和觀念