diff options
author | Mike Pall <mike> | 2013-02-22 01:40:41 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2013-02-22 01:40:41 +0100 |
commit | e20157c6e68472e7c4d82d9ed4c0bb5be029c388 (patch) | |
tree | b26bfadc10b7301d73b84293630c44e7d1fb37f9 /src/host/buildvm_lib.c | |
parent | c3219b7d177f6722b9de808cfd3d3dbfc6808e6f (diff) | |
download | luajit-e20157c6e68472e7c4d82d9ed4c0bb5be029c388.tar.gz luajit-e20157c6e68472e7c4d82d9ed4c0bb5be029c388.tar.bz2 luajit-e20157c6e68472e7c4d82d9ed4c0bb5be029c388.zip |
Add support for embedding LuaJIT bytecode for builtins.
Diffstat (limited to 'src/host/buildvm_lib.c')
-rw-r--r-- | src/host/buildvm_lib.c | 51 |
1 files changed, 51 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. */ |
11 | static uint8_t obuf[8192]; | 12 | static 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 | ||
155 | static 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 | |||
167 | static 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 | |||
180 | static 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 | |||
154 | static uint32_t find_rec(char *name) | 204 | static 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 }, |