summaryrefslogtreecommitdiff
path: root/src/host/buildvm_lib.c
diff options
context:
space:
mode:
authorMike Pall <mike>2013-02-22 01:40:41 +0100
committerMike Pall <mike>2013-02-22 01:40:41 +0100
commite20157c6e68472e7c4d82d9ed4c0bb5be029c388 (patch)
treeb26bfadc10b7301d73b84293630c44e7d1fb37f9 /src/host/buildvm_lib.c
parentc3219b7d177f6722b9de808cfd3d3dbfc6808e6f (diff)
downloadluajit-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.c51
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. */
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 },