2012-03-06 29 views
14

Tôi đã nhúng lua cùng với một đoạn mã bytecode vào một dự án được viết bằng C. Bây giờ khi tôi mở rộng cơ sở mã lua của tôi bằng cách thêm các tệp .lua, có cách nào để giữ mã này trong một đoạn mã bytecode không?Giữ mọi thứ trong một đoạn mã bytecode đơn lẻ?

(Tôi biết làm thế nào để tải nhiều khối bytecode. Nhưng làm cho nó tải một đoạn duy nhất và sau đó quên về mã keo sẽ chỉ có vẻ thoải mái.)

Tôi cố gắng để sử dụng bao gồm văn bản, nhưng có vẻ như không có từ khóa cho điều này trong Lua. "Yêu cầu" và "dofile" xem các tệp tại thời gian chạy, do đó kết quả bytecode sau khi chạy "lua -b ..." sẽ không bao gồm mã của các tệp đó.

Và không có cách nào để kết hợp các tệp bytecode, phải không? Ý tôi là, khi tạo một tệp bytecode, lệnh "require" sẽ thêm mã của tất cả các tệp đó vào một tệp bytecode.

PS: Câu trả lời của Michal Kottman hoạt động cho Lua, đó là những gì tôi yêu cầu. Tôi nghĩ Lua và LuaJIT sẽ làm việc theo cùng một cách. Họ không. Để kết hợp nhiều file .lua cho tập tin bytecode một LuaJIT, nên một

  • sử dụng "LuaJIT -b" (dường như không làm việc)
  • biên dịch luac.c Lua với nguồn LuaJIT
  • thi đua luac.c với lệnh lua (không có API C)?
+0

Đây là câu trả lời có thể về chủ đề và hữu ích. http://stackoverflow.com/questions/8936369/compile-lua-code-store-bytecode-then-load-and-execute-it –

Trả lời

11

Bạn có thể kết hợp nhiều tệp vào một tệp bằng cách sử dụng luac. Khi chạy, tất cả các khối từ các tập tin nguồn được thực hiện theo thứ tự chúng được thêm vào tập tin biên soạn:

$ 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 

Bạn có thể tải tập tin này vào Lua từ C sử dụng luaL_loadfile, mà đặt một hàm trên đỉnh ngăn xếp nếu nó nạp thành công. Sau đó, bạn chỉ có thể chạy hàm này bằng cách sử dụng lua_call để chạy tất cả các tệp được biên dịch kết hợp.

Lưu ý rằng bạn có thể nhúng nội dung của tệp được biên dịch dưới dạng chuỗi vào dự án của bạn, không cần giữ nó trong tệp bên ngoài.

Cập nhật cho LuaJIT 2

Như các bạn đã tìm thấy, bạn có thể sử dụng Lua Compiler in Lua để có được một tập tin kết hợp mà có thể được nạp như đã nói trước đây.Đây là một phiên bản đơn giản, mà kết quả đầu ra để 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)) 

Đối với mẫu trước đó, bạn có thể sử dụng nó như sau:

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

Rất cám ơn! Tốt rằng với bản gốc Lua này sẽ làm việc. Tôi đang cố gắng để đạt được cùng với luaJIT, bằng cách sử dụng "luajit -b" và một số tập tin, nhưng không thể làm cho nó được thực hiện ở đó. Không có luac.c trong luaJIT và định dạng bytecode khác nhau, vì vậy tôi tự hỏi nếu cách này có thể làm việc với luaJIT quá. Có thể bằng cách mô phỏng luac như ở đây http://lua-users.org/wiki/LuaCompilerInLua. – John

+0

Theo http://lua-users.org/lists/lua-l/2005-12/msg00209.html luac.c này cũng sẽ hoạt động với luaJIT. – John

+0

Lưu ý rằng đó là LuaJIT 1, có khả năng đọc mã byte Lua tiêu chuẩn. LuaJIT 2 mới hơn có bytecode không tương thích. –

0

loadstring là những gì bạn đang tìm kiếm. Phải mất một chuỗi và tải nếu (sau khi biên dịch nó thành mã byte nếu cần). Nó kết quả trong một hàm có thể được thực hiện để chạy mã chứa sau đó.

Nếu bạn vẫn cần một cái gì đó tổng quát hơn, hãy nhìn vào load cho phép bạn chỉ định một chức năng để nuôi các khối trong.

Cả hai chức năng có thể xử lý cả hai mã nguồn Lua và mã byte biên soạn.

+0

Tôi đã thử nó, tôi thấy cách nó hoạt động, nhưng không phải cách tôi có thể tạo ra một đĩa đơn đoạn có chứa cả đoạn tải và đoạn tải. Bạn có thể đưa ra một ví dụ không? Tôi đang tìm một cái gì đó như (khi làm việc với C) tạo ra một tập tin thư viện duy nhất từ ​​các tập tin đối tượng, vì vậy bạn không cần phải liên kết với mọi tập tin đối tượng. Chỉ cần như thế này, nhưng đối với Lua, do đó tôi chỉ cần nhúng một tài nguyên vào tệp thực thi của mình. – John

+0

Tôi hiểu. Có lẽ liên kết này có thể giúp bạn thêm: [Lua Compiler in Lua] (http://lua-users.org/wiki/LuaCompilerInLua) – jpjacobs

+0

Cảm ơn rất nhiều, đây có lẽ là cách duy nhất với luaJIT, vì không có luac. – John

4

Một lựa chọn khác là sử dụng một công cụ như Mathew Wild squish để thu thập tất cả các nguồn Lua của bạn thành một tệp .lua. Một tính năng tuyệt vời của squish là nó hỗ trợ nhiều bộ lọc khác nhau để giúp làm cho gói nhỏ hơn tổng số tệp nguồn.

Sau khi áp dụng squish, bạn có thể chạy kết quả qua luac để nhận bytecode. Tuy nhiên, bytecode thường lớn hơn mã nguồn, và gần như chắc chắn lớn hơn nếu một bộ lọc tích cực hơn (chẳng hạn như gzip) được sử dụng trong squish.

Nếu tệp bytecode của bạn được lưu trữ riêng biệt với tệp thực thi (hoặc tệ hơn, được truyền qua mạng), tôi cũng sẽ đưa ra các vấn đề bảo mật liên quan đến bytecode không áp dụng cho mã nguồn Lua. Tuy nhiên, bytecode được liên kết trong một ứng dụng sẽ khó phá vỡ hơn vì mã bytecode độc ​​hại sẽ không bao giờ là kết quả của việc chạy luac.

2

Sau khi thử luac, luajit và squish, tôi thấy tất cả chúng yêu cầu bạn duy trì một danh sách tệp để kết hợp. Đó là mệt mỏi khi làm việc trên một dự án có chứa nhiều tập tin lua.

Vì vậy, tôi đã viết một công cụ nhỏ để merge lua file bằng cách phân tích require s

Ở đây là: https://github.com/yi/node-lua-distiller

Hy vọng nó sẽ hữu ích.

Các vấn đề liên quan