2012-03-06 6 views
14

Ho incorporato lua insieme a un byte byte del codice in un progetto scritto in C. Ora, quando estendo il mio codice code lua aggiungendo i file .lua, c'è un modo per mantenere questo codice in un unico byte bytecode?Mantenere tutto in un unico byte bytecode lua?

(So come caricare più pezzi bytecode. Ma fare è caricare un singolo pezzo e poi dimenticare il codice collante sarebbe solo sembrare comodo.)

Ho cercato di usare l'inserimento testuale, ma sembra che non c'è parola chiave per questo in Lua. "Require" e "dofile" guardano i file in fase di esecuzione, quindi il bytecode risultante dopo aver eseguito "lua -b ..." non includerà il codice di quei file.

E non c'è modo di combinare i file bytecode, vero? Intendo dire che, quando si crea un file bytecode, il comando "richiede" aggiungerebbe il codice di tutti quei file in un unico file bytecode.

PS: la risposta di Michal Kottman funziona per Lua, che è quello che ho chiesto. Pensavo che Lua e LuaJIT avrebbero funzionato allo stesso modo. Non lo fanno. Per combinare più file in un file bytecode .lua una LuaJIT, dovrebbe uno

  • uso "LuaJIT -b" (non sembra funzionare)
  • compilare luac.c di Lua con le fonti LuaJIT
  • emulare luac.c con comandi lua (senza C API)?
+0

Ecco una risposta che potrebbe essere in argomento e utile. http://stackoverflow.com/questions/8936369/compile-lua-code-store-bytecode-then-load-and-execute-it –

risposta

11

È possibile combinare più file in un unico file utilizzando luac. Quando viene eseguito, tutti i pezzi dai file di origine vengono eseguiti nell'ordine in cui sono stati aggiunti al file compilato:

$ 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 

È possibile caricare questo file in Lua da C utilizzando luaL_loadfile, che pone una funzione sulla parte superiore della lo stack se è stato caricato con successo. Quindi è possibile eseguire questa funzione utilizzando lua_call per eseguire tutti i file compilati combinati.

Si noti che è possibile incorporare il contenuto del file compilato come una stringa nel progetto, non è necessario conservarlo in un file esterno.

Aggiornamento per LuaJIT 2

Come hai trovato, è possibile utilizzare il Lua Compiler in Lua per ottenere un file combinato che può essere caricato come indicato in precedenza.Questa è una versione semplificata, che fornisce in uscita a stdout:

-- 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)) 

Per il campione precedente, è possibile utilizzarlo come segue:

$ luajit combine.lua l1.lua l2.lua l3.lua > out.ljc 
$ luajit out.ljc 
1 2 
+0

Mille grazie! Bene che con la Lua originale questo funzionerà. Sto cercando di ottenere lo stesso con luaJIT, usando "luajit -b" e diversi file, ma non ho potuto farlo lì. Non c'è luac.c in luaJIT e il formato bytecode è diverso, quindi mi chiedo se questo metodo possa funzionare anche con luaJIT. Forse emulando luac come qui http://lua-users.org/wiki/LuaCompilerInLua. – John

+0

Secondo questo http://lua-users.org/lists/lua-l/2005-12/msg00209.html luac.c funzionerà anche con luaJIT. – John

+0

Si noti che è LuaJIT 1, in grado di leggere il bytecode Lua standard. Il nuovo LuaJIT 2 ha un bytecode incompatibile. –

0

loadstring è quello che stai cercando. Prende una stringa e carica se (dopo averlo compilato in byte code se necessario). Risulta in una funzione che può essere eseguita per eseguire successivamente il codice contenuto.

Se hai ancora bisogno di qualcosa di più generale, un'occhiata a load che consente di specificare una funzione per alimentare i pezzi in.

Entrambe le funzioni in grado di elaborare sia codice sorgente Lua e byte di codice compilato.

+0

Ho provato, vedo come funziona, ma non come potrei creare un singolo blocco che contiene sia il blocco di caricamento che il blocco caricato. Puoi fare un esempio? Sto cercando qualcosa di simile (quando si lavora con C) creando un singolo file di libreria da file oggetto, quindi non è necessario collegarsi a tutti i file oggetto. Proprio così, ma per Lua, così ho bisogno di incorporare solo una risorsa nel mio eseguibile. – John

+0

Capisco. Forse questo link può aiutarti ulteriormente: [Lua Compiler in Lua] (http://lua-users.org/wiki/LuaCompilerInLua) – jpjacobs

+0

Grazie mille, questo è forse l'unico modo con luaJIT, dal momento che non c'è luac. – John

4

Un'altra alternativa è quella di utilizzare uno strumento come Mathew selvaggio di squish per raccogliere tutte le tue sorgenti Lua in un unico file .lua. Una bella caratteristica di squish è che supporta una varietà di filtri per rendere il pacchetto più piccolo più piccolo rispetto al totale dei file sorgente.

Dopo aver applicato lo squish, è possibile eseguire il risultato tramite luac per ottenere il bytecode. Tuttavia, il bytecode è spesso più grande del codice sorgente e quasi certamente più grande se viene utilizzato un filtro più aggressivo (ad esempio gzip) in squish.

Se il file bytecode è stato memorizzato separatamente dall'eseguibile (o, peggio, trasmesso attraverso la rete), vorrei anche sollevare problemi di sicurezza relativi al bytecode che non si applicano al codice sorgente Lua. Tuttavia, il bytecode collegato a un'applicazione è molto più difficile da sovvertire poiché il bytecode dannoso non sarà mai il risultato dell'esecuzione di luac.

2

Dopo aver provato luac, luajit e squish, ho trovato che tutti richiedono di mantenere un elenco di file da combinare. È faticoso quando si lavora su un progetto che contiene molti file lua.

così ho scritto un piccolo strumento per unire i file lua analizzando require s

Eccolo: https://github.com/yi/node-lua-distiller

speranza che utile.