4 – Интерфейс прикладного программирования
В этом разделе описывается C API для Lua, то есть
набор C функций, доступных хост-программе для взаимодействия
с Lua.
Все функции API, а также связанные с ними типы и константы
объявлены в заголовочном файле lua.h.
Даже когда мы используем термин «функция», любая возможность в API может быть предоставлена вместо этого в виде макроса. Если не указано иное, все такие макросы используют каждый свой аргумент ровно один раз (кроме первого аргумента, который всегда является состоянием Lua), и поэтому не создают скрытых побочных эффектов.
Как и в большинстве C библиотек,
функции Lua API не проверяют свои аргументы
на допустимость или согласованность.
Однако это поведение можно изменить, скомпилировав Lua
с определённым макросом LUA_USE_APICHECK.
Библиотека Lua является полностью реентерабельной: у неё нет глобальных переменных. Всю необходимую информацию она хранит в динамической структуре, называемой состоянием Lua.
Каждое состояние Lua имеет один или несколько потоков,
которые соответствуют независимым кооперативным линиям исполнения.
Тип 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 – Размер стека
При взаимодействии с API Lua вы отвечаете за обеспечение согласованности. В частности, вы отвечаете за контроль переполнения стека. При вызове любой функции API вы должны убедиться, что в стеке достаточно места для размещения результатов.
Из вышеуказанного правила есть одно исключение:
когда вы вызываете функцию Lua
без фиксированного числа результатов (см. lua_call),
Lua гарантирует, что в стеке достаточно места для всех результатов.
Однако Lua не гарантирует дополнительного места.
Поэтому перед тем, как поместить что-либо в стек после такого вызова,
следует использовать lua_checkstack.
Всякий раз, когда Lua вызывает C,
гарантируется, что в стеке есть место
как минимум для LUA_MINSTACK дополнительных элементов;
то есть вы можете безопасно поместить в него до LUA_MINSTACK значений.
LUA_MINSTACK определён как 20,
поэтому обычно вам не нужно беспокоиться о месте в стеке,
если только в вашем коде нет циклов, помещающих элементы в стек.
При необходимости
вы можете использовать функцию lua_checkstack,
чтобы убедиться, что в стеке достаточно места для добавления новых элементов.
4.1.2 – Допустимые и приемлемые индексы
Любая функция в API, которая получает индексы стека, работает только с допустимыми индексами или приемлемыми индексами.
Допустимый индекс — это индекс, который ссылается на
позицию, хранящую изменяемое значение 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 имеют параметры,
являющиеся указателями на C-строки (const char*).
Некоторые из этих параметров имеют связанную длину (size_t).
Если не указано иное,
при наличии связанной длины
строка может содержать встроенные нули;
кроме того, указатель может быть NULL, если длина равна нулю.
Если связанной длины нет,
указатель должен указывать на строку, завершающуюся нулём.
В любом случае содержимое строки должно оставаться неизменным
до возврата функции.
Несколько функций в 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-замыкание
(см. lua_pushcclosure);
эти значения называются upvalue (внешними значениями) и
доступны функции при каждом её вызове.
При каждом вызове C-функции
её upvalue располагаются по определённым псевдоиндексам.
Эти псевдоиндексы порождаются макросом
lua_upvalueindex.
Первое upvalue, связанное с функцией, находится по индексу
lua_upvalueindex(1), и так далее.
Любое обращение к lua_upvalueindex(n),
где n больше числа upvalue текущей функции
(но не больше 256,
что на единицу превышает максимальное число upvalue в замыкании),
порождает допустимый, но недействительный индекс.
C-замыкание также может изменять значения соответствующих ему upvalue.
4.3 – Реестр
Lua предоставляет реестр —
предопределённую таблицу, которую любой C -код может использовать для
хранения любых нужных ему значений Lua.
Таблица реестра всегда доступна по псевдоиндексу
LUA_REGISTRYINDEX.
Любая C -библиотека может хранить данные в этой таблице,
но она должна позаботиться о выборе ключей,
отличных от используемых другими библиотеками, чтобы избежать коллизий.
Как правило, в качестве ключа следует использовать строку с именем вашей библиотеки,
либо light userdata с адресом C -объекта в вашем коде,
либо любой объект Lua, созданный вашим кодом.
Как и в случае имён переменных,
строковые ключи, начинающиеся с подчёркивания, за которым следуют
заглавные буквы, зарезервированы для Lua.
Целочисленные ключи в реестре используются
механизмом ссылок (см. luaL_ref),
с некоторыми предопределёнными значениями.
Поэтому целочисленные ключи в реестре
не должны использоваться для других целей.
При создании нового состояния Lua
его реестр содержит некоторые предопределённые значения.
Эти предопределённые значения индексируются целочисленными ключами,
определёнными как константы в lua.h.
Определены следующие константы:
LUA_RIDX_MAINTHREAD: По этому индексу в реестре находится главный поток состояния. (Главный поток — это тот, который создаётся вместе с состоянием.)LUA_RIDX_GLOBALS: По этому индексу в реестре находится глобальное окружение.
4.4 – Обработка ошибок в C
Внутри Lua использует механизм longjmp языка C для обработки ошибок.
(Lua будет использовать исключения, если скомпилировать её как C++;
подробности ищите LUAI_THROW в исходном коде.)
Когда Lua сталкивается с любой ошибкой,
например с ошибкой выделения памяти или ошибкой типа,
она возбуждает ошибку;
то есть выполняет длинный переход.
Защищённое окружение использует setjmp
для установки точки восстановления;
любая ошибка приводит к переходу к самой последней активной точке восстановления.
Внутри функции на C можно явно возбудить ошибку,
вызвав lua_error.
Большинство функций API могут возбуждать ошибку, например из-за ошибки выделения памяти. Документация для каждой функции указывает, может ли она возбуждать ошибки.
Если ошибка происходит вне любого защищённого окружения,
Lua вызывает panic-функцию (см. lua_atpanic)
и затем вызывает abort,
завершая таким образом приложение-хост.
Ваша panic-функция может избежать этого завершения,
если никогда не будет возвращать управление
(например, выполнив длинный переход к собственной точке восстановления вне Lua).
Panic-функция,
как следует из её названия,
является механизмом последней инстанции.
Программы должны избегать её.
Как правило,
когда функция на C вызывается из Lua с состоянием Lua,
она может делать с этим состоянием Lua всё, что угодно,
поскольку оно уже должно быть защищено.
Однако,
когда код на C работает с другими состояниями Lua
(например, с аргументом-состоянием Lua, переданным функции,
с состоянием Lua, хранящимся в реестре, или
с результатом lua_newthread),
он должен использовать их только в вызовах API, которые не могут возбуждать ошибки.
Panic-функция выполняется так, как если бы она была обработчиком сообщений (см. §2.3); в частности, объект ошибки находится на вершине стека. Однако нет никаких гарантий насчёт пространства стека. Чтобы что-либо поместить в стек, panic-функция должна сначала проверить доступное пространство (см. §4.1.1).
4.4.1 – Коды состояния
Некоторые функции API, сообщающие об ошибках, используют следующие коды состояния для указания различных видов ошибок или других условий:
LUA_OK(0): нет ошибок.LUA_ERRRUN: ошибка времени выполнения.LUA_ERRMEM: ошибка выделения памяти. Для таких ошибок Lua не вызывает обработчик сообщений.LUA_ERRERR: переполнение стека при выполнении обработчика сообщений из-за другого переполнения стека. Чаще всего эта ошибка является результатом какой-либо другой ошибки при выполнении обработчика сообщений. Ошибка в обработчике сообщений вызовет обработчик снова, который снова сгенерирует ошибку, и так далее, пока этот цикл не исчерпает стек и не вызовет эту ошибку.LUA_ERRSYNTAX: синтаксическая ошибка во время предкомпиляции или ошибка формата в двоичном фрагменте.LUA_YIELD: поток (корутина) уступает управление.LUA_ERRFILE: ошибка, связанная с файлом; например, невозможно открыть или прочитать файл.
Эти константы определены в заголовочном файле lua.h.
4.5 – Обработка yield в C
Внутри Lua использует средство C longjmp для передачи управления из корутины.
Поэтому, если C-функция foo вызывает функцию API
и эта функция API передаёт управление
(напрямую или косвенно, вызывая другую функцию, которая передаёт управление),
Lua больше не может вернуться в foo,
потому что longjmp удаляет её кадр из стека C.
Чтобы избежать такого рода проблем,
Lua возбуждает ошибку всякий раз, когда пытается передать управление через вызов API,
за исключением трёх функций:
lua_yieldk, lua_callk и lua_pcallk.
Все эти функции получают функцию продолжения
(как параметр с именем k), чтобы продолжить выполнение после передачи управления.
Нам нужно определить некоторые термины, чтобы объяснить функции продолжения.
У нас есть C-функция, вызываемая из Lua, которую мы будем называть
исходной функцией.
Эта исходная функция затем вызывает одну из тех трёх функций в C API,
которую мы будем называть вызываемой функцией,
а та затем передаёт управление текущего потока.
Это может произойти, когда вызываемая функция — это lua_yieldk,
или когда вызываемая функция — это lua_callk или lua_pcallk,
и вызываемая ими функция передаёт управление.
Предположим, что выполняющийся поток передаёт управление во время выполнения вызываемой функции. После возобновления потока он в конечном итоге завершит выполнение вызываемой функции. Однако вызываемая функция не может вернуться в исходную функцию, потому что её кадр в стеке C был уничтожен при передаче управления. Вместо этого Lua вызывает функцию продолжения, которая была передана в качестве аргумента вызываемой функции. Как следует из названия, функция продолжения должна продолжить задачу исходной функции.
Для иллюстрации рассмотрим следующую функцию:
int original_function (lua_State *L) {
... /* code 1 */
status = lua_pcall(L, n, m, h); /* calls Lua */
... /* code 2 */
}
Теперь мы хотим разрешить
Lua-коду, выполняемому через lua_pcall, передавать управление.
Сначала мы можем переписать нашу функцию так:
int k (lua_State *L, int status, lua_KContext ctx) {
... /* code 2 */
}
int original_function (lua_State *L) {
... /* code 1 */
return k(L, lua_pcall(L, n, m, h), ctx);
}
В приведённом выше коде
новая функция k является
функцией продолжения (с типом lua_KFunction),
которая должна выполнять всю работу, которую исходная функция
выполняла после вызова lua_pcall.
Теперь мы должны сообщить Lua, что она должна вызвать k, если Lua-код,
выполняемый через lua_pcall, будет прерван каким-либо образом
(ошибки или передача управления),
поэтому мы перепишем код так, как здесь,
заменив lua_pcall на lua_pcallk:
int original_function (lua_State *L) {
... /* code 1 */
return k(L, lua_pcallk(L, n, m, h, ctx2, k), ctx1);
}
Обратите внимание на внешний, явный вызов функции продолжения:
Lua вызовет функцию продолжения только при необходимости, то есть
в случае ошибок или возобновления после передачи управления.
Если вызываемая функция возвращает управление нормально, ни разу не передав управление,
lua_pcallk (и lua_callk) также вернёт управление нормально.
(Конечно, вместо вызова функции продолжения в этом случае
вы можете выполнить эквивалентную работу непосредственно внутри исходной функции.)
Помимо состояния Lua,
функция продолжения имеет два других параметра:
итоговый статус вызова и значение контекста (ctx), которое
изначально было передано в lua_pcallk.
Lua не использует это значение контекста;
она только передаёт это значение из исходной функции в
функцию продолжения.
Для lua_pcallk
статус — это то же значение, которое было бы возвращено lua_pcallk,
за исключением того, что это LUA_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; /* not used */
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: выполняет побитовое NOT (~)LUA_OPBAND: выполняет побитовое AND (&)LUA_OPBOR: выполняет побитовое OR (|)LUA_OPBXOR: выполняет побитовое исключающее OR (~)LUA_OPSHL: выполняет сдвиг влево (<<)LUA_OPSHR: выполняет сдвиг вправо (>>)
lua_atpanic
[-0, +0, –]
lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);
Устанавливает новую panic-функцию и возвращает старую (см. §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"); /* function to be called */
lua_pushliteral(L, "how"); /* 1st argument */
lua_getglobal(L, "t"); /* table to be indexed */
lua_getfield(L, -1, "x"); /* push result of t.x (2nd arg) */
lua_remove(L, -2); /* remove 't' from the stack */
lua_pushinteger(L, 14); /* 3rd argument */
lua_call(L, 3, 1); /* call 'f' with 3 arguments and 1 result */
lua_setglobal(L, "a"); /* set global '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,
но позволяет вызываемой функции приостановиться (см. §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); /* number of arguments */
lua_Number sum = 0.0;
int i;
for (i = 1; i <= n; i++) {
if (!lua_isnumber(L, i)) {
lua_pushliteral(L, "incorrect argument");
lua_error(L);
}
sum += lua_tonumber(L, i);
}
lua_pushnumber(L, sum/n); /* first result */
lua_pushnumber(L, sum); /* second result */
return 2; /* number of results */
}
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);
Закрывает все активные переменные, подлежащие закрытию, в главном потоке, освобождает все объекты в заданном состоянии Lua (вызывая соответствующие метаметоды сборки мусора, если они есть) и освобождает всю динамическую память, используемую этим состоянием.
На нескольких платформах вам может не понадобиться вызывать эту функцию, так как все ресурсы естественно освобождаются при завершении принимающей программы. С другой стороны, долго работающие программы, которые создают несколько состояний, например демоны или веб-серверы, вероятно, должны закрывать состояния, как только они перестают быть нужны.
lua_closeslot
[-0, +0, e]
void lua_closeslot (lua_State *L, int index);
Закрывает слот, подлежащий закрытию, по заданному индексу и устанавливает его значение в nil.
Индекс должен быть последним ранее помеченным для закрытия
(см. lua_toclose) и всё ещё активным (то есть ещё не закрытым).
Метаметод __close не может приостановить выполнение
при вызове через эту функцию.
lua_closethread
[-0, +?, –]
int lua_closethread (lua_State *L, lua_State *from);
Сбрасывает поток, очищая его стек вызовов и закрывая все ожидающие
переменные, подлежащие закрытию.
Параметр from представляет корутину, которая сбрасывает L.
Если такой корутины нет,
этот параметр может быть NULL.
Если L не равен from,
вызов возвращает код состояния:
LUA_OK при отсутствии ошибок в потоке
(либо исходной ошибки, остановившей поток, либо
ошибок в методах закрытия),
или статус ошибки в противном случае.
В случае ошибки
объект ошибки помещается на вершину стека.
Если L равен from,
это соответствует закрытию потока самим собой.
В этом случае
вызов не возвращает управление;
вместо этого возвращается вызов возобновления, который (повторно) запустил поток.
Поток должен выполняться внутри вызова возобновления.
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 равен true,
двоичное представление может не включать всю отладочную информацию
о функции,
чтобы сэкономить место.
Возвращаемое значение — код ошибки, возвращённый последним вызовом функции записи; 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-е пользовательское значение, связанное с
полным 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, если значение по заданному индексу является light 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 (полным или light), и 0 в противном случае.
lua_isyieldable
[-0, +0, –]
int lua_isyieldable (lua_State *L);
Возвращает 1, если заданная корутина может приостановиться, и 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',
что означает фиксированный буфер с двоичным дампом.
Фиксированный буфер означает, что адрес, возвращённый функцией чтения,
будет содержать блок до тех пор, пока всё, что создано блоком, не
будет собрано сборщиком мусора;
поэтому 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.
Блок памяти должным образом выровнен для любого объекта ISO C.
(См. макрос LUAI_MAXALIGN в файле luaconf.h для других
требований к выравниванию.)
Функция возвращает адрес блока памяти. 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 и ничего не помещает.
Типичный обход таблицы выглядит так:
/* table is in the stack at index 't' */
lua_pushnil(L); /* first key */
while (lua_next(L, t) != 0) {
/* uses 'key' (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)));
/* removes 'value'; keeps 'key' for next iteration */
lua_pop(L, 1);
}
При обходе таблицы
избегайте прямого вызова lua_tolstring для ключа,
если вы не знаете, что ключ на самом деле является строкой.
Напомним, что lua_tolstring может изменить
значение по заданному индексу;
это запутает следующий вызов lua_next.
Эта функция может вызвать ошибку, если заданный ключ не является nil и отсутствует в таблице.
Дополнительные сведения об обходе см. в функции next.
lua_Number
typedef ... lua_Number;
Тип чисел с плавающей точкой в Lua.
По умолчанию этот тип — double,
но его можно изменить на single 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,
за исключением того, что она позволяет вызываемой функции приостановиться (см. §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 равен нулю,
эта функция создаёт light C-функцию,
которая является просто указателем на 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);
Создаёт внешнюю строку,
то есть строку, использующую память, не управляемую 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);
Помещает light userdata в стек.
Userdata представляют C-значения в Lua.
Light userdata представляет указатель, void*.
Это значение (как число):
вы его не создаёте, у него нет индивидуальной метатаблицы,
и он не собирается сборщиком мусора (так как никогда не создавался).
Light userdata равен «любому»
light 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, но выполняет raw-доступ
(то есть без метаметодов).
Значение по индексу index должно быть таблицей.
lua_rawgeti
[-0, +1, –]
int lua_rawgeti (lua_State *L, int index, lua_Integer n);
Помещает в стек значение t[n],
где t — таблица по заданному индексу.
Доступ является raw,
то есть не использует метазначение __index.
Возвращает тип помещённого значения.
lua_rawgetp
[-0, +1, –]
int lua_rawgetp (lua_State *L, int index, const void *p);
Помещает в стек значение t[k],
где t — таблица по заданному индексу, а
k — указатель p, представленный как light userdata.
Доступ является raw;
то есть не использует метазначение __index.
Возвращает тип помещённого значения.
lua_rawlen
[-0, +0, –]
lua_Unsigned lua_rawlen (lua_State *L, int index);
Возвращает raw-«длину» значения по заданному индексу:
для строк это длина строки;
для таблиц это результат оператора длины ('#')
без метаметодов;
для userdata это размер блока памяти, выделенного
для userdata.
Для других значений вызов возвращает 0.
lua_rawset
[-2, +0, m]
void lua_rawset (lua_State *L, int index);
Аналогична lua_settable, но выполняет raw-присваивание
(то есть без метаметодов).
Значение по индексу index должно быть таблицей.
lua_rawseti
[-1, +0, m]
void lua_rawseti (lua_State *L, int index, lua_Integer i);
Выполняет эквивалент t[i] = v,
где t — таблица по заданному индексу,
а v — значение на вершине стека.
Эта функция снимает значение со стека.
Присваивание является raw,
то есть не использует метазначение __newindex.
lua_rawsetp
[-1, +0, m]
void lua_rawsetp (lua_State *L, int index, const void *p);
Выполняет эквивалент t[p] = v,
где t — таблица по заданному индексу,
p кодируется как light userdata,
а v — значение на вершине стека.
Эта функция снимает значение со стека.
Присваивание является raw,
то есть не использует метазначение __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, если корутина приостанавливается,
LUA_OK, если корутина завершает выполнение
без ошибок,
или код ошибки в случае ошибок (см. §4.4.1).
В случае ошибок
объект ошибки помещается на вершину стека.
(В этом случае nresults не обновляется,
так как для единственного объекта ошибки его значение должно было бы быть 1.)
Чтобы возобновить приостановленную корутину,
снимите *nresults переданных значений с её стека,
поместите значения, которые должны быть переданы как результаты из 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, то все элементы стека удаляются.
Эта функция может выполнять произвольный код при удалении из стека индекса, помеченного как подлежащий закрытию.
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, +(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);
Помечает заданный индекс в стеке как
слот, подлежащий закрытию (см. §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,
возвращает адрес его блока памяти.
Если значение является light 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 должно быть
продолжено в другом вызове этой функции.
Дополнительные сведения о предупреждениях см. в 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);
Приостанавливает корутину (поток).
Когда C-функция вызывает lua_yieldk,
выполняющаяся корутина приостанавливает выполнение,
и вызов lua_resume, запустивший эту корутину, возвращает управление.
Параметр nresults — это число значений из стека,
которые будут переданы как результаты в lua_resume.
Когда корутина снова возобновляется,
Lua вызывает заданную функцию продолжения k, чтобы продолжить
выполнение C-функции, которая приостановилась (см. §4.5).
Эта функция продолжения получает тот же стек
от предыдущей функции,
из которого все результаты (nresults) удалены и
заменены аргументами, переданными в lua_resume.
Кроме того,
функция продолжения получает значение ctx,
которое было передано в lua_yieldk.
Обычно эта функция не возвращает управление;
когда корутина в конце концов возобновляется,
она продолжает выполнять функцию продолжения.
Однако есть один особый случай,
когда эта функция вызывается
изнутри хука строки или хука счётчика (см. §4.7).
В этом случае lua_yieldk следует вызывать без продолжения
(вероятно, в форме lua_yield) и без результатов,
а хук должен немедленно вернуться после вызова.
Lua приостановится и,
когда корутина снова возобновится,
продолжит нормальное выполнение
(функции Lua), инициировавшей хук.
Эта функция может вызвать ошибку, если она вызвана из потока с ожидающим C-вызовом без функции продолжения (так называемая граница C-вызова), или если она вызвана из потока, который не выполняется внутри возобновления (обычно главный поток).
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) number of upvalues */
unsigned char nparams; /* (u) number of parameters */
char isvararg; /* (u) */
unsigned char extraargs; /* (t) number of extra arguments */
char istailcall; /* (t) */
int ftransfer; /* (r) index of first value transferred */
int ntransfer; /* (r) number of transferred values */
char short_src[LUA_IDSIZE]; /* (S) */
/* private part */
other fields
} 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: истинно, если этот вызов функции был выполнен хвостовым вызовом. В этом случае вызывающая функция этого уровня отсутствует в стеке.extraargs: Количество дополнительных аргументов, добавленных вызовом функций, вызываемых через метаметоды__call. (Каждое метазначение__callдобавляет один дополнительный аргумент — вызываемый объект, но может быть цепочка метазначений__call.)nups: количество внешних переменных функции.nparams: количество параметров функции (всегда 0 для C функций).isvararg: истинно, если функция является функцией с переменным числом аргументов (всегда истинно для 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"); /* get global '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,srclen,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-й внешней переменной
замыкания по индексу funcindex.
Она помещает значение внешней переменной в стек
и возвращает её имя.
Возвращает NULL (и ничего не помещает в стек),
когда индекс n больше количества внешних переменных.
Дополнительные сведения о внешних переменных см. в 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 с ненулевым k.
Функции-хуки могут уступать управление при следующих условиях:
Только события счётчика и строки могут уступать управление;
чтобы уступить управление, функция-хук должна завершить своё выполнение,
вызвав 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,
за исключением того, что ar не может быть NULL,
так как lua_setlocal работает только с записями активации.
lua_setupvalue
[-(0|1), +0, –]
const char *lua_setupvalue (lua_State *L, int funcindex, int n);
Устанавливает значение внешней переменной замыкания. Она присваивает внешней переменной значение на вершине стека и возвращает её имя. Она также извлекает значение из стека.
Возвращает NULL (и ничего не извлекает),
когда индекс n больше количества внешних переменных.
Параметры funcindex и n такие же, как в
функции lua_getupvalue.
lua_upvalueid
[-0, +0, –]
void *lua_upvalueid (lua_State *L, int funcindex, int n);
Возвращает уникальный идентификатор для внешней переменной с номером n
из замыкания по индексу funcindex.
Эти уникальные идентификаторы позволяют программе проверять, разделяют ли разные замыкания внешние переменные. Замыкания Lua, которые совместно используют внешнюю переменную (то есть обращаются к одной и той же внешней локальной переменной), будут возвращать одинаковые идентификаторы для этих индексов внешних переменных.
Параметры funcindex и n такие же, как в
функции lua_getupvalue,
но n не может быть больше количества внешних переменных.
lua_upvaluejoin
[-0, +0, –]
void lua_upvaluejoin (lua_State *L, int funcindex1, int n1,
int funcindex2, int n2);
Заставляет n1-ю внешнюю переменную замыкания Lua по индексу funcindex1
ссылаться на n2-ю внешнюю переменную замыкания Lua по индексу funcindex2.