Хранить все в одном байт-коде lua? - PullRequest
14 голосов
/ 06 марта 2012

Я встроил lua вместе с байт-кодом в проект, написанный на C. Теперь, когда я расширяю свою базу кода lua, добавляя файлы .lua, есть ли способ сохранить этот код в одном байт-коде?

(Я знаю, как загрузить несколько кусков байт-кода. Но сделать так, чтобы он загружал один кусочек, а затем забыть о связующем коде, было бы просто удобно).

Я пытался использовать текстовое включение, но, похоже, в Lua для этого нет ключевого слова. «Require» и «dofile» проверяют файлы во время выполнения, поэтому результирующий байт-код после выполнения «lua -b ...» не будет включать код этих файлов.

И нет способа объединить файлы байт-кода, не так ли? Я имею в виду, что при создании файла байт-кода команда require добавит код всех этих файлов в один файл байт-кода.

PS : ответ Михала Котмана работает на Луа, о чем я и просил. Я думал, что Lua и LuaJIT будут работать одинаково. Они не Чтобы объединить несколько файлов .lua в один файл байт-кода LuaJIT, следует один

  • использовать "LuaJIT -b" (кажется, не работает)
  • скомпилировать Lua's luac.c с исходниками LuaJIT
  • эмулировать luac.c с помощью команд lua (без C API)?

Ответы [ 4 ]

11 голосов
/ 06 марта 2012

Вы можете объединить несколько файлов в один файл, используя luac . При запуске все чанки из исходных файлов выполняются в порядке их добавления в скомпилированный файл:

$ echo "x=1"         > l1.lua
$ echo "y=2"         > l2.lua
$ echo "print(x, y)" > l3.lua
$ luac -o run.luac l1.lua l2.lua l3.lua
$ lua run.luac
1   2

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

Обратите внимание, что вы можете встроить содержимое скомпилированного файла в виде строки в ваш проект, нет необходимости сохранять его во внешнем файле.

Обновление для LuaJIT 2

Как вы обнаружили, вы можете использовать Lua Compiler в Lua , чтобы получить комбинированный файл, который можно загрузить, как было отмечено ранее. Это упрощенная версия, которая выводит на стандартный вывод:

-- http://lua-users.org/wiki/LuaCompilerInLua
-- compile the input file(s) passed as arguments and output them combined to stdout
local chunk = {}
for _, file in ipairs(arg) do
  chunk[#chunk + 1] = assert(loadfile(file))
end
if #chunk == 1 then
  chunk = chunk[1]
else
  -- combine multiple input files into a single chunk
  for i, func in ipairs(chunk) do
    chunk[i] = ("loadstring%q(...);"):format(string.dump(func))
  end
  chunk = assert(loadstring(table.concat(chunk)))
end
io.write(string.dump(chunk))

Для предыдущего примера вы можете использовать его следующим образом:

$ luajit combine.lua l1.lua l2.lua l3.lua > out.ljc
$ luajit out.ljc
1   2
4 голосов
/ 07 марта 2012

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

После применения squish вы можете запустить результат через luac, чтобы получить байт-код. Однако байт-код часто больше исходного кода и почти наверняка больше, если в squish используется более агрессивный фильтр (например, gzip).

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

2 голосов
/ 12 июля 2014

После того, как я попробовал luac, luajit и squish, я обнаружил, что все они требуют, чтобы вы поддерживали список файлов для объединения. Это утомительно, когда работа над проектом содержит много файлов lua.

Итак, я написал небольшой инструмент для объединения файлов lua путем анализа require s

Вот оно: https://github.com/yi/node-lua-distiller

Надеюсь, это поможет.

0 голосов
/ 06 марта 2012

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

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

Обе функции могут обрабатывать как исходный код Lua, так и скомпилированный байт-код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...