mirror of
https://github.com/luau-lang/luau.git
synced 2025-01-20 01:38:07 +00:00
Merge branch 'master' into merge
This commit is contained in:
commit
89090a16a6
12 changed files with 115 additions and 18 deletions
|
@ -71,7 +71,7 @@ bool forgLoopTableIter(lua_State* L, Table* h, int index, TValue* ra)
|
||||||
|
|
||||||
if (!ttisnil(e))
|
if (!ttisnil(e))
|
||||||
{
|
{
|
||||||
setpvalue(ra + 2, reinterpret_cast<void*>(uintptr_t(index + 1)));
|
setpvalue(ra + 2, reinterpret_cast<void*>(uintptr_t(index + 1)), LU_TAG_ITERATOR);
|
||||||
setnvalue(ra + 3, double(index + 1));
|
setnvalue(ra + 3, double(index + 1));
|
||||||
setobj2s(L, ra + 4, e);
|
setobj2s(L, ra + 4, e);
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ bool forgLoopTableIter(lua_State* L, Table* h, int index, TValue* ra)
|
||||||
|
|
||||||
if (!ttisnil(gval(n)))
|
if (!ttisnil(gval(n)))
|
||||||
{
|
{
|
||||||
setpvalue(ra + 2, reinterpret_cast<void*>(uintptr_t(index + 1)));
|
setpvalue(ra + 2, reinterpret_cast<void*>(uintptr_t(index + 1)), LU_TAG_ITERATOR);
|
||||||
getnodekey(L, ra + 3, n);
|
getnodekey(L, ra + 3, n);
|
||||||
setobj(L, ra + 4, gval(n));
|
setobj(L, ra + 4, gval(n));
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ bool forgLoopNodeIter(lua_State* L, Table* h, int index, TValue* ra)
|
||||||
|
|
||||||
if (!ttisnil(gval(n)))
|
if (!ttisnil(gval(n)))
|
||||||
{
|
{
|
||||||
setpvalue(ra + 2, reinterpret_cast<void*>(uintptr_t(index + 1)));
|
setpvalue(ra + 2, reinterpret_cast<void*>(uintptr_t(index + 1)), LU_TAG_ITERATOR);
|
||||||
getnodekey(L, ra + 3, n);
|
getnodekey(L, ra + 3, n);
|
||||||
setobj(L, ra + 4, gval(n));
|
setobj(L, ra + 4, gval(n));
|
||||||
|
|
||||||
|
@ -697,7 +697,7 @@ const Instruction* executeFORGPREP(lua_State* L, const Instruction* pc, StkId ba
|
||||||
{
|
{
|
||||||
// set up registers for builtin iteration
|
// set up registers for builtin iteration
|
||||||
setobj2s(L, ra + 1, ra);
|
setobj2s(L, ra + 1, ra);
|
||||||
setpvalue(ra + 2, reinterpret_cast<void*>(uintptr_t(0)));
|
setpvalue(ra + 2, reinterpret_cast<void*>(uintptr_t(0)), LU_TAG_ITERATOR);
|
||||||
setnilvalue(ra);
|
setnilvalue(ra);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -159,9 +159,11 @@ LUA_API const char* lua_namecallatom(lua_State* L, int* atom);
|
||||||
LUA_API int lua_objlen(lua_State* L, int idx);
|
LUA_API int lua_objlen(lua_State* L, int idx);
|
||||||
LUA_API lua_CFunction lua_tocfunction(lua_State* L, int idx);
|
LUA_API lua_CFunction lua_tocfunction(lua_State* L, int idx);
|
||||||
LUA_API void* lua_tolightuserdata(lua_State* L, int idx);
|
LUA_API void* lua_tolightuserdata(lua_State* L, int idx);
|
||||||
|
LUA_API void* lua_tolightuserdatatagged(lua_State* L, int idx, int tag);
|
||||||
LUA_API void* lua_touserdata(lua_State* L, int idx);
|
LUA_API void* lua_touserdata(lua_State* L, int idx);
|
||||||
LUA_API void* lua_touserdatatagged(lua_State* L, int idx, int tag);
|
LUA_API void* lua_touserdatatagged(lua_State* L, int idx, int tag);
|
||||||
LUA_API int lua_userdatatag(lua_State* L, int idx);
|
LUA_API int lua_userdatatag(lua_State* L, int idx);
|
||||||
|
LUA_API int lua_lightuserdatatag(lua_State* L, int idx);
|
||||||
LUA_API lua_State* lua_tothread(lua_State* L, int idx);
|
LUA_API lua_State* lua_tothread(lua_State* L, int idx);
|
||||||
LUA_API void* lua_tobuffer(lua_State* L, int idx, size_t* len);
|
LUA_API void* lua_tobuffer(lua_State* L, int idx, size_t* len);
|
||||||
LUA_API const void* lua_topointer(lua_State* L, int idx);
|
LUA_API const void* lua_topointer(lua_State* L, int idx);
|
||||||
|
@ -186,7 +188,7 @@ LUA_API void lua_pushcclosurek(lua_State* L, lua_CFunction fn, const char* debug
|
||||||
LUA_API void lua_pushboolean(lua_State* L, int b);
|
LUA_API void lua_pushboolean(lua_State* L, int b);
|
||||||
LUA_API int lua_pushthread(lua_State* L);
|
LUA_API int lua_pushthread(lua_State* L);
|
||||||
|
|
||||||
LUA_API void lua_pushlightuserdata(lua_State* L, void* p);
|
LUA_API void lua_pushlightuserdatatagged(lua_State* L, void* p, int tag);
|
||||||
LUA_API void* lua_newuserdatatagged(lua_State* L, size_t sz, int tag);
|
LUA_API void* lua_newuserdatatagged(lua_State* L, size_t sz, int tag);
|
||||||
LUA_API void* lua_newuserdatadtor(lua_State* L, size_t sz, void (*dtor)(void*));
|
LUA_API void* lua_newuserdatadtor(lua_State* L, size_t sz, void (*dtor)(void*));
|
||||||
|
|
||||||
|
@ -323,6 +325,9 @@ typedef void (*lua_Destructor)(lua_State* L, void* userdata);
|
||||||
LUA_API void lua_setuserdatadtor(lua_State* L, int tag, lua_Destructor dtor);
|
LUA_API void lua_setuserdatadtor(lua_State* L, int tag, lua_Destructor dtor);
|
||||||
LUA_API lua_Destructor lua_getuserdatadtor(lua_State* L, int tag);
|
LUA_API lua_Destructor lua_getuserdatadtor(lua_State* L, int tag);
|
||||||
|
|
||||||
|
LUA_API void lua_setlightuserdataname(lua_State* L, int tag, const char* name);
|
||||||
|
LUA_API const char* lua_getlightuserdataname(lua_State* L, int tag);
|
||||||
|
|
||||||
LUA_API void lua_clonefunction(lua_State* L, int idx);
|
LUA_API void lua_clonefunction(lua_State* L, int idx);
|
||||||
|
|
||||||
LUA_API void lua_cleartable(lua_State* L, int idx);
|
LUA_API void lua_cleartable(lua_State* L, int idx);
|
||||||
|
@ -370,6 +375,7 @@ LUA_API void lua_unref(lua_State* L, int ref);
|
||||||
#define lua_pushliteral(L, s) lua_pushlstring(L, "" s, (sizeof(s) / sizeof(char)) - 1)
|
#define lua_pushliteral(L, s) lua_pushlstring(L, "" s, (sizeof(s) / sizeof(char)) - 1)
|
||||||
#define lua_pushcfunction(L, fn, debugname) lua_pushcclosurek(L, fn, debugname, 0, NULL)
|
#define lua_pushcfunction(L, fn, debugname) lua_pushcclosurek(L, fn, debugname, 0, NULL)
|
||||||
#define lua_pushcclosure(L, fn, debugname, nup) lua_pushcclosurek(L, fn, debugname, nup, NULL)
|
#define lua_pushcclosure(L, fn, debugname, nup) lua_pushcclosurek(L, fn, debugname, nup, NULL)
|
||||||
|
#define lua_pushlightuserdata(L, p) lua_pushlightuserdatatagged(L, p, 0)
|
||||||
|
|
||||||
#define lua_setglobal(L, s) lua_setfield(L, LUA_GLOBALSINDEX, (s))
|
#define lua_setglobal(L, s) lua_setfield(L, LUA_GLOBALSINDEX, (s))
|
||||||
#define lua_getglobal(L, s) lua_getfield(L, LUA_GLOBALSINDEX, (s))
|
#define lua_getglobal(L, s) lua_getfield(L, LUA_GLOBALSINDEX, (s))
|
||||||
|
|
|
@ -101,6 +101,11 @@
|
||||||
#define LUA_UTAG_LIMIT 128
|
#define LUA_UTAG_LIMIT 128
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// number of valid Lua lightuserdata tags
|
||||||
|
#ifndef LUA_LUTAG_LIMIT
|
||||||
|
#define LUA_LUTAG_LIMIT 128
|
||||||
|
#endif
|
||||||
|
|
||||||
// upper bound for number of size classes used by page allocator
|
// upper bound for number of size classes used by page allocator
|
||||||
#ifndef LUA_SIZECLASSES
|
#ifndef LUA_SIZECLASSES
|
||||||
#define LUA_SIZECLASSES 32
|
#define LUA_SIZECLASSES 32
|
||||||
|
|
|
@ -505,6 +505,12 @@ void* lua_tolightuserdata(lua_State* L, int idx)
|
||||||
return (!ttislightuserdata(o)) ? NULL : pvalue(o);
|
return (!ttislightuserdata(o)) ? NULL : pvalue(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* lua_tolightuserdatatagged(lua_State* L, int idx, int tag)
|
||||||
|
{
|
||||||
|
StkId o = index2addr(L, idx);
|
||||||
|
return (!ttislightuserdata(o) || lightuserdatatag(o) != tag) ? NULL : pvalue(o);
|
||||||
|
}
|
||||||
|
|
||||||
void* lua_touserdata(lua_State* L, int idx)
|
void* lua_touserdata(lua_State* L, int idx)
|
||||||
{
|
{
|
||||||
StkId o = index2addr(L, idx);
|
StkId o = index2addr(L, idx);
|
||||||
|
@ -530,6 +536,14 @@ int lua_userdatatag(lua_State* L, int idx)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lua_lightuserdatatag(lua_State* L, int idx)
|
||||||
|
{
|
||||||
|
StkId o = index2addr(L, idx);
|
||||||
|
if (ttislightuserdata(o))
|
||||||
|
return lightuserdatatag(o);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
lua_State* lua_tothread(lua_State* L, int idx)
|
lua_State* lua_tothread(lua_State* L, int idx)
|
||||||
{
|
{
|
||||||
StkId o = index2addr(L, idx);
|
StkId o = index2addr(L, idx);
|
||||||
|
@ -665,9 +679,10 @@ void lua_pushboolean(lua_State* L, int b)
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lua_pushlightuserdata(lua_State* L, void* p)
|
void lua_pushlightuserdatatagged(lua_State* L, void* p, int tag)
|
||||||
{
|
{
|
||||||
setpvalue(L->top, p);
|
api_check(L, unsigned(tag) < LUA_LUTAG_LIMIT);
|
||||||
|
setpvalue(L->top, p, tag);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1412,6 +1427,24 @@ lua_Destructor lua_getuserdatadtor(lua_State* L, int tag)
|
||||||
return L->global->udatagc[tag];
|
return L->global->udatagc[tag];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lua_setlightuserdataname(lua_State* L, int tag, const char* name)
|
||||||
|
{
|
||||||
|
api_check(L, unsigned(tag) < LUA_LUTAG_LIMIT);
|
||||||
|
api_check(L, !L->global->lightuserdataname[tag]); // renaming not supported
|
||||||
|
if (!L->global->lightuserdataname[tag])
|
||||||
|
{
|
||||||
|
L->global->lightuserdataname[tag] = luaS_new(L, name);
|
||||||
|
luaS_fix(L->global->lightuserdataname[tag]); // never collect these names
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* lua_getlightuserdataname(lua_State* L, int tag)
|
||||||
|
{
|
||||||
|
api_check(L, unsigned(tag) < LUA_LUTAG_LIMIT);
|
||||||
|
const TString* name = L->global->lightuserdataname[tag];
|
||||||
|
return name ? getstr(name) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void lua_clonefunction(lua_State* L, int idx)
|
void lua_clonefunction(lua_State* L, int idx)
|
||||||
{
|
{
|
||||||
luaC_checkGC(L);
|
luaC_checkGC(L);
|
||||||
|
|
|
@ -48,7 +48,7 @@ int luaO_rawequalObj(const TValue* t1, const TValue* t2)
|
||||||
case LUA_TBOOLEAN:
|
case LUA_TBOOLEAN:
|
||||||
return bvalue(t1) == bvalue(t2); // boolean true must be 1 !!
|
return bvalue(t1) == bvalue(t2); // boolean true must be 1 !!
|
||||||
case LUA_TLIGHTUSERDATA:
|
case LUA_TLIGHTUSERDATA:
|
||||||
return pvalue(t1) == pvalue(t2);
|
return pvalue(t1) == pvalue(t2) && (!FFlag::TaggedLuData || lightuserdatatag(t1) == lightuserdatatag(t2));
|
||||||
default:
|
default:
|
||||||
LUAU_ASSERT(iscollectable(t1));
|
LUAU_ASSERT(iscollectable(t1));
|
||||||
return gcvalue(t1) == gcvalue(t2);
|
return gcvalue(t1) == gcvalue(t2);
|
||||||
|
@ -71,7 +71,7 @@ int luaO_rawequalKey(const TKey* t1, const TValue* t2)
|
||||||
case LUA_TBOOLEAN:
|
case LUA_TBOOLEAN:
|
||||||
return bvalue(t1) == bvalue(t2); // boolean true must be 1 !!
|
return bvalue(t1) == bvalue(t2); // boolean true must be 1 !!
|
||||||
case LUA_TLIGHTUSERDATA:
|
case LUA_TLIGHTUSERDATA:
|
||||||
return pvalue(t1) == pvalue(t2);
|
return pvalue(t1) == pvalue(t2) && (!FFlag::TaggedLuData || lightuserdatatag(t1) == lightuserdatatag(t2));
|
||||||
default:
|
default:
|
||||||
LUAU_ASSERT(iscollectable(t1));
|
LUAU_ASSERT(iscollectable(t1));
|
||||||
return gcvalue(t1) == gcvalue(t2);
|
return gcvalue(t1) == gcvalue(t2);
|
||||||
|
|
|
@ -80,6 +80,11 @@ typedef struct lua_TValue
|
||||||
|
|
||||||
#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
|
#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
|
||||||
|
|
||||||
|
#define lightuserdatatag(o) check_exp(ttislightuserdata(o), (o)->extra[0])
|
||||||
|
|
||||||
|
// Internal tags used by the VM
|
||||||
|
#define LU_TAG_ITERATOR LUA_UTAG_LIMIT
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** for internal debug only
|
** for internal debug only
|
||||||
*/
|
*/
|
||||||
|
@ -120,10 +125,11 @@ typedef struct lua_TValue
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define setpvalue(obj, x) \
|
#define setpvalue(obj, x, tag) \
|
||||||
{ \
|
{ \
|
||||||
TValue* i_o = (obj); \
|
TValue* i_o = (obj); \
|
||||||
i_o->value.p = (x); \
|
i_o->value.p = (x); \
|
||||||
|
i_o->extra[0] = (tag); \
|
||||||
i_o->tt = LUA_TLIGHTUSERDATA; \
|
i_o->tt = LUA_TLIGHTUSERDATA; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -492,3 +498,5 @@ LUAI_FUNC int luaO_str2d(const char* s, double* result);
|
||||||
LUAI_FUNC const char* luaO_pushvfstring(lua_State* L, const char* fmt, va_list argp);
|
LUAI_FUNC const char* luaO_pushvfstring(lua_State* L, const char* fmt, va_list argp);
|
||||||
LUAI_FUNC const char* luaO_pushfstring(lua_State* L, const char* fmt, ...);
|
LUAI_FUNC const char* luaO_pushfstring(lua_State* L, const char* fmt, ...);
|
||||||
LUAI_FUNC const char* luaO_chunkid(char* buf, size_t buflen, const char* source, size_t srclen);
|
LUAI_FUNC const char* luaO_chunkid(char* buf, size_t buflen, const char* source, size_t srclen);
|
||||||
|
|
||||||
|
LUAU_FASTFLAG(TaggedLuData)
|
||||||
|
|
|
@ -210,6 +210,8 @@ lua_State* lua_newstate(lua_Alloc f, void* ud)
|
||||||
g->mt[i] = NULL;
|
g->mt[i] = NULL;
|
||||||
for (i = 0; i < LUA_UTAG_LIMIT; i++)
|
for (i = 0; i < LUA_UTAG_LIMIT; i++)
|
||||||
g->udatagc[i] = NULL;
|
g->udatagc[i] = NULL;
|
||||||
|
for (i = 0; i < LUA_LUTAG_LIMIT; i++)
|
||||||
|
g->lightuserdataname[i] = NULL;
|
||||||
for (i = 0; i < LUA_MEMORY_CATEGORIES; i++)
|
for (i = 0; i < LUA_MEMORY_CATEGORIES; i++)
|
||||||
g->memcatbytes[i] = 0;
|
g->memcatbytes[i] = 0;
|
||||||
|
|
||||||
|
|
|
@ -214,6 +214,8 @@ typedef struct global_State
|
||||||
|
|
||||||
void (*udatagc[LUA_UTAG_LIMIT])(lua_State*, void*); // for each userdata tag, a gc callback to be called immediately before freeing memory
|
void (*udatagc[LUA_UTAG_LIMIT])(lua_State*, void*); // for each userdata tag, a gc callback to be called immediately before freeing memory
|
||||||
|
|
||||||
|
TString* lightuserdataname[LUA_LUTAG_LIMIT]; // names for tagged lightuserdata
|
||||||
|
|
||||||
GCStats gcstats;
|
GCStats gcstats;
|
||||||
|
|
||||||
#ifdef LUAI_GCMETRICS
|
#ifdef LUAI_GCMETRICS
|
||||||
|
|
|
@ -129,6 +129,18 @@ const TString* luaT_objtypenamestr(lua_State* L, const TValue* o)
|
||||||
if (ttisstring(type))
|
if (ttisstring(type))
|
||||||
return tsvalue(type);
|
return tsvalue(type);
|
||||||
}
|
}
|
||||||
|
else if (FFlag::TaggedLuData && ttislightuserdata(o))
|
||||||
|
{
|
||||||
|
int tag = lightuserdatatag(o);
|
||||||
|
|
||||||
|
if (unsigned(tag) < LUA_LUTAG_LIMIT)
|
||||||
|
{
|
||||||
|
const TString* name = L->global->lightuserdataname[tag];
|
||||||
|
|
||||||
|
if (name)
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (Table* mt = L->global->mt[ttype(o)])
|
else if (Table* mt = L->global->mt[ttype(o)])
|
||||||
{
|
{
|
||||||
const TValue* type = luaH_getstr(mt, L->global->tmname[TM_TYPE]);
|
const TValue* type = luaH_getstr(mt, L->global->tmname[TM_TYPE]);
|
||||||
|
|
|
@ -135,6 +135,8 @@
|
||||||
// Does VM support native execution via ExecutionCallbacks? We mostly assume it does but keep the define to make it easy to quantify the cost.
|
// Does VM support native execution via ExecutionCallbacks? We mostly assume it does but keep the define to make it easy to quantify the cost.
|
||||||
#define VM_HAS_NATIVE 1
|
#define VM_HAS_NATIVE 1
|
||||||
|
|
||||||
|
LUAU_FASTFLAGVARIABLE(TaggedLuData, false)
|
||||||
|
|
||||||
LUAU_NOINLINE void luau_callhook(lua_State* L, lua_Hook hook, void* userdata)
|
LUAU_NOINLINE void luau_callhook(lua_State* L, lua_Hook hook, void* userdata)
|
||||||
{
|
{
|
||||||
ptrdiff_t base = savestack(L, L->base);
|
ptrdiff_t base = savestack(L, L->base);
|
||||||
|
@ -1110,7 +1112,7 @@ reentry:
|
||||||
VM_NEXT();
|
VM_NEXT();
|
||||||
|
|
||||||
case LUA_TLIGHTUSERDATA:
|
case LUA_TLIGHTUSERDATA:
|
||||||
pc += pvalue(ra) == pvalue(rb) ? LUAU_INSN_D(insn) : 1;
|
pc += (pvalue(ra) == pvalue(rb) && (!FFlag::TaggedLuData || lightuserdatatag(ra) == lightuserdatatag(rb))) ? LUAU_INSN_D(insn) : 1;
|
||||||
LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode));
|
LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode));
|
||||||
VM_NEXT();
|
VM_NEXT();
|
||||||
|
|
||||||
|
@ -1225,7 +1227,7 @@ reentry:
|
||||||
VM_NEXT();
|
VM_NEXT();
|
||||||
|
|
||||||
case LUA_TLIGHTUSERDATA:
|
case LUA_TLIGHTUSERDATA:
|
||||||
pc += pvalue(ra) != pvalue(rb) ? LUAU_INSN_D(insn) : 1;
|
pc += (pvalue(ra) != pvalue(rb) || (FFlag::TaggedLuData && lightuserdatatag(ra) != lightuserdatatag(rb))) ? LUAU_INSN_D(insn) : 1;
|
||||||
LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode));
|
LUAU_ASSERT(unsigned(pc - cl->l.p->code) < unsigned(cl->l.p->sizecode));
|
||||||
VM_NEXT();
|
VM_NEXT();
|
||||||
|
|
||||||
|
@ -2296,7 +2298,7 @@ reentry:
|
||||||
{
|
{
|
||||||
// set up registers for builtin iteration
|
// set up registers for builtin iteration
|
||||||
setobj2s(L, ra + 1, ra);
|
setobj2s(L, ra + 1, ra);
|
||||||
setpvalue(ra + 2, reinterpret_cast<void*>(uintptr_t(0)));
|
setpvalue(ra + 2, reinterpret_cast<void*>(uintptr_t(0)), LU_TAG_ITERATOR);
|
||||||
setnilvalue(ra);
|
setnilvalue(ra);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2348,7 +2350,7 @@ reentry:
|
||||||
|
|
||||||
if (!ttisnil(e))
|
if (!ttisnil(e))
|
||||||
{
|
{
|
||||||
setpvalue(ra + 2, reinterpret_cast<void*>(uintptr_t(index + 1)));
|
setpvalue(ra + 2, reinterpret_cast<void*>(uintptr_t(index + 1)), LU_TAG_ITERATOR);
|
||||||
setnvalue(ra + 3, double(index + 1));
|
setnvalue(ra + 3, double(index + 1));
|
||||||
setobj2s(L, ra + 4, e);
|
setobj2s(L, ra + 4, e);
|
||||||
|
|
||||||
|
@ -2369,7 +2371,7 @@ reentry:
|
||||||
|
|
||||||
if (!ttisnil(gval(n)))
|
if (!ttisnil(gval(n)))
|
||||||
{
|
{
|
||||||
setpvalue(ra + 2, reinterpret_cast<void*>(uintptr_t(index + 1)));
|
setpvalue(ra + 2, reinterpret_cast<void*>(uintptr_t(index + 1)), LU_TAG_ITERATOR);
|
||||||
getnodekey(L, ra + 3, n);
|
getnodekey(L, ra + 3, n);
|
||||||
setobj2s(L, ra + 4, gval(n));
|
setobj2s(L, ra + 4, gval(n));
|
||||||
|
|
||||||
|
@ -2421,7 +2423,7 @@ reentry:
|
||||||
{
|
{
|
||||||
setnilvalue(ra);
|
setnilvalue(ra);
|
||||||
// ra+1 is already the table
|
// ra+1 is already the table
|
||||||
setpvalue(ra + 2, reinterpret_cast<void*>(uintptr_t(0)));
|
setpvalue(ra + 2, reinterpret_cast<void*>(uintptr_t(0)), LU_TAG_ITERATOR);
|
||||||
}
|
}
|
||||||
else if (!ttisfunction(ra))
|
else if (!ttisfunction(ra))
|
||||||
{
|
{
|
||||||
|
@ -2450,7 +2452,7 @@ reentry:
|
||||||
{
|
{
|
||||||
setnilvalue(ra);
|
setnilvalue(ra);
|
||||||
// ra+1 is already the table
|
// ra+1 is already the table
|
||||||
setpvalue(ra + 2, reinterpret_cast<void*>(uintptr_t(0)));
|
setpvalue(ra + 2, reinterpret_cast<void*>(uintptr_t(0)), LU_TAG_ITERATOR);
|
||||||
}
|
}
|
||||||
else if (!ttisfunction(ra))
|
else if (!ttisfunction(ra))
|
||||||
{
|
{
|
||||||
|
|
|
@ -288,7 +288,7 @@ int luaV_equalval(lua_State* L, const TValue* t1, const TValue* t2)
|
||||||
case LUA_TBOOLEAN:
|
case LUA_TBOOLEAN:
|
||||||
return bvalue(t1) == bvalue(t2); // true must be 1 !!
|
return bvalue(t1) == bvalue(t2); // true must be 1 !!
|
||||||
case LUA_TLIGHTUSERDATA:
|
case LUA_TLIGHTUSERDATA:
|
||||||
return pvalue(t1) == pvalue(t2);
|
return pvalue(t1) == pvalue(t2) && (!FFlag::TaggedLuData || lightuserdatatag(t1) == lightuserdatatag(t2));
|
||||||
case LUA_TUSERDATA:
|
case LUA_TUSERDATA:
|
||||||
{
|
{
|
||||||
tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, TM_EQ);
|
tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, TM_EQ);
|
||||||
|
|
|
@ -32,6 +32,7 @@ LUAU_FASTFLAG(LuauBufferDefinitions);
|
||||||
LUAU_FASTFLAG(LuauCodeGenFixByteLower);
|
LUAU_FASTFLAG(LuauCodeGenFixByteLower);
|
||||||
LUAU_FASTFLAG(LuauCompileBufferAnnotation);
|
LUAU_FASTFLAG(LuauCompileBufferAnnotation);
|
||||||
LUAU_FASTFLAG(LuauLoopInterruptFix);
|
LUAU_FASTFLAG(LuauLoopInterruptFix);
|
||||||
|
LUAU_FASTFLAG(TaggedLuData);
|
||||||
LUAU_DYNAMIC_FASTFLAG(LuauStricterUtf8);
|
LUAU_DYNAMIC_FASTFLAG(LuauStricterUtf8);
|
||||||
LUAU_FASTINT(CodegenHeuristicsInstructionLimit);
|
LUAU_FASTINT(CodegenHeuristicsInstructionLimit);
|
||||||
|
|
||||||
|
@ -1700,6 +1701,32 @@ TEST_CASE("UserdataApi")
|
||||||
CHECK(dtorhits == 42);
|
CHECK(dtorhits == 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("LightuserdataApi")
|
||||||
|
{
|
||||||
|
ScopedFastFlag taggedLuData{FFlag::TaggedLuData, true};
|
||||||
|
|
||||||
|
StateRef globalState(luaL_newstate(), lua_close);
|
||||||
|
lua_State* L = globalState.get();
|
||||||
|
|
||||||
|
void* value = (void*)0x12345678;
|
||||||
|
|
||||||
|
lua_pushlightuserdatatagged(L, value, 1);
|
||||||
|
CHECK(lua_lightuserdatatag(L, -1) == 1);
|
||||||
|
CHECK(lua_tolightuserdatatagged(L, -1, 0) == nullptr);
|
||||||
|
CHECK(lua_tolightuserdatatagged(L, -1, 1) == value);
|
||||||
|
|
||||||
|
lua_setlightuserdataname(L, 1, "id");
|
||||||
|
CHECK(!lua_getlightuserdataname(L, 0));
|
||||||
|
CHECK(strcmp(lua_getlightuserdataname(L, 1), "id") == 0);
|
||||||
|
CHECK(strcmp(luaL_typename(L, -1), "id") == 0);
|
||||||
|
|
||||||
|
lua_pushlightuserdatatagged(L, value, 0);
|
||||||
|
lua_pushlightuserdatatagged(L, value, 1);
|
||||||
|
CHECK(lua_rawequal(L, -1, -2) == 0);
|
||||||
|
|
||||||
|
globalState.reset();
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("Iter")
|
TEST_CASE("Iter")
|
||||||
{
|
{
|
||||||
runConformance("iter.lua");
|
runConformance("iter.lua");
|
||||||
|
|
Loading…
Reference in a new issue