mirror of
https://github.com/luau-lang/luau.git
synced 2025-05-04 10:33:46 +01:00
Move duplicated FORGPREP code to seperate function
This commit is contained in:
parent
f803995825
commit
39c155dc8a
1 changed files with 50 additions and 123 deletions
|
@ -141,6 +141,51 @@ LUAU_NOINLINE static void luau_prepareFORN(lua_State* L, StkId plimit, StkId pst
|
||||||
luaG_forerror(L, pstep, "step");
|
luaG_forerror(L, pstep, "step");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void luau_prepareFORG(lua_State* L, StkId base, const Instruction* pc, StkId& ra)
|
||||||
|
{
|
||||||
|
if (!ttisfunction(ra))
|
||||||
|
{
|
||||||
|
Table* mt = ttistable(ra) ? hvalue(ra)->metatable : ttisuserdata(ra) ? uvalue(ra)->metatable : cast_to(Table*, NULL);
|
||||||
|
|
||||||
|
if (const TValue* fn = fasttm(L, mt, TM_ITER))
|
||||||
|
{
|
||||||
|
setobj2s(L, ra + 1, ra);
|
||||||
|
setobj2s(L, ra, fn);
|
||||||
|
|
||||||
|
L->top = ra + 2; // func + self arg
|
||||||
|
LUAU_ASSERT(L->top <= L->stack_last);
|
||||||
|
|
||||||
|
VM_PROTECT(luaD_call(L, ra, 3));
|
||||||
|
L->top = L->ci->top;
|
||||||
|
|
||||||
|
// recompute ra since stack might have been reallocated
|
||||||
|
ra = VM_REG(LUAU_INSN_A(*pc));
|
||||||
|
|
||||||
|
// protect against __iter returning nil, since nil is used as a marker for builtin iteration in FORGLOOP
|
||||||
|
if (ttisnil(ra))
|
||||||
|
{
|
||||||
|
VM_PROTECT(luaG_typeerror(L, ra, "call"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (fasttm(L, mt, TM_CALL))
|
||||||
|
{
|
||||||
|
// table or userdata with __call, will be called during FORGLOOP
|
||||||
|
// TODO: we might be able to stop supporting this depending on whether it's used in practice
|
||||||
|
}
|
||||||
|
else if (ttistable(ra))
|
||||||
|
{
|
||||||
|
// set up registers for builtin iteration
|
||||||
|
setobj2s(L, ra + 1, ra);
|
||||||
|
setpvalue(ra + 2, reinterpret_cast<void*>(uintptr_t(0)));
|
||||||
|
setnilvalue(ra);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VM_PROTECT(luaG_typeerror(L, ra, "iterate over"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// calls a C function f with no yielding support; optionally save one resulting value to the res register
|
// calls a C function f with no yielding support; optionally save one resulting value to the res register
|
||||||
// the function and arguments have to already be pushed to L->top
|
// the function and arguments have to already be pushed to L->top
|
||||||
LUAU_NOINLINE static void luau_callTM(lua_State* L, int nparams, int res)
|
LUAU_NOINLINE static void luau_callTM(lua_State* L, int nparams, int res)
|
||||||
|
@ -2190,51 +2235,7 @@ static void luau_execute(lua_State* L)
|
||||||
Instruction insn = *pc++;
|
Instruction insn = *pc++;
|
||||||
StkId ra = VM_REG(LUAU_INSN_A(insn));
|
StkId ra = VM_REG(LUAU_INSN_A(insn));
|
||||||
|
|
||||||
if (ttisfunction(ra))
|
luau_prepareFORG(L, base, pc, ra);
|
||||||
{
|
|
||||||
// will be called during FORGLOOP
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Table* mt = ttistable(ra) ? hvalue(ra)->metatable : ttisuserdata(ra) ? uvalue(ra)->metatable : cast_to(Table*, NULL);
|
|
||||||
|
|
||||||
if (const TValue* fn = fasttm(L, mt, TM_ITER))
|
|
||||||
{
|
|
||||||
setobj2s(L, ra + 1, ra);
|
|
||||||
setobj2s(L, ra, fn);
|
|
||||||
|
|
||||||
L->top = ra + 2; // func + self arg
|
|
||||||
LUAU_ASSERT(L->top <= L->stack_last);
|
|
||||||
|
|
||||||
VM_PROTECT(luaD_call(L, ra, 3));
|
|
||||||
L->top = L->ci->top;
|
|
||||||
|
|
||||||
// recompute ra since stack might have been reallocated
|
|
||||||
ra = VM_REG(LUAU_INSN_A(insn));
|
|
||||||
|
|
||||||
// protect against __iter returning nil, since nil is used as a marker for builtin iteration in FORGLOOP
|
|
||||||
if (ttisnil(ra))
|
|
||||||
{
|
|
||||||
VM_PROTECT(luaG_typeerror(L, ra, "call"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (fasttm(L, mt, TM_CALL))
|
|
||||||
{
|
|
||||||
// table or userdata with __call, will be called during FORGLOOP
|
|
||||||
// TODO: we might be able to stop supporting this depending on whether it's used in practice
|
|
||||||
}
|
|
||||||
else if (ttistable(ra))
|
|
||||||
{
|
|
||||||
// set up registers for builtin iteration
|
|
||||||
setobj2s(L, ra + 1, ra);
|
|
||||||
setpvalue(ra + 2, reinterpret_cast<void*>(uintptr_t(0)));
|
|
||||||
setnilvalue(ra);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
VM_PROTECT(luaG_typeerror(L, ra, "iterate over"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pc += LUAU_INSN_D(insn);
|
pc += LUAU_INSN_D(insn);
|
||||||
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));
|
||||||
|
@ -2353,46 +2354,9 @@ static void luau_execute(lua_State* L)
|
||||||
// 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)));
|
||||||
}
|
}
|
||||||
else if (!ttisfunction(ra))
|
else
|
||||||
{
|
{
|
||||||
Table* mt = ttistable(ra) ? hvalue(ra)->metatable : ttisuserdata(ra) ? uvalue(ra)->metatable : cast_to(Table*, NULL);
|
luau_prepareFORG(L, base, pc, ra);
|
||||||
|
|
||||||
if (const TValue* fn = fasttm(L, mt, TM_ITER))
|
|
||||||
{
|
|
||||||
setobj2s(L, ra + 1, ra);
|
|
||||||
setobj2s(L, ra, fn);
|
|
||||||
|
|
||||||
L->top = ra + 2; // func + self arg
|
|
||||||
LUAU_ASSERT(L->top <= L->stack_last);
|
|
||||||
|
|
||||||
VM_PROTECT(luaD_call(L, ra, 3));
|
|
||||||
L->top = L->ci->top;
|
|
||||||
|
|
||||||
// recompute ra since stack might have been reallocated
|
|
||||||
ra = VM_REG(LUAU_INSN_A(insn));
|
|
||||||
|
|
||||||
// protect against __iter returning nil, since nil is used as a marker for builtin iteration in FORGLOOP
|
|
||||||
if (ttisnil(ra))
|
|
||||||
{
|
|
||||||
VM_PROTECT(luaG_typeerror(L, ra, "call"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (fasttm(L, mt, TM_CALL))
|
|
||||||
{
|
|
||||||
// table or userdata with __call, will be called during FORGLOOP
|
|
||||||
// TODO: we might be able to stop supporting this depending on whether it's used in practice
|
|
||||||
}
|
|
||||||
else if (ttistable(ra))
|
|
||||||
{
|
|
||||||
// set up registers for builtin iteration
|
|
||||||
setobj2s(L, ra + 1, ra);
|
|
||||||
setpvalue(ra + 2, reinterpret_cast<void*>(uintptr_t(0)));
|
|
||||||
setnilvalue(ra);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
VM_PROTECT(luaG_typeerror(L, ra, "iterate over"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pc += LUAU_INSN_D(insn);
|
pc += LUAU_INSN_D(insn);
|
||||||
|
@ -2418,46 +2382,9 @@ static void luau_execute(lua_State* L)
|
||||||
// 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)));
|
||||||
}
|
}
|
||||||
else if (!ttisfunction(ra))
|
else
|
||||||
{
|
{
|
||||||
Table* mt = ttistable(ra) ? hvalue(ra)->metatable : ttisuserdata(ra) ? uvalue(ra)->metatable : cast_to(Table*, NULL);
|
luau_prepareFORG(L, base, pc, ra);
|
||||||
|
|
||||||
if (const TValue* fn = fasttm(L, mt, TM_ITER))
|
|
||||||
{
|
|
||||||
setobj2s(L, ra + 1, ra);
|
|
||||||
setobj2s(L, ra, fn);
|
|
||||||
|
|
||||||
L->top = ra + 2; // func + self arg
|
|
||||||
LUAU_ASSERT(L->top <= L->stack_last);
|
|
||||||
|
|
||||||
VM_PROTECT(luaD_call(L, ra, 3));
|
|
||||||
L->top = L->ci->top;
|
|
||||||
|
|
||||||
// recompute ra since stack might have been reallocated
|
|
||||||
ra = VM_REG(LUAU_INSN_A(insn));
|
|
||||||
|
|
||||||
// protect against __iter returning nil, since nil is used as a marker for builtin iteration in FORGLOOP
|
|
||||||
if (ttisnil(ra))
|
|
||||||
{
|
|
||||||
VM_PROTECT(luaG_typeerror(L, ra, "call"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (fasttm(L, mt, TM_CALL))
|
|
||||||
{
|
|
||||||
// table or userdata with __call, will be called during FORGLOOP
|
|
||||||
// TODO: we might be able to stop supporting this depending on whether it's used in practice
|
|
||||||
}
|
|
||||||
else if (ttistable(ra))
|
|
||||||
{
|
|
||||||
// set up registers for builtin iteration
|
|
||||||
setobj2s(L, ra + 1, ra);
|
|
||||||
setpvalue(ra + 2, reinterpret_cast<void*>(uintptr_t(0)));
|
|
||||||
setnilvalue(ra);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
VM_PROTECT(luaG_typeerror(L, ra, "iterate over"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pc += LUAU_INSN_D(insn);
|
pc += LUAU_INSN_D(insn);
|
||||||
|
|
Loading…
Add table
Reference in a new issue