4 – Интерфейс прикладного программирования (API)
Categories:
Оглавление
4 – Интерфейс прикладного программирования
В этом разделе описывается C API для Lua, то есть набор функций C, доступных программе-хосту для взаимодействия с Lua. Все функции API и связанные с ними типы и константы объявлены в заголовочном файле lua.h.
Даже когда мы используем термин “функция”, любое средство в API может быть предоставлено в виде макроса. За исключением случаев, где указано иное, все такие макросы используют каждый из своих аргументов ровно один раз (кроме первого аргумента, который всегда является состоянием Lua), и поэтому не генерируют никаких скрытых побочных эффектов.
Как и в большинстве библиотек C, функции Lua API не проверяют свои аргументы на допустимость или согласованность. Однако вы можете изменить это поведение, скомпилировав Lua с определенным макросом LUA_USE_APICHECK.
Библиотека Lua полностью реентерабельна: у нее нет глобальных переменных. Она хранит всю необходимую информацию в динамической структуре, называемой состоянием Lua (Lua state).
Каждое состояние Lua имеет один или несколько потоков (threads), которые соответствуют независимым, кооперативным линиям выполнения. Тип lua_State (несмотря на свое имя) ссылается на поток. (Косвенно, через поток, он также ссылается на состояние Lua, связанное с потоком.)
Указатель на поток должен передаваться в качестве первого аргумента каждой функции в библиотеке, кроме lua_newstate, которая создает состояние Lua с нуля и возвращает указатель на главный поток в новом состоянии.
4.1 – Стек
Lua использует виртуальный стек для передачи значений в C и из C. Каждый элемент в этом стеке представляет значение Lua (nil, число, строка и т. д.). Функции в API могут обращаться к этому стеку через параметр состояния Lua, который они получают.
Всякий раз, когда Lua вызывает C, вызываемая функция получает новый стек, который независим от предыдущих стеков и от стеков функций C, которые все еще активны. Этот стек изначально содержит любые аргументы для функции C, и именно в нем функция C может хранить временные значения Lua и должна помещать свои результаты для возврата вызывающей стороне (см. lua_CFunction).
Для удобства большинство операций запроса в API не следуют строгой стековой дисциплине. Вместо этого они могут ссылаться на любой элемент в стеке, используя индекс: Положительный индекс представляет абсолютную позицию в стеке, начиная с 1 как дна стека; отрицательный индекс представляет смещение относительно вершины стека. Более конкретно, если в стеке n элементов, то индекс 1 представляет первый элемент (то есть элемент, который был помещен в стек первым), а индекс n представляет последний элемент; индекс -1 также представляет последний элемент (то есть элемент на вершине), а индекс -n представляет первый элемент.
4.1.1 – Размер стека
При взаимодействии с Lua API вы несете ответственность за обеспечение согласованности. В частности, вы отвечаете за контроль переполнения стека. При вызове любой функции API вы должны убедиться, что в стеке достаточно места для размещения результатов.
Из вышеуказанного правила есть одно исключение: когда вы вызываете функцию Lua без фиксированного количества результатов (см. lua_call), Lua гарантирует, что в стеке достаточно места для всех результатов. Однако она не гарантирует никакого дополнительного места. Поэтому перед тем, как помещать что-либо в стек после такого вызова, следует использовать lua_checkstack.
Всякий раз, когда Lua вызывает C, он гарантирует, что в стеке есть место как минимум для LUA_MINSTACK дополнительных элементов; то есть вы можете безопасно поместить в него до LUA_MINSTACK значений. LUA_MINSTACK определено как 20, так что обычно вам не нужно беспокоиться о пространстве стека, если только ваш код не содержит циклов, помещающих элементы в стек. При необходимости вы можете использовать функцию lua_checkstack, чтобы убедиться, что в стеке достаточно места для размещения новых элементов.
4.1.2 – Допустимые и приемлемые индексы
Любая функция в API, которая получает индексы стека, работает только с допустимыми индексами (valid indices) или приемлемыми индексами (acceptable indices).
Допустимый индекс — это индекс, который ссылается на позицию, хранящую изменяемое значение Lua. Он включает индексы стека между 1 и вершиной стека (1 ≤ abs(index) ≤ top) плюс псевдоиндексы, которые представляют некоторые позиции, доступные коду C, но не находящиеся в стеке. Псевдоиндексы используются для доступа к реестру (см. §4.3) и к upvalue функции C (см. §4.2).
Функции, которым не нужна конкретная изменяемая позиция, а только значение (например, функции запроса), могут вызываться с приемлемыми индексами. Приемлемый индекс может быть любым допустимым индексом, но также может быть любым положительным индексом после вершины стека в пределах пространства, выделенного для стека, то есть индексами вплоть до размера стека. (Обратите внимание, что 0 никогда не является приемлемым индексом.) Индексы к upvalue (см. §4.2), превышающие реальное количество upvalue в текущей функции C, также являются приемлемыми (но недопустимыми). За исключением случаев, когда указано иное, функции в API работают с приемлемыми индексами.
Приемлемые индексы служат для избежания дополнительных проверок вершины стека при запросе стека. Например, функция C может запросить свой третий аргумент без необходимости проверять, существует ли третий аргумент, то есть без необходимости проверять, является ли 3 допустимым индексом.
Для функций, которые могут вызываться с приемлемыми индексами, любой недопустимый индекс обрабатывается так, как если бы он содержал значение виртуального типа LUA_TNONE, которое ведет себя как значение nil.
4.1.3 – Указатели на строки
Несколько функций в API возвращают указатели (const char*) на строки Lua в стеке. (См. lua_pushfstring, lua_pushlstring, lua_pushstring и lua_tolstring. См. также luaL_checklstring, luaL_checkstring и luaL_tolstring во вспомогательной библиотеке.)
В общем случае сборщик мусора Lua может освобождать или перемещать память и, таким образом, делать недействительными указатели на строки, обрабатываемые состоянием Lua. Чтобы обеспечить безопасное использование этих указателей, API гарантирует, что любой указатель на строку в индексе стека действителен, пока строковое значение по этому индексу не удалено из стека. (Однако оно может быть перемещено на другой индекс). Когда индекс является псевдоиндексом (ссылающимся на upvalue), указатель действителен, пока активен соответствующий вызов и соответствующее upvalue не изменено.
Некоторые функции в отладочном интерфейсе также возвращают указатели на строки, а именно lua_getlocal, lua_getupvalue, lua_setlocal и lua_setupvalue. Для этих функций гарантируется, что указатель действителен, пока активна функция-вызыватель и данное замыкание (если оно было дано) находится в стеке.
За исключением этих гарантий, сборщик мусора может свободно делать недействительным любой указатель на внутренние строки.
4.2 – Замыкания C
При создании функции C с ней можно связать некоторые значения, создавая таким образом замыкание C (C closure) (см. lua_pushcclosure); эти значения называются upvalue и доступны функции при каждом ее вызове.
Всякий раз, когда вызывается функция C, ее upvalue располагаются по определенным псевдоиндексам. Эти псевдоиндексы создаются макросом lua_upvalueindex. Первое upvalue, связанное с функцией, находится по индексу lua_upvalueindex(1), и так далее. Любой доступ к lua_upvalueindex(n), где n больше количества upvalue текущей функции (но не больше 256, что на единицу больше максимального количества upvalue в замыкании), дает приемлемый, но недопустимый индекс.
Замыкание C также может изменять значения своих соответствующих upvalue.
4.3 – Реестр
Lua предоставляет реестр (registry) — предопределенную таблицу, которая может использоваться любым кодом C для хранения любых значений Lua, которые ему необходимо сохранить. Таблица реестра всегда доступна по псевдоиндексу LUA_REGISTRYINDEX. Любая библиотека C может хранить данные в этой таблице, но она должна позаботиться о выборе ключей, отличных от тех, что используются другими библиотеками, чтобы избежать коллизий. Обычно в качестве ключа следует использовать строку, содержащую имя вашей библиотеки, или легкий userdata с адресом объекта C в вашем коде, или любой объект Lua, созданный вашим кодом. Как и в случае с именами переменных, строковые ключи, начинающиеся с подчеркивания, за которым следуют заглавные буквы, зарезервированы для Lua.
Целочисленные ключи в реестре используются механизмом ссылок (см. luaL_ref) и имеют некоторые предопределенные значения. Поэтому целочисленные ключи в реестре не должны использоваться для других целей.
При создании нового состояния Lua его реестр содержит некоторые предопределенные значения. Эти предопределенные значения индексируются целочисленными ключами, определенными как константы в lua.h. Определены следующие константы:
LUA_RIDX_MAINTHREAD: По этому индексу в реестре находится главный поток состояния. (Главный поток — это тот, который создается вместе с состоянием).LUA_RIDX_GLOBALS: По этому индексу в реестре находится глобальное окружение.
4.4 – Обработка ошибок в C
Внутренне Lua использует средство C longjmp для обработки ошибок. (Lua будет использовать исключения, если вы компилируете его как C++; подробности ищите в исходном коде по LUAI_THROW). Когда Lua сталкивается с какой-либо ошибкой, такой как ошибка выделения памяти или ошибка типа, он возбуждает ошибку (raises an error); то есть выполняет длинный переход (long jump). Защищенное окружение использует setjmp для установки точки восстановления; любая ошибка переходит к самой последней активной точке восстановления.
Внутри функции C вы можете явно возбудить ошибку, вызвав lua_error.
Большинство функций в API могут возбуждать ошибки, например, из-за ошибки выделения памяти. Документация для каждой функции указывает, может ли она возбуждать ошибки.
Если ошибка происходит вне любого защищенного окружения, Lua вызывает функцию паники (panic function) (см. lua_atpanic), а затем вызывает abort, завершая таким образом хостовое приложение. Ваша функция паники может избежать этого завершения, никогда не возвращаясь (например, выполняя длинный переход к вашей собственной точке восстановления вне Lua).
Функция паники, как следует из ее названия, является механизмом “последней надежды”. Программы должны избегать ее. Как общее правило, когда функция C вызывается из Lua с состоянием Lua, она может делать с этим состоянием все, что угодно, так как оно уже должно быть защищено. Однако когда код C работает с другими состояниями Lua (например, аргумент-состояние Lua для функции, состояние Lua, сохраненное в реестре, или результат lua_newthread), он должен использовать их только в вызовах API, которые не могут возбуждать ошибки.
Функция паники работает так, как если бы она была обработчиком сообщений (см. §2.3); в частности, объект ошибки находится на вершине стека. Однако нет никаких гарантий относительно пространства стека. Чтобы поместить что-либо в стек, функция паники должна сначала проверить доступное пространство (см. §4.1.1).
4.4.1 – Коды состояния
Некоторые функции, сообщающие об ошибках в API, используют следующие коды состояния для указания различных видов ошибок или других условий:
LUA_OK(0): нет ошибок.LUA_ERRRUN: ошибка времени выполнения.LUA_ERRMEM: ошибка выделения памяти. Для таких ошибок Lua не вызывает обработчик сообщений.LUA_ERRERR: переполнение стека при выполнении обработчика сообщений из-за другого переполнения стека. Чаще всего эта ошибка является результатом какой-либо другой ошибки во время выполнения обработчика сообщений. Ошибка в обработчике сообщений вызовет обработчик снова, что снова сгенерирует ошибку, и так далее, пока этот цикл не исчерпает стек и не вызовет эту ошибку.LUA_ERRSYNTAX: синтаксическая ошибка во время предкомпиляции или ошибка формата в двоичном чанке.LUA_YIELD: поток (сопрограмма) выполняет yield.LUA_ERRFILE: ошибка, связанная с файлом; например, невозможно открыть или прочитать файл.
Эти константы определены в заголовочном файле lua.h.
4.5 – Обработка yield в C
Внутренне Lua использует средство C longjmp для выполнения yield в сопрограмме. Следовательно, если функция C foo вызывает функцию API, и эта функция API выполняет yield (прямо или косвенно, вызывая другую функцию, которая выполняет yield), Lua больше не может вернуться в foo, потому что longjmp удаляет ее фрейм из стека C.
Чтобы избежать подобной проблемы, Lua возбуждает ошибку всякий раз, когда пытается выполнить yield через вызов API, за исключением трех функций: lua_yieldk, lua_callk и lua_pcallk. Все эти функции получают функцию продолжения (continuation function) (в качестве параметра с именем k) для продолжения выполнения после yield.
Нам необходимо установить некоторую терминологию для объяснения продолжений. У нас есть функция C, вызванная из Lua, которую мы будем называть исходной функцией (original function). Эта исходная функция затем вызывает одну из этих трех функций в C API, которую мы будем называть вызываемой функцией (callee function), которая затем выполняет yield текущего потока. Это может произойти, когда вызываемая функция — lua_yieldk, или когда вызываемая функция — lua_callk либо lua_pcallk, и функция, вызываемая ими, выполняет yield.
Предположим, что выполняющийся поток делает yield во время выполнения вызываемой функции. После возобновления потока он в конечном итоге завершит выполнение вызываемой функции. Однако вызываемая функция не может вернуться в исходную функцию, потому что ее фрейм в стеке C был уничтожен при yield. Вместо этого Lua вызывает функцию продолжения, которая была передана в качестве аргумента вызываемой функции. Как следует из названия, функция продолжения должна продолжить задачу исходной функции.
В качестве иллюстрации рассмотрим следующую функцию:
int original_function (lua_State *L) {
... /* код 1 */
status = lua_pcall(L, n, m, h); /* вызывает Lua */
... /* код 2 */
}
Теперь мы хотим позволить коду Lua, выполняемому lua_pcall, делать yield. Во-первых, мы можем переписать нашу функцию следующим образом:
int k (lua_State *L, int status, lua_KContext ctx) {
... /* код 2 */
}
int original_function (lua_State *L) {
... /* код 1 */
return k(L, lua_pcall(L, n, m, h), ctx);
}
В приведенном выше коде новая функция k является функцией продолжения (с типом lua_KFunction), которая должна выполнять всю ту работу, которую исходная функция выполняла после вызова lua_pcall. Теперь мы должны сообщить Lua, что он должен вызвать k, если код Lua, выполняемый lua_pcall, будет прерван каким-либо образом (ошибки или yield), поэтому мы переписываем код следующим образом, заменяя lua_pcall на lua_pcallk:
int original_function (lua_State *L) {
... /* код 1 */
return k(L, lua_pcallk(L, n, m, h, ctx2, k), ctx1);
}
Обратите внимание на внешний явный вызов продолжения: Lua вызовет продолжение только при необходимости, то есть в случае ошибок или возобновления после yield. Если вызываемая функция возвращается нормально, ни разу не выполнив yield, lua_pcallk (и lua_callk) также вернется нормально. (Конечно, вместо вызова продолжения в этом случае вы можете выполнить эквивалентную работу непосредственно внутри исходной функции).
Помимо состояния Lua, функция продолжения имеет два других параметра: окончательный статус вызова и значение контекста (ctx), которое было изначально передано в lua_pcallk. Lua не использует это значение контекста; он только передает это значение от исходной функции к функции продолжения. Для lua_pcallk статус — это то же значение, которое было бы возвращено lua_pcallk, за исключением того, что это LUA_YIELD при выполнении после yield (вместо LUA_OK). Для lua_yieldk и lua_callk статус всегда LUA_YIELD, когда Lua вызывает продолжение. (Для этих двух функций Lua не будет вызывать продолжение в случае ошибок, потому что они не обрабатывают ошибки). Аналогично, при использовании lua_callk вы должны вызвать функцию продолжения с LUA_OK в качестве статуса. (Для lua_yieldk нет особого смысла вызывать функцию продолжения напрямую, потому что lua_yieldk обычно не возвращается).
Lua обрабатывает функцию продолжения так, как если бы она была исходной функцией. Функция продолжения получает тот же стек Lua от исходной функции, в том же состоянии, в котором он был бы, если бы вызываемая функция вернулась. (Например, после lua_callk функция и ее аргументы удаляются из стека и заменяются результатами вызова). Она также имеет те же upvalue. Все, что она возвращает, обрабатывается Lua так, как если бы это был возврат исходной функции.
4.6 – Функции и типы
Здесь мы перечисляем все функции и типы из C API в алфавитном порядке. Каждая функция имеет индикатор вида: [-o, +p, x]
Первое поле, o, — сколько элементов функция извлекает из стека. Второе поле, p, — сколько элементов функция помещает в стек. (Любая функция всегда помещает свои результаты после извлечения своих аргументов.) Поле вида x|y означает, что функция может поместить (или извлечь) x или y элементов, в зависимости от ситуации; знак вопроса '?' означает, что мы не можем узнать, сколько элементов функция извлекает/помещает, глядя только на ее аргументы. (Например, это может зависеть от того, что находится в стеке). Третье поле, x, сообщает, может ли функция возбуждать ошибки: '-' означает, что функция никогда не возбуждает ошибок; 'm' означает, что функция может возбуждать только ошибки нехватки памяти; 'v' означает, что функция может возбуждать ошибки, объясненные в тексте; 'e' означает, что функция может выполнять произвольный код Lua, либо напрямую, либо через метаметоды, и поэтому может возбуждать любые ошибки.
lua_absindex
[-0, +0, –]
int lua_absindex (lua_State *L, int idx);
Преобразует приемлемый индекс idx в эквивалентный абсолютный индекс (то есть такой, который не зависит от размера стека).
lua_Alloc
typedef void * (*lua_Alloc) (void *ud,
void *ptr,
size_t osize,
size_t nsize);
Тип функции распределения памяти, используемой состояниями Lua. Функция-аллокатор должна обеспечивать функциональность, аналогичную realloc, но не точно такую же. Ее аргументы: ud — непрозрачный указатель, переданный в lua_newstate; ptr — указатель на выделяемый/перераспределяемый/освобождаемый блок; osize — исходный размер блока или некоторый код о том, что выделяется; и nsize — новый размер блока.
Когда ptr не равен NULL, osize — это размер блока, на который указывает ptr, то есть размер, указанный при его выделении или перераспределении.
Когда ptr равен NULL, osize кодирует тип объекта, который Lua выделяет. osize равен LUA_TSTRING, LUA_TTABLE, LUA_TFUNCTION, LUA_TUSERDATA или LUA_TTHREAD, когда (и только когда) Lua создает новый объект этого типа. Когда osize имеет какое-либо другое значение, Lua выделяет память для чего-то другого.
Lua предполагает следующее поведение от функции-аллокатора:
Когда nsize равно нулю, аллокатор должен вести себя как free и затем возвращать NULL.
Когда nsize не равно нулю, аллокатор должен вести себя как realloc. В частности, аллокатор возвращает NULL тогда и только тогда, когда он не может выполнить запрос.
Вот простая реализация функции-аллокатора, соответствующая функции luaL_alloc из вспомогательной библиотеки.
void *luaL_alloc (void *ud, void *ptr, size_t osize,
size_t nsize) {
(void)ud; (void)osize; /* не используется */
if (nsize == 0) {
free(ptr);
return NULL;
}
else
return realloc(ptr, nsize);
}
Обратите внимание, что стандарт ISO C гарантирует, что free(NULL) не имеет эффекта, и что realloc(NULL,size) эквивалентно malloc(size).
lua_arith
[-(2|1), +1, e]
void lua_arith (lua_State *L, int op);
Выполняет арифметическую или побитовую операцию над двумя значениями (или одним, в случае отрицаний) на вершине стека, при этом значение на вершине является вторым операндом, извлекает эти значения и помещает результат операции в стек. Функция следует семантике соответствующего оператора Lua (то есть может вызывать метаметоды).
Значение op должно быть одной из следующих констант:
| Константа | Операция |
|---|---|
LUA_OPADD | сложение (+) |
LUA_OPSUB | вычитание (-) |
LUA_OPMUL | умножение (*) |
LUA_OPDIV | деление с плавающей запятой (/) |
LUA_OPIDIV | деление нацело вниз (//) |
LUA_OPMOD | остаток от деления (%) |
LUA_OPPOW | возведение в степень (^) |
LUA_OPUNM | унарный минус (унарный -) |
LUA_OPBNOT | побитовое НЕ (~) |
LUA_OPBAND | побитовое И (&) |
LUA_OPBOR | побитовое ИЛИ (|) |
LUA_OPBXOR | побитовое исключающее ИЛИ (~) |
LUA_OPSHL | сдвиг влево (<<) |
LUA_OPSHR | сдвиг вправо (>>) |
lua_atpanic
[-0, +0, –]
lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);
Устанавливает новую функцию паники и возвращает старую (см. §4.4).
lua_call
[-(nargs+1), +nresults, e]
void lua_call (lua_State *L, int nargs, int nresults);
Вызывает функцию. Как и обычные вызовы Lua, lua_call учитывает метаметод __call. Таким образом, здесь слово “функция” означает любое вызываемое значение.
Для выполнения вызова необходимо использовать следующий протокол: сначала функция, которую нужно вызвать, помещается в стек; затем аргументы вызова помещаются в прямом порядке, то есть первый аргумент помещается первым. Наконец, вы вызываете lua_call; nargs — это количество аргументов, которое вы поместили в стек. Когда функция возвращается, все аргументы и значение функции извлекаются, а результаты вызова помещаются в стек. Количество результатов выравнивается до nresults, если только nresults не равно LUA_MULTRET, что приводит к помещению всех результатов функции. В первом случае (явное количество результатов) вызывающая сторона должна убедиться, что в стеке достаточно места для возвращаемых значений. Во втором случае (все результаты) Lua заботится о том, чтобы возвращаемые значения поместились в пространство стека, но не гарантирует никакого дополнительного места в стеке. Результаты функции помещаются в стек в прямом порядке (первый результат помещается первым), так что после вызова последний результат находится на вершине стека.
Максимальное значение для nresults — 250.
Любая ошибка при вызове и выполнении функции распространяется вверх (с помощью longjmp).
Следующий пример показывает, как программа-хост может выполнить эквивалент этого кода Lua:
a = f("how", t.x, 14)
Вот это на C:
lua_getglobal(L, "f"); /* функция для вызова */
lua_pushliteral(L, "how"); /* 1-й аргумент */
lua_getglobal(L, "t"); /* таблица для индексации */
lua_getfield(L, -1, "x"); /* поместить результат t.x (2-й аргумент) */
lua_remove(L, -2); /* удалить 't' из стека */
lua_pushinteger(L, 14); /* 3-й аргумент */
lua_call(L, 3, 1); /* вызвать 'f' с 3 аргументами и 1 результатом */
lua_setglobal(L, "a"); /* установить глобальную 'a' */
Обратите внимание, что приведенный выше код сбалансирован: в конце стек возвращается к своей исходной конфигурации. Это считается хорошей практикой программирования.
lua_callk
[-(nargs + 1), +nresults, e]
void lua_callk (lua_State *L,
int nargs,
int nresults,
lua_KContext ctx,
lua_KFunction k);
Эта функция ведет себя точно так же, как lua_call, но позволяет вызываемой функции выполнять yield (см. §4.5).
lua_CFunction
typedef int (*lua_CFunction) (lua_State *L);
Тип для функций C.
Чтобы правильно взаимодействовать с Lua, функция C должна использовать следующий протокол, который определяет способ передачи параметров и результатов: функция C получает свои аргументы от Lua в своем стеке в прямом порядке (первый аргумент помещается первым). Таким образом, когда функция запускается, lua_gettop(L) возвращает количество аргументов, полученных функцией. Первый аргумент (если есть) находится по индексу 1, а последний аргумент — по индексу lua_gettop(L). Чтобы вернуть значения в Lua, функция C просто помещает их в стек в прямом порядке (первый результат помещается первым) и возвращает в C количество результатов. Любые другие значения в стеке ниже результатов будут корректно отброшены Lua. Как и функция Lua, функция C, вызванная из Lua, также может возвращать много результатов.
В качестве примера, следующая функция получает переменное количество числовых аргументов и возвращает их среднее значение и сумму:
static int foo (lua_State *L) {
int n = lua_gettop(L); /* количество аргументов */
lua_Number sum = 0.0;
int i;
for (i = 1; i <= n; i++) {
if (!lua_isnumber(L, i)) {
lua_pushliteral(L, "неверный аргумент");
lua_error(L);
}
sum += lua_tonumber(L, i);
}
lua_pushnumber(L, sum/n); /* первый результат */
lua_pushnumber(L, sum); /* второй результат */
return 2; /* количество результатов */
}
lua_checkstack
[-0, +0, –]
int lua_checkstack (lua_State *L, int n);
Гарантирует, что в стеке есть место как минимум для n дополнительных элементов, то есть что вы можете безопасно поместить в него до n значений. Возвращает false, если не может выполнить запрос, либо потому, что это привело бы к превышению фиксированного максимального размера стека (обычно не менее нескольких тысяч элементов), либо потому, что не может выделить память для дополнительного пространства. Эта функция никогда не уменьшает стек; если в стеке уже есть место для дополнительных элементов, он остается без изменений.
lua_close
[-0, +0, –]
void lua_close (lua_State *L);
Закрывает все активные закрываемые переменные (to-be-closed variables) в главном потоке, освобождает все объекты в данном состоянии Lua (вызывая соответствующие метаметоды сборки мусора, если таковые имеются) и освобождает всю динамическую память, используемую этим состоянием.
На некоторых платформах вам может не потребоваться вызывать эту функцию, потому что все ресурсы естественным образом освобождаются при завершении программы-хоста. С другой стороны, долго работающим программам, создающим несколько состояний, таким как демоны или веб-серверы, вероятно, потребуется закрывать состояния, как только они становятся ненужными.
lua_closeslot
[-0, +0, e]
void lua_closeslot (lua_State *L, int index);
Закрывает закрываемый слот (to-be-closed slot) по заданному индексу и устанавливает его значение в nil. Индекс должен быть последним индексом, ранее отмеченным для закрытия (см. lua_toclose), который все еще активен (то есть еще не закрыт).
Метаметод __close не может выполнять yield при вызове через эту функцию.
lua_closethread
[-0, +?, –]
int lua_closethread (lua_State *L, lua_State *from);
Сбрасывает поток, очищая его стек вызовов и закрывая все ожидающие закрываемые переменные. Параметр from представляет сопрограмму, которая сбрасывает L. Если такой сопрограммы нет, этот параметр может быть NULL.
Если L не равен from, вызов возвращает код состояния: LUA_OK при отсутствии ошибок в потоке (либо исходная ошибка, остановившая поток, либо ошибки в методах закрытия), или статус ошибки в противном случае. В случае ошибки объект ошибки помещается на вершину стека.
Если L равен from, это соответствует потоку, закрывающему сам себя. В этом случае вызов не возвращается; вместо этого возвращается resume, который (пере)запустил поток. Поток должен выполняться внутри resume.
lua_compare
[-0, +0, e]
int lua_compare (lua_State *L, int index1, int index2, int op);
Сравнивает два значения Lua. Возвращает 1, если значение по индексу index1 удовлетворяет условию op при сравнении со значением по индексу index2, следуя семантике соответствующего оператора Lua (то есть может вызывать метаметоды). В противном случае возвращает 0. Также возвращает 0, если какой-либо из индексов недействителен.
Значение op должно быть одной из следующих констант:
LUA_OPEQ: сравнение на равенство (==)LUA_OPLT: сравнение на меньше (<)LUA_OPLE: сравнение на меньше или равно (<=)
lua_concat
[-n, +1, e]
void lua_concat (lua_State *L, int n);
Конкатенирует n значений на вершине стека, извлекает их и оставляет результат на вершине. Если n равно 1, результатом является единственное значение в стеке (то есть функция ничего не делает); если n равно 0, результатом является пустая строка. Конкатенация выполняется в соответствии с обычной семантикой Lua (см. §3.4.6).
lua_copy
[-0, +0, –]
void lua_copy (lua_State *L, int fromidx, int toidx);
Копирует элемент по индексу fromidx в допустимый индекс toidx, заменяя значение в этой позиции. Значения в других позициях не затрагиваются.
lua_createtable
[-0, +1, m]
void lua_createtable (lua_State *L, int nseq, int nrec);
Создает новую пустую таблицу и помещает ее в стек. Параметр nseq — это подсказка о том, сколько элементов таблица будет иметь в качестве последовательности; параметр nrec — подсказка о том, сколько других элементов будет иметь таблица. Lua может использовать эти подсказки для предварительного выделения памяти для новой таблицы. Это предварительное выделение может помочь производительности, когда вы заранее знаете, сколько элементов будет в таблице. В противном случае следует использовать функцию lua_newtable.
lua_dump
[-0, +0, –]
int lua_dump (lua_State *L,
lua_Writer writer,
void *data,
int strip);
Дамп функции в виде двоичного чанка. Получает функцию Lua на вершине стека и создает двоичный чанк, который, будучи загруженным снова, дает функцию, эквивалентную дампнутой. По мере создания частей чанка lua_dump вызывает функцию writer (см. lua_Writer) с заданными data для их записи.
Функция lua_dump полностью сохраняет стек Lua при вызовах функции-писателя, за исключением того, что она может поместить некоторые значения для внутреннего использования перед первым вызовом и восстанавливает размер стека до исходного после последнего вызова.
Если strip истинно, двоичное представление может не включать всю отладочную информацию о функции для экономии места.
Возвращаемое значение — это код ошибки, возвращенный последним вызовом writer; 0 означает отсутствие ошибок.
lua_error
[-1, +0, v]
int lua_error (lua_State *L);
Возбуждает ошибку Lua, используя значение на вершине стека в качестве объекта ошибки. Эта функция выполняет длинный переход и, следовательно, никогда не возвращается (см. luaL_error).
lua_gc
[-0, +0, –]
int lua_gc (lua_State *L, int what, ...);
Управляет сборщиком мусора.
Эта функция выполняет несколько задач в зависимости от значения параметра what. Для опций, требующих дополнительных аргументов, они перечислены после опции.
LUA_GCCOLLECT: Выполняет полный цикл сборки мусора.LUA_GCSTOP: Останавливает сборщик мусора.LUA_GCRESTART: Перезапускает сборщик мусора.LUA_GCCOUNT: Возвращает текущий объем памяти (в Кбайтах), используемый Lua.LUA_GCCOUNTB: Возвращает остаток от деления текущего объема памяти в байтах, используемого Lua, на 1024.LUA_GCSTEP(size_t n): Выполняет шаг сборки мусора.LUA_GCISRUNNING: Возвращает булево значение, указывающее, работает ли сборщик (т.е. не остановлен).LUA_GCINC: Переключает сборщик в инкрементальный режим. Возвращает предыдущий режим (LUA_GCGENилиLUA_GCINC).LUA_GCGEN: Переключает сборщик в поколенческий режим. Возвращает предыдущий режим (LUA_GCGENилиLUA_GCINC).LUA_GCPARAM(int param, int val): Изменяет и/или возвращает значение параметра сборщика. Еслиvalравно -1, вызов только возвращает текущее значение. Аргументparamдолжен иметь одно из следующих значений:LUA_GCPMINORMUL: Множитель minor.LUA_GCPMAJORMINOR: Множитель major-minor.LUA_GCPMINORMAJOR: Множитель minor-major.LUA_GCPPAUSE: Пауза сборщика мусора.LUA_GCPSTEPMUL: Множитель шага.LUA_GCPSTEPSIZE: Размер шага.
Для получения более подробной информации об этих опциях см. collectgarbage.
Эта функция не должна вызываться финализатором.
lua_getallocf
[-0, +0, –]
lua_Alloc lua_getallocf (lua_State *L, void **ud);
Возвращает функцию-аллокатор памяти для данного состояния. Если ud не NULL, Lua сохраняет в *ud непрозрачный указатель, переданный при установке функции-аллокатора.
lua_getfield
[-0, +1, e]
int lua_getfield (lua_State *L, int index, const char *k);
Помещает в стек значение t[k], где t — это значение по заданному индексу. Как и в Lua, эта функция может вызвать метаметод для события “index” (см. §2.4).
Возвращает тип помещенного значения.
lua_getextraspace
[-0, +0, –]
void *lua_getextraspace (lua_State *L);
Возвращает указатель на область сырой памяти, связанную с данным состоянием Lua. Приложение может использовать эту область для любых целей; Lua не использует ее ни для чего.
Каждый новый поток имеет эту область, инициализированную копией области главного потока.
По умолчанию эта область имеет размер указателя на void, но вы можете перекомпилировать Lua с другим размером для этой области. (См. LUA_EXTRASPACE в luaconf.h).
lua_getglobal
[-0, +1, e]
int lua_getglobal (lua_State *L, const char *name);
Помещает в стек значение глобальной переменной name. Возвращает тип этого значения.
lua_geti
[-0, +1, e]
int lua_geti (lua_State *L, int index, lua_Integer i);
Помещает в стек значение t[i], где t — это значение по заданному индексу. Как и в Lua, эта функция может вызвать метаметод для события “index” (см. §2.4).
Возвращает тип помещенного значения.
lua_getmetatable
[-0, +(0|1), –]
int lua_getmetatable (lua_State *L, int index);
Если значение по заданному индексу имеет метатаблицу, функция помещает эту метатаблицу в стек и возвращает 1. В противном случае функция возвращает 0 и ничего не помещает в стек.
lua_gettable
[-1, +1, e]
int lua_gettable (lua_State *L, int index);
Помещает в стек значение t[k], где t — это значение по заданному индексу, а k — значение на вершине стека.
Эта функция извлекает ключ из стека, помещая результирующее значение на его место. Как и в Lua, эта функция может вызвать метаметод для события “index” (см. §2.4).
Возвращает тип помещенного значения.
lua_gettop
[-0, +0, –]
int lua_gettop (lua_State *L);
Возвращает индекс верхнего элемента в стеке. Поскольку индексы начинаются с 1, этот результат равен количеству элементов в стеке; в частности, 0 означает пустой стек.
lua_getiuservalue
[-0, +1, –]
int lua_getiuservalue (lua_State *L, int index, int n);
Помещает в стек n-е пользовательское значение (user value), связанное с полным userdata по заданному индексу, и возвращает тип помещенного значения.
Если userdata не имеет такого значения, помещает nil и возвращает LUA_TNONE.
lua_insert
[-1, +1, –]
void lua_insert (lua_State *L, int index);
Перемещает верхний элемент в заданный допустимый индекс, сдвигая вверх элементы над этим индексом для освобождения места. Эта функция не может вызываться с псевдоиндексом, поскольку псевдоиндекс не является фактической позицией в стеке.
lua_Integer
typedef ... lua_Integer;
Тип целых чисел в Lua.
По умолчанию этот тип — long long (обычно 64-битное целое число в дополнительном коде), но его можно изменить на long или int (обычно 32-битное целое число в дополнительном коде). (См. LUA_INT_TYPE в luaconf.h).
Lua также определяет константы LUA_MININTEGER и LUA_MAXINTEGER с минимальным и максимальным значениями, которые помещаются в этот тип.
lua_isboolean
[-0, +0, –]
int lua_isboolean (lua_State *L, int index);
Возвращает 1, если значение по заданному индексу является булевым, и 0 в противном случае.
lua_iscfunction
[-0, +0, –]
int lua_iscfunction (lua_State *L, int index);
Возвращает 1, если значение по заданному индексу является функцией C, и 0 в противном случае.
lua_isfunction
[-0, +0, –]
int lua_isfunction (lua_State *L, int index);
Возвращает 1, если значение по заданному индексу является функцией (либо C, либо Lua), и 0 в противном случае.
lua_isinteger
[-0, +0, –]
int lua_isinteger (lua_State *L, int index);
Возвращает 1, если значение по заданному индексу является целым числом (то есть значение является числом и представлено как целое), и 0 в противном случае.
lua_islightuserdata
[-0, +0, –]
int lua_islightuserdata (lua_State *L, int index);
Возвращает 1, если значение по заданному индексу является легким userdata, и 0 в противном случае.
lua_isnil
[-0, +0, –]
int lua_isnil (lua_State *L, int index);
Возвращает 1, если значение по заданному индексу равно nil, и 0 в противном случае.
lua_isnone
[-0, +0, –]
int lua_isnone (lua_State *L, int index);
Возвращает 1, если заданный индекс недействителен, и 0 в противном случае.
lua_isnoneornil
[-0, +0, –]
int lua_isnoneornil (lua_State *L, int index);
Возвращает 1, если заданный индекс недействителен или если значение по этому индексу равно nil, и 0 в противном случае.
lua_isnumber
[-0, +0, –]
int lua_isnumber (lua_State *L, int index);
Возвращает 1, если значение по заданному индексу является числом или строкой, преобразуемой в число, и 0 в противном случае.
lua_isstring
[-0, +0, –]
int lua_isstring (lua_State *L, int index);
Возвращает 1, если значение по заданному индексу является строкой или числом (которое всегда можно преобразовать в строку), и 0 в противном случае.
lua_istable
[-0, +0, –]
int lua_istable (lua_State *L, int index);
Возвращает 1, если значение по заданному индексу является таблицей, и 0 в противном случае.
lua_isthread
[-0, +0, –]
int lua_isthread (lua_State *L, int index);
Возвращает 1, если значение по заданному индексу является потоком, и 0 в противном случае.
lua_isuserdata
[-0, +0, –]
int lua_isuserdata (lua_State *L, int index);
Возвращает 1, если значение по заданному индексу является userdata (полным или легким), и 0 в противном случае.
lua_isyieldable
[-0, +0, –]
int lua_isyieldable (lua_State *L);
Возвращает 1, если данная сопрограмма может выполнить yield, и 0 в противном случае.
lua_KContext
typedef ... lua_KContext;
Тип для контекстов функций продолжения. Должен быть числовым типом. Этот тип определен как intptr_t, когда intptr_t доступен, чтобы он мог хранить и указатели. В противном случае он определен как ptrdiff_t.
lua_KFunction
typedef int (*lua_KFunction) (lua_State *L, int status, lua_KContext ctx);
Тип для функций продолжения (см. §4.5).
lua_len
[-0, +1, e]
void lua_len (lua_State *L, int index);
Возвращает длину значения по заданному индексу. Эквивалентно оператору # в Lua (см. §3.4.7) и может вызвать метаметод для события “length” (см. §2.4). Результат помещается в стек.
lua_load
[-0, +1, –]
int lua_load (lua_State *L,
lua_Reader reader,
void *data,
const char *chunkname,
const char *mode);
Загружает чанк Lua без его выполнения. Если ошибок нет, lua_load помещает скомпилированный чанк как функцию Lua на вершину стека. В противном случае она помещает сообщение об ошибке.
Функция lua_load использует предоставленную пользователем функцию-читатель (reader) для чтения чанка (см. lua_Reader). Аргумент data — это непрозрачное значение, передаваемое в функцию-читатель.
Аргумент chunkname дает имя чанку, которое используется для сообщений об ошибках и в отладочной информации (см. §4.7).
lua_load автоматически определяет, является ли чанк текстовым или двоичным, и загружает его соответствующим образом (см. программу luac). Строка mode работает как в функции load, с тем дополнением, что значение NULL эквивалентно строке "bt". Более того, она может содержать 'B' вместо 'b', что означает фиксированный буфер (fixed buffer) с двоичным дампом.
Фиксированный буфер означает, что адрес, возвращаемый функцией-читателем, будет содержать чанк до тех пор, пока все, созданное чанком, не будет собрано сборщиком мусора; таким образом, Lua может избежать копирования некоторых частей чанка во внутренние структуры. (В общем случае фиксированный буфер будет сохранять свое содержимое до конца программы, например, при чанке в ПЗУ). Более того, для фиксированного буфера функция-читатель должна вернуть весь чанк при первом чтении. (В качестве примера, luaL_loadbufferx делает это, что означает, что вы можете использовать ее для загрузки фиксированных буферов).
Функция lua_load полностью сохраняет стек Lua при вызовах функции-читателя, за исключением того, что она может поместить некоторые значения для внутреннего использования перед первым вызовом и восстанавливает размер стека до исходного размера плюс один (для помещенного результата) после последнего вызова.
lua_load может возвращать LUA_OK, LUA_ERRSYNTAX или LUA_ERRMEM. Функция также может возвращать другие значения, соответствующие ошибкам, возбужденным функцией чтения (см. §4.4.1).
Если результирующая функция имеет upvalue, ее первое upvalue устанавливается в значение глобального окружения, хранящееся по индексу LUA_RIDX_GLOBALS в реестре (см. §4.3). При загрузке главных чанков этим upvalue будет переменная _ENV (см. §2.2). Остальные upvalue инициализируются значением nil.
lua_newstate
[-0, +0, –]
lua_State *lua_newstate (lua_Alloc f, void *ud,
unsigned int seed);
Создает новое независимое состояние и возвращает его главный поток. Возвращает NULL, если не может создать состояние (из-за нехватки памяти). Аргумент f — это функция-аллокатор; Lua будет выполнять все выделение памяти для этого состояния через эту функцию (см. lua_Alloc). Второй аргумент, ud, — непрозрачный указатель, который Lua передает аллокатору при каждом вызове. Третий аргумент, seed, — это начальное значение для хеширования строк.
lua_newtable
[-0, +1, m]
void lua_newtable (lua_State *L);
Создает новую пустую таблицу и помещает ее в стек. Эквивалентно lua_createtable(L,0,0).
lua_newthread
[-0, +1, m]
lua_State *lua_newthread (lua_State *L);
Создает новый поток, помещает его в стек и возвращает указатель на lua_State, представляющий этот новый поток. Новый поток, возвращаемый этой функцией, разделяет с исходным потоком его глобальное окружение, но имеет независимый стек выполнения.
Потоки подлежат сборке мусора, как и любой объект Lua.
lua_newuserdatauv
[-0, +1, m]
void *lua_newuserdatauv (lua_State *L, size_t size, int nuvalue);
Эта функция создает и помещает в стек новый полный userdata с nuvalue связанными значениями Lua, называемыми пользовательскими значениями (user values), плюс связанный блок сырой памяти размером size байт. (Пользовательские значения можно устанавливать и читать с помощью функций lua_setiuservalue и lua_getiuservalue).
Функция возвращает адрес блока памяти. Lua гарантирует, что этот адрес действителен, пока соответствующий userdata жив (см. §2.5). Более того, если userdata помечен для финализации (см. §2.5.3), его адрес действителен по крайней мере до вызова его финализатора.
lua_next
[-1, +(2|0), v]
int lua_next (lua_State *L, int index);
Извлекает ключ из стека и помещает пару ключ-значение из таблицы по заданному индексу — “следующую” пару после данного ключа. Если в таблице больше нет элементов, lua_next возвращает 0 и ничего не помещает.
Типичный обход таблицы выглядит так:
/* таблица находится в стеке по индексу 't' */
lua_pushnil(L); /* первый ключ */
while (lua_next(L, t) != 0) {
/* используем 'key' (по индексу -2) и 'value' (по индексу -1) */
printf("%s - %s\n",
lua_typename(L, lua_type(L, -2)),
lua_typename(L, lua_type(L, -1)));
/* удаляем 'value'; сохраняем 'key' для следующей итерации */
lua_pop(L, 1);
}
При обходе таблицы избегайте вызова lua_tolstring непосредственно для ключа, если вы не уверены, что ключ действительно является строкой. Напомним, что lua_tolstring может изменить значение по заданному индексу; это собьет следующий вызов lua_next.
Эта функция может возбудить ошибку, если данный ключ не равен nil и не присутствует в таблице. См. функцию next для предостережений относительно модификации таблицы во время ее обхода.
lua_Number
typedef ... lua_Number;
Тип чисел с плавающей запятой в Lua.
По умолчанию этот тип — double, но его можно изменить на float или long double. (См. LUA_FLOAT_TYPE в luaconf.h).
lua_numbertointeger
int lua_numbertointeger (lua_Number n, lua_Integer *p);
Пытается преобразовать число Lua с плавающей запятой в целое число Lua; число n должно иметь целое значение. Если это значение находится в диапазоне целых чисел Lua, оно преобразуется в целое и присваивается *p. Макрос возвращает булево значение, указывающее, было ли преобразование успешным. (Обратите внимание, что эту проверку диапазона трудно выполнить корректно без этого макроса из-за округления).
Этот макрос может вычислять свои аргументы более одного раза.
lua_numbertocstring
[-0, +0, –]
unsigned lua_numbertocstring (lua_State *L, int idx,
char *buff);
Преобразует число по приемлемому индексу idx в строку и помещает результат в buff. Буфер должен иметь размер не менее LUA_N2SBUFFSZ байт. Преобразование следует неуказанному формату (см. §3.4.3). Функция возвращает количество байт, записанных в буфер (включая завершающий ноль), или ноль, если значение по idx не является числом.
lua_pcall
[-(nargs + 1), +(nresults|1), –]
int lua_pcall (lua_State *L, int nargs, int nresults, int msgh);
Вызывает функцию (или вызываемый объект) в защищенном режиме.
И nargs, и nresults имеют то же значение, что и в lua_call. Если во время вызова нет ошибок, lua_pcall ведет себя точно так же, как lua_call. Однако, если возникает какая-либо ошибка, lua_pcall перехватывает ее, помещает в стек единственное значение (объект ошибки) и возвращает код ошибки. Как и lua_call, lua_pcall всегда удаляет функцию и ее аргументы из стека.
Если msgh равно 0, то объект ошибки, возвращаемый в стеке, является в точности исходным объектом ошибки. В противном случае msgh — это индекс в стеке обработчика сообщений. (Этот индекс не может быть псевдоиндексом). В случае ошибок времени выполнения этот обработчик будет вызван с объектом ошибки, и его возвращаемое значение будет объектом, возвращенным в стеке функцией lua_pcall.
Обычно обработчик сообщений используется для добавления дополнительной отладочной информации к объекту ошибки, такой как трассировка стека. Такую информацию невозможно собрать после возврата lua_pcall, поскольку к тому времени стек уже свернут.
Функция lua_pcall возвращает один из следующих кодов состояния: LUA_OK, LUA_ERRRUN, LUA_ERRMEM или LUA_ERRERR.
lua_pcallk
[-(nargs + 1), +(nresults|1), –]
int lua_pcallk (lua_State *L,
int nargs,
int nresults,
int msgh,
lua_KContext ctx,
lua_KFunction k);
Эта функция ведет себя точно так же, как lua_pcall, за исключением того, что она позволяет вызываемой функции выполнять yield (см. §4.5).
lua_pop
[-n, +0, e]
void lua_pop (lua_State *L, int n);
Извлекает n элементов из стека. Реализован как макрос над lua_settop.
lua_pushboolean
[-0, +1, –]
void lua_pushboolean (lua_State *L, int b);
Помещает булево значение со значением b в стек.
lua_pushcclosure
[-n, +1, m]
void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
Помещает новое замыкание C в стек. Эта функция получает указатель на функцию C и помещает в стек значение Lua типа function, которое при вызове вызывает соответствующую функцию C. Параметр n сообщает, сколько upvalue будет у этой функции (см. §4.2).
Любая функция, вызываемая из Lua, должна следовать правильному протоколу для получения параметров и возврата результатов (см. lua_CFunction).
При создании функции C с ней можно связать некоторые значения, так называемые upvalue; эти upvalue затем доступны функции при каждом ее вызове. Эта связь называется замыканием C (см. §4.2). Чтобы создать замыкание C, сначала начальные значения для его upvalue должны быть помещены в стек. (Если upvalue несколько, первое значение помещается первым). Затем вызывается lua_pushcclosure для создания и помещения функции C в стек, при этом аргумент n сообщает, сколько значений будет связано с функцией. lua_pushcclosure также извлекает эти значения из стека.
Максимальное значение для n — 255.
Когда n равно нулю, эта функция создает легкую функцию C (light C function), которая является просто указателем на функцию C. В этом случае она никогда не вызывает ошибку памяти.
lua_pushcfunction
[-0, +1, –]
void lua_pushcfunction (lua_State *L, lua_CFunction f);
Помещает функцию C в стек. Эта функция эквивалентна lua_pushcclosure без upvalue.
lua_pushexternalstring
[-0, +1, m]
const char *lua_pushexternalstring (lua_State *L,
const char *s, size_t len, lua_Alloc falloc, void *ud);
Создает внешнюю строку (external string), то есть строку, использующую память, не управляемую Lua. Указатель s указывает на внешний буфер, содержащий содержимое строки, а len — это длина строки. Строка должна иметь ноль в конце, то есть должно выполняться условие s[len] == '\0'. Как и для любой строки в Lua, длина должна помещаться в целое число Lua.
Если falloc отличается от NULL, эта функция будет вызвана Lua, когда внешний буфер больше не нужен. Содержимое буфера не должно изменяться до этого вызова. Функция будет вызвана с заданным ud, строкой s в качестве блока, длиной плюс один (для учета завершающего нуля) в качестве старого размера и 0 в качестве нового размера.
Даже при использовании внешнего буфера Lua все равно должен выделить заголовок для строки. В случае ошибки выделения памяти Lua вызовет falloc перед возбуждением ошибки.
Функция возвращает указатель на строку (то есть s).
lua_pushfstring
[-0, +1, v]
const char *lua_pushfstring (lua_State *L, const char *fmt, ...);
Помещает в стек форматированную строку и возвращает указатель на эту строку (см. §4.1.3). Результат — это копия fmt, в которой каждый спецификатор преобразования заменен строковым представлением соответствующего дополнительного аргумента. Спецификатор преобразования (и соответствующий ему дополнительный аргумент) может быть: '%%' (вставляет символ '%'), '%s' (вставляет строку с завершающим нулем, без ограничений по размеру), '%f' (вставляет lua_Number), '%I' (вставляет lua_Integer), '%p' (вставляет указатель void*), '%d' (вставляет int), '%c' (вставляет int как однобайтовый символ) и '%U' (вставляет unsigned long как последовательность байт UTF-8).
Каждое вхождение '%' в строке fmt должно образовывать допустимый спецификатор преобразования.
Помимо ошибок выделения памяти, эта функция может возбудить ошибку, если результирующая строка слишком велика.
lua_pushglobaltable
[-0, +1, –]
void lua_pushglobaltable (lua_State *L);
Помещает глобальное окружение в стек.
lua_pushinteger
[-0, +1, –]
void lua_pushinteger (lua_State *L, lua_Integer n);
Помещает целое число со значением n в стек.
lua_pushlightuserdata
[-0, +1, –]
void lua_pushlightuserdata (lua_State *L, void *p);
Помещает легкий userdata в стек.
Userdata представляют значения C в Lua. Легкий userdata представляет указатель, void*. Это значение (как число): вы его не создаете, у него нет индивидуальной метатаблицы, и оно не собирается сборщиком мусора (поскольку никогда не создавалось). Легкий userdata равен “любому” легкому userdata с тем же адресом C.
lua_pushliteral
[-0, +1, v]
const char *lua_pushliteral (lua_State *L, const char *s);
Этот макрос эквивалентен lua_pushstring, но должен использоваться только тогда, когда s является литеральной строкой. (Lua может оптимизировать этот случай).
lua_pushlstring
[-0, +1, v]
const char *lua_pushlstring (lua_State *L, const char *s, size_t len);
Помещает строку, на которую указывает s, размером len, в стек. Lua создаст или повторно использует внутреннюю копию данной строки, так что память по адресу s может быть освобождена или повторно использована сразу после возврата функции. Строка может содержать любые двоичные данные, включая встроенные нули.
Возвращает указатель на внутреннюю копию строки (см. §4.1.3).
Помимо ошибок выделения памяти, эта функция может возбудить ошибку, если строка слишком велика.
lua_pushnil
[-0, +1, –]
void lua_pushnil (lua_State *L);
Помещает значение nil в стек.
lua_pushnumber
[-0, +1, –]
void lua_pushnumber (lua_State *L, lua_Number n);
Помещает число с плавающей запятой со значением n в стек.
lua_pushstring
[-0, +1, m]
const char *lua_pushstring (lua_State *L, const char *s);
Помещает строку с завершающим нулем, на которую указывает s, в стек. Lua создаст или повторно использует внутреннюю копию данной строки, так что память по адресу s может быть освобождена или повторно использована сразу после возврата функции.
Возвращает указатель на внутреннюю копию строки (см. §4.1.3).
Если s равен NULL, помещает nil и возвращает NULL.
lua_pushthread
[-0, +1, –]
int lua_pushthread (lua_State *L);
Помещает поток, представленный L, в стек. Возвращает 1, если этот поток является главным потоком своего состояния.
lua_pushvalue
[-0, +1, –]
void lua_pushvalue (lua_State *L, int index);
Помещает копию элемента по заданному индексу в стек.
lua_pushvfstring
[-0, +1, –]
const char *lua_pushvfstring (lua_State *L,
const char *fmt,
va_list argp);
Эквивалентно lua_pushfstring, за исключением того, что получает va_list вместо переменного количества аргументов и не возбуждает ошибок. Вместо этого в случае ошибок помещает сообщение об ошибке и возвращает NULL.
lua_rawequal
[-0, +0, –]
int lua_rawequal (lua_State *L, int index1, int index2);
Возвращает 1, если два значения по индексам index1 и index2 примитивно равны (то есть равны без вызова метаметода __eq). В противном случае возвращает 0. Также возвращает 0, если какой-либо из индексов недействителен.
lua_rawget
[-1, +1, –]
int lua_rawget (lua_State *L, int index);
Аналогично lua_gettable, но выполняет сырой доступ (т.е. без метаметодов). Значение по индексу index должно быть таблицей.
lua_rawgeti
[-0, +1, –]
int lua_rawgeti (lua_State *L, int index, lua_Integer n);
Помещает в стек значение t[n], где t — таблица по заданному индексу. Доступ сырой, то есть не использует метазначение __index.
Возвращает тип помещенного значения.
lua_rawgetp
[-0, +1, –]
int lua_rawgetp (lua_State *L, int index, const void *p);
Помещает в стек значение t[k], где t — таблица по заданному индексу, а k — указатель p, представленный как легкий userdata. Доступ сырой, то есть не использует метазначение __index.
Возвращает тип помещенного значения.
lua_rawlen
[-0, +0, –]
lua_Unsigned lua_rawlen (lua_State *L, int index);
Возвращает сырую “длину” значения по заданному индексу: для строк это длина строки; для таблиц это результат оператора длины (#) без метаметодов; для userdata это размер блока памяти, выделенного для userdata. Для других значений этот вызов возвращает 0.
lua_rawset
[-2, +0, m]
void lua_rawset (lua_State *L, int index);
Аналогично lua_settable, но выполняет сырое присваивание (т.е. без метаметодов). Значение по индексу index должно быть таблицей.
lua_rawseti
[-1, +0, m]
void lua_rawseti (lua_State *L, int index, lua_Integer i);
Выполняет эквивалент t[i] = v, где t — таблица по заданному индексу, а v — значение на вершине стека.
Эта функция извлекает значение из стека. Присваивание сырое, то есть не использует метазначение __newindex.
lua_rawsetp
[-1, +0, m]
void lua_rawsetp (lua_State *L, int index, const void *p);
Выполняет эквивалент t[p] = v, где t — таблица по заданному индексу, p закодировано как легкий userdata, а v — значение на вершине стека.
Эта функция извлекает значение из стека. Присваивание сырое, то есть не использует метазначение __newindex.
lua_Reader
typedef const char * (*lua_Reader) (lua_State *L,
void *data,
size_t *size);
Функция-читатель, используемая lua_load. Каждый раз, когда lua_load нуждается в очередной части чанка, она вызывает читатель, передавая его параметр data. Читатель должен вернуть указатель на блок памяти с новым куском чанка и установить size в размер блока. Блок должен существовать до тех пор, пока функция-читатель не будет вызвана снова. Чтобы сигнализировать о конце чанка, читатель должен вернуть NULL или установить size в ноль. Функция-читатель может возвращать куски любого размера больше нуля.
lua_register
[-0, +0, e]
void lua_register (lua_State *L, const char *name, lua_CFunction f);
Устанавливает функцию C f как новое значение глобальной переменной name. Определено как макрос:
#define lua_register(L,n,f) \
(lua_pushcfunction(L, f), lua_setglobal(L, n))
lua_remove
[-1, +0, –]
void lua_remove (lua_State *L, int index);
Удаляет элемент по заданному допустимому индексу, сдвигая вниз элементы над этим индексом для заполнения промежутка. Эта функция не может вызываться с псевдоиндексом, поскольку псевдоиндекс не является фактической позицией в стеке.
lua_replace
[-1, +0, –]
void lua_replace (lua_State *L, int index);
Перемещает верхний элемент в заданный допустимый индекс без сдвига каких-либо элементов (таким образом, заменяя значение по этому заданному индексу), а затем извлекает верхний элемент.
lua_resume
[-?, +?, –]
int lua_resume (lua_State *L, lua_State *from, int nargs,
int *nresults);
Запускает и возобновляет сопрограмму в заданном потоке L.
Чтобы запустить сопрограмму, вы помещаете главную функцию и все аргументы в пустой стек потока, затем вызываете lua_resume, где nargs — количество аргументов. Функция возвращается, когда сопрограмма приостанавливается, завершает свое выполнение или возбуждает незащищенную ошибку. Когда она возвращается без ошибок, *nresults обновляется, и вершина стека содержит *nresults значений, переданных в lua_yield или возвращенных функцией тела. lua_resume возвращает LUA_YIELD, если сопрограмма выполняет yield, LUA_OK, если сопрограмма завершает выполнение без ошибок, или код ошибки в случае ошибок (см. §4.4.1). В случае ошибок объект ошибки помещается на вершину стека. (В этом случае nresults не обновляется, так как его значение должно было бы быть 1 для единственного объекта ошибки).
Чтобы возобновить приостановленную сопрограмму, вы удаляете *nresults значений, возвращенных yield, из ее стека, помещаете значения, которые будут переданы как результаты из yield, а затем вызываете lua_resume.
Параметр from представляет сопрограмму, которая возобновляет L. Если такой сопрограммы нет, этот параметр может быть NULL.
lua_rotate
[-0, +0, –]
void lua_rotate (lua_State *L, int idx, int n);
Вращает элементы стека между допустимым индексом idx и вершиной стека. Элементы вращаются на n позиций в направлении вершины для положительного n или на -n позиций в направлении дна для отрицательного n. Абсолютное значение n не должно превышать размер вращаемого среза. Эта функция не может вызываться с псевдоиндексом, поскольку псевдоиндекс не является фактической позицией в стеке.
lua_setallocf
[-0, +0, –]
void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
Изменяет функцию-аллокатор данного состояния на f с пользовательскими данными ud.
lua_setfield
[-1, +0, e]
void lua_setfield (lua_State *L, int index, const char *k);
Выполняет эквивалент t[k] = v, где t — значение по заданному индексу, а v — значение на вершине стека.
Эта функция извлекает значение из стека. Как и в Lua, эта функция может вызвать метаметод для события “newindex” (см. §2.4).
lua_setglobal
[-1, +0, e]
void lua_setglobal (lua_State *L, const char *name);
Извлекает значение из стека и устанавливает его как новое значение глобальной переменной name.
lua_seti
[-1, +0, e]
void lua_seti (lua_State *L, int index, lua_Integer n);
Выполняет эквивалент t[n] = v, где t — значение по заданному индексу, а v — значение на вершине стека.
Эта функция извлекает значение из стека. Как и в Lua, эта функция может вызвать метаметод для события “newindex” (см. §2.4).
lua_setiuservalue
[-1, +0, –]
int lua_setiuservalue (lua_State *L, int index, int n);
Извлекает значение из стека и устанавливает его как новое n-е пользовательское значение, связанное с полным userdata по заданному индексу. Возвращает 0, если userdata не имеет такого значения.
lua_setmetatable
[-1, +0, –]
int lua_setmetatable (lua_State *L, int index);
Извлекает таблицу или nil из стека и устанавливает это значение как новую метатаблицу для значения по заданному индексу. (nil означает отсутствие метатаблицы).
(По историческим причинам эта функция возвращает int, который теперь всегда равен 1).
lua_settable
[-2, +0, e]
void lua_settable (lua_State *L, int index);
Выполняет эквивалент t[k] = v, где t — значение по заданному индексу, v — значение на вершине стека, а k — значение непосредственно под вершиной.
Эта функция извлекает и ключ, и значение из стека. Как и в Lua, эта функция может вызвать метаметод для события “newindex” (см. §2.4).
lua_settop
[-?, +?, e]
void lua_settop (lua_State *L, int index);
Принимает любой приемлемый индекс стека или 0 и устанавливает вершину стека в этот индекс. Если новая вершина больше старой, то новые элементы заполняются значением nil. Если index равен 0, то все элементы стека удаляются.
Эта функция может выполнять произвольный код при удалении из стека индекса, помеченного как закрываемый (to-be-closed).
lua_setwarnf
[-0, +0, –]
void lua_setwarnf (lua_State *L, lua_WarnFunction f, void *ud);
Устанавливает функцию предупреждения, используемую Lua для выдачи предупреждений (см. lua_WarnFunction). Параметр ud устанавливает значение ud, передаваемое в функцию предупреждения.
lua_State
typedef struct lua_State lua_State;
Непрозрачная структура, которая указывает на поток и косвенно (через поток) на все состояние интерпретатора Lua. Библиотека Lua полностью реентерабельна: у нее нет глобальных переменных. Вся информация о состоянии доступна через эту структуру.
Указатель на эту структуру должен передаваться в качестве первого аргумента каждой функции в библиотеке, кроме lua_newstate, которая создает состояние Lua с нуля.
lua_status
[-0, +0, –]
int lua_status (lua_State *L);
Возвращает статус потока L.
Статус может быть LUA_OK для нормального потока, кодом ошибки, если поток завершил выполнение lua_resume с ошибкой, или LUA_YIELD, если поток приостановлен.
Вы можете вызывать функции только в потоках со статусом LUA_OK. Вы можете возобновлять потоки со статусом LUA_OK (для запуска новой сопрограммы) или LUA_YIELD (для возобновления сопрограммы).
lua_stringtonumber
[-0, +1, –]
size_t lua_stringtonumber (lua_State *L, const char *s);
Преобразует строку с завершающим нулем s в число, помещает это число в стек и возвращает общий размер строки, то есть ее длину плюс один. Преобразование может дать целое число или число с плавающей запятой в соответствии с лексическими соглашениями Lua (см. §3.1). Строка может иметь начальные и конечные пробелы и знак. Если строка не является допустимым числом, возвращает 0 и ничего не помещает. (Обратите внимание, что результат можно использовать как булево значение, true, если преобразование успешно).
lua_toboolean
[-0, +0, –]
int lua_toboolean (lua_State *L, int index);
Преобразует значение Lua по заданному индексу в булево значение C (0 или 1). Как и все проверки в Lua, lua_toboolean возвращает true для любого значения Lua, отличного от false и nil; в противном случае возвращает false. (Если вы хотите принимать только фактические булевы значения, используйте lua_isboolean для проверки типа значения).
lua_tocfunction
[-0, +0, –]
lua_CFunction lua_tocfunction (lua_State *L, int index);
Преобразует значение по заданному индексу в функцию C. Это значение должно быть функцией C; в противном случае возвращает NULL.
lua_toclose
[-0, +0, v]
void lua_toclose (lua_State *L, int index);
Помечает заданный индекс в стеке как закрываемый слот (to-be-closed slot) (см. §3.3.8). Как и закрываемая переменная в Lua, значение в этом слоте стека будет закрыто, когда оно выйдет из области видимости. Здесь, в контексте функции C, “выйти из области видимости” означает, что выполняющаяся функция возвращается в Lua, или происходит ошибка, или слот удаляется из стека через lua_settop или lua_pop, или происходит вызов lua_closeslot. Слот, помеченный как закрываемый, не должен удаляться из стека никакой другой функцией API, кроме lua_settop или lua_pop, если только он предварительно не деактивирован вызовом lua_closeslot.
Эта функция возбуждает ошибку, если значение в заданном слоте не имеет метаметода __close и не является ложным значением.
Эту функцию не следует вызывать для индекса, который равен или находится ниже активного закрываемого слота.
Обратите внимание, что как в случае ошибок, так и при обычном возврате, к моменту выполнения метаметода __close стек C уже свернут, так что любые автоматические переменные C, объявленные в вызывающей функции (например, буфер), будут вне области видимости.
lua_tointeger
[-0, +0, –]
lua_Integer lua_tointeger (lua_State *L, int index);
Эквивалентно lua_tointegerx с isnum, равным NULL.
lua_tointegerx
[-0, +0, –]
lua_Integer lua_tointegerx (lua_State *L, int index, int *isnum);
Преобразует значение Lua по заданному индексу в знаковый целочисленный тип lua_Integer. Значение Lua должно быть целым числом, или числом, или строкой, преобразуемой в целое число (см. §3.4.3); в противном случае lua_tointegerx возвращает 0.
Если isnum не NULL, по его ссылке присваивается булево значение, указывающее, успешно ли выполнена операция.
lua_tolstring
[-0, +0, m]
const char *lua_tolstring (lua_State *L, int index, size_t *len);
Преобразует значение Lua по заданному индексу в строку C. Значение Lua должно быть строкой или числом; в противном случае функция возвращает NULL. Если значение — число, то lua_tolstring также изменяет фактическое значение в стеке на строку. (Это изменение сбивает lua_next, когда lua_tolstring применяется к ключам во время обхода таблицы).
Если len не NULL, функция устанавливает *len в длину строки. Возвращаемая строка C всегда имеет ноль ('\0') после своего последнего символа, но может содержать другие нули в своем теле.
Указатель, возвращаемый lua_tolstring, может быть признан недействительным сборщиком мусора, если соответствующее значение Lua удалено из стека (см. §4.1.3).
Эта функция может вызывать ошибки памяти только при преобразовании числа в строку (поскольку в этом случае она может создать новую строку).
lua_tonumber
[-0, +0, –]
lua_Number lua_tonumber (lua_State *L, int index);
Эквивалентно lua_tonumberx с isnum, равным NULL.
lua_tonumberx
[-0, +0, –]
lua_Number lua_tonumberx (lua_State *L, int index, int *isnum);
Преобразует значение Lua по заданному индексу в тип C lua_Number (см. lua_Number). Значение Lua должно быть числом или строкой, преобразуемой в число (см. §3.4.3); в противном случае lua_tonumberx возвращает 0.
Если isnum не NULL, по его ссылке присваивается булево значение, указывающее, успешно ли выполнена операция.
lua_topointer
[-0, +0, –]
const void *lua_topointer (lua_State *L, int index);
Преобразует значение по заданному индексу в обобщенный указатель C (void*). Значение может быть userdata, таблицей, потоком, строкой или функцией; в противном случае lua_topointer возвращает NULL. Разные объекты будут давать разные указатели. Нет способа преобразовать указатель обратно в исходное значение.
Обычно эта функция используется только для хеширования и отладочной информации.
lua_tostring
[-0, +0, m]
const char *lua_tostring (lua_State *L, int index);
Эквивалентно lua_tolstring с len, равным NULL.
lua_tothread
[-0, +0, –]
lua_State *lua_tothread (lua_State *L, int index);
Преобразует значение по заданному индексу в поток Lua (представленный как lua_State*). Это значение должно быть потоком; в противном случае функция возвращает NULL.
lua_touserdata
[-0, +0, –]
void *lua_touserdata (lua_State *L, int index);
Если значение по заданному индексу является полным userdata, возвращает адрес его блока памяти. Если значение — легкий userdata, возвращает его значение (указатель). В противном случае возвращает NULL.
lua_type
[-0, +0, –]
int lua_type (lua_State *L, int index);
Возвращает тип значения в заданном допустимом индексе или LUA_TNONE для недопустимого, но приемлемого индекса. Типы, возвращаемые lua_type, кодируются следующими константами, определенными в lua.h: LUA_TNIL, LUA_TNUMBER, LUA_TBOOLEAN, LUA_TSTRING, LUA_TTABLE, LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD и LUA_TLIGHTUSERDATA.
lua_typename
[-0, +0, –]
const char *lua_typename (lua_State *L, int tp);
Возвращает имя типа, закодированного значением tp, которое должно быть одним из значений, возвращаемых lua_type.
lua_Unsigned
typedef ... lua_Unsigned;
Беззнаковая версия lua_Integer.
lua_upvalueindex
[-0, +0, –]
int lua_upvalueindex (int i);
Возвращает псевдоиндекс, представляющий i-е upvalue выполняющейся функции (см. §4.2). i должно быть в диапазоне [1,256].
lua_version
[-0, +0, –]
lua_Number lua_version (lua_State *L);
Возвращает номер версии данного ядра.
lua_WarnFunction
typedef void (*lua_WarnFunction) (void *ud, const char *msg, int tocont);
Тип функций предупреждения, вызываемых Lua для выдачи предупреждений. Первый параметр — непрозрачный указатель, установленный lua_setwarnf. Второй параметр — сообщение предупреждения. Третий параметр — булево значение, указывающее, будет ли сообщение продолжено сообщением в следующем вызове.
См. warn для получения дополнительной информации о предупреждениях.
lua_warning
[-0, +0, –]
void lua_warning (lua_State *L, const char *msg, int tocont);
Выдает предупреждение с заданным сообщением. Сообщение в вызове с tocont равным true должно быть продолжено в другом вызове этой функции.
См. warn для получения дополнительной информации о предупреждениях.
lua_Writer
typedef int (*lua_Writer) (lua_State *L,
const void* p,
size_t sz,
void* ud);
Тип функции-писателя, используемой lua_dump. Каждый раз, когда lua_dump создает очередную часть чанка, она вызывает писатель, передавая буфер для записи (p), его размер (sz) и параметр ud, переданный в lua_dump.
После того как lua_dump запишет свою последнюю часть, она сигнализирует об этом, вызывая функцию-писатель еще один раз с буфером NULL (и размером 0).
Писатель возвращает код ошибки: 0 означает отсутствие ошибок; любое другое значение означает ошибку и останавливает lua_dump от дальнейших вызовов писателя.
lua_xmove
[-?, +?, –]
void lua_xmove (lua_State *from, lua_State *to, int n);
Обменивает значения между разными потоками одного и того же состояния.
Эта функция извлекает n значений из стека from и помещает их в стек to.
lua_yield
[-?, +?, v]
int lua_yield (lua_State *L, int nresults);
Эта функция эквивалентна lua_yieldk, но не имеет продолжения (см. §4.5). Следовательно, когда поток возобновляется, он продолжает функцию, которая вызвала функцию, вызывающую lua_yield. Во избежание неожиданностей эту функцию следует вызывать только в хвостовом вызове.
lua_yieldk
[-?, +?, v]
int lua_yieldk (lua_State *L,
int nresults,
lua_KContext ctx,
lua_KFunction k);
Выполняет yield сопрограммы (потока).
Когда функция C вызывает lua_yieldk, выполняющаяся сопрограмма приостанавливает свое выполнение, и вызов lua_resume, запустивший эту сопрограмму, возвращается. Параметр nresults — это количество значений из стека, которые будут переданы как результаты в lua_resume.
Когда сопрограмма возобновляется снова, Lua вызывает заданную функцию продолжения k для продолжения выполнения функции C, которая выполнила yield (см. §4.5). Эта функция продолжения получает тот же стек, что и предыдущая функция, с удаленными n результатами и замененными аргументами, переданными в lua_resume. Более того, функция продолжения получает значение ctx, которое было передано в lua_yieldk.
Обычно эта функция не возвращается; когда сопрограмма в конечном итоге возобновляется, она продолжает выполнение функции продолжения. Однако есть один особый случай: когда эта функция вызывается изнутри хука строки или счетчика (см. §4.7). В этом случае lua_yieldk должна вызываться без продолжения (вероятно, в форме lua_yield) и без результатов, а хук должен возвращаться немедленно после вызова. Lua выполнит yield, и, когда сопрограмма снова возобновится, она продолжит нормальное выполнение функции (Lua), которая вызвала хук.
Эта функция может возбудить ошибку, если она вызывается из потока с ожидающим вызовом C без функции продолжения (то, что называется границей C-вызова), или если она вызывается из потока, который не выполняется внутри resume (обычно главный поток).
4.7 – Отладочный интерфейс
Lua не имеет встроенных средств отладки. Вместо этого он предлагает специальный интерфейс посредством функций и хуков. Этот интерфейс позволяет создавать различные виды отладчиков, профайлеров и других инструментов, которым нужна “внутренняя информация” от интерпретатора.
lua_Debug
typedef struct lua_Debug {
int event;
const char *name; /* (n) */
const char *namewhat; /* (n) */
const char *what; /* (S) */
const char *source; /* (S) */
size_t srclen; /* (S) */
int currentline; /* (l) */
int linedefined; /* (S) */
int lastlinedefined; /* (S) */
unsigned char nups; /* (u) количество upvalue */
unsigned char nparams; /* (u) количество параметров */
char isvararg; /* (u) */
unsigned char extraargs; /* (t) количество дополнительных аргументов */
char istailcall; /* (t) */
int ftransfer; /* (r) индекс первого передаваемого значения */
int ntransfer; /* (r) количество передаваемых значений */
char short_src[LUA_IDSIZE]; /* (S) */
/* приватная часть */
другие поля
} lua_Debug;
Структура, используемая для переноса различных фрагментов информации о функции или записи активации. lua_getstack заполняет только приватную часть этой структуры для последующего использования. Чтобы заполнить другие поля lua_Debug полезной информацией, необходимо вызвать lua_getinfo с соответствующим параметром. (В частности, чтобы получить поле, необходимо добавить букву в скобках в комментарии к полю в параметр what функции lua_getinfo.)
Поля lua_Debug имеют следующее значение:
source: источник чанка, создавшего функцию. Еслиsourceначинается с'@', это означает, что функция была определена в файле, имя которого следует за'@'. Еслиsourceначинается с'=', остальная часть его содержимого описывает источник способом, зависящим от пользователя. В противном случае функция была определена в строке, гдеsourceи есть эта строка.srclen: Длина строкиsource.short_src: “печатная” версияsourceдля использования в сообщениях об ошибках.linedefined: номер строки, с которой начинается определение функции.lastlinedefined: номер строки, на которой заканчивается определение функции.what: строка"Lua", если функция Lua,"C", если функция C,"main", если это главная часть чанка.currentline: текущая строка, в которой выполняется данная функция. Когда информация о строке недоступна,currentlineустанавливается в -1.name: подходящее имя для данной функции. Поскольку функции в Lua являются значениями первого класса, у них нет фиксированного имени: некоторые функции могут быть значением нескольких глобальных переменных, в то время как другие могут храниться только в поле таблицы. Функцияlua_getinfoпроверяет, как была вызвана функция, чтобы найти подходящее имя. Если она не может найти имя, тоnameустанавливается вNULL.namewhat: объясняет полеname. Значениеnamewhatможет быть"global","local","upvalue","field",""(пустая строка) плюс некоторые другие варианты, в зависимости от того, как была вызвана функция. (Lua использует пустую строку, когда ни один другой вариант не подходит).istailcall:true, если этот вызов функции был сделан через хвостовой вызов. В этом случае вызыватель этого уровня отсутствует в стеке.extraargs: Количество дополнительных аргументов, добавленных при вызове функций через метаметоды__call. (Каждое метазначение__callдобавляет один дополнительный аргумент — вызываемый объект, но может быть цепочка метазначений__call).nups: количество upvalue функции.nparams: количество параметров функции (всегда 0 для функций C).isvararg:true, если функция вариадическая (всегдаtrueдля функций C).ftransfer: индекс в стеке первого “передаваемого” значения, то есть параметров при вызове или возвращаемых значений при возврате. (Остальные значения находятся в последовательных индексах). Используя этот индекс, вы можете получать и изменять эти значения черезlua_getlocalиlua_setlocal. Это поле имеет значение только во время хука вызова, обозначая первый параметр, или хука возврата, обозначая первое возвращаемое значение. (Для хуков вызова это значение всегда равно 1).ntransfer: Количество передаваемых значений (см. предыдущий пункт). (Для вызовов функций Lua это значение всегда равноnparams).
lua_gethook
[-0, +0, –]
lua_Hook lua_gethook (lua_State *L);
Возвращает текущую функцию хука.
lua_gethookcount
[-0, +0, –]
int lua_gethookcount (lua_State *L);
Возвращает текущий счетчик хука.
lua_gethookmask
[-0, +0, –]
int lua_gethookmask (lua_State *L);
Возвращает текущую маску хука.
lua_getinfo
[-(0|1), +(0|1|2), m]
int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
Получает информацию о конкретной функции или вызове функции.
Чтобы получить информацию о вызове функции, параметр ar должен быть действительной записью активации, которая была заполнена предыдущим вызовом lua_getstack или передана в качестве аргумента хуку (см. lua_Hook).
Чтобы получить информацию о функции, вы помещаете ее в стек и начинаете строку what с символа '>'. (В этом случае lua_getinfo извлекает функцию с вершины стека). Например, чтобы узнать, в какой строке была определена функция f, можно написать следующий код:
lua_Debug ar;
lua_getglobal(L, "f"); /* получить глобальную 'f' */
lua_getinfo(L, ">S", &ar);
printf("%d\n", ar.linedefined);
Каждый символ в строке what выбирает некоторые поля структуры ar для заполнения или значение для помещения в стек. (Эти символы также задокументированы в объявлении структуры lua_Debug, в скобках в комментариях после каждого поля).
'f': помещает в стек функцию, которая выполняется на данном уровне;'l': заполняет полеcurrentline;'n': заполняет поляnameиnamewhat;'r': заполняет поляftransferиntransfer;'S': заполняет поляsource,short_src,linedefined,lastlinedefinedиwhat;'t': заполняет поляistailcallиextraargs;'u': заполняет поляnups,nparamsиisvararg;'L': помещает в стек таблицу, индексами которой являются строки в функции с некоторым ассоциированным кодом, то есть строки, в которых можно поставить точку останова. (Строки без кода включают пустые строки и комментарии). Если эта опция дана вместе с опцией'f', ее таблица помещается после функции. Это единственная опция, которая может вызвать ошибку памяти.
Эта функция возвращает 0, чтобы сигнализировать о недопустимой опции в what; даже в этом случае допустимые опции обрабатываются корректно.
lua_getlocal
[-0, +(0|1), –]
const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);
Получает информацию о локальной переменной или временном значении заданной записи активации или заданной функции.
В первом случае параметр ar должен быть действительной записью активации, которая была заполнена предыдущим вызовом lua_getstack или передана в качестве аргумента хуку (см. lua_Hook). Индекс n выбирает, какую локальную переменную инспектировать; подробности об индексах и именах переменных см. в debug.getlocal.
lua_getlocal помещает значение переменной в стек и возвращает ее имя.
Во втором случае ar должен быть NULL, а инспектируемая функция должна находиться на вершине стека. В этом случае видны только параметры функций Lua (поскольку нет информации о том, какие переменные активны), и значения в стек не помещаются.
Возвращает NULL (и ничего не помещает), когда индекс больше количества активных локальных переменных.
lua_getstack
[-0, +0, –]
int lua_getstack (lua_State *L, int level, lua_Debug *ar);
Получает информацию о стеке времени выполнения интерпретатора.
Эта функция заполняет части структуры lua_Debug идентификацией записи активации функции, выполняющейся на заданном уровне. Уровень 0 — это текущая выполняющаяся функция, тогда как уровень n+1 — это функция, которая вызвала уровень n (за исключением хвостовых вызовов, которые не учитываются в стеке). При вызове с уровнем, превышающим глубину стека, lua_getstack возвращает 0; в противном случае возвращает 1.
lua_getupvalue
[-0, +(0|1), –]
const char *lua_getupvalue (lua_State *L, int funcindex, int n);
Получает информацию об n-м upvalue замыкания по индексу funcindex. Помещает значение upvalue в стек и возвращает его имя. Возвращает NULL (и ничего не помещает), когда индекс n больше количества upvalue.
Дополнительную информацию об upvalue см. в debug.getupvalue.
lua_Hook
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
Тип для отладочных функций хука.
Всякий раз, когда вызывается хук, его аргумент ar имеет поле event, установленное в конкретное событие, которое вызвало хук. Lua идентифицирует эти события следующими константами: LUA_HOOKCALL, LUA_HOOKRET, LUA_HOOKTAILCALL, LUA_HOOKLINE и LUA_HOOKCOUNT. Более того, для событий строки также устанавливается поле currentline. Чтобы получить значение любого другого поля в ar, хук должен вызвать lua_getinfo.
Для событий вызова event может быть LUA_HOOKCALL (обычное значение) или LUA_HOOKTAILCALL (для хвостового вызова); в этом случае не будет соответствующего события возврата.
Пока Lua выполняет хук, он отключает другие вызовы хуков. Следовательно, если хук вызывает обратно в Lua для выполнения функции или чанка, это выполнение происходит без каких-либо вызовов хуков.
Функции хуков не могут иметь продолжений, то есть они не могут вызывать lua_yieldk, lua_pcallk или lua_callk с не-null k.
Функции хуков могут выполнять yield при следующих условиях: Только события счетчика и строки могут выполнять yield; чтобы выполнить yield, функция хука должна завершить свое выполнение вызовом lua_yield с nresults, равным нулю (то есть без значений).
lua_sethook
[-0, +0, –]
void lua_sethook (lua_State *L, lua_Hook f, int mask, int count);
Устанавливает отладочную функцию хука.
Аргумент f — функция хука. mask указывает, на каких событиях будет вызываться хук: она формируется побитовым ИЛИ констант LUA_MASKCALL, LUA_MASKRET, LUA_MASKLINE и LUA_MASKCOUNT. Аргумент count имеет значение только тогда, когда маска включает LUA_MASKCOUNT. Для каждого события хук вызывается, как описано ниже:
- Хук вызова: вызывается, когда интерпретатор вызывает функцию. Хук вызывается сразу после того, как Lua входит в новую функцию.
- Хук возврата: вызывается, когда интерпретатор возвращается из функции. Хук вызывается непосредственно перед тем, как Lua покидает функцию.
- Хук строки: вызывается, когда интерпретатор собирается начать выполнение новой строки кода или когда он перепрыгивает назад в коде (даже на ту же строку). Это событие происходит только во время выполнения Lua функции Lua.
- Хук счетчика: вызывается после того, как интерпретатор выполняет каждые
countинструкций. Это событие происходит только во время выполнения Lua функции Lua.
Хуки отключаются установкой mask в ноль.
lua_setlocal
[-(0|1), +0, –]
const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
Устанавливает значение локальной переменной заданной записи активации. Присваивает значение на вершине стека переменной и возвращает ее имя. Также извлекает значение из стека.
Возвращает NULL (и ничего не извлекает), когда индекс больше количества активных локальных переменных.
Параметры ar и n такие же, как в функции lua_getlocal.
lua_setupvalue
[-(0|1), +0, –]
const char *lua_setupvalue (lua_State *L, int funcindex, int n);
Устанавливает значение upvalue замыкания. Присваивает значение на вершине стека upvalue и возвращает его имя. Также извлекает значение из стека.
Возвращает NULL (и ничего не извлекает), когда индекс n больше количества upvalue.
Параметры funcindex и n такие же, как в функции lua_getupvalue.
lua_upvalueid
[-0, +0, –]
void *lua_upvalueid (lua_State *L, int funcindex, int n);
Возвращает уникальный идентификатор для upvalue с номером n из замыкания по индексу funcindex.
Эти уникальные идентификаторы позволяют программе проверять, разделяют ли разные замыкания upvalue. Замыкания Lua, которые разделяют upvalue (то есть обращаются к одной и той же внешней локальной переменной), будут возвращать идентичные идентификаторы для этих индексов upvalue.
Параметры funcindex и n такие же, как в функции lua_getupvalue, но n не может быть больше количества upvalue.
lua_upvaluejoin
[-0, +0, –]
void lua_upvaluejoin (lua_State *L, int funcindex1, int n1,
int funcindex2, int n2);
Делает так, чтобы n1-е upvalue замыкания Lua по индексу funcindex1 ссылалось на n2-е upvalue замыкания Lua по индексу funcindex2.