前言:閱讀Cobalt源碼的時候發現一個問題,H5 Video標籤對應的c++代碼是html_video_element.cc,繼承自html_media_element.cc,但是video標籤包含的屬性明明是playbackRate,而html_media_element.cc的成員對象卻是playback_rate,爲什麼屬性名不一樣呢?這樣一個問題促使了這篇分析的誕生。
兩個個概念
Web interfaces:Javascript暴露給web APP的接口,也就是ES定義的接口。
Web IDL (Interface Definition Language): 用來定義Web interfaces的語言,其通過一種規範實現了JS engine(V8)和Web core(Blink)之間的低耦合綁定.
舉例
接下來我們舉一個例子解釋Web IDL如何實現這種綁定
1、找到測試網站
https://ytlr-cert.appspot.com/demoplayer/2019/dash-player.html?manifest_url=assets/waymo_vp9_opus.mpd&playbackRate=1.0
。
2、debug網頁:
shaka.player.Player.prototype.setPlaybackRate = function(rate) {
// Cancel any rewind we might be in the middle of.
this.cancelRewindTimer_();
if (rate >= 0) {
// Slow-mo or fast-forward are handled natively by the UA.
this.video_.playbackRate = rate;
// Only rewind when not paused.
} else if (!this.video_.paused) {
// Rewind is not supported by any UA to date (2015), so we fake it.
// http://crbug.com/33099
this.video_.playbackRate = 0;
this.onRewindTimer_(this.video_.currentTime, Date.now(), rate);
}
this.playbackRate_ = rate;
};
找到改變播放速率時調用的接口
this.video_.playbackRate = rate;
也就是對video標籤的playbackRate屬性賦值
3、然後在html_media_element.cc的set_playback_rate()函數中打印調用棧
4、執行瀏覽器cobalt,訪問網站後點擊其他的播放速率,有以下調用棧打印
5、使用addr2line打印0x283c943
6、我們會發現一個源文件沒有的文件v8c_html_media_element.cc
7、找到v8c_html_media_element.h頭文件,會看到以下描述
也就是這個文件是以idl爲源,以interface.h.template爲模板生成的。
總結:
V8和WebCore之間的文件關係:
v8調用順序:
參考:
https://www.chromium.org/developers/web-idl-interfaces
https://www.chromium.org/blink/webidl