source code是比較容易遵循和非常評論。
該庫確定哪些部分組成函數和/或線程,然後分別存儲每個部分。
如果跳過代碼,只是閱讀註釋,這裏的兩個相關的功能怎麼看:
static void persistfunction(PersistInfo *pi)
{
...
if(cl->c.isC) {
/* It's a C function. For now, we aren't going to allow
* persistence of C closures, even if the "C proto" is
* already in the permanents table. */
lua_pushstring(pi->L, "Attempt to persist a C function");
lua_error(pi->L);
} else { /* It's a Lua closure. */
/* Persist prototype */
...
/* Persist upvalue values (not the upvalue objects themselves) */
...
/* Persist function environment */
...
}
}
static void persistthread(PersistInfo *pi)
{
...
/* Persist the stack */
...
/* Now, persist the CallInfo stack. */
...
/* Serialize the state's other parameters, with the exception of upval stuff */
...
/* Finally, record upvalues which need to be reopened */
...
}
所以,你可以看到,函數可以被看作是一個原型的組合物,價值羣和環境(一張桌子)。一個線程是兩個「堆棧」(我認爲是調用堆棧和內存堆棧),狀態信息(不包括upvalues),它基本上是什麼變量在定義線程時具有哪些值,以及upvalues。
您可以在PiL 27.3.3
中查看更多關於upvalues的信息