Symbol表的啟發

2021-09-21 01:46:38 字數 2314 閱讀 3967

本文是《google.loader **欣賞》系列的一部分。

這段**原本是非常好讀懂的,但是當所有的函式名和變數名都用小寫的a到z之間的乙個字母代替以後,就變得不好讀起來,尤其是這段令人抓狂的**,

function k(c,a,b,d,e,f)
不死一堆腦細胞是很難摸得到門路的。

其實,這說明,這個**一定是經過編譯的。說編譯可能有點不是很準確,說「轉化」或者更恰當些。為什麼要這麼做呢?

symbol表

在整個**的最後一句

g("google_exportsymbol",g);
洩露了些原因。

symbol是什麼?在windows的世界(或者幾乎所有的編譯語言,或曰高階語言的世界裡),都少不了symbol這個東西。在編譯的時候,所有的函式名,變數的名字,都會被乙個位址或者乙個標記代替,寫進二進位制檔案裡面,所以如果從乙個.exe檔案反編譯出來,還是可以看得出執行的語句邏輯的(用彙編的形式),卻永遠無法獲取原來的源**。而symbol檔案,就是連線編譯好的二進位制程式,和源**的橋梁,包含了關於函式,變數的名字以及源**的檔名以及行數的資訊。而symbol檔案編譯以後,一般不和執行檔案一起發布,需要另外去找。比方說當年除錯iis的時候,就把iis的symbol拿過來,再把源**拿過來,用windbg就可以開工了。。。這是以前的古老的windows時代乙個程式設計師要做的事情(對了,現在所有的windows公開的symbol可以在這裡獲得)。symbol簡直就是windows世界裡的解開二進位制檔案的一把神秘的鑰匙。

google loader的symbol庫

既然有編譯,就一定要有一張自己存著的對應**。我猜測這個**應該是這樣樣子的:

function "google_exportsymbol" => function "g", @d:\my\code\uds\uds.js line #122

function "setapikeylookupmap" => function "p", @d:\my\code\uds\uds.js line #102

function "load" => "o", @d:\my\code\uds\uds.js line #77

function "writeloadtag" => "m", @d:\my\code\uds\uds.js line #115

var "google_exportsymbol"::"funcnamestring" => "c", @d:\my\code\uds\uds.js line#122

var "google_exportsymbol"::"function" => "a", @d:\my\code\uds\uds.js line #122

需要說明的是,我沒有原來的**,也徹底不知道這個symbol表是不是存在,甚至在這裡開玩笑一樣的假設原來的**放在一台windows的機器上面(顯然這不是很可能),但我希望就是表達這麼乙個意思,就是說,如果有編譯,就應該附屬產生這樣的乙個symbol表,只不過沒有公布而已。如果沒有這個表,debug會是一件和我們直接看源**一樣痛苦的過程。

dll的exportsymbols

如果大家熟悉windows的dll檔案結構的話,就會發現exportsymbols和importsymbols是乙個常見的概念。就是說,雖說在dll內部所有的函式的名字已經被編譯的面目全非,就像這裡的函式g(),函式q()一樣,但是為了方便外界的呼叫,還是把乙個標準的介面給輸出(export)出去。打個比方,乙個windows xp上的c:\windows\system32\user32.dll就export了732個之多的函式(函式名是字串,比如activatekeyboardlayout,實際的函式確實乙個位址為:7e42d32ah的entrypoint。

微軟的世界和google的世界

乙個微軟的世界的基石應該是pe(portal exexcutable)的檔案格式(也就是.exe, .dll所使用的格式),這些格式讓dos作業系統可以"load"到記憶體裡面執行。

那麼在google的世界裡面先出現了乙個loader(就好比dos的loader),然後作為load的基礎函式出現了這麼乙個google_exportsymbols,這是巧合呢,還是意味著什麼呢?

且聽下回分解。

注:第二次(其實是不知道多少次)宣告,以上純屬個人的主觀臆斷,就好像聽到了「咕咚」的聲音就驚呼「咕咚來了」的猴子一樣。或許是真的「咕咚」來了,或許僅僅是乙個熟了的果子掉到湖裡而已。是哪一種?只有時間告訴我們。

ES6 symbol 以及symbol的簡單應用

1.es6 引入了一種新的原始資料型別symbol,表示獨一無二的值。2.symbol 值通過symbol函式生成。3.symbol 函式可以接受乙個字串作為引數,表示對 symbol 例項的描述,主要是為了在控制台顯示,或者轉為字串時,比較容易區分。4.es2019 提供了乙個例項屬性descri...

symbol 的前世今生

es5 的物件屬性名都是字串,這容易造成屬性名的衝突。比如,你使用了乙個他人提供的物件,但又想為這個物件新增新的方法 mixin 模式 新方法的名字就有可能與現有方法產生衝突。如果有一種機制,保證每個屬性的名字都是獨一無二的就好了,這樣就從根本上防止屬性名的衝突。這就是 es6 引入symbol的原...

內建的Symbol值

除了定義自己使用的symbol值以外,es6還提供了11個內建的symbol值,指向語言內部使用的方法。物件的symbol.hasinstance屬性,指向乙個內部方法。當其他物件使用instanceof運算子,判斷是否為該物件的例項時,會呼叫這個方法。比如,foo instanceof foo在語...