Skip to content

Commit

Permalink
Merge branch 'v3.0' of https://github.com/achaulk/LuaJIT into v2.1-v3…
Browse files Browse the repository at this point in the history
….0-achaulk-changes
  • Loading branch information
Brugarolas committed Jan 13, 2024
2 parents b579bb5 + 1b4f72a commit 892ce5a
Show file tree
Hide file tree
Showing 14 changed files with 1,617 additions and 24 deletions.
129 changes: 128 additions & 1 deletion src/lj_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include "lj_vm.h"
#include "lj_strscan.h"
#include "lj_strfmt.h"
#include "lj_clib.h"
#include "luacpp.h"

/* -- Common helper functions --------------------------------------------- */

Expand Down Expand Up @@ -618,6 +620,22 @@ LUA_API void *lua_touserdata(lua_State *L, int idx)
return NULL;
}

LUA_API void *(lua_totypeduserdata)(lua_State *L, int idx, unsigned int type)
{
cTValue *o = index2adr(L, idx);
if (tvisudata(o)) {
GCudata *ud = udataV(o);
if (ud->udtype == UDTYPE_TYPED) {
if (ud->len == type)
return uddata(ud);
const struct lua_typeduserdatainfo *info =
(const struct lua_typeduserdatainfo *)gcrefu(ud->env);
return info->type_cast ? info->type_cast(uddata(ud), type) : NULL;
}
}
return NULL;
}

LUA_API lua_State *lua_tothread(lua_State *L, int idx)
{
cTValue *o = index2adr(L, idx);
Expand Down Expand Up @@ -782,6 +800,41 @@ LUA_API void *lua_newuserdata(lua_State *L, size_t size)
return uddata(ud);
}

LUA_API void lua_newtypeduserdata(lua_State *L, void *ptr,
const struct lua_typeduserdatainfo *info)
{
GCudata *ud;
lj_checkapi(info && ptr && info->type_id != 0, "bad typed userdata");
lj_gc_check(L);
ud = lj_udata_new(L, 0, NULL);
setudataV(L, L->top, ud);
incr_top(L);
ud->udtype = UDTYPE_TYPED;
ud->len = info->type_id;
setmref(ud->payload, ptr);
setgcrefp(ud->env, info);
}

LUA_API void(lua_releasetypeduserdata)(lua_State *L, int idx)
{
cTValue *o = index2adr(L, idx);
if (tvisudata(o)) {
GCudata *ud = udataV(o);
if (ud->udtype == UDTYPE_TYPED) {
const struct lua_typeduserdatainfo *info = (const struct lua_typeduserdatainfo *)
gcrefu(ud->env);
if (info) {
info->release(uddata(ud));

setmref(ud->payload, NULL);
setgcrefnull(ud->env);
ud->len = 0;
ud->udtype = UDTYPE_USERDATA;
}
}
}
}

LUA_API void lua_concat(lua_State *L, int n)
{
lj_checkapi_slot(n);
Expand Down Expand Up @@ -907,7 +960,10 @@ LUA_API void lua_getfenv(lua_State *L, int idx)
if (tvisfunc(o)) {
settabV(L, L->top, tabref(funcV(o)->c.env));
} else if (tvisudata(o)) {
settabV(L, L->top, tabref(udataV(o)->env));
if (udataV(o)->udtype == UDTYPE_TYPED)
setnilV(L->top);
else
settabV(L, L->top, tabref(udataV(o)->env));
} else if (tvisthread(o)) {
settabV(L, L->top, tabref(threadV(o)->env));
} else {
Expand Down Expand Up @@ -1107,6 +1163,10 @@ LUA_API int lua_setfenv(lua_State *L, int idx)
if (tvisfunc(o)) {
setgcref(funcV(o)->c.env, obj2gco(t));
} else if (tvisudata(o)) {
if (udataV(o)->udtype == UDTYPE_TYPED) {
L->top--;
return 0;
}
setgcref(udataV(o)->env, obj2gco(t));
} else if (tvisthread(o)) {
setgcref(threadV(o)->env, obj2gco(t));
Expand Down Expand Up @@ -1346,3 +1406,70 @@ LUA_API size_t luaJIT_getpagesize()
{
return ARENA_SIZE;
}

LUA_API uint64_t lj_internal_getstack(lua_State *L, int index)
{
TValue *o = index2adr(L, index);
return o->u64;
}

LUA_API void lj_internal_setstack(lua_State *L, int index, uint64_t tv)
{
TValue t;
t.u64 = tv;
copy_slot(L, &t, index);
}

LUA_API void lj_internal_pushraw(lua_State *L, uint64_t tv)
{
TValue t;
t.u64 = tv;
copyTV(L, L->top, &t);
incr_top(L);
}

LUA_API void *lj_internal_mt__index(const lua_State *L, void *mt)
{
return (void *)lj_meta_fast(L, (GCtab *)mt, MM_index);
}

LUA_API void *lj_internal_getstr(const lua_State *L, const char *s, size_t n)
{
return lj_str_new((lua_State*)L, s, n);
}

LUA_API void *lj_internal_newtab(const lua_State *L)
{
return lj_tab_new((lua_State *)L, 0, 0);
}

LUA_API void lj_internal_rawset(const lua_State *cL, void *t, uint64_t k, uint64_t v)
{
lua_State *L = (lua_State *)cL;
TValue key, val;
TValue *dst;
key.u64 = k;
val.u64 = v;
dst = lj_tab_set(L, (GCtab*)t, &key);
copyTV(L, dst, &val);
lj_gc_anybarriert(L, t);
}

LUA_API void lj_internal_setmetatable(const lua_State *cL, void *rawt, void *rawmt)
{
GCtab *t = (GCtab *)rawt;
GCtab *mt = (GCtab *)rawmt;
lua_State *L = (lua_State *)cL;
setgcref(t->metatable, obj2gco(mt));
if(mt)
lj_gc_objbarriert(L, t, mt);
}

LUA_API int lj_internal_bindfunc(lua_State *L, void *clib, const char *name, size_t namelen,
const char *cdef, void *impl)
{
GCstr *namestr = name ? lj_str_new(L, name, namelen) : NULL;
if (!!name != !!impl)
return LUA_ERRERR;
return lj_clib_define_symbol(L, (CLibrary *)clib, cdef, namestr, impl);
}
9 changes: 9 additions & 0 deletions src/lj_arena.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ int lj_arena_init(struct global_State *g, luaJIT_allocpages allocp,
void lj_arena_cleanup(struct global_State *g);

/* Add ARENA_FREELIST_CHUNK free arenas */
void lj_arena_alloc_fill(arena_context *ctx);
static inline void *lj_arena_alloc(arena_context *ctx)
{
if (!ctx->freelist_at) {
Expand All @@ -86,12 +87,20 @@ static inline void *lj_arena_alloc(arena_context *ctx)
return NULL;
}
void *p = ctx->freelist[--ctx->freelist_at];
#ifdef LUA_USE_ASSERT
memset(p, 0xDD, ARENA_SIZE);
#endif
return p;
}


/* Free the last ARENA_FREELIST_CHUNK arenas */
void lj_arena_free_extra(arena_context *ctx);
static inline void lj_arena_free(arena_context *ctx, void *p)
{
#ifdef LUA_USE_ASSERT
memset(p, 0xED, ARENA_SIZE);
#endif
if (ctx->freelist_at == ARENA_FREELIST_SIZE) {
ctx->freepages(ctx->pageud, ctx->freelist + (ARENA_FREELIST_SIZE - ARENA_FREELIST_CHUNK), ARENA_FREELIST_CHUNK);
ctx->freelist_at -= ARENA_FREELIST_CHUNK;
Expand Down
2 changes: 2 additions & 0 deletions src/lj_asm_x86.h
Original file line number Diff line number Diff line change
Expand Up @@ -1403,6 +1403,8 @@ static void asm_uref(ASMState *as, IRIns *ir)
emit_rmro(as, XO_MOV, uv|REX_GC64,
ra_alloc1(as, ir->op1, RSET_GPR), offsetof(GCfuncL, uvptr));
}
emit_rmro(as, XO_MOV, uv|REX_GC64, uv, (int32_t)sizeof(MRef) * (int32_t)(ir->op2 >> 8));
emit_rmro(as, XO_MOV, uv|REX_GC64, func, offsetof(GCfuncL, uvptr));
}
}

Expand Down
73 changes: 71 additions & 2 deletions src/lj_clib.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#include "lj_cdata.h"
#include "lj_clib.h"
#include "lj_strfmt.h"
#include "lj_cparse.h"
#include "lj_vm.h"

/* -- OS-specific functions ----------------------------------------------- */

Expand Down Expand Up @@ -143,8 +145,13 @@ static void clib_unloadlib(CLibrary *cl)

static void *clib_getsym(CLibrary *cl, const char *name)
{
void *p = dlsym(cl->handle, name);
return p;
void *p;
if (cl->getprocaddr) {
p = cl->getprocaddr(cl->ud, name);
if (p || !cl->handle)
return p;
}
return dlsym(cl->handle, name);
}

#elif LJ_TARGET_WINDOWS
Expand Down Expand Up @@ -247,6 +254,11 @@ EXTERN_C IMAGE_DOS_HEADER __ImageBase;
static void *clib_getsym(CLibrary *cl, const char *name)
{
void *p = NULL;
if (cl->getprocaddr) {
p = cl->getprocaddr(cl->ud, name);
if (p || !cl->handle)
return p;
}
if (cl->handle == CLIB_DEFHANDLE) { /* Search default libraries. */
MSize i;
for (i = 0; i < CLIB_HANDLE_MAX; i++) {
Expand Down Expand Up @@ -406,6 +418,7 @@ static CLibrary *clib_new(lua_State *L, GCtab *mt)
GCudata *ud = lj_udata_new(L, sizeof(CLibrary), t);
CLibrary *cl = (CLibrary *)uddata(ud);
cl->cache = t;
cl->getprocaddr = NULL;
ud->udtype = UDTYPE_FFI_CLIB;
/* NOBARRIER: The GCudata is new (marked white). */
setgcref(ud->metatable, obj2gco(mt));
Expand Down Expand Up @@ -435,4 +448,60 @@ void lj_clib_default(lua_State *L, GCtab *mt)
cl->handle = CLIB_DEFHANDLE;
}

static void *lj_clib_fake_getprocaddr(void *ud, const char *str)
{
void *p = *(void **)ud;
*(void **)ud = NULL;
return p;
}

struct def_sym
{
CLibrary *cl;
GCstr *name;
};

static TValue *cpcdefsym(lua_State *L, lua_CFunction dummy, void *ud)
{
struct def_sym *sym = (struct def_sym *)ud;
lj_clib_index(L, sym->cl, sym->name);
return NULL;
}


int lj_clib_define_symbol(lua_State *L, CLibrary *cl, const char *cdef,
GCstr *name, void *impl)
{
void *(*oldprocaddr)(void *, const char *) = cl->getprocaddr;
void *oldud = cl->ud;
struct def_sym sym = {cl, name};
CPState cp;
int ret;

if (cdef) {
cp.L = L;
cp.cts = ctype_cts(L);
cp.srcname = name ? strdata(name) : "external cdef";
cp.p = cdef;
cp.param = NULL;
cp.mode = CPARSE_MODE_MULTI | CPARSE_MODE_DIRECT;
ret = lj_cparse(&cp);
if (ret) {
return ret;
}
}

if (impl) {
cl->getprocaddr = &lj_clib_fake_getprocaddr;
cl->ud = &impl;
lj_vm_cpcall(L, NULL, &sym, cpcdefsym);
cl->getprocaddr = oldprocaddr;
cl->ud = oldud;
if (impl)
return LUA_ERRRUN;
}

return LUA_OK;
}

#endif
4 changes: 4 additions & 0 deletions src/lj_clib.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@
typedef struct CLibrary {
void *handle; /* Opaque handle for dynamic library loader. */
GCtab *cache; /* Cache for resolved symbols. Anchored in ud->env. */
void *(*getprocaddr)(void *, const char *); /* Application override */
void *ud;
} CLibrary;

LJ_FUNC TValue *lj_clib_index(lua_State *L, CLibrary *cl, GCstr *name);
LJ_FUNC void lj_clib_load(lua_State *L, GCtab *mt, GCstr *name, int global);
LJ_FUNC void lj_clib_unload(CLibrary *cl);
LJ_FUNC void lj_clib_default(lua_State *L, GCtab *mt);
LJ_FUNC int lj_clib_define_symbol(lua_State *L, CLibrary *cl,
const char *cdef, GCstr *name, void *impl);

#endif

Expand Down
3 changes: 1 addition & 2 deletions src/lj_func.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,7 @@ GCfunc *lj_func_newL_gc(lua_State *L, GCproto *pt, GCfuncL *parent)

void LJ_FASTCALL lj_func_free(global_State *g, GCfunc *fn)
{
MSize size = isluafunc(fn) ? sizeLfunc((MSize)fn->l.nupvalues) :
sizeCfunc((MSize)fn->c.nupvalues);
MSize size = isluafunc(fn) ? sizeLfunc((MSize)fn->l.nupvalues) : sizeCfunc((MSize)fn->c.nupvalues);
lj_mem_free(g, fn, size);
#ifdef COUNTS
g->gc.fnum--;
Expand Down
Loading

0 comments on commit 892ce5a

Please sign in to comment.