a symmetry

雑な自己満足を残していくブログ 年度によってテンションが違うっぽい

セキュキャン2018に参加した話 ~集中コースYII Cコンパイラを自作してみよう!ゼミ~

こんにちは. 以前にも書いた通り集中コースの Y【システムプログラミングトラック】Cコンパイラを自作してみよう!ゼミに応募して通ったので参加しました. knium.hatenadiary.com

今更参加記かよって感じですが気にしないでいただけると.

このゼミの目標としてC言語でCコンパイラを書いて,その自作コンパイラで自分の書いたCコンパイラのソースをコンパイルできるようになるセルフホストを目標としてて,結論から言うと参加者の3/6人が達成しました(僕はまだ).みんなプロですごかった.

期間中には,全体講義だったりグループワークだったりがあるのですが色々省略.社会性のある他の参加者にご期待を.

あとCコンパイラについてはこの記事を読むより他の同ゼミ参加者/講師の方がためになるのでそっちを読んだ方がいいです.

セキュリティ・キャンプ 2018 (Cコンパイラ自作ゼミ) に参加してきました - 0x19f (Shinya Kato) の日報

セキュリティ・キャンプ2018参加記 - hsjoihs’s diary

http://anqou.net/aqcc_diary.html

Cコンパイラ制作の夏期集中コースが思っていた以上にうまくいった話|Rui Ueyama|note

当日まで

Cコンパイラが書けるようになる魔法の資料が渡されました.それを読んで各自で時間を割いて進捗を出すと言った感じです.ステップは十何段階 + α ぐらいあったのですが,色々メンタル案件(お酒ください)が立て続いたので4ステップぐらいしか終わらせることができなかった・・・ 前日から準備中にtiltしてバックれようかと思いましたが流石にしなかった.

ここまでの進捗は """'a=1; b=2; a+b; """ や 外部オブジェクトファイルで定義されたadd_one関数を"""add_one(1);"""で呼び出せたりとかそんな感じの四則演算(実は割り算を実装してない)がパースでき,変数が存在してて,外部のオブジェクトファイルで定義された関数が呼べて,それらのコードが吐けるぐらい.

初日

ずっとフォローしてるけど会ったことない

Harutaka Takeuchi (@nametaketakewo_) | Twitter

がセキュキャンに来ることを知ってたので新宿で名刺印刷するの手伝ってもらったりお昼食べたりした.多分当日の集合2時間前にコンビニで名刺作って刷って失敗したり昼ごはん中に名刺切ってたのは僕だけでは

見られてツイートされるのもインターネットとの複合現実であるセキュキャンの特徴っぽい. 名刺ですが,結局そんなに配らなかったので40枚刷って20枚ほど余りました(コミュ障). 人間の好き嫌い激しいのと配ってもそのあとの繋がりが確約されるわけでもないので同年代と繋がりたいなら #seccamp でツイートしてる方が繋がる面においては効果がありそうという気持ち. #seccamp でもそんなにツイートはしてないけど

その後は共通の座学を受けたりチェックインしたりした.個室でベットがありエアコンがついてて,この瞬間私はセキュリティキャンプでの勝ちを確信しました.自室にはエアコンもベッドもないんだよなぁ・・・

2日目

朝ごはんはだいたい食べたい奴だったので脳死で選んでいつもオーバーフローしかけて辛かった・・・ 朝ごはんトークンを無限個先読みできる頭と目が欲しかった.あとは備え付けのデイリーなカミソリが辛かったので,コンビニで買おうと思ったが売ってなくて完全にお菓子を買いに来た人になった.

Cコンパイラゼミの全体的な講義の時間は当日までに配られた実装をやるだけなので,2~4日目で大きな差異はなかったがとても充実していた.

初めて「真面目にアセンブリを読む」をした.スタックマシンでやっていくのだが,図を書くのにめっちゃ苦労した記憶がある. というか 「アセンブリが読める人類はスタックの中に何がどれだけ入ってどのレジスタにもなんの値が入ってるかを全員図を書かなくても完全理解してるもの」 だと勝手に思い込んでやってきたので「あ,書いていいんだ〜,というか書くんだ〜」とか思った.

あらかじめ共有されてたCの規格書に目を通したがBNFがわからないので hikalium大先生にたくさん 殴られ 教わりました.ここでは殴られを打ち消しにしてますが,本当に優しく分かりやすく教えてもらいました.本当に感謝.hikalium先生,わかんないとこたくさん聞いちゃったし理解遅かったけど怒ってませんよね!? 最後にBNFの部分を印刷してもらってずっと読んで再帰下降の気持ちになりながらコード書いたりした.

その日の進捗は """add(x,y) { x + y; } main() { add(1,2); }"""みたいに自分で関数定義して呼びだししたり.

3日目

朝ごはんがオーバーフローしかける.昨日の反動でBNFの表を読みながら朝ごはんを食べる.少しずつ気持ちがわかって来た気がするけど本当か???

この日めちゃくちゃ集中できていた自信がある,compound statement何もわからんって感じだったけど何となくわかるぞ,何となく.if文とwhile文とfor文を生やし,今まで変数が出て来たら暗黙的にint型だと定義していたものを明示的に宣言しないといけないようにした.

つまり,"""int main() { int a; for (a = 1; a < 10; a = a + 1) { a = a + 2; } return a;}"""だったり

"""int inc(int a) { return a+1; } int main() { int a; a=10; if (1) { return inc(a); }}""" が通るようになった.ちょっとずつC言語っぽくなってきて嬉しくなった記憶がある.

あと3日目には他の集中講義の様子を見に行く時間があったのでXの部屋に行ったのですが川合さんが面白い人すぎて面白かった.また,リバエンがすごい楽しそうだなぁとか思ったりした,分解したものを戻すリバースリバースエンジニアリングはしないらしいけど.

翌日に個人成果発表をするらしく進捗がァなので夜を消費してやっていこうとするも既存のバグ取りで終わる.(だいたい3:30ぐらいまでやってた)

4日目

寝坊した.部屋のインターホンの音がファミマの入店音だったため,反射的に「いらっしゃいませ〜〜」って心の中では言った.寝坊するとチューターとか色々の方が部屋に起こしにくるようだ.というか体調大丈夫?的な意味合いが強く,ちょっとの寝不足だったがそれ以上にやっていきがあったのでやっていった.ご迷惑をかけてすみません.

進捗としてはポインタ型の定義,ポインタの&, *演算子,ポインタ演算とそのコードが生えて来た,具体的に言うと

int main() { int a; a = 10; int *b; b = &a; return *b + 1;} // 11

// 外部オブジェクトファイルで定義されてる関数
void allocate4(int **p, int a, int b, int c, int d) {
    *p = malloc(sizeof(int) * 4);
    (*p)[0] = a;
    (*p)[1] = b;
    (*p)[2] = c;
    (*p)[3] = d;
}

int main() { int *p; allocate4(&p, 1, 2, 4, 8); int *q; q = p+3; return *q; } // 8

が通るようになってた.結構C言語では?

スライド発表では通るコードと通らないコード,進捗具合と3日間の開発に割いた時間を計測してたのでネタにしてスライドを作った.同じゼミで6人が同じものを作ってるのに発表が被ってなくてすごい.

部屋に戻って来てからリファクタリングをメインにした.ここら辺から,別の参加者のコードをちょっとずつ読み始めて色々参考にしてる.他のプロたちに圧倒的感謝

期間終了時にはここまでできてた.うーーーん・・・・ GitHub - Knium/knicc at 183668eacb57ea350c1ff09ae615a5863442b4d9

最終日

してないから!!!朝ごはん食べながら @nametaketakewo_ と話してたら「15分でシャワーと荷物片付けとチェックアウト」に気づいてちょっと遅れただけだから!!!!

知らない間に5日間が終わってた.気持ち3日目ぐらいだったのでマジかってなった.チューターや講師としていつか来たいなぁとなったし,他の講義もすごい魅力的な内容だったので来世また受けて見たいなぁと思った.

f:id:Knium:20180825162913p:plain

全体的に

技術的な面ではBNFの読み方や構文解析アセンブリでのコード生成をどのようにすれば良いのかを学んだ. しかし,僕が一番強く印象に残ったのが環境面である. 日常生活を送る上でどうしても避けることができない雑務や課題や用事などに文字通り何一つも追われることもなく,ただコードの事だけを考えていれば良いあの時間はとっっても幸せだった. そのような環境にいれてかつ分からないことがあったら信頼できる方に秒で質問できる.どう考えても最高では? またずっとCのコンパイラとそのコードについて向き合っていたので,いやでも何か一つに集中して諦めずに取り組む能力は身についた. 他の方々は日常的にこの集中ができるからきっと成長できるんだなぁとか.なのでこれをキャンプが終わってからも継続的に技術的な何か1つに取り組みたいと思う.

Cコンパイラゼミの参加者,講師,チューターをはじめとした全てのキャンプ関連者に感謝申し上げます.本当にありがとうございました.

f:id:Knium:20180914134001p:plain
期間中にコーディングに費やせた時間

作業時間が2.5日あってそのうち36時間ちょいを進捗に費やせてたっぽい

終わってから

セキュキャン終わってからもkniccの機能をちょっとずつ増やしていて,

  • *(<ident> + <number>) = <expr>のderefな代入
  • 配列の実装
  • 配列の添字アクセス
  • int型のグローバル変数の実装
  • char型
  • 文字列リテラル
  • +=, ==, !=, ||, &&, ++, -- 演算子
  • elseの実装
  • for文の(;;) 第1~3式の省略
  • リファクタリングしたらフィボナッチ数を計算できるようになった
  • -1 とかの表現

などができるようになった.セキュキャン期間中やその前に出した進捗よりもそのあとの心がけが大事だし絶えずに何かをやり続けることに意味があるんだろうなぁとキャンプ前に思ったし話も聞いた気がする.他人と比べることに意味はないけど,期間までに一番進捗を出せなかったのでどうせなら一番終わった後に進捗出せたらなぁと思ってる.

あとは

  • 構造体(.演算子, ->演算子を含む)
  • 引数としてポインタを取るケース
  • typedef
  • enum
  • bool
  • NULL
  • void
  • size_t
  • 関数でポインタを返すケース
  • 型キャスト

辺りが終われば1個のファイルぐらいは部分セルフコンパイルできちゃったりするのでは?やっていかないと・・・と思ったけど記述して見たら意外と多くて辛くなった

github.com

でやっていってるので見守っていただけると嬉しいです.