Mercurial > hg > Papers > 2019 > anatofuz-prosym
comparison Slide/slide.md @ 93:c3b973a23fee
update
author | Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 11 Jan 2019 10:41:24 +0900 |
parents | 3beea12854b0 |
children | 4f0eaa330295 |
comparison
equal
deleted
inserted
replaced
92:2387a5edfd58 | 93:c3b973a23fee |
---|---|
61 | 61 |
62 - Perl6専用のVMであり, Cで記述されている | 62 - Perl6専用のVMであり, Cで記述されている |
63 - レジスタマシンとして実装されている. | 63 - レジスタマシンとして実装されている. |
64 - MoarVMはバイトコードインタプリタを `src/core/interp.c` で定義しており, この中の関数 `MVM_interp_run` でバイトコードに応じた処理を実行する | 64 - MoarVMはバイトコードインタプリタを `src/core/interp.c` で定義しており, この中の関数 `MVM_interp_run` でバイトコードに応じた処理を実行する |
65 | 65 |
66 ## MVM_interp_run | 66 - マクロDISPATCHで, ラベルgotoかcase文に, バイトコードに対応した処理を行う |
67 | 67 - この中の `OP` で宣言されたブロックがそれぞれバイトコードに対応する処理となっている. |
68 - DISPATCHマクロは次の様に記述されており, この中の `OP` で宣言されたブロックがそれぞれオペコードに対応する処理となっている. | |
69 - この中では `GET_REG` などのマクロを用いてMoarVMのレジスタにアクセスする. | 68 - この中では `GET_REG` などのマクロを用いてMoarVMのレジスタにアクセスする. |
70 - `cur_op`は次のオペコード列が登録されており, マクロ `NEXT` で決められた方法で次のオペコードに遷移する. | 69 - `cur_op`は次のバイトコード列が登録されており, マクロ `NEXT` で決められた方法で次のバイトコードに対応した処理に遷移する. |
71 | 70 |
72 ``` | 71 ``` |
73 DISPATCH(NEXT_OP) { | 72 DISPATCH(NEXT_OP) { |
74 OP(const_i64): | 73 OP(const_i64): |
75 GET_REG(cur_op, 0).i64 = MVM_BC_get_I64(cur_op, 2); | 74 GET_REG(cur_op, 0).i64 = MVM_BC_get_I64(cur_op, 2); |
79 | 78 |
80 ``` | 79 ``` |
81 | 80 |
82 ## MVM_interp_runで使用されているマクロ | 81 ## MVM_interp_runで使用されているマクロ |
83 | 82 |
83 - マクロDISPATCHでは | |
84 | |
84 - MVM_interp_runではマクロを利用してMoarVMの環境などにアクセスしている | 85 - MVM_interp_runではマクロを利用してMoarVMの環境などにアクセスしている |
85 - 頻出するマクロに `GET_REG` があり, 次のような使い方をする | 86 - 頻出するマクロに `GET_REG` があり, 次のような使い方をする |
86 | 87 |
87 ``` | 88 ``` |
88 OP(const_i64): | 89 OP(const_i64): |
89 GET_REG(cur_op, 0).i64 = MVM_BC_get_I64(cur_op, 2); | 90 GET_REG(cur_op, 0).i64 = MVM_BC_get_I64(cur_op, 2); |
90 cur_op += 10; | 91 cur_op += 10; |
91 ``` | 92 ``` |
92 | 93 |
93 - これはバイトコードに埋められた数値を利用して, レジスタ情報を取得/設定などをする | 94 |
94 - `reg_base` はMoarVMの現在のフレームのレジスタ情報が保存されたポインタであり, 本来のMVM_interp_runではローカル変数として利用している | 95 - `GET_REG`はバイトコードに埋められた数値を利用して, レジスタ情報を取得/設定などをする |
95 | 96 - `GET_REG`は次の様に展開される |
96 | 97 |
97 ``` | 98 ``` |
98 (i->reg_base[*((MVMuint16 *)(i->cur_op + 0))]).i64 = MVM_BC_get_I64(i->cur_op, 2); | 99 reg_base[*((MVMuint16 *)(cur_op + 0))].i64 = MVM_BC_get_I64(cur_op, 2); |
99 i->cur_op += 10; | 100 |
100 goto cbc_next(i); | 101 ``` |
101 ``` | 102 |
102 | 103 - `reg_base` はMoarVMの現在のフレームのレジスタ情報が保存されたポインタであり, MVM_interp_runではローカル変数として利用している |
103 | 104 |
104 ## MVM_interp_run | 105 ## MVM_interp_runで使用されているマクロ |
105 | 106 |
106 - MVM_interp_runでは次のオペコードをフェッチする際に `NEXT_OP` マクロを介して計算を行う. | 107 - 次のバイトコード命令に遷移するマクロ `NEXT` は, ラベルgotoが使用可能な場合次の様に記述されている |
107 - オペコードが対応する命令を実行する際は, `MVM_CGOTO` フラグが立っている場合はCのラベルgotoを利用し, 使えない場合はswitch文を利用して遷移する. | 108 - `NEXT`自体はラベルテーブルにアクセスし, ラベルを取り出す |
108 | 109 - 次のバイトコードを取り出すのは, `NEXT_OP` というマクロが担っている |
109 | 110 |
110 ``` | 111 ``` |
111 #define NEXT_OP (op = *(MVMuint16 *)(cur_op), cur_op += 2, op) | 112 #define NEXT_OP (op = *(MVMuint16 *)(cur_op), cur_op += 2, op) |
112 | |
113 #if MVM_CGOTO | |
114 #define DISPATCH(op) | |
115 #define OP(name) OP_ ## name | |
116 #define NEXT *LABELS[NEXT_OP] | 113 #define NEXT *LABELS[NEXT_OP] |
117 #else | 114 |
118 #define DISPATCH(op) switch (op) | 115 ``` |
119 #define OP(name) case MVM_OP_ ## name | 116 - マクロ `NEXT` は次の様に展開される |
120 #define NEXT runloop | 117 |
121 #endif | 118 ``` |
122 ``` | 119 goto *LABELS[(op = *(MVMuint16 *)(cur_op), cur_op += 2, op)]; |
120 ``` | |
121 | |
123 | 122 |
124 ## MVM_interp_run | 123 ## MVM_interp_run |
125 | 124 |
126 - ラベル遷移を利用する場合は配列`LABELS`にアクセスし, ラベル情報を取得する | 125 - ラベル遷移を利用する場合は配列`LABELS`にアクセスし, ラベル情報を取得する |
127 | 126 |
227 __code cbc_const_i64(INTERP i){ | 226 __code cbc_const_i64(INTERP i){ |
228 GET_REG(i->cur_op, 0,i).i64 = MVM_BC_get_I64(i->cur_op, 2); | 227 GET_REG(i->cur_op, 0,i).i64 = MVM_BC_get_I64(i->cur_op, 2); |
229 i->cur_op += 10; | 228 i->cur_op += 10; |
230 goto cbc_next(i); | 229 goto cbc_next(i); |
231 } | 230 } |
231 (i->reg_base[*((MVMuint16 *)(i->cur_op + 0))]).i64 = MVM_BC_get_I64(i->cur_op, 2); | |
232 i->cur_op += 10; | |
233 goto cbc_next(i); | |
232 ``` | 234 ``` |
233 | 235 |
234 ## NQP | 236 ## NQP |
235 - Perl6の機能を制約したプログラミング言語であり, Perl6はNQPで記述されている | 237 - Perl6の機能を制約したプログラミング言語であり, Perl6はNQPで記述されている |
236 - その為Perl6処理系は, NQPの動作を目的に実装することでPerl6の動作が可能となる | 238 - その為Perl6処理系は, NQPの動作を目的に実装することでPerl6の動作が可能となる |