aboutsummaryrefslogtreecommitdiff
path: root/src/host
diff options
context:
space:
mode:
Diffstat (limited to 'src/host')
-rw-r--r--src/host/buildvm_lib.c32
-rw-r--r--src/host/buildvm_libbc.h4
-rw-r--r--src/host/genlibbc.lua108
3 files changed, 122 insertions, 22 deletions
diff --git a/src/host/buildvm_lib.c b/src/host/buildvm_lib.c
index 182ab90f..dcd3ca41 100644
--- a/src/host/buildvm_lib.c
+++ b/src/host/buildvm_lib.c
@@ -5,6 +5,7 @@
5 5
6#include "buildvm.h" 6#include "buildvm.h"
7#include "lj_obj.h" 7#include "lj_obj.h"
8#include "lj_bc.h"
8#include "lj_lib.h" 9#include "lj_lib.h"
9#include "buildvm_libbc.h" 10#include "buildvm_libbc.h"
10 11
@@ -152,28 +153,36 @@ static void libdef_func(BuildCtx *ctx, char *p, int arg)
152 regfunc = REGFUNC_OK; 153 regfunc = REGFUNC_OK;
153} 154}
154 155
155static uint32_t libdef_uleb128(uint8_t **pp) 156static uint8_t *libdef_uleb128(uint8_t *p, uint32_t *vv)
156{ 157{
157 uint8_t *p = *pp;
158 uint32_t v = *p++; 158 uint32_t v = *p++;
159 if (v >= 0x80) { 159 if (v >= 0x80) {
160 int sh = 0; v &= 0x7f; 160 int sh = 0; v &= 0x7f;
161 do { v |= ((*p & 0x7f) << (sh += 7)); } while (*p++ >= 0x80); 161 do { v |= ((*p & 0x7f) << (sh += 7)); } while (*p++ >= 0x80);
162 } 162 }
163 *pp = p; 163 *vv = v;
164 return v; 164 return p;
165} 165}
166 166
167static void libdef_swapbc(uint8_t *p) 167static void libdef_fixupbc(uint8_t *p)
168{ 168{
169 uint32_t i, sizebc; 169 uint32_t i, sizebc;
170 p += 4; 170 p += 4;
171 libdef_uleb128(&p); 171 p = libdef_uleb128(p, &sizebc);
172 libdef_uleb128(&p); 172 p = libdef_uleb128(p, &sizebc);
173 sizebc = libdef_uleb128(&p); 173 p = libdef_uleb128(p, &sizebc);
174 for (i = 0; i < sizebc; i++, p += 4) { 174 for (i = 0; i < sizebc; i++, p += 4) {
175 uint8_t t = p[0]; p[0] = p[3]; p[3] = t; 175 uint8_t op = p[libbc_endian ? 3 : 0];
176 t = p[1]; p[1] = p[2]; p[2] = t; 176 uint8_t ra = p[libbc_endian ? 2 : 1];
177 uint8_t rc = p[libbc_endian ? 1 : 2];
178 uint8_t rb = p[libbc_endian ? 0 : 3];
179 if (!LJ_DUALNUM && op == BC_ISTYPE && rc == ~LJ_TNUMX+1) {
180 op = BC_ISNUM; rc++;
181 }
182 p[LJ_ENDIAN_SELECT(0, 3)] = op;
183 p[LJ_ENDIAN_SELECT(1, 2)] = ra;
184 p[LJ_ENDIAN_SELECT(2, 1)] = rc;
185 p[LJ_ENDIAN_SELECT(3, 0)] = rb;
177 } 186 }
178} 187}
179 188
@@ -190,8 +199,7 @@ static void libdef_lua(BuildCtx *ctx, char *p, int arg)
190 *optr++ = LIBINIT_LUA; 199 *optr++ = LIBINIT_LUA;
191 libdef_name(p, 0); 200 libdef_name(p, 0);
192 memcpy(optr, libbc_code + ofs, len); 201 memcpy(optr, libbc_code + ofs, len);
193 if (libbc_endian != LJ_BE) 202 libdef_fixupbc(optr);
194 libdef_swapbc(optr);
195 optr += len; 203 optr += len;
196 return; 204 return;
197 } 205 }
diff --git a/src/host/buildvm_libbc.h b/src/host/buildvm_libbc.h
index ee97836a..6b0e1d03 100644
--- a/src/host/buildvm_libbc.h
+++ b/src/host/buildvm_libbc.h
@@ -3,8 +3,8 @@
3static const int libbc_endian = 0; 3static const int libbc_endian = 0;
4 4
5static const uint8_t libbc_code[] = { 5static const uint8_t libbc_code[] = {
60,1,2,0,0,1,2,22,1,0,0,72,1,2,0,241,135,158,166,3,220,203,178,130,4,0,1,2,0, 60,1,2,0,0,1,2,24,1,0,0,76,1,2,0,241,135,158,166,3,220,203,178,130,4,0,1,2,0,
70,1,2,22,1,0,0,72,1,2,0,243,244,148,165,20,198,190,199,252,3,0 70,1,2,24,1,0,0,76,1,2,0,243,244,148,165,20,198,190,199,252,3,0
8}; 8};
9 9
10static const struct { const char *name; int ofs; } libbc_map[] = { 10static const struct { const char *name; int ofs; } libbc_map[] = {
diff --git a/src/host/genlibbc.lua b/src/host/genlibbc.lua
index bdcfb588..72c55d73 100644
--- a/src/host/genlibbc.lua
+++ b/src/host/genlibbc.lua
@@ -6,6 +6,15 @@
6-- Released under the MIT license. See Copyright Notice in luajit.h 6-- Released under the MIT license. See Copyright Notice in luajit.h
7---------------------------------------------------------------------------- 7----------------------------------------------------------------------------
8 8
9local ffi = require("ffi")
10local bit = require("bit")
11local vmdef = require("jit.vmdef")
12local bcnames = vmdef.bcnames
13
14local format = string.format
15
16local isbe = (string.byte(string.dump(function() end), 5) % 2 == 1)
17
9local function usage(arg) 18local function usage(arg)
10 io.stderr:write("Usage: ", arg and arg[0] or "genlibbc", 19 io.stderr:write("Usage: ", arg and arg[0] or "genlibbc",
11 " [-o buildvm_libbc.h] lib_*.c\n") 20 " [-o buildvm_libbc.h] lib_*.c\n")
@@ -36,15 +45,100 @@ local function read_files(names)
36 return src 45 return src
37end 46end
38 47
48local function transform_lua(code)
49 local fixup = {}
50 local n = -30000
51 code = string.gsub(code, "CHECK_(%w*)%((.-)%)", function(tp, var)
52 n = n + 1
53 fixup[n] = { "CHECK", tp }
54 return format("%s=%d", var, n)
55 end)
56 code = string.gsub(code, "PAIRS%((.-)%)", function(var)
57 fixup.PAIRS = true
58 return format("nil, %s, 0", var)
59 end)
60 return "return "..code, fixup
61end
62
63local function read_uleb128(p)
64 local v = p[0]; p = p + 1
65 if v >= 128 then
66 local sh = 7; v = v - 128
67 repeat
68 local r = p[0]
69 v = v + bit.lshift(bit.band(r, 128), sh)
70 sh = sh + 7
71 p = p + 1
72 until r < 128
73 end
74 return p, v
75end
76
77-- ORDER LJ_T
78local name2itype = {
79 str = 5, func = 9, tab = 12, int = 14, num = 15
80}
81
82local BC = {}
83for i=0,#bcnames/6-1 do
84 BC[string.gsub(string.sub(bcnames, i*6+1, i*6+6), " ", "")] = i
85end
86local xop, xra = isbe and 3 or 0, isbe and 2 or 1
87local xrc, xrb = isbe and 1 or 2, isbe and 0 or 3
88
89local function fixup_dump(dump, fixup)
90 local buf = ffi.new("uint8_t[?]", #dump+1, dump)
91 local p = buf+5
92 local n, sizebc
93 p, n = read_uleb128(p)
94 local start = p
95 p = p + 4
96 p = read_uleb128(p)
97 p = read_uleb128(p)
98 p, sizebc = read_uleb128(p)
99 local rawtab = {}
100 for i=0,sizebc-1 do
101 local op = p[xop]
102 if op == BC.KSHORT then
103 local rd = p[xrc] + 256*p[xrb]
104 rd = bit.arshift(bit.lshift(rd, 16), 16)
105 local f = fixup[rd]
106 if f then
107 if f[1] == "CHECK" then
108 local tp = f[2]
109 if tp == "tab" then rawtab[p[xra]] = true end
110 p[xop] = tp == "num" and BC.ISNUM or BC.ISTYPE
111 p[xrb] = 0
112 p[xrc] = name2itype[tp]
113 else
114 error("unhandled fixup type: "..f[1])
115 end
116 end
117 elseif op == BC.TGETV then
118 if rawtab[p[xrb]] then
119 p[xop] = BC.TGETR
120 end
121 elseif op == BC.TSETV then
122 if rawtab[p[xrb]] then
123 p[xop] = BC.TSETR
124 end
125 elseif op == BC.ITERC then
126 if fixup.PAIRS then
127 p[xop] = BC.ITERN
128 end
129 end
130 p = p + 4
131 end
132 return ffi.string(start, n)
133end
134
39local function find_defs(src) 135local function find_defs(src)
40 local defs = {} 136 local defs = {}
41 for name, code in string.gmatch(src, "LJLIB_LUA%(([^)]*)%)%s*/%*(.-)%*/") do 137 for name, code in string.gmatch(src, "LJLIB_LUA%(([^)]*)%)%s*/%*(.-)%*/") do
42 local env = {} 138 local env = {}
43 local func = assert(load("return "..code, "", nil, env))() 139 local tcode, fixup = transform_lua(code)
44 local d = string.dump(func, true) 140 local func = assert(load(tcode, "", nil, env))()
45 local ofs = 6 141 defs[name] = fixup_dump(string.dump(func, true), fixup)
46 while string.byte(d, ofs) > 127 do ofs = ofs + 1 end
47 defs[name] = string.sub(d, ofs+1, -2)
48 defs[#defs+1] = name 142 defs[#defs+1] = name
49 end 143 end
50 return defs 144 return defs
@@ -54,9 +148,7 @@ local function gen_header(defs)
54 local t = {} 148 local t = {}
55 local function w(x) t[#t+1] = x end 149 local function w(x) t[#t+1] = x end
56 w("/* This is a generated file. DO NOT EDIT! */\n\n") 150 w("/* This is a generated file. DO NOT EDIT! */\n\n")
57 w("static const int libbc_endian = ") 151 w("static const int libbc_endian = ") w(isbe and 1 or 0) w(";\n\n")
58 w(string.byte(string.dump(function() end), 5) % 2)
59 w(";\n\n")
60 local s = "" 152 local s = ""
61 for _,name in ipairs(defs) do 153 for _,name in ipairs(defs) do
62 s = s .. defs[name] 154 s = s .. defs[name]