Доступ к телу функции с помощью Lua - PullRequest
9 голосов
/ 02 февраля 2009

Я возвращаюсь к основам здесь, но в Lua вы можете определить таблицу следующим образом:

myTable = {}
myTable [1] = 12

Печать самой ссылки на таблицу возвращает указатель на нее. Чтобы получить доступ к его элементам, вам нужно указать индекс (т. Е. Точно так же, как и массив)

print(myTable )    --prints pointer
print(myTable[1])  --prints 12

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

myFunc = function() local x = 14 end     --Defined function
print(myFunc)                            --Printed pointer to function

Есть ли способ доступа к телу определенной функции. Я пытаюсь собрать небольшой визуализатор кода и хотел бы «заполнить» заданную функцию специальными функциями / переменными, чтобы позволить визуализатору «привязать» себя к коду. Мне нужно было бы переопределить функцию либо переменная или строка.

Ответы [ 4 ]

10 голосов
/ 03 февраля 2009

Нет способа получить доступ к исходному коду тела данной функции на простом Lua. Исходный код выбрасывается после компиляции в байт-код.

Примечание. Кстати, эта функция может быть определена во время выполнения с помощью средства, подобного loadstring.

Возможны частичные решения & mdash; в зависимости от того, чего вы на самом деле хотите достичь.

Вы можете получить позицию исходного кода из библиотеки отладки & mdash; если библиотека отладки включена и символы отладки не удаляются из байт-кода. После этого вы можете загрузить исходный файл и извлечь из него код.

Вы можете вручную украсить интересующие вас функции необходимыми метаданными. Обратите внимание, что функции в Lua являются допустимыми ключами таблицы, поэтому вы можете создать таблицу функций для метаданных. Возможно, вы захотите сделать эту таблицу слабой, чтобы она не помешала GC собирать функции.

Если вам нужно решение для анализа кода Lua, взгляните на Metalua .

4 голосов
/ 04 февраля 2009

Использование библиотеки отладки - ваша единственная ставка. Используя это, вы можете получить либо строку (если функция определена в блоке, который был загружен с помощью 'loadstring'), либо имя файла, в котором была определена функция; вместе с номерами строк, с которых начинается и заканчивается определение функции. См. документацию .

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

2 голосов
/ 02 февраля 2009

Извлечение Lua Introspective Facilities в библиотеке отладки.

Основная интроспективная функция в библиотека отладки - это debug.getinfo функция. Его первый параметр может быть функция или уровень стека. Когда ты вызовите debug.getinfo (foo) для некоторых Функция Foo, вы получаете таблицу с некоторые данные об этой функции. Таблица может иметь следующие поля:

Поля, которые вы хотели бы получить, я думаю.

0 голосов
/ 02 февраля 2009

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

env = {}
myFunc = function() x = 14 end
setfenv(myFunc, env)
myFunc()
print(myFunc)    -- prints pointer
print(env.x)     -- prints 14

Кроме того, вы можете использовать Debug Library :

> myFunc = function() local x = 14 ; debug.debug() end
> myFunc()
> lua_debug> _, x = debug.getlocal(3, 1)
> lua_debug> print(x) -- prints 14

Возможно, было бы более полезно получить локальные переменные с помощью функции hook вместо явного входа в режим отладки (т. Е. Добавив вызов debug.debug ())

В Lua C API также имеется Интерфейс отладки .

...