丨webassembly模塊的基本組成結(jié)構(gòu)到底有多簡單_第1頁
丨webassembly模塊的基本組成結(jié)構(gòu)到底有多簡單_第2頁
丨webassembly模塊的基本組成結(jié)構(gòu)到底有多簡單_第3頁
丨webassembly模塊的基本組成結(jié)構(gòu)到底有多簡單_第4頁
丨webassembly模塊的基本組成結(jié)構(gòu)到底有多簡單_第5頁
已閱讀5頁,還剩9頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

WasmSection。相信通過這一講,你能夠從另一個角度看到Wasm的不同面貌。Section從整體上來看,同ELF二進(jìn)制文件類似,Wasm模塊的二進(jìn)制數(shù)據(jù)也是以ecion的形式被安排和存放的。ecion翻譯成中文是“段”,但為了保證講解的嚴(yán)謹(jǐn)性,以及你在理解上的準(zhǔn)確性,后文我會直接使用它的英文名詞ecion。對于ecion,你可以直接把它想象成,一個個具有特定功能的一簇二進(jìn)制數(shù)據(jù)。通常,為了能夠更好地組織模塊內(nèi)的二進(jìn)制數(shù)據(jù),我們需要把具有相同功能,或者相關(guān)聯(lián)的那部分二進(jìn)制數(shù)據(jù)擺放到一起。而這些被擺放在一起,具有一定相關(guān)性的數(shù)據(jù),便組成了一個個ecion。SectionWasm的所有Section放在一起,便描述了整個模塊在二進(jìn)制層面的組成結(jié)構(gòu)。在一個標(biāo)準(zhǔn)的Wasm模塊內(nèi),以現(xiàn)階段的MVP標(biāo)準(zhǔn)為參考,可用的Section有如下幾種。要注意的是,在我們接下來將要講解的這些Section中,除了其中名為“CustomSecton”,也就是“自定義段”這個Section之外,其他的Section均需要按照每個SectionSectionIDID位方向依次進(jìn)行“擺放”。下面我來分別講解一下這些基本Section的作用和結(jié)構(gòu)。單體首先我們來講解的這部分Section被我劃分到了“單體Section”這一類別。也就是說,這一類Section一般可以獨自描述整個模塊的一部分特征(或者說是功能),同時也可以與其他Section一起配合起來使用。Section如何相互協(xié)作這部分內(nèi)容時提供一些幫助。這種劃分規(guī)則并非來源于標(biāo)準(zhǔn)或者官Type首先,第一個出現(xiàn)在模塊中的Section是“TypeSection”。顧名思義,這個Section用“函數(shù)”作為編程語言的基本代碼封裝單位,無論是在C/C++這類高級編程語言,還是匯編語言(一般被稱為rouie、例程,但也可以理解為函數(shù)或者方法)這類低級語言中,都有它的身影,而Wasm也不例外。在后面的課程中,會再次詳細(xì)講解,如何在瀏覽器中使用這些被定義在Wasm模塊內(nèi),同時又被標(biāo)記導(dǎo)出的函數(shù)方法,現(xiàn)在你只要先了解這些就可以了。與大部分編程語言類似,函數(shù)類型一般由函數(shù)的參數(shù)和返回值兩部分組成。而只要知道了這兩部分,我們就能夠確定在函數(shù)調(diào)用前后,棧上數(shù)據(jù)的變化情況。因此,對于“函數(shù)類型“,你也可以將其直接理解為我們更加常見的一個概念——“函數(shù)簽名”。接下來我們試著更進(jìn)一步,來看看這個Section在二進(jìn)制層面的具體組成方式。我們可以將TypeSection的組成內(nèi)容分為如下兩個部分,分別是:所有Section都具有的通Section從整體上來看,每一個Section都由有著相同結(jié)構(gòu)的“頭部”作為起始,在這部分結(jié)構(gòu)中描述了這個Section的一些屬性字段,比如不同類型Section所專有的ID、Section的有效載荷長度。除此之外還有一些可選字段,比如當(dāng)前Section的名稱與長度信息等等。關(guān)于對于表中第二列給出的一些類型,你目前只需要將它們理解為一種特定的編碼方式就可以了,關(guān)于這些編碼方式和數(shù)據(jù)類型的具體信息,我會在下一節(jié)課中進(jìn)行講解?!白侄巍边@一列中的“amelen”與“name”兩個字段主要用于Customecion,用來存放這個ecion名字的長度,以及名字所對應(yīng)的字符串?dāng)?shù)據(jù)。對于TypeSection來說,它的專有ID是1。緊接著排在“頭部”后面的便是這個Section(payload_data)Section載荷的結(jié)構(gòu)都不相同。比如,TypeSection的有效載荷部分組成如下表所示。可以看到,TypeSectioncountentries合而成的。其中要注意的是entries字段對應(yīng)的func_type類型,該類型是一個復(fù)合類關(guān)于表中各個字段的具體說明,你可以參考表格中最后一列的“描述”信息來進(jìn)行理解。因為其解讀方式與上述的Section頭部十分類似。更詳細(xì)的信息,你可以按照需求直接參考文檔來進(jìn)行查閱。StartStartSection的ID為8。通過這個Section,我們可以為模塊指定在其初始化過程完成所謂的“初始化完成后”是指:模塊實例內(nèi)部的線性內(nèi)存和Table,已經(jīng)通過相應(yīng)的DataSection和ElementSection填充好相應(yīng)的數(shù)據(jù),但導(dǎo)出函數(shù)還無法被宿主環(huán)境調(diào)用的這個時刻。關(guān)于DataSection和ElementSection,我們會在下文給你講解,這里你只需要對于StartSection來說,有一些限制是需要注意的,比如:一個Wasm模塊只能擁有一個StartSection,也就是說只能調(diào)用一個函數(shù)。并且調(diào)用的函數(shù)也不能擁有任何參數(shù),同GlobalGlobalSection的ID為6。同樣地,從名字我們也可以猜到,這個Section中主要存放了整個模塊中使用到的全局?jǐn)?shù)據(jù)(變量)信息。這些全局變量信息可以用來模塊的狀態(tài),你可以直接把它們類比為我們在C/C++代碼中使用的全局變量。Section(也就CustomCustomSection的ID為0。這個Section主要用來存放一些與模塊本身主體結(jié)構(gòu)無關(guān)的數(shù)據(jù),比如調(diào)試信息、source-map信息等等。VM(VirtualMachine,虛擬機(jī))在實例化并執(zhí)行一個Wasm二進(jìn)制模塊中的指令時,對于可以識別的CustomSection,將會以特定的方式為其提供相應(yīng)的功能。而VM對于無法識別的CustomSection則會選擇直接VMCustomSection“name行。在目前的MVP標(biāo)準(zhǔn)中,有且僅有一個標(biāo)準(zhǔn)中明確定義的CustomSection,也就是“NameSection”。這個Section對應(yīng)的頭部信息中,“name”字段的值即為字符串“name”。在這個Section中存放了有關(guān)模塊定義中“可打印名稱”的一些信息?;パa(bǔ)SectionSection”這一類別,也就是說,每一組的兩個Section共同協(xié)作,一同描述了整個Wasm模塊的某方面特征。ImportSection和ExportSection首先是ImportSection,它的ID為2。ImportSectionWasmSection允許被導(dǎo)入到Wasm模塊中的資源包括:函數(shù)(Function)、全局?jǐn)?shù)據(jù)(Global)、線性內(nèi)存對象(Memory)以及Table對象(Table)。那為什么要設(shè)計ImportSection呢?其實就是希望能夠在Wasm模塊之間,以及Wasm模塊與宿主環(huán)境之間共享代碼和數(shù)據(jù)。我將在實戰(zhàn)篇中給你詳細(xì)講解,如何在瀏覽器內(nèi)向一個正在實例化中的Wasm模塊,ImportSection為此,我們便可以利用名為“Eportecion”的Secion結(jié)構(gòu)。Exportecion的為7,通過它,我們可以將一些資源導(dǎo)出到虛擬機(jī)所在的宿主環(huán)境中。允許被導(dǎo)出的資源類型同Importecion的可導(dǎo)入資源一致。而導(dǎo)出的資源應(yīng)該如何被表達(dá)及處理,則需要由宿主環(huán)境運行時的具體實現(xiàn)來決定。FunctionSection和Code關(guān)于FunctionSection與CodeSection之間的關(guān)系,你可以先參考上圖,以便有一個直觀的印象。FunctionSection的ID為3,你一定認(rèn)為,在這個Section中存放的是函數(shù)體的代碼,但事實并非如此。FunctionSection中其實存放了這個模塊中所有函數(shù)對在Wasm標(biāo)準(zhǔn)中,所有模塊內(nèi)使用到的函數(shù)都會通過整型的inies來進(jìn)行索引并調(diào)用。你可以想象這樣一個數(shù)組,在這個數(shù)組中的每一個單元格內(nèi)都存放有一個函數(shù)指針,當(dāng)你需要調(diào)用某個函數(shù)時,通過“指定數(shù)組下標(biāo)”的方式來進(jìn)行索引就可以了。而FunctionSection便描述了在這個數(shù)組中,從索引0開始,一直到數(shù)組末尾所有單元格內(nèi)函數(shù),所分別對應(yīng)的函數(shù)類型信息。這些類型信息是由我們先前介紹的TypeSection來TypeSection存放了Wasm模塊使用到的所有函數(shù)類型(簽名);FunctionSection存放了模塊內(nèi)每個函數(shù)對應(yīng)的函數(shù)類型,即具體的函數(shù)與類型對應(yīng)關(guān)系;而在CodeSectionCoeecion的ID為10。Coeecion的組織結(jié)構(gòu)從宏觀上來看,你同樣可以將它理解成一個數(shù)組結(jié)構(gòu),這個數(shù)組中的每個單元格都存放著某個函數(shù)的具體定義,也就是函數(shù)體對應(yīng)的一簇Wasm指令集合。CodeSectionFunctionSection位置的單元格。也就是說舉個例子,CodeSection的0號單元格中存放著FunctionSection的0號單元格中所描述函數(shù)類型對應(yīng)的具體實現(xiàn)。當(dāng)然,上述我們提到的各種“數(shù)組”結(jié)構(gòu),其實并不一定真的是由編程語言中的數(shù)組來實現(xiàn)的。只是從各個Section概念上的協(xié)作和數(shù)據(jù)方式來看,我們可以通過數(shù)組來模擬這樣的交互流程。具體實現(xiàn)需要依以各個VM為準(zhǔn)。TableSection和Element同樣的,TableSectionElementSection到。TableSection的ID為4。在MVP標(biāo)準(zhǔn)中,Tableetion的作用并不大,你只需要知道我們可以在其對應(yīng)的Tale結(jié)構(gòu)中存放類型為“ayfunc”的函數(shù)指針,并且還可以通過指令“all_inirect”用這些函數(shù)指針?biāo)赶虻暮瘮?shù),這就可以了。Taleecion的結(jié)構(gòu)與Fncionecion類似,也都是由“一個個小格子”按順序排列而成的,你可以用數(shù)組的結(jié)構(gòu)來類比著進(jìn)行理解。VMTable模塊線性內(nèi)存的區(qū)域中,這個區(qū)域無法被模塊本身直接。因此Table中這些“小格子”內(nèi)具體存放的值,對于Wasmcall_indirectindicies,也就是“索引”的方式,來指定和這些“小格子”中的內(nèi)容。這在某種程度上,保證了Table中數(shù)據(jù)的安全性。在默認(rèn)情況下,TableSection在TableSection中,只存放了用于描述某個Table屬性的一些元信息。比如:Table中可以存放哪種類型的數(shù)據(jù)?Table的大小信息?等等。那為了給TableSection所描述的Table對象填充實際的數(shù)據(jù),我們還需要使用名為ElementSectionSectionElementSectionID9Section,我們便可以為Table內(nèi)部填充實際的數(shù)據(jù)。MemorySection和DataMemorySection的ID為5。同樣,從這個Section的名字中我們就基本能夠猜到它的用途。同TableSection的結(jié)構(gòu)類似,借助MemorySection,我們可以描述一個Wasm模Wasm模塊內(nèi)的線性內(nèi)存結(jié)構(gòu),主要用來以二進(jìn)制字節(jié)的形式,存放各類模塊可能使用到通過瀏覽器等宿主環(huán)境提供的比如WebAssembly.Memory對象,我們可以直接將一個Wasm模塊的線性內(nèi)存結(jié)構(gòu),以“對象”的形式從模塊實例中導(dǎo)出。而被導(dǎo)出的ImportSection,再次導(dǎo)入給其他的Wasm模塊來進(jìn)行使用。MemorySection果要為線性內(nèi)存段填充實際的二進(jìn)制數(shù)據(jù),我們還需要使用另外的DataSection。DataSection的ID為11。到這里呢,我們就已經(jīng)大致分析完在MVP標(biāo)準(zhǔn)下,Wasm模塊內(nèi)Section的二進(jìn)制組成結(jié)構(gòu)。但少俠且慢,Section信息固然十分重要,但另一個更重要的問題是:我們?nèi)绾巫R別一個二進(jìn)制文件是不是一個合法有效的Wasm模塊文件呢?其實同ELF二進(jìn)制文件一樣,Wasm也同樣使用“魔數(shù)”來標(biāo)記其二進(jìn)制文件類型。所謂魔數(shù),你可以簡單地將它理解為具有特定含義/功能的一串?dāng)?shù)字。Wasm前節(jié)分別為“(高地址)0x6d0x730x610x0(低地址)”,這節(jié)對應(yīng)的ASCII可見字符為“asm”(第一個為空字符,不可見)。接下來的節(jié),用來表示當(dāng)前Wasm二進(jìn)制文件所使用的Wasm標(biāo)準(zhǔn)版本號。就目前來說,所有Wasm模塊該節(jié)的值均為“(高地址)0x00x00x00x1(低地址)”,1WasmVM判斷,當(dāng)前正在解析的二進(jìn)制文件是否是一個合法的Wasm二進(jìn)制模塊文件。Wasm了方便你理解,我簡化了一下分析流程。使用以下C/C++代碼所對應(yīng)生成的Wasm二進(jìn)制字節(jié)碼來作為例子進(jìn)行講解:intadd(inta,intb)returna+3在這段代碼中,我們定義了一個簡單的函數(shù)“add”。這個函數(shù)接收兩個int類型的參數(shù),并返回這兩個參數(shù)的和。我們使用一個線上的名為WasmFiddle的Wasm編譯工具,將上述代碼編譯成對應(yīng)的Wasm二進(jìn)制文件,并將它到本地。然后,我們可以使用“hexdump”命令來查看這個二進(jìn)制文件的字節(jié)碼內(nèi)容。對于這個命令的實際運行結(jié)你可以看到,最開始紅色方框內(nèi)的前八個字節(jié)“0x00x610x730x6d0x10x00x00x0”便是我們之前介紹的,Wasm模塊文件開頭的“魔數(shù)”和版本號。這里需要注意地址增長接下來的“0x1”是Section頭部結(jié)構(gòu)中的“id”字段,這里的值為“0x1”,表明接下來的數(shù)據(jù)屬于模塊的TypeSection。緊接著綠色方框內(nèi)的五個十六進(jìn)制數(shù)字“0x870x800x800x800x0”是由varuint32編碼的“payload_len”字段信息,經(jīng)過,它的值為“0x7”,表明這個Section的有效載荷長度為7個字節(jié)(關(guān)于編的具體過根據(jù)這節(jié)課一開始我們對TypeSection結(jié)構(gòu)的介紹,你可以知道,TypeSection的有效載荷是由一個“count”字段和多個“entries”類型數(shù)據(jù)組成的。因此我們可以進(jìn)一步推斷出,接下來的字節(jié)“0x1”便代表著,當(dāng)前Section中接下來存在的“entries”類型實體的個數(shù)為1個。根據(jù)同樣的分析過程,你可以知道,緊接著紫色方框內(nèi)的六個十六進(jìn)制數(shù)字序列“0x600x20x7f0x7f0x10x7f”i32i32值的函數(shù)類型”。同樣的分析過程,也適用于接下來的其他類型Section,你可以試著結(jié)合文檔給出的各Section的詳細(xì)組成結(jié)構(gòu),來將剩下的字節(jié)分別對應(yīng)到模塊的不同Section結(jié)構(gòu)中。今天我們主要

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論