Slide 104
Slide 104 text
Psyco の中の a + b
Psyco のソースコード抜粋(..... は中略)
/* ① c/Objects/pintobject.c(実物・抜粋) */
static vinfo_t* pint_add(PsycoObject* po,
vinfo_t* v, vinfo_t* w) {
CONVERT_TO_LONG(v, a); /* int? 検査+箱外し */
x = integer_add(po, a, b, true);
..... /* overflow → CPython の nb_add へ退避 */
/* ② c/i386/iencoding.c */
BEGIN_CODE
COPY_IN_REG(v1, rg);
/* MOV rg,(v1) */
COMMON_INSTR_FROM(group, rg,
/* ADD rg,(v2) */
v2->source);
END_CODE
if (ovf && runtime_condition_f(po, CC_O))
return NULL;
/* あふれ検知も自前 */
① 型ガードも“退避路”も、自分で設計
int か検査して箱外し、あふれたら CPython へ退避
—— 型の“意味の再実装”だけで 約9,200行
② レジスタ割り当ても、あふれ検知も自前
ADD 1命令のために MOV・フラグ管理・レジスタ確保
—— コード生成の共通土台で 約5,900行
③ 命令バイトを、1バイトずつ直書き
0x83 は ADD の命令番号。ModRM バイトも手計算
—— x86 一式 約3,000行のうち、生バイト書きは 約1,500
行
/* ③ c/i386/iencoding.h */
code[1] = 0xC0 | (group<<3) | (rg);
code[2] = (code_t) _v; code[0] = 0x83;
code += 3; .....
104