diff options
Diffstat (limited to '')
-rw-r--r-- | src/host/genlibbc.lua | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/src/host/genlibbc.lua b/src/host/genlibbc.lua new file mode 100644 index 00000000..b0dbf17a --- /dev/null +++ b/src/host/genlibbc.lua | |||
@@ -0,0 +1,68 @@ | |||
1 | ---------------------------------------------------------------------------- | ||
2 | -- Lua script to dump the bytecode of the library functions written in Lua. | ||
3 | -- The resulting 'buildvm_libbc.h' is used for the build process of LuaJIT. | ||
4 | ---------------------------------------------------------------------------- | ||
5 | -- Copyright (C) 2005-2013 Mike Pall. All rights reserved. | ||
6 | -- Released under the MIT license. See Copyright Notice in luajit.h | ||
7 | ---------------------------------------------------------------------------- | ||
8 | |||
9 | local function usage() | ||
10 | io.stderr:write("Usage: ", arg and arg[0] or "genlibbc", " lib_*.c\n") | ||
11 | os.exit(1) | ||
12 | end | ||
13 | |||
14 | local function read_source() | ||
15 | if not (arg and arg[1]) then usage() end | ||
16 | local src = "" | ||
17 | for _,name in ipairs(arg) do | ||
18 | local fp = assert(io.open(name)) | ||
19 | src = src .. fp:read("*a") | ||
20 | fp:close() | ||
21 | end | ||
22 | return src | ||
23 | end | ||
24 | |||
25 | local function find_defs(src) | ||
26 | local defs = {} | ||
27 | for name, code in string.gmatch(src, "LJLIB_LUA%(([^)]*)%)%s*/%*(.-)%*/") do | ||
28 | local env = {} | ||
29 | local func = assert(load("return "..code, "", nil, env))() | ||
30 | local d = string.dump(func, true) | ||
31 | local ofs = 6 | ||
32 | while string.byte(d, ofs) > 127 do ofs = ofs + 1 end | ||
33 | defs[name] = string.sub(d, ofs+1, -2) | ||
34 | defs[#defs+1] = name | ||
35 | end | ||
36 | return defs | ||
37 | end | ||
38 | |||
39 | local function write_defs(fp, defs) | ||
40 | fp:write("/* This is a generated file. DO NOT EDIT! */\n\n") | ||
41 | fp:write("static const int libbc_endian = ", | ||
42 | string.byte(string.dump(function() end), 5) % 2, ";\n\n") | ||
43 | local s = "" | ||
44 | for _,name in ipairs(defs) do | ||
45 | s = s .. defs[name] | ||
46 | end | ||
47 | fp:write("static const uint8_t libbc_code[] = {\n") | ||
48 | local n = 0 | ||
49 | for i=1,#s do | ||
50 | local x = string.byte(s, i) | ||
51 | fp:write(x, ",") | ||
52 | n = n + (x < 10 and 2 or (x < 100 and 3 or 4)) | ||
53 | if n >= 75 then n = 0; fp:write("\n") end | ||
54 | end | ||
55 | fp:write("0\n};\n\n") | ||
56 | fp:write("static const struct { const char *name; int ofs; } libbc_map[] = {\n") | ||
57 | local m = 0 | ||
58 | for _,name in ipairs(defs) do | ||
59 | fp:write('{"', name, '",', m, '},\n') | ||
60 | m = m + #defs[name] | ||
61 | end | ||
62 | fp:write("{NULL,", m, "}\n};\n\n") | ||
63 | fp:flush() | ||
64 | end | ||
65 | |||
66 | local src = read_source() | ||
67 | local defs = find_defs(src) | ||
68 | write_defs(io.stdout, defs) | ||