mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
Add support for embedding LuaJIT bytecode for builtins.
This commit is contained in:
parent
c3219b7d17
commit
e20157c6e6
@ -558,6 +558,10 @@ amalg:
|
|||||||
clean:
|
clean:
|
||||||
$(HOST_RM) $(ALL_RM)
|
$(HOST_RM) $(ALL_RM)
|
||||||
|
|
||||||
|
libbc:
|
||||||
|
./$(LUAJIT_T) host/genlibbc.lua $(LJLIB_C) >host/buildvm_libbc.h
|
||||||
|
$(MAKE) all
|
||||||
|
|
||||||
depend:
|
depend:
|
||||||
@for file in $(ALL_HDRGEN); do \
|
@for file in $(ALL_HDRGEN); do \
|
||||||
test -f $$file || touch $$file; \
|
test -f $$file || touch $$file; \
|
||||||
@ -572,7 +576,7 @@ depend:
|
|||||||
test -s $$file || $(HOST_RM) $$file; \
|
test -s $$file || $(HOST_RM) $$file; \
|
||||||
done
|
done
|
||||||
|
|
||||||
.PHONY: default all amalg clean depend
|
.PHONY: default all amalg clean libbc depend
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# Rules for generated files.
|
# Rules for generated files.
|
||||||
|
@ -124,7 +124,8 @@ lj_lex.o: lj_lex.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
|
|||||||
lj_state.h lj_lex.h lj_parse.h lj_char.h lj_strscan.h
|
lj_state.h lj_lex.h lj_parse.h lj_char.h lj_strscan.h
|
||||||
lj_lib.o: lj_lib.c lauxlib.h lua.h luaconf.h lj_obj.h lj_def.h lj_arch.h \
|
lj_lib.o: lj_lib.c lauxlib.h lua.h luaconf.h lj_obj.h lj_def.h lj_arch.h \
|
||||||
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h lj_bc.h \
|
lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_func.h lj_bc.h \
|
||||||
lj_dispatch.h lj_jit.h lj_ir.h lj_vm.h lj_strscan.h lj_lib.h
|
lj_dispatch.h lj_jit.h lj_ir.h lj_vm.h lj_strscan.h lj_lex.h lj_bcdump.h \
|
||||||
|
lj_lib.h
|
||||||
lj_load.o: lj_load.c lua.h luaconf.h lauxlib.h lj_obj.h lj_def.h \
|
lj_load.o: lj_load.c lua.h luaconf.h lauxlib.h lj_obj.h lj_def.h \
|
||||||
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_func.h lj_frame.h \
|
lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_func.h lj_frame.h \
|
||||||
lj_bc.h lj_vm.h lj_lex.h lj_bcdump.h lj_parse.h
|
lj_bc.h lj_vm.h lj_lex.h lj_bcdump.h lj_parse.h
|
||||||
@ -220,7 +221,8 @@ host/buildvm_asm.o: host/buildvm_asm.c host/buildvm.h lj_def.h lua.h luaconf.h \
|
|||||||
host/buildvm_fold.o: host/buildvm_fold.c host/buildvm.h lj_def.h lua.h \
|
host/buildvm_fold.o: host/buildvm_fold.c host/buildvm.h lj_def.h lua.h \
|
||||||
luaconf.h lj_arch.h lj_obj.h lj_def.h lj_arch.h lj_ir.h lj_obj.h
|
luaconf.h lj_arch.h lj_obj.h lj_def.h lj_arch.h lj_ir.h lj_obj.h
|
||||||
host/buildvm_lib.o: host/buildvm_lib.c host/buildvm.h lj_def.h lua.h luaconf.h \
|
host/buildvm_lib.o: host/buildvm_lib.c host/buildvm.h lj_def.h lua.h luaconf.h \
|
||||||
lj_arch.h lj_obj.h lj_def.h lj_arch.h lj_lib.h lj_obj.h
|
lj_arch.h lj_obj.h lj_def.h lj_arch.h lj_lib.h lj_obj.h \
|
||||||
|
host/buildvm_libbc.h
|
||||||
host/buildvm_peobj.o: host/buildvm_peobj.c host/buildvm.h lj_def.h lua.h \
|
host/buildvm_peobj.o: host/buildvm_peobj.c host/buildvm.h lj_def.h lua.h \
|
||||||
luaconf.h lj_arch.h lj_bc.h lj_def.h lj_arch.h
|
luaconf.h lj_arch.h lj_bc.h lj_def.h lj_arch.h
|
||||||
host/minilua.o: host/minilua.c
|
host/minilua.o: host/minilua.c
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "buildvm.h"
|
#include "buildvm.h"
|
||||||
#include "lj_obj.h"
|
#include "lj_obj.h"
|
||||||
#include "lj_lib.h"
|
#include "lj_lib.h"
|
||||||
|
#include "buildvm_libbc.h"
|
||||||
|
|
||||||
/* Context for library definitions. */
|
/* Context for library definitions. */
|
||||||
static uint8_t obuf[8192];
|
static uint8_t obuf[8192];
|
||||||
@ -151,6 +152,55 @@ static void libdef_func(BuildCtx *ctx, char *p, int arg)
|
|||||||
regfunc = REGFUNC_OK;
|
regfunc = REGFUNC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t libdef_uleb128(uint8_t **pp)
|
||||||
|
{
|
||||||
|
uint8_t *p = *pp;
|
||||||
|
uint32_t v = *p++;
|
||||||
|
if (v >= 0x80) {
|
||||||
|
int sh = 0; v &= 0x7f;
|
||||||
|
do { v |= ((*p & 0x7f) << (sh += 7)); } while (*p++ >= 0x80);
|
||||||
|
}
|
||||||
|
*pp = p;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void libdef_swapbc(uint8_t *p)
|
||||||
|
{
|
||||||
|
uint32_t i, sizebc;
|
||||||
|
p += 4;
|
||||||
|
libdef_uleb128(&p);
|
||||||
|
libdef_uleb128(&p);
|
||||||
|
sizebc = libdef_uleb128(&p);
|
||||||
|
for (i = 0; i < sizebc; i++, p += 4) {
|
||||||
|
uint8_t t = p[0]; p[0] = p[3]; p[3] = t;
|
||||||
|
t = p[1]; p[1] = p[2]; p[2] = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void libdef_lua(BuildCtx *ctx, char *p, int arg)
|
||||||
|
{
|
||||||
|
UNUSED(arg);
|
||||||
|
if (ctx->mode == BUILD_libdef) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; libbc_map[i].name != NULL; i++) {
|
||||||
|
if (!strcmp(libbc_map[i].name, p)) {
|
||||||
|
int ofs = libbc_map[i].ofs;
|
||||||
|
int len = libbc_map[i+1].ofs - ofs;
|
||||||
|
obuf[2]++; /* Bump hash table size. */
|
||||||
|
*optr++ = LIBINIT_LUA;
|
||||||
|
libdef_name(p, 0);
|
||||||
|
memcpy(optr, libbc_code + ofs, len);
|
||||||
|
if (libbc_endian != LJ_BE)
|
||||||
|
libdef_swapbc(optr);
|
||||||
|
optr += len;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf(stderr, "Error: missing libbc definition for %s\n", p);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t find_rec(char *name)
|
static uint32_t find_rec(char *name)
|
||||||
{
|
{
|
||||||
char *p = (char *)obuf;
|
char *p = (char *)obuf;
|
||||||
@ -277,6 +327,7 @@ static const LibDefHandler libdef_handlers[] = {
|
|||||||
{ "CF(", ")", libdef_func, LIBINIT_CF },
|
{ "CF(", ")", libdef_func, LIBINIT_CF },
|
||||||
{ "ASM(", ")", libdef_func, LIBINIT_ASM },
|
{ "ASM(", ")", libdef_func, LIBINIT_ASM },
|
||||||
{ "ASM_(", ")", libdef_func, LIBINIT_ASM_ },
|
{ "ASM_(", ")", libdef_func, LIBINIT_ASM_ },
|
||||||
|
{ "LUA(", ")", libdef_lua, 0 },
|
||||||
{ "REC(", ")", libdef_rec, 0 },
|
{ "REC(", ")", libdef_rec, 0 },
|
||||||
{ "PUSH(", ")", libdef_push, 0 },
|
{ "PUSH(", ")", libdef_push, 0 },
|
||||||
{ "SET(", ")", libdef_set, 0 },
|
{ "SET(", ")", libdef_set, 0 },
|
||||||
|
12
src/host/buildvm_libbc.h
Normal file
12
src/host/buildvm_libbc.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
/* This is a generated file. DO NOT EDIT! */
|
||||||
|
|
||||||
|
static const int libbc_endian = 0;
|
||||||
|
|
||||||
|
static const uint8_t libbc_code[] = {
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct { const char *name; int ofs; } libbc_map[] = {
|
||||||
|
{NULL,0}
|
||||||
|
};
|
||||||
|
|
68
src/host/genlibbc.lua
Normal file
68
src/host/genlibbc.lua
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
----------------------------------------------------------------------------
|
||||||
|
-- Lua script to dump the bytecode of the library functions written in Lua.
|
||||||
|
-- The resulting 'buildvm_libbc.h' is used for the build process of LuaJIT.
|
||||||
|
----------------------------------------------------------------------------
|
||||||
|
-- Copyright (C) 2005-2013 Mike Pall. All rights reserved.
|
||||||
|
-- Released under the MIT license. See Copyright Notice in luajit.h
|
||||||
|
----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
local function usage()
|
||||||
|
io.stderr:write("Usage: ", arg and arg[0] or "genlibbc", " lib_*.c\n")
|
||||||
|
os.exit(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function read_source()
|
||||||
|
if not (arg and arg[1]) then usage() end
|
||||||
|
local src = ""
|
||||||
|
for _,name in ipairs(arg) do
|
||||||
|
local fp = assert(io.open(name))
|
||||||
|
src = src .. fp:read("*a")
|
||||||
|
fp:close()
|
||||||
|
end
|
||||||
|
return src
|
||||||
|
end
|
||||||
|
|
||||||
|
local function find_defs(src)
|
||||||
|
local defs = {}
|
||||||
|
for name, code in string.gmatch(src, "LJLIB_LUA%(([^)]*)%)%s*/%*(.-)%*/") do
|
||||||
|
local env = {}
|
||||||
|
local func = assert(load("return "..code, "", nil, env))()
|
||||||
|
local d = string.dump(func, true)
|
||||||
|
local ofs = 6
|
||||||
|
while string.byte(d, ofs) > 127 do ofs = ofs + 1 end
|
||||||
|
defs[name] = string.sub(d, ofs+1, -2)
|
||||||
|
defs[#defs+1] = name
|
||||||
|
end
|
||||||
|
return defs
|
||||||
|
end
|
||||||
|
|
||||||
|
local function write_defs(fp, defs)
|
||||||
|
fp:write("/* This is a generated file. DO NOT EDIT! */\n\n")
|
||||||
|
fp:write("static const int libbc_endian = ",
|
||||||
|
string.byte(string.dump(function() end), 5) % 2, ";\n\n")
|
||||||
|
local s = ""
|
||||||
|
for _,name in ipairs(defs) do
|
||||||
|
s = s .. defs[name]
|
||||||
|
end
|
||||||
|
fp:write("static const uint8_t libbc_code[] = {\n")
|
||||||
|
local n = 0
|
||||||
|
for i=1,#s do
|
||||||
|
local x = string.byte(s, i)
|
||||||
|
fp:write(x, ",")
|
||||||
|
n = n + (x < 10 and 2 or (x < 100 and 3 or 4))
|
||||||
|
if n >= 75 then n = 0; fp:write("\n") end
|
||||||
|
end
|
||||||
|
fp:write("0\n};\n\n")
|
||||||
|
fp:write("static const struct { const char *name; int ofs; } libbc_map[] = {\n")
|
||||||
|
local m = 0
|
||||||
|
for _,name in ipairs(defs) do
|
||||||
|
fp:write('{"', name, '",', m, '},\n')
|
||||||
|
m = m + #defs[name]
|
||||||
|
end
|
||||||
|
fp:write("{NULL,", m, "}\n};\n\n")
|
||||||
|
fp:flush()
|
||||||
|
end
|
||||||
|
|
||||||
|
local src = read_source()
|
||||||
|
local defs = find_defs(src)
|
||||||
|
write_defs(io.stdout, defs)
|
@ -61,6 +61,7 @@ enum {
|
|||||||
|
|
||||||
LJ_FUNC int lj_bcwrite(lua_State *L, GCproto *pt, lua_Writer writer,
|
LJ_FUNC int lj_bcwrite(lua_State *L, GCproto *pt, lua_Writer writer,
|
||||||
void *data, int strip);
|
void *data, int strip);
|
||||||
|
LJ_FUNC GCproto *lj_bcread_proto(LexState *ls);
|
||||||
LJ_FUNC GCproto *lj_bcread(LexState *ls);
|
LJ_FUNC GCproto *lj_bcread(LexState *ls);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -326,25 +326,13 @@ static void bcread_uv(LexState *ls, GCproto *pt, MSize sizeuv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Read a prototype. */
|
/* Read a prototype. */
|
||||||
static GCproto *bcread_proto(LexState *ls)
|
GCproto *lj_bcread_proto(LexState *ls)
|
||||||
{
|
{
|
||||||
GCproto *pt;
|
GCproto *pt;
|
||||||
MSize framesize, numparams, flags, sizeuv, sizekgc, sizekn, sizebc, sizept;
|
MSize framesize, numparams, flags, sizeuv, sizekgc, sizekn, sizebc, sizept;
|
||||||
MSize ofsk, ofsuv, ofsdbg;
|
MSize ofsk, ofsuv, ofsdbg;
|
||||||
MSize sizedbg = 0;
|
MSize sizedbg = 0;
|
||||||
BCLine firstline = 0, numline = 0;
|
BCLine firstline = 0, numline = 0;
|
||||||
MSize len, startn;
|
|
||||||
|
|
||||||
/* Read length. */
|
|
||||||
if (ls->n > 0 && ls->p[0] == 0) { /* Shortcut EOF. */
|
|
||||||
ls->n--; ls->p++;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
bcread_want(ls, 5);
|
|
||||||
len = bcread_uleb128(ls);
|
|
||||||
if (!len) return NULL; /* EOF */
|
|
||||||
bcread_need(ls, len);
|
|
||||||
startn = ls->n;
|
|
||||||
|
|
||||||
/* Read prototype header. */
|
/* Read prototype header. */
|
||||||
flags = bcread_byte(ls);
|
flags = bcread_byte(ls);
|
||||||
@ -413,9 +401,6 @@ static GCproto *bcread_proto(LexState *ls)
|
|||||||
setmref(pt->uvinfo, NULL);
|
setmref(pt->uvinfo, NULL);
|
||||||
setmref(pt->varinfo, NULL);
|
setmref(pt->varinfo, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len != startn - ls->n)
|
|
||||||
bcread_error(ls, LJ_ERR_BCBAD);
|
|
||||||
return pt;
|
return pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -462,8 +447,21 @@ GCproto *lj_bcread(LexState *ls)
|
|||||||
if (!bcread_header(ls))
|
if (!bcread_header(ls))
|
||||||
bcread_error(ls, LJ_ERR_BCFMT);
|
bcread_error(ls, LJ_ERR_BCFMT);
|
||||||
for (;;) { /* Process all prototypes in the bytecode dump. */
|
for (;;) { /* Process all prototypes in the bytecode dump. */
|
||||||
GCproto *pt = bcread_proto(ls);
|
GCproto *pt;
|
||||||
if (!pt) break;
|
MSize len, startn;
|
||||||
|
/* Read length. */
|
||||||
|
if (ls->n > 0 && ls->p[0] == 0) { /* Shortcut EOF. */
|
||||||
|
ls->n--; ls->p++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bcread_want(ls, 5);
|
||||||
|
len = bcread_uleb128(ls);
|
||||||
|
if (!len) break; /* EOF */
|
||||||
|
bcread_need(ls, len);
|
||||||
|
startn = ls->n;
|
||||||
|
pt = lj_bcread_proto(ls);
|
||||||
|
if (len != startn - ls->n)
|
||||||
|
bcread_error(ls, LJ_ERR_BCBAD);
|
||||||
setprotoV(L, L->top, pt);
|
setprotoV(L, L->top, pt);
|
||||||
incr_top(L);
|
incr_top(L);
|
||||||
}
|
}
|
||||||
|
@ -321,7 +321,7 @@ const char *lj_debug_funcname(lua_State *L, TValue *frame, const char **name)
|
|||||||
/* -- Source code locations ----------------------------------------------- */
|
/* -- Source code locations ----------------------------------------------- */
|
||||||
|
|
||||||
/* Generate shortened source name. */
|
/* Generate shortened source name. */
|
||||||
void lj_debug_shortname(char *out, GCstr *str)
|
void lj_debug_shortname(char *out, GCstr *str, BCLine line)
|
||||||
{
|
{
|
||||||
const char *src = strdata(str);
|
const char *src = strdata(str);
|
||||||
if (*src == '=') {
|
if (*src == '=') {
|
||||||
@ -335,11 +335,11 @@ void lj_debug_shortname(char *out, GCstr *str)
|
|||||||
*out++ = '.'; *out++ = '.'; *out++ = '.';
|
*out++ = '.'; *out++ = '.'; *out++ = '.';
|
||||||
}
|
}
|
||||||
strcpy(out, src);
|
strcpy(out, src);
|
||||||
} else { /* Output [string "string"]. */
|
} else { /* Output [string "string"] or [builtin:name]. */
|
||||||
size_t len; /* Length, up to first control char. */
|
size_t len; /* Length, up to first control char. */
|
||||||
for (len = 0; len < LUA_IDSIZE-12; len++)
|
for (len = 0; len < LUA_IDSIZE-12; len++)
|
||||||
if (((const unsigned char *)src)[len] < ' ') break;
|
if (((const unsigned char *)src)[len] < ' ') break;
|
||||||
strcpy(out, "[string \""); out += 9;
|
strcpy(out, line == ~(BCLine)0 ? "[builtin:" : "[string \""); out += 9;
|
||||||
if (src[len] != '\0') { /* Must truncate? */
|
if (src[len] != '\0') { /* Must truncate? */
|
||||||
if (len > LUA_IDSIZE-15) len = LUA_IDSIZE-15;
|
if (len > LUA_IDSIZE-15) len = LUA_IDSIZE-15;
|
||||||
strncpy(out, src, len); out += len;
|
strncpy(out, src, len); out += len;
|
||||||
@ -347,7 +347,7 @@ void lj_debug_shortname(char *out, GCstr *str)
|
|||||||
} else {
|
} else {
|
||||||
strcpy(out, src); out += len;
|
strcpy(out, src); out += len;
|
||||||
}
|
}
|
||||||
strcpy(out, "\"]");
|
strcpy(out, line == ~(BCLine)0 ? "]" : "\"]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,8 +360,9 @@ void lj_debug_addloc(lua_State *L, const char *msg,
|
|||||||
if (isluafunc(fn)) {
|
if (isluafunc(fn)) {
|
||||||
BCLine line = debug_frameline(L, fn, nextframe);
|
BCLine line = debug_frameline(L, fn, nextframe);
|
||||||
if (line >= 0) {
|
if (line >= 0) {
|
||||||
|
GCproto *pt = funcproto(fn);
|
||||||
char buf[LUA_IDSIZE];
|
char buf[LUA_IDSIZE];
|
||||||
lj_debug_shortname(buf, proto_chunkname(funcproto(fn)));
|
lj_debug_shortname(buf, proto_chunkname(pt), pt->firstline);
|
||||||
lj_str_pushf(L, "%s:%d: %s", buf, line, msg);
|
lj_str_pushf(L, "%s:%d: %s", buf, line, msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -377,7 +378,9 @@ void lj_debug_pushloc(lua_State *L, GCproto *pt, BCPos pc)
|
|||||||
const char *s = strdata(name);
|
const char *s = strdata(name);
|
||||||
MSize i, len = name->len;
|
MSize i, len = name->len;
|
||||||
BCLine line = lj_debug_line(pt, pc);
|
BCLine line = lj_debug_line(pt, pc);
|
||||||
if (*s == '@') {
|
if (pt->firstline == ~(BCLine)0) {
|
||||||
|
lj_str_pushf(L, "builtin:%s", s);
|
||||||
|
} else if (*s == '@') {
|
||||||
s++; len--;
|
s++; len--;
|
||||||
for (i = len; i > 0; i--)
|
for (i = len; i > 0; i--)
|
||||||
if (s[i] == '/' || s[i] == '\\') {
|
if (s[i] == '/' || s[i] == '\\') {
|
||||||
@ -453,7 +456,7 @@ int lj_debug_getinfo(lua_State *L, const char *what, lj_Debug *ar, int ext)
|
|||||||
BCLine firstline = pt->firstline;
|
BCLine firstline = pt->firstline;
|
||||||
GCstr *name = proto_chunkname(pt);
|
GCstr *name = proto_chunkname(pt);
|
||||||
ar->source = strdata(name);
|
ar->source = strdata(name);
|
||||||
lj_debug_shortname(ar->short_src, name);
|
lj_debug_shortname(ar->short_src, name, pt->firstline);
|
||||||
ar->linedefined = (int)firstline;
|
ar->linedefined = (int)firstline;
|
||||||
ar->lastlinedefined = (int)(firstline + pt->numline);
|
ar->lastlinedefined = (int)(firstline + pt->numline);
|
||||||
ar->what = firstline ? "Lua" : "main";
|
ar->what = firstline ? "Lua" : "main";
|
||||||
|
@ -34,7 +34,7 @@ LJ_FUNC const char *lj_debug_slotname(GCproto *pt, const BCIns *pc,
|
|||||||
BCReg slot, const char **name);
|
BCReg slot, const char **name);
|
||||||
LJ_FUNC const char *lj_debug_funcname(lua_State *L, TValue *frame,
|
LJ_FUNC const char *lj_debug_funcname(lua_State *L, TValue *frame,
|
||||||
const char **name);
|
const char **name);
|
||||||
LJ_FUNC void lj_debug_shortname(char *out, GCstr *str);
|
LJ_FUNC void lj_debug_shortname(char *out, GCstr *str, BCLine line);
|
||||||
LJ_FUNC void lj_debug_addloc(lua_State *L, const char *msg,
|
LJ_FUNC void lj_debug_addloc(lua_State *L, const char *msg,
|
||||||
cTValue *frame, cTValue *nextframe);
|
cTValue *frame, cTValue *nextframe);
|
||||||
LJ_FUNC void lj_debug_pushloc(lua_State *L, GCproto *pt, BCPos pc);
|
LJ_FUNC void lj_debug_pushloc(lua_State *L, GCproto *pt, BCPos pc);
|
||||||
|
@ -587,7 +587,7 @@ LJ_NOINLINE void lj_err_lex(lua_State *L, GCstr *src, const char *tok,
|
|||||||
{
|
{
|
||||||
char buff[LUA_IDSIZE];
|
char buff[LUA_IDSIZE];
|
||||||
const char *msg;
|
const char *msg;
|
||||||
lj_debug_shortname(buff, src);
|
lj_debug_shortname(buff, src, line);
|
||||||
msg = lj_str_pushvf(L, err2msg(em), argp);
|
msg = lj_str_pushvf(L, err2msg(em), argp);
|
||||||
msg = lj_str_pushf(L, "%s:%d: %s", buff, line, msg);
|
msg = lj_str_pushf(L, "%s:%d: %s", buff, line, msg);
|
||||||
if (tok)
|
if (tok)
|
||||||
|
27
src/lj_lib.c
27
src/lj_lib.c
@ -18,6 +18,8 @@
|
|||||||
#include "lj_dispatch.h"
|
#include "lj_dispatch.h"
|
||||||
#include "lj_vm.h"
|
#include "lj_vm.h"
|
||||||
#include "lj_strscan.h"
|
#include "lj_strscan.h"
|
||||||
|
#include "lj_lex.h"
|
||||||
|
#include "lj_bcdump.h"
|
||||||
#include "lj_lib.h"
|
#include "lj_lib.h"
|
||||||
|
|
||||||
/* -- Library initialization ---------------------------------------------- */
|
/* -- Library initialization ---------------------------------------------- */
|
||||||
@ -43,6 +45,28 @@ static GCtab *lib_create_table(lua_State *L, const char *libname, int hsize)
|
|||||||
return tabV(L->top-1);
|
return tabV(L->top-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const uint8_t *lib_read_lfunc(lua_State *L, const uint8_t *p, GCtab *tab)
|
||||||
|
{
|
||||||
|
int len = *p++;
|
||||||
|
GCstr *name = lj_str_new(L, (const char *)p, len);
|
||||||
|
LexState ls;
|
||||||
|
GCproto *pt;
|
||||||
|
GCfunc *fn;
|
||||||
|
memset(&ls, 0, sizeof(ls));
|
||||||
|
ls.L = L;
|
||||||
|
ls.p = (const char *)(p+len);
|
||||||
|
ls.n = ~(MSize)0;
|
||||||
|
ls.current = -1;
|
||||||
|
ls.level = (BCDUMP_F_STRIP|(LJ_BE*BCDUMP_F_BE));
|
||||||
|
ls.chunkname = name;
|
||||||
|
pt = lj_bcread_proto(&ls);
|
||||||
|
pt->firstline = ~(BCLine)0;
|
||||||
|
fn = lj_func_newL_empty(L, pt, tabref(L->env));
|
||||||
|
/* NOBARRIER: See below for common barrier. */
|
||||||
|
setfuncV(L, lj_tab_setstr(L, tab, name), fn);
|
||||||
|
return (const uint8_t *)ls.p;
|
||||||
|
}
|
||||||
|
|
||||||
void lj_lib_register(lua_State *L, const char *libname,
|
void lj_lib_register(lua_State *L, const char *libname,
|
||||||
const uint8_t *p, const lua_CFunction *cf)
|
const uint8_t *p, const lua_CFunction *cf)
|
||||||
{
|
{
|
||||||
@ -87,6 +111,9 @@ void lj_lib_register(lua_State *L, const char *libname,
|
|||||||
ofn = fn;
|
ofn = fn;
|
||||||
} else {
|
} else {
|
||||||
switch (tag | len) {
|
switch (tag | len) {
|
||||||
|
case LIBINIT_LUA:
|
||||||
|
p = lib_read_lfunc(L, p, tab);
|
||||||
|
break;
|
||||||
case LIBINIT_SET:
|
case LIBINIT_SET:
|
||||||
L->top -= 2;
|
L->top -= 2;
|
||||||
if (tvisstr(L->top+1) && strV(L->top+1)->len == 0)
|
if (tvisstr(L->top+1) && strV(L->top+1)->len == 0)
|
||||||
|
@ -77,6 +77,7 @@ static LJ_AINLINE void lj_lib_pushcc(lua_State *L, lua_CFunction f,
|
|||||||
#define LJLIB_CF(name) static int lj_cf_##name(lua_State *L)
|
#define LJLIB_CF(name) static int lj_cf_##name(lua_State *L)
|
||||||
#define LJLIB_ASM(name) static int lj_ffh_##name(lua_State *L)
|
#define LJLIB_ASM(name) static int lj_ffh_##name(lua_State *L)
|
||||||
#define LJLIB_ASM_(name)
|
#define LJLIB_ASM_(name)
|
||||||
|
#define LJLIB_LUA(name)
|
||||||
#define LJLIB_SET(name)
|
#define LJLIB_SET(name)
|
||||||
#define LJLIB_PUSH(arg)
|
#define LJLIB_PUSH(arg)
|
||||||
#define LJLIB_REC(handler)
|
#define LJLIB_REC(handler)
|
||||||
@ -96,7 +97,8 @@ LJ_FUNC void lj_lib_register(lua_State *L, const char *libname,
|
|||||||
#define LIBINIT_ASM 0x40
|
#define LIBINIT_ASM 0x40
|
||||||
#define LIBINIT_ASM_ 0x80
|
#define LIBINIT_ASM_ 0x80
|
||||||
#define LIBINIT_STRING 0xc0
|
#define LIBINIT_STRING 0xc0
|
||||||
#define LIBINIT_MAXSTR 0x39
|
#define LIBINIT_MAXSTR 0x38
|
||||||
|
#define LIBINIT_LUA 0xf9
|
||||||
#define LIBINIT_SET 0xfa
|
#define LIBINIT_SET 0xfa
|
||||||
#define LIBINIT_NUMBER 0xfb
|
#define LIBINIT_NUMBER 0xfb
|
||||||
#define LIBINIT_COPY 0xfc
|
#define LIBINIT_COPY 0xfc
|
||||||
|
Loading…
Reference in New Issue
Block a user