Skip to content
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

Merged
merged 3 commits into from Jun 1, 2020
Merged

Fix TypeUse #23

merged 3 commits into from Jun 1, 2020

Conversation

kariya-mitsuru
Copy link
Contributor

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

End ".../wain/spec-test/wasm-testsuite/func.wast":
  total: 130, passed: 124, failed: 6, skipped: 0

End ".../wain/spec-test/wasm-testsuite/call_indirect.wast":
  total: 153, passed: 149, failed: 4, skipped: 0

Results of 76 files:
  total: 19757, passed: 19416, failed: 212, skipped: 129

after

End ".../wain/spec-test/wasm-testsuite/func.wast":
  total: 130, passed: 130, failed: 0, skipped: 0

End ".../wain/spec-test/wasm-testsuite/call_indirect.wast":
  total: 153, passed: 153, failed: 0, skipped: 0

Results of 76 files:
  total: 19757, passed: 19426, failed: 202, skipped: 129

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.
.iter()
.map(|wat::TypeDef { ty, .. }| ty.clone())
.collect(),
);
Copy link
Owner

@rhysd rhysd May 31, 2020

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
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

メソッド定義の前後は1行空白をあけておいていただけますでしょうか

idx: Index::Num(idx),
idx: match idx {
Some(idx) => RefOrInline::Reference(idx),
None => RefOrInline::Inline(parser.create_inline_typeuse(start, &params, &results)),
Copy link
Owner

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 のほうが良さそうに感じました

Copy link
Contributor Author

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 と言う用語は出てきません。

Copy link
Owner

@rhysd rhysd Jun 1, 2020

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 だけですね.

Copy link
Contributor Author

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)*" のパターンを区別する短くて良い単語が他に思い浮かばなかったので、型定義への参照を含むパターンを Referenceparamresult は外側の TypeUse 構造体に含まれているのでそれ自身で有無を区別する必要が無い)、型定義への参照を含まずインライン宣言のみのパターンを Inline 、と言う名称にしました。

とは言え、列挙型名の RefOrInline も含めてあまり良い名前とは思っていないので(あまり?)、何か良い命名があればさっくり直します。

Copy link
Owner

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),
}

.results
.iter()
.map(|p| p.ty.transform(ctx))
.collect::<Result<'_, _>>()?,
Copy link
Owner

@rhysd rhysd May 31, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

問題ないのですが,ここってどうして paramsresults を外に移したのでしょう?borrow checker がらみでしょうか?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

あ、すみません、ボロ―チェッカやデータの値確認とかで悪戦苦闘してた際に切り出したりしてたんですが、最終的に元の状態で上手くいくので戻します。

@@ -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)?)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここムーブして渡していただけますでしょうか?そうすれば resolve_type_idx は参照で受け取る必要がなく,したがって resolve_indexIndex を参照で受け取る必要がなくなりそうです

@@ -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()),
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
tentatives: std::mem::replace(&mut parsed.module.tentatives, Vec::new()),
tentatives: std::mem::take(&mut parsed.module.tentatives),

意味は同じですが,take でよりシンプルになりそうです

@@ -248,6 +248,7 @@ struct ParseContext<'s> {
table_indices: Indices<'s>,
mem_indices: Indices<'s>,
global_indices: Indices<'s>,
tentatives: Vec<TentativeTypeUse<'s>>,
Copy link
Owner

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)でまたがって使う値なので,なるべく説明的な変数名を付けておきたいです

Copy link
Contributor Author

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 が良ければそちらにします。

Copy link
Owner

@rhysd rhysd Jun 1, 2020

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 自体は完了しているという.うーむ

Copy link
Owner

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 のほうが簡潔で良い気もしてきました…(将来的にもっと良い名前を思い付いたらリファクタする感じで…)

Copy link
Owner

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 が良いように思います

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

メンバ名は implicit_type_uses、構造体名も ImplicitTypeUse で修正しました。

@rhysd
Copy link
Owner

rhysd commented May 31, 2020

ありがとうございます.

ちなみにこの fresh ID を後で解決しないといけないのって,type use に限らず table とか memory もそうですよね…

Comment on lines 219 to 231
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)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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() を使うとシーケンスの長さをチェックする必要がなくなるので,よりシンプルになりそうです.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ちなみに、is_empty() は省略できないので残しました。

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

あっ,すみません,そうですね.僕の suggestion のほうが間違いです

@kariya-mitsuru
Copy link
Contributor Author

ちなみにこの fresh ID を後で解決しないといけないのって,type use に限らず table とか memory もそうですよね…

上のコメントにもリプライしましたが、typeuse では fresh ID は出てきません。
逆に、fresh ID の解決は(まだちゃんと確認してませんが)後である必要が無いと思います。

typeuse は以下の点で特殊だと思います。

  • 型定義を自動挿入すべきかどうかはモジュールを最後まで見ないとわからない。
  • 型定義を自動挿入する必要がある場合は、モジュールの最後に挿入する必要がある。

まぁ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.
Copy link
Owner

@rhysd rhysd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯

@rhysd
Copy link
Owner

rhysd commented Jun 1, 2020

いつもありがとうございます!

@rhysd rhysd merged commit af84260 into rhysd:master Jun 1, 2020
@kariya-mitsuru kariya-mitsuru deleted the fix-typeuse branch June 1, 2020 17:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants