5. API

Этот раздел описывает API для Lua, то есть набор функций C, доступных ведущей программе, чтобы связаться с Lua. Все функции API, связанные типы и константы объявлены в файле заголовка lua.h.

Даже когда используем термин "функция", любое средство в API можно обеспечить как макрокоманду. Все такие макрокоманды используют каждый из параметров точно однажды и не генерируют скрытые побочные эффекты.

5.1 Состояния

Библиотека Lua полностью повторно используема: она не имеет никаких глобальных переменных. Все состояние интерпретатора Lua (глобальные переменные, стек, методы тэгов и т.д.) сохранено в динамически распределенной структуре типа lua_State. Это состояние должно быть передано как первый параметр каждой функции в библиотеке (за исключением lua_open).

Перед вызовом любой функции API, Вы должны создать состояние вызовом:

lua_State *lua_open (int stacksize);
Единственный параметр этой функции: размер стека для интерпретатора. Каждое обращение к функции нуждается в одной позиции стека для каждого параметра, локальной переменной и временного значения, плюс по одной позиция для бухгалтерии. Стек должен также иметь приблизительно 20 позиций дополнительного пространства доступными. Для очень маленьких реализаций, без применения рекурсивных функций, размер стека в 100 должен быть достаточным. Если параметр stacksize равен 0, то используется заданный по умолчанию размер в 1024.

Чтобы освободить состояние, созданное lua_open, вызовите:

void lua_close (lua_State *L);
Эта функция уничтожает все объекты в данной среде Lua (вызывая соответствующие методы тэгов для уборки мусора, если они есть) и освобождает всю динамическую память, используемую этим состоянием. Обычно Вы не должны вызвать эту функцию потому, что все ресурсы естественно освобождены, когда Ваша программа заканчивается. С другой стороны, долго работающие программы должны бы освобождать ресурсы как только они становятся ненужными, чтобы не становиться слишком большими.

За исключением lua_open все функции в Lua API нуждаются в состоянии как в первом параметре.

5.2 Стек и индексы

Lua использует стек (stack), чтобы передавать значения в и из C. Каждый элемент в этом стеке представляет значение Lua (nil, число, строка).

Для удобства большинство операций запроса в API не следует за строгой дисциплиной стека. Вместо этого они могут обратиться к любому элементу в стеке, используя индекс: положительный индекс представляет абсолютную позицию стека (начиная с 1, а не с 0, как в C). Отрицательный индекс представляет смещение от верхней части стека. Более определенно, если стек имеет n элементов, индекс 1 представляет первый элемент (то есть, первый элемент, помещенный в стек), а индекс n представляет последний элемент. Индекс -1 также представляет последний элемент (то есть, элемент наверху), и индекс -n представляет первый элемент. Мы говорим, что индекс имеет силу, если он находится между 1 и верхней частью стека (то есть, если 1 <= abs(index) <= top).

В любое время Вы можете получать индекс верхнего элемента вызовом:

int lua_gettop (lua_State *L);
Потому, что начало индексов в 1, результат lua_gettop равно числу элементов в стеке (0 стало быть означает пустой стек).

Когда Вы взаимодействуете с Lua API, Вы ответственны за контроль переполнения стека. Функция

int lua_stackspace (lua_State *L);
возвращает число доступных позиций стека. Всякий раз, когда Lua вызывается C, это гарантирует, что по крайней мере LUA_MINSTACK позиций все еще доступны. LUA_MINSTACK определен в файле заголовка lua.h и по крайней мере 16, так что Вы должны позаботиться о месте в стеке только, когда Ваш код имеет циклы, помещающие элементы в стек.

Большинство функций запроса принимает как индексы любое значение внутри доступного места в стеке. Такие индексы названы приемлемыми индексами . Более формально можно определять приемлемый индекс таким образом:

(index < 0 && abs(index) <= top) ||
(index > 0 && index <= top + stackspace)

Обратите внимание, что 0 не является приемлемым индексом.

5.3 Манипуляции со стеком

API предлагает следующие функции для базисного манипулирования стеком:
void lua_settop(lua_State *L, int index);
void lua_pushvalue(lua_State *L, int index);
void lua_remove(lua_State *L, int index);
void lua_insert(lua_State *L, int index);

lua_settop принимает любые приемлемые индексы или 0 и устанавливает верхнюю часть стека к этому индексу. Если новая верхняя часть больше, чем старая, то новые элементы заполнены nil. Если index равен 0, то все элементы из стека будут удалены. Полезная макрокоманда, определенная в API:

#define lua_pop(L,n) lua_settop(L, -(n)-1)
выталкивает n элементов из стека.

lua_pushvalue помещает в стек копию элемента в данном индексе. lua_remove удаляет элемент в данной позиции, сдвигая элементы вверх от этой позиции, чтобы заполнить промежуток. lua_insert перемещает верхний элемент в данную позицию, сдвигая элементы вверх от позиции на открытое место. Эти функции принимают только имеющие силу индексы. Как пример, если стек хранит значения (снизу вверх) 10 20 30 40 50:

lua_pushvalue(L, 3)  --> 10 20 30 40 50 30
lua_pushvalue(L, -1) --> 10 20 30 40 50 30 30
lua_remove(L, -3)    --> 10 20 30 40 30 30
lua_remove(L,  6)    --> 10 20 30 40 30
lua_insert(L,  1)    --> 30 10 20 30 40
lua_insert(L, -1)    --> 30 10 20 30 40  (никакого эффекта нет)
lua_settop(L, -3)    --> 30 10 20
lua_settop(L, 6)     --> 30 10 20 nil nil nil

5.4 Запросы к стеку

Чтобы проверять тип элемента стека, следующие функции доступны:

int lua_type(lua_State *L, int index);
int lua_tag(lua_State *L, int index);
int lua_isnil(lua_State *L, int index);
int lua_isnumber(lua_State *L, int index);
int lua_isstring(lua_State *L, int index);
int lua_istable(lua_State *L, int index);
int lua_isfunction(lua_State *L, int index);
int lua_iscfunction(lua_State *L, int index);
int lua_isuserdata(lua_State *L, int index);
Эти функции могут быть вызваны с любым приемлемым индексом.

lua_type возвращает одну из следующих констант, согласно типу данного объекта: LUA_TNIL, LUA_TNUMBER, LUA_TSTRING, LUA_TTABLE, LUA_TFUNCTION, LUA_TUSERDATA. Если индекс не имеет силу (то есть, если та позиция стека пуста), то lua_type возвращает LUA_TNONE. Эти константы могут быть преобразованы в строки с помощью вызова:

const char *lua_typename(lua_State *L, int t);
здесь t представляет собой тип, возвращенный lua_type. Строки, возвращаемые lua_typename: "nil", "number", "string", "table", "function", "userdata" и "no value",

lua_tag возвращает тэг значения или LUA_NOTAG для не имеющего силу индекса.

Функция lua_is* возвращает 1, если объект совместим с данным типом, и 0 в противном случае. Всегда возвращается 0 для не имеющего силу индекса. lua_isnumber принимает числа и числовые строки. lua_isstring берет строки и числа и lua_isfunction воспринимает функции Lua и C. Чтобы различать между функциями Lua и функциями C, Вы должны использовать lua_iscfunction. Чтобы различать между числами и числовыми строками, Вы можете использовать lua_type.

API также имеет функции, чтобы сравнить два значения в стеке:

int lua_equal(lua_State *L, int index1, int index2);
int lua_lessthan(lua_State *L, int index1, int index2);
Эти функции эквивалентны их дубликатам в Lua. Определенно, lua_lessthan эквивалентна lt_event. Обе функции возвращают 0, если любой из индексов не имеет силу.

Чтобы транслировать значение в стеке к специфическому типу C, Вы можете использовать следующие функции преобразования:

double  lua_tonumber(lua_State *L, int index);
const char *lua_tostring(lua_State *L, int index);
size_t lua_strlen(lua_State *L, int index);
lua_CFunction lua_tocfunction(lua_State *L, int index);
void *lua_touserdata(lua_State *L, int index);
Эти функции могут быть вызваны с любым приемлемым индексом. Когда вызваны с не имеющим силу индексом, они действуют так, как будто переданное им значение имело неправильный тип.

lua_tonumber преобразовывает значение в данном индексе к числу с плавающей запятой. Это значение должно быть числом или строкой, обратимой в число (подробности в разделе 4.2). Иначе lua_tonumber возвращает 0.

lua_tostring преобразовывает значение Lua в строку (const char*). Это значение должно быть числом или строкой, иначе будет возвращен NULL. Эта функция возвращает указатель на строку внутри Lua-среды. Эти строки всегда имеют ноль ('\0') после их последнего символа (как в C), но могут содержать другие ноли в их теле. Если Вы не знаете, может ли строка содержать ноли, Вы должны использовать lua_strlen, чтобы получить фактическую длину. Потому, что Lua имеет мусороуборщик, не имеется никакой гарантии, что указатель, возвращенный lua_tostring, будет иметь силу после того, как соответствующее значение удалено из стека.

lua_tocfunction преобразовывает значение в стеке к функции C. Это значение должно быть функцией C, иначе lua_tocfunction возвращает NULL. Тип lua_CFunction рассмотрен более подробно в отдельном разделе 5.13.

lua_touserdata преобразовывает значение в void*. Это значение должно иметь тип userdata, иначе lua_touserdata вернет NULL.

5.5 Помещение значений в стек

API имеет следующие функции, чтобы поместить значения C в стек:

void lua_pushnumber(lua_State *L, double n);
void lua_pushlstring(lua_State *L, const char *s, size_t len);
void lua_pushstring(lua_State *L, const char *s);
void lua_pushusertag(lua_State *L, void *u, int tag);
void lua_pushnil(lua_State *L);
void lua_pushcfunction(lua_State *L, lua_CFunction f);

Эти функции получают значение C, преобразовывают его в соответствующее значение Lua, и помещают результат в стек. В частности, lua_pushlstring и lua_pushstring делают внутреннюю копию данной строки. lua_pushstring может использоваться только, чтобы поместить соответствующие C-строки (то есть, такие строки, которые заканчиваются нолем и не содержат вложенные ноли), иначе Вы должны использовать более общую функцию lua_pushlstring, которая принимает явный размер данных.

5.6 Сборка мусора

Lua использует два числа, чтобы управлять совокупностью мусора. Одно число рассчитывает, сколько байтов динамической памяти Lua использует, а другое задает порог. Это внутренний счетчик байтов, сохраняемый Lua не полностью аккуратно: это может отклоняться на 10% от реального положения дел в памяти. Когда число байтов пересекает порог, Lua выполняет цикл зачистки мусора, который исправляет память и стирает оттуда все отработавшие свое, но забытые там объекты (то есть объекты, больше доступные из Lua). Счетчик байтов будет исправлен, а затем порог сброшен к двойному значению счетчика байтов.

Вы можете обращаться к текущим значениям этих двух чисел через следующие функции:

int lua_getgccount (lua_State *L);
int lua_getgcthreshold (lua_State *L);
Оба возвращают их соответствующие значения в килобайтах. Вы можете изменять пороговое значение с помощью:
void  lua_setgcthreshold (lua_State *L, int newthreshold);
Снова значение newthreshold задано в килобайтах. Когда Вы вызываете эту функцию, Lua устанавливает новый порог и проверяет счетчик байтов. Если новый порог меньше, чем счетчик байтов, то Lua немедленно выполняет cборку мусора. После нее новый порог будет установлен согласно предыдущему правилу.

Если Вы хотите изменять поведение коллектора мусора адаптивно, Вы можете использовать метод тэга мусоросборщика для nil, чтобы установить ваш собственный порог (метод тэга будет вызван после того, как Lua сбрасывает порог).

5.7 Userdata и тэги

Поскольку userdata представляют собой объекты, функция lua_pushusertag может создавать новые userdata. Если Lua имеет userdata с данным значением (void*) и тэг, то этот объект размещен. Иначе создается новый userdata с данным значением и тэгом. Если эта функция вызвана с тэгом, равным LUA_ANYTAG , то Lua пробует находить любой объект userdata с данным значением, независимо от его тэга. Если не имеется никакого userdata с этим значением, то новый объект будет создан с тэгом, равным 0.

Userdata может иметь различные тэги, чья семантика известна только ведущей программе. Тэги создаются функцией:

int lua_newtag (lua_State *L);
Функция lua_settag меняет тэг объекта в верхней части стека (без того, чтобы получить его):
void lua_settag (lua_State *L, int tag);

Объект должен быть userdata или таблицей, данный тэг должен быть значением, созданным с помощью функции lua_newtag.

5.8 Выполнение Lua-кода

Ведущая программа может выполнять Lua-chunk, записанные в файле или в строке, используя следующие функции:
int lua_dofile(lua_State *L, const char *filename);
int lua_dostring(lua_State *L, const char *string);
int lua_dobuffer(lua_State *L, const char *buff, size_t size,
                 const char *name);
Эти функции возвращают 0 в случае успеха, или один из следующих кодов ошибки, если они терпят неудачу: Эти константы определены в lua.h.

Когда функция lua_dofile вызвана с параметром NULL, она выполняет поток stdin. lua_dofile и lua_dobuffer способны выполнить прекомпилируемые объекты кода. Они автоматически обнаруживают, является ли кусок кода текстовым или двоичным, и загружают его соответственно. lua_dostring выполняет только исходный текст, заданный в простой текстовой форме.

Третий параметр для lua_dobuffer задает имя chunk, который используется сообщениях об ошибках и отладочных сообщениях. Если имя name равно NULL, то Lua дает заданное по умолчанию имя этому chunk.

Эти функции помещают в стек любые значения, в конечном счете возвращенные кодом. Код может возвращать любое число значений; Lua соблюдает осторожность, в том плане, что эти значения вписываются в размер стека, но после обращения ответственность переходит к Вам. Если Вы должны поместить другие элементы после вызова любой из этих функций, и Вы хотите работать спокойно, Вы должны или проверить место в стеке с помощью lua_stackspace, или удалять возвращенные элементы из стека (если Вы не нуждаетесь в них). Например, следующий код загружает код в файле и отбрасывает все результаты, возвращенные этим кодом:

{
  int oldtop = lua_gettop(L);
  lua_dofile(L, filename);
  lua_settop(L, oldtop);
}

5.9 Управление глобальными переменными в Lua

Чтобы прочитать значение глобальной переменной Lua, надо:

void lua_getglobal (lua_State *L, const char *varname);
Это помещает в стек значение данной переменной. Как в Lua эта функция может вызывать метод тэга для события getglobal. Чтобы читать реальное значение глобальной переменной без того, чтобы вызывать любой метод тэга, используют lua_rawget над таблицей глобальных переменных.

Чтобы записать значение в глобальнукю переменную:

void lua_setglobal (lua_State *L, const char *varname);
Это извлекает из стека значение, которое будет сохранено в данной переменной. Как в Lua эта функция может вызывать метод тэга для события setglobal. Чтобы устанавливать реальное значение глобальной переменной без того, чтобы вызывать любой метод тэга, используют lua_rawset над таблицей глобальных переменных (подробности приведены ниже).

Все глобальные переменные сохраняются в обычной Lua-таблице. Вы можете получать ее вызовом:

void lua_getglobals (lua_State *L);
Это помещает текущую (актуальную) таблицу глобальных переменных в стек. Чтобы устанавливать другую таблицу глобальных переменных, используйте вызов:
void lua_setglobals (lua_State *L);

Таблица, которую нужно использовать, извлекается из стека.

5.10 Управление таблицами в Lua

Lua-таблицы могут также управляться через API.

Чтобы читать значение в таблице, таблица должна находиться где-нибудь в стеке. Теперь вызовите

void lua_gettable (lua_State *L, int index);
    
где index относится к таблице. lua_gettable извлекает ключ из стека и возвращает (через стек) содержание таблицы для заданного ключа. Как в Lua эта операция может вызывать метод тэга для события gettable. Получать реальное значение любого ключа таблицы, без того, чтобы вызывать любой метод тэга, можно, используя
void lua_rawget (lua_State *L, int index);

Чтобы сохранять значение в таблицу, которая находится где-нибудь в стеке, Вы помещаете ключ и значение в стек (именно в этом порядке!), а затем вызываете такое обращение:

void lua_settable (lua_State *L, int index);
здесь index относится к таблице. lua_settable извлекает из стека ключ и значение. Как и все в Lua, эта операция может вызывать метод тэга для события settable. Чтобы устанавливать реальное значение любого индекса таблицы без того, чтобы вызывать любой метод тэга, используют raw-версию:
void lua_rawset (lua_State *L, int index);

В заключение, еще одна функция

void lua_newtable (lua_State *L);

создает новую, пустую, таблицу и помещает ее в стек.

5.11 Использование таблиц как массивов

API имеет функции, которые помогают использовать таблицы Lua как массивы, то есть таблицы, индексированные только числами:
void lua_rawgeti(lua_State *L, int index, int n);
void lua_rawseti(lua_State *L, int index, int n);
int lua_getn(lua_State *L, int index);

lua_rawgeti получает значение энного элемента таблицы в позиции index стека.

lua_rawseti устанавливает значение энного элемента таблицы в позиции index стека к значению наверху стека.

lua_getn возвращает число элементов в таблице в позиции index. Это число представляет собой значение поля n таблицы, если это имеет числовое значение, или самый большой числовой индекс со значением non-nil в таблице.

5.12 Вызов функций Lua

Функции, определенные в Lua (и функции C, зарегистрированные в Lua), могут быть вызваны из ведущей программы. Это выполнено, используя следующий протокол: сначала, функция, которая будет вызвана, помещена в стек, затем, параметры функции помещены в прямом порядке, то есть первый параметр помещен в стек первым. В заключение, функция вызвана:

int lua_call (lua_State *L, int nargs, int nresults);
    
Эта функция возвращает те же самые коды ошибки, что и lua_dostring и другие (подробности в разделе 5.8). Если Вы хотите исследовать ошибку, вместо того, чтобы возвратить код ошибки, используйте:
void lua_rawcall(lua_State *L, int nargs, int nresults);

В обеих функциях nargs задает число параметров, которые Вы поместили в стек. Все параметры и функциональное значение берутся из стека, а функциональные результаты помещены туда. Число результатов будет откорректировано до nresults, если nresults не LUA_MULTRET. В этом случае все результаты функции будут помещены в стек. Функциональные результаты помещены в прямом порядке (первый результат и помещен первым), чтобы после обращения последний результат оказался на самой вершине стека.

Следующий пример показывает, как ведущая программа может делать эквивалент коду на Lua:

a,b = f("how", t.x, 4)
Here it is in C:
/* глобальная `t' (потом пригодится) */
lua_getglobal(L, "t");
/* функция, которая будет вызвана */
lua_getglobal(L, "f");
/* 1-ый параметр */
lua_pushstring(L, "how");
/* помещает в стек строку `x' */
lua_pushstring(L, "x");
/* помещает в стек результат t.x (2-ой аргумент) */
lua_gettable(L, -4);
/* 3-ий параметр */
lua_pushnumber(L, 4);
/* вызывает функцию с 3 параметрами и 2 результатами */
lua_call(L, 3, 2);
/* устанавливает глобальную переменную `b' */
lua_setglobal(L, "b");
/* устанавливает глобальную переменную `a' */
lua_setglobal(L, "a");
/* удаляет из стека `t' */
lua_pop(L, 1);
Обратите внимание, что код выше сбалансированный: в конце стек обратен к первоначальной конфигурации. Это считается хорошей практикой.

Некоторые специальные функции Lua имеют собственные интерфейсы C. Ведущая программа может генерировать ошибку Lua, вызывая функцию:

void lua_error (lua_State *L, const char *message);
Эта функция никогда не возвращает ничего. Если lua_error вызвана из функции C, которая была вызвана из Lua, то соответствующий блок кода Lua завершается так, как будто ошибка произошла внутри кода Lua. Иначе вся ведущая программа завершается обращением exit(EXIT_FAILURE). Перед завершением выполнения, сообщение message будет передано функции драйвера ошибки _ERRORMESSAGE. Если message равно NULL, то _ERRORMESSAGE не вызывается.

Методы тэгов могут быть изменены с

void lua_settagmethod (lua_State *L, int tag, const char *event);
Второй параметр задает тэг, а третий представляет собой имя события. Новый метод берется из стека. Чтобы получить текущее (актуальное) значение метода тэга используйте функцию
void lua_gettagmethod(lua_State *L, int tag, const char *event);

Также возможно копировать все методы из одного тэга в другой:

int lua_copytagmethods (lua_State *L, int tagto, int tagfrom);
Эта функция вернет tagto.

Вы можете пересекать таблицу с функцией:

int lua_next (lua_State *L, int index);
здесь index относится к таблице, которая будет пересечена. Функция берет ключ из стека и помещает туда пару "значение-ключ" из таблицы (следующую после данного ключа). Если не имеется больше элементов, то функция возвращает 0 (и не помещает в стек ничего). Типичный пример использования выглядит следующим образом:
lua_pushnil(L);  /* first key */
while (lua_next(L, t) != 0) {
  /* `key' is at index -2 and `value' at index -1 */
  printf("%s - %s\n", lua_typename(L, lua_type(L, -2)),
         lua_typename(L, lua_type(L, -1)));
  lua_pop(L, 1);  /* removes `value'; keeps `index' for next iteration */
}

Функция

void lua_concat (lua_State *L, int n);

конкатенирует n значений сверху стека, извлекает их и оставляет результат наверху. Здесь n должно быть по крайней мере равно 2. Конкатенация выполнена по правилам обычной семантики Lua

5.13 Определение функций C

Чтобы зарегистрировать функцию C в Lua, имеется следующая макрокоманда:
#define lua_register(L, n, f) (lua_pushcfunction(L,f),lua_setglobal(L,n))
/* const char *n;   */
/* lua_CFunction f; */
Которая получает имя, которое функция будет иметь в Lua, и указатель на функцию. Этот указатель должен иметь тип lua_CFunction, который определен так;
typedef int (*lua_CFunction) (lua_State *L);
То есть, это указатель на функцию с целочисленным результатом и одиночным параметром, Lua-средой.

Чтобы связываться правильно с Lua, функция C должна следовать следующему протоколу, который определяет путь, которым параметры и результаты переданы: функция C получает параметры от Lua в стеке, в прямом порядке (первый параметр помещен первым). Чтобы возвращать значения Lua, функция C только помещает их в стек в прямом порядке и возвращает число результатов. Подобно функции Lua, функция C, вызванная Lua, может возвращать много результатов.

Как пример, следующая функция получает переменное число числовых параметров, а возвращает их среднее и сумму:

static int foo (lua_State *L) {
  int n = lua_gettop(L);    /* number of arguments */
  double sum = 0;
  int i;

  for (i = 1; i <= n; i++) {
    if (!lua_isnumber(L, i))
       lua_error(L, "incorrect argument to function `average'");
    sum += lua_tonumber(L, i);
  }
  lua_pushnumber(L, sum/n);   /* первый результат */
  lua_pushnumber(L, sum);     /* второй результат */
  return 2;                   /* сколько всего результатов */
}
Эта функция может быть зарегистрирована в Lua как average таким вызовом:
lua_register(L, "average", foo);

Когда функция C создана, возможно сопоставить с ней некоторые upvalues, таким образом создавая замкнутое выражение C; эти значения будут переданы функции всякий раз, когда она вызвана, как обычные параметры. Чтобы сопоставить upvalues с функцией C, сначала эти значения должны быть помещены в стек. Затем функция

void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
используется, чтобы поместить функцию C в стек с параметром n означающим, сколько upvalues должно быть связан с функцией (эти upvalues берутся из стека). Фактически, макрокоманда lua_pushcfunction определена как lua_pushcclosure с n установленным в 0. Затем, всякий раз, когда функция C вызвана, эти upvalues вставлены как последние параметры функции, после фактических параметров, переданных в обращении. Это избавляет от необходимости выяснять, сколько параметров было передано фактически. Так i-th upvalue находится в стеке в индексе i-(n+1), где n задает номер upvalues.

Для большего количества примеров функций C и замкнутых выражений изучите файлы lbaselib.c, liolib.c, lmathlib.c и lstrlib.c в дистрибутиве Lua.

5.14 Ссылки к Lua-объектам

Если C-код должен хранить значение Lua вне продолжительности жизни функции C, то надо создать ссылку к значению. Функции, чтобы управлять ссылками, следующие:

int lua_ref(lua_State *L, int lock);
int lua_getref(lua_State *L, int ref);
void lua_unref(lua_State *L, int ref);
    

lua_ref выталкивает значение из стека, создает ссылку к нему и возвращает эту ссылку. Для значения nil ссылка всегда LUA_REFNIL. lua.h также определяет константу LUA_NOREF, которая отличается от любой имеющей силу ссылки. Если lock не равно 0, то объект блокирован: это означает, что объект не будет обработан мусоросборщиком. Разблокированные ссылки могут быть удалены в порядке уборки мусора на общих основаниях.

Всякий раз, когда вызванный объект необходим в C, обращение к lua_getref помещает тот объект в стек; если объект был убран, lua_getref вернет 0 (и не поместит ничего в стек).

Когда ссылка больше не нужна, ее надо освободить вызовом lua_unref.

5.15 Системный реестр

При своем запуске Lua регистрируют таблицу в позиции LUA_REFREGISTRY. К этому можно обращаться через макрокоманду:

#define lua_getregistry(L) lua_getref(L, LUA_REFREGISTRY)
    

Эта таблица может использоваться C-библиотеками как общий механизм системного реестра. Любая C-библиотека может сохранять данные в этой таблице, пока она выбирает ключ регистрации, отличный от других библиотек.