Исходный код относительно прост и понятен.
Что делает библиотека, это определяет, какие части составляют функции и / или потоки, и затем сохраняет каждую часть отдельно.
Если вы пропустите код и просто прочитаете комментарии, вот как выглядят две соответствующие функции:
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