New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix TypeUse #23
Fix TypeUse #23
Conversation
Inline parameter and result declaration without typeidx should insert type definition at the last of module. Inline parameter and result declaration with typeidx should check consistency.
2a00a22
to
67ece75
Compare
wain-syntax-text/src/wat2wasm.rs
Outdated
.iter() | ||
.map(|wat::TypeDef { ty, .. }| ty.clone()) | ||
.collect(), | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ctx.types.reserve(self.types.len());
for type_def in self.types.iter() {
ctx.types.push(type_def.ty.clone());
}
にしてもらえると,.collect()
によるアロケーションが不要になりそうです
results: results.to_vec(), | ||
}); | ||
idx as u32 | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
メソッド定義の前後は1行空白をあけておいていただけますでしょうか
wain-syntax-text/src/parser.rs
Outdated
idx: Index::Num(idx), | ||
idx: match idx { | ||
Some(idx) => RefOrInline::Reference(idx), | ||
None => RefOrInline::Inline(parser.create_inline_typeuse(start, ¶ms, &results)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
これって inline というワードの使い方適切でしょうか?暗黙に自動で生成される ID は仕様では fresh id と呼ばれていたので,fresh のほうが良さそうに感じました
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inline は spec で使用されている言葉です。
A
typeuse
may also be replaced entirely by inline parameter and result declarations.
spec 上この構文要素(typeuse
)では fresh id と言う用語は出てきません。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A typeuse may also be replaced entirely by inline parameter and result declarations.
https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#abbreviations%E2%91%A6
この inline は parameter and result declarations にかかっているので,例えば (type 0) (param)
の代わりに param
が直接書かれているのを指して inline と書いてるのではないでしょうか?typeuse
の index を省略した時を指して inline と書いているようには読めませんでした.
spec 上この構文要素(typeuse) fresh id と言う用語は出てきません。
すみません,これは僕の勘違いでした.fresh identifier は function, memory, table, global だけですね.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
この inline は parameter and result declarations にかかっているので,例えば
(type 0) (param)
の代わりにparam
が直接書かれているのを指して inline と書いてるのではないでしょうか?typeuse
の index を省略した時を指して inline と書いているようには読めませんでした.
それはその通りです。
が、"(type n)
" と "(type n)
(param
)* (result
)*" のパターンと "(param
)* (result
)*" のパターンを区別する短くて良い単語が他に思い浮かばなかったので、型定義への参照を含むパターンを Reference
(param
と result
は外側の TypeUse
構造体に含まれているのでそれ自身で有無を区別する必要が無い)、型定義への参照を含まずインライン宣言のみのパターンを Inline
、と言う名称にしました。
とは言え、列挙型名の RefOrInline
も含めてあまり良い名前とは思っていないので(あまり?)、何か良い命名があればさっくり直します。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
下記に合わせて Implicit というのはどうでしょう?また enum の名前は僕も良いものが思い付かないのですが,明示するものと暗黙に挿入されるものの2種類があるという意味で TypeUseKind とかどうでしょう?
enum TypeUseKind<'s> {
Explicit(Index<'s>),
Implicit(u32),
}
wain-syntax-text/src/wat2wasm.rs
Outdated
.results | ||
.iter() | ||
.map(|p| p.ty.transform(ctx)) | ||
.collect::<Result<'_, _>>()?, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
問題ないのですが,ここってどうして params
と results
を外に移したのでしょう?borrow checker がらみでしょうか?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
あ、すみません、ボロ―チェッカやデータの値確認とかで悪戦苦闘してた際に切り出したりしてたんですが、最終的に元の状態で上手くいくので戻します。
wain-syntax-text/src/wat2wasm.rs
Outdated
@@ -470,7 +518,7 @@ impl<'s> Transform<'s> for wat::Instruction<'s> { | |||
wat::InsnKind::Return => wasm::InsnKind::Return, | |||
wat::InsnKind::Call(idx) => wasm::InsnKind::Call(ctx.resolve_func_idx(idx, start)?), | |||
wat::InsnKind::CallIndirect(ty) => { | |||
wasm::InsnKind::CallIndirect(ctx.resolve_type_idx(ty.idx, start)?) | |||
wasm::InsnKind::CallIndirect(ctx.resolve_type_idx(&ty, start)?) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ここムーブして渡していただけますでしょうか?そうすれば resolve_type_idx
は参照で受け取る必要がなく,したがって resolve_index
も Index
を参照で受け取る必要がなくなりそうです
wain-syntax-text/src/wat2wasm.rs
Outdated
@@ -265,6 +302,8 @@ pub fn wat2wasm<'s>( | |||
local_indices: Indices::new(), | |||
next_local_idx: 0, | |||
label_stack: LabelStack::new(source), | |||
tentatives: std::mem::replace(&mut parsed.module.tentatives, Vec::new()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tentatives: std::mem::replace(&mut parsed.module.tentatives, Vec::new()), | |
tentatives: std::mem::take(&mut parsed.module.tentatives), |
意味は同じですが,take
でよりシンプルになりそうです
wain-syntax-text/src/parser.rs
Outdated
@@ -248,6 +248,7 @@ struct ParseContext<'s> { | |||
table_indices: Indices<'s>, | |||
mem_indices: Indices<'s>, | |||
global_indices: Indices<'s>, | |||
tentatives: Vec<TentativeTypeUse<'s>>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tentative は temp と同じぐらい情報量が無いので,fresh_types または implicit_types とかでお願いできませんでしょうか?複数のソース(parser.rs と wat2wasm.rs)でまたがって使う値なので,なるべく説明的な変数名を付けておきたいです
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
用語 fresh は fresh id ではないのでミスリード、用語 implicit も、この時点では暗黙定義するとは限らない(単なる参照の場合がある)ので不適切と考えました。
ちなみに、tentative は C 言語では仮定義の意味で tentative definition と言うように使用します。今回のケースでは、C 言語では仮定義と同様、定義になる場合と単なる参照になる場合の両方があるためニュアンス的に合ってるなと思い、この用語を使用しました。
「何の?」に当たる部分が無いのはご指摘通りなので、tentative_types ではどうでしょうか?(「仮の」のニュアンスが欲しいな、と思いまして。ホントは tentative_type_definitions とかのほうがいいのかもしれませんが、流石に長すぎる気が…)
他に良い用語があればそれでも構いませんし、もちろんやはり fresh か implicit が良ければそちらにします。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
完全に好みの問題で申し訳ないですが,unresolved_type_uses が良いです!!
すみません,誤読してましたが,tentatives
は自動挿入される type use の添字 → type use の index のマッピングを表すものなんですね.wat のパースが終わった時点で resolve 自体は完了しているという.うーむ
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inserted_type_to_index
とかになるのかな… 一周回って kariya さん案の tentative_types
のほうが簡潔で良い気もしてきました…(将来的にもっと良い名前を思い付いたらリファクタする感じで…)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
暗黙に指定されているという意味で implicit_types または implicit_type_uses が良いように思います
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
メンバ名は implicit_type_uses
、構造体名も ImplicitTypeUse
で修正しました。
ありがとうございます. ちなみにこの fresh ID を後で解決しないといけないのって,type use に限らず table とか memory もそうですよね… |
wain-syntax-text/src/wat2wasm.rs
Outdated
if ty.params.is_empty() && ty.results.is_empty() | ||
|| ty.params.len() == params.len() | ||
&& ty.results.len() == results.len() | ||
&& ty | ||
.params | ||
.iter() | ||
.zip(params.iter()) | ||
.all(|(l, r)| l.ty == r.ty) | ||
&& ty | ||
.results | ||
.iter() | ||
.zip(results.iter()) | ||
.all(|(l, r)| l.ty == r.ty) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if ty.params.is_empty() && ty.results.is_empty() | |
|| ty.params.len() == params.len() | |
&& ty.results.len() == results.len() | |
&& ty | |
.params | |
.iter() | |
.zip(params.iter()) | |
.all(|(l, r)| l.ty == r.ty) | |
&& ty | |
.results | |
.iter() | |
.zip(results.iter()) | |
.all(|(l, r)| l.ty == r.ty) | |
if ty.params | |
.iter() | |
.map(|p| p.ty) | |
.eq(params.iter().map(|p| p.ty)) | |
&& ty | |
.results | |
.iter() | |
.map(|r| r.ty) | |
.eq(results.iter().map(|r| r.ty)) |
.eq()
を使うとシーケンスの長さをチェックする必要がなくなるので,よりシンプルになりそうです.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ちなみに、is_empty()
は省略できないので残しました。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
あっ,すみません,そうですね.僕の suggestion のほうが間違いです
上のコメントにもリプライしましたが、
まぁ2点目は1点目の裏返しですが… |
Use reserve & push instead of map & collect to avoid unnecessary allocation. Add blank line arround the create_inline_typeuse method definition. Revert unnecessary local variable introduction. Change the parameter type of the resplve_type_idx from reference to non reference. Change std::mem::replace to std::mem::take for simplicity.
Use more better names for struct & enum.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💯
いつもありがとうございます! |
Inline parameter and result declaration without typeidx should insert
type definition at the last of module.
Inline parameter and result declaration with typeidx should check
consistency.
Passed new 10 tests.
before
after