aboutsummaryrefslogtreecommitdiff
path: root/src/host
diff options
context:
space:
mode:
Diffstat (limited to 'src/host')
-rw-r--r--src/host/buildvm_lib.c51
-rw-r--r--src/host/buildvm_libbc.h12
-rw-r--r--src/host/genlibbc.lua68
3 files changed, 131 insertions, 0 deletions
diff --git a/src/host/buildvm_lib.c b/src/host/buildvm_lib.c
index 40141dfb..182ab90f 100644
--- a/src/host/buildvm_lib.c
+++ b/src/host/buildvm_lib.c
@@ -6,6 +6,7 @@
6#include "buildvm.h" 6#include "buildvm.h"
7#include "lj_obj.h" 7#include "lj_obj.h"
8#include "lj_lib.h" 8#include "lj_lib.h"
9#include "buildvm_libbc.h"
9 10
10/* Context for library definitions. */ 11/* Context for library definitions. */
11static uint8_t obuf[8192]; 12static uint8_t obuf[8192];
@@ -151,6 +152,55 @@ static void libdef_func(BuildCtx *ctx, char *p, int arg)
151 regfunc = REGFUNC_OK; 152 regfunc = REGFUNC_OK;
152} 153}
153 154
155static uint32_t libdef_uleb128(uint8_t **pp)
156{
157 uint8_t *p = *pp;
158 uint32_t v = *p++;
159 if (v >= 0x80) {
160 int sh = 0; v &= 0x7f;
161 do { v |= ((*p & 0x7f) << (sh += 7)); } while (*p++ >= 0x80);
162 }
163 *pp = p;
164 return v;
165}
166
167static void libdef_swapbc(uint8_t *p)
168{
169 uint32_t i, sizebc;
170 p += 4;
171 libdef_uleb128(&p);
172 libdef_uleb128(&p);
173 sizebc = libdef_uleb128(&p);
174 for (i = 0; i < sizebc; i++, p += 4) {
175 uint8_t t = p[0]; p[0] = p[3]; p[3] = t;
176 t = p[1]; p[1] = p[2]; p[2] = t;
177 }
178}
179
180static void libdef_lua(BuildCtx *ctx, char *p, int arg)
181{
182 UNUSED(arg);
183 if (ctx->mode == BUILD_libdef) {
184 int i;
185 for (i = 0; libbc_map[i].name != NULL; i++) {
186 if (!strcmp(libbc_map[i].name, p)) {
187 int ofs = libbc_map[i].ofs;
188 int len = libbc_map[i+1].ofs - ofs;
189 obuf[2]++; /* Bump hash table size. */
190 *optr++ = LIBINIT_LUA;
191 libdef_name(p, 0);
192 memcpy(optr, libbc_code + ofs, len);
193 if (libbc_endian != LJ_BE)
194 libdef_swapbc(optr);
195 optr += len;
196 return;
197 }
198 }
199 fprintf(stderr, "Error: missing libbc definition for %s\n", p);
200 exit(1);
201 }
202}
203
154static uint32_t find_rec(char *name) 204static uint32_t find_rec(char *name)
155{ 205{
156 char *p = (char *)obuf; 206 char *p = (char *)obuf;
@@ -277,6 +327,7 @@ static const LibDefHandler libdef_handlers[] = {
277 { "CF(", ")", libdef_func, LIBINIT_CF }, 327 { "CF(", ")", libdef_func, LIBINIT_CF },
278 { "ASM(", ")", libdef_func, LIBINIT_ASM }, 328 { "ASM(", ")", libdef_func, LIBINIT_ASM },
279 { "ASM_(", ")", libdef_func, LIBINIT_ASM_ }, 329 { "ASM_(", ")", libdef_func, LIBINIT_ASM_ },
330 { "LUA(", ")", libdef_lua, 0 },
280 { "REC(", ")", libdef_rec, 0 }, 331 { "REC(", ")", libdef_rec, 0 },
281 { "PUSH(", ")", libdef_push, 0 }, 332 { "PUSH(", ")", libdef_push, 0 },
282 { "SET(", ")", libdef_set, 0 }, 333 { "SET(", ")", libdef_set, 0 },
diff --git a/src/host/buildvm_libbc.h b/src/host/buildvm_libbc.h
new file mode 100644
index 00000000..d2d83ea6
--- /dev/null
+++ b/src/host/buildvm_libbc.h
@@ -0,0 +1,12 @@
1/* This is a generated file. DO NOT EDIT! */
2
3static const int libbc_endian = 0;
4
5static const uint8_t libbc_code[] = {
60
7};
8
9static const struct { const char *name; int ofs; } libbc_map[] = {
10{NULL,0}
11};
12
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
9local function usage()
10 io.stderr:write("Usage: ", arg and arg[0] or "genlibbc", " lib_*.c\n")
11 os.exit(1)
12end
13
14local 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
23end
24
25local 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
37end
38
39local 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()
64end
65
66local src = read_source()
67local defs = find_defs(src)
68write_defs(io.stdout, defs)