# 環境構築
# デバッグ方法
- コンパイル時に関数に型名を入れるので,nmで関数名を取り出す必要がある
$nm /rust/rust/build/x86_64-unknown-linux-gnu/stage1/bin/../lib/librustc_driver-ce53599820ba664c.so | grep parse_expr
# compilerソースながめる
- https://github.com/rust-lang/rust/tree/master/compiler
- メイン部分
- クレート寄せ集めっぽい
run_compiler()
||
lambda式FnOnce
rustc_interface::interface::create_compiler_and_run::hd06f00e0a4bf9137 at interface.rs:190:5
# backtrace
|
|
-
if let Some(stmt) = this.parse_full_stmt()? {} みたいな構文
-
macro文
- https://doc.rust-lang.org/nightly/nightly-rustc/rustc_expand/mbe/index.html
- 例
- walk_list
- 引数がvisitor, method, list の3つで構成されている.
- 引数3つ以上の場合もある.
- visitorパターン
- デザインパターンを読もう
- https://www.amazon.co.jp/gp/product/B00I8ATHGW/ref=dbs_a_def_rwt_bibl_vppi_i0
walk_list
はこのあたりで使われているらしい
|
|
- passes
- https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/passes/index.html
- configure_and_expand()
- https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/passes/fn.configure_and_expand.html
- コンパイラの前処理的な
- harness
- importとかで指定されてるライブラリの読み込み
- etc
# lldbのbreak pointをsaveする
-
lldbで
br write -f /tmp/rust_breakpoint.txt
-
jsonが書き込まれる
|
|
#
/rust/rust/compiler/rustc
- src/main.rs
- _F1~_F6という関数がある
jmalloc_sys
rustc_driver
というのをrustcにしたかった.
# lldbがコンパイラのコードをうまく読み込めてないからブレークポイントがうまく立てられない感じ.
parse_expr
で止められない!break point
がなんかよくわからないところについてる.
# もう少しbreakpointの問題を追求する
- 関数のアドレスが実際のものとずれているのが問題
- シンボルファイルから正しいアドレスを特定できればそのアドレスを使ってブレークポイントを設定できるはず.
- stage1のコンパイラを使ってやる.
- ダイナミックリンキングライブラリ
/rust/rust/build/x86_64-unknown-linux-gnu/stage1/bin/../lib/librustc_driver-ce53599820ba664c.so
# 次はgdbでやってみる
b main
,run
をやるとダイナミックリンクが発動して行き先ができる.- gdbのほうが若干まし.
#
rustc_interface/src/callbacks.rs
span_debug()
struct Compiler
- pub(crate)
- 自分のname spaceにしか公開しない.
- pub(crate)
impl Compiler
(メソッド群)run_compiler()
R + Send
#
rustc_interface/src/lib.rs
- passes
#
'a
(頭のシングルクオート)
- ライフポインタパラメーター
# passesの終わったルーチンのところは正しくブレークポイントでとまる.
- rustcはlldbを今はサポートしてないっぽい
- 走らせてからbreakpointを付ければリンクがあるから行ける
# これでparse部分は止められた
b rustc_interface::passes::parse
b parse_crate_from_file
backtrace
# back trace
/rust/rust/compiler/rustc_parse/src/parser/item.rs
|
|
compiler/rustc_parse/src/parser/item.rs
- parse_crate_mod()
- parse_item()
- parse_item_common()
- Selfはキーワード
- collect_tokenがparse_itemを実行
- parse_item_kind()
- check_fn_front_matter()
- fnのパーサー(関数判定)
- parse_ident()
- 関数名が入るはず(pで中身見れないのつらいな.)
- fn where構文
- parse_fn_body()
- check_fn_front_matter()
|
|
# 2020/11/29
# テストコード
|
|
# used with no filenames on the command line, reading from STDIN.
# compiler/rustc_ast
- READMEにあったURL
- https://rustc-dev-guide.rust-lang.org/the-parser.html
- https://rustc-dev-guide.rust-lang.org/macro-expansion.html
- マクロ展開系を書くのは新たに1言語書くのに等しい…
- マクロルールで定義する方法
- src
- ast.rs
- trait
- lifetime
- AngleBracketedArg
- ParamKindOrd
- 関数の中で関数を定義(nested function)
- operator
- Exprのspanの中身をみたい.
- exprが1 + 1だったらspanには1が入っているはず
- precedence
- operationのオーダー
- ExprKind::Binary
- ast.rs
# compiler/rustc_parse/src/parser/expr.rs周辺をトレース
- used with no filenames on the command line, reading from STDIN.
- mk_expr_opでexprのoperationを作るはず
- bump() bump_with()
- https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/parser/struct.Parser.html#method.bump
- advance the parser by one token
- トークン一つ読み飛ばす…?
- 1 + 1だったら1の次に1を読む感じか.
- op.fixity()
- 計算された値はrhsに入るはず(pで中身が見れないから全部"〜はず"になる…)
- mk_expr_sp()
- 計算の優先順位をみて順番を変える.
- recursive descent
# コード生成部分をみる
- used with no filenames on the command line, reading from STDIN.
- compiler/rustc_codegen_ssa/README.md
- LLVM IRを生成する前にMIRを生成する.
- compiler/rustc_mirあたりを読む
- compiler/rustc_middle
- compiler/rustc_hir
- high level IR
- src
- arena.rs
- def.rs
- DefKind
- 定義できるものの種類をまとめた
- DefKind
- rustcで生成後のものは見れる
|
|
- used with no filenames on the command line, reading from STDIN.
- rustc -Zunpretty=hir-tree /tmp/test.rs
- こっちのほうが正解
- 実行してみるとめっちゃ長いHIRのコードが見れる.
# high level からじゃなくて low levelからアプローチしてみる?
- rustc_passesからアプローチをかけるか.
- public/rustc_mir_build/src/build/
- into.rs
- into_expr()
- into.rs
- codegenっぽいところ
|
|
- rustでunicode使えるはず
- https://doc.rust-lang.org/book/ch08-02-strings.html
# compiler/rustc_interface/src/queries.rs
- lower_to_hir
# compiler/rustc_codegen_ssa
- codegen_crate()
- cgu_name_builder()
- codegen_unit()
- monomorphization
- ポリモーフィズムなところをアセンブラ用にモノに直すこと
- dep_graph
- dependency graph
- ongoing_codegen
- パラレルコンパイル
- LTO
- linking最適化をしてスピードアップを図る
- https://doc.rust-lang.org/rustc/linker-plugin-lto.html
- generate_lto_work
- WorkItem::CopyPostLtoArtifacts()
- Itemは並列処理でスレッド処理していく単位
- codegen_statement
# rustc_codegen_llvm
- https://rustc-dev-guide.rust-lang.org/backend/codegen.html
- builder.rs
- BuilderMethods
- from_const
- 実態はlayout
- OperandValue::Immediate()
- llvmのAPI
- OperandValue::Immediate()
- eval_mir_constant_to_operand
- 実態はlayout
|
|