4 – Интерфейс прикладного программирования (API)
Эта глава описывает C-ишный API для Lua, то есть, набор функций на языке C, доступных хост-программе для взаимодействия с Lua.
Все функции API и связанные с ним типы и константы объявлены в заголовочном файле lua.h.
Даже когда мы используем термин "функция", взамен любая возможность в API может быть представлена как макрос.
За исключением случаев, когда указано иное, все такие макросы используют каждый из своих аргументов только один раз (за исключением первого аргумента,
которым всегда является Lua состояние), и поэтому не создают никаких скрытых побочных эффектов.
Как в большинстве C-ишных библиотек, функции API Lua не проверяют свои аргументы на правильность или согласованность.
Однако, это поведение можно изменить компилированием Lua с макросом, определенным в LUA_USE_APICHECK.
Для передачи значений в С и обратно Lua использует виртуальный стек. Каждый элемент в этом стеке представляет Lua значение (nil, число, строка, и т.д.).
Всякий раз когда Lua вызывает C, вызываемая функция получает новый стек, который независим от предыдущего стека и стеков С-ишных функций, которые по-прежнему активны.
Этот стек изначально содержит любые аргументы к С-ишной функции и это то место, куда C-ишная функция помещает свои результаты для возвращения их вызывающей функции (смотрите lua_CFunction).
Для удобства, большинство запрашиваемых операций в API не придерживаются строгим правилам работы стека (последний вошел – первый вышел). Вместо этого, они могут обратиться к любому элементу в стеке, используя индекс:
положительный индекс представляет абсолютную позицию стека (счет начинается с 1); отрицательный индекс представляет смещение относительно вершины стека.
Более конкретно, если стек имеет n элементов, то индекс 1 представляет первый элемент (то есть, элемент который был первым помещен в стек), а индекс n представляет последний элемент;
индекс -1 также представляет последний элемент (то есть, элемент на вершине стека), а индекс -n представляет первый элемент.
При взаимодействии с API Lua, вы отвечаете за обеспечение совместимости. В частности, вы ответственны за управление переполнением стека.
Чтобы убедиться в том, что стек имеет достаточно места для помещения в него новых элементов, можно использовать функцию lua_checkstack.
Всякий раз, когда Lua вызывает C, он гарантирует, что стек имеет по меньшей мере LUA_MINSTACK дополнительных слотов.
LUA_MINSTACK определен как 20, так что обычно не приходится беспокоиться о местах в стеке, если код не имеет циклов размещения элементов в стеке.
При вызове функции Lua с изменяемым числом результатов (смотрите lua_call), Lua гарантирует что стек имеет достаточно места для всех результатов, но не обеспечивает никакого дополнительного пространства.
Так что, перед помещением чего-либо в стек после подобного вызова, следует использовать lua_checkstack.
Любая функция в API, которая получает индексы стека, работает только с действительными (valid) индексами или допустимыми (acceptable) индексами.
Действительный индекс - это индекс, который ссылается на позицию, где хранится изменяемое Lua значение.
Сюда включаются индексы стека между 1 и вершиной стека (1 ≤ abs(index) ≤ top) плюс псевдоиндексы, которые представляют некоторые позиции, что доступны в C коде, но отсутствуют в стеке.
Псевдоиндексы используются для доступа к реестру (смотрите §4.5) и внешним локальным переменным (upvalue) C-ишных функций (смотрите §4.4).
Функции, которым не требуется определенное изменяемое положение, а только значение (например, функции запроса), могут вызываться с допустимыми индексами.
Допустимым индексом может быть любой действительный индекс, но это также может быть любой положительный индекс после вершины стека, внутри пространства, выделенного под стек, то есть, индексы до размера стека.
(Обратите внимание что 0 никогда не являлся допустимым индексом.) За исключением случаев, когда указаано иное, функции в API работают с допустимыми индексами.
Допустимые индексы служат для того, чтобы избежать дополнительных проверок вершины стека при запросах стека.
Например, C функция может запросить свой третий аргумент без необходимости начальной проверки, существует ли третий аргумент, то есть, без необходимости проверки, является ли 3 действительным индексом.
Для функций, которые могут быть вызваны с допустимыми индексами, любой недействительный индекс рассматривается как если бы он содержит значение виртуального типа LUA_TNONE, которое ведет себя как значение nil.
При создании C функции имеется возможность связать с ней некие значения, таким образом создается C замыкание (closure) (смотрите lua_pushcclosure);
эти значения называются внешними локальными переменными (upvalue) и они доступны для функции всякий раз при её вызове.
Всякий раз при вызове C функции, эти upvalue-переменные размещаются под определенными псевдоиндексами. Эти псевдоиндексы производятся макросом lua_upvalueindex.
Первая upvalue, связанная с функцией, получает индекс lua_upvalueindex(1), и так далее.
Любое обращение к lua_upvalueindex(n), где n является числом большим числа upvalue текущей функции (но не более чем 256), выдает допустимый, но недействительный индекс.
Lua предоставляет реестр, предопределенную таблицу, которая может быть использована любым C кодом для сохранения любых Lua-значений, что требуется сохранить.
Эта "реестровая" таблица всегда находится по псевдоиндексу LUA_REGISTRYINDEX.
Любая C-ишная библиотека может хранить данные в этой таблице, но нужно озаботиться выбором ключей, которые должны отличаться от используемых другими библиотеками, во избежание противоречий.
Как правило, следует использовать в качестве ключа строку, содержащую имя (название) библиотеки или легкие userdata с адресом C объекта в коде, или любой Lua-объект, созданный кодом.
Как и с именами переменных, строковые ключи, начинающиеся с символа подчеркивания и последующими буквами верхнего регистра зарезервированы за Lua.
Целочисленные ключи в реестре используются ссылочным механизмом (смотрите luaL_ref) и некоторыми предопределенными значениями.
Поэтому целочисленные ключи не должны использоваться для других целей.
При создании нового состояния Lua, его реестр поставляется с некоторыми предопределенными значениями.
Эти предварительно заданные значения, индексированные целочисленными ключами, в lua.h определяются как константы. Установлены следующие константы:
- LUA_RIDX_MAINTHREAD: По этому индексу реестра находится основная нить состояния. (Основная нить - это та, что создается вместе с состоянием.)
- LUA_RIDX_GLOBALS: По этому индексу реестра находится глобальное окружение (среда).
Внутри себя, Lua использует возможности C-ишного longjmp для обработки ошибок.
(Если это компилируется на C++, Lua будет использовать исключения; для дополнительной информации поищите в исходном коде LUAI_THROW.)
Когда Lua сталкивается с любой ошибкой (такой, как например ошибка выделения памяти, ошибки в определении типа, синтаксические ошибки и ошибки во время выполнения) он выдает ошибку; то есть, делает длинный переход (long jump).
Защищенная среда использует setjmp для установки точки восстановления; любая ошибка приводит к переходу на самую последнюю активную точку восстановления.
Если ошибка происходит снаружи любой защищенной среды, Lua вызывает "тревожную" функцию (смотрите lua_atpanic) и затем вызывает abort - прерывание, таким образом выходя из хост-приложения.
Наша тревожная функция может избежать такого выхода никогда не возвращаясь (например, делая длинный переход на свою собственную точку восстановления снаружи Lua).
Тревожная функция работает так, как если бы она была обработчиком ошибки (смотрите §2.3); в частности, сообщение об ошибке находится на вершине стека.
Однако, нет никаких гарантий о пространстве стека. Чтобы поместить что-либо в стек, тревожная функция сначала должна проверить доступное пространство (смотрите §4.2).
Большинство функций в API могут вызывать ошибку, например из-за ошибки выделения памяти. Документация по каждой функции показывает может ли она вызывать ошибки.
Внутри C функции можно вызвать ошибку вызовом функции lua_error.
Внутри себя, Lua использует возможность C-ишного longjmp для выхода (приостановки выполнения) из сопрограммы.
Поэтому, если C-ишная функция foo вызывает функцию API и эта функция API приостанавливает выполнение (непосредственно сама или косвенно вызывая другую функцию, которая делает выход), Lua не может ничего больше возвратить в foo,
потому что longjmp удалил его из C-ишного стека.
Во избежание проблем такого рода, Lua выдает ошибку всякий раз при попытке выхода через вызов API, за исключением трех функций: lua_yieldk, lua_callk, и lua_pcallk.
Все эти функции принимают функцию-продолжение (в качестве параметра с именем k) чтобы продолжить выполнение после выхода.
Чтобы объяснить продолжения, следует установить некоторую терминологию.
У нас есть функция C вызываемая из Lua, которую мы будем называть исходной функцией.
Эта исходная функция затем вызывает одну из этих трех функций в С-ишном API, которая будет называться вызываемой функцией, которая затем приостанавливает выполнение текущей нити (потока).
(Это может произойти, когда вызываемой функцией является lua_yieldk, или, когда вызываемая функция - либо lua_callk, либо lua_pcallk, а функция, вызванная ими, приостанавливает выполнение.)
Предположим, что работающая нить приостанавливается на время выполнения вызываемой функции. После возобновления работы нити, она, в конечном счете, завершит работу вызываемой функции.
Однако, вызываемая функция не может возвратиться к исходной функции, так как её фрейм в С-ишном стеке был разрушен приостановкой выполнения нити.
Вместо этого, Lua вызывает функцию продолжения (continuation function), которая будет задана в качестве аргумента вызываемой функции. Как следует из названия, функция продолжения должна продолжить задачу исходной функции.
В качестве иллюстрации, рассмотрим следующую функцию:
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 вызывает продолжение, для lua_yieldk и lua_callk, состоянием всегда будет LUA_YIELD.
(Для этих двух функций, Lua не будет вызывать продолжения в случае ошибок, так как они не обрабатывают ошибки.)
Точно также, при использовании lua_callk, следует вызывать функцию продолжения с LUA_OK в качестве состояния.
(Для lua_yieldk, в прямом вызове функции продолжения нет особого смысла, поскольку lua_yieldk обычно ничего не возвращает.)
Lua рассматривает функцию продолжения как если бы она была исходной функцией.
Функция продолжения принимает тот же самый Lua стек от исходной функции, в том же самом состоянии, как если бы он был возвращен вызываемой функцией.
(Например, после lua_callk функция и её аргументы удаляются из стека и заменяются результатами из вызова.)
Она также имеет те же самые внешние локальные переменные. Все что она возвращает, обрабатывается Lua как если бы это было возвращено исходной функцией.
Здесь находится список всех функций и типов из C-ишного API в алфавитном порядке.
[-o, +p, x]
Каждая функция имеет индикатор, подобный вот такому:
Первое поле, o, показывает как много элементов функция берет из стека.
Второе поле, p, показывает сколько элементов функция помещает в стек.
(Любая функция всегда помещает в стек свои результаты после получения из стека своих аргументов.)
Поле в виде x|y означает что функция может поместить в стек (или взять из стека) x или y элементов, в зависимости от ситуации;
вопросительный знак '?' означает, что нельзя узнать количество элементов, которые функция принимает из стека или перемещает в стек, глядя только на свои аргументы (например, это может зависеть от того, что находится в стеке).
Третье поле, x, показывает может ли функция выдавать ошибки:
'-' означает, что функция никогда не выдает никакой ошибки;
'e' означает, что функция может выдавать ошибки;
'v' показывает, что функция может выдавать ошибку специально (целенаправленно).
[-0, +0, –]
int lua_absindex (lua_State *L, int idx);
Конвертирует допустимый (acceptable) индекс idx в эквивалентный ему абсолютный индекс (то есть, тот, что не зависит от вершины стека).
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 только в том случае, если он не может выполнить запрос.
Lua предполагает, что распределитель никогда не дает сбоев при osize >= nsize.
Вот простая реализация функции распределителя. Она используется во вспомогательной библиотеке функцией luaL_newstate.
static void *l_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);
}
Обратите внимание, что Standard C гарантирует, что free(NULL) не оказывает никакого влияния и что realloc(NULL,size) эквивалентно malloc(size).
Этот код предполагает, что realloc не дает сбоев при сокращении блока.
(Хотя Standard C и не гарантирует такое поведение, это вроде бы безопасное допущение.)
[-(2|1), +1, e]
void lua_arith (lua_State *L, int op);
Выполняет арифметические или побитовые операции над двумя значениями (или одним, в случае отрицания) на вершине стека, с значением, вторым от вершины стека, извлекает эти значения и помещает в стек результат операции.
Функция следует
соответствующих Lua операторов (то есть, она может вызывать метаметоды).
Значение параметра op должно быть одной из следующих констант:
[-0, +0, –]
lua_CFunction lua_atpanic (lua_State *L,
lua_CFunction panicf);
Устанавливает новую тревожную (panic) функцию и возвращает старую (смотрите §4.6).
[-(nargs+1), +nresults, e]
void lua_call (lua_State *L, int nargs,
int nresults);
Вызывает функцию.
Для вызова функции нужно использовать следующий протокол: вначале, функция, что будет вызываться, помещается в стек; затем, в стек помещаются аргументы функции в прямом порядке; то есть, первый аргумент помещается первым.
Наконец, вызывается lua_call; nargs - это количество аргументов, помещенных в стек.
При вызове функции, все аргументы и значение функции извлекаются из стека. При возврате функции, результаты функции помещаются в стек.
Количество результатов сводится к значению nresults, пока nresults не равен LUA_MULTRET. В этом случае, помещаются в стек все результаты функции.
Lua сам позаботится о том, чтобы возвращаемые значения поместились в стековом пространстве.
Результаты функции помещаются в стек в прямом порядке (первый результат помещается первым), так что после вызова последний результат будет на вершине стека.
Любая ошибка внутри вызванной функции передается вверх (с 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' */
Обратите внимание, что код, приведенный выше, сбалансирован: по его завершении стек возвращается к своей исходной конфигурации. Это считается хорошим стилем программирования.
[-(nargs + 1), +nresults, e]
void lua_callk (lua_State *L, int nargs,
int nresults,
lua_KContext ctx,
lua_KFunction k);
Данная функция ведет себя точно также как lua_call, но позволяет приостанавливать выполнение вызванной функции (смотрите §4.7).
typedef int (*lua_CFunction) (lua_State *L);
Тип для C функций.
Для правильного взаимодействия с Lua, C функция должна использовать следующий протокол, который определяет способ передачи параметров и результатов:
C функция получает свои аргументы от Lua в свой стек в прямом порядке (первый аргумент помещается в стек первым).
Поэтому, при запуске функции, lua_gettop(L) возвращает число аргументов полученных функцией.
Первый аргумент (если таковой имеется) находится по индексу 1, а последний аргумент по индексу lua_gettop(L).
Для возврата значений в Lua, 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 */
}
[-0, +0, –]
int lua_checkstack (lua_State *L, int n);
Функция удостоверяется, что стек имеет пространство как минимум для n дополнительных слотов.
Она возвращает значение false, если не может выполнить запрос, либо потому, что вызовет стек больше максимально установленного размера (обычно как минимум несколько тысяч элементов),
либо оттого, что не может выделить память под дополнительное пространство.
Эта функция никогда не сокращает стек; если стек уже больше нового размера, то она просто оставляет его без изменений.
[-0, +0, –]
void lua_close (lua_State *L);
Разрушает все объекты в заданном Lua состоянии (вызывая соответствующие метаметоды сборки мусора, если таковые имеются) и высвобождает всю динамическую память, используемую этим состоянием.
На некоторых платформах вызов этой функции может не понадобиться, потому что все ресурсы высвобождаются естественным образом, при завершении хост-программы.
С другой стороны, долго работающим программам, создающим множество состояний, вроде демонов или веб-серверов, она возможно потребуется для закрытия состояний, как только они станут не нужны.
[-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: сопоставление на меньше или равно (<=)
[-n, +1, e]
void lua_concat (lua_State *L, int n);
Конкатенирует n значений на вершине стека, извлекает их и оставляет результат на вершине стека.
Если n равен 1, результатом является одиночное значение на стеке (то есть, функция ничего не делает); если n равен 0, результатом будет пустая строка.
Конкатенация выполняется в соответствии с обычной семантикой Lua (смотрите §3.4.6).
[-0, +0, –]
void lua_copy (lua_State *L, int fromidx,
int toidx);
Копирует элемент с индексом fromidx в действительный индекс toidx, заменяя значение в этой позиции. Значения в других позициях не изменяются.
[-0, +1, e]
void lua_createtable (lua_State *L, int narr,
int nrec);
Создает новую, пустую таблицу и помещает её на стек. Параметр narr - это предположительное количество элементов в ряду таблицы; параметр nrec - предположительное количество других элементов в таблице.
Lua может использовать эти подсказки для предварительного выделения памяти под новую таблицу.
Такое предварительное распределение целесообразно для работы когда заранее известно сколько элементов будет иметь таблица. В других случаях можно использовать функцию lua_newtable.
[-0, +0, e]
int lua_dump (lua_State *L,
lua_Writer writer,
void *data,
int strip);
Выводит (сбрасывает) функцию в виде двоичных данных.
Получает Lua функцию, находящуюся на вершине стека, и выдает её в виде куска двоичных данных, которые, если их вновь загрузить в память, дадут в результате функцию, эквивалентную сброшенной.
Так как эти двоичные данные выводятся по частям, lua_dump вызывает функцию записи (смотрите lua_Writer) с установленными данными (аргумент data) для их записи.
Если у аргумента strip истинное значение, представленные двоичные данные могут не включать в себя всю отладочную информацию о функции, для экономии места.
Значением возвращения является кодом ошибки, возвращенным последним вызовом функции записи; 0 означает отсутствие ошибок.
Эта функция не извлекает (не выталкивает) Lua функцию из стека.
[-1, +0, v]
int lua_error (lua_State *L);
Создает Lua ошибку, используя значение на вершине стека в качестве объекта ошибки.
Эта функция делает длинный переход (long jump), и поэтому никогда не возвращает (смотрите luaL_error).
[-0, +0, e]
int lua_gc (lua_State *L, int what, int data);
Управляет сборщиком мусора.
Данная функция выполняет несколько задач, в соответствии со значением параметра what:
- LUA_GCSTOP: останавливает сборщик мусора.
- LUA_GCRESTART: перезапускает сборщик мусора.
- LUA_GCCOLLECT: выполняет полный цикл сборки мусора.
- LUA_GCCOUNT: возвращает текущее количество памяти (в килобайтах), используемой Lua.
- LUA_GCCOUNTB: возвращает остаток от деления текущего количества байт памяти, используемой Lua, на 1024.
- LUA_GCSTEP: выполняет возрастающий шаг сборки мусора.
- LUA_GCSETPAUSE: устанавливает data в качестве нового значения для паузы в работе сборщика (смотрите §2.5) и возвращает предыдущее значение паузы.
- LUA_GCSETSTEPMUL: устанавливает data в качестве нового значения для множителя шага сборщика мусора
(смотрите §2.5) и возвращает предыдущее значение множителя шага.
- LUA_GCISRUNNING: возвращает логическое значение, сообщающее работает ли сборщик мусора (т.е., не остановлен).
Для более подробного знакомства с этими опциями смотрите описание collectgarbage.
[-0, +0, –]
lua_Alloc lua_getallocf (lua_State *L, void **ud);
Возвращает функцию распределения памяти в указанном состоянии. Если ud не равен NULL, Lua сохраняет в *ud непрозрачный указатель, заданный при установке функции распределения памяти.
[-0, +1, e]
int lua_getfield (lua_State *L, int index,
const char *k);
Помещает в стек значение t[k], где t - это значение с указанным индексом.
Как и в Lua, эта функция может вызывать метаметод для события "index" (смотрите §2.4). Функция возвращает тип размещенного значения.
[-0, +0, –]
void *lua_getextraspace (lua_State *L);
Возвращает указатель на область необработанной памяти, связанной с заданным Lua состоянием. Приложение может использовать эту область для любых целей; Lua эту область никак не использует.
Каждая новая нить (поток) имеет такую область, инициализированную с копии области основной нити.
По умолчанию, данная область имеет размер указателя на пустое место (void), но можно перекомпилировать Lua с другим размером для этой области. (Смотрите LUA_EXTRASPACE в luaconf.h.)
[-0, +1, e]
int lua_getglobal (lua_State *L,
const char *name);
Помещает в стек значение глобального name. Возвращает тип этого значения.
[-0, +1, e]
int lua_geti (lua_State *L, int index,
lua_Integer i);
Помещает в стек значение t[i], где t является значением с указанным индексом. Как и в Lua, данная функция может вызывать метаметод для события "index" (смотрите §2.4).
Возвращает тип размещенного значения.
[-0, +(0|1), –]
int lua_getmetatable (lua_State *L, int index);
Если значение с указанным индексом имеет метатаблицу, функция помещает эту метатаблицу в стек и возвращает 1. В противном случае функция возвращает 0 и в стек ничего не помещает.
[-1, +1, e]
int lua_gettable (lua_State *L, int index);
Помещает в стек значение t[k], где t является значением с указанным индексом, а k - это значение на вершине стека.
Данная функция извлекает ключ из стека, помещая на это место получившееся значение.
Как и в Lua, данная функция может вызывать метаметод для события "index" (смотрите §2.4).
Возвращает тип размещенного значения.
[-0, +0, –]
int lua_gettop (lua_State *L);
Возвращает индекс элемента на вершине стека. Поскольку счет индексов начинается с 1, результат функции равен числу элементов в стеке; в частности, 0 означает пустой стек.
[-0, +1, –]
int lua_getuservalue (lua_State *L, int index);
Помещает в стек Lua значение, связанное с userdata с указанным индексом.
Возвращает тип размещенного значения.
[-1, +1, –]
void lua_insert (lua_State *L, int index);
Перемещает верхний элемент стека в место с указанным индексом, сдвигая вверх элементы выше этого индекса на освободившееся пространство.
Данная функция не может быть вызвана с псевдоиндексом, так как псевдоиндекс не является действующей позицией стека.
typedef ... lua_Integer;
Тип целых чисел в Lua.
По умолчанию этим типом является ,
(как правило, 64-битное целое число в двоично-дополнительном коде),
но это может быть изменено на long или int (как правило, 32-битное целое число в двоично-дополнительном коде).
(Смотрите LUA_INT_TYPE в luaconf.h.)
Lua также определяет константы LUA_MININTEGER и LUA_MAXINTEGER, с минимальным и максимальным значениями, которые соответствуют данному типу.
[-0, +0, –]
int lua_isboolean (lua_State *L, int index);
Возвращает 1, если тип значения по указанному индексу является логическим (boolean), и 0 в противном случае.
[-0, +0, –]
int lua_iscfunction (lua_State *L, int index);
Возвращает 1, если тип значения по указанному индексу является C функцией, и 0 в противном случае.
[-0, +0, –]
int lua_isfunction (lua_State *L, int index);
Возвращает 1, если тип значения по указанному индексу является функцией (либо C, либо Lua), и 0 в противном случае.
[-0, +0, –]
int lua_isinteger (lua_State *L, int index);
Возвращает 1, если тип значения по указанному индексу является целым числом (integer) (то есть, значением является число и представлено в виде целочисленного значения), и 0 в противном случае.
[-0, +0, –]
int lua_islightuserdata (lua_State *L, int index);
Возвращает 1, если тип значения по указанному индексу является легким userdata, и 0 в противном случае.
[-0, +0, –]
int lua_isnil (lua_State *L, int index);
Возвращает 1, если тип значения по указанному индексу является nil, и 0 в противном случае.
[-0, +0, –]
int lua_isnone (lua_State *L, int index);
Возвращает 1, если указанный индекс является недействительным, и 0 в противном случае.
[-0, +0, –]
int lua_isnoneornil (lua_State *L, int index);
Возвращает 1, если указанный индекс является недействительным или если значением по этому индексу является nil, и 0 в противном случае.
[-0, +0, –]
int lua_isnumber (lua_State *L, int index);
Возвращает 1, если тип значения по указанному индексу является числом или строкой, с возможностью конвертирования в число, и 0 в противном случае.
[-0, +0, –]
int lua_isstring (lua_State *L, int index);
Возвращает 1, если тип значения по указанному индексу является строкой или числом (которое всегда можно конвертировать в строку, и 0 в противном случае.
[-0, +0, –]
int lua_istable (lua_State *L, int index);
Возвращает 1, если тип значения по указанному индексу является таблицей, и 0 в противном случае.
[-0, +0, –]
int lua_isthread (lua_State *L, int index);
Возвращает 1, если тип значения по указанному индексу является нитью (thread), и 0 в противном случае.
[-0, +0, –]
int lua_isuserdata (lua_State *L, int index);
Возвращает 1, если тип значения по указанному индексу является userdata (либо полноценным, либо легким), и 0 в противном случае.
[-0, +0, –]
int lua_isyieldable (lua_State *L);
Возвращает 1, если указанная сопрограмма может приостановить выполнение, и 0 в противном случае.
typedef ... lua_KContext;
Тип для контекстов функций продолжения. Он должен быть числового типа.
При доступном intptr_t, этот тип определяется как intptr_t, так что он также может сохранять указатели. В противном случае он определяется как ptrdiff_t.
typedef int (*lua_KFunction) (lua_State *L,
int status,
lua_KContext ctx);
Тип для функций продолжения (смотрите §4.7).
[-0, +1, e]
void lua_len (lua_State *L, int index);
Возвращает длину значения с указанным индексом. Функция аналогична оператору '#' в Lua (смотрите §3.4.7)
и может вызывать метаметод для события "length" (смотрите §2.4). Результат помещается в стек.
[-0, +1, –]
int lua_load (lua_State *L,
lua_Reader reader,
void *data,
const char *chunkname,
const char *mode);
Функция загружает порцию (chunk) Lua не запуская её. Если нет ошибок, lua_load помещает скомпилированную порцию как функцию Lua на вершину стека. В противном случае, она размещает там сообщение об ошибке.
Возвращаемыми значениями lua_load являются:
- LUA_OK: нет ошибок;
- LUA_ERRSYNTAX: синтаксическая ошибка во время предварительной компиляции;
- LUA_ERRMEM: ошибка выделения памяти;
- LUA_ERRGCMM: ошибка при выполнении метаметода __gc. (Эта ошибка не имеет никакого отношения к загружаемой порции. Она генерируется сборщиком мусора.)
Функция lua_load использует предоставляемую пользователем функцию reader для считывания порции (смотрите lua_Reader).
Аргументом data является непрозрачное значение переданное функции считывания.
Аргумент chunkname задает имя для порции, которое используется для сообщений об ошибках и в отладочной информации (смотрите §4.9).
lua_load автоматически определяет, является ли порция текстовой или бинарной и соответственно этому выполняет загрузку
(смотрите ).
Строковый аргумент mode работает как в функции load, с дополнением, что значение NULL эквивалентно строке "bt".
lua_load внутри себя использует стек, поэтому функция считывания при возвращении всегда должна оставлять стек неизменным.
Если полученная функция имеет внешние локальные переменные (upvalue), первой её upvalue устанавливается значение глобального окружения, хранящееся в реестре по индексу LUA_RIDX_GLOBALS (смотрите §4.5).
При загрузке основных порций, этой upvalue будет переменная _ENV (смотрите §2.2). Другие внешние локальные переменные (upvalue) инициализируются со значением nil.
[-0, +0, –]
lua_State *lua_newstate (lua_Alloc f, void *ud);
Создает новую нить (thread), выполняемую в новом, независимом состоянии. Возвращает NULL, если не может создать нить или состояние (из-за недостатка памяти).
Аргумент f является функцией распределения памяти; Lua всё распределение памяти для этого состояния делает через эту функцию.
Второй аргумент ud - непрозрачный указатель, который Lua передает распределителю в каждом вызове.
[-0, +1, e]
void lua_newtable (lua_State *L);
Создает новую пустую таблицу и помещает её в стек. Эта функция эквивалентна lua_createtable(L, 0, 0).
[-0, +1, e]
lua_State *lua_newthread (lua_State *L);
Создает новую нить (thread), помещает её в стек и возвращает указатель на состояние Lua lua_State, которое представляет эту новую нить.
Новая нить, возвращаемая этой функцией, разделяет (использует совместно) с исходной нитью её глобальное окружение, но имеет независимый стек выполнения.
Не существует функции для непосредственного закрытия или уничтожения нити. Нить - субъект для сборщика мусора, как и любой другой объект Lua.
[-0, +1, e]
void *lua_newuserdata (lua_State *L, size_t size);
Данная функция выделяет новый блок памяти с заданным размером, помещает в стек новые полноценные userdata с адресом блока и возвращает этот адрес. Хост-программа может свободно использовать эту память.
[-1, +(2|0), e]
int lua_next (lua_State *L, int index);
Извлекает ключ из стека и помещает пару ключ-значение из таблицы с заданным индексом ("следующую (next)" пару после заданного ключа).
Если в таблице больше нет элементов, то lua_next возвращает 0 (и ничего не помещает).
Типичный обход выглядит следующим образом:
/* table is in the stack at index 't' */
/* таблица в стеке находится по индексу 't' */
lua_pushnil(L); /* first key (первый ключ) */
while (lua_next(L, t) != 0) {
/* uses 'key' (at index -2) and 'value' (at index -1) */
/* используем 'key' (по индексу -2) и 'value' (по индексу -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 */
/* удаляем 'value'; сохраняя 'key' для следующей итерации */
lua_pop(L, 1);
}
При обходе таблицы, не делайте вызов lua_tolstring непосредственно на ключ, если неизвестно, что ключ действительно является строкой.
Помните, что lua_tolstring может изменить значение по заданному индексу; это дезориентирует следующий вызов lua_next.
Смотрите описание функции next для пояснений о изменении таблицы во время её обхода.
typedef ... lua_Number;
Тип чисел с плавающей запятой в Lua.
По умолчанию этим типом является ,
но это можно изменить на
или . (Смотрите LUA_FLOAT_TYPE в luaconf.h.)
int lua_numbertointeger (lua_Number n, lua_Integer *p);
Конвертирует Lua число с плавающей запятой в целое число Lua. Этот макрос предполагает, что n имеет целочисленное значение.
Если это значение находится внутри диапазона целых чисел Lua, оно конвертируется в целое число и присваивается *p.
Макрос выводит логическое значение, указывающее, успешно ли прошло преобразование. (Отметьте, что такая проверка диапазона, из-за округлений, может быть довольно сложна для выполнения без этого макроса.)
Этот макрос может вычислять свои аргументы неоднократно.
[-(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.h):
- LUA_OK (0): успешное выполнение.
- LUA_ERRRUN: ошибка при выполнении.
- LUA_ERRMEM: ошибка выделения памяти. Для таких ошибок Lua не вызывает обработчик сообщений.
- LUA_ERRERR: ошибка во время работы обработчика сообщений.
- LUA_ERRGCMM: ошибка во время работы метаметода __gc. (Эта ошибка обычно не связана с вызванной функцией.)
[-(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.7).
[-n, +0, –]
void lua_pop (lua_State *L, int n);
Извлекает (выталкивает) n элементов из стека.
[-0, +1, –]
void lua_pushboolean (lua_State *L, int b);
Помещает в стек значение b логического типа.
[-n, +1, e]
void lua_pushcclosure (lua_State *L,
lua_CFunction fn,
int n);
Помещает в стек новое C замыкание.
При создании C функций, можно увязать с ней некоторые значения, таким образом создавая C замыкания (closure) (смотрите §4.4); затем эти значения будут доступны функции каждый раз при её вызове.
Для связывания значений с C функцией, вначале эти значения помещаются в стек (когда имеется несколько значений, первое значение помещается первым).
Затем вызывается lua_pushcclosure для создания и помещения в стек C функции, с аргументом n, сообщающим сколько значений будет связано с этой функцией.
lua_pushcclosure также выводит из стека эти значения.
Максимальным значением для n является 255.
При n равным нулю, эта функция создает легкую C функцию, которая является просто указателем на C функцию. В этом случае, она никогда не вызывает ошибку памяти.
[-0, +1, –]
void lua_pushcfunction (lua_State *L,
lua_CFunction f);
Помещает C функцию в стек. Данная функция получает указатель на C функцию и помещает в стек Lua значение типа function которое, при вызове, вызовет соответствующую C функцию.
Любая функция, чтобы иметь возможность быть вызванной Lua, должна следовать правилам получения своих параметров и возврата своих результатов (смотрите lua_CFunction).
[-0, +1, e]
const char *lua_pushfstring (lua_State *L,
const char *fmt,
...);
Помещает в стек сформатированную строку и возвращает указатель на эту строку.
Эта функция похожа на ISO C функцию sprintf, но имеет некоторые важные отличия:
- Не нужно выделять пространство под результат: результатом является строка Lua и Lua сам позаботится о выделении памяти (и её высвобождении через сборщика мусора).
- Спецификаторы конвертирования крайне ограничены. Нет ни флагов, ни ширины, ни уточнений. Спецификаторами конвертирования могут быть только:
'
%%' (вставляет символ '
%'),
'
%s' (вставляет строку, завершающуюся нулем, без ограничений размера),
'
%f' (вставляет
lua_Number),
'
%I' (вставляет
lua_Integer),
'
%p' (вставляет указатель в виде шестнадцатиричных цифр),
'
%d' (вставляет
int),
'
%c' (вставляет
int в виде однобайтного символа), и
'
%U' (вставляет
long int как последовательность байтов
UTF-8).
[-0, +1, –]
void lua_pushglobaltable (lua_State *L);
Помещает на стек глобальное окружение.
[-0, +1, –]
void lua_pushinteger (lua_State *L,
lua_Integer n);
Помещает в стек целое число со значением n.
[-0, +1, –]
void lua_pushlightuserdata (lua_State *L,
void *p);
Помещает в стек легкие userdata.
Userdata представляют C значения в Lua. Легкие userdata представлены указателем, void*.
Они являются значением (как число): вы не создавали их, они не имеют отдельной метатаблицы и они не собираются сборщиком мусора (так как никогда не создавались).
Легкие userdata равны "любым" легким userdata с тем же самым C адресом.
[-0, +1, e]
const char *lua_pushliteral (lua_State *L,
const char *s);
Этот макрос аналогичен lua_pushstring, но должен использоваться только, когда s является буквенной строкой.
[-0, +1, e]
const char *lua_pushlstring (lua_State *L,
const char *s,
size_t len);
Помещает в стек строку размером len, на которую указывает s.
Lua делает (или повторно использует) внутреннюю копию заданной строки, так что память, на которую указывает s, может быть высвобождена или вновь использована, сразу после возврата функции.
Строка может содержать любые двоичные данные, включая вложенные нули.
Возвращает указатель на внутреннюю копию строки.
[-0, +1, –]
void lua_pushnil (lua_State *L);
Помещает в стек значение nil.
[-0, +1, –]
void lua_pushnumber (lua_State *L, lua_Number n);
Помещает в стек число с плавающей запятой со значением n.
[-0, +1, e]
const char *lua_pushstring (lua_State *L,
const char *s);
Помещает в стек, завершающуюся нулем строку, на которую указывает s.
Lua делает (или повторно использует) внутреннюю копию заданной строки, так что память, на которую указывает s, может быть высвобождена или вновь использована, сразу после возврата функции.
Возвращает указатель на внутреннюю копию строки.
Если s равно NULL, в стек помещается nil и возвращает NULL.
[-0, +1, –]
int lua_pushthread (lua_State *L);
Помещает в стек нить, представленную L. Возвращает 1, если эта нить является основной нитью в своем состоянии.
[-0, +1, –]
void lua_pushvalue (lua_State *L, int index);
Помещает в стек копию элемента с указанным индексом.
[-0, +1, e]
const char *lua_pushvfstring (lua_State *L,
const char *fmt,
va_list argp);
Аналогична lua_pushfstring, за исключением того, что получает va_list вместо переменного числа аргументов.
[-0, +0, –]
int lua_rawequal (lua_State *L, int index1,
int index2);
Возвращает 1, если два значения с индексами index1 и index2 просто равны (то есть, без вызова метаметодов). В противном случае возвращает 0. Также возвращает 0, если любой из индексов недействителен.
[-1, +1, –]
int lua_rawget (lua_State *L, int index);
Аналогична lua_gettable, но обращение напрямую (raw) (то есть, без метаметодов).
[-0, +1, –]
int lua_rawgeti (lua_State *L, int index,
lua_Integer n);
Помещает на стек значение t[n], где t является таблицей с указанным индексом. Непосредственное (raw) обращение; то есть, метаметоды не вызываются.
Возвращает тип размещенного значения.
[-0, +1, –]
int lua_rawgetp (lua_State *L, int index,
const void *p);
Помещает на стек значение t[k], где t является таблицей с указанным индексом, а k - это указатель p представленный в виде легких userdata.
Непосредственное (raw) обращение; то есть, метаметоды не вызываются.
Возвращает тип размещенного значения.
[-0, +0, –]
size_t lua_rawlen (lua_State *L, int index);
Возвращает непосредственную (raw) "длину" значения по указанному индексу: для строк это будет длина строки; для таблиц - результат работы оператора длины ('#') без метаметодов;
для userdata - размер блока памяти, выделенной для userdata; для других значений это 0.
[-2, +0, e]
void lua_rawset (lua_State *L, int index);
Аналогична lua_settable, но делает прямое (raw) назначение (то есть, без метаметодов).
[-1, +0, e]
void lua_rawseti (lua_State *L, int index,
lua_Integer i);
Выполняет операцию, аналогичную t[i] = v, где t является таблицей с указанным индексом, а v - значением на вершине стека.
Данная функция извлекает значение из стека. Непосредственное (raw) назначение; то есть, она не вызывает метаметодов.
[-1, +0, e]
void lua_rawsetp (lua_State *L, int index,
const void *p);
Выполняет операцию, аналогичную t[p] = v, где t является таблицей с указанным индексом, p кодируется как легкие userdata, а v - значением на вершине стека.
Данная функция извлекает значение из стека. Непосредственное (raw) назначение; то есть, она не вызывает метаметодов.
typedef const char * (*lua_Reader) (lua_State *L,
void *data,
size_t *size);
Функция считывания, используемая lua_load.
Каждый раз, когда ей требуется очередной кусок порции (chunk) lua_load вызывает функцию считывания, проходя по её параметру data.
Функция считывания должна возвратить указатель на блок памяти с новым куском порции (chunk) и установить значение size для размера блока. Блок должен существовать пока функция считывания не будет вызвана снова.
Для обозначения конца порции (chunk), функция считывания должна возвратить NULL или установить size как нуль. Функция считывания может возвращать куски любого размера, большего нуля.
[-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))
[-1, +0, –]
void lua_remove (lua_State *L, int index);
Удаляет элемент из стека по указанному действительному индексу, сдвигая вниз элементы выше этого индекса для заполнения образовавшегося разрыва.
Данная функция не может быть вызвана с псевдоиндексом, так как псевдоиндекс не является фактически существующей позицией стека.
[-1, +0, –]
void lua_replace (lua_State *L, int index);
Перемещает верхний элемент в заданный действительный индекс без сдвига какого-либо элемента (следовательно, заменяя значение по этому заданному индексу), и затем извлекает верхний элемент.
[-?, +?, –]
int lua_resume (lua_State *L, lua_State *from,
int nargs);
Запускает и возобновляет выполнение сопрограммы в заданной нити (thread) L.
Для запуска сопрограммы, на стек нити помещается основная функция плюс любые аргументы; затем вызывается lua_resume, с nargs, который является числом аргументов.
Этот вызов возвращается когда сопрограмма приостанавливает или завершает свое выполнение.
При её возвращении, стек содержит все значения переданные в функцию lua_yield, или все значения, возвращенные телом функции.
lua_resume возвращает LUA_YIELD, если сопрограмма приостанавливает выполнение,
LUA_OK, если сопрограмма завершила свое выполнение без ошибок или код ошибки в случае ошибок (смотрите lua_pcall).
В случае ошибок, стек не разбирается, так что над ним можно использовать отладочный API. Сообщение об ошибке появляется на вершине стека.
Для возобновления выполнения сопрограммы, удаляются любые результаты из последней lua_yield, помещая на её стек только значения, передаваемые в качестве результатов из yield,
и затем вызывается lua_resume.
Параметр from представляет сопрограмму, которая возобновляет L. Если такой сопрограммы нет, этот параметр может быть равен NULL.
[-0, +0, –]
void lua_rotate (lua_State *L, int idx, int n);
Прокручивает элементы стека между действительным индексом idx и вершиной стека.
При положительном n, элементы проворачиваются на n позиций в направлении к вершине, или на -n позиций в направлении вниз, при отрицательномn.
Абсолютное значение n не должно быть больше размера прокручиваемой части стека. Данная функция не может быть вызвана с псевдоиндексом, так как псевдоиндекс не является фактической позицией стека.
[-0, +0, –]
void lua_setallocf (lua_State *L, lua_Alloc f,
void *ud);
Заменяет функцию распределения памяти заданного состояния на f с пользовательскими данными ud.
[-1, +0, e]
void lua_setfield (lua_State *L, int index,
const char *k);
Выполняет действие аналогичное t[k] = v, где t является значением по заданному индексу, а v - значение вершины стека.
Эта функция извлекает значение из стека. Как и в Lua, данная функция может вызывать метаметод для события "newindex" (смотрите §2.4).
[-1, +0, e]
void lua_setglobal (lua_State *L,
const char *name);
Извлекает значение из стека и устанавливает его в качестве нового значения глобальной name.
[-1, +0, e]
void lua_seti (lua_State *L, int index,
lua_Integer n);
Выполняет действие аналогичное t[n] = v, где t является значением по заданному индексу, а v - значение на вершине стека.
Эта функция извлекает значение из стека. Как и в Lua, данная функция может вызывать метаметод для события "newindex" (смотрите §2.4).
[-1, +0, –]
void lua_setmetatable (lua_State *L, int index);
Извлекает (выталкивает) таблицу из стека и устанавливает её в качестве новой метатаблицы для значения с заданным индексом.
[-2, +0, e]
void lua_settable (lua_State *L, int index);
Выполняет действие аналогичное t[k] = v, где t является значением по заданному индексу, v - значение вершины стека, а k - это значение чуть ниже вершины.
Эта функция извлекает из стека и ключ и значение. Как и в Lua, данная функция может вызывать метаметод для события "newindex" (смотрите §2.4).
[-?, +?, –]
void lua_settop (lua_State *L, int index);
Принимает любой индекс, или 0, и устанавливает вершину стека на этот индекс. Если новая вершина больше старой, то новые элементы заполняются значениями nil.
Если index равен 0, то удаляются все элементы стека.
[-1, +0, –]
void lua_setuservalue (lua_State *L, int index);
Извлекает значение из стека и устанавливает его в качестве нового значения, связанного с userdata по заданному индексу.
typedef struct lua_State lua_State;
Непрозрачная структура, которая указывает на нить (thread) и косвенно (через нить) на все состояние интерпретатора Lua.
Библиотека Lua полностью реентерабельна: она не имеет глобальных переменных. Вся информация о состоянии доступна через эту структуру.
Примечание: Компьютерная программа в целом или её отдельная процедура называется реентерабельной (от англ. reentrant — повторно входимый), если она разработана таким образом, что одна и та же копия инструкций программы в памяти может быть совместно использована несколькими пользователями или процессами.
... читать далее
При этом второй пользователь может вызвать реентерабельный код до того, как с ним завершит работу первый пользователь и это как минимум не должно привести к ошибке,
а при корректной реализации не должно вызвать потери вычислений (то есть не должно появиться необходимости выполнять уже выполненные фрагменты кода).
Реентерабельность тесно связана с безопасностью функции в многопоточной среде (thread-safety), тем не менее,
это разные понятия (в практическом программировании под современные ОС термин «реентерабельный» на деле равносилен термину «thread-safe»).
Обеспечение реентерабельности является ключевым моментом при программировании многозадачных систем, в частности, операционных систем.
Для обеспечения реентерабельности необходимо выполнение нескольких условий:
никакая часть вызываемого кода не должна модифицироваться;
вызываемая процедура не должна сохранять информацию между вызовами;
если процедура изменяет какие-либо данные, то они должны быть уникальными для каждого пользователя;
процедура не должна возвращать указатели на объекты, общие для разных пользователей.
В общем случае, для обеспечения реентерабельности необходимо, чтобы вызывающий процесс или функция каждый раз передавал вызываемому процессу все необходимые данные.
Таким образом, функция, которая зависит только от своих параметров, не использует глобальные и статические переменные и вызывает только реентерабельные функции, будет реентерабельной.
Если функция использует глобальные или статические переменные, необходимо обеспечить, чтобы каждый пользователь хранил свою локальную копию этих переменных.
(Из Википедии)
Указатель на эту структуру должен передаваться в качестве первого аргумента для каждой функции в библиотеке, за исключением lua_newstate, которая создает состояние Lua с нуля.
[-0, +0, –]
int lua_status (lua_State *L);
Возвращает состояние нити (thread) L.
Состояние может быть 0 (LUA_OK) для обычного состояния нити, кодом ошибки - если нить закончила выполнение lua_resume с ошибкой,
или LUA_YIELD - если нить приостановлена.
Вызывать функции можно только в нити с состоянием LUA_OK.
Можно возобновлять нити с состоянием LUA_OK (для запуска новой сопрограммы) или LUA_YIELD (для возобновления выполнения сопрограммы).
[-0, +1, –]
size_t lua_stringtonumber (lua_State *L,
const char *s);
Конвертирует строку s, завершающуюся нулем, в число, помещает число в стек и возвращает полный размер строки, то есть, её длину плюс один.
Преобразование может привести к целому числу или к числу с плавающей запятой, в соответствии с лексическими соглашениями Lua (смотрите §3.1).
Строка может иметь начальные и конечные пробелы и знак.
Если строка в действительности не является числом, возвращается 0 и в стек ничего не помещается. (Обратите внимание, что результат может использоваться в качестве логического, значение true, если преобразование успешно.)
[-0, +0, –]
int lua_toboolean (lua_State *L, int index);
Конвертирует Lua значение с заданным индексом в логическое значение C (0 или 1).
Как и все проверки Lua, lua_toboolean возвращает true для любого Lua значения, отличного от false и nil; в противном случае возвращает false.
(Если нужно принимать только настоящие логические значения, для проверки типа значения используйте lua_isboolean.)
[-0, +0, –]
lua_CFunction lua_tocfunction (lua_State *L,
int index);
Конвертирует значение по заданному индексу в C функцию. Это значение должно быть C функцией; в противном случае, возвращается NULL.
[-0, +0, –]
lua_Integer lua_tointeger (lua_State *L,
int index);
Эквивалентна функции lua_tointegerx с isnum равным NULL.
[-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, его объекту ссылки назначается логическое значение, которое показывает, была ли операция успешной.
[-0, +0, e]
const char *lua_tolstring (lua_State *L,
int index,
size_t *len);
Конвертирует Lua значение по заданному индексу в C строку. Если len не является NULL, она также устанавливает указатель *len с длиной строки.
Lua значение должно быть строкой или числом; в противном случае функция возвращает NULL. Если значение является числом, то lua_tolstring также изменяет действительное значение в стеке на строку.
(Такое изменение дезориентирует функцию lua_next, когда lua_tolstring применяется для ключей во время обхода таблицы.)
lua_tolstring возвращает полностью согласованный, внутри Lua состояния, указатель на строку.
В этой строке всегда имеется нуль ('\0'), после последнего символа (как в C), но может содержать и другие нули в своем теле.
Поскольку в Lua есть сборщик мусора, нет гарантии что указатель, возвращенный lua_tolstring, будет действительным после удаления из стека соответствующего Lua значения.
[-0, +0, –]
lua_Number lua_tonumber (lua_State *L, int index);
Эквивалентна функции lua_tonumberx с аргументом isnum равным NULL.
[-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, его отсылочному значению назначается логическое значение, которое показывает, успешно ли выполнена операция.
[-0, +0, –]
const void *lua_topointer (lua_State *L,
int index);
Конвертирует значение по заданному индексу в универсальный C указатель (void*).
Значение может быть userdata, таблицей, нитью (thread) или функцией; в противном случае lua_topointer возвращает NULL.
Разные объекты дают разные указатели. Не существует способа конвертировать указатель обратно, к исходному значению.
Обычно эта функция используется для
и отладочной информации.
[-0, +0, e]
const char *lua_tostring (lua_State *L,
int index);
Функция эквивалентна lua_tolstring с len равным NULL.
[-0, +0, –]
lua_State *lua_tothread (lua_State *L, int index);
Конвертирует значение по заданному индексу в Lua нить (thread) (представленную как lua_State*). Это значение должно быть нитью; в противном случае функция возвращает NULL.
[-0, +0, –]
void *lua_touserdata (lua_State *L, int index);
Если значением по заданному индексу являются полноценные userdata, возвращается адрес его блока. Если значением является light userdata, возвращается его указатель. В противном случае, возвращает NULL.
[-0, +0, –]
int lua_type (lua_State *L, int index);
Возвращает тип значения по указанному действительному индексу, или LUA_TNONE для недействительного (но допустимого) индекса.
Типы, возвращенные lua_type, кодируются следующими константами, определенными в lua.h:
[-0, +0, –]
const char *lua_typename (lua_State *L, int tp);
Возвращает название типа, кодированного по значению tp, которое должно быть одним из значений, возвращенных lua_type.
typedef ... lua_Unsigned;
Беззнаковая версия lua_Integer.
[-0, +0, –]
int lua_upvalueindex (int i);
Возвращает псевдоиндекс, который представляет i-ковою внешнюю локальную переменную (upvalue) выполняемой функции (смотрите §4.4).
[-0, +0, v]
const lua_Number *lua_version (lua_State *L);
Возвращает адрес номера версии, хранящегося в ядре Lua.
При вызове с действующим lua_State, возвращает адрес версии, использованной для создания этого состояния. При вызове с NULL, возвращает адрес версии, выполнившей вызов.
typedef int (*lua_Writer) (lua_State *L,
const void* p,
size_t sz,
void* ud);
Тип функции записи, используемый lua_dump.
Каждый раз при выдаче очередной части порции, lua_dump вызывает функцию записи, передавая буфер для записи (p), его размер (sz) и параметр data, предоставляемый в lua_dump.
Функция записи возвращает код ошибки: 0 означает отсутствие ошибок; любое другое значение означает ошибку и удерживает lua_dump от повторного вызова записи.
[-?, +?, –]
void lua_xmove (lua_State *from, lua_State *to,
int n);
Функция обменивает значения между разными нитями (потоками) одного и того же состояния.
Она извлекает n значений из стека from, и помещает их в стек to.
[-?, +?, e]
int lua_yield (lua_State *L, int nresults);
Эта функция эквивалентна функции lua_yieldk, но не имеет продолжения (смотрите §4.7).
Поэтому, при возобновлении выполнения нити, она продолжает функцию, которая вызвана функцией, вызвавшей lua_yield.
[-?, +?, e]
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.7).
Эта функция продолжения получит тот же самый стек от предыдущей функции, с n-ным числом результатов, удаленных и замененных посредством аргументов, переданных в lua_resume.
Кроме того, функция продолжения получает значение ctx, которое было передано в lua_yieldk.
Как правило, эта функция ничего не возвращает; когда сопрограмма в конце концов возобновляется, она продолжает выполнение функции продолжения.
Тем не менее, существует один особый случай, который появляется когда эта функция вызывается внутри строковой ловушки (смотрите §4.9).
В этом случае, lua_yieldk следует вызывать без продолжения (вероятно в виде lua_yield), и ловушка должна возвращать сразу после вызова.
Lua будет приостановлена и, когда сопрограмма снова возобновит выполнение, продолжит нормальное выполнение функции (Lua), которая вызвала ловушку.
Данная функция может выдавать ошибку, если она вызвана из нити (thread) с ожиданием C вызова без функции продолжения или из нити, которая не работает внутри возобновления (например, основная нить).
Lua не имеет встроенных средств отладки. Взамен предлагается специальный интерфейс с помощью функций и ловушек (hook).
Этот интерфейс позволяет конструировать различные виды отладчиков, профайлеров и другие инструменты, которые требуются для получения "инсайдерской информации" от интерпретатора.
Примечание: Профилирование — сбор характеристик работы программы, таких как время выполнения отдельных фрагментов (обычно подпрограмм), число верно предсказанных условных переходов, число кэш-промахов и т. д.
Инструмент, используемый для анализа работы, называют профилировщиком или профайлером (англ. profiler).
... читать далее
Обычно выполняется совместно с оптимизацией программы.
Характеристики могут быть аппаратными (время) или вызванные программным обеспечением (функциональный запрос). Инструментальные средства анализа программы чрезвычайно важны для того, чтобы понять поведение программы.
Проектировщики ПО нуждаются в таких инструментальных средствах, чтобы оценить, как хорошо выполнена работа.
Программисты нуждаются в инструментальных средствах, чтобы проанализировать их программы и идентифицировать критические участки программы.
Это часто используется, чтобы определить, как долго выполняются определенные части программы, как часто они выполняются, или генерировать граф вызовов (Call Graph).
Обычно эта информация используется, чтобы идентифицировать те участки программы, которые работают больше всего. Эти трудоёмкие участки могут быть оптимизированы, чтобы выполняться быстрее.
Также выделяют анализ покрытия (Code Coverage) — процесс выявления неиспользуемых участков кода при помощи, например, многократного запуска программы.
(Из Википедии)
typedef struct lua_Debug {
int event;
const char *name; /* (n) */
const char *namewhat; /* (n) */
const char *what; /* (S) */
const char *source; /* (S) */
int currentline; /* (l) */
int linedefined; /* (S) */
int lastlinedefined; /* (S) */
unsigned char nups; /* (u) число upvalue */
unsigned char nparams; /* (u) число параметров */
char isvararg; /* (u) */
char istailcall; /* (t) */
char short_src[LUA_IDSIZE]; /* (S) */
/* private part (отдельная часть) */
other fields (другие поля)
} lua_Debug;
Структура, используемая для переноса различных частей сведений о функции или записи активации. lua_getstack заполняет только отдельную часть этой структуры, для последующего использования.
Для наполнения полезной информацией других полей lua_Debug, вызывайте функцию lua_getinfo.
Поля структуры lua_Debug имеют следующее значение:
- source: имя порции (chunk), которая создала функцию. Если source начинается с '@', это значит что функция была определена в файле, где за символом '@' следует имя файла.
Если source начинается с '=', то остальная часть его содержимого описана исходником, зависимым от пользователя.
В противном случае, функция была определена в строке, где source является этой строкой.
- short_src: "печатабельная" версия source, для использования в сообщениях об ошибках.
- linedefined: номер строки, с которой начинается определение функции.
- lastlinedefined: номер строки, на которой оканчивается определение функции.
- what: строка "Lua", если функция является Lua функцией, "C" - если это C функция, "main" - если это основная часть порции (chunk).
- currentline: текущая строка, где выполняется данная функция. Если нет доступных сведений о строке, currentline устанавливается равной -1.
- name: допустимое имя для заданной функции. Так как функции в Lua являются значениями первого класса, у них нет фиксированного имени:
некоторые функции могут быть значением нескольких глобальных переменных, в то время как другие могут только сохраняться в поле таблицы.
Функция lua_getinfo проверяет, как функция была названа для поиска соответствующего имени. Если имя найти не удается, то name устанавливается как NULL.
- namewhat: поясняет поле name.
Значением namewhat может быть "global", "local", "method", "field", "upvalue", или "" (пустая строка), в соответствии с тем, как функция была вызвана.
(Lua использует пустую строку когда нет другого выбора, представленного к применению.)
- istailcall: значение true, если данный вызов функции был вызван хвостовым вызовом. В этом случае, функция, вызывающая этот уровень не находится в стеке.
- nups: число внешних локальных переменных (upvalue) функции.
- nparams: число фиксированных (установленных) параметров функции (для C-ишных функций значение всегда равно 0).
- isvararg: значение true, если у функции переменное число аргументов т.е. vararg функция (для C-ишных функций значение всегда истинно).
[-0, +0, –]
lua_Hook lua_gethook (lua_State *L);
Возвращает текущую функцию ловушки.
[-0, +0, –]
int lua_gethookcount (lua_State *L);
Возвращает текущий счет ловушки.
[-0, +0, –]
int lua_gethookmask (lua_State *L);
Возвращает текущую маску ловушки.
[-(0|1), +(0|1|2), e]
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 для заполнения или значение для помещения в стек:
- 'n': заполняет поля name и namewhat;
- 'S':заполняет поля source, short_src, linedefined, lastlinedefined, и what;
- 'l': заполняет поле currentline;
- 't': заполняет поле istailcall;
- 'u': заполняет поля nups, nparams, и isvararg;
- 'f': помещает в стек функцию, которая запускает указанный уровень;
- 'L': помещает в стек таблицу, чьими индексами являются номера действующих (valid) строк функции.
(Действующей строкой является строка с некоторым объединенным кодом, то есть, строка, на которую можно установить точку останова (break point).
Недействующие строки включают в себя пустые строки и комментарии.) Если эта опция задана вместе с опцией 'f', то её таблица помещается в стек после функции.
Данная функция при ошибке возвращает 0 (например, неверная опция в what).
[-0, +(0|1), –]
const char *lua_getlocal (lua_State *L,
const lua_Debug *ar,
int n);
Получает информацию о локальной переменной заданной записи активации или заданной функции.
В первом случае, параметр ar должен быть действительной записью активации, которая была заполнена предыдущим вызовом lua_getstack или задана в качестве аргумента к ловушке (hook) (смотрите lua_Hook).
Индекс n определяет нужную для просмотра локальную переменную; смотрите debug.getlocal для более подробных сведений о индексах и именах переменных.
lua_getlocal помещает значение переменной в стек и возвращает её имя.
Во втором случае, ar должен быть NULL и рассматриваемая функция должна находиться на вершине стека.
В этом случае, видимыми будут только параметры Lua функций (так как нет никакой информации о том, какие переменные являются активными) и в стек никаких значений не помещается.
Если индекс больше числа активных локальных переменных, функция возвращает NULL (и ничего в стек не помещает).
[-0, +0, –]
int lua_getstack (lua_State *L, int level,
lua_Debug *ar);
Получает сведения о стеке во время выполнения интерпретатора.
Данная функция заполняет части структуры lua_Debug с идентификации записи активации функции, выполняемой на заданном уровне.
Уровень 0 является выполняемой в данный момент функцией, в то время как n+1 - это функция, которая вызвала уровень n (за исключением хвостовых вызовов, которые не учитываются в стеке).
При отсутствии ошибок lua_getstack возвращает 1; при вызове с уровнем большем глубины стека, она возвращает 0.
[-0, +(0|1), –]
const char *lua_getupvalue (lua_State *L,
int funcindex,
int n);
Получает информацию о n-ной внешней локальной переменной (upvalue) замыкания функции с индексом funcindex. Функция помещает значение внешней локальной переменной в стек и возвращает её имя.
Если индекс n больше числа внешних локальных переменных, функция возвращает NULL (и ничего в стек не помещает).
Для функций C, данная функция использует в качестве имени, для всех внешних локальных переменных, пустую строку "".
(Для функций Lua, upvalue - это внешняя локальная переменная, используемая функциями и, следовательно, включена в их замыкания.)
Внешние локальные переменные не особо упорядочены, поскольку они действуют по всей функции. Они нумеруются в произвольном порядке.
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
Тип для функций отладочной ловушки (hook).
Всякий раз, когда вызывается ловушка, в поле event её аргумента ar устанавливается определенное событие, на которое срабатывает ловушка.
Lua отождествляет эти события со следующими константами: LUA_HOOKCALL, LUA_HOOKRET,
LUA_HOOKTAILCALL, LUA_HOOKLINE, и LUA_HOOKCOUNT.
Более того, для строковых событий также устанавливается поле currentline. Для получения значения из любого другого поля в ar, ловушка должна вызвать lua_getinfo.
Для событий вызова, event может быть LUA_HOOKCALL - обычное значение, или LUA_HOOKTAILCALL - для хвостового вызова; в этом случае не будет соответствующего события возврата.
В то время когда Lua обрабатывает ловушку (hook), он запрещает другие вызовы ловушек. Поэтому, если ловушка обратно вызывает Lua для выполнения функции или порции (chunk), это выполнение происходит без каких-либо вызовов ловушек.
Функции ловушек не могут иметь продолжений, то есть, они не могут вызывать lua_yieldk, lua_pcallk, или lua_callk с ненулевым k.
Функции ловушек могут приостанавливать выполнение при следующих условиях: могут быть приостановлены только события счета и строковые;
для приостановки функция ловушка должна завершить свое выполнение вызовом lua_yield с nresults равным нулю (то есть, без значений).
[-0, +0, –]
void lua_sethook (lua_State *L, lua_Hook f,
int mask,
int count);
Устанавливает функцию отладочной ловушки (hook).
Аргумент f является функцией ловушки. mask указывает на каких событиях будет вызываться ловушка: значение аргумента формируется побитовым ИЛИ из констант
LUA_MASKCALL, LUA_MASKRET, LUA_MASKLINE, и LUA_MASKCOUNT.
Аргумент count имеет смысл только когд маска содержит LUA_MASKCOUNT. Для каждого события, ловушка вызывается как описано ниже:
- Ловушка вызова: вызывается, когда интерпретатор вызывает функцию.
Ловушка вызывается сразу после ввода Lua новой функции, перед получением функцией своих аргументов.
- Ловушка возврата: вызывается когда интерпретатор возвращается из функции. Ловушка вызывается непосредственно перед тем, как Lua оставляет функцию. При этом нет стандартного способа обращения к значениям, возвращаемым функцией.
- Ловушка строки: вызывается когда интерпретатор собирается начать выполнение новой строки кода или когда он переходит назад в коде (даже на ту же самую строку).
(Это событие происходит только пока Lua выполняет Lua функцию.)
- Ловушка счета: вызывается после выполнения интерпретатором каждого определенного количества (указанного в count) инструкций. (Это событие происходит только пока Lua выполняет Lua функцию.)
Ловушка отключается установкой аргумента mask в ноль.
[-(0|1), +0, –]
const char *lua_setlocal (lua_State *L,
const lua_Debug *ar,
int n);
Устанавливает значение локальной переменной заданной записи активации. Она присваивает значение вершины стека переменной и возвращает её имя. Также она извлекает значение из стека.
При индексе, большем числа активных локальных переменных, возвращает значение NULL (и ничего не извлекает).
Параметры ar и n такие же, как в функции lua_getlocal.
[-(0|1), +0, –]
const char *lua_setupvalue (lua_State *L,
int funcindex,
int n);
Устанавливает значение внешней локальной переменной (upvalue) замыкания. Функция присваивает значение вершины стека внешней локальной переменной и возвращает её имя. Также она извлекает значение из стека.
При индексе n, большем числа внешних локальных переменных, возвращает NULL (и ничего из стека не извлекает).
Параметры funcindex и n такие же как в функции lua_getupvalue.
[-0, +0, –]
void *lua_upvalueid (lua_State *L, int funcindex,
int n);
Возвращает уникальный идентификатор внешней локальной переменной (upvalue) под номером n из замыкания функции по индексу funcindex.
Эти уникальные идентификаторы позволяют программе проверить, используют ли совместно различные замыкания функции внешние локальные переменные.
Lua замыкания, которые совместно используют upvalue (то есть те, что обращаются к одной и той же внешней локальной переменной) будут возвращать одинаковые идентификаторы для индексов этой upvalue.
Параметры funcindex и n такие же как в функции lua_getupvalue, но n не может быть больше числа имеющихся внешних локальных переменных.
[-0, +0, –]
void lua_upvaluejoin (lua_State *L, int funcindex1,
int n1,
int funcindex2,
int n2);
Функция делает n1-ную внешнюю локальную переменную (upvalue) замыкания Lua функции по индексу funcindex1 отсылаемой на n2-ную upvalue замыкания Lua функции по индексу funcindex2.